%%%%%%%%%%%%%%%%%%%%%% pdfmanagement-testphase %%%%%%%%%%%%%%%%%%%
\newif\if@ocgxii@testphase
\ExplSyntaxOn
\bool_if:nTF{
  \bool_lazy_and_p:nn {\cs_if_exist_p:N \pdfmanagement_if_active_p:} { \pdfmanagement_if_active_p: }
}{\@ocgxii@testphasetrue}{
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  % ocgx2.sty
  %
  % Copyright 2015--\today, Alexander Grahn
  %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  % The intent of this package is to be a drop-in replacement for the already
  % existing CTAN package `ocgx' by Paul Gaborit, and also for `ocg-p' and `ocg'.
  %
  % It re-implements the functionality of the ocg, ocgx and ocg-p packages
  % and adds support for all known engines and backends including
  % latex+dvips+ps2pdf, xelatex, latex+dvipdfmx, lualatex.
  %
  % With ocgx2, PDF layers may extend across page breaks.
  %
  % ocgx2 implements OCMDs (optional content membership dictionaries)
  %
  % Adds some minor improvements, such as package options, remembering option.
  % settings of reopened ocgs, correct behaviour of ocg switching links that were
  % themselves placed on layers, compatibility with the animate and media9
  % packages.
  %
  % Re-implements hyperref's `ocgcolorlinks' option to produce coloured links
  % that may wrap around line breaks and page breaks.
  %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  % This work may be distributed and/or modified under the
  % conditions of the LaTeX Project Public License.
  %
  % The latest version of this license is in
  %   http://mirrors.ctan.org/macros/latex/base/lppl.txt
  %
  % This work has the LPPL maintenance status `maintained'.
  %
  % The Current Maintainer of this work is A. Grahn.

  \def\g@ocgxii@date@tl{2022/12/16}
  \def\g@ocgxii@version@tl{0.56}

  \ProvidesExplPackage{ocgx2}{\g@ocgxii@date@tl}{\g@ocgxii@version@tl}
  {ports `ocgx' functionality to dvips+ps2pdf, xelatex and dvipdfmx}

  %creating global definitions
  \cs_new_protected:Npn\ocgxii@newkey#1#2{\tl_gset:cx{#1}{#2}}
  \cs_new_protected:Npn\ocgxii@newkeynoexp#1#2{\tl_gset:cn{#1}{#2}}

  \AtBeginDocument{
    \iow_now:Nx\@mainaux{
      \token_to_str:N\providecommand\token_to_str:N\ocgxii@newkey[2]{}
    }
    \iow_now:Nx\@mainaux{
      \token_to_str:N\providecommand\token_to_str:N\ocgxii@newkeynoexp[2]{}
    }
    \iow_now:Nx\@mainaux{
      \token_to_str:N\providecommand\token_to_str:N\ocgxii@ocg@stack@on@page[2]{}
    }
    \iow_now:Nx\@mainaux{
      \token_to_str:N\providecommand
        \token_to_str:N\ocgxii@lnkcol@stack@on@page[2]{}
    }
  }

  \msg_set:nnn{ocgx2}{generic~msg}{#1\\#2}

  \msg_set:nnn{ocgx2}{missing~package}{
    Package~`#1'~must~be~loaded~before~ocgx2.\\\\
    Put\\\\
    \space\space\string\usepackage#2{#1}\\
    \space\space\string\usepackage[ocgcolorlinks]{ocgx2}\\\\
    to~the~preamble~of~your~document.
  }

  \msg_set:nnn{ocgx2}{beamer~and~ocgcolorlinks}{
    Option~`ocgcolorlinks'~cannot~be~used~with~class~Beamer.\\\\
    Using~`colorlinks'~instead.
  }

  % package options

  \msg_set:nnnn{ocgx2}{unknown~package~option}{Unknown~package~option~`#1'.}{
    Package option~'#1'~is~unknown;\\
    perhaps~it~is~spelled~incorrectly.
  }

  \bool_new:N\g_ocgxii_dvipdfmx_bool
  \bool_new:N\l_ocgxii_tikz_bool
  \bool_new:N\l_ocgxii_ocgcolorlinks_bool
  \bool_new:N\g_ocgxii_showingui_bool
  \bool_new:N\l_ocgxii_showingui_bool

  \keys_define:nn{ocgx2}{
    pdftex.code:n = {},
    pdftex.value_forbidden:n = true,

    luatex.code:n = {},
    luatex.value_forbidden:n = true,

    xetex.code:n = {},
    xetex.value_forbidden:n = true,

    dvips.code:n = {},
    dvips.value_forbidden:n = true,

    dvipdfmx .code:n = {
      \PassOptionsToPackage{dvipdfmx}{ocgbase}
    },
    dvipdfmx .value_forbidden:n = true,

    viewocg .choice:,
    viewocg / always .code:n={
      \tl_gset:Nn\g_ocgxii_view_tl{/View<</ViewState/ON>>}},
    viewocg / never .code:n={
      \tl_gset:Nn\g_ocgxii_view_tl{/View<</ViewState/OFF>>}},
    viewocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_view_tl},
    viewocg .default:n={ifvisible},

    printocg .choice:,
    printocg / always .code:n={
      \tl_gset:Nn\g_ocgxii_print_tl{/Print<</PrintState/ON>>}},
    printocg / never .code:n={
      \tl_gset:Nn\g_ocgxii_print_tl{/Print<</PrintState/OFF>>}},
    printocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_print_tl},
    printocg .default:n={ifvisible},

    exportocg .choice:,
    exportocg / always .code:n={
      \tl_gset:Nn\g_ocgxii_export_tl{/Export<</ExportState/ON>>}},
    exportocg / never .code:n={
      \tl_gset:Nn\g_ocgxii_export_tl{/Export<</ExportState/OFF>>}},
    exportocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_export_tl},
    exportocg .default:n={ifvisible},

    showingui .choices:nn = {true,false,always,never,iffirstuse}{
      \bool_if:nTF{
        \str_if_eq_p:ee{#1}{false} ||
        \str_if_eq_p:ee{#1}{never}
      }{
        \bool_gset_false:N\g_ocgxii_showingui_bool
      }{
        \bool_gset_true:N\g_ocgxii_showingui_bool
      }
    },
    showingui .default:n={true},

    listintoolbar .meta:n = {showingui=#1},
    listintoolbar .default:n={true},

    tikz .bool_set:N = \l_ocgxii_tikz_bool,
    tikz .default:n = true,

    ocgcolorlinks .bool_set:N = \l_ocgxii_ocgcolorlinks_bool,
    ocgcolorlinks .default:n = true,

    unknown .code:n = {
      \msg_error:nnx{ocgx2}{unknown~package~option}{\l_keys_key_tl}
    }
  }

  %package options preset
  \keys_set:nn{ocgx2}{viewocg,printocg,exportocg,showingui,tikz=false}

  %process package options
  \ProcessKeyOptions[ocgx2]

  \RequirePackage{ocgbase} %also loads pdfbase.sty

  \bool_gset_eq:NN\g_ocgxii_dvipdfmx_bool\g_pbs_dvipdfmx_bool

  \bool_if:NT\g_pbs_dvisvgm_bool{
    \msg_error:nnn{ocgx2}{generic~msg}{
      Package~`ocgx2'~is~incompatible~with~the~`dvisvgm'~backend.
    }
  }

  %re-implement ocg-p's `ocg' environment
  \DeclareDocumentEnvironment{ocg}{O{}mmm}{
    \ocgxii_begin_ocg:nnnn{#1}{#2}{#3}{#4}
  }{
    \ocgxii_end_ocg:
  }

  \cs_new_protected_nopar:Nn\ocgxii_begin_ocg:nnnn{
    \group_begin:
      \ocgxii_reset_cmd_opts:  % ... to the user-set package options
      \tl_set:Nx\l_ocgxii_argiv_tl{\tl_trim_spaces:n{#4}}
      \tl_if_exist:cTF{ocgxii_ocg_#3}{ %re-open existing layer
        \tl_set:Nx\l_tempa_tl{\tl_use:c{ocgxii_ocg_#3.opts},#1}
        \tl_gset:cx{ocgxii_ocg_#3.opts}{\l_tempa_tl} %new options appended
        \keys_set:nV{ocgx2/ocgenv}\l_tempa_tl
        \bool_if:nTF{ %initial visibility
          \str_if_eq_p:ee{\l_ocgxii_argiv_tl}{1} ||
          \str_if_eq_p:ee{\l_ocgxii_argiv_tl}{on} ||
          \str_if_eq_p:ee{\l_ocgxii_argiv_tl}{true}
        }{
          \ocgbase_del_from_off_list:n{\tl_use:c{ocgxii_ocg_#3}}
        }{
          \ocgbase_add_to_off_list:n{\tl_use:c{ocgxii_ocg_#3}}
        }
      }{
        \tl_set:Nx\l_tempa_tl{#1}
        \tl_gset:cx{ocgxii_ocg_#3.opts}{\l_tempa_tl}
        \keys_set:nV{ocgx2/ocgenv}\l_tempa_tl
        \ocgbase_new_ocg:nnn{#2}{
          \l_ocgxii_view_tl\l_ocgxii_print_tl\l_ocgxii_export_tl
        }{\l_ocgxii_argiv_tl}
        \tl_gset:cx{ocgxii_ocg_#3}{\ocgbase_last_ocg:}
        \tl_gset:cx{ocgx2.ocg.\ocgbase_last_ocg:}{\ocgbase_last_ocg:}
        \tl_gset:cx{ocgx2.ocg.#3}{\ocgbase_last_ocg:}
        \iow_now:Nx\@mainaux{
          \token_to_str:N\ocgxii@newkey{ocgx2.ocg.#3}{\ocgbase_last_ocg:}
        }
      }
      \bool_if:nT{
        !\cs_if_exist:cTF{ocgx2.ocg.#3}{
          \str_if_eq_p:ee{\tl_use:c{ocgx2.ocg.#3}}{\tl_use:c{ocgxii_ocg_#3}}
        }{
          \c_false_bool
        }
      }{
        \tl_if_exist:NF\g_ocgxii_rerunwarned_tl{
          \tl_new:N\g_ocgxii_rerunwarned_tl
          \AtEndDocument{\msg_warning:nn{ocgx2}{rerun}}
        }
      }
      \seq_map_inline:Nn\l_ocgxii_rbgrps_seq{% process list of radio btn groups
        \ocgbase_add_ocg_to_radiobtn_grp:nn{##1}{\tl_use:c{ocgxii_ocg_#3}}
      }
      \ocgbase_open_stack_push:n{\tl_use:c{ocgxii_ocg_#3}}
      \ocgxii_make_oc_entry:
      \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
      % insert OCG into Order tree
      \bool_if:NT\l_ocgxii_showingui_bool{
        \ocgbase_tree_node_begin:n{\tl_use:c{ocgxii_ocg_#3}}
      }
    \group_end:
    \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_#3}}
    \ignorespaces
  }

  \cs_new_protected_nopar:Nn\ocgxii_end_ocg:{
    \unskip
    \ocgbase_oc_emc:
    \ocgbase_tree_node_end:
    \ocgbase_open_stack_pop:N\l_trash_tl
    \ocgxii_make_oc_entry:
    \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
  }

  % OCMD implementation
  \DeclareDocumentEnvironment{ocmd}{O{}m}{
    \ocgxii_begin_ocmd:on{#1}{#2}
    \ignorespaces
  }{
    \unskip
    \ocgxii_end_ocmd:
  }

  \cs_new_protected_nopar:Nn\ocgxii_protected_dummy_cs:n{}

  \cs_new_protected_nopar:Nn\ocgxii_begin_ocmd:nn{ % #1: id,
    \bool_if:nTF{                                  % #2: visib. expr. or policy
      \tl_if_blank:oTF{#1}{
        \c_false_bool
      }{
        \tl_if_exist_p:c{ocgxii_ocmd_#1}
      }
    }{
      % re-open existing ocmd
      \tl_set_eq:Nc\l_ocgxii_cur_ocmd_tl{ocgxii_ocmd_#1}
    }{
      % new ocmd
      \group_begin:
        \cs_set_eq:NN\AllOn \ocgxii_protected_dummy_cs:n
        \cs_set_eq:NN\AnyOn \ocgxii_protected_dummy_cs:n
        \cs_set_eq:NN\AnyOff\ocgxii_protected_dummy_cs:n
        \cs_set_eq:NN\AllOff\ocgxii_protected_dummy_cs:n
        \cs_set_eq:NN\Not   \ocgxii_protected_dummy_cs:n
        \cs_set_eq:NN\And   \ocgxii_protected_dummy_cs:n
        \cs_set_eq:NN\Or    \ocgxii_protected_dummy_cs:n
        \ocgxii_ocmd_read_visbility:xN{#2}\l_ocgxii_ocmd_visibility_tl
        \pbs_pdfobj:nnn{}{dict}{/Type/OCMD\l_ocgxii_ocmd_visibility_tl}
        %if only visb. policy is given, generate equivalent visib. expression,
        %needed for stack of open layers and \ocgxii_make_oc_entry: command
        \ocgxii_ocmd_make_equiv_ve:xN{#2}\l_ocgxii_ocmd_equiv_ve_tl
        \tl_gset:co{ocgx2.ocmd.\pbs_pdflastobj:}{\l_ocgxii_ocmd_equiv_ve_tl}
      \group_end:
      \tl_set:Nx\l_ocgxii_cur_ocmd_tl{\pbs_pdflastobj:}
      \tl_if_blank:oF{#1}{
        \tl_gset:cx{ocgxii_ocmd_#1}{\pbs_pdflastobj:}
        \group_begin:
          \cs_set_eq:NN\AllOn \ocgxii_protected_dummy_cs:n
          \cs_set_eq:NN\AnyOn \ocgxii_protected_dummy_cs:n
          \cs_set_eq:NN\AnyOff\ocgxii_protected_dummy_cs:n
          \cs_set_eq:NN\AllOff\ocgxii_protected_dummy_cs:n
          \cs_set_eq:NN\Not   \ocgxii_protected_dummy_cs:n
          \cs_set_eq:NN\And   \ocgxii_protected_dummy_cs:n
          \cs_set_eq:NN\Or    \ocgxii_protected_dummy_cs:n
          \iow_now:Nx\@mainaux{\exp_not:N\ocgxii@newkeynoexp{ocgx2.ocmd.#1}{#2}}
        \group_end:
      }
    }
    \ocgbase_open_stack_push:n{\l_ocgxii_cur_ocmd_tl}
    \ocgxii_make_oc_entry:
    \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
    \ocgbase_oc_bdc:n{\l_ocgxii_cur_ocmd_tl}
  }
  \cs_generate_variant:Nn\ocgxii_begin_ocmd:nn{on}

  \cs_new_protected_nopar:Nn\ocgxii_end_ocmd:{
    \ocgbase_oc_emc:
    \ocgbase_open_stack_pop:N\l_trash_tl
    \ocgxii_make_oc_entry: %update
    \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
  }

  %visibility expressions
  \cs_new_protected_nopar:Nn\ocgxii_ocmd_read_visbility:nN{
    \int_zero:N\l_ocgxii_ve_cnt_int
    \int_zero:N\l_ocgxii_vp_cnt_int
    \tl_clear_new:N#2
    \clist_map_inline:nn{#1}{\ocgxii_omcd_parse_argument:nN{##1}#2}
  }
  \cs_generate_variant:Nn\ocgxii_ocmd_read_visbility:nN{xN}

  \cs_new_protected_nopar:Nn\ocgxii_omcd_parse_argument:nN{
    \cs_set_eq:NN\AllOn \ocgxii_vp_check:n
    \cs_set_eq:NN\AnyOn \ocgxii_vp_check:n
    \cs_set_eq:NN\AnyOff\ocgxii_vp_check:n
    \cs_set_eq:NN\AllOff\ocgxii_vp_check:n
    \cs_set_eq:NN\Not\ocgxii_ve_check:n
    \cs_set_eq:NN\And\ocgxii_ve_check:n
    \cs_set_eq:NN\Or \ocgxii_ve_check:n
    \tl_if_exist:cTF{ocgx2.ocg.#1}{
      \msg_error:nnxx{ocgx2}{generic~msg}{
        OCG~ids~cannot~be~directly~used~in~the~visibility~argument~of~an~
        `ocmd'~environment.
      }{\g_ocgxii_help_msg_tl}
    }{
      \tl_if_exist:cTF{ocgx2.ocmd.#1}{
        \msg_error:nnxx{ocgx2}{generic~msg}{
          OCMD~ids~cannot~be~directly~used~in~the~visibility~argument~of~an~
          `ocmd'~environment.
        }{\g_ocgxii_help_msg_tl}
      }{
        \tl_if_exist:cTF{ocgxii_#1}{
          \str_case_e:nn{\tl_use:c{ocgxii_#1}}{
            {VisExpr}{
              \int_incr:N\l_ocgxii_ve_cnt_int
              \int_compare:nNnTF{\l_ocgxii_ve_cnt_int}>{1}{
                \msg_error:nnnn{ocgx2}{generic~msg}{
                  More~than~one~visibility~expression~passed~to~the~`ocmd'~
                  environment.
                }{
                  At~most~one~visibility~expression~is~allowed.~A~visibility~
                  expression~is~a~boolean~expression~built~by~nesting~any~number~of~
                  \And{...},~\Or{...},~\Not{...}~commands.
                }
              }{
                \tl_put_right:Nx#2{/VE~}
                \ocgxii_ocmd_expression_parser:nN{#1}#2
              }
            }
            {VisPol}{
              \int_incr:N\l_ocgxii_vp_cnt_int
              \int_compare:nNnTF{\l_ocgxii_vp_cnt_int}>{1}{
                \msg_error:nnnn{ocgx2}{generic~msg}{
                  More~than~one~visibility~policy~passed~to~the~`ocmd'~environment.
                }{
                  At~most~one~visibility~policy~out~of~\AllOn{...},~\AnyOn{...},~
                  \AnyOff{...},~\AllOff{...}~is~allowed.~Any~number~of~OCG~IDs,~
                  separated~by~commas,~may~be~passed~as~arguments~to~these~
                  commands,~but~commands~may~not~be~nested.~For~complex~visibilty~
                  relations,~consider~using~a~visibility~expression.
                }
              }{
                \ocgxii_ocmd_expression_parser:nN{#1}#2
              }
            }
          }
        }{
          \msg_error:nnxx{ocgx2}{generic~msg}{
            The~visibility~argument~of~the~`ocmd'~environment~cannot~be~parsed.
          }{\g_ocgxii_help_msg_tl}
        }
      }
    }
  }
  \cs_generate_variant:Nn\ocgxii_omcd_parse_argument:nN{xN}
  \cs_generate_variant:Nn\ocgxii_omcd_parse_argument:nN{oN}
  \cs_new_protected_nopar:Nn\ocgxii_ocmd_expression_parser:nN{
    \cs_set_eq:NN\AllOn \ocgxii_vp_check:n
    \cs_set_eq:NN\AnyOn \ocgxii_vp_check:n
    \cs_set_eq:NN\AnyOff\ocgxii_vp_check:n
    \cs_set_eq:NN\AllOff\ocgxii_vp_check:n
    \cs_set_eq:NN\Not\ocgxii_ve_check:n
    \cs_set_eq:NN\And\ocgxii_ve_check:n
    \cs_set_eq:NN\Or \ocgxii_ve_check:n
    \tl_if_exist:cTF{ocgx2.ocg.#1}{% ocg reference
      \tl_put_right:Nx#2{~\tl_use:c{ocgx2.ocg.#1}}
    }{
      \tl_if_exist:cTF{ocgx2.ocmd.#1}{% ocmd reference
        \ocgxii_ocmd_expression_parser:vN{ocgx2.ocmd.#1}#2
      }{
        \tl_if_exist:cTF{ocgxii_#1}{% visib. bool expression or policy directive
          \bool_if:nTF{
            \str_if_eq_p:ee{\tl_use:c{ocgxii_#1}}{VisExpr} &&
            \bool_if_p:N\l_ocgxii_vp_open_bool ||
            \str_if_eq_p:ee{\tl_use:c{ocgxii_#1}}{VisPol} &&
            \bool_if_p:N\l_ocgxii_ve_open_bool
          }{
            \msg_error:nnxx{ocgx2}{generic~msg}{
              Visibility~policy~and~expression~commands~cannot~be~mixed.
            }{\g_ocgxii_help_msg_tl}
          }{
            \bool_if:nT{
              \str_if_eq_p:ee{\tl_use:c{ocgxii_#1}}{VisPol} &&
              \bool_if_p:N\l_ocgxii_vp_open_bool
            }{
              \msg_error:nnxx{ocgx2}{generic~msg}{
                Visibility~policy~commands~cannot~be~nested.~For~more~complex~
                visibilty~relations,~consider~using~a~visibility~expression.
              }{\g_ocgxii_help_msg_tl}
            }
          }
          \cs_set_eq:NN\AllOn \ocgxii_vp_allon:nN
          \cs_set_eq:NN\AnyOn \ocgxii_vp_anyon:nN
          \cs_set_eq:NN\AnyOff\ocgxii_vp_anyoff:nN
          \cs_set_eq:NN\AllOff\ocgxii_vp_alloff:nN
          \cs_set_eq:NN\Not\ocgxii_ve_not:nN
          \cs_set_eq:NN\And\ocgxii_ve_and:nN
          \cs_set_eq:NN\Or \ocgxii_ve_or:nN
          #1#2
        }{
          \msg_warning:nnx{ocgx2}{undefined~OCG}{#1}
          \tl_if_exist:NF\g_ocgxii_refundefwarned_tl{
            \tl_new:N\g_ocgxii_refundefwarned_tl
            \AtEndDocument{\msg_warning:nn{ocgx2}{undefined~OCGs}}
          }
        }
      }
    }
  }
  \cs_generate_variant:Nn\ocgxii_ocmd_expression_parser:nN{vN}
  % visib. policy directives
  \cs_new_protected_nopar:Nn\ocgxii_vp_allon:nN{
    \bool_set_true:N\l_ocgxii_vp_open_bool
    \tl_put_right:Nx#2{/P/AllOn/OCGs~\g_ocgxii_left_bracket_tl}
    \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
    \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
    \bool_set_false:N\l_ocgxii_vp_open_bool
  }
  \cs_new_protected_nopar:Nn\ocgxii_vp_anyon:nN{
    \bool_set_true:N\l_ocgxii_vp_open_bool
    \tl_gput_right:Nx#2{/P/AnyOn/OCGs~\g_ocgxii_left_bracket_tl}
    \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
    \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
    \bool_set_false:N\l_ocgxii_vp_open_bool
  }
  \cs_new_protected_nopar:Nn\ocgxii_vp_anyoff:nN{
    \bool_set_true:N\l_ocgxii_vp_open_bool
    \tl_gput_right:Nx#2{/P/AnyOff/OCGs~\g_ocgxii_left_bracket_tl}
    \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
    \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
    \bool_set_false:N\l_ocgxii_vp_open_bool
  }
  \cs_new_protected_nopar:Nn\ocgxii_vp_alloff:nN{
    \bool_set_true:N\l_ocgxii_vp_open_bool
    \tl_gput_right:Nx#2{/P/AllOff/OCGs~\g_ocgxii_left_bracket_tl}
    \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
    \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
    \bool_set_false:N\l_ocgxii_vp_open_bool
  }
  % policy to expression conversion
  \cs_new_protected_nopar:Nn\ocgxii_ocmd_make_equiv_ve:nN{
    \int_zero:N\l_ocgxii_ve_cnt_int
    \tl_clear_new:N#2
    \clist_map_inline:nn{#1}{\ocgxii_omcd_convert_vp:nN{##1}#2}
  }
  \cs_generate_variant:Nn\ocgxii_ocmd_make_equiv_ve:nN{xN}

  \cs_new_protected_nopar:Nn\ocgxii_omcd_convert_vp:nN{
    \cs_set_eq:NN\AllOn \ocgxii_vp_check:n
    \cs_set_eq:NN\AnyOn \ocgxii_vp_check:n
    \cs_set_eq:NN\AnyOff\ocgxii_vp_check:n
    \cs_set_eq:NN\AllOff\ocgxii_vp_check:n
    \cs_set_eq:NN\Not\ocgxii_ve_check:n
    \cs_set_eq:NN\And\ocgxii_ve_check:n
    \cs_set_eq:NN\Or \ocgxii_ve_check:n
    \tl_if_exist:cT{ocgxii_#1}{
      \str_case_e:nn{\tl_use:c{ocgxii_#1}}{
        {VisExpr}{
          \int_incr:N\l_ocgxii_ve_cnt_int
          \tl_set:Nn#2{#1}
        }
        {VisPol}{
          \int_compare:nNnT{\l_ocgxii_ve_cnt_int}={0}{
            \cs_set_eq:NN\AllOn \ocgxii_allon_to_ve:n
            \cs_set_eq:NN\AnyOn \ocgxii_anyon_to_ve:n
            \cs_set_eq:NN\AnyOff\ocgxii_anyoff_to_ve:n
            \cs_set_eq:NN\AllOff\ocgxii_alloff_to_ve:n
            \tl_set:No#2{#1}
          }
        }
      }
    }
  }
  \cs_new_protected_nopar:Nn\ocgxii_allon_to_ve:n{\And{#1}}
  \cs_new_protected_nopar:Nn\ocgxii_anyon_to_ve:n{\Or{#1}}
  \cs_new_protected_nopar:Nn\ocgxii_anyoff_to_ve:n{\Not{\And{#1}}}
  \cs_new_protected_nopar:Nn\ocgxii_alloff_to_ve:n{\Not{\Or{#1}}}
  % visib. boolean expressions
  \cs_new_protected_nopar:Nn\ocgxii_ve_and:nN{
    \bool_set_true:N\l_ocgxii_ve_open_bool
    \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/And}
    \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
    \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
    \bool_set_false:N\l_ocgxii_ve_open_bool
  }
  \cs_new_protected_nopar:Nn\ocgxii_ve_or:nN{
    \bool_set_true:N\l_ocgxii_ve_open_bool
    \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/Or}
    \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
    \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
    \bool_set_false:N\l_ocgxii_ve_open_bool
  }
  \cs_new_protected_nopar:Nn\ocgxii_ve_not:nN{
    \bool_set_true:N\l_ocgxii_ve_open_bool
    % only one item allowed in \Not{...} argument
    \int_compare:nNnT{\clist_count:n{#1}}>{\c_one_int}{
      \msg_error:nnnn{ocgx2}{generic~msg}{
        More~than~one~item~passed~to~\Not{...}.
      }{
        Only~one~item~is~allowed.
      }
    }
    \int_compare:nNnT{\clist_count:n{#1}}={\c_one_int}{
      \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/Not}
      \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
      \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
    }
    \bool_set_false:N\l_ocgxii_ve_open_bool
  }
  \cs_new_protected_nopar:Nn\ocgxii_ve_check:n{VisExpr}
  \tl_set:cn{ocgxii_VisExpr}{VisExpr}
  \cs_new_protected_nopar:Nn\ocgxii_vp_check:n{VisPol}
  \tl_set:cn{ocgxii_VisPol}{VisPol}
  \tl_set:Nx\g_ocgxii_left_bracket_tl{\tl_to_str:N[}
  \tl_set:Nx\g_ocgxii_right_bracket_tl{\tl_to_str:N]}
  \int_new:N\l_ocgxii_vp_cnt_int %number of visib. policies
  \int_new:N\l_ocgxii_ve_cnt_int %number of visib. expressions
  \bool_new:N\l_ocgxii_vp_open_bool %for nesting test
  \bool_new:N\l_ocgxii_ve_open_bool %for nesting test
  \tl_set:Nn\g_ocgxii_help_msg_tl{
    At~most~one~visibility~policy~and,~separated~by~a~comma,~at~most~one~
    visibility~expression~may~be~passed~as~the~2nd~argument~to~the~`ocmd'~
    environment.~A~visibility~
    policy~is~defined~by~one~of~\AllOn{...},~\AnyOn{...},~\AnyOff{...},~
    \AllOff{...}.~A~visibility~expression~is~a~boolean~expression~built~by~
    nesting~any~number~of~\And{...},~\Or{...},~\Not{...}~commands.~If~both~are~
    provided,~the~visibility~expression~takes~precedence~over~the~policy,~but~the~
    latter~may~be~used~as~fallback~by~non-conforming~PDF~viewers.
  }
  %command that builds /OC entry from open layer stack
  \cs_new_protected_nopar:Nn\ocgxii_make_oc_entry:{
    \group_begin:
    \tl_gclear:N\g_ocgxii_oc_entry_tl
    \tl_clear:N\l_tempa_tl
    \seq_if_empty:NF\g_ocgbase_open_stack_seq{
      \seq_clear:N\l_tempa_seq
      %additional level of braces around indirect PDF objects (needed for dvips)
      \seq_map_inline:Nn\g_ocgbase_open_stack_seq{
        \seq_put_right:Nn\l_tempa_seq{{##1}}
      }
      \ocgxii_omcd_parse_argument:xN{
        \exp_not:N\And{\seq_use:Nn\l_tempa_seq{,}}
      }\l_tempa_tl
      \tl_gset:Nx\g_ocgxii_oc_entry_tl{/OC~<</Type/OCMD\l_tempa_tl>>}
    }
    \group_end:
  }
  %programmer/author command that inserts /OC << >> entry; for use in
  %annotation/xobject dicts, in order to make them layer-aware
  \cs_new_nopar:Nn\ocgxii_insert_oc:{\g_ocgxii_oc_entry_tl}
  \cs_gset_eq:NN\ocgbase_insert_oc:\ocgxii_insert_oc:
  \cs_gset_eq:NN\ocgbase@insert@oc\ocgxii_insert_oc:
  \tl_new:N\g_ocgxii_oc_entry_tl

  \cs_new_protected_nopar:Nn\ocgxii_stack_shipout:NN{
    \iow_shipout_x:Nx\@mainaux{
      \token_to_str:N#1{
        \exp_not:N\int_use:N\g_ocgxii_page_int
      }{\seq_use:Nn#2{,}}
    }
  }

  \cs_new_protected_nopar:Npn\ocgxii@ocg@stack@on@page#1#2{
    \seq_gset_from_clist:cn{g_pending_ocgs_on_#1_seq}{#2}
    %re-add braces around items for dvips
    \bool_if:nT{\sys_if_output_dvi_p: && !\g_ocgxii_dvipdfmx_bool}{
      \seq_map_inline:cn{g_pending_ocgs_on_#1_seq}{
        \seq_gpop_left:cN{g_pending_ocgs_on_#1_seq}\l_trash_tl
        \seq_gput_right:cn{g_pending_ocgs_on_#1_seq}{{##1}}
      }
    }
  }
  \ocgxii@ocg@stack@on@page{0}{} %initialize

  \cs_new_protected_nopar:Npn\ocgxii@lnkcol@stack@on@page#1#2{
    \seq_gset_from_clist:cn{g_pending_lnkcols_on_#1_seq}{#2}
    %re-add braces around items
    \seq_map_inline:cn{g_pending_lnkcols_on_#1_seq}{
      \seq_gpop_left:cN{g_pending_lnkcols_on_#1_seq}\l_trash_tl
      \seq_gput_right:cn{g_pending_lnkcols_on_#1_seq}{{##1}}
    }
  }
  \ocgxii@lnkcol@stack@on@page{0}{} %initialize

  %end-of-page action
  \pbs_eop_action:n{
    \seq_if_exist:cT{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{
      %check whether end-of-page link colour stack has settled
      \iow_shipout:Nx\@mainaux{
        \token_to_str:N\ocgxii@newkey{ocgx2.oldlnkcol.\int_use:N\g_ocgxii_page_int}{
          \seq_use:cn{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
        }
      }
      \bool_if:nT{
        !\cs_if_exist:cTF{ocgx2.oldlnkcol.\int_use:N\g_ocgxii_page_int}{
          \str_if_eq_p:ee{
            \tl_use:c{ocgx2.oldlnkcol.\int_use:N\g_ocgxii_page_int}
          }{
            \seq_use:cn{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
          }
        }{
          \c_false_bool
        }
      }{
        \tl_if_exist:NF\g_ocgxii_rerunwarned_tl{
          \tl_new:N\g_ocgxii_rerunwarned_tl
          \AtEndDocument{\msg_warning:nn{ocgx2}{rerun}}
        }
      }
      % now close the colourlink opened last
      \seq_get:cNT{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}\l_tmpa_tl{
        \tl_gset:Nx\g_ocgxii_lnkcol_tl{{\l_tmpa_tl}}
        \ocgxii_colourlink_end:
      }
    }
    %check whether end-of-page ocg stack has settled
    \iow_shipout:Nx\@mainaux{
      \token_to_str:N\ocgxii@newkey{ocgx2.oldstack.\int_use:N\g_ocgxii_page_int}{
        \seq_use:cn{g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
      }
    }
    \bool_if:nT{
      !\cs_if_exist:cTF{ocgx2.oldstack.\int_use:N\g_ocgxii_page_int}{
        \str_if_eq_p:ee{
          \tl_use:c{ocgx2.oldstack.\int_use:N\g_ocgxii_page_int}
        }{
          \seq_use:cn{g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
        }
      }{
        \c_false_bool
      }
    }{
      \tl_if_exist:NF\g_ocgxii_rerunwarned_tl{
        \tl_new:N\g_ocgxii_rerunwarned_tl
        \AtEndDocument{\msg_warning:nn{ocgx2}{rerun}}
      }
    }
    %now close pending ocgs
    \seq_map_variable:cNn{
      g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq
    }\l_tmpb_tl{\ocgbase_oc_emc:}
  }

  %begin-of-page action
  \pbs_bop_action:n{
    % re-open all pending ocgs in original order
    \seq_set_eq:Nc\l_ocgxii_pending_ocgs_seq{
      g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq
    }
    \seq_reverse:N\l_ocgxii_pending_ocgs_seq
    \seq_map_variable:NNn\l_ocgxii_pending_ocgs_seq\l_tmpa_tl{
      \ocgbase_oc_bdc:n{\l_tmpa_tl}
    }
    % re-open the colourlink opened last
    \seq_get:cNT{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}\l_tmpa_tl{
      \tl_gset:Nx\g_ocgxii_lnkcol_tl{{\l_tmpa_tl}}
      \ocgxii_colourlink_begin:
    }
    \int_gincr:N\g_ocgxii_page_int
    % copy pending ocg stack from previous page, if it has not been initialized
    % yet from aux file
    \seq_if_exist:cF{g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq}{
      \seq_gset_eq:cc{
        g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq
      }{
        g_pending_ocgs_on_\int_eval:n{\g_ocgxii_page_int-\c_one_int}_seq
      }
    }
    %the same for link colour stack
    \seq_if_exist:cF{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{
      \seq_gset_eq:cc{
        g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq
      }{
        g_pending_lnkcols_on_\int_eval:n{\g_ocgxii_page_int-\c_one_int}_seq
      }
    }
  }
  \int_new:N\g_ocgxii_page_int %abs. page counter

  \cs_new_protected_nopar:Nn\ocgxii_ocglist_reset:{
    \tl_clear_new:N\l_ocgxii_u_list_tl
    \tl_clear_new:N\l_ocgxii_d_list_tl
    \tl_clear_new:N\l_ocgxii_e_list_tl
    \tl_clear_new:N\l_ocgxii_x_list_tl
  }

  \cs_new_protected_nopar:Nn\ocgxii_ocglist_build:Nn{
    \tl_set:Nx\l_ocglistarg_tl{#2}\tl_trim_spaces:N\l_ocglistarg_tl
    % first try splitting at commas (ocgx2 syntax)
    \tl_set_eq:NN\l_tmpa_tl\l_ocglistarg_tl
    \tl_remove_all:Nn\l_tmpa_tl{~}
    \seq_set_split:NnV\l_ocgxii_ocglistarg_seq{,}\l_tmpa_tl
    \seq_remove_all:Nn\l_ocgxii_ocglistarg_seq{}
    \tl_set:Nx\l_tmpa_tl{\seq_count:N\l_ocgxii_ocglistarg_seq}
    % now at spaces (legacy ocgx/ocg-p)
    \tl_set_eq:NN\l_tmpb_tl\l_ocglistarg_tl
    \tl_remove_all:Nn\l_tmpb_tl{,}
    \seq_set_split:NnV\l_tmpb_seq{~}\l_tmpb_tl
    \seq_remove_all:Nn\l_tmpb_seq{}
    \tl_set:Nx\l_tmpb_tl{\seq_count:N\l_tmpb_seq}
    %take the seq having more elements (guessing the separator most likely used)
    \int_compare:nT{\l_tmpb_tl>\l_tmpa_tl}{
      \seq_set_eq:NN\l_ocgxii_ocglistarg_seq\l_tmpb_seq
    }
    \seq_map_variable:NNn\l_ocgxii_ocglistarg_seq\l_tempa_tl{
      \ocgxii_process_ocgref:NN#1\l_tempa_tl
    }
  }

  \cs_new_protected_nopar:Nn\ocgxii_commalist_process:n{
    \seq_set_split:Nnn\l_tmpa_seq{,}{#1}
    \ocgxii_ocglist_build:Nn\l_ocgxii_e_list_tl{\seq_item:Nn\l_tmpa_seq{1}}
    \ocgxii_ocglist_build:Nn\l_ocgxii_x_list_tl{\seq_item:Nn\l_tmpa_seq{2}}
    \ocgxii_ocglist_build:Nn\l_ocgxii_d_list_tl{\seq_item:Nn\l_tmpa_seq{3}}
    \ocgxii_ocglist_build:Nn\l_ocgxii_u_list_tl{\seq_item:Nn\l_tmpa_seq{4}}
  }

  \cs_new_protected_nopar:Nn\ocgxii_ocglist_process_idlist:nn{
    \ocgxii_ocglist_reset:
    \tl_set:Nx\l_ocgxii_opt_tl{#1}\tl_remove_all:Nn\l_ocgxii_opt_tl{~}
    \str_case_e:nnF{\l_ocgxii_opt_tl}{
      {onmouseup}{
        \ocgxii_ocglist_build:Nn\l_ocgxii_u_list_tl{#2}
      }
      {onmousedown}{
        \ocgxii_ocglist_build:Nn\l_ocgxii_d_list_tl{#2}
      }
      {onmouseenter}{
        \ocgxii_ocglist_build:Nn\l_ocgxii_e_list_tl{#2}
      }
      {onmouseexit}{
        \ocgxii_ocglist_build:Nn\l_ocgxii_x_list_tl{#2}
      }
      {onmouseall}{
        \ocgxii_commalist_process:n{#2}
      }
    }{
      \msg_error:nnx{ocgx2}{unknown~option}{\l_ocgxii_opt_tl}
    }
  }

  \int_new:N\g_ocgxii_widcount_int% widget counter

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % re-implement commands from ocgx.sty (all engines including ps2pdf [gs>=9.15])
  % adding optional `*' (arg 1) -> non-breakable link instead of plain (multiline)
  % Link;
  % adding optional 2nd argument -> Button Widget (non-breakable) with one of
  % various mouse triggers (`troggerocgs` option from ocg-p)
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  \DeclareDocumentCommand\switchocg{s O{} m +m}{
    \ocgxii_actionsocg:nnnnnn{#1}{#2}{#3}{}{}{#4}
  }

  \DeclareDocumentCommand\showocg{s O{} m +m}{
    \ocgxii_actionsocg:nnnnnn{#1}{#2}{}{#3}{}{#4}
  }

  \DeclareDocumentCommand\hideocg{s O{} m +m}{
    \ocgxii_actionsocg:nnnnnn{#1}{#2}{}{}{#3}{#4}
  }

  \DeclareDocumentCommand\actionsocg{s O{} m m m +m}{
    \ocgxii_actionsocg:nnnnnn{#1}{#2}{#3}{#4}{#5}{#6}
  }

  \bool_new:N\l_ocgxii_mouse_triggers_bool
  \bool_new:N\l_ocgxii_nobreak_bool
  \cs_new_protected:Nn\ocgxii_actionsocg:nnnnnn{
    \leavevmode
    \bool_set_false:N\l_ocgxii_mouse_triggers_bool
    \bool_set_false:N\l_ocgxii_nobreak_bool
    % explicitly non-breakable?
    \bool_if:nT{#1}{\bool_set_true:N\l_ocgxii_nobreak_bool}
    %
    %clear actions for various mouse triggers (e,d,x)
    \tl_clear:N\l_ocgxii_toswitch_e_tl
    \tl_clear:N\l_ocgxii_toswitch_x_tl
    \tl_clear:N\l_ocgxii_toswitch_d_tl
    \tl_clear:N\l_ocgxii_toshow_e_tl
    \tl_clear:N\l_ocgxii_toshow_x_tl
    \tl_clear:N\l_ocgxii_toshow_d_tl
    \tl_clear:N\l_ocgxii_tohide_e_tl
    \tl_clear:N\l_ocgxii_tohide_x_tl
    \tl_clear:N\l_ocgxii_tohide_d_tl
    %
    %process *all* mouse triggers (e,d,u,x)
    \ocgxii_ocglist_process_idlist:nn{
      \tl_if_blank:oTF{#2}{onmouseup}{#2}
    }{#3}
    \tl_set_eq:NN\l_ocgxii_toswitch_e_tl\l_ocgxii_e_list_tl
    \tl_set_eq:NN\l_ocgxii_toswitch_x_tl\l_ocgxii_x_list_tl
    \tl_set_eq:NN\l_ocgxii_toswitch_d_tl\l_ocgxii_d_list_tl
    \tl_set_eq:NN\l_ocgxii_toswitch_u_tl\l_ocgxii_u_list_tl
    \ocgxii_ocglist_process_idlist:nn{
      \tl_if_blank:oTF{#2}{onmouseup}{#2}
    }{#4}
    \tl_set_eq:NN\l_ocgxii_toshow_e_tl\l_ocgxii_e_list_tl
    \tl_set_eq:NN\l_ocgxii_toshow_x_tl\l_ocgxii_x_list_tl
    \tl_set_eq:NN\l_ocgxii_toshow_d_tl\l_ocgxii_d_list_tl
    \tl_set_eq:NN\l_ocgxii_toshow_u_tl\l_ocgxii_u_list_tl
    \ocgxii_ocglist_process_idlist:nn{
      \tl_if_blank:oTF{#2}{onmouseup}{#2}
    }{#5}
    \tl_set_eq:NN\l_ocgxii_tohide_e_tl\l_ocgxii_e_list_tl
    \tl_set_eq:NN\l_ocgxii_tohide_x_tl\l_ocgxii_x_list_tl
    \tl_set_eq:NN\l_ocgxii_tohide_d_tl\l_ocgxii_d_list_tl
    \tl_set_eq:NN\l_ocgxii_tohide_u_tl\l_ocgxii_u_list_tl
    %any triggers apart from mouse-up?
    \str_if_eq:eeF{
      \l_ocgxii_toswitch_e_tl\l_ocgxii_toswitch_x_tl\l_ocgxii_toswitch_d_tl
      \l_ocgxii_toshow_e_tl\l_ocgxii_toshow_x_tl\l_ocgxii_toshow_d_tl
      \l_ocgxii_tohide_e_tl\l_ocgxii_tohide_x_tl\l_ocgxii_tohide_d_tl
    }{}{
      \bool_set_true:N\l_ocgxii_mouse_triggers_bool
    }
    %
    \bool_if:nTF{\l_ocgxii_nobreak_bool || \l_ocgxii_mouse_triggers_bool}{
      \hbox_set:Nn\l_tmpa_box{#6}
      \pbs_pdfannot:nnnn{
        \dim_use:N\box_wd:N\l_tmpa_box}{
        \dim_use:N\box_ht:N\l_tmpa_box}{
        \dim_use:N\box_dp:N\l_tmpa_box
      }{
        \bool_if:NTF\l_ocgxii_mouse_triggers_bool{
          % e,d,x mouse triggers require (non-breakable) /Widget annot with AA
          % (additional actions) dict
          /Subtype/Widget/Ff~65536/FT/Btn/BS<</W~0>>
          /T~(ocgx2@\int_use:N\g_ocgxii_widcount_int)
          %treat mouse-up as mouse-click --> handle through /A dictionary
          \str_if_eq:eeF{}{
            \l_ocgxii_toswitch_u_tl\l_ocgxii_toshow_u_tl\l_ocgxii_tohide_u_tl
          }{
            /A <</S/SetOCGState/State [
              \str_if_eq:VnF\l_ocgxii_toswitch_u_tl{}{
                /Toggle~\l_ocgxii_toswitch_u_tl
              }
              \str_if_eq:VnF\l_ocgxii_toshow_u_tl{}{
                /ON~\l_ocgxii_toshow_u_tl
              }
              \str_if_eq:VnF\l_ocgxii_tohide_u_tl{}{
                /OFF~\l_ocgxii_tohide_u_tl
              }
            ]>>
          }
          /AA <<
            %\str_if_eq:eeF{}{ % mouse-up
            %  \l_ocgxii_toswitch_u_tl\l_ocgxii_toshow_u_tl\l_ocgxii_tohide_u_tl
            %}{
            %  /U <</S/SetOCGState/State [
            %    \str_if_eq:VnF\l_ocgxii_toswitch_u_tl{}{
            %      /Toggle~\l_ocgxii_toswitch_u_tl
            %    }
            %    \str_if_eq:VnF\l_ocgxii_toshow_u_tl{}{
            %      /ON~\l_ocgxii_toshow_u_tl
            %    }
            %    \str_if_eq:VnF\l_ocgxii_tohide_u_tl{}{
            %      /OFF~\l_ocgxii_tohide_u_tl
            %    }
            %  ]>>
            %}
            \str_if_eq:eeF{}{ % mouse-down
              \l_ocgxii_toswitch_d_tl\l_ocgxii_toshow_d_tl\l_ocgxii_tohide_d_tl
            }{
              /D <</S/SetOCGState/State [
                \str_if_eq:VnF\l_ocgxii_toswitch_d_tl{}{
                  /Toggle~\l_ocgxii_toswitch_d_tl
                }
                \str_if_eq:VnF\l_ocgxii_toshow_d_tl{}{
                  /ON~\l_ocgxii_toshow_d_tl
                }
                \str_if_eq:VnF\l_ocgxii_tohide_d_tl{}{
                  /OFF~\l_ocgxii_tohide_d_tl
                }
              ]>>
            }
            \str_if_eq:eeF{}{ % mouse-enter
              \l_ocgxii_toswitch_e_tl\l_ocgxii_toshow_e_tl\l_ocgxii_tohide_e_tl
            }{
              /E <</S/SetOCGState/State [
                \str_if_eq:VnF\l_ocgxii_toswitch_e_tl{}{
                  /Toggle~\l_ocgxii_toswitch_e_tl
                }
                \str_if_eq:VnF\l_ocgxii_toshow_e_tl{}{
                  /ON~\l_ocgxii_toshow_e_tl
                }
                \str_if_eq:VnF\l_ocgxii_tohide_e_tl{}{
                  /OFF~\l_ocgxii_tohide_e_tl
                }
              ]>>
            }
            \str_if_eq:eeF{}{ % mouse-exit
              \l_ocgxii_toswitch_x_tl\l_ocgxii_toshow_x_tl\l_ocgxii_tohide_x_tl
            }{
              /X <</S/SetOCGState/State [
                \str_if_eq:VnF\l_ocgxii_toswitch_x_tl{}{
                  /Toggle~\l_ocgxii_toswitch_x_tl
                }
                \str_if_eq:VnF\l_ocgxii_toshow_x_tl{}{
                  /ON~\l_ocgxii_toshow_x_tl
                }
                \str_if_eq:VnF\l_ocgxii_tohide_x_tl{}{
                  /OFF~\l_ocgxii_tohide_x_tl
                }
              ]>>
            }
          >>
        }{
          %mouse-up alone may go with simple /Link annot
          /Subtype/Link
          /A <</S/SetOCGState
            /State [
              \str_if_eq:VnF{\l_ocgxii_toswitch_u_tl}{}{
                /Toggle~\l_ocgxii_toswitch_u_tl}~
              \str_if_eq:VnF{\l_ocgxii_toshow_u_tl}{}{/ON~\l_ocgxii_toshow_u_tl}~
              \str_if_eq:VnF{\l_ocgxii_tohide_u_tl}{}{/OFF~\l_ocgxii_tohide_u_tl}
            ]
          >>
          /Border~[0~0~0]
        }
        \cs_if_exist:NT\@pdfhighlight{
          \ifx\@pdfhighlight\@empty\else/H\@pdfhighlight\fi
        }
      }\box_use_drop:N\l_tmpa_box
      \bool_if:NT\l_ocgxii_mouse_triggers_bool{
        \pbs_appendtofields:n{\pbs_pdflastann:}
        \int_gincr:N\g_ocgxii_widcount_int
      }
    }{
      %line-breakable annotation
      \pbs_pdflink:nn{
        /Subtype/Link
        /A <</S/SetOCGState
          /State [
            \str_if_eq:VnF{\l_ocgxii_toswitch_u_tl}{}{
              /Toggle~\l_ocgxii_toswitch_u_tl}~
            \str_if_eq:VnF{\l_ocgxii_toshow_u_tl}{}{/ON~\l_ocgxii_toshow_u_tl}~
            \str_if_eq:VnF{\l_ocgxii_tohide_u_tl}{}{/OFF~\l_ocgxii_tohide_u_tl}
          ]
        >>
        %look and feel of hyperref links, if hyperref has been loaded
        \cs_if_exist:NTF\Hy@setpdfborder{
          \Hy@setpdfborder\g_ocgxii_patch_tl
          \ifx\@pdfhighlight\@empty\else/H\@pdfhighlight\fi
          \ifx\@linkbordercolor\relax\else/C[\@linkbordercolor]\fi
          \ifHy@pdfa /F~4\fi
        }{
          /Border~[0~0~0]
        }
      }{
        \cs_if_exist:NTF\Hy@colorlink{
          \Hy@colorlink\@linkcolor#6\Hy@endcolorlink\Hy@VerboseLinkStop
        }{#6}
      }
    }
  }

  %mimic commands from ocg-p
  \keys_define:nn{ocgx2/ocgpcmd}{
    triggerocg .choices:nn = {
      onmouseenter, onmouseexit, onmousedown, onmouseup, allactions
    }{
      \str_if_eq:eeTF{\l_keys_choice_tl}{allactions}{
        \tl_set:Nn\l_ocgxii_trigger_tl{onmouseall}
      }{
        \tl_set_eq:NN\l_ocgxii_trigger_tl\l_keys_choice_tl
      }
    }
  }
  \DeclareDocumentCommand\toggleocgs{O{} m +m}{
    \tl_clear_new:N\l_ocgxii_trigger_tl
    \keys_set:nn{ocgx2/ocgpcmd}{#1}
    \switchocg*[\l_ocgxii_trigger_tl]{#2}{#3}
  }
  \DeclareDocumentCommand\showocgs{O{} m +m}{
    \tl_clear_new:N\l_ocgxii_trigger_tl
    \keys_set:nn{ocgx2/ocgpcmd}{#1}
    \showocg*[\l_ocgxii_trigger_tl]{#2}{#3}
  }
  \DeclareDocumentCommand\hideocgs{O{} m +m}{
    \tl_clear_new:N\l_ocgxii_trigger_tl
    \keys_set:nn{ocgx2/ocgpcmd}{#1}
    \hideocg*[\l_ocgxii_trigger_tl]{#2}{#3}
  }
  \DeclareDocumentCommand\setocgs{O{} m m m +m}{
    \tl_clear_new:N\l_ocgxii_trigger_tl
    \keys_set:nn{ocgx2/ocgpcmd}{#1}
    \actionsocg*[\l_ocgxii_trigger_tl]{#2}{#3}{#4}{#5}
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  \cs_new_protected:Nn\ocgxii_process_ocgref:NN{
    \tl_if_exist:cTF{ocgx2.ocg.#2}{
      \tl_put_right:Nx#1{~\tl_use:c{ocgx2.ocg.#2}}
    }{
      \msg_warning:nnx{ocgx2}{undefined~OCG}{#2}
      \tl_if_exist:NF\g_ocgxii_refundefwarned_tl{
        \tl_new:N\g_ocgxii_refundefwarned_tl
        \AtEndDocument{\msg_warning:nn{ocgx2}{undefined~OCGs}}
      }
    }
  }

  %ocg environment opts
  \keys_define:nn{ocgx2/ocgenv}{
    viewocg .choice:,
    viewocg / always .code:n={
      \tl_set:Nn\l_ocgxii_view_tl{/View<</ViewState/ON>>}},
    viewocg / never .code:n={
      \tl_set:Nn\l_ocgxii_view_tl{/View<</ViewState/OFF>>}},
    viewocg / ifvisible .code:n={
      \tl_clear:N\l_ocgxii_view_tl},
    viewocg .default:n={ifvisible},

    printocg .choice:,
    printocg / always .code:n={
      \tl_set:Nn\l_ocgxii_print_tl{/Print<</PrintState/ON>>}},
    printocg / never .code:n={
      \tl_set:Nn\l_ocgxii_print_tl{/Print<</PrintState/OFF>>}},
    printocg / ifvisible .code:n={
      \tl_clear:N\l_ocgxii_print_tl},
    printocg .default:n={ifvisible},

    exportocg .choice:,
    exportocg / always .code:n={
      \tl_set:Nn\l_ocgxii_export_tl{/Export<</ExportState/ON>>}},
    exportocg / never .code:n={
      \tl_set:Nn\l_ocgxii_export_tl{/Export<</ExportState/OFF>>}},
    exportocg / ifvisible .code:n={\tl_clear:N\l_ocgxii_export_tl},
    exportocg .default:n={ifvisible},

    showingui .choices:nn = {true,false,always,never,iffirstuse}{
      \bool_if:nTF{
        \str_if_eq_p:ee{#1}{false} ||
        \str_if_eq_p:ee{#1}{never}
      }{
        \bool_set_false:N\l_ocgxii_showingui_bool
      }{
        \bool_set_true:N\l_ocgxii_showingui_bool
      }
    },
    showingui .default:n={true},

    listintoolbar .meta:n = {showingui=#1},
    listintoolbar .default:n={true},

    radiobtngrps .code:n = {
      \clist_map_inline:nn{#1}{
        \seq_if_in:NxF\l_ocgxii_rbgrps_seq{##1}{
          \seq_put_right:Nx\l_ocgxii_rbgrps_seq{##1}
        }
      }
    },
    radiobtngrps .value_required:n = {true},
    radiobtngrp .meta:n={radiobtngrps={#1}},
    radiobtngrp .value_required:n = {true}
  }

  \cs_new_protected:Nn\ocgxii_reset_cmd_opts:{
    \tl_set_eq:NN\l_ocgxii_view_tl\g_ocgxii_view_tl
    \tl_set_eq:NN\l_ocgxii_print_tl\g_ocgxii_print_tl
    \tl_set_eq:NN\l_ocgxii_export_tl\g_ocgxii_export_tl
    \bool_set_eq:NN\l_ocgxii_showingui_bool\g_ocgxii_showingui_bool
    %stack of radio button group names the current ocg belongs to
    \seq_clear_new:N\l_ocgxii_rbgrps_seq
  }

  \msg_set:nnn{ocgx2}{rerun}{Rerun~to~get~OCG~references~right!}
  \msg_set:nnn{ocgx2}{undefined~OCG}{
    Line~\msg_line_number: :~OCG~`#1'~is~not~defined.
  }
  \msg_set:nnn{ocgx2}{undefined~OCGs}{There~were~undefined~OCGs!}
  \msg_set:nnn{ocgx2}{unknown~option}{
    Line~\msg_line_number: :~unknown~option~`#1'.
  }

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % patch hyperref to ensure compatibility with our `ocgcolorlinks' option
  %
  % Plus:
  %
  % * add `ocgcolorlinks' support to all drivers
  %
  % * allows for `ocgcolorlinks' extending over
  %
  %      line-breaks AND page-breaks
  %
  %   with pdftex, luatex, xetex, dvipdfmx drivers
  %
  % based on Ben Lerner's idea
  %   http://tex.stackexchange.com/a/104227;
  % with some improvements
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  \cs_new_protected_nopar:Nn\ocgxii_colourlink_begin:{}
  \cs_new_protected_nopar:Nn\ocgxii_colourlink_end:{}
  \cs_new_protected_nopar:Nn\ocgxii_colourlink_nobreak_begin:{
    \hbox_set:Nw\l_tmpa_box\color@begingroup
      \tl_set_eq:NN\color@setgroup\group_begin:
  }
  \cs_new_protected_nopar:Nn\ocgxii_colourlink_nobreak_end:{
    \color@endgroup\hbox_set_end:
    \mbox{
      \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCPrint}}
      \hbox_to_zero:n{\box_use:N\l_tmpa_box\hss}
      \ocgbase_oc_emc:
      \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCView}}
      \group_begin:
        \exp_after:wN\HyColor@UseColor\l_ocgxii_lnkcol_tl
        \box_use_drop:N\l_tmpa_box
      \group_end:
      \ocgbase_oc_emc:
    }
  }

  \seq_new:N\g_ocgxii_lnk_color_seq %stack of colours of currently open links
  \tl_new:N\g_ocgxii_patch_tl % `BorderArrayPatch' for dvips

  %we'll be using the downscaled space character (32) from the pzdr
  % (dingbats) font at the end of every ocgcolorlink in order to prevent
  % empty links from flooding the page with link colour
  \cs_new_protected_nopar:Npn\ocgxii_tiny_space_char:{
    \group_begin: \font\l_tmpa_tl=pzdr~scaled~1\l_tmpa_tl\char32 \group_end:
  }

  \bool_if:nTF{\sys_if_output_dvi_p: && !\g_ocgxii_dvipdfmx_bool}{
    % non-breakable links in dvips
    \cs_new_protected_nopar:Nn\ocgxii_enable_ocglinks:{
      \def\Hy@colorlink##1{
        \group_begin:
        \tl_set:Nn\l_ocgxii_lnkcol_tl{##1}
        \ocgxii_colourlink_nobreak_begin:
      }
      \def\Hy@endcolorlink{
        \ocgxii_colourlink_nobreak_end:
        \group_end:
      }
    }
    \tl_gset:Nn\g_ocgxii_patch_tl{BorderArrayPatch}
  }{
    % pdftex,luatex,xetex,dvipdfmx:
    % ocgcolorlinks that extend over line and page breaks
    \cs_new_protected_nopar:Nn\ocgxii_enable_ocglinks:{
      \def\Hy@colorlink##1{
        \ifx\Hy@setbreaklinks\@gobble\else
          \Hy@breaklinkstrue
        \fi
        \ifHy@breaklinks
          \seq_get_left:NNT\g_ocgxii_lnk_color_seq\l_tmpa_tl{
            \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
            \ocgxii_colourlink_end:
          }
          \group_begin:
          \ocgxii_colourlink_begin:
          \seq_gpush:Nx\g_ocgxii_lnk_color_seq{{##1}}
          \ocgxii_stack_shipout:NN\ocgxii@lnkcol@stack@on@page\g_ocgxii_lnk_color_seq
        \else
          \group_begin:
          \tl_set:Nn\l_ocgxii_lnkcol_tl{##1}
          \ocgxii_colourlink_nobreak_begin:
        \fi
      }
      \def\Hy@endcolorlink{
        \ifHy@breaklinks
          \seq_gpop:NN\g_ocgxii_lnk_color_seq\l_tmpa_tl
          \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
          \ocgxii_stack_shipout:NN\ocgxii@lnkcol@stack@on@page\g_ocgxii_lnk_color_seq
          \ocgxii_colourlink_end:
          \group_end:
          \seq_get_left:NNT\g_ocgxii_lnk_color_seq\l_tmpa_tl{
            \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
            \ocgxii_colourlink_begin:
          }
        \else
          \ocgxii_colourlink_nobreak_end:
          \group_end:
        \fi
      }
    }
    \bool_if:NT\l_ocgxii_ocgcolorlinks_bool{
      \cs_gset_protected_nopar:Nn\ocgxii_colourlink_begin:{
        %tiny space char put here in order to neutralise possible transformation
        %matrix modifications from previous \pdfliteral{} (TikZ makes a lot use of it)
        \hbox_overlap_left:n{\ocgxii_tiny_space_char:}
        \pbs_literal:nn{page}{q~7~Tr}
      }
      \cs_gset_protected_nopar:Nn\ocgxii_colourlink_end:{
        %a tiny space char should keep empty link annots from flooding the page
        % with link colour
        \hbox_overlap_left:n{\ocgxii_tiny_space_char:}
        \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCPrint}}
          \pbs_literal:nn{page}{-88888~-88888~99999~99999~re~f}
        \ocgbase_oc_emc:
        \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCView}}
          \group_begin:
            \exp_after:wN\HyColor@UseColor\g_ocgxii_lnkcol_tl
            \pbs_literal:nn{page}{-88888~-88888~99999~99999~re~f}
          \group_end:
        \ocgbase_oc_emc:
        \pbs_literal:nn{page}{0~Tr~Q}
      }
    }
  }

  % user command for protecting graphical content (external file, inline
  % [e. g. TikZ], \fbox{...}) inside breakable ocgcolorlink
  \bool_if:NTF\l_ocgxii_ocgcolorlinks_bool{
    \DeclareDocumentCommand\ocglinkprotect{m}{
      \seq_get_left:NNT\g_ocgxii_lnk_color_seq\l_tmpa_tl{
        \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
        \ocgxii_colourlink_end:
        \group_begin:
          \tl_set_eq:NN\l_ocgxii_lnkcol_tl\l_tmpa_tl
          \ocgxii_colourlink_nobreak_begin:
      }
      \group_begin:
      \cs_set_nopar:Npn\ocglinkprotect##1{##1} % in case of nesting
      \sys_if_output_pdf:TF{
        \leavevmode
        \hbox_set:Nn\l_tmpb_box{#1}
        \hbox_to_wd:nn{\box_wd:N\l_tmpb_box}{
          \vrule~width~\c_zero_dim~height~\box_ht:N\l_tmpb_box~
            depth~\box_dp:N\l_tmpb_box
          \pbs_pdfxform:nnnnn{1}{0}{}{}{\l_tmpb_box}
          \pbs_pdfrefxform:n{\pbs_pdflastxform:}
          \hss
        }
      }{#1}
      \group_end:
      \seq_get_left:NNT\g_ocgxii_lnk_color_seq\l_tmpa_tl{
          \ocgxii_colourlink_nobreak_end:
        \group_end:
        \ocgxii_colourlink_begin:
      }
    }
  }{
    \DeclareDocumentCommand\ocglinkprotect{m}{#1}
  }

  % option ocgcolorlinks and beamer are not compatible
  \bool_if:NT\l_ocgxii_ocgcolorlinks_bool{
    \@ifclassloaded{beamer}{
      \bool_set_false:N\l_ocgxii_ocgcolorlinks_bool
      \hypersetup{colorlinks}
      \msg_warning:nn{ocgx2}{beamer~and~ocgcolorlinks}
    }{}
  }

  \bool_if:NT\l_ocgxii_ocgcolorlinks_bool{
    \@ifpackageloaded{hyperref}{
      \Hy@colorlinkstrue
      \AtBeginDocument{
        \ocgbase_new_ocg:nnn{OCView}{
          /Print<</PrintState/OFF>>
          /Export<</ExportState/OFF>>
        }{on}
        \tl_gset:cx{ocgxii_ocg_OCView}{\ocgbase_last_ocg:}
        %in case somebody wants to reopen with \begin{ocg}...
        \tl_gset:cx{ocgxii_ocg_OCView.opts}{
          showingui=never,printocg=never,exportocg=never
        }
        \ocgbase_new_ocg:nnn{OCPrint}{
          /Print<</PrintState/ON>>
          /Export<</ExportState/ON>>
        }{off}
        \tl_gset:cx{ocgxii_ocg_OCPrint}{\ocgbase_last_ocg:}
        \tl_gset:cx{ocgxii_ocg_OCPrint.opts}{
          showingui=never,printocg=always,exportocg=always
        }
        \ocgxii_enable_ocglinks:
        \iow_now:Nx\@mainaux{
          \token_to_str:N\ocgxii@newkey{ocgx2.ocg.OCView}{
            \tl_use:c{ocgxii_ocg_OCView}}
        }
        \iow_now:Nx\@mainaux{
          \token_to_str:N\ocgxii@newkey{ocgx2.ocg.OCPrint}{
            \tl_use:c{ocgxii_ocg_OCPrint}}
        }
      }
    }{
      \msg_error:nnn{ocgx2}{missing~package}{hyperref}
    }
  }
  \bool_if:NT\l_ocgxii_tikz_bool{\cs_set_eq:NN\ocgxii@trmspc\tl_trim_spaces:N}
}
\group_begin:
\bool_if:nF{
  \bool_lazy_or_p:nn{
    \bool_lazy_and_p:nn{
      \cs_if_exist_p:N\pdfmanagement_if_active_p:
    }{
      \pdfmanagement_if_active_p:
    }
  }{
    \bool_if_p:N\l_ocgxii_tikz_bool
  }
}{\aftergroup\endinput}
\group_end:
\ExplSyntaxOff
\if@ocgxii@testphase\else
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% TikZ related code follows (to be enabled with package option `tikz')

\RequirePackage{tikz}
\usetikzlibrary{calc}

% helper, replaces all spaces in #1 with `_'
\def\ocgxii@cnvspc#1{\expandafter\ocgxii@@cnvspc#1 \@nil}
\def\ocgxii@@cnvspc#1 #2\@nil{#1\ifx\@nil#2\@nil\else_\ocgxii@@cnvspc#2\@nil\fi}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Copyright notice: The code that follows until the end of the file was
% taken in large parts from Paul Gaborit's `tikzlibraryocgx.code.tex' with
% some additions/fixes:
%
%  - opts={...} inside ocg={...} allows ocg-environment options to be passed
%    to a TikZ scope
%
%  - The style ocmd={...} is another way for turning a TikZ scope into a PDF
%    layer (in addition to ocg={...}). It has two sub-keys, ref={...} and
%    visibility={...}, which have the same meaning as the optional and the
%    mandatory arguments of the `ocmd' environment
%
%  - TikZ objects to be turned into OCG switching links accept the additional
%    key
%
%      trigger ocg = onmousenter | onmouseexit | onmousedown | onmouseup |
%                      onmouseall
%
%    to react to various mouse gestures
%
%  - switching links properly sized and working in scaled tikzpictures
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\tikzset{
  ocg/.style={ocg/.cd,#1,/tikz/.cd},
  ocg={
    % parameters
    name/.store in=\ocgxii@name,
    opts/.store in=\ocgxii@opts,
    visibility/.store in=\ocgxii@visibility,
    status/.is choice,
    status/visible/.style={visibility=1},
    status/invisible/.style={visibility=0},
    status/true/.style={visibility=1},
    status/false/.style={visibility=0},
    status/on/.style={visibility=1},
    status/off/.style={visibility=0},
    status/1/.style={visibility=1},
    status/0/.style={visibility=0},
    % default values
    name=,
    opts=, % NEW
    status=on,
    % ref
    ref/.style={
      /tikz/execute at begin scope={%
        \begin{ocg}[\ocgxii@opts]{%
            \ifx\empty\ocgxii@name\empty#1\else\ocgxii@name\fi%
        }{#1}{\ocgxii@visibility}},
      /tikz/execute at end scope={\end{ocg}},
    }
  },
  ocmd/.style={
    ocmd/.cd,
    #1,
    /tikz/execute at begin scope={%
      \begin{ocmd}[\ocgxii@ocmdref]{\ocgxii@ocmdvisibility}%
    },
    /tikz/execute at end scope={\end{ocmd}},
    /tikz/.cd
  },
  ocmd={
    % parameters
    ref/.store in=\ocgxii@ocmdref,
    visibility/.store in=\ocgxii@ocmdvisibility,
    % default values
    ref=,
    visibility=,
  },
  trigger ocg/.store in=\ocgxii@trigger,
  trigger ocg/.value required,
  switch ocg/.style={
    postaction={
      path picture={
        \path (path picture bounding box.south west) coordinate (p1)
          (path picture bounding box.north east) coordinate (p2)
          (p1) node[inner sep=0pt,anchor=south west,outer sep=0pt] {%
            \ifdefined\ocgxii@trigger%
              \switchocg*[\ocgxii@trigger]{#1}{%
                \tikz \useasboundingbox (p1) rectangle (p2);}%
            \else%
              \switchocg*{#1}{\tikz \useasboundingbox (p1) rectangle (p2);}%
            \fi%
          };
      }
    }
  },
  switch ocg with mark on/.style 2 args={
    postaction={
      path picture={%
        \edef\ocgxii@argone{#1}%ocg ref for checkmark
        \ocgxii@trmspc\ocgxii@argone%
        \global\let\ocgxii@argone\ocgxii@argone%
        %default ocg ref for checkmark, if nothing provided in #1
        \xdef\ocgxii@argtwo{#2.mark}%
        \xdef\ocgxii@argtwo{\ocgxii@cnvspc{\ocgxii@argtwo}}%
        \begin{ocg}[showingui=false]{%
          \ifx\ocgxii@argone\@empty\ocgxii@argtwo\else\ocgxii@argone\fi%
        }{%
          \ifx\ocgxii@argone\@empty\ocgxii@argtwo\else\ocgxii@argone\fi%
        }{on}%
          \draw
          (path picture bounding box.south west)
          --
          (path picture bounding box.north east)
          (path picture bounding box.south east)
          --
          (path picture bounding box.north west)
          ;
        \end{ocg}%
      },
      switch ocg={%
        \ifx\ocgxii@argone\@empty\ocgxii@argtwo\else{\ocgxii@argone}\fi\space #2%
      }
    }
  },
  switch ocg with mark off/.style 2 args={
    postaction={
      path picture={%
        \edef\ocgxii@argone{#1}%ocg ref for checkmark
        \ocgxii@trmspc\ocgxii@argone%
        \global\let\ocgxii@argone\ocgxii@argone%
        %default ocg ref for checkmark, if nothing provided in #1
        \xdef\ocgxii@argtwo{#2.mark}%
        \xdef\ocgxii@argtwo{\ocgxii@cnvspc{\ocgxii@argtwo}}%
        \begin{ocg}[showingui=false]{%
          \ifx\ocgxii@argone\@empty\ocgxii@argtwo\else\ocgxii@argone\fi%
        }{%
          \ifx\ocgxii@argone\@empty\ocgxii@argtwo\else\ocgxii@argone\fi%
        }{off}%
          \draw
          (path picture bounding box.south west)
          --
          (path picture bounding box.north east)
          (path picture bounding box.south east)
          --
          (path picture bounding box.north west)
          ;
        \end{ocg}%
      },
      switch ocg={%
        \ifx\ocgxii@argone\@empty\ocgxii@argtwo\else{\ocgxii@argone}\fi\space #2%
      }
    }
  },
  show ocg/.style={
    postaction={
      path picture={
        \path (path picture bounding box.south west) coordinate (p1)
          (path picture bounding box.north east) coordinate (p2)
          (p1) node[inner sep=0pt,anchor=south west,outer sep=0pt] {%
            \ifdefined\ocgxii@trigger%
              \showocg*[\ocgxii@trigger]{#1}{%
                \tikz \useasboundingbox (p1) rectangle (p2);}%
            \else%
              \showocg*{#1}{\tikz \useasboundingbox (p1) rectangle (p2);}%
            \fi%
          };
      }
    }
  },
  hide ocg/.style={
    postaction={
      path picture={
        \path (path picture bounding box.south west) coordinate (p1)
          (path picture bounding box.north east) coordinate (p2)
          (p1) node[inner sep=0pt,anchor=south west,outer sep=0pt] {%
            \ifdefined\ocgxii@trigger%
              \hideocg*[\ocgxii@trigger]{#1}{%
                \tikz \useasboundingbox (p1) rectangle (p2);}%
            \else%
              \hideocg*{#1}{\tikz \useasboundingbox (p1) rectangle (p2);}%
            \fi%
          };
      }
    }
  },
  actions ocg/.style n args={3}{
    postaction={
      path picture={
        \path (path picture bounding box.south west) coordinate (p1)
          (path picture bounding box.north east) coordinate (p2)
          (p1) node[inner sep=0pt,anchor=south west,outer sep=0pt] {%
            \ifdefined\ocgxii@trigger%
              \actionsocg*[\ocgxii@trigger]{#1}{#2}{#3}{%
                \tikz \useasboundingbox (p1) rectangle (p2);}%
            \else%
              \actionsocg*{#1}{#2}{#3}{%
                \tikz \useasboundingbox (p1) rectangle (p2);}%
            \fi%
          };
      }
    }
  }
}
\fi
\begingroup
\if@ocgxii@testphase\else\aftergroup\endinput\fi
\endgroup
%%%%%%%%%%%%%%%%%%%%%% /pdfmanagement-testphase %%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ocgx2.sty
%
% Copyright 2015--\today, Alexander Grahn
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% The intent of this package is to be a drop-in replacement for the already
% existing CTAN package `ocgx' by Paul Gaborit, and also for `ocg-p' and `ocg'.
%
% It re-implements the functionality of the ocg, ocgx and ocg-p packages
% and adds support for all known engines and backends including
% latex+dvips+ps2pdf, xelatex, latex+dvipdfmx, lualatex.
%
% With ocgx2, PDF layers may extend across page breaks.
%
% ocgx2 implements OCMDs (optional content membership dictionaries)
%
% Adds some minor improvements, such as package options, remembering option.
% settings of reopened ocgs, correct behaviour of ocg switching links that were
% themselves placed on layers, compatibility with the animate and media9
% packages.
%
% Re-implements hyperref's `ocgcolorlinks' option to produce coloured links
% that may wrap around line breaks and page breaks.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License.
%
% The latest version of this license is in
%   http://mirrors.ctan.org/macros/latex/base/lppl.txt
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is A. Grahn.

\def\g@ocgxii@date@tl{2022/08/04}
\def\g@ocgxii@version@tl{0.55}

\ProvidesExplPackage{ocgx2}{\g@ocgxii@date@tl}{\g@ocgxii@version@tl}
{ports `ocgx' functionality to dvips+ps2pdf, xelatex and dvipdfmx}

%creating global definitions
\cs_new_protected:Npn\ocgxii@newkey#1#2{\tl_gset:cx{#1}{#2}}
\cs_new_protected:Npn\ocgxii@newkeynoexp#1#2{\tl_gset:cn{#1}{#2}}

\AtBeginDocument{
  \iow_now:Nx\@mainaux{
    \token_to_str:N\providecommand\token_to_str:N\ocgxii@newkey[2]{}
  }
  \iow_now:Nx\@mainaux{
    \token_to_str:N\providecommand\token_to_str:N\ocgxii@newkeynoexp[2]{}
  }
  \iow_now:Nx\@mainaux{
    \token_to_str:N\providecommand\token_to_str:N\ocgxii@ocg@stack@on@page[2]{}
  }
  \iow_now:Nx\@mainaux{
    \token_to_str:N\providecommand
      \token_to_str:N\ocgxii@lnkcol@stack@on@page[2]{}
  }
}

\msg_set:nnn{ocgx2}{generic~msg}{#1\\#2}

\msg_set:nnn{ocgx2}{missing~package}{
  Package~`#1'~must~be~loaded~before~ocgx2.\\\\
  Put\\\\
  \space\space\string\usepackage#2{#1}\\
  \space\space\string\usepackage[ocgcolorlinks]{ocgx2}\\\\
  to~the~preamble~of~your~document.
}

\msg_set:nnn{ocgx2}{beamer~and~ocgcolorlinks}{
  Option~`ocgcolorlinks'~cannot~be~used~with~class~Beamer.\\\\
  Using~`colorlinks'~instead.
}

% package options

\msg_set:nnnn{ocgx2}{unknown~package~option}{Unknown~package~option~`#1'.}{
  Package option~'#1'~is~unknown;\\
  perhaps~it~is~spelled~incorrectly.
}

\bool_new:N\g_ocgxii_dvipdfmx_bool
\bool_new:N\l_ocgxii_tikz_bool
\bool_new:N\l_ocgxii_ocgcolorlinks_bool
\bool_new:N\g_ocgxii_showingui_bool
\bool_new:N\l_ocgxii_showingui_bool

\keys_define:nn{ocgx2}{
  pdftex.code:n = {},
  pdftex.value_forbidden:n = true,

  luatex.code:n = {},
  luatex.value_forbidden:n = true,

  xetex.code:n = {},
  xetex.value_forbidden:n = true,

  dvips.code:n = {},
  dvips.value_forbidden:n = true,

  dvipdfmx .code:n = {
    \PassOptionsToPackage{dvipdfmx}{ocgbase}
  },
  dvipdfmx .value_forbidden:n = true,

  viewocg .choice:,
  viewocg / always .code:n={
    \tl_gset:Nn\g_ocgxii_view_tl{/View<</ViewState/ON>>}},
  viewocg / never .code:n={
    \tl_gset:Nn\g_ocgxii_view_tl{/View<</ViewState/OFF>>}},
  viewocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_view_tl},
  viewocg .default:n={ifvisible},

  printocg .choice:,
  printocg / always .code:n={
    \tl_gset:Nn\g_ocgxii_print_tl{/Print<</PrintState/ON>>}},
  printocg / never .code:n={
    \tl_gset:Nn\g_ocgxii_print_tl{/Print<</PrintState/OFF>>}},
  printocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_print_tl},
  printocg .default:n={ifvisible},

  exportocg .choice:,
  exportocg / always .code:n={
    \tl_gset:Nn\g_ocgxii_export_tl{/Export<</ExportState/ON>>}},
  exportocg / never .code:n={
    \tl_gset:Nn\g_ocgxii_export_tl{/Export<</ExportState/OFF>>}},
  exportocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_export_tl},
  exportocg .default:n={ifvisible},

  showingui .choices:nn = {true,false,always,never,iffirstuse}{
    \bool_if:nTF{
      \str_if_eq_p:ee{#1}{false} ||
      \str_if_eq_p:ee{#1}{never}
    }{
      \bool_gset_false:N\g_ocgxii_showingui_bool
    }{
      \bool_gset_true:N\g_ocgxii_showingui_bool
    }
  },
  showingui .default:n={true},

  listintoolbar .meta:n = {showingui=#1},
  listintoolbar .default:n={true},

  tikz .bool_set:N = \l_ocgxii_tikz_bool,
  tikz .default:n = true,

  ocgcolorlinks .bool_set:N = \l_ocgxii_ocgcolorlinks_bool,
  ocgcolorlinks .default:n = true,

  unknown .code:n = {
    \msg_error:nnx{ocgx2}{unknown~package~option}{\l_keys_key_tl}
  }
}

%package options preset
\keys_set:nn{ocgx2}{viewocg,printocg,exportocg,showingui,tikz=false}

%process package options
\ProcessKeyOptions[ocgx2]

\RequirePackage{ocgbase} %also loads pdfbase.sty

\bool_gset_eq:NN\g_ocgxii_dvipdfmx_bool\g_pbs_dvipdfmx_bool

\bool_if:NT\g_pbs_dvisvgm_bool{
  \msg_error:nnn{ocgx2}{generic~msg}{
    Package~`ocgx2'~is~incompatible~with~the~`dvisvgm'~backend.
  }
}

%re-implement ocg-p's `ocg' environment
\DeclareDocumentEnvironment{ocg}{O{}mmm}{
  \ocgxii_begin_ocg:nnnn{#1}{#2}{#3}{#4}
}{
  \ocgxii_end_ocg:
}

\cs_new_protected_nopar:Nn\ocgxii_begin_ocg:nnnn{
  \group_begin:
    \ocgxii_reset_cmd_opts:  % ... to the user-set package options
    \tl_set:Nx\l_ocgxii_argiv_tl{\tl_trim_spaces:n{#4}}
    \tl_if_exist:cTF{ocgxii_ocg_#3}{ %re-open existing layer
      \tl_set:Nx\l_tempa_tl{\tl_use:c{ocgxii_ocg_#3.opts},#1}
      \tl_gset:cx{ocgxii_ocg_#3.opts}{\l_tempa_tl} %new options appended
      \keys_set:nV{ocgx2/ocgenv}\l_tempa_tl
      \bool_if:nTF{ %initial visibility
        \str_if_eq_p:ee{\l_ocgxii_argiv_tl}{1} ||
        \str_if_eq_p:ee{\l_ocgxii_argiv_tl}{on} ||
        \str_if_eq_p:ee{\l_ocgxii_argiv_tl}{true}
      }{
        \ocgbase_del_from_off_list:n{\tl_use:c{ocgxii_ocg_#3}}
      }{
        \ocgbase_add_to_off_list:n{\tl_use:c{ocgxii_ocg_#3}}
      }
    }{
      \tl_set:Nx\l_tempa_tl{#1}
      \tl_gset:cx{ocgxii_ocg_#3.opts}{\l_tempa_tl}
      \keys_set:nV{ocgx2/ocgenv}\l_tempa_tl
      \ocgbase_new_ocg:nnn{#2}{
        \l_ocgxii_view_tl\l_ocgxii_print_tl\l_ocgxii_export_tl
      }{\l_ocgxii_argiv_tl}
      \tl_gset:cx{ocgxii_ocg_#3}{\ocgbase_last_ocg:}
      \tl_gset:cx{ocgx2.ocg.\ocgbase_last_ocg:}{\ocgbase_last_ocg:}
      \tl_gset:cx{ocgx2.ocg.#3}{\ocgbase_last_ocg:}
      \iow_now:Nx\@mainaux{
        \token_to_str:N\ocgxii@newkey{ocgx2.ocg.#3}{\ocgbase_last_ocg:}
      }
    }
    \bool_if:nT{
      !\cs_if_exist:cTF{ocgx2.ocg.#3}{
        \str_if_eq_p:ee{\tl_use:c{ocgx2.ocg.#3}}{\tl_use:c{ocgxii_ocg_#3}}
      }{
        \c_false_bool
      }
    }{
      \tl_if_exist:NF\g_ocgxii_rerunwarned_tl{
        \tl_new:N\g_ocgxii_rerunwarned_tl
        \AtEndDocument{\msg_warning:nn{ocgx2}{rerun}}
      }
    }
    \seq_map_inline:Nn\l_ocgxii_rbgrps_seq{% process list of radio btn groups
      \ocgbase_add_ocg_to_radiobtn_grp:nn{##1}{\tl_use:c{ocgxii_ocg_#3}}
    }
    \ocgbase_open_stack_push:n{\tl_use:c{ocgxii_ocg_#3}}
    \ocgxii_make_oc_entry:
    \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
    % insert OCG into Order tree
    \bool_if:NT\l_ocgxii_showingui_bool{
      \ocgbase_tree_node_begin:n{\tl_use:c{ocgxii_ocg_#3}}
    }
  \group_end:
  \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_#3}}
  \ignorespaces
}

\cs_new_protected_nopar:Nn\ocgxii_end_ocg:{
  \unskip
  \ocgbase_oc_emc:
  \ocgbase_tree_node_end:
  \ocgbase_open_stack_pop:N\l_trash_tl
  \ocgxii_make_oc_entry:
  \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
}

% OCMD implementation
\DeclareDocumentEnvironment{ocmd}{O{}m}{
  \ocgxii_begin_ocmd:on{#1}{#2}
  \ignorespaces
}{
  \unskip
  \ocgxii_end_ocmd:
}

\cs_new_protected_nopar:Nn\ocgxii_protected_dummy_cs:n{}

\cs_new_protected_nopar:Nn\ocgxii_begin_ocmd:nn{ % #1: id,
  \bool_if:nTF{                                  % #2: visib. expr. or policy
    \tl_if_blank:oTF{#1}{
      \c_false_bool
    }{
      \tl_if_exist_p:c{ocgxii_ocmd_#1}
    }
  }{
    % re-open existing ocmd
    \tl_set_eq:Nc\l_ocgxii_cur_ocmd_tl{ocgxii_ocmd_#1}
  }{
    % new ocmd
    \group_begin:
      \cs_set_eq:NN\AllOn \ocgxii_protected_dummy_cs:n
      \cs_set_eq:NN\AnyOn \ocgxii_protected_dummy_cs:n
      \cs_set_eq:NN\AnyOff\ocgxii_protected_dummy_cs:n
      \cs_set_eq:NN\AllOff\ocgxii_protected_dummy_cs:n
      \cs_set_eq:NN\Not   \ocgxii_protected_dummy_cs:n
      \cs_set_eq:NN\And   \ocgxii_protected_dummy_cs:n
      \cs_set_eq:NN\Or    \ocgxii_protected_dummy_cs:n
      \ocgxii_ocmd_read_visbility:xN{#2}\l_ocgxii_ocmd_visibility_tl
      \pdf_object_new:xn{g_object_\int_use:N\g_ocgbase_int _pdf}{dict}
      \pdf_object_write:xx{g_object_\int_use:N\g_ocgbase_int _pdf}{
        /Type/OCMD\l_ocgxii_ocmd_visibility_tl
      }
      \tl_gset:cx{g_pbs_objname_\pdf_object_ref_last: _tl}{
        g_object_\int_use:N\g_ocgbase_int _pdf
      }
      \int_gincr:N\g_ocgbase_int
      %if only visb. policy is given, generate equivalent visib. expression,
      %needed for stack of open layers and \ocgxii_make_oc_entry: command
      \ocgxii_ocmd_make_equiv_ve:xN{#2}\l_ocgxii_ocmd_equiv_ve_tl
      \tl_gset:co{ocgx2.ocmd.\pdf_object_ref_last:}{\l_ocgxii_ocmd_equiv_ve_tl}
    \group_end:
    \tl_set:Nx\l_ocgxii_cur_ocmd_tl{\pdf_object_ref_last:}
    \tl_if_blank:oF{#1}{
      \tl_gset:cx{ocgxii_ocmd_#1}{\pdf_object_ref_last:}
      \group_begin:
        \cs_set_eq:NN\AllOn \ocgxii_protected_dummy_cs:n
        \cs_set_eq:NN\AnyOn \ocgxii_protected_dummy_cs:n
        \cs_set_eq:NN\AnyOff\ocgxii_protected_dummy_cs:n
        \cs_set_eq:NN\AllOff\ocgxii_protected_dummy_cs:n
        \cs_set_eq:NN\Not   \ocgxii_protected_dummy_cs:n
        \cs_set_eq:NN\And   \ocgxii_protected_dummy_cs:n
        \cs_set_eq:NN\Or    \ocgxii_protected_dummy_cs:n
        \iow_now:Nx\@mainaux{\exp_not:N\ocgxii@newkeynoexp{ocgx2.ocmd.#1}{#2}}
      \group_end:
    }
  }
  \ocgbase_open_stack_push:n{\l_ocgxii_cur_ocmd_tl}
  \ocgxii_make_oc_entry:
  \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
  \ocgbase_oc_bdc:n{\l_ocgxii_cur_ocmd_tl}
}
\cs_generate_variant:Nn\ocgxii_begin_ocmd:nn{on}

\cs_new_protected_nopar:Nn\ocgxii_end_ocmd:{
  \ocgbase_oc_emc:
  \ocgbase_open_stack_pop:N\l_trash_tl
  \ocgxii_make_oc_entry: %update
  \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
}

%visibility expressions
\cs_new_protected_nopar:Nn\ocgxii_ocmd_read_visbility:nN{
  \int_zero:N\l_ocgxii_ve_cnt_int
  \int_zero:N\l_ocgxii_vp_cnt_int
  \tl_clear_new:N#2
  \clist_map_inline:nn{#1}{\ocgxii_omcd_parse_argument:nN{##1}#2}
}
\cs_generate_variant:Nn\ocgxii_ocmd_read_visbility:nN{xN}

\cs_new_protected_nopar:Nn\ocgxii_omcd_parse_argument:nN{
  \cs_set_eq:NN\AllOn \ocgxii_vp_check:n
  \cs_set_eq:NN\AnyOn \ocgxii_vp_check:n
  \cs_set_eq:NN\AnyOff\ocgxii_vp_check:n
  \cs_set_eq:NN\AllOff\ocgxii_vp_check:n
  \cs_set_eq:NN\Not\ocgxii_ve_check:n
  \cs_set_eq:NN\And\ocgxii_ve_check:n
  \cs_set_eq:NN\Or \ocgxii_ve_check:n
  \tl_if_exist:cTF{ocgx2.ocg.#1}{
    \msg_error:nnxx{ocgx2}{generic~msg}{
      OCG~ids~cannot~be~directly~used~in~the~visibility~argument~of~an~
      `ocmd'~environment.
    }{\g_ocgxii_help_msg_tl}
  }{
    \tl_if_exist:cTF{ocgx2.ocmd.#1}{
      \msg_error:nnxx{ocgx2}{generic~msg}{
        OCMD~ids~cannot~be~directly~used~in~the~visibility~argument~of~an~
        `ocmd'~environment.
      }{\g_ocgxii_help_msg_tl}
    }{
      \tl_if_exist:cTF{ocgxii_#1}{
        \str_case_e:nn{\tl_use:c{ocgxii_#1}}{
          {VisExpr}{
            \int_incr:N\l_ocgxii_ve_cnt_int
            \int_compare:nNnTF{\l_ocgxii_ve_cnt_int}>{1}{
              \msg_error:nnnn{ocgx2}{generic~msg}{
                More~than~one~visibility~expression~passed~to~the~`ocmd'~
                environment.
              }{
                At~most~one~visibility~expression~is~allowed.~A~visibility~
                expression~is~a~boolean~expression~built~by~nesting~any~number~of~
                \And{...},~\Or{...},~\Not{...}~commands.
              }
            }{
              \tl_put_right:Nx#2{/VE~}
              \ocgxii_ocmd_expression_parser:nN{#1}#2
            }
          }
          {VisPol}{
            \int_incr:N\l_ocgxii_vp_cnt_int
            \int_compare:nNnTF{\l_ocgxii_vp_cnt_int}>{1}{
              \msg_error:nnnn{ocgx2}{generic~msg}{
                More~than~one~visibility~policy~passed~to~the~`ocmd'~environment.
              }{
                At~most~one~visibility~policy~out~of~\AllOn{...},~\AnyOn{...},~
                \AnyOff{...},~\AllOff{...}~is~allowed.~Any~number~of~OCG~IDs,~
                separated~by~commas,~may~be~passed~as~arguments~to~these~
                commands,~but~commands~may~not~be~nested.~For~complex~visibilty~
                relations,~consider~using~a~visibility~expression.
              }
            }{
              \ocgxii_ocmd_expression_parser:nN{#1}#2
            }
          }
        }
      }{
        \msg_error:nnxx{ocgx2}{generic~msg}{
          The~visibility~argument~of~the~`ocmd'~environment~cannot~be~parsed.
        }{\g_ocgxii_help_msg_tl}
      }
    }
  }
}
\cs_generate_variant:Nn\ocgxii_omcd_parse_argument:nN{xN}
\cs_generate_variant:Nn\ocgxii_omcd_parse_argument:nN{oN}
\cs_new_protected_nopar:Nn\ocgxii_ocmd_expression_parser:nN{
  \cs_set_eq:NN\AllOn \ocgxii_vp_check:n
  \cs_set_eq:NN\AnyOn \ocgxii_vp_check:n
  \cs_set_eq:NN\AnyOff\ocgxii_vp_check:n
  \cs_set_eq:NN\AllOff\ocgxii_vp_check:n
  \cs_set_eq:NN\Not\ocgxii_ve_check:n
  \cs_set_eq:NN\And\ocgxii_ve_check:n
  \cs_set_eq:NN\Or \ocgxii_ve_check:n
  \tl_if_exist:cTF{ocgx2.ocg.#1}{% ocg reference
    \tl_put_right:Nx#2{~\tl_use:c{ocgx2.ocg.#1}}
  }{
    \tl_if_exist:cTF{ocgx2.ocmd.#1}{% ocmd reference
      \ocgxii_ocmd_expression_parser:vN{ocgx2.ocmd.#1}#2
    }{
      \tl_if_exist:cTF{ocgxii_#1}{% visib. bool expression or policy directive
        \bool_if:nTF{
          \str_if_eq_p:ee{\tl_use:c{ocgxii_#1}}{VisExpr} &&
          \bool_if_p:N\l_ocgxii_vp_open_bool ||
          \str_if_eq_p:ee{\tl_use:c{ocgxii_#1}}{VisPol} &&
          \bool_if_p:N\l_ocgxii_ve_open_bool
        }{
          \msg_error:nnxx{ocgx2}{generic~msg}{
            Visibility~policy~and~expression~commands~cannot~be~mixed.
          }{\g_ocgxii_help_msg_tl}
        }{
          \bool_if:nT{
            \str_if_eq_p:ee{\tl_use:c{ocgxii_#1}}{VisPol} &&
            \bool_if_p:N\l_ocgxii_vp_open_bool
          }{
            \msg_error:nnxx{ocgx2}{generic~msg}{
              Visibility~policy~commands~cannot~be~nested.~For~more~complex~
              visibilty~relations,~consider~using~a~visibility~expression.
            }{\g_ocgxii_help_msg_tl}
          }
        }
        \cs_set_eq:NN\AllOn \ocgxii_vp_allon:nN
        \cs_set_eq:NN\AnyOn \ocgxii_vp_anyon:nN
        \cs_set_eq:NN\AnyOff\ocgxii_vp_anyoff:nN
        \cs_set_eq:NN\AllOff\ocgxii_vp_alloff:nN
        \cs_set_eq:NN\Not\ocgxii_ve_not:nN
        \cs_set_eq:NN\And\ocgxii_ve_and:nN
        \cs_set_eq:NN\Or \ocgxii_ve_or:nN
        #1#2
      }{
        \msg_warning:nnx{ocgx2}{undefined~OCG}{#1}
        \tl_if_exist:NF\g_ocgxii_refundefwarned_tl{
          \tl_new:N\g_ocgxii_refundefwarned_tl
          \AtEndDocument{\msg_warning:nn{ocgx2}{undefined~OCGs}}
        }
      }
    }
  }
}
\cs_generate_variant:Nn\ocgxii_ocmd_expression_parser:nN{vN}
% visib. policy directives
\cs_new_protected_nopar:Nn\ocgxii_vp_allon:nN{
  \bool_set_true:N\l_ocgxii_vp_open_bool
  \tl_put_right:Nx#2{/P/AllOn/OCGs~\g_ocgxii_left_bracket_tl}
  \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
  \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
  \bool_set_false:N\l_ocgxii_vp_open_bool
}
\cs_new_protected_nopar:Nn\ocgxii_vp_anyon:nN{
  \bool_set_true:N\l_ocgxii_vp_open_bool
  \tl_gput_right:Nx#2{/P/AnyOn/OCGs~\g_ocgxii_left_bracket_tl}
  \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
  \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
  \bool_set_false:N\l_ocgxii_vp_open_bool
}
\cs_new_protected_nopar:Nn\ocgxii_vp_anyoff:nN{
  \bool_set_true:N\l_ocgxii_vp_open_bool
  \tl_gput_right:Nx#2{/P/AnyOff/OCGs~\g_ocgxii_left_bracket_tl}
  \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
  \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
  \bool_set_false:N\l_ocgxii_vp_open_bool
}
\cs_new_protected_nopar:Nn\ocgxii_vp_alloff:nN{
  \bool_set_true:N\l_ocgxii_vp_open_bool
  \tl_gput_right:Nx#2{/P/AllOff/OCGs~\g_ocgxii_left_bracket_tl}
  \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
  \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
  \bool_set_false:N\l_ocgxii_vp_open_bool
}
% policy to expression conversion
\cs_new_protected_nopar:Nn\ocgxii_ocmd_make_equiv_ve:nN{
  \int_zero:N\l_ocgxii_ve_cnt_int
  \tl_clear_new:N#2
  \clist_map_inline:nn{#1}{\ocgxii_omcd_convert_vp:nN{##1}#2}
}
\cs_generate_variant:Nn\ocgxii_ocmd_make_equiv_ve:nN{xN}

\cs_new_protected_nopar:Nn\ocgxii_omcd_convert_vp:nN{
  \cs_set_eq:NN\AllOn \ocgxii_vp_check:n
  \cs_set_eq:NN\AnyOn \ocgxii_vp_check:n
  \cs_set_eq:NN\AnyOff\ocgxii_vp_check:n
  \cs_set_eq:NN\AllOff\ocgxii_vp_check:n
  \cs_set_eq:NN\Not\ocgxii_ve_check:n
  \cs_set_eq:NN\And\ocgxii_ve_check:n
  \cs_set_eq:NN\Or \ocgxii_ve_check:n
  \tl_if_exist:cT{ocgxii_#1}{
    \str_case_e:nn{\tl_use:c{ocgxii_#1}}{
      {VisExpr}{
        \int_incr:N\l_ocgxii_ve_cnt_int
        \tl_set:Nn#2{#1}
      }
      {VisPol}{
        \int_compare:nNnT{\l_ocgxii_ve_cnt_int}={0}{
          \cs_set_eq:NN\AllOn \ocgxii_allon_to_ve:n
          \cs_set_eq:NN\AnyOn \ocgxii_anyon_to_ve:n
          \cs_set_eq:NN\AnyOff\ocgxii_anyoff_to_ve:n
          \cs_set_eq:NN\AllOff\ocgxii_alloff_to_ve:n
          \tl_set:No#2{#1}
        }
      }
    }
  }
}
\cs_new_protected_nopar:Nn\ocgxii_allon_to_ve:n{\And{#1}}
\cs_new_protected_nopar:Nn\ocgxii_anyon_to_ve:n{\Or{#1}}
\cs_new_protected_nopar:Nn\ocgxii_anyoff_to_ve:n{\Not{\And{#1}}}
\cs_new_protected_nopar:Nn\ocgxii_alloff_to_ve:n{\Not{\Or{#1}}}
% visib. boolean expressions
\cs_new_protected_nopar:Nn\ocgxii_ve_and:nN{
  \bool_set_true:N\l_ocgxii_ve_open_bool
  \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/And}
  \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
  \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
  \bool_set_false:N\l_ocgxii_ve_open_bool
}
\cs_new_protected_nopar:Nn\ocgxii_ve_or:nN{
  \bool_set_true:N\l_ocgxii_ve_open_bool
  \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/Or}
  \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
  \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
  \bool_set_false:N\l_ocgxii_ve_open_bool
}
\cs_new_protected_nopar:Nn\ocgxii_ve_not:nN{
  \bool_set_true:N\l_ocgxii_ve_open_bool
  % only one item allowed in \Not{...} argument
  \int_compare:nNnT{\clist_count:n{#1}}>{\c_one_int}{
    \msg_error:nnnn{ocgx2}{generic~msg}{
      More~than~one~item~passed~to~\Not{...}.
    }{
      Only~one~item~is~allowed.
    }
  }
  \int_compare:nNnT{\clist_count:n{#1}}={\c_one_int}{
    \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/Not}
    \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
    \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
  }
  \bool_set_false:N\l_ocgxii_ve_open_bool
}
\cs_new_protected_nopar:Nn\ocgxii_ve_check:n{VisExpr}
\tl_set:cn{ocgxii_VisExpr}{VisExpr}
\cs_new_protected_nopar:Nn\ocgxii_vp_check:n{VisPol}
\tl_set:cn{ocgxii_VisPol}{VisPol}
\tl_set:Nx\g_ocgxii_left_bracket_tl{\tl_to_str:N[}
\tl_set:Nx\g_ocgxii_right_bracket_tl{\tl_to_str:N]}
\int_new:N\l_ocgxii_vp_cnt_int %number of visib. policies
\int_new:N\l_ocgxii_ve_cnt_int %number of visib. expressions
\bool_new:N\l_ocgxii_vp_open_bool %for nesting test
\bool_new:N\l_ocgxii_ve_open_bool %for nesting test
\tl_set:Nn\g_ocgxii_help_msg_tl{
  At~most~one~visibility~policy~and,~separated~by~a~comma,~at~most~one~
  visibility~expression~may~be~passed~as~the~2nd~argument~to~the~`ocmd'~
  environment.~A~visibility~
  policy~is~defined~by~one~of~\AllOn{...},~\AnyOn{...},~\AnyOff{...},~
  \AllOff{...}.~A~visibility~expression~is~a~boolean~expression~built~by~
  nesting~any~number~of~\And{...},~\Or{...},~\Not{...}~commands.~If~both~are~
  provided,~the~visibility~expression~takes~precedence~over~the~policy,~but~the~
  latter~may~be~used~as~fallback~by~non-conforming~PDF~viewers.
}
%command that builds /OC entry from open layer stack
\cs_new_protected_nopar:Nn\ocgxii_make_oc_entry:{
  \group_begin:
  \tl_gclear:N\g_ocgxii_oc_entry_tl
  \tl_clear:N\l_tempa_tl
  \seq_if_empty:NF\g_ocgbase_open_stack_seq{
    \seq_clear:N\l_tempa_seq
    %additional level of braces around indirect PDF objects (needed for dvips)
    \seq_map_inline:Nn\g_ocgbase_open_stack_seq{
      \seq_put_right:Nn\l_tempa_seq{{##1}}
    }
    \ocgxii_omcd_parse_argument:xN{
      \exp_not:N\And{\seq_use:Nn\l_tempa_seq{,}}
    }\l_tempa_tl
    \tl_gset:Nx\g_ocgxii_oc_entry_tl{/OC~<</Type/OCMD\l_tempa_tl>>}
  }
  \group_end:
}
%programmer/author command that inserts /OC << >> entry; for use in
%annotation/xobject dicts, in order to make them layer-aware
\cs_new_nopar:Nn\ocgxii_insert_oc:{\g_ocgxii_oc_entry_tl}
\cs_gset_eq:NN\ocgbase_insert_oc:\ocgxii_insert_oc:
\cs_gset_eq:NN\ocgbase@insert@oc\ocgxii_insert_oc:
\tl_new:N\g_ocgxii_oc_entry_tl

\cs_new_protected_nopar:Nn\ocgxii_stack_shipout:NN{
  \iow_shipout_x:Nx\@mainaux{
    \token_to_str:N#1{
      \exp_not:N\int_use:N\g_ocgxii_page_int
    }{\seq_use:Nn#2{,}}
  }
}

\cs_new_protected_nopar:Npn\ocgxii@ocg@stack@on@page#1#2{
  \seq_gset_from_clist:cn{g_pending_ocgs_on_#1_seq}{#2}
  %re-add braces around items for dvips
  \bool_if:nT{\sys_if_output_dvi_p: && !\g_ocgxii_dvipdfmx_bool}{
    \seq_map_inline:cn{g_pending_ocgs_on_#1_seq}{
      \seq_gpop_left:cN{g_pending_ocgs_on_#1_seq}\l_trash_tl
      \seq_gput_right:cn{g_pending_ocgs_on_#1_seq}{{##1}}
    }
  }
}
\ocgxii@ocg@stack@on@page{0}{} %initialize

\cs_new_protected_nopar:Npn\ocgxii@lnkcol@stack@on@page#1#2{
  \seq_gset_from_clist:cn{g_pending_lnkcols_on_#1_seq}{#2}
}
\ocgxii@lnkcol@stack@on@page{0}{} %initialize

%end-of-page action
\pbs_eop_action:n{
  \seq_if_exist:cT{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{
    %check whether end-of-page link colour stack has settled
    \iow_shipout:Nx\@mainaux{
      \token_to_str:N\ocgxii@newkey{ocgx2.oldlnkcol.\int_use:N\g_ocgxii_page_int}{
        \seq_use:cn{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
      }
    }
    \bool_if:nT{
      !\cs_if_exist:cTF{ocgx2.oldlnkcol.\int_use:N\g_ocgxii_page_int}{
        \str_if_eq_p:ee{
          \tl_use:c{ocgx2.oldlnkcol.\int_use:N\g_ocgxii_page_int}
        }{
          \seq_use:cn{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
        }
      }{
        \c_false_bool
      }
    }{
      \tl_if_exist:NF\g_ocgxii_rerunwarned_tl{
        \tl_new:N\g_ocgxii_rerunwarned_tl
        \AtEndDocument{\msg_warning:nn{ocgx2}{rerun}}
      }
    }
    % now close the colourlink opened last
    \seq_get:cNT{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}\l_tmpa_tl{
      \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
      \ocgxii_colourlink_end:
    }
  }
  %check whether end-of-page ocg stack has settled
  \iow_shipout:Nx\@mainaux{
    \token_to_str:N\ocgxii@newkey{ocgx2.oldstack.\int_use:N\g_ocgxii_page_int}{
      \seq_use:cn{g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
    }
  }
  \bool_if:nT{
    !\cs_if_exist:cTF{ocgx2.oldstack.\int_use:N\g_ocgxii_page_int}{
      \str_if_eq_p:ee{
        \tl_use:c{ocgx2.oldstack.\int_use:N\g_ocgxii_page_int}
      }{
        \seq_use:cn{g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
      }
    }{
      \c_false_bool
    }
  }{
    \tl_if_exist:NF\g_ocgxii_rerunwarned_tl{
      \tl_new:N\g_ocgxii_rerunwarned_tl
      \AtEndDocument{\msg_warning:nn{ocgx2}{rerun}}
    }
  }
  %now close pending ocgs
  \seq_map_variable:cNn{
    g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq
  }\l_tmpb_tl{\ocgbase_oc_emc:}
}

%begin-of-page action
\pbs_bop_action:n{
  % re-open all pending ocgs in original order
  \seq_set_eq:Nc\l_ocgxii_pending_ocgs_seq{
    g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq
  }
  \seq_reverse:N\l_ocgxii_pending_ocgs_seq
  \seq_map_variable:NNn\l_ocgxii_pending_ocgs_seq\l_tmpa_tl{
    \ocgbase_oc_bdc:n{\l_tmpa_tl}
  }
  % re-open the colourlink opened last
  \seq_get:cNT{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}\l_tmpa_tl{
    \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
    \ocgxii_colourlink_begin:
  }
  \int_gincr:N\g_ocgxii_page_int
  % copy pending ocg stack from previous page, if it has not been initialized
  % yet from aux file
  \seq_if_exist:cF{g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq}{
    \seq_gset_eq:cc{
      g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq
    }{
      g_pending_ocgs_on_\int_eval:n{\g_ocgxii_page_int-\c_one_int}_seq
    }
  }
  %the same for link colour stack
  \seq_if_exist:cF{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{
    \seq_gset_eq:cc{
      g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq
    }{
      g_pending_lnkcols_on_\int_eval:n{\g_ocgxii_page_int-\c_one_int}_seq
    }
  }
}
\int_new:N\g_ocgxii_page_int %abs. page counter

\cs_new_protected_nopar:Nn\ocgxii_ocglist_reset:{
  \tl_clear_new:N\l_ocgxii_u_list_tl
  \tl_clear_new:N\l_ocgxii_d_list_tl
  \tl_clear_new:N\l_ocgxii_e_list_tl
  \tl_clear_new:N\l_ocgxii_x_list_tl
}

\cs_new_protected_nopar:Nn\ocgxii_ocglist_build:Nn{
  \tl_set:Nx\l_ocglistarg_tl{#2}\tl_trim_spaces:N\l_ocglistarg_tl
  % first try splitting at commas (ocgx2 syntax)
  \tl_set_eq:NN\l_tmpa_tl\l_ocglistarg_tl
  \tl_remove_all:Nn\l_tmpa_tl{~}
  \seq_set_split:NnV\l_ocgxii_ocglistarg_seq{,}\l_tmpa_tl
  \seq_remove_all:Nn\l_ocgxii_ocglistarg_seq{}
  \tl_set:Nx\l_tmpa_tl{\seq_count:N\l_ocgxii_ocglistarg_seq}
  % now at spaces (legacy ocgx/ocg-p)
  \tl_set_eq:NN\l_tmpb_tl\l_ocglistarg_tl
  \tl_remove_all:Nn\l_tmpb_tl{,}
  \seq_set_split:NnV\l_tmpb_seq{~}\l_tmpb_tl
  \seq_remove_all:Nn\l_tmpb_seq{}
  \tl_set:Nx\l_tmpb_tl{\seq_count:N\l_tmpb_seq}
  %take the seq having more elements (guessing the separator most likely used)
  \int_compare:nT{\l_tmpb_tl>\l_tmpa_tl}{
    \seq_set_eq:NN\l_ocgxii_ocglistarg_seq\l_tmpb_seq
  }
  \seq_map_variable:NNn\l_ocgxii_ocglistarg_seq\l_tempa_tl{
    \ocgxii_process_ocgref:NN#1\l_tempa_tl
  }
}

\cs_new_protected_nopar:Nn\ocgxii_commalist_process:n{
  \seq_set_split:Nnn\l_tmpa_seq{,}{#1}
  \ocgxii_ocglist_build:Nn\l_ocgxii_e_list_tl{\seq_item:Nn\l_tmpa_seq{1}}
  \ocgxii_ocglist_build:Nn\l_ocgxii_x_list_tl{\seq_item:Nn\l_tmpa_seq{2}}
  \ocgxii_ocglist_build:Nn\l_ocgxii_d_list_tl{\seq_item:Nn\l_tmpa_seq{3}}
  \ocgxii_ocglist_build:Nn\l_ocgxii_u_list_tl{\seq_item:Nn\l_tmpa_seq{4}}
}

\cs_new_protected_nopar:Nn\ocgxii_ocglist_process_idlist:nn{
  \ocgxii_ocglist_reset:
  \tl_set:Nx\l_ocgxii_opt_tl{#1}\tl_remove_all:Nn\l_ocgxii_opt_tl{~}
  \str_case_e:nnF{\l_ocgxii_opt_tl}{
    {onmouseup}{
      \ocgxii_ocglist_build:Nn\l_ocgxii_u_list_tl{#2}
    }
    {onmousedown}{
      \ocgxii_ocglist_build:Nn\l_ocgxii_d_list_tl{#2}
    }
    {onmouseenter}{
      \ocgxii_ocglist_build:Nn\l_ocgxii_e_list_tl{#2}
    }
    {onmouseexit}{
      \ocgxii_ocglist_build:Nn\l_ocgxii_x_list_tl{#2}
    }
    {onmouseall}{
      \ocgxii_commalist_process:n{#2}
    }
  }{
    \msg_error:nnx{ocgx2}{unknown~option}{\l_ocgxii_opt_tl}
  }
}

\int_new:N\g_ocgxii_widcount_int% widget counter

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% re-implement commands from ocgx.sty (all engines including ps2pdf [gs>=9.15])
% adding optional `*' (arg 1) -> non-breakable link instead of plain (multiline)
% Link;
% adding optional 2nd argument -> Button Widget (non-breakable) with one of
% various mouse triggers (`troggerocgs` option from ocg-p)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\DeclareDocumentCommand\switchocg{s O{} m +m}{
  \ocgxii_actionsocg:nnnnnn{#1}{#2}{#3}{}{}{#4}
}

\DeclareDocumentCommand\showocg{s O{} m +m}{
  \ocgxii_actionsocg:nnnnnn{#1}{#2}{}{#3}{}{#4}
}

\DeclareDocumentCommand\hideocg{s O{} m +m}{
  \ocgxii_actionsocg:nnnnnn{#1}{#2}{}{}{#3}{#4}
}

\DeclareDocumentCommand\actionsocg{s O{} m m m +m}{
  \ocgxii_actionsocg:nnnnnn{#1}{#2}{#3}{#4}{#5}{#6}
}

\bool_new:N\l_ocgxii_mouse_triggers_bool
\bool_new:N\l_ocgxii_nobreak_bool
\cs_new_protected:Nn\ocgxii_actionsocg:nnnnnn{
  \group_begin:
  \mode_leave_vertical:
  \bool_set_false:N\l_ocgxii_mouse_triggers_bool
  \bool_set_false:N\l_ocgxii_nobreak_bool
  % explicitly non-breakable?
  \bool_if:nT{#1}{\bool_set_true:N\l_ocgxii_nobreak_bool}
  %
  %clear actions for various mouse triggers (e,d,x)
  \tl_clear:N\l_ocgxii_toswitch_e_tl
  \tl_clear:N\l_ocgxii_toswitch_x_tl
  \tl_clear:N\l_ocgxii_toswitch_d_tl
  \tl_clear:N\l_ocgxii_toshow_e_tl
  \tl_clear:N\l_ocgxii_toshow_x_tl
  \tl_clear:N\l_ocgxii_toshow_d_tl
  \tl_clear:N\l_ocgxii_tohide_e_tl
  \tl_clear:N\l_ocgxii_tohide_x_tl
  \tl_clear:N\l_ocgxii_tohide_d_tl
  %
  %process *all* mouse triggers (e,d,u,x)
  \ocgxii_ocglist_process_idlist:nn{
    \tl_if_blank:oTF{#2}{onmouseup}{#2}
  }{#3}
  \tl_set_eq:NN\l_ocgxii_toswitch_e_tl\l_ocgxii_e_list_tl
  \tl_set_eq:NN\l_ocgxii_toswitch_x_tl\l_ocgxii_x_list_tl
  \tl_set_eq:NN\l_ocgxii_toswitch_d_tl\l_ocgxii_d_list_tl
  \tl_set_eq:NN\l_ocgxii_toswitch_u_tl\l_ocgxii_u_list_tl
  \ocgxii_ocglist_process_idlist:nn{
    \tl_if_blank:oTF{#2}{onmouseup}{#2}
  }{#4}
  \tl_set_eq:NN\l_ocgxii_toshow_e_tl\l_ocgxii_e_list_tl
  \tl_set_eq:NN\l_ocgxii_toshow_x_tl\l_ocgxii_x_list_tl
  \tl_set_eq:NN\l_ocgxii_toshow_d_tl\l_ocgxii_d_list_tl
  \tl_set_eq:NN\l_ocgxii_toshow_u_tl\l_ocgxii_u_list_tl
  \ocgxii_ocglist_process_idlist:nn{
    \tl_if_blank:oTF{#2}{onmouseup}{#2}
  }{#5}
  \tl_set_eq:NN\l_ocgxii_tohide_e_tl\l_ocgxii_e_list_tl
  \tl_set_eq:NN\l_ocgxii_tohide_x_tl\l_ocgxii_x_list_tl
  \tl_set_eq:NN\l_ocgxii_tohide_d_tl\l_ocgxii_d_list_tl
  \tl_set_eq:NN\l_ocgxii_tohide_u_tl\l_ocgxii_u_list_tl
  %any triggers apart from mouse-up?
  \str_if_eq:eeF{
    \l_ocgxii_toswitch_e_tl\l_ocgxii_toswitch_x_tl\l_ocgxii_toswitch_d_tl
    \l_ocgxii_toshow_e_tl\l_ocgxii_toshow_x_tl\l_ocgxii_toshow_d_tl
    \l_ocgxii_tohide_e_tl\l_ocgxii_tohide_x_tl\l_ocgxii_tohide_d_tl
  }{}{
    \bool_set_true:N\l_ocgxii_mouse_triggers_bool
  }
  %
  \bool_if:nTF{\l_ocgxii_nobreak_bool || \l_ocgxii_mouse_triggers_bool}{
    \hbox_set:Nn\l_tmpa_box{#6}
    \bool_if:NTF\l_ocgxii_mouse_triggers_bool{
      % e,d,x mouse triggers require (non-breakable) /Widget annot
      \pdfannot_dict_put:nnn{link/GoTo}{Subtype}{/Widget}
      \pdfannot_dict_remove:nn{link/GoTo}{Border}
    }{
      \pdfannot_dict_put:nnn{link/GoTo}{Border}{[0~0~0]}
    }
    \pdfannot_dict_remove:nn{link/GoTo}{C}
    \pbs_pdfannot:nnnn{
      \dim_use:N\box_wd:N\l_tmpa_box}{
      \dim_use:N\box_ht:N\l_tmpa_box}{
      \dim_use:N\box_dp:N\l_tmpa_box
    }{
      \pdfannot_dict_use:n{link/GoTo}
      \bool_if:NTF\l_ocgxii_mouse_triggers_bool{
        /Ff~65536/FT/Btn/BS<</W~0>>
        /T~(ocgx2@\int_use:N\g_ocgxii_widcount_int)
        %treat mouse-up as mouse-click --> handle through /A dictionary
        \str_if_eq:eeF{}{
          \l_ocgxii_toswitch_u_tl\l_ocgxii_toshow_u_tl\l_ocgxii_tohide_u_tl
        }{
          /A <</S/SetOCGState/State [
            \str_if_eq:VnF\l_ocgxii_toswitch_u_tl{}{
              /Toggle~\l_ocgxii_toswitch_u_tl
            }
            \str_if_eq:VnF\l_ocgxii_toshow_u_tl{}{
              /ON~\l_ocgxii_toshow_u_tl
            }
            \str_if_eq:VnF\l_ocgxii_tohide_u_tl{}{
              /OFF~\l_ocgxii_tohide_u_tl
            }
          ]>>
        }
        % other mouse triggers need add. actions dict
        /AA <<
          %\str_if_eq:eeF{}{ % mouse-up
          %  \l_ocgxii_toswitch_u_tl\l_ocgxii_toshow_u_tl\l_ocgxii_tohide_u_tl
          %}{
          %  /U <</S/SetOCGState/State [
          %    \str_if_eq:VnF\l_ocgxii_toswitch_u_tl{}{
          %      /Toggle~\l_ocgxii_toswitch_u_tl
          %    }
          %    \str_if_eq:VnF\l_ocgxii_toshow_u_tl{}{
          %      /ON~\l_ocgxii_toshow_u_tl
          %    }
          %    \str_if_eq:VnF\l_ocgxii_tohide_u_tl{}{
          %      /OFF~\l_ocgxii_tohide_u_tl
          %    }
          %  ]>>
          %}
          \str_if_eq:eeF{}{ % mouse-down
            \l_ocgxii_toswitch_d_tl\l_ocgxii_toshow_d_tl\l_ocgxii_tohide_d_tl
          }{
            /D <</S/SetOCGState/State [
              \str_if_eq:VnF\l_ocgxii_toswitch_d_tl{}{
                /Toggle~\l_ocgxii_toswitch_d_tl
              }
              \str_if_eq:VnF\l_ocgxii_toshow_d_tl{}{
                /ON~\l_ocgxii_toshow_d_tl
              }
              \str_if_eq:VnF\l_ocgxii_tohide_d_tl{}{
                /OFF~\l_ocgxii_tohide_d_tl
              }
            ]>>
          }
          \str_if_eq:eeF{}{ % mouse-enter
            \l_ocgxii_toswitch_e_tl\l_ocgxii_toshow_e_tl\l_ocgxii_tohide_e_tl
          }{
            /E <</S/SetOCGState/State [
              \str_if_eq:VnF\l_ocgxii_toswitch_e_tl{}{
                /Toggle~\l_ocgxii_toswitch_e_tl
              }
              \str_if_eq:VnF\l_ocgxii_toshow_e_tl{}{
                /ON~\l_ocgxii_toshow_e_tl
              }
              \str_if_eq:VnF\l_ocgxii_tohide_e_tl{}{
                /OFF~\l_ocgxii_tohide_e_tl
              }
            ]>>
          }
          \str_if_eq:eeF{}{ % mouse-exit
            \l_ocgxii_toswitch_x_tl\l_ocgxii_toshow_x_tl\l_ocgxii_tohide_x_tl
          }{
            /X <</S/SetOCGState/State [
              \str_if_eq:VnF\l_ocgxii_toswitch_x_tl{}{
                /Toggle~\l_ocgxii_toswitch_x_tl
              }
              \str_if_eq:VnF\l_ocgxii_toshow_x_tl{}{
                /ON~\l_ocgxii_toshow_x_tl
              }
              \str_if_eq:VnF\l_ocgxii_tohide_x_tl{}{
                /OFF~\l_ocgxii_tohide_x_tl
              }
            ]>>
          }
        >>
      }{
        %mouse-up alone
        /A <</S/SetOCGState
          /State [
            \str_if_eq:VnF{\l_ocgxii_toswitch_u_tl}{}{
              /Toggle~\l_ocgxii_toswitch_u_tl}~
            \str_if_eq:VnF{\l_ocgxii_toshow_u_tl}{}{/ON~\l_ocgxii_toshow_u_tl}~
            \str_if_eq:VnF{\l_ocgxii_tohide_u_tl}{}{/OFF~\l_ocgxii_tohide_u_tl}
          ]
        >>
      }
    }\box_use_drop:N\l_tmpa_box
    \bool_if:NT\l_ocgxii_mouse_triggers_bool{
      \pbs_appendtofields:n{\pbs_pdflastann:}
      \int_gincr:N\g_ocgxii_widcount_int
    }
  }{
    %line-breakable annotation
    \pbs_pdflink:nn{
      %look and feel of hyperref internal links
      \pdfannot_dict_use:n{link/GoTo}
      /A <</S/SetOCGState
        /State [
          \str_if_eq:VnF{\l_ocgxii_toswitch_u_tl}{}{
            /Toggle~\l_ocgxii_toswitch_u_tl}~
          \str_if_eq:VnF{\l_ocgxii_toshow_u_tl}{}{/ON~\l_ocgxii_toshow_u_tl}~
          \str_if_eq:VnF{\l_ocgxii_tohide_u_tl}{}{/OFF~\l_ocgxii_tohide_u_tl}
        ]
      >>
    }{
      \hook_use:n{pdfannot/link/GoTo/begin}
      #6
      \hook_use:n{pdfannot/link/GoTo/end}
    }
  }
  \group_end:
}

%mimic commands from ocg-p
\keys_define:nn{ocgx2/ocgpcmd}{
  triggerocg .choices:nn = {
    onmouseenter, onmouseexit, onmousedown, onmouseup, allactions
  }{
    \str_if_eq:eeTF{\l_keys_choice_tl}{allactions}{
      \tl_set:Nn\l_ocgxii_trigger_tl{onmouseall}
    }{
      \tl_set_eq:NN\l_ocgxii_trigger_tl\l_keys_choice_tl
    }
  }
}
\DeclareDocumentCommand\toggleocgs{O{} m +m}{
  \tl_clear_new:N\l_ocgxii_trigger_tl
  \keys_set:nn{ocgx2/ocgpcmd}{#1}
  \switchocg*[\l_ocgxii_trigger_tl]{#2}{#3}
}
\DeclareDocumentCommand\showocgs{O{} m +m}{
  \tl_clear_new:N\l_ocgxii_trigger_tl
  \keys_set:nn{ocgx2/ocgpcmd}{#1}
  \showocg*[\l_ocgxii_trigger_tl]{#2}{#3}
}
\DeclareDocumentCommand\hideocgs{O{} m +m}{
  \tl_clear_new:N\l_ocgxii_trigger_tl
  \keys_set:nn{ocgx2/ocgpcmd}{#1}
  \hideocg*[\l_ocgxii_trigger_tl]{#2}{#3}
}
\DeclareDocumentCommand\setocgs{O{} m m m +m}{
  \tl_clear_new:N\l_ocgxii_trigger_tl
  \keys_set:nn{ocgx2/ocgpcmd}{#1}
  \actionsocg*[\l_ocgxii_trigger_tl]{#2}{#3}{#4}{#5}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cs_new_protected:Nn\ocgxii_process_ocgref:NN{
  \tl_if_exist:cTF{ocgx2.ocg.#2}{
    \tl_put_right:Nx#1{~\tl_use:c{ocgx2.ocg.#2}}
  }{
    \msg_warning:nnx{ocgx2}{undefined~OCG}{#2}
    \tl_if_exist:NF\g_ocgxii_refundefwarned_tl{
      \tl_new:N\g_ocgxii_refundefwarned_tl
      \AtEndDocument{\msg_warning:nn{ocgx2}{undefined~OCGs}}
    }
  }
}

%ocg environment opts
\keys_define:nn{ocgx2/ocgenv}{
  viewocg .choice:,
  viewocg / always .code:n={
    \tl_set:Nn\l_ocgxii_view_tl{/View<</ViewState/ON>>}},
  viewocg / never .code:n={
    \tl_set:Nn\l_ocgxii_view_tl{/View<</ViewState/OFF>>}},
  viewocg / ifvisible .code:n={
    \tl_clear:N\l_ocgxii_view_tl},
  viewocg .default:n={ifvisible},

  printocg .choice:,
  printocg / always .code:n={
    \tl_set:Nn\l_ocgxii_print_tl{/Print<</PrintState/ON>>}},
  printocg / never .code:n={
    \tl_set:Nn\l_ocgxii_print_tl{/Print<</PrintState/OFF>>}},
  printocg / ifvisible .code:n={
    \tl_clear:N\l_ocgxii_print_tl},
  printocg .default:n={ifvisible},

  exportocg .choice:,
  exportocg / always .code:n={
    \tl_set:Nn\l_ocgxii_export_tl{/Export<</ExportState/ON>>}},
  exportocg / never .code:n={
    \tl_set:Nn\l_ocgxii_export_tl{/Export<</ExportState/OFF>>}},
  exportocg / ifvisible .code:n={\tl_clear:N\l_ocgxii_export_tl},
  exportocg .default:n={ifvisible},

  showingui .choices:nn = {true,false,always,never,iffirstuse}{
    \bool_if:nTF{
      \str_if_eq_p:ee{#1}{false} ||
      \str_if_eq_p:ee{#1}{never}
    }{
      \bool_set_false:N\l_ocgxii_showingui_bool
    }{
      \bool_set_true:N\l_ocgxii_showingui_bool
    }
  },
  showingui .default:n={true},

  listintoolbar .meta:n = {showingui=#1},
  listintoolbar .default:n={true},

  radiobtngrps .code:n = {
    \clist_map_inline:nn{#1}{
      \seq_if_in:NxF\l_ocgxii_rbgrps_seq{##1}{
        \seq_put_right:Nx\l_ocgxii_rbgrps_seq{##1}
      }
    }
  },
  radiobtngrps .value_required:n = {true},
  radiobtngrp .meta:n={radiobtngrps={#1}},
  radiobtngrp .value_required:n = {true}
}

\cs_new_protected:Nn\ocgxii_reset_cmd_opts:{
  \tl_set_eq:NN\l_ocgxii_view_tl\g_ocgxii_view_tl
  \tl_set_eq:NN\l_ocgxii_print_tl\g_ocgxii_print_tl
  \tl_set_eq:NN\l_ocgxii_export_tl\g_ocgxii_export_tl
  \bool_set_eq:NN\l_ocgxii_showingui_bool\g_ocgxii_showingui_bool
  %stack of radio button group names the current ocg belongs to
  \seq_clear_new:N\l_ocgxii_rbgrps_seq
}

\msg_set:nnn{ocgx2}{rerun}{Rerun~to~get~OCG~references~right!}
\msg_set:nnn{ocgx2}{undefined~OCG}{
  Line~\msg_line_number: :~OCG~`#1'~is~not~defined.
}
\msg_set:nnn{ocgx2}{undefined~OCGs}{There~were~undefined~OCGs!}
\msg_set:nnn{ocgx2}{unknown~option}{
  Line~\msg_line_number: :~unknown~option~`#1'.
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% allows `ocgcolorlinks' to extend over line-breaks AND page-breaks with
% pdftex, luatex, xetex, dvipdfmx drivers
%
% based on Ben Lerner's idea
%   http://tex.stackexchange.com/a/104227;
% with some improvements
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\bool_if:NT\l_ocgxii_ocgcolorlinks_bool{
  % option ocgcolorlinks and beamer are not compatible
  \@ifclassloaded{beamer}{
    \bool_set_false:N\l_ocgxii_ocgcolorlinks_bool
    \hypersetup{colorlinks}
    \msg_warning:nn{ocgx2}{beamer~and~ocgcolorlinks}
  }{}
  % make sure that hyperref has been loaded if `ocgcolorlinks' is set via
  % pkg option
  \@ifpackageloaded{hyperref}{
    \hypersetup{ocgcolorlinks}
  }{
    \msg_error:nnn{ocgx2}{missing~package}{hyperref}
  }
}

% we'll be using the downscaled space character (32) from the pzdr
% (dingbats) font at the start and at the end of every ocgcolorlink
\cs_new_protected_nopar:Npn\ocgxii_tiny_space_char:{
  \group_begin: \font\l_tmpa_tl=pzdr~scaled~1\l_tmpa_tl\char32 \group_end:
}

\@ifpackageloaded{hyperref}{
  \bool_if:nTF{\sys_if_output_dvi_p: && !\g_ocgxii_dvipdfmx_bool}{
    \prop_map_inline:Nn\c__hyp_map_hyp_annot_prop{
      \hook_gremove_code:nn{pdfannot/link/#2/begin}{hyp/ocg}
      \hook_gput_code:nnn{pdfannot/link/#2/begin}{hyp/ocg}{
        \bool_if:cT{l_hyp_annot_ocgcolor#1_bool}{
          \ocgxii_colorlinks_init:
          \group_begin:
          \color_export:nnN{hyp/color/#1}{backend}\l_tempb_tl
          \tl_set:Nx\l_tempa_tl{\tl_item:Nn\l_tempb_tl{1}}
          \tl_set:Nx\l_tempb_tl{\tl_item:Nn\l_tempb_tl{2}}
          \str_replace_all:Nnn\l_tempb_tl{~}{,}
          \tl_set:Nx\l_ocgxii_lnkcol_tl{{\l_tempa_tl}{\l_tempb_tl}}
          \ocgxii_colourlink_nobreak_begin:
        }
      }
      \hook_gremove_code:nn{pdfannot/link/#2/end}{hyp/ocg}
      \hook_gput_code:nnn{pdfannot/link/#2/end}{hyp/ocg}{
        \bool_if:cT{l_hyp_annot_ocgcolor#1_bool}{
          \ocgxii_colourlink_nobreak_end:
          \group_end:
        }
      }
    }
  }{
    \prop_map_inline:Nn\c__hyp_map_hyp_annot_prop{
      \hook_gremove_code:nn{pdfannot/link/#2/begin}{hyp/ocg}
      \hook_gput_code:nnn{pdfannot/link/#2/begin}{hyp/ocg}{
        \bool_if:cT{l_hyp_annot_ocgcolor#1_bool}{
          \ocgxii_colorlinks_init:
          \seq_get_left:NNT\g_ocgxii_lnk_color_seq\l_tmpa_tl{
            \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
            \ocgxii_colourlink_end:
          }
          \group_begin:
          \ocgxii_colourlink_begin:
          %query current link colour, export it into backend format
          %and put it on the link colour stack
          \color_export:nnN{hyp/color/#1}{backend}\l_tempb_tl
          \tl_set:Nx\l_tempa_tl{\tl_item:Nn\l_tempb_tl{1}} % model
          \tl_set:Nx\l_tempb_tl{\tl_item:Nn\l_tempb_tl{2}} % components
          \str_replace_all:Nnn\l_tempb_tl{~}{,}
          \seq_gpush:Nx\g_ocgxii_lnk_color_seq{{\l_tempa_tl}{\l_tempb_tl}}
          \ocgxii_stack_shipout:NN\ocgxii@lnkcol@stack@on@page\g_ocgxii_lnk_color_seq
        }
      }
      \hook_gremove_code:nn{pdfannot/link/#2/end}{hyp/ocg}
      \hook_gput_code:nnn{pdfannot/link/#2/end}{hyp/ocg}{
        \bool_if:cT{l_hyp_annot_ocgcolor#1_bool}{
          \seq_gpop:NN\g_ocgxii_lnk_color_seq\l_tmpa_tl
          \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
          \ocgxii_stack_shipout:NN\ocgxii@lnkcol@stack@on@page\g_ocgxii_lnk_color_seq
          \ocgxii_colourlink_end:
          \group_end:
          \seq_get_left:NNT\g_ocgxii_lnk_color_seq\l_tmpa_tl{
            \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
            \ocgxii_colourlink_begin:
          }
        }
      }
    }
  }
}{}

\seq_new:N\g_ocgxii_lnk_color_seq %stack of colours of currently open links

\cs_new_protected_nopar:Nn\ocgxii_colourlink_begin:{
  %tiny space char put here in order to neutralise possible transformation
  %matrix modifications from previous \pdfliteral{} (TikZ makes a lot use of it)
  \hbox_overlap_left:n{\ocgxii_tiny_space_char:}
  \pbs_literal:nn{page}{q~7~Tr}
}
\cs_new_protected_nopar:Nn\ocgxii_colourlink_end:{
  %a tiny space char should keep empty link annots from flooding the page
  % with link colour
  %tiny space char put here in order to neutralise possible transformation
  \hbox_overlap_left:n{\ocgxii_tiny_space_char:}
  \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCPrint}}
    \pbs_literal:nn{page}{-88888~-88888~99999~99999~re~f}
  \ocgbase_oc_emc:
  \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCView}}
    \group_begin:
      \exp_after:wN\color_select:nn\g_ocgxii_lnkcol_tl
      \pbs_literal:nn{page}{-88888~-88888~99999~99999~re~f}
    \group_end:
  \ocgbase_oc_emc:
  \pbs_literal:nn{page}{0~Tr~Q}
}

\cs_new_protected_nopar:Nn\ocgxii_colourlink_nobreak_begin:{
  \hbox_set:Nw\l_tmpa_box
}
\cs_new_protected_nopar:Nn\ocgxii_colourlink_nobreak_end:{
  \hbox_set_end:
  \mbox{
    \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCPrint}}
    \hbox_overlap_right:n{\box_use:N\l_tmpa_box}
    \ocgbase_oc_emc:
    \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCView}}
    \group_begin:
      \exp_after:wN\color_select:nn\l_ocgxii_lnkcol_tl
      \box_use_drop:N\l_tmpa_box
    \group_end:
    \ocgbase_oc_emc:
  }
}

% creates OCG objects for printing and viewing
\cs_new_protected:Npn\ocgxii_colorlinks_init:{
  \ocgbase_new_ocg:nnn{OCView}{
    /Print<</PrintState/OFF>>
    /Export<</ExportState/OFF>>
  }{on}
  \tl_gset:cx{ocgxii_ocg_OCView}{\ocgbase_last_ocg:}
  %in case somebody wants to reopen with \begin{ocg}...
  \tl_gset:cx{ocgxii_ocg_OCView.opts}{
    showingui=never,printocg=never,exportocg=never
  }
  \ocgbase_new_ocg:nnn{OCPrint}{
    /Print<</PrintState/ON>>
    /Export<</ExportState/ON>>
  }{off}
  \tl_gset:cx{ocgxii_ocg_OCPrint}{\ocgbase_last_ocg:}
  \tl_gset:cx{ocgxii_ocg_OCPrint.opts}{
    showingui=never,printocg=always,exportocg=always
  }
  \iow_now:Nx\@mainaux{
    \token_to_str:N\ocgxii@newkey{ocgx2.ocg.OCView}{
      \tl_use:c{ocgxii_ocg_OCView}}
  }
  \iow_now:Nx\@mainaux{
    \token_to_str:N\ocgxii@newkey{ocgx2.ocg.OCPrint}{
      \tl_use:c{ocgxii_ocg_OCPrint}}
  }
  \cs_gset:Npn\ocgxii_colorlinks_init:{}
}

% user command for protecting graphical content (external file, inline
% [e. g. TikZ], \fbox{...}) inside breakable ocgcolorlink
\DeclareDocumentCommand\ocglinkprotect{m}{
  \seq_get_left:NNTF\g_ocgxii_lnk_color_seq\l_tmpa_tl{
    \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
    \ocgxii_colourlink_end:
    \group_begin:
      \tl_set_eq:NN\l_ocgxii_lnkcol_tl\l_tmpa_tl
      \ocgxii_colourlink_nobreak_begin:
        \cs_set_nopar:Npn\ocglinkprotect##1{##1} % in case of nesting
        \sys_if_output_pdf:TF{
          \mode_leave_vertical:
          \hbox_set:Nn\l_tmpb_box{\skip_horizontal:n{1em}#1\skip_horizontal:n{1em}}
          \box_set_ht:Nn\l_tmpb_box{\box_ht:N\l_tmpb_box+1em}
          \box_set_dp:Nn\l_tmpb_box{\box_dp:N\l_tmpb_box+1em}
          \hbox_to_wd:nn{\box_wd:N\l_tmpb_box-2em}{
            \vrule~
              width~\c_zero_dim~
              height~\dim_eval:n{\box_ht:N\l_tmpb_box-1em}~
              depth~\dim_eval:n{\box_dp:N\l_tmpb_box -1em}~
            \pbs_pdfxform:nnnnn{1}{0}{}{}{\l_tmpb_box}
            \skip_horizontal:n{-1em}
            \pbs_pdfrefxform:n{\pbs_pdflastxform:}
            \hss
          }
        }{#1}
      \ocgxii_colourlink_nobreak_end:
    \group_end:
    \ocgxii_colourlink_begin:
  }{#1}
}
\group_begin:
\bool_if:NF\l_ocgxii_tikz_bool{\aftergroup\endinput}
\group_end:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% TikZ related code follows (to be enabled with package option `tikz')

\cs_set_eq:NN\ocgxii@trmspc\tl_trim_spaces:N
\ExplSyntaxOff
\RequirePackage{tikz}
\usetikzlibrary{calc}

% helper, replaces all spaces in #1 with `_'
\def\ocgxii@cnvspc#1{\expandafter\ocgxii@@cnvspc#1 \@nil}
\def\ocgxii@@cnvspc#1 #2\@nil{#1\ifx\@nil#2\@nil\else_\ocgxii@@cnvspc#2\@nil\fi}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Copyright notice: The code that follows until the end of the file was
% taken in large parts from Paul Gaborit's `tikzlibraryocgx.code.tex' with
% some additions/fixes:
%
%  - opts={...} inside ocg={...} allows ocg-environment options to be passed
%    to a TikZ scope
%
%  - The style ocmd={...} is another way for turning a TikZ scope into a PDF
%    layer (in addition to ocg={...}). It has two sub-keys, ref={...} and
%    visibility={...}, which have the same meaning as the optional and the
%    mandatory arguments of the `ocmd' environment
%
%  - TikZ objects to be turned into OCG switching links accept the additional
%    key
%
%      trigger ocg = onmousenter | onmouseexit | onmousedown | onmouseup |
%                      onmouseall
%
%    to react to various mouse gestures
%
%  - switching links properly sized and working in scaled tikzpictures
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\tikzset{
  ocg/.style={ocg/.cd,#1,/tikz/.cd},
  ocg={
    % parameters
    name/.store in=\ocgxii@name,
    opts/.store in=\ocgxii@opts,
    visibility/.store in=\ocgxii@visibility,
    status/.is choice,
    status/visible/.style={visibility=1},
    status/invisible/.style={visibility=0},
    status/true/.style={visibility=1},
    status/false/.style={visibility=0},
    status/on/.style={visibility=1},
    status/off/.style={visibility=0},
    status/1/.style={visibility=1},
    status/0/.style={visibility=0},
    % default values
    name=,
    opts=, % NEW
    status=on,
    % ref
    ref/.style={
      /tikz/execute at begin scope={%
        \begin{ocg}[\ocgxii@opts]{%
            \ifx\empty\ocgxii@name\empty#1\else\ocgxii@name\fi%
        }{#1}{\ocgxii@visibility}},
      /tikz/execute at end scope={\end{ocg}},
    }
  },
  ocmd/.style={
    ocmd/.cd,
    #1,
    /tikz/execute at begin scope={%
      \begin{ocmd}[\ocgxii@ocmdref]{\ocgxii@ocmdvisibility}%
    },
    /tikz/execute at end scope={\end{ocmd}},
    /tikz/.cd
  },
  ocmd={
    % parameters
    ref/.store in=\ocgxii@ocmdref,
    visibility/.store in=\ocgxii@ocmdvisibility,
    % default values
    ref=,
    visibility=,
  },
  trigger ocg/.store in=\ocgxii@trigger,
  trigger ocg/.value required,
  switch ocg/.style={
    postaction={
      path picture={
        \path (path picture bounding box.south west) coordinate (p1)
          (path picture bounding box.north east) coordinate (p2)
          (p1) node[inner sep=0pt,anchor=south west,outer sep=0pt] {%
            \ifdefined\ocgxii@trigger%
              \switchocg*[\ocgxii@trigger]{#1}{%
                \tikz \useasboundingbox (p1) rectangle (p2);}%
            \else%
              \switchocg*{#1}{\tikz \useasboundingbox (p1) rectangle (p2);}%
            \fi%
          };
      }
    }
  },
  switch ocg with mark on/.style 2 args={
    postaction={
      path picture={%
        \edef\ocgxii@argone{#1}%ocg ref for checkmark
        \ocgxii@trmspc\ocgxii@argone%
        \global\let\ocgxii@argone\ocgxii@argone%
        %default ocg ref for checkmark, if nothing provided in #1
        \xdef\ocgxii@argtwo{#2.mark}%
        \xdef\ocgxii@argtwo{\ocgxii@cnvspc{\ocgxii@argtwo}}%
        \begin{ocg}[showingui=false]{%
          \ifx\ocgxii@argone\@empty\ocgxii@argtwo\else\ocgxii@argone\fi%
        }{%
          \ifx\ocgxii@argone\@empty\ocgxii@argtwo\else\ocgxii@argone\fi%
        }{on}%
          \draw
          (path picture bounding box.south west)
          --
          (path picture bounding box.north east)
          (path picture bounding box.south east)
          --
          (path picture bounding box.north west)
          ;
        \end{ocg}%
      },
      switch ocg={%
        \ifx\ocgxii@argone\@empty\ocgxii@argtwo\else{\ocgxii@argone}\fi\space #2%
      }
    }
  },
  switch ocg with mark off/.style 2 args={
    postaction={
      path picture={%
        \edef\ocgxii@argone{#1}%ocg ref for checkmark
        \ocgxii@trmspc\ocgxii@argone%
        \global\let\ocgxii@argone\ocgxii@argone%
        %default ocg ref for checkmark, if nothing provided in #1
        \xdef\ocgxii@argtwo{#2.mark}%
        \xdef\ocgxii@argtwo{\ocgxii@cnvspc{\ocgxii@argtwo}}%
        \begin{ocg}[showingui=false]{%
          \ifx\ocgxii@argone\@empty\ocgxii@argtwo\else\ocgxii@argone\fi%
        }{%
          \ifx\ocgxii@argone\@empty\ocgxii@argtwo\else\ocgxii@argone\fi%
        }{off}%
          \draw
          (path picture bounding box.south west)
          --
          (path picture bounding box.north east)
          (path picture bounding box.south east)
          --
          (path picture bounding box.north west)
          ;
        \end{ocg}%
      },
      switch ocg={%
        \ifx\ocgxii@argone\@empty\ocgxii@argtwo\else{\ocgxii@argone}\fi\space #2%
      }
    }
  },
  show ocg/.style={
    postaction={
      path picture={
        \path (path picture bounding box.south west) coordinate (p1)
          (path picture bounding box.north east) coordinate (p2)
          (p1) node[inner sep=0pt,anchor=south west,outer sep=0pt] {%
            \ifdefined\ocgxii@trigger%
              \showocg*[\ocgxii@trigger]{#1}{%
                \tikz \useasboundingbox (p1) rectangle (p2);}%
            \else%
              \showocg*{#1}{\tikz \useasboundingbox (p1) rectangle (p2);}%
            \fi%
          };
      }
    }
  },
  hide ocg/.style={
    postaction={
      path picture={
        \path (path picture bounding box.south west) coordinate (p1)
          (path picture bounding box.north east) coordinate (p2)
          (p1) node[inner sep=0pt,anchor=south west,outer sep=0pt] {%
            \ifdefined\ocgxii@trigger%
              \hideocg*[\ocgxii@trigger]{#1}{%
                \tikz \useasboundingbox (p1) rectangle (p2);}%
            \else%
              \hideocg*{#1}{\tikz \useasboundingbox (p1) rectangle (p2);}%
            \fi%
          };
      }
    }
  },
  actions ocg/.style n args={3}{
    postaction={
      path picture={
        \path (path picture bounding box.south west) coordinate (p1)
          (path picture bounding box.north east) coordinate (p2)
          (p1) node[inner sep=0pt,anchor=south west,outer sep=0pt] {%
            \ifdefined\ocgxii@trigger%
              \actionsocg*[\ocgxii@trigger]{#1}{#2}{#3}{%
                \tikz \useasboundingbox (p1) rectangle (p2);}%
            \else%
              \actionsocg*{#1}{#2}{#3}{%
                \tikz \useasboundingbox (p1) rectangle (p2);}%
            \fi%
          };
      }
    }
  }
}
