From 62dc979b3581324476e859c5193c81c4583e2618 Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Sat, 27 Jun 2020 03:01:57 +0000
Subject: CTAN sync 202006270301

---
 .../contrib/aeb_pro/acromemory/acromemory.dtx      | 1029 ++++++++++----------
 1 file changed, 505 insertions(+), 524 deletions(-)

(limited to 'macros/latex/contrib/aeb_pro/acromemory/acromemory.dtx')

diff --git a/macros/latex/contrib/aeb_pro/acromemory/acromemory.dtx b/macros/latex/contrib/aeb_pro/acromemory/acromemory.dtx
index 8770f3c3e7..2fb7486d1e 100644
--- a/macros/latex/contrib/aeb_pro/acromemory/acromemory.dtx
+++ b/macros/latex/contrib/aeb_pro/acromemory/acromemory.dtx
@@ -2,7 +2,7 @@
 %<*copyright>
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %% acromemory.sty package,                              %%
-%% Copyright (C) 2006--2017  D. P. Story                %%
+%% Copyright (C) 2006--2020  D. P. Story                %%
 %%   dpstory@acrotex.net                                %%
 %%                                                      %%
 %% This program can redistributed and/or modified under %%
@@ -14,14 +14,29 @@
 %</copyright>
 %<package>\NeedsTeXFormat{LaTeX2e}
 %<package>\ProvidesPackage{acromemory}
-%<package> [2017/02/23 v1.1 AcroMemory (dps)]
+%<package> [2020/06/23 v2.0 AcroMemory (dps)]
 %<*driver>
 \documentclass{ltxdoc}
-\usepackage[colorlinks,hyperindex]{hyperref}
+\usepackage[colorlinks,hyperindex=false]{hyperref}
 \pdfstringdefDisableCommands{\let\\\textbackslash}%
-\EnableCrossrefs \CodelineIndex
-\OnlyDescription  % comment out for implementation details
+\EnableCrossrefs \CodelineIndex \RecordChanges
+\InputIfFileExists{aebdocfmt.def}{\PackageInfo{acromemory}{Inputting aebdocfmt.def}}
+    {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax
+     \PackageInfo{acromemory}{aebdocfmt.def cannot be found}}
 \begin{document}
+\bgroup\ttfamily
+\gdef\brpr#1{\char123\relax#1\char125\relax}\egroup
+\let\darg\brpr
+\let\env\texttt
+\let\opt\texttt
+\let\app\textsf
+\def\visispace{\symbol{32}}
+\def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}}
+\def\meta#1{\textsl{\texttt{#1}}}
+\def\SUB#1{\ensuremath{{}_{\mbox{\scriptsize\ttfamily#1}}}}
+\def\ltag{<}\def\rtag{>}
+\def\EXCL{!}
+\let\app\textsf\let\pkg\textsf
   \GetFileInfo{acromemory.sty}
   \title{The \texttt{AcroMemory} Package\texorpdfstring{\\}{: }
   A member of the AeB Pro family}
@@ -32,20 +47,20 @@
   \tableofcontents
   \let\Email\texttt
   \DocInput{acromemory.dtx}
-  \PrintIndex
+\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\PrintIndex}{\paragraph*{Index} The index goes here.\\Execute
+    \texttt{makeindex -s gind.ist -o acromemory.ind acromemory.idx} on the command line and recompile
+    \texttt{acromemory.dtx}.}
+\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here.\\Execute
+    \texttt{makeindex -s gglo.ist -o acromemory.gls acromemory.glo} on the command line and recompile
+    \texttt{acromemory.dtx}.}
 \end{document}
 %</driver>
 % \fi
-% \section{What is the AeB Pro Family?}
-%   Through the years, I have tried to make my AeB software
-%   ({Acro\negthinspace\TeX} eDucation Bundle) compatible with
-%   \textsf{pdftex} and \textsf{dvipdfm}; however, during that time,
-%   I've developed a number of techniques that require the use of
-%   Acrobat and distiller. Therefore, I have set off in a new direction and
-%   will be publishing a new line of {\LaTeX} packages, one that require the use
-%   of Acrobat.
 %
-%   The current package, \textsf{AcroMemory}, requires the use of Acrobat Pro~7.0 or later.
+% \MakeShortVerb{|}
+% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{eforms}{Inputting aebdonotindex.def}}
+%    {\PackageInfo{eforms}{aebdonotindex.def cannot be found}}
+%
 % \section{Introduction}
 %
 % At the instigation of my erstwhile friend, J\"{u}ergen, I present to you \textsf{AcroMemory}, and
@@ -79,184 +94,342 @@
 % The demo files are \texttt{acromemory1.tex} and \texttt{acromemory2.tex}. These files show how to
 % lay out the various elements of this package.
 %
+% \paragraph*{What's New for version v2.0 (2020-06-23):} Rewrote the entire package to support all
+% \LaTeX\space workflows: \app{pdflatex}, \app{lualatex}, \app{xelatex}, and \app{dvips \texttt{->} distiller}.
+% \changes{v2.0}{2020/06/23}{Rewrote entire package in order to support all \string\LaTeX\space
+% workflows}
+%
 % \section{Creating the Image Tiles}
 %
-% There are a couple of ways you can package your image tiles: (1) place all tiles (all of identical size)
-% into a single PDF and use the \texttt{iconfile} option to tell AcroMemory you are using this method; (2)
-% each image file is a separate PDF. In the latter case, there is a naming convention that must be followed;
-% the files must be named \texttt{<basename>\_01.pdf}, \texttt{<basename>\_02.pdf}, \dots,
-% \texttt{<basename>\_10.pdf}, \texttt{<basename>\_11.pdf}, \dots. You'll note the consistent two digit
-% numbering system is used.
-
 % For \texttt{acromemory2}, slicing of the image is at the very heart
 % of this game. You can slice an image in to rectangular tiles using
-% any of several applications: \textsf{Adobe Illustrator},
-% \textsf{Photoshop} and \textsf{ImageReady}, for example. But these are
-% expensive applications and you have already bought \textsf{Acrobat Pro}. For this purpose,
-% AeB Pro provides the \textsf{AcroSlicing} batch sequence.
+% any of several applications: \app{Adobe Illustrator},
+% \app{Photoshop} and \textsf{ImageReady}, for example. But these are
+% expensive applications; a cheap method is to use the {\LaTeX} package
+% \pkg{tile-graphic}.\footnote{\url{https://ctan.org/pkg/tile-graphic}}
 %
 %    \begin{macrocode}
 %<*package>
 \RequirePackage{xkeyval}
 %    \end{macrocode}
-%    \begin{macro}{acromemory1}
+%    \leavevmode\IndexOpt{acromemory1}
 % One playing board, where you try to match identical icons.
 %    \begin{macrocode}
 \DeclareOptionX{acromemory1}{\acromemoryitrue}
 %    \end{macrocode}
-%    \end{macro}
-%    \begin{macro}{acromemory2}
+%    \leavevmode\IndexOpt{acromemory2}
 % Two playing boards, one board randomized the other not. Try to find the matching icons,
 % one from each of the two boards.
 %    \begin{macrocode}
 \DeclareOptionX{acromemory2}{\acromemoryifalse}
 %    \end{macrocode}
-%    \end{macro}
-%    \begin{macro}{acromemory2}
-% Two playing boards, one board randomized the other not. Try to find the matching icons,
-% one from each of the two boards.
-%    \begin{macrocode}
-\DeclareOptionX{iconfile}{\def\iconsInOneFile{true}}
-\def\iconsInOneFile{false}
-%    \end{macrocode}
-%    \end{macro}
-%    \begin{macro}{includehelp}
+%    \leavevmode\IndexOpt{includehelp}
 % Only valid when \texttt{acromemory2} is taken, this option allows you to provide a
 % figure showing the completed puzzle.
 %    \begin{macrocode}
 \DeclareOptionX{includehelp}{\includehelptrue}
 %    \end{macrocode}
-%    \end{macro}
+%    \leavevmode\IndexOpt{draft} Draft mode, works for \app{pdflatex} and \app{lualatex} only.
+%    \begin{macrocode}
+\DeclareOptionX{draft}{\PassOptionsToPackage{draft}{graphicx}}
+%    \end{macrocode}
+%    Declare to booleans, and process options
 %    \begin{macrocode}
 \newif\ifincludehelp \includehelpfalse
 \newif\ifacromemoryi \acromemoryifalse
-\ProcessOptionsX
+\ProcessOptionsX\relax
+\@ifpackageloaded{eforms}{\execJSOn}
+  {\RequirePackage[execJS]{eforms}}
+\RequirePackage{aeb-comment}
+\ifxetex\makeXasPDOff\fi
+\RequirePackage{icon-appr}
+\RequirePackage{multido}
 \RequirePackage{graphicx}
-\RequirePackage{comment}
 \ifacromemoryi
     \def\RanIdentifier{\@gobble}
     \includecomment{acromemory1}
     \excludecomment{acromemory2}
-    \excludecomment{needhelp}
+    \includehelpfalse
 \else
     \def\RanIdentifier{R\@gobble}
     \includecomment{acromemory2}
     \excludecomment{acromemory1}
-    \ifincludehelp
-        \includecomment{needhelp}
-    \else
-        \excludecomment{needhelp}
-    \fi
 \fi
+\newcount\am@nCnt
 %    \end{macrocode}
 % \section{Main Macro Code}
-% When setting up your AcroMemory document, you need to provide this package with
-% certain information, as listed below.
-%    \begin{macro}{\theTotalTiles}
-%    \begin{macro}{\theNumRows}
-%    \begin{macro}{\theNumCols}
-%    \begin{macro}{\theImportPath}
-%    \begin{macro}{\theIconExt}
-%    \begin{macro}{\theTeXImageWidth}
-%    \begin{macro}{\provideDimensions}
-%\begin{itemize}
-%   \item \cs{theTotalTiles}: The total number of tiles in the game board. For example,
-%   \verb!\theTotalTiles{20}!. This parameter is required.
-%   \item \cs{theNumRows}: The number of rows in the game board. For example,
-%   \verb!\theNumRows{5}!. This parameter is required.
-%   \item \cs{theNumCols}: The number of columns in the game board. For example,
-%   \verb!\theNumCols{4}!. This parameter is required.
-%   \item \cs{theImportPath}: The import path to the basename of the image. The path
-%   should use the path specification as defined in the PDF Ref, and the file name should
-%   have no extension. For example, \verb!\theImportPath{myFig/myimages}!. Required.
-%   There is an optional argument that is typically used when the iconfile is in effect
-%   with the acromemory2 option,  and an image of the game board is different from the
-%    path given by the optional argument; for example,
-%\begin{verbatim}
-%   \theImportPath[dpsweb/dpsweb]{dpsweb/dpsweb_package}
-%\end{verbatim}
-%   The required argument points the packaged icons, the optional argument points to
-%   a file showing the entire image
-%   \item \cs{theIconExt}: The extension of the image file(s), Required if different
-%   from \texttt{pdf}.
-%   \item \cs{theTeXImageWidth}: The scaled width of the rectangular game board. The
-%   game board will be rescaled so that its width is equal to the value specified
-%   by the argument of this command, e.g., \verb!\theTeXImageWidth{2in}!.
-%   \item\cs{provideDimensions}: If the dimension of the game board is known, the width
-%   and height can be entered with this command using the two parameters. For example,
-%   \verb!\provideDimensions{2in}{2.5in}! (width, height).
-%\end{itemize}
+%
+%    \begin{macro}{\bDebug}
+% A debugging command. When executed in the preamble, more is written to the Acrobat console
+% as the document is  opened the first time, also, the icons are initially visible so you can
+% see the layout, and quickly play the game. This was used in development extensively to help
+% develop the JavaScript.
+%    \begin{macrocode}
+\def\bDebug{\def\memDebug{true}}
+\def\memDebug{false}
+%    \end{macrocode}
+%    \end{macro}
+%    \leavevmode\DescribeMacro\isPackage Placed prior to \cs{amEmbedTiles}, it signals
+%    that the images are in a package file.
+%    \begin{macrocode}
+\newif\if@isPackaged\@isPackagedfalse
+\def\isPackage{\@isPackagedtrue}
+\let\amIconObjs\@gobble
+%    \end{macrocode}
+%    \leavevmode\DescribeMacro\amEmbedTiles\hskip-\marginparsep\texttt
+%    {[\ameta{ext}]\darg{\ameta{name}}\darg{\ameta{n-rows}}\darg{\ameta{n-cols}}\darg{\ameta{path}}}
+%    Embed the required files for this puzzle. We require a \ameta{name}, in the off chance that some day
+%    more than one puzzles are allowed.
+%    \begin{macrocode}
+\newcommand{\amEmbedTiles}[4][]{\begingroup
+  \gdef\amNumImages{#3}%
+  \csarg\gdef{amGraphicPath#2}{#4}%
+  \gdef\imageImportPath{#4}%
+  \ifacromemoryi
+%    \end{macrocode}
+%    If \opt{acromemoryi} is in effect, then \texttt{\#3} is half the required icons,
+%    each icon is placed twice, then mixed up. Anyway, we double this value going forward.
 %    \begin{macrocode}
-\def\theTotalTiles#1{\def\nTotalTiles{#1}}
-\def\theNumRows#1{\def\nRows{#1}}
-\def\theNumCols#1{\def\nCols{#1}}
-\newcommand{\theImportPath}[2][]{%
+    \@tempcnta=#3\relax
+    \multiply\@tempcnta\tw@
+    \xdef\nTotalTiles{\the\@tempcnta}\else
+    \gdef\nTotalTiles{#3}\fi
+  \def\@Ext{#1}\ifx\@Ext\@empty\def\@Ext{.pdf}\else\def\@Ext{.#1}\fi
+  \@tempcnta\z@
+  \let\@embedList\@empty
+  \let\AMIndxList\@gobble
+  \edef\z{\noexpand\g@addto@macro\noexpand
+    \amIconObjs{,"#2":\amNumImages}}\z
+  \@whilenum \@tempcnta < \amNumImages \do{%
+    \am@nCnt\@tempcnta\advance\am@nCnt\@ne
+    \ifnum\am@nCnt<10\relax\edef\x{0\the\am@nCnt}\else
+      \edef\x{\the\am@nCnt}\fi
+    \edef\z{\noexpand\g@addto@macro\noexpand\AMIndxList{,"#2pic\x"}}\z
+    \ifxetex\if@isPackaged
+      \PackageWarning{acromemory}
+      {There is no support for embedding packaged\MessageBreak
+      PDFs with xelatex. Ignoring the \string\isPackage\MessageBreak
+      command}%
+      \@isPackagedfalse
+    \fi\fi
     \ifacromemoryi
-        \def\imageImportPath{#2}
-        \def\importpath{#2}
+      \@tempcntb\@tempcnta
+      \multiply\@tempcntb\tw@
+      \advance\@tempcntb\@ne
+      \edef\z{\the\@tempcntb}\advance\@tempcntb\@ne
+      \edef\zi{\the\@tempcntb}%
+      \if@isPackaged
+        \ifpdf
+          \edef\y{\noexpand
+            \embedIcon[name=#2pic\x,%
+            hyopts={page=\x}]{#4_package.pdf}}%
+        \else
+          \edef\y{\noexpand
+            \embedIcon[name=#2pic\x,%
+              placement={[1]Membutton.\z,[1]Membutton.\zi},%
+              page=\x-1]{#4_package.pdf}}%
+        \fi
+      \else
+        \edef\y{\noexpand
+          \embedIcon[name=#2pic\x,%
+            placement={[1]Membutton.\z,[1]Membutton.\zi}]{#4_\x\@Ext}}%
+      \fi
     \else
-        \def\argi{#1}\ifx\argi\@empty
-            \def\imageImportPath{#2}
-            \def\importpath{#2}
+      \ifincludehelp\embedIcon[name=helpimage,%
+        placement={[1]memoryhelp}]{#4\@Ext}\fi
+      \edef\z{\the\am@nCnt}%
+      \if@isPackaged
+        \ifpdf
+          \edef\y{\noexpand
+            \embedIcon[name=#2pic\x,%
+            hyopts={page=\x}]{#4_package.pdf}}%
         \else
-            \def\imageImportPath{#1}
-            \def\importpath{#2}
+          \edef\y{\noexpand
+            \embedIcon[name=#2pic\x,%
+              placement={[1]MemLbutton.\z,[1]MemRbutton.\z},%
+            page=\x-1]{#4_package.pdf}}%
         \fi
+      \else
+        \edef\y{\noexpand
+          \embedIcon[name=#2pic\x,%
+            placement={[1]MemLbutton.\z,[1]MemRbutton.\z}%
+          ]{#4_\x\@Ext}}%
+      \fi
     \fi
+    \expandafter\g@addto@macro\expandafter
+    \@embedList\expandafter{\y}%
+    \@tempcnta\am@nCnt
+  }% do
+  \toks@=\expandafter{\@embedList}\the\toks@
+%%\typeout{!! \the\toks@}%
+  \endgroup
+  \global\@isPackagedfalse
 }
-\def\theIconExt#1{\def\iconsExt{#1}}
-\def\iconsExt{pdf}
-\def\theTeXImageWidth#1{\def\texImageWidth{#1}%
-    {\dimen0 = \texImageWidth \xdef\imageWidth{\strip@pt\dimen0 }}%
-}
-\newcommand{\provideDimensions}[3][]{%
-    \def\argi{#1}\ifx\argi\@empty
-        {\dimen0 = #2 \xdef\trueImageWidth{\strip@pt\dimen0 }%
-         \dimen0 = #3 \xdef\trueImageHeight{\strip@pt\dimen0 }}%
-    \else
-        \def\trueImageWidth{#1}\def\trueImageHeight{#2}%
-    \fi
-    \def\bProvideDimen{true}%
+%    \end{macrocode}
+%    \leavevmode\DescribeMacro\amIconPic\hskip-\marginparsep\texttt
+%    {[\ameta{opts}]\darg{\ameta{fname}}\darg{\ameta{wd}}\darg{\ameta{ht}}} A general
+%    purpose push button that will have icon appearances.
+%    \begin{macrocode}
+\newcommand{\amIconPic}[4][]{% \I{\csOf{name}} required
+  \pushButton[\BG{}\W{1}\S{S}#1\TP{1}%\F{\FHidden}
+    ]{#2}{#3}{#4}}
+%    \end{macrocode}
+%   \DescribeMacro\insertTiles\hskip-\marginparsep
+%   \texttt{\darg{\ameta{name}}\darg{\ameta{width}}\darg{\ameta{rows}}\darg{\ameta{cols}}}
+% Command for placing the tiles of a picture. We assume that the pictures are numbered
+% consecutively across rows.
+% \begin{quote}
+% \begin{description}
+% \item[\ameta{name}]  The name of the graphic (a JavaScript identifier)
+% \item[\ameta{width}] The width of the image, the height is scaled proportionally
+% \item[\ameta{rows}]  The number of rows
+% \item[\ameta{cols}]  The number of columns
+% \end{description}
+% \end{quote}
+%    \begin{macrocode}
+\newcommand\insertTiles[4]{\begingroup
+  \@tempdima#2\relax
+  \divide\@tempdima #4\relax
+  \setbox\z@\hbox{\includegraphics[draft,width=\@tempdima]%
+  {\@nameuse{amGraphicPath#1}}}%
+  \edef\amTileWd{\the\wd\z@}%
+  \setlength\@tempdima{\ht\z@+\dp\z@}%
+  \setbox\z@\box\voidb@x
+  \edef\amTileHt{\the\@tempdima}%
+  \@tempdima\amTileWd\relax
+  \multiply\@tempdima #4\relax
+  \edef\tot@lWd{\the\@tempdima}%
+  \@tempcnta#3\relax
+  \multiply\@tempcnta #4\relax
+  \divide\@tempcnta\tw@
+  \edef\tot@lHalfTiles{\the\@tempcnta}%
+  \begin{minipage}{\tot@lWd}%
+    \offinterlineskip\hbadness=10000\@tempcnta\z@
+    \leavevmode
+    \rlap{\amIconPic[\BC{}\BG{}]{nullIconBtn}{0bp}{0bp}}%
+    \multido{\i=1+1}{\tot@lHalfTiles}{%
+      \advance\@tempcnta\@ne
+      \edef\y{\the\@tempcnta}%
+      \ifnum\i<10\relax
+        \edef\x{0\i}\else
+        \edef\x{\i}\fi
+      \edef\iconPresets{\noexpand\IX{\noexpand\csOf{#1pic\x}}}%
+      \amIconPic[\AAmouseup{selectTile();}\FB{true}
+        \presets{\iconPresets}\presets{\amtile@KVs}
+      ]{Membutton.\y}{\amTileWd}{\amTileHt}\allowbreak
+      \advance\@tempcnta\@ne
+      \edef\y{\the\@tempcnta}%
+      \edef\iconPresets{\noexpand\IX{\noexpand\csOf{#1pic\x}}}%
+      \amIconPic[\AAmouseup{selectTile();}\FB{true}
+        \presets{\iconPresets}\presets{\amtile@KVs}
+      ]{Membutton.\y}{\amTileWd}{\amTileHt}\allowbreak
+    }% multido
+  \end{minipage}%
+  \endgroup
+}
+\def\amtileKVs#1{\def\amtile@KVs{#1}}
+\amtileKVs{}
+%    \end{macrocode}
+%    \leavevmode\DescribeMacro\insertTilesii\hskip-\marginparsep\texttt
+%    {\darg{\ameta{name}}\darg{\ameta{width}}\darg{\ameta{n-rows}}\darg{\ameta{n-cols}}\darg{\ameta{\upshape L\string|R}}}
+% \begin{quote}
+% \begin{description}
+% \item[\ameta{name}]  The name of the graphic (a JavaScript identifier)
+% \item[\ameta{width}] The width of the image, the height is scaled proportionally
+% \item[\ameta{rows}]  The number of rows
+% \item[\ameta{cols}]  The number of columns
+% \item[\ameta{\upshape L\string|R}] Indicates for Left or Right Image
+% \end{description}
+% \end{quote}
+% Is the common code for \cs{insertTilesL} and \cs{insertTilesR}.
+%    \begin{macrocode}
+\newcommand\insertTilesii[5]{\begingroup
+  \def\@rgv{#5}\def\as@L{L}%
+  \@tempdima#2\relax
+  \setbox\z@\hbox{\includegraphics[draft,width=\@tempdima]{%
+    \@nameuse{amGraphicPath#1}}}%
+  \edef\amImageWd{\the\wd\z@}%
+  \setlength\@tempdima{\ht\z@+\dp\z@}%
+  \setbox\z@\box\voidb@x
+  \edef\amImageHt{\the\@tempdima}%
+% Now calculate wd and ht of a tile
+  \@tempdima\amImageWd\relax
+  \divide\@tempdima#4\relax
+  \edef\amTileWd{\the\@tempdima}%
+  \@tempdima\amImageHt\relax
+  \divide\@tempdima#3\relax
+  \edef\amTileHt{\the\@tempdima}%
+% Calculate total number of tiles
+  \@tempcnta#3\relax
+  \multiply\@tempcnta#4\relax
+  \edef\Tot@lTiles{\the\@tempcnta}%
+% Begin minipage of width \amImageWd
+  \begin{minipage}{\amImageWd}%
+    \offinterlineskip\hbadness=10000\@tempcnta\z@
+    \leavevmode
+    \rlap{\amIconPic[\BC{}\BG{}]{nullIconBtn}{0bp}{0bp}}%
+    \multido{\i=1+1}{\Tot@lTiles}{%
+      \advance\@tempcnta\@ne
+      \edef\y{\the\@tempcnta}%
+      \ifnum\i<10\relax
+        \edef\x{0\i}\else
+        \edef\x{\i}\fi
+      \ifx\@rgv\as@L
+        \def\muAction{nRowsAM=#3;nColsAM=#4;\string\r
+          selectNonRandomTile(\y,\y);}\else
+        \def\muAction{nRowsAM=#3;nColsAM=#4;\string\r
+          selectRandomTile(randomAM[\y],\y);}\fi
+      \edef\iconPresets{\noexpand\AAmouseup{\muAction}\noexpand
+        \IX{\noexpand\csOf{#1pic\x}}}%
+      \amIconPic[\presets{\iconPresets} %\FB{true}
+        \presets{\amtile@KVs}
+      ]{Mem#5button.\y}{\amTileWd}{\amTileHt}\allowbreak
+    }% multido
+  \end{minipage}\endgroup
 }
-\def\bProvideDimen{false}%
-\def\trueImageWidth{0}\def\trueImageHeight{0}%
 %    \end{macrocode}
-%    \end{macro}
-%    \end{macro}
-%    \end{macro}
-%    \end{macro}
-%    \end{macro}
-%    \end{macro}
-%    \end{macro}
-%    \begin{macro}{\bDebug}
-% A debugging command. When executed in the preamble, more is written to the Acrobat console
-% as the document is  opened the first time, also, the icons are initially visible so you can
-% see the layout, and quickly play the game. This was used in development extensively to help
-% develop the JavaScript.
+%    \leavevmode\DescribeMacro\insertTilesL\hskip-\marginparsep\texttt
+%    {\darg{\ameta{name}}\darg{\ameta{width}}\darg{\ameta{n-rows}}\darg{\ameta{n-cols}}}
+%    Inserts the left-hand tiles, which is the non-randomize version of the picture.
 %    \begin{macrocode}
-\def\bDebug{\def\memDebug{true}}
-\def\memDebug{false}
+\newcommand\insertTilesL[4]{\ifacromemoryi
+  \def\AM@next{\PackageWarning{acromemory}
+  {The use of \string\insertTilesL\space is supported\MessageBreak
+  only for the acromemory2 option}}\else
+  \def\AM@next{\insertTilesii{#1}{#2}{#3}{#4}{L}}\fi\AM@next}
 %    \end{macrocode}
-%    \end{macro}
-%    \begin{macro}{\helpImage}
-%    \begin{macro}{\rolloverHelpButton}
-%    \begin{macro}{\setHelpImageWidth}
-%    \begin{macro}{\theHelpCaption}
-%  When \texttt{acromemory2} options and the \texttt{includehelp}
-%  options are taken, these commands are available. The command
+%    \leavevmode\DescribeMacro\insertTilesR\hskip-\marginparsep\texttt
+%    {\darg{\ameta{name}}\darg{\ameta{width}}\darg{\ameta{n-rows}}\darg{\ameta{n-cols}}}
+%    Inserts the right-hand tiles, which is the randomized version of the picture.
+%    \begin{macrocode}
+\newcommand\insertTilesR[4]{\ifacromemoryi
+  \def\AM@next{\PackageWarning{acromemory}
+  {The use of \string\insertTilesR\space is supported\MessageBreak
+  only for the acromemory2 option}}\else
+  \def\AM@next{\insertTilesii{#1}{#2}{#3}{#4}{R}}\fi\AM@next}
+%    \end{macrocode}
+%    \begin{macro}{\helpImage}\hskip-\marginparsep\texttt
+%    {[\ameta{eform-opts}]\darg{\ameta{width}}}
+%  When \texttt{acromemory2} option and the \texttt{includehelp}
+%  option are taken, these commands are available. The command
 %  \cs{helpImage} will contain an icon of the puzzle, and it width
 %  is set by the command \cs{setHelpImageWidth}. The image is normally
 %  hidden until the user rolls over the \cs{rolloverHelpButton}. The
 %  icons appears with an caption under it, the content of the caption
 %  can be entered using \cs{theHelpCaption}.
 %    \begin{macrocode}
-\newcommand{\helpImage}[1][]{{%
-    \ifincludehelp{\setbox0 = \hbox{%
-        \includegraphics[draft,width=\helpImageWidth]%
-        {\imageImportPath}}%[\Ff\FfReadOnly]
-    \dimen0=\ht0 \advance\dimen0by14bp\ht0=\dimen0
-    \pushButton[\BC{}\BG{}\S{S}#1]{memoryhelp}{\the\wd0}{\the\ht0}}\fi
-}}
+\newcommand{\helpImage}[2][]{%
+    \ifincludehelp{\setbox\z@\hbox{%
+        \includegraphics[draft,width=#2]{\imageImportPath}}%
+    \dimen\z@=\ht\z@\advance\dimen\z@14bp\ht\z@=\dimen\z@
+    \pushButton[\IX{\csOf{helpimage}}\TP{2} %\CA{\helpCaption}
+    \Ff\FfReadOnly\BC{}\BG{}\S{S}#1]%
+    {memoryhelp}{\the\wd\z@}{\the\ht\z@}}\fi
+}
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\rolloverHelpButton}
+%    \begin{macrocode}
 \newcommand{\rolloverHelpButton}[3][]{%
     \ifincludehelp
         \pushButton[\CA{Help}\BC{0 0 1}\BG{0.89 0.9 0.9}
@@ -275,16 +448,16 @@
         }}}#1]{checkhelp}{#2}{#3}%
     \fi
 }
-\newcommand{\setHelpImageWidth}[1]{\def\helpImageWidth{#1}}
-\def\helpImageWidth{1in}
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\theHelpCaption}
+%    \begin{macrocode}
 \def\theHelpCaption#1{\def\helpCaption{#1}}
 \theHelpCaption{A little help}
 %    \end{macrocode}
 %    \end{macro}
-%    \end{macro}
-%    \end{macro}
-%    \end{macro}
-%    \begin{macro}{\messageBox}
+%    \begin{macro}{\messageBox}\hskip-\marginparsep\texttt
+%    {[\ameta{opts}]\darg{\ameta{wd}}\darg{\ameta{ht}}}
 % A message text field, as the user works the puzzle, the progress is reported
 % to this field.
 %    \begin{macrocode}
@@ -292,90 +465,52 @@
     \textField[#1\Ff\FfMultiline]{MsgBox}{#2}{#3}}
 %    \end{macrocode}
 %    \end{macro}
-%    \begin{macro}{\playItAgain}
-% For the \texttt{acromemory1} option, this button can be placed to reset
-% the game board, the icons are rearranged hand hidden again.
+%    \begin{macro}{\playItAgain}\hskip-\marginparsep\texttt
+%    {[\ameta{opts}]\darg{\ameta{wd}}\darg{\ameta{ht}}}
+% For the \texttt{acromemory2} option, this button can be placed to reset
+% the two memory boards, so the memory game can be played again.
 %    \begin{macrocode}
-\newcommand{\playItAgain}[3][]{\ifacromemoryi{\small
-    \pushButton[\CA{Play again}#1\A{\JS{playagain();}}]%
-    {playAgain}{#2}{#3}}%
-    \fi
+\newcommand{\playItAgain}[3][]{\ifacromemoryi
+    \pushButton[\CA{Play again}#1\AAmouseup{playagain();}]%
+    {playAgain}{#2}{#3}\fi
 }
 %    \end{macrocode}
 %    \end{macro}
-%    \begin{macro}{\ulCornerHere}
-%    \begin{macro}{\LulCornerHere}
-%    \begin{macro}{\RulCornerHere}
-%    \begin{macro}{\reserveSpaceByDimension}
-%    \begin{macro}{\reserveSpaceByFile}
-% This group of buttons appear together. \cs{ulCornerHere} is used to
-% set the upper left corner of the game board in the case of the
-% \texttt{acromemory1} option; while \cs{LulCornerHere} and \cs{RulCornerHere}
-% do the same thing for the \texttt{acromemory2} option. One of the two commands
-% \cs{reserveSpaceByDimension} or \cs{reserveSpaceByFile} immediately follow
-% the `corner' commands.
-%    \begin{macrocode}
-\def\ulCornerHere{\makebox[0pt][l]%
-    {\pushButton[\autoCenter{n}]{ulcorner}{0pt}{0pt}%
-     \pushButton[\autoCenter{n}\BC{}\BG{}\FB{true}\I{null}\TP{1}]{nullIconBtn}{0pt}{0pt}%
-    }}
-\def\LulCornerHere{\makebox[0pt][l]%
-    {\pushButton[\autoCenter{n}]{Lulcorner}{0pt}{0pt}%
-    \pushButton[\autoCenter{n}\BC{}\BG{}\FB{true}\I{null}\TP{1}]{nullIconBtn}{0pt}{0pt}%
-    }}
-\def\RulCornerHere{\makebox[0pt][l]%
-    {\pushButton[\autoCenter{n}]{Rulcorner}{0pt}{0pt}}}
-%    \end{macrocode}
-% The two arguments are $\texttt{\#1} = \mbox{width}$ and $\texttt{\#2} = \mbox{height}$.
+%    \begin{macro}{\playItAgain}\hskip-\marginparsep\texttt
+%    {[\ameta{opts}]\darg{\ameta{wd}}\darg{\ameta{ht}}}
+% For the \texttt{acromemory1} option, this button can be placed to reset
+% the game board, the icons are rearranged hand hidden again.
 %    \begin{macrocode}
-\def\reserveSpaceByDimension#1#2{%
-    \hbox{\ifpreview\setlength\fboxrule{0.4pt}\setlength\fboxsep{0pt}%
-    \@tempdima=#1\advance\@tempdima by-\fboxrule
-    \@tempdimb=#2\advance\@tempdimb by-\fboxrule
-    \fbox{\parbox[t][\@tempdimb][t]{\@tempdima}{\kern0pt\hfill\vfill}}%
-    \else\parbox[t][#2][t]{#1}{\kern0pt\hfill\vfill}\fi}%
+\newcommand{\tryItAgain}[3][]{\ifacromemoryi\else
+    \pushButton[\CA{Test Your Memory}#1\AAmouseup{tryAgain();}]%
+    {testYourMemory}{#2}{#3}\fi
 }
 %    \end{macrocode}
-% The optional argument can be used to insert a file that has the same aspect ratio as
-% the puzzle, the default is the one specified by the optional argument of
-% \cs{theImportPath}, which, if not specified, is the same as the required argument
-% of \cs{theImportPath}
-%    \begin{macrocode}
-\newcommand{\reserveSpaceByFile}[1][\imageImportPath]%
-    {{\setbox0=\hbox{\includegraphics[draft,width=\texImageWidth]{#1}}%
-    \reserveSpaceByDimension{\wd0}{\ht0}}}
-%    \end{macrocode}
-%    \end{macro}
-%    \end{macro}
-%    \end{macro}
-%    \end{macro}
 %    \end{macro}
+%
 % \section{Document JavaScript for \textsf{AcroMemory}}
-% Most of the work of this package is done with document JavaScript, and here
-% it is.
-%\par\medskip\noindent
-%\StopEventually{JavaScript listing suppressed,
-% comment out \cs{OnlyDescription} at the beginning of this file to see
-% the JavaScript.}
+% Operational support is provide by JavaScript.
 %    \begin{macrocode}
-\begin{insDLJS*}[_MemLoaded]{memjs}
+\newcommand{\initFirstiMsg}{"Press the 'Play again'
+  button to initialize the puzzle"}
+\newcommand{\initFirstiiMsg}{"Press the 'Test Your Memory'
+  button to initialize the puzzle"}
+\begin{insDLJS*}{memjs}
 \begin{newsegment}{AcroMemory 1: Global Data and Initialization}
 // Global Data:
-_MemLoaded=true;
-var randomDPS = new Array(\nTotalTiles+1);
-var imageNames = new Array();
-imageNames.push("null");
-
-var dpsl = randomDPS.length;
+var isRandomized=false;
+var randomAM = new Array(\nTotalTiles+1);
+var imageNames = new Array(\AMIndxList);
+imageNames.push(\AMIndxList);
+imageNames.unshift("null");
+var dpsl = randomAM.length;
 var timeout = 10;
 var shutdown, rAE;
 var ok2Continue = true;
-var nRows = \nRows;
-var nCols = \nCols;
-var nCorrect = 0;
-var nAttempts = 0;
-
-for (i=1; i<=\nTotalTiles; i++) randomDPS[i]=i;
+var nRowsAM, nColsAM;
+var nCorrectAM = 0;
+var nAttemptsAM = 0;
+for (i=1; i<=\nTotalTiles; i++) randomAM[i]=i;
 %    \end{macrocode}
 % We get the push button with a null icon (nullIconBtn) We get the null icon object
 % from it. This technique eliminates the previous need for the Acrobat application when
@@ -386,28 +521,14 @@ var f=this.getField("nullIconBtn");
 var nullIcon=f.buttonGetIcon();
 var debug = \memDebug;
 \end{newsegment}
-
 \begin{acromemory1}
 \begin{newsegment}{AcroMemory 2: Initialize Pic Names}
-var nttl = \nTotalTiles/2;
-for ( var i = 1; i <= nttl; i++)
-{
-    imageNames.push("pic"+i +".0");
-    imageNames.push("pic"+i +".1");
-}
 var currentChoice = "";
-var currentTile1 = 0;
-var currentTile2 = 0;
 var currentIconName = "";
 \end{newsegment}
 \end{acromemory1}
 \begin{acromemory2}
 \begin{newsegment}{AcroMemory 2: Initialize Pic Names}
-var nttl = \nTotalTiles;
-for ( var i = 1; i <= nttl; i++)
-{
-    imageNames.push("pic."+i);
-}
 var LcurrentChoice = 0;
 var LcurrentTile = 0;
 var RcurrentChoice = 0;
@@ -415,9 +536,7 @@ var RcurrentTile = 0;
 \end{newsegment}
 \end{acromemory2}
 \begin{newsegment}{AcroMemory 3: Bubble Sort}
-// Clear DPS:
-
-function clearDPS()
+function clearAM()
 {
     for ( var i=1; i<=\nTotalTiles; i++ )
     {
@@ -425,9 +544,7 @@ function clearDPS()
         f.buttonSetIcon(nullIcon);
     }
 }
-
-// Mixup DPS:
-function mixupDPS()
+function mixupAM()
 {
     var i, rand;
     for (i=1; i<= \nTotalTiles; i++)
@@ -437,50 +554,51 @@ function mixupDPS()
         rand = Math.ceil(rand);
         rand = rand \% dpsl;
         if (rand == 0 ) rand = 1;
-        temp = randomDPS[i];
-        randomDPS[i]=randomDPS[rand];
-        randomDPS[rand]=temp;
+        temp = randomAM[i];
+        randomAM[i]=randomAM[rand];
+        randomAM[rand]=temp;
     }
 }
-
-// Show DPS:
-function showDPS()
+function showAM()
 {
     for ( var i=1; i<=\nTotalTiles; i++ )
     {
-        var oIcon = this.getIcon(imageNames[randomDPS[i]]);
+        var oIcon = this.getIcon(imageNames[randomAM[i]]);
         var f = this.getField("Mem\RanIdentifier button."+i);
         f.buttonSetIcon(oIcon);
     }
 }
-
-// Sortout DPS: begin bubble sort
-function sortoutDPS()
+// Begin bubble sort
+function sortoutAM()
 {
-    outerLoop(randomDPS.length-1);
+    outerLoop(randomAM.length-1);
 }
 function outerLoop(i)
 {
-     if ( ok2Continue && (i >= 0) ) shutdown = app.setTimeOut("app.clearTimeOut(shutdown); innerLoop("+i+",1);", timeout);
+     if ( ok2Continue && (i >= 0) ) shutdown = %
+app.setTimeOut("app.clearTimeOut(shutdown); %
+innerLoop("+i+",1);", timeout);
 }
 function innerLoop(i,j)
 {
     if ( j <= i )
     {
-       if (randomDPS[j-1] > randomDPS[j])
+       if (randomAM[j-1] > randomAM[j])
        {
-            var temp = randomDPS[j-1];
-            randomDPS[j-1] = randomDPS[j];
-            randomDPS[j] = temp;
-            var oIcon = this.getIcon(imageNames[randomDPS[j-1]]);
+            var temp = randomAM[j-1];
+            randomAM[j-1] = randomAM[j];
+            randomAM[j] = temp;
+            var oIcon = this.getIcon(imageNames[randomAM[j-1]]);
             var f = this.getField("Mem\RanIdentifier button."+(j-1));
             f.buttonSetIcon(oIcon);
-            var oIcon = this.getIcon(imageNames[randomDPS[j]]);
+            var oIcon = this.getIcon(imageNames[randomAM[j]]);
             var f = this.getField("Mem\RanIdentifier button."+j);
             f.buttonSetIcon(oIcon);
         }
         j++
-        if ( ok2Continue ) shutdown = app.setTimeOut("app.clearTimeOut(shutdown); innerLoop("+i+","+j+");", timeout);
+        if ( ok2Continue ) shutdown = %
+app.setTimeOut("app.clearTimeOut(shutdown); %
+innerLoop("+i+","+j+");", timeout);
     }
     else
     {
@@ -489,19 +607,28 @@ function innerLoop(i,j)
     }
 }
 function randomizePuzzle() {
-    mixupDPS();
+    mixupAM();
     for ( var i=1; i<=\nTotalTiles; i++) {
         var g = this.getField("Mem\RanIdentifier button."+i);
-        var oIcon = this.getIcon(imageNames[randomDPS[i]]);
+        var oIcon = this.getIcon(imageNames[randomAM[i]]);
         g.buttonSetIcon(oIcon,1);
         if (debug) g.buttonSetIcon(oIcon,0);
     }
+    isRandomized=true;
 }
 \end{newsegment}
 \begin{acromemory1}
 \begin{newsegment}{AcroMemory 4: Tile Processing}
+var currentIndex="";
+var currentName="";
+var _bOK1=true;
 function selectTile() // right side randomly arranged
 {
+    if(!isRandomized){
+      app.alert(\initFirstiMsg);
+      return;
+    }
+    if (!_bOK1) return;
     var f = event.target;
     var oIcon = f.buttonGetIcon(1);
     f.buttonSetIcon(oIcon,0);
@@ -509,41 +636,37 @@ function selectTile() // right side randomly arranged
     var re1 = /Membutton\.(\d+)/;
     var index = re1.exec(fname);
     if (debug) console.println("index = " + index[1]);
-    var thisiconName = imageNames[randomDPS[index[1]]];
+    var thisiconName = imageNames[randomAM[index[1]]];
     if (debug) console.println("thisiconName = " + thisiconName);
-    var re = /pic(\d+)\.(\d)/;
-    var image = re.exec(thisiconName)
-    if (debug) console.println("selected: " + image[1] + "." + image[2]);
     if ( currentChoice == "" ) {
         currentChoice = fname;
-        currentTile1=image[1];
-        currentTile2=image[2];
         currentIconName = thisiconName;
         return;
     }
-    if ( (image[1] == currentTile1) && (image[2] != currentTile2) )
+    if ( (thisiconName == currentIconName) )
     { // right choice
-        nCorrect++;
-        nAttempts++
+        nCorrectAM++;
+        nAttemptsAM++
         f.readonly = true;
         var g = this.getField(currentChoice);
         g.readonly = true;
-        reportProgress(nCorrect,nAttempts);
-        resetCounters();
+        reportProgress(nCorrectAM,nAttemptsAM);
+        resetCountersAM();
 
     } else { // wrong choice
-        nAttempts++
-        reportProgress(nCorrect,nAttempts);
-        rAE = app.setTimeOut("resetAfterError(\""+currentChoice+"\",\""+fname+"\")", 1000);
-        resetCounters();
+        nAttemptsAM++
+        _bOK1=false;
+        reportProgress(nCorrectAM,nAttemptsAM);
+        rAE = app.setTimeOut(%
+"resetAfterError(\""+currentChoice+"\",\""+fname+"\");%
+_bOK1=true;", 1000);
+        resetCountersAM();
     }
 
 }
-function resetCounters ()
+function resetCountersAM ()
 {
     currentChoice = "";
-    currentTile1 = 0;
-    currentTile2 = 0;
     currentIconName = "";
 }
 function resetAfterError(l,r)
@@ -552,9 +675,7 @@ function resetAfterError(l,r)
     var f = this.getField(l);
     var g = this.getField(r);
     if (!debug) g.buttonSetIcon(nullIcon,0);
-//    g.strokeColor=color.black;
     if (!debug) f.buttonSetIcon(nullIcon,0);
-//    f.strokeColor=color.black;
 }
 function executePostGameEffects() {return;}
 function playagain()
@@ -565,28 +686,49 @@ function playagain()
     }
     g = this.getField("Membutton");
     g.readonly=false;
-    resetCounters();
-    nCorrect = 0;
-    nAttempts = 0;
-    reportProgress(nCorrect,nAttempts);
+    resetCountersAM();
+    nCorrectAM = 0;
+    nAttemptsAM = 0;
+    reportProgress(nCorrectAM,nAttemptsAM);
     randomizePuzzle();
 }
 \end{newsegment}
 \end{acromemory1}
 \begin{acromemory2}
 \begin{newsegment}{AcroMemory 4: Tile Processing}
+// save original positions of fields
+var aLRect=new Array();
+var aRRect=new Array();
+aLRect.push("null");
+aRRect.push("null");
+var f=this.getField("MemLbutton");
+var g=f.getArray();
+for (var i=0; i<g.length; i++)aLRect.push(g[i].rect);
+var f=this.getField("MemRbutton");
+var g=f.getArray();
+for (var i=0; i<g.length; i++)aRRect.push(g[i].rect);
+%    \end{macrocode}
+%    \begin{macrocode}
+var _bOK2=true;
 function selectRandomTile(nCnt,n) // right side randomly arranged
 {
+      if(!isRandomized){
+      app.alert(\initFirstiiMsg);
+      return;
+    }
+    if (!_bOK2) return;
     if ( RcurrentChoice != 0 ) return;
     RcurrentChoice = nCnt;
     RcurrentTile = n;
-    nAttempts++;
+    nAttemptsAM++;
     var f = event.target;
     f.strokeColor = ["RGB", 0, .6, 0];
     var oIcon = f.buttonGetIcon(1);
     f.buttonSetIcon(oIcon,0);
     if ( LcurrentChoice != 0 ) {
-        if (debug) console.println("LcurrentChoice = " + LcurrentChoice + ", RcurrentChoice = " + RcurrentChoice);
+        if (debug) console.println(%
+"LcurrentChoice = " + LcurrentChoice + ", RcurrentChoice = " %
++ RcurrentChoice);
         if ( LcurrentChoice == nCnt ) {// right answer
             // need to make right side hidden and readonly
             // need to make this button readonly
@@ -595,20 +737,30 @@ function selectRandomTile(nCnt,n) // right side randomly arranged
             g.readonly = true;
             f.strokeColor=color.transparent;
             f.readonly = true;
-            if (++nCorrect == \nTotalTiles ) // game complete
+            if (++nCorrectAM == \nTotalTiles ) // game complete
                 executePostGameEffects();
-            reportProgress(nCorrect,nAttempts);
-            resetCounters();
+            reportProgress(nCorrectAM,nAttemptsAM);
+            resetCountersAM();
         } else { // wrong answer
             // need to set current choices back to zero
-            reportProgress(nCorrect,nAttempts);
-            rAE = app.setTimeOut("resetAfterError("+LcurrentTile+","+RcurrentTile+")", 1000);
-            resetCounters();
+            reportProgress(nCorrectAM,nAttemptsAM);
+            _bOK2=false;
+            rAE = app.setTimeOut("resetAfterError(%
+"+LcurrentTile+","+RcurrentTile+");_bOK2=true;", 1000);
+            resetCountersAM();
         }
     }
 }
-function selectNonRandomTile(nCnt,n) // left side, arranged in natural order
+%    \end{macrocode}
+%    \begin{macrocode}
+// left side, arranged in natural order
+function selectNonRandomTile(nCnt,n)
 {
+      if(!isRandomized){
+      app.alert(\initFirstiiMsg);
+      return;
+    }
+    if (!_bOK2) return
     if ( LcurrentChoice != 0 ) return;
     LcurrentChoice = nCnt;
     LcurrentTile = n;
@@ -617,7 +769,9 @@ function selectNonRandomTile(nCnt,n) // left side, arranged in natural order
     var oIcon = f.buttonGetIcon(1);
     f.buttonSetIcon(oIcon,0);
     if ( RcurrentChoice != 0 ) {
-        if (debug) console.println("LcurrentChoice = " + LcurrentChoice + ", RcurrentChoice = " + RcurrentChoice);
+        if (debug) console.println(%
+"LcurrentChoice = " + LcurrentChoice + ", RcurrentChoice = " %
++ RcurrentChoice);
         if ( RcurrentChoice == nCnt ) {// right answer
             // need to make right side hidden and readonly
             // need to make this button readonly
@@ -626,25 +780,32 @@ function selectNonRandomTile(nCnt,n) // left side, arranged in natural order
             g.readonly = true;
             f.readonly = true;
             f.strokeColor=color.transparent;
-            if (++nCorrect == \nTotalTiles ) // game complete
+            if (++nCorrectAM == \nTotalTiles ) // game complete
                 executePostGameEffects();
-            reportProgress(nCorrect,nAttempts);
-            resetCounters();
+            reportProgress(nCorrectAM,nAttemptsAM);
+            resetCountersAM();
         } else { // wrong answer
             // need to set current choices back to zero
-            reportProgress(nCorrect,nAttempts);
-            rAE = app.setTimeOut("resetAfterError("+LcurrentTile+","+RcurrentTile+")", 1000);
-            resetCounters();
+            reportProgress(nCorrectAM,nAttemptsAM);
+            _bOK2=false;
+            rAE = app.setTimeOut(%
+"resetAfterError("+LcurrentTile+","+RcurrentTile+");%
+_bOK2=true;", 1000);
+            resetCountersAM();
         }
     }
 }
-function resetCounters ()
+%    \end{macrocode}
+%    \begin{macrocode}
+function resetCountersAM ()
 {
     LcurrentChoice = 0;
     RcurrentChoice = 0;
     LcurrentTile = 0;
     RcurrentTile = 0;
 }
+%    \end{macrocode}
+%    \begin{macrocode}
 function resetAfterError(l,r)
 {
     try { app.clearTimeOut(rAE); } catch(e) {};
@@ -655,8 +816,38 @@ function resetAfterError(l,r)
     if (!debug) f.buttonSetIcon(nullIcon,0);
     f.strokeColor=color.black;
 }
+%    \end{macrocode}
+%    \begin{macrocode}
+function tryAgain() {
+  nCorrectAM=0;
+  nAttemptsAM=0;
+  reportProgress(nCorrectAM,nAttemptsAM);
+%  this.resetForm("MsgBox");
+  resetCountersAM();
+  this.delay=true;
+  for(var i=1; i<=20; i++) {
+    var f=this.getField("MemLbutton."+i);
+    var g=this.getField("MemRbutton."+i);
+    f.buttonSetIcon(nullIcon,0);
+    f.rect=aLRect[i];
+    g.buttonSetIcon(nullIcon,0);
+    g.rect=aRRect[i];
+  }
+  var f=this.getField("MemLbutton");
+  var g=this.getField("MemRbutton");
+  f.lineWidth=1;
+  f.strokeColor=color.black;
+  f.readonly=false;
+  g.lineWidth=1;
+  g.strokeColor=color.black;
+  g.readonly=false;
+  this.delay=false;
+  randomizePuzzle();
+}
+%    \end{macrocode}
+%    \begin{macrocode}
 function executePostGameEffects() {
-    sortoutDPS();
+    sortoutAM();
     var fL = this.getField("MemLbutton.1");
     var fR = this.getField("MemRbutton.1");
     var LulCorner = fL.rect;
@@ -664,254 +855,44 @@ function executePostGameEffects() {
     var mWidth = LulCorner[2]-LulCorner[0];
     var mHeight = LulCorner[1]-LulCorner[3];
     var nCnt = 0;
-    for ( var i=0; i<nRows; i++) {
-        for ( var j=0; j<nCols; j++ ) {
+    for ( var i=0; i<nRowsAM; i++) {
+        for ( var j=0; j<nColsAM; j++ ) {
             nCnt++;
             try {
                 var g = this.getField("MemLbutton."+nCnt);
-                g.rect  = [ LulCorner[0]+j*mWidth, LulCorner[1]-i*mHeight, LulCorner[0]+(j+1)*mWidth, LulCorner[1]-(i+1)*mHeight ]
+                g.rect  = %
+[ LulCorner[0]+j*mWidth, LulCorner[1]-i*mHeight, %
+LulCorner[0]+(j+1)*mWidth, %
+LulCorner[1]-(i+1)*mHeight ]
                 g.lineWidth = 0;
                 g.strokeColor = color.transparent;
-
+%    \end{macrocode}
+%    \begin{macrocode}
                 var h = this.getField("MemRbutton."+nCnt);
-                h.rect  = [ RulCorner[0]+j*mWidth, RulCorner[1]-i*mHeight, RulCorner[0]+(j+1)*mWidth, RulCorner[1]-(i+1)*mHeight ]
+                h.rect  = [ RulCorner[0]+j*mWidth, %
+RulCorner[1]-i*mHeight, %
+RulCorner[0]+(j+1)*mWidth, RulCorner[1]-(i+1)*mHeight ]
                 h.lineWidth = 0;
                 h.strokeColor = color.transparent;
-
-            } catch(e) { console.println("set properties: " + e.toSource()) }
+            } catch(e) { %
+console.println("set properties: " + e.toSource()) }
         }
     }
 }
 \end{newsegment}
 \end{acromemory2}
 \begin{newsegment}{AcroMemory 5: Reporting}
-function reportProgress(nCorrect,nAttempts) {
+function reportProgress(nCorrectAM,nAttemptsAM) {
     var Msg = this.getField("MsgBox")
     if ( Msg != null ) {
-    Msg.value = "Number matched = " + nCorrect
-        + "\n Number of attempts = " + nAttempts;
+    Msg.value = "Number matched = " + nCorrectAM
+        + "\n Number of attempts = " + nAttemptsAM;
     }
 }
-try { randomizePuzzle(); } catch(e) {}
+%try { randomizePuzzle(); } catch(e) {}
+%var to=app.setTimeOut("randomizePuzzle();",1000);
 \end{newsegment}
 \end{insDLJS*}
-
-\begin{acromemory1}
-\begin{execJS}{acromemjs}
-var l = \nTotalTiles/2;
-var pt2bpScaleFactor = 72/72.27;
-if (\iconsInOneFile) {
-    for ( var i = 0; i < l; i++)
-    {
-        try {
-            aebTrustedFunctions(this, aebImportIcon, {cName: "pic"+(i+1) +".0", cDIPath: "\importpath.pdf", nPage: i }, this);
-            aebTrustedFunctions(this, aebImportIcon, {cName: "pic"+(i+1) +".1", cDIPath: "\importpath.pdf", nPage: i }, this);
-        }
-        catch(e) {console.println("exception: " + e.toSource())}
-    }
-} else {
-    var index, j;
-    for ( var i = 0; i < l; i++)
-    {
-        try {
-            j = i+1;
-            index = ( j < 10 ) ? "0"+j : ""+j;
-            if (debug) console.println("Importing: \importpath_"+index+".\iconsExt")
-            aebTrustedFunctions(this, aebImportIcon, {cName: "pic"+j+".0", cDIPath: "\importpath_"+index+".\iconsExt"}, this);
-            aebTrustedFunctions(this, aebImportIcon, {cName: "pic"+j+".1", cDIPath: "\importpath_"+index+".\iconsExt"}, this);
-        }
-        catch(e) {console.println("import exception: " + e.toSource())}
-    }
-}
-
-// Now lay out the icon fields.
-var f = this.getField("ulcorner");
-var ulCorner = f.rect;
-var nPage = f.page;
-this.removeField("ulcorner");
-
-if (\bProvideDimen) {
-    var width = \trueImageWidth*pt2bpScaleFactor;
-    var height =\trueImageHeight*pt2bpScaleFactor;
-} else {
-    var doc = aebTrustedFunctions( this, aebAppOpenDoc, { cPath: "\importpath.pdf", oDoc: this });
-    var aRect = doc.getPageBox({cBox:"Crop"})
-    doc.closeDoc(true);
-    var width = aRect[2]-aRect[0];
-    var height = aRect[1]-aRect[3];
-}
-var scaleFactor = (\imageWidth*pt2bpScaleFactor)/width;
-
-var scaledWidth = width*scaleFactor;
-var scaledHeight = height*scaleFactor;
-
-if (debug) {
-    console.println("scaleFactor = " + scaleFactor);
-    console.println("scaledWidth = " + scaledWidth);
-    console.println("scaledHeight = " + scaledHeight);
-}
-
-var mWidth = scaledWidth/nCols
-var mHeight = scaledHeight/nRows
-
-var nCnt = 0;
-
-for ( var i=0; i<nRows; i++) {
-    for ( var j=0; j<nCols; j++ ) {
-        nCnt++;
-        try {
-        var g = this.addField({
-            cName: "Membutton."+nCnt,
-            cFieldType: "button",
-            nPageNum: nPage,
-            oCoords: [ ulCorner[0]+j*mWidth, ulCorner[1]-i*mHeight, ulCorner[0]+(j+1)*mWidth, ulCorner[1]-(i+1)*mHeight ]
-        });
-        } catch(e) { console.println( e.toSource() ); }
-        try {
-            g.highlight=highlight.p
-            g.buttonPosition = position.iconOnly;
-            g.lineWidth = 1;
-            g.strokeColor = color.black;
-            g.setAction("MouseDown", "selectTile();")
-        } catch(e) { console.println("set properties: " + e.toSource()) }
-        try {
-          var pNCnt = nCnt + 1;
-          var index = parseInt( pNCnt/2)
-          var oIcon = this.getIcon("pic"+index+"."+ ( pNCnt \% 2 ));
-          g.buttonSetIcon(oIcon,1);
-          if (debug) g.buttonSetIcon(oIcon,0);
-        } catch(e) { console.println("set properties: " + e.toSource()) }
-    }
-}
-try { randomizePuzzle(); } catch(e) { console.println("execJS--randomizePuzzle exceptions: " + e.toSource()) }
-var isRandomized = true;
-\end{execJS}
-\end{acromemory1}
-
-\begin{acromemory2}
-\begin{execJS}{execjs}
-var index;
-var pt2bpScaleFactor = 72/72.27;
-if (\iconsInOneFile) {
-    for ( var i = 1; i <= \nTotalTiles; i++)
-    {
-        index = ( i < 10 ) ? "0"+i : ""+i;
-        if (debug) console.println("\importpath_"+index+".\iconsExt")
-        try { aebTrustedFunctions(this, aebImportIcon, {cName: "pic."+i, cDIPath: "\importpath.pdf", nPage: (i-1) }, this);
-        }
-        catch(e) {console.println("exception: " + e.toSource())}
-    }
-} else {
-    for ( var i = 1; i <= \nTotalTiles; i++)
-    {
-        index = ( i < 10 ) ? "0"+i : ""+i;
-        if (debug) console.println("\importpath_"+index+".\iconsExt")
-        try { aebTrustedFunctions(this, aebImportIcon, {cName: "pic."+i, cDIPath: "\importpath_"+index+".\iconsExt"}, this);
-        }
-        catch(e) {console.println("exception: " + e.toSource())}
-    }
-}
-// Now lay out the icon fields.
-var f = this.getField("Lulcorner");
-var ulCorner = f.rect;
-var nPage = f.page;
-this.removeField("Lulcorner");
-
-if (\bProvideDimen) {
-    var width = \trueImageWidth*pt2bpScaleFactor;
-    var height =\trueImageHeight*pt2bpScaleFactor;
-} else {
-    var doc = aebTrustedFunctions( this, aebAppOpenDoc, { cPath: "\imageImportPath.pdf", oDoc: this });
-    var aRect = doc.getPageBox({cBox:"Crop"})
-    doc.closeDoc(true);
-    var width = aRect[2]-aRect[0];
-    var height = aRect[1]-aRect[3];
-}
-var scaleFactor = (\imageWidth*pt2bpScaleFactor)/width;
-
-var scaledWidth = width*scaleFactor;
-var scaledHeight = height*scaleFactor;
-
-if (debug) {
-    console.println("scaleFactor = " + scaleFactor);
-    console.println("scaledWidth = " + scaledWidth);
-    console.println("scaledHeight = " + scaledHeight);
-}
-
-var mWidth = scaledWidth/nCols
-var mHeight = scaledHeight/nRows
-
-%console.println("mWidth = " + mWidth);
-%console.println("mHeight = " + mHeight);
-
-var nCnt = 0;
-
-for ( var i=0; i<nRows; i++) {
-    for ( var j=0; j<nCols; j++ ) {
-        nCnt++;
-        try {
-        var g = this.addField({
-            cName: "MemLbutton."+nCnt,
-            cFieldType: "button",
-            nPageNum: nPage,
-            oCoords: [ ulCorner[0]+j*mWidth, ulCorner[1]-i*mHeight, ulCorner[0]+(j+1)*mWidth, ulCorner[1]-(i+1)*mHeight ]
-        });
-        } catch(e) { console.println( e.toSource()); }
-        try {
-            g.highlight=highlight.p
-            g.buttonPosition = position.iconOnly;
-            g.lineWidth = 1;
-            g.strokeColor = color.black;
-            g.setAction("MouseDown", "selectNonRandomTile("+nCnt+","+nCnt+");")
-        } catch(e) { console.println("set properties: " + e.toSource()) }
-          var oIcon = this.getIcon("pic."+nCnt);
-          g.buttonSetIcon(oIcon,1);
-          if (debug) g.buttonSetIcon(oIcon,0);
-    }
-}
-// Now lay out the icon fields.
-var f = this.getField("Rulcorner");
-var ulCorner = f.rect;
-this.removeField("Rulcorner");
-
-var nCnt = 0;
-
-for ( var i=0; i<nRows; i++) {
-    for ( var j=0; j<nCols; j++ ) {
-        nCnt++;
-        try {
-        var g = this.addField({
-            cName: "MemRbutton."+nCnt,
-            cFieldType: "button",
-            nPageNum: nPage,
-            oCoords: [ ulCorner[0]+j*mWidth, ulCorner[1]-i*mHeight, ulCorner[0]+(j+1)*mWidth, ulCorner[1]-(i+1)*mHeight ]
-        });
-        } catch(e) { console.println( e.toSource()); }
-        try {
-        g.highlight=highlight.p
-        g.buttonPosition = position.iconOnly;
-        g.lineWidth = 1;
-        g.strokeColor = color.black;
-        g.setAction("MouseDown", "selectRandomTile(randomDPS["+nCnt+"],"+nCnt+");")
-        } catch(e) { console.println("set properties: " + e.toSource()) }
-    }
-}
-try { randomizePuzzle(); } catch(e) { console.println("randomizePuzzle exceptions: " + e.toSource()) }
-var isRandomized = true;
-\end{execJS}
-\end{acromemory2}
-\begin{needhelp}
-\begin{execJS}{helpjs}
-try {
-    aebTrustedFunctions(this, aebImportIcon, {cName: "helpicon", cDIPath: "\imageImportPath.\iconsExt"}, this);
-    var f = this.getField("memoryhelp");
-    var oIcon = this.getIcon("helpicon");
-    f.buttonPosition = position.iconOnly;
-    f.buttonSetIcon(oIcon,1);
-    f.buttonSetCaption({cCaption: "\helpCaption"});
-} catch(e) {console.println("exception: " + e.toSource())}
-\end{execJS}
-\end{needhelp}
 %</package>
 %    \end{macrocode}
 %  \Finale
-- 
cgit v1.2.3

