%%%==============================================================================
%% Copyright 2023-present by Alceu Frigeri
%%
%% This work may be distributed and/or modified under the conditions of
%%
%% * The [LaTeX Project Public License](http://www.latex-project.org/lppl.txt),
%%   version 1.3c (or later), and/or
%% * The [GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.html),
%%   version 3 (or later)
%%
%% This work has the LPPL maintenance status *maintained*.
%%
%% The Current Maintainer of this work is Alceu Frigeri
%%
%% This is version {2.0} {2025/10/03}
%%
%% The list of files that compose this work can be found in the README.md file at
%% https://ctan.org/pkg/tikzquests
%%
%%%==============================================================================
\NeedsTeXFormat{LaTeX2e}[2022/06/01]


\ProvidesExplPackage
    {tikzquests}
    {2025/10/03}
    {2.0}
    {A Simple Framework for (tikz/text) Parametric Questions}

\ExplSyntaxOn
%%%%%%%
%%%
%%% Just an attempt of having my packages info in a regular way
%%% Idea being: { <pck-name> / pkg info } for each and all.
%%%
%%%%%%%
\keys_define:nn { tikzquests / pkg info}
  {
     name        .code:n = {tikzquests} ,
     prefix      .code:n = {tikzquests} ,
     date        .code:n = {2025/10/03},
     version     .code:n = {2.0} ,
     description .code:n = {A Simple Framework for (tikz/text) Parametric Questions}
  }
\cs_if_exist:NF \PkgInfo 
  {
    \NewDocumentCommand \PkgInfo {mm} { \keys_set:nn {#1 / pkg info}{#2} } 
    \NewDocumentCommand \PkgDescription {m} 
      { \noindent Package~ \textbf{\PkgInfo{#1}{name}}~Version:~\PkgInfo{#1}{version}~ -~ \PkgInfo{#1}{date}\par \emph{\PkgInfo{#1}{description}}~\par } 
  }  
%%%%%%%
%%% End of cut-n-paste
%%%%%%%


%\newif\iftikzquests@@nodefs
%\tikzquests@@nodefsfalse

\keys_define:nn {tikzquests }
  {
    no~ alias  .usage:n = load ,
    no~ alias  .bool_set:N = \l__tikzquests_noalias_bool ,
    no~ alias  .value_forbidden:n  = true ,

    xtrakeys .usage:n = load ,
    xtrakeys .tl_set:N = \l__tikzquests_xtrakeys_tl ,
    xtrakeys .value_required:n  = true ,
    
    xtraidx .usage:n = load ,
    xtraidx .tl_set:N = \l__tikzquests_xtraidx_tl ,
    xtraidx .value_required:n  = true ,
   
    undef~ color .usage:n = load ,
    undef~ color .tl_set:N = \l__tikzquests_undefcolor_tl , 
    undef~ color .value_required:n  = true ,
    undef~ color .initial:n = {red} ,

    in~ review .usage:n = load ,
    in~ review .bool_set:N = \l__tikzquests_inreview_bool ,

    no~ defs  .usage:n = load ,
    no~ defs  .bool_set:N = \l__tikzquests_nodefs_bool ,
    no~ defs  .value_forbidden:n  = true ,

    old~ settings  .usage:n = load ,
    old~ settings  .bool_set:N = \l__tikzquests_oldsettings_bool ,
    old~ settings  .value_forbidden:n  = true ,
  }
\ProcessKeyOptions [ tikzquests ]



%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%
%%
%%
%%
%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%

\msg_new:nnnn {tikzquests} {repository already defined}
  {
    (ID:#1)~Repository~ '#2'~already~defined!
  }
  {
    You~tried~to~create~an~already~defined~Repository:~'#2'.
    ~Error~Code~ ID:<#1>.
  }

\msg_new:nnnn {tikzquests} {invalid repository}
  {
    (ID:#1)~Invalid~Repository:~ '#2'
  }
  {
    You~tried~to~use~an~invalid~Repository:~'#2'.
    ~Error~Code~ ID:<#1>.
  }

\msg_new:nnnn {tikzquests} {invalid question}
  {
    (ID:#1)~Invalid~Question:~ '#2'
  }
  {
    You~tried~to~use~an~invalid~Question:~'#2'.
    ~Error~Code~ ID:<#1>.
  }


\msg_new:nnnn {tikzquests} {deprecated}
  {
    (ID:#1)~#2 ~ is ~ deprecated.~ use~ '#3' ~ instead
  }
  {
    You~tried~to~use~a~deprecated~command:~#2. Use~'#3'~ instead.
    ~Error~Code~ ID:<#1>.
  }



\seq_new:N  \l__tikzquests_repositories_seq
\tl_new:N   \l__tikzquests_active_repository_tl
\seq_new:N  \l__tikzquests_tmpa_seq
\seq_new:N  \l__tikzquests_tmpb_seq
\tl_new:N   \l__tikzquests_tmp_tl  

\cs_new_protected:Npn \__tikzquests_select_repository:n #1
  {
    \prop_if_exist:cTF {l__tikzquests_ #1 _tikzrepo_prop}
    { 
      \tl_set:Nn \l__tikzquests_active_repository_tl {#1}
    }
    {  
      \msg_error:nnne {tikzquests}{invalid repository}{select~01}{#1}
    }
  }

\cs_new_protected:Npn \__tikzquests_new_repository:nn #1#2
  {
    \prop_if_exist:cTF {l__tikzquests_ #2 _tikzrepo_prop}
      {
        \msg_warning:nnne {tikzquests}{repository already defined}{new~01}{#2}
      }
      { 
        \prop_new_linked:c {l__tikzquests_ #2 _tikzrepo_prop}
        \prop_new_linked:c {l__tikzquests_ #2 _tikzrepo_remarks_prop}
        \prop_new_linked:c {l__tikzquests_ #2 _textrepo_prop}
        \prop_new_linked:c {l__tikzquests_ #2 _textrepo_remarks_prop}
        \seq_put_right:Nn \l__tikzquests_repositories_seq {#2}
      }
    \bool_if:nT {#1}
      {
        \__tikzquests_select_repository:n {#2}
      }
  }  

\__tikzquests_new_repository:nn {\c_true_bool}{default}

\NewDocumentCommand{\SelectRepository}{m}
  {
    \__tikzquests_select_repository:n {#1}
  }
  
\NewDocumentCommand{\defRepository}{sm}
  {
    \__tikzquests_new_repository:nn {#1}{#2}
  }  
%\cs_new_eq:NN   \defRepository \defRepository
%
\NewDocumentCommand\defNewRepository{sm}
  {
    \msg_warning:nnnnn {tikzquests}{deprecated}{dep~03}{\defNewRepository}{\defRepository}
    \__tikzquests_new_repository:nn {#1}{#2}
  }


\NewDocumentCommand{\defQuestion}{sO{\l__tikzquests_active_repository_tl}m+mO{}}
  {
    \prop_if_exist:cTF {l__tikzquests_ #2 _tikzrepo_prop}
    {
      \bool_if:nTF {#1}
        { 
          \prop_put:cnn {l__tikzquests_ #2 _textrepo_prop}{#3}{#4} 
          \prop_put:cnn {l__tikzquests_ #2 _textrepo_remarks_prop}{#3}{#5} 
        }
        { 
          \prop_put:cnn {l__tikzquests_ #2 _tikzrepo_prop}{#3}{#4} 
          \prop_put:cnn {l__tikzquests_ #2 _tikzrepo_remarks_prop}{#3}{#5} 
        }    
    }
    {
      \msg_error:nnne {tikzquests}{invalid repository}{def~quest~01}{#2}
    }
  }
  
  
\NewDocumentCommand{\defQuestionAlias}{sO{\l__tikzquests_active_repository_tl}mO{}m}
  {
    \tl_if_blank:nTF {#4}
      { \tl_set:Nn \l_tmpa_tl {#2} }
      { \tl_set:Nn \l_tmpa_tl {#4} }
    \bool_lazy_and:nnTF { \prop_if_exist_p:c {l__tikzquests_ #2 _tikzrepo_prop} } { \prop_if_exist_p:c {l__tikzquests_ \l_tmpa_tl _tikzrepo_prop} }
    {
      \bool_if:NF \l__tikzquests_noalias_bool
        {
          \bool_if:nTF {#1}
            { 
              \prop_get:cnNTF {l__tikzquests_ \l_tmpa_tl _textrepo_prop}{#5} \l_tmpb_tl
                {
                  \prop_put:cnV {l__tikzquests_ #2 _textrepo_prop}{#3} \l_tmpb_tl
                  \prop_get:cnNTF {l__tikzquests_ \l_tmpa_tl _textrepo_remarks_prop}{#5} \l_tmpb_tl
                    { \prop_put:cnV {l__tikzquests_ #2 _textrepo_remarks_prop}{#3} \l_tmpb_tl }
                    { \prop_put:cnn {l__tikzquests_ #2 _textrepo_remarks_prop}{#3}{} }
                }
                { 
                  \msg_error:nnnn {tikzquests}{invalid question}{alias~01}{#5} 
                }
            }
            { 
              \prop_get:cnNTF {l__tikzquests_ \l_tmpa_tl _tikzrepo_prop}{#5} \l_tmpb_tl
                {
                  \prop_put:cnV {l__tikzquests_ #2 _tikzrepo_prop}{#3} \l_tmpb_tl
                  \prop_get:cnNTF {l__tikzquests_ \l_tmpa_tl _tikzrepo_remarks_prop}{#5} \l_tmpb_tl
                    { \prop_put:cnV {l__tikzquests_ #2 _tikzrepo_remarks_prop}{#3} \l_tmpb_tl }
                    { \prop_put:cnn {l__tikzquests_ #2 _tikzrepo_remarks_prop}{#3}{} }
                }
                { 
                  \msg_error:nnnn {tikzquests}{invalid question}{alias~02}{#5} 
                }
            }
        }
    }
    {
      \tl_if_blank:nTF {#4}
        {
          \msg_error:nnne {tikzquests}{invalid repository}{alias~04}{<#2>}
        }
        {
          \msg_error:nnne {tikzquests}{invalid repository}{alias~04}{<#2> - <#4>}
        }
    }
  }
  
\cs_new_protected:Npn \__tikzquests_remarks:nnn #1#2#3
  {
    \prop_get:cnN {l__tikzquests_ #1 _remarks_prop} {#2} \l__tikzquests_tmp_tl
    \tl_if_blank:eF {\l__tikzquests_tmp_tl}
      {
        {\par\footnotesize\textbf{Remarks:~}\color{\l__tikzquests_undefcolor_tl}\l__tikzquests_tmp_tl}
      }
  }  

\cs_new_protected:Npn \__tikzquests_inreview_remarks:nnn #1#2#3
  {
    \bool_if:nT {\l__tikzquests_inreview_bool}
      {  
        \__tikzquests_remarks:nnn {#1}{#2}{#3}  
        \tl_if_blank:nF {#3}
          {
            {\par\footnotesize\textbf{Annotation:~}\color{\l__tikzquests_undefcolor_tl}#3}
          }
      }
  }  
  
  
\NewDocumentCommand{\ftikzQuestion}{sD(){}O{\l__tikzquests_active_repository_tl}mO{}}
  {
    \bool_if:nTF {#1}
      {
  			\begin{center}
          \tikzQuestion*(#2)[#3]{#4}[#5]
  			\end{center}
      }
      {
  			\begin{center}
          \tikzQuestion(#2)[#3]{#4}[#5]
  			\end{center}
      }
  }  

\cs_new_protected:Npn \__tikzquests_pgfkeys:n #1
  {
    \pgfkeys{tikz , #1}
  }
  
\tl_new:N \l__tikzquests_repo_tl    
\NewDocumentCommand{\tikzQuestion}{sD(){}O{\l__tikzquests_active_repository_tl}mO{}D<>{}}
  {
    \bool_if:nTF {#1}
      { \tl_set:Nn \l__tikzquests_repo_tl {textrepo} }
      { \tl_set:Nn \l__tikzquests_repo_tl {tikzrepo} }
    \prop_if_exist:cTF {l__tikzquests_ #3 _ \l__tikzquests_repo_tl _prop}
    {
      \prop_get:cnNTF {l__tikzquests_ #3 _ \l__tikzquests_repo_tl _prop} {#4} \l__tikzquests_tmp_tl
        {
          \tl_if_blank:nTF {#2}
            {
      				\begin{tikzpicture}
                \__tikzquests_keys_set:n{#5}
                \exp_args:NV \__tikzquests_pgfkeys:n \l__tikzquests_tikz_keys_tl
        				\l__tikzquests_tmp_tl
      				\end{tikzpicture}
            }
            {
      				\resizebox{#2\textwidth}{!}{
      				\begin{tikzpicture}
                \__tikzquests_keys_set:n{#5}
                \exp_args:NV \__tikzquests_pgfkeys:n \l__tikzquests_tikz_keys_tl
        				\l__tikzquests_tmp_tl
      				\end{tikzpicture}}
            }
          \__tikzquests_inreview_remarks:nnn {#3 _ \l__tikzquests_repo_tl}{#4}{#6}
        }
        {
          Invalid~Question:~#4
          \msg_error:nnnn {tikzquests}{invalid question}{quest~01}{#4}
        }
    }
    {
      Invalid~Repository:~#3
      \msg_error:nnne {tikzquests}{invalid repository}{quest~01}{#3}
    }
  }  

\cs_new_protected:Npn \__tikzquests_rawquestion:nnnnn #1#2#3#4#5
  {
    \prop_if_exist:cTF {l__tikzquests_ #1 _ #2 _prop}
    {
      \prop_get:cnNTF {l__tikzquests_ #1 _ #2 _prop} {#3} \l__tikzquests_tmp_tl
        {
          \begingroup
            \__tikzquests_keys_set:n{#4}
     				\l__tikzquests_tmp_tl
          \endgroup
          \__tikzquests_inreview_remarks:nnn {#1 _ #2}{#3}{#5}
        }
        {
          Invalid~Question:~#3
          \msg_error:nnnn {tikzquests}{invalid question}{quest~02}{#3}
        }
    }
    {
      Invalid~Repository:~#1
      \msg_error:nnne {tikzquests}{invalid repository}{quest~02}{#1}
    }
  }  
  
\NewDocumentCommand{\rawtikzQuestion}{O{\l__tikzquests_active_repository_tl}mO{}D<>{}}
  {
    \msg_warning:nnnnn {tikzquests}{deprecated}{dep~01}{\rawtikzQuestion}{\Question}
    \__tikzquests_rawquestion:nnnnn {#1}{tikzrepo}{#2}{#3}{#4}
  }

  
\NewDocumentCommand{\textQuestion}{O{\l__tikzquests_active_repository_tl}mO{}D<>{}}
  {
    \msg_warning:nnnnn {tikzquests}{deprecated}{dep~02}{\textQuestion}{\Question*}
    \__tikzquests_rawquestion:nnnnn {#1}{textrepo}{#2}{#3}{#4}
  }

\NewDocumentCommand{\Question}{sO{\l__tikzquests_active_repository_tl}mO{}D<>{}}
  {
    \bool_if:nTF {#1}
      { \__tikzquests_rawquestion:nnnnn {#2}{textrepo}{#3}{#4}{#5} }
      { \__tikzquests_rawquestion:nnnnn {#2}{tikzrepo}{#3}{#4}{#5} }
  }


%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%

\coffin_new:N \l__tikzquests_tmpa_coffin
\coffin_new:N \l__tikzquests_tmpb_coffin

\cs_new_protected:Npn \__tikzquests_sorted_list_new:nnn #1#2#3
  {
      \prop_if_empty:cF {l__tikzquests_ #1 _ #2 _prop}
        {
            \seq_gclear_new:N \l__tikzquests_questions_seq
            \prop_map_inline:cn {l__tikzquests_ #1 _ #2 _prop}
              {
                \seq_put_right:Nn \l__tikzquests_questions_seq {##1}
              }
            \seq_sort:Nn \l__tikzquests_questions_seq
              {
                \str_compare:eNeTF { ##1 } > { ##2 }
                  { \sort_return_swapped: }
                  { \sort_return_same: }
              }
              
              \seq_map_inline:Nn \l__tikzquests_questions_seq
                {
                  \coffin_clear:N \l__tikzquests_tmpa_coffin
                  \coffin_clear:N \l__tikzquests_tmpb_coffin
                  
                  \vcoffin_set:Nnn \l__tikzquests_tmpa_coffin {0.2\textwidth}
                    {
                      \noindent \textbf{##1}
                    }
                  \vcoffin_set:Nnn \l__tikzquests_tmpb_coffin {0.8\textwidth}
                    {
                      \noindent #3[#1]{##1}
                      \bool_if:nF {\l__tikzquests_inreview_bool}
                        {  \__tikzquests_remarks:nnn {#1 _ #2}{##1}{}  }
                    }
                  \coffin_join:NnnNnnnn
                    \l__tikzquests_tmpa_coffin {r}{vc}
                    \l__tikzquests_tmpb_coffin {l}{vc}
                    {0pt}{0pt}
                  \noindent \coffin_typeset:Nnnnn \l__tikzquests_tmpa_coffin {l}{t}{0pt}{0pt}
                  \skip_vertical:n{0.35ex}  
                  {
                    \color{white!20!gray}\hrule\relax
                  }
                  \skip_vertical:n{1ex}  
                  
                }    
        }
  }


\NewDocumentCommand{\QuestionsFmtList}{O{}mm}
  {
    \tl_if_blank:nTF {#1}
      { 
        \seq_set_eq:NN \l__tikzquests_tmpb_seq \l__tikzquests_repositories_seq
      }
      {
        \seq_set_from_clist:Nn \l__tikzquests_tmpb_seq {#1}
      }
      
    \seq_map_inline:Nn \l__tikzquests_tmpb_seq
      {
        \regex_match:nnTF {/$}{##1}
          {
            \tl_set:Nn \l_tmpa_tl {##1}
            \regex_replace_once:nnN {/$}{} \l_tmpa_tl
            \seq_put_right:Nn \l__tikzquests_tmpa_seq {\l_tmpa_tl}
            \seq_map_inline:Nn \l__tikzquests_repositories_seq
              {
                \regex_match:nnTF {##1}{####1}
                  {
                    \seq_put_right:Nn \l__tikzquests_tmpa_seq {####1}
                  }
                  {}
              }
          }
          {
            \seq_put_right:Nn \l__tikzquests_tmpa_seq {##1}
          }
      }      
      
    \seq_remove_duplicates:N \l__tikzquests_tmpa_seq
    \seq_sort:Nn \l__tikzquests_tmpa_seq
      {
        \str_compare:eNeTF { ##1 } > { ##2 }
          { \sort_return_swapped: }
          { \sort_return_same: }
      }
    \seq_map_inline:Nn \l__tikzquests_tmpa_seq
      {
        \prop_if_exist:cTF {l__tikzquests_ ##1 _tikzrepo_prop}
        {    
          \skip_vertical:n{0.35ex}  
          \hrule\relax\hrule\relax
          
          \skip_vertical:n{1ex}  
          Repository:~ \large\textbf{##1}
          \skip_vertical:n{0.35ex}  
          \hrule
          
          \skip_vertical:n{1ex}  
          ~\hfill\emph{\underline{ non~ starred~ ones~ -~ TikZ~ graphics}}
          \skip_vertical:n{0.35ex}  
          
          \__tikzquests_sorted_list_new:nnn {##1}{tikzrepo}{#3}
          
          \skip_vertical:n{1ex}  
          ~\hfill\emph{\underline{starred~ ones~ -~ text/\TeX}}
          \skip_vertical:n{0.35ex}  

          \__tikzquests_sorted_list_new:nnn {##1}{textrepo}{#2}
        }
        {
          \msg_error:nnne {tikzquests}{invalid repository}{Qlist~01}{##1}
        }
      }
  }


\NewDocumentCommand{\QuestionsList}{O{}}
  {
    \QuestionsFmtList[#1]{\Question*}{\tikzQuestion(0.35)}
  }



%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%

 
\cs_new:Npn \__tikzquests_keys_set:n #1
  { 
    \keys_set:nn { tikzquests / vars }
      {#1}
  }


\NewDocumentCommand {\QuestVal} {m}
  {
    \tl_if_exist:cTF {l__tikzquests_ #1 _key_tl}
      { \use:c {l__tikzquests_ #1 _key_tl} }
      { 
        \textbf { \emph{ \color{ \l__tikzquests_undefcolor_tl } #1  } }
      }
  }

\cs_new_protected:Npn \__tikzquests_keydef:nnnN #1#2#3#4
  {
    \tl_set:cn {#2} {#3}
    \keys_define:nn { tikzquests / vars }
      {
        #1 .code:n = 
          {
            \tl_set:cn {#2} {#4{##1}}
          } ,
        #1 .value_required:n = true ,
        
        #1* .code:n = 
          {
            \tl_set:cn {#2} {\ensuremath{##1}}
          } ,                      
        #1* .value_required:n = true ,
        
        #1 ~ raw .code:n = 
          {
            \tl_set:cn {#2} {##1}
          } ,                      
        #1 ~ raw .value_required:n = true ,
      }
  }


\cs_new_protected:Npn \__tikzquests_keys:NNn #1#2#3
  {
    \clist_map_inline:Nn #1
      {
        \clist_map_inline:Nn #2
          {
            \clist_map_inline:nn {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}
              {
                \exp_args:Ncc \tl_set:Nn {l__tikzquests_ ##1####1########1 _key_tl} {##1####1########1}
                \__tikzquests_keydef:nnnN 
                  { ##1####1########1 }
                  { ##1####1########1 }
                  {\ensuremath{##1 \char_generate:nn { `\_ } { 8 } {#3{####1########1}}}}
                  \ensuremath
              }
          }
      }   
  }


\cs_new_protected:Npn \__tikzquests_keys_nodefs:NNn #1#2#3
  {
    \bool_if:NTF \l__tikzquests_oldsettings_bool
      {
        \cs_set_eq:NN \__tikzquests_auxi: \relax
      }
      {
        \cs_set_eq:NN \__tikzquests_auxi: \ensuremath
      }
    \clist_map_inline:Nn #1
      {
        \clist_map_inline:Nn #2
          {
            \clist_map_inline:nn {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}
              {
                \__tikzquests_keydef:nnnN
                  { ##1####1########1 }
                  { l__tikzquests_ ##1####1########1 _key_tl }
                  {\ensuremath{##1 \char_generate:nn { `\_ } { 8 } {#3{####1########1}}}}
                  \__tikzquests_auxi:
              }
          }
      }   
  }




\cs_new_protected:Npn \__tikzquests_newkey:nn #1#2
  {
    \tl_if_empty:nTF {#2}
      {
        \tl_set:cn {l__tikzquests_ #1 _key_tl} 
          {
            \textbf { \emph{ \color{ \l__tikzquests_undefcolor_tl } #1  } }
          }        
      }
      {
        \tl_set:cn {l__tikzquests_ #1 _key_tl} 
          { #2 }        
      }
    \keys_define:nn { tikzquests / vars }
      {
        #1 .tl_set:c = {l__tikzquests_ #1 _key_tl} , 
        #1 .value_required:n = true
      }    
  }


\cs_new_protected:Npn \__tikzquests_keys_set: 
  {
    \keys_define:nn { tikzquests / vars }
      {
        unknown .code:n = 
          {
            \exp_args:NV \__tikzquests_newkey:nn \l_keys_key_str {##1}          
          } ,
        tikz ~ keys .tl_set:N = \l__tikzquests_tikz_keys_tl
      }

    \clist_set:Nn \l__tikzquests_keys_clist {R,L,C,X,Y,Z,K,T,Q,EQ,V,I}
    \clist_put_right:NV \l__tikzquests_keys_clist \l__tikzquests_xtrakeys_tl
    \clist_set:Nn \l__tikzquests_idx_clist {{},a,b}
    \clist_put_right:NV \l__tikzquests_idx_clist \l__tikzquests_xtraidx_tl
    
    \bool_if:NTF \l__tikzquests_nodefs_bool
      { \cs_gset_eq:NN \__tikzquests_map:NNn \__tikzquests_keys_nodefs:NNn }
      { \cs_gset_eq:NN \__tikzquests_map:NNn \__tikzquests_keys:NNn }
            
    \__tikzquests_map:NNn 
      \l__tikzquests_keys_clist
      \l__tikzquests_idx_clist 
      {}
      
    \clist_set:Nn \l__tikzquests_keys_clist {V,I}
    \__tikzquests_map:NNn 
      \l__tikzquests_keys_clist
      \l__tikzquests_idx_clist 
      {f \char_generate:nn { `\_ } { 8 }}
  }
  

\AtBeginDocument{\__tikzquests_keys_set:}


