% \iffalse meta-comment
% ==================================================
% exam-rtl.dtx – LaTeX Exam Package (RTL/Arabic)
% Version: 1.0
% Date: 2026/08/20
% 
% Copyright (C) 2026 by Nadeer Aljaroudi
%
% This file may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3c of this license or (at your option) any later
% version.
% ==================================================
% \fi

% \iffalse
%<*driver>
\documentclass{ltxdoc}
\usepackage{xcolor}
\usepackage{tcolorbox}
\tcbuselibrary{skins, breakable}
\usepackage{enumitem}
\usepackage[hyperindex=false]{hyperref}
\hypersetup{colorlinks=true,linkcolor=blue}
\EnableCrossrefs
\RecordChanges
\OnlyDescription   % لا نعرض الكود في PDF

\begin{document}
  \DocInput{exam-rtl.dtx}
\end{document}
%</driver>
% \fi

% \changes{v1.0}{2026/08/20}{Initial Arabic/RTL release}

% \GetFileInfo{exam-rtl.dtx}

% \title{^^A
%   \textsf{exam-rtl} --- An Arabic/RTL Exam Package\thanks{^^A
%     This file has version v1.0, dated 2026-08-20.}^^A
% }
%
% \author{Nadeer Aljaroudi}
% \date{2026-08-20}
%
% \maketitle
%
% \begin{abstract}
%   The \textsf{exam-rtl} package is the Arabic/RTL version of
%   \textsf{exam-ltr}. It provides a comprehensive framework for
%   creating professional exams in Arabic and Right-to-Left (RTL)
%   languages. It supports a wide variety of question types,
%   including Multiple Choice, True/False, Fill in the Blank,
%   Ordering, Matching, Essay, Short Answer, and Reading Passages.
%
%   Key features include automatic answer key generation, controlled
%   randomization of options and matching items, and full support for
%   RTL text alignment and Eastern Arabic numerals.
% \end{abstract}
%
% \tableofcontents
%
% \section{Introduction}
%
% The \textsf{exam-rtl} package is the Arabic/RTL version of \textsf{exam-ltr}.
% It provides a clean and robust environment for building professional exams
% without manual formatting. Built with educators in mind, it allows you to
% focus on creating high-quality question content while the package handles
% question layout and RTL alignment automatically.
%
% \medskip
% \textbf{Key features:}
% \begin{itemize}
%   \item \textbf{8 Dedicated Question Types}: MC, TF, FillBlank, Ordering,
%         Matching, Essay, ShortAnswer, and ReadingPassage.
%   \item \textbf{Automated Answer Keys}: Answers are collected and displayed
%         directly after each question in teacher mode.
%   \item \textbf{Smart Randomization}: Shuffles options, matching columns,
%         and ordering items in a reproducible manner.
%   \item \textbf{Metadata Display}: Show or hide marks, difficulty levels,
%         and question type tags.
%   \item \textbf{Dual-Mode Output}: Switch between student version (answers
%         hidden) and teacher version (answers shown).
%   \item \textbf{Arabic Support}: RTL text alignment and Eastern Arabic numerals.
% \end{itemize}
%
% \section{Requirements}
%
% \begin{itemize}
%   \item \textbf{LaTeX engine}: XeLaTeX (PDFLaTeX and LuaLaTeX are \textbf{not} supported)
%   \item \textbf{Fonts}: IBM Plex Sans Arabic (default) – ensure it is installed on your system
%   \item \textbf{Required packages} (loaded automatically):
%         \texttt{xcolor}, \texttt{tcolorbox}, \texttt{fontspec},
%         \texttt{polyglossia}, \texttt{bidi}, \texttt{expl3}, \texttt{xparse}
% \end{itemize}
%
% \section{Installation}
%
% The \texttt{exam-rtl} package is distributed through CTAN and is included
% in all major LaTeX distributions (TeX Live, MiKTeX, MacTeX). In most cases,
% no manual installation is needed; the system's package manager will handle
% it automatically.
%
% If manual installation is required, use one of the following methods.
%
% \subsection*{Quick Installation (Single Project)}
%
% \begin{enumerate}
%   \item Place \texttt{exam-rtl.sty} in the same folder as your \texttt{.tex} file.
%   \item Add \texttt{\textbackslash usepackage\{exam-rtl\}} to your preamble.
% \end{enumerate}
%
% \subsection*{Permanent Installation (All Projects)}
%
% \subsubsection*{Linux / macOS}
% \begin{enumerate}
%   \item Create the target directory:\\
%         \texttt{mkdir -p \~{}/texmf/tex/latex/exam-rtl}
%
%   \item Copy the package file into this directory:\\
%         \texttt{cp exam-rtl.sty \~{}/texmf/tex/latex/exam-rtl/}
%
%   \item Update the LaTeX file database:\\
%         \texttt{texhash \~{}/texmf}
% \end{enumerate}
%
% \subsubsection*{Windows}
%
% \paragraph*{MiKTeX:}
% \begin{enumerate}
%   \item Create the folder:
%         \texttt{C:\textbackslash texmf\textbackslash tex\textbackslash latex\textbackslash exam-rtl}
%   \item Copy \texttt{exam-rtl.sty} into it.
%   \item Refresh the database via the MiKTeX Console ``Refresh FNDB''.
% \end{enumerate}
%
% \paragraph*{TeX Live:}
% \begin{enumerate}
%   \item Create the folder:
%         \texttt{C:\textbackslash texlive\textbackslash texmf-local\textbackslash tex\textbackslash latex\textbackslash exam-rtl}
%   \item Copy \texttt{exam-rtl.sty} into it.
%   \item Refresh the database by running \texttt{texhash}.
% \end{enumerate}
%
% \section{Quick Start}
%
% This section outlines the standard workflow for creating an exam with
% the \texttt{exam-rtl} package.
%
% \subsection*{Step 1: Load the Package and Configure Mode}
%
% Include the package in your document preamble and set the desired output
% mode:
%
% \begin{flushleft}\ttfamily
% \cs{documentclass}\{article\}\\
% \cs{usepackage}\{exam-rtl\}\\[1em]
%
% \cs{TeacherMode} \quad \% Show answer keys\\[1em]
%
% \cs{ShowMarks} \quad \% Display marks\\
% \cs{ShowCorrection} \quad \% Show answer boxes\\
% \cs{ExamID}\{123\} \quad \% Fix randomization seed
% \end{flushleft}
%
% \subsection*{Step 2: Structure Your Questions}
%
% Wrap every question in the \texttt{Question} environment. You must
% specify four arguments: \meta{Type}, \meta{Difficulty}, \meta{Marks},
% and \meta{Question text}:
%
% \begin{flushleft}\ttfamily
% \cs{begin}\{Question\}\marg{Type}\marg{Difficulty}\marg{Marks}\marg{Question text}\\
% \hspace*{2em}\textit{question content}\\
% \cs{end}\{Question\}
% \end{flushleft}
%
% \subsection*{Step 3: Choose the Environment for Your Question}
%
% Inside the \texttt{Question} environment, select the environment that
% matches your question type: \texttt{MC} (Multiple Choice), \texttt{TF}
% (True/False), \texttt{FillBlank}, \texttt{Ordering}, \texttt{Matching},
% \texttt{Essay}, \texttt{ShortAnswer}, or \texttt{ReadingPassage}.
%
% \subsection*{Step 4: Compile and View Output}
%
% Compile your document with \texttt{xelatex}. The output depends on the
% mode set in Step 1:
%
% \begin{itemize}
%   \item \textbf{Student Mode (default):} Answer keys are hidden.
%   \item \textbf{Teacher Mode:} Answer keys appear only when
%         \cs{ShowCorrection} is also enabled.
% \end{itemize}
%
% For complete examples in Arabic, please refer to the
% \texttt{exam-rtl-doc.tex} file included with the package.
%
% \section{Mode Commands}
%
% The package provides several switches that control the appearance of
% the final exam sheet. These switches allow you to toggle between student
% and teacher views, display metadata, and show answer boxes.
%
% \subsection*{Student and Teacher Modes}
%
% \DescribeMacro{\StudentMode}
% \DescribeMacro{\TeacherMode}
% These commands toggle between student and teacher views.
%
% \begin{flushleft}\ttfamily
% \cs{StudentMode} \quad \% Hide answer keys (default)\\
% \cs{TeacherMode} \quad \% Show answer keys
% \end{flushleft}
%
% The default mode is \cs{StudentMode}. When \cs{TeacherMode} is active,
% answer keys become visible.
%
% \subsection*{Metadata Visibility}
%
% \DescribeMacro{\ShowMarks}
% \DescribeMacro{\ShowDifficulty}
% \DescribeMacro{\ShowType}
% These commands control the visibility of question metadata.
%
% \begin{flushleft}\ttfamily
% \cs{ShowMarks} \quad \% Display marks\\
% \cs{ShowDifficulty} \quad \% Display difficulty levels\\
% \cs{ShowType} \quad \% Display question type
% \end{flushleft}
%
% Each switch is independent; any combination may be enabled.
%
% \subsection*{Correction Boxes}
%
% \DescribeMacro{\ShowCorrection}
% Enables the display of correction boxes for teacher use.
%
% \begin{flushleft}\ttfamily
% \cs{ShowCorrection}
% \end{flushleft}
%
% Only takes effect when \cs{TeacherMode} is explicitly enabled.
%
% \subsection*{Randomization Seed}
%
% \DescribeMacro{\ExamID}
% Sets a fixed seed for all randomization operations (shuffling MC options,
% ordering items, and matching pairs).
%
% \begin{flushleft}\ttfamily
% \cs{ExamID}\marg{number}
% \end{flushleft}
%
% Using the same seed guarantees identical output across compilations.
%
% \section{Question Environment}
%
% \DescribeEnv{Question}
% The Question environment is the primary container for all question
% types. It handles automatic numbering, manages metadata display
% (type, difficulty, marks), and integrates answer key collection
% in teacher mode.
%
% \subsection*{Syntax}
%
% \begin{flushleft}\ttfamily
% \cs{begin}\{Question\}\marg{Type}\marg{Difficulty}\marg{Marks}\marg{Question Text}\\
% \hspace*{2em}\textit{question content}\\
% \cs{end}\{Question\}
% \end{flushleft}
%
% \subsection*{Arguments}
%
% \begin{itemize}
%   \item \meta{Type}: Question category (MC, TF, FillBlank, Ordering,
%         Matching, Essay, ShortAnswer, ReadingPassage).
%   \item \meta{Difficulty}: Descriptive label (e.g., Easy, Medium, Hard).
%   \item \meta{Marks}: Numeric score assigned to the question.
%   \item \meta{Question Text}: Main prompt or instruction.
% \end{itemize}
%
% \subsection*{How It Works}
%
% \begin{itemize}
%   \item \textbf{Automatic Numbering:} Questions are numbered sequentially.
%
%   \item \textbf{Metadata Display:} When enabled via \cs{ShowType},
%         \cs{ShowDifficulty}, and \cs{ShowMarks}, the corresponding
%         labels are displayed alongside the question.
%
%   \item \textbf{Answer Key Collection:} When \cs{TeacherMode} and
%         \cs{ShowCorrection} are enabled, all answers are collected
%         and displayed in a dedicated answer key box.
%
%   \item \textbf{Consistent Formatting:} All question types placed
%         inside this environment share consistent spacing and layout.
% \end{itemize}
%
% \section{Question Types}
%
% \subsection{Multiple Choice (MC)}
% \DescribeEnv{MC}
% \DescribeMacro{\MCQuestion}
% \DescribeMacro{\MCOption}
% The MC environment creates multiple-choice questions with automatically
% shuffled options. Multiple questions can be placed inside a single
% MC environment, each with its own set of options. The correct answer
% is stored internally and appears in the answer key in teacher mode.
% Options are displayed in a grid layout with a customizable number
% of columns.
%
% \subsubsection*{Syntax:}
% \begin{quote}\ttfamily
% \cs{begin}\{MC\}\oarg{columns}\\
% \hspace*{2em}\cs{MCQuestion}\marg{question text}\marg{correct\_index}\\
% \hspace*{4em}\cs{MCOption}\marg{option 1}\\
% \hspace*{4em}\cs{MCOption}\marg{option 2}\\
% \hspace*{4em}\cs{MCOption}\marg{option 3}\\
% \hspace*{4em}...\\
% \cs{end}\{MC\}
% \end{quote}
%
% \subsubsection*{How It Works:}
% \begin{itemize}
%   \item \textbf{Column Layout (default: 4):} The optional \oarg{columns} argument
%         sets the number of columns for displaying options.
%         Any number can be used as long as it fits the page width.
%   \item \textbf{Correct Answer Index:} The \marg{correct\_index}
%         refers to the position of the correct option as written
%        (e.g., 1, 2, 3). This index is used internally to track
%         the correct answer after shuffling.
%   \item \textbf{Randomization:} All options inside \cs{MCQuestion}
%         are shuffled based on the global exam seed set by
%         \cs{ExamID}. This ensures reproducibility when a fixed
%         seed is provided.
%   \item \textbf{Answer Key Integration:} The correct answer is
%         collected automatically and displayed in the answer key
%         when \cs{TeacherMode} and \cs{ShowCorrection} are enabled.
% \end{itemize}
%
% \subsection{True/False (TF)}
% \DescribeEnv{TF}
% \DescribeMacro{\TFQuestion}
% The TF environment creates True/False questions. Multiple statements
% can be placed inside a single TF environment, each with its own
% correct answer. Two display styles are available: bracket style
% (default) and options style, allowing flexibility for different
% assessment needs.
%
% \subsubsection*{Syntax:}
% \begin{quote}\ttfamily
% \cs{begin}\{TF\}\oarg{style}\\
% \hspace*{2em}\cs{TFQuestion}\marg{statement}\marg{answer}\\
% \hspace*{2em}\cs{TFQuestion}\marg{statement}\marg{answer}\\
% \hspace*{2em}...\\
% \cs{end}\{TF\}
% \end{quote}
%
% \subsubsection*{How It Works:}
% \begin{itemize}
%   \item \textbf{Visual Style:} The optional \oarg{style} argument
%         selects the display format:
%     \begin{itemize}
%       \item \texttt{bracket} (default): Places an empty answer slot
%             \texttt{( )} after each statement.
%       \item \texttt{options}: Places ``True'' and ``False'' labels
%             to the right of each statement.
%     \end{itemize}
%   \item \textbf{Statement Input:} The \marg{statement} argument
%         receives the text that students must evaluate.
%   \item \textbf{Answer Specification:} The \marg{answer} argument
%         must contain either ``True'' or ``False''.
%   \item \textbf{Answer Key:} When \cs{TeacherMode} and
%         \cs{ShowCorrection} are enabled, the correct answers are
%         collected and displayed in the answer key.
%   \item \textbf{Multiple Questions:} Multiple \cs{TFQuestion}
%         commands can be placed sequentially within one TF environment.
% \end{itemize}
%
% \subsection{Fill in the Blank (FillBlank)}
% \DescribeEnv{FillBlank}
% \DescribeMacro{\WordBank}
% \DescribeMacro{\FillQuestion}
% \DescribeMacro{\Blank}
% The FillBlank environment creates fill-in-the-blank questions where
% students complete sentences with appropriate words. It supports
% single or multiple blanks per question and an optional word
% bank to assist students during assessment.
%
% \subsubsection*{Syntax:}
% \begin{quote}\ttfamily
% \cs{begin}\{FillBlank\}\oarg{wordbank}\\
% \hspace*{2em}\cs{WordBank}\oarg{separator}\marg{word1, word2, ...}\\
% \hspace*{2em}\cs{FillQuestion}\marg{text with \cs{Blank}}\marg{answer}\\
% \hspace*{2em}...\\
% \cs{end}\{FillBlank\}
% \end{quote}
%
% \subsubsection*{How It Works:}
% \begin{itemize}
%   \item \textbf{Blank Creation:} The \cs{Blank} command creates an
%         underline field where students write their answers.
%         Its optional argument \oarg{width} sets the line length
%         (default: 15mm).
%   \item \textbf{Word Bank Activation:} The optional \oarg{wordbank}
%         argument controls whether a word bank is displayed.
%         Set to \texttt{true} to show a framed list of words
%         above the questions (default is \texttt{false}).
%   \item \textbf{Word Bank Configuration:} The \cs{WordBank} command
%         defines the vocabulary list. Words must be separated by commas.
%         The optional \oarg{separator} controls spacing between words
%         (default: \cs{quad}).
%   \item \textbf{Multiple Questions:} Multiple \cs{FillQuestion}
%         commands can be placed sequentially within one FillBlank environment.
%   \item \textbf{Answer Key:} When \cs{TeacherMode} and
%         \cs{ShowCorrection} are enabled, correct answers are
%         collected and displayed in a dedicated answer key box.
% \end{itemize}
%
% \subsection{Ordering}
% \DescribeEnv{Ordering}
% \DescribeMacro{\OrderQuestion}
% \DescribeMacro{\OrderOption}
% \DescribeMacro{\OrderAnswer}
% The Ordering environment creates sequencing questions where students
% must arrange items in their correct logical order. Items must be
% written in their proper sequence inside the environment, but are
% presented to students in a shuffled layout. The original order
% is preserved for the teacher's answer key. Options are displayed
% in a grid layout with a customizable number of columns.
%
% \subsubsection*{Syntax:}
% \begin{quote}\ttfamily
% \cs{begin}\{Ordering\}\oarg{columns}\\
% \hspace*{2em}\cs{OrderQuestion}\marg{instruction}\\
% \hspace*{4em}\cs{OrderOption}\marg{item 1}\\
% \hspace*{4em}\cs{OrderOption}\marg{item 2}\\
% \hspace*{4em}\cs{OrderOption}\marg{item 3}\\
% \hspace*{4em}...\\
% \hspace*{2em}\cs{OrderAnswer}\oarg{width}\\
% \cs{end}\{Ordering\}
% \end{quote}
%
% \subsubsection*{How It Works:}
% \begin{itemize}
%   \item \textbf{Correct Sequence:} Items must be written inside
%         \cs{OrderOption} in their correct logical order. This order
%         is preserved for the answer key.
%
%   \item \textbf{Randomization:} Items are shuffled for the student
%         based on the global exam seed (\cs{ExamID}), ensuring
%         consistent randomization across compilations.
%
%   \item \textbf{Column Layout (default: 4):} The optional \oarg{columns} argument
%         sets the number of columns for displaying shuffled items.
%         Any number can be used as long as it fits the page width.
%
%   \item \textbf{Answer Space:} The \cs{OrderAnswer} command adds
%         an optional answer space with customizable width (default: 5mm) where
%         students write their final ordered sequence.
%
%   \item \textbf{Answer Key:} When \cs{TeacherMode} and
%         \cs{ShowCorrection} are enabled, the correct sequence is
%         collected and displayed in the answer key.
% \end{itemize}
%
% \subsection{Matching}
% \DescribeEnv{Matching}
% \DescribeMacro{\MatchPair}
% The Matching environment creates two-column association questions.
% Items must be written in their correct pairs inside the environment.
% The right column remains fixed and numbered, while the left column
% is automatically shuffled for students. The original pairings
% are preserved for the teacher's answer key.
%
% \subsubsection*{Syntax:}
% \begin{quote}\ttfamily
% \cs{begin}\{Matching\}\oarg{right\_ratio}\\
% \hspace*{2em}\cs{MatchPair}\marg{left item}\marg{right item}\\
% \hspace*{2em}\cs{MatchPair}\marg{left item}\marg{right item}\\
% \hspace*{2em}...\\
% \cs{end}\{Matching\}
% \end{quote}
%
% \subsubsection*{How It Works:}
% \begin{itemize}
%   \item \textbf{Pair Definition:} Each pair is defined using \cs{MatchPair}.
%         The order of definition determines the correct answer key.
%         The right column is fixed and numbered, while the left column
%         is automatically shuffled.
%   \item \textbf{Column Width Control:} The optional \oarg{right\_ratio}
%         adjusts the width of the right column as a decimal fraction
%         between 0 and 1. Default is 0.5 (equal split). This is useful
%         when the right column contains short terms and the left column
%         has lengthy descriptions (e.g., 0.3 for 30\% width).
%   \item \textbf{Randomization:} The left column is shuffled based on
%         the global exam seed (\cs{ExamID}), ensuring consistency
%         across compilations.
%   \item \textbf{Answer Key:} When \cs{TeacherMode} and
%         \cs{ShowCorrection} are enabled, the correct mappings are
%         displayed as numbered-to-lettered pairs.
%   \item \textbf{Capacity:} Supports a maximum of 28 pairs per question
%         (limited by Arabic alphabet).
% \end{itemize}
%
% \subsection{Essay}
% \DescribeEnv{Essay}
% \DescribeMacro{\EssayQuestion}
% The Essay environment creates open-ended, long-form written response
% questions. It provides a writing area with either ruled lines or
% blank space, depending on the selected style. The instructor's
% answer summary is stored and displayed in the answer key in teacher
% mode.

% \subsubsection*{Syntax:}
% \begin{quote}\ttfamily
% \cs{begin}\{Essay\}\oarg{lines}\\
% \hspace*{2em}\cs{EssayQuestion}\oarg{line\_count}\marg{question}\marg{answer summary}\\
% \hspace*{2em}...\\
% \cs{end}\{Essay\}
% \end{quote}

% \subsubsection*{How It Works:}
% \begin{itemize}
%   \item \textbf{Writing Space Style:} The optional environment argument
%         \oarg{lines} controls the appearance of the writing area:
%     \begin{itemize}
%       \item \texttt{true}: Generates ruled notebook lines (default).
%       \item \texttt{false}: Provides blank white space for free-form
%             text or diagrams.
%     \end{itemize}
%   \item \textbf{Writing Space Size (default: 4):} The optional \oarg{line\_count}
%         argument specifies the number of lines allocated for the
%         student's answer.
%   \item \textbf{Question Components:} \cs{EssayQuestion} command
%         takes two mandatory arguments: the question prompt and a
%         concise answer summary for the instructor's reference.
%   \item \textbf{Multiple Questions:} Multiple \cs{EssayQuestion}
%         commands can be placed sequentially within one Essay environment.
%   \item \textbf{Answer Key:} When \cs{TeacherMode} and
%         \cs{ShowCorrection} are enabled, all answer summaries are
%         collected and displayed in a dedicated answer key box.
% \end{itemize}
%
% \subsection{Short Answer}
% \DescribeEnv{ShortAnswer}
% \DescribeMacro{\ShortQuestion}
% The ShortAnswer environment creates questions that require brief,
% direct responses — such as single words, short phrases, or concise
% statements. The answer space can be customized (0, 1, or 2 lines)
% to keep the exam layout clear and space-efficient. The instructor's
% answer is stored and displayed in the answer key in teacher mode.
%
% \subsubsection*{Syntax:}
% \begin{quote}\ttfamily
% \cs{begin}\{ShortAnswer\}\oarg{lines}\\
% \hspace*{2em}\cs{ShortQuestion}\oarg{size}\marg{question}\marg{answer}\\
% \hspace*{2em}...\\
% \cs{end}\{ShortAnswer\}
% \end{quote}
%
% \subsubsection*{How It Works:}
% \begin{itemize}
%   \item \textbf{Writing Space Style:} The optional environment argument
%         \oarg{lines} controls the appearance of the answer space:
%     \begin{itemize}
%       \item \texttt{true}: Generates ruled notebook lines (default).
%       \item \texttt{false}: Provides blank white space without lines.
%     \end{itemize}
%   \item \textbf{Answer Space Size:} The optional \oarg{size} argument
%         specifies the number of lines for the student's answer:
%     \begin{itemize}
%       \item \texttt{0}: Prints a short underline directly after the
%             question text — ideal for single-word answers.
%             (Prints a line regardless of the environment style.)
%       \item \texttt{1}: Generates a one-line writing space below the
%             question.
%       \item \texttt{2}: Generates a two-line writing space below the
%             question.
%     \end{itemize}
%
%   \item \textbf{Question Components:} \cs{ShortQuestion} command
%         takes two mandatory arguments: the question prompt and the
%         model answer or keyword solution.
%
%   \item \textbf{Multiple Questions:} Multiple \cs{ShortQuestion}
%         commands can be placed sequentially within one ShortAnswer
%         environment.
%
%   \item \textbf{Answer Key:} When \cs{TeacherMode} and
%         \cs{ShowCorrection} are enabled, all answers are collected
%         and displayed in a dedicated answer key box.
% \end{itemize}
%
% \subsection{Reading Passage}
% \DescribeEnv{ReadingPassage}
% The ReadingPassage environment provides a container for reading
% comprehension texts. The passage is printed exactly as written —
% preserving all formatting, paragraph breaks, and inline styling —
% without any modification or randomization. The passage is displayed 
% in a standalone box, and authors can place any question type after 
% it to assess comprehension.
%
% \subsubsection*{Syntax:}
% \begin{quote}\ttfamily
% \cs{begin}\{ReadingPassage\}\marg{title}\\
% \hspace*{2em}\textit{passage text}\\
% \cs{end}\{ReadingPassage\}
% \end{quote}
%
% \subsubsection*{How It Works:}
% \begin{itemize}
%   \item \textbf{Passage Rendering:} The text is displayed in a framed
%         box, exactly as entered, preserving all formatting.
%   \item \textbf{Title:} The mandatory \marg{title} argument sets the
%         centered heading above the passage. If left empty \{\},
%         the default title ``Reading Passage'' is used.
%   \item \textbf{Content Flexibility:} The passage can include multiple
%         paragraphs, inline text styles (bold, italic, etc.), and
%         custom lists.
%   \item \textbf{Question Integration:} Any question type can follow
%         a ReadingPassage within the same \texttt{Question} block
%         to assess comprehension.
% \end{itemize}
%
% \section{Complete Example}
%
% A fully functional sample exam file, \texttt{example.tex}, is included with
% the package to demonstrate its capabilities in a realistic academic context.
% The example file covers all question types supported by the package:
% \texttt{MC}, \texttt{TF}, \texttt{Ordering}, \texttt{FillBlank},
% \texttt{Matching}, \texttt{ShortAnswer}, \texttt{Essay}, and
% \texttt{ReadingPassage}.
%
% \medskip
% \textbf{Usage Instructions:}
%
% \begin{enumerate}
%   \item Ensure you have the file \texttt{example.tex} in your working
%         directory (usually found in the package documentation folder).
%
%   \item Open it in your \LaTeX{} editor and compile with \texttt{xelatex}.
%
%   \item To switch between student and teacher views, uncomment or comment
%         the \cs{TeacherMode} and \cs{ShowCorrection} commands in the
%         preamble. This toggles the display of answer keys and correction
%         boxes.
% \end{enumerate}
%
% \textbf{Note:} Arabic examples are provided in the \texttt{exam-rtl-doc.tex}
% file included with the package.
%
% \section{Common Mistakes}
%
% The following list addresses frequent errors encountered during exam
% creation. Adhering to these guidelines ensures correct compilation
% and output.
%
% \begin{itemize}
%   \item \textbf{Enabling \cs{ShowCorrection} without \cs{TeacherMode}:}
%         \cs{ShowCorrection} alone does not display answers. Both
%         \cs{TeacherMode} and \cs{ShowCorrection} must be active for
%         solutions to appear.
%
%   \item \textbf{Omitting the \texttt{Question} Environment:}
%         All question types must be wrapped inside the \texttt{Question}
%         environment. Failing to do so prevents metadata and answer keys
%         from appearing.
%
%   \item \textbf{Using Invalid Type Identifiers:}
%         The first argument of \texttt{Question} must be a valid
%         identifier: \texttt{MC}, \texttt{TF}, \texttt{FillBlank},
%         \texttt{Ordering}, \texttt{Matching}, \texttt{Essay},
%         \texttt{ShortAnswer}, or \texttt{ReadingPassage}. Using
%         non-standard identifiers (e.g., \texttt{MCQ}) will result in
%         missing or incorrect metadata labels.
%
%   \item \textbf{Using the Wrong Engine:}
%         This package requires XeLaTeX. PDFLaTeX and LuaLaTeX are not
%         supported due to the \texttt{bidi} package dependency.
%
%   \item \textbf{Incorrect Column Placement in \texttt{Matching}:}
%         The \texttt{Matching} environment always shuffles the left
%         column. Items intended for randomization must be placed in
%         the first argument.
%
%   \item \textbf{Incorrect Input Sequence in \texttt{Ordering}:}
%         The order in which you write the \cs{OrderOption} commands
%         in your document defines the correct answer. Entering them
%         in the wrong order will result in incorrect grading.
%
%   \item \textbf{Omitting the Title in \texttt{ReadingPassage}:}
%         The \texttt{ReadingPassage} environment requires a title
%         argument. If no custom title is needed, use empty braces
%         \texttt{\{\}}. Omitting the argument causes LaTeX to misinterpret
%         the first character of the passage text as the title.
%
%   \item \textbf{Font not installed:} The default font is IBM Plex Sans Arabic.
%         Ensure it is installed on your system.
% \end{itemize}
%
% \section{Known Limitations}
%
% The \texttt{exam-rtl} package has the following limitations in its
% current version.
%
% \begin{itemize}
%   \item \textbf{Directionality:}
%         The package is optimized for Right-to-Left (RTL) languages
%         (e.g., Arabic). For LTR support, use the companion package
%         \texttt{exam-ltr}.
%
%   \item \textbf{Mandatory Randomization:}
%         Option shuffling cannot be fully disabled. Even without the
%         \cs{ExamID} macro, a default randomization is applied.
%
%   \item \textbf{Scope of Randomization:}
%         Randomization is limited to internal elements: choices in
%         \texttt{MC}, items in \texttt{Ordering}, and the left-hand
%         column in \texttt{Matching}. Shuffling the entire sequence
%         of question blocks is not supported in this version.
%
%   \item \textbf{Item Capacity:}
%         In \texttt{Ordering}, each question is limited to a maximum 
%         of 28 options (items to order). In \texttt{Matching}, each 
%         question is limited to a maximum of 28 pairs. Both limits 
%         are due to the 28 Arabic letters used for labeling.
%
%   \item \textbf{Short Answer Lines:}
%         Configuring more than 2 lines in the \texttt{ShortAnswer}
%         environment caps the display at 2.
%
%   \item \textbf{Answer Key Placement:}
%         Answer keys are displayed individually beneath each question.
%         A centralized answer sheet at the end of the document is not
%         supported in this version.
% \end{itemize}
%
% \section{License}
%
% This package is distributed under the LaTeX Project Public License (LPPL),
% version 1.3c or later.
%
% The latest version of this license is available at:
% \url{http://www.latex-project.org/lppl.txt}
%
% \section{Source Code}
%
% The complete source code of the \textsf{exam-rtl} package is included in this
% \texttt{.dtx} file. To view the code:
%
% \begin{itemize}
%   \item Open \texttt{exam-rtl.dtx} in any text editor.
%   \item The code is located after the line: \verb|%    \begin{macrocode}|.
%   \item To extract the package only: \texttt{latex exam-rtl.ins}.
%   \item The extracted \texttt{exam-rtl.sty} will preserve all Arabic text correctly.
%   \item This documentation does not include the source code to avoid
%         compilation issues with Arabic text.
% \end{itemize}
%
% \StopEventually{^^A
%   \PrintChanges
%   % \PrintIndex
% }
%
% \section{Implementation}

% \iffalse
%<*package>
% \fi

%    \begin{macrocode}
% ==================================================
% exam-rtl.sty – Arabic/RTL Exam Package
% Version: 1.0
% Date: 2026/08/20
% ==================================================

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{exam-rtl}[2026/08/20 v1.0 Arabic/RTL Exam Package]

% --------------------------------------------------
% 1. Required Packages
% --------------------------------------------------
\RequirePackage{xcolor}
\RequirePackage{tcolorbox}
\tcbuselibrary{all}
\RequirePackage{fontspec}
\RequirePackage{polyglossia}
\RequirePackage{bidi}
\RequirePackage{expl3}
\RequirePackage{xparse}

% --------------------------------------------------
% 2. Arabic Font Setup
% --------------------------------------------------
\setmainlanguage{arabic}
\setotherlanguages{english}
\newfontfamily\arabicfont[Script=Arabic, BoldFont={* Medium}]{IBM Plex Sans Arabic}
\newfontfamily\arabicfontsf[Script=Arabic, BoldFont={* Medium}]{IBM Plex Sans Arabic}
\newfontfamily\arabicfonttt[Script=Arabic]{Cascadia Code-SemiLight}

% --------------------------------------------------
% 3. Basic Macros
% --------------------------------------------------
\newcommand{\ArNum}[1]{\textarabic{\arabicdigits{\number#1}}}
\newcommand{\arbstrut}{\vrule height 1.15em depth 0.51em width 0pt}

% --------------------------------------------------
% 4. Expl3 Setup
% --------------------------------------------------
\ExplSyntaxOn

\cs_generate_variant:Nn \tl_if_eq:nnT { VVT }
\cs_generate_variant:Nn \prop_item:Nn { Nx }
\cs_generate_variant:Nn \msg_warning:nnn { nnx }

% --------------------------------------------------
% 5. Core Booleans
% --------------------------------------------------
\bool_new:N \g__mode_teacher_bool
\bool_new:N \g__mode_marks_bool
\bool_new:N \g__mode_difficulty_bool
\bool_new:N \g__mode_type_bool
\bool_new:N \g__mode_correction_bool

% --------------------------------------------------
% 6. Core Integers
% --------------------------------------------------
\int_new:N \g__exam_id_int
\int_new:N \g__question_number_int
\int_new:N \g__question_seed_int

% --------------------------------------------------
% 7. Core Token Lists
% --------------------------------------------------
\tl_new:N  \g__question_answer_tl
\tl_new:N  \g__question_type_tl
\tl_new:N  \g__question_level_tl
\tl_new:N  \g__question_marks_tl

% --------------------------------------------------
% 8. Type Properties
% --------------------------------------------------
\prop_new:N \g__question_type_prop
\prop_put:Nnn \g__question_type_prop {MC} {اختيار~من~متعدد}
\prop_put:Nnn \g__question_type_prop {TF} {صح~خطأ}
\prop_put:Nnn \g__question_type_prop {FillBlank} {ملء~فراغ}
\prop_put:Nnn \g__question_type_prop {Ordering} {ترتيب}
\prop_put:Nnn \g__question_type_prop {Matching} {توصيل}
\prop_put:Nnn \g__question_type_prop {Essay} {مقالي}
\prop_put:Nnn \g__question_type_prop {ShortAnswer} {جواب~قصير}
\prop_put:Nnn \g__question_type_prop {ReadingPassage} {قطعة~قراءة}

% --------------------------------------------------
% 9. Letters Sequence (Arabic)
% --------------------------------------------------
\seq_new:N \g_exam_letters_seq
\seq_set_from_clist:Nn \g_exam_letters_seq
{
  أ , ب , ج , د , هـ , و , ز , ح , ط , ي ,
  ك , ل , م , ن , س , ع , ف , ص , ق , ر ,
  ش , ت , ث , خ , ذ , ض , ظ , غ
}

% --------------------------------------------------
% 10. Mode Control Commands
% --------------------------------------------------
\NewDocumentCommand{\StudentMode}{}
  { \bool_gset_false:N \g__mode_teacher_bool }

\NewDocumentCommand{\TeacherMode}{}
  { \bool_gset_true:N \g__mode_teacher_bool }

\NewDocumentCommand{\ShowMarks}{}
  { \bool_gset_true:N \g__mode_marks_bool }

\NewDocumentCommand{\ShowDifficulty}{}
  { \bool_gset_true:N \g__mode_difficulty_bool }

\NewDocumentCommand{\ShowType}{}
  { \bool_gset_true:N \g__mode_type_bool }

\NewDocumentCommand{\ShowCorrection}{}
  { \bool_gset_true:N \g__mode_correction_bool }

\NewDocumentCommand{\ExamID}{ m }
  {
    \tl_if_blank:nTF {#1}
      {
        \int_gset:Nn \g__exam_id_int {0}
        \sys_gset_rand_seed:n {0}
      }
      {
        \int_gset:Nn \g__exam_id_int {#1}
        \sys_gset_rand_seed:n {#1}
      }
  }

% --------------------------------------------------
% 11. Seed Builder
% --------------------------------------------------
\cs_new_protected:Npn \__question_build_seed:
  {
    \int_gset:Nn \g__question_seed_int
      { \int_eval:n { \g__exam_id_int * 1000 + \g__question_number_int } }
    \sys_gset_rand_seed:n { \g__question_seed_int }
  }

\cs_new_protected:Npn \__subquestion_build_seed:n #1
  {
    \sys_gset_rand_seed:n
      {
        \g__exam_id_int * 10000 +
        \g__question_number_int * 100 +
        #1
      }
  }

% --------------------------------------------------
% 12. Answer Box
% --------------------------------------------------
\cs_new_protected:Npn \__exam_print_answer_box:
{
    \par\smallskip
    \begin{tcolorbox}[
	enhanced,
	breakable,
	colback=white,
	colframe=black,
	arc=0pt,
	outer~arc=0pt,
	boxrule=1pt,
	top=10pt,
	bottom=10pt,
	left=10pt,
	right=10pt,
	parbox=true,
	fontupper=\linespread{1.3}\selectfont,
	before~upper={\begin{flushright}},
	after~upper={\end{flushright}},
	coltitle=black,
	fonttitle=\bfseries,
	title={نموذج~الإجابة},
	attach~boxed~title~to~top~right={
	xshift=-5mm,
	yshift=-3mm,
	yshifttext=-1mm
	},
	boxed~title~style={
	colback=white,
	colframe=white,
	left=5pt, right=5pt
	}
	]{
	\setlength{\baselineskip}{1.2\normalbaselineskip}
	\tl_use:N \g__question_answer_tl
	}
	\end{tcolorbox}
	\par\smallskip
}

% --------------------------------------------------
% 13. Question Environment
% --------------------------------------------------
\dim_new:N \g__question_number_width_dim
\dim_new:N \g__question_metadata_width_dim
\dim_new:N \g__question_text_width_dim

\NewDocumentEnvironment{Question}{ m m m m }
  {
    \int_gincr:N \g__question_number_int

    \tl_gset:Nn \g__question_type_tl   {#1}
    \tl_gset:Nn \g__question_level_tl  {#2}
    \tl_gset:Nn \g__question_marks_tl  {#3}

    \tl_gclear:N \g__question_answer_tl

    \__question_build_seed:

    \tl_clear:N \l_tmpa_tl
    \bool_if:nT { \g__mode_type_bool }
      {
        \tl_put_right:Nn \l_tmpa_tl
          { [\prop_item:Nn \g__question_type_prop {#1}] }
      }
    \bool_if:nT { \g__mode_difficulty_bool }
      { \tl_put_right:Nn \l_tmpa_tl { ~[#2] } }
    \bool_if:nT { \g__mode_marks_bool }
      { \tl_put_right:Nn \l_tmpa_tl { ~[#3~درجات] } }

    \settowidth{\g__question_metadata_width_dim}
      { \footnotesize \l_tmpa_tl }

    \settowidth{\g__question_number_width_dim}
      { \bfseries سؤال~\ArNum{\g__question_number_int}:~ }

    \dim_set:Nn \g__question_text_width_dim
      {
        \linewidth
        - \g__question_number_width_dim
        - \g__question_metadata_width_dim
        - 1em
      }

    \dim_compare:nNnT { \g__question_text_width_dim } < { 0pt }
      { \dim_set:Nn \g__question_text_width_dim { 0pt } }

    \par\medskip
    \noindent
    \makebox[\linewidth][r]
      {
        \makebox[\g__question_number_width_dim][r]
          { \bfseries سؤال~\ArNum{\g__question_number_int}:~ }

        \parbox[t]{\g__question_text_width_dim}
          {
            \setlength{\baselineskip}{1.3\normalbaselineskip}
            \bfseries #4
            \par
            \vspace{0.01em}
          }

        \hfill
        { \footnotesize
          \bool_if:nT { \g__mode_type_bool }
            { [\prop_item:Nn \g__question_type_prop {#1}] }
          \bool_if:nT { \g__mode_difficulty_bool }
            { ~[#2] }
          \bool_if:nT { \g__mode_marks_bool }
            { ~[#3~درجات] }
        }
      }
    \par\smallskip
  }
  {
    \bool_if:nT { \g__mode_teacher_bool && \g__mode_correction_bool }
      {
        \tl_if_empty:NF \g__question_answer_tl
          { \__exam_print_answer_box: }
      }
    \par\medskip
  }

% --------------------------------------------------
% 14. Multiple Choice (MC)
% --------------------------------------------------
\int_new:N \l__mc_question_counter_int
\int_new:N \l__mc_option_counter_int
\int_new:N \l__mc_columns_int
\int_new:N \l__mc_correct_index_int
\seq_new:N \l__mc_options_seq
\tl_new:N \l__mc_question_text_tl

\dim_new:N \l__mc_label_width_dim
\dim_new:N \l__mc_label_sep_dim
\dim_new:N \l__mc_col_sep_dim
\dim_new:N \l__mc_text_width_dim
\dim_set:Nn \l__mc_label_width_dim { 1.5em }
\dim_set:Nn \l__mc_label_sep_dim { 0.8em }
\dim_set:Nn \l__mc_col_sep_dim { 1.5em }

\dim_new:N \l__mc_before_first_question_dim
\dim_new:N \l__mc_after_question_text_dim
\dim_new:N \l__mc_between_questions_dim
\dim_new:N \l__mc_after_options_dim
\dim_new:N \l__mc_between_option_lines_dim

\dim_set:Nn \l__mc_before_first_question_dim { 0.5em }
\dim_set:Nn \l__mc_after_question_text_dim { 0.3em }
\dim_set:Nn \l__mc_between_questions_dim { 0.1em }
\dim_set:Nn \l__mc_after_options_dim { 0.3em }
\dim_set:Nn \l__mc_between_option_lines_dim { 0.3em }

\NewDocumentEnvironment{MC}{ O{4} }
  {
    \int_set:Nn \l__mc_columns_int {#1}
    \int_zero:N \l__mc_question_counter_int
    \int_zero:N \l__mc_option_counter_int
    \par
  }
  {
    \int_compare:nNnT { \l__mc_option_counter_int } > { 0 }
      { \__mc_display_options: }
    \par
  }

\NewDocumentCommand{\MCQuestion}{ m m }
  {
    \int_compare:nNnT { \l__mc_option_counter_int } > { 0 }
      {
        \__mc_display_options:
        \par\vspace{\l__mc_after_options_dim}
      }

    \int_incr:N \l__mc_question_counter_int

    \int_compare:nNnTF { \l__mc_question_counter_int } = { 1 }
      { \par\vspace{\l__mc_before_first_question_dim} }
      { \par\vspace{\l__mc_between_questions_dim} }

    \par\noindent
    \makebox[2.65mm][c]{\bfseries\ArNum{\l__mc_question_counter_int}}%
    \makebox[2.65mm][r]{\bfseries.}%
    \hspace{0.7mm}%
    \parbox[t]{\dim_eval:n{\linewidth-6.0mm}}{
      \setlength{\baselineskip}{1.3\normalbaselineskip}
      \bfseries#1}

    \par\vspace{\l__mc_after_question_text_dim}

    \int_set:Nn \l__mc_correct_index_int {#2}
    \int_zero:N \l__mc_option_counter_int
    \seq_clear:N \l__mc_options_seq
  }

\NewDocumentCommand{\MCOption}{ m }
  {
    \int_incr:N \l__mc_option_counter_int
    \seq_put_right:Nn \l__mc_options_seq {#1}
  }

\cs_new_protected:Npn \__mc_display_options:
  {
    \int_compare:nNnT { \l__mc_option_counter_int } = { 0 }
      {
        \msg_warning:nn { mc } { no-options }
        \par
        \scan_stop:
      }

    \tl_set:Nx \l_tmpa_tl
      { \seq_item:Nn \l__mc_options_seq { \l__mc_correct_index_int } }

    \seq_shuffle:N \l__mc_options_seq

    \int_set:Nn \l_tmpa_int
      { \int_mod:nn { \l__mc_option_counter_int } { \l__mc_columns_int } }

    \int_compare:nNnT { \l_tmpa_int } > { 0 }
      {
        \int_set:Nn \l_tmpb_int { \l__mc_columns_int - \l_tmpa_int }
        \prg_replicate:nn { \l_tmpb_int }
          { \seq_put_right:Nn \l__mc_options_seq { \hspace{0pt} } }
      }

    \dim_set:Nn \l_tmpb_dim
      { \int_eval:n { \l__mc_columns_int - 1 } \l__mc_col_sep_dim }
    \dim_set:Nn \l_tmpa_dim
      { ( \linewidth - \l_tmpb_dim ) / \l__mc_columns_int }

    \dim_set:Nn \l__mc_text_width_dim
      { \dim_eval:n
        { \l_tmpa_dim - \l__mc_label_width_dim - \l__mc_label_sep_dim }
      }

    \dim_compare:nNnT { \l__mc_text_width_dim } < { 0pt }
      { \dim_set:Nn \l__mc_text_width_dim { 0pt } }

    \noindent
    \int_step_inline:nn { \seq_count:N \l__mc_options_seq }
      {
        \tl_set:Nx \l_tmpb_tl { \seq_item:Nn \l__mc_options_seq { ##1 } }

        \makebox[\l_tmpa_dim][r]
          {
            \makebox[\l__mc_label_width_dim][l]
              {
                \int_compare:nNnTF { ##1 } > { \l__mc_option_counter_int }
                  { \hspace{0pt} }
                  { \seq_item:Nn \g_exam_letters_seq {##1}) }
              }%
            \hspace{\l__mc_label_sep_dim}%
            \parbox[t]{\l__mc_text_width_dim}
              {
                \setlength{\baselineskip}{1.3\normalbaselineskip}
                \raggedleft
                \arbstrut
                \l_tmpb_tl
                \par
              }
          }

        \int_compare:nNnT { ##1 } < { \l__mc_option_counter_int + 1 }
          {
            \tl_if_eq:VVT \l_tmpb_tl \l_tmpa_tl
              {
                \tl_gput_right:Nx \g__question_answer_tl
                  {
                    \exp_not:N \makebox[4em][r]
                      {
                        (\ArNum{\l__mc_question_counter_int})
                        ~{$\;\Leftarrow\;$}~
                        (\seq_item:Nn \g_exam_letters_seq {##1})
                      }%
                    \qquad
                  }
              }
          }

        \int_compare:nNnF
          { \int_mod:nn {##1} { \l__mc_columns_int } } = { 0 }
          { \hspace{\l__mc_col_sep_dim} }

        \int_compare:nNnT
          { \int_mod:nn {##1} { \l__mc_columns_int } } = { 0 }
          {
            \par\prevdepth=\dp\strutbox%
            \vspace{\l__mc_between_option_lines_dim}
          }
      }
    \par
  }

\msg_new:nnn { mc } { no-options }
  {
    تحذير:~لا~توجد~خيارات~للسؤال~\int_use:N \l__mc_question_counter_int.
  }

% --------------------------------------------------
% 15. True/False (TF)
% --------------------------------------------------
\int_new:N \l__tf_question_counter_int
\tl_new:N \l__tf_question_text_tl
\tl_new:N \l__tf_correct_answer_tl
\bool_new:N \l__tf_style_bool

\dim_const:Nn \l__tf_number_width_dim { 5.3mm }
\dim_const:Nn \l__tf_bracket_width_dim { 3em }
\dim_const:Nn \l__tf_option_width_dim { 8em }

\dim_new:N \l__tf_before_first_question_dim
\dim_new:N \l__tf_between_questions_dim
\dim_set:Nn \l__tf_before_first_question_dim { 0.5em }
\dim_set:Nn \l__tf_between_questions_dim { 0.3\baselineskip }

\NewDocumentEnvironment{TF}{ O{bracket} }
  {
    \int_zero:N \l__tf_question_counter_int

    \str_if_eq:nnTF {#1} {bracket}
      { \bool_set_true:N \l__tf_style_bool }
      { \bool_set_false:N \l__tf_style_bool }
  }
  {}

\NewDocumentCommand{\TFQuestion}{ m m }
  {
    \int_incr:N \l__tf_question_counter_int

    \int_compare:nNnTF { \l__tf_question_counter_int } = { 1 }
      { \par\vspace{\l__tf_before_first_question_dim} }
      { \par\vspace{\l__tf_between_questions_dim} }

    \par\noindent
    \makebox[2.65mm][c]{\ArNum{\l__tf_question_counter_int}}%
    \makebox[2.65mm][r]{.}%

    \bool_if:NTF \l__tf_style_bool
      {
        \parbox[t]{\dim_eval:n{\linewidth-10.0mm}}
          {
            \setlength{\baselineskip}{1.3\normalbaselineskip}
            \arbstrut#1\unskip\nobreak\hspace{1em}%
            \makebox[3em][c]{(\hspace{2em})}
            \par
          }
      }
      {
        \parbox[t]{\dim_eval:n{\linewidth-10.0mm-\l__tf_option_width_dim}}
          {
            \setlength{\baselineskip}{1.3\normalbaselineskip}
            \arbstrut#1
            \par
          }%
        \hfill
        \makebox[\l__tf_option_width_dim][c]
          {
            \makebox[3em][c]{صح}%
            \hspace{1em}%
            \makebox[3em][c]{خطأ}
          }
      }
    \par\prevdepth=\dp\strutbox%

    \tl_gput_right:Nx \g__question_answer_tl
      {
        \exp_not:N \makebox[4em][r]
          {
            (\ArNum{\l__tf_question_counter_int})
            ~{$\;\Leftarrow\;$}~
            #2
          }%
        \qquad
      }
  }

% --------------------------------------------------
% 16. Ordering
% --------------------------------------------------
\int_new:N \l__ord_question_counter_int
\int_new:N \l__ord_option_counter_int
\int_new:N \l__ord_columns_int
\seq_new:N \l__ord_options_seq
\seq_new:N \l__ord_original_order_seq
\tl_new:N  \l__ord_answer_tl

\bool_new:N \l__ord_answer_pending_bool

\dim_new:N \l__ord_answer_width_dim
\dim_set:Nn \l__ord_answer_width_dim { 5mm }

\dim_new:N \l__ord_label_width_dim
\dim_new:N \l__ord_label_sep_dim
\dim_new:N \l__ord_col_sep_dim
\dim_new:N \l__ord_text_width_dim
\dim_set:Nn \l__ord_label_width_dim { 1.5em }
\dim_set:Nn \l__ord_label_sep_dim { 0.8em }
\dim_set:Nn \l__ord_col_sep_dim { 1.5em }

\dim_new:N \l__ord_before_first_question_dim
\dim_new:N \l__ord_after_question_text_dim
\dim_new:N \l__ord_between_questions_dim
\dim_new:N \l__ord_after_options_dim
\dim_new:N \l__ord_between_option_lines_dim

\dim_set:Nn \l__ord_before_first_question_dim { 0.5em }
\dim_set:Nn \l__ord_after_question_text_dim { 0.3em }
\dim_set:Nn \l__ord_between_questions_dim { 0.1em }
\dim_set:Nn \l__ord_after_options_dim { 0.3em }
\dim_set:Nn \l__ord_between_option_lines_dim { 0.3em }

\NewDocumentEnvironment{Ordering}{ O{4} }
  {
    \int_set:Nn \l__ord_columns_int {#1}
    \int_zero:N \l__ord_question_counter_int
    \int_zero:N \l__ord_option_counter_int
    \tl_clear:N \l__ord_answer_tl
    \seq_clear:N \l__ord_options_seq
    \seq_clear:N \l__ord_original_order_seq
    \bool_set_false:N \l__ord_answer_pending_bool
    \par
  }
  {
    \int_compare:nNnT { \l__ord_option_counter_int } > { 0 }
      { \__ord_display_options: }
    \par
  }

\NewDocumentCommand{\OrderQuestion}{ m }
  {
    \int_compare:nNnT { \l__ord_option_counter_int } > { 0 }
      {
        \__ord_display_options:
        \par\vspace{\l__ord_after_options_dim}
      }

    \int_incr:N \l__ord_question_counter_int

    \int_compare:nNnTF { \l__ord_question_counter_int } = { 1 }
      { \par\vspace{\l__ord_before_first_question_dim} }
      { \par\vspace{\l__ord_between_questions_dim} }

    \par\noindent
    \makebox[2.65mm][c]{\bfseries\ArNum{\l__ord_question_counter_int}}%
    \makebox[2.65mm][r]{\bfseries.}%
    \hspace{0.7mm}%
    \parbox[t]{\dim_eval:n{\linewidth-6.0mm}}{
      \setlength{\baselineskip}{1.3\normalbaselineskip}
      \bfseries#1}

    \par\vspace{\l__ord_after_question_text_dim}

    \int_zero:N \l__ord_option_counter_int
    \seq_clear:N \l__ord_options_seq
    \seq_clear:N \l__ord_original_order_seq
    \bool_set_false:N \l__ord_answer_pending_bool
  }

\NewDocumentCommand{\OrderOption}{ m }
  {
    \int_incr:N \l__ord_option_counter_int
    \seq_put_right:Nn \l__ord_options_seq {#1}
    \seq_put_right:Nn \l__ord_original_order_seq {#1}
  }

\NewDocumentCommand{\OrderAnswer}{ O{5mm} }
  {
    \bool_set_true:N \l__ord_answer_pending_bool
    \dim_set:Nn \l__ord_answer_width_dim {#1}
  }

\cs_new_protected:Npn \__ord_print_answer:
  {
    \par\noindent
    الترتيب:\quad

    \int_step_inline:nn { \l__ord_option_counter_int }
      {
        \underline{\hspace{\l__ord_answer_width_dim}}\,
        \int_compare:nNnT { ##1 } < { \l__ord_option_counter_int } { ,\ }
      }
    \par\vspace{0.5\baselineskip}
  }

\cs_new_protected:Npn \__ord_display_options:
  {
    \int_compare:nNnT { \l__ord_option_counter_int } = { 0 }
      {
        \msg_warning:nn { ord } { no-options }
        \par
        \scan_stop:
      }

    \seq_shuffle:N \l__ord_options_seq

    \int_set:Nn \l_tmpa_int
      { \int_mod:nn { \l__ord_option_counter_int } { \l__ord_columns_int } }

    \int_compare:nNnT { \l_tmpa_int } > { 0 }
      {
        \int_set:Nn \l_tmpb_int { \l__ord_columns_int - \l_tmpa_int }
        \prg_replicate:nn { \l_tmpb_int }
          { \seq_put_right:Nn \l__ord_options_seq { \hspace{0pt} } }
      }

    \dim_set:Nn \l_tmpb_dim
      { \int_eval:n { \l__ord_columns_int - 1 } \l__ord_col_sep_dim }
    \dim_set:Nn \l_tmpa_dim
      { ( \linewidth - \l_tmpb_dim ) / \l__ord_columns_int }

    \dim_set:Nn \l__ord_text_width_dim
      { \dim_eval:n
        { \l_tmpa_dim - \l__ord_label_width_dim - \l__ord_label_sep_dim }
      }

    \dim_compare:nNnT { \l__ord_text_width_dim } < { 0pt }
      { \dim_set:Nn \l__ord_text_width_dim { 0pt } }

    \noindent
    \int_step_inline:nn { \seq_count:N \l__ord_options_seq }
      {
        \tl_set:Nx \l_tmpb_tl { \seq_item:Nn \l__ord_options_seq { ##1 } }

        \makebox[\l_tmpa_dim][r]
          {
            \makebox[\l__ord_label_width_dim][l]
              {
                \int_compare:nNnTF { ##1 } > { \l__ord_option_counter_int }
                  { \hspace{0pt} }
                  { \seq_item:Nn \g_exam_letters_seq {##1}) }
              }%
            \hspace{\l__ord_label_sep_dim}%
            \parbox[t]{\l__ord_text_width_dim}
              {
                \setlength{\baselineskip}{1.3\normalbaselineskip}
                \raggedleft
                \arbstrut
                \l_tmpb_tl
                \par
              }
          }

        \int_compare:nNnF
          { \int_mod:nn {##1} { \l__ord_columns_int } } = { 0 }
          { \hspace{\l__ord_col_sep_dim} }

        \int_compare:nNnT
          { \int_mod:nn {##1} { \l__ord_columns_int } } = { 0 }
          {
            \par\prevdepth=\dp\strutbox%
            \vspace{\l__ord_between_option_lines_dim}
          }
      }
    \par

    \__ord_build_correct_order:

    \bool_if:NT \l__ord_answer_pending_bool
      {
        \__ord_print_answer:
        \bool_set_false:N \l__ord_answer_pending_bool
      }
  }

\cs_new_protected:Npn \__ord_build_correct_order:
  {
    \tl_clear:N \l_tmpa_tl

    \int_step_inline:nn { \l__ord_option_counter_int }
      {
        \int_zero:N \l_tmpb_int
        \tl_set:Nx \l_tmpb_tl
          { \seq_item:Nn \l__ord_original_order_seq {##1} }

        \int_step_inline:nn { \l__ord_option_counter_int }
          {
            \tl_set:Nx \l_tmpc_tl
              { \seq_item:Nn \l__ord_options_seq {####1} }
            \tl_if_eq:NNT \l_tmpb_tl \l_tmpc_tl
              { \int_set:Nn \l_tmpb_int {####1} }
          }

        \tl_put_right:Nx \l_tmpa_tl
          { \seq_item:Nn \g_exam_letters_seq { \int_use:N \l_tmpb_int } }

        \int_compare:nNnF {##1} = { \l__ord_option_counter_int }
          { \tl_put_right:Nn \l_tmpa_tl { ~،~ } }
      }

    \tl_put_right:Nx \l__ord_answer_tl
      {
        \exp_not:N \makebox[4em][r]
          {
            (\ArNum{\l__ord_question_counter_int})
            ~{$\;\Leftarrow\;$}~
            \l_tmpa_tl
          }%
        \par
      }
    \tl_gset_eq:NN \g__question_answer_tl \l__ord_answer_tl
  }

\msg_new:nnn { ord } { no-options }
  {
    تحذير:~لا~توجد~خيارات~للسؤال~\int_use:N \l__ord_question_counter_int.
  }

% --------------------------------------------------
% 17. FillBlank
% --------------------------------------------------
\int_new:N \l__fb_question_counter_int
\tl_new:N \l__fb_answer_tl
\bool_new:N \l__fb_wordbank_bool

\dim_const:Nn \l__fb_number_width_dim { 5.3mm }

\dim_new:N \l__fb_before_first_question_dim
\dim_new:N \l__fb_between_questions_dim
\dim_set:Nn \l__fb_before_first_question_dim { 0.2em }
\dim_set:Nn \l__fb_between_questions_dim { 0.5em }

\NewDocumentEnvironment{FillBlank}{ O{false} }
  {
    \int_zero:N \l__fb_question_counter_int
    \tl_clear:N \l__fb_answer_tl
    \str_if_eq:nnTF {#1} {true}
      { \bool_set_true:N \l__fb_wordbank_bool }
      { \bool_set_false:N \l__fb_wordbank_bool }
  }
  {
    \smallskip
    \tl_gset_eq:NN \g__question_answer_tl \l__fb_answer_tl
  }

\NewDocumentCommand{\WordBank}{ O{\quad} m }
  {
    \bool_if:NT \l__fb_wordbank_bool
      {
        \par\vspace{0.5em}\noindent

        \tl_clear:N \l_tmpa_tl
        \clist_set:Nn \l_tmpa_clist {#2}

        \hbox_set:Nn \l_tmpa_box { \clist_use:Nn \l_tmpa_clist {#1} }
        \dim_set:Nn \l_tmpa_dim { \box_wd:N \l_tmpa_box }

        \dim_set:Nn \l_tmpb_dim { 0.9\linewidth }

        \dim_compare:nNnTF { \l_tmpa_dim } > { \l_tmpb_dim }
          { \dim_set:Nn \l_tmpa_dim { \l_tmpb_dim } }
          { }

        \dim_add:Nn \l_tmpa_dim { 10pt }

        \makebox[\linewidth][c]
          {
            \fbox
              {%
                \begin{minipage}{\l_tmpa_dim}
                  \centering
                  \vspace{4pt}
                  \setlength{\baselineskip}{1.3\normalbaselineskip}
                  \clist_use:Nn \l_tmpa_clist {#1}
                  \vspace{3pt}
                \end{minipage}%
              }
          }%
        \par\vspace{0.5em}
      }
  }

\NewDocumentCommand{\Blank}{ O{15mm} }
  { \underline{\hspace{#1}} }

\NewDocumentCommand{\FullBlank}{}
  { \leavevmode\unskip\enspace\hrulefill\enspace }

\NewDocumentCommand{\FillQuestion}{ m m }
  {
    \int_incr:N \l__fb_question_counter_int

    \int_compare:nNnTF { \l__fb_question_counter_int } = { 1 }
      { \par\vspace{\l__fb_before_first_question_dim} }
      { \par\vspace{\l__fb_between_questions_dim} }

    \par\noindent

    \makebox[2.65mm][c]{\ArNum{\l__fb_question_counter_int}}%
    \makebox[2.65mm][r]{.}%

    \parbox[t]{\dim_eval:n{\linewidth-6.0mm}}
      {
        \setlength{\baselineskip}{1.3\normalbaselineskip}
        \arbstrut#1
        \par
      }
    \par\prevdepth=\dp\strutbox%

    \tl_put_right:Nx \l__fb_answer_tl
      {
        \exp_not:N (\ArNum{\l__fb_question_counter_int})
        ~{$\;\Leftarrow\;$}~
        #2%
        \par
      }
  }

% --------------------------------------------------
% 18. Matching
% --------------------------------------------------
\seq_new:N \l__match_left_seq      % التعريفات (سيظهر في اليسار)
\seq_new:N \l__match_right_seq     % المصطلحات (سيظهر في اليمين)
\seq_new:N \l__match_index_seq
\int_new:N \l__match_count_int
\tl_new:N  \l__match_answer_tl

\dim_new:N \l__match_label_width_dim
\dim_new:N \l__match_label_sep_dim
\dim_new:N \l__match_col_sep_dim
\dim_new:N \l__match_left_text_width_dim
\dim_new:N \l__match_right_text_width_dim
\dim_new:N \l__match_left_width_dim
\dim_new:N \l__match_right_width_dim

\dim_new:N \l__match_before_first_dim
\dim_new:N \l__match_between_pairs_dim

\dim_set:Nn \l__match_label_width_dim { 1.75em }
\dim_set:Nn \l__match_label_sep_dim { 0.5em }
\dim_set:Nn \l__match_col_sep_dim { 2em }
\dim_set:Nn \l__match_before_first_dim { 0.5em }
\dim_set:Nn \l__match_between_pairs_dim { 0.2em }

\msg_new:nnn { matching } { empty-pair }
  {
    خطأ~في~نمط~التوصيل:~لا~يوجد~أزواج!~
    أضف~أزواجاً~باستخدام~\token_to_str:N \MatchPair.
  }

\msg_new:nnn { matching } { odd-number }
  {
    تحذير:~عدد~العناصر~في~العمودين~غير~متساوٍ.~
    العمود~الأيمن:~#1،~العمود~الأيسر:~#2.
  }

\NewDocumentEnvironment{Matching}{ O{0.5} }
  {
    \seq_clear:N \l__match_left_seq
    \seq_clear:N \l__match_right_seq
    \seq_clear:N \l__match_index_seq
    \tl_clear:N  \l__match_answer_tl

    \dim_set:Nn \l__match_right_width_dim
      { #1\linewidth - \l__match_label_width_dim - \l__match_label_sep_dim }
    \dim_set:Nn \l__match_left_width_dim
      { \linewidth - \l__match_right_width_dim - \l__match_col_sep_dim }

    \dim_set:Nn \l__match_right_text_width_dim
      { \l__match_right_width_dim
        - \l__match_label_width_dim
        - \l__match_label_sep_dim }
    \dim_set:Nn \l__match_left_text_width_dim
      { \l__match_left_width_dim
        - \l__match_label_width_dim
        - \l__match_label_sep_dim }
  }
  {
    \int_compare:nNnT { \seq_count:N \l__match_left_seq } = { 0 }
      { \msg_error:nn { matching } { empty-pair } }

    \int_compare:nNnF { \seq_count:N \l__match_left_seq } =
      { \seq_count:N \l__match_right_seq }
      {
        \msg_warning:nnx { matching } { odd-number }
          { \int_use:N \seq_count:N \l__match_left_seq }
          { \int_use:N \seq_count:N \l__match_right_seq }
      }

    \int_set:Nn \l__match_count_int
      { \seq_count:N \l__match_right_seq }

    \int_step_inline:nn { \l__match_count_int }
      { \seq_put_right:Nn \l__match_index_seq {##1} }

    \seq_shuffle:N \l__match_index_seq

    \par\vspace{\l__match_before_first_dim}
    \noindent
    \begin{minipage}[t]{\l__match_right_width_dim}
      \raggedleft
      \int_step_inline:nn { \l__match_count_int }
        {
          \makebox[\l__match_label_width_dim][l]
            { \ArNum{##1}) }%
          \hspace{\l__match_label_sep_dim}%
          \parbox[t]{\l__match_right_text_width_dim}
            {
              \setlength{\baselineskip}{1.3\normalbaselineskip}
              \raggedleft
              \arbstrut
              \seq_item:Nn \l__match_right_seq {##1}
              \par
              \vspace{0.1em}
            }
          \par\prevdepth=\dp\strutbox%
          \vspace{\l__match_between_pairs_dim}
        }
    \end{minipage}
    \hspace{\l__match_col_sep_dim}
    \begin{minipage}[t]{\l__match_left_width_dim}
      \raggedleft
      \int_step_inline:nn { \l__match_count_int }
        {
          \makebox[\l__match_label_width_dim][l]
            { \seq_item:Nn \g_exam_letters_seq {##1}) }%
          \hspace{\l__match_label_sep_dim}%
          \parbox[t]{\l__match_left_text_width_dim}
            {
              \setlength{\baselineskip}{1.3\normalbaselineskip}
              \raggedleft
              \arbstrut
              \seq_item:Nn \l__match_left_seq
                { \seq_item:Nn \l__match_index_seq {##1} }
              \par
              \vspace{0.1em}
            }
          \par\prevdepth=\dp\strutbox%
          \vspace{\l__match_between_pairs_dim}
        }
    \end{minipage}
    \par\vspace{0.1em}

    \tl_clear:N \l__match_answer_tl

    \int_step_inline:nn { \l__match_count_int }
      {
        \int_zero:N \l_tmpa_int

        \int_step_inline:nn { \l__match_count_int }
          {
            \int_compare:nNnT
              { \seq_item:Nn \l__match_index_seq {####1} } = { ##1 }
              { \int_set:Nn \l_tmpa_int {####1} }
          }

        \tl_put_right:Nx \l__match_answer_tl
          {
            \exp_not:N \makebox[5.25em][r]
              {
                (\ArNum{##1})
                ~{$\;\Leftarrow\;$}~
                (\seq_item:Nn \g_exam_letters_seq
                  { \int_use:N \l_tmpa_int })
              }%
            \qquad
          }
      }

    \tl_gset_eq:NN \g__question_answer_tl \l__match_answer_tl
  }

\NewDocumentCommand{\MatchPair}{mm}
  {
    \seq_put_right:Nn \l__match_left_seq  {#1}   % التعريفات
    \seq_put_right:Nn \l__match_right_seq {#2}   % المصطلحات
  }

% --------------------------------------------------
% 19. Essay
% --------------------------------------------------
\int_new:N \l__essay_question_counter_int
\tl_new:N \l__essay_answer_tl
\bool_new:N \l__essay_lines_bool

\dim_const:Nn \l__essay_number_width_dim { 5.3mm }
\dim_new:N \l__essay_line_skip_dim
\dim_set:Nn \l__essay_line_skip_dim { 0.4\baselineskip }

\dim_new:N \l__essay_before_first_question_dim
\dim_new:N \l__essay_between_questions_dim
\dim_new:N \l__essay_after_question_dim
\dim_new:N \l__essay_user_line_skip_dim

\dim_set:Nn \l__essay_before_first_question_dim { 0.5em }
\dim_set:Nn \l__essay_between_questions_dim { 0.8\baselineskip }
\dim_set:Nn \l__essay_after_question_dim { 0.7\baselineskip }
\dim_set:Nn \l__essay_user_line_skip_dim { 1.4\baselineskip }

\NewDocumentEnvironment{Essay}{ O{true} }
  {
    \int_zero:N \l__essay_question_counter_int
    \tl_clear:N \l__essay_answer_tl

    \str_if_eq:nnTF {#1} {true}
      { \bool_set_true:N \l__essay_lines_bool }
      { \bool_set_false:N \l__essay_lines_bool }
  }
  {
    \tl_gset_eq:NN \g__question_answer_tl \l__essay_answer_tl
  }

\NewDocumentCommand{\EssayQuestion}{ O{4} m m }
  {
    \int_incr:N \l__essay_question_counter_int

    \int_compare:nNnTF { \l__essay_question_counter_int } = { 1 }
      { \par\vspace{\l__essay_before_first_question_dim} }
      { \par\vspace{\l__essay_between_questions_dim} }

    \par\noindent
    \makebox[2.65mm][c]{\ArNum{\l__essay_question_counter_int}}%
    \makebox[2.65mm][r]{.}%
    \hspace{0.7mm}%
    \parbox[t]{\dim_eval:n{\linewidth-6.0mm}}
      {
        \setlength{\baselineskip}{1.3\normalbaselineskip}
        #2
        \par
      }
    \par\prevdepth=\dp\strutbox%
    \par\vspace{\l__essay_after_question_dim}

    \bool_if:NTF \l__essay_lines_bool
      {
        \int_step_inline:nn {#1}
          {
            \noindent
            \hspace*{6.0mm}%
            \rule{\dim_eval:n{\linewidth-6.0mm}}{0.4pt}
            \par\vspace{\l__essay_line_skip_dim}
          }
      }
      {
        \int_step_inline:nn {#1}
          {
            \par\vspace{\l__essay_user_line_skip_dim}
          }
      }

    \tl_put_right:Nx \l__essay_answer_tl
      {
        \exp_not:N (\ArNum{\l__essay_question_counter_int})
        ~{$\;\Leftarrow\;$}~
        #3
        \par
      }
  }

% --------------------------------------------------
% 20. ShortAnswer
% --------------------------------------------------
\int_new:N \l__short_question_counter_int
\tl_new:N \l__short_answer_tl
\bool_new:N \l__short_lines_bool

\dim_const:Nn \l__short_number_width_dim { 5.3mm }

\dim_new:N \l__short_line_height_dim
\dim_new:N \l__short_line_after_dim
\dim_set:Nn \l__short_line_height_dim { 0.4\baselineskip }
\dim_set:Nn \l__short_line_after_dim { 0.4\baselineskip }

\dim_new:N \l__short_before_first_question_dim
\dim_new:N \l__short_between_questions_dim
\dim_new:N \l__short_after_question_dim

\dim_set:Nn \l__short_before_first_question_dim { 0.5em }
\dim_set:Nn \l__short_between_questions_dim { 0.1\baselineskip }
\dim_set:Nn \l__short_after_question_dim { 0.7\baselineskip }

\NewDocumentEnvironment{ShortAnswer}{ O{true} }
  {
    \int_zero:N \l__short_question_counter_int
    \tl_clear:N \l__short_answer_tl

    \str_if_eq:nnTF {#1} {true}
      { \bool_set_true:N \l__short_lines_bool }
      { \bool_set_false:N \l__short_lines_bool }
  }
  {
    \tl_gset_eq:NN \g__question_answer_tl \l__short_answer_tl
  }

\NewDocumentCommand{\ShortQuestion}{ O{1} m m }
  {
    \int_incr:N \l__short_question_counter_int

    \int_set:Nn \l_tmpa_int {#1}
    \int_compare:nNnT {#1} > { 2 }
      { \int_set:Nn \l_tmpa_int { 2 } }

    \int_compare:nNnTF { \l__short_question_counter_int } = { 1 }
      { \par\vspace{\l__short_before_first_question_dim} }
      { \par\vspace{\l__short_between_questions_dim} }

    \par\noindent
    \makebox[2.65mm][c]{\ArNum{\l__short_question_counter_int}}%
    \makebox[2.65mm][r]{.}%
    \hspace{0.7mm}%
    \parbox[t]{\dim_eval:n{\linewidth-6.0mm}}
      {
        \setlength{\baselineskip}{18pt}
        #2
        \int_compare:nNnT { \l_tmpa_int } = { 0 }
          { \quad \underline{\hspace{7em}} }
      }
    \par\prevdepth=\dp\strutbox%
    \vspace{\l__short_after_question_dim}

    \int_compare:nNnT { \l_tmpa_int } > { 0 }
      {
        \int_step_inline:nn { \l_tmpa_int }
          {
            \par
            \noindent
            \hspace*{6.0mm}%
            \rule{\dim_eval:n{\linewidth-6.0mm}}
              { \bool_if:NTF \l__short_lines_bool {0.4pt} {0pt} }
            \par\vspace{\l__short_line_height_dim}
          }
        \vspace{\l__short_line_after_dim}
      }
    \par

    \tl_put_right:Nx \l__short_answer_tl
      {
        \exp_not:N (\ArNum{\l__short_question_counter_int})
        ~{$\;\Leftarrow\;$}~
        #3
        \par
      }
  }

% --------------------------------------------------
% 21. Reading Passage
% --------------------------------------------------
\NewDocumentEnvironment{ReadingPassage}{ O{} m }
  {
    \par
    \begin{tcolorbox}[
      enhanced,
      breakable,
      colback=white,
      colframe=black,
      arc=0pt,
      outer~arc=0pt,
      boxrule=1pt,
      top=10pt,
      bottom=10pt,
      left=10pt,
      right=10pt,
      parbox=true,
      fontupper=\linespread{1.4}\selectfont,
      before~upper={\begin{RTL}},
      after~upper={\end{RTL}},
      coltitle=black,
      fonttitle=\bfseries,
      title={\textbf{\tl_if_empty:nTF {#2} {قطعة~القراءة} {#2}}},
      #1,
      attach~boxed~title~to~top~center={
        yshift=-3mm,
        yshifttext=-1mm
      },
      boxed~title~style={
        colback=white,
        colframe=white,
        left=5pt, right=5pt
      }
    ]
  }
  {
    \end{tcolorbox}
    \par\smallskip
  }

% --------------------------------------------------
% 22. End
% --------------------------------------------------
\ExplSyntaxOff

%    \end{macrocode}

% \iffalse
%</package>
% \fi

% \Finale