% \iffalse
% makeindex -s gglo.ist -o exerquiz.gls exerquiz.glo
% makeindex -s gind.ist -o exerquiz.ind exerquiz.idx
%<*copyright>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Exerquiz.sty package,                                %%
%% Copyright (C) 1999-2021  D. P. Story                 %%
%%   dpstory@uakron.edu                                 %%
%%                                                      %%
%% This program can redistributed and/or modified under %%
%% the terms of the LaTeX Project Public License        %%
%% Distributed from CTAN archives in directory          %%
%% macros/latex/base/lppl.txt; either version 1 of the  %%
%% License, or (at your option) any later version.      %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%</copyright>
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{exerquiz}
%<driver>\ProvidesFile{exerquiz.drv}
%<aebjs>\ProvidesFile{aebjs.def}
%<eqexam>\ProvidesFile{eqexam.def}
%<randomize>\ProvidesFile{aebrandom.def}
%<sumrytbls>\ProvidesFile{aebsumrytbls.def}
%<template>\ProvidesFile{template.def}
%<package|driver|aebjs|eqexam|randomize|sumrytbls|template> [2021/10/03 v8.8.5 %
%<package> Exerquiz: Exercises and Quizzes for LaTeX/PDF package (dps)]
%<driver> Exerquiz documentation driver file (dps)]
%<aebjs> Exerquiz document level JavaScript (dps)]
%<eqexam> Exerquiz support file for eqexam (dps)]
%<randomize> Exerquiz support for randomization (dps)]
%<sumrytbls> Exerquiz support for summary tables (dps)]
%<template> Exerquiz template for language support (dps)]
%<eqfr>\ProvidesFile{eqfr.def}
%<eqde>\ProvidesFile{eqde.def}
%<eqno>\ProvidesFile{eqno.def}
%<eqnl>\ProvidesFile{eqnl.def}
%<eqes>\ProvidesFile{eqes.def}
%<eqit>\ProvidesFile{eqit.def}
%<eqru>\ProvidesFile{eqru.def}
%<eqda>\ProvidesFile{eqda.def}
%<eqpo>\ProvidesFile{eqpo.def}
%<eqfin>\ProvidesFile{eqfin.def}
%<eqcat>\ProvidesFile{eqcat.def}
%<eqcz>\ProvidesFile{eqcz.def}
%<eqbr>\ProvidesFile{eqbr.def}
%<eqtr>\ProvidesFile{eqtr.def}
%<*driver>
\documentclass{ltxdoc}
\usepackage[colorlinks,hyperindex=false]{hyperref}
\usepackage{fancyvrb}
\gdef\darg#1{\texttt{\char123\relax#1\char125\relax}}
\let\env\texttt
\let\opt\texttt
\let\app\textsf
\let\uif\textsf
\def\nmpsep#1{\hskip-\marginparsep\texttt{#1}}
\def\visispace{\symbol{32}}
\def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}}
\def\meta#1{\textit{\texttt{#1}}}
\def\SUB#1{\ensuremath{{}_{\mbox{\scriptsize\ttfamily#1}}}}
\def\GT{\string>}
\pdfstringdefDisableCommands{\let\\\textbackslash}
\OnlyDescription  % comment out for implementation details
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\InputIfFileExists{aebdocfmt.def}{\PackageInfo{exerquiz}{Inputting aebdocfmt.def}}
    {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax
     \PackageInfo{exerquiz}{aebdocfmt.def cannot be found}}
\makeatletter
  \let\@latex@warning\@gobble
\makeatother
\begin{document}
  \let\env\texttt\let\pkg\textsf
  \let\app\textsf
  \let\tops\texorpdfstring
  \let\key\texttt
  \GetFileInfo{exerquiz.sty}
  \title{Exerquiz: Exercises and Quizzes for \LaTeX/PDF}
  \author{D. P. Story\\
    Email: \texttt{dpstory@uakron.edu}}
  \date{processed \today}
  \maketitle
  \tableofcontents
  \let\Email\texttt
  \DocInput{exerquiz.dtx}
\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\PrintIndex}{\paragraph*{Index}
    The index goes here.\\Execute
    \texttt{makeindex -s gind.ist -o exerquiz.ind exerquiz.idx} on the command line
    and recompile \texttt{exerquiz.dtx}.}
\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of
    changes goes here.\\Execute
    \texttt{makeindex -s gglo.ist -o exerquiz.gls exerquiz.glo} on the command line
    and recompile \texttt{exerquiz.dtx}.}
\end{document}
%</driver>
% \fi
%
% \MakeShortVerb{|}
% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{exerquiz}{Inputting aebdonotindex.def}}
%    {\PackageInfo{exerquiz}{aebdonotindex.def cannot be found}}
%    \begin{macrocode}
%    \end{macrocode}
%\changes{v8.8.5}{2021/10/03}{This version attempts to fix a problem induced to acrotex by displaying
%the export values of choice field. The export values secretly contain a zero (0) or one (1) to signal
%that the current choice is wrong or right.}
%\changes{v8.6.3}{2021/01/31}{Updated documentation, informing users of \string\app{Acrobat DC} that
%   it is necessary to change their \string\uif{Security (Enhanced)} preferences.}
%\changes{v8.2.8}{2018/12/13}{The SOL file is now written entirely when there is no solution option specified}
% (2017/08/08) This version introduces multi-letter variables and what I'll term `alternate appearances'.
% \changes{v8.0}{2017/08/08}{Introduce multi-letter variables and alternate appearances. Changes
% made are marked by `\texttt{dps17}' throughout the DTX.}
% \changes{v7.7k}{2016/04/18}{Minor bug fixes, improved driver recognition}
% \changes{v7.7j}{2016/04/05}{Change in \string\pkg{eforms} to 2016/04/05 v2.8f}
%
% \section{Introduction}
%
% The \pkg{exerquiz} package provides support for the creation of exercises and quizzes
% with or without solutions. These are PDF form and link based. The packages provides ``intelligent'' evaluation
% of the students' responses. This package also provides code for the \pkg{eqexam} package so that these
% two packages are consistent in their approach.
%
% \section{Package options and setup}\label{options}
%
% Introduce a number of useful options for \pkg{exerquiz}.
% \subsection{Options for paper, solutions, JavaScript and preview}
%    \begin{macrocode}
%<*package>
\usepackage{keyval}
%    \end{macrocode}
%    Some early required packages.
%\changes{v6.4t}{2012/06/18}{Added \string\pkg{ifpdf} as a required package}
%\changes{v8.1a}{2017/09/03}{Added check for luatex}
%    \begin{macrocode}
\RequirePackage{ifpdf}[2006/02/20]
\RequirePackage{ifxetex}[2006/08/21]
\RequirePackage{ifluatex}
\@ifundefined{exqtable}{\def\exqtable{table}}{}
\IfFileExists{xcolor.sty}{%
  \def\eq@ColorPackage{xcolor}%
  \PassOptionsToPackage{\exqtable,hyperref}{xcolor}}
  {\def\eq@ColorPackage{color}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{noxcolor}^^A
%    An option to force
%    the use of the \textsf{color} package.
%    \begin{macrocode}
\DeclareOption{noxcolor}{\def\eq@ColorPackage{color}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{forpaper}^^A
%    Pass the \opt{monochrome} option to the color package
%\changes{v6.06a}{2007/04/09}
%{
%   Added the \string\texttt{forcolorpaper} option for those using
%   \string\textsf{exerquiz} without \string\textsf{web}.
%}
%    \begin{macrocode}
\DeclareOption{forpaper}{%
   \eqforpapertrue\PassOptionsToPackage{monochrome}{\eq@ColorPackage}
   \AtBeginDocument{\AllowPeeking}}
%    \end{macrocode}
%   \leavevmode\IndexOpt{forcolorpaper}^^A
%   The \opt{forcolorpaper} is the same as \opt{forpaper}, but does not
%   pass the \pkg{monochrome} option to the color package.
%    \begin{macrocode}
\DeclareOption{forcolorpaper}{\eqforpapertrue
   \AtBeginDocument{\AllowPeeking}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{preview}^^A
% With this option, the bounding boxes of all form fields appear in the
% dvi preview. Use this option of properly positioning your fields, then
% remove this option on the final build of the document. This option is no
% appropriate for the \texttt{pdftex} option which does not have a dvi preview.
%    \begin{macrocode}
\DeclareOption{preview}{\PassOptionsToPackage{preview}{eforms}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{nosolutions}^^A
%    With the option, the solutions to the exercises are not
%    included in the typeset document.
%    \begin{macrocode}
\DeclareOption{nosolutions}{\eq@nosolutionstrue\eq@nolinktrue}
%    \end{macrocode}
%    \leavevmode\IndexOpt{noquizolutions}^^A
% No solutions for quizzes (shortquiz and quiz environments).
%    \begin{macrocode}
\DeclareOption{noquizsolutions}{\eq@noquizsolutionstrue\eq@nolinktrue}
%    \end{macrocode}
%    \leavevmode\IndexOpt{allowanswers}^^A
% Only effective when \texttt{noquizsolutions} option is in force. Normally, the \uif{Correct} control
% (\cs{CorrAnsButton}) does not appear; if \texttt{answersallowed} is also specified,
% the \cs{CorrAnsButton} does appear.
% \changes{v8.8.1}{2021/05/21}{Added the \string\texttt{allowanswers} key}
%    \begin{macrocode}
\DeclareOption{allowanswers}{\eq@answersallowedtrue}
\newif\ifeq@answersallowed \eq@answersallowedfalse
%</package>
%<*package|eqexam>
%    \end{macrocode}
% An \IndexOpt{online}\texttt{online} options.
%    \begin{macrocode}
\let\eq@YES=y \let\eq@NO=n
\let\eq@One=1 \let\eq@Zero=0
\def\eq@r{r}\let\eq@f=f \let\eq@l=l
%</package|eqexam>
%<*package>
\DeclareOption{online}{\let\eq@online\eq@YES}
\let\eq@online\eq@NO
%    \end{macrocode}
%    \leavevmode\IndexOpt{nohiddensolutions}\IndexOpt{noHiddensolutions}^^A
% Overrides any hidden solutions specified with the \texttt{exercise}
% environment.
%    \begin{macrocode}
\DeclareOption{nohiddensolutions}{\eq@globalshowsolutionstrue}
\DeclareOption{noHiddensolutions}%
  {\eq@globalshowsolutionstrue\AtBeginDocument{\def\Hidesymbol{h}}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{solutionsafter}^^A
%    Solutions will appear after the statement of the exercise.
%    \begin{macrocode}
\DeclareOption{solutionsafter}{\eq@solutionsaftertrue\eq@nolinktrue}
%    \end{macrocode}
%    \leavevmode\IndexOpt{solutionsonly}^^A
% Here is a highly specialized option, put in at the request of a former friend.
%\changes{v6.2f}{2007/12/21}{Added a \string\opt{solutionsonly} option}
%    \begin{macrocode}
\DeclareOption{solutionsonly}{\solutionsonlytrue\answerkeytrue
  \therearesolutionstrue\AtEndOfPackage{\let\exerSolnsHeadnToc\relax}}
%    \end{macrocode}
%    \changes{v8.1k}{2018/02/04}{Added \string\cs{ifanswerkey} switch}
%    \begin{macrocode}
\newif\ifsolutionsonly\solutionsonlyfalse
\@ifundefined{ifanswerkey}{\newif\ifanswerkey\answerkeyfalse}{}
%    \end{macrocode}
%    \leavevmode\IndexOpt{contsolns}^^A
%    This option requires both \textsf{web} and \textsf{exerquiz}. The package
%    tests for the presence of the \textsf{web} and whether webheadings pagestyle
%    is used.
%    \begin{macrocode}
\DeclareOption{contsolns}{\AtEndOfPackage{\InputIfFileExists
  {contsolns.def}{\contsolnsInputMsg}{\contsolnsErrorMsg}}}
\def\contsolnsInputMsg{\PackageInfo{exerquiz}{contsolns option,
  inputting file contsolns.def}}
\def\contsolnsErrorMsg{\PackageWarning{exerquiz}{contsolns option,
  cannot find file contsolns.def}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{nocorrections}^^A
%    The code for correcting the |quiz| environment is
%    not written; this results in a smaller file.
%    \begin{macrocode}
\DeclareOption{nocorrections}{\nocorrectionstrue}
%    \end{macrocode}
%    \leavevmode\IndexOpt{proofing}^^A
%    An option for marking the correct answers for shortquiz and quiz
%    \begin{macrocode}
\DeclareOption{proofing}{\eq@proofingtrue}
%    \end{macrocode}
%    \leavevmode\IndexOpt{showgrayletters}^^A
% When this option is in effect, capital letters in gray appear under
% the multiple choice question boxes of quizzes.
%    \begin{macrocode}
\newif\ifaebshowgrayletters\aebshowgraylettersfalse
\DeclareOption{showgrayletters}{\aebshowgrayletterstrue}
%    \end{macrocode}
%    \leavevmode\IndexOpt{vspacewithsolns}^^A
% This is for the \texttt{vspacewithsolns} option designed for
% \textsf{eqexam}, but can be used in \textsf{exerquiz}. The switch
% \cs{ifvspacewithsolns} is defined in \textsf{eqexam}, and we only
% define it here if \textsf{eqexam} is not loaded.
% \changes{v6.3x}{2011/04/05}{Added \string\opt{vspacewithsolns}}
%    \begin{macrocode}
\@ifundefined{ifvspacewithsolns}{%
  \DeclareOption{vspacewithsolns}{\vspacewithsolnstrue}
  \newif\ifvspacewithsolns\vspacewithsolnsfalse
}{}
%    \end{macrocode}
%    \changes{v8.1m}{2018/02/09}{\string\cs{ifdisplayworkarea} conditionally defined}
%    \changes{v8.2.8}{2018/12/13}{defined \string\cs{displayworkareaOn} and
%    \string\cs{displayworkareaOff}}
%    \begin{macrocode}
\@ifundefined{ifdisplayworkarea}{\newif\ifdisplayworkarea
  \displayworkareafalse}{}
\providecommand\displayworkareaOn{\displayworkareatrue}
\providecommand\displayworkareaOff{\displayworkareafalse}
%    \end{macrocode}
%    \leavevmode\IndexOpt{nodljs}^^A
%    An option for excluding all DLJS from the document. Useful with the
%    \texttt{forpaper} option, or a document destined to be printed. Pass
%    on to \pkg{insdljs} package.
%    \begin{macrocode}
\DeclareOption{nodljs}{\PassOptionsToPackage{nodljs}{insdljs}%
  \AtEndOfPackage{\let\importdljs\eq@YES}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{execJS}^^A
% Execute any JS defined within the \env{execJS} environment. Works only for
% authors using Acrobat 5.0 or Acrobat Approval.
%    \begin{macrocode}
\DeclareOption{execJS}{\PassOptionsToPackage{execJS}{insdljs}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{usealtadobe}^^A
%    Pass the \opt{usealtadobe} to \pkg{insdljs} as a convenience option.
%    \changes{v8.7.7}{2021/05/10}{Pass \string\opt{usealtadobe} option to \string\pkg{insdljs}}
%    \begin{macrocode}
\DeclareOption{usealtadobe}{\PassOptionsToPackage{usealtadobe}{insdljs}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{exercisesonly}^^A
% If the document author wants only to create a series of exercises, no quizzes, there is no
% need for the Document-level JavaScript. So, we have a couple of convenience options.
%    \begin{macrocode}
\DeclareOption{exercisesonly}{\PassOptionsToPackage{nodljs}{insdljs}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{debug}^^A
%    An option for debugging JavaScript. Pass on to insdljs package.
%    \begin{macrocode}
\DeclareOption{debug}{\PassOptionsToPackage{debug}{insdljs}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{allowrandomize}^^A
% Beginning with version 6.1 of \textsf{exerquiz}, it is possible to randomize
% the choices in a multiple choice question. These choices must be set off
% by the command \cs{bChoices}/\cs{eChoices} pair. The command \cs{bChoices} now has
% two optional arguments \texttt{nCols} and \texttt{random}. See \autoref{randomize}.
%    \begin{macrocode}
\DeclareOption{allowrandomize}{\AtEndOfPackage{\inputRandomizeChoices}}
\def\inputRandomizeChoices{\InputIfFileExists{aebrandom.def}
  {\PackageInfo{exerquiz}{inputting aebrandom.def}}
  {cannot find aebrandom.def}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{usesumrytbls}^^A
%    The declare the use of summary tables
%    \begin{macrocode}
\newif \ifusesumrytbls \usesumrytblsfalse
\DeclareOption{usesumrytbls}{\usesumrytblstrue
  \def\inputSumryTblCode{\InputIfFileExists{aebsumrytbls.def}
  {\PackageInfo{exerquiz}{inputting aebsumrytbls.def}}%
  {cannot find aebsumrytbls.def}}}
\let\inputSumryTblCode\relax
%    \end{macrocode}
% The \IndexOpt{usemcfi}\texttt{usemcfi} option inputs special code for creating a MC/math fill-in question, a type
% of question suggested to me by Stefka K.\ of Bulgaria.
%    \begin{macrocode}
\DeclareOption{usemcfi}{%
  \def\inputMCFICode{\InputIfFileExists{usemcfi.def}
  {\PackageInfo{exerquiz}{inputting usemcfi.def}}%
  {cannot find usemcfi.def}}}
\let\inputMCFICode\relax
%    \end{macrocode}
% \changes{v7.7o}{2016/07/08}{Added switch \string\cs{ifwithinMCFI}}
%    The switch \cs{ifwithinMCFI} help to determine if a quiz problem occurs within
%    the command \cs{bMCFI}/\cs{eMCFI} pair.
%    \begin{macrocode}
\newif\ifwithinMCFI\withinMCFIfalse
%    \end{macrocode}
%    The \IndexOpt{userbmintrvl}\opt{userbmintrvl} option defines \cs{rbmIntrvl} command, which
%    is a special \cs{RespBoxMath} command were some of the parameters are set by an
%    interval. Refer to Section~\ref{ss:rbmi} for details.
%    \changes{v8.7}{2021/04/24}{Added the option \string\opt{userbmintrvl}}
%    \begin{macrocode}
\DeclareOption{userbmintrvl}{%
  \def\inputRBMICode{\InputIfFileExists{rbmintrvl.def}
  {\PackageInfo{exerquiz}{Inputting rbmintrvl.def}}%
  {cannot find rbmintrvl.def}}}
\let\inputRBMICode\relax
%    \end{macrocode}
%    \subsection{Driver Options}
%     The \textsf{web} package passes these driver options to \textsf{exerquiz}.
%    These options are needed is \textsf{exerquiz} is used without
%    \textsf{web}; in this case, the options below must explicitly included.
%    \IndexOpt{dvipsone}\IndexOpt{dvips}\IndexOpt{pdftex}
%    Set the driver dependent code for the |quiz| environments.
%    \begin{macrocode}
% \def\eq@drivernum{5} % 5 = no choice
\DeclareOption{dvipsone}{%
  \def\eq@drivernum{0}\def\eq@driver{dvipsone}
  \PassOptionsToPackage{dvipsone}{eforms}
}
\DeclareOption{dvips}{%
  \def\eq@drivernum{0}\def\eq@driver{dvips}
  \PassOptionsToPackage{dvips}{eforms}
}
\DeclareOption{pdftex}{%
    \def\eq@drivernum{1}\def\eq@driver{pdftex}%
    \PassOptionsToPackage{pdftex}{\eq@ColorPackage}
    \PassOptionsToPackage{pdftex}{eforms}
}
%    \end{macrocode}
%    Added a \texttt{luatex} option
%\changes{v8.1a}{2017/09/03}{Added a \string\texttt{luatex} option}
%    \begin{macrocode}
\DeclareOption{luatex}{%
    \def\eq@drivernum{1}\def\eq@driver{luatex}
    \PassOptionsToPackage{luatex}{\eq@ColorPackage}
    \PassOptionsToPackage{luatex}{eforms}
}
%    \end{macrocode}
%    \IndexOpt{dvipdfm}\IndexOpt{dvipdfmx}\IndexOpt{xetex}
%    Set the driver dependent code for the \texttt{quiz} and \texttt{quiz}
%    environments.
%    \begin{macrocode}
\DeclareOption{dvipdfm}{%
    \def\eq@drivernum{2}\def\eq@driver{dvipdfm}
    \PassOptionsToPackage{dvipdfm}{\eq@ColorPackage}
    \PassOptionsToPackage{dvipdfm}{eforms}%
}
\DeclareOption{dvipdfmx}{%
    \def\eq@drivernum{2}\def\eq@driver{dvipdfmx}
    \PassOptionsToPackage{dvipdfmx}{\eq@ColorPackage}
    \PassOptionsToPackage{dvipdfmx}{eforms}
}
\DeclareOption{xetex}{%
    \def\eq@drivernum{2}\def\eq@driver{xetex}
    \PassOptionsToPackage{xetex}{\eq@ColorPackage}
    \PassOptionsToPackage{xetex}{eforms}
}
%    \end{macrocode}
%    \leavevmode\IndexOpt{textures}^^A
% This option, and testing are due to Ross Moore  3/6/02
%    \begin{macrocode}
\DeclareOption{textures}{\def\eq@drivernum{3}
  \def\eq@driver{textures}
  \PassOptionsToPackage{textures}{\eq@ColorPackage}
  \PassOptionsToPackage{textures}{eforms}
}
%    \end{macrocode}
%    \leavevmode\IndexOpt{dviwindo}^^A
%    Set \cmd{\eq@noformstrue}, this inserts an \cmd{\endinput} just after
%    the end of the \env{exercise} environment.  No quizzes for
%    \texttt{dviwindo}.
%    \begin{macrocode}
\DeclareOption{dviwindo}{\def\eq@drivernum{4}\def\eq@driver{dviwindo}
  \eq@noformstrue\PassOptionsToPackage{nodljs}{insdljs}}
%    \end{macrocode}
% If no driver is passed to \pkg{exerquiz}, assume it is
% dvipsone or dvips---\pkg{hyperref} defines the specials.
% Default driver dvipsone/dvips
%    \begin{macrocode}
\def\eq@drivernum{5}
\def\eq@driver{dvipsone/dvips}
\def\eq@driver@nodriver{no driver specified}
%    \end{macrocode}
%    \leavevmode\IndexOpt{unicode}^^A
% Passes the unicode option to \textsf{hyperref}.
% \changes{v6.3}{2008/03/19}
% {
%   Added the \string\opt{unicode} option, which is passed to \string\pkg{hyperref}.
% }
%    \begin{macrocode}
\DeclareOption{unicode}{\PassOptionsToPackage{unicode}{hyperref}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{useui}^^A
% Passes the useui option to eforms. With this option,
% the key-value pairs \textsl{\'{a} la xkeyval} can be used.
% \changes{v6.3}{2008/03/19}
% {
%   Added the \string\opt{useui} option, which is passed to eforms.
% }
%    \begin{macrocode}
\DeclareOption{useui}{\PassOptionsToPackage{useui}{eforms}}
%    \end{macrocode}
%
% \subsection{Language Options}
%    \textsf{exerquiz} uses many language dependent typeset labels
%    and JavaScript messages.  These messages are defined in the
%    English language in Section~\ref{ss:ldm}. The language options
%    defines the macro \cmd{\LangRedefinition} to input language
%    dependent redefinitions of these messages.  Initially,
%    \cmd{\LangRedefinition} is set to relax and no redefinition files
%    are input.
%    \begin{macrocode}
\let\LangRedefinitions\relax
%    \end{macrocode}
%    \leavevmode\IndexOpt{french}^^A
%    Translations due to Jean-Michel SARLAT.
%    \begin{macrocode}
\DeclareOption{french}{%
   \def\LangRedefinitions{\InputIfFileExists{eqfr.def}%
     {\PackageInfo{exerquiz}{Inputting French Option}}%
     {\PackageInfo{exerquiz}{French Option: Cannot find the file
      eqfr.def, using the default, English.}}}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{german}^^A
%    Translation due to Michael Wiedmann.
%    \begin{macrocode}
\DeclareOption{german}{%
   \def\LangRedefinitions{\InputIfFileExists{eqde.def}%
   {\PackageInfo{exerquiz}{Inputting German Option}}%
   {\PackageInfo{exerquiz}{German Option: Kann die Datei eqde.def
     nicht finden, benutze Default, Englisch.}}}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{norsk}^^A
%    Translation due to Hans Fredrik Nordhaug.
%    \begin{macrocode}
\DeclareOption{norsk}{%
   \def\LangRedefinitions{\InputIfFileExists{eqno.def}%
   {\PackageInfo{exerquiz}{Inputting Norsk Option}}%
   {\PackageInfo{exerquiz}{Norsk Option: Cannot find the file eqno.def,
   using the default, English.}}}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{dutch}^^A
%    Translation due to Henny Wilbrink
%    \begin{macrocode}
\DeclareOption{dutch}{%
   \def\LangRedefinitions{\InputIfFileExists{eqnl.def}%
   {\PackageInfo{exerquiz}{Inputting Dutch Option}}%
   {\PackageInfo{exerquiz}{Dutch Option: Kan bestand eqnl.def niet
    vinden, gebruik default, Engels.}}}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{spanish}^^A
%    Translation due to Pedro Luis Luque
%    \begin{macrocode}
\DeclareOption{spanish}{%
   \def\LangRedefinitions{\InputIfFileExists{eqes.def}%
   {\PackageInfo{exerquiz}{Inputting Spanish Option}}%
   {\PackageInfo{exerquiz}{Spanish Option: Opci\'on Espa\~nola: no puede
    encontrar el fichero eqes.def, usar\'a por defecto, English.}}}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{italian}^^A
%    Translation due to PierLuigi Zezza
%    \begin{macrocode}
\DeclareOption{italian}{%
   \def\LangRedefinitions{\InputIfFileExists{eqit.def}%
   {\PackageInfo{exerquiz}{Opzione Lingua Italiana}}%
   {\PackageInfo{exerquiz}{pzione Italiano: Non trovo il file eqit.def,
    utilizzo  quello di default, English.}}}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{russian}^^A
%    Translation due to Sergei V. Znamenskii
%    \begin{macrocode}
\DeclareOption{russian}{%
   \@ifpackageloaded{hyperref}{%
    \ifHy@unicode\else\PackageWarning{exerquiz}{%
        The unicode option recommended for hyperref\MessageBreak}\fi
   }{\PassOptionsToPackage{unicode}{hyperref}}
   \def\LangRedefinitions{\InputIfFileExists{eqru.def}%
   {\PackageInfo{exerquiz}{Inputting Russian Option}}%
   {\PackageInfo{exerquiz}{Russian Option: Cannot find the file
    eqru.def, using the default, English.}}}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{dansk}^^A
%    Translation due to Erik Leimand
%    \begin{macrocode}
\DeclareOption{dansk}{%
   \def\LangRedefinitions{\InputIfFileExists{eqda.def}%
   {\PackageInfo{exerquiz}{Inputting Dansk Option}}%
   {\PackageInfo{exerquiz}{Dansk Option: Cannot find the file eqda.def,
   using the default, English.}}}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{polish}^^A
%    Translation due to Jerzy Mycielski
%    \begin{macrocode}
\DeclareOption{polish}{%
   \def\LangRedefinitions{\InputIfFileExists{eqpo.def}%
   {\PackageInfo{exerquiz}{Inputting Polish Option}}%
   {\PackageInfo{exerquiz}{Polish Option: Cannot find the file
    eqpo.def, using the default, English.}}}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{finnish}^^A
% Translation due to Paivi Porras
%    \begin{macrocode}
\DeclareOption{finnish}{%
   \def\LangRedefinitions{\InputIfFileExists{eqfin.def}%
   {\PackageInfo{exerquiz}{Inputting Finnish Option}}%
   {\PackageInfo{exerquiz}{Finnish Option: Cannot find the file
    eqfin.def, using the default, English.}}}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{catalan}^^A
% Translation due to Ramon Ballester
%    \begin{macrocode}
\DeclareOption{catalan}{%
   \def\LangRedefinitions{\InputIfFileExists{eqcat.def}%
   {\PackageInfo{exerquiz}{Inputting Catalan Option}}%
   {\PackageInfo{exerquiz}{Catalan Option: Cannot find the file
    eqcat.def, using the default, English.}}}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{czech}^^A
% Translation due to Robert Marik
%    \begin{macrocode}
\DeclareOption{czech}{%
   \def\LangRedefinitions{\InputIfFileExists{eqcz.def}%
   {\PackageInfo{exerquiz}{Inputting Czech Option}}%
   {\PackageInfo{exerquiz}{Czech Option: Cannot find the file eqcz.def,
   using the default, English.}}}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{brazil}^^A
%    Translation due to Koichi Sameshima
%    \begin{macrocode}
\DeclareOption{brazil}{%
   \def\LangRedefinitions{\InputIfFileExists{eqbr.def}%
   {\PackageInfo{exerquiz}{Inputting Brazilian Portuguese Option}}%
   {\PackageInfo{exerquiz}{Portuguese Option: Opc\~ao Portugu\^es:
    n\~ao foi poss\'ivel encontrar o arquivo eqbr.def, usaremos
    o padr\~ao, English.}}}}
%    \end{macrocode}
%    \leavevmode\IndexOpt{turkish}^^A
%    Translation due to Mahmut Ko\c{c}ak
%    \begin{macrocode}
\DeclareOption{turkish}{%
   \@ifpackageloaded{hyperref}{%
    \ifHy@unicode\else\PackageWarning{exerquiz}{%
        The unicode option recommended for hyperref\MessageBreak}\fi
   }{\PassOptionsToPackage{unicode}{hyperref}}
   \def\LangRedefinitions{\InputIfFileExists{eqtr.def}%
   {\PackageInfo{exerquiz}{Inputting Turkish Option}}%
   {\PackageInfo{exerquiz}{Cannot find the file eqtk.def,
    using the default, English.}}}}
%    \end{macrocode}
%    \begin{macrocode}
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{\eq@ColorPackage}}
\@ifpackageloaded{xcolor}%
{%
    \@ifpackagelater{xcolor}{2004/07/04}{}
    {%
    \PackageError{exerquiz}{%
    *************************************************\MessageBreak
    * Your Version of `xcolor.sty' is too old!\MessageBreak
    * You need the version from 2004/07/04 or newer\MessageBreak
    * or use: \string\usepackage[noxcolor]{exerquiz}\MessageBreak
    *************************************************}{}%
    }%
}{}
%    \end{macrocode}
% \subsection{Switches}
%    Boolean switches used by the declared options.
%    \begin{macrocode}
\let\iterate\relax
\newif\ifeq@solutionsafter \eq@solutionsafterfalse
\def\ifsolutionsafter{\csname ifeq@solutionsafter\endcsname}
  \let\solutionsaftertrue\eq@solutionsaftertrue
  \let\solutionsafterfalse\eq@solutionsafterfalse
\newif\ifeq@hidesolution \eq@hidesolutionfalse
\newif\ifeq@globalshowsolutions \eq@globalshowsolutionsfalse
\newif\ifeq@nosolutions \eq@nosolutionsfalse
\newif\ifeq@proofing \eq@proofingfalse
\providecommand\turnProofingOn{\eq@proofingtrue}
\providecommand\turnProofingOff{\eq@proofingfalse}
\newif\ifeqforpaper \eqforpaperfalse
%</package>
%<*package|eqexam>
\newif\ifeq@noforms \eq@noformsfalse
\newif\ifeq@noquizsolutions \eq@noquizsolutionsfalse
\newif\ifnocorrections \nocorrectionsfalse
%    \end{macrocode}
%    Added \cs{ifeqe@flextended} to support \pkg{eqexam}
%    \changes{v8.1h}{2018/01/03}{Added \string\cs{ifeqe@flextended} to support \string\pkg{eqexam}}
%    \changes{v8.1o}{2018/02/12}{Added \string\cs{ifcont@nnot} to support \string\pkg{eqexam}}
%    \begin{macrocode}
\@ifundefined{ifeqe@flextended}{\newif\ifeqe@flextended
  \eqe@flextendedfalse}{}
\@ifundefined{ifcont@nnot}{\newif\ifcont@nnot \cont@nnotfalse}{}
\@ifundefined{if@eqalignfilllinestoleft}
  {\newif\if@eqalignfilllinestoleft\@eqalignfilllinestoleftfalse}{}
%    \end{macrocode}
%   \changes{v6.3z}{2011/04/28}{Created a switch \string\cs{ifkeepdeclaredvspacing},
%     used primarily by \textsf{eqexam}}
% (4/28/11) A switch to control whether the declared vertical space
% for the \texttt{solution} environment is preserved during the \texttt{answerkey}
% option. This is an \textsf{eqexam} feature.
%    \begin{macrocode}
\newif\ifkeepdeclaredvspacing \keepdeclaredvspacingfalse
\newif\ifeq@nolink \eq@nolinkfalse
\def\eq@ckglobalhide{\ifeq@globalshowsolutions\eq@hidesolutionfalse\fi}
\def\hidesymbol{h}\def\Hidesymbol{H}
%    \end{macrocode}
% When the first solution is written, \cs{therearesolutions} is
% made true.  When the solutions are input back into the file, and
% this switch is still false, then no exercise header is typeset;
% this avoids an empty exercise section with only the header.
%    \begin{macrocode}
\newif\iftherearesolutions \therearesolutionsfalse
%    \end{macrocode}
%\DescribeMacro{\ifIsRespBox}\cmd{\ifIsRespBox} is a switch used to detect the presence
% of a response box, math or text, on a page. The switch is used to automatically place
% an \cs{AnswerField} in the running footer.
%    \begin{macrocode}
\newif\ifIsRespBox \global\IsRespBoxfalse
%    \end{macrocode}
%    \begin{macro}{\SolutionsAfter}
%    \begin{macro}{\SolutionsAtEnd}
%    \begin{macro}{\NoSpaceToWork}
%    \begin{macro}{\SpaceToWork}
% Some macros to turn \cs{eq@solutionsafter} on or off, and to suppress
% the vertical space in the solutions environment when the \texttt{nosolutions}
% option is in effect. Concerning leaving space to work, the default is to
% leave space to work (\cs{SpaceToWork}).
%    \changes{v8.2.8}{2018/12/13}{Set \string\cs{displayworkareafalse} in definition
%     of \string\cs{SolutionsAfter}; also, inserted \string\cs{eq@proofingfalse}}
%    \begin{macrocode}
\def\SolutionsAfter{\solutionsAtEndfalse\eq@solutionsaftertrue
  \displayworkareafalse\eq@proofingfalse\eq@nolinktrue}
%    \end{macrocode}
%    The \DescribeMacro\ifcqSA\cs{ifcaSA} switch is used with the \env{cq*} environment
%    to create conditional content. It is true when the \env{solution} environment
%    is in a \textsf{solutions-after} state.
%    \begin{macrocode}
\newif\ifcqSA\cqSAfalse
%    \end{macrocode}
%    Modified \cs{SolutionsAtEnd} (2018/02/02) to include \cs{eq@nosolutionsfalse}
%    and \cs{eq@proofingfalse}.
%    \changes{v8.1j}{2018/02/02}{Added \string\cs{eq@nosolutionsfalse}
%    and \string\cs{eq@proofingfalse} to the
%    definition of \string\cs{SolutionsAtEnd}}
%    \changes{v8.2.8}{2018/12/13}{Removed \string\cs{therearesolutionstrue}
%    from \string\cs{SolutionsAtEnd}}
%    \begin{macrocode}
\def\SolutionsAtEnd{\solutionsAtEndtrue\vspacewithsolnstrue
  \eq@solutionsafterfalse\eq@nolinkfalse
%    \end{macrocode}
%    Now, if |\ifvspacewithsolns| is true, we set |\eq@nosolutionsfalse| so solutions appear
%    at the end of the file; otherwise, we set |\eq@nosolutionstrue|.
%    \changes{v8.1k}{2018/02/04}{Added a conditional within \string\cs{SolutionsAtEnd}}
%    \changes{v8.1m}{2018/02/09}{Include \string\cs{displayworkareatrue} in definition
%    of \string\cs{SolutionsAtEnd}}
%    \changes{v8.2.8}{2018/12/13}{Set \string\cs{displayworkareafalse} in definition
%     of \string\cs{SolutionsAtEnd}}
%    \begin{macrocode}
  \displayworkareafalse\ifvspacewithsolns\eq@nosolutionsfalse\else
  \eq@nosolutionstrue\fi\eq@proofingfalse\answerkeyfalse}
\def\NoSpaceToWork{\let\eq@insertverticalspace\eq@NO}
\def\SpaceToWork{\let\eq@insertverticalspace\eq@YES}
\SpaceToWork
%    \end{macrocode}
%    (2017/03/16) Made def of \cs{ifNoSolutions} long.
%    \changes{v7.8g}{2017/03/16}{Made def of \string\cs{ifNoSolutions} long}
%    \begin{macrocode}
\long\def\ifNoSolutions#1#2{%
    \ifeq@nosolutions\expandafter#1\else
    \expandafter#2\fi}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% Some switches to control the randomization process, which comes into play
% with the \texttt{allowrandomize} option. These are set to \texttt{false} initially,
% The first one is set locally by the random option of \cs{bChoices}; the second
% one overrides the first so that all multiple choice questions can be randomized
% without having to edit every \cs{bChoices} command. The user has access to this
% switch through the \cs{turnOnRandomize} and \cs{obeyLocalRandomize} commands.
% The topic of randomizing the choices is taken up in \autoref{randomize}.
%    \begin{macrocode}
\newif\ifeq@randomizeChoices \eq@randomizeChoicesfalse
\newif\ifeq@randomizeallChoices \eq@randomizeallChoicesfalse
\newif\if@DoNotRandomize \@DoNotRandomizefalse
%    \end{macrocode}
%    \begin{macro}{\turnOnRandomize}
%    \begin{macro}{\obeyLocalRandomize}
% When the \texttt{allowrandomize} option is in effect, the randomization can be
% turned on and off locally by the optional parameter in \cs{bChoices}. These
% two commands can be used to override \texttt{random=false}. Consequently,
% by saying \cs{turnOnRandomize} you can convert your old multiple choice
% questions so that are randomly arranged, without having to edit them and
% add the optional \texttt{random} key.
%    \begin{macrocode}
\def\turnOnRandomize{\eq@randomizeallChoicestrue}
\def\obeyLocalRandomize{\eq@randomizeallChoicesfalse}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\doNotRandomizeChoices}
%    \begin{macro}{\allowRandomizedChoices}
%    These two commands allow for finer control over whether to randomize choices
%    or not. Expanding \cs{doNoRandomizeChoices} overrides the \opt{allowrandomize}
%    option; whereas \cs{allowRandomizedChoices} restores the original behavior
%    set by the \opt{allowrandomize} option.
%    \changes{v8.6.2}{2021/01/20}{Added \string\cs{doNoRandomizeChoices} and
%    \string\cs{allowRandomizedChoices}}
%    \begin{macrocode}
\def\doNotRandomizeChoices{\@DoNotRandomizetrue}
\def\allowRandomizedChoices{\@DoNotRandomizefalse}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
% These\DescribeMacro{\saveRandomSeed}\DescribeMacro{\inputRandomSeed} two
% commands are used when the \texttt{allowrandomize} option is in effect, Until
% then, they do nothing. See the definition in \autoref{randomize}.
%    \begin{macrocode}
\let\saveRandomSeed\relax
\let\inputRandomSeed\relax
%</package|eqexam>
%<*package>
%    \end{macrocode}
%    \begin{macro}{\CorrectionsOn}
%    \begin{macro}{\CorrectionsOff}
%    Use these macros to locally turn on or off the inclusion
%    of the correction code.
%    \begin{macrocode}
\def\CorrectionsOn{\global\nocorrectionsfalse}
\def\CorrectionsOff{\global\nocorrectionstrue}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \subsection{Process Options and Require Packages}
% The \texttt{quiz} environments use Acrobat forms and JavaScript
% so we need to load in the AcroForm Dictionary---unless the
% \texttt{dviwindo} (\cmd{\eq@noformstrue}) option is requested.
%\changes{v6.3y}{2011/04/23}{%
% As per Heiko's suggestion, I've change the \string\env{Form} environment
% no longer creates a grouping. This was causing problems with
% the \string\pkg{atveryend} package.
%}
%    \begin{macrocode}
\AtBeginDocument{\ifeq@noforms\else\Form\fi}
\AtEndDocument{%
    \include@solutions
    \ifeq@noforms\else\include@quizsolutions\fi
    \clearpage
    \csname endForm\endcsname
%    \end{macrocode}
% (04/12/07) I put a \cs{clearpage} for some good reason, can't remember, I think
% it had to do with templates, but dvipdfm has problems with this. The document
% level JavaScript are not inserted, they are cleared out by the \cs{clearpage}.
% So, we'll only to a \cs{clearpage} if the driver is not dvipdfm.
%    \begin{macrocode}
    \if\eq@drivernum2\else\clearpage\fi}
%    \end{macrocode}
% \subsection{Load Configuration File: exerquiz.cfg}
% Look for configuration file, exerquiz.cfg.
%\begin{verbatim}
%    \ExecuteOptions{noquizsolutions,nocorrections}
%\end{verbatim}
% sets several options.
%    \begin{macrocode}
\InputIfFileExists{exerquiz.cfg}{}{}
%    \end{macrocode}
% If web is already loaded, we use its driver.
% \changes{v6.4t}{2012/06/18}{Testing for pdflatex and xetex}
% \changes{v8.1a}{2017/09/03}{Testing for luatex}
%    \begin{macrocode}
\let\bWebCustomize\endinput
\let\eWebCustomize\relax
\@ifpackageloaded{web}{%
    \ExecuteOptions{\eq@driver@name}%
}{%
    \ifluatex\ExecuteOptions{luatex}\else
    \ifpdf\ExecuteOptions{pdftex}\else
    \ifxetex\ExecuteOptions{xetex}\else
        \InputIfFileExists{web.cfg}{}
        {\@ifundefined{l@tex@@@@driver}{\ExecuteOptions{dvips}}
            {\ExecuteOptions{dvipsone}}}\fi\fi\fi
}
%    \end{macrocode}
%    \begin{macrocode}
\ProcessOptions
%    \end{macrocode}
% Input required packages.
% \changes{v7.03}{2015/03/02}{Added the \string\pkg{array} package, mostly
% for use in the tabular setup of parts in tabular mode.}
%    \begin{macrocode}
\RequirePackage{array}
\RequirePackage{\eq@ColorPackage}
%    \end{macrocode}
%     Changed order of loading, comment package first, then verbatim package; prior to the change, anomalous
%     errors, which were traced to these two packages.
%     \changes{v7.8k}{2017/07/25}{Changed order of loading, comment package first, then verbatim package}
%     \changes{v8.2.7}{2018/12/05}{require \string\pkg{aeb-comment} (version 3.1 of comment)}
%    \begin{macrocode}
\RequirePackage{aeb-comment}
\def\eq@commentChkMsg{\@ifpackageloaded{comment}
  {\PackageWarningNoLine{exerquiz}
    {The comment package is incompatible with the\MessageBreak
     aeb-comment package, do not use the comment package}}{}}
\AtBeginDocument{\eq@commentChkMsg}
\RequirePackage{verbatim}
\RequirePackage{hyperref}
\RequirePackage{amssymb}% used for return symbols
%    \end{macrocode}
%    (2021/05/10) Newer version of \pkg{eforms} required, as this package uses
%    \cs{dl@EForAF4}, which is defined by \pkg{insdljs} of the same date.
%    \changes{v8.7.7}{2021/05/10}{Now require \string\pkg{eforms} dated 2021/05/10}
%    \begin{macrocode}
\RequirePackage{eforms}[2021/05/10]
\dlSetPkgInfo
%    \end{macrocode}
%    \begin{macrocode}
\@ifundefined{eq@drivernum}{%
    \PackageError{exerquiz}%
        {You  have not specified dvips, dvipsone, pdftex, dvipdfm,
        dvipdfmx, or xetex
        \MessageBreak in the option list of the exerquiz package}
        {Place one of the drivers dvips, dvipsone, pdftex, dvipdfm,
        dvipdfmx, or xetex
        \MessageBreak in the option list of the exerquiz package.}
}{}
%    \end{macrocode}
%    \begin{macrocode}
\edef\eq@restoreCats{%
  \catcode`\noexpand\"=\the\catcode`\"\relax
  \catcode`\noexpand\'=\the\catcode`\'\relax
  \catcode`\noexpand\,=\the\catcode`\,\relax
  \catcode`\noexpand\(=\the\catcode`\(\relax
  \catcode`\noexpand\!=\the\catcode`\!\relax
  \catcode`\noexpand\_=\the\catcode`\_\relax
}
\@makeother\"\@makeother\'\@makeother\,%
\@makeother\(\@makeother\!\@makeother\_
%    \end{macrocode}
% Determine whether we have solutions at end.
%    \begin{macrocode}
\@ifundefined{ifsolutionsAtEnd}
    {\newif\ifsolutionsAtEnd\solutionsAtEndtrue}{}
\ifeq@nosolutions\solutionsAtEndfalse\fi
\ifeq@solutionsafter\solutionsAtEndfalse\fi
\@ifundefined{if@fleqn}{\let\fleqnOn\relax\let\fleqnOff\relax}
    {\def\fleqnOn{\@fleqntrue}\def\fleqnOff{\@fleqnfalse}}
%    \end{macrocode}
% \changes{v7.7o}{2016/07/08}{Added Boolean \string\cs{if@inclkey} in support of the
%    \string\pkg{eq2db} package}
%    \begin{macrocode}
\@ifundefined{if@inclkey}{\newif\if@inclkey\@inclkeytrue}{}
%</package>
%    \end{macrocode}
% \subsection{The Template \& Language dependent messages}\label{ss:ldm}
% The following define labels and messages for the exercise and
% various quiz environments. They are all redefined when a
% language option is used.  All of them can be redefined to
% customize a users document.
%
% In attempt to better manage the language localizations, I've placed the
% template for Web and Exerquiz in the Exerquiz.dtx file.
%    \begin{macrocode}
%<*template>
%%------------- Instructions ------------------------------------
%% Make your language localizations to this file and rename it to
%% something like \texttt{eq<mylang>.def}, where \texttt{<mylang>}
%% is a short 2-letter designator of the language. Test the tile
%% by inputting it in the preamble of your document
%% \input{eq<mylang>.def}. When satisfied, send it to me at
%% dpstory@uakron.edu or dpstory@acrotex.net.
%</template>
%<template>%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%<template>%% Web.sty                                            %%
%<template>%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%<template>% Language dependent definitions for Web.sty
%<*template>
\DeclareOption{newlanguage}{%
  \AtEndOfPackage{%
    \def\today{\ifcase\month\or January
            \or February \or March \or April
            \or May \or June  \or July  \or August
            \or September  \or October  \or November
            \or December \fi \the\day,  \the\year}
    \def\web@versionlabel{Version}
    \def\web@toc{Table of Contents}
    \def\web@continued{cont.}
    \def\web@article{Begin \hyperlink{section.1}{Article}}
    \def\web@directory{Directory}
    \def\web@revision{Last Revision Date:}
    \def\web@copyright{Copyright}
    \def\web@section{Section}
    % Label Navibar
    \def\web@back{Back}
    \def\web@doc{Doc}} % restricted to three characters
    \PassOptionsToPackage{newlanguage}{exerquiz}
}
%</template>
%    \end{macrocode}
%    \begin{macrocode}
%<template>%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%<template>%% Exerquiz.sty                                       %%
%<template>%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%<template>\DeclareOption{newlanguage}{%
%<template>   \def\LangRedefinitions{\InputIfFileExists{eqlang.def}%
%<template>   {\PackageInfo{exerquiz}{Inputting a New Language Option}}%
%<template>   {\PackageInfo{exerquiz}{Language Option: Cannot find the file
%<template>    eqpo.def, using the default, English.}}}}
%<template>
%<package>\def\eqretnSymb{$\blacksquare$}%{\rule{6bp}{6.8bp}}
% The exercise label
%<package>\newcommand\exlabel{Exercise}
%<package>\newcommand\exlabelsol{\exlabel}
%<template>% The exercise label
%<template>% Accents: \renewcommand\exlabel{\"Ubung} (German)
%<template>\renewcommand\exlabel{Exercise}
%<template>% The value of this macro is written to \jobname.sol,
%<template>% accented characters must be protected with a \protect
%<template>% E.g., \renewcommand\exlabelsol{\protect\"Ubung} (German)
%<template>\renewcommand\exlabelsol{\exlabel}
%    \end{macrocode}
%    \begin{macrocode}
% Title of exercise solution section
%<package>\newcommand\exsectitle{Solutions to \exlabel s}
%<package>\newcommand\exsecrunhead{\exsectitle} %% change to @ form
%<template>
%<template>% Title of exercise solution section
%<template>% E.g.: \renewcommand\exsectitle
%<template>%            {L\"osungen der \exlabel en} (German)
%<template>\renewcommand\exsectitle{Solutions to \exlabel s}
%<template>\renewcommand\exsecrunhead{\exsectitle} %% change to @ form
%    \end{macrocode}
%    \begin{macrocode}
%<*package|eqexam>
%    \end{macrocode}
%    \begin{macro}{\exsolafter}
% Solution label for \texttt{solutionafter} option for exercise, this is a command
% that may be redefined. Either by a \cs{recommand} or by the use of
% \cs{renameSolnAfterTo}.
%    \begin{macro}{\resetSolnAfterToDefault}
% This command resets \cs{exsolafter} to the default value.
%    \begin{macro}{\exsolafterDefault}
% Takes one argument, the argument is the default value of \cs{exsolafter}
%    \begin{macro}{\renameSolnAfterTo}
% This command takes one command, it redefines \cs{exsolafter}, but does
% not change the default value.
%\changes{v6.05g}{2007/01/28}
%{
% Added to commands for use in exerquiz or in \string\pkg{eqexam}. They are
% \string\cs{renameSolnAfterTo} for conveniently changing the solution
% after label, and \string\cs{resetSolnAfterToDefault} for resetting
% back to the default.
%}
%    \begin{macrocode}
\newcommand{\exsolafter}{\eq@exsolafterDefault}
\newcommand{\resetSolnAfterToDefault}{%
    \def\exsolafter{\eq@exsolafterDefault}}
\newcommand{\exsolafterDefault}[1]{\def\eq@exsolafterDefault{#1}%
    \def\exSolafterDefault{#1}\resetSolnAfterToDefault}
\exsolafterDefault{\textit{Solution}:}
\newcommand{\renameSolnAfterTo}[1]{\def\exsolafter{#1}}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \DescribeMacro{\adjDisplayBelow} is useful when expanded beneath distplays that
%    have no follow-up text below them. These seems to me, in certain situations, unnecessary
%    space is created. The \cs{adjDisplayBelow} attempts to remedy this. The
%    \DescribeMacro{\adjDisplayBelowPlus}\cs{adjDisplayBelowPlus} is the same as
%    \cs{adjDisplayBelow}, but adds \cs{recoverDisplayBelow}. The command \cs{adjDisplayBelow}
%    has a |vskip-\baselineskip|, if this is too much, use \cs{adjDisplayBelowPlus}.
%    \begin{macrocode}
\newcommand{\adjDisplayBelow}{\vskip-\lastskip\vskip-\baselineskip}
\newcommand{\adjDisplayBelowPlus}{\adjDisplayBelow\recoverDisplayBelow}
\def\recoverDisplayBelow{\vskip\belowdisplayskip}
%</package|eqexam>
%<template>
%<template>% Solution label for solutionafter option for exercise
%<template>\renewcommand\exsolafter{\textit{Solution}:}
%    \end{macrocode}
%    \begin{macrocode}
% Title of quiz solution section
%<package>\newcommand\eq@sqslsectitle{Solutions to Quizzes}
%<package>\newcommand\sqslsectitle{\eq@sqslsectitle}
%<template>
%<template>% Title of short quiz solution section
%<template>% Example: \renewcommand\eq@sqslsectitle
%<template>%               {L\"osungen der Aufgaben} (German)
%<template>\renewcommand\eq@sqslsectitle{Solutions to Quizzes}
%<template>\renewcommand\sqslsectitle{\eq@sqslsectitle}
%    \end{macrocode}
%    \begin{macrocode}
% Running header/section title for solutions to short quizzes
%<package>\newcommand\eq@sqslsecrunhead{Solutions to Quizzes}
% User access
%<package>\newcommand\sqslsecrunhead{\eq@sqslsecrunhead}
%<template>
%<template>% Running header/section title for solutions to short quizzes
%<template>\renewcommand\eq@sqslsecrunhead{Solutions to Quizzes}
%<template>% User access
%<template>\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
%    \end{macrocode}
%    \begin{macrocode}
% Label for solutions to quizzes, appears in solutions sections
%<package>\newcommand\eq@sqsllabel{\protect\textbf{Solution to Quiz:}}
% User access
%<package>\newcommand\sqsllabel{\eq@sqsllabel}
%<template>
%<template>% Label for solutions to short quizzes, appears
%<template>% in solutions sections
%<template>% Protect accents with \protect
%<template>% E.g.: \renewcommand\eq@sqsllabel
%<template>%       {\string\textbf{L\protect\"osung zu Aufgabe:}} (German)
%<template>\renewcommand\eq@sqsllabel{\string\textbf{Solution to Quiz:}}
%<template>% User access
%<template>\renewcommand\sqsllabel{\eq@sqsllabel}
%    \end{macrocode}
%    \begin{macrocode}
% Solution label for solutionafter option for shortquiz
%<package>\newcommand\sqsolafter{\textit{Solution}:}
%<template>
%<template>% Solution label for solutionafter option for shortquiz
%<template>\renewcommand\sqsolafter{\textit{Solution}:}
%    \end{macrocode}
%    \begin{macrocode}
% Here is the default short quiz label.
%<package>\newcommand{\sqDefaultFmtTitle}[1]%
%<package>      {\def\eq@sqlabel{#1}\def\sqlabel{#1}}
% User access to shortquiz label
%<package>\newcommand\sqlabel{\eq@sqlabel}
%<package>\sqDefaultFmtTitle{\textcolor{red}{Quiz}}
%<template>
%<template>% User access to shortquiz label
%<template>\renewcommand\sqlabel{\eq@sqlabel}
%<template>% Here is the default short quiz label.
%<template>\sqDefaultFmtTitle{\textcolor{red}{Quiz.}}
%    \end{macrocode}
%    \begin{macrocode}
% Here is the default short quiz return label
% No formatting allowed
%<package>\newcommand\eq@sqslrtnlabel{\protect\eqretnSymb}
% User access to shortquiz label
%<package>\newcommand\sqslrtnlabel{\eq@sqslrtnlabel}
%<template>
%<template>% Here is the default short quiz return label
%<template>% No formatting allowed
%<template>\renewcommand\eq@sqslrtnlabel{End Quiz}
%<template>% User access to shortquiz label
%<template>\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
%    \end{macrocode}
%    \begin{macrocode}
% Short quiz feedback messages
%<package>\newcommand\eqsqrtmsg{"Right!"}
%<package>\newcommand\eqsqwgmsg{"Wrong!"}
%<package>\newcommand\doNotShowAgainMsg{Do not show this message again}
%<template>
%<template>% Short quiz feedback messages
%<template>\renewcommand\eqsqrtmsg{"Right!"}
%<template>\renewcommand\eqsqwgmsg{"Wrong!"}
%<template>\renewcommand\doNotShowAgainMsg{Do not show this message again}
%    \end{macrocode}
%    \begin{macrocode}
% Here is the default quiz label.
%<package>\newcommand\eq@bqlabel{Begin Quiz}
% User access to quiz label
%<package>\newcommand\bqlabel{\eq@bqlabel}
% Used for writing JavaScript Messages on screen
%<package>\newcommand\eq@bqlabelISO{\eq@bqlabel}
%<package>\newcommand\bqlabelISO{\eq@bqlabelISO}
% Default title for a quiz used for \verb!\@currentlablename!
%<package|eqexam>\newcommand\setDefShortQuizLabelName[1]%
%<package|eqexam>    {\def\eq@defaultShortQuizLabelName{#1}}
%<package|eqexam>\setDefShortQuizLabelName{Quiz}
%<package>\newcommand\setDefQuizLabelName[1]
%<package>    {\def\eq@defaultQuizLabelName{#1}}
%<package>\setDefQuizLabelName{Quiz}
%<template>
%<template>% Here is the default quiz label.
%<template>% No formatting allowed
%<template>% For Example: \renewcommand\eq@bqlabel{D\'ebut}  (French)
%<template>\renewcommand\eq@bqlabel{Begin Quiz}
%<template>% User access to shortquiz label
%<template>\renewcommand\bqlabel{\eq@bqlabel}
%<template>% Used for writing JavaScript Messages on screen.
%<template>% Use PDFDocEncoding
%<template>% For Example:
%<template>% \renewcommand\eq@bqlabelISO{D\string\351but}  (French)
%<template>% Use \string not \protect, this helps out
%<template>% TeX4ht by Eitan Gurari.
%<template>\renewcommand\eq@bqlabelISO{\eq@bqlabel}
%<template>\renewcommand\bqlabelISO{\eq@bqlabel}
%<template>% Default title for a quiz used for \verb!\@currentlablename!
%<template>\setDefShortQuizLabelName{Quiz}
%<template>\setDefQuizLabelName{Quiz}
%    \end{macrocode}
%    \begin{macrocode}
% Here is the default quiz label.
% No formatting allowed
%<package>\newcommand\eq@eqlabel{End Quiz}
% User access to quiz label
%<package>\newcommand\eqlabel{\eq@eqlabel}
%<template>
%<template>% Here is the default quiz label.
%<template>% No formatting allowed
%<template>\renewcommand\eq@eqlabel{End Quiz}
%<template>% User access to shortquiz label
%<template>\renewcommand\eqlabel{\eq@eqlabel}
%    \end{macrocode}
%    \begin{macrocode}
% JavaScript Messages for Quiz Environments
%<package>\newcommand\eq@Score{Score:}\newcommand\eq@OutOf{out of}
%<package>\newcommand\eq@ptScore{Score:}
%<package>\newcommand\stOutOf{of}
%<package>\newcommand\eqScore{\eq@Score}\newcommand\eqOutOf{\eq@OutOf}
%<package>\newcommand\eqptScore{\eq@ptScore}
%<template>
%<template>% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
%<template>% Note: Use  \string rather than \protect for escape codes,
%<template>% i.e. \string\374
%<template>%
%<template>% In the Text Field showing the score, there is the default
%<template>% phrase in English
%<template>% Score: 2 out of 3, the word "Score" and "out of" needs
%<template>% translation.
%<template>\renewcommand\eq@Score{Score:}\renewcommand\eq@OutOf{out of}
%<template>\renewcommand\eq@ptScore{Score:}
%<template>% used in summary tables
%<template>\renewcommand\stOutOf{of}
%    \end{macrocode}
%    \begin{macrocode}
%<package>\newcommand\eqInitQuizMsg{%
%<package>  "You must initialize the Quiz! Click on "+msg+"."}
%<template>% If you are taking a quiz and click on an alternative without
%<template>% initializing the quiz
%<template>% first, this message appears.
%<template>% This string is placed in the DLJS, so the escape sequences
%<template>% need to be protected more. Instead of \string\340 we need
%<template>% \string\\340.
%<template>% Example: \renewcommand\eqInitQuizMsg{%    (German)
%<template>%   "Sie m\string\\374ssen die Aufgaben initialisieren!
%<template>%    Bitte klicken Sie auf "+msg+"."}
%<template>\renewcommand\eqInitQuizMsg{%
%<template>  "You must initialize the Quiz! Click on "+msg+"."}
%    \end{macrocode}
%    \begin{macrocode}
%<package>\newcommand\eqQuizTotalMsg{%
%<package>  "\eqScore\space"+Score+" \eqOutOf\space"+nQuestions}
%<package>\newcommand\eqQuizPointsMsg{%
%<package>  "\eqptScore\space"+ptScore+" \eqOutOf\space"+nPointTotal}
%<package>\newcommand\eqQuizPercentMsg{pcScore+"\%"}
%<package>\newcommand\eqQuizGradeMsg{quizGrade}
%<template>
%<template>% This macro doesn't usually need translation, it uses \eqScore
%<template>% and \eqOutOf. However, if the sentence "Score: 2 out of 3"
%<template>% does not translate conveniently into a particular language,
%<template>% this macro may have to be modified.  It's the one that puts
%<template>% the message in the message box.
%<template>\renewcommand\eqQuizTotalMsg
%<template> {"\eqScore\space"+Score+" \eqOutOf\space"+nQuestions}
%<template>\renewcommand\eqQuizPointsMsg{%
%<template>  "\eqptScore\space"+ptScore+" \eqOutOf\space"+nPointTotal}
%<template>\renewcommand\eqQuizPercentMsg{pcScore+"\%"}
%<template>\renewcommand\eqQuizGradeMsg{quizGrade}
%    \end{macrocode}
%    \begin{macrocode}
%<package>\newcommand\eqMadeChoice{%
%<package>  "You have already made a choice."
%<package>  + " Your choice was ("+Responses[probno]+")."
%<package>  + " Do you want to change it?"}
%<template>
%<template>% In the link form of a quiz, of you change your choice,
%<template>% this message appears. This string is placed in the
%<template>% DLJS, so the escape sequences need to be protected more.
%<template>% Instead of \string\340 we need \string\\340.
%<template>% For Example: \renewcommand\eqMadeChoice{%
%<template>% "Vous avez d\string\\351j\string\\340 fait un choix,
%<template>%   ce choix est ("+Responses[probno]+").
%<template>%   Souhaitez vous le modifier ?"}  (French)
%<template>\renewcommand\eqMadeChoice{%
%<template>  "You have already made a choice.
%<template>   Your choice was ("+Responses[probno]+").
%<template>   Do you want to change it?"}
%    \end{macrocode}
% Default language phrases used by \cmd{\eqButton}. These are overwritten by the
% language options.
%    \begin{macrocode}
%<package>\newcommand\eq@local@CA{Correct}
%<package>\newcommand\eq@local@RC{My Answers!}
%<package>\newcommand\eq@local@AC{Please!}
%<template>% Default button labels for \eqButton
%<template>% Accents are handled as above:
%<template>% A French Language Example
%<template>% \renewcommand\eq@local@CA{R\string\351ponses}
%<template>% \renewcommand\eq@local@RC{Correctes}
%<template>% \renewcommand\eq@local@AC{SVP !}
%<template>\renewcommand\eq@local@CA{Correct}
%<template>\renewcommand\eq@local@RC{My Answers!}
%<template>\renewcommand\eq@local@AC{Please!}
%    \end{macrocode}
% Default language phrases used by \cmd{\CorrAnsButton}. These are overwritten by the
% language options.
%    \begin{macrocode}
%<package>\newcommand\eq@local@CorrAnsButton{Ans}
%<template>
%<template>% Default button label of \CorrAnsButton.
%<template>\renewcommand\eq@local@CorrAnsButton{Ans}
%<package>\newcommand{\eq@local@sqClearButton}{Clear}
%<template>% Default button label of \sqClearButton
%<template>\renewcommand{\eq@local@sqClearButton}{Clear}
%<template>% Short string used by the \PromptButton
%<template>\renewcommand{\AnsPromptBtnStr}{Answer:\space}
%    \end{macrocode}
% The following are (error) messages generated from the math fill-in questions.
%    \begin{macrocode}
%<*package>
\newcommand\eqerrABS{"Absolute values not balanced. Please correct."}
\dlJSStr[noquotes]\eqerrBadMathFunc{"The expression \""+aF[i]
    +"\" is neither a defined function nor a valid math expression."}
\newcommand\eqParens{"Parentheses"}
\newcommand\eqBrackets{"Brackets"}
\newcommand\eqBraces{"Braces"}
\newcommand\eqerrDelimNotBal{aGroup[i][2] + " not balanced.
    Please correct."}
\newcommand\eqerrBadExp{"Invalid mathematical expression.
    A problem with one of the exponents. Please correct."}
\newcommand\eqerrUnfinishQuiz{"There is an unfinished quiz,
    please finish before moving on to another."}
\newcommand\noPeekMsg{"Viewing Solutions to quizzes is not allowed
    until you take or finish this quiz!"}
\newcommand\highThresholdMsg{"You are required to respond to all
    questions before the quiz is evaluated."}
\newcommand\eqSyntaxErrorUndefVar{"Syntax Error: Possibly an undefined
    variable present, or an expression is not written in an expected
    format."}
\dlJSStr[noquotes]{\eqSyntaxErrorComma}{%
    "Syntax Error: A comma was found"
    + " in your response \""
    + UserAns + "\". Please remove the comma, or this answer"
    + " will be marked as wrong."}
\newcommand{\limSelWarningMsg}{"For this question, you are allowed to
    make at most " + n + " selections."}
\newcommand{\defaultReqFormMsg}{%
    "The expression is not in the expected form."}
%</package>
%<template>
%<template>% These (error) messages are generated when the user enters an
%<template>% invalid math expression into a math fill-in response box.
%<template>% The messages come in the form of an eqAppAlert() so
%<template>% PDFDocEncoding needs to be used.
%<*template>
\renewcommand\eqerrABS{"Absolute values not balanced. Please correct."}
\renewcommand\eqerrBadMathFunc{"The expression \""+aF[i]+"\" is neither
    a defined " +"function, nor a valid math expression."}
\renewcommand\eqParens{"Parentheses"}
\renewcommand\eqBrackets{"Brackets"}
\renewcommand\eqBraces{"Braces"}
\renewcommand\eqerrDelimNotBal{aGroup[i][2] + " not balanced.
    Please correct."}
\renewcommand\eqerrBadExp{"Invalid mathematical expression.
    A problem with one of the exponents. Please correct."}
\renewcommand\eqerrUnfinishQuiz{"There is an unfinished quiz,
    please finish before moving on to another."}
\renewcommand\noPeekMsg{"Viewing Solutions to quizzes is not allowed
    until you take or finish this quiz!"}
\renewcommand\highThresholdMsg{"You are required to respond to all
    questions before the quiz is evaluated."}
\renewcommand\eqSyntaxErrorUndefVar{"Syntax Error: Possibly an
    undefined variable present."}
\newcommand{\eqSyntaxErrorComma}{"Syntax Error: A comma was found"
    + " in your response \\""
    + UserAns + "\\". Please remove the comma, or this answer"
    + " will be marked as wrong."}
\renewcommand{\limSelWarningMsg}{"For this questions, you are allowed to
    make at most " + n + " selections."}
\renewcommand{\promptButtonMsg}{%
    "Would you like to see the correct answer at this time? "
    + "Your current answer will be the one that will be scored. "
    + "If you click on \\"Yes\\",
        you will not be able to change your answer."
}
\renewcommand{\defaultReqFormMsg}{%
    "The expression is not in the expected form."}
\renewcommand\eqAnd{and}
%</template>
%<*template>
%%%%%%%%%%%%%%%%%%%%%% End Message Section %%%%%%%%%%%%%
%% Some typeout messages                              %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% In exerquiz.sty
\typeout{Inputting French Option}
\typeout{French Option: Cannot find the file eqfr.def, using the
    default, English.}
\typeout{Solutions not allowed with this option}
\typeout{Check: `#1' is not an acceptable option, inserting
    default, `check'.}
%</template>
%<*package>
%    \end{macrocode}
% Announce driver option
%    \begin{macrocode}
\PackageInfo{exerquiz}{* Using \eq@driver\space option *}
%</package>
%<*package|eqexam>
%    \end{macrocode}
%    \subsection{Handles, counters and such}
% Handles to write solutions to quizzes and exercises to a file.
%    \begin{macrocode}
\newcommand{\writeToExSolns@}[1]{%
  \ifsolutionsonly\else
    \ifOKToWriteExamData
      \set@display@protect
      \immediate\write\ex@solns{#1}\set@typeset@protect
  \fi\fi
}
\ifsolutionsonly
  \InputIfFileExists{\jobname_xdefs.cut}{%
    \typeout{^^JExerquiz|Eqexam: Reading \jobname_xdefs.cut^^J}}
    {\PackageWarningNoLine{exerquiz|eqexam}{%
    \jobname_xdefs.cut not found.\MessageBreak
     Recompile file under the vspacewithsolns\MessageBreak
     option, then compile with the solutionsonly\MessageBreak
     option}}
  \let\writeToExSolns\@gobble
\else
  \newwrite\ex@solns \immediate\openout \ex@solns \jobname.sol
  \let\writeToExSolns\writeToExSolns@
%    \end{macrocode}
% If we are not in \cs{ifsolutionsonly} mode, we write some definitions to a .def
% file to be read back in at the beginning of the document.
%    \begin{macrocode}
  \newwrite\eq@xrefdefns
  \immediate\openout\eq@xrefdefns\jobname_xdefs.cut
\fi
\let\writeT@ExSolns\writeToExSolns
\newwrite\quiz@solns \immediate\openout \quiz@solns \jobname.qsl
\newcommand{\writeToQzSolns}[1]{\ifOKToWriteExamData\set@display@protect
  \immediate\write\quiz@solns{#1}\set@typeset@protect\fi}
\let\writeT@QzSolns\writeToQzSolns
\def\eq@IWAuxOut#1{\immediate\write\@auxout{#1}}
\def\eq@IWDefs#1{\immediate\write\eq@xrefdefns{#1}}
%    \end{macrocode}
%   \changes{v8.2.8}{2018/12/13}{more controls for solution files}
%   Two sets of controls for the solution files. If \DescribeMacro\normalSolnWrites
%   \cs{normalSolnWrites} is expanded (the default), solutions are written to the solution files
%   as they normally do; if \DescribeMacro\noSolnWrites\cs{noSolnWrites} is in force, nothing is written
%   to the solution file, except for verbatim content from the \env{solution}
%   environments. When all else fails, when verbatim content is written to the solution files that
%   you don't want to appear, use \DescribeMacro\bHideSolnIn\cs{bHideSolnIn\darg{\ameta{wrt-cmd}}}
%   to write \cs{iffalse} then \DescribeMacro\eHideSolnIn\cs{eHideSolnIn\darg{\ameta{wrt-cmd}}}
%   to close off the conditional. Where, \ameta{wrt-cmd} is either \cs{writeToSolnFile} (or \cs{writeToExSolns}), or
%   \cs{writeToQzSolns}.
%   For example,
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
%commandchars={!()},codes={\catcode`\%=9}]
%\bHideSolns\writeToSolnFile % for eqexam
%\begin{exam}{test}
%...
%\end{exam}
%\eHideSolns\writeToSolnFile
%\end{Verbatim}
%Now this exam has no footprint within the solution file.
%    \begin{macrocode}
\@ifundefined{ifOKToWriteExamData}{\newif\ifOKToWriteExamData
  \OKToWriteExamDatatrue}{}
\def\noSolnWrites{\OKToWriteExamDatafalse}
\def\normalSolnWrites{\OKToWriteExamDatatrue}
\def\bHideSolnIn#1{#1{\protect\iffalse}\noSolnWrites}
\def\eHideSolnIn#1{\normalSolnWrites#1{\protect\fi^^J}}
%    \end{macrocode}
% Counters to keep track of exercise questions.
%    \begin{macrocode}
\newcounter{eqexno} \setcounter{eqexno}{0}
\newcounter{@exno} \setcounter{@exno}{0}  % running exno
%    \end{macrocode}
% Counter to keep track of quiz questions.
%    \begin{macrocode}
\newcounter{quizno} \setcounter{quizno}{0}
\renewcommand\thequizno{\alph{quizno}}
%    \end{macrocode}
%    (2020/01/01) In certain circumstances, page numbering is incorrect; traced it to the
%    use of \cs{count0}/\cs{count\cs{z@}}, possibly not used within a group. As a fix,
%    replaced this usage with the counter \cs{eqtmpcnta}.
% \changes{v8.5.7}{2020/01/01}{added public counter \string\cs{eqtmpcnta}}
% \changes{v8.5.8}{2020/01/01}{Replaced \string\cs{count\string\cs{z@}} and
% \string\cs{count0} with \string\cs{eqtmpcnta}, this fixed the page number
% leakage problem}
%    \begin{macrocode}
\newcount\eqtmpcnta
%</package|eqexam>
%<*package>
\def\theHquizno{\curr@quiz.\theeqquestionnoi.%
  \ifcase\@eqquestiondepth\or\or\arabic{eqquestionnoii}.%
  \or\arabic{eqquestionnoii}.\roman{eqquestionnoiii}.%
  \else\fi\alph{quizno}}
%    \end{macrocode}
% (2016/05/17) \cs{eqemargin} is used in \textsf{eqexam}, but some calculations use it for the list version of
% answers. We declare this length to be 0pt. The \textsf{eqexam} resets this value.
%    \begin{macrocode}
\newlength\eqemargin \eqemargin=0pt
%</package>
%<*package|eqexam>
%    \end{macrocode}
% Keep track of point values of quizzes
%    \begin{macrocode}
\newcounter{eqpointvalue} \setcounter{eqpointvalue}{0}
%    \end{macrocode}
% Some scratch registers and boxes.
%    \begin{macrocode}
\newlength\eq@tmplength
\newlength\eqtmplength
%    \end{macrocode}
%    \begin{macro}{eqquestionno}
% The counter that keeps track of the question number.
% Used by the \texttt{questions environment}
%    \begin{macrocode}
\newcounter{questionno}
\newcounter{eqquestionnoi}
\newcounter{eqquestionnoii}
\newcounter{eqquestionnoiii}
\newcount\@eqquestiondepth \@eqquestiondepth=0
%</package|eqexam>
%<*package>
\newcounter{grpquestionno}
%</package>
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{partno}
%    This counter keeps track of the parts of an exercise, when the *-option
%    is used.
%    \begin{macrocode}
%<*package|eqexam>
\newcounter{partno}
%    \end{macrocode}
%    (2017/01/11) Added \DescribeMacro{\numberParts}\cs{numberParts} to change how this counter is displayed
%    as a number. The default is \DescribeMacro{\alphaParts}\cs{alphaParts} to display the \texttt{partno}
%    counter as a letter.
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
%commandchars={!()},codes={\catcode`\%=9}]
%\renewcommand{\partnoFmt}{\arabic}
%\setPartsWidth{(00)}
%\partsformat{\makebox[\widthOfParts][c]{(\hfil\thepartno\hfil)}}
%\end{Verbatim}
%    With this code, the items in the \texttt{parts} environment are numbered.
%    \changes{v7.8d}{2017/01/11}{Added \string\cs{partnoFmt} to change how this counter is displayed}
%    \begin{macrocode}
\newif\ifuseNumForParts\useNumForPartsfalse
\def\alphaParts{\def\partnoFmt{\alph}\useNumForPartsfalse}\alphaParts
\def\numberParts{\def\partnoFmt{\arabic}\useNumForPartstrue}
\renewcommand\thepartno{\partnoFmt{partno}}
\newtoks\eq@scratchtoks
%</package|eqexam>
%<*package>
\def\theHpartno{partno\the@exno\thepartno}
%</package>
%<*package|eqexam>
%    \end{macrocode}
%    \end{macro}
%    \subsection{Write to a file}
% We must have a way to write the solutions of our exercises and
% quizzes to a file.  The following \cmd{\verbatimwrite} was
% taken from the \texttt{moreverb} package, it uses the
% \texttt{verbatim} package.
%
%    \begin{macrocode}
\def\verbatimwrite{\@bsphack
  \let\do\@makeother\dospecials
  \catcode`\^^M\active \catcode`\^^I=12
  \def\verbatim@processline{%
    \immediate\write\verbatim@out
      {\the\verbatim@line}}%
  \verbatim@start}
\def\endverbatimwrite{\@esphack}
%    \end{macrocode}
%    \section{The \texttt{exercise} Environment}
%
% We use \cmd{\raggedright} within a \texttt{tabular} environment,
% so we must use a little trick, illustrated in the \textsl{\LaTeX\
% Companion} by M. Goossens et al. This macro is used with \texttt{exercise}
% with parts, \texttt{shortquiz} and \texttt{quiz} environments.
%    \begin{macrocode}
\providecommand\PBS[1]{\let\temp=\\#1\let\\=\temp}
%</package|eqexam>
%<*package>
%    \end{macrocode}
% Define some formatting commands.  These can all be redefined to
% customize the document.
%    \begin{macro}{\exlabelformat}
%    This is the formatted label for the exercise environment.
%    \begin{macrocode}
\newcommand\exlabelformat{{\scshape\exlabel\ \theeqexno.}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\exlabelformatwp}
%    This is the formatted label for the exercise environment with parts.
%    When an exercises has parts, the word `Exercise' is not a link,
%    so we color this word for emphasis.
%    \begin{macrocode}
%\newcommand\exlabelformatwp{{\scshape\exlabel\ \theeqexno.}}
\newcommand\exlabelformatwp{\exlabelformat}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\exsllabelformat}
%    This is the formatted solution label.
%    \begin{macrocode}
\newcommand\exsllabelformat{\protect\textbf{\exlabelsol\ \theeqexno.}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\exsllabelformatwp}
%    This is the formatted solution when the *-options is use, that is,
%    when there are multiple parts to the question.
%    \begin{macrocode}
\newcommand\exsllabelformatwp
     {\protect\textbf{\exlabelsol\ \theeqexno(\thepartno)}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\exrtnlabelformat}
%    This is the formatted return label (return from the solution).
%    \begin{macrocode}
\newcommand\exrtnlabelformat{$\square$}
%\newcommand\exrtnlabelformat{\exlabelsol\ \theeqexno}
%    \end{macrocode}
%    \end{macro}
%    This\DescribeMacro{\exrtnlabelformatwp} is the formatted return label (return from the solution),
%    for an exercise with parts.
%    \begin{macrocode}
\newcommand\exrtnlabelformatwp{$\square$}
%</package>
%<*package|eqexam>
%    \end{macrocode}
%    \begin{macro}{\aboveexskip}
%    \begin{macro}{\belowexskip}
% Amount of skip before and after exercise environment
%    \begin{macrocode}
\newcommand{\belowexskip}[1]{\setlength{\eq@tmplength}{#1}%
    \edef\eq@exerskip{\noexpand\removelastparskip
    \noexpand\vskip\the\eq@tmplength\relax\kern0pt}}
\let\eqexerskip\belowexskip
\belowexskip{\medskipamount}
\newcommand{\aboveexskip}[1]{\setlength{\eq@tmplength}{#1}%
    \edef\eq@priorexskip{\noexpand\vskip\the\eq@tmplength\relax
        \kern0pt}}
\let\priorexskip\aboveexskip
\aboveexskip{\medskipamount}
\let\eq@postexerciseHook\relax
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\belowexsolnskip}
% Amount of skip after solutions, this one is written to a file, so
% we must protect it from early expansion.
%    \begin{macrocode}
\newcommand\belowexsolnskip{\protect\medskip}
%\let\eqafterexersolnskip\belowexsolnskip
%    \end{macrocode}
% \changes{v7.4}{2015/03/23}{added \string\cs{removelastparskip}}
% \DescribeMacro\removelastparskip removes last \cmd\parskip, as needed.
%    \begin{macrocode}
\def\removelastparskip{\ifdim\parskip>0pt\vskip-\parskip\fi}
%</package|eqexam>
%<*package>
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\nolinkcolor}
% This is the color to paint the word 'Exercise' with parts;
% or it colors all the 'Exercise's when the nosolutions option
% has been used
% \changes{v6.05a}{2006/05/08}
% {
%   Changed \string\cs{nolinkcolor} into a text fill-in. Now, the command \string\cs{nolinkcolor}
%   fills in \string\cs{@nolinkcolor}, which holds the named color.
% }
%    \begin{macrocode}
\newcommand{\nolinkcolor}[1]{\def\@nolinkcolor{#1}}
\nolinkcolor{blue}
%    \end{macrocode}
%    \end{macro}
%    \subsection{Define \texttt{exercise} Environment}
% Defines the \texttt{exercise} environment for writing exercises,
% and solutions.  The solutions are written to the file
% \cmd{\jobname.sol}, and input at the end of the file.  Hypertext
% links connect the statement of the exercise with its solution.
%
%\smallskip\noindent\textbf{Basic usage}
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
%commandchars={!()},codes={\catcode`\%=9}]
%\begin{exercise}
%The exercise question is posed.
%\begin{solution}
%The solution to exercise goes here.
%\end{solution}
%\end{exercise}
%\end{Verbatim}
% These environments should be nested as illustrated above.
%
% The \texttt{exercise} environment has three optional arguments. The syntax
% for an exercise without parts is\dots
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
%commandchars={!()},codes={\catcode`\%=9}]
%\begin{exercise}[!ameta(ctr)][h|H]
%...
%\end{exercise}
%\end{Verbatim}
% (1) The value of this first optional argument, \texttt{<ctr>}, is a counter.
% You can use the \texttt{exercise}
% environment then to create other environments with their own
% counters.  A special value of zero (0) for this optional argument,
% means not to associate any counter with the environment.  These
% features can be used in combination with the \cs{SolutionsAfter}
% and \cs{SolutionsAtEnd} commands to obtain different effects,
% see the manual for examples
%
% (2) The second optional argument is an `\texttt{h}' or an \texttt{H}, this signals that the
% solution to the exercise should not be written to the \cmd{\jobname.sol}
% file.  See manual for examples.
%
% The \texttt{exercise} environment has three optional arguments. The syntax
% for an exercise with parts is\dots
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
%commandchars={!()},codes={\catcode`\%=9}]
%\begin{exercise}[!ameta(ctr)]* ...\end{exercise}
%\begin{exercise*}[!ameta(ctr)] ...\end{exercise*}
%\end{Verbatim}
% (1) The value of this first optional argument, \texttt{<ctr>}, is a counter.
% You can use the \texttt{exercise}
% environment then to create other environments with their own
% counters.  A special value of zero (0) for this optional argument,
% means not to associate any counter with the environment.  These
% features can be used in combination with the \cs{SolutionsAfter}
% and \cs{SolutionsAtEnd} commands to obtain different effects,
% see the manual for examples
%
% (2) The second argument is a star \texttt{*}.  The presence of a * signals
% that this exercise has multiple parts.  See the manual for the proper
% syntax.
%
% Beginning with version 6.07, there is now a \texttt{exercise*}
% environment, this is what I should have done originally, but now its
% done.  The \texttt{exercise*} signals an exercise with parts. It takes
% one optional parameter, the name of a counter \texttt{<ctr>} that is to
% be used.\medskip
%
% \noindent With the exercises\DescribeMacro{\exerSolnInExtFile},
% you have the option of including them in the main document, or putting them
% in an external document.  The \cs{exerSolnsInExtFile} command lets you specify an external file name.
% Just use the \textit{basename}, hyperref will add the extension.  If an external file is specified, all
% solution links are changed to links between documents. Usage:
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
%commandchars={!()},codes={\catcode`\%=9}]
%\exerSolnsInExtFile{myExSonls}
%\end{Verbatim}
%    \begin{macrocode}
\newcommand{\exerSolnsInExtFile}[2][]
  {\let\exerSolns@ExtFile\eq@YES\gdef\eq@exerSolns@fileName{#2}%
   \gdef\exerSolns@ReturnPath{#1}}
\let\exerSolns@ExtFile\eq@NO
\def\exerSolns@ReturnPath{}
%</package>
%<*package|eqexam>
%    \end{macrocode}
%\DescribeMacro{\marginparpriorhook}\DescribeMacro{\marginparafterhook}
%\DescribeMacro{\afterlabelhskip} Various hooks into an exercise.
%    \begin{macrocode}
\let\marginparpriorhook\@empty % used to material before the exercise
\let\marginparafterhook\@empty % used to material after the exercise
\let\afterlabelhskip\space
%    \end{macrocode}
% \DescribeMacro{\exersolnheadhook}
% Inserted in the header of each exercise solution. May be used for inserting
% addition text or macros in the solution.
%    \begin{macrocode}
\let\exersolnheadhook\@empty
\let\exer@solnheadhook\@empty
%    \end{macrocode}
%    \begin{macro}{\eqexheader}
%    \begin{macro}{\eqexheader@wrapper}
% \cs{eqexheader} typesets `Exercise xx'. \cs{eqexheader@wrapper} creates a hypertarget
% at the heading. Portions of \cs{eqexheader} is also used by \textsf{eqExam}.
%    \begin{macrocode}
\newcommand{\eqexheader}
{%
%</package|eqexam>
%<*package>
    \ifeq@nolink   % no link to solution
%</package>
%<*package|eqexam>
        \mbox{\color{\@nolinkcolor}\if\exerstar*\exlabelformatwp\else
        \exlabelformat\fi}%
%</package|eqexam>
%<*package>
    \else
        \if\exerSolns@ExtFile\eq@YES
            \mbox{\href{\eq@exerSolns@fileName\#ex.\the@exno}%
                {\exlabelformat}}%
        \else
            \mbox{\hyperlink{ex.\the@exno}{\exlabelformat}}%
        \fi
    \fi
%</package>
%<*package|eqexam>
}
\def\eqexheader@wrapper{\hypertarget{qex.\the@exno}{\eqexheader}}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\eqexlisttabheader}
% \cs{eqexlisttabheader} typesets `(a)' when we have exercises with parts.
% Portions are also used by \textsf{eqExam}.
%    \begin{macrocode}
\newcommand{\partsformat}[1]{\def\eq@partsformat{#1}}
\partsformat{(\hfil\thepartno\hfil)}
\newcommand{\defaultpartsformat}{%
    \partsformat{(\hfil\thepartno\hfil)}}
\let\exlisttabheaderpriorhook\@empty
\let\exlisttabheaderafterhook\@empty
\newcommand{\eqexlisttabheader}
{%
    \exlisttabheaderpriorhook
%</package|eqexam>
%<*package>
    \ifeq@nolink
%</package>
%<*package|eqexam>
      \color{\@nolinkcolor}\eq@partsformat
%</package|eqexam>
%<*package>
    \else
      \if\exerSolns@ExtFile\eq@YES
        \href{\eq@exerSolns@fileName\#ex.\the@exno\thepartno}%
            {\eq@partsformat}%
        \else
            \hyperlink{ex.\the@exno\thepartno}{\eq@partsformat}%
        \fi
    \fi
%</package>
%<*package|eqexam>
}
%    \end{macrocode}
%    \end{macro}
%    Introduce a method of copying questions from \env{exercise} environment to solution page. The \env{cq@CQ}
%    is \cs{let} to the \env{cq} environment, only defined within the \env{exercise} environment.
%    \changes{v7.8}{2016/11/02}{Added support to copy questions in the exercise environment to solution pages.}
%    \begin{macrocode}
\newcount\cq@Cnt
\def\cq@CutName{cq-\the\cq@Cnt.cut}
%    \end{macrocode}
%    \begin{environment}{cq}
%    The \env{cq} environment is \cs{let} to the \env{cq@CQ} environment at the beginning of
%    the \env{exercise} environment, \env{cq@CQ} begin the internal name of the environment.
%    \par\medskip\noindent\textbf{Example}
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
%commandchars={!()},codes={\catcode`\%=9}]
%\begin{exercise}
%\begin{cq}
%!quad(This is the question)
%\end{cq}
%\begin{solution}
%!quad(This is the question)
%\end{solution}
%\end{exercise}
%\end{Verbatim}
%    \begin{macrocode}
\let\cq@star\eq@NO
%    \end{macrocode}
%    We declare a new switch \cs{ifcqs}
%    \changes{v7.8}{2016/11/02}{Added code to copy questions of exercises to
%    the solution page}
%    \begin{macrocode}
\newif\ifcqqs \cqqstrue
\newif\ifcqIsActive \cqIsActivefalse
\def\cqQS{\@ifstar{\cqQSV}{\cqQSA}}
\def\cqQSA#1#2{\ifcqqs#1\else#2\fi}
%    \end{macrocode}
%    Also defined in the \pkg{web} package.
%    \begin{macrocode}
\@ifpackageloaded{web}{\@ifundefined{IF@AorBswitch}{%
    \PackageWarningNoLine{A version of the web package
    dated\MessageBreak 2016/11/03 or later is required
    for \string\cqQS}}}{}%
\@ifundefined{webtempboxi}{\newbox\webtempboxi
    \newbox\webtempboxii}{}
\providecommand\SHOWTEMPBOXi{\unhbox\webtempboxi}
\providecommand\TRUEACTIONi{\aftergroup\SETTEMPBOXii}
\providecommand\TRUEACTIONia{\aftergroup\SHOWTEMPBOXi}
\providecommand\FALSEACTIONii{\aftergroup\SETTEMPBOXi}
\providecommand\FALSEACTIONiia{\aftergroup\SHOWTEMPBOXi}
\providecommand\SETTEMPBOXi{\IF@AorBswitch\else
    \afterassignment\TRUEACTIONia\fi
    \setbox\webtempboxi=\hbox}
\providecommand\SETTEMPBOXii{\IF@AorBswitch
    \afterassignment\FALSEACTIONiia\fi
    \setbox\webtempboxii=\hbox}
\def\cqQSV{\let\IF@AorBswitch\ifcqqs
    \IF@AorBswitch
        \def\eq@next{\afterassignment\TRUEACTIONi\SETTEMPBOXi}\else
        \def\eq@next{\afterassignment\FALSEACTIONii\SETTEMPBOXii}\fi
    \eq@next}
\def\eq@turnMessageOff{\let\save@message\message
    \let\message\@gobble}
\def\eq@turnMessageOn{\let\message\save@message}
\def\eqCQDeclarations{\cqqsfalse\eq@turnMessageOff
    \includecomment{sPage}\excludecomment{qPage}%
    \eq@turnMessageOn}
\def\eqTopOfSolnPage{\withinsoldoctrue\cqSAfalse
    \eqCQDeclarations}
\def\eqTopOfQslPage{\withinqsldoctrue}
\eq@turnMessageOff
\includecomment{qPage}\excludecomment{sPage}
\eq@turnMessageOn
%</package|eqexam>
%<*package>
\def\writecqQSfalse{%
  \writeT@ExSolns{\protect\eqTopOfSolnPage}}
\def\writeTopOfQslPage{\writeT@QzSolns{\protect\eqTopOfQslPage}}
\AtBeginDocument{\writecqQSfalse\writeTopOfQslPage}
%</package>
%<*package|eqexam>
\newenvironment{cq@CQ}
{%
%    \end{macrocode}
%    Begin verbatim write, the listing is saved to \cs{cq@CutName}, indexed by
%    \cs{cq@Cnt}.
%    \begin{macrocode}
    \global\cqIsActivetrue
    \global\advance\cq@Cnt1\relax
    \immediate\openout\CommentStream=\cq@CutName
    \let\verbatim@out\CommentStream
    \verbatimwrite
}{%
    \endverbatimwrite
    \immediate\closeout\CommentStream
%    \end{macrocode}
%    Close out the stream, define \cs{cq@INPUTCUT}, which is then input back in
%    after the end of the group.
%    \begin{macrocode}
    \ifx\cq@star\eq@YES
        \xdef\cq@INPUTCUT{\noexpand\cqqstrue
            \noexpand\input{\cq@CutName}\noexpand
            \def@QuesToSoln}\else
        \xdef\cq@INPUTCUT{\noexpand\cqqstrue
            \noexpand\input{\cq@CutName}\noexpand
            \p@ssQuesToSoln}\fi
    \aftergroup\cq@INPUTCUT
}
%    \end{macrocode}
%    \end{environment}
%    \begin{environment}{cq*}
%    The \env{cq*} version of \env{cq}; within the \env{exercise} environment \env{cq*}
%    is \cs{let} to \env{cqs@CQ}. This version does not automatically paste the question
%    into the solution, instead, the command \cs{cqCopiedQues} is defined for that solution,
%    which expands to the question statement.
%    \begin{macrocode}
\newenvironment{cqs@CQ}{\let\cq@star\eq@YES\cq@CQ}{\endcq@CQ}
%    \end{macrocode}
%    \end{environment}
%    The default formatting on the solution page is, when \env{cq} is used,
%\begin{flushleft}
%\textbf{Exercise 1.} \emph{Question}: This is the question
%\medskip\par
%\emph{Solution}: This is its solution
%\end{flushleft}
%The word `Question' may be localized using \cs{declCQQuesStr}\DescribeMacro{\declCQQuesStr}, the default is
%seen below. The word `Solution' can be localized with \cs{declCQSolStr}\DescribeMacro{\declCQSolStr}, the default is seen below.
%    \begin{macrocode}
\def\declCQQuesStr#1{\def\cqQStr{#1}}
\declCQQuesStr{Question}
\def\declCQSolStr#1{\def\cqSStr{#1}}
\declCQSolStr{Solution}
%    \end{macrocode}
%    Aside from the words `Question' and `Solution', the way these two are formated is determined
%    through \cs{declCQPre}\DescribeMacro{\declCQPre} and \cs{declCQPost}\DescribeMacro{\declCQPost}.
%    These declarations are seen below.  The \cs{declCQPost} is more complicated in that it handles the
%    formatting after the copied question; in the default definition, we skip a \cs{medskip} and do a \cs{indent}.
%    Trailing the string \cs{cqSStr}, the internal command defined by \cs{declCQSolnStr}, is a space and
%    an \cs{ignorespaces}. Use \cs{writeToExSolns} to make local changes, for example,
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
%commandchars={!()},codes={\catcode`\%=9}]
%...
%\end{exercise}
% Changed the string from Solution to Answer, do this prior to the
% exercise.
%\writeToExSolns{\protect\declCQSolStr{Answer}}
%
%\begin{exercise*}
%...
%\end{Verbatim}
%Best placed between exercises.
%    \begin{macrocode}
\newcommand\declCQPre[1]{\def\cq@Pre{#1}}
\declCQPre{\emph{\cqQStr}:\space}
\newcommand\declCQPost[1]{\def\cq@Post{#1}}
\declCQPost{\par\medskip\noindent\emph{\cqSStr}:\space\ignorespaces}
%    \end{macrocode}
%    The command \cs{cqFmtPasteQues}\DescribeMacro{\cqFmtPasteQues} inputs the copied question text,
%    along with \cs{cq@Pre} to the left and \cs{cq@Post} to the right. This command is normally
%    not redefined.
%    \begin{macrocode}
\def\cqFmtPasteQues#1{\cq@Pre\input{#1}\cq@Post}
%    \end{macrocode}
%    The command \cs{p@ssQuesToSoln} does the work of formatting the question that is pasted
%    to the solution page. It is executed at the end of the \env{cq} environment.
%    \begin{macrocode}
\def\p@ssQuesToSoln{\ifeq@hidesolution\else
%    \end{macrocode}
%    Inform the system that the definition of \cs{eqterminex} is changing. This to prevent
%    writing the same line multiple times.
%    \changes{v8.2.8}{2018/12/13}{write \string\cs{declareterminex} only if not solutionsafter}
%    \begin{macrocode}
    \global\terminexchangedtrue % dps cq
    \ifeq@solutionsafter\else
    \writeT@ExSolns{\protect\decleqterminex{\protect
      \cqFmtPasteQues{\cq@CutName}}\eq@commentchar}\fi\fi}
\def\declCopyQues#1{\def\cqCopiedQues{#1}}
\def\def@QuesToSoln{\restoreNormalSolns
%    \end{macrocode}
%    Here we restore \cs{eqterminex} to its default value, we set the stitch to false.
%    \begin{macrocode}
    \global\terminexchangedfalse % dps cq
    \ifeq@hidesolution\else\writeT@ExSolns{\protect
        \declCopyQues{\protect\input{\cq@CutName}}}\fi}
%    \end{macrocode}
%    \cs{restoreNormalSolns}\DescribeMacro{\restoreNormalSolns} restores \cs{eqterminex} to  its
%    default definition. It is place between exercises.
%    \changes{v8.2.8}{2018/12/13}{write \string\cs{declareterminex} only if not \string\opt{solutionsafter}}
%    \begin{macrocode}
\newcommand\restoreNormalSolns{\ifeq@solutionsafter\else
    \writeT@ExSolns{\protect\decleqterminex{\protect
      \eqterminexDEF}\eq@commentchar}\fi}
%    \end{macrocode}
%    \begin{environment}{exercise}
% With some of the preliminaries out of the way, we begin the exercise `environment'.
%    \begin{macrocode}
\newcommand{\eq@CommonCmd}[1]{\def\eq@@CommonCmd{#1}#1}
\let\eq@@CommonCmd\@empty
\newcommand\gExCommonCmd[1]{\gdef\gEx@CommonCmd{\eq@CommonCmd{#1}}}
\let\gEx@CommonCmd\@empty
\let\endexerhook\@empty
\newenvironment{exercise}
{%
    \let\cq\cq@CQ\let\endcq\endcq@CQ
    \csarg\let{cq*}\cqs@CQ
    \csarg\let{endcq*}\endcqs@CQ
    \par\removelastskip\eq@priorexskip\noindent
    \let\eqCommonCmd\eq@CommonCmd
    \def\eq@argi{eqexno}%% use eqexno counter
    \if\eq@exerstarEnv*\def\exerstar{*}\else\def\exerstar{x}\fi
    \def\currhideopt{x}%
    \@ifnextchar[{\exercise@}%
        {\if\exerstar*\def\eq@next{\@exercise}\else
         \def\eq@next{\exercise@@}\fi\eq@next}%
}{\eq@postexerciseHook\endexerhook\par
    \global\let\insE@rlyAtQues\@empty
    \global\eq@exerciseheadingtrue\removelastskip\eq@exerskip}
%    \end{macrocode}
% the exercise environment takes two sets of optional parameter,
% the first one is a counter (or 0) and second one is either \texttt{h} or \texttt{H}.
%    \begin{macrocode}
\def\exercise@[#1]{\edef\eq@arg{#1}%
    \if\eq@arg h\def\currhideopt{h}%
        \eq@hidesolutiontrue\eq@nolinktrue%
        \ifeq@globalshowsolutions
            \eq@hidesolutionfalse\eq@nolinkfalse\fi
        \def\eq@next{\@exercise}%   h, no *, no counter
    \else
        \if\eq@arg H%
            \edef\currhideopt{\Hidesymbol}%
            \eq@hidesolutiontrue\eq@nolinktrue%
            \ifeq@globalshowsolutions
                \eq@hidesolutionfalse\eq@nolinkfalse
            \fi
            \def\eq@next{\@exercise}%   H, no *, no counter
        \else
            \def\currhideopt{x}%
            \ifx\eq@arg\@empty\else\def\eq@argi{#1}\fi
            \if\exerstar*\def\eq@next{\@exercise}\else
            \def\eq@next{\exercise@@}\fi
        \fi
    \fi
\eq@next}
%    \end{macrocode}
% Specified counter, test for *
%    \begin{macrocode}
\def\exercise@@{\@ifstar{\def\exerstar{*}\@exercise}{\exercise@@@}}
%    \end{macrocode}
% We have recorded the presence of a star, is there
% another optional argument, h
%    \begin{macrocode}
\def\exercise@@@{\@ifnextchar[{\exercise@@@@}{\@exercise}}
%    \end{macrocode}
%    \begin{macrocode}
\def\exercise@@@@[#1]{\edef\eq@arg{#1}%
    \if\eq@arg h\def\currhideopt{h}%
        \eq@hidesolutiontrue\eq@nolinktrue
        \ifeq@globalshowsolutions
            \eq@hidesolutionfalse\eq@nolinkfalse\fi
        \def\eq@next{\@exercise}%   h, no *, no counter
    \else
        \if\eq@arg H\edef\currhideopt{\Hidesymbol}%
            \eq@hidesolutiontrue\eq@nolinktrue%
            \def\eq@next{\@exercise}%   h, no *, no counter
        \else
            \def\currhideopt{x}%
            \PackageWarning{exerquiz}{The option #1 is not recognized}
            \let\eq@next\relax
        \fi
    \fi
\eq@next}
%    \end{macrocode}
%    \begin{macro}{\exerSolnHeader}
% When a solution is written to the .sol file, there is a header line that contains formatting information.
% This command can be redefined as desired.  We also introduce to markers, \cs{eqEXt} and \cs{endeqEXt} which
% can be used in any way your imaginations can conjure up. Basically, the mark the beginning and ending of the solution.
%    \begin{macrocode}
\newif\ifeq@exerciseheading \eq@exerciseheadingtrue
%    \end{macrocode}
% \changes{v6.7q}{2013/12/15}{Added this hook for use by \string\textsf{contsolns.dtx}}
% \changes{v8.5.10}{2020/03/14}{Added \string\cs{priorexlabelheader} to support \string\pkg{eqexam}}
%    \begin{macrocode}
\let\prior@exerSolnHeaderHook\@empty
\newcommand\exerSolnHeader[3]{%
    \prior@exerSolnHeaderHook
    \ifeqforpaper\else\webnewpage\fi\markright{#1}%\par\noindent%
    \priorexlabelheader
%</package|eqexam>
%<*package>
    \noindent\hypertarget{#2}{#3}\global\let\priorexlabelheader\relax
%</package>
%<*eqexam>
    #3\global\let\priorexlabelheader\relax
%</eqexam>
%<*package|eqexam>
    \solnhspace
}
%    \end{macrocode}
% (2015/05/18) Made this definition conditional on whether \textsf{eqexam}
% is loaded. The command is meant for \textsf{eqexam}. The \textsf{exerquiz}
% package should be loaded after \textsf{eqexam} if the two are to be used
% together, preferably by the \texttt{links} or \texttt{online} options of \textsf{eqexam}.
%    \begin{macrocode}
\let\solnItemMngt\relax
%    \end{macrocode}
%    \end{macro}
% \DescribeMacro{\eqEXt}These two mark the beginning and end of solution to an exercise. \cs{eqEXt} is
% set up to have two required arguments, usually both empty. The arguments are
% used for filtering. The first might be a number, so we can filter out even numbered
% exercises from odd ones. The second one is a keyword, we can filter by keyword.
%\changes{v6.7}{2013/04/07}{Changing \string\cs{eqEXt} so that it has two
%required arguments}
%    \begin{macrocode}
\let\eqEXt\@gobbletwo
\let\endeqEXt\relax
%    \end{macrocode}
% \DescribeMacro{\eqExtArg}\cs{eqExtArg} and \DescribeMacro{\eqFilterArg}\cs{eqFilterArg}
% are the arguments for \cs{eqEXt}. They are redefined at the creation of the
% exercise.
%    \begin{macrocode}
\let\eqExtArg\@empty
\let\eqFilterArg\@empty
%    \end{macrocode}
% The format of the solutions to exercises as they appear in the SOL file is,
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
%commandchars={!()},codes={\catcode`\%=9}]
%\eqEXt{\eqExtArg}{\eqFilterArg}\exerSolnHeader
%!quad{\exsecrunhead}{ex.1}{\textbf{Exercise\ 1.}}\relax
%!quad...
%!quad!ameta(solution content)
%!quad...
%\ReturnTo{qex.1}{\hbox {$\square $}}\endeqEXt\par\medskip
%\end{Verbatim}
% \changes{v6.7a}{2013/05/03}{Change name of \string\cs{eq@writeexheader} to \string\cs{eqExerSolnHeader}}
%    \begin{macrocode}
\let\eqExerSolnHeader\@empty
%    \end{macrocode}
% The \cs{solutionparshape} is a command that supports the \cs{leadinitem} command
% of \texttt{eqexam}. Its normal value is \cs{@empty}.
%    \begin{macrocode}
\let\solutionparshape\@empty
%    \end{macrocode}
%\changes{v7.2}{2015/03/22}{added \string\cs{setPrbSolnAftrIndent}}
% \DescribeMacro{\setPrbSolnAftrIndent}\cmd{\setPrbSolnAftrIndent} sets the amount of indent
% for the statement of problem and the solution-after solution. The command saves its argument
% in \cs{eq@pslnaindnt} (default \texttt{0pt}) and sets the hook
% \cs{eq@setPrbSolnAftrIndnt}. This latter macro appears in \cs{@exercise} below. Its
% initial value is \cs{relax}; otherwise, it sets \cs{parindent=\#1}.
%    \begin{macrocode}
\def\eq@pslnaindnt{0pt}
\let\eq@setPrbSolnAftrIndnt\relax
\newcommand{\setPrbSolnAftrIndent}[1]{\ifdim#1=0pt
  \def\eq@pslnaindnt{0pt}\let\eq@setPrbSolnAftrIndnt\relax\else
  \edef\eq@pslnaindnt{#1}\edef\eq@setPrbSolnAftrIndnt{\expandafter
  \noexpand\expandafter\parindent#1\noexpand\relax}\fi}
%    \end{macrocode}
%\changes{v7.2}{2015/03/22}{added \string\cs{restorejustify}}
%The command \DescribeMacro\restorejustify\cmd{\restorejustify} is designed
%for use in the \texttt{solution} environment of an \cs{item} within the
%\texttt{parts} environment in \texttt{tabular} mode. By default,
%\texttt{parts[2]}, for example, sets up a tabular, each entry is in a
%paragraph (\texttt{p\{\}}) but \cs{raggedright} is used. We change this for
%the solution using \cmd{\restorejustify}. Use \DescribeMacro\restoreJustifyOn\cmd{\restoreJustifyOn}
% to turn on this feature and \DescribeMacro\restoreJustifyOff\cmd{\restoreJustifyOff}
% to turn it off (default).
%    \begin{macrocode}
\newif\if@restorejustify \@restorejustifyfalse
\newcommand\restoreJustifyOn{\@restorejustifytrue}
\newcommand\restoreJustifyOff{\@restorejustifyfalse}
\def\restorejustify{\if@restorejustify
    \@rightskip\z@skip \rightskip\@rightskip
    \leftskip\z@skip \let\\\@normalcr\fi}
%    \end{macrocode}
% The \DescribeMacro\@exercise definition of the \texttt{exercise} environment continues here.
%    \begin{macrocode}
\def\@exercise{%
    \global\let\solutionparshape\@empty
    \let\verbatim@out=\ex@solns
    \if\eq@argi0\else\refstepcounter{\eq@argi}\fi\stepcounter{@exno}%
    \if\exerstar*% if exercise with parts
        \eq@nolinktrue
    \else
        \if\currhideopt H%
        \else
            \ifeq@solutionsafter
                \eq@nolinktrue  % no link to solution
            \else
                \eq@ckglobalhide %
                \ifeq@hidesolution\else
%    \end{macrocode}
% Here's where we write the header to the .sol file.
%    \begin{macrocode}
                   \global\let\eqExerSolnHeader\eq@@writeexheader
                \fi
            \fi
        \fi
    \fi
    \ifvmode\ifdim\lastskip>\z@
        \vskip-\lastskip
    \fi\fi
    \if\exerstar*%
        \let\solution\solnexer@woparts
        \let\endsolution\endsolnexer@woparts
        \let\parts\exercise@parts
        \let\endparts\endexercise@parts
    \else
        \let\solution\solnexer@woparts
        \let\endsolution\endsolnexer@woparts
        \let\parts\relax
        \let\endparts\relax
        \if\Hidesymbol h\eq@nolinkfalse\ifeq@solutionsafter
            \eq@nolinktrue\fi\fi
    \fi
%    \end{macrocode}
% Here is where `Exercise' is typeset; the commands \cs{marginparpriorhook} and \cs{marginpartafterhook}
% can be used to insert content in before and after the `Exercise'.
%    \begin{macrocode}
    \eq@initializeContAnnot
    \ifeq@exerciseheading
    \prior@questionsHook
    \insE@rlyAtQues\marginparpriorhook\noindent\eqexheader@wrapper
    \afterlabelhskip\marginparafterhook\gEx@CommonCmd
    \eq@setPrbSolnAftrIndnt\ignorespaces\fi}
%    \end{macrocode}
%    \end{environment}
% \changes{v6.4z}{2012/11/28}{Extracted code to make it available elsewhere.}
% (2012/11/28) Extracted the code below from the macro above so it can be used
% elsewhere as well.
%\par\medskip\noindent
%    The \cs{eqterminex} command is one that appears on the solution page, just after the exercise number.
%    We redefine it to do our will. The convenience macro \DescribeMacro{\decleqterminex}\cs{decleqterminex} is used for that purpose.
%    We use \cs{ifterminexchanged} to track whether the default definition is changed.
%    \begin{macrocode}
\newif\ifterminexchanged \terminexchangedfalse % dps cq
\newcommand\decleqterminex[1]{\def\eqterminex{#1}}
%    \end{macrocode}
%    The default definition of \cs{eqterminex} is saved under \cs{eqterminexDEF}.
%    \begin{macrocode}
\def\eqterminexDEF{\relax\ignorespaces}
\decleqterminex{\eqterminexDEF}
%    \end{macrocode}
%\changes{v6.7}{2013/04/07}{Inserted another argument into \string\cs{eqEXt}}
% (2013/04/07) Added another argument into \cs{eqEXt}, used for filtering.\par\medskip
%    \noindent
%    (2018/02/13) When solutions are written to the SOL file, they are not normally in a group.
%    If you execute \DescribeMacro\makeExSolnsLocalOn\cs{makeExSolnsLocalOn}, each solution
%    is written in a group. Undo this with \DescribeMacro\makeExSolnsLocalOff\cs{makeExSolnsLocalOff},
%    which is the historic default.
%    \changes{v8.1p}{2018/02/13}{Added grouping for exercise solutions to the SOL file}
%    \begin{macrocode}
\newif\ifmakeExSlLocal \makeExSlLocalfalse
\def\makeExSolnsLocalOn{\makeExSlLocaltrue}
\def\makeExSolnsLocalOff{\makeExSlLocalfalse}
\let\eqMrkSoln\@gobble
\let\priorexlabelheader\relax
\def\eqExerSolnHeaderSngl{%
    \ifmakeExSlLocal\protect\begingroup^^J\fi
    \ifx\eqMrkCpyArg\@empty\else
      \protect\eqMrkSoln{\eqMrkCpyArg}\fi
    \protect\eqEXt{\eqExtArg}{\eqFilterArg}\protect
    \solnItemMngt\protect\exerSolnHeader{\exsecrunhead}{ex.\the@exno}%
    {\exsllabelformat}\exer@solnheadhook
    \exersolnheadhook\protect\eqterminex}
\def\eq@@writeexheader{\ifeq@hidesolution\else\ifOKToWriteExamData
  \set@display@protect
  \immediate\write\verbatim@out{\eqExerSolnHeaderSngl}%
  \set@typeset@protect\fi\fi}
%    \end{macrocode}
%\changes{v6.7}{2013/04/07}{Inserted another argument into \string\cs{eqEXt}}
% Added another argument into \cs{eqEXt}, used for filtering.
%    \begin{macrocode}
\def\eqExerSolnHeaderList{%
    \ifmakeExSlLocal\protect\begingroup^^J\fi
    \ifx\eqMrkCpyArg\@empty\else
      \protect\eqMrkSoln{\eqMrkCpyArg}\fi
    \protect\eqEXt{\eqExtArg}{\eqFilterArg}\protect
    \solnItemMngt\protect\exerSolnHeader{\exsecrunhead}%
    {ex.\the@exno\thepartno}{\exsllabelformatwp}%
    \exer@solnheadhook\exersolnheadhook\protect\eqterminex}
\def\eq@@writeexheaderlist{\ifeq@hidesolution\else\ifOKToWriteExamData
  \set@display@protect\immediate
  \write\verbatim@out{\eqExerSolnHeaderList}\set@typeset@protect\fi\fi}
%    \end{macrocode}
%    \subsection{Define \texttt{solution} Environment for \texttt{exercise}}
%    \begin{macro}{solution}
%    This is the \texttt{solution} environment for
%    \texttt{exercise}; either start \cmd{\verbatim} or,
%    \cmd{\eq@solutionsaftertrue} write the label \cmd{\exsolafter}.
%
% The solution macro for the \texttt{exercise} environment now takes an optional
% argument. This argument must be a vertical skip ( i.e., \texttt{[1in]} ).  When the solution
% does not correspond to a tabular multi-part question, a vertical skip
% |\vspace{#1}| is introduced when the \texttt{nosolutions} is in effect and when
% \texttt{solutionsafter} is not.  This feature may be useful for constructing
% tests in this space is left for the student to write in the answer; yet, later
% when \texttt{solutionsafter} is true, the solutions appear instead of the vertical
% white space.
%    \begin{macrocode}
\long\def\setsolnspace#1{\def\newsolnspace{#1}%
    \let\solnspace\newsolnspace}
%    \end{macrocode}
%    \begin{macro}{\ckSolnOpt}
%    \begin{macro}{\noSolnOpt}
%    \cs{noSolnOpt} turns off the check for the option argument
%    of the \texttt{solution} environment for the \texttt{exercise}
%    environment. Designed for use with \textsf{eqexam}.
% \changes{v6.4v}{2012/07/27}{Added \string\cs{ckSolnOpt} and \string\cs{noSolnOpt}
% to switch on and off checking for the optional vertical space in the
% \texttt{solution} environment.}
%    \begin{macrocode}
\newif\ifeq@ckSolnVspace \eq@ckSolnVspacetrue
\def\ckSolnOpt{\global\eq@ckSolnVspacetrue}
\def\noSolnOpt{\global\eq@ckSolnVspacefalse}
\let\solnhspace\space
\let\solnspace\space
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
% This macro is the beginning of the \texttt{solution} environment for
% exercises.
%    \changes{v8.1g}{2017/12/27}{added \string\cs{pushEnvir} and \string\cs{popEnvir} to remove
%    \string\cs{everypar} influence in \string\cs{solnexer@woparts}}
%    \changes{v8.1o}{2018/02/12}{Added cond. definition for \string\cs{if@eqalignfilllinestoleft}}
%    \begin{macrocode}
\let\exsolnonceonlytophook\relax
\def\solnexer@woparts{%
  \ifanswerkey\ifeqe@flextended\ifcont@nnot
  \ifx\solutionparshape\@empty\else % dpsj8
    \pushEnvir
      \everypar{}\if@eqalignfilllinestoleft\else
      \parshape=1 \leadinIndent \linewidth\fi
    \popEnvir
  \fi\fi\fi\fi\def\bLeaveVspace{x}% = no vertical space added
  \exsolnonceonlytophook % dps27
  \global\let\exsolnonceonlytophook\relax
%    \end{macrocode}
%   The following lines are needed to get a better alignment
%   with the bgonly key option, in \pkg{eqexam}.
%   \changes{v8.1f}{2017/12/04}{Added lines to support eqexam}
%    \begin{macrocode}
  \@ifundefined{KV@eqefillLines@bgonly}{}
    {\ifKV@eqefillLines@bgonly\ifvmode\else
      \par\leavevmode\strut\fi\fi
    \ifKV@eqefillLines@outlineonly\leavevmode\strut\fi}%
    \ifeq@ckSolnVspace
        \def\eq@next{\@ifnextchar[{\solnexer@@woparts}%]
        {\solnexer@@woparts[\null]}}\else
        \def\eq@next{\solnexer@@woparts[\null]}\fi
%    \end{macrocode}
% The code below, now removed, used to deny the use of the optional parameter
% in the parts-tabular environment. (2013/03/26)
%\begin{verbatim}
%    \ifx\endparts\endexercise@parts@tabular
%        \def\eq@next{\solnexer@@@woparts}\fi
%\end{verbatim}
%    \begin{macrocode}
    \eq@next}
\let\eqPriorVspace\@gobble
\newif\if@eqlinedfiller \@eqlinedfillerfalse
\newcommand{\vspaceFiller}[1]{\vfill}
\newcommand{\vspaceFillerDefault}[1]{\vfill}
\def\eqWriteLine{\hfill}
\def\eq@linesXPgs{%
    \begingroup\offinterlineskip\parskip0pt
    \@tempcnta=0
    \@whilenum\@tempcnta<\soln@keys@nLines\relax\do
    {\vskip0pt\penalty-50\vglue\wlVspace\eqWriteLine
        \advance\@tempcnta1\relax}\par\endgroup}
\let\leavevspace\relax % dpsj5
\newcommand{\vspaceFmt}[1]{%
  \ifx\solutionparshape\@empty\else
%    \end{macrocode}
% This must be part of the solution for a \cs{leadinitem} question.
% We need to make an adjustment to the \cs{linewidth}.
%    \begin{macrocode}
      \advance\linewidth-\leadinIndentPrtSep\fi
    \ifdim\sameVspace>0pt
      \let\bLeaveVspace\@empty
      \def\leavevspace{%
        \ifx\eq@insertverticalspace\eq@YES\par\eq@quessolskip
          \eqPriorVspace{#1}{\nobreak\noindent
%    \end{macrocode}
% If \texttt{nLines} is non-empty, we'll use some spacial code
% to generate the lines so it breaks across pages.
%    \begin{macrocode}
          \if@eqlinedfiller
            \ifx\soln@keys@nLines\@empty
              \def\eq@lines@next{\vspaceFiller{#1}}\else
                \def\eq@lines@next{\eq@linesXPgs}\fi
          \else
            \def\eq@lines@next{\parbox[b][#1][t]{\linewidth}
              {\vspaceFiller{#1}}}%
          \fi\eq@lines@next}%
        \fi
      }\expandafter\leavevspace
  \fi}
%    \end{macrocode}
% \changes{v6.8g}{2014/04/08}{Added key-val here for \string\pkg{eqexam}.}
% New option for the \texttt{solution} environment, \IndexKey{nLines}\texttt{nLines}.
%    \begin{macrocode}
\define@key{soln@keys}{nLines}[]{\def\soln@keys@nLines{#1}}
\let\soln@keys@nLines\@empty
%    \end{macrocode}
% \cs{eqKV@errx} is a hack into the \textsf{keyval} package. The change, made
% below in \cs{solnexer@@woparts} is temporary. We use it to get the dimen
% of the \texttt{solution} env. Necessary since we have an \texttt{nLines} key defined
% for \textsf{eqexam}.
%    \begin{macrocode}
%  keyval package \@tempa contains undefined key
\def\eqKV@errx#1{\xdef\XKV@rm{\@tempa}}
%    \end{macrocode}
%    \begin{macrocode}
\def\eqSolnForEqexam#1{%
    \let\soln@keys@nLines\@empty
    \setkeys*{soln@keys}{#1}%
    \ifx\soln@keys@nLines\@empty
        \ifx\minVspacet@bs\@empty\xdef\sameVspace{\XKV@rm}\else
        \xdef\sameVspace{\minVspacet@bs}\fi
    \else
        \@tempdima\wlVspace
        \@tempdima=\soln@keys@nLines\@tempdima
        \xdef\sameVspace{\the\@tempdima}%
       \ifx\XKV@rm\@empty\else
            \if@equsedim\let\soln@keys@nLines\@empty
                \xdef\sameVspace{\XKV@rm}\fi
        \fi
    \fi
    \ifx\sameVspace\@empty\gdef\sameVspace{0pt}\fi
}
%    \end{macrocode}
% Now the beginning of the \textsf{solution} environment for \texttt{exercise} env.
%    \begin{macrocode}
\def\solnexer@@woparts[#1]{%
    \ifcqIsActive\else\ifterminexchanged
%    \end{macrocode}
%    If this problem does not use \env{cq} or \env{cq*}, we reset the solution page,
%    to the default definition of \cs{eqterminex}.
%    \begin{macrocode}
        \restoreNormalSolns\fi\fi % dps cq
    \global\cqIsActivefalse
%    \end{macrocode}
% \changes{v6.3z}{2011/04/28}{Added definition of \string\cs{sameVspace} for the cases
% where there is no vertical space specified.}
%    Is the argument \cs{null}? If yes, same as \texttt{0pt}.
%    \begin{macrocode}
    \def\eq@argi{#1}\def\eq@null{\null}%
    \ifx\eq@argi\@empty\gdef\sameVspace{0pt}\else
        \ifx\eq@argi\eq@null\gdef\sameVspace{0pt}\else
%    \end{macrocode}
% \changes{v6.8g}{2014/04/08}{Added key-val here for \string\pkg{eqexam}.}
% Now, if the optional argument is non-null, we must discern the argument:
% is it a vertical space or a key-value?
%    \begin{macrocode}
        \@ifundefined{PointsOnLeft}{%
            \let\eqKV@errx@SAVE\KV@errx
            \let\KV@errx\eqKV@errx\let\XKV@rm\@empty
            \edef\temp@exp{\noexpand\setkeys*{soln@keys}{#1}}\temp@exp
            \let\KV@errx\eqKV@errx@SAVE
            \ifx\soln@keys@nLines\@empty\else
            \PackageInfo{exerquiz}{%
            nLines key detected in solution environment,\MessageBreak
            is not not recognized without eqexam,\MessageBreak
            will remove it}%
            \let\soln@keys@nLines\@empty\fi
            \xdef\sameVspace{\XKV@rm}%
        }{\eqSolnForEqexam{#1}}%
%    \end{macrocode}
% (03/04/11) Try to insert a new option: if there are \cs{ifvspacewithsolns} option
% then \textsf{eqexam} should leave space for writing an answer, and put solutions at the end
% of the document.
%    \begin{macrocode}
% dpsj5 moved to solnexer@@@woparts
%        \ifx\sameVspace\@empty\gdef\sameVspace{0pt}\fi
%        \ifvspacewithsolns\vspaceFmt{\sameVspace}\fi
%        \ifeq@nosolutions\ifeq@solutionsafter\else
%            \vspaceFmt{\sameVspace}\fi\fi
    \fi\fi
    \solnexer@@@woparts
}
%    \end{macrocode}
% \changes{v7.7q}{2016/07/22}{Added \string\cs{solnsafterSkip}}
% \changes{v8.1h}{2018/01/03}{Added \string\cs{@solnafterSkipOnce} (package use only)}
%    \begin{macrocode}
\def\solnsafterSkip#1{\setlength{\@tempdima}{#1}%
    \edef\solnsafterSkipAmt{\the\@tempdima}%
    \def\solutionsafterSkip{\vskip\solnsafterSkipAmt\relax}}
\solnsafterSkip{\smallskipamount}
\def\@solnafterSkipOnce#1{\setlength{\@tempdima}{#1}%
    \xdef\@solnafterSkipOnceAmt{\the\@tempdima}}%
\def\@@solnafterSkipOnce{\vskip\@solnafterSkipOnceAmt\relax %dpsj3
  \gdef\@solnafterSkipOnceAmt{0pt}}
\def\@solnafterSkipOnceAmt{0pt}
%    \end{macrocode}
%   Add separation between the question and the \texttt{solution} environment.
%   \changes{v8.1d}{2017/11/13}{Added \string\cs{quessolsep} for exercises (eqexam)}
%    \begin{macrocode}
\def\quessolSkip#1{\setlength{\@tempdima}{#1}%
  \edef\eq@quessolskip{\noexpand\vskip\the\@tempdima\relax}}
\def\eq@quessolskip{\vskip\smallskipamount}
%    \end{macrocode}
% The next two definitions are used for debugging the
% \cs{ifkeepdeclaredvspacing} feature (\textsf{eqexam} only).
%    \begin{macrocode}
\def\eqe@debugVertSkip#1{}
\def\eqe@showEndHere#1{#1}
%    \end{macrocode}
% Used to set the starting point of the solution
%    \begin{macrocode}
\def\eqe@setStartSolns{%
    \xdef\eq@startSoln{\the\pagetotal}%
    \eqe@debugVertSkip{\marginpar{\smash{b[\sameVspace]}}}%
}
%    \end{macrocode}
%\changes{v6.4b}{2011/06/30}{%
% Save the definitions of \string\cs{comment} and \string\cs{endcomment}. For some reason,
% yet to be determined, there are problems when using the \string\opt{fortextbook}
% option when hiding solutions.
%}
%\changes{v8.2.9}{2019/02/11}{\string\cs{eqSavedComment}\string\cs{dlcomment}, \string\cs{dlcomment}\space
%is not defined in \string\pkg{insdljs}}
%    \begin{macrocode}
\let\eqSavedComment\dlcomment
\let\endeqSavedComment\enddlcomment
%    \end{macrocode}
%\changes{v7.4}{2015/03/23}{added \string\cs{setTabulrSolnEnv}}
%    \begin{macrocode}
\def\setTabulrSolnEnv{%
    \@ifundefined{@listii@SAVE}{\global\let\@listii@SAVE\@listii}{}%
    \expandafter\def\expandafter\@listii\expandafter{\@listii@SAVE
      \leftmargin\leftmarginii \labelwidth\leftmarginii
      \advance\labelwidth-\labelsep}%
    \def\everyparShape{\everypar{\parshape \@ne 0pt \linewidth}}%
%    \end{macrocode}
% \cmd{\reset@doendpe} resets the definition of the core command
% \cmd{\@doendpe} so behavior is correct whether list environment
% starts in vertical mode or not.
%    \begin{macrocode}
    \reset@doendpe{\parshape \@ne 0pt \linewidth}%
    \parshape \@ne 0pt \linewidth
    \everyparShape
}
\newif\ifthereissolution
\let\priorexsolafterList\@empty
\let\priorexsolafterTab\@empty
\let\priorexsolafterSngl\@empty
\def\eq@Hid{H}\def\eq@hid{h}
\def\solutionafterExCmds#1{\def\@rgi{#1}\ifx\@rgi\@empty
  \let\eqSolnExCmds\relax\else
  \def\eqSolnExCmds{#1}\fi}
\let\eqSolnExCmds\relax
\def\eq@b@ddCodeSpecialDef#1{#1}%
\let\eq@b@ddCodeSpecial\eq@b@ddCodeSpecialDef
\def\solnexer@@@woparts{\ifeq@solutionsafter\else
    \expandafter\begingroup\fi
  \global\thereissolutiontrue
  \global\let\procsoln\relax
  \global\let\endprocsoln\relax
  \def\exerwparts@cols{0}%
  \let\verbatim@out\ex@solns
  \if\currhideopt\eq@Hid
%    \end{macrocode}
%    (2017/02/09) Hide \cs{minVspacet@bs} for `H' option
%    \changes{v7.8e}{2017/02/09}{Hide \string\cs{minVspacet@bs} for `H' option}
%    \begin{macrocode}
    \let\minVspacet@bs\@empty
    \let\procsoln\eqSavedComment
    \let\endprocsoln\endeqSavedComment
    \def\eq@next{\procsoln}%
  \else
    \eq@ckglobalhide
    \ifeq@hidesolution
      \let\procsoln\eqSavedComment
      \let\endprocsoln\endeqSavedComment
    \else
      \ifeq@solutionsafter\else
          \ifx\eq@@CommonCmd\@empty\else
              \set@display@protect
              \immediate\write\verbatim@out{\eq@@CommonCmd}%
              \set@typeset@protect
          \fi
      \fi
        \let\procsoln\verbatimwrite
        \let\endprocsoln\endverbatimwrite
    \fi
    \def\eq@next{%
      \ifeq@solutionsafter
        \let\procsoln\relax
        \let\endprocsoln\relax
        \removelastskip\removelastparskip
        \cqSAtrue\eqCQDeclarations
        \declCopyQues{\input{\cq@CutName}}%
        \ifx\exsolafter\@empty
%    \end{macrocode}
%    If we have solutions after and there is no label and no vertical
%    skip specified, we do nothing other than to execute \cs{eqe@setStartSolns},
%    which marks the beginning of the ``solution.''
%    \begin{macrocode}
          \ifdim\sameVspace=0pt\eqe@setStartSolns
          \else
%    \end{macrocode}
%    If there is vertical space specified, we do a standard skip, and mark the beginning
%    of the solution with \cs{eqe@setStartSolns}.
%    \begin{macrocode}
            \solutionsafterSkip
            \@@solnafterSkipOnce
            \eqe@setStartSolns
          \fi
        \else\par\kern0pt
          \solutionsafterSkip
          \@@solnafterSkipOnce
          \noindent\strut\eqe@setStartSolns
        \fi
        \parskip\eqeques@parsep
        \ifx\endparts\endexercise@parts@tabular
          \eq@setPrbSolnAftrIndnt
          \restorejustify
        \fi
%    \end{macrocode}
%    (2017/02/09) Added prior \cs{exsolafter} hooks.
%    \changes{v7.8e}{2017/02/09}{Added prior \string\cs{exsolafter} hooks}
%    \begin{macrocode}
        \ifx\endparts\endexercise@parts@tabular\expandafter
          \priorexsolafterTab\else
        \ifx\endparts\endexercise@parts@list\expandafter
          \priorexsolafterList\else\expandafter
          \priorexsolafterSngl\fi\fi
%    \end{macrocode}
% The solution after label, followed by a space.
%    \begin{macrocode}
%        \eqSolnExCmds
        \exsolafter\space\ignorespaces
%    \end{macrocode}
% We set the shape of the solutionafter.
% This is empty if \cs{leadinitem} is not used.
%    \begin{macrocode}
        \solutionparshape
      \else
%    \end{macrocode}
%    Write the solution header 11/03/05
%    \begin{macrocode}
        \eqExerSolnHeader
%    \end{macrocode}
%     Write \cs{eqExerSolnHeader} after all.
% \changes{v8.2.8}{2018/12/13}{write \string\cs{eqExerSolnHeader} after all}
%    \begin{macrocode}
        \global\therearesolutionstrue\expandafter\procsoln
      \fi
    }%
  \fi
  \eq@b@ddCodeSpecial{\eq@next}%
}% dpsj4
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\let\endsolnexerhook\@empty
\let\pkg@endsolnexerhook\@empty
\let\endsolnexerhookaux\@empty
%    \end{macrocode}
% This macro attempts to insert the return link at the end of the
% last paragraph of the solutions, this makes the return label
% look nice, and saves a little space.
%    \begin{macrocode}
\def\eq@fititin#1{\noindent\unskip\nobreak\hfill\penalty100
    \hskip1em\hbox{}\nobreak\hfill#1}%
\let\eqfititin\eq@fititin
%</package|eqexam>
%<*package>
\def\ReturnTo#1#2{\eq@fititin{\hyperlink{#1}{#2}}}
\def\xReturnTo#1#2{\eq@fititin{\href{#1}{#2}}}
%</package>
%    \end{macrocode}
%    \begin{macro}{\eqExerSolnTrailer}
% The material that follows the solution in the SOL file.
%    \begin{macrocode}
%<*package|eqexam>
%    \end{macrocode}
%   \changes{v8.2.6}{2018/12/03}{defined \string\cs{eq@commentchar}}
%    \begin{macrocode}
\bgroup\catcode`\%=12\relax
\gdef\eq@commentchar{%}\egroup
\newcommand\eqExerSolnTrailer{%
%</package|eqexam>
%<*package>
    \if\exerSolns@ExtFile\eq@YES\protect\xReturnTo
        {\exerSolns@ReturnPath\jobname\#qex.\the@exno}%
    \else\protect\ReturnTo{qex.\the@exno}\fi
    {\protect\mbox{\if\exerstar*\exrtnlabelformatwp\else
        \exrtnlabelformat\fi}}%
    \protect\endeqEXt\ifeqforpaper\protect\par{\belowexsolnskip}\fi
%    \end{macrocode}
%    Tack on comment character at the end of the line.
%   \changes{v8.2.6}{2018/12/03}{defined \string\cs{eq@commentchar}}
%    \begin{macrocode}
    \eq@commentchar^^J% %dpsd03
%</package>
%<*eqexam>
    \protect\ReturnTo{page.\the\c@page}%
    {\protect\mbox{\if\exerstar*\exrtnlabelformatwp\else
        \exrtnlabelformat\fi}}%
    \protect\endeqEXt\ifeqforpaper\protect\par{\belowexsolnskip}\fi
    \eq@commentchar^^J%
%</eqexam>
%<*package|eqexam>
%    \end{macrocode}
%     \changes{v8.2.5}{2018/10/03}{\string\cs{ifmakeExSlLocal} misplaced, corrected}
%    \begin{macrocode}
    \ifmakeExSlLocal\protect\endgroup^^J\fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\endsolnexer@woparts}
%    Unless \cmd{\eq@solutionsaftertrue}, then \cmd{\endverbitim},
%    and write return labels.
%    \begin{macrocode}
\let\eq@e@ddCodeSpecialDef\relax % dpsj4
\let\eq@e@ddCodeSpecial\eq@e@ddCodeSpecialDef % dpsj6
%    \end{macrocode}
%    Added \cs{kdvsp@Restore} to support
%    the \texttt{flextended} option from \textsf{eqexam}. See the placement
%    of this command below its default definition of \cs{relax}.
%    \changes{v8.1i}{2018/01/20}{Added \string\cs{kdvsp@Restore} to support
%    the \string\opt{flextended} option from \string\pkg{eqexam}}
%    \begin{macrocode}
\let\kdvsp@Restore\relax
\def\eq@clearMrkCpy{\if@targetforextr
  \global\let\eqMrkCpyArg\@empty
  \global\@targetforextrfalse\fi
}
\def\endsolnexer@woparts{\endprocsoln\eq@e@ddCodeSpecial
  \pkg@endsolnexerhook
  \eq@clearMrkCpy
  \ifeq@solutionsafter\else
    \expandafter\endgroup\fi % from \begingroup at \solnexer@@@woparts
  \global\let\exsolnonceonlytophook\relax
  \ifx\sameVspace\@empty\gdef\sameVspace{0pt}\fi
  \ifvspacewithsolns\vspaceFmt{\sameVspace}\else
  \ifeq@nosolutions\ifeq@solutionsafter\else
    \vspaceFmt{\sameVspace}\fi\fi\fi
  \if\currhideopt H%
    \ifkeepdeclaredvspacing\vskip\sameVspace\fi
  \else
%    \end{macrocode}
% If solutions after, we start a new paragraph, then add some kerning glue,
% this gives a better gauge for calculating the \cs{pagetotal}.
%    \begin{macrocode}
    \ifeq@solutionsafter
      \ifx\isitleadin\eq@YES\parshape=0 \fi
      \if\exerstar*%
      \eq@fititin{\mbox{\exrtnlabelformatwp}}\else
      \eq@fititin{\mbox{\exrtnlabelformat}}\fi
      \ifx\istabularexer\eq@YES\unskip\kern0pt\else\par\fi
%    \end{macrocode}
% if \cs{ifkeepdeclaredvspacing} is true, we attempt
% to preserve the vertical space declared by the \textsf{solution} environment when
% \cs{ifeq@solutionsafter} is true.
% \changes{v6.3z}{2011/04/28}{if \string\cs{ifkeepdeclaredvspacing} is true, we attempt
% to preserve the vertical space declared by the \string\env{solution} environment when
% \string\cs{ifeq@solutionsafter} is true.}
%    \begin{macrocode}
      \ifx\minVspacet@bs\@empty
        \ifkeepdeclaredvspacing
%    \end{macrocode}
% We get the current \cs{pagetotal}, and subtract off the page total as recorded
% by \cs{eq@startSoln}.
%    \begin{macrocode}
          \@tempdima\pagetotal
          \advance\@tempdima-\eq@startSoln
%    \end{macrocode}
% \changes{v6.4w}{2012/26/27}{Added \string\cs{relax} following the assignment.}
% {\TeX} was looking ahead looking for the rest of the dimension, this caused
% problems because later code was expanded when it should not have been. Inserted
% \cs{relax}, |\@tempdimb\sameVspace\relax|.
%    \begin{macrocode}
          \@tempdimb\sameVspace\relax
%    \end{macrocode}
%    if \cs{soln@keys@nLines} is nonempty, we put \cs{sameVspace} to \texttt{1sp},
%    unless the author asks for \texttt{1sp}, this is how it is set.
%    \begin{macrocode}
          \ifdim\@tempdimb>1sp\relax
%    \end{macrocode}
% If there is a positive value for \cs{sameVspace}, we calculate
% the difference between\cs{@tempdimab} and \cs{@tempdima}, that is, we calculate
%\begin{verbatim}
%   \sameVspace-(\pagetotal-\eq@startSoln)
%\end{verbatim}
%    \begin{macrocode}
            \advance\@tempdimb-\@tempdima
%    \end{macrocode}
% If this difference is positive, we will skip this amount.
%    \begin{macrocode}
            \ifdim\@tempdimb>0pt\vglue\@tempdimb\kern0pt
              \let\eqe@showEndHere\@gobble
              \edef\tmp@exp{\noexpand\marginpar{\noexpand
                \smash{e: adj \the\@tempdimb}}}%
                \eqe@debugVertSkip{\tmp@exp}%
            \fi
          \fi
        \fi
        \eqe@showEndHere{\eqe@debugVertSkip{\marginpar{\smash{e}}}}%
        \fi
      \else
        \eq@ckglobalhide
        \ifeq@hidesolution\else
          \endsolnexerhookaux
%    \end{macrocode}
% Here's were we write the trailer for the solution
%   \changes{v8.2.6}{2018/12/03}{if \string\cs{@targetforextrfalse}, set \string\cs{@targetforextrfalse}}
%    \begin{macrocode}
          \writeT@ExSolns{\eqExerSolnTrailer}%
        \fi
      \fi
    \fi
    \kdvsp@Restore
    \endsolnexerhook\penalty0\relax}
%    \end{macrocode}
%    \end{macro}
% \subsection{The \texttt{exercise*} Environment: Exercises with Parts}
% Exercises with parts are enclosed within a \texttt{parts} environment. There are two types
% of parts listing: list-type and tabular-type.
%    \begin{environment}{exercise*}
% For the \texttt{exercise*} environment, we set a flag to indicate that the \cs{exerstar}
% has been set in the star environment, the begin the \cs{exercise} and finished with
% \cs{endexercise}.
%\changes{v6.07}{2007/05/05}
%{
%   Created the \string\texttt{exercise*} environment, this is equivalent to the \string\texttt{*} option of the
%   \string\env{exercise} environment. You can use either version, but now, \string\env{exercise*} is preferred.
%}
%    \begin{macrocode}
\let\eq@exerstarEnv\relax
\newenvironment{exercise*}{\def\eq@exerstarEnv{*}\exercise}
{\global\let\insE@rlyAtQues\@empty\endexercise}
%    \end{macrocode}
%    \end{environment}
%    \begin{environment}{parts}
%    Initially, we see if there is an optional argument, if yes, the
%    tabular environment is used, the argument is the number of columns
%    requested.  Otherwise, we use a list environment.
%    \begin{macrocode}
\def\exerwparts@cols{0}
\let\topofpartshook\relax
\let\@listiiredefined\eq@NO
\let\itsExerParts\eq@NO
%    \end{macrocode}
% (2015/05/30) Added a feature for lead in for tabular mode for parts environment.
% \DescribeMacro{\tableadin}\cmd{\tableadin} is placed prior to
% \verb!\begin{parts}[2}!, no preamble leading into the question is assumed.
% Using the switch \cs{if@tableadinitem} we remove any \cs{par}s and \cs{vskip}s.
%    \begin{macrocode}
\newif\if@tableadinitem\@tableadinitemfalse
\newcommand{\tableadin@external}{\PackageError{exerquiz/eqexam}
    {The \string\tableadin\space command is designed\MessageBreak
     for the problem* environment of eqexam}{Use \string\tableadin\space
     in the problem* environment of eqexam.}%
}
\let\tableadin\tableadin@external
\newcommand{\eq@tableadinparts}{\item\relax
    \PackageError{exerquiz/eqexam}{The \string\tableadin\space
        command is not allowed in the\MessageBreak
        parts environment}{Use \string\tableadin\space
        in the problem* environment of eqexam.}%
}
%    \end{macrocode}
%    (2016/12/16) Define a flag \cs{istabularexer} that signals to the solution environment it is in a tab environment
%    \changes{v7.8b}{2016/12/16}{Added \string\cs{istabularexer}}
%    \begin{macrocode}
\let\istabularexer\eq@NO
\def\exercise@parts{\let\rlspar\relax
  \ifx\solutionparshape\@empty
    \let\isitleadin\eq@NO
%    \end{macrocode}
% If \cs{tableadin}, we remove the \cs{removelastskip} and \cs{par} that follows.
%    \begin{macrocode}
    \if@tableadinitem\let\rlspar\@gobbletwo\fi
  \else\let\isitleadin\eq@YES\fi
  \rlspar\removelastskip\par
  \if\isitleadin\eq@YES
%    \end{macrocode}
% \changes{v7.6}{2015/05/24}{Some vspace adjustment at the beginning of
% a leadinitem.} If there is a lead-in, we set \cs{topsep} to \texttt{0pt}
% and skip \cs{itemsep}.
%    \begin{macrocode}
    \def\eqparts@topsep{0pt}%
    \vskip\eqparts@itemsep\relax\fi
  \topofpartshook
  \let\itsExerParts\eq@YES
  \global\let\@listiiredefined\eq@NO
  \def\exerwparts@cols{0}\@ifnextchar[%
  {%
%    \end{macrocode}
% When there is a \cs{tableadin}, we remove \cs{removelastparskip} because it does not occur above.
%    \begin{macrocode}
   \if@tableadinitem\else\removelastparskip\fi
   \let\endparts\endexercise@parts@tabular\exercise@parts@tabular@}%
  {\let\endparts\endexercise@parts@list\exercise@parts@list}}
%    \end{macrocode}
% \subsubsection{List-type Parts Question}
%    This is a redesigned \texttt{list} environment.  Meant to be used with the
%    \texttt{exercise} environment with the *-option.
%    \begin{macrocode}
\def\eq@extralabelsep{0pt}
%    \end{macrocode}
%    \begin{macro}{\setPartsWidth}
% Convenience macro to set \cs{part@indent}.
%\changes{v6.4h}{2011/07/28}{%
%   Added \string\cs{setPartsWidth} to set \string\cs{part@indent}. Also
%   defined \string\cs{eqe@prtsepPrb}.
%}
%    \begin{macrocode}
\newcommand{\setPartsWidth}[1]{\def\parts@indent{\normalfont#1}%
    \bgroup\settowidth{\eq@tmpdima}{\parts@indent}%
    \xdef\widthOfParts{\the\eq@tmpdima}\egroup}
\setPartsWidth{(d)}
%    \end{macrocode}
%    \end{macro}
% \DescribeMacro{\eqe@prtsepPrb} is used to set \cs{labelsep}.
% I've also added the two hooks \DescribeMacro{\prior@parts@hook}\cs{prior@parts@hook} and
% \DescribeMacro{\post@parts@hook}\cs{post@parts@hook} as well; these are used
% by \textsf{eqexam} for hanging the solutions with parts correctly.
%    \begin{macrocode}
\def\eqe@prtsepPrb{\ }
\providecommand{\prbPrtsep}[1]{\def\eqe@prtsepPrb{#1}}
\providecommand{\exPrtsep}[1]{\def\eqe@prtsepPrb{#1}}
\providecommand{\eqequesparsep}[1]{\def\eqeques@parsep{#1}}
\eqequesparsep{0pt}
\let\prior@parts@hook\@empty
\let\post@parts@hook\@empty
\let\abovepartshook\@empty
\let\belowpartshook\@empty
\let\eqp@rtc@lcm@rk\relax
\let\eq@insertContAnnot\relax
%    \end{macrocode}
% (2012/02/04) Common code to the definition of \cs{item}
% both list and tabular versions.
% \changes{v8.5.10}{2020/03/14}{\string\cs{probInMinip@ge} set to \string\cs{relax}}
%    \begin{macrocode}
\def\eq@item@common{\eq@insertContAnnot\eqp@rtc@lcm@rk
    \global\let\probInMinip@ge\relax
    \def\currhideopt{x}\eq@hidesolutionfalse\eq@nolinkfalse
    \@ifnextchar[{\@ckhide}{\eq@item}}
%    \end{macrocode}
% \DescribeMacro{\eqpartsitemsep}(2012/02/03) Fine tune the control over space between
% parts.
%\changes{v6.4o}{2012/02/04} {Fine tune the control over space between parts.}
%    \begin{macrocode}
\newcommand{\partsitemsep}[1]{{%
    \setlength{\@tempdima}{#1}%
    \xdef\eqparts@itemsep{\the\@tempdima}}}
\let\eqpartsitemsep\partsitemsep
\def\eqparts@itemsep{0pt}
\newcommand\partsparsep[1]{{%
    \setlength{\@tempdima}{#1}%
    \xdef\eqparts@parsep{\the\@tempdima}}}
\def\eqparts@parsep{0pt}
\newcommand\partstopsep[1]{{%
    \setlength{\@tempdima}{#1}%
    \xdef\eqparts@topsep{\the\@tempdima}}}
\def\eqparts@topsep{3pt}
%    \end{macrocode}
% The next two commands are in support of the \cs{leadinitem} definition
% of \textsf{eqexam}
%    \begin{macrocode}
\newcommand{\leadinitem@external}{\PackageError{exerquiz/eqexam}
    {The \string\leadinitem\space command is designed to be\MessageBreak
     the first item in the problem*\MessageBreak
     environment above the parts environment}
     {Use \string\leadinitem\space in the problem* environment.}}
\let\leadinitem\leadinitem@external
\let\itsforleadinitem\eq@NO
\newcommand{\eq@leadinitemparts}{\item\relax
    \PackageError{exerquiz/eqexam}{The \string\leadinitem\space
        command is not allowed in the\MessageBreak
        parts environment}
     {Use \string\leadinitem\space in the problem* environment.}}
%    \end{macrocode}
% (2014/03/23) Problems when description env is used with parts env. The
% hook \cs{exlisttabheaderafterhook} is interfering with the optional argument.
%    \begin{macrocode}
\def\eq@handleOptArg[#1]{\def\eq@optArg{[#1]}\eq@handleOptArgi}
\def\eq@handleOptArgi{\expandafter
    \eq@item@latex\eq@optArg\exlisttabheaderafterhook}
%    \end{macrocode}
% We add a new switch \cs{ifwithinparts} (2014/12/03) that is used to detect whether
% we are within the parts environment.
%    \begin{macrocode}
\newif\ifwithinparts
\let\ex@listtabheader@fterhook\@empty
\let\probInMinip@ge\relax
%    \end{macrocode}
% Begin the list version of the parts environment.
%    \begin{macrocode}
\newenvironment{exercise@parts@list}{%
    \settowidth{\eq@tmplength}{\parts@indent}%
    \edef\widthOfParts{\the\eq@tmplength}%
%    \end{macrocode}
%    Write to SOL file, unless solutions-after.
%    \changes{v8.2.8}{2018/12/13}{Write to SOL file, unless solutions-after}
%    \begin{macrocode}
    \global\let\eqExerSolnHeader\eq@@writeexheaderlist
    \eq@initializeContAnnot\eq@nolinkfalse\prior@parts@hook
    \abovepartshook\list{\normalfont
    \if\Hidesymbol h\eq@nolinkfalse\ifeq@solutionsafter
        \eq@nolinktrue\fi\fi
    \if\currhideopt H%
    \else
        \ifeq@solutionsafter
            \eq@nolinktrue  % no link to solution
        \else
            \ifeq@nosolutions
                \eq@nolinktrue  % no link to solution
            \else
                \eq@ckglobalhide
                \ifeq@hidesolution\eq@nolinktrue\else
%    \end{macrocode}
% Write the solution header to .sol for list type question.
%    \begin{macrocode}
                    \global\let\eqExerSolnHeader\eq@@writeexheaderlist
                \fi
            \fi
        \fi
    \fi
%    \end{macrocode}
% (2013/04/28) Inserted \texttt{[r]}
%    \begin{macrocode}
    \makebox[\widthOfParts][r]{\eqexlisttabheader}%
}{%
    \usecounter{partno}%
%    \end{macrocode}
% (2012/11/30) If \cs{solutionparshape} is nonempty, the user has used
% \cs{leadinitem}, so we increment \texttt{partno}.
%    \begin{macrocode}
    \if\isitleadin\eq@YES
      \settowidth{\eq@tmplength}{\parts@indent\eqe@prtsepPrb}%
      \xdef\prtsIndntSep{\the\eq@tmplength}%
      \if\itsforleadinitem\eqe@YES\setcounter{partno}{\fliPartNo}\else
      \setcounter{partno}{1}\fi\fi
    \let\leadinitem\eq@leadinitemparts
    \let\tableadin\eq@tableadinparts
    \global\let\solutionparshape\@empty
    \setlength{\topsep}{\eqparts@topsep}%
    \setlength{\parskip}{0pt}%
    \setlength{\partopsep}{0pt plus 1pt minus 1pt}%
    \ifdim\eqeques@parsep=0pt
        \setlength{\parsep}{\eqparts@parsep}%
    \else
        \setlength{\parsep}{\eqeques@parsep}%
    \fi
    \setlength{\itemsep}{\eqparts@itemsep-\parsep}%
    \setlength{\itemindent}{0pt}%
    \setlength{\listparindent}{\parindent}%
%    \end{macrocode}
% For \cs{itemsep}, we subtract off, for reasons not precisely known to me.
% This is done for \textsf{eqexam}, what effect does it have on a straight
% \textsf{exerquiz} file?
%    \begin{macrocode}
    \settowidth{\labelsep}{\normalfont\eqe@prtsepPrb}%
    \addtolength{\labelsep}{\eq@extralabelsep}%
    \settowidth{\labelwidth}{\parts@indent}%
    \setlength{\leftmargin}{\labelwidth}%
    \addtolength{\leftmargin}{\labelsep}%
%    \end{macrocode}
% When a \texttt{trivlist} appear with the parts environment, it executes
% \cs{item}\cs{relax}, which causes problems because \cs{item} has been
% redefined. We try to correct this.
%    \begin{macrocode}
    \let\eq@item@latex\item
%    \end{macrocode}
% We handle the problem of seeing the optional argument by getting the argument,
% if there is one, and switching commands around.
%    \begin{macrocode}
    \def\eq@item{\@ifnextchar[{\eq@handleOptArg}
        {\eq@item@latex\ex@listtabheader@fterhook
            \exlisttabheaderafterhook}}%
    \def\eqthisenv{parts}\withinpartstrue
%    \end{macrocode}
%   If \cs{probInMinip@ge} has been redefined, continue to \cs{eq@item@common} to support \pkg{eqexam}.
%   \changes{v8.5.10}{2020/03/14}{Change in logic for \string\cs{item} to support \string\pkg{eqexam}}
%    \begin{macrocode}
    \def\item{\ifx\probInMinip@ge\relax
      \ifx\@currenvir\eqthisenv
        \def\eq@next{\eq@item@common}\else
        \def\eq@next{\eq@item}\fi
      \else\def\eq@next{\eq@item@common}\fi
    \eq@next}%
}}{\endlist\global\let\leadinitem\leadinitem@external
    \post@parts@hook\belowpartshook}
%    \end{macrocode}
% The following command is inserted at the beginning of the parts environment
% and defines the current problem number and the page the \texttt{problem*} environment
% starts. The command is used by the \textsf{eqexam} package.
%    \begin{macrocode}
\def\eq@initializeContAnnot{\@ifundefined{eqequestions}
    {\global\let\eqeCurrProb\relax}
    {\xdef\eqeCurrProb{\theeqquestionnoi}}%
    \xdef\eq@currProbStartPage{\arabic{page}}}
%    \end{macrocode}
% \subsubsection{Tabular-type Parts Question}
% Now for the tabular style of multi-part exercise, the argument
% \#1 is the number of columns requested.\medskip
%
%    \noindent(2017/02/09) Added \pkg{xkeyval} to optional argument of \env{parts}. Syntax is now
%\begin{verbatim}
%    \begin{parts}[<num>|nCols=<num>,minVspace=<length>]
%\end{verbatim}
%    \changes{v7.8e}{2017/02/09}{Added xkeyval to optional argument of \string\env{parts}}
%    \begin{macrocode}
\define@key{tabp@rts}{nCols}{\def\exerwparts@cols{#1}}
\define@key{tabp@rts}{minVspace}{\def\minVspacet@bs{#1}}
%    \end{macrocode}
%    Code to create vertical space when \texttt{answerkey} are in effect and
%    \cs{vspacewithkeyOn} is present.
%    \changes{v7.8e}{2017/02/09}{Added code for tab parts environment}
%    \begin{macrocode}
\let\minVspacet@bs\@empty
\def\minVspacetabs#1{\def\minVspacet@bs{#1}}
\def\priorexsolafterTab{\ifkeepdeclaredvspacing
    \ifeq@solutionsafter\ifx\minVspacet@bs\@empty\else
        \priorexsolafterTab@cont\fi\fi\fi}
\def\priorexsolafterTab@cont{\let\exsolafter@save\exsolafter
    \let\exsolafter\@empty
    \makebox[0pt][r]{\parbox[t][\minVspacet@bs][t]{0pt}
        {\strut\hfill\vfill\strut}}%
    \minipage[t]{\linewidth}\exsolafter@save}
\def\pkg@endsolnexerhook{\ifkeepdeclaredvspacing
    \ifeq@solutionsafter\ifx\minVspacet@bs\@empty\else
        \endminipage\fi\fi\fi}
%    \end{macrocode}
%    Begin the core of the \texttt{parts} tabular-mode environment.
%    \begin{macrocode}
\def\exercise@parts@tabular@[#1]{%
%    \end{macrocode}
% \cs{inittabMark} initializes the auto-tab feature. (2013/03/26)
%    \begin{macrocode}
  \inittabMark
%    \end{macrocode}
% locally, turn off continued annotations. Not allowed in tabular parts.
%    \begin{macrocode}
  \let\eq@insertContAnnot\relax
  \let\exerwparts@cols\@empty
  \setkeys*{tabp@rts}{#1}\ifx\exerwparts@cols\@empty
    \edef\exerwparts@cols{\XKV@rm}\fi
  \ifx\minVspacet@bs\@empty\keepdeclaredvspacingfalse\fi
  \let\istabularexer\eq@YES
  \@tempcnta\exerwparts@cols\relax
  \ifnum\@tempcnta<2\relax
        \PackageError{exerquiz}{%
        The number of columns for parts\MessageBreak
        needs to be an integer greater than 1}
        {Enter an integer, 2 or larger}\fi
  \exercise@parts@tabular}
%    \end{macrocode}
% For the tabular environment for the \texttt{exercise*} environment, we try
% to automatically insert the column delimiter (\texttt{\&}) and the end of line.
% \cs{eq@extabColCnt} keeps track of the column number for the auto-tab feature.
%    \begin{macrocode}
\newcount\eq@extabColCnt
%    \end{macrocode}
% \DescribeMacro{\autotabOn} turns on the auto-tab feature for the \texttt{parts} environment,
% while \cs{autotabOff}\DescribeMacro{\autotabOff} turns it off. The off setting is the default.
%    \begin{macrocode}
\def\autotabOn{\let\eq@tabMarkChk\relax%
    \PackageInfo{exerquiz/eqexam}{Executing \string\autotabOn}}
\def\autotabOff{\let\eq@tabMarkChk\@gobble
    \PackageInfo{exerquiz/eqexam}{Executing \string\autotabOff}}
\autotabOff
\def\inittabMark{\global\eq@extabColCnt=0 }
\def\resettabMark{\global\eq@extabColCnt=1 }
%    \end{macrocode}
% \DescribeMacro{\autotabnewline} is the new line command for the auto-tab feature.
% It does a |\\| and resets the column counter \cs{eq@extabColCnt}. The user can use
% \texttt{[vspace]}, the default is \cs{eqparts@tabrowsep}. We use \cs{noalign} so that the space
% is added to the bottom of the whole row.
%    \begin{macrocode}
\newcommand\autotabnewline[1][\eqparts@tabrowsep]{%
%    \end{macrocode}
%    If this is not tabular env, \cs{autotabnewline} does nothing
%    \begin{macrocode}
    \ifnum\exerwparts@cols>0\relax
    \ifx\eq@tabMarkChk\@gobble
        \def\eq@atnext{\expandafter
            \tabularnewline\expandafter[#1]}\else
        \def\eq@atnext{\resettabMark\tabularnewline
            \noalign{\expandafter\kern#1}}\fi
    \expandafter\eq@atnext\fi}
\def\eq@tabMark{%
    \ifnum\eq@extabColCnt=0\relax
        \global\advance\eq@extabColCnt1\relax
        \let\eq@next\relax
    \else
        \ifnum\eq@extabColCnt=1\relax
            \let\eq@next\relax
        \else
            \ifnum\eq@extabColCnt>\exerwparts@cols
                \let\eq@next\autotabnewline
            \else\def\eq@next{&}\fi
        \fi
    \fi
    \eq@next
    \global\advance\eq@extabColCnt1\relax}
%    \end{macrocode}
%    Set up the tabular environment, after making a lot of decisions.
%    \begin{macrocode}
\newcommand\partstabcolsep[1]{\def\eq@partstabcolsep{#1}}
\partstabcolsep{1.5pt}
\newcommand\partstabtopsep[1]{\def\eq@partstabtopsep{#1}}
\partstabtopsep{3pt}
\def\eq@vpartstabtopsep{\vskip\eq@partstabtopsep\relax}
\newcommand\partstabrowsep[1]{\setlength{\@tempdima}{#1}%
    \edef\eqparts@tabrowsep{\the\@tempdima}}
\partstabrowsep{0pt}
\newenvironment{exercise@parts@tabular}{%
    \setcounter{partno}{0}%
%    \end{macrocode}
%    \changes{v8.2.8}{2018/12/13}{Write to SOL file, unless solutions-after}
%    \begin{macrocode}
    \global\let\eqExerSolnHeader\eq@@writeexheaderlist
%    \end{macrocode}
% (2015/01/10) If \cs{solutionparshape} is nonempty, the user has used
% \cs{leadinitem}, so we increment \texttt{partno}.
%    \begin{macrocode}
    \def\tablrIndent{\hglue\prtsIndntSep\relax}%
    \if\isitleadin\eq@YES
        \if$\the\everypar$\let\tablrIndent\relax\fi
        \setcounter{partno}{1}\fi
    \let\leadinitem\eq@leadinitemparts
    \let\tableadin\eq@tableadinparts
    \global\let\solutionparshape\@empty
    \settowidth{\eq@tmplength}{\parts@indent\eqe@prtsepPrb}%
    \xdef\prtsIndntSep{\the\eq@tmplength}%
    \sbox{\eq@tmpbox}{\parts@indent}%
    \let\eq@item@latex\item
    \let\eq@item\item@part@tabular
    \def\eqthisenv{parts}\withinpartstrue
    \def\item{\ifx\@currenvir\eqthisenv
        \def\eq@next{\eq@tabMarkChk\eq@tabMark\eq@item@common}\else
        \def\eq@next{\eq@item@latex}\fi
    \eq@next}\eq@nolinkfalse
%    \end{macrocode}
%\changes{v6.4x}{2012/11/27}{Added control over row spacing in parts environment}
% Added control over row spacing in parts environment. The spacing
% is controlled by \cs{eqpartstabrowsep}, default value of \texttt{0pt}. The macro
% \cs{@xtabularcr} is from the {\LaTeX} core. Definition \cs{eq@xtabularcr} is found
% after the current definition block.
%    \begin{macrocode}
    \@ifundefined{@xtabularcr}{\let\@xarraycr\eq@xtabularcr}
    {\let\@xtabularcr\eq@xtabularcr}%
%    \end{macrocode}
% We reduce the width of the \cs{parbox}es (p|{width}|) by \cs{eq@partstabcolsep} to leave
% room for \cs{tabcolsep=}\cs{eq@partstabcolsep} between columns.
%\begin{verbatim}
%   n=\exerwparts@cols
%   width=(\linewidth-2*(n-1)*\tabcolsep)/n
%\end{verbatim}
%    \begin{macrocode}
    \eq@tmpdima=\linewidth
    \advance\eq@tmpdima-\prtsIndntSep\relax
    \@tempcnta\exerwparts@cols\relax
    \advance\@tempcnta-1\relax
    \multiply\@tempcnta2\relax
    \@tempdima\prtsIndntSep\relax
    \divide\@tempdima 2\relax
    \edef\halfWidth{\the\@tempdima}%
    \advance\@tempdima\eq@partstabcolsep\relax
    \tabcolsep\@tempdima
    \multiply\@tempdima\@tempcnta
    \advance\eq@tmpdima-\@tempdima
    \divide\eq@tmpdima by\exerwparts@cols\relax %dpsj3
    \edef\widthOfPartsBox{\the\eq@tmpdima}% dpsj2
%    \end{macrocode}
% If there is a \cs{tableadin}, we do not perform a \cs{vskip}.
%    \begin{macrocode}
    \if@tableadinitem\else\vskip\eq@partstabtopsep\relax\fi
    \noindent\normalbaselines\kern0pt
    \prior@parts@hook\abovepartshook
%    \end{macrocode}
%\changes{v7.03}{2015/03/02}{Added \string\texttt{\string\GT{\string\cs{strut}}}, this gives
% better control over vertical spacing.}%
% \changes{v7.4}{2015/03/23}{inserted \string\cs{setTabulrSolnEnv}}%
%    \begin{macrocode}
    \tablrIndent\tabular[t]{@{}*{\exerwparts@cols}{>{\setTabulrSolnEnv
        \parskip\eqeques@parsep\relax
        \parindent0pt\relax\strut}p{\eq@tmpdima}}@{\hidewidth}}%
}{\endtabular\kern0pt
    \@ifundefined{@listii@SAVE}{}{\global\let\@listii\@listii@SAVE
    \global\let\@listii@SAVE\relax}%
    \post@parts@hook\belowpartshook
%    \end{macrocode}
% \changes{v7.4}{2015/03/23}{added an adjustment to the command \string\cs{endexercise@parts@tabular}}
% A vertical space adjustment\par\medskip\noindent
% (201/05/09) There is a problem of communicating the totals through
% the \cs{mark} command (use in \textsf{eqexam}). In \textsf{eqexam}
% the command \cs{eqe@innermarkpts} is defined. Once the group is closed
% we emit this mark.
%    \begin{macrocode}
    \aftergroup\eqe@innermarkpts
    \aftergroup\eq@vpartstabtopsep}
%    \end{macrocode}
% (201/05/09) We make a default definition for \cs{eqe@innermarkpts}, this is needed
% when \textsf{exerquiz} is used without \textsf{eqexam}.
%    \begin{macrocode}
\let\eqe@innermarkpts\relax
%    \end{macrocode}
%    Redefine \verb+\item+, could be risky
%    \begin{macrocode}
\def\item@part@tabular{\refstepcounter{partno}%
%    \end{macrocode}
% As of 2013/03/25, I am allowing solutions after for tabular parts. I'm commenting
% out the following line.\\
% |%\eq@solutionsafterfalse % no solutionsafter are allowed|
% \changes{v8.2.8}{2018/12/13}{write \string\cs{eqExerSolnHeader} after all}
%    \begin{macrocode}
  \ifeq@solutionsafter
    \eq@nolinktrue  % no link to solution
  \else\ifeq@nosolutions
    \eq@nolinktrue  % no link to solution
  \else
      \eq@ckglobalhide
      \ifeq@hidesolution\eq@nolinktrue\else
%    \end{macrocode}
% Write the solution header to \texttt{.sol} for tabular type question.
%    \begin{macrocode}
      \gdef\eqExerSolnHeader{\eq@@writeexheaderlist}%
  \fi\fi\fi
  \if@restorejustify\restorejustify\else\PBS\raggedright\fi
  \settowidth{\eq@tmplength}{\parts@indent\eqe@prtsepPrb}%
  \xdef\prtsIndntSep{\the\eq@tmplength}%
  \sbox{\eq@tmpbox}{\parts@indent}%
  \eq@tmpdima=\wd\eq@tmpbox
  \addtolength\eq@tmplength{\eq@extralabelsep}%
  \xdef\partshangamount{\the\eq@tmplength}%
  \parshape \@ne 0pt \linewidth
  \everypar{\parshape \@ne 0pt \linewidth}%
  \eq@setPrbSolnAftrIndnt
%    \end{macrocode}
% (2013/04/28) Inserted \texttt{[r]}
%    \begin{macrocode}
  \makebox[0pt][r]{\eqexlisttabheader\eqe@prtsepPrb}%
    \ex@listtabheader@fterhook
    \exlisttabheaderafterhook\ignorespaces}
%    \end{macrocode}
%    \begin{macrocode}
\def\@ckhide[#1]{\edef\eq@arg{#1}%
  \def\currhideopt{x}%
  \ifx\eq@arg\@empty\else
  \if\eq@arg\eq@Hid
      \eq@hidesolutiontrue\eq@nolinktrue%
      \edef\currhideopt{\Hidesymbol}%
  \else
      \ifeq@globalshowsolutions\else
          \if\eq@arg\eq@hid
              \eq@hidesolutiontrue\eq@nolinktrue%
              \def\currhideopt{h}%
          \fi
      \fi
  \fi\fi
  \eq@item}
%    \end{macrocode}
% End of the \texttt{parts} environment.
%    \end{environment}
% In the above tabular parts environment, \cs{@xtabularcr} is \cs{let} to
% equal to \cs{eq@xtabularcr}.
%    \begin{macrocode}
\def\tabControlOn{\@ifundefined{@xtabularcr}
  {\let\save@@xtabularcr\@xarraycr}
  {\let\save@@xtabularcr\@xtabularcr}}
%    \end{macrocode}
%\changes{v7.0}{2014/11/05}{Added \string\cs{tabControlOn} and \string\cs{tabControlOff}.
% Tab control is interfering with regular tabular environments, or anywhere
% \string\texttt{d} is used.}
%    \begin{macrocode}
\def\tabControlOff{\@ifundefined{@xtabularcr}
  {\let\@xarraycr\save@@xtabularcr}
  {\let\@xtabularcr\save@@xtabularcr}}
\AtBeginDocument{\tabControlOn}
\def\eq@xtabularcr{\@ifnextchar[{\save@@xtabularcr}
  {\eqe@tab@parts@rowsep}}%
\def\eqe@tab@parts@rowsep{\save@@xtabularcr
  \noalign{\expandafter\kern\eqparts@tabrowsep}}%
\let\eqgrii\relax
\let\eqgriii\relax
%</package|eqexam>
%<*package>
%    \end{macrocode}
% \subsection{Enumerating exercises}
% Here we provide the \texttt{exEnumerate} environment for enumerating exercises.
% We provide several key-values for adjusting the spacing of the environment.
% The keys defined here are \texttt{labelwidthTo}, \texttt{labelwidth}, \texttt{topsep},
% \texttt{parsep},\texttt{itemsep}, \texttt{labelsep}, and \texttt{continue}.%
% \IndexKey{labelwidthTo}\IndexKey{labelwidth}
%    \begin{macrocode}
\define@key{exEnum}{labelwidthTo}[\normalsize\normalfont\bfseries00.\ ]%
    {\def\exE@labelwidthTo{#1}}
\define@key{exEnum}{labelwidth}[\@empty]{\def\exE@labelwidth{#1}}
%    \end{macrocode}
%    Keys continued.\IndexKey{topsep}%
% \IndexKey{parsep}\IndexKey{itemsep}\IndexKey{labelsep}\IndexKey{continue}%
%    \begin{macrocode}
\let\exE@labelwidth\@empty
\define@key{exEnum}{topsep}[3pt]{\def\exE@topsep{#1}}
\define@key{exEnum}{parsep}[3pt]{\def\exE@parsep{#1}}
\define@key{exEnum}{itemsep}[0pt]{\def\exE@itemsep{#1}}
\define@key{exEnum}{labelsep}[\normalsize\normalfont\ ]%
    {\settowidth{\@tempdima}{#1}\edef\exE@labelsep{\the\@tempdima}}
\define@key{exEnum}{continue}[]{\let\eq@ExEnumResetCnt\@empty}
\def\eq@ExEnumResetCnt{\setcounter{questionno}{0}}
\setkeys{exEnum}{labelwidthTo,topsep,parsep,itemsep,labelsep}%
%    \end{macrocode}
%    \begin{environment}{exEnumerate}
% The environment for enumerating exercises. The companion definitions for
% these exercises follow. The argument is expanded first before being passed
% to \cs{setkeys}; therefore you can pass a command of key-value options through
% the optional argument:
% |\def\myOpts{topsep=0pt}|, |\begin{exEnumerate}[\myOpts]|.
% \changes{v8.2.6}{2018/12/03}{Inserted \string\cs{eqprior} prior to \string\env{exEnumerate} env}
% The \cs{eqprior} command normally does nothing unless it is redefined.
%    \begin{macrocode}
\newenvironment{exEnumerate}[1][]{\everypar{}%
    \toks@=\expandafter{#1}%
    \edef\tempexp{\noexpand\setkeys{exEnum}{\the\toks@}}\tempexp
    \eq@ExEnumResetCnt
    \let\afterlabelhskip\@empty
    \let\solnhspace\@empty
    \aboveexskip{0pt}\belowexskip{\exE@parsep}%\belowexskip{0pt}%
    \def\eqexheader@wrapper{\makebox[0pt][r]{%
        \hypertarget{qex.\the@exno}{\eqexheader}\hspace{\labelsep}}}%
%    \end{macrocode}
% The next two definitions are to correctly format bookmarks for these exercises.
%    \begin{macrocode}
    \def\exbookmarkfmt{\thequestionno.\space}
    \def\partbookmarkfmt{(\thepartno)\space}
%    \end{macrocode}
%    The definition of \cmd{\setEnum} supports the \texttt{contsolns} option.
%    \begin{macrocode}
    \def\setENum{\Elabel\if\exerstar*\thequestionno(\thepartno)\else
        \thequestionno\fi}%
    \ifExSolutionsSet\else\writeT@ExSolns{^^J\string\eqgrii
      \protect\begin{exEnumerate}\eq@commentchar^^J}\fi
    \list{}{%
        \ifx\exE@labelwidth\@empty
        \settowidth{\labelwidth}{\exE@labelwidthTo}\else
        \setlength{\labelwidth}{\exE@labelwidth}\fi
        \setlength{\topsep}{\exE@topsep}%
        \ifdim\parskip>\z@\addtolength{\topsep}{-\parskip}\fi
        \setlength{\parsep}{\exE@parsep}%
        \setlength{\itemsep}{\exE@itemsep}%
        \setlength{\itemindent}{0pt}%
        \setlength{\listparindent}{0pt}%
        \setlength{\itemindent}{0pt}%
        \settowidth{\labelsep}{\normalfont\ }%
        \setlength{\leftmargin}{\labelwidth}%
    }\item\relax}{\ifExSolutionsSet\else
        \writeT@ExSolns{\string\eqgrii
          \protect\end{exEnumerate}\eq@commentchar^^J}\fi
\endlist}
%    \end{macrocode}
%    \end{environment}
%    \begin{environment}{enumex}
%    \begin{environment}{enumex*}
% Prototype environments for enumerating exercises. These can be redefined as desired.
%    \begin{macrocode}
\newenvironment{enumex}{%
    \renewcommand\exlabelformat{\textbf{\thequestionno.}}%
    \renewcommand\exsllabelformat
        {\protect\makebox[0pt][r]{\protect\textbf{\thequestionno.\ }}}%
\begin{exercise}[questionno]}{\end{exercise}}
\newenvironment{enumex*}{%
    \renewcommand\exlabelformatwp{\textbf{\thequestionno.}}%
    \renewcommand\exsllabelformatwp
        {\protect\makebox[0pt][r]{\protect\textbf{\thequestionno.}\ }%
            \protect\textbf{(\thepartno)}\ }%
\begin{exercise*}[questionno]}{\end{exercise*}}
%    \end{macrocode}
%    \end{environment}
%    \end{environment}
%    \begin{macrocode}
% End of enumeration exercises section
%</package>
%<*package|eqexam>
%    \end{macrocode}
%    \subsection{Including the \texttt{exercise} Solutions}
% Include solutions to the exercises back into the file.  This
% section also handles solutions to quizzes as well. This macro
% was taken from the \TeX book.
%    \begin{macro}{\includeexersolutions}
% This macro inserts the solutions to the exercises, if there are
% any solutions.  If a user uses this macro to insert the solutions
% elsewhere, \cmd{\include@solutions} is called, then put is to
% \cmd{\relax}.
%    \begin{macrocode}
\def\includeexersolutions{\@ifstar
  {\let\resetEXsolns\relax\includeexersolutionsi}
  {\def\resetEXsolns{\global\let\include@solutions\relax}%
   \includeexersolutionsi}}
\newcommand{\includeexersolutionsi}[1][]{%
  \filterFor{#1}\includeexersolutionsii}
\def\includeexersolutionsii{%
%</package|eqexam>
%<*package>
  \if\exerSolns@ExtFile\eq@NO
%</package>
%<*package|eqexam>
%    \end{macrocode}
% \cmd{\include@solutions} is the internal command that insert solutions.  This command
% appears at the end of document, where it will insert the
% solutions, unless it has been redefined to \cmd{\relax} by
% \cmd{\includesolutions}.
%    \begin{macrocode}
    \include@solutions
    \resetEXsolns
    \let\eqFilterArg\@empty
%</package|eqexam>
%<*package>
  \fi
%</package>
%<*package|eqexam>
}
%    \end{macrocode}
%
%\subsection{Filtering solutions to exercises}
%
% The \cs{eqEXt} command has two arguments designed to be used to filter
% solutions to exercises. The demo document is \texttt{filter\_exercises.tex},
% but basically, we can include the solutions several times, once for each set filtered set.
%    \begin{macrocode}
\long\def\gobbleToEndEXt#1\endeqEXt{\ifeqforpaper
  \expandafter\@gobbletwo\fi}
%    \end{macrocode}
% \DescribeMacro\filterFor is used to mark a exercise with a name
%    \begin{macrocode}
\newif\if@targetforextr \@targetforextrfalse
\newcommand\filterFor[1]{\def\eqFilterArg{#1}}
\newcommand{\mrkForIns}[1]{\def\eqMrkCpyArg{#1}\global
  \@targetforextrtrue\@ifundefined{#1@mfc}
    {\global\@namedef{#1@mfc}{}}
    {\PackageWarning{exerquiz/eqexam}
    {The name '#1' has already been used.\MessageBreak
      Please choose another, otherwise results may\MessageBreak
      be as unexpected}}\ignorespaces}
\let\eqMrkCpyArg\@empty
\newcommand\inclEXtFilter[2]{\def\eqargii{#2}\ifx\eqargii\eqFilterArg
    \else\expandafter\gobbleToEndEXt\fi}
%    \end{macrocode}
%    \end{macro}
% \DescribeMacro\useEXtFilter is used to \cs{let} \cs{eqEXt} to \cs{EXtFilter}, which does the
% filtering based on the value of \cs{eqFilterArg}.
%    \begin{macrocode}
\newcommand\useEXtFilter{\let\eqEXt\inclEXtFilter}
%    \end{macrocode}
% The basic methodology is as follows: We use \cs{filterFor} to mark an exercise, or block
% of exercises by a name, for example, \verb!\filterFor{Problems}!. Now, at the end of the document, we can
% say
%\begin{verbatim}
%   \useEXtFilter
%   \renewcommand\exsectitle{Solutions to Exercises}
%   \includeexersolutions*[Exercises]
%   \renewcommand\exsectitle{Solutions to Examples}
%   \includeexersolutions*[Examples]
%   \renewcommand\exsectitle{Solutions to Problems}
%   \includeexersolutions[Problems]
%\end{verbatim}
% \DescribeMacro{\eqsolutionshook}\DescribeMacro{\priorexsectitle}
% \DescribeMacro{\priorexslinput} These are commands that can be
% redefined by the user, their location can be found below.
%    \begin{macrocode}
\let\eqsolutionshook\@empty
\let\eq@solutionshook\@empty
\let\priorexsectitle\@empty
\let\priorexslinput\@empty
%    \end{macrocode}
% \DescribeMacro{\InputExrSolnsLevel}\nmpsep{*[\ameta{name}]\darg{\ameta{level}}} The solutions to the exercises
% are in their own section, historically this has been \cs{section*}; however for some documents, it is
% desirable to have a numbered section number \cs{section} or \cs{chapter}, or \cs{chapter*}. The
% \cs{InputExrSolnsLevel} is designed to ease the task of changing how section-type. \ameta{level} is usually
% \texttt{section} or \texttt{chapter}; use \texttt* if you want solutions to be in \cs{section*} or \cs{chapter*};
% if the \ameta{name} is used, the beginning of the solutions is marked with \cs{label\darg{name}}.
% \changes{v8.5.5}{2019/12/17}{Added \string\cs{InputQzSolnsLevel}}
%    \begin{macrocode}
\def\InputExrSolnsLevel{\@ifstar
  {\def\eq@ExrSolnsStar{*}\InputExrSolnsLevel@i}
  {\let\eq@ExrSolnsStar\@empty\InputExrSolnsLevel@i}}
\newcommand{\InputExrSolnsLevel@i}[2][]{%
  \def\eq@ExrSolnsLabel{#1}\def\eq@ExrSolnsLevel{#2}}
\InputExrSolnsLevel*{section}
%    \end{macrocode}
%\DescribeMacro{\exerSolnsHeadnToc} sets the section title for the solutions
% to the exercises. May be redefined, I suppose.
%    \begin{macrocode}
\def\exerSolnsHeadnToc{%
  \edef\eq@mkCmd{\expandafter\noexpand
    \csname\eq@ExrSolnsLevel\endcsname\eq@ExrSolnsStar}%
  \eq@mkCmd{\exsectitle}\if!\eq@ExrSolnsLabel!\else
  \label{\eq@ExrSolnsLabel}\fi
  \if\eq@ExrSolnsStar*%
%   \addtocontents{toc}{\protect\def\protect\web@finalDot{}}
    \addcontentsline{toc}{\eq@ExrSolnsLevel}{%
      \@ifundefined{web@latextoc}{}{%
        \ifx\web@latextoc\eq@YES\else
          \protect\numberline{}\fi
      }\exsectitle
    }%
  \fi
}
%    \end{macrocode}
%\changes{v6.4q}{2012/03/23}{define \string\cs{eq@defaultlheader}}
% Determine whether \textsf{web} package is loaded, and define \cs{eq@normallheader}
% and \cs{eq@defaultlheader}. These are designed to fix a problem of disappearing
% headers in the solutions section of the document.
%    \begin{macrocode}
\@ifpackageloaded{web}{\def\eq@normallheader{\lheader{\rightmark}}}
    {\let\eq@normallheader\relax}
\@ifpackageloaded{web}{\def\eq@defaultlheader{\lheader{\aeb@setmarks}}}
    {\let\eq@defaultlheader\relax}
%    \end{macrocode}
% \DescribeMacro{\exerSolnInput} is the macro that formats the opening page
% of the solutions page and inputs \cmd{\jobname.sol}. \DescribeMacro\eqExSolFileName
% \cs{eqExSolFileName} is defined in support of the \texttt{solutionsonly} option and the \pkg{ci-solns} package.
% \changes{v8.2.8}{2018/12/13}{Defined \string\cs{eqExSolFileName}}
%    \begin{macrocode}
\newif\ifExSolutionsSet \ExSolutionsSetfalse
\def\eqExSolFileName{\jobname.sol}
\newcommand{\exerSolnInput}
{%
  \@ifundefined{eqe@IWO}{}{\ifsolutionsAtEnd
    \eqe@IWO\@auxout{\string\csarg\string\gdef
    {eqExamQuesLastPage}{\arabic{page}}}\fi}\let\webnewpage\relax
  \ifsolutionsonly\else
%    \end{macrocode}
%   \changes{v8.2.6}{2018/12/03}{place \string\cs{endinput} at end of sol file}
%   place \cs{endinput} at end of sol file
%    \begin{macrocode}
    \bgroup\OKToWriteExamDatatrue
    \writeT@ExSolns{\string\endinput}\egroup
    \immediate\closeout\ex@solns\fi
  \ifeq@nosolutions\else
    \iftherearesolutions
      \ifsolutionsonly\eq@solutionshook
        \eqsolutionshook
      \else
%    \end{macrocode}
% If there are solutions and this is not the \texttt{solutionsonly} option,
% we start a new page, clear the right mark and start a normal header.
% \changes{v6.4q}{2012/03/23}{Inserted \string\cs{eq@normalheader} after \string\cs{newpage}
% to get running headers to appear on each page of solutions}%
% Inserted |\markright{}| and \cs{eq@normalheader} to fix a problem with
% disappearing running headers.
%    \begin{macrocode}
        \newpage\eq@solutionshook
        \eqsolutionshook\markright{}\eq@normallheader
      \fi
%    \end{macrocode}
% We are still under the assumption that there are solutions to be input.
% We set the mark of \cs{exsectitle}.
%    \begin{macrocode}
      \markright{\exsectitle}%
      \ifx\webnewpage\relax
%    \end{macrocode}
% \cs{webnewpage} is a mechanism to initially do nothing, then
% to be redefined to \cs{newpage}. It is used in \cs{exerSolnHeader}.
% The reasons for this definition are lost in time.
%    \begin{macrocode}
        \def\webnewpage{\global\let\webnewpage\newpage}\fi
%    \end{macrocode}
% We have a prior command, followed by the section title
% \cs{exerSolnsHeadnToc}, followed by a post command. The prior and
% post commands may be defined as the document author wishes.
% Both of these are used in the \textsf{APB} pacakge.
%    \begin{macrocode}
      \priorexsectitle\exerSolnsHeadnToc\priorexslinput
%    \end{macrocode}
% Finally, we input the solutions file, \cs{jobname.sol}, if one exists.
%    \begin{macrocode}
      \InputIfFileExists{\eqExSolFileName}
      {\global\ExSolutionsSettrue}{\PackageWarning{exerquiz}
      {!!! Solutions to exercises not found}}%
      \global\ExSolutionsSetfalse
%    \end{macrocode}
% Convert back to \cs{eq@defaultlheader} cleanly by first executing \cs{newpage}
%    \begin{macrocode}
      \newpage\eq@defaultlheader
    \fi
  \fi
}
%    \end{macrocode}
% The \cs{include@solutions} is a wrapper command for \cs{exerSolnInput}
%    \begin{macrocode}
\def\include@solutions{%
%</package|eqexam>
%<*package>
    \if\exerSolns@ExtFile\eq@NO
%</package>
%<*package|eqexam>
        \exerSolnInput
%</package|eqexam>
%<*package>
    \fi
%</package>
%<*package|eqexam>
}
%</package|eqexam>
%<*package>
%    \end{macrocode}
% \subsection{Bookmarking Exercises}
%
% Someone asked how to bookmark the exercises, it was an interesting
% little exercise for a Saturday morning. So, here it is.
% \par\medskip\noindent
% \cs{eqexpdfentry} marks first entry into an exercise.
%    \begin{macrocode}
\let\eqexpdfentry=0
%    \end{macrocode}
% \cs{eq@postexerciseHook}: Restores the \cs{Hy@currentbookmarklevel} bookmark level to what it was when
% we first entered the exercise. This is executed at the end of the exercise
% environment.
%    \begin{macrocode}
\let\eq@postexerciseHook\relax
\def\eq@postexerciseHook@BM{%
    \xdef\Hy@currentbookmarklevel{\eq@currentbookmarklevel}}
%    \end{macrocode}
%    \begin{macro}{\exbookmarkfmt}
%    \begin{macro}{\partbookmarkfmt}
%    \begin{macro}{\expdfbookmark}
% ``Intelligent'' bookmarking for \textsf{Exerquiz} exercises. Detects the correct bookmark level
% determines if this is a part of an exercise, or the entry into an exercise and
% automatically sets a unique destination.
%
% \cs{expdfbookmark} is the main interface to bookmarking an exercise. The single argument
% is the text that is to appear in the bookmark panel. \cs{exbookmarkfmt} and
% \cs{partbookmarkfmt} formats the exercise number and part letter. These can be redefined.
%
%\changes{v6.2a}{2007/11/10 }
%{
%   Added \string\cs{expdfbookmark} to bookmark exercises.
%}
% We have to increase the \texttt{tocdepth} so hyperref will create the bookmark at the
% subsection level.
%    \begin{macrocode}
{\eqtmpcnta\value{tocdepth}
\advance\eqtmpcnta\tw@ \xdef\eqbmkmrkdepth{\the\eqtmpcnta}}
\@ifundefined{Hy@bookmarksdepth}
    {\setcounter{tocdepth}{\eqbmkmrkdepth}}
    {\hypersetup{bookmarksdepth=\eqbmkmrkdepth}}
\newcommand{\exbookmarkfmt}{\exlabel\space\theeqexno.\space}
\newcommand{\partbookmarkfmt}{(\thepartno)\space}
\newcommand{\expdfbookmark}[1]{\relax
     \def\expdfbookmarktitle{#1}%
%    \end{macrocode}
% The default definition of \cs{eq@postexerciseHook} is \cs{relax}. We'll
% check if someone is using \cs{eq@postexerciseHook}.
%    \begin{macrocode}
    \ifx\eq@postexerciseHook\relax
        \let\eq@postexerciseHook\eq@postexerciseHook@BM
    \else
%    \end{macrocode}
% Yes, \cs{eq@postexerciseHook} is in use, we'll add our stuff onto the end of it.
%    \begin{macrocode}
        \let\eq@postexerciseHook@save\eq@postexerciseHook
        \def\eq@postexerciseHook@BM@plus{\eq@postexerciseHook@save
            \eq@postexerciseHook@BM}%
        \let\eq@postexerciseHook\eq@postexerciseHook@BM@plus
    \fi
    \if\exerstar*%
%    \end{macrocode}
% If entering an exercise with parts for the first time, we also capture current bookmark level,
% and mark, using \cs{eqexpdfentry} that we have entered an exercises with parts.
%    \begin{macrocode}
        \if\eqexpdfentry0\let\eqexpdfentry=1
            \xdef\eq@currentbookmarklevel{\Hy@currentbookmarklevel}%
            \def\eqex@next{\subpdfbookmark{\exbookmarkfmt#1}%
                {qex.\the@exno}}%
        \else
%    \end{macrocode}
% Already in an exercise with parts, no need to reduce bookmark level again
%    \begin{macrocode}
            \def\eqex@next{\belowpdfbookmark{\partbookmarkfmt#1}%
                {qex.\the@exno.\thepartno}}%
        \fi
    \else
%    \end{macrocode}
% A regular exercise, no parts, we also capture current bookmark level
%    \begin{macrocode}
        \xdef\eq@currentbookmarklevel{\Hy@currentbookmarklevel}%
        \def\eqex@next{\subpdfbookmark{\exbookmarkfmt#1}%
            {qex.\the@exno}}%
    \fi
    \eqex@next\ignorespaces}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%
%    \section{Early end of input}
%
% There is no support for the Acrobat Forms features with the
% \texttt{dviwindo} option by \textsf{hyperref}; therefore there is
% none here as well.  \textsf{dviwindo} can use the
% \texttt{exercise} environment, but not the quizzes, so end here.
%    \begin{macrocode}
\ifeq@noforms\endinput\fi
%    \end{macrocode}
% \section{Common code for quizzes.}
% Here, we include a few commands common to both
% quiz environments.
%\medskip\par\noindent
% Colors used by \pkg{exerquiz}: \texttt{webgreen} normally defined in \pkg{web}.
%    \begin{macrocode}
\definecolor{webgreen}{rgb}{0,.6,0}
%    \end{macrocode}
%    \begin{macro}{\proofingsymbol}
%    \begin{macro}{\proofingsymbolColor}
% Proofing symbol and accompanying color (little green bullet)
% \changes{v6.05b}{2006/05/12}
% {
% added a command to change the color of the proofing symbol
% changed the definition of \string\cs{proofingsymbol} to a text fillin. This creates the command
% \string\cs{@proofingsymbol}. Can now control the symbol and the color (through \string\cs{proofingsymbolColor}
% }
%    \begin{macrocode}
\newcommand{\proofingsymbolColor}[1]{\def\@proofingsymbolColor{#1}}
\proofingsymbolColor{red}
\let\@proofsymbolredefined\eq@Zero
\newcommand{\proofingsymbol}[1]{\let\@proofsymbolredefined\eq@One
  \def\@proofingsymbol{\textcolor{\@proofingsymbolColor}{#1}}}
\def\@proofingsymbol{\textcolor{\@proofingsymbolColor}{\ding{52}}}
\def\setproofingsymbol{\ifx\@proofsymbolredefined\eq@One\else
  \@ifpackageloaded{pifont}{\proofingsymbol{\ding{52}}}
  {\proofingsymbol{$\bullet$}}\fi
}
\AtBeginDocument{\setproofingsymbol}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{macrocode}
%</package>
%<*package|eqexam>
%    \end{macrocode}
%
%    \subsection{The \texttt{questions} Environment}
% The \texttt{questions} environment is used inside the
% \texttt{shortquiz} and \texttt{quiz} environments, though it can
% also be used a stand alone list. Beginning with version 5.5, the \texttt{questions}
% environment can be nested three deep.
%    \begin{macro}{questions}
%    This is a redesigned \texttt{list} environment.
%    \begin{macrocode}
\newcommand{\prior@questionsHook}{}
\let\insE@rlyAtQues\@empty
\let\qMark@Hook\@empty
\let\aebtitleQuiz\@empty
\newcommand{\post@questionsHook}{}
\newcommand{\quesNumColor}[1]{\def\eq@quesNumCol{#1}}
\quesNumColor{blue}
\renewcommand{\theeqquestionnoi}{\arabic{eqquestionnoi}}
\newcommand{\labeleqquestionnoi}{\color{\eq@quesNumCol}\bfseries
  \theeqquestionnoi.}
\renewcommand\theeqquestionnoii{(\alph{eqquestionnoii})}
\newcommand{\labeleqquestionnoii}{\color{\eq@quesNumCol}\bfseries
  \theeqquestionnoii}
\renewcommand\theeqquestionnoiii{(\roman{eqquestionnoiii})}
\newcommand{\labeleqquestionnoiii}{\color{\eq@quesNumCol}\bfseries
  \theeqquestionnoiii}
%    \end{macrocode}
% \paragraph*{Properties of the questions environment.} (2013/07/10) These include
% \IndexKey{labelwidthTo}\texttt{labelwidthTo} and
% \IndexKey{labelwidth}\texttt{labelwidth}.
%    \begin{macrocode}
\define@key{props@ques}{labelwidthTo}%
  [\normalsize\normalfont\bfseries00.]%
  {\def\propQ@labelwidthTo{#1}}
\define@key{props@ques}{labelwidth}[]{\def\propQ@labelwidth{#1}}
\let\propQ@labelwidth\@empty
%    \end{macrocode}
% \leavevmode\IndexKey{topsep}^^A
%   \texttt{topsep}, \IndexKey{partopsep}\texttt{partopsep},
% \IndexKey{parsep}\texttt{parsep}, and \IndexKey{itemsep}\texttt{itemsep}.
%    \begin{macrocode}
\define@key{props@ques}{topsep}[\the\topsep]{\edef\propQ@topsep{#1}}
\define@key{props@ques}{partopsep}[\the\partopsep]%
  {\edef\propQ@partopsep{#1}}
\define@key{props@ques}{parsep}[\the\parsep]{\edef\propQ@parsep{#1}}
\define@key{props@ques}{itemsep}[\the\itemsep]{\edef\propQ@itemsep{#1}}
%    \end{macrocode}
% \leavevmode\IndexKey{labelsepTo}\texttt{labelsepTo} and \IndexKey{labelsep}\texttt{labelsep}
%    \begin{macrocode}
\define@key{props@ques}{labelsepTo}[\normalsize\normalfont\ ]%
  {\def\propQ@labelsepTo{#1}}
\define@key{props@ques}{labelsep}[\@empty]{\def\propQ@labelsep{#1}}
\let\propQ@labelsep\@empty
%    \end{macrocode}
% \leavevmode\IndexKey{color}^^A
%   A color key set the color of the numbers in a question environment.
%    \begin{macrocode}
\define@key{props@ques}{color}[blue]{\quesNumColor{#1}}
%    \end{macrocode}
% The default properties of the \texttt{questions} environment.
%    \begin{macrocode}
\setkeys{props@ques}{labelwidthTo,topsep,partopsep,parsep,%
    itemsep,labelsepTo,color}%
%    \end{macrocode}
% Now we begin the \texttt{questions} environment. There is an optional parameter
% wherein we pass the key-value pairs defined above.
%    \begin{macrocode}
\newenvironment{questions}[1][]{%
%    \end{macrocode}
%    Insert \cs{nopartquestion} to fix problem
%    with \cs{multipartquestion}
%    \changes{v8.8.4}{2021/10/02}{Insert \string\cs{nopartquestion} to fix problem
%    with \string\cs{multipartquestion}}
%    \begin{macrocode}
  \nopartquestion
  \ifnum\@eqquestiondepth>\tw@\@toodeep\else
  \advance\@eqquestiondepth\@ne\fi
  \def\@quesctr{eqquestionno\romannumeral\the\@eqquestiondepth}%
  \toks@=\expandafter\expandafter\expandafter{#1}\expandafter
  \xdef\csname quesOpts\@quesctr\endcsname{\the\toks@}%
  \edef\tempexp{\noexpand\setkeys{props@ques}{\the\toks@}}\tempexp
  \list{\qMark@Hook\prior@questionsHook
  \insE@rlyAtQues\gdef\eqPTs{1}%
  \global\let\eqQT\eq@na%
%    \end{macrocode}
% (06/06/10) We create a macro, \cs{@currentQues}, that holds the current
% problem number; 2(a)(i), for example.
% \changes{v8.6.7}{2021/04/12}{Remove the misplaced \string\cs{endcsname}
% \string\cs{@thispr@b}, within the \string\env{questions} environment.}
%    \begin{macrocode}
  {\@tempcnta\z@\let\@thispr@b\@empty
   \@whilenum\@tempcnta<\@eqquestiondepth\do{\advance\@tempcnta\@ne
   \ifx\@thispr@b\@empty\edef\@thispr@b{\@nameuse
      {theeqquestionno\romannumeral\the\@tempcnta}}\else
   \edef\@thispr@b{\@thispr@b\@nameuse
    {theeqquestionno\romannumeral\the\@tempcnta}}\fi
  }\xdef\@currentQues{\@thispr@b}}%
  \makebox[\labelwidth][r]{\normalfont
    \@nameuse{label\@quesctr}}% format label
  \xdef\eq@pageThisQ{\the\c@page}%
  \post@questionsHook}{\usecounter{\@quesctr}%
%    \end{macrocode}
% We set the list parameter for the \texttt{questions} environment.
%    \begin{macrocode}
    \ifx\propQ@labelsep\@empty
      \settowidth{\labelsep}{\propQ@labelsepTo}\else
      \setlength{\labelsep}{\propQ@labelsep}\fi
    \ifx\propQ@labelwidth\@empty
      \settowidth{\labelwidth}%
        {\propQ@labelwidthTo\hspace{\labelsep}}\else
      \settowidth{\labelwidth}{\hspace{\propQ@labelwidth}%
        \hspace{\labelsep}}\fi
    \setlength{\topsep}{\propQ@topsep}%
    \setlength{\partopsep}{\propQ@partopsep}%
    \ifdim\parskip>\z@\addtolength{\topsep}{-\parskip}\fi
    \setlength{\parsep}{\propQ@parsep}%
    \setlength{\itemsep}{\propQ@itemsep}%
    \setlength{\itemindent}{0pt}%
    \setlength{\leftmargin}{\labelwidth}%
  }%
}{\endlist}
%    \end{macrocode}
%    \begin{macro}{\pushquestions}
%    \begin{macro}{\popquestions}
% Between \cs{item}s within a question environment, you can execute
% \cs{pushquestions}, this save the question counter, you are then free
% to make comments between problem, when finished, executed a \cs{popquestions}
% to return to questioning where you left off.
%    \begin{macrocode}
\def\pushquestions{\expandafter\xdef\csname save\@quesctr\endcsname
  {\expandafter\the\csname c@\@quesctr\endcsname}\end{questions}}
\def\popquestions{%
  \begin{questions}[\csname quesOpts\@quesctr\endcsname]%
  \setcounter{\@quesctr}{\csname save\@quesctr\endcsname}%
  \@ifnextchar\popquestions{\item[]}{\@ifnextchar\begin{\item[]}{}}}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%
%    \section{The \texttt{shortquiz} and \texttt{shortquiz*} Environments}
%
%     \subsection{Preliminaries}
%     Beginning with 2021/05/15 v8.7, we introduce several changes that affect
%     both \env{shortquiz} and \env{quiz} environments. These definitions are
%     placed here.
%     \changes{v8.7}{2021/05/15}{Enhanced control over placement of \string\cs{eq@answersEndHook}}
%
%     These definitions support the added control over the \ameta{content} placed by the
%     command \cs{answersEndHook\darg{\ameta{content}}}. The \ameta{content} argument is
%     usally a combination of \cs{sqTallyBox} and \cs{sqSolnBtn} commands, but can be anything.
%
%     Another aspect of the change is the \cs{setAnsEnvLinewidth}. Through this command, the
%     value of \cs{linewidth} can be changed within the \env{answers} and \env{manswers} environmnts.
%    \begin{macro}{\setAnsEnvLinewidth}\hskip-\marginparsep\,\texttt{\darg{\ameta{length}}} Sets the
%    \cs{linewidth} of the \env{answers} and \env{manswers} for both the \env{list} and \env{tabular} modes.
%    It it not shown here, but within each of these envioronments, before the change is made
%    the ``natural'' \cs{linewidth} is saved as \DescribeMacro\natlinewidth\cs{natlinewidth},
%    this value is available only locally, within the environments.
%
%    All changes corresponding to enhanced control over placement of \ameta{content} are marked in the source
%    by \texttt{dps21-5-15}, \texttt{dps21-5-16}, and \texttt{dps21-5-17}.
%    \begin{macrocode}
\def\setAnsEnvLinewidth#1{\def\@nsLineWidth{#1}} % dps21-5-17
\let\@nsLineWidth\@empty % dps21-5-17
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\answersEndHook}\hskip-\marginparsep\,\texttt{\darg{\ameta{content}}}
%    Internally, defines the text macro \cs{eq@answersEndHook} to expand to \ameta{content}.
%    The command also defines text macro \cs{insertAnsEndHookHere} to expand to \ameta{content}.
%    \cs{eq@answsersEndHook} is used when placing \ameta{content} in the default location;
%    while \cs{insertAnsEndHookHere} is used to place \ameta{content} at the location specified
%    by the value of the \texttt{insertAt} key of the \cs{bChoices} command.
%    \begin{macrocode}
\newcommand\answersEndHook[1]{\def\eq@answersEndHook{#1}%
  \ifx\eq@answersEndHook\@empty\else
    \def\insertAnsEndHookHere{#1}%
  \fi
} % dps21-5-15
\let\eq@answersEndHook\@empty
\let\insertAnsEndHookHere\@empty % dps21-5-15
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
%    \end{macrocode}
%    At the end of each of the targeted envionments, we insert \ameta{content},
%    provided a value for \texttt{insertAt} has not been specified; otherwise, we
%    do nothing as \ameta{content} has been inserted according to the value
%    of \texttt{insertAt}.
%    \begin{macrocode}
\def\@insertAndHookAtEndEnv{% dps21-5-16
  \ifx\insertAnsHookAt\@empty
      \eq@answersEndHook
  \else % dps21-5-16
    \ifnum\insertAnsHookAt>\aeb@RowCnt
      \eq@answersEndHook
      \PackageWarning{exerquiz}{insertAt=\insertAnsHookAt:
      The value (\insertAnsHookAt) of insertAt is greater\MessageBreak
      than the number of rows (\aeb@RowCnt).
      Using the default\MessageBreak
      positioning instead}
    \else
%    \end{macrocode}
%    Reset the value of \cs{insertAnsHookAt} to its default value. The document
%    author must specify \texttt{insertAt} for each \cs{eChoices} where a nondefault
%    placement is wanted.
%    \begin{macrocode}
      \global\let\insertAnsHookAt\@empty
    \fi
  \fi
}
%    \end{macrocode}
%    \cs{@insertAnsHookAt} is inserted at the end of \cs{Ans}/\cs{eAns} pair;
%    the \ameta{content} is placed just after the text of this item.
%    \begin{macrocode}
\def\@insertAnsHookAt{% dps21-5-16
  \let\eqe@next\relax
  \ifx\insertAnsHookAt\@empty\else
    \ifnum\insertAnsHookAt=\aeb@RowCnt
      \def\eqe@next{\insertAnsEndHookHere}\fi
  \fi\eqe@next
}
%    \end{macrocode}
%    Repetitive code to increment the \cs{aeb@RowCnt} macro.
%    \begin{macrocode}
\def\@incRowCnt{{\@tempcnta\aeb@RowCnt\advance\@tempcnta\@ne
  \xdef\aeb@RowCnt{\the\@tempcnta}}% dps21-5-16
}
%    \end{macrocode}
%
%     \subsection{The \texttt{shortquiz} environment}
%
% This \texttt{shortquiz} environment sets up multiple choice
% questions, with immediate feedback whether the user clicked on the
% right or wrong answer.  Solutions to the \texttt{shortquiz} may,
% or may not be included.
%    \begin{environment}{shortquiz}
% The \texttt{shortquiz} environment, really just a shell to define the
% \cmd{\Ans} macro and the \texttt{solution} environment that go with
% the \texttt{shortquiz}
%\par\medskip\noindent
% After all the parsing is done, the parameters for this environment are
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
%commandchars={!()},codes={\catcode`\%=9}]
%\begin{shortquiz}*[!ameta(basename)]
%\end{Verbatim}
%The `\texttt{*}' is optional and signals that forms should be used instead
%of links. This option is regressed. The user should use the \texttt{shortquiz*}
% environment. The \verb![<basename>]! is the basename of any form fields
% generated. If not present, an base fieldname is generated based on the
% \cs{@shortquizCnt} macro (not a counter). The actual name is given in \cs{@sqGenBaseName}.
%\par\medskip\noindent
% \DescribeMacro{\priorsqhook}\cmd{\priorsqhook} and \DescribeMacro{\abovesqskip}\cmd{\abovesqskip}
% are early hooks and skips.
%    \begin{macrocode}
\newcommand{\priorsqhook}[1]{\def\sq@priorhook{#1}}
\priorsqhook{}
\newcommand{\abovesqskip}[1]{\def\sq@aboveskip{#1}}
\abovesqskip{\par\medskip}
%    \end{macrocode}
%\changes{v6.4a}{2011/05/11}{%
% Added \string\cs{sq@afterhook} for use by \string\pkg{eqexam}, but may be useful elsewhere.
%}
%\DescribeMacro\endsqhook\cmd\endsqhook is a late hook
%    \begin{macrocode}
\long\def\endsqhook#1{\def\sq@afterhook{#1}}
\endsqhook{}
\def\@shortquizCnt{0}
\def\@sqGenBaseName{eqSqBn\@shortquizCnt}
%    \end{macrocode}
%\DescribeMacro\sqhspace\cmd\sqhspace\ is the space that follows \cmd\sqlabel
%    \begin{macrocode}
\let\sqhspace\space
\let\ListOfSQuizNames\@empty
\newenvironment{shortquiz}{\def\eqPTs{1}%
%    \end{macrocode}
% (06/08/10) The next two lines initialize the macros for registering the
% question label, i.e., \texttt{2(a)(ii)}. These two lines are repeated for
% the \texttt{oQuestion} and \texttt{quiz} environments.
%    \begin{macrocode}
  \xdef\eq@pageThisQ{\the\c@page}%
  \let\@currentQues\@empty
  {\eqtmpcnta\@shortquizCnt\relax\advance\eqtmpcnta\@ne
    \xdef\@shortquizCnt{\the\eqtmpcnta}}%
  \goodbreak\@ifstar{\sqForms\@shortquiz}%
    {\if\aeb@FLOverride\eq@f\def\sqstar{*}\else
     \def\sqstar{}\sqLinks\fi\@shortquiz}%
}{\aeb@endshortquiz}
%    \end{macrocode}
%    \end{environment}
%    \begin{environment}{shortquiz*}
% The \texttt{shortquiz*} is a short quiz that uses forms.
%\par\medskip\noindent
% The parameter for this environment is
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
%commandchars={!()},codes={\catcode`\%=9}]
%\begin{shortquiz}[!ameta(basename)]
%\end{Verbatim}
% The \texttt{[\ameta{basename}]} is the basename of any form fields
% generated. If not present, an base fieldname is generated based on the
% \cs{@shortquizCnt} macro (not a counter). The actual name is given in \cs{@sqGenBaseName}.
%    \begin{macrocode}
\newenvironment{shortquiz*}{%
  \xdef\eq@pageThisQ{\the\c@page}%
  {\eqtmpcnta\@shortquizCnt\relax\advance\eqtmpcnta\@ne
    \xdef\@shortquizCnt{\the\eqtmpcnta}}%
  \sqForms\@shortquiz
}{\aeb@endshortquiz}
%    \end{macrocode}
% Determines if the next argument is optional, if yes, we pass to
% \cs{@@shortquiz}, else, we supply a automated form name, then
% continue to \cs{@@shortquiz}.
%    \begin{macrocode}
\def\@shortquiz{\@ifnextchar[%
  {\@@shortquiz}{\@@shortquiz[\@sqGenBaseName]}}
%    \end{macrocode}
%    \end{environment}
% \cs{@@shortquiz} continues the parsing of \texttt{shortquiz} and \texttt{shortquiz*}.
% Here we take in the basename for any fields generated. The basename is passed
% as a delimited parameter \texttt{\#1}.
%    \begin{macrocode}
\def\sq@setCLN#1{\ifx\aebTitleQuiz\@empty
  \protected@edef\@currentlabelname{#1}\else
  \protected@edef\@currentlabelname{\@currentlabelname}\fi
}
%    \end{macrocode}
% (2013/09/29) Added \cs{isQZ} and \cs{isSQZ}
%    \begin{macrocode}
\let\isQZ=q \let\isSQZ=s
%</package|eqexam>
%<*package>
%    \end{macrocode}
% The hidden ID field for a short-quiz
%    \begin{macrocode}
\def\sq@IDTxtField{\makebox[0pt][l]{%
  \textField[\autoCenter{n}\BC{}\BG{}
    \S{S}\textSize{0}\Ff{\FfReadOnly}
    \AA{\AAFormat{%
      if\eqSP(typeof\eqSP\oField=="undefined")\eqSP
        var\eqSP\oField=new\eqSP Object;\r
      \oField.sqTlyTotCnt=0;\r
      \oField.Grp={};%
      \ifx\defaultColorJSLoc\@empty\else\r
      \oField.DefaultColorJSLoc=\defaultColorJSLoc;\fi
      \ifx\rghtColorJSLoc\@empty\else\r
      \oField.RightColorJSLoc=\rghtColorJSLoc;\fi
      \ifx\wrngColorJSLoc\@empty\else\r
      \oField.WrongColorJSLoc=\wrngColorJSLoc;\fi
      \ifx\rghtAnsSymbJSLoc\@empty\else\r
      \oField.RightAnsSymbJSLoc=\rghtAnsSymbJSLoc;\fi
      \ifx\wrngAnsSymbJSLoc\@empty\else\r
      \oField.WrongAnsSymbJSLoc=\wrngAnsSymbJSLoc;\fi
  }}]{sqID\oField}{2bp}{2bp}}%
}
%    \end{macrocode}
%    The \uif{Format} code for the hidden quiz ID text field.
%\changes{v8.6}{2020/11/29}{\string\cs{qz@IDTxtField}: Format code now in \string\env{defineJS}}
%    \begin{macrocode}
\begin{defineJS}[\makeesc\!\makecmt\%]{\qzIDFmt}
if(typeof aQuizzesInDoc=="undefined")
  var aQuizzesInDoc=new Array();
if (aQuizzesInDoc.indexOf("!oField"))
  aQuizzesInDoc.push("!oField");
%    \end{macrocode}
% (2019/06/22) Added in declaration of quiz object.
%\changes{v8.2.12}{2019/06/22}{Added declaration of quiz object}
%    \begin{macrocode}
if (typeof !oField=="undefined")
  var !oField=new Object;
\end{defineJS}
%    \end{macrocode}
%    The hidden text field for quizzes. The role of this field is to initialize things
%    for the associated quiz. This field has \uif{Format} code (\cs{qzIDFmt}), and the \app{Reader} will
%    execute this code when the page is opened. The code creates a new array \texttt{aQuizzesInDoc}, if needed,
%    and adds this quiz to the list of quizzes in the doc. Refer to \cs{qzIDFmt} above.
%    \changes{v8.8.2}{2021/05/29}{Check for dupl short-quiz names}
%    \begin{macrocode}
\def\qz@IDTxtField{\makebox[0pt][l]{\textField[\autoCenter{n}\BC{}\BG{}
  \S{S}\textSize{0}\Ff{\FfReadOnly}
  \AA{\AAFormat{\qzIDFmt}}]{qzID\oField}{2bp}{2bp}}}
%</package>
%<*package|eqexam>
\let\eqQuizType\relax
\def\@@shortquiz[#1]{\csarg % dps5-29
  \ifx{SQName-#1}\relax
    \csarg\gdef{SQName-#1}{1}\else
    \PackageWarning{exerquiz}{%
      The short-quiz name '#1' is already used,\MessageBreak
      please choose a quiz name unique throughout\MessageBreak
      this document}\csarg\gdef{SQName-#1}{0}%
  \fi
  \gdef\oField{#1}\gdef\curr@quiz{#1}\gdef\currQuiz{#1}%
  \edef\tmp@Exp{\noexpand\g@addto@macro\noexpand
    \ListOfSQuizNames{,#1}}\tmp@Exp
%    \end{macrocode}
% We try to support {\LaTeX}'s cross-referencing system by defining
% \cs{@currentlabel}, \cs{@currentHlabel}, and \cs{@currentlabelname}.
%    \begin{macrocode}
    \global\let\eqQzQuesList\@empty
    \let\eq@AddProbToQzQuesList\relax
    \edef\@currentlabel{\@shortquizCnt}%
    \edef\@currentHref{shortquiz.\@shortquizCnt}%
  \global\let\eqQuizType\isSQZ\let\@qzsolndest\@empty
  \if\sqstar*\relax
    \let\@Ans\Ans@sq@f
    \ifx\oField\@empty
        \typeout{^^JExerquiz: Base field name required when using
            shortquiz with '*' option}%
        \PackageInfo{exerquiz}{Assuming link style^^J}%
        \let\@Ans\Ans@sq@l
    \fi
  \else
     \let\@Ans\Ans@sq@l
  \fi
  \setcounter{questionno}{0}%
  \let\answers\answers@sq
  \let\endanswers\endanswers@sq
  \let\manswers\manswers@sq
  \let\endmanswers\endmanswers@sq
  \let\solution\solution@sq
  \let\endsolution\endsolution@sq
%    \end{macrocode}
% Lay down the question header. \cs{sqlabel} defaults to a red ``Quiz''.
%    \begin{macrocode}
%</package|eqexam>
%    \end{macrocode}
% The next segment is for \textsf{exerquiz} only, and not for eqexam.
%    \begin{macrocode}
%<*package>
  \let\ifstaroption\eq@ifstaroption
  \if\eq@tq@star*%
%    \end{macrocode}
% The next code lines supports the \cs{titleQuiz*} option.
% If its the star option, we define \cs{sqlabel}, and finished up with
% a \cs{@gobbletwo}, this eats up the next two tokens that immediately
% follow \cs{sqlabel} in the beginning of the \texttt{shortquiz} environment.
%    \begin{macrocode}
      \def\sqlabel{\aebtitleQuiz\@gobbletwo}%
   \fi
%    \end{macrocode}
% When the online (or email) options are used in eqexam, the \cs{hypertarget}
% command is adding vertical space. Normally \cs{sqlabel} is empty, so we don't
% need \cs{hypertarget} in this case here.
%    \begin{macrocode}
  \sq@aboveskip\sq@priorhook
  \@ifundefined{PointsOnLeft}%
  {\sq@setCLN{\eq@defaultShortQuizLabelName}%
    \ifx\sqlabel\@empty\else\noindent\fi
    \hypertarget{sqH\@currentHref}{}\sq@IDTxtField
    \ifx\sqlabel\@empty\else\expandafter
      \sqlabel\expandafter\sqhspace\fi
  {\set@typeset@protect\aebtitleQuiz}}{}\ignorespaces
%</package>
%<eqexam>  \sq@aboveskip\sq@priorhook\ignorespaces
%<*package|eqexam>
}
%    \end{macrocode}
%    \begin{macro}{\aeb@endshortquiz}
%    \begin{macro}{\aftershortquizskip}
% We reset the labels to the default in case the author
% of the document has redefined them temporarily. The author can
% avoid this reset, by redefining the global variables.
%    \begin{macrocode}
\newcommand\belowsqskip[1]{\def\aftershortquizskip{#1}}
\belowsqskip{\medskip}
\def\aeb@endshortquiz{\setcounter{quizno}{0}%
    \sq@afterhook
%</package|eqexam>
%<*package>
    \global\let\aebtitleQuiz\@empty
    \global\let\aebTitleQuiz\@empty
    \global\let\eq@tq@star\relax
%</package>
%<*package|eqexam>
    \global\let\sqlabel\eq@sqlabel
    \global\let\sqslrtnlabel\eq@sqslrtnlabel
    \global\let\sqsllabel\eq@sqsllabel
    \par\aftershortquizskip
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\sqLinks}
%    \begin{macro}{\sqForms}
% (01/01/05) Use these two commands to locally change the style of multiple choice
% questions: link or form.
%    \begin{macrocode}
\def\sqLinks{\def\sqstar{}}\sqLinks
\def\sqForms{\def\sqstar{*}}
\let\eq@tq@star\relax
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{macrocode}
%</package|eqexam>
%<*package>
%    \end{macrocode}
% The \texttt{shortquiz} contains two other environments, each nested inside
% the next: The \texttt{answers} environment and the \texttt{solution}
% environment. The latter environment is optional.
%
% \smallskip\noindent\textbf{Basic Usage for the \texttt{shortquiz} environment}
%\begin{verbatim}
%No solutions included             With Solutions
%\begin{shortquiz}                 \begin{shortquiz}
%The question                      The question
%\begin{answers}                   \begin{answers}[qz:mysoln]
%\Ans1 ... &\Ans0 &... &\Ans0 ...  \Ans1 ... &\Ans0 &... &\Ans0 ...
%\end{answers}                     \begin{solution}
%\end{shortquiz}                   .....
%                                  \end{solution}
%                                  \end{answers}
%                                  \end{shortquiz}
%\end{verbatim}
% To further complicate matters, the \env{shortquiz} can be
% used with the \env{questions} environment to create a series of
% numbered short question quizzes. See the manual for examples.
% \texttt{solution} environment is defined next.
%    \begin{macro}{solution}
% The \texttt{solution} environment does double duty, it is used by both
% the \texttt{shortquiz} and \texttt{quiz} environments.
% The macro \cmd{\solution@sq} is the one that actually does the work
% of \cmd{\solution}: It  writes the solutions to the file
% \cmd{\jobname.qsl}.  This macro obeys the \texttt{forpaper}
% option. In this case, solutions are separated by a
% \cmd{\medskip} rather then put on a separate page.  It also
% obeys the \texttt{solutionsafter} option
% \changes{v6.4s}{2012/06/03}{Added hooks \string\cs{sqPostHeaderHook} and
% \string\cs{qPostHeaderHook}}
%\par\medskip\noindent
% Hooks \DescribeMacro\sqPostHeaderHook\cmd{\sqPostHeaderHook},
% \DescribeMacro\qzPriorSolutionAfterHook\cmd\qzPriorSolutionAfterHook,
% \DescribeMacro\qPostHeaderHook\cmd{\qPostHeaderHook}
%    \begin{macrocode}
%</package>
%<*package|eqexam>
\def\qzPriorSolutionAfterHook{\smallskip}
\let\sqPostHeaderHook\@empty
\let\qPostHeaderHook\@empty
%    \end{macrocode}
% Private versions of the two above. Used by the \texttt{contsolns} option
%    \begin{macrocode}
\let\eq@sqPostHeaderHook\@empty
\let\eq@qPostHeaderHook\@empty
\let\prior@eqQt\@empty
\let\prior@eqSQt\@empty
%    \end{macrocode}
% \DescribeMacro\sqsolafterhspace The space after the solution label
%    \begin{macrocode}
\def\sqsolafterhspace{\space}
%    \end{macrocode}
%    When solutions are written to the QSL file, they are not normally in a group.
%    If you execute \DescribeMacro\makeQzSolnsLocalOn\cs{makeQzSolnsLocalOn}, each solution
%    is written in a group. Undo this with \DescribeMacro\makeQzSolnsLocalOff\cs{makeQzSolnsLocalOff},
%    which is the historic default.
%    \changes{v8.1p}{2018/02/13}{Added grouping for quiz solutions to the QSL file}
%    \begin{macrocode}
\newif\ifmakeQzSlLocal \makeQzSlLocalfalse
\def\makeQzSolnsLocalOn{\makeQzSlLocaltrue}
\def\makeQzSolnsLocalOff{\makeQzSlLocalfalse}
\def\solution@sq{\let\eq@next\relax
  \ifx\@qzsolndest\@empty
    \PackageWarning{exerquiz}%
    {* Solutions unexpected here, will *\MessageBreak
     * assume solutionsafter option *}%
    \eq@solutionsaftertrue
  \fi
  \ifeq@solutionsafter
    \par\qzPriorSolutionAfterHook\noindent
    \if!\sqsolafter!\else
    \sqsolafter\sqsolafterhspace\fi\ignorespaces
  \else
    \global\therearequizsolutionstrue\let\verbatim@out\quiz@solns
    \set@display@protect
    \immediate\write\verbatim@out{%
      \ifmakeQzSlLocal\protect\begingroup^^J\fi
%    \end{macrocode}
% Mark in the solutions files whether this is a quiz or a shortquiz solution.
%    \begin{macrocode}
      \if\eqQuizType\isQZ
            \ifx\prior@eqQt\@empty\else\prior@eqQt\fi
    \ifx\eqMrkCpyArg\@empty\else
      \protect\eqMrkSoln{\eqMrkCpyArg}\fi
            \protect\eqQt{\eqFilterArg}\else
            \ifx\prior@eqSQt\@empty\else\prior@eqSQt\fi
    \ifx\eqMrkCpyArg\@empty\else
      \protect\eqMrkSoln{\eqMrkCpyArg}\fi
            \protect\eqSQt{\eqFilterArg}\fi
      \protect\quizSolnHeader\if\eqQuizType\isQZ\ifx\allow@peek\eq@NO
        [{\curr@quiz}{\currQuizStartPage}]\fi\fi
        {\@qzsolndest}{\sqsllabel}\protect\eqterminex
        \if\eqQuizType\isQZ\expandafter\eq@qPostHeaderHook
        \expandafter\qPostHeaderHook\else
        \expandafter\eq@sqPostHeaderHook
        \expandafter\sqPostHeaderHook\fi}%
    \set@typeset@protect
    \expandafter\verbatimwrite\fi
}
\let\qzSolutionsAfterHook\@empty
\def\endsolution@sq{%
  \ifeq@solutionsafter
    \eq@fititin{\mbox{\sqslrtnlabel}}\par\qzSolutionsAfterHook
    \aftergroup\ignorespaces
  \else
    \endverbatimwrite
    \eq@clearMrkCpy
    \ifx\@qzsolndest\@empty\else\set@display@protect
      \immediate\write\verbatim@out{\eqSqSolnTrailer}%
     \set@typeset@protect
    \fi
  \fi
  \global\let\@qzsolndest\@empty
}
%</package|eqexam>
%<*package>
%    \end{macrocode}
% \DescribeMacro{\promoteNewPageHere}\cmd{\promoteNewPageHere} promotes
% a new page. The argument is a vertical skip. If there is \texttt{\#1}
% or more space remaining on the page, the command does nothing, otherwise
% it issues a \cs{newpage}.
% \changes{v6.4s}{2012/06/03}{Added \string\cs{promoteNewPageHere}}
% \changes{v6.8a}{2014/01/01}{Made an optional argument, but test for required argument as swell.}
% \changes{v8.5.6}{2020/01/01}{\string\cs{promoteNewPageHere}: added condition, first arg must be greater
% then 0pt; otherwise, do nothing}
%    \begin{macrocode}
\newcommand\pnphDflt{.1\textheight}
\newcommand{\promoteNewPageHere}[1][\pnphDflt]{%
    \@ifnextchar\bgroup{\eq@promoteNewPageHere}
        {\eq@promoteNewPageHere{#1}}%
}
\def\eq@promoteNewPageHere#1{\setlength{\@tempdimb}{#1}%
    \ifdim\@tempdima>\z@\par
    \bgroup\@nobreakfalse\addpenalty{-500}%
%    \setlength{\@tempdimb}{#1}
    \@tempdima \pagegoal
    \advance \@tempdima -\pagetotal
    \ifdim \@tempdima<\@tempdimb\ifnum\col@number>\@ne\columnbreak
        \else\newpage\penalty1\fi\fi\egroup\fi
}
%    \end{macrocode}
% The two macros\DescribeMacro{\saveDest}\cs{saveDest} and \DescribeMacro{\useDest}\cs{useDest} are used,
% as needed to save the destination name of a solution, then
% re-emitting it later, just prior to the solution. Useful for grouped questions.
%    \begin{macrocode}
\newcommand{\saveDest}[1][]{%
  \def\sd@arg{#1}\ifx\sd@arg\@empty
  \xdef\holdDest{\@qzsolndest}\else
  \xdef\@qzsolndest{#1}\xdef\holdDest{#1}\fi}
\def\useDest{\def\@qzsolndest{\holdDest}}
\let\holdDest\@empty
%</package>
%<*package|eqexam>
\def\fpAfterSolutionsSkip{\par\medskip}
\let\eqSqSolnTrailerHook\@empty
\let\eqQzSolnTrailerHook\@empty
\newcommand\eqSqSolnTrailer{%
  \if\eqQuizType\isQZ
    \eqQzSolnTrailerHook
    \protect\ReturnTo{page.\eq@pageThisQ}%
      {\protect\mbox{\sqslrtnlabel}}\string\endeqQt
  \else
    \eqSqSolnTrailerHook
    \protect\ReturnTo{page.\eq@pageThisQ}%
      {\protect\mbox{\sqslrtnlabel}}\string\endeqSQt%
  \fi
  \ifeqforpaper\protect\fpAfterSolutionsSkip\fi^^J%
  \ifmakeQzSlLocal\protect\endgroup^^J\fi
}
%</package|eqexam>
%<*package>
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\eqQt}
%    \begin{macro}{\endeqQt}
%    \begin{macro}{\eqSQt}
%    \begin{macro}{\endeqSQt}
% The \cmd{\eqQt} and \cmd{\eqSQt} are markers at the beginning of each
% quiz (short quiz, respectively) solution. These markers, along with
% ``end'' versions, \cmd{\endeqQt} and \cmd{\endeqSQt}, respectively,
% can be used to filter out the quiz solutions or the
% short-quiz solutions. The following example removes all short quizzes.
%\begin{verbatim}
%\long\def\eqSQt#1\endeqSQt{}
%\begin{document}
%\input{mydoc.qsl}
%\end{document}
%\end{verbatim}
%    \begin{macrocode}
% End package and begin package|eqexam
%</package>
%<*package|eqexam>
\let\eqSQt\@gobble
\let\endeqSQt\relax
\let\eqQt\@gobble
\let\endeqQt\relax
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\quizSolnHeader}
%  Each solution begins with \cmd{\quizSolnHeader}. This can be redefined
%  for whatever reason. It takes three arguments, one of which is optional.
%  \texttt{\#1} is the \cmd{\noPeek} parameters; \texttt{\#2} is the named destination to this
%  solution; \texttt{\#3} is the \cmd{\sqsllabel}.
%
% If you want to typeset solutions separately, you can redefine
% \cmd{\quizSolnHeader} as desired, and used in conjunction with
% \cmd{eqQt}.
% \changes{v6.7q}{2013/12/15}{Added this hook for use by \string\textsf{contsolns.dtx}}
%    \begin{macrocode}
\let\prior@quizSolnHeaderHook\@empty
\newcommand\quizSolnHeader[3][]{%
  \prior@quizSolnHeaderHook
  \ifeqforpaper\else\webnewpage\fi\noindent
%</package|eqexam>
%<*package>
  \def\eq@argi{#1}%
  \ifx\eq@argi\@empty\else\noPeek#1\fi
  \hypertarget{#2}{#3}\relax
%</package>
%<*eqexam>
  #2%
%</eqexam>
%<*package|eqexam>
  \solnspace
}
%</package|eqexam>
%<*package>
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\NoPeeking}
%    \begin{macro}{\AllowPeeking}
% A \texttt{quiz} solution has an additional (optional) feature. If
% \cmd{\NoPeeking} is executed, then an open action is placed on the opening
% page of each solution. This open action simply changes the page back to
% the page of the quiz. This is an attempt at keeping students from ``peeking''
% at the solutions before, or while they are taking a quiz. \cmd{\AllowPeeking}
% is the default.
%    \begin{macrocode}
\def\AllowPeeking{\global\let\allow@peek\eq@YES}\AllowPeeking
\def\NoPeeking{\global\let\allow@peek\eq@NO}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
% The\DescribeMacro{\noPeekAction} default definition of \cs{quizSolnHeader} contains a macro called
% \cmd{\noPeek}. This is the action that \cmd{\noPeek} performs. The actual
% definition of \cmd{\noPeek} is driver dependent, and is listed elsewhere.
% An open page action will be created with a JavaScript action, which calls
% a DLJS function \texttt{noPeek("\#1",\#2)}. The first parameter is the base
% name of the quiz; the second parameter is the page number the quiz starts from
% (so that we can return to that page when the student tries to view the solution
% when he is not authorized to).
%    \begin{macrocode}
\def\noPeekAction#1#2{%
  /AA <</O<</S/JavaScript/JS(noPeek("#1",#2))>> >>
}
%</package>
%<*package|eqexam>
%    \end{macrocode}
%    \subsection{The \texttt{shortquiz} Solutions}
% When the first solution is written, \cmd{\therearequizsolutions} is
% made true.  When the solutions are input back into the file, and
% this switch is still false, then no quiz header is typeset;
% this avoids an empty quiz solutions section with only the header.
%    \begin{macrocode}
\newif\iftherearequizsolutions \therearequizsolutionsfalse
\let\aeb@FLOverride\relax
%    \end{macrocode}
%    \begin{macro}{\includequizsolutions}
% This macro inserts the solutions to the short quizzes, if there are
% any solutions.  If a user uses this macro to insert the solutions
% elsewhere, \cmd{\include@quizsolutions} is called, then put is to
% \cmd{\relax}.
%    \begin{macrocode}
\def\includequizsolutions{\@ifstar
  {\let\resetQZtsolns\relax\includequizsolutionsi}
  {\def\resetQZtsolns{\global\let\include@quizsolutions\relax}%
   \includequizsolutionsi}}
\newcommand{\includequizsolutionsi}[1][]{%
  \filterFor{#1}\includequizsolutionsii}
\def\includequizsolutionsii{\include@quizsolutions
  \resetQZtsolns
  \let\eqFilterArg\@empty}
%</package|eqexam>
%<*package>
%    \end{macrocode}
%    \end{macro}
% \DescribeMacro{\eqqzsolutionshook}\DescribeMacro{\priorsqslsectitle}
% \DescribeMacro{\priorsqslinput} are commands executed at the beginning of the page of quiz solutions.
% These may be defined by the document author.
%    \begin{macrocode}
\let\eqqzsolutionshook\@empty
\let\priorsqslsectitle\@empty
\let\priorsqslinput\@empty
%    \end{macrocode}
% \DescribeMacro{\InputQzSolnsLevel}\nmpsep{*[\ameta{name}]\darg{\ameta{level}}} The solutions to the quizzes
% are in their own section, historically this has been \cs{section*}; however for some documents, it is
% desirable to have a numbered section number \cs{section} or \cs{chapter}, or \cs{chapter*}. The
% \cs{InputQzSolnsLevel} is designed to ease the task of changing how section-type. \ameta{level} is usually
% \texttt{section} or \texttt{chapter}; use \texttt* if you want solutions to be in \cs{section*} or \cs{chapter*};
% if the \ameta{name} is used, the beginning of the solutions is marked with \cs{label\darg{name}}.
% \changes{v8.5.5}{2019/12/17}{Added \string\cs{InputQzSolnsLevel}}
%    \begin{macrocode}
\def\InputQzSolnsLevel{\@ifstar
  {\def\eq@QzSolnsStar{*}\InputQzSolnsLevel@i}
  {\let\eq@QzSolnsStar\@empty\InputQzSolnsLevel@i}}
\newcommand{\InputQzSolnsLevel@i}[2][]{%
  \def\eq@QzSolnsLabel{#1}\def\eq@QzSolnsLevel{#2}}
\InputQzSolnsLevel*{section}
%    \end{macrocode}
% \DescribeMacro{\quizSolnsHeadnToc} sets up the quiz solution title.
%    \begin{macrocode}
\def\quizSolnsHeadnToc{%
  \edef\eq@mkCmd{\expandafter\noexpand
    \csname\eq@QzSolnsLevel\endcsname\eq@QzSolnsStar}%
  \eq@mkCmd{\sqslsectitle}\if!\eq@QzSolnsLabel!\else
  \label{\eq@QzSolnsLabel}\fi
  \if\eq@QzSolnsStar*%
    \addcontentsline{toc}{\eq@QzSolnsLevel}{%
      \@ifundefined{web@latextoc}{}{%
        \ifx\web@latextoc\eq@YES\else
        \protect\numberline{}\fi
      }\sqslsectitle
    }%
  \fi
}
%    \end{macrocode}
% \DescribeMacro{\quizSolnInput} is the command that actually inputs
% the solutions file \cmd{\jobname.qsl}.
% \changes{v8.2.6}{2018/12/03}{Placed \string\cs{endinput} at the end of
% the quiz solutions file}
%    \begin{macrocode}
\newcommand{\quizSolnInput}{%
  \global\let\webnewpage\relax
  \bgroup\OKToWriteExamDatatrue
  \writeT@QzSolns{\string\endinput}\egroup
  \immediate\closeout\quiz@solns
  \ifeq@noquizsolutions\else
%    \end{macrocode}
% If there are quiz solutions, we start a new page, and clear the right mark.
% We execute \cmd{\eq@normallheader} which sets the running left header,
% except on the page with a section head. We set the right mark as
% \cmd{\eq@sqslsecrunhead}. (2013/09/23) replaced \cmd{\eq@sqslsecrunhead}
% with \cmd{\sqslsecrunhead}, makes it easier to define running headers
% when solutions are filtered.
%    \begin{macrocode}
    \iftherearequizsolutions\newpage\markright{}%
      \eq@normallheader\markright{\sqslsecrunhead}%
      \ifx\webnewpage\relax
        \def\webnewpage{\global\let\webnewpage\newpage}\fi
%    \end{macrocode}
% Here we have various prior commands, and the setting of the
% section title.
%    \begin{macrocode}
      \priorsqslsectitle\quizSolnsHeadnToc\priorsqslinput
%    \end{macrocode}
% Now input the solution file \cmd{\jobname.qsl}.
%    \begin{macrocode}
      \InputIfFileExists{\jobname.qsl}{}%
        {!!! Solutions to quizzes not found}
%    \end{macrocode}
% A hook for hanging things
%    \begin{macrocode}
      \eqqzsolutionshook
%    \end{macrocode}
% Reset the running header cleanly
%    \begin{macrocode}
      \newpage\eq@defaultlheader
    \fi
  \fi
}
%    \end{macrocode}
% The internal command that insert solutions.  This command
% appears at the end of document, where it will insert the
% solutions, unless it has been redefined to \cmd{\relax} by
% \cmd{\includequizsolutions}.
%    \begin{macrocode}
\def\include@quizsolutions{\quizSolnInput}
%    \end{macrocode}
%
%    \section{The \texttt{quiz} and \texttt{quiz*} Environments}
%
% In this section we introduce the \texttt{quiz} environment, and all its
% supporting elements.
%
%    \subsection{Define the \texttt{quiz} Environment}
% \DescribeMacro{\priorqhook}\DescribeMacro{\aboveqskip}
% \DescribeMacro{\endqhook}\DescribeMacro{\belowqskip} These are hooks and skip
% before and after the \texttt{quiz} environment.
%    \begin{macrocode}
\newcommand{\priorqhook}[1]{\def\q@priorhook{#1}}
\priorqhook{}
\newcommand{\aboveqskip}[1]{\def\q@aboveskip{#1}}
\aboveqskip{\par\medskip}
\newcommand{\qhspace}{\space}
\def\endqhook#1{\def\eq@prior@endQuiz{#1}}
\endqhook{}
\newcommand{\belowqHooknSkip}[1]{\def\eq@belowqskip{#1}}
\belowqHooknSkip{\medskip}
\def\belowqskip{\belowqHooknSkip}
%    \end{macrocode}
%    \begin{macrocode}
\let\eq@initializeServerSubmit\@empty
%    \end{macrocode}
%    \begin{macro}{\quiztype}
%    \begin{macro}{\defaultquiztype}
% The command \cs{quiztype} can be used to force subsequent quizzes to be link
% style or form style, independent of the environment. Recognized values are
% \texttt{f} and \texttt{l}.  Once the override \cs{quiztype} has been used,
% you can recover the default behavior of the quizzes by expanding
% \cs{defaultquiztype}.
%    \begin{macrocode}
\newcommand{\quiztype}[1]{%
  \def\@quiztype{#1}\def\aeb@FLOverride{#1}}
\let\@quiztype\@empty
\newcommand{\defaultquiztype}{\let\@quiztype\@empty
  \let\aeb@FLOverride\relax}
\let\aeb@FLOverride\relax
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{macrocode}
\def\@setFormLinkType{%
  \if\qstar*%
    \ifx\aeb@FLOverride\relax%
      \def\@@quiztype{f}%
    \else
      \if\aeb@FLOverride l\def\@@quiztype{l}\else
        \def\@@quiztype{f}\fi
    \fi
  \else
    \ifx\aeb@FLOverride\relax
      \def\@@quiztype{l}%
    \else
      \if\aeb@FLOverride f\def\@@quiztype{f}\else
        \def\@@quiztype{l}\fi
    \fi
  \fi
}
\def\setdefault@Ans{\@setFormLinkType
  \expandafter\global\expandafter
  \let\expandafter\@Ans\expandafter=\csname Ans@\@@quiztype\endcsname
}
%    \end{macrocode}
%    \begin{macro}{\useForms}
%    \begin{macro}{\useLinks}
%    \begin{macro}{\restoreFLTypeDefault}
% For multiple choice questions, here we give the option of using a mixture of links
% and forms.
%    \begin{macrocode}
% Begin joint package and eqexam
%</package>
%<*package|eqexam>
\newcommand\useForms{\def\aeb@FLOverride{f}}
\newcommand\useLinks{\def\aeb@FLOverride{l}}
\newcommand\restoreFLTypeDefault{\global\let\aeb@FLOverride\relax}
\let\aeb@FLOverride\relax
%</package|eqexam>
%<*package>
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \begin{environment}{quiz}
% The \texttt{quiz} environment takes an optional `\texttt*'
% and one required argument.  There are two styles of quizzes:
% links or checkboxes. Beginning with v6.08, the use of the \texttt*-option
% is discouraged, use the \env{quiz*} environment instead.
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
%commandchars={!()},codes={\catcode`\%=9}]
%\begin{quiz}[*]{!ameta(base-name)}
% ...
%\end{quiz}
%\end{Verbatim}
%Brief description of parameters:
% \begin{itemize}
% \item optional \texttt{*} means to use checkboxes, otherwise use links;
% \item \texttt{\ameta{base-name}}: required argument is the base name of quiz.
% \end{itemize}
% Note that I set \cs{tabcolsep=0pt} in preparation for a tabular environment.
% If authors wants to use a tabular environment within a question, he/she must
% reset this value to its default, |\setlength{\tabcolsep}{6pt}|.
%    \begin{macrocode}
\newenvironment{quiz}{\goodbreak
  \@ifstar
    {\gdef\qstar{*}\@quiz*f}
    {\gdef\qstar{x}\@quiz*l}%
}{\aeb@endquiz}
\def\@quizCnt{0}
%    \end{macrocode}
%     \cs{ListOfQuizNames} and \cs{ListOfSQuizNames} are master lists of all
%     quizzes in the document.
%     \changes{v7.8l}{2017/07/29}{Added \string\cs{ListOfQuizNames} and
%     \string\cs{ListOfSQuizNames}}
%    \changes{v8.8.2}{2021/05/29}{Check for dupl quiz names}
%    \begin{macrocode}
\let\ListOfQuizNames\@empty
\def\@quiz*#1#2{\csarg % dps5-29
  \ifx{QzName-#2}\relax
    \csarg\gdef{QzName-#2}{1}\else
    \PackageWarning{exerquiz}{%
      The quiz name '#2' is already used,\MessageBreak
      please choose a quiz name unique throughout\MessageBreak
      this document}\csarg\gdef{QzName-#2}{0}%
  \fi
%    \end{macrocode}
% (06/08/10) The next two lines initialize the macros for registering the
% question label, i.e., \texttt{2(a)(ii)}. These two lines are repeated for
% the \texttt{oQuestion} and \texttt{shortquiz} environments.
%    \begin{macrocode}
  \xdef\eq@pageThisQ{\the\c@page}%
  \let\@currentQues\@empty
  \global\let\eqQzQuesList\@empty
  \global\let\pointValuesArray\@empty
%    \end{macrocode}
%    Initialize \texttt{ptypeArray} to track problem types better
% \changes{v7.7m}{2016/07/04}{Initialize \string\texttt{ptypeArray} to track problem types better}
%    \begin{macrocode}
  \global\let\ptypeArray\@empty
%    \end{macrocode}
%    Initialize \texttt{corrAnsArray} to track the correct answers
% \changes{v7.7n}{2016/07/06}{Initialize \string\texttt{ptypeArray} to track problem types better}
%    \begin{macrocode}
  \global\let\corrAnsArray\@empty
%    \end{macrocode}
%    Update the internal quiz counter.
%    \begin{macrocode}
  {\eqtmpcnta\@quizCnt\advance\eqtmpcnta\@ne
    \xdef\@quizCnt{\the\eqtmpcnta}}%
%    \end{macrocode}
% We try to support {\LaTeX}'s cross-referencing system by defining
% \cs{@currentlabel}, \cs{@currentHlabel}, and \cs{@currentlabelname}.
%    \begin{macrocode}
  \edef\@currentlabel{\@quizCnt}%
  \edef\@currentHref{quiz.\@quizCnt}%
  \sq@setCLN{\eq@defaultQuizLabelName}%
  \setcounter{eqpointvalue}{0}\setcounter{questionno}{0}%
  \eq@initializeServerSubmit
  \global\let\eqQuizType\isQZ %\tabcolsep=0pt
  \gdef\eqPTs{1}\global\let\eqQT\eq@na
%    \end{macrocode}
% \changes{v6.3u}{2010/11/04}{%
%    Added \string\cs{xdef}\string\cs{oField}\string\darg{\#2}, this is
%    needed for \string\textsf{apb.dtx}}
%    Add \string\cs{listOfQuizNames} to track quizzes
%    \changes{v7.8k}{2017/07/25}{Added \string\cs{listOfQuizNames} to track quizzes}
%    \begin{macrocode}
  \g@addto@macro\ListOfQuizNames{,#2}%
  \gdef\quiz@total{#2}\xdef\curr@quiz{#2}\xdef\oField{#2}%
  \xdef\currQuiz{#2}\xdef\currQuizStartPage{\thepage}%
  \xdef\aPointType{0}%
%    \end{macrocode}
% (2013/12/20) Pass \cs{bqlabelISO} through \cs{pdfstringdef}.
%    \begin{macrocode}
  \def\fieldJSStr@CMD{\flJSStr*[noquotes]\bqlabelISO}%
  \expandafter\fieldJSStr@CMD\expandafter{\bqlabelISO}%
  \ifx\@quiztype\@empty\gdef\@@quiztype{#1}\else
    \xdef\@@quiztype{\@quiztype}\fi
  \let\@qzsolndest\@empty
  \let\answers\answers@q\let\endanswers\endanswers@q
  \let\manswers\manswers@q\let\endmanswers\endanswers@q
  \let\solution\solution@sq\let\endsolution\endsolution@sq
  \expandafter
    \xdef\csname titleOf\currQuiz\endcsname{\aebTitleQuiz}%
%    \end{macrocode}
%    Modified the destination name of \cs{hypertarget} to avoid deplicate
%    destinations. Did the same thing for the \texttt{shortquiz}.
%    \changes{v7.8a}{2016/12/07}{Modified destination name of \string\cs{hypertarget}}
%    \begin{macrocode}
  \q@aboveskip\q@priorhook\noindent\hypertarget{qzH\@currentHref}{}%
  \eq@beginQuiz\qhspace{\set@typeset@protect\aebtitleQuiz}%
  \ignorespaces
}
%    \end{macrocode}
% Here is the end for the \texttt{quiz} and \texttt{quiz*} environments. The
% \cs{eq@prior@endQuiz} can be used for whatever purposes a
% developer wants.
%    \begin{macrocode}
\def\aeb@endquiz
{%
  \eq@prior@endQuiz\noindent\eq@endQuiz
  \global\let\eqQuizType\relax
  \global\let\aebtitleQuiz\@empty
  \global\let\aebTitleQuiz\@empty
  \global\let\bqlabel\eq@bqlabel % reset beginning label to default
  \global\let\eqlabel\eq@eqlabel % reset ending label to default
%    \end{macrocode}
% (2013/10/18) Added \cs{sqsllabel} to list of commands that are reset.
%    \begin{macrocode}
  \global\let\sqsllabel\eq@sqsllabel
  \global\let\sqslrtnlabel\eq@sqslrtnlabel
  \global\let\bqlabelISO\eq@bqlabelISO
  \eq@belowqskip
}
%    \end{macrocode}
%    \end{environment}
%
%    \subsection{Define the \texttt{quiz*} Environment}
%
%    \begin{environment}{quiz*}
% This environment is more latexy, \texttt{quiz*} environment is for quizzes with forms. Equivalent
% to \verb!\begin{quiz}*...\end{quiz}!/
%    \begin{macrocode}
\newenvironment{quiz*}{\goodbreak\gdef\qstar{*}\@quiz*f}{\aeb@endquiz}
%    \end{macrocode}
%    \end{environment}
%
%    \subsection{Begin/End Quiz with Link or Buttons}
%
% Redefine this macro to \cmd{\eq@BeginQuizButton} to get a form button
% for the \texttt{quiz} environment. Pressing on the link or button
% initializes the quiz. The default is `link': \cmd{\eq@BeginQuizLink}.
%    \begin{macrocode}
\newcommand\eq@beginQuiz{\eq@BeginQuizLink}
%    \end{macrocode}
% Redefine this macro to |\eq@EndQuizButton| to get a form button
% for the \texttt{quiz} environment. Pressing on the link or button
% will score the quiz. The default is `link': |\eq@EndQuizLink|.
%    \begin{macrocode}
\newcommand\eq@endQuiz{\eq@EndQuizLink}
%    \end{macrocode}
%    \begin{macro}{\useBeginQuizButton}
% Use a button instead of a link for begin quiz
%    \begin{macrocode}
\newcommand\useBeginQuizButton[1][]
  {\renewcommand\eq@beginQuiz{\eq@BeginQuizButton[#1]}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\useEndQuizButton}
% Use a button instead of a link for end quiz
%    \begin{macrocode}
\newcommand\useEndQuizButton[1][]
  {\renewcommand\eq@endQuiz{\eq@EndQuizButton[#1]}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\useBeginQuizLink}
% Use a link begin quiz (the default)
%    \begin{macrocode}
\newcommand\useBeginQuizLink
  {\renewcommand\eq@beginQuiz{\eq@BeginQuizLink}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\useEndQuizLink}
% Use a link end quiz (the default)
%    \begin{macrocode}
\newcommand\useEndQuizLink
  {\renewcommand\eq@endQuiz{\eq@EndQuizLink}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\@initQuiz}
% \cs{@initQuiz} is executed when you click on `Begin Quiz'. Included here are some
% macro hooks for insert code prior to, and after the quiz initialization. This
% command appears in the commands \cs{eq@@BeginQuizLinkActions} and \cs{eq@@BeginQuizButtonActions} below.
%\changes{v7.0}{2014/11/05}{Added some JS: lstOfQuizzes is an object
%   listing all quizzes in the document, the value is the quiz object. We add properties
%   isSubmitted and initializeWith to the quiz object.}
%\changes{v8.6.1}{2020/12/30}{Changed the comparison method for \string\cs{priorInitQuiz} and
%   \string\cs{postInitQuiz} to reflect their \string\cs{newcommand} definition.}
%\changes{v8.8.1}{2021/05/21}{Added a gateway into \string\cs{@initQuiz}}
%    \begin{macrocode}
\begingroup
  \catcode`<=1 \catcode`\>=2 \@makeother\{ \@makeother\}
  \gdef\jsLB<{>\gdef\jsRB<}>
\endgroup
%    \end{macrocode}
%    (2021/05/21) Added a gate keeper into \uif{Begin Quiz}. Normally, all code
%    passes through, but this can be modified by redefining \DescribeMacro\BeginQuizG@te
%    \cs{BeginQuizG@te}; restore any changes with  \DescribeMacro\restoreBeginQuiz
%    \cs{restoreBeginQuiz}.
%    \begin{macrocode}
\newcommand{\BeginQuizG@te}{if (true)}
\def\Norm@lBeginQuiz{if (true)}
\def\restoreBeginQuiz{\let\BeginQuizG@te\Norm@lBeginQuiz}
\newcommand\@initQuiz{%
  \BeginQuizG@te\space\jsLB\jsR\jsT
    var\eqSP\curr@quiz=new Object();\jsR\jsT
    lstOfQuizzes["\curr@quiz"]=\curr@quiz;\jsR\jsT
    \curr@quiz.oAlertCheck={bAfterValue:false};\jsR\jsT
    \curr@quiz.Grp={};%
    \ifx\defaultColorJSLoc\@empty\else\jsR\jsT
    \oField.DefaultColorJSLoc=\defaultColorJSLoc;\fi
    \ifx\rghtColorJSLoc\@empty\else\jsR\jsT
    \oField.RightColorJSLoc=\rghtColorJSLoc;\fi
    \ifx\wrngColorJSLoc\@empty\else\jsR\jsT
    \oField.WrongColorJSLoc=\wrngColorJSLoc;\fi
    \ifx\partialColorJSLoc\@empty\else\jsR\jsT
    \oField.PartialColorJSLoc=\partialColorJSLoc;\fi
    \ifx\rghtAnsSymbJSLoc\@empty\else\jsR\jsT
    \oField.RightAnsSymbJSLoc=\rghtAnsSymbJSLoc;\fi
    \ifx\wrngAnsSymbJSLoc\@empty\else\jsR\jsT
    \oField.WrongAnsSymbJSLoc=\wrngAnsSymbJSLoc;\fi
    \ifx\corrAnsSymbJSLoc\@empty\else\jsR\jsT
    \oField.CorrAnsSymbJSLoc=\corrAnsSymbJSLoc;\fi
    \ifx\eqGradeScaleLoc\@empty\else\jsR\jsT
    \oField.GradeScaleLoc=new Array(\eqGradeScaleLoc);\fi
    \ifx\eqCorrLocalChoiceFully\@empty\else\jsR\jsT
    \oField.fullyCorrectLoc=\eqCorrLocalChoiceFully;\fi
    \if$\priorInitQuiz$\else\jsR\jsT\priorInitQuiz\fi\jsR\jsT
    InitializeQuiz("\curr@quiz",\ifnocorrections0\else1\fi);%
    \ifx\eq@CGI\@empty\jsR\jsT\curr@quiz.isSubmitted=false;\else
    \jsR\jsT\curr@quiz.isSubmitted=true;\fi
    \jsR\jsT\curr@quiz.initializeWith=%
      'InitializeQuiz("\curr@quiz",\ifnocorrections0\else1\fi);';%
    \if$\postInitQuiz$\else\jsR\jsT\postInitQuiz\fi\jsR
  \jsRB
}
%    \end{macrocode}
%     The following is the \env{defineJS} version of \cs{@initQuiz}. This is experiemental
%     for now, not yet implemented.
%\begin{verbatim}
%\begin{defineJS}[\makeesc\!\makecmt\%]{\@initQuiz}
%var !curr@quiz=new Object();
%lstOfQuizzes["!curr@quiz"]=!curr@quiz;
%!curr@quiz.oAlertCheck={bAfterValue:false};
%!curr@quiz.Grp={};%
%!ifx!defaultColorJSLoc!@empty!else
%!oField.DefaultColorJSLoc=!defaultColorJSLoc;!fi%
%!ifx!rghtColorJSLoc!@empty!else
%!oField.RightColorJSLoc=!rghtColorJSLoc;!fi%
%!ifx!wrngColorJSLoc!@empty!else
%!oField.WrongColorJSLoc=!wrngColorJSLoc;!fi%
%!ifx!partialColorJSLoc!@empty!else
%!oField.PartialColorJSLoc=!partialColorJSLoc;!fi%
%!ifx!rghtAnsSymbJSLoc!@empty!else
%!oField.RightAnsSymbJSLoc=!rghtAnsSymbJSLoc;!fi%
%!ifx!wrngAnsSymbJSLoc!@empty!else
%!oField.WrongAnsSymbJSLoc=!wrngAnsSymbJSLoc;!fi%
%!ifx!corrAnsSymbJSLoc!@empty!else
%!oField.CorrAnsSymbJSLoc=!corrAnsSymbJSLoc;!fi%
%!ifx!eqGradeScaleLoc!@empty!else
%!oField.GradeScaleLoc=new Array(!eqGradeScaleLoc);!fi%
%!ifx!eqCorrLocalChoiceFully!@empty!else
%!oField.fullyCorrectLoc=!eqCorrLocalChoiceFully;!fi%
%!if$!priorInitQuiz$!else
%!priorInitQuiz!fi%
%InitializeQuiz("!curr@quiz",!ifnocorrections0!else1!fi);%
%!ifx!eq@CGI!@empty
%!curr@quiz.isSubmitted=false;!else
%!curr@quiz.isSubmitted=true;!fi
%!curr@quiz.initializeWith=%
%'InitializeQuiz("!curr@quiz",!ifnocorrections0!else1!fi);';%
%!if$!postInitQuiz$!else
%!postInitQuiz!fi
%\end{defineJS}
%\end{verbatim}
%    \end{macro}
%    \begin{macro}{\priorInitQuiz}
%    \begin{macro}{\postInitQuiz}
% These two commands are hooks that allow a document author to
% execute JavaScript just prior to initializing the quiz and just after. These appear in
% \cs{eq@@BeginQuizLinkActions} and \cs{eq@@BeginQuizButtonActions} below.
%    \begin{macrocode}
\newcommand{\priorInitQuiz}{}
\newcommand{\postInitQuiz}{}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
% Here are a couple\DescribeMacro{\eq@submitURL}\DescribeMacro{\eq@insertHiddenFields}{}
% of macros that appear in `\uif{End Quiz}', and are used for
% submitting quiz results to a web server.
%    \begin{macrocode}
\let\eq@submitURL\@empty
\let\eq@insertHiddenFields\@empty
%    \end{macrocode}
%    \begin{macro}{\priorSubmitQuiz}
%    \begin{macro}{\postSubmitQuiz}
%    These two commands are defined in this package, but are use in \pkg{eq2db}.
%    \begin{macrocode}
\newcommand\priorSubmitQuiz{}
\newcommand\postSubmitQuiz{}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%
% \subsubsection{With Links}
%
%    \begin{macro}{\eq@BeginQuizLink}
% `\uif{Begin Quiz}' with links
%    \begin{macrocode}
\def\eq@@BeginQuizLinkActions{\A{\JS{\@initQuiz}}}
\def\eq@BeginQuizLinkDefaults{\Border{0 0 0}}
\let\bqlabelFmt\@empty
\def\eq@BeginQuizLink{\qz@IDTxtField
  \set@@Link{}{}{}{\color{\@linkcolor}\bqlabelFmt\bqlabel}{}%
  {\eq@setWidgetProps\setLink@driver}%
  {\eq@BeginQuizLinkDefaults\eq@@BeginQuizLinkActions\every@Link}%
  \space\ignorespaces}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\eq@EndQuizLink}
% Code the the link version of `End Quiz'.
% \changes{v8.6}{2020/11/29}{Action for End Quiz Lnk now a \string\env{defineJS} env}
%    \begin{macrocode}
\def\eq@@EndQuizLinkActions{\A{\JS{\eQzBtnActns}}}
\def\eq@EndQuizLinkDefaults{\Border{0 0 0}}
\let\eqlabelFmt\@empty
\def\eq@EndQuizLink{%
  \ifx\eq@CGI\@empty
    \let\eq@submitURL\@empty
    \let\eq@insertHiddenFields\@empty\fi
  \set@@Link{}{}{}{\color{\@linkcolor}\eqlabelFmt\eqlabel}{}%
  {\eq@setWidgetProps\setLink@driver}%
  {\eq@EndQuizLinkDefaults\eq@@EndQuizLinkActions\every@Link}%
  \makebox[0pt][r]{\textField[\BC{}\autoCenter{n}]%
    {htxtfld.\curr@quiz}{2bp}{2bp}}%
  \makebox[0pt][r]{\eq@hiddenScoreData\eq@insertHiddenFields}%
  \global\let\eq@CGI\@empty\ignorespaces
}
%    \end{macrocode}
%    \end{macro}
%
% \subsubsection{With Buttons}
%
%    \begin{macro}{\eq@BeginQuizButton}
% This is the button when the user wants button rather than link for the
% \texttt{quiz} environment.
% \changes{v8.6}{2020/11/29}{Action for End Quiz Btn now a \string\env{defineJS} env}
%    \begin{macrocode}
\def\BeginQuizButtonDefaults{%
  \CA{\bqlabel}\H{P}\F{\FPrint}
  \BC{1 0 0}\BG{.7529 .7529 .7529}\W{1}\S{B}}
\def\eq@@BeginQuizButtonActions{\A{\JS{\@initQuiz}}}
\newcommand\eq@BeginQuizButton[1][]{%
  \mbox{\qz@IDTxtField\push@@Button{#1}{beginQuiz.\curr@quiz}{}%
    {\DefaultHeightOfWidget}{\eq@protect\A}%
    {\eq@setButtonProps\eq@Button@driver}%
    {\BeginQuizButtonDefaults\eq@@BeginQuizButtonActions
     \every@ButtonField\every@BeginQuizButton}}}
%    \end{macrocode}
%    \end{macro}
%    \DescribeMacro\EndQuizG@te is an entry point in the \uif{End Quiz} action
%    that, if redefined, allows the document author to intercept the end of the quiz
%    code and insert alternate code lines; perhaps giving the student one last chance
%    to change his/her quiz before submittal. A document author may redefine \cs{EndQuizLastChance}
%    for one quiz, then change the \cs{eQzBtnActns} code by back to its default by expanding
%    \DescribeMacro\restoreEndQuiz\cs{restoreEndQuiz} after the quiz. See the DTX of the
%    package \pkg{eq-pin2corr} for an example of redefining \cs{EndQuizLastChance}.
%    The default definition is to ``pass-thru'' with no action.
%    \changes{v8.8.1}{2021/05/21}{\string\cs{EndQuizG@te} defined as part
%    of \string\cs{eQzBtnActns}}
%    \begin{macrocode}
\newcommand{\EndQuizG@te}{if (true)}
\def\Norm@lEndQuiz{if (true)}
\def\restoreEndQuiz{\let\EndQuizG@te\Norm@lEndQuiz}
%    \end{macrocode}
%    \begin{macro}{\eQzBtnActns}
% The `End Quiz' JavaScript action code
% \changes{v8.8.1}{2021/05/21}{Modified \string\cs{eQzBtnActns} to allow more
% customizations by inserting \string\cs{EndQuizLastChance} into the code}
%    \begin{macrocode}
\begin{defineJS}[\makeesc\*\makecmt\%]{\eQzBtnActns}
if (!isQuizInitialized("*curr@quiz"))
  eqAppAlert(InitMsg("*bqlabelISO"),3);
else {
  if (*minQuizResp(*thequestionno)&&_ModalNotOn){
%    \end{macrocode}
%    Insert one last chance.
%    \begin{macrocode}
    *EndQuizG@te {
      *curr@quiz.PtValues=new Array(*pointValuesArray);
      ProbType=[*ptypeArray];%
*if@inclkey
      *curr@quiz.CorrAns=new Array(*corrAnsArray);*fi
%    \end{macrocode}
%    (2021/02/17) Pass a fourth argument to \texttt{DisplayQuizResults()}, its default
%    value is \texttt{bDisplaySilent=false}, but can be changed locally
%    to \texttt{true}. When \texttt{bDisplaySilent=true}, \texttt{DisplayQuizResults()}
%    does not write its results to any field (\uif{Score Field}, \uif{Points Field}, etc.).
% \changes{v8.6.4}{2021/02/17}{We pass
%  a new \texttt{bDisplaySilent} argument to \texttt{DisplayQuizResults} for ``silent reporting''}
%    \begin{macrocode}
      DisplayQuizResults("*curr@quiz",*theeqpointvalue,%
*thequestionno,bDisplaySilent);
      bDisplaySilent=false;
      var h=this.getField("ScoreData.*curr@quiz");
      h.value=Score+";"+NQuestions+";"%
+ptScore+";"+NPointTotal;%
*ifx*eq@submitURL*empty*else
      *eq@submitURL*fi%
*if$*postSubmitQuiz$*else
      *postSubmitQuiz*fi
      resetQuiz("*curr@quiz");
    }
  }
}
\end{defineJS}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\def\EndQuizButtonDefaults{%
  \CA{\eqlabel}\F{\FPrint}\BC{1 0 0}
  \BG{.7529 .7529 .7529}\W{1}\S{B}\H{P}}
\def\eq@@EndQuizButtonActions{%
  \A{\JS{\eQzBtnActns}}}
%    \end{macrocode}
% Save end quiz button action. The \DescribeMacro\restoreNormalEndQuiz\cs{restoreNormalEndQuiz}
% restores the action to its original definition.
% \changes{v8.8.3}{2021/06/24}{Added \string\cs{restoreNormalEndQuiz}}
%    \begin{macrocode}
\let\eq@@EndQuizButtonActionsDefSave\eq@@EndQuizButtonActions % dps0624
\def\restoreNormalEndQuiz % dps0624
  {\let\eq@@EndQuizButtonActions\eq@@EndQuizButtonActionsDefSave}
\newcommand{\eq@hiddenScoreData}{\makebox[0pt][r]{%
  \textField[\BC{}\F{\FHidden}]{ScoreData.\curr@quiz}{2bp}{2bp}}}
%    \end{macrocode}
%    \begin{macro}{\eq@EndQuizButton}
%    \begin{macrocode}
\newcommand\eq@EndQuizButton[1][]{%
  \ifx\eq@CGI\@empty
    \let\eq@submitURL\@empty
    \let\eq@insertHiddenFields\@empty\fi
  \mbox{\push@@Button{#1}{endQuiz.\curr@quiz}{}%
    {\DefaultHeightOfWidget}{\eq@protect\A}%
    {\eq@setButtonProps\eq@Button@driver}%
    {\EndQuizButtonDefaults\eq@@EndQuizButtonActions
     \every@ButtonField\every@EndQuizButton}}%
  \makebox[0pt][r]{\eq@hiddenScoreData\eq@insertHiddenFields}%
  \global\let\eq@CGI\@empty}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\databaseName}
%    \begin{macro}{\tableName}
%    \begin{macro}{\eqCGI}
%    \begin{macro}{\eqSubmit}
% These four commands give general support for submitting quiz data
% to a web server for storage in a database.  Use in the \pkg{eq2db} package.
% (2014/09/14) Sanitized first argument of \cs{eqSubmit}.
%    \begin{macrocode}
\newcommand\databaseName[1]{\gdef\db@Name{#1}}\def\db@Name{}
\newcommand\tableName[1]{\gdef\db@Table{#1}}\def\db@Table{}
\newcommand\eqCGI{\definePath{\eq@CGI}}\def\eq@CGI{}
\newcommand\eqSubmit{\hyper@normalise\eqSubmiti}
\def\eqSubmiti#1{\xdef\eq@CGI{"#1"}\eqSubmitii}
\def\eqSubmitii#1#2{\databaseName{#1}\tableName{#2}}
\providecommand{\rtnURL}{\definePath{\thisRtnURL}}
\let\thisRtnURL\@empty
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% The next two commands are used in the \textsf{eq2db} package. We make the
% definitions here so that they can be used even if the package is not loaded.
% In this way, a self-contained quiz can be submitted just by loading the
% package.
%    \begin{macrocode}
\newcommand\addHiddenTextField[3][]{}
\newcommand\populateHiddenField[2]{}
%    \end{macrocode}
%    \subsection{Correcting the Quiz}
%
%    \begin{macro}{\eqButton}
% Use this button to correct the quiz. Can be customize with
% optional arguments.
% section.
%\begin{verbatim}
% #1 = optional attributes of button
% #2 = title of textfield that contains the score.
%\end{verbatim}
%    \begin{macrocode}
\def\eqButtonDefaults{%
  \CA{\eq@local@CA}\AC{}\H{P}\W{1}\S{B}
  \BC{1 0 0}\BG{.7529 .7529 .7529}}
%    \end{macrocode}
%    \leavevmode\DescribeMacro\CorrBtnActionsJS is the JavaScript action
%    to support the \cs{eqButton}/\cs{CorrButton}. The macro may be redefined
%    using the \env{defineJS*} environment. Copy and pasted the contents into
%    a new \env{defineJS*} environment and modify the code.
%    \changes{v8.5}{2019/10/11}{Incorporated \string\env{defineJS} into
%    the action of \string\cs{eqButton}}
%    \begin{macrocode}
\begin{defineJS}[\makeesc\@]{\CorrBtnActionsJS}
if (isEndQuizPushed("@eqBaseName")){
  correctQuiz("@eqBaseName",@thequestionno);
%    \end{macrocode}
% (06/13/10) Added the quiz summary table, and the function
% \texttt{correctSumryTbl}. If a summary table is not present
% the function does nothing.
%    \begin{macrocode}
  if (typeof correctSumryTbl == "function")
    correctSumryTbl("@eqBaseName",@thequestionno);
}
\end{defineJS}
\def\@@eqButtonActions{\A{\JS{\CorrBtnActionsJS}}}
\newcommand\eqButton[2][]{%
%    \end{macrocode}
% If nocorrections is true, then this button does not appear.
%    \begin{macrocode}
  \ifnocorrections\else
    \def\eqBaseName{#2}%
    \mbox{\push@@Button{#1}{correct.#2}{}{\DefaultHeightOfWidget}%
    {\eq@protect\A}{\eq@setButtonProps\eq@Button@driver}%
    {\eqButtonDefaults\@@eqButtonActions\every@ButtonField
    \every@eqButton}}%
  \fi
}
%    \end{macrocode}
% \changes{v6.7n}{2013/09/17}{\string\cs{CorrButton} is now an alias for \string\cs{eqButton}}
% \DescribeMacro{\CorrButton} is a name better suited for the task of this button
% than the \cs{eqButton} name.
%    \begin{macrocode}
\def\CorrButton{\eqButton}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\rbMarkup}
% An optional element for quizzes. Place just after a response box (perhaps, before the
% \cs{CorrAnsButton}. When the correct button is pressed, this check box will show a
% green check or a red cross (by default).
%    \begin{macrocode}
\def\rbMarkup@Defaults{%
  \BC{}\F{\FHidden}\Ff{\FfReadOnly}\textSize{12}
  \textColor{0 g}\symbolchoice{check}\W{}}
\newcommand\rbMarkup[1][]{%
  \ifx\grpquestions\eq@One
    \def\Fld@name{%
        \oField.\thequestionno.\thegrpquestionno}\else
    \def\Fld@name{\oField.\thequestionno}\fi
  \mbox{\check@@Box{#1\V{Yes}\DV{Yes}}%
  {rbmarkup.\Fld@name}%
  {\RadioFieldSize}{\RadioFieldSize}{Yes}{}%
  {\eq@setWidgetProps\eq@Check@driver}%
  {\rbMarkup@Defaults\every@CheckBox\every@rbMarkup}}}
%    \end{macrocode}
%    \end{macro}
%
%    \subsection{Measuring Quiz Results}
%
%    \begin{macro}{\minQuizResp}
% Define the threshold level. The two permissible values are \texttt{lowTreshold}
% and \texttt{highThreshold}. These are names of DLJS. New threshold functions
% can be defined and specified.
%    \begin{macrocode}
\newcommand\minQuizResp{lowThreshold}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\PTs}
% Use this macro to assign weights to the quiz questions. Use only within
% the \texttt{questions} environment, just after an \cmd{\item}. If
% \cmd{\PTs} does not appear, then a weight of $1$ is assumed.
%\par\noindent|#1 = number of points for the current question.|
% The star-form records the points but does not display the points.
%    \begin{macrocode}
\newcommand\PTs{\@ifstar{\def\eq@star{*}\@PTs}{\def\eq@star{x}\@PTs}}
\def\@PTs#1{\gdef\eq@PTs{#1}\ifx\eq@PTs\@empty\gdef\eq@PTs{1}\fi
    \global\let\eqPTs\eq@PTs\global\let\eq@PTs\@empty
    \if\eq@star*\else\PTs@Hook\fi}
\def\eq@PTs{0} % initialize this variable
%    \end{macrocode}
%    \begin{macro}{\QT}
% \cs{QT} is used for entering the ``question type'' for the question (optional).
% This question type is entered into the ``\texttt{tagged}'' data, and is meant to be
% used for classifying and in tracking the problem types. Example: \verb+\QT{limits}+.
%    \begin{macrocode}
\newcommand\QT[1]{%
  \gdef\eq@qT{#1}\ifx\eq@qT\@empty\global\let\eq@qT\eq@na\fi
%    \end{macrocode}
%    \cs{eqQT} saves the value, then we put \cs{eq@qT} back to its default.
%    \begin{macrocode}
  \global\let\eqQT\eq@qT\global\let\eq@qT\eq@na}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\def\eq@na{na} % not applicable
\let\eq@qT\eq@na
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\PTsHook}
% Used to typeset the number of points.
%    \begin{macrocode}
\newcommand\PTsHook[1]{\def\PTs@Hook{#1}}
\let\PTs@Hook\@empty
\let\eq@PTs\@empty
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\eqGradeScale}
% This is an array of letter grades and grade ranges. This macro is use as the argument
% of the JS function \texttt{GetGrade}.
%    \begin{macrocode}
\newcommand\eqGradeScale{%
    "A",[90, 100],"B",[80,90],"C",[70,80],"D",[60,70],"F",[0,60]}
\let\eqGradeScaleLoc\@empty
\newcommand{\resetGradeScaleLoc}{\global\let\eqGradeScaleLoc\@empty}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\DefaultHeightOfWidget}
%    \begin{macro}{\RBW}
%    \begin{macro}{\SFW}
%    \begin{macro}{\GFW}
%    \begin{macro}{\PtW}
%    \begin{macro}{\PcW}
% \cmd{\DefaultHeightOfWidget} is the default height of all form
% fields (except radio fields and checkboxes). \cmd{\RBW} is the
% default width of the \cmd{\RespBox}; and \cmd{\SFW} is the
% default width of the \cmd{\ScoreField}. \cs{GFW} is the default
% width of a grade field button; \cs{PtFW} is the default width
% of a points field button; and \cs{PcFW} is the default width
% of the percent field button.
%    \begin{macrocode}
\def\tallywidth#1{\def\TBW{#1}}
\def\TBW{15bp}
\def\DefaultHeightOfWidget{11bp}
\def\RadioFieldSize{11bp}
\def\RBW{2in}       % Response Box width (math,txt, txtpc, answer field)
\def\SFW{1.5in}     % Score Field Width
\def\GFW{20pt}      % Grade Field Width
\def\PtFW{1.5in}    % Point Field Width
\def\PcFW{1.5in}    % Percent Field Width
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\ScoreField}
%     This text field will receive the scores
%     of a quiz.  The command \cmd{\eqScore} was defined
%     in Section~\ref{ss:ldm}.  This command takes an optional
%     argument and a required argument.
%\begin{verbatim}
%#1 = one or more commands that will customize the design of the
%     field.  See the manual for examples.
%#2 = Base name of the quiz
%\end{verbatim}
%    \begin{macrocode}
\def\ScoreFieldDefaults
{%
    \Ff{\FfReadOnly}\BC{1 0 0}\BG{}\S{S}
    \DV{\eqScore}\V{\eqScore}\W{1}
}
\newcommand\ScoreField[2][]{%
  \mbox{\text@@Field{#1}{ScoreField.#2}{\SFW}%
    {\DefaultHeightOfWidget}{}{\eq@setWidgetProps\eq@TextField}%
    {\ScoreFieldDefaults\every@eqTextField\every@ScoreField}}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\GradeField}
% This command creates a text field that shows the letter grade of the user's
% effort on the current quiz.
%    \begin{macrocode}
\def\GradeFieldDefaults{%
  \textColor{0 0 1 rg}\BC{1 0 0}\BG{1 1 1}\S{S}
  \Ff{\FfReadOnly}\Q{1}\W{1}}
\newcommand\GradeField[2][]{%
  \mbox{\text@@Field{#1}{GradeField.#2}{\GFW}%
    {\DefaultHeightOfWidget}{}{\eq@setWidgetProps\eq@TextField}%
    {\GradeFieldDefaults\every@eqTextField\every@GradeField}}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\AnswerField}
% This command creates a text field to receive the answers to the
% fill-in questions.
%    \begin{macro}{\resetAnsFieldOnClose}
% When expanded, the \cs{AnswerField}s will be reset whenever the user changes pages.
%    \begin{macro}{\noResetAnsFieldOnClose}
% When expanded, the \cs{AnswerField}s will not be reset, this is the default behavior.
%    \begin{macrocode}
\def\AnswerFieldDefaults{%
  \BC{0 0 0}\S{S}\Ff{\FfReadOnly}\W{1}
  \presets{\eq@resetAnsFieldOnClose}}
\let\eq@resetAnsFieldOnClose\@empty
\newcommand{\noResetAnsFieldOnClose}{%
    \global\let\eq@resetAnsFieldOnClose\@empty}
\newcommand{\resetAnsFieldOnClose}{%
  \gdef\eq@resetAnsFieldOnClose{%
    \AApageclose{this.resetForm(["\Fld@name"]);}}}
\newcommand\AnswerField[2][]{%
  \mbox{\text@@Field{#1}{Ans.#2}{\RBW}{\DefaultHeightOfWidget}%
    {}{\eq@setWidgetProps\eq@TextField}%
    {\AnswerFieldDefaults\every@eqTextField\every@AnswerField}}}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\autoAnswerField}
% An attempt at putting \cs{AnswerField} in the left running footer on each page where there
% is a response box.
%    \begin{macrocode}
\newcommand\autoAnswerField{%
  \@ifundefined{lfooter}{\def\eq@next{\eq@autoAnswerFieldgobble}%
  \PackageError{exerquiz}{The \string\autoAnswerField\space
    command\MessageBreak requires the web package}{Use web package}
  }{%
    \PackageInfo{exerquiz}{%
    For this auto answer field feature to run\MessageBreak
    the webheadings pagestyle of the web package\MessageBreak
    is required}\def\eq@next{\eq@autoAnswerField}%
    \ifx\web@lfoot\@empty\else
    \PackageWarning{exerquiz}{The left running footer already in
    use\MessageBreak Will overwrite what is there now.
    Better fix it.}\fi
  }%
  \eq@next}
\newcommand\eq@autoAnswerFieldgobble[1][]{\relax}
\newcommand\autoAnsFldRaiseBox[1]{\def\ef@aAFRB{#1}}
\autoAnsFldRaiseBox{0pt}
\let\autoAFOpts\@empty
\newcommand\eq@autoAnswerField[1][]{\gdef\autoAFOpts{#1}%
  \def\eq@insertAnswerField{\AnswerField[#1]{\currQuiz}}%
  \eq@@autoAnswerField}
\newcommand\eq@@autoAnswerField{\lfooter{\ifIsRespBox
  \raisebox{\ef@aAFRB}{\eq@insertAnswerField}%
  \global\IsRespBoxfalse\fi}}
\newcommand\manualAnswerField[1][\autoAFOpts]{%
  \expandafter\AnswerField\expandafter[#1]{\currQuiz}}
%    \end{macrocode}
%    \end{macro}
% Now let's define some additional text fields for the quiz environment.
%    \begin{macro}{\PointsField}
% This command creates a text field which displays the number of points in the
% quiz scored by the user of the \texttt{quiz}.
%    \begin{macrocode}
\def\PointsFieldDefaults{%
  \rawPDF{}\BC{1 0 0}\BG{}\W{1}\S{S}\Ff{\FfReadOnly}}
\newcommand\PointsField[2][]{%
  \mbox{\text@@Field{#1}{PointsField.#2}{\PtFW}%
    {\DefaultHeightOfWidget}{}{\eq@setWidgetProps\eq@TextField}%
    {\PointsFieldDefaults\every@eqTextField\every@PointsField}}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\PercentField}
% This command creates a text field which displays user's score in percent
% form.
%    \begin{macrocode}
\def\PercentFieldDefaults{%
  \rawPDF{}\BC{1 0 0}\BG{}\W{1}\S{S}\Ff{\FfReadOnly}}
\newcommand\PercentField[2][]{%
  \mbox{\text@@Field{#1}{PercentField.#2}{\PcFW}%
    {\DefaultHeightOfWidget}{}{\eq@setWidgetProps\eq@TextField}%
    {\PercentFieldDefaults\every@eqTextField\every@PercentField}}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\RestoreScoreField}
% Reset the score field to its default, in case some author
% changed things.
%    \begin{macrocode}
\newcommand\RestoreScoreField{%
  \global\let\eqScore\eq@Score
  \global\let\eqOutOf\eq@OutOf}
%    \end{macrocode}
%    \end{macro}
%
% \subsection{Floating and Docking a Quiz}
%
%    \begin{macro}{\DeclareQuiz}
%   A convenience macro for setting the name of the quiz. This command defines the
%   text macro \cs{currQuiz} which contains the quiz name. Can be used in conjunction
%   with \cs{floatQuiz} and \cs{startQuizHere}.
% \changes{v6.05c}{2006/05/19}
% {
%   Added a convenience macro for setting the name of the quiz. This command defines the
%   text macro \string\cs{currQuiz} which contains the quiz name. Can be used in conjunction
%   with \string\cs{floatQuiz} and \string\cs{startQuizHere}.
% }
% \changes{v8.1k}{2018/02/04}{Added \string\cs{oField} to list in \string\cs{DeclareQuiz}}
%    \begin{macrocode}
\def\DeclareQuiz#1{\edef\oField{#1}%
    \edef\thisQuiz{#1}\edef\curr@quiz{#1}%
    \edef\currQuiz{#1}}
\let\Quiz\DeclareQuiz
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\floatQuiz}
%    \begin{macro}{\dockQuiz}
% Use \cs{floatQuiz} to create commands \cs{startQuizHere} and \cs{endQuizHere}. These commands expand to the
% `Begin Quiz' button or link (`End Quiz' button or link).  But these commands can be placed anywhere before the
% \texttt{quiz} environment (after the \texttt{quiz} environment). Use \cs{dockQuiz} to return to the default behavior of the
% \texttt{quiz} environment.
% \changes{v6.05c}{2006/05/19}
% {
%   Added \string\cs{floatQuiz}, \string\cs{dockQuiz} and \string\cs{startQuizHere} to start a quiz in an
%   arbitrary place prior to the beginning of the quiz.
% }
%\par\medskip\noindent Usage:
%\begin{verbatim}
%\DeclareQuiz{myQuiz}
%\floatQuiz
%........
%\begin{center}
%\startQuizHere
%\end{center}
%....
%\begin{quiz*}{\thisQuiz}
%....
%\end{quiz*}
%....
%\endQuizHere
% ...
%\docQuiz
%\begin{quiz}{anotherQuiz}
%....
%\end{verbatim}
%    \begin{macrocode}
\def\aeb@noindgobble{\noindent\@gobbletwo}
\let\startQuizHere\relax
\let\endQuizHere\relax
\let\dockQuiz\relax
\newcommand\floatQuiz{%
  \global\let\eq@beginQuiz@saved\eq@beginQuiz
  \global\let\eq@endQuiz@saved\eq@endQuiz
  \global\let\startQuizHere\eq@beginQuiz
  \global\let\endQuizHere\eq@endQuiz
  \global\let\eq@beginQuiz\aeb@noindgobble
  \global\let\eq@endQuiz\@empty
  \global\let\dockQuiz\eq@dockQuiz
}
\newcommand\eq@dockQuiz{%
  \global\let\eq@beginQuiz\eq@beginQuiz@saved
  \global\let\eq@endQuiz\eq@endQuiz@saved
  \global\let\startQuizHere\relax
  \global\let\endQuizHere\relax
  \global\let\eq@beginQuiz@saved\relax
  \global\let\eq@endQuiz@saved
  \global\let\dockQuiz\relax
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%
% \subsection{\texorpdfstring{\protect\cs{titleQuiz} and \protect\cs{fancyQuizHeaders}}
%   {\textbackslash{titleQuiz} and \textbackslash{fancyQuizHeaders}}}
%
%    \begin{macro}{\fancyQuizHeaders}
%    \begin{macro}{\restoreDefaultQuizHeaders}
%    \begin{macro}{\dfltFncyQHdrsFmt}
%    \begin{macro}{\dclrFncyQzHdrsFmt}
%    \begin{macro}{\dclrFncySqHdrsFmt}
% The commands for \cs{fancyQuizHeaders}: \cs{restoreDefaultQuizHeaders} restores
% solution headers to the old style; \cs{eq@fancyQuizHeadersfmt} determines the
% formatting for quizzes; and \cs{eq@fancyShrtQuizHeadersfmt} does the same for
% short quizzes.
%    \begin{macrocode}
\def\fancyQuizHeaders{%
  \global\let\eq@sqsllabel@fancy@save\eq@sqsllabel
  \gdef\eq@sqsllabel{\eq@fancyQuizHeaders}}
\def\eq@fancyQuizHeaders{%
  \if\eqQuizType\isQZ\expandafter\eq@fancyQuizHeadersfmt\else
  \expandafter\eq@fancyShrtQuizHeadersfmt\fi}
\let\eq@sqsllabel@fancy@save\@empty
%    \end{macrocode}
% We set \cs{eq@sqsllabel} back to its value when \cs{fancyQuizHeaders} was last
% invoked.
%    \begin{macrocode}
\def\restoreDefaultQuizHeaders{%
  \global\let\eq@sqsllabel\eq@sqsllabel@fancy@save}
%    \end{macrocode}
% Here is the definition of the format for quizzes. This can be redefined, a few
% suggestions are made in the documentation. \DescribeMacro{\dfltFncyQHdrsFmt}
% \cmd{\dfltFncyQHdrsFmt} is the common format for both \texttt{quiz} and \texttt{shortquiz}.
%    \begin{macrocode}
\newcommand\fncyQHdrsColor{blue}
%    \end{macrocode}
%    (2016/12/21) Localized some text strings in \cs{dfltFncyHdrsFmt}.
%    \changes{v7.8c}{2016/12/21}{Localized some text strings in \string\cs{dfltFncyHdrsFmt}}
%    \begin{macrocode}
\newcommand\FncyHdrsFmtNoTitleQuiz{Solution to Quiz:}
\newcommand\FncyHdrsFmtQuestion{Question}
\newcommand\dfltFncyQHdrsFmt{%
  \protect\bfseries\protect\color{\fncyQHdrsColor}%
  \ifx\aebTitleQuiz\@empty
  \ifnum\@eqquestiondepth>0\relax\FncyHdrsFmtNoTitleQuiz\fi
  \else\aebTitleQuiz:\ifnum\@eqquestiondepth=0\else\protect\ %
  \FncyHdrsFmtQuestion\fi\fi\ifcase\@eqquestiondepth
  \ifx\aebTitleQuiz\@empty\FncyHdrsFmtNoTitleQuiz\fi
  \or\space\arabic{eqquestionnoi}.%
  \or\space\arabic{eqquestionnoi}(\alph{eqquestionnoii})%
  \or\space\arabic{eqquestionnoi}(\alph{eqquestionnoii})%
    (\roman{eqquestionnoiii})\fi}
%    \end{macrocode}
% \DescribeMacro{\dclrFncyQzHdrsFmt}\cmd{\dclrFncyQzHdrsFmt} is used to declare the formatting for quizzes.
%    \begin{macrocode}
\newcommand\dclrFncyQzHdrsFmt[1]{%
    \def\eq@fancyQuizHeadersfmt{{#1}}%
}
\dclrFncyQzHdrsFmt{\dfltFncyQHdrsFmt}
%    \end{macrocode}
% \DescribeMacro{\dclrFncySqHdrsFmt}\cmd{\dclrFncySqHdrsFmt} is for short quizzes, we make the formatting the same as that for quizzes.
% re-defined.
%    \begin{macrocode}
\newcommand\dclrFncySqHdrsFmt[1]{%
    \def\eq@fancyShrtQuizHeadersfmt{{#1}}%
}
\dclrFncySqHdrsFmt{\dfltFncyQHdrsFmt}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\titleQuiz}
%    \begin{macro}{\titleQuizfmt}
%    \begin{macro}{\ifQuizType}
%    \begin{macro}{\ifstaroption}
%    \begin{macro}{\eq@ifstaroption}
% The \cs{titleQuiz} command adds a title to the quiz or short quiz, using
% a format, as defined in \cs{titleQuizfmt}. The switches \cs{ifQuizType}
% and \cs{eq@ifstaroption} allows you to distinguish between quizzes and
% short quizzes, a \texttt{*} option or non-\texttt{*} option.
%
%\cs{titleQuiz} takes two parameters: an optional \texttt{*} and the
%text for the title of the quiz. When \texttt{*} is used---for short
%quizzes only---the title of the quiz is used for the definition of
%\cs{sqlabel}. Note that \cs{makeatletter} is invoked before the
% parameters are read.
% \changes{v6.7o}{2013/11/25}{Changed \string\cs{aeb@@titleQuzi} to \string\cs{aebTitleQuiz}}
% \changes{v6.7p}{2013/12/11}{Added optional parameter to \string\cs{titleQuiz}
%   to execute a command, such as incrementing a counter.}
%    \begin{macrocode}
\let\tqhspace\space
\newcommand\titleQuiz[1][]{#1\@titleQuizi}
\def\@titleQuizi{\makeatletter
    \@ifstar{\def\eq@tq@star{*}\eq@titleQuiz}%
{\def\eq@tq@star{x}\eq@titleQuiz}}
\def\eq@titleQuiz#1{%
  \gdef\aebTitleQuiz{#1}\def\@currentlabelname{#1}%
  \gdef\aeb@@titleQuiz{#1}%
  \gdef\aebtitleQuiz{\mbox{\titleQuizfmt{#1}}\tqhspace}%
\makeatother}
%</package>
%<package|eqexam>\let\aebtitleQuiz\@empty
%<package|eqexam>\let\aebTitleQuiz\@empty
%<*package>
%    \end{macrocode}
% The command to format the \cs{titleQuiz}.
%    \begin{macrocode}
\newcommand\titleQuizfmt{\bfseries}
%    \end{macrocode}
% A user interface to distinguish between quizzes and short quizzes.
%    \begin{macrocode}
\def\ifQuizType#1#2{\if\eqQuizType\isQZ\def\qt@next{#1}%
    \else\def\qt@next{#2}\fi\qt@next}
%    \end{macrocode}
% Used to distinguish between whether \cs{titleQuiz} was invoked with
% the \texttt{*} option. In the short quiz environment, this command
% is let equal to \cs{ifstaroption}, which is the user-access to this command.
% Outside the \texttt{shortquiz} environment, \cs{ifstaroption} is \cs{@gobbletwo}
%    \begin{macrocode}
\def\eq@ifstaroption#1#2{\if\eq@tq@star*\def\sq@next{#1}%
  \else\def\sq@next{#2}\fi\sq@next}
\let\eq@tq@star\relax
\def\ifstaroption{\PackageWarning{exerquiz}
  {\protect\ifstaroption\space is only defined within the\MessageBreak
  shortquiz environment. Gobbling up its two\MessageBreak
  arguments, sorry. This occurred}%
  \@gobbletwo}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%
% \subsection{Showing Partial Credit Markup}
%
%    \begin{macro}{\aeb@creditmarkup}
%    \begin{macro}{\aeb@creditmarkupfmt}
%    \begin{macro}{\ptsLabel}
%    \begin{macro}{\ptLabel}
%    \begin{macro}{\hideCreditMarkup}
%    \begin{macro}{\showCreditMarkup}
% \cs{showCreditMarkup} will show points assigned to individual questions in a quiz.
% \cs{showCreditMarkup} turns off this feature. Should be placed before the next quiz,
% not within a quiz. The command \cs{multipartquestion} is placed just prior to a question
% that introduces a problem with sub-parts. See the demo file \texttt{pc\_test.tex} for examples.
% The other two commands \cs{aeb@creditmarkup} and \cs{aeb@creditmarkupfmt} can be redefined
% to suite your tastes.
%
%\changes{v6.2c}{2007/11/14}
%{
%  Added the commands \string\cs{showCreditMarkup} and \string\cs{hideCreditMarkup} to show partial credit markup
%}
%\changes{v6.3k}{2008/01/09}
%{
%  Added \string\cs{ptsLabel} and \string\cs{ptLabel} to localize the markup in the margin of a quiz
%}
%    \begin{macrocode}
\newcounter{qMarkCnt}
%    \end{macrocode}
% When a question has multi-parts, use \DescribeMacro{\multipartquestion}\cs{multipartquestion} to suppress
% the partial credit markup.
%    \begin{macrocode}
\def\multipartquestion{\global
  \let\aeb@multipart\eq@One
}
%    \end{macrocode}
% The default is that a question does not have multiple parts, use \DescribeMacro{\nopartquestion}\cs{nopartquestion}
% to return to this detault after a \cs{multipartquestion} has been expanded.
% \changes{v8.8.4}{2021/10/02}{Define \string\cs{nopartquestion} to recover from
% \string\cs{multipartquestion}}
%    \begin{macrocode}
\def\nopartquestion{\global
  \let\aeb@multipart\eq@Zero
}
\let\aeb@multipart\eq@Zero
%    \end{macrocode}
% The labeling for the partial credit markup. These two commands are
% are defined (identically) in the \textsf{eqexam} package, hence the
% use of \cs{providecommand}.
%    \begin{macrocode}
\providecommand{\ptsLabel}[1]{\def\eqptsLabel{#1}}\ptsLabel{pts}
\providecommand{\ptLabel}[1]{\def\eqptLabel{#1}}\ptLabel{pt}
%    \end{macrocode}
% \DescribeMacro{\pcMarkupColor} is the named color in RGB color space to
% use for the color of the partial credit markup. (2013/09/14).
%    \begin{macrocode}
\newcommand\pcMarkupColor{red}
%    \end{macrocode}
% \cs{aeb@creditmarkup} creates a small text fields that holds the partial
% credit markup. The command may be redefined, perhaps to changes the dimensions
% of the rectangular bounding box, set at \texttt{12bp} by \texttt{8bp}.
%
% We supply basic controls for the text field, width (\DescribeMacro{\markupWidth}\cmd\markupWidth),
% height (\DescribeMacro{\markupHeight}\cmd{\markupHeight}), and text size
% (\DescribeMacro{\markupTextSize}\cmd{\markupTextSize})
%    \begin{macrocode}
\def\markupWidth{12bp}\def\markupHeight{8bp}\def\markupTextSize{0}
%    \end{macrocode}
% \cmd\aeb@creditmarkup creates the text field that appears in the margins.
%    \begin{macrocode}
\newcommand{\aeb@creditmarkup}{%
  \textField[\Ff\FfReadOnly\BC{}\F\FHidden
  \textColor{\pcMarkupColor}\textSize{\markupTextSize}\autoCenter{n}%
  \DV{0 \eqptsLabel}\V{0 \eqptsLabel}]%
  {qMark.\currQuiz.\thequestionno.\arabic{qMarkCnt}}%
  {\markupWidth}{\markupHeight}%
}
%    \end{macrocode}
% The \cs{showCreditMarkup} command defines \cs{qMark} and \cs{qMark@Hook}.
%    \begin{macrocode}
\def\showCreditMarkup{%
%    \end{macrocode}
% \cs{qMark} makes the decision whether to place a mark or not. If
% the command \cs{multipartquestion} has been expanded, \cs{aeb@multipart} is one, otherwise
% it is zero. If zero we do place the markup, otherwise, no.
%    \begin{macrocode}
  \def\qMark{\if\aeb@multipart\eq@Zero\aeb@creditmarkup
  \stepcounter{qMarkCnt}\else\nopartquestion\fi}%
%    \end{macrocode}
% \cs{qMark@Hook} is a hook that is normally \cs{@empty}. The hook is strategically
% placed at the beginning of each question \cs{item}. Here we define it to be
% \cs{aeb@creditmarkupfmt}.
%    \begin{macrocode}
  \def\qMark@Hook{\aeb@creditmarkupfmt}}
%    \end{macrocode}
% Turn off partial credit markup by putting \cs{qMark@Hook} back to its default.
%    \begin{macrocode}
\def\hideCreditMarkup{\global\let\qMark@Hook\@empty}
%    \end{macrocode}
% A simple command to place the \cs{qMark} in a \cs{makebox[0pt][r]}, with
% a little adjustment to please the eye.
%    \begin{macrocode}
\newcommand{\aeb@creditmarkupfmt}{\makebox[0pt][r]{\qMark\hspace{-2bp}}}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%\subsection{Filtering solutions to quizzes}
% The \cs{eqQt} and \cs{eqSQt} commands have one argument designed to be used to filter
% solutions to quizzes. The demo document is \texttt{filter\_quizzes.tex},
% but basically, we can include the solutions several times, once for each set filtered set.
%    \begin{macrocode}
\long\def\gobbleToEndQt#1\endeqQt{\ifeqforpaper\expandafter\@gobble\fi}
\long\def\gobbleToEndSQt#1\endeqSQt{%
  \ifeqforpaper\expandafter\@gobble\fi}
%    \end{macrocode}
% The \DescribeMacro{\inclQtFilter}\cmd{\inclQtFilter} operates on the quizzes. If the argument \texttt{\#1}
% matches the optional argument of \cs{filterFor}, we include, otherwise, we gobble
% up everything to the end of the quiz, including the token that follows
% \cmd{\gobbleToEndQt}.
%    \begin{macrocode}
\newcommand\inclQtFilter[1]{\def\eqarg{#1}\ifx\eqarg\eqFilterArg
  \else\expandafter\gobbleToEndQt\fi}
%    \end{macrocode}
% The \DescribeMacro{\exclQt}\cmd{\exclQt} command exclude all quiz solutions.
%    \begin{macrocode}
\newcommand{\exclQt}[1]{\gobbleToEndQt}
%    \end{macrocode}
% The \DescribeMacro{\useQtFilter}\cmd{\useQtFilter} command \cs{let}s \cs{eqQt} to
% \cs{inclQtFilter}, and it also \cs{let}s \cs{eqSQt} to
% \cs{exclSQt}.
%    \begin{macrocode}
\newcommand{\useQtFilter}{\let\eqQt\inclQtFilter
  \let\eqSQt\exclSQt}
%    \end{macrocode}
% Now we repeat the same sequence of construct for short quizzes.
%  The command \DescribeMacro{\inclSQtFilter}\cmd{\inclSQtFilter} includes a short quiz
% solution if it meets the filter criteria.
%    \begin{macrocode}
\newcommand\inclSQtFilter[1]{\def\eqarg{#1}\ifx\eqarg\eqFilterArg
  \else\expandafter\gobbleToEndSQt\fi}
%    \end{macrocode}
% The \DescribeMacro{\exclSQt}\cmd{\exclSQt} command excludes all short quiz solutions.
%    \begin{macrocode}
\newcommand{\exclSQt}[1]{\gobbleToEndSQt}
%    \end{macrocode}
% The \DescribeMacro{\useSQtFilter}\cmd{\useSQtFilter} \cs{let}s \cs{eqSQt} to
% \cs{inclSQtFilter}.
%    \begin{macrocode}
\newcommand{\useSQtFilter}{\let\eqSQt\inclSQtFilter\let\eqQt\exclQt}
%    \end{macrocode}
%
%\section{Bookmarking the Quizzes}
%
%    \begin{macro}{\sqbookmarkfmt}
%    \begin{macro}{\qzbookmarkfmt}
%    \begin{macro}{\quizpdfbookmark}
% Support for bookmarking the quizzes and shortquizzes. Unlike the bookmarking
% of the exercises, there is  no support for bookmarking individual questions
% within a quiz.
%\changes{v6.2a}{2007/11/10}
%{
%   Added \string\cs{quizpdfbookmark} to bookmark quizzes.
%}
%    \begin{macrocode}
\newcommand{\sqbookmarkfmt}{Short Quiz \@shortquizCnt.\space}
\newcommand{\qzbookmarkfmt}{Quiz \@quizCnt.\space}
\newcommand{\quizpdfbookmark}[1]{\relax\def\argi{#1}%
  \if\eqQuizType\isSQZ\edef\aeb@bmmrkdest{sqbm.\@shortquizCnt}%
  \def\aeb@thisbkmrkfmt{\sqbookmarkfmt}\else
  \edef\aeb@bmmrkdest{qzbm.\@quizCnt}%
  \def\aeb@thisbkmrkfmt{\qzbookmarkfmt}\fi
  \def\quizpdfbookmarktitle{#1}%
  \def\eqex@next{\belowpdfbookmark{\aeb@thisbkmrkfmt#1}%
    {\aeb@bmmrkdest}}%
  \ifx\aebTitleQuiz\@empty\else\ifx\argi\@empty
    \def\quizpdfbookmarktitle{\aebTitleQuiz}%
    \def\eqex@next{\belowpdfbookmark{\aebTitleQuiz}%
    {\aeb@bmmrkdest}}\fi\fi
  \eqex@next\ignorespaces
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% \section{Multiple Choice Alternatives}
% \subsection{For \texttt{shortquiz}}
% \subsubsection{The \texttt{answers} Environment}
%    \begin{macro}{answers}
% The alternatives of a multiple choice question are enclosed in
% the \texttt{answers} environment.
% This environment takes an optional argument, and one
% required argument.  The required parameter is the number of
% columns to  construct in the underlying \texttt{tabular}
% environment; the presence of the optional argument means the author
% wants to include the solution to this quiz question.  The value of
% the optional parameter is the named destination of the solution.
% The optional parameter for the named destination can also be a
% `\texttt*', in which case a name of \texttt{\string\curr@quiz.\string\thequestionno}
% is assigned.
%    \begin{macrocode}
% Begin joint package and eqexam
%</package>
%<*package|eqexam>
\def\pushEnvir{\xdef\eq@currenvir{\@currenvir}\endgroup}
\def\popEnvir{\begingroup\@endpefalse
    \edef\@currenvir{\eq@currenvir}%
    \edef\@currenvline{\on@line}%
}
\def\answers@sq{\parindent0pt
%    \end{macrocode}
% The \texttt{answers} environment needs to go into horizontal mode for the
% \cs{linelength} to be correct when using \cs{leadinitem}.
%    \begin{macrocode}
  \ifx\solutionparshape\@empty\else
    \pushEnvir\par\noindent\expandafter\popEnvir\fi
  \stepcounter{questionno}%
  \if\sqstar*\relax
    \if\aeb@FLOverride\eq@l
      \let\@Ans\Ans@sq@l\else
      \let\@Ans\Ans@sq@f\fi
  \else
    \if\aeb@FLOverride\eq@f
      \let\@Ans\Ans@sq@f\else
      \let\@Ans\Ans@sq@l\fi
  \fi
  \def\aeb@answerType{r}\@ifnextchar[{\answers@@sq}%
  {\@ifstar{\answers@@sq[\curr@quiz.\thequestionno]}{\answers@@sq[]}}}
\def\manswers@sq{\parindent0pt
%    \end{macrocode}
% \cs{ifuserectforms} is defined in \textsf{eqexam},
%    \begin{macrocode}
    \@ifundefined{ifuserectforms}{}
        {\if\aeb@FLOverride\eq@f\ifuserectforms
            \useRectForMC\else\useCircForMC\fi\fi}%
    \ifx\solutionparshape\@empty\else
        \pushEnvir\par\noindent\expandafter\popEnvir\fi
    \stepcounter{questionno}%
    \if\sqstar*\relax
        \if\aeb@FLOverride\eq@l
        \let\@Ans\Ans@ck@sq@l\else
        \let\@Ans\Ans@ck@sq@f\fi
    \else
        \if\aeb@FLOverride\eq@f
            \let\@Ans\Ans@ck@sq@f\else
            \let\@Ans\Ans@ck@sq@l\fi
    \fi
    \def\aeb@answerType{c}\@ifnextchar[{\answers@@sq}%
    {\@ifstar{\answers@@sq[\curr@quiz.\thequestionno]}{\answers@@sq[]}}}
%    \end{macrocode}
%    \end{macro}
%\begin{verbatim}
% #1 = named destination to be associated with solution
% #2 = number of columns in the tabular environment
%\end{verbatim}
% If the number of columns specified, then we use a list environment.
%    \begin{macrocode}
\let\sq@hwdest\@empty % hard-wired destination
\def\answers@@sq[#1]#2{%
  \xdef\aeb@numCols{#2}%
  \ifx\sq@hwdest\@empty
    \xdef\@qzsolndest{#1}\else
    \gdef\@qzsolndest{\sq@hwdest}\fi
  \if\aeb@numCols1\gdef\eq@listType{1}\expandafter\answers@sq@list
  \else
      \gdef\eq@listType{0}\expandafter\answers@@sq@tabular
  \fi{\aeb@numCols}}
%    \end{macrocode}
%    \begin{macro}{\setMClabelsep}
% \changes{v6.05e}{2006/18/06 v6.05e}
% {
%   Added control over the separation between the MC label and subsequent text:
%   \string\cs{setMClabelsep} and \string\cs{resetMClabelsep}.
% }
%    \begin{macro}{\resetMClabelsep}
%    \begin{macro}{\eq@hspanner}
%    \begin{macro}{\eq@hspanner@default}
% Some convenience macros for computing the width of labels. The command \cs{setMClabelsep}
% can be used to set the separation between the MC label and the beginning of text.  The
% argument for this command is anything that takes up horizontal space. The command sets
% the value of \cs{eq@hspanner}. The default value % of the separation is given by \cs{eq@hspanner@default}.
% The default value can be restored by executing \cs{resetMClabelsep}.
%    \begin{macrocode}
\def\setMClabelsepDefault#1{\def\eq@hspanner@default{#1}}
\def\setMClabelsep#1{\def\eq@hspanner{#1}}
\setMClabelsep{\ }\setMClabelsepDefault{\ }
\def\resetMClabelsep{\expandafter\setMClabelsep\expandafter
  {\eq@hspanner@default}}
\def\eq@lw@l{\eq@l@l\eq@hspanner}
%    \end{macrocode}
% For the link-style MC question, the default width, \cs{eq@l@l}, of the label is the normalsize width of
% `(d)'. For a form checkbox or radiobutton, the default width, \cs{eq@lw@f}, is \cs{RadioFieldSize},
% normally defined as \texttt{11bp}.
%    \begin{macrocode}
\def\eq@l@l{\normalsize\normalfont(d)}
\def\eq@lw@f{\kern\RadioFieldSize\eq@hspanner}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% This macro will pick up the arguments of the \cs{Ans} command.
%\begin{verbatim}
% [#1] = points to be awarded if problem is false (partial credit)
%  #2  = 1 (for true) or 0 (for false)
%\end{verbatim}
% In a list, each time the \cs{item} is executed, \cs{@Ans}
% is executed as the default label.
%
% These parameters are saved in the commands \cs{eq@pPTs} and
% \cs{Ans@choice}.
%    \begin{macrocode}
\@ifundefined{ifwithinsoldoc}{\newif\ifwithinsoldoc\withinsoldocfalse}{}
\@ifundefined{ifwithinqsldoc}{\newif\ifwithinqsldoc\withinqsldocfalse}{}
\let\eq@ansChoiceArray\@empty
\def\eq@recordAnsChoice{%
  \ifx\eq@ansChoiceArray\@empty
    \edef\tmp@exp{\noexpand\g@addto@macro
      \noexpand\eq@ansChoiceArray{"\alph{quizno}"}}\else
    \edef\tmp@exp{\noexpand\g@addto@macro
      \noexpand\eq@ansChoiceArray{,"\alph{quizno}"}}\fi
  \tmp@exp}
\newcommand\Ans@list[2][0]{\gdef\eq@pPTs{#1}\xdef\Ans@choice{#2}%
  \item\relax\noindent\if\eq@listType\eq@One
  \addtocounter{quizno}{-1}\@ifundefined{ifwithinsoldoc}
    {\refstepcounter{quizno}}{\ifwithinsoldoc\stepcounter{quizno}\else
    \refstepcounter{quizno}\fi}\fi
    \ignorespaces}
%    \end{macrocode}
% Answers environment for a list environment.
%    \begin{macrocode}
\newenvironment{answers@sq@list}[1]{%
  \ifx\aeb@answerType\eq@r
    \let\endanswers\endanswers@sq@list\else
    \let\endmanswers\endanswers@sq@list\fi
  \list{\strut\@Ans}{%
%    \end{macrocode}
% Save the natural width of the line, then readjust the
% width if \cs{@nsLineWidth} is not empty.
%    \begin{macrocode}
    \edef\natlinewidth{\the\linewidth}% dps21-5-17
    \ifx\@nsLineWidth\@empty\else % dps21-5-17
      \setlength{\linewidth}{\@nsLineWidth}\fi
    \if\sqstar*\relax
      \settowidth{\labelwidth}{\eq@lw@f}\else
      \settowidth{\labelwidth}{\eq@lw@l}\fi
%    \end{macrocode}
%    (2013/05/17) Incorporated \cs{aboveanswersSkip} into \cs{topsep}
%    \begin{macrocode}
    \setlength{\topsep}{-\parskip+\aboveanswersSkip}%
    \setlength{\parsep}{0pt}\setlength{\itemindent}{0pt}%
%    \end{macrocode}
%    (2014/04/05) Added a specification for \cs{itemsep} so that the
% \cs{rowsep} acts identically for tabular and list.
%    \begin{macrocode}
    \setlength{\itemsep}{0pt}\setlength{\partopsep}{0pt}%
    \setlength{\listparindent}{\parindent}%
%    \end{macrocode}
%    (2013/05/17) When inside the parts environment in tabular-mode,
%    we need to add in \cs{eqemargin}. For \textsf{exerquiz} defaults
%    to 0pt; when \textsf{eqexam} is used, it has a nonzero value.
%    \begin{macrocode}
    \ifnum\exerwparts@cols>1\relax
      \ifx\itsExerParts\eq@YES
        \setlength{\leftmargin}{\labelwidth}\else
        \setlength{\leftmargin}{\labelwidth+\eqemargin}\fi
    \else
%    \end{macrocode}
%    (2013/05/17) Some adjustments depending on whether \cs{solutionparshape}
%    is empty or not. If empty, \cs{leftmargin} is its usual value; otherwise
%    we add in \cs{eqemargin} (0pt in \textsf{exerquiz}, nonzero in \textsf{eqexam}).
%    \begin{macrocode}
      \ifx\solutionparshape\@empty
        \setlength{\leftmargin}{\labelwidth}\else
        \setlength{\leftmargin}{\labelwidth+\eqemargin}\fi
    \fi
%    \end{macrocode}
% (2013/10/10) I'm changing the \cs{labelsep}, one definition for \texttt{eqexam}
% another for \texttt{exerquiz}.
% to the following.
%    \begin{macrocode}
% End joint package and eqexam
%</package|eqexam>
%<package>    \setlength{\labelsep}{0pt}%
%<eqexam>     \setlength{\labelsep}{0pt}%
%<*package|eqexam>
    \def\Ans{\Ans@list}%
  }% list
}{\@insertAndHookAtEndEnv\endlist\setcounter{quizno}{0}} % dps21-5-16
%    \end{macrocode}
% Answers environment for a tabular environment. This command picks
% up the arguments of \cs{Ans}, then passes on the \cs{@Ans}
%\begin{verbatim}
% [#1] = points to be awarded if problem is false (partial credit)
%  #2  = 1 (for true) or 0 (for false)
%\end{verbatim}
% These parameters are saved in the commands \cs{eq@pPTs} and
% \cs{Ans@choice}.
%    \begin{macrocode}
\newcommand\Ans@tabular[2][0]{\gdef\eq@pPTs{#1}\xdef\Ans@choice{#2}%
    \leavevmode\@Ans
}
%    \end{macrocode}
%    (2013/05/17) \DescribeMacro{\sqtabsep} sets the \cs{tabsep} between columns.
%    \DescribeMacro{\sqTabPos} \cs{sqTabPos} allows you to set the positioning
%    optional parameter (t,c,b) on the tabular env. The default is no optional parameter.
%    \begin{macrocode}
\newcommand\sqtabsep[1]{\def\eq@argi{#1}\ifx\eq@argi\@empty
    \def\sq@tabsep{1.5pt}\else\def\sq@tabsep{#1}\fi}
\sqtabsep{1.5pt}
\def\sqTabPos#1{\def\sq@TabPos{[#1]}}\sqTabPos{}
\def\answers@@sq@tabular#1{%
  \ifinner
    \ifx\itsExerParts\eq@YES\par\removelastskip
      \removelastparskip\vskip\aboveanswersSkip\fi
    \else\par\removelastskip\removelastparskip
      \vskip\aboveanswersSkip\fi
%    \end{macrocode}
%    (2013/05/17) If within a parts environment in tabular mode, the tab env
%    needs to be shifted over by an amount of \cs{eqemargin}, for
%    \textsf{exerquiz} this is 0pt, nonzero for \textsf{eqexam}.
%    \begin{macrocode}
    \noindent\ifnum\exerwparts@cols>1\relax\parshape=0\fi
    \tabcolsep=0pt
%    \end{macrocode}
%\begin{verbatim}
%   n=#1
%   width=(\linewidth-2*(n-1)*\tabcolsep)/n
%\end{verbatim}
% In the next line, we adjust \cs{linewidth}, \cs{eqemargin} is \texttt{0pt}
% in \textsf{exerquiz} and nonzero otherwise.
%    \begin{macrocode}
%    \end{macrocode}
% Save the natural width of the line, then readjust the
% width if \cs{@nsLineWidth} is not empty.
%    \begin{macrocode}
    \edef\natlinewidth{\the\linewidth}% dps21-5-17
    \ifx\@nsLineWidth\@empty\else % dps21-5-17
      \setlength{\linewidth}{\@nsLineWidth}\fi
    \eq@tmpdima\linewidth
    \@tempcnta#1\relax
% n-1
    \advance\@tempcnta\m@ne\relax
% 2(n-1)
    \multiply\@tempcnta\tw@
    \@tempdima\sq@tabsep\relax
% 2*(n-1)*\eq@partstabcolsep
    \multiply\@tempdima\@tempcnta
% \linewidth-(n-1)*\sq@tabsep
    \advance\eq@tmpdima-\@tempdima
% (\linewidth-(n-1)*\sq@tabsep)/n
    \divide\eq@tmpdima by#1
    \def\Ans{\Ans@tabular}%
    \tabcolsep\sq@tabsep\relax
%    \end{macrocode}
%    (2013/05/17) We allow the position argument (t,b,c). It changed
%    through \cs{sqTabPos} defined above.
%    \begin{macrocode}
    \expandafter\tabular\sq@TabPos{@{}*{#1}{p{\eq@tmpdima}}@{}}}%
%    \end{macrocode}
%    \changes{v7.4}{2015/03/23}{added \string\cs{reset@doendpe}}
%    \DescribeMacro{\reset@doendpe} attempts to restore the \cs{parshape}
%    following a list environment. It appears in several locations, includeing
%    \cs{endanswers}, \cs{endmanswers}, and \cs{setTabulrSolnEnv}.
%    \par\medskip\noindent We begin by saving the core definition of \cs{@doendpe},
%    it is restored after each usage of \cs{reset@doendpe}.
%    \begin{macrocode}
\let\eq@save@doendpe\@doendpe
%    \end{macrocode}
% The argument \texttt{\#1} consists of the \cs{parshape} parameters to be restored
% following the closing of any environment that uses \cs{doendpe}
%    \begin{macrocode}
\def\reset@doendpe#1{\global\eq@scratchtoks=\expandafter{#1}%
    \gdef\@doendpe{\par\@endpetrue\global\let\@doendpe\eq@save@doendpe
        \def\par{\@restorepar
        \expandafter\everypar
            \expandafter{\the\eq@scratchtoks}\par\@endpefalse}%
        \everypar{{\setbox\z@\lastbox}%
            \everypar{}\@endpefalse}\the\eq@scratchtoks
    }%
}
%    \end{macrocode}
%
%    \begin{macro}{\endanswers}
%    Close off \texttt{tabular} environment, and re-initialize the
%    \texttt{quizno} counter. Added \cs{answersEndHook}.
%    \begin{macrocode}
\def\endanswers@sq{\endtabular\setcounter{quizno}{0}%
  \@insertAndHookAtEndEnv % dps21-5-16
  \global\let\@nsLineWidth\@empty % dps21-5-17
  \reset@doendpe{\the\everypar}%
  \ifinner\else%\par
    \removelastskip
%   \removelastparskip
    \vspace{\aboveanswersSkip}\@endpetrue
  \fi
}
\def\endmanswers@sq{\endtabular\setcounter{quizno}{0}%
  \@insertAndHookAtEndEnv % dps21-5-16
  \global\let\@nsLineWidth\@empty % dps21-5-17
  \reset@doendpe{\the\everypar}%
  \ifinner\else%\par
    \removelastskip
%   \removelastparskip
    \vspace{\aboveanswersSkip}\@endpetrue
  \fi
}
\def\popiiictm{\special{CTM: pop pop pop}}
%</package|eqexam>
%<*package>
%    \end{macrocode}
%    \end{macro}
% \subsubsection{Link Style}
%    \begin{macro}{\Ans@sq@l}
% For the link multiple choice type question. The driver independent stuff starts
% here, then goes to |\Ans@sq@l@driver| the rest of the code that depends on the
% driver.
% \changes{v8.8.5}{2021/10/03}{Allow MC in short-quizzes to have check box to dismiss
% alert box.}
%    \begin{macrocode}
\def\sqWrongRespJS{% dpsx
  \ifx\@sqTurnOffAlerts\eq@One%
    OnBlurRespBox(false,"\oField");\r\fi
    this.getField("mc.\curr@quiz.\thequestionno").value="\alph{quizno}";
}
\def\sqRightRespJS{% dpsx
  \ifx\@sqTurnOffAlerts\eq@One%
    OnBlurRespBox(true,"\oField");\r\fi
    this.getField("mc.\curr@quiz.\thequestionno").value="\alph{quizno}";
}
\def\Ans@sq@l@Actions{\A{%
  \if\Ans@choice\eq@One\JS{\sqRightRespJS}
    \ifx\@qzsolndest\@empty\else
      \ifeq@solutionsafter\else
        /Next <</S/GoTo/D(\@qzsolndest)>>
      \fi
    \fi
  \else
    \JS{\sqWrongRespJS\jsR
    \ifx\oField\@empty\else
      updateTally("\oField.\thequestionno");\fi}%
  \fi
}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\def\linkContentFormat{\alph{quizno}}
\def\aebChoiceAltFmt{\noexpand\ifaebshowgrayletters
    \Alph{quizno}\noexpand\else\linkContentFormat\noexpand\fi}
%</package>
%<*eqexam>
\def\aebChoiceAltFmt{\noexpand\ifaebshowgrayletters
    \Alph{quizno}\noexpand\else\linkContentFormat\noexpand\fi}
\def\linkContentFormat{%
    \if\probstar*\Alph{quizno}\else\alph{quizno}\fi}
%</eqexam>
%<*package|eqexam>
\def\linkContentWrapper{(\hfil\linkContentFormat\hfil)}%
\def\Ans@sq@l{\leavevmode
  \if\eq@listType\eq@One\stepcounter{quizno}\else
    \@ifundefined{ifwithinsoldoc}{\refstepcounter{quizno}}
    {\ifwithinsoldoc\stepcounter{quizno}\else
    \refstepcounter{quizno}\fi}\fi\PBS\raggedright
  \settowidth{\eq@tmplength}{\eq@lw@l}\sbox{\eq@tmpbox}{\eq@l@l}%
  \eq@tmpdima=\wd\eq@tmpbox
  \def\link@@Content{\linkContentWrapper}%
  \hangindent=\eq@tmplength\hangafter=1\relax
%</package|eqexam>
%<*eqexam>
  \Ans@sq@l@driver
%</eqexam>
%<*package>
%    \end{macrocode}
% (2021/10/03) Move 0 and 1 to tooltip of underlying radio button that flags
% choice as incorrect and incorrect.
%    \begin{macrocode}
  \if\Ans@choice\eq@One % dpsx
    \def\Ans@c@l@Choice{\TU{1}%
      \BC{}\Ff{\FfReadOnly}}%
    \def\rbf@Opts{\symbolchoice{\sq@corrsymch}%
      \textColor{\sq@corrsymcol}}%
  \else
    \def\Ans@c@l@Choice{\TU{0}\DV{Yes}%
      \Ff{\FfReadOnly}\BC{}}%
    \def\rbf@Opts{\symbolchoice{\sq@wrgsymch}%
      \textColor{\sq@wrgsymcol}}%
  \fi
  \makebox[0pt][l]{\expandafter\radio@@Button\expandafter{\rbf@Opts}%
    {mc.\curr@quiz.\thequestionno}%
%    \end{macrocode}
% (2021/10/03) Remove 0 and 1 from export value radio button
%    \begin{macrocode}
    {\eq@tmpdima}{\RadioFieldSize}{\alph{quizno}}% dpsx
%   {\eq@tmpdima}{\RadioFieldSize}{\Ans@choice\alph{quizno}}%
    {\eq@protect\A}{\eq@setWidgetProps\eq@l@check@driver}%
    {\Ans@r@l@Defaults\every@RadioButton
    \every@qRadioButton}}%
    \set@@Link{}{}{}%
      {\makebox[\eq@tmpdima]{\color{\@linkcolor}\link@@Content}}
      {\eq@protect\A}{\eq@setWidgetProps\setLink@driver}%
      {\set@LinkTextDefaults\Ans@sq@l@Actions\every@Link}%
  \Ans@proofing{\eq@tmpdima}%
%</package>
%<*package|eqexam>
\eq@hspanner\ignorespaces}
%</package|eqexam>
%<*package>
%    \end{macrocode}
%    \begin{macro}{\Ans@ck@sq@l}
% Created in support of eqExam to give multiple selection for the
% online and email options.  Otherwise, it defaults to a radio button field.
%    \begin{macrocode}
\def\Ans@ck@sq@l{\Ans@ck@sq@f}
%</package>
%<*eqexam>
% dps 4/16/05
\let\Ans@ck@sq@l\Ans@sq@l
%</eqexam>
%<*package>
%    \end{macrocode}
%    \end{macro}
% \subsubsection{Form Style}
% \subsubsection{Answers for the \texttt{answers} and \texttt{manswers} Environment}
%    \begin{macro}{\Ans@sq@f}
% For the link multiple choice type question. The driver independent stuff starts
% here, then goes to |\Ans@sq@f@driver| the rest of the code that depends on the
% driver.
% \changes{v7.7d}{2015/11/15}{Changed mc.\string\cs{oFields} so it is printable}
%    \begin{macrocode}
%    \end{macrocode}
%\DescribeMacro{\TUChoice}\hskip-\marginparsep\texttt{\darg{\ameta{text}}} A generic
%tooltip for radio buttons and check boxes for MS and MS questions. The default
%is |\TUChoice{Choice}|.
%\changes{v8.8.5}{2021/10/03}{Added \string\cs{TUChoice}}
%    \begin{macrocode}
\def\TUChoice#1{\def\TU@Choice{#1}}
\TUChoice{Choice}
%    \end{macrocode}
%    \begin{macrocode}
\def\@@Ans@sq@f@Defaults{%
  \BC{0 0 0}\Ff{\FfNoToggleToOff}\W{1}%\F{\FPrint}
  \textSize{12}\textColor{0 g}\TU{\TU@Choice} % dpsx
}
%    \end{macrocode}
% For short-quizzes, refine the type of responses: turn off the alert
% message (the default is on); or have a (red) `\texttt{x}' make an
% incorrect answer, and a (green) check mark a correct answer.
%    \begin{macrocode}
\def\sqTurnOffAlerts{\let\@sqTurnOffAlerts\eq@Zero}
\def\sqTurnOnAlerts{\let\@sqTurnOffAlerts\eq@One}
\sqTurnOnAlerts
%    \end{macrocode}
% This feature was discontinued sometime between version 5.x and 6.x.
%    \begin{macrocode}
\def\sqNoCorrections{\let\@sqAlertsOnly\eq@One}
\def\sqCorrections{\let\@sqAlertsOnly\eq@Zero}
\sqNoCorrections
%    \end{macrocode}
% JavaScript code for the mouse up action for the \emph{correct} choice of the radio button field
% (\texttt{mc.\ameta{fld-name}.\ameta{q-num}}) for the form version of a multiple choice question of a \texttt{shortquiz}.
%    \begin{macrocode}
\begin{defineJS}[\makeesc\*\makecmt\%]{\Ans@sq@f@ActionsTrue}
*ifx*@sqTurnOffAlerts*eq@One%
OnBlurRespBox(true,"*oField");
*fi%
var qzSolnDest="*@qzsolndest";
var solnAfter=*ifeq@solutionsafter%
true*else%
false*fi;
%    \end{macrocode}
%    Introduce changes in this code in response to \cs{sqSolnBtn} command.
%    \changes{v8.7.5}{2021/05/05}{\string\cs{sqSolnBtn} changes: execute block
%    if \string\cs{sqSolnBtn} not detected}
%    \begin{macrocode}
var f=this.getField("corr.*oField.*thequestionno");
if (f==null) {
  if ((qzSolnDest!="") && !solnAfter) %
jmpToNamedDest("*oField","*@qzsolndest",%
  *ifx*@sqTurnOffAlerts*eq@Zero0*else1*fi);%
  *ifx*eqAddAAMouseUpMC*empty*else
  *eqAddAAMouseUpMC*fi
}
\end{defineJS}
%    \end{macrocode}
% JavaScript code for the mouse up action for the \emph{incorrect} choice of the radio button field
% (\texttt{mc.\ameta{fld-name}.q-num}) for the form version of a multiple choice question of a \texttt{shortquiz}.
%    \begin{macrocode}
\begin{defineJS}[\makeesc\*\makecmt\%]{\Ans@sq@f@ActionsFalse}
*ifx*@sqTurnOffAlerts*eq@One%
OnBlurRespBox(false,"*oField");
*fi%
var qzSolnDest="*@qzsolndest";
updateTally("*oField.*thequestionno");%
*ifx*eqAddAAMouseUpMC*empty*else
*eqAddAAMouseUpMC*fi
\end{defineJS}
%    \end{macrocode}
% The actions for the form version of a multiple choice question of a \texttt{shortquiz}.
%    \begin{macrocode}
\def\Ans@sq@f@Actions{\AAmouseup{\if\Ans@choice\eq@One
  \Ans@sq@f@ActionsTrue\else\Ans@sq@f@ActionsFalse\fi}
  \AAmousedown{updateTally.downState=!!event.target.isBoxChecked%
    (\arabic{quizno}-1);}}
\def\Ans@proofing#1{\ifeq@proofing\if\Ans@choice1\relax
  \llap{\@proofingsymbol\,\hskip#1\relax}\fi\fi}
%    \end{macrocode}
%\DescribeMacro{\sqRghtSymbChoice}\DescribeMacro{\sqRghtSymbColor} for the \texttt{shortquiz}
% environment, these first two commands assign the right symbol (default check) and
% color (default webgreen). The second two\DescribeMacro{\sqWrngSymbChoice}\DescribeMacro{\sqWrngSymbColor}
% does the same thing for the wrong answer.
%    \begin{macrocode}
\def\sqRghtSymbChoice#1{\chooseJSsymbol*{#1}%
  \ifx\eq@retnStyle\@empty
  \edef\sq@corrsymch{\sqRghtSymbChoiceDef}\else
  \edef\sq@corrsymch{#1}\fi}
\def\sqRghtSymbColor#1{\edef\eq@arg{#1}\ifx\eq@arg\@empty
  \edef\sq@corrsymcol{\sqRghtSymbColorDef}\else
  \edef\sq@corrsymcol{#1}\fi}
\def\sqWrngSymbChoice#1{\chooseJSsymbol*{#1}%
  \ifx\eq@retnStyle\@empty
  \edef\sq@wrgsymch{\sqWrngSymbChoiceDef}\else
  \edef\sq@wrgsymch{#1}\fi}
\def\sqWrngSymbColor#1{\edef\eq@arg{#1}\ifx\eq@arg\@empty
  \edef\sq@wrgsymcol{\sqWrngSymbColorDef}\else
  \edef\sq@wrgsymcol{#1}\fi}
\def\sqRghtSymbChoiceDef{check}
\def\sqRghtSymbColorDef{0 .6 0 rg}
\def\sqWrngSymbChoiceDef{cross}
\def\sqWrngSymbColorDef{1 0 0 rg}
\edef\sq@corrsymch{\sqRghtSymbChoiceDef}
\edef\sq@corrsymcol{\sqRghtSymbColorDef}
\edef\sq@wrgsymch{\sqWrngSymbChoiceDef}
\edef\sq@wrgsymcol{\sqWrngSymbColorDef}
\def\sqResetSymbToDef{%
  \sqRghtSymbChoice{}\sqRghtSymbColor{}%
  \sqWrngSymbChoice{}\sqWrngSymbColor{}%
}
%    \end{macrocode}
%\DescribeMacro{\qChoiceSymb}\DescribeMacro{\qChoiceColor} for the \texttt{quiz}
% environment, these two commands assign the selection symbol (default check) and the
% color (default webgreen).
%    \begin{macrocode}
\def\qChoiceSymb#1{\chooseJSsymbol*{#1}%
  \ifx\eq@retnStyle\@empty
  \edef\qz@chksymb{\qChoiceSymbDef}\else
  \edef\qz@chksymb{#1}\fi}
\def\qChoiceColor#1{\edef\eq@arg{#1}\ifx\eq@arg\@empty
  \edef\qz@chksymbcol{\qChoiceColorDef}\else
  \edef\qz@chksymbcol{#1}\fi}
\def\qChoiceSymbDef{check}
\def\qChoiceColorDef{0 0 0 rg}
\edef\qz@chksymb{\qChoiceSymbDef}
\edef\qz@chksymbcol{\qChoiceColorDef}
%</package>
%<*package|eqexam>
\let\rbf@Opts\@empty
%    \end{macrocode}
%    The \cs{Ans} for a short-quiz, using forms.
%    \begin{macrocode}
\def\Ans@sq@f{\if\eq@listType\eq@One
  \stepcounter{quizno}\else
  \@ifundefined{ifwithinsoldoc}{\refstepcounter{quizno}}
  {\ifwithinsoldoc\stepcounter{quizno}\else
  \refstepcounter{quizno}\fi}\fi
  \PBS\raggedright
%</package|eqexam>
%    \end{macrocode}
%\changes{v6.7d}{2013/05/27}{added \string\cs{rbf@Opts} to hardwire choices.}
%    \begin{macrocode}
%<*package>
  \if\Ans@choice\eq@One
    \def\rbf@Opts{\symbolchoice{\sq@corrsymch}%
      \textColor{\sq@corrsymcol}}\else
    \def\rbf@Opts{\symbolchoice{\sq@wrgsymch}%
      \textColor{\sq@wrgsymcol}}\fi
%</package>
%<*package|eqexam>
  \settowidth{\eq@tmplength}{\eq@lw@f}%
  \eq@tmpdima=\wd\eq@tmpbox%
  \hangindent=\eq@tmplength\hangafter=1\relax
  \insertGrayLetters
%</package|eqexam>
%<*eqexam>
  \Ans@sq@f@driver
%</eqexam>
%<*package>
  \mbox{\expandafter\radio@@Button\expandafter{\rbf@Opts}%
    {mc.\oField.\thequestionno}%
    {\RadioFieldSize}{\RadioFieldSize}%
    {\alph{quizno}}{\eq@protect\A}%
%   {\Ans@choice\alph{quizno}}{\eq@protect\A}%
    {\eq@setWidgetProps\eq@Radio@driver}%
    {\@@Ans@sq@f@Defaults\Ans@sq@f@Actions\every@RadioButton
     \every@sqRadioButton}}%
  \Ans@proofing{\RadioFieldSize}%
%</package>
%<*package|eqexam>
  \eq@hspanner\ignorespaces}
%</package|eqexam>
%<*package>
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\Ans@ck@sq@f}
% Created in support of \textsf{eqExam} to give multiple selection for the
% online and email options.  Otherwise, it defaults to a radio button field.
%    \begin{macrocode}
%</package>
%<*eqexam>
\let\Ans@ck@sq@f\Ans@sq@f
%</eqexam>
%<*package>
\def\@@Ans@ck@sq@f@Defaults{%
  \BC{0 0 0}\Ff{\FfNoToggleToOff}\TU{\TU@Choice} % dpsx
  \F{\FPrint}\textSize{12}\textColor{0 g}\W{1}
}
\begingroup
\catcode`\&=12
\gdef\eq@AND{&&}
\endgroup
%    \end{macrocode}
%    Mouse up action for a \emph{correct answer box} (a checkbox) to MS question of short-quiz
%    (field name: \texttt{mc.\ameta{fld-name}.\ameta{ques-num}}.\ameta{choice-num})
%    \begin{macrocode}
\begin{defineJS}[\makeesc\*\makecmt\%]{\Ans@ck@sq@f@ActionsTrue}
var fName=event.target.name;
var g=this.getField("mck.*oField.*thequestionno");
var a=g.getArray();
% dpsx
var h=this.getField("mcq.*oField.*thequestionno");
var b=h.getArray();
%    \end{macrocode}
% (2021/10/03) Work with the tooltop of \texttt{mcq} rather than the export value
% of \texttt{mck}.
%    \begin{macrocode}
for (var i=0; i<a.length; i++)
  if ( (a[i].isBoxChecked(0)) && (b[i].userName=="0" ) )
%(a[i].value.charAt(0)==0) )
    a[i].checkThisBox(0,false);%
*ifx*@sqTurnOffAlerts*eq@One
OnBlurRespBox(true,"*oField");*else
*fi%
var qzSolnDest="*@qzsolndest";
var solnAfter=*ifeq@solutionsafter%
true*else%
false*fi;
%    \end{macrocode}
%    Introduce changes in this code in response to \cs{sqSolnBtn} command.
%    \changes{v8.7.5}{2021/05/05}{\string\cs{sqSolnBtn} changes: execute block
%    if \string\cs{sqSolnBtn} not detected}
%    \begin{macrocode}
var f=this.getField("corr.*oField.*thequestionno");
if (f==null) {
  if ( (qzSolnDest != "") && !solnAfter ) {
    for (var i=0; i<a.length; i++){
%     if ((a[i].exportValues[0].charAt(0)==1) && % dpsx %
%    \end{macrocode}
% (2021/10/03) Work with the tooltop of \texttt{mcq} rather than the export value
% of \texttt{mck}.
%    \begin{macrocode}
      if ((b[i].userName=="1") && (!a[i].isBoxChecked(0))) break;
    }
  }
  if (i>=a.length) jmpToNamedDest("*oField","*@qzsolndest",%
  *ifx*@sqTurnOffAlerts*eq@Zero0*else1*fi);%
  *ifx*eqAddAAMouseUpMS*empty*else
  *eqAddAAMouseUpMS*fi
}
\end{defineJS}
%    \end{macrocode}
%    Mouse up action for a \emph{incorrect answer box} (a checkbox) to MS question of short-quiz
%    (field name: \texttt{mc.\ameta{fld-name}.\ameta{ques-num}}.\ameta{choice-num})
%    \begin{macrocode}
\begin{defineJS}[\makeesc\*\makecmt\%]{\Ans@ck@sq@f@ActionsFalse}
var fName=event.target.name;
var g=this.getField("mck.*oField.*thequestionno");
var a=g.getArray();
% dpsx
var h=this.getField("mcq.*oField.*thequestionno");
var b=h.getArray();
for (var i=0; i<a.length; i++) {
%  if (a[i].value.charAt(0)==0) {
%    \end{macrocode}
% (2021/10/03) Work with the tooltop of \texttt{mcq} rather than the export value
% of \texttt{mck}.
%    \begin{macrocode}
  if (b[i].userName=="0") {
  if ( fName != a[i].name )
    a[i].checkThisBox(0,false);
  }
}%
*ifx*@sqTurnOffAlerts*eq@One
OnBlurRespBox(false,"*oField");*fi%
*ifx*oField*@empty*else
updateTally("*oField.*thequestionno");*fi%
*ifx*eqAddAAMouseUpMS*empty*else
*eqAddAAMouseUpMS*fi
\end{defineJS}
%    \end{macrocode}
%    Set all actions for check box for a MS question of a short-quiz
%    (field name: \texttt{mc.\ameta{fld-name}.\ameta{ques-num}}.\ameta{choice-num})
%    \begin{macrocode}
\def\Ans@ck@sq@f@Actions{%
  \AAmouseup{\if\Ans@choice\eq@One
    \Ans@ck@sq@f@ActionsTrue\else
    \Ans@ck@sq@f@ActionsFalse\fi}
  \AAmousedown{updateTally.downState=!!event.target.isBoxChecked(0);}}
%    \end{macrocode}
%    The check boxes to a MS question in an \env{manswers} environment of a short-quiz; the name of this field
%    |mc.\oField.\thequestionno.\arabic{quizno}|.
%    \begin{macrocode}
\def\Ans@ck@sq@f{\if\eq@listType\eq@One
    \stepcounter{quizno}\else
    \@ifundefined{ifwithinsoldoc}{\refstepcounter{quizno}}
    {\ifwithinsoldoc\stepcounter{quizno}\else
    \refstepcounter{quizno}\fi}\fi\PBS\raggedright
  \if\Ans@choice\eq@One
    \def\rbf@Opts{\symbolchoice{\sq@corrsymch}%
      \textColor{\sq@corrsymcol}}\else
    \def\rbf@Opts{\symbolchoice{\sq@wrgsymch}%
      \textColor{\sq@wrgsymcol}}\fi
  \settowidth{\eq@tmplength}{\eq@lw@f}\eq@tmpdima\wd\eq@tmpbox
  \hangindent\eq@tmplength\hangafter\@ne % dps
  \insertGrayLetters % 6.3d
  \mbox{\expandafter\check@@Box\expandafter{\rbf@Opts}%
    {mck.\oField.\thequestionno.\arabic{quizno}}%
    {\RadioFieldSize}{\RadioFieldSize}
    {\alph{quizno}}{\eq@protect\A}%
%   {\Ans@choice\alph{quizno}}{\eq@protect\A}% dpsx
    {\eq@setWidgetProps\eq@Check@driver}%
    {\@@Ans@ck@sq@f@Defaults\Ans@ck@sq@f@Actions\every@CheckBox
     \every@sqCheckBox}}%
  \def\late@options{\BC{}}%
  \if\Ans@choice\eq@One % dpsx
    \eq@addExpandTo\late@options{\TU{1}}\else
    \eq@addExpandTo\late@options{\TU{0}}\fi
  \makebox[0pt][r]{\check@@Box{}% dpsx
    {mcq.\oField.\thequestionno.\arabic{quizno}}%
    {0pt}{0pt}{Yes}{}% \@tempdimb
    {\eq@setWidgetProps\eq@Check@driver}%
    {\Ans@c@f@Defaults\every@RadioButton
     \every@qRadioButton\late@options}}% dpsx
  \Ans@proofing{\RadioFieldSize}\eq@hspanner
  \ignorespaces
}
%    \end{macrocode}
%    \end{macro}
% \subsection{For the \texttt{quiz} environment}
% \subsubsection{The \texttt{answers} and \texttt{manswers} Environment}
%    \begin{macro}{answers}
% This is the answers environment for the \texttt{quiz}
% environment.  The \texttt{quiz} environment states
% \verb+\let\answers=\answers@q+.  This is to avoid a conflict
% with \texttt{shortquiz}, which also as an \texttt{answers}
% environment.
%
% The following parameters are recognized:
%\begin{verbatim}
% [#1]|* = named destination to be associated with solution;
%          with *, the destination is automatically generated
%  #2    = number of columns in the tabular environment
%\end{verbatim}
% If the number of columns is $1$, then we use a list environment,
% else, we use a tabular environment.
%    \begin{macrocode}
%</package>
%<*package|eqexam>
\newskip\aboveanswersSkip
\setlength\aboveanswersSkip{3pt}
%</package|eqexam>
%<*package>
\let\q@hwdest\@empty % hard-wired destination
\let\pointValuesArray\@empty
\newif\ifeqshowmarkup\eqshowmarkupfalse
\newif\ifeqshowOutOf \eqshowOutOffalse
\def\showOutOfinSmryTbl{false}
\def\eq@recordThesePTs{%
  \ifx\pointValuesArray\@empty
  \edef\ptsValue{\showOutOfinSmryTbl,\eqPTs}\else
    \edef\ptsValue{,\eqPTs}\fi
  \expandafter\g@addto@macro\expandafter\pointValuesArray
  \expandafter{\ptsValue}}
%    \end{macrocode}
% \changes{v7.7m}{2016/07/04}{Added \string\texttt{ptypeArray} to track problem types better}
%    \begin{macrocode}
\let\ptypeArray\@empty
\def\eq@recordProbType{%
  \ifx\ptypeArray\@empty
    \edef\tmp@exp{\noexpand\g@addto@macro
      \noexpand\ptypeArray{null,"\eqQT"}}\else
    \edef\tmp@exp{\noexpand\g@addto@macro
      \noexpand\ptypeArray{,"\eqQT"}}\fi
  \tmp@exp
}
\let\corrAnsArray\@empty
\def\eq@recordCorrAns#1{%
  \ifx\corrAnsArray\@empty
    \edef\tmp@exp{\noexpand\g@addto@macro
      \noexpand\corrAnsArray{null,#1}}\else
    \edef\tmp@exp{\noexpand\g@addto@macro
      \noexpand\corrAnsArray{,#1}}\fi
  \tmp@exp
}
\def\aeb@answerType@r{r}
\def\aeb@answerType@c{c}
\newcommand\answers@q{%
  \eq@AddProbToQzQuesList
  \def\aeb@answerType{r}\setdefault@Ans\eq@recordThesePTs
  \eq@recordProbType
  \addtocounter{eqpointvalue}{\eqPTs}\stepcounter{questionno}%
  \def\aeb@thisType{"mc"}\@ifnextchar[{\answers@@q}%
  {\@ifstar{\answers@@q[\curr@quiz.\thequestionno]}{\answers@@q[]}}%
}
\def\answers@@q[#1]#2{\global\let\eq@ansChoiceArray\@empty
  \xdef\aeb@numCols{#2}\edef\eqtmp{\aPointType}%
  \xdef\aPointType{\eqtmp,[\eqPTs,\aeb@thisType]}%
  \ifx\q@hwdest\@empty
    \xdef\@qzsolndest{#1}\else
    \gdef\@qzsolndest{\q@hwdest}\fi
  \ifnum\aeb@numCols=1
  \gdef\eq@listType{1}\expandafter\answers@q@list\else
  \gdef\eq@listType{0}\expandafter\answers@q@tabular\fi{\aeb@numCols}%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{manswers}
% The \texttt{manswers} environment is used for multiple selection questions for the quiz
% environment only. Within this environment, the \cs{Ans} command (\cs{@Ans} actually) is let equal to
% \cs{Ans@ck@f} or \cs{Ans@ck@l} for forms or links respectively. These commands are defined
% in the sections that follow.
% \changes{v6.2}{2007/11/08 }
%{
%   Added the \string\texttt{manswers} environment, and supporting elements, both {\string\LaTeX}
%   and JavaScript. This \string\texttt{manswers} environment is for the \string\texttt{quiz} environment
%   only. There is a \string\texttt{manswers} environment for the \string\texttt{shortquiz} environment, but
%   this is used by \textsf{eqExam} only.
%}
%
% The following parameters are recognized
%\begin{verbatim}
% [#1]|* = named destination to be associated with solution;
%          with *, the destination is automatically generated
%  #2    = number of columns in the tabular environment
%\end{verbatim}
%    \begin{macrocode}
\newcommand\manswers@q{%
  \eq@AddProbToQzQuesList
  \def\aeb@answerType{c}\@setFormLinkType
  \global\expandafter\let\expandafter\@Ans
  \expandafter=\csname Ans@ck@\@@quiztype\endcsname
  \eq@recordThesePTs\eq@recordProbType
  \addtocounter{eqpointvalue}{\eqPTs}\stepcounter{questionno}%
  \def\aeb@thisType{"ms"}\@ifnextchar[{\answers@@q}%
  {\@ifstar{\answers@@q[\curr@quiz.\thequestionno]}{\answers@@q[]}}%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\newenvironment{answers@q@list}[1]{%
  \ifx\aeb@answerType\eq@r
    \let\endanswers\endanswers@q@list\else
    \let\endmanswers\endanswers@q@list\fi
  \list{\strut\@Ans}{%
%    \end{macrocode}
% Save the natural width of the line, then readjust the
% width if \cs{@nsLineWidth} is not empty.
%    \begin{macrocode}
    \edef\natlinewidth{\the\linewidth}% dps21-5-17
    \ifx\@nsLineWidth\@empty\else % dps21-5-17
      \setlength{\linewidth}{\@nsLineWidth}\fi
    \if\qstar*\relax
      \if\aeb@FLOverride\eq@l
      \settowidth{\labelwidth}{\eq@lw@l}\else
      \settowidth{\labelwidth}{\eq@lw@f}\fi
    \else
      \if\aeb@FLOverride\eq@f
      \settowidth{\labelwidth}{\eq@lw@f}\else
      \settowidth{\labelwidth}{\eq@lw@l}\fi
    \fi
    \setlength{\topsep}{-\parskip+\aboveanswersSkip}%
    \setlength{\parsep}{0pt}\setlength{\itemindent}{0pt}%
    \setlength{\listparindent}{\parindent}%
    \setlength{\leftmargin}{\labelwidth}%
    \setlength{\labelsep}{0pt}%
    \def\Ans{\Ans@list}%
  }%
}{\endlist\setcounter{quizno}{0}%
  \@insertAndHookAtEndEnv % dps21-5-17
  \global\let\@nsLineWidth\@empty % dps21-5-17
  \setdefault@Ans
  \ifx\aeb@answerType\aeb@answerType@r
%    \end{macrocode}
% If this is a MC question, we record the author's correct answer
%    \begin{macrocode}
    \eq@recordCorrAns{\eq@ansChoiceArray}\ifwithinMCFI
%    \end{macrocode}
% If within a \cs{bMCFI}/\cs{eMCFI} command pair, we also record
% the author's correct answer.
%    \begin{macrocode}
    \eq@recordCorrAns{\s@veCorrAnsMCFI}\fi\else
%    \end{macrocode}
% If this is a MS question, we record the author's correct answer as an array
%    \begin{macrocode}
    \eq@recordCorrAns{[\eq@ansChoiceArray]}\fi
  \global\let\eqlimselTo\@empty
}
%    \end{macrocode}
%    \begin{macrocode}
\newcommand\qztabsep[1]{\def\eq@argi{#1}\ifx\eq@argi\@empty
    \def\qz@tabsep{1.5pt}\else\def\qz@tabsep{#1}\fi}
\qztabsep{1.5pt}
\def\qzTabPos#1{\def\qz@TabPos{[#1]}}\qzTabPos{}
\def\answers@q@tabular#1{%
  \ifinner\else\par\removelastparskip\vspace{\aboveanswersSkip}\fi
%    \end{macrocode}
% Save the natural width of the line, then readjust the
% width if \cs{@nsLineWidth} is not empty.
%    \begin{macrocode}
  \edef\natlinewidth{\the\linewidth}% dps21-5-17
  \ifx\@nsLineWidth\@empty\else % dps21-5-17
    \setlength{\linewidth}{\@nsLineWidth}\fi
  \eq@tmpdima\linewidth
  \@tempcnta#1\relax
% n-1
  \advance\@tempcnta\m@ne
% 2(n-1)
  \multiply\@tempcnta\tw@
  \@tempdima\qz@tabsep\relax
% 2*(n-1)*\qz@tabsep
  \multiply\@tempdima\@tempcnta
% \linewidth-(n-1)*\qz@tabsep
  \advance\eq@tmpdima-\@tempdima
% (\linewidth-(n-1)*\qz@tabsep)/n
  \divide\eq@tmpdima by#1
  \tabcolsep\qz@tabsep\relax
  \def\Ans{\Ans@tabular}%
  \ifx\aeb@answerType\eq@r
    \let\endanswers\endanswers@q@tabular\else
    \let\endmanswers\endanswers@q@tabular\fi
  \noindent\expandafter
  \tabular\qz@TabPos{@{}*{#1}{p{\eq@tmpdima}}@{}}%
}
%    \end{macrocode}
%    \begin{macro}{\endanswers}
% Again, we put \verb+\let\endanswers=\endanswers@q+.
%    \begin{macrocode}
\def\endanswers@q@tabular{%
  \endtabular\setcounter{quizno}{0}%
  \@insertAndHookAtEndEnv % dps21-5-17
  \global\let\@nsLineWidth\@empty % dps21-5-17
  \setdefault@Ans
  \ifx\aeb@answerType\aeb@answerType@r
%    \end{macrocode}
% If this is a MC question, we record the author's correct answer
%    \begin{macrocode}
    \eq@recordCorrAns{\eq@ansChoiceArray}\ifwithinMCFI
%    \end{macrocode}
% If within the MCFI command pair, we record the author's fill-in as well.
%    \begin{macrocode}
    \eq@recordCorrAns{\s@veCorrAnsMCFI}\fi\else
%    \end{macrocode}
% If this is a MS question, we record the author's correct answer as an array
%    \begin{macrocode}
    \eq@recordCorrAns{[\eq@ansChoiceArray]}\fi
  \global\let\eqlimselTo\@empty
}
%    \end{macrocode}
%    \end{macro}
% \subsubsection{Link Style}
%
%    \begin{macro}{\Ans@l}
% For the forms version of the \texttt{quiz} environment.
% dps 12/19/03 removed the notify because we are not embedding a radio button field
%    \begin{macrocode}
\let\qRadionActionsHook\@empty
\def\Ans@@l@Actions{\A{\JS{%
   this.getField("mc.\curr@quiz.\thequestionno").value\eqSP
      =\eqSP"\alph{quizno}";\jsR
%     =\eqSP"\Ans@choice\alph{quizno}";\jsR // dpsx
   RecordPointValue([0,\eqPTs,\eq@pPTs],\thequestionno);\jsR
   RecordProblemType("\eqQT",\thequestionno);\jsR
   ProcessQuestion(\Ans@choice,"\alph{quizno}",\thequestionno,%
    \arabic{quizno},"\curr@quiz",0,\ifnocorrections0\else1\fi,%
    "\bqlabelISO"\if\eqQuizType\isQZ\ifx\eq@online\eq@YES
    \ifeq@noquizsolutions\else,1\fi\fi\fi);\qRadionActionsHook}}%
}
\def\Ans@r@l@Defaults{%
  \BC{}\S{S}\W{1}\Ff{\FfNoToggleToOff}\F{\FPrint}\TU{\TU@Choice} % dpsx
  \textSize{12}\textColor{0 g}\Ff{\FfReadOnly}
}
%    \end{macrocode}
% (2021/10/03) Changes are needed to radio buttons and checkboxes (Commands: \cs{Ans@l},\cs{Ans@ck@l}, \cs{Ans@@f}, and \cs{Ans@@ck@f})
% of the \env{answers} and \env{manswers} environments. AA/AR has changed the way they display the tooltip: changed
% from `\ameta{tooltip}' to `\ameta{tooltip}\texttt:\,\ameta{export-value}'. Unfortunately, the \ameta{export-value}
% contains code that signals whether this field is a correct choice or not: an export value that begins with a
% one (1) indicates a correct choice, which one that begins with a zero (0) marks an incorrect choice. When the student passes
% his mouse cursor over a choice, he sees `1a' or `0b'; seeing enough of these patterns, their meaning will become known.
%
% The workaround is to move the binary flag to the tooltip of the underlying checkbox, which is readonly, hence,
% there is not over display of this field. In the fields listed above, we insert \cs{TU{1}} or \cs{TU{0}}
% into each of the checkboxes whose names begin with \texttt{mcq}.
%
% The final step is to change the JavaScript to look at the \texttt{mcq} fields rather than
% the \texttt{mc} or \texttt{mck} fields.
% \changes{v8.8.5}{2021/10/03}{Changes required by changes in the display of
% tooltip for choice fields}
%    \begin{macrocode}
\def\Ans@l{\leavevmode\if\eq@listType1\stepcounter{quizno}%
  \else\refstepcounter{quizno}\fi\PBS\raggedright
  \settowidth{\eq@tmplength}{\eq@lw@l}\sbox{\eq@tmpbox}{\eq@l@l}%
  \hangindent=\eq@tmplength\hangafter=1\relax
  \eq@tmpdima=\wd\eq@tmpbox
  \def\link@@Content{(\hfil\linkContentFormat\hfil)}%
%    \end{macrocode}
% (2013/10/24) Imperative that radio button have no boundary line.
%    \begin{macrocode}
  \def\late@options{\BC{}}%
  \if\Ans@choice\eq@One\relax\eq@recordAnsChoice\fi
  \makebox[0pt][l]{\radio@@Button{}{mc.\curr@quiz.\thequestionno}%
    {\eq@tmpdima}{\RadioFieldSize}{\alph{quizno}}% dpsx
%   {\eq@tmpdima}{\RadioFieldSize}{\Ans@choice\alph{quizno}}%
    {\eq@protect\A}{\eq@setWidgetProps\eq@l@check@driver}%
    {\Ans@r@l@Defaults\every@RadioButton
    \every@qRadioButton\late@options}}%
  \set@@Link{}{}{}%
    {\makebox[\eq@tmpdima]{\color{\@linkcolor}\link@@Content}}%
    {\eq@protect\A}{\eq@setWidgetProps\setLink@driver}%
    {\set@LinkTextDefaults\Ans@@l@Actions\every@Link}%
  \ifnocorrections\else
    \if\Ans@choice\eq@One
      \edef\Ans@c@l@Choice{\noexpand\DV{Yes}%
          \ifx\@qzsolndest\@empty
              \noexpand\Ff{\FfReadOnly}%
          \else % there is a solution
              \ifeq@noquizsolutions\noexpand
                \Ff{\FfReadOnly}%
              \else\noexpand
                \A{\noexpand\quiz@SolutionActionHook}%
              \fi
          \fi
      }%
    \else
      \def\Ans@c@l@Choice{\Ff{\FfReadOnly}\BC{}}%
    \fi
    \def\late@options{\BC{}}%
    \if\Ans@choice\eq@One
      \eq@addExpandTo\late@options{\TU{1}}%
        \ifx\@qzsolndest\@empty\else
          \ifeq@noquizsolutions\else
            \eq@addExpandTo\late@options{%
              \BC{\solution@Color}}%
          \fi
        \fi
    \else
      \eq@addExpandTo\late@options{\TU{0}}%
    \fi
    \makebox[0pt][r]{\check@@Box{}%
      {mcq.\curr@quiz.\thequestionno.\arabic{quizno}}%
      {\eq@tmpdima}{0pt}{Yes}{}% \@tempdimb
      {\eq@setWidgetProps\eq@l@check@driver}%
      {\Ans@c@f@Defaults\Ans@c@l@Choice\every@RadioButton
       \every@qRadioButton\late@options}}%
  \fi
  \Ans@proofing{\eq@tmpdima}\eq@hspanner
  \ignorespaces
}
%    \end{macrocode}
%    \end{macro}
% Now for the code to support the \texttt{manswers} environment for link style.
%    \begin{macro}{\Ans@ck@l}
% Below is \cs{Ans@ck@l} and its supporting default appearances and actions. The command \cs{Ans@ck@l} defines
% a checkbox, on top of that a link (that the user interacts with) and on top another check box.
%    \begin{macrocode}
\def\Ans@ck@@l@Actions{\A{\JS{%
  var\eqSP ckfName="mck.\curr@quiz.\thequestionno.\arabic{quizno}";\jsR
  var\eqSP ckf = this.getField(ckfName);\jsR
  ckf.checkThisBox(0,!ckf.isBoxChecked(0));\jsR
  var\eqSP _bOK=true;\jsR
\ifx\eqlimselTo\@empty\else
  _bOK=LimitSelection(\eqlimselTo,%
    "mck.\curr@quiz.\thequestionno","\arabic{quizno}");\jsR
\fi
  if(_bOK)\eqSP{\jsR\jsT
  var\eqSP aPMSretn=ProcessMultiSelection(\Ans@choice,"\alph{quizno}",%
    \thequestionno,\arabic{quizno},"\curr@quiz",%
    \eqPTs,\eq@pPTs);\jsR\jsT
  RecordProblemType("\eqQT",\thequestionno);\jsR\jsT
  ProcessQuestion(aPMSretn[0],aPMSretn[1],\thequestionno,%
    \arabic{quizno},"\curr@quiz",0,\ifnocorrections0\else1\fi,%
    "\bqlabelISO"\if\eqQuizType\isQZ\ifx\eq@online\eq@YES
    \ifeq@noquizsolutions\else,1\fi\fi\fi);\jsR
  }}}%
}
%    \end{macrocode}
%    \begin{macrocode}
\def\Ans@ck@l@Defaults{%
  \BC{}\S{S}\W{1}\H{N}\Ff{\FfNoToggleToOff}\TU{\TU@Choice} % dpsx
  \textSize{12}\textColor{0 g}\Ff{\FfReadOnly}
}
%    \end{macrocode}
%    \begin{macrocode}
\def\Ans@ck@l{\leavevmode
  \if\eq@listType1\stepcounter{quizno}%
  \else\refstepcounter{quizno}\fi
  \if\Ans@choice\eq@One\eq@recordAnsChoice\fi
  \PBS\raggedright
  \settowidth{\eq@tmplength}{\eq@lw@l}\sbox{\eq@tmpbox}{\eq@l@l}%
  \hangindent\eq@tmplength\hangafter\@ne
  \eq@tmpdima\wd\eq@tmpbox
  \def\link@@Content{(\hfil\linkContentFormat\hfil)}%
  \makebox[0pt][l]{%
    \check@@Box{}{mck.\curr@quiz.\thequestionno.\arabic{quizno}}%
    {\eq@tmpdima}{\RadioFieldSize}{\alph{quizno}}% dpsx
%   {\eq@tmpdima}{\RadioFieldSize}{\Ans@choice\alph{quizno}}%
    {\eq@protect\A}{\eq@setWidgetProps\eq@l@check@driver}%
    {\Ans@ck@l@Defaults\every@RadioButton
     \every@qckCheckbox}}%
  \set@@Link{}{}{}%
    {\makebox[\eq@tmpdima]{\color{\@linkcolor}\link@@Content}}%
    {\eq@protect\A}{\eq@setWidgetProps\setLink@driver}%
    {\set@LinkTextDefaults\Ans@ck@@l@Actions\every@Link}%
  \ifnocorrections\else
    \if\Ans@choice\eq@One
      \edef\Ans@c@l@Choice{\noexpand\TU{1}\noexpand\DV{Yes}%
        \ifx\@qzsolndest\@empty\noexpand\BC{}%
        \noexpand\Ff{\FfReadOnly}%
        \else % there is a solution
          \ifeq@noquizsolutions
            \noexpand\BC{}\noexpand\Ff{\FfReadOnly}%
          \else
            \noexpand\BC{\solution@Color}%
            \noexpand\A{\noexpand\quiz@SolutionActionHook}%
          \fi
        \fi
      }%
    \else
      \def\Ans@c@l@Choice{\TU{0}\Ff{\FfReadOnly}\BC{}}%
    \fi
    \makebox[0pt][r]{\check@@Box{}%
      {mcq.\curr@quiz.\thequestionno.\arabic{quizno}}%
      {\eq@tmpdima}{0pt}{Yes}{}%
      {\eq@setWidgetProps\eq@l@check@driver}%
      {\Ans@c@f@Defaults\Ans@c@l@Choice\every@RadioButton
       \every@qRadioButton}}%
  \fi
  \Ans@proofing{\eq@tmpdima}\eq@hspanner
  \ignorespaces
}
%    \end{macrocode}
%    \end{macro}
% \subsubsection{Form Style}
%    \begin{macro}{\Ans@f}
% For the form button multiple choice type question. The driver independent stuff starts
% here, then goes to |\Ans@f@driver| the rest of the code that depends on the
% driver.
%    \begin{macrocode}
\def\Ans@f{\leavevmode
  \if\eq@listType1\stepcounter{quizno}\else
    \refstepcounter{quizno}\fi
  \PBS\raggedright\Ans@@f}
\def\Ans@r@f@Defaults{%
  \BC{0 0 0}\S{S}\W{1}\Ff{\FfNoToggleToOff}\TU{\TU@Choice} % dpsx
  \F{\FPrint}\textSize{12}\textColor{0 g}
}
%    \end{macrocode}
% Action of the radio button field
%    \begin{macrocode}
\def\Ans@r@f@Actions{\A{\JS{%
  RecordPointValue([0,\eqPTs,\eq@pPTs],\thequestionno);\jsR
  RecordProblemType("\eqQT",\thequestionno);\jsR
  ProcessQuestion(\Ans@choice,"\alph{quizno}",\thequestionno,%
  \arabic{quizno},"\curr@quiz",0,\ifnocorrections0\else1\fi,%
  "\bqlabelISO"\if\eqQuizType\isQZ\ifx\eq@online\eq@YES
  \ifeq@noquizsolutions\else,1\fi\fi\fi);\qRadionActionsHook}}
}
%    \end{macrocode}
% Action of the check box underlying the radio button field
%    \begin{macrocode}
\def\quiz@SolutionActionHook{%
  /S/GoTo/D(\@qzsolndest)/Next<<\JS{this.resetForm(%
    ["mcq.\curr@quiz.\thequestionno.\arabic{quizno}"]);}>>
}
\def\Ans@c@f@Defaults{%
  \BC{0 0 0}\S{S}\W{1}\F{\FHidden}\textSize{12}
  \textColor{0 g}\symbolchoice{circle}
}
%    \end{macrocode}
% \changes{v6.05d}{2007/04/14}
% {
%   Added the command \string\cs{insertGrayLetters}. This can be defined to place symbols under
%   the multiple choice form boxes. The command \string\cs{bottomOfAnsfStack} is there as a
%   hook for whatever purposes are desired.
% }
%    \begin{macrocode}
\let\bottomOfAnsfStack\relax
%</package>
%<*package|eqexam>
%    \end{macrocode}
% \changes{v7.7}{2015/06/04}{Added \string\cs{graylettersColor}}
% \DescribeMacro\graylettersColor sets the color of the gray letters, the default is
% \texttt{gray}.
%    \begin{macrocode}
\providecommand\graylettersColor{gray}
\def\insertGrayLetters{\ifaebshowgrayletters
  \rlap{\makebox[\RadioFieldSize]%
    {\textcolor{\graylettersColor}{\Alph{quizno}}}}\else\relax\fi}
%</package|eqexam>
%<*package>
%    \end{macrocode}
%    The \cs{Ans} command for a quiz using forms.
%    \begin{macrocode}
\def\Ans@@f{%
  \settowidth{\eq@tmplength}{\eq@lw@f}%
  \hangindent=\eq@tmplength\hangafter=\@ne
  \bottomOfAnsfStack\insertGrayLetters
  \edef\rbf@Opts{\ifaeb@usecircles\else
  \noexpand\symbolchoice{\qz@chksymb}\fi
  \noexpand\textColor{\qz@chksymbcol}}%
  \if\Ans@choice\eq@One\eq@recordAnsChoice\fi
  \mbox{\expandafter\radio@@Button\expandafter{\rbf@Opts}%
    {mc.\curr@quiz.\thequestionno}%
    {\RadioFieldSize}{\RadioFieldSize}{\alph{quizno}}% dpsx
%   {\RadioFieldSize}{\RadioFieldSize}{\Ans@choice\alph{quizno}}%
    {\eq@protect\A}{\eq@setWidgetProps\eq@Radio@driver}%
    {\Ans@r@f@Defaults\Ans@r@f@Actions\every@RadioButton
     \every@qRadioButton\insert@circlesymbol}}%
  \let\late@options\@empty
  \ifnocorrections\else
    \if\Ans@choice\eq@One
      \edef\Ans@c@f@Choice{\noexpand\DV{Yes}%
        \ifx\@qzsolndest\@empty\noexpand\Ff{\FfReadOnly}\else
          \ifeq@noquizsolutions
            \noexpand\Ff{\FfReadOnly}\else
            \noexpand\A{\noexpand\quiz@SolutionActionHook}\fi
        \fi
      }%
    \else
      \def\Ans@c@f@Choice{\Ff{\FfReadOnly}}%
    \fi
%    \end{macrocode}
% \changes{v6.7h}{2013/08/19}{When the \string\cs{useMCCircles} is used, the boundary
% color is transparent. We try a fix for this to show the colored solution
% boundary. The fix uses the \string\cs{late@options} commands.}
%    \begin{macrocode}
    \ifaeb@usecircles\def\late@options{\BC{}}\fi
    \if\Ans@choice\eq@One
      \eq@addExpandTo\late@options{\TU{1}}%
      \ifx\@qzsolndest\@empty\else
        \ifeq@noquizsolutions\else
          \eq@addExpandTo\late@options{%
            \BC{\solution@Color}}%
        \fi
      \fi
    \else
      \eq@addExpandTo\late@options{\TU{0}}%
    \fi
    \makebox[0pt][r]{\check@@Box{}%
      {mcq.\curr@quiz.\thequestionno.\arabic{quizno}}%
      {\RadioFieldSize}{\RadioFieldSize}{Yes}{}%
      {\eq@setWidgetProps\eq@Check@driver}%
      {\Ans@c@f@Defaults\Ans@c@f@Choice\every@CheckBox
       \every@qCheckBox\late@options}}%
  \fi
  \Ans@proofing{\RadioFieldSize}\eq@hspanner
  \ignorespaces
}
%    \end{macrocode}
% \DescribeMacro{\limitSelectionTo} limits the selection to the number specified
% by its argument for multiple selection questions.
%    \begin{macrocode}
\def\limitSelectionTo#1{\def\eqlimselTo{#1}}
\let\eqlimselTo\@empty
%    \end{macrocode}
%    \begin{macro}{\Ans@ck@f}
% The support for multiple selection answers within the \texttt{manswers} environment.
%    \begin{macrocode}
\def\Ans@ck@f{\leavevmode
  \if\eq@listType1\stepcounter{quizno}%
  \else\refstepcounter{quizno}\fi
  \if\Ans@choice\eq@One\eq@recordAnsChoice\fi
  \PBS\raggedright\Ans@@ck@f}
%    \end{macrocode}
%    \begin{macrocode}
\def\Ans@ck@f@Defaults{%
  \BC{0 0 0}\S{S}\W{1}\Ff{\FfNoToggleToOff}
  \TU{\TU@Choice} % dpsx
  \textSize{12}\textColor{0 g}
}
%    \end{macrocode}
% Action of the radio button field
%    \begin{macrocode}
\def\Ans@ck@f@Actions{%
  \A{\JS{%
%    \end{macrocode}
% Here is limit the number of selections. If \cs{eqlimselTo} is nonempty,
% we call \texttt{LimitSelection()} to count the number of checks in this
% current field. If too many, we uncheck the current effort and inform the
% user.
%    \begin{macrocode}
  var\eqSP_bOK=true;\jsR
\ifx\eqlimselTo\@empty\else
  _bOK\eqSP=\eqSP LimitSelection(\eqlimselTo,%
    "mck.\curr@quiz.\thequestionno","\arabic{quizno}");\jsR\fi
%    \end{macrocode}
% As a result of the previous changes, we make this a condition:
% if the JavaScript function \texttt{LimitSelection()} returns false, we do not execute. The default
% value is \texttt{\_bOK=true}.
%    \begin{macrocode}
  if(_bOK)\eqSP{\jsR\jsT
    var aPMSretn=ProcessMultiSelection(\Ans@choice,"\alph{quizno}",%
      \thequestionno,\arabic{quizno},"\curr@quiz",%
      \eqPTs,\eq@pPTs);\jsR\jsT
    RecordProblemType("\eqQT",\thequestionno);\jsR\jsT
    ProcessQuestion(aPMSretn[0],aPMSretn[1],\thequestionno,%
      \arabic{quizno},"\curr@quiz",0,\ifnocorrections0\else1\fi,%
      "\bqlabelISO"\if\eqQuizType\isQZ\ifx\eq@online\eq@YES
      \ifeq@noquizsolutions\else,1\fi\fi\fi);\jsR
  }}}%
}
%    \end{macrocode}
% Action of the check box underlying the radio button field
%    \begin{macrocode}
\def\quiz@SolutionActionHook{/S/GoTo/D(\@qzsolndest)%
  /Next<<\JS{this.resetForm([%
  "mcq.\curr@quiz.\thequestionno.\arabic{quizno}"]);}>>
}
%    \end{macrocode}
% \cs{Ans@@ck@f} is the definition of the \cs{Ans} command within the
% \texttt{manswers} environment.
%    \begin{macrocode}
\def\Ans@@ck@f{%
  \settowidth{\eq@tmplength}{\eq@lw@f}%
  \hangindent\eq@tmplength\hangafter\@ne
  \bottomOfAnsfStack\insertGrayLetters
%    \end{macrocode}
% The bottom most checkbox
%    \begin{macrocode}
  \bottomOfAnsfStack\insertGrayLetters
  \def\cbf@Opts{\symbolchoice{\qz@chksymb}%
    \textColor{\qz@chksymbcol}}%
  \mbox{\expandafter\check@@Box\expandafter{\cbf@Opts}%
    {mck.\curr@quiz.\thequestionno.\arabic{quizno}}%
    {\RadioFieldSize}{\RadioFieldSize}{\alph{quizno}}% dpsx
%   {\RadioFieldSize}{\RadioFieldSize}{\Ans@choice\alph{quizno}}%
    {\eq@protect\A}{\eq@setWidgetProps\eq@Check@driver}%
    {\Ans@ck@f@Defaults\Ans@ck@f@Actions\every@RadioButton
    \every@qckCheckbox}}%
  \ifnocorrections\else
    \if\Ans@choice\eq@One
      \edef\Ans@c@f@Choice{\noexpand\DV{Yes}%
        \ifx\@qzsolndest\@empty\noexpand\Ff{\FfReadOnly}\else
          \ifeq@noquizsolutions
            \noexpand\Ff{\FfReadOnly}\else
            \noexpand\A{\noexpand\quiz@SolutionActionHook}\fi
        \fi
      }%
    \else
      \def\Ans@c@f@Choice{\Ff{\FfReadOnly}}%
    \fi
    \let\late@options\@empty
    \if\Ans@choice\eq@One
      \eq@addExpandTo\late@options{\TU{1}}%
      \ifx\@qzsolndest\@empty\else
        \ifeq@noquizsolutions\else
          \eq@addExpandTo\late@options{%
            \BC{\solution@Color}}\fi
      \fi
    \else
      \eq@addExpandTo\late@options{\TU{0}}%
    \fi
%    \end{macrocode}
% The top most checkbox
%    \begin{macrocode}
    \makebox[0pt][r]{\check@@Box{}%
      {mcq.\curr@quiz.\thequestionno.\arabic{quizno}}%
      {\RadioFieldSize}{\RadioFieldSize}{Yes}{}%
      {\eq@setWidgetProps\eq@Check@driver}%
      {\Ans@c@f@Defaults\Ans@c@f@Choice\every@CheckBox
%    \end{macrocode}
% (2012/12/22) Replace \cs{every@qRadioButton} with \cs{every@qCheckBox}.
%    \begin{macrocode}
    \every@qCheckBox\late@options}}%
  \fi
  \Ans@proofing{\RadioFieldSize}\eq@hspanner
  \ignorespaces
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
% Begin joint package and eqexam
%</package>
%<*package|eqexam>
%    \end{macrocode}
%\subsection{The \texorpdfstring{\protect\cs{bChoices}/\protect\cs{eChoices}}
% {\textbackslash{bChoices}/\textbackslash{eChoices}} Pair}
% (2/15/05) This pair of macros is not really an environment, the
% \cs{eChoices} really does nothing other than to act as an ending marker. The idea
%behind this pair of macros twofold: (1) To provide a convenient way of listing
%alternate choices for a multiple choice questions, the ``environment'' makes it
%easy to change the number of columns, or to change from tabular to list (or visa-versa);
%(2) Laying out the alternatives in a list style, makes it easy to develop techniques
%of randomizing the alternatives. Here is an example of usage:
%\begin{verbatim}
%\begin{answers}{4}
%\bChoices[2]
%    \Ans0 a choice\eAns
%    \Ans1 another choice\eAns
%    \Ans0 still another choice\eAns
%    \Ans0 another\eAns
%    \Ans0 incoming\eAns
%    \Ans0 more choices\eAns
%    \Ans0 another still\eAns
%    \Ans0 too many\eAns
%    \Ans0 choices\eAns
%\eChoices
%\end{answers}
%\end{verbatim}
%\noindent The argument of the \texttt{answers} environment is $4$ which means we are
%going to use the tabular environment with $4$ columns. Now within those $4$ we are going
%to only use the first $2$ columns ( this is the optional argument of \cs{bChoices}.
%
% If the optional argument is removed from \cs{bChoices}, the choices are typeset
% in the with $4$ columns. If the argument of \cs{answers} is changed to $1$, then the
% optional argument of \cs{bChoices} is ignored, and the alternatives are typeset in a
% one column list environment.
%
% By changing the two parameters (one for \cs{answers} and one for \cs{bChoices})
% you can easily modify how the alternatives are typeset.
%\par\medskip\noindent
% This counter tracts the column number we are in.
%    \begin{macrocode}
\newcount\eq@tabColCnt
%    \end{macrocode}
%    \begin{macro}{\bChoices}
% This command has one optional argument, the number of columns to use.
%
% When the answer environment sets the number of columns, the answers are set in
% tabular form.  If you say \verb!\begin{answers}[4]!, four columns are used.
% If you then say \IndexKey{nCols}\verb!\Choices[nCols=2]!, only the first two columns are used.
% To maintain backward compatibility, you can also say \verb!\Choices[2]!
%    \begin{macrocode}
\define@key{bchoice}{nCols}{\def\bChoiceNumCols{#1}}
\@for\eqi:=1,2,3,4,5,6,7,8,9,10 \do{\edef\temp@expand@def{%
  \noexpand\define@key{bchoice}{\eqi}[\eqi]{%
    \noexpand\def\noexpand\bChoiceNumCols{\eqi}}%
  }\temp@expand@def
}
%    \end{macrocode}
% The number of columns specified in the answers environment is saved as the value
% of \cs{aeb@numCols}. This the default value of \cs{bChoiceNumCols}.
%    \begin{macrocode}
\def\bChoiceNumCols{\aeb@numCols}
%    \end{macrocode}
% This is the definition of the random key\IndexKey{random}, a boolean.
%    \begin{macrocode}
\define@key{bchoice}{random}[true]{%
  \csname if#1\endcsname\eq@randomizeChoicestrue
  \else\eq@randomizeChoicesfalse\fi
}
%    \end{macrocode}
% \changes{v6.3x}{2011/04/05}{%
%   Added \string\texttt{label} parameter to \string\cs{bChoices}.
%}
% A new key, \IndexKey{label}\texttt{label=\ameta{name}}, if this label is specified, then we keep track of all the
% correct alternatives, put them into a commands to make them accessible by the user.
%    \begin{macrocode}
\define@key{bchoice}{label}[]{\xdef\bChoiceLabel{#1}}
%    \end{macrocode}
% New key, \IndexKey{insertAt}\texttt{insertAt=\ameta{n}} inserts the content of
% the \cs{answersEndHook\darg{\ameta{content}}} at line \ameta{n}.
%    \begin{macrocode}
\def\rmFracPrt#1.#2\@nil{\gdef\intPrt{#1}}
\define@key{bchoice}{insertAt}[]{%
  \let\insertAtMsg\relax
  \def\rmFr@cPrt##1.##2\@nil{\def\intP@rt{##1}}
  \def\@rgi{#1}\ifx\@rgi\@empty
    \def\insertAtMsg{\PackageWarning{exerquiz}
      {An empty value for insertAt, will use\MessageBreak
       the default positioning}}%
  \else
    \rmFr@cPrt#1.\@nil
    \expandafter\@tempcnta\intP@rt\relax
    \ifnum\@tempcnta<\@ne
      \def\insertAtMsg{\PackageWarning{exerquiz}
        {insertAt=#1: The value (#1) of insertAt must be\MessageBreak
        greater than zero. Using the default\MessageBreak
        positioning instead}}
    \else
      \xdef\insertAnsHookAt{\the\@tempcnta}
    \fi
  \fi
  \insertAtMsg
} % dps21-5-15
\let\insertAnsHookAt\@empty
%    \end{macrocode}
% The \cs{bChoices} command is now processed by the \texttt{keyval} package. There
% are two keys: \texttt{nCols} and \texttt{random}. The first key
% sets the number of columns we are limited to; the second one obviously declares
% that this list of choices should be randomized, a boolean. The \texttt{random}
% key is ignored unless the document author has use the \texttt{allowrandomize} option.
%    \begin{macrocode}
\def\bChoices{\@ifnextchar[{\@ansChoices}{\@ansChoices[\aeb@numCols]}}
%    \end{macrocode}
% If \cs{numCols} is $1$, we use a list environment, otherwise, a tabular is used.
%    \begin{macrocode}
\def\@ansChoices[#1]{%
%    \end{macrocode}
% We initialize some variables that the new label option uses.
%    \begin{macrocode}
  \global\let\@tempholdSaveAns\@empty
  \global\let\@tempholdSaveChoice\@empty
  \global\let\bChoiceLabel\@empty
  \setkeys{bchoice}{#1}% dps21-5-15
  \def\aeb@RowCnt{0}\global\eq@tabColCnt\z@
  \ifnum\aeb@numCols=\@ne % list mode
    \def\eq@next{\@layoutListAns}\else % tabular mode
    \def\eq@next{\@layoutTabularAns{\bChoiceNumCols}}\fi
  \eq@next
}
\let\eChoices\relax
%    \end{macrocode}
%    \end{macro}
% If the next token is \cs{Ans} we grab its all stuff between
% \cs{Ans} and \cs{eAns} and typeset it. We continue until the
% next token is not \cs{Ans}. (This last token
% should be \cs{eChoices}.)
%    \begin{macrocode}
\def\@layoutListAns{\@ifnextchar\Ans{\@getListAns}%
  {\@lookforendansChoices{\@layoutListAns}}%
}
%    \end{macrocode}
% \changes{v6.3x}{2011/04/05}{%
% Supporting commands that use the value of the \string\texttt{label} parameter
% of \string\cs{bChoices}: \string\cs{eq@saveAns}, \string\cs{eq@displayAns},
% \string\cs{eq@displayAlts}, etc.
%}
% \texttt{4/5} We begin an experimental series of commands. The idea is to be able to
% conveniently reference a multiple choice problem when the
% \texttt{vspacewithsolns} option is in effect (\textsf{eqexam}).
%
% \cs{eq@saveAns} is an internal macro, it gathers up the first two
% arguments of \cs{Ans}, if the second arg is a 1, it passes the flow
% to \cs{@@@SaveAns}; otherwise, it gobbles all leftovers.
%    \begin{macrocode}
\newcommand{\eq@saveAns}[2][]{%
  \let\eq@next\@@@SaveAnsGobbleAns
  \ifx\bChoiceLabel\@empty\else
  \def\eq@savedAnsOpt{#1}\def\eq@savedAnsZO{#2}%
  \if\eq@savedAnsZO1\let\eq@next\@@@SaveAns\fi
  \fi\eq@next
}
%    \end{macrocode}
% \cs{@@@SaveAns} collects the answer to the problem, and placed
% it in the holding command \cs{@tempholdSaveAns}, it also saves
% the alternative letter as well in \cs{@tempholdSaveChoice}.
%    \begin{macrocode}
\long\def\@@@SaveAns#1\eAns{% 4/5
  \g@addto@macro\@tempholdSaveAns{\\{\ignorespaces#1}}%
%    \end{macrocode}
% This code is expanded before the \cs{Ans} command is, so we'll simulate
% incrementing the \texttt{quizno} counter, \dots
%    \begin{macrocode}
  \addtocounter{quizno}{1}%
  \edef\temp@expand{\noexpand\g@addto@macro\noexpand
    \@tempholdSaveChoice{%
      \noexpand\\{\ifx\sqstar\@empty\aebChoiceAltFmt\else
      \ifaebshowgrayletters\Alph{quizno}\else
      \linkContentFormat\fi\fi}}}\temp@expand
%    \end{macrocode}
% and decrement when we are finished adding to the token list.
%    \begin{macrocode}
  \addtocounter{quizno}{-1}%
}
%    \end{macrocode}
% \cs{eq@displayAns} is \cs{let} to \verb!\\!. Definition and name may change.
% \cs{useSaveAns} is a simple interface to accessing the list of all correct
% answers. Probably this definition will change.
%
% \cs{eq@insertComma} is a simple way of delimiting the list. We put a  comma
% before each expression, except for the first one.
%
% (2016/11/21) The \DescribeMacro{\oxfordCommaOn}\cs{oxfordCommaOn} is on by default, while
% \DescribeMacro{\oxfordCommaOn}\cs{oxfordCommaOff} turns off the Oxford comma. The
% Oxford comma comes into play only with the star-forms of \cs{useSavedAns},
% \cs{useSavedAlts}, and \cs{useSavedAltsAns}.
% \changes{v7.8}{2016/11/21}{Added star option to each of the \string\cs{useSaved...} commands}
%    \begin{macrocode}
\newif\ifoxfordcomma \oxfordcommatrue
\def\oxfordCommaOn{\oxfordcommatrue}
\def\oxfordCommaOff{\oxfordcommafalse}
\def\eq@insertComma{%
  \ifx\eq@comma\@empty
    \ifnum\@nameuse{NumAns\eq@namearg}>\tw@
      \def\eq@comma{,}\fi
  \else\ifx\eq@insertAnd\@empty\eq@comma\space
    \else\ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}%
      \ifoxfordcomma\eq@comma\fi\else\eq@comma\fi\space
    \fi
  \fi
}
\newcommand\eqAnd{and}\def\eq@insertAnd{%
  \ifnum\@nameuse{NumAns\eq@namearg}<\tw@\else
  \ifnum\@nameuse{NumAns\eq@namearg}>\tw@\relax
  \else\leavevmode\space\fi\eqAnd\space\fi
}
\long\def\eq@displayAns#1{\advance\@tempcnta\@ne
  \eq@insertComma
  \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi#1}
\def\eq@displayAlts#1{\advance\@tempcnta1
  \eq@insertComma
  \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi
  \savedAltFmt{#1}}
\def\eq@displayAltsAns#1{\advance\@tempcnta1\relax
  \eq@insertComma
  \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi#1}
%    \end{macrocode}
%    \begin{macro}{\useSavedAns}
%    \begin{macro}{\useSavedAlts}
%    \begin{macro}{\useSavedAltsAns}
%    \begin{macro}{\useSavedNumAns}
% \changes{v6.3x}{2011/04/05}{%
% Added \string\cs{useSavedAns}, \string\cs{useSavedAlts}, and \string\cs{useSavedAltsAns}.
%}
% These three commands hold the correct alternatives and answers to a multiple choice
% or multiple selection problem. The optional first argument allows you to display
% a particular result, the second argument is the value of the \texttt{label} key-value,
% given in the enclosing \cs{bChoices}/\cs{eChoices} ``environment.''
%    \begin{macrocode}
\newcommand{\savedAltFmt}[1]{(#1)}
\newcommand{\useSavedAns}{\bgroup\@ifstar{\useSavedAns@i}
  {\let\eq@insertAnd\@empty\useSavedAns@i}}
\newcommand{\useSavedAns@i}[2][]{\@tempcnta=0\relax
  \def\eq@namearg{#2}\let\label\@gobble
  \def\eq@argi{#1}\ifx\eq@argi\@empty
    \let\eq@comma\@empty
    \let\\\eq@displayAns\@nameuse{SavedAns#2}\else
    \@nameuse{SavedAns#2-Idx#1}\fi
  \egroup
}
\newcommand{\useSavedAlts}{\bgroup\@ifstar{\useSavedAlts@i}
  {\let\eq@insertAnd\@empty\useSavedAlts@i}}
\newcommand{\useSavedAlts@i}[2][]{\@tempcnta=0\relax
  \def\eq@namearg{#2}\@nameuse{caseFor#2}%
  \def\eq@argi{#1}\ifx\eq@argi\@empty
    \let\eq@comma\@empty
    \let\\\eq@displayAlts\@nameuse{SavedAlts#2}\else
    \savedAltFmt{\@nameuse{SavedAlts#2-Idx#1}}\fi
  \egroup
}
\newcommand{\useSavedAltsAns}{\bgroup\@ifstar{\useSavedAltsAns@i}
  {\let\eq@insertAnd\@empty\useSavedAltsAns@i}}
\newcommand{\useSavedAltsAns@i}[2][]{\@tempcnta=0\relax
  \def\eq@namearg{#2}\@nameuse{caseFor#2}\let\label\@gobble
  \def\eq@argi{#1}\ifx\eq@argi\@empty
    \let\eq@comma\@empty
    \let\\\eq@displayAltsAns\@nameuse{SavedAltsAns#2}\else
    \savedAltFmt{\@nameuse{SavedAlts#2-Idx#1}}
    \@nameuse{SavedAns#2-Idx#1}\fi
  \egroup
}
\newcommand{\useSavedNumAns}[1]{\@nameuse{NumAns#1}}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \begin{macrocode}
\long\def\@@@SaveAnsGobbleAns#1\eAns{}
%    \end{macrocode}
% This command gets, and sets the list of alternatives
%    \begin{macrocode}
\long\def\@getListAns\Ans#1\eAns{%\@@par
  \@incRowCnt  % dps21-5-16
%    \end{macrocode}
% We record the list as we process each item.
%    \begin{macrocode}
  \eq@saveAns#1\eAns
  \Ans#1% dps21-5-15
  \@insertAnsHookAt % dps21-5-16
  \vspace{\@rowskip}\@layoutListAns
}
\long\def\@lookforendansChoices#1{%
  \@ifnextchar\eChoices{\rowsep{\rowsep@default}%
    \expandafter\@findendans\@gobble}{\expandafter#1\@gobble}%
}
%    \end{macrocode}
% The argument is the number of columns to typeset, this number
% is forced to be \texttt{<=} to the number of columns specified in the \texttt{answers}
% environment.
%    \begin{macrocode}
\def\@layoutTabularAns#1{%
  \@incRowCnt % dps21-5-16
  \let\eq@tabSep\@empty
  \xdef\numShortCols{#1}%
%\typeout{!! compare #1 with \aeb@numCols}%
  \@tempcnta\aeb@numCols % dps21-5-16
  \advance\@tempcnta-#1
%\typeout{!! need \the\@tempcnta\space more tabs}%
  \global\let\nAddT@bs\@empty
  \@whilenum\@tempcnta>\z@\do
  {\g@addto@macro\nAddT@bs{&}\advance\@tempcnta\m@ne}%
%\toks@=\expandafter{\nAddT@bs}\typeout{!! \the\toks@}%
  \ifnum#1>\aeb@numCols \xdef\numShortCols{\aeb@numCols}\fi
  \@@layoutTabularAns
}
%    \end{macrocode}
% If the next token is \cs{Ans} we grab its all stuff between
% \cs{Ans} and \cs{eAns} and typeset it and insert the appropriate
% token, either \texttt{\&} or \texttt{\string\cr}.
% We continue until the next token is not \cs{Ans}. (This last token
% should be \cs{eChoices}.)
%    \begin{macrocode}
\def\@@layoutTabularAns{%
  \@ifnextchar\Ans{\@getTabAns}%
    {\@lookforendansChoices{\@@layoutTabularAns}}%
}
\def\rowsep#1{\gdef\@rowsep{[#1]}\gdef\@rowskip{#1}}%
\rowsep{\rowsep@default}
\def\rowsepDefault#1{\def\rowsep@default{#1}}
\def\rowsep@default{0pt}
\long\def\@getTabAns\Ans#1\eAns{%
  \eq@saveAns#1\eAns
  \global\advance\eq@tabColCnt\@ne % dps21-5-16
  \let\@save@tabSep\eq@tabSep % dps21-5-16
  \ifnum\eq@tabColCnt=\numShortCols
    \global\eq@tabColCnt\z@ % dps21-5-16
    \xdef\eq@tabSep{%
      \noexpand\nAddT@bs
      \noexpand\@insertAnsHookAt
      \noexpand\\
      \noalign{\kern\@rowskip\relax}\noexpand\@incRowCnt
    }%
  \else
    \gdef\eq@tabSep{&}%
  \fi
  \@ifnextchar\eChoices{\@save@tabSep\Ans#1\rowsep{\rowsep@default}%
    \nAddT@bs\@insertAnsHookAt\expandafter\@findendans\@gobble}%
    {\@save@tabSep\Ans#1\@@layoutTabularAns}%
}
%    \end{macrocode}
% This command, I think, is executed after we've found the \cs{eChoices}.
%    \begin{macrocode}
\def\@findendans{\@ifnextchar\end{%
%    \end{macrocode}
% If there is a \cs{bChoiceLabel} we process the alternatives.
%    \begin{macrocode}
  \ifx\bChoiceLabel\@empty\else
  \processLabeledAns\fi
  }{\expandafter\@findendans\@gobble}}%
%    \end{macrocode}
% The command that processes the alternatives.
% \changes{v6.7g}{2013/08/09}{Changed \string\texttt{\string\#1} to \string\cs{the}\string\cs{@temptokena} Fixing
% a nasty bug. Reported by Christopher C.}
%    \begin{macrocode}
\def\defineEachAns#1{\advance\eqtmpcnta\@ne
  \@temptokena={#1}\csarg\xdef
  {SavedAns\bChoiceLabel-Idx\the\eqtmpcnta}{\the\@temptokena}%
  \ifsolutionsonly\else
    {\let\\\relax\eq@IWDefs{\string
      \csarg\string\gdef{SavedAns\bChoiceLabel-Idx\the\eqtmpcnta}%
      {\the\@temptokena}}}%
  \fi
}
\def\defineEachChoice#1{\advance\eqtmpcnta\@ne
  \@temptokena={#1}\csarg\xdef
    {SavedAlts\bChoiceLabel-Idx\the\eqtmpcnta}%
    {\the\@temptokena}\ifsolutionsonly\else
    {\let\\\relax\eq@IWDefs{\string
      \csarg\string
        \gdef{SavedAlts\bChoiceLabel-Idx\the\eqtmpcnta}%
      {\the\@temptokena}}}\fi
}
\def\processLabeledAns{%
  \bgroup
    \let\label\@gobble
%    \end{macrocode}
% \changes{v7.7c}{2015/10/08}{Added memory for the case}
%    \begin{macrocode}
    \if\aeb@FLOverride\eq@l
      \global\@namedef{caseFor\bChoiceLabel}{\graylettersOff}\else
      \ifaebshowgrayletters
        \global\@namedef{caseFor\bChoiceLabel}{\graylettersOn}\else
        \global\@namedef{caseFor\bChoiceLabel}{\graylettersOff}\fi
    \fi
    \toks@=\expandafter{\@tempholdSaveAns}\csarg
    \xdef{SavedAns\bChoiceLabel}{\the\toks@}%
    \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string
    \csarg\string\gdef{SavedAns\bChoiceLabel}{\the\toks@}}}\fi
    \eqtmpcnta\z@\let\\\defineEachAns\the\toks@
    \xdef\@currNCntAns{\the\eqtmpcnta}\csarg
    \xdef{NumAns\bChoiceLabel}{\@currNCntAns}%
    \ifsolutionsonly\else{\eq@IWDefs{\string
    \csarg\string\gdef{NumAns\bChoiceLabel}{\the\eqtmpcnta}}}\fi
    \toks@=\expandafter{\@tempholdSaveChoice}\csarg
    \xdef{SavedAlts\bChoiceLabel}{\the\toks@}%
    \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string
    \csarg\string\gdef{SavedAlts\bChoiceLabel}{\the\toks@}}}\fi
    \eqtmpcnta\z@\relax\let\\\defineEachChoice\the\toks@
    \eqtmpcnta\@ne\toks@={}%{\ignorespaces\@gobble}%
    \loop
      \edef\temp@exp{\the\toks@\noexpand\\{%
      \noexpand\useSavedAlts[\the\eqtmpcnta]{\bChoiceLabel}
      \noexpand\useSavedAns[\the\eqtmpcnta]{\bChoiceLabel}}}%
      \toks@=\expandafter{\temp@exp}%
      \ifnum\eqtmpcnta<\@currNCntAns\relax
      \advance\eqtmpcnta\@ne
    \repeat
    \csarg\xdef{SavedAltsAns\bChoiceLabel}{\the\toks@}%
    \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string
    \csarg\string\gdef{SavedAltsAns\bChoiceLabel}{\the\toks@}}}\fi
  \egroup
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
% end joint package and eqexam
%</package|eqexam>
%    \end{macrocode}
%    \begin{macrocode}
% Begin randomize segment
%<*randomize>
%    \end{macrocode}
%
% \subsection{Randomizing the Order of the Multiple Choices}\label{randomize}
%
% When the author wants to randomize the multiple choices, we require the \texttt{keyval}
% package and the \texttt{random.tex} macro file.  This works only when using \cs{bChoices}
% and \cs{eChoices}. The use of \cs{bChoices} and \cs{eChoices} is limited to non-verbatim
% items.
%
% \changes{v6.7f}{2013/08/03}{Added conditional input of random.tex}
% The \texttt{random.tex}, by Donald Arseneau, provides the random number support.
%    \begin{macrocode}
\@ifundefined{nextrandom}{\input{random.tex}}{}
%    \end{macrocode}
% We redefine \cs{nextrandom} from \texttt{random.tex} to save the initializing seed.
%    \begin{macrocode}
\def\nextrandom{\begingroup
  \ifnum\randomi<\@ne % then initialize with time
    \global\randomi\time
    \global\multiply\randomi388 \global\advance\randomi\year
    \global\multiply\randomi31 \global\advance\randomi\day
    \global\multiply\randomi97 \global\advance\randomi\month
    \message{Randomizer initialized to \the\randomi.}%
    \nextrandom \nextrandom \nextrandom
%    \end{macrocode}
% Save the initial seed value to \cs{eqInitSeedValue}.
% \changes{v6.7f}{2013/08/03}{Save the initial seed value to \string\cs{eqInitSeedValue}.}
%    \begin{macrocode}
    \xdef\InitSeedValue{\the\randomi}%
  \fi
  \count@ii\randomi
  \divide\count@ii 127773 % modulus = multiplier * 127773 + 2836
  \count@\count@ii
  \multiply\count@ii 127773
  \global\advance\randomi-\count@ii % random mod 127773
  \global\multiply\randomi 16807
  \multiply\count@ 2836
  \global\advance\randomi-\count@
  \ifnum\randomi<\z@\global\advance\randomi 2147483647\relax\fi
 \endgroup
}
%    \end{macrocode}
%    \DescribeMacro{\writeSeedToSolnFile} writes the current
%    value of \cs{randomi} to the solution file. May be useful in randomizing choices
%    in the solution file in the same order they were randomized in the main document.
%    \changes{v7.8h}{2017/04/14}{Added \string\cs{writeSeedToSolnFile}}
%    \begin{macrocode}
\def\writeSeedToSolnFile{\writeT@ExSolns{\string\randomi=\the\randomi}}
%    \end{macrocode}
% The \cs{bChoices} command is now processed by the \texttt{keyval} package. There
% are two keys: \texttt{nCols} and \texttt{random}. The first key
% sets the number of columns we are limited to; the second one obviously declares
% that this list of choices should be randomized, a boolean.
%
% We redefine \cs{@ansChoices} above to take key-value optional arguments.
% We allow for a global override of the \key{random} key. If \key{random} is true, we
% call \cs{@@bChoices}, which begins the process of randomization; otherwise
% we call \cs{@@ansChoices} which is roughly equal to the earlier
% \cs{@ansChoices}.
% \changes{v6.1}{2007/10/28}
% {%
%   Added support for randomizing the multiple choices, requires the use of \string\cs{bChoices}
%   and \string\cs{eChoices}.
% }
% \changes{v8.6.2}{2021/01/20}{Incorporated \string\cs{if@DoNotRandomize}
% into the \string\cs{@ansChoices} macro for MC and MS questions}
% \changes{v8.7}{2021/05/15}{Support for the \texttt{insertAt} key
% of \cs{bChoices}; initialize macro \string\cs{aeb@numRows}}
%    \begin{macrocode}
\def\@ansChoices[#1]{%
  \global\let\@tempholdSaveAns\@empty
  \global\let\@tempholdSaveChoice\@empty
  \global\let\bChoiceLabel\@empty
  \ifeq@randomizeallChoices
    \setkeys{bchoice}{#1,random=true}\else
    \setkeys{bchoice}{#1}\fi
  \global\eq@tabColCnt\z@
  \def\aeb@RowCnt{0}% dps21-5-15
  \if@DoNotRandomize\eq@randomizeChoicesfalse\fi
  \ifeq@randomizeChoices\expandafter\@@bChoices
  \else\expandafter\@@ansChoices\fi
}
%    \end{macrocode}
% This is actually the old \cs{@ansChoices} only slightly modified.
%    \begin{macrocode}
\def\@@ansChoices{%
  \ifnum\aeb@numCols=\@ne % list mode
    \def\eq@next{\@layoutListAns}%
  \else % tabular mode
    \edef\eq@next{\noexpand\@layoutTabularAns{\bChoiceNumCols}}%
  \fi
  \eq@next
}
%    \end{macrocode}
% The following are some registers to hold integers and tokens.
%    \begin{macrocode}
\newcount\aeb@numChoices
\newcount\aeb@ranChoice
\newtoks\aeb@hold\aeb@hold={}
%    \end{macrocode}
% This is the command that begins the randomization of the alternatives.
% First we initialize some scratch macros to hold the choices, then
% we look for the next token, if it is \cs{Ans} we then execute \cs{@getAns}
% otherwise, we're finished.
%    \begin{macrocode}
\def\@@bChoices{\gdef\@temphold{}\gdef\@tempholdrandom{}%
  \gdef\@tempholdfreeze{}\aeb@searchfortoken{\@getAns}%
}
\def\aeb@searchfortoken#1{%
  \@ifnextchar\Ans{\advance\aeb@numChoices1\relax#1}
    {\@ifnextchar\eFreeze{\expandafter\@getFreezeAns\@gobble}
    {\@ifnextchar\par{\def\@@temp{\aeb@searchfortoken{#1}}%
    \expandafter\@@temp\@gobble}{\@eChoices}}}%
}
%    \end{macrocode}
% The non-frozen questions will be held in the macro \cs{@temphold}.
% We keep track of the number of choices using the counter \cs{aeb@numChoices}.
%    \begin{macrocode}
\long\def\@getAns\Ans#1\eAns{%
  \g@addto@macro\@temphold{{\Ans#1\eAns}}%
  \aeb@searchfortoken{\@getAns}%
}
%    \end{macrocode}
% We've encountered \cs{eFreeze}, if the next token is \cs{Ans}, go get the
% choices, otherwise, we are finished.
%    \begin{macrocode}
\def\@getFreezeAns{\aeb@searchfortoken{\@@getFreezeAns}}
%    \end{macrocode}
% Get the frozen choice, then look for another. Hold these frozen choices
% in the macro \cs{@tempholdfreeze}.
%    \begin{macrocode}
\long\def\@@getFreezeAns\Ans#1\eAns{%
  \g@addto@macro\@tempholdfreeze{\Ans#1\eAns}%
  \aeb@searchfortoken{\@@getFreezeAns}%
}
%    \end{macrocode}
% When we are finished finding all the choices, we come here to randomize the choices.
%    \begin{macrocode}
\long\def\@eChoices#1\eChoices{%
  \aeb@randomizeChoices{\the\aeb@numChoices}%
}
%    \end{macrocode}
% The routine that randomizes the choices. Basically, we use \texttt{random.tex} to get
% a random number between one and \cs{aeb@numChoices}, inclusive. Then we search through
% the list of choices (\cs{@temphold}, moved to \cs{aeb@hold}). The one selected at random
% is moved to \cs{@tempholdrandom}, and the rest of the choices are moved to \cs{@temphold},
% here \cs{aeb@hold} is used as a scratch token register.
%    \begin{macrocode}
\def\aeb@randomizeChoices#1{%
  \setrannum{\aeb@ranChoice}{1}{#1}
  \eqtmpcnta\z@\aeb@hold=\expandafter{\@temphold}\def\@temphold{}%
  \expandafter\@tfor\expandafter
    \@temp\expandafter:\expandafter=\the\aeb@hold \do {%
    \advance\eqtmpcnta\@ne
    \ifnum\eqtmpcnta=\aeb@ranChoice\relax
      \aeb@hold=\expandafter\expandafter\expandafter
        {\expandafter\@tempholdrandom\@temp}%
        \edef\@tempholdrandom{\the\aeb@hold}%
    \else
      \aeb@hold=\expandafter\expandafter\expandafter
        {\expandafter\@temphold\expandafter{\@temp}}%
      \edef\@temphold{\the\aeb@hold}%
    \fi
  }%
%    \end{macrocode}
% We repeat this process a total of \cs{aeb@numChoices}, the original count of the number
% of choices. Once finished, we go to \cs{aeb@finishedRandomizing} to lay out the
% randomized choices for typesetting.
%    \begin{macrocode}
  \aeb@numChoices=#1
  \advance\aeb@numChoices\m@ne
  \ifnum\aeb@numChoices=\z@
    \def\aeb@next{\aeb@finishedRandomizing}\else
    \def\aeb@next{\aeb@randomizeChoices{\the\aeb@numChoices}}\fi
  \aeb@next
}
%    \end{macrocode}
% This command assembles the questions held in random order in the command \cs{@tempholdrandom} and
% the frozen ones held in \cs{@tempholdfreeze}, and lays out the choices for typesetting.
%    \begin{macrocode}
\def\aeb@finishedRandomizing{%
  \aeb@hold=\expandafter\expandafter\expandafter
    {\expandafter\@tempholdrandom\@tempholdfreeze}%
  \gdef\@temphold{}\gdef\@tempholdrandom{}\gdef\@tempholdfreeze{}%
  \edef\finished@Randomizing{%
  \noexpand\@@ansChoices
  \the\aeb@hold
  \noexpand\eChoices}%
  \finished@Randomizing
}
%    \end{macrocode}
%    \begin{macro}{\saveRandomSeed}
%    \begin{macro}{\inputRandomSeed}
%    \begin{macro}{\useRandomSeed}
%
% \cs{saveRandomSeed} causes \texttt{exerquiz/eqexam} to save the last random seed used.
%
% When you have labels, as we might have in a list of multiple choices, the save feature
% needs to be turned off for several runs of latex until the label reference
% becomes up to date.
%
% \cs{inputRandomSeed} causes \texttt{exerquiz/eqexam} to input the last random seed used, if
% one exists, to re-seed the randomization so a new random sequence
% will be generated. This allows you to get a new sequence every time
% you latex.
%
% (2013/09/17) Made a number of changes so that the randomization of \cs{bChoices}
% and \cs{eChoices} works well with the \textsf{ran\_toks}. There is a lot of common
% code, and commands with the same name. I've also change from using the aux file
% \cs{jobname\_ran.sav} to \cs{jobname\_rt.sav}, the latter being the aux file used
% by \textsf{ran\_toks}. Now, there share a common aux file and common initial and final
% seeds.
%    \begin{macrocode}
\def\saveRandomSeed{\PackageInfo{exerquiz}
  {The command \string\saveRandomSeed\space
  is deprecated.\MessageBreak Seed automatically saved}}
%    \end{macrocode}
% I \cs{let} the commands in this file to the companion commands in \textsf{ran\_toks} file.
% The user can use either set of commands \cs{inputRandomSeed} or \cs{useLastSeed} as one
% pair and \cs{useRandomSeed} and \cs{useThisSeed} as the other pair.
%    \begin{macrocode}
\@ifpackageloaded{ran_toks}{%
  \let\inputRandomSeed\useLastAsSeed
  \let\useRandomSeed\useThisSeed
}{%
  \def\inputRandomSeed{\eq@readRandomData}%
  \def\useRandomSeed#1{\saveseedfalse\randomi=#1}%
}
\def\InitSeedValue{\the\randomi} % dps
\@ifundefined{ifsaveseed}{\newif\ifsaveseed\saveseedtrue}{} % dps
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \begin{macrocode}
\def\eq@writeRandomData{%
  \ifsaveseed
    \@ifundefined{saveseedinfo}{\newwrite\saveseedinfo}{}
    \immediate\openout \saveseedinfo \jobname_rt.sav
    \let\verbatim@out\saveseedinfo
    \def\eqrt@msgi{initializing seed value}%
    \def\eqrt@msgii{last random number used}%
    \uccode`c=`\%\uppercase{%
      \immediate\write\verbatim@out
        {\InitSeedValue\space c \eqrt@msgi}%
      \immediate\write\verbatim@out
        {\the\randomi\space c \eqrt@msgii}%
    }\immediate\closeout\saveseedinfo
  \fi
}
\AtEndDocument{\eq@writeRandomData}
%    \end{macrocode}
% Save the data to the file \cs{jobname\_ran.sav}.
%    \begin{macrocode}
\def\eq@readRandomData{\IfFileExists{\jobname_rt.sav}{%
  \PackageInfo{exerquiz}{Inputting \jobname_rt.sav}%
 \@ifundefined{readsavfile}{\newread\readsavfile}{}%
  \openin\readsavfile=\jobname_rt.sav
  \read\readsavfile to \InitSeedValue
  \read\readsavfile to \eqlastRandomNum
  \closein\readsavfile
  \randomi=\eqlastRandomNum
  \xdef\InitSeedValue{\the\randomi}%
  \immediate\closeout\readsavfile
}{%
  \PackageInfo{exerquiz}{\jobname_rt.sav cannot
  be found, \MessageBreak
  using the random initializer}%
}}
%    \end{macrocode}
%    \begin{macrocode}
%</randomize>
%    \end{macrocode}
%\subsection{In Support of showgrayletters}
%
% This is a hack to reference multiple choice questions when the
% \texttt{showgrayletters} option is in effect. We define \cs{REF} to
% return the uppercase version of the letters.
%    \begin{macrocode}
%<*package|eqexam>
%    \end{macrocode}
%    \begin{macro}{\graylettersOn}
%    \begin{macro}{\graylettersOff}
% Convenience commands for turning on or off the gray letter feature
%    \begin{macrocode}
\def\graylettersOn{\aebshowgrayletterstrue}
\def\graylettersOff{\aebshowgraylettersfalse}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{macrocode}
\def\aeb@exiii{\expandafter\expandafter\expandafter}
%    \end{macrocode}
%    \begin{macro}{\REF}
% Same syntax as \cs{ref}, including a \texttt{*} option. the
% \texttt{*} version does not create a link. If
% \texttt{showgrayletters} is not in effect, then \cs{REF} is
% equivalent to \cs{ref}.
%\changes{v6.06c}{2007/04/26}
%{
%   Added \string\cs{REF} in support of the \string\texttt{showgrayletters} option.
%}
%\changes{v6.4d}{2011/07/14}{%
%   Correct \string\cs{REF} so that a link is created.
%}
%    \begin{macrocode}
\def\REF{\@ifstar{\let\isREFstar\eq@One\aeb@REFstar}
  {\let\isREFstar\eq@Zero\aeb@REF}}
\def\aeb@REFstar#1{\@ifundefined{r@#1}{\hbox{\reset@font\bfseries ??}}
  {\ifaebshowgrayletters\aeb@buildUpperCaseRef{#1}%
   \else\ref*{#1}\fi}%
}
\def\aeb@REF#1{\@ifundefined{r@#1}{\hbox{\reset@font\bfseries ??}}
  {\ifaebshowgrayletters\aeb@buildUpperCaseRef{#1}%
   \else\ref{#1}\fi}%
}
%</package|eqexam>
%<*eqexam>
\def\aeb@buildUpperCaseRef#1{%
  \xdef\tmp@expand{\aeb@exiii\@firstoftwo\csname r@#1\endcsname}%
  \xdef\tmp@expand{\uppercase{\tmp@expand}}\tmp@expand
}
%</eqexam>
%<*package>
\def\aeb@buildUpperCaseRef#1{%
  \xdef\tmp@expand{\aeb@exiii\@firstoffive\csname r@#1\endcsname}%
  \xdef\tmp@expand{\uppercase{\tmp@expand}}%
  \if\isREFstar\eq@One\tmp@expand\else\hyperref[#1]{\tmp@expand}\fi
}
%    \end{macrocode}
%    \end{macro}
%
%    \subsection{Circles instead of Rectangles}
%
% For quizzes only, there is now an way to use circles for the radio button
% fields for multiple choice questions (not for multiple selection questions, however).
%
%    \begin{macro}{\useMCCircles}
% Execute this command prior to the quiz you want to use circular radio buttons. The command
% saves the values of \cs{every@qRadioButton} and \cs{every@qCheckBox}, then uses the
% every mechanism to set the all radio buttons created in a quiz to a circle symbol, we also
% set all check boxes used in multiple choice question to a transparent border.
%
%\changes{v6.3j}{2008/12/08}
%{
%   Added \string\cs{useMCCircles} and \string\cs{useMCCRects}.
%}
% \par\medskip\noindent We use a switch to keep track of ``circle mode.'' If the
% document author invokes \cs{useMCCircles} when we are already in circle mode,
% \cs{useMCCircles} does nothing.
%    \begin{macrocode}
\newif\ifaeb@usecircles\aeb@usecirclesfalse
%    \end{macrocode}
%    \begin{macrocode}
\let\insert@circlesymbol\@empty
\def\useMCCircles{%\useForms
  \ifaeb@usecircles\else
    \global\aeb@usecirclestrue
    \gdef\insert@circlesymbol{\symbolchoice{circle}}%
  \fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\useMCRects}
% We can restore the default behavior by executing \cs{useMCRects} prior to the next quiz.
% The command restores the state of \cs{every@qRadioButton} and \cs{every@qCheckBox}
% to their values prior to the last invocation of \cs{useMCCircles}.
%    \begin{macrocode}
\def\useMCRects{\useForms
  \ifaeb@usecircles\global\aeb@usecirclesfalse
    \global\let\insert@circlesymbol\@empty
  \fi
}
\let\useMCCRects\useMCRects
%    \end{macrocode}
%    \end{macro}
%
%    \section{Objective Style Questions}
%
% The code for objective style questions is very simple. The
% evaluation of the  user's response is done by JavaScript. The
% JavaScript is inserted into the PDF file through DLJS. For
% authors using \textsf{pdftex} or \textsf{dvipdfm}, this process
% is automatic; for authors using the distiller (hence, would use
% the \texttt{dvips} or \texttt{dvipsone} option), the solution is
% also automatic if you  use \textbf{Acrobat 5.0}. If you do not have
% the latest version  of Acrobat, the DLJS must be inserted
% manually using the \texttt{Document > Insert Pages} menu item. See
% paragraphs below for a little more detail, or see the manual.
%
% There are two kinds of questions that can be posed (actually only one type):
% (1) a question that has a numerical answer;
% (2) a question that has a symbolic answer in one variable,
% $x$. The symbolic answer must reduce, however, to a numerical value when
% $x$ is given a numerical value.  Thus, only questions whose answers can
% be reduced to numerical values can be posed.
%
% If the author has Acrobat 5.0, the \textsf{exerquiz} package should be
% built using the \texttt{Acrobatv} option in the
% \textsf{exerquiz.ins} file. In this case, Document level
% Javascript will be input when the newly distilled file is
% first opened in the Acrobat Viewer. If the function ``CkBalP'' is
% undefined, the we input the FDF file contained the Doc Level JS.
% The file needs to be saved (Save As) for the Doc Level JS to
% remain in the PDF file.
%
% In the case of the author using Acrobat 4.0, he/she needs to load
% manually insert the \texttt{eq\_DLJS.pdf} file. If only exercises
% are used, this insertion is not needed.
%    \begin{environment}{oQuestion}
% This was my first attempt and I have not deleted it from the package yet.
% Useful for posing a single question only. The argument is the (unique) name
% of this question. This name is used to define the macro \cmd{\oField} which is used
% by support macros.  The \texttt{shortquiz} environment can also be used for
% single/multiple questions as well.
%    \changes{v8.8.2}{2021/05/29}{Check for dupl oQuestion names}
%    \begin{macrocode}
\let\oqpriorhook\@empty
\newenvironment{oQuestion}[1]{\csarg % dps5-29
  \ifx{oQName-#1}\relax
    \csarg\gdef{oQName-#1}{1}\else
    \PackageWarning{exerquiz}{%
      The quiz name '#1' is already used,\MessageBreak
      please choose a quiz name unique throughout\MessageBreak
      this document}\csarg\gdef{oQName-#1}{0}%
  \fi
%    \end{macrocode}
% (06/08/10) The next two lines initialize the macros for registering the
% question label, i.e., \texttt{2(a)(ii)}. These two lines are repeated for
% the \texttt{shortquiz} and \texttt{quiz} environments.
%    \begin{macrocode}
  \let\@currentQues\@empty
  \xdef\eq@pageThisQ{\the\c@page}\global
  \let\eqQzQuesList\@empty
  \xdef\oField{#1}\xdef\curr@quiz{#1}\xdef\currQuiz{#1}%
  \g@addto@macro\ListOfSQuizNames{,#1}\let\@qzsolndest\@empty
  \let\eqQuizType\isSQZ\gdef\eqPTs{1}\global\let\eqQT\eq@na
  \let\answers\answers@sq
  \let\endanswers\endanswers@sq
  \let\manswers\manswers@sq
  \let\endmanswers\endmanswers@sq
  \let\solution\solution@sq
  \let\endsolution\endsolution@sq
  \noindent\oqpriorhook\sq@IDTxtField\ifx\aebTitleQuiz\@empty
  \else\aebtitleQuiz\fi\ignorespaces
}{%
  \global\let\aebtitleQuiz\@empty
  \global\let\aebTitleQuiz\@empty
  \global\let\eq@tq@star\relax
%    \end{macrocode}
%    (2021/05/07) Reset \cs{eqpriorhook} at end of \env{oQuestions} environment.
%    \changes{v8.7.6}{2021/05/07}{Reset \string\cs{eqpriorhook} at end of \string\env{oQuestions} environment}
%    \begin{macrocode}
  \global\let\oqpriorhook\@empty
  \aftergroup\ignorespaces
}
\def\oSolution#1{\edef\@qzsolndest{#1}}
%    \end{macrocode}
%    \end{environment}
%    \begin{macro}{\replaceExclPt}
% When processing a mathematical expression, replace \texttt{n!} or \texttt{(n)!} with
% \texttt{fact(n)}. Used with the \texttt{combinatorics} option of \textsf{dljslib} package.
%    \begin{macrocode}
\def\replaceExclPt#1{\def\replaceexclaim{#1}}
\replaceExclPt{false}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\negPointsAllowed}
% Used with the \texttt{ProcessMultiSelection} when processing \texttt{manswers} environments.
% The default is not to allow the score to go below 0. By executing \cs{negPointsAllowed}
% in the preamble, we allow the score to go below zero.
%\changes{v6.3i}{2008/10/22}
%{
%   Added \string\cs{negPointsAllowed} to allow negative scores on quizzes. This is only relevant
%   when the quiz has a \string\texttt{manswers} environment.
%}
%    \begin{macrocode}
\def\negPointsAllowed{\def\negpointsallowed{true}}
\@onlypreamble{\negPointsAllowed}
\def\negpointsallowed{false}
\def\negPointsMarkupAllowed{\def\negpointsmarkupallowed{true}}
\def\negpointsmarkupallowed{false}
\@onlypreamble{\negPointsMarkupAllowed}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\requireAlertBox}
% Turn off the ``Do not show this message again'' checkbox for objective questions
% and multiple choice questions.
%\changes{v6.3m}{2010/01/27}
%{
%   Added \string\cs{requireAlertBox} to turn off the ``Do not show this message again'' checkbox for objective questions.
%}
%The alert box displays the message \DescribeMacro{\doNotShowAgainMsg}\cs{doNotShowAgainMsg}, which by default is
%``Do not show this message again''. This message appear when \DescribeMacro{\allowNoAlertBox}\cs{allowNoAlertBox} (the default)
% is in effect.
%    \begin{macrocode}
\def\requireAlertBox{\def\bcheckboxused{false}}
\def\allowNoAlertBox{\def\bcheckboxused{true}}
\allowNoAlertBox
%    \end{macrocode}
%    \end{macro}
% When \DescribeMacro{\useCkBxAlertsOn}\cs{useCkBxAlertsOn} is expanded in the preamble, alerts
% generated by links (usually a short-quiz) uses a check box that allows its dismissal
% subsequently. \DescribeMacro{\useCkBxAlertsOff}\cs{useCkBxAlertsOff} reverts the behavior
% to alert boxes with no check box, the old default.
% \changes{v8.8.5}{2021/10/03}{Added \string\cs{useCkBxAlertsOn}}
%    \begin{macrocode}
\def\useCkBxAlertsOn{\def\buseckbx{true}} % dpsx
\def\useCkBxAlertsOff{\def\buseckbx{false}}
\useCkBxAlertsOn
%    \end{macrocode}
%    \subsection{Math Fill-In Questions}
%    \begin{macro}{\RespBox}
%    \begin{macro}{\RespBoxMath}
%    \begin{macro}{\RespBoxNT}
% \cmd{\RespBox} and \cmd{\RespBoxNT} lay out a text box, into which the
% user enters his/her response to the question. \cmd{\RespBox} expects the presence
% of \cmd{\sqTallyBox}, whereas \cmd{\RespBoxNT} does not (NT = No Tally ).
%\par\medskip
% Usage: |\RespBox[#1]#2(#3)[#4]#5#6#7#8[#9]*#10|
% \begin{description}
% \item[\ttfamily\#1 :] Optional parameter used to modify the appearance of the
%     text field.
% \item[\ttfamily\#2 :] The correct answer to the question.
%     This must be a numerical value, or a function of one variable.
%     JavaScript Note:
%     In JavaScript, functions such as \texttt{sin(x)} and \texttt{cos(x)} are
%     methods of the \texttt{Math} object.  It is not necessary, however, to
%     type \texttt{Math.sin(x)} or \texttt{Math.cos(x)}; this is done by inserting
%     the expression into a \texttt{with(Math)} group.
% \item[\ttfamily\#3 :] An optional parameter, \textit{delimited by parentheses},
% that defines the independent variable; \texttt{x}, is the default value. Note
% that this parameter is set off by parentheses.  For a multivariate question, just
% list the variables in juxtaposition, \texttt{(xyz)}.  An alternate method is to
% delimit with commas \texttt{(x,y,n)} and include the type of the variables
% \texttt{(r:x,r:y,i:n)}, where \texttt{"r"} means a real variable and \texttt{"i"}
% means an integer variable.  The variables must be either of the old style (no commas, no typing)
% or the new style. Do  not mix the styles.
%
% \changes{v8.0}{2017/08/08}{Support for multi-letter variables and alternate appearances}
% \textbf{Multi-letter variables.} Beginning with v8.0 (2017/08/08) support for multi-letter variables and appearance replacement
% is added. Within the \texttt{\#3}, use the following notation:
%\begin{verbatim}
%   (x\rpl{alpha}{y}z)
%\end{verbatim}
%This declares three variables, \texttt{x}, \texttt{alpha}, and \texttt{z}. What in fact is
%taking place is that \texttt{alpha} is replaced by \texttt{y} and processing continues from there.
%
% \textbf{Alternate appearances.} Additionally, there is  now a scheme for replacing the variables
% with alternate appearances.
%\begin{verbatim}
%   (x\rpl{alpha->\\u03B1}{y}z)
%\end{verbatim}
%The arrow notation (\texttt{->}) tells \pkg{exerquiz} to replace \texttt{alpha} with the unicode character
%\verb~\u03B1~ (note the double backslash above), which is the Greek letter alpha ($\alpha$).
%
% \item[\ttfamily\#4 :] Optional, a named destination to the solution to the
% question. If this parameter appears, then a solution must follow the
% question, enclosed in a \texttt{solution} environment.
% Alternately, the fourth parameter can be a `\texttt*', in which case, we have
% automatic naming of the destination, namely, \texttt{[\string\curr@quiz.\string\thequestionno]}
% \item[\ttfamily\#5 :] The number of samples points to be used, usually $3$ or $4$ is
% sufficient.
% \item[\ttfamily\#6 :] Precision required, the $\epsilon$ value, if you will.
% \item[\ttfamily\#7 :] Parameters \#7 and \#8 are  used to define the interval from
% which to draw the sample points. There are two forms: (1) \#7 is the left-hand endpoint
% of the interval and \#8 is the right-hand endpoint (the use of \#7 and \#8 in this form
% is deprecated); (2) the interval is defined by standard interval notation, \texttt{[a,b]}.
% For a multivariate question---one where parameter \#2 lists more than one variable,
% separate the intervals for each variable by a `x', \texttt{[0,2]x[1,2]x[3,4]}.
% \item[\ttfamily\#8 :] (1) \#8 is the right-hand endpoint of the interval (the use of this
% parameter is deprecated); (2) in the second
% case, \#8 is not used.
% \item[\ttfamily\#9 :] This optional parameter is either the name of a customized
% comparison function \textit{or} a JavaScript object with at most two properties:
% \texttt{priorParse} and \texttt{comp}. See the demo file \texttt{integer\_tst.tex} for
% examples of usage.
% \item[\ttfamily\#10:] (Only detected if following an asterisk, `\texttt*')
% The name of a JavaScript function that is to be used to process the user input.
% \end{description}
% Example:
%\begin{flushleft}\footnotesize
%|\RespBoxMath{<exp(t), 2*t, sin(t)>}(t)[soln]{3}{.0001}{[0,1]}[compare]*{ProcVec}|
%\end{flushleft}
% or (the deprecated form)
%\begin{flushleft}\footnotesize
%|\RespBoxMath{<exp(t), 2*t, sin(t)>}(t)[soln]{3}{.0001}{0}{1}[compare]*{ProcVec}|
%\end{flushleft}
% \changes{v8.1}{2017/09/02}{Sanitize superscript before reading parameters in \string\cs{RespBoxMath}}
%    \begin{macrocode}
\newcommand\RespBoxNT{\RespBoxMath}
\newcommand\RespBox{\RespBoxMath}
%    \end{macrocode}
%     (2018/03/21) Exclude unicode from \cs{RespBoxMath}
%    \changes{v8.2.2}{2018/03/21}{Exclude unicode from \string\cs{RespBoxMath}}
%    \changes{v8.2.3}{2018/09/12}{Made subscript catode 12 in \string\cs{RespBoxMath}}
%    \changes{v8.2.4}{2018/09/24}{Defined \string\cs{eqsanitize} for \string\cs{RespBoxMath}}
%    \begin{macrocode}
\def\eqsanitize{\@makeother\_\@makeother\^\@makeother\&}
\newcommand\RespBoxMath{\def\rbFlag{0}\begingroup\Hy@unicodefalse
    \eqsanitize\@RespBox}
%    \end{macrocode}
% Within \cs{RespBoxMath}, \cs{rpl} (\cs{rpl=\texttt{\underbar{r}e\underbar{pl}ace}}) is \cs{let} to \cs{eq@rpl}. The command \cs{rpl}, used
% within the variable argument of \cs{RespBoxMath}, declares a multi-letter variable. There are
% two styles, one an extension of the other: (1) |\rpl{alpha}{x}|, declares that the multi-letter
% variable `\texttt{alpha}' is the same as the usual single variable `\texttt{x}'; (2) |\rpl{alpha->\\u03B1}{x}| declare
% the variable `\texttt{alpha}' to be the same as `\texttt{x}', it also says to use |\\u0381| as the
% format appearance of `\texttt{alpha}'.
% \changes{v7.9a}{2017/08/05}{Added \string\cs{eq@rpl} to support multi-letter variables}
%    \begin{macrocode}
\def\eq@rpl#1#2{_rplVarsBy('#1','#2')@} % dps17
%    \end{macrocode}
%    \textbf{Correcting an incorrect entry.} A variation on the objective style math problem is to initially populate the response box with an
%    incorrect answer and ask the student to correct it. (Good for future teachers.) The problem type set
%    straightforward when multi-variables are not used, just specify the \cs{V} and \cs{DV} keys in the
%    optional argument of \cs{RespBoxMath}. When multi-variables are used, we enclose the question
%    with \DescribeMacro{\bInitAltAppr}\cs{bInitAltAppr}/\allowbreak\DescribeMacro{\eInitAltAppr}\cs{eInitAltAppr}. There are two variations, the first is for
%    a non-\app{dvips/Distiller} workflow (document JavaScript are embedded at the creation of the PDF;
%    the second variation is with Distiller, where the document JavaScript is embedded with \app{Acrobat}
%    after the creation of the PDF. In the latter case, the JavaScript functions used below (\texttt{processMathVars},
%    \texttt{getSubstValue}, and \texttt{RespBoxAppr} are not available yet when the document is initially
%    opened in \app{Acrobat}. As a result, an exception is thrown. When the exception is thrown,
%    \texttt{app.setTimeOut} gives a delay and the field is reset after 25 milliseconds, this causes
%    the \emph{initial} alternate appearance to appear, if that is desired.
%    \changes{v8.1a}{2017/09/03}{Added \string\cs{bInitAltAppr}/\string\allowbreak\string\cs{eInitAltAppr}
%    command pair for setting the initial alternate appearance}
%    \begin{macrocode}
\ifnum\eq@drivernum=\z@
  \def\RorRT{\r\t}\else\def\RorRT{\r}\fi
%    \end{macrocode}
%    The following commands are in support of the \cs{bInitAltAppr}/\allowbreak\cs{eInitAltAppr} command pair.
%    \begin{macrocode}
\def\toAltApprCnt{0}\def\toAltApprVar{_toAltAppr\toAltApprCnt}
\def\toAltApprCntInc{{\@tempcnta=\toAltApprCnt\relax
  \advance\@tempcnta\@ne\xdef\toAltApprCnt{\the\@tempcnta}}}
\def\setCoreInitAltAppr{%
	var\eqSP_substVars=\indepVars;\RorRT
	var\eqSP_mathVars=processMathVars(_substVars);\RorRT
	var\eqSP_substValue=getSubstValue(_substVars,event.value);\RorRT
    event.value=RespBoxAppr(event);\RorRT
    getSubstValue.aSubsts=[];%
}
%    \end{macrocode}
%   \leavevmode\DescribeMacro{\bInitAltAppr}\DescribeMacro{\eInitAltAppr} This command pair
%   are used to set the initial value of a \cs{RespBoxMath} field.
%    See the {Acro\negthinspace\TeX} article \url{http://www.acrotex.net/blog/?p=1335}
%    for a discussion of the use of \cs{bInitAltAppr}/\allowbreak
%    \cs{bInitAltAppr}.
%    An alternate method is to use \cs{formatInitAltApprs} directly
%    \begin{macrocode}
\def\bInitAltAppr{\ifShowAppr
  \def\ShowApprSAVE{true}\toAltApprCntInc\ShowApprfalse
  \def\eqAddAAFormat{\ifnum\eq@drivernum=\z@ try\eqLBr\RorRT\fi
    \setCoreInitAltAppr\ifnum\eq@drivernum=\z@\r\eqRBr catch(e){\RorRT
    var\eqSP\toAltApprVar=%
    app.setTimeOut('this.resetForm("'+event.target.name+'");%
    app.clearTimeOut(\toAltApprVar);',250);\r}\fi}\else
    \def\ShowApprSAVE{false}\fi
}
\def\eInitAltAppr{\@nameuse{ShowAppr\ShowApprSAVE}%
  \ifShowAppr\altApprOn\let\eqAddAAFormat\@empty\fi}
%    \end{macrocode}
% Get any changes in the appearance of the text box
% \changes{v6.4c}{2011/07/01}{\string\cs{RespBoxMath} now records its lists of
% independent variables under the global variable \string\texttt{\_mathVars}.}
%    \begin{macrocode}
\begin{defineJS}[\makeesc\*\makecmt\%]{\AAKqRespBoxMath}
%    \end{macrocode}
%    \cs{AAKqRespBoxMath} is the default keystroke action script for \cs{RespBoxMath}
%    \begin{macrocode}
if(event.willCommit){
  RecordPointValue(*eqPTs,*thequestionno*ifx*grpquestions*eq@One,%
*thegrpquestionno,*grpPointValue,*grpTotalWeight,%
"*grpEvalFunction"*fi);
  RecordProblemType("*eqQT",*thequestionno);
%    \end{macrocode}
%    If there are substitute variables, \cs{ifSubstVars} is true, and the script below
%    are the lines developed in support of multi-letter variables.
%    \begin{macrocode}
*ifSubstVars%
  var _substVars=*indepVars;
  var _mathVars=processMathVars(_substVars);
  var _substValue=getSubstValue(_substVars,event.value);
  var _substAns=getSubstValue(_substVars,"*eqCorrectAns");
  var retn=*processJSfunc(*rbArgs,%
    *compareJSfunc,_substValue);*else%
  var _mathVars=*indepVars;
  var retn=*processJSfunc(*rbArgs,*compareJSfunc);*fi
  ProcUserResp(retn,event.value,*thequestionno,0%
*ifx*grpquestions*eq@One,*thegrpquestionno*fi);
}
if (!isQuizInitialized("*currQuiz")) {
  *eqObjAlert*eqAppAlert(InitMsg("*bqlabelISO"),3);
  event.rc = false;%
*ifx*eqAddAAKeystroke*@empty*else
*eqAddAAKeystroke*fi
}
\end{defineJS}
\def\RespBoxMathDefaults{%
  \BC{0 0 0}\S{S}\textColor{0 g}\F{\FPrint}\W{1}
}
\def\moreRespBoxMathDefaults{%
  \edef\@moreRespBoxMathDefaults{%
    \if\eqQuizType\isQZ\ifx\eq@online\eq@YES
      \ifeq@noquizsolutions
      \else\noexpand\Ff{\FfReadOnly}\fi\fi\fi
  }%
}
\let\eqAddAAFormat\@empty
%    \end{macrocode}
%    \DescribeMacro{\eqSP}\cs{eqSP} is a space character to keep \textsf{dvips} from breaking lines at space.
%    \begin{macrocode}
\def\eqSP{\string\040}
\def\eqLBr{\string\173}
\def\eqRBr{\string\175}
%    \end{macrocode}
% Keystroke action for \cs{RespBoxMath}.
%    \begin{macrocode}
\begin{defineJS}[\makeesc\!\makecmt\%]{\rbmAAKey}
if(event.willCommit) {
!ifSubstVars%
%    \end{macrocode}
%     If there are multi-letter variables (\cs{SubstVarstrue}), we insert the code developed.
%    \begin{macrocode}
  var _substVars=!indepVars;
  var _mathVars=processMathVars(_substVars);
  var _substValue=getSubstValue(_substVars,event.value);
  var _substAns=getSubstValue(_substVars,"!eqCorrectAns");
  var retn=!processJSfunc(!rbArgs,%
!compareJSfunc,_substValue);!else%
  var _mathVars=!indepVars;
  var retn=!processJSfunc(!rbArgs,!compareJSfunc);!fi%
!ifx!@sqTurnOffAlerts!eq@One
  OnBlurRespBox(retn,"!curr@quiz");!fi%
!ifx!eqAddAAKeystroke!@empty!else
!eqAddAAKeystroke!fi
}
\end{defineJS}
%    \end{macrocode}
%    The actions of \cs{RespBoxMath}
%    \begin{macrocode}
\def\@@RespBoxMathActions{%
  \AA{\if\eqQuizType\isQZ
    \AAKeystroke{\AAKqRespBoxMath}
    \AAFormat{\ifShowAppr\ifSubstVars\ifarrowDelim
%    \end{macrocode}
%    The \texttt{RespBoxApp()} JavaScript function replaces the multi-letter variable (\texttt{alpha}, for example)
%    with its appearance (|\\u03B1|, eg).
%    \begin{macrocode}
      try{event.value=RespBoxAppr(event);}catch(e){}\r
        \fi\fi\fi\eqAddAAFormat}
  \else
    \AAKeystroke{\rbmAAKey}
    \AAFormat{\ifShowAppr\ifSubstVars\ifarrowDelim
      try{event.value=RespBoxAppr(event);}catch(e){}\r\fi\fi\fi
        \eqAddAAFormat}%
    \AAOnFocus{\JS{var retn = null;}}%
    \AAOnBlur{\JS{OnBlurRespBox(null,"\curr@quiz");}}%
\fi
  }
}
\def\annot@subtype@rbm{rbm}
\newcommand\@RespBox[1][]
{%
  \edef\annot@subtype{\annot@subtype@rbm}%
  \eq@AddProbToQzQuesList
  \smallskip\ifx\grpquestions\eq@Zero
    \addtocounter{eqpointvalue}{\eqPTs}\fi
  \if\eqQuizType\isQZ
    \def\rbFlag{1}\global\IsRespBoxtrue
    \ifx\grpquestions\eq@One
      \stepcounter{grpquestionno}%
      \def\Fld@name{%
        grpobj.\curr@quiz.\thequestionno.\thegrpquestionno}%
    \else
      \eq@recordThesePTs\eq@recordProbType
      \edef\eqtmp{\aPointType}%
      \xdef\aPointType{\eqtmp,[\eqPTs,"math"]}%
      \stepcounter{questionno}%
      \def\Fld@name{obj.\curr@quiz.\thequestionno}%
    \fi
  \else % shortquiz
    \ifx\grpquestions\eq@One
      \stepcounter{grpquestionno}%
      \def\Fld@name{%
        grpobj.\oField.\thequestionno.\thegrpquestionno}%
    \else
      \stepcounter{questionno}%
      \def\Fld@name{%
        obj.\oField.\thequestionno}%
    \fi
  \fi
%    \end{macrocode}
% Changed (v6.3f, 2008/10/08) the command \cs{array} to \cs{Array} to avoid clashing with the
% array command defined in \texttt{amsmath}.
%    \begin{macrocode}
  \let\Array\aeb@array
  \moreRespBoxMathDefaults
%    \end{macrocode}
% (2014/01/23) This is tricky, I'm enclosing \cs{text@@Field} in an \cs{mbox}, beginning here
%    \begin{macrocode}
  \leavevmode\hbox\bgroup\let\rpl\eq@rpl
  \text@@Field{#1}{\Fld@name}%
  {\RBW}{\DefaultHeightOfWidget}%
  {\eq@protect\AA}{\eq@setWidgetProps\eq@RespBox}%
  {\RespBoxMathDefaults\@moreRespBoxMathDefaults
  \@@RespBoxMathActions\every@eqTextField\every@RespBoxMath}%
}
%    \end{macrocode}
% Get the second parameter, which is the correct answer to the question, and
% test to see if there is a specification for the optional third parameter,
% which is the variable list, `\texttt x' is the default.
% \changes{v8.1}{2017/09/02}{Sanitize superscript before \string\cs{pdfstringdef} is applied}
% \changes{v8.1c}{2017/09/30}{Define \string\cs{eqCorrectAnsTeX} to display the answer
% in preview mode.}
%    \begin{macrocode}
\def\eq@RespBox#1{\pdfstringdef\eqCorrectAns{#1}%
  \gdef\eqCorrectAnsTeX{#1}\if\grpquestions\eq@Zero
%    \end{macrocode}
%    If not within a \texttt{mathGrp} environment, if within a MCFI command pair we save the author's
%    answer as \cs{s@veCorrAnsMCFI}; otherwise, we record the author's answer. If within
%    \texttt{mathGrp} environment, we record is as part of the group array to be use later.
%    \begin{macrocode}
    \ifwithinMCFI\gdef\s@veCorrAnsMCFI{"#1"}\fi
  \else
    \eq@recordGrpAnsArray{"#1"}\fi
  \@ifnextchar({\@eq@RespBox{#1}}{\@eq@RespBox{#1}(x)}}
%    \end{macrocode}
% Pick up the optional third parameter, then test whether the optional fourth parameter is there.
% There are two forms: the [mydest] an explicit destination for the solution to the problem, or
% a `\texttt*', in which case, we have automatic naming, the name is
% \texttt{[\string\curr@quiz.\string\thequestionno]}.
%    \begin{macrocode}
\def\@eq@RespBox#1(#2){\@ifnextchar[{\@eq@RespB@x{#1}(#2)}%
  {\@ifstar{\@eq@RespB@x{#1}(#2)[\curr@quiz.\thequestionno]}%
    {\@eq@RespB@x{#1}(#2)[]}}}
%    \end{macrocode}
% Now get the next three parameters: the number of samples, the precision, and the first of the
% two interval parameters.
%    \begin{macrocode}
\def\eq@ZERO{0}
\def\defaultRDPrecision#1{\def\eq@defaultRDPrecision{#1}}
\defaultRDPrecision{1E-14}
%    \end{macrocode}
% dps/change 02/23/07 Here we try to implement a suggestion of Bruce Wagner. If the tolerance
% is set to zero, then use \texttt{reldiffCompare} as the default compare, and set the tolerance
% to some small value. Here, the small value is the value of the command
% \cs{eq@defaultRDPrecision} which can be set by \cs{defaultRDPrecision}. The default definition
% is \verb!\defaultRDPrecision{1E-14}!.
%    \begin{macrocode}
\newif\ifarrowDelim\arrowDelimfalse
%    \end{macrocode}
%   The problem is to detect when \cs{indepVars} contains the arrow notation (\verb~->~), this signals
%   that the appearance of the user's response is to be replaced by another appearance. The command
%   \cs{GiiRpli} attempts to do just that, it sets \cs{arrowDelim} to true if an arrow is detectect,
%   otherwise, to false.
%    \begin{macrocode}
\def\rpl@#1#2{\rpl@i#1->\@nil}
\def\rpl@i#1->#2\@nil{\def\argii{#2}\ifx\argii\@empty\else
  \global\arrowDelimtrue\fi}
\def\GiiRpli#1{\global\arrowDelimfalse\GiiRplii#1\rpl{}{}\@nil}
\def\GiiRplii#1\rpl#2#3#4\@nil{\def\argiv{#4}%
  \ifx\argiv\@empty\let\eq@next\relax\else
  \rpl@{#2}{#3}\ifarrowDelim\let\eq@next\relax\else
    \def\eq@next{\GiiRplii#4\@nil}\fi\fi
  \eq@next}
%    \end{macrocode}
%    \textbf{Is arrow specified?} \cs{isAltApprSpec} determines whether the delimiter `\texttt{->}' is present, if it is
%    we set |\global\arrowDelimtrue|, otherwise it is globally set to false. Its supporting
%    code is listed above: \cs{rpl@} and \cs{GiiRpli}
%    \begin{macrocode}
\def\isAltApprSpec#1{\bgroup\if\frstIsrpl\eq@YES\GiiRpli{#1}\else
  \expandafter\GiiRpli\expandafter{#1}\fi\egroup} % dps17
%    \end{macrocode}
%     If the independent variables are passed as a command, we need
%     to expand first; on the other hand, if the argument is literal and begins with \cs{rpl}
%     we do not expand first. This is to get a correct determination of \cs{ifSubstVars}
%     and \cs{ifarrowDelim}.
%    \begin{macrocode}
\def\isFrstrpl#1#2\@nil{\ifx#1\rpl\let\frstIsrpl\eq@YES\else
  \let\frstIsrpl\eq@NO\fi}
%    \end{macrocode}
%    Macros to count the number of independent variables
%    \begin{macrocode}
\def\cntComm@s#1{\@tempcnta\z@\expandafter\cntComm@si#1,,\@nil}
\def\cntComm@si#1,#2,\@nil{\def\argii{#2}\ifx\argii\@empty
  \def\eq@next{\edef\nC{\the\@tempcnta}}\else
  \advance\@tempcnta\@ne\def\eq@next{\cntComm@si#2,\@nil}\fi
  \eq@next}\def\eq@SC{;}\def\rplSofT#1#2{#2}
\def\cntVars#1{\let\rpl\rplSofT\edef\eV@rs{#1}\let\rpl\eq@rpl
  \cntComm@s{\eV@rs}\ifnum\nC>\z@
  \@tempcnta\nC\relax\advance\@tempcnta\@ne
  \xdef\nV{\the\@tempcnta}\else\@tempcnta\z@
  \expandafter\cntVarsi\eV@rs;\@nil\fi}
  \def\cntVarsi#1#2\@nil{\def\argii{#2}%
  \ifx\argii\eq@SC\def\eq@next{\advance\@tempcnta\@ne
    \edef\nV{\the\@tempcnta}}\else\advance\@tempcnta\@ne
    \def\eq@next{\cntVarsi#2\@nil}\fi
  \eq@next}
\def\eq@X{x}
%    \end{macrocode}
%    It there repetition? (\texttt{[0,1]*3}, eg)
%    \begin{macrocode}
\def\eq@isThereRept#1{\let\eq@isRept\eq@Zero\expandafter
  \eq@isThereRepti#1*\@nil}
\def\eq@isThereRepti#1*#2\@nil{\def\argii{#2}\ifx\argii\@empty
  \let\eq@isRept\eq@Zero\else\let\eq@isRept\eq@One\fi}
%    \end{macrocode}
%    Expand repetition if present (\texttt{[0,1]*3=[0,1]x[0,1]x[0,1]}, eg)
%    \begin{macrocode}
\def\eq@obeyReptOfIntrvls#1{%
  \expandafter\eq@isThereRept\expandafter{#1}% sets \eq@isRept
  \if\eq@isRept\eq@Zero\relax\let\eq@interv@ls\@empty\expandafter
    \g@addto@macro\expandafter\eq@interv@ls
    \expandafter{#1}\let\eq@next\relax\else\let\eq@interv@ls\@gobble
    \def\eq@next{\expandafter
      \eq@obeyReptOfIntrvlsi#1x[]x\@nil}\fi\eq@next}
\def\eq@obeyReptOfIntrvlsi#1[#2]#3#4x#5\@nil{%
  \def\argi{#2}\def\argii{#3}\def\argiv{#5}%
  \ifx\argi\@empty\let\eq@next\relax\else
    \ifx\argii\eq@X\g@addto@macro\eq@interv@ls{x[#2]}%
      \def\eq@next{\eq@obeyReptOfIntrvlsi#4x#5x\@nil}\else
      % repetition of an interval
      \eq@ddtorepIntrvl{[#2]}{#4}%
      \def\eq@next{\eq@obeyReptOfIntrvlsi#5x\@nil}\fi
  \fi
  \eq@next
}
\def\eq@ddtorepIntrvl#1#2{\@tempcnta=#2 \eq@ddtorepIntrvli{#1}{#2}}
\def\eq@ddtorepIntrvli#1#2{\@whilenum\@tempcnta>\z@\do
  {\g@addto@macro\eq@interv@ls{x#1}\advance\@tempcnta\m@ne}}
%    \end{macrocode}
%    Macros to count the number of intervals. First determine if there
%    are repetitions if so, expand them \cs{eq@obeyReptOfIntrvls} returns
%    the expanded intervals in \cs{eq@interv@ls}
%    \begin{macrocode}
\def\cntIv@ls#1{\@tempcnta\z@\expandafter\cntIv@lsi#1xxx\@nil}%
%    \end{macrocode}
%    Before counting the intervals, determine if there is repetition, if so
%    expand those intervals appropriately.
%    \begin{macrocode}
\def\cntIv@lsi#1x#2x\@nil{\def\argii{#2}\ifx\argii\eq@X
  \advance\@tempcnta\@ne
  \edef\nI{\the\@tempcnta}\let\eq@next\relax\else
  \advance\@tempcnta\@ne\def\eq@next{\cntIv@lsi#2x\@nil}\fi
\eq@next}
%    \end{macrocode}
%    A interval specification might have an intersection in it (\texttt{\&}, so for the purpose
%    of counting, we count the intervals up to the first ampersand.
%    \changes{v8.1b}{2017/09/06}{Fixed a problem with the use of \string\cs{RespBoxMath}
%    when it is within a tabular environment.}
%    \begin{macrocode}
\begingroup\@makeother\&
\gdef\eq@ProcIntrvls#1{\expandafter
  \eq@ProcIntrvlsi#1&&\@nil}
\gdef\eq@ProcIntrvlsi#1&#2&#3\@nil{\def\argii{#2}%
  \ifx\argii\@empty
%    \end{macrocode}
%     The intervals do not contain an ampersand.
%     Expand intervals, if necessary result returns in \cs{eq@interv@ls}
%    \begin{macrocode}
    \eq@obeyReptOfIntrvls{#1}%
%    \end{macrocode}
%     Count the intervals
%    \begin{macrocode}
    \cntIv@ls{\eq@interv@ls}%
  \else
%    \end{macrocode}
%     The intervals contain an ampersand (union of two intervals of equal dimension assumed,
%     \meta{interval${}_1$}\texttt{\&}\meta{interval${}_1$}).
%     Expand the first set of union.
%    \begin{macrocode}
    \eq@obeyReptOfIntrvls{#1}%
%    \end{macrocode}
%     Save this result in \cs{interv@ls}
%    \begin{macrocode}
    \edef\interv@ls{\eq@interv@ls}%
    \cntIv@ls{\eq@interv@ls}%
%    \end{macrocode}
%     Expand the second set of union
%    \begin{macrocode}
    \eq@obeyReptOfIntrvls{#2}%
    \edef\eq@interv@ls{\interv@ls&\eq@interv@ls}%
  \fi
}
\endgroup
%    \end{macrocode}
%    \cs{RespBoxMath} continues here
%    \begin{macrocode}
\def\@eq@RespB@x#1(#2)[#3]#4#5#6{\xdef\@qzsolndest{#3}% dps17
  \gdef\indepVars{"#2"}\isFrstrpl#2\@nil
  \if\frstIsrpl\eq@YES
    \def\@IVi{#2}\else\expandafter\def\expandafter
    \@IVi\expandafter{#2}\fi
  \edef\@IVii{#2}%
  \ifx\@IVi\@IVii
%    \end{macrocode}
%     If \cs{indepVars} (\texttt{\#2}) does not contain \cs{rpl}, the two versions
%     of \cs{@IVi} and \cs{@IVii} should compare favorably. If they differ, the difference
%     is due to the presence of \cs{rpl}.
%    \begin{macrocode}
    \global\SubstVarsfalse
  \else
    \global\SubstVarstrue
    \isAltApprSpec{#2}%
  \fi
%    \end{macrocode}
%    \textbf{Counting number of variables.} We count the number of independent variables.
%    \begin{macrocode}
  \cntVars{#2}\def\eq@precision{#5}%
  \ifx\eq@precision\eq@ZERO
    \def\eq@defaultCompare{reldiffCompare}%
%    \end{macrocode}
%    (2017/01/11) Replace \texttt{\#1} by \cs{eqCorrectAns} to delay expansion
%    \changes{v7.8d}{2017/01/11}{Replace \string\texttt{\#1} by \string\cs{eqCorrectAns} to delay expansion}
%    \begin{macrocode}
    \def\rbArgstmp{\rbFlag,%
      \ifSubstVars_substAns\else"#1"\fi,#4,%
        \eq@defaultRDPrecision}%
  \else
    \def\eq@defaultCompare{diffCompare}%
    \def\rbArgstmp{\rbFlag,%
      \ifSubstVars_substAns\else"#1"\fi,#4,#5}%
  \fi
%    \end{macrocode}
% We have arrived at the first of possibly two parameters that define the interval(s)
% from which to sample random points. There are two forms, the old style (deprecated)
% and the new style. We must detect which form this is.
% \par\medskip\noindent
% (10/10/11) To support \cs{viidna}, we expand \texttt{\#6} first before passing it
% to the command \cs{@checkforInterval}.
%    \begin{macrocode}
  \edef\eq@ixparam{#6}\expandafter\eq@chkivIntrvls\eq@ixparam\\%
}
%    \end{macrocode}
% \DescribeMacro{\viidna} is used with the \texttt{satisfyEq} for the seventh parameter,
% these routines do not use the ninth, but there needs to be something that does not
% stop compilation.
%    \begin{macrocode}
\def\viidna{[0,1]}
%    \end{macrocode}
% If the next token is a `\texttt[', then that signals the beginning of an interval
% such as \texttt{[a,b]}, must be the new style. The second parameter is not
% needed, and not expected in this case. It would be a mistake to include it.
%    \begin{macrocode}
\def\eq@chkivIntrvls{\@ifnextchar[{\eq@chkivIntrvlsi}%
  {\eq@chkivIntrvlsii}}
%    \end{macrocode}
% This is the case of the new style of defining the interval. We insert it into the
%  arguments list, and continue on to the next stage.
%
% I have detected a problem when the ninth parameters is a JavaScript object and the left brace
% is next to the left bracket. Somehow, the left brace and right brace get absorbed. We do a
% work around, and insert a space after the left bracket.
%    \begin{macrocode}
\def\eq@chkivIntrvlsi#1\\{\eq@ProcIntrvls{#1}%
  \def\rbArgs{\rbArgstmp,"\eq@interv@ls",_mathVars}% dps17
  \@ifnextchar[{\@eq@@RespBox[ \expandafter\@gobble}%
    {\@eq@@RespBox[\eq@defaultCompare]}%
}
%    \end{macrocode}
% This is assumed to be the old style for defining the interval. In this case, the next
% token is the right-hand endpoint of the interval, we need it. We also test for the presence of the optional
% of a customized comparison function, parameter \texttt{\#9}
%    \begin{macrocode}
\def\eq@chkivIntrvlsii#1\\#2{\def\nI{1}%
  \def\rbArgs{\rbArgstmp,"[#1,#2]",_mathVars}%
  \@ifnextchar[{\@eq@@RespBox}{\@eq@@RespBox[\eq@defaultCompare]}%
}
%    \end{macrocode}
% Finally, we see if there will be a 10th parameter by seeing if `\texttt*' comes
% next. We change the catcodes here, so we can have a left and right brace in the
% optional argument \#9. Hope it works. dps 12/30/03\medskip
%    \begin{macrocode}
\def\@eq@@RespBox[#1]{\@ifstar{\jsRespBox[#1]}%
    {\jsRespBox[#1]{ProcResp}}}
\def\eq@ProcRespIntervals{ProcRespIntervals}
\def\eq@ProcRespSetNum{ProcRespSetNum}
\def\eq@ProcRespSetSym{ProcRespSetSym}
\def\eq@ProcRespEvalEq{ProcRespEvalEq}
\def\eq@ProcRespEvalEqNonZero{ProcRespEvalEqNonZero}
\def\eq@ProcRespEvalEqList{ProcRespEvalEqList}
\def\eq@ProcRespEvalEqListNonZero{ProcRespEvalEqListNonZero}
\def\jsRespBox[#1]#2{\def\compareJSfunc{#1}%
  \def\processJSfunc{#2}\gdef\g@processJSfunc{#2}% 01/11
  \ifnum\nV=\nI\relax\else
  \ifx\processJSfunc\eq@ProcRespSetNum\else
  \ifx\processJSfunc\eq@ProcRespSetSym\else
  \ifx\processJSfunc\eq@ProcRespEvalEq\else
  \ifx\processJSfunc\eq@ProcRespEvalEqNonZero\else
  \ifx\processJSfunc\eq@ProcRespEvalEqList\else
  \ifx\processJSfunc\eq@ProcRespEvalEqListNonZero\else
  \PackageWarning{exerquiz}{The number of variables does not
    match\MessageBreak the number of intervals. The
    problem\MessageBreak may not evaluate properly}\fi\fi\fi\fi\fi\fi\fi
%    \end{macrocode}
%    (2017/01/11) Run answer through \cs{pdfstringdef} if
%       \texttt{ProcRespIntervals} is used to avoid unbalanced parentheses.
%    \changes{v7.8d}{2017/01/11}{Run answer through \string\cs{pdfstringdef} if
%       \string\texttt{ProcRespIntervals} is used.}
%    \begin{macrocode}
  \ifx\eq@ProcRespIntervals\g@processJSfunc
%    \end{macrocode}
%    When the response function is \texttt{ProcRespIntervals} there is no `real' math, no subscripts,
%    no superscripts. We turn of the math mode warning before \cs{pdfstringdef}.
%    \begin{macrocode}
    \let\@inmathwarn@SAVE\@inmathwarn\let\@inmathwarn\@gobble
%    \end{macrocode}
%    When the response function is \texttt{ProcRespIntervals}, there may be unbalanced parentheses, we'll
%    pass \cs{eqCorrectAns} through \cs{pdfstringdef} to escape them.
%    \begin{macrocode}
    \pdfstringdef{\eqCorrectAns}{\eqCorrectAns}%
    \let\@inmathwarn\@inmathwarn@SAVE\fi
%    \end{macrocode}
%   Remove parentheses from the argument of \cs{eq@recordCorrAns}.
%    \changes{v8.2}{2018/03/18}{Corrected \string\cs{eq@recordCorrAns}}
%    \changes{v8.2.1}{2018/03/19}{If not a math group, record this data}
%    \begin{macrocode}
  \ifx\grpquestions\eq@Zero
    \eq@recordCorrAns{"\eqCorrectAns"}\fi
  \ifeq@proofing\makebox[0pt][l]{\space\math@correctAnswer}\fi
  \eq@TextField % send to the driver-dependent macro
%    \end{macrocode}
% (2014/01/23) Closing the \cs{hbox} here, begun at the opening of \cs{text@@Field} above.
%    \begin{macrocode}
  \egroup   % hbox
  \endgroup % \RespBoxMath
}
%    \end{macrocode}
% The primitive \cs{meaning} is used to get a typeset version of the answer for the \texttt{proofing}
% option. I found it a difficult problem because once the answer is scanned, it has catcodes attached.
% Once that is done, it is impossible to use standard methods to make a typeset the answer in
% verbatim mode.  This trick appears in the \TeX book.  \cs{meaning} inserts additional spaces on occasion,
% for example, following a period (`.'). Oh, well.
%    \begin{macrocode}
\def\gobbleMacro#1>{}
\gdef\math@correctAnswer{\ttfamily
  \color{\@proofingsymbolColor}\spaceskip=2pt\xspaceskip=2pt%
  \expandafter\gobbleMacro\meaning\eqCorrectAnsTeX
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \begin{macrocode}
%</package>
%<*rbmIntrvl>
%    \end{macrocode}
%   \subsubsection{The \texorpdfstring{\protect\cs}{\textbackslash}{rbmIntrvl} command}\label{ss:rbmi}
%   This code segment is input into \pkg{exerquiz} when the \opt{userbmintrvl} is specified.
%   The commands of this section are motivated by an {Acro\negthinspace\TeX} user (Thor G). He
%   wants to ask his students to make a series of calculations, the result of
%   which is to be entered into a \cs{RespBoxMath} input box. He is willing to
%   accept the response as correct if the response falls into a designated
%   interval $[a,b]$.
%
%   Two commands are defined, one internal (\cs{c@lcEPInfo}) and the other public {\cs{rbmIntrvl}}.
%
%   The first command \cs{c@lcEPInfo} takes as its parameters an (closed) interval of numbers.
%   It calculates the midpoint \DescribeMacro\intrCAns\cs{intrCAns} and
%   \DescribeMacro\intrPrec\cs{intrPrec}. The first number can be used as a (representative) point
%   value of the answer; the second is used as the precision parameter of \cs{RespBoxMath}.
%   \changes{v8.7}{2021/04/24}{Added \string\cs{rbmIntrvl}}
%    \begin{macrocode}
\def\c@lcEPInfo[#1,#2]{%
  \setlength{\eflength}{(#1pt+#2pt)/2}%
  \edef\intrCAns{\strip@pt\eflength}%
  \setlength{\eflength}{(#2pt-#1pt)/2}%
    \edef\intrPrec{\strip@pt\eflength}%
}
%    \end{macrocode}
% \DescribeMacro\rbmIntrvl\hskip-\marginparsep\texttt{\darg{[\meta{a{\upshape,}b}]}}
% This macro takes as its first argument the interval you want the student response
% to fall into. The command expands \cs{c@lcEPInfo} then \cs{RespBoxMath}. Use \cs{intrCAns} and \cs{intrPrec}
% in the arguments of \cs{RespBoxMath}.
%    \begin{macrocode}
\newcommand{\rbmIntrvl}[1]{\c@lcEPInfo#1\RespBoxMath}
%    \end{macrocode}
%      \cs{rbmIntrvl} has implied arguments, those of \cs{RespBoxMath}. Below is a simple example.
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,codes={\catcode`\%=9}]
%\rbmIntrvl{[6.40,6.90]}{\intrCAns}{1}{\intrPrec}{[0,1]}
%\end{Verbatim}
%Following the interval declaration are the parameters of \cs{RespBoxMath}. The first
%one following the interval is the correct answer (\cs{intrCAns}), the midpoint of the interval;
%the third argument following the interval is the precision parameter of \cs{RespBoxMath},
%which is taken to be \cs{intrPrec}, the half-width of the interval.
%    \begin{macrocode}
%</rbmIntrvl>
%<*package>
%    \end{macrocode}
%    We input the definition of \cs{rbmIntrvl} here, if the \opt{userbmintrvl}
%    option is taken.
%    \begin{macrocode}
\inputRBMICode
%    \end{macrocode}
%\subsection{Text Fill-In}
%    \begin{macro}{\RespBoxTxt}
%    \begin{macro}{\RespBoxTxtNT}
% These two macros process open-ended questions that require a text response.
% There are several ways to customize these macros; as described below.
% \par\medskip
% \noindent Usage: |\RespBoxTxt[#1]#2#3[#4]#5<plus listing of alternatives>|
% \begin{description}
% \item[\ttfamily\#1 :] Optional parameter used to modify the appearance of the
%     text field.
% \item[\ttfamily\#2 :] This required parameter is a number that indicates
% the filtering method to be used. Permissible values of this parameter are
% \begin{description}
%     \item[\ttfamily -1: ] (The default) The author's and user's answers are not filtered
%     in any way. (Spaces, case, and punctuation are preserved.)
%     \item[\ttfamily 0: ] The author's and user's answers are converted to
%     lower case, any white space and non-word characters are removed.
%     \item[\ttfamily 1: ] The author's and user's answers are converted to
%     lower case, any white space is removed.
%     \item[\ttfamily 2: ] The author's and user's answers are stripped of any
%     white space.
% \end{description}
% \item[\ttfamily\#3 :] This parameter a number that indicates the compare
% method to be used. Permissible values of this parameter are
% \begin{description}
%     \item[\ttfamily 0: ] (The default) The author's and user's answers are
%     compared for an exact match. (These answers are filtered before they are
%     compared.)
%     \item[\ttfamily 1: ] The user's response is searched in an attempt to
%     get a substring match with the author's alternatives. Additional comparison
%     methods may be added.
% \end{description}
% \item[\ttfamily\#4 :] Optional, a named destination to the solution to the
% question. If this parameter appears, then a solution must follow the
% question, enclosed in a \texttt{solution} environment.
% \item[\ttfamily\#5 :] This required parameter is the number of alternative
% answers that are acceptable. The alternative answers are listed
% immediately after this parameter. (The example above specified
% that $4$ alternatives follow.)
% \end{description}
%    \begin{macrocode}
\newcommand\RespBoxTxtNT{\def\rbFlag{0}\@RespBoxTxt}
\newcommand\RespBoxTxt{\def\rbFlag{0}\@RespBoxTxt}
%    \end{macrocode}
% Pick up any parameters that would modify the appearance of this text field.
%    \begin{macrocode}
\def\RespBoxTxtOnBlur{OnBlurRespBox(%
  \ifx\@sqTurnOffAlerts\eq@One
    retn\else null\fi,"\curr@quiz");}
\def\eqObjAlertIfFalse{if (false) }
\def\eqObjAlert{%
  \ifx\eqQuizType\isQZ\ifx\eq@online\eq@YES\ifeq@noquizsolutions
  \else\eqObjAlertIfFalse\fi\fi\fi}
\def\eqAppAlert{eqAppAlert}
%    \end{macrocode}
%    Keystroke action for \cs{RespBoxTxt} for a quiz
%    \changes{v8.6.4}{2021/02/15}{Corrected coding of  \string\cs{AAKqRespBoxTxt}, wrong
%    escape char}
%    \begin{macrocode}
\begin{defineJS}[\makeesc\*\makecmt\%]{\AAKqRespBoxTxt}
if(event.willCommit){
  RecordPointValue(*eqPTs,*thequestionno*ifx*grpquestions*eq@One,%
*thegrpquestionno,*grpPointValue,*grpTotalWeight,%
"*grpEvalFunction"*fi);
  RecordProblemType("*eqQT",*thequestionno);
  var retn = ProcRespTxt(*rbTxtAlt);
  ProcUserResp(retn,event.value,*thequestionno,0%
*ifx*grpquestions*eq@One,*thegrpquestionno*fi);
}
if (!isQuizInitialized("*currQuiz")) {
  *eqObjAlert*eqAppAlert(InitMsg("*bqlabelISO"),3);
  event.rc = false;
}
\end{defineJS}
\def\RespBoxTxtDefaults{%
  \BC{0 0 0}\W{1}\S{S}\textColor{0 g}\F{\FPrint}%
}
\def\moreRespBoxTxtDefaults{%
  \edef\@moreRespBoxTxtDefaults{%
    \if\eqQuizType\isQZ\ifx\eq@online\eq@YES
    \ifeq@noquizsolutions\else
    \noexpand\Ff{\FfReadOnly}\fi\fi\fi
  }%
}
%    \end{macrocode}
%    The keystroke action for \cs{RespBoxTxt} for a short-quiz
%    \changes{v8.6.5}{2021/02/21}{Removed comment character from last line
%    of \string\cs{rbtAAKey}}
%    \begin{macrocode}
\begin{defineJS}[\makeesc\!\makecmt\%]{\rbtAAKey}
if(event.willCommit) {
  var retn = ProcRespTxt(!rbTxtAlt);%
!ifx!@sqTurnOffAlerts!eq@One
  !RespBoxTxtOnBlur!fi
}%
!ifx!eqAddAAKeystroke!@empty!else%
!eqAddAAKeystroke!fi
\end{defineJS}
\def\@@RespBoxTxtActions{%
  \AA{\if\eqQuizType\isQZ
%    \end{macrocode}
%     Added \cs{eqAddAAKeystroke} to \cs{@@RespBoxTxtActions}
%     \changes{v7.8i}{2017/07/21}{Added \string\cs{eqAddAAKeystroke} to \string\cs{@@RespBoxTxtActions}}
%    \begin{macrocode}
      \AAKeystroke{\AAKqRespBoxTxt\eqAddAAKeystroke}
      \AAFormat{\eqAddAAFormat}
    \else
      \AAKeystroke{\rbtAAKey}
      \AAFormat{\eqAddAAFormat}
      \AAOnFocus{\JS{var\eqSP retn=null;}}
%    \end{macrocode}
% (2005/12/02) A fix for Acro7.0, a change in the blur event, must
% move this event to keystroke so behavior is the same as in previous
% versions.
%    \begin{macrocode}
      \ifx\@sqTurnOffAlerts\eq@Zero
      \AAOnBlur{\JS{\RespBoxTxtOnBlur}}\fi
    \fi
  }
}
\def\annot@subtype@rbt{rbt}
\newcommand\@RespBoxTxt[1][]{%
  \edef\annot@subtype{\annot@subtype@rbt}%
  \eq@AddProbToQzQuesList
  \ifx\grpquestions\eq@Zero\addtocounter{eqpointvalue}{\eqPTs}\fi
  \if\eqQuizType\isQZ
    \def\rbFlag{1}\global\IsRespBoxtrue
    \ifx\grpquestions\eq@One
      \stepcounter{grpquestionno}%
      \def\Fld@name{%
        grpobj.\curr@quiz.\thequestionno.\thegrpquestionno}%
    \else
      \eq@recordThesePTs\eq@recordProbType
      \edef\eqtmp{\aPointType}%
      \xdef\aPointType{\eqtmp,[\eqPTs,"text"]}%
      \stepcounter{questionno}%
      \def\Fld@name{obj.\curr@quiz.\thequestionno}%
    \fi
  \else
      \stepcounter{questionno}%
      \def\Fld@name{obj.\oField.\thequestionno}%
  \fi
  \moreRespBoxTxtDefaults
  \leavevmode\hbox\bgroup\text@@Field{#1}{\Fld@name}%
  {\RBW}{\DefaultHeightOfWidget}%
  {\eq@protect\AA}{\eq@setWidgetProps\@@RespBoxTxt}%
  {\RespBoxTxtDefaults\@moreRespBoxTxtDefaults
   \@@RespBoxTxtActions\every@eqTextField\every@RespBoxTxt}%
}
%    \end{macrocode}
% Now get the next two required parameters. Also, see if there is going to be a solution.
% This can be specified in two ways: (1) By inserting an explicit named destination \texttt{[mydest]}
% or (2) by specifying a `\texttt*', in which case, automatic naming is performed. The name is
% \texttt{\string\curr@quiz.\string\thequestionno}, \texttt{[\string\curr@quiz.\string\thequestionno]]} is inserted
% as the parameter.
% \medskip\noindent
% |#1 = filter|, |#2 = comp|
%    \begin{macrocode}
\def\@@RespBoxTxt#1#2{%
  \@ifnextchar[%]
    {\@@@RespBoxTxt{#1}{#2}}
    {\@ifstar{\@@@RespBoxTxt{#1}{#2}[\curr@quiz.\thequestionno]}%
      {\@@@RespBoxTxt{#1}{#2}[]}}}
%    \end{macrocode}
% |#1 = filter|, |#2 = comp|, |#3 = dest|, |#4 = num_alts|
%    \begin{macrocode}
\def\eq@ZERO{0}\def\eq@ONE{1}\def\eq@TWO{2}
\def\@@@RespBoxTxt#1#2[#3]#4{%
  \xdef\@qzsolndest{#3}%
  \def\eq@argi{#1}\ifx\eq@argi\eq@ZERO\else
    \ifx\eq@argi\eq@ONE\else\ifx\eq@argi\eq@TWO\else
    \def\eq@argi{-1}\fi\fi\fi
  \def\eq@argii{#2}\ifx\eq@argii\eq@ONE\else\def\eq@argii{0}\fi
  \begingroup
  \ifnum\eq@argii=\@ne
%    \end{macrocode}
% local definitions: \DescribeMacro{\rexpStr}\cs{rexpStr},
% \DescribeMacro{\\<RegEXP>}|\\|, and \DescribeMacro{\word}\cs{word}.
%    \begin{macrocode}
    \def\rexpStr##1{\eqbs\eqbs\eqbs\eqbs##1}%
    \def\\##1{\eqbs\eqbs\eqbs\eqbs##1}%
    \def\word##1{\\b##1\\b}\def\any{@any@}\fi
  \xdef\rbTxtAlt{\rbFlag,\eq@argi,\eq@argii}%
  \global\let\txtAltList\@empty
  \eqtmpcnta=#4\relax\ifnum\eqtmpcnta>\z@\expandafter\@argRead\else
  \PackageError{exerquiz}{%
      The fourth required parameter of \string\RespBoxTxt\MessageBreak
      is required to be a positive integer. You entered\MessageBreak
      #4\space instead}{Enter a positive integer.}\fi
}
\def\@argRead#1{\xdef\jsTempArgs{\txtAltList}%
  \ifx\txtAltList\@empty\xdef\txtAltList{"#1"}\else
  \xdef\txtAltList{\jsTempArgs,"#1"}\fi\@@argRead}
\def\@@argRead{\advance\eqtmpcnta\m@ne
  \ifnum\eqtmpcnta=\z@
    \def\eq@next{\endgroup
      \xdef\rbTxtAlt{\rbTxtAlt,\txtAltList}%
      \if\grpquestions\eq@Zero
        \ifwithinMCFI
          \xdef\s@veCorrAnsMCFI{[\txtAltList]}\else
          \eq@recordCorrAns{[\txtAltList]}\fi
      \else
%    \end{macrocode}
%    \changes{v7.8a}{2016/11/18}{Fixed a typo, \string\texttt{...AnsArrayi} should be
%    \string\texttt{...AnsGrpAnsArray}}
%    Fixed typo, changed \cs{eq@recordGrpAnsArrayi} to \cs{eq@recordGrpAnsArray}.
%    \begin{macrocode}
        \eq@recordGrpAnsArray{[\txtAltList]}%
      \fi
      \eq@@RespBoxTxt
    }%
  \else
    \def\eq@next{\@argRead}%
  \fi\eq@next
}
\def\eq@@RespBoxTxt{%
  \ifeq@proofing\makebox[0pt][l]{\space\txt@correctAnswer}\fi
  \eq@TextField
%    \end{macrocode}
% Closing of the \cs{hbox} begun above.
%    \begin{macrocode}
  \egroup
}
%    \end{macrocode}
% If the \texttt{proofing} option is specified, then we type out the author's list of
% acceptable answers.  Again, we use \cs{meaning}, probably not needed here.
%    \begin{macrocode}
\def\gobbleTxt#1>#2,#3,#4,{}
\gdef\txt@correctAnswer{\ttfamily\color{\@proofingsymbolColor}%
  \spaceskip=2pt\xspaceskip=2pt
  \expandafter\gobbleTxt\meaning\rbTxtAlt
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \DescribeMacro{\txtRef}\hskip-\marginparsep\texttt{\darg{\ameta{label}}}
%    The \cs{RespBoxTxt} can be used for a matching-type question. We define a special
%    \cs{ref}-type command that produces plain text. Refer to demo file
%    \texttt{qz-matching.tex} for details.
%    \changes{v8.6.4}{2021/02/15}{Support for matching-type question based in
%    \string\cs{RespBoxTxt}}
%    \begin{macrocode}
\def\txtRef#1{\@ifundefined{r@#1}
  {??}{\aeb@exiii\@firstoffive\csname r@#1\endcsname}}
%    \end{macrocode}
%    \begin{macro}{\RespBoxTxtPC}
% This is pretty much a copy of \cs{RespBoxTxt}, with slight modifications. Here,
% we attempt to award partial credit for words that appear in the answer.
% This  is a feature request of Kate of Kenya.
% \par\medskip
% \noindent Usage:
%\begin{verbatim}
%   \RespBoxTxtPC[#1]#2[#3]#4[<num1>]{<word1>}...[<num_n>]{<word_n>}
%\end{verbatim}
% \begin{description}
% \item[\ttfamily\#1 :] Optional parameter used to modify the appearance of the
%     text field.
% \item[\ttfamily\#2 :] This required parameter is a number that indicates
% the filtering method to be used. Permissible values of this parameter are
% \begin{description}
%     \item[\ttfamily -1: ] (The default) The author's and user's answers are not filtered
%     in any way. (Spaces, case, and punctuation are preserved.)
%     \item[\ttfamily 0: ] The author's and user's answers are converted to
%     lower case, any white space and non-word characters are removed.
%     \item[\ttfamily 1: ] The author's and user's answers are converted to
%     lower case, any white space is removed.
%     \item[\ttfamily 2: ] The author's and user's answers are stripped of any
%     white space.
%     \item[\ttfamily 3: ] The author's and user's answers are converted to
%     lower case only. \emph{This is the recommended value for this function.}
% \end{description}
% \item[\ttfamily\#3 :] Optional, a named destination to the solution to the
% question. If this parameter appears, then a solution must follow the
% question, enclosed in a \texttt{solution} environment.
% \item[\ttfamily\#4 :] This required parameter is the number of alternative
% answers that are acceptable. The alternative answers are listed
% immediately after this parameter. (The example above specified
% that $4$ alternatives follow.)
% \end{description}
%    \begin{macrocode}
\begin{defineJS}[\makeesc\*\makecmt\%]{\AAKqRespBoxTxtPC}
if(event.willCommit){
  RecordPointValue(*eqPTs,*thequestionno*ifx*grpquestions*eq@One,%
*thegrpquestionno,*grpPointValue,*grpTotalWeight,%
"*grpEvalFunction"*fi);
  RecordProblemType("*eqQT",*thequestionno);
  var retn = ProcRespTxtPC(*rbTxtAlt);
*ifx*grpquestions*eq@One%
  ProbValue[*thequestionno][3+*thegrpquestionno]%
=ProcRespTxtPC.txtPCpCr;*else%
  ProbValue[*thequestionno]=ProcRespTxtPC.txtPCpCr;*fi
  ProcUserResp(retn,event.value,*thequestionno,0%
*ifx*grpquestions*eq@One,*thegrpquestionno*fi);
}
if (!isQuizInitialized("*currQuiz")) {
  *eqObjAlert*eqAppAlert(InitMsg("*bqlabelISO"),3);
  event.rc = false;
}
\end{defineJS}
\begin{defineJS}[\makeesc\!\makecmt\%]{\rbtPCAAKey}
if(event.willCommit) {
    retn = ProcRespTxtPC(!rbTxtAlt);%
!ifx!@sqTurnOffAlerts!eq@One
  !RespBoxTxtOnBlur!fi%
}
\end{defineJS}
\def\@@RespBoxTxtPCActions{%
  \AA{%
    \if\eqQuizType\isQZ
      \AAKeystroke{\AAKqRespBoxTxtPC}
    \else
      \AAKeystroke{\rbtPCAAKey}
      \AAOnFocus{\JS{var\eqSP retn=null;}}
      \ifx\@sqTurnOffAlerts\eq@Zero
      \AAOnBlur{\JS{\RespBoxTxtOnBlur}}\fi
    \fi
  }
}
%    \end{macrocode}
% Here is the beginning of \cs{RespBoxTxtPC}.
%    \begin{macrocode}
\newcommand{\RespBoxTxtPC}{\def\rbFlag{0}\@RespBoxTxtPC}
\def\annot@subtype@rbtpc{rbtpc}
\newcommand\@RespBoxTxtPC[1][]{%
  \edef\annot@subtype{\annot@subtype@rbtpc}%
  \eq@AddProbToQzQuesList
  \smallskip\ifx\grpquestions\eq@Zero
    \addtocounter{eqpointvalue}{\eqPTs}\fi
  \if\eqQuizType\isQZ\def\rbFlag{1}\global\IsRespBoxtrue
    \ifx\grpquestions\eq@One
      \stepcounter{grpquestionno}%
      \def\Fld@name{%
          grpobj.\curr@quiz.\thequestionno.\thegrpquestionno}%
    \else
      \eq@recordThesePTs\eq@recordProbType
      \edef\eqtmp{\aPointType}%
      \xdef\aPointType{\eqtmp,[\eqPTs,"text"]}%
      \stepcounter{questionno}%
      \def\Fld@name{obj.\curr@quiz.\thequestionno}%
    \fi
  \else
    \stepcounter{questionno}%
    \def\Fld@name{obj.\oField.\thequestionno}%
  \fi
  \moreRespBoxTxtDefaults
  \leavevmode\hbox\bgroup\text@@Field{#1}{\Fld@name}%
  {\RBW}{\DefaultHeightOfWidget}%
  {\eq@protect\AA}{\eq@setWidgetProps\@@RespBoxTxtPC}%
  {\RespBoxTxtDefaults\@moreRespBoxTxtDefaults
   \@@RespBoxTxtPCActions\every@eqTextField\every@RespBoxTxt}%
}
\def\@@RespBoxTxtPC#1{\@ifnextchar[{\@@@RespBoxTxtPC{#1}}
  {\@ifstar{\@@@RespBoxTxtPC{#1}[\curr@quiz.\thequestionno]}%
  {\@@@RespBoxTxtPC{#1}[]}}}
\def\@@@RespBoxTxtPC#1[#2]#3{\xdef\@qzsolndest{#2}%
    \begingroup
%    \end{macrocode}
% We make special definitions for retrieving the parameters.
%    \begin{macrocode}
  \def\rexpStr##1{\eqbs\eqbs\eqbs\eqbs##1}%
  \def\\##1{\eqbs\eqbs\eqbs\eqbs##1}%
  \def\word##1{\\b##1\\b}\def\any{@any@}
  \gdef\rbTxtAlt{\rbFlag,#1,1}% force sub-string match
  \global\let\txtAltList\@empty
  \eqtmpcnta=#3\relax\ifnum\eqtmpcnta>\z@\expandafter\@argReadPC\else
  \PackageError{exerquiz}{%
    The third required parameter of
    \string\RespBoxTxtPC\MessageBreak
    is required to be a positive integer.
    You entered\MessageBreak #3\space instead}
    {Enter a positive integer.}\fi
}
%    \end{macrocode}
% \texttt{\#1=<num>}, partial credit for this answer, \texttt{\#2=word}.
%    \begin{macrocode}
\newcommand\@argReadPC[2][0]{\xdef\jsTempArgs{\txtAltList}%
  \ifx\txtAltList\@empty\xdef\txtAltList{["#2",#1]}\else
  \xdef\txtAltList{\jsTempArgs,["#2",#1]}\fi\@@argReadPC}
\def\@@argReadPC{\advance\eqtmpcnta\m@ne
  \ifnum\eqtmpcnta=\z@
    \def\eq@next{\endgroup
      \xdef\rbTxtAlt{\rbTxtAlt,\txtAltList}%
      \if\grpquestions\eq@Zero
        \ifwithinMCFI
          \xdef\s@veCorrAnsFCFI{[\txtAltList]}\else
          \eq@recordCorrAns{[\txtAltList]}\fi
      \else
        \eq@recordGrpAnsArray{[\txtAltList]}%
      \fi
      \eq@@RespBoxTxtPC
    }%
  \else
    \def\eq@next{\@argReadPC}%
  \fi\eq@next
}
\def\eq@@RespBoxTxtPC{\ifeq@proofing
  \makebox[0pt][l]{\space\txt@correctAnswer}\fi
  \eq@TextField
%    \end{macrocode}
% Closing of the \cs{hbox} begun above.
%    \begin{macrocode}
  \egroup
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\SpellCheck}\hskip-\marginparsep\texttt{[\ameta{options}]}
%    This command is designed to be used with text fill-in questions; the action of this button
%    allows the user to correct spelling, but it does record the number of initially misspelled words.
%    The placement of this field is after the text field (\cs{RespBoxTxt} or \cs{RespBoxTxtPC}) so
%    it can pick up on the field name. The root name of this field is \texttt{spl}. Two helper commands
%    are defined: \DescribeMacro{\splChkCA}\cmd{\splChkCA} and \DescribeMacro{\splChkTU}\cmd{\splChkTU}.
%    \changes{v8.5.11}{2020/11/11}{Added \string\cs{SpellCheck}}
%    \begin{macrocode}
\def\afterSplChkActn#1{\def\@fterSplChkActn{\r #1}}
\let\@fterSplChkActn\@empty
\newcommand{\splChkCA}{Check}
\newcommand{\splChkTU}{Check spelling}
\newcommand\SpellCheck[1][]{%
  \pushButton[\CA{\splChkCA}\TU{\splChkTU}\S{S}
    #1\A{\JS{%
      \ifx\grpquestions\eq@One
        var targetFldName=%
          "grpobj.\curr@quiz.\thequestionno.\thegrpquestionno";
      \else
        \ifx\annot@subtype\annot@subtype@rbe
          var targetFldName="essay.\curr@quiz.\thequestionno";
        \else
          var targetFldName="obj.\curr@quiz.\thequestionno";
        \fi
      \fi\r
      var splErrors=checkTheSpelling(targetFldName);\@fterSplChkActn
  }}]{spl.\curr@quiz.\thequestionno}{}{11bp}}
%    \end{macrocode}
%    \end{macro}
%\subsection{Essay Fill-In}
%    \begin{macro}{\RespBoxEssay}
% Here is a simple text field with a multi-line attribute for entering
% essay-type questions. This question will not be graded by JavaScript,
% of course; ideally, the response will be submitted to a server-side script for storage
% in a database. The instructor can later bring up the student's response
% and assign a grade. Syntax:
%\begin{quote}\ttfamily
%   \string\RespBoxEssay[\ameta{opts}][\ameta{dest}]\darg{\ameta{wd}}\darg{\ameta{ht}}\\[3pt]
%   \string\RespBoxEssay[\ameta{opts}]*\darg{\ameta{wd}}\darg{\ameta{ht}}
% \end{quote}
% The second argument declares the problem has a \env{solution} file; we define the target
% of the solution two ways: an explicit \ameta{dest} string or a star (\texttt*), where
% the destination is automatically named. If you use \ameta{dest}, you must have
% a first optional argument \ameta{opts}, even if its only empty (\texttt{[]}), to correctly
% parse this construction.
% \changes{v8.3}{2019/08/13}{\string\env{solution} environment now defined for
% \string\cs{RespBoxEssay}}
%    \begin{macrocode}
\def\RespBoxEssayDefaults{%
  \BC{0 0 0}\W{1}\S{S}\Ff{\FfMultiline}\rawPDF{}%
}
\def\@@RespBoxEssayActions{\AA{%
  \if\eqQuizType\isQZ
    \AAKeystroke{%
      if(event.willCommit){\jsR\jsT
      RecordPointValue(\eqPTs,\thequestionno);\jsR\jsT
      RecordProblemType("\eqQT",\thequestionno);\jsR %\jsT
      }\jsR
      if (!isQuizInitialized("\curr@quiz")) {\jsR\jsT
        \eqObjAlert\space eqAppAlert(%
          InitMsg("\bqlabelISO"),3);\jsR\jsT
        event.rc = false;\jsR
      }%
    }%
  \fi}%
}
%    \end{macrocode}
%    Begin the \cs{RespBoxEassay} command.
%    \begin{macrocode}
\def\annot@subtype@rbe{rbe}
\newcommand\RespBoxEssay[1][]{\edef\annot@subtype{\annot@subtype@rbe}%
  \def\rbe@rgi{#1}\RespBoxEssay@i}
\def\RespBoxEssay@i{\@ifnextchar[%]
  {\RespBoxEssay@ii}
  {\@ifstar{\RespBoxEssay@ii[\curr@quiz.\thequestionno]}}%
  {\RespBoxEssay@ii[]}%
}
\newcommand\RespBoxEssay@ii[3][]{%
  \smallskip\addtocounter{eqpointvalue}{\eqPTs}%
%    \end{macrocode}
%    (2019/06/26) Added \cs{eq@AddProbToQzQuesList} for \cs{RespBoxEssay}
%   \changes{v8.2.13}{2019/06/26}{Added \string\cs{eq@AddProbToQzQuesList}
%   for \string\cs{RespBoxEssay}}
%    \begin{macrocode}
  \eq@AddProbToQzQuesList
  \stepcounter{questionno}%
  \xdef\@qzsolndest{#1}%
  \edef\eqtmp{\aPointType}\xdef\aPointType{\eqtmp,[\eqPTs,"essay"]}%
  \expandafter\mbox\expandafter{\expandafter\text@@Field
    \expandafter{\rbe@rgi}{essay.\curr@quiz.\thequestionno}{#2}{#3}%
  {\eq@protect\AA}{\eq@setWidgetProps
   \eq@TextField}{\RespBoxEssayDefaults\@@RespBoxEssayActions
   \every@eqTextField}}%
}
%    \end{macrocode}
%    \end{macro}
%    \section{Fields that play a supportive role}
%
%    \subsection{Support for the short-quiz}
%
%    \subsubsection{The \tops{\protect\cs}{\textbackslash}{sqTallyBox} command}
%
%    \begin{macro}{\sqTallyBox}\hskip-\marginparsep\texttt{[\ameta{options}]}
% The \cmd{\sqTallyBox} holds the number of incorrect responses to the
% question. This box is not required to appear.
%    \begin{macrocode}
\let\@@sqTallyBoxActions\@empty
\def\sqTallyBoxDefaults{%
  \BC{0 0 0}\W{1}\textColor{1 0 0 rg}\S{I}\Q{2}\Ff{\FfReadOnly}}
\newcommand\sqTallyBox[1][]{%
  \mbox{\text@@Field{#1}{tally.\oField.\thequestionno}%
    {\TBW}{\DefaultHeightOfWidget}%
    {}{\eq@setWidgetProps\eq@TextField}%
    {\sqTallyBoxDefaults\@@sqTallyBoxActions\every@eqTextField
    \every@sqTallyBox}}}
%    \end{macrocode}
%    \end{macro}
%    \subsubsection{The \tops{\protect\cs}{\textbackslash}{sqTallyTotal} command}
%    \begin{macro}{\sqTallyTotal}\hskip-\marginparsep\texttt{[\ameta{options}]}
% This text field stores the tally total. Only used within the
% \env{shortquiz} environment. Takes on optional parameter; this
% parameter can be used to modify the appearance of the fields. Two special
% key-values are also recognized: \cs{weakpass\darg{\ameta{n}}} and \cs{strongpass\darg{\ameta{n}}}
%    \begin{macrocode}
\def\sqTallyTotalDefaults{%
  \rawPDF{}\W{1}\BC{0 0 0}\S{I}\textColor{1 0 0 rg}
  \Q{2}\Ff{\FfReadOnly}
}
%    \end{macrocode}
%    \DescribeMacro{\sqWeakMsg} The message that appears in an alert box
%    when the use has exceeded the weak-pass limit.
%    \begin{macrocode}
\flJSStr{\sqWeakMsg}{You have missed too many questions.
After you finish, it is recommended you retake this quiz
with fewer errors and greater understanding.}
%    \end{macrocode}
%    \DescribeMacro{\sqStrongMsg} The message that appears in an alert box
%    when the use has exceeded the strong-pass limit.
%    \begin{macrocode}
\flJSStr{\sqStrongMsg}{You have missed too many questions.
We are resetting the quiz. Start over, this time with
fewer errors and greater understanding.}
%    \end{macrocode}
%    The code that formats the field and if needed, responds to the weak-pass
%    or strong-pass parameter.
%    \changes{v8.7.8}{2021/05/13}{Use try/catch (\string\cs{dlTC}) in number format.}
%    \begin{macrocode}
\def\@@sqTallyTotalActions{\AA{%
  \AAKeystroke{\dl@EForAF4Number_Keystroke(0,0,0,0,"",true);}
  \AAFormat{\dlTC{\dl@EForAF4Number_Format(0,0,0,0,"",true);}}
  \AACalculate{%
    \dl@EForAF4Simple_Calculate("SUM",new Array("tally.\oField"));\r
    var sqTlyTotl=event.value;
    \ifx\eq@strongpass\@empty
      \ifx\eq@weakpass\@empty\else\r
%    \end{macrocode}
%    \textbf{Weak pass:} When \uif{sqTlyTotl} exceeds \cs{eq@weakpass},
%    an alert message with a message of \cs{sqWeakMsg}.
%    \begin{macrocode}
         if(sqTlyTotl > \eq@weakpass) {\r\t
            if (\oField.sqTlyTotCnt==0)\r\t\t
              app.alert(\sqWeakMsg);\r\t
            \oField.sqTlyTotCnt++;\r
          }
      \fi
    \else\r
%    \end{macrocode}
%    \textbf{Strong pass:} When \uif{sqTlyTotl} exceeds \cs{eq@strongpass},
%    an alert message with a message of \cs{sqStrongMsg}, and the whole
%    short-quiz is reset.
%    \begin{macrocode}
      if(sqTlyTotl > \eq@strongpass) {\r\t
        app.alert(\sqStrongMsg);\r
        \@@sqClearButtonJSCode\r
        event.value=0;\r
      }
    \fi
}}}
%    \end{macrocode}
%    \begin{macrocode}
\def\@eqweakpass#1{\def\eq@weakpass{#1}}
\def\@eqstrongpass#1{\def\eq@strongpass{#1}}
\let\eq@weakpass\@empty
\let\eq@strongpass\@empty
%    \end{macrocode}
%    On 2021/05/07, the action of \cs{sqTallyTotal} is enhanced; two special keys-values
%    are defined: \cs{weakpass\darg{\ameta{n}}} and \cs{strongpass\darg{\ameta{n}}}.
%    For the weak pass, as soon as the student misses more than \ameta{n} questions,
%    an alert box message; for the strong pass, an alert message appears and the quiz
%    is reset.
%    \changes{v8.7.6}{2021/05/07}{Enhanced capabilities of \string\cs{sqTallyTotal}}
%    \begin{macrocode}
\newcommand\sqTallyTotal[1][]{%
  \processAppArgs#1\end\@nil
  \mbox{\text@@Field{#1}{tallytotal.\oField}{\TBW}%
    {\DefaultHeightOfWidget}{\eq@protect\AA}%
    {\eq@setWidgetProps\eq@TextField}%
    {\sqTallyTotalDefaults\@@sqTallyTotalActions\every@eqTextField
     \every@sqTallyTotal}}%
}
%    \end{macrocode}
%    \end{macro}
%
%    \subsubsection{The \tops{\protect\cs}{\textbackslash}{sqClearButton} command}
%
%    \begin{macro}{\sqClearButton}
% This button will clear the tallyfields and change the color of
% the \cmd{\RespBox} back to \cmd{\defaultColorJS}. The button clears the fields
% based on the current value of \cmd{\oField}. This text macro is
% given its value when the optional parameter in the
% \texttt{shortquiz} environment is specified.
%\changes{v6.3g}{2008/10/13}
%{%
% Fixed a problem with the clear button not setting the boundary color
% back to the default. I must have changed the name of an objective field,
% now, we say \string\texttt{this.getField("obj.\string\cs{oField}")}.
%}
%    \begin{macrocode}
\def\sqClearButtonDefaults{%
  \CA{\eq@local@sqClearButton}\textColor{0 g}\F{\FPrint}
  \BC{0 0 0}\BG{.7529 .7529 .7529}\W{1}\S{B}\Ff{\FfNoExport}
}
%    \end{macrocode}
% In an attempt to supply some custom colors for the shortquiz, we
% define \cmd{\sqRespBoxResetColor}. It determines the clear color
% \changes{v8.6}{2020/11/29}{Rewrote SQ clear button using \string\env{defineJS} env}
%    \begin{macrocode}
\begin{defineJS}[\makeesc\*\makecmt\%]{\@@sqClearButtonJSCode}
ProcessIt = false;
if ( typeof *oField == "undefined" )
    *oField = new Object;
if (typeof appAlerts["*oField"] == "undefined")
    appAlerts["*oField"] = new Object;
% dpsx
this.resetForm(new Array("mc.*oField","mck.*oField","obj.*oField",%
"tally.*oField","grpobj.*oField"));
var f = this.getField("obj.*oField");
if ( f != null ) f.strokeColor=*ifx*defaultColorJSLoc*@empty%
*defaultColorJS*else*defaultColorJSLoc*fi;
f = this.getField("grpobj.*oField");
%    \end{macrocode}
%    Here, we give the user an opportunity to designate the color
%    of the response boxes when they are reset by the \cs{sqClearButton}.
%    The default is to use \cs{eqDefaultColor}.
%    \begin{macrocode}
if ( f != null ) f.strokeColor=*ifx*defaultColorJSLoc*@empty%
*defaultColorJS*else*defaultColorJSLoc*fi;
f = this.getField("rbmarkup.*oField");
if ( f != null ) f.display=display.hidden;
*oField.Grp = {};
appAlerts["*oField"].bAfterValue=false;
%    \end{macrocode}
%    \begin{macrocode}
*oField.sqTlyTotCnt=0;
ProcessIt=true;
\end{defineJS}
\def\@@sqClearButtonActions{\A{\JS{\@@sqClearButtonJSCode}}}
\newcommand\sqClearButton[1][]{%
  \mbox{\push@@Button{#1}{clear.\oField}{}{\DefaultHeightOfWidget}%
    {\eq@protect\A}{\eq@setButtonProps\eq@Button@driver}%
    {\sqClearButtonDefaults\@@sqClearButtonActions\every@ButtonField
     \every@sqClearButton}}%
}
%    \end{macrocode}
%    \end{macro}
%
%    \subsubsection{The \tops{\protect\cs}{\textbackslash}{sqSolnBtn} command}
%    The default scheme for pointing the student to the soltuion to a MC or MS question
%    is through the buttons themselves. For MC, when the student chooses the correct
%    answer from the choice field, the page jumps to the soltution page automatically
%    (assuming there is a solution); for MS, the same jump does not occur until all
%    correct choices are made.
%
%    In this section, we introduce an alternate scheme for handling jumps to MC and
%    MS questions.
%    \changes{v8.7.5}{2021/05/05}{Defined \string\cs{sqSolnBtn}}
%    \par\medskip\noindent
%    \DescribeMacro{\sqSolnMCMsg} Alert message for MC question
%    \begin{macrocode}
\flJSStr{\sqSolnMCMsg}{You must first select the correct
answer to see the solution.}
%    \end{macrocode}
%    \DescribeMacro{\sqSolnMSMsg} Alert message for MS question
%    \begin{macrocode}
\flJSStr{\sqSolnMSMsg}{You must first select all the correct
answers to see the solution.}
%    \end{macrocode}
%    \DescribeMacro{\sqCorrSolCodeMC} The code for \cs{sqSolnBtn} when the choice
%    field is MC
%    \begin{macrocode}
\begin{defineJS}[\makeesc\*\makecmt\%]{\sqCorrSolCodeMC}
var qzSolnDest="*@qzsolndest";
var solnAfter=*ifeq@solutionsafter%
true*else%
false*fi;
var qzSolnDest="*@qzsolndest";
var f=this.getField("mc.*oField.*thequestionno");
if(f.value.charAt(0)=="1") {
  if ((qzSolnDest!="") && !solnAfter) %
jmpToNamedDest("answer",qzSolnDest,1);
} else app.alert(*sqSolnMCMsg);
\end{defineJS}
%    \end{macrocode}
%    \DescribeMacro{\sqCorrSolCodeMS} The code for \cs{sqSolnBtn} when the choice
%    field is MS
%    \begin{macrocode}
\begin{defineJS}[\makeesc\*\makecmt\%]{\sqCorrSolCodeMS}
// multiple selection
var g=this.getField("mc.*oField.*thequestionno");
var a=g.getArray();
var qzSolnDest="*@qzsolndest";
var solnAfter=*ifeq@solutionsafter%
true*else%
false*fi;
var qzSolnDest="*@qzsolndest";
var f=this.getField("corr.*oField.*thequestionno");
if ( (qzSolnDest != "") && !solnAfter ) {
  for (var i=0; i<a.length; i++){
    if ((a[i].exportValues[0].charAt(0)==1) && %
(!a[i].isBoxChecked(0))) break;
  }
}
if (i>=a.length) jmpToNamedDest("*oField","*@qzsolndest",%
*ifx*@sqTurnOffAlerts*eq@Zero0*else1*fi);
else app.alert(*sqSolnMSMsg);
\end{defineJS}
%    \end{macrocode}
%    The action for \cs{sqSolnBtn} as a function of whether
%    this is a MC or MS button.
%    \begin{macrocode}
\def\sqCorrSolButtonActionHook{\ifx\aeb@answerType
  \aeb@answerType@r\JS{\sqCorrSolCodeMC}\else
  \JS{\sqCorrSolCodeMS}\fi
}
%    \end{macrocode}
%    \DescribeMacro{\sqSolnBtn}\hskip-\marginparsep\texttt{[\ameta{options}]} The
%    code for \cs{sqSolnBtn}. This command is usually inserted into the workflow
%    through the \cs{answersEndHook} command.
%    \begin{macrocode}
\newcommand{\sqSolnBtn}[1][]{%
  \def\Fld@name{corr.\oField.\thequestionno}%
  \edef\@@CorrSolButtonActions{\noexpand
    \A{\noexpand\sqCorrSolButtonActionHook}}%
%    \end{macrocode}
%   The \cs{sqSolnBtn} button only appears when \cs{@qasolndest} is nonempty.
%    \begin{macrocode}
  \ifx\@qzsolndest\@empty\else
  \mbox{\push@@Button{#1}{\Fld@name}{}{\DefaultHeightOfWidget}%
    {\eq@protect\A}{\eq@setButtonProps\eq@Button@driver}%
    {\CorrAnsButtonDefaults\@@CorrSolButtonActions
    \every@ButtonField\every@CorrAnsButton}}\fi
}
%    \end{macrocode}
%
%    \subsection{The \tops{\protect\cs}{\textbackslash}{CorrAnsButton} buttons}
%
%    \begin{macro}{\CorrAnsButton}
% The \cmd{\CorrAnsButton} is a button macro which, when pressed, will
% display the correct answer for the user. This button is again
% optional. This macro takes one parameter and one optional parameter
%\begin{verbatim}
%#1 : the correct answer as the user should enter it.
%\end{verbatim}
% The value if \texttt{\#1} may be different from the parameter
% \texttt{\#2} in \cmd{\RespBox}; for example, if the answer is
% $x^2$, then \texttt{\#2} of \cmd{\RespBox} would be
% \texttt{pow(x,2)}; but the user would enter |x^2|.
%
% The optional parameter is specified by a star * followed by a
% name of a JavaScript function. The arguments of this JS function
% is the same as that of DisplayAnswer. For example,
%\begin{verbatim}
%\CorrAnsButton{convertFrac('#1','#2')}*{EvalCorrAnsButton}}
%\end{verbatim}
% The JavaScript function might be
%\begin{verbatim}
%function EvalCorrAnsButton(fieldname,theanswer)
%{
%    theanswer = eval(theanswer);
%    DisplayAnswer(fieldname,theanswer);
%}
%\end{verbatim}
% Here, we call a function to evaluate the answer for us.
%    \begin{macrocode}
\def\CorrAnsButtonDefaults{%
  \CA{\eq@local@CorrAnsButton}\W{1}\S{S}
  \BC{0 0 0}\BG{.7529 .7529 .7529}\H{P}
}
\def\normalCABtnBC{0 0 0}
\def\qCorrAnsButtonActionHook{\JS{%
\ifx\@qzsolndest\@empty\else
  if(event.shift)\jsR\jsT
      this.gotoNamedDest("\@qzsolndest");\jsR
  else {\jsR\jsT\fi
%    \end{macrocode}
%     The script for the \cs{CorrAnsButton} accommodates multi-letter variables
%    \begin{macrocode}
\ifShowAppr
  \ifarrowDelim
    if(typeof event.target.appr=="undefined")\r\JST\t
      event.target.appr=false;\r\JST
    event.target.appr=!event.target.appr;\r\JST
    if(event.target.appr) {\r\t\JST
      var\eqSP_substVars=\indepVars;\r\t\JST
      var\eqSP_substAns=getSubstValue(_substVars,"\CorrectAns");\r\t\JST
      var\eqSP value=RespBoxAppr("\CorrectAns");\r\JST
    } else\eqSP var\eqSP value="\CorrectAns";\r\JST
  \else
    var\eqSP value="\CorrectAns";\r\JST
  \fi
\else
    var\eqSP value="\CorrectAns";\r\JST
\fi
    \processJSfunc("Ans.\curr@quiz",value,\currQuiz);\r
\ifx\@qzsolndest\@empty\else
  }\fi
}}
%    \end{macrocode}
%    \leavevmode\DescribeMacro{\sqCorrAnsCode}
%    The JavaScript code for \cs{CorrAnsButton} now in a \env{defineJS} env.
%    \changes{v8.6}{2020/11/29}{code for \string\cs{CorrAnsButton} now in a
%    \string\env{defineJS} env}
%    \begin{macrocode}
\begin{defineJS}[\makeesc\!\makecmt\%]{\sqCorrAnsCode}
!ifx!@qzsolndest!@empty%
!processJSfunc("obj.!oField.!thequestionno","!CorrectAns",%
!currQuiz);!else%
if (event.shift) this.gotoNamedDest("!@qzsolndest");
else !processJSfunc("obj.!oField.!thequestionno","!CorrectAns",%
!currQuiz);!fi
\end{defineJS}
\def\sqCorrAnsButtonActionHook{\JS{\sqCorrAnsCode}}
%    \end{macrocode}
%    \leavevmode\DescribeMacro{\CorrAnsButton}
%    The definition of \cs{CorrAnsButton}
%    \begin{macrocode}
\newcommand\CorrAnsButton[1][]{\eq@@CorrAnsButton{#1}}
\def\eq@@CorrAnsButton#1#2{\bgroup\makeJSspecials % 1/12
  \@ifstar{\eq@@@CorrAnsButton{#1}{#2}}{%
    \eq@@@CorrAnsButton{#1}{#2}{DisplayAnswer}}}
\def\eq@@@CorrAnsButton#1#2#3{\gdef\CorrectAns{#2}%
  \def\processJSfunc{#3}\ifx\@qzsolndest\@empty\let\JST\@empty\else
  \let\JST\jsT\fi % dps17
  \ifx\eq@ProcRespIntervals\g@processJSfunc
    \let\@inmathwarn@SAVE\@inmathwarn\let\@inmathwarn\@gobble
%    \end{macrocode}
%    When the response function is \texttt{ProcRespIntervals}, there may be unbalanced parentheses, we'll
%    pass \cs{CorrectAns} through \cs{pdfstringdef} to escape them.
%    \begin{macrocode}
    \pdfstringdef{\CorrectAns}{\CorrectAns}%
    \let\@inmathwarn\@inmathwarn@SAVE\fi
    \if\eqQuizType\isQZ\def\Fld@name{corr.\curr@quiz.\thequestionno}%
    \else\def\Fld@name{corr.\oField.\thequestionno}\fi
    \if\eqQuizType\isQZ
      \edef\@@CorrAnsButtonActions{\noexpand\F{\FHidden}%
        \ifx\@qzsolndest\@empty%\noexpand\BC{\normalCABtnBC}%
        \else\noexpand\BC{\solution@Color}\fi
        \noexpand\A{\noexpand\qCorrAnsButtonActionHook}}%
%    \end{macrocode}
%     (2021/05/21) Code to support the \texttt{allowanswers} option. When the options \texttt{noquizsolutions}
%     and \texttt{allowanswers} are both specified, the \cs{CorrAnsButton} is typeset.
%     Normally, when \texttt{noquizsolutions} is specified, \cs{CorrAnsButton} not typeset.
%    \begin{macrocode}
      \let\eq@insertFld\eq@YES
      \ifeq@noquizsolutions\let\eq@insertFld\eq@NO
        \ifeq@answersallowed\let\eq@insertFld\eq@YES\fi\fi
      \ifx\eq@insertFld\eq@YES
        \mbox{\let\rpl\eq@rpl
        \push@@Button{#1}{\Fld@name}{}{\DefaultHeightOfWidget}%
          {\eq@protect\A}{\eq@setButtonProps\eq@Button@driver}%
          {\CorrAnsButtonDefaults\@@CorrAnsButtonActions
          \every@ButtonField\every@CorrAnsButton}}%
      \fi
    \else
        \edef\@@CorrAnsButtonActions{%
        \ifx\@qzsolndest\@empty%\noexpand\BC{\normalCABtnBC}
        \else\noexpand\BC{\solution@Color}\fi
        \noexpand\A{\noexpand\sqCorrAnsButtonActionHook}}%
        \mbox{\push@@Button{#1}{\Fld@name}{}{\DefaultHeightOfWidget}%
          {\eq@protect\A}{\eq@setButtonProps\eq@Button@driver}%
          {\CorrAnsButtonDefaults\@@CorrAnsButtonActions
          \every@ButtonField\every@CorrAnsButton}}%
    \fi
    \egroup
}
%    \end{macrocode}
%    \end{macro}
%
%    \subsection{The \tops{\protect\cs}{\textbackslash}{@PromptButton} command}
%
%    \begin{macro}{\@PromptButton}
% The \cs{@PromptButton} is used to create a ``progressive-style'' question (for math fill-in).
% Some series of questions build on one another. You can use this button to show the solution
% for one problem, so the student can try the next problem. On clicking on the prompt button,
% the student cannot enter another answer in the text field, and the input that is already
% there will be the one that is counted has the student's response.
%    \begin{macrocode}
\def\PromptButtonDefaults{%
 \CA{\eq@local@CorrAnsButton}\W{1}\S{S}\BC{0 0 0}
 \BG{.7529 .7529 .7529}\H{P}
}
\newcommand{\promptButtonMsg}{%
  "Would you like to see the correct answer at this time? "\r\t\t
  + "Your current answer will be the one that will be scored. "\r\t\t
  + "If you click on \\"Yes\\",
      you will not be able to change your answer."
}
\newcommand{\AnsPromptBtnStr}{Answer:\space}
\begin{defineJS}[\makeesc\*\makecmt\%]{\PromptButtonActionCode}
if (!isQuizInitialized("*currQuiz")) {
  eqAppAlert(InitMsg("*bqlabelISO"),3);
  event.rc=false;
} else {
  if ( !*currQuiz.oAlertCheck.bAfterValue ) {
    var resp=eqAppAlert({
        cMsg:*promptButtonMsg,
        nIcon: 2, nType: 2,
        cTitle: ("AcroTeX Prompt Message"),
        oCheckbox: *currQuiz.oAlertCheck
    });
  }
%    \end{macrocode}
%    Correction to the if condition below
%    \changes{v7.8d}{2017/01/11}{Correction to the if condition in \string\cs{PromptButtonActionHook}}
%    \begin{macrocode}
  if ( promptQuiz.oAlertCheck.bAfterValue || resp==4 ) {
    var field=this.getField("obj.*currQuiz.*thequestionno");
    field.readonly=true;
    field=this.getField("Ans.*currQuiz");
    if (field!=null) field.value = ("*AnsPromptBtnStr*PromptAns");
  }
}
\end{defineJS}
\def\PromptButtonActionHook{\JS{\PromptButtonActionCode}}
%    \end{macrocode}
% \DescribeMacro{\@PromptButton}\hskip-\marginparsep\texttt{[\ameta{options}]\darg{\ameta{answer}}}
% This button takes the standard two arguments
% \begin{flushleft}
% \texttt{\#1}: Optional parameters to change the appearance of the field\\
% \texttt{\#2}: Prompt answer
% \end{flushleft}
%    \begin{macrocode}
\newcommand\@PromptButton[2][]{%
  \def\PromptAns{#2}\if\eqQuizType\isQZ
  \def\Fld@name{promptButton.\curr@quiz.\thequestionno}%
  \else\def\Fld@name{promptButton.\oField.\thequestionno}\fi
  \if\eqQuizType\isQZ
    \def\@@PromptButtonActions{%
      \A{\PromptButtonActionHook}}%
    \mbox{\push@@Button{#1}{\Fld@name}{}%
      {\DefaultHeightOfWidget}{\eq@protect\A}%
      {\eq@setButtonProps\eq@Button@driver}%
      {\PromptButtonDefaults\@@PromptButtonActions
      \every@ButtonField\every@CorrAnsButton}}%
  \else\PackageWarning{exerquiz}{The \string\PromptButton
        is for quiz questions only.}
  \fi
}
%    \end{macrocode}
%    \end{macro}
% \DescribeMacro{\PromptButton} is the default definition of the \cs{PromptButton},
% it can be redefined. The \cs{CorrectAns} command is defined in the
% \cs{CorrAnsButton} as the answer provided by the author.
%    \begin{macrocode}
\newcommand{\PromptButton}{\makebox[0pt][r] % assumes xcolor
  {\@PromptButton[\textColor{1 0 0 rg}]{\CorrectAns}}}
%    \end{macrocode}
%
%    \subsection{The \tops{\protect\env}{}{mathGrp} environment}
%
%    \begin{environment}{mathGrp}
% An environment for enclosing a collection of math/text fill-ins that are to be grouped
% together. This grouping should not cross a begin or end of another environment, or include more
% an \cs{item}. This environment has two optional arguments:
%\begin{description}
% \item[\texttt{[\#1]}] : total weight (needed when sum of weight is greater than total number of points
% \item[\texttt{[\#2]}] : evaluation function, a JavaScript function to evaluate the user's responses.
% The default evaluation function is \texttt{groupEval}.
%\end{description}
% The way the parsing of the parameters works out, to specify \texttt{\#1}, you must specify
%\texttt{\#2}.
%    \begin{macrocode}
\let\eq@ansGrpArray\@empty
\def\eq@recordGrpAnsArray#1{%
  \ifx\eq@ansGrpArray\@empty
    \edef\tmp@exp{\noexpand\g@addto@macro
      \noexpand\eq@ansGrpArray{#1}}\else
    \edef\tmp@exp{\noexpand\g@addto@macro
      \noexpand\eq@ansGrpArray{,#1}}\fi
  \tmp@exp
}
\let\grpquestions\eq@Zero
\def\mathGrp{\global\let\eq@ansGrpArray\@empty
  \@ifnextchar[{\@imathGrp}{\@imathGrp[groupEval]}}
\def\@imathGrp[#1]{\def\argi{#1}%
  \@ifnextchar[{\@iimathGrp}{\@iimathGrp[]}}
\def\@iimathGrp[#1]{\def\argii{#1}%
  \eq@AddProbToQzQuesList
  \global\let\grpquestions\eq@One
  \setcounter{grpquestionno}{0}%
  \stepcounter{questionno}%
  \xdef\beginGrp{\thequestionno}%
  \xdef\grpPointValue{\eqPTs}%
  \eq@recordThesePTs\eq@recordProbType
  \if\eqQuizType\isQZ
    \edef\eqtmp{\aPointType}%
    \xdef\aPointType{\eqtmp,[\eqPTs,"grp"]}\fi
  \addtocounter{eqpointvalue}{\eqPTs}%
  \ifx\argii\@empty
    \xdef\grpTotalWeight{\eqPTs}%
    \xdef\grpEvalFunction{\argi}%
  \else
    \xdef\grpTotalWeight{\argi}%
    \xdef\grpEvalFunction{\argii}%
  \fi
}
\def\endmathGrp{\global\let\grpquestions\eq@Zero
  \eq@recordCorrAns{[\eq@ansGrpArray]}%
  \xdef\endGrp{\thequestionno}}
%    \end{macrocode}
%    \end{environment}
%    \begin{macro}{\CorrAnsButtonGrp}
% The correct answer button for grouped questions.
% \changes{v8.6}{2020/11/29}{Action for group answer btn now a \string\env{defineJS} env}
%    \begin{macrocode}
\def\CorrAnsButtonGrpDefaults{%
  \CA{\eq@local@CorrAnsButton}\W{1}\S{S}\BC{0 0 0}
  \BG{.7529 .7529 .7529}\H{P}
}
\begin{defineJS}[\makeesc\!\makecmt\%]{\cabGrpActn}
!ifx!@qzsolndest!@empty!else%
if (event.shift) this.gotoNamedDest("!@qzsolndest");
else !fi%
{
  var aCorrectAns=!CorrectAns;
  var beginGrp=1;
  var grpOffset=beginGrp;
  if(!currQuiz.Grp==null)!currQuiz.Grp={};
  if(typeof !currQuiz.Grp["!thequestionno"]=="undefined")
  {
    !currQuiz.Grp["!thequestionno"]={offset:0};
  } else {
    !currQuiz.Grp["!thequestionno"].offset=%
++(!currQuiz.Grp["!thequestionno"].offset)!%aCorrectAns.length;
    grpOffset=beginGrp%
+!currQuiz.Grp["!thequestionno"].offset;
  }
  var f=this.getField("grpobj.!curr@quiz.!thequestionno." %
+ grpOffset);
%    \end{macrocode}
% When the field is readonly, then we cannot set the focus. We'll remove the readonly, set focus, then
% reset readonly to true again; however, we must wait a little for !texttt{setFocus} to finish.
%    \begin{macrocode}
  if(f.readonly){
    f.readonly=false;
    f.setFocus();
    eqDelay=app.setTimeOut(%
"f.readonly=true;app.clearTimeOut(eqDelay);",10);
  } else f.setFocus();
!if!eqQuizType!isQZ%
  DisplayAnswer("Ans.!curr@quiz",%
aCorrectAns[!currQuiz.Grp["!thequestionno"].offset],!currQuiz);!else%
  DisplayAnswer("grpobj.!oField.!thequestionno."+ grpOffset,%
aCorrectAns[!currQuiz.Grp["!thequestionno"].offset],!oField);!fi
}
\end{defineJS}
\def\CorrAnsButtonGrpActionHook{\JS{\cabGrpActn}}
\newcommand\CorrAnsButtonGrp[2][]{%
  \makeStringArray{#2}%
  \edef\CorrectAns{\stringArray}%
  \if\eqQuizType\isQZ\def\Fld@name{corr.\curr@quiz.\thequestionno}%
  \else\edef\currQuiz{\oField}%
    \def\Fld@name{corr.\oField.\thequestionno}\fi
  \if\eqQuizType\isQZ
    \edef\@@CorrAnsButtonGrpActions{\noexpand\F{\FHidden}%
      \ifx\@qzsolndest\@empty
      \else\noexpand\BC{\solution@Color}\fi
      \noexpand\A{\noexpand\CorrAnsButtonGrpActionHook}}%
    \ifeq@noquizsolutions\let\x\relax\else
    \def\x{\mbox{\push@@Button{#1}{\Fld@name}{}%
      {\DefaultHeightOfWidget}{\eq@protect\A}%
      {\eq@setButtonProps\eq@Button@driver}%
      {\CorrAnsButtonGrpDefaults\@@CorrAnsButtonGrpActions
      \every@ButtonField\every@CorrAnsButton}}}\fi\x
  \else
    \edef\@@CorrAnsButtonGrpActions{%
      \ifx\@qzsolndest\@empty%\noexpand\BC{\normalCABtnBC}
      \else\noexpand\BC{\solution@Color}\fi
      \noexpand\A{\noexpand\CorrAnsButtonGrpActionHook}}%
    \mbox{\push@@Button{#1}{\Fld@name}{}{\DefaultHeightOfWidget}%
      {\eq@protect\A}{\eq@setButtonProps\eq@Button@driver}%
      {\CorrAnsButtonGrpDefaults\@@CorrAnsButtonGrpActions
      \every@ButtonField\every@CorrAnsButton}}%
  \fi
}
\def\makeStringArray#1{\def\stringArray{[}\@makeStringArray#1,\@nil}
\def\@makeStringArray#1,#2\@nil{%
  \edef\eq@temp{\stringArray}\def\argii{#2}%
  \ifx\argii\@empty
    \edef\stringArray{\eq@temp"#1"]}%
    \def\eq@next{}%
  \else
    \edef\stringArray{\eq@temp"#1",}%
    \def\eq@next{\@makeStringArray#2\@nil}%
  \fi
  \eq@next
}
%    \end{macrocode}
%    \end{macro}
%
% \section{Quiz Summary Tables}
%
% This code is designed for use with a \texttt{quiz}, as opposed to a
% \texttt{shortquiz}. Insert the command \cs{displaySumryTbl} after the
% end of the quiz, but before \verb!\end{quiz}!. The expansion  of
% \cs{displaySumryTbl} is a table summarizing the user's effort on the
% quiz, indicating which questions had responses, and which did not.
%\par\medskip\noindent
% (06/08/10) We define \cs{eq@AddProbToQzQuesList}, which adds the current question label to
% the list \cs{eqQzQuesList}. The command \cs{@eqListExp} is initially defined
% to be \cs{relax} and is redefined just before \cs{eqQzQuesList} is expanded.
%    \begin{macrocode}
\let\@eqListExp\relax
\let\@currentQues\@empty
\let\eqQzQuesList\@empty
\def\eq@AddProbToQzQuesList{%
  \edef\eq@tmpExp{\noexpand\g@addto@macro%
%    \end{macrocode}
%    Cosmetic change replaced \cs{noexpand} with \cs{string}.
%    \changes{v8.2.15}{2019/08/06}{replace \string\cs{noexpand} with \string\cs{string}}
%    \changes{v8.5.4}{2019/11/03}{Reverted to \string\cs{noexpand}}
%    \begin{macrocode}
    \noexpand\eqQzQuesList{\noexpand
    \@eqListExp{\@currentQues}{\the\c@page}}}%
%    \end{macrocode}
% We add to the list only if we are not within a \texttt{mathGrp} environment.
%    \begin{macrocode}
    \ifx\grpquestions\eq@Zero\eq@tmpExp\fi
}
%</package>
%<*sumrytbls>
%    \end{macrocode}
% The command below is convenience command to concatenate the current quiz with
% another string. The reason the parameter is enclosed in parenthesis is that
% the command is (sometimes) executed in a limited verbatim environment were the
% catcodes of our friendly braces have been changed.
%    \begin{macrocode}
\def\ccatCurrQzWith(#1){\currQuiz#1}
%    \end{macrocode}
% This is the JavaScript action for the push button \cs{pbPopulateSumTable}.
% The code is activated when the page becomes visible. The code reads through
% the Responses array and determines which questions were answered, and checks
% the appropriate box. (Version 6 or greater)
%    \begin{macrocode}
%    \end{macrocode}
% This zero width/height push button is hidden at the top of the table. When
% the page that contains the button, the JS is executes.
%    \begin{macrocode}
\def\pbPopulateSumTable{\pushButton[\W0\BG{}\BC{}\S{S}\autoCenter{n}
  \TU{\thequestionno}\Ff{\FfReadOnly}
  \AA{\AAPageVisible{try{popVisitsTbl("\currQuiz",\thequestionno)}%
      catch(e){}}}]{\currQuiz activateSC}{0pt}{0pt}}
%    \end{macrocode}
% (2013/12/29) Here are some ideas to think about. Each change in the response to a question
% can execute the following code. I've put the needed information in the tooltip
% above, the code below extracts this information and calls \texttt{popVisitsTbl}
% in this way, the summary need to be required to appear on separate page.
%\begin{verbatim}
%f=this.getField("\currQuiz activateSC");
%v=f.userName
%v=v.split(",")
%popVisitsTbl.apply(null,v)
%\end{verbatim}
%    \begin{macrocode}
\def\pbDoNoCorrectSumryTbl{\makebox[0pt][l]{\pushButton[\F{\FHidden}]%
    {\currQuiz NoCorrections}{0pt}{0pt}}}
%    \end{macrocode}
% A scratch counter to count the number of row entries we have created.
%    \begin{macrocode}
\newcount\eq@rowcnt
%    \end{macrocode}
%    \begin{macro}{\sumryTblQ}
%    \begin{macro}{\sumryTblR}
%    \begin{macro}{\sumryTblP}
% Through these commands, the author can change the title headings of the summary table.
%    \begin{macrocode}
\newcommand{\sumryTblQ}{Question}
\newcommand{\sumryTblR}{Responded}
\newcommand{\sumryTblP}{Page}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\displaySumryTbl}
% Place this command between the end of the quiz \textbf{on a new page} (after the closing of the
% last \texttt{questions} environment and before \verb!\end{quiz}!.
%
% The \cs{displaySumryTbl} takes two parameters, one optional and one required.
%\begin{description}
%  \item[{[\texttt{\#1}]}] is optional and takes key-value pairs
%   \begin{itemize}
%       \item \texttt{ntables}\IndexKey{ntables} is a key that has a value of 1, 2, or 3, the default is determined by
%             \cs{smrytbl@ntables}, which is set to 2 in this package. If
%             \texttt{ntables=1} only one table is created, and if \texttt{ntables=2}
%             two tables are created, each containing half the information.
%       \item \texttt{showmarkup}\IndexKey{showmarkup}: If this switch is true, then markup fields are
%             created that will hold the number of points the student received for
%             each problem. The default is there is no markup. Entering
%             \texttt{showmarkup} in the option list will generate the markup fields.
%       \item \texttt{nocorrections}\IndexKey{nocorrections}: If this switch is true, corrections will not
%             be shown when the user presses the `End Quiz' button.
%       \item \texttt{showOutOf}\IndexKey{showOutOf}: if taken the point and total points for the problem are displayed.
%               For example, `2 of 5 pts'.
%       \item \texttt{setDimens}\IndexKey{setDimen} is a key to pass its value within group created by
%             the command \cs{displaySumryTbl}. Use it to use the conditional switches to set the
%             dimensions of the markup text fields, color declarations, font declarations, etc.
%             None of it should take up space of any kind.
%   \end{itemize}
%  \item[\texttt{\#2}] is the quiz this table represents, usually this is \cs{currQuiz}.
%\end{description}
%    \begin{macrocode}
\define@key{smrytbl}{ntables}{%
  \@tempcntb=#1
  \ifnum\@tempcntb<\@ne\@tempcntb=\@ne\fi
  \ifnum\@tempcntb>\thr@@\@tempcntb=\thr@@\fi
  \edef\smrytbl@ntables{\the\@tempcntb}%
}
\def\smrytbl@ntables{2}
\define@key{smrytbl}{showmarkup}[true]{%
  \csname if#1\endcsname\eqshowmarkuptrue
    \else\eqshowmarkupfalse\fi
}
\newif\ifsmrytbl@corrections\smrytbl@correctionstrue
\define@key{smrytbl}{nocorrections}[true]{%
  \csname if#1\endcsname\smrytbl@correctionsfalse
    \else\smrytbl@correctionstrue\fi
}
\define@key{smrytbl}{showOutOf}[true]{%
  \csname if#1\endcsname\eqshowOutOftrue\def\stfmtType{OO}%
    \gdef\showOutOfinSmryTbl{true}\let\stmarkupbox\relax
  \else
    \eqshowOutOffalse\let\stfmtType\@empty
    \gdef\showOutOfinSmryTbl{false}%
  \fi
}
\let\stfmtType\@empty
\define@key{smrytbl}{setDimens}[]{#1}
\def\showOutOfinSmryTbl{false}
\def\stmarkupbox{\makebox[0pt][l]}
%    \end{macrocode}
% Finally we come to the definition of \cs{displaySumryTbl}.
%    \begin{macrocode}
\newcommand{\displaySumryTbl}[2][]{%
  \begingroup\edef\currQuiz{#2}\edef\oField{#2}\edef\curr@quiz{#2}%
  \setkeys{smrytbl}{#1}%
  \eqtmpcnta\smrytbl@ntables\relax
%    \end{macrocode}
% We accept only 1 or 2 as an argument, we put it in \cs{count0},
% if not an integer, we'll stop the compile. If the argument is not 1,
% we force a value of 2.
%    \begin{macrocode}
  \eq@rowcnt\z@\@tempcntb=\value{questionno}%
%    \end{macrocode}
% We calculate the number of rows in the first column, in case
% of a two column table. When the number of questions is odd,
% the the left-hand table will have one more entry than the right-hand
% column.
%    \begin{macrocode}
  \ifnum\eqtmpcnta=\tw@
    \divide\@tempcntb\tw@
    \advance\@tempcntb\ifodd\value{questionno}\tw@\else\@ne\fi
    \xdef\@beginSecCol{\the\@tempcntb}\advance
    \@tempcntb\m@ne
  \fi
%    \end{macrocode}
%    Three table support
%    \begin{macrocode}
  \ifnum\eqtmpcnta=\thr@@
    \edef\eq@n{\the\@tempcntb}%
    \divide\@tempcntb\eqtmpcnta
    \edef\eq@q{\the\@tempcntb}%
    \@tempcnta=\@tempcntb\multiply\@tempcnta3
    \edef\eq@p{\the\@tempcnta}%
    \@tempcnta=\eq@n
    \advance\@tempcnta-\eq@p\relax
    \ifnum\@tempcnta=\z@
      \@tempcntb=\eq@q \advance\@tempcntb\@ne
      \xdef\@beginSecCol{\the\@tempcntb}%
      \advance\@tempcntb\eq@q\relax
      \xdef\@beginThrdCol{\the\@tempcntb}%
    \else\ifnum\@tempcnta=\@ne
      \@tempcntb=\eq@q \advance\@tempcntb\@ne
      \edef\nB@lCols{\the\@tempcntb}%
      \advance\@tempcntb\@ne
      \xdef\@beginSecCol{\the\@tempcntb}%
      \advance\@tempcntb\eq@q\relax
      \xdef\@beginThrdCol{\the\@tempcntb}%
    \else\ifnum\@tempcnta=\tw@
      \@tempcntb=\eq@q \advance\@tempcntb\@ne
      \edef\nB@lCols{\the\@tempcntb}%
      \advance\@tempcntb\@ne
      \xdef\@beginSecCol{\the\@tempcntb}%
      \advance\@tempcntb\nB@lCols
      \xdef\@beginThrdCol{\the\@tempcntb}%
    \fi\fi\fi
    \@tempcntb=\eq@n
  \fi
%    \end{macrocode}
% We \cs{let} \cs{@eqListExp} to \cs{@@eqListExp}, defined below.
%    \begin{macrocode}
    \let\@eqListExp\@@eqListExp
%    \end{macrocode}
% \dots and expand the token list \cs{eqQzQuesList}.
%    \begin{macrocode}
    \eqQzQuesList
    \endgroup
}
%    \end{macrocode}
%    \end{macro}
% \paragraph*{Construction of the table.} The construction is performed by \cs{@eqListExp}.
% This is a definition of \cs{@eqListExp}. It appears in the
% token list \cs{eqQzQuesList}. A typical entry in  \cs{eqQzQuesList} is
% of the form
%\begin{quote}\ttfamily
%\string\@eqListExp\darg{\ameta{question\_label}}\darg{\string\thepage}
%\end{quote}
% We use the two arguments to construct a table of three columns: Question (consisting
% of the question label); Responded (a checkbox that is checked if that question was answered);
% and Page (a hypertext link to the page containing he question). The command may be redefined
% to as needed.\medskip\par\noindent
% \textbf{Column headings} are defined by \cmd{\eq@begintab}.
% This can be redefined. We begin a \texttt{tabular} with
% headings (may be redefined).
%    \begin{macrocode}
\def\eq@begintab{%
  \begin{tabular}[t]{lcc}\sumryTblQ&\sumryTblR&\sumryTblP\\\sthline
  {\Large\strut}}
%    \end{macrocode}
% \DescribeMacro{\sthline}\cmd{\sthline}
% is a user hook to change the appearance of the horizontal line, such
% as adding color.
%    \begin{macrocode}
\def\sthline{\hline}
%    \end{macrocode}
% End of the \texttt{tabular}.
%    \begin{macrocode}
\def\eq@endtab{\end{tabular}}
%    \end{macrocode}
% \cs{@@eqListExp} is \cs{let} to \cs{@eqListExp} in \cs{displaySumryTbl}.
%    \begin{macrocode}
\def\sumrytblCkMUsep{\kern3bp}
\def\sumrytbllinkHook#1{#1}
%    \end{macrocode}
% \textbf{First Column.} \DescribeMacro{\sumryTblProbFmt}\cmd{\sumryTblProbFmt}
% sets the {\LaTeX} formatting for the problem numbers that appear in the
% first column of the table.
%    \begin{macrocode}
\newcommand{\sumryTblProbFmt}[1]{\textbf{\textcolor{blue}{#1}}}
%    \end{macrocode}
% A macro to set the separation between the tables.
%    \begin{macrocode}
\newcommand{\sumrytablesep}{\space}
%    \end{macrocode}
% We supply basic controls for the text field, width (\DescribeMacro{\stmarkupWidth}\cmd{\stmarkupWidth}),
% height (\DescribeMacro{\stmarkupHeight}\cmd{\stmarkupHeight}), and text size
% (\DescribeMacro{\stmarkupTextSize}\cmd{\stmarkupTextSize})
%    \begin{macrocode}
\def\stmarkupWidth{12bp}\def\stmarkupHeight{9bp}\def\stmarkupTextSize{0}
%    \end{macrocode}
% \textbf{Second column.} The second column of the table consisting of a checkbox
% and stMarkup text field.
%    \begin{macrocode}
\def\st@scndclmn{%
  \checkBox[\Ff{\FfReadOnly}]
    {\ccatCurrQzWith(SanityCheck).\the\eq@rowcnt}
    {\markupHeight}{\markupHeight}{Yes}%
  \ifeqshowmarkup
    \stmarkupbox{\sumrytblCkMUsep\textField[%
      \Ff\FfReadOnly\BC{}\textColor{\pcMarkupColor}
      \textSize{\stmarkupTextSize}\autoCenter{n}]
%    \end{macrocode}
% Key to being able to have duplicated summary fields with different \texttt{showOutOf}
% options is the naming of the text field. If \texttt{showOutOf=false}, the default,
% the field name is \cs{currQuizSanityCheckPts}, but if \texttt{showOutOf=true}, the
% text field is named \cs{currQuizSanityCheckOOPts}. When the Correct button is pressed,
% the JavaScript function \texttt{correctSumryTbl()} checks for the existence of each of
% these two fields, and populates them properly formatted. The command \cs{stfmtType} is
% either \cs{@empty} or \cs{OO}.
%    \begin{macrocode}
    {\ccatCurrQzWith(SanityCheck\stfmtType Pts).\the\eq@rowcnt}%
    {\stmarkupWidth}{\stmarkupHeight}}%
  \fi
}
%    \end{macrocode}
% \textbf{Third column.} The third column of the table consisting of a link to the
% page that contains the question.
%    \begin{macrocode}
\def\st@thrdclmn#1{%
  \setLink[\linktxtcolor{\@linkcolor}
    \A{\JS{this.pageNum=(#1-1)}}]{\sumrytbllinkHook{#1}}}
%    \end{macrocode}
% Now for the definition of \cs{@@eqListExp} which does the work in the table.
%    \begin{macrocode}
\def\@@eqListExp#1#2{\global\advance\eq@rowcnt\@ne
%    \end{macrocode}
% If it is the first row, we insert the push button that will activate
% when the page becomes visible, and we expand \cs{eq@begintab}, which
% is a \texttt{tabular} environment.
%    \begin{macrocode}
  \ifnum\eq@rowcnt=\@ne
    \pbPopulateSumTable\ifsmrytbl@corrections\else
    \pbDoNoCorrectSumryTbl\fi\expandafter\eq@begintab\fi
%    \end{macrocode}
% If it is the two table solution, and the row number equals the calculated
% value of the first row of the second table, we emit another
% \cs{eq@begintab}.
%    \begin{macrocode}
  \ifnum\eqtmpcnta>\@ne\ifnum\eq@rowcnt=\@beginSecCol\relax
    \eq@endtab\expandafter\sumrytablesep\expandafter\eq@begintab
  \fi\fi
  \ifnum\eqtmpcnta=\thr@@\ifnum\eq@rowcnt=\@beginThrdCol\relax
    \eq@endtab\expandafter\sumrytablesep\expandafter\eq@begintab
  \fi\fi
%    \end{macrocode}
% We layout a row of the table, problem label, checkbox, and page.
%    \begin{macrocode}
    \sumryTblProbFmt{#1}&\st@scndclmn&\st@thrdclmn{#2}\\[1bp]
%    \end{macrocode}
% We set the \cs{eq@endtab} at the bottom of the first table,
% and at the bottom of the second table.
%    \begin{macrocode}
  \ifnum\eq@rowcnt=\value{questionno}\expandafter\eq@endtab\fi
}
%    \end{macrocode}
%
% \subsection{Duplicating the Summary Table elsewhere}
%
%    \begin{macro}{\writeProListAux}
% This command writes the information essential to the creation of
% the quiz summary table (\cs{displaySumryTbl}), and should be
% placed after the final question, and before the `End Quiz'. The purpose
% is to write the info to the auxiliary file so the table can be
% constructed elsewhere, for example, at the beginning of the quiz, or
% wherever desired.  The command writes two macros to the aux file,
% \verb!\csname \currQuiz QzQuesList\endcsname! that contains the token
% list of problems using by the table, and
% \verb!\csname \currQuiz nQuestions\endcsname! that contains the
% total number of questions.
%    \begin{macrocode}
\def\writeProListAux{%
  \eq@IWAuxOut{\string
    \csarg\string\gdef{\currQuiz QzQuesList}{\eqQzQuesList}}%
  \eq@IWAuxOut{\string
    \csarg\string\gdef{\currQuiz nQuestions}{\thequestionno}}%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\def\setParamSumryTblAux{%
  \edef\eqQzQuesList{\@nameuse{\currQuiz QzQuesList}}%
  \@ifundefined{\currQuiz nQuestions}{}{%
    \value{questionno}=\@nameuse{\currQuiz nQuestions}}%
}
%    \end{macrocode}
%    \begin{environment}{sumryTblAux}
% Normally, we use \cs{displaySumryTbl} right after the last question, and before
% the `End Quiz.' It is possible to display a summary table elsewhere, perhaps at the beginning
% of the quiz, on the first page, wherever. Assuming \cs{writeProListAux} jas beem
% inserted after the last question and before `End Quiz', you can then use the
% \texttt{sumryTblAux} environment to place the same table in another location. For example,
%\begin{verbatim}
%    \begin{sumryTblAux}{demoQuiz}
%    \begin{center}
%        {\normalsize\sffamily\bfseries Quiz Summary Table}\\[3pt]
%        \displaySumryTbl[showmarkup]{\currQuiz}
%    \end{center}
%    \end{sumryTblAux}
%\end{verbatim}
% The environment takes one parameter, the quiz name that this table
% represents. It uses \cs{setParamSumryTblAux} to set the appropriate
% variables that \cs{displaySumryTbl} uses.
%
% This environment \emph{is required} if the table appears outside the scope of the
% quiz.
%    \begin{macrocode}
\newenvironment{sumryTblAux}[1]{%
  \DeclareQuiz{#1}\setParamSumryTblAux}{}%
%    \end{macrocode}
%    \end{environment}
%    \begin{macrocode}
% End sumrytbls segment
%</sumrytbls>
%<*mcfi>
%    \end{macrocode}
% \subsection{Posing MC/math fill-in questions}
%    \begin{macrocode}
\def\bMCFI{\withinMCFItrue
  \ifx\qRadionActionsHook\@empty
    \let\qRadionActionsHook@SAVE\@empty
    \def\qRadionActionsHook{\jsR
    qRadioButtonMCFI(\Ans@choice,"\currQuiz",\thequestionno);}\else
    \let\qRadionActionsHook@SAVE\qRadionActionsHook
    \def\qRadionActionsHook{\qRadionActionsHook@SAVE\jsR
    qRadioButtonMCFI(\Ans@choice,"\currQuiz",\thequestionno);}\fi
  \ifx\every@RespBoxMath\@empty
    \let\every@RespBoxMath@SAVE\@empty
    \def\every@RespBoxMath{%
    \AddAAKeystroke{mcfiKeyStroke("\currQuiz",\thequestionno);}}%
  \else
    \let\every@RespBoxMath@SAVE\every@RespBoxMath
    \expandafter\def\expandafter\every@RespBoxMath\expandafter
    {\every@RespBoxMath@SAVE
    \AddAAKeystroke{mcfiKeyStroke("\currQuiz",\thequestionno);}}%
  \fi
}
\def\eMCFI{%
  \ifx\qRadionActionsHook@SAVE\@empty
    \let\qRadionActionsHook\@empty\else
    \let\qRadionActionsHook\qRadionActionsHook@SAVE\fi
  \ifx\every@RespBoxMath@SAVE\@empty
    \let\every@RespBoxMath\@empty\else
    \let\every@RespBoxMath\every@RespBoxMath@SAVE\fi
  \withinMCFIfalse
}
\def\eqNA{-43252452452}
\@ifundefined{text}{\let\MCFIMarkup@BOX\mbox}{\let\MCFIMarkup@BOX\text}
\newcommand\mcfiMarkupfmt{\cgBdry
  ${}^{\MCFIMarkup@BOX{\aeb@creditmarkup}}$}
\def\mcfiMarkup{\addtocounter{questionno}{-1}\mcfiMarkupfmt
  \stepcounter{questionno}}
%</mcfi>
%<*package>
%    \end{macrocode}
%    \section{Input Language definitions and JS}
% Here is were we make the redefinitions of the above commands if
% a language option is specified.
%    \begin{macrocode}
\LangRedefinitions
%    \end{macrocode}
% We introduce the document-level JavaScript for exerquiz at this point.
%    \begin{macrocode}
\input{aebjs.def}
%    \end{macrocode}
% If the \texttt{usesumrytbls} option is taken, we input the code.
%    \begin{macrocode}
\inputSumryTblCode
%    \end{macrocode}
% If the \texttt{usemcfi} option is taken, we input the code.
%    \begin{macrocode}
\inputMCFICode
%    \end{macrocode}
%    \section{eForms Support}
%    \begin{macro}{\solutionColor}
% This color is introduced at the pdfmark/rawPDF level. Define
% the color without commas. For example |\solutionColor{0 .6 0}|
%    \begin{macrocode}
\newcommand{\solutionColor}[1]{\def\eq@argi{#1}\ifx\eq@argi\@empty
  \def\solution@Color{\solutionColorDef}\else
  \def\solution@Color{#1}\fi}
\newcommand{\solutionColorDef}{0 .6 0}
\solutionColor{\solutionColorDef}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
% End of package segment
%</package>
%<*eqcolor>
%    \end{macrocode}
%
% \subsection{Color support}
%
%    \begin{macrocode}
\def\eq@getCmdName#1#2{\edef#1{\expandafter\@gobble\string#2}}
\def\eq@getfirst#1#2\@nil{\def\eq@argi{#1}}
\def\eq@checkValidityModel#1{%
  \if#1g\else\if#1r\else\if#1c\else
    \PackageError{exerquiz}
    {JavaScript does not support this model}
    {Use a named color from one of the models gray, rgb, or cmyk.}
  \fi\fi\fi
}
\def\eq@jsSetColorMsg#1#2{\PackageWarning{exerquiz}
  {The argument `#2' of \string#1\MessageBreak
  is not of the right form.\MessageBreak Using the default}}
\def\eqModelInfo#1#2{%
  \uppercase{\def\eq@ucmodel{#1}}\def\eq@modelspec{#2}%
  \eq@getfirst#1\@nil\eq@ResetModelForGray{\eq@argi}%
  \eq@checkValidityModel{\eq@argi}%
}
\def\eq@ResetModelForGray#1{\if#1g\def\eq@ucmodel{G}\fi}
%    \end{macrocode}
% We test for raw JS color in two ways, look for \texttt{["} or look for \texttt{co}
% as the first two tokens.
%    \begin{macrocode}
\def\eq@checkRawJSColor#1{%
  \edef\eq@argi{#1}\ifx\eq@argi\@empty
    \def\eq@next{\let\eq@rawJSCol\eq@YES}\else
  \def\eq@next{\expandafter\eq@@checkRawJSColor#1\@nil}\fi\eq@next
}
\def\eq@@checkRawJSColor#1#2#3\@nil{\let\eq@rawJSCol\eq@NO
  \let\eqpredefineJSCol\eq@NO
  \if[#1\if#2"\let\eq@rawJSCol\eq@YES\fi\fi
  \ifx\eq@rawJSCol\eq@NO\if#1c\if#2o\let\eq@rawJSCol\eq@YES
  \let\eqpredefineJSCol\eq@YES\fi\fi\fi
}
\def\eq@jsColorWXColori#1#2{\edef\eq@colorDefn{#2}%
  \ifx\eq@colorDefn\@empty
    \ifx\is@Defined\eq@YES
      \edef\eq@colorDefn{\csname\cmdName Def\endcsname}\else
      \PackageError{exerquiz}{JS color \string#1 has an
        empty definition}{}\fi
  \fi
  \eq@checkRawJSColor{\eq@colorDefn}%
  \ifx\eq@rawJSCol\eq@NO
  \extractcolorspec{\eq@colorDefn}{\eq@tmp@color}%
  \expandafter\eqModelInfo\eq@tmp@color
  \edef#1{["\eq@ucmodel",\eq@modelspec]}%
  \else\edef#1{\eq@colorDefn}\fi
}
\def\eq@jsColorWOXColori#1#2{\def\eq@colorDefn{#2}%
  \ifx\eq@colorDefn\@empty
    \ifx\is@Defined\eq@YES
      \edef\eq@colorDefn{\csname cmdName Def\endcsname}\else
      \PackageError{exerquiz}{JS color \string#1 has an
          empty definition}{}\fi
  \fi
  \eq@checkRawJSColor{\eq@colorDefn}%
  \ifx\eq@rawJSCol\eq@YES\edef#1{\eq@colorDefn}\else
    \eq@jsSetColorMsg{#1}{#2}\fi
}
%    \end{macrocode}
% \DescribeMacro{\jsColor} General command for defining a JavaScript Color, and support commands for
% \textsf{xcolor} and w/o \textsf{xcolor}. When \textsf{xcolor} is used, colors
% can be specified using the usual {\LaTeX} color methods:
%\begin{verbatim}
%   \jsColor{\rghtColorJS}{blue}
%   \jsColor{\rghtColorJS}{[cmyk]{0,1,0,0}}
%\end{verbatim}
% or the \emph{JavaScript format} can be used:
%\begin{verbatim}
%   \jsColor{\rghtColorJS}{["RGB",0,0,1]}
%   \jsColor{\rghtColorJS}{["CMYK",0,1,0,0}
%\end{verbatim}
% When \textsf{xcolor} is not used, only the JavaScript format is allowed.
%    \begin{macrocode}
\def\jsColor#1#2{\eq@getCmdName{\cmdName}{#1}%
  \let\is@Defined\eq@YES
  \expandafter\ifx\csname\cmdName\endcsname\relax
    \PackageWarning{exerquiz}{\string#1 is not a command used by
    exerquiz.\MessageBreak Will define it anyway}%
    \let\is@Defined\eq@NO\fi
  \HyColor@IfXcolor{\eq@jsColorWXColori{#1}{#2}}%
    {\eq@jsColorWOXColori{#1}{#2}}%
}
%    \end{macrocode}
%    \begin{macrocode}
%</eqcolor>
%<*package>
%    \end{macrocode}
%    Now input \texttt{eqcolor.def}.
%    \changes{v7.8f}{2017/02/29}{Separated the color stuff into its own segment
%    (\string\texttt{eqcolor})}
%    \begin{macrocode}
\@ifundefined{jsColor}{%
  \InputIfFileExists{eqcolor.def}{\PackageInfo{exerquiz}
    {Inputting eqcolor.def}}
    {\PackageError{exerquiz}{cannot find eqcolor.def}
    {Refresh your file name database and try again.}}
}{}
%    \end{macrocode}
%
% \subsection{Default Colors for Checks, Crosses, and Borders}
%
% These commands are used to define the colors for the checks,
% crosses and correct symbols.  These are controlled by JavaScript,
% so use the correct syntax for defining colors here.
%
% The default colors for the above defined color declaration commands, the
% the default definitions of the color commands. The commands appear in pairs
% and are used in the second and third arguments of \cs{eq@jsColor}.
%    \begin{macrocode}
\newcommand\rghtColorJSDef{["RGB", 0, .6, 0]}
\newcommand\rghtColorJS{\rghtColorJSDef}
\newcommand\wrngColorJSDef{color.red}
\newcommand\wrngColorJS{\wrngColorJSDef}
\newcommand\partialColorJSDef{color.blue}
\newcommand\partialColorJS{\partialColorJSDef}
\newcommand\defaultColorJSDef{color.black}
\newcommand\defaultColorJS{\defaultColorJSDef}
%    \end{macrocode}
% The next command is special, it is used in the quiz environments to allow a localization
% of the color. Unlike the ones above, this can be specified within the body of the document.
%    \begin{macrocode}
\let\defaultColorJSLoc\@empty
\let\defaultColorJSLocDef\@empty
\let\rghtColorJSLoc\@empty
\let\rghtColorJSLocDef\@empty
\let\wrngColorJSLoc\@empty
\let\wrngColorJSLocDef\@empty
\let\partialColorJSLoc\@empty
\let\partialColorJSLocDef\@empty
%    \end{macrocode}
% \paragraph*{Symbol choice.} This is in support for changing check styles for quizzes
% These must be declared in the preamble.
%    \begin{macrocode}
\def\chooseJSsymbol{\@ifstar{\let\eq@isstar\eq@YES\chooseJSsymboli}
  {\let\eq@isstar\eq@NO\chooseJSsymboli}}
\def\chooseJSsymboli#1{\lowercase{\edef\eq@arg{#1}}%
  \def\eq@carg{check}\ifx\eq@arg\eq@carg
  \def\eq@retnStyle{style.ch}\else
  \def\eq@carg{cross}\ifx\eq@arg\eq@carg
  \def\eq@retnStyle{style.cr}\else
  \def\eq@carg{diamond}\ifx\eq@arg\eq@carg
  \def\eq@retnStyle{style.di}\else
  \def\eq@carg{circle}\ifx\eq@arg\eq@carg
  \def\eq@retnStyle{style.ci}\else
  \def\eq@carg{star}\ifx\eq@arg\eq@carg
  \def\eq@retnStyle{style.st}\else
  \def\eq@carg{square}\ifx\eq@arg\eq@carg
  \def\eq@retnStyle{style.sq}\else
  \let\eq@retnStyle\@empty
  \ifx\eq@isstar\eq@NO\PackageWarning{exerquiz}
  {Argument `#1' not recognized.\MessageBreak
   Permissible values are check, cross, diamond,\MessageBreak
   circle, star, square. Will use the default}\fi
  \fi\fi\fi\fi\fi\fi
}
%    \end{macrocode}
%    \begin{macro}{\setRightAnsSymb}
%    The check style when the user is correct. (def: \texttt{style.ch})
%    \begin{macro}{\setCorrAnsSymb}
%    The check style when the user is wrong but you are marking which response is correct.
%    (def: \texttt{style.ci})
%    \begin{macro}{\setWrongAnsSymb}
%    The check style when the use chooses the incorrect answer.
%    (def: \texttt{style.cr})
%    \begin{macrocode}
\newcommand\setRghtAnsSymb[1]{\chooseJSsymbol{#1}%
  \ifx\eq@retnStyle\@empty\else
  \edef\rghtAnsSymbJS{\eq@retnStyle}%
  \edef\rghtAnsSymb{\eq@carg}\fi}
\def\rghtAnsSymbJS{style.ch}
\def\rghtAnsSymb{check}
\newcommand\setCorrAnsSymb[1]{\chooseJSsymbol{#1}%
  \ifx\eq@retnStyle\@empty\else
  \edef\corrAnsSymbJS{\eq@retnStyle}%
  \edef\corrAnsSymb{\eq@carg}\fi}
\def\corrAnsSymbJS{style.ci}
\def\corrAnsSymb{circle}
\newcommand\setWrngAnsSymb[1]{\chooseJSsymbol{#1}%
  \ifx\eq@retnStyle\@empty\else
  \edef\wrngAnsSymbJS{\eq@retnStyle}%
  \edef\wrngAnsSymb{\eq@carg}\fi}
\def\wrngAnsSymbJS{style.cr}
\def\wrngAnsSymb{cross}
\def\setRghtAnsSymbLoc#1{\chooseJSsymbol*{#1}%
  \ifx\eq@retnStyle\@empty
    \let\rghtAnsSymbJSLoc\@empty\else
    \edef\rghtAnsSymbJSLoc{\eq@retnStyle}\fi
}
\def\setCorrAnsSymbLoc#1{\chooseJSsymbol*{#1}%
  \ifx\eq@retnStyle\@empty
    \let\corrAnsSymbJSLoc\@empty\else
    \edef\corrAnsSymbJSLoc{\eq@retnStyle}\fi
}
\def\setWrngAnsSymbLoc#1{\chooseJSsymbol*{#1}%
  \ifx\eq@retnStyle\@empty
    \let\wrngAnsSymbJSLoc\@empty\else
    \edef\wrngAnsSymbJSLoc{\eq@retnStyle}\fi
}
\let\rghtAnsSymbJSLoc\@empty
\let\rghtAnsSymbJSLocDef\@empty
\let\corrAnsSymbJSLoc\@empty
\let\corrAnsSymbJSLocDef\@empty
\let\wrngAnsSymbJSLoc\@empty
\let\wrngAnsSymbJSLocDef\@empty
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% \subsection{``Every'' Definitions}
%    \begin{macrocode}
\newcommand\everyeqTextField[1]{\def\every@eqTextField{#1}}
\def\every@eqTextField{}
\newcommand\everyRespBoxMath[1]{\def\every@RespBoxMath{#1}}
\def\every@RespBoxMath{}
\newcommand\everyRespBoxTxt[1]{\def\every@RespBoxTxt{#1}}
\def\every@RespBoxTxt{}
\newcommand\everyrbMarkup[1]{\def\every@rbMarkup{#1}}
\def\every@rbMarkup{}
\newcommand\everysqTallyBox[1]{\def\every@sqTallyBox{#1}}
\def\every@sqTallyBox{}
\newcommand\everysqTallyTotal[1]{\def\every@sqTallyTotal{#1}}
\def\every@sqTallyTotal{}
\newcommand\everyScoreField[1]{\def\every@ScoreField{#1}}
\def\every@ScoreField{}
\newcommand\everyAnswerField[1]{\def\every@AnswerField{#1}}
\def\every@AnswerField{}
\newcommand\everyPointsField[1]{\def\every@PointsField{#1}}
\def\every@PointsField{}
\newcommand\everyPercentField[1]{\def\every@PercentField{#1}}
\def\every@PercentField{}
\newcommand\everyGradeField[1]{\def\every@GradeField{#1}}
\def\every@GradeField{}
%    \end{macrocode}
%    \begin{macro}{\everysqRadioButton}
%    \begin{macro}{\everyqRadioButton}
% Here, you can control the appearance of all the standard checkboxes, also
% effects radio fields of \texttt{shortquiz} and \texttt{quiz}.
%    \begin{macro}{\everyqckCheckBox}
% (2010/07/30) Added \cs{everyqckCheckBox} to control the appearance
% of the underlying checkbox for \texttt{manswers} environments.
% Previously \cs{everyqRadioButton} was used, but this is the same as used by
% multiple choice. To get control over \texttt{manswers} when \cs{useMCCircles}
% and \cs{useMCCRects} \texttt{manswers} needs it one ``every'' command.
%    \begin{macrocode}
\newcommand{\everysqRadioButton}[1]{\def\every@sqRadioButton{#1}}
\def\every@sqRadioButton{}
\newcommand{\everyqRadioButton}[1]{\def\every@qRadioButton{#1}}
\def\every@qRadioButton{}
\newcommand{\everyqckCheckBox}[1]{\def\every@qckCheckbox{#1}}
\def\every@qckCheckbox{}
%    \end{macrocode}
%    \begin{macro}{\everyqCheckBox}
% (12/08/2008) Added \cs{everyqCheckBox}, this is used only for the check boxes
% that hold the answer of a multiple choice question, not a multiple selection
% problem. This change is needed to create a circle radio button, in this case
% we need to make the boundary of the check box to 0 width.
%    \begin{macrocode}
\newcommand{\everyqCheckBox}[1]{\def\every@qCheckBox{#1}}
\def\every@qCheckBox{}
\newcommand{\everysqCheckBox}[1]{\def\every@sqCheckBox{#1}}
\def\every@sqCheckBox{}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% Here, you can control the appearance of all the standard buttons.
%    \begin{macrocode}
\let\everyeqButtonField\everyButtonField
\newcommand\everyCorrAnsButton[1]{\def\every@CorrAnsButton{#1}}
\def\every@CorrAnsButton{}
\newcommand\everysqClearButton[1]{\def\every@sqClearButton{#1}}
\def\every@sqClearButton{}
\newcommand\everyeqButton[1]{\def\every@eqButton{#1}}
\newcommand\everyCorrButton{\everyeqButton}
\def\every@eqButton{}
\newcommand\everyBeginQuizButton[1]{\def\every@BeginQuizButton{#1}}
\def\every@BeginQuizButton{}
\newcommand\everyEndQuizButton[1]{\def\every@EndQuizButton{#1}}
\def\every@EndQuizButton{}
% Replace everyeqGenButten with everyPushButton
\let\everyeqGenButton\everyPushButton
\let\every@eqGenButton\every@PushButton
\let\eqGenButton\pushButton
\newcommand\everyeqIcon[1]{\def\every@eqIcon{#1}}
\def\every@eqIcon{}
%    \end{macrocode}
%
%  \subsection{Utility macro to dynamically modify appearances}
%
%  This internal command is used to dynamically modify the appearance of form fields.
%  \begin{macro}{\eq@addExpandTo}\hskip-\marginparsep\texttt{\darg{\ameta{\cs{CMD}}}\darg{\ameta{KVPs}}}
%  The \cs{eq@addExpandTo} is a utility command that  adds eforms key-value pairs to the
%  end of the macro \texttt{\ameta{\cs{CMD}}}. The second argument of the KVP is expanded first.
%  Used to dynamically modify appearances of a form field.
% \changes{v8.8.5}{2021/10/03}{Added \string\cs{eq@addExpandTo}}
%    \begin{macrocode}
\def\eq@addExpandTo#1#2{\bgroup\let\protect\noexpand
  \toks@=\expandafter{#1}\protectedKeys*{p@Keys}{#2}%
  \edef\x{\@nameuse{p@Keys}}\toks2=\expandafter{\x}%
  \xdef#1{\the\toks@\the\toks2}\egroup
}
%    \end{macrocode}
%    \end{macro}

% \subsection{Additional Format and Action keys}
%
%    \begin{macro}{\AddAAFormat}
% Here is the definition of \cs{AddAAFormat}. This macro can be used
% in \cs{RespBoxMath} to add in formatting of the answer. This macro is
% necessary because the \cs{AA} actions for the \textsf{exerquiz} quiz macros
% are ``protected''; the document author cannot accidentally overwrite my
% JavaScript for processing the user's answer.
% \begin{flushleft}
% Example: In the preamble
%\begin{verbatim}
%\begin{defineJS}{\formatAsSet}
%if (event.value.replace(/\\s/g,"") != "")
%    event.value =  "{ " + event.value + " }";
%\end{defineJS}
%\end{verbatim}
% and in the body of a \texttt{quiz} environment,
%\begin{verbatim}
%$x^2 - 3x + 2 = 0$, $S = \RespBoxMath[\AddAAFormat{\formatAsSet}
%    \rectW{.75in}\textSize{0}]{1,2}{1}{.0001}{[0,1]}*{ProcRespSetNum}$
%\end{verbatim}
%\end{flushleft}
%    Define a special value (\cs{formatInitAltApprs}) for \cs{AddAAFormat} used in initializing \cs{RespBoxMath} problems,
%    where there are alternate appearances.
%    See the {Acro\negthinspace\TeX} Blog article \url{http://www.acrotex.net/blog/?p=1335} for a discussion of the use of \cs{formatInitAltApprs}.
%    \changes{v8.1a}{2017/09/03}{Define a special value (\string\cs{formatInitAltApprs}) for \string\cs{AddAAFormat}}
%    \begin{macrocode}
\def\formatInitAltApprs{\formatInitAltApprs}
\def\@eqAddAAFormat#1{\def\@rgi{#1}\ifx\@rgi\formatInitAltApprs
  \bInitAltAppr\else\def\eqAddAAFormat{#1}\fi}
\def\eqAddAAFormat{}
\def\formatAsSet{try{formatAsSet()}catch(e){}}
\def\formatAsVector{try{formatAsVector()}catch(e){}}
%    \end{macrocode}
%    \end{macro}
%    What follows are a series of three ``action'' keys, that is, their arguments are
%    JavaScript code. They are meant to be used in highly specialized settings.
%    \begin{macro}{\setActionKeys}
%    The action keys can be set through the optional argument, if available, or they can be set
%    globally using the command \cs{setActionKeys}. The only keys supported for use
%    as the argument of \cs{setActionKeys} are \cs{AddAAKeystroke\{\meta{code}\}},
%    \cs{AddAAMouseUpMC\{\meta{code}\}}, and \cs{AddAAMouseUpMS\{\meta{code}\}}, though
%    this is not enforced due to the obscure nature their use. The action settings remain
%    in force until you cancel them out with \cs{AddAAKeystroke\{\}}, for example.
%    \changes{v7.8k}{2017/07/22}{Added \string\cs{setActionKeys}}
%    \changes{v7.8j}{2017/07/23}{Restricted the use of \string\cs{setActionKeys} to a
%    selected number of keys}
%    \begin{macrocode}
\def\eq@SupActnLst{{\AddAAKeystroke}{\AddAAMouseUpMC}%
  {\AddAAMouseUpMS}{\AddAAFormat}}
\newcommand\setActionKeys{\edef\catOfAt{\the\catcode`@}%
  \ifnum\catOfAt=11 \let\eq@CatTail\relax\else
  \makeatletter\let\eq@CatTail\makeatother\fi\setActionKeysi}
\def\setActionKeysi#1{\let\eq@itsGood\eq@One
  \def\setActionKeys@cont{\processAppArgs#1\end\@nil}%
  \begingroup\eq@checkivValidKeys#1\end\ef@nil\endgroup\eq@CatTail}
\def\eq@checkivValidKeys#1#2{\def\eq@GOOD{good}\expandafter
    \@tfor\expandafter
    \@ction\expandafter:\expandafter=\eq@SupActnLst\do{%
    \expandafter\def\@ction{good}}%
    \ifx\end#1% if #1=\end, #2=\ef@nil.
      \def\eq@next{\aftergroup\setActionKeys@cont}%
    \else
      \if\eq@itsGood\eq@One
        \let\itp@ss0\let\@@next\relax
        \expandafter\@tfor\expandafter
          \@ction\expandafter:\expandafter=\eq@SupActnLst\do{%
          \expandafter\ifx\expandafter#1\@ction
          \let\itp@ss\eq@One\@break@tfor
        \fi}% do
        \if\itp@ss\eq@Zero\let\eq@itsGood\eq@Zero
          \def\eq@next{\def\eq@lastArg{#1}\expandafter
            \eq@sqkErrorMsg\ef@gobbletonil}\else
          \let\eq@next\eq@checkivValidKeys\fi
        \else\let\eq@next\ef@gobbletonil\fi
    \fi %\ifx\end
    \eq@next
}
\def\eq@sqkErrorMsg#1{\PackageError{exerquiz}{The key \expandafter
  \string\eq@lastArg\space is not supported by
  \string\setActionKeys.\MessageBreak
  Remove the key or correct the spelling of the key}{}}
%    \end{macrocode}
%     The \DescribeMacro{\addToAction}\cs{addToAction} is a companion to \cs{setActionKeys}. When
%     \cs{setActionKeys} sets a key, later in the document, you might want to add to that action
%     earlier defined. Thus, \verb~\addToAction{\AddAAFormat}{var x=2;}~ appends
%     \texttt{var x=2;} to the code already defined earlier by
%     \cs{setActionKeys}, I hope. The first argument is one of the keys in \cs{eq@SupActnLst}
%     (the only ones accepted), the second argument is the script to add to the previously added script.
%     The optional \texttt{*}-argument reverses the order the code is arranged.
%    \begin{macrocode}
\def\addToAction{\makeatletter\@ifstar{\let\isSt@r\eq@YES\@ddToAction}
  {\let\isSt@r\eq@NO\@ddToAction}}
\def\@ddToAction#1#2{\let\eq@itsGood\eq@One
  \def\setActionKeys@cont{\@@ddToAction{#1}{#2}}\begingroup
  \eq@checkivValidKeys{#1}{#2}\end\ef@nil\endgroup\makeatother}
\def\@@ddToAction#1#2{\@getCmdName{#1}%
  \if\isSt@r\eq@YES\toks2={#2}%
    \toks@=\aeb@exiii{\csname eq\@CmdName\endcsname}%
    \edef\tmp@tokshold{\the\toks2 \the\toks@}%
    \toks@=\expandafter{\tmp@tokshold}\else
    \toks@=\aeb@exiii{\csname eq\@CmdName\endcsname#2}\fi
  \expandafter\edef\csname eq\@CmdName\endcsname{\the\toks@}%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\AddAAKeystroke}
% The value of this key is JS code that executes after the input box has been processed.
% Created to use with AcroFleX for showing graphs after the user enters a response.
%
%\changes{v6.3b}{2008/06/29}
%{
% Added the \string\cs{AddAAKeystroke} to the recognizable set of keys. This will be obeyed
% within the optional arguments of \string\cs{RespBoxMath} and \string\cs{RespBoxTxt}.
%}
%    \begin{macrocode}
\def\@eqAddAAKeystroke#1{\def\argi{#1}\ifx\argi\@empty
  \def\eqAddAAKeystroke{}\else\def\eqAddAAKeystroke{\r #1}\fi} %\r
\def\eqAddAAKeystroke{}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\AddAAMouseUpMC}
%    \begin{macro}{\AddAAMouseUpMS}
%    Added form keys (for MC and MS questions), can be use to add additional
%    action with a mouse up event.
%    \changes{v7.8j}{2017/07/21}{Added form keys \string\cs{@eqAddAAMouseUpMC}
%    and \string\cs{@eqAddAAMouseUpMS}}
%    \begin{macrocode}
\def\@eqAddAAMouseUpMC#1{\def\argi{#1}\ifx\argi\@empty
  \def\eqAddAAMouseUpMC{}\else\def\eqAddAAMouseUpMC{#1}\fi}
\def\eqAddAAMouseUpMC{}
\def\@eqAddAAMouseUpMS#1{\def\argi{#1}\ifx\argi\@empty
  \def\eqAddAAMouseUpMS{}\else\def\eqAddAAMouseUpMS{#1}\fi}
\def\eqAddAAMouseUpMS{}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \subsection{An pushbutton to hold an icon appearance}
%    I don't remember much about the \cs{eqIcon} command, don't remember
%    how this is used.
%    \begin{macro}{\eqIcon}
% Create a push button for displaying an icon. I've set this on read only, this
% can be removed by saying \verb+\Ff{-\FfReadOnly}+/
%\begin{verbatim}
% #1 = optional, used to enter any modification of the appearance/actions
% #2 = the title of the button field
% #3 = the width of the bounding rectangle
% #4 = the height of the bounding rectangle
%\end{verbatim}
%    \begin{macrocode}
\def\eqIconDefaults{%
  \rawPDF{}\S{}\mkIns{/TP 1}\W{}
  \CA{}\RC{}\AC{}\BC{}\BG{}\H{N}
  \textColor{0 g}\Ff{\FfReadOnly}
}
\newcommand\eqIcon[4][]{%
  \mbox{\push@@Button{#1}{#2}{#3}{#4}{}{\eq@setButtonProps
    \eq@Button@driver}{\eqIconDefaults\every@ButtonField
    \every@eqIcon}}%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\eq@restoreCats
%</package>
%    \end{macrocode}
%
%    \section{Document Level JavaScripts}
%
% The \texttt{insDLJS} package is used to insert the JavaScript at
% the document level. This package makes all necessary
% driver-dependent conversions, we just write the JavaScript code,
% which is hard enough.
%
%    \begin{macrocode}
%<*aebjs>
%    \end{macrocode}
%    \begin{macrocode}
\def\aeb@array{new Array}
%    \end{macrocode}
% (07/16/11) Some definitions that may be used by \texttt{requireForm}, a \cs{RespMathBox} filter
%    \begin{macrocode}
\def\refac#1{\\(#1\\)}\def\regrp#1{(#1)}\def\rechrclass#1{[#1]}
\def\redm{\\.}\def\remul{\\*}\def\rediv{\\/}\def\repow{\\^}
\def\redigit{\\d}\def\reany{.}\def\rebstr{\string^}\def\reestr{\string$}
%    \end{macrocode}
%    \begin{macro}{\preDenyForm}
%    \begin{macro}{\preReqForm}
%    \begin{macro}{\postDenyForm}
% (10/07/11) Some convenience commands to simplifying the use of the \texttt{priorParse}
% and \texttt{postParse} filters.
%    \begin{macrocode}
\def\preReqForm{\Array(requireForm,\@gobble}
\def\preDenyForm{\Array(denyForm,\@gobble}
\def\postDenyForm{\Array(requireFormNot,\@gobble}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% \DescribeMacro{\noPeekArgs}\cmd{\noPeekArgs} is used to modify the arguments
% of the no peeking alert box.
%    \begin{macrocode}
\newcommand{\noPeekArgs}[1]{%
  \def\NoPeekAlert{eqAppAlert(#1)}}\def\newNoPeekArgs{}
\def\NoPeekAlert{eqAppAlert(\noPeekMsg,3)}
%    \end{macrocode}
%    \begin{macrocode}
\newcommand{\dlLibSpecRespJS}{"none","undefined","empty"}
\newif\ifSubstVars\SubstVarsfalse % dps17
\newif\ifShowAppr\ShowApprtrue % dps17
\def\altApprOn{\ShowApprtrue} % dps17
\def\altApprOff{\ShowApprfalse} % dps17
\def\corrChoiceFullyOn{\def\eqCorrChoiceFully{true}}
\def\corrChoiceFullyOff{\def\eqCorrChoiceFully{false}}
\corrChoiceFullyOn
%    \end{macrocode}
%    Implement a local version of full corrections of MC and MS
%    \changes{v8.1l}{2018/02/07}{Add local version of \string\cs{corrChoiceFullOn}}
%    \begin{macrocode}
\def\corrLocalChoiceFullyOn{\def\eqCorrLocalChoiceFully{true}}
\def\corrLocalChoiceFullyOff{\def\eqCorrLocalChoiceFully{false}}
\def\resetLocalChoiceFully{\let\eqCorrLocalChoiceFully\@empty}
\resetLocalChoiceFully % no local implementation
\begin{insDLJS*}[exerquizLoaded]{exerquiz}
%    \end{macrocode}
% \subsection{Global Data}
% Global data and some miscellaneous definitions
%    \begin{macrocode}
\begin{newsegment}{AeB: AcroTeX eDucation Bundle}
/*
  Document Level JavaScript
  AcroTeX eDucation Bundle
  D. P. Story copyright 2000-\the\year
  \dlPkgInfoPkg Dated \dlPkgInfoDate
*/
var exerquizLoaded = true;
this.disclosed = true;
app.runtimeHighlight=false;
var bDisplaySilent=false; // dps
\end{newsegment}
\begin{newsegment}{Eq: Global Data}
var ok2Continue = true;
%    \end{macrocode}
% The global variable \texttt{ProcessIt} is really used only once. In the
% function \texttt{DisplayAnswer()}. The function is called by the correct
% answer button. It sets \texttt{ProcessIt = false}, then it inserts the correct
% answer into the text field. A \texttt{false} value of \texttt{ProcessIt}
% prevents the \texttt{ProcResp} (and others) from from processing the answer.
%
% The arrays \texttt{RightWrong}, \texttt{ProbValue}, \texttt{ProbDist} and \texttt{ProbType} maintain quiz information
% for a quiz. The following are typical values of these arrays. This is a quiz taken
% from the \texttt{manswer.tex} demo file. Question 1 is a multiple selection question; Question 2
% is a multiple choice question; Question 3 is a math fill-in question; and Question 4
% is a grouped question. (The \texttt{undefined} entries indicate an empty or a not used entry.)
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
%commandchars={!()},codes={\catcode`\%=9}]
%RightWrong.toSource()
%[undefined, [0, 1, [undefined, undefined, 0, 1, 1, 0, 1]], 1, 1,
%   [undefined, 1, 1, 1, 0]]
%
%Responses.toSource()
%[undefined, [undefined, undefined, "b", "c", "d", "e", "f"], "a", "cos(x)",
%   [undefined, "0", "4", "1", "9"]]
%
%ProbValue.toSource()
%[undefined, [3, 5, [undefined, undefined, -2, 3, 3, -2, 3]], [0, 3, 0], 3,
%   [1, "groupEval", 4, 4, 1, 1, 1, 1]]
%
%ProbDist.toSource()
%[undefined, 5, 3, 3, 3]
%
%ProbType.toSource()
%[undefined, "na", "na", "na", "na"]
%
%aPointType.toSource()
% [undefined, [2, "mc"], [4, "ms"], [2, "text"], [4, "math"], [4, "grp"]]
%\end{Verbatim}
%    \begin{macrocode}
var ProcessIt = true;
var retn;
var Score=0;
var ptScore=0;
var pcScore=0;
var quizGrade="C";
var NQuestions=0;
var NPointTotal=0;
var e = Math.E;
var pi = Math.PI;
var replaceExclaim = \replaceexclaim;
var negPointsAllowed = \negpointsallowed;
var negPointsMarkupAllowed = \negpointsmarkupallowed;
var aQuizControl = new Object;
var RightWrong=new Array();
var ProbValue = new Array();
var ProbDist = new Array();
var ProbType = new Array();
var Responses=new Array();
var appAlerts = new Object;
var _mathVars="x";
var _ModalNotOn=true;
var GradeScaleDefault=new Array(\eqGradeScale);
var aDlLibSpecResp=new Array(\dlLibSpecRespJS);
%    \end{macrocode}
% JSf is an array of supported mathematical functions.
%\changes{v6.06}{2007/02/23}
%{
% Separated the \string\texttt{JSf} array into \string\texttt{JSfBuiltIn} and \string\texttt{JSfCustom}. This
% allows us to identify the built-in JavaScript functions. I concatenate these two
% into \string\texttt{JSf}.
%}
%    \begin{macrocode}
var JSfBuiltIn = new Array
    ( "abs","acos","asin","atan","ceil", "floor","cos","exp",
      "log","max","min","pow","random","round","sin",
      "sqrt","tan");
%    \end{macrocode}
%\changes{v6.3c}{2008/07/03}
%{
%   Added the hyperbolic functions and inverse hyperbolic functions
%}
% Additional function recognized by exerquiz. Note to self, when adding
% functions, if one function is a substring of another, list the function
% with the longer name first. Searching is done in the order the functions
% are listed in this array.
%\changes{v6.3o}{2010/05/24}
%{
%   Modification of the array structure for supported JS functions, due to
%    Robert Marik. He writes, ``arcsin(x), arccos(x) and arctan(x) are not
%    recognized properly when implmulti from dljslib is active. I think that
%    the problem is caused by the fact that arcsin(x) follows sin(x) in the
%    field of known functions and converted into arc*sin(x) and then into
%    a*r*c*sin(x). I enclose the patch for the \textsf{exerquiz.dtx} file which in my
%    opinion solves the problem.''
%}
%    \begin{macrocode}
var JSfCustomEarly = new Array ("arctan", "arcsin", "arccos")
var JSfCustomLate = new Array
    ( "logc", "ln","sec","csc","cot",
       "asinh", "acosh","atanh","acoth","asech","acsch",
       "sinh", "cosh","tanh","coth","sech","csch","sgn",
       "C","P","fact","pi");
var JSf = new Array().concat(JSfCustomEarly, JSfBuiltIn, JSfCustomLate);
var JSfCustom = new Array().concat(JSfCustomEarly, JSfCustomLate);
var JSc = new Array("PI","E")
%    \end{macrocode}
% Additional functions that I've defined.
%    \begin{macrocode}
function ln(x) { return Math.log(x); }
function sec(x) { return 1/Math.cos(x); }
function csc(x) { return 1/Math.sin(x);}
function cot(x) { return Math.cos(x)/Math.sin(x); }
function arctan(x) { return Math.atan(x); }
function arcsin(x) { return Math.asin(x); }
function arccos(x) { return Math.acos(x); }
function logc(x) { return Math.LOG10E * Math.log(x); }
function C(x,y) {return ch(x,y);}
function P(x,y) {return perm(x,y);}
%    \end{macrocode}
% Additional functions that I've defined. (07/03/08)
%    \begin{macrocode}
function sinh(x) { return ( Math.exp(x) - Math.exp(-x) )/2; }
function cosh(x) { return ( Math.exp(x) + Math.exp(-x) )/2; }
function tanh(x) {
    return (Math.exp(x)-Math.exp(-x))/(Math.exp(x)+Math.exp(-x)); }
function coth(x) {
    return ( Math.exp(x)+Math.exp(-x))/(Math.exp(x)-Math.exp(-x)); }
function sech(x) { return 2/( Math.exp(x) + Math.exp(-x) )/2; }
function csch(x) { return 2/( Math.exp(x) - Math.exp(-x) )/2; }
function asinh(x) { return Math.log (x+Math.sqrt(Math.pow(x,2)+1)); }
function acosh(x) {
    return Math.log (x+Math.sqrt(Math.pow(x,2)-1)); } // x ge 1
function atanh(x) { return .5*Math.log ((1+x)/(1-x)); } // -1 < x < 1
function acoth(x) { return atanh(1/x); } // |x| > 1
function asech(x) { return acosh(1/x); } // 0 < x le 1
function asch(x) { return asinh(1/x); } // x ne 0
function acsch(x) { return asinh(1/x); } // x ne 0
function sgn(x) { return (x==0?0:(x<0?-1:1)) };
%    \end{macrocode}
% The aGroup array lists left and right grouping delimiters. This array is
% used by ParseInput() to call CkBalP().
%    \begin{macrocode}
var aGroup = new Array
    ( ["\(","\)",\eqParens],
      ["[","]",\eqBrackets],
      ["{","}",\eqBraces]
    );
\end{newsegment}
%    \end{macrocode}
% \subsection{Math Fill-in}
% This section of the code is primarily dedicated to processing the math fill-in questions.
%    \begin{macrocode}
\begin{newsegment}{Eq: Support for Math Fill-in}
%    \end{macrocode}
% A custom alert box that uses \texttt{\_ModalNotOn} to alert when the modal alert
% box is displayed. When \texttt{!\_ModalNotOn} is true, there is an alert box being
% displayed.
%\changes{v6.9}{2014/10/05}{Added eqAppAlert}
%    \begin{macrocode}
var _mto;
function eqAppAlert(args) {
    _ModalNotOn = false;
    var retn=app.alert(args);
    _mto= app.setTimeOut("_ModalNotOn = true", 100);
%    \end{macrocode}
%    Add a return to eqAppAlert, needed for the prompt button
%    \changes{v7.8d}{2017/01/11}{Add a return to eqAppAlert}
%    \begin{macrocode}
    return retn;
}
%    \end{macrocode}
% Description: Checks for balanced grouping delimiters.
% Arguments:
%\begin{enumerate}
%   \item \texttt{UserInput}: A string
%   \item \texttt{lDelimiter}: left delimiter
%   \item \texttt{rDelimiter}: right delimiter
%\end{enumerate}
% Returns: \texttt{true} (if balanced); \texttt{false} (if not)
%    \begin{macrocode}
function CkBalP(UserInput,lDelimiter,rDelimiter)
{
    var Lcount=0, Rcount=0;
    for (var k=0; k < UserInput.length; k++)
    {
        if (UserInput.charAt(k) == lDelimiter) Lcount++;
        else if (UserInput.charAt(k) == rDelimiter) Rcount++;
    }
    return (Lcount==Rcount);
}
%    \end{macrocode}
% Description: This function simply determines if there are an even number of
% `\verb+|+' chars.  Used for parsing absolute value.
% \verb=| x+2 | --> abs(x+2)=.\\
% Arguments:\\
%   \texttt{UserInput}: a string\\
%   Returns: \texttt{true} (if even); \texttt{false} (if odd)
%    \begin{macrocode}
function CkBalVert(UserInput)
{
    var Lcount=0;
    for (var k=0; k < UserInput.length; k++)
        if (UserInput.charAt(k)=="|") Lcount++;
    return (Lcount \% 2 == 0);
}
%    \end{macrocode}
% Description: This function searches for alpha words and matches them against supported
% mathematical functions.\\
% Arguments:\\
%   \texttt{UserInput}: a string\\
%   Returns: 1 (if there is a match); 0 (if no match)
%       also sets the global variable \texttt{ok2Continue} to \texttt{false}.
% \changes{v6.4c}{2011/07/01}{Ckfunc now uses a global variable \string\texttt{\_mathVars} which
% holds the variables of the current \string\cs{RespBoxMath} being processed. We search
% all substrings containing 2 or more letters; if it consists only of the variables
% that substring is OK.}
%    \begin{macrocode}
function Ckfuncs(UserInput)
{
    var re, rei, reii;
    re = /[a-zA-Z]{2,}/g;
    reii=/r:|i:|,/g
%    \end{macrocode}
% Get \texttt{\_mathVars}, and remove special formatting, new variable \texttt{\_v}.
%    \begin{macrocode}
    var _v=_mathVars.replace(reii,"");
%    \end{macrocode}
% Define a regular expression that will return null if the string
% contains only letters from the variable list \texttt{\_v}.
%    \begin{macrocode}
	rei=new RegExp("[^"+_v+"]", "g");
    aF = UserInput.match(re);
    if ( aF == null ) return true;
    for (var i=0; i < aF.length; i++)
    {
%    \end{macrocode}
% If the current string contains only variables, move on to the next string
%    \begin{macrocode}
		if ( rei.exec(aF[i]) == null ) continue;
        for(var j=0; j < JSf.length; j++)
            if ( aF[i].indexOf(JSf[j]) != -1 ) break;
        if (j < JSf.length) continue;
        for(var j=0; j < JSc.length; j++)
            if ( aF[i].indexOf(JSc[j]) != -1 ) break;
        if(j==JSc.length)
        {
            eqAppAlert(\eqerrBadMathFunc,3);
%    \end{macrocode}
% 09/07/09 added the next line, this could change behavior. We try to signal
% that an alert box has already been displayed, don't display another one.
%    \begin{macrocode}
            ok2Continue=false;
            return false;
        }
    }
    return true;
}
%    \end{macrocode}
% This function displays the answer.
%    \begin{macrocode}
function DisplayAnswer(fieldname,theanswer)
{
    ProcessIt = false;
    var oDefault;
    if (arguments.length > 2 )
        var oQName = arguments[2];
    else var oQName = oDefault;
    if (typeof oQName=="undefined")
        var oQName = new Object;
    var defaultColor=(typeof oQName.DefaultColorJSLoc=="undefined")%
?\defaultColorJS:oQName.DefaultColorJSLoc;
    try { this.getField(fieldname).value=(theanswer); } catch(e) {}
    ProcessIt = true;
}
function EvalCorrAnsButton(fieldname,theanswer)
{
    theanswer = eval(theanswer);
    DisplayAnswer(fieldname,theanswer);
}
%    \end{macrocode}
% Finds and returns the position of the matching parentheses.
%    \begin{macrocode}
function FindBalP(UserInput,Poff,Forward)
{
    var j,depth;
    if (Forward)
    {
        for (depth=-1, j=Poff+1; depth !=0; j++)
        {
            if ( j > UserInput.length) return null;
            if (UserInput.charAt(j)=="\(") depth--;
            else if (UserInput.charAt(j)=="\)") depth++;
        }
        j--
    }
    else
    {
        for (depth=-1, j=Poff-1; depth !=0; j--)
        {
            if ( j < 1 ) return null;
            if (UserInput.charAt(j)=="\)") depth--;
            else if (UserInput.charAt(j)=="\(") depth++;
        }
        j++
    }
    return j;
}
%    \end{macrocode}
% Remove white spaces from \texttt{UserInput}.
%    \begin{macrocode}
function stripWhiteSpace (UserInput)
{
    UserInput = UserInput.replace(/\s/g,"");
    if(UserInput==null || UserInput.length==0)
    {
        ok2Continue = false;
        return false;
    } else return UserInput;
}
function stripOutMuli (UserInput)
{
    UserInput = UserInput.replace(/\*/g,"");
    return UserInput;
}
%    \end{macrocode}
% This function takes its argument, and adds in the suffix of \texttt{Math.}
% in front of every recognizable JS built-in functions.
%    \begin{macrocode}
function addMathObject(UserInput)
{
    for ( var i=0; i < JSfBuiltIn.length; i++) {
        var re = new RegExp("\\b("+JSfBuiltIn[i]+")\\b","g");
        UserInput = UserInput.replace(re,"Math.$1");
    }
    re = /\b(PI)\b/g;
    UserInput = UserInput.replace(re,"Math.$1");
    return UserInput;
}
%    \end{macrocode}
%
% \paragraph{ParseInput.}
%
% This is the very heart of parsing the user's input.  This function takes the
% \texttt{UserInput} and works it over and places it in a proper JavaScript expression
% for the JavaScript interpreter to evaluate.
%
% First get rid of all whitespace. Then
% check for balanced parentheses followed by checking for known
% or unknown math functions.
%
% The power function is \texttt{pow}; thus, |x^2| is \texttt{pow(x,2)}. Rather than
% make students write \texttt{pow(x,2)} we try to code things so they can enter
% |x^2| instead, much easier for them.  Now we must scan through for different
% patterns. The patterns are: |x^n|, |(expr)^n|, |x^(expr)| and |(expr1)^(expr1)|. We
% search through looking for these patterns and replace them appropriately:
% |pow(x,n)|, |pow(expr,n)|, |pow(x,expr)| and |pow (expr1,expr2)|. To do this, we
% must find balanced parentheses.
%
% For those who have Acrobat 5.0, you can call this function from the console, something
% I do quite a lot when developing new scripts. From the console, enter, for example,
% \verb+ParseInput("xycos(xy^3)")+, and the return value of this function will be
% displayed in the console.  An author can check the syntax of his/her answer.
%
%    \begin{macrocode}
function ParseInput(UserInput)
{
    var re, repi;
%    \end{macrocode}
%    When `a' is a variable, and the user types in `a cos(x)', exerquiz eventually removes spaces and this
%    becomes `acos(x)', which is not is wanted. Early on, we replace `a' with `(a)' so it is interpreted as
%    a factor: `a cos(x) becomes `(a) cos(x)', which when spaces are stripped out, becomes `(a)cos(x)'.
%    \changes{v8.1b}{2017/09/06}{Enclosed literal `a' in parentheses to disambiguate `a cos' from `acos'.}
%    \begin{macrocode}
    re = /\b(a)\b/g;
    UserInput = UserInput.replace(re, "(a)");
    UserInput = stripWhiteSpace (UserInput);
    if (!ok2Continue) return null;
%    \end{macrocode}
% See if there are matching `\texttt{[]}', `\verb~{}~' and `\texttt{()}'.
%    \begin{macrocode}
    for(var i=0; i< aGroup.length; i++)
    {
        if(!CkBalP(UserInput, aGroup[i][0], aGroup[i][1]))
        {
            eqAppAlert(\eqerrDelimNotBal,3);
            ok2Continue = false;
            return false;
        }
    }
%    \end{macrocode}
% Replace `\texttt{[]}' and `\verb~{}~' with `\texttt{()}'; only parentheses
% are used in JavaScript for grouping.
%    \begin{macrocode}
    UserInput = ChngAllGrpsToParens(UserInput);
%    \end{macrocode}
% If the \texttt{fact} function is defined, we attempt to replace user's input of the form
% \texttt{<number>!} with \texttt{fact(<number>)}.
%    \begin{macrocode}
    if ( replaceExclaim &&(typeof fact == "function") )
        UserInput = UserInput.replace(%
/(?=\()?(\d+)(?=\))?!/g,"fact($1)");
%    \end{macrocode}
% Check to see if there are an even number of absolute value symbols, `\verb+|+'.
%    \begin{macrocode}
    if (!CkBalVert(UserInput))
    {
        eqAppAlert(\eqerrABS,3);
        ok2Continue = false;
        return false;
    }
%    \end{macrocode}
% 07/07/08 Before we go further, find all occurrences of the JavaScript function,
% and enclose each in parentheses. This helps with some of the exponential parsing
% later. Things of the form \verb!sin^2(x)! will not be enclosed, but will be
% if the \texttt{ImplMulti} option is used.
%    \begin{macrocode}
    UserInput=groupJSf(UserInput);
%    \end{macrocode}
% (01/09/10) We try to identify an expression of the form \verb!e^!, when preceded by a
% letter or number, in this case we assume multiplication. We also look for
% the letter \texttt{e} when it is not in the middle of \texttt{sec}, this interpreted
% as a numerical constant, it is converted to \verb!(e^1)!.
%    \begin{macrocode}
    re=/(\w)(e)(\^)/g;
    repi=/(\w)(pi)/g;
%    \end{macrocode}
% If its a word followed by e, followed by the exponent symbol (\verb!^!), it is
% multiplication.
%    \begin{macrocode}
    UserInput=UserInput.replace(re, "$1*$2$3");
    UserInput=UserInput.replace(repi, "$1*$2");
%    UserInput=UserInput.replace(repE, "$1*$2");
%    \end{macrocode}
% We mark \texttt{sec} so we don't get a hit on the next search.
%    \begin{macrocode}
    UserInput=UserInput.replace(/(sec)/g, "s@e@c");
    re=/(\w)(e)([^\^])?/g;
%    \end{macrocode}
% If its a word, followed by e, followed by something other than \verb!^!
% then e must be used in the sense of a constant, so we replace it by
% \verb!(e^1)!, so subsequence searches within this function will ultimately
% convert it to \texttt{pow(e,1)}.
% multiplication.
%    \begin{macrocode}
    UserInput=UserInput.replace(re,"$1($2\^1)$3");
    UserInput=UserInput.replace(/(s@e@c)/g, "sec");
%    \end{macrocode}
% (07/16/11) In support of scientific notation. It is desirable to support E4, for example.
% So we search for any occurrence of  \texttt{E\cs{d}} and replace with \texttt{E+\cs{d}}.
% Note: the letters \texttt{E} and \texttt{e} are used in JS to represent floating point numbers.
% In this package \texttt{e} will be used for the natural number. Another problem,
% JavaScript does not compute something like \texttt{1*E+2}, so we must remove any \texttt{*} between
% the digit previous to \texttt{E} and \texttt{E}.
%    \begin{macrocode}
    re=/E(\d)/g;
    UserInput=UserInput.replace(re,"E+$1");
    re=/(\d)\*E/g;
    UserInput=UserInput.replace(re,"$1E");
%    \end{macrocode}
% We make a rough check of the user input, if it has alpha-words of size two or greater
% that do not match up against a recognizable function, it must be an error.
%    \begin{macrocode}
    if(!Ckfuncs(UserInput)) return false;
%    \end{macrocode}
% Now try to insert the multiplication operator where applicable.
%    \begin{macrocode}
    if (typeof(Ck4Exponents) != "undefined")
        UserInput = Ck4Exponents(UserInput);
    if (typeof(Ck4Products) != "undefined" )
        UserInput = Ck4Products(UserInput);
    ok2Continue = true;
%    \end{macrocode}
% Convert any occurrence of log to log10 (known internally as logc). We are now (12/22/06) going to use log for
% common log even though log in JS is natural log. This may break a few things.
% \changes{v6.05f}{2006/12/22 }
% {
%   Added support for common logarithms.  log is now common logs, and ln is
%   natural logs.
% }
%    \begin{macrocode}
    re = /\b(log)\b/g;
    UserInput = UserInput.replace(re, "logc");
%    \end{macrocode}
% Search for occurrences of \verb!|<exp>|! and replace with \texttt{abs(<exp>)}.
%    \begin{macrocode}
    while (/\|/.test(UserInput)&&(ok2Continue))
    {
        re = /(\|)([^\|]*)(\|)([-\+\/\*\^\)\|])/;
        if (re.test(UserInput))
            if (re.exec(UserInput)[4] == '^')
                UserInput = UserInput.replace(re, "(abs($2))$4");
            else
                UserInput = UserInput.replace(re, "abs($2)$4");
        else
        {
            re = /(\|)([^\|]*)(\|$)/;
            if (re.test(UserInput))
                UserInput = UserInput.replace(re, "abs($2)");
        }
    }
%    \end{macrocode}
% Replace every instance of \texttt{pi} with \texttt{(pi)} so things like
% \verb!pi^2! are parsed correctly.
%    \begin{macrocode}
    re=/\b(pi)\b/g;
    UserInput=UserInput.replace(re,"($1)")
%    \end{macrocode}
% We now begin our search for exponents, we search the UserInput from left to right
% for any of the four strings \texttt{"\string^"},\texttt{")\string^"}, \texttt{"\string^("}, and
% \texttt{")\string^("}, using the regular expression \texttt{reTstExp}. (07/07/08) I've rewritten
% this part of the parser to accommodate nested exponents of the form \verb!x^2^3!, which should
% be interpreted as \verb!(x^2)^2!, something like \verb!2^sin(x)! and \verb!sin(x)^2! work, the latter
% is interpreted as \verb!(sin(x))^2!. This is why earlier we executed \texttt{groupJSf} to enclose
% all JS function and their arguments in parentheses; by the time \verb!sin(x)^2! reaches this parser
% it has already been changed to \verb!(sin(x))^2!, which is correct syntax.
%
% These is another change to the parser here. We pass through \texttt{Ck4OddRoots}, which tries,
% in a crude way, to determine if this exponent is of the form \texttt{a/b}, and if so, whether
% \texttt{b}, the denominator, is an odd root. If so, we change the calculation of \texttt{Math.pow}
% to avoid a calculation bug by that JavaScript function.
%    \begin{macrocode}
    var reTstExp = /(\))?\^(\()?/g;
    while ( ((aResults=reTstExp.exec(UserInput))!=null)&&(ok2Continue) )
    {
        var firstGroup = Number(Boolean(aResults[1]));      // 0 or 1
        var secondGroup = 2*Number(Boolean(aResults[2]));   // 0 or 2
        var caseStudy = firstGroup+secondGroup;             // 0,1,2,3
        switch(caseStudy) {
            case 0:
                re=/([a-zA-Z]|\d*\.?\d*)\^([a-zA-Z]|[\+-]?\d+\.?\d*|%
[\+-]?\d*\.?\d+)/;
                if (re.test(UserInput))
                    UserInput=Ck4OddRoots(UserInput,re);
                else ok2Continue=false;
                break;
            case 1:
                aP =/\)\^/.exec(UserInput);
                LeftP=FindBalP(UserInput,aP.index,0);
                re = new RegExp("\\((.{"+eval(aP.index-LeftP-1)
                    +"})\\)\\^([a-zA-Z]|[\+-]?\\d+\\.?\\d*|%
[\+-]?\\d*\\.?\\d+)");
                if (re.test(UserInput))
                    UserInput=Ck4OddRoots(UserInput,re);
                else ok2Continue=false;
                break;
            case 2:
                aP = /\^\(/.exec(UserInput);
                RightP=FindBalP(UserInput,aP.index+1,1);
                re = new RegExp("([a-zA-Z]|\\d*\\.?\\d*)\\^\\((.{"
                    +eval(RightP-aP.index-2)+"})\\)");
                if (re.test(UserInput))
                    UserInput=Ck4OddRoots(UserInput,re);
                else ok2Continue=false;
                break;
            case 3:
                aP = /\)\^\(/.exec(UserInput);
                LeftP=FindBalP(UserInput,aP.index,0);
                RightP=FindBalP(UserInput,aP.index+2,1);
                re = new RegExp("\\((.{"+eval(aP.index-LeftP-1)
                    +"})\\)\\^\\((.{"+eval(RightP-aP.index-3)+"})\\)");
                if (re.test(UserInput))
                    UserInput=Ck4OddRoots(UserInput,re);
                else ok2Continue=false;
                break;
            default:
                ok2Continue=false;
        }
    }
    if (!ok2Continue)
    {
        eqAppAlert(\eqerrBadExp,3);
        return false;
    } else {
%    \end{macrocode}
%(2007/02/23) Just before we return the parsed expression, we append all built-in
% JavaScript functions and constants with \texttt{Math.}, this is to avoid
% having to use the \texttt{with(Math)} construct.
%\changes{v6.06}{2007/02/23}{%
% Now, just before we return the parsed expression, we append all built-in
% JavaScript functions and constants with \string\texttt{Math.}, this is to avoid
% having to use the \string\texttt{with(Math)} construct. These changes are in support
% of using scientific notation.}
%    \begin{macrocode}
        UserInput=addMathObject(UserInput);
        return UserInput;
    }
}
%    \end{macrocode}
% \DescribeMacro{ChngAllGrpsToParens}(2011/10/04) Separated out the routine to replace `\texttt{[}' and `\verb!{!' with
% `\texttt{(}'.
%    \begin{macrocode}
function ChngAllGrpsToParens(UserInput)
{
    UserInput = UserInput.replace(/\[|\{/g, "\(");
    UserInput = UserInput.replace(/\]|\}/g, "\)");
    return UserInput;
}
%    \end{macrocode}
% \DescribeMacro{Ck4OddRoots}The \texttt{Ck4OddRoots} function looks for exponents of the form \texttt{a/b},
% it checks whether \texttt{b} is an odd integer, if yes, instead of returning
% the usual of \verb!"(pow($1,$2))"!, it returns something like
% \verb!(sgn(<base>)^a*(abs(<base>)^a)^(1/b))!. This gives a base that evaluates
% to a negative number a change of being evaluated, and avoid a bug in the \texttt{Math.pow}
% function.
%    \begin{macrocode}
function Ck4OddRoots(UserInput,re) {
    var a=re.exec(UserInput);
%    \end{macrocode}
% \texttt{a[2]} should be the exponent
% try to remove extraneous parentheses
%    \begin{macrocode}
    while ( a[2].charAt(0)=="\(") {
        var RightP=FindBalP(a[2],0,1); // forward search
        if (RightP == a[2].length-1)
            a[2]=a[2].substring(1,a[2].length-1);
        else break;
    }
    var b=a[2].split("/");
%    \end{macrocode}
% We are looking for an exponent of the form a/b, if we can't find it
% we process this power in the usual way. \texttt{b[0]} is our possible numerator
% and \texttt{b[1]} is our possible denominator.
%    \begin{macrocode}
    if ( b.length==2 ) {
        try { _m=eval(b[1])
%    \end{macrocode}
% We try to evaluate the denominator \texttt{b[1]}. If there are unbalanced
% parentheses, JavaScript will throw an exception, if \texttt{\_m} is either
% undefined or not a number, we throw an exception. The expression will be
% processed in the usual way.
%    \begin{macrocode}
            if ( _m == undefined || isNaN(_m) ) throw new Error();
%    \end{macrocode}
% The denominator appears to be numerical, so we'll continue
%    \begin{macrocode}
            var d = b[1];
%    \end{macrocode}
% Check for the presence of enclosing parentheses
%    \begin{macrocode}
    var isEnclosed=(d.charAt(0) == "\(" && d.charAt(d.length-1)=="\)");
%    \end{macrocode}
% if not enclosed look for arithmetic operations
%    \begin{macrocode}
    if (!isEnclosed)
%    \end{macrocode}
% if arithmetic operations of add/sub found, exit. In this case, perhaps the user had an
% exponent of the form \texttt{x/2 + 3}, and so \texttt{d = 2 + 3}, which is not the desired denominator.
% We'll throw an exception, and process as usual.
%    \begin{macrocode}
        if (/.+[\+\-].+/.test(d)) throw new Error();
%    \end{macrocode}
% remove enclosing parentheses
%    \begin{macrocode}
    if (isEnclosed) d = s.substring(1,d.length-1);
%    \end{macrocode}
% now need to do the same thing for the numerator
%    \begin{macrocode}
    var n = b[0];
    isEnclosed=(n.charAt(0) == "\(" && n.charAt(d.length-1)=="\)");
    if (!isEnclosed)
%    \end{macrocode}
% if arithmetic operations of add/sub found, exit. If numerator was not enclosed
% in parentheses, and there is either addition or subtraction, we are looking
% at an exponent of the form \texttt{1 + x/d,} and \texttt{n = 1 + x}. The numerator is not \texttt{1+x}, we
% process in the usual way.
%    \begin{macrocode}
            if (/.+[\+\-].+/.test(n)) throw new Error();
%    \end{macrocode}
% I don't think we need to remove the enclosing parentheses
% as we did for the denominator.
%
% Now check if the denominator, \texttt{d}, is an integer, for that we'll use \texttt{parseInt},
% If it is an integer, we see if it is odd or even using \verb!d % 2!, which yields
% a nonzero remainder if d is odd. If \texttt{d} passes all tests, we write
% \verb!<base>^(n/d)! as \verb!(sgn(<base>))^n! \verb!(abs(<base>)^(n/d))!.
%    \begin{macrocode}
            if ( d == parseInt(d) && ( Boolean(d \% 2) ) ) {
                UserInput=UserInput.replace(re,
                    "(pow(sgn($1),"+n+")*(pow(abs($1),$2)))");
%    \end{macrocode}
% We we have an odd integer as a denominator, we return our result here
%    \begin{macrocode}
                return UserInput;
            }
%    \end{macrocode}
% All exceptions come here, then continue on to the lines that follow.
%    \begin{macrocode}
        } catch(e) {}
    }
%    \end{macrocode}
% If we don't have an odd integer as a denominator, we return here
%    \begin{macrocode}
    UserInput=UserInput.replace(re,"(pow($1,$2))");
    return UserInput;
}
%    \end{macrocode}
% \DescribeMacro{groupJSf}We enclose all recognizable functions in parentheses. This makes it easier for doing
% exponents, and avoids parsing errors. We look for functions of the form \texttt{fname(..)},
% replace that with \texttt{fname@(..)} to avoid an infinite loop, as we search for the function
% name followed by a left parenthesis. Once finished, we remove the \texttt@ character.
%    \begin{macrocode}
function groupJSf(UserInput)
{
    var re, regexp, aP, RightP;
    for (var i=0; (i<JSf.length) && (ok2Continue); i++)
    {
        re = new RegExp(JSf[i]+"\\\(");
        while ( re.test(UserInput) && (ok2Continue) )
        {
            regexp = new RegExp(JSf[i]+"\\\(", "g");
            if ( (aP = regexp.exec(UserInput)) != null )
            {
                RightP=FindBalP(UserInput,regexp.lastIndex-1,1);
                offsetArg = RightP - regexp.lastIndex;
                regexp = new RegExp(%
"("+JSf[i]+")\\((.{"+offsetArg+"})\\)");
                regexp.lastIndex=0;
                if (regexp.test(UserInput))
                    UserInput=UserInput.replace(regexp,"($1@($2))");
                else ok2Continue=false;
                continue;
            }
        }
    }
%    \end{macrocode}
% Remove the \texttt@ marker, and return.
%    \begin{macrocode}
    UserInput=UserInput.replace(/@/g,"");
    return UserInput;
}
%    \end{macrocode}
% Process the user's response.  Here, we randomly choose, $n$,
% points from the selected interval $[a,b]$. The correct answer (as
% supplied by the author of the document and the answer provided by
% the user are evaluated at each of the $n$ points. If any of the
% evaluations differs by more than \texttt{epsilon}, the answer is
% considered wrong.
%
% The idea for evaluating user input in this way comes from  Drs.\
% Wlodzimierz Bryc and Stephan Pelikan of The University of
% Cincinnati.  These two have developed an \texttt{html} based
% \textbf{Online Exercise System} which can  evaluate objective
% type questions. This evaluation, however, takes place on the
% \emph{server-side}. This implementation is on \emph{the client-side}.
%
%    \begin{macro}{TypeParameters}
% The argument \texttt{v} is either a comma delimited list of variables \texttt{"x,y,z"} or just a list \texttt{"xyz"}.
% This function types each untyped variable that is not typed. Currently, there
% are only two data types: \texttt{"r"} and \texttt{"i"}.  \texttt{"r:x"} means \texttt{"x"} is a real variable,
% \texttt{"i:x"} means \texttt{"x"} is an integer variable.
%    \begin{macrocode}
function TypeParameters(v)
{
    var aV;
%    \end{macrocode}
% If \texttt{v} has a colon in it, we take that as a signal that the variables are comma
% delimited.
%    \begin{macrocode}
    aV = ( (v.indexOf(":") == -1) && (v.indexOf(",") == -1) ) ?
        v.split("") : v.split(",");
    for ( var i=0; i < aV.length; i++)
        if ( aV[i].indexOf(":") == -1 ) aV[i] = "r:"+aV[i];
    return aV.join(",")
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{ProcResp}
% This function handles numerical answers or function of a single variable, x,
% that evaluate to a number
%    \begin{macrocode}
function ProcResp(flag,CorrAns,n,epsilon,domain,indepVars,oComp)
{
    if (!ProcessIt) return null;
    var fieldname = event.target.name;
    var bSubstVars=(arguments.length>7); // dps17
%    \end{macrocode}
%     The introduction of multi-letter variables, necessitates a slight revision of the JavaScript function
%     \texttt{ProcResp()}. This fundamental function, changes to this function must be propagated
%     to \pkg{dljslib} to all `proc resp' function.
%    \begin{macrocode}
    var UserAns=(arguments.length>7)?arguments[7]:event.value;
    var success = _ProcResp(flag,CorrAns,UserAns,%
n,epsilon,domain,indepVars,oComp);
%    \end{macrocode}
% 09/07/09 Added next line to avoid double alert boxes
%    \begin{macrocode}
    if ( success == -1 || !ok2Continue )
      { resetHeadsUp(flag,fieldname); return null; } // dps17
    if ( success == null )
      { resetHeadsUp(flag,fieldname);
        return syntaxError(), null; } // dps17
    return notifyField(success, flag, fieldname);
}
// changed name of var comp -> oComp
function _ProcResp(flag,CorrAns,UserAns,n,epsilon,domain,%
indepVars,oComp){
    ok2Continue = true;
%    \end{macrocode}
% by preprocessing.
%    \begin{macrocode}
    CorrAns = ParseInput(CorrAns);
    if (!ok2Continue) {
        eqAppAlert("Syntax error in author's answer! Check console.",3);
        return null;
    }
%    \end{macrocode}
% If \texttt{oComp} is an object, then see if it has a \texttt{comp} property
%    \begin{macrocode}
    var comp = ( typeof oComp == "object" ) ?
        ((typeof oComp.comp == "undefined" ) ?
            diffCompare : oComp.comp ) : oComp;
%    \end{macrocode}
% \paragraph*{priorParse} The \texttt{comp} parameter, which has been changed to \texttt{oComp}, can now be
% an object. One property of this object is \texttt{comp}, handled above. Another
% property is \texttt{priorParse}, this is a function that returns \texttt{null}
% or \texttt{true}. This \texttt{priorParse} function allows for additional
% filtering of the \texttt{UserAns} before parsing. If it returns \texttt{true},
% we are ok to continue, if \texttt{null}, we don't like something the user has entered,
% and ask him/her to change it.
%    \begin{macrocode}
    if ( (typeof(oComp)=="object") %
&& (typeof(oComp.priorParse)!="undefined") ) {
        var retn=processSpecialParse(oComp.priorParse,UserAns);
        if (retn==null) return -1;
    }
%    \end{macrocode}
% (2014/01/22) Before we solve Bruce's problem with the commas, we need to allow for the use of
% the combinatorics functions \texttt{C(x,y)} and \texttt{P(x,y)}.
%    \begin{macrocode}
    var reCP=/((C|P)\(.+?)(,)(.+?\))/g
    UserAns=UserAns.replace(reCP,"$1@c@$4");
%    \end{macrocode}
% (2012/04/13) Bruce Wagner reports a problem with the user enters an answer containing
% a comma \texttt{"3,2"}, if the correct answer is 2, exerquiz marks the response as correct
% even though the user has also entered a 3. The comma operator in JS, evaluates its operands
% one to the left, one to the right, and returns the value of the one on the right. To fix
% this problem, we scan the \texttt{UserAns} for a comma (,) and set an alert if one is found.
%
% For vector- and list-valued answers, the \texttt{ProcResp<name>} procedure should parse
% the comma-delimited answers and call \texttt{\_ProcResp} once for each answer in the list
% so there should be no problem with commas in that regard.
% \changes{v6.4r}{2012/04/13}{Added a warning about commas in an answer.}
%    \begin{macrocode}
    var reComma=/,/;
    if ( reComma.test(UserAns) ) {
        eqAppAlert(\eqSyntaxErrorComma,3);
        return -1;
    }
%    \end{macrocode}
%    \begin{macrocode}
     var reRlCommaSubst=/@c@/g;
     UserAns=UserAns.replace(reRlCommaSubst,",");
%    \end{macrocode}
% Parse the user's input.
%    \begin{macrocode}
    UserAns = ParseInput(UserAns);
%    \end{macrocode}
% Originally, the value of \texttt{indepVars} is a string of variables \texttt{"xyz"}. You can
% now have variables of the form \texttt{"r:x,i:n,r:y"}. Where the identifier \texttt{"r:"} indicates a
% real variable and \texttt{"i:"} indicates an integer variable. \texttt{indepVars} must be either
% of the old style, or the new style, not a mixture of both, e.g. \texttt{"xyi:n"}.
%    \begin{macrocode}
    indepVars = TypeParameters(indepVars);
    if (!ok2Continue) return null;
    var success=randomPointCompare(n,domain,indepVars,%
epsilon,CorrAns,UserAns,comp);
%    \end{macrocode}
% \paragraph*{postParse} (2011/10/05) The beginning of an idea, \texttt{postParse}. After it is determined
% whether the answer is right or wrong, post-process it here. For example,
% if the problem is to extract all roots of $\sqrt{72}$, the correct answer
% is $6\sqrt{2}$, whereas $3\sqrt{8}$ is not correct though it is equal to
% $\sqrt{72}$
%    \begin{macrocode}
        if ( success && (typeof(oComp)=="object") %
&& (typeof(oComp.postParse)!="undefined") )
        success=processSpecialParse(oComp.postParse,UserAns);
    return success;
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
function processSpecialParse(oParse,UserAns) {
    var retn, f, _o
    if ( typeof(oParse) == "object" ) {
        for ( var i=0; i < oParse.length; i++) {
            _o=oParse[i];
            if (typeof(_o)=="function") {
%    \end{macrocode}
% If \texttt{oParse} is an object (it should be an array), and the first entry is a function
% then we have: \texttt{priorParse:\,[myfunction, optional arguments]}. The function is
% evaluated with the args \texttt{(UserAns, optional args)}. In the code below, we remove
% the name of the function at the beginning of the array, and insert the \texttt{UserAns}
% in its place. Various syntax variations supported.
%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
%commandchars={!()},codes={\catcode`\%=9}]
%priorParse: nodec,
%priorParse: [nodec,noBinFac],
%priorParse: [nodec,noBinFac,[myFunc,arg1, arg2,..]],
%\end{Verbatim}
%    \begin{macrocode}
               retn=_o(UserAns);
               if (retn==null) return retn;
%    \end{macrocode}
% In this case, we break out of the loop, we don't expect any more properties
% for \texttt{priorParse} or \texttt{postParse}.
%    \begin{macrocode}
            } else {
%    \end{macrocode}
% If \texttt{oComp.priorParse[i]} is not a function, it is required to be an array. The first
% element of the array is the function, the rest of the entries are the additional arguments
% (in addition to \texttt{UserAns}).
%    \begin{macrocode}
               retn=_o[0].apply(null, [ UserAns ].concat(_o.slice(1)));
               if (retn==null) return null;
            }
        }
    } else {
%    \end{macrocode}
% The case where \texttt{preParse: myfunction} or \texttt{postParse: myfunction}.
% Such a function is evaluated with the \texttt{UserAns} argument.
%    \begin{macrocode}
        retn = oParse(UserAns);
    }
    return retn;
}
%    \end{macrocode}
% This function randomly selects points from the interval [a,b]
% and calls the 'comp' function to compare results.
% Returns: null if the expression is bad, no penalty.
%          true if the error of the random comparison is less than epsilon
%          false if the error of the random comparison is greater than epsilon
%    \begin{macrocode}
function randomPointCompare (n,domain,indepVars,epsilon,%
CorrAns,userAns,comp)
{
    var error, i, j, k;
    var aXY = new Array();
    domain = domain.replace(/[\[\]\s]/g, "");
    var aIntervals = domain.split("&");
    for (k=0; k < aIntervals.length; k++)
    {
        var aInterval = aIntervals[k].split("x");
        nI = aInterval.length;
        with (Math) {
            for (j=0; j < n; j++)
            {
                for (i=0; i < nI; i++)
                {
                    var endpoints = aInterval[i].split(",");
                    aXY[i] = eval(endpoints[0])-0+(eval(endpoints[1])%
-eval(endpoints[0]))*Math.random();
                }
                var cXY = aXY.toString();
                error = comp(domain,cXY,indepVars,CorrAns,userAns);
                if (error == null) return null;
                if ( (error == -1) || (error > epsilon) ) {j=-1; break;}
            }
        }
        if (j!=n) return false;
    }
    return true;
}
%    \end{macrocode}
% \texttt{diffCompare}: A simple comparison function, we evaluate the two input function `\texttt{\_F}'
% and `\texttt{\_G}' and the point `\texttt{\_c}' and return the absolute difference.
%
% Returns: Absolute difference between `\texttt{\_F}' and `\texttt{\_G}'
%          null if expression was not valid
%          -1 if expression is not a number
%    \begin{macrocode}
var ckDZRe=/\b([^0-9]*)(\d*)\./g;
function ckDZReRepl(match,a,b,offset,string){
  if (b[0]!="0") return match;
  else return util.printf(a+"\%d.",b);
}
function diffCompare(_a,_c,_v,_F,_G) {
    var aXY = _c.split(",");
    var _V = _v.split(",");  // e.g. _V[0] = "i:x"
    var _n = aXY.length;
%    \end{macrocode}
% For each of the independent variables, we set them equal to a randomly chosen value
% from the specified interval.
%    \begin{macrocode}
    for (var _i=0; _i < _n; _i++)
    {
        if (_V[_i].charAt(0) == "r" )
          eval ("var "+_V[_i].charAt(2)+"="+aXY[_i]+";");
        else // assume type "i"
          eval ("var "+_V[_i].charAt(2)+"="+Math.ceil(aXY[_i])+";");
    }
%    \end{macrocode}
% The \texttt{\_F} is the author's answer, we assume this is  well formed JavaScript
% and do not test it for possible errors. The author can correct before s/he distributes
% the document.
%    \begin{macrocode}
    _F = eval(_F);
%    \end{macrocode}
% Now we try to protect our code from bad input. We use \texttt{try/catch} to try and
% thrown exceptions. However, \texttt{try/catch} is not valid in any version of the
% Acrobat Reader prior to version 5.
%    \begin{macrocode}
    if ( app.viewerVersion >= 5)
    {
%    \end{macrocode}
% This code, which uses \texttt{eval()} and \texttt{try/catch} is an attempt to write
% code that both works for Acro5 (or higher) and Acro4.05/4.0.  In Acro4.x, \texttt{try/catch}
% are reserved words, so we can't use them even in a conditional. However, within a string
% the JavaScript interpreter does not see them. The other complication is that Acro5 objects
% to having a \texttt{return} within an \texttt{eval()}, so we work around that with a
% \texttt{rtnCode}. The returns are executed outside the \texttt{eval()}.
% \changes{v8.7.4}{2021/05/03}{Changed logic in \string\texttt{diffCompare()} function}
%    \begin{macrocode}
        var rtnCode = 0;
%    \end{macrocode}
%    JavaScript has problems with numbers that are not properly written.
%    If a number has a decimal point, the integer part of the decimal must be blank, a zero (0),
%    or must begin with a non-zero number. In the \texttt{String.replace()} method below,
%    the regular expression \texttt{ckDZRe} identifies leading digits, and the function
%    \texttt{ckDZReRepl} is a replacement function that implements the requirements described above.
%    The same changes is made in \texttt{reldiffCompare()} below.
%    \begin{macrocode}
        _G=_G.replace(ckDZRe,ckDZReRepl);
        eval("try {if(isNaN(_G = eval(_G))) rtnCode=-1; }"
            +"catch (e) { rtnCode=1; }");
%    \end{macrocode}
%Below is the code removed on 2021/05/01 for the above two lines. When |_G="00.00"|, for example.
%and |ifNaN(_G = eval(_G))| is executed, a exception is thrown and \texttt{null} is returned;
%even though the string does evaluate to a number, but JavaScript does not recognize it as such.
%As a result, we try an alternate strategy. The same change is made in the function
%\texttt{reldiffCompare()}, below.
%\begin{Verbatim}[xleftmargin=\parindent,codes={\catcode`\%=9}]
%eval("try {if(isNaN(_G = eval(_G))) rtnCode=-1; }"
%  +"catch (e) { rtnCode=1; }");
%\end{Verbatim}
%    \begin{macrocode}
        switch(rtnCode)
        {
            case  0: break;
            case  1: return null;
            case -1: return -1;
        }
    }
    else
%    \end{macrocode}
% For Acro4/4.05, all we can do is detect whether \texttt{\_G} is a number or not. If the user
% enters an undefined symbol, for example, we cannot catch this as we can with Acro5. Oh, well.
%    \begin{macrocode}
        if(isNaN(_G = eval(_G))) return -1;
%    \end{macrocode}
%
% The function \texttt{G} is the user's input expression. There may be syntax errors
% that prevent the successful numerical evaluation of the expression. We try to
% prevent problems.
%
% If the user enters a function such as \texttt{sqrt( 1 - x )}, and this function is
% evaluated at a x = 2, for example, we are outside the domain of the function. The \texttt{isNaN}
% function will catch this type of error.  A return of \texttt{-1} signals an error
% at this of this type. This is considered to be an error by the user, and will be scored as an
% incorrect answer.
%
% The error described above does not throw an exception. What will throw an exception
% is if the users function has some undefined variables in it. For example, suppose
% we are expecting a response that is a function of \texttt{x} and the user enters a
% function of \texttt{t} instead. This will throw an exception as \texttt{t} is undefined.
% In this case, we do not treat this as an error, and expect the user to correct the
% input. This kind of error is signaled by returning a \texttt{null}.
%
%    \begin{macrocode}
    return Math.abs ( _F - _G );
}
%    \end{macrocode}
% This function is the same as above, but returns the relative absolute error.
% \changes{v8.7.1}{2021/05/01}{Changed logic in \string\texttt{reldiffCompare()} function}
%    \begin{macrocode}
function reldiffCompare(_a,_c,_v,_F,_G) {
    var aXY = _c.split(",");
    var _V = _v.split(",");  // e.g. _V[0] = "i:x"
    var _n = aXY.length
    for (var _i=0; _i < _n; _i++)
    {
        if (_V[_i].charAt(0) == "r" )
          eval ("var "+_V[_i].charAt(2)+"="+aXY[_i]+";");
        else // assume type "i"
          eval ("var "+_V[_i].charAt(2)+"="+Math.ceil(aXY[_i])+";");
    }
    _F = eval(_F);
    if ( app.viewerVersion >= 5)
    {
        var rtnCode = 0;
        _G=_G.replace(ckDZRe,ckDZReRepl);
        eval("try {if(isNaN(_G = eval(_G))) rtnCode=-1; }"
            +"catch (e) { rtnCode=1; }");
        switch(rtnCode)
        {
            case  0: break;
            case  1: return null;
            case -1: return -1;
        }
    }
    else
        if(isNaN(_G = eval(_G))) return -1;
    return Math.abs ( (_F - _G)/_G );
}
%    \end{macrocode}
% \DescribeMacro{requireForm}(07/16/11) The JS function \texttt{requireForm} is an example of a filter function. It is
% of such a general nature we put it in the \textsf{exerquiz} code, rather than the \textsf{dljslib} code.
% The function takes two or three arguments, the second one is an regular expression or an array
% of regular expressions to test \texttt{UserAns} against. The third, optional argument is a text message to
% be displayed if the \texttt{UserAns} is not of the required form.
%\changes{v6.4f}{2011/07/16}{Added \texttt{requireForm} filtering function}
%\par\medskip\noindent Usage: Factor: $-36z^5 - 96z^4 - 64z^3.$
%\begin{verbatim}
%\RespBoxMath{-4z^3(3z+4)^2}(z)*{3}{.0001}{[0,1]}[ { priorParse:
%    \Array( \Array( requireForm, \Array(%
%        /.*(\refac\repow|\refac\refac)/,%
%        /.*\refac\refac\repow\redigit+/,%
%        /.*\refac\repow\redigit+\refac/,%
%        /.*\refac\refac\refac/%
%        ), \myCustomMsg ) ) }
%    ]\CorrAnsButton{-4z^3(3z+4)^2}
%\end{verbatim}
% where \cs{refac}, \cs{repow}, \cs{redigit}, and \cs{rediv} are convenience macros defined
% earlier in \textsf{exerquiz.dtx}. The regular expression describe the form of the answer
% acceptable.
%
% There seems to be a redundancy in the usage of \cs{Array}, but this is by design.
% The first \cs{Array} is there so the function \texttt{\_ProcResp} does not misinterpret
% the second \cs{Array}.
%    \begin{macrocode}
function requireForm(UserAns, regexpr) {
    var msg=\defaultReqFormMsg;
    UserAns = stripWhiteSpace (UserAns);
    if (!ok2Continue) return null;
%    UserAns = stripOutMuli(UserAns);
    UserAns = ChngAllGrpsToParens(UserAns);
    if (arguments.length>2) msg=arguments[2];
    if (typeof(regexpr.length)=="undefined") {
        if (regexpr.test(UserAns)) return true;
        else { eqAppAlert(msg,3); return null; }
%    \end{macrocode}
% \texttt{regexpr} is an array of regular expressions.
%    \begin{macrocode}
    } else {
        for (var i=0; i<regexpr.length; i++)
            if (regexpr[i].test(UserAns)) break;
        if ( i < regexpr.length ) return true;
        else { eqAppAlert(msg,3); return null; }
    }
}
%    \end{macrocode}
% \DescribeMacro{denyForm}Same type of function as \texttt{requireForm}.
% If the regular expression is found, we return \texttt{null}
% and emit an alert.
%    \begin{macrocode}
function denyForm(UserAns, regexpr) {
    var msg=\defaultReqFormMsg;
    UserAns = stripWhiteSpace (UserAns);
    if (!ok2Continue) return null;
    UserAns = ChngAllGrpsToParens(UserAns);
    if (arguments.length>2) msg=arguments[2];
    if (typeof(regexpr.length)=="undefined") {
        if (regexpr.test(UserAns)) { eqAppAlert(msg,3); return null; }
        else return true;
%    \end{macrocode}
% \texttt{regexpr} is an array of regular expressions.
%    \begin{macrocode}
    } else {
        for (var i=0; i<regexpr.length; i++)
            if (regexpr[i].test(UserAns)) break;
        if ( i < regexpr.length ) { eqAppAlert(msg,3); return null; }
        else return true;
    }
}
%    \end{macrocode}
% \DescribeMacro{requireFormNot} does the opposite of
% \texttt{requireForm}. If the regular expression is found,
% we return \texttt{false}. \texttt{postParse} does not emit any messages.
%    \begin{macrocode}
function requireFormNot(UserAns, regexpr) {
    UserAns = stripWhiteSpace (UserAns);
    if (!ok2Continue) return null;
    UserAns = stripOutMuli(UserAns);
    UserAns = ChngAllGrpsToParens(UserAns);
    if (typeof(regexpr.length)=="undefined") {
%    \end{macrocode}
% If the regular expression is found, we return false
% this is opposite to what \texttt{requireForm} returns
%    \begin{macrocode}
        if (regexpr.test(UserAns)) return false;
        else return true;
%    \end{macrocode}
% \texttt{regexpr} is an array of regular expressions.
%    \begin{macrocode}
    } else {
        for (var i=0; i<regexpr.length; i++)
            if (regexpr[i].test(UserAns)) break;
        if ( i < regexpr.length ) return false;
        else return true;
    }
}
\end{newsegment}
\begin{newsegment}{Eq: Support for multi-letter variables}
if (!String.prototype.trim) {
  String.prototype.trim = function () {
    return this.replace(/^[\s\string\\uFEFF\string\\xA0]+|%
[\s\string\\uFEFF\string\\xA0]+$/g, '');
  };
}
%    \end{macrocode}
%    \makebox[0pt][r]{\texttt{\_rplVarsBy\hskip\marginparsep}}\hskip-\marginparsep\texttt{(str1,str2)}
%    replaces \texttt{str1} by \texttt{str2}; i.e.,
%    |_rplVarsBy('theta','x')|. The first argument is a multi-letter variable,
%    the second is a single letter variable that \pkg{exerquiz} works with directly.
%    \begin{macrocode}
function _rplVarsBy(str1,str2) {
    var re=new RegExp(str1,"g");
    var result=str1.replace(re,str2);
    return result;
}
%    \end{macrocode}
%    \makebox[0pt][r]{\texttt{processMathVars\hskip\marginparsep}}\hskip-\marginparsep\texttt{(str)}
%    searches through \texttt{str} for the string \texttt{\_rplVarsBy}; if found, it gets all string
%    content up to the next \texttt{@} marker. It replaces the multi-letter with single letter and returns
%    the \pkg{exerquiz} single-leter variable list.
%\begin{verbatim}
%   var _substVars="a,_rplVarsBy('omega->\u03C9','y')@";
%   var _mathVars=processMathVars(_substVars);
%   var _substValue=getSubstValue(_substVars,event.value);
%   var _substAns=getSubstValue(_substVars,"a+omega");
%\end{verbatim}
%    \begin{macrocode}
function processMathVars(str) {
  var pos1,pos2,lead,tmp;
  while ((pos1=str.indexOf("_rplVarsBy"))!=-1) {
    pos2=str.indexOf("@");
    lead=str.substring(0,pos1);
    tmp=str.substring(pos1,pos2);
    str=str.substring(pos2+1);
%    \end{macrocode}
%    For example, for |tmp="_rplVarsBy('omega->\u03C9','y')"|, after \texttt{eval(tmp)}, \texttt{tmp} is then
%    \texttt{y}.
%    \begin{macrocode}
    tmp=eval(tmp);
%    \end{macrocode}
%    Combine this new result with the old, for example \texttt{str="a,y"}, for the example above.
%    \begin{macrocode}
    str=lead+tmp+str;
  }
  str=str.replace(/\s/g,"");
  return str;
}
%    \end{macrocode}
%    \makebox[0pt][r]{\texttt{getSubstValue}\hskip\marginparsep}\hskip-\marginparsep\texttt{(v,s)}
%    Below is a two multi-letter variable example:
%\begin{verbatim}
%	var _substVars=
%   "c_rplVarsBy('theta->\u03B8','x')@_rplVarsBy('alpha->\u03B1','y')@";
%	var _mathVars=processMathVars(_substVars);
%	var _substValue=getSubstValue(_substVars,event.value);
%	var _substAns=getSubstValue(_substVars,"-c alpha sin(theta)");
%	var retn=ProcResp(0,_substAns,3,.0001,"[0,1]x[0,1]x[0,1]",%
%   _mathVars,diffCompare,_substValue);
%\end{verbatim}
%The first argument is \texttt{v}, the variable list; it might be \texttt{"xyz"}, or
%if there are substitutions, it might be as above (see \texttt{\_substVars}). The second
%argument is \texttt{s}, the user's answer or the author's answer.
%    \begin{macrocode}
getSubstValue.aSubsts=new Array();
function getSubstValue(v,s){
  var pos1,pos2,tmp,args,re,arg1,arg2;
%    \end{macrocode}
%  Change new style to old.\\
%  \textbf{New style} (commas):\\\null\quad|v="c,_rplVarsBy('theta->\u03B8','r:x')@,%|\\\null\qquad
%|_rplVarsBy('alpha->\u03B1','r:y')@";|\\
%  \textbf{Old style} (no commas):\\\null\quad|v="c_rplVarsBy('theta->\u03B8','x')@%|\\\null\qquad
%|_rplVarsBy('alpha->\u03B1','y')@";|\\
%We want to remove the commas that are \emph{not preceded} by a single quote (\texttt'), as this type
%are inside the argument of \texttt{\_rplVarsBy}. We also remove things like \texttt{r:x}.
%    \begin{macrocode}
  re=/([^'])(,)/g;
  v=v.replace(re,'$1');
  re=/([ri]\string\:)+(\string\w)/g;
  v=v.replace(re,'$2');
%    \end{macrocode}
%  Now, develop an array of all variables and their substitutes.
%  ie,\\|getSubstValue.aSubsts=[ ["theta","\u03B8"],["alpha","\u03B1"],...];|
%    \begin{macrocode}
  getSubstValue.aSubsts=[]; // dps17
  var start=0;
  while (true) {
    v=v.substring(start);
    pos1=v.indexOf("_rplVarsBy");
    if (pos1==-1) break;
    pos2=v.indexOf("@");
    args=v.substring(pos1+10+1,pos2-1);
    tmp=args.split(",");
    arg1=eval(tmp[0].toString());
    tmp1=arg1.split("->");
    for (var i=0; i<tmp1.length; i++)
      tmp1[i]=tmp1[i].trim();
    if (tmp1.length==1) getSubstValue.aSubsts.push(tmp1[0]);
    else getSubstValue.aSubsts.push(tmp1);
    arg2=eval(tmp[1].toString());
    re=new RegExp(tmp1[0],"g");
    s=s.replace(re,arg2);
    start=pos2+1;
  }
  return s;
}
%    \end{macrocode}
%    \makebox[0pt][r]{\texttt{RespBoxAppr}\hskip\marginparsep}\hskip-\marginparsep\texttt{(e)}
%    The variable is either an event object (when called from a format event) or is a string
%    (when called from an Ans button). Assume \texttt{e="-c*alpha*sin(theta)"}.
%    We go through the \texttt{etSubstValue.aSubsts}, and replace each variable
%    developed by \texttt{getSubstValue()} by its substitute variable. Here a lines from
%    an Ans button
%\begin{verbatim}
%		var _substVars="c_rplVarsBy('theta->\u03B8','x')@
%       _rplVarsBy('alpha->\u03B1','y')@";
%		var _substAns=getSubstValue(_substVars,"-c*alpha*sin(theta)");
%		var value=RespBoxAppr("-c*alpha*sin(theta)");
%\end{verbatim}
%We must call \texttt{getSubstValue()} prior to calling this function.
%    \begin{macrocode}
function RespBoxAppr(e){
  var value=(typeof e=="object")?e.value:e;
  var re;
  for (var i=0; i<getSubstValue.aSubsts.length; i++) {
    if (typeof getSubstValue.aSubsts[i]=="object") {
      re=new RegExp(getSubstValue.aSubsts[i][0],"g");
      value=(value.replace(re,getSubstValue.aSubsts[i][1],"g"));
    }
  }
  return value;
}
\end{newsegment}
%    \end{macrocode}
% \subsection{Text Fill-in}
% Now the JS functions that process text fill-in questions.
%    \begin{macrocode}
\begin{newsegment}{Eq: Support Text Fill-in}
%    \end{macrocode}
% This function processes fill-in problems that require only a text
% response. It takes a variable number of arguments, which are retrieved
% using the \texttt{arguments[]} array
%    \begin{macrocode}
function ProcRespTxt() {
    var i, success, authorAnswer, userAnswer = event.value;
    var fieldname=event.target.name;
    var flag = arguments[0];
    var filterMethod = arguments[1];
    var compareMethod = arguments[2];
    if ( !ProcessIt || userAnswer == "" ) return null;
    for (i = 3; i < arguments.length; i++)
        if ( success = compareTxt(userAnswer,arguments[i],%
filterMethod, compareMethod)) break;
    return notifyField(success, flag, fieldname);
}
%    \end{macrocode}
% This is for text fill-in problems with partial credit. It takes a variable
% number of arguments. \texttt{arguments[i]=["<word>", part\_credit]}. This
% function has a property attached to it \texttt{ProcRespTxtPC.txtPCpCr}
% is the credit received for this problem. This function is called by
% \cs{RespBoxTxtPC}.
%    \begin{macrocode}
function ProcRespTxtPC() {
    var i, success, authorAnswer, userAnswer = event.value;
    ProcRespTxtPC.txtPCpCr=0;
    var fieldname=event.target.name;
    var flag = arguments[0];
    var filterMethod = arguments[1];
    var compareMethod = arguments[2];
    if ( !ProcessIt || userAnswer == "" ) return null;
%    \end{macrocode}
% Unlike \texttt{ProcRespTxt}, we do not break at our first success. We go through
% all \texttt{<words>}, each having partial credit associated with it. For each
% success returned by \texttt{compareTxt}, we add in the credit to the total.
%    \begin{macrocode}
    for (i=3;i<arguments.length;i++)
        if(compareTxt(userAnswer,arguments[i][0],%
filterMethod,compareMethod))
            ProcRespTxtPC.txtPCpCr+=(arguments[i][1]);
%    \end{macrocode}
% success if at least one of the words were used, partial credit awarded.
%    \begin{macrocode}
    success=(ProcRespTxtPC.txtPCpCr>0);
    return notifyField(success,flag,fieldname);
}
%    \end{macrocode}
%
% \texttt{compareTxt} actually compares the \texttt{userAnswer} with the \texttt{authorAnswer}.
% there are options for various types of comparisons.
% Returns true or false.
%    \begin{macrocode}
function compareTxt(userAnswer,authorAnswer,filterMethod,compareMethod)
{
    var caseSensitive = ( compareMethod==3 ) ? "" : "i";
    var reSwitches = "g"+caseSensitive;
    userAnswer = new String(userAnswer).filter(filterMethod);
    switch(compareMethod) {
        case 1:
            var AuthorAnswer;
            var aAuthorAnswer = authorAnswer.split(/\s+/);
            for (var j=0; j < aAuthorAnswer.length; j++) {
                AuthorAnswer = new String(%
aAuthorAnswer[j]).filter(filterMethod);
%    \end{macrocode}
% When using \cs{RespBoxTxtPC}, if the author wants to use the
% character class . (period, meaning match anything newline or another unicode line terminator)
% we define in \cs{RespBoxTxtPC} a local command \cs{any} which expands to \texttt{@any@}.
% After we replace any occurrence of . (period) with \verb!\\.!, we then replace \texttt{@any@}
% with \texttt{.}.
%    \begin{macrocode}
                AuthorAnswer = AuthorAnswer.replace(/\./g,"\\.");
                AuthorAnswer = AuthorAnswer.replace(/@any@/g,".");
                var re = new RegExp(AuthorAnswer, reSwitches);
                if (!re.test(userAnswer)) return false;
            }
            return true;
        default:
            authorAnswer=new String(authorAnswer).filter(filterMethod);
            return (userAnswer == authorAnswer) ? true : false;
    }
}
%    \end{macrocode}
% Various string prototypes. This function is called by compareTxt.
% The function returns the 'filtered' string.
%    \begin{macrocode}
String.prototype.filter = eqFilter;
function eqFilter(filterMethod) {
    switch (filterMethod) {
        case 0:
            var re = /\W/g;
            return this.replace(re,"").toLowerCase();
        case 1:
            var re = /\s/g;
            return this.replace(re,"").toLowerCase();
        case 2:
            var re = /\s/g;
            return this.replace(re,"");
%    \end{macrocode}
% If filter method 3 is used, a case-insensitive search is used in the
% \texttt{compareTxt} method. Added 04/21/09.
%    \begin{macrocode}
        case 3:
        default:
%    \end{macrocode}
%\changes{v6.4k}{2011/08/17}{Within the function eqFilter, changed \string\texttt{this} to
% \string\texttt{this.toString()}. The comparisons were returning false when they shouldn't
% this is because in this case, we were comparing objects to objects}
%    \begin{macrocode}
            return this.toString();
    }
}
%    \end{macrocode}
%    JavaScript support of spell checking command |\SpellCheck|
%    \changes{v8.5.11}{2020/11/11}{JavaScript support of spell checking command \string\cs{SpellCheck}}.
%    Returns the number of misspelled words, but allows user to to correct.
%    \begin{macrocode}
function checkTheSpelling(targetFieldName) {
  var spellChkCnt=0;
%  var thisName=event.target.name;
%    \end{macrocode}
%    The root name of the \cs{SpellCheck} field is \texttt{spl}. Here we replace
%    the root name with \texttt{obj} to get the field name of the previous \cs{RespBoxTxt(PC)}
%    field. For the \texttt{spell.checkWord()} method, \app{PDF-XChange Editor} returns \texttt{undefined}.
%    This (spell checking) is a AR/AA feature only.
%    \begin{macrocode}
  var f=this.getField(targetFieldName);
  var value=f.value;
  var valueStrip = value.replace(/\s+/g,"");
  if ( valueStrip != "" ) {
    aBrk=value.split(/\s+/);
    for (var i=0; i<aBrk.length; i++){
      var word=aBrk[i];
      var aRetnSC=spell.checkWord(word);
      if (aRetnSC!=null) spellChkCnt++;
    }
    var corrdStr=spell.checkText(value);
    f.value=corrdStr;
  }
  return spellChkCnt;
}
\end{newsegment}
%    \end{macrocode}
% \subsection{Multiple Choice Questions}
% These are the routines for processing multiple choice questions.
%    \begin{macrocode}
\begin{newsegment}{Eq: Quiz Management}
function InitMsg(msg) { return (\eqInitQuizMsg) }
function syntaxError() { eqAppAlert(\eqSyntaxErrorUndefVar,3); }
%    \end{macrocode}
%    \begin{macrocode}
var lstOfQuizzes=new Object();
%    \end{macrocode}
% There are four required parameters, if there is a fifth, that means
% we have a grouped question, parameter 5 will be the group sub-problem number.
%    \begin{macrocode}
var reExtractBaseName=/^.+?\.(.+?)\..+$/;
function ProcUserResp(key,userresp,probno,notify)
{
    if (key==null) {
        ProcUserNoResp.apply(null,arguments);
        return;
    }
    if ( arguments.length > 4 ) {
        if ( typeof RightWrong[probno] == "undefined" ) {
            RightWrong[probno] = new Array();
            RightWrong[probno][0] = "grp";
            Responses[probno] = new Array();
        }
        RightWrong[probno][arguments[4]] = (!!key) ? 1 : 0;
        Responses[probno][arguments[4]] = userresp;
    } else {
%    \end{macrocode}
% If key is an array, we are processing a multiple selection problem. The
% actual key is the first entry. The second entry, not used here, is 1
% if user has selected at least one correct answer, zero otherwise.
%    \begin{macrocode}
      if ( typeof key == "object" ) {
          RightWrong[probno][0] = key[0];
          RightWrong[probno][1] = key[1];
          Responses[probno] = userresp;
          if (Responses[probno].length==0)
            Responses[probno]=undefined;
      } else {
        RightWrong[probno] = (!!key)?1:0;
        Responses[probno] = userresp;
      }
    }
%    \end{macrocode}
% \texttt{ProcUserResp()} is also called by a link, so we'll skip this code.
% \texttt{fieldPopTbl()} is executed later in \texttt{ProcessQuestions()}
%    \begin{macrocode}
    if ( (typeof fieldPopTbl == "function")&&(event.type != "Link") ) {
        var a=reExtractBaseName.exec(event.target.name);
        fieldPopTbl(a[1]);
    }
}
%    \end{macrocode}
% (2021/04/04) Added try/catch to catch exceptions.
% \changes{v8.6.6}{2021/04/04}{Added some try/catch pairs to avoid tossing cookies}
%    \begin{macrocode}
function ProcUserNoResp(key,userresp,probno,notify)
{
  if ( arguments.length > 4 ) {
    try{
      RightWrong[probno][arguments[4]] = undefined;
      Responses[probno][arguments[4]] = undefined;
    } catch(e){};
    var bVoidArray=true;
    try {
      for (var i=0; i<Responses[probno].length; i++) {
        if ( typeof Responses[probno][i] != "undefined") {
          bVoidArray=false;
          break;
        }
      }
    } catch(e){};
    if (bVoidArray) {
      Responses[probno]=undefined;
      RightWrong[probno]=undefined;
      ProbValue[probno]=undefined;
    }
  } else {
      RightWrong[probno] = undefined;
      Responses[probno] = undefined;
  }
  if ( typeof fieldPopTbl == "function" ) {
    var a=reExtractBaseName.exec(event.target.name);
    fieldPopTbl(a[1]);
  }
}
function InitializeQuiz(qtfield,mark) {
    var oQName=eval(qtfield);
    Score=0;
    retn = null;
    if (!isQuizInitialized(qtfield)&&!isAQuizUnfinished()) return null;
    neutralizeQuizzes();
    ProcessIt = false;
%    aQuizControl[qtfield] = 1;
%    \end{macrocode}
%    (2021/05/29) Pressing \uif{Shift-Begin Quiz} will clear the quiz,
%    but not initialize for another quiz.
%    \changes{v8.8.1}{2021/05/25}{Shift-Begin Quiz clears the quiz, but does
%    not initialize the quiz.}
%    \begin{macrocode}
    if (arguments.length>2)
      aQuizControl[qtfield] = arguments[2]; // 0 or 1 designed for 0
    else aQuizControl[qtfield] = (event.shift)?0:1; // dps5-25
    this.resetForm(["ScoreField." + qtfield,"mc."+qtfield,
      "obj."+qtfield,"mck."+qtfield,"Ans."+qtfield,
      "PointsField."+qtfield,"PercentField."+qtfield,
      "essay."+qtfield,"GradeField."+qtfield,
      "grpobj."+qtfield,"qMark."+qtfield, qtfield+"SanityCheck",
      qtfield+"SanityCheckPts",qtfield+"SanityCheckOOPts",
      "rbmarkup."+qtfield]);
    ProcessIt = true;
    var f = this.getField("qMark."+qtfield);
    if ( f != null ) f.display = display.hidden;
    f = this.getField("promptButton."+qtfield);
    if (f != null) f.display=display.visible;
%    \end{macrocode}
% We create a special parameter for Oa.Sys. Then the arguments.length is
% 3 (or greater) we do not set the objective text fields to readonly=false.
% Oa.Sys already creates a readonly field for the solutions, we don't want
% to mess with that.
%    \begin{macrocode}
    if (arguments.length<4)  {
        f = this.getField("obj." + qtfield);
        if ( f != null ) f.readonly = false;
    }
    RightWrong=new Array();
    Responses=new Array();
    ProbValue=new Array();
    ProbDist=new Array();
    ProbType=new Array();
    if (mark==1)
    {
%    \end{macrocode}
%    The next few lines support local symbol and color assignment.
%    \begin{macrocode}
        var defaultColor=(typeof oQName.DefaultColorJSLoc=="undefined")%
?\defaultColorJS:oQName.DefaultColorJSLoc;
        var rightColor=(typeof oQName.RightColorJSLoc=="undefined")%
?\rghtColorJS:oQName.RightColorJSLoc;
        var corrAnsSymb=(typeof oQName.CorrAnsSymbJSLoc=="undefined")%
?\corrAnsSymbJS:oQName.CorrAnsSymbJSLoc;
        var f = this.getField("mcq." + qtfield);
        if (f != null) {
            f.delay=true;
            f.display=display.hidden;
            this.resetForm([f.name]);
%    \end{macrocode}
%    (2013/10/27) Removed legacy code for version prior to 4.0
%    \begin{macrocode}
            f.textColor = rightColor;
            var a = f.getArray();
            for (var i=0; i<a.length; i++) a[i].style=corrAnsSymb;
            f.delay=false;
        }
        f = this.getField("obj." + qtfield);
        if ( f != null ) f.strokeColor = defaultColor;
        f = this.getField("grpobj." + qtfield);
        if ( f != null ) f.strokeColor = defaultColor;
        f = this.getField("corr." + qtfield);
        if ( f != null ) f.display = display.hidden;
        f = this.getField(qtfield+"SanityCheck");
        if ( f != null ) f.strokeColor=defaultColor;
        f = this.getField("rbmarkup."+qtfield);
        if ( f != null ) f.display = display.hidden;
    }
    return null;
}
function resetHeadsUp(flag,fieldname) {
  if (flag==1) return;
  var pos1=fieldname.indexOf(".");
  var pos2=fieldname.indexOf(".",pos1+1);
  var baseName=fieldname.substring(pos1+1,pos2);
  var oQName=eval(baseName);
  var defaultColor=(typeof oQName.DefaultColorJSLoc=="undefined")%
?\defaultColorJS:oQName.DefaultColorJSLoc;
  var f=this.getField(fieldname);
  if (f!=null) f.strokeColor=defaultColor;

}
function neutralizeQuizzes()
{
    for ( var qtfield in aQuizControl ) aQuizControl[qtfield] = 0;
}
isAQuizUnfinished.check=true;
function isAQuizUnfinished()
{
    if (!isAQuizUnfinished.check) return true;
    for ( var qtfield in aQuizControl )
        if ( aQuizControl[qtfield] == 1 )
        {
            eqAppAlert(\eqerrUnfinishQuiz, 3);
            return false;
        }
    return true;
}
function isQuizInitialized(qtfield)
{
    if (typeof (aQuizControl[qtfield]) == "undefined")
        return false;
    else
        return (aQuizControl[qtfield] == 1);
}
function isEndQuizPushed(qtfield)
{
    if (typeof (aQuizControl[qtfield]) == "undefined")
        return false;
    else
        return (aQuizControl[qtfield] == -1);
}
function resetQuiz(qtfield)
{
    aQuizControl[qtfield] = -1;
}
%    \end{macrocode}
%     \leavevmode\IndexJS{RecordPointValue}\hskip-\marginparsep\texttt{(\ameta{ptValue},\ameta{probno}}\\
%     \texttt{[,grpquestionno,grpPointValue,\ameta{total-weight},\ameta{grpEvalFunction}])}\\
% The function \texttt{RecordPointValue} has two required parameters. For a grouped question,
% there are four \emph{more} parameters, they are, in order (2) \texttt{grpquestionno} (3) \texttt{grpPointValue}
% (4) total weight (5) \texttt{grpEvalFunction}, a JS function that evaluates the group.\par\medskip\noindent
% The elements of the \texttt{ProbValue} array are as follows:
%\begin{enumerate}
%    \item If multiple choice, then the entry is \texttt{[0, point value, partial credit]}
%    \item If objective type question that is not part of a group, the entry is a number \texttt{point value}
%    \item total weight of the group, significant only if greater than point value
%    \item If objective grouped-type question, the entry is\\
%          \texttt{[1, EvalJS, grpPointValue, \ameta{list of points for each part}]}
%\end{enumerate}
%    \begin{macrocode}
function RecordPointValue(ptvalue,probno)
{
  if (arguments.length > 2) {
    if ( typeof ProbValue[probno] == "undefined" ) {
      ProbValue[probno]=[1,arguments[5],arguments[3],arguments[4]];
      ProbValue[probno][3+arguments[2]] = ptvalue;
    } else ProbValue[probno][3+arguments[2]] = ptvalue;
  }
  else {
    ProbValue[probno]=ptvalue;
  }
}
function RecordProblemType(qType,probno)
{
    ProbType[probno]=qType;
}
function GrpRight( a, nProb, qtfield )
{
    var f = this.getField("grpobj."+qtfield+"."+nProb);
    var l = f.getArray().length
    var prod = 1;
    for ( var i=1; i <= l; i++) prod *= !!a[i];
    return prod;
}
function DisplayQuizResults(qtfield,nPointTotal,nQuestions) {
    Score = 0; ptScore = 0;
    NPointTotal=nPointTotal; NQuestions=nQuestions;
%    \end{macrocode}
%    If \texttt{RightWrong} is undefined, set length = 0 (dps5-24)
%    \begin{macrocode}
    var l=(typeof RightWrong=="undefined")?0:RightWrong.length;
    for (var i=1; i < l; i++) {
        if ( (typeof RightWrong[i] == "object" ) && %
( RightWrong[i][0] == "grp" ) ) {
            // grouped question
            Score += GrpRight(RightWrong[i], i, qtfield);
            var aWeights = ProbValue[i].slice(2);
            var evalGrpJS = eval(ProbValue[i][1]);
            var evalGrpJSValue = evalGrpJS(this,qtfield,i,
                RightWrong[i],aWeights);
            ProbDist[i] = evalGrpJSValue;
            ptScore = ptScore + evalGrpJSValue;
        } else {
            if (typeof RightWrong[i] == "object") {
                if ( RightWrong[i][0] == 1 ) {
                    Score++;
                    ProbDist[i]=(typeof ProbValue[i] == "object") ?
                        1*ProbValue[i][1] : 1*ProbValue[i];
                    ptScore += (1*ProbDist[i]);
                } else {
                    if (RightWrong[i][1] == 1)
                        ProbDist[i]=(typeof ProbValue[i]=="object") ?
                            1*ProbValue[i][1] : 1*ProbValue[i];
                    else {
                        ProbDist[i]=(typeof ProbValue[i] == "object") ?
                            1*ProbValue[i][1] : 0;
%    \end{macrocode}
%     If the user receives negative points, we change it to zero points.
%    \changes{v8.5.9}{2020/02/21}{If the user receives negative points, we change it to zero points.}
%    \begin{macrocode}
                        if (!negPointsAllowed && %
!negPointsMarkupAllowed && (ProbDist[i]<0) ) ProbDist[i]=0;
                    }
                    ptScore += (1*ProbDist[i]);
                }
            } else {
                if (RightWrong[i]==1) {
                    Score++;
                    ProbDist[i] = ( typeof ProbValue[i] == "object") ? %
1*ProbValue[i][1] : 1*ProbValue[i];
                    ptScore += (1*ProbDist[i]);
                }
                else {
                    ProbDist[i] = ( typeof ProbValue[i] == "object") ? %
1*ProbValue[i][2] : 0;
                    ptScore += (1*ProbDist[i]);
                }
            }
        }
    }
    if ( !negPointsAllowed && (ptScore < 0) ) ptScore = 0;
    if (ptScore == nPointTotal) pcScore = 100;
    else pcScore = util.printf("\%.1f", (100 * ptScore) / nPointTotal);
    var oQName=eval(qtfield);
    var gradeScale=%
(typeof oQName.GradeScaleLoc=="undefined")%
?GradeScaleDefault:oQName.GradeScaleLoc;
    quizGrade = GetGrade.apply(null,gradeScale);
%    \end{macrocode}
%   (2021/02/17) If there is a fourth argument for this function, it should
%   be either \texttt{true} or \texttt{false}; if \texttt{true}, \texttt{DisplayQuizResults()}
%   does not display quiz results; the default is \texttt{false}. This feature is used in the
%   demo file \texttt{qz-pin-to-correct.tex} found on the {Acro\negthinspace\TeX} Blog.
%   \changes{v8.6.4}{2021/02/17}{Added conditional (\string\texttt{\_bSilent})}
%    \begin{macrocode}
    var _bSilent=(arguments.length > 3 ) ? arguments[3] : false;
    if (!_bSilent) {
      var f = this.getField("ScoreField."+qtfield);
      if ( f != null ) f.value=(\eqQuizTotalMsg);
      f = this.getField("PointsField."+qtfield);
      if ( f != null) f.value=(\eqQuizPointsMsg);
      f = this.getField("PercentField."+qtfield);
      if ( f != null) f.value=(\eqQuizPercentMsg);
      f = this.getField("GradeField."+qtfield);
      if ( f != null) f.value=(\eqQuizGradeMsg);
    }
}
function GetGrade()
{
    var cGrade, aRange;
    var l = arguments.length/2;
    if (pcScore >=100) return arguments[0];
    if (pcScore < 0 ) return arguments[arguments.length-2];
    for (var i=0; i < l; i++)
    {
        cGrade = arguments[2*i];
        aRange = arguments[2*i+1];
        if ( (pcScore >= arguments[2*i+1][0])
            && (pcScore < arguments[2*i+1][1])) return cGrade;
    }
    return null;
}
function ProcessQuestion (key,letterresp,probno,
    quizno,qtfield,notify,mark,msg) {
    var silent = ( arguments.length > 8 ) ? true : false;
    if (!isQuizInitialized(qtfield))
    {
        if (!silent) eqAppAlert(InitMsg(msg),3);
        this.resetForm(["mc."+qtfield+"."+probno,
            "mck."+qtfield+"."+probno]);
    }
    else
    {
        ProcUserResp(key,letterresp,probno,notify);
        if (mark==1)
        {
            var oQName=eval(qtfield);
            var defaultColor=%
(typeof oQName.DefaultColorJSLoc=="undefined")%
?\defaultColorJS:oQName.DefaultColorJSLoc;
            var rightColor=%
(typeof oQName.RightColorJSLoc== "undefined")%
?\rghtColorJS:oQName.RightColorJSLoc;
            var wrongColor=%
(typeof oQName.WrongColorJSLoc=="undefined")%
?\wrngColorJS:oQName.WrongColorJSLoc;
            var rightAnsSymb=%
(typeof oQName.RightAnsSymbJSLoc=="undefined")%
?\rghtAnsSymbJS:oQName.RightAnsSymbJSLoc;
            var wrongAnsSymb=%
(typeof oQName.WrongAnsSymbJSLoc=="undefined")%
?\wrngAnsSymbJS:oQName.WrongAnsSymbJSLoc;
            var corrAnsSymb=%
(typeof oQName.CorrAnsSymbJSLoc=="undefined")%
?\corrAnsSymbJS:oQName.CorrAnsSymbJSLoc;
%    \end{macrocode}
% MC or MS questions
%    \begin{macrocode}
            var f = this.getField("mcq."+qtfield+"."+probno);
            var fck = this.getField("mck."+qtfield+"."+probno);
            var bMultiSelect = ( fck != null ) ? true : false;
            f.delay=true;
            this.resetForm([f.name]);
            var a = f.getArray();
            var l = a.length;
            if ( bMultiSelect ) {
                var ack = fck.getArray();
                for ( var i=0; i<l; i++) {
                    if ( ack[i].isBoxChecked(0)  ) {
                        a[i].style = ( a[i].isDefaultChecked(0) ) ?
                            rightAnsSymb : wrongAnsSymb;
                        a[i].textColor = ( a[i].isDefaultChecked(0) ) ?
                            rightColor : wrongColor;
                        a[i].value = "Yes";
                    } else {
                        a[i].style = ( a[i].isDefaultChecked(0) ) ?
                            corrAnsSymb : wrongAnsSymb;
                        a[i].textColor = ( a[i].isDefaultChecked(0) ) ?
                            rightColor : wrongColor;
                        a[i].value = ( a[i].isDefaultChecked(0) ) ?
                            "Yes" : "Off";
                    }
                }
            } else {
                for (var i=0; i < a.length; i++)
                    if (a[i].style == rightAnsSymb)
                    {
                        a[i].style = corrAnsSymb;
                        a[i].textColor = rightColor;
                    }
                var qr=this.getField(%
"mcq."+qtfield+"."+probno+"."+quizno);
%    \end{macrocode}
% (2013/10/27) removed legacy code for versions prior to 4.0.
%    \begin{macrocode}
                qr.textColor = key ? rightColor :wrongColor;
                qr.style = key ? rightAnsSymb : wrongAnsSymb;
                qr.value="Yes"; // gr.checkThisBox(0);  // ver 5.0
            }
            this.getField("mcq."+qtfield+"."+probno).delay=false;
        }
    }
    if ( typeof fieldPopTbl == "function" ) fieldPopTbl(qtfield);
}
%    \end{macrocode}
%    \leavevmode
%    \IndexJS{correctQuiz}\hskip-\marginparsep\texttt{(\ameta{fld-name},\ameta{num-ques})}
%    This function is called when the \uif{Correct} control is pressed on a quiz.
%    Dependencies: \texttt{RightWrong}, \texttt{ProbDist} (if \texttt{qMark} is present). Other dependencies
%    needed to save the state of the quiz after the \uif{End Quiz} control is pressed and before the
%    \uif{Correct} control is pressed:
%    \begin{macrocode}
function correctQuiz(qtfield,nQuestions)
{
%    \end{macrocode}
%    (2019/10/14) If \texttt{oRecordOfQuizData} is present (from \pkg{eq-save}), we use that data from the quiz.
%    \changes{v8.5.1}{2019/10/14}{Incorporated oRecordOfQuizData into correctQuiz()}
%    \begin{macrocode}
  var bROQD=(typeof oRecordOfQuizData=="object");
  if(bROQD && %
(typeof oRecordOfQuizData["RightWrong."+qtfield]!="undefined")) {
    RightWrong=oRecordOfQuizData["RightWrong."+qtfield];
    ProbDist=oRecordOfQuizData["ProbDist."+qtfield];
  }
%    \end{macrocode}
%    Determine the color scheme to be used.
%    \begin{macrocode}
  var oQName=eval(qtfield);
  var defaultColor=(typeof oQName.DefaultColorJSLoc=="undefined")%
?\defaultColorJS:oQName.DefaultColorJSLoc;
  var rightColor=(typeof oQName.RightColorJSLoc=="undefined")%
?\rghtColorJS:oQName.RightColorJSLoc;
  var wrongColor=(typeof oQName.WrongColorJSLoc=="undefined")%
?\wrngColorJS:oQName.WrongColorJSLoc;
  var rightAnsSymb=(typeof oQName.RightAnsSymbJSLoc=="undefined")%
?\rghtAnsSymbJS:oQName.RightAnsSymbJSLoc;
  var wrongAnsSymb=(typeof oQName.WrongAnsSymbJSLoc=="undefined")%
?\wrngAnsSymbJS:oQName.WrongAnsSymbJSLoc;
%    \end{macrocode}
%    Implement a local version of fully correcting MC and MS questions.
%    \changes{v8.1l}{2018/02/07}{Add local version of \string\cs{corrChoiceFullOn}}
%    \begin{macrocode}
  var bFullyCorrect=(typeof oQName.fullyCorrectLoc=="undefined")%
?\eqCorrChoiceFully:oQName.fullyCorrectLoc;
%    \end{macrocode}
% MC or MS questions
%    \begin{macrocode}
  var f = this.getField("mcq." + qtfield);
%    \end{macrocode}
%      For MC question, show only the incorrect ones, depending on the
%      switch \texttt{bFullyCorrect}.
%      \changes{v8.1f}{2017/12/04}{Added an option for MC question not to
%      show the correct answer, but only the incorrect ones.}
%    \begin{macrocode}
  if ( f != null) {
    if (bFullyCorrect) {
      f.display = display.visible;
    } else {
      for (var n=1; n<=nQuestions; n++) {
        var h=this.getField("mc."+qtfield+"."+n);
        var bOk=(h!=null);
        if(bOk) var choiceType="mc";
        else {
          h=this.getField("mck."+qtfield+"."+n);
          bOk=(h!=null);
          var choiceType="mck";
        }
        if (bOk) {
          var mcq=this.getField("mcq."+qtfield+"."+n);
          var g=mcq.getArray();
          if (choiceType=="mc") {
            for (var j=0; j< g.length; j++) {
              g[j].display=(h.isBoxChecked(j))?%
display.visible:display.hidden;
              }
            } else {
              var ck=h.getArray();
              for (var j=0; j< g.length; j++) {
                g[j].display=(ck[j].isBoxChecked(0))?%
display.visible:display.hidden;
              }
            }
          }
        }
      }
    }
    f = this.getField("obj." + qtfield);
    if ( f != null ) {
    var a = f.getArray();
    var re=/^obj\./;
    for (var i = 0; i < a.length; i++) {
      var probno = a[i].name.replace(/.*\./g,"");
      var rbmuname = a[i].name.replace(re,"rbmarkup\.");
      var oRBMarkup = this.getField(rbmuname);
      var bRBMU = ( oRBMarkup != null );
      if ( (typeof RightWrong!="undefined") && % // dps5-24
(RightWrong[probno] == 1) ) {
        a[i].strokeColor = rightColor;
        if (bRBMU) {
            oRBMarkup.textColor=rightColor;
            oRBMarkup.style=rightAnsSymb;
        }
      } else {
        a[i].strokeColor = wrongColor;
        if (bRBMU) {
            oRBMarkup.textColor=wrongColor;
            oRBMarkup.style=wrongAnsSymb;
        }
      }
    }
  }
  f = this.getField("grpobj." + qtfield);
  var re=/^grpobj\./;
  if ( f != null ) {
    var a = f.getArray();
    for ( var i = 0; i < a.length; i++) {
      var rbmuname = a[i].name.replace(re,"rbmarkup\.");
      var oRBMarkup = this.getField(rbmuname);
      var bRBMU = ( oRBMarkup != null );
      var aX = a[i].name.split(".");
      var probno = 1*aX[aX.length-2];
      var grpProbno = 1*aX[aX.length-1];
      if ( ( RightWrong[probno] != undefined ) %
&& ( RightWrong[probno][grpProbno] == 1 ) ) {
        a[i].strokeColor = rightColor;
        if (bRBMU) {
            oRBMarkup.textColor=rightColor;
            oRBMarkup.style=rightAnsSymb;
        }
      } else {
        a[i].strokeColor = wrongColor;
        if (bRBMU) {
          oRBMarkup.textColor=wrongColor;
          oRBMarkup.style=wrongAnsSymb;
        }
      }
    }
  }
  f=this.getField("rbmarkup."+qtfield);
  if ( f != null ) f.display = display.visible;
  f = this.getField("promptButton." + qtfield)
  if ( f != null ) f.display = display.hidden;
  f = this.getField("corr." + qtfield);
  if ( f != null ) f.display = display.noPrint;
%    \end{macrocode}
% dps (01/01/04) If there are qMark fields, then write marks for each question
% to them.
%    \begin{macrocode}
  f = this.getField("qMark."+qtfield);
  if ( f != null ) {
    for ( var i = 1; i <= nQuestions; i++) {
      if ( ProbValue[i] == undefined ) ProbValue[i]=0;
      f = this.getField("qMark."+qtfield+"."+(i-1));
      if ( f != null ) {
%    \end{macrocode}
% (3/22/04) This is code to account for grouping
%    \begin{macrocode}
        // find the next non-null field
        for ( var j=i; j <= nQuestions; j++)
        {
            var h = this.getField("qMark."+qtfield+"."+j);
            if ( h != null ) break;
        }
        var g = f.getArray();
        if (typeof ProbDist == "undefined" ) var qpts=0; // dps5-24
        else
          var qpts=(ProbDist[i]==undefined) ? 0 : ProbDist[i];
        if ( !negPointsMarkupAllowed && (qpts < 0) ) qpts=0;
        g[0].value = qpts + (( qpts == 1 ) ? " \eqptLabel\space"
            : " \eqptsLabel");
      }
    }
    this.getField("qMark."+qtfield).display = display.visible;
  }
}
%    \end{macrocode}
% When pdftex is used, the total tally box does not work because pdftex does not support
% the calculate key in AcroForms. We try to simulate this.
%    \begin{macrocode}
function getTotalTally(basename) {
    var sqtotal=0;
    var f=this.getField("tally."+basename);
    var g = f.getArray();
    for (var i=0; i<g.length; i++) {
        if ( g[i] == event.target ) sqtotal += (1*event.value);
        else sqtotal += (1*g[i].value);
    }
% console.println("sqtotal="+sqtotal);
    if ( ( f=this.getField("tallytotal."+basename) ) != null )
        f.value = sqtotal;
}
function clearAllSubQuizzes() {
    isAQuizUnfinished.check=false;
    for ( var o in lstOfQuizzes) {
        if (lstOfQuizzes[o].isSubmitted)
            eval ( lstOfQuizzes[o].initializeWith );
    }
    isAQuizUnfinished.check=true;
}
\end{newsegment}
%    \end{macrocode}
% \subsection{Support for Multiple Selection Questions}
% This function
%    \begin{macrocode}
\begin{newsegment}{Eq: Support for Multi-Selection}
function ProcessMultiSelection(key,letterresp,probno,%
quizno,qtfield,pts,ppts) {
%   var f = this.getField("mck."+qtfield+"."+probno); // dpsx
    var f = this.getField("mcq."+qtfield+"."+probno);
%    \end{macrocode}
%        For the multiple selection problem, the formats for the \texttt{RightWrong} and \texttt{ProbValue}
%        arrays are as follows:
%\begin{verbatim}
%        RightWrong[probno]
%            [0, 1, [undefined, undefined, 0, 1, 1, 0, 1]]
%\end{verbatim}
%        The first entry records whether the user answered the question totally correctly,
%        the second entry is for awarding points, 1 if the user selected at least one correct
%        answer. The third entry is an array of right/wrong responses to the user's responses.
%\begin{verbatim}
%        ProbValue[probno]
%            [3, 5, [undefined, undefined, -2, 3, 3, -2, 3]]
%\end{verbatim}
%        First entry is the number of correct answers for this problem, the second entry is the
%        number of points the student has earned for this problem, the third entry is an array of points obtained
%        based on the user's responses.
%\changes{v6.3h}{2008/10/17 }
%{%
%   For the manswers environment, we were not determining if the user had answered the question
%   correctly.
%}
%    \begin{macrocode}
    if ( typeof ProbValue[probno] == "undefined" )  {
        var g = f.getArray();
%    \end{macrocode}
%     We calculate the total number of correct alternatives in this MS field
%    \begin{macrocode}
        var nTotalCorrect = 0;
        for ( var i=0; i<g.length; i++ )
%    \end{macrocode}
% (2021/10/03) Work with the tool tip of \texttt{mcq} rather than the export value
% of \texttt{mck}.
%    \begin{macrocode}
          nTotalCorrect += (1*g[i].userName);
%         nTotalCorrect += (1*g[i].exportValues[0].charAt(0)); // dpsx
        ProbValue[probno] = new Array();
        RightWrong[probno] = new Array();
        ProbValue[probno] = [nTotalCorrect,pts,[]];
        RightWrong[probno][2] = new Array();
    } else var nTotalCorrect = ProbValue[probno][0];
    var fck = this.getField("mck."+qtfield+"."+probno+"."+quizno);
    if ( fck.isBoxChecked(0) ) {
        ProbValue[probno][2][quizno] = ppts;
        RightWrong[probno][2][quizno] = key;
    } else {
        ProbValue[probno][2][quizno] = undefined;
    }
    var pointsThisProblem=0;
    var scoreThisProblem = 0;
    var letterResponses = new Array();
    var areAllCorrect=1;
    var numCorrect=0;
    for ( var i=1; i< ProbValue[probno][2].length; i++ ) {
        if ( typeof ProbValue[probno][2][i] != "undefined" )
            letterResponses[i] = (String.fromCharCode(96+i));
        pointsThisProblem += ( ( typeof ProbValue[probno][2][i]==%
"undefined" )?0:ProbValue[probno][2][i]);
        if ( typeof ProbValue[probno][2][i]!="undefined" ) {
%    \end{macrocode}
% As we go through the \texttt{ProbValue[probno][2]} array, we use the index
% to make some tallies in the \texttt{RightWrong[probno][2]} array. We multiply
% and add all entries together. The value of \texttt{areAllCorrect} will be 1 if the
% student only chooses correct answers, while \texttt{numCorrect} totals the number of
% correct responses.
%    \begin{macrocode}
            areAllCorrect *= (1*RightWrong[probno][2][i]);
            numCorrect +=(1*RightWrong[probno][2][i]);
        }
    }
%    \end{macrocode}
% The value of \texttt{scoreThisProblem} will be 0 if the user selects any false
% answers, and will be the number of correct answers selected otherwise.
%    \begin{macrocode}
    scoreThisProblem = areAllCorrect*numCorrect;
%    \end{macrocode}
% Now the value of \texttt{scoreThisProblem} is 0 if the user selects any false
% answers, and~1 if the number of correct answer equals the total number of
% correct answers for this problem.
%    \begin{macrocode}
    var scoreThisProblem = Number( scoreThisProblem == nTotalCorrect );
%    \end{macrocode}
% \texttt{(02/02/09)}: If we determine this problem is right, but \texttt{pointsThisProblem==0},
% then there must be no partial credit specification of the points, so we'll award all points.
%    \begin{macrocode}
    if (scoreThisProblem==1 && pointsThisProblem==0 )
        pointsThisProblem=pts;
    ProbValue[probno][1] =
        ( (ProbValue[probno][1] == 0) && (scoreThisProblem == 1) )
            ? pts : pointsThisProblem;
%    \end{macrocode}
%    \texttt{passKey} represents whether positive credit is assigned; \texttt{passKey} is only 1
%    when points are awarded. \texttt{scoreThisProblem} is 0 or 1 dependent
%    on whether the problem is wrong or right.
%    \begin{macrocode}
    var passKey = ( pointsThisProblem > 0 ) ? 1 : 0;
    var retn = [ [ scoreThisProblem, passKey ], letterResponses ] ;
    return retn;
}
%    \end{macrocode}
%    \leavevmode\IndexJS{LimitSelection}\hskip-\marginparsep\texttt{(\ameta{n},\ameta{fname},\ameta{index}}
%    This function supports the \cs{limitSelectionTo\darg{\ameta{n}}} command. The function determines
%    whether the user has chosen more than \ameta{n} in a MS choice field. The widget that activated this
%    function is \texttt{\ameta{fname}.\ameta{index}}.
%    \begin{macrocode}
function LimitSelection(n,fname,k) {
    var f = this.getField(fname);
    var g = f.getArray();
    var total=0;
    for (var i=0; i<g.length; i++) {
        total+=( g[i].isBoxChecked(0) );
    }
    if (total > n) {
        eqAppAlert(\limSelWarningMsg,3);
        f=this.getField(fname+"."+k);
        f.checkThisBox(0,false);
        return false
    } else return true;
}
\end{newsegment}
%    \end{macrocode}
% \subsection{Miscellaneous JS}
%    \begin{macrocode}
\begin{newsegment}{Eq: Miscellaneous JS}
%    \end{macrocode}
% This function notifies the calling field of the results. If flag=0,
% it changes the color of the field and updates the tally field.
%    \begin{macrocode}
function chooseJSColor( b, c1, c2 ) {
    return ( b ) ? c1 : c2;
}
function notifyField(success, flag, fieldname) {
  if ( flag != 0 )
    return (success)?true:false;
%    \end{macrocode}
% if \texttt{flag == 0}, then we are working with a \texttt{shortquiz}, and immediate response
% is needed.
%    \begin{macrocode}
  var f = this.getField(fieldname);
  var re=/^(obj|grpobj)\./;
  var gname=fieldname.replace(re,"rbmarkup\.");
  var g =this.getField(gname);
  var isthereRBUP = ( g !=null );
%    \end{macrocode}
% Extract the quiz name from the field name: \texttt{obj.QName.num} or \texttt{grpobj.QName.num}
%    \begin{macrocode}
  var h = fieldname.replace(re,"");
  var index=h.indexOf(".");
  var oQName = eval(h.substring(0,index));
  var rightColor=(typeof oQName.RightColorJSLoc=="undefined")%
?\rghtColorJS:oQName.RightColorJSLoc;
  var rightSymb=(typeof oQName.RightColorJSLoc=="undefined")%
?\rghtAnsSymbJS:oQName.RightAnsSymbJSLoc;
  var wrongColor=(typeof oQName.WrongColorJSLoc=="undefined")%
?\wrngColorJS:oQName.WrongColorJSLoc;
  var wrongSymb=(typeof oQName.WrongAnsSymbJSLoc=="undefined")%
?\wrngAnsSymbJS:oQName.WrongAnsSymbJSLoc;
  if (success) {
    f.strokeColor = rightColor;
    if (isthereRBUP) {
      g.style = rightSymb;
      g.textColor=rightColor;
      g.display=display.visible;
    }
      return true;
  } else {
    updateTally.downState=false;
    updateTally(fieldname);
    f.strokeColor = wrongColor;
    if (isthereRBUP) {
      b2 = ( typeof oQName.WrongAnsSymbJSLoc == "undefined" );
      g.style = wrongSymb;
      g.textColor=wrongColor;
      g.display=display.visible;
    }
    return false;
  }
}
%    \end{macrocode}
%    \begin{macrocode}
function updateTally(fieldname)
{
    var objre = /^obj\./;
    var grpre = /^grpobj\./;
%    \end{macrocode}
% If the question is part of a group of questions, then it has a root name of \texttt{grpobj}.
% This root needs to be removed, as well as the sub-group number.
%    \begin{macrocode}
    if ( grpre.test(fieldname) ) {
        fieldname = fieldname.replace(grpre,"");
        var pos = fieldname.lastIndexOf(".");
        fieldname = fieldname.substring(0,pos);
    } else if ( objre.test(fieldname) )
        fieldname = fieldname.replace(objre,"");
    var f = this.getField("tally."+fieldname);
    if ( f != null ) {
        if (!updateTally.downState) f.value += 1;
        return true;
    } else return false;
}
%    \end{macrocode}
% Below is the \texttt{noPeek} JS function that has been part of \textsf{exerquiz} from the
% beginning.
%\begin{verbatim}
%function noPeek(qtfield,rtnPage)
%{
%    if ( (typeof (aQuizControl[qtfield]) == "undefined") %
%|| (aQuizControl[qtfield] != -1) ) {
%        this.pageNum = rtnPage-1;
%        eqAppAlert(\noPeekMsg,3);
%    }
%}
%\end{verbatim}
% (2010/08/09 v6.3s) One user recently reported that Acrobat/Reader can crash when \texttt{noPeek} is in effect.
% This occurs when the down arrow on the scroll bar is pressed and kept pressed by the mouse.
% The pages can jump between the quiz and a solution page, and build up alert boxes each time.
% Eventually, there is a crash (though I haven't experienced the crash, I have seen the effects
% of using the down arrow on the scroll bar). Below is a proposed ``fix'' for using this
% hellish button. We turn off the alert for 5 milliseconds but always return to the
% starting page (\texttt{rtnPage}), it is not the best solution, but it fixes the crashing
% problem.
%    \begin{macrocode}
var bNoPeekWait=false;
var oNoPeekTimer;
function noPeek(qtfield,rtnPage)
{
  if (!bNoPeekWait) {
    if ( (typeof (aQuizControl[qtfield]) == "undefined") %
|| (aQuizControl[qtfield] != -1) ) {
      bNoPeekWait=true;
      oNoPeekTimer=app.setTimeOut("bNoPeekWait=false;%
app.clearTimeOut(oNoPeekTimer);",5);
      this.pageNum = rtnPage-1;
      \NoPeekAlert;
    }
  } else this.pageNum = rtnPage-1;
}
%    \end{macrocode}
% When the user exits a fill-in short-quiz field, this function is called.
% It immediately notifies user of whether their answer is right
% or wrong, and changes the color of the boundary field.
%    \begin{macrocode}
var bCB=\bcheckboxused
%    \end{macrocode}
% (2021/10/03) Boolean to use extended alert boxes for MC and MS, short-quiz.
%    \begin{macrocode}
var bUseCkBx=\buseckbx; // dpsx
function OnBlurRespBox (retn)
{
  var qname = arguments[1];
  var oQName = eval(qname);
  var respMsg;
  var cTitle = "AcroTeX eDucation Bundle";
  if (retn != null) {
    if ( typeof appAlerts[qname] == "undefined")
      appAlerts[qname] = {bAfterValue: false, %
cMsg: "\doNotShowAgainMsg"};
    var respMsg = (retn) ? \eqsqrtmsg\space : \eqsqwgmsg;
%    \end{macrocode}
%    If \texttt{event.target} is the Doc object, the function has been called from
%    a link; if called from a field action \texttt{event.target} is a Field object.
%    \begin{macrocode}
    if ( !bUseCkBx && ( (event.target == this) || !bCB ) ) // dpsx
      eqAppAlert({ cMsg: respMsg, nIcon: 3, cTitle: cTitle });
    else {
      if ( ! appAlerts[arguments[1]].bAfterValue )
        eqAppAlert({ cMsg: respMsg, nIcon: 3, cTitle: cTitle, %
oCheckbox: appAlerts[qname]});
    }
  }
  else {
  	var re=/^(obj|grpobj)\./;
  	var gname=event.target.name.replace(re,"rbmarkup\.");
  	var g =this.getField(gname);
  	var isthereRBUP = ( g !=null );
    var str = event.target.value.toString();
    if (str.replace(/\s/g,"") == "") {
      var defaultColor=%
(typeof oQName.DefaultColorJSLoc=="undefined")%
?\defaultColorJS:oQName.DefaultColorJSLoc;
  		if (isthereRBUP) g.display=display.hidden;
        event.target.strokeColor = defaultColor;
    }
  }
}
function jmpToNamedDest(fName,cDest,bAlert) {
  if (cDest == "") return;
  if ( (typeof appAlerts[fName]!="undefined" %
&& appAlerts[fName].bAfterValue) || bAlert==0)
    app.setTimeOut("this.gotoNamedDest(\""+cDest+"\")",500);
  else
    this.gotoNamedDest(cDest);
}
%    \end{macrocode}
% Description: This is the default function for determining whether
%   the minimal requirements for finishing a quiz have been met. The
%   default is that there is no minimal requirement.
% Arguments: qtfield = name of the field.
% Returns: true if minimum threshold is met, false otherwise.
%    \begin{macrocode}
function lowThreshold(nQuestions)
{
    return true;
}
%    \end{macrocode}
% Description: This is the default function for determining whether
%   the minimal requirements for finishing a quiz have been met. Here
%   the requirements are to answer all the questions.
% Arguments: nQuestions = number of questions.
% Returns: true if minimum threshold is met, false otherwise.
%
% \noindent You can define this function as the default threshold function by
% typing\par
%\begin{verbatim}
%\renewcommand\minQuizResp{highThreshold}
%\end{verbatim}
%    \begin{macrocode}
function highThreshold(nQuestions)
{
    var cnt=0;
    for ( var i=0; i< Responses.length; i++ ) {
        if ( typeof Responses[i]!="undefined") cnt++
    }
    if ( cnt<nQuestions )
        eqAppAlert(\highThresholdMsg,3);
    return (cnt >= nQuestions);
}
\end{newsegment}
%    \end{macrocode}
% \subsection{Support for Grouped Questions}
% These function can be called by the \texttt{mathGrp} environment to score the user's
% responses to the grouped questions.
%    \begin{macrocode}
\begin{newsegment}{Eq: Support for Grouped Questions}
function groupEval(doc,qtfield,probno,aKey,aWeights)
{
    var totalGrpPts = aWeights[0];
    var totalWeight = aWeights[1];
    for ( var i=1,total=0; i< aKey.length; i++ )
        if (aKey[i] != undefined) total += aKey[i]*aWeights[i+1];
    return total;
}
function WeightedEval(doc,qtfield,probno,aKey,aWeights)
{
    var f = doc.getField("grpobj." + qtfield + "." + probno);
    var nGrpQno = f.getArray().length;
    var totalGrpPts = aWeights[0];
    var totalWeight = aWeights[1];
    for ( var i=1,total=0; i < aKey.length; i++ )
        if (aKey[i] != undefined) total += aKey[i]*aWeights[i+1];
    total /= totalWeight;
    total = Math.floor( total * totalGrpPts );
    return total;
}
%    \end{macrocode}
% This function gives full credit if all parts are answer correctly,
% otherwise, it gives no credit.  This defeats the purpose of partial
% credit. But someone asked for it.
%    \begin{macrocode}
function groupBernoulliEval(doc,qtfield,probno,aKey,aWeights)
{
    var f = doc.getField("grpobj." + qtfield + "." + probno);
    var nGrpQno = f.getArray().length;
    var totalGrpPts = aWeights[0];
    for ( var i=1,isCorrect=1; i<= nGrpQno; i++ )
        isCorrect *= (aKey[i] != undefined) ? (Number(aKey[i])) : 0;
    return (isCorrect*totalGrpPts);
}
\end{newsegment}
\end{insDLJS*}
%</aebjs>
%<*sumrytbls>
%    \end{macrocode}
% This function is called by the \cs{CorrButton}, it does nothing if the ``SanityCheck''
% fields are not present; otherwise,  it colors the boundaries red, green or blue
% depending on whether the problem is wrong, right, or wrong with partial credit given.
%    \begin{macrocode}
\begin{insDLJS}[correctSumryTbl]{sumtbljs}{Eq: Populate Summary Table}
function correctSumryTbl(qtfield,nQuestions) {
%    \end{macrocode}
% \paragraph*{Checkboxes.} We begin by correcting the second column of the summary table.
%    \begin{macrocode}
    var oQName=eval(qtfield);
    var rightColor=(typeof oQName.RightColorJSLoc=="undefined")%
?\rghtColorJS:oQName.RightColorJSLoc;
    var wrongColor=(typeof oQName.WrongColorJSLoc=="undefined")%
?\wrngColorJS:oQName.WrongColorJSLoc;
    var partialColor=(typeof oQName.PartialColorJSLoc=="undefined")%
?\partialColorJS:oQName.PartialColorJSLoc;
    var sc=this.getField(qtfield+"SanityCheck");
    var nc=this.getField(qtfield+"NoCorrections");
    if (sc != null && nc == null ) {
        for (var i=0; i<nQuestions; i++) {
            var cb=this.getField(qtfield+"SanityCheck."+(i+1));
            if (typeof RightWrong[i+1] == "undefined" ) {
                cb.strokeColor=wrongColor;
                continue;
            }
            if ( RightWrong[i+1] == 1 ) {
                cb.strokeColor=rightColor;
                continue;
            }
            if ( RightWrong[i+1] == 0 ) {
                // this is either an obj or multiple choice q
                if ( typeof ProbValue[i+1] == "object" )
                    cb.strokeColor=( ProbValue[i+1][2] > 0 )?%
partialColor:wrongColor;
                else cb.strokeColor=wrongColor; // obj q
                continue;
            }
            // either multiple selection or grouped math
            if ( RightWrong[i+1][0] == "grp" ) {
                // grouped question
                var f = this.getField("grpobj."+qtfield+"."+(i+1));
                var l = f.getArray().length;
                // is this right?
                for (var sum=0, j=1; j<=l; j++)
                    sum+=(!!RightWrong[i+1][j]);
                if ( sum == l ) cb.strokeColor=["RGB", 0, .6, 0];
                else cb.strokeColor=( sum > 0 )?%
partialColor:wrongColor;
                continue;
            }
            // multiple selection
            if ( RightWrong[i+1][0] == 1 ) cb.strokeColor=rightColor;
            else cb.strokeColor=(RightWrong[i+1][1]== 1)?%
partialColor:wrongColor;
        }
    }
%    \end{macrocode}
% \paragraph*{Markup text fields.} Now, we insert the points into the
% markup text fields for the summary table. We look for two types of
% fields, in the next two lines. Each type is formatted differently.
%    \begin{macrocode}
    var f1=this.getField(qtfield+"SanityCheckPts");
    var f2=this.getField(qtfield+"SanityCheckOOPts");
    var h=this.getField(qtfield+"activateSC");
%    \end{macrocode}
% If nonnull here, we format these text fields in the usual way, `2 pts', for example.
%    \begin{macrocode}
    if ( f1 != null ) {
        for ( var i = 1; i <= nQuestions; i++) {
            if ( ProbValue[i] == undefined ) ProbValue[i]=0
                // find the next non-null field
                var g=this.getField(qtfield+"SanityCheckPts."+i);
                var qpts=(ProbDist[i]==undefined) ? 0 : ProbDist[i];
%    \end{macrocode}
%   (2019/06/30) if negative points are not allowed, make qpts zero if necessary
%   \changes{v8.2.14}{2019/06/30}{Added a condition if negPointsAllowed}
%    \begin{macrocode}
                if ( !negPointsAllowed && (qpts < 0) ) qpts=0;
                var thesePts= qpts + (( qpts == 1 )?%
" \eqptLabel":" \eqptsLabel");
                g.value = thesePts;
        }
    }
%    \end{macrocode}
% \texttt{f2} is nonnull when \texttt{showOutOf=true} for any of the tables supporting \texttt{qtfield},
% we repeat basically the same loop, but formatting the value differently.
%    \begin{macrocode}
    if ( f2 != null ) {
        for ( var i = 1; i <= nQuestions; i++) {
            if ( ProbValue[i] == undefined ) ProbValue[i]=0
                // find the next non-null field
                var g=this.getField(qtfield+"SanityCheckOOPts."+i);
                var qpts=(ProbDist[i]==undefined) ? 0 : ProbDist[i];
                if ( !negPointsAllowed && (qpts < 0) ) qpts=0;
                var ptValue = oQName.PtValues[i];
                var probPts = ptValue + (( ptValue == 1 )?%
" \eqptLabel":" \eqptsLabel");
                g.value = qpts +" \stOutOf\space"+probPts;
        }
    }
}
function popVisitsTbl(qtfield,nQuestions) {
    if ( aQuizControl[qtfield] == 1) {
        this.resetForm([qtfield+"SanityCheck"]);
        for ( var i=0; i < nQuestions; i++ ) {
            var f=this.getField(qtfield+"SanityCheck."+(i+1));
            f.checkThisBox(0,(typeof Responses[i+1]!="undefined"));
        }
    }
}
%    \end{macrocode}
% \DescribeMacro{fieldPopTbl} is called when there is a change in a response.
% it gets info contained in a button embedded in the summary table (\texttt{nQuestions})
% and then calls \texttt{popVisitsTbl()}.
%    \begin{macrocode}
function fieldPopTbl(qtfield) {
    var f=this.getField(qtfield+"activateSC");
    if ( f != null) {
        var n=Number(f.userName);
        var a = [ qtfield, n ];
        popVisitsTbl.apply(null,a);
    }
}
\end{insDLJS}
%</sumrytbls>
%<*mcfi>
\newcommand{\clickChkBxMCFI}{"Click the check box preceding this
    math input field to enter text."}
\begin{insDLJS}{mcf}{Eq: Supports MCFI-type questions}
function mcfiKeyStroke(qname,n) {
    if (event.change=="") return;
    var qNumMC=--n;
    var mcName="mc."+qname+"."+qNumMC;
    var mc= this.getField(mcName);
    var aExpVs=mc.exportValues;
    var l=aExpVs.length-1;
    if (!mc.isBoxChecked(l)) {
        eqAppAlert(\clickChkBxMCFI,3);
        event.rc=false;
    }
}
function qRadioButtonMCFI(key,qname,n) {
    var fname = "obj."+qname+"."+(n+1);
    if ( key == 0) this.resetForm(fname);
}
\end{insDLJS}
%</mcfi>
%    \end{macrocode}
%    \section{Language Definitions}
% \StopEventually{Comment out \cs{OnlyDescription}
%   at the beginning of this file to see the language code.}
%    \subsection{French}
%    \begin{macrocode}
%<*eqfr>
%    \end{macrocode}
%    \begin{macrocode}
%%%%%%%%%%%%%%%%%%%%%%% eqfr.def %%%%%%%%%%%%%%%%%%%%%%%
%% Foreign language support for the exerquiz package. %%
%% Name of translator: Jean-Michel SARLAT             %%
%% Language: French                                   %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Exercise label
\renewcommand\exlabel{Exercice}
% The value of this macro is written to \jobname.sol,
% accented characters must be protected with a \protect
\renewcommand\exlabelsol{\exlabel}

% Solution label for solutionafter option for exercise
\renewcommand{\eq@exsolafterDefault}{\textit{Solution} :}

% Title of exercise solution section
\renewcommand\exsectitle{Solutions des \exlabelsol s}
\renewcommand\exsecrunhead{\exsectitle}

% Title of quiz solution section
\renewcommand\eq@sqslsectitle{Les r\'{e}ponses aux questionnaires}
\renewcommand\sqslsectitle{\eq@sqslsectitle}

% Running header/section title for solutions to quizzes
\renewcommand\eq@sqslsecrunhead{Les r\'{e}ponses aux questionnaires}
% User access
\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}

% Label for solutions to quizzes, appears in solutions sections
\renewcommand\eq@sqsllabel{%
   \protect\textbf{R\protect\'{e}ponse :}}
\renewcommand\sqsllabel{\eq@sqsllabel}% User access

% Solution label for solutionafter option for shortquiz
\renewcommand\sqsolafter{\textit{Solution} :}

% Here is the default short quiz label.
\renewcommand\eq@sqlabel{\textcolor{red}{Question.}}
% User access to shortquiz label
\renewcommand\sqlabel{\eq@sqlabel}

% Here is the default short quiz return label
% No formatting allowed
\renewcommand\eq@sqslrtnlabel{Retour au questionnaire.}
% User access to shortquiz label
\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}

% Short quiz feedback messages
\renewcommand\eqsqrtmsg{"Exact !"}
\renewcommand\eqsqwgmsg{"Faux !"}

% Here is the default quiz label. No formatting allowed!
\renewcommand\eq@bqlabel{D\'ebut}
% User access to shortquiz label
\renewcommand\bqlabel{\eq@bqlabel}
%==> modif JMS <==%
% Les modifications du contenu de \eqlabel ne seront pas prises en
% compte dans les messages de javascript (pb pour faire passer les
% accents dans le code !). Ceci justifie pour moi l'introduction de
% la variable \bqlabelISO ou le label de debut de questionnaire est
% cod\'{e}  ISO (octal). Cela parce que je veux utiliser le mot D\'ebut.
% Use \protect\351, this helps out TeX4ht by Eitan Gurari
\renewcommand\eq@bqlabelISO{D\string\351but}
\renewcommand\bqlabelISO{\eq@bqlabelISO}

% Here is the default quiz label.
\renewcommand\eq@eqlabel{Fin}
% User access to shortquiz label
\renewcommand\eqlabel{\eq@eqlabel}
%
% JavaScript Messages for Quiz Environments
\renewcommand\eq@Score{Score :}\renewcommand\eq@OutOf{sur}
\renewcommand\eqInitQuizMsg{%
   "Vous devez initialiser le questionnaire ! Clicker sur "+msg+"."}
\renewcommand\eqMadeChoice{
   "Vous avez d\string\\351j\string\\340 fait un choix,"
   + " ce choix est ("+Responses[probno]+")."
   + " Souhaitez vous le modifier ?"}
%
% Valeur "Yes" d'Acrobat
%
% Default button labels for \eqButton
%\renewcommand\eq@local@CA{R\string\351ponses}
\renewcommand\eq@local@CA{%
    R\texorpdfstring{\'}{\string\351}ponses}
\renewcommand\eq@local@RC{Correctes}
\renewcommand\eq@local@AC{SVP !}
\dlJSStr*[noquotes]{\limSelWarningMsg}{"Pour cette question,
  vous \u00EAtes autoris\'{e} \`{a} faire au plus "
  + n + " s\'{e}lections."}
%</eqfr>
%    \end{macrocode}
%    \subsection{German}
%    \begin{macrocode}
%<*eqde>
%    \end{macrocode}
%    \begin{macrocode}
%%%%%%%%%%%%%%%%%%%% eqde.def %%%%%%%%%%%%%%%%%%%%%%%%%%
%% Foreign language support for the exerquiz package. %%
%% Name of translator: Michael Wiedmann               %%
%% e-mail address: michael.wiedmann@detewe.de         %%
%% Language: German                                   %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% The exercise label
\renewcommand\exlabel{\"Ubung}
% The value of this macro is written to \jobname.sol,
% accented characters must be protected with a \protect
\renewcommand\exlabelsol{\protect\"Ubung}

% Title of exercise solution section
\renewcommand\exsectitle{L\"osungen der \exlabel en}
\renewcommand\exsecrunhead{L\protect\"osungen der \exlabelsol en}

% Solution label for solutionafter option
\renewcommand{\eq@exsolafterDefault}{\textit{L\"osung}:}

% Title of quiz solution section
\renewcommand\eq@sqslsectitle{L\"osungen der Aufgaben}
\renewcommand\sqslsectitle{\eq@sqslsectitle}

% Running header/section title for solutions to quizzes
%\renewcommand\eq@sqslsecrunhead{L\"osungen der \"Ubungen}
\renewcommand\eq@sqslsecrunhead{L\"osungen der Aufgaben}
% User access
\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}

% Label for solutions to quizzes, appears in solutions sections
\renewcommand\eq@sqsllabel{%
   \protect\textbf{L\protect\"osung zu Aufgabe:}}
% User access
\renewcommand\sqsllabel{\eq@sqsllabel}

% Solution label for solutionafter option for shortquiz
\renewcommand\sqsolafter{\textit{L\"osung}:}

% Here is the default short quiz label.
\renewcommand\eq@sqlabel{\textcolor{red}{Aufgabe}}
% User access to shortquiz label
\renewcommand\sqlabel{\eq@sqlabel}

% Here is the default short quiz return label
%\renewcommand\eq@sqslrtnlabel{Ende Aufgabe}
%\renewcommand\eq@sqslrtnlabel{Test beenden}
\renewcommand\eq@sqslrtnlabel{zur\"{u}ck zur Aufgabe}
% User access to shortquiz label
\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}

% Short quiz feedback messages
\renewcommand\eqsqrtmsg{"Richtig!"}
\renewcommand\eqsqwgmsg{"Falsch!"}

% Here is the default quiz label.
%\renewcommand\eq@bqlabel{Beginn Aufgabe}
\renewcommand\eq@bqlabel{Test starten}
% User access to quiz label
\renewcommand\bqlabel{\eq@bqlabel}
% Used for writing JavaScript Messages on screen. Use PDFDocEncoding
\renewcommand\eq@bqlabelISO{\eq@bqlabel}
\renewcommand\bqlabelISO{\eq@bqlabelISO}

% Here is the default quiz label.
%\renewcommand\eq@eqlabel{Ende Aufgabe}
\renewcommand\eq@eqlabel{Test beenden}
% User access to quiz label
\renewcommand\eqlabel{\eq@eqlabel}
%
% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
%
\renewcommand\eq@Score{Punkte:}\renewcommand\eq@OutOf{von}
\renewcommand\eq@ptScore{Punkte:}
\renewcommand\eqInitQuizMsg{%
   "Sie m\374ssen die Aufgaben zuerst initialisieren!"
   + " Bitte klicken Sie hierf\374r auf "+msg+" am Anfang des Tests."}
\renewcommand\eqMadeChoice{%
   "Sie haben bereits geantwortet. Ihre Antwort war
   ("+Responses[probno]+")." + " Wollen Sie dies \string\344ndern?"}
\renewcommand\eq@local@CA{Korrigiere}
\renewcommand\eq@local@RC{Meine Antworten!}
\renewcommand\eq@local@AC{Bitte!}
\renewcommand{\AnsPromptBtnStr}{Antwort:\space}
\renewcommand\eqerrABS{"Betr\string\344ge sind nicht ausgeglichen.
    Bitte korrigieren Sie das."}
\renewcommand\eqerrBadMathFunc{"Der Ausdruck '"+aF[i]+"' ist weder
    eine definierte Funktion noch ein g\string\374ltiger mathematischer
    Ausdruck."}
\renewcommand\eqParens{"runde Klammern"} % ( )
\renewcommand\eqBrackets{"eckige Klammern"} % [ ]
\renewcommand\eqBraces{"geschweifte Klammern"} % { }
\renewcommand\eqerrDelimNotBal{aGroup[i][2] + " sind nicht ausgeglichen.
    Bitte korrigieren Sie das."}
\renewcommand\eqerrBadExp{"Ung\string\374ltiger mathematischer Ausdruck.
     Es gibt ein Problem mit einem der Exponenten.
     Bitte korrigieren Sie das!"}
\renewcommand\eqerrUnfinishQuiz{"Sie haben einen Test nicht beendet.
    Bitte beenden Sie diesen, bevor Sie einen neuen Test beginnen."}
\dlJSStr*[noquotes]{\noPeekMsg}{"Bevor Sie den Test nicht beendet
    haben, ist es nicht erlaubt, die L\"{o}sungen anzuschauen!"}
\renewcommand\highThresholdMsg{"Sie m\string\374ssen alle Fragen
    beantworten, bevor der Test ausgewertet wird."}
\dlJSStr*[noquotes]{\eqSyntaxErrorUndefVar}{"Syntax Error: Es existiert
    m\"{o}glicherweise eine undefinierte Variable oder ein Ausdruck
    ist nicht im erwarteten Format geschrieben."}
\dlJSStr[noquotes]{\eqSyntaxErrorComma}{"Syntax Error: Ein Komma wurde"
    + " in Ihrer Antwort \""
    + UserAns + "\" gefunden. Bitte entfernen Sie das Komma,"
    + " sonst wird diese Antwort als falsch gewertet."}
\dlJSStr*[noquotes]{\limSelWarningMsg}{"F\"{u}r diese Aufgabe k\"{o}nnen
    sie h\"{o}chstens " + n + " ausw\string\344hlen."}
\flJSStr*[noquotes]{\promptButtonMsg}{%
    "M\"{o}chten Sie die richtige Antwort jetzt sehen?"
    + " Ihre derzeitige Antwort ist diejenige, die gewertet wird."
    + " Wenn Sie auf \\"Yes\\" klicken, k\"{o}nnen Sie ihre Antwort
    nicht mehr \string\344ndern."
}
\renewcommand{\defaultReqFormMsg}{%
    "Der Ausdruck ist nicht in der erwarteten Form."}
%</eqde>
%    \end{macrocode}
%    \subsection{Norwegian}
%    \begin{macrocode}
%<*eqno>
%%%%%%%%%%%%%%%%%%%% eqno.def %%%%%%%%%%%%%%%%%%%%%%%%%%
%% Foreign language support for the exerquiz package. %%
%% Name of translator: Hans Fredrik Nordhaug          %%
%% e-mail address: hansfn@mi.uib.no                   %%
%% Language: Norwegian                                %%
%%                                                    %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\renewcommand\exlabel{{\O}velse}
\renewcommand\exlabelsol{{\protect\O}velse}

\renewcommand\exsectitle{L{\o}sning p{\aa} {\o}velsene}
\renewcommand\exsecrunhead{L{\protect\o}sning p{\protect\aa}
   {\protect\o}velsene}

\renewcommand{\eq@exsolafterDefault}{\textit{L{\o}sning}:}

\renewcommand\eq@sqslsectitle{L{\o}sning p{\aa} oppgavene}
\renewcommand\sqslsectitle{\eq@sqslsectitle}

\renewcommand\eq@sqslsecrunhead{L{\o}sning p{\aa} oppgavene}
\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}

\renewcommand\eq@sqsllabel{%
    \protect\textbf{L{\protect\o}sning p{\protect\aa} oppgave:}}
\renewcommand\sqsllabel{\eq@sqsllabel}

\renewcommand\sqsolafter{\textit{L{\o}sning}:}

\renewcommand\eq@sqlabel{\textcolor{red}{Oppgave}}
\renewcommand\sqlabel{\eq@sqlabel}

\renewcommand\eq@sqslrtnlabel{Slutt}
\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}

\renewcommand\eqsqrtmsg{"Rett!"}
\renewcommand\eqsqwgmsg{"Feil!"}

\renewcommand\eq@bqlabel{Start oppgaver}
\renewcommand\bqlabel{\eq@bqlabel}
\renewcommand\eq@bqlabelISO{\eq@bqlabel}
\renewcommand\bqlabelISO{\eq@bqlabel}

\renewcommand\eq@eqlabel{Slutt}
\renewcommand\eqlabel{\eq@eqlabel}

\renewcommand\eqScore{Poeng:}\renewcommand\eqOutOf{av}
\renewcommand\eqInitQuizMsg{"Du m\string\\345 initialisere testen!"
+" Klikk p\string\\345 "+msg+"."}
\renewcommand\eqMadeChoice{%
    "Du har allerede gjort et valg.
     Valget var ("+Responses[probno]+").
     Vil du endre det?"}
\renewcommand\eq@local@CA{Rett}
\renewcommand\eq@local@RC{mine svar!}
%\renewcommand\eq@local@AC{V\string\346r s\string\345 snill!}}
\renewcommand\eq@local@AC{%
    V\texorpdfstring{\ae}{\string\346}r
    s\texorpdfstring{\r}{\string\345}snill!}
\dlJSStr*[noquotes]{\limSelWarningMsg}{"For dette sp\string\370rsm\string\345let
  har du lov til \string\345 gj\string\370re p\string\345 det meste "
  + n + " valg."}
%</eqno>
%    \end{macrocode}
%    \subsection{Dutch}
%    \begin{macrocode}
%<*eqnl>
%%%%%%%%%%%%%%%%%%% eqnl.def %%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Foreign language support for the exerquiz package. %%
%% Name of translator: Henny Wilbrink                 %%
%% e-mail address: wsdwhw@win.tue.nl                  %%
%% Language: Dutch                                    %%
%%                                                    %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% The exercise label
\renewcommand\exlabel{Opgave}
\renewcommand\exlabelsol{\exlabel}

% Title of exercise solution section
\renewcommand\exsectitle{Oplossingen van de Opgaven}
\renewcommand\exsecrunhead{\exsectitle}

% Solution label for solutionafter option for exercise
\renewcommand{\eq@exsolafterDefault}{\textit{Oplossing}:}

% Title of short quiz solution section
\renewcommand\eq@sqslsectitle{Oplossingen van de Toetsen}
\renewcommand\sqslsectitle{\eq@sqslsectitle}

% Running header/section title for solutions to short quizzes
\renewcommand\eq@sqslsecrunhead{Oplossingen van de Toetsen}
% User access
\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}

% Solution label for solutionafter option
\renewcommand{\eq@exsolafterDefault}{\textit{Oplossing}:}

% Label for solutions to short quizzes, appears in solutions sections
\renewcommand\eq@sqsllabel{\string\textbf{Oplossing van Toets:}}
% User access
\renewcommand\sqsllabel{\eq@sqsllabel}

% Solution label for solutionafter option for shortquiz
\renewcommand\sqsolafter{\textit{Oplossing}:}

% Here is the default short quiz label.
\renewcommand\eq@sqlabel{\textcolor{red}{Toets.}}
% User access to shortquiz label
\renewcommand\sqlabel{\eq@sqlabel}

% Here is the default short quiz return label
\renewcommand\eq@sqslrtnlabel{Terug naar Toets}
% User access to shortquiz label
\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}

% Short quiz feedback messages
\renewcommand\eqsqrtmsg{"Goed!"}
\renewcommand\eqsqwgmsg{"Fout!"}

% Here is the default quiz label.
\renewcommand\eq@bqlabel{Begin Toets}
% User access to shortquiz label
\renewcommand\bqlabel{\eq@bqlabel}
% Used for writing JavaScript Messages on screen. Use PDFDocEncoding
\renewcommand\eq@bqlabelISO{\eq@bqlabel}
\renewcommand\bqlabelISO{\eq@bqlabel}

% Here is the default quiz label.
% No formatting allowed
\renewcommand\eq@eqlabel{Einde Toets}
% User access to shortquiz label
\renewcommand\eqlabel{\eq@eqlabel}

%
% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
%
\renewcommand\eq@Score{Score:}\renewcommand\eq@OutOf{van de}

\renewcommand\eqInitQuizMsg{%
  "U moet de Toets initialiseren! Klik op "+msg+"."}
\renewcommand\eqMadeChoice{%
   "U hebt al een keuze gemaakt.
    Uw keuze was ("+Responses[probno]+").
    Wil u dit veranderen?"}
%
% Default button labels for \eqButton
\renewcommand\eq@local@CA{Corrigeer}
\renewcommand\eq@local@RC{Mijn Antwoorden!}
\renewcommand\eq@local@AC{AUB!}
\dlJSStr*[noquotes]{\limSelWarningMsg}{"Voor deze vraag mag je maximaal "
  + n + " selecties maken."}
%</eqnl>
%    \end{macrocode}
%    \subsection{Spanish}
%    \begin{macrocode}
%<*eqes>
%%%%%%%%%%%%%%%%%%% eqes.def %%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Foreign language support for the exerquiz package. %%
%% Name of translator: Pedro Luis Luque               %%
%% e-mail address: calvo@cica.es                      %%
%% Language:  (spanish)                               %%
%%                                                    %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% The exercise label
\renewcommand\exlabel{Ejercicio}
% The value of this macro is written to \jobname.sol,
\renewcommand\exlabelsol{\exlabel}

% Title of exercise solution section
\renewcommand\exsectitle{Soluciones a los \exlabel s}
\renewcommand\exsecrunhead{\exsectitle} %% change to @ form

% Solution label for solutionafter option for exercise
\renewcommand{\eq@exsolafterDefault}{\textit{Soluci\'{o}n}:}

% Title of short quiz solution section
\renewcommand\eq@sqslsectitle{Soluciones a los Tests}
\renewcommand\sqslsectitle{\eq@sqslsectitle}

% Running header/section title for solutions to short quizzes
\renewcommand\eq@sqslsecrunhead{Soluciones a los Tests}
% User access
\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}

% Label for solutions to short quizzes, appears in solutions sections
\renewcommand\eq@sqsllabel{%
  \string\textbf{Soluci\protect\'{o}n al Test:}}
% User access
\renewcommand\sqsllabel{\eq@sqsllabel}

% Solution label for solutionafter option for shortquiz
\renewcommand\sqsolafter{\textit{Soluci\'{o}n}:}

% Here is the default short quiz label.
\renewcommand\eq@sqlabel{\textcolor{red}{Test.}}
% User access to shortquiz label
\renewcommand\sqlabel{\eq@sqlabel}

% Here is the default short quiz return label
\renewcommand\eq@sqslrtnlabel{Final del Test}
% User access to shortquiz label
\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}

% Short quiz feedback messages
\renewcommand\eqsqrtmsg{"Correcto!"}
\renewcommand\eqsqwgmsg{"Incorrecto!"}

% Here is the default quiz label.
\renewcommand\eq@bqlabel{Inicio del Test}
% User access to shortquiz label
\renewcommand\bqlabel{\eq@bqlabel}
% Used for writing JavaScript Messages on screen. Use PDFDocEncoding
\renewcommand\eq@bqlabelISO{\eq@bqlabel}
\renewcommand\bqlabelISO{\eq@bqlabel}

% Here is the default quiz label.
% No formatting allowed
\renewcommand\eq@eqlabel{Final del Test}
% User access to shortquiz label
\renewcommand\eqlabel{\eq@eqlabel}
%
% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
%
\renewcommand\eq@Score{Puntos:}\renewcommand\eq@OutOf{de}
\renewcommand\eqInitQuizMsg{"Debes inicializar el Test!
    Click sobre "+msg+"."}
\renewcommand\eqMadeChoice{%
   "Ya has elegido una respuesta.
    Tu respuesta fue ("+Responses[probno]+").
    Quieres cambiarla?"}
%
% Default button labels for \eqButton
\renewcommand\eq@local@CA{Correctas}
\renewcommand\eq@local@RC{Mis Respuestas!}
\renewcommand\eq@local@AC{Por Favor!}
\dlJSStr*[noquotes]{\limSelWarningMsg}{"Para esta pregunta,
  se le permite hacer como m\'{a}ximo "
  + n + " selecciones."}
%</eqes>
%    \end{macrocode}
%    \subsection{Italian}
%    \begin{macrocode}
%<*eqit>
%%%%%%%%%%%%%%%%%%% eqit.def %%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Foreign language support for the exerquiz package. %%
%% Name of translator:  PierLuigi Zezza               %%
%% e-mail address:  pzezza@cce.unifi.it               %%
%% Language: Italian                                  %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The exercise label
\renewcommand\exlabel{Esercizio}
%
% The value of this macro is written to \jobname.sol,
\renewcommand\exlabelsol{\exlabel}
%
% Title of exercise solution section
\renewcommand\exsectitle{Soluzioni degli Esercizi }
\renewcommand\exsecrunhead{\exsectitle}
%
% Solution label for solutionafter option for exercise
\renewcommand{\eq@exsolafterDefault}{\textit{Soluzione}:}
%
% Title of short quiz solution section
\renewcommand\eq@sqslsectitle{Soluzioni dei Quiz}
\renewcommand\sqslsectitle{\eq@sqslsectitle}
%
% Running header/section title for solutions to short quizzes
\renewcommand\eq@sqslsecrunhead{Soluzioni dei Quiz}
%
% User access
\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
%
% Label for solutions to short quizzes, appears in solutions sections
\renewcommand\eq@sqsllabel{\string\textbf{Soluzione del Quiz:}}
%
% User access
\renewcommand\sqsllabel{\eq@sqsllabel}
%
% Solution label for solutionafter option for shortquiz
\renewcommand\sqsolafter{\textit{Soluzione}:}
%
% Here is the default short quiz label.
\renewcommand\eq@sqlabel{\textcolor{red}{Quiz.}}
%
% User access to shortquiz label
\renewcommand\sqlabel{\eq@sqlabel}
%
% Here is the default short quiz return label
\renewcommand\eq@sqslrtnlabel{Fine Quiz}
%
% User access to shortquiz label
\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
%
% Short quiz feedback messages
\renewcommand\eqsqrtmsg{"Giusto!"}
\renewcommand\eqsqwgmsg{"Sbagliato!"}
%
% Here is the default quiz label.
% No formatting allowed
\renewcommand\eq@bqlabel{Inizio Test}
%
% User access to shortquiz label
\renewcommand\bqlabel{\eq@bqlabel}
\renewcommand\eq@bqlabelISO{\eq@bqlabel}
\renewcommand\bqlabelISO{\eq@bqlabel}
%
% Here is the default quiz label.
% No formatting allowed
\renewcommand\eq@eqlabel{Fine Test}
%
% User access to shortquiz label
\renewcommand\eqlabel{\eq@eqlabel}
%
% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
%
\renewcommand\eq@Score{Punteggio:}\renewcommand\eq@OutOf{su}
\renewcommand\eqInitQuizMsg{"Dovete inizializzare il Quiz!
    Click su "+msg+"."}
\renewcommand\eqMadeChoice{%
   "Avete gi\string\\340 fatto una scelta.
    La vostra scelta era ("+Responses[probno]+").
    Volete cambiarla ?"}
%
% Default button labels for \eqButton
\renewcommand\eq@local@CA{Correggere}
\renewcommand\eq@local@RC{Le mie risposte!}
\renewcommand\eq@local@AC{Per favore!}
\dlJSStr*[noquotes]{\limSelWarningMsg}{"Per questa domanda,
  \`{e} possibile effettuare al massimo "
  + n + " selezioni."}
%</eqit>
%    \end{macrocode}
%    \subsection{Russian}
%    \begin{macrocode}
%<*eqru>
%%%%%%%%%%%%%%%%%%% eqru.def %%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Foreign language support for the exerquiz package. %%
%% Name of translator:  Sergei V. Znamenskii          %%
%% e-mail address:  znamensk@rustex.botik.ru          %%
%% Language: Russian                                  %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\PassOptionsToPackage{unicode}{hyperref}
\expandafter\ifx\csname inputencoding\endcsname\relax
	\RequirePackage{inputenc}\fi
\inputencoding{cp1251}\makeatletter
\expandafter\ifx\csname Russian\endcsname\relax
	\RequirePackage[russian]{babel}\fi
% Language dependent definitions for Web.sty
    \def\web@versionlabel{\^{A}{\aa}ð\~{n}\`{e}\"{y}}%
    \def\web@toc{\~{N}\^{\i}\"{a}{\aa}ð{\ae}\`{a}\'{\i}\`{e}{\aa}}%
    \def\web@continued{\"{\i}ð\^{\i}\"{a}\^{\i}\"{e}{\ae}.}%
    \def\web@article{\'{I}\`{a}{\div}\`{a}\"{e}\^{\i}
        \hyperlink{section.1}{}}%
    \def\web@directory{\"{I}\`{a}\"{\i}\^{e}\`{a}}%
    \def\web@revision{\"{A}\`{a}\`{o}\`{a} \"{\i}\^{\i}\~{n}\"{e}%
        {\aa}\"{a}\'{\i}{\aa}\~{a}\^{\i} \`{e}\c{c}\`{\i}{\aa}%
        \'{\i}{\aa}\'{\i}\`{e}\"{y}:}%
    \def\web@copyright{\^{E}\^{\i}\"{\i}\`{e}ð\`{a}\'{e}\`{o}}%
    \def\web@section{\textsection\ }%
    % Label Navibar
    \def\web@back{\'{I}\`{a}\c{c}\`{a}\"{a}}%
    \def\web@doc{\"{A}\^{\i}\^{e}.}% restricted to three characters

% The exercise label
% Accents: \renewcommand\exlabel{\"Ubung} (German)
\renewcommand\exlabel{\'{O}\"{\i}ð\`{a}{\ae}\'{\i}{\aa}\'{\i}\`{e}{\aa}}
% The value of this macro is written to \jobname.sol,
% accented characters must be protected with a \protect
% E.g., \renewcommand\exlabelsol{\protect\"Ubung} (German)
\renewcommand\exlabelsol{\^{E} \'{o}\"{\i}ð\`{a}{\ae}%
    \'{\i}{\aa}\'{\i}\`{e}þ}

% Title of exercise solution section
% E.g.: \renewcommand\exsectitle
%            {L\"osungen der \exlabel en} (German)
\renewcommand\exsectitle{Ð{\aa}{\o}{\aa}\'{\i}\`{e}\"{y}
    \'{o}\"{\i}ð\`{a}{\ae}\'{\i}{\aa}\'{\i}\`{e}\'{e}}
\renewcommand\exsecrunhead{\exsectitle} %% change to @ form

% Solution label for solutionafter option for exercise
\renewcommand\exsolafter{\textit{Ð{\aa}{\o}{\aa}\'{\i}\`{e}{\aa}}:}

% Title of short quiz solution section
% Example: \renewcommand\eq@sqslsectitle
%               {L\"osungen der Aufgaben} (German)
\renewcommand\eq@sqslsectitle{\^{I}\`{o}\^{a}{\aa}\`{o}\^{u}
    \^{e} \`{o}{\aa}\~{n}\`{o}\`{a}\`{\i}}
\renewcommand\sqslsectitle{\eq@sqslsectitle}

% Running header/section title for solutions to short quizzes
\renewcommand\eq@sqslsecrunhead{\^{I}\`{o}\^{a}{\aa}\`{o}\^{u}
    \^{e} \^{e}\^{\i}ð\^{\i}\`{o}\^{e}\`{e}\`{\i}
    \`{o}{\aa}\~{n}\`{o}\`{a}\`{\i}}
% User access
\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}

% Label for solutions to short quizzes, appears
% in solutions sections
% Protect accents with \protect
% E.g.: \renewcommand\eq@sqsllabel
%       {\string\textbf{L\protect\"osung zu Aufgabe:}} (German)
\renewcommand\eq@sqsllabel{%
    \string\textbf{\^{I}\`{o}\^{a}{\aa}\`{o}\^{u}:}}
% User access
\renewcommand\sqsllabel{\eq@sqsllabel}

% Solution label for solutionafter option for shortquiz
\renewcommand\sqsolafter{\textit{Ð{\aa}{\o}{\aa}\'{\i}\`{e}{\aa}}:}

% Here is the default short quiz label.
\renewcommand\eq@sqlabel{%
    \textcolor{red}{\c{C}\`{a}\"{a}\`{a}\'{\i}\`{e}{\aa}.}}
% User access to shortquiz label
\renewcommand\sqlabel{\eq@sqlabel}

% Here is the default short quiz return label
% No formatting allowed
\renewcommand\eq@sqslrtnlabel{\^{a}{\aa}ð\'{\i}\'{o}\`{o}\"{u}\~{n}\"{y}}
% User access to shortquiz label
\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
\cyrCommand\eqsqslrtnlabel{\^{E} \^{o}\^{\i}ð\`{\i}\'{o}\"{e}%
    \`{e}ð\^{\i}\^{a}\^{e}{\aa} \c{c}\`{a}\"{a}\`{a}\'{\i}\`{e}\"{y}}
\renewcommand\eq@sqslrtnlabel{\eqsqslrtnlabel}
% Here is the default quiz label.
% No formatting allowed
% For Example: \renewcommand\eq@bqlabel{D\'ebut}  (French)
\renewcommand\eq@bqlabel{CTAPT}
% User access to shortquiz label
\renewcommand\bqlabel{\eq@bqlabel}
% Used for writing JavaScript Messages on screen.
% Use PDFDocEncoding
% For Example:
% \renewcommand\eq@bqlabelISO{D\string\351but}  (French)
% Use \string not \protect, this helps out
% TeX4ht by Eitan Gurari.
\renewcommand\eq@bqlabelISO{\eq@bqlabel}
\renewcommand\bqlabelISO{\eq@bqlabel}

% Here is the default quiz label.
% No formatting allowed
\renewcommand\eq@eqlabel{\^{O}\`{E}\'{I}\`{E}{\O}}
% User access to shortquiz label
\renewcommand\eqlabel{\eq@eqlabel}
\def\ScoreFieldDefaults
{%
    \Ff{\FfReadOnly}\BC{1 0 0}\BG{}\S{S}
    \DV{\^{A}{\aa}ð\'{\i}\^{\i}:}\W{1}
}
% Default button labels for \eqButton
\renewcommand\eq@local@CA{\`{E}\~{n}\"{\i}ð\`{a}\^{a}\`{e}\`{o}\"{u}}
\renewcommand\eq@local@RC{\`{\i}\^{\i}\`{e} \^{\i}\`{o}\^{a}{\aa}%
    \`{o}\^{u}!}
\renewcommand\eq@local@AC{\"{I}\^{\i}{\ae}\`{a}\"{e}\'{o}\'{e}\~{n}%
    \`{o}\`{a}!}
%
% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
% In the Text Field showing the score, there is the default phrase in
% English Score: 2 out of 3, the word "Score" and "out of" needs
% translation.
%% In Cyrillic, at least with pdflatex v.1.40.3 , the same \eq@Score
%% unfortunately can not serve both \ScoreFieldDefaults and
%% \eqQuizTotalMsg.

\renewcommand\eq@Score{\u0412\u0435\u0440\u043D\u043E:}
\renewcommand\eq@OutOf{\u0438\u0437}

% Short quiz feedback messages
%\def\eq@sqrtmsg{"\u0412\u0435\u0440\u043D\u043E!"}
%\def\eq@sqwgmsg{"\u041E\u0448\u0438\u0431\u043A\u0430!"}
\def\eqsqrtmsg{"\u0412\u0435\u0440\u043D\u043E!"}
\def\eqsqwgmsg{"\u041E\u0448\u0438\u0431\u043A\u0430!"}

% If you are taking a quiz and click on an alternative without
% initializing the quiz first, this message appears.
% Example: \renewcommand\eqInitQuizMsg{"Sie m\string\\374ssen die
%   Aufgaben initialisieren! Bitte klicken Sie auf "+msg+"."}%(German)
\def\eqInitQuizMsg{"\u041A\u043B\u0438\u043A\u043D\u0438\u0442\u0435
    \u043D\u0430 \u00AB"+msg+"\u00BB, \u0447\u0442\u043E\u0431\u044B
    \u043D\u0430\u0447\u0430\u0442\u044C
    \u043E\u0442\u0432\u0435\u0442."}

% This macro doesn't usually need translation, it uses
% \eqScore and \eqOutOf. However, if the sentence "Score: 2 out of 3"
% does not translate conveniently into a particular language,
% this macro may have to be modified.  It's the one that puts the
% message in the message box.
% \renewcommand\eqQuizTotalMsg {"\eqScore\space"+Score+"
%   \eqOutOf\space"+nQuestions}
% \renewcommand\eqQuizPointsMsg{"\eqptScore\space"+ptScore+"
%   \eqOutOf\space"+nPointTotal}
% \renewcommand\eqQuizPercentMsg{pcScore+"\%"}
% \renewcommand\eqQuizGradeMsg{quizGrade}
% In the link form of a quiz, of you change your choice, this message
% appears.
% For Example: \renewcommand\eqMadeChoice{"Vous avez
% d\string\\351j\string\\340 fait un choix, ce choix est
% ("+Responses[probno]+"). Souhaitez vous le modifier ?"}%(French)
\renewcommand\eqMadeChoice{"\u0412\u044B \u0443\u0436\u0435
    \u0432\u044B\u0431\u0440\u0430\u043B\u0438
    \u043E\u0442\u0432\u0435\u0442
    ("+Responses[probno]+"). \u0418\u043B\u0438 \u0412\u044B
    \u043F\u0435\u0440\u0435\u0434\u0443\u043C\u0430\u043B\u0438?"}
% Default button label of \CorrAnsButton.
\renewcommand\eq@local@CorrAnsButton{Ans}
% These (error) messages are generated when the user enters an invalid
% math expression into a math fill-in response box. The messages come in
% the form of an eqAppAlert() so PDFDocEncoding needs to be used.
\renewcommand\eqerrABS{"\u0417\u043D\u0430\u043A\u0438
    \u0430\u0431\u0441\u043E\u043B\u044E\u0442\u043D\u043E\u0439
    \u0432\u0435\u043B\u0438\u0447\u0438\u043D\u044B \u043D\u0435
    \u0441\u0431\u0430\u043B\u0430\u043D\u0441\u0438\u0440\u043E\u0432%
    \u0430\u043D\u044B.
    \u0418\u0441\u043F\u0440\u0430\u0432\u044C\u0442\u0435,
    \u043F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430."}
\renewcommand\eqerrBadMathFunc{"\u0412\u044B\u0440\u0430\u0436\u0435%
    \u043D\u0438\u0435 `"+aF[i]+"' \u043D\u0435 \u044F\u0432\u043B%
    \u044F\u0435\u0442\u0441\u044F \u043D\u0438
    \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u043E\u0439 "
    +"\u0444\u0443\u043D\u043A\u0446\u0438\u0435\u0439,
    \u043D\u0438 \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D%
    \u044B\u043C\u043C\u0430\u0442\u0435\u043C\u0430\u0442\u0438\u0447%
    \u0435\u0441\u043A\u0438\u043C \u0432\u044B\u0440\u0430\u0436\u0435%
    \u043D\u0438\u0435\u043C."}
\renewcommand\eqParens{"\u041A\u0440\u0443\u0433\u043B\u044B\u0435
    \u0441\u043A\u043E\u0431\u043A\u0438"}
\renewcommand\eqBrackets{"\u041A\u0432\u0430\u0434\u0440\u0430\u0442%
    \u043D\u044B\u0435 \u0441\u043A\u043E\u0431\u043A\u0438"}
\renewcommand\eqBraces{"\u0424\u0438\u0433\u0443\u0440\u043D\u044B\u0435
    \u0441\u043A\u043E\u0431\u043A\u0438"}
\renewcommand\eqerrDelimNotBal{aGroup[i][2] + " \u043D\u0435
    \u0441\u0431\u0430\u043B\u0430\u043D\u0441\u0438\u0440%
    \u043E\u0432\u0430\u043D\u043E.
    \u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430,
    \u0438\u0441\u043F\u0440\u0430\u0432\u044C\u0442\u0435."}
\renewcommand\eqerrBadExp{"\u0418\u0441\u043F\u0440\u0430\u0432%
    \u044C\u0442\u0435, \u043F\u043E\u0436\u0430\u043B\u0443\u0439%
    \u0441\u0442\u0430, \u0432\u044B\u0440\u0430\u0436\u0435\u043D%
    \u0438\u0435 \u0441\u043E \u0441\u0442\u0435\u043F\u0435\u043D%
    \u044C\u044E."}
\renewcommand\eqerrUnfinishQuiz{"\u041F\u043E\u0436\u0430\u043B\u0443%
    \u0439\u0441\u0442\u0430, \u0437\u0430\u043A\u043E\u043D\u0447%
    \u0438\u0442\u0435 \u043D\u0430\u0447\u0430\u0442\u043E\u0435
    \u0440\u0430\u043D\u0435\u0435 \u0437\u0430\u0434\u0430\u043D%
    \u0438\u0435."}
\renewcommand\noPeekMsg{"\u0420\u0435\u0448\u0435\u043D\u0438\u044F
    \u043D\u0435 \u043F\u043E\u043A\u0430\u0436\u0443\u0442\u0441\u044F,
    \u043F\u043E\u043A\u0430 \u0437\u0430\u0434\u0430\u043D\u0438\u0435
    \u043D\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043A
    \u043E\u043D\u0447\u0435\u043D\u043E!"}
\renewcommand\highThresholdMsg{"\u0412\u044B \u043D\u0435
    \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u0435
    \u043E\u0446\u0435\u043D\u043A\u0438, \u043F\u043E\u043A\u0430
    \u043D\u0435 \u043E\u0442\u0432\u0435\u0442\u0438\u0442\u0435
    \u043D\u0430 \u0412\u0421\u0415 \u0432\u043E\u043F\u0440\u043E%
    \u0441\u044B."}
\renewcommand\eqSyntaxErrorUndefVar{"\u0421\u0438\u043D\u0442\u0430%
    \u043A\u0441\u0438\u0447\u0435\u0441\u043A\u0430\u044F
    \u043E\u0448\u0438\u0431\u043A\u0430:
    \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E,
    \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u0430\u044F
    \u043D\u0435 \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435%
    \u043D\u0430."}
%</eqru>
%    \end{macrocode}
%    \subsection{Danish}
%    \begin{macrocode}
%<*eqda>
%%%%%%%%%%%%%%%%%%%% eqda.def %%%%%%%%%%%%%%%%%%%%%%%%%%
%% Foreign language support for the exerquiz package. %%
%% Name of translator: Erik Leimand                   %%
%% e-mail address: buhlleimand@worldonline.dk         %%
%% Language: Danish                                   %%
%%                                                    %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\renewcommand\exlabel{{\O}velse}
\renewcommand\exlabelsol{{\protect\O}velse}

\renewcommand\exsectitle{L{\o}sning p{\aa} {\o}velserne}
\renewcommand\exsecrunhead{L{\protect\o}sning p{\protect\aa}
   {\protect\o}velserne}

\renewcommand{\eq@exsolafterDefault}{\textit{L{\o}sning}:}

\renewcommand\eq@sqslsectitle{L{\o}sning p{\aa} opgaverne}
\renewcommand\sqslsectitle{\eq@sqslsectitle}

\renewcommand\eq@sqslsecrunhead{L{\o}sning p{\aa} opgaverne}
\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}

\renewcommand\eq@sqsllabel{%
    \string\textbf{L{\protect\o}sning p{\protect\aa} opgave:}}
\renewcommand\sqsllabel{\eq@sqsllabel}

\renewcommand\sqsolafter{\textit{L{\o}sning}:}

\renewcommand\eq@sqlabel{\textcolor{red}{Opgave.}}
\renewcommand\sqlabel{\eq@sqlabel}

\renewcommand\eq@sqslrtnlabel{Slut}
\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}

\renewcommand\eqsqrtmsg{"Rigtigt!"}
\renewcommand\eqsqwgmsg{"Forkert!"}

\renewcommand\eq@bqlabel{Start opgaver}
\renewcommand\bqlabel{\eq@bqlabel}
\renewcommand\eq@bqlabelISO{\eq@bqlabel}
\renewcommand\bqlabelISO{\eq@bqlabel}

\renewcommand\eq@eqlabel{Slut}
\renewcommand\eqlabel{\eq@eqlabel}

\renewcommand\eq@Score{Score:}\renewcommand\eq@OutOf{ud af}
\renewcommand\eqQuizTotalMsg{"\eqScore\space"+Score+"
    \eqOutOf\space"+nQuestions}
\renewcommand\eqInitQuizMsg{"Du skal starte testen! Klik
    p\string\\345 "+msg+"."}
\renewcommand\eqMadeChoice{%
   "Du har allerede valgt.
    Du valgte ("+Responses[probno]+").
    Vil du \string\\346ndre det?"}
\renewcommand\eq@local@CA{Ret}
\renewcommand\eq@local@RC{Mine svar!}
%\renewcommand\eq@local@AC{V\string\346r s\string\345 god!}}
\renewcommand\eq@local@AC{%
    V\texorpdfstring{\ae}{\string\346}r
    s\texorpdfstring{\r}{\string\345}god!}
\dlJSStr*[noquotes]{\limSelWarningMsg}{"Til dette sp\string\370rgsm\string\345l,
  er du lov til at g\string\370re h\string\370jst "
  + n + " valg."}
%</eqda>
%    \end{macrocode}
%    \subsection{Polish}
%    \begin{macrocode}
%<*eqpo>
%%%%%%%%%%%%%%%%%%%% eqpo.def %%%%%%%%%%%%%%%%%%%%%%%%%%
%% Foreign language support for the exerquiz package. %%
%% Name of translator: Jerzy Mycielski                %%
%% e-mail address: jmyc@poczta.onet.pl                %%
%% Language: Polish                                   %%
%%                                                    %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% The polish accented characters included in pdfendconding is
%% lslash and oacute, not included are zacute, zdot, cacute,
%% nacute, sacute, aogonek, eogonek and corresponding capital
%% characters.
%  Z   \'{Z}  \u0179
%  a   \k{a}  \u0105
%  c   \'{c}  \u0107
%  l   \l     \u0142
%  s   \'{s}  \u015B
%  z   \.{z}  \u017C
%  \'{o}   \'{o}  \u00F3
\renewcommand\exlabel{Zadanie}
\renewcommand\exlabelsol{\exlabel}

\renewcommand\exsectitle{Rozwi\k{a}zania Zada\'{n}}
\renewcommand\exsecrunhead{\protect\exsectitle}

\renewcommand{\eq@exsolafterDefault}{\textit{Rozwi\k{a}znie}:}

\renewcommand\eq@sqslsectitle{Rozwi\k{a}zania Test\'{o}w}
\renewcommand\sqslsectitle{\eq@sqslsectitle}

\renewcommand\eq@sqslsecrunhead{Rozwi\protect\k{a}zania
    Test\protect\'{o}w}
\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}

\renewcommand\eq@sqsllabel{\string\textbf{Rozwi\protect\k{a}zanie
    Testu:}}
\renewcommand\sqsllabel{\eq@sqsllabel}

\renewcommand\sqsolafter{\textit{Rozwi\k{a}zanie}:}

\renewcommand\eq@sqlabel{\textcolor{red}{Test.}}
\renewcommand\sqlabel{\eq@sqlabel}

%\renewcommand\eq@sqslrtnlabel{Zako\protect\'{n}cz Test}
\renewcommand\eq@sqslrtnlabel{Zako\ifeq@solutionsafter\else
    \expandafter\protect\fi\'{n}cz Test}
\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}

\renewcommand\eqsqrtmsg{"Dobrze!"}
\renewcommand\eqsqwgmsg{"\string\\u0179le!"}
%\renewcommand\eqsqwgmsg{"\'{Z}le!"}

\renewcommand\eq@bqlabel{Rozpocznij Test}
\renewcommand\bqlabel{\eq@bqlabel}
\renewcommand\eq@bqlabelISO{\eq@bqlabel}
\renewcommand\bqlabelISO{\eq@bqlabel}

\renewcommand\eq@eqlabel{Zakoncz Test}
% \renewcommand\eq@eqlabel{Zako\'{n}cz Test}
\renewcommand\eqlabel{\eq@eqlabel}

\renewcommand\eq@Score{Punkt\'{o}w:}
\renewcommand\eq@OutOf{z mozliwych}
\renewcommand\eqQuizTotalMsg{"\eqScore\space"+Score +
    " \eqOutOf\space"+nQuestions}

\renewcommand\eqInitQuizMsg{"Musisz rozpoczac Test! Kliknij
    na "+msg+"."}

\renewcommand\eqMadeChoice{%
   "Juz dokonal\string\\233e\string\\u015B wyboru.
    Twoim wyborem by\string\\233o ("+Responses[probno]+").
    Czy chcesz go zmieni\string\\u0107?"}
%\renewcommand\eqMadeChoice{%
%"Ju\.{z} dokona\string\233e\'{s} wyboru. Twoim wyborem"
%+" by\string\233o ("+Responses[probno]+")."+" Czy chcesz go
%zmieni\'{c}?"}

\renewcommand\eq@local@CA{Popraw}
\renewcommand\eq@local@RC{Moje odpowiedzi!}
\renewcommand\eq@local@AC{Prosze!}
%\renewcommand\eq@local@AC{Prosz\k{e}!}
\dlJSStr*[noquotes]{\limSelWarningMsg}{"Na to pytanie,
  mo\u017Cesz dokona\u0107 co najwy\u017Cej  "
  + n + " wybor\string\363w."}
%</eqpo>
%    \end{macrocode}
%    \subsection{Finnish}
%    \begin{macrocode}
%<*eqfin>
%%%%%%%%%%%%%%%%%%%% eqfin.def %%%%%%%%%%%%%%%%%%%%%%%%%%
%% Foreign language support for the exerquiz package.  %%
%% Name of translator: Paivi Porras                    %%
%% e-mail address: paivi.porras@lut.fi                 %%
%% Language: Finnish                                   %%
%%                                                     %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\renewcommand\exlabel{Harjoitus}
\renewcommand\exlabelsol{Harjoitus}

\renewcommand\exsectitle{Ratkaisut}
\renewcommand\exsecrunhead{Ratkaisu \exlabelsol }

\renewcommand{\eq@exsolafterDefault}{\textit{Ratkaisu}:}

\renewcommand\eq@sqslsectitle{Vastaukset testikysymyksiin}
\renewcommand\sqslsectitle{\eq@sqslsectitle}

\renewcommand\eq@sqslsecrunhead{Vastaukset testikysymyksiin}
\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}

\renewcommand\eq@sqsllabel{%
   \string\textbf{Vastaus testikysymykseen:}}
\renewcommand\sqsllabel{\eq@sqsllabel}

\renewcommand\sqsolafter{\textit{Ratkaisu}:}

\renewcommand\eq@sqlabel{\textcolor{red}{Testikysymys}}
\renewcommand\sqlabel{\eq@sqlabel}

\renewcommand\eq@sqslrtnlabel{Lopeta testi}
\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}

\renewcommand\eqsqrtmsg{"Oikein!"} %muokattu
\renewcommand\eqsqwgmsg{"V\string\344\string\344rin!"} %m
%\renewcommand\eqsqwgmsg{"V\"a\"arin!"} %m

\renewcommand\eq@bqlabel{Aloita testi}
\renewcommand\bqlabel{\eq@bqlabel}
\renewcommand\eq@bqlabelISO{\eq@bqlabel}
\renewcommand\bqlabelISO{\eq@bqlabelISO}

\renewcommand\eq@eqlabel{Lopeta testi}
\renewcommand\eqlabel{\eq@eqlabel}

\renewcommand\eq@Score{Pisteet:}\renewcommand\eq@OutOf{/}
\renewcommand\eqInitQuizMsg{%m
   "Testi on aloitettava painamalla  "+msg+"."}
\renewcommand\eqMadeChoice{%m
   "Olet jo kerran valinnut.
    Valintasi oli ("+Responses[probno]+")."
+" Haluatko vaihtaa?"}
\AtEndOfPackage{%
\renewcommand\eq@local@CA{Oikein}
\renewcommand\eq@local@RC{Omat vastaukset!}
\renewcommand\eq@local@AC{Ole hyv\string\344!}}
\dlJSStr*[noquotes]{\limSelWarningMsg}{"T\string\344h\string\344n
  kysymykseen, voit tehd\string\344 enint\string\344\string\344n  "
  + n + " valintoja."}
%</eqfin>
%    \end{macrocode}
%    \subsection{catalan}
%    \begin{macrocode}
%<*eqcat>
%%%%%%%%%%%%%%%%%%% eqcat.def %%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Foreign language support for the exerquiz package.  %%
%% Name of translator: Ramon Ballester                 %%
%% e-mail address: ramon.ballester@udg.es              %%
%% Language:  (catalan)                                %%
%%                                                     %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% The exercise label
\renewcommand\exlabel{Exercici}
% The value of this macro is written to \jobname.sol,
\renewcommand\exlabelsol{\exlabel}

% Title of exercise solution section
\renewcommand\exsectitle{Solucions als \exlabel s}
\renewcommand\exsecrunhead{\exsectitle} %% change to @ form

% Solution label for solutionafter option for exercise
\renewcommand{\eq@exsolafterDefault}{\textit{Soluci\'o}:}

% Title of short quiz solution section
\renewcommand\eq@sqslsectitle{Solucions als Tests}
\renewcommand\sqslsectitle{\eq@sqslsectitle}

% Running header/section title for solutions to short quizzes
\renewcommand\eq@sqslsecrunhead{Solucions als Tests}
% User access
\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}

% Label for solutions to short quizzes, appears in solutions sections
\renewcommand\eq@sqsllabel{%
   \string\textbf{Soluci\protect\'{o} al Test:}}
% User access
\renewcommand\sqsllabel{\eq@sqsllabel}

% Solution label for solutionafter option for shortquiz
\renewcommand\sqsolafter{\textit{Soluci\'o}:}

% Here is the default short quiz label.
\renewcommand\eq@sqlabel{\textcolor{red}{Test.}}
% User access to shortquiz label
\renewcommand\sqlabel{\eq@sqlabel}

% Here is the default short quiz return label
\renewcommand\eq@sqslrtnlabel{Final del Test}
% User access to shortquiz label
\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}

% Short quiz feedback messages
\renewcommand\eqsqrtmsg{"Correcte!"}
\renewcommand\eqsqwgmsg{"Incorrecte!"}

% Here is the default quiz label.
\renewcommand\eq@bqlabel{Inici del Test}
% User access to shortquiz label
\renewcommand\bqlabel{\eq@bqlabel}
% Used for writing JavaScript Messages on screen. Use PDFDocEncoding
\renewcommand\eq@bqlabelISO{\eq@bqlabel}
\renewcommand\bqlabelISO{\eq@bqlabel}

% Here is the default quiz label.
% No formatting allowed
\renewcommand\eq@eqlabel{Final del Test}
% User access to shortquiz label
\renewcommand\eqlabel{\eq@eqlabel}
%
% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
%
\renewcommand\eq@Score{Punts:}\renewcommand\eq@OutOf{de}
\renewcommand\eqInitQuizMsg{"Has d'iniciar el Test!
    Prem sobre "+msg+"."}
\renewcommand\eqMadeChoice{%
    "Ja has elegit una resposta.
     La teva resposta ha estat ("+Responses[probno]+").
     Vols canviar--la?"}
%
% Default button labels for \eqButton
\renewcommand\eq@local@CA{Correctes}
\renewcommand\eq@local@RC{Les meves Respostes!}
\renewcommand\eq@local@AC{Si us plau!}
\dlJSStr*[noquotes]{\limSelWarningMsg}{"Per a aquesta pregunta,
  se li permet fer com a m\`{a}xim  "
  + n + " seleccions."}
%</eqcat>
%    \end{macrocode}
%
%    \subsection{Czech}
%    \begin{macrocode}
%<*eqcz>
%%%%%%%%%%%%%%%%%%% eqcat.def %%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Foreign language support for the exerquiz package.  %%
%% Name of translator: Robert Marik                    %%
%% e-mail address: marik@mendelu.cz                    %%
%% Language:  (czech)                                  %%
%%                                                     %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\SFW{1.75in}

% The exercise label
\renewcommand\exlabel{Cvi\v{c}en\'{\i}}
% The value of this macro is written to \jobname.sol,
\renewcommand\exlabelsol{Cvi\protect\v{c}en\protect\'{\protect\i}}

% Title of exercise solution section
\renewcommand\exsectitle{\texorpdfstring{\v{R}e\v{s}en\'{\i}
    ke cvi\v{c}en\'{\i}m}
    {Resen\355{} ke cvicen\355m}} %% change to @ form
\renewcommand\exsecrunhead{%
    \string\v{R}e\string\v{s}en\string\'{\string\i}
    ke cvi\string\v{c}en\string\'{\string\i}m}

% Solution label for solutionafter option for exercise
\renewcommand{\eq@exsolafterDefault}{\textit{\v{R}e\v{s}en\'\i}:}

% Title of short quiz solution section
\renewcommand\eq@sqslsectitle{\texorpdfstring{\v{R}e\v{s}en\'{\i}
    kv\'{\i}z\r{u}}{Resen\355{} kv\355zu}}
\renewcommand\sqslsectitle{\eq@sqslsectitle}

% Running header/section title for solutions to short quizzes
\renewcommand\eq@sqslsecrunhead{\v{R}e\v{s}en\'{\i} kv\'{\i}z\r{u}}
% User access
\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}

% Label for solutions to short quizzes, appears in solutions sections
\renewcommand\eq@sqsllabel{\string\textbf{%
    \string\v{R}e\string\v{s}en\string\'{\string\i}
    kv\string\'{\string\i}zu:}}
% User access
\renewcommand\sqsllabel{\eq@sqsllabel}

% Solution label for solutionafter option for shortquiz
\renewcommand\sqsolafter{\textit{\v{R}e\v{s}en\'{\i}}:}

% Here is the default short quiz label.
\renewcommand\eq@sqlabel{\textcolor{red}{Kv\'{\i}z.}}
% User access to shortquiz label
\renewcommand\sqlabel{\eq@sqlabel}

% Here is the default short quiz return label
%\renewcommand\eq@sqslrtnlabel{Konec kv\string\'{\string\i}zu}
\renewcommand\eq@sqslrtnlabel{Zp\string\v{e}t na ot\string\'{a}zky}
% User access to shortquiz label
\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}

% Short quiz feedback messages
\renewcommand\eqsqrtmsg{"Spravne !"}
\renewcommand\eqsqwgmsg{"Spatne !"}

% Here is the default quiz label.
\renewcommand\eq@bqlabel{Zacatek kvizu}
% User access to shortquiz label
\renewcommand\bqlabel{\eq@bqlabel}
% Used for writing JavaScript Messages on screen. Use PDFDocEncoding
\renewcommand\eq@bqlabelISO{Zacatek kvizu}
\renewcommand\bqlabelISO{Zacatek kvizu}

% Here is the default quiz label.
% No formatting allowed
\renewcommand\eq@eqlabel{Konec kvizu}
% User access to shortquiz label
\renewcommand\eqlabel{\eq@eqlabel}
%
% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
%
%\renewcommand\eq@Score{Hodnoceni:}
\renewcommand\eq@Score{}
\renewcommand\eq@OutOf{z celkovych}
\renewcommand\eqInitQuizMsg{%
  "Chcete-li pracovat s kvizem, musite jej nejprve spustit!
    Kliknete na "+msg+"."}
\renewcommand\eqMadeChoice{%
  "Uz jste si jednou odpoved vybral(a). Vase odpoved byla (" +
   Responses[probno]+"). Chcete ji opravdu zmenit?"}
%
% Default button labels for \eqButton
\renewcommand\eq@local@CA{Opravit}
\renewcommand\eq@local@RC{odpovedi!}
\renewcommand\eq@local@AC{Prosim!}
% Messages for math fill-in questions
\renewcommand\eqerrABS{"Spatne uzavrena absolutni hodnota.
    Opravte prosim."}
\renewcommand\eqerrBadMathFunc{"Vyraz `"+aF[i]+"' neni ani
    definovanou funkci ani  " +", ani platnym matematickym vyrazem."}
\renewcommand\eqParens{"Zavorky (kulate)"}
\renewcommand\eqBrackets{"Hranate zavorky"}
\renewcommand\eqBraces{"Slozene zavorky"}
\renewcommand\eqerrDelimNotBal{aGroup[i][2] + " nejsou parove.
    Opravte je prosim."}
\renewcommand\eqerrBadExp{"Spatny matematicky vyraz - problem v nekterem
    exponentu. Opravte jej prosim."}
\renewcommand\eqerrUnfinishQuiz{"Chyba: Nektery kviz mate nedokonceny.
    Musite jej dokoncit, nez budete pokracovat u dalsiho kvizu. Pokud si
    nepamatuje, ktery kviz jste nechali rozpracovany, zavrete cely
    soubor, znovu jej otevrete a k testu, ktery chcete vyplnovat,
    se vratte."}
\renewcommand\noPeekMsg{"Prohlizeni reseni neni povoleno pred dokoncenim
    kvizu!"}
\renewcommand\highThresholdMsg{"Musite odpovedet na vsechny otazky, nez
    ukoncite kviz."}
\renewcommand\eqSyntaxErrorUndefVar{"Chyba: Pravdepodobne pouzivate
    nespravnou promennou nebo mate preklep ve jmenu nektere funkce."}
\renewcommand{\promptButtonMsg}{%
        "Chcete ted videt spravnou odpoved? "\r\t\t
        + "Hodnocena bude Vase soucasna odpoved. "\r\t\t
        + "Kliknete-li na \\"Yes\\", uvidite spravnou odpoved, ale svou
           stavajici odpoved na tuto otazku uz nebudete moct zmenit."
}
\dlJSStr*[noquotes]{\limSelWarningMsg}{"Pro tuto ot\string\341zku
  m\u016F\u017Eete prov\'{e}st maxim\'{a}ln\u011B "
  + n + " v\u00FDb\u0115ry."}
%</eqcz>
%    \end{macrocode}
%    \subsection{brazil}
%    \begin{macrocode}
%<*eqbr>
%%%%%%%%%%%%%%%%%%% eqbr.def %%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Foreign language support for the exerquiz package. %%
%% Name of translator: Koichi Sameshima               %%
%% e-mail address: ksameshi@usp.br                    %%
%% Language:  (brazil)                                %%
%%                                                    %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% The exercise label
\renewcommand\exlabel{Exerc\texorpdfstring{\'{\i}}{\string\355}cio}
% The value of this macro is written to \jobname.sol,
\renewcommand\exlabelsol{Exerc\string\'{\string\i}cio}

% Title of exercise solution section
\renewcommand\exsectitle{Solu\texorpdfstring{\c{c}}{\string\347}%
    \texorpdfstring{\~{o}}{%
    \string\365}es dos  Exerc\texorpdfstring{\'{\i}}{\string\355}cios}
    %{Solu\string\\347\string\\363es dos Exerc\string\\355cios}}
\renewcommand\exsecrunhead{%
    Solu\protect\c{c}\protect\~{o}es dos Exerc\protect\'{i}cios}

% Solution label for solutionafter option for exercise
\renewcommand{\eq@exsolafterDefault}{\textit{Solu\c{c}\~{a}o}:}

% Title of short quiz solution section
\renewcommand\eq@sqslsectitle{Solu\c{c}\~{o}es
    dos Testes}
\renewcommand\sqslsectitle{\eq@sqslsectitle}

% Running header/section title for solutions to short quizzes
\renewcommand\eq@sqslsecrunhead{Solu\protect\c{c}\protect\~{o}es
    dos Testes}
% User access
\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}

% Label for solutions to short quizzes, appears in solutions sections
\renewcommand\eq@sqsllabel{%
  \string\textbf{Solu\protect\c{c}\protect\~{a}o do Teste:}}
% User access
\renewcommand\sqsllabel{\eq@sqsllabel}

% Solution label for solutionafter option for shortquiz
\renewcommand\sqsolafter{\textit{Solu\protect\c{c}\protect\~{a}o}:}

% Here is the default short quiz label.
\renewcommand\eq@sqlabel{\textcolor{red}{Teste.}}
% User access to shortquiz label
\renewcommand\sqlabel{\eq@sqlabel}

% Here is the default short quiz return label
\renewcommand\eq@sqslrtnlabel{Finaliza Teste}
% User access to shortquiz label
\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}

% Short quiz feedback messages
\renewcommand\eqsqrtmsg{"Correto!"}
\renewcommand\eqsqwgmsg{"Incorreto!"}

% Here is the default quiz label.
\renewcommand\eq@bqlabel{Inicia Teste}
% User access to shortquiz label
\renewcommand\bqlabel{\eq@bqlabel}
% Used for writing JavaScript Messages on screen. Use PDFDocEncoding
\renewcommand\eq@bqlabelISO{\eq@bqlabel}
\renewcommand\bqlabelISO{\eq@bqlabel}

% Here is the default quiz label.
% No formatting allowed
\renewcommand\eq@eqlabel{Finaliza Teste}
% User access to shortquiz label
\renewcommand\eqlabel{\eq@eqlabel}
%
% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
%
\renewcommand\eq@Score{Pontos:}\renewcommand\eq@OutOf{de}
\renewcommand\eqInitQuizMsg{% ******
   "Voc\string\352 precisa iniciar o Teste! Clique sobre "+msg+"."}
\renewcommand\eqMadeChoice{%
   "Voc\string\352 j\string\341 respondeu.
    Sua resposta foi ("+Responses[probno]+").
    Quer alter\string\341-la?"}
%
% Default button labels for \eqButton
\renewcommand\eq@local@CA{Corretas}
\renewcommand\eq@local@RC{Minhas Respostas!}
\renewcommand\eq@local@AC{Por Favor!}
\dlJSStr*[noquotes]{\limSelWarningMsg}{"Pro tuto ot\string\341zku
  m\u016F\u017Eete prov\'{e}st maxim\'{a}ln\u011B "
  + n + " v\u00FDb\u0115ry."}
%</eqbr>
%    \end{macrocode}
%    \subsection{turkish}
%    \begin{macrocode}
%<*eqtr>
%%%%%%%%%%%%%%%%%%%% eqtr.def %%%%%%%%%%%%%%%%%%%%%%%%%%
%% Foreign language support for the exerquiz package. %%
%% Name of translator: Mahmut Ko\c{c}ak               %%
%% e-mail address: mkocak@ogu.edu.tr                  %%
%% Language: Turkish                                  %%
%%                                                    %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\renewcommand\exlabel{Al\i \c st\i rma}
\renewcommand\exlabelsol{\noexpand\c C\noexpand\"oz\noexpand\"um}
\renewcommand\exsectitle{\exlabel lar{\i}n \c C\"oz\"umleri  }
\renewcommand\exsecrunhead{Al\noexpand\i \noexpand\c st\noexpand\i rma
    \exlabelsol leri }
\renewcommand\exsolafter{\textbf{\c C\"oz\"um}:}
\renewcommand\eq@sqslsectitle{Kuizlerin \c C\"oz\"umleri }
\renewcommand\sqslsectitle{\eq@sqslsectitle}
\renewcommand\eq@sqslsecrunhead{Kuizlerin \c C\"oz\"umleri}
\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
\renewcommand\eq@sqsllabel{%
   \protect\textbf{Kuiz \noexpand\c C\noexpand\"oz\noexpand\"um%
    \noexpand\"u:}}
\renewcommand\sqsllabel{\eq@sqsllabel}
\renewcommand\sqsolafter{\textit{\c C\"oz\"um}:}
\renewcommand\eq@sqlabel{\textcolor{red}{Soru}}
\renewcommand\sqlabel{\eq@sqlabel}
\renewcommand\eq@sqslrtnlabel{Kuizi Bitir}
\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
% JavaScript alert box text
\renewcommand\eqsqrtmsg{"Do\protect\u011Fru!"}
\renewcommand\eqsqwgmsg{"Yanl\protect\u0131\protect\u015F!"}
%
\renewcommand\eq@bqlabel{Kuize Ba\c sla}
\renewcommand\bqlabel{\eq@bqlabel}
\renewcommand\eq@bqlabelISO{\eq@bqlabel}
\renewcommand\bqlabelISO{\eq@bqlabelISO}
\renewcommand\eq@eqlabel{Kuizi Bitir}
\renewcommand\eqlabel{\eq@eqlabel}
%
% JavaScript messages
%
\renewcommand\eq@Score{Skor:}
\renewcommand\eq@OutOf{\protect\374zerinden}
\renewcommand\eqQuizTotalMsg{%
  "\eqScore\space"+Score+" \eqOutOf\space"+nQuestions}
  \renewcommand\eqQuizPointsMsg{%
  "\eqptScore\space"+ptScore+" \eqOutOf\space"+nPointTotal}
\renewcommand\eq@local@CorrAnsButton{Cevap}
\renewcommand\eqInitQuizMsg{%
  "Kuizi Bitirdiniz. Do\protect\u011Fru cevaplar\protect\u0131
    g\protect\u00F6rmek i\protect\u00E7in 'cevap'
    tu\protect\u015Flar\protect\u0131na
    bas\protect\u0131n\protect\u0131z."}
\renewcommand\eqMadeChoice{%
   "Bir se\protect\u00E7im yapt\protect\u0131n\protect\u0131z.
   Se\protect\u00E7iminiz ("+Responses[probno]+") idi."
    +" Se\protect\u00E7iminizi de\protect\u011Fi\protect\u015Ftirmek
    istermisiniz?"}
\renewcommand\eqerrABS{"Mutlak de\protect\u011Fer do\protect\u011Fru
    degil. L\protect\u00FCtfen d\protect\u00FCzeltiniz."}
\renewcommand\eqerrBadMathFunc{" `"+aF[i]+"' ifadesi
    tan\protect\u0131ml\protect\u0131 bir fonksiyon veya
    ge\protect\u00E7erli bir matematiksel ifade de\protect\u011Fil."}
\renewcommand\eqParens{"Parentezler"}
\renewcommand\eqBrackets{"S\protect\u00FCsl\protect\u00FC Parentazle"}
\renewcommand\eqBraces{"K\protect\u00F6\protect\u015Feli Parentezler"}
\renewcommand\eqerrDelimNotBal{aGroup[i][2] + " do\protect\u011Fru
    de\protect\u011Fil. L\protect\u00FCtfen d\protect\u00FCzeltiniz."}
\renewcommand\eqerrBadExp{"Ge\protect\u00E7ersiz matematiksel ifade.
    \protect\u00FCstel ifadeli bir hata.
    L\protect\u00FCtfen d\protect\u00FCzeltiniz."}
\renewcommand\eqerrUnfinishQuiz{"Bitirilmemi\protect\u015F bir kuiz var,
    di\protect\u011Fer kuize ge\protect\u00E7meden \protect\u00F6nce
    bu kuizi tamamlay\protect\u0131n."}
\renewcommand\noPeekMsg{"Kuizi bitirmeden yada kuizden
    ba\protect\u015Far\protect\u0131l\protect\u0131 olana kadar
    \protect\u00E7\protect\u00F6z\protect\u00FCmleri
    g\protect\u00F6remezsiniz.!"}
\renewcommand\highThresholdMsg{"Kuiz sonucu hesaplanmadan
    \protect\u00F6nce b\protect\u00FCt\protect\u00FCn
    sorular\protect\u0131 cevapland\protect\u0131rmal\protect
    \u0131s\protect\u0131n\protect\u0131z."}
\renewcommand\eqSyntaxErrorUndefVar{"Syntax Error: Tan\protect
    \u0131mlanmam\protect\u0131\protect\u015F de\protect\u011Fi\protect
    \u015Fken veya ifadeler istenilen formatta yaz\protect
    \u0131lmam\protect\u0131\protect\u015Ft\protect\u0131r."}
\renewcommand\eq@local@CA{Dogru}
\renewcommand\eq@local@RC{Benim Cevaplar\protect\u0131m!}
\renewcommand\eq@local@AC{L\protect\374tfen!}
\dlJSStr*[noquotes]{\limSelWarningMsg}{"Bu soru i\u00E7in, en fazla "
  + n + " se\u00E7im yapmak i\u00E7in izin verilir."}
%</eqtr>
%    \end{macrocode}
%  \Finale
