%%
%% Copyright (C) 2021-2024 by Jinwen XU
%% ------------------------------------
%%
%% This file may be distributed and/or modified under the conditions of
%% the LaTeX Project Public License, either version 1.3c of this license
%% or (at your option) any later version.  The latest version of this
%% license is in:
%%
%%    http://www.latex-project.org/lppl.txt
%%
\NeedsTeXFormat{LaTeX2e}[2022-06-01]
\ProvidesExplPackage
  {create-theorem}
  {2024/02/25} {}
  {Initializing theorem-like environments with multilingual support}

\keys_define:nn { create-theorem }
  {
    , name-as-context       .bool_set:N         = \l__crthm_regionalref_bool
    , name-as-context       .initial:n          = { true }
    , name~as~context       .bool_set:N         = \l__crthm_regionalref_bool
    , name as context       .bool_set:N         = \l__crthm_regionalref_bool
    , regionalref           .bool_set:N         = \l__crthm_regionalref_bool
    , name-as-is            .bool_set_inverse:N = \l__crthm_regionalref_bool
    , name~as~is            .bool_set_inverse:N = \l__crthm_regionalref_bool
    , name as is            .bool_set_inverse:N = \l__crthm_regionalref_bool
    , originalref           .bool_set_inverse:N = \l__crthm_regionalref_bool
    , name-in-link          .bool_set:N         = \l__crthm_nameinlink_bool
    , name-in-link          .initial:n          = { false }
    , name~in~link          .bool_set:N         = \l__crthm_nameinlink_bool
    , name in link          .bool_set:N         = \l__crthm_nameinlink_bool
    , no-preset-names       .bool_set_inverse:N = \l__crthm_presetname_bool
    , no-preset-names       .initial:n          = { false }
    , no~preset~names       .bool_set_inverse:N = \l__crthm_presetname_bool
    , no preset names       .bool_set_inverse:N = \l__crthm_presetname_bool
    , unknown               .code:n             = {}
  }
\ProcessKeyOptions [ create-theorem ]

\msg_new:nnn { create-theorem }
  { no-backend }
  { A~backend~(such~as~"amsthm")~~is~needed~to~provide~the~commands~"\iow_char:N \\newtheorem(*)"~and~"\iow_char:N \\theoremstyle"~with~the~usual~behaviour. }
\cs_if_exist:cF { theoremstyle }
  {
    \msg_error:nn  { create-theorem } { no-backend }
  }

\bool_if:NT \l__crthm_nameinlink_bool
  {
    \PassOptionsToPackage { nameinlink } { cleveref }
  }
\RequirePackage { crefthe }
\RequirePackage { amsfonts }

\IfPackageLoadedTF { thmtools }
  {
    \cs_gset_eq:NN \crthm_newtheorem:w \thmt@original@newtheorem
  }
  {
    \cs_gset_eq:NN \crthm_newtheorem:w \newtheorem
  }


% Users should consider appending their languages to this list as needed,
% otherwise the naming functionality may not work in monolingual documents.
\clist_new:N   \g_crthm_supported_language_clist
\clist_gset:Nn \g_crthm_supported_language_clist
  {
    english     ,
    french      ,
    ngerman     ,
    italian     ,
    portuguese  ,
    brazilian   ,
    spanish     ,
    schinese    ,
    tchinese    ,
    japanese    ,
    russian     ,
  }

\cs_new:Nn \crthm_add_to_language_list:n
  {
    \clist_gput_right:Nn \g_crthm_supported_language_clist { #1 }
    \clist_gremove_duplicates:N \g_crthm_supported_language_clist
  }

\NewDocumentCommand \CreateTheoremAddLanguage { m }
  {
    \crthm_add_to_language_list:n { #1 }
  }


\tl_new:N \l__crthm_current_env_tl

\keys_define:nn { create-theorem-naming }
  {
    , heading               .code:n             = { \crthm_set_name_heading:en { \l__crthm_current_env_tl } { #1 } }
    , heading               .value_required:n   = true
    , crefname              .code:n             = { \crthm_set_name_crefname:en { \l__crthm_current_env_tl } { #1 } }
    , crefname              .value_required:n   = true
    , Crefname              .code:n             = { \crthm_set_name_Crefname:en { \l__crthm_current_env_tl } { #1 } }
    , Crefname              .value_required:n   = true
    , heading~style         .code:n             = { \crthm_set_name_style_heading:en { \l__crthm_current_env_tl } { #1 } }
    , heading~style         .value_required:n   = true
    , heading-style         .meta:n             = { heading~style = { #1 } }
    , heading-style         .value_required:n   = true
    , heading style         .meta:n             = { heading~style = { #1 } }
    , heading style         .value_required:n   = true
    , crefname~style        .code:n             = { \crthm_set_name_style_crefname:en { \l__crthm_current_env_tl } { #1 } }
    , crefname~style        .value_required:n   = true
    , crefname-style        .meta:n             = { crefname~style = { #1 } }
    , crefname-style        .value_required:n   = true
    , crefname style        .meta:n             = { crefname~style = { #1 } }
    , crefname style        .value_required:n   = true
    , Crefname~style        .code:n             = { \crthm_set_name_style_Crefname:en { \l__crthm_current_env_tl } { #1 } }
    , Crefname~style        .value_required:n   = true
    , Crefname-style        .meta:n             = { Crefname~style = { #1 } }
    , Crefname-style        .value_required:n   = true
    , Crefname style        .meta:n             = { Crefname~style = { #1 } }
    , Crefname style        .value_required:n   = true
    , numbering~style       .code:n             = { \crthm_set_name_style_numbering:en { \l__crthm_current_env_tl } { #1 } }
    , numbering~style       .value_required:n   = true
    , numbering-style       .meta:n             = { numbering~style = { #1 } }
    , numbering-style       .value_required:n   = true
    , numbering style       .meta:n             = { numbering~style = { #1 } }
    , numbering style       .value_required:n   = true
    , use~name              .code:n             = { \crthm_set_name_with_existed_names:en { \l__crthm_current_env_tl } { #1 } }
    , use~name              .value_required:n   = true
    , use-name              .meta:n             = { use~name = { #1 } }
    , use-name              .value_required:n   = true
    , use name              .meta:n             = { use~name = { #1 } }
    , use name              .value_required:n   = true
    , combined              .meta:n             = { use~name = { #1 } }
    , combined              .value_required:n   = true
    , unknown               .code:n             = {}
  }

\cs_new:Nn \__crthm_set_generic:nnn
  {
    \str_if_in:nnTF { #2 } { = }
      {% key-value definition
        \keyval_parse:nnn
          {}
          { \use:c { __crthm_ #3 :nnn } { #1 } }
          { #2 }
      }
      {% simple definition
        \clist_map_inline:Nn \g_crthm_supported_language_clist
          {
            \use:c { __crthm_ #3 :nnn } { #1 } { ##1 } { #2 }
          }
      }
  }

\cs_new:Nn \crthm_set_name_heading:nn
  % #1 = env name
  % #2 = the settings
  {
    \__crthm_set_generic:nnn { #1 } { #2 } { set_name_heading }
  }
\cs_generate_variant:Nn \crthm_set_name_heading:nn { en }

\cs_new:Nn \__crthm_set_name_heading:nnn
  % #1 = env name
  % #2 = language name
  % #3 = corresponding heading name
  {
    \tl_if_exist:cF { g_crthm_style_heading_ #1 _ #2 _tl }
      {
        \tl_new:c { g_crthm_style_heading_ #1 _ #2 _tl }
      }
    \tl_gset:cn { g_crthm_name_heading_ #1 _ #2 _tl } { \tl_use:c { g_crthm_style_heading_ #1 _ #2 _tl } { #3 } }
  }

\cs_new:Nn \crthm_set_name_crefname:nn
  % #1 = env name
  % #2 = the settings
  {
    \crthm_set_name_crefname_generic:nnn { #1 } { #2 } { c }
  }
\cs_generate_variant:Nn \crthm_set_name_crefname:nn { en }

\cs_new:Nn \crthm_set_name_Crefname:nn
  % #1 = env name
  % #2 = the settings
  {
    \crthm_set_name_crefname_generic:nnn { #1 } { #2 } { C }
  }
\cs_generate_variant:Nn \crthm_set_name_Crefname:nn { en }

\cs_new:Nn \crthm_set_name_crefname_generic:nnn
  % #1 = env name
  % #2 = the settings
  % #3 = c or C
  {
    \__crthm_set_generic:nnn { #1 } { #2 } { set_name_ #3 refname }
  }

\cs_new:Nn \__crthm_set_name_crefname:nnn
  % #1 = env name
  % #2 = language name
  % #3 = corresponding crefname {..}{..} or [..]{..}[..]{..}, or a set of crefnames for different variants
  {
    \str_if_in:nnTF { #3 } { = }
      {
        \crefthe_parse_variant:n { #3 }
        \crefthe_pass_variant_to:n { \__crthm_set_name_crefname_generic:w { #1 } { #2 } } { c }
      }
      {
        \__crthm_set_name_crefname_generic:w { #1 } { #2 } #3 { c }
      }
  }

\cs_new:Nn \__crthm_set_name_Crefname:nnn
  % #1 = env name
  % #2 = language name
  % #3 = corresponding Crefname {..}{..} or [..]{..}[..]{..}, or a set of crefnames for different variants
  {
    \str_if_in:nnTF { #3 } { = }
      {
        \crefthe_parse_variant:n { #3 }
        \crefthe_pass_variant_to:n { \__crthm_set_name_crefname_generic:w { #1 } { #2 } } { C }
      }
      {
        \__crthm_set_name_crefname_generic:w { #1 } { #2 } #3 { C }
      }
  }

\NewExpandableDocumentCommand \__crthm_set_name_crefname_generic:w { m m O{} m O{} m m }
  % #1 = env name
  % #2 = language name
  % #7 = c or C
  {
    % It is assumed that when #3 is empty, so is #5
    \tl_if_blank:eTF { #3 }
      {
        \tl_gset:cn { g_crthm_core_name_ #7 ref_article_singular_ #1 _ #2 _tl } { }
        \tl_gset:cn { g_crthm_core_name_ #7 ref_article_plural_ #1 _ #2 _tl } { }
        \tl_gset:cn { g_crthm_name_ #7 ref_article_singular_ #1 _ #2 _tl } { \nobreak \crefthemark { \crefthe_retrieve_space: } \nobreak }
        \tl_gset:cn { g_crthm_name_ #7 ref_article_plural_ #1 _ #2 _tl } { \nobreak \crefthemark { \crefthe_retrieve_space: } \nobreak }
      }
      {
        \tl_gset:cn { g_crthm_core_name_ #7 ref_article_singular_ #1 _ #2 _tl } { #3 }
        \tl_gset:cn { g_crthm_core_name_ #7 ref_article_plural_ #1 _ #2 _tl } { #5 }
        \tl_gset:cn { g_crthm_name_ #7 ref_article_singular_ #1 _ #2 _tl } { \crefthemark { #3 } }
        \tl_gset:cn { g_crthm_name_ #7 ref_article_plural_ #1 _ #2 _tl } { \crefthemark { #5 } }
      }

    \tl_if_exist:cF { g_crthm_style_ #7 refname_ #1 _ #2 _tl }
      {
        \tl_new:c { g_crthm_style_ #7 refname_ #1 _ #2 _tl }
      }

    \tl_if_blank:eTF { #4 }
      {
        \tl_gset:cn { g_crthm_name_ #7 ref_singular_ #1 _ #2 _tl } { \nobreak \crefthe_retrieve_space: \nobreak }
      }
      {
        \tl_gset:cn { g_crthm_name_ #7 ref_singular_ #1 _ #2 _tl } { \tl_use:c { g_crthm_style_ #7 refname_ #1 _ #2 _tl } { #4 } }
      }

    \tl_if_blank:eTF { #6 }
      {
        \tl_gset:cn { g_crthm_name_ #7 ref_plural_ #1 _ #2 _tl } { \nobreak \crefthe_retrieve_space: \nobreak }
      }
      {
        \tl_gset:cn { g_crthm_name_ #7 ref_plural_ #1 _ #2 _tl } { \tl_use:c { g_crthm_style_ #7 refname_ #1 _ #2 _tl } { #6 } }
      }

    \bool_if:NTF \l__crthm_regionalref_bool
      {% "regionalref" mode
        \use:c { __crthm_set_name_ #7 refname_do:nnn } { #1 _crthm_regional } { #1 } { \languagename }
      }
      {% "originalref" mode
        \tl_if_exist:cF { c@ #1 _crthm_original_ #2 }
          {
            \crthm_counter_alias:nn { #1 _crthm_original_ #2 } { #1 }
            \hook_gput_code:nnn { begindocument/before } { crthm }
              {
                \cs_set_eq:cc { the #1 _crthm_original_ #2 } { the #1 }
              }
          }
        \use:c { __crthm_set_name_ #7 refname_do:nnn } { #1 _crthm_original_ #2 } { #1 } { #2 }
      }
  }

\cs_new:Nn \__crthm_set_name_crefname_do:nnn
  % #1 = counter name
  % #2 = env name
  % #3 = language name
  {
    \__crthm_set_name_crefname_do_generic:nnnn { #1 } { #2 } { #3 } { c }
  }

\cs_new:Nn \__crthm_set_name_Crefname_do:nnn
  % #1 = counter name
  % #2 = env name
  % #3 = language name
  {
    \__crthm_set_name_crefname_do_generic:nnnn { #1 } { #2 } { #3 } { C }
  }

\seq_new:N \g__crthm_format_already_set_seq

\cs_new:Nn \__crthm_set_name_crefname_do_generic:nnnn
  % #1 = counter name
  % #2 = env name
  % #3 = language name
  % #4 = c or C
  {
    \tl_gset:cn { #4 ref@ #1 @name }
      {
        \tl_use:c { g_crthm_name_ #4 ref_article_singular_ #2 _ #3 _tl }
        \bool_if:NTF \g__crefthe_has_prep_bool
          {
            \tl_use:c { g_crthm_name_ cref_singular_ #2 _ #3 _tl }
          }
          {
            \tl_use:c { g_crthm_name_ #4 ref_singular_ #2 _ #3 _tl }
          }
      }
    \tl_gset:cn { #4 ref@ #1 @name@plural }
      { % Use the definite article of the original language,
        % with name's casing depends on the preposition and the article
        \tl_use:c { g_crthm_name_ #4 ref_article_plural_ #2 _ #3 _tl }
        \bool_if:NTF \g__crefthe_has_prep_bool
          {
            \tl_use:c { g_crthm_name_ cref_plural_ #2 _ #3 _tl }
          }
          {
            \tl_use:c { g_crthm_name_ #4 ref_plural_ #2 _ #3 _tl }
          }
      }

    \seq_if_in:NnF \g__crthm_format_already_set_seq { #2 _ #3 }
      {
        \@crefdefineallformats { #1 }
        \seq_gput_right:Nn \g__crthm_format_already_set_seq { #2 _ #3 }
      }

    \tl_if_exist:cF { g_crthm_number_style_ #2 _tl }
      {
        \tl_new:c { g_crthm_number_style_ #2 _tl }
      }

    % Redefine the cref formats so that definite articles are placed outside the hyperlinks
    \crthm_modify_format_according_to_nameinlink:nnn
      { \crthm_define_format_short_version:nnnn { #2 } { #4 ref@ #1 @format } }
      { \tl_use:c { g_crthm_name_ #4 ref_article_singular_ #2 _ #3 _tl } }
      {
        \bool_if:NTF \g__crefthe_has_prep_bool
          {
            \tl_use:c { g_crthm_name_ cref_singular_ #2 _ #3 _tl }
          }
          {
            \tl_use:c { g_crthm_name_ #4 ref_singular_ #2 _ #3 _tl }
          }
      }
    \crthm_modify_format_according_to_nameinlink:nnn
      { \crthm_define_format_short_version:nnnn { #2 } { #4 ref@ #1 @format@first } }
      { \tl_use:c { g_crthm_name_ #4 ref_article_plural_ #2 _ #3 _tl } }
      {
        \bool_if:NTF \g__crefthe_has_prep_bool
          {
            \tl_use:c { g_crthm_name_ cref_plural_ #2 _ #3 _tl }
          }
          {
            \tl_use:c { g_crthm_name_ #4 ref_plural_ #2 _ #3 _tl }
          }
      }
    \cs_set:cpn { #4 ref@ #1 @format@second } ##1##2##3
      {
        \crefpairconjunction
        \group_begin:
        \crthm_format_short_generic:nnn { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##1 } } { ##2 } { ##3 }
        \group_end:
      }
    \cs_set:cpn { #4 ref@ #1 @format@middle } ##1##2##3
      {
        \crefmiddleconjunction
        \group_begin:
        \crthm_format_short_generic:nnn { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##1 } } { ##2 } { ##3 }
        \group_end:
      }
    \cs_set:cpn { #4 ref@ #1 @format@last } ##1##2##3
      {
        \creflastconjunction
        \group_begin:
        \crthm_format_short_generic:nnn { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##1 } } { ##2 } { ##3 }
        \group_end:
      }

    \crthm_modify_format_according_to_nameinlink:nnn
      { \crthm_define_format_long_version:nnnn { #2 } { #4 refrange@ #1 @format } }
      { \tl_use:c { g_crthm_name_ #4 ref_article_plural_ #2 _ #3 _tl } }
      {
        \bool_if:NTF \g__crefthe_has_prep_bool
          {
            \tl_use:c { g_crthm_name_ cref_plural_ #2 _ #3 _tl }
          }
          {
            \tl_use:c { g_crthm_name_ #4 ref_plural_ #2 _ #3 _tl }
          }
      }
    \crthm_modify_format_according_to_nameinlink:nnn
      { \crthm_define_format_long_version:nnnn { #2 } { #4 refrange@ #1 @format@first } }
      { \tl_use:c { g_crthm_name_ #4 ref_article_plural_ #2 _ #3 _tl } }
      {
        \bool_if:NTF \g__crefthe_has_prep_bool
          {
            \tl_use:c { g_crthm_name_ cref_plural_ #2 _ #3 _tl }
          }
          {
            \tl_use:c { g_crthm_name_ #4 ref_plural_ #2 _ #3 _tl }
          }
      }
    \cs_set:cpn { #4 refrange@ #1 @format@second } ##1##2##3##4##5##6
      {
        \crefpairconjunction
        \group_begin:
        \crthm_format_long_generic:nnnnnn
          { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##1 } }
          { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##2 } }
          { ##3 } { ##4 } { ##5 } { ##6 }
        \group_end:
      }
    \cs_set:cpn { #4 refrange@ #1 @format@middle } ##1##2##3##4##5##6
      {
        \crefmiddleconjunction
        \group_begin:
        \crthm_format_long_generic:nnnnnn
          { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##1 } }
          { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##2 } }
          { ##3 } { ##4 } { ##5 } { ##6 }
        \group_end:
      }
    \cs_set:cpn { #4 refrange@ #1 @format@last } ##1##2##3##4##5##6
      {
        \creflastconjunction
        \group_begin:
        \crthm_format_long_generic:nnnnnn
          { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##1 } }
          { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##2 } }
          { ##3 } { ##4 } { ##5 } { ##6 }
        \group_end:
      }

    % Redefine the labelcref formats to match the numbering format
    \cs_set:cpn { labelcref@ #1 @format } ##1##2##3
      {
        \group_begin:
        \crthm_format_short_generic:nnn { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##1 } } { ##2 } { ##3 }
        \group_end:
      }
    \cs_set_eq:cc { labelcref@ #1 @format@first } { labelcref@ #1 @format }
    \cs_set:cpn { labelcref@ #1 @format@second } ##1##2##3
      {
        \crefpairconjunction
        \group_begin:
        \crthm_format_short_generic:nnn { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##1 } } { ##2 } { ##3 }
        \group_end:
      }
    \cs_set:cpn { labelcref@ #1 @format@middle } ##1##2##3
      {
        \crefmiddleconjunction
        \group_begin:
        \crthm_format_short_generic:nnn { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##1 } } { ##2 } { ##3 }
        \group_end:
      }
    \cs_set:cpn { labelcref@ #1 @format@last } ##1##2##3
      {
        \creflastconjunction
        \group_begin:
        \crthm_format_short_generic:nnn { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##1 } } { ##2 } { ##3 }
        \group_end:
      }

    \crthm_define_format_long_version:nnnn { #2 } { labelcrefrange@ #1 @format } {} {}
    \crthm_define_format_long_version:nnnn { #2 } { labelcrefrange@ #1 @format@first } {} {}
    \cs_set:cpn { labelcrefrange@ #1 @format@second } ##1##2##3##4##5##6
      {
        \crefpairconjunction
        \group_begin:
        \crthm_format_long_generic:nnnnnn
          { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##1 } }
          { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##2 } }
          { ##3 } { ##4 } { ##5 } { ##6 }
        \group_end:
      }
    \cs_set:cpn { labelcrefrange@ #1 @format@middle } ##1##2##3##4##5##6
      {
        \crefmiddleconjunction
        \group_begin:
        \crthm_format_long_generic:nnnnnn
          { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##1 } }
          { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##2 } }
          { ##3 } { ##4 } { ##5 } { ##6 }
        \group_end:
      }
    \cs_set:cpn { labelcrefrange@ #1 @format@last } ##1##2##3##4##5##6
      {
        \creflastconjunction
        \group_begin:
        \crthm_format_long_generic:nnnnnn
          { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##1 } }
          { \tl_use:c { g_crthm_number_style_ #2 _tl } { ##2 } }
          { ##3 } { ##4 } { ##5 } { ##6 }
        \group_end:
      }
  }

\cs_new:Nn \crthm_modify_format_according_to_nameinlink:nnn
  % #1 = the macro (and argument) to be used
  % #2 = content always before the hyperlink beginning mark
  % #3 = content before or after the hyperlink beginning mark, depending on whether nameinlink=true
  {
    \bool_if:NTF \l__crthm_nameinlink_bool
      {
        #1 { #2 } { #3 }
      }
      {
        #1 { #2 #3 \nobreakspace } { }
      }
  }

\cs_new:Nn \crthm_define_format_short_version:nnnn
  % #1 = name of the environment
  % #2 = name of the format command
  % #3 = content before the hyperlink beginning mark
  % #4 = content after the hyperlink beginning mark
  {
    \cs_if_exist:cF { crthm_format_ #2 :nnn }
      {
        \cs_new:cn { crthm_format_ #2 :nnn }
          {
            { #3 } ##2 { #4 }
            \tl_if_blank:nF { #4 } { \nobreakspace }
            { \tl_use:c { g_crthm_number_style_ #1 _tl } { ##1 } } ##3
          }
        \cs_set_eq:cc { #2 } { crthm_format_ #2 :nnn }
      }
  }
\cs_new:Nn \crthm_define_format_long_version:nnnn
  % #1 = name of the environment
  % #2 = name of the format command
  % #3 = content before the hyperlink beginning mark
  % #4 = content after the hyperlink beginning mark
  {
    \cs_if_exist:cF { crthm_format_ #2 :nnnnnn }
      {
        \cs_new:cn { crthm_format_ #2 :nnnnnn }
          {
            { #3 } ##3 { #4 }
            \tl_if_blank:nF { #4 } { \nobreakspace } \crefrangepreconjunction
            { \tl_use:c { g_crthm_number_style_ #1 _tl } { ##1 } }
            ##4 \crefrangeconjunction
            ##5 { \tl_use:c { g_crthm_number_style_ #1 _tl } { ##2 } } ##6
            \crefrangepostconjunction
          }
        \cs_set_eq:cc { #2 } { crthm_format_ #2 :nnnnnn }
      }
  }

\cs_new:Nn \crthm_format_short_generic:nnn
  {
    #2 { #1 } #3
  }
\cs_new:Nn \crthm_format_long_generic:nnnnnn
  {
    \crefrangepreconjunction
    #3 { #1 } #4
    \crefrangeconjunction
    #5 { #2 } #6
    \crefrangepostconjunction
  }


\cs_new:Nn \crthm_set_name_style_heading:nn
  % #1 = env name
  % #2 = the settings
  {
    \__crthm_set_generic:nnn { #1 } { #2 } { set_name_style_heading }
  }
\cs_generate_variant:Nn \crthm_set_name_style_heading:nn { en }

\cs_new:Nn \__crthm_set_name_style_heading:nnn
  % #1 = env name
  % #2 = language name
  % #3 = corresponding heading style
  {
    \tl_gset:cn { g_crthm_style_heading_ #1 _ #2 _tl } { \normalfont #3 }
  }

\cs_new:Nn \crthm_set_name_style_crefname:nn
  % #1 = env name
  % #2 = the settings
  {
    \__crthm_set_generic:nnn { #1 } { #2 } { set_name_style_crefname }
  }
\cs_generate_variant:Nn \crthm_set_name_style_crefname:nn { en }

\cs_new:Nn \__crthm_set_name_style_crefname:nnn
  % #1 = env name
  % #2 = language name
  % #3 = corresponding crefname style
  {
    \tl_gset:cn { g_crthm_style_crefname_ #1 _ #2 _tl } { \normalfont #3 }
  }

\cs_new:Nn \crthm_set_name_style_Crefname:nn
  % #1 = env name
  % #2 = the settings
  {
    \__crthm_set_generic:nnn { #1 } { #2 } { set_name_style_Crefname }
  }
\cs_generate_variant:Nn \crthm_set_name_style_Crefname:nn { en }

\cs_new:Nn \__crthm_set_name_style_Crefname:nnn
  % #1 = env name
  % #2 = language name
  % #3 = corresponding Crefname style
  {
    \tl_gset:cn { g_crthm_style_Crefname_ #1 _ #2 _tl } { \normalfont #3 }
  }

\cs_new:Nn \crthm_set_name_style_numbering:nn
  % #1 = env name
  % #2 = the settings
  {
    \__crthm_set_generic:nnn { #1 } { #2 } { set_name_style_numbering }
  }
\cs_generate_variant:Nn \crthm_set_name_style_numbering:nn { en }

\cs_new:Nn \__crthm_set_name_style_numbering:nnn
  % #1 = env name
  % #2 = language name
  % #3 = corresponding numbering style
  {
    \tl_gset:cn { g_crthm_number_style_ #1 _tl } { \normalfont #3 }
  }


\tl_new:N   \g_crthm_combined_name_sep_tl
\tl_gset:Nn \g_crthm_combined_name_sep_tl { - }

\cs_new:Nn \crthm_set_name_with_existed_names:nn
  % #1 = env name
  % #2 = list of existed environments
  {
    \clist_map_inline:Nn \g_crthm_supported_language_clist
      { % ##1 = language name
        \seq_gclear_new:c { g_crthm_name_heading_ #1 _ ##1 _seq }
        \seq_gclear_new:c { g_crthm_name_cref_article_singular_ #1 _ ##1 _seq }
        \seq_gclear_new:c { g_crthm_name_cref_article_plural_ #1 _ ##1 _seq }
        \seq_gclear_new:c { g_crthm_name_cref_singular_ #1 _ ##1 _seq }
        \seq_gclear_new:c { g_crthm_name_cref_plural_ #1 _ ##1 _seq }
        \seq_gclear_new:c { g_crthm_name_Cref_article_singular_ #1 _ ##1 _seq }
        \seq_gclear_new:c { g_crthm_name_Cref_article_plural_ #1 _ ##1 _seq }
        \seq_gclear_new:c { g_crthm_name_Cref_singular_ #1 _ ##1 _seq }
        \seq_gclear_new:c { g_crthm_name_Cref_plural_ #1 _ ##1 _seq }
        \bool_set_true:N \l_tmpa_bool
        \regex_split:nnN { \s* ; \s* } { #2 } { \l_tmpa_seq }
        \seq_map_inline:Nn \l_tmpa_seq
          { % ####1 = existed environments
            % Here we use the definite article of the last environment as that of the combined environment
            % Uncomment the lines below if you wish to use the definite article of the first environment
            % \bool_if:NT \l_tmpa_bool
            %   {
                \tl_gset_eq:cc { g_crthm_saved_name_cref_article_singular_ #1 _ ##1 _tl } { g_crthm_core_name_cref_article_singular_ ####1 _ ##1 _tl }
                \tl_gset_eq:cc { g_crthm_saved_name_cref_article_plural_ #1 _ ##1 _tl } { g_crthm_core_name_cref_article_plural_ ####1 _ ##1 _tl }
                \tl_gset_eq:cc { g_crthm_saved_name_Cref_article_singular_ #1 _ ##1 _tl } { g_crthm_core_name_Cref_article_singular_ ####1 _ ##1 _tl }
                \tl_gset_eq:cc { g_crthm_saved_name_Cref_article_plural_ #1 _ ##1 _tl } { g_crthm_core_name_Cref_article_plural_ ####1 _ ##1 _tl }
            %     \bool_set_false:N \l_tmpa_bool
            %   }
            \seq_gput_right:cn { g_crthm_name_heading_ #1 _ ##1 _seq } { \tl_use:c { g_crthm_name_heading_ ####1 _ ##1 _tl } }
            \seq_gput_right:cn { g_crthm_name_cref_singular_ #1 _ ##1 _seq } { \tl_use:c { g_crthm_name_cref_singular_ ####1 _ ##1 _tl } }
            \seq_gput_right:cn { g_crthm_name_cref_plural_ #1 _ ##1 _seq } { \tl_use:c { g_crthm_name_cref_plural_ ####1 _ ##1 _tl } }
            \seq_gput_right:cn { g_crthm_name_Cref_singular_ #1 _ ##1 _seq } { \tl_use:c { g_crthm_name_Cref_singular_ ####1 _ ##1 _tl } }
            \seq_gput_right:cn { g_crthm_name_Cref_plural_ #1 _ ##1 _seq } { \tl_use:c { g_crthm_name_Cref_plural_ ####1 _ ##1 _tl } }
            % set the numbering style to be the same as the last environment
            \tl_gset_eq:cc { g_crthm_number_style_ #1 _tl } { g_crthm_number_style_ ####1 _tl }
          }
        % set heading name for the combined environment
        \tl_gset:cn { g_crthm_name_heading_ #1 _ ##1 _tl } { \seq_use:cn { g_crthm_name_heading_ #1 _ ##1 _seq } { \g_crthm_combined_name_sep_tl } }
        % set crefname for the combined environment
        \tl_if_empty:cTF { g_crthm_saved_name_cref_article_singular_ #1 _ ##1 _tl }
          {
            \__crthm_set_name_crefname:nnn { #1 } { ##1 }
              {
                { \seq_use:cn { g_crthm_name_cref_singular_ #1 _ ##1 _seq } { \g_crthm_combined_name_sep_tl } }
                { \seq_use:cn { g_crthm_name_cref_plural_ #1 _ ##1 _seq } { \g_crthm_combined_name_sep_tl } }
              }
          }
          {
            \__crthm_set_name_crefname:nnn { #1 } { ##1 }
              {
                [ \tl_use:c { g_crthm_saved_name_cref_article_singular_ #1 _ ##1 _tl } ]
                { \seq_use:cn { g_crthm_name_cref_singular_ #1 _ ##1 _seq } { \g_crthm_combined_name_sep_tl } }
                [ \tl_use:c { g_crthm_saved_name_cref_article_plural_ #1 _ ##1 _tl } ]
                { \seq_use:cn { g_crthm_name_cref_plural_ #1 _ ##1 _seq } { \g_crthm_combined_name_sep_tl } }
              }
          }
        % set Crefname for the combined environment
        \tl_if_empty:cTF { g_crthm_saved_name_Cref_article_singular_ #1 _ ##1 _tl }
          {
            \__crthm_set_name_Crefname:nnn { #1 } { ##1 }
              {
                { \seq_use:cn { g_crthm_name_Cref_singular_ #1 _ ##1 _seq } { \g_crthm_combined_name_sep_tl } }
                { \seq_use:cn { g_crthm_name_Cref_plural_ #1 _ ##1 _seq } { \g_crthm_combined_name_sep_tl } }
              }
          }
          {
            \__crthm_set_name_Crefname:nnn { #1 } { ##1 }
              {
                [ \tl_use:c { g_crthm_saved_name_Cref_article_singular_ #1 _ ##1 _tl } ]
                { \seq_use:cn { g_crthm_name_Cref_singular_ #1 _ ##1 _seq } { \g_crthm_combined_name_sep_tl } }
                [ \tl_use:c { g_crthm_saved_name_Cref_article_plural_ #1 _ ##1 _tl } ]
                { \seq_use:cn { g_crthm_name_Cref_plural_ #1 _ ##1 _seq } { \g_crthm_combined_name_sep_tl } }
              }
          }
      }
  }
\cs_generate_variant:Nn \crthm_set_name_with_existed_names:nn { en }


\NewDocumentCommand \NameTheorem { m m }
  {
    \crthm_name_theorem:nn { #1 } { #2 }
  }

\cs_new:Nn \crthm_name_theorem:nn
  {
    \tl_set:Nn \l__crthm_current_env_tl { #1 }
    \cs_if_exist:cF { c@ #1 }
      {
        \newcounter { #1 }
      }
    \keys_set:nn { create-theorem-naming } { #2 }
  }


\tl_new:N \l__crthm_current_lang_tl

\keys_define:nn { create-theorem-naming-per-language }
  {
    , heading               .code:n             = { \crthm_set_name_per_lang_heading:en { \l__crthm_current_lang_tl } { #1 } }
    , heading               .value_required:n   = true
    , crefname              .code:n             = { \crthm_set_name_per_lang_crefname:en { \l__crthm_current_lang_tl } { #1 } }
    , crefname              .value_required:n   = true
    , Crefname              .code:n             = { \crthm_set_name_per_lang_Crefname:en { \l__crthm_current_lang_tl } { #1 } }
    , Crefname              .value_required:n   = true
    , unknown               .code:n             = {}
  }

\cs_new:Nn \crthm_set_name_per_lang_heading:nn
  % #1 = language name
  % #2 = the settings
  {
    \keyval_parse:nnn
      {}
      { \use:c { __crthm_set_name_per_lang_heading:nnn } { #1 } }
      { #2 }
  }
\cs_generate_variant:Nn \crthm_set_name_per_lang_heading:nn { en }

\cs_new:Nn \__crthm_set_name_per_lang_heading:nnn
  % #1 = language name
  % #2 = env name
  % #3 = corresponding heading name
  {
    \tl_if_exist:cF { g_crthm_style_heading_ #2 _ #1 _tl }
      {
        \tl_new:c { g_crthm_style_heading_ #2 _ #1 _tl }
      }
    \tl_gset:cn { g_crthm_name_heading_ #2 _ #1 _tl } { \tl_use:c { g_crthm_style_heading_ #2 _ #1 _tl } { #3 } }
  }

\cs_new:Nn \crthm_set_name_per_lang_crefname:nn
  % #1 = language name
  % #2 = the settings
  {
    \crthm_set_name_per_lang_crefname_generic:nnn { #1 } { #2 } { c }
  }
\cs_generate_variant:Nn \crthm_set_name_per_lang_crefname:nn { en }

\cs_new:Nn \crthm_set_name_per_lang_Crefname:nn
  % #1 = language name
  % #2 = the settings
  {
    \crthm_set_name_per_lang_crefname_generic:nnn { #1 } { #2 } { C }
  }
\cs_generate_variant:Nn \crthm_set_name_per_lang_Crefname:nn { en }

\cs_new:Nn \crthm_set_name_per_lang_crefname_generic:nnn
  % #1 = language name
  % #2 = the settings
  % #3 = c or C
  {
    \keyval_parse:nnn
      {}
      { \use:c { __crthm_set_name_per_lang_ #3 refname:nnn } { #1 } }
      { #2 }
  }

\cs_new:Nn \__crthm_set_name_per_lang_crefname:nnn
  % #1 = language name
  % #2 = env name
  % #3 = corresponding crefname {..}{..} or [..]{..}[..]{..}, or a set of crefnames for different variants
  {
    \str_if_in:nnTF { #3 } { = }
      {
        \crefthe_parse_variant:n { #3 }
        \crefthe_pass_variant_to:n { \__crthm_set_name_crefname_generic:w { #2 } { #1 } } { c }
      }
      {
        \__crthm_set_name_crefname_generic:w { #2 } { #1 } #3 { c }
      }
  }

\cs_new:Nn \__crthm_set_name_per_lang_Crefname:nnn
  % #1 = language name
  % #2 = env name
  % #3 = corresponding Crefname {..}{..} or [..]{..}[..]{..}, or a set of crefnames for different variants
  {
    \str_if_in:nnTF { #3 } { = }
      {
        \crefthe_parse_variant:n { #3 }
        \crefthe_pass_variant_to:n { \__crthm_set_name_crefname_generic:w { #2 } { #1 } } { C }
      }
      {
        \__crthm_set_name_crefname_generic:w { #2 } { #1 } #3 { C }
      }
  }


\NewDocumentCommand \NameTheorems { m m }
  {
    \crthm_name_theorems:nn { #1 } { #2 }
  }

\cs_new:Nn \crthm_name_theorems:nn
  {
    \tl_set:Nn \l__crthm_current_lang_tl { #1 }
    \crthm_add_to_language_list:n { #1 }
    \keys_set:nn { create-theorem-naming-per-language } { #2 }
  }


\tl_const:Nn \c__crthm_qedsymbol_tl { \Box }
\bool_new:N \l__crthm_creating_qed_bool
\tl_new:N   \l__crthm_creating_qed_tl
\bool_new:N \l__crthm_creating_apply_style_bool
\tl_new:N   \l__crthm_creating_apply_style_tl
\bool_new:N \l__crthm_creating_numberless_bool
\bool_new:N \l__crthm_creating_create_starred_bool
\bool_new:N \l__crthm_creating_copy_existed_bool
\tl_new:N   \l__crthm_creating_copy_existed_tl
\keys_define:nn { create-theorem-creating }
  {
    , name                        .code:n             = { \exp_args:Ne \NameTheorem { \l__crthm_current_env_tl } { #1 } }
    , name                        .value_required:n   = true
    , name~style                  .code:n             = { \exp_args:Ne \NameTheorem { \l__crthm_current_env_tl } { #1 } }
    , name~style                  .value_required:n   = true
    , name-style                  .meta:n             = { name~style = { #1 } }
    , name-style                  .value_required:n   = true
    , name style                  .meta:n             = { name~style = { #1 } }
    , name style                  .value_required:n   = true
    , use~name                    .code:n             = { \exp_args:Ne \NameTheorem { \l__crthm_current_env_tl } { use~name = #1 } }
    , use~name                    .value_required:n   = true
    , use-name                    .meta:n             = { use~name = { #1 } }
    , use-name                    .value_required:n   = true
    , use name                    .meta:n             = { use~name = { #1 } }
    , use name                    .value_required:n   = true
    , combined                    .meta:n             = { use~name = { #1 } }
    , combined                    .value_required:n   = true
    , style                       .code:n             = { \bool_set_true:N \l__crthm_creating_apply_style_bool
                                                          \tl_set:Nn \l__crthm_creating_apply_style_tl { #1 }  }
    , style                       .value_required:n   = true
    , apply~style                 .meta:n             = { style = { #1 } }
    , apply~style                 .value_required:n   = true
    , apply-style                 .meta:n             = { style = { #1 } }
    , apply-style                 .value_required:n   = true
    , apply style                 .meta:n             = { style = { #1 } }
    , apply style                 .value_required:n   = true
    , qed                         .code:n             = { \bool_set_true:N \l__crthm_creating_qed_bool
                                                          \tl_set:Nn \l__crthm_creating_qed_tl { #1 }  }
    , qed                         .default:n          = \c__crthm_qedsymbol_tl
    , qed~symbol                  .meta:n             = { qed = #1 }
    , qed~symbol                  .default:n          = \c__crthm_qedsymbol_tl
    , qed-symbol                  .meta:n             = { qed = #1 }
    , qed-symbol                  .default:n          = \c__crthm_qedsymbol_tl
    , qed symbol                  .meta:n             = { qed = #1 }
    , qed symbol                  .default:n          = \c__crthm_qedsymbol_tl
    , numberless                  .bool_set:N         = \l__crthm_creating_numberless_bool
    , create~starred~version      .bool_set:N         = \l__crthm_creating_create_starred_bool
    , create-starred-version      .meta:n             = { create~starred~version }
    , create starred version      .meta:n             = { create~starred~version }
    , create~numberless~version   .meta:n             = { create~starred~version }
    , create-numberless-version   .meta:n             = { create~starred~version }
    , create numberless version   .meta:n             = { create~starred~version }
    , copy~existed                .code:n             = { \bool_set_true:N \l__crthm_creating_copy_existed_bool
                                                          \tl_set:Nn \l__crthm_creating_copy_existed_tl { #1 }  }
    , copy~existed                .value_required:n   = true
    , copy-existed                .meta:n             = { copy~existed = { #1 } }
    , copy-existed                .value_required:n   = true
    , copy existed                .meta:n             = { copy~existed = { #1 } }
    , copy existed                .value_required:n   = true
    , quiet                       .bool_set:N         = \l__crthm_creating_quiet_bool
    , quiet                       .initial:n          = { false }
    , unknown                     .code:n             = {}
  }

\keys_define:nn { create-theorem-creating / counter-management }
  {
    , parent~counter              .code:n             = { \crthm_counter_within:en { \l__crthm_current_env_tl } { #1 } }
    , parent~counter              .value_required:n   = true
    , parent-counter              .meta:n             = { parent~counter = { #1 } }
    , parent-counter              .value_required:n   = true
    , parent counter              .meta:n             = { parent~counter = { #1 } }
    , parent counter              .value_required:n   = true
    , number~within               .meta:n             = { parent~counter = { #1 } }
    , number~within               .value_required:n   = true
    , number-within               .meta:n             = { parent~counter = { #1 } }
    , number-within               .value_required:n   = true
    , number within               .meta:n             = { parent~counter = { #1 } }
    , number within               .value_required:n   = true
    , shared~counter              .code:n             = { \crthm_counter_alias:en { \l__crthm_current_env_tl } { #1 } }
    , shared~counter              .value_required:n   = true
    , shared-counter              .meta:n             = { shared~counter = { #1 } }
    , shared-counter              .value_required:n   = true
    , shared counter              .meta:n             = { shared~counter = { #1 } }
    , shared counter              .value_required:n   = true
    , number~like                 .meta:n             = { shared~counter = { #1 } }
    , number~like                 .value_required:n   = true
    , number-like                 .meta:n             = { shared~counter = { #1 } }
    , number-like                 .value_required:n   = true
    , number like                 .meta:n             = { shared~counter = { #1 } }
    , number like                 .value_required:n   = true
    , unknown                     .code:n             = {}
  }


\NewDocumentCommand \CreateTheorem { m m }
  {
    \clist_map_inline:nn { #1 }
      {
        \crthm_create_theorem:nn { ##1 } { #2 }
      }
  }

\msg_new:nnn { create-theorem }
  { env-not-created }
  { The~theorem-like~environment~"#1"~cannot~be~created,~an~environment~with~the~same~name~has~already~existed. }

\msg_new:nnn { create-theorem }
  { env-not-named }
  { The~theorem-like~environment~"#1"~cannot~be~created,~you~have~to~name~it~before~initialization. }

\cs_new:Nn \crthm_create_theorem:nn
  % #1 = env name
  % #2 = options
  {
    \tl_set:Nn \l__crthm_current_env_tl { #1 }
    \bool_set_false:N \l__crthm_creating_apply_style_bool
    \bool_set_false:N \l__crthm_creating_numberless_bool
    \bool_set_false:N \l__crthm_creating_qed_bool
    \bool_set_false:N \l__crthm_creating_create_starred_bool
    \bool_set_false:N \l__crthm_creating_copy_existed_bool
    \keys_set:nn { create-theorem-creating } { #2 }
    \bool_if:NTF \l__crthm_creating_copy_existed_bool
      {
        \__crthm_copy_env:ee { \l__crthm_current_env_tl } { \l__crthm_creating_copy_existed_tl }
        \bool_if:NT \l__crthm_creating_create_starred_bool
          {
            \__crthm_copy_env:ee { \l__crthm_current_env_tl * } { \l__crthm_creating_copy_existed_tl * }
          }
      }
      {
        \cs_if_exist:cTF { #1 }
          {
            \bool_if:NF \l__crthm_creating_quiet_bool
              {
                \msg_warning:nnn  { create-theorem } { env-not-created } { #1 }
              }
          }
          {
            \cs_if_exist:cTF { c@ #1 }
              {
                \IfPackageLoadedTF { ntheorem }
                  {
                    \bool_if:NT \l__crthm_creating_qed_bool
                      {
                        \theoremsymbol { \ensuremath { \l__crthm_creating_qed_tl } }
                      }
                  } {}
                \group_begin:
                \bool_if:NTF \l__crthm_creating_apply_style_bool
                  {
                    \exp_args:No \theoremstyle { \l__crthm_creating_apply_style_tl }
                  }
                  {
                    \tl_if_exist:cT { c_crthm_theorem_style_preset_ #1 _tl }
                      {
                        \exp_args:Nv \theoremstyle { c_crthm_theorem_style_preset_ #1 _tl }
                      }
                  }
                \bool_if:NTF \l__crthm_creating_numberless_bool
                  {
                    \crthm_newtheorem:w*{ #1 _crthm_regional } { \tl_use:c { g_crthm_name_heading_ #1 _ \languagename _tl } }
                  }
                  {
                    \crthm_newtheorem:w { #1 _crthm_regional } [#1] { \tl_use:c { g_crthm_name_heading_ #1 _ \languagename _tl } }
                  }
                \bool_if:NT \l__crthm_creating_create_starred_bool
                  {
                    \crthm_newtheorem:w*{ #1 * } { \tl_use:c { g_crthm_name_heading_ #1 _ \languagename _tl } }
                  }
                \group_end:
                \IfPackageLoadedTF { ntheorem }
                  {
                    \bool_if:NT \l__crthm_creating_qed_bool
                      {
                        \theoremsymbol { }
                      }
                  } {}
                \NewDocumentEnvironment { #1 } { O{} }
                  % In "regionalref" mode, the counter received by the referencing system is "#1 _crthm_regional"
                  % while in "originalref" mode, the counter received is "#1 _crthm_original_\languagename"
                  {
                    \tl_if_blank:nTF { ##1 }
                      {
                        \begin{ #1 _crthm_regional }
                      }
                      {
                        \begin{ #1 _crthm_regional }[{##1}]
                      }
                      \bool_if:NF \l__crthm_regionalref_bool
                        {
                          \addtocounter   { #1 _crthm_original_\languagename } { -1 }
                          \refstepcounter { #1 _crthm_original_\languagename }
                        }
                  }
                  {
                    \end{ #1 _crthm_regional }
                  }
                \keys_set:nn { create-theorem-creating / counter-management } { #2 }

                \IfPackageLoadedTF { amsthm }
                  {
                    \bool_if:NT \l__crthm_creating_qed_bool
                      {
                        \exp_args:Nx \hook_gput_code:nnn { env/ \l__crthm_current_env_tl /begin } { crthm } { \cs_set:Npn \qedsymbol { \ensuremath { \l__crthm_creating_qed_tl } } \pushQED{\qed} }
                        \exp_args:Nx \hook_gput_code:nnn { env/ \l__crthm_current_env_tl /end } { crthm } { \popQED }
                        \bool_if:NT \l__crthm_creating_create_starred_bool
                          {
                            \exp_args:Nx \hook_gput_code:nnn { env/ \l__crthm_current_env_tl * /begin } { crthm } { \cs_set:Npn \qedsymbol { \ensuremath { \l__crthm_creating_qed_tl } } \pushQED{\qed} }
                            \exp_args:Nx \hook_gput_code:nnn { env/ \l__crthm_current_env_tl * /end } { crthm } { \popQED }
                          }
                      }
                  } {}
              }
              {
                \msg_error:nnn  { create-theorem } { env-not-named } { #1 }
              }
          }
      }
  }

\cs_new:Nn \__crthm_copy_env:nn
  {
    \cs_set_eq:cc { #1 } { #2 }
    \cs_set_eq:cc { end #1 } { end #2 }
  }
\cs_generate_variant:Nn \__crthm_copy_env:nn { ee }

\cs_new:Nn \crthm_counter_within:nn
  {
    \counterwithin { #1 } { #2 }
  }
\cs_generate_variant:Nn \crthm_counter_within:nn { en }

\cs_new:Nn \crthm_counter_alias:nn
  {
    \cs_if_exist:cTF { c@ #2 }
      {
        \cs_gset_eq:cc { c@ #1 } { c@ #2 }
        \cs_gset_eq:cc { the #1 } { the #2 }
        \cs_gset_eq:cc { theH #1 } { theH #2 }
        \cs_gset_eq:cc { p@ #1 } { p@ #2 }
        \cs_gset_eq:cc { cl@ #1 } { cl@ #2 }
      }
      {
        \@nocounterr { #2 }
      }
  }
\cs_generate_variant:Nn \crthm_counter_alias:nn { en }


\keys_define:nn { create-theorem-setting }
  {
    , name                        .code:n             = { \exp_args:Ne \NameTheorem { \l__crthm_current_env_tl } { #1 } }
    , name                        .value_required:n   = true
    , name~style                  .code:n             = { \exp_args:Ne \NameTheorem { \l__crthm_current_env_tl } { #1 } }
    , name~style                  .value_required:n   = true
    , name-style                  .meta:n             = { name~style = { #1 } }
    , name-style                  .value_required:n   = true
    , name style                  .meta:n             = { name~style = { #1 } }
    , name style                  .value_required:n   = true
    , qed                         .code:n             = {
                                                          \exp_args:Nx \hook_gput_code:nnn { env/ \l__crthm_current_env_tl /begin } { crthm } { \cs_set:Npn \qedsymbol { \ensuremath { #1 } } }
                                                        }
    , qed                         .default:n          = \c__crthm_qedsymbol_tl
    , qed~symbol                  .meta:n             = { qed = #1 }
    , qed~symbol                  .default:n          = \c__crthm_qedsymbol_tl
    , qed-symbol                  .meta:n             = { qed = #1 }
    , qed-symbol                  .default:n          = \c__crthm_qedsymbol_tl
    , qed symbol                  .meta:n             = { qed = #1 }
    , qed symbol                  .default:n          = \c__crthm_qedsymbol_tl
    , parent~counter              .code:n             = { \crthm_counter_within:en { \l__crthm_current_env_tl } { #1 } }
    , parent~counter              .value_required:n   = true
    , parent-counter              .meta:n             = { parent~counter = { #1 } }
    , parent-counter              .value_required:n   = true
    , parent counter              .meta:n             = { parent~counter = { #1 } }
    , parent counter              .value_required:n   = true
    , number~within               .meta:n             = { parent~counter = { #1 } }
    , number~within               .value_required:n   = true
    , number-within               .meta:n             = { parent~counter = { #1 } }
    , number-within               .value_required:n   = true
    , number within               .meta:n             = { parent~counter = { #1 } }
    , number within               .value_required:n   = true
    , shared~counter              .code:n             = { \crthm_counter_alias:en { \l__crthm_current_env_tl } { #1 } }
    , shared~counter              .value_required:n   = true
    , shared-counter              .meta:n             = { shared~counter = { #1 } }
    , shared-counter              .value_required:n   = true
    , shared counter              .meta:n             = { shared~counter = { #1 } }
    , shared counter              .value_required:n   = true
    , number~like                 .meta:n             = { shared~counter = { #1 } }
    , number~like                 .value_required:n   = true
    , number-like                 .meta:n             = { shared~counter = { #1 } }
    , number-like                 .value_required:n   = true
    , number like                 .meta:n             = { shared~counter = { #1 } }
    , number like                 .value_required:n   = true
    , unknown                     .code:n             = {}
  }


\NewDocumentCommand \SetTheorem { m m }
  {
    \clist_map_inline:nn { #1 }
      {
        \prop_if_in:NnTF \l_crthm_binding_prop { ##1 }
          {
            \prop_get:NnN \l_crthm_binding_prop { ##1 } \l__crthm_current_env_tl
          }
          {
            \tl_set:Nn \l__crthm_current_env_tl { ##1 }
          }
        \keys_set:nn { create-theorem-setting } { #2 }
      }
  }

\prop_new:N \l_crthm_binding_prop
\NewDocumentCommand \SetTheoremBinding { m m }
  {
    \clist_map_inline:nn { #1 }
      {
        \prop_put:Nxx \l_crthm_binding_prop { ##1 } { #2 }
      }
  }

% Load predefined namesets
\bool_if:NT \l__crthm_presetname_bool
  {
    \input { create-theorem-preset-names-cleveref }
    \input { create-theorem-preset-names-plural-cleveref }
  }

\endinput
%%
%% End of file `create-theorem.sty'.