summaryrefslogtreecommitdiff
path: root/macros
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2024-04-15 03:01:17 +0000
committerNorbert Preining <norbert@preining.info>2024-04-15 03:01:17 +0000
commitefca04f9a0ac7156dacf34c21a20614e34e37ca2 (patch)
tree8b2eb913577e8fceac2a8fb7a93bdb7e20715755 /macros
parentad42b96b7e6aa836e884a18da3f45d53dc779145 (diff)
CTAN sync 202404150301
Diffstat (limited to 'macros')
-rw-r--r--macros/generic/crossrefenum/CHANGELOG.md9
-rw-r--r--macros/generic/crossrefenum/README.md6
-rw-r--r--macros/generic/crossrefenum/doc/TEMPLATE_crossrefenum.context6
-rw-r--r--macros/generic/crossrefenum/doc/crossrefenum.md17
-rw-r--r--macros/generic/crossrefenum/doc/crossrefenum.pdfbin214504 -> 214804 bytes
-rw-r--r--macros/generic/crossrefenum/test/Makefile8
-rw-r--r--macros/generic/crossrefenum/test/validated-output7589
-rw-r--r--macros/generic/crossrefenum/tex/crossrefenum.tex15
-rw-r--r--macros/generic/crossrefenum/tex/t-crossrefenum.tex2
-rw-r--r--macros/latex-dev/required/l3backend/CHANGELOG.md402
-rw-r--r--macros/latex-dev/required/l3backend/README.md16
-rw-r--r--macros/latex-dev/required/l3backend/l3backend-basics.dtx497
-rw-r--r--macros/latex-dev/required/l3backend/l3backend-box.dtx470
-rw-r--r--macros/latex-dev/required/l3backend/l3backend-code.pdfbin0 -> 907792 bytes
-rw-r--r--macros/latex-dev/required/l3backend/l3backend-code.tex63
-rw-r--r--macros/latex-dev/required/l3backend/l3backend-color.dtx1356
-rw-r--r--macros/latex-dev/required/l3backend/l3backend-draw.dtx1067
-rw-r--r--macros/latex-dev/required/l3backend/l3backend-graphics.dtx931
-rw-r--r--macros/latex-dev/required/l3backend/l3backend-header.dtx590
-rw-r--r--macros/latex-dev/required/l3backend/l3backend-opacity.dtx353
-rw-r--r--macros/latex-dev/required/l3backend/l3backend-pdf.dtx1755
-rw-r--r--macros/latex-dev/required/l3backend/l3backend.ins168
-rw-r--r--macros/latex-dev/required/l3kernel/CHANGELOG.md1879
-rw-r--r--macros/latex-dev/required/l3kernel/README.md96
-rw-r--r--macros/latex-dev/required/l3kernel/expl3.dtx1798
-rw-r--r--macros/latex-dev/required/l3kernel/expl3.pdfbin0 -> 610072 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/interface3.pdfbin0 -> 1801762 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/interface3.tex82
-rw-r--r--macros/latex-dev/required/l3kernel/l3.ins182
-rw-r--r--macros/latex-dev/required/l3kernel/l3basics.dtx3507
-rw-r--r--macros/latex-dev/required/l3kernel/l3bitset.dtx629
-rw-r--r--macros/latex-dev/required/l3kernel/l3bootstrap.dtx357
-rw-r--r--macros/latex-dev/required/l3kernel/l3box.dtx2530
-rw-r--r--macros/latex-dev/required/l3kernel/l3cctab.dtx975
-rw-r--r--macros/latex-dev/required/l3kernel/l3clist.dtx2248
-rw-r--r--macros/latex-dev/required/l3kernel/l3coffins.dtx2590
-rw-r--r--macros/latex-dev/required/l3kernel/l3color.dtx3246
-rw-r--r--macros/latex-dev/required/l3kernel/l3debug.dtx1478
-rw-r--r--macros/latex-dev/required/l3kernel/l3deprecation.dtx691
-rw-r--r--macros/latex-dev/required/l3kernel/l3doc.dtx4802
-rw-r--r--macros/latex-dev/required/l3kernel/l3doc.pdfbin0 -> 565293 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3docstrip.dtx96
-rw-r--r--macros/latex-dev/required/l3kernel/l3docstrip.pdfbin0 -> 150996 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3expan.dtx2398
-rw-r--r--macros/latex-dev/required/l3kernel/l3file.dtx4026
-rw-r--r--macros/latex-dev/required/l3kernel/l3flag.dtx396
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-assign.dtx316
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-aux.dtx1291
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-basics.dtx2181
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-convert.dtx630
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-expo.dtx1380
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-extended.dtx1275
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-functions.dtx288
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-logic.dtx750
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-parse.dtx2899
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-random.dtx629
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-round.dtx592
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-symbolic.dtx688
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-traps.dtx402
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-trig.dtx1700
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-types.dtx184
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp.dtx1663
-rw-r--r--macros/latex-dev/required/l3kernel/l3fparray.dtx427
-rw-r--r--macros/latex-dev/required/l3kernel/l3int.dtx2679
-rw-r--r--macros/latex-dev/required/l3kernel/l3intarray.dtx974
-rw-r--r--macros/latex-dev/required/l3kernel/l3kernel-functions.dtx739
-rw-r--r--macros/latex-dev/required/l3kernel/l3keys.dtx3649
-rw-r--r--macros/latex-dev/required/l3kernel/l3legacy.dtx161
-rw-r--r--macros/latex-dev/required/l3kernel/l3luatex.dtx750
-rw-r--r--macros/latex-dev/required/l3kernel/l3msg.dtx2443
-rw-r--r--macros/latex-dev/required/l3kernel/l3names.dtx1568
-rw-r--r--macros/latex-dev/required/l3kernel/l3news.pdfbin0 -> 402149 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news.tex187
-rw-r--r--macros/latex-dev/required/l3kernel/l3news01.pdfbin0 -> 122973 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news01.tex102
-rw-r--r--macros/latex-dev/required/l3kernel/l3news02.pdfbin0 -> 150932 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news02.tex153
-rw-r--r--macros/latex-dev/required/l3kernel/l3news03.pdfbin0 -> 154694 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news03.tex128
-rw-r--r--macros/latex-dev/required/l3kernel/l3news04.pdfbin0 -> 114764 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news04.tex123
-rw-r--r--macros/latex-dev/required/l3kernel/l3news05.pdfbin0 -> 112536 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news05.tex64
-rw-r--r--macros/latex-dev/required/l3kernel/l3news06.pdfbin0 -> 151602 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news06.tex141
-rw-r--r--macros/latex-dev/required/l3kernel/l3news07.pdfbin0 -> 128356 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news07.tex111
-rw-r--r--macros/latex-dev/required/l3kernel/l3news08.pdfbin0 -> 163496 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news08.tex170
-rw-r--r--macros/latex-dev/required/l3kernel/l3news09.pdfbin0 -> 256114 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news09.tex1433
-rw-r--r--macros/latex-dev/required/l3kernel/l3news10.pdfbin0 -> 156270 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news10.tex220
-rw-r--r--macros/latex-dev/required/l3kernel/l3news11.pdfbin0 -> 176082 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news11.tex208
-rw-r--r--macros/latex-dev/required/l3kernel/l3news12.pdfbin0 -> 210972 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news12.tex383
-rw-r--r--macros/latex-dev/required/l3kernel/l3pdf.dtx831
-rw-r--r--macros/latex-dev/required/l3kernel/l3prefixes.csv296
-rw-r--r--macros/latex-dev/required/l3kernel/l3prefixes.pdfbin0 -> 82732 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3prefixes.tex91
-rw-r--r--macros/latex-dev/required/l3kernel/l3prg.dtx1829
-rw-r--r--macros/latex-dev/required/l3kernel/l3prop.dtx2602
-rw-r--r--macros/latex-dev/required/l3kernel/l3quark.dtx1008
-rw-r--r--macros/latex-dev/required/l3kernel/l3regex.dtx8205
-rw-r--r--macros/latex-dev/required/l3kernel/l3seq.dtx2681
-rw-r--r--macros/latex-dev/required/l3kernel/l3skip.dtx2600
-rw-r--r--macros/latex-dev/required/l3kernel/l3sort.dtx1097
-rw-r--r--macros/latex-dev/required/l3kernel/l3str-convert.dtx3566
-rw-r--r--macros/latex-dev/required/l3kernel/l3str.dtx2226
-rw-r--r--macros/latex-dev/required/l3kernel/l3styleguide.pdfbin0 -> 296269 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3styleguide.tex303
-rw-r--r--macros/latex-dev/required/l3kernel/l3syntax-changes.pdfbin0 -> 231115 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3syntax-changes.tex190
-rw-r--r--macros/latex-dev/required/l3kernel/l3sys.dtx1383
-rw-r--r--macros/latex-dev/required/l3kernel/l3term-glossary.pdfbin0 -> 241905 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3term-glossary.tex180
-rw-r--r--macros/latex-dev/required/l3kernel/l3text-case.dtx2336
-rw-r--r--macros/latex-dev/required/l3kernel/l3text-map.dtx586
-rw-r--r--macros/latex-dev/required/l3kernel/l3text-purify.dtx797
-rw-r--r--macros/latex-dev/required/l3kernel/l3text.dtx1453
-rw-r--r--macros/latex-dev/required/l3kernel/l3tl-analysis.dtx1660
-rw-r--r--macros/latex-dev/required/l3kernel/l3tl-build.dtx356
-rw-r--r--macros/latex-dev/required/l3kernel/l3tl.dtx3843
-rw-r--r--macros/latex-dev/required/l3kernel/l3token.dtx2936
-rw-r--r--macros/latex-dev/required/l3kernel/l3unicode.dtx1031
-rw-r--r--macros/latex-dev/required/l3kernel/source3.pdfbin0 -> 7624184 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/source3.tex106
-rw-r--r--macros/latex-dev/required/l3kernel/source3body.tex620
-rw-r--r--macros/latex/contrib/acmart/README10
-rw-r--r--macros/latex/contrib/acmart/acmart.dtx168
-rw-r--r--macros/latex/contrib/acmart/acmart.pdfbin915325 -> 918804 bytes
-rw-r--r--macros/latex/contrib/acmart/acmguide.pdfbin441031 -> 439778 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-acmcp.pdfbin215115 -> 214495 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-acmengage.pdfbin400681 -> 400681 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-acmlarge.pdfbin611834 -> 611542 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-acmsmall-biblatex.pdfbin634465 -> 634239 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-acmsmall-conf.pdfbin1057098 -> 1056847 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-acmsmall-submission.pdfbin624275 -> 624039 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-acmsmall.pdfbin621763 -> 621531 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-acmtog-conf.pdfbin569862 -> 569299 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-acmtog.pdfbin569337 -> 569061 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-manuscript.pdfbin623270 -> 623030 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-sigconf-authordraft.pdfbin1048892 -> 1048753 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-sigconf-biblatex.pdfbin622211 -> 622065 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-sigconf-i13n.pdfbin1060387 -> 1060242 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-sigconf.pdfbin1045103 -> 1044964 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/sample-sigplan.pdfbin1053568 -> 1053423 bytes
-rw-r--r--macros/latex/contrib/acmart/samples/samples.dtx10
-rw-r--r--macros/latex/contrib/thesis-ekf/thesis-ekf.dtx188
-rw-r--r--macros/latex/contrib/thesis-ekf/thesis-ekf.pdfbin299369 -> 200001 bytes
-rw-r--r--macros/luatex/latex/piton/piton-french.pdf2017
-rw-r--r--macros/luatex/latex/piton/piton-french.tex24
-rw-r--r--macros/luatex/latex/piton/piton.dtx98
-rw-r--r--macros/luatex/latex/piton/piton.pdf18658
155 files changed, 137373 insertions, 11619 deletions
diff --git a/macros/generic/crossrefenum/CHANGELOG.md b/macros/generic/crossrefenum/CHANGELOG.md
index 70ca26494a..82f9e6b252 100644
--- a/macros/generic/crossrefenum/CHANGELOG.md
+++ b/macros/generic/crossrefenum/CHANGELOG.md
@@ -1,5 +1,9 @@
## Changes
+```{=context}
+\parindent=0pt
+```
+
### 2022/11/11: Version 1.0
### 2023/02/20: Version 1.0.1
@@ -10,3 +14,8 @@
Fixed some minor issues in version numbers and in the manual.
+### 2024/04/13: Version 1.1
+
+Various fixes in the documentation and new convenience macro `\crfnm@declareType`.
+
+The test suite now uses _lualatex_.
diff --git a/macros/generic/crossrefenum/README.md b/macros/generic/crossrefenum/README.md
index fc699bfe96..19798def6a 100644
--- a/macros/generic/crossrefenum/README.md
+++ b/macros/generic/crossrefenum/README.md
@@ -1,8 +1,8 @@
-# crossrefenum 2023/02/20 v1.0.2
+# crossrefenum 2024/04/13 v1.1
Smart typesetting of enumerated cross-references for various TeX formats.
-Copyright (C) 2022-2023
+Copyright (C) 2022-2024
by Bastien Dumont <bastien.dumont@posteo.net>
CTAN: `macros/generic/crossrefenum`
@@ -66,7 +66,7 @@ and put in it `crossrefenum.tex` and, if required,
## License
-Copyright 2022-2023 by Bastien Dumont (bastien.dumont@posteo.net)
+Copyright 2022-2024 by Bastien Dumont (bastien.dumont@posteo.net)
crossrefenum.tex is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/macros/generic/crossrefenum/doc/TEMPLATE_crossrefenum.context b/macros/generic/crossrefenum/doc/TEMPLATE_crossrefenum.context
index 27b15a0d85..e40f2dce99 100644
--- a/macros/generic/crossrefenum/doc/TEMPLATE_crossrefenum.context
+++ b/macros/generic/crossrefenum/doc/TEMPLATE_crossrefenum.context
@@ -22,7 +22,7 @@ $endif$
\setupbodyfontenvironment[default][em=italic]
\definefontfamily[mainface][rm][cochineal]
-\definefontfamily[mainface][ss][linuxbiolinumo]
+\definefontfamily[mainface][ss][libertinussans]
\definefontfamily[mainface][tt][nimbusmonops][features=none]
\setupbodyfont[mainface,12pt]
@@ -116,7 +116,7 @@ $endif$
$if(license)$
\startlicensepagemakeup
\inframed[frame=off, width=0.66\textwidth, align=normal]{%
- Copyright (C) 2022-2023 Bastien Dumont.
+ Copyright (C) 2022-2024 Bastien Dumont.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
@@ -136,4 +136,4 @@ $endif$
$body$
-\stoptext \ No newline at end of file
+\stoptext
diff --git a/macros/generic/crossrefenum/doc/crossrefenum.md b/macros/generic/crossrefenum/doc/crossrefenum.md
index 13e5494695..ee4da984aa 100644
--- a/macros/generic/crossrefenum/doc/crossrefenum.md
+++ b/macros/generic/crossrefenum/doc/crossrefenum.md
@@ -2,7 +2,7 @@
title: "crossrefenum"
subtitle: "Smart typesetting of enumerated cross-references for various TeX formats"
author: Bastien Dumont
-date: 2023/02/20
+date: 2024/04/13
lang: en-US
toc: true
license: true
@@ -40,7 +40,7 @@ you can do:
* `\input{crossrefenum}` (generic);
* `\usepackage{crossrefenum}` (LaTeX;
- must be called after _nameref_ if you use _hyperref_);
+ must be called after _nameref_ if you use _hyperref_`\kern1.5pt`{=context});
* `\usemodule[crossrefenum]` (ConTeXt).
## Basic invocation
@@ -164,7 +164,7 @@ for instance, you may want to use the word “andâ€
before the last note number if the reference type is a simple one (`note`),
and a comma if it is comes in second in a double reference (e.g. in `pagenote`).
To achieve this, you should redefine `\crfnmDefaultEnumDelimInSecond`
-and `\crfnmDefaultBeforeLastInEnumInSecond`.
+and `\crfnmDefaultBeforeLastInSecond`.
By default, these macros fall back respectively
on `\crfnmDefaultEnumDelim` and `\crfnmDefaultBeforeLastInEnum`.
@@ -215,6 +215,8 @@ use an empty group (e.g. `\def\crfnmPageEnumDelim{}`).
Adding support for new types consists in defining the related macros in your preamble.
Here is a commented example that would add support for references to lines in ConTeXt
if this feature were not already included in _crossrefenum_.
+We suppose that the labels are inserted in the document using the standard ConTeXt macros,
+i.e. `\someline` for line references and `\pagereference` for page references.
```{.tex}
% Register the types. Take care about capitalization!
@@ -226,10 +228,8 @@ if this feature were not already included in _crossrefenum_.
\def\crfnm@pageline{Pageline}
%% Add them to the lists of known types.
-\crfnm@newListFrom[\crfnm@simpleRefTypes][\crfnm@line] -> \crfnm@simpleRefTypes
-\crfnm@newListFrom[\crfnm@doubleRefTypes][\crfnm@pageline] -> \crfnm@doubleRefTypes
-\crfnm@newListFrom[\crfnm@supportedTypes][\crfnm@line] -> \crfnm@supportedTypes
-\crfnm@newListFrom[\crfnm@supportedTypes][\crfnm@pageline] -> \crfnm@supportedTypes
+\crfnm@declareType[simple][\crfnm@line]
+\crfnm@declareType[double][\crfnm@pageline]
```
```{.tex}
@@ -244,6 +244,7 @@ if this feature were not already included in _crossrefenum_.
% Define the macro used by \crossrefenum internally
% to retrieve the raw reference number without typesetting it.
+% This macro must be purely expandable.
% If you want to support multiple formats,
% see how the macro \crfnm@case is used in crossrefenum.tex.
% Note: the Lua function get_raw_ref_number is defined
@@ -275,7 +276,7 @@ If you have wishes or hints about this, please contact me.
## Compatibility issues
-With LaTeX, the _nameref_ package (required by _hyperref_)
+With LaTeX, the _nameref_ package (required by _hyperref_`\kern1.5pt`{=context})
must be loaded explicitely before _crossrefenum_.
However, if the links in the output of `\crossrefenum` (not the numbers)
point to a wrong location, you may wish to patch the macro
diff --git a/macros/generic/crossrefenum/doc/crossrefenum.pdf b/macros/generic/crossrefenum/doc/crossrefenum.pdf
index 94387d3b92..f21dab3285 100644
--- a/macros/generic/crossrefenum/doc/crossrefenum.pdf
+++ b/macros/generic/crossrefenum/doc/crossrefenum.pdf
Binary files differ
diff --git a/macros/generic/crossrefenum/test/Makefile b/macros/generic/crossrefenum/test/Makefile
index 749d63a96a..13021c9bd8 100644
--- a/macros/generic/crossrefenum/test/Makefile
+++ b/macros/generic/crossrefenum/test/Makefile
@@ -4,10 +4,10 @@ ALL=main-test.tex data-common.tex data-reledmac.tex config-formats.tex config-cr
define MAKE_BOXES_LIST
sed -i 's/%\\tracingoutput/\\tracingoutput/' $<
- -xelatex main-test.tex
+ -lualatex main-test.tex
sed -i 's/^\\tracingoutput/%\\tracingoutput/' $<
full_boxes_list="$$(grep -E '^\.+\\TU' main-test.log)"; \
- i_test_result_end="$$(( $$(grep -Fn '....\TU/lmr/m/sc/10 Capitulus' <<< "$$full_boxes_list" | head -n 1 | cut -d ':' -f 1) - 1))"; \
+ i_test_result_end="$$(( $$(grep -Fn '....\TU/lmr/m/sc/10 C' <<< "$$full_boxes_list" | head -n 1 | cut -d ':' -f 1) - 1))"; \
sed -n 1,$${i_test_result_end}p <<< "$$full_boxes_list" > $@
endef
@@ -15,12 +15,12 @@ clean:
-rm main-test.{aux,log,1,2,fdb_latexmk,fls,xdv,tuc}
test: clean $(ALL)
- latexmk -xelatex main-test.tex
+ latexmk -lualatex main-test.tex
log: $(ALL)
sed -i 's/%\\tracingcommands/\\tracingcommands/' $<
sed -i 's/%\\tracingmacros/\\tracingmacros/' $<
- -xelatex main-test.tex
+ -lualatex main-test.tex
sed -i 's/^\\tracingcommands/%\\tracingcommands/' $<
sed -i 's/^\\tracingmacros/%\\tracingmacros/' $<
diff --git a/macros/generic/crossrefenum/test/validated-output b/macros/generic/crossrefenum/test/validated-output
index e4c0843b3e..299e35f955 100644
--- a/macros/generic/crossrefenum/test/validated-output
+++ b/macros/generic/crossrefenum/test/validated-output
@@ -1,1229 +1,6658 @@
-....\TU/lmr/m/sc/10 All
-....\TU/lmr/m/sc/10 references
-....\TU/lmr/m/sc/10 point
-....\TU/lmr/m/sc/10 to
-....\TU/lmr/m/sc/10 different
-....\TU/lmr/m/sc/10 pages
-.....\TU/lmr/m/it/10 Nothing
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [p. ]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [p.
-.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 One
-.....\TU/lmr/m/it/10 single
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-14}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [p. 2]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [p.
-.....\TU/lmtt/m/n/10 2
-.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 One
-.....\TU/lmr/m/it/10 single
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/it/10 without
-.....\TU/lmr/m/it/10 prefix
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-18}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [2]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [2
+....\TU/lmr/m/sc/10 A
+....\TU/lmr/m/sc/10 l
+....\TU/lmr/m/sc/10 l
+....\TU/lmr/m/sc/10 r
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 f
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 r
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 n
+....\TU/lmr/m/sc/10 c
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 s
+....\TU/lmr/m/sc/10 p
+....\TU/lmr/m/sc/10 o
+....\TU/lmr/m/sc/10 i
+....\TU/lmr/m/sc/10 n
+....\TU/lmr/m/sc/10 t
+....\TU/lmr/m/sc/10 t
+....\TU/lmr/m/sc/10 o
+....\TU/lmr/m/sc/10 d
+....\TU/lmr/m/sc/10 i
+....\TU/lmr/m/sc/10 f
+....\TU/lmr/m/sc/10 f
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 r
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 n
+....\TU/lmr/m/sc/10 t
+....\TU/lmr/m/sc/10 p
+....\TU/lmr/m/sc/10 a
+....\TU/lmr/m/sc/10 g
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 s
+.....\TU/lmr/m/it/10 N
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/it/10 O
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/it/10 O
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 ï¬
+.....\TU/lmr/m/it/10 x
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 8
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 2
.....\TU/lmtt/m/n/10 ]
....\TU/lmr/m/n/10 1
-.....\TU/lmr/m/it/10 Two
-.....\TU/lmr/m/it/10 single
-.....\TU/lmr/m/it/10 pages
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-14}
-.....\TU/lmtt/m/n/10 {matthaeus-025}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 2
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 4]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
-.....\TU/lmtt/m/n/10 2
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmr/m/it/10 T
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 4
.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 Two
-.....\TU/lmr/m/it/10 single
-.....\TU/lmr/m/it/10 pages
-.....\TU/lmr/m/it/10 without
-.....\TU/lmr/m/it/10 prefix
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-19}
-.....\TU/lmtt/m/n/10 {matthaeus-0210}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [2
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 4]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [2
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 4
.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 More
-.....\TU/lmr/m/it/10 than
-.....\TU/lmr/m/it/10 two
-.....\TU/lmr/m/it/10 single
-.....\TU/lmr/m/it/10 pages
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-14}
-.....\TU/lmtt/m/n/10 {matthaeus-026}
-.....\TU/lmtt/m/n/10 {matthaeus-0223}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 2,
+.....\TU/lmr/m/it/10 T
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 ï¬
+.....\TU/lmr/m/it/10 x
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 9
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/it/10 M
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
.....\TU/lmtt/m/n/10 4
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 6]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 6
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
.....\TU/lmtt/m/n/10 2
.....\TU/lmtt/m/n/10 ,
.....\TU/lmtt/m/n/10 4
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 6
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 6
.....\TU/lmtt/m/n/10 ]
....\TU/lmr/m/n/10 2
-.....\TU/lmr/m/it/10 One
-.....\TU/lmr/m/it/10 single
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/it/10 again
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-027}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [p. 4]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [p.
+.....\TU/lmr/m/it/10 O
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 7
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
.....\TU/lmtt/m/n/10 4
.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 One
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-14
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 matthaeus-23}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 2-3]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
-.....\TU/lmtt/m/n/10 2
-.....\TU/lmtt/m/n/10 -3
-.....\TU/lmtt/m/n/10 ]
-....\TU/lmr/m/sc/10 Some
-....\TU/lmr/m/sc/10 references
-....\TU/lmr/m/sc/10 point
-....\TU/lmr/m/sc/10 to
-....\TU/lmr/m/sc/10 the
-....\TU/lmr/m/sc/10 same
-....\TU/lmr/m/sc/10 page
-.....\TU/lmr/m/it/10 One
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/it/10 that
-.....\TU/lmr/m/it/10 returns
-.....\TU/lmr/m/it/10 a
-.....\TU/lmr/m/it/10 single
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-027
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 matthaeus-029}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [p. 4]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [p.
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/it/10 O
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 ]
+....\TU/lmr/m/sc/10 S
+....\TU/lmr/m/sc/10 o
+....\TU/lmr/m/sc/10 m
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 r
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 f
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 r
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 n
+....\TU/lmr/m/sc/10 c
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 s
+....\TU/lmr/m/sc/10 p
+....\TU/lmr/m/sc/10 o
+....\TU/lmr/m/sc/10 i
+....\TU/lmr/m/sc/10 n
+....\TU/lmr/m/sc/10 t
+....\TU/lmr/m/sc/10 t
+....\TU/lmr/m/sc/10 o
+....\TU/lmr/m/sc/10 t
+....\TU/lmr/m/sc/10 h
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 s
+....\TU/lmr/m/sc/10 a
+....\TU/lmr/m/sc/10 m
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 p
+....\TU/lmr/m/sc/10 a
+....\TU/lmr/m/sc/10 g
+....\TU/lmr/m/sc/10 e
+.....\TU/lmr/m/it/10 O
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 7
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 9
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 4
.....\TU/lmtt/m/n/10 ]
....\TU/lmr/m/n/10 3
-.....\TU/lmr/m/it/10 Two
-.....\TU/lmr/m/it/10 identical
-.....\TU/lmr/m/it/10 pages
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-026}
-.....\TU/lmtt/m/n/10 {matthaeus-028}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [p. 4]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [p.
+.....\TU/lmr/m/it/10 T
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 6
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 8
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 4
.....\TU/lmtt/m/n/10 ]
.....\TU/lmr/m/it/10 A
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/it/10 followed
-.....\TU/lmr/m/it/10 by
-.....\TU/lmr/m/it/10 a
-.....\TU/lmr/m/it/10 reference
-.....\TU/lmr/m/it/10 on
-.....\TU/lmr/m/it/10 its
-.....\TU/lmr/m/it/10 end
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-2
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 matthaeus-15}
-.....\TU/lmtt/m/n/10 {matthaeus-16}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 1-2]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
-.....\TU/lmtt/m/n/10 1
-.....\TU/lmtt/m/n/10 -2
-.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 Two
-.....\TU/lmr/m/it/10 ranges
-.....\TU/lmr/m/it/10 with
-.....\TU/lmr/m/it/10 a
-.....\TU/lmr/m/it/10 common
-.....\TU/lmr/m/it/10 boundary
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-5
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 matthaeus-21}
-.....\TU/lmtt/m/n/10 {matthaeus-25
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 matthaeus-0214}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 1-5]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
-.....\TU/lmtt/m/n/10 1
-.....\TU/lmtt/m/n/10 -5
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 y
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 6
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/it/10 T
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 y
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 5
.....\TU/lmtt/m/n/10 ]
....\TU/lmr/m/n/10 4
-.....\TU/lmr/m/it/10 Two
-.....\TU/lmr/m/it/10 ranges
-.....\TU/lmr/m/it/10 with
-.....\TU/lmr/m/it/10 a
-.....\TU/lmr/m/it/10 common
-.....\TU/lmr/m/it/10 boundary,
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 second
-.....\TU/lmr/m/it/10 one
-.....\TU/lmr/m/it/10 having
-.....\TU/lmr/m/it/10 boths
-.....\TU/lmr/m/it/10 ends
-.....\TU/lmr/m/it/10 on
-.....\TU/lmr/m/it/10 a
-.....\TU/lmr/m/it/10 single
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-5
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 matthaeus-21}
-.....\TU/lmtt/m/n/10 {matthaeus-25
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 matthaeus-022}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 1-3]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
-.....\TU/lmtt/m/n/10 1
-.....\TU/lmtt/m/n/10 -3
+.....\TU/lmr/m/it/10 T
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 y
+.....\TU/lmr/m/it/10 ,
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 v
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 3
.....\TU/lmtt/m/n/10 ]
.....\TU/lmr/m/it/10 A
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/it/10 followed
-.....\TU/lmr/m/it/10 by
-.....\TU/lmr/m/it/10 a
-.....\TU/lmr/m/it/10 reference
-.....\TU/lmr/m/it/10 to
-.....\TU/lmr/m/it/10 its
-.....\TU/lmr/m/it/10 end
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/it/10 and
-.....\TU/lmr/m/it/10 a
-.....\TU/lmr/m/it/10 reference
-.....\TU/lmr/m/it/10 to
-.....\TU/lmr/m/it/10 another
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-2
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 matthaeus-15}
-.....\TU/lmtt/m/n/10 {matthaeus-16}
-.....\TU/lmtt/m/n/10 {matthaeus-0216}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 1-2
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 5]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
-.....\TU/lmtt/m/n/10 1
-.....\TU/lmtt/m/n/10 -2
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 y
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 6
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 6
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 5
.....\TU/lmtt/m/n/10 ]
.....\TU/lmr/m/it/10 A
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/it/10 followed
-.....\TU/lmr/m/it/10 by
-.....\TU/lmr/m/it/10 two
-.....\TU/lmr/m/it/10 references
-.....\TU/lmr/m/it/10 to
-.....\TU/lmr/m/it/10 its
-.....\TU/lmr/m/it/10 end
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-2
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 matthaeus-15}
-.....\TU/lmtt/m/n/10 {matthaeus-16}
-.....\TU/lmtt/m/n/10 {matthaeus-18}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 1-2]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
-.....\TU/lmtt/m/n/10 1
-.....\TU/lmtt/m/n/10 -2
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 y
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 6
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 8
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 2
.....\TU/lmtt/m/n/10 ]
....\TU/lmr/m/n/10 5
.....\TU/lmr/m/it/10 A
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/it/10 preceded
-.....\TU/lmr/m/it/10 by
-.....\TU/lmr/m/it/10 a
-.....\TU/lmr/m/it/10 reference
-.....\TU/lmr/m/it/10 to
-.....\TU/lmr/m/it/10 its
-.....\TU/lmr/m/it/10 begin
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-1}
-.....\TU/lmtt/m/n/10 {matthaeus-2
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 matthaeus-15}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 1-2]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
-.....\TU/lmtt/m/n/10 1
-.....\TU/lmtt/m/n/10 -2
-.....\TU/lmtt/m/n/10 ]
-....\TU/lmr/m/sc/10 Some
-....\TU/lmr/m/sc/10 references
-....\TU/lmr/m/sc/10 point
-....\TU/lmr/m/sc/10 to
-....\TU/lmr/m/sc/10 successive
-....\TU/lmr/m/sc/10 pages
-.....\TU/lmr/m/it/10 Successive
-.....\TU/lmr/m/it/10 pages
-.....\TU/lmr/m/it/10 forming
-.....\TU/lmr/m/it/10 a
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-2}
-.....\TU/lmtt/m/n/10 {matthaeus-15}
-.....\TU/lmtt/m/n/10 {matthaeus-22}
-.....\TU/lmtt/m/n/10 {matthaeus-025}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 1-4]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
-.....\TU/lmtt/m/n/10 1
-.....\TU/lmtt/m/n/10 -4
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 y
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 ]
+....\TU/lmr/m/sc/10 S
+....\TU/lmr/m/sc/10 o
+....\TU/lmr/m/sc/10 m
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 r
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 f
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 r
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 n
+....\TU/lmr/m/sc/10 c
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 s
+....\TU/lmr/m/sc/10 p
+....\TU/lmr/m/sc/10 o
+....\TU/lmr/m/sc/10 i
+....\TU/lmr/m/sc/10 n
+....\TU/lmr/m/sc/10 t
+....\TU/lmr/m/sc/10 t
+....\TU/lmr/m/sc/10 o
+....\TU/lmr/m/sc/10 s
+....\TU/lmr/m/sc/10 u
+....\TU/lmr/m/sc/10 c
+....\TU/lmr/m/sc/10 c
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 s
+....\TU/lmr/m/sc/10 s
+....\TU/lmr/m/sc/10 i
+....\TU/lmr/m/sc/10 v
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 p
+....\TU/lmr/m/sc/10 a
+....\TU/lmr/m/sc/10 g
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 s
+.....\TU/lmr/m/it/10 S
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 v
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
.....\TU/lmtt/m/n/10 ]
.....\TU/lmr/m/it/10 A
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/it/10 followed
-.....\TU/lmr/m/it/10 by
-.....\TU/lmr/m/it/10 a
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/it/10 that
-.....\TU/lmr/m/it/10 extends
-.....\TU/lmr/m/it/10 it
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-2
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 matthaeus-15}
-.....\TU/lmtt/m/n/10 {matthaeus-22}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 1-3]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
-.....\TU/lmtt/m/n/10 1
-.....\TU/lmtt/m/n/10 -3
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 y
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 x
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 3
.....\TU/lmtt/m/n/10 ]
....\TU/lmr/m/n/10 6
.....\TU/lmr/m/it/10 A
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/it/10 preceded
-.....\TU/lmr/m/it/10 by
-.....\TU/lmr/m/it/10 a
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/it/10 that
-.....\TU/lmr/m/it/10 extends
-.....\TU/lmr/m/it/10 it
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-1}
-.....\TU/lmtt/m/n/10 {matthaeus-14
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 matthaeus-0210}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 1-4]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
-.....\TU/lmtt/m/n/10 1
-.....\TU/lmtt/m/n/10 -4
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 y
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 x
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
.....\TU/lmtt/m/n/10 ]
.....\TU/lmr/m/it/10 A
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/it/10 extended
-.....\TU/lmr/m/it/10 by
-.....\TU/lmr/m/it/10 another
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {matthaeus-2
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 matthaeus-15}
-.....\TU/lmtt/m/n/10 {matthaeus-22
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 matthaeus-025}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 page
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 1-4]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
-.....\TU/lmtt/m/n/10 1
-.....\TU/lmtt/m/n/10 -4
-.....\TU/lmtt/m/n/10 ]
-....\TU/lmr/m/sc/10 References
-....\TU/lmr/m/sc/10 to
-....\TU/lmr/m/sc/10 notes
-.....\TU/lmr/m/it/10 One
-.....\TU/lmr/m/it/10 note
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {note-Aminadab-undecim}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 note
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [n. 1]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [n.
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 x
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 y
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 ]
+....\TU/lmr/m/sc/10 R
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 f
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 r
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 n
+....\TU/lmr/m/sc/10 c
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 s
+....\TU/lmr/m/sc/10 t
+....\TU/lmr/m/sc/10 o
+....\TU/lmr/m/sc/10 n
+....\TU/lmr/m/sc/10 o
+....\TU/lmr/m/sc/10 t
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 s
+.....\TU/lmr/m/it/10 O
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 A
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 b
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 1
.....\TU/lmtt/m/n/10 ]
....\TU/lmr/m/n/10 7
-.....\TU/lmr/m/it/10 Two
-.....\TU/lmr/m/it/10 notes
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {note-autem-non}
-.....\TU/lmtt/m/n/10 {note-generatio-Persarum}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 note
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [nn. 2
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 4]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [nn.
-.....\TU/lmtt/m/n/10 2
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmr/m/it/10 T
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 P
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 4
.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 Two
-.....\TU/lmr/m/it/10 consecutive
-.....\TU/lmr/m/it/10 notes
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {note-autem-non}
-.....\TU/lmtt/m/n/10 {note-generationes-quis}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 note
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [nn. 2
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 3]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [nn.
-.....\TU/lmtt/m/n/10 2
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/it/10 T
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 v
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 q
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 3
.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 Three
-.....\TU/lmr/m/it/10 consecutive
-.....\TU/lmr/m/it/10 notes
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {note-congregans-conteram}
-.....\TU/lmtt/m/n/10 {note-Israhel-mittam}
-.....\TU/lmtt/m/n/10 {note-regem-Theman}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 note
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [nn. 1,
-.....\TU/lmtt/m/n/10 2
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 3]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [nn.
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/it/10 T
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 v
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 I
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 T
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 1
.....\TU/lmtt/m/n/10 ,
.....\TU/lmtt/m/n/10 2
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 3
.....\TU/lmtt/m/n/10 ]
....\TU/lmr/m/n/10 8
-.\TU/lmr/m/it/10 Same
-.\TU/lmr/m/it/10 thing,
-.\TU/lmr/m/it/10 but
-.\TU/lmr/m/it/10 with
-.\TU/lmtt/m/n/10 \crfnmPagenotePrintFirstPrefix
-.\TU/lmr/m/it/10 set
-.\TU/lmr/m/it/10 to
-.\TU/lmtt/m/n/10 once
-....\TU/lmr/m/sc/10 References
-....\TU/lmr/m/sc/10 to
-....\TU/lmr/m/sc/10 notes
-....\TU/lmr/m/sc/10 with
-....\TU/lmr/m/sc/10 page
-....\TU/lmr/m/sc/10 number
-.....\TU/lmr/m/it/10 One
-.....\TU/lmr/m/it/10 note
-.....\TU/lmr/m/it/10 with
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/it/10 number
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {note-Babylonis-Libani}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 pagenote
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [p. 2,
-.....\TU/lmtt/m/n/10 n. 1]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [p.
+.\TU/lmr/m/it/10 S
+.\TU/lmr/m/it/10 a
+.\TU/lmr/m/it/10 m
+.\TU/lmr/m/it/10 e
+.\TU/lmr/m/it/10 t
+.\TU/lmr/m/it/10 h
+.\TU/lmr/m/it/10 i
+.\TU/lmr/m/it/10 n
+.\TU/lmr/m/it/10 g
+.\TU/lmr/m/it/10 ,
+.\TU/lmr/m/it/10 b
+.\TU/lmr/m/it/10 u
+.\TU/lmr/m/it/10 t
+.\TU/lmr/m/it/10 w
+.\TU/lmr/m/it/10 i
+.\TU/lmr/m/it/10 t
+.\TU/lmr/m/it/10 h
+.\TU/lmtt/m/n/10 \
+.\TU/lmtt/m/n/10 c
+.\TU/lmtt/m/n/10 r
+.\TU/lmtt/m/n/10 f
+.\TU/lmtt/m/n/10 n
+.\TU/lmtt/m/n/10 m
+.\TU/lmtt/m/n/10 P
+.\TU/lmtt/m/n/10 a
+.\TU/lmtt/m/n/10 g
+.\TU/lmtt/m/n/10 e
+.\TU/lmtt/m/n/10 n
+.\TU/lmtt/m/n/10 o
+.\TU/lmtt/m/n/10 t
+.\TU/lmtt/m/n/10 e
+.\TU/lmtt/m/n/10 P
+.\TU/lmtt/m/n/10 r
+.\TU/lmtt/m/n/10 i
+.\TU/lmtt/m/n/10 n
+.\TU/lmtt/m/n/10 t
+.\TU/lmtt/m/n/10 F
+.\TU/lmtt/m/n/10 i
+.\TU/lmtt/m/n/10 r
+.\TU/lmtt/m/n/10 s
+.\TU/lmtt/m/n/10 t
+.\TU/lmtt/m/n/10 P
+.\TU/lmtt/m/n/10 r
+.\TU/lmtt/m/n/10 e
+.\TU/lmtt/m/n/10 f
+.\TU/lmtt/m/n/10 i
+.\TU/lmtt/m/n/10 x
+.\TU/lmr/m/it/10 s
+.\TU/lmr/m/it/10 e
+.\TU/lmr/m/it/10 t
+.\TU/lmr/m/it/10 t
+.\TU/lmr/m/it/10 o
+.\TU/lmtt/m/n/10 o
+.\TU/lmtt/m/n/10 n
+.\TU/lmtt/m/n/10 c
+.\TU/lmtt/m/n/10 e
+....\TU/lmr/m/sc/10 R
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 f
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 r
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 n
+....\TU/lmr/m/sc/10 c
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 s
+....\TU/lmr/m/sc/10 t
+....\TU/lmr/m/sc/10 o
+....\TU/lmr/m/sc/10 n
+....\TU/lmr/m/sc/10 o
+....\TU/lmr/m/sc/10 t
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 s
+....\TU/lmr/m/sc/10 w
+....\TU/lmr/m/sc/10 i
+....\TU/lmr/m/sc/10 t
+....\TU/lmr/m/sc/10 h
+....\TU/lmr/m/sc/10 p
+....\TU/lmr/m/sc/10 a
+....\TU/lmr/m/sc/10 g
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 n
+....\TU/lmr/m/sc/10 u
+....\TU/lmr/m/sc/10 m
+....\TU/lmr/m/sc/10 b
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 r
+.....\TU/lmr/m/it/10 O
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 B
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 b
+.....\TU/lmtt/m/n/10 y
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 L
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 b
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
.....\TU/lmtt/m/n/10 2
.....\TU/lmtt/m/n/10 ,
-.....\TU/lmtt/m/n/10 n.
-.....\TU/lmtt/m/n/10 1
-.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 Same
-.....\TU/lmr/m/it/10 thing,
-.....\TU/lmr/m/it/10 but
-.....\TU/lmr/m/it/10 with
-.....\TU/lmtt/m/n/10 \crfnmPagenoteOrder
-.....\TU/lmr/m/it/10 set
-.....\TU/lmr/m/it/10 to
-.....\TU/lmtt/m/n/10 inverted
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {note-quaerat-clamate}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 pagenote
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [n. 3,
-.....\TU/lmtt/m/n/10 p. 5]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [n.
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/it/10 S
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 ,
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmtt/m/n/10 \
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 f
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 P
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 O
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 o
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 q
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 3
.....\TU/lmtt/m/n/10 ,
-.....\TU/lmtt/m/n/10 p.
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 5
.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 Four
-.....\TU/lmr/m/it/10 notes
-.....\TU/lmr/m/it/10 on
-.....\TU/lmr/m/it/10 different
-.....\TU/lmr/m/it/10 pages
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {note-Aminadab-undecim}
-.....\TU/lmtt/m/n/10 {note-generationes-quis}
-.....\TU/lmtt/m/n/10 {note-regem-Theman}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 pagenote
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [p. 1,
-.....\TU/lmtt/m/n/10 n. 1,
-.....\TU/lmtt/m/n/10 p. 2,
-.....\TU/lmtt/m/n/10 n. 3
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 p. 4,
-.....\TU/lmtt/m/n/10 n. 3]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [p.
+.....\TU/lmr/m/it/10 F
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 A
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 b
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 q
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 T
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
.....\TU/lmtt/m/n/10 1
.....\TU/lmtt/m/n/10 ,
-.....\TU/lmtt/m/n/10 n.
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
.....\TU/lmtt/m/n/10 1
.....\TU/lmtt/m/n/10 ,
-.....\TU/lmtt/m/n/10 p.
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
.....\TU/lmtt/m/n/10 2
.....\TU/lmtt/m/n/10 ,
-.....\TU/lmtt/m/n/10 n.
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
.....\TU/lmtt/m/n/10 3
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 p.
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
.....\TU/lmtt/m/n/10 4
.....\TU/lmtt/m/n/10 ,
-.....\TU/lmtt/m/n/10 n.
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 3
.....\TU/lmtt/m/n/10 ]
....\TU/lmr/m/n/10 9
-.....\TU/lmr/m/it/10 Same
-.....\TU/lmr/m/it/10 thing,
-.....\TU/lmr/m/it/10 but
-.....\TU/lmr/m/it/10 with
-.....\TU/lmtt/m/n/10 \crfnmPagenotePrintFirstPrefix
-.....\TU/lmr/m/it/10 set
-.....\TU/lmr/m/it/10 to
-.....\TU/lmtt/m/n/10 once
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {note-Aminadab-undecim}
-.....\TU/lmtt/m/n/10 {note-generationes-quis}
-.....\TU/lmtt/m/n/10 {note-regem-Theman}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 pagenote
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 1,
-.....\TU/lmtt/m/n/10 n. 1,
-.....\TU/lmtt/m/n/10 2,
-.....\TU/lmtt/m/n/10 n. 3
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 4,
-.....\TU/lmtt/m/n/10 n. 3]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
+.....\TU/lmr/m/it/10 S
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 ,
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmtt/m/n/10 \
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 f
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 P
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 P
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 F
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 P
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 f
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 x
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 o
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 A
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 b
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 q
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 T
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 1
.....\TU/lmtt/m/n/10 ,
-.....\TU/lmtt/m/n/10 n.
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 1
.....\TU/lmtt/m/n/10 ,
.....\TU/lmtt/m/n/10 2
.....\TU/lmtt/m/n/10 ,
-.....\TU/lmtt/m/n/10 n.
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 3
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 4
.....\TU/lmtt/m/n/10 ,
-.....\TU/lmtt/m/n/10 n.
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 3
.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 Several
-.....\TU/lmr/m/it/10 notes
-.....\TU/lmr/m/it/10 on
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 same
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {note-et-et}
-.....\TU/lmtt/m/n/10 {note-puerum-et}
-.....\TU/lmtt/m/n/10 {note-habitavit-quae}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 pagenote
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [p. 6,
-.....\TU/lmtt/m/n/10 nn. 1,
+.....\TU/lmr/m/it/10 S
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 v
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 b
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 q
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 6
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 ,
.....\TU/lmtt/m/n/10 3
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 4]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [p.
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 6
.....\TU/lmtt/m/n/10 ,
-.....\TU/lmtt/m/n/10 nn.
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 1
.....\TU/lmtt/m/n/10 ,
.....\TU/lmtt/m/n/10 3
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 4
.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 Same
-.....\TU/lmr/m/it/10 thing,
-.....\TU/lmr/m/it/10 but
-.....\TU/lmr/m/it/10 followed
-.....\TU/lmr/m/it/10 by
-.....\TU/lmr/m/it/10 an
-.....\TU/lmr/m/it/10 isolated
-.....\TU/lmr/m/it/10 reference
-.....\TU/lmr/m/it/10 on
-.....\TU/lmr/m/it/10 another
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {note-somnis-hic}
-.....\TU/lmtt/m/n/10 {note-cum-haec}
-.....\TU/lmtt/m/n/10 {note-quaerat-clamate}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 pagenote
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [p. 3,
-.....\TU/lmtt/m/n/10 nn. 1
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 2
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 p. 5,
-.....\TU/lmtt/m/n/10 n. 3]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [p.
+.....\TU/lmr/m/it/10 S
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 ,
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 y
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 q
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
.....\TU/lmtt/m/n/10 3
.....\TU/lmtt/m/n/10 ,
-.....\TU/lmtt/m/n/10 nn.
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
.....\TU/lmtt/m/n/10 1
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 2
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 p.
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
.....\TU/lmtt/m/n/10 5
.....\TU/lmtt/m/n/10 ,
-.....\TU/lmtt/m/n/10 n.
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
.....\TU/lmtt/m/n/10 3
.....\TU/lmtt/m/n/10 ]
-....\TU/lmr/m/n/10 10
-.....\TU/lmr/m/it/10 Same
-.....\TU/lmr/m/it/10 thing,
-.....\TU/lmr/m/it/10 but
-.....\TU/lmr/m/it/10 with
-.....\TU/lmtt/m/n/10 \crfnmPagenoteOrder
-.....\TU/lmr/m/it/10 set
-.....\TU/lmr/m/it/10 to
-.....\TU/lmtt/m/n/10 inverted
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {note-somnis-hic}
-.....\TU/lmtt/m/n/10 {note-cum-haec}
-.....\TU/lmtt/m/n/10 {note-quaerat-clamate}
-.....\TU/lmtt/m/n/10 {note-obitum-mittite}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 pagenote
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [nn. 1
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 2,
-.....\TU/lmtt/m/n/10 p. 3
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 nn. 3
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 4,
-.....\TU/lmtt/m/n/10 p. 5]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [nn.
-.....\TU/lmtt/m/n/10 1
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 5
.....\TU/lmtt/m/n/10 ,
-.....\TU/lmtt/m/n/10 p.
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 3
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 nn.
+.....\TU/lmtt/m/n/10 ]
+....\TU/lmr/m/n/10 1
+....\TU/lmr/m/n/10 0
+.....\TU/lmr/m/it/10 S
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 ,
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmtt/m/n/10 \
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 f
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 P
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 O
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 o
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 h
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 q
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 b
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
.....\TU/lmtt/m/n/10 3
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 4
.....\TU/lmtt/m/n/10 ,
-.....\TU/lmtt/m/n/10 p.
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
.....\TU/lmtt/m/n/10 5
.....\TU/lmtt/m/n/10 ]
-....\TU/lmr/m/sc/10 Reledmac
-.....\TU/lmr/m/it/10 Simple
-.....\TU/lmr/m/it/10 reference
-.....\TU/lmr/m/it/10 to
-.....\TU/lmr/m/it/10 a
-.....\TU/lmr/m/it/10 line
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {vulgate-12}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 edline
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [l. 8]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [l.
-.....\TU/lmtt/m/n/10 8]
-.....\TU/lmr/m/it/10 Simple
-.....\TU/lmr/m/it/10 reference
-.....\TU/lmr/m/it/10 to
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/it/10 and
-.....\TU/lmr/m/it/10 line
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {vulgate-14}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 edpageline
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [p. 8
-......\TU/lmtt/m/n/7 12
-.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [p.
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 ,
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 ]
+....\TU/lmr/m/sc/10 R
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 l
+....\TU/lmr/m/sc/10 e
+....\TU/lmr/m/sc/10 d
+....\TU/lmr/m/sc/10 m
+....\TU/lmr/m/sc/10 a
+....\TU/lmr/m/sc/10 c
+.....\TU/lmr/m/it/10 S
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 8
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 8
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/it/10 S
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 8
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 2
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 8
-......\TU/lmtt/m/n/7 12
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 2
.....\TU/lmtt/m/n/10 ]
-....\TU/lmr/m/n/10 11
+....\TU/lmr/m/n/10 1
+....\TU/lmr/m/n/10 1
.\TU/lmr/m/it/10 A
-.\TU/lmr/m/it/10 range
-.\TU/lmr/m/it/10 of
-.\TU/lmr/m/it/10 lines
-.\TU/lmr/m/it/10 on
-.\TU/lmr/m/it/10 two
-.\TU/lmr/m/it/10 different
-.\TU/lmr/m/it/10 pages
-.\TU/lmr/m/it/10 with
-.\TU/lmtt/m/n/10 \crfnmEdpagelineGroupSubtypes
-.....\TU/lmr/m/it/10 Several
-.....\TU/lmr/m/it/10 lines
-.....\TU/lmr/m/it/10 on
-.....\TU/lmr/m/it/10 different
-.....\TU/lmr/m/it/10 pages
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {vulgate-15}
-.....\TU/lmtt/m/n/10 {vulgate-24}
-.....\TU/lmtt/m/n/10 {vulgate-215}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 edpageline
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 8
-......\TU/lmtt/m/n/7 13
+.\TU/lmr/m/it/10 r
+.\TU/lmr/m/it/10 a
+.\TU/lmr/m/it/10 n
+.\TU/lmr/m/it/10 g
+.\TU/lmr/m/it/10 e
+.\TU/lmr/m/it/10 o
+.\TU/lmr/m/it/10 f
+.\TU/lmr/m/it/10 l
+.\TU/lmr/m/it/10 i
+.\TU/lmr/m/it/10 n
+.\TU/lmr/m/it/10 e
+.\TU/lmr/m/it/10 s
+.\TU/lmr/m/it/10 o
+.\TU/lmr/m/it/10 n
+.\TU/lmr/m/it/10 t
+.\TU/lmr/m/it/10 w
+.\TU/lmr/m/it/10 o
+.\TU/lmr/m/it/10 d
+.\TU/lmr/m/it/10 i
+.\TU/lmr/m/it/10 e
+.\TU/lmr/m/it/10 r
+.\TU/lmr/m/it/10 e
+.\TU/lmr/m/it/10 n
+.\TU/lmr/m/it/10 t
+.\TU/lmr/m/it/10 p
+.\TU/lmr/m/it/10 a
+.\TU/lmr/m/it/10 g
+.\TU/lmr/m/it/10 e
+.\TU/lmr/m/it/10 s
+.\TU/lmr/m/it/10 w
+.\TU/lmr/m/it/10 i
+.\TU/lmr/m/it/10 t
+.\TU/lmr/m/it/10 h
+.\TU/lmtt/m/n/10 \
+.\TU/lmtt/m/n/10 c
+.\TU/lmtt/m/n/10 r
+.\TU/lmtt/m/n/10 f
+.\TU/lmtt/m/n/10 n
+.\TU/lmtt/m/n/10 m
+.\TU/lmtt/m/n/10 E
+.\TU/lmtt/m/n/10 d
+.\TU/lmtt/m/n/10 p
+.\TU/lmtt/m/n/10 a
+.\TU/lmtt/m/n/10 g
+.\TU/lmtt/m/n/10 e
+.\TU/lmtt/m/n/10 l
+.\TU/lmtt/m/n/10 i
+.\TU/lmtt/m/n/10 n
+.\TU/lmtt/m/n/10 e
+.\TU/lmtt/m/n/10 G
+.\TU/lmtt/m/n/10 r
+.\TU/lmtt/m/n/10 o
+.\TU/lmtt/m/n/10 u
+.\TU/lmtt/m/n/10 p
+.\TU/lmtt/m/n/10 S
+.\TU/lmtt/m/n/10 u
+.\TU/lmtt/m/n/10 b
+.\TU/lmtt/m/n/10 t
+.\TU/lmtt/m/n/10 y
+.\TU/lmtt/m/n/10 p
+.\TU/lmtt/m/n/10 e
+.\TU/lmtt/m/n/10 s
+.....\TU/lmr/m/it/10 S
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 v
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 8
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 3
.....\TU/lmtt/m/n/10 ,
.....\TU/lmtt/m/n/10 9
-......\TU/lmtt/m/n/7 15
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 11
-......\TU/lmtt/m/n/7 13
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 5
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 1
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 3
.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 8
-......\TU/lmtt/m/n/7 13
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 3
.....\TU/lmtt/m/n/10 ,
.....\TU/lmtt/m/n/10 9
-......\TU/lmtt/m/n/7 15
-.....\TU/lmtt/m/n/10 and
-.....\TU/lmtt/m/n/10 11
-......\TU/lmtt/m/n/7 13
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 5
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 1
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 3
.....\TU/lmtt/m/n/10 ]
.....\TU/lmr/m/it/10 A
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/it/10 of
-.....\TU/lmr/m/it/10 lines
-.....\TU/lmr/m/it/10 on
-.....\TU/lmr/m/it/10 a
-.....\TU/lmr/m/it/10 single
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {vulgate-22
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 vulgate-23}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 edpageline
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [p. 9
-......\TU/lmtt/m/n/7 9-11
-.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [p.
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 9
+......\TU/lmtt/m/n/7 9
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 1
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 9
-......\TU/lmtt/m/n/7 9-11
+......\TU/lmtt/m/n/7 9
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 1
.....\TU/lmtt/m/n/10 ]
.....\TU/lmr/m/it/10 A
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/it/10 of
-.....\TU/lmr/m/it/10 lines
-.....\TU/lmr/m/it/10 on
-.....\TU/lmr/m/it/10 two
-.....\TU/lmr/m/it/10 different
-.....\TU/lmr/m/it/10 pages
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {vulgate-24
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 vulgate-212}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 edpageline
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 9
-......\TU/lmtt/m/n/7 15
-.....\TU/lmtt/m/n/10 -11
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 9
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 5
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 1
......\TU/lmtt/m/n/7 6
.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 9
-......\TU/lmtt/m/n/7 15
-.....\TU/lmtt/m/n/10 -11
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 5
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 1
......\TU/lmtt/m/n/7 6
.....\TU/lmtt/m/n/10 ]
-....\TU/lmr/m/n/10 12
+....\TU/lmr/m/n/10 1
+....\TU/lmr/m/n/10 2
.....\TU/lmr/m/it/10 A
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/it/10 of
-.....\TU/lmr/m/it/10 lines
-.....\TU/lmr/m/it/10 on
-.....\TU/lmr/m/it/10 two
-.....\TU/lmr/m/it/10 different
-.....\TU/lmr/m/it/10 pages
-.....\TU/lmr/m/it/10 with
-.....\TU/lmtt/m/n/10 \crfnmEdpagelineGroupSubtypes
-.....\TU/lmr/m/it/10 set
-.....\TU/lmr/m/it/10 to
-.....\TU/lmtt/m/n/10 yes
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {vulgate-11
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 vulgate-215}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 edpageline
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 8-11
-......\TU/lmtt/m/n/7 4-13
-.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
-.....\TU/lmtt/m/n/10 8-11
-......\TU/lmtt/m/n/7 4-13
-.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 Two
-.....\TU/lmr/m/it/10 ranges
-.....\TU/lmr/m/it/10 of
-.....\TU/lmr/m/it/10 lines
-.....\TU/lmr/m/it/10 on
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 same
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/it/10 that
-.....\TU/lmr/m/it/10 should
-.....\TU/lmr/m/it/10 be
-.....\TU/lmr/m/it/10 merged
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {vulgate-211
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 vulgate-212}
-.....\TU/lmtt/m/n/10 {vulgate-213
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 vulgate-217}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 edpageline
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [p. 11
-......\TU/lmtt/m/n/7 4-19
-.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [p.
-.....\TU/lmtt/m/n/10 11
-......\TU/lmtt/m/n/7 4-19
-.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 Two
-.....\TU/lmr/m/it/10 ranges
-.....\TU/lmr/m/it/10 of
-.....\TU/lmr/m/it/10 lines
-.....\TU/lmr/m/it/10 on
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 same
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/it/10 that
-.....\TU/lmr/m/it/10 should
-.....\TU/lmr/m/it/10 not
-.....\TU/lmr/m/it/10 be
-.....\TU/lmr/m/it/10 merged
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {vulgate-219
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 vulgate-221}
-.....\TU/lmtt/m/n/10 {vulgate-224
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 vulgate-227}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 edpageline
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [p. 12
-......\TU/lmtt/m/n/7 1-6,
-......\TU/lmtt/m/n/7 12-19
-.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [p.
-.....\TU/lmtt/m/n/10 12
-......\TU/lmtt/m/n/7 1-6,
-......\TU/lmtt/m/n/7 12-19
-.....\TU/lmtt/m/n/10 ]
-....\TU/lmr/m/n/10 13
-.\TU/lmr/m/it/10 Same
-.\TU/lmr/m/it/10 as
-.\TU/lmr/m/it/10 the
-.\TU/lmr/m/it/10 above,
-.\TU/lmr/m/it/10 but
-.\TU/lmr/m/it/10 with
-.\TU/lmtt/m/n/10 \crfnmEdlineNumberingContinuousAcrossDocument
-.....\TU/lmr/m/it/10 Two
-.....\TU/lmr/m/it/10 ranges
-.....\TU/lmr/m/it/10 of
-.....\TU/lmr/m/it/10 lines
-.....\TU/lmr/m/it/10 spanning
-.....\TU/lmr/m/it/10 across
-.....\TU/lmr/m/it/10 pages
-.....\TU/lmr/m/it/10 that
-.....\TU/lmr/m/it/10 should
-.....\TU/lmr/m/it/10 be
-.....\TU/lmr/m/it/10 merged
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {vulgate-214
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 vulgate-223}
-.....\TU/lmtt/m/n/10 {vulgate-224
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 vulgate-233}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 edpageline
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 11
-......\TU/lmtt/m/n/7 10
-.....\TU/lmtt/m/n/10 -13
-......\TU/lmtt/m/n/7 15
-.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
-.....\TU/lmtt/m/n/10 11
-......\TU/lmtt/m/n/7 10
-.....\TU/lmtt/m/n/10 -13
-......\TU/lmtt/m/n/7 15
-.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/it/10 Two
-.....\TU/lmr/m/it/10 ranges
-.....\TU/lmr/m/it/10 of
-.....\TU/lmr/m/it/10 lines
-.....\TU/lmr/m/it/10 on
-.....\TU/lmr/m/it/10 consecutive
-.....\TU/lmr/m/it/10 pages,
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 beginning
-.....\TU/lmr/m/it/10 of
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 second
-.....\TU/lmr/m/it/10 being
-.....\TU/lmr/m/it/10 at
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 same
-.....\TU/lmr/m/it/10 line
-.....\TU/lmr/m/it/10 number
-.....\TU/lmr/m/it/10 as
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 end
-.....\TU/lmr/m/it/10 of
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 first
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmtt/m/n/10 \
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 f
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 E
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 G
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 S
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 b
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 y
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 o
+.....\TU/lmtt/m/n/10 y
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 8
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 1
+......\TU/lmtt/m/n/7 4
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 3
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 8
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 1
+......\TU/lmtt/m/n/7 4
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 3
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/it/10 T
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 7
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 1
+......\TU/lmtt/m/n/7 4
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 9
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 1
+......\TU/lmtt/m/n/7 4
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 9
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/it/10 T
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 9
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 7
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 2
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 6
+......\TU/lmtt/m/n/7 ,
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 2
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 9
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 2
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 6
+......\TU/lmtt/m/n/7 ,
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 2
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 9
+.....\TU/lmtt/m/n/10 ]
+....\TU/lmr/m/n/10 1
+....\TU/lmr/m/n/10 3
+.\TU/lmr/m/it/10 S
+.\TU/lmr/m/it/10 a
+.\TU/lmr/m/it/10 m
+.\TU/lmr/m/it/10 e
+.\TU/lmr/m/it/10 a
+.\TU/lmr/m/it/10 s
+.\TU/lmr/m/it/10 t
+.\TU/lmr/m/it/10 h
+.\TU/lmr/m/it/10 e
+.\TU/lmr/m/it/10 a
+.\TU/lmr/m/it/10 b
+.\TU/lmr/m/it/10 o
+.\TU/lmr/m/it/10 v
+.\TU/lmr/m/it/10 e
+.\TU/lmr/m/it/10 ,
+.\TU/lmr/m/it/10 b
+.\TU/lmr/m/it/10 u
+.\TU/lmr/m/it/10 t
+.\TU/lmr/m/it/10 w
+.\TU/lmr/m/it/10 i
+.\TU/lmr/m/it/10 t
+.\TU/lmr/m/it/10 h
+.\TU/lmtt/m/n/10 \
+.\TU/lmtt/m/n/10 c
+.\TU/lmtt/m/n/10 r
+.\TU/lmtt/m/n/10 f
+.\TU/lmtt/m/n/10 n
+.\TU/lmtt/m/n/10 m
+.\TU/lmtt/m/n/10 E
+.\TU/lmtt/m/n/10 d
+.\TU/lmtt/m/n/10 l
+.\TU/lmtt/m/n/10 i
+.\TU/lmtt/m/n/10 n
+.\TU/lmtt/m/n/10 e
+.\TU/lmtt/m/n/10 N
+.\TU/lmtt/m/n/10 u
+.\TU/lmtt/m/n/10 m
+.\TU/lmtt/m/n/10 b
+.\TU/lmtt/m/n/10 e
+.\TU/lmtt/m/n/10 r
+.\TU/lmtt/m/n/10 i
+.\TU/lmtt/m/n/10 n
+.\TU/lmtt/m/n/10 g
+.\TU/lmtt/m/n/10 C
+.\TU/lmtt/m/n/10 o
+.\TU/lmtt/m/n/10 n
+.\TU/lmtt/m/n/10 t
+.\TU/lmtt/m/n/10 i
+.\TU/lmtt/m/n/10 n
+.\TU/lmtt/m/n/10 u
+.\TU/lmtt/m/n/10 o
+.\TU/lmtt/m/n/10 u
+.\TU/lmtt/m/n/10 s
+.\TU/lmtt/m/n/10 A
+.\TU/lmtt/m/n/10 c
+.\TU/lmtt/m/n/10 r
+.\TU/lmtt/m/n/10 o
+.\TU/lmtt/m/n/10 s
+.\TU/lmtt/m/n/10 s
+.\TU/lmtt/m/n/10 D
+.\TU/lmtt/m/n/10 o
+.\TU/lmtt/m/n/10 c
+.\TU/lmtt/m/n/10 u
+.\TU/lmtt/m/n/10 m
+.\TU/lmtt/m/n/10 e
+.\TU/lmtt/m/n/10 n
+.\TU/lmtt/m/n/10 t
+.....\TU/lmr/m/it/10 T
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 1
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 0
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 3
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 5
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 1
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 0
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 3
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 5
+.....\TU/lmtt/m/n/10 ]
+.....\TU/lmr/m/it/10 T
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 v
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 ,
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 ï¬
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 t
.....\TU/lmr/m/it/10 +
-.....\TU/lmr/m/it/10 1.
-.....\TU/lmr/m/it/10 They
-.....\TU/lmr/m/it/10 should
-.....\TU/lmr/m/it/10 not
-.....\TU/lmr/m/it/10 be
-.....\TU/lmr/m/it/10 merged,
-.....\TU/lmr/m/it/10 since
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 document
-.....\TU/lmr/m/it/10 is
-.....\TU/lmr/m/it/10 lineated
-.....\TU/lmr/m/it/10 per
-.....\TU/lmr/m/it/10 page.
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {vulgate-2
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 vulgate-6}
-.....\TU/lmtt/m/n/10 {vulgate-14
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 vulgate-18}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 edpageline
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 7
-......\TU/lmtt/m/n/7 3-11
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmr/m/it/10 1
+.....\TU/lmr/m/it/10 .
+.....\TU/lmr/m/it/10 T
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 y
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 ,
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 .
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 6
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 1
.....\TU/lmtt/m/n/10 8
-......\TU/lmtt/m/n/7 12-20
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 7
+......\TU/lmtt/m/n/7 3
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 1
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 8
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 2
+......\TU/lmtt/m/n/7 2
+......\TU/lmtt/m/n/7 0
.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 7
-......\TU/lmtt/m/n/7 3-11
-.....\TU/lmtt/m/n/10 and
+......\TU/lmtt/m/n/7 3
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 1
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 8
-......\TU/lmtt/m/n/7 12-20
-.....\TU/lmtt/m/n/10 ]
-....\TU/lmr/m/n/10 14
-.....\TU/lmr/m/it/10 Same
-.....\TU/lmr/m/it/10 as
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 above,
-.....\TU/lmr/m/it/10 but
-.....\TU/lmr/m/it/10 with
-.....\TU/lmtt/m/n/10 \crfnmEdlineNumberingContinuousAcrossDocument
-.....\TU/lmr/m/it/10 set
-.....\TU/lmr/m/it/10 to
-.....\TU/lmtt/m/n/10 yes
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 2
+......\TU/lmtt/m/n/7 2
+......\TU/lmtt/m/n/7 0
+.....\TU/lmtt/m/n/10 ]
+....\TU/lmr/m/n/10 1
+....\TU/lmr/m/n/10 4
+.....\TU/lmr/m/it/10 S
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 v
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 ,
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmtt/m/n/10 \
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 f
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 E
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 N
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 b
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 C
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 A
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 r
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 s
+.....\TU/lmtt/m/n/10 D
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 c
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 m
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 o
+.....\TU/lmtt/m/n/10 y
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 s
.....\TU/lmr/m/it/10 .
-.....\TU/lmr/m/it/10 We
-.....\TU/lmr/m/it/10 make
-.....\TU/lmr/m/n/10 crossrefenum
-.....\TU/lmr/m/it/10 believe
-.....\TU/lmr/m/it/10 that
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 first
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/it/10 ends
-.....\TU/lmr/m/it/10 at
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 end
-.....\TU/lmr/m/it/10 of
-.....\TU/lmr/m/it/10 a
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/it/10 and
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 second
-.....\TU/lmr/m/it/10 begins
-.....\TU/lmr/m/it/10 at
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 first
-.....\TU/lmr/m/it/10 line
-.....\TU/lmr/m/it/10 of
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 following
-.....\TU/lmr/m/it/10 page.
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {vulgate-2
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 vulgate-6}
-.....\TU/lmtt/m/n/10 {vulgate-14
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 vulgate-18}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 edpageline
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 7
+.....\TU/lmr/m/it/10 W
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 m
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 k
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 v
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 ï¬
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 ï¬
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 .
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 6
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 4
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 1
+.....\TU/lmtt/m/n/10 8
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 7
......\TU/lmtt/m/n/7 3
-.....\TU/lmtt/m/n/10 -8
-......\TU/lmtt/m/n/7 20
+.....\TU/lmtt/m/n/10 8
+......\TU/lmtt/m/n/7 2
+......\TU/lmtt/m/n/7 0
.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 7
......\TU/lmtt/m/n/7 3
-.....\TU/lmtt/m/n/10 -8
-......\TU/lmtt/m/n/7 20
+.....\TU/lmtt/m/n/10 8
+......\TU/lmtt/m/n/7 2
+......\TU/lmtt/m/n/7 0
.....\TU/lmtt/m/n/10 ]
.....\TU/lmr/m/it/10 A
-.....\TU/lmr/m/it/10 range
-.....\TU/lmr/m/it/10 of
-.....\TU/lmr/m/it/10 lines
-.....\TU/lmr/m/it/10 whose
-.....\TU/lmr/m/it/10 page
-.....\TU/lmr/m/it/10 boundaries
-.....\TU/lmr/m/it/10 are
-.....\TU/lmr/m/it/10 identical
-.....\TU/lmr/m/it/10 to
-.....\TU/lmr/m/it/10 those
-.....\TU/lmr/m/it/10 of
-.....\TU/lmr/m/it/10 the
-.....\TU/lmr/m/it/10 preceding
-.....\TU/lmr/m/it/10 and
-.....\TU/lmr/m/it/10 following
-.....\TU/lmr/m/it/10 references
-.....\TU/lmr/m/n/10 Enumeration:
-.....\TU/lmtt/m/n/10 {vulgate-3}
-.....\TU/lmtt/m/n/10 {vulgate-7
-.....\TU/lmtt/m/n/10 to
-.....\TU/lmtt/m/n/10 vulgate-20}
-.....\TU/lmtt/m/n/10 {vulgate-25}
-.....\TU/lmr/m/n/10 Reference
-.....\TU/lmr/m/n/10 type:
-.....\TU/lmtt/m/n/10 edpageline
-.....\TU/lmr/m/n/10 Expected:
-.....\TU/lmtt/m/n/10 [pp. 7
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 b
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 u
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 t
+.....\TU/lmr/m/it/10 h
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 p
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 a
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 d
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 l
+.....\TU/lmr/m/it/10 o
+.....\TU/lmr/m/it/10 w
+.....\TU/lmr/m/it/10 i
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 g
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 f
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 r
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 n
+.....\TU/lmr/m/it/10 c
+.....\TU/lmr/m/it/10 e
+.....\TU/lmr/m/it/10 s
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 m
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 a
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 i
+.....\TU/lmr/m/n/10 o
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 3
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 7
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 o
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 0
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmtt/m/n/10 {
+.....\TU/lmtt/m/n/10 v
+.....\TU/lmtt/m/n/10 u
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 t
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 2
+.....\TU/lmtt/m/n/10 5
+.....\TU/lmtt/m/n/10 }
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 f
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 r
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 n
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 y
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 d
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 g
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmtt/m/n/10 l
+.....\TU/lmtt/m/n/10 i
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 e
+.....\TU/lmr/m/n/10 E
+.....\TU/lmr/m/n/10 x
+.....\TU/lmr/m/n/10 p
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 c
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 d
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
+.....\TU/lmtt/m/n/10  
+.....\TU/lmtt/m/n/10 7
......\TU/lmtt/m/n/7 5
.....\TU/lmtt/m/n/10 ,
.....\TU/lmtt/m/n/10 7
-......\TU/lmtt/m/n/7 13
-.....\TU/lmtt/m/n/10 -9
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 3
+.....\TU/lmtt/m/n/10 9
......\TU/lmtt/m/n/7 5
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 9
-......\TU/lmtt/m/n/7 17
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 7
.....\TU/lmtt/m/n/10 ]
-.....\TU/lmr/m/n/10 Result:
-.....\TU/lmtt/m/n/10 [pp.
+.....\TU/lmr/m/n/10 R
+.....\TU/lmr/m/n/10 e
+.....\TU/lmr/m/n/10 s
+.....\TU/lmr/m/n/10 u
+.....\TU/lmr/m/n/10 l
+.....\TU/lmr/m/n/10 t
+.....\TU/lmr/m/n/10 :
+.....\TU/lmtt/m/n/10 [
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 p
+.....\TU/lmtt/m/n/10 .
.....\TU/lmtt/m/n/10 7
......\TU/lmtt/m/n/7 5
.....\TU/lmtt/m/n/10 ,
.....\TU/lmtt/m/n/10 7
-......\TU/lmtt/m/n/7 13
-.....\TU/lmtt/m/n/10 -9
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 3
+.....\TU/lmtt/m/n/10 9
......\TU/lmtt/m/n/7 5
-.....\TU/lmtt/m/n/10 and
+.....\TU/lmtt/m/n/10 a
+.....\TU/lmtt/m/n/10 n
+.....\TU/lmtt/m/n/10 d
.....\TU/lmtt/m/n/10 9
-......\TU/lmtt/m/n/7 17
+......\TU/lmtt/m/n/7 1
+......\TU/lmtt/m/n/7 7
.....\TU/lmtt/m/n/10 ]
-....\TU/lmr/m/n/10 15
+....\TU/lmr/m/n/10 1
+....\TU/lmr/m/n/10 5
diff --git a/macros/generic/crossrefenum/tex/crossrefenum.tex b/macros/generic/crossrefenum/tex/crossrefenum.tex
index 46196edece..81d991200a 100644
--- a/macros/generic/crossrefenum/tex/crossrefenum.tex
+++ b/macros/generic/crossrefenum/tex/crossrefenum.tex
@@ -2,10 +2,10 @@
\def\crfnmName{crossrefenum}
\def\crfnmShortDesc{Smart typesetting of enumerated cross-references for various TeX formats}
\def\crfnmAuthor{Bastien Dumont}
-\def\crfnmDate{2023/02/20}
-\def\crfnmVersion{1.0.2}
+\def\crfnmDate{2024/04/13}
+\def\crfnmVersion{1.1}
%
-% Copyright 2022-2023 by Bastien Dumont (bastien.dumont@posteo.net)
+% Copyright 2022-2024 by Bastien Dumont (bastien.dumont@posteo.net)
%
% crossrefenum.tex is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
@@ -472,8 +472,7 @@
\def\crfnm@newListFrom[#1][#2] -> #3{%
% #1 is either a list or a reference.
- % #2 is a reference.
- % #2 is appended to #1.
+ % #2 is the reference appended to #1.
% #3 is the control sequence which the resulting list will be bound to.
\crfnm@ifIsList[#1]{%
\edef#3{#1{#2}}%
@@ -481,6 +480,12 @@
\edef#3{{#1}{#2}}%
}%
}
+\def\crfnm@addToList[#1][#2]{\crfnm@newListFrom[#1][#2] -> #1}
+\def\crfnm@declareType[#1][#2]{%
+ % #1 is "simple" or "double", #2 is the type
+ \expandafter\crfnm@addToList\expandafter[\csname crfnm@#1RefTypes\endcsname][#2]%
+ \crfnm@addToList[\crfnm@supportedTypes][#2]%
+}
\def\crfnm@replaceFirstInList[#1]#2{%
% #1 is a token, #2 is a list of tokens
diff --git a/macros/generic/crossrefenum/tex/t-crossrefenum.tex b/macros/generic/crossrefenum/tex/t-crossrefenum.tex
index 9629faf04c..eec8042320 100644
--- a/macros/generic/crossrefenum/tex/t-crossrefenum.tex
+++ b/macros/generic/crossrefenum/tex/t-crossrefenum.tex
@@ -5,7 +5,7 @@
%D subtitle=Smart typesetting of enumerated cross-references for various TeX formats,
%D author=Bastien Dumont,
%D date=2022/11/11,
-%D url=%TODO,
+%D url=https://ctan.org/tex-archive/macros/generic/crossrefenum/tex/t-crossrefenum.tex,
%D copyright=Bastien Dumont,
%D license=GNU Public License v. 3.0 or higher]
diff --git a/macros/latex-dev/required/l3backend/CHANGELOG.md b/macros/latex-dev/required/l3backend/CHANGELOG.md
new file mode 100644
index 0000000000..ecd8593881
--- /dev/null
+++ b/macros/latex-dev/required/l3backend/CHANGELOG.md
@@ -0,0 +1,402 @@
+# Changelog
+All notable changes to the `l3backend` bundle will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+this project uses date-based 'snapshot' version identifiers.
+
+## [Unreleased]
+
+## [2024-04-11]
+
+### Added
+- Support for 'raw' PDF object IDs
+
+### Changed
+- Update PDF object management code
+
+## [2024-03-14]
+
+### Removed
+- Range guard for opacity
+
+### Fixed
+- Initiation of opacity data (see \#1472)
+- ExtGState setup for stroking opacity (issue \#1472)
+- Inconsistent behavior of opacity functions w/o `pdfmanagement`
+ (issue \#1473)
+- Redundant braces in opacity backend for dvisvgm
+- Interaction of scope with box insertion with `dvips` (see \#1504)
+
+## [2024-02-20]
+
+### Fixed
+- Naming of a variable in the `draw` code
+
+## [2024-01-04]
+
+### Changed
+- Documentation tweaks
+
+## [2023-11-09]
+
+### Changed
+- Changed `luaotfload` integration to allow coexistance with (x)color.
+
+## [2023-11-04]
+
+### Fixed
+- Interaction with `luaotfload` transparency colorstacks
+
+## [2023-10-23]
+
+### Changed
+- Update minimal `expl3` version required
+
+## [2023-10-10]
+
+### Changed
+- Track `expl3` changes
+
+## [2023-04-19]
+
+### Changed
+- Pass additional attributes when loading graphics in PDF mode
+
+### Fixed
+- Remove a stray `>` from graphics inclusion code for `dvipdfmx`
+
+## [2023-03-30]
+
+### Changed
+- Integrate `l3color` and `l3opacity` with `luaotfload` to ensure that
+ opacity specifications don't conflict
+
+## [2023-01-16]
+
+### Changed
+- Adjust internal scope of a PDF function
+
+## [2022-10-26]
+
+### Changed
+- Avoid setting media box if `\mag` is non-standard
+
+## [2022-09-28]
+
+### Changed
+- Add support for media box setting
+
+## [2022-08-30]
+
+### Added
+- Support for new approach to writing PDF objects
+
+## [2022-08-23]
+
+### Changed
+- Approach to setting current color data from LaTeX2e
+
+## [2022-08-05]
+
+### Changed
+- Add no-op backend functions for annotations with `dvisvgm`
+
+## [2022-07-01]
+
+#### Fixed
+- Do not include PDF file to count pages on pdfTeX
+- Opacity creation with `dvipdfmx`/XeTeX (issue [\#1106](https://github.com/latex3/latex3/issues/1106))
+- Reset opacity when no stack is available at the backend (issue [\#1107](https://github.com/latex3/latex3/issues/1107))
+
+## [2022-04-20]
+
+### Changed
+- Adjust `(x)dvipdfmx` backend approach to color following issues with
+ multiple color stacks in `xetex.def`
+- Move some functions to `l3color`
+
+## [2022-04-14]
+
+### Added
+- Support for SVG graphic inclusion by `dvisvgm`
+
+### Fixed
+- `\color_ensure_current:` backend with DVI-based routes (issue [\#1085](https://github.com/latex3/latex3/issues/1085))
+
+## [2022-04-10]
+
+### Added
+- Support for graphics (PDF) page count extraction
+
+### Fixed
+- Setup for graphics extension searching
+- Various internal issues in graphics inclusion
+- Some missing functions for `dvisvgm` color support added
+
+### Removed
+- Support for pre-2020-11-11 `dvipdfmx`
+
+## [2022-02-07]
+
+### Fixed
+- Use of color stack int in scope end for `(x)dvipdfmx`
+
+## [2022-01-12]
+
+### Changed
+- Move some functions to `l3color`
+
+## [2021-12-14]
+
+### Fixed
+- Scoping issues for `dvisvgm`
+- Some incorrect functions in `l3draw` backend for `dvisvgm`
+
+## [2021-10-17]
+
+### Changed
+- Better DeviceN support
+
+## [2021-10-12]
+
+### Fixed
+- Issues with creating DeviceN color spaces
+
+## [2021-08-04]
+
+### Changed
+- Only use `pdfmanagement` module if active
+
+## [2021-07-12]
+
+### Fixed
+- GoTo link formation for Distiller-based workflows (issue [\#957](https://github.com/latex3/latex3/issues/957))
+- Support transparency with Distiller
+
+## [2021-05-07]
+
+### Changed
+- `\pdf_version_gset:n` in `dvips` now sets `\pdf_version_minor:` and
+ `\pdf_version_major:`. This doesn't set the PDF version but allows to test
+ which version the user intents to create.
+
+## [2021-03-18]
+
+### Fixed
+- Maintain stack color correctly with `(x)dvipdfmx`
+
+## [2021-03-02]
+
+### Changed
+- Drop 'correction' for link placement in `(x)dvidpfmx`: no longer required
+- Define `\main@pdfcolorstack` for `(x)dvipdfmx` if it does not exist
+
+### Fixed
+- Initialisation of color stacks for `(x)dvipdfmx`
+
+## [2021-02-18]
+
+### Changed
+- Update tracking of PDF management functions
+
+### Fixed
+- Opacity support for pdfTeX/LuaTeX
+
+## [2021-02-06]
+
+### Changed
+- Use new (internal) interface for kerns
+
+## [2021-01-29]
+
+### Added
+- Basic opacity support
+
+### Changed
+- Use color stack for fill color, and for stroke color if possible
+
+### Fixed
+- Implementation of `filldraw` for `dvips`
+
+## [2021-01-09]
+
+### Added
+- Support for referencing last link with `(x)dvipdfmx` (requires an up-to-date
+ backend)
+
+### Changed
+- Implementation of color wtih (x)dvipdfmx (requires an up-to-date
+ backend)
+
+## [2020-09-24]
+
+### Fixed
+- Documented source as PDF
+
+## [2020-09-11]
+
+### Added
+- Support for CIELAB separations with `dvips`
+
+### Fixed
+- Some PDF object functions
+- Separation color selection for `dvipdfmx`/XeTeX
+- Logic for some aspects of CIELAB Separation color
+
+## [2020-09-01]
+
+### Changed
+- Improved support for Separation colors
+- Updated approach to `dvipdfmx`/XeTeX color support
+- Split `pdfmode` driver into pdfTeX- and LuaTeX-specific files
+- Renamed `xdvipdfmx` backend files to `xetex`
+
+## [2020-08-07]
+
+### Changed
+- Color selection implementation
+- Improved support for Separation colors
+
+## [2020-06-29]
+
+### Fixed
+- Loading with `dvisvgm`
+
+## [2020-06-23]
+
+### Changed
+- Improved color support for drawings with `dvisvgm`
+
+### Fixed
+- Loading with `dvisvgm`
+
+## [2020-06-18]
+
+### Changed
+- Use `scn` operator for separations
+- Internal color model
+- Internal performance enhancements
+
+## [2020-06-03]
+
+### Fixed
+- Unneeded `[nobreak]` in `dvips` driver (issue [\#709](https://github.com/latex3/latex3/issues/709))
+- `\__pdf_backend_object_write_fstream:nn` with `dvips` backend (issue [\#710](https://github.com/latex3/latex3/issues/710))
+- Array writing in `dvips` mode
+
+## [2020-05-05]
+
+### Added
+- `\__pdf_backend_pageobject_ref:n`
+
+### Changed
+- Extend PDF compression control to `dvips`
+
+## [2020-03-12]
+
+### Fixed
+- Creation of PDF annotations with `dvips` backend
+
+## [2020-02-23]
+
+### Fixed
+- Mismatch between release tag and CTAN version
+
+## [2020-02-21]
+
+### Added
+- Support for suppressing backend headers (see matching change in
+ `l3kernel`)
+
+## [2020-02-03]
+
+### Fixed
+- Corrected release string information
+
+## [2019-11-25]
+
+### Changed
+- Move dvips header material to `.pro` file
+
+## [2019-10-11]
+
+### Changed
+- Improved functionality in generic mode
+
+## [2019-09-05]
+
+### Added
+- Support for EPS and PDF files with `dvisvgm` backend
+
+### Fixed
+- Some primitive use in the `dvips` backend
+
+## [2019-08-25]
+
+### Fixed
+- Setting for PDF version in `dvipdfmx` route
+- Support for PDF objects with XeTeX
+
+## [2019-07-01]
+
+### Added
+- Driver support for anonymous objects
+
+### Changed
+- Moved backend code to separate release module `l3backend`
+- Include `l3backend` in file names
+- Moved backend code to internal for each 'parent' module
+
+[Unreleased]: https://github.com/latex3/latex3/compare/2024-04-11...HEAD
+[2024-04-11]: https://github.com/latex3/latex3/compare/2024-03-14...2024-04-11
+[2024-03-14]: https://github.com/latex3/latex3/compare/2024-02-20...2024-03-14
+[2024-02-20]: https://github.com/latex3/latex3/compare/2024-01-04...2024-02-20
+[2024-01-04]: https://github.com/latex3/latex3/compare/2023-11-09...2024-01-04
+[2023-11-09]: https://github.com/latex3/latex3/compare/2023-11-04...2023-11-09
+[2023-11-04]: https://github.com/latex3/latex3/compare/2023-10-23...2023-11-04
+[2023-10-23]: https://github.com/latex3/latex3/compare/2023-10-10...2023-10-23
+[2023-10-10]: https://github.com/latex3/latex3/compare/2023-04-19...2023-10-10
+[2023-04-19]: https://github.com/latex3/latex3/compare/2023-03-30...2023-04-19
+[2023-03-30]: https://github.com/latex3/latex3/compare/2023-01-16...2023-03-30
+[2023-01-16]: https://github.com/latex3/latex3/compare/2022-10-26...2023-01-16
+[2022-10-26]: https://github.com/latex3/latex3/compare/2022-09-28...2022-10-26
+[2022-09-28]: https://github.com/latex3/latex3/compare/2022-08-30...2022-09-28
+[2022-08-30]: https://github.com/latex3/latex3/compare/2022-08-23...2022-08-30
+[2022-08-23]: https://github.com/latex3/latex3/compare/2022-08-05...2022-08-23
+[2022-08-05]: https://github.com/latex3/latex3/compare/2022-07-01...2022-08-05
+[2022-07-01]: https://github.com/latex3/latex3/compare/2022-04-20...2022-07-01
+[2022-04-20]: https://github.com/latex3/latex3/compare/2022-04-14...2022-04-20
+[2022-04-14]: https://github.com/latex3/latex3/compare/2022-04-10...2022-04-14
+[2022-04-10]: https://github.com/latex3/latex3/compare/2022-02-07...2022-04-10
+[2022-02-07]: https://github.com/latex3/latex3/compare/2022-01-12...2022-02-07
+[2022-01-12]: https://github.com/latex3/latex3/compare/2021-12-14...2022-01-12
+[2021-12-14]: https://github.com/latex3/latex3/compare/2021-10-17...2021-12-14
+[2021-10-17]: https://github.com/latex3/latex3/compare/2021-10-12...2021-10-17
+[2021-10-12]: https://github.com/latex3/latex3/compare/2021-08-04...2021-10-12
+[2021-08-04]: https://github.com/latex3/latex3/compare/2021-07-12...2021-08-04
+[2021-07-12]: https://github.com/latex3/latex3/compare/2021-05-07...2021-07-12
+[2021-05-07]: https://github.com/latex3/latex3/compare/2021-03-18...2021-05-07
+[2021-03-18]: https://github.com/latex3/latex3/compare/2021-03-02...2021-03-18
+[2021-03-02]: https://github.com/latex3/latex3/compare/2021-02-18...2021-03-02
+[2021-02-18]: https://github.com/latex3/latex3/compare/2021-02-06...2021-02-18
+[2021-02-06]: https://github.com/latex3/latex3/compare/2021-01-29...2021-02-06
+[2021-01-29]: https://github.com/latex3/latex3/compare/2021-01-09...2021-01-29
+[2021-01-09]: https://github.com/latex3/latex3/compare/2020-09-24...2021-01-09
+[2020-09-24]: https://github.com/latex3/latex3/compare/2020-09-11...2020-09-24
+[2020-09-11]: https://github.com/latex3/latex3/compare/2020-09-01...2020-09-11
+[2020-09-01]: https://github.com/latex3/latex3/compare/2020-08-07...2020-09-01
+[2020-08-07]: https://github.com/latex3/latex3/compare/2020-06-29...2020-08-07
+[2020-06-29]: https://github.com/latex3/latex3/compare/2020-06-23...2020-06-29
+[2020-06-23]: https://github.com/latex3/latex3/compare/2020-06-18...2020-06-23
+[2020-06-18]: https://github.com/latex3/latex3/compare/2020-06-03...2020-06-18
+[2020-06-03]: https://github.com/latex3/latex3/compare/2020-05-05...2020-06-03
+[2020-05-05]: https://github.com/latex3/latex3/compare/2020-03-12...2020-05-05
+[2020-03-12]: https://github.com/latex3/latex3/compare/2020-02-23...2020-03-12
+[2020-02-23]: https://github.com/latex3/latex3/compare/2020-02-21...2020-02-23
+[2020-02-21]: https://github.com/latex3/latex3/compare/2020-02-03...2020-02-21
+[2020-02-03]: https://github.com/latex3/latex3/compare/2019-11-25...2020-02-03
+[2019-11-25]: https://github.com/latex3/latex3/compare/2019-10-11...2019-11-25
+[2019-10-11]: https://github.com/latex3/latex3/compare/2019-09-05...2019-10-11
+[2019-09-05]: https://github.com/latex3/latex3/compare/2019-08-25...2019-09-05
+[2019-08-25]: https://github.com/latex3/latex3/compare/2019-07-01...2019-08-25
+[2019-07-01]: https://github.com/latex3/latex3/compare/2019-05-28...2019-07-01
diff --git a/macros/latex-dev/required/l3backend/README.md b/macros/latex-dev/required/l3backend/README.md
new file mode 100644
index 0000000000..058fa63cc2
--- /dev/null
+++ b/macros/latex-dev/required/l3backend/README.md
@@ -0,0 +1,16 @@
+LaTeX3 Backend Drivers
+======================
+
+Release 2024-04-11
+
+This package forms parts of `expl3`, and contains the code used to interface
+with backends (drivers) across the `expl3` codebase. The functions here are
+defined differently depending on the engine in use. As such, these are
+distributed separately from `l3kernel` to allow this code to be updated
+on an independent schedule.
+
+-----
+
+<p>Copyright (C) 2019-2024 The LaTeX Project <br />
+<a href="http://latex-project.org/">http://latex-project.org/</a> <br />
+All rights reserved.</p>
diff --git a/macros/latex-dev/required/l3backend/l3backend-basics.dtx b/macros/latex-dev/required/l3backend/l3backend-basics.dtx
new file mode 100644
index 0000000000..fbac503317
--- /dev/null
+++ b/macros/latex-dev/required/l3backend/l3backend-basics.dtx
@@ -0,0 +1,497 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-basics.dtx
+%
+% Copyright (C) 2019-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3backend bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3backend-basics} module\\ Backend basics^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-basics} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% Whilst there is a reasonable amount of code overlap between backends,
+% it is much clearer to have the blocks more-or-less separated than run
+% in together and DocStripped out in parts. As such, most of the following
+% is set up on a per-backend basis, though there is some common code (again
+% given in blocks not interspersed with other material).
+%
+% All the file identifiers are up-front so that they come out in the right
+% place in the files.
+% \begin{macrocode}
+\ProvidesExplFile
+%<*dvipdfmx>
+ {l3backend-dvipdfmx.def}{2024-04-11}{}
+ {L3 backend support: dvipdfmx}
+%</dvipdfmx>
+%<*dvips>
+ {l3backend-dvips.def}{2024-04-11}{}
+ {L3 backend support: dvips}
+%</dvips>
+%<*dvisvgm>
+ {l3backend-dvisvgm.def}{2024-04-11}{}
+ {L3 backend support: dvisvgm}
+%</dvisvgm>
+%<*luatex>
+ {l3backend-luatex.def}{2024-04-11}{}
+ {L3 backend support: PDF output (LuaTeX)}
+%</luatex>
+%<*pdftex>
+ {l3backend-pdftex.def}{2024-04-11}{}
+ {L3 backend support: PDF output (pdfTeX)}
+%</pdftex>
+%<*xetex>
+ {l3backend-xetex.def}{2024-04-11}{}
+ {L3 backend support: XeTeX}
+%</xetex>
+% \end{macrocode}
+%
+% Check if the loaded kernel is at least enough to load this file.
+% The kernel date has to be at least equal to \cs{ExplBackendFileDate}
+% or later. If \cs{__kernel_dependency_version_check:Nn} doesn't
+% exist we're loading in an older kernel, so it's an error anyway.
+% With time, this test should vanish and only the dependency check
+% should remain.
+% \begin{macrocode}
+\cs_if_exist:NTF \__kernel_dependency_version_check:nn
+ {
+ \__kernel_dependency_version_check:nn {2023-10-10}
+%<dvipdfmx> {l3backend-dvipdfmx.def}
+%<dvips> {l3backend-dvips.def}
+%<dvisvgm> {l3backend-dvisvgm.def}
+%<luatex> {l3backend-luatex.def}
+%<pdftex> {l3backend-pdftex.def}
+%<xetex> {l3backend-xetex.def}
+ }
+ {
+ \cs_if_exist_use:cF { @latex@error } { \errmessage }
+ {
+ Mismatched~LaTeX~support~files~detected. \MessageBreak
+ Loading~aborted!
+ }
+ { \use:c { @ehd } }
+ \tex_endinput:D
+ }
+% \end{macrocode}
+%
+% The order of the backend code here is such that we get somewhat logical
+% outcomes in terms of code sharing whilst keeping things readable. (Trying to
+% mix all of the code by concept is almost unmanageable.) The key parts which
+% are shared are
+% \begin{itemize}
+% \item Color support is either \texttt{dvips}-like or \LuaTeX{}/pdfTeX{}-like.
+% \item \LuaTeX{}/pdfTeX{} and \texttt{dvipdfmx}/\XeTeX{} share drawing routines.
+% \item \XeTeX{} is the same as \texttt{dvipdfmx} other than image size
+% extraction so takes most of the same code.
+% \end{itemize}
+%
+% \begin{macro}
+% {
+% \__kernel_backend_literal:e,
+% \__kernel_backend_literal:n
+% }
+% The one shared function for all backends is access to the basic
+% \tn{special} primitive: it has slightly odd expansion behaviour
+% so a wrapper is provided.
+% \begin{macrocode}
+\cs_new_eq:NN \__kernel_backend_literal:e \tex_special:D
+\cs_new_protected:Npn \__kernel_backend_literal:n #1
+ { \__kernel_backend_literal:e { \exp_not:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_first_shipout:n}
+% We need to write at first shipout in a few places. As we want to use the
+% most up-to-date method,
+% \begin{macrocode}
+\cs_if_exist:NTF \@ifl@t@r
+ {
+ \@ifl@t@r \fmtversion { 2020-10-01 }
+ {
+ \cs_new_protected:Npn \__kernel_backend_first_shipout:n #1
+ { \hook_gput_code:nnn { shipout / firstpage } { l3backend } {#1} }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+ }
+ { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{\texttt{dvips} backend}
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}
+% {\__kernel_backend_literal_postscript:n, \__kernel_backend_literal_postscript:e}
+% Literal PostScript can be included using a few low-level formats. Here,
+% we use the form with no positioning: this is overall more convenient as
+% a wrapper. Note that this does require that where position is important,
+% an appropriate wrapper is included.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_literal_postscript:n #1
+ { \__kernel_backend_literal:n { ps:: #1 } }
+\cs_generate_variant:Nn \__kernel_backend_literal_postscript:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_postscript:n, \__kernel_backend_postscript:e}
+% PostScript data that does have positioning, and also applying
+% a shift to |SDict| (which is not done automatically by
+% |ps:| or |ps::|, in contrast to |!| or |"|).
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_postscript:n #1
+ { \__kernel_backend_literal:n { ps: SDict ~ begin ~ #1 ~ end } }
+\cs_generate_variant:Nn \__kernel_backend_postscript:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% PostScript for the header: a small saving but makes the code clearer.
+% This is held until the start of shipout such that a document with no
+% actual output does not write anything.
+% \begin{macrocode}
+\bool_if:NT \g__kernel_backend_header_bool
+ {
+ \__kernel_backend_first_shipout:n
+ { \__kernel_backend_literal:n { header = l3backend-dvips.pro } }
+ }
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \__kernel_backend_align_begin:,
+% \__kernel_backend_align_end:
+% }
+% In \texttt{dvips} there is no built-in saving of the current
+% position, and so some additional PostScript is required to set up the
+% transformation matrix and also to restore it afterwards. Notice the use
+% of the stack to save the current position \enquote{up front} and to
+% move back to it at the end of the process. Notice that the |[begin]|/^^A
+% |[end]| pair here mean that we can use a run of PostScript statements
+% in separate lines: not \emph{required} but does make the code and
+% output more clear.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_align_begin:
+ {
+ \__kernel_backend_literal:n { ps::[begin] }
+ \__kernel_backend_literal_postscript:n { currentpoint }
+ \__kernel_backend_literal_postscript:n { currentpoint~translate }
+ }
+\cs_new_protected:Npn \__kernel_backend_align_end:
+ {
+ \__kernel_backend_literal_postscript:n { neg~exch~neg~exch~translate }
+ \__kernel_backend_literal:n { ps::[end] }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_scope_begin:, \__kernel_backend_scope_end:}
+% Saving/restoring scope for general operations needs to be done with
+% \texttt{dvips} positioning (try without to see this!). Thus we need the
+% |ps:| version of the special here. As only the graphics state is ever
+% altered within this pairing, we use the lower-cost |g|-versions.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_scope_begin:
+ { \__kernel_backend_literal:n { ps:gsave } }
+\cs_new_protected:Npn \__kernel_backend_scope_end:
+ { \__kernel_backend_literal:n { ps:grestore } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \subsection{\LuaTeX{} and \pdfTeX{} backends}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% Both \LuaTeX{} and \pdfTeX{} write PDFs directly rather than via an
+% intermediate file. Although there are similarities, the move of \LuaTeX{}
+% to have more code in Lua means we create two independent files using
+% shared DocStrip code.
+%
+% \begin{macro}{\__kernel_backend_literal_pdf:n, \__kernel_backend_literal_pdf:e}
+% This is equivalent to \verb|\special{pdf:}| but the engine can
+% track it. Without the \texttt{direct} keyword everything is kept in
+% sync: the transformation matrix is set to the current point automatically.
+% Note that this is still inside the text (\texttt{BT} \dots \texttt{ET}
+% block).
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_literal_pdf:n #1
+ {
+%<*luatex>
+ \tex_pdfextension:D literal
+%</luatex>
+%<*pdftex>
+ \tex_pdfliteral:D
+%</pdftex>
+ { \exp_not:n {#1} }
+ }
+\cs_generate_variant:Nn \__kernel_backend_literal_pdf:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_literal_page:n, \__kernel_backend_literal_page:e}
+% Page literals are pretty simple. To avoid an expansion, we write out
+% by hand.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_literal_page:n #1
+ {
+%<*luatex>
+ \tex_pdfextension:D literal ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfliteral:D
+%</pdftex>
+ page { \exp_not:n {#1} }
+ }
+\cs_new_protected:Npn \__kernel_backend_literal_page:e #1
+ {
+%<*luatex>
+ \tex_pdfextension:D literal ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfliteral:D
+%</pdftex>
+ page {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_scope_begin:, \__kernel_backend_scope_end:}
+% Higher-level interfaces for saving and restoring the graphic state.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_scope_begin:
+ {
+%<*luatex>
+ \tex_pdfextension:D save \scan_stop:
+%</luatex>
+%<*pdftex>
+ \tex_pdfsave:D
+%</pdftex>
+ }
+\cs_new_protected:Npn \__kernel_backend_scope_end:
+ {
+%<*luatex>
+ \tex_pdfextension:D restore \scan_stop:
+%</luatex>
+%<*pdftex>
+ \tex_pdfrestore:D
+%</pdftex>
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_matrix:n, \__kernel_backend_matrix:e}
+% Here the appropriate function is set up to insert an affine matrix
+% into the PDF. With \pdfTeX{} and \LuaTeX{} in direct PDF output mode there
+% is a primitive for this, which only needs the rotation/scaling/skew part.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_matrix:n #1
+ {
+%<*luatex>
+ \tex_pdfextension:D setmatrix
+%</luatex>
+%<*pdftex>
+ \tex_pdfsetmatrix:D
+%</pdftex>
+ { \exp_not:n {#1} }
+ }
+\cs_generate_variant:Nn \__kernel_backend_matrix:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvipdfmx} backend}
+%
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+% \end{macrocode}
+%
+% The \texttt{dvipdfmx} shares code with the PDF mode one (using the common
+% section to this file) but also with \XeTeX{}. The latter is close
+% to identical to \texttt{dvipdfmx} and so all of the code here is extracted
+% for both backends, with some \texttt{clean up} for \XeTeX{} as
+% required.
+%
+% \begin{macro}{\__kernel_backend_literal_pdf:n, \__kernel_backend_literal_pdf:e}
+% Undocumented but equivalent to \pdfTeX{}'s |literal| keyword. It's similar to
+% be not the same as the documented |contents| keyword as that adds a |q|/|Q|
+% pair.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_literal_pdf:n #1
+ { \__kernel_backend_literal:n { pdf:literal~ #1 } }
+\cs_generate_variant:Nn \__kernel_backend_literal_pdf:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_literal_page:n}
+% Whilst the manual says this is like |literal direct| in \pdfTeX{},
+% it closes the |BT| block!
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_literal_page:n #1
+ { \__kernel_backend_literal:n { pdf:literal~direct~ #1 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_backend_scope_begin:, \__kernel_backend_scope_end:}
+% Scoping is done using the backend-specific specials. We use the versions
+% originally from \texttt{xdvidfpmx} (\texttt{x:}) as these are well-tested
+% \enquote{in the wild}.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_scope_begin:
+ { \__kernel_backend_literal:n { x:gsave } }
+\cs_new_protected:Npn \__kernel_backend_scope_end:
+ { \__kernel_backend_literal:n { x:grestore } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvisvgm} backend}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}{\__kernel_backend_literal_svg:n, \__kernel_backend_literal_svg:e}
+% Unlike the other backends, the requirements for making SVG files mean
+% that we can't conveniently transform all operations to the current point.
+% That makes life a bit more tricky later as that needs to be accounted for.
+% A new line is added after each call to help to keep the output readable
+% for debugging.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_literal_svg:n #1
+ { \__kernel_backend_literal:n { dvisvgm:raw~ #1 { ?nl } } }
+\cs_generate_variant:Nn \__kernel_backend_literal_svg:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g__kernel_backend_scope_int, \l__kernel_backend_scope_int}
+% In SVG, we need to track scope nesting as properties attach to scopes; that
+% requires a pair of \texttt{int} registers.
+% \begin{macrocode}
+\int_new:N \g__kernel_backend_scope_int
+\int_new:N \l__kernel_backend_scope_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\__kernel_backend_scope_begin:, \__kernel_backend_scope_end:}
+% \begin{macro}{\__kernel_backend_scope_begin:n, \__kernel_backend_scope_begin:e}
+% \begin{macro}{\__kernel_backend_scope:n, \__kernel_backend_scope:e}
+% In SVG, the need to attach concepts to a scope means we need to be sure we
+% will close all of the open scopes. That is easiest done if we only need
+% an outer \enquote{wrapper} \texttt{begin}/\texttt{end} pair, and within
+% that we apply operations as a simple scoped statements. To keep down the
+% non-productive groups, we also have a \texttt{begin} version that does take
+% an argument.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_backend_scope_begin:
+ {
+ \__kernel_backend_literal_svg:n { <g> }
+ \int_set_eq:NN
+ \l__kernel_backend_scope_int
+ \g__kernel_backend_scope_int
+ \group_begin:
+ \int_gset:Nn \g__kernel_backend_scope_int { 1 }
+ }
+\cs_new_protected:Npn \__kernel_backend_scope_end:
+ {
+ \prg_replicate:nn
+ { \g__kernel_backend_scope_int }
+ { \__kernel_backend_literal_svg:n { </g> } }
+ \group_end:
+ \int_gset_eq:NN
+ \g__kernel_backend_scope_int
+ \l__kernel_backend_scope_int
+ }
+\cs_new_protected:Npn \__kernel_backend_scope_begin:n #1
+ {
+ \__kernel_backend_literal_svg:n { <g ~ #1 > }
+ \int_set_eq:NN
+ \l__kernel_backend_scope_int
+ \g__kernel_backend_scope_int
+ \group_begin:
+ \int_gset:Nn \g__kernel_backend_scope_int { 1 }
+ }
+\cs_generate_variant:Nn \__kernel_backend_scope_begin:n { e }
+\cs_new_protected:Npn \__kernel_backend_scope:n #1
+ {
+ \__kernel_backend_literal_svg:n { <g ~ #1 > }
+ \int_gincr:N \g__kernel_backend_scope_int
+ }
+\cs_generate_variant:Nn \__kernel_backend_scope:n { e }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3backend/l3backend-box.dtx b/macros/latex-dev/required/l3backend/l3backend-box.dtx
new file mode 100644
index 0000000000..93d83293ef
--- /dev/null
+++ b/macros/latex-dev/required/l3backend/l3backend-box.dtx
@@ -0,0 +1,470 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-box.dtx
+%
+% Copyright (C) 2019-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3backend bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3backend-box} package\\ Backend box support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-box} implementation}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=box>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvips} backend}
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_clip:N}
+% The \texttt{dvips} backend scales all absolute dimensions based on the
+% output resolution selected and any \TeX{} magnification. Thus for any
+% operation involving absolute lengths there is a correction to make. See
+% \texttt{normalscale} from \texttt{special.pro} for the variables, noting
+% that here everything is saved on the stack rather than as a separate
+% variable. Once all of that is done, the actual clipping is trivial.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_clip:N #1
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_align_begin:
+ \__kernel_backend_literal_postscript:n { matrix~currentmatrix }
+ \__kernel_backend_literal_postscript:n
+ { Resolution~72~div~VResolution~72~div~scale }
+ \__kernel_backend_literal_postscript:n { DVImag~dup~scale }
+ \__kernel_backend_literal_postscript:e
+ {
+ 0 ~
+ \dim_to_decimal_in_bp:n { \box_dp:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~
+ \dim_to_decimal_in_bp:n { -\box_ht:N #1 - \box_dp:N #1 } ~
+ rectclip
+ }
+ \__kernel_backend_literal_postscript:n { setmatrix }
+ \__kernel_backend_align_end:
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ \skip_horizontal:n { \box_wd:N #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_rotate:Nn}
+% \begin{macro}{\@@_backend_rotate_aux:Nn}
+% Rotating using \texttt{dvips} does not require that the box dimensions
+% are altered and has a very convenient built-in operation. Zero rotation
+% must be written as |0| not |-0| so there is a quick test.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_rotate:Nn #1#2
+ { \exp_args:NNf \@@_backend_rotate_aux:Nn #1 { \fp_eval:n {#2} } }
+\cs_new_protected:Npn \@@_backend_rotate_aux:Nn #1#2
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_align_begin:
+ \__kernel_backend_literal_postscript:e
+ {
+ \fp_compare:nNnTF {#2} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( -(#2) , 5 ) } } ~
+ rotate
+ }
+ \__kernel_backend_align_end:
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_scale:Nnn}
+% The \texttt{dvips} backend once again has a dedicated operation we can
+% use here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_scale:Nnn #1#2#3
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_align_begin:
+ \__kernel_backend_literal_postscript:e
+ {
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ \fp_eval:n { round ( #3 , 5 ) } ~
+ scale
+ }
+ \__kernel_backend_align_end:
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \subsection{\LuaTeX{} and \pdfTeX{} backends}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_clip:N}
+% The general method is to save the current location, define a clipping path
+% equivalent to the bounding box, then insert the content at the current
+% position and in a zero width box. The \enquote{real} width is then made up
+% using a horizontal skip before tidying up. There are other approaches that
+% can be taken (for example using XForm objects), but the logic here shares
+% as much code as possible and uses the same conversions (and so same
+% rounding errors) in all cases.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_clip:N #1
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal_pdf:e
+ {
+ 0~
+ \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ re~W~n
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ \skip_horizontal:n { \box_wd:N #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_rotate:Nn}
+% \begin{macro}{\@@_backend_rotate_aux:Nn}
+% \begin{variable}{\l_@@_backend_cos_fp, \l_@@_backend_sin_fp}
+% Rotations are set using an affine transformation matrix which therefore
+% requires sine/cosine values not the angle itself. We store the rounded
+% values to avoid rounding twice. There are also a couple of comparisons to
+% ensure that |-0| is not written to the output, as this avoids any issues
+% with problematic display programs. Note that numbers are compared to~$0$
+% after rounding.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_rotate:Nn #1#2
+ { \exp_args:NNf \@@_backend_rotate_aux:Nn #1 { \fp_eval:n {#2} } }
+\cs_new_protected:Npn \@@_backend_rotate_aux:Nn #1#2
+ {
+ \__kernel_backend_scope_begin:
+ \box_set_wd:Nn #1 { 0pt }
+ \fp_set:Nn \l_@@_backend_cos_fp { round ( cosd ( #2 ) , 5 ) }
+ \fp_compare:nNnT \l_@@_backend_cos_fp = \c_zero_fp
+ { \fp_zero:N \l_@@_backend_cos_fp }
+ \fp_set:Nn \l_@@_backend_sin_fp { round ( sind ( #2 ) , 5 ) }
+ \__kernel_backend_matrix:e
+ {
+ \fp_use:N \l_@@_backend_cos_fp \c_space_tl
+ \fp_compare:nNnTF \l_@@_backend_sin_fp = \c_zero_fp
+ { 0~0 }
+ {
+ \fp_use:N \l_@@_backend_sin_fp
+ \c_space_tl
+ \fp_eval:n { -\l_@@_backend_sin_fp }
+ }
+ \c_space_tl
+ \fp_use:N \l_@@_backend_cos_fp
+ }
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+\fp_new:N \l_@@_backend_cos_fp
+\fp_new:N \l_@@_backend_sin_fp
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_scale:Nnn}
+% The same idea as for rotation but without the complexity of signs and
+% cosines.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_scale:Nnn #1#2#3
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_matrix:e
+ {
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ 0~0~
+ \fp_eval:n { round ( #3 , 5 ) }
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvipdfmx}/\XeTeX{} backend}
+%
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_clip:N}
+% The code here is identical to that for \LuaTeX{}/\pdfTeX{}: unlike rotation and
+% scaling, there is no higher-level support in the backend for clipping.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_clip:N #1
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal_pdf:e
+ {
+ 0~
+ \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~
+ \dim_to_decimal_in_bp:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ re~W~n
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ \skip_horizontal:n { \box_wd:N #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_rotate:Nn}
+% \begin{macro}{\@@_backend_rotate_aux:Nn}
+% Rotating in \texttt{dvipdmfx}/\XeTeX{} can be implemented using either PDF or
+% backend-specific code. The former approach however is not \enquote{aware}
+% of the content of boxes: this means that any embedded links would not be
+% adjusted by the rotation. As such, the backend-native approach is preferred:
+% the code therefore is similar (though not identical) to the \texttt{dvips}
+% version (notice the rotation angle here is positive). As for
+% \texttt{dvips}, zero rotation is written as |0| not |-0|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_rotate:Nn #1#2
+ { \exp_args:NNf \@@_backend_rotate_aux:Nn #1 { \fp_eval:n {#2} } }
+\cs_new_protected:Npn \@@_backend_rotate_aux:Nn #1#2
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal:e
+ {
+ x:rotate~
+ \fp_compare:nNnTF {#2} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( #2 , 5 ) } }
+ }
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_scale:Nnn}
+% Much the same idea for scaling: use the higher-level backend operation to allow
+% for box content.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_scale:Nnn #1#2#3
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_literal:e
+ {
+ x:scale~
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ \fp_eval:n { round ( #3 , 5 ) }
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvisvgm} backend}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_clip:N}
+% \begin{variable}{\g__kernel_clip_path_int}
+% Clipping in SVG is more involved than with other backends. The first issue
+% is that the clipping path must be defined separately from where it is used,
+% so we need to track how many paths have applied. The naming here uses
+% \texttt{l3cp} as the namespace with a number following. Rather than use
+% a rectangular operation, we define the path manually as this allows it to
+% have a depth: easier than the alternative approach of shifting content
+% up and down using scopes to allow for the depth of the \TeX{} box and
+% keep the reference point the same!
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_clip:N #1
+ {
+ \int_gincr:N \g__kernel_clip_path_int
+ \__kernel_backend_literal_svg:e
+ { < clipPath~id = " l3cp \int_use:N \g__kernel_clip_path_int " > }
+ \__kernel_backend_literal_svg:e
+ {
+ <
+ path ~ d =
+ "
+ M ~ 0 ~
+ \dim_to_decimal:n { -\box_dp:N #1 } ~
+ L ~ \dim_to_decimal:n { \box_wd:N #1 } ~
+ \dim_to_decimal:n { -\box_dp:N #1 } ~
+ L ~ \dim_to_decimal:n { \box_wd:N #1 } ~
+ \dim_to_decimal:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ L ~ 0 ~
+ \dim_to_decimal:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ Z
+ "
+ />
+ }
+ \__kernel_backend_literal_svg:n
+ { < /clipPath > }
+% \end{macrocode}
+% In general the SVG set up does not try to transform coordinates to the
+% current point. For clipping we need to do that, so have a transformation
+% here to get us to the right place, and a matching one just before the
+% \TeX{} box is inserted to get things back on track. The clip path needs to
+% come between those two such that if lines up with the current point, as
+% does the \TeX{} box.
+% \begin{macrocode}
+ \__kernel_backend_scope_begin:n
+ {
+ transform =
+ "
+ translate ( { ?x } , { ?y } ) ~
+ scale ( 1 , -1 )
+ "
+ }
+ \__kernel_backend_scope:e
+ {
+ clip-path =
+ "url ( \c_hash_str l3cp \int_use:N \g__kernel_clip_path_int ) "
+ }
+ \__kernel_backend_scope:n
+ {
+ transform =
+ "
+ scale ( -1 , 1 ) ~
+ translate ( { ?x } , { ?y } ) ~
+ scale ( -1 , -1 )
+ "
+ }
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+\int_new:N \g__kernel_clip_path_int
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_rotate:Nn}
+% Rotation has a dedicated operation which includes a centre-of-rotation
+% optional pair. That can be picked up from the backend syntax, so there is
+% no need to worry about the transformation matrix.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_rotate:Nn #1#2
+ {
+ \__kernel_backend_scope_begin:e
+ {
+ transform =
+ "
+ rotate
+ ( \fp_eval:n { round ( -(#2) , 5 ) } , ~ { ?x } , ~ { ?y } )
+ "
+ }
+ \box_use:N #1
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_scale:Nnn}
+% In contrast to rotation, we have to account for the current position in this
+% case. That is done using a couple of translations in addition to the scaling
+% (which is therefore done backward with a flip).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_scale:Nnn #1#2#3
+ {
+ \__kernel_backend_scope_begin:e
+ {
+ transform =
+ "
+ translate ( { ?x } , { ?y } ) ~
+ scale
+ (
+ \fp_eval:n { round ( -#2 , 5 ) } ,
+ \fp_eval:n { round ( -#3 , 5 ) }
+ ) ~
+ translate ( { ?x } , { ?y } ) ~
+ scale ( -1 )
+ "
+ }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3backend/l3backend-code.pdf b/macros/latex-dev/required/l3backend/l3backend-code.pdf
new file mode 100644
index 0000000000..acc3e33012
--- /dev/null
+++ b/macros/latex-dev/required/l3backend/l3backend-code.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3backend/l3backend-code.tex b/macros/latex-dev/required/l3backend/l3backend-code.tex
new file mode 100644
index 0000000000..df0dd0ea8c
--- /dev/null
+++ b/macros/latex-dev/required/l3backend/l3backend-code.tex
@@ -0,0 +1,63 @@
+\iffalse meta-comment
+
+File: l3backend-code.tex
+
+Copyright (C) 2019,2021 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this
+license or (at your option) any later version. The latest version
+of this license is in the file
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3backend bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+The released version of this bundle is available from CTAN.
+
+-----------------------------------------------------------------------
+
+The development version of the bundle can be found at
+
+ https://github.com/latex3/latex3
+
+for those people who are interested.
+
+\fi
+
+\documentclass[full,kernel]{l3doc}
+
+\begin{document}
+
+\makeatletter
+\let\DelayPrintIndex\PrintIndex
+\let\PrintIndex\@empty
+\makeatother
+
+\ExplSyntaxOn
+\clist_gput_right:Nn \g_docinput_clist
+ {
+ l3backend-basics.dtx ,
+ l3backend-box.dtx ,
+ l3backend-color.dtx ,
+ l3backend-draw.dtx ,
+ l3backend-graphics.dtx ,
+ l3backend-pdf.dtx ,
+ l3backend-opacity.dtx ,
+ l3backend-header.dtx
+ }
+\ExplSyntaxOff
+
+\part{Implementation}
+
+\def\maketitle{}
+\EnableImplementation
+\DisableDocumentation
+\DocInputAgain
+
+\clearpage
+
+\DelayPrintIndex
+
+\end{document}
diff --git a/macros/latex-dev/required/l3backend/l3backend-color.dtx b/macros/latex-dev/required/l3backend/l3backend-color.dtx
new file mode 100644
index 0000000000..307432d554
--- /dev/null
+++ b/macros/latex-dev/required/l3backend/l3backend-color.dtx
@@ -0,0 +1,1356 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-color.dtx
+%
+% Copyright (C) 2019-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3backend bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3backend-color} module\\ Backend color support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-color} implementation}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=color>
+% \end{macrocode}
+%
+% Color support is split into parts: collecting data from \LaTeXe{}, the color
+% stack, general color, separations, and color for drawings. We have different
+% approaches in each backend, and have some choices to make about
+% \texttt{dvipdfmx}/\XeTeX{} in particular. Whilst it is in some ways
+% convenient to use the same approach in multiple backends, the fact that
+% \texttt{dvipdfmx}/\XeTeX{} is PDF-based means it (largely) sticks closer to
+% direct PDF output.
+%
+% \subsection{The color stack}
+%
+% For PDF-based engines, we have a color stack available inside the specials.
+% This is used for concepts beyond color itself: it is needed to manage the
+% graphics state generally. Although \texttt{dvipdfmx}/\XeTeX{} have multiple
+% color stacks in recent releases, the way these interact with the original
+% single stack and with other graphic state operations means that currently it
+% is not feasible to use the multiple stacks.
+%
+% \subsubsection{Common code}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \begin{variable}{\l_@@_backend_stack_int}
+% For tracking which stack is in use where multiple stacks are used:
+% currently just \pdfTeX{}/\LuaTeX{} but at some future stage may also cover
+% \texttt{dvipdfmx}/\XeTeX{}.
+% \begin{macrocode}
+\int_new:N \l_@@_backend_stack_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \subsubsection{\LuaTeX and \pdfTeX{}}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \begin{macro}{\__kernel_color_backend_stack_init:Nnn}
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_color_backend_stack_init:Nnn #1#2#3
+ {
+ \int_const:Nn #1
+ {
+%<*luatex>
+ \tex_pdffeedback:D colorstackinit ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfcolorstackinit:D
+%</pdftex>
+ \tl_if_blank:nF {#2} { #2 ~ }
+ {#3}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_color_backend_stack_push:nn}
+% \begin{macro}{\__kernel_color_backend_stack_pop:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2
+ {
+%<*luatex>
+ \tex_pdfextension:D colorstack ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfcolorstack:D
+%</pdftex>
+ \int_eval:n {#1} ~ push ~ {#2}
+ }
+\cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1
+ {
+%<*luatex>
+ \tex_pdfextension:D colorstack ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfcolorstack:D
+%</pdftex>
+ \int_eval:n {#1} ~ pop \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \subsection{General color}
+%
+% \subsubsection{\texttt{dvips}-style}
+%
+% \begin{macrocode}
+%<*dvips|dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_select_cmyk:n ,
+% \@@_backend_select_gray:n ,
+% \@@_backend_select_named:n ,
+% \@@_backend_select_rgb:n ,
+% \@@_backend_select:n
+% }
+% \begin{macro}{\@@_backend_reset:}
+% Push the data to the stack. In the case of \texttt{dvips} also saves the
+% drawing color in raw PostScript. The |spot| model is for handling data
+% in classical format.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_cmyk:n #1
+ { \@@_backend_select:n { cmyk ~ #1 } }
+\cs_new_protected:Npn \@@_backend_select_gray:n #1
+ { \@@_backend_select:n { gray ~ #1 } }
+\cs_new_protected:Npn \@@_backend_select_named:n #1
+ { \@@_backend_select:n { ~ #1 } }
+\cs_new_protected:Npn \@@_backend_select_rgb:n #1
+ { \@@_backend_select:n { rgb ~ #1 } }
+\cs_new_protected:Npn \@@_backend_select:n #1
+ {
+ \__kernel_backend_literal:n { color~push~ #1 }
+%<*dvips>
+ \__kernel_backend_postscript:n { /color.sc ~ { } ~ def }
+%</dvips>
+ }
+\cs_new_protected:Npn \@@_backend_reset:
+ { \__kernel_backend_literal:n { color~pop } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips|dvisvgm>
+% \end{macrocode}
+%
+% \subsubsection{\LuaTeX{} and \pdfTeX{}}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \begin{variable}{\l_@@_backend_fill_tl, \l_@@_backend_stroke_tl}
+% \begin{macrocode}
+\tl_new:N \l_@@_backend_fill_tl
+\tl_new:N \l_@@_backend_stroke_tl
+\tl_set:Nn \l_@@_backend_fill_tl { 0 ~ g }
+\tl_set:Nn \l_@@_backend_stroke_tl { 0 ~ G }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \@@_backend_select_cmyk:n ,
+% \@@_backend_select_gray:n ,
+% \@@_backend_select_rgb:n
+% }
+% \begin{macro}{\@@_backend_select:nn}
+% \begin{macro}{\@@_backend_reset:}
+% Store the values then pass to the stack.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_cmyk:n #1
+ { \@@_backend_select:nn { #1 ~ k } { #1 ~ K } }
+\cs_new_protected:Npn \@@_backend_select_gray:n #1
+ { \@@_backend_select:nn { #1 ~ g } { #1 ~ G } }
+\cs_new_protected:Npn \@@_backend_select_rgb:n #1
+ { \@@_backend_select:nn { #1 ~ rg } { #1 ~ RG } }
+\cs_new_protected:Npn \@@_backend_select:nn #1#2
+ {
+ \tl_set:Nn \l_@@_backend_fill_tl {#1}
+ \tl_set:Nn \l_@@_backend_stroke_tl {#2}
+ \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int { #1 ~ #2 }
+ }
+\cs_new_protected:Npn \@@_backend_reset:
+ { \__kernel_color_backend_stack_pop:n \l_@@_backend_stack_int }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \subsubsection{\texttt{dvipmdfx}/\XeTeX{}}
+%
+% These backends have the most possible approaches: it recognises both
+% \texttt{dvips}-based color specials and its own format, plus one can
+% include PDF statements directly. Recent releases also have a color stack
+% approach similar to \pdfTeX{}. Of the stack methods, the dedicated
+% the most versatile is the latter as it can cover all of the use cases
+% we have. However, at present this interacts problematically with any color
+% on the original stack. We therefore stick to a single-stack approach here.
+%
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_select:n ,
+% \@@_backend_select_cmyk:n ,
+% \@@_backend_select_gray:n ,
+% \@@_backend_select_rgb:n
+% }
+% \begin{macro}{\@@_backend_reset:}
+% Using the single stack is relatively easy as there is only one route.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select:n #1
+ { \__kernel_backend_literal:n { pdf : bc ~ [ #1 ] } }
+\cs_new_eq:NN \@@_backend_select_cmyk:n \@@_backend_select:n
+\cs_new_eq:NN \@@_backend_select_gray:n \@@_backend_select:n
+\cs_new_eq:NN \@@_backend_select_rgb:n \@@_backend_select:n
+\cs_new_protected:Npn \@@_backend_reset:
+ { \__kernel_backend_literal:n { pdf : ec } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_select_named:n}
+% For classical named colors, the only value we should get is |Black|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_named:n #1
+ {
+ \str_if_eq:nnTF {#1} { Black }
+ { \@@_backend_select_gray:n { 0 } }
+ { \msg_error:nnn { color } { unknown-named-color } {#1} }
+ }
+\msg_new:nnn { color } { unknown-named-color }
+ { Named~color~'#1'~is~not~known. }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \subsection{Separations}
+%
+% Here, life gets interesting and we need essentially one approach per
+% backend.
+%
+% \begin{macrocode}
+%<*dvipdfmx|luatex|pdftex|xetex|dvips>
+% \end{macrocode}
+%
+% But we start with some functionality needed for both PostScript and
+% PDF based backends.
+%
+% \begin{variable}{\g_@@_backend_colorant_prop}
+% \begin{macrocode}
+\prop_new:N \g_@@_backend_colorant_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_backend_devicen_colorants:n}
+% \begin{macro}[EXP]{\@@_backend_devicen_colorants:w}
+% \begin{macrocode}
+\cs_new:Npe \@@_backend_devicen_colorants:n #1
+ {
+ \exp_not:N \tl_if_blank:nF {#1}
+ {
+ \c_space_tl
+ << ~
+ /Colorants ~
+ << ~
+ \exp_not:N \@@_backend_devicen_colorants:w #1 ~
+ \exp_not:N \q_recursion_tail \c_space_tl
+ \exp_not:N \q_recursion_stop
+ >> ~
+ >>
+ }
+ }
+\cs_new:Npn \@@_backend_devicen_colorants:w #1 ~
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ \prop_if_in:NnT \g_@@_backend_colorant_prop {#1}
+ {
+ #1 ~
+ \prop_item:Nn \g_@@_backend_colorant_prop {#1} ~
+ }
+ \@@_backend_devicen_colorants:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|luatex|pdftex|xetex|dvips>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_select_separation:nn, \@@_backend_select_devicen:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2
+ { \@@_backend_select:n { separation ~ #1 ~ #2 } }
+\cs_new_eq:NN \@@_backend_select_devicen:nn \@@_backend_select_separation:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_select_iccbased:nn}
+% No support.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_iccbased:nn #1#2 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_separation_init:nnnnn,
+% \@@_backend_separation_init:neenn
+% }
+% \begin{macro}
+% {\@@_backend_separation_init_aux:nnnnnn}
+% \begin{macro}[EXP]
+% {
+% \@@_backend_separation_init_/DeviceCMYK:nnn ,
+% \@@_backend_separation_init_/DeviceGray:nnn ,
+% \@@_backend_separation_init_/DeviceRGB:nnn
+% }
+% \begin{macro}[EXP]{\@@_backend_separation_init_Device:Nn}
+% \begin{macro}[EXP]{\@@_backend_separation_init:nnn}
+% \begin{macro}[EXP]{\@@_backend_separation_init_count:n}
+% \begin{macro}[EXP]{\@@_backend_separation_init_count:w}
+% \begin{macro}[EXP]{\@@_backend_separation_init:nnnn}
+% \begin{macro}[EXP]{\@@_backend_separation_init:w}
+% \begin{macro}[EXP]{\@@_backend_separation_init:n}
+% \begin{macro}[EXP]{\@@_backend_separation_init:nw}
+% \begin{macro}{\@@_backend_separation_init_CIELAB:nnn}
+% Initialising here means creating a small header set up plus massaging
+% some data. This comes about as we have to deal with PDF-focussed data,
+% which makes most sense \enquote{higher-up}. The approach is based on
+% ideas from \url{https://tex.stackexchange.com/q/560093} plus using
+% the PostScript manual for other aspects.
+% \begin{macrocode}
+\cs_new_protected:Npe \@@_backend_separation_init:nnnnn #1#2#3#4#5
+ {
+ \bool_if:NT \g__kernel_backend_header_bool
+ {
+ \exp_not:N \exp_args:Ne \__kernel_backend_first_shipout:n
+ {
+ \exp_not:N \@@_backend_separation_init_aux:nnnnnn
+ { \exp_not:N \int_use:N \g_@@_model_int }
+ {#1} {#2} {#3} {#4} {#5}
+ }
+ \prop_gput:Nee \exp_not:N \g_@@_backend_colorant_prop
+ { / \exp_not:N \str_convert_pdfname:n {#1} }
+ {
+ << ~
+ /setcolorspace ~ {} ~
+ >> ~ begin ~
+ color \exp_not:N \int_use:N \g_@@_model_int \c_space_tl
+ end
+ }
+ }
+ }
+\cs_generate_variant:Nn \@@_backend_separation_init:nnnnn { nee }
+\cs_new_protected:Npn \@@_backend_separation_init_aux:nnnnnn #1#2#3#4#5#6
+ {
+ \__kernel_backend_literal:e
+ {
+ !
+ TeXDict ~ begin ~
+ /color #1
+ {
+ [ ~
+ /Separation ~ ( \str_convert_pdfname:n {#2} ) ~
+ [ ~ #3 ~ ] ~
+ {
+ \cs_if_exist_use:cF { @@_backend_separation_init_ #3 :nnn }
+ { \@@_backend_separation_init:nnn }
+ {#4} {#5} {#6}
+ }
+ ] ~ setcolorspace
+ } ~ def ~
+ end
+ }
+ }
+\cs_new:cpn { @@_backend_separation_init_ /DeviceCMYK :nnn } #1#2#3
+ { \@@_backend_separation_init_Device:Nn 4 {#3} }
+\cs_new:cpn { @@_backend_separation_init_ /DeviceGray :nnn } #1#2#3
+ { \@@_backend_separation_init_Device:Nn 1 {#3} }
+\cs_new:cpn { @@_backend_separation_init_ /DeviceRGB :nnn } #1#2#3
+ { \@@_backend_separation_init_Device:Nn 2 {#3} }
+\cs_new:Npn \@@_backend_separation_init_Device:Nn #1#2
+ {
+ #2 ~
+ \prg_replicate:nn {#1}
+ { #1 ~ index ~ mul ~ #1 ~ 1 ~ roll ~ }
+ \int_eval:n { #1 + 1 } ~ -1 ~ roll ~ pop
+ }
+% \end{macrocode}
+% For the generic case, we cannot use |/FunctionType 2| unfortunately, so
+% we have to code that idea up in PostScript. Here, we will therefore assume
+% that a range is \emph{always} given. First, we count values in each argument:
+% at the backend level, we can assume there are always well-behaved with
+% spaces present.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_separation_init:nnn #1#2#3
+ {
+ \exp_args:Ne \@@_backend_separation_init:nnnn
+ { \@@_backend_separation_init_count:n {#2} }
+ {#1} {#2} {#3}
+ }
+\cs_new:Npn \@@_backend_separation_init_count:n #1
+ { \int_eval:n { 0 \@@_backend_separation_init_count:w #1 ~ \s_@@_stop } }
+\cs_new:Npn \@@_backend_separation_init_count:w #1 ~ #2 \s_@@_stop
+ {
+ +1
+ \tl_if_blank:nF {#2}
+ { \@@_backend_separation_init_count:w #2 \s_@@_stop }
+ }
+% \end{macrocode}
+% Now we implement the algorithm. In the terms in the PostScript manual,
+% we have $\mathbf{N} = 1$ and $\mathbf{Domain} = [0~1]$, with
+% $\mathbf{Range}$ as |#2|, $\mathbf{C0}$ as |#3| and $\mathbf{C1}$
+% as |#4|, with the number of output components in |#1|. So all we have
+% to do is implement $y_{i} = \mathbf{C0}_{i} + x(\mathbf{C1}_{i} -
+% \mathbf{C0}_{i})$ with lots of stack manipulation, then check the
+% ranges. That's done by adding everything to the stack first, then using
+% the fact we know all of the offsets. As manipulating the stack is tricky,
+% we start by re-formatting the $\mathbf{C0}$ and $\mathbf{C1}$ arrays to
+% be interleaved, and add a \texttt{0} to each pair: this is used
+% to keep the stack of constant length while we are doing the first pass of
+% mathematics. We then working through that list, calculating from the
+% last to the first value before tidying up by removing all of the input
+% values. We do that by first copying all of the final $y$ values to the
+% end of the stack, then rolling everything so we can pop the now-unneeded
+% material.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_separation_init:nnnn #1#2#3#4
+ {
+ \@@_backend_separation_init:w #3 ~ \s_@@_stop #4 ~ \s_@@_stop
+ \prg_replicate:nn {#1}
+ {
+ pop ~ 1 ~ index ~ neg ~ 1 ~ index ~ add ~
+ \int_eval:n { 3 * #1 } ~ index ~ mul ~
+ 2 ~ index ~ add ~
+ \int_eval:n { 3 * #1 } ~ #1 ~ roll ~
+ }
+ \int_step_function:nnnN {#1} { -1 } { 1 }
+ \@@_backend_separation_init:n
+ \int_eval:n { 4 * #1 + 1 } ~ #1 ~ roll ~
+ \prg_replicate:nn { 3 * #1 + 1 } { pop ~ }
+ \tl_if_blank:nF {#2}
+ { \@@_backend_separation_init:nw {#1} #2 ~ \s_@@_stop }
+ }
+\cs_new:Npn \@@_backend_separation_init:w
+ #1 ~ #2 \s_@@_stop #3 ~ #4 \s_@@_stop
+ {
+ #1 ~ #3 ~ 0 ~
+ \tl_if_blank:nF {#2}
+ { \@@_backend_separation_init:w #2 \s_@@_stop #4 \s_@@_stop }
+ }
+\cs_new:Npn \@@_backend_separation_init:n #1
+ { \int_eval:n { #1 * 2 } ~ index ~ }
+% \end{macrocode}
+% Finally, we deal with the range limit if required. This is handled
+% by splitting the range into pairs. It's then just a question of doing
+% the comparisons, this time dropping everything except the desired
+% result.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_separation_init:nw #1#2 ~ #3 ~ #4 \s_@@_stop
+ {
+ #2 ~ #3 ~
+ 2 ~ index ~ 2 ~ index ~ lt ~
+ { ~ pop ~ exch ~ pop ~ } ~
+ { ~
+ 2 ~ index ~ 1 ~ index ~ gt ~
+ { ~ exch ~ pop ~ exch ~ pop ~ } ~
+ { ~ pop ~ pop ~ } ~
+ ifelse ~
+ }
+ ifelse ~
+ #1 ~ 1 ~ roll ~
+ \tl_if_blank:nF {#4}
+ { \@@_backend_separation_init:nw {#1} #4 \s_@@_stop }
+ }
+% \end{macrocode}
+% CIELAB support uses the detail from the PostScript reference, page 227;
+% other than that block of PostScript, this is the same as for PDF-based
+% routes.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_separation_init_CIELAB:nnn #1#2#3
+ {
+ \@@_backend_separation_init:neenn
+ {#2}
+ {
+ /CIEBasedABC ~
+ << ~
+ /RangeABC ~ [ ~ \c_@@_model_range_CIELAB_tl \c_space_tl ] ~
+ /DecodeABC ~
+ [ ~
+ { ~ 16 ~ add ~ 116 ~ div ~ } ~ bind ~
+ { ~ 500 ~ div ~ } ~ bind ~
+ { ~ 200 ~ div ~ } ~ bind ~
+ ] ~
+ /MatrixABC ~ [ ~ 1 ~ 1 ~ 1 ~ 1 ~ 0 ~ 0 ~ 0 ~ 0 ~ -1 ~ ] ~
+ /DecodeLMN ~
+ [ ~
+ { ~
+ dup ~ 6 ~ 29 ~ div ~ ge ~
+ { ~ dup ~ dup ~ mul ~ mul ~ ~ } ~
+ { ~ 4 ~ 29 ~ div ~ sub ~ 108 ~ 841 ~ div ~ mul ~ } ~
+ ifelse ~
+ 0.9505 ~ mul ~
+ } ~ bind ~
+ { ~
+ dup ~ 6 ~ 29 ~ div ~ ge ~
+ { ~ dup ~ dup ~ mul ~ mul ~ } ~
+ { ~ 4 ~ 29 ~ div ~ sub ~ 108 ~ 841 ~ div ~ mul ~ } ~
+ ifelse ~
+ } ~ bind ~
+ { ~
+ dup ~ 6 ~ 29 ~ div ~ ge ~
+ { ~ dup ~ dup ~ mul ~ mul ~ } ~
+ { ~ 4 ~ 29 ~ div ~ sub ~ 108 ~ 841 ~ div ~ mul ~ } ~
+ ifelse ~
+ 1.0890 ~ mul ~
+ } ~ bind
+ ] ~
+ /WhitePoint ~
+ [ ~ \tl_use:c { c_@@_model_whitepoint_CIELAB_ #1 _tl } ~ ] ~
+ >>
+ }
+ { \c_@@_model_range_CIELAB_tl }
+ { 100 ~ 0 ~ 0 }
+ {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_devicen_init:nnn}
+% Trivial as almost all of the work occurs in the shared code.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_devicen_init:nnn #1#2#3
+ {
+ \__kernel_backend_literal:e
+ {
+ !
+ TeXDict ~ begin ~
+ /color \int_use:N \g_@@_model_int
+ {
+ [ ~
+ /DeviceN ~
+ [ ~ #1 ~ ] ~
+ #2 ~
+ { ~ #3 ~ } ~
+ \@@_backend_devicen_colorants:n {#1}
+ ] ~ setcolorspace
+ } ~ def ~
+ end
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_iccbased_init:nnn}
+% No support at present.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_iccbased_init:nnn #1#2#3 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_select_separation:nn,
+% \@@_backend_select_devicen:nn
+% }
+% No support at present.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2 { }
+\cs_new_eq:NN \@@_backend_select_devicen:nn \@@_backend_select_separation:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_backend_separation_init:nnnnn, \@@_backend_separation_init_CIELAB:nnn}
+% No support at present.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_separation_init:nnnnn #1#2#3#4#5 { }
+\cs_new_protected:Npn \@@_backend_separation_init_CIELAB:nnnnnn #1#2#3 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_select_iccbased:nn}
+% As detailed in \url{https://www.w3.org/TR/css-color-4/#at-profile},
+% we can apply a color profile using CSS. As we have a local file, we use
+% a relative URL.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_iccbased:nn #1#2
+ {
+ \__kernel_backend_literal_svg:e
+ {
+ <style>
+ @color-profile ~
+ \str_if_eq:nnTF {#2} { cmyk }
+ { device-cmyk }
+ { --color \int_use:N \g_@@_model_int }
+ \c_space_tl
+ {
+ src:("#1")
+ }
+ </style>
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvipdfmx|luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_select_separation:nn,
+% \@@_backend_select_devicen:nn ,
+% \@@_backend_select_iccbased:nn
+% }
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2
+ { \__kernel_backend_literal:e { pdf : bc ~ \pdf_object_ref:n {#1} ~ [ #2 ] } }
+%</dvipdfmx|xetex>
+%<*luatex|pdftex>
+\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2
+ { \@@_backend_select:nn { /#1 ~ cs ~ #2 ~ scn } { /#1 ~ CS ~ #2 ~ SCN } }
+%</luatex|pdftex>
+\cs_new_eq:NN \@@_backend_select_devicen:nn \@@_backend_select_separation:nn
+\cs_new_eq:NN \@@_backend_select_iccbased:nn \@@_backend_select_separation:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_init_resource:n}
+% Resource initiation comes up a few times. For \texttt{dvipdfmx}/\XeTeX{},
+% we skip this as at present it's handled by the backend.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_init_resource:n #1
+ {
+%<*luatex|pdftex>
+ \bool_lazy_and:nnT
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+ \use:e
+ {
+ \pdfmanagement_add:nnn
+ { Page / Resources / ColorSpace }
+ { #1 }
+ { \pdf_object_ref_last: }
+ }
+ }
+%</luatex|pdftex>
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_separation_init:nnnnn}
+% \begin{macro}{\@@_backend_separation_init:nn}
+% \begin{macro}{\@@_backend_separation_init_CIELAB:nnn}
+% Initialising the PDF structures needs two parts: creating an object
+% containing the \enquote{real} name of the Separation, then adding a reference
+% to that to each page. We use a separate object for the tint transformation
+% following the model in the PDF reference. The object here for the color
+% needs to be named as that way it's accessible to
+% \texttt{dvipdfmx}/\XeTeX{}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_separation_init:nnnnn #1#2#3#4#5
+ {
+ \pdf_object_unnamed_write:ne { dict }
+ {
+ /FunctionType ~ 2
+ /Domain ~ [0 ~ 1]
+ \tl_if_blank:nF {#3} { /Range ~ [#3] }
+ /C0 ~ [#4] ~
+ /C1 ~ [#5] /N ~ 1
+ }
+ \exp_args:Ne \@@_backend_separation_init:nn
+ { \str_convert_pdfname:n {#1} } {#2}
+ \@@_backend_init_resource:n { color \int_use:N \g_@@_model_int }
+ }
+\cs_new_protected:Npn \@@_backend_separation_init:nn #1#2
+ {
+ \use:e
+ {
+ \pdf_object_new:n { color \int_use:N \g_@@_model_int }
+ \pdf_object_write:nnn { color \int_use:N \g_@@_model_int } { array }
+ { /Separation /#1 ~ #2 ~ \pdf_object_ref_last: }
+ }
+ \prop_gput:Nne \g_@@_backend_colorant_prop { /#1 }
+ { \pdf_object_ref_last: }
+ }
+% \end{macrocode}
+% For CIELAB colors, we need one object per document for the illuminant,
+% plus initialisation of the color space referencing that object.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_separation_init_CIELAB:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { @@_illuminant_CIELAB_ #1 }
+ {
+ \pdf_object_new:n { @@_illuminant_CIELAB_ #1 }
+ \pdf_object_write:nne { @@_illuminant_CIELAB_ #1 } { array }
+ {
+ /Lab ~
+ <<
+ /WhitePoint ~
+ [ \tl_use:c { c_@@_model_whitepoint_CIELAB_ #1 _tl } ]
+ /Range ~ [ \c_@@_model_range_CIELAB_tl ]
+ >>
+ }
+ }
+ \@@_backend_separation_init:nnnnn
+ {#2}
+ { \pdf_object_ref:n { @@_illuminant_CIELAB_ #1 } }
+ { \c_@@_model_range_CIELAB_tl }
+ { 100 ~ 0 ~ 0 }
+ {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_devicen_init:nnn}
+% \begin{macro}[EXP]{\@@_backend_devicen_init:w}
+% Similar to the Separations case, but with an arbitrary function for
+% the alternative space work.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_devicen_init:nnn #1#2#3
+ {
+ \pdf_object_unnamed_write:ne { stream }
+ {
+ {
+ /FunctionType ~ 4 ~
+ /Domain ~
+ [ ~
+ \prg_replicate:nn
+ { 0 \@@_backend_devicen_init:w #1 ~ \s_@@_stop }
+ { 0 ~ 1 ~ }
+ ] ~
+ /Range ~
+ [ ~
+ \str_case:nn {#2}
+ {
+ { /DeviceCMYK } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 }
+ { /DeviceGray } { 0 ~ 1 }
+ { /DeviceRGB } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 }
+ } ~
+ ]
+ }
+ { {#3} }
+ }
+ \use:e
+ {
+ \pdf_object_new:n { color \int_use:N \g_@@_model_int }
+ \pdf_object_write:nnn { color \int_use:N \g_@@_model_int } { array }
+ {
+ /DeviceN ~
+ [ ~ #1 ~ ] ~
+ #2 ~
+ \pdf_object_ref_last:
+ \@@_backend_devicen_colorants:n {#1}
+ }
+ }
+ \@@_backend_init_resource:n { color \int_use:N \g_@@_model_int }
+ }
+\cs_new:Npn \@@_backend_devicen_init:w #1 ~ #2 \s_@@_stop
+ {
+ + 1
+ \tl_if_blank:nF {#2}
+ { \@@_backend_devicen_init:w #2 \s_@@_stop }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_iccbased_init:nnn}
+% Lots of data to save here: we only want to do that once per file,
+% so track it by name.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_iccbased_init:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { @@_icc_ #1 }
+ {
+ \pdf_object_new:n { @@_icc_ #1 }
+ \pdf_object_write:nne { @@_icc_ #1 } { fstream }
+ {
+ {
+ /N ~ \exp_not:n { #2 } ~
+ \tl_if_empty:nF { #3 } { /Range~[ #3 ] }
+ }
+ {#1}
+ }
+ }
+ \pdf_object_unnamed_write:ne { array }
+ { /ICCBased ~ \pdf_object_ref:n { @@_icc_ #1 } }
+ \@@_backend_init_resource:n { color \int_use:N \g_@@_model_int }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_iccbased_device:nnn}
+% This is very similar to setting up a color space: the only part we
+% add to the page resources differently.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_iccbased_device:nnn #1#2#3
+ {
+ \pdf_object_if_exist:nF { @@_icc_ #1 }
+ {
+ \pdf_object_new:n { @@_icc_ #1 }
+ \pdf_object_write:nnn { @@_icc_ #1 } { fstream }
+ {
+ { /N ~ #3 }
+ {#1}
+ }
+ }
+ \pdf_object_unnamed_write:ne { array }
+ { /ICCBased ~ \pdf_object_ref:n { @@_icc_ #1 } }
+ \@@_backend_init_resource:n { Default #2 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \subsection{Fill and stroke color}
+%
+% Here, \texttt{dvipdfmx}/\XeTeX{} we write direct PDF specials for the fill,
+% and only use the stack for the stroke color (see above for comments on why
+% we cannot use multiple stacks with these backends). \LuaTeX{} and \pdfTeX{}
+% have mutiple stacks that can deal with fill and stroke. For \texttt{dvips}
+% we have to manage fill and stroke color ourselves. We also handle
+% \texttt{dvisvgm} independently, as there we can create SVG directly.
+%
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill:n ,
+% \@@_backend_fill_cmyk:n ,
+% \@@_backend_fill_gray:n ,
+% \@@_backend_fill_rgb:n ,
+% \@@_backend_stroke:n ,
+% \@@_backend_stroke_cmyk:n ,
+% \@@_backend_stroke_gray:n ,
+% \@@_backend_stroke_rgb:n
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill:n #1
+ { \__kernel_backend_literal:n { pdf : bc ~ fill ~ [ #1 ] } }
+\cs_new_eq:NN \@@_backend_fill_cmyk:n \@@_backend_fill:n
+\cs_new_eq:NN \@@_backend_fill_gray:n \@@_backend_fill:n
+\cs_new_eq:NN \@@_backend_fill_rgb:n \@@_backend_fill:n
+\cs_new_protected:Npn \@@_backend_stroke:n #1
+ { \__kernel_backend_literal:n { pdf : bc ~ stroke ~ [ #1 ] } }
+\cs_new_eq:NN \@@_backend_stroke_cmyk:n \@@_backend_stroke:n
+\cs_new_eq:NN \@@_backend_stroke_gray:n \@@_backend_stroke:n
+\cs_new_eq:NN \@@_backend_stroke_rgb:n \@@_backend_stroke:n
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_separation:nn,
+% \@@_backend_stroke_separation:nn,
+% \@@_backend_fill_devicen:nn,
+% \@@_backend_stroke_devicen:nn
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2
+ {
+ \__kernel_backend_literal:e
+ { pdf : bc ~ fill ~ \pdf_object_ref:n {#1} ~ [ #2 ] }
+ }
+\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2
+ {
+ \__kernel_backend_literal:e
+ { pdf : bc ~ stroke ~ \pdf_object_ref:n {#1} ~ [ #2 ] }
+ }
+\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn
+\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_fill_reset:, \@@_backend_stroke_reset:}
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_fill_reset: \@@_backend_reset:
+\cs_new_eq:NN \@@_backend_stroke_reset: \@@_backend_reset:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_cmyk:n ,
+% \@@_backend_fill_gray:n ,
+% \@@_backend_fill_rgb:n ,
+% \@@_backend_fill:n ,
+% \@@_backend_stroke_cmyk:n ,
+% \@@_backend_stroke_gray:n ,
+% \@@_backend_stroke_rgb:n ,
+% \@@_backend_stroke:n
+% }
+% Drawing (fill/stroke) color is handled in \texttt{dvipdfmx}/\XeTeX{} in the
+% same way as \LuaTeX{}/\pdfTeX{}. We use the same approach as earlier, except the
+% color stack is not involved so the generic direct PDF operation is used.
+% There is no worry about the nature of strokes: everything is handled
+% automatically.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_cmyk:n #1
+ { \@@_backend_fill:n { #1 ~ k } }
+\cs_new_protected:Npn \@@_backend_fill_gray:n #1
+ { \@@_backend_fill:n { #1 ~ g } }
+\cs_new_protected:Npn \@@_backend_fill_rgb:n #1
+ { \@@_backend_fill:n { #1 ~ rg } }
+\cs_new_protected:Npn \@@_backend_fill:n #1
+ {
+ \tl_set:Nn \l_@@_backend_fill_tl {#1}
+ \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int
+ { #1 ~ \l_@@_backend_stroke_tl }
+ }
+\cs_new_protected:Npn \@@_backend_stroke_cmyk:n #1
+ { \@@_backend_stroke:n { #1 ~ K } }
+\cs_new_protected:Npn \@@_backend_stroke_gray:n #1
+ { \@@_backend_stroke:n { #1 ~ G } }
+\cs_new_protected:Npn \@@_backend_stroke_rgb:n #1
+ { \@@_backend_stroke:n { #1 ~ RG } }
+\cs_new_protected:Npn \@@_backend_stroke:n #1
+ {
+ \tl_set:Nn \l_@@_backend_stroke_tl {#1}
+ \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int
+ { \l_@@_backend_fill_tl \c_space_tl #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_separation:nn,
+% \@@_backend_stroke_separation:nn,
+% \@@_backend_fill_devicen:nn,
+% \@@_backend_stroke_devicen:nn
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2
+ { \@@_backend_fill:n { /#1 ~ cs ~ #2 ~ scn } }
+\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2
+ { \@@_backend_stroke:n { /#1 ~ CS ~ #2 ~ SCN } }
+\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn
+\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_fill_reset:, \@@_backend_stroke_reset:}
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_fill_reset: \@@_backend_reset:
+\cs_new_eq:NN \@@_backend_stroke_reset: \@@_backend_reset:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_cmyk:n ,
+% \@@_backend_fill_gray:n ,
+% \@@_backend_fill_rgb:n ,
+% \@@_backend_fill:n ,
+% \@@_backend_stroke_cmyk:n ,
+% \@@_backend_stroke_gray:n ,
+% \@@_backend_stroke_rgb:n
+% }
+% Fill color here is the same as general color \emph{except} we skip the
+% stroke part.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_cmyk:n #1
+ { \@@_backend_fill:n { cmyk ~ #1 } }
+\cs_new_protected:Npn \@@_backend_fill_gray:n #1
+ { \@@_backend_fill:n { gray ~ #1 } }
+\cs_new_protected:Npn \@@_backend_fill_rgb:n #1
+ { \@@_backend_fill:n { rgb ~ #1 } }
+\cs_new_protected:Npn \@@_backend_fill:n #1
+ {
+ \__kernel_backend_literal:n { color~push~ #1 }
+ }
+\cs_new_protected:Npn \@@_backend_stroke_cmyk:n #1
+ { \__kernel_backend_postscript:n { /color.sc { #1 ~ setcmykcolor } def } }
+\cs_new_protected:Npn \@@_backend_stroke_gray:n #1
+ { \__kernel_backend_postscript:n { /color.sc { #1 ~ setgray } def } }
+\cs_new_protected:Npn \@@_backend_stroke_rgb:n #1
+ { \__kernel_backend_postscript:n { /color.sc { #1 ~ setrgbcolor } def } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_separation:nn,
+% \@@_backend_stroke_separation:nn,
+% \@@_backend_fill_devicen:nn,
+% \@@_backend_stroke_devicen:nn
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2
+ { \@@_backend_fill:n { separation ~ #1 ~ #2 } }
+\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2
+ { \__kernel_backend_postscript:n { /color.sc { separation ~ #1 ~ #2 } def } }
+\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn
+\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_fill_reset:, \@@_backend_stroke_reset:}
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_fill_reset: \@@_backend_reset:
+\cs_new_protected:Npn \@@_backend_stroke_reset: { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_cmyk:n ,
+% \@@_backend_fill_gray:n ,
+% \@@_backend_fill_rgb:n ,
+% \@@_backend_fill:n
+% }
+% Fill color here is the same as general color \emph{except} we skip the
+% stroke part.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_cmyk:n #1
+ { \@@_backend_fill:n { cmyk ~ #1 } }
+\cs_new_protected:Npn \@@_backend_fill_gray:n #1
+ { \@@_backend_fill:n { gray ~ #1 } }
+\cs_new_protected:Npn \@@_backend_fill_rgb:n #1
+ { \@@_backend_fill:n { rgb ~ #1 } }
+\cs_new_protected:Npn \@@_backend_fill:n #1
+ {
+ \__kernel_backend_literal:n { color~push~ #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_stroke_cmyk:n}
+% \begin{macro}{\@@_backend_stroke_cmyk:w}
+% \begin{macro}{\@@_backend_stroke_gray:n, \@@_backend_stroke_gray_aux:n}
+% \begin{macro}{\@@_backend_stroke_rgb:n}
+% \begin{macro}{\@@_backend_stroke_rgb:w}
+% \begin{macro}{\@@_backend:nnn}
+% For drawings in SVG, we use scopes for all stroke colors. That
+% requires using \texttt{RGB} values, which luckily are easy to
+% convert here (|cmyk| to |RGB| is a fixed function).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_stroke_cmyk:n #1
+ { \@@_backend_cmyk:w #1 \s_@@_stop }
+\cs_new_protected:Npn \@@_backend_stroke_cmyk:w
+ #1 ~ #2 ~ #3 ~ #4 \s_@@_stop
+ {
+ \use:e
+ {
+ \@@_backend:nnn
+ { \fp_eval:n { -100 * ( 1 - min ( 1 , #1 + #4 ) ) } }
+ { \fp_eval:n { -100 * ( 1 - min ( 1 , #2 + #4 ) ) } }
+ { \fp_eval:n { -100 * ( 1 - min ( 1 , #3 + #4 ) ) } }
+ }
+ }
+\cs_new_protected:Npn \@@_backend_stroke_gray:n #1
+ {
+ \use:e
+ {
+ \@@_backend_stroke_gray_aux:n
+ { \fp_eval:n { 100 * (#1) } }
+ }
+ }
+\cs_new_protected:Npn \@@_backend_stroke_gray_aux:n #1
+ { \@@_backend:nnn {#1} {#1} {#1} }
+\cs_new_protected:Npn \@@_backend_stroke_rgb:n #1
+ { \@@_backend_rgb:w #1 \s_@@_stop }
+\cs_new_protected:Npn \@@_backend_stroke_rgb:w
+ #1 ~ #2 ~ #3 \s_@@_stop
+ {
+ \use:e
+ {
+ \@@_backend:nnn
+ { \fp_eval:n { 100 * (#1) } }
+ { \fp_eval:n { 100 * (#2) } }
+ { \fp_eval:n { 100 * (#3) } }
+ }
+ }
+\cs_new_protected:Npe \@@_backend:nnn #1#2#3
+ {
+ \__kernel_backend_scope:n
+ {
+ stroke =
+ "
+ rgb
+ (
+ #1 \c_percent_str ,
+ #2 \c_percent_str ,
+ #3 \c_percent_str
+ )
+ "
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_separation:nn,
+% \@@_backend_stroke_separation:nn,
+% \@@_backend_fill_devicen:nn,
+% \@@_backend_stroke_devicen:nn
+% }
+% At present, these are no-ops.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2 { }
+\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2 { }
+\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn
+\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_fill_reset:, \@@_backend_stroke_reset:}
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_fill_reset: \@@_backend_reset:
+\cs_new_protected:Npn \@@_backend_stroke_reset: { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_devicen_init:nnn, \@@_backend_iccbased_init:nnn}
+% No support at present.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_devicen_init:nnn #1#2#3 { }
+\cs_new_protected:Npn \@@_backend_iccbased_init:nnn #1#2#3 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \subsection{Font handling integration}
+%
+% In \LuaTeX{} these colors should also be usable to color fonts, so
+% \texttt{luaotfload} color handling is extended to include these.
+%
+% \begin{macrocode}
+%<*lua>
+% \end{macrocode}
+%
+% \begin{macrocode}
+local l = lpeg
+local spaces = l.P' '^0
+local digit16 = l.R('09', 'af', 'AF')
+
+local octet = digit16 * digit16 / function(s)
+ return string.format('%.3g ', tonumber(s, 16) / 255)
+end
+
+if luaotfload and luaotfload.set_transparent_colorstack then
+ local htmlcolor = l.Cs(octet * octet * octet * -1 * l.Cc'rg')
+ local color_export = {
+ token.create'tex_endlocalcontrol:D',
+ token.create'tex_hpack:D',
+ token.new(0, 1),
+ token.create'color_export:nnN',
+ token.new(0, 1),
+ '',
+ token.new(0, 2),
+ token.new(0, 1),
+ 'backend',
+ token.new(0, 2),
+ token.create'l_tmpa_tl',
+ token.create'exp_after:wN',
+ token.create'@@_select:nn',
+ token.create'l_tmpa_tl',
+ token.new(0, 2),
+ }
+ local group_end = token.create'group_end:'
+ local value = (1 - l.P'}')^0
+ luatexbase.add_to_callback('luaotfload.parse_color', function (value)
+% Also allow HTML colors to preserve compatibility
+ local html = htmlcolor:match(value)
+ if html then return html end
+
+% If no l3color named color with this name is known, check for defined xcolor colors
+ local l3color_prop = token.get_macro(string.format('l_@@_named_%s_prop', value))
+ if l3color_prop == nil or l3color_prop == '' then
+ local legacy_color_macro = token.create(string.format('\\color@%s', value))
+ if legacy_color_macro.cmdname ~= 'undefined_cs' then
+ token.put_next(legacy_color_macro)
+ return token.scan_argument()
+ end
+ end
+
+ tex.runtoks(function()
+ token.get_next()
+ color_export[6] = value
+ tex.sprint(-2, color_export)
+ end)
+ local list = token.scan_list()
+ if not list.head or list.head.next
+ or list.head.subtype ~= node.subtype'pdf_colorstack' then
+ error'Unexpected backend behavior'
+ end
+ local cmd = list.head.data
+ node.free(list)
+ return cmd
+ end, 'l3color')
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</lua>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*luatex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\lua_load_module:n {l3backend-luatex}
+%</package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</luatex>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3backend/l3backend-draw.dtx b/macros/latex-dev/required/l3backend/l3backend-draw.dtx
new file mode 100644
index 0000000000..c651ab92fe
--- /dev/null
+++ b/macros/latex-dev/required/l3backend/l3backend-draw.dtx
@@ -0,0 +1,1067 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-draw.dtx
+%
+% Copyright (C) 2019-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3backend bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3backend-draw} package\\ Backend drawing support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-draw} implementation}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=draw>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvips} backend}
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_literal:n, \@@_backend_literal:e}
+% The same as literal PostScript: same arguments about positioning apply
+% here.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_literal:n \__kernel_backend_literal_postscript:n
+\cs_generate_variant:Nn \@@_backend_literal:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_begin:, \@@_backend_end:}
+% The |ps::[begin]| special here deals with positioning but allows us to
+% continue on to a matching |ps::[end]|: contrast with |ps:|, which positions
+% but where we can't split material between separate calls. The
+% |@beginspecial|/|@endspecial| pair are from |special.pro| and correct the
+% scale and $y$-axis direction.
+% As for \pkg{pgf}, we need to save the current point as this is
+% required for box placement. (Note that
+% |@beginspecial|/|@endspecial| forms a backend scope.)
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_begin:
+ {
+ \@@_backend_literal:n { [begin] }
+ \@@_backend_literal:n { /draw.x~currentpoint~/draw.y~exch~def~def }
+ \@@_backend_literal:n { @beginspecial }
+ }
+\cs_new_protected:Npn \@@_backend_end:
+ {
+ \@@_backend_literal:n { @endspecial }
+ \@@_backend_literal:n { [end] }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_scope_begin:, \@@_backend_scope_end:}
+% Scope here may need to contain saved definitions, so the entire memory
+% rather than just the graphic state has to be sent to the stack.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_scope_begin:
+ { \@@_backend_literal:n { save } }
+\cs_new_protected:Npn \@@_backend_scope_end:
+ { \@@_backend_literal:n { restore } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_moveto:nn, \@@_backend_lineto:nn}
+% \begin{macro}{\@@_backend_rectangle:nnnn}
+% \begin{macro}{\@@_backend_curveto:nnnnnn}
+% Path creation operations mainly resolve directly to PostScript primitive
+% steps, with only the need to convert to \texttt{bp}. Notice that
+% \texttt{x}-type expansion is included here to ensure that any variable
+% values are forced to literals before any possible caching. There is
+% no native rectangular path command (without also clipping, filling or
+% stroking), so that task is done using a small amount of PostScript.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_moveto:nn #1#2
+ {
+ \@@_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~
+ \dim_to_decimal_in_bp:n {#2} ~ moveto
+ }
+ }
+\cs_new_protected:Npn \@@_backend_lineto:nn #1#2
+ {
+ \@@_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~
+ \dim_to_decimal_in_bp:n {#2} ~ lineto
+ }
+ }
+\cs_new_protected:Npn \@@_backend_rectangle:nnnn #1#2#3#4
+ {
+ \@@_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#4} ~ \dim_to_decimal_in_bp:n {#3} ~
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ moveto~dup~0~rlineto~exch~0~exch~rlineto~neg~0~rlineto~closepath
+ }
+ }
+\cs_new_protected:Npn \@@_backend_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~
+ curveto
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_evenodd_rule:, \@@_backend_nonzero_rule:}
+% \begin{variable}{\g_@@_draw_eor_bool}
+% The even-odd rule here can be implemented as a simply switch.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_evenodd_rule:
+ { \bool_gset_true:N \g_@@_draw_eor_bool }
+\cs_new_protected:Npn \@@_backend_nonzero_rule:
+ { \bool_gset_false:N \g_@@_draw_eor_bool }
+\bool_new:N \g_@@_draw_eor_bool
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_closepath: ,
+% \@@_backend_stroke: ,
+% \@@_backend_closestroke: ,
+% \@@_backend_fill: ,
+% \@@_backend_fillstroke: ,
+% \@@_backend_clip: ,
+% \@@_backend_discardpath:
+% }
+% \begin{variable}{\g_@@_draw_clip_bool}
+% Unlike PDF, PostScript doesn't track separate colors for strokes and other
+% elements. It is also desirable to have the |clip| keyword after a stroke or
+% fill. To achieve those outcomes, there is some work to do. For color, the
+% stoke color is simple but the fill one has to be inserted by hand. For
+% clipping, the required ordering is achieved using a \TeX{} switch. All of
+% the operations end with a new path instruction as they do not terminate
+% (again in contrast to PDF).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_closepath:
+ { \@@_backend_literal:n { closepath } }
+\cs_new_protected:Npn \@@_backend_stroke:
+ {
+ \@@_backend_literal:n { gsave }
+ \@@_backend_literal:n { color.sc }
+ \@@_backend_literal:n { stroke }
+ \@@_backend_literal:n { grestore }
+ \bool_if:NT \g_@@_draw_clip_bool
+ {
+ \@@_backend_literal:e
+ {
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
+ clip
+ }
+ }
+ \@@_backend_literal:n { newpath }
+ \bool_gset_false:N \g_@@_draw_clip_bool
+ }
+\cs_new_protected:Npn \@@_backend_closestroke:
+ {
+ \@@_backend_closepath:
+ \@@_backend_stroke:
+ }
+\cs_new_protected:Npn \@@_backend_fill:
+ {
+ \@@_backend_literal:e
+ {
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
+ fill
+ }
+ \bool_if:NT \g_@@_draw_clip_bool
+ {
+ \@@_backend_literal:e
+ {
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
+ clip
+ }
+ }
+ \@@_backend_literal:n { newpath }
+ \bool_gset_false:N \g_@@_draw_clip_bool
+ }
+\cs_new_protected:Npn \@@_backend_fillstroke:
+ {
+ \@@_backend_literal:e
+ {
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
+ fill
+ }
+ \@@_backend_literal:n { gsave }
+ \@@_backend_literal:n { color.sc }
+ \@@_backend_literal:n { stroke }
+ \@@_backend_literal:n { grestore }
+ \bool_if:NT \g_@@_draw_clip_bool
+ {
+ \@@_backend_literal:e
+ {
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
+ clip
+ }
+ }
+ \@@_backend_literal:n { newpath }
+ \bool_gset_false:N \g_@@_draw_clip_bool
+ }
+\cs_new_protected:Npn \@@_backend_clip:
+ { \bool_gset_true:N \g_@@_draw_clip_bool }
+\bool_new:N \g_@@_draw_clip_bool
+\cs_new_protected:Npn \@@_backend_discardpath:
+ {
+ \bool_if:NT \g_@@_draw_clip_bool
+ {
+ \@@_backend_literal:e
+ {
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
+ clip
+ }
+ }
+ \@@_backend_literal:n { newpath }
+ \bool_gset_false:N \g_@@_draw_clip_bool
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_dash_pattern:nn}
+% \begin{macro}{\@@_backend_dash:n}
+% \begin{macro}{\@@_backend_linewidth:n}
+% \begin{macro}{\@@_backend_miterlimit:n}
+% \begin{macro}
+% {
+% \@@_backend_cap_butt:, \@@_backend_cap_round:, \@@_backend_cap_rectangle:,
+% \@@_backend_join_miter:, \@@_backend_join_round:, \@@_backend_join_bevel:
+% }
+% Converting paths to output is again a case of mapping directly to
+% PostScript operations.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_dash_pattern:nn #1#2
+ {
+ \@@_backend_literal:e
+ {
+ [
+ \exp_args:Nf \use:n
+ { \clist_map_function:nN {#1} \@@_backend_dash:n }
+ ] ~
+ \dim_to_decimal_in_bp:n {#2} ~ setdash
+ }
+ }
+\cs_new:Npn \@@_backend_dash:n #1
+ { ~ \dim_to_decimal_in_bp:n {#1} }
+\cs_new_protected:Npn \@@_backend_linewidth:n #1
+ {
+ \@@_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ setlinewidth }
+ }
+\cs_new_protected:Npn \@@_backend_miterlimit:n #1
+ { \@@_backend_literal:n { #1 ~ setmiterlimit } }
+\cs_new_protected:Npn \@@_backend_cap_butt:
+ { \@@_backend_literal:n { 0 ~ setlinecap } }
+\cs_new_protected:Npn \@@_backend_cap_round:
+ { \@@_backend_literal:n { 1 ~ setlinecap } }
+\cs_new_protected:Npn \@@_backend_cap_rectangle:
+ { \@@_backend_literal:n { 2 ~ setlinecap } }
+\cs_new_protected:Npn \@@_backend_join_miter:
+ { \@@_backend_literal:n { 0 ~ setlinejoin } }
+\cs_new_protected:Npn \@@_backend_join_round:
+ { \@@_backend_literal:n { 1 ~ setlinejoin } }
+\cs_new_protected:Npn \@@_backend_join_bevel:
+ { \@@_backend_literal:n { 2 ~ setlinejoin } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_backend_cm:nnnn}
+% In \texttt{dvips}, keeping the transformations in line with the engine
+% is unfortunately not possible for scaling and rotations: even if we
+% decompose the matrix into those operations, there is still no backend
+% tracking (\emph{cf.}~\texttt{dvipdfmx}/\XeTeX{}). Thus we take the shortest
+% path available and simply dump the matrix as given.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_cm:nnnn #1#2#3#4
+ {
+ \@@_backend_literal:n
+ { [ #1 ~ #2 ~ #3 ~ #4 ~ 0 ~ 0 ] ~ concat }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_box_use:Nnnnn}
+% Inside a picture |@beginspecial|/|@endspecial| are active, which is
+% normally a good thing but means that the position and scaling would be off
+% if the box was inserted directly. To deal with that, there are a number of
+% possible approaches. A previous implementation suggested by Tom Rokici
+% used |@endspecial|/|@beginspecial|. This avoids needing internals of
+% \texttt{dvips}, but fails if there the box is used inside a scope
+% (see \url{https://github.com/latex3/latex3/issues/1504}). Instead,
+% we use the same method as \pkg{pgf}, which means tracking the position
+% at the PostScript level. Also note that using |@endspecial| would
+% close the scope it creates, meaning that after a box insertion, any
+% local changes would be lost. Keeping \texttt{dvips} on track is
+% non-trivial, hence the |[begin]|/|[end]| pair before the
+% |save| and around the |restore|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_box_use:Nnnnn #1#2#3#4#5
+ {
+ \@@_backend_literal:n { save }
+ \@@_backend_literal:n { 72~Resolution~div~72~VResolution~div~neg~scale }
+ \@@_backend_literal:n { magscale { 1~DVImag~div~dup~scale } if }
+ \@@_backend_literal:n { draw.x~neg~draw.y~neg~translate }
+ \@@_backend_literal:n { [end] }
+ \@@_backend_literal:n { [begin] }
+ \@@_backend_literal:n { save }
+ \@@_backend_literal:n { currentpoint }
+ \@@_backend_literal:n { currentpoint~translate }
+ \@@_backend_cm:nnnn { 1 } { 0 } { 0 } { -1 }
+ \@@_backend_cm:nnnn {#2} {#3} {#4} {#5}
+ \@@_backend_cm:nnnn { 1 } { 0 } { 0 } { -1 }
+ \@@_backend_literal:n { neg~exch~neg~exch~translate }
+ \@@_backend_literal:n { [end] }
+ \hbox_overlap_right:n { \box_use:N #1 }
+ \@@_backend_literal:n { [begin] }
+ \@@_backend_literal:n { restore }
+ \@@_backend_literal:n { [end] }
+ \@@_backend_literal:n { [begin] }
+ \@@_backend_literal:n { restore }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \subsection{\LuaTeX{}, \pdfTeX{}, \texttt{dvipdfmx} and \XeTeX{}}
+%
+% \LuaTeX{}, \pdfTeX{}, \texttt{dvipdfmx} and \XeTeX{} directly produce PDF output
+% and understand a shared set of specials for drawing commands.
+%
+% \begin{macrocode}
+%<*dvipdfmx|luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \subsubsection{Drawing}
+%
+% \begin{macro}{\@@_backend_literal:n, \@@_backend_literal:e}
+% Pass data through using a dedicated interface.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_literal:n \__kernel_backend_literal_pdf:n
+\cs_generate_variant:Nn \@@_backend_literal:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_begin:, \@@_backend_end:}
+% No special requirements here, so simply set up a drawing scope.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_begin:
+ { \@@_backend_scope_begin: }
+\cs_new_protected:Npn \@@_backend_end:
+ { \@@_backend_scope_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_scope_begin:, \@@_backend_scope_end:}
+% Use the backend-level scope mechanisms.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_scope_begin: \__kernel_backend_scope_begin:
+\cs_new_eq:NN \@@_backend_scope_end: \__kernel_backend_scope_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_moveto:nn, \@@_backend_lineto:nn}
+% \begin{macro}{\@@_backend_curveto:nnnnnn}
+% \begin{macro}{\@@_backend_rectangle:nnnn}
+% Path creation operations all resolve directly to PDF primitive steps, with
+% only the need to convert to \texttt{bp}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_moveto:nn #1#2
+ {
+ \@@_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ m }
+ }
+\cs_new_protected:Npn \@@_backend_lineto:nn #1#2
+ {
+ \@@_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ l }
+ }
+\cs_new_protected:Npn \@@_backend_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~
+ c
+ }
+ }
+\cs_new_protected:Npn \@@_backend_rectangle:nnnn #1#2#3#4
+ {
+ \@@_backend_literal:e
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ re
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_evenodd_rule:, \@@_backend_nonzero_rule:}
+% \begin{variable}{\g_@@_draw_eor_bool}
+% The even-odd rule here can be implemented as a simply switch.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_evenodd_rule:
+ { \bool_gset_true:N \g_@@_draw_eor_bool }
+\cs_new_protected:Npn \@@_backend_nonzero_rule:
+ { \bool_gset_false:N \g_@@_draw_eor_bool }
+\bool_new:N \g_@@_draw_eor_bool
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_closepath: ,
+% \@@_backend_stroke: ,
+% \@@_backend_closestroke: ,
+% \@@_backend_fill: ,
+% \@@_backend_fillstroke: ,
+% \@@_backend_clip: ,
+% \@@_backend_discardpath:
+% }
+% Converting paths to output is again a case of mapping directly to
+% PDF operations.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_closepath:
+ { \@@_backend_literal:n { h } }
+\cs_new_protected:Npn \@@_backend_stroke:
+ { \@@_backend_literal:n { S } }
+\cs_new_protected:Npn \@@_backend_closestroke:
+ { \@@_backend_literal:n { s } }
+\cs_new_protected:Npn \@@_backend_fill:
+ {
+ \@@_backend_literal:e
+ { f \bool_if:NT \g_@@_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \@@_backend_fillstroke:
+ {
+ \@@_backend_literal:e
+ { B \bool_if:NT \g_@@_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \@@_backend_clip:
+ {
+ \@@_backend_literal:e
+ { W \bool_if:NT \g_@@_draw_eor_bool * }
+ }
+\cs_new_protected:Npn \@@_backend_discardpath:
+ { \@@_backend_literal:n { n } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_dash_pattern:nn}
+% \begin{macro}{\@@_backend_dash:n}
+% \begin{macro}{\@@_backend_linewidth:n}
+% \begin{macro}{\@@_backend_miterlimit:n}
+% \begin{macro}
+% {
+% \@@_backend_cap_butt:, \@@_backend_cap_round:, \@@_backend_cap_rectangle:,
+% \@@_backend_join_miter:, \@@_backend_join_round:, \@@_backend_join_bevel:
+% }
+% Converting paths to output is again a case of mapping directly to
+% PDF operations.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_dash_pattern:nn #1#2
+ {
+ \@@_backend_literal:e
+ {
+ [
+ \exp_args:Nf \use:n
+ { \clist_map_function:nN {#1} \@@_backend_dash:n }
+ ] ~
+ \dim_to_decimal_in_bp:n {#2} ~ d
+ }
+ }
+\cs_new:Npn \@@_backend_dash:n #1
+ { ~ \dim_to_decimal_in_bp:n {#1} }
+\cs_new_protected:Npn \@@_backend_linewidth:n #1
+ {
+ \@@_backend_literal:e
+ { \dim_to_decimal_in_bp:n {#1} ~ w }
+ }
+\cs_new_protected:Npn \@@_backend_miterlimit:n #1
+ { \@@_backend_literal:e { #1 ~ M } }
+\cs_new_protected:Npn \@@_backend_cap_butt:
+ { \@@_backend_literal:n { 0 ~ J } }
+\cs_new_protected:Npn \@@_backend_cap_round:
+ { \@@_backend_literal:n { 1 ~ J } }
+\cs_new_protected:Npn \@@_backend_cap_rectangle:
+ { \@@_backend_literal:n { 2 ~ J } }
+\cs_new_protected:Npn \@@_backend_join_miter:
+ { \@@_backend_literal:n { 0 ~ j } }
+\cs_new_protected:Npn \@@_backend_join_round:
+ { \@@_backend_literal:n { 1 ~ j } }
+\cs_new_protected:Npn \@@_backend_join_bevel:
+ { \@@_backend_literal:n { 2 ~ j } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_cm:nnnn}
+% \begin{macro}{\@@_backend_cm_aux:nnnn}
+% Another split here between \LuaTeX{}/pdfTeX{} and \texttt{dvipdfmx}/\XeTeX{}.
+% In the former, we have a direct method to maintain alignment: the backend
+% can use a matrix itself. For \texttt{dvipdfmx}/\XeTeX{}, we can to decompose the
+% matrix into rotations and a scaling, then use those operations as they
+% are handled by the backend. (There is backend support for matrix operations in
+% \texttt{dvipdfmx}/\XeTeX{}, but as a matched pair so not suitable for the
+% \enquote{stand alone} transformation set up here.) The specials used here
+% are from \texttt{xdvipdfmx} originally: they are well-tested, but probably
+% equivalent to the \texttt{pdf:} versions!
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_cm:nnnn #1#2#3#4
+ {
+%<*luatex|pdftex>
+ \__kernel_backend_matrix:n { #1 ~ #2 ~ #3 ~ #4 }
+%</luatex|pdftex>
+%<*dvipdfmx|xetex>
+ \@@_backend_cm_decompose:nnnnN {#1} {#2} {#3} {#4}
+ \@@_backend_cm_aux:nnnn
+%</dvipdfmx|xetex>
+ }
+%<*dvipdfmx|xetex>
+\cs_new_protected:Npn \@@_backend_cm_aux:nnnn #1#2#3#4
+ {
+ \__kernel_backend_literal:e
+ {
+ x:rotate~
+ \fp_compare:nNnTF {#1} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( -#1 , 5 ) } }
+ }
+ \__kernel_backend_literal:e
+ {
+ x:scale~
+ \fp_eval:n { round ( #2 , 5 ) } ~
+ \fp_eval:n { round ( #3 , 5 ) }
+ }
+ \__kernel_backend_literal:e
+ {
+ x:rotate~
+ \fp_compare:nNnTF {#4} = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( -#4 , 5 ) } }
+ }
+ }
+%</dvipdfmx|xetex>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_cm_decompose:nnnnN}
+% \begin{macro}
+% {
+% \@@_backend_cm_decompose_auxi:nnnnN,
+% \@@_backend_cm_decompose_auxii:nnnnN,
+% \@@_backend_cm_decompose_auxiii:nnnnN,
+% }
+% Internally, transformations for drawing are tracked as a matrix. Not all
+% engines provide a way of dealing with this: if we use a raw matrix, the
+% engine looses track of positions (for example for hyperlinks), and this is
+% not desirable. They do, however, allow us to track rotations and scalings.
+% Luckily, we can decompose any (two-dimensional) matrix into two rotations
+% and a single scaling:
+% \[
+% \begin{bmatrix}
+% A & B \\ C & D
+% \end{bmatrix}
+% =
+% \begin{bmatrix}
+% \cos\beta & \sin\beta \\ -\sin\beta & \cos\beta
+% \end{bmatrix}
+% \begin{bmatrix}
+% w_{1} & 0 \\ 0 & w_{2}
+% \end{bmatrix}
+% \begin{bmatrix}
+% \cos\gamma & \sin\gamma \\ -\sin\gamma & \cos\gamma
+% \end{bmatrix}
+% \]
+% The parent matrix can be converted to
+% \[
+% \begin{bmatrix}
+% A & B \\ C & D
+% \end{bmatrix}
+% =
+% \begin{bmatrix}
+% E & H \\-H & E
+% \end{bmatrix}
+% +
+% \begin{bmatrix}
+% F & G \\ G & -F
+% \end{bmatrix}
+% \]
+% From these, we can find that
+% \begin{align*}
+% \frac{w_{1} + w_{2}}{2} &= \sqrt{E^{2} + H^{2}} \\
+% \frac{w_{1} - w_{2}}{2} &= \sqrt{F^{2} + G^{2}} \\
+% \gamma - \beta &= \tan^{-1}(G/F) \\
+% \gamma + \beta &= \tan^{-1}(H/E)
+% \end{align*}
+% at which point we just have to do various pieces of re-arrangement to
+% get all of the values. (See J.~Blinn, \emph{IEEE Comput.\ Graph.\ Appl.},
+% 1996, \textbf{16}, 82--88.) There is one wrinkle: the PostScript (and PDF)
+% way of specifying a transformation matrix exchanges where one would
+% normally expect $B$ and $C$ to be.
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+\cs_new_protected:Npn \@@_backend_cm_decompose:nnnnN #1#2#3#4#5
+ {
+ \use:e
+ {
+ \@@_backend_cm_decompose_auxi:nnnnN
+ { \fp_eval:n { (#1 + #4) / 2 } }
+ { \fp_eval:n { (#1 - #4) / 2 } }
+ { \fp_eval:n { (#3 + #2) / 2 } }
+ { \fp_eval:n { (#3 - #2) / 2 } }
+ }
+ #5
+ }
+\cs_new_protected:Npn \@@_backend_cm_decompose_auxi:nnnnN #1#2#3#4#5
+ {
+ \use:e
+ {
+ \@@_backend_cm_decompose_auxii:nnnnN
+ { \fp_eval:n { 2 * sqrt ( #1 * #1 + #4 * #4 ) } }
+ { \fp_eval:n { 2 * sqrt ( #2 * #2 + #3 * #3 ) } }
+ { \fp_eval:n { atand ( #3 , #2 ) } }
+ { \fp_eval:n { atand ( #4 , #1 ) } }
+ }
+ #5
+ }
+\cs_new_protected:Npn \@@_backend_cm_decompose_auxii:nnnnN #1#2#3#4#5
+ {
+ \use:e
+ {
+ \@@_backend_cm_decompose_auxiii:nnnnN
+ { \fp_eval:n { ( #4 - #3 ) / 2 } }
+ { \fp_eval:n { ( #1 + #2 ) / 2 } }
+ { \fp_eval:n { ( #1 - #2 ) / 2 } }
+ { \fp_eval:n { ( #4 + #3 ) / 2 } }
+ }
+ #5
+ }
+\cs_new_protected:Npn \@@_backend_cm_decompose_auxiii:nnnnN #1#2#3#4#5
+ {
+ \fp_compare:nNnTF { abs( #2 ) } > { abs ( #3 ) }
+ { #5 {#1} {#2} {#3} {#4} }
+ { #5 {#1} {#3} {#2} {#4} }
+ }
+%</dvipdfmx|xetex>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_box_use:Nnnnn}
+% Inserting a \TeX{} box transformed to the requested position and using
+% the current matrix is done using a mixture of \TeX{} and low-level
+% manipulation. The offset can be handled by \TeX{}, so only any rotation/^^A
+% skew/scaling component needs to be done using the matrix operation. As this
+% operation can never be cached, the scope is set directly not using the
+% \texttt{draw} version.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_box_use:Nnnnn #1#2#3#4#5
+ {
+ \__kernel_backend_scope_begin:
+%<*luatex|pdftex>
+ \@@_backend_cm:nnnn {#2} {#3} {#4} {#5}
+%</luatex|pdftex>
+%<*dvipdfmx|xetex>
+ \__kernel_backend_literal:n
+ { pdf:btrans~matrix~ #2 ~ #3 ~ #4 ~ #5 ~ 0 ~ 0 }
+%</dvipdfmx|xetex>
+ \hbox_overlap_right:n { \box_use:N #1 }
+%<*dvipdfmx|xetex>
+ \__kernel_backend_literal:n { pdf:etrans }
+%</dvipdfmx|xetex>
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvisvgm} backend}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_literal:n, \@@_backend_literal:e}
+% The same as the more general literal call.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_literal:n \__kernel_backend_literal_svg:n
+\cs_generate_variant:Nn \@@_backend_literal:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_scope_begin:, \@@_backend_scope_end:}
+% Use the backend-level scope mechanisms.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_backend_scope_begin: \__kernel_backend_scope_begin:
+\cs_new_eq:NN \@@_backend_scope_end: \__kernel_backend_scope_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_begin:, \@@_backend_end:}
+% A drawing needs to be set up such that the co-ordinate system is
+% translated. That is done inside a scope, which as described below
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_begin:
+ {
+ \__kernel_backend_scope_begin:
+ \__kernel_backend_scope:n { transform="translate({?x},{?y})~scale(1,-1)" }
+ }
+\cs_new_eq:NN \@@_backend_end: \__kernel_backend_scope_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_moveto:nn, \@@_backend_lineto:nn}
+% \begin{macro}{\@@_backend_rectangle:nnnn}
+% \begin{macro}{\@@_backend_curveto:nnnnnn}
+% \begin{macro}{\@@_backend_add_to_path:n}
+% \begin{variable}{\g_@@_backend_path_tl}
+% Once again, some work is needed to get path constructs correct. Rather
+% then write the values as they are given, the entire path needs to be
+% collected up before being output in one go. For that we use a dedicated
+% storage routine, which adds spaces as required. Since paths should
+% be fully expanded there is no need to worry about the internal
+% \texttt{x}-type expansion.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_moveto:nn #1#2
+ {
+ \@@_backend_add_to_path:n
+ { M ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} }
+ }
+\cs_new_protected:Npn \@@_backend_lineto:nn #1#2
+ {
+ \@@_backend_add_to_path:n
+ { L ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} }
+ }
+\cs_new_protected:Npn \@@_backend_rectangle:nnnn #1#2#3#4
+ {
+ \@@_backend_add_to_path:n
+ {
+ M ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2}
+ h ~ \dim_to_decimal:n {#3} ~
+ v ~ \dim_to_decimal:n {#4} ~
+ h ~ \dim_to_decimal:n { -#3 } ~
+ Z
+ }
+ }
+\cs_new_protected:Npn \@@_backend_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_backend_add_to_path:n
+ {
+ C ~
+ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} ~
+ \dim_to_decimal:n {#3} ~ \dim_to_decimal:n {#4} ~
+ \dim_to_decimal:n {#5} ~ \dim_to_decimal:n {#6}
+ }
+ }
+\cs_new_protected:Npn \@@_backend_add_to_path:n #1
+ {
+ \tl_gset:Ne \g_@@_backend_path_tl
+ {
+ \g_@@_backend_path_tl
+ \tl_if_empty:NF \g_@@_backend_path_tl { \c_space_tl }
+ #1
+ }
+ }
+\tl_new:N \g_@@_backend_path_tl
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_evenodd_rule:, \@@_backend_nonzero_rule:}
+% The fill rules here have to be handled as scopes.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_evenodd_rule:
+ { \__kernel_backend_scope:n { fill-rule="evenodd" } }
+\cs_new_protected:Npn \@@_backend_nonzero_rule:
+ { \__kernel_backend_scope:n { fill-rule="nonzero" } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_path:n}
+% \begin{macro}
+% {
+% \@@_backend_closepath: ,
+% \@@_backend_stroke: ,
+% \@@_backend_closestroke: ,
+% \@@_backend_fill: ,
+% \@@_backend_fillstroke: ,
+% \@@_backend_clip: ,
+% \@@_backend_discardpath:
+% }
+% \begin{variable}{\g_@@_draw_clip_bool}
+% \begin{variable}{\g_@@_draw_path_int}
+% Setting fill and stroke effects and doing clipping all has to be done using
+% scopes. This means setting up the various requirements in a shared
+% auxiliary which deals with the bits and pieces. Clipping paths are reused
+% for path drawing: not essential but avoids constructing them twice.
+% Discarding a path needs a separate function as it's not quite the same.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_closepath:
+ { \@@_backend_add_to_path:n { Z } }
+\cs_new_protected:Npn \@@_backend_path:n #1
+ {
+ \bool_if:NTF \g_@@_draw_clip_bool
+ {
+ \int_gincr:N \g__kernel_clip_path_int
+ \@@_backend_literal:e
+ {
+ < clipPath~id = " l3cp \int_use:N \g__kernel_clip_path_int " >
+ { ?nl }
+ <path~d=" \g_@@_backend_path_tl "/> { ?nl }
+ < /clipPath > { ? nl }
+ <
+ use~xlink:href =
+ "\c_hash_str l3path \int_use:N \g_@@_backend_path_int " ~
+ #1
+ />
+ }
+ \__kernel_backend_scope:e
+ {
+ clip-path =
+ "url( \c_hash_str l3cp \int_use:N \g__kernel_clip_path_int)"
+ }
+ }
+ {
+ \@@_backend_literal:e
+ { <path ~ d=" \g_@@_backend_path_tl " ~ #1 /> }
+ }
+ \tl_gclear:N \g_@@_backend_path_tl
+ \bool_gset_false:N \g_@@_draw_clip_bool
+ }
+\int_new:N \g_@@_backend_path_int
+\cs_new_protected:Npn \@@_backend_stroke:
+ { \@@_backend_path:n { style="fill:none" } }
+\cs_new_protected:Npn \@@_backend_closestroke:
+ {
+ \@@_backend_closepath:
+ \@@_backend_stroke:
+ }
+\cs_new_protected:Npn \@@_backend_fill:
+ { \@@_backend_path:n { style="stroke:none" } }
+\cs_new_protected:Npn \@@_backend_fillstroke:
+ { \@@_backend_path:n { } }
+\cs_new_protected:Npn \@@_backend_clip:
+ { \bool_gset_true:N \g_@@_draw_clip_bool }
+\bool_new:N \g_@@_draw_clip_bool
+\cs_new_protected:Npn \@@_backend_discardpath:
+ {
+ \bool_if:NT \g_@@_draw_clip_bool
+ {
+ \int_gincr:N \g__kernel_clip_path_int
+ \@@_backend_literal:e
+ {
+ < clipPath~id = " l3cp \int_use:N \g__kernel_clip_path_int " >
+ { ?nl }
+ <path~d=" \g_@@_backend_path_tl "/> { ?nl }
+ < /clipPath >
+ }
+ \__kernel_backend_scope:e
+ {
+ clip-path =
+ "url( \c_hash_str l3cp \int_use:N \g__kernel_clip_path_int)"
+ }
+ }
+ \tl_gclear:N \g_@@_backend_path_tl
+ \bool_gset_false:N \g_@@_draw_clip_bool
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_dash_pattern:nn}
+% \begin{macro}{\@@_backend_dash:n}
+% \begin{macro}{\@@_backend_dash_aux:nn}
+% \begin{macro}{\@@_backend_linewidth:n}
+% \begin{macro}{\@@_backend_miterlimit:n}
+% \begin{macro}
+% {
+% \@@_backend_cap_butt:, \@@_backend_cap_round:, \@@_backend_cap_rectangle:,
+% \@@_backend_join_miter:, \@@_backend_join_round:, \@@_backend_join_bevel:
+% }
+% All of these ideas are properties of scopes in SVG. The only slight
+% complexity is converting the dash array properly (doing any required
+% maths).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_dash_pattern:nn #1#2
+ {
+ \use:e
+ {
+ \@@_backend_dash_aux:nn
+ { \clist_map_function:nN {#1} \@@_backend_dash:n }
+ { \dim_to_decimal:n {#2} }
+ }
+ }
+\cs_new:Npn \@@_backend_dash:n #1
+ { , \dim_to_decimal_in_bp:n {#1} }
+\cs_new_protected:Npn \@@_backend_dash_aux:nn #1#2
+ {
+ \__kernel_backend_scope:e
+ {
+ stroke-dasharray =
+ "
+ \tl_if_empty:nTF {#1}
+ { none }
+ { \use_none:n #1 }
+ " ~
+ stroke-offset=" #2 "
+ }
+ }
+\cs_new_protected:Npn \@@_backend_linewidth:n #1
+ { \__kernel_backend_scope:e { stroke-width=" \dim_to_decimal:n {#1} " } }
+\cs_new_protected:Npn \@@_backend_miterlimit:n #1
+ { \__kernel_backend_scope:e { stroke-miterlimit=" #1 " } }
+\cs_new_protected:Npn \@@_backend_cap_butt:
+ { \__kernel_backend_scope:n { stroke-linecap="butt" } }
+\cs_new_protected:Npn \@@_backend_cap_round:
+ { \__kernel_backend_scope:n { stroke-linecap="round" } }
+\cs_new_protected:Npn \@@_backend_cap_rectangle:
+ { \__kernel_backend_scope:n { stroke-linecap="square" } }
+\cs_new_protected:Npn \@@_backend_join_miter:
+ { \__kernel_backend_scope:n { stroke-linejoin="miter" } }
+\cs_new_protected:Npn \@@_backend_join_round:
+ { \__kernel_backend_scope:n { stroke-linejoin="round" } }
+\cs_new_protected:Npn \@@_backend_join_bevel:
+ { \__kernel_backend_scope:n { stroke-linejoin="bevel" } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_cm:nnnn}
+% The four arguments here are floats (the affine matrix), the last
+% two are a displacement vector.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_cm:nnnn #1#2#3#4
+ {
+ \__kernel_backend_scope:n
+ {
+ transform =
+ " matrix ( #1 , #2 , #3 , #4 , 0pt , 0pt ) "
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_box_use:Nnnnn}
+% No special savings can be made here: simply displace the box inside
+% a scope. As there is nothing to re-box, just make the box passed of
+% zero size.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_box_use:Nnnnn #1#2#3#4#5
+ {
+ \__kernel_backend_scope_begin:
+ \@@_backend_cm:nnnn {#2} {#3} {#4} {#5}
+ \__kernel_backend_literal_svg:n
+ {
+ < g~
+ stroke="none"~
+ transform="scale(-1,1)~translate({?x},{?y})~scale(-1,-1)"
+ >
+ }
+ \box_set_wd:Nn #1 { 0pt }
+ \box_set_ht:Nn #1 { 0pt }
+ \box_set_dp:Nn #1 { 0pt }
+ \box_use:N #1
+ \__kernel_backend_literal_svg:n { </g> }
+ \__kernel_backend_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3backend/l3backend-graphics.dtx b/macros/latex-dev/required/l3backend/l3backend-graphics.dtx
new file mode 100644
index 0000000000..e20457368d
--- /dev/null
+++ b/macros/latex-dev/required/l3backend/l3backend-graphics.dtx
@@ -0,0 +1,931 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-graphics.dtx
+%
+% Copyright (C) 2019-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3backend bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3backend-graphics} module\\ Backend graphics support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-graphics} implementation}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=graphics>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_loaded:n}
+% To deal with file load ordering. Plain users are on their own.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_loaded:n #1
+ {
+ \cs_if_exist:NTF \hook_gput_code:nnn
+ {
+ \hook_gput_code:nnn
+ { package / l3graphics / after }
+ { backend }
+ {#1}
+ }
+ {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{\texttt{dvips} backend}
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{variable}[no-user-doc]{\l_graphics_search_ext_seq}
+% \begin{macrocode}
+\@@_backend_loaded:n
+ { \seq_set_from_clist:Nn \l_graphics_search_ext_seq { .eps , .ps } }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_backend_getbb_eps:n, \@@_backend_getbb_ps:n}
+% Simply use the generic function.
+% \begin{macrocode}
+\@@_backend_loaded:n
+ {
+ \cs_new_eq:NN \@@_backend_getbb_eps:n \@@_read_bb:n
+ \cs_new_eq:NN \@@_backend_getbb_ps:n \@@_read_bb:n
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_include_eps:n, \@@_backend_include_ps:n}
+% The special syntax is relatively clear here: remember we need PostScript
+% sizes here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_eps:n #1
+ {
+ \__kernel_backend_literal:e
+ {
+ PSfile = #1 \c_space_tl
+ llx = \dim_to_decimal_in_bp:n \l_@@_llx_dim \c_space_tl
+ lly = \dim_to_decimal_in_bp:n \l_@@_lly_dim \c_space_tl
+ urx = \dim_to_decimal_in_bp:n \l_@@_urx_dim \c_space_tl
+ ury = \dim_to_decimal_in_bp:n \l_@@_ury_dim
+ }
+ }
+\cs_new_eq:NN \@@_backend_include_ps:n \@@_backend_include_eps:n
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_get_pagecount:n}
+% \begin{macrocode}
+\@@_backend_loaded:n
+ { \cs_new_eq:NN \@@_backend_get_pagecount:n \@@_get_pagecount:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \subsection{\LuaTeX{} and \pdfTeX{} backends}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \begin{variable}[no-user-doc]{\l_graphics_search_ext_seq}
+% \begin{macrocode}
+\@@_backend_loaded:n
+ {
+ \seq_set_from_clist:Nn
+ \l_graphics_search_ext_seq
+ { .pdf , .eps , .ps , .png , .jpg , .jpeg }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_attr_tl}
+% In PDF mode, additional attributes of an graphic (such as page number) are
+% needed both to obtain the bounding box and when inserting the graphic: this
+% occurs as the graphic dictionary approach means they are read as part of
+% the bounding box operation. As such, it is easier to track additional
+% attributes using a dedicated |tl| rather than build up the same data
+% twice.
+% \begin{macrocode}
+\tl_new:N \l_@@_attr_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \@@_backend_getbb_jpg:n ,
+% \@@_backend_getbb_jpeg:n ,
+% \@@_backend_getbb_pdf:n ,
+% \@@_backend_getbb_png:n
+% }
+% \begin{macro}
+% {
+% \@@_backend_getbb_auxi:n ,
+% \@@_backend_getbb_auxii:n ,
+% \@@_backend_getbb_auxiii:n
+% }
+% \begin{macro}[EXP]{\@@_backend_dequote:w}
+% Getting the bounding box here requires us to box up the graphic and
+% measure it. To deal with the difference in feature support in bitmap
+% and vector graphics but keeping the common parts, there is a little work
+% to do in terms of auxiliaries. The key here is to notice that we need
+% two forms of the attributes: a \enquote{short} set to allow us to
+% track for caching, and the full form to pass to the primitive.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_getbb_jpg:n #1
+ {
+ \int_zero:N \l_@@_page_int
+ \tl_clear:N \l_@@_pagebox_tl
+ \tl_set:Ne \l_@@_attr_tl
+ {
+ \tl_if_empty:NF \l_@@_decodearray_str
+ { :D \l_@@_decodearray_str }
+ \bool_if:NT \l_@@_interpolate_bool
+ { :I }
+ \str_if_empty:NF \l_@@_pdf_str
+ { :X \l_@@_pdf_str }
+ }
+ \@@_backend_getbb_auxi:n {#1}
+ }
+\cs_new_eq:NN \@@_backend_getbb_jpeg:n \@@_backend_getbb_jpg:n
+\cs_new_eq:NN \@@_backend_getbb_png:n \@@_backend_getbb_jpg:n
+\cs_new_protected:Npn \@@_backend_getbb_pdf:n #1
+ {
+ \tl_clear:N \l_@@_decodearray_str
+ \bool_set_false:N \l_@@_interpolate_bool
+ \tl_set:Ne \l_@@_attr_tl
+ {
+ : \l_@@_pagebox_tl
+ \int_compare:nNnT \l_@@_page_int > 1
+ { :P \int_use:N \l_@@_page_int }
+ \str_if_empty:NF \l_@@_pdf_str
+ { :X \l_@@_pdf_str }
+ }
+ \@@_backend_getbb_auxi:n {#1}
+ }
+\cs_new_protected:Npn \@@_backend_getbb_auxi:n #1
+ {
+ \@@_bb_restore:eF { #1 \l_@@_attr_tl }
+ { \@@_backend_getbb_auxii:n {#1} }
+ }
+% \end{macrocode}
+% Measuring the graphic is done by boxing up: for PDF graphics we could
+% use |\tex_pdfximagebbox:D|, but if doesn't work for other types.
+% As the box always starts at $(0,0)$ there is no need to worry about
+% the lower-left position. Quotes need to be \emph{removed} as \LuaTeX{}
+% does not like them here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_getbb_auxii:n #1
+ {
+ \exp_args:Ne \@@_backend_getbb_auxiii:n
+ { \@@_backend_dequote:w #1 " #1 " \s_@@_stop }
+ \int_const:cn { c_@@_ #1 \l_@@_attr_tl _int }
+ { \tex_the:D \tex_pdflastximage:D }
+ \@@_bb_save:e { #1 \l_@@_attr_tl }
+ }
+\cs_new_protected:Npn \@@_backend_getbb_auxiii:n #1
+ {
+ \tex_immediate:D \tex_pdfximage:D
+ \bool_lazy_any:nT
+ {
+ { \l_@@_interpolate_bool }
+ { ! \tl_if_empty_p:N \l_@@_decodearray_str }
+ { ! \str_if_empty_p:N \l_@@_pdf_str }
+ }
+ {
+ attr ~
+ {
+ \tl_if_empty:NF \l_@@_decodearray_str
+ { /Decode~[ \l_@@_decodearray_str ] }
+ \bool_if:NT \l_@@_interpolate_bool
+ { /Interpolate~true }
+ \l_@@_pdf_str
+ }
+ }
+ \int_compare:nNnT \l_@@_page_int > 0
+ { page ~ \int_use:N \l_@@_page_int }
+ \tl_if_empty:NF \l_@@_pagebox_tl
+ { \l_@@_pagebox_tl }
+ {#1}
+ \hbox_set:Nn \l_@@_internal_box
+ { \tex_pdfrefximage:D \tex_pdflastximage:D }
+ \dim_set:Nn \l_@@_urx_dim { \box_wd:N \l_@@_internal_box }
+ \dim_set:Nn \l_@@_ury_dim { \box_ht:N \l_@@_internal_box }
+ }
+\cs_new:Npn \@@_backend_dequote:w #1 " #2 " #3 \s_@@_stop {#2}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_include_jpg:n ,
+% \@@_backend_include_jpeg:n ,
+% \@@_backend_include_pdf:n ,
+% \@@_backend_include_png:n
+% }
+% Images are already loaded for the measurement part of the code, so
+% inclusion is straight-forward, with only any attributes to worry about. The
+% latter carry through from determination of the bounding box.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_jpg:n #1
+ {
+ \tex_pdfrefximage:D
+ \int_use:c { c_@@_ #1 \l_@@_attr_tl _int }
+ }
+\cs_new_eq:NN \@@_backend_include_jpeg:n \@@_backend_include_jpg:n
+\cs_new_eq:NN \@@_backend_include_pdf:n \@@_backend_include_jpg:n
+\cs_new_eq:NN \@@_backend_include_png:n \@@_backend_include_jpg:n
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_getbb_eps:n, \@@_backend_getbb_ps:n}
+% \begin{macro}{\@@_backend_getbb_eps:nm}
+% \begin{macro}{\@@_backend_include_eps:n, \@@_backend_include_ps:n}
+% \begin{variable}
+% {\l_@@_backend_dir_str, \l_@@_backend_name_str, \l_@@_backend_ext_str}
+% EPS graphics may be included in \LuaTeX{}/pdfTeX{} by conversion to
+% PDF: this requires restricted shell escape. Modelled on the \pkg{epstopdf}
+% \LaTeXe{} package, but simplified, conversion takes place here if we have
+% shell access.
+% \begin{macrocode}
+\sys_if_shell:T
+ {
+ \str_new:N \l_@@_backend_dir_str
+ \str_new:N \l_@@_backend_name_str
+ \str_new:N \l_@@_backend_ext_str
+ \cs_new_protected:Npn \@@_backend_getbb_eps:n #1
+ {
+ \file_parse_full_name:nNNN {#1}
+ \l_@@_backend_dir_str
+ \l_@@_backend_name_str
+ \l_@@_backend_ext_str
+ \exp_args:Ne \@@_backend_getbb_eps:nn
+ {
+ \exp_args:Ne \__kernel_file_name_quote:n
+ {
+ \l_@@_backend_name_str
+ - \str_tail:N \l_@@_backend_ext_str
+ -converted-to.pdf
+ }
+ }
+ {#1}
+ }
+ \cs_new_eq:NN \@@_backend_getbb_ps:n \@@_backend_getbb_eps:n
+ \cs_new_protected:Npn \@@_backend_getbb_eps:nn #1#2
+ {
+ \file_compare_timestamp:nNnT {#2} > {#1}
+ {
+ \sys_shell_now:n
+ { repstopdf ~ #2 ~ #1 }
+ }
+ \tl_set:Nn \l_@@_final_name_str {#1}
+ \@@_backend_getbb_pdf:n {#1}
+ }
+ \cs_new_protected:Npn \@@_backend_include_eps:n #1
+ {
+ \file_parse_full_name:nNNN {#1}
+ \l_@@_backend_dir_str \l_@@_backend_name_str \l_@@_backend_ext_str
+ \exp_args:Ne \@@_backend_include_pdf:n
+ {
+ \exp_args:Ne \__kernel_file_name_quote:n
+ {
+ \l_@@_backend_name_str
+ - \str_tail:N \l_@@_backend_ext_str
+ -converted-to.pdf
+ }
+ }
+ }
+ \cs_new_eq:NN \@@_backend_include_ps:n \@@_backend_include_eps:n
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_get_pagecount:n}
+% Simply load and store.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_get_pagecount:n #1
+ {
+ \tex_pdfximage:D {#1}
+ \int_const:cn { c_@@_ #1 _pages_int }
+ { \int_use:N \tex_pdflastximagepages:D }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvipdfmx} backend}
+%
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \begin{variable}[no-user-doc]{\l_graphics_search_ext_seq}
+% \begin{macrocode}
+\@@_backend_loaded:n
+ {
+ \seq_set_from_clist:Nn \l_graphics_search_ext_seq
+ { .pdf , .eps , .ps , .png , .jpg , .jpeg , .bmp }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \@@_backend_getbb_eps:n , \@@_backend_getbb_ps:n ,
+% \@@_backend_getbb_jpg:n , \@@_backend_getbb_jpeg:n ,
+% \@@_backend_getbb_pdf:n , \@@_backend_getbb_png:n ,
+% \@@_backend_getbb_bmp:n
+% }
+% Simply use the generic functions: only for \texttt{dvipdfmx} in the
+% extraction cases.
+% \begin{macrocode}
+\@@_backend_loaded:n
+ {
+ \cs_new_eq:NN \@@_backend_getbb_eps:n \@@_read_bb:n
+ \cs_new_eq:NN \@@_backend_getbb_ps:n \@@_read_bb:n
+ }
+%<*dvipdfmx>
+\cs_new_protected:Npn \@@_backend_getbb_jpg:n #1
+ {
+ \int_zero:N \l_@@_page_int
+ \tl_clear:N \l_@@_pagebox_tl
+ \@@_extract_bb:n {#1}
+ }
+\cs_new_eq:NN \@@_backend_getbb_jpeg:n \@@_backend_getbb_jpg:n
+\cs_new_eq:NN \@@_backend_getbb_png:n \@@_backend_getbb_jpg:n
+\cs_new_eq:NN \@@_backend_getbb_bmp:n \@@_backend_getbb_jpg:n
+\cs_new_protected:Npn \@@_backend_getbb_pdf:n #1
+ {
+ \tl_clear:N \l_@@_decodearray_str
+ \bool_set_false:N \l_@@_interpolate_bool
+ \@@_extract_bb:n {#1}
+ }
+%</dvipdfmx>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_track_int}
+% Used to track the object number associated with each graphic.
+% \begin{macrocode}
+\int_new:N \g_@@_track_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \@@_backend_include_eps:n , \@@_backend_include_ps:n ,
+% \@@_backend_include_jpg:n , \@@_backend_include_jpseg:n ,
+% \@@_backend_include_pdf:n , \@@_backend_include_png:n ,
+% \@@_backend_include_bmp:n ,
+% }
+% \begin{macro}{\@@_backend_include_auxi:nn}
+% \begin{macro}{\@@_backend_include_auxii:nnn, \@@_backend_include_auxii:enn}
+% \begin{macro}{\@@_backend_include_auxiii:nnn}
+% The special syntax depends on the file type. There is a difference in
+% how PDF graphics are best handled between |dvipdfmx| and \XeTeX{}: for
+% the latter it is better to use the primitive route. The relevant code for
+% that is included later in this file.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_eps:n #1
+ {
+ \__kernel_backend_literal:e
+ {
+ PSfile = #1 \c_space_tl
+ llx = \dim_to_decimal_in_bp:n \l_@@_llx_dim \c_space_tl
+ lly = \dim_to_decimal_in_bp:n \l_@@_lly_dim \c_space_tl
+ urx = \dim_to_decimal_in_bp:n \l_@@_urx_dim \c_space_tl
+ ury = \dim_to_decimal_in_bp:n \l_@@_ury_dim
+ }
+ }
+\cs_new_eq:NN \@@_backend_include_ps:n \@@_backend_include_eps:n
+\cs_new_protected:Npn \@@_backend_include_jpg:n #1
+ { \@@_backend_include_auxi:nn {#1} { image } }
+\cs_new_eq:NN \@@_backend_include_jpeg:n \@@_backend_include_jpg:n
+\cs_new_eq:NN \@@_backend_include_png:n \@@_backend_include_jpg:n
+\cs_new_eq:NN \@@_backend_include_bmp:n \@@_backend_include_jpg:n
+%<*dvipdfmx>
+\cs_new_protected:Npn \@@_backend_include_pdf:n #1
+ { \@@_backend_include_auxi:nn {#1} { epdf } }
+%</dvipdfmx>
+% \end{macrocode}
+% Graphic inclusion is set up to use the fact that each image is stored in
+% the PDF as an XObject. This means that we can include repeated images
+% only once and refer to them. To allow that, track the nature of each
+% image: much the same as for the direct PDF mode case.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_auxi:nn #1#2
+ {
+ \@@_backend_include_auxii:enn
+ {
+ \tl_if_empty:NF \l_@@_pagebox_tl
+ { : \l_@@_pagebox_tl }
+ \int_compare:nNnT \l_@@_page_int > 1
+ { :P \int_use:N \l_@@_page_int }
+ \tl_if_empty:NF \l_@@_decodearray_str
+ { :D \l_@@_decodearray_str }
+ \bool_if:NT \l_@@_interpolate_bool
+ { :I }
+ }
+ {#1} {#2}
+ }
+\cs_new_protected:Npn \@@_backend_include_auxii:nnn #1#2#3
+ {
+ \int_if_exist:cTF { c_@@_ #2#1 _int }
+ {
+ \__kernel_backend_literal:e
+ { pdf:usexobj~@graphic \int_use:c { c_@@_ #2#1 _int } }
+ }
+ { \@@_backend_include_auxiii:nnn {#2} {#1} {#3} }
+ }
+\cs_generate_variant:Nn \@@_backend_include_auxii:nnn { e }
+% \end{macrocode}
+% Inclusion using the specials is relatively straight-forward, but there
+% is one wrinkle. To get the |pagebox| correct for PDF graphics in all cases,
+% it is necessary to provide both that information and the |bbox| argument:
+% odd things happen otherwise!
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_auxiii:nnn #1#2#3
+ {
+ \int_gincr:N \g_@@_track_int
+ \int_const:cn { c_@@_ #1#2 _int } { \g_@@_track_int }
+ \__kernel_backend_literal:e
+ {
+ pdf:#3~
+ @graphic \int_use:c { c_@@_ #1#2 _int } ~
+ \int_compare:nNnT \l_@@_page_int > 1
+ { page ~ \int_use:N \l_@@_page_int \c_space_tl }
+ \tl_if_empty:NF \l_@@_pagebox_tl
+ {
+ pagebox ~ \l_@@_pagebox_tl \c_space_tl
+ bbox ~
+ \dim_to_decimal_in_bp:n \l_@@_llx_dim \c_space_tl
+ \dim_to_decimal_in_bp:n \l_@@_lly_dim \c_space_tl
+ \dim_to_decimal_in_bp:n \l_@@_urx_dim \c_space_tl
+ \dim_to_decimal_in_bp:n \l_@@_ury_dim \c_space_tl
+ }
+ (#1)
+ \bool_lazy_or:nnT
+ { \l_@@_interpolate_bool }
+ { ! \tl_if_empty_p:N \l_@@_decodearray_str }
+ {
+ <<
+ \tl_if_empty:NF \l_@@_decodearray_str
+ { /Decode~[ \l_@@_decodearray_str ] }
+ \bool_if:NT \l_@@_interpolate_bool
+ { /Interpolate~true }
+ >>
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_get_pagecount:n}
+% \begin{macrocode}
+%<*dvipdfmx>
+\@@_backend_loaded:n
+ { \cs_new_eq:NN \@@_backend_get_pagecount:n \@@_get_pagecount:n }
+%</dvipdfmx>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \subsection{\XeTeX{} backend}
+%
+% \begin{macrocode}
+%<*xetex>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_getbb_jpg:n ,
+% \@@_backend_getbb_jpeg:n ,
+% \@@_backend_getbb_pdf:n ,
+% \@@_backend_getbb_png:n ,
+% \@@_backend_getbb_bmp:n
+% }
+% \begin{macro}{\@@_backend_getbb_auxi:nN}
+% \begin{macro}{\@@_backend_getbb_auxii:nnN, \@@_backend_getbb_auxii:VnN}
+% \begin{macro}{\@@_backend_getbb_auxiii:nNnn}
+% \begin{macro}{\@@_backend_getbb_auxiv:nnNnn, \@@_backend_getbb_auxiv:VnNnn}
+% \begin{macro}{\@@_backend_getbb_auxv:nNnn, \@@_backend_getbb_auxv:nNnn}
+% \begin{macro}[EXP]{\@@_backend_getbb_pagebox:w}
+% For \XeTeX{}, there are two primitives that allow us to obtain
+% the bounding box without needing \texttt{extractbb}. The only complexity
+% is passing the various minor variations to a common core process. The
+% \XeTeX{} primitive omits the text |box| from the page box specification,
+% so there is also some \enquote{trimming} to do here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_getbb_jpg:n #1
+ {
+ \int_zero:N \l_@@_page_int
+ \tl_clear:N \l_@@_pagebox_tl
+ \@@_backend_getbb_auxi:nN {#1} \tex_XeTeXpicfile:D
+ }
+\cs_new_eq:NN \@@_backend_getbb_jpeg:n \@@_backend_getbb_jpg:n
+\cs_new_eq:NN \@@_backend_getbb_png:n \@@_backend_getbb_jpg:n
+\cs_new_eq:NN \@@_backend_getbb_bmp:n \@@_backend_getbb_jpg:n
+\cs_new_protected:Npn \@@_backend_getbb_pdf:n #1
+ {
+ \tl_clear:N \l_@@_decodearray_str
+ \bool_set_false:N \l_@@_interpolate_bool
+ \@@_backend_getbb_auxi:nN {#1} \tex_XeTeXpdffile:D
+ }
+\cs_new_protected:Npn \@@_backend_getbb_auxi:nN #1#2
+ {
+ \int_compare:nNnTF \l_@@_page_int > 1
+ { \@@_backend_getbb_auxii:VnN \l_@@_page_int {#1} #2 }
+ { \@@_backend_getbb_auxiii:nNnn {#1} #2 { :P 1 } { page 1 } }
+ }
+\cs_new_protected:Npn \@@_backend_getbb_auxii:nnN #1#2#3
+ { \@@_backend_getbb_auxiii:nNnn {#2} #3 { :P #1 } { page #1 } }
+\cs_generate_variant:Nn \@@_backend_getbb_auxii:nnN { V }
+\cs_new_protected:Npn \@@_backend_getbb_auxiii:nNnn #1#2#3#4
+ {
+ \tl_if_empty:NTF \l_@@_pagebox_tl
+ { \@@_backend_getbb_auxiv:VnNnn \l_@@_pagebox_tl }
+ { \@@_backend_getbb_auxv:nNnn }
+ {#1} #2 {#3} {#4}
+ }
+\cs_new_protected:Npn \@@_backend_getbb_auxiv:nnNnn #1#2#3#4#5
+ {
+ \use:e
+ {
+ \@@_backend_getbb_auxv:nNnn {#2} #3 { : #1 #4 }
+ {
+ #5
+ \tl_if_blank:nF {#1}
+ { \c_space_tl \@@_backend_getbb_pagebox:w #1 }
+ }
+ }
+ }
+\cs_generate_variant:Nn \@@_backend_getbb_auxiv:nnNnn { V }
+\cs_new_protected:Npn \@@_backend_getbb_auxv:nNnn #1#2#3#4
+ {
+ \@@_bb_restore:nF {#1#3}
+ { \@@_backend_getbb_auxvi:nNnn {#1} #2 {#3} {#4} }
+ }
+\cs_new_protected:Npn \@@_backend_getbb_auxvi:nNnn #1#2#3#4
+ {
+ \hbox_set:Nn \l_@@_internal_box { #2 #1 ~ #4 }
+ \dim_set:Nn \l_@@_urx_dim { \box_wd:N \l_@@_internal_box }
+ \dim_set:Nn \l_@@_ury_dim { \box_ht:N \l_@@_internal_box }
+ \@@_bb_save:n {#1#3}
+ }
+\cs_new:Npn \@@_backend_getbb_pagebox:w #1 box {#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_include_pdf:n}
+% For PDF graphics, properly supporting the |pagebox| concept in \XeTeX{}
+% is best done using the |\tex_XeTeXpdffile:D| primitive. The syntax here
+% is the same as for the graphic measurement part, although we know at this
+% stage that there must be some valid setting for \cs{l_@@_pagebox_tl}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_pdf:n #1
+ {
+ \tex_XeTeXpdffile:D #1 ~
+ \int_compare:nNnT \l_@@_page_int > 0
+ { page ~ \int_use:N \l_@@_page_int \c_space_tl }
+ \exp_after:wN \@@_backend_getbb_pagebox:w \l_@@_pagebox_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_get_pagecount:n}
+% Very little to do here other than cover the case of a non-PDF file.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_get_pagecount:n #1
+ {
+ \int_const:cn { c_@@_ #1 _pages_int }
+ {
+ \int_max:nn
+ { \int_use:N \tex_XeTeXpdfpagecount:D #1 ~ }
+ { 1 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</xetex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvisvgm} backend}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{variable}[no-user-doc]{\l_graphics_search_ext_seq}
+% \begin{macrocode}
+\@@_backend_loaded:n
+ {
+ \seq_set_from_clist:Nn
+ \l_graphics_search_ext_seq
+ { .svg , .pdf , .eps , .ps , .png , .jpg , .jpeg }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_backend_getbb_svg:n}
+% \begin{macro}{\@@_backend_getbb_svg_auxi:nNn}
+% \begin{macro}{\@@_backend_getbb_svg_auxii:w}
+% \begin{macro}
+% {
+% \@@_backend_getbb_svg_auxiii:Nw ,
+% \@@_backend_getbb_svg_auxiv:Nw ,
+% \@@_backend_getbb_svg_auxv:Nw
+% }
+% \begin{macro}{\@@_backend_getbb_svg_auxvi:Nn}
+% \begin{macro}{\@@_backend_getbb_svg_auxvii:w}
+% This is relatively similar to reading bounding boxes for |.eps| files. Life
+% is though made more tricky as we cannot pick a single line for the data. So
+% we have to loop until we collect up both height and width. To do that, we
+% can use a marker value. We also have to allow for the default units of the
+% lengths: they are big points and may be omitted.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_getbb_svg:n #1
+ {
+ \@@_bb_restore:nF {#1}
+ {
+ \ior_open:Nn \l_@@_internal_ior {#1}
+ \ior_if_eof:NTF \l_@@_internal_ior
+ { \msg_error:nnn { graphics } { graphic-not-found } {#1} }
+ {
+ \dim_zero:N \l_@@_llx_dim
+ \dim_zero:N \l_@@_lly_dim
+ \dim_set:Nn \l_@@_urx_dim { -\c_max_dim }
+ \dim_set:Nn \l_@@_ury_dim { -\c_max_dim }
+ \ior_str_map_inline:Nn \l_@@_internal_ior
+ {
+ \dim_compare:nNnT \l_@@_urx_dim = { -\c_max_dim }
+ {
+ \@@_backend_getbb_svg_auxi:nNn
+ { width } \l_@@_urx_dim {##1}
+ }
+ \dim_compare:nNnT \l_@@_ury_dim = { -\c_max_dim }
+ {
+ \@@_backend_getbb_svg_auxi:nNn
+ { height } \l_@@_ury_dim {##1}
+ }
+ \bool_lazy_and:nnF
+ { \dim_compare_p:nNn \l_@@_urx_dim = { -\c_max_dim } }
+ { \dim_compare_p:nNn \l_@@_ury_dim = { -\c_max_dim } }
+ { \ior_map_break: }
+ }
+ \@@_bb_save:n {#1}
+ }
+ \ior_close:N \l_@@_internal_ior
+ }
+ }
+\cs_new_protected:Npn \@@_backend_getbb_svg_auxi:nNn #1#2#3
+ {
+ \use:e
+ {
+ \cs_set_protected:Npn \@@_backend_getbb_svg_auxii:w
+ ##1 \tl_to_str:n {#1} = ##2 \tl_to_str:n {#1} = ##3
+ \s_@@_stop
+ }
+ {
+ \tl_if_blank:nF {##2}
+ {
+ \peek_remove_spaces:n
+ {
+ \peek_meaning:NTF ' % '
+ { \@@_backend_getbb_svg_auxiii:Nw #2 }
+ {
+ \peek_meaning:NTF " % "
+ { \@@_backend_getbb_svg_auxiv:Nw #2 }
+ { \@@_backend_getbb_svg_auxv:Nw #2 }
+ }
+ }
+ ##2 \s_@@_stop
+ }
+ }
+ \use:e
+ {
+ \@@_backend_getbb_svg_auxii:w #3
+ \tl_to_str:n {#1} = \tl_to_str:n {#1} =
+ \s_@@_stop
+ }
+ }
+\cs_new_protected:Npn \@@_backend_getbb_svg_auxii:w { }
+\cs_new_protected:Npn \@@_backend_getbb_svg_auxiii:Nw #1 ' #2 ' #3 \s_@@_stop
+ { \@@_backend_getbb_svg_auxvi:Nn #1 {#2} }
+\cs_new_protected:Npn \@@_backend_getbb_svg_auxiv:Nw #1 " #2 " #3 \s_@@_stop
+ { \@@_backend_getbb_svg_auxvi:Nn #1 {#2} }
+\cs_new_protected:Npn \@@_backend_getbb_svg_auxv:Nw #1 #2 ~ #3 \s_@@_stop
+ { \@@_backend_getbb_svg_auxvi:Nn #1 {#2} }
+\cs_new_protected:Npn \@@_backend_getbb_svg_auxvi:Nn #1#2
+ {
+ \tex_afterassignment:D \@@_backend_getbb_svg_auxvii:w
+ \l_@@_internal_dim #2 bp \scan_stop:
+ \dim_set_eq:NN #1 \l_@@_internal_dim
+ }
+\cs_new_protected:Npn \@@_backend_getbb_svg_auxvii:w #1 \scan_stop: { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_getbb_eps:n, \@@_backend_getbb_ps:n}
+% Simply use the generic function.
+% \begin{macrocode}
+\@@_backend_loaded:n
+ {
+ \cs_new_eq:NN \@@_backend_getbb_eps:n \@@_read_bb:n
+ \cs_new_eq:NN \@@_backend_getbb_ps:n \@@_read_bb:n
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_getbb_png:n, \@@_backend_getbb_jpg:n, \@@_backend_getbb_jpeg:n}
+% These can be included by extracting the bounding box data.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_getbb_jpg:n #1
+ {
+ \int_zero:N \l_@@_page_int
+ \tl_clear:N \l_@@_pagebox_tl
+ \@@_extract_bb:n {#1}
+ }
+\cs_new_eq:NN \@@_backend_getbb_jpeg:n \@@_backend_getbb_jpg:n
+\cs_new_eq:NN \@@_backend_getbb_png:n \@@_backend_getbb_jpg:n
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_getbb_pdf:n}
+% Same as for \texttt{dvipdfmx}: use the generic function
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_getbb_pdf:n #1
+ {
+ \tl_clear:N \l_@@_decodearray_str
+ \bool_set_false:N \l_@@_interpolate_bool
+ \@@_extract_bb:n {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_include_eps:n ,
+% \@@_backend_include_ps:n ,
+% \@@_backend_include_pdf:n
+% }
+% \begin{macro}{\@@_backend_include:nn}
+% The special syntax is relatively clear here: remember we need PostScript
+% sizes here. (This is the same as the \texttt{dvips} code.)
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_eps:n #1
+ { \@@_backend_include:nn { PSfile } {#1} }
+\cs_new_eq:NN \@@_backend_include_ps:n \@@_backend_include_eps:n
+\cs_new_protected:Npn \@@_backend_include_pdf:n #1
+ { \@@_backend_include:nn { pdffile } {#1} }
+\cs_new_protected:Npn \@@_backend_include:nn #1#2
+ {
+ \__kernel_backend_literal:e
+ {
+ #1 = #2 \c_space_tl
+ llx = \dim_to_decimal_in_bp:n \l_@@_llx_dim \c_space_tl
+ lly = \dim_to_decimal_in_bp:n \l_@@_lly_dim \c_space_tl
+ urx = \dim_to_decimal_in_bp:n \l_@@_urx_dim \c_space_tl
+ ury = \dim_to_decimal_in_bp:n \l_@@_ury_dim
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_include_svg:n ,
+% \@@_backend_include_png:n ,
+% \@@_backend_include_jpg:n ,
+% \@@_backend_include_jpeg:n
+% }
+% \begin{macro}{\@@_backend_include_dequote:w}
+% The backend here has built-in support for basic graphic inclusion (see
+% \texttt{dvisvgm.def} for a more complex approach, needed if clipping,
+% \emph{etc.}, is covered at the graphic backend level). We have to deal
+% with the fact that the image reference point is at the \emph{top}, so
+% there is a need for a vertical shift to put it in the right place.
+% The other issue is that |#1| must be quote-corrected. The
+% \texttt{dvisvgm:img} operation quotes the file name, but if it is already
+% quoted (contains spaces) then we have an issue: we simply strip off any
+% quotes as a result.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_include_svg:n #1
+ {
+ \box_move_up:nn { \l_@@_ury_dim }
+ {
+ \hbox:n
+ {
+ \__kernel_backend_literal:e
+ {
+ dvisvgm:img~
+ \dim_to_decimal:n { \l_@@_urx_dim } ~
+ \dim_to_decimal:n { \l_@@_ury_dim } ~
+ \@@_backend_include_dequote:w #1 " #1 " \s_@@_stop
+ }
+ }
+ }
+ }
+\cs_new_eq:NN \@@_backend_include_png:n \@@_backend_include_svg:n
+\cs_new_eq:NN \@@_backend_include_jpeg:n \@@_backend_include_svg:n
+\cs_new_eq:NN \@@_backend_include_jpg:n \@@_backend_include_svg:n
+\cs_new:Npn \@@_backend_include_dequote:w #1 " #2 " #3 \s_@@_stop
+ {#2}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_get_pagecount:n}
+% \begin{macrocode}
+\@@_backend_loaded:n
+ { \cs_new_eq:NN \@@_backend_get_pagecount:n \@@_get_pagecount:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3backend/l3backend-header.dtx b/macros/latex-dev/required/l3backend/l3backend-header.dtx
new file mode 100644
index 0000000000..486f564822
--- /dev/null
+++ b/macros/latex-dev/required/l3backend/l3backend-header.dtx
@@ -0,0 +1,590 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-header.dtx
+%
+% Copyright (C) 2019-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3backend bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3backend-header} module\\ Backend graphics support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-header} implementation}
+%
+% \begin{macrocode}
+%<*dvips&header>
+% \end{macrocode}
+%
+% \begin{macro}[no-user-doc]{color.sc}
+% Empty definition for color at the top level.
+% \begin{macrocode}
+/color.sc { } def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{TeXcolorseparation, separation}
+% Support for separation/spot colors: this strange naming is so
+% things work with the color stack.
+% \begin{macrocode}
+TeXDict begin
+/TeXcolorseparation { setcolor } def
+end
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{pdf.globaldict}
+% A small global dictionary for backend use.
+% \begin{macrocode}
+true setglobal
+/pdf.globaldict 4 dict def
+false setglobal
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% pdf.cvs ,
+% pdf.dvi.pt ,
+% pdf.pt.dvi ,
+% pdf.rect.ht
+% }
+% Small utilities for PostScript manipulations. Conversion to DVI dimensions
+% is done here to allow for |Resolution|. The total height of a rectangle
+% (an array) needs a little maths, in contrast to simply extracting a value.
+% \begin{macrocode}
+/pdf.cvs { 65534 string cvs } def
+/pdf.dvi.pt { 72.27 mul Resolution div } def
+/pdf.pt.dvi { 72.27 div Resolution mul } def
+/pdf.rect.ht { dup 1 get neg exch 3 get add } def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{pdf.linkmargin, pdf.linkdp.pad, pdf.linkht.pad}
+% Settings which are defined up-front in |SDict|.
+% \begin{macrocode}
+/pdf.linkmargin { 1 pdf.pt.dvi } def
+/pdf.linkdp.pad { 0 } def
+/pdf.linkht.pad { 0 } def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% pdf.rect ,
+% pdf.save.ll ,
+% pdf.save.ur ,
+% pdf.save.linkll ,
+% pdf.save.linkur ,
+% pdf.llx ,
+% pdf.lly ,
+% pdf.urx ,
+% pdf.ury
+% }
+% Functions for marking the limits of an annotation/link, plus drawing the
+% border. We separate links for generic annotations to support adding a
+% margin and setting a minimal size.
+% \begin{macrocode}
+/pdf.rect
+ { /Rect [ pdf.llx pdf.lly pdf.urx pdf.ury ] } def
+/pdf.save.ll
+ {
+ currentpoint
+ /pdf.lly exch def
+ /pdf.llx exch def
+ }
+ def
+/pdf.save.ur
+ {
+ currentpoint
+ /pdf.ury exch def
+ /pdf.urx exch def
+ }
+ def
+/pdf.save.linkll
+ {
+ currentpoint
+ pdf.linkmargin add
+ pdf.linkdp.pad add
+ /pdf.lly exch def
+ pdf.linkmargin sub
+ /pdf.llx exch def
+ }
+ def
+/pdf.save.linkur
+ {
+ currentpoint
+ pdf.linkmargin sub
+ pdf.linkht.pad sub
+ /pdf.ury exch def
+ pdf.linkmargin add
+ /pdf.urx exch def
+ }
+ def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% pdf.dest.anchor ,
+% pdf.dest.x ,
+% pdf.dest.y ,
+% pdf.dest.point ,
+% pdf.dest2device ,
+% pdf.dev.x ,
+% pdf.dev.y ,
+% pdf.tmpa ,
+% pdf.tmpb ,
+% pdf.tmpc ,
+% pdf.tmpd
+% }
+% For finding the anchor point of a destination link. We make the use case
+% a separate function as it comes up a lot, and as this makes it easier to
+% adjust if we need additional effects. We also need a more complex approach
+% to convert a co-ordinate pair correctly when defining a rectangle: this
+% can otherwise be out when using a landscape page. (Thanks to Alexander
+% Grahn for the approach here.)
+% \begin{macrocode}
+/pdf.dest.anchor
+ {
+ currentpoint exch
+ pdf.dvi.pt 72 add
+ /pdf.dest.x exch def
+ pdf.dvi.pt
+ vsize 72 sub exch sub
+ /pdf.dest.y exch def
+ }
+ def
+/pdf.dest.point
+ { pdf.dest.x pdf.dest.y } def
+/pdf.dest2device
+ {
+ /pdf.dest.y exch def
+ /pdf.dest.x exch def
+ matrix currentmatrix
+ matrix defaultmatrix
+ matrix invertmatrix
+ matrix concatmatrix
+ cvx exec
+ /pdf.dev.y exch def
+ /pdf.dev.x exch def
+ /pdf.tmpd exch def
+ /pdf.tmpc exch def
+ /pdf.tmpb exch def
+ /pdf.tmpa exch def
+ pdf.dest.x pdf.tmpa mul
+ pdf.dest.y pdf.tmpc mul add
+ pdf.dev.x add
+ pdf.dest.x pdf.tmpb mul
+ pdf.dest.y pdf.tmpd mul add
+ pdf.dev.y add
+ }
+ def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% pdf.bordertracking ,
+% pdf.bordertracking.begin ,
+% pdf.bordertracking.end ,
+% pdf.leftboundary ,
+% pdf.rightboundary ,
+% pdf.brokenlink.rect ,
+% pdf.brokenlink.skip ,
+% pdf.brokenlink.dict ,
+% pdf.bordertracking.endpage ,
+% pdf.bordertracking.continue ,
+% pdf.originx ,
+% pdf.originy
+% }
+% To know where a breakable link can go, we need to track the boundary
+% rectangle. That can be done by hooking into |a| and |x| operations:
+% those names have to be retained. The boundary is stored at the end of
+% the operation. Special effort is needed at the start and end of pages
+% (or rather galleys), such that everything works properly.
+% \begin{macrocode}
+/pdf.bordertracking false def
+/pdf.bordertracking.begin
+ {
+ SDict /pdf.bordertracking true put
+ SDict /pdf.leftboundary undef
+ SDict /pdf.rightboundary undef
+ /a where
+ {
+ /a
+ {
+ currentpoint pop
+ SDict /pdf.rightboundary known dup
+ {
+ SDict /pdf.rightboundary get 2 index lt
+ { not }
+ if
+ }
+ if
+ { pop }
+ { SDict exch /pdf.rightboundary exch put }
+ ifelse
+ moveto
+ currentpoint pop
+ SDict /pdf.leftboundary known dup
+ {
+ SDict /pdf.leftboundary get 2 index gt
+ { not }
+ if
+ }
+ if
+ { pop }
+ { SDict exch /pdf.leftboundary exch put }
+ ifelse
+ }
+ put
+ }
+ if
+ }
+ def
+/pdf.bordertracking.end
+ {
+ /a where { /a { moveto } put } if
+ /x where { /x { 0 exch rmoveto } put } if
+ SDict /pdf.leftboundary known
+ { pdf.outerbox 0 pdf.leftboundary put }
+ if
+ SDict /pdf.rightboundary known
+ { pdf.outerbox 2 pdf.rightboundary put }
+ if
+ SDict /pdf.bordertracking false put
+ }
+ def
+ /pdf.bordertracking.endpage
+{
+ pdf.bordertracking
+ {
+ pdf.bordertracking.end
+ true setglobal
+ pdf.globaldict
+ /pdf.brokenlink.rect [ pdf.outerbox aload pop ] put
+ pdf.globaldict
+ /pdf.brokenlink.skip pdf.baselineskip put
+ pdf.globaldict
+ /pdf.brokenlink.dict
+ pdf.link.dict pdf.cvs put
+ false setglobal
+ mark pdf.link.dict cvx exec /Rect
+ [
+ pdf.llx
+ pdf.lly
+ pdf.outerbox 2 get pdf.linkmargin add
+ currentpoint exch pop
+ pdf.outerbox pdf.rect.ht sub pdf.linkmargin sub
+ ]
+ /ANN pdf.pdfmark
+ }
+ if
+}
+ def
+/pdf.bordertracking.continue
+ {
+ /pdf.link.dict pdf.globaldict
+ /pdf.brokenlink.dict get def
+ /pdf.outerbox pdf.globaldict
+ /pdf.brokenlink.rect get def
+ /pdf.baselineskip pdf.globaldict
+ /pdf.brokenlink.skip get def
+ pdf.globaldict dup dup
+ /pdf.brokenlink.dict undef
+ /pdf.brokenlink.skip undef
+ /pdf.brokenlink.rect undef
+ currentpoint
+ /pdf.originy exch def
+ /pdf.originx exch def
+ /a where
+ {
+ /a
+ {
+ moveto
+ SDict
+ begin
+ currentpoint pdf.originy ne exch
+ pdf.originx ne or
+ {
+ pdf.save.linkll
+ /pdf.lly
+ pdf.lly pdf.outerbox 1 get sub def
+ pdf.bordertracking.begin
+ }
+ if
+ end
+ }
+ put
+ }
+ if
+ /x where
+ {
+ /x
+ {
+ 0 exch rmoveto
+ SDict
+ begin
+ currentpoint
+ pdf.originy ne exch pdf.originx ne or
+ {
+ pdf.save.linkll
+ /pdf.lly
+ pdf.lly pdf.outerbox 1 get sub def
+ pdf.bordertracking.begin
+ }
+ if
+ end
+ }
+ put
+ }
+ if
+ }
+ def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% pdf.breaklink ,
+% pdf.breaklink.write ,
+% pdf.count ,
+% pdf.currentrect
+% }
+% Dealing with link breaking itself has multiple stage. The first step is to
+% find the |Rect| entry in the dictionary, looping over key--value pairs.
+% The first line is handled first, adjusting the rectangle to stay inside the
+% text area. The second phase is a loop over the height of the bulk of the
+% link area, done on the basis of a number of baselines. Finally, the end of
+% the link area is tidied up, again from the boundary of the text area.
+% \begin{macrocode}
+/pdf.breaklink
+ {
+ pop
+ counttomark 2 mod 0 eq
+ {
+ counttomark /pdf.count exch def
+ {
+ pdf.count 0 eq { exit } if
+ counttomark 2 roll
+ 1 index /Rect eq
+ {
+ dup 4 array copy
+ dup dup
+ 1 get
+ pdf.outerbox pdf.rect.ht
+ pdf.linkmargin 2 mul add sub
+ 3 exch put
+ dup
+ pdf.outerbox 2 get
+ pdf.linkmargin add
+ 2 exch put
+ dup dup
+ 3 get
+ pdf.outerbox pdf.rect.ht
+ pdf.linkmargin 2 mul add add
+ 1 exch put
+ /pdf.currentrect exch def
+ pdf.breaklink.write
+ {
+ pdf.currentrect
+ dup
+ pdf.outerbox 0 get
+ pdf.linkmargin sub
+ 0 exch put
+ dup
+ pdf.outerbox 2 get
+ pdf.linkmargin add
+ 2 exch put
+ dup dup
+ 1 get
+ pdf.baselineskip add
+ 1 exch put
+ dup dup
+ 3 get
+ pdf.baselineskip add
+ 3 exch put
+ /pdf.currentrect exch def
+ pdf.breaklink.write
+ }
+ 1 index 3 get
+ pdf.linkmargin 2 mul add
+ pdf.outerbox pdf.rect.ht add
+ 2 index 1 get sub
+ pdf.baselineskip div round cvi 1 sub
+ exch
+ repeat
+ pdf.currentrect
+ dup
+ pdf.outerbox 0 get
+ pdf.linkmargin sub
+ 0 exch put
+ dup dup
+ 1 get
+ pdf.baselineskip add
+ 1 exch put
+ dup dup
+ 3 get
+ pdf.baselineskip add
+ 3 exch put
+ dup 2 index 2 get 2 exch put
+ /pdf.currentrect exch def
+ pdf.breaklink.write
+ SDict /pdf.pdfmark.good false put
+ exit
+ }
+ { pdf.count 2 sub /pdf.count exch def }
+ ifelse
+ }
+ loop
+ }
+ if
+ /ANN
+ }
+ def
+/pdf.breaklink.write
+ {
+ counttomark 1 sub
+ index /_objdef eq
+ {
+ counttomark -2 roll
+ dup wcheck
+ {
+ readonly
+ counttomark 2 roll
+ }
+ { pop pop }
+ ifelse
+ }
+ if
+ counttomark 1 add copy
+ pop pdf.currentrect
+ /ANN pdfmark
+ }
+ def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% pdf.pdfmark ,
+% pdf.pdfmark.good ,
+% pdf.outerbox ,
+% pdf.baselineskip ,
+% pdf.pdfmark.dict
+% }
+% The business end of breaking links starts by hooking into |pdfmarks|.
+% Unlike \pkg{hypdvips}, we avoid altering any links we have not created
+% by using a copy of the core |pdfmarks| function. Only mark types which
+% are known are altered. At present, this is purely |ANN| marks, which are
+% measured relative to the size of the baseline skip. If they are
+% more than one apparent line high, breaking is applied.
+% \begin{macrocode}
+/pdf.pdfmark
+ {
+ SDict /pdf.pdfmark.good true put
+ dup /ANN eq
+ {
+ pdf.pdfmark.store
+ pdf.pdfmark.dict
+ begin
+ Subtype /Link eq
+ currentdict /Rect known and
+ SDict /pdf.outerbox known and
+ SDict /pdf.baselineskip known and
+ {
+ Rect 3 get
+ pdf.linkmargin 2 mul add
+ pdf.outerbox pdf.rect.ht add
+ Rect 1 get sub
+ pdf.baselineskip div round cvi 0 gt
+ { pdf.breaklink }
+ if
+ }
+ if
+ end
+ SDict /pdf.outerbox undef
+ SDict /pdf.baselineskip undef
+ currentdict /pdf.pdfmark.dict undef
+ }
+ if
+ pdf.pdfmark.good
+ { pdfmark }
+ { cleartomark }
+ ifelse
+ }
+ def
+/pdf.pdfmark.store
+ {
+ /pdf.pdfmark.dict 65534 dict def
+ counttomark 1 add copy
+ pop
+ {
+ dup mark eq
+ {
+ pop
+ exit
+ }
+ {
+ pdf.pdfmark.dict
+ begin def end
+ }
+ ifelse
+ }
+ loop
+}
+ def
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips&header>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3backend/l3backend-opacity.dtx b/macros/latex-dev/required/l3backend/l3backend-opacity.dtx
new file mode 100644
index 0000000000..0c29574c37
--- /dev/null
+++ b/macros/latex-dev/required/l3backend/l3backend-opacity.dtx
@@ -0,0 +1,353 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-opacity.dtx
+%
+% Copyright (C) 2021-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3backend bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3backend-opacity} module\\ Backend opacity support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-opacity} implementation}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=opacity>
+% \end{macrocode}
+%
+% Although opacity is not color, it needs to be managed in a somewhat
+% similar way: using a dedicated stack if possible. Depending on the backend,
+% that may not be possible. There is also the need to cover fill/stroke setting
+% as well as more general running opacity. It is easiest to describe the value
+% used in terms of opacity, although commonly this is referred to as
+% transparency.
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_select:n}
+% \begin{macro}{\@@_backend_fill:n, \@@_backend_stroke:n}
+% \begin{macro}{\@@_backend:nnn}
+% No stack so set values directly. The need to deal with Distiller and
+% Ghostscript separately means we use a common auxiliary: the two
+% systems require different PostScript for transparency. This is
+% of course not quite as efficient as doing one test for setting all
+% transparency, but it keeps things clearer here. Thanks to Alex Grahn
+% for the detail on testing for GhostScript.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select:n #1
+ {
+ \@@_backend:nnn {#1} { fill } { ca }
+ \@@_backend:nnn {#1} { stroke } { CA }
+ }
+\cs_new_protected:Npn \@@_backend_fill:n #1
+ {
+ \@@_backend:nnn
+ { #1 }
+ { fill }
+ { ca }
+ }
+\cs_new_protected:Npn \@@_backend_stroke:n #1
+ {
+ \@@_backend:nnn
+ { #1 }
+ { stroke }
+ { CA }
+ }
+\cs_new_protected:Npn \@@_backend:nnn #1#2#3
+ {
+ \__kernel_backend_postscript:n
+ {
+ product ~ (Ghostscript) ~ search
+ {
+ pop ~ pop ~ pop ~
+ #1 ~ .set #2 constantalpha
+ }
+ {
+ pop ~
+ mark ~
+ /#3 ~ #1
+ /SetTransparency ~
+ pdfmark
+ }
+ ifelse
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvipdfmx|luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \begin{variable}{\c_@@_backend_stack_int}
+% Set up a stack, where that is applicable.
+% \begin{macrocode}
+\bool_lazy_and:nnT
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+%<*luatex|pdftex>
+ \__kernel_color_backend_stack_init:Nnn \c_@@_backend_stack_int
+ { page ~ direct } { /opacity 1 ~ gs }
+%</luatex|pdftex>
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity 1 } { << /ca ~ 1 /CA ~ 1 >> }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_backend_fill_tl, \l_@@_backend_stroke_tl}
+% We use |tl| here for speed: at the backend, this should be reasonable.
+% Both need to start off fully opaque.
+% \begin{macrocode}
+\tl_new:N \l_@@_backend_fill_tl
+\tl_new:N \l_@@_backend_stroke_tl
+\tl_set:Nn \l_@@_backend_fill_tl { 1 }
+\tl_set:Nn \l_@@_backend_stroke_tl { 1 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_backend_select:n}
+% \begin{macro}{\@@_backend_reset:}
+% Much the same as color.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select:n #1
+ {
+ \tl_set:Nn \l_@@_backend_fill_tl {#1}
+ \tl_set:Nn \l_@@_backend_stroke_tl {#1}
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity #1 }
+ { << /ca ~ #1 /CA ~ #1 >> }
+%<*dvipdfmx|xetex>
+ \__kernel_backend_literal_pdf:n
+%</dvipdfmx|xetex>
+%<*luatex|pdftex>
+ \__kernel_color_backend_stack_push:nn \c_@@_backend_stack_int
+%</luatex|pdftex>
+ { /opacity #1 ~ gs }
+ \group_insert_after:N \@@_backend_reset:
+ }
+\cs_new_protected:Npn \@@_backend_reset:
+ {
+%<*dvipdfmx|xetex>
+ \__kernel_backend_literal_pdf:n
+ { /opacity1 ~ gs }
+%</dvipdfmx|xetex>
+%<*luatex|pdftex>
+ \__kernel_color_backend_stack_pop:n \c_@@_backend_stack_int
+%</luatex|pdftex>
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_fill:n, \@@_backend_stroke:n}
+% \begin{macro}{\@@_backend_fill_stroke:nn}
+% For separate fill and stroke, we need to work out if we need to do
+% more work or if we can stick to a single setting.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill:n #1
+ {
+ \exp_args:Nno \@@_backend_fill_stroke:nn
+ { #1 }
+ { \l_@@_backend_stroke_tl }
+ }
+\cs_new_protected:Npn \@@_backend_stroke:n #1
+ {
+ \exp_args:No \@@_backend_fill_stroke:nn
+ { \l_@@_backend_fill_tl }
+ { #1 }
+ }
+\cs_new_protected:Npn \@@_backend_fill_stroke:nn #1#2
+ {
+ \str_if_eq:nnTF {#1} {#2}
+ { \@@_backend_select:n {#1} }
+ {
+ \tl_set:Nn \l_@@_backend_fill_tl {#1}
+ \tl_set:Nn \l_@@_backend_stroke_tl {#2}
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity.fill #1 }
+ { << /ca ~ #1 >> }
+ \pdfmanagement_add:nnn { Page / Resources / ExtGState }
+ { opacity.stroke #2 }
+ { << /CA ~ #2 >> }
+%<*dvipdfmx|xetex>
+ \__kernel_backend_literal_pdf:n
+%</dvipdfmx|xetex>
+%<*luatex|pdftex>
+ \__kernel_color_backend_stack_push:nn \c_@@_backend_stack_int
+%</luatex|pdftex>
+ { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs }
+ \group_insert_after:N \@@_backend_reset:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_select:n, \@@_backend_fill_stroke:nn}
+% Redefine them to stubs if pdfmanagement is either not loaded or
+% deactivated.
+% \begin{macrocode}
+\bool_lazy_and:nnF
+ { \cs_if_exist_p:N \pdfmanagement_if_active_p: }
+ { \pdfmanagement_if_active_p: }
+ {
+ \cs_gset_protected:Npn \@@_backend_select:n #1 { }
+ \cs_gset_protected:Npn \@@_backend_fill_stroke:nn #1#2 { }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_select:n, \@@_backend_fill:n, \@@_backend_stroke:n}
+% \begin{macro}{\@@_backend:nn}
+% Once again, we use a scope here. There is a general opacity function for
+% SVG, but that is of course not set up using the stack.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select:n #1
+ { \@@_backend:nn {#1} { } }
+\cs_new_protected:Npn \@@_backend_fill:n #1
+ { \@@_backend:nn {#1} { fill- } }
+\cs_new_protected:Npn \@@_backend_stroke:n #1
+ { \@@_backend:nn {#1} { stroke- } }
+\cs_new_protected:Npn \@@_backend:nn #1#2
+ { \__kernel_backend_scope:e { #2 opacity = " #1 " } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \subsection{Font handling integration}
+%
+% In \LuaTeX{} we want to use these functions also for transparent fonts
+% to avoid interference between both uses of transparency.
+%
+% \begin{macrocode}
+%<*lua>
+% \end{macrocode}
+%
+% First we need to check if pdfmanagement is active from Lua.
+% \begin{macrocode}
+local pdfmanagement_active do
+ local pdfmanagement_if_active_p = token.create'pdfmanagement_if_active_p:'
+ local cmd = pdfmanagement_if_active_p.cmdname
+ if cmd == 'undefined_cs' then
+ pdfmanagement_active = false
+ else
+ token.put_next(pdfmanagement_if_active_p)
+ pdfmanagement_active = token.scan_int() ~= 0
+ end
+end
+
+if pdfmanagement_active and luaotfload and luaotfload.set_transparent_colorstack then
+ luaotfload.set_transparent_colorstack(function() return token.create'c_@@_backend_stack_int'.index end)
+
+ local transparent_register = {
+ token.create'pdfmanagement_add:nnn',
+ token.new(0, 1),
+ 'Page/Resources/ExtGState',
+ token.new(0, 2),
+ token.new(0, 1),
+ '',
+ token.new(0, 2),
+ token.new(0, 1),
+ '<</ca ',
+ '',
+ '/CA ',
+ '',
+ '>>',
+ token.new(0, 2),
+ }
+ luatexbase.add_to_callback('luaotfload.parse_transparent', function(value)
+ value = (octet * -1):match(value)
+ if not value then
+ tex.error'Invalid transparency value'
+ return
+ end
+ value = value:sub(1, -2)
+ local result = 'opacity' .. value
+ tex.runtoks(function()
+ transparent_register[6], transparent_register[10], transparent_register[12] = result, value, value
+ tex.sprint(-2, transparent_register)
+ end)
+ return '/' .. result .. ' gs'
+ end, 'l3opacity')
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</lua>
+% \end{macrocode}
+%
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3backend/l3backend-pdf.dtx b/macros/latex-dev/required/l3backend/l3backend-pdf.dtx
new file mode 100644
index 0000000000..cf09c0eec2
--- /dev/null
+++ b/macros/latex-dev/required/l3backend/l3backend-pdf.dtx
@@ -0,0 +1,1755 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-pdf.dtx
+%
+% Copyright (C) 2019-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3backend bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3backend-pdf} module\\ Backend PDF features^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-pdf} implementation}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=pdf>
+% \end{macrocode}
+%
+% Setting up PDF resources is a complex area with only limited documentation
+% in the engine manuals. The following code builds heavily on existing ideas
+% from \pkg{hyperref} work by Sebastian Rahtz and Heiko Oberdiek, and
+% significant contributions by Alexander Grahn, in addition to the specific
+% code referenced a various points.
+%
+% \subsection{Shared code}
+%
+% A very small number of items that belong at the backend level but which
+% are common to most backends.
+%
+% \begin{macrocode}
+%<*!dvisvgm>
+% \end{macrocode}
+%
+% \begin{variable}{\l_@@_internal_box}
+% \begin{macrocode}
+\box_new:N \l_@@_internal_box
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macrocode}
+%</!dvisvgm>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvips} backend}
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_pdfmark:n, \@@_backend_pdfmark:e}
+% Used often enough it should be a separate function.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_pdfmark:n #1
+ { \__kernel_backend_postscript:n { mark #1 ~ pdfmark } }
+\cs_generate_variant:Nn \@@_backend_pdfmark:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Catalogue entries}
+%
+% \begin{macro}{\@@_backend_catalog_gput:nn, \@@_backend_info_gput:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_catalog_gput:nn #1#2
+ { \@@_backend_pdfmark:n { { Catalog } << /#1 ~ #2 >> /PUT } }
+\cs_new_protected:Npn \@@_backend_info_gput:nn #1#2
+ { \@@_backend_pdfmark:n { /#1 ~ #2 /DOCINFO } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Objects}
+%
+% \begin{macro}{\@@_backend_object_new:}
+% \begin{macro}[EXP]{\@@_backend_object_ref:n, \@@_backend_object_id:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_new:
+ { \int_gincr:N \g_@@_backend_object_int }
+\cs_new:Npn \@@_backend_object_ref:n #1 { { pdf.obj #1 } }
+\cs_new_eq:NN \@@_backend_object_id:n \@@_backend_object_ref:n
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_object_write:nnn, \@@_backend_object_write:nne,
+% \@@_backend_object_write_aux:nnn
+% }
+% \begin{macro}
+% {
+% \@@_backend_object_write_array:nn ,
+% \@@_backend_object_write_dict:nn ,
+% \@@_backend_object_write_fstream:nn ,
+% \@@_backend_object_write_stream:nn
+% }
+% \begin{macro}{\@@_backend_object_write_stream:nnn}
+% This is where we choose the actual type: some work to get things
+% right. To allow code sharing with the anonymous version, we use an
+% auxiliary.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_write:nnn #1#2#3
+ {
+ \@@_backend_object_write_aux:nnn
+ { \@@_backend_object_ref:n {#1} }
+ {#2} {#3}
+ }
+\cs_generate_variant:Nn \@@_backend_object_write:nnn { nne }
+\cs_new_protected:Npn \@@_backend_object_write_aux:nnn #1#2#3
+ {
+ \@@_backend_pdfmark:e
+ {
+ /_objdef ~ #1
+ /type
+ \str_case:nn {#2}
+ {
+ { array } { /array }
+ { dict } { /dict }
+ { fstream } { /stream }
+ { stream } { /stream }
+ }
+ /OBJ
+ }
+ \use:c { @@_backend_object_write_ #2 :nn } {#1} {#3}
+ }
+\cs_new_protected:Npn \@@_backend_object_write_array:nn #1#2
+ {
+ \@@_backend_pdfmark:e
+ { #1 ~0~ [ ~ \exp_not:n {#2} ~ ] ~ /PUTINTERVAL }
+ }
+\cs_new_protected:Npn \@@_backend_object_write_dict:nn #1#2
+ {
+ \@@_backend_pdfmark:e
+ { #1 << \exp_not:n {#2} >> /PUT }
+ }
+\cs_new_protected:Npn \@@_backend_object_write_fstream:nn #1#2
+ {
+ \exp_args:Ne
+ \@@_backend_object_write_fstream:nnn {#1} #2
+ }
+\cs_new_protected:Npn \@@_backend_object_write_fstream:nnn #1#2#3
+ {
+ \__kernel_backend_postscript:n
+ {
+ SDict ~ begin ~
+ mark ~ #1 ~ << #2 >> /PUT ~ pdfmark ~
+ mark ~ #1 ~ ( #3 )~ ( r )~ file ~ /PUT ~ pdfmark ~
+ end
+ }
+ }
+\cs_new_protected:Npn \@@_backend_object_write_stream:nn #1#2
+ {
+ \exp_args:Ne
+ \@@_backend_object_write_stream:nnn {#1} #2
+ }
+\cs_new_protected:Npn \@@_backend_object_write_stream:nnn #1#2#3
+ {
+ \__kernel_backend_postscript:n
+ {
+ mark ~ #1 ~ ( #3 ) /PUT ~ pdfmark ~
+ mark ~ #1 ~ << #2 >> /PUT ~ pdfmark
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_object_now:nn, \@@_backend_object_now:ne}
+% No anonymous objects, so things are done manually.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_now:nn #1#2
+ {
+ \int_gincr:N \g_@@_backend_object_int
+ \@@_backend_object_write_aux:nnn
+ { { pdf.obj \int_use:N \g_@@_backend_object_int } }
+ {#1} {#2}
+ }
+\cs_generate_variant:Nn \@@_backend_object_now:nn { ne }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_object_last:}
+% Much like the annotation version.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_object_last:
+ { { pdf.obj \int_use:N \g_@@_backend_object_int } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_pageobject_ref:n}
+% Page references are easy in \texttt{dvips}.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_pageobject_ref:n #1
+ { { Page #1 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Annotations}
+%
+% In \texttt{dvips}, annotations have to be constructed manually. As such,
+% we need the object code above for some definitions.
+%
+% \begin{variable}{\l_@@_backend_content_box}
+% The content of an annotation.
+% \begin{macrocode}
+\box_new:N \l_@@_backend_content_box
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_backend_model_box}
+% For creating model sizing for links.
+% \begin{macrocode}
+\box_new:N \l_@@_backend_model_box
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_backend_annotation_int}
+% Needed as objects which are not annotations could be created.
+% \begin{macrocode}
+\int_new:N \g_@@_backend_annotation_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_backend_annotation:nnnn}
+% Annotations are objects, but we track them separately. Notably, they are
+% not in the object data lists. Here, to get the co-ordinates of the
+% annotation, we need to have the data collected at the PostScript level.
+% That requires a bit of box trickery (effectively a \LaTeXe{} |picture|
+% of zero size). Once the data is collected, use it to set up the annotation
+% border.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_annotation:nnnn #1#2#3#4
+ {
+ \exp_args:Nf \@@_backend_annotation_aux:nnnn
+ { \dim_eval:n {#1} } {#2} {#3} {#4}
+ }
+\cs_new_protected:Npn \@@_backend_annotation_aux:nnnn #1#2#3#4
+ {
+ \box_move_down:nn {#3}
+ { \hbox:n { \__kernel_backend_postscript:n { pdf.save.ll } } }
+ \box_move_up:nn {#2}
+ {
+ \hbox:n
+ {
+ \__kernel_kern:n {#1}
+ \__kernel_backend_postscript:n { pdf.save.ur }
+ \__kernel_kern:n { -#1 }
+ }
+ }
+ \int_gincr:N \g_@@_backend_object_int
+ \int_gset_eq:NN \g_@@_backend_annotation_int \g_@@_backend_object_int
+ \@@_backend_pdfmark:e
+ {
+ /_objdef { pdf.obj \int_use:N \g_@@_backend_object_int }
+ pdf.rect
+ #4 ~
+ /ANN
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_annotation_last:}
+% Provide the last annotation we created: could get tricky of course if
+% other packages are loaded.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_annotation_last:
+ { { pdf.obj \int_use:N \g_@@_backend_annotation_int } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_backend_link_int}
+% To track annotations which are links.
+% \begin{macrocode}
+\int_new:N \g_@@_backend_link_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_backend_link_dict_tl}
+% To pass information to the end-of-link function.
+% \begin{macrocode}
+\tl_new:N \g_@@_backend_link_dict_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_backend_link_sf_int}
+% Needed to save/restore space factor, which is needed to deal with the face
+% we need a box.
+% \begin{macrocode}
+\int_new:N \g_@@_backend_link_sf_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_backend_link_math_bool}
+% Needed to save/restore math mode.
+% \begin{macrocode}
+\bool_new:N \g_@@_backend_link_math_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_backend_link_bool}
+% Track link formation: we cannot nest at all.
+% \begin{macrocode}
+\bool_new:N \g_@@_backend_link_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_breaklink_pdfmark_tl}
+% Swappable content for link breaking.
+% \begin{macrocode}
+\tl_new:N \l_@@_breaklink_pdfmark_tl
+\tl_set:Nn \l_@@_breaklink_pdfmark_tl { pdfmark }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_breaklink_postscript:n}
+% To allow dropping material unless link breaking is active.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_breaklink_postscript:n #1 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_breaklink_usebox:N}
+% Swappable box unpacking or use.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_breaklink_usebox:N \box_use:N
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_begin_goto:nnw, \@@_backend_link_begin_user:nnw}
+% \begin{macro}{\@@_backend_link:nw, \@@_backend_link_aux:nw}
+% \begin{macro}{\@@_backend_link_end:, \@@_backend_link_end_aux:}
+% \begin{macro}{\@@_backend_link_minima:}
+% \begin{macro}{\@@_backend_link_outerbox:n}
+% \begin{macro}{\@@_backend_link_sf_save:, \@@_backend_link_sf_restore:}
+% Links are crated like annotations but with dedicated code to allow for
+% adjusting the size of the rectangle. In contrast to \pkg{hyperref}, we
+% grab the link content as a box which can then unbox: this allows the same
+% interface as for \pdfTeX{}.
+%
+% Notice that the link setup here uses |/Action| not |/A|. That is because
+% Distiller \emph{requires} this trigger word, rather than a \enquote{raw}
+% PDF dictionary key (Ghostscript can handle either form).
+%
+% Taking the idea of |evenboxes| from \pkg{hypdvips}, we implement a minimum
+% box height and depth for link placement. This means that \enquote{underlining}
+% with a hyperlink will generally give an even appearance. However, to ensure
+% that the full content is always above the link border, we do not allow
+% this to be negative (contrast \pkg{hypdvips} approach). The result should
+% be similar to \pdfTeX{} in the vast majority of foreseeable cases.
+%
+% The object number for a link is saved separately from the rest of the
+% dictionary as this allows us to insert it just once, at either an
+% unbroken link or only in the first line of a broken one. That makes the
+% code clearer but also avoids a low-level PostScript error with the code
+% as taken from \pkg{hypdvips}.
+%
+% Getting the outer dimensions of the text area may be better using a two-pass
+% approach and |\tex_savepos:D|. That plus generic mode are still to re-examine.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_begin_goto:nnw #1#2
+ {
+ \@@_backend_link_begin:nw
+ { #1 /Subtype /Link /Action << /S /GoTo /D ( #2 ) >> }
+ }
+\cs_new_protected:Npn \@@_backend_link_begin_user:nnw #1#2
+ { \@@_backend_link_begin:nw {#1#2} }
+\cs_new_protected:Npn \@@_backend_link_begin:nw #1
+ {
+ \bool_if:NF \g_@@_backend_link_bool
+ { \@@_backend_link_begin_aux:nw {#1} }
+ }
+% \end{macrocode}
+% The definition of |pdf.link.dict| here is needed as there is code in the
+% PostScript headers for breaking links, and that can only work with this
+% available.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_begin_aux:nw #1
+ {
+ \bool_gset_true:N \g_@@_backend_link_bool
+ \__kernel_backend_postscript:n
+ { /pdf.link.dict ( #1 ) def }
+ \tl_gset:Nn \g_@@_backend_link_dict_tl {#1}
+ \@@_backend_link_sf_save:
+ \mode_if_math:TF
+ { \bool_gset_true:N \g_@@_backend_link_math_bool }
+ { \bool_gset_false:N \g_@@_backend_link_math_bool }
+ \hbox_set:Nw \l_@@_backend_content_box
+ \@@_backend_link_sf_restore:
+ \bool_if:NT \g_@@_backend_link_math_bool
+ { \c_math_toggle_token }
+ }
+\cs_new_protected:Npn \@@_backend_link_end:
+ {
+ \bool_if:NT \g_@@_backend_link_bool
+ { \@@_backend_link_end_aux: }
+ }
+\cs_new_protected:Npn \@@_backend_link_end_aux:
+ {
+ \bool_if:NT \g_@@_backend_link_math_bool
+ { \c_math_toggle_token }
+ \@@_backend_link_sf_save:
+ \hbox_set_end:
+ \@@_backend_link_minima:
+ \hbox_set:Nn \l_@@_backend_model_box { Gg }
+ \exp_args:Ne \@@_backend_link_outerbox:n
+ {
+ \int_if_odd:nTF { \value { page } }
+ { \oddsidemargin }
+ { \evensidemargin }
+ }
+ \box_move_down:nn { \box_dp:N \l_@@_backend_content_box }
+ { \hbox:n { \__kernel_backend_postscript:n { pdf.save.linkll } } }
+ \@@_breaklink_postscript:n { pdf.bordertracking.begin }
+ \@@_breaklink_usebox:N \l_@@_backend_content_box
+ \@@_breaklink_postscript:n { pdf.bordertracking.end }
+ \box_move_up:nn { \box_ht:N \l_@@_backend_content_box }
+ {
+ \hbox:n
+ { \__kernel_backend_postscript:n { pdf.save.linkur } }
+ }
+ \int_gincr:N \g_@@_backend_object_int
+ \int_gset_eq:NN \g_@@_backend_link_int \g_@@_backend_object_int
+ \__kernel_backend_postscript:e
+ {
+ mark
+ /_objdef { pdf.obj \int_use:N \g_@@_backend_link_int }
+ \g_@@_backend_link_dict_tl \c_space_tl
+ pdf.rect
+ /ANN ~ \l_@@_breaklink_pdfmark_tl
+ }
+ \@@_backend_link_sf_restore:
+ \bool_gset_false:N \g_@@_backend_link_bool
+ }
+\cs_new_protected:Npn \@@_backend_link_minima:
+ {
+ \hbox_set:Nn \l_@@_backend_model_box { Gg }
+ \__kernel_backend_postscript:e
+ {
+ /pdf.linkdp.pad ~
+ \dim_to_decimal:n
+ {
+ \dim_max:nn
+ {
+ \box_dp:N \l_@@_backend_model_box
+ - \box_dp:N \l_@@_backend_content_box
+ }
+ { 0pt }
+ } ~
+ pdf.pt.dvi ~ def
+ /pdf.linkht.pad ~
+ \dim_to_decimal:n
+ {
+ \dim_max:nn
+ {
+ \box_ht:N \l_@@_backend_model_box
+ - \box_ht:N \l_@@_backend_content_box
+ }
+ { 0pt }
+ } ~
+ pdf.pt.dvi ~ def
+ }
+ }
+\cs_new_protected:Npn \@@_backend_link_outerbox:n #1
+ {
+ \__kernel_backend_postscript:e
+ {
+ /pdf.outerbox
+ [
+ \dim_to_decimal:n {#1} ~
+ \dim_to_decimal:n { -\box_dp:N \l_@@_backend_model_box } ~
+ \dim_to_decimal:n { #1 + \textwidth } ~
+ \dim_to_decimal:n { \box_ht:N \l_@@_backend_model_box }
+ ]
+ [ exch { pdf.pt.dvi } forall ] def
+ /pdf.baselineskip ~
+ \dim_to_decimal:n { \tex_baselineskip:D } ~ dup ~ 0 ~ gt
+ { pdf.pt.dvi ~ def }
+ { pop ~ pop }
+ ifelse
+ }
+ }
+\cs_new_protected:Npn \@@_backend_link_sf_save:
+ {
+ \int_gset:Nn \g_@@_backend_link_sf_int
+ {
+ \mode_if_horizontal:TF
+ { \tex_spacefactor:D }
+ { 0 }
+ }
+ }
+\cs_new_protected:Npn \@@_backend_link_sf_restore:
+ {
+ \mode_if_horizontal:T
+ {
+ \int_compare:nNnT \g_@@_backend_link_sf_int > { 0 }
+ { \int_set_eq:NN \tex_spacefactor:D \g_@@_backend_link_sf_int }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% Hooks to allow link breaking: something will be needed in format mode
+% at some stage. At present this code is disabled as there is an open
+% question about the name of the hook: to be resolved at the \LaTeXe{}
+% end.
+% \begin{macrocode}
+\use_none:n
+ {
+ \cs_if_exist:NT \@makecol@hook
+ {
+ \tl_put_right:Nn \@makecol@hook
+ {
+ \box_if_empty:NF \l_shipout_box
+ {
+ \vbox_set:Nn \l_shipout_box
+ {
+ \__kernel_backend_postscript:n
+ {
+ pdf.globaldict /pdf.brokenlink.rect ~ known
+ { pdf.bordertracking.continue }
+ if
+ }
+ \vbox_unpack_drop:N \l_shipout_box
+ \__kernel_backend_postscript:n
+ { pdf.bordertracking.endpage }
+ }
+ }
+ }
+ \tl_set:Nn \l_@@_breaklink_pdfmark_tl { pdf.pdfmark }
+ \cs_set_eq:NN \@@_breaklink_postscript:n \__kernel_backend_postscript:n
+ \cs_set_eq:NN \@@_breaklink_usebox:N \hbox_unpack:N
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_link_last:}
+% The same as annotations, but with a custom integer.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_link_last:
+ { { pdf.obj \int_use:N \g_@@_backend_link_int } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_margin:n}
+% Convert to big points and pass to PostScript.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_margin:n #1
+ {
+ \__kernel_backend_postscript:e
+ {
+ /pdf.linkmargin { \dim_to_decimal:n {#1} ~ pdf.pt.dvi } def
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_destination:nn}
+% \begin{macro}{\@@_backend_destination:nnnn, \@@_backend_destination_aux:nnnn}
+% Here, we need to turn the zoom into a scale. We also need to know where
+% the current anchor point actually is: worked out in PostScript. For the
+% rectangle version, we have a bit more PostScript: we need two points.
+% fitr without rule spec doesn't work, so it falls back to \texttt{/Fit} here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_destination:nn #1#2
+ {
+ \__kernel_backend_postscript:n { pdf.dest.anchor }
+ \@@_backend_pdfmark:e
+ {
+ /View
+ [
+ \str_case:nnF {#2}
+ {
+ { xyz } { /XYZ ~ pdf.dest.point ~ null }
+ { fit } { /Fit }
+ { fitb } { /FitB }
+ { fitbh } { /FitBH ~ pdf.dest.y }
+ { fitbv } { /FitBV ~ pdf.dest.x }
+ { fith } { /FitH ~ pdf.dest.y }
+ { fitv } { /FitV ~ pdf.dest.x }
+ { fitr } { /Fit }
+ }
+ {
+ /XYZ ~ pdf.dest.point ~ \fp_eval:n { (#2) / 100 }
+ }
+ ]
+ /Dest ( \exp_not:n {#1} ) cvn
+ /DEST
+ }
+ }
+\cs_new_protected:Npn \@@_backend_destination:nnnn #1#2#3#4
+ {
+ \exp_args:Ne \@@_backend_destination_aux:nnnn
+ { \dim_eval:n {#2} } {#1} {#3} {#4}
+ }
+\cs_new_protected:Npn \@@_backend_destination_aux:nnnn #1#2#3#4
+ {
+ \vbox_to_zero:n
+ {
+ \__kernel_kern:n {#4}
+ \hbox:n { \__kernel_backend_postscript:n { pdf.save.ll } }
+ \tex_vss:D
+ }
+ \__kernel_kern:n {#1}
+ \vbox_to_zero:n
+ {
+ \__kernel_kern:n { -#3 }
+ \hbox:n { \__kernel_backend_postscript:n { pdf.save.ur } }
+ \tex_vss:D
+ }
+ \__kernel_kern:n { -#1 }
+ \@@_backend_pdfmark:n
+ {
+ /View
+ [
+ /FitR ~
+ pdf.llx ~ pdf.lly ~ pdf.dest2device ~
+ pdf.urx ~ pdf.ury ~ pdf.dest2device
+ ]
+ /Dest ( #2 ) cvn
+ /DEST
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Structure}
+%
+% \begin{macro}{\@@_backend_compresslevel:n}
+% \begin{macro}{\@@_backend_compress_objects:n}
+% Doable for the usual \texttt{ps2pdf} method.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_compresslevel:n #1
+ {
+ \int_compare:nNnT {#1} = 0
+ {
+ \__kernel_backend_literal_postscript:n
+ {
+ /setdistillerparams ~ where
+ { pop << /CompressPages ~ false >> setdistillerparams }
+ if
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_backend_compress_objects:n #1
+ {
+ \bool_if:nF {#1}
+ {
+ \__kernel_backend_literal_postscript:n
+ {
+ /setdistillerparams ~ where
+ { pop << /CompressStreams ~ false >> setdistillerparams }
+ if
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_backend_version_major_gset:n, \@@_backend_version_minor_gset:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_version_major_gset:n #1
+ {
+ \cs_gset:Npe \@@_backend_version_major: { \int_eval:n {#1} }
+ }
+\cs_new_protected:Npn \@@_backend_version_minor_gset:n #1
+ {
+ \cs_gset:Npe \@@_backend_version_minor: { \int_eval:n {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_version_major:, \@@_backend_version_minor:}
+% Data not available!
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_version_major: { -1 }
+\cs_new:Npn \@@_backend_version_minor: { -1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Marked content}
+%
+% \begin{macro}{\@@_backend_bdc:nn}
+% \begin{macro}{\@@_backend_emc:}
+% Simple wrappers.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_bdc:nn #1#2
+ { \@@_backend_pdfmark:n { /#1 ~ #2 /BDC } }
+\cs_new_protected:Npn \@@_backend_emc:
+ { \@@_backend_pdfmark:n { /EMC } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \subsection{\LuaTeX{} and \pdfTeX{} backend}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \subsubsection{Annotations}
+%
+% \begin{macro}{\@@_backend_annotation:nnnn}
+% Simply pass the raw data through, just dealing with evaluation of dimensions.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_annotation:nnnn #1#2#3#4
+ {
+%<*luatex>
+ \tex_pdfextension:D annot ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfannot:D
+%</pdftex>
+ width ~ \dim_eval:n {#1} ~
+ height ~ \dim_eval:n {#2} ~
+ depth ~ \dim_eval:n {#3} ~
+ {#4}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_annotation_last:}
+% A tiny amount of extra data gets added here; we use \texttt{x}-type
+% expansion to get the space in the right place and form. The \enquote{extra}
+% space in the \LuaTeX{} version is \emph{required} as it is consumed in
+% finding the end of the keyword.
+% \begin{macrocode}
+\cs_new:Npe \@@_backend_annotation_last:
+ {
+ \exp_not:N \int_value:w
+%<*luatex>
+ \exp_not:N \tex_pdffeedback:D lastannot ~
+%</luatex>
+%<*pdftex>
+ \exp_not:N \tex_pdflastannot:D
+%</pdftex>
+ \c_space_tl 0 ~ R
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_backend_link_begin_goto:nnw, \@@_backend_link_begin_user:nnw}
+% \begin{macro}{\@@_backend_link_begin:nnnw}
+% \begin{macro}{\@@_backend_link_end:}
+% Links are all created using the same internals.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_begin_goto:nnw #1#2
+ { \@@_backend_link_begin:nnnw {#1} { goto~name } {#2} }
+\cs_new_protected:Npn \@@_backend_link_begin_user:nnw #1#2
+ { \@@_backend_link_begin:nnnw {#1} { user } {#2} }
+\cs_new_protected:Npn \@@_backend_link_begin:nnnw #1#2#3
+ {
+%<*luatex>
+ \tex_pdfextension:D startlink ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfstartlink:D
+%</pdftex>
+ attr {#1}
+ #2 {#3}
+ }
+\cs_new_protected:Npn \@@_backend_link_end:
+ {
+%<*luatex>
+ \tex_pdfextension:D endlink \scan_stop:
+%</luatex>
+%<*pdftex>
+ \tex_pdfendlink:D
+%</pdftex>
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_last:}
+% Formatted for direct use.
+% \begin{macrocode}
+\cs_new:Npe \@@_backend_link_last:
+ {
+ \exp_not:N \int_value:w
+%<*luatex>
+ \exp_not:N \tex_pdffeedback:D lastlink ~
+%</luatex>
+%<*pdftex>
+ \exp_not:N \tex_pdflastlink:D
+%</pdftex>
+ \c_space_tl 0 ~ R
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_margin:n}
+% A simple task: pass the data to the primitive.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_margin:n #1
+ {
+%<*luatex>
+ \tex_pdfvariable:D linkmargin
+%</luatex>
+%<*pdftex>
+ \tex_pdflinkmargin:D
+%</pdftex>
+ \dim_eval:n {#1} \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_destination:nn}
+% \begin{macro}{\@@_backend_destination:nnnn}
+% A simple task: pass the data to the primitive. The |\scan_stop:| deals
+% with the danger of an unterminated keyword. The zoom given here is a
+% percentage, but we need to pass it as \emph{per mille}. The rectangle
+% version is also easy as everything is build in.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_destination:nn #1#2
+ {
+%<*luatex>
+ \tex_pdfextension:D dest ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfdest:D
+%</pdftex>
+ name {#1}
+ \str_case:nnF {#2}
+ {
+ { xyz } { xyz }
+ { fit } { fit }
+ { fitb } { fitb }
+ { fitbh } { fitbh }
+ { fitbv } { fitbv }
+ { fith } { fith }
+ { fitv } { fitv }
+ { fitr } { fitr }
+ }
+ { xyz ~ zoom \fp_eval:n { #2 * 10 } }
+ \scan_stop:
+ }
+\cs_new_protected:Npn \@@_backend_destination:nnnn #1#2#3#4
+ {
+%<*luatex>
+ \tex_pdfextension:D dest ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfdest:D
+%</pdftex>
+ name {#1}
+ fitr ~
+ width \dim_eval:n {#2} ~
+ height \dim_eval:n {#3} ~
+ depth \dim_eval:n {#4} \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Catalogue entries}
+%
+% \begin{macro}{\@@_backend_catalog_gput:nn, \@@_backend_info_gput:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_catalog_gput:nn #1#2
+ {
+%<*luatex>
+ \tex_pdfextension:D catalog
+%</luatex>
+%<*pdftex>
+ \tex_pdfcatalog:D
+%</pdftex>
+ { / #1 ~ #2 }
+ }
+\cs_new_protected:Npn \@@_backend_info_gput:nn #1#2
+ {
+%<*luatex>
+ \tex_pdfextension:D info
+%</luatex>
+%<*pdftex>
+ \tex_pdfinfo:D
+%</pdftex>
+ { / #1 ~ #2 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Objects}
+%
+% \begin{variable}{\g_@@_backend_object_prop}
+% For tracking objects to allow finalisation.
+% \begin{macrocode}
+\prop_new:N \g_@@_backend_object_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_backend_object_new:}
+% \begin{macro}[EXP]{\@@_backend_object_ref:n, \@@_backend_object_id:n}
+% Declaring objects means reserving at the PDF level plus starting
+% tracking.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_new:
+ {
+%<*luatex>
+ \tex_pdfextension:D obj ~
+%</luatex>
+%<*pdftex>
+ \tex_pdfobj:D
+%</pdftex>
+ reserveobjnum ~
+ \int_gset:Nn \g_@@_backend_object_int
+%<*luatex>
+ { \tex_pdffeedback:D lastobj }
+%</luatex>
+%<*pdftex>
+ { \tex_pdflastobj:D }
+%</pdftex>
+ }
+\cs_new:Npn \@@_backend_object_ref:n #1 { #1 ~ 0 ~ R }
+\cs_new:Npn \@@_backend_object_id:n #1 {#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_object_write:nnn, \@@_backend_object_write:nne}
+% \begin{macro}[EXP]{\@@_backend_object_write:nn}
+% \begin{macro}[EXP]{\@@_exp_not_i:nn, \@@_exp_not_ii:nn}
+% Writing the data needs a little information about the structure of the
+% object.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_write:nnn #1#2#3
+ {
+%<*luatex>
+ \tex_immediate:D \tex_pdfextension:D obj ~
+%</luatex>
+%<*pdftex>
+ \tex_immediate:D \tex_pdfobj:D
+%</pdftex>
+ useobjnum ~ #1
+ \@@_backend_object_write:nn {#2} {#3}
+ }
+\cs_new:Npn \@@_backend_object_write:nn #1#2
+ {
+ \str_case:nn {#1}
+ {
+ { array } { { [ ~ \exp_not:n {#2} ~ ] } }
+ { dict } { { << ~ \exp_not:n {#2} ~ >> } }
+ { fstream }
+ {
+ stream ~ attr ~ { \@@_exp_not_i:nn #2 } ~
+ file ~ { \@@_exp_not_ii:nn #2 }
+ }
+ { stream }
+ {
+ stream ~ attr ~ { \@@_exp_not_i:nn #2 } ~
+ { \@@_exp_not_ii:nn #2 }
+ }
+ }
+ }
+\cs_generate_variant:Nn \@@_backend_object_write:nnn { nne }
+\cs_new:Npn \@@_exp_not_i:nn #1#2 { \exp_not:n {#1} }
+\cs_new:Npn \@@_exp_not_ii:nn #1#2 { \exp_not:n {#2} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_object_now:nn, \@@_backend_object_now:ne}
+% Much like writing, but direct creation.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_now:nn #1#2
+ {
+%<*luatex>
+ \tex_immediate:D \tex_pdfextension:D obj ~
+%</luatex>
+%<*pdftex>
+ \tex_immediate:D \tex_pdfobj:D
+%</pdftex>
+ \@@_backend_object_write:nn {#1} {#2}
+ }
+\cs_generate_variant:Nn \@@_backend_object_now:nn { ne }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_object_last:}
+% Much like annotation.
+% \begin{macrocode}
+\cs_new:Npe \@@_backend_object_last:
+ {
+ \exp_not:N \int_value:w
+%<*luatex>
+ \exp_not:N \tex_pdffeedback:D lastobj ~
+%</luatex>
+%<*pdftex>
+ \exp_not:N \tex_pdflastobj:D
+%</pdftex>
+ \c_space_tl 0 ~ R
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_pageobject_ref:n}
+% The usual wrapper situation; the three spaces here are essential.
+% \begin{macrocode}
+\cs_new:Npe \@@_backend_pageobject_ref:n #1
+ {
+ \exp_not:N \int_value:w
+%<*luatex>
+ \exp_not:N \tex_pdffeedback:D pageref
+%</luatex>
+%<*pdftex>
+ \exp_not:N \tex_pdfpageref:D
+%</pdftex>
+ \c_space_tl #1 \c_space_tl \c_space_tl \c_space_tl 0 ~ R
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Structure}
+%
+% \begin{macro}{\@@_backend_compresslevel:n}
+% \begin{macro}{\@@_backend_compress_objects:n}
+% \begin{macro}{\@@_backend_objcompresslevel:n}
+% Simply pass data to the engine.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_compresslevel:n #1
+ {
+ \tex_global:D
+%<*luatex>
+ \tex_pdfvariable:D compresslevel
+%</luatex>
+%<*pdftex>
+ \tex_pdfcompresslevel:D
+%</pdftex>
+ \int_value:w \int_eval:n {#1} \scan_stop:
+ }
+\cs_new_protected:Npn \@@_backend_compress_objects:n #1
+ {
+ \bool_if:nTF {#1}
+ { \@@_backend_objcompresslevel:n { 2 } }
+ { \@@_backend_objcompresslevel:n { 0 } }
+ }
+\cs_new_protected:Npn \@@_backend_objcompresslevel:n #1
+ {
+ \tex_global:D
+%<*luatex>
+ \tex_pdfvariable:D objcompresslevel
+%</luatex>
+%<*pdftex>
+ \tex_pdfobjcompresslevel:D
+%</pdftex>
+ #1 \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_backend_version_major_gset:n, \@@_backend_version_minor_gset:n}
+% The availability of the primitive is not universal, so we have to test
+% at load time.
+% \begin{macrocode}
+\cs_new_protected:Npe \@@_backend_version_major_gset:n #1
+ {
+%<*luatex>
+ \int_compare:nNnT \tex_luatexversion:D > { 106 }
+ {
+ \exp_not:N \tex_global:D \tex_pdfvariable:D majorversion
+ \exp_not:N \int_eval:n {#1} \scan_stop:
+ }
+%</luatex>
+%<*pdftex>
+ \cs_if_exist:NT \tex_pdfmajorversion:D
+ {
+ \exp_not:N \tex_global:D \tex_pdfmajorversion:D
+ \exp_not:N \int_eval:n {#1} \scan_stop:
+ }
+%</pdftex>
+ }
+\cs_new_protected:Npn \@@_backend_version_minor_gset:n #1
+ {
+ \tex_global:D
+%<*luatex>
+ \tex_pdfvariable:D minorversion
+%</luatex>
+%<*pdftex>
+ \tex_pdfminorversion:D
+%</pdftex>
+ \int_eval:n {#1} \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_version_major:, \@@_backend_version_minor:}
+% As above.
+% \begin{macrocode}
+\cs_new:Npe \@@_backend_version_major:
+ {
+%<*luatex>
+ \int_compare:nNnTF \tex_luatexversion:D > { 106 }
+ { \exp_not:N \tex_the:D \tex_pdfvariable:D majorversion }
+ { 1 }
+%</luatex>
+%<*pdftex>
+ \cs_if_exist:NTF \tex_pdfmajorversion:D
+ { \exp_not:N \tex_the:D \tex_pdfmajorversion:D }
+ { 1 }
+%</pdftex>
+ }
+\cs_new:Npn \@@_backend_version_minor:
+ {
+ \tex_the:D
+%<*luatex>
+ \tex_pdfvariable:D minorversion
+%</luatex>
+%<*pdftex>
+ \tex_pdfminorversion:D
+%</pdftex>
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Marked content}
+%
+% \begin{macro}{\@@_backend_bdc:nn}
+% \begin{macro}{\@@_backend_emc:}
+% Simple wrappers. May need refinement: see
+% \url{https://chat.stackexchange.com/transcript/message/49970158#49970158}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_bdc:nn #1#2
+ { \__kernel_backend_literal_page:n { /#1 ~ #2 ~ BDC } }
+\cs_new_protected:Npn \@@_backend_emc:
+ { \__kernel_backend_literal_page:n { EMC } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvipdfmx} backend}
+%
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend:n, \@@_backend:e}
+% A generic function for the backend PDF specials: used where we can.
+% \begin{macrocode}
+\cs_new_protected:Npe \@@_backend:n #1
+ { \__kernel_backend_literal:n { pdf: #1 } }
+\cs_generate_variant:Nn \@@_backend:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Catalogue entries}
+%
+% \begin{macro}{\@@_backend_catalog_gput:nn, \@@_backend_info_gput:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_catalog_gput:nn #1#2
+ { \@@_backend:n { put ~ @catalog << /#1 ~ #2 >> } }
+\cs_new_protected:Npn \@@_backend_info_gput:nn #1#2
+ { \@@_backend:n { docinfo << /#1 ~ #2 >> } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Objects}
+%
+% \begin{variable}{\g_@@_backend_object_prop}
+% For tracking objects to allow finalisation.
+% \begin{macrocode}
+\prop_new:N \g_@@_backend_object_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_backend_object_new:}
+% \begin{macro}[EXP]{\@@_backend_object_ref:n, \@@_backend_object_id:n}
+% Objects are tracked at the macro level, but we don't have to do anything
+% at this stage.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_new:
+ { \int_gincr:N \g_@@_backend_object_int }
+\cs_new:Npn \@@_backend_object_ref:n #1 { @pdf.obj #1 }
+\cs_new_eq:NN \@@_backend_object_id:n \@@_backend_object_ref:n
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_object_write:nnn, \@@_backend_object_write:nne}
+% \begin{macro}
+% {
+% \@@_backend_object_write_array:nn ,
+% \@@_backend_object_write_dict:nn ,
+% \@@_backend_object_write_fstream:nn ,
+% \@@_backend_object_write_stream:nn
+% }
+% \begin{macro}{\@@_backend_object_write_stream:nnnn}
+% This is where we choose the actual type.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_write:nnn #1#2#3
+ {
+ \use:c { @@_backend_object_write_ #2 :nn }
+ { \@@_backend_object_ref:n {#1} } {#3}
+ }
+\cs_generate_variant:Nn \@@_backend_object_write:nnn { nne }
+\cs_new_protected:Npn \@@_backend_object_write_array:nn #1#2
+ {
+ \@@_backend:e
+ { obj ~ #1 ~ [ ~ \exp_not:n {#2} ~ ] }
+ }
+\cs_new_protected:Npn \@@_backend_object_write_dict:nn #1#2
+ {
+ \@@_backend:e
+ { obj ~ #1 ~ << ~ \exp_not:n {#2} ~ >> }
+ }
+\cs_new_protected:Npn \@@_backend_object_write_fstream:nn #1#2
+ { \@@_backend_object_write_stream:nnnn { f } {#1} #2 }
+\cs_new_protected:Npn \@@_backend_object_write_stream:nn #1#2
+ { \@@_backend_object_write_stream:nnnn { } {#1} #2 }
+\cs_new_protected:Npn \@@_backend_object_write_stream:nnnn #1#2#3#4
+ {
+ \@@_backend:e
+ {
+ #1 stream ~ #2 ~
+ ( \exp_not:n {#4} ) ~ << \exp_not:n {#3} >>
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_object_now:nn, \@@_backend_object_now:ne}
+% No anonymous objects with \texttt{dvipdfmx} so we have to give an
+% object name.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_now:nn #1#2
+ {
+ \int_gincr:N \g_@@_backend_object_int
+ \exp_args:Nne \use:c { @@_backend_object_write_ #1 :nn }
+ { @pdf.obj \int_use:N \g_@@_backend_object_int }
+ {#2}
+ }
+\cs_generate_variant:Nn \@@_backend_object_now:nn { ne }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_object_last:}
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_object_last:
+ { @pdf.obj \int_use:N \g_@@_backend_object_int }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_pageobject_ref:n}
+% Page references are easy in \texttt{dvipdfmx}/\XeTeX{}.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_pageobject_ref:n #1
+ { @page #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Annotations}
+%
+% \begin{variable}{\g_@@_backend_annotation_int}
+% Needed as objects which are not annotations could be created.
+% \begin{macrocode}
+\int_new:N \g_@@_backend_annotation_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_backend_annotation:nnnn}
+% Simply pass the raw data through, just dealing with evaluation of dimensions.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_annotation:nnnn #1#2#3#4
+ {
+ \int_gincr:N \g_@@_backend_object_int
+ \int_gset_eq:NN \g_@@_backend_annotation_int \g_@@_backend_object_int
+ \@@_backend:e
+ {
+ ann ~ @pdf.obj \int_use:N \g_@@_backend_object_int \c_space_tl
+ width ~ \dim_eval:n {#1} ~
+ height ~ \dim_eval:n {#2} ~
+ depth ~ \dim_eval:n {#3} ~
+ << /Type /Annot #4 >>
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_annotation_last:}
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_annotation_last:
+ { @pdf.obj \int_use:N \g_@@_backend_annotation_int }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_backend_link_int}
+% To track annotations which are links.
+% \begin{macrocode}
+\int_new:N \g_@@_backend_link_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {\@@_backend_link_begin_goto:nnw, \@@_backend_link_begin_user:nnw}
+% \begin{macro}{\@@_backend_link_begin:n}
+% \begin{macro}{\@@_backend_link_end:}
+% All created using the same internals.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_begin_goto:nnw #1#2
+ { \@@_backend_link_begin:n { #1 /Subtype /Link /A << /S /GoTo /D ( #2 ) >> } }
+\cs_new_protected:Npn \@@_backend_link_begin_user:nnw #1#2
+ { \@@_backend_link_begin:n {#1#2} }
+\cs_new_protected:Npe \@@_backend_link_begin:n #1
+ {
+ \exp_not:N \int_gincr:N \exp_not:N \g_@@_backend_link_int
+ \@@_backend:e
+ {
+ bann ~
+ @pdf.lnk
+ \exp_not:N \int_use:N \exp_not:N \g_@@_backend_link_int
+ \c_space_tl
+ <<
+ /Type /Annot
+ #1
+ >>
+ }
+ }
+\cs_new_protected:Npn \@@_backend_link_end:
+ { \@@_backend:n { eann } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_last:}
+% Available using the backend mechanism with a suitably-recent
+% version.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_link_last:
+ { @pdf.lnk \int_use:N \g_@@_backend_link_int }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_margin:n}
+% Pass to \texttt{dvipdfmx}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_margin:n #1
+ { \__kernel_backend_literal:e { dvipdfmx:config~g~ \dim_eval:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_destination:nn}
+% \begin{macro}{\@@_backend_destination:nnnn,\@@_backend_destination_aux:nnnn}
+% Here, we need to turn the zoom into a scale. The method for \texttt{FitR}
+% is from Alexander Grahn: the idea is to avoid needing to do any calculations
+% in \TeX{} by using the backend data for \texttt{@xpos} and \texttt{@ypos}.
+% \texttt{/FitR} without rule spec doesn't work, so it falls back to
+% \texttt{/Fit} here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_destination:nn #1#2
+ {
+ \@@_backend:e
+ {
+ dest ~ ( \exp_not:n {#1} )
+ [
+ @thispage
+ \str_case:nnF {#2}
+ {
+ { xyz } { /XYZ ~ @xpos ~ @ypos ~ null }
+ { fit } { /Fit }
+ { fitb } { /FitB }
+ { fitbh } { /FitBH }
+ { fitbv } { /FitBV ~ @xpos }
+ { fith } { /FitH ~ @ypos }
+ { fitv } { /FitV ~ @xpos }
+ { fitr } { /Fit }
+ }
+ { /XYZ ~ @xpos ~ @ypos ~ \fp_eval:n { (#2) / 100 } }
+ ]
+ }
+ }
+\cs_new_protected:Npn \@@_backend_destination:nnnn #1#2#3#4
+ {
+ \exp_args:Ne \@@_backend_destination_aux:nnnn
+ { \dim_eval:n {#2} } {#1} {#3} {#4}
+ }
+\cs_new_protected:Npn \@@_backend_destination_aux:nnnn #1#2#3#4
+ {
+ \vbox_to_zero:n
+ {
+ \__kernel_kern:n {#4}
+ \hbox:n
+ {
+ \@@_backend:n { obj ~ @pdf_ #2 _llx ~ @xpos }
+ \@@_backend:n { obj ~ @pdf_ #2 _lly ~ @ypos }
+ }
+ \tex_vss:D
+ }
+ \__kernel_kern:n {#1}
+ \vbox_to_zero:n
+ {
+ \__kernel_kern:n { -#3 }
+ \hbox:n
+ {
+ \@@_backend:n
+ {
+ dest ~ (#2)
+ [
+ @thispage
+ /FitR ~
+ @pdf_ #2 _llx ~ @pdf_ #2 _lly ~
+ @xpos ~ @ypos
+ ]
+ }
+ }
+ \tex_vss:D
+ }
+ \__kernel_kern:n { -#1 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Structure}
+%
+% \begin{macro}{\@@_backend_compresslevel:n}
+% \begin{macro}{\@@_backend_compress_objects:n}
+% Pass data to the backend: these are a one-shot.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_compresslevel:n #1
+ { \__kernel_backend_literal:e { dvipdfmx:config~z~ \int_eval:n {#1} } }
+\cs_new_protected:Npn \@@_backend_compress_objects:n #1
+ {
+ \bool_if:nF {#1}
+ { \__kernel_backend_literal:n { dvipdfmx:config~C~0x40 } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_backend_version_major_gset:n, \@@_backend_version_minor_gset:n}
+% We start with the assumption that the default is active.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_version_major_gset:n #1
+ {
+ \cs_gset:Npe \@@_backend_version_major: { \int_eval:n {#1} }
+ \__kernel_backend_literal:e { pdf:majorversion~ \@@_backend_version_major: }
+ }
+\cs_new_protected:Npn \@@_backend_version_minor_gset:n #1
+ {
+ \cs_gset:Npe \@@_backend_version_minor: { \int_eval:n {#1} }
+ \__kernel_backend_literal:e { pdf:minorversion~ \@@_backend_version_minor: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_version_major:, \@@_backend_version_minor:}
+% We start with the assumption that the default is active.
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_version_major: { 1 }
+\cs_new:Npn \@@_backend_version_minor: { 5 }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Marked content}
+%
+% \begin{macro}{\@@_backend_bdc:nn}
+% \begin{macro}{\@@_backend_emc:}
+% Simple wrappers. May need refinement: see
+% \url{https://chat.stackexchange.com/transcript/message/49970158#49970158}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_bdc:nn #1#2
+ { \__kernel_backend_literal_page:n { /#1 ~ #2 ~ BDC } }
+\cs_new_protected:Npn \@@_backend_emc:
+ { \__kernel_backend_literal_page:n { EMC } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \subsection{\texttt{dvisvgm} backend}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \subsubsection{Annotations}
+%
+% \begin{macro}{\@@_backend_annotation:nnnn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_annotation:nnnn #1#2#3#4 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_annotation_last:}
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_annotation_last: { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_backend_link_begin_goto:nnw, \@@_backend_link_begin_user:nnw}
+% \begin{macro}{\@@_backend_link_begin:nnnw}
+% \begin{macro}{\@@_backend_link_end:}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_begin_goto:nnw #1#2 { }
+\cs_new_protected:Npn \@@_backend_link_begin_user:nnw #1#2 { }
+\cs_new_protected:Npn \@@_backend_link_begin:nnnw #1#2#3 { }
+\cs_new_protected:Npn \@@_backend_link_end: { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_last:}
+% \begin{macrocode}
+\cs_new:Npe \@@_backend_link_last: { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_link_margin:n}
+% A simple task: pass the data to the primitive.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_link_margin:n #1 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_destination:nn}
+% \begin{macro}{\@@_backend_destination:nnnn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_destination:nn #1#2 { }
+\cs_new_protected:Npn \@@_backend_destination:nnnn #1#2#3#4 { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Catalogue entries}
+%
+% \begin{macro}{\@@_backend_catalog_gput:nn, \@@_backend_info_gput:nn}
+% No-op.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_catalog_gput:nn #1#2 { }
+\cs_new_protected:Npn \@@_backend_info_gput:nn #1#2 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Objects}
+%
+% \begin{macro}{\@@_backend_object_new:}
+% \begin{macro}[EXP]{\@@_backend_object_ref:n, \@@_backend_object_id:n}
+% \begin{macro}{\@@_backend_object_write:nnn, \@@_backend_object_write:ne}
+% \begin{macro}{\@@_backend_object_now:nn, , \@@_backend_object_now:ne}
+% \begin{macro}{\@@_backend_object_last:}
+% \begin{macro}[EXP]{\@@_backend_pageobject_ref:n}
+% All no-ops here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_object_new: { }
+\cs_new:Npn \@@_backend_object_ref:n #1 { }
+\cs_new:Npn \@@_backend_object_id:n #1 { }
+\cs_new_protected:Npn \@@_backend_object_write:nnn #1#2#3 { }
+\cs_new_protected:Npn \@@_backend_object_write:nne #1#2#3 { }
+\cs_new_protected:Npn \@@_backend_object_now:nn #1#2 { }
+\cs_new_protected:Npn \@@_backend_object_now:ne #1#2 { }
+\cs_new:Npn \@@_backend_object_last: { }
+\cs_new:Npn \@@_backend_pageobject_ref:n #1 { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Structure}
+%
+% \begin{macro}{\@@_backend_compresslevel:n}
+% \begin{macro}{\@@_backend_compress_objects:n}
+% These are all no-ops.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_compresslevel:n #1 { }
+\cs_new_protected:Npn \@@_backend_compress_objects:n #1 { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_backend_version_major_gset:n, \@@_backend_version_minor_gset:n}
+% Data not available!
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_version_major_gset:n #1 { }
+\cs_new_protected:Npn \@@_backend_version_minor_gset:n #1 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_backend_version_major:, \@@_backend_version_minor:}
+% Data not available!
+% \begin{macrocode}
+\cs_new:Npn \@@_backend_version_major: { -1 }
+\cs_new:Npn \@@_backend_version_minor: { -1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_backend_bdc:nn}
+% \begin{macro}{\@@_backend_emc:}
+% More no-ops.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_bdc:nn #1#2 { }
+\cs_new_protected:Npn \@@_backend_emc: { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \subsection{PDF Page size (media box)}
+%
+% For setting the media box, the split between backends is somewhat different
+% to other areas, thus we approach this separately. The code here assumes a
+% recent \LaTeXe{}: that is ensured at the level above.
+%
+% \begin{macrocode}
+%<*dvipdfmx|dvips>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_pagesize_gset:nn}
+% This is done as a backend literal, so we deal with it using the shipout
+% hook.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_pagesize_gset:nn #1#2
+ {
+ \__kernel_backend_first_shipout:n
+ {
+ \__kernel_backend_literal:e
+ {
+%<*dvipdfmx>
+ pdf:pagesize ~
+ width ~ \dim_eval:n {#1} ~
+ height ~ \dim_eval:n {#2}
+%</dvipdfmx>
+%<*dvips>
+ papersize = \dim_eval:n {#1} , \dim_eval:n {#2}
+%</dvips>
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|dvips>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_pagesize_gset:nn}
+% Pass to the primitives.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_pagesize_gset:nn #1#2
+ {
+ \dim_gset:Nn \tex_pagewidth:D {#1}
+ \dim_gset:Nn \tex_pageheight:D {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_backend_pagesize_gset:nn}
+% A no-op.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_pagesize_gset:nn #1#2 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3backend/l3backend.ins b/macros/latex-dev/required/l3backend/l3backend.ins
new file mode 100644
index 0000000000..e24c41d236
--- /dev/null
+++ b/macros/latex-dev/required/l3backend/l3backend.ins
@@ -0,0 +1,168 @@
+\iffalse meta-comment
+
+File l3backend.ins
+
+Copyright (C) 2019-2024 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this
+license or (at your option) any later version. The latest version
+of this license is in the file
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3backend bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+-----------------------------------------------------------------------
+
+The development version of the bundle can be found at
+
+ https://github.com/latex3/latex3
+
+for those people who are interested.
+
+-----------------------------------------------------------------------
+
+Any modification of this file should ensure that the copyright and
+license information is placed in the derived files.
+
+\fi
+
+\let\jobname\relax
+\input docstrip %
+\askforoverwritefalse
+
+\preamble
+
+Copyright (C) 2019-2024 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of
+the LaTeX Project Public License (LPPL), either version 1.3c of
+this license or (at your option) any later version. The latest
+version of this license is in the file:
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3backend bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+\endpreamble
+% stop docstrip adding \endinput
+\postamble
+\endpostamble
+
+\keepsilent
+
+\generate
+ {
+ \file{l3backend-dvipdfmx.def}
+ {
+ \from{l3backend-basics.dtx} {package,dvipdfmx}
+ \from{l3backend-color.dtx} {package,dvipdfmx}
+ \from{l3backend-box.dtx} {package,dvipdfmx}
+ \from{l3backend-draw.dtx} {package,dvipdfmx}
+ \from{l3backend-graphics.dtx}{package,dvipdfmx}
+ \from{l3backend-pdf.dtx} {package,dvipdfmx}
+ \from{l3backend-opacity.dtx} {package,dvipdfmx}
+ }
+ }
+\generate
+ {
+ \file{l3backend-dvips.def}
+ {
+ \from{l3backend-basics.dtx} {package,dvips}
+ \from{l3backend-color.dtx} {package,dvips}
+ \from{l3backend-box.dtx} {package,dvips}
+ \from{l3backend-draw.dtx} {package,dvips}
+ \from{l3backend-graphics.dtx}{package,dvips}
+ \from{l3backend-pdf.dtx} {package,dvips}
+ \from{l3backend-opacity.dtx} {package,dvips}
+ }
+ \file{l3backend-dvips.pro}
+ {
+ \from{l3backend-header.dtx} {header,dvips}
+ }
+ }
+\generate
+ {
+ \file{l3backend-dvisvgm.def}
+ {
+ \from{l3backend-basics.dtx} {package,dvisvgm}
+ \from{l3backend-color.dtx} {package,dvisvgm}
+ \from{l3backend-box.dtx} {package,dvisvgm}
+ \from{l3backend-draw.dtx} {package,dvisvgm}
+ \from{l3backend-graphics.dtx}{package,dvisvgm}
+ \from{l3backend-pdf.dtx} {package,dvisvgm}
+ \from{l3backend-opacity.dtx} {package,dvisvgm}
+ }
+ }
+\generate
+ {
+ \file{l3backend-luatex.def}
+ {
+ \from{l3backend-basics.dtx} {package,luatex}
+ \from{l3backend-color.dtx} {package,luatex}
+ \from{l3backend-box.dtx} {package,luatex}
+ \from{l3backend-draw.dtx} {package,luatex}
+ \from{l3backend-graphics.dtx}{package,luatex}
+ \from{l3backend-pdf.dtx} {package,luatex}
+ \from{l3backend-opacity.dtx} {package,luatex}
+ }
+ }
+\generate
+ {
+ \file{l3backend-pdftex.def}
+ {
+ \from{l3backend-basics.dtx} {package,pdftex}
+ \from{l3backend-color.dtx} {package,pdftex}
+ \from{l3backend-box.dtx} {package,pdftex}
+ \from{l3backend-draw.dtx} {package,pdftex}
+ \from{l3backend-graphics.dtx}{package,pdftex}
+ \from{l3backend-pdf.dtx} {package,pdftex}
+ \from{l3backend-opacity.dtx} {package,pdftex}
+ }
+ }
+\generate
+ {
+ \file{l3backend-xetex.def}
+ {
+ \from{l3backend-basics.dtx} {package,xetex}
+ \from{l3backend-color.dtx} {package,xetex}
+ \from{l3backend-box.dtx} {package,xetex}
+ \from{l3backend-draw.dtx} {package,xetex}
+ \from{l3backend-graphics.dtx}{package,xetex}
+ \from{l3backend-pdf.dtx} {package,xetex}
+ \from{l3backend-opacity.dtx} {package,xetex}
+ }
+ }
+
+% Lua code
+
+\def\MetaPrefix{--}
+\preamble
+
+Copyright (C) 2023,2024 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of
+the LaTeX Project Public License (LPPL), either version 1.3c of
+this license or (at your option) any later version. The latest
+version of this license is in the file:
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3backend bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+\endpreamble
+\nopostamble
+\generate
+ {
+ \file{l3backend-luatex.lua}
+ {
+ \from{l3backend-color.dtx} {lua}
+ \from{l3backend-opacity.dtx} {lua}
+ }
+ }
+
+\endbatchfile
diff --git a/macros/latex-dev/required/l3kernel/CHANGELOG.md b/macros/latex-dev/required/l3kernel/CHANGELOG.md
new file mode 100644
index 0000000000..e770f3fe36
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/CHANGELOG.md
@@ -0,0 +1,1879 @@
+# Changelog
+All notable changes to the `l3kernel` bundle since the start of 2018
+will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+this project uses date-based 'snapshot' version identifiers.
+
+## [Unreleased]
+
+## [2024-04-11]
+
+### Added
+- `\prop_(g)put_if_not_in:Nnn` (renamed from `\prop_(g)put_if_new:Nnn`)
+- `\intarray_if_exist:N(TF)`
+- `\fparray_if_exist:N(TF)`
+- Support for 'indexed' PDF objects
+
+### Changed
+- Expand object names in `\pdf_object_...` functions (issue \#1521)
+- Adapt `l3doc` for `ltcmd` change to handling of newlines
+ (see latex3/latex2e\#1304)
+- Return active spaces from `\sys_get_query:n(nn)N` (issue \#1529)
+
+### Fixed
+- False `debug` error raised by `\cctab_const:Nn` (issue \#1508)
+- Undefined `\__kernel_iwo_open:Nn` used in `\iow_shell_open:Nn`
+ (issue \#1515)
+- Naming of register functions in LuaMetaTeX 2.11+ (issue \#1518)
+- Catcode applied to letters by `\sys_get_query:n(nn)N`
+
+### Deprecated
+- `\prop_(g)put_if_new:Nnn` (renamed to `\prop_(g)put_if_not_in:Nnn`)
+
+## [2024-03-14]
+
+### Added
+- Macro interface for `l3sys-query`
+
+### Changed
+- Require that `expl3` is loaded at top level in generic mode
+- Ensure that the dimension arguments to `\box_autosize_to_...:Nnn`
+ are properly formed (issue \#1502)
+
+### Fixed
+- Typeset `TF` of internal conditionals in current color (issue \#730)
+- Some functions and variables were defined locally
+
+## [2024-02-20]
+
+### Changed
+- Improve error recovery when an invalid `prop` is used (PR \#1464)
+
+### Fixed
+- Restore `\__kernel_msg_...:nnx(xx)` for older `xparse` support
+- Prevent an infinite loop in `\debug_(on|off):n` (issue \#1442)
+- Require `\sys_ensure_backend:` is used in the preamble (issue \#1442)
+
+## [2024-02-18]
+
+### Changed
+- Work-around to enable `\prop_set_from_keyval:Nn`, etc., to avoid an error if
+ `prop` is not already defined
+
+### Fixed
+- Extend debug checking to cover `\prop_(g)set_from_keyval:Nn`
+
+## [2024-02-13]
+
+### Added
+- Checking missing `\endgroup` at the end of `\DocInclude`
+- Linked storage type for large property lists (issue \#1040, pull \#1059)
+
+### Changed
+- `\meta` now typesets in `\texttt`, along with `\Arg`
+- Improved the performance of `\cs_if_exist:NTF`, `\cs_if_free:NTF`,
+ `\cs_if_exist_use:NTF`, and most notably their `c`-type variants.
+
+### Fixed
+- Inconsistent local/global assignments in `\vcoffin_gset:Nnn` and
+ `\vcoffin_gset:Nnw`
+- Tokenization by `\peek_analysis_map_inline:n` of one additional
+ character after any space or brace
+
+### Deprecated
+- `\msg_gset:nnn(n)`
+
+## [2024-01-22]
+
+### Added
+- `\keys_set_exclude_groups:nnn(nN)` to replace `\keys_set_filter:nnn(nN)`
+- Flags with N-type names, like other variable types
+
+### Changed
+- Set `l3doc` option `kernel` off as-standard (issue \#1403)
+- Moved `\seq_set_filter:NNn` to stable
+
+### Deprecated
+- `\keys_set_filter:nnn(nN)` in favor of `\keys_set_exclude_groups:nnn(nN)`
+
+## [2024-01-04]
+
+### Added
+- Documentation for `\bitset_show_named_index:N` (issue \#1372)
+- `\bitset_log_named_index:N`
+- `\tl_build_get_intermediate:NN`
+- Support for `.default:n` values for the `unknown` handler (see issue \#67)
+
+### Changed
+- Improved method to suppress `l3bitset` where required
+- Clarify behavior of `\tl_if_novalue:n(TF)` (see issue \#1402)
+
+### Deprecated
+- `\tl_build_get:NN` in favor of `\tl_build_get_intermediate:NN`
+
+### Fixed
+- Handling of `documented-as` variants in `l3doc` indexing
+ (see issue \#1345)
+- Missing trailing `TF` in single variant of conditional functions (issue \#1398)
+
+## [2023-12-11]
+
+### Changed
+- Use keyval handler for `l3doc` class options
+
+### Fixed
+- Support for deprecated `pdf` module functions (issue \#1373)
+- Generate stub `l3bitset` for transitional support
+
+## [2023-12-08]
+
+### Added
+- `\c_empty_str` (issue \#1361)
+- `l3bitset`: moved from `l3experimental`
+
+### Fixed
+- Return `str` (not `tl`) in `\bool_to_str:N` and `\bool_to_str:n` (issue \#1331)
+- Catcode of space from `\str_set_convert:Nnnn` (issue \#1344)
+- Tidy up various documentation issues (issue \#1345)
+
+## [2023-11-09]
+
+### Added
+- Documentation for `\c_nan_fp`
+- `\str_case_e:en(TF)`
+
+### Changed
+- Speed up `\str_(g)set:Nn`, `\str_const:Nn`, `\str_(g)put_left:Nn`,
+ and `\str_(g)put_right:Nn`
+
+### Fixed
+- Normalisation of `.inherit:n` key data (issue \#1314)
+
+## [2023-11-01]
+
+### Added
+- `\seq_(g)set_map_e:NNn`
+- Documentation for `\ExplLoaderFileDate` in `expl3.pdf`
+
+### Changed
+- Documentation improvements
+- Refine action of `\text_titlecase_first:n(n)` to be focussed strictly on
+ first (relevant) codepoint in the input
+- Standardize "This is the (e)TeX primitive ..." in `texnote` in documentation
+- Move `\tl_build_(g)begin:N`, `\tl_build_(g)end:N`, `\tl_build_(g)put_left:Nn`
+ and `\tl_build_(g)right:Nn` to stable status
+
+### Deprecated
+- `\seq_(g)set_map_x:NNn` in favor of `e`-type naming
+
+### Fixed
+- `\fp_clear_variable:n` should act locally (issue \#1298)
+- `\fp_clear_function:n` should act locally and correctly
+- Support for `\fp_show:N` showing symbolic expressions (issue \#1301)
+- Undefined `\str_case:en(TF)` (excluding `\str_case:en`)
+
+## [2023-10-23]
+
+### Added
+- `\text_titlecase_all:n(n)`
+- `\token_to_catcode:N`
+- Support for symbolic variables in fp input:
+ `\fp_new_variable:n`, `\fp_set_variable:nn` and `\fp_clear_variable:n`
+- Support for user-defined functions in fp expressions:
+ `\fp_new_function:n`, `\fp_set_function:nnn` and `\fp_clear_function:n`
+
+### Changed
+- Clarify action of `\text_titlecase_first:n(n)`
+- Detect letters for titlecasing based on Unicode general category
+
+### Deprecated
+- `\text_titlecase:n(n)` as ambiguous: replaced by `\text_titlecase_all:n(n)`
+- `\tl_build_(g)clear:N` in favour of `\tl_build_(g)begin:N`
+
+### Fixed
+- Support arbitrary BCP-47 locales for case-changing overrides (issue \#1239)
+- Retain braces when ending titlecasing with some input structures
+
+## [2023-10-10]
+
+### Added
+- `\iow_shipout_e:Nn`
+- Documentation for `\sys_if_timer_exist_p:` and `\sys_if_timer_exist:(TF)`.
+ They were supported since l3kernel 2021-05-25, along with `\sys_timer:`.
+- l3doc.dtx: Support for footnotes in the function and variable environment
+- Variants `\tl_if_single:c(TF)` and `\tl_if_single_p:c` (issue \#1272)
+- Key properties `.str_(g)set_e:N` and `.tl_(g)set_e:N`
+
+### Changed
+- Switch generally from `x`- to `e`-type variants
+- Convert `\file_if_exist:n(TF)` to expandable status,
+ adding predicate version
+- Standardise variants for `\prop_(g)pop:NnN(TF)`
+- Standardise variants for `\prop_(g)put:Nnn`
+- Standardise variants for `\prop_(g)put_if_new:Nnn`
+- Standardise variants for `\prop_(g)remove:Nn`
+
+### Deprecated
+- `\iow_shipout_x:Nn` in favor of `e`-type naming
+- Key properties `.str_(g)set_x:N` and `.tl_(g)set_x:N`
+
+### Fixed
+- Rare rounding error in divisions (issue \#1264)
+
+## [2023-08-29]
+
+### Added
+- `\c_sys_timestamp_str`
+
+### Changed
+- Rename `\tex_pdfcreationdate:D` to `\tex_creationdate:D`
+
+## [2023-08-11]
+
+### Changed
+- Wrap long lists of variants in `l3doc` display of functions (issue \#1258)
+
+### Fixed
+- Revert 'Allow for implicit chars when case changing' (issue \#1260)
+
+## [2023-08-03]
+
+### Added
+- `\tex_XeTeXhyphenatablelength:D`, `\tex_XeTeXinterwordspaceshaping:D`,
+ `\tex_XeTeXselectorcode:D`
+- Several missing `\tex_<name>:D` primitives from LuaTeX and (up)TeX
+
+### Changed
+
+- `\tex_protrudechars:D` now defined for XeTeX (to `\XeTeXprotrudechars`)
+- Allow for optional `v` in version string argument to
+ `\ProvidesExpl...`
+
+### Fixed
+- Allow for implicit chars when case changing
+
+## [2023-06-30]
+
+### Added
+- `\codepoint_to_category:n`
+
+### Changed
+- Drop notes about slow `\expanded` emulation. `\expanded` is required since
+ release 2023-05-15
+- Sync engine/primitive requirements in `expl3.dtx` with code and README
+
+### Fixed
+- Case changing of Greek characters with complex NFD representation (issue \#1236)
+- Error recovery when wrongly applying abs to a tuple (issue \#1238)
+
+## [2023-06-16]
+
+### Changed
+- Exclude entries in `\l_text_case_exclude_arg_tl` from expansion in `\text_expand:n`
+ (latex3/latex2e\#904)
+- Generate _dialytika_ if appropriate when uppercasing Greek words starting with a
+ vowel taking a breathing mark (issue \#1228)
+- Retain stress diacritics when uppercasing Greek (issue \#1230)
+- Expand (partial) paths in `\l_file_search_path_seq` and `\input@path`
+ (see latex3/latex2e\#1086)
+
+## [2023-06-05]
+
+### Added
+- `\cctab_gsave_current:N`, `\g_tmpa_cctab` and `\g_tmpb_cctab` (issue \#1089)
+- `\prg_gset_eq_conditional:NNn` (issue \#1212)
+- `\iow_shell_open:Nn` (issue \#1122)
+
+### Deprecated
+- `\tl_case:Nn(TF)`
+- `expl3` package option `enable-debug` (no longer required)
+
+### Fixed
+- Set `\l_keys_value_tl` in `.initial:n` (issue \#1013)
+- Support for boolean values in `expl3` package options
+ `check-declarations` and `log-functions` (issue \#978)
+- Allow for optional `/` at end of `\input@path` entries
+ (see latex3/latex2e\#1076)
+
+## [2023-05-22]
+
+### Added
+- Rounded out the `\use_i:nn...` functions to cover all cases taking
+ one argument from up to nine arguments
+- `\coffin_(g)reset_poles:N`
+- `\dim_to_decimal_in_<unit>:n`, for `<unit>` types
+ `cc`, `cm`, `dd`, `in`, `mm` and `pc`
+- `\file_input_raw:n`
+- `\int_if_zero:n(TF)`
+- `\str_mdfive_hash:n`
+### Changed
+- Remove `\noexpand` inside math mode in `\text_expand:n`
+- Re-implement `\dim_to_decimal_in_bp:n` and
+ `\dim_to_decimal_in_unit:nn` to be re-entrant (issue \#954)
+
+### Fixed
+- Omit `0123456789` from URL escaping (issue \#838)
+- Leave implicit chars unchanged in `\text_expand:n` (issue \#874)
+- Filtering/grouping applied to meta keys (issue \#940)
+- Issue correct error message if `bool` key is set
+ incorrectly using `.initial:n` (issue \#1013)
+- Set `\l_keys_key_str` in `.initial:n` (issue \#1013)
+- Handling of implicit chars in `\text_purify:n` (issue \#1208)
+
+## [2023-05-15]
+
+### Changed
+- Require `\expanded` and 'pdfTeX extension' primitives,
+ and thus TeX distributions from mid-2019 onward
+
+### Fixed
+- Treatment of trailing `/` in `\input@path`
+
+## [2023-05-11]
+
+### Added
+- `\seq_map_pairwise_function:NNN` (renamed from `\seq_mapthread_function:NNN`)
+
+### Changed
+- Moved `\seq_set_item:Nnn` to stable status
+- Track seen filenames to improve performance of
+ `\file_full_name:n` and dependent file operations
+
+### Removed
+- Experimental function `\seq_pop_item:NnN` from `l3candidates`
+- Experimental function `\seq_mapthread_function:NNN` now renamed
+ `\seq_map_pairwise_function:NNN`
+
+## [2023-05-05]
+
+### Added
+- `\bool_case:n(TF)` (renamed from `\bool_case_true:n(TF)`)
+- `\flag_ensure_raised:n` (renamed from `\flag_raise_if_clear:n`)
+- `\iow_wrap_allow_break:` (renamed from `\iow_allow_break:`)
+
+### Changed
+- Moved to stable status:
+ - `\bool_(g)set_inverse:N`
+ - `\c_catcode_active_space_tl`
+ - `\c_sys_engine_version_str`
+ - `\exp_args_generate:n`
+ - `\fp_if_nan:n(TF)`
+ - `\ior_get_term:nN` and `\ior_str_get_term:nN`
+ - `\ior_shell_open:Nn`
+ - `\msg_show_item:n`, `\msg_show_item_unbraced:n`,
+ `\msg_show_item:nn`, `\msg_show_item_unbraced:nn`
+- Require random number support from engine
+
+### Removed
+- Experimental functions from `l3candidates`:
+ - `\bool_case_false:n(TF)`
+ - `\intarray_gset_rand:Nn(n)`
+ - `\intarray_to_clist:N`
+ - `\peek_catcode_collect_inline:Nn`, `\peek_charcode_collect_inline:Nn` and
+ `\peek_meaning_collect_inline:Nn`
+ - `\prop_rand_key_value:N`
+ - `\seq_set_from_function:Nnn` and `\seq_set_from_inline_x:Nnn`
+ - `\sys_if_rand_exist:(TF)`
+ - `\tl_range_braced:Nnn` and `\tl_range_unbraced:Nnn`
+- Experimental functions now renamed
+ - `\bool_case_true:n(TF)` (now `\bool_case:n(TF)`)
+ - `\flag_raise_if_clear:n` (now `\flag_ensure_raised:n`)
+ - `\iow_allow_break:` (now `\iow_wrap_allow_break:`)
+- Experimental functions moved to kernel-internal:
+ - `\msg_log_eval:Nn` and `\msg_show_eval:Nn`
+
+## [2023-04-20]
+
+### Changed
+- Re-order arguments of `\text_declare_lowercase_mapping:nnn`,
+ `\text_declare_titlecase_mapping:nnn` and
+ `\text_declare_uppercase_mapping:nnn`
+
+## [2023-04-19]
+
+### Added
+- `\box_set_clipped:N` and variants (renamed from `\box_clip:N`)
+- `\text_declare_lowercase_mapping:nn(n)`,
+ `\text_declare_titlecase_mapping:nn(n)`
+ and `\text_declare_uppercase_mapping:nn(n)` to allow customization of
+ case changing outcomes
+
+### Changed
+- `\box_set_trim:Nnnnn` and `\box_set_viewport:Nnnnn` moved to
+ stable kernel
+
+### Fixed
+- Incorrect internal name in `\pdf_pagesize_gset:nn`
+
+### Removed
+- Experimental `\box_clip:N` and variants (renamed to
+ `\box_set_clipped:N`)
+
+## [2023-03-30]
+
+### Added
+- `\tex_endlocalcontrol:D` as expl3 name for the LuaTeX primitive
+
+### Changed
+- Allow non-integer values in color expressions
+- Restrict color expressions values to the range [0, 100]
+- Leave Greek spacing diacritics unchanged in uppercasing
+
+### Fixed
+- Fix minor version in `\c_sys_engine_version_str` for pdfTeX and LuaTeX
+ (issue [\#1186](https://github.com/latex3/latex3/issues/1186))
+
+## [2023-02-22]
+
+### Changed
+- More defensive approach in `\codepoint_to_nfd:n`
+
+### Fixed
+- CJK character handling for (u)pTeX (issue
+ [\#1171](https://github.com/latex3/latex3/issues/1171))
+
+## [2023-02-07]
+
+### Changed
+- Swap meaning of `el` and `el-x-iota` when case changing
+ Greek: match traditional LaTeX approach
+
+### Deprecated
+- `\l_text_accents_tl` and `\l_text_letterlike_tl`
+
+## [2023-02-02]
+
+### Fixed
+- Handling of multiple accents when uppercasing Greek
+ (see LaTeX2e issue
+ [\#987](https://github.com/latex3/latex2e/issues/987))
+
+## [2023-02-01]
+
+### Fixed
+- Allow for expressions within color `RGB`/`HSB` input
+
+## [2023-01-24]
+
+### Added
+- Complete list of pdfTeX primitives
+
+### Fixed
+- Allow for multi-part BCP47 strings in case changing
+- Loading with plain TeX due to `\outer` status of `^^L`
+ issue ([\#1161](https://github.com/latex3/latex3/issues/1161))
+
+### Changed
+- Leave catcode of `&` unchanged in code environment
+
+## [2023-01-16]
+
+### Added
+- `\pdf_pagesize_gset:nn`
+
+### Fixed
+- Enable `\char_generate:nn` to create active tokens which are `\outer`
+ or equal to `\fi`
+
+## [2022-12-17]
+
+### Added
+- `\codepoint_to_nfd:n`
+- `\codepoint_generate:n` and `\codepoint_str_generate:n`
+- `\str_casefold:n`
+
+### Changed
+- Protect `babel` shorthands from expansion
+
+### Fixed
+- Appearance of `\DescribeOption` (issue
+ [\#1111](https://github.com/latex3/latex3/issues/1111))
+
+## [2022-11-02]
+
+### Added
+- `\prg_gset_conditional:N(p)nn` and
+ `\prg_gset_protected_conditional:N(p)nn`
+
+### Fixed
+- Loading of `expl3` with ConTeXt MkIV (issue
+ [\#1142](https://github.com/latex3/latex3/issues/1142))
+
+## [2022-10-26]
+
+### Changed
+- Usage of `\exp_not:n`/`\exp_not:N` in `\peek_analysis_map_inline:n` output
+
+### Fixed
+- `\peek_analysis_map_inline:n` support for macro parameter characters (issue
+ [\#1109](https://github.com/latex3/latex3/issues/1109)), for many expandable
+ tokens (issue [\#1110](https://github.com/latex3/latex3/issues/1110)), and an
+ esoteric case (issue [\#1113](https://github.com/latex3/latex3/issues/1113))
+- Creation of a message with some engines (issue
+ [\#1139](https://github.com/latex3/latex3/issues/1139))
+
+### Deprecated
+- `\char_to_nfd:N`, `\char_to_nfd:n`
+- `\char_foldcase:N`, `\char_lowercase:N`, `\char_titlecase:N`,
+ `\char_uppercase:N` and `str` variants
+- `\char_to_utfviii_bytes:n`
+- `\str_foldcase:n`
+
+## [2022-09-28]
+
+### Added
+- Set media box for test phase documents
+
+### Fixed
+- Text case switching in `\text_titlecase_first:n` (issue
+ [\#1130](https://github.com/latex3/latex3/issues/1130))
+
+## [2022-08-30]
+
+### Added
+- `\pdf_object_new:n` and `\pdf_object_write:nnn` - support assignment of object
+ type at point-of-writing (issue
+ [\#1123](https://github.com/latex3/latex3/issues/1123))
+- `\text_map_function:nN` and `\text_map_inline:nn` for mapping to
+ graphemes in textual input
+- Support for medieval Latin case changing
+- `\char_to_nfd:n` to extend NFD support to 8-bit engines
+
+### Deprecated
+- `\pdf_object_new:nn` and `\pdf_object_write:nn`, in favor of
+ `\pdf_object_new:n` and `\pdf_object_write:nnn`, respectively
+
+## [2022-08-23]
+
+### Added
+- Shortened range of chars which are left unchanged when converted to
+ strings with `\str_(g)set_convert:Nnnn`.
+- `\color_if_exist:n(TF)`
+- Support for case changing Vietnamese characters with 8-bit engines
+- Parsing of `cmy`, `tHsb` and `&spot` color models to support data exchange with
+ `xcolor`
+
+### Changed
+- Replace `LaTeX3` in message text by `LaTeX`
+
+### Changed
+- Approach to setting current color data from LaTeX2e
+## [2022-08-05]
+
+### Added
+- Support for case changing Croatian diagraph with 8-bit engines
+- Support accent removal when uppercasing Greek with 8-bit engines
+- Function `\sys_ensure_backend:`
+
+### Fixed
+- Behavior of `\color_math:nn` in alignments
+- Expansion of text containing unterminated `\romannumeral` primitives
+
+## [2022-07-21]
+
+### Fixed
+- `\iow_open:N` in ConTeXt MkII
+
+## [2022-07-15]
+
+### Fixed
+- Correct argument order in `\text_case_switch:nnnn`
+
+## [2022-07-14]
+
+### Changed
+- Improved approach to `\text_case_switch:nnnn` expansion
+
+## [2022-07-04]
+
+### Added
+- `\text_declare_case_equivalent:Nn`, `\text_case_switch:nnnn` and
+ related mechanism to allow specialisation of case changing output
+ for selected commands
+
+## [2022-07-01]
+
+### Added
+- `\cs_parameter_spec:N`
+
+### Changed
+- `\text_expand:n` now acts on active chars to support legacy input encodings
+
+### Deprecated
+- `\cs_argument_spec:N`
+
+### Fixed
+- Correct validity check performed by `\regex_show:N` (issue [\#1093](https://github.com/latex3/latex3/issues/1093))
+- Closing of file handles (issue [\#1105](https://github.com/latex3/latex3/issues/1105))
+
+## [2022-06-16]
+
+### Fixed
+- Made `\peek_analysis_map_inline:n` alignment-safe (issue [\#1090](https://github.com/latex3/latex3/issues/1090))
+- Setting a boolean to itself no longer errors (issue [\#1055](https://github.com/latex3/latex3/issues/1055))
+
+## [2022-06-02]
+
+### Changed
+- Exclude only first mandatory argument of entries in
+ `\l_text_case_exclude_arg_tl` from case changing
+
+## [2022-05-30]
+
+### Added
+- Add `\lua_load_module:n`
+
+### Fixed
+- Typo in implementation of titlecase `hy-x-yiwn`
+- Definition order issue with `\str_case:Nn(TF)`
+
+## [2022-05-04]
+
+### Added
+- Language settings `hy` and `hy-x-yiwn` for handling of ech-yiwn ligature
+ uppercasing
+
+### Changed
+- Support BCP 47 properly in case changer language argument
+
+### Fixed
+- Correct `el-xiota` and `de-xeszett` to `el-x-iota` and `de-x-eszett`
+
+## [2022-04-29]
+
+### Added
+- Language setting `el-xiota` for retention of ypogegrammeni when uppercasing
+ Greek
+
+### Changed
+- Rename case-changing variant `de-alt` to `de-xeszett` to align with
+ `luaotfload`
+- Allow for `\lccode`/`\uccode` changes in `\char_...case:n` functions
+
+### Fixed
+- Support for ypogegrammeni in case changing Greek (see issue [\#1088](https://github.com/latex3/latex3/issues/1088))
+
+## [2022-04-20]
+
+### Changed
+- Collect some common code from `l3backend-color`
+
+## [2022-04-10]
+
+### Added
+- `\keys_precompile:nnN` for conversion of keyvals to fast-to-apply token
+ lists
+- Missing `\str_if_empty:n(TF)` (see issue [\#1071](https://github.com/latex3/latex3/issues/1071))
+- Missing `\str_case:Nn(TF)` (see issue [\#1071](https://github.com/latex3/latex3/issues/1071))
+- `\tex_...:D` names for primitives added in TeX Live 2022
+
+### Changed
+- Definition of `\legacy_if:n(TF)` to support primitive conditionals
+- `\str_<type>case:n` now case changes codepoints above 127 with all engines
+- `\char_generate:nn` now also allows to generate category 10 tokens (spaces)
+ except for char code 0
+
+### Fixed
+- Handling of 'misplaced' `\protect` by `\text_expand:n`
+- Nesting of `\tl_analysis_map_inline:nn`
+- Naming of an error message
+
+## [2022-02-24]
+
+### Changed
+- Better support for `\cite`, _etc._, in case changing
+
+## [2022-02-21]
+
+### Fixed
+- Use of `\@uclclist` for case changing
+
+## [2022-02-05]
+
+### Added
+- Distribute `l3doc.pdf` with a prominent warning about future changes
+- `\color_math:nn(n)` as a functional equivalent of the new `\mathcolor`
+ command in LaTeX2e
+
+### Changed
+- Documentation for horizontal coffin poles (see issue [\#1041](https://github.com/latex3/latex3/issues/1041))
+- Update primitive requirements to enable loading with Prote/HINT
+
+## [2022-01-21]
+
+### Changed
+- Auto-generate legacy switch if required in `.legacy_set_if:n`
+ key property
+
+### Fixed
+- Correct creation of `.if` property
+- Handling of colors created in a group once they go out-of-scope
+
+## [2022-01-12]
+
+### Added
+- Support for validity scope for keys
+- `\peek_remove_filler:n`
+- `\prop_to_keyval:N`
+- `\regex_match_case:nn(TF)`, `\regex_replace_case_once:nN(TF)`,
+ `\regex_replace_case_all:nN(TF)`
+
+### Changed
+- Policy change: functions will no longer be removed after deprecation,
+ thus the Lua functions noted below are the *last* 'stable' code to be
+ removed from `l3kernel` after deprecation
+- Allow indirect conversions between colorspaces through fallback models
+- Move some color functions from `l3backend`
+
+### Deprecated
+- `\peek_..._ignore_spaces:N(TF)` functions
+- `\sys_load_deprecation:`
+- Option `undo-recent-deprecations`
+
+### Removed
+- Lua functions in `l3kernel` table
+
+## [2021-11-22]
+
+### Added
+- Support for legacy `if` switches in `l3keys`
+
+### Changed
+- Documentation improvements
+- Implementation of `intarray` data type with LuaTeX
+- Better support for LuaMetaTeX
+
+## [2021-11-12]
+
+### Fixed
+- DeviceN colorspace conversions with alternative model RGB
+
+### Added
+- `.str_set:N`, etc., key properties (issue [\#1007](https://github.com/latex3/latex3/issues/1007))
+- `\bool_to_str:n` (issue [\#1010](https://github.com/latex3/latex3/issues/1010))
+
+### Changed
+- `\prop_..._from_keyval:Nn` functions now support active comma or
+ equal sign (pull \#1012)
+
+## [2021-10-18]
+
+### Added
+- Support for ICC-based color profiles
+- `\color_profile_apply:nn`
+
+## [2021-10-17]
+
+### Changed
+- Better DeviceN support
+
+## [2021-10-12]
+
+### Fixed
+- Global assignments for `\box_gresize_to_ht_plus_dp:Nn`
+ and `\coffin_gattach:NnnNnnnn`
+- Conversion of DeviceN colors to device fallback
+
+## [2021-08-27]
+
+### Changed
+- Formatting of expandable errors (issue [\#931](https://github.com/latex3/latex3/issues/931))
+- Internal code for kernel messages
+
+## [2021-07-12]
+
+### Fixed
+- Handling of multiple color models (issue [\#962](https://github.com/latex3/latex3/issues/962))
+
+### Removed
+- Functions marked for removal end-2020
+
+## [2021-06-18]
+
+### Fixed
+- Local assignment to `\g__sys_backend_tl`
+- Incorrect internal function name (issue [\#939](https://github.com/latex3/latex3/issues/939))
+- Case-changing exceptions for (u)pTeX (issue [\#939](https://github.com/latex3/latex3/issues/939))
+- Low-level error if accent commands are not followed by
+ letter when case changing (see \#946)
+
+## [2021-06-01]
+
+### Fixed
+- Loading when `\expanded` is not available
+
+## [2021-05-27]
+
+### Fixed
+- Correctly detect local formats in `Mismatched LaTeX support files` error.
+
+## [2021-05-25]
+
+### Added
+- `\msg_note:nnnnnn` (issue [\#911](https://github.com/latex3/latex3/issues/911))
+- `\str_compare:nNnTF` (issue [\#927](https://github.com/latex3/latex3/issues/927))
+- `\sys_timer:`
+- `\prop_concat:NNN`, `\prop_put_from_keyval:Nn` (issue [\#924](https://github.com/latex3/latex3/issues/924))
+- Functions to show and log various datatypes (issue [\#241](https://github.com/latex3/latex3/issues/241)):
+ `\coffin_show:Nnn`, `\coffin_show:N`, `\coffin_log:Nnn`, `\coffin_log:N`,
+ `\color_log:n`, `\group_show_list:`, `\group_log_list:`,
+ `\ior_show:N`, `\ior_log:N`, `\iow_show:N`, `\iow_log:N`,
+ `\tl_log_analysis:N`, `\tl_log_analysis:n`
+- `\legacy_if_set_true:n`, `\legacy_if_set_false:n`, `\legacy_if_set:nn`
+- Matching multiple regex at the same time (issue [\#433](https://github.com/latex3/latex3/issues/433)):
+ `\regex_case_match:nn(TF)`,
+ `\regex_case_replace_once:nN(TF)`,
+ `\regex_case_replace_all:nN(TF)`
+
+### Fixed
+- Checking brace balance in all regex functions (issue [\#377](https://github.com/latex3/latex3/issues/377))
+- Removing duplicates in clists when items contain commas (issue [\#917](https://github.com/latex3/latex3/issues/917))
+
+### Changed
+- Slight speed up in some elementary int/dim/skip/muskip operations and
+ in setting tl or clist variables equal.
+- Speed up mapping functions in l3clist, l3prop, l3seq, l3tl
+
+## [2021-05-11]
+
+### Added
+- `\cctab_item:Nn` (issue [\#880](https://github.com/latex3/latex3/issues/880))
+- `\clist_use:nnnn` and `\clist_use:nn` (issue [\#561](https://github.com/latex3/latex3/issues/561))
+
+### Fixed
+- Loading of backend in generic DVI mode (issue [\#905](https://github.com/latex3/latex3/issues/905))
+- Make `\keyval_parse:nnn` alignment-safe (issue [\#896](https://github.com/latex3/latex3/issues/896))
+- Control sequences and category codes in regex replacements (issue [\#909](https://github.com/latex3/latex3/issues/909))
+
+### Changed
+- Speed up `\group_align_safe_begin:` (pull \#906)
+
+## [2021-05-07]
+
+### Added
+- Color export in comma-separated format
+- `\ur{...}` escape in `l3regex` to compose regexes
+- `\seq_set_split_keep_spaces:Nnn` (see \#784)
+- `\seq_set_item:Nnn(TF)` and `\seq_pop_item:NnN(TF)`
+- `\box_ht_plus_dp:N` (issue [\#899](https://github.com/latex3/latex3/issues/899))
+- `\clist_map_tokens:nn`, `\clist_map_tokens:Nn`,
+ `\str_map_tokens:nn`, `\str_map_tokens:Nn`
+
+### Changed
+- Use prevailing catcodes instead of string in regex replacement (issue [\#621](https://github.com/latex3/latex3/issues/621))
+ (*Breaking change*)
+- `\__kernel_file_name_sanitize:n` now uses a faster `\csname`-based
+ approach to expand the file name
+- Improved performance for basic conditionals
+- `\pdf_version_gset:n` support for `dvips`
+- Improve handling of `\exp_not:n` in `\text_expand:n` (issue [\#875](https://github.com/latex3/latex3/issues/875))
+- `\file_full_name:n` now avoids calling `\pdffilesize` primitive multiple times
+ on the same file
+- Show printable characters explicitly in `\regex_show:n`
+- Regex replacement now errors when using a submatch (`\1` etc) for which
+ the regex has too few groups
+- Showing complex datatypes now validates their internal structure (issue [\#884](https://github.com/latex3/latex3/issues/884))
+- Indexing in l3doc: all page references before codeline references,
+ improve target placement, solve pdfTeX and makeindex warnings
+
+### Fixed
+- Evalutate integer constants only once (issue [\#861](https://github.com/latex3/latex3/issues/861))
+- Detect `\ior_map_inline:Nn` calls on undefined streams (issue [\#194](https://github.com/latex3/latex3/issues/194))
+
+### Deprecated
+- `l3docstrip` converted to a stub which simply loads DocStrip: use
+ the latter directly
+
+## [2021-02-18]
+
+### Added
+- `l3color`: Moved from `l3experimental`
+- `l3pdf`: Moved from `l3experimental`
+- `default` alias to str_convert
+
+### Changed
+- Re-ordered `interface3` documentation
+- Moved `msg_show:nn(nnnn)` to stable
+
+## [2021-02-06]
+
+### Changed
+- Use new (internal) interface for kerns
+
+## [2021-02-02]
+
+### Added
+- `\c_zero_str`
+
+## [2021-01-09]
+
+### Added
+- `\keyval_parse:nnn`
+
+### Changed
+- `\keyval_parse:NNn` is set equal to `\keyval_parse:nnn`
+
+### Fixed
+- Handling of encoding-specfic commands in `\text_purify:n`
+
+## [2020-12-07]
+
+### Fixed
+- `\peek_analysis_map_inline:n` with spaces and braces
+
+## [2020-12-05]
+
+### Fixed
+- Setting of line width in vertical coffins in LaTeX
+
+## [2020-12-03]
+
+### Added
+- `\peek_analysis_map_inline:n`
+- `\peek_regex:nTF`, `\peek_regex_remove_once:nTF`, and
+ `\peek_regex_replace_once:nnTF`
+- `\token_case_catcode:NnTF`, `\token_case_charcode:NnTF`, and
+ `\token_case_meaning:NnTF`
+
+### Changed
+- Extend `\text_expand:n` to cover `\@protected@testopt`
+- Extend `\text_purify:n` to cover `\@protected@testopt`
+
+## [2020-10-27]
+
+### Added
+- `\token_if_font_selection:N(TF)` (see \#806)
+
+### Fixed
+- Avoid relying on braced `\input` primitive syntax
+- Correct expansion of environments in `\text_purify:n`
+- Some aspects of `cctab` setup with 8-bit engines(issue [\#814](https://github.com/latex3/latex3/issues/814))
+
+### Changed
+- Improved performance for `tl` functions
+- Extend case changer to cover all of Greek with pdfTeX
+
+## [2020-10-05]
+
+### Fixed
+- Correctly detect LaTeX when pre-loading expl3 and setting up
+ case changer
+- Lua emulation of \strcmp (issue [\#813](https://github.com/latex3/latex3/issues/813))
+
+## [2020-09-24]
+
+### Changed
+- Use Lua pseudo-primitives instead of `\directlua`
+- `\token_if_primitive:N(TF)` now reports pseudo-primitives as primitives in LuaTeX
+
+## [2020-09-06]
+
+### Fixed
+- Loading in generic mode (issue [\#800](https://github.com/latex3/latex3/issues/800))
+
+## [2020-09-03]
+
+### Fixed
+- Save primitive definition of `\pdfoutput` with CSLaTeX
+
+## [2020-09-01]
+
+### Added
+- `\hbox_overlap_center:n`
+
+### Changed
+- Backend setting for direct PDF output
+- Backend setting for XeTeX support
+
+### Deprecated
+- Backend setting `pdfmode`
+
+### Fixed
+- `\file_compare_timestamp:nNn(TF)` in LuaTeX (issue [\#792](https://github.com/latex3/latex3/issues/792))
+- Text case changing and expansion where an excluded command is equivalent
+ to `\use:n`
+
+## [2020-08-07]
+
+### Changed
+- Color selection implementation
+- Performance enhancements for `\keys_set:nn`
+
+### Fixed
+- Loading generically on ConTeXt (issue [\#783](https://github.com/latex3/latex3/issues/783))
+
+## [2020-07-17]
+
+### Added
+- `l3cctab` module for using category code tables
+- `\file_parse_full_name:n` and `\file_parse_full_name_apply:nN`
+- Additional `\prop_put:Nnn` variants
+- `\seq_set_map_x:NNn`
+- `\msg_term:nn(nnnn)`
+
+### Fixed
+- File lookup with `\input@path`
+- 8-bit encodings in `\str_set_convert:Nnnn`
+
+### Changed
+- Implementation of `\file_parse_full_name:nNNN` now uses
+ `\file_parse_full_name:n` internally
+- `\seq_set_map:NNn` no longer `x`-expands `<inline function>`
+ (`\seq_set_map_x:NNn` now does that). Both moved to stable.
+
+### Removed
+- Functions deprecated at end of 2019
+
+### Deprecated
+- `\str_declare_eight_bit_encoding:nnn`
+
+## [2020-06-18]
+
+### Changed
+- Use `scn` operator for separations
+- Internal color model
+- Internal performance enhancements
+- Moved `\msg_expandable_error:nn(nnnn)` to stable.
+- Moved `\seq_indexed_map_inline:Nn` and `\seq_indexed_map_function:Nn`
+ to stable as `\seq_map_indexed_inline:Nn` and `\seq_map_indexed_function:Nn`.
+- Internal changes to `expl3` to allow loading earlier in LaTeX2e.
+
+## [2020-06-03]
+
+### Added
+- `\str_convert_pdfname:n`
+
+## [2020-05-15]
+
+### Changed
+- Make `\text_purify:n` `f`-type expandable
+
+## [2020-05-14]
+
+### Changed
+- Performance improvements in keyval processing
+
+## [2020-05-11]
+
+### Changed
+- Internal changes to quark handling
+
+## [2020-05-05]
+
+### Added
+- Recognize the exponent marker `E` (same as `e`) in floating point numbers
+
+### Fixed
+- Leave active characters untouched when case-changing (see \#715)
+
+## [2020-04-06]
+
+### Added
+- Control for start-of-titlecasing: see `\l_text_titlecase_check_letter_bool`
+
+### Fixed
+- Nesting of `\seq_shuffle:N` in another sequence mapping (issue [\#687](https://github.com/latex3/latex3/issues/687))
+- `\ior_shell_open:Nn` in engines other than LuaTeX - shell commands didn't
+ execute, plus the command call would be left in the input stream.
+
+## [2020-03-06]
+
+### Added
+- `\text_purify:n`
+
+### Fixed
+- Issue with case-changing Turkish
+
+## [2020-03-03]
+
+### Added
+- `\tex...:D` coverage for TeX Live 2020 engine changes
+
+### Changed
+- New implementation for `\keyval_parse:NNn` - around 40% speed improvement,
+ also *expandable*
+
+### Fixed
+- Make `expl3` reload-safe for `latexrelease` (see latex3/latex2e#295)
+
+## [2020-02-25]
+
+### Changed
+- Extend case-changing encoding support to Cyrillic and Greek
+
+## [2020-02-21]
+
+### Added
+- Option `suppress-backend-headers` (see matching change in
+ `l3backend`)
+
+### Changed
+- Allow `dvisvgm` driver with XeTeX (issue [\#677](https://github.com/latex3/latex3/issues/677))
+
+### Fixed
+- `undo-recent-deprecations` would not reload the deprecation code
+
+## [2020-02-14]
+
+### Fixed
+- Interaction with some `babel` languages at the start of the document
+
+## [2020-02-13]
+
+### Changed
+- Leave implicit tokens unchanged by `\text_expand:n`
+- Extend the `de-alt` case changing locale to 8-bit engines
+
+## [2020-02-11]
+
+### Added
+- Key property `.cs_set:Np` and variants
+
+### Changed
+- Support `\@uclclist` entries when case-changing
+
+### Fixed
+- Allow for full range of encodings when expanding text (issue [\#671](https://github.com/latex3/latex3/issues/671))
+- Support `\begin`/`\end` in text expansion
+
+## [2020-02-08]
+
+### Added
+- `\l_keys_key_str` and `\l_keys_path_str`
+
+### Deprecated
+- `\l_keys_key_tl` and `\l_keys_path_tl`, replaced by `\l_keys_key_str` and
+ `\l_keys_path_str`, respectively
+
+## [2020-02-03]
+
+### Changed
+- Minor edits to LaTeX3 News
+
+## [2020-01-31]
+
+### Added
+- Table of Contents for combined LaTeX3 News
+
+### Changed
+- Use Lua `utf8` library if available
+
+### Fixed
+- Undefined command in box debugging code
+
+## [2020-01-22]
+
+### Added
+- Support for command replacement in text expansion
+
+### Changed
+- Require key values for numerical key types (dim, int, etc.) (see \#661)
+
+### Fixed
+- Issue with keys where some leading spaces could be left in key names
+
+## [2020-01-12]
+
+### Added
+- `\bool_case_true:n(TF)` and `\bool_case_false:n(TF)`
+- `\file_hex_dump:n(nn)` and `\file_get_hex_dump:n(nn)N(TF)`
+- `\str_<type>case:n`
+- `\text_<type>case:n(n)`
+- `\text_expand:n` and supporting data structures
+
+### Changed
+- Distribute LaTeX3 News
+- Moved `\char_<type>case:N` to stable
+- Documentation improvements
+
+### Fixed
+- Inherit key required/forbidden properties (see \#653)
+- Set backend at the beginning of `\document` (see \#657)
+
+### Deprecated
+- `\str_<type>_case:n` replaced by `\str_<type>case:n`
+ except `\str_mixed_case:n` replaced by `\str_titlecase:n`
+- `\tl_<type>_case:n(n)` replaced by `\text_<type>case:n(n)`,
+ except `\tl_mixed_case:n(n)` replaced by `\text_titlecase:n(n)`
+
+## [2019-11-07]
+
+### Fixed
+- Handling of repeated loading of a backend (issue [\#646](https://github.com/latex3/latex3/issues/646))
+- Handling of repeated loading of deprecated functions
+
+## [2019-10-28]
+
+### Fixed
+- File searching when `\(pdf)filesize` is not available (issue \#644)
+
+## [2019-10-27]
+
+### Changed
+- Internal structure of `\c_sys_jobname_str` altered
+- Update upTeX test to follow guidance from developers
+
+## [2019-10-24]
+
+### Changed
+- File names are now returned without quotes by `\file_full_name:n`
+
+### Fixed
+- `\file_if_exist:n(TF)`, etc., when dealing with file names containing
+ spaces (see \#642)
+
+## [2019-10-21]
+
+### Added
+- Lua function `l3kernel.shellescape()`
+
+### Changed
+- Better coverage of (u)pTeX primitives following publication of
+ pTeX manual in English
+- Trim spaces surrounding file names
+
+### Removed
+- HarfTeX primitives
+
+## [2019-10-14]
+
+### Fixed
+- Correct handling of 'traditional' class options for backend
+
+## [2019-10-11]
+
+### Changed
+- Standard backend for (u)pTeX is now `dvips`
+- Minimum LuaTeX version now v0.95
+- Moved `\debug_on:n`, `\debug_off:n`, `\debug_suspend:` and `\debug_resume:`
+ to stable
+- Accept 'traditional' class options for backend (`dvipdfmx`, `dvips`, etc.)
+- Performance enhancements when loading `expl3`
+
+### Fixed
+- Handling of files with no extension
+- Behaviour of Lua function `l3kernel.charcat` in some circumstances
+- Loading under ConTeXt
+
+## [2019-10-02]
+
+### Fixed
+- Variants using `\exp_args` functions with more than 9 arguments (see \#636)
+
+## [2019-09-30]
+
+### Fixed
+- File searching using `\file_full_name:n` (see \#634)
+
+## [2019-09-28]
+
+### Changed
+- Speed up variants and reduce their `\tracingall` output
+- Debug and deprecation code are now loaded independently of expl3 core
+- `\file_compare_timestamp:nNn(TF)` now usable in expansion contexts
+- Moved to stable:
+ - `\bool_const:Nn`
+ - `\dim_sign:n`
+ - `\file_compare_timestamp:nNn(TF)`
+ - FP `logb` operator
+ - `\fp_sign:n`
+ - `fparray` module
+ - `\int_sign:n`
+ - `\intarray_const_from_clist:Nn`
+ - `\intarray_show:N`
+ - `\ior_map_variable:NNn`
+ - `\ior_str_map_variable:NNn`
+ - `\mode_leave_vertical:`
+ - `\prop_(g)set_from_clist:Nn`
+ - `\prop_const_from_clist:Nn`
+ - `\seq_const_from_clist:Nn`
+ - `\seq_(g)shuffle:N`
+ - `\sys_if_platform_unix:(TF)`
+ - `\sys_if_platform_windows:(TF)`
+ - `\sys_gset_rand_seed:`
+ - `\sys_rand_seed:`
+ - Shell access functions
+
+### Fixed
+- Key `.initial:n` property when combined with inherited keys (see \#631)
+
+## [2019-09-19]
+
+### Fixed
+- Loading Unicode data when some chars may be active (see \#627)
+
+## [2019-09-08]
+
+### Fixed
+- Missing internal variant (issue \#624)
+
+## [2019-09-05]
+
+### Added
+- `\file_full_name:n`, `\file_mdfive_hash:n`, `\file_size:n`,
+ `\file_timestamp:n`
+- `\seq_map_tokens:Nn`, `\tl_map_tokens:nn`, `\tl_map_tokens:Nn`
+
+### Changed
+- Moved `\prop_map_tokens:Nn` to stable
+- Generate chars with catcode as-supplied when case changing
+
+## [2019-08-25]
+
+### Added
+- `\fp_if_nan:nTF`
+
+### Changed
+- Make round(.,nan)=nan with no "Invalid operation" error
+
+### Fixed
+- `\tl_rescan:nn` and `\tl_(g)set_rescan:Nnn` when single-line input
+ contains a comment character (see \#607)
+- Final value of the variable in `\tl_map_variable:NNn` and
+ `\clist_map_variable:NNn`.
+- Remove duplicate keys in `\prop_set_from_keyval:Nn` (see \#572)
+
+## [2019-08-14]
+
+### Deprecated
+- `\c_term_ior`
+
+### Fixed
+- Coffin pole intersection in some cases (see \#605)
+
+## [2019-07-25]
+
+### Fixed
+- Loading for `expl3` with plain TeX
+
+## [2019-07-01]
+
+### Added
+- Moved `l3str-convert` module to `l3kernel`
+
+### Changed
+- Ensure `\msg_fatal:nn` ends the TeX run if used inside an
+ hbox (see \#587)
+- Moved backend code to a separate release schedule
+
+### Fixed
+- Handling of control sequences in key names (see \#594)
+
+## [2019-05-28]
+
+### Added
+- Experimental `\file_compare_timestamp:nNn(TF)`
+
+### Changed
+- Precedence of juxtaposition (implicit multiplication) in `l3fp`
+ now different for keywords/variables and factors in parentheses
+
+## [2019-05-09]
+
+### Added
+- Experimental driver-level interfaces for image inclusion
+- Experimental `\ior_shell_open:Nn`
+
+### Fixed
+- Some issues in `dvisvgm` driver
+
+## [2019-05-07]
+
+### Added
+- `.muskip_set:N` property
+
+### Changed
+- Experimental `\driver_pdf_compress_objects:n` replaces
+ `\driver_pdf_objects_(en|dis)able:`
+
+## [2019-05-05]
+
+### Added
+- `\char_str_<target>_case:N`
+
+### Fixed
+- Infinite loop in some cases in DVI mode due to link-breaking code
+ (see \#570)
+- Category code of output from `\char_<target>_case:N`, and
+ same issue in `\str_<target>_case:n`
+
+## [2019-05-03]
+
+### Added
+- New `l3legacy` module containing
+ - `\legacy_if:n(TF)`
+
+### Changed
+- Moved `\file_get_mdfive_hash:nN(TF)`, `\file_get_size:nN(TF)`
+ and `\file_get_timestamp:nN(TF)` to stable
+- Moved `\file_if_exist_input:n` and `\file_if_exist_input:nF` to stable
+- Moved `\file_input_stop:` to stable
+- Moved `\peek_N_type:TF` to stable
+
+## [2019-04-21]
+
+### Added
+- Experimental support for a range of PDF concepts at the lowest
+ (driver abstraction) level
+
+## [2019-04-06]
+
+### Changed
+- Moved `\tl_if_single_token:n(TF)` to stable
+
+### Fixed
+- Support for ConTeXt from mid-December 2018
+
+## [2019-03-26]
+
+### Fixed
+- Loading when pre-TL'18 XeTeX is in use (see \#555)
+
+## [2019-03-05]
+
+### Added
+- `\str_log:n`, `\str_log:N`
+- `TF` versions for `\file_get_...:nN` and `\ior_(str_)get:NN` functions
+- `\cs_prefix_spec:N`, `\cs_argument_spec:N`, `\cs_replacement_spec:N`
+- `undo-recent-deprecations` option
+- `factorial` function in `l3fp`
+
+### Changed
+- Return values from `\file_get:nnN`, `\file_get_...:nN`, `\ior_get:NN`,
+ `\sys_shell_get:nnN`
+- Moved coffin affine transformations to stable
+- Moved `\prop_count:N` to stable
+- Moved `\tl_count_tokens:n` to stable
+- Completed emulation of e-type argument when `\expanded` is unavailable
+- Made expandable messages expand their result, like usual messages
+- Made deprecation errors less intrusive by default
+- Stopped providing do-nothing `\color` macro when undefined
+
+### Deprecated
+- `\token_get_prefix_spec:N`, `\token_get_arg_spec:N`,
+ `\token_get_replacement_spec:N` replaced by `\cs_prefix_spec:N`,
+ `\cs_argument_spec:N`, `\cs_replacement_spec:N`, respectively
+
+### Fixed
+- Treatment of inherited keys when setting only known keys (see \#548)
+
+### Removed
+- Experimental `\skip_split_finite_else_action:nnNN`
+- Experimental `\tl_reverse_tokens:n`
+
+## [2019-02-15]
+
+### Changed
+- Defensive code for redefinition of `\time`, `\day`, `\month` and `\year`
+
+### Fixed
+- Resetting of key inheritance (see \#535)
+- Issue in deprecated command `\tl_set_from_file:Nnn`
+ (see https://tex.stackexchange.com/q/474813/)
+
+## [2019-02-03]
+
+### Added
+- Support for return of whole path by `\keys_set_known:nnN`-like
+ function `\keys_set_known:nnnN` (see \#508)
+- `.prop_(g)put:N` key property (see \#444)
+
+### Fixed
+- Handling of nested key setting when filtering, _etc._ (see \#526)
+- Inheritance of default values (see \#504)
+
+## [2019-01-28]
+
+### Added
+- Global versions of box affine functions, e.g. `\box_grotate:Nn`
+- Global versions of box size adjustment functions
+- `\box_(g)set_eq_drop:NN`, `\(h|v)box_unpack_drop:N`
+- `\file_get:nnN` and `\file_get:nnNTF`
+- Experimental functions `\sys_shell_get:nnN` and `\sys_shell_get:nnNTF`
+
+### Changed
+- `\char_generate:nn` now always takes exactly two expansions
+- Move `\prg_generate_conditional_variant:Nnn` to stable
+- Renamed experimental `\box_trim:Nnnnn` and `\box_viewport:Nnnnn` as
+ `\box_set_trim:Nnnnn` and `\box_set_viewport:Nnnnn`, respectively
+
+### Deprecated
+- `\box_(g)set_eq_clear:NN`, replaced by `\box_(g)set_eq_drop:NN`
+- `\(h|v)box_unpack_clear:N`, replaced by `\(h|v)box_unpack_drop:N`
+- `\tl_(g)set_from_file(_x):Nnn`, replaced by `\file_get:nnN`
+
+### Fixed
+- Scope treatment of `\box_set_dp:N`, _etc._
+- In (u)platex: detection of spaces in `\tl_rescan:nn` and related functions
+
+### Removed
+- Experimental function family `\tl_(g)set_from_shell:(N|c)nn`
+ (replaced by `\sys_shell_get:nnN`)
+
+## [2019-01-13]
+
+### Added
+- `\ior_map_variable:NNn` and `\ior_str_map_variable:NNn`
+
+### Fixed
+- Unclosed conditional with Unicode engines
+
+## [2019-01-12]
+
+### Changed
+- Improved `expl3` loading time with LuaTeX and XeTeX
+- Improved performance of `\ior_map_inline:Nn` and related functions
+
+### Fixed
+- Handling of accented characters under mixed case changing in 8-bit engines
+ (see \#514)
+
+## [2019-01-01]
+
+### Added
+- `\iow_allow_break:`
+
+### Fixed
+- Correct fp randint with zero argument (see \#507)
+- Handling of `\current@color` with `(x)dvipdfmx` (see \#510)
+
+### Removed
+- Support for stand-alone `l3regex`, `l3sort`, `l3srt`, `l3tl-analysis`,
+ `l3tl-build`
+- `\box_resize:Nnn`
+- `\box_use_clear:N`
+- `\c_minus_one`
+- `\file_add_path:nN`
+- `\file_list:`
+- `\file_path_include:n` and `\file_path_remove:n`
+- `\io(r|w)_list_streams:` and `\io(r|w)_log_streams:`
+- `\sort_ordered:` and `\sort_reversed:`
+- `\token_new:Nn`
+- Generation of invalid variants from `n`/`N` base types
+
+## [2018-12-12]
+
+### Changed
+- Move `\tl_range:nnn` to stable
+
+### Fixed
+- Loading in ConTeXt MkIV
+
+## [2018-12-11]
+
+### Changed
+- Enable `\char_generate:nn` to create active tokens with XeTeX
+
+## [2018-12-06]
+
+### Changed
+- Apply `\par` only at the end of vertical boxes
+- Move `\int_rand:n` to stable
+- Move `\<var>_rand_item:N` to stable
+
+### Fixed
+- Typo in `\lua_shipout_e:n` (see \#503)
+
+## [2018-11-19]
+
+### Added
+- Support for cross-compatibility primitives in XeTeX
+- `\int_sign:n`, `\dim_sign:n` and `\fp_sign:n`
+
+## [2018-10-19]
+
+### Fixed
+- Wrapping of text in messages, etc., for some line lengths (issue \#491)
+
+## [2018-10-17]
+
+### Added
+- `\g_msg_module_documentation_prop` (see \#471)
+- `\peek_remove_spaces:n`
+
+### Changed
+- Formatting of messages: now follows LaTeX2e closely
+
+### Deprecated
+- `\msg_interrupt:nn`, `\msg_log:n` and `\msg_term:n`
+
+### Fixed
+- Handling of inheritance for choice keys (issue \#483)
+
+## [2018-09-24]
+
+### Added
+- Some driver-level support for PDF features
+- `\peek_catcode_collect_inline:Nn`, `\peek_charcode_collect_inline:Nn`,
+ `\peek_meaning_collect_inline:Nn`
+
+### Fixed
+- Handling of unknown keys when inheritance is active (issue \#481)
+
+## [2018-08-23]
+
+### Added
+- `\lua_escape:e`, `\lua_now:e` and `\lua_shipout_e:n`
+- `\str_case_e:nn(TF)` and `\str_if_eq:ee(TF)`
+- `\sys_if_platform_unix:(TF)` and `\sys_if_platform_windows:(TF)`
+- `\tl_(g)set_from_shell:Nnn`
+
+### Deprecated
+- `\lua_escape_x:n`, `\lua_now_x:n` and `\lua_shipout_x:n`
+- `\str_case_x:nn(TF)` and `\str_if_eq_x:nn(TF)`
+
+## [2018-06-14]
+
+### Added
+- Support for `e`-type argument using `\expanded` or macro emulation
+
+## [2018-06-01]
+
+### Added
+- `CHANGELOG.md` (issue \#460)
+
+### Fixed
+- Loading `expl3` with LuaTeX/XeTeX and certain letter tokens set
+ to be active (see \#462)
+
+### Changed
+- Alter `\char_codepoint_from_bytes:n` to produce four groups in all
+ cases; make `f`-type expandable
+
+## [2018-05-13]
+
+### Fixed
+- Correct date string in `expl3.dtx`
+- Correct `\c_sys_engine_version_str` when using XeTeX
+
+## [2018-05-12]
+
+### Added
+- Define `\c_zero_int` and `\c_one_int`
+- Implement `\c_sys_engine_version_str`
+- Implement `\seq_indexed_map_function/inline`
+- Implement `\intarray_gzero:N`
+- Implement `\intarray_const_from_clist:Nn`
+- Implement `\bool_set_inverse:N`
+- Implement `\bool_xor:nnTF` instead of just `\bool_xor_p:nn`
+- Implement candidate `\int_rand:n`
+- Implement `\intarray_gset_rand:Nnn`
+- Implement candidate `l3fparray` module
+
+### Changed
+- Update minimal required versions of XeTeX and LuaTeX
+- Deprecate named integer constants `\c_zero`. etc.
+- Move all primitives to `\tex_...:D namespace`,
+ deprecating older engine-dependent prefixes
+- Several internal optimisations
+
+### Fixed
+- Expand boolean expression before calling `\chardef` (issue \#461)
+
+### Removed
+- Remove undocumented `\fp_function:Nw` and `\fp_new_function:Npn`
+
+## [2018-04-30]
+
+### Added
+- Implement `\tl_analysis_map_inline:nn`
+- Implement `\exp_args_generate:n` to define new `\exp_args:N...`
+ functions
+- Low-level `\int_value:w` function
+- New experimental functions for
+ - Building token lists piecewise
+ - Fast manipulation of integer arrays
+ - Sequence shuffling
+ - `\seq_set_from_function:NnN`
+ - `\char_codepoint_to_bytes:n`
+
+### Changed
+- Significant internal revision to use only internal functions
+ 'private' to specific modules
+- Better documentation of cross-module kernel-internal functions
+- Enable `\char_generate:nn` for active chars
+- Renamed `\tl_show_analysis:(N|n)n` as `\tl_analysis_show:(N|n)n`
+- Change `\int_rand:nn` (and rand_item functions) to better use
+ the RNG
+- Make prg break functions public
+- Make scan marks mechanism public
+- Make `\prg_do_nothing:` long rather than nopar (issue \#455)
+- Several performance improvements
+- Documentation improvements
+
+### Fixed
+- Only index TF, T, F functions together if they are `expl3`
+ functions (issue \#453)
+- Make `\infty` and `\pi` into errors in fp expressions
+ (issue \#357)
+
+### Removed
+- Deprecated functions expiring at end of 2017
+- Old module `.sty` files
+
+## [2018-03-05]
+
+### Changes
+- Adjustments to `l3drivers` to support `l3draw` development in
+ `l3experimental` bundle
+
+## [2018-02-21]
+
+### Added
+- Tuple support in fp expressions
+- Step functions have been added for dim variables,
+ e.g. `\dim_step_inline:nnnn`
+
+[Unreleased]: https://github.com/latex3/latex3/compare/2024-04-11...HEAD
+[2024-04-11]: https://github.com/latex3/latex3/compare/2024-03-14...2024-04-11
+[2024-03-14]: https://github.com/latex3/latex3/compare/2024-02-20...2024-03-14
+[2024-02-20]: https://github.com/latex3/latex3/compare/2024-02-18...2024-02-20
+[2024-02-18]: https://github.com/latex3/latex3/compare/2024-02-13...2024-02-18
+[2024-02-13]: https://github.com/latex3/latex3/compare/2024-01-22...2024-02-13
+[2024-01-22]: https://github.com/latex3/latex3/compare/2024-01-04...2024-01-22
+[2024-01-04]: https://github.com/latex3/latex3/compare/2023-12-11...2024-01-04
+[2023-12-11]: https://github.com/latex3/latex3/compare/2023-12-08...2023-12-11
+[2023-12-08]: https://github.com/latex3/latex3/compare/2023-11-09...2023-12-08
+[2023-11-09]: https://github.com/latex3/latex3/compare/2023-11-01...2023-11-09
+[2023-11-01]: https://github.com/latex3/latex3/compare/2023-10-23...2023-11-01
+[2023-10-23]: https://github.com/latex3/latex3/compare/2023-10-10...2023-10-23
+[2023-10-10]: https://github.com/latex3/latex3/compare/2023-08-29...2023-10-10
+[2023-08-29]: https://github.com/latex3/latex3/compare/2023-08-11...2023-08-29
+[2023-08-11]: https://github.com/latex3/latex3/compare/2023-08-03...2023-08-11
+[2023-08-03]: https://github.com/latex3/latex3/compare/2023-06-30...2023-08-03
+[2023-06-30]: https://github.com/latex3/latex3/compare/2023-06-16...2023-06-30
+[2023-06-16]: https://github.com/latex3/latex3/compare/2023-06-05...2023-06-16
+[2023-06-05]: https://github.com/latex3/latex3/compare/2023-05-22...2023-06-05
+[2023-05-22]: https://github.com/latex3/latex3/compare/2023-05-15...2023-05-22
+[2023-05-15]: https://github.com/latex3/latex3/compare/2023-05-11...2023-05-15
+[2023-05-11]: https://github.com/latex3/latex3/compare/2023-05-05...2023-05-11
+[2023-05-05]: https://github.com/latex3/latex3/compare/2023-04-20...2023-05-05
+[2023-04-20]: https://github.com/latex3/latex3/compare/2023-04-19...2023-04-20
+[2023-04-19]: https://github.com/latex3/latex3/compare/2023-03-30...2023-04-19
+[2023-03-30]: https://github.com/latex3/latex3/compare/2023-02-22...2023-03-30
+[2023-02-22]: https://github.com/latex3/latex3/compare/2023-02-07...2023-02-22
+[2023-02-07]: https://github.com/latex3/latex3/compare/2023-02-02...2023-02-07
+[2023-02-02]: https://github.com/latex3/latex3/compare/2023-02-01...2023-02-02
+[2023-02-01]: https://github.com/latex3/latex3/compare/2023-01-24...2023-02-01
+[2023-01-24]: https://github.com/latex3/latex3/compare/2023-01-16...2023-01-24
+[2023-01-16]: https://github.com/latex3/latex3/compare/2022-12-17...2023-01-16
+[2022-12-17]: https://github.com/latex3/latex3/compare/2022-11-02...2022-12-17
+[2022-11-02]: https://github.com/latex3/latex3/compare/2022-10-26...2022-11-02
+[2022-10-26]: https://github.com/latex3/latex3/compare/2022-09-28...2022-10-26
+[2022-09-28]: https://github.com/latex3/latex3/compare/2022-08-30...2022-09-28
+[2022-08-30]: https://github.com/latex3/latex3/compare/2022-08-23...2022-08-30
+[2022-08-23]: https://github.com/latex3/latex3/compare/2022-08-05...2022-08-23
+[2022-08-05]: https://github.com/latex3/latex3/compare/2022-07-15...2022-08-05
+[2022-07-15]: https://github.com/latex3/latex3/compare/2022-07-14...2022-07-15
+[2022-07-14]: https://github.com/latex3/latex3/compare/2022-07-04...2022-07-14
+[2022-07-04]: https://github.com/latex3/latex3/compare/2022-07-01...2022-07-04
+[2022-07-01]: https://github.com/latex3/latex3/compare/2022-06-16...2022-07-01
+[2022-06-16]: https://github.com/latex3/latex3/compare/2022-06-02...2022-06-16
+[2022-06-02]: https://github.com/latex3/latex3/compare/2022-05-30...2022-06-02
+[2022-05-30]: https://github.com/latex3/latex3/compare/2022-05-04...2022-05-30
+[2022-05-04]: https://github.com/latex3/latex3/compare/2022-04-29...2022-05-04
+[2022-04-29]: https://github.com/latex3/latex3/compare/2022-04-20...2022-04-29
+[2022-04-20]: https://github.com/latex3/latex3/compare/2022-04-10...2022-04-20
+[2022-04-10]: https://github.com/latex3/latex3/compare/2022-02-24...2022-04-10
+[2022-02-24]: https://github.com/latex3/latex3/compare/2022-02-21...2022-02-24
+[2022-02-21]: https://github.com/latex3/latex3/compare/2022-02-05...2022-02-21
+[2022-02-05]: https://github.com/latex3/latex3/compare/2022-01-21...2022-02-05
+[2022-01-21]: https://github.com/latex3/latex3/compare/2022-01-12...2022-01-21
+[2022-01-12]: https://github.com/latex3/latex3/compare/2021-11-22...2022-01-12
+[2021-11-22]: https://github.com/latex3/latex3/compare/2021-11-12...2021-11-22
+[2021-11-12]: https://github.com/latex3/latex3/compare/2021-10-18...2021-11-12
+[2021-10-18]: https://github.com/latex3/latex3/compare/2021-10-17...2021-10-18
+[2021-10-17]: https://github.com/latex3/latex3/compare/2021-10-12...2021-10-17
+[2021-10-12]: https://github.com/latex3/latex3/compare/2021-08-27...2021-10-12
+[2021-08-27]: https://github.com/latex3/latex3/compare/2021-07-12...2021-08-27
+[2021-07-12]: https://github.com/latex3/latex3/compare/2021-06-18...2021-07-12
+[2021-06-18]: https://github.com/latex3/latex3/compare/2021-06-01...2021-06-18
+[2021-06-01]: https://github.com/latex3/latex3/compare/2021-05-27...2021-06-01
+[2021-05-27]: https://github.com/latex3/latex3/compare/2021-05-25...2021-05-27
+[2021-05-25]: https://github.com/latex3/latex3/compare/2021-05-11...2021-05-25
+[2021-05-11]: https://github.com/latex3/latex3/compare/2021-05-07...2021-05-11
+[2021-05-07]: https://github.com/latex3/latex3/compare/2021-02-18...2021-05-07
+[2021-02-18]: https://github.com/latex3/latex3/compare/2021-02-06...2021-02-18
+[2021-02-06]: https://github.com/latex3/latex3/compare/2021-02-02...2021-02-06
+[2021-02-02]: https://github.com/latex3/latex3/compare/2021-01-09...2021-02-02
+[2021-01-09]: https://github.com/latex3/latex3/compare/2020-12-07...2021-01-09
+[2020-12-07]: https://github.com/latex3/latex3/compare/2020-12-05...2020-12-07
+[2020-12-05]: https://github.com/latex3/latex3/compare/2020-12-03...2020-12-05
+[2020-12-03]: https://github.com/latex3/latex3/compare/2020-10-27...2020-12-03
+[2020-10-27]: https://github.com/latex3/latex3/compare/2020-10-05...2020-10-27
+[2020-10-05]: https://github.com/latex3/latex3/compare/2020-09-24...2020-10-05
+[2020-09-24]: https://github.com/latex3/latex3/compare/2020-09-06...2020-09-24
+[2020-09-06]: https://github.com/latex3/latex3/compare/2020-09-03...2020-09-06
+[2020-09-03]: https://github.com/latex3/latex3/compare/2020-09-01...2020-09-03
+[2020-09-01]: https://github.com/latex3/latex3/compare/2020-08-07...2020-09-01
+[2020-08-07]: https://github.com/latex3/latex3/compare/2020-07-17...2020-08-07
+[2020-07-17]: https://github.com/latex3/latex3/compare/2020-06-18...2020-07-17
+[2020-06-18]: https://github.com/latex3/latex3/compare/2020-06-03...2020-06-18
+[2020-06-03]: https://github.com/latex3/latex3/compare/2020-05-15...2020-06-03
+[2020-05-15]: https://github.com/latex3/latex3/compare/2020-05-14...2020-05-15
+[2020-05-14]: https://github.com/latex3/latex3/compare/2020-05-11...2020-05-14
+[2020-05-11]: https://github.com/latex3/latex3/compare/2020-05-05...2020-05-11
+[2020-05-05]: https://github.com/latex3/latex3/compare/2020-04-06...2020-05-05
+[2020-04-06]: https://github.com/latex3/latex3/compare/2020-03-06...2020-04-06
+[2020-03-06]: https://github.com/latex3/latex3/compare/2020-03-03...2020-03-06
+[2020-03-03]: https://github.com/latex3/latex3/compare/2020-02-25...2020-03-03
+[2020-02-25]: https://github.com/latex3/latex3/compare/2020-02-21...2020-02-25
+[2020-02-21]: https://github.com/latex3/latex3/compare/2020-02-14...2020-02-21
+[2020-02-14]: https://github.com/latex3/latex3/compare/2020-02-13...2020-02-14
+[2020-02-13]: https://github.com/latex3/latex3/compare/2020-02-11...2020-02-13
+[2020-02-11]: https://github.com/latex3/latex3/compare/2020-02-08...2020-02-11
+[2020-02-08]: https://github.com/latex3/latex3/compare/2020-02-03...2020-02-08
+[2020-02-03]: https://github.com/latex3/latex3/compare/2020-01-31...2020-02-03
+[2020-01-31]: https://github.com/latex3/latex3/compare/2020-01-22...2020-01-31
+[2020-01-22]: https://github.com/latex3/latex3/compare/2020-01-12...2020-01-22
+[2020-01-12]: https://github.com/latex3/latex3/compare/2019-11-07...2020-01-12
+[2019-11-07]: https://github.com/latex3/latex3/compare/2019-10-28...2019-11-07
+[2019-10-28]: https://github.com/latex3/latex3/compare/2019-10-27...2019-10-28
+[2019-10-27]: https://github.com/latex3/latex3/compare/2019-10-24...2019-10-27
+[2019-10-24]: https://github.com/latex3/latex3/compare/2019-10-21...2019-10-24
+[2019-10-21]: https://github.com/latex3/latex3/compare/2019-10-14...2019-10-21
+[2019-10-14]: https://github.com/latex3/latex3/compare/2019-10-11...2019-10-14
+[2019-10-11]: https://github.com/latex3/latex3/compare/2019-10-02...2019-10-11
+[2019-10-02]: https://github.com/latex3/latex3/compare/2019-09-30...2019-10-02
+[2019-09-30]: https://github.com/latex3/latex3/compare/2019-09-28...2019-09-30
+[2019-09-28]: https://github.com/latex3/latex3/compare/2019-09-19...2019-09-28
+[2019-09-19]: https://github.com/latex3/latex3/compare/2019-09-08...2019-09-19
+[2019-09-08]: https://github.com/latex3/latex3/compare/2019-09-05...2019-09-08
+[2019-09-05]: https://github.com/latex3/latex3/compare/2019-08-25...2019-09-05
+[2019-08-25]: https://github.com/latex3/latex3/compare/2019-08-14...2019-08-25
+[2019-08-14]: https://github.com/latex3/latex3/compare/2019-07-25...2019-08-14
+[2019-07-25]: https://github.com/latex3/latex3/compare/2019-07-01...2019-07-25
+[2019-07-01]: https://github.com/latex3/latex3/compare/2019-05-28...2019-07-01
+[2019-05-28]: https://github.com/latex3/latex3/compare/2019-05-09...2019-05-28
+[2019-05-09]: https://github.com/latex3/latex3/compare/2019-05-07...2019-05-09
+[2019-05-07]: https://github.com/latex3/latex3/compare/2019-05-05...2019-05-07
+[2019-05-05]: https://github.com/latex3/latex3/compare/2019-05-03...2019-05-05
+[2019-05-03]: https://github.com/latex3/latex3/compare/2019-04-21...2019-05-03
+[2019-04-21]: https://github.com/latex3/latex3/compare/2019-04-06...2019-04-21
+[2019-04-06]: https://github.com/latex3/latex3/compare/2019-03-26...2019-04-06
+[2019-03-26]: https://github.com/latex3/latex3/compare/2019-03-05...2019-03-26
+[2019-03-05]: https://github.com/latex3/latex3/compare/2019-02-15...2019-03-05
+[2019-02-15]: https://github.com/latex3/latex3/compare/2019-02-03...2019-02-15
+[2019-02-03]: https://github.com/latex3/latex3/compare/2019-01-28...2019-02-03
+[2019-01-28]: https://github.com/latex3/latex3/compare/2019-01-13...2019-01-28
+[2019-01-13]: https://github.com/latex3/latex3/compare/2019-01-12...2019-01-13
+[2019-01-12]: https://github.com/latex3/latex3/compare/2019-01-01...2019-01-12
+[2019-01-01]: https://github.com/latex3/latex3/compare/2018-12-12...2019-01-01
+[2018-12-12]: https://github.com/latex3/latex3/compare/2018-12-11...2018-12-12
+[2018-12-11]: https://github.com/latex3/latex3/compare/2018-12-06...2018-12-11
+[2018-12-06]: https://github.com/latex3/latex3/compare/2018-11-19...2018-12-06
+[2018-11-19]: https://github.com/latex3/latex3/compare/2018-10-31...2018-11-19
+[2018-10-31]: https://github.com/latex3/latex3/compare/2018-10-26...2018-10-31
+[2018-10-26]: https://github.com/latex3/latex3/compare/2018-10-19...2018-10-26
+[2018-10-19]: https://github.com/latex3/latex3/compare/2018-10-17...2018-10-19
+[2018-10-17]: https://github.com/latex3/latex3/compare/2018-09-24...2018-10-17
+[2018-09-24]: https://github.com/latex3/latex3/compare/2018-08-23...2018-09-24
+[2018-08-23]: https://github.com/latex3/latex3/compare/2018-06-14...2018-08-23
+[2018-06-14]: https://github.com/latex3/latex3/compare/2018-06-01...2018-06-14
+[2018-06-01]: https://github.com/latex3/latex3/compare/2018-05-13...2018-06-01
+[2018-05-13]: https://github.com/latex3/latex3/compare/2018-05-12...2018-05-13
+[2018-05-12]: https://github.com/latex3/latex3/compare/2018-04-30...2018-05-12
+[2018-04-30]: https://github.com/latex3/latex3/compare/2018-03-05...2018-04-30
+[2018-03-05]: https://github.com/latex3/latex3/compare/2018-02-21...2018-03-05
+[2018-02-21]: https://github.com/latex3/latex3/compare/2017-12-16...2018-02-21
diff --git a/macros/latex-dev/required/l3kernel/README.md b/macros/latex-dev/required/l3kernel/README.md
new file mode 100644
index 0000000000..70d106b496
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/README.md
@@ -0,0 +1,96 @@
+LaTeX3 Programming Conventions
+==============================
+
+Release 2024-04-11
+
+Overview
+--------
+
+The files of the `l3kernel` bundle provide an API for TeX programmers
+with defined syntax conventions, completely separating it from document level
+syntax. Hence, the commands provided are not intended for use at the document
+level nor for use in describing design layouts in document class files.
+
+This API provides the foundation on which new additions to the LaTeX kernel and
+other advanced extensions are built. The programming layer is designed to be
+loaded as part of LaTeX2e format building or as a loaded package with plain TeX
+or other formats.
+
+The syntax and functionality provided by `l3kernel` is regarded by the LaTeX
+team as stable. There may still be changes to some functions, but these will be
+very minor when compared to the scope of `l3kernel`. In particular, no functions
+will be removed, although some may be deprecated.
+
+
+Requirements
+------------
+
+The `l3kernel` bundle requires the e-TeX extensions and a number of additional
+'utility' primitives, almost all of which were first added to pdfTeX. In
+particular, the functionality equivalent to the following pdfTeX primitives must
+be available
+
+- `\ifincsname`
+- `\ifpdfprimitive`
+- `\pdfcreationdate`
+- `\pdfelapsedtime`
+- `\pdffiledump`
+- `\pdffilemoddate`
+- `\pdffilesize`
+- `\pdflastxpos`
+- `\pdflastypos`
+- `\pdfmdfivesum`
+- `\pdfnormaldeviate`
+- `\pdfpageheight`
+- `\pdfpagewidth`
+- `\pdfprimitive`
+- `\pdfrandomseed`
+- `\pdfresettimer`
+- `\pdfsavepos`
+- `\pdfsetrandomseed`
+- `\pdfshellescape`
+- `\pdfstrcmp`
+- `\pdfuniformdeviate`
+
+For ease of reference, these primitives will be referred to as the 'pdfTeX
+utilities'. With the exception of `\expanded`, these have been present in pdfTeX
+since the release of version 1.40.0 in 2007; `\expanded` was added for TeX Live
+2019. Similarly, the full set of these utility primitives has been available in
+XeTeX from the 2019 TeX Live release, and has always been available in LuaTeX
+(some by Lua emulation). The Japanese pTeX and upTeX gained all of the above
+(except `\ifincsname`) for TeX Live 2019 and `\ifincsname` for TeX Live 2020.
+
+Starting from release 2023-05-15, the `\expanded` primitive is *required*.
+Its slow emulation has been removed.
+
+In addition to the above, engines which are fully Unicode-compatible
+must provide the functionality of the following primitives, documented in the
+LuaTeX manual
+
+- `\Uchar`
+- `\Ucharcat`
+- `\Umathcode`
+
+The existence of the primitive `\Umathcode` is used as the marker for Unicode
+support.
+
+Issues
+------
+
+The issue tracker for LaTeX3 is currently located
+[on GitHub](https://github.com/latex3/latex3/issues).
+
+The LaTeX Project
+------------------
+
+Development of LaTeX3 is carried out by
+[The LaTeX Project](https://www.latex-project.org/latex3/).
+
+The development team can be contacted
+by e-mail: <latex-team@latex-project.org>.
+
+-----
+
+<p>Copyright (C) 1998-2012,2015-2024 The LaTeX Project <br />
+<a href="http://latex-project.org/">http://latex-project.org/</a> <br />
+All rights reserved.</p>
diff --git a/macros/latex-dev/required/l3kernel/expl3.dtx b/macros/latex-dev/required/l3kernel/expl3.dtx
new file mode 100644
index 0000000000..56a62010fa
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/expl3.dtx
@@ -0,0 +1,1798 @@
+% \iffalse meta-comment
+%
+%% File: expl3.dtx
+%
+% Copyright (C) 1990-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver|generic|package|2ekernel>
+%</driver|generic|package|2ekernel>
+\def\ExplFileDate{2024-04-11}%
+%<*driver>
+\documentclass[full]{l3doc}
+\usepackage{graphicx}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \providecommand\acro[1]{\textsc{\MakeLowercase{#1}}}
+% \newenvironment{arg-description}{%
+% \begin{itemize}\def\makelabel##1{\hss\llap{\bfseries##1}}}{\end{itemize}}
+%
+% \title{^^A
+% The \pkg{expl3} package and \LaTeX3 programming^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \begin{abstract}
+%
+% This document gives an introduction to a new set of programming
+% conventions that have been designed to meet the requirements of
+% implementing large scale \TeX{} macro programming projects such as
+% \LaTeX{}. These programming conventions are the base layer of \LaTeX3.
+%
+% The main features of the system described are:
+% \begin{itemize}
+% \item classification of the macros (or, in \LaTeX{} terminology,
+% commands) into \LaTeX{} functions and \LaTeX{} parameters, and also
+% into modules containing related commands;
+% \item a systematic naming scheme based on these classifications;
+% \item a simple mechanism for controlling the expansion of a function's
+% arguments.
+% \end{itemize}
+% This system is being used as the basis for \TeX{} programming within
+% The \LaTeX{} Project. Note that the language is not intended for either
+% document mark-up or style specification. Instead, it is intended that
+% such features will be built on top of the conventions described here.
+%
+% This document is an introduction to the ideas behind the \pkg{expl3}
+% programming interface. For the complete documentation of the programming
+% layer provided by The \LaTeX{} Project, see the accompanying
+% \texttt{interface3} document.
+%
+% \end{abstract}
+%
+% \section{Introduction}
+%
+% The first step to develop a \LaTeX{} kernel beyond \LaTeXe{} is to
+% address how the underlying system is programmed. Rather than the
+% current mix of \LaTeX{} and \TeX{} macros, the \LaTeX3 system provides
+% its own consistent interface to all of the functions needed to
+% control \TeX{}. A key part of this work is to ensure that everything
+% is documented, so that \LaTeX{} programmers and users can work
+% efficiently without needing to be familiar with the internal nature
+% of the kernel or with plain \TeX{}.
+%
+% The \pkg{expl3} bundle provides this new programming interface for
+% \LaTeX{}. To make programming systematic, \LaTeX3 uses some very
+% different conventions to \LaTeXe{} or plain \TeX{}. As a result,
+% programmers starting with \LaTeX3 need to become familiar with
+% the syntax of the new language.
+%
+% The next section shows where this language fits into a complete
+% \TeX{}-based document processing system. We then describe the major
+% features of the syntactic structure of command names, including the
+% argument specification syntax used in function names.
+%
+% The practical ideas behind this argument syntax will be explained,
+% together with the expansion control mechanism and the interface
+% used to define variant forms of functions.
+%
+% As we shall demonstrate, the use of a structured naming scheme and of
+% variant forms for functions greatly improves the readability of the
+% code and hence also its reliability. Moreover, experience has shown
+% that the longer command names which result from the new syntax do not
+% make the process of \emph{writing} code significantly harder.
+%
+% \section{Languages and interfaces}
+%
+% It is possible to identify several distinct languages related to the
+% various interfaces that are needed in a \TeX{}-based document processing
+% system. This section looks at those we consider most important for
+% the \LaTeX3 system.
+%
+% \begin{description}
+% \item[Document mark-up] This comprises those commands (often called
+% tags) that are to embedded in the document (the |.tex| file).
+%
+% It is generally accepted that such mark-up should be essentially
+% \emph{declarative}. It may be traditional \TeX{}-based mark-up such
+% as \LaTeXe{}, as described in~\cite{A-W:LLa94} and~\cite{A-W:GMS94},
+% or a mark-up language defined via \acro{HTML} or \acro{XML}.
+%
+% One problem with more traditional \TeX{} coding conventions (as
+% described in~\cite{A-W:K-TB}) is that the names and syntax of \TeX{}'s
+% primitive formatting commands are ingeniously designed to be
+% \enquote{natural} when used directly by the author as document mark-up
+% or in macros. Ironically, the ubiquity (and widely recognised
+% superiority) of logical mark-up has meant that such explicit
+% formatting commands are almost never needed in documents or in
+% author-defined macros. Thus they are used almost exclusively by
+% \TeX{} programmers to define higher-level commands, and their
+% idiosyncratic syntax is not at all popular with this community.
+% Moreover, many of them have names that could be very useful as
+% document mark-up tags were they not pre-empted as primitives
+% (\emph{e.g.}~\tn{box} or \tn{special}).
+%
+% \item[Designer interface] This relates a (human) typographic
+% designer's specification for a document to a program that
+% \enquote{formats
+% the document}. It should ideally use a declarative language that
+% facilitates expression of the relationship and spacing rules
+% specified for the layout of the various document elements.
+%
+% This language is not embedded in document text and it will be very
+% different in form to the document mark-up language. For \LaTeX{},
+% this level was almost completely missing from \LaTeX{}2.09; \LaTeXe{}
+% made some improvements in this area but it is still the case that
+% implementing a design specification in \LaTeX{} requires far more
+% \enquote{low-level} coding than is acceptable.
+%
+% \item[Programmer interface]
+% This language is the implementation language within which the
+% basic typesetting functionality is implemented, building upon the
+% primitives of \TeX{} (or a successor program). It may also be used
+% to implement the previous two languages \enquote{within} \TeX{}, as in
+% the
+% current \LaTeX{} system.
+%
+% \end{description}
+%
+% The last layer is covered by the conventions described in this
+% document, which describes a system aimed at providing a suitable
+% basis for coding \LaTeX3. Its main distinguishing features are
+% summarised here:
+% \begin{itemize}
+% \item A consistent naming scheme for all commands, including \TeX{}
+% primitives.
+% \item The classification of commands as \LaTeX{} functions or \LaTeX{}
+% parameters, and also their division into modules according to their
+% functionality.
+% \item A simple mechanism for controlling argument expansion.
+% \item Provision of a set of core \LaTeX{} functions that is sufficient
+% for handling programming constructs such as queues, sets, stacks,
+% property lists.
+% \item A \TeX{} programming environment in which, for example, all
+% white space is ignored.
+% \end{itemize}
+%
+% \section{The naming scheme}
+%
+% \LaTeX3 does not use |@| as a \enquote{letter} for defining
+% internal macros. Instead, the symbols |_| and |:|
+% are used in internal macro names to provide structure. In
+% contrast to the plain \TeX{} format and the \LaTeXe{} kernel, these
+% extra letters are used only between parts of a macro name (no
+% strange vowel replacement).
+%
+% While \TeX{} is actually a macro processor, by
+% convention for the \pkg{expl3} programming language we distinguish between
+% \emph{functions} and \emph{variables}. Functions can have arguments and they
+% are either expanded or executed. Variables can be assigned values and they
+% are used in arguments to functions; they are not used directly but are
+% manipulated by functions (including getting and setting functions).
+% Functions and variables with a related functionality (for example accessing
+% counters, or manipulating token lists, \emph{etc.})\ are collected together
+% into a
+% \emph{module}.
+%
+% \subsection{Examples}
+%
+% Before giving the details of the naming scheme, here are a few typical
+% examples to indicate the flavour of the scheme; first some variable
+% names.
+% \begin{quote}
+% \cs{l_tmpa_box} is a local variable (hence the~|l_| prefix)
+% corresponding to a box register.\\
+% \cs{g_tmpa_int} is a global variable (hence the~|g_| prefix)
+% corresponding to an integer register (i.e.~a \TeX{} count
+% register).\\
+% \cs{c_empty_tl} is the constant~(|c_|) token list variable
+% that is always empty.
+% \end{quote}
+%
+% Now here is an example of a typical function name.
+%
+% \cs{seq_push:Nn} is the function which puts the token list specified
+% by its second argument onto the stack specified by its first argument.
+% The different natures of the two arguments are indicated by the~|:Nn|
+% suffix. The first argument must be a single token which \enquote{names}
+% the stack parameter: such single-token arguments are denoted~|N|.
+% The second argument is a normal \TeX{} \enquote{undelimited argument},
+% which
+% may either be a single token or a balanced, brace-delimited token
+% list (which we shall here call a \textit{braced token list}): the~|n|
+% denotes such a \enquote{normal} argument form. The name of the function
+% indicates it belongs to the |seq| module.
+%
+% \subsection{Formal naming syntax}
+%
+% We shall now look in more detail at the syntax of these names. A
+% function name in \LaTeX3 has a name consisting of three parts:
+% \begin{quote}
+% |\|\meta{module}|_|\meta{description}|:|\meta{arg-spec}
+% \end{quote}
+% while a variable has (up to) four distinct parts to its name:
+% \begin{quote}
+% |\|\meta{scope}|_|\meta{module}|_|\meta{description}|_|\meta{type}
+% \end{quote}
+%
+% The syntax of all names contains
+% \begin{quote}
+% \meta{module} and \meta{description}
+% \end{quote}
+% these both give information about the command.
+%
+% A \emph{module} is a collection of closely related functions and
+% variables. Typical module names include~|int| for integer parameters
+% and related functions,~|seq| for sequences and~|box| for boxes.
+%
+% Packages providing new programming functionality will add new modules
+% as needed; the programmer can choose any unused name, consisting
+% of letters only, for a module. In general, the module name and module
+% prefix should be related: for example, the kernel module containing
+% \texttt{box} functions is called \texttt{l3box}. Module names and
+% programmers' contact details are listed in \pkg{l3prefixes.csv}.
+%
+% The \emph{description} gives more detailed information about the
+% function or parameter, and provides a unique name for it. It should
+% consist of letters and, possibly,~|_|~characters. In general, the
+% description should use |_| to divide up \enquote{words} or other easy to
+% follow parts of the name. For example, the \LaTeX3 kernel provides
+% \cs{if_cs_exist:N} which, as might be expected, tests if a command
+% name exists.
+%
+% Where functions for variable manipulation can perform assignments
+% either locally or globally, the latter case is indicated by the inclusion of
+% a |g| in the second part of the function name. Thus \cs{tl_set:Nn} is a local
+% function but \cs{tl_gset:Nn} acts globally. Functions of this type are
+% always documented together, and the scope of action may therefore be
+% inferred from the presence or absence of a |g|. See the next subsection for
+% more detail on variable scope.
+%
+% \subsubsection{Separating private and public material}
+%
+% One of the issues with the \TeX{} language is that it doesn't support
+% name spaces and encapsulation other than by convention. As a result
+% nearly every internal command in the \LaTeXe{} kernel has eventually
+% be used by extension packages as an entry point for modifications or
+% extensions. The consequences of this is that nowadays it is next to
+% impossible to change anything in the \LaTeXe{} kernel (even if it is
+% clearly just an internal command) without breaking something.
+%
+% In \pkg{expl3} we hope to improve this situation drastically by
+% clearly separating public interfaces (that extension packages can use
+% and rely on) and private functions and variables (that should not
+% appear outside of their module). There is (nearly) no way to enforce
+% this without severe computing overhead, so we implement it only
+% through a naming convention, and some support mechanisms. However, we
+% think that this naming convention is easy to understand and to follow,
+% so that we are confident that this will adopted and provides the
+% desired results.
+%
+% Functions created by a module may either be \enquote{public} (documented
+% with a defined interface) or \enquote{private} (to be used only within
+% that module, and thus not formally documented). It is important that
+% only documented interfaces are used; at the same time, it is necessary to
+% show within the name of a function or variable whether it is public
+% or private.
+%
+% To allow clear separation of these two cases, the following convention
+% is used. To denote a private function or a private variable (of the module),
+% two |_| characters are used in front of the module name, e.g.
+% \begin{verbatim}
+% \module_foo:nnn
+% \end{verbatim}
+% is a public function which should be documented while
+% \begin{verbatim}
+% \__module_foo:nnn
+% \end{verbatim}
+% is private to the module, and should \emph{not} be used outside of that
+% module.
+%
+% For variables, to avoid three |_| in a row, the separator for the variable
+% scope and any leading |_| for a private interface in the module part are
+% combined. Thus
+% \begin{verbatim}
+% \l_module_foo_tl
+% \end{verbatim}
+% is a public variable and
+% \begin{verbatim}
+% \l__module_foo_tl
+% \end{verbatim}
+% is private.
+%
+% \subsubsection{Using \texttt{@@} and \pkg{DocStrip} to mark private code}
+%
+% The formal syntax for internal functions allows clear separation of public
+% and private code, but includes redundant information (every internal function
+% or variable includes \texttt{__\meta{module}}). To aid programmers, the
+% \pkg{DocStrip} program introduces the syntax
+% \begin{quote}
+% \ttfamily
+% |%<@@=|\meta{module}|>|
+% \end{quote}
+% which then allows |@@| (and |_@@| in case of variables) to be used as
+% a place holder for \texttt{__\meta{module}} in code. Thus for example
+% \begin{verbatim}
+% %<@@=foo>
+% % \begin{macrocode}
+% \cs_new:Npn \@@_function:n #1
+% ...
+% \tl_new:N \l_@@_my_tl
+% % \end{macrocode}
+% \end{verbatim}
+% is converted by \pkg{DocStrip} to
+% \begin{verbatim}
+% \cs_new:Npn \__foo_function:n #1
+% ...
+% \tl_new:N \l__foo_my_tl
+% \end{verbatim}
+% on extraction. As you can see both |_@@| and |@@| are mapped to
+% \texttt{__\meta{module}}, because we think that this helps to
+% distinguish variables from functions in the source when the |@@|
+% convention is used.
+%
+% \subsubsection{Variables: declaration}
+%
+% In well-formed \pkg{expl3} code, variables should always be declared before
+% assignment is attempted. This is true even for variable types where the
+% underlying \TeX{} implementation will allow direct assignment. This applies
+% both to setting directly (\cs{tl_set:Nn}, etc.) and to setting equal
+% (\cs{tl_set_eq:NN}, etc.).
+%
+% To help programmers to adhere to this approach, the debugging option
+% |check-declarations| may be given
+% \begin{verbatim}
+% \debug_on:n { check-declarations }
+% \end{verbatim}
+% and will issue an error whenever an assignment is made to a non-declared
+% variable. There is a performance implication, so this option should only
+% be used for testing.
+%
+% \subsubsection{Variables: scope and type}
+%
+% The \meta{scope} part of the name describes how the variable can be
+% accessed. Variables are classified as local, global or constant.
+% This \emph{scope} type appears as a code at the beginning of the name;
+% the codes used are:
+% \begin{arg-description}
+% \item[c] constants (global variables whose value should not be
+% changed);
+% \item[g] variables whose value should only be set globally;
+% \item[l] variables whose value should only be set locally.
+% \end{arg-description}
+%
+% Separate functions are provided to assign data to local and global
+% variables; for example, \cs{tl_set:Nn} and \cs{tl_gset:Nn} respectively
+% set the value of a local or global \enquote{token list} variable.
+% Note that it is a poor \TeX{} practice to intermix local and global
+% assignments to a variable; otherwise you risk exhausting the save
+% stack.\footnote{See \emph{The \TeX{}book}, p.\,301, for further
+% information.}
+%
+% The \meta{type} is in the list of available
+% \emph{data-types};\footnote{Of course, if a totally new data type is
+% needed then this will not be the case. However, it is hoped that only
+% the kernel team will need to create new data types.} these include the
+% primitive \TeX{} data-types, such as the various registers, but to
+% these are added data-types built within the \LaTeX{} programming
+% system.
+%
+% The data types in \LaTeX3 are:
+% \begin{description}
+% \item[bitset] a string of bits (\texttt{0} and \texttt{1} tokens) that are
+% accessed by position or by name;
+% \item[bool] either true or false (the \LaTeX3 implementation does
+% not use \tn{iftrue} or \tn{iffalse});
+% \item[box] box register;
+% \item[cctab] category code table;
+% \item[clist] comma separated list;
+% \item[coffin] a \enquote{box with handles} --- a higher-level data
+% type for carrying out |box| alignment operations;
+% \item[dim] \enquote{rigid} lengths;
+% \item[fp] floating-point values;
+% \item[fparray] fixed-size vector of floating-point values;
+% \item[int] integer-valued count register;
+% \item[intarray] fixed-size vector of integer values;
+% \item[ior] an input stream (for reading from a file);
+% \item[iow] an output stream (for writing to a file);
+% \item[muskip] math mode \enquote{rubber} lengths;
+% \item[prop] property list;
+% \item[regex] regular expression;
+% \item[seq] sequence: a data-type used to implement lists (with
+% access at both ends) and stacks;
+% \item[skip] \enquote{rubber} lengths;
+% \item[str] \TeX{} strings: a special case of |tl| in which all
+% characters have category \enquote{other} (catcode~$12$),
+% other than spaces which are category \enquote{space}
+% (catcode~$10$);
+% \item[token] equal to a single arbitrary token;
+% \item[tl] \enquote{token list variables}: placeholders for token lists.
+% \end{description}
+% When the \meta{type} and \meta{module} are identical (as often happens in
+% the more basic modules) the \meta{module} part is often omitted for
+% aesthetic reasons.
+%
+% The name \enquote{token list} may cause confusion, and so some
+% background is useful. \TeX{} works with tokens and lists of tokens,
+% rather than characters. It provides two ways to store these token
+% lists: within macros and as token registers (|toks|). The
+% implementation in \LaTeX3 means that |toks| are not required, and that
+% all operations for storing tokens can use the |tl| variable type.
+%
+% Experienced \TeX{} programmers will notice that some of the variable
+% types listed are native \TeX{} registers whilst others are not. In
+% general, the underlying \TeX{} implementation for a data structure may
+% vary but the \emph{documented interface} will be stable. For example,
+% the |prop| data type was originally implemented as a |toks|, but
+% is currently built on top of the |tl| data structure.
+%
+% \subsubsection{Variables: guidance}
+%
+% Both comma lists and sequences have similar characteristics.
+% They both use special delimiters to mark out one entry from the
+% next, and are both accessible at both ends. In general, it is
+% easier to create comma lists `by hand' as they can be typed
+% in directly. User input often takes the form of a comma separated
+% list and so there are many cases where this is the obvious
+% data type to use. On the other hand, sequences use special internal
+% tokens to separate entries. This means that they can be used to
+% contain material that comma lists cannot (such as items that may
+% themselves contain commas!). In general, comma lists should be
+% preferred for creating fixed lists inside programs and for
+% handling user input where commas will not occur. On the other
+% hand, sequences should be used to store arbitrary lists of
+% data.
+%
+% \pkg{expl3} implements stacks using the sequence data structure.
+% Thus creating stacks involves first creating a sequence, and
+% then using the sequence functions which work in a stack manner
+% (\cs{seq_push:Nn}, \emph{etc}.).
+%
+% Due to the nature of the underlying \TeX{} implementation, it is
+% possible to assign values to token list variables and comma lists
+% without first declaring them. However, this is \emph{not supported
+% behavior}. The \LaTeX3 coding convention is that all variables must
+% be declared before use.
+%
+% The \pkg{expl3} package can be loaded with the \texttt{check-declarations}
+% option to verify that all variables are declared before use. This has
+% a performance implication and is therefore intended for testing during
+% development and not for use in production documents.
+%
+% \subsubsection{Functions: argument specifications}
+%
+% Function names end with an \meta{arg-spec} after a colon. This
+% gives an indication of the types of argument that a function takes,
+% and provides a convenient method of naming similar functions that
+% differ only in their argument forms (see the next section for
+% examples).
+%
+% The \meta{arg-spec} consists of a (possibly empty) list of letters,
+% each denoting one argument of the function. The letter, including
+% its case, conveys information about the type of argument required.
+%
+% All functions have a base form with arguments using one of the
+% following argument specifiers:
+% \begin{arg-description}
+% \item[n] Unexpanded token or braced token list.\\
+% This is a standard \TeX{} undelimited macro argument.
+% \item[N] Single token (unlike~|n|, the argument must \emph{not} be
+% surrounded by braces).\\
+% A typical example of a command taking an~|N|
+% argument is~|\cs_set|, in which the command being defined must be
+% unbraced.
+% \item[p] Primitive \TeX{} parameter specification.\\
+% This can be something simple like~|#1#2#3|, but may use arbitrary
+% delimited argument syntax such as: |#1,#2\q_stop#3|. This is used
+% when defining functions.
+% \item[T,F]
+% These are special cases of~|n| arguments, used for the
+% true and false code in conditional commands.
+% \end{arg-description}
+% There are two other specifiers with more general meanings:
+% \begin{arg-description}
+% \item[D] Stands for \textbf{Do not use}. This special case is used
+% for \TeX{} primitives. These functions have no standardized
+% syntax, they are engine dependent and their name can change
+% without warning, thus their use is \emph{strongly discouraged} in
+% package code: programmers should instead use the interfaces
+% documented in \href{interface3.pdf}{interface3.pdf}%^^A
+% \footnote{If a primitive offers a functionality not yet in the
+% kernel, programmers and users are encouraged to write to the
+% \texttt{LaTeX-L} mailing list
+% (\url{mailto:LATEX-L@listserv.uni-heidelberg.de}) describing
+% their use-case and intended behaviour, so that a possible
+% interface can be discussed. Temporarily, while an interface is
+% not provided, programmers may use the procedure described in the
+% \href{l3styleguide.pdf}{l3styleguide.pdf}.}.
+% \item[w] This means that the argument syntax is \enquote{weird} in that it
+% does not follow any standard rule. It is used for functions with
+% arguments that take non standard forms: examples are \TeX{}-level
+% delimited arguments and the boolean tests needed after certain
+% primitive |\if|\ldots{} commands.
+% \end{arg-description}
+%
+% In case of |n| arguments that consist of a single token the
+% surrounding braces can be omitted in nearly all
+% situations---functions that force the use of braces even for single
+% token arguments are explicitly mentioned. However, programmers are
+% encouraged to always use braces around \texttt{n} arguments, as this
+% makes the relationship between function and argument clearer.
+%
+% Further argument specifiers are available as part of the expansion
+% control system. These are discussed in the next section.
+%
+% \section{Expansion control}
+%
+% Let's take a look at some typical operations one might want to
+% perform. Suppose we maintain a stack of open files and we use the
+% stack |\g_ior_file_name_seq| to keep track of them (\texttt{ior} is
+% the prefix used for the file reading module). The basic operation here
+% is to push a name onto this stack which could be done by the operation
+% \begin{quote}
+% \cs{seq_gpush:Nn} |\g_ior_file_name_seq {#1}|
+% \end{quote}
+% where |#1| is the filename. In other words, this operation would
+% push the file name as is onto the stack.
+%
+% However, we might face a situation where the filename is stored in
+% a variable of some sort, say |\l_ior_curr_file_tl|. In this case we
+% want to retrieve the value of the variable. If we simply use
+% \begin{quote}
+% \cs{seq_gpush:Nn} |\g_ior_file_name_seq| |\l_ior_curr_file_tl|
+% \end{quote}
+% we do not get the value of the variable pushed onto the stack,
+% only the variable name itself. Instead a suitable number of
+% \cs{exp_after:wN} would be necessary (together with extra braces) to
+% change the order of expansion,\footnote{\cs{exp_after:wN} is
+% the \LaTeX3 name for the \TeX{} \tn{expandafter} primitive.} \emph{i.e.}
+% \begin{quote}
+% \cs{exp_after:wN} \\
+% | |\cs{seq_gpush:Nn} \\
+% \cs{exp_after:wN} \\
+% | \g_ior_file_name_seq| \\
+% \cs{exp_after:wN} \\
+% | { \l_ior_curr_file_tl }|
+% \end{quote}
+%
+% The above example is probably the simplest case but already shows
+% how the code changes to something difficult to understand.
+% Furthermore there is an assumption in this: that the storage bin
+% reveals its contents after exactly one expansion. Relying on this
+% means that you cannot do proper checking plus you have to know
+% exactly how a storage bin acts in order to get the correct number
+% of expansions. Therefore \LaTeX3 provides the programmer with a
+% general scheme that keeps the code compact and easy to understand.
+%
+% To denote that some argument to a function needs special treatment one
+% just uses different letters in the arg-spec part of the function to
+% mark the desired behavior. In the above example one would write
+% \begin{quote}
+% \cs{seq_gpush:NV} |\g_ior_file_name_seq \l_ior_curr_file_tl|
+% \end{quote}
+% to achieve the desired effect. Here the |V| (the second argument)
+% is for \enquote{retrieve the value of the variable} before passing it to
+% the base function.
+%
+% The following letters can be used to denote special treatment of
+% arguments before passing it to the base function:
+% \begin{description}
+% \item[c] Character string used as a command name.\\ The argument (a
+% token or braced token list) is \emph{fully expanded}; the result
+% must be a sequence of characters which is then used to construct a
+% command name (\emph{via}~\tn{csname} \ldots \tn{endcsname}). This
+% command name is a single token that is passed to the function as
+% the argument. Hence
+% \begin{quote}
+% \cs{seq_gpush:cV} |{ g_file_name_seq }| \cs{l_tmpa_tl}
+% \end{quote}
+% is equivalent to
+% \begin{quote}
+% \cs{seq_gpush:NV} |\g_file_name_seq| \cs{l_tmpa_tl}.
+% \end{quote}
+% Full expansion means that (a) the entire
+% argument must be expandable and (b) any variables are
+% converted to their content. So the preceding examples are also
+% equivalent to
+% \begin{quote}
+% \cs{tl_new:N} |\g_file_seq_name_tl| \\
+% \cs{tl_gset:Nn} |\g_file_seq_name_tl { g_file_name_seq }| \\
+% \cs{seq_gpush:cV} |{| \cs{tl_use:N} |\g_file_seq_name_tl }| \cs{l_tmpa_tl}.
+% \end{quote}
+% (Token list variables are expandable and we could omit the
+% accessor function \cs{tl_use:N}. Other variable types require the
+% appropriate \cs{\meta{var}_use:N} functions to be used in this
+% context.)
+% \item[V] Value of a variable.\\
+% This means that the contents of the register in question is used
+% as the argument, be it an integer, a length-type register, a token
+% list variable or similar. The value is passed to the function as a
+% braced token list. Can be applied to variables which have a
+% \cs{\meta{var}_use:N} function (other than boxes),
+% and which therefore deliver a single \enquote{value}.
+% \item[v] Value of a register, constructed from a character string
+% used as a command name.\\
+% This is a combination of |c| and |V| which first constructs a
+% control sequence from the argument and then passes the value of
+% the resulting register to the function. Can be applied to
+% variables which have a \cs{\meta{var}_use:N} function (other than
+% boxes), and which therefore deliver a single
+% \enquote{value}.
+% \item[e] Fully-expanded token or braced token list.\\
+% This means that the argument is expanded as in the replacement
+% text of a~\tn{message}, and the expansion is passed to the function as
+% a braced token list.
+% \item[o] One-level-expanded token or braced token list.\\
+% This means that the argument is expanded one level, as by
+% \tn{expandafter}, and the expansion is passed to the function as a
+% braced token list. Note that if the original argument is a braced
+% token list then only the first token in that list is expanded.
+% In general, using \texttt{V} should be preferred to using
+% \texttt{o} for simple variable retrieval.
+% \item[f] Expanding the first token recursively in a braced token
+% list.\\ Almost the same as the |e| type except here the token list
+% is expanded fully until the first unexpandable token is found and
+% the rest is left unchanged. Note that if this function finds a
+% space at the beginning of the argument it gobbles it and does not
+% expand the next token.
+% \item[x] Fully-expanded token or braced token list.\\
+% This expansion is very similar to |e|-type but is not nestable,
+% can only be used to create non-expandable functions, and requires
+% that |#| tokens are doubled in the argument. In almost all cases,
+% |e|-type should be preferred: retained largely for historical
+% reasons, and should where possible be replaced by the |e|-type
+% equivalent.
+% \end{description}
+%
+% \subsection{Simpler means better}
+%
+% Anyone who programs in \TeX{} is frustratingly familiar with the
+% problem of arranging that arguments to functions are suitably expanded
+% before the function is called. To illustrate how expansion control
+% can bring instant relief to this problem we shall consider two
+% examples copied from \texttt{latex.ltx}.
+%
+% \begin{verbatim}
+% \global\expandafter\let
+% \csname\cf@encoding \string#1\expandafter\endcsname
+% \csname ?\string#1\endcsname
+% \end{verbatim}
+% This first piece of code is in essence simply a global \tn{let} whose
+% two arguments firstly have to be constructed before \tn{let} is
+% executed. The |#1| is a control sequence name such as
+% |\textcurrency|. The token to be defined is obtained by
+% concatenating the characters of the current font encoding stored in
+% |\cf@encoding|, which has to be fully expanded, and the name of the
+% symbol. The second token is the same except it uses the default
+% encoding |?|. The result is a mess of interwoven \tn{expandafter}
+% and \tn{csname} beloved of all \TeX{} programmers, and the code is
+% essentially unreadable.
+%
+% Using the conventions and functionality outlined here, the task would
+% be achieved with code such as this:
+% \begin{verbatim}
+% \cs_gset_eq:cc
+% { \cf@encoding \token_to_str:N #1 } { ? \token_to_str:N #1 }
+% \end{verbatim}
+% The command \cs{cs_gset_eq:cc} is a global~\tn{let} that generates
+% command names out of both of its arguments before making the
+% definition. This produces code that is far more readable and more
+% likely to be correct first time. (\cs{token_to_str:N} is the \LaTeX3
+% name for \tn{string}.)
+%
+% Here is the second example.
+% \begin{verbatim}
+% \expandafter
+% \in@
+% \csname sym#3%
+% \expandafter
+% \endcsname
+% \expandafter
+% {%
+% \group@list}%
+% \end{verbatim}
+% This piece of code is part of the definition of another function. It
+% first produces two things: a token list, by expanding |\group@list| once;
+% and a token whose name comes from~`|sym#3|'. Then the function~\cs{in@}
+% is called and this tests if its first argument occurs in the token list
+% of its second argument.
+%
+% Again we can improve enormously on the code. First we shall rename
+% the function~\cs{in@}, which tests if its first argument appears
+% within its second argument, according to our conventions. Such a
+% function takes two normal \enquote{\texttt{n}} arguments and operates
+% on token lists: it might reasonably be named |\tl_test_in:nn|. Thus
+% the variant function we need would be defined with the appropriate
+% argument types and its name would be |\tl_test_in:cV|. Now this code
+% fragment would be simply:
+% \begin{verbatim}
+% \tl_test_in:cV { sym #3 } \group@list
+% \end{verbatim}
+% This code could be improved further by using a sequence |\l_group_seq|
+% rather than the bare token list |\group@list|. Note that, in addition
+% to the lack of \tn{expandafter}, the space after the~|}| is
+% silently ignored since all white space is ignored in this programming
+% environment.
+%
+% \subsection{New functions from old}
+%
+% For many common functions the \LaTeX3 kernel provides variants
+% with a range of argument forms, and similarly it is expected that
+% extension packages providing new functions will make them available in
+% all the commonly needed forms.
+%
+% However, there will be occasions where it is necessary to construct a
+% new such variant form; therefore the expansion module provides a
+% straightforward mechanism for the creation of functions with any
+% required argument type, starting from a function that takes \enquote{normal}
+% \TeX{} undelimited arguments.
+%
+% To illustrate this let us suppose you have a \enquote{base function}
+% |\demo_cmd:Nnn| that takes three normal arguments, and that you need
+% to construct the variant |\demo_cmd:cne|, for which the first argument
+% is used to construct the \emph{name} of a command, whilst the third
+% argument must be fully expanded before being passed to
+% |\demo_cmd:Nnn|.
+% To produce the variant form from the base form, simply use this:
+% \begin{verbatim}
+% \cs_generate_variant:Nn \demo_cmd:Nnn { cne }
+% \end{verbatim}
+% This defines the variant form so that you can then write, for example:
+% \begin{verbatim}
+% \demo_cmd:cne { abc } { pq } { \rst \xyz }
+% \end{verbatim}
+% rather than \ldots\ well, something like this!
+% \begin{verbatim}
+% \def \tempa {{pq}}%
+% \edef \tempb {\rst \xyz}%
+% \expandafter
+% \demo@cmd:nnn
+% \csname abc%
+% \expandafter
+% \expandafter
+% \expandafter
+% \endcsname
+% \expandafter
+% \tempa
+% \expandafter
+% {%
+% \tempb
+% }%
+% \end{verbatim}
+%
+% Another example: you may wish to declare a function
+% |\demo_cmd_b:enene|, a variant of an existing function
+% |\demo_cmd_b:nnnnn|, that fully
+% expands arguments 1,~3 and~5, and produces commands to pass as
+% arguments 2 and~4 using~\tn{csname}.
+% The definition you need is simply
+% \begin{verbatim}
+% \cs_generate_variant:Nn \demo_cmd_b:nnnnn { enene }
+% \end{verbatim}
+%
+% This extension mechanism is written so that if the same new form of
+% some existing command is implemented by two extension packages then the
+% two definitions are identical and thus no conflict occurs.
+%
+% \section{The distribution}
+%
+% The \pkg{expl3} modules are designed to be loaded on top of \LaTeXe{}.
+%
+% \begin{bfseries}
+% The core \pkg{expl3} language is broadly stable, and thus
+% the syntax conventions and functions provided
+% are now ready for wider use. There may still be changes to some
+% functions, but these will be minor when compared to the scope of
+% \pkg{expl3}. A robust mechanism is in place for such deprecations.
+% \end{bfseries}
+%
+% The distribution of \pkg{expl3} is split up into three packages on
+% CTAN: \pkg{l3kernel}, \pkg{l3packages} and \pkg{l3experimental}.
+% The core programming layer provided by \pkg{l3kernel} has been loaded
+% as part of the \LaTeX{} since 2020-02-02. For historical reasons, in
+% older kernel releases
+% \begin{verbatim}
+% \RequirePackage{expl3}
+% \end{verbatim}
+% loads the code distributed as \pkg{l3kernel}. This monolithic
+% package contains all of the modules regarded by the team as stable,
+% and any changes in this code are very limited. This material is
+% therefore suitable for use in third-party packages without concern
+% about changes in support. All of this code is documented in
+% \texttt{interface3.pdf}.
+%
+% The material in \pkg{l3packages} is also stable; this bundle provides
+% user-level commands, some of which have been integrated in the
+% \LaTeX{} kernel.
+%
+% Finally, \pkg{l3experimental} contains modules ready for public use
+% but not yet integrated into \pkg{l3kernel}. These modules have to
+% be loaded explicitly. The team anticipate that all of these modules
+% will move to stable status over time, but they may be more flexible
+% in terms of interface and functionality detail. Feedback on these
+% modules is extremely valuable.
+%
+% \section{Moving from \LaTeXe{} to \pkg{expl3}}
+%
+% To help programmers to use \pkg{expl3} code in existing \LaTeXe{} package,
+% some short notes on making the change are probably desirable.
+% Suggestions for inclusion here are welcome! Some of the following
+% is concerned with code, and some with coding style.
+%
+% \begin{itemize}
+% \item \pkg{expl3} is mainly focused on programming. This means that
+% some areas still require the use of \LaTeXe{} internal macros.
+% For example, you may well need \tn{IfPackageLoadedTF}, as there
+% is currently no native \pkg{expl3} package loading module.
+% \item User level macros should be generated using the mechanism
+% available in the \pkg{ltcmd} module, which is part of the
+% the \LaTeX{} kernel since 2020-10-01.
+% \item At an internal level, most functions should be generated
+% \tn{long} (using \cs{cs_new:Npn}) rather than \enquote{short} (using
+% \cs{cs_new_nopar:Npn}).
+% \item Where possible, declare all variables and functions (using
+% \cs{cs_new:Npn}, \cs{tl_new:N}, etc.) before use.
+% \item Prefer \enquote{higher-level} functions over \enquote{lower-level},
+% where possible. So for example use \cs{cs_if_exist:NTF} and not
+% \cs{if_cs_exist:N}.
+% \item Use space to make code readable. In general, we recommend
+% a layout such as:
+% \begin{verbatim}
+% \cs_new:Npn \foo_bar:Nn #1#2
+% {
+% \cs_if_exist:NTF #1
+% { \__foo_bar:n {#2} }
+% { \__foo_bar:nn {#2} { literal } }
+% }
+% \end{verbatim}
+% where spaces are used around |{| and |}| except for isolated
+% |#1|, |#2|, \emph{etc.}
+% \item Put different code items on separate lines: readability is
+% much more useful than compactness.
+% \item Use long, descriptive names for functions and variables,
+% and for auxiliary functions use the parent function name plus
+% |aux|, |auxi|, |auxii| and so on.
+% \item If in doubt, ask the team via the LaTeX-L list: someone will
+% soon get back to you!
+% \end{itemize}
+%
+% \section{Load-time options for \pkg{expl3}}
+%
+% To support code authors, the \pkg{expl3} package for \LaTeXe{} includes
+% a small number of load-time options. These all work in a key--value
+% sense, recognising the \texttt{true} and \texttt{false} values. Giving
+% the option name alone is equivalent to using the option with the
+% \texttt{true} value.
+%
+% \DescribeOption{check-declarations}
+% All variables used in \pkg{expl3} code should be declared. This is enforced
+% by \TeX{} for variable types based on \TeX{} registers, but not for those
+% which are constructed using macros as the underlying storage system. The
+% \texttt{check-declarations} option enables checking for all variable
+% assignments, issuing an error if any variables are assigned without being
+% initialised. See also \cs{debug_on:n} \texttt{\{check-declarations\}}
+% in \pkg{interface3} for finer control.
+%
+% \DescribeOption{log-functions}
+% The \texttt{log-functions} option is used to enable recording of every new
+% function name in the \texttt{.log} file. This is useful for debugging
+% purposes, as it means that there is a complete list of all functions
+% created by each module loaded (with the exceptions of a very small number
+% required by the bootstrap code). See also \cs{debug_on:n}
+% \texttt{\{log-functions\}} in \pkg{interface3} for finer control.
+%
+% \DescribeOption{backend}
+% Selects the backend to be used for color, graphics and related operations that
+% are backend-dependent. Options available are
+% \begin{itemize}[font = \texttt]
+% \item[dvips] Use the \texttt{dvips} driver.
+% \item[dvipdfmx] Use the \texttt{dvipdfmx} driver.
+% \item[dvisvgm] Use the \texttt{dvisvgm} driver.
+% \item[luatex] Use the direct PDF output mode of \LuaTeX{}
+% \item[pdftex] Use the direct PDF output mode of \pdfTeX{}
+% \item[xetex] Use the \XeTeX{} version of the \texttt{dvipdfmx} driver.
+% \end{itemize}
+% For historical reasons, there is also \texttt{pdfmode} as an equivalent of
+% \texttt{luatex} or \texttt{pdftex}, and \texttt{xdvipdfmx} as
+% an equivalent to \texttt{xetex}, but these are deprecated
+%
+% \DescribeOption{suppress-backend-headers}
+% The \texttt{suppress-backend-headers} option suppresses loading of
+% backend-specific header files; currently this only affects \texttt{dvips}.
+% This option is available to support DVI-based routes that do not
+% support the |header| line used by \texttt{dvips}.
+%
+% The debugging options may also be given using
+% \verb|\keys_set:nn { sys } { ... }|; the \texttt{backend} option can be
+% given in this way \emph{only} if a backend has not already been loaded.
+% This method of setting options is useful where \pkg{expl3} is pre-loaded
+% by the \LaTeXe{} format.
+%
+% \section{Using \pkg{expl3} with formats other than \LaTeXe{}}
+%
+% As well as the \LaTeXe{} package \pkg{expl3}, there is also a
+% \enquote{generic} loader for the code, \texttt{expl3-generic.tex}.
+% This may be loaded using the plain \TeX{} syntax
+% \begin{verbatim}
+% \input expl3-generic %
+% \end{verbatim}
+% This enables the programming layer to work with the other formats.
+% As no options are available loading in this way, the \enquote{native}
+% drivers are automatically used. If this \enquote{generic} loader is
+% used with \LaTeXe{} the code automatically switches to the appropriate
+% package route.
+%
+% After loading the programming layer using the generic interface, the
+% commands \cs{ExplSyntaxOn} and \cs{ExplSyntaxOff} and the code-level
+% functions and variables detailed in \pkg{interface3} are available.
+% Note that other \LaTeXe{} packages \emph{using} \pkg{expl3} are not
+% loadable: package loading is dependent on the \LaTeXe{} package-management
+% mechanism.
+%
+% \section{Getting the version of \pkg{expl3}}
+%
+% \begin{function}{\ExplLoaderFileDate}
+% Once the programming layer is loaded by one of the loaders, you can access
+% its version in the ISO date format \meta{year}-\meta{month}-\meta{day},
+% through \cs{ExplLoaderFileDate}.
+%
+% The current version of \pkg{expl3} is \ExplLoaderFileDate.
+% \end{function}
+%
+% \section{Engine/primitive requirements}
+%
+% To use \pkg{expl3} and the higher level packages provided by the
+% team, the minimal set of primitive requirements is currently described
+% in \href{README.md}{README.md}.
+%
+% Practically, these requirements are met by the engines
+% \begin{itemize}
+% \item \pdfTeX{} v1.40.20 or later.
+% \item \XeTeX{} v0.999991 or later.
+% \item \LuaTeX{} v1.10 or later.
+% \item e-(u)\pTeX{} v3.8.2 or later.
+% \item Prote (2021) or later.
+% \end{itemize}
+%
+% Additional modules beyond the core of \pkg{expl3} may require additional
+% primitives. In particular, third-party authors may significantly
+% extend the primitive coverage requirements.
+%
+% \section{The \LaTeX{} Project}
+%
+% Development of \LaTeX3 is carried out by The \LaTeX{} Project:
+% \url{https://www.latex-project.org/latex3/}.
+%
+% \begin{thebibliography}{1}
+%
+% \bibitem{A-W:K-TB}
+% Donald E Knuth
+% \newblock \emph{The \TeX{}book}.
+% \newblock Addison-Wesley, Reading, Massachusetts, 1984.
+%
+% \bibitem{A-W:GMS94}
+% Goossens, Mittelbach and Samarin.
+% \newblock \emph{ The \LaTeX{} Companion}.
+% \newblock Addison-Wesley, Reading, Massachusetts, 1994.
+%
+% \bibitem{A-W:LLa94}
+% Leslie Lamport.
+% \newblock \emph{\LaTeX{}: A Document Preparation System}.
+% \newblock Addison-Wesley, Reading, Massachusetts, second edition, 1994.
+%
+% \bibitem{tub:MR97-1}
+% Frank Mittelbach and Chris Rowley.
+% \newblock \enquote{The \LaTeX{} Project}.
+% \newblock \emph{TUGboat},
+% Vol.\,18, No.\,3, pp.\,195--198, 1997.
+%
+% \end{thebibliography}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{expl3} implementation}
+%
+% The implementation here covers several things. There are two
+% \enquote{loaders} to define: the parts of the code that are specific to
+% \LaTeXe{} or to non-\LaTeXe{} formats. These have to cover the same
+% concepts as each other but in rather different ways: as a result, much
+% of the code is given in separate blocks. There is also a short piece of
+% code for the start of the \enquote{payload}: this is to ensure that
+% loading is always done in the right way.
+%
+% \subsection{Loader interlock}
+%
+% A short piece of set up to check that the loader and \enquote{payload}
+% versions match.
+%
+% \begin{macro}{\ExplLoaderFileDate}
+% As DocStrip is used to generate \cs{ExplFileDate}
+% for all files from the same source, it has to match. Thus the loaders
+% simply save this information with a new name.
+% \begin{macrocode}
+%<*loader>
+\let\ExplLoaderFileDate\ExplFileDate
+%</loader>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\c__kernel_expl_date_tl}
+% The \LaTeXe{} loader stores a private copy of \cs{ExplFileDate},
+% which is fixed when the format is build and cannot be changed later.
+% While \cs{ExplFileDate} ensures that the loader (either
+% \texttt{2ekernel} or \texttt{package}) version matches the version
+% of \file{expl3-code.tex}, this one ensures that the version of an
+% eventual |\usepackage{expl3}| matches the version from the format.
+% It seems to be common to have stray format files in the user tree
+% which trigger errors due to mismatched versions (\emph{e.g.}
+% \url{https://github.com/latex3/latex3/issues/781}).
+%
+% This block also goes to the generic loader, as \pkg{expl3} isn't
+% preloaded there, so the kernel date should be equal to the loader
+% date.
+% \begin{macrocode}
+%<*2ekernel|generic>
+\begingroup
+ \catcode`\_=11
+ \expandafter
+ \ifx\csname c__kernel_expl_date_tl\endcsname\relax
+ \global\let\c__kernel_expl_date_tl\ExplFileDate
+ \fi
+\endgroup
+%</2ekernel|generic>
+% \end{macrocode}
+% \end{macro}
+%
+% The interlock test itself is simple: \cs{ExplLoaderFileDate} must be
+% defined and identical to \cs{ExplFileDate}. As this has to work for
+% both \LaTeXe{} and other formats, there is some auto-detection involved.
+% (Done this way avoids having two very similar blocks for \LaTeXe{} and
+% other formats.)
+% \begin{macrocode}
+%<*!loader>
+\begingroup
+ \def\next{\endgroup}%
+ \expandafter\ifx\csname PackageError\endcsname\relax
+ \begingroup
+ \def\next{\endgroup\endgroup}%
+ \def\PackageError#1#2#3%
+ {%
+ \endgroup
+ \errhelp{#3}%
+ \errmessage{#1 Error: #2!}%
+ }%
+ \fi
+ \expandafter\ifx\csname ExplLoaderFileDate\endcsname\relax
+ \def\next
+ {%
+ \PackageError{expl3}{No expl3 loader detected}
+ {%
+ You have attempted to use the expl3 code directly rather than using
+ the correct loader. Loading of expl3 will abort.
+ }%
+ \endgroup
+ \endinput
+ }
+ \else
+ \ifx\ExplLoaderFileDate\ExplFileDate
+ \else
+ \def\next
+ {%
+ \PackageError{expl3}{Mismatched expl3 files detected}
+ {%
+ You have attempted to load expl3 with mismatched files:
+ probably you have one or more files 'locally installed' which
+ are in conflict. Loading of expl3 will abort.
+ }%
+ \endgroup
+ \endinput
+ }%
+ \fi
+\fi
+\next
+%</!loader>
+% \end{macrocode}
+%
+% A reload test for the payload, just in case.
+% \begin{macrocode}
+%<*!loader>
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname ver@expl3-code.tex\endcsname\relax
+ \expandafter\edef\csname ver@expl3-code.tex\endcsname
+ {%
+ \ExplFileDate\space
+ L3 programming layer
+ }%
+\else
+ \expandafter\endinput
+\fi
+%</!loader>
+% \end{macrocode}
+%
+% All good: log the version of the code used (for log completeness). As this
+% is more-or-less \cs{ProvidesPackage} without a separate file and as this also
+% needs to work without \LaTeXe{}, just write the information directly to the
+% log.
+% \begin{macrocode}
+%<*!loader>
+\immediate\write-1 %
+ {%
+ Package: expl3
+ \ExplFileDate\space
+ L3 programming layer (code)%
+ }%
+%</!loader>
+% \end{macrocode}
+%
+% \subsection{\LaTeXe{} loaders}
+%
+% Loading with \LaTeXe{} may be as part of the format (pre-loading)
+% or as a package. We have to allow for both possible paths, and of
+% course the package being loaded on to of the pre-load. That means
+% the code here must be safe against re-loading.
+%
+% \begin{macrocode}
+%<*package&loader|2ekernel>
+% \end{macrocode}
+%
+% Identify the package or add to the format message.
+% \begin{macrocode}
+%<*2ekernel>
+\ifdefined\LaTeXReleaseInfo
+ \LaTeXReleaseInfo\expandafter{\the\LaTeXReleaseInfo
+ \show@release@info{L3 programming layer <\ExplFileDate>}%
+ }%
+\else
+ \everyjob\expandafter{\the\everyjob
+ \message{L3 programming layer <\ExplFileDate>}%
+ }%
+\fi
+%</2ekernel>
+%<*!2ekernel>
+\ProvidesPackage{expl3}
+ [%
+ \ExplFileDate\space
+ L3 programming layer (loader)
+ ]%
+%</!2ekernel>
+% \end{macrocode}
+%
+% \begin{macro}{\ProvidesExplPackage, \ProvidesExplClass, \ProvidesExplFile}
+% For other packages and classes building on this one it is convenient
+% not to need \cs{ExplSyntaxOn} each time. All macros use the same
+% internal one with the proper \LaTeXe{} command.
+% \begin{macrocode}
+\protected\def\ProvidesExplPackage
+ {\@expl@provides@file@@Nnnnnn\ProvidesPackage{Package}}
+\protected\def\ProvidesExplClass
+ {\@expl@provides@file@@Nnnnnn\ProvidesClass{Document Class}}
+\protected\def\ProvidesExplFile
+ {\@expl@provides@file@@Nnnnnn\ProvidesFile{File}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@expl@provides@file@@Nnnnnn}
+% \begin{macro}{\@expl@provides@file@@N}
+% \begin{macro}{\@expl@provides@generic@@wnnw}
+% We need to check the existence of the
+% \cs[no-index]{Provides\meta{thing}}, since we need to load this very
+% early in the \LaTeXe{} kernel. The gymnastics with the version identifier
+% argument allow for the case where it starts with a \texttt{v} and the one
+% where it does not: formally the \texttt{v} is not part of the version,
+% but a lot of people include it.
+% \begin{macrocode}
+\protected\long\def\@expl@provides@file@@Nnnnnn#1#2#3#4#5#6%
+ {%
+ \ifnum0%
+ \ifdefined#11\fi
+ \ifx\relax#1\else1\fi
+ =11
+ \expandafter#1%
+ \else
+ \@expl@provides@generic@@wnnw{#2}%
+ \fi
+ {#3}[{#4 \ifx\relax#5\relax\else\@expl@provides@file@@N#5\space\fi #6}]%
+ \ExplSyntaxOn
+ }
+\long\def\@expl@provides@file@@N#1{v\if#1v\else#1\fi}
+\protected\long\def\@expl@provides@generic@@wnnw#1\fi#2[#3]%
+ {%
+ \immediate\write-1{#1: #2 #3}%
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% Load the business end: this leaves \cs{expl3} syntax on.
+% The test ensures we only load once without needing to know if
+% there was a preloading step.
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname tex\string _let:D\endcsname\relax
+ \expandafter\@firstofone
+\else
+ \expandafter\@gobble
+\fi
+ {\input expl3-code.tex }%
+% \end{macrocode}
+%
+% A check that the bootstrap code did not abort loading: if it did,
+% bail out silently here.
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname tex\string _let:D\endcsname\relax
+ \expandafter\endinput
+\fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=expl>
+% \end{macrocode}
+%
+% At this point, if we have \cs{c__kernel_expl_date_tl} defined, just
+% call the \cs{__kernel_dependency_version_check:Nn} auxiliary to check
+% if it matches \cs{ExplLoaderFileDate}. Here the test is performed
+% only if \cs{c__kernel_expl_date_tl} exists because this file can be
+% loaded in a \LaTeXe{} format without \pkg{expl3} preloaded, where that
+% token list doesn't exist.
+%
+% This is all done in the \texttt{package} \pkg{docstrip} guard because
+% it doesn't apply to \pkg{expl3.ltx}.
+% \begin{macrocode}
+%<*package>
+\ifcsname\detokenize{c__kernel_expl_date_tl}\endcsname
+ \expandafter\@firstofone
+\else
+% \end{macrocode}
+% If \cs{c__kernel_expl_date_tl} does \emph{not} exist we may be loading
+% in a format without \pkg{expl3} preloaded or in the earlier (although
+% still compatible) version in which the error mentioned above showed
+% up. If loading as a package, \file{expl3-code.tex} got read and here
+% the \pkg{expl3} syntax is on. Otherwise it was already loaded in a
+% sligtly older kernel, so we fire the incompatibility error message and
+% abort loading.
+% \begin{macrocode}
+ \ifodd\csname\detokenize{l__kernel_expl_bool}\endcsname
+% \end{macrocode}
+% In package mode all files are loaded in one go, so versions will
+% match. We just have to set \cs{c__kernel_expl_date_tl} so that
+% further dependencies don't break:
+% \begin{macrocode}
+ \global\expandafter\let\csname\detokenize
+ {c__kernel_expl_date_tl}\endcsname\ExplLoaderFileDate
+ \expandafter\expandafter
+ \expandafter\@gobble
+ \else
+% \end{macrocode}
+% And reloading in an incompatible version is an error:
+% \begin{macrocode}
+ \expandafter\expandafter
+ \expandafter\@firstofone
+ \fi
+\fi
+ {\csname\detokenize{__kernel_dependency_version_check:Nn}\endcsname
+ \ExplLoaderFileDate{expl3.sty}}%
+%</package>
+% \end{macrocode}
+%
+% Here we can also detect whether we're reloading. This code goes into
+% \texttt{expl3.ltx} and \texttt{expl3.sty}, the former loaded into the
+% \LaTeXe{} format. When this code is loaded for the first time, the
+% \cs{g_@@_reload_bool} boolean doesn't exist (\cs{else} branch of the
+% \cs{ifcsname} below), so we create it. If the \cs{ifcsname} is true,
+% then we do \cs{ExplSyntaxOn} (because when reloading,
+% \texttt{expl3-code.tex} isn't read again), and set
+% \cs{g_@@_reload_bool} to true.
+% \begin{macrocode}
+\ifcsname\detokenize{g_@@_reload_bool}\endcsname
+ \ExplSyntaxOn
+ \bool_gset_true:N \g_@@_reload_bool
+\else
+ \bool_new:N \g_@@_reload_bool
+\fi
+% \end{macrocode}
+%
+% \begin{variable}{\c_@@_def_ext_tl}
+% Needed by \LaTeXe{}, and avoiding a re-load issue. Variables are
+% best checked explicitly, rather than with \cs{g_@@_reload_bool}
+% because some appear only in one of the code files, so
+% \cs{g_@@_reload_bool} doesn't necessarily mean that the variable
+% is already declared.
+% \begin{macrocode}
+\tl_if_exist:NF \c_@@_def_ext_tl
+ { \tl_const:Nn \c_@@_def_ext_tl { def } }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {\__kernel_sys_configuration_load:n,\__kernel_sys_configuration_load_std:n}
+% To load configurations, we have the following cases
+% \begin{itemize}
+% \item \pkg{expl3} is pre-loaded: by the time any configuration loads,
+% we have the full file loading stack, and only need the standard
+% version of the code here.
+% \item The package is loaded with pre-loading: we again use the standard
+% version, but we don't test just yet.
+% \item The package is used without pre-loaded code: we need to manually
+% manage \pkg{expl3} syntax.
+% \end{itemize}
+% \begin{macrocode}
+\cs_gset_protected:Npn \__kernel_sys_configuration_load:n #1
+%<*!2ekernel>
+ {
+ \ExplSyntaxOff
+ \cs_undefine:c { ver@ #1 .def }
+ \@onefilewithoptions {#1} [ ] [ ]
+ \c_@@_def_ext_tl
+ \ExplSyntaxOn
+ }
+\cs_gset_protected:Npn \__kernel_sys_configuration_load_std:n #1
+%</!2ekernel>
+ {
+ \cs_undefine:c { ver@ #1 .def }
+ \@onefilewithoptions {#1} [ ] [ ]
+ \c_@@_def_ext_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_options_clist}
+% \begin{macrocode}
+%<*!2ekernel>
+\clist_if_exist:NF \l_@@_options_clist
+ { \clist_new:N \l_@@_options_clist }
+\DeclareOption*
+ { \clist_put_right:NV \l_@@_options_clist \CurrentOption }
+\ProcessOptions \relax
+%</!2ekernel>
+% \end{macrocode}
+% \end{variable}
+%
+% Pretty standard setting creation.
+% \begin{macrocode}
+\keys_define:nn { sys }
+ {
+ backend .choices:nn =
+ { dvipdfmx , dvips , dvisvgm , luatex , pdftex , pdfmode , xdvipdfmx , xetex }
+ { \sys_load_backend:n {#1} } ,
+ check-declarations .choice: ,
+ check-declarations / true .code:n =
+ { \debug_on:n { check-declarations } } ,
+ check-declarations / false .code:n =
+ {
+ \__kernel_if_debug:TF
+ { \debug_off:n { check-declarations } }
+ { }
+ } ,
+ check-declarations .default:n = true ,
+ driver .meta:n = { backend = #1 } ,
+ enable-debug .code:n = {} , % A stub
+ log-functions .choice: ,
+ log-functions / true .code:n =
+ { \debug_on:n { log-functions } } ,
+ log-functions / false .code:n =
+ {
+ \__kernel_if_debug:TF
+ { \debug_off:n { log-functions } }
+ { }
+ } ,
+ log-functions .default:n = true ,
+ suppress-backend-headers .bool_gset_inverse:N
+ = \g__kernel_backend_header_bool ,
+ suppress-backend-headers .initial:n = false ,
+ undo-recent-deprecations .code:n = {} % A stub
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\@expl@sys@load@backend@@@@}
+% A backend has to be in place by the start of the document: this has
+% to be before global options are checked for use.
+%
+% The \cs[no-index]{@expl@...@@@@} macros defined in this package are
+% interfaces for \LaTeXe{}. There are currently (this will change
+% with the next release of \LaTeXe{}) two possible cases, at this
+% point of the code: either \cs{@expl@sys@load@backend@@@@} (and the
+% others) already exist because they were defined in
+% \texttt{ltexpl.ltx} (in \texttt{2ekernel} mode) or in
+% \texttt{expl3.ltx} (in \texttt{package} mode).
+%
+% In \texttt{2ekernel} mode, if they exist we are using a future
+% (2020-10-01) release of \LaTeXe{} and we don't need (and can't)
+% patch \LaTeXe's internals because these commands are already there.
+% Though if they don't exist in \texttt{2ekernel} mode, we're using
+% an older version of the kernel, so we \emph{must} patch.
+%
+% In \texttt{package} mode, if these commands exist, then we are using
+% a version of \LaTeXe{} with \pkg{expl3} preloaded (any version)
+% and in any case patching is already done or the macros are in the
+% format itself, so nothing to do.
+% But if in \texttt{package} mode these macros don't exist, we have an
+% even older version of \LaTeXe{} which doesn't even have
+% \pkg{expl3} preloaded, so patching is necessary.
+%
+% All this means that in both \texttt{2ekernel} and \texttt{package}
+% mode we have to check whether \cs{@expl@sys@load@backend@@@@}
+% exists, and patch some \LaTeXe{} internals if it doesn't.
+%
+% In newer \LaTeXe{}, these macros have an empty definition in
+% \texttt{ltexpl.dtx} in case something wrong happens while loading
+% this file (\texttt{expl3.ltx}), so they can safely be used in the
+% \LaTeXe{} kernel.
+%
+% \cs{@expl@sys@load@backend@@@@} is inserted right at the beginning
+% of \cs{document}, but after closing the group started by \cs{begin}.
+% When using \cs{tl_put_left:Nn} to patch the backend loading in
+% \cs{document}, we need to make sure that it happens at group level
+% zero, thus the strange |\endgroup...\begingroup| thing.
+%
+% This chunk of code should only be executed when loading
+% \texttt{expl3.sty} in a \LaTeXe{} without \pkg{expl3} preloaded, so
+% we check if \cs{@expl@sys@load@backend@@@@} exists.
+% \begin{macrocode}
+\cs_if_exist:NF \@expl@sys@load@backend@@@@
+ {
+ \tl_put_left:Nn \document
+ {
+ \endgroup
+ \@expl@sys@load@backend@@@@
+ \begingroup
+ }
+ }
+% \end{macrocode}
+%
+% Now we define it anyhow.
+% \begin{macrocode}
+\cs_gset_protected:Npn \@expl@sys@load@backend@@@@
+ {
+ \str_if_exist:NF \c_sys_backend_str
+ { \sys_load_backend:n { } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% Process package options.
+% \begin{macrocode}
+%<*!2ekernel>
+\keys_set:nV { sys } \l_@@_options_clist
+\str_if_exist:NF \c_sys_backend_str
+ { \sys_load_backend:n { } }
+%</!2ekernel>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*!2ekernel>
+\bool_if:NT \g_@@_reload_bool
+ {
+ \cs_gset_eq:NN \__kernel_sys_configuration_load:n
+ \__kernel_sys_configuration_load_std:n
+ \ExplSyntaxOff
+ \file_input_stop:
+ }
+%</!2ekernel>
+% \end{macrocode}
+%
+% Load the dynamic part of the code, either now or during the next run.
+% \begin{macrocode}
+\cs_if_free:cTF { ver@expl3.sty }
+ {
+ \tex_everyjob:D \exp_after:wN
+ {
+ \tex_the:D \tex_everyjob:D
+ \__kernel_sys_everyjob:
+ }
+ }
+ { \__kernel_sys_everyjob: }
+% \end{macrocode}
+%
+% \begin{variable}{\s_@@_stop}
+% Internal scan marks. This code has to be reload-safe, so this one
+% has to be guarded with \cs{if_cs_exist:N} (\cs{cs_if_exist:NF}) wouldn't
+% do because it returns false for control sequences equal to \cs{scan_stop:}.
+% \begin{macrocode}
+\reverse_if:N \if_cs_exist:N \s_@@_stop
+ \scan_new:N \s_@@_stop
+\fi:
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@pushfilename, \@popfilename}
+% \begin{macro}{\@@_status_pop:w}
+% \begin{macro}{\@expl@push@filename@@@@}
+% \begin{macro}{\@expl@push@filename@aux@@@@}
+% \begin{macro}{\@expl@pop@filename@@@@}
+% The idea here is to use \LaTeXe{}'s \tn{@pushfilename} and
+% \tn{@popfilename} to track the current syntax status. This can be
+% achieved by saving the current status flag at each push to a stack,
+% then recovering it at the pop stage and checking if the code
+% environment should still be active.
+%
+% Here the code follows the same patching logic than above for
+% \cs{@expl@sys@load@backend@@@@}.
+% \begin{macrocode}
+\cs_if_exist:NF \@expl@push@filename@@@@
+ {
+ \tl_put_left:Nn \@pushfilename { \@expl@push@filename@@@@ }
+ \tl_put_right:Nn \@pushfilename { \@expl@push@filename@aux@@@@ }
+ }
+\cs_gset_protected:Npn \@expl@push@filename@@@@
+ {
+ \exp_args:Ne \__kernel_file_input_push:n
+ {
+ \tl_to_str:N \@currname .
+ \tl_to_str:N \@currext
+ }
+ \tl_put_left:Ne \l_@@_status_stack_tl
+ {
+ \bool_if:NTF \l__kernel_expl_bool
+ { 1 }
+ { 0 }
+ }
+ \ExplSyntaxOff
+ }
+% \end{macrocode}
+% This bit of trickery is needed to grab the name of the file being loaded
+% so we can record it.
+% \begin{macrocode}
+\cs_gset_protected:Npn \@expl@push@filename@aux@@@@ #1#2#3
+ {
+ \str_gset:Nn \g_file_curr_name_str {#3}
+ #1 #2 {#3}
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_if_exist:NF \@expl@pop@filename@@@@
+ {
+ \tl_put_right:Nn \@popfilename
+ { \@expl@pop@filename@@@@ }
+ }
+\cs_gset_protected:Npn \@expl@pop@filename@@@@
+ {
+ \__kernel_file_input_pop:
+ \tl_if_empty:NTF \l_@@_status_stack_tl
+ { \ExplSyntaxOff }
+ { \exp_after:wN \@@_status_pop:w \l_@@_status_stack_tl \s_@@_stop }
+ }
+% \end{macrocode}
+% The pop auxiliary function removes the first item from the stack,
+% saves the rest of the stack and then does the test. The flag here
+% is not a proper \texttt{bool}, so a low-level test is used.
+% \begin{macrocode}
+\cs_gset_protected:Npn \@@_status_pop:w #1#2 \s_@@_stop
+ {
+ \tl_set:Nn \l_@@_status_stack_tl {#2}
+ \int_if_odd:nTF {#1}
+ { \ExplSyntaxOn }
+ { \ExplSyntaxOff }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_status_stack_tl}
+% As \pkg{expl3} itself cannot be loaded with the code environment
+% already active, at the end of the package \cs{ExplSyntaxOff} can
+% safely be called.
+% \begin{macrocode}
+\tl_if_exist:NF \l_@@_status_stack_tl
+ {
+ \tl_new:N \l_@@_status_stack_tl
+ \tl_set:Nn \l_@@_status_stack_tl { 0 }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% Tidy up configuration loading, as promised.
+% \begin{macrocode}
+%<*!2ekernel>
+\cs_gset_eq:NN \__kernel_sys_configuration_load:n
+ \__kernel_sys_configuration_load_std:n
+%</!2ekernel>
+% \end{macrocode}
+%
+% For pre-loading, we have to manually disable the syntax.
+% \begin{macrocode}
+%<*2ekernel>
+\ExplSyntaxOff
+%</2ekernel>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package&loader|2ekernel>
+% \end{macrocode}
+%
+% \subsection{Generic loader}
+%
+% \begin{macrocode}
+%<*generic>
+% \end{macrocode}
+%
+% The generic loader starts with a test to ensure that the current format is
+% not \LaTeXe{}!
+% \begin{macrocode}
+\begingroup
+ \def\tempa{LaTeX2e}%
+ \def\next{}%
+ \ifx\fmtname\tempa
+ \def\next
+ {%
+ \PackageInfo{expl3}{Switching from generic to LaTeX2e loader}%
+% \end{macrocode}
+% The \cs{relax} stops \cs{RequirePackage} from scanning for a date
+% argument. Putting \tn{endinput} \emph{after} loading the package is
+% crucial, as otherwise \tn{endinput} would close the file
+% \file{expl3.sty} at the end of its first line: indeed, as long as
+% \file{expl3.sty} is open it is impossible to close the file
+% \file{expl3-generic.tex}.
+% \begin{macrocode}
+ \RequirePackage{expl3}\relax \endinput
+ }%
+ \fi
+\expandafter\endgroup
+\next
+% \end{macrocode}
+%
+% Reload check and identify the package:
+% no \LaTeXe{} mechanism so this is all pretty basic.
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname ver@expl3-generic.tex\endcsname\relax
+\else
+ \immediate\write-1
+ {%
+ Package expl3 Info: The package is already loaded.%
+ }%
+ \expandafter\endinput
+\fi
+\immediate\write-1
+ {%
+ Package: expl3
+ \ExplFileDate\space
+ L3 programming layer (loader)%
+ }%
+\expandafter\edef\csname ver@expl3-generic.tex\endcsname
+ {\ExplFileDate\space L3 programming layer}%
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ifnum\currentgrouplevel=0 %
+\else
+ \errhelp{expl3 cannot be loaded inside a group:
+ reading the code has been aborted.}%
+ \errmessage{expl3 Error: Loading attempted inside a group!}%
+ \expandafter\endinput
+\fi
+% \end{macrocode}
+%
+% \begin{variable}[int]{\l@expl@tidy@tl}
+% Save the category code of |@| and then set it to \enquote{letter}.
+% \begin{macrocode}
+\expandafter\edef\csname l@expl@tidy@tl\endcsname
+ {%
+ \catcode64=\the\catcode64\relax
+ \let\expandafter\noexpand\csname l@expl@tidy@tl\endcsname
+ \noexpand\undefined
+ }%
+\catcode64=11 %
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\AtBeginDocument}
+% \begin{macro}[int]{\expl@AtBeginDocument}
+% There are a few uses of \cs{AtBeginDocument} in the package code: the
+% easiest way around that is to simply do the code \enquote{now}. As
+% bundles such as \pkg{miniltx} may have defined \cs{AtBeginDocument}
+% any existing definition is saved for restoration after the payload.
+% \begin{macrocode}
+\let\expl@AtBeginDocument\AtBeginDocument
+\def\AtBeginDocument#1{#1}%
+\expandafter\def\expandafter\l@expl@tidy@tl\expandafter
+ {%
+ \l@expl@tidy@tl
+ \let\AtBeginDocument\expl@AtBeginDocument
+ \let\expl@AtBeginDocument\undefined
+ }%
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Load the business end: this leaves \cs{expl3} syntax on.
+% \begin{macrocode}
+\input expl3-code.tex %
+% \end{macrocode}
+%
+% A check that the bootstrap code did not abort loading: if it did,
+% bail out silently here.
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname tex\string _let:D\endcsname\relax
+ \expandafter\endinput
+\fi
+% \end{macrocode}
+%
+% \begin{macro}{\__kernel_sys_configuration_load:n}
+% Very basic.
+% \begin{macrocode}
+\cs_gset_protected:Npn \__kernel_sys_configuration_load:n #1
+ {
+ \group_begin:
+ \cs_set_protected:Npn \ProvidesExplFile
+ {
+ \char_set_catcode_space:n { `\ }
+ \ProvidesExplFileAux
+ }
+ \cs_set_protected:Npn \ProvidesExplFileAux ##1##2##3##4
+ {
+ \group_end:
+ \iow_log:e { File:~##1~##2~v##3~##4 }
+ }
+ \tex_input:D #1 .def \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\g__kernel_backend_header_bool}
+% Load the dynamic code and standard back-end.
+% \begin{macrocode}
+\__kernel_sys_everyjob:
+\bool_new:N \g__kernel_backend_header_bool
+\bool_gset_true:N \g__kernel_backend_header_bool
+\sys_load_backend:n { }
+% \end{macrocode}
+% \end{macro}
+%
+% For the generic loader, a few final steps to take. Turn of \cs{expl3}
+% syntax and tidy up the small number of temporary changes.
+% \begin{macrocode}
+\ExplSyntaxOff
+\l@expl@tidy@tl
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</generic>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/expl3.pdf b/macros/latex-dev/required/l3kernel/expl3.pdf
new file mode 100644
index 0000000000..892886a362
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/expl3.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/interface3.pdf b/macros/latex-dev/required/l3kernel/interface3.pdf
new file mode 100644
index 0000000000..a866590ab0
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/interface3.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/interface3.tex b/macros/latex-dev/required/l3kernel/interface3.tex
new file mode 100644
index 0000000000..1bf31032ee
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/interface3.tex
@@ -0,0 +1,82 @@
+\iffalse meta-comment
+
+File: interface3.tex
+
+Copyright (C) 1990-2011,2017-2024 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this
+license or (at your option) any later version. The latest version
+of this license is in the file
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3kernel bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+The released version of this bundle is available from CTAN.
+
+-----------------------------------------------------------------------
+
+The development version of the bundle can be found at
+
+ https://github.com/latex3/latex3
+
+for those people who are interested.
+
+\fi
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% This document typesets the LaTeX3 interface descriptions a single document.
+% This produces quite a large file (more than 360 pages as of Dec 2023).
+%
+% There is also a full version of the sources (source3.tex) which additionally
+% also typesets the command implementations.
+%
+% Do not forget to generate the index (as explained on the terminal output
+% near the end of the run)!
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\documentclass[kernel]{l3doc}
+
+\newif\ifinterface
+\interfacetrue
+
+\listfiles
+
+\begin{document}
+
+\title{The \LaTeX3 Interfaces}
+\author{%
+ The \LaTeX{} Project\thanks
+ {%
+ E-mail:
+ \href{mailto:latex-team@latex-project.org}
+ {latex-team@latex-project.org}%
+ }%
+}
+\date{Released 2024-04-11}
+
+\pagenumbering{roman}
+\maketitle
+
+%
+% First load all modules and typeset the documentation parts
+%
+
+\input{source3body} % all the individual modules
+
+\clearpage
+
+\begingroup
+ \def\endash{--}
+ \catcode`\-\active
+ \def-{\futurelet\temp\indexdash}
+ \def\indexdash{\ifx\temp-\endash\fi}
+ \DelayPrintIndex
+\endgroup
+
+\end{document}
diff --git a/macros/latex-dev/required/l3kernel/l3.ins b/macros/latex-dev/required/l3kernel/l3.ins
new file mode 100644
index 0000000000..bf7a75381d
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3.ins
@@ -0,0 +1,182 @@
+\iffalse meta-comment
+
+File l3.ins
+
+Copyright (C) 2011,2012,2014-2024 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this
+license or (at your option) any later version. The latest version
+of this license is in the file
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3kernel bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+-----------------------------------------------------------------------
+
+The development version of the bundle can be found at
+
+ https://github.com/latex3/latex3
+
+for those people who are interested.
+
+-----------------------------------------------------------------------
+
+Any modification of this file should ensure that the copyright and
+license information is placed in the derived files.
+
+\fi
+
+\let\jobname\relax
+\input docstrip %
+\askforoverwritefalse
+
+\preamble
+
+Copyright (C) 1990-2024 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of
+the LaTeX Project Public License (LPPL), either version 1.3c of
+this license or (at your option) any later version. The latest
+version of this license is in the file:
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3kernel bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+\endpreamble
+% stop docstrip adding \endinput
+\postamble
+\endpostamble
+
+\keepsilent
+
+\generate
+ {
+ \file{expl3-code.tex}
+ {
+ \from{expl3.dtx} {package}
+ \from{l3bootstrap.dtx} {package}
+ \from{l3names.dtx} {package,tex}
+ \from{l3basics.dtx} {package}
+ \from{l3expan.dtx} {package}
+ \from{l3quark.dtx} {package}
+ \from{l3tl.dtx} {package}
+ \from{l3tl-build.dtx} {package}
+ \from{l3str.dtx} {package}
+ \from{l3seq.dtx} {package}
+ \from{l3int.dtx} {package}
+ \from{l3flag.dtx} {package}
+ \from{l3prg.dtx} {package}
+ \from{l3sys.dtx} {package,tex}
+ \from{l3clist.dtx} {package}
+ \from{l3token.dtx} {package,tex}
+ \from{l3prop.dtx} {package}
+ \from{l3msg.dtx} {package}
+ \from{l3file.dtx} {package}
+ \from{l3skip.dtx} {package}
+ \from{l3keys.dtx} {package}
+ \from{l3intarray.dtx} {package,tex}
+ \from{l3fp.dtx} {package}
+ \from{l3fp-aux.dtx} {package}
+ \from{l3fp-traps.dtx} {package}
+ \from{l3fp-round.dtx} {package}
+ \from{l3fp-parse.dtx} {package}
+ \from{l3fp-assign.dtx} {package}
+ \from{l3fp-logic.dtx} {package}
+ \from{l3fp-basics.dtx} {package}
+ \from{l3fp-extended.dtx}{package}
+ \from{l3fp-expo.dtx} {package}
+ \from{l3fp-trig.dtx} {package}
+ \from{l3fp-convert.dtx} {package}
+ \from{l3fp-random.dtx} {package}
+ \from{l3fp-types.dtx} {package}
+ \from{l3fp-symbolic.dtx}{package}
+ \from{l3fp-functions.dtx}{package}
+ \from{l3fparray.dtx} {package}
+ \from{l3bitset.dtx} {package}
+ \from{l3cctab.dtx} {package}
+ \from{l3sort.dtx} {package}
+ \from{l3str-convert.dtx}{package}
+ \from{l3tl-analysis.dtx}{package}
+ \from{l3regex.dtx} {package}
+ \from{l3box.dtx} {package}
+ \from{l3color.dtx} {package}
+ \from{l3pdf.dtx} {package,tex}
+ \from{l3coffins.dtx} {package}
+ \from{l3luatex.dtx} {package,tex}
+ \from{l3unicode.dtx} {package}
+ \from{l3text.dtx} {package}
+ \from{l3text-case.dtx} {package}
+ \from{l3text-map.dtx} {package}
+ \from{l3text-purify.dtx}{package}
+ \from{l3legacy.dtx} {package}
+ \from{l3deprecation.dtx}{package}
+ }
+ }
+
+\generate{\file{expl3.sty} {\from{expl3.dtx} {package,loader}}}
+\generate{\file{expl3.ltx} {\from{expl3.dtx} {2ekernel,loader}}}
+\generate{\file{expl3-generic.tex}{\from{expl3.dtx} {generic,loader}}}
+
+\generate{\file{l3doc.cls} {\from{l3doc.dtx} {class}}}
+% not distributed:
+%\generate{\file{l3doc.ist} {\from{l3doc.dtx} {docist}}}
+
+% ISO-8859 encodings.
+\generate{%
+ \file{l3str-enc-iso88591.def} {\from{l3str-convert.dtx}{iso88591}}%
+ \file{l3str-enc-iso88592.def} {\from{l3str-convert.dtx}{iso88592}}%
+ \file{l3str-enc-iso88593.def} {\from{l3str-convert.dtx}{iso88593}}%
+ \file{l3str-enc-iso88594.def} {\from{l3str-convert.dtx}{iso88594}}%
+ \file{l3str-enc-iso88595.def} {\from{l3str-convert.dtx}{iso88595}}%
+ \file{l3str-enc-iso88596.def} {\from{l3str-convert.dtx}{iso88596}}%
+ \file{l3str-enc-iso88597.def} {\from{l3str-convert.dtx}{iso88597}}%
+ \file{l3str-enc-iso88598.def} {\from{l3str-convert.dtx}{iso88598}}%
+ \file{l3str-enc-iso88599.def} {\from{l3str-convert.dtx}{iso88599}}%
+ \file{l3str-enc-iso885910.def} {\from{l3str-convert.dtx}{iso885910}}%
+ \file{l3str-enc-iso885911.def} {\from{l3str-convert.dtx}{iso885911}}%
+ \file{l3str-enc-iso885913.def} {\from{l3str-convert.dtx}{iso885913}}%
+ \file{l3str-enc-iso885914.def} {\from{l3str-convert.dtx}{iso885914}}%
+ \file{l3str-enc-iso885915.def} {\from{l3str-convert.dtx}{iso885915}}%
+ \file{l3str-enc-iso885916.def} {\from{l3str-convert.dtx}{iso885916}}%
+}
+
+\generate{\file{l3debug.def} {\from{l3debug.dtx} {package}}}
+
+\generate{\file{l3docstrip.tex} {\from{l3docstrip.dtx} {program}}}
+
+\generate{\file{l3names.def} {\from{l3names.dtx} {names}}}
+
+% Lua code
+
+\def\MetaPrefix{--}
+\preamble
+
+Copyright (C) 1990-2024 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of
+the LaTeX Project Public License (LPPL), either version 1.3c of
+this license or (at your option) any later version. The latest
+version of this license is in the file:
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3kernel bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+\endpreamble
+\nopostamble
+\generate{\file{expl3.lua}{
+ \from{l3luatex.dtx}{package,lua}
+ \from{l3names.dtx}{package,lua}
+ \from{l3sys.dtx}{package,lua}
+ \from{l3token.dtx}{package,lua}
+ \from{l3intarray.dtx}{package,lua}
+ \from{l3pdf.dtx}{package,lua}
+}}
+
+\endbatchfile
diff --git a/macros/latex-dev/required/l3kernel/l3basics.dtx b/macros/latex-dev/required/l3kernel/l3basics.dtx
new file mode 100644
index 0000000000..eabf678caa
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3basics.dtx
@@ -0,0 +1,3507 @@
+% \iffalse meta-comment
+%
+%% File: l3basics.dtx
+%
+% Copyright (C) 1990-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3basics} module\\ Basic definitions^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% As the name suggests, this module holds some basic definitions which
+% are needed by most or all other modules in this set.
+%
+% Here we describe those functions that are used all over the place.
+% By that, we mean functions dealing with the construction and testing of
+% control sequences. Furthermore the basic parts of conditional
+% processing are covered; conditional processing dealing with specific
+% data types is described in the modules specific for the respective
+% data types.
+%
+% \section{No operation functions}
+%
+% \begin{function}[EXP]{\prg_do_nothing:}
+% \begin{syntax}
+% \cs{prg_do_nothing:}
+% \end{syntax}
+% An expandable function which does nothing at all: leaves nothing
+% in the input stream after a single expansion.
+% \end{function}
+%
+% \begin{function}{\scan_stop:}
+% \begin{syntax}
+% \cs{scan_stop:}
+% \end{syntax}
+% A non-expandable function which does nothing. Does not vanish on
+% expansion but produces no typeset output.
+% \end{function}
+%
+% \section{Grouping material}
+%
+% \begin{function}{\group_begin:, \group_end:}
+% \begin{syntax}
+% \cs{group_begin:}
+% \cs{group_end:}
+% \end{syntax}
+% These functions begin and end a group for definition purposes.
+% Assignments are local to groups unless carried out in a global
+% manner. (A small number of exceptions to this rule will be noted
+% as necessary elsewhere in this document.) Each \cs{group_begin:}
+% must be matched by a \cs{group_end:}, although this does not have
+% to occur within the same function. Indeed, it is often necessary
+% to start a group within one function and finish it within another,
+% for example when seeking to use non-standard category codes.
+% \begin{texnote}
+% These are the \TeX{} primitives \tn{begingroup} and \tn{endgroup}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\group_insert_after:N}
+% \begin{syntax}
+% \cs{group_insert_after:N} \meta{token}
+% \end{syntax}
+% Adds \meta{token} to the list of \meta{tokens} to be inserted
+% when the current group level ends. The list of \meta{tokens} to be
+% inserted is empty at the beginning of a group: multiple
+% applications of \cs{group_insert_after:N} may be used to build
+% the inserted list one \meta{token} at a time. The current group
+% level may be closed by a \cs{group_end:} function or by a token
+% with category code $2$ (close-group), namely a ^^A{
+% |}| if standard category codes apply.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{aftergroup}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2021-05-11]{\group_show_list:, \group_log_list:}
+% \begin{syntax}
+% \cs{group_show_list:}
+% \cs{group_log_list:}
+% \end{syntax}
+% Display (to the terminal or log file) a list of the groups that are
+% currently opened. This is intended for tracking down problems.
+% \begin{texnote}
+% This is a wrapper around the \eTeX{} primitive \tn{showgroups}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Control sequences and functions}
+%
+% As \TeX{} is a macro language, creating new functions means
+% creating macros. At point of use, a function is replaced by
+% the replacement text (\enquote{code}) in which each parameter
+% in the code (|#1|, |#2|, \emph{etc.}) is replaced the appropriate
+% arguments absorbed by the function. In the following, \meta{code}
+% is therefore used as a shorthand for \enquote{replacement text}.
+%
+% Functions which are not \enquote{protected} are fully expanded
+% inside an \texttt{e}-type or \texttt{x}-type expansion.
+% In contrast, \enquote{protected} functions are not expanded within
+% \texttt{e} and \texttt{x} expansions.
+%
+% \subsection{Defining functions}
+%
+% Functions can be created with no requirement that they are declared
+% first (in contrast to variables, which must always be declared).
+% Declaring a function before setting up the code means that the name
+% chosen is checked and an error raised if it is already in use.
+% The name of a function can be checked at the point of definition using
+% the \cs[no-index]{cs_new\ldots} functions: this is recommended for all
+% functions which are defined for the first time.
+%
+% There are three ways to define new functions.
+% All classes define a function to expand to the substitution text.
+% Within the substitution text the actual parameters are substituted
+% for the formal parameters (|#1|, |#2|, \ldots).
+% \begin{description}
+% \item[\texttt{new}]
+% Create a new function with the \texttt{new} scope,
+% such as \cs{cs_new:Npn}. The definition is global and results in
+% an error if it is already defined.
+% \item[\texttt{set}]
+% Create a new function with the \texttt{set} scope,
+% such as \cs{cs_set:Npn}. The definition is restricted to the current
+% \TeX{} group and does not result in an error if the function is already
+% defined.
+% \item[\texttt{gset}]
+% Create a new function with the \texttt{gset} scope,
+% such as \cs{cs_gset:Npn}. The definition is global and
+% does not result in an error if the function is already defined.
+% \end{description}
+%
+% Within each set of scope there are different ways to define a function.
+% The differences depend on restrictions on the actual parameters and
+% the expandability of the resulting function.
+% \begin{description}
+% \item[\texttt{nopar}]
+% Create a new function with the \texttt{nopar} restriction,
+% such as \cs{cs_set_nopar:Npn}. The parameter may not contain
+% \cs{par} tokens.
+% \item[\texttt{protected}]
+% Create a new function with the \texttt{protected} restriction,
+% such as \cs{cs_set_protected:Npn}. The parameter may contain
+% \cs{par} tokens but the function will not expand within an
+% \texttt{e}-type or \texttt{x}-type expansion.
+% \end{description}
+%
+% Finally, the functions in
+% Subsections~\ref{sec:l3basics:defining-new-function-1}~and
+% \ref{sec:l3basics:defining-new-function-2} are primarily meant to define
+% \emph{base functions} only. Base functions can only have the following
+% argument specifiers:
+% \begin{description}
+% \item[|N| and |n|] No manipulation.
+% \item[|T| and |F|] Functionally equivalent to |n| (you are actually
+% encouraged to use the family of |\prg_new_conditional:| functions
+% described in Section~\ref{sec:l3prg:new-conditional-functions}).
+% \item[|p| and |w|] These are special cases.
+% \end{description}
+%
+% The |\cs_new:| functions below (and friends) do not stop you from using
+% other argument specifiers in your function names, but they do not handle
+% expansion for you. You should define the base function and then use
+% \cs{cs_generate_variant:Nn} to generate custom variants as described in
+% Section~\ref{sec:l3expan:variants-method}.
+%
+% \subsection{Defining new functions using parameter text}
+% \label{sec:l3basics:defining-new-function-1}
+%
+% \begin{function}
+% {
+% \cs_new:Npn, \cs_new:cpn,
+% \cs_new:Npe, \cs_new:cpe,
+% \cs_new:Npx, \cs_new:cpx
+% }
+% \begin{syntax}
+% \cs{cs_new:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% The definition is global and an error results if the
+% \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_new_nopar:Npn, \cs_new_nopar:cpn,
+% \cs_new_nopar:Npe, \cs_new_nopar:cpe,
+% \cs_new_nopar:Npx, \cs_new_nopar:cpx
+% }
+% \begin{syntax}
+% \cs{cs_new_nopar:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% When the \meta{function} is used the \meta{parameters} absorbed
+% cannot contain \cs{par} tokens. The definition is global and
+% an error results if the \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_new_protected:Npn, \cs_new_protected:cpn,
+% \cs_new_protected:Npe, \cs_new_protected:cpe,
+% \cs_new_protected:Npx, \cs_new_protected:cpx
+% }
+% \begin{syntax}
+% \cs{cs_new_protected:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% The \meta{function} will not expand within an \texttt{e}-type or
+% or \texttt{x}-type
+% argument. The definition is global and an error results if the
+% \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_new_protected_nopar:Npn, \cs_new_protected_nopar:cpn ,
+% \cs_new_protected_nopar:Npe, \cs_new_protected_nopar:cpe ,
+% \cs_new_protected_nopar:Npx, \cs_new_protected_nopar:cpx
+% }
+% \begin{syntax}
+% \cs{cs_new_protected_nopar:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% When the \meta{function} is used the \meta{parameters} absorbed
+% cannot contain \cs{par} tokens. The \meta{function} will not
+% expand within an \texttt{e}-type or \texttt{x}-type argument. The definition is global
+% and an error results if the \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set:Npn, \cs_set:cpn,
+% \cs_set:Npe, \cs_set:cpe,
+% \cs_set:Npx, \cs_set:cpx
+% }
+% \begin{syntax}
+% \cs{cs_set:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% The assignment of a meaning to the \meta{function} is restricted to
+% the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set_nopar:Npn, \cs_set_nopar:cpn,
+% \cs_set_nopar:Npe, \cs_set_nopar:cpe,
+% \cs_set_nopar:Npx, \cs_set_nopar:cpx
+% }
+% \begin{syntax}
+% \cs{cs_set_nopar:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% When the \meta{function} is used the \meta{parameters} absorbed
+% cannot contain \cs{par} tokens. The assignment of a meaning
+% to the \meta{function} is restricted to the current \TeX{} group
+% level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set_protected:Npn, \cs_set_protected:cpn,
+% \cs_set_protected:Npe, \cs_set_protected:cpe,
+% \cs_set_protected:Npx, \cs_set_protected:cpx
+% }
+% \begin{syntax}
+% \cs{cs_set_protected:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% The assignment of a meaning to the \meta{function} is restricted to
+% the current \TeX{} group level. The \meta{function} will
+% not expand within an \texttt{e}-type or \texttt{x}-type argument.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set_protected_nopar:Npn, \cs_set_protected_nopar:cpn ,
+% \cs_set_protected_nopar:Npe, \cs_set_protected_nopar:cpe ,
+% \cs_set_protected_nopar:Npx, \cs_set_protected_nopar:cpx ,
+% }
+% \begin{syntax}
+% \cs{cs_set_protected_nopar:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% When the \meta{function} is used the \meta{parameters} absorbed
+% cannot contain \cs{par} tokens. The assignment of a meaning
+% to the \meta{function} is restricted to the current \TeX{} group
+% level. The \meta{function} will not expand within an
+% \texttt{e}-type or \texttt{x}-type argument.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset:Npn, \cs_gset:cpn,
+% \cs_gset:Npe, \cs_gset:cpe,
+% \cs_gset:Npx, \cs_gset:cpx
+% }
+% \begin{syntax}
+% \cs{cs_gset:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Globally sets \meta{function} to expand to \meta{code} as replacement
+% text. Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% The assignment of a meaning to the \meta{function} is \emph{not}
+% restricted to the current \TeX{} group level: the assignment is
+% global.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset_nopar:Npn, \cs_gset_nopar:cpn,
+% \cs_gset_nopar:Npe, \cs_gset_nopar:cpe,
+% \cs_gset_nopar:Npx, \cs_gset_nopar:cpx
+% }
+% \begin{syntax}
+% \cs{cs_gset_nopar:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Globally sets \meta{function} to expand to \meta{code} as replacement
+% text. Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% When the \meta{function} is used the \meta{parameters} absorbed
+% cannot contain \cs{par} tokens. The assignment of a meaning to the
+% \meta{function} is \emph{not} restricted to the current \TeX{}
+% group level: the assignment is global.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset_protected:Npn, \cs_gset_protected:cpn,
+% \cs_gset_protected:Npe, \cs_gset_protected:cpe,
+% \cs_gset_protected:Npx, \cs_gset_protected:cpx
+% }
+% \begin{syntax}
+% \cs{cs_gset_protected:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Globally sets \meta{function} to expand to \meta{code} as replacement
+% text. Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% The assignment of a meaning to the \meta{function} is \emph{not}
+% restricted to the current \TeX{} group level: the assignment is
+% global. The \meta{function} will not expand within an
+% \texttt{e}-type or \texttt{x}-type argument.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset_protected_nopar:Npn, \cs_gset_protected_nopar:cpn,
+% \cs_gset_protected_nopar:Npe, \cs_gset_protected_nopar:cpe,
+% \cs_gset_protected_nopar:Npx, \cs_gset_protected_nopar:cpx
+% }
+% \begin{syntax}
+% \cs{cs_gset_protected_nopar:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Globally sets \meta{function} to expand to \meta{code} as replacement
+% text. Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% When the \meta{function} is used the \meta{parameters} absorbed
+% cannot contain \cs{par} tokens. The assignment of a meaning to the
+% \meta{function} is \emph{not} restricted to the current \TeX{}
+% group level: the assignment is global. The \meta{function} will
+% not expand within an \texttt{e}-type or \texttt{x}-type argument.
+% \end{function}
+%
+% \subsection{Defining new functions using the signature}
+% \label{sec:l3basics:defining-new-function-2}
+%
+% \begin{function}
+% {
+% \cs_new:Nn, \cs_new:cn,
+% \cs_new:Ne, \cs_new:ce
+% }
+% \begin{syntax}
+% \cs{cs_new:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. The definition is global and
+% an error results if the \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_new_nopar:Nn, \cs_new_nopar:cn,
+% \cs_new_nopar:Ne, \cs_new_nopar:ce
+% }
+% \begin{syntax}
+% \cs{cs_new_nopar:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. When the \meta{function} is used the \meta{parameters}
+% absorbed cannot contain \cs{par} tokens. The definition is global and
+% an error results if the \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_new_protected:Nn, \cs_new_protected:cn,
+% \cs_new_protected:Ne, \cs_new_protected:ce
+% }
+% \begin{syntax}
+% \cs{cs_new_protected:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. The \meta{function} will not expand within an \texttt{e}-type
+% or \texttt{x}-type argument. The definition is global and
+% an error results if the \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_new_protected_nopar:Nn, \cs_new_protected_nopar:cn,
+% \cs_new_protected_nopar:Ne, \cs_new_protected_nopar:ce
+% }
+% \begin{syntax}
+% \cs{cs_new_protected_nopar:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. When the \meta{function} is used the \meta{parameters}
+% absorbed cannot contain \cs{par} tokens. The \meta{function} will not
+% expand within an \texttt{e}-type or \texttt{x}-type argument. The definition is global and
+% an error results if the \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set:Nn, \cs_set:cn,
+% \cs_set:Ne, \cs_set:ce
+% }
+% \begin{syntax}
+% \cs{cs_set:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function.
+% The assignment of a meaning to the \meta{function} is restricted to
+% the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set_nopar:Nn, \cs_set_nopar:cn,
+% \cs_set_nopar:Ne, \cs_set_nopar:ce
+% }
+% \begin{syntax}
+% \cs{cs_set_nopar:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. When the \meta{function} is used the \meta{parameters}
+% absorbed cannot contain \cs{par} tokens.
+% The assignment of a meaning to the \meta{function} is restricted to
+% the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set_protected:Nn, \cs_set_protected:cn,
+% \cs_set_protected:Ne, \cs_set_protected:ce
+% }
+% \begin{syntax}
+% \cs{cs_set_protected:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. The \meta{function} will not expand within an \texttt{e}-type
+% or \texttt{x}-type argument.
+% The assignment of a meaning to the \meta{function} is restricted to
+% the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set_protected_nopar:Nn, \cs_set_protected_nopar:cn,
+% \cs_set_protected_nopar:Ne, \cs_set_protected_nopar:ce
+% }
+% \begin{syntax}
+% \cs{cs_set_protected_nopar:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. When the \meta{function} is used the \meta{parameters}
+% absorbed cannot contain \cs{par} tokens. The \meta{function} will not
+% expand within an \texttt{e}-type or \texttt{x}-type argument.
+% The assignment of a meaning to the \meta{function} is restricted to
+% the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset:Nn, \cs_gset:cn,
+% \cs_gset:Ne, \cs_gset:ce
+% }
+% \begin{syntax}
+% \cs{cs_gset:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function.
+% The assignment of a meaning to the \meta{function} is global.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset_nopar:Nn, \cs_gset_nopar:cn,
+% \cs_gset_nopar:Ne, \cs_gset_nopar:ce
+% }
+% \begin{syntax}
+% \cs{cs_gset_nopar:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. When the \meta{function} is used the \meta{parameters}
+% absorbed cannot contain \cs{par} tokens.
+% The assignment of a meaning to the \meta{function} is global.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset_protected:Nn, \cs_gset_protected:cn,
+% \cs_gset_protected:Ne, \cs_gset_protected:ce
+% }
+% \begin{syntax}
+% \cs{cs_gset_protected:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. The \meta{function} will not expand within an \texttt{e}-type
+% or \texttt{x}-type argument.
+% The assignment of a meaning to the \meta{function} is global.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset_protected_nopar:Nn, \cs_gset_protected_nopar:cn,
+% \cs_gset_protected_nopar:Ne, \cs_gset_protected_nopar:ce
+% }
+% \begin{syntax}
+% \cs{cs_gset_protected_nopar:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. When the \meta{function} is used the \meta{parameters}
+% absorbed cannot contain \cs{par} tokens. The \meta{function} will not
+% expand within an \texttt{e}-type or \texttt{x}-type argument.
+% The assignment of a meaning to the \meta{function} is global.
+% \end{function}
+%
+% \begin{function}[updated = 2012-01-14]
+% {
+% \cs_generate_from_arg_count:NNnn,
+% \cs_generate_from_arg_count:NNno,
+% \cs_generate_from_arg_count:cNnn,
+% \cs_generate_from_arg_count:Ncnn
+% }
+% \begin{syntax}
+% \cs{cs_generate_from_arg_count:NNnn} \meta{function} \meta{creator} \Arg{number} \Arg{code}
+% \end{syntax}
+% Uses the \meta{creator} function (which should have signature
+% |Npn|, for example \cs{cs_new:Npn}) to define a \meta{function}
+% which takes \meta{number} arguments and has \meta{code} as
+% replacement text. The \meta{number} of arguments is an integer expression,
+% evaluated as detailed for \cs{int_eval:n}.
+% \end{function}
+%
+% \subsection{Copying control sequences}
+%
+% Control sequences (not just functions as defined above) can
+% be set to have the same meaning using the functions described
+% here. Making two control sequences equivalent means that the
+% second control sequence is a \emph{copy} of the first (rather than
+% a pointer to it). Thus the old and new control sequence are not
+% tied together: changes to one are not reflected in the other.
+%
+% In the following text \enquote{cs} is used as an abbreviation for
+% \enquote{control sequence}.
+%
+% \begin{function}
+% {\cs_new_eq:NN, \cs_new_eq:Nc, \cs_new_eq:cN, \cs_new_eq:cc}
+% \begin{syntax}
+% \cs{cs_new_eq:NN} \meta{cs_1} \meta{cs_2}
+% \cs{cs_new_eq:NN} \meta{cs_1} \meta{token}
+% \end{syntax}
+% Globally creates \meta{control sequence_1} and sets it to have the same
+% meaning as \meta{control sequence_2} or <token>.
+% The second control sequence may
+% subsequently be altered without affecting the copy.
+% \end{function}
+%
+% \begin{function}
+% {\cs_set_eq:NN, \cs_set_eq:Nc, \cs_set_eq:cN, \cs_set_eq:cc}
+% \begin{syntax}
+% \cs{cs_set_eq:NN} \meta{cs_1} \meta{cs_2}
+% \cs{cs_set_eq:NN} \meta{cs_1} \meta{token}
+% \end{syntax}
+% Sets \meta{control sequence_1} to have the same meaning as
+% \meta{control sequence_2} (or <token>).
+% The second control sequence may subsequently be
+% altered without affecting the copy. The assignment of a meaning
+% to the \meta{control sequence_1} is restricted to the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {\cs_gset_eq:NN, \cs_gset_eq:Nc, \cs_gset_eq:cN, \cs_gset_eq:cc}
+% \begin{syntax}
+% \cs{cs_gset_eq:NN} \meta{cs_1} \meta{cs_2}
+% \cs{cs_gset_eq:NN} \meta{cs_1} \meta{token}
+% \end{syntax}
+% Globally sets \meta{control sequence_1} to have the same meaning as
+% \meta{control sequence_2} (or <token>).
+% The second control sequence may subsequently be
+% altered without affecting the copy. The assignment of a meaning to
+% the \meta{control sequence_1} is \emph{not} restricted to the current
+% \TeX{} group level: the assignment is global.
+% \end{function}
+%
+% \subsection{Deleting control sequences}
+%
+% There are occasions where control sequences need to be deleted.
+% This is handled in a very simple manner.
+%
+% \begin{function}[updated = 2011-09-15]{\cs_undefine:N, \cs_undefine:c}
+% \begin{syntax}
+% \cs{cs_undefine:N} \meta{control sequence}
+% \end{syntax}
+% Sets \meta{control sequence} to be globally undefined.
+% \end{function}
+%
+% \subsection{Showing control sequences}
+%
+% \begin{function}[EXP, updated = 2011-12-22]{\cs_meaning:N, \cs_meaning:c}
+% \begin{syntax}
+% \cs{cs_meaning:N} \meta{control sequence}
+% \end{syntax}
+% This function expands to the \emph{meaning} of the \meta{control sequence}
+% control sequence. For a macro, this includes the \meta{replacement text}.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{meaning}.
+% For tokens that are not control sequences, it is more logical to
+% use \cs{token_to_meaning:N}.
+% The \texttt{c} variant correctly reports undefined arguments.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[updated = 2017-02-14]{\cs_show:N, \cs_show:c}
+% \begin{syntax}
+% \cs{cs_show:N} \meta{control sequence}
+% \end{syntax}
+% Displays the definition of the \meta{control sequence} on the
+% terminal.
+% \begin{texnote}
+% This is similar to the \TeX{} primitive \tn{show}, wrapped to a
+% fixed number of characters per line.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2017-02-14]{\cs_log:N, \cs_log:c}
+% \begin{syntax}
+% \cs{cs_log:N} \meta{control sequence}
+% \end{syntax}
+% Writes the definition of the \meta{control sequence} in the log
+% file. See also \cs{cs_show:N} which displays the result in the
+% terminal.
+% \end{function}
+%
+% \subsection{Converting to and from control sequences}
+%
+% \begin{function}[EXP]{\use:c}
+% \begin{syntax}
+% \cs{use:c} \Arg{control sequence name}
+% \end{syntax}
+% Expands the \meta{control sequence name} until only characters
+% remain, and then converts this into a control sequence. This process
+% requires two expansions. As in other \texttt{c}-type arguments the
+% \meta{control sequence name} must, when fully expanded, consist of
+% character tokens, typically a mixture of category code $10$ (space),
+% $11$ (letter) and $12$ (other).
+% \end{function}
+%
+% As an example of the \cs{use:c} function, both
+% \begin{verbatim}
+% \use:c { a b c }
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% \tl_new:N \l_my_tl
+% \tl_set:Nn \l_my_tl { a b c }
+% \use:c { \tl_use:N \l_my_tl }
+% \end{verbatim}
+% would be equivalent to
+% \begin{verbatim}
+% \abc
+% \end{verbatim}
+% after two expansions of \cs{use:c}.
+%
+% \begin{function}[noTF, EXP, added = 2012-11-10]
+% {\cs_if_exist_use:N, \cs_if_exist_use:c}
+% \begin{syntax}
+% \cs{cs_if_exist_use:N} \meta{control sequence}
+% \cs{cs_if_exist_use:NTF} \meta{control sequence} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{control sequence} is currently defined
+% according to the conditional \cs{cs_if_exist:NTF}
+% (whether as a function or another control sequence type), and if it
+% is inserts the \meta{control sequence} into the input stream followed
+% by the \meta{true code}. Otherwise the \meta{false code} is used.
+% \end{function}
+%
+% \begin{function}[EXP]{\cs:w, \cs_end:}
+% \begin{syntax}
+% \cs{cs:w} \meta{control sequence name} \cs{cs_end:}
+% \end{syntax}
+% Converts the given \meta{control sequence name} into a single
+% control sequence token. This process requires one expansion.
+% The content for \meta{control sequence name} may be literal
+% material or from other expandable functions. The
+% \meta{control sequence name} must, when fully expanded, consist
+% of character tokens which are not active: typically
+% of category code $10$ (space), $11$ (letter)
+% or $12$ (other), or a mixture of these.
+% \begin{texnote}
+% These are the \TeX{} primitives \tn{csname} and \tn{endcsname}.
+% \end{texnote}
+% \end{function}
+%
+% As an example of the \cs{cs:w} and \cs{cs_end:} functions, both
+% \begin{verbatim}
+% \cs:w a b c \cs_end:
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% \tl_new:N \l_my_tl
+% \tl_set:Nn \l_my_tl { a b c }
+% \cs:w \tl_use:N \l_my_tl \cs_end:
+% \end{verbatim}
+% would be equivalent to
+% \begin{verbatim}
+% \abc
+% \end{verbatim}
+% after one expansion of \cs{cs:w}.
+%
+% \begin{function}[EXP]{\cs_to_str:N}
+% \begin{syntax}
+% \cs{cs_to_str:N} \meta{control sequence}
+% \end{syntax}
+% Converts the given \meta{control sequence} into a series of
+% characters with category code $12$ (other), except spaces,
+% of category code $10$. The result does \emph{not} include
+% the current escape token, contrarily to \cs{token_to_str:N}.
+% Full expansion of this function requires exactly $2$ expansion
+% steps, and so an \texttt{e}-type or \texttt{x}-type expansion, or two
+% \texttt{o}-type expansions are required to
+% convert the \meta{control sequence} to a sequence of characters
+% in the input stream. In most cases, an \texttt{f}-expansion
+% is correct as well, but this loses a space at the start
+% of the result.
+% \end{function}
+%
+% \section{Analysing control sequences}
+%
+% \begin{function}[EXP, added = 2018-04-06]{\cs_split_function:N}
+% \begin{syntax}
+% \cs{cs_split_function:N} \meta{function}
+% \end{syntax}
+% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part
+% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon).
+% This information is then placed in the input stream
+% in three parts: the \meta{name}, the
+% \meta{signature} and a logic token indicating if a colon was found
+% (to differentiate variables from function names). The \meta{name}
+% does not include the escape character, and both the \meta{name} and
+% \meta{signature} are made up of tokens with category code $12$
+% (other).
+% \end{function}
+%
+% The next three functions decompose \TeX{} macros into their
+% constituent parts: if the \meta{token} passed is not a macro then no
+% decomposition can occur. In the latter case, all three functions leave
+% \cs{scan_stop:} in the input stream.
+%
+% \begin{function}[EXP, added = 2019-02-27]{\cs_prefix_spec:N}
+% \begin{syntax}
+% \cs{cs_prefix_spec:N} \meta{token}
+% \end{syntax}
+% If the \meta{token} is a macro, this function leaves the applicable
+% \TeX{} prefixes in input stream as a string of tokens of category
+% code $12$ (with spaces having category code $10$). Thus for example
+% \begin{verbatim}
+% \cs_set:Npn \next:nn #1#2 { x #1~y #2 }
+% \cs_prefix_spec:N \next:nn
+% \end{verbatim}
+% leaves |\long| in the input stream. If the \meta{token} is
+% not a macro then \cs{scan_stop:} is left in the input stream.
+% \begin{texnote}
+% The prefix can be empty, |\long|, |\protected| or
+% |\protected\long| with backslash replaced by the current escape
+% character.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2022-06-24]{\cs_parameter_spec:N}
+% \begin{syntax}
+% \cs{cs_parameter_spec:N} \meta{token}
+% \end{syntax}
+% If the \meta{token} is a macro, this function leaves the primitive
+% \TeX{} parameter specification in input stream as a string of
+% character tokens of category code $12$ (with spaces having category
+% code $10$). Thus for example
+% \begin{verbatim}
+% \cs_set:Npn \next:nn #1#2 { x #1 y #2 }
+% \cs_parameter_spec:N \next:nn
+% \end{verbatim}
+% leaves |#1#2| in the input stream. If the \meta{token} is
+% not a macro then \cs{scan_stop:} is left in the input stream.
+% \begin{texnote}
+% If the parameter specification contains the string |->|, then the
+% function produces incorrect results.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2019-02-27]{\cs_replacement_spec:N, \cs_replacement_spec:c}
+% \begin{syntax}
+% \cs{cs_replacement_spec:N} \meta{token}
+% \end{syntax}
+% If the \meta{token} is a macro, this function leaves the replacement
+% text in input stream as a string of character tokens of category
+% code $12$ (with spaces having category code $10$). Thus for example
+% \begin{verbatim}
+% \cs_set:Npn \next:nn #1#2 { x #1~y #2 }
+% \cs_replacement_spec:N \next:nn
+% \end{verbatim}
+% leaves \verb*|x#1 y#2| in the input stream. If the \meta{token} is
+% not a macro then \cs{scan_stop:} is left in the input stream.
+% \begin{texnote}
+% If the parameter specification contains the string |->|, then the
+% function produces incorrect results.
+% \end{texnote}
+% \end{function}
+%
+% \section{Using or removing tokens and arguments}
+%
+% Tokens in the input can be read and used or read and discarded.
+% If one or more tokens are wrapped in braces then when absorbing them
+% the outer set is removed. At the same time, the category code
+% of each token is set when the token is read by a function (if it
+% is read more than once, the category code is determined by
+% the situation in force when first function absorbs the token).
+%
+% \begin{function}[EXP]{\use:n, \use:nn, \use:nnn, \use:nnnn}
+% \begin{syntax}
+% \cs{use:n} \Arg{group_1}
+% \cs{use:nn} \Arg{group_1} \Arg{group_2}
+% \cs{use:nnn} \Arg{group_1} \Arg{group_2} \Arg{group_3}
+% \cs{use:nnnn} \Arg{group_1} \Arg{group_2} \Arg{group_3} \Arg{group_4}
+% \end{syntax}
+% As illustrated, these functions absorb between one and four
+% arguments, as indicated by the argument specifier. The braces
+% surrounding each argument are removed and the remaining tokens are
+% left in the input stream. The category code of these tokens is
+% also fixed by this process (if it has not already been by some
+% other absorption). All of these functions require only a single
+% expansion to operate, so that one expansion of
+% \begin{verbatim}
+% \use:nn { abc } { { def } }
+% \end{verbatim}
+% results in the input stream containing
+% \begin{verbatim}
+% abc { def }
+% \end{verbatim}
+% \emph{i.e.} only the outer braces are removed.
+% \begin{texnote}
+% The \cs{use:n} function is equivalent to \LaTeXe{}'s \tn{@firstofone}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]
+% {
+% \use_i:nn, \use_ii:nn ,
+% \use_i:nnn , \use_ii:nnn , \use_iii:nnn ,
+% \use_i:nnnn, \use_ii:nnnn, \use_iii:nnnn, \use_iv:nnnn ,
+% \use_i:nnnnn, \use_ii:nnnnn, \use_iii:nnnnn, \use_iv:nnnnn ,
+% \use_v:nnnnn ,
+% \use_i:nnnnnn, \use_ii:nnnnnn, \use_iii:nnnnnn, \use_iv:nnnnnn ,
+% \use_v:nnnnnn , \use_vi:nnnnnn ,
+% \use_i:nnnnnnn, \use_ii:nnnnnnn, \use_iii:nnnnnnn, \use_iv:nnnnnnn ,
+% \use_v:nnnnnnn , \use_vi:nnnnnnn , \use_vii:nnnnnnn ,
+% \use_i:nnnnnnnn, \use_ii:nnnnnnnn, \use_iii:nnnnnnnn, \use_iv:nnnnnnnn ,
+% \use_v:nnnnnnnn , \use_vi:nnnnnnnn , \use_vii:nnnnnnnn , \use_viii:nnnnnnnn ,
+% \use_i:nnnnnnnnn, \use_ii:nnnnnnnnn, \use_iii:nnnnnnnnn, \use_iv:nnnnnnnnn ,
+% \use_v:nnnnnnnnn , \use_vi:nnnnnnnnn , \use_vii:nnnnnnnnn , \use_viii:nnnnnnnnn ,
+% \use_ix:nnnnnnnnn
+% }
+% \begin{syntax}
+% \cs{use_i:nn} \Arg{arg_1} \Arg{arg_2}
+% \cs{use_i:nnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3}
+% \cs{use_i:nnnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{arg_4}
+% \cs{use_i:nnnnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{arg_4} \Arg{arg_5}
+% \cs{use_i:nnnnnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{arg_4} \Arg{arg_5} \Arg{arg_6}
+% \cs{use_i:nnnnnnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{arg_4} \Arg{arg_5} \Arg{arg_6} \Arg{arg_7}
+% \cs{use_i:nnnnnnnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{arg_4} \Arg{arg_5} \Arg{arg_6} \Arg{arg_7} \Arg{arg_8}
+% \cs{use_i:nnnnnnnnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{arg_4} \Arg{arg_5} \Arg{arg_6} \Arg{arg_7} \Arg{arg_8} \Arg{arg_9}
+% \end{syntax}
+% These functions absorb a number ($n$) arguments from the input stream.
+% They then discard all arguments other than that indicated by the roman
+% numeral, which is left in the input stream. For example, \cs{use_i:nn}
+% discards the second argument, and leaves the content of the first
+% argument in the input stream.
+% The category code
+% of these tokens is also fixed (if it has not already been by
+% some other absorption). A single expansion is needed for the
+% functions to take effect.
+% \end{function}
+%
+% \begin{function}[EXP]{\use_i_ii:nnn}
+% \begin{syntax}
+% \cs{use_i_ii:nnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3}
+% \end{syntax}
+% This function absorbs three arguments and leaves the content of the
+% first and second in the input stream. The category code of
+% these tokens is also fixed (if it has not already been by
+% some other absorption). A single expansion is needed for the
+% function to take effect. An example:
+% \begin{verbatim}
+% \use_i_ii:nnn { abc } { { def } } { ghi }
+% \end{verbatim}
+% results in the input stream containing
+% \begin{verbatim}
+% abc { def }
+% \end{verbatim}
+% \emph{i.e.} the outer braces are removed and the third group
+% is removed.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2019-06-02]{\use_ii_i:nn}
+% \begin{syntax}
+% \cs{use_ii_i:nn} \Arg{arg_1} \Arg{arg_2}
+% \end{syntax}
+% This function absorbs two arguments and leaves the content of the
+% second and first in the input stream. The category code of
+% these tokens is also fixed (if it has not already been by
+% some other absorption). A single expansion is needed for the
+% function to take effect.
+% \end{function}
+%
+% \begin{function}[EXP]
+% {
+% \use_none:n ,
+% \use_none:nn ,
+% \use_none:nnn ,
+% \use_none:nnnn ,
+% \use_none:nnnnn ,
+% \use_none:nnnnnn ,
+% \use_none:nnnnnnn ,
+% \use_none:nnnnnnnn ,
+% \use_none:nnnnnnnnn
+% }
+% \begin{syntax}
+% \cs{use_none:n} \Arg{group_1}
+% \end{syntax}
+% These functions absorb between one and nine groups from the
+% input stream, leaving nothing on the resulting input stream.
+% These functions work after a single expansion. One or more of the
+% \texttt{n} arguments may be an unbraced single token
+% (\emph{i.e.}~an \texttt{N} argument).
+% \begin{texnote}
+% These are equivalent to \LaTeXe{}'s \tn{@gobble}, \tn{@gobbletwo},
+% \emph{etc.}
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2018-06-18, updated = 2023-07-05]{\use:e}
+% \begin{syntax}
+% \cs{use:e} \Arg{expandable tokens}
+% \end{syntax}
+% Fully expands the \meta{token list} in an \texttt{e}-type manner,
+% in which parameter character (usually~|#|) need not be doubled, \emph{and}
+% the function remains fully expandable.
+% \begin{texnote}
+% \cs{use:e} is a wrapper around the primitive \tn{expanded}.
+% It requires two expansions to complete its action.
+% \end{texnote}
+% \end{function}
+%
+% \subsection{Selecting tokens from delimited arguments}
+%
+% A different kind of function for selecting tokens from the token
+% stream are those that use delimited arguments.
+%
+% \begin{function}[EXP]
+% {
+% \use_none_delimit_by_q_nil:w,
+% \use_none_delimit_by_q_stop:w,
+% \use_none_delimit_by_q_recursion_stop:w
+% }
+% \begin{syntax}
+% \cs{use_none_delimit_by_q_nil:w} \meta{balanced text} \cs{q_nil}
+% \cs{use_none_delimit_by_q_stop:w} \meta{balanced text} \cs{q_stop}
+% \cs{use_none_delimit_by_q_recursion_stop:w} \meta{balanced text} \cs{q_recursion_stop}
+% \end{syntax}
+% Absorb the \meta{balanced text} from the input stream delimited by
+% the marker given in the function name, leaving nothing in the
+% input stream.
+% \end{function}
+%
+% \begin{function}[EXP]
+% {
+% \use_i_delimit_by_q_nil:nw,
+% \use_i_delimit_by_q_stop:nw,
+% \use_i_delimit_by_q_recursion_stop:nw
+% }
+% \begin{syntax}
+% \cs{use_i_delimit_by_q_nil:nw} \Arg{inserted tokens} \meta{balanced text} \cs{q_nil}
+% \cs{use_i_delimit_by_q_stop:nw} \Arg{inserted tokens} \meta{balanced text} \cs{q_stop}
+% \cs{use_i_delimit_by_q_recursion_stop:nw} \Arg{inserted tokens} \meta{balanced text} \cs{q_recursion_stop}
+% \end{syntax}
+% Absorb the \meta{balanced text} from the input stream delimited by
+% the marker given in the function name, leaving \meta{inserted tokens}
+% in the input stream for further processing.
+% \end{function}
+%
+% \section{Predicates and conditionals}
+%
+% \LaTeX3 has three concepts for conditional flow processing:
+% \begin{description}
+% \item[Branching conditionals]
+% Functions that carry out a test and then execute, depending on its
+% result, either the code supplied as the \meta{true code} or the
+% \meta{false code}.
+% These arguments are denoted with |T| and |F|, respectively. An
+% example would be
+% \begin{quote}
+% |\cs_if_free:cTF {abc}| \Arg{true code} \Arg{false code}
+% \end{quote}
+% a function that turns the first argument into a control sequence
+% (since it's marked as |c|) then checks whether this control sequence
+% is still free and then depending on the result carries out the code in
+% the second argument (true case) or in the third argument (false
+% case).
+%
+% These type of functions are known as \enquote{conditionals};
+% whenever a |TF| function is defined it is usually accompanied by
+% |T| and |F| functions as well. These are provided for convenience when
+% the branch only needs to go a single way. Package writers are free to
+% choose which types to define but the kernel definitions always
+% provide all three versions.
+%
+% Important to note is that these branching conditionals with \meta{true
+% code} and/or \meta{false code} are always defined in a way that the
+% code of the chosen alternative can operate on following tokens in
+% the input stream.
+%
+% These conditional functions may or may not be fully expandable, but if
+% they are expandable they are accompanied by a \enquote{predicate}
+% for the same test as described below.
+%
+% \item[Predicates]
+% \enquote{Predicates} are functions that return a special type of
+% boolean value which can be tested by the boolean expression parser.
+% All functions of this type
+% are expandable and have names that end with |_p| in the
+% description part. For example,
+% \begin{quote}
+% \cs{cs_if_free_p:N}
+% \end{quote}
+% would be a predicate function for the same type of test as the
+% conditional described above. It would return \enquote{true} if its
+% argument (a single token denoted by |N|) is still free for definition.
+% It would be used in constructions like
+% \begin{quote}
+% |\bool_if:nTF {| \\
+% \verb" \cs_if_free_p:N \l_tmpz_tl || \cs_if_free_p:N \g_tmpz_tl " \\
+% |}|
+% \Arg{true code} \Arg{false code}
+% \end{quote}
+%
+% For each predicate defined, a \enquote{branching conditional}
+% also exists that behaves like a conditional described above.
+%
+% \item[Primitive conditionals]
+% There is a third variety of conditional, which is the original
+% concept used in plain \TeX{} and \LaTeXe{}. Their use is discouraged
+% in \pkg{expl3} (although still used in low-level definitions)
+% because they are more fragile and in many cases require more
+% expansion control (hence more code) than the two types of
+% conditionals described above.
+% \end{description}
+%
+% \subsection{Tests on control sequences}
+%
+% \begin{function}[EXP,pTF]{\cs_if_eq:NN}
+% \begin{syntax}
+% \cs{cs_if_eq_p:NN} \meta{cs_1} \meta{cs_2}
+% \cs{cs_if_eq:NNTF} \meta{cs_1} \meta{cs_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Compares the definition of two \meta{control sequences} and
+% is logically \texttt{true} if they are the same, \emph{i.e.}~if they have exactly
+% the same definition when examined with \cs{cs_show:N}.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\cs_if_exist:N, \cs_if_exist:c}
+% \begin{syntax}
+% \cs{cs_if_exist_p:N} \meta{control sequence}
+% \cs{cs_if_exist:NTF} \meta{control sequence} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{control sequence} is currently defined
+% (whether as a function or another control sequence type). Any
+% definition of \meta{control sequence} other than \tn{relax}
+% evaluates as \texttt{true}.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\cs_if_free:N, \cs_if_free:c}
+% \begin{syntax}
+% \cs{cs_if_free_p:N} \meta{control sequence}
+% \cs{cs_if_free:NTF} \meta{control sequence} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{control sequence} is currently free to
+% be defined. This test is \texttt{false} if the
+% \meta{control sequence} currently exists (as defined by
+% \cs{cs_if_exist:NTF}).
+% \end{function}
+%
+% \subsection{Primitive conditionals}
+%
+% The \eTeX{} engine itself provides many different conditionals. Some
+% expand whatever comes after them and others don't. Hence the names
+% for these underlying functions often contains a |:w| part but
+% higher level functions are often available. See for instance
+% \cs{int_compare_p:nNn} which is a wrapper for \cs{if_int_compare:w}.
+%
+% Certain conditionals deal with specific data types like boxes and
+% fonts and are described there. The ones described below are either
+% the universal conditionals or deal with control sequences. We
+% prefix primitive conditionals with |\if_|, except for \cs{if:w}.
+%
+% \begin{function}[EXP]
+% {\if_true:, \if_false:, \else:, \fi:, \reverse_if:N}
+% \begin{syntax}
+% "\if_true:" <true code> "\else:" <false code> "\fi:" \\
+% "\if_false:" <true code> "\else:" <false code> "\fi:" \\
+% "\reverse_if:N" <primitive conditional>
+% \end{syntax}
+% "\if_true:" always executes <true code>, while "\if_false:" always
+% executes <false code>. "\reverse_if:N" reverses any two-way primitive
+% conditional. "\else:" and "\fi:" delimit the branches of the
+% conditional. The function "\or:" is documented in \pkg{l3int} and
+% used in case switches.
+% \begin{texnote}
+% \cs{if_true:} and \cs{if_false:} are equivalent to their corresponding
+% \TeX{} primitive conditionals \tn{iftrue} and \tn{iffalse};
+% \cs{else:} and \cs{fi:} are the \TeX{} primitives \tn{else} and \tn{fi};
+% \cs{reverse_if:N} is the \eTeX{} primitive \tn{unless}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\if_meaning:w}
+% \begin{syntax}
+% "\if_meaning:w" <arg_1> <arg_2> <true code> "\else:" <false code> "\fi:"
+% \end{syntax}
+% "\if_meaning:w" executes <true code> when <arg_1> and <arg_2> are the same,
+% otherwise it executes <false code>.
+% <arg_1> and <arg_2> could be functions, variables, tokens; in all cases the
+% \emph{unexpanded} definitions are compared.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifx}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\if:w, \if_charcode:w, \if_catcode:w}
+% \begin{syntax}
+% "\if:w" <token(s)> <true code> "\else:" <false code> "\fi:" \\
+% "\if_catcode:w" <token(s)> <true code> "\else:" <false code> "\fi:"
+% \end{syntax}
+% "\if_charcode:w" is an alternative name for "\if:w".
+% These conditionals expand \meta{token(s)} until two
+% unexpandable tokens \meta{token_1} and \meta{token_2} are found;
+% any further tokens up to the next unbalanced "\else:" are the true branch,
+% ending with \meta{true code}. It is executed if the condition is fulfilled,
+% otherwise \meta{false code} is executed.
+% You can omit "\else:" when just in front of "\fi:" and
+% you can nest "\if...\else:...\fi:" constructs inside the true branch or the
+% \meta{false code}.
+% With "\exp_not:N", you can prevent the expansion of a token.
+%
+% "\if_catcode:w"
+% tests if \meta{token_1} and \meta{token_2} have the same category code whereas
+% "\if:w" and \cs{if_charcode:w} test if they have the same character code.
+% \begin{texnote}
+% \cs{if:w} and \cs{if_charcode:w} are both the \TeX{} primitive \tn{if}.
+% \cs{if_catcode:w} is the \TeX{} primitive \tn{ifcat}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\if_cs_exist:N, \if_cs_exist:w}
+% \begin{syntax}
+% "\if_cs_exist:N" <cs> <true code> "\else:" <false code> "\fi:" \\
+% "\if_cs_exist:w" <tokens> "\cs_end:" <true code> "\else:" <false code> "\fi:"
+% \end{syntax}
+% Check if <cs> appears in the hash table or if the control sequence
+% that can be formed from <tokens> appears in the hash table. The
+% latter function does not turn the control sequence in question into
+% "\scan_stop:"! This can be useful when dealing with control
+% sequences which cannot be entered as a single token.
+% \begin{texnote}
+% These are the \TeX{} primitives \tn{ifdefined} and \tn{ifcsname}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]
+% {
+% \if_mode_horizontal:, \if_mode_vertical:,
+% \if_mode_math:, \if_mode_inner:
+% }
+% \begin{syntax}
+% "\if_mode_horizontal:" <true code> "\else:" <false code> "\fi:"
+% \end{syntax}
+% Execute <true code> if currently in horizontal mode, otherwise
+% execute <false code>. Similar for the other functions.
+% \begin{texnote}
+% These are the \TeX{} primitives \tn{ifhmode}, \tn{ifvmode}, \tn{ifmmode},
+% and~\tn{ifinner}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Starting a paragraph}
+%
+% \begin{function}[added = 2017-07-04]{\mode_leave_vertical:}
+% \begin{syntax}
+% \cs{mode_leave_vertical:}
+% \end{syntax}
+% Ensures that \TeX{} is not in vertical (inter-paragraph) mode. In
+% horizontal or math mode this command has no effect, in vertical mode it
+% switches to horizontal mode, and inserts a box of width
+% \tn{parindent}, followed by the \tn{everypar} token list.
+% \begin{texnote}
+% This results in the contents of the \tn{everypar} token register being
+% inserted, after \cs{mode_leave_vertical:} is complete. Notice that in
+% contrast to the \LaTeXe{} \tn{leavevmode} approach, no box is used
+% by the method implemented here.
+% \end{texnote}
+% \end{function}
+%
+% \section{Debugging support}
+%
+% \begin{function}[added = 2017-07-16, updated = 2023-05-23]{\debug_on:n, \debug_off:n}
+% \begin{syntax}
+% \cs{debug_on:n} |{| \meta{comma-separated list} |}|
+% \cs{debug_off:n} |{| \meta{comma-separated list} |}|
+% \end{syntax}
+% Turn on and off within a group various debugging code, some of which
+% is also available as \pkg{expl3} load-time options. The items that
+% can be used in the \meta{list} are
+% \begin{itemize}
+% \item \texttt{check-declarations} that checks all \pkg{expl3}
+% variables used were previously declared and that local/global
+% variables (based on their name or on their first assignment) are
+% only locally/globally assigned;
+% \item \texttt{check-expressions} that checks integer, dimension,
+% skip, and muskip expressions are not terminated prematurely;
+% \item \texttt{deprecation} that makes deprecated commands produce errors;
+% \item \texttt{log-functions} that logs function definitions and
+% variable declarations;
+% \item \texttt{all} that does all of the above.
+% \end{itemize}
+% Providing these as switches rather than options allows testing code
+% even if it relies on other packages: load all other packages, call
+% \cs{debug_on:n}, and load the code that one is interested in
+% testing.
+% \end{function}
+%
+% \begin{function}[added = 2017-11-28]{\debug_suspend:, \debug_resume:}
+% \begin{syntax}
+% \cs{debug_suspend:} \ldots{} \cs{debug_resume:}
+% \end{syntax}
+% Suppress (locally) errors and logging from \texttt{debug} commands,
+% except for the \texttt{deprecation} errors. These pairs
+% of commands can be nested. This can be used around pieces of code
+% that are known to fail checks, if such failures should be ignored.
+% See for instance \pkg{l3cctab} and \pkg{l3coffins}.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3basics} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \subsection{Renaming some \TeX{} primitives (again)}
+%
+% Having given all the \TeX{} primitives a consistent name, we need to
+% give sensible names to the ones we actually want to use.
+% These will be defined as needed in the appropriate modules, but we
+% do a few now, just to get started.\footnote{This renaming gets expensive
+% in terms of csname usage, an alternative scheme would be to just use
+% the \cs[no-index]{tex_\ldots:D} name in the cases where no good alternative exists.}
+%
+% \begin{macro}[EXP]
+% {
+% \if_true:, \if_false:, \or:, \else:, \fi:, \reverse_if:N,
+% \if:w, \if_charcode:w, \if_catcode:w, \if_meaning:w
+% }
+% Then some conditionals.
+% \begin{macrocode}
+\tex_global:D \tex_let:D \if_true: \tex_iftrue:D
+\tex_global:D \tex_let:D \if_false: \tex_iffalse:D
+\tex_global:D \tex_let:D \or: \tex_or:D
+\tex_global:D \tex_let:D \else: \tex_else:D
+\tex_global:D \tex_let:D \fi: \tex_fi:D
+\tex_global:D \tex_let:D \reverse_if:N \tex_unless:D
+\tex_global:D \tex_let:D \if:w \tex_if:D
+\tex_global:D \tex_let:D \if_charcode:w \tex_if:D
+\tex_global:D \tex_let:D \if_catcode:w \tex_ifcat:D
+\tex_global:D \tex_let:D \if_meaning:w \tex_ifx:D
+\tex_global:D \tex_let:D \if_bool:N \tex_ifodd:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \if_mode_math:,
+% \if_mode_horizontal:,
+% \if_mode_vertical:,
+% \if_mode_inner:
+% }
+% \TeX{} lets us detect some if its modes.
+% \begin{macrocode}
+\tex_global:D \tex_let:D \if_mode_math: \tex_ifmmode:D
+\tex_global:D \tex_let:D \if_mode_horizontal: \tex_ifhmode:D
+\tex_global:D \tex_let:D \if_mode_vertical: \tex_ifvmode:D
+\tex_global:D \tex_let:D \if_mode_inner: \tex_ifinner:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\if_cs_exist:N, \if_cs_exist:w, \cs:w, \cs_end:}
+% Building csnames and testing if control sequences exist.
+% \begin{macrocode}
+\tex_global:D \tex_let:D \if_cs_exist:N \tex_ifdefined:D
+\tex_global:D \tex_let:D \if_cs_exist:w \tex_ifcsname:D
+\tex_global:D \tex_let:D \cs:w \tex_csname:D
+\tex_global:D \tex_let:D \cs_end: \tex_endcsname:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\exp_after:wN, \exp_not:N, \exp_not:n}
+% The five |\exp_| functions are used in the \pkg{l3expan} module
+% where they are described.
+% \begin{macrocode}
+\tex_global:D \tex_let:D \exp_after:wN \tex_expandafter:D
+\tex_global:D \tex_let:D \exp_not:N \tex_noexpand:D
+\tex_global:D \tex_let:D \exp_not:n \tex_unexpanded:D
+\tex_global:D \tex_let:D \exp:w \tex_romannumeral:D
+\tex_global:D \tex_chardef:D \exp_end: = 0 ~
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\token_to_meaning:N, \cs_meaning:N}
+% Examining a control sequence or token.
+% \begin{macrocode}
+\tex_global:D \tex_let:D \token_to_meaning:N \tex_meaning:D
+\tex_global:D \tex_let:D \cs_meaning:N \tex_meaning:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\tl_to_str:n, \token_to_str:N, \__kernel_tl_to_str:w}
+% Making strings.
+% \begin{macrocode}
+\tex_global:D \tex_let:D \tl_to_str:n \tex_detokenize:D
+\tex_global:D \tex_let:D \token_to_str:N \tex_string:D
+\tex_global:D \tex_let:D \__kernel_tl_to_str:w \tex_detokenize:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\scan_stop:, \group_begin:, \group_end:}
+% The next three are basic functions for which there also exist
+% versions that are safe inside alignments. These safe versions are
+% defined in the \pkg{l3prg} module.
+% \begin{macrocode}
+\tex_global:D \tex_let:D \scan_stop: \tex_relax:D
+\tex_global:D \tex_let:D \group_begin: \tex_begingroup:D
+\tex_global:D \tex_let:D \group_end: \tex_endgroup:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%<@@=int>
+% \end{macrocode}
+%
+% \begin{macro}[EXP]{\if_int_compare:w, \@@_to_roman:w}
+% For integers.
+% \begin{macrocode}
+\tex_global:D \tex_let:D \if_int_compare:w \tex_ifnum:D
+\tex_global:D \tex_let:D \@@_to_roman:w \tex_romannumeral:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\group_insert_after:N}
+% Adding material after the end of a group.
+% \begin{macrocode}
+\tex_global:D \tex_let:D \group_insert_after:N \tex_aftergroup:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\exp_args:Nc, \exp_args:cc}
+% Discussed in \pkg{l3expan}, but needed much earlier.
+% \begin{macrocode}
+\tex_long:D \tex_gdef:D \exp_args:Nc #1#2
+ { \exp_after:wN #1 \cs:w #2 \cs_end: }
+\tex_long:D \tex_gdef:D \exp_args:cc #1#2
+ { \cs:w #1 \exp_after:wN \cs_end: \cs:w #2 \cs_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, documented-as=\token_to_meaning:N]
+% {\token_to_meaning:c, \token_to_str:c, \cs_meaning:c}
+% A small number of variants defined by hand.
+% Some of the necessary functions
+% (\cs{use_i:nn}, \cs{use_ii:nn}, and \cs{exp_args:NNc}) are not
+% defined at that point yet, but will be defined before those variants
+% are used. The \cs{cs_meaning:c} command must check for an undefined
+% control sequence to avoid defining it mistakenly.
+% \begin{macrocode}
+\tex_gdef:D \token_to_str:c { \exp_args:Nc \token_to_str:N }
+\tex_long:D \tex_gdef:D \cs_meaning:c #1
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ { \exp_args:Nc \cs_meaning:N {#1} }
+ { \tl_to_str:n {undefined} }
+ }
+\tex_global:D \tex_let:D \token_to_meaning:c = \cs_meaning:c
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Defining some constants}
+%
+% \begin{variable}{\c_zero_int}
+% We need the constant \cs{c_zero_int}
+% which is used by some functions in current module. The
+% rest are defined in the \pkg{l3int} module -- at least for the
+% ones that can be defined with \cs{tex_chardef:D} or
+% \cs{tex_mathchardef:D}. For other constants the \pkg{l3int} module is
+% required but it can't be used until the allocation has been set
+% up properly!
+% \begin{macrocode}
+\tex_global:D \tex_chardef:D \c_zero_int = 0 ~
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_max_register_int}
+% This is here as this particular integer is needed in modules
+% loaded before \pkg{l3int}, and is documented in \pkg{l3int}.
+% \LuaTeX{} and those which contain parts of the Omega extensions have
+% more registers available than \eTeX{}.
+% \begin{macrocode}
+\tex_ifdefined:D \tex_luatexversion:D
+ \tex_global:D \tex_chardef:D \c_max_register_int = 65 535 ~
+\tex_else:D
+ \tex_ifdefined:D \tex_omathchardef:D
+ \tex_global:D \tex_omathchardef:D \c_max_register_int = 65535 ~
+ \tex_else:D
+ \tex_global:D \tex_mathchardef:D \c_max_register_int = 32767 ~
+ \tex_fi:D
+\tex_fi:D
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Defining functions}
+%
+% We start by providing functions for the typical definition
+% functions. First the global ones.
+%
+% \begin{macro}
+% {
+% \cs_gset_nopar:Npn , \cs_gset_nopar:Npe , \cs_gset_nopar:Npx ,
+% \cs_gset:Npn , \cs_gset:Npe , \cs_gset:Npx ,
+% \cs_gset_protected_nopar:Npn , \cs_gset_protected_nopar:Npe , \cs_gset_protected_nopar:Npx ,
+% \cs_gset_protected:Npn , \cs_gset_protected:Npe , \cs_gset_protected:Npx
+% }
+% All assignment functions in \LaTeX3 should be naturally protected;
+% after all, the \TeX{} primitives for assignments are and it can be
+% a cause of problems if others aren't.
+% \begin{macrocode}
+\tex_global:D \tex_let:D \cs_gset_nopar:Npn \tex_gdef:D
+\tex_global:D \tex_let:D \cs_gset_nopar:Npe \tex_xdef:D
+\tex_global:D \tex_let:D \cs_gset_nopar:Npx \tex_xdef:D
+\tex_protected:D \tex_long:D \tex_gdef:D \cs_gset:Npn
+ { \tex_long:D \tex_gdef:D }
+\tex_protected:D \tex_long:D \tex_gdef:D \cs_gset:Npe
+ { \tex_long:D \tex_xdef:D }
+\tex_global:D \tex_let:D \cs_gset:Npx \cs_gset:Npe
+\tex_protected:D \tex_long:D \tex_gdef:D \cs_gset_protected_nopar:Npn
+ { \tex_protected:D \tex_gdef:D }
+\tex_protected:D \tex_long:D \tex_gdef:D \cs_gset_protected_nopar:Npe
+ { \tex_protected:D \tex_xdef:D }
+\tex_global:D \tex_let:D \cs_gset_protected_nopar:Npx \cs_gset_protected_nopar:Npe
+\tex_protected:D \tex_long:D \tex_gdef:D \cs_gset_protected:Npn
+ { \tex_protected:D \tex_long:D \tex_gdef:D }
+\tex_protected:D \tex_long:D \tex_gdef:D \cs_gset_protected:Npe
+ { \tex_protected:D \tex_long:D \tex_xdef:D }
+\tex_global:D \tex_let:D \cs_gset_protected:Npx \cs_gset_protected:Npe
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \cs_set_nopar:Npn , \cs_set_nopar:Npe , \cs_set_nopar:Npx ,
+% \cs_set:Npn , \cs_set:Npe , \cs_set:Npx ,
+% \cs_set_protected_nopar:Npn , \cs_set_protected_nopar:Npe , \cs_set_protected_nopar:Npx ,
+% \cs_set_protected:Npn , \cs_set_protected:Npe , \cs_set_protected:Npx
+% }
+% Local versions of the above functions.
+% \begin{macrocode}
+\tex_global:D \tex_let:D \cs_set_nopar:Npn \tex_def:D
+\tex_global:D \tex_let:D \cs_set_nopar:Npe \tex_edef:D
+\tex_global:D \tex_let:D \cs_set_nopar:Npx \tex_edef:D
+\cs_gset_protected:Npn \cs_set:Npn
+ { \tex_long:D \tex_def:D }
+\cs_gset_protected:Npn \cs_set:Npe
+ { \tex_long:D \tex_edef:D }
+\tex_global:D \tex_let:D \cs_set:Npx \cs_set:Npe
+\cs_gset_protected:Npn \cs_set_protected_nopar:Npn
+ { \tex_protected:D \tex_def:D }
+\cs_gset_protected:Npn \cs_set_protected_nopar:Npe
+ { \tex_protected:D \tex_edef:D }
+\tex_global:D \tex_let:D \cs_set_protected_nopar:Npx \cs_set_protected_nopar:Npe
+\cs_gset_protected:Npn \cs_set_protected:Npn
+ { \tex_protected:D \tex_long:D \tex_def:D }
+\cs_gset_protected:Npn \cs_set_protected:Npe
+ { \tex_protected:D \tex_long:D \tex_edef:D }
+\tex_global:D \tex_let:D \cs_set_protected:Npx \cs_set_protected:Npe
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Selecting tokens}
+%
+% \begin{macrocode}
+%<@@=exp>
+% \end{macrocode}
+%
+% \begin{variable}{\l_@@_internal_tl}
+% Scratch token list variable for \pkg{l3expan}, used by \cs{use:x},
+% used in defining conditionals. We don't use |tl| methods because
+% \pkg{l3basics} is loaded earlier.
+% \begin{macrocode}
+\cs_gset_nopar:Npn \l_@@_internal_tl { }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\use:c}
+% This macro grabs its argument and returns a csname from it.
+% \begin{macrocode}
+\cs_gset:Npn \use:c #1 { \cs:w #1 \cs_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[deprecated]{\use:x}
+% Fully expands its argument and passes it to the input stream. Uses
+% the reserved \cs{l_@@_internal_tl} which we've set up above.
+% \begin{macrocode}
+\cs_gset_protected:Npn \use:x #1
+ {
+ \cs_set_nopar:Npx \l_@@_internal_tl {#1}
+ \l_@@_internal_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%<@@=use>
+% \end{macrocode}
+%
+% \begin{macro}[EXP]{\use:e}
+% \begin{macrocode}
+\cs_gset:Npn \use:e #1 { \tex_expanded:D {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%<@@=exp>
+% \end{macrocode}
+%
+% \begin{macro}[EXP]{\use:n, \use:nn, \use:nnn, \use:nnnn}
+% These macros grab their arguments and return them back to the input
+% (with outer braces removed).
+% \begin{macrocode}
+\cs_gset:Npn \use:n #1 {#1}
+\cs_gset:Npn \use:nn #1#2 {#1#2}
+\cs_gset:Npn \use:nnn #1#2#3 {#1#2#3}
+\cs_gset:Npn \use:nnnn #1#2#3#4 {#1#2#3#4}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\use_i:nn, \use_ii:nn}
+% The equivalent to \LaTeXe{}'s \tn{@firstoftwo} and \tn{@secondoftwo}.
+% \begin{macrocode}
+\cs_gset:Npn \use_i:nn #1#2 {#1}
+\cs_gset:Npn \use_ii:nn #1#2 {#2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \use_i:nnn , \use_ii:nnn , \use_iii:nnn ,
+% \use_i:nnnn, \use_ii:nnnn, \use_iii:nnnn, \use_iv:nnnn ,
+% \use_i:nnnnn, \use_ii:nnnnn, \use_iii:nnnnn, \use_iv:nnnnn ,
+% \use_v:nnnnn ,
+% \use_i:nnnnnn, \use_ii:nnnnnn, \use_iii:nnnnnn, \use_iv:nnnnnn ,
+% \use_v:nnnnnn , \use_vi:nnnnnn ,
+% \use_i:nnnnnnn, \use_ii:nnnnnnn, \use_iii:nnnnnnn, \use_iv:nnnnnnn ,
+% \use_v:nnnnnnn , \use_vi:nnnnnnn , \use_vii:nnnnnnn ,
+% \use_i:nnnnnnnn, \use_ii:nnnnnnnn, \use_iii:nnnnnnnn, \use_iv:nnnnnnnn ,
+% \use_v:nnnnnnnn , \use_vi:nnnnnnnn , \use_vii:nnnnnnnn , \use_viii:nnnnnnnn ,
+% \use_i:nnnnnnnnn, \use_ii:nnnnnnnnn, \use_iii:nnnnnnnnn, \use_iv:nnnnnnnnn ,
+% \use_v:nnnnnnnnn , \use_vi:nnnnnnnnn , \use_vii:nnnnnnnnn , \use_viii:nnnnnnnnn ,
+% \use_ix:nnnnnnnnn
+% }
+% We also need something for picking up arguments from a longer list.
+% \begin{macrocode}
+\cs_gset:Npn \use_i:nnn #1#2#3 {#1}
+\cs_gset:Npn \use_ii:nnn #1#2#3 {#2}
+\cs_gset:Npn \use_iii:nnn #1#2#3 {#3}
+\cs_gset:Npn \use_i:nnnn #1#2#3#4 {#1}
+\cs_gset:Npn \use_ii:nnnn #1#2#3#4 {#2}
+\cs_gset:Npn \use_iii:nnnn #1#2#3#4 {#3}
+\cs_gset:Npn \use_iv:nnnn #1#2#3#4 {#4}
+\cs_gset:Npn \use_i:nnnnn #1#2#3#4#5 {#1}
+\cs_gset:Npn \use_ii:nnnnn #1#2#3#4#5 {#2}
+\cs_gset:Npn \use_iii:nnnnn #1#2#3#4#5 {#3}
+\cs_gset:Npn \use_iv:nnnnn #1#2#3#4#5 {#4}
+\cs_gset:Npn \use_v:nnnnn #1#2#3#4#5 {#5}
+\cs_gset:Npn \use_i:nnnnnn #1#2#3#4#5#6 {#1}
+\cs_gset:Npn \use_ii:nnnnnn #1#2#3#4#5#6 {#2}
+\cs_gset:Npn \use_iii:nnnnnn #1#2#3#4#5#6 {#3}
+\cs_gset:Npn \use_iv:nnnnnn #1#2#3#4#5#6 {#4}
+\cs_gset:Npn \use_v:nnnnnn #1#2#3#4#5#6 {#5}
+\cs_gset:Npn \use_vi:nnnnnn #1#2#3#4#5#6 {#6}
+\cs_gset:Npn \use_i:nnnnnnn #1#2#3#4#5#6#7 {#1}
+\cs_gset:Npn \use_ii:nnnnnnn #1#2#3#4#5#6#7 {#2}
+\cs_gset:Npn \use_iii:nnnnnnn #1#2#3#4#5#6#7 {#3}
+\cs_gset:Npn \use_iv:nnnnnnn #1#2#3#4#5#6#7 {#4}
+\cs_gset:Npn \use_v:nnnnnnn #1#2#3#4#5#6#7 {#5}
+\cs_gset:Npn \use_vi:nnnnnnn #1#2#3#4#5#6#7 {#6}
+\cs_gset:Npn \use_vii:nnnnnnn #1#2#3#4#5#6#7 {#7}
+\cs_gset:Npn \use_i:nnnnnnnn #1#2#3#4#5#6#7#8 {#1}
+\cs_gset:Npn \use_ii:nnnnnnnn #1#2#3#4#5#6#7#8 {#2}
+\cs_gset:Npn \use_iii:nnnnnnnn #1#2#3#4#5#6#7#8 {#3}
+\cs_gset:Npn \use_iv:nnnnnnnn #1#2#3#4#5#6#7#8 {#4}
+\cs_gset:Npn \use_v:nnnnnnnn #1#2#3#4#5#6#7#8 {#5}
+\cs_gset:Npn \use_vi:nnnnnnnn #1#2#3#4#5#6#7#8 {#6}
+\cs_gset:Npn \use_vii:nnnnnnnn #1#2#3#4#5#6#7#8 {#7}
+\cs_gset:Npn \use_viii:nnnnnnnn #1#2#3#4#5#6#7#8 {#8}
+\cs_gset:Npn \use_i:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#1}
+\cs_gset:Npn \use_ii:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#2}
+\cs_gset:Npn \use_iii:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#3}
+\cs_gset:Npn \use_iv:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#4}
+\cs_gset:Npn \use_v:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#5}
+\cs_gset:Npn \use_vi:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#6}
+\cs_gset:Npn \use_vii:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#7}
+\cs_gset:Npn \use_viii:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#8}
+\cs_gset:Npn \use_ix:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#9}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\use_i_ii:nnn}
+% \begin{macrocode}
+\cs_gset:Npn \use_i_ii:nnn #1#2#3 {#1#2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\use_ii_i:nn}
+% \begin{macrocode}
+\cs_gset:Npn \use_ii_i:nn #1#2 { #2 #1 }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}[EXP]
+% {
+% \use_none_delimit_by_q_nil:w ,
+% \use_none_delimit_by_q_stop:w ,
+% \use_none_delimit_by_q_recursion_stop:w
+% }
+% Functions that gobble everything until they see either \cs{q_nil},
+% \cs{q_stop}, or \cs{q_recursion_stop}, respectively.
+% \begin{macrocode}
+\cs_gset:Npn \use_none_delimit_by_q_nil:w #1 \q_nil { }
+\cs_gset:Npn \use_none_delimit_by_q_stop:w #1 \q_stop { }
+\cs_gset:Npn \use_none_delimit_by_q_recursion_stop:w #1 \q_recursion_stop { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \use_i_delimit_by_q_nil:nw ,
+% \use_i_delimit_by_q_stop:nw ,
+% \use_i_delimit_by_q_recursion_stop:nw
+% }
+% Same as above but execute first argument after gobbling. Very useful
+% when you need to skip the rest of a mapping sequence but want an
+% easy way to control what should be expanded next.
+% \begin{macrocode}
+\cs_gset:Npn \use_i_delimit_by_q_nil:nw #1#2 \q_nil {#1}
+\cs_gset:Npn \use_i_delimit_by_q_stop:nw #1#2 \q_stop {#1}
+\cs_gset:Npn \use_i_delimit_by_q_recursion_stop:nw
+ #1#2 \q_recursion_stop {#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Gobbling tokens from input}
+%
+% \begin{macro}[EXP]
+% {
+% \use_none:n,
+% \use_none:nn,
+% \use_none:nnn,
+% \use_none:nnnn,
+% \use_none:nnnnn,
+% \use_none:nnnnnn,
+% \use_none:nnnnnnn,
+% \use_none:nnnnnnnn,
+% \use_none:nnnnnnnnn
+% }
+% To gobble tokens from the input we use a standard naming convention:
+% the number of tokens gobbled is given by the number of |n|'s
+% following the |:| in the name. Although we could define functions to
+% remove ten arguments or more using separate calls of
+% \cs{use_none:nnnnn}, this is very non-intuitive to the programmer
+% who will assume that expanding such a function once takes care
+% of gobbling all the tokens in one go.
+% \begin{macrocode}
+\cs_gset:Npn \use_none:n #1 { }
+\cs_gset:Npn \use_none:nn #1#2 { }
+\cs_gset:Npn \use_none:nnn #1#2#3 { }
+\cs_gset:Npn \use_none:nnnn #1#2#3#4 { }
+\cs_gset:Npn \use_none:nnnnn #1#2#3#4#5 { }
+\cs_gset:Npn \use_none:nnnnnn #1#2#3#4#5#6 { }
+\cs_gset:Npn \use_none:nnnnnnn #1#2#3#4#5#6#7 { }
+\cs_gset:Npn \use_none:nnnnnnnn #1#2#3#4#5#6#7#8 { }
+\cs_gset:Npn \use_none:nnnnnnnnn #1#2#3#4#5#6#7#8#9 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Debugging and patching later definitions}
+%
+% \begin{macrocode}
+%<@@=debug>
+% \end{macrocode}
+%
+% \begin{macro}{\__kernel_if_debug:TF}
+% A more meaningful test of whether debugging is enabled than messing
+% up with guards. We can also more easily change the logic in one
+% place then. This is needed primarily for deprecations.
+% \begin{macrocode}
+\cs_gset_protected:Npn \__kernel_if_debug:TF #1#2 {#2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\debug_on:n, \debug_off:n}
+% Stubs.
+% \begin{macrocode}
+\cs_gset_protected:Npn \debug_on:n #1
+ {
+ \sys_load_debug:
+ \cs_if_exist:NT \@@_all_on:
+ { \debug_on:n {#1} }
+ }
+\cs_gset_protected:Npn \debug_off:n #1
+ {
+ \sys_load_debug:
+ \cs_if_exist:NT \@@_all_on:
+ { \debug_off:n {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\debug_suspend:, \debug_resume:}
+% \begin{macrocode}
+\cs_gset_protected:Npn \debug_suspend: { }
+\cs_gset_protected:Npn \debug_resume: { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_deprecation_code:nn}
+% \begin{variable}{\g_@@_deprecation_on_tl, \g_@@_deprecation_off_tl}
+% Make deprecated commands throw errors if the user requests it.
+% This relies on two token lists, filled up in \pkg{l3deprecation}.
+% \begin{macrocode}
+\cs_gset_nopar:Npn \g_@@_deprecation_on_tl { }
+\cs_gset_nopar:Npn \g_@@_deprecation_off_tl { }
+\cs_gset_protected:Npn \__kernel_deprecation_code:nn #1#2
+ {
+ \tl_gput_right:Nn \g_@@_deprecation_on_tl {#1}
+ \tl_gput_right:Nn \g_@@_deprecation_off_tl {#2}
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \subsection{Conditional processing and definitions}
+%
+% \begin{macrocode}
+%<@@=prg>
+% \end{macrocode}
+%
+% Underneath any predicate function (|_p|) or other conditional forms
+% (|TF|, etc.) is a built-in logic saying that it after all of the
+% testing and processing must return the \meta{state} this leaves
+% \TeX{} in. Therefore, a simple user interface could be something like
+% \begin{verbatim}
+% \if_meaning:w #1#2
+% \prg_return_true:
+% \else:
+% \if_meaning:w #1#3
+% \prg_return_true:
+% \else:
+% \prg_return_false:
+% \fi:
+% \fi:
+% \end{verbatim}
+% Usually, a \TeX{} programmer would have to insert a number of
+% \cs{exp_after:wN}s to ensure the state value is returned at exactly
+% the point where the last conditional is finished. However, that
+% obscures the code and forces the \TeX{} programmer to prove that
+% he/she knows the $2^{n}-1$ table. We therefore provide the simpler
+% interface.
+%
+% \begin{macro}[EXP]{\prg_return_true:, \prg_return_false:}
+% The idea here is that \cs{exp:w} expands fully any
+% \cs{else:} and \cs{fi:} that are waiting to be discarded,
+% before reaching the \cs{exp_end:} which leaves an empty expansion.
+% The code can then leave either the first or second argument in the
+% input stream. This means that all of the branching code has to contain
+% at least two tokens: see how the logical tests are actually implemented
+% to see this.
+% \begin{macrocode}
+\cs_gset:Npn \prg_return_true:
+ { \exp_after:wN \use_i:nn \exp:w }
+\cs_gset:Npn \prg_return_false:
+ { \exp_after:wN \use_ii:nn \exp:w}
+% \end{macrocode}
+% An extended state space could be implemented by including a more
+% elaborate function in place of \cs{use_i:nn}/\cs{use_ii:nn}. Provided
+% two arguments are absorbed then the code would work.
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_use_none_delimit_by_q_recursion_stop:w}
+% Private version of \cs{use_none_delimit_by_q_recursion_stop:w}.
+% \begin{macrocode}
+\cs_gset:Npn \@@_use_none_delimit_by_q_recursion_stop:w
+ #1 \q_@@_recursion_stop { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \prg_set_conditional:Npnn ,
+% \prg_gset_conditional:Npnn ,
+% \prg_new_conditional:Npnn ,
+% \prg_set_protected_conditional:Npnn ,
+% \prg_gset_protected_conditional:Npnn,
+% \prg_new_protected_conditional:Npnn
+% }
+% \begin{macro}{\@@_generate_conditional_parm:NNNpnn}
+% The user functions for the types using parameter text from the
+% programmer. The various functions only differ by which function is
+% used for the assignment. For those |Npnn| type functions, we must
+% grab the parameter text, reading everything up to a left brace
+% before continuing. Then split the base function into name and
+% signature, and feed \Arg{name} \Arg{signature} \meta{boolean}
+% \Arg{set~or~new} \Arg{maybe~protected} \Arg{parameters} |{TF,...}|
+% \Arg{code} to the auxiliary function responsible for defining all
+% conditionals.
+% Note that |e| stands for expandable and |p| for protected.
+% \begin{macrocode}
+\cs_gset_protected:Npn \prg_set_conditional:Npnn
+ { \@@_generate_conditional_parm:NNNpnn \cs_set:Npn e }
+\cs_gset_protected:Npn \prg_gset_conditional:Npnn
+ { \@@_generate_conditional_parm:NNNpnn \cs_gset:Npn e }
+\cs_gset_protected:Npn \prg_new_conditional:Npnn
+ { \@@_generate_conditional_parm:NNNpnn \cs_new:Npn e }
+\cs_gset_protected:Npn \prg_set_protected_conditional:Npnn
+ { \@@_generate_conditional_parm:NNNpnn \cs_set_protected:Npn p }
+\cs_gset_protected:Npn \prg_gset_protected_conditional:Npnn
+ { \@@_generate_conditional_parm:NNNpnn \cs_gset_protected:Npn p }
+\cs_gset_protected:Npn \prg_new_protected_conditional:Npnn
+ { \@@_generate_conditional_parm:NNNpnn \cs_new_protected:Npn p }
+\cs_gset_protected:Npn \@@_generate_conditional_parm:NNNpnn #1#2#3#4#
+ {
+ \use:e
+ {
+ \@@_generate_conditional:nnNNNnnn
+ \cs_split_function:N #3
+ }
+ #1 #2 {#4}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \prg_set_conditional:Nnn ,
+% \prg_gset_conditional:Nnn ,
+% \prg_new_conditional:Nnn ,
+% \prg_set_protected_conditional:Nnn ,
+% \prg_gset_protected_conditional:Nnn,
+% \prg_new_protected_conditional:Nnn
+% }
+% \begin{macro}
+% {
+% \@@_generate_conditional_count:NNNnn ,
+% \@@_generate_conditional_count:nnNNNnn
+% }
+% The user functions for the types automatically inserting the correct
+% parameter text based on the signature. The various functions only
+% differ by which function is used for the assignment. Split the base
+% function into name and signature. The second auxiliary generates
+% the parameter text from the number of letters in the signature.
+% Then feed \Arg{name} \Arg{signature} \meta{boolean} \Arg{set~or~new}
+% \Arg{maybe~protected} \Arg{parameters} |{TF,...}| \Arg{code} to the
+% auxiliary function responsible for defining all conditionals. If
+% the \meta{signature} has more than $9$ letters, the definition is
+% aborted since \TeX{} macros have at most $9$ arguments. The
+% erroneous case where the function name contains no colon is captured
+% later.
+% \begin{macrocode}
+\cs_gset_protected:Npn \prg_set_conditional:Nnn
+ { \@@_generate_conditional_count:NNNnn \cs_set:Npn e }
+\cs_gset_protected:Npn \prg_gset_conditional:Nnn
+ { \@@_generate_conditional_count:NNNnn \cs_set:Npn e }
+\cs_gset_protected:Npn \prg_new_conditional:Nnn
+ { \@@_generate_conditional_count:NNNnn \cs_new:Npn e }
+\cs_gset_protected:Npn \prg_set_protected_conditional:Nnn
+ { \@@_generate_conditional_count:NNNnn \cs_set_protected:Npn p }
+\cs_gset_protected:Npn \prg_gset_protected_conditional:Nnn
+ { \@@_generate_conditional_count:NNNnn \cs_gset_protected:Npn p }
+\cs_gset_protected:Npn \prg_new_protected_conditional:Nnn
+ { \@@_generate_conditional_count:NNNnn \cs_new_protected:Npn p }
+\cs_gset_protected:Npn \@@_generate_conditional_count:NNNnn #1#2#3
+ {
+ \use:e
+ {
+ \@@_generate_conditional_count:nnNNNnn
+ \cs_split_function:N #3
+ }
+ #1 #2
+ }
+\cs_gset_protected:Npn \@@_generate_conditional_count:nnNNNnn #1#2#3#4#5
+ {
+ \__kernel_cs_parm_from_arg_count:nnF
+ { \@@_generate_conditional:nnNNNnnn {#1} {#2} #3 #4 #5 }
+ { \tl_count:n {#2} }
+ {
+ \msg_error:nnee { kernel } { bad-number-of-arguments }
+ { \token_to_str:c { #1 : #2 } }
+ { \tl_count:n {#2} }
+ \use_none:nn
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_generate_conditional:nnNNNnnn,
+% \@@_generate_conditional:NNnnnnNw,
+% \@@_generate_conditional_test:w,
+% \@@_generate_conditional_fast:nw,
+% }
+% The workhorse here is going through a list of desired forms, \emph{i.e.},
+% |p|, |TF|, |T| and |F|. The first three arguments come from splitting up
+% the base form of the conditional, which gives the name, signature
+% and a boolean to signal whether or not there was a colon in the
+% name. In the absence of a colon, we throw an error and don't define
+% any conditional. The fourth and fifth arguments build up the
+% defining function. The sixth is the parameters to use (possibly
+% empty), the seventh is the list of forms to define, the eighth is the
+% replacement text which we will augment when defining the forms.
+% The use of \cs{tl_to_str:n} makes the later loop more robust.
+%
+% A large number of our low-level conditionals look like \meta{code}
+% \cs{prg_return_true:} \cs{else:} \cs{prg_return_false:} \cs{fi:} so
+% we optimize this special case by calling
+% \cs{@@_generate_conditional_fast:nw} \Arg{code}. This passes
+% \cs{use_i:nn} instead of \cs{use_i_ii:nnn} to functions such as
+% \cs{@@_generate_p_form:wNNnnnnN}.
+% \begin{macrocode}
+\cs_gset_protected:Npn \@@_generate_conditional:nnNNNnnn #1#2#3#4#5#6#7#8
+ {
+ \if_meaning:w \c_false_bool #3
+ \msg_error:nne { kernel } { missing-colon }
+ { \token_to_str:c {#1} }
+ \exp_after:wN \use_none:nn
+ \fi:
+ \use:e
+ {
+ \exp_not:N \@@_generate_conditional:NNnnnnNw
+ \exp_not:n { #4 #5 {#1} {#2} {#6} }
+ \@@_generate_conditional_test:w
+ #8 \s_@@_mark
+ \@@_generate_conditional_fast:nw
+ \prg_return_true: \else: \prg_return_false: \fi: \s_@@_mark
+ \use_none:n
+ \exp_not:n { {#8} \use_i_ii:nnn }
+ \tl_to_str:n {#7}
+ \exp_not:n { , \q_@@_recursion_tail , \q_@@_recursion_stop }
+ }
+ }
+\cs_gset:Npn \@@_generate_conditional_test:w
+ #1 \prg_return_true: \else: \prg_return_false: \fi: \s_@@_mark #2
+ { #2 {#1} }
+\cs_gset:Npn \@@_generate_conditional_fast:nw #1#2 \exp_not:n #3
+ { \exp_not:n { {#1} \use_i:nn } }
+% \end{macrocode}
+% Looping through the list of desired forms. First are six arguments
+% and seventh is the form. Use the form to call the
+% correct type. If the form does not exist, the \cs{use:c}
+% construction results in \tn{relax}, and the error message is
+% displayed (unless the form is empty, to allow for |{T, , F}|),
+% then \cs{use_none:nnnnnnnn} cleans up. Otherwise, the
+% error message is removed by the variant form.
+% \begin{macrocode}
+\cs_gset_protected:Npn \@@_generate_conditional:NNnnnnNw #1#2#3#4#5#6#7#8 ,
+ {
+ \if_meaning:w \q_@@_recursion_tail #8
+ \exp_after:wN \@@_use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ \use:c { @@_generate_ #8 _form:wNNnnnnN }
+ \tl_if_empty:nF {#8}
+ {
+ \msg_error:nnee
+ { kernel } { conditional-form-unknown }
+ {#8} { \token_to_str:c { #3 : #4 } }
+ }
+ \use_none:nnnnnnnn
+ \s_@@_stop
+ #1 #2 {#3} {#4} {#5} {#6} #7
+ \@@_generate_conditional:NNnnnnNw #1 #2 {#3} {#4} {#5} {#6} #7
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_generate_p_form:wNNnnnnN,
+% \@@_generate_TF_form:wNNnnnnN,
+% \@@_generate_T_form:wNNnnnnN,
+% \@@_generate_F_form:wNNnnnnN
+% }
+% \begin{macro}[EXP]{\@@_p_true:w, \@@_T_true:w, \@@_F_true:w, \@@_TF_true:w}
+% How to generate the various forms. Those functions take the
+% following arguments: 1: junk, 2: \cs{cs_set:Npn} or similar, 3: |p|
+% (for protected conditionals) or |e|, 4: function name, 5: signature,
+% 6: parameter text, 7: replacement (possibly trimmed by
+% \cs{@@_generate_conditional_fast:nw}), 8: \cs{use_i_ii:nnn} or
+% \cs{use_i:nn} (for \enquote{fast} conditionals). Remember that the
+% logic-returning functions expect two arguments to be present after
+% \cs{exp_end:}: notice the construction of the different variants
+% relies on this, and that the |TF| and |F| variants will be slightly
+% faster than the |T| version. The |p| form is only valid for
+% expandable tests, we check for that by making sure that the second
+% argument is empty. For \enquote{fast} conditionals, |#7| has an
+% extra \cs[no-index]{if_\ldots{}}. To optimize a bit further we
+% don't use \cs{exp_after:wN} \cs{use_ii:nnn} and similar but instead use
+% \cs{@@_TF_true:w} and similar to swap out the macro after \cs{fi:}. It would
+% be a tiny bit faster if we directly grabbed the |T| and |F| arguments there,
+% but if those are actually missing, the recovery from the runaway argument
+% would not insert \cs{fi:} back, messing up nesting of conditionals.
+% \begin{macrocode}
+\cs_gset_protected:Npn \@@_generate_p_form:wNNnnnnN
+ #1 \s_@@_stop #2#3#4#5#6#7#8
+ {
+ \if_meaning:w e #3
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ #8
+ { \exp_args:Nc #2 { #4 _p: #5 } #6 }
+ { { #7 \exp_end: \c_true_bool \c_false_bool } }
+ { #7 \@@_p_true:w \fi: \c_false_bool }
+ }
+ {
+ \msg_error:nne { kernel } { protected-predicate }
+ { \token_to_str:c { #4 _p: #5 } }
+ }
+ }
+\cs_gset_protected:Npn \@@_generate_T_form:wNNnnnnN
+ #1 \s_@@_stop #2#3#4#5#6#7#8
+ {
+ #8
+ { \exp_args:Nc #2 { #4 : #5 T } #6 }
+ { { #7 \exp_end: \use:n \use_none:n } }
+ { #7 \@@_T_true:w \fi: \use_none:n }
+ }
+\cs_gset_protected:Npn \@@_generate_F_form:wNNnnnnN
+ #1 \s_@@_stop #2#3#4#5#6#7#8
+ {
+ #8
+ { \exp_args:Nc #2 { #4 : #5 F } #6 }
+ { { #7 \exp_end: { } } }
+ { #7 \@@_F_true:w \fi: \use:n }
+ }
+\cs_gset_protected:Npn \@@_generate_TF_form:wNNnnnnN
+ #1 \s_@@_stop #2#3#4#5#6#7#8
+ {
+ #8
+ { \exp_args:Nc #2 { #4 : #5 TF } #6 }
+ { { #7 \exp_end: } }
+ { #7 \@@_TF_true:w \fi: \use_ii:nn }
+ }
+\cs_gset:Npn \@@_p_true:w \fi: \c_false_bool { \fi: \c_true_bool }
+\cs_gset:Npn \@@_T_true:w \fi: \use_none:n { \fi: \use:n }
+\cs_gset:Npn \@@_F_true:w \fi: \use:n { \fi: \use_none:n }
+\cs_gset:Npn \@@_TF_true:w \fi: \use_ii:nn { \fi: \use_i:nn }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \prg_set_eq_conditional:NNn ,
+% \prg_gset_eq_conditional:NNn,
+% \prg_new_eq_conditional:NNn
+% }
+% \begin{macro}{\@@_set_eq_conditional:NNNn}
+% The setting-equal functions. Split both functions and feed
+% \Arg{name_1} \Arg{signature_1} \meta{boolean_1}
+% \Arg{name_2} \Arg{signature_2} \meta{boolean_2}
+% \meta{copying~function} \meta{conditions} |,| \cs{q_@@_recursion_tail}
+% |,| \cs{q_@@_recursion_stop}
+% to a first auxiliary.
+% \begin{macrocode}
+\cs_gset_protected:Npn \prg_set_eq_conditional:NNn
+ { \@@_set_eq_conditional:NNNn \cs_set_eq:cc }
+\cs_gset_protected:Npn \prg_gset_eq_conditional:NNn
+ { \@@_set_eq_conditional:NNNn \cs_gset_eq:cc }
+\cs_gset_protected:Npn \prg_new_eq_conditional:NNn
+ { \@@_set_eq_conditional:NNNn \cs_new_eq:cc }
+\cs_gset_protected:Npn \@@_set_eq_conditional:NNNn #1#2#3#4
+ {
+ \use:e
+ {
+ \exp_not:N \@@_set_eq_conditional:nnNnnNNw
+ \cs_split_function:N #2
+ \cs_split_function:N #3
+ \exp_not:N #1
+ \tl_to_str:n {#4}
+ \exp_not:n { , \q_@@_recursion_tail , \q_@@_recursion_stop }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_set_eq_conditional:nnNnnNNw ,
+% \@@_set_eq_conditional_loop:nnnnNw
+% }
+% \begin{macro}[EXP]
+% {
+% \@@_set_eq_conditional_p_form:nnn ,
+% \@@_set_eq_conditional_TF_form:nnn ,
+% \@@_set_eq_conditional_T_form:nnn ,
+% \@@_set_eq_conditional_F_form:nnn ,
+% }
+% Split the function to be defined, and setup a manual clist loop over
+% argument |#6| of the first auxiliary. The second auxiliary receives
+% twice three arguments coming from splitting the function to be
+% defined and the function to copy. Make sure that both functions
+% contained a colon, otherwise we don't know how to build
+% conditionals, hence abort. Call the looping macro, with arguments
+% \Arg{name_1} \Arg{signature_1} \Arg{name_2} \Arg{signature_2}
+% \meta{copying~function} and followed by the comma list. At each
+% step in the loop, make sure that the conditional form we copy is
+% defined, and copy it, otherwise abort.
+% \begin{macrocode}
+\cs_gset_protected:Npn \@@_set_eq_conditional:nnNnnNNw #1#2#3#4#5#6
+ {
+ \if_meaning:w \c_false_bool #3
+ \msg_error:nne { kernel } { missing-colon }
+ { \token_to_str:c {#1} }
+ \exp_after:wN \@@_use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ \if_meaning:w \c_false_bool #6
+ \msg_error:nne { kernel } { missing-colon }
+ { \token_to_str:c {#4} }
+ \exp_after:wN \@@_use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ \@@_set_eq_conditional_loop:nnnnNw {#1} {#2} {#4} {#5}
+ }
+\cs_gset_protected:Npn \@@_set_eq_conditional_loop:nnnnNw #1#2#3#4#5#6 ,
+ {
+ \if_meaning:w \q_@@_recursion_tail #6
+ \exp_after:wN \@@_use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ \use:c { @@_set_eq_conditional_ #6 _form:wNnnnn }
+ \tl_if_empty:nF {#6}
+ {
+ \msg_error:nnee
+ { kernel } { conditional-form-unknown }
+ {#6} { \token_to_str:c { #1 : #2 } }
+ }
+ \use_none:nnnnnn
+ \s_@@_stop
+ #5 {#1} {#2} {#3} {#4}
+ \@@_set_eq_conditional_loop:nnnnNw {#1} {#2} {#3} {#4} #5
+ }
+\cs_gset:Npn \@@_set_eq_conditional_p_form:wNnnnn #1 \s_@@_stop #2#3#4#5#6
+ { #2 { #3 _p : #4 } { #5 _p : #6 } }
+\cs_gset:Npn \@@_set_eq_conditional_TF_form:wNnnnn #1 \s_@@_stop #2#3#4#5#6
+ { #2 { #3 : #4 TF } { #5 : #6 TF } }
+\cs_gset:Npn \@@_set_eq_conditional_T_form:wNnnnn #1 \s_@@_stop #2#3#4#5#6
+ { #2 { #3 : #4 T } { #5 : #6 T } }
+\cs_gset:Npn \@@_set_eq_conditional_F_form:wNnnnn #1 \s_@@_stop #2#3#4#5#6
+ { #2 { #3 : #4 F } { #5 : #6 F } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% All that is left is to define the canonical boolean true and false.
+% I think Michael originated the idea of expandable boolean tests. At
+% first these were supposed to expand into either \texttt{TT} or
+% \texttt{TF} to be tested using \cs{if:w} but this was later changed to
+% |00| and |01|, so they could be used in logical
+% operations. Later again they were changed to being numerical
+% constants with values of $1$ for true and $0$ for false. We need
+% this from the get-go.
+%
+% \begin{variable}{\c_true_bool, \c_false_bool}
+% Here are the canonical boolean values.
+% \begin{macrocode}
+\tex_global:D \tex_chardef:D \c_true_bool = 1 ~
+\tex_global:D \tex_chardef:D \c_false_bool = 0 ~
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Dissecting a control sequence}
+%
+% \begin{macrocode}
+%<@@=cs>
+% \end{macrocode}
+%
+% \begin{function}[EXP]{\@@_count_signature:N}
+% \begin{syntax}
+% \cs{@@_count_signature:N} \meta{function}
+% \end{syntax}
+% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part
+% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon).
+% The \meta{number} of tokens in the \meta{signature} is then left in
+% the input stream. If there was no \meta{signature} then the result is
+% the marker value $-1$.
+% \end{function}
+%
+% \begin{function}{\@@_tmp:w}
+% Function used for various short-term usages, for instance defining
+% functions whose definition involves tokens which are hard to insert
+% normally (spaces, characters with category other).
+% \end{function}
+%
+% \begin{macro}[EXP]{\cs_to_str:N}
+% \begin{macro}[EXP]{\@@_to_str:N, \@@_to_str:w}
+% This converts a control sequence into the character string of its
+% name, removing the leading escape character. This turns out to be
+% a non-trivial matter as there a different cases:
+% \begin{itemize}
+% \item The usual case of a printable escape character;
+% \item the case of a non-printable escape characters, e.g., when
+% the value of the \tn{escapechar} is negative;
+% \item when the escape character is a space.
+% \end{itemize}
+% One approach to solve this is to test how many tokens result from
+% |\token_to_str:N \a|. If there are two tokens, then the escape
+% character is printable, while if it is non-printable then only
+% one is present.
+%
+% However, there is an additional complication: the control
+% sequence itself may start with a space. Clearly that should \emph{not} be
+% lost in the process of converting to a string. So the approach adopted is
+% a little more intricate still. When the escape character is printable,
+% \verb*|\token_to_str:N \ | yields the escape character itself and a space.
+% The character codes are different, thus the \cs{if:w} test is false,
+% and \TeX{} reads \cs{@@_to_str:N} after turning the following
+% control sequence into a string; this auxiliary removes the escape
+% character, and stops the expansion of the initial \cs{tex_romannumeral:D}.
+% The second case is that the escape character is not printable. Then
+% the \cs{if:w} test is unfinished after reading a the space from
+% \verb*|\token_to_str:N \ |, and the auxiliary \cs{@@_to_str:w}
+% is expanded, feeding |-| as a second character for the test;
+% the test is false, and \TeX{} skips to \cs{fi:}, then performs
+% \cs{token_to_str:N}, and stops the \cs{tex_romannumeral:D} with \cs{c_zero_int}.
+% The last case is that the escape character is itself a space. In this
+% case, the \cs{if:w} test is true, and the auxiliary \cs{@@_to_str:w}
+% comes into play, inserting |-\int_value:w|, which expands \cs{c_zero_int}
+% to the character |0|. The initial \cs{tex_romannumeral:D} then sees
+% |0|, which is not a terminated number, followed by the escape character,
+% a space, which is removed, terminating the expansion of
+% \cs{tex_romannumeral:D}.
+% In all three cases, \cs{cs_to_str:N} takes two expansion steps
+% to be fully expanded.
+% \begin{macrocode}
+\cs_gset:Npn \cs_to_str:N
+ {
+% \end{macrocode}
+% We implement the expansion scheme using \cs{tex_romannumeral:D}
+% terminating it with \cs{c_zero_int} rather than using \cs{exp:w} and
+% \cs{exp_end:} as we normally do. The reason is that the code
+% heavily depends on terminating the expansion with \cs{c_zero_int} so
+% we make this dependency explicit.
+% \begin{macrocode}
+ \tex_romannumeral:D
+ \if:w \token_to_str:N \ \@@_to_str:w \fi:
+ \exp_after:wN \@@_to_str:N \token_to_str:N
+ }
+\cs_gset:Npn \@@_to_str:N #1 { \c_zero_int }
+\cs_gset:Npn \@@_to_str:w #1 \@@_to_str:N
+ { - \int_value:w \fi: \exp_after:wN \c_zero_int }
+% \end{macrocode}
+% If speed is a concern we could use \tn{csstring} in \LuaTeX{}. For
+% the empty csname that primitive gives an empty result while the
+% current \cs{cs_to_str:N} gives incorrect results in all engines
+% (this is impossible to fix without huge performance hit).
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\cs_split_function:N}
+% \begin{macro}[EXP]
+% {\@@_split_function_auxi:w, \@@_split_function_auxii:w}
+% This function takes a function name and splits it into name with
+% the escape char removed and argument specification. In addition to
+% this, a third argument, a boolean \meta{true} or \meta{false} is
+% returned with \meta{true} for when there is a colon in the function
+% and \meta{false} if there is not.
+%
+% First ensure that we actually get a properly evaluated string by
+% expanding \cs{cs_to_str:N} twice. If the function contained a
+% colon, the auxiliary takes as |#1| the function name, delimited by
+% the first colon, then the signature |#2|, delimited by \cs{s_@@_mark},
+% then \cs{c_true_bool} as |#3|, and |#4| cleans up until \cs{s_@@_stop}.
+% Otherwise, the |#1| contains the function name and \cs{s_@@_mark}
+% \cs{c_true_bool}, |#2| is empty, |#3| is \cs{c_false_bool}, and |#4|
+% cleans up. The second
+% auxiliary trims the trailing \cs{s_@@_mark} from the function name if
+% present (that is, if the original function had no colon).
+% \begin{macrocode}
+\cs_gset_protected:Npn \@@_tmp:w #1
+ {
+ \cs_gset:Npn \cs_split_function:N ##1
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \@@_split_function_auxi:w
+ \cs_to_str:N ##1 \s_@@_mark \c_true_bool
+ #1 \s_@@_mark \c_false_bool \s_@@_stop
+ }
+ \cs_gset:Npn \@@_split_function_auxi:w
+ ##1 #1 ##2 \s_@@_mark ##3##4 \s_@@_stop
+ { \@@_split_function_auxii:w ##1 \s_@@_mark \s_@@_stop {##2} ##3 }
+ \cs_gset:Npn \@@_split_function_auxii:w ##1 \s_@@_mark ##2 \s_@@_stop
+ { {##1} }
+ }
+\exp_after:wN \@@_tmp:w \token_to_str:N :
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Exist or free}
+%
+% A control sequence is said to \emph{exist} (to be used) if has an entry in
+% the hash table and its meaning is different from the primitive
+% \tn{relax} token. A control sequence is said to be \emph{free}
+% (to be defined) if it does not already exist.
+%
+% \begin{macro}[pTF, EXP]{\cs_if_exist:N, \cs_if_exist:c}
+% \begin{macro}{\@@_if_exist_c_aux:,\@@_if_exist_c_aux:w}
+% Two versions for checking existence. For the |N| form we firstly
+% check for \cs{scan_stop:} and then if it is in the hash
+% table. There is no problem when inputting something like \cs{else:}
+% or \cs{fi:} as \TeX{} will only ever skip input in case the token
+% tested against is \cs{scan_stop:}.
+%
+% In both the |N| and |c| form we use the way \cs{prg_set_conditional:Npnn}
+% optimizes the conditionals to negate the tests using \cs{else:} (the
+% \cs{else:} in the top level functions will be removed by the optimization,
+% and this usage of \cs{else:} will be fine).
+% \begin{macrocode}
+\prg_gset_conditional:Npnn \cs_if_exist:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \scan_stop:
+ \use_i:nnnn
+ \else:
+ \fi:
+ \if_cs_exist:N #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% For the |c| form we firstly check if it is in the hash table and
+% then for \cs{scan_stop:} so that we do not add it to the hash table
+% unless it was already there. Here we have to be careful as the text
+% to be skipped if the first test is false may contain tokens that
+% disturb the scanner. Therefore, we ensure that the second test is
+% performed after the first one has concluded completely.
+% \begin{macrocode}
+\cs_if_exist:NTF \tex_lastnamedcs:D
+ {
+ \prg_gset_conditional:Npnn \cs_if_exist:c #1 { p , T , F , TF }
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \@@_if_exist_c_aux:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ \cs_gset:Npn \@@_if_exist_c_aux:
+ { \fi: \exp_after:wN \if_meaning:w \tex_lastnamedcs:D \scan_stop: \else: }
+ }
+ {
+ \prg_gset_conditional:Npnn \cs_if_exist:c #1 { p , T , F , TF }
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \@@_if_exist_c_aux:w
+ \fi:
+ \use_none:n {#1}
+ \if_false:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ \cs_gset:Npn \@@_if_exist_c_aux:w \fi: \use_none:n #1 \if_false:
+ { \fi: \exp_after:wN \if_meaning:w \cs:w #1 \cs_end: \scan_stop: \else: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF, EXP]{\cs_if_free:N, \cs_if_free:c}
+% The logical reversal of the above.
+% \begin{macrocode}
+\prg_gset_conditional:Npnn \cs_if_free:N #1 { p , T , F , TF }
+ {
+ \if_cs_exist:N #1
+ \else:
+ \use_none:nnnn
+ \fi:
+ \if_meaning:w #1 \scan_stop:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_if_exist:NTF \tex_lastnamedcs:D
+ {
+ \prg_gset_conditional:Npnn \cs_if_free:c #1 { p , T , F , TF }
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \@@_if_free_c_aux:w
+ \fi:
+ \if_true:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ \cs_gset:Npn \@@_if_free_c_aux:w \fi: \if_true:
+ { \fi: \exp_after:wN \if_meaning:w \tex_lastnamedcs:D \scan_stop: }
+ }
+ {
+ \prg_gset_conditional:Npnn \cs_if_free:c #1 { p , T , F , TF }
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \@@_if_free_c_aux:w
+ \fi:
+ \use_none:n {#1}
+ \if_true:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ \cs_gset:Npn \@@_if_free_c_aux:w \fi: \use_none:n #1 \if_true:
+ { \fi: \exp_after:wN \if_meaning:w \cs:w #1 \cs_end: \scan_stop: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP,noTF,added=2011-10-10]
+% {\cs_if_exist_use:N, \cs_if_exist_use:c}
+% \begin{macro}{\@@_if_exist_use_aux:w, \@@_if_exist_use_aux:Nnn}
+% The \cs[index=cs_if_exist_use:N]{cs_if_exist_use:\ldots{}}
+% functions cannot be implemented
+% as conditionals because the true branch must leave both the control
+% sequence itself and the true code in the input stream.
+% For the \texttt{c} variants, we are careful not to put the control
+% sequence in the hash table if it does not exist.
+% If available we use the \tn{lastnamedcs} primitive.
+% \begin{macrocode}
+\cs_gset:Npn \cs_if_exist_use:NTF #1#2
+ { \cs_if_exist:NTF #1 { #1 #2 } }
+\cs_gset:Npn \cs_if_exist_use:NF #1
+ { \cs_if_exist:NTF #1 #1 }
+\cs_gset:Npn \cs_if_exist_use:NT #1 #2
+ { \cs_if_exist:NT #1 { #1 #2 } }
+\cs_gset:Npn \cs_if_exist_use:N #1
+ { \cs_if_exist:NT #1 #1 }
+\cs_if_exist:NTF \tex_lastnamedcs:D
+ {
+ \cs_gset:Npn \cs_if_exist_use:cTF #1
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \@@_if_exist_use_aux:w
+ \fi:
+ \use_ii:nn
+ }
+ \cs_gset:Npn \@@_if_exist_use_aux:w \fi: \use_ii:nn
+ { \fi: \exp_after:wN \@@_if_exist_use_aux:Nnn \tex_lastnamedcs:D }
+ }
+ {
+ \cs_gset:Npn \cs_if_exist_use:cTF #1
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \@@_if_exist_use_aux:w
+ \fi:
+ \use_iii:nnn {#1}
+ }
+ \cs_gset:Npn \@@_if_exist_use_aux:w \fi: \use_iii:nnn #1
+ { \fi: \exp_after:wN \@@_if_exist_use_aux:Nnn \cs:w #1 \cs_end: }
+ }
+\cs_gset:Npn \@@_if_exist_use_aux:Nnn #1#2
+ {
+ \if_meaning:w #1 \scan_stop:
+ \exp_after:wN \use_iii:nnn
+ \fi:
+ \use_i:nn { #1 #2 }
+ }
+\cs_gset:Npn \cs_if_exist_use:cF #1
+ { \cs_if_exist_use:cTF {#1} {} }
+\cs_gset:Npn \cs_if_exist_use:cT #1#2
+ { \cs_if_exist_use:cTF {#1} {#2} {} }
+\cs_gset:Npn \cs_if_exist_use:c #1
+ { \cs_if_exist_use:cTF {#1} {} {} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Preliminaries for new functions}
+%
+% We provide two kinds of functions that can be used to define
+% control sequences. On the one hand we have functions that check
+% if their argument doesn't already exist, they are called
+% |\..._new|. The second type of defining functions doesn't check
+% if the argument is already defined.
+%
+% Before we can define them, we need some auxiliary macros that allow
+% us to generate error messages. The next few definitions here are
+% only temporary, they will be redefined later on.
+%
+% \begin{macro}[documented-as = \msg_error:nnnn]
+% {\msg_error:nnee, \msg_error:nne, \msg_error:nn}
+% If an internal error occurs before \LaTeX3 has loaded \pkg{l3msg} then
+% the code should issue a usable if terse error message and halt. This
+% can only happen if a coding error is made by the team, so this is
+% a reasonable response. Setting the \tn{newlinechar} is needed, to
+% turn |^^J| into a proper line break in plain \TeX{}.
+% \begin{macrocode}
+\cs_gset_protected:Npn \msg_error:nnee #1#2#3#4
+ {
+ \tex_newlinechar:D = `\^^J \scan_stop:
+ \tex_errmessage:D
+ {
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!~! ^^J
+ Argh,~internal~LaTeX3~error! ^^J ^^J
+ Module ~ #1 , ~ message~name~"#2": ^^J
+ Arguments~'#3'~and~'#4' ^^J ^^J
+ This~is~one~for~The~LaTeX3~Project:~bailing~out
+ }
+ \tex_end:D
+ }
+\cs_gset_protected:Npn \msg_error:nne #1#2#3
+ { \msg_error:nnee {#1} {#2} {#3} { } }
+\cs_gset_protected:Npn \msg_error:nn #1#2
+ { \msg_error:nnee {#1} {#2} { } { } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\msg_line_context:}
+% Another one from \pkg{l3msg} which will be altered later.
+% \begin{macrocode}
+\cs_gset:Npn \msg_line_context:
+ { on~line~ \tex_the:D \tex_inputlineno:D }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[documented-as=\iow_log:n]{\iow_log:e, \iow_term:e}
+% We define a routine to write only to the log file. And a
+% similar one for writing to both the log file and the terminal.
+% These will be redefined later by \pkg{l3file}.
+% \begin{macrocode}
+\cs_gset_protected:Npn \iow_log:e
+ { \tex_immediate:D \tex_write:D -1 }
+\cs_gset_protected:Npn \iow_term:e
+ { \tex_immediate:D \tex_write:D 16 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_chk_if_free_cs:N, \__kernel_chk_if_free_cs:c}
+% This command is called by \cs{cs_new_nopar:Npn} and \cs{cs_new_eq:NN}
+% \emph{etc.}\
+% to make sure that the argument sequence is not already in use. If
+% it is, an error is signalled. It checks if \meta{csname} is
+% undefined or \cs{scan_stop:}. Otherwise an error message is
+% issued. We have to make sure we don't put the argument into the
+% conditional processing since it may be an |\if...| type function!
+% \begin{macrocode}
+\cs_gset_protected:Npn \__kernel_chk_if_free_cs:N #1
+ {
+ \cs_if_free:NF #1
+ {
+ \msg_error:nnee { kernel } { command-already-defined }
+ { \token_to_str:N #1 } { \token_to_meaning:N #1 }
+ }
+ }
+\cs_gset_protected:Npn \__kernel_chk_if_free_cs:c
+ { \exp_args:Nc \__kernel_chk_if_free_cs:N }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Defining new functions}
+%
+% \begin{macrocode}
+%<@@=cs>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \cs_new_nopar:Npn , \cs_new_nopar:Npe , \cs_new_nopar:Npx ,
+% \cs_new:Npn , \cs_new:Npe , \cs_new:Npx ,
+% \cs_new_protected_nopar:Npn , \cs_new_protected_nopar:Npe , \cs_new_protected_nopar:Npx ,
+% \cs_new_protected:Npn , \cs_new_protected:Npe , \cs_new_protected:Npx
+% }
+% \begin{macro}{\@@_tmp:w}
+% Function which check that the control sequence is free before
+% defining it.
+% \begin{macrocode}
+\cs_set:Npn \@@_tmp:w #1#2
+ {
+ \cs_gset_protected:Npn #1 ##1
+ {
+ \__kernel_chk_if_free_cs:N ##1
+ #2 ##1
+ }
+ }
+\@@_tmp:w \cs_new_nopar:Npn \cs_gset_nopar:Npn
+\@@_tmp:w \cs_new_nopar:Npe \cs_gset_nopar:Npe
+\@@_tmp:w \cs_new_nopar:Npx \cs_gset_nopar:Npx
+\@@_tmp:w \cs_new:Npn \cs_gset:Npn
+\@@_tmp:w \cs_new:Npe \cs_gset:Npe
+\@@_tmp:w \cs_new:Npx \cs_gset:Npx
+\@@_tmp:w \cs_new_protected_nopar:Npn \cs_gset_protected_nopar:Npn
+\@@_tmp:w \cs_new_protected_nopar:Npe \cs_gset_protected_nopar:Npe
+\@@_tmp:w \cs_new_protected_nopar:Npx \cs_gset_protected_nopar:Npx
+\@@_tmp:w \cs_new_protected:Npn \cs_gset_protected:Npn
+\@@_tmp:w \cs_new_protected:Npe \cs_gset_protected:Npe
+\@@_tmp:w \cs_new_protected:Npx \cs_gset_protected:Npx
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[documented-as=\cs_set_nopar:Npn]
+% {
+% \cs_set_nopar:cpn , \cs_set_nopar:cpe , \cs_set_nopar:cpx ,
+% \cs_gset_nopar:cpn , \cs_gset_nopar:cpe , \cs_gset_nopar:cpx ,
+% \cs_new_nopar:cpn , \cs_new_nopar:cpe , \cs_new_nopar:cpx
+% }
+% Like \cs{cs_set_nopar:Npn} and \cs{cs_new_nopar:Npn}, except that the
+% first argument consists of the sequence of characters that should
+% be used to form the name of the desired control sequence (the |c|
+% stands for csname argument, see the expansion module). Global
+% versions are also provided.
+%
+% \cs{cs_set_nopar:cpn}\meta{string}\meta{rep-text} turns \meta{string}
+% into a csname and then assigns \meta{rep-text} to it by using
+% \cs{cs_set_nopar:Npn}. This means that there might be a parameter
+% string between the two arguments.
+% \begin{macrocode}
+\cs_set:Npn \@@_tmp:w #1#2
+ { \cs_new_protected_nopar:Npn #1 { \exp_args:Nc #2 } }
+\@@_tmp:w \cs_set_nopar:cpn \cs_set_nopar:Npn
+\@@_tmp:w \cs_set_nopar:cpe \cs_set_nopar:Npe
+\@@_tmp:w \cs_set_nopar:cpx \cs_set_nopar:Npx
+\@@_tmp:w \cs_gset_nopar:cpn \cs_gset_nopar:Npn
+\@@_tmp:w \cs_gset_nopar:cpe \cs_gset_nopar:Npe
+\@@_tmp:w \cs_gset_nopar:cpx \cs_gset_nopar:Npx
+\@@_tmp:w \cs_new_nopar:cpn \cs_new_nopar:Npn
+\@@_tmp:w \cs_new_nopar:cpe \cs_new_nopar:Npe
+\@@_tmp:w \cs_new_nopar:cpx \cs_new_nopar:Npx
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[documented-as=\cs_set:Npn]
+% {
+% \cs_set:cpn , \cs_set:cpe , \cs_set:cpx ,
+% \cs_gset:cpn , \cs_gset:cpe , \cs_gset:cpx ,
+% \cs_new:cpn , \cs_new:cpe , \cs_new:cpx
+% }
+% Variants of the \cs{cs_set:Npn} versions which make a csname out
+% of the first arguments. We may also do this globally.
+% \begin{macrocode}
+\@@_tmp:w \cs_set:cpn \cs_set:Npn
+\@@_tmp:w \cs_set:cpe \cs_set:Npe
+\@@_tmp:w \cs_set:cpx \cs_set:Npx
+\@@_tmp:w \cs_gset:cpn \cs_gset:Npn
+\@@_tmp:w \cs_gset:cpe \cs_gset:Npe
+\@@_tmp:w \cs_gset:cpx \cs_gset:Npx
+\@@_tmp:w \cs_new:cpn \cs_new:Npn
+\@@_tmp:w \cs_new:cpe \cs_new:Npe
+\@@_tmp:w \cs_new:cpx \cs_new:Npx
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[documented-as=\cs_set_protected_nopar:Npn]
+% {
+% \cs_set_protected_nopar:cpn , \cs_set_protected_nopar:cpe , \cs_set_protected_nopar:cpx ,
+% \cs_gset_protected_nopar:cpn , \cs_gset_protected_nopar:cpe , \cs_gset_protected_nopar:cpx ,
+% \cs_new_protected_nopar:cpn , \cs_new_protected_nopar:cpe , \cs_new_protected_nopar:cpx
+% }
+% Variants of the \cs{cs_set_protected_nopar:Npn} versions which make
+% a csname out of the first arguments. We may also do this globally.
+% \begin{macrocode}
+\@@_tmp:w \cs_set_protected_nopar:cpn \cs_set_protected_nopar:Npn
+\@@_tmp:w \cs_set_protected_nopar:cpe \cs_set_protected_nopar:Npe
+\@@_tmp:w \cs_set_protected_nopar:cpx \cs_set_protected_nopar:Npx
+\@@_tmp:w \cs_gset_protected_nopar:cpn \cs_gset_protected_nopar:Npn
+\@@_tmp:w \cs_gset_protected_nopar:cpe \cs_gset_protected_nopar:Npe
+\@@_tmp:w \cs_gset_protected_nopar:cpx \cs_gset_protected_nopar:Npx
+\@@_tmp:w \cs_new_protected_nopar:cpn \cs_new_protected_nopar:Npn
+\@@_tmp:w \cs_new_protected_nopar:cpe \cs_new_protected_nopar:Npe
+\@@_tmp:w \cs_new_protected_nopar:cpx \cs_new_protected_nopar:Npx
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[documented-as=\cs_set_protected:Npn]
+% {
+% \cs_set_protected:cpn , \cs_set_protected:cpe , \cs_set_protected:cpx ,
+% \cs_gset_protected:cpn , \cs_gset_protected:cpe , \cs_gset_protected:cpx ,
+% \cs_new_protected:cpn , \cs_new_protected:cpe , \cs_new_protected:cpx
+% }
+% Variants of the \cs{cs_set_protected:Npn} versions which make a csname
+% out of the first arguments. We may also do this globally.
+% \begin{macrocode}
+\@@_tmp:w \cs_set_protected:cpn \cs_set_protected:Npn
+\@@_tmp:w \cs_set_protected:cpe \cs_set_protected:Npe
+\@@_tmp:w \cs_set_protected:cpx \cs_set_protected:Npx
+\@@_tmp:w \cs_gset_protected:cpn \cs_gset_protected:Npn
+\@@_tmp:w \cs_gset_protected:cpe \cs_gset_protected:Npe
+\@@_tmp:w \cs_gset_protected:cpx \cs_gset_protected:Npx
+\@@_tmp:w \cs_new_protected:cpn \cs_new_protected:Npn
+\@@_tmp:w \cs_new_protected:cpe \cs_new_protected:Npe
+\@@_tmp:w \cs_new_protected:cpx \cs_new_protected:Npx
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Copying definitions}
+%
+% \begin{macro}
+% {
+% \cs_set_eq:NN , \cs_set_eq:cN , \cs_set_eq:Nc , \cs_set_eq:cc ,
+% \cs_gset_eq:NN , \cs_gset_eq:cN , \cs_gset_eq:Nc , \cs_gset_eq:cc ,
+% \cs_new_eq:NN , \cs_new_eq:cN , \cs_new_eq:Nc , \cs_new_eq:cc
+% }
+% These macros allow us to copy the definition of a control sequence
+% to another control sequence.
+%
+% The |=| sign allows us to define funny char tokens like |=| itself
+% or \verb*| | with this function. For the definition of
+% |\c_space_char{~}| to work we need the |~| after the |=|.
+%
+% \cs{cs_set_eq:NN} is long to avoid problems with a literal argument
+% of \cs{par}. While \cs{cs_new_eq:NN} will probably never be correct
+% with a first argument of \cs{par}, define it long in order to throw
+% an \enquote{already defined} error rather than
+% \enquote{runaway argument}.
+% \begin{macrocode}
+\cs_new_protected:Npn \cs_set_eq:NN #1 { \tex_let:D #1 =~ }
+\cs_new_protected:Npn \cs_set_eq:cN { \exp_args:Nc \cs_set_eq:NN }
+\cs_new_protected:Npn \cs_set_eq:Nc { \exp_args:NNc \cs_set_eq:NN }
+\cs_new_protected:Npn \cs_set_eq:cc { \exp_args:Ncc \cs_set_eq:NN }
+\cs_new_protected:Npn \cs_gset_eq:NN { \tex_global:D \cs_set_eq:NN }
+\cs_new_protected:Npn \cs_gset_eq:Nc { \exp_args:NNc \cs_gset_eq:NN }
+\cs_new_protected:Npn \cs_gset_eq:cN { \exp_args:Nc \cs_gset_eq:NN }
+\cs_new_protected:Npn \cs_gset_eq:cc { \exp_args:Ncc \cs_gset_eq:NN }
+\cs_new_protected:Npn \cs_new_eq:NN #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \tex_global:D \cs_set_eq:NN #1
+ }
+\cs_new_protected:Npn \cs_new_eq:cN { \exp_args:Nc \cs_new_eq:NN }
+\cs_new_protected:Npn \cs_new_eq:Nc { \exp_args:NNc \cs_new_eq:NN }
+\cs_new_protected:Npn \cs_new_eq:cc { \exp_args:Ncc \cs_new_eq:NN }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Undefining functions}
+%
+% \begin{macro}{\cs_undefine:N, \cs_undefine:c}
+% The following function is used to free the main memory from the
+% definition of some function that isn't in use any longer.
+% The \texttt{c} variant is careful not to add the control sequence
+% to the hash table if it isn't there yet, and it also avoids nesting
+% \TeX{} conditionals in case |#1| is unbalanced in this matter.
+% We optimize the case where the command exists by reducing as much as
+% possible the tokens in the conditional.
+% \begin{macrocode}
+\cs_new_protected:Npn \cs_undefine:N #1
+ { \cs_gset_eq:NN #1 \tex_undefined:D }
+\cs_new_protected:Npn \cs_undefine:c #1
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \else:
+ \use_i:nnnn
+ \fi:
+ \exp_args:Nc \cs_undefine:N {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Generating parameter text from argument count}
+%
+% \begin{macrocode}
+%<@@=cs>
+% \end{macrocode}
+%
+% \begin{macro}{\__kernel_cs_parm_from_arg_count:nnF}
+% \begin{macro}{\@@_parm_from_arg_count_test:nnF}
+% \LaTeX3 provides shorthands to define control sequences and
+% conditionals with a simple parameter text, derived directly from the
+% signature, or more generally from knowing the number of arguments,
+% between~$0$ and~$9$. This function expands to its first argument,
+% untouched, followed by a brace group containing the parameter text
+% |{#|$1$\ldots{}|#|$n$|}|, where $n$ is the result of evaluating the
+% second argument (as described in \cs{int_eval:n}). If the second
+% argument gives a result outside the range $[0,9]$, the third
+% argument is returned instead, normally an error message. Some of
+% the functions use here are not defined yet, but will be defined
+% before this function is called.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_cs_parm_from_arg_count:nnF #1#2
+ {
+ \exp_args:Ne \@@_parm_from_arg_count_test:nnF
+ {
+ \exp_after:wN \exp_not:n
+ \if_case:w \int_eval:n {#2}
+ { }
+ \or: { ##1 }
+ \or: { ##1##2 }
+ \or: { ##1##2##3 }
+ \or: { ##1##2##3##4 }
+ \or: { ##1##2##3##4##5 }
+ \or: { ##1##2##3##4##5##6 }
+ \or: { ##1##2##3##4##5##6##7 }
+ \or: { ##1##2##3##4##5##6##7##8 }
+ \or: { ##1##2##3##4##5##6##7##8##9 }
+ \else: { \c_false_bool }
+ \fi:
+ }
+ {#1}
+ }
+\cs_new_protected:Npn \@@_parm_from_arg_count_test:nnF #1#2
+ {
+ \if_meaning:w \c_false_bool #1
+ \exp_after:wN \use_ii:nn
+ \else:
+ \exp_after:wN \use_i:nn
+ \fi:
+ { #2 {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Defining functions from a given number of arguments}
+%
+% \begin{macrocode}
+%<@@=cs>
+% \end{macrocode}
+%
+% \begin{macro}[EXP]{\@@_count_signature:N, \@@_count_signature:c}
+% \begin{macro}[EXP]{\@@_count_signature:n}
+% \begin{macro}[EXP]{\@@_count_signature:nnN}
+% Counting the number of tokens in the signature, \emph{i.e.}, the
+% number of arguments the function should take. Since this is not
+% used in any time-critical function, we simply use \cs{tl_count:n} if
+% there is a signature, otherwise $-1$ arguments to signal an error.
+% We need a variant form right away.
+% \begin{macrocode}
+\cs_new:Npn \@@_count_signature:N #1
+ { \exp_args:Nf \@@_count_signature:n { \cs_split_function:N #1 } }
+\cs_new:Npn \@@_count_signature:n #1
+ { \int_eval:n { \@@_count_signature:nnN #1 } }
+\cs_new:Npn \@@_count_signature:nnN #1#2#3
+ {
+ \if_meaning:w \c_true_bool #3
+ \tl_count:n {#2}
+ \else:
+ -1
+ \fi:
+ }
+\cs_new:Npn \@@_count_signature:c
+ { \exp_args:Nc \@@_count_signature:N }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \cs_generate_from_arg_count:NNnn,
+% \cs_generate_from_arg_count:cNnn,
+% \cs_generate_from_arg_count:Ncnn
+% }
+% We provide a constructor function for defining functions with a
+% given number of arguments. For this we need to choose the correct
+% parameter text and then use that when defining. Since \TeX{}
+% supports from zero to nine arguments, we use a simple switch to
+% choose the correct parameter text, ensuring the result is returned
+% after finishing the conditional. If it is not between zero and
+% nine, we throw an error.
+%
+% 1: function to define, 2: with what to define it, 3: the number of
+% args it requires and 4: the replacement text
+% \begin{macrocode}
+\cs_new_protected:Npn \cs_generate_from_arg_count:NNnn #1#2#3#4
+ {
+ \__kernel_cs_parm_from_arg_count:nnF { \use:nnn #2 #1 } {#3}
+ {
+ \msg_error:nnee { kernel } { bad-number-of-arguments }
+ { \token_to_str:N #1 } { \int_eval:n {#3} }
+ \use_none:n
+ }
+ {#4}
+ }
+% \end{macrocode}
+% A variant form we need right away, plus one which is used elsewhere but
+% which is most logically created here.
+% \begin{macrocode}
+\cs_new_protected:Npn \cs_generate_from_arg_count:cNnn
+ { \exp_args:Nc \cs_generate_from_arg_count:NNnn }
+\cs_new_protected:Npn \cs_generate_from_arg_count:Ncnn
+ { \exp_args:NNc \cs_generate_from_arg_count:NNnn }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Using the signature to define functions}
+%
+% \begin{macrocode}
+%<@@=cs>
+% \end{macrocode}
+%
+% We can now combine some of the tools we have to provide a simple
+% interface for defining functions, where the number of arguments is
+% read from the signature. For instance,
+% |\cs_set:Nn \foo_bar:nn {#1,#2}|.
+%
+% \begin{macro}
+% {
+% \cs_set:Nn , \cs_set:Ne , \cs_set:Nx ,
+% \cs_set_nopar:Nn , \cs_set_nopar:Ne , \cs_set_nopar:Nx ,
+% \cs_set_protected:Nn , \cs_set_protected:Ne , \cs_set_protected:Nx ,
+% \cs_set_protected_nopar:Nn , \cs_set_protected_nopar:Ne , \cs_set_protected_nopar:Nx ,
+% \cs_gset:Nn , \cs_gset:Ne , \cs_gset:Nx ,
+% \cs_gset_nopar:Nn , \cs_gset_nopar:Ne , \cs_gset_nopar:Nx ,
+% \cs_gset_protected:Nn , \cs_gset_protected:Ne , \cs_gset_protected:Nx ,
+% \cs_gset_protected_nopar:Nn , \cs_gset_protected_nopar:Ne , \cs_gset_protected_nopar:Nx ,
+% \cs_new:Nn , \cs_new:Ne , \cs_new:Nx ,
+% \cs_new_nopar:Nn , \cs_new_nopar:Ne , \cs_new_nopar:Nx ,
+% \cs_new_protected:Nn , \cs_new_protected:Ne , \cs_new_protected:Nx ,
+% \cs_new_protected_nopar:Nn , \cs_new_protected_nopar:Ne , \cs_new_protected_nopar:Nx ,
+% }
+% We want to define \cs{cs_set:Nn} as
+% \begin{verbatim}
+% \cs_set_protected:Npn \cs_set:Nn #1#2
+% {
+% \cs_generate_from_arg_count:NNnn #1 \cs_set:Npn
+% { \@@_count_signature:N #1 } {#2}
+% }
+% \end{verbatim}
+% In short, to define \cs{cs_set:Nn} we need just use \cs{cs_set:Npn},
+% everything else is the same for each variant. Therefore, we can
+% make it simpler by temporarily defining a function to do this for
+% us.
+% \begin{macrocode}
+\cs_set:Npn \@@_tmp:w #1#2#3
+ {
+ \cs_new_protected:cpx { cs_ #1 : #2 }
+ {
+ \exp_not:N \@@_generate_from_signature:NNn
+ \exp_after:wN \exp_not:N \cs:w cs_ #1 : #3 \cs_end:
+ }
+ }
+\cs_new_protected:Npn \@@_generate_from_signature:NNn #1#2
+ {
+ \use:e
+ {
+ \@@_generate_from_signature:nnNNNn
+ \cs_split_function:N #2
+ }
+ #1 #2
+ }
+\cs_new_protected:Npn \@@_generate_from_signature:nnNNNn #1#2#3#4#5#6
+ {
+ \bool_if:NTF #3
+ {
+ \cs_set_nopar:Npx \@@_tmp:w
+ { \tl_map_function:nN {#2} \@@_generate_from_signature:n }
+ \tl_if_empty:oF \@@_tmp:w
+ {
+ \msg_error:nneee { kernel } { non-base-function }
+ { \token_to_str:N #5 } {#2} { \@@_tmp:w }
+ }
+ \cs_generate_from_arg_count:NNnn
+ #5 #4 { \tl_count:n {#2} } {#6}
+ }
+ {
+ \msg_error:nne { kernel } { missing-colon }
+ { \token_to_str:N #5 }
+ }
+ }
+\cs_new:Npn \@@_generate_from_signature:n #1
+ {
+ \if:w n #1 \else: \if:w N #1 \else:
+ \if:w T #1 \else: \if:w F #1 \else: #1 \fi: \fi: \fi: \fi:
+ }
+% \end{macrocode}
+% Then we define the 24 variants beginning with |N|.
+% \begin{macrocode}
+\@@_tmp:w { set } { Nn } { Npn }
+\@@_tmp:w { set } { Ne } { Npe }
+\@@_tmp:w { set } { Nx } { Npx }
+\@@_tmp:w { set_nopar } { Nn } { Npn }
+\@@_tmp:w { set_nopar } { Ne } { Npe }
+\@@_tmp:w { set_nopar } { Nx } { Npx }
+\@@_tmp:w { set_protected } { Nn } { Npn }
+\@@_tmp:w { set_protected } { Ne } { Npe }
+\@@_tmp:w { set_protected } { Nx } { Npx }
+\@@_tmp:w { set_protected_nopar } { Nn } { Npn }
+\@@_tmp:w { set_protected_nopar } { Ne } { Npe }
+\@@_tmp:w { set_protected_nopar } { Nx } { Npx }
+\@@_tmp:w { gset } { Nn } { Npn }
+\@@_tmp:w { gset } { Ne } { Npe }
+\@@_tmp:w { gset } { Nx } { Npx }
+\@@_tmp:w { gset_nopar } { Nn } { Npn }
+\@@_tmp:w { gset_nopar } { Ne } { Npe }
+\@@_tmp:w { gset_nopar } { Nx } { Npx }
+\@@_tmp:w { gset_protected } { Nn } { Npn }
+\@@_tmp:w { gset_protected } { Ne } { Npe }
+\@@_tmp:w { gset_protected } { Nx } { Npx }
+\@@_tmp:w { gset_protected_nopar } { Nn } { Npn }
+\@@_tmp:w { gset_protected_nopar } { Ne } { Npe }
+\@@_tmp:w { gset_protected_nopar } { Nx } { Npx }
+\@@_tmp:w { new } { Nn } { Npn }
+\@@_tmp:w { new } { Ne } { Npe }
+\@@_tmp:w { new } { Nx } { Npx }
+\@@_tmp:w { new_nopar } { Nn } { Npn }
+\@@_tmp:w { new_nopar } { Ne } { Npe }
+\@@_tmp:w { new_nopar } { Nx } { Npx }
+\@@_tmp:w { new_protected } { Nn } { Npn }
+\@@_tmp:w { new_protected } { Ne } { Npe }
+\@@_tmp:w { new_protected } { Nx } { Npx }
+\@@_tmp:w { new_protected_nopar } { Nn } { Npn }
+\@@_tmp:w { new_protected_nopar } { Ne } { Npe }
+\@@_tmp:w { new_protected_nopar } { Nx } { Npx }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[documented-as=\cs_set:Nn]
+% {
+% \cs_set:cn , \cs_set:ce , \cs_set:cx ,
+% \cs_set_nopar:cn , \cs_set_nopar:ce , \cs_set_nopar:cx ,
+% \cs_set_protected:cn , \cs_set_protected:ce , \cs_set_protected:cx ,
+% \cs_set_protected_nopar:cn , \cs_set_protected_nopar:ce , \cs_set_protected_nopar:cx ,
+% \cs_gset:cn , \cs_gset:ce , \cs_gset:cx ,
+% \cs_gset_nopar:cn , \cs_gset_nopar:ce , \cs_gset_nopar:cx ,
+% \cs_gset_protected:cn , \cs_gset_protected:ce , \cs_gset_protected:cx ,
+% \cs_gset_protected_nopar:cn , \cs_gset_protected_nopar:ce , \cs_gset_protected_nopar:cx ,
+% \cs_new:cn , \cs_new:ce , \cs_new:cx ,
+% \cs_new_nopar:cn , \cs_new_nopar:ce , \cs_new_nopar:cx ,
+% \cs_new_protected:cn , \cs_new_protected:ce , \cs_new_protected:cx ,
+% \cs_new_protected_nopar:cn , \cs_new_protected_nopar:ce , \cs_new_protected_nopar:cx ,
+% }
+% The 24 |c| variants simply use \cs{exp_args:Nc}.
+% \begin{macrocode}
+\cs_set:Npn \@@_tmp:w #1#2
+ {
+ \cs_new_protected:cpx { cs_ #1 : c #2 }
+ {
+ \exp_not:N \exp_args:Nc
+ \exp_after:wN \exp_not:N \cs:w cs_ #1 : N #2 \cs_end:
+ }
+ }
+\@@_tmp:w { set } { n }
+\@@_tmp:w { set } { e }
+\@@_tmp:w { set } { x }
+\@@_tmp:w { set_nopar } { n }
+\@@_tmp:w { set_nopar } { e }
+\@@_tmp:w { set_nopar } { x }
+\@@_tmp:w { set_protected } { n }
+\@@_tmp:w { set_protected } { e }
+\@@_tmp:w { set_protected } { x }
+\@@_tmp:w { set_protected_nopar } { n }
+\@@_tmp:w { set_protected_nopar } { e }
+\@@_tmp:w { set_protected_nopar } { x }
+\@@_tmp:w { gset } { n }
+\@@_tmp:w { gset } { e }
+\@@_tmp:w { gset } { x }
+\@@_tmp:w { gset_nopar } { n }
+\@@_tmp:w { gset_nopar } { e }
+\@@_tmp:w { gset_nopar } { x }
+\@@_tmp:w { gset_protected } { n }
+\@@_tmp:w { gset_protected } { e }
+\@@_tmp:w { gset_protected } { x }
+\@@_tmp:w { gset_protected_nopar } { n }
+\@@_tmp:w { gset_protected_nopar } { e }
+\@@_tmp:w { gset_protected_nopar } { x }
+\@@_tmp:w { new } { n }
+\@@_tmp:w { new } { e }
+\@@_tmp:w { new } { x }
+\@@_tmp:w { new_nopar } { n }
+\@@_tmp:w { new_nopar } { e }
+\@@_tmp:w { new_nopar } { x }
+\@@_tmp:w { new_protected } { n }
+\@@_tmp:w { new_protected } { e }
+\@@_tmp:w { new_protected } { x }
+\@@_tmp:w { new_protected_nopar } { n }
+\@@_tmp:w { new_protected_nopar } { e }
+\@@_tmp:w { new_protected_nopar } { x }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Checking control sequence equality}
+%
+% \begin{macro}[pTF, EXP]
+% {\cs_if_eq:NN, \cs_if_eq:cN, \cs_if_eq:Nc, \cs_if_eq:cc}
+% Check if two control sequences are identical.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \cs_if_eq:NN #1#2 { p , T , F , TF }
+ {
+ \if_meaning:w #1#2
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\cs_new:Npn \cs_if_eq_p:cN { \exp_args:Nc \cs_if_eq_p:NN }
+\cs_new:Npn \cs_if_eq:cNTF { \exp_args:Nc \cs_if_eq:NNTF }
+\cs_new:Npn \cs_if_eq:cNT { \exp_args:Nc \cs_if_eq:NNT }
+\cs_new:Npn \cs_if_eq:cNF { \exp_args:Nc \cs_if_eq:NNF }
+\cs_new:Npn \cs_if_eq_p:Nc { \exp_args:NNc \cs_if_eq_p:NN }
+\cs_new:Npn \cs_if_eq:NcTF { \exp_args:NNc \cs_if_eq:NNTF }
+\cs_new:Npn \cs_if_eq:NcT { \exp_args:NNc \cs_if_eq:NNT }
+\cs_new:Npn \cs_if_eq:NcF { \exp_args:NNc \cs_if_eq:NNF }
+\cs_new:Npn \cs_if_eq_p:cc { \exp_args:Ncc \cs_if_eq_p:NN }
+\cs_new:Npn \cs_if_eq:ccTF { \exp_args:Ncc \cs_if_eq:NNTF }
+\cs_new:Npn \cs_if_eq:ccT { \exp_args:Ncc \cs_if_eq:NNT }
+\cs_new:Npn \cs_if_eq:ccF { \exp_args:Ncc \cs_if_eq:NNF }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Diagnostic functions}
+%
+% \begin{macrocode}
+%<@@=kernel>
+% \end{macrocode}
+%
+% \begin{macro}{\@@_chk_defined:NT}
+% Error if the variable |#1| is not defined.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_chk_defined:NT #1#2
+ {
+ \cs_if_exist:NTF #1
+ {#2}
+ {
+ \msg_error:nne { kernel } { variable-not-defined }
+ { \token_to_str:N #1 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_register_show:N, \@@_register_show:c, \@@_register_log:N, \@@_register_log:c}
+% \begin{macro}{\@@_register_show_aux:NN, \@@_register_show_aux:nNN}
+% Simply using the \tn{showthe} primitive does not allow for
+% line-wrapping, so instead use \cs{tl_show:n} and \cs{tl_log:n} (defined
+% in \pkg{l3tl} and that performs line-wrapping). This displays
+% |>~|\meta{variable}|=|\meta{value}. We expand the value before-hand
+% as otherwise some integers (such as \tn{currentgrouplevel} or
+% \tn{currentgrouptype}) altered by the line-wrapping code would show
+% wrong values.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_register_show:N
+ { \@@_register_show_aux:NN \tl_show:n }
+\cs_new_protected:Npn \@@_register_show:c
+ { \exp_args:Nc \@@_register_show:N }
+\cs_new_protected:Npn \@@_register_log:N
+ { \@@_register_show_aux:NN \tl_log:n }
+\cs_new_protected:Npn \@@_register_log:c
+ { \exp_args:Nc \@@_register_log:N }
+\cs_new_protected:Npn \@@_register_show_aux:NN #1#2
+ {
+ \@@_chk_defined:NT #2
+ {
+ \exp_args:No \@@_register_show_aux:nNN
+ { \tex_the:D #2 } #2 #1
+ }
+ }
+\cs_new_protected:Npn \@@_register_show_aux:nNN #1#2#3
+ { \exp_args:No #3 { \token_to_str:N #2 = #1 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_show:N, \cs_show:c, \cs_log:N, \cs_log:c, \@@_show:NN}
+% Some control sequences have a very long name or meaning. Thus,
+% simply using \TeX{}'s primitive \tn{show} could lead to overlong
+% lines. The output of this primitive is mimicked to some extent,
+% then the re-built string is given to \cs{tl_show:n} or \cs{tl_log:n} for
+% line-wrapping. We must expand the meaning before passing it to the
+% wrapping code as otherwise we would wrongly see the definitions that
+% are in place there. To get correct escape characters, set the
+% \tn{escapechar} in a group; this also localizes the assignment
+% performed by \texttt{e}-expansion. The \cs{cs_show:c} and \cs{cs_log:c} commands
+% convert their argument to a control sequence within a group to avoid
+% showing \tn{relax} for undefined control sequences.
+% \begin{macrocode}
+\cs_new_protected:Npn \cs_show:N { \@@_show:NN \tl_show:n }
+\cs_new_protected:Npn \cs_show:c
+ { \group_begin: \exp_args:NNc \group_end: \cs_show:N }
+\cs_new_protected:Npn \cs_log:N { \@@_show:NN \tl_log:n }
+\cs_new_protected:Npn \cs_log:c
+ { \group_begin: \exp_args:NNc \group_end: \cs_log:N }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \group_begin:
+ \int_set:Nn \tex_escapechar:D { `\\ }
+ \exp_args:NNe
+ \group_end:
+ #1 { \token_to_str:N #2 = \cs_meaning:N #2 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\group_show_list:, \group_log_list:, \@@_group_show:NN}
+% Wrapper around \tn{showgroups}. Getting \TeX{} to write to the log
+% without interruption the run is done by altering the interaction
+% mode.
+% \begin{macrocode}
+\cs_new_protected:Npn \group_show_list:
+ { \@@_group_show:NN \use_none:n 1 }
+\cs_new_protected:Npn \group_log_list:
+ { \@@_group_show:NN \int_gzero:N 0 }
+\cs_new_protected:Npn \@@_group_show:NN #1#2
+ {
+ \use:e
+ {
+ #1 \tex_interactionmode:D
+ \int_set:Nn \tex_tracingonline:D {#2}
+ \int_set:Nn \tex_errorcontextlines:D { -1 }
+ \exp_not:N \exp_after:wN \scan_stop:
+ \tex_showgroups:D
+ \int_gset:Nn \tex_interactionmode:D
+ { \int_use:N \tex_interactionmode:D }
+ \int_set:Nn \tex_tracingonline:D
+ { \int_use:N \tex_tracingonline:D }
+ \int_set:Nn \tex_errorcontextlines:D
+ { \int_use:N \tex_errorcontextlines:D }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Decomposing a macro definition}
+%
+% \begin{macro}{\cs_prefix_spec:N}
+% \begin{macro}{\cs_parameter_spec:N}
+% \begin{macro}{\cs_replacement_spec:N}
+% \begin{macro}{\@@_prefix_arg_replacement:wN}
+% We sometimes want to test if a control sequence can be expanded to
+% reveal a hidden value. However, we cannot just expand the macro
+% blindly as it may have arguments and none might be
+% present. Therefore we define these functions to pick either the
+% prefix(es), the parameter specification, or the replacement text from
+% a macro. All of this information is returned as characters with
+% catcode~$12$. If the token in question isn't a macro, the token
+% \cs{scan_stop:} is returned instead.
+% \begin{macrocode}
+\use:e
+ {
+ \exp_not:n { \cs_new:Npn \@@_prefix_arg_replacement:wN #1 }
+ \tl_to_str:n { macro : } \exp_not:n { #2 -> #3 \s_@@_stop #4 }
+ }
+ { #4 {#1} {#2} {#3} }
+\cs_new:Npn \cs_prefix_spec:N #1
+ {
+ \token_if_macro:NTF #1
+ {
+ \exp_after:wN \@@_prefix_arg_replacement:wN
+ \token_to_meaning:N #1 \s_@@_stop \use_i:nnn
+ }
+ { \scan_stop: }
+ }
+\cs_new:Npn \cs_parameter_spec:N #1
+ {
+ \token_if_macro:NTF #1
+ {
+ \exp_after:wN \@@_prefix_arg_replacement:wN
+ \token_to_meaning:N #1 \s_@@_stop \use_ii:nnn
+ }
+ { \scan_stop: }
+ }
+\cs_new:Npn \cs_replacement_spec:N #1
+ {
+ \token_if_macro:NTF #1
+ {
+ \exp_after:wN \@@_prefix_arg_replacement:wN
+ \token_to_meaning:N #1 \s_@@_stop \use_iii:nnn
+ }
+ { \scan_stop: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Doing nothing functions}
+%
+% \begin{macro}[EXP]{\prg_do_nothing:}
+% This does not fit anywhere else!
+% \begin{macrocode}
+\cs_new:Npn \prg_do_nothing: { }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Breaking out of mapping functions}
+%
+% \begin{macrocode}
+%<@@=prg>
+% \end{macrocode}
+%
+% \begin{macro}[EXP]{\prg_break_point:Nn, \prg_map_break:Nn}
+% In inline mappings, the nesting level must be reset
+% at the end of the mapping, even when the user decides
+% to break out. This is done by putting the code that
+% must be performed as an argument of \cs{@@_break_point:Nn}.
+% The breaking functions are then defined to jump to
+% that point and perform the argument of \cs{@@_break_point:Nn},
+% before the user's code (if any). There is a check that we close the
+% correct loop, otherwise we continue breaking.
+% \begin{macrocode}
+\cs_new_eq:NN \prg_break_point:Nn \use_ii:nn
+\cs_new:Npn \prg_map_break:Nn #1#2#3 \prg_break_point:Nn #4#5
+ {
+ #5
+ \if_meaning:w #1 #4
+ \exp_after:wN \use_iii:nnn
+ \fi:
+ \prg_map_break:Nn #1 {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prg_break_point:}
+% \begin{macro}{\prg_break:, \prg_break:n}
+% Very simple analogues of \cs{prg_break_point:Nn} and
+% \cs{prg_map_break:Nn}, for use in fast short-term recursions which
+% are not mappings, do not need to support nesting, and in which
+% nothing has to be done at the end of the loop.
+% \begin{macrocode}
+\cs_new_eq:NN \prg_break_point: \prg_do_nothing:
+\cs_new:Npn \prg_break: #1 \prg_break_point: { }
+\cs_new:Npn \prg_break:n #1#2 \prg_break_point: {#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Starting a paragraph}
+%
+% \begin{macro}{\mode_leave_vertical:}
+% The approach here is different to that used by \LaTeXe{} or plain \TeX{},
+% which unbox a void box to force horizontal mode. That inserts the
+% \tn{everypar} tokens \emph{before} the re-inserted unboxing tokens. The
+% approach here uses a protected macro, equivalent to the \tn{quitvmode}
+% primitive. In vertical mode, the \tn{indent} primitive is inserted:
+% this will switch to horizontal mode and insert \tn{everypar} tokens and
+% nothing else. Unlike the \LaTeXe{} version, the availability of \eTeX{}
+% means using a mode test can be done at for example the start of an
+% \tn{halign}.
+% \begin{macrocode}
+\cs_new_protected:Npn \mode_leave_vertical:
+ {
+ \if_mode_vertical:
+ \exp_after:wN \tex_indent:D
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3bitset.dtx b/macros/latex-dev/required/l3kernel/l3bitset.dtx
new file mode 100644
index 0000000000..b0bd996d26
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3bitset.dtx
@@ -0,0 +1,629 @@
+% \iffalse meta-comment
+%
+%% File: l3bitset.dtx
+%
+% Copyright (C) 2020-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+% \title{^^A
+% The \pkg{l3bitset} module\\ Bitsets^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% This module defines and implements the data type \texttt{bitset}, a vector of
+% bits. The size of the vector may grow dynamically.
+% Individual bits can be set and unset by names pointing to an index position.
+% The names |1|, |2|, |3|, \ldots\ are predeclared and point to the
+% index positions $1$, $2$, $3$,\ldots. More names can be added and existing names can
+% be changed.
+% The index is like all other indices in \pkg{expl3} modules \emph{1-based}.
+% A \texttt{bitset} can be output as binary number or---as needed e.g. in a
+% PDF dictionary---as decimal (arabic) number.
+% Currently only a small subset of the functions provided by the \pkg{bitset}
+% package are implemented here, mainly the functions needed to use bitsets in
+% PDF dictionaries.
+%
+% The bitset is stored as a string (but one shouldn't rely on the internal
+% representation) and so the vector size is theoretically
+% unlimited, only restricted by \TeX-memory. But the functions to set and clear
+% bits use integer functions for the index so bitsets can't be longer
+% than $2^{31} - 1$.
+% The export function
+% \cs{bitset_to_arabic:N} can use functions from the \texttt{int} module only if
+% the largest index used for this bitset is smaller than $32$, for longer
+% bitsets \texttt{fp} is used and this is slower.
+%
+% \section{Creating bitsets}
+%
+% \begin{function}[added = 2023-11-15]
+% {\bitset_new:N,\bitset_new:c,\bitset_new:Nn, \bitset_new:cn}
+% \begin{syntax}
+% \cs{bitset_new:N} \meta{bitset var} \\
+% \cs{bitset_new:Nn} \meta{bitset var}
+% ~~\{
+% ~~~~\meta{name_1} |=| \meta{index_1} |,|
+% ~~~~\meta{name_2} |=| \meta{index_2} |,| \ldots{}
+% ~~\}
+% \end{syntax}
+% Creates a new \meta{bitset var} or raises an error if the name is already taken.
+% The declaration is global. The \meta{bitset var} is initially $0$.
+%
+% Bitsets are implemented as string variables consisting of
+% \texttt{1}'s and \texttt{0}'s.
+% The rightmost number is the index position $1$, so
+% the string variable can be viewed directly as the binary number.
+% But one shouldn't rely on the internal representation, but use the
+% dedicated \cs{bitset_to_bin:N} instead to get the binary number.
+%
+% The name--index pairs given in the second
+% argument of \cs{bitset_new:Nn} declares names for some indices,
+% which can be used to set and unset bits.
+% The names |1|, |2|, |3|, \ldots\ are predeclared and point to the
+% index positions $1$, $2$, $3$, \ldots.
+%
+% \meta{index\ldots} should be a positive number or an
+% \meta{integer expression} which evaluates to a positive number.
+% The expression is evaluated when the index is used, not at declaration time.
+% The names \meta{name\ldots}
+% should be unique. Using a number as name, e.g.~|10=1|, is allowed, it
+% then overwrites the predeclared name |10|,
+% but the index position $10$ can then only be reached if some other
+% name for it exists, e.g. |ten=10|.
+% It is not necessary to give every index
+% a name, and an index can have more than one name. The named index
+% can be extended or changed with the next function.
+% \end{function}
+%
+% \begin{function}[added = 2023-11-15]
+% {\bitset_addto_named_index:Nn}
+% \begin{syntax}
+% \cs{bitset_addto_named_index:Nn} \meta{bitset var}
+% ~~\{
+% ~~~~\meta{name_1} |=| \meta{index_1} |,|
+% ~~~~\meta{name_2} |=| \meta{index_2} |,| \ldots{}
+% ~~\}
+% \end{syntax}
+% This extends or changes the name--index pairs for \meta{bitset var}
+% globally as described for \cs{bitset_new:Nn}.
+% \end{function}
+%
+% For example after these settings
+% \begin{verbatim}
+% \bitset_new:Nn \l_pdfannot_F_bitset
+% {
+% Invisible = 1,
+% Hidden = 2,
+% Print = 3,
+% NoZoom = 4,
+% NoRotate = 5,
+% NoView = 6,
+% ReadOnly = 7,
+% Locked = 8,
+% ToggleNoView = 9,
+% LockedContents = 10
+% }
+% \bitset_addto_named_index:Nn \l_pdfannot_F_bitset
+% {
+% print = 3
+% }
+% \end{verbatim}
+% it is possible to set bit $3$ by using any of these alternatives:
+% \begin{verbatim}
+% \bitset_set_true:Nn \l_pdfannot_F_bitset {Print}
+% \bitset_set_true:Nn \l_pdfannot_F_bitset {print}
+% \bitset_set_true:Nn \l_pdfannot_F_bitset {3}
+% \end{verbatim}
+%
+% \begin{function}[EXP, pTF,added = 2023-11-15]
+% {\bitset_if_exist:N, \bitset_if_exist:c}
+% \begin{syntax}
+% \cs{bitset_if_exist_p:N} \meta{bitset var}
+% \cs{bitset_if_exist:NTF} \meta{bitset var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{bitset var} exist.
+% \end{function}
+%
+% \section{Setting and unsetting bits}
+%
+% \begin{function}[added = 2023-11-15]
+% {
+% \bitset_set_true:Nn, \bitset_set_true:cn,
+% \bitset_gset_true:Nn, \bitset_gset_true:cn
+% }
+% \begin{syntax}
+% \cs{bitset_set_true:Nn} \meta{bitset var} \Arg{name}
+% \end{syntax}
+% This sets the bit of the index position represented by \Arg{name} to $1$.
+% \meta{name} should be either one of the predeclared names
+% |1|, |2|, |3|, \ldots, or one of the names added manually.
+% Index position are 1-based.
+% If needed the length of the bit vector is enlarged.
+% \end{function}
+%
+% \begin{function}[added = 2023-11-15]
+% {
+% \bitset_set_false:Nn, \bitset_set_false:cn,
+% \bitset_gset_false:Nn, \bitset_gset_false:cn
+% }
+% \begin{syntax}
+% \cs{bitset_set_false:Nn} \meta{bitset var} \Arg{name}
+% \end{syntax}
+% This unsets the bit of the index position represented by \Arg{name} (sets
+% it to $0$).
+% \meta{name} should be either one of the predeclared names
+% |1|, |2|, |3|, \ldots, or one of the names added manually.
+% The index is $1$-based. If the index position is larger
+% than the current length of the bit vector
+% nothing happens. If the leading (left most) bit is unset,
+% zeros are not trimmed but stay in the bit vector and are still shown
+% by \cs{bitset_show:N}.
+% \end{function}
+%
+% \begin{function}[added = 2023-11-15]
+% {\bitset_clear:N,\bitset_clear:c,\bitset_gclear:N,\bitset_gclear:c}
+% \begin{syntax}
+% \cs{bitset_clear:N} \meta{bitset var}
+% \end{syntax}
+% This resets the bitset to the initial state. The declared names are not changed.
+% \end{function}
+%
+% \section{Using bitsets}
+%
+% \begin{function}[EXP,added = 2023-11-15]
+% {\bitset_item:Nn, \bitset_item:cn}
+% \begin{syntax}
+% \cs{bitset_item:Nn} \meta{bitset var} \Arg{name}
+% \end{syntax}
+% \cs{bitset_item:Nn} outputs \texttt{1} if the bit with
+% the index number represented by \meta{name} is set and \texttt{0} otherwise.
+% \meta{name} is either one of the predeclared names
+% |1|, |2|, |3|, \ldots, or one of the names added manually.
+% \end{function}
+%
+% \begin{function}[EXP,added = 2023-11-15]
+% {\bitset_to_bin:N, \bitset_to_bin:c}
+% \begin{syntax}
+% \cs{bitset_to_bin:N} \meta{bitset var}
+% \end{syntax}
+% This leaves the current value of the bitset expressed as
+% a binary (string) number in the input stream.
+% If no bit has been set yet, the output is zero.
+% \end{function}
+%
+% \begin{function}[EXP,added = 2023-11-15]
+% {\bitset_to_arabic:N, \bitset_to_arabic:c}
+% \begin{syntax}
+% \cs{bitset_to_arabic:N} \meta{bitset var}
+% \end{syntax}
+% This leaves the current value of the bitset expressed as
+% a decimal number in the input stream. If no bit has been set yet,
+% the output is zero. The function uses \cs{int_from_bin:n} if the largest
+% index that have been set or unset is smaller than $32$, and a slower
+% implementation based on \cs{fp_eval:n} otherwise.
+% \end{function}
+%
+% \begin{function}[added = 2023-11-15]
+% {\bitset_show:N, \bitset_show:c}
+% \begin{syntax}
+% \cs{bitset_show:N} \meta{bitset var}
+% \end{syntax}
+% Displays the binary and decimal values of the \meta{bitset var}
+% on the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2023-11-15]
+% {\bitset_log:N, \bitset_log:c}
+% \begin{syntax}
+% \cs{bitset_log:N} \meta{bitset var}
+% \end{syntax}
+% Writes the binary and decimal values of the \meta{bitset var}
+% in the log file.
+% \end{function}
+%
+% \begin{function}[added = 2023-11-15]
+% {
+% \bitset_show_named_index:N, \bitset_show_named_index:c
+% }
+% \begin{syntax}
+% \cs{bitset_show_named_index:N} \meta{bitset var}
+% \end{syntax}
+% Displays declared name--index pairs of the \meta{bitset var}
+% on the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2023-12-11]
+% {
+% \bitset_log_named_index:N, \bitset_log_named_index:c
+% }
+% \begin{syntax}
+% \cs{bitset_log_named_index:N} \meta{bitset var}
+% \end{syntax}
+% Writes declared name--index pairs of the \meta{bitset var}
+% in the log file.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3bitset} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=bitset>
+% \end{macrocode}
+%
+% Transitional support.
+% \begin{macrocode}
+\cs_if_exist:NT \@expl@finalise@setup@@@@
+ {
+ \tl_gput_right:Nn \@expl@finalise@setup@@@@
+ { \declare@file@substitution { l3bitset.sty } { null.tex } }
+ }
+% \end{macrocode}
+%
+% A bitset is a string variable.
+% \begin{macro}{\bitset_new:N, \bitset_new:c}
+% \begin{macro}{\bitset_new:Nn, \bitset_new:cn}
+% \begin{macrocode}
+\cs_new_protected:Npn \bitset_new:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \cs_gset_eq:NN #1 \c_zero_str
+ \prop_new:c { g__bitset_ \cs_to_str:N #1 _name_prop }
+ }
+\cs_new_protected:Npn \bitset_new:Nn #1 #2
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \cs_gset_eq:NN #1 \c_zero_str
+ \prop_new:c { g__bitset_ \cs_to_str:N #1 _name_prop }
+ \prop_gset_from_keyval:cn
+ { g__bitset_ \cs_to_str:N #1 _name_prop }
+ {#2}
+ }
+\cs_generate_variant:Nn \bitset_new:N { c }
+\cs_generate_variant:Nn \bitset_new:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\bitset_addto_named_index:Nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \bitset_addto_named_index:Nn #1#2
+ {
+ \prop_gput_from_keyval:cn
+ { g_@@_ \cs_to_str:N #1 _name_prop } { #2 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP,pTF]
+% {
+% \bitset_if_exist:N, \bitset_if_exist:c
+% }
+% Existence tests.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn
+ \bitset_if_exist:N \str_if_exist:N { p , T , F , TF }
+\prg_new_eq_conditional:NNn
+ \bitset_if_exist:c \str_if_exist:c { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_set_true:Nn, \@@_gset_true:Nn, \@@_set_false:Nn, \@@_gset_false:Nn}
+% \begin{macro}{\@@_set:NNnN}
+% The internal command uses only numbers (integer expressions) for the
+% position.
+% A bit is set by either extending the string or by splitting it and
+% then inserting an $1$. It is not checked if the value was already $1$.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_true:Nn #1#2
+ { \@@_set:NNnN \str_set:Ne #1 {#2} 1 }
+\cs_new_protected:Npn \@@_gset_true:Nn #1#2
+ { \@@_set:NNnN \str_gset:Ne #1 {#2} 1 }
+\cs_new_protected:Npn \@@_set_false:Nn #1#2
+ { \@@_set:NNnN \str_set:Ne #1 {#2} 0 }
+\cs_new_protected:Npn \@@_gset_false:Nn #1#2
+ { \@@_set:NNnN \str_gset:Ne #1 {#2} 0 }
+\cs_new_protected:Npn \@@_set:NNnN #1#2#3#4
+ {
+ \int_compare:nNnT {#3} > { 0 }
+ {
+ \int_compare:nNnTF { \str_count:N #2 } < {#3}
+ {
+ #1 #2
+ {
+ #4
+ \prg_replicate:nn { #3 - \str_count:N #2 - 1 } { 0 }
+ #2
+ }
+ }
+ {
+ #1 #2
+ {
+ \str_range:Nnn #2 { 1 } { -1 - (#3) }
+ #4
+ \str_range:Nnn #2 { 1 - (#3) } { -1 }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_internal_int}
+% \begin{macrocode}
+\int_new:N \l_@@_internal_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[TF]{\@@_test_digits:n}
+% \begin{macro}{\@@_test_digits_end:n}
+% \begin{macro}{\@@_test_digits:w}
+% \url{https://chat.stackexchange.com/transcript/message/56878159#56878159}
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \@@_test_digits:n #1 { TF }
+ {
+ \tex_afterassignment:D \@@_test_digits:w
+ \l_@@_internal_int = 0 \tl_trim_spaces_apply:nN {#1} \tl_to_str:n
+ \@@_test_digits_end:
+ \use_i:nnn \if_false:
+ \@@_test_digits_end:
+ \if_int_compare:w \c_zero_int < \l_@@_internal_int
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new_eq:NN \@@_test_digits_end: \exp_stop_f:
+\cs_new_protected:Npn \@@_test_digits:w #1 \@@_test_digits_end: { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \bitset_set_true:Nn, \bitset_set_true:cn,
+% \bitset_gset_true:Nn, \bitset_gset_true:cn,
+% \bitset_set_false:Nn, \bitset_set_false:cn,
+% \bitset_gset_false:Nn, \bitset_gset_false:cn
+% }
+% \begin{macro}{\@@_set_aux:NNn}
+% The user commands must first translate the argument to an index number.
+% \begin{macrocode}
+\cs_new_protected:Npn \bitset_set_true:Nn #1#2
+ { \@@_set:NNn \@@_set_true:Nn #1 {#2} }
+\cs_new_protected:Npn \bitset_gset_true:Nn #1#2
+ { \@@_set:NNn \@@_gset_true:Nn #1 {#2} }
+\cs_new_protected:Npn \bitset_set_false:Nn #1#2
+ { \@@_set:NNn \@@_set_false:Nn #1 {#2} }
+\cs_new_protected:Npn \bitset_gset_false:Nn #1#2
+ { \@@_set:NNn \@@_gset_false:Nn #1 {#2} }
+\cs_new_protected:Npn \@@_set:NNn #1#2#3
+ {
+ \prop_if_in:cnTF { g_@@_ \cs_to_str:N #2 _name_prop } {#3}
+ {
+ #1 #2
+ {
+ \prop_item:cn { g_@@_ \cs_to_str:N #2 _name_prop } {#3}
+ }
+ }
+ {
+ \@@_test_digits:nTF {#3}
+ {
+ #1 #2 {#3}
+ \prop_gput:cnn { g_@@_ \cs_to_str:N #2 _name_prop } {#3} {#3}
+ }
+ {
+ \msg_warning:nnee { bitset } { unknown-name }
+ { \token_to_str:N #2 }
+ { \tl_to_str:n {#3} }
+ }
+ }
+ }
+\cs_generate_variant:Nn \bitset_set_true:Nn { c }
+\cs_generate_variant:Nn \bitset_gset_true:Nn { c }
+\cs_generate_variant:Nn \bitset_set_false:Nn { c }
+\cs_generate_variant:Nn \bitset_gset_false:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \bitset_clear:N, \bitset_clear:c,
+% \bitset_gclear:N, \bitset_gclear:c
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \bitset_clear:N #1
+ {
+ \str_set_eq:NN #1 \c_zero_str
+ }
+\cs_new_protected:Npn \bitset_gclear:N #1
+ {
+ \str_gset_eq:NN #1 \c_zero_str
+ }
+\cs_generate_variant:Nn \bitset_clear:N { c }
+\cs_generate_variant:Nn \bitset_gclear:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \bitset_to_arabic:N, \bitset_to_arabic:c,
+% \bitset_to_bin:N, \bitset_to_bin:c,
+% }
+% \begin{macro}[EXP]{\@@_to_int:nN}
+% The naming of the commands follow the names in the \texttt{int} module.
+% \cs{bitset_to_arabic:N} uses \cs{int_from_bin:n} if the string is shorter
+% than $32$ and the slower \cs{fp_eval:n} for larger bitsets.
+% \begin{macrocode}
+\cs_new:Npn \bitset_to_arabic:N #1
+ {
+ \int_compare:nNnTF { \str_count:N #1 } < { 32 }
+ { \exp_args:No \int_from_bin:n {#1} }
+ {
+ \exp_after:wN \@@_to_int:nN \exp_after:wN 0
+ #1 \q_recursion_tail \q_recursion_stop
+ }
+ }
+\cs_new:Npn \@@_to_int:nN #1#2
+ {
+ \quark_if_recursion_tail_stop_do:Nn #2 {#1}
+ \exp_args:Nf \@@_to_int:nN { \fp_eval:n { #1 * 2 + #2 } }
+ }
+\cs_new:Npn \bitset_to_bin:N #1
+ {
+ #1
+ }
+\cs_generate_variant:Nn \bitset_to_arabic:N { c }
+\cs_generate_variant:Nn \bitset_to_bin:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \bitset_item:Nn, \bitset_item:cn
+% }
+% All bits that have been set at anytime have an entry in the prop,
+% so we can take everything else as $0$.
+% \begin{macrocode}
+\cs_new:Npn \bitset_item:Nn #1#2
+ {
+ \prop_if_in:cnTF { g_@@_ \cs_to_str:N #1 _name_prop } {#2}
+ {
+ \int_eval:n
+ {
+ \str_item:Nn #1
+ { 0 - ( \prop_item:cn { g_@@_ \cs_to_str:N #1 _name_prop } {#2} ) }
+ +0
+ }
+ }
+ {
+ 0
+ }
+ }
+\cs_generate_variant:Nn \bitset_item:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \bitset_show:N, \bitset_show:c,
+% \bitset_log:N, \bitset_log:c
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \bitset_show:N { \@@_show:NN \msg_show:nneeee }
+\cs_generate_variant:Nn \bitset_show:N { c }
+\cs_new_protected:Npn \bitset_log:N { \@@_show:NN \msg_log:nneeee }
+\cs_generate_variant:Nn \bitset_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_chk_defined:NT #2
+ {
+ #1 { bitset } { show }
+ { \token_to_str:N #2 }
+ { \bitset_to_bin:N #2 }
+ { \bitset_to_arabic:N #2 }
+ { }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \bitset_show_named_index:N, \bitset_show_named_index:c,
+% \bitset_log_named_index:N, \bitset_log_named_index:c
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \bitset_show_named_index:N
+ { \@@_show_named_index:NN \msg_show:nneeee }
+\cs_generate_variant:Nn \bitset_show_named_index:N { c }
+\cs_new_protected:Npn \bitset_log_named_index:N
+ { \@@_show_named_index:NN \msg_log:nneeee }
+\cs_generate_variant:Nn \bitset_log_named_index:N { c }
+\cs_new_protected:Npn \@@_show_named_index:NN #1#2
+ {
+ \__kernel_chk_defined:NT #2
+ {
+ #1 { bitset } { show-names }
+ { \token_to_str:N #2 }
+ { \prop_map_function:cN { g_@@_ \cs_to_str:N #2 _name_prop } \msg_show_item:nn }
+ { } { }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Messages}
+% \begin{macrocode}
+\msg_new:nnn { bitset } { show }
+ {
+ The~bitset~#1~has~the~representation: \\
+ >~binary:~#2 \\
+ >~arabic:~#3 .
+ }
+\msg_new:nnn { bitset } { show-names }
+ {
+ The~bitset~#1~
+ \tl_if_empty:nTF {#2}
+ { knows~no~names~yet \\>~ . }
+ { knows~the~name/index~pairs~(without~outer~braces): #2 . }
+ }
+\msg_new:nnn { bitset } { unknown-name }
+ { The~name~'#2'~is~unknown~for~bitset~\tl_to_str:n {#1} }
+\prop_gput:Nnn \g_msg_module_name_prop { bitset } { LaTeX }
+\prop_gput:Nnn \g_msg_module_type_prop { bitset } { }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3bootstrap.dtx b/macros/latex-dev/required/l3kernel/l3bootstrap.dtx
new file mode 100644
index 0000000000..2c51bf3bb0
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3bootstrap.dtx
@@ -0,0 +1,357 @@
+% \iffalse meta-comment
+%
+%% File: l3bootstrap.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3bootstrap} module\\ Bootstrap code^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{Using the \LaTeX3 modules}
+%
+% The modules documented in ^^A
+% \ifinterface
+% this file (and \file{source3} for documented sources) ^^A
+% \else
+% \file{interface3} (and this file) ^^A
+% \fi
+% are designed to be used on top of \LaTeXe{} and are already pre-loaded
+% since \LaTeXe{} 2020-02-02.
+% To support older formats, the |\usepackage{expl3}| or |\RequirePackage{expl3}|
+% instructions are still available to load them all as one.
+%
+% As the modules use a coding syntax different from standard
+% \LaTeXe{} it provides a few functions for setting it up.
+%
+% \begin{function}[updated = 2011-08-13]{\ExplSyntaxOn, \ExplSyntaxOff}
+% \begin{syntax}
+% \cs{ExplSyntaxOn} \meta{code} \cs{ExplSyntaxOff}
+% \end{syntax}
+% The \cs{ExplSyntaxOn} function switches to a category code
+% regime in which spaces and new lines are ignored, and in which the colon (|:|)
+% and underscore (|_|) are treated as \enquote{letters}, thus allowing
+% access to the names of code functions and variables. Within this
+% environment, |~| is used to input a space. The \cs{ExplSyntaxOff}
+% reverts to the document category code regime.
+% \begin{texnote}
+% Spaces introduced by~|~| behave much in the same way as normal
+% space characters in the standard category code regime: they are
+% ignored after a control word or at the start of a line, and
+% multiple consecutive~|~| are equivalent to a single one. However,
+% |~|~is \emph{not} ignored at the end of a line.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[updated = 2017-03-19, updated = 2023-08-03]
+% {\ProvidesExplPackage, \ProvidesExplClass, \ProvidesExplFile}
+% \begin{syntax}
+% \cs{ProvidesExplPackage} \Arg{package} \Arg{date} \Arg{version} \Arg{description}
+% \end{syntax}
+% These functions act broadly in the same way as the corresponding
+% \LaTeXe{} kernel
+% functions \tn{ProvidesPackage}, \tn{ProvidesClass} and
+% \tn{ProvidesFile}. However, they also implicitly switch
+% \cs{ExplSyntaxOn} for the remainder of the code with the file. At the
+% end of the file, \cs{ExplSyntaxOff} will be called to reverse this.
+% (This is the same concept as \LaTeXe{} provides in turning on
+% \tn{makeatletter} within package and class code.) The \meta{date} should
+% be given in the format \meta{year}/\meta{month}/\meta{day} or in the ISO
+% date format \meta{year}-\meta{month}-\meta{day}. If the
+% \meta{version} is given then a leading \texttt{v} is optional: if given
+% as a \enquote{pure} version string, a \texttt{v} will be prepended.
+% \end{function}
+%
+% \begin{function}[updated = 2012-06-04]{\GetIdInfo}
+% \begin{syntax}
+% \cs{GetIdInfo} |$Id:| \meta{SVN info field} |$| \Arg{description}
+% \end{syntax}
+% Extracts all information from a SVN field. Spaces are not
+% ignored in these fields. The information pieces are stored in
+% separate control sequences with \cs{ExplFileName} for the part of the
+% file name leading up to the period, \cs{ExplFileDate} for date,
+% \cs{ExplFileVersion} for version and \cs{ExplFileDescription} for the
+% description.
+% \end{function}
+%
+% To summarize: Every single package using this syntax should identify
+% itself using one of the above methods. Special care is taken so that
+% every package or class file loaded with \tn{RequirePackage} or similar
+% are loaded with usual \LaTeXe{} category codes and the \LaTeX3 category code
+% scheme is reloaded when needed afterwards. See implementation for
+% details. If you use the \cs{GetIdInfo} command you can use the
+% information when loading a package with
+% \begin{verbatim}
+% \ProvidesExplPackage{\ExplFileName}
+% {\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+% \end{verbatim}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3bootstrap} implementation}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=kernel>
+% \end{macrocode}
+%
+% \subsection{The \tn{pdfstrcmp} primitive in \XeTeX{}}
+%
+% Only \pdfTeX{} has a primitive called \tn{pdfstrcmp}. The \XeTeX{}
+% version is just \tn{strcmp}, so there is some shuffling to do. As
+% this is still a real primitive, using the \pdfTeX{} name is \enquote{safe}.
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+ \expandafter\ifx\csname pdfstrcmp\endcsname\relax
+ \let\pdfstrcmp\strcmp
+\fi
+% \end{macrocode}
+%
+% \subsection{Loading support \Lua{} code}
+%
+% When \LuaTeX{} is used there are various pieces of \Lua{} code which need to
+% be loaded. The code itself is defined in \pkg{l3luatex} and is extracted into
+% a separate file. Thus here the task is to load the \Lua{} code both now and
+% (if required) at the start of each job.
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname directlua\endcsname\relax
+\else
+ \ifnum\luatexversion<110 %
+ \else
+% \end{macrocode}
+% For \LuaTeX{} we make sure the basic support is loaded:
+% this is only necessary in plain.
+% \begin{macrocode}
+ \begingroup\expandafter\expandafter\expandafter\endgroup
+ \expandafter\ifx\csname newcatcodetable\endcsname\relax
+ \input{ltluatex}%
+ \fi
+ \begingroup\expandafter\expandafter\expandafter\endgroup
+ \expandafter\ifx\csname newluabytecode\endcsname\relax
+ \else
+ \newluabytecode\@expl@luadata@bytecode
+ \fi
+ \directlua{require("expl3")}%
+% \end{macrocode}
+% As the user might be making a custom format, no assumption is made about
+% matching package mode with only loading the \Lua{} code once. Instead, a
+% query to \Lua{} reveals what mode is in operation.
+% \begin{macrocode}
+ \ifnum 0%
+ \directlua{
+ if status.ini_version then
+ tex.write("1")
+ end
+ }>0 %
+ \everyjob\expandafter{%
+ \the\expandafter\everyjob
+ \csname\detokenize{lua_now:n}\endcsname{require("expl3")}%
+ }%
+ \fi
+ \fi
+\fi
+% \end{macrocode}
+%
+% \subsection{Engine requirements}
+%
+% The code currently requires \eTeX{}, the set of \enquote{\pdfTeX{}
+% extensions} \emph{including} \tn{expanded}, and for Unicode engines the
+% ability to generate arbitrary character tokens by expansion. That is covered
+% by all supported engines since \TeX{} Live 2019, which we therefore use
+% as a baseline for engine and \LaTeX{} format support.
+% For \LuaTeX, we require at least Lua 5.3 and the |token.set_lua| function.
+% This is available at least since \LuaTeX{} 1.10, which again is the one
+% in \TeX{} Live 2019. (u)p\TeX{} only gained \tn{ifincsname} for \TeX{}
+% Live 2020, but at present that primitive is unused in \pkg{expl3} so for
+% the present it's not tested. If and when that changes, we will need to
+% revisit the code here.
+% \begin{macrocode}
+\begingroup
+ \def\next{\endgroup}%
+ \def\ShortText{Required primitives not found}%
+ \def\LongText%
+ {%
+ The L3 programming layer requires the e-TeX primitives and the
+ \LineBreak 'pdfTeX utilities' as described in the README file.
+ \LineBreak
+ These are available in the engines\LineBreak
+ - pdfTeX v1.40.20\LineBreak
+ - XeTeX v0.999991\LineBreak
+ - LuaTeX v1.10\LineBreak
+ - e-(u)pTeX v3.8.2\LineBreak
+ - Prote (2021)\LineBreak
+ or later.\LineBreak
+ \LineBreak
+ }%
+ \ifnum0%
+ \expandafter\ifx\csname luatexversion\endcsname\relax
+ \expandafter\ifx\csname expanded\endcsname\relax\else 1\fi
+ \else
+ \ifnum\luatexversion<110 \else 1\fi
+ \fi
+ =0 %
+ \newlinechar`\^^J %
+ \def\LineBreak{\noexpand\MessageBreak}%
+ \expandafter\ifx\csname PackageError\endcsname\relax
+ \def\LineBreak{^^J}%
+ \begingroup
+ \lccode`\~=`\ \lccode`\}=`\ %
+ \lccode`\T=`\T\lccode`\H=`\H%
+ \catcode`\ =11 %
+\lowercase{\endgroup\def\PackageError#1#2#3{%
+\begingroup\errorcontextlines-1\immediate\write0{}\errhelp{#3}\def%
+\ {#1 Error: #2.^^J^^J
+Type H <return> for immediate help}\def~{\errmessage{%
+\ }}~\endgroup}}%
+ \fi
+ \edef\next
+ {%
+ \noexpand\PackageError{expl3}{\ShortText}
+ {\LongText Loading of expl3 will abort!}%
+ \endgroup
+ \noexpand\endinput
+ }%
+ \fi
+\next
+% \end{macrocode}
+%
+% \subsection{The \LaTeX3 code environment}
+%
+% The code environment is now set up.
+%
+% \begin{macro}{\ExplSyntaxOff}
+% Before changing any category codes, in package mode we need to save
+% the situation before loading. Note the set up here means that once applied
+% \cs{ExplSyntaxOff} becomes a \enquote{do nothing} command until
+% \cs{ExplSyntaxOn} is used.
+% \begin{macrocode}
+\protected\edef\ExplSyntaxOff
+ {%
+ \protected\def\noexpand\ExplSyntaxOff{}%
+ \catcode 9 = \the\catcode 9\relax
+ \catcode 32 = \the\catcode 32\relax
+ \catcode 34 = \the\catcode 34\relax
+ \catcode 58 = \the\catcode 58\relax
+ \catcode 94 = \the\catcode 94\relax
+ \catcode 95 = \the\catcode 95\relax
+ \catcode 124 = \the\catcode 124\relax
+ \catcode 126 = \the\catcode 126\relax
+ \endlinechar = \the\endlinechar\relax
+ \chardef\csname\detokenize{l_@@_expl_bool}\endcsname = 0\relax
+ }%
+% \end{macrocode}
+% \end{macro}
+%
+% The code environment is now set up.
+% \begin{macrocode}
+\catcode 9 = 9\relax
+\catcode 32 = 9\relax
+\catcode 34 = 12\relax
+\catcode 58 = 11\relax
+\catcode 94 = 7\relax
+\catcode 95 = 11\relax
+\catcode 124 = 12\relax
+\catcode 126 = 10\relax
+\endlinechar = 32\relax
+% \end{macrocode}
+%
+% \begin{variable}{\l_@@_expl_bool}
+% The status for code syntax: this is on at present.
+% \begin{macrocode}
+\global\chardef\l_@@_expl_bool = 1\relax
+% \end{macrocode}
+%\end{variable}
+%
+% \begin{macro}{\ExplSyntaxOn}
+% The idea here is that multiple \cs{ExplSyntaxOn} calls are not
+% going to mess up category codes, and that multiple calls to
+% \cs{ExplSyntaxOff} are also not wasting time. Applying
+% \cs{ExplSyntaxOn} alters the definition of \cs{ExplSyntaxOff}
+% and so in package mode this function should not be used until after
+% the end of the loading process!
+% \begin{macrocode}
+\protected \def \ExplSyntaxOn
+ {
+ \bool_if:NF \l_@@_expl_bool
+ {
+ \cs_set_protected:Npe \ExplSyntaxOff
+ {
+ \char_set_catcode:nn { 9 } { \char_value_catcode:n { 9 } }
+ \char_set_catcode:nn { 32 } { \char_value_catcode:n { 32 } }
+ \char_set_catcode:nn { 34 } { \char_value_catcode:n { 34 } }
+ \char_set_catcode:nn { 58 } { \char_value_catcode:n { 58 } }
+ \char_set_catcode:nn { 94 } { \char_value_catcode:n { 94 } }
+ \char_set_catcode:nn { 95 } { \char_value_catcode:n { 95 } }
+ \char_set_catcode:nn { 124 } { \char_value_catcode:n { 124 } }
+ \char_set_catcode:nn { 126 } { \char_value_catcode:n { 126 } }
+ \tex_endlinechar:D =
+ \tex_the:D \tex_endlinechar:D \scan_stop:
+ \bool_set_false:N \l_@@_expl_bool
+ \cs_set_protected:Npn \ExplSyntaxOff { }
+ }
+ }
+ \char_set_catcode_ignore:n { 9 } % tab
+ \char_set_catcode_ignore:n { 32 } % space
+ \char_set_catcode_other:n { 34 } % double quote
+ \char_set_catcode_letter:n { 58 } % colon
+ \char_set_catcode_math_superscript:n { 94 } % circumflex
+ \char_set_catcode_letter:n { 95 } % underscore
+ \char_set_catcode_other:n { 124 } % pipe
+ \char_set_catcode_space:n { 126 } % tilde
+ \tex_endlinechar:D = 32 \scan_stop:
+ \bool_set_true:N \l_@@_expl_bool
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3box.dtx b/macros/latex-dev/required/l3kernel/l3box.dtx
new file mode 100644
index 0000000000..2d4902950f
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3box.dtx
@@ -0,0 +1,2530 @@
+% \iffalse meta-comment
+%
+%% File: l3box.dtx
+%
+% Copyright (C) 2005-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3box} module\\ Boxes^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% Box variables contain typeset material that can be inserted on the
+% page or in other boxes. Their contents cannot be converted back to
+% lists of tokens.
+% There are three kinds of box operations: horizontal mode denoted
+% with prefix |\hbox_|, vertical mode with prefix |\vbox_|, and the
+% generic operations working in both modes with prefix |\box_|.
+% For instance, a new box variable containing the words \enquote{Hello,
+% world!} (in a horizontal box) can be obtained by the following code.
+% \begin{verbatim}
+% \box_new:N \l_hello_box
+% \hbox_set:Nn \l_hello_box { Hello, ~ world! }
+% \end{verbatim}
+% The argument is typeset inside a \TeX{} group so that any variables
+% assigned during the construction of this box restores its value
+% afterwards.
+%
+% Box variables from \pkg{l3box} are compatible with those of \LaTeXe{}
+% and plain \TeX{} and can be used interchangeably. The \pkg{l3box}
+% commands to construct boxes, such as \cs{hbox:n} or \cs{hbox_set:Nn},
+% are \enquote{color-safe}, meaning that
+% \begin{verbatim}
+% \hbox:n { \color_select:n { blue } Hello, } ~ world!
+% \end{verbatim}
+% will result in \enquote{Hello,} taking the color blue, but
+% \enquote{world!} remaining with the prevailing color outside the box.
+%
+% \section{Creating and initialising boxes}
+%
+% \begin{function}{\box_new:N, \box_new:c}
+% \begin{syntax}
+% \cs{box_new:N} \meta{box}
+% \end{syntax}
+% Creates a new \meta{box} or raises an error if the name is
+% already taken. The declaration is global. The \meta{box} is
+% initially void.
+% \end{function}
+%
+% \begin{function}{\box_clear:N, \box_clear:c, \box_gclear:N, \box_gclear:c}
+% \begin{syntax}
+% \cs{box_clear:N} \meta{box}
+% \end{syntax}
+% Clears the content of the \meta{box} by setting the box equal to
+% \cs{c_empty_box}.
+% \end{function}
+%
+% \begin{function}
+% {\box_clear_new:N, \box_clear_new:c, \box_gclear_new:N, \box_gclear_new:c}
+% \begin{syntax}
+% \cs{box_clear_new:N} \meta{box}
+% \end{syntax}
+% Ensures that the \meta{box} exists globally by applying
+% \cs{box_new:N} if necessary, then applies
+% \cs[index=box_clear:N]{box_(g)clear:N} to leave
+% the \meta{box} empty.
+% \end{function}
+%
+% \begin{function}
+% {
+% \box_set_eq:NN, \box_set_eq:cN, \box_set_eq:Nc, \box_set_eq:cc,
+% \box_gset_eq:NN, \box_gset_eq:cN, \box_gset_eq:Nc, \box_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{box_set_eq:NN} \meta{box_1} \meta{box_2}
+% \end{syntax}
+% Sets the content of \meta{box_1} equal to that of \meta{box_2}.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added=2012-03-03]
+% {\box_if_exist:N, \box_if_exist:c}
+% \begin{syntax}
+% \cs{box_if_exist_p:N} \meta{box}
+% \cs{box_if_exist:NTF} \meta{box} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{box} is currently defined. This does not
+% check that the \meta{box} really is a box.
+% \end{function}
+%
+% \section{Using boxes}
+%
+% \begin{function}{\box_use:N, \box_use:c}
+% \begin{syntax}
+% \cs{box_use:N} \meta{box}
+% \end{syntax}
+% Inserts the current content of the \meta{box} onto the current
+% list for typesetting. An error is raised if the variable does
+% not exist or if it is invalid.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{copy}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\box_move_right:nn, \box_move_left:nn}
+% \begin{syntax}
+% \cs{box_move_right:nn} \Arg{dim expr} \Arg{box function}
+% \end{syntax}
+% This function operates in vertical mode, and inserts the
+% material specified by the \meta{box function}
+% such that its reference point is displaced horizontally by the given
+% \meta{dim expr} from the reference point for typesetting, to the right
+% or left as appropriate. The \meta{box function} should be
+% a box operation such as \cs{box_use:N} |\<box>| or a \enquote{raw}
+% box specification such as \cs{vbox:n} |{ xyz }|.
+% \end{function}
+%
+% \begin{function}{\box_move_up:nn, \box_move_down:nn}
+% \begin{syntax}
+% \cs{box_move_up:nn} \Arg{dim expr} \Arg{box function}
+% \end{syntax}
+% This function operates in horizontal mode, and inserts the
+% material specified by the \meta{box function}
+% such that its reference point is displaced vertically by the given
+% \meta{dim expr} from the reference point for typesetting, up
+% or down as appropriate. The \meta{box function} should be
+% a box operation such as \cs{box_use:N} |\<box>| or a \enquote{raw}
+% box specification such as \cs{vbox:n} |{ xyz }|.
+% \end{function}
+%
+% \section{Measuring and setting box dimensions}
+%
+% \begin{function}{\box_dp:N, \box_dp:c}
+% \begin{syntax}
+% \cs{box_dp:N} \meta{box}
+% \end{syntax}
+% Calculates the depth (below the baseline) of the \meta{box}
+% in a form suitable for use in a \meta{dim expr}.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{dp}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\box_ht:N, \box_ht:c}
+% \begin{syntax}
+% \cs{box_ht:N} \meta{box}
+% \end{syntax}
+% Calculates the height (above the baseline) of the \meta{box}
+% in a form suitable for use in a \meta{dim expr}.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ht}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\box_wd:N, \box_wd:c}
+% \begin{syntax}
+% \cs{box_wd:N} \meta{box}
+% \end{syntax}
+% Calculates the width of the \meta{box} in a form
+% suitable for use in a \meta{dim expr}.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{wd}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2021-05-05]{\box_ht_plus_dp:N, \box_ht_plus_dp:c}
+% \begin{syntax}
+% \cs{box_ht_plus_dp:N} \meta{box}
+% \end{syntax}
+% Calculates the total vertical size (height plus depth) of the \meta{box}
+% in a form suitable for use in a \meta{dim expr}.
+% \end{function}
+%
+% \begin{function}[updated = 2019-01-22]
+% {
+% \box_set_dp:Nn, \box_set_dp:cn,
+% \box_gset_dp:Nn, \box_gset_dp:cn
+% }
+% \begin{syntax}
+% \cs{box_set_dp:Nn} \meta{box} \Arg{dim expr}
+% \end{syntax}
+% Set the depth (below the baseline) of the \meta{box} to the value of
+% the \Arg{dim expr}.
+% \end{function}
+%
+% \begin{function}[updated = 2019-01-22]
+% {
+% \box_set_ht:Nn, \box_set_ht:cn,
+% \box_gset_ht:Nn, \box_gset_ht:cn
+% }
+% \begin{syntax}
+% \cs{box_set_ht:Nn} \meta{box} \Arg{dim expr}
+% \end{syntax}
+% Set the height (above the baseline) of the \meta{box} to the value of
+% the \Arg{dim expr}.
+% \end{function}
+%
+% \begin{function}[updated = 2019-01-22]
+% {
+% \box_set_wd:Nn, \box_set_wd:cn,
+% \box_gset_wd:Nn, \box_gset_wd:cn
+% }
+% \begin{syntax}
+% \cs{box_set_wd:Nn} \meta{box} \Arg{dim expr}
+% \end{syntax}
+% Set the width of the \meta{box} to the value of the
+% \Arg{dim expr}.
+% \end{function}
+%
+% \section{Box conditionals}
+%
+% \begin{function}[EXP,pTF]{\box_if_empty:N, \box_if_empty:c}
+% \begin{syntax}
+% \cs{box_if_empty_p:N} \meta{box}
+% \cs{box_if_empty:NTF} \meta{box} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{box} is a empty (equal to \cs{c_empty_box}).
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\box_if_horizontal:N, \box_if_horizontal:c}
+% \begin{syntax}
+% \cs{box_if_horizontal_p:N} \meta{box}
+% \cs{box_if_horizontal:NTF} \meta{box} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{box} is a horizontal box.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\box_if_vertical:N, \box_if_vertical:c}
+% \begin{syntax}
+% \cs{box_if_vertical_p:N} \meta{box}
+% \cs{box_if_vertical:NTF} \meta{box} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{box} is a vertical box.
+% \end{function}
+%
+% \section{The last box inserted}
+%
+% \begin{function}
+% {
+% \box_set_to_last:N, \box_set_to_last:c,
+% \box_gset_to_last:N, \box_gset_to_last:c
+% }
+% \begin{syntax}
+% \cs{box_set_to_last:N} \meta{box}
+% \end{syntax}
+% Sets the \meta{box} equal to the last item (box) added to the current
+% partial list, removing the item from the list at the same time. When
+% applied to the main vertical list, the \meta{box} is always void as
+% it is not possible to recover the last added item.
+% \end{function}
+%
+% \section{Constant boxes}
+%
+% \begin{variable}[updated = 2012-11-04]{\c_empty_box}
+% This is a permanently empty box, which is neither set as horizontal
+% nor vertical.
+% \begin{texnote}
+% At the \TeX{} level this is a void box.
+% \end{texnote}
+% \end{variable}
+%
+% \section{Scratch boxes}
+%
+% \begin{variable}[updated = 2012-11-04]{\l_tmpa_box, \l_tmpb_box}
+% Scratch boxes for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_box, \g_tmpb_box}
+% Scratch boxes for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Viewing box contents}
+%
+% \begin{function}[updated = 2012-05-11]{\box_show:N, \box_show:c}
+% \begin{syntax}
+% \cs{box_show:N} \meta{box}
+% \end{syntax}
+% Shows full details of the content of the \meta{box} in the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2012-05-11]{\box_show:Nnn, \box_show:cnn}
+% \begin{syntax}
+% \cs{box_show:Nnn} \meta{box} \Arg{int expr_1} \Arg{int expr_2}
+% \end{syntax}
+% Display the contents of \meta{box} in the terminal, showing the first
+% \meta{int expr_1} items of the box, and descending into \meta{int expr_2}
+% group levels.
+% \end{function}
+%
+% \begin{function}[added = 2012-05-11]{\box_log:N, \box_log:c}
+% \begin{syntax}
+% \cs{box_log:N} \meta{box}
+% \end{syntax}
+% Writes full details of the content of the \meta{box} to the log.
+% \end{function}
+%
+% \begin{function}[added = 2012-05-11]{\box_log:Nnn, \box_log:cnn}
+% \begin{syntax}
+% \cs{box_log:Nnn} \meta{box} \Arg{int expr_1} \Arg{int expr_2}
+% \end{syntax}
+% Writes the contents of \meta{box} to the log, showing the first
+% \meta{int expr_1} items of the box, and descending into \meta{int expr_2}
+% group levels.
+% \end{function}
+%
+% \section{Boxes and color}
+%
+% All \LaTeX{}3 boxes are \enquote{color safe}: a color set inside the box
+% stops applying after the end of the box has occurred.
+%
+% \section{Horizontal mode boxes}
+%
+% \begin{function}[updated = 2017-04-05]{\hbox:n}
+% \begin{syntax}
+% \cs{hbox:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a horizontal box of natural
+% width and then includes this box in the current list for typesetting.
+% \end{function}
+%
+% \begin{function}[updated = 2017-04-05]{\hbox_to_wd:nn}
+% \begin{syntax}
+% \cs{hbox_to_wd:nn} \Arg{dim expr} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a horizontal box of width
+% \meta{dim expr} and then includes this box in the current list for
+% typesetting.
+% \end{function}
+%
+% \begin{function}[updated = 2017-04-05]{\hbox_to_zero:n}
+% \begin{syntax}
+% \cs{hbox_to_zero:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a horizontal box of zero width
+% and then includes this box in the current list for typesetting.
+% \end{function}
+%
+% \begin{function}[updated = 2017-04-05]
+% {\hbox_set:Nn, \hbox_set:cn, \hbox_gset:Nn, \hbox_gset:cn}
+% \begin{syntax}
+% \cs{hbox_set:Nn} \meta{box} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} at natural width and then stores the
+% result inside the \meta{box}.
+% \end{function}
+%
+% \begin{function}[updated = 2017-04-05]
+% {
+% \hbox_set_to_wd:Nnn, \hbox_set_to_wd:cnn,
+% \hbox_gset_to_wd:Nnn, \hbox_gset_to_wd:cnn
+% }
+% \begin{syntax}
+% \cs{hbox_set_to_wd:Nnn} \meta{box} \Arg{dim expr} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} to the width given by the \meta{dim expr}
+% and then stores the result inside the \meta{box}.
+% \end{function}
+%
+% \begin{function}[added = 2020-08-25]{\hbox_overlap_center:n}
+% \begin{syntax}
+% \cs{hbox_overlap_center:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a horizontal box of zero width
+% such that material protrudes equally to both sides of the insertion point.
+% \end{function}
+%
+% \begin{function}[updated = 2017-04-05]{\hbox_overlap_right:n}
+% \begin{syntax}
+% \cs{hbox_overlap_right:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a horizontal box of zero width
+% such that material protrudes to the right of the insertion point.
+% \end{function}
+%
+% \begin{function}[updated = 2017-04-05]{\hbox_overlap_left:n}
+% \begin{syntax}
+% \cs{hbox_overlap_left:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a horizontal box of zero width
+% such that material protrudes to the left of the insertion point.
+% \end{function}
+%
+% \begin{function}[updated = 2017-04-05]
+% {
+% \hbox_set:Nw, \hbox_set:cw,
+% \hbox_set_end:,
+% \hbox_gset:Nw, \hbox_gset:cw,
+% \hbox_gset_end:
+% }
+% \begin{syntax}
+% \cs{hbox_set:Nw} \meta{box} \meta{contents} \cs{hbox_set_end:}
+% \end{syntax}
+% Typesets the \meta{contents} at natural width and then stores the
+% result inside the \meta{box}. In contrast
+% to \cs{hbox_set:Nn} this function does not absorb the argument
+% when finding the \meta{content}, and so can be used in circumstances
+% where the \meta{content} may not be a simple argument.
+% \end{function}
+%
+% \begin{function}[added = 2017-06-08]
+% {
+% \hbox_set_to_wd:Nnw, \hbox_set_to_wd:cnw,
+% \hbox_gset_to_wd:Nnw, \hbox_gset_to_wd:cnw
+% }
+% \begin{syntax}
+% \cs{hbox_set_to_wd:Nnw} \meta{box} \Arg{dim expr} \meta{contents} \cs{hbox_set_end:}
+% \end{syntax}
+% Typesets the \meta{contents} to the width given by the \meta{dim expr}
+% and then stores the result inside the \meta{box}. In contrast
+% to \cs{hbox_set_to_wd:Nnn} this function does not absorb the argument
+% when finding the \meta{content}, and so can be used in circumstances
+% where the \meta{content} may not be a simple argument
+% \end{function}
+%
+% \begin{function}{\hbox_unpack:N, \hbox_unpack:c}
+% \begin{syntax}
+% \cs{hbox_unpack:N} \meta{box}
+% \end{syntax}
+% Unpacks the content of the horizontal \meta{box}, retaining any stretching
+% or shrinking applied when the \meta{box} was set.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{unhcopy}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Vertical mode boxes}
+%
+% Vertical boxes inherit their baseline from their contents. The
+% standard case is that the baseline of the box is at the same position
+% as that of the last item added to the box. This means that the box
+% has no depth unless the last item added to it had depth. As a
+% result most vertical boxes have a large height value and small or
+% zero depth. The exception are |_top| boxes, where the reference point
+% is that of the first item added. These tend to have a large depth and
+% small height, although the latter is typically non-zero.
+%
+% \begin{function}[updated = 2017-04-05]{\vbox:n}
+% \begin{syntax}
+% \cs{vbox:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a vertical box of natural height
+% and includes this box in the current list for typesetting.
+% \end{function}
+%
+% \begin{function}[updated = 2017-04-05]{\vbox_top:n}
+% \begin{syntax}
+% \cs{vbox_top:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a vertical box of natural height
+% and includes this box in the current list for typesetting. The
+% baseline of the box is equal to that of the \emph{first}
+% item added to the box.
+% \end{function}
+%
+% \begin{function}[updated = 2017-04-05]{\vbox_to_ht:nn}
+% \begin{syntax}
+% \cs{vbox_to_ht:nn} \Arg{dim expr} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a vertical box of height
+% \meta{dim expr} and then includes this box in the current list for
+% typesetting.
+% \end{function}
+%
+% \begin{function}[updated = 2017-04-05]{\vbox_to_zero:n}
+% \begin{syntax}
+% \cs{vbox_to_zero:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a vertical box of zero height
+% and then includes this box in the current list for typesetting.
+% \end{function}
+%
+% \begin{function}[updated = 2017-04-05]
+% {\vbox_set:Nn, \vbox_set:cn, \vbox_gset:Nn, \vbox_gset:cn}
+% \begin{syntax}
+% \cs{vbox_set:Nn} \meta{box} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} at natural height and then stores the
+% result inside the \meta{box}.
+% \end{function}
+%
+% \begin{function}[updated = 2017-04-05]
+% {\vbox_set_top:Nn, \vbox_set_top:cn, \vbox_gset_top:Nn, \vbox_gset_top:cn}
+% \begin{syntax}
+% \cs{vbox_set_top:Nn} \meta{box} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} at natural height and then stores the
+% result inside the \meta{box}. The baseline of the box is equal
+% to that of the \emph{first} item added to the box.
+% \end{function}
+%
+% \begin{function}[updated = 2017-04-05]
+% {
+% \vbox_set_to_ht:Nnn, \vbox_set_to_ht:cnn,
+% \vbox_gset_to_ht:Nnn, \vbox_gset_to_ht:cnn
+% }
+% \begin{syntax}
+% \cs{vbox_set_to_ht:Nnn} \meta{box} \Arg{dim expr} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} to the height given by the
+% \meta{dim expr} and then stores the result inside the \meta{box}.
+% \end{function}
+%
+% \begin{function}[updated = 2017-04-05]
+% {
+% \vbox_set:Nw, \vbox_set:cw,
+% \vbox_set_end:,
+% \vbox_gset:Nw, \vbox_gset:cw,
+% \vbox_gset_end:
+% }
+% \begin{syntax}
+% \cs{vbox_set:Nw} \meta{box} \meta{contents} \cs{vbox_set_end:}
+% \end{syntax}
+% Typesets the \meta{contents} at natural height and then stores the
+% result inside the \meta{box}. In contrast
+% to \cs{vbox_set:Nn} this function does not absorb the argument
+% when finding the \meta{content}, and so can be used in circumstances
+% where the \meta{content} may not be a simple argument.
+% \end{function}
+%
+% \begin{function}[added = 2017-06-08]
+% {
+% \vbox_set_to_ht:Nnw, \vbox_set_to_ht:cnw,
+% \vbox_gset_to_ht:Nnw, \vbox_gset_to_ht:cnw
+% }
+% \begin{syntax}
+% \cs{vbox_set_to_ht:Nnw} \meta{box} \Arg{dim expr} \meta{contents} \cs{vbox_set_end:}
+% \end{syntax}
+% Typesets the \meta{contents} to the height given by the \meta{dim expr}
+% and then stores the result inside the \meta{box}. In contrast
+% to \cs{vbox_set_to_ht:Nnn} this function does not absorb the argument
+% when finding the \meta{content}, and so can be used in circumstances
+% where the \meta{content} may not be a simple argument
+% \end{function}
+%
+%
+% \begin{function}[updated = 2018-12-29]
+% {
+% \vbox_set_split_to_ht:NNn, \vbox_set_split_to_ht:cNn,
+% \vbox_set_split_to_ht:Ncn, \vbox_set_split_to_ht:ccn,
+% \vbox_gset_split_to_ht:NNn, \vbox_gset_split_to_ht:cNn,
+% \vbox_gset_split_to_ht:Ncn, \vbox_gset_split_to_ht:ccn
+% }
+% \begin{syntax}
+% \cs{vbox_set_split_to_ht:NNn} \meta{box_1} \meta{box_2} \Arg{dim expr}
+% \end{syntax}
+% Sets \meta{box_1} to contain material to the height given by the
+% \meta{dim expr} by removing content from the top of \meta{box_2}
+% (which must be a vertical box).
+% \end{function}
+%
+% \begin{function}{\vbox_unpack:N, \vbox_unpack:c}
+% \begin{syntax}
+% \cs{vbox_unpack:N} \meta{box}
+% \end{syntax}
+% Unpacks the content of the vertical \meta{box}, retaining any stretching
+% or shrinking applied when the \meta{box} was set.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{unvcopy}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Using boxes efficiently}
+%
+% The functions above for using box contents work in exactly the same
+% way as for any other \pkg{expl3} variable. However, for efficiency
+% reasons, it is also useful to have functions which \emph{drop} box
+% contents on use. When a box is dropped, the box becomes empty at the group
+% level \emph{where the box was originally set} rather than necessarily
+% \emph{at the current group level}. For example, with
+% \begin{verbatim}
+% \hbox_set:Nn \l_tmpa_box { A }
+% \group_begin:
+% \hbox_set:Nn \l_tmpa_box { B }
+% \group_begin:
+% \box_use_drop:N \l_tmpa_box
+% \group_end:
+% \box_show:N \l_tmpa_box
+% \group_end:
+% \box_show:N \l_tmpa_box
+% \end{verbatim}
+% the first use of \cs{box_show:N} will show an entirely cleared (void) box, and the
+% second will show the letter |A| in the box.
+%
+% These functions should be preferred when the content of the box is no
+% longer required after use. Note that due to the unusual scoping behaviour of
+% \texttt{drop} functions they may be applied to both local and global boxes:
+% the latter will naturally be set and thus cleared at a global level.
+%
+% \begin{function}{\box_use_drop:N, \box_use_drop:c}
+% \begin{syntax}
+% \cs{box_use_drop:N} \meta{box}
+% \end{syntax}
+% Inserts the current content of the \meta{box} onto the current
+% list for typesetting then drops the box content. An error is raised if the
+% variable does not exist or if it is invalid. This function may be applied to
+% local or global boxes.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{box}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2019-01-17]
+% {
+% \box_set_eq_drop:NN, \box_set_eq_drop:cN,
+% \box_set_eq_drop:Nc, \box_set_eq_drop:cc
+% }
+% \begin{syntax}
+% \cs{box_set_eq_drop:NN} \meta{box_1} \meta{box_2}
+% \end{syntax}
+% Sets the content of \meta{box_1} equal to that of \meta{box_2}, then
+% drops \meta{box_2}.
+% \end{function}
+%
+% \begin{function}[added = 2019-01-17]
+% {
+% \box_gset_eq_drop:NN, \box_gset_eq_drop:cN,
+% \box_gset_eq_drop:Nc, \box_gset_eq_drop:cc
+% }
+% \begin{syntax}
+% \cs{box_gset_eq_drop:NN} \meta{box_1} \meta{box_2}
+% \end{syntax}
+% Sets the content of \meta{box_1} globally equal to that of \meta{box_2},
+% then drops \meta{box_2}.
+% \end{function}
+%
+% \begin{function}[added = 2019-01-17]
+% {\hbox_unpack_drop:N, \hbox_unpack_drop:c}
+% \begin{syntax}
+% \cs{hbox_unpack_drop:N} \meta{box}
+% \end{syntax}
+% Unpacks the content of the horizontal \meta{box}, retaining any stretching
+% or shrinking applied when the \meta{box} was set. The original \meta{box}
+% is then dropped.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{unhbox}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2019-01-17]
+% {\vbox_unpack_drop:N, \vbox_unpack_drop:c}
+% \begin{syntax}
+% \cs{vbox_unpack_drop:N} \meta{box}
+% \end{syntax}
+% Unpacks the content of the vertical \meta{box}, retaining any stretching
+% or shrinking applied when the \meta{box} was set. The original \meta{box}
+% is then dropped.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{unvbox}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Affine transformations}
+%
+% Affine transformations are changes which (informally) preserve straight
+% lines. Simple translations are affine transformations, but are better handled
+% in \TeX{} by doing the translation first, then inserting an unmodified box.
+% On the other hand, rotation and resizing of boxed material can best be
+% handled by modifying boxes. These transformations are described here.
+%
+% \begin{function}[added = 2017-04-04, updated = 2019-01-22]
+% {
+% \box_autosize_to_wd_and_ht:Nnn, \box_autosize_to_wd_and_ht:cnn,
+% \box_gautosize_to_wd_and_ht:Nnn, \box_gautosize_to_wd_and_ht:cnn,
+% }
+% \begin{syntax}
+% \cs{box_autosize_to_wd_and_ht:Nnn} \meta{box} \Arg{x-size} \Arg{y-size}
+% \end{syntax}
+% Resizes the \meta{box} to fit within the given \meta{x-size} (horizontally)
+% and \meta{y-size} (vertically); both of the sizes are dimension
+% expressions. The \meta{y-size} is the height only: it does not include any
+% depth. The updated \meta{box} is an |hbox|, irrespective of the nature
+% of the \meta{box} before the resizing is applied. The final size of the
+% \meta{box} is the smaller of \Arg{x-size} and \Arg{y-size},
+% \emph{i.e.}~the result fits within the dimensions specified. Negative
+% sizes cause the material in the \meta{box} to be reversed in direction,
+% but the reference point of the \meta{box} is unchanged. Thus a negative
+% \meta{y-size} results in the \meta{box} having a depth dependent on the
+% height of the original and \emph{vice versa}.
+% \end{function}
+%
+% \begin{function}[added = 2017-04-04, updated = 2019-01-22]
+% {
+% \box_autosize_to_wd_and_ht_plus_dp:Nnn,
+% \box_autosize_to_wd_and_ht_plus_dp:cnn,
+% \box_gautosize_to_wd_and_ht_plus_dp:Nnn,
+% \box_gautosize_to_wd_and_ht_plus_dp:cnn
+% }
+% \begin{syntax}
+% \cs{box_autosize_to_wd_and_ht_plus_dp:Nnn} \meta{box} \Arg{x-size} \Arg{y-size}
+% \end{syntax}
+% Resizes the \meta{box} to fit within the given \meta{x-size} (horizontally)
+% and \meta{y-size} (vertically); both of the sizes are dimension
+% expressions. The \meta{y-size} is the total vertical size (height plus
+% depth). The updated \meta{box} is an |hbox|, irrespective of the nature
+% of the \meta{box} before the resizing is applied. The final size of the
+% \meta{box} is the smaller of \Arg{x-size} and \Arg{y-size},
+% \emph{i.e.}~the result fits within the dimensions specified. Negative
+% sizes cause the material in the \meta{box} to be reversed in direction,
+% but the reference point of the \meta{box} is unchanged. Thus a negative
+% \meta{y-size} results in the \meta{box} having a depth dependent on the
+% height of the original and \emph{vice versa}.
+% \end{function}
+%
+% \begin{function}[updated = 2019-01-22]
+% {
+% \box_resize_to_ht:Nn, \box_resize_to_ht:cn,
+% \box_gresize_to_ht:Nn, \box_gresize_to_ht:cn
+% }
+% \begin{syntax}
+% \cs{box_resize_to_ht:Nn} \meta{box} \Arg{y-size}
+% \end{syntax}
+% Resizes the \meta{box} to \meta{y-size} (vertically), scaling the horizontal
+% size by the same amount; \meta{y-size} is a dimension expression. The
+% \meta{y-size} is the height only: it does not include any depth. The updated
+% \meta{box} is an |hbox|, irrespective of the nature of the \meta{box}
+% before the resizing is applied. A negative \meta{y-size} causes the
+% material in the \meta{box} to be reversed in direction, but the reference
+% point of the \meta{box} is unchanged. Thus a negative \meta{y-size}
+% results in the \meta{box} having a depth dependent on the height of the
+% original and \emph{vice versa}.
+% \end{function}
+%
+% \begin{function}[updated = 2019-01-22]
+% {
+% \box_resize_to_ht_plus_dp:Nn, \box_resize_to_ht_plus_dp:cn,
+% \box_gresize_to_ht_plus_dp:Nn, \box_gresize_to_ht_plus_dp:cn,
+% }
+% \begin{syntax}
+% \cs{box_resize_to_ht_plus_dp:Nn} \meta{box} \Arg{y-size}
+% \end{syntax}
+% Resizes the \meta{box} to \meta{y-size} (vertically), scaling the horizontal
+% size by the same amount; \meta{y-size} is a dimension expression. The
+% \meta{y-size} is the total vertical size (height plus depth). The updated
+% \meta{box} is an |hbox|, irrespective of the nature of the \meta{box}
+% before the resizing is applied. A negative \meta{y-size} causes
+% the material in the \meta{box} to be reversed in direction, but the
+% reference point of the \meta{box} is unchanged. Thus a negative
+% \meta{y-size} results in the \meta{box} having a depth dependent on the
+% height of the original and \emph{vice versa}.
+% \end{function}
+%
+% \begin{function}[updated = 2019-01-22]
+% {
+% \box_resize_to_wd:Nn, \box_resize_to_wd:cn,
+% \box_gresize_to_wd:Nn, \box_gresize_to_wd:cn
+% }
+% \begin{syntax}
+% \cs{box_resize_to_wd:Nn} \meta{box} \Arg{x-size}
+% \end{syntax}
+% Resizes the \meta{box} to \meta{x-size} (horizontally), scaling the vertical
+% size by the same amount; \meta{x-size} is a dimension expression. The updated
+% \meta{box} is an |hbox|, irrespective of the nature of the \meta{box}
+% before the resizing is applied. A negative \meta{x-size} causes the
+% material in the \meta{box} to be reversed in direction, but the reference
+% point of the \meta{box} is unchanged. Thus a negative \meta{x-size}
+% results in the \meta{box} having a depth dependent on the height of the
+% original and \emph{vice versa}.
+% \end{function}
+%
+% \begin{function}[added = 2014-07-03, updated = 2019-01-22]
+% {
+% \box_resize_to_wd_and_ht:Nnn, \box_resize_to_wd_and_ht:cnn,
+% \box_gresize_to_wd_and_ht:Nnn, \box_gresize_to_wd_and_ht:cnn
+% }
+% \begin{syntax}
+% \cs{box_resize_to_wd_and_ht:Nnn} \meta{box} \Arg{x-size} \Arg{y-size}
+% \end{syntax}
+% Resizes the \meta{box} to \meta{x-size} (horizontally) and \meta{y-size}
+% (vertically): both of the sizes are dimension expressions. The
+% \meta{y-size} is the height only and does not include any depth. The updated
+% \meta{box} is an |hbox|, irrespective of the nature of the \meta{box}
+% before the resizing is applied. Negative sizes cause the material in
+% the \meta{box} to be reversed in direction, but the reference point of the
+% \meta{box} is unchanged. Thus a negative \meta{y-size} results in
+% the \meta{box} having a depth dependent on the height of the original and
+% \emph{vice versa}.
+% \end{function}
+%
+% \begin{function}[added = 2017-04-06, updated = 2019-01-22]
+% {
+% \box_resize_to_wd_and_ht_plus_dp:Nnn,
+% \box_resize_to_wd_and_ht_plus_dp:cnn,
+% \box_gresize_to_wd_and_ht_plus_dp:Nnn,
+% \box_gresize_to_wd_and_ht_plus_dp:cnn
+% }
+% \begin{syntax}
+% \cs{box_resize_to_wd_and_ht_plus_dp:Nnn} \meta{box} \Arg{x-size} \Arg{y-size}
+% \end{syntax}
+% Resizes the \meta{box} to \meta{x-size} (horizontally) and \meta{y-size}
+% (vertically): both of the sizes are dimension expressions. The
+% \meta{y-size} is the total vertical size (height plus depth). The updated
+% \meta{box} is an |hbox|, irrespective of the nature of the \meta{box}
+% before the resizing is applied. Negative sizes cause the material in
+% the \meta{box} to be reversed in direction, but the reference point of the
+% \meta{box} is unchanged. Thus a negative \meta{y-size} results in
+% the \meta{box} having a depth dependent on the height of the original and
+% \emph{vice versa}.
+% \end{function}
+%
+% \begin{function}[updated = 2019-01-22]
+% {
+% \box_rotate:Nn, \box_rotate:cn,
+% \box_grotate:Nn, \box_grotate:cn
+% }
+% \begin{syntax}
+% \cs{box_rotate:Nn} \meta{box} \Arg{angle}
+% \end{syntax}
+% Rotates the \meta{box} by \meta{angle} (a \meta{fp expr} in degrees)
+% anti-clockwise about
+% its reference point. The reference point of the updated box is moved
+% horizontally such that it is at the left side of the smallest rectangle
+% enclosing the rotated material. The updated \meta{box} is an |hbox|,
+% irrespective of the nature of the \meta{box} before the rotation is applied.
+% \end{function}
+%
+% \begin{function}[updated = 2019-01-22]
+% {
+% \box_scale:Nnn, \box_scale:cnn,
+% \box_gscale:Nnn, \box_gscale:cnn
+% }
+% \begin{syntax}
+% \cs{box_scale:Nnn} \meta{box} \Arg{x-scale} \Arg{y-scale}
+% \end{syntax}
+% Scales the \meta{box} by factors \meta{x-scale} and \meta{y-scale} in
+% the horizontal and vertical directions, respectively (both scales are
+% \meta{fp expr}). The updated \meta{box} is an |hbox|, irrespective
+% of the nature of the \meta{box} before the scaling is applied. Negative
+% scalings cause the material in the \meta{box} to be reversed in
+% direction, but the reference point of the \meta{box} is unchanged.
+% Thus a negative \meta{y-scale} results in the \meta{box} having a depth
+% dependent on the height of the original and \emph{vice versa}.
+% \end{function}
+%
+% \section{Viewing part of a box}
+%
+% \begin{function}[updated = 2023-04-14]
+% {
+% \box_set_clipped:N, \box_set_clipped:c,
+% \box_gset_clipped:N, \box_gset_clipped:c
+% }
+% \begin{syntax}
+% \cs{box_set_clipped:N} \meta{box}
+% \end{syntax}
+% Clips the \meta{box} in the output so that only material inside the
+% bounding box is displayed in the output. The updated \meta{box} is an
+% hbox, irrespective of the nature of the \meta{box} before the clipping is
+% applied. Additional box levels are also generated by this operation.
+%
+% \begin{texnote}
+% Clipping is implemented by the driver, and as such the full content of
+% the box is placed in the output file. Thus clipping does not remove
+% any information from the raw output, and hidden material can therefore
+% be viewed by direct examination of the file.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2019-01-23]
+% {
+% \box_set_trim:Nnnnn, \box_set_trim:cnnnn,
+% \box_gset_trim:Nnnnn, \box_gset_trim:cnnnn
+% }
+% \begin{syntax}
+% \cs{box_set_trim:Nnnnn} \meta{box} \Arg{left} \Arg{bottom} \Arg{right} \Arg{top}
+% \end{syntax}
+% Adjusts the bounding box of the \meta{box} \meta{left} is removed from
+% the left-hand edge of the bounding box, \meta{right} from the right-hand
+% edge and so fourth. All adjustments are \meta{dim exprs}.
+% Material outside of the bounding box is still displayed in the output
+% unless \cs{box_set_clipped:N} is subsequently applied.
+% The updated \meta{box} is an
+% hbox, irrespective of the nature of the \meta{box} before the trim
+% operation is applied.
+% Additional box levels are also generated by this operation.
+% The behavior of the operation where the trims requested is
+% greater than the size of the box is undefined.
+% \end{function}
+%
+% \begin{function}[added = 2019-01-23]
+% {
+% \box_set_viewport:Nnnnn, \box_set_viewport:cnnnn,
+% \box_gset_viewport:Nnnnn, \box_gset_viewport:cnnnn
+% }
+% \begin{syntax}
+% \cs{box_set_viewport:Nnnnn} \meta{box} \Arg{llx} \Arg{lly} \Arg{urx} \Arg{ury}
+% \end{syntax}
+% Adjusts the bounding box of the \meta{box} such that it has lower-left
+% co-ordinates (\meta{llx}, \meta{lly}) and upper-right co-ordinates
+% (\meta{urx}, \meta{ury}). All four co-ordinate positions are
+% \meta{dim exprs}. Material outside of the bounding box is
+% still displayed in the output unless \cs{box_set_clipped:N} is
+% subsequently applied.
+% The updated \meta{box} is an
+% hbox, irrespective of the nature of the \meta{box} before the viewport
+% operation is applied.
+% Additional box levels are also generated by this operation.
+% \end{function}
+%
+% \section{Primitive box conditionals}
+%
+% \begin{function}[EXP]{\if_hbox:N}
+% \begin{syntax}
+% \cs{if_hbox:N} \meta{box}
+% ~~\meta{true code}
+% \cs{else:}
+% ~~\meta{false code}
+% \cs{fi:}
+% \end{syntax}
+% Tests is \meta{box} is a horizontal box.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifhbox}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\if_vbox:N}
+% \begin{syntax}
+% \cs{if_vbox:N} \meta{box}
+% ~~\meta{true code}
+% \cs{else:}
+% ~~\meta{false code}
+% \cs{fi:}
+% \end{syntax}
+% Tests is \meta{box} is a vertical box.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifvbox}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\if_box_empty:N}
+% \begin{syntax}
+% \cs{if_box_empty:N} \meta{box}
+% ~~\meta{true code}
+% \cs{else:}
+% ~~\meta{false code}
+% \cs{fi:}
+% \end{syntax}
+% Tests is \meta{box} is an empty (void) box.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifvoid}.
+% \end{texnote}
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3box} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=box>
+% \end{macrocode}
+%
+% \subsection{Support code}
+%
+% \begin{macro}{\@@_dim_eval:w}
+% \begin{macro}{\@@_dim_eval:n}
+% Evaluating a dimension expression expandably. The only
+% difference with \cs{dim_eval:n} is the lack of \cs{dim_use:N}, to
+% produce an internal dimension rather than expand it into characters.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_dim_eval:w \tex_dimexpr:D
+\cs_new:Npn \@@_dim_eval:n #1
+ { \@@_dim_eval:w #1 \scan_stop: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_kern:n}
+% We need kerns in a few places. At present, we don't have a module for
+% this concept, so it goes in at first use: here. The idea is to avoid
+% repeated use of the bare primitive.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_kern:n #1
+ { \tex_kern:D \@@_dim_eval:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Creating and initialising boxes}
+%
+% \TestFiles{m3box001.lvt}
+%
+% \begin{macro}{\box_new:N, \box_new:c}
+% Defining a new \meta{box} register: remember that box $255$ is not
+% generally available.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_new:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \cs:w newbox \cs_end: #1
+ }
+\cs_generate_variant:Nn \box_new:N { c }
+% \end{macrocode}
+%
+% \begin{macro}{\box_clear:N, \box_clear:c}
+% \begin{macro}{\box_gclear:N, \box_gclear:c}
+% \testfile*
+% Clear a \meta{box} register.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_clear:N #1
+ { \box_set_eq:NN #1 \c_empty_box }
+\cs_new_protected:Npn \box_gclear:N #1
+ { \box_gset_eq:NN #1 \c_empty_box }
+\cs_generate_variant:Nn \box_clear:N { c }
+\cs_generate_variant:Nn \box_gclear:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\box_clear_new:N, \box_clear_new:c}
+% \begin{macro}{\box_gclear_new:N, \box_gclear_new:c}
+% \testfile*
+% Clear or new.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_clear_new:N #1
+ { \box_if_exist:NTF #1 { \box_clear:N #1 } { \box_new:N #1 } }
+\cs_new_protected:Npn \box_gclear_new:N #1
+ { \box_if_exist:NTF #1 { \box_gclear:N #1 } { \box_new:N #1 } }
+\cs_generate_variant:Nn \box_clear_new:N { c }
+\cs_generate_variant:Nn \box_gclear_new:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\box_set_eq:NN, \box_set_eq:cN, \box_set_eq:Nc, \box_set_eq:cc}
+% \testfile*
+% \begin{macro}
+% {\box_gset_eq:NN, \box_gset_eq:cN, \box_gset_eq:Nc, \box_gset_eq:cc}
+% \testfile*
+% Assigning the contents of a box to be another box.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_set_eq:NN #1#2
+ { \tex_setbox:D #1 \tex_copy:D #2 }
+\cs_new_protected:Npn \box_gset_eq:NN #1#2
+ { \tex_global:D \tex_setbox:D #1 \tex_copy:D #2 }
+\cs_generate_variant:Nn \box_set_eq:NN { c , Nc , cc }
+\cs_generate_variant:Nn \box_gset_eq:NN { c , Nc , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \box_set_eq_drop:NN, \box_set_eq_drop:cN,
+% \box_set_eq_drop:Nc, \box_set_eq_drop:cc
+% }
+% \begin{macro}
+% {
+% \box_gset_eq_drop:NN, \box_gset_eq_drop:cN,
+% \box_gset_eq_drop:Nc, \box_gset_eq_drop:cc
+% }
+% Assigning the contents of a box to be another box, then drops the
+% original box.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_set_eq_drop:NN #1#2
+ { \tex_setbox:D #1 \tex_box:D #2 }
+\cs_new_protected:Npn \box_gset_eq_drop:NN #1#2
+ { \tex_global:D \tex_setbox:D #1 \tex_box:D #2 }
+\cs_generate_variant:Nn \box_set_eq_drop:NN { c , Nc , cc }
+\cs_generate_variant:Nn \box_gset_eq_drop:NN { c , Nc , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\box_if_exist:N, \box_if_exist:c}
+% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \box_if_exist:N \cs_if_exist:N
+ { TF , T , F , p }
+\prg_new_eq_conditional:NNn \box_if_exist:c \cs_if_exist:c
+ { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Measuring and setting box dimensions}
+%
+% \begin{macro}{\box_ht:N, \box_ht:c}
+% \begin{macro}{\box_dp:N, \box_dp:c}
+% \begin{macro}{\box_wd:N, \box_wd:c}
+% \testfile*
+% Accessing the height, depth, and width of a \meta{box} register.
+% \begin{macrocode}
+\cs_new_eq:NN \box_ht:N \tex_ht:D
+\cs_new_eq:NN \box_dp:N \tex_dp:D
+\cs_new_eq:NN \box_wd:N \tex_wd:D
+\cs_generate_variant:Nn \box_ht:N { c }
+\cs_generate_variant:Nn \box_dp:N { c }
+\cs_generate_variant:Nn \box_wd:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\box_ht_plus_dp:N}
+% The \cs{box_ht:N} and \cs{box_dp:N} primitives do not expand but
+% rather are suitable for use after \tn{the} or inside dimension
+% expressions. Here we obtain the same behaviour by using
+% \cs{@@_dim_eval:n} (basically \tn{dimexpr}) rather than
+% \cs{dim_eval:n} (basically \tn{the} \tn{dimexpr}).
+% \begin{macrocode}
+\cs_new_protected:Npn \box_ht_plus_dp:N #1
+ { \@@_dim_eval:n { \box_ht:N #1 + \box_dp:N #1 } }
+\cs_generate_variant:Nn \box_ht_plus_dp:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\box_set_ht:Nn, \box_set_ht:cn, \box_gset_ht:Nn, \box_gset_ht:cn}
+% \begin{macro}{\box_set_dp:Nn, \box_set_dp:cn, \box_gset_dp:Nn, \box_gset_dp:cn}
+% \begin{macro}{\box_set_wd:Nn, \box_set_wd:cn, \box_gset_wd:Nn, \box_gset_wd:cn}
+% Setting the size whilst respecting local scope requires copying;
+% the same issue does not come up when working globally.
+% When debugging, the dimension expression |#2| is surrounded by
+% parentheses to catch early termination.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_set_dp:Nn #1#2
+ {
+ \tex_setbox:D #1 = \tex_copy:D #1
+ \box_dp:N #1 \@@_dim_eval:n {#2}
+ }
+\cs_generate_variant:Nn \box_set_dp:Nn { c }
+\cs_new_protected:Npn \box_gset_dp:Nn #1#2
+ { \box_dp:N #1 \@@_dim_eval:n {#2} }
+\cs_generate_variant:Nn \box_gset_dp:Nn { c }
+\cs_new_protected:Npn \box_set_ht:Nn #1#2
+ {
+ \tex_setbox:D #1 = \tex_copy:D #1
+ \box_ht:N #1 \@@_dim_eval:n {#2}
+ }
+\cs_generate_variant:Nn \box_set_ht:Nn { c }
+\cs_new_protected:Npn \box_gset_ht:Nn #1#2
+ { \box_ht:N #1 \@@_dim_eval:n {#2} }
+\cs_generate_variant:Nn \box_gset_ht:Nn { c }
+\cs_new_protected:Npn \box_set_wd:Nn #1#2
+ {
+ \tex_setbox:D #1 = \tex_copy:D #1
+ \box_wd:N #1 \@@_dim_eval:n {#2}
+ }
+\cs_generate_variant:Nn \box_set_wd:Nn { c }
+\cs_new_protected:Npn \box_gset_wd:Nn #1#2
+ { \box_wd:N #1 \@@_dim_eval:n {#2} }
+\cs_generate_variant:Nn \box_gset_wd:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using boxes}
+%
+% \begin{macro}{\box_use_drop:N, \box_use_drop:c}
+% \begin{macro}{\box_use:N, \box_use:c}
+% Using a \meta{box}. These are just \TeX{} primitives with meaningful
+% names.
+% \begin{macrocode}
+\cs_new_eq:NN \box_use_drop:N \tex_box:D
+\cs_new_eq:NN \box_use:N \tex_copy:D
+\cs_generate_variant:Nn \box_use_drop:N { c }
+\cs_generate_variant:Nn \box_use:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\box_move_left:nn, \box_move_right:nn}
+% \begin{macro}{\box_move_up:nn, \box_move_down:nn}
+% \testfile*
+% Move box material in different directions.
+% When debugging, the dimension expression |#1| is surrounded by
+% parentheses to catch early termination.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_move_left:nn #1#2
+ { \tex_moveleft:D \@@_dim_eval:n {#1} #2 }
+\cs_new_protected:Npn \box_move_right:nn #1#2
+ { \tex_moveright:D \@@_dim_eval:n {#1} #2 }
+\cs_new_protected:Npn \box_move_up:nn #1#2
+ { \tex_raise:D \@@_dim_eval:n {#1} #2 }
+\cs_new_protected:Npn \box_move_down:nn #1#2
+ { \tex_lower:D \@@_dim_eval:n {#1} #2 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Box conditionals}
+%
+% \begin{macro}{\if_hbox:N}
+% \begin{macro}{\if_vbox:N}
+% \begin{macro}{\if_box_empty:N}
+% \testfile*
+% The primitives for testing if a \meta{box} is empty/void or which
+% type of box it is.
+% \begin{macrocode}
+\cs_new_eq:NN \if_hbox:N \tex_ifhbox:D
+\cs_new_eq:NN \if_vbox:N \tex_ifvbox:D
+\cs_new_eq:NN \if_box_empty:N \tex_ifvoid:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\box_if_horizontal:N, \box_if_horizontal:c}
+% \testfile*
+% \begin{macro}[pTF]{\box_if_vertical:N, \box_if_vertical:c}
+% \testfile*
+% \begin{macrocode}
+\prg_new_conditional:Npnn \box_if_horizontal:N #1 { p , T , F , TF }
+ { \if_hbox:N #1 \prg_return_true: \else: \prg_return_false: \fi: }
+\prg_new_conditional:Npnn \box_if_vertical:N #1 { p , T , F , TF }
+ { \if_vbox:N #1 \prg_return_true: \else: \prg_return_false: \fi: }
+\prg_generate_conditional_variant:Nnn \box_if_horizontal:N
+ { c } { p , T , F , TF }
+\prg_generate_conditional_variant:Nnn \box_if_vertical:N
+ { c } { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\box_if_empty:N, \box_if_empty:c}
+% \testfile*
+% Testing if a \meta{box} is empty/void.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \box_if_empty:N #1 { p , T , F , TF }
+ { \if_box_empty:N #1 \prg_return_true: \else: \prg_return_false: \fi: }
+\prg_generate_conditional_variant:Nnn \box_if_empty:N
+ { c } { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{The last box inserted}
+%
+% \begin{macro}{\box_set_to_last:N, \box_set_to_last:c}
+% \begin{macro}{\box_gset_to_last:N, \box_gset_to_last:c}
+% \testfile*
+% Set a box to the previous box.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_set_to_last:N #1
+ { \tex_setbox:D #1 \tex_lastbox:D }
+\cs_new_protected:Npn \box_gset_to_last:N #1
+ { \tex_global:D \tex_setbox:D #1 \tex_lastbox:D }
+\cs_generate_variant:Nn \box_set_to_last:N { c }
+\cs_generate_variant:Nn \box_gset_to_last:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Constant boxes}
+%
+% \begin{variable}{\c_empty_box}
+% A box we never use.
+% \begin{macrocode}
+\box_new:N \c_empty_box
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Scratch boxes}
+%
+% \begin{variable}{\l_tmpa_box, \l_tmpb_box, \g_tmpa_box, \g_tmpb_box}
+% Scratch boxes.
+% \begin{macrocode}
+\box_new:N \l_tmpa_box
+\box_new:N \l_tmpb_box
+\box_new:N \g_tmpa_box
+\box_new:N \g_tmpb_box
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Viewing box contents}
+%
+% \TeX{}'s \tn{showbox} is not really that helpful in many cases, and
+% it is also inconsistent with other \LaTeX3{} \texttt{show} functions as it
+% does not actually shows material in the terminal. So we provide a richer
+% set of functionality.
+%
+% \begin{macro}{\box_show:N, \box_show:c}
+% \begin{macro}{\box_show:Nnn, \box_show:cnn}
+% Essentially a wrapper around the internal function, but evaluating
+% the breadth and depth arguments now outside the group.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_show:N #1
+ { \box_show:Nnn #1 \c_max_int \c_max_int }
+\cs_generate_variant:Nn \box_show:N { c }
+\cs_new_protected:Npn \box_show:Nnn #1#2#3
+ { \@@_show:NNff 1 #1 { \int_eval:n {#2} } { \int_eval:n {#3} } }
+\cs_generate_variant:Nn \box_show:Nnn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\box_log:N, \box_log:c}
+% \begin{macro}{\box_log:Nnn, \box_log:cnn}
+% \begin{macro}{\@@_log:nNnn}
+% Getting \TeX{} to write to the log without interruption the run is done by
+% altering the interaction mode. For that, the \eTeX{} extensions are needed.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_log:N #1
+ { \box_log:Nnn #1 \c_max_int \c_max_int }
+\cs_generate_variant:Nn \box_log:N { c }
+\cs_new_protected:Npn \box_log:Nnn
+ { \exp_args:No \@@_log:nNnn { \tex_the:D \tex_interactionmode:D } }
+\cs_new_protected:Npn \@@_log:nNnn #1#2#3#4
+ {
+ \int_gset:Nn \tex_interactionmode:D { 0 }
+ \@@_show:NNff 0 #2 { \int_eval:n {#3} } { \int_eval:n {#4} }
+ \int_gset:Nn \tex_interactionmode:D {#1}
+ }
+\cs_generate_variant:Nn \box_log:Nnn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_show:NNnn, \@@_show:NNff}
+% The internal auxiliary to actually do the output uses a group to deal
+% with breadth and depth values. The \cs{use:n} here gives better output
+% appearance. Setting \tn{tracingonline} and \tn{errorcontextlines} is
+% used to control what appears in the terminal.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show:NNnn #1#2#3#4
+ {
+ \box_if_exist:NTF #2
+ {
+ \group_begin:
+ \int_set:Nn \tex_showboxbreadth:D {#3}
+ \int_set:Nn \tex_showboxdepth:D {#4}
+ \int_set:Nn \tex_tracingonline:D {#1}
+ \int_set:Nn \tex_errorcontextlines:D { -1 }
+ \tex_showbox:D \use:n {#2}
+ \group_end:
+ }
+ {
+ \msg_error:nne { kernel } { variable-not-defined }
+ { \token_to_str:N #2 }
+ }
+ }
+\cs_generate_variant:Nn \@@_show:NNnn { NNff }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Horizontal mode boxes}
+%
+% \begin{macro}{\hbox:n}
+% \testfile{m3box002.lvt}
+% Put a horizontal box directly into the input stream.
+% \begin{macrocode}
+\cs_new_protected:Npn \hbox:n #1
+ { \tex_hbox:D \scan_stop: { \color_group_begin: #1 \color_group_end: } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hbox_set:Nn, \hbox_set:cn}
+% \begin{macro}{\hbox_gset:Nn, \hbox_gset:cn}
+% \testfile*
+% \begin{macrocode}
+\cs_new_protected:Npn \hbox_set:Nn #1#2
+ {
+ \tex_setbox:D #1 \tex_hbox:D
+ { \color_group_begin: #2 \color_group_end: }
+ }
+\cs_new_protected:Npn \hbox_gset:Nn #1#2
+ {
+ \tex_global:D \tex_setbox:D #1 \tex_hbox:D
+ { \color_group_begin: #2 \color_group_end: }
+ }
+\cs_generate_variant:Nn \hbox_set:Nn { c }
+\cs_generate_variant:Nn \hbox_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hbox_set_to_wd:Nnn, \hbox_set_to_wd:cnn}
+% \begin{macro}{\hbox_gset_to_wd:Nnn, \hbox_gset_to_wd:cnn}
+% \testfile*
+% Storing material in a horizontal box with a specified width.
+% Again, put the dimension expression in parentheses when debugging.
+% \begin{macrocode}
+\cs_new_protected:Npn \hbox_set_to_wd:Nnn #1#2#3
+ {
+ \tex_setbox:D #1 \tex_hbox:D to \@@_dim_eval:n {#2}
+ { \color_group_begin: #3 \color_group_end: }
+ }
+\cs_new_protected:Npn \hbox_gset_to_wd:Nnn #1#2#3
+ {
+ \tex_global:D \tex_setbox:D #1 \tex_hbox:D to \@@_dim_eval:n {#2}
+ { \color_group_begin: #3 \color_group_end: }
+ }
+\cs_generate_variant:Nn \hbox_set_to_wd:Nnn { c }
+\cs_generate_variant:Nn \hbox_gset_to_wd:Nnn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hbox_set:Nw, \hbox_set:cw}
+% \begin{macro}{\hbox_gset:Nw, \hbox_gset:cw}
+% \begin{macro}{\hbox_set_end:, \hbox_gset_end:}
+% \testfile*
+% Storing material in a horizontal box. This type is useful in
+% environment definitions.
+% \begin{macrocode}
+\cs_new_protected:Npn \hbox_set:Nw #1
+ {
+ \tex_setbox:D #1 \tex_hbox:D
+ \c_group_begin_token
+ \color_group_begin:
+ }
+\cs_new_protected:Npn \hbox_gset:Nw #1
+ {
+ \tex_global:D \tex_setbox:D #1 \tex_hbox:D
+ \c_group_begin_token
+ \color_group_begin:
+ }
+\cs_generate_variant:Nn \hbox_set:Nw { c }
+\cs_generate_variant:Nn \hbox_gset:Nw { c }
+\cs_new_protected:Npn \hbox_set_end:
+ {
+ \color_group_end:
+ \c_group_end_token
+ }
+\cs_new_eq:NN \hbox_gset_end: \hbox_set_end:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hbox_set_to_wd:Nnw, \hbox_set_to_wd:cnw}
+% \begin{macro}{\hbox_gset_to_wd:Nnw, \hbox_gset_to_wd:cnw}
+% Combining the above ideas.
+% \begin{macrocode}
+\cs_new_protected:Npn \hbox_set_to_wd:Nnw #1#2
+ {
+ \tex_setbox:D #1 \tex_hbox:D to \@@_dim_eval:n {#2}
+ \c_group_begin_token
+ \color_group_begin:
+ }
+\cs_new_protected:Npn \hbox_gset_to_wd:Nnw #1#2
+ {
+ \tex_global:D \tex_setbox:D #1 \tex_hbox:D to \@@_dim_eval:n {#2}
+ \c_group_begin_token
+ \color_group_begin:
+ }
+\cs_generate_variant:Nn \hbox_set_to_wd:Nnw { c }
+\cs_generate_variant:Nn \hbox_gset_to_wd:Nnw { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hbox_to_wd:nn}
+% \begin{macro}{\hbox_to_zero:n}
+% \testfile*
+% Put a horizontal box directly into the input stream.
+% \begin{macrocode}
+\cs_new_protected:Npn \hbox_to_wd:nn #1#2
+ {
+ \tex_hbox:D to \@@_dim_eval:n {#1}
+ { \color_group_begin: #2 \color_group_end: }
+ }
+\cs_new_protected:Npn \hbox_to_zero:n #1
+ {
+ \tex_hbox:D to \c_zero_dim
+ { \color_group_begin: #1 \color_group_end: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hbox_overlap_center:n, \hbox_overlap_left:n, \hbox_overlap_right:n}
+% Put a zero-sized box with the contents pushed against one side (which
+% makes it stick out on the other) directly into the input stream.
+% \begin{macrocode}
+\cs_new_protected:Npn \hbox_overlap_center:n #1
+ { \hbox_to_zero:n { \tex_hss:D #1 \tex_hss:D } }
+\cs_new_protected:Npn \hbox_overlap_left:n #1
+ { \hbox_to_zero:n { \tex_hss:D #1 } }
+\cs_new_protected:Npn \hbox_overlap_right:n #1
+ { \hbox_to_zero:n { #1 \tex_hss:D } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hbox_unpack:N, \hbox_unpack:c}
+% \begin{macro}{\hbox_unpack_drop:N, \hbox_unpack_drop:c}
+% \testfile*
+% Unpacking a box and if requested also clear it.
+% \begin{macrocode}
+\cs_new_eq:NN \hbox_unpack:N \tex_unhcopy:D
+\cs_new_eq:NN \hbox_unpack_drop:N \tex_unhbox:D
+\cs_generate_variant:Nn \hbox_unpack:N { c }
+\cs_generate_variant:Nn \hbox_unpack_drop:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Vertical mode boxes}
+%
+% \TeX{} ends these boxes directly with the internal \emph{end_graf}
+% routine. This means that there is no \cs{par} at the end of vertical
+% boxes unless we insert one. Thus all vertical boxes include a \cs{par}
+% just before closing the color group.
+%
+% \begin{macro}{\vbox:n}
+% \TestFiles{m3box003.lvt}
+% \begin{macro}{\vbox_top:n}
+% \TestFiles{m3box003.lvt}
+% Put a vertical box directly into the input stream.
+% \begin{macrocode}
+\cs_new_protected:Npn \vbox:n #1
+ { \tex_vbox:D { \color_group_begin: #1 \par \color_group_end: } }
+\cs_new_protected:Npn \vbox_top:n #1
+ { \tex_vtop:D { \color_group_begin: #1 \par \color_group_end: } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\vbox_to_ht:nn, \vbox_to_zero:n}
+% \begin{macro}{\vbox_to_ht:nn, \vbox_to_zero:n}
+% \testfile*
+% Put a vertical box directly into the input stream.
+% \begin{macrocode}
+\cs_new_protected:Npn \vbox_to_ht:nn #1#2
+ {
+ \tex_vbox:D to \@@_dim_eval:n {#1}
+ { \color_group_begin: #2 \par \color_group_end: }
+ }
+\cs_new_protected:Npn \vbox_to_zero:n #1
+ {
+ \tex_vbox:D to \c_zero_dim
+ { \color_group_begin: #1 \par \color_group_end: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\vbox_set:Nn, \vbox_set:cn}
+% \begin{macro}{\vbox_gset:Nn, \vbox_gset:cn}
+% \testfile*
+% Storing material in a vertical box with a natural height.
+% \begin{macrocode}
+\cs_new_protected:Npn \vbox_set:Nn #1#2
+ {
+ \tex_setbox:D #1 \tex_vbox:D
+ { \color_group_begin: #2 \par \color_group_end: }
+ }
+\cs_new_protected:Npn \vbox_gset:Nn #1#2
+ {
+ \tex_global:D \tex_setbox:D #1 \tex_vbox:D
+ { \color_group_begin: #2 \par \color_group_end: }
+ }
+\cs_generate_variant:Nn \vbox_set:Nn { c }
+\cs_generate_variant:Nn \vbox_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\vbox_set_top:Nn, \vbox_set_top:cn}
+% \begin{macro}{\vbox_gset_top:Nn, \vbox_gset_top:cn}
+% \testfile*
+% Storing material in a vertical box with a natural height and reference
+% point at the baseline of the first object in the box.
+% \begin{macrocode}
+\cs_new_protected:Npn \vbox_set_top:Nn #1#2
+ {
+ \tex_setbox:D #1 \tex_vtop:D
+ { \color_group_begin: #2 \par \color_group_end: }
+ }
+\cs_new_protected:Npn \vbox_gset_top:Nn #1#2
+ {
+ \tex_global:D \tex_setbox:D #1 \tex_vtop:D
+ { \color_group_begin: #2 \par \color_group_end: }
+ }
+\cs_generate_variant:Nn \vbox_set_top:Nn { c }
+\cs_generate_variant:Nn \vbox_gset_top:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\vbox_set_to_ht:Nnn, \vbox_set_to_ht:cnn}
+% \begin{macro}{\vbox_gset_to_ht:Nnn, \vbox_gset_to_ht:cnn}
+% \testfile*
+% Storing material in a vertical box with a specified height.
+% \begin{macrocode}
+\cs_new_protected:Npn \vbox_set_to_ht:Nnn #1#2#3
+ {
+ \tex_setbox:D #1 \tex_vbox:D to \@@_dim_eval:n {#2}
+ { \color_group_begin: #3 \par \color_group_end: }
+ }
+\cs_new_protected:Npn \vbox_gset_to_ht:Nnn #1#2#3
+ {
+ \tex_global:D \tex_setbox:D #1 \tex_vbox:D to \@@_dim_eval:n {#2}
+ { \color_group_begin: #3 \par \color_group_end: }
+ }
+\cs_generate_variant:Nn \vbox_set_to_ht:Nnn { c }
+\cs_generate_variant:Nn \vbox_gset_to_ht:Nnn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\vbox_set:Nw, \vbox_set:cw}
+% \begin{macro}{\vbox_gset:Nw, \vbox_gset:cw}
+% \begin{macro}{\vbox_set_end:, \vbox_gset_end:}
+% \testfile*
+% Storing material in a vertical box. This type is useful in
+% environment definitions.
+% \begin{macrocode}
+\cs_new_protected:Npn \vbox_set:Nw #1
+ {
+ \tex_setbox:D #1 \tex_vbox:D
+ \c_group_begin_token
+ \color_group_begin:
+ }
+\cs_new_protected:Npn \vbox_gset:Nw #1
+ {
+ \tex_global:D \tex_setbox:D #1 \tex_vbox:D
+ \c_group_begin_token
+ \color_group_begin:
+ }
+\cs_generate_variant:Nn \vbox_set:Nw { c }
+\cs_generate_variant:Nn \vbox_gset:Nw { c }
+\cs_new_protected:Npn \vbox_set_end:
+ {
+ \par
+ \color_group_end:
+ \c_group_end_token
+ }
+\cs_new_eq:NN \vbox_gset_end: \vbox_set_end:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\vbox_set_to_ht:Nnw, \vbox_set_to_ht:cnw}
+% \begin{macro}{\vbox_gset_to_ht:Nnw, \vbox_gset_to_ht:cnw}
+% A combination of the above ideas.
+% \begin{macrocode}
+\cs_new_protected:Npn \vbox_set_to_ht:Nnw #1#2
+ {
+ \tex_setbox:D #1 \tex_vbox:D to \@@_dim_eval:n {#2}
+ \c_group_begin_token
+ \color_group_begin:
+ }
+\cs_new_protected:Npn \vbox_gset_to_ht:Nnw #1#2
+ {
+ \tex_global:D \tex_setbox:D #1 \tex_vbox:D to \@@_dim_eval:n {#2}
+ \c_group_begin_token
+ \color_group_begin:
+ }
+\cs_generate_variant:Nn \vbox_set_to_ht:Nnw { c }
+\cs_generate_variant:Nn \vbox_gset_to_ht:Nnw { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\vbox_unpack:N, \vbox_unpack:c}
+% \begin{macro}{\vbox_unpack_drop:N, \vbox_unpack_drop:c}
+% \testfile*
+% Unpacking a box and if requested also clear it.
+% \begin{macrocode}
+\cs_new_eq:NN \vbox_unpack:N \tex_unvcopy:D
+\cs_new_eq:NN \vbox_unpack_drop:N \tex_unvbox:D
+\cs_generate_variant:Nn \vbox_unpack:N { c }
+\cs_generate_variant:Nn \vbox_unpack_drop:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \vbox_set_split_to_ht:NNn, \vbox_set_split_to_ht:cNn,
+% \vbox_set_split_to_ht:Ncn, \vbox_set_split_to_ht:ccn,
+% \vbox_gset_split_to_ht:NNn, \vbox_gset_split_to_ht:cNn,
+% \vbox_gset_split_to_ht:Ncn, \vbox_gset_split_to_ht:ccn,
+% }
+% \testfile*
+% Splitting a vertical box in two.
+% \begin{macrocode}
+\cs_new_protected:Npn \vbox_set_split_to_ht:NNn #1#2#3
+ { \tex_setbox:D #1 \tex_vsplit:D #2 to \@@_dim_eval:n {#3} }
+\cs_generate_variant:Nn \vbox_set_split_to_ht:NNn { c , Nc , cc }
+\cs_new_protected:Npn \vbox_gset_split_to_ht:NNn #1#2#3
+ {
+ \tex_global:D \tex_setbox:D #1
+ \tex_vsplit:D #2 to \@@_dim_eval:n {#3}
+ }
+\cs_generate_variant:Nn \vbox_gset_split_to_ht:NNn { c , Nc , cc }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Affine transformations}
+%
+% \begin{variable}{\l_@@_angle_fp}
+% When rotating boxes, the angle itself may be needed by the
+% engine-dependent code. This is done using the \pkg{fp} module so
+% that the value is tidied up properly.
+% \begin{macrocode}
+\fp_new:N \l_@@_angle_fp
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_cos_fp, \l_@@_sin_fp}
+% These are used to hold the calculated sine and cosine values while
+% carrying out a rotation.
+% \begin{macrocode}
+\fp_new:N \l_@@_cos_fp
+\fp_new:N \l_@@_sin_fp
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {\l_@@_top_dim, \l_@@_bottom_dim, \l_@@_left_dim, \l_@@_right_dim}
+% These are the positions of the four edges of a box before
+% manipulation.
+% \begin{macrocode}
+\dim_new:N \l_@@_top_dim
+\dim_new:N \l_@@_bottom_dim
+\dim_new:N \l_@@_left_dim
+\dim_new:N \l_@@_right_dim
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \l_@@_top_new_dim, \l_@@_bottom_new_dim ,
+% \l_@@_left_new_dim, \l_@@_right_new_dim
+% }
+% These are the positions of the four edges of a box after
+% manipulation.
+% \begin{macrocode}
+\dim_new:N \l_@@_top_new_dim
+\dim_new:N \l_@@_bottom_new_dim
+\dim_new:N \l_@@_left_new_dim
+\dim_new:N \l_@@_right_new_dim
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_internal_box}
+% Scratch space, but also needed by some parts of the driver.
+% \begin{macrocode}
+\box_new:N \l_@@_internal_box
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \box_rotate:Nn, \box_rotate:cn,
+% \box_grotate:Nn, \box_grotate:cn
+% }
+% \begin{macro}{\@@_rotate:NnN}
+% \begin{macro}{\@@_rotate:N}
+% \begin{macro}{\@@_rotate_xdir:nnN, \@@_rotate_ydir:nnN}
+% \begin{macro}
+% {
+% \@@_rotate_quadrant_one:, \@@_rotate_quadrant_two:,
+% \@@_rotate_quadrant_three:, \@@_rotate_quadrant_four:
+% }
+% Rotation of a box starts with working out the relevant sine and
+% cosine. The actual rotation is in an auxiliary to keep the flow slightly
+% clearer
+% \begin{macrocode}
+\cs_new_protected:Npn \box_rotate:Nn #1#2
+ { \@@_rotate:NnN #1 {#2} \hbox_set:Nn }
+\cs_generate_variant:Nn \box_rotate:Nn { c }
+\cs_new_protected:Npn \box_grotate:Nn #1#2
+ { \@@_rotate:NnN #1 {#2} \hbox_gset:Nn }
+\cs_generate_variant:Nn \box_grotate:Nn { c }
+\cs_new_protected:Npn \@@_rotate:NnN #1#2#3
+ {
+ #3 #1
+ {
+ \fp_set:Nn \l_@@_angle_fp {#2}
+ \fp_set:Nn \l_@@_sin_fp { sind ( \l_@@_angle_fp ) }
+ \fp_set:Nn \l_@@_cos_fp { cosd ( \l_@@_angle_fp ) }
+ \@@_rotate:N #1
+ }
+ }
+% \end{macrocode}
+% The edges of the box are then recorded: the left edge is
+% always at zero. Rotation of the four edges then takes place: this is
+% most efficiently done on a quadrant by quadrant basis.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_rotate:N #1
+ {
+ \dim_set:Nn \l_@@_top_dim { \box_ht:N #1 }
+ \dim_set:Nn \l_@@_bottom_dim { -\box_dp:N #1 }
+ \dim_set:Nn \l_@@_right_dim { \box_wd:N #1 }
+ \dim_zero:N \l_@@_left_dim
+% \end{macrocode}
+% The next step is to work out the $x$ and $y$ coordinates of vertices of
+% the rotated box in relation to its original coordinates. The box can be
+% visualized with vertices $B$, $C$, $D$ and $E$ is illustrated
+% (Figure~\ref{fig:l3box:rotation}). The vertex $O$ is the reference point
+% on the baseline, and in this implementation is also the centre of rotation.
+% \begin{figure}
+% \centering
+% \setlength{\unitlength}{3pt}^^A
+% \begin{picture}(34,36)(12,44)
+% \thicklines
+% \put(20,52){\dashbox{1}(20,21){}}
+% \put(20,80){\line(0,-1){36}}
+% \put(12,58){\line(1, 0){34}}
+% \put(41,59){A}
+% \put(40,74){B}
+% \put(21,74){C}
+% \put(21,49){D}
+% \put(40,49){E}
+% \put(21,59){O}
+% \end{picture}
+% \caption{Co-ordinates of a box prior to rotation.}
+% \label{fig:l3box:rotation}
+% \end{figure}
+% The formulae are, for a point $P$ and angle $\alpha$:
+% \[
+% \begin{array}{l}
+% P'_x = P_x - O_x \\
+% P'_y = P_y - O_y \\
+% P''_x = ( P'_x \cos(\alpha)) - ( P'_y \sin(\alpha) ) \\
+% P''_y = ( P'_x \sin(\alpha)) + ( P'_y \cos(\alpha) ) \\
+% P'''_x = P''_x + O_x + L_x \\
+% P'''_y = P''_y + O_y
+% \end{array}
+% \]
+% The \enquote{extra} horizontal translation $L_x$ at the end is calculated
+% so that the leftmost point of the resulting box has $x$-coordinate $0$.
+% This is desirable as \TeX{} boxes must have the reference point at
+% the left edge of the box. (As $O$ is always $(0,0)$, this part of the
+% calculation is omitted here.)
+% \begin{macrocode}
+ \fp_compare:nNnTF \l_@@_sin_fp > \c_zero_fp
+ {
+ \fp_compare:nNnTF \l_@@_cos_fp > \c_zero_fp
+ { \@@_rotate_quadrant_one: }
+ { \@@_rotate_quadrant_two: }
+ }
+ {
+ \fp_compare:nNnTF \l_@@_cos_fp < \c_zero_fp
+ { \@@_rotate_quadrant_three: }
+ { \@@_rotate_quadrant_four: }
+ }
+% \end{macrocode}
+% The position of the box edges are now known, but the box at this
+% stage be misplaced relative to the current \TeX{} reference point. So the
+% content of the box is moved such that the reference point of the
+% rotated box is in the same place as the original.
+% \begin{macrocode}
+ \hbox_set:Nn \l_@@_internal_box { \box_use:N #1 }
+ \hbox_set:Nn \l_@@_internal_box
+ {
+ \__kernel_kern:n { -\l_@@_left_new_dim }
+ \hbox:n
+ {
+ \@@_backend_rotate:Nn
+ \l_@@_internal_box
+ \l_@@_angle_fp
+ }
+ }
+% \end{macrocode}
+% Tidy up the size of the box so that the material is actually inside
+% the bounding box. The result can then be used to reset the original
+% box.
+% \begin{macrocode}
+ \box_set_ht:Nn \l_@@_internal_box { \l_@@_top_new_dim }
+ \box_set_dp:Nn \l_@@_internal_box { -\l_@@_bottom_new_dim }
+ \box_set_wd:Nn \l_@@_internal_box
+ { \l_@@_right_new_dim - \l_@@_left_new_dim }
+ \box_use_drop:N \l_@@_internal_box
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% These functions take a general point $(|#1|, |#2|)$ and rotate its
+% location about the origin, using the previously-set sine and cosine
+% values. Each function gives only one component of the location of the
+% updated point. This is because for rotation of a box each step needs
+% only one value, and so performance is gained by avoiding working
+% out both $x'$ and $y'$ at the same time. Contrast this with
+% the equivalent function in the \pkg{l3coffins} module, where both parts
+% are needed.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_rotate_xdir:nnN #1#2#3
+ {
+ \dim_set:Nn #3
+ {
+ \fp_to_dim:n
+ {
+ \l_@@_cos_fp * \dim_to_fp:n {#1}
+ - \l_@@_sin_fp * \dim_to_fp:n {#2}
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_rotate_ydir:nnN #1#2#3
+ {
+ \dim_set:Nn #3
+ {
+ \fp_to_dim:n
+ {
+ \l_@@_sin_fp * \dim_to_fp:n {#1}
+ + \l_@@_cos_fp * \dim_to_fp:n {#2}
+ }
+ }
+ }
+% \end{macrocode}
+% Rotation of the edges is done using a different formula for each
+% quadrant. In every case, the top and bottom edges only need the
+% resulting $y$-values, whereas the left and right edges need the
+% $x$-values. Each case is a question of picking out which corner
+% ends up at with the maximum top, bottom, left and right value. Doing
+% this by hand means a lot less calculating and avoids lots of
+% comparisons.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_rotate_quadrant_one:
+ {
+ \@@_rotate_ydir:nnN \l_@@_right_dim \l_@@_top_dim
+ \l_@@_top_new_dim
+ \@@_rotate_ydir:nnN \l_@@_left_dim \l_@@_bottom_dim
+ \l_@@_bottom_new_dim
+ \@@_rotate_xdir:nnN \l_@@_left_dim \l_@@_top_dim
+ \l_@@_left_new_dim
+ \@@_rotate_xdir:nnN \l_@@_right_dim \l_@@_bottom_dim
+ \l_@@_right_new_dim
+ }
+\cs_new_protected:Npn \@@_rotate_quadrant_two:
+ {
+ \@@_rotate_ydir:nnN \l_@@_right_dim \l_@@_bottom_dim
+ \l_@@_top_new_dim
+ \@@_rotate_ydir:nnN \l_@@_left_dim \l_@@_top_dim
+ \l_@@_bottom_new_dim
+ \@@_rotate_xdir:nnN \l_@@_right_dim \l_@@_top_dim
+ \l_@@_left_new_dim
+ \@@_rotate_xdir:nnN \l_@@_left_dim \l_@@_bottom_dim
+ \l_@@_right_new_dim
+ }
+\cs_new_protected:Npn \@@_rotate_quadrant_three:
+ {
+ \@@_rotate_ydir:nnN \l_@@_left_dim \l_@@_bottom_dim
+ \l_@@_top_new_dim
+ \@@_rotate_ydir:nnN \l_@@_right_dim \l_@@_top_dim
+ \l_@@_bottom_new_dim
+ \@@_rotate_xdir:nnN \l_@@_right_dim \l_@@_bottom_dim
+ \l_@@_left_new_dim
+ \@@_rotate_xdir:nnN \l_@@_left_dim \l_@@_top_dim
+ \l_@@_right_new_dim
+ }
+\cs_new_protected:Npn \@@_rotate_quadrant_four:
+ {
+ \@@_rotate_ydir:nnN \l_@@_left_dim \l_@@_top_dim
+ \l_@@_top_new_dim
+ \@@_rotate_ydir:nnN \l_@@_right_dim \l_@@_bottom_dim
+ \l_@@_bottom_new_dim
+ \@@_rotate_xdir:nnN \l_@@_left_dim \l_@@_bottom_dim
+ \l_@@_left_new_dim
+ \@@_rotate_xdir:nnN \l_@@_right_dim \l_@@_top_dim
+ \l_@@_right_new_dim
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_scale_x_fp, \l_@@_scale_y_fp}
+% Scaling is potentially-different in the two axes.
+% \begin{macrocode}
+\fp_new:N \l_@@_scale_x_fp
+\fp_new:N \l_@@_scale_y_fp
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \box_resize_to_wd_and_ht_plus_dp:Nnn,
+% \box_resize_to_wd_and_ht_plus_dp:cnn,
+% \box_gresize_to_wd_and_ht_plus_dp:Nnn,
+% \box_gresize_to_wd_and_ht_plus_dp:cnn
+% }
+% \begin{macro}{\@@_resize_to_wd_and_ht_plus_dp:NnnN}
+% \begin{macro}{\@@_resize_set_corners:N}
+% \begin{macro}{\@@_resize:N}
+% \begin{macro}{\@@_resize:NNN}
+% Resizing a box starts by working out the various dimensions of the
+% existing box.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_resize_to_wd_and_ht_plus_dp:Nnn #1#2#3
+ {
+ \@@_resize_to_wd_and_ht_plus_dp:NnnN #1 {#2} {#3}
+ \hbox_set:Nn
+ }
+\cs_generate_variant:Nn \box_resize_to_wd_and_ht_plus_dp:Nnn { c }
+\cs_new_protected:Npn \box_gresize_to_wd_and_ht_plus_dp:Nnn #1#2#3
+ {
+ \@@_resize_to_wd_and_ht_plus_dp:NnnN #1 {#2} {#3}
+ \hbox_gset:Nn
+ }
+\cs_generate_variant:Nn \box_gresize_to_wd_and_ht_plus_dp:Nnn { c }
+\cs_new_protected:Npn \@@_resize_to_wd_and_ht_plus_dp:NnnN #1#2#3#4
+ {
+ #4 #1
+ {
+ \@@_resize_set_corners:N #1
+% \end{macrocode}
+% The $x$-scaling and resulting box size is easy enough to work
+% out: the dimension is that given as |#2|, and the scale is simply the
+% new width divided by the old one.
+% \begin{macrocode}
+ \fp_set:Nn \l_@@_scale_x_fp
+ { \dim_to_fp:n {#2} / \dim_to_fp:n { \l_@@_right_dim } }
+% \end{macrocode}
+% The $y$-scaling needs both the height and the depth of the current box.
+% \begin{macrocode}
+ \fp_set:Nn \l_@@_scale_y_fp
+ {
+ \dim_to_fp:n {#3}
+ / \dim_to_fp:n { \l_@@_top_dim - \l_@@_bottom_dim }
+ }
+% \end{macrocode}
+% Hand off to the auxiliary which does the rest of the work.
+% \begin{macrocode}
+ \@@_resize:N #1
+ }
+ }
+\cs_new_protected:Npn \@@_resize_set_corners:N #1
+ {
+ \dim_set:Nn \l_@@_top_dim { \box_ht:N #1 }
+ \dim_set:Nn \l_@@_bottom_dim { -\box_dp:N #1 }
+ \dim_set:Nn \l_@@_right_dim { \box_wd:N #1 }
+ \dim_zero:N \l_@@_left_dim
+ }
+% \end{macrocode}
+% With at least one real scaling to do, the next phase is to find the new
+% edge co-ordinates. In the $x$~direction this is relatively easy: just
+% scale the right edge. In the $y$~direction, both dimensions have to be
+% scaled, and this again needs the absolute scale value.
+% Once that is all done, the common resize/rescale code can be employed.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_resize:N #1
+ {
+ \@@_resize:NNN \l_@@_right_new_dim
+ \l_@@_scale_x_fp \l_@@_right_dim
+ \@@_resize:NNN \l_@@_bottom_new_dim
+ \l_@@_scale_y_fp \l_@@_bottom_dim
+ \@@_resize:NNN \l_@@_top_new_dim
+ \l_@@_scale_y_fp \l_@@_top_dim
+ \@@_resize_common:N #1
+ }
+\cs_new_protected:Npn \@@_resize:NNN #1#2#3
+ {
+ \dim_set:Nn #1
+ { \fp_to_dim:n { \fp_abs:n { #2 } * \dim_to_fp:n { #3 } } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \box_resize_to_ht:Nn, \box_resize_to_ht:cn,
+% \box_gresize_to_ht:Nn, \box_gresize_to_ht:cn
+% }
+% \begin{macro}{\@@_resize_to_ht:NnN}
+% \begin{macro}
+% {
+% \box_resize_to_ht_plus_dp:Nn, \box_resize_to_ht_plus_dp:cn,
+% \box_gresize_to_ht_plus_dp:Nn, \box_gresize_to_ht_plus_dp:cn
+% }
+% \begin{macro}{\@@_resize_to_ht_plus_dp:NnN}
+% \begin{macro}
+% {
+% \box_resize_to_wd:Nn, \box_resize_to_wd:cn,
+% \box_gresize_to_wd:Nn, \box_gresize_to_wd:cn
+% }
+% \begin{macro}{\@@_resize_to_wd:NnN}
+% \begin{macro}
+% {
+% \box_resize_to_wd_and_ht:Nnn, \box_resize_to_wd_and_ht:cnn,
+% \box_gresize_to_wd_and_ht:Nnn, \box_gresize_to_wd_and_ht:cnn
+% }
+% \begin{macro}{\@@_resize_to_wd_ht:NnnN}
+% Scaling to a (total) height or to a width is a simplified version of the main
+% resizing operation, with the scale simply copied between the two parts. The
+% internal auxiliary is called using the scaling value twice, as the sign for
+% both parts is needed (as this allows the same internal code to be used as
+% for the general case).
+% \begin{macrocode}
+\cs_new_protected:Npn \box_resize_to_ht:Nn #1#2
+ { \@@_resize_to_ht:NnN #1 {#2} \hbox_set:Nn }
+\cs_generate_variant:Nn \box_resize_to_ht:Nn { c }
+\cs_new_protected:Npn \box_gresize_to_ht:Nn #1#2
+ { \@@_resize_to_ht:NnN #1 {#2} \hbox_gset:Nn }
+\cs_generate_variant:Nn \box_gresize_to_ht:Nn { c }
+\cs_new_protected:Npn \@@_resize_to_ht:NnN #1#2#3
+ {
+ #3 #1
+ {
+ \@@_resize_set_corners:N #1
+ \fp_set:Nn \l_@@_scale_y_fp
+ {
+ \dim_to_fp:n {#2}
+ / \dim_to_fp:n { \l_@@_top_dim }
+ }
+ \fp_set_eq:NN \l_@@_scale_x_fp \l_@@_scale_y_fp
+ \@@_resize:N #1
+ }
+ }
+\cs_new_protected:Npn \box_resize_to_ht_plus_dp:Nn #1#2
+ { \@@_resize_to_ht_plus_dp:NnN #1 {#2} \hbox_set:Nn }
+\cs_generate_variant:Nn \box_resize_to_ht_plus_dp:Nn { c }
+\cs_new_protected:Npn \box_gresize_to_ht_plus_dp:Nn #1#2
+ { \@@_resize_to_ht_plus_dp:NnN #1 {#2} \hbox_gset:Nn }
+\cs_generate_variant:Nn \box_gresize_to_ht_plus_dp:Nn { c }
+\cs_new_protected:Npn \@@_resize_to_ht_plus_dp:NnN #1#2#3
+ {
+ #3 #1
+ {
+ \@@_resize_set_corners:N #1
+ \fp_set:Nn \l_@@_scale_y_fp
+ {
+ \dim_to_fp:n {#2}
+ / \dim_to_fp:n { \l_@@_top_dim - \l_@@_bottom_dim }
+ }
+ \fp_set_eq:NN \l_@@_scale_x_fp \l_@@_scale_y_fp
+ \@@_resize:N #1
+ }
+ }
+\cs_new_protected:Npn \box_resize_to_wd:Nn #1#2
+ { \@@_resize_to_wd:NnN #1 {#2} \hbox_set:Nn }
+\cs_generate_variant:Nn \box_resize_to_wd:Nn { c }
+\cs_new_protected:Npn \box_gresize_to_wd:Nn #1#2
+ { \@@_resize_to_wd:NnN #1 {#2} \hbox_gset:Nn }
+\cs_generate_variant:Nn \box_gresize_to_wd:Nn { c }
+\cs_new_protected:Npn \@@_resize_to_wd:NnN #1#2#3
+ {
+ #3 #1
+ {
+ \@@_resize_set_corners:N #1
+ \fp_set:Nn \l_@@_scale_x_fp
+ { \dim_to_fp:n {#2} / \dim_to_fp:n { \l_@@_right_dim } }
+ \fp_set_eq:NN \l_@@_scale_y_fp \l_@@_scale_x_fp
+ \@@_resize:N #1
+ }
+ }
+\cs_new_protected:Npn \box_resize_to_wd_and_ht:Nnn #1#2#3
+ { \@@_resize_to_wd_and_ht:NnnN #1 {#2} {#3} \hbox_set:Nn }
+\cs_generate_variant:Nn \box_resize_to_wd_and_ht:Nnn { c }
+\cs_new_protected:Npn \box_gresize_to_wd_and_ht:Nnn #1#2#3
+ { \@@_resize_to_wd_and_ht:NnnN #1 {#2} {#3} \hbox_gset:Nn }
+\cs_generate_variant:Nn \box_gresize_to_wd_and_ht:Nnn { c }
+\cs_new_protected:Npn \@@_resize_to_wd_and_ht:NnnN #1#2#3#4
+ {
+ #4 #1
+ {
+ \@@_resize_set_corners:N #1
+ \fp_set:Nn \l_@@_scale_x_fp
+ { \dim_to_fp:n {#2} / \dim_to_fp:n { \l_@@_right_dim } }
+ \fp_set:Nn \l_@@_scale_y_fp
+ {
+ \dim_to_fp:n {#3}
+ / \dim_to_fp:n { \l_@@_top_dim }
+ }
+ \@@_resize:N #1
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \box_scale:Nnn, \box_scale:cnn,
+% \box_gscale:Nnn, \box_gscale:cnn
+% }
+% \begin{macro}{\@@_scale:NnnN}
+% \begin{macro}{\@@_scale:N}
+% When scaling a box, setting the scaling itself is easy enough. The
+% new dimensions are also relatively easy to find, allowing only for
+% the need to keep them positive in all cases. Once that is done then
+% after a check for the trivial scaling a hand-off can be made to the
+% common code. The code here is split into two as this allows sharing
+% with the auto-resizing functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_scale:Nnn #1#2#3
+ { \@@_scale:NnnN #1 {#2} {#3} \hbox_set:Nn }
+\cs_generate_variant:Nn \box_scale:Nnn { c }
+\cs_new_protected:Npn \box_gscale:Nnn #1#2#3
+ { \@@_scale:NnnN #1 {#2} {#3} \hbox_gset:Nn }
+\cs_generate_variant:Nn \box_gscale:Nnn { c }
+\cs_new_protected:Npn \@@_scale:NnnN #1#2#3#4
+ {
+ #4 #1
+ {
+ \fp_set:Nn \l_@@_scale_x_fp {#2}
+ \fp_set:Nn \l_@@_scale_y_fp {#3}
+ \@@_scale:N #1
+ }
+ }
+\cs_new_protected:Npn \@@_scale:N #1
+ {
+ \dim_set:Nn \l_@@_top_dim { \box_ht:N #1 }
+ \dim_set:Nn \l_@@_bottom_dim { -\box_dp:N #1 }
+ \dim_set:Nn \l_@@_right_dim { \box_wd:N #1 }
+ \dim_zero:N \l_@@_left_dim
+ \dim_set:Nn \l_@@_top_new_dim
+ { \fp_abs:n { \l_@@_scale_y_fp } \l_@@_top_dim }
+ \dim_set:Nn \l_@@_bottom_new_dim
+ { \fp_abs:n { \l_@@_scale_y_fp } \l_@@_bottom_dim }
+ \dim_set:Nn \l_@@_right_new_dim
+ { \fp_abs:n { \l_@@_scale_x_fp } \l_@@_right_dim }
+ \@@_resize_common:N #1
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \box_autosize_to_wd_and_ht:Nnn ,
+% \box_autosize_to_wd_and_ht:cnn ,
+% \box_gautosize_to_wd_and_ht:Nnn ,
+% \box_gautosize_to_wd_and_ht:cnn ,
+% \box_autosize_to_wd_and_ht_plus_dp:Nnn ,
+% \box_autosize_to_wd_and_ht_plus_dp:cnn ,
+% \box_gautosize_to_wd_and_ht_plus_dp:Nnn ,
+% \box_gautosize_to_wd_and_ht_plus_dp:cnn
+% }
+% \begin{macro}{\@@_autosize:NnnnN}
+% Although autosizing a box uses dimensions, it has more in common in
+% implementation with scaling. As such, most of the real work here is
+% done elsewhere.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_autosize_to_wd_and_ht:Nnn #1#2#3
+ { \@@_autosize:NnnnN #1 {#2} {#3} { \box_ht:N #1 } \hbox_set:Nn }
+\cs_generate_variant:Nn \box_autosize_to_wd_and_ht:Nnn { c }
+\cs_new_protected:Npn \box_gautosize_to_wd_and_ht:Nnn #1#2#3
+ { \@@_autosize:NnnnN #1 {#2} {#3} { \box_ht:N #1 } \hbox_gset:Nn }
+\cs_generate_variant:Nn \box_gautosize_to_wd_and_ht:Nnn { c }
+\cs_new_protected:Npn \box_autosize_to_wd_and_ht_plus_dp:Nnn #1#2#3
+ {
+ \@@_autosize:NnnnN #1 {#2} {#3} { \box_ht:N #1 + \box_dp:N #1 }
+ \hbox_set:Nn
+ }
+\cs_generate_variant:Nn \box_autosize_to_wd_and_ht_plus_dp:Nnn { c }
+\cs_new_protected:Npn \box_gautosize_to_wd_and_ht_plus_dp:Nnn #1#2#3
+ {
+ \@@_autosize:NnnnN #1 {#2} {#3} { \box_ht:N #1 + \box_dp:N #1 }
+ \hbox_gset:Nn
+ }
+\cs_generate_variant:Nn \box_gautosize_to_wd_and_ht_plus_dp:Nnn { c }
+\cs_new_protected:Npn \@@_autosize:NnnnN #1#2#3#4#5
+ {
+ #5 #1
+ {
+ \fp_set:Nn \l_@@_scale_x_fp { ( \dim_to_fp:n {#2} ) / \box_wd:N #1 }
+ \fp_set:Nn \l_@@_scale_y_fp
+ { ( \dim_to_fp:n {#3} ) / ( \dim_to_fp:n {#4} ) }
+ \fp_compare:nNnTF \l_@@_scale_x_fp > \l_@@_scale_y_fp
+ { \fp_set_eq:NN \l_@@_scale_x_fp \l_@@_scale_y_fp }
+ { \fp_set_eq:NN \l_@@_scale_y_fp \l_@@_scale_x_fp }
+ \@@_scale:N #1
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_resize_common:N}
+% The main resize function places its input into a box which start
+% off with zero width, and includes the handles for engine rescaling.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_resize_common:N #1
+ {
+ \hbox_set:Nn \l_@@_internal_box
+ {
+ \@@_backend_scale:Nnn
+ #1
+ \l_@@_scale_x_fp
+ \l_@@_scale_y_fp
+ }
+% \end{macrocode}
+% The new height and depth can be applied directly.
+% \begin{macrocode}
+ \fp_compare:nNnTF \l_@@_scale_y_fp > \c_zero_fp
+ {
+ \box_set_ht:Nn \l_@@_internal_box { \l_@@_top_new_dim }
+ \box_set_dp:Nn \l_@@_internal_box { -\l_@@_bottom_new_dim }
+ }
+ {
+ \box_set_dp:Nn \l_@@_internal_box { \l_@@_top_new_dim }
+ \box_set_ht:Nn \l_@@_internal_box { -\l_@@_bottom_new_dim }
+ }
+% \end{macrocode}
+% Things are not quite as obvious for the width, as the reference point
+% needs to remain unchanged. For positive scaling factors resizing the
+% box is all that is needed. However, for case of a negative scaling
+% the material must be shifted such that the reference point ends up in
+% the right place.
+% \begin{macrocode}
+ \fp_compare:nNnTF \l_@@_scale_x_fp < \c_zero_fp
+ {
+ \hbox_to_wd:nn { \l_@@_right_new_dim }
+ {
+ \__kernel_kern:n { \l_@@_right_new_dim }
+ \box_use_drop:N \l_@@_internal_box
+ \tex_hss:D
+ }
+ }
+ {
+ \box_set_wd:Nn \l_@@_internal_box { \l_@@_right_new_dim }
+ \hbox:n
+ {
+ \__kernel_kern:n { 0pt }
+ \box_use_drop:N \l_@@_internal_box
+ \tex_hss:D
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Viewing part of a box}
+%
+% \begin{macro}{\box_set_clipped:N, \box_set_clipped:c, \box_gset_clipped:N, \box_gset_clipped:c}
+% A wrapper around the driver-dependent code.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_set_clipped:N #1
+ { \hbox_set:Nn #1 { \@@_backend_clip:N #1 } }
+\cs_generate_variant:Nn \box_set_clipped:N { c }
+\cs_new_protected:Npn \box_gset_clipped:N #1
+ { \hbox_gset:Nn #1 { \@@_backend_clip:N #1 } }
+\cs_generate_variant:Nn \box_gset_clipped:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \box_set_trim:Nnnnn, \box_set_trim:cnnnn,
+% \box_gset_trim:Nnnnn, \box_gset_trim:cnnnn
+% }
+% \begin{macro}{\@@_set_trim:NnnnnN}
+% Trimming from the left- and right-hand edges of the box is easy: kern the
+% appropriate parts off each side.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_set_trim:Nnnnn #1#2#3#4#5
+ { \@@_set_trim:NnnnnN #1 {#2} {#3} {#4} {#5} \box_set_eq:NN }
+\cs_generate_variant:Nn \box_set_trim:Nnnnn { c }
+\cs_new_protected:Npn \box_gset_trim:Nnnnn #1#2#3#4#5
+ { \@@_set_trim:NnnnnN #1 {#2} {#3} {#4} {#5} \box_gset_eq:NN }
+\cs_generate_variant:Nn \box_gset_trim:Nnnnn { c }
+\cs_new_protected:Npn \@@_set_trim:NnnnnN #1#2#3#4#5#6
+ {
+ \hbox_set:Nn \l_@@_internal_box
+ {
+ \__kernel_kern:n { -#2 }
+ \box_use:N #1
+ \__kernel_kern:n { -#4 }
+ }
+% \end{macrocode}
+% For the height and depth, there is a need to watch the baseline is
+% respected. Material always has to stay on the correct side, so trimming
+% has to check that there is enough material to trim. First, the bottom
+% edge. If there is enough depth, simply set the depth, or if not move
+% down so the result is zero depth. \cs{box_move_down:nn} is used in both
+% cases so the resulting box always contains a \tn{lower} primitive.
+% The internal box is used here as it allows safe use of \cs{box_set_dp:Nn}.
+% \begin{macrocode}
+ \dim_compare:nNnTF { \box_dp:N #1 } > {#3}
+ {
+ \hbox_set:Nn \l_@@_internal_box
+ {
+ \box_move_down:nn \c_zero_dim
+ { \box_use_drop:N \l_@@_internal_box }
+ }
+ \box_set_dp:Nn \l_@@_internal_box { \box_dp:N #1 - (#3) }
+ }
+ {
+ \hbox_set:Nn \l_@@_internal_box
+ {
+ \box_move_down:nn { (#3) - \box_dp:N #1 }
+ { \box_use_drop:N \l_@@_internal_box }
+ }
+ \box_set_dp:Nn \l_@@_internal_box \c_zero_dim
+ }
+% \end{macrocode}
+% Same thing, this time from the top of the box.
+% \begin{macrocode}
+ \dim_compare:nNnTF { \box_ht:N \l_@@_internal_box } > {#5}
+ {
+ \hbox_set:Nn \l_@@_internal_box
+ {
+ \box_move_up:nn \c_zero_dim
+ { \box_use_drop:N \l_@@_internal_box }
+ }
+ \box_set_ht:Nn \l_@@_internal_box
+ { \box_ht:N \l_@@_internal_box - (#5) }
+ }
+ {
+ \hbox_set:Nn \l_@@_internal_box
+ {
+ \box_move_up:nn { (#5) - \box_ht:N \l_@@_internal_box }
+ { \box_use_drop:N \l_@@_internal_box }
+ }
+ \box_set_ht:Nn \l_@@_internal_box \c_zero_dim
+ }
+ #6 #1 \l_@@_internal_box
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \box_set_viewport:Nnnnn, \box_set_viewport:cnnnn,
+% \box_gset_viewport:Nnnnn, \box_gset_viewport:cnnnn
+% }
+% \begin{macro}{\@@_viewport:NnnnnN}
+% The same general logic as for the trim operation, but with absolute
+% dimensions. As a result, there are some things to watch out for in the
+% vertical direction.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_set_viewport:Nnnnn #1#2#3#4#5
+ { \@@_set_viewport:NnnnnN #1 {#2} {#3} {#4} {#5} \box_set_eq:NN }
+\cs_generate_variant:Nn \box_set_viewport:Nnnnn { c }
+\cs_new_protected:Npn \box_gset_viewport:Nnnnn #1#2#3#4#5
+ { \@@_set_viewport:NnnnnN #1 {#2} {#3} {#4} {#5} \box_gset_eq:NN }
+\cs_generate_variant:Nn \box_gset_viewport:Nnnnn { c }
+\cs_new_protected:Npn \@@_set_viewport:NnnnnN #1#2#3#4#5#6
+ {
+ \hbox_set:Nn \l_@@_internal_box
+ {
+ \__kernel_kern:n { -#2 }
+ \box_use:N #1
+ \__kernel_kern:n { #4 - \box_wd:N #1 }
+ }
+ \dim_compare:nNnTF {#3} < \c_zero_dim
+ {
+ \hbox_set:Nn \l_@@_internal_box
+ {
+ \box_move_down:nn \c_zero_dim
+ { \box_use_drop:N \l_@@_internal_box }
+ }
+ \box_set_dp:Nn \l_@@_internal_box { - \@@_dim_eval:n {#3} }
+ }
+ {
+ \hbox_set:Nn \l_@@_internal_box
+ { \box_move_down:nn {#3} { \box_use_drop:N \l_@@_internal_box } }
+ \box_set_dp:Nn \l_@@_internal_box \c_zero_dim
+ }
+ \dim_compare:nNnTF {#5} > \c_zero_dim
+ {
+ \hbox_set:Nn \l_@@_internal_box
+ {
+ \box_move_up:nn \c_zero_dim
+ { \box_use_drop:N \l_@@_internal_box }
+ }
+ \box_set_ht:Nn \l_@@_internal_box
+ {
+ (#5)
+ \dim_compare:nNnT {#3} > \c_zero_dim
+ { - (#3) }
+ }
+ }
+ {
+ \hbox_set:Nn \l_@@_internal_box
+ {
+ \box_move_up:nn { - \@@_dim_eval:n {#5} }
+ { \box_use_drop:N \l_@@_internal_box }
+ }
+ \box_set_ht:Nn \l_@@_internal_box \c_zero_dim
+ }
+ #6 #1 \l_@@_internal_box
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3cctab.dtx b/macros/latex-dev/required/l3kernel/l3cctab.dtx
new file mode 100644
index 0000000000..dd35fb00a3
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3cctab.dtx
@@ -0,0 +1,975 @@
+% \iffalse meta-comment
+%
+%% File: l3cctab.dtx
+%
+% Copyright (C) 2018-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3cctab} module\\ Category code tables^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% A category code table enables rapid switching of all category codes in
+% one operation. For \LuaTeX{}, this is possible over the entire Unicode
+% range. For other engines, only the $8$-bit range ($0$--$255$) is covered by
+% such tables. The implementation of category code tables in \pkg{expl3}
+% also saves and restores the \TeX{} \tn{endlinechar} primitive value, meaning
+% they could be used for example to implement \cs{ExplSyntaxOn}.
+%
+% \section{Creating and initialising category code tables}
+%
+% \begin{function}[updated = 2020-07-02]{\cctab_new:N,\cctab_new:c}
+% \begin{syntax}
+% \cs{cctab_new:N} \meta{category code table}
+% \end{syntax}
+% Creates a new \meta{category code table} variable or raises an error if
+% the name is already taken. The declaration is global. The
+% \meta{category code table} is initialised with the codes
+% as used by \IniTeX{}.
+% \end{function}
+%
+% \begin{function}[updated = 2020-07-07]{\cctab_const:Nn,\cctab_const:cn}
+% \begin{syntax}
+% \cs{cctab_const:Nn} \meta{category code table} \Arg{category code set up}
+% \end{syntax}
+% Creates a new \meta{category code table}, applies (in a group) the
+% \meta{category code set up} on top of \IniTeX{} settings,
+% then saves them globally as a constant
+% table. The \meta{category code set up} can include a call to
+% \cs{cctab_select:N}.
+% \end{function}
+%
+% \begin{function}[updated = 2020-07-07]{\cctab_gset:Nn,\cctab_gset:cn}
+% \begin{syntax}
+% \cs{cctab_gset:Nn} \meta{category code table} \Arg{category code set up}
+% \end{syntax}
+% Starting from the \IniTeX{} category codes,
+% applies (in a group) the \meta{category code set up}, then saves them
+% globally in the \meta{category code table}. The \meta{category code set up}
+% can include a call to \cs{cctab_select:N}.
+% \end{function}
+%
+% \begin{function}[added = 2023-05-26]
+% {\cctab_gsave_current:N,\cctab_gsave_current:c}
+% \begin{syntax}
+% \cs{cctab_gsave_current:N} \meta{category code table}
+% \end{syntax}
+% Saves the current prevailing category codes in the
+% \meta{category code table}.
+% \end{function}
+%
+% \section{Using category code tables}
+%
+% \begin{function}[updated = 2020-07-02]{\cctab_begin:N,\cctab_begin:c}
+% \begin{syntax}
+% \cs{cctab_begin:N} \meta{category code table}
+% \end{syntax}
+% Switches locally the category codes in force to those stored in the
+% \meta{category code table}. The prevailing codes before the
+% function is called are added to a stack, for use with
+% \cs{cctab_end:}. This function does not start a \TeX{} group.
+% \end{function}
+%
+% \begin{function}[updated = 2020-07-02]{\cctab_end:}
+% \begin{syntax}
+% \cs{cctab_end:}
+% \end{syntax}
+% Ends the scope of a \meta{category code table} started using
+% \cs{cctab_begin:N}, returning the codes to those in force before the
+% matching \cs{cctab_begin:N} was used. This must be used within the
+% same \TeX{} group (and at the same \TeX{} group level) as the
+% matching \cs{cctab_begin:N}.
+% \end{function}
+%
+% \begin{function}[added = 2020-05-19, updated = 2020-07-02]{\cctab_select:N, \cctab_select:c}
+% \begin{syntax}
+% \cs{cctab_select:N} \meta{category code table}
+% \end{syntax}
+% Selects the \meta{category code table} for the scope of the current
+% group. This is in particular useful in the \meta{setup} arguments
+% of \cs{tl_set_rescan:Nnn}, \cs{tl_rescan:nn}, \cs{cctab_const:Nn},
+% and \cs{cctab_gset:Nn}.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2021-05-10]{\cctab_item:Nn, \cctab_item:cn}
+% \begin{syntax}
+% \cs{cctab_item:Nn} \meta{category code table} \Arg{int expr}
+% \end{syntax}
+% Determines the \meta{character} with character code given by the
+% \meta{int expr} and expands to its category code specified
+% by the \meta{category code table}.
+% \end{function}
+%
+% \section{Category code table conditionals}
+%
+% \begin{function}[pTF]{\cctab_if_exist:N, \cctab_if_exist:c}
+% \begin{syntax}
+% \cs{cctab_if_exist_p:N} \meta{category code table}
+% \cs{cctab_if_exist:NTF} \meta{category code table} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{category code table} is currently defined.
+% This does not check that the \meta{category code table} really is a
+% category code table.
+% \end{function}
+%
+% \section{Constant and scratch category code tables}
+%
+% \begin{variable}[updated = 2020-07-10]{\c_code_cctab}
+% Category code table for the \pkg{expl3} code environment; this does
+% \emph{not} include \texttt{@}, which is retained as an \enquote{other}
+% character. Sets the \tn{endlinechar} value to $32$ (a space).
+% \end{variable}
+%
+% \begin{variable}[updated = 2020-07-08]{\c_document_cctab}
+% Category code table for a standard \LaTeX{} document, as set by the \LaTeX{}
+% kernel. In particular, the upper-half of the $8$-bit range will be set to
+% \enquote{active} with \pdfTeX{} \emph{only}. No \pkg{babel} shorthands
+% will be activated. Sets the \tn{endlinechar} value to $13$ (normal
+% line ending).
+% \end{variable}
+%
+% \begin{variable}[updated = 2020-07-02]{\c_initex_cctab}
+% Category code table as set up by \IniTeX{}.
+% \end{variable}
+%
+% \begin{variable}[updated = 2020-07-02]{\c_other_cctab}
+% Category code table where all characters have category code $12$
+% (other). Sets the \tn{endlinechar} value to $-1$.
+% \end{variable}
+%
+% \begin{variable}[updated = 2020-07-02]{\c_str_cctab}
+% Category code table where all characters have category code $12$
+% (other) with the exception of spaces, which have category code
+% $10$ (space). Sets the \tn{endlinechar} value to $-1$.
+% \end{variable}
+%
+% \begin{variable}[added = 2023-05-26]{\g_tmpa_cctab, \g_tmpb_cctab}
+% Scratch category code tables.
+% \end{variable}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3cctab} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=cctab>
+% \end{macrocode}
+%
+% As \LuaTeX{} offers engine support for category code tables, and this
+% is entirely lacking from the other engines, we need two complementary
+% approaches. (Some future \XeTeX{} may add support, at which point the
+% conditionals below would be different.)
+%
+% \subsection{Variables}
+%
+% \begin{variable}{\g_@@_stack_seq, \g_@@_unused_seq}
+% List of catcode tables saved by nested \cs{cctab_begin:N}, to
+% restore catcodes at the matching \cs{cctab_end:}. When popped from
+% the \cs{g_@@_stack_seq} the table numbers are stored in
+% \cs{g_@@_unused_seq} for later reuse.
+% \begin{macrocode}
+\seq_new:N \g_@@_stack_seq
+\seq_new:N \g_@@_unused_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_group_seq}
+% A stack to store the group level when a catcode table started.
+% \begin{macrocode}
+\seq_new:N \g_@@_group_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_allocate_int}
+% Integer to keep track of what category code table to allocate. In
+% \LuaTeX{} it is only used in format mode to implement
+% \cs{cctab_new:N}. In other engines it is used to make csnames for
+% dynamic tables.
+% \begin{macrocode}
+\int_new:N \g_@@_allocate_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_internal_a_tl,\l_@@_internal_b_tl}
+% Scratch space. For instance, when popping
+% \cs{g_@@_stack_seq}/\cs{g_@@_unused_seq}, consists of the
+% catcodetable number (integer denotation) in \LuaTeX{}, or of an
+% intarray variable (as a single token) in other engines.
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_a_tl
+\tl_new:N \l_@@_internal_b_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_endlinechar_prop}
+% In \LuaTeX{} we store the \tn{endlinechar} associated to each
+% \tn{catcodetable} in a property list, unless it is the default
+% value~$13$.
+% \begin{macrocode}
+\prop_new:N \g_@@_endlinechar_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Allocating category code tables}
+%
+% \begin{macro}{\cctab_new:N, \cctab_new:c, \@@_new:N, \@@_gstore:Nnn}
+% The \cs{@@_new:N} auxiliary allocates a new catcode table but does
+% not attempt to set its value consistently across engines. It is
+% used both in \cs{cctab_new:N}, which sets catcodes to \IniTeX{}
+% values, and in \cs{cctab_begin:N}/\cs{cctab_end:} for dynamically
+% allocated tables.
+%
+% First, the \LuaTeX{} case.
+% Creating a new category code table is done like other registers.
+% In Con\TeX{}t, \tn{newcatcodetable} does not include the initialisation,
+% so that is added explicitly.
+% \begin{macrocode}
+\sys_if_engine_luatex:TF
+ {
+ \cs_new_protected:Npn \cctab_new:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \@@_new:N #1
+ }
+ \cs_new_protected:Npn \@@_new:N #1
+ {
+ \newcatcodetable #1
+ \tex_initcatcodetable:D #1
+ }
+ }
+% \end{macrocode}
+% Now the case for other engines. Here, each table is an integer
+% array. Following the \LuaTeX{} pattern, a new table starts with
+% \IniTeX{} codes. The \cs{debug_suspend:} and \cs{debug_resume:}
+% functions prevent errors and logging from \texttt{debug} commands
+% which are either duplicate or false when \cs{@@_new:N} is used
+% by \cs{cctab_new:N} or \cs{cctab_const:Nn}.
+% The index base is out-by-one, so we have an
+% internal function to handle that. The \IniTeX{} \tn{endlinechar} is
+% $13$.
+% \begin{macrocode}
+ {
+ \cs_new_protected:Npn \@@_new:N #1
+ {
+ \debug_suspend:
+ \intarray_new:Nn #1 { 257 }
+ \debug_resume:
+ }
+ \cs_new_protected:Npn \@@_gstore:Nnn #1#2#3
+ { \intarray_gset:Nnn #1 { #2 + 1 } {#3} }
+ \cs_new_protected:Npn \cctab_new:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \@@_new:N #1
+ \int_step_inline:nn { 256 }
+ { \__kernel_intarray_gset:Nnn #1 {##1} { 12 } }
+ \__kernel_intarray_gset:Nnn #1 { 257 } { 13 }
+ \@@_gstore:Nnn #1 { 0 } { 9 }
+ \@@_gstore:Nnn #1 { 13 } { 5 }
+ \@@_gstore:Nnn #1 { 32 } { 10 }
+ \@@_gstore:Nnn #1 { 37 } { 14 }
+ \int_step_inline:nnn { 65 } { 90 }
+ { \@@_gstore:Nnn #1 {##1} { 11 } }
+ \@@_gstore:Nnn #1 { 92 } { 0 }
+ \int_step_inline:nnn { 97 } { 122 }
+ { \@@_gstore:Nnn #1 {##1} { 11 } }
+ \@@_gstore:Nnn #1 { 127 } { 15 }
+ }
+ }
+\cs_generate_variant:Nn \cctab_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Saving category code tables}
+%
+% \begin{macro}{\@@_gset:n, \@@_gset_aux:n}
+% In various functions we need to save the current catcodes (globally)
+% in a table. In \LuaTeX{}, saving the catcodes is a primitives, but
+% the \tn{endlinechar} needs more work: to avoid filling
+% \cs{g_@@_endlinechar_prop} with many entries we special-case the
+% default value $13$. In other engines we store $256$ current
+% catcodes and the \tn{endlinechar} in an intarray variable.
+% \begin{macrocode}
+\sys_if_engine_luatex:TF
+ {
+ \cs_new_protected:Npn \@@_gset:n #1
+ { \exp_args:Nf \@@_gset_aux:n { \int_eval:n {#1} } }
+ \cs_new_protected:Npn \@@_gset_aux:n #1
+ {
+ \tex_savecatcodetable:D #1 \scan_stop:
+ \int_compare:nNnTF { \tex_endlinechar:D } = { 13 }
+ { \prop_gremove:Nn \g_@@_endlinechar_prop {#1} }
+ {
+ \prop_gput:NnV \g_@@_endlinechar_prop {#1}
+ \tex_endlinechar:D
+ }
+ }
+ }
+ {
+ \cs_new_protected:Npn \@@_gset:n #1
+ {
+ \int_step_inline:nn { 256 }
+ {
+ \__kernel_intarray_gset:Nnn #1 {##1}
+ { \char_value_catcode:n { ##1 - 1 } }
+ }
+ \__kernel_intarray_gset:Nnn #1 { 257 }
+ { \tex_endlinechar:D }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cctab_gset:Nn, \cctab_gset:cn}
+% Category code tables are always global, so only one version of
+% assignments is needed. Simply run the setup in a group and save the
+% result in a category code table~|#1|, provided it is valid. The
+% internal function is defined above depending on the engine.
+% \begin{macrocode}
+\cs_new_protected:Npn \cctab_gset:Nn #1#2
+ {
+ \@@_chk_if_valid:NT #1
+ {
+ \group_begin:
+ \cctab_select:N \c_initex_cctab
+ #2 \scan_stop:
+ \@@_gset:n {#1}
+ \group_end:
+ }
+ }
+\cs_generate_variant:Nn \cctab_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cctab_gsave_current:N, \cctab_gsave_current:c}
+% Very simple.
+% \begin{macrocode}
+\cs_new_protected:Npn \cctab_gsave_current:N #1
+ {
+ \@@_chk_if_valid:NT #1
+ { \@@_gset:n {#1} }
+ }
+\cs_generate_variant:Nn \cctab_gsave_current:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Using category code tables}
+%
+% \begin{variable}{\g_@@_internal_cctab}
+% \begin{macro}[EXP]{\@@_internal_cctab_name:}
+% In \LuaTeX{}, we must ensure that the saved tables are read-only.
+% This is done by applying the saved table, then switching immediately
+% to a scratch table. Any later catcode assignment will affect that
+% scratch table rather than the saved one. If we simply switched to
+% the saved tables, then \cs{char_set_catcode_other:N} in the example
+% below would change \cs{c_document_cctab} and a later use of that
+% table would give the wrong category code to |_|.
+% \begin{verbatim}
+% \use:n
+% {
+% \cctab_begin:N \c_document_cctab
+% \char_set_catcode_other:N \_
+% \cctab_end:
+% \cctab_begin:N \c_document_cctab
+% \int_compare:nTF { \char_value_catcode:n { `_ } = 8 }
+% { \TRUE } { \ERROR }
+% \cctab_end:
+% }
+% \end{verbatim}
+% We must also make sure that a scratch table is never reused in a
+% nested group: in the following example, the scratch table used by
+% the first \cs{cctab_begin:N} would be changed globally by the second
+% one issuing \tn{savecatcodetable}, and after \cs{group_end:} the
+% wrong category codes (those of \cs{c_str_cctab}) would be imposed.
+% Note that the inner \cs{cctab_end:} restores the correct catcodes
+% only locally, so the problem really comes up because of the
+% different grouping level. The simplest is to use a scratch table
+% labeled by the \tn{currentgrouplevel}. We initialize one of them as
+% an example.
+% \begin{verbatim}
+% \use:n
+% {
+% \cctab_begin:N \c_document_cctab
+% \group_begin:
+% \cctab_begin:N \c_str_cctab
+% \cctab_end:
+% \group_end:
+% \cctab_end:
+% }
+% \end{verbatim}
+% \begin{macrocode}
+\sys_if_engine_luatex:T
+ {
+ \@@_new:N \g_@@_internal_cctab
+ \cs_new:Npn \@@_internal_cctab_name:
+ {
+ g_@@_internal
+ \tex_romannumeral:D \tex_currentgrouplevel:D
+ _cctab
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{variable}
+%
+% \begin{macro}{\cctab_select:N, \cctab_select:c}
+% \begin{macro}{\@@_select:N}
+% The public function simply checks the \meta{cctab~var} exists before
+% using the engine-dependent \cs{@@_select:N}. Skipping these checks
+% would result in low-level engine-dependent errors. First, the
+% \LuaTeX{} case. In other engines, selecting a catcode table is a matter
+% of doing $256$ catcode assignments and setting the \tn{endlinechar}.
+% \begin{macrocode}
+\cs_new_protected:Npn \cctab_select:N #1
+ { \@@_chk_if_valid:NT #1 { \@@_select:N #1 } }
+\cs_generate_variant:Nn \cctab_select:N { c }
+\sys_if_engine_luatex:TF
+ {
+ \cs_new_protected:Npn \@@_select:N #1
+ {
+ \tex_catcodetable:D #1
+ \prop_get:NVNTF \g_@@_endlinechar_prop #1 \l_@@_internal_a_tl
+ { \int_set:Nn \tex_endlinechar:D { \l_@@_internal_a_tl } }
+ { \int_set:Nn \tex_endlinechar:D { 13 } }
+ \cs_if_exist:cF { \@@_internal_cctab_name: }
+ { \exp_args:Nc \@@_new:N { \@@_internal_cctab_name: } }
+ \exp_args:Nc \tex_savecatcodetable:D { \@@_internal_cctab_name: }
+ \exp_args:Nc \tex_catcodetable:D { \@@_internal_cctab_name: }
+ }
+ }
+ {
+ \cs_new_protected:Npn \@@_select:N #1
+ {
+ \int_step_inline:nn { 256 }
+ {
+ \char_set_catcode:nn { ##1 - 1 }
+ { \__kernel_intarray_item:Nn #1 {##1} }
+ }
+ \int_set:Nn \tex_endlinechar:D
+ { \__kernel_intarray_item:Nn #1 { 257 } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_next_cctab}
+% \begin{macro}{\@@_begin_aux:}
+% For \cs{cctab_begin:N}/\cs{cctab_end:} we will need to allocate
+% dynamic tables. This is done here by \cs{@@_begin_aux:}, which puts
+% a table number (in \LuaTeX{}) or name (in other engines) into
+% \cs{l_@@_internal_a_tl}. In \LuaTeX{} this simply calls \cs{@@_new:N}
+% and uses the resulting catcodetable number; in other engines we need
+% to give a name to the intarray variable and use that. In \LuaTeX{},
+% to restore catcodes at \cs{cctab_end:} we cannot just set
+% \tn{catcodetable} to its value before \cs{cctab_begin:N}, because
+% that table may have been altered by other code in the mean time. So
+% we must make sure to save the catcodes in a table we control and
+% restore them at \cs{cctab_end:}.
+% \begin{macrocode}
+\sys_if_engine_luatex:TF
+ {
+ \cs_new_protected:Npn \@@_begin_aux:
+ {
+ \@@_new:N \g_@@_next_cctab
+ \tl_set:NV \l_@@_internal_a_tl \g_@@_next_cctab
+ \cs_undefine:N \g_@@_next_cctab
+ }
+ }
+ {
+ \cs_new_protected:Npn \@@_begin_aux:
+ {
+ \int_gincr:N \g_@@_allocate_int
+ \exp_args:Nc \@@_new:N
+ { g_@@_ \int_use:N \g_@@_allocate_int _cctab }
+ \exp_args:NNc \tl_set:Nn \l_@@_internal_a_tl
+ { g_@@_ \int_use:N \g_@@_allocate_int _cctab }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{variable}
+%
+% \begin{macro}{\cctab_begin:N, \cctab_begin:c}
+% Check the \meta{cctab~var} exists, to avoid low-level errors. Get
+% in \cs{l_@@_internal_a_tl} the number/name of a dynamic table, either
+% from \cs{g_@@_unused_seq} where we save tables that are not
+% currently in use, or from \cs{@@_begin_aux:} if none are available.
+% Then save the current catcodes into the table (pointed to by)
+% \cs{l_@@_internal_a_tl} and save that table number in a stack before
+% selecting the desired catcodes.
+% \begin{macrocode}
+\cs_new_protected:Npn \cctab_begin:N #1
+ {
+ \@@_chk_if_valid:NT #1
+ {
+ \seq_gpop:NNF \g_@@_unused_seq \l_@@_internal_a_tl
+ { \@@_begin_aux: }
+ \@@_chk_group_begin:e
+ { \@@_nesting_number:N \l_@@_internal_a_tl }
+ \seq_gpush:NV \g_@@_stack_seq \l_@@_internal_a_tl
+ \exp_args:NV \@@_gset:n \l_@@_internal_a_tl
+ \@@_select:N #1
+ }
+ }
+\cs_generate_variant:Nn \cctab_begin:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cctab_end:}
+% Make sure a \cs{cctab_begin:N} was used some time earlier, get in
+% \cs{l_@@_internal_a_tl} the catcode table number/name in which the
+% prevailing catcodes were stored, then restore these catcodes. The
+% dynamic table is now unused hence stored in \cs{g_@@_unused_seq} for
+% recycling by later \cs{cctab_begin:N}.
+% \begin{macrocode}
+\cs_new_protected:Npn \cctab_end:
+ {
+ \seq_gpop:NNTF \g_@@_stack_seq \l_@@_internal_a_tl
+ {
+ \seq_gpush:NV \g_@@_unused_seq \l_@@_internal_a_tl
+ \exp_args:Ne \@@_chk_group_end:n
+ { \@@_nesting_number:N \l_@@_internal_a_tl }
+ \@@_select:N \l_@@_internal_a_tl
+ }
+ { \msg_error:nn { cctab } { extra-end } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_chk_group_begin:n,\@@_chk_group_begin:e, \@@_chk_group_end:n}
+% Catcode tables are not allowed to be intermixed with groups, so here
+% we check that they are properly nested regarding \TeX{} groups.
+% \cs{@@_chk_group_begin:n} stores the current group level in a stack,
+% and locally defines a dummy control sequence
+% \cs[no-index]{@@_group_\meta{cctab-level}_chk:}.
+%
+% \cs{@@_chk_group_end:n} pops the stack, and compares the returned
+% value with \cs{tex_currentgrouplevel:D}. If they differ,
+% \cs{cctab_end:} is in a different grouping level than the matching
+% \cs{cctab_begin:N}. If they are the same, both happened at the same
+% level, however a group might have ended and another started between
+% \cs{cctab_begin:N} and \cs{cctab_end:}:
+% \begin{verbatim}
+% \group_begin:
+% \cctab_begin:N \c_document_cctab
+% \group_end:
+% \group_begin:
+% \cctab_end:
+% \group_end:
+% \end{verbatim}
+% In this case checking \cs{tex_currentgrouplevel:D} is not enough, so
+% we locally define \cs[no-index]{@@_group_\meta{cctab-level}_chk:},
+% and then check if it exist in \cs{cctab_end:}. If it doesn't,
+% we know there was a group end where it shouldn't.
+%
+% The \meta{cctab-level} in the sentinel macro above cannot be
+% replaced by the more convenient \cs{tex_currentgrouplevel:D} because
+% with the latter we might be tricked. Suppose:
+% \begin{verbatim}
+% \group_begin:
+% \cctab_begin:N \c_code_cctab % A
+% \group_end:
+% \group_begin:
+% \cctab_begin:N \c_code_cctab % B
+% \cctab_end: % C
+% \cctab_end: % D
+% \group_end:
+% \end{verbatim}
+% The line marked with |A| would start a |cctab| with a sentinel token
+% named \cs[no-index]{@@_group_1_chk:}, which would disappear at the
+% \cs{group_end:} that follows. But |B| would create the same
+% sentinel token, since both are at the same group level. Line |C|
+% would end the |cctab| from line |B| correctly, but so would line |D|
+% because line |B| created the same sentinel token. Using
+% \meta{cctab-level} works correctly because it signals that certain
+% |cctab| level was activated somewhere, but if it doesn't exist when
+% the \cs{cctab_end:} is reached, we had a problem.
+%
+% Unfortunately these tests only flag the wrong usage at the
+% \cs{cctab_end:}, which might be far from the \cs{cctab_begin:N}.
+% However it isn't possible to signal the wrong usage at the
+% \cs{group_end:} without using \cs{tex_aftergroup:D}, which is
+% unsafe in certain types of groups.
+%
+% The three cases checked here just raise an error, and no recovery is
+% attempted: usually interleaving groups and catcode tables will work
+% predictably.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_chk_group_begin:n #1
+ {
+ \seq_gpush:Ne \g_@@_group_seq
+ { \int_use:N \tex_currentgrouplevel:D }
+ \cs_set_eq:cN { @@_group_ #1 _chk: } \prg_do_nothing:
+ }
+\cs_generate_variant:Nn \@@_chk_group_begin:n { e }
+\cs_new_protected:Npn \@@_chk_group_end:n #1
+ {
+ \seq_gpop:NN \g_@@_group_seq \l_@@_internal_b_tl
+ \bool_lazy_and:nnF
+ {
+ \int_compare_p:nNn
+ { \tex_currentgrouplevel:D } = { \l_@@_internal_b_tl }
+ }
+ { \cs_if_exist_p:c { @@_group_ #1 _chk: } }
+ {
+ \msg_error:nne { cctab } { group-mismatch }
+ {
+ \int_sign:n
+ { \tex_currentgrouplevel:D - \l_@@_internal_b_tl }
+ }
+ }
+ \cs_undefine:c { @@_group_ #1 _chk: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_nesting_number:N,\@@_nesting_number:w}
+% This macro returns the numeric index of the current catcode table.
+% In \LuaTeX{} this is just the argument, which is a count reference
+% to a \tn{catcodetable} register. In other engines, the number is
+% extracted from the |cctab| variable.
+% \begin{macrocode}
+\sys_if_engine_luatex:TF
+ { \cs_new:Npn \@@_nesting_number:N #1 {#1} }
+ {
+ \cs_new:Npn \@@_nesting_number:N #1
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_nesting_number:w
+ \exp_after:wN \token_to_str:N #1
+ }
+ \use:e
+ {
+ \cs_new:Npn \exp_not:N \@@_nesting_number:w
+ #1 \tl_to_str:n { g_@@_ } #2 \tl_to_str:n { _cctab } {#2}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% Finally, install some code at the end of the \TeX{} run to check that
+% all \cs{cctab_begin:N} were ended by some \cs{cctab_end:}.
+% \begin{macrocode}
+\cs_if_exist:NT \hook_gput_code:nnn
+ {
+ \hook_gput_code:nnn { enddocument/end } { cctab }
+ {
+ \seq_if_empty:NF \g_@@_stack_seq
+ { \msg_error:nn { cctab } { missing-end } }
+ }
+ }
+% \end{macrocode}
+%
+%
+% \begin{macro}{\cctab_item:Nn, \cctab_item:cn}
+% Evaluate the integer argument only once. In most engines the
+% |cctab| variable only has $256$ entries so we only look up the
+% catcode for these entries, otherwise we use the current catcode. In
+% particular, for out-of-range values we use whatever fall-back
+% \cs{char_value_catcode:n}. In \LuaTeX{}, we use the
+% |tex.getcatcode| function.
+% \begin{macrocode}
+\cs_new:Npn \cctab_item:Nn #1#2
+ { \exp_args:Nf \@@_item:nN { \int_eval:n {#2} } #1 }
+\sys_if_engine_luatex:TF
+ {
+ \cs_new:Npn \@@_item:nN #1#2
+ { \lua_now:e { tex.print(-2, tex.getcatcode(\int_use:N #2, #1)) } }
+ }
+ {
+ \cs_new:Npn \@@_item:nN #1#2
+ {
+ \int_compare:nNnTF {#1} < { 256 }
+ { \intarray_item:Nn #2 { #1 + 1 } }
+ { \char_value_catcode:n {#1} }
+ }
+ }
+\cs_generate_variant:Nn \cctab_item:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Category code table conditionals}
+%
+% \begin{macro}[pTF]{\cctab_if_exist:N,\cctab_if_exist:c}
+% Checks whether a \meta{cctab~var} is defined.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \cctab_if_exist:N \cs_if_exist:N
+ { TF , T , F , p }
+\prg_new_eq_conditional:NNn \cctab_if_exist:c \cs_if_exist:c
+ { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\@@_chk_if_valid:N}
+% \begin{macro}{\@@_chk_if_valid_aux:NTF}
+% Checks whether the argument is defined and whether it is a valid
+% \meta{cctab~var}. In \LuaTeX{} the validity of the \meta{cctab~var}
+% is checked by the engine, which complains if the argument is not a
+% \cs{chardef}'ed constant. In other engines, check if the given
+% command is an intarray variable (the underlying definition is a copy
+% of the \texttt{cmr10} font).
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \@@_chk_if_valid:N #1
+ { TF , T , F }
+ {
+ \cctab_if_exist:NTF #1
+ {
+ \@@_chk_if_valid_aux:NTF #1
+ { \prg_return_true: }
+ {
+ \msg_error:nne { cctab } { invalid-cctab }
+ { \token_to_str:N #1 }
+ \prg_return_false:
+ }
+ }
+ {
+ \msg_error:nne { kernel } { command-not-defined }
+ { \token_to_str:N #1 }
+ \prg_return_false:
+ }
+ }
+\sys_if_engine_luatex:TF
+ {
+ \cs_new_protected:Npn \@@_chk_if_valid_aux:NTF #1
+ {
+ \int_compare:nNnTF {#1-1} < { \e@alloc@ccodetable@count }
+ }
+ \cs_if_exist:NT \c_syst_catcodes_n
+ {
+ \cs_gset_protected:Npn \@@_chk_if_valid_aux:NTF #1
+ {
+ \int_compare:nTF { #1 <= \c_syst_catcodes_n }
+ }
+ }
+ }
+ {
+ \cs_new_protected:Npn \@@_chk_if_valid_aux:NTF #1
+ {
+ \exp_args:Nf \str_if_in:nnTF
+ { \cs_meaning:N #1 }
+ { select~font~cmr10~at~ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Constant category code tables}
+%
+% \begin{macro}{\cctab_const:Nn,\cctab_const:cn}
+% Creates a new \meta{cctab~var} then sets it with the \IniTeX{} and
+% user-supplied codes. To avoid false \texttt{debug} errors, we write
+% out implementation of \cs{cctab_new:N} and \cs{cctab_gset:Nn}
+% instead of directly using them here. The initialization part in
+% \cs{cctab_new:N} in non-\LuaTeX{} is omitted as it's covered by
+% the \IniTeX{} settings.
+% \begin{macrocode}
+\cs_new_protected:Npn \cctab_const:Nn #1#2
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \@@_new:N #1
+ \group_begin:
+ \cctab_select:N \c_initex_cctab
+ #2 \scan_stop:
+ \@@_gset:n {#1}
+ \group_end:
+ }
+\cs_generate_variant:Nn \cctab_const:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}
+% {
+% \c_initex_cctab ,
+% \c_other_cctab ,
+% \c_str_cctab
+% }
+% Creating category code tables means thinking starting from \IniTeX{}.
+% For all-other and the standard \enquote{string} tables that's easy.
+% \begin{macrocode}
+\cctab_new:N \c_initex_cctab
+\cctab_const:Nn \c_other_cctab
+ {
+ \cctab_select:N \c_initex_cctab
+ \int_set:Nn \tex_endlinechar:D { -1 }
+ \int_step_inline:nnn { 0 } { 127 }
+ { \char_set_catcode_other:n {#1} }
+ }
+\cctab_const:Nn \c_str_cctab
+ {
+ \cctab_select:N \c_other_cctab
+ \char_set_catcode_space:n { 32 }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_code_cctab, \c_document_cctab}
+% To pick up document-level category codes, we need to delay set up to the
+% end of the format, where that's possible. Also, as there are a \emph{lot}
+% of category codes to set, we avoid using the official interface and store the
+% document codes using internal code. Depending on whether we are in the hook
+% or not, the catcodes may be code or document, so we explicitly set up both
+% correctly.
+% \begin{macrocode}
+\cs_if_exist:NTF \@expl@finalise@setup@@@@
+ { \tl_gput_right:Nn \@expl@finalise@setup@@@@ }
+ { \use:n }
+ {
+ \@@_new:N \c_code_cctab
+ \group_begin:
+ \int_set:Nn \tex_endlinechar:D { 32 }
+ \char_set_catcode_invalid:n { 0 }
+ \bool_lazy_or:nnTF
+ { \sys_if_engine_xetex_p: } { \sys_if_engine_luatex_p: }
+ { \int_step_function:nN { 31 } \char_set_catcode_invalid:n }
+ { \int_step_function:nN { 31 } \char_set_catcode_active:n }
+ \int_step_function:nnN { 33 } { 64 } \char_set_catcode_other:n
+ \int_step_function:nnN { 65 } { 90 } \char_set_catcode_letter:n
+ \int_step_function:nnN { 91 } { 96 } \char_set_catcode_other:n
+ \int_step_function:nnN { 97 } { 122 } \char_set_catcode_letter:n
+ \char_set_catcode_ignore:n { 9 } % tab
+ \char_set_catcode_other:n { 10 } % lf
+ \char_set_catcode_active:n { 12 } % ff
+ \char_set_catcode_end_line:n { 13 } % cr
+ \char_set_catcode_ignore:n { 32 } % space
+ \char_set_catcode_parameter:n { 35 } % hash
+ \char_set_catcode_math_toggle:n { 36 } % dollar
+ \char_set_catcode_comment:n { 37 } % percent
+ \char_set_catcode_alignment:n { 38 } % ampersand
+ \char_set_catcode_letter:n { 58 } % colon
+ \char_set_catcode_escape:n { 92 } % backslash
+ \char_set_catcode_math_superscript:n { 94 } % circumflex
+ \char_set_catcode_letter:n { 95 } % underscore
+ \char_set_catcode_group_begin:n { 123 } % left brace
+ \char_set_catcode_other:n { 124 } % pipe
+ \char_set_catcode_group_end:n { 125 } % right brace
+ \char_set_catcode_space:n { 126 } % tilde
+ \char_set_catcode_invalid:n { 127 } % ^^?
+ \bool_lazy_or:nnF
+ { \sys_if_engine_xetex_p: } { \sys_if_engine_luatex_p: }
+ { \int_step_function:nnN { 128 } { 255 } \char_set_catcode_active:n }
+ \@@_gset:n { \c_code_cctab }
+ \group_end:
+ \cctab_const:Nn \c_document_cctab
+ {
+ \cctab_select:N \c_code_cctab
+ \int_set:Nn \tex_endlinechar:D { 13 }
+ \char_set_catcode_space:n { 9 }
+ \char_set_catcode_space:n { 32 }
+ \char_set_catcode_other:n { 58 }
+ \char_set_catcode_math_subscript:n { 95 }
+ \char_set_catcode_active:n { 126 }
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_cctab, \g_tmpb_cctab}
+% \begin{macrocode}
+\cctab_new:N \g_tmpa_cctab
+\cctab_new:N \g_tmpb_cctab
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Messages}
+%
+% \begin{macrocode}
+\msg_new:nnnn { cctab } { stack-full }
+ { The~category~code~table~stack~is~exhausted. }
+ {
+ LaTeX~has~been~asked~to~switch~to~a~new~category~code~table,~
+ but~there~is~no~more~space~to~do~this!
+ }
+\msg_new:nnnn { cctab } { extra-end }
+ { Extra~\iow_char:N\\cctab_end:~ignored~\msg_line_context:. }
+ {
+ LaTeX~came~across~a~\iow_char:N\\cctab_end:~without~a~matching~
+ \iow_char:N\\cctab_begin:N.~This~command~will~be~ignored.
+ }
+\msg_new:nnnn { cctab } { missing-end }
+ { Missing~\iow_char:N\\cctab_end:~before~end~of~TeX~run. }
+ {
+ LaTeX~came~across~more~\iow_char:N\\cctab_begin:N~than~
+ \iow_char:N\\cctab_end:.
+ }
+\msg_new:nnnn { cctab } { invalid-cctab }
+ { Invalid~\iow_char:N\\catcode~table. }
+ {
+ You~can~only~switch~to~a~\iow_char:N\\catcode~table~that~is~
+ initialized~using~\iow_char:N\\cctab_new:N~or~
+ \iow_char:N\\cctab_const:Nn.
+ }
+\msg_new:nnnn { cctab } { group-mismatch }
+ {
+ \iow_char:N\\cctab_end:~occurred~in~a~
+ \int_case:nn {#1}
+ {
+ { 0 } { different~group }
+ { 1 } { higher~group~level }
+ { -1 } { lower~group~level }
+ } ~than~
+ the~matching~\iow_char:N\\cctab_begin:N.
+ }
+ {
+ Catcode~tables~and~groups~must~be~properly~nested,~but~
+ you~tried~to~interleave~them.~LaTeX~will~try~to~proceed,~
+ but~results~may~be~unexpected.
+ }
+\prop_gput:Nnn \g_msg_module_name_prop { cctab } { LaTeX }
+\prop_gput:Nnn \g_msg_module_type_prop { cctab } { }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+%\PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3clist.dtx b/macros/latex-dev/required/l3kernel/l3clist.dtx
new file mode 100644
index 0000000000..c67f70db2c
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3clist.dtx
@@ -0,0 +1,2248 @@
+% \iffalse meta-comment
+%
+%% File: l3clist.dtx
+%
+% Copyright (C) 2004-2011 Frank Mittelbach, The LaTeX Project
+% (C) 2012-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3clist} module\\ Comma separated lists^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% Comma lists (in short, |clist|) contain ordered data where items can
+% be added to the left or right end of the list. This data type allows
+% basic list
+% manipulations such as adding/removing items, applying a function to
+% every item, removing duplicate items, extracting a given item, using
+% the comma list with specified separators, and so on. Sequences
+% (defined in \pkg{l3seq}) are safer, faster, and provide more features,
+% so they should often be preferred to comma lists. Comma lists are
+% mostly useful when interfacing with \LaTeXe{} or other code that
+% expects or provides items separated by commas.
+%
+% Several items can be added at once. To ease input of comma lists from
+% data provided by a user outside an \cs{ExplSyntaxOn} \ldots{}
+% \cs{ExplSyntaxOff} block, spaces are removed from both sides of each
+% comma-delimited argument upon input. Blank arguments are ignored, to
+% allow for trailing commas or repeated commas (which may otherwise
+% arise when concatenating comma lists \enquote{by hand}). In addition,
+% a set of braces is removed if the result of space-trimming is braced:
+% this allows the storage of any item in a comma list. For instance,
+% \begin{verbatim}
+% \clist_new:N \l_my_clist
+% \clist_put_left:Nn \l_my_clist { ~a~ , ~{b}~ , c~\d }
+% \clist_put_right:Nn \l_my_clist { ~{e~} , , {{f}} , }
+% \end{verbatim}
+% results in |\l_my_clist| containing |a,b,c~\d,{e~},{{f}}| namely the
+% five items |a|, |b|, |c~\d|, |e~| and~|{f}|. Comma lists normally do
+% not contain empty or blank items so the following gives an empty comma list:
+% \begin{verbatim}
+% \clist_clear_new:N \l_my_clist
+% \clist_set:Nn \l_my_clist { , ~ , , }
+% \clist_if_empty:NTF \l_my_clist { true } { false }
+% \end{verbatim}
+% and it leaves \texttt{true} in the input stream. To include an
+% \enquote{unsafe} item (empty, or one that contains a comma, or starts
+% or ends with a space, or is a single brace group), surround it with
+% braces.
+%
+% Any |n|-type token list is a valid comma list input for \pkg{l3clist}
+% functions, which will split the token list at every comma and process
+% the items as described above. On the other hand, |N|-type functions
+% expect comma list variables, which are particular token list variables
+% in which this processing of items (and removal of blank items) has
+% already occurred. Because comma list variables are token list
+% variables, expanding them once yields their items separated by commas,
+% and \pkg{l3tl} functions such as \cs{tl_show:N} can be applied to
+% them. (These functions often have \pkg{l3clist} analogues, which
+% should be preferred.)
+%
+% Almost all operations on comma lists are
+% noticeably slower than those on sequences so converting the data to
+% sequences using \cs{seq_set_from_clist:Nn} (see \pkg{l3seq}) may be
+% advisable if speed is important. The exception is that
+% \cs{clist_if_in:NnTF} and \cs{clist_remove_duplicates:N} may be faster
+% than their sequence analogues for large lists. However, these
+% functions work slowly for \enquote{unsafe} items that must be braced,
+% and may produce errors when their argument contains |{|, |}| or |#|
+% (assuming the usual \TeX{} category codes apply). The sequence
+% data type should thus certainly be preferred to comma lists to store
+% such items.
+%
+% \section{Creating and initialising comma lists}
+%
+% \begin{function}{\clist_new:N, \clist_new:c}
+% \begin{syntax}
+% \cs{clist_new:N} \meta{clist~var}
+% \end{syntax}
+% Creates a new \meta{clist~var} or raises an error if the name is
+% already taken. The declaration is global. The \meta{clist~var}
+% initially contains no items.
+% \end{function}
+%
+% \begin{function}[added = 2014-07-05]
+% {
+% \clist_const:Nn, \clist_const:Ne,
+% \clist_const:cn, \clist_const:ce
+% }
+% \begin{syntax}
+% \cs{clist_const:Nn} \meta{clist~var} \Arg{comma list}
+% \end{syntax}
+% Creates a new constant \meta{clist~var} or raises an error
+% if the name is already taken. The value of the
+% \meta{clist~var} is set globally to the
+% \meta{comma list}.
+% \end{function}
+%
+% \begin{function}
+% {\clist_clear:N, \clist_clear:c, \clist_gclear:N, \clist_gclear:c}
+% \begin{syntax}
+% \cs{clist_clear:N} \meta{clist~var}
+% \end{syntax}
+% Clears all items from the \meta{clist~var}.
+% \end{function}
+%
+% \begin{function}
+% {
+% \clist_clear_new:N, \clist_clear_new:c,
+% \clist_gclear_new:N, \clist_gclear_new:c
+% }
+% \begin{syntax}
+% \cs{clist_clear_new:N} \meta{clist~var}
+% \end{syntax}
+% Ensures that the \meta{clist~var} exists globally by applying
+% \cs{clist_new:N} if necessary, then applies
+% \cs[index=clist_clear:N]{clist_(g)clear:N} to leave
+% the list empty.
+% \end{function}
+%
+% \begin{function}
+% {
+% \clist_set_eq:NN, \clist_set_eq:cN,
+% \clist_set_eq:Nc, \clist_set_eq:cc,
+% \clist_gset_eq:NN, \clist_gset_eq:cN,
+% \clist_gset_eq:Nc, \clist_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{clist_set_eq:NN} \meta{clist~var_1} \meta{clist~var_2}
+% \end{syntax}
+% Sets the content of \meta{clist~var_1} equal to that of
+% \meta{clist~var_2}. To set a token list variable equal to a comma
+% list variable, use \cs{tl_set_eq:NN}. Conversely, setting a comma
+% list variable to a token list is unadvisable unless one checks
+% space-trimming and related issues.
+% \end{function}
+%
+% \begin{function}[added = 2014-07-17]
+% {
+% \clist_set_from_seq:NN, \clist_set_from_seq:cN,
+% \clist_set_from_seq:Nc, \clist_set_from_seq:cc,
+% \clist_gset_from_seq:NN, \clist_gset_from_seq:cN,
+% \clist_gset_from_seq:Nc, \clist_gset_from_seq:cc
+% }
+% \begin{syntax}
+% \cs{clist_set_from_seq:NN} \meta{clist~var} \meta{seq~var}
+% \end{syntax}
+% Converts the data in the \meta{seq~var} into a \meta{clist~var}:
+% the original \meta{seq~var} is unchanged.
+% Items which contain either spaces or commas are surrounded by braces.
+% \end{function}
+%
+% \begin{function}
+% {
+% \clist_concat:NNN, \clist_concat:ccc,
+% \clist_gconcat:NNN, \clist_gconcat:ccc
+% }
+% \begin{syntax}
+% \cs{clist_concat:NNN} \meta{clist~var_1} \meta{clist~var_2} \meta{clist~var_3}
+% \end{syntax}
+% Concatenates the content of \meta{clist~var_2} and \meta{clist~var_3}
+% together and saves the result in \meta{clist~var_1}. The items in
+% \meta{clist~var_2} are placed at the left side of the new comma list.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added=2012-03-03]
+% {\clist_if_exist:N, \clist_if_exist:c}
+% \begin{syntax}
+% \cs{clist_if_exist_p:N} \meta{clist~var}
+% \cs{clist_if_exist:NTF} \meta{clist~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{clist~var} is currently defined. This does
+% not check that the \meta{clist~var} really is a comma list.
+% \end{function}
+%
+% \section{Adding data to comma lists}
+%
+% \begin{function}[added = 2011-09-06]
+% {
+% \clist_set:Nn, \clist_set:NV, \clist_set:Ne,
+% \clist_set:No,
+% \clist_set:cn, \clist_set:cV, \clist_set:ce,
+% \clist_set:co,
+% \clist_gset:Nn, \clist_gset:NV, \clist_gset:Ne,
+% \clist_gset:No,
+% \clist_gset:cn, \clist_gset:cV, \clist_gset:ce,
+% \clist_gset:co
+% }
+% \begin{syntax}
+% \cs{clist_set:Nn} \meta{clist~var} |{|\meta{item_1},\ldots{},\meta{item_n}|}|
+% \end{syntax}
+% Sets \meta{clist~var} to contain the \meta{items},
+% removing any previous content from the variable.
+% Blank items are omitted, spaces are removed from both sides of each
+% item, then a set of braces is removed if the resulting space-trimmed
+% item is braced.
+% To store some \meta{tokens} as a single \meta{item} even if the
+% \meta{tokens} contain commas or spaces, add a set of braces:
+% \cs{clist_set:Nn} \meta{clist~var} |{| \Arg{tokens} |}|.
+% \end{function}
+%
+% \begin{function}[updated = 2011-09-05]
+% {
+% \clist_put_left:Nn, \clist_put_left:NV,
+% \clist_put_left:Nv, \clist_put_left:Ne,
+% \clist_put_left:No,
+% \clist_put_left:cn, \clist_put_left:cV,
+% \clist_put_left:cv, \clist_put_left:ce,
+% \clist_put_left:co,
+% \clist_gput_left:Nn, \clist_gput_left:NV,
+% \clist_gput_left:Nv, \clist_gput_left:Ne,
+% \clist_gput_left:No,
+% \clist_gput_left:cn, \clist_gput_left:cV,
+% \clist_gput_left:cv, \clist_gput_left:ce,
+% \clist_gput_left:co
+% }
+% \begin{syntax}
+% \cs{clist_put_left:Nn} \meta{clist~var} |{|\meta{item_1},\ldots{},\meta{item_n}|}|
+% \end{syntax}
+% Appends the \meta{items} to the left of the \meta{clist~var}.
+% Blank items are omitted, spaces are removed from both sides of each
+% item, then a set of braces is removed if the resulting space-trimmed
+% item is braced.
+% To append some \meta{tokens} as a single \meta{item} even if the
+% \meta{tokens} contain commas or spaces, add a set of braces:
+% \cs{clist_put_left:Nn} \meta{clist~var} |{| \Arg{tokens} |}|.
+% \end{function}
+%
+% \begin{function}[updated = 2011-09-05]
+% {
+% \clist_put_right:Nn, \clist_put_right:NV,
+% \clist_put_right:Nv, \clist_put_right:Ne,
+% \clist_put_right:No,
+% \clist_put_right:cn, \clist_put_right:cV,
+% \clist_put_right:cv, \clist_put_right:ce,
+% \clist_put_right:co,
+% \clist_gput_right:Nn, \clist_gput_right:NV,
+% \clist_gput_right:Nv, \clist_gput_right:Ne,
+% \clist_gput_right:No,
+% \clist_gput_right:cn, \clist_gput_right:cV,
+% \clist_gput_right:cv, \clist_gput_right:ce,
+% \clist_gput_right:co
+% }
+% \begin{syntax}
+% \cs{clist_put_right:Nn} \meta{clist~var} |{|\meta{item_1},\ldots{},\meta{item_n}|}|
+% \end{syntax}
+% Appends the \meta{items} to the right of the \meta{clist~var}.
+% Blank items are omitted, spaces are removed from both sides of each
+% item, then a set of braces is removed if the resulting space-trimmed
+% item is braced.
+% To append some \meta{tokens} as a single \meta{item} even if the
+% \meta{tokens} contain commas or spaces, add a set of braces:
+% \cs{clist_put_right:Nn} \meta{clist~var} |{| \Arg{tokens} |}|.
+% \end{function}
+%
+% \section{Modifying comma lists}
+%
+% While comma lists are normally used as ordered lists, it may be
+% necessary to modify the content. The functions here may be used
+% to update comma lists, while retaining the order of the unaffected
+% entries.
+%
+% \begin{function}
+% {
+% \clist_remove_duplicates:N, \clist_remove_duplicates:c,
+% \clist_gremove_duplicates:N, \clist_gremove_duplicates:c
+% }
+% \begin{syntax}
+% \cs{clist_remove_duplicates:N} \meta{clist~var}
+% \end{syntax}
+% Removes duplicate items from the \meta{clist~var}, leaving the
+% left most copy of each item in the \meta{clist~var}. The \meta{item}
+% comparison takes place on a token basis, as for \cs{tl_if_eq:nnTF}.
+% \begin{texnote}
+% This function iterates through every item in the \meta{clist~var} and
+% does a comparison with the \meta{items} already checked. It is therefore
+% relatively slow with large comma lists.
+% Furthermore, it may fail if any of the items in the
+% \meta{clist~var} contains |{|, |}|, or |#|
+% (assuming the usual \TeX{} category codes apply).
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[updated = 2011-09-06]
+% {
+% \clist_remove_all:Nn, \clist_remove_all:cn,
+% \clist_remove_all:NV, \clist_remove_all:cV,
+% \clist_gremove_all:Nn, \clist_gremove_all:cn,
+% \clist_gremove_all:NV, \clist_gremove_all:cV
+% }
+% \begin{syntax}
+% \cs{clist_remove_all:Nn} \meta{clist~var} \Arg{item}
+% \end{syntax}
+% Removes every occurrence of \meta{item} from the \meta{clist~var}.
+% The \meta{item} comparison takes place on a token basis, as for
+% \cs{tl_if_eq:nnTF}.
+% \begin{texnote}
+% The function may fail if the \meta{item} contains |{|, |}|, or |#|
+% (assuming the usual \TeX{} category codes apply).
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2014-07-18]
+% {
+% \clist_reverse:N, \clist_reverse:c,
+% \clist_greverse:N, \clist_greverse:c
+% }
+% \begin{syntax}
+% \cs{clist_reverse:N} \meta{clist~var}
+% \end{syntax}
+% Reverses the order of items stored in the \meta{clist~var}.
+% \end{function}
+%
+% \begin{function}[added = 2014-07-18]{\clist_reverse:n}
+% \begin{syntax}
+% \cs{clist_reverse:n} \Arg{comma list}
+% \end{syntax}
+% Leaves the items in the \meta{comma list} in the input stream in
+% reverse order. Contrarily to other what is done for other
+% \texttt{n}-type \meta{comma list} arguments, braces and spaces are
+% preserved by this process.
+% \begin{texnote}
+% The result is returned within \tn{unexpanded}, which means that the
+% comma list does not expand further when appearing in an
+% \texttt{e}-type or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2017-02-06]
+% {\clist_sort:Nn, \clist_sort:cn, \clist_gsort:Nn, \clist_gsort:cn}
+% \begin{syntax}
+% \cs{clist_sort:Nn} \meta{clist var} \Arg{comparison code}
+% \end{syntax}
+% Sorts the items in the \meta{clist var} according to the
+% \meta{comparison code}, and assigns the result to
+% \meta{clist var}. The details of sorting comparison are
+% described in Section~\ref{sec:l3sort:mech}.
+% \end{function}
+%
+% \section{Comma list conditionals}
+%
+% \begin{function}[EXP,pTF]{\clist_if_empty:N, \clist_if_empty:c}
+% \begin{syntax}
+% \cs{clist_if_empty_p:N} \meta{clist~var}
+% \cs{clist_if_empty:NTF} \meta{clist~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{clist~var} is empty (containing no items).
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added = 2014-07-05]{\clist_if_empty:n}
+% \begin{syntax}
+% \cs{clist_if_empty_p:n} \Arg{comma list}
+% \cs{clist_if_empty:nTF} \Arg{comma list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{clist~var} is empty (containing no items).
+% The rules for space trimming are as for other \texttt{n}-type
+% comma-list functions, hence the comma list |{~,~,,~}| (without
+% outer braces) is empty, while |{~,{},}| (without outer braces)
+% contains one element, which happens to be empty: the comma-list
+% is not empty.
+% \end{function}
+%
+% \begin{function}[updated = 2011-09-06, TF]
+% {
+% \clist_if_in:Nn, \clist_if_in:NV, \clist_if_in:No,
+% \clist_if_in:cn, \clist_if_in:cV, \clist_if_in:co,
+% \clist_if_in:nn, \clist_if_in:nV, \clist_if_in:no
+% }
+% \begin{syntax}
+% \cs{clist_if_in:NnTF} \meta{clist~var} \Arg{item} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{item} is present in the \meta{clist~var}.
+% In the case of an \texttt{n}-type \meta{comma list}, the usual rules
+% of space trimming and brace stripping apply. Hence,
+% \begin{verbatim}
+% \clist_if_in:nnTF { a , {b}~ , {b} , c } { b } {true} {false}
+% \end{verbatim}
+% yields \texttt{true}.
+% \begin{texnote}
+% The function may fail if the \meta{item} contains |{|, |}|, or |#|
+% (assuming the usual \TeX{} category codes apply).
+% \end{texnote}
+% \end{function}
+%
+% \section{Mapping over comma lists}
+%
+% The functions described in this section apply a specified function
+% to each item of a comma list.
+% All mappings are done at the current group level, \emph{i.e.}~any
+% local assignments made by the \meta{function} or \meta{code} discussed
+% below remain in effect after the loop.
+%
+% When the comma list is given explicitly, as an \texttt{n}-type argument,
+% spaces are trimmed around each item.
+% If the result of trimming spaces is empty, the item is ignored.
+% Otherwise, if the item is surrounded by braces, one set is removed,
+% and the result is passed to the mapped function. Thus, if the
+% comma list that is being mapped is \verb*|{a , {{b} }, ,{}, {c},}|
+% then the arguments passed to the mapped function are
+% `\verb*|a|', `\verb*|{b} |', an empty argument, and `\verb*|c|'.
+%
+% When the comma list is given as an \texttt{N}-type argument, spaces
+% have already been trimmed on input, and items are simply stripped
+% of one set of braces if any. This case is more efficient than using
+% \texttt{n}-type comma lists.
+%
+% \begin{function}[rEXP, updated = 2012-06-29]
+% {\clist_map_function:NN, \clist_map_function:cN, \clist_map_function:nN, \clist_map_function:eN}
+% \begin{syntax}
+% \cs{clist_map_function:NN} \meta{clist~var} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every \meta{item} stored in the
+% \meta{clist~var}. The \meta{function} receives one argument for
+% each iteration. The \meta{items} are returned from left to right.
+% The function \cs{clist_map_inline:Nn} is in general more efficient
+% than \cs{clist_map_function:NN}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-06-29]
+% {\clist_map_inline:Nn, \clist_map_inline:cn, \clist_map_inline:nn}
+% \begin{syntax}
+% \cs{clist_map_inline:Nn} \meta{clist~var} \Arg{inline function}
+% \end{syntax}
+% Applies \meta{inline function} to every \meta{item} stored
+% within the \meta{clist~var}. The \meta{inline function} should
+% consist of code which receives the \meta{item} as |#1|.
+% The \meta{items} are returned from left to right.
+% \end{function}
+%
+% \begin{function}[updated = 2012-06-29]
+% {\clist_map_variable:NNn, \clist_map_variable:cNn, \clist_map_variable:nNn}
+% \begin{syntax}
+% \cs{clist_map_variable:NNn} \meta{clist~var} \meta{variable} \Arg{code}
+% \end{syntax}
+% Stores each \meta{item} of the \meta{clist~var} in turn in the
+% (token list) \meta{variable} and applies the \meta{code}. The
+% \meta{code} will usually make use of the \meta{variable}, but this
+% is not enforced. The assignments to the \meta{variable} are local.
+% Its value after the loop is the last \meta{item} in the \meta{clist~var},
+% or its original value if there were no \meta{item}. The
+% \meta{items} are returned from left to right.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2021-05-05]
+% {\clist_map_tokens:Nn, \clist_map_tokens:cn, \clist_map_tokens:nn}
+% \begin{syntax}
+% \cs{clist_map_tokens:Nn} \meta{clist~var} \Arg{code}
+% \cs{clist_map_tokens:nn} \Arg{comma list} \Arg{code}
+% \end{syntax}
+% Calls \meta{code} \Arg{item} for every \meta{item} stored in the
+% \meta{clist~var}. The \meta{code} receives each \meta{item} as a
+% trailing brace group. If the \meta{code} consists of a single
+% function this is equivalent to \cs{clist_map_function:nN}.
+% \end{function}
+%
+% \begin{function}[rEXP, updated = 2012-06-29]{\clist_map_break:}
+% \begin{syntax}
+% \cs{clist_map_break:}
+% \end{syntax}
+% Used to terminate a \cs[no-index]{clist_map_\ldots{}} function before all
+% entries in the \meta{comma list} have been processed. This
+% normally takes place within a conditional statement, for example
+% \begin{verbatim}
+% \clist_map_inline:Nn \l_my_clist
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \clist_map_break: }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs[no-index]{clist_map_\ldots{}} scenario leads to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted
+% before further items are taken
+% from the input stream. This depends on the design of the mapping
+% function.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[updated = 2012-06-29, rEXP]{\clist_map_break:n}
+% \begin{syntax}
+% \cs{clist_map_break:n} \Arg{code}
+% \end{syntax}
+% Used to terminate a \cs[no-index]{clist_map_\ldots{}} function before all
+% entries in the \meta{comma list} have been processed, inserting
+% the \meta{code} after the mapping has ended. This
+% normally takes place within a conditional statement, for example
+% \begin{verbatim}
+% \clist_map_inline:Nn \l_my_clist
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \clist_map_break:n { <code> } }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs[no-index]{clist_map_\ldots{}} scenario leads to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted
+% before the \meta{code} is
+% inserted into the input stream.
+% This depends on the design of the mapping function.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2012-07-13]
+% {\clist_count:N, \clist_count:c, \clist_count:n, \clist_count:e}
+% \begin{syntax}
+% \cs{clist_count:N} \meta{clist~var}
+% \end{syntax}
+% Leaves the number of items in the \meta{clist~var} in the input
+% stream as an \meta{integer denotation}. The total number of items
+% in a \meta{clist~var} includes those which are duplicates,
+% \emph{i.e.}~every item in a \meta{clist~var} is counted.
+% \end{function}
+%
+% \section{Using the content of comma lists directly}
+%
+% \begin{function}[EXP, added = 2013-05-26]{\clist_use:Nnnn, \clist_use:cnnn}
+% \begin{syntax}
+% \cs{clist_use:Nnnn} \meta{clist~var} \Arg{separator~between~two} \Arg{separator~between~more~than~two} \Arg{separator~between~final~two}
+% \end{syntax}
+% Places the contents of the \meta{clist~var} in the input stream,
+% with the appropriate \meta{separator} between the items. Namely, if
+% the comma list has more than two items, the \meta{separator between
+% more than two} is placed between each pair of items except the
+% last, for which the \meta{separator between final two} is used. If
+% the comma list has exactly two items, then they are placed in the input
+% stream separated by the \meta{separator between two}. If the comma
+% list has a single item, it is placed in the input stream, and a comma
+% list with no items produces no output. An error is raised if
+% the variable does not exist or if it is invalid.
+%
+% For example,
+% \begin{verbatim}
+% \clist_set:Nn \l_tmpa_clist { a , b , , c , {de} , f }
+% \clist_use:Nnnn \l_tmpa_clist { ~and~ } { ,~ } { ,~and~ }
+% \end{verbatim}
+% inserts \enquote{\texttt{a, b, c, de, and f}} in the input
+% stream. The first separator argument is not used in this case
+% because the comma list has more than $2$ items.
+% \begin{texnote}
+% The result is returned within the \tn{unexpanded}
+% primitive (\cs{exp_not:n}), which means that the \meta{items}
+% do not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2013-05-26]{\clist_use:Nn, \clist_use:cn}
+% \begin{syntax}
+% \cs{clist_use:Nn} \meta{clist~var} \Arg{separator}
+% \end{syntax}
+% Places the contents of the \meta{clist~var} in the input stream,
+% with the \meta{separator} between the items. If the comma
+% list has a single item, it is placed in the input stream, and a comma
+% list with no items produces no output. An error is raised if
+% the variable does not exist or if it is invalid.
+%
+% For example,
+% \begin{verbatim}
+% \clist_set:Nn \l_tmpa_clist { a , b , , c , {de} , f }
+% \clist_use:Nn \l_tmpa_clist { ~and~ }
+% \end{verbatim}
+% inserts \enquote{\texttt{a and b and c and de and f}} in the input
+% stream.
+% \begin{texnote}
+% The result is returned within the \tn{unexpanded}
+% primitive (\cs{exp_not:n}), which means that the \meta{items}
+% do not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2021-05-10]{\clist_use:nnnn, \clist_use:nn}
+% \begin{syntax}
+% \cs{clist_use:nnnn} \meta{comma~list} \Arg{separator~between~two} \Arg{separator~between~more~than~two} \Arg{separator~between~final~two}
+% \cs{clist_use:nn} \meta{comma~list} \Arg{separator}
+% \end{syntax}
+% Places the contents of the \meta{comma~list} in the input stream,
+% with the appropriate \meta{separator} between the items. As for
+% \cs{clist_set:Nn}, blank items are omitted, spaces are removed from
+% both sides of each item, then a set of braces is removed if the
+% resulting space-trimmed item is braced. The \meta{separators} are
+% then inserted in the same way as for \cs{clist_use:Nnnn} and
+% \cs{clist_use:Nn}, respectively.
+% \begin{texnote}
+% The result is returned within the \tn{unexpanded}
+% primitive (\cs{exp_not:n}), which means that the \meta{items}
+% do not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \section{Comma lists as stacks}
+%
+% Comma lists can be used as stacks, where data is pushed to and popped
+% from the top of the comma list. (The left of a comma list is the top, for
+% performance reasons.) The stack functions for comma lists are not
+% intended to be mixed with the general ordered data functions detailed
+% in the previous section: a comma list should either be used as an
+% ordered data type or as a stack, but not in both ways.
+%
+% \begin{function}[noTF, added = 2012-05-14, updated = 2019-02-16]
+% {\clist_get:NN, \clist_get:cN}
+% \begin{syntax}
+% \cs{clist_get:NN} \meta{clist~var} \meta{token list variable}
+% \end{syntax}
+% Stores the left-most item from a \meta{clist~var} in the
+% \meta{token list variable} without removing it from the
+% \meta{clist~var}. The \meta{token list variable} is assigned locally.
+% In the non-branching version, if the \meta{clist~var} is empty the
+% \meta{token list variable} is set to the marker value \cs{q_no_value}.
+% \end{function}
+%
+% \begin{function}[updated = 2011-09-06]{\clist_pop:NN, \clist_pop:cN}
+% \begin{syntax}
+% \cs{clist_pop:NN} \meta{clist~var} \meta{token list variable}
+% \end{syntax}
+% Pops the left-most item from a \meta{clist~var} into the
+% \meta{token list variable}, \emph{i.e.}~removes the item from the
+% comma list and stores it in the \meta{token list variable}.
+% Both of the variables are assigned locally.
+% \end{function}
+%
+% \begin{function}{\clist_gpop:NN, \clist_gpop:cN}
+% \begin{syntax}
+% \cs{clist_gpop:NN} \meta{clist~var} \meta{token list variable}
+% \end{syntax}
+% Pops the left-most item from a \meta{clist~var} into the
+% \meta{token list variable}, \emph{i.e.}~removes the item from the
+% comma list and stores it in the \meta{token list variable}.
+% The \meta{clist~var} is modified globally, while the assignment of
+% the \meta{token list variable} is local.
+% \end{function}
+%
+% \begin{function}[TF, added = 2012-05-14]{\clist_pop:NN, \clist_pop:cN}
+% \begin{syntax}
+% \cs{clist_pop:NNTF} \meta{clist~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{clist~var} is empty, leaves the \meta{false code} in the
+% input stream. The value of the \meta{token list variable} is
+% not defined in this case and should not be relied upon. If the
+% \meta{clist~var} is non-empty, pops the top item from the
+% \meta{clist~var} in the \meta{token list variable}, \emph{i.e.}~removes
+% the item from the \meta{clist~var}. Both the \meta{clist~var} and the
+% \meta{token list variable} are assigned locally.
+% \end{function}
+%
+% \begin{function}[TF, added = 2012-05-14]{\clist_gpop:NN, \clist_gpop:cN}
+% \begin{syntax}
+% \cs{clist_gpop:NNTF} \meta{clist~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{clist~var} is empty, leaves the \meta{false code} in the
+% input stream. The value of the \meta{token list variable} is
+% not defined in this case and should not be relied upon. If the
+% \meta{clist~var} is non-empty, pops the top item from the
+% \meta{clist~var} in the \meta{token list variable}, \emph{i.e.}~removes
+% the item from the \meta{clist~var}. The \meta{clist~var} is modified
+% globally, while the \meta{token list variable} is assigned locally.
+% \end{function}
+%
+% \begin{function}
+% {
+% \clist_push:Nn, \clist_push:NV, \clist_push:No,
+% \clist_push:cn, \clist_push:cV, \clist_push:co,
+% \clist_gpush:Nn, \clist_gpush:NV, \clist_gpush:No,
+% \clist_gpush:cn, \clist_gpush:cV, \clist_gpush:co,
+% }
+% \begin{syntax}
+% \cs{clist_push:Nn} \meta{clist~var} \Arg{items}
+% \end{syntax}
+% Adds the \Arg{items} to the top of the \meta{clist~var}.
+% Spaces are removed from both sides of each item as for any
+% \texttt{n}-type comma list.
+% \end{function}
+%
+% \section{Using a single item}
+%
+% \begin{function}[added = 2014-07-17, EXP]
+% {\clist_item:Nn, \clist_item:cn, \clist_item:nn, \clist_item:en}
+% \begin{syntax}
+% \cs{clist_item:Nn} \meta{clist~var} \Arg{int expr}
+% \end{syntax}
+% Indexing items in the \meta{clist~var} from~$1$ at the top (left), this
+% function evaluates the \meta{int expr} and leaves the
+% appropriate item from the comma list in the input stream. If the
+% \meta{int expr} is negative, indexing occurs from the
+% bottom (right) of the comma list. When the \meta{int expr}
+% is larger than the number of items in the \meta{clist~var} (as
+% calculated by \cs{clist_count:N}) then the function expands to
+% nothing.
+% \begin{texnote}
+% The result is returned within the \tn{unexpanded}
+% primitive (\cs{exp_not:n}), which means that the \meta{item}
+% does not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2016-12-06]
+% {\clist_rand_item:N, \clist_rand_item:n, \clist_rand_item:c}
+% \begin{syntax}
+% \cs{clist_rand_item:N} \meta{clist~var}
+% \cs{clist_rand_item:n} \Arg{comma list}
+% \end{syntax}
+% Selects a pseudo-random item of the \meta{clist~var}/\meta{comma list}.
+% If the \meta{comma list} has no item, the result is empty.
+% \begin{texnote}
+% The result is returned within the \tn{unexpanded}
+% primitive (\cs{exp_not:n}), which means that the \meta{item}
+% does not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \section{Viewing comma lists}
+%
+% \begin{function}[updated = 2021-04-29]{\clist_show:N, \clist_show:c}
+% \begin{syntax}
+% \cs{clist_show:N} \meta{clist~var}
+% \end{syntax}
+% Displays the entries in the \meta{clist~var} in the terminal.
+% \end{function}
+%
+% \begin{function}[updated = 2013-08-03]{\clist_show:n}
+% \begin{syntax}
+% \cs{clist_show:n} \Arg{tokens}
+% \end{syntax}
+% Displays the entries in the comma list in the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2021-04-29]{\clist_log:N, \clist_log:c}
+% \begin{syntax}
+% \cs{clist_log:N} \meta{clist~var}
+% \end{syntax}
+% Writes the entries in the \meta{clist~var} in the log file. See
+% also \cs{clist_show:N} which displays the result in the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22]{\clist_log:n}
+% \begin{syntax}
+% \cs{clist_log:n} \Arg{tokens}
+% \end{syntax}
+% Writes the entries in the comma list in the log file. See also
+% \cs{clist_show:n} which displays the result in the terminal.
+% \end{function}
+%
+% \section{Constant and scratch comma lists}
+%
+% \begin{variable}[added = 2012-07-02]{\c_empty_clist}
+% Constant that is always empty.
+% \end{variable}
+%
+% \begin{variable}[added = 2011-09-06]{\l_tmpa_clist, \l_tmpb_clist}
+% Scratch comma lists for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}[added = 2011-09-06]{\g_tmpa_clist, \g_tmpb_clist}
+% Scratch comma lists for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3clist} implementation}
+%
+% \TestFiles{m3clist002}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=clist>
+% \end{macrocode}
+%
+% \begin{variable}{\c_empty_clist}
+% An empty comma list is simply an empty token list.
+% \begin{macrocode}
+\cs_new_eq:NN \c_empty_clist \c_empty_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_internal_clist}
+% Scratch space for various internal uses. This comma list variable
+% cannot be declared as such because it comes before \cs{clist_new:N}
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_clist
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\s_@@_mark,\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{
+% \@@_use_none_delimit_by_s_mark:w,
+% \@@_use_none_delimit_by_s_stop:w,
+% \@@_use_i_delimit_by_s_stop:nw
+% }
+% Functions to gobble up to a scan mark.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_none_delimit_by_s_mark:w #1 \s_@@_mark { }
+\cs_new:Npn \@@_use_none_delimit_by_s_stop:w #1 \s_@@_stop { }
+\cs_new:Npn \@@_use_i_delimit_by_s_stop:nw #1 #2 \s_@@_stop {#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_tmp:w}
+% A temporary function for various purposes.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_tmp:w { }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Removing spaces around items}
+%
+% \begin{macro}{\@@_trim_next:w}
+% Called as \cs{exp:w} \cs{@@_trim_next:w} \cs{prg_do_nothing:}
+% \meta{comma list} \ldots{} it expands to \Arg{trimmed item} where
+% the \meta{trimmed item} is the first non-empty result from removing
+% spaces from both ends of comma-delimited items in the \meta{comma
+% list}. The \cs{prg_do_nothing:} marker avoids losing braces. The
+% test for blank items is a somewhat optimized \cs{tl_if_empty:oTF}
+% construction; if blank, another item is sought, otherwise trim
+% spaces.
+% \begin{macrocode}
+\cs_new:Npn \@@_trim_next:w #1 ,
+ {
+ \tl_if_empty:oTF { \use_none:nn #1 ? }
+ { \@@_trim_next:w \prg_do_nothing: }
+ { \tl_trim_spaces_apply:oN {#1} \exp_end: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_sanitize:n}
+% \begin{macro}{\@@_sanitize:Nn}
+% The auxiliary \cs{@@_sanitize:Nn} receives a delimiter
+% (\cs{c_empty_tl} the first time, afterwards a comma) and that item
+% as arguments. Unless we are done with the loop it calls
+% \cs{@@_wrap_item:w} to unbrace the item (using a comma delimiter is
+% safe since |#2| came from removing spaces from an argument delimited
+% by a comma) and possibly re-brace it if needed.
+% \begin{macrocode}
+\cs_new:Npn \@@_sanitize:n #1
+ {
+ \exp_after:wN \@@_sanitize:Nn \exp_after:wN \c_empty_tl
+ \exp:w \@@_trim_next:w \prg_do_nothing:
+ #1 , \s_@@_stop \prg_break: , \prg_break_point:
+ }
+\cs_new:Npn \@@_sanitize:Nn #1#2
+ {
+ \@@_use_none_delimit_by_s_stop:w #2 \s_@@_stop
+ #1 \@@_wrap_item:w #2 ,
+ \exp_after:wN \@@_sanitize:Nn \exp_after:wN ,
+ \exp:w \@@_trim_next:w \prg_do_nothing:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]{\@@_if_wrap:n}
+% \begin{macro}{\@@_if_wrap:w}
+% True if the argument must be wrapped to avoid getting altered by some
+% clist operations. That is the case whenever the argument
+% \begin{itemize}
+% \item starts or end with a space or contains a comma,
+% \item is empty, or
+% \item consists of a single braced group.
+% \end{itemize}
+% If the argument starts or ends with a space or contains
+% a comma then one of the three arguments of \cs{@@_if_wrap:w} will
+% have its end delimiter (partly) in one of the three copies of |#1|
+% in \cs{@@_if_wrap:nTF}; this has a knock-on effect meaning that the
+% result of the expansion is not empty; in that case, wrap.
+% Otherwise, the argument is safe unless it starts with a brace group
+% (or is empty) and it is empty or consists of a single
+% \texttt{n}-type argument.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_if_wrap:n #1 { TF }
+ {
+ \tl_if_empty:oTF
+ {
+ \@@_if_wrap:w
+ \s_@@_mark ? #1 ~ \s_@@_mark ? ~ #1
+ \s_@@_mark , ~ \s_@@_mark #1 ,
+ }
+ {
+ \tl_if_head_is_group:nTF { #1 { } }
+ {
+ \tl_if_empty:nTF {#1}
+ { \prg_return_true: }
+ {
+ \tl_if_empty:oTF { \use_none:n #1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ }
+ { \prg_return_false: }
+ }
+ { \prg_return_true: }
+ }
+\cs_new:Npn \@@_if_wrap:w #1 \s_@@_mark ? ~ #2 ~ \s_@@_mark #3 , { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_wrap_item:w}
+% Safe items are put in \cs{exp_not:n}, otherwise we put an extra set
+% of braces.
+% \begin{macrocode}
+\cs_new:Npn \@@_wrap_item:w #1 ,
+ { \@@_if_wrap:nTF {#1} { \exp_not:n { {#1} } } { \exp_not:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Allocation and initialisation}
+%
+% \begin{macro}{\clist_new:N, \clist_new:c}
+% \UnitTested
+% Internally, comma lists are just token lists.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_new:N \tl_new:N
+\cs_new_eq:NN \clist_new:c \tl_new:c
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \clist_const:Nn, \clist_const:Ne, \clist_const:Nx,
+% \clist_const:cn, \clist_const:ce, \clist_const:cx
+% }
+% Creating and initializing a constant comma list is done by
+% sanitizing all items (stripping spaces and braces).
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_const:Nn #1#2
+ { \tl_const:Ne #1 { \@@_sanitize:n {#2} } }
+\cs_generate_variant:Nn \clist_const:Nn { Ne , c , ce }
+\cs_generate_variant:Nn \clist_const:Nn { Nx , cx }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clist_clear:N, \clist_clear:c}
+% \UnitTested
+% \begin{macro}{\clist_gclear:N, \clist_gclear:c}
+% \UnitTested
+% Clearing comma lists is just the same as clearing token lists.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_clear:N \tl_clear:N
+\cs_new_eq:NN \clist_clear:c \tl_clear:c
+\cs_new_eq:NN \clist_gclear:N \tl_gclear:N
+\cs_new_eq:NN \clist_gclear:c \tl_gclear:c
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_clear_new:N, \clist_clear_new:c}
+% \UnitTested
+% \begin{macro}{\clist_gclear_new:N, \clist_gclear_new:c}
+% \UnitTested
+% Once again a copy from the token list functions.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_clear_new:N \tl_clear_new:N
+\cs_new_eq:NN \clist_clear_new:c \tl_clear_new:c
+\cs_new_eq:NN \clist_gclear_new:N \tl_gclear_new:N
+\cs_new_eq:NN \clist_gclear_new:c \tl_gclear_new:c
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\clist_set_eq:NN, \clist_set_eq:cN, \clist_set_eq:Nc, \clist_set_eq:cc}
+% \UnitTested
+% \begin{macro}
+% {
+% \clist_gset_eq:NN, \clist_gset_eq:cN,
+% \clist_gset_eq:Nc, \clist_gset_eq:cc
+% }
+% \UnitTested
+% Once again, these are simple copies from the token list functions.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_set_eq:NN \tl_set_eq:NN
+\cs_new_eq:NN \clist_set_eq:Nc \tl_set_eq:Nc
+\cs_new_eq:NN \clist_set_eq:cN \tl_set_eq:cN
+\cs_new_eq:NN \clist_set_eq:cc \tl_set_eq:cc
+\cs_new_eq:NN \clist_gset_eq:NN \tl_gset_eq:NN
+\cs_new_eq:NN \clist_gset_eq:Nc \tl_gset_eq:Nc
+\cs_new_eq:NN \clist_gset_eq:cN \tl_gset_eq:cN
+\cs_new_eq:NN \clist_gset_eq:cc \tl_gset_eq:cc
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \clist_set_from_seq:NN, \clist_set_from_seq:cN,
+% \clist_set_from_seq:Nc, \clist_set_from_seq:cc
+% }
+% \UnitTested
+% \begin{macro}
+% {
+% \clist_gset_from_seq:NN, \clist_gset_from_seq:cN,
+% \clist_gset_from_seq:Nc, \clist_gset_from_seq:cc
+% }
+% \UnitTested
+% \begin{macro}{\@@_set_from_seq:NNNN, \@@_set_from_seq:n}
+% Setting a comma list from a comma-separated list is done using a
+% simple mapping. Safe items are put in \cs{exp_not:n}, otherwise we
+% put an extra set of braces. The first comma must be removed, except
+% in the case of an empty comma-list.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_set_from_seq:NN
+ { \@@_set_from_seq:NNNN \clist_clear:N \__kernel_tl_set:Nx }
+\cs_new_protected:Npn \clist_gset_from_seq:NN
+ { \@@_set_from_seq:NNNN \clist_gclear:N \__kernel_tl_gset:Nx }
+\cs_new_protected:Npn \@@_set_from_seq:NNNN #1#2#3#4
+ {
+ \seq_if_empty:NTF #4
+ { #1 #3 }
+ {
+ #2 #3
+ {
+ \exp_after:wN \use_none:n \exp:w \exp_end_continue_f:w
+ \seq_map_function:NN #4 \@@_set_from_seq:n
+ }
+ }
+ }
+\cs_new:Npn \@@_set_from_seq:n #1
+ {
+ ,
+ \@@_if_wrap:nTF {#1}
+ { \exp_not:n { {#1} } }
+ { \exp_not:n {#1} }
+ }
+\cs_generate_variant:Nn \clist_set_from_seq:NN { Nc }
+\cs_generate_variant:Nn \clist_set_from_seq:NN { c , cc }
+\cs_generate_variant:Nn \clist_gset_from_seq:NN { Nc }
+\cs_generate_variant:Nn \clist_gset_from_seq:NN { c , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_concat:NNN, \clist_concat:ccc}
+% \UnitTested
+% \begin{macro}{\clist_gconcat:NNN, \clist_gconcat:ccc}
+% \UnitTested
+% \begin{macro}{\@@_concat:NNNN}
+% Concatenating comma lists is not quite as easy as it seems, as
+% there needs to be the correct addition of a comma to the output. So
+% a little work to do.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_concat:NNN
+ { \@@_concat:NNNN \__kernel_tl_set:Nx }
+\cs_new_protected:Npn \clist_gconcat:NNN
+ { \@@_concat:NNNN \__kernel_tl_gset:Nx }
+\cs_new_protected:Npn \@@_concat:NNNN #1#2#3#4
+ {
+ #1 #2
+ {
+ \exp_not:o #3
+ \clist_if_empty:NF #3 { \clist_if_empty:NF #4 { , } }
+ \exp_not:o #4
+ }
+ }
+\cs_generate_variant:Nn \clist_concat:NNN { ccc }
+\cs_generate_variant:Nn \clist_gconcat:NNN { ccc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\clist_if_exist:N, \clist_if_exist:c}
+% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \clist_if_exist:N \cs_if_exist:N
+ { TF , T , F , p }
+\prg_new_eq_conditional:NNn \clist_if_exist:c \cs_if_exist:c
+ { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Adding data to comma lists}
+%
+% \begin{macro}
+% {
+% \clist_set:Nn, \clist_set:NV, \clist_set:Ne,
+% \clist_set:No, \clist_set:Nx,
+% \clist_set:cn, \clist_set:cV, \clist_set:ce,
+% \clist_set:co, \clist_set:cx
+% }
+% \begin{macro}
+% {
+% \clist_gset:Nn, \clist_gset:NV, \clist_gset:Ne,
+% \clist_gset:No, \clist_gset:Nx,
+% \clist_gset:cn, \clist_gset:cV, \clist_gset:ce,
+% \clist_gset:co, \clist_gset:cx,
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_set:Nn #1#2
+ { \__kernel_tl_set:Nx #1 { \@@_sanitize:n {#2} } }
+\cs_new_protected:Npn \clist_gset:Nn #1#2
+ { \__kernel_tl_gset:Nx #1 { \@@_sanitize:n {#2} } }
+\cs_generate_variant:Nn \clist_set:Nn { NV , Ne , c , cV , ce }
+\cs_generate_variant:Nn \clist_set:Nn { No , Nx , co , cx }
+\cs_generate_variant:Nn \clist_gset:Nn { NV , Ne , c , cV , ce }
+\cs_generate_variant:Nn \clist_gset:Nn { No , Nx , co , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \clist_put_left:Nn, \clist_put_left:NV,
+% \clist_put_left:Nv, \clist_put_left:Ne,
+% \clist_put_left:No, \clist_put_left:Nx,
+% \clist_put_left:cn, \clist_put_left:cV,
+% \clist_put_left:cv, \clist_put_left:ce,
+% \clist_put_left:co, \clist_put_left:cx,
+% }
+% \UnitTested
+% \begin{macro}
+% {
+% \clist_gput_left:Nn, \clist_gput_left:NV,
+% \clist_gput_left:Nv, \clist_gput_left:Ne,
+% \clist_gput_left:No, \clist_gput_left:Nx,
+% \clist_gput_left:cn, \clist_gput_left:cV,
+% \clist_gput_left:cv, \clist_gput_left:ce,
+% \clist_gput_left:co, \clist_gput_left:cx,
+% }
+% \UnitTested
+% \begin{macro}{\@@_put_left:NNNn}
+% Everything is based on concatenation after storing in
+% \cs{l_@@_internal_clist}. This avoids having to worry here about
+% space-trimming and so on.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_put_left:Nn
+ { \@@_put_left:NNNn \clist_concat:NNN \clist_set:Nn }
+\cs_new_protected:Npn \clist_gput_left:Nn
+ { \@@_put_left:NNNn \clist_gconcat:NNN \clist_set:Nn }
+\cs_new_protected:Npn \@@_put_left:NNNn #1#2#3#4
+ {
+ #2 \l_@@_internal_clist {#4}
+ #1 #3 \l_@@_internal_clist #3
+ }
+\cs_generate_variant:Nn \clist_put_left:Nn { NV , Nv , Ne , c , cV , cv , ce }
+\cs_generate_variant:Nn \clist_put_left:Nn { No , Nx , co , cx }
+\cs_generate_variant:Nn \clist_gput_left:Nn { NV , Nv , Ne , c , cV , cv , ce }
+\cs_generate_variant:Nn \clist_gput_left:Nn { No , Nx , co , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \clist_put_right:Nn, \clist_put_right:NV,
+% \clist_put_right:Nv, \clist_put_right:Ne,
+% \clist_put_right:No, \clist_put_right:Nx,
+% \clist_put_right:cn, \clist_put_right:cV,
+% \clist_put_right:cv, \clist_put_right:ce,
+% \clist_put_right:co, \clist_put_right:cx
+% }
+% \UnitTested
+% \begin{macro}
+% {
+% \clist_gput_right:Nn, \clist_gput_right:NV,
+% \clist_gput_right:Nv, \clist_gput_right:Ne,
+% \clist_gput_right:No, \clist_gput_right:Nx,
+% \clist_gput_right:cn, \clist_gput_right:cV,
+% \clist_gput_right:cv, \clist_gput_right:ce,
+% \clist_gput_right:cx, \clist_gput_right:co
+% }
+% \UnitTested
+% \begin{macro}{\@@_put_right:NNNn}
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_put_right:Nn
+ { \@@_put_right:NNNn \clist_concat:NNN \clist_set:Nn }
+\cs_new_protected:Npn \clist_gput_right:Nn
+ { \@@_put_right:NNNn \clist_gconcat:NNN \clist_set:Nn }
+\cs_new_protected:Npn \@@_put_right:NNNn #1#2#3#4
+ {
+ #2 \l_@@_internal_clist {#4}
+ #1 #3 #3 \l_@@_internal_clist
+ }
+\cs_generate_variant:Nn \clist_put_right:Nn
+ { NV , Nv , Ne , c , cV , cv , ce }
+\cs_generate_variant:Nn \clist_put_right:Nn
+ { No , Nx , co , cx }
+\cs_generate_variant:Nn \clist_gput_right:Nn
+ { NV , Nv , Ne , c , cV , cv , ce }
+\cs_generate_variant:Nn \clist_gput_right:Nn
+ { No , Nx , co , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Comma lists as stacks}
+%
+% \begin{macro}{\clist_get:NN, \clist_get:cN}
+% \UnitTested
+% \begin{macro}{\@@_get:wN}
+% Getting an item from the left of a comma list is pretty easy: just
+% trim off the first item using the comma. No need to trim spaces as
+% comma-list \emph{variables} are assumed to have \enquote{cleaned-up}
+% items. (Note that grabbing a comma-delimited item removes an outer
+% pair of braces if present, exactly as needed to uncover the
+% underlying item.)
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_get:NN #1#2
+ {
+ \if_meaning:w #1 \c_empty_clist
+ \tl_set:Nn #2 { \q_no_value }
+ \else:
+ \exp_after:wN \@@_get:wN #1 , \s_@@_stop #2
+ \fi:
+ }
+\cs_new_protected:Npn \@@_get:wN #1 , #2 \s_@@_stop #3
+ { \tl_set:Nn #3 {#1} }
+\cs_generate_variant:Nn \clist_get:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_pop:NN, \clist_pop:cN}
+% \UnitTested
+% \begin{macro}{\clist_gpop:NN, \clist_gpop:cN}
+% \UnitTested
+% \begin{macro}
+% {\@@_pop:NNN, \@@_pop:wwNNN, \@@_pop:wN}
+% An empty clist leads to \cs{q_no_value}, otherwise grab until the
+% first comma and assign to the variable. The second argument of
+% \cs{@@_pop:wwNNN} is a comma list ending in a comma and
+% \cs{s_@@_mark}, unless the original clist contained exactly one item:
+% then the argument is just \cs{s_@@_mark}. The next auxiliary picks
+% either \cs{exp_not:n} or \cs{use_none:n} as |#2|, ensuring that the
+% result can safely be an empty comma list.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_pop:NN
+ { \@@_pop:NNN \__kernel_tl_set:Nx }
+\cs_new_protected:Npn \clist_gpop:NN
+ { \@@_pop:NNN \__kernel_tl_gset:Nx }
+\cs_new_protected:Npn \@@_pop:NNN #1#2#3
+ {
+ \if_meaning:w #2 \c_empty_clist
+ \tl_set:Nn #3 { \q_no_value }
+ \else:
+ \exp_after:wN \@@_pop:wwNNN #2 , \s_@@_mark \s_@@_stop #1#2#3
+ \fi:
+ }
+\cs_new_protected:Npn \@@_pop:wwNNN #1 , #2 \s_@@_stop #3#4#5
+ {
+ \tl_set:Nn #5 {#1}
+ #3 #4
+ {
+ \@@_pop:wN \prg_do_nothing:
+ #2 \exp_not:o
+ , \s_@@_mark \use_none:n
+ \s_@@_stop
+ }
+ }
+\cs_new:Npn \@@_pop:wN #1 , \s_@@_mark #2 #3 \s_@@_stop { #2 {#1} }
+\cs_generate_variant:Nn \clist_pop:NN { c }
+\cs_generate_variant:Nn \clist_gpop:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]{\clist_get:NN, \clist_get:cN}
+% \begin{macro}[TF]{\clist_pop:NN, \clist_pop:cN}
+% \begin{macro}[TF]{\clist_gpop:NN, \clist_gpop:cN}
+% \begin{macro}{\@@_pop_TF:NNN}
+% The same, as branching code: very similar to the above.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \clist_get:NN #1#2 { T , F , TF }
+ {
+ \if_meaning:w #1 \c_empty_clist
+ \prg_return_false:
+ \else:
+ \exp_after:wN \@@_get:wN #1 , \s_@@_stop #2
+ \prg_return_true:
+ \fi:
+ }
+\prg_generate_conditional_variant:Nnn \clist_get:NN { c } { T , F , TF }
+\prg_new_protected_conditional:Npnn \clist_pop:NN #1#2 { T , F , TF }
+ { \@@_pop_TF:NNN \__kernel_tl_set:Nx #1 #2 }
+\prg_new_protected_conditional:Npnn \clist_gpop:NN #1#2 { T , F , TF }
+ { \@@_pop_TF:NNN \__kernel_tl_gset:Nx #1 #2 }
+\cs_new_protected:Npn \@@_pop_TF:NNN #1#2#3
+ {
+ \if_meaning:w #2 \c_empty_clist
+ \prg_return_false:
+ \else:
+ \exp_after:wN \@@_pop:wwNNN #2 , \s_@@_mark \s_@@_stop #1#2#3
+ \prg_return_true:
+ \fi:
+ }
+\prg_generate_conditional_variant:Nnn \clist_pop:NN { c } { T , F , TF }
+\prg_generate_conditional_variant:Nnn \clist_gpop:NN { c } { T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{
+% \clist_push:Nn, \clist_push:NV, \clist_push:No, \clist_push:Nx,
+% \clist_push:cn, \clist_push:cV, \clist_push:co, \clist_push:cx,
+% }
+% \UnitTested
+% \begin{macro}{
+% \clist_gpush:Nn, \clist_gpush:NV, \clist_gpush:No, \clist_gpush:Nx,
+% \clist_gpush:cn, \clist_gpush:cV, \clist_gpush:co, \clist_gpush:cx,
+% }
+% \UnitTested
+% Pushing to a comma list is the same as adding on the left.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_push:Nn \clist_put_left:Nn
+\cs_generate_variant:Nn \clist_push:Nn { NV , No , Nx , c , cV , co , cx }
+\cs_new_eq:NN \clist_gpush:Nn \clist_gput_left:Nn
+\cs_generate_variant:Nn \clist_gpush:Nn { NV , No , Nx , c , cV , co , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Modifying comma lists}
+%
+% \begin{variable}{\l_@@_internal_remove_clist, \l_@@_internal_remove_seq}
+% An internal comma list and a sequence for the removal routines.
+% \begin{macrocode}
+\clist_new:N \l_@@_internal_remove_clist
+\seq_new:N \l_@@_internal_remove_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\clist_remove_duplicates:N, \clist_remove_duplicates:c}
+% \UnitTested
+% \begin{macro}{\clist_gremove_duplicates:N, \clist_gremove_duplicates:c}
+% \UnitTested
+% \begin{macro}{\@@_remove_duplicates:NN}
+% Removing duplicates means making a new list then copying it.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_remove_duplicates:N
+ { \@@_remove_duplicates:NN \clist_set_eq:NN }
+\cs_new_protected:Npn \clist_gremove_duplicates:N
+ { \@@_remove_duplicates:NN \clist_gset_eq:NN }
+\cs_new_protected:Npn \@@_remove_duplicates:NN #1#2
+ {
+ \clist_clear:N \l_@@_internal_remove_clist
+ \clist_map_inline:Nn #2
+ {
+ \clist_if_in:NnF \l_@@_internal_remove_clist {##1}
+ {
+ \tl_put_right:Ne \l_@@_internal_remove_clist
+ {
+ \clist_if_empty:NF \l_@@_internal_remove_clist { , }
+ \@@_if_wrap:nTF {##1} { \exp_not:n { {##1} } } { \exp_not:n {##1} }
+ }
+ }
+ }
+ #1 #2 \l_@@_internal_remove_clist
+ }
+\cs_generate_variant:Nn \clist_remove_duplicates:N { c }
+\cs_generate_variant:Nn \clist_gremove_duplicates:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \clist_remove_all:Nn, \clist_remove_all:cn,
+% \clist_remove_all:NV, \clist_remove_all:cV
+% }
+% \UnitTested
+% \begin{macro}
+% {
+% \clist_gremove_all:Nn, \clist_gremove_all:cn,
+% \clist_gremove_all:NV, \clist_gremove_all:cV
+% }
+% \UnitTested
+% \begin{macro}{\@@_remove_all:NNNn}
+% \begin{macro}{\@@_remove_all:w}
+% \begin{macro}{\@@_remove_all:}
+% The method used here for safe items is very similar to
+% \cs{tl_replace_all:Nnn}. However, if the item contains commas or
+% leading/trailing spaces, or is empty, or consists of a single brace
+% group, we know that it can only appear within braces so the code
+% would fail; instead just convert to a sequence and do the removal
+% with \pkg{l3seq} code (it involves somewhat elaborate code to do
+% most of the work expandably but the final token list comparisons
+% non-expandably).
+%
+% For \enquote{safe} items, build a function delimited by the
+% \meta{item} that should be removed,
+% surrounded with commas, and call that function followed by
+% the expanded comma list, and another copy of the \meta{item}.
+% The loop is controlled by the argument grabbed by
+% \cs{@@_remove_all:w}: when the item was found,
+% the \cs{s_@@_mark} delimiter used is the one inserted by
+% \cs{@@_tmp:w}, and \cs{@@_use_none_delimit_by_s_stop:w}
+% is deleted. At the end, the final \meta{item} is
+% grabbed, and the argument of \cs{@@_tmp:w} contains
+% \cs{s_@@_mark}: in that case, \cs{@@_remove_all:w}
+% removes the second \cs{s_@@_mark} (inserted by \cs{@@_tmp:w}),
+% and lets \cs{@@_use_none_delimit_by_s_stop:w} act.
+%
+% No brace is lost because items are always grabbed with a leading comma.
+% The result of the first assignment has an extra leading comma,
+% which we remove in a second assignment.
+% Two exceptions: if the clist lost all of its elements, the result
+% is empty, and we shouldn't remove anything; if the clist started up
+% empty, the first step happens to turn it into a single comma, and
+% the second step removes it.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_remove_all:Nn
+ { \@@_remove_all:NNNn \clist_set_from_seq:NN \__kernel_tl_set:Nx }
+\cs_new_protected:Npn \clist_gremove_all:Nn
+ { \@@_remove_all:NNNn \clist_gset_from_seq:NN \__kernel_tl_gset:Nx }
+\cs_new_protected:Npn \@@_remove_all:NNNn #1#2#3#4
+ {
+ \@@_if_wrap:nTF {#4}
+ {
+ \seq_set_from_clist:NN \l_@@_internal_remove_seq #3
+ \seq_remove_all:Nn \l_@@_internal_remove_seq {#4}
+ #1 #3 \l_@@_internal_remove_seq
+ }
+ {
+ \cs_set:Npn \@@_tmp:w ##1 , #4 ,
+ {
+ ##1
+ , \s_@@_mark , \@@_use_none_delimit_by_s_stop:w ,
+ \@@_remove_all:
+ }
+ #2 #3
+ {
+ \exp_after:wN \@@_remove_all:
+ #3 , \s_@@_mark , #4 , \s_@@_stop
+ }
+ \clist_if_empty:NF #3
+ {
+ #2 #3
+ {
+ \exp_args:No \exp_not:o
+ { \exp_after:wN \use_none:n #3 }
+ }
+ }
+ }
+ }
+\cs_new:Npn \@@_remove_all:
+ { \exp_after:wN \@@_remove_all:w \@@_tmp:w , }
+\cs_new:Npn \@@_remove_all:w #1 , \s_@@_mark , #2 , { \exp_not:n {#1} }
+\cs_generate_variant:Nn \clist_remove_all:Nn { c , NV , cV }
+\cs_generate_variant:Nn \clist_gremove_all:Nn { c , NV , cV }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \clist_reverse:N, \clist_reverse:c,
+% \clist_greverse:N, \clist_greverse:c
+% }
+% Use \cs{clist_reverse:n} in an \texttt{e}-expanding assignment. The
+% extra work that \cs{clist_reverse:n} does to preserve braces and
+% spaces would not be needed for the well-controlled case of
+% \texttt{N}-type comma lists, but the slow-down is not too bad.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_reverse:N #1
+ { \__kernel_tl_set:Nx #1 { \exp_args:No \clist_reverse:n {#1} } }
+\cs_new_protected:Npn \clist_greverse:N #1
+ { \__kernel_tl_gset:Nx #1 { \exp_args:No \clist_reverse:n {#1} } }
+\cs_generate_variant:Nn \clist_reverse:N { c }
+\cs_generate_variant:Nn \clist_greverse:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\clist_reverse:n}
+% \begin{macro}[EXP]{\@@_reverse:wwNww, \@@_reverse_end:ww}
+% The reversed token list is built one item at a time, and stored
+% between \cs{s_@@_stop} and \cs{s_@@_mark}, in the form of |?| followed by
+% zero or more instances of \enquote{\meta{item}\texttt{,}}. We start from a comma
+% list \enquote{\meta{item_1}\texttt{,\ldots,}\meta{item_n}}. During the loop,
+% the auxiliary \cs{@@_reverse:wwNww} receives \enquote{\texttt{?}\meta{item_i}} as
+% |#1|, \enquote{\meta{item_{i+1}}\texttt{,\ldots,}\meta{item_n}} as |#2|,
+% \cs{@@_reverse:wwNww} as |#3|, what remains until \cs{s_@@_stop} as
+% |#4|, and \enquote{\meta{item_{i-1}}\texttt{,\ldots,}\meta{item_1}\texttt{,}} as |#5|.
+% The auxiliary moves |#1| just before |#5|, with a comma, and calls
+% itself (|#3|). After the last item is moved, \cs{@@_reverse:wwNww}
+% receives \enquote{\cs{s_@@_mark} \cs{@@_reverse:wwNww} \texttt{!}} as its argument
+% |#1|, thus \cs{@@_reverse_end:ww} as its argument |#3|. This second
+% auxiliary cleans up until the marker~|!|, removes the trailing comma
+% (introduced when the first item was moved after \cs{s_@@_stop}), and
+% leaves its argument~|#1| within \cs{exp_not:n}. There is also a
+% need to remove a leading comma, hence \cs{exp_not:o} and
+% \cs{use_none:n}.
+% \begin{macrocode}
+\cs_new:Npn \clist_reverse:n #1
+ {
+ \@@_reverse:wwNww ? #1 ,
+ \s_@@_mark \@@_reverse:wwNww ! ,
+ \s_@@_mark \@@_reverse_end:ww
+ \s_@@_stop ? \s_@@_mark
+ }
+\cs_new:Npn \@@_reverse:wwNww
+ #1 , #2 \s_@@_mark #3 #4 \s_@@_stop ? #5 \s_@@_mark
+ { #3 ? #2 \s_@@_mark #3 #4 \s_@@_stop #1 , #5 \s_@@_mark }
+\cs_new:Npn \@@_reverse_end:ww #1 ! #2 , \s_@@_mark
+ { \exp_not:o { \use_none:n #2 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\clist_sort:Nn, \clist_sort:cn, \clist_gsort:Nn, \clist_gsort:cn}
+% Implemented in \pkg{l3sort}.
+% \end{macro}
+%
+% \subsection{Comma list conditionals}
+%
+% \begin{macro}[pTF]{\clist_if_empty:N, \clist_if_empty:c}
+% \UnitTested
+% Simple copies from the token list variable material.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \clist_if_empty:N \tl_if_empty:N
+ { p , T , F , TF }
+\prg_new_eq_conditional:NNn \clist_if_empty:c \tl_if_empty:c
+ { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, pTF]{\clist_if_empty:n}
+% \begin{macro}[EXP]{\@@_if_empty_n:w}
+% \begin{macro}[EXP]{\@@_if_empty_n:wNw}
+% As usual, we insert a token (here |?|) before grabbing
+% any argument: this avoids losing braces. The argument
+% of \cs{tl_if_empty:oTF} is empty if |#1| is |?| followed
+% by blank spaces (besides, this particular variant of
+% the emptiness test is optimized). If the item of the
+% comma list is blank, grab the next one. As soon as one
+% item is non-blank, exit: the second auxiliary grabs
+% \cs{prg_return_false:} as |#2|, unless every item in
+% the comma list was blank and the loop actually got broken
+% by the trailing \cs{s_@@_mark} \cs{prg_return_false:} item.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \clist_if_empty:n #1 { p , T , F , TF }
+ {
+ \@@_if_empty_n:w ? #1
+ , \s_@@_mark \prg_return_false:
+ , \s_@@_mark \prg_return_true:
+ \s_@@_stop
+ }
+\cs_new:Npn \@@_if_empty_n:w #1 ,
+ {
+ \tl_if_empty:oTF { \use_none:nn #1 ? }
+ { \@@_if_empty_n:w ? }
+ { \@@_if_empty_n:wNw }
+ }
+\cs_new:Npn \@@_if_empty_n:wNw #1 \s_@@_mark #2#3 \s_@@_stop {#2}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]
+% {
+% \clist_if_in:Nn, \clist_if_in:NV, \clist_if_in:No,
+% \clist_if_in:cn, \clist_if_in:cV, \clist_if_in:co,
+% \clist_if_in:nn, \clist_if_in:nV, \clist_if_in:no
+% }
+% \begin{macro}{\@@_if_in_return:nnN}
+% \UnitTested
+% For \enquote{safe} items, we simply surround the comma list, and the
+% item, with commas, then use the same code as for \cs{tl_if_in:Nn}.
+% For \enquote{unsafe} items we follow the same route as
+% \cs{seq_if_in:Nn}, mapping through the list a comparison function.
+% If found, return \texttt{true} and remove \cs{prg_return_false:}.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \clist_if_in:Nn #1#2 { T , F , TF }
+ {
+ \exp_args:No \@@_if_in_return:nnN #1 {#2} #1
+ }
+\prg_new_protected_conditional:Npnn \clist_if_in:nn #1#2 { T , F , TF }
+ {
+ \clist_set:Nn \l_@@_internal_clist {#1}
+ \exp_args:No \@@_if_in_return:nnN \l_@@_internal_clist {#2}
+ \l_@@_internal_clist
+ }
+\cs_new_protected:Npn \@@_if_in_return:nnN #1#2#3
+ {
+ \@@_if_wrap:nTF {#2}
+ {
+ \cs_set:Npe \@@_tmp:w ##1
+ {
+ \exp_not:N \tl_if_eq:nnT {##1}
+ \exp_not:n
+ {
+ {#2}
+ { \clist_map_break:n { \prg_return_true: \use_none:n } }
+ }
+ }
+ \clist_map_function:NN #3 \@@_tmp:w
+ \prg_return_false:
+ }
+ {
+ \cs_set:Npn \@@_tmp:w ##1 ,#2, { }
+ \tl_if_empty:oTF
+ { \@@_tmp:w ,#1, {} {} ,#2, }
+ { \prg_return_false: } { \prg_return_true: }
+ }
+ }
+\prg_generate_conditional_variant:Nnn \clist_if_in:Nn
+ { NV , No , c , cV , co } { T , F , TF }
+\prg_generate_conditional_variant:Nnn \clist_if_in:nn
+ { nV , no } { T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Mapping over comma lists}
+%
+% \begin{macro}{\clist_map_function:NN, \clist_map_function:cN}
+% \UnitTested
+% \begin{macro}{\@@_map_function:Nw, \@@_map_function_end:w}
+% If the variable is empty, the mapping is skipped (otherwise,
+% that comma-list would be seen as consisting of one empty item).
+% Then loop over the comma-list, grabbing eight comma-delimited items
+% at a time. The end is marked by \cs{s_@@_stop}, which may not appear
+% in any of the items. Once the last group of eight items has been
+% reached, we go through them more slowly using
+% \cs{@@_map_function_end:w}. The auxiliary function
+% \cs{@@_map_function:Nw} is also used in some other clist mappings.
+% \begin{macrocode}
+\cs_new:Npn \clist_map_function:NN #1#2
+ {
+ \clist_if_empty:NF #1
+ {
+ \exp_after:wN \@@_map_function:Nw \exp_after:wN #2 #1 ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
+ \prg_break_point:Nn \clist_map_break: { }
+ }
+ }
+\cs_new:Npn \@@_map_function:Nw #1 #2, #3, #4, #5, #6, #7, #8, #9,
+ {
+ \@@_use_none_delimit_by_s_stop:w
+ #9 \@@_map_function_end:w \s_@@_stop
+ #1 {#2} #1 {#3} #1 {#4} #1 {#5} #1 {#6} #1 {#7} #1 {#8} #1 {#9}
+ \@@_map_function:Nw #1
+ }
+\cs_new:Npn \@@_map_function_end:w \s_@@_stop #1#2
+ {
+ \@@_use_none_delimit_by_s_stop:w #2 \clist_map_break: \s_@@_stop
+ #1 {#2}
+ \@@_map_function_end:w \s_@@_stop
+ }
+\cs_generate_variant:Nn \clist_map_function:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_map_function:nN, \clist_map_function:eN}
+% \UnitTested
+% \begin{macro}{\@@_map_function_n:Nn}
+% \begin{macro}{\@@_map_unbrace:wn}
+% The \texttt{n}-type mapping function is a bit more awkward,
+% since spaces must be trimmed from each item.
+% Space trimming is again based on \cs{@@_trim_next:w}.
+% The auxiliary \cs{@@_map_function_n:Nn} receives as arguments the
+% function, and the next non-empty item (after space trimming but
+% before brace removal). One level of braces is removed by
+% \cs{@@_map_unbrace:wn}.
+% \begin{macrocode}
+\cs_new:Npn \clist_map_function:nN #1#2
+ {
+ \exp_after:wN \@@_map_function_n:Nn \exp_after:wN #2
+ \exp:w \@@_trim_next:w \prg_do_nothing: #1 ,
+ \s_@@_stop \clist_map_break: ,
+ \prg_break_point:Nn \clist_map_break: { }
+ }
+\cs_generate_variant:Nn \clist_map_function:nN { e }
+\cs_new:Npn \@@_map_function_n:Nn #1 #2
+ {
+ \@@_use_none_delimit_by_s_stop:w #2 \s_@@_stop
+ \@@_map_unbrace:wn #2 , #1
+ \exp_after:wN \@@_map_function_n:Nn \exp_after:wN #1
+ \exp:w \@@_trim_next:w \prg_do_nothing:
+ }
+\cs_new:Npn \@@_map_unbrace:wn #1, #2 { #2 {#1} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_map_inline:Nn, \clist_map_inline:cn}
+% \UnitTested
+% \begin{macro}{\clist_map_inline:nn}
+% \UnitTested
+% Inline mapping is done by creating a suitable function
+% \enquote{on the fly}: this is done globally to avoid
+% any issues with \TeX{}'s groups. We use a different
+% function for each level of nesting.
+%
+% Since the mapping is non-expandable, we can perform
+% the space-trimming needed by the \texttt{n} version
+% simply by storing the comma-list in a variable. We
+% don't need a different comma-list for each nesting
+% level: the comma-list is expanded before the mapping
+% starts.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_map_inline:Nn #1#2
+ {
+ \clist_if_empty:NF #1
+ {
+ \int_gincr:N \g__kernel_prg_map_int
+ \cs_gset_protected:cpn
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w } ##1 {#2}
+ \exp_last_unbraced:Nco \@@_map_function:Nw
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
+ #1 ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
+ \prg_break_point:Nn \clist_map_break:
+ { \int_gdecr:N \g__kernel_prg_map_int }
+ }
+ }
+\cs_new_protected:Npn \clist_map_inline:nn #1
+ {
+ \clist_set:Nn \l_@@_internal_clist {#1}
+ \clist_map_inline:Nn \l_@@_internal_clist
+ }
+\cs_generate_variant:Nn \clist_map_inline:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_map_variable:NNn, \clist_map_variable:cNn}
+% \UnitTested
+% \begin{macro}{\clist_map_variable:nNn}
+% \begin{macro}{\@@_map_variable:Nnn}
+% The |N|-type version is a straightforward application of
+% \cs{clist_map_tokens:Nn}, calling \cs{@@_map_variable:Nnn} for each
+% item to assign the variable and run the user's code. The |n|-type
+% version is \emph{not} implemented in terms of the |n|-type function
+% \cs{clist_map_tokens:Nn}, because here we are allowed to clean up
+% the |n|-type comma list non-expandably.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_map_variable:NNn #1#2#3
+ { \clist_map_tokens:Nn #1 { \@@_map_variable:Nnn #2 {#3} } }
+\cs_generate_variant:Nn \clist_map_variable:NNn { c }
+\cs_new_protected:Npn \@@_map_variable:Nnn #1#2#3
+ { \tl_set:Nn #1 {#3} #2 }
+\cs_new_protected:Npn \clist_map_variable:nNn #1
+ {
+ \clist_set:Nn \l_@@_internal_clist {#1}
+ \clist_map_variable:NNn \l_@@_internal_clist
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_map_tokens:Nn, \clist_map_tokens:cn}
+% \begin{macro}{\@@_map_tokens:nw, \@@_map_tokens_end:w}
+% Essentially a copy of \cs{clist_map_function:NN} with braces added.
+% \begin{macrocode}
+\cs_new:Npn \clist_map_tokens:Nn #1#2
+ {
+ \clist_if_empty:NF #1
+ {
+ \exp_last_unbraced:Nno \@@_map_tokens:nw {#2} #1 ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
+ \prg_break_point:Nn \clist_map_break: { }
+ }
+ }
+\cs_new:Npn \@@_map_tokens:nw #1 #2, #3, #4, #5, #6, #7, #8, #9,
+ {
+ \@@_use_none_delimit_by_s_stop:w
+ #9 \@@_map_tokens_end:w \s_@@_stop
+ \use:n {#1} {#2} \use:n {#1} {#3} \use:n {#1} {#4} \use:n {#1} {#5}
+ \use:n {#1} {#6} \use:n {#1} {#7} \use:n {#1} {#8} \use:n {#1} {#9}
+ \@@_map_tokens:nw {#1}
+ }
+\cs_new:Npn \@@_map_tokens_end:w \s_@@_stop \use:n #1#2
+ {
+ \@@_use_none_delimit_by_s_stop:w #2 \clist_map_break: \s_@@_stop
+ #1 {#2}
+ \@@_map_tokens_end:w \s_@@_stop
+ }
+\cs_generate_variant:Nn \clist_map_tokens:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_map_tokens:nn, \@@_map_tokens_n:nw}
+% Similar to \cs{clist_map_function:nN} but with a different way of
+% grabbing items because we cannot use \cs{exp_after:wN} to pass the
+% \meta{code}.
+% \begin{macrocode}
+\cs_new:Npn \clist_map_tokens:nn #1#2
+ {
+ \@@_map_tokens_n:nw {#2}
+ \prg_do_nothing: #1 , \s_@@_stop \clist_map_break: ,
+ \prg_break_point:Nn \clist_map_break: { }
+ }
+\cs_new:Npn \@@_map_tokens_n:nw #1#2 ,
+ {
+ \tl_if_empty:oF { \use_none:nn #2 ? }
+ {
+ \@@_use_none_delimit_by_s_stop:w #2 \s_@@_stop
+ \tl_trim_spaces_apply:oN {#2} \use_ii_i:nn
+ \@@_map_unbrace:wn , {#1}
+ }
+ \@@_map_tokens_n:nw {#1} \prg_do_nothing:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clist_map_break:, \clist_map_break:n}
+% The break statements use the general \cs{prg_map_break:Nn} mechanism.
+% \begin{macrocode}
+\cs_new:Npn \clist_map_break:
+ { \prg_map_break:Nn \clist_map_break: { } }
+\cs_new:Npn \clist_map_break:n
+ { \prg_map_break:Nn \clist_map_break: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clist_count:N, \clist_count:c, \clist_count:n, \clist_count:e}
+% \begin{macro}{\@@_count:n}
+% \begin{macro}{\@@_count:w}
+% Counting the items in a comma list is done using the same approach as for
+% other token count functions: turn each entry into a \texttt{+1} then use
+% integer evaluation to actually do the mathematics.
+% In the case of an \texttt{n}-type comma-list, we could of course use
+% \cs{clist_map_function:nN}, but that is very slow, because it carefully
+% removes spaces. Instead, we loop manually, and skip blank items
+% (but not |{}|, hence the extra spaces).
+% \begin{macrocode}
+\cs_new:Npn \clist_count:N #1
+ {
+ \int_eval:n
+ {
+ 0
+ \clist_map_function:NN #1 \@@_count:n
+ }
+ }
+\cs_generate_variant:Nn \clist_count:N { c }
+\cs_new:Npn \@@_count:n #1 { + 1 }
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \cs_new:Npn \clist_count:n ##1
+ {
+ \int_eval:n
+ {
+ 0
+ \@@_count:w #1
+ ##1 , \s_@@_stop \prg_break: , \prg_break_point:
+ }
+ }
+ \cs_new:Npn \@@_count:w ##1 ,
+ {
+ \@@_use_none_delimit_by_s_stop:w ##1 \s_@@_stop
+ \tl_if_blank:nF {##1} { + 1 }
+ \@@_count:w #1
+ }
+ }
+\exp_args:No \@@_tmp:w \c_space_tl
+\cs_generate_variant:Nn \clist_count:n { e }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using comma lists}
+%
+% \begin{macro}[EXP]{\clist_use:Nnnn, \clist_use:cnnn}
+% \begin{macro}[EXP]
+% {\@@_use:wwn, \@@_use:nwwwwnwn, \@@_use:nwwn}
+% \begin{macro}[EXP]{\clist_use:Nn, \clist_use:cn}
+% First check that the variable exists. Then count the items in the
+% comma list. If it has none, output nothing. If it has one item,
+% output that item, brace stripped (note that space-trimming has
+% already been done when the comma list was assigned). If it has two,
+% place the \meta{separator~between~two} in the middle.
+%
+% Otherwise, \cs{@@_use:nwwwwnwn} takes the following arguments; 1:
+% a \meta{separator}, 2, 3, 4: three items from the comma list (or
+% quarks), 5: the rest of the comma list, 6: a \meta{continuation}
+% function (\texttt{use_ii} or \texttt{use_iii} with its
+% \meta{separator} argument), 7: junk, and 8: the temporary result,
+% which is built in a brace group following \cs{s_@@_stop}. The
+% \meta{separator} and the first of the three items are placed in the
+% result, then we use the \meta{continuation}, placing the remaining
+% two items after it. When we begin this loop, the three items really
+% belong to the comma list, the first \cs{s_@@_mark} is taken as a
+% delimiter to the \texttt{use_ii} function, and the continuation is
+% \texttt{use_ii} itself. When we reach the last two items of the
+% original token list, \cs{s_@@_mark} is taken as a third item, and now
+% the second \cs{s_@@_mark} serves as a delimiter to \texttt{use_ii},
+% switching to the other \meta{continuation}, \texttt{use_iii}, which
+% uses the \meta{separator between final two}.
+% \begin{macrocode}
+\cs_new:Npn \clist_use:Nnnn #1#2#3#4
+ {
+ \clist_if_exist:NTF #1
+ {
+ \int_case:nnF { \clist_count:N #1 }
+ {
+ { 0 } { }
+ { 1 } { \exp_after:wN \@@_use:wwn #1 , , { } }
+ { 2 } { \exp_after:wN \@@_use:wwn #1 , {#2} }
+ }
+ {
+ \exp_after:wN \@@_use:nwwwwnwn
+ \exp_after:wN { \exp_after:wN } #1 ,
+ \s_@@_mark , { \@@_use:nwwwwnwn {#3} }
+ \s_@@_mark , { \@@_use:nwwn {#4} }
+ \s_@@_stop { }
+ }
+ }
+ {
+ \msg_expandable_error:nnn
+ { kernel } { bad-variable } {#1}
+ }
+ }
+\cs_generate_variant:Nn \clist_use:Nnnn { c }
+\cs_new:Npn \@@_use:wwn #1 , #2 , #3 { \exp_not:n { #1 #3 #2 } }
+\cs_new:Npn \@@_use:nwwwwnwn
+ #1#2 , #3 , #4 , #5 \s_@@_mark , #6#7 \s_@@_stop #8
+ { #6 {#3} , {#4} , #5 \s_@@_mark , {#6} #7 \s_@@_stop { #8 #1 #2 } }
+\cs_new:Npn \@@_use:nwwn #1#2 , #3 \s_@@_stop #4
+ { \exp_not:n { #4 #1 #2 } }
+\cs_new:Npn \clist_use:Nn #1#2
+ { \clist_use:Nnnn #1 {#2} {#2} {#2} }
+\cs_generate_variant:Nn \clist_use:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \clist_use:nnnn, \clist_use:nn, \@@_use:Nw,
+% \@@_use_one:w, \@@_use_end:w, \@@_use_more:w
+% }
+% Items are grabbed by \cs{@@_use:Nw}, which detects blank items with
+% a \cs{tl_if_empty:oTF} test (in which case it recurses). Non-blank
+% items are either the end of the list, in which case the argument
+% |#1| of \cs{@@_use:Nw} is used to properly end the list, or are
+% normal items, which must be trimmed and properly unbraced. As we
+% find successive items, the long list of \cs{@@_use:Nw} calls gets
+% shortened and we end up calling \cs{@@_use_more:w} once we have
+% found $3$ items. This auxiliary leaves the first-found item and the
+% general separator, and calls \cs{@@_use:Nw} to find more items.
+% A subtlety is that we use \cs{@@_use_end:w} both in the case of a
+% two-item list and for the last two items of a general list: to get
+% the correct separator, \cs{@@_use_more:w} replaces the
+% separator-of-two by the last-separator when called, namely as soon
+% as we have found three items.
+% \begin{macrocode}
+\cs_new:Npn \clist_use:nnnn #1#2#3#4
+ {
+ \@@_use:Nw \@@_use_none_delimit_by_s_stop:w
+ \@@_use:Nw \@@_use_one:w
+ \@@_use:Nw \@@_use_end:w
+ \@@_use_more:w ;
+ {#2} {#3} {#4} ;
+ \prg_do_nothing: #1 , \s_@@_mark ,
+ \s_@@_stop
+ }
+\cs_new:Npn \@@_use:Nw #1#2 ; #3 ; #4 ,
+ {
+ \tl_if_empty:oTF { \use_none:nn #4 ? }
+ { \@@_use:Nw #1#2 ; }
+ {
+ \@@_use_none_delimit_by_s_mark:w #4 #1 \s_@@_mark
+ \tl_trim_spaces_apply:oN {#4} \use_ii_i:nn
+ \@@_map_unbrace:wn , { #2 ; }
+ }
+ #3 ; \prg_do_nothing:
+ }
+\cs_new:Npn \@@_use_one:w \s_@@_mark #1 , #2#3#4 \s_@@_stop
+ { \exp_not:n {#3} }
+\cs_new:Npn \@@_use_end:w
+ \s_@@_mark #1 , #2#3#4#5#6 \s_@@_stop
+ { \exp_not:n { #4 #5 #3 } }
+\cs_new:Npn \@@_use_more:w ; #1#2#3#4#5#6 ;
+ {
+ \exp_not:n { #3 #5 }
+ \@@_use:Nw \@@_use_end:w \@@_use_more:w ;
+ {#1} {#2} {#6} {#5} {#6} ;
+ }
+\cs_new:Npn \clist_use:nn #1#2 { \clist_use:nnnn {#1} {#2} {#2} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Using a single item}
+%
+% \begin{macro}{\clist_item:Nn, \clist_item:cn}
+% \begin{macro}{\@@_item:nnnN, \@@_item:ffoN, \@@_item:ffnN}
+% \begin{macro}{\@@_item_N_loop:nw}
+% To avoid needing to test the end of the list at each step,
+% we first compute the \meta{length} of the list. If the item number
+% is~$0$, less than $-\meta{length}$, or more than $\meta{length}$,
+% the result is empty. If it is negative, but not less than $-\meta{length}$,
+% add $\meta{length}+1$ to the item number before performing the loop.
+% The loop itself is very simple, return the item if the counter
+% reached~$1$, otherwise, decrease the counter and repeat.
+% \begin{macrocode}
+\cs_new:Npn \clist_item:Nn #1#2
+ {
+ \@@_item:ffoN
+ { \clist_count:N #1 }
+ { \int_eval:n {#2} }
+ #1
+ \@@_item_N_loop:nw
+ }
+\cs_new:Npn \@@_item:nnnN #1#2#3#4
+ {
+ \int_compare:nNnTF {#2} < 0
+ {
+ \int_compare:nNnTF {#2} < { - #1 }
+ { \@@_use_none_delimit_by_s_stop:w }
+ { \exp_args:Nf #4 { \int_eval:n { #2 + 1 + #1 } } }
+ }
+ {
+ \int_compare:nNnTF {#2} > {#1}
+ { \@@_use_none_delimit_by_s_stop:w }
+ { #4 {#2} }
+ }
+ { } , #3 , \s_@@_stop
+ }
+\cs_generate_variant:Nn \@@_item:nnnN { ffo, ff }
+\cs_new:Npn \@@_item_N_loop:nw #1 #2,
+ {
+ \int_compare:nNnTF {#1} = 0
+ { \@@_use_i_delimit_by_s_stop:nw { \exp_not:n {#2} } }
+ { \exp_args:Nf \@@_item_N_loop:nw { \int_eval:n { #1 - 1 } } }
+ }
+\cs_generate_variant:Nn \clist_item:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_item:nn, \clist_item:en}
+% \begin{macro}{
+% \@@_item_n:nw,
+% \@@_item_n_loop:nw,
+% \@@_item_n_end:n,
+% \@@_item_n_strip:n,
+% \@@_item_n_strip:w}
+% This starts in the same way as \cs{clist_item:Nn} by counting the items
+% of the comma list. The final item should be space-trimmed before being
+% brace-stripped, hence we insert a couple of odd-looking
+% \cs{prg_do_nothing:} to avoid losing braces. Blank items are ignored.
+% \begin{macrocode}
+\cs_new:Npn \clist_item:nn #1#2
+ {
+ \@@_item:ffnN
+ { \clist_count:n {#1} }
+ { \int_eval:n {#2} }
+ {#1}
+ \@@_item_n:nw
+ }
+\cs_generate_variant:Nn \clist_item:nn { e }
+\cs_new:Npn \@@_item_n:nw #1
+ { \@@_item_n_loop:nw {#1} \prg_do_nothing: }
+\cs_new:Npn \@@_item_n_loop:nw #1 #2,
+ {
+ \exp_args:No \tl_if_blank:nTF {#2}
+ { \@@_item_n_loop:nw {#1} \prg_do_nothing: }
+ {
+ \int_compare:nNnTF {#1} = 0
+ { \exp_args:No \@@_item_n_end:n {#2} }
+ {
+ \exp_args:Nf \@@_item_n_loop:nw
+ { \int_eval:n { #1 - 1 } }
+ \prg_do_nothing:
+ }
+ }
+ }
+\cs_new:Npn \@@_item_n_end:n #1 #2 \s_@@_stop
+ { \tl_trim_spaces_apply:nN {#1} \@@_item_n_strip:n }
+\cs_new:Npn \@@_item_n_strip:n #1 { \@@_item_n_strip:w #1 , }
+\cs_new:Npn \@@_item_n_strip:w #1 , { \exp_not:n {#1} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_rand_item:n, \clist_rand_item:N, \clist_rand_item:c}
+% \begin{macro}{\@@_rand_item:nn}
+% The |N|-type function is not implemented through the |n|-type
+% function for efficiency: for instance comma-list variables do not
+% require space-trimming of their items. Even testing for emptyness
+% of an |n|-type comma-list is slow, so we count items first and use
+% that both for the emptyness test and the pseudo-random integer.
+% Importantly, \cs{clist_item:Nn} and \cs{clist_item:nn} only evaluate
+% their argument once.
+% \begin{macrocode}
+\cs_new:Npn \clist_rand_item:n #1
+ { \exp_args:Nf \@@_rand_item:nn { \clist_count:n {#1} } {#1} }
+\cs_new:Npn \@@_rand_item:nn #1#2
+ {
+ \int_compare:nNnF {#1} = 0
+ { \clist_item:nn {#2} { \int_rand:nn { 1 } {#1} } }
+ }
+\cs_new:Npn \clist_rand_item:N #1
+ {
+ \clist_if_empty:NF #1
+ { \clist_item:Nn #1 { \int_rand:nn { 1 } { \clist_count:N #1 } } }
+ }
+\cs_generate_variant:Nn \clist_rand_item:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Viewing comma lists}
+%
+% \begin{macro}{\clist_show:N, \clist_show:c, \clist_log:N, \clist_log:c, \@@_show:NN}
+% Apply the general \cs{__kernel_chk_tl_type:NnnT} with \cs{exp_not:o}
+% |#2| serving as a dummy code to prevent a check performed by this
+% auxiliary.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_show:N { \@@_show:NN \msg_show:nneeee }
+\cs_generate_variant:Nn \clist_show:N { c }
+\cs_new_protected:Npn \clist_log:N { \@@_show:NN \msg_log:nneeee }
+\cs_generate_variant:Nn \clist_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_chk_tl_type:NnnT #2 { clist } { \exp_not:o #2 }
+ {
+ \int_compare:nNnTF { \clist_count:N #2 }
+ = { \exp_args:No \clist_count:n #2 }
+ {
+ #1 { clist } { show }
+ { \token_to_str:N #2 }
+ { \clist_map_function:NN #2 \msg_show_item:n }
+ { } { }
+ }
+ {
+ \msg_error:nnee { clist } { non-clist }
+ { \token_to_str:N #2 } { \tl_to_str:N #2 }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clist_show:n, \clist_log:n, \@@_show:Nn}
+% A variant of the above: no existence check, empty first argument for
+% the message.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_show:n { \@@_show:Nn \msg_show:nneeee }
+\cs_new_protected:Npn \clist_log:n { \@@_show:Nn \msg_log:nneeee }
+\cs_new_protected:Npn \@@_show:Nn #1#2
+ {
+ #1 { clist } { show }
+ { } { \clist_map_function:nN {#2} \msg_show_item:n } { } { }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Scratch comma lists}
+%
+% \begin{variable}{\l_tmpa_clist, \l_tmpb_clist}
+% \begin{variable}{\g_tmpa_clist, \g_tmpb_clist}
+% Temporary comma list variables.
+% \begin{macrocode}
+\clist_new:N \l_tmpa_clist
+\clist_new:N \l_tmpb_clist
+\clist_new:N \g_tmpa_clist
+\clist_new:N \g_tmpb_clist
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3coffins.dtx b/macros/latex-dev/required/l3kernel/l3coffins.dtx
new file mode 100644
index 0000000000..164d10019d
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3coffins.dtx
@@ -0,0 +1,2590 @@
+% \iffalse meta-comment
+%
+%% File: l3coffins.dtx
+%
+% Copyright (C) 2010-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3coffins} module\\ Coffin code layer^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% The material in this module provides the low-level support system
+% for coffins. For details about the design concept of a coffin, see
+% the \pkg{xcoffins} module (in the \pkg{l3experimental} bundle).
+%
+% \section{Creating and initialising coffins}
+%
+% \begin{function}[added = 2011-08-17]{\coffin_new:N, \coffin_new:c}
+% \begin{syntax}
+% \cs{coffin_new:N} \meta{coffin}
+% \end{syntax}
+% Creates a new \meta{coffin} or raises an error if the name is
+% already taken. The declaration is global. The \meta{coffin} is
+% initially empty.
+% \end{function}
+%
+% \begin{function}[added = 2011-08-17, updated = 2019-01-21]
+% {
+% \coffin_clear:N, \coffin_clear:c,
+% \coffin_gclear:N, \coffin_gclear:c
+% }
+% \begin{syntax}
+% \cs{coffin_clear:N} \meta{coffin}
+% \end{syntax}
+% Clears the content of the \meta{coffin}.
+% \end{function}
+%
+% \begin{function}[added = 2011-08-17, updated = 2019-01-21]
+% {
+% \coffin_set_eq:NN, \coffin_set_eq:Nc,
+% \coffin_set_eq:cN, \coffin_set_eq:cc,
+% \coffin_gset_eq:NN, \coffin_gset_eq:Nc,
+% \coffin_gset_eq:cN, \coffin_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{coffin_set_eq:NN} \meta{coffin_1} \meta{coffin_2}
+% \end{syntax}
+% Sets both the content and poles of \meta{coffin_1} equal to those
+% of \meta{coffin_2}.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added = 2012-06-20]
+% {\coffin_if_exist:N, \coffin_if_exist:c}
+% \begin{syntax}
+% \cs{coffin_if_exist_p:N} \meta{coffin}
+% \cs{coffin_if_exist:NTF} \meta{coffin} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{coffin} is currently defined.
+% \end{function}
+%
+% \section{Setting coffin content and poles}
+%
+% \begin{function}[added = 2011-08-17, updated = 2019-01-21]
+% {
+% \hcoffin_set:Nn, \hcoffin_set:cn,
+% \hcoffin_gset:Nn, \hcoffin_gset:cn
+% }
+% \begin{syntax}
+% \cs{hcoffin_set:Nn} \meta{coffin} \Arg{material}
+% \end{syntax}
+% Typesets the \meta{material} in horizontal mode, storing the result
+% in the \meta{coffin}. The standard poles for the \meta{coffin} are
+% then set up based on the size of the typeset material.
+% \end{function}
+%
+% \begin{function}[added = 2011-09-10, updated = 2019-01-21]
+% {
+% \hcoffin_set:Nw, \hcoffin_set:cw, \hcoffin_set_end:,
+% \hcoffin_gset:Nw, \hcoffin_gset:cw, \hcoffin_gset_end:
+% }
+% \begin{syntax}
+% \cs{hcoffin_set:Nw} \meta{coffin} \meta{material} \cs{hcoffin_set_end:}
+% \end{syntax}
+% Typesets the \meta{material} in horizontal mode, storing the result
+% in the \meta{coffin}. The standard poles for the \meta{coffin} are
+% then set up based on the size of the typeset material.
+% These functions are useful for setting the entire contents of an
+% environment in a coffin.
+% \end{function}
+%
+% \begin{function}[added = 2011-08-17, updated = 2023-02-03]
+% {
+% \vcoffin_set:Nnn, \vcoffin_set:cnn,
+% \vcoffin_gset:Nnn, \vcoffin_gset:cnn
+% }
+% \begin{syntax}
+% \cs{vcoffin_set:Nnn} \meta{coffin} \Arg{width} \Arg{material}
+% \end{syntax}
+% Typesets the \meta{material} in vertical mode constrained to the
+% given \meta{width} and stores the result in the \meta{coffin}. The
+% standard poles for the \meta{coffin} are then set up based on the
+% size of the typeset material.
+% \end{function}
+%
+% \begin{function}[added = 2011-09-10, updated = 2023-02-03]
+% {
+% \vcoffin_set:Nnw, \vcoffin_set:cnw, \vcoffin_set_end:,
+% \vcoffin_gset:Nnw, \vcoffin_gset:cnw, \vcoffin_gset_end:
+% }
+% \begin{syntax}
+% \cs{vcoffin_set:Nnw} \meta{coffin} \Arg{width} \meta{material} \cs{vcoffin_set_end:}
+% \end{syntax}
+% Typesets the \meta{material} in vertical mode constrained to the
+% given \meta{width} and stores the result in the \meta{coffin}. The
+% standard poles for the \meta{coffin} are then set up based on the
+% size of the typeset material.
+% These functions are useful for setting the entire contents of an
+% environment in a coffin.
+% \end{function}
+%
+% \begin{function}[added = 2012-07-20, updated = 2019-01-21]
+% {
+% \coffin_set_horizontal_pole:Nnn, \coffin_set_horizontal_pole:cnn,
+% \coffin_gset_horizontal_pole:Nnn, \coffin_gset_horizontal_pole:cnn
+% }
+% \begin{syntax}
+% \cs{coffin_set_horizontal_pole:Nnn} \meta{coffin}
+% ~~\Arg{pole} \Arg{offset}
+% \end{syntax}
+% Sets the \meta{pole} to run horizontally through the \meta{coffin}.
+% The \meta{pole} is placed at the \meta{offset} from the
+% baseline of the \meta{coffin}. The
+% \meta{offset} should be given as a dimension expression.
+% \end{function}
+%
+% \begin{function}[added = 2012-07-20, updated = 2019-01-21]
+% {
+% \coffin_set_vertical_pole:Nnn, \coffin_set_vertical_pole:cnn,
+% \coffin_gset_vertical_pole:Nnn, \coffin_gset_vertical_pole:cnn
+% }
+% \begin{syntax}
+% \cs{coffin_set_vertical_pole:Nnn} \meta{coffin} \Arg{pole} \Arg{offset}
+% \end{syntax}
+% Sets the \meta{pole} to run vertically through the \meta{coffin}.
+% The \meta{pole} is placed at the \meta{offset} from the
+% left-hand edge of the bounding box of the \meta{coffin}. The
+% \meta{offset} should be given as a dimension expression.
+% \end{function}
+%
+% \begin{function}[added = 2023-05-17]{\coffin_reset_poles:N, \coffin_greset_poles:N}
+% \begin{syntax}
+% \cs{coffin_reset_poles:N} \meta{coffin}
+% \end{syntax}
+% Resets the poles of the \meta{coffin} to the standard set, removing any
+% custom or inherited poles. The poles will therefore be equal to those that
+% would be obtained from \cs{hcoffin_set:Nn} or similar; the bounding box
+% of the coffin is not reset, so any material outside of the formal bounding box
+% will not influence the poles.
+% \end{function}
+%
+% \section{Coffin affine transformations}
+%
+% \begin{function}[updated = 2019-01-23]
+% {
+% \coffin_resize:Nnn, \coffin_resize:cnn,
+% \coffin_gresize:Nnn, \coffin_gresize:cnn
+% }
+% \begin{syntax}
+% \cs{coffin_resize:Nnn} \meta{coffin} \Arg{width} \Arg{total-height}
+% \end{syntax}
+% Resized the \meta{coffin} to \meta{width} and \meta{total-height},
+% both of which should be given as dimension expressions.
+% \end{function}
+%
+% \begin{function}
+% {
+% \coffin_rotate:Nn, \coffin_rotate:cn,
+% \coffin_grotate:Nn, \coffin_grotate:cn
+% }
+% \begin{syntax}
+% \cs{coffin_rotate:Nn} \meta{coffin} \Arg{angle}
+% \end{syntax}
+% Rotates the \meta{coffin} by the given \meta{angle} (given in
+% degrees counter-clockwise). This process rotates both the
+% coffin content and poles. Multiple rotations do not result in
+% the bounding box of the coffin growing unnecessarily.
+% \end{function}
+%
+% \begin{function}[updated = 2019-01-23]
+% {
+% \coffin_scale:Nnn, \coffin_scale:cnn,
+% \coffin_gscale:Nnn, \coffin_gscale:cnn
+% }
+% \begin{syntax}
+% \cs{coffin_scale:Nnn} \meta{coffin} \Arg{x-scale} \Arg{y-scale}
+% \end{syntax}
+% Scales the \meta{coffin} by a factors \meta{x-scale} and
+% \meta{y-scale} in the horizontal and vertical directions,
+% respectively. The two scale factors should be given as real numbers.
+% \end{function}
+%
+% \section{Joining and using coffins}
+%
+% \begin{function}[updated = 2019-01-22]
+% {
+% \coffin_attach:NnnNnnnn, \coffin_attach:cnnNnnnn,
+% \coffin_attach:Nnncnnnn, \coffin_attach:cnncnnnn,
+% \coffin_gattach:NnnNnnnn, \coffin_gattach:cnnNnnnn,
+% \coffin_gattach:Nnncnnnn, \coffin_gattach:cnncnnnn
+% }
+% \begin{syntax}
+% \cs{coffin_attach:NnnNnnnn}
+% ~~\meta{coffin_1} \Arg{coffin_1-pole_1} \Arg{coffin_1-pole_2}
+% ~~\meta{coffin_2} \Arg{coffin_2-pole_1} \Arg{coffin_2-pole_2}
+% ~~\Arg{x-offset} \Arg{y-offset}
+% \end{syntax}
+% This function attaches \meta{coffin_2} to \meta{coffin_1} such that the bounding box
+% of \meta{coffin_1} is not altered, \emph{i.e.}~\meta{coffin_2} can
+% protrude outside of the bounding box of the coffin. The alignment
+% is carried out by first calculating \meta{handle_1}, the
+% point of intersection of \meta{coffin_1-pole_1} and
+% \meta{coffin_1-pole_2}, and \meta{handle_2}, the point of intersection
+% of \meta{coffin_2-pole_1} and \meta{coffin_2-pole_2}. \meta{coffin_2} is
+% then attached to \meta{coffin_1} such that the relationship between
+% \meta{handle_1} and \meta{handle_2} is described by the \meta{x-offset}
+% and \meta{y-offset}. The two offsets should be given as dimension
+% expressions.
+% \end{function}
+%
+% \begin{function}[updated = 2019-01-22]
+% {
+% \coffin_join:NnnNnnnn, \coffin_join:cnnNnnnn,
+% \coffin_join:Nnncnnnn, \coffin_join:cnncnnnn,
+% \coffin_gjoin:NnnNnnnn, \coffin_gjoin:cnnNnnnn,
+% \coffin_gjoin:Nnncnnnn, \coffin_gjoin:cnncnnnn
+% }
+% \begin{syntax}
+% \cs{coffin_join:NnnNnnnn}
+% ~~\meta{coffin_1} \Arg{coffin_1-pole_1} \Arg{coffin_1-pole_2}
+% ~~\meta{coffin_2} \Arg{coffin_2-pole_1} \Arg{coffin_2-pole_2}
+% ~~\Arg{x-offset} \Arg{y-offset}
+% \end{syntax}
+% This function joins \meta{coffin_2} to \meta{coffin_1} such that the bounding box
+% of \meta{coffin_1} may expand. The new bounding
+% box covers the area containing the bounding boxes of the two
+% original coffins. The alignment is carried out by first calculating
+% \meta{handle_1}, the point of intersection of \meta{coffin_1-pole_1} and
+% \meta{coffin_1-pole_2}, and \meta{handle_2}, the point of intersection
+% of \meta{coffin_2-pole_1} and \meta{coffin_2-pole_2}. \meta{coffin_2} is
+% then attached to \meta{coffin_1} such that the relationship between
+% \meta{handle_1} and \meta{handle_2} is described by the \meta{x-offset}
+% and \meta{y-offset}. The two offsets should be given as dimension
+% expressions.
+% \end{function}
+%
+% \begin{function}[updated = 2012-07-20]
+% {\coffin_typeset:Nnnnn, \coffin_typeset:cnnnn}
+% \begin{syntax}
+% \cs{coffin_typeset:Nnnnn} \meta{coffin} \Arg{pole_1} \Arg{pole_2}
+% ~~\Arg{x-offset} \Arg{y-offset}
+% \end{syntax}
+% Typesetting is carried out by first calculating \meta{handle}, the
+% point of intersection of \meta{pole_1} and \meta{pole_2}. The coffin
+% is then typeset in horizontal mode such that the relationship between the
+% current reference point in the document and the \meta{handle} is described
+% by the \meta{x-offset} and \meta{y-offset}. The two offsets should
+% be given as dimension expressions. Typesetting a coffin is
+% therefore analogous to carrying out an alignment where the
+% \enquote{parent} coffin is the current insertion point.
+% \end{function}
+%
+% \section{Measuring coffins}
+%
+% \begin{function}{\coffin_dp:N, \coffin_dp:c}
+% \begin{syntax}
+% \cs{coffin_dp:N} \meta{coffin}
+% \end{syntax}
+% Calculates the depth (below the baseline) of the \meta{coffin}
+% in a form suitable for use in a \meta{dim expr}.
+% \end{function}
+%
+% \begin{function}{\coffin_ht:N, \coffin_ht:c}
+% \begin{syntax}
+% \cs{coffin_ht:N} \meta{coffin}
+% \end{syntax}
+% Calculates the height (above the baseline) of the \meta{coffin}
+% in a form suitable for use in a \meta{dim expr}.
+% \end{function}
+%
+% \begin{function}{\coffin_wd:N, \coffin_wd:c}
+% \begin{syntax}
+% \cs{coffin_wd:N} \meta{coffin}
+% \end{syntax}
+% Calculates the width of the \meta{coffin} in a form
+% suitable for use in a \meta{dim expr}.
+% \end{function}
+%
+% \section{Coffin diagnostics}
+%
+% \begin{function}[updated = 2011-09-02]
+% {\coffin_display_handles:Nn, \coffin_display_handles:cn}
+% \begin{syntax}
+% \cs{coffin_display_handles:Nn} \meta{coffin} \Arg{color}
+% \end{syntax}
+% This function first calculates the intersections between all of
+% the \meta{poles} of the \meta{coffin} to give a set of
+% \meta{handles}. It then prints the \meta{coffin} at the current
+% location in the source, with the position of the \meta{handles}
+% marked on the coffin. The \meta{handles} are labelled as part
+% of this process: the locations of the \meta{handles} and the labels
+% are both printed in the \meta{color} specified.
+% \end{function}
+%
+% \begin{function}[updated = 2011-09-02]
+% {\coffin_mark_handle:Nnnn, \coffin_mark_handle:cnnn}
+% \begin{syntax}
+% \cs{coffin_mark_handle:Nnnn} \meta{coffin} \Arg{pole_1} \Arg{pole_2} \Arg{color}
+% \end{syntax}
+% This function first calculates the \meta{handle} for the
+% \meta{coffin} as defined by the intersection of \meta{pole_1} and
+% \meta{pole_2}. It then marks the position of the \meta{handle}
+% on the \meta{coffin}. The \meta{handle} are labelled as part of
+% this process: the location of the \meta{handle} and the label are
+% both printed in the \meta{color} specified.
+% \end{function}
+%
+% \begin{function}[updated = 2015-08-01]
+% {\coffin_show_structure:N, \coffin_show_structure:c}
+% \begin{syntax}
+% \cs{coffin_show_structure:N} \meta{coffin}
+% \end{syntax}
+% This function shows the structural information about the
+% \meta{coffin} in the terminal. The width, height and depth of the
+% typeset material are given, along with the location of all of the
+% poles of the coffin.
+%
+% Notice that the poles of a coffin are defined by four values:
+% the $x$ and $y$ co-ordinates of a point that the pole
+% passes through and the $x$- and $y$-components of a
+% vector denoting the direction of the pole. It is the ratio between
+% the later, rather than the absolute values, which determines the
+% direction of the pole.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2015-08-01]
+% {\coffin_log_structure:N, \coffin_log_structure:c}
+% \begin{syntax}
+% \cs{coffin_log_structure:N} \meta{coffin}
+% \end{syntax}
+% This function writes the structural information about the
+% \meta{coffin} in the log file. See also \cs{coffin_show_structure:N}
+% which displays the result in the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2021-05-11]
+% {\coffin_show:N, \coffin_show:c, \coffin_log:N, \coffin_log:c}
+% \begin{syntax}
+% \cs{coffin_show:N} \meta{coffin}
+% \cs{coffin_log:N} \meta{coffin}
+% \end{syntax}
+% Shows full details of poles and contents of the \meta{coffin} in the
+% terminal or log file. See \cs{coffin_show_structure:N} and
+% \cs{box_show:N} to show separately the pole structure and the
+% contents.
+% \end{function}
+%
+% \begin{function}[added = 2021-05-11]
+% {\coffin_show:Nnn, \coffin_show:cnn, \coffin_log:Nnn, \coffin_log:cnn}
+% \begin{syntax}
+% \cs{coffin_show:Nnn} \meta{coffin} \Arg{int expr_1} \Arg{int expr_2}
+% \cs{coffin_log:Nnn} \meta{coffin} \Arg{int expr_1} \Arg{int expr_2}
+% \end{syntax}
+% Shows poles and contents of the \meta{coffin} in the terminal or log
+% file, showing the first \meta{int expr_1} items in the coffin, and
+% descending into \meta{int expr_2} group levels. See
+% \cs{coffin_show_structure:N} and \cs{box_show:Nnn} to show
+% separately the pole structure and the contents.
+% \end{function}
+%
+% \section{Constants and variables}
+%
+% \begin{variable}{\c_empty_coffin}
+% A permanently empty coffin.
+% \end{variable}
+%
+% \begin{variable}[added = 2012-06-19]{\l_tmpa_coffin, \l_tmpb_coffin}
+% Scratch coffins for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}[added = 2019-01-24]{\g_tmpa_coffin, \g_tmpb_coffin}
+% Scratch coffins for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3coffins} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=coffin>
+% \end{macrocode}
+%
+% \subsection{Coffins: data structures and general variables}
+%
+% \begin{variable}{\l_@@_internal_box}
+% \begin{variable}{\l_@@_internal_dim}
+% \begin{variable}{\l_@@_internal_tl}
+% Scratch variables.
+% \begin{macrocode}
+\box_new:N \l_@@_internal_box
+\dim_new:N \l_@@_internal_dim
+\tl_new:N \l_@@_internal_tl
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_corners_prop}
+% The \enquote{corners}; of a coffin define the real content, as
+% opposed to the \TeX{} bounding box. They all start off in the same
+% place, of course.
+% \begin{macrocode}
+\prop_const_from_keyval:Nn \c_@@_corners_prop
+ {
+ tl = { 0pt } { 0pt } ,
+ tr = { 0pt } { 0pt } ,
+ bl = { 0pt } { 0pt } ,
+ br = { 0pt } { 0pt } ,
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_poles_prop}
+% Pole positions are given for horizontal, vertical and reference-point
+% based values.
+% \begin{macrocode}
+\prop_const_from_keyval:Nn \c_@@_poles_prop
+ {
+ l = { 0pt } { 0pt } { 0pt } { 1000pt } ,
+ hc = { 0pt } { 0pt } { 0pt } { 1000pt } ,
+ r = { 0pt } { 0pt } { 0pt } { 1000pt } ,
+ b = { 0pt } { 0pt } { 1000pt } { 0pt } ,
+ vc = { 0pt } { 0pt } { 1000pt } { 0pt } ,
+ t = { 0pt } { 0pt } { 1000pt } { 0pt } ,
+ B = { 0pt } { 0pt } { 1000pt } { 0pt } ,
+ H = { 0pt } { 0pt } { 1000pt } { 0pt } ,
+ T = { 0pt } { 0pt } { 1000pt } { 0pt } ,
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_slope_A_fp}
+% \begin{variable}{\l_@@_slope_B_fp}
+% Used for calculations of intersections.
+% \begin{macrocode}
+\fp_new:N \l_@@_slope_A_fp
+\fp_new:N \l_@@_slope_B_fp
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_error_bool}
+% For propagating errors so that parts of the code can work around them.
+% \begin{macrocode}
+\bool_new:N \l_@@_error_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_offset_x_dim}
+% \begin{variable}{\l_@@_offset_y_dim}
+% The offset between two sets of coffin handles when typesetting. These
+% values are corrected from those requested in an alignment for the
+% positions of the handles.
+% \begin{macrocode}
+\dim_new:N \l_@@_offset_x_dim
+\dim_new:N \l_@@_offset_y_dim
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_pole_a_tl}
+% \begin{variable}{\l_@@_pole_b_tl}
+% Needed for finding the intersection of two poles.
+% \begin{macrocode}
+\tl_new:N \l_@@_pole_a_tl
+\tl_new:N \l_@@_pole_b_tl
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_x_dim}
+% \begin{variable}{\l_@@_y_dim}
+% \begin{variable}{\l_@@_x_prime_dim}
+% \begin{variable}{\l_@@_y_prime_dim}
+% For calculating intersections and so forth.
+% \begin{macrocode}
+\dim_new:N \l_@@_x_dim
+\dim_new:N \l_@@_y_dim
+\dim_new:N \l_@@_x_prime_dim
+\dim_new:N \l_@@_y_prime_dim
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \subsection{Basic coffin functions}
+%
+% There are a number of basic functions needed for creating coffins and
+% placing material in them. This all relies on the following data
+% structures.
+%
+% \begin{macro}[EXP]{\@@_to_value:N}
+% Coffins are a two-part structure and we rely on the internal nature of
+% box allocation to make everything work. As such, we need an interface
+% to turn coffin identifiers into numbers. For the purposes here, the
+% signature allowed is |N| despite the nature of the underlying primitive.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_to_value:N \tex_number:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, pTF]{\coffin_if_exist:N, \coffin_if_exist:c}
+% Several of the higher-level coffin functions would give multiple
+% errors if the coffin does not exist. A cleaner way to handle this
+% is provided here: both the box and the coffin structure are
+% checked.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \coffin_if_exist:N #1 { p , T , F , TF }
+ {
+ \cs_if_exist:NTF #1
+ {
+ \cs_if_exist:cTF { coffin ~ \@@_to_value:N #1 ~ poles }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn \coffin_if_exist:N
+ { c } { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_if_exist:NT}
+% Several of the higher-level coffin functions would give multiple
+% errors if the coffin does not exist. So a wrapper is provided to deal
+% with this correctly, issuing an error on erroneous use.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_if_exist:NT #1#2
+ {
+ \coffin_if_exist:NTF #1
+ { #2 }
+ {
+ \msg_error:nne { coffin } { unknown }
+ { \token_to_str:N #1 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \coffin_clear:N, \coffin_clear:c,
+% \coffin_gclear:N, \coffin_gclear:c
+% }
+% Clearing coffins means emptying the box and resetting all of the
+% structures.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_clear:N #1
+ {
+ \@@_if_exist:NT #1
+ {
+ \box_clear:N #1
+ \@@_reset_structure:N #1
+ }
+ }
+\cs_generate_variant:Nn \coffin_clear:N { c }
+\cs_new_protected:Npn \coffin_gclear:N #1
+ {
+ \@@_if_exist:NT #1
+ {
+ \box_gclear:N #1
+ \@@_greset_structure:N #1
+ }
+ }
+\cs_generate_variant:Nn \coffin_gclear:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\coffin_new:N, \coffin_new:c}
+% Creating a new coffin means making the underlying box and adding the
+% data structures. The \cs{debug_suspend:} and \cs{debug_resume:} functions
+% prevent \cs{prop_gclear_new:c} from writing useless information to
+% the log file.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_new:N #1
+ {
+ \box_new:N #1
+ \debug_suspend:
+ \prop_gclear_new:c { coffin ~ \@@_to_value:N #1 ~ corners }
+ \prop_gclear_new:c { coffin ~ \@@_to_value:N #1 ~ poles }
+ \prop_gset_eq:cN { coffin ~ \@@_to_value:N #1 ~ corners }
+ \c_@@_corners_prop
+ \prop_gset_eq:cN { coffin ~ \@@_to_value:N #1 ~ poles }
+ \c_@@_poles_prop
+ \debug_resume:
+ }
+\cs_generate_variant:Nn \coffin_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \hcoffin_set:Nn, \hcoffin_set:cn,
+% \hcoffin_gset:Nn, \hcoffin_gset:cn
+% }
+% Horizontal coffins are relatively easy: set the appropriate box,
+% reset the structures then update the handle positions.
+% \begin{macrocode}
+\cs_new_protected:Npn \hcoffin_set:Nn #1#2
+ {
+ \@@_if_exist:NT #1
+ {
+ \hbox_set:Nn #1
+ {
+ \color_ensure_current:
+ #2
+ }
+ \coffin_reset_poles:N #1
+ }
+ }
+\cs_generate_variant:Nn \hcoffin_set:Nn { c }
+\cs_new_protected:Npn \hcoffin_gset:Nn #1#2
+ {
+ \@@_if_exist:NT #1
+ {
+ \hbox_gset:Nn #1
+ {
+ \color_ensure_current:
+ #2
+ }
+ \coffin_greset_poles:N #1
+ }
+ }
+\cs_generate_variant:Nn \hcoffin_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \vcoffin_set:Nnn, \vcoffin_set:cnn,
+% \vcoffin_gset:Nnn, \vcoffin_gset:cnn
+% }
+% \begin{macro}{\@@_set_vertical:NnnNNN}
+% \begin{macro}{\@@_set_vertical_aux:}
+% Setting vertical coffins is more complex. First, the material is
+% typeset with a given width. The default handles and poles are set as
+% for a horizontal coffin, before finding the top baseline using a
+% temporary box. No \cs{color_ensure_current:} here as that would add a
+% whatsit to the start of the vertical box and mess up the location of the
+% \texttt{T}~pole (see \emph{\TeX{} by Topic} for discussion of the
+% \tn{vtop} primitive, used to do the measuring).
+% \begin{macrocode}
+\cs_new_protected:Npn \vcoffin_set:Nnn #1#2#3
+ {
+ \@@_set_vertical:NnnNNN #1 {#2} {#3}
+ \vbox_set:Nn \coffin_reset_poles:N \@@_set_pole:Nnn
+ }
+\cs_generate_variant:Nn \vcoffin_set:Nnn { c }
+\cs_new_protected:Npn \vcoffin_gset:Nnn #1#2#3
+ {
+ \@@_set_vertical:NnnNNN #1 {#2} {#3}
+ \vbox_gset:Nn \coffin_greset_poles:N \@@_gset_pole:Nnn
+ }
+\cs_generate_variant:Nn \vcoffin_gset:Nnn { c }
+\cs_new_protected:Npn \@@_set_vertical:NnnNNN #1#2#3#4#5#6
+ {
+ \@@_if_exist:NT #1
+ {
+ #4 #1
+ {
+ \dim_set:Nn \tex_hsize:D {#2}
+ \@@_set_vertical_aux:
+ #3
+ }
+ #5 #1
+ \vbox_set_top:Nn \l_@@_internal_box { \vbox_unpack:N #1 }
+ #6 #1 { T }
+ {
+ { 0pt }
+ {
+ \dim_eval:n
+ { \box_ht:N #1 - \box_ht:N \l_@@_internal_box }
+ }
+ { 1000pt }
+ { 0pt }
+ }
+ \box_clear:N \l_@@_internal_box
+ }
+ }
+\cs_new_protected:Npe \@@_set_vertical_aux:
+ {
+ \bool_lazy_and:nnT
+ { \cs_if_exist_p:N \fmtname }
+ { \str_if_eq_p:Vn \fmtname { LaTeX2e } }
+ {
+ \dim_set_eq:NN \exp_not:N \linewidth \tex_hsize:D
+ \dim_set_eq:NN \exp_not:N \columnwidth \tex_hsize:D
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\hcoffin_set:Nw, \hcoffin_set:cw, \hcoffin_gset:Nw, \hcoffin_gset:cw}
+% \begin{macro}{\hcoffin_set_end:, \hcoffin_gset_end:}
+% These are the \enquote{begin}/\enquote{end} versions of the above:
+% watch the grouping!
+% \begin{macrocode}
+\cs_new_protected:Npn \hcoffin_set:Nw #1
+ {
+ \@@_if_exist:NT #1
+ {
+ \hbox_set:Nw #1 \color_ensure_current:
+ \cs_set_protected:Npn \hcoffin_set_end:
+ {
+ \hbox_set_end:
+ \coffin_reset_poles:N #1
+ }
+ }
+ }
+\cs_generate_variant:Nn \hcoffin_set:Nw { c }
+\cs_new_protected:Npn \hcoffin_gset:Nw #1
+ {
+ \@@_if_exist:NT #1
+ {
+ \hbox_gset:Nw #1 \color_ensure_current:
+ \cs_set_protected:Npn \hcoffin_gset_end:
+ {
+ \hbox_gset_end:
+ \coffin_greset_poles:N #1
+ }
+ }
+ }
+\cs_generate_variant:Nn \hcoffin_gset:Nw { c }
+\cs_new_protected:Npn \hcoffin_set_end: { }
+\cs_new_protected:Npn \hcoffin_gset_end: { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\vcoffin_set:Nnw, \vcoffin_set:cnw, \vcoffin_gset:Nnw, \vcoffin_gset:cnw}
+% \begin{macro}{\@@_set_vertical:NnNNNNNw}
+% \begin{macro}{\vcoffin_set_end:, \vcoffin_gset_end:}
+% The same for vertical coffins.
+% \begin{macrocode}
+\cs_new_protected:Npn \vcoffin_set:Nnw #1#2
+ {
+ \@@_set_vertical:NnNNNNNw #1 {#2} \vbox_set:Nw
+ \vcoffin_set_end:
+ \vbox_set_end: \coffin_reset_poles:N \@@_set_pole:Nnn
+ }
+\cs_generate_variant:Nn \vcoffin_set:Nnw { c }
+\cs_new_protected:Npn \vcoffin_gset:Nnw #1#2
+ {
+ \@@_set_vertical:NnNNNNNw #1 {#2} \vbox_gset:Nw
+ \vcoffin_gset_end:
+ \vbox_gset_end: \coffin_greset_poles:N \@@_gset_pole:Nnn
+ }
+\cs_generate_variant:Nn \vcoffin_gset:Nnw { c }
+\cs_new_protected:Npn \@@_set_vertical:NnNNNNNw #1#2#3#4#5#6#7
+ {
+ \@@_if_exist:NT #1
+ {
+ #3 #1
+ \dim_set:Nn \tex_hsize:D {#2}
+ \@@_set_vertical_aux:
+ \cs_set_protected:Npn #4
+ {
+ #5
+ #6 #1
+ \vbox_set_top:Nn \l_@@_internal_box { \vbox_unpack:N #1 }
+ #7 #1 { T }
+ {
+ { 0pt }
+ {
+ \dim_eval:n
+ { \box_ht:N #1 - \box_ht:N \l_@@_internal_box }
+ }
+ { 1000pt }
+ { 0pt }
+ }
+ \box_clear:N \l_@@_internal_box
+ }
+ }
+ }
+\cs_new_protected:Npn \vcoffin_set_end: { }
+\cs_new_protected:Npn \vcoffin_gset_end: { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \coffin_set_eq:NN, \coffin_set_eq:Nc,
+% \coffin_set_eq:cN, \coffin_set_eq:cc,
+% \coffin_gset_eq:NN, \coffin_gset_eq:Nc,
+% \coffin_gset_eq:cN, \coffin_gset_eq:cc
+% }
+% Setting two coffins equal is just a wrapper around other functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_set_eq:NN #1#2
+ {
+ \@@_if_exist:NT #1
+ {
+ \box_set_eq:NN #1 #2
+ \prop_set_eq:cc { coffin ~ \@@_to_value:N #1 ~ corners }
+ { coffin ~ \@@_to_value:N #2 ~ corners }
+ \prop_set_eq:cc { coffin ~ \@@_to_value:N #1 ~ poles }
+ { coffin ~ \@@_to_value:N #2 ~ poles }
+ }
+ }
+\cs_generate_variant:Nn \coffin_set_eq:NN { c , Nc , cc }
+\cs_new_protected:Npn \coffin_gset_eq:NN #1#2
+ {
+ \@@_if_exist:NT #1
+ {
+ \box_gset_eq:NN #1 #2
+ \prop_gset_eq:cc { coffin ~ \@@_to_value:N #1 ~ corners }
+ { coffin ~ \@@_to_value:N #2 ~ corners }
+ \prop_gset_eq:cc { coffin ~ \@@_to_value:N #1 ~ poles }
+ { coffin ~ \@@_to_value:N #2 ~ poles }
+ }
+ }
+\cs_generate_variant:Nn \coffin_gset_eq:NN { c , Nc , cc }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\c_empty_coffin}
+% \begin{variable}{\l_@@_aligned_coffin}
+% \begin{variable}{\l_@@_aligned_internal_coffin}
+% Special coffins: these cannot be set up earlier as they need
+% \cs{coffin_new:N}. The empty coffin is set as a box as the full
+% coffin-setting system needs some material which is not yet available.
+% The empty coffin is creted entirely by hand: not everything is in place
+% yet.
+% \begin{macrocode}
+\coffin_new:N \c_empty_coffin
+\coffin_new:N \l_@@_aligned_coffin
+\coffin_new:N \l_@@_aligned_internal_coffin
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}
+% {\l_tmpa_coffin, \l_tmpb_coffin, \g_tmpa_coffin, \g_tmpb_coffin}
+% The usual scratch space.
+% \begin{macrocode}
+\coffin_new:N \l_tmpa_coffin
+\coffin_new:N \l_tmpb_coffin
+\coffin_new:N \g_tmpa_coffin
+\coffin_new:N \g_tmpb_coffin
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Measuring coffins}
+%
+% \begin{macro}
+% {
+% \coffin_dp:N, \coffin_dp:c, \coffin_ht:N, \coffin_ht:c,
+% \coffin_wd:N, \coffin_wd:c
+% }
+% Coffins are just boxes when it comes to measurement. However, semantically
+% a separate set of functions are required.
+% \begin{macrocode}
+\cs_new_eq:NN \coffin_dp:N \box_dp:N
+\cs_new_eq:NN \coffin_dp:c \box_dp:c
+\cs_new_eq:NN \coffin_ht:N \box_ht:N
+\cs_new_eq:NN \coffin_ht:c \box_ht:c
+\cs_new_eq:NN \coffin_wd:N \box_wd:N
+\cs_new_eq:NN \coffin_wd:c \box_wd:c
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Coffins: handle and pole management}
+%
+% \begin{macro}{\@@_get_pole:NnN}
+% A simple wrapper around the recovery of a coffin pole, with some
+% error checking and recovery built-in.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_get_pole:NnN #1#2#3
+ {
+ \prop_get:cnNF
+ { coffin ~ \@@_to_value:N #1 ~ poles } {#2} #3
+ {
+ \msg_error:nnee { coffin } { unknown-pole }
+ { \exp_not:n {#2} } { \token_to_str:N #1 }
+ \tl_set:Nn #3 { { 0pt } { 0pt } { 0pt } { 0pt } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_reset_structure:N, \@@_greset_structure:N}
+% Resetting the structure is a simple copy job.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_reset_structure:N #1
+ {
+ \prop_set_eq:cN { coffin ~ \@@_to_value:N #1 ~ corners }
+ \c_@@_corners_prop
+ \prop_set_eq:cN { coffin ~ \@@_to_value:N #1 ~ poles }
+ \c_@@_poles_prop
+ }
+\cs_new_protected:Npn \@@_greset_structure:N #1
+ {
+ \prop_gset_eq:cN { coffin ~ \@@_to_value:N #1 ~ corners }
+ \c_@@_corners_prop
+ \prop_gset_eq:cN { coffin ~ \@@_to_value:N #1 ~ poles }
+ \c_@@_poles_prop
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \coffin_set_horizontal_pole:Nnn, \coffin_set_horizontal_pole:cnn,
+% \coffin_gset_horizontal_pole:Nnn, \coffin_gset_horizontal_pole:cnn
+% }
+% \begin{macro}{\@@_set_horizontal_pole:NnnN}
+% \begin{macro}
+% {
+% \coffin_set_vertical_pole:Nnn, \coffin_set_vertical_pole:cnn,
+% \coffin_gset_vertical_pole:Nnn, \coffin_gset_vertical_pole:cnn
+% }
+% \begin{macro}{\@@_set_vertical_pole:NnnN}
+% \begin{macro}{\@@_set_pole:Nnn, \@@_gset_pole:Nnn}
+% Setting the pole of a coffin at the user/designer level requires a
+% bit more care. The idea here is to provide a reasonable interface to
+% the system, then to do the setting with full expansion. The
+% three-argument version is used internally to do a direct setting.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_set_horizontal_pole:Nnn #1#2#3
+ { \@@_set_horizontal_pole:NnnN #1 {#2} {#3} \prop_put:cne }
+\cs_generate_variant:Nn \coffin_set_horizontal_pole:Nnn { c }
+\cs_new_protected:Npn \coffin_gset_horizontal_pole:Nnn #1#2#3
+ { \@@_set_horizontal_pole:NnnN #1 {#2} {#3} \prop_gput:cne }
+\cs_generate_variant:Nn \coffin_gset_horizontal_pole:Nnn { c }
+\cs_new_protected:Npn \@@_set_horizontal_pole:NnnN #1#2#3#4
+ {
+ \@@_if_exist:NT #1
+ {
+ #4 { coffin ~ \@@_to_value:N #1 ~ poles }
+ {#2}
+ {
+ { 0pt } { \dim_eval:n {#3} }
+ { 1000pt } { 0pt }
+ }
+ }
+ }
+\cs_new_protected:Npn \coffin_set_vertical_pole:Nnn #1#2#3
+ { \@@_set_vertical_pole:NnnN #1 {#2} {#3} \prop_put:cne }
+\cs_generate_variant:Nn \coffin_set_vertical_pole:Nnn { c }
+\cs_new_protected:Npn \coffin_gset_vertical_pole:Nnn #1#2#3
+ { \@@_set_vertical_pole:NnnN #1 {#2} {#3} \prop_gput:cne }
+ \cs_generate_variant:Nn \coffin_gset_vertical_pole:Nnn { c }
+\cs_new_protected:Npn \@@_set_vertical_pole:NnnN #1#2#3#4
+ {
+ \@@_if_exist:NT #1
+ {
+ #4 { coffin ~ \@@_to_value:N #1 ~ poles }
+ {#2}
+ {
+ { \dim_eval:n {#3} } { 0pt }
+ { 0pt } { 1000pt }
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_set_pole:Nnn #1#2#3
+ {
+ \prop_put:cne { coffin ~ \@@_to_value:N #1 ~ poles }
+ {#2} {#3}
+ }
+\cs_new_protected:Npn \@@_gset_pole:Nnn #1#2#3
+ {
+ \prop_gput:cne { coffin ~ \@@_to_value:N #1 ~ poles }
+ {#2} {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\coffin_reset_poles:N, \coffin_greset_poles:N}
+% Simple shortcuts.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_reset_poles:N #1
+ {
+ \@@_reset_structure:N #1
+ \@@_update_corners:N #1
+ \@@_update_poles:N #1
+ }
+\cs_new_protected:Npn \coffin_greset_poles:N #1
+ {
+ \@@_greset_structure:N #1
+ \@@_gupdate_corners:N #1
+ \@@_gupdate_poles:N #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_update_corners:N, \@@_gupdate_corners:N}
+% \begin{macro}{\@@_update_corners:NN}
+% \begin{macro}{\@@_update_corners:NNN}
+% Updating the corners of a coffin is straight-forward as at this stage
+% there can be no rotation. So the corners of the content are just those
+% of the underlying \TeX{} box.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_update_corners:N #1
+ { \@@_update_corners:NN #1 \prop_put:Nne }
+\cs_new_protected:Npn \@@_gupdate_corners:N #1
+ { \@@_update_corners:NN #1 \prop_gput:Nne }
+\cs_new_protected:Npn \@@_update_corners:NN #1#2
+ {
+ \exp_args:Nc \@@_update_corners:NNN
+ { coffin ~ \@@_to_value:N #1 ~ corners }
+ #1 #2
+ }
+\cs_new_protected:Npn \@@_update_corners:NNN #1#2#3
+ {
+ #3 #1
+ { tl }
+ { { 0pt } { \dim_eval:n { \box_ht:N #2 } } }
+ #3 #1
+ { tr }
+ {
+ { \dim_eval:n { \box_wd:N #2 } }
+ { \dim_eval:n { \box_ht:N #2 } }
+ }
+ #3 #1
+ { bl }
+ { { 0pt } { \dim_eval:n { -\box_dp:N #2 } } }
+ #3 #1
+ { br }
+ {
+ { \dim_eval:n { \box_wd:N #2 } }
+ { \dim_eval:n { -\box_dp:N #2 } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_update_poles:N, \@@_gupdate_poles:N}
+% \begin{macro}{\@@_update_poles:NN}
+% \begin{macro}{\@@_update_poles:NNN}
+% This function is called when a coffin is set, and updates the poles to
+% reflect the nature of size of the box. Thus this function only alters
+% poles where the default position is dependent on the size of the box.
+% It also does not set poles which are relevant only to vertical
+% coffins.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_update_poles:N #1
+ { \@@_update_poles:NN #1 \prop_put:Nne }
+\cs_new_protected:Npn \@@_gupdate_poles:N #1
+ { \@@_update_poles:NN #1 \prop_gput:Nne }
+\cs_new_protected:Npn \@@_update_poles:NN #1#2
+ {
+ \exp_args:Nc \@@_update_poles:NNN
+ { coffin ~ \@@_to_value:N #1 ~ poles }
+ #1 #2
+ }
+\cs_new_protected:Npn \@@_update_poles:NNN #1#2#3
+ {
+ #3 #1 { hc }
+ {
+ { \dim_eval:n { 0.5 \box_wd:N #2 } }
+ { 0pt } { 0pt } { 1000pt }
+ }
+ #3 #1 { r }
+ {
+ { \dim_eval:n { \box_wd:N #2 } }
+ { 0pt } { 0pt } { 1000pt }
+ }
+ #3 #1 { vc }
+ {
+ { 0pt }
+ { \dim_eval:n { ( \box_ht:N #2 - \box_dp:N #2 ) / 2 } }
+ { 1000pt }
+ { 0pt }
+ }
+ #3 #1 { t }
+ {
+ { 0pt }
+ { \dim_eval:n { \box_ht:N #2 } }
+ { 1000pt }
+ { 0pt }
+ }
+ #3 #1 { b }
+ {
+ { 0pt }
+ { \dim_eval:n { -\box_dp:N #2 } }
+ { 1000pt }
+ { 0pt }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Coffins: calculation of pole intersections}
+%
+% \begin{macro}{\@@_calculate_intersection:Nnn}
+% \begin{macro}{\@@_calculate_intersection:nnnnnnnn}
+% \begin{macro}{\@@_calculate_intersection:nnnnnn}
+% The lead off in finding intersections is to recover the two poles
+% and then hand off to the auxiliary for the actual calculation. There
+% may of course not be an intersection, for which an error trap is
+% needed.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_calculate_intersection:Nnn #1#2#3
+ {
+ \@@_get_pole:NnN #1 {#2} \l_@@_pole_a_tl
+ \@@_get_pole:NnN #1 {#3} \l_@@_pole_b_tl
+ \bool_set_false:N \l_@@_error_bool
+ \exp_last_two_unbraced:Noo
+ \@@_calculate_intersection:nnnnnnnn
+ \l_@@_pole_a_tl \l_@@_pole_b_tl
+ \bool_if:NT \l_@@_error_bool
+ {
+ \msg_error:nn { coffin } { no-pole-intersection }
+ \dim_zero:N \l_@@_x_dim
+ \dim_zero:N \l_@@_y_dim
+ }
+ }
+% \end{macrocode}
+% The two poles passed here each have four values (as dimensions),
+% ($a$, $b$, $c$, $d$) and
+% ($a'$, $b'$, $c'$, $d'$). These are arguments
+% $1$--$4$ and $5$--$8$, respectively. In both
+% cases $a$ and $b$ are the co-ordinates of a point on the
+% pole and $c$ and $d$ define the direction of the pole. Finding
+% the intersection depends on the directions of the poles, which are
+% given by $d / c$ and $d' / c'$. However, if one of the poles
+% is either horizontal or vertical then one or more of $c$, $d$,
+% $c'$ and $d'$ are zero and a special case is needed.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_calculate_intersection:nnnnnnnn
+ #1#2#3#4#5#6#7#8
+ {
+ \dim_compare:nNnTF {#3} = \c_zero_dim
+% \end{macrocode}
+% The case where the first pole is vertical. So the $x$-component
+% of the interaction is at $a$. There is then a test on the
+% second pole: if it is also vertical then there is an error.
+% \begin{macrocode}
+ {
+ \dim_set:Nn \l_@@_x_dim {#1}
+ \dim_compare:nNnTF {#7} = \c_zero_dim
+ { \bool_set_true:N \l_@@_error_bool }
+% \end{macrocode}
+% The second pole may still be horizontal, in which case the
+% $y$-component of the intersection is $b'$. If not,
+% \[
+% y = \frac{d'}{c'} \left ( a - a' \right ) + b'
+% \]
+% with the $x$-component already known to be |#1|.
+% \begin{macrocode}
+ {
+ \dim_set:Nn \l_@@_y_dim
+ {
+ \dim_compare:nNnTF {#8} = \c_zero_dim
+ {#6}
+ {
+ \fp_to_dim:n
+ {
+ ( \dim_to_fp:n {#8} / \dim_to_fp:n {#7} )
+ * ( \dim_to_fp:n {#1} - \dim_to_fp:n {#5} )
+ + \dim_to_fp:n {#6}
+ }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% If the first pole is not vertical then it may be horizontal. If so,
+% then the procedure is essentially the same as that already done but
+% with the $x$- and $y$-components interchanged.
+% \begin{macrocode}
+ {
+ \dim_compare:nNnTF {#4} = \c_zero_dim
+ {
+ \dim_set:Nn \l_@@_y_dim {#2}
+ \dim_compare:nNnTF {#8} = { \c_zero_dim }
+ { \bool_set_true:N \l_@@_error_bool }
+ {
+% \end{macrocode}
+% Now we deal with the case where the second pole may be vertical, or
+% if not we have
+% \[
+% x = \frac{c'}{d'} \left ( b - b' \right ) + a'
+% \]
+% which is again handled by the same auxiliary.
+% \begin{macrocode}
+ \dim_set:Nn \l_@@_x_dim
+ {
+ \dim_compare:nNnTF {#7} = \c_zero_dim
+ {#5}
+ {
+ \fp_to_dim:n
+ {
+ ( \dim_to_fp:n {#7} / \dim_to_fp:n {#8} )
+ * ( \dim_to_fp:n {#4} - \dim_to_fp:n {#6} )
+ + \dim_to_fp:n {#5}
+ }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% The first pole is neither horizontal nor vertical. To avoid even
+% more complexity, we now work out both slopes and pass to an auxiliary.
+% \begin{macrocode}
+ {
+ \use:e
+ {
+ \@@_calculate_intersection:nnnnnn
+ { \dim_to_fp:n {#4} / \dim_to_fp:n {#3} }
+ { \dim_to_fp:n {#8} / \dim_to_fp:n {#7} }
+ }
+ {#1} {#2} {#5} {#6}
+ }
+ }
+ }
+% \end{macrocode}
+% Assuming the two poles are not parallel, then the intersection point is
+% found in two steps. First we find the $x$-value with
+% \[
+% x = \frac { sa - s'a' - b + b' }{ s - s' }
+% \]
+% and then finding the $y$-value with
+% \[
+% y = s ( x - a ) + b
+% \]
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_calculate_intersection:nnnnnn #1#2#3#4#5#6
+ {
+ \fp_compare:nNnTF {#1} = {#2}
+ { \bool_set_true:N \l_@@_error_bool }
+ {
+ \dim_set:Nn \l_@@_x_dim
+ {
+ \fp_to_dim:n
+ {
+ (
+ #1 * \dim_to_fp:n {#3}
+ - #2 * \dim_to_fp:n {#5}
+ - \dim_to_fp:n {#4}
+ + \dim_to_fp:n {#6}
+ )
+ /
+ ( #1 - #2 )
+ }
+ }
+ \dim_set:Nn \l_@@_y_dim
+ {
+ \fp_to_dim:n
+ {
+ #1 * ( \l_@@_x_dim - \dim_to_fp:n {#3} )
+ + \dim_to_fp:n {#4}
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Affine transformations}
+%
+% \begin{variable}{\l_@@_sin_fp}
+% \begin{variable}{\l_@@_cos_fp}
+% Used for rotations to get the sine and cosine values.
+% \begin{macrocode}
+\fp_new:N \l_@@_sin_fp
+\fp_new:N \l_@@_cos_fp
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_bounding_prop}
+% A property list for the bounding box of a coffin. This is only needed
+% during the rotation, so there is just the one.
+% \begin{macrocode}
+\prop_new:N \l_@@_bounding_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_corners_prop, \l_@@_poles_prop}
+% Used to avoid needing to track scope for intermediate steps.
+% \begin{macrocode}
+\prop_new:N \l_@@_corners_prop
+\prop_new:N \l_@@_poles_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_bounding_shift_dim}
+% The shift of the bounding box of a coffin from the real content.
+% \begin{macrocode}
+\dim_new:N \l_@@_bounding_shift_dim
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_left_corner_dim}
+% \begin{variable}{\l_@@_right_corner_dim}
+% \begin{variable}{\l_@@_bottom_corner_dim}
+% \begin{variable}{\l_@@_top_corner_dim}
+% These are used to hold maxima for the various corner values: these
+% thus define the minimum size of the bounding box after rotation.
+% \begin{macrocode}
+\dim_new:N \l_@@_left_corner_dim
+\dim_new:N \l_@@_right_corner_dim
+\dim_new:N \l_@@_bottom_corner_dim
+\dim_new:N \l_@@_top_corner_dim
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \coffin_rotate:Nn, \coffin_rotate:cn,
+% \coffin_grotate:Nn, \coffin_grotate:cn
+% }
+% \begin{macro}{\@@_rotate:NnNNN}
+% Rotating a coffin requires several steps which can be conveniently
+% run together. The sine and cosine of the angle in degrees are
+% computed. This is then used to set \cs{l_@@_sin_fp} and
+% \cs{l_@@_cos_fp}, which are carried through unchanged for the rest
+% of the procedure.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_rotate:Nn #1#2
+ { \@@_rotate:NnNNN #1 {#2} \box_rotate:Nn \prop_set_eq:cN \hbox_set:Nn }
+\cs_generate_variant:Nn \coffin_rotate:Nn { c }
+\cs_new_protected:Npn \coffin_grotate:Nn #1#2
+ { \@@_rotate:NnNNN #1 {#2} \box_grotate:Nn \prop_gset_eq:cN \hbox_gset:Nn }
+\cs_generate_variant:Nn \coffin_grotate:Nn { c }
+\cs_new_protected:Npn \@@_rotate:NnNNN #1#2#3#4#5
+ {
+ \fp_set:Nn \l_@@_sin_fp { sind ( #2 ) }
+ \fp_set:Nn \l_@@_cos_fp { cosd ( #2 ) }
+% \end{macrocode}
+% Use a local copy of the property lists to avoid needing to pass the
+% name and scope around.
+% \begin{macrocode}
+ \prop_set_eq:Nc \l_@@_corners_prop
+ { coffin ~ \@@_to_value:N #1 ~ corners }
+ \prop_set_eq:Nc \l_@@_poles_prop
+ { coffin ~ \@@_to_value:N #1 ~ poles }
+% \end{macrocode}
+% The corners and poles of the coffin can now be rotated around the
+% origin. This is best achieved using mapping functions.
+% \begin{macrocode}
+ \prop_map_inline:Nn \l_@@_corners_prop
+ { \@@_rotate_corner:Nnnn #1 {##1} ##2 }
+ \prop_map_inline:Nn \l_@@_poles_prop
+ { \@@_rotate_pole:Nnnnnn #1 {##1} ##2 }
+% \end{macrocode}
+% The bounding box of the coffin needs to be rotated, and to do this
+% the corners have to be found first. They are then rotated in the same
+% way as the corners of the coffin material itself.
+% \begin{macrocode}
+ \@@_set_bounding:N #1
+ \prop_map_inline:Nn \l_@@_bounding_prop
+ { \@@_rotate_bounding:nnn {##1} ##2 }
+% \end{macrocode}
+% At this stage, there needs to be a calculation to find where the
+% corners of the content and the box itself will end up.
+% \begin{macrocode}
+ \@@_find_corner_maxima:N #1
+ \@@_find_bounding_shift:
+ #3 #1 {#2}
+% \end{macrocode}
+% The correction of the box position itself takes place here. The idea
+% is that the bounding box for a coffin is tight up to the content, and
+% has the reference point at the bottom-left. The $x$-direction is
+% handled by moving the content by the difference in the positions of
+% the bounding box and the content left edge. The $y$-direction is
+% dealt with by moving the box down by any depth it has acquired. The
+% internal box is used here to allow for the next step.
+% \begin{macrocode}
+ \hbox_set:Nn \l_@@_internal_box
+ {
+ \__kernel_kern:n
+ { \l_@@_bounding_shift_dim - \l_@@_left_corner_dim }
+ \box_move_down:nn { \l_@@_bottom_corner_dim }
+ { \box_use:N #1 }
+ }
+% \end{macrocode}
+% If there have been any previous rotations then the size of the
+% bounding box will be bigger than the contents. This can be corrected
+% easily by setting the size of the box to the height and width of the
+% content. As this operation requires setting box dimensions and these
+% transcend grouping, the safe way to do this is to use the internal box
+% and to reset the result into the target box.
+% \begin{macrocode}
+ \box_set_ht:Nn \l_@@_internal_box
+ { \l_@@_top_corner_dim - \l_@@_bottom_corner_dim }
+ \box_set_dp:Nn \l_@@_internal_box { 0pt }
+ \box_set_wd:Nn \l_@@_internal_box
+ { \l_@@_right_corner_dim - \l_@@_left_corner_dim }
+ #5 #1 { \box_use_drop:N \l_@@_internal_box }
+% \end{macrocode}
+% The final task is to move the poles and corners such that they are
+% back in alignment with the box reference point.
+% \begin{macrocode}
+ \prop_map_inline:Nn \l_@@_corners_prop
+ { \@@_shift_corner:Nnnn #1 {##1} ##2 }
+ \prop_map_inline:Nn \l_@@_poles_prop
+ { \@@_shift_pole:Nnnnnn #1 {##1} ##2 }
+% \end{macrocode}
+% Update the coffin data.
+% \begin{macrocode}
+ #4 { coffin ~ \@@_to_value:N #1 ~ corners }
+ \l_@@_corners_prop
+ #4 { coffin ~ \@@_to_value:N #1 ~ poles }
+ \l_@@_poles_prop
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_set_bounding:N}
+% The bounding box corners for a coffin are easy enough to find: this
+% is the same code as for the corners of the material itself, but
+% using a dedicated property list.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_bounding:N #1
+ {
+ \prop_put:Nne \l_@@_bounding_prop { tl }
+ { { 0pt } { \dim_eval:n { \box_ht:N #1 } } }
+ \prop_put:Nne \l_@@_bounding_prop { tr }
+ {
+ { \dim_eval:n { \box_wd:N #1 } }
+ { \dim_eval:n { \box_ht:N #1 } }
+ }
+ \dim_set:Nn \l_@@_internal_dim { -\box_dp:N #1 }
+ \prop_put:Nne \l_@@_bounding_prop { bl }
+ { { 0pt } { \dim_use:N \l_@@_internal_dim } }
+ \prop_put:Nne \l_@@_bounding_prop { br }
+ {
+ { \dim_eval:n { \box_wd:N #1 } }
+ { \dim_use:N \l_@@_internal_dim }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_rotate_bounding:nnn}
+% \begin{macro}{\@@_rotate_corner:Nnnn}
+% Rotating the position of the corner of the coffin is just a case
+% of treating this as a vector from the reference point. The same
+% treatment is used for the corners of the material itself and the
+% bounding box.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_rotate_bounding:nnn #1#2#3
+ {
+ \@@_rotate_vector:nnNN {#2} {#3} \l_@@_x_dim \l_@@_y_dim
+ \prop_put:Nne \l_@@_bounding_prop {#1}
+ { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
+ }
+\cs_new_protected:Npn \@@_rotate_corner:Nnnn #1#2#3#4
+ {
+ \@@_rotate_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
+ \prop_put:Nne \l_@@_corners_prop {#2}
+ { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_rotate_pole:Nnnnnn}
+% Rotating a single pole simply means shifting the co-ordinate of
+% the pole and its direction. The rotation here is about the bottom-left
+% corner of the coffin.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_rotate_pole:Nnnnnn #1#2#3#4#5#6
+ {
+ \@@_rotate_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
+ \@@_rotate_vector:nnNN {#5} {#6}
+ \l_@@_x_prime_dim \l_@@_y_prime_dim
+ \prop_put:Nne \l_@@_poles_prop {#2}
+ {
+ { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim }
+ { \dim_use:N \l_@@_x_prime_dim }
+ { \dim_use:N \l_@@_y_prime_dim }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_rotate_vector:nnNN}
+% A rotation function, which needs only an input vector (as dimensions)
+% and an output space. The values \cs{l_@@_cos_fp} and
+% \cs{l_@@_sin_fp} should previously have been set up correctly.
+% Working this way means that the floating point work is kept to a
+% minimum: for any given rotation the sin and cosine values do no
+% change, after all.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_rotate_vector:nnNN #1#2#3#4
+ {
+ \dim_set:Nn #3
+ {
+ \fp_to_dim:n
+ {
+ \dim_to_fp:n {#1} * \l_@@_cos_fp
+ - \dim_to_fp:n {#2} * \l_@@_sin_fp
+ }
+ }
+ \dim_set:Nn #4
+ {
+ \fp_to_dim:n
+ {
+ \dim_to_fp:n {#1} * \l_@@_sin_fp
+ + \dim_to_fp:n {#2} * \l_@@_cos_fp
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_find_corner_maxima:N}
+% \begin{macro}{\@@_find_corner_maxima_aux:nn}
+% The idea here is to find the extremities of the content of the
+% coffin. This is done by looking for the smallest values for the bottom
+% and left corners, and the largest values for the top and right
+% corners. The values start at the maximum dimensions so that the
+% case where all are positive or all are negative works out correctly.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_find_corner_maxima:N #1
+ {
+ \dim_set:Nn \l_@@_top_corner_dim { -\c_max_dim }
+ \dim_set:Nn \l_@@_right_corner_dim { -\c_max_dim }
+ \dim_set:Nn \l_@@_bottom_corner_dim { \c_max_dim }
+ \dim_set:Nn \l_@@_left_corner_dim { \c_max_dim }
+ \prop_map_inline:Nn \l_@@_corners_prop
+ { \@@_find_corner_maxima_aux:nn ##2 }
+ }
+\cs_new_protected:Npn \@@_find_corner_maxima_aux:nn #1#2
+ {
+ \dim_set:Nn \l_@@_left_corner_dim
+ { \dim_min:nn { \l_@@_left_corner_dim } {#1} }
+ \dim_set:Nn \l_@@_right_corner_dim
+ { \dim_max:nn { \l_@@_right_corner_dim } {#1} }
+ \dim_set:Nn \l_@@_bottom_corner_dim
+ { \dim_min:nn { \l_@@_bottom_corner_dim } {#2} }
+ \dim_set:Nn \l_@@_top_corner_dim
+ { \dim_max:nn { \l_@@_top_corner_dim } {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_find_bounding_shift:}
+% \begin{macro}{\@@_find_bounding_shift_aux:nn}
+% The approach to finding the shift for the bounding box is similar to
+% that for the corners. However, there is only one value needed here and
+% a fixed input property list, so things are a bit clearer.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_find_bounding_shift:
+ {
+ \dim_set:Nn \l_@@_bounding_shift_dim { \c_max_dim }
+ \prop_map_inline:Nn \l_@@_bounding_prop
+ { \@@_find_bounding_shift_aux:nn ##2 }
+ }
+\cs_new_protected:Npn \@@_find_bounding_shift_aux:nn #1#2
+ {
+ \dim_set:Nn \l_@@_bounding_shift_dim
+ { \dim_min:nn { \l_@@_bounding_shift_dim } {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_shift_corner:Nnnn}
+% \begin{macro}{\@@_shift_pole:Nnnnnn}
+% Shifting the corners and poles of a coffin means subtracting the
+% appropriate values from the $x$- and $y$-components. For
+% the poles, this means that the direction vector is unchanged.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_shift_corner:Nnnn #1#2#3#4
+ {
+ \prop_put:Nne \l_@@_corners_prop {#2}
+ {
+ { \dim_eval:n { #3 - \l_@@_left_corner_dim } }
+ { \dim_eval:n { #4 - \l_@@_bottom_corner_dim } }
+ }
+ }
+\cs_new_protected:Npn \@@_shift_pole:Nnnnnn #1#2#3#4#5#6
+ {
+ \prop_put:Nne \l_@@_poles_prop {#2}
+ {
+ { \dim_eval:n { #3 - \l_@@_left_corner_dim } }
+ { \dim_eval:n { #4 - \l_@@_bottom_corner_dim } }
+ {#5} {#6}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_scale_x_fp}
+% \begin{variable}{\l_@@_scale_y_fp}
+% Storage for the scaling factors in $x$ and $y$, respectively.
+% \begin{macrocode}
+\fp_new:N \l_@@_scale_x_fp
+\fp_new:N \l_@@_scale_y_fp
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_scaled_total_height_dim}
+% \begin{variable}{\l_@@_scaled_width_dim}
+% When scaling, the values given have to be turned into absolute values.
+% \begin{macrocode}
+\dim_new:N \l_@@_scaled_total_height_dim
+\dim_new:N \l_@@_scaled_width_dim
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \coffin_resize:Nnn, \coffin_resize:cnn,
+% \coffin_gresize:Nnn, \coffin_gresize:cnn
+% }
+% \begin{macro}{\@@_resize:NnnNN}
+% Resizing a coffin begins by setting up the user-friendly names for
+% the dimensions of the coffin box. The new sizes are then turned into
+% scale factor. This is the same operation as takes place for the
+% underlying box, but that operation is grouped and so the same
+% calculation is done here.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_resize:Nnn #1#2#3
+ {
+ \@@_resize:NnnNN #1 {#2} {#3}
+ \box_resize_to_wd_and_ht_plus_dp:Nnn
+ \prop_set_eq:cN
+ }
+\cs_generate_variant:Nn \coffin_resize:Nnn { c }
+\cs_new_protected:Npn \coffin_gresize:Nnn #1#2#3
+ {
+ \@@_resize:NnnNN #1 {#2} {#3}
+ \box_gresize_to_wd_and_ht_plus_dp:Nnn
+ \prop_gset_eq:cN
+ }
+\cs_generate_variant:Nn \coffin_gresize:Nnn { c }
+\cs_new_protected:Npn \@@_resize:NnnNN #1#2#3#4#5
+ {
+ \fp_set:Nn \l_@@_scale_x_fp
+ { \dim_to_fp:n {#2} / \dim_to_fp:n { \coffin_wd:N #1 } }
+ \fp_set:Nn \l_@@_scale_y_fp
+ {
+ \dim_to_fp:n {#3}
+ / \dim_to_fp:n { \coffin_ht:N #1 + \coffin_dp:N #1 }
+ }
+ #4 #1 {#2} {#3}
+ \@@_resize_common:NnnN #1 {#2} {#3} #5
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_resize_common:NnnN}
+% The poles and corners of the coffin are scaled to the appropriate
+% places before actually resizing the underlying box.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_resize_common:NnnN #1#2#3#4
+ {
+ \prop_set_eq:Nc \l_@@_corners_prop
+ { coffin ~ \@@_to_value:N #1 ~ corners }
+ \prop_set_eq:Nc \l_@@_poles_prop
+ { coffin ~ \@@_to_value:N #1 ~ poles }
+ \prop_map_inline:Nn \l_@@_corners_prop
+ { \@@_scale_corner:Nnnn #1 {##1} ##2 }
+ \prop_map_inline:Nn \l_@@_poles_prop
+ { \@@_scale_pole:Nnnnnn #1 {##1} ##2 }
+% \end{macrocode}
+% Negative $x$-scaling values place the poles in the wrong
+% location: this is corrected here.
+% \begin{macrocode}
+ \fp_compare:nNnT \l_@@_scale_x_fp < \c_zero_fp
+ {
+ \prop_map_inline:Nn \l_@@_corners_prop
+ { \@@_x_shift_corner:Nnnn #1 {##1} ##2 }
+ \prop_map_inline:Nn \l_@@_poles_prop
+ { \@@_x_shift_pole:Nnnnnn #1 {##1} ##2 }
+ }
+ #4 { coffin ~ \@@_to_value:N #1 ~ corners }
+ \l_@@_corners_prop
+ #4 { coffin ~ \@@_to_value:N #1 ~ poles }
+ \l_@@_poles_prop
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \coffin_scale:Nnn, \coffin_scale:cnn,
+% \coffin_gscale:Nnn, \coffin_gscale:cnn
+% }
+% \begin{macro}{\@@_scale:NnnNN}
+% For scaling, the opposite calculation is done to find the new
+% dimensions for the coffin. Only the total height is needed, as this
+% is the shift required for corners and poles. The scaling is done
+% the \TeX{} way as this works properly with floating point values
+% without needing to use the \texttt{fp} module.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_scale:Nnn #1#2#3
+ { \@@_scale:NnnNN #1 {#2} {#3} \box_scale:Nnn \prop_set_eq:cN }
+\cs_generate_variant:Nn \coffin_scale:Nnn { c }
+\cs_new_protected:Npn \coffin_gscale:Nnn #1#2#3
+ { \@@_scale:NnnNN #1 {#2} {#3} \box_gscale:Nnn \prop_gset_eq:cN }
+\cs_generate_variant:Nn \coffin_gscale:Nnn { c }
+\cs_new_protected:Npn \@@_scale:NnnNN #1#2#3#4#5
+ {
+ \fp_set:Nn \l_@@_scale_x_fp {#2}
+ \fp_set:Nn \l_@@_scale_y_fp {#3}
+ #4 #1 { \l_@@_scale_x_fp } { \l_@@_scale_y_fp }
+ \dim_set:Nn \l_@@_internal_dim
+ { \coffin_ht:N #1 + \coffin_dp:N #1 }
+ \dim_set:Nn \l_@@_scaled_total_height_dim
+ { \fp_abs:n { \l_@@_scale_y_fp } \l_@@_internal_dim }
+ \dim_set:Nn \l_@@_scaled_width_dim
+ { -\fp_abs:n { \l_@@_scale_x_fp } \coffin_wd:N #1 }
+ \@@_resize_common:NnnN #1
+ { \l_@@_scaled_width_dim } { \l_@@_scaled_total_height_dim }
+ #5
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_scale_vector:nnNN}
+% This functions scales a vector from the origin using the pre-set scale
+% factors in $x$ and $y$. This is a much less complex operation
+% than rotation, and as a result the code is a lot clearer.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scale_vector:nnNN #1#2#3#4
+ {
+ \dim_set:Nn #3
+ { \fp_to_dim:n { \dim_to_fp:n {#1} * \l_@@_scale_x_fp } }
+ \dim_set:Nn #4
+ { \fp_to_dim:n { \dim_to_fp:n {#2} * \l_@@_scale_y_fp } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_scale_corner:Nnnn}
+% \begin{macro}{\@@_scale_pole:Nnnnnn}
+% Scaling both corners and poles is a simple calculation using the
+% preceding vector scaling.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scale_corner:Nnnn #1#2#3#4
+ {
+ \@@_scale_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
+ \prop_put:Nne \l_@@_corners_prop {#2}
+ { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
+ }
+\cs_new_protected:Npn \@@_scale_pole:Nnnnnn #1#2#3#4#5#6
+ {
+ \@@_scale_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
+ \prop_put:Nne \l_@@_poles_prop {#2}
+ {
+ { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim }
+ {#5} {#6}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_x_shift_corner:Nnnn}
+% \begin{macro}{\@@_x_shift_pole:Nnnnnn}
+% These functions correct for the $x$ displacement that takes
+% place with a negative horizontal scaling.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_x_shift_corner:Nnnn #1#2#3#4
+ {
+ \prop_put:Nne \l_@@_corners_prop {#2}
+ {
+ { \dim_eval:n { #3 + \box_wd:N #1 } } {#4}
+ }
+ }
+\cs_new_protected:Npn \@@_x_shift_pole:Nnnnnn #1#2#3#4#5#6
+ {
+ \prop_put:Nne \l_@@_poles_prop {#2}
+ {
+ { \dim_eval:n { #3 + \box_wd:N #1 } } {#4}
+ {#5} {#6}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Aligning and typesetting of coffins}
+%
+% \begin{macro}
+% {
+% \coffin_join:NnnNnnnn, \coffin_join:cnnNnnnn,
+% \coffin_join:Nnncnnnn, \coffin_join:cnncnnnn,
+% \coffin_gjoin:NnnNnnnn, \coffin_gjoin:cnnNnnnn,
+% \coffin_gjoin:Nnncnnnn, \coffin_gjoin:cnncnnnn
+% }
+% \begin{macro}{\@@_join:NnnNnnnnN}
+% This command joins two coffins, using a horizontal and vertical pole
+% from each coffin and making an offset between the two. The result
+% is stored as the as a third coffin, which has all of its handles
+% reset to standard values. First, the more basic alignment function is
+% used to get things started.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_join:NnnNnnnn #1#2#3#4#5#6#7#8
+ {
+ \@@_join:NnnNnnnnN #1 {#2} {#3} #4 {#5} {#6} {#7} {#8}
+ \coffin_set_eq:NN
+ }
+\cs_generate_variant:Nn \coffin_join:NnnNnnnn { c , Nnnc , cnnc }
+\cs_new_protected:Npn \coffin_gjoin:NnnNnnnn #1#2#3#4#5#6#7#8
+ {
+ \@@_join:NnnNnnnnN #1 {#2} {#3} #4 {#5} {#6} {#7} {#8}
+ \coffin_gset_eq:NN
+ }
+\cs_generate_variant:Nn \coffin_gjoin:NnnNnnnn { c , Nnnc , cnnc }
+\cs_new_protected:Npn \@@_join:NnnNnnnnN #1#2#3#4#5#6#7#8#9
+ {
+ \@@_align:NnnNnnnnN
+ #1 {#2} {#3} #4 {#5} {#6} {#7} {#8} \l_@@_aligned_coffin
+% \end{macrocode}
+% Correct the placement of the reference point. If the $x$-offset
+% is negative then the reference point of the second box is to the left
+% of that of the first, which is corrected using a kern. On the right
+% side the first box might stick out, which would show up if it is wider
+% than the sum of the $x$-offset and the width of the second box.
+% So a second kern may be needed.
+% \begin{macrocode}
+ \hbox_set:Nn \l_@@_aligned_coffin
+ {
+ \dim_compare:nNnT { \l_@@_offset_x_dim } < \c_zero_dim
+ { \__kernel_kern:n { -\l_@@_offset_x_dim } }
+ \hbox_unpack:N \l_@@_aligned_coffin
+ \dim_set:Nn \l_@@_internal_dim
+ { \l_@@_offset_x_dim - \box_wd:N #1 + \box_wd:N #4 }
+ \dim_compare:nNnT \l_@@_internal_dim < \c_zero_dim
+ { \__kernel_kern:n { -\l_@@_internal_dim } }
+ }
+% \end{macrocode}
+% The coffin structure is reset, and the corners are cleared: only
+% those from the two parent coffins are needed.
+% \begin{macrocode}
+ \@@_reset_structure:N \l_@@_aligned_coffin
+ \prop_clear:c
+ {
+ coffin ~ \@@_to_value:N \l_@@_aligned_coffin
+ \c_space_tl corners
+ }
+ \@@_update_poles:N \l_@@_aligned_coffin
+% \end{macrocode}
+% The structures of the parent coffins are now transferred to the new
+% coffin, which requires that the appropriate offsets are applied. That
+% then depends on whether any shift was needed.
+% \begin{macrocode}
+ \dim_compare:nNnTF \l_@@_offset_x_dim < \c_zero_dim
+ {
+ \@@_offset_poles:Nnn #1 { -\l_@@_offset_x_dim } { 0pt }
+ \@@_offset_poles:Nnn #4 { 0pt } { \l_@@_offset_y_dim }
+ \@@_offset_corners:Nnn #1 { -\l_@@_offset_x_dim } { 0pt }
+ \@@_offset_corners:Nnn #4 { 0pt } { \l_@@_offset_y_dim }
+ }
+ {
+ \@@_offset_poles:Nnn #1 { 0pt } { 0pt }
+ \@@_offset_poles:Nnn #4
+ { \l_@@_offset_x_dim } { \l_@@_offset_y_dim }
+ \@@_offset_corners:Nnn #1 { 0pt } { 0pt }
+ \@@_offset_corners:Nnn #4
+ { \l_@@_offset_x_dim } { \l_@@_offset_y_dim }
+ }
+ \@@_update_vertical_poles:NNN #1 #4 \l_@@_aligned_coffin
+ #9 #1 \l_@@_aligned_coffin
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \coffin_attach:NnnNnnnn, \coffin_attach:cnnNnnnn,
+% \coffin_attach:Nnncnnnn, \coffin_attach:cnncnnnn,
+% \coffin_gattach:NnnNnnnn, \coffin_gattach:cnnNnnnn,
+% \coffin_gattach:Nnncnnnn, \coffin_gattach:cnncnnnn
+% }
+% \begin{macro}{\@@_attach:NnnNnnnnN}
+% \begin{macro}{\@@_attach_mark:NnnNnnnn}
+% A more simple version of the above, as it simply uses the size of the
+% first coffin for the new one. This means that the work here is rather
+% simplified compared to the above code. The function used when marking
+% a position is hear also as it is similar but without the structure
+% updates.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_attach:NnnNnnnn #1#2#3#4#5#6#7#8
+ {
+ \@@_attach:NnnNnnnnN #1 {#2} {#3} #4 {#5} {#6} {#7} {#8}
+ \coffin_set_eq:NN
+ }
+\cs_generate_variant:Nn \coffin_attach:NnnNnnnn { c , Nnnc , cnnc }
+\cs_new_protected:Npn \coffin_gattach:NnnNnnnn #1#2#3#4#5#6#7#8
+ {
+ \@@_attach:NnnNnnnnN #1 {#2} {#3} #4 {#5} {#6} {#7} {#8}
+ \coffin_gset_eq:NN
+ }
+\cs_generate_variant:Nn \coffin_gattach:NnnNnnnn { c , Nnnc , cnnc }
+\cs_new_protected:Npn \@@_attach:NnnNnnnnN #1#2#3#4#5#6#7#8#9
+ {
+ \@@_align:NnnNnnnnN
+ #1 {#2} {#3} #4 {#5} {#6} {#7} {#8} \l_@@_aligned_coffin
+ \box_set_ht:Nn \l_@@_aligned_coffin { \box_ht:N #1 }
+ \box_set_dp:Nn \l_@@_aligned_coffin { \box_dp:N #1 }
+ \box_set_wd:Nn \l_@@_aligned_coffin { \box_wd:N #1 }
+ \@@_reset_structure:N \l_@@_aligned_coffin
+ \prop_set_eq:cc
+ {
+ coffin ~ \@@_to_value:N \l_@@_aligned_coffin
+ \c_space_tl corners
+ }
+ { coffin ~ \@@_to_value:N #1 ~ corners }
+ \@@_update_poles:N \l_@@_aligned_coffin
+ \@@_offset_poles:Nnn #1 { 0pt } { 0pt }
+ \@@_offset_poles:Nnn #4
+ { \l_@@_offset_x_dim } { \l_@@_offset_y_dim }
+ \@@_update_vertical_poles:NNN #1 #4 \l_@@_aligned_coffin
+ #9 #1 \l_@@_aligned_coffin
+ }
+\cs_new_protected:Npn \@@_attach_mark:NnnNnnnn #1#2#3#4#5#6#7#8
+ {
+ \@@_align:NnnNnnnnN
+ #1 {#2} {#3} #4 {#5} {#6} {#7} {#8} \l_@@_aligned_coffin
+ \box_set_ht:Nn \l_@@_aligned_coffin { \box_ht:N #1 }
+ \box_set_dp:Nn \l_@@_aligned_coffin { \box_dp:N #1 }
+ \box_set_wd:Nn \l_@@_aligned_coffin { \box_wd:N #1 }
+ \box_set_eq:NN #1 \l_@@_aligned_coffin
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_align:NnnNnnnnN}
+% The internal function aligns the two coffins into a third one, but
+% performs no corrections on the resulting coffin poles. The process
+% begins by finding the points of intersection for the poles for each
+% of the input coffins. Those for the first coffin are worked out after
+% those for the second coffin, as this allows the `primed'
+% storage area to be used for the second coffin. The `real' box
+% offsets are then calculated, before using these to re-box the
+% input coffins. The default poles are then set up, but the final result
+% depends on how the bounding box is being handled.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_align:NnnNnnnnN #1#2#3#4#5#6#7#8#9
+ {
+ \@@_calculate_intersection:Nnn #4 {#5} {#6}
+ \dim_set:Nn \l_@@_x_prime_dim { \l_@@_x_dim }
+ \dim_set:Nn \l_@@_y_prime_dim { \l_@@_y_dim }
+ \@@_calculate_intersection:Nnn #1 {#2} {#3}
+ \dim_set:Nn \l_@@_offset_x_dim
+ { \l_@@_x_dim - \l_@@_x_prime_dim + #7 }
+ \dim_set:Nn \l_@@_offset_y_dim
+ { \l_@@_y_dim - \l_@@_y_prime_dim + #8 }
+ \hbox_set:Nn \l_@@_aligned_internal_coffin
+ {
+ \box_use:N #1
+ \__kernel_kern:n { -\box_wd:N #1 }
+ \__kernel_kern:n { \l_@@_offset_x_dim }
+ \box_move_up:nn { \l_@@_offset_y_dim } { \box_use:N #4 }
+ }
+ \coffin_set_eq:NN #9 \l_@@_aligned_internal_coffin
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_offset_poles:Nnn}
+% \begin{macro}{\@@_offset_pole:Nnnnnnn}
+% Transferring structures from one coffin to another requires that the
+% positions are updated by the offset between the two coffins. This is
+% done by mapping over the property list of the source coffins, moving
+% as appropriate and saving to the new coffin data structures. The
+% test for a |-| means that the structures from the parent coffins
+% are uniquely labelled and do not depend on the order of alignment.
+% The pay off for this is that |-| should not be used in coffin pole
+% or handle names, and that multiple alignments do not result in a
+% whole set of values.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_offset_poles:Nnn #1#2#3
+ {
+ \prop_map_inline:cn { coffin ~ \@@_to_value:N #1 ~ poles }
+ { \@@_offset_pole:Nnnnnnn #1 {##1} ##2 {#2} {#3} }
+ }
+\cs_new_protected:Npn \@@_offset_pole:Nnnnnnn #1#2#3#4#5#6#7#8
+ {
+ \dim_set:Nn \l_@@_x_dim { #3 + #7 }
+ \dim_set:Nn \l_@@_y_dim { #4 + #8 }
+ \tl_if_in:nnTF {#2} { - }
+ { \tl_set:Nn \l_@@_internal_tl { {#2} } }
+ { \tl_set:Nn \l_@@_internal_tl { { #1 - #2 } } }
+ \exp_last_unbraced:NNo \@@_set_pole:Nnn \l_@@_aligned_coffin
+ { \l_@@_internal_tl }
+ {
+ { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim }
+ {#5} {#6}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_offset_corners:Nnn}
+% \begin{macro}{\@@_offset_corner:Nnnnn}
+% Saving the offset corners of a coffin is very similar, except that
+% there is no need to worry about naming: every corner can be saved
+% here as order is unimportant.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_offset_corners:Nnn #1#2#3
+ {
+ \prop_map_inline:cn { coffin ~ \@@_to_value:N #1 ~ corners }
+ { \@@_offset_corner:Nnnnn #1 {##1} ##2 {#2} {#3} }
+ }
+\cs_new_protected:Npn \@@_offset_corner:Nnnnn #1#2#3#4#5#6
+ {
+ \prop_put:cne
+ {
+ coffin ~ \@@_to_value:N \l_@@_aligned_coffin
+ \c_space_tl corners
+ }
+ { #1 - #2 }
+ {
+ { \dim_eval:n { #3 + #5 } }
+ { \dim_eval:n { #4 + #6 } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_update_vertical_poles:NNN}
+% \begin{macro}{\@@_update_T:nnnnnnnnN}
+% \begin{macro}{\@@_update_B:nnnnnnnnN}
+% The \texttt{T} and \texttt{B} poles need to be recalculated
+% after alignment. These functions find the larger absolute value for
+% the poles, but this is of course only logical when the poles are
+% horizontal.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_update_vertical_poles:NNN #1#2#3
+ {
+ \@@_get_pole:NnN #3 { #1 -T } \l_@@_pole_a_tl
+ \@@_get_pole:NnN #3 { #2 -T } \l_@@_pole_b_tl
+ \exp_last_two_unbraced:Noo \@@_update_T:nnnnnnnnN
+ \l_@@_pole_a_tl \l_@@_pole_b_tl #3
+ \@@_get_pole:NnN #3 { #1 -B } \l_@@_pole_a_tl
+ \@@_get_pole:NnN #3 { #2 -B } \l_@@_pole_b_tl
+ \exp_last_two_unbraced:Noo \@@_update_B:nnnnnnnnN
+ \l_@@_pole_a_tl \l_@@_pole_b_tl #3
+ }
+\cs_new_protected:Npn \@@_update_T:nnnnnnnnN #1#2#3#4#5#6#7#8#9
+ {
+ \dim_compare:nNnTF {#2} < {#6}
+ {
+ \@@_set_pole:Nnn #9 { T }
+ { { 0pt } {#6} { 1000pt } { 0pt } }
+ }
+ {
+ \@@_set_pole:Nnn #9 { T }
+ { { 0pt } {#2} { 1000pt } { 0pt } }
+ }
+ }
+\cs_new_protected:Npn \@@_update_B:nnnnnnnnN #1#2#3#4#5#6#7#8#9
+ {
+ \dim_compare:nNnTF {#2} < {#6}
+ {
+ \@@_set_pole:Nnn #9 { B }
+ { { 0pt } {#2} { 1000pt } { 0pt } }
+ }
+ {
+ \@@_set_pole:Nnn #9 { B }
+ { { 0pt } {#6} { 1000pt } { 0pt } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\c_@@_empty_coffin}
+% An empty-but-horizontal coffin.
+% \begin{macrocode}
+\coffin_new:N \c_@@_empty_coffin
+\tex_setbox:D \c_@@_empty_coffin = \tex_hbox:D { }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\coffin_typeset:Nnnnn, \coffin_typeset:cnnnn}
+% Typesetting a coffin means aligning it with the current position,
+% which is done using a coffin with no content at all. As well as aligning to
+% the empty coffin, there is also a need to leave vertical mode, if necessary.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_typeset:Nnnnn #1#2#3#4#5
+ {
+ \mode_leave_vertical:
+ \@@_align:NnnNnnnnN \c_@@_empty_coffin { H } { l }
+ #1 {#2} {#3} {#4} {#5} \l_@@_aligned_coffin
+ \box_use_drop:N \l_@@_aligned_coffin
+ }
+\cs_generate_variant:Nn \coffin_typeset:Nnnnn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Coffin diagnostics}
+%
+% \begin{variable}{\l_@@_display_coffin}
+% \begin{variable}{\l_@@_display_coord_coffin}
+% \begin{variable}{\l_@@_display_pole_coffin}
+% Used for printing coffins with data structures attached.
+% \begin{macrocode}
+\coffin_new:N \l_@@_display_coffin
+\coffin_new:N \l_@@_display_coord_coffin
+\coffin_new:N \l_@@_display_pole_coffin
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_display_handles_prop}
+% This property list is used to print coffin handles at suitable
+% positions. The offsets are expressed as multiples of the basic offset
+% value, which therefore acts as a scale-factor.
+% \begin{macrocode}
+\prop_new:N \l_@@_display_handles_prop
+\prop_put:Nnn \l_@@_display_handles_prop { tl }
+ { { b } { r } { -1 } { 1 } }
+\prop_put:Nnn \l_@@_display_handles_prop { thc }
+ { { b } { hc } { 0 } { 1 } }
+\prop_put:Nnn \l_@@_display_handles_prop { tr }
+ { { b } { l } { 1 } { 1 } }
+\prop_put:Nnn \l_@@_display_handles_prop { vcl }
+ { { vc } { r } { -1 } { 0 } }
+\prop_put:Nnn \l_@@_display_handles_prop { vchc }
+ { { vc } { hc } { 0 } { 0 } }
+\prop_put:Nnn \l_@@_display_handles_prop { vcr }
+ { { vc } { l } { 1 } { 0 } }
+\prop_put:Nnn \l_@@_display_handles_prop { bl }
+ { { t } { r } { -1 } { -1 } }
+\prop_put:Nnn \l_@@_display_handles_prop { bhc }
+ { { t } { hc } { 0 } { -1 } }
+\prop_put:Nnn \l_@@_display_handles_prop { br }
+ { { t } { l } { 1 } { -1 } }
+\prop_put:Nnn \l_@@_display_handles_prop { Tl }
+ { { t } { r } { -1 } { -1 } }
+\prop_put:Nnn \l_@@_display_handles_prop { Thc }
+ { { t } { hc } { 0 } { -1 } }
+\prop_put:Nnn \l_@@_display_handles_prop { Tr }
+ { { t } { l } { 1 } { -1 } }
+\prop_put:Nnn \l_@@_display_handles_prop { Hl }
+ { { vc } { r } { -1 } { 1 } }
+\prop_put:Nnn \l_@@_display_handles_prop { Hhc }
+ { { vc } { hc } { 0 } { 1 } }
+\prop_put:Nnn \l_@@_display_handles_prop { Hr }
+ { { vc } { l } { 1 } { 1 } }
+\prop_put:Nnn \l_@@_display_handles_prop { Bl }
+ { { b } { r } { -1 } { -1 } }
+\prop_put:Nnn \l_@@_display_handles_prop { Bhc }
+ { { b } { hc } { 0 } { -1 } }
+\prop_put:Nnn \l_@@_display_handles_prop { Br }
+ { { b } { l } { 1 } { -1 } }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_display_offset_dim}
+% The standard offset for the label from the handle position when
+% displaying handles.
+% \begin{macrocode}
+\dim_new:N \l_@@_display_offset_dim
+\dim_set:Nn \l_@@_display_offset_dim { 2pt }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_display_x_dim}
+% \begin{variable}{\l_@@_display_y_dim}
+% As the intersections of poles have to be calculated to find which
+% ones to print, there is a need to avoid repetition. This is done
+% by saving the intersection into two dedicated values.
+% \begin{macrocode}
+\dim_new:N \l_@@_display_x_dim
+\dim_new:N \l_@@_display_y_dim
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_display_poles_prop}
+% A property list for printing poles: various things need to be deleted
+% from this to get a \enquote{nice} output.
+% \begin{macrocode}
+\prop_new:N \l_@@_display_poles_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_display_font_tl}
+% Stores the settings used to print coffin data: this keeps things
+% flexible.
+% \begin{macrocode}
+\tl_new:N \l_@@_display_font_tl
+\bool_lazy_and:nnT
+ { \cs_if_exist_p:N \fmtname }
+ { \str_if_eq_p:Vn \fmtname { LaTeX2e } }
+ {
+ \tl_set:Nn \l_@@_display_font_tl
+ { \sffamily \tiny }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_rule:nn}
+% Abstract out creation of rules here until there is a higher-level interface.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_rule:nn #1#2
+ {
+ \mode_leave_vertical:
+ \hbox:n { \tex_vrule:D width #1 height #2 \scan_stop: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\coffin_mark_handle:Nnnn, \coffin_mark_handle:cnnn}
+% \begin{macro}{\@@_mark_handle_aux:nnnnNnn}
+% Marking a single handle is relatively easy. The standard attachment
+% function is used, meaning that there are two calculations for the
+% location. However, this is likely to be okay given the load expected.
+% Contrast with the more optimised version for showing all handles which
+% comes next.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_mark_handle:Nnnn #1#2#3#4
+ {
+ \hcoffin_set:Nn \l_@@_display_pole_coffin
+ {
+ \color_select:n {#4}
+ \@@_rule:nn { 1pt } { 1pt }
+ }
+ \@@_attach_mark:NnnNnnnn #1 {#2} {#3}
+ \l_@@_display_pole_coffin { hc } { vc } { 0pt } { 0pt }
+ \hcoffin_set:Nn \l_@@_display_coord_coffin
+ {
+ \color_select:n {#4}
+ \l_@@_display_font_tl
+ ( \tl_to_str:n { #2 , #3 } )
+ }
+ \prop_get:NnN \l_@@_display_handles_prop
+ { #2 #3 } \l_@@_internal_tl
+ \quark_if_no_value:NTF \l_@@_internal_tl
+ {
+ \prop_get:NnN \l_@@_display_handles_prop
+ { #3 #2 } \l_@@_internal_tl
+ \quark_if_no_value:NTF \l_@@_internal_tl
+ {
+ \@@_attach_mark:NnnNnnnn #1 {#2} {#3}
+ \l_@@_display_coord_coffin { l } { vc }
+ { 1pt } { 0pt }
+ }
+ {
+ \exp_last_unbraced:No \@@_mark_handle_aux:nnnnNnn
+ \l_@@_internal_tl #1 {#2} {#3}
+ }
+ }
+ {
+ \exp_last_unbraced:No \@@_mark_handle_aux:nnnnNnn
+ \l_@@_internal_tl #1 {#2} {#3}
+ }
+ }
+\cs_new_protected:Npn \@@_mark_handle_aux:nnnnNnn #1#2#3#4#5#6#7
+ {
+ \@@_attach_mark:NnnNnnnn #5 {#6} {#7}
+ \l_@@_display_coord_coffin {#1} {#2}
+ { #3 \l_@@_display_offset_dim }
+ { #4 \l_@@_display_offset_dim }
+ }
+\cs_generate_variant:Nn \coffin_mark_handle:Nnnn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\coffin_display_handles:Nn, \coffin_display_handles:cn}
+% \begin{macro}{\@@_display_handles_aux:nnnnnn}
+% \begin{macro}{\@@_display_handles_aux:nnnn}
+% \begin{macro}{\@@_display_attach:Nnnnn}
+% Printing the poles starts by removing any duplicates, for which the
+% \texttt{H} poles is used as the definitive version for the baseline
+% and bottom. Two loops are then used to find the combinations of
+% handles for all of these poles. This is done such that poles are
+% removed during the loops to avoid duplication.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_display_handles:Nn #1#2
+ {
+ \hcoffin_set:Nn \l_@@_display_pole_coffin
+ {
+ \color_select:n {#2}
+ \@@_rule:nn { 1pt } { 1pt }
+ }
+ \prop_set_eq:Nc \l_@@_display_poles_prop
+ { coffin ~ \@@_to_value:N #1 ~ poles }
+ \@@_get_pole:NnN #1 { H } \l_@@_pole_a_tl
+ \@@_get_pole:NnN #1 { T } \l_@@_pole_b_tl
+ \tl_if_eq:NNT \l_@@_pole_a_tl \l_@@_pole_b_tl
+ { \prop_remove:Nn \l_@@_display_poles_prop { T } }
+ \@@_get_pole:NnN #1 { B } \l_@@_pole_b_tl
+ \tl_if_eq:NNT \l_@@_pole_a_tl \l_@@_pole_b_tl
+ { \prop_remove:Nn \l_@@_display_poles_prop { B } }
+ \coffin_set_eq:NN \l_@@_display_coffin #1
+ \prop_map_inline:Nn \l_@@_display_poles_prop
+ {
+ \prop_remove:Nn \l_@@_display_poles_prop {##1}
+ \@@_display_handles_aux:nnnnnn {##1} ##2 {#2}
+ }
+ \box_use_drop:N \l_@@_display_coffin
+ }
+% \end{macrocode}
+% For each pole there is a check for an intersection, which here does
+% not give an error if none is found. The successful values are stored
+% and used to align the pole coffin with the main coffin for output.
+% The positions are recovered from the preset list if available.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_display_handles_aux:nnnnnn #1#2#3#4#5#6
+ {
+ \prop_map_inline:Nn \l_@@_display_poles_prop
+ {
+ \bool_set_false:N \l_@@_error_bool
+ \@@_calculate_intersection:nnnnnnnn {#2} {#3} {#4} {#5} ##2
+ \bool_if:NF \l_@@_error_bool
+ {
+ \dim_set:Nn \l_@@_display_x_dim { \l_@@_x_dim }
+ \dim_set:Nn \l_@@_display_y_dim { \l_@@_y_dim }
+ \@@_display_attach:Nnnnn
+ \l_@@_display_pole_coffin { hc } { vc }
+ { 0pt } { 0pt }
+ \hcoffin_set:Nn \l_@@_display_coord_coffin
+ {
+ \color_select:n {#6}
+ \l_@@_display_font_tl
+ ( \tl_to_str:n { #1 , ##1 } )
+ }
+ \prop_get:NnN \l_@@_display_handles_prop
+ { #1 ##1 } \l_@@_internal_tl
+ \quark_if_no_value:NTF \l_@@_internal_tl
+ {
+ \prop_get:NnN \l_@@_display_handles_prop
+ { ##1 #1 } \l_@@_internal_tl
+ \quark_if_no_value:NTF \l_@@_internal_tl
+ {
+ \@@_display_attach:Nnnnn
+ \l_@@_display_coord_coffin { l } { vc }
+ { 1pt } { 0pt }
+ }
+ {
+ \exp_last_unbraced:No
+ \@@_display_handles_aux:nnnn
+ \l_@@_internal_tl
+ }
+ }
+ {
+ \exp_last_unbraced:No \@@_display_handles_aux:nnnn
+ \l_@@_internal_tl
+ }
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_display_handles_aux:nnnn #1#2#3#4
+ {
+ \@@_display_attach:Nnnnn
+ \l_@@_display_coord_coffin {#1} {#2}
+ { #3 \l_@@_display_offset_dim }
+ { #4 \l_@@_display_offset_dim }
+ }
+\cs_generate_variant:Nn \coffin_display_handles:Nn { c }
+% \end{macrocode}
+% This is a dedicated version of \cs{coffin_attach:NnnNnnnn} with
+% a hard-wired first coffin. As the intersection is already known
+% and stored for the display coffin the code simply uses it directly,
+% with no calculation.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_display_attach:Nnnnn #1#2#3#4#5
+ {
+ \@@_calculate_intersection:Nnn #1 {#2} {#3}
+ \dim_set:Nn \l_@@_x_prime_dim { \l_@@_x_dim }
+ \dim_set:Nn \l_@@_y_prime_dim { \l_@@_y_dim }
+ \dim_set:Nn \l_@@_offset_x_dim
+ { \l_@@_display_x_dim - \l_@@_x_prime_dim + #4 }
+ \dim_set:Nn \l_@@_offset_y_dim
+ { \l_@@_display_y_dim - \l_@@_y_prime_dim + #5 }
+ \hbox_set:Nn \l_@@_aligned_coffin
+ {
+ \box_use:N \l_@@_display_coffin
+ \__kernel_kern:n { -\box_wd:N \l_@@_display_coffin }
+ \__kernel_kern:n { \l_@@_offset_x_dim }
+ \box_move_up:nn { \l_@@_offset_y_dim } { \box_use:N #1 }
+ }
+ \box_set_ht:Nn \l_@@_aligned_coffin
+ { \box_ht:N \l_@@_display_coffin }
+ \box_set_dp:Nn \l_@@_aligned_coffin
+ { \box_dp:N \l_@@_display_coffin }
+ \box_set_wd:Nn \l_@@_aligned_coffin
+ { \box_wd:N \l_@@_display_coffin }
+ \box_set_eq:NN \l_@@_display_coffin \l_@@_aligned_coffin
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \coffin_show_structure:N, \coffin_show_structure:c,
+% \coffin_log_structure:N, \coffin_log_structure:c,
+% \@@_show_structure:NN
+% }
+% For showing the various internal structures attached to a coffin in
+% a way that keeps things relatively readable. If there is no apparent
+% structure then the code complains.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_show_structure:N
+ { \@@_show_structure:NN \msg_show:nneeee }
+\cs_generate_variant:Nn \coffin_show_structure:N { c }
+\cs_new_protected:Npn \coffin_log_structure:N
+ { \@@_show_structure:NN \msg_log:nneeee }
+\cs_generate_variant:Nn \coffin_log_structure:N { c }
+\cs_new_protected:Npn \@@_show_structure:NN #1#2
+ {
+ \@@_if_exist:NT #2
+ {
+ #1 { coffin } { show }
+ { \token_to_str:N #2 }
+ {
+ \iow_newline: >~ ht ~=~ \dim_eval:n { \coffin_ht:N #2 }
+ \iow_newline: >~ dp ~=~ \dim_eval:n { \coffin_dp:N #2 }
+ \iow_newline: >~ wd ~=~ \dim_eval:n { \coffin_wd:N #2 }
+ }
+ {
+ \prop_map_function:cN
+ { coffin ~ \@@_to_value:N #2 ~ poles }
+ \msg_show_item_unbraced:nn
+ }
+ { }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \coffin_show:N, \coffin_show:c, \coffin_log:N, \coffin_log:c,
+% \coffin_show:Nnn, \coffin_show:cnn, \coffin_log:Nnn, \coffin_log:cnn,
+% \@@_show:NNNnn
+% }
+% Essentially a combination of \cs{coffin_show_structure:N} and
+% \cs{box_show:Nnn}, but we need to avoid having two prompts, so we
+% use \cs{msg_term:nneeee} instead of
+% \cs{msg_show:nneeee} in the |show| case.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_show:N #1
+ { \coffin_show:Nnn #1 \c_max_int \c_max_int }
+\cs_generate_variant:Nn \coffin_show:N { c }
+\cs_new_protected:Npn \coffin_log:N #1
+ { \coffin_log:Nnn #1 \c_max_int \c_max_int }
+\cs_generate_variant:Nn \coffin_log:N { c }
+\cs_new_protected:Npn \coffin_show:Nnn
+ { \@@_show:NNNnn \msg_term:nneeee \box_show:Nnn }
+\cs_generate_variant:Nn \coffin_show:Nnn { c }
+\cs_new_protected:Npn \coffin_log:Nnn
+ { \@@_show:NNNnn \msg_log:nneeee \box_show:Nnn }
+\cs_generate_variant:Nn \coffin_log:Nnn { c }
+\cs_new_protected:Npn \@@_show:NNNnn #1#2#3#4#5
+ {
+ \@@_if_exist:NT #3
+ {
+ \@@_show_structure:NN #1 #3
+ #2 #3 {#4} {#5}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% \begin{macrocode}
+\msg_new:nnnn { coffin } { no-pole-intersection }
+ { No~intersection~between~coffin~poles. }
+ {
+ LaTeX~was~asked~to~find~the~intersection~between~two~poles,~
+ but~they~do~not~have~a~unique~meeting~point:~
+ the~value~(0pt,~0pt)~will~be~used.
+ }
+\msg_new:nnnn { coffin } { unknown }
+ { Unknown~coffin~'#1'. }
+ { The~coffin~'#1'~was~never~defined. }
+\msg_new:nnnn { coffin } { unknown-pole }
+ { Pole~'#1'~unknown~for~coffin~'#2'. }
+ {
+ LaTeX~was~asked~to~find~a~typesetting~pole~for~a~coffin,~
+ but~either~the~coffin~does~not~exist~or~the~pole~name~is~wrong.
+ }
+\msg_new:nnn { coffin } { show }
+ {
+ Size~of~coffin~#1 : #2 \\
+ Poles~of~coffin~#1 : #3 .
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3color.dtx b/macros/latex-dev/required/l3kernel/l3color.dtx
new file mode 100644
index 0000000000..0edc225c52
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3color.dtx
@@ -0,0 +1,3246 @@
+% \iffalse meta-comment
+%
+%% File: l3color.dtx
+%
+% Copyright (C) 2017-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3color} module\\ Color support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{Color in boxes}
+%
+% Controlling the color of text in boxes requires a small number of control
+% functions, so that the boxed material uses the color at the point where
+% it is set, rather than where it is used.
+%
+% \begin{function}[added = 2011-09-03]{\color_group_begin:, \color_group_end:}
+% \begin{syntax}
+% \cs{color_group_begin:}
+% \ldots
+% \cs{color_group_end:}
+% \end{syntax}
+% Creates a color group: one used to \enquote{trap} color settings.
+% This grouping is built in to for example \cs{hbox_set:Nn}.
+% \end{function}
+%
+% \begin{function}[added = 2011-09-03]{\color_ensure_current:}
+% \begin{syntax}
+% \cs{color_ensure_current:}
+% \end{syntax}
+% Ensures that material inside a box uses the foreground color
+% at the point where the box is set, rather than that in force when the
+% box is used. This function should usually be used within a
+% \cs{color_group_begin:} \ldots \cs{color_group_end:} group.
+% \end{function}
+%
+% \section{Color models}
+%
+% A color \emph{model} is a way to represent sets of colors. Different models
+% are particularly suitable for different output methods, \emph{e.g.}~screen
+% or print. Parameter-based models can describe a very large number of unique
+% colors, and have a varying number of \emph{axes} which define a color
+% space. In contrast, various proprietary models are available which define
+% \emph{spot} colors (more formally separations).
+%
+% Core models are used to pass color information to output; these are
+% \enquote{native} to \pkg{l3color}. Core models use real numbers in the range
+% $[0,1]$ to represent values. The core models supported here are
+% \begin{itemize}
+% \item \texttt{gray} Grayscale color, with a single axis running from
+% $0$ (fully black) to $1$ (fully white)
+% \item \texttt{rgb} Red-green-blue color, with three axes, one for each of
+% the components
+% \item \texttt{cmyk} Cyan-magenta-yellow-black color, with four axes, one for
+% each of the components
+% \end{itemize}
+%
+% There are also interface models: these are convenient for users but have
+% to be manipulated before storing/passing to the backend. Interface models
+% are primarily integer-based: see below for more detail. The supported
+% interface models are
+% \begin{itemize}
+% \item \texttt{Gray} Grayscale color, with a single axis running from
+% $0$ (fully black) to $15$ (fully white)
+% \item \texttt{hsb} Hue-saturation-brightness color, with three axes,all
+% real values in the range $[0,1]$ for hue saturation and brightness
+% \item \texttt{Hsb} Hue-saturation-brightness color, with three axes, integer
+% in the range $[0,360]$ for hue, real values in the range $[0,1]$ for
+% saturation and brightness
+% \item \texttt{HSB} Hue-saturation-brightness color, with three axes, integers
+% in the range $[0,240]$ for hue, saturation and brightness
+% \item \texttt{HTML} HTML format representation of RGB color given as a
+% single six-digit hexadecimal number
+% \item \texttt{RGB} Red-green-blue color, with three axes, one for each of
+% the components, values as integers from $0$ to $255$
+% \item \texttt{wave} Light wavelength, a real number in the range
+% $380$ to $780$ (nanometres)
+% \end{itemize}
+% All interface models are internally stored as |rgb|.
+%
+% Finally, there are a small number of models which are parsed to allow
+% data transfer from \pkg{xcolor} but which should not be used by end-users.
+% These are
+% \begin{itemize}
+% \item \texttt{cmy} Cyan-magenta-yellow color with three axes, one for
+% each of the components; converted to |cmyk|
+% \item \texttt{tHsb} \enquote{Tuned} hue-saturation-brightness color with three
+% axes, integer in the range $[0,360]$ for hue, real values in the range
+% $[0,1]$ for saturation and brightness; converted to |rgb| using the
+% standard tuning map defined by \pkg{xcolor}
+% \item \texttt{\&spot} Spot color tint with one value; treated as a gray
+% tint as spot color data is not available for extraction
+% \end{itemize}
+%
+% To allow parsing of data from \pkg{xcolor}, any leading model up the first
+% \texttt{:} will be discarded; the approach of selecting an internal form
+% for data is \emph{not} used in \pkg{l3color}.
+%
+% Additional models may be created to allow mixing of separation colors
+% with each other or with those from other models. See
+% Section~\ref{l3color:sec:new-models} for more detail of color support
+% for additional models.
+%
+% When color is selected by model, the \meta{values} given are specified as
+% a comma-separated list. The length of the list will therefore be determined
+% by the detail of the model involved.
+%
+% Color models (and interconversion) are complex, and more details are given
+% in the manual to the \LaTeXe{} \pkg{xcolor} package and in the
+% \emph{PostScript Language Reference Manual}, published by Addison--Wesley.
+%
+% \section{Color expressions}
+%
+% In addition to allowing specification of color by model and values,
+% \pkg{l3color} also supports color expressions. These are created
+% by combining one or more color names, with the amount of each specified
+% as a value in the range $0$--$100$. The value should be given between
+% |!| symbols in the expression. Thus for example
+% \begin{verbatim}
+% red!50!green
+% \end{verbatim}
+% is a mixture of $50\,\%$ red and $50\,\%$ green. A trailing value is
+% interpreted as implicitly followed by |!white|, and so
+% \begin{verbatim}
+% red!25
+% \end{verbatim}
+% specifies $25\,\%$ red mixed with $75\,\%$ white.
+%
+% Where the models for the mixed colors are different, the model of the first
+% color is used. Thus
+% \begin{verbatim}
+% red!50!cyan
+% \end{verbatim}
+% will result in a color specification using the |rgb| model, made up of
+% $50\,\%$ red and $50\,\%$ of cyan \emph{expressed in \texttt{rgb}}.
+% This may be important as color model interconversion is not exact.
+%
+% The one exception to the above is where the first model in an expression is
+% |gray|. In this case, the order of mixing is \enquote{swapped} internally, so
+% that for example
+% \begin{verbatim}
+% black!50!red
+% \end{verbatim}
+% has the same result as
+% \begin{verbatim}
+% red!50!black
+% \end{verbatim}
+% (the predefined colors |black| and |white| use the |gray| model).
+%
+% Where more than two colors are mixed in an expression, evaluation takes place
+% in a stepwise fashion. Thus in
+% \begin{verbatim}
+% cyan!50!magenta!10!yellow
+% \end{verbatim}
+% the sub-expression
+% \begin{verbatim}
+% cyan!50!magenta
+% \end{verbatim}
+% is first evaluated to give an intermediate color specification, before
+% the second step
+% \begin{verbatim}
+% <intermediate>!10!yellow
+% \end{verbatim}
+% where |<intermediate>| represents this transitory calculated value.
+%
+% Within a color expression, |.| may be used to represent the color active
+% for typesetting (the current color). This allows for example
+% \begin{verbatim}
+% .!50
+% \end{verbatim}
+% to mean a mixture of $50\,\%$ of current color with white.
+%
+% (Color expressions supported here are a subset of those provided by
+% the \LaTeXe{} \pkg{xcolor} package. At present, only such features as are
+% clearly useful have been added here.)
+%
+% \section{Named colors}
+%
+% Color names are stored in a single namespace, which makes them accessible
+% as part of color expressions. Whilst they are not reserved in a technical
+% sense, the names |black|, |white|, |red|, |green|, |blue|, |cyan|, |magenta|
+% and |yellow| have special meaning and should not be redefined. Color names
+% should be made up of letters, numbers and spaces only: other characters are
+% reserved for use in color expressions. In particular, |.| represents the
+% current color at the start of a color expression.
+%
+% \begin{function}{\color_set:nn}
+% \begin{syntax}
+% \cs{color_set:nn} \Arg{name} \Arg{color expression}
+% \end{syntax}
+% Evaluates the \meta{color expression} and stores the resulting
+% color specification as the \meta{name}.
+% \end{function}
+%
+% \begin{function}{\color_set:nnn}
+% \begin{syntax}
+% \cs{color_set:nnn} \Arg{name} \Arg{model(s)} \Arg{value(s)}
+% \end{syntax}
+% Stores the color specification equivalent to the \meta{model(s)} and
+% \meta{values} as the \meta{name}.
+% \end{function}
+%
+% \begin{function}{\color_set_eq:nn}
+% \begin{syntax}
+% \cs{color_set_eq:nn} \Arg{name1} \Arg{name2}
+% \end{syntax}
+% Copies the color specification in \meta{name2} to \meta{name1}. The
+% special name |.| may be used to represent the current color, allowing
+% it to be saved to a name.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added = 2022-08-12]{\color_if_exist:n}
+% \begin{syntax}
+% \cs{color_if_exist_p:n} \Arg{name}
+% \cs{color_if_exist:nTF} \Arg{name} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether \meta{name} is currently defined to provide a color
+% specification.
+% \end{function}
+%
+% \begin{function}[added = 2021-05-11]{\color_show:n, \color_log:n}
+% \begin{syntax}
+% \cs{color_show:n} \Arg{name}
+% \cs{color_log:n} \Arg{name}
+% \end{syntax}
+% Displays the color specification stored in the \meta{name} on the
+% terminal or log file.
+% \end{function}
+%
+% \section{Selecting colors}
+%
+% General selection of color is safe when split across pages: a stack is
+% used to ensure that the correct color is re-selected on the new page.
+%
+% These commands set the current color (|.|): other more specialised functions
+% such as fill and stroke selectors do \emph{not} adjust this value.
+%
+% \begin{function}{\color_select:n}
+% \begin{syntax}
+% \cs{color_select:n} \Arg{color expression}
+% \end{syntax}
+% Parses the \meta{color expression} and then activates the resulting
+% color specification for typeset material.
+% \end{function}
+%
+% \begin{function}{\color_select:nn}
+% \begin{syntax}
+% \cs{color_select:nn} \Arg{model(s)} \Arg{value(s)}
+% \end{syntax}
+% Activates the color specification equivalent to the \meta{model(s)} and
+% \meta{value(s)} for typeset material.
+% \end{function}
+%
+% \begin{variable}{\l_color_fixed_model_tl}
+% When this is set to a non-empty value, colors will be converted to
+% the specified model when they are selected. Note that included images
+% and similar are not influenced by this setting.
+% \end{variable}
+%
+% \section{Colors for fills and strokes}
+%
+% Colors for drawing operations and so forth are split into strokes and fills
+% (the latter may also be referred to as non-stroke color). The fill color is
+% used for text under normal circumstances. Depending on the backend, stroke
+% color may use a \emph{stack}, in which case it exhibits the same page breaking
+% behavior as general color. However, \texttt{dvips}/\texttt{dvisvgm} do not
+% support this, and so color will need to be contained within a scope, such
+% as \cs{draw_begin:}/\cs{draw_end:}.
+%
+% \begin{function}{\color_fill:n, \color_stroke:n}
+% \begin{syntax}
+% \cs{color_fill:n} \Arg{color expression}
+% \end{syntax}
+% Parses the \meta{color expression} and then activates the resulting
+% color specification for filling or stroking.
+% \end{function}
+%
+% \begin{function}{\color_fill:nn, \color_stroke:nn}
+% \begin{syntax}
+% \cs{color_fill:nn} \Arg{model(s)} \Arg{value(s)}
+% \end{syntax}
+% Activates the color specification equivalent to the \meta{model(s)} and
+% \meta{value(s)} for filling or stroking.
+% \end{function}
+%
+% \begin{variable}[module = color]{color.sc}
+% When using \texttt{dvips}, this PostScript variables hold the stroke color.
+% \end{variable}
+%
+% \subsection{Coloring math mode material}
+%
+% Coloring math mode material using \cs[no-index]{color_select:nn(n)} has some restrictions
+% and often leads to spacing issues and/or poor input syntax. Avoiding generating
+% \tn{mathord} atoms whilst coloring only those parts of the input which are
+% required needs careful handling. The functionality here covers this important
+% use case.
+%
+% \begin{function}[added = 2022-01-26]{\color_math:nn, \color_math:nnn}
+% \begin{syntax}
+% \cs{color_math:nn} \Arg{color expression}\Arg{content}
+% \cs{color_math:nnn} \Arg{model(s)} \Arg{value(s)} \Arg{content}
+% \end{syntax}
+% Works as for \cs[no-index]{color_select:n(n)} but applies color only to the math mode
+% \meta{content}. The function does not generate a group and the \meta{content}
+% therefore retains its math atom states. Sub/superscripts are also properly
+% handled.
+% \end{function}
+%
+% \begin{variable}[added = 2022-01-26]{\l_color_math_active_tl}
+% This list controls which tokens are considered as math active and
+% should therefore be replaced by their definition during searching for
+% sub/superscripts.
+% \end{variable}
+%
+% \section{Multiple color models}
+%
+% When selecting or setting a color with an explicit model, it is possible
+% to give values for more than one model at one time. This is particularly
+% useful where automated conversion between models does not give the desired
+% outcome. To do this, the list of models and list of values are both subdivided
+% using |/| characters (as for the similar function in \pkg{xcolor}). For
+% example, to save a color with explicit |cmyk| and |rgb| values, one could
+% use
+% \begin{verbatim}
+% \color_set:nnn { foo } { cmyk / rgb }
+% { 0.1 , 0.2 , 0.3 , 0.4 / 0.1, 0.2 , 0.3 }
+% \end{verbatim}
+% The manually-specified conversion will be used in preference to automated
+% calculation whenever the model(s) listed are used: both in expressions and
+% when a fixed model is active.
+%
+% Similarly, the same syntax can be applied to directly selecting a color.
+% \begin{verbatim}
+% \color_select:nn { cmyk / rgb }
+% { 0.1 , 0.2 , 0.3 , 0.4 / 0.1, 0.2 , 0.3 }
+% \end{verbatim}
+% Again, this list is used when a fixed model is active: the first entry is used
+% unless there is a fixed model matching one of the other entries.
+%
+% \section{Exporting color specifications}
+%
+% The major use of color expressions is in setting typesetting output, but there
+% are other places in which some form of color information is required. These
+% may need data in a different format or using a different model to the internal
+% representation. Thus a set of functions are available to export colors in
+% different formats.
+%
+% Valid export targets are
+% \begin{itemize}
+% \item \texttt{backend} Two brace groups: the first containing the
+% model, the second containing space-separated values appropriate
+% for the model; this is the format required by backend functions
+% of \pkg{expl3}
+% \item \texttt{comma-sep-cmyk} Comma-separated cyan-magenta-yellow-black
+% values
+% \item \texttt{comma-sep-rgb} Comma-separated red-green-blue values
+% suitable for use as a PDF annotation color
+% \item \texttt{HTML} Uppercase two-digit hexadecimal values, expressing
+% a red-green-blue color; the digits are \emph{not} separated
+% \item \texttt{space-sep-cmyk} Space-separated cyan-magenta-yellow-black
+% values
+% \item \texttt{space-sep-rgb} Space-separated red-green-blue values
+% suitable for use as a PDF annotation color
+% \end{itemize}
+%
+% \begin{function}{\color_export:nnN}
+% \begin{syntax}
+% \cs{color_export:nnN} \Arg{color expression} \Arg{format} \Arg{tl}
+% \end{syntax}
+% Parses the \meta{color expression} as described earlier,
+% then converts to the \meta{format} specified and assigns the data to the
+% \meta{tl}.
+% \end{function}
+%
+% \begin{function}{\color_export:nnnN}
+% \begin{syntax}
+% \cs{color_export:nnnN} \Arg{model} \Arg{value(s)} \Arg{format} \Arg{tl}
+% \end{syntax}
+% Expresses the combination of \meta{model} and \meta{value(s)} in an
+% internal representation, then converts to the \meta{format} specified and
+% assigns the data to the \meta{tl}.
+% \end{function}
+%
+% \section{Creating new color models}
+% \label{l3color:sec:new-models}
+%
+% Additional color models are required to support specialist workflows, for
+% example those involving separations (see
+% \url{https://helpx.adobe.com/indesign/using/spot-process-colors.html}
+% for details of the use of separations in print). Color models may be split
+% into families; for the standard device-based color models (\texttt{DeviceCMYK},
+% \texttt{DeviceRGB}, \texttt{DeviceGray}), these are synonymous. This
+% is not generally the case: see the PDF reference for more details. (Note that
+% \pkg{l3color} uses the shorter names \texttt{cmyk}, etc.)
+%
+% \begin{function}{\color_model_new:nnn}
+% \begin{syntax}
+% \cs{color_model_new:nnn} \Arg{model} \Arg{family} \Arg{params}
+% \end{syntax}
+% Creates a new \meta{model} which is derived from the color model \meta{family}.
+% The latter should be one of
+% \begin{itemize}
+% \item \texttt{DeviceN}
+% \item \texttt{ICCBased}
+% \item \texttt{Separation}
+% \end{itemize}
+% (The \meta{family} may be given in mixed case as-in the PDF reference:
+% internally, case of these strings is folded.)
+% Depending on the \meta{family}, one or more \meta{params} are mandatory or
+% optional.
+% \end{function}
+%
+% For a \texttt{Separation} space, there are three \emph{compulsory} keys.
+% \begin{itemize}
+% \item \texttt{name} The name of the Separation, for example the formal
+% name of a spot color ink. Such a \meta{name} may contain spaces, etc.,
+% which are not permitted in the \meta{model}.
+% \item \texttt{alternative-model} An alternative device colorspace, one of
+% \texttt{cmyk}, \texttt{rgb}, \texttt{gray} or \texttt{CIELAB}. The three
+% parameter-based models work as described above; see below for
+% details of CIELAB colors.
+% \item \texttt{alternative-values} A comma-separated list of values
+% appropriate to the \texttt{alternative-model}. This information is used by
+% the PDF application if the \texttt{Separation} is not available.
+% \end{itemize}
+%
+% CIELAB color separations are created using the
+% \texttt{alternative-model = CIELAB} setting. These colors must also have an
+% \texttt{illuminant} key, one of \texttt{a}, \texttt{c}, \texttt{e},
+% \texttt{d50}, \texttt{d55}, \texttt{d65} or \texttt{d75}. The
+% \texttt{alternative-values} in this case are the three parameters $L*$, $a*$
+% and $b*$ of the CIELAB model. Full details of this device-independent color
+% approach are given in the documentation to the \pkg{colorspace} package.
+%
+% CIELAB colors \emph{cannot} be converted into other device-dependent color
+% spaces, and as such, mixing can only occur if colors set up using the CIELAB
+% model are also given with an alternative parameter-based model. If that is
+% not the case, \pkg{l3color} will fallback to using black as the colorant in
+% any mixing.
+%
+% For a \texttt{DeviceN} space, there is one \emph{compulsory} key.
+% \begin{itemize}
+% \item \texttt{names} The names of the components of the \texttt{DeviceN}
+% space. Each should be either the \meta{name} of a \texttt{Separation} model,
+% a process color name (\texttt{cyan}, etc.) or the special name \texttt{none}.
+% \end{itemize}
+%
+% For a \texttt{ICCBased} space, there is one \emph{compulsory} key.
+% \begin{itemize}
+% \item \texttt{file} The name of the file containing the profile.
+% \end{itemize}
+%
+% \subsection{Color profiles}
+%
+% Color profiles are used to ensure color accuracy by linking to collaboration.
+% Applying a profile can be used to standardise color which is otherwise
+% device-dependence.
+%
+% \begin{function}[added = 2021-02-23]{\color_profile_apply:nn}
+% \begin{syntax}
+% \cs{color_profile_apply:nn} \Arg{profile} \Arg{model}
+% \end{syntax}
+% This function applies a \meta{profile} to one of the device \meta{models}.
+% The profile will then apply to all color of the selected \meta{model}. The
+% \meta{profile} should specify an ICC profile file. The \meta{model} has to
+% be one the standard device models: \texttt{cmyk}, \texttt{gray} or
+% \texttt{rgb}.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3color} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=color>
+% \end{macrocode}
+%
+% \subsection{Basics}
+%
+% \begin{variable}
+% {\l_@@_current_tl}
+% The color currently active for foreground (text, \emph{etc.}) material.
+% This is stored in the form of a color model followed by one or more
+% values. There are four pre-defined models, three of which take numerical
+% values in the range $[0,1]$:
+% \begin{itemize}
+% \item \texttt{gray \meta{gray}} Grayscale color with the \meta{gray}
+% value running from $0$ (fully black) to $1$ (fully white)
+% \item \texttt{cmyk \meta{cyan} \meta{magenta} \meta{yellow} \meta{black}}
+% \item \texttt{rgb \meta{red} \meta{green} \meta{blue}}
+% \end{itemize}
+% Notice that the value are separated by spaces. There is a fourth pre-defined
+% model using a string value and a numerical one:
+% \begin{itemize}
+% \item \texttt{spot \meta{name} \meta{tint}} A pre-defined spot color,
+% where the \meta{name} should be a pre-defined string color name and the
+% \meta{tint} should be in the range $[0,1]$.
+% \end{itemize}
+%
+% Additional models may be created to allow mixing of spot colors. The
+% number of data entries these require will depend on the number of
+% colors to be mixed.
+% \begin{texnote}
+% The content of \cs{l_@@_current_tl} comprises two brace groups, the
+% first containing the color model and the second containing the value(s)
+% applicable in that model.
+% \end{texnote}
+% \end{variable}
+%
+% \begin{macro}{\color_group_begin:, \color_group_end:}
+% Grouping for color is the same as using the basic \cs{group_begin:}
+% and \cs{group_end:} functions. However, for semantic reasons, they
+% are renamed here.
+% \begin{macrocode}
+\cs_new_eq:NN \color_group_begin: \group_begin:
+\cs_new_eq:NN \color_group_end: \group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\color_ensure_current:}
+% A driver-independent wrapper for setting the foreground color to the
+% current color \enquote{now}.
+% \begin{macrocode}
+\cs_new_protected:Npn \color_ensure_current:
+ { \@@_select:N \l_@@_current_tl }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_select:N, \@@_select_math:N}
+% \begin{macro}{\@@_select:nn}
+% Take an internal color specification and pass it to the driver. This code
+% is needed to ensure the current color but will also be used by the
+% higher-level material.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_select:N #1
+ {
+ \exp_after:wN \@@_select:nn #1
+ \group_insert_after:N \@@_backend_reset:
+ }
+\cs_new_protected:Npn \@@_select_math:N #1
+ { \exp_after:wN \@@_select:nn #1 }
+\cs_new_protected:Npn \@@_select:nn #1#2
+ { \use:c { @@_backend_select_ #1 :n } {#2} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_current_tl}
+% The current color, with the model and
+% \begin{macrocode}
+\tl_new:N \l_@@_current_tl
+\tl_set:Nn \l_@@_current_tl { { gray } { 0 } }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Predefined color names}
+%
+% The ability to predefine colors with a name is a key part of this module and
+% means there has to be a method for storing the results. At first sight, it
+% seems natural to follow the usual \pkg{expl3} model and create a
+% \texttt{color} variable type for the process. That would then allow both
+% local and global colors, constant colors and the like. However, these names
+% need to be accessible in some form at the user level, for selection of colors
+% either simply by name or as part of a more complex expression. This does not
+% require that the full name is exposed but does require that they can be
+% looked up in a predictable way. As such, it is more useful to expose just the
+% color names as part of the interface, with the result that only local color
+% names can be created. (This is also seen for example in key creation in
+% \pkg{l3keys}.) As a result, color names are declarative (no \texttt{new}
+% functions).
+%
+% Since there is no need to manipulate colors \emph{en masse}, each is stored
+% in a two-part structure: a \texttt{prop} for the colors themselves, and a
+% \texttt{tl} for the default model for each color.
+%
+% \subsection{Setup}
+%
+% \begin{variable}{\l_@@_internal_int, \l_@@_internal_tl}
+% \begin{macrocode}
+\int_new:N \l_@@_internal_int
+\tl_new:N \l_@@_internal_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\s_@@_mark}
+% Internal scan marks. \cs{s_@@_stop} is already defined in \pkg{l3color-base}.
+% \begin{macrocode}
+\scan_new:N \s_@@_mark
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_ignore_error_bool}
+% Used to avoid issuing multiple errors if there is a change-of-model with
+% input container an error.
+% \begin{macrocode}
+\bool_new:N \l_@@_ignore_error_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Utility functions}
+%
+% \begin{macro}[pTF, EXP]{\color_if_exist:n}
+% A simple wrapper to avoid needing to have the lookup repeated in too many
+% places.To guard against a color created in a group, we need to test for
+% entries in the |prop|.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \color_if_exist:n #1 { p , T, F, TF }
+ {
+ \prop_if_exist:cTF { l_@@_named_ #1 _prop }
+ {
+ \prop_if_empty:cTF { l_@@_named_ #1 _prop }
+ \prg_return_false:
+ \prg_return_true:
+ }
+ \prg_return_false:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_model:N, \@@_values:N}
+% Simple abstractions.
+% \begin{macrocode}
+\cs_new:Npn \@@_model:N #1 { \exp_after:wN \use_i:nn #1 }
+\cs_new:Npn \@@_values:N #1 { \exp_after:wN \use_ii:nn #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_extract:nNN, \@@_extract:VNN}
+% Recover the values for the standard model for a color.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_extract:nNN #1#2#3
+ {
+ \tl_set_eq:Nc #2 { l_@@_named_ #1 _tl }
+ \prop_get:cVN { l_@@_named_ #1 _prop } #2 #3
+ }
+\cs_generate_variant:Nn \@@_extract:nNN { V }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Model conversion}
+%
+% \begin{macro}{\@@_convert:nnN, \@@_convert:VVN}
+% \begin{macro}{\@@_convert:nnnN, \@@_convert:nVnN, \@@_convert:nnVN}
+% \begin{macro}[EXP]
+% {
+% \@@_convert_gray_gray:w
+% \@@_convert_gray_rgb:w
+% \@@_convert_gray_cmyk:w
+% \@@_convert_cmyk_gray:w
+% \@@_convert_cmyk_rgb:w
+% \@@_convert_cmyk_cmyk:w
+% \@@_convert_rgb_gray:w
+% \@@_convert_rgb_rgb:w
+% \@@_convert_rgb_cmyk:w
+% }
+% \begin{macro}[EXP]{\@@_convert_rgb_cmyk:nnn}
+% \begin{macro}[EXP]{\@@_convert_rgb_cmyk:nnnn}
+% Model conversion is carried out using standard formulae for base models,
+% as described in the manual for \pkg{xcolor} (see also the \emph{PostScript
+% Language Reference Manual}). For other models direct conversion might not
+% be defined, so we go through the fallback models if necessary.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_convert:nnN #1#2#3
+ { \@@_convert:nnVN {#1} {#2} #3 #3 }
+\cs_generate_variant:Nn \@@_convert:nnN { VV }
+\cs_generate_variant:Nn \exp_last_unbraced:Nf { c }
+\cs_new_protected:Npn \@@_convert:nnnN #1#2#3#4
+ {
+ \tl_set:Ne #4
+ {
+ \cs_if_exist_use:cTF { @@_convert_ #1 _ #2 :w }
+ { #3 \s_@@_stop }
+ {
+ \cs_if_exist:cTF { @@_convert_ \use:c { c_@@_fallback_ #1 _tl } _ #2 :w }
+ {
+ \exp_last_unbraced:cf
+ { @@_convert_ \use:c { c_@@_fallback_ #1 _tl } _ #2 :w }
+ { \use:c { @@_convert_ #1 _ \use:c { c_@@_fallback_ #1 _tl } :w } #3 \s_@@_stop }
+ \s_@@_stop
+ }
+ {
+ \exp_last_unbraced:cf
+ { @@_convert_ \use:c { c_@@_fallback_ #2 _tl } _ #2 :w }
+ {
+ \cs_if_exist_use:cTF { @@_convert_ #1 _ \use:c { c_@@_fallback_ #2 _tl } :w }
+ { #3 \s_@@_stop }
+ {
+ \exp_last_unbraced:cf
+ { @@_convert_ \use:c { c_@@_fallback_ #1 _tl } _ \use:c { c_@@_fallback_ #2 _tl } :w }
+ { \use:c { @@_convert_ #1 _ \use:c { c_@@_fallback_ #1 _tl } :w } #3 \s_@@_stop }
+ \s_@@_stop
+ }
+ }
+ \s_@@_stop
+ }
+ }
+ }
+ }
+\cs_generate_variant:Nn \@@_convert:nnnN { nV , nnV }
+\cs_new:Npn \@@_convert_gray_gray:w #1 \s_@@_stop
+ { #1 }
+\cs_new:Npn \@@_convert_gray_rgb:w #1 \s_@@_stop
+ { #1 ~ #1 ~ #1 }
+\cs_new:Npn \@@_convert_gray_cmyk:w #1 \s_@@_stop
+ { 0 ~ 0 ~ 0 ~ \fp_eval:n { 1 - #1 } }
+% \end{macrocode}
+% These rather odd values are based on \textsc{ntsc} television: the set are
+% used for the |cmyk| conversion.
+% \begin{macrocode}
+\cs_new:Npn \@@_convert_rgb_gray:w #1 ~ #2 ~ #3 \s_@@_stop
+ { \fp_eval:n { 0.3 * #1 + 0.59 * #2 + 0.11 * #3 } }
+\cs_new:Npn \@@_convert_rgb_rgb:w #1 \s_@@_stop
+ { #1 }
+% \end{macrocode}
+% The conversion from |rgb| to |cmyk| is the most complex: a two-step
+% procedure which requires \emph{black generation} and \emph{undercolor
+% removal} functions. The PostScript reference describes them as
+% device-dependent, but following \pkg{xcolor} we assume they are linear.
+% Moreover, as the likelihood of anyone using a non-unitary matrix here is
+% tiny, we simplify and treat those two concepts as no-ops. To allow code
+% sharing with parsing of |cmy| values, we have an intermediate function
+% here (\cs{@@_convert_rgb_cmyk:nnn}) which actually takes |cmy| values
+% as input.
+% \begin{macrocode}
+\cs_new:Npn \@@_convert_rgb_cmyk:w #1 ~ #2 ~ #3 \s_@@_stop
+ {
+ \exp_args:Neee \@@_convert_rgb_cmyk:nnn
+ { \fp_eval:n { 1 - #1 } }
+ { \fp_eval:n { 1 - #2 } }
+ { \fp_eval:n { 1 - #3 } }
+ }
+\cs_new:Npn \@@_convert_rgb_cmyk:nnn #1#2#3
+ {
+ \exp_args:Ne \@@_convert_rgb_cmyk:nnnn
+ { \fp_eval:n { min( #1, #2 , #3 ) } } {#1} {#2} {#3}
+ }
+\cs_new:Npn \@@_convert_rgb_cmyk:nnnn #1#2#3#4
+ {
+ \fp_eval:n { min ( 1 , max ( 0 , #2 - #1 ) ) } \c_space_tl
+ \fp_eval:n { min ( 1 , max ( 0 , #3 - #1 ) ) } \c_space_tl
+ \fp_eval:n { min ( 1 , max ( 0 , #4 - #1 ) ) } \c_space_tl
+ #1
+ }
+\cs_new:Npn \@@_convert_cmyk_gray:w #1 ~ #2 ~ #3 ~ #4 \s_@@_stop
+ { \fp_eval:n { 1 - min ( 1 , 0.3 * #1 + 0.59 * #2 + 0.11 * #3 + #4 ) } }
+\cs_new:Npn \@@_convert_cmyk_rgb:w #1 ~ #2 ~ #3 ~ #4 \s_@@_stop
+ {
+ \fp_eval:n { 1 - min ( 1 , #1 + #4 ) } \c_space_tl
+ \fp_eval:n { 1 - min ( 1 , #2 + #4 ) } \c_space_tl
+ \fp_eval:n { 1 - min ( 1 , #3 + #4 ) }
+ }
+\cs_new:Npn \@@_convert_cmyk_cmyk:w #1 \s_@@_stop
+ { #1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Color expressions}
+%
+% \begin{variable}
+% {\l_@@_model_tl, \l_@@_value_tl, \l_@@_next_model_tl, \l_@@_next_value_tl}
+% Working space to store the color data whilst doing calculations: keeping
+% it on the stack is attractive but gets tricky (return is non-trivial).
+% \begin{macrocode}
+\tl_new:N \l_@@_model_tl
+\tl_new:N \l_@@_value_tl
+\tl_new:N \l_@@_next_model_tl
+\tl_new:N \l_@@_next_value_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_parse:nN}
+% \begin{macro}{\@@_parse_aux:nN}
+% \begin{macro}{\@@_parse_eq:Nn}
+% \begin{macro}{\@@_parse_eq:nNn}
+% \begin{macro}{\@@_parse:Nw}
+% \begin{macro}{\@@_parse_loop_init:Nnn}
+% \begin{macro}{\@@_parse_loop:w}
+% \begin{macro}{\@@_parse_loop_check:nn}
+% \begin{macro}{\@@_parse_loop:nn}
+% \begin{macro}{\@@_parse_gray:n, \@@_parse_std:n}
+% \begin{macro}{\@@_parse_break:w}
+% \begin{macro}{\@@_parse_end:}
+% \begin{macro}[EXP]{\@@_parse_mix:Nnnn, \@@_parse_mix:NVVn}
+% \begin{macro}[EXP]{\@@_parse_mix:nNnn}
+% \begin{macro}[EXP]
+% {
+% \@@_parse_mix_gray:nw ,
+% \@@_parse_mix_rgb:nw ,
+% \@@_parse_mix_cmyk:nw
+% }
+% The main function for parsing color expressions removes actives but
+% otherwise expands, then starts working through the expression itself.
+% At the end, we apply the payload.
+% \begin{macrocode}
+\cs_new_protected:Npe \@@_parse:nN #1#2
+ {
+ \tl_set:Ne \exp_not:c { l_@@_named_ . _tl }
+ { \exp_not:N \@@_model:N \exp_not:N \l_@@_current_tl }
+ \prop_put:NVe \exp_not:c { l_@@_named_ . _prop }
+ \exp_not:c { l_@@_named_ . _tl }
+ { \exp_not:N \@@_values:N \exp_not:N \l_@@_current_tl }
+ \exp_not:N \exp_args:Ne \exp_not:N \@@_parse_aux:nN
+ { \exp_not:N \tl_to_str:n {#1} } #2
+ }
+% \end{macrocode}
+% Before going to all of the effort of parsing an expression, these two
+% precursor functions look for a pre-defined name, either on its own or
+% with a trailing |!| (which is the same thing).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_parse_aux:nN #1#2
+ {
+ \color_if_exist:nTF {#1}
+ { \@@_parse_set_eq:Nn #2 {#1} }
+ { \@@_parse:Nw #2#1 ! \s_@@_stop }
+ \@@_check_model:N #2
+ }
+\cs_new_protected:Npn \@@_parse_set_eq:Nn #1#2
+ {
+ \tl_if_empty:NTF \l_color_fixed_model_tl
+ { \exp_args:Nv \@@_parse_set_eq:nNn { l_@@_named_ #2 _tl } }
+ { \exp_args:NV \@@_parse_set_eq:nNn \l_color_fixed_model_tl }
+ #1 {#2}
+ }
+% \end{macrocode}
+% Here, we have to allow for the case where there is a fixed model:
+% that can't be swept up by generic conversion as we are dealing with a
+% named color.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_parse_set_eq:nNn #1#2#3
+ {
+ \prop_get:cnNTF
+ { l_@@_named_ #3 _prop } {#1}
+ \l_@@_value_tl
+ { \tl_set:Ne #2 { {#1} { \l_@@_value_tl } } }
+ {
+ \tl_set_eq:Nc \l_@@_model_tl { l_@@_named_ #3 _tl }
+ \prop_get:cVN { l_@@_named_ #3 _prop } \l_@@_model_tl
+ \l_@@_value_tl
+ \@@_convert:nnN
+ \l_@@_model_tl {#1} \l_@@_value_tl
+ \tl_set:Ne #2
+ {
+ {#1}
+ { \l_@@_value_tl }
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_parse:Nw #1#2 ! #3 \s_@@_stop
+ {
+ \color_if_exist:nTF {#2}
+ {
+ \tl_if_blank:nTF {#3}
+ { \@@_parse_set_eq:Nn #1 {#2} }
+ { \@@_parse_loop_init:Nnn #1 {#2} {#3} }
+ }
+ {
+ \msg_error:nnn { color } { unknown-color } {#2}
+ \tl_set:Nn \l_@@_current_tl { { gray } { 0 } }
+ }
+ }
+% \end{macrocode}
+% Once we establish that a full parse is needed, the next job is to get the
+% detail of the first color. That will determine the model we use for the
+% calculation: splitting here makes checking that a bit easier.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_parse_loop_init:Nnn #1#2#3
+ {
+ \group_begin:
+ \@@_extract:nNN {#2} \l_@@_model_tl \l_@@_value_tl
+ \@@_parse_loop:w #3 ! ! ! ! \s_@@_stop
+ \tl_set:Ne \l_@@_internal_tl
+ { { \l_@@_model_tl } { \l_@@_value_tl } }
+ \exp_args:NNNV \group_end:
+ \tl_set:Nn #1 \l_@@_internal_tl
+ }
+% \end{macrocode}
+% This is the loop proper: there can be an open-ended set of colors to parse,
+% separated by |!| tokens. There are a few cases to look out for. At the end
+% of the expression and with we find a mix of $100$ then we simply skip the
+% next color entirely (we can't stop the loop as there might be a further
+% valid color to mix in). On the other hand, if we get a mix of $0$ then
+% drop everything so far and start again. There is also a trailing
+% |white| to \enquote{read in} if the final explicit data is a mix.
+% Those conditions are separate from actually looping, which is therefore
+% sorted out by checking if we have further data to process: in contrast
+% to \pkg{xcolor}, we don't allow |!!| so the test can be simplified.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_parse_loop:w #1 ! #2 ! #3 ! #4 ! #5 \s_@@_stop
+ {
+ \tl_if_blank:nF {#1}
+ {
+ \bool_lazy_and:nnTF
+ { \fp_compare_p:nNn {#1} > { 0 } }
+ { \fp_compare_p:nNn {#1} < { 100 } }
+ {
+ \use:e
+ {
+ \@@_parse_loop:nn {#1}
+ { \tl_if_blank:nTF {#2} { white } {#2} }
+ }
+ }
+ { \@@_parse_loop_check:nn {#1} {#2} }
+ }
+ \tl_if_blank:nF {#3}
+ { \@@_parse_loop:w #3 ! #4 ! #5 \s_@@_stop }
+ \@@_parse_end:
+ }
+% \end{macrocode}
+% As these are unusual cases, we accept slower performance here for clearer
+% code: check for the error conditions, handle the boundary cases after
+% that.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_parse_loop_check:nn #1#2
+ {
+ \bool_if:NF \l_@@_ignore_error_bool
+ {
+ \bool_lazy_or:nnT
+ { \fp_compare_p:nNn {#1} < { 0 } }
+ { \fp_compare_p:nNn {#1} > { 100 } }
+ { \msg_error:nnnnn { color } { out-of-range } {#1} { 0 } { 100 } }
+ }
+ \fp_compare:nNnF {#1} > \c_zero_fp
+ {
+ \tl_if_blank:nTF {#2}
+ { \@@_extract:nNN { white } }
+ { \@@_extract:nNN {#2} }
+ \l_@@_model_tl \l_@@_value_tl
+ }
+ }
+% \end{macrocode}
+% The \enquote{payload} of calculation in the loop first. If the model for
+% the upcoming color is different from that of the existing (partial) color,
+% convert the model. For |gray| the two are flipped round so that the outcome
+% is something with \enquote{real} color. We are then in a position to do the
+% actual calculation itself. The two auxiliaries here give us a way to break
+% the loop should an invalid name be found.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_parse_loop:nn #1#2
+ {
+ \color_if_exist:nTF {#2}
+ {
+ \@@_extract:nNN {#2} \l_@@_next_model_tl \l_@@_next_value_tl
+ \tl_if_eq:NNF \l_@@_model_tl \l_@@_next_model_tl
+ {
+ \str_if_eq:VnTF \l_@@_model_tl { gray }
+ { \@@_parse_gray:n {#2} }
+ { \@@_parse_std:n {#2} }
+ }
+ \tl_set:Ne \l_@@_value_tl
+ {
+ \@@_parse_mix:NVVn
+ \l_@@_model_tl \l_@@_value_tl \l_@@_next_value_tl {#1}
+ }
+ }
+ {
+ \msg_error:nnn { color } { unknown-color } {#2}
+ \@@_extract:nNN { black } \l_@@_model_tl \l_@@_value_tl
+ \@@_parse_break:w
+ }
+ }
+% \end{macrocode}
+% The \texttt{gray} model needs special handling: the models need to be
+% swapped: we do that using a dedicated function.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_parse_gray:n #1
+ {
+ \tl_set_eq:NN \l_@@_model_tl \l_@@_next_model_tl
+ \tl_set:Nn \l_@@_next_model_tl { gray }
+ \exp_args:NnV \@@_convert:nnN { gray } \l_@@_model_tl
+ \l_@@_value_tl
+ \prop_get:cVN { l_@@_named_ #1 _prop } \l_@@_model_tl
+ \l_@@_next_value_tl
+ }
+\cs_new_protected:Npn \@@_parse_std:n #1
+ {
+ \prop_get:cVNF { l_@@_named_ #1 _prop }
+ \l_@@_model_tl
+ \l_@@_next_value_tl
+ {
+ \@@_convert:VVN
+ \l_@@_next_model_tl
+ \l_@@_model_tl
+ \l_@@_next_value_tl
+ }
+ }
+\cs_new_protected:Npn \@@_parse_break:w #1 \@@_parse_end: { }
+\cs_new_protected:Npn \@@_parse_end: { }
+% \end{macrocode}
+% Do the vector arithmetic: mainly a question of shuffling input, along
+% with one pre-calculation to keep down the use of division.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_mix:Nnnn #1#2#3#4
+ {
+ \exp_args:Nf \@@_parse_mix:nNnn
+ { \fp_eval:n { #4 / 100 } }
+ #1 {#2} {#3}
+ }
+\cs_generate_variant:Nn \@@_parse_mix:Nnnn { NVV }
+\cs_new:Npn \@@_parse_mix:nNnn #1#2#3#4
+ {
+ \use:c { @@_parse_mix_ #2 :nw } {#1}
+ #3 \s_@@_mark #4 \s_@@_stop
+ }
+\cs_new:Npn \@@_parse_mix_gray:nw #1#2 \s_@@_mark #3 \s_@@_stop
+ { \fp_eval:n { #2 * #1 + #3 * ( 1 - #1 ) } }
+\cs_new:Npn \@@_parse_mix_rgb:nw
+ #1#2 ~ #3 ~ #4 \s_@@_mark #5 ~ #6 ~ #7 \s_@@_stop
+ {
+ \fp_eval:n { #2 * #1 + #5 * ( 1 - #1 ) } \c_space_tl
+ \fp_eval:n { #3 * #1 + #6 * ( 1 - #1 ) } \c_space_tl
+ \fp_eval:n { #4 * #1 + #7 * ( 1 - #1 ) }
+ }
+\cs_new:Npn \@@_parse_mix_cmyk:nw
+ #1#2 ~ #3 ~ #4 ~ #5 \s_@@_mark #6 ~ #7 ~ #8 ~ #9 \s_@@_stop
+ {
+ \fp_eval:n { #2 * #1 + #6 * ( 1 - #1 ) } \c_space_tl
+ \fp_eval:n { #3 * #1 + #7 * ( 1 - #1 ) } \c_space_tl
+ \fp_eval:n { #4 * #1 + #8 * ( 1 - #1 ) } \c_space_tl
+ \fp_eval:n { #5 * #1 + #9 * ( 1 - #1 ) }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_model_gray:w, \@@_parse_model_rgb:w,
+% \@@_parse_model_cmyk:w
+% }
+% \begin{macro}[EXP]{\@@_parse_number:n}
+% \begin{macro}[EXP]{\@@_parse_number:w}
+% Turn the input into internal form, also tidying up the number quickly.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_model_gray:w #1 , #2 \s_@@_stop
+ { { gray } { \@@_parse_number:n {#1} } }
+\cs_new:Npn \@@_parse_model_rgb:w #1 , #2 , #3 , #4 \s_@@_stop
+ {
+ { rgb }
+ {
+ \@@_parse_number:n {#1} ~
+ \@@_parse_number:n {#2} ~
+ \@@_parse_number:n {#3}
+ }
+ }
+\cs_new:Npn \@@_parse_model_cmyk:w #1 , #2 , #3 , #4 , #5 \s_@@_stop
+ {
+ { cmyk }
+ {
+ \@@_parse_number:n {#1} ~
+ \@@_parse_number:n {#2} ~
+ \@@_parse_number:n {#3} ~
+ \@@_parse_number:n {#4}
+ }
+ }
+\cs_new:Npn \@@_parse_number:n #1
+ { \@@_parse_number:w #1 . 0 . \s_@@_stop }
+\cs_new:Npn \@@_parse_number:w #1 . #2 . #3 \s_@@_stop
+ { \tl_if_blank:nTF {#1} { 0 } {#1} . #2 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_model_Gray:w, \@@_parse_model_hsb:w,
+% \@@_parse_model_Hsb:w, \@@_parse_model_HSB:w,
+% \@@_parse_model_HTML:w, \@@_parse_model_RGB:w
+% }
+% \begin{macro}[EXP]{\@@_parse_model_hsb:nnn, \@@_parse_model_hsb_aux:nnn}
+% \begin{macro}[EXP]{\@@_parse_model_hsb:nnnn}
+% \begin{macro}[EXP]{\@@_parse_model_hsb:nnnnn}
+% \begin{macro}[EXP]
+% {
+% \@@_parse_model_hsb_0:nnnn ,
+% \@@_parse_model_hsb_1:nnnn ,
+% \@@_parse_model_hsb_2:nnnn ,
+% \@@_parse_model_hsb_3:nnnn ,
+% \@@_parse_model_hsb_4:nnnn ,
+% \@@_parse_model_hsb_5:nnnn
+% }
+% \begin{macro}[EXP]{\@@_parse_model_wave:w}
+% \begin{macro}[EXP]
+% {\@@_parse_model_wave_auxi:nn, \@@_parse_model_wave_auxii:nn}
+% \begin{macro}[EXP]{\@@_parse_model_wave_rho:n}
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_model_Gray:w #1 , #2 \s_@@_stop
+ { { gray } { \fp_eval:n { #1 / 15 } } }
+\cs_new:Npn \@@_parse_model_hsb:w #1 , #2 , #3 , #4 \s_@@_stop
+ { \@@_parse_model_hsb:nnn {#1} {#2} {#3} }
+\cs_new:Npn \@@_parse_model_Hsb:w #1 , #2 , #3 , #4 \s_@@_stop
+ {
+ \exp_args:Ne \@@_parse_model_hsb:nnn { \fp_eval:n { #1 / 360 } }
+ {#2} {#3}
+ }
+% \end{macrocode}
+% The conversion here is non-trivial but is described at length
+% in the \pkg{xcolor} manual. For ease, we calculate the integer
+% and fractional parts of the hue first, then use them to work out the
+% possible values for $r$, $g$ and $b$ before putting them in the correct
+% places.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_model_hsb:nnn #1#2#3
+ {
+ { rgb }
+ {
+ \exp_args:Ne \@@_parse_model_hsb_aux:nnn
+ { \fp_eval:n { 6 * (#1) } } {#2} {#3}
+ }
+ }
+\cs_new:Npn \@@_parse_model_hsb_aux:nnn #1#2#3
+ {
+ \exp_args:Nee \@@_parse_model_hsb_aux:nnnn
+ { \fp_eval:n { floor(#1) } } { \fp_eval:n { #1 - floor(#1) } }
+ {#2} {#3}
+ }
+\cs_new:Npn \@@_parse_model_hsb_aux:nnnn #1#2#3#4
+ {
+ \use:e
+ {
+ \exp_not:N \@@_parse_model_hsb_aux:nnnnn
+ { \@@_parse_number:n {#4} }
+ { \fp_eval:n { round(#4 * (1 - #3) ,5) } }
+ { \fp_eval:n { round(#4 * ( 1 - #3 * #2 ) ,5) } }
+ { \fp_eval:n { round(#4 * ( 1 - #3 * (1 - #2) ) ,5) } }
+ {#1}
+ }
+ }
+\cs_new:Npn \@@_parse_model_hsb_aux:nnnnn #1#2#3#4#5
+ { \use:c { @@_parse_model_hsb_ #5 :nnnn } {#1} {#2} {#3} {#4} }
+\cs_new:cpn { @@_parse_model_hsb_0:nnnn } #1#2#3#4 { #1 ~ #4 ~ #2 }
+\cs_new:cpn { @@_parse_model_hsb_1:nnnn } #1#2#3#4 { #3 ~ #1 ~ #2 }
+\cs_new:cpn { @@_parse_model_hsb_2:nnnn } #1#2#3#4 { #2 ~ #1 ~ #4 }
+\cs_new:cpn { @@_parse_model_hsb_3:nnnn } #1#2#3#4 { #2 ~ #3 ~ #1 }
+\cs_new:cpn { @@_parse_model_hsb_4:nnnn } #1#2#3#4 { #4 ~ #2 ~ #1 }
+\cs_new:cpn { @@_parse_model_hsb_5:nnnn } #1#2#3#4 { #1 ~ #2 ~ #3 }
+\cs_new:cpn { @@_parse_model_hsb_6:nnnn } #1#2#3#4 { #1 ~ #2 ~ #2 }
+\cs_new:Npn \@@_parse_model_HSB:w #1 , #2 , #3 , #4 \s_@@_stop
+ {
+ \exp_args:Neee \@@_parse_model_hsb:nnn
+ { \fp_eval:n { round((#1) / 240,5) } }
+ { \fp_eval:n { round((#2) / 240,5) } }
+ { \fp_eval:n { round((#3) / 240,5) } }
+ }
+\cs_new:Npn \@@_parse_model_HTML:w #1 , #2 \s_@@_stop
+ { \@@_parse_model_HTML_aux:w #1 0 0 0 0 0 0 \s_@@_stop }
+\cs_new:Npn \@@_parse_model_HTML_aux:w #1#2#3#4#5#6#7 \s_@@_stop
+ {
+ { rgb }
+ {
+ \fp_eval:n { round(\int_from_hex:n {#1#2} / 255,5) } ~
+ \fp_eval:n { round(\int_from_hex:n {#3#4} / 255,5) } ~
+ \fp_eval:n { round(\int_from_hex:n {#5#6} / 255,5) }
+ }
+ }
+\cs_new:Npn \@@_parse_model_RGB:w #1 , #2 , #3 , #4 \s_@@_stop
+ {
+ { rgb }
+ {
+ \fp_eval:n { round((#1) / 255,5) } ~
+ \fp_eval:n { round((#2) / 255,5) } ~
+ \fp_eval:n { round((#3) / 255,5) }
+ }
+ }
+% \end{macrocode}
+% Following the description in the \pkg{xcolor} manual. As we always use |rgb|,
+% there is no need to find the sixth, we just pas the information straight
+% to the |hsb| auxiliary defined earlier.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_model_wave:w #1 , #2 \s_@@_stop
+ {
+ { rgb }
+ {
+ \fp_compare:nNnTF {#1} < { 420 }
+ { \@@_parse_model_wave_auxi:nn {#1} { 0.3 + 0.7 * (#1 - 380) / 40 }
+ }
+ {
+ \fp_compare:nNnTF {#1} > { 700 }
+ { \@@_parse_model_wave_auxi:nn {#1} { 0.3 + 0.7 * (#1 - 780) / -80 } }
+ { \@@_parse_model_wave_auxi:nn {#1} { 1 } }
+ }
+ }
+ }
+\cs_new:Npn \@@_parse_model_wave_auxi:nn #1#2
+ {
+ \fp_compare:nNnTF {#1} < { 440 }
+ {
+ \@@_parse_model_wave_auxii:nn
+ { 4 + \@@_parse_model_wave_rho:n { (#1 - 440) / -60 } }
+ {#2}
+ }
+ {
+ \fp_compare:nNnTF {#1} < { 490 }
+ {
+ \@@_parse_model_wave_auxii:nn
+ { 4 - \@@_parse_model_wave_rho:n { (#1 - 440) / 50 } }
+ {#2}
+ }
+ {
+ \fp_compare:nNnTF {#1} < { 510 }
+ {
+ \@@_parse_model_wave_auxii:nn
+ { 2 + \@@_parse_model_wave_rho:n { (#1 - 510) / -20 } }
+ {#2}
+ }
+ {
+ \fp_compare:nNnTF {#1} < { 580 }
+ {
+ \@@_parse_model_wave_auxii:nn
+ { 2 - \@@_parse_model_wave_rho:n { (#1 - 510) / 70 } }
+ {#2}
+ }
+ {
+ \fp_compare:nNnTF {#1} < { 645 }
+ {
+ \@@_parse_model_wave_auxii:nn
+ { \@@_parse_model_wave_rho:n { (#1 - 645) / -65 } }
+ {#2}
+ }
+ { \@@_parse_model_wave_auxii:nn { 0 } {#2} }
+ }
+ }
+ }
+ }
+ }
+\cs_new:Npn \@@_parse_model_wave_auxii:nn #1#2
+ {
+ \exp_args:Neee \@@_parse_model_hsb_aux:nnn
+ { \fp_eval:n {#1} }
+ { 1 }
+ { \@@_parse_model_wave_rho:n {#2} }
+ }
+\cs_new:Npn \@@_parse_model_wave_rho:n #1
+ { \fp_eval:n { min(1, max(0,#1) ) } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_parse_model_cmy:w}
+% Simply pass data to the conversion functions.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_model_cmy:w #1 , #2 , #3 , #4 \s_@@_stop
+ {
+ { cmyk }
+ { \@@_convert_rgb_cmyk:nnn {#1} {#2} {#3} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_parse_model_tHsb:w}
+% \begin{macro}{\@@_parse_model_tHsb:n}
+% \begin{macro}{\@@_parse_model_tHsb:nw}
+% There are three stages to the process here: bring the |tH| argument into
+% the normal range, divide through to get to |hsb| and finally convert that
+% to |rgb|. The final stage can be delegated to the parsing function for
+% |hsb|, and the conversion from |Hsb| to |hsb| is trivial, so the main focus
+% here is the first stage. We use a simple expandable loop to do the work,
+% and we implement the equation given in the \pkg{xcolor} manual
+% (number~85 there) as a simple expression.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_model_tHsb:w #1 , #2 , #3 , #4 \s_@@_stop
+ {
+ \exp_args:Ne \@@_parse_model_hsb:nnn
+ { \@@_parse_model_tHsb:n {#1} } {#2} {#3}
+ }
+\cs_new:Npn \@@_parse_model_tHsb:n #1
+ {
+ \@@_parse_model_tHsb:nw {#1}
+ 0 , 0 ;
+ 60 , 30 ;
+ 120 , 60 ;
+ 180 , 120 ;
+ 210 , 180 ;
+ 240 , 240 ;
+ 360 , 360 ;
+ \q_recursion_tail , ;
+ \q_recursion_stop
+ }
+\cs_new:Npn \@@_parse_model_tHsb:nw #1 #2 , #3 ; #4 , #5 ;
+ {
+ \quark_if_recursion_tail_stop_do:nn {#4} { 0 }
+ \fp_compare:nNnTF {#1} > {#4}
+ { \@@_parse_model_tHsb:nw {#1} #4 , #5 ; }
+ {
+ \use_i_delimit_by_q_recursion_stop:nw
+ { \fp_eval:n { ((#1 - #2) / (#4 - #2) * (#5 - #3) + #3) / 360 } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_parse_model_&spot:w}
+% We cannot extract data here from that passed by \pkg{xcolor}, so
+% we fall back on a black tint.
+% \begin{macrocode}
+\cs_new:cpn { @@_parse_model_&spot:w } #1 , #2 \s_@@_stop
+ { { gray } { #1 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Selecting colors (and color models)}
+%
+% \begin{variable}{\l_color_fixed_model_tl}
+% For selecting a single fixed model.
+% \begin{macrocode}
+\tl_new:N \l_color_fixed_model_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_check_model:N}
+% \begin{macro}{\@@_check_model:nn}
+% Check that the model in use is the one required.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_check_model:N #1
+ {
+ \tl_if_empty:NF \l_color_fixed_model_tl
+ {
+ \exp_after:wN \@@_check_model:nn #1
+ \tl_if_eq:NNF \l_@@_model_tl \l_color_fixed_model_tl
+ {
+ \@@_convert:VVN \l_@@_model_tl \l_color_fixed_model_tl
+ \l_@@_value_tl
+ }
+ \tl_set:Ne #1
+ { { \l_color_fixed_model_tl } { \l_@@_value_tl } }
+ }
+ }
+\cs_new_protected:Npn \@@_check_model:nn #1#2
+ {
+ \tl_set:Nn \l_@@_model_tl {#1}
+ \tl_set:Nn \l_@@_value_tl {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_finalise_current:}
+% A backend-neutral location for \enquote{last minute} manipulations before
+% handing off to the backend code. We set the special |.| syntax here: this
+% will therefore always be available. The finalisation is separate from the
+% main function so it can also be applied to \emph{e.g.}~page color.
+% \begin{macrocode}
+\cs_new_protected:Npe \@@_finalise_current:
+ {
+ \tl_set:Ne \exp_not:c { l_@@_named_ . _tl }
+ { \exp_not:N \@@_model:N \exp_not:N \l_@@_current_tl }
+ \prop_clear:N \exp_not:c { l_@@_named_ . _prop }
+ \prop_put:NVe \exp_not:c { l_@@_named_ . _prop }
+ \exp_not:c { l_@@_named_ . _tl }
+ { \exp_not:N \@@_values:N \exp_not:N \l_@@_current_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\color_select:n}
+% \begin{macro}{\color_select:nn}
+% \begin{macro}{\@@_select_main:Nw, \@@_select_loop:Nw}
+% \begin{macro}{\@@_select:nnN}
+% \begin{macro}{\@@_select_swap:Nnn}
+% Parse the input expressions then get the backend to actually activate
+% them. The main complexity here is the need to check through multiple models.
+% That is done \enquote{locally} here as the approach is subtly different to
+% when different models are being stored.
+% \begin{macrocode}
+\cs_new_protected:Npn \color_select:n #1
+ {
+ \@@_parse:nN {#1} \l_@@_current_tl
+ \@@_finalise_current:
+ \@@_select:N \l_@@_current_tl
+ }
+\cs_new_protected:Npn \color_select:nn #1#2
+ {
+ \@@_select_main:Nw \l_@@_current_tl
+ #1 / / \s_@@_mark #2 / / \s_@@_stop
+ \@@_finalise_current:
+ \@@_select:N \l_@@_current_tl
+ }
+% \end{macrocode}
+% If the first color model is the fixed one, or if there is no fixed
+% model, we don't need most of the data: just set up and apply the backend
+% function.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_select_main:Nw
+ #1 #2 / #3 / #4 \s_@@_mark #5 / #6 / #7 \s_@@_stop
+ {
+ \@@_select:nnN {#2} {#5} #1
+ \bool_lazy_or:nnF
+ { \tl_if_empty_p:N \l_color_fixed_model_tl }
+ { \str_if_eq_p:nV {#2} \l_color_fixed_model_tl }
+ { \@@_select_loop:Nw #1 #3 / #4 \s_@@_mark #6 / #7 \s_@@_stop }
+ }
+% \end{macrocode}
+% If a fixed model applies, we need to check each possible value in order.
+% If there is no hit at all, fall back on the generic formula-based
+% interchange.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_select_loop:Nw
+ #1 #2 / #3 \s_@@_mark #4 / #5 \s_@@_stop
+ {
+ \str_if_eq:nVTF {#2} \l_color_fixed_model_tl
+ { \@@_select:nnN {#2} {#4} #1 }
+ {
+ \tl_if_blank:nTF {#2}
+ { \exp_after:wN \@@_select_swap:Nnn \exp_after:wN #1 #1 }
+ { \@@_select_loop:Nw #1 #3 \s_@@_mark #5 \s_@@_stop }
+ }
+ }
+\cs_new_protected:Npn \@@_select:nnN #1#2#3
+ {
+ \cs_if_exist:cTF { @@_parse_model_ #1 :w }
+ {
+ \tl_set:Ne #3
+ { \use:c { @@_parse_model_ #1 :w } #2 , 0 , 0 , 0 , 0 \s_@@_stop }
+ }
+ { \msg_error:nnn { color } { unknown-model } {#1} }
+ }
+\cs_new_protected:Npn \@@_select_swap:Nnn #1#2#3
+ {
+ \@@_convert:nVnN {#2} \l_color_fixed_model_tl {#3} \l_@@_value_tl
+ \tl_set:Ne #1
+ { { \l_color_fixed_model_tl } { \l_@@_value_tl } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Math color}
+%
+% The approach here is the same as for the \LaTeXe{} \cs{mathcolor} command,
+% but as we are working at the \pkg{expl3} level we can make some minor
+% changes.
+%
+% \begin{macro}{\l_color_math_active_tl}
+% Tokens representing active sub/superscripts.
+% \begin{macrocode}
+\tl_new:N \l_color_math_active_tl
+\tl_set:Nn \l_color_math_active_tl { ' }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\g_@@_math_seq}
+% Not all engines have multiple color stacks, and at the same time we are
+% not expecting breaking within a colored math fragment. So we track the
+% color stack ourselves.
+% \begin{macrocode}
+\seq_new:N \g_@@_math_seq
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\color_math:nn}
+% \begin{macro}{\color_math:nnn}
+% \begin{macro}{\@@_math:nn}
+% The basic set up here is relatively simple: store the current color,
+% parse the new color as-normal, then switch color before inserting the
+% tokens we are asked to change. The tricky part is right at the end,
+% handling the reset.
+% \begin{macrocode}
+\cs_new_protected:Npn \color_math:nn #1#2
+ {
+ \@@_math:nn {#2}
+ { \@@_parse:nN {#1} \l_@@_current_tl }
+ }
+\cs_new_protected:Npn \color_math:nnn #1#2#3
+ {
+ \@@_math:nn {#3}
+ {
+ \@@_select_main:Nw \l_@@_current_tl
+ #1 / / \s_@@_mark #2 / / \s_@@_stop
+ }
+ }
+\cs_new_protected:Npn \@@_math:nn #1#2
+ {
+ \seq_gpush:NV \g_@@_math_seq \l_@@_current_tl
+ #2
+ \@@_select_math:N \l_@@_current_tl
+ #1
+ \@@_math_scan:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_math_scan:w ,
+% \@@_math_scan_auxi: ,
+% \@@_math_scan_auxii: ,
+% \@@_math_scan_end:
+% }
+% The complication when changing the color back is due to the fact
+% that the \cs{color_math:nn(n)} may be followed by \verb=^= or \verb=_=
+% or the hidden superscript (for example \texttt{'}) and its argument may
+% end in a \tn{mathop} in which case the sub- and superscripts may be
+% attached as \cs{limits} instead of after the material. All cases
+% need separate treatment. To avoid repeatedly collecting the same
+% token, we first check for an alignment tab: assuming we don't have
+% one of those, we can \enquote{recycle} \cs{l_peek_token} safely.
+% As we have an explicit \cs{c_alignment_token}, there needs to be
+% an align-safe group present.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_math_scan:w
+ {
+ \peek_remove_filler:n
+ {
+ \group_align_safe_begin:
+ \peek_catcode:NTF \c_alignment_token
+ {
+ \group_align_safe_end:
+ \@@_math_scan_end:
+ }
+ {
+ \group_align_safe_end:
+ \@@_math_scan_auxi:
+ }
+ }
+ }
+% \end{macrocode}
+% Dealing with literal |_| and |^| is easy, and as we have exactly two cases,
+% we can hard-code this. We use a hard-coded list for limits: these are all
+% primitives. The \cs{use_none:n} here also removes the test token so it is
+% left just in the right place.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_math_scan_auxi:
+ {
+ \token_case_catcode:NnTF \l_peek_token
+ {
+ \c_math_subscript_token { }
+ \c_math_superscript_token { }
+ }
+ { \@@_math_scripts:Nw }
+ {
+ \token_case_meaning:NnTF \l_peek_token
+ {
+ \tex_limits:D { \tex_limits:D }
+ \tex_nolimits:D { \tex_nolimits:D }
+ \tex_displaylimits:D { \tex_displaylimits:D }
+ }
+ { \@@_math_scan:w \use_none:n }
+ { \@@_math_scan_auxii: }
+ }
+ }
+% \end{macrocode}
+% The one final case to handle is math-active tokens, most obviously
+% \texttt{'}, as these won't be covered earlier.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_math_scan_auxii:
+ {
+ \tl_map_inline:Nn \l_color_math_active_tl
+ {
+ \token_if_eq_meaning:NNT \l_peek_token ##1
+ {
+ \tl_map_break:n
+ {
+ \use_i:nn
+ { \@@_math_scan_auxiii:N ##1 }
+ }
+ }
+ \@@_math_scan_end:
+ }
+ }
+\cs_new_protected:Npn \@@_math_scan_auxiii:N #1
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_math_scan:w
+ \char_generate:nn { `#1 } { 13 }
+ }
+\cs_new_protected:Npn \@@_math_scan_end:
+ {
+ \@@_backend_reset:
+ \seq_gpop:NN \g_@@_math_seq \l_@@_current_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_math_scripts:Nw}
+% \begin{macro}{\@@_math_script_aux:N}
+% The tricky part of handling sub and superscripts is that we have
+% to reset color to the one that is on the stack but reset it back
+% to what it was before to allow for cases like
+% \begin{verbatim}
+% \[ \color_math:n { red } { a + \sum } _ { i = 1 } ^ { n } \]
+% \end{verbatim}
+% Here, \TeX{} constructs a \cs{vbox} stacking subscript, summation
+% sign, and superscript. So technically the superscript comes first
+% and the \cs{sum} that should get colored red is the middle.
+%
+% The approach here is to set up a brace group immediately after the
+% script token, then to set the color appropriately in that argument.
+% We need an extra group to keep the color contained, and as we
+% need to allow for an explicit closing brace in the source, the
+% inner group also is a brace one rather than \cs{group_begin:}-based.
+% At the end of the outer group we need to insert \cs{@@_math_scan:w}
+% to continue the search for a second script token.
+%
+% Notice that here we \emph{don't} need to use the math-specific
+% color selector as we can allow the
+% |\group_insert_after:N \@@_backend_reset:| to operate normally.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_math_scripts:Nw #1
+ {
+ #1
+ \c_group_begin_token
+ \c_group_begin_token
+ \seq_get:NN \g_@@_math_seq \l_@@_current_tl
+ \@@_select:N \l_@@_current_tl
+ \group_insert_after:N \c_group_end_token
+ \group_insert_after:N \@@_math_scan:w
+ \peek_remove_filler:n
+ {
+ \peek_catcode_remove:NF \c_group_begin_token
+ { \@@_math_script_aux:N }
+ }
+ }
+% \end{macrocode}
+% Deal with the case where we do not have an explicit brace pair in the
+% source.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_math_script_aux:N #1 { #1 \c_group_end_token }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Fill and stroke color}
+%
+% \begin{macro}{\color_fill:n, \color_stroke:n}
+% \begin{macro}{\color_fill:nn, \color_stroke:nn}
+% \begin{macro}{\@@_draw:nnn}
+% \begin{macrocode}
+\cs_new_protected:Npn \color_fill:n #1
+ {
+ \@@_parse:nN {#1} \l_@@_current_tl
+ \exp_after:wN \@@_draw:nnn \l_@@_current_tl { fill }
+ }
+\cs_new_protected:Npn \color_stroke:n #1
+ {
+ \@@_parse:nN {#1} \l_@@_current_tl
+ \exp_after:wN \@@_draw:nnn \l_@@_current_tl { stroke }
+ }
+\cs_new_protected:Npn \color_fill:nn #1#2
+ {
+ \@@_select_main:Nw \l_@@_current_tl
+ #1 / / \s_@@_mark #2 / / \s_@@_stop
+ \exp_after:wN \@@_draw:nnn \l_@@_current_tl { fill }
+ }
+\cs_new_protected:Npn \color_stroke:nn #1#2
+ {
+ \@@_select_main:Nw \l_@@_current_tl
+ #1 / / \s_@@_mark #2 / / \s_@@_stop
+ \exp_after:wN \@@_draw:nnn \l_@@_current_tl { stroke }
+ }
+\cs_new_protected:Npn \@@_draw:nnn #1#2#3
+ {
+ \use:c { @@_backend_ #3 _ #1 :n } {#2}
+ \exp_args:Nc \group_insert_after:N { @@_backend_ #3 _ reset: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Defining named colors}
+%
+% \begin{variable}{\l_@@_named_tl}
+% Space to store the detail of the named color.
+% \begin{macrocode}
+\tl_new:N \l_@@_named_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\color_set:nn}
+% \begin{macro}{\@@_set:nnn}
+% \begin{macro}{\@@_set:nn}
+% \begin{macro}{\@@_set:nnw}
+% \begin{macro}{\color_set:nnn, \@@_set_aux:nnn}
+% \begin{macro}{\@@_set_colon:nnw}
+% \begin{macro}{\@@_set_loop:nw}
+% \begin{macro}{\color_set_eq:nn}
+% Defining named colors means working through the model list and saving
+% both the \enquote{main} color and any equivalents in other models. Even
+% if there is only one model, we store a |prop| as well as a |tl|, as there
+% could be grouping weirdness, etc. When setting using an expression,
+% we need to avoid any fixed model issues, which is done without a group as
+% in \pkg{l3keys}.
+% \begin{macrocode}
+\cs_new_protected:Npn \color_set:nn #1#2
+ {
+ \exp_args:NV \@@_set:nnn
+ \l_color_fixed_model_tl {#1} {#2}
+ }
+\cs_new_protected:Npn \@@_set:nnn #1#2#3
+ {
+ \tl_clear:N \l_color_fixed_model_tl
+ \@@_set:nn {#2} {#3}
+ \tl_set:Nn \l_color_fixed_model_tl {#1}
+ }
+\cs_new_protected:Npn \@@_set:nn #1#2
+ {
+ \str_if_eq:nnF {#1} { . }
+ {
+ \@@_parse:nN {#2} \l_@@_named_tl
+ \tl_clear_new:c { l_@@_named_ #1 _tl }
+ \tl_set:ce { l_@@_named_ #1 _tl }
+ { \@@_model:N \l_@@_named_tl }
+ \prop_clear_new:c { l_@@_named_ #1 _prop }
+ \prop_put:cve { l_@@_named_ #1 _prop } { l_@@_named_ #1 _tl }
+ { \@@_values:N \l_@@_named_tl }
+ \@@_set:nnw {#1} {#2} #2 ! \s_@@_stop
+ }
+ }
+% \end{macrocode}
+% When setting an expression-based color, there could be multiple model
+% data available for one or more of the input colors. Where that is true for
+% the \emph{first} named color in an expression, we re-parse the expression
+% when they are also parameter-based: only |cmyk|, |gray| and |rgb| make
+% any sense here. There is a bit of a performance hit but this should be
+% rare and taking place during set-up.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set:nnw #1#2#3 ! #4 \s_@@_stop
+ {
+ \clist_map_inline:nn { cmyk , gray , rgb }
+ {
+ \prop_get:cnNT { l_@@_named_ #3 _prop } {##1} \l_@@_internal_tl
+ {
+ \prop_if_in:cnF { l_@@_named_ #1 _prop } {##1}
+ {
+ \group_begin:
+ \bool_set_true:N \l_@@_ignore_error_bool
+ \tl_set:cn { l_@@_named_ #3 _tl } {##1}
+ \@@_parse:nN {#2} \l_@@_internal_tl
+ \exp_args:NNNV \group_end:
+ \tl_set:Nn \l_@@_internal_tl \l_@@_internal_tl
+ \prop_put:cee { l_@@_named_ #1 _prop }
+ { \@@_model:N \l_@@_internal_tl }
+ { \@@_values:N \l_@@_internal_tl }
+ }
+ }
+ }
+ }
+\cs_new_protected:Npn \color_set:nnn #1#2#3
+ {
+ \str_if_eq:nnF {#1} { . }
+ {
+ \tl_clear_new:c { l_@@_named_ #1 _tl }
+ \prop_clear_new:c { l_@@_named_ #1 _prop }
+ \exp_args:Ne \@@_set_aux:nnn { \tl_to_str:n {#2} }
+ {#1} {#3}
+ }
+ }
+\cs_new_protected:Npe \@@_set_aux:nnn #1#2#3
+ {
+ \exp_not:N \@@_set_colon:nnw {#2} {#3}
+ #1 \c_colon_str \c_colon_str \exp_not:N \s_@@_stop
+ }
+\use:e
+ {
+ \cs_new_protected:Npn \exp_not:N \@@_set_colon:nnw
+ #1#2 #3 \c_colon_str #4 \c_colon_str
+ #5 \exp_not:N \s_@@_stop
+ }
+ {
+ \tl_if_blank:nTF {#4}
+ { \@@_set_loop:nw {#1} #3 }
+ { \@@_set_loop:nw {#1} #4 }
+ / / \s_@@_mark #2 / / \s_@@_stop
+ }
+\cs_new_protected:Npn \@@_set_loop:nw
+ #1#2 / #3 \s_@@_mark #4 / #5 \s_@@_stop
+ {
+ \tl_if_blank:nF {#2}
+ {
+ \@@_select:nnN {#2} {#4} \l_@@_named_tl
+ \tl_set:Ne \l_@@_internal_tl { \@@_model:N \l_@@_named_tl }
+ \tl_if_empty:cT { l_@@_named_ #1 _tl }
+ { \tl_set_eq:cN { l_@@_named_ #1 _tl } \l_@@_internal_tl }
+ \prop_put:cVe { l_@@_named_ #1 _prop } \l_@@_internal_tl
+ { \@@_values:N \l_@@_named_tl }
+ \@@_set_loop:nw {#1} #3 \s_@@_mark #5 \s_@@_stop
+ }
+ }
+\cs_new_protected:Npn \color_set_eq:nn #1#2
+ {
+ \color_if_exist:nTF {#2}
+ {
+ \tl_clear_new:c { l_@@_named_ #1 _tl }
+ \prop_clear_new:c { l_@@_named_ #1 _prop }
+ \str_if_eq:nnTF {#2} { . }
+ {
+ \tl_set:ce { l_@@_named_ #1 _tl }
+ { \@@_model:N \l_@@_current_tl }
+ \prop_put:cve { l_@@_named_ #1 _prop } { l_@@_named_ #1 _tl }
+ { \@@_values:N \l_@@_current_tl }
+ }
+ {
+ \tl_set_eq:cc { l_@@_named_ #1 _tl } { l_@@_named_ #2 _tl }
+ \prop_set_eq:cc { l_@@_named_ #1 _prop } { l_@@_named_ #2 _prop }
+ }
+ }
+ {
+ \msg_error:nnn { color } { unknown-color } {#2}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% A small set of colors are always defined.
+% \begin{macrocode}
+\color_set:nnn { black } { gray } { 0 }
+\color_set:nnn { white } { gray } { 1 }
+\color_set:nnn { cyan } { cmyk } { 1 , 0 , 0 , 0 }
+\color_set:nnn { magenta } { cmyk } { 0 , 1 , 0 , 0 }
+\color_set:nnn { yellow } { cmyk } { 0 , 0 , 1 , 0 }
+\color_set:nnn { red } { rgb } { 1 , 0 , 0 }
+\color_set:nnn { green } { rgb } { 0 , 1 , 0 }
+\color_set:nnn { blue } { rgb } { 0 , 0 , 1 }
+% \end{macrocode}
+%
+% \begin{variable}{\l_@@_named_._prop, \l_@@_named_._tl}
+% A special named color: this is always defined though not fixed in
+% definition.
+% \begin{macrocode}
+\prop_new:c { l_@@_named_._prop }
+\tl_new:c { l_@@_named_._tl }
+\tl_set:ce { l_@@_named_._tl } { \@@_model:N \l_@@_current_tl }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Exporting colors}
+%
+% \begin{macro}{\color_export:nnN}
+% \begin{macro}{\color_export:nnnN}
+% \begin{macro}{\@@_export:nN}
+% \begin{macro}{\@@_export:nnnN}
+% \begin{macrocode}
+\cs_new_protected:Npn \color_export:nnN #1#2#3
+ {
+ \group_begin:
+ \tl_if_exist:cT { c_@@_export_ #2 _tl }
+ { \tl_set_eq:Nc \l_color_fixed_model_tl { c_@@_export_ #2 _tl } }
+ \@@_parse:nN {#1} #3
+ \@@_export:nN {#2} #3
+ \exp_args:NNNV \group_end:
+ \tl_set:Nn #3 #3
+ }
+\cs_new_protected:Npn \color_export:nnnN #1#2#3#4
+ {
+ \@@_select_main:Nw #4
+ #1 / / \s_@@_mark #2 / / \s_@@_stop
+ \@@_export:nN {#3} #4
+ }
+\cs_new_protected:Npn \@@_export:nN #1#2
+ { \exp_after:wN \@@_export:nnnN #2 {#1} #2 }
+\cs_new:Npn \@@_export:nnnN #1#2#3#4
+ {
+ \cs_if_exist_use:cF { @@_export_format_ #3 :nnN }
+ {
+ \msg_error:nnn { color } { unknown-export-format } {#3}
+ \use_none:nnn
+ }
+ {#1} {#2} #4
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_export_format_backend:nnN}
+% Simple.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_export_format_backend:nnN #1#2#3
+ { \tl_set:Nn #3 { {#1} {#2} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_export:nnnNN}
+% A generic auxiliary for cases where only one model is appropriate.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_export:nnnNN #1#2#3#4#5
+ {
+ \str_if_eq:nnTF {#2} {#1}
+ { #5 #4 #3 \s_@@_stop }
+ {
+ \@@_convert:nnnN {#2} {#1} {#3} #4
+ \exp_after:wN #5 \exp_after:wN #4
+ #4 \s_@@_stop
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}
+% {
+% \c_@@_export_comma-sep-cmyk_tl ,
+% \c_@@_export_comma-sep-rgb_tl ,
+% \c_@@_export_HTML_tl ,
+% \c_@@_export_space-sep-cmyk_tl ,
+% \c_@@_export_space-sep-rgb_tl
+% }
+% \begin{macrocode}
+\tl_const:cn { c_@@_export_comma-sep-cmyk_tl } { cmyk }
+\tl_const:cn { c_@@_export_comma-sep-rgb_tl } { rgb }
+\tl_const:Nn \c_@@_export_HTML_tl { rgb }
+\tl_const:cn { c_@@_export_space-sep-cmyk_tl } { cmyk }
+\tl_const:cn { c_@@_export_space-sep-rgb_tl } { rgb }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \@@_export_format_comma-sep-cmyk:nnN ,
+% \@@_export_format_comma-sep-rgb:nnN ,
+% \@@_export_format_space-sep-cmyk:nnN ,
+% \@@_export_format_space-sep-rgb:nnN
+% }
+% \begin{macrocode}
+\group_begin:
+ \cs_set_protected:Npn \@@_tmp:w #1#2
+ {
+ \cs_new_protected:cpe { @@_export_format_ #1 :nnN } ##1##2##3
+ {
+ \exp_not:N \@@_export:nnnNN {#2} {##1} {##2} ##3
+ \exp_not:c { @@_export_ #1 :Nw }
+ }
+ }
+ \@@_tmp:w { comma-sep-cmyk } { cmyk }
+ \@@_tmp:w { comma-sep-rgb } { rgb }
+ \@@_tmp:w { HTML } { rgb }
+ \@@_tmp:w { space-sep-cmyk } { cmyk }
+ \@@_tmp:w { space-sep-rgb } { rgb }
+
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_export_space-sep-cmyk:Nw, \@@_export_comma-sep-cmyk:Nw}
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_export_comma-sep-cmyk:Nw }
+ #1#2 ~ #3 ~ #4 ~ #5 \s_@@_stop
+ { \tl_set:Nn #1 { #2 , #3 , #4 , #5 } }
+\cs_new_protected:cpn { @@_export_space-sep-cmyk:Nw } #1#2 \s_@@_stop
+ { \tl_set:Nn #1 {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_export_comma-sep-rgb:Nw ,
+% \@@_export_HTML:Nw ,
+% \@@_export_space-sep-rgb:Nw
+% }
+% \begin{macro}[EXP]{\@@_export_HTML:n}
+% \textsc{html} values must be given in |rgb|: we force conversion if
+% required, then do some simple maths.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_export_comma-sep-rgb:Nw } #1#2 ~ #3 ~ #4 \s_@@_stop
+ { \tl_set:Ne #1 { #2 , #3 , #4 } }
+\cs_new_protected:Npn \@@_export_HTML:Nw #1#2 ~ #3 ~ #4 \s_@@_stop
+ {
+ \tl_set:Ne #1
+ {
+ \@@_export_HTML:n {#2}
+ \@@_export_HTML:n {#3}
+ \@@_export_HTML:n {#4}
+ }
+ }
+\cs_new:Npn \@@_export_HTML:n #1
+ {
+ \fp_compare:nNnTF {#1} = { 0 }
+ { 00 }
+ {
+ \fp_compare:nNnT { #1 * 255 } < { 16 } { 0 }
+ \int_to_Hex:n { \fp_to_int:n { #1 * 255 } }
+ }
+ }
+\cs_new_protected:cpn { @@_export_space-sep-rgb:Nw } #1#2 \s_@@_stop
+ { \tl_set:Nn #1 {#2} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Additional color models}
+%
+% \begin{variable}{\l_@@_internal_prop}
+% \begin{macrocode}
+\prop_new:N \l_@@_internal_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_model_int}
+% A tracker for the total number of new models.
+% \begin{macrocode}
+\int_new:N \g_@@_model_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {\c_@@_fallback_cmyk_tl, \c_@@_fallback_gray_tl, \c_@@_fallback_rgb_tl}
+% For every colorspace, we define one of the base colorspaces as a fallback.
+% The base colorspaces themselves are their own fallback.
+% \begin{macrocode}
+\tl_const:Nn \c_@@_fallback_cmyk_tl { cmyk }
+\tl_const:Nn \c_@@_fallback_gray_tl { gray }
+\tl_const:Nn \c_@@_fallback_rgb_tl { rgb }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_colorants_prop}
+% Mapping from names to colorants.
+% \begin{macrocode}
+\prop_new:N \g_@@_colorants_prop
+\prop_gput:Nnn \g_@@_colorants_prop { black } { Black }
+\prop_gput:Nnn \g_@@_colorants_prop { blue } { Blue }
+\prop_gput:Nnn \g_@@_colorants_prop { cyan } { Cyan }
+\prop_gput:Nnn \g_@@_colorants_prop { green } { Green }
+\prop_gput:Nnn \g_@@_colorants_prop { magenta } { Magenta }
+\prop_gput:Nnn \g_@@_colorants_prop { none } { None }
+\prop_gput:Nnn \g_@@_colorants_prop { red } { Red }
+\prop_gput:Nnn \g_@@_colorants_prop { yellow } { Yellow }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \c_@@_model_whitepoint_CIELAB_a_tl ,
+% \c_@@_model_whitepoint_CIELAB_b_tl ,
+% \c_@@_model_whitepoint_CIELAB_e_tl ,
+% \c_@@_model_whitepoint_CIELAB_d50_tl ,
+% \c_@@_model_whitepoint_CIELAB_d55_tl ,
+% \c_@@_model_whitepoint_CIELAB_d65_tl ,
+% \c_@@_model_whitepoint_CIELAB_d75_tl
+% }
+% Whitepoint data for the CIELAB profiles.
+% \begin{macrocode}
+\tl_const:Nn \c_@@_model_whitepoint_CIELAB_a_tl { 1.0985 ~ 1 ~ 0.3558 }
+\tl_const:Nn \c_@@_model_whitepoint_CIELAB_b_tl { 0.9807 ~ 1 ~ 1.1822 }
+\tl_const:Nn \c_@@_model_whitepoint_CIELAB_e_tl { 1 ~ 1 ~ 1 }
+\tl_const:cn { c_@@_model_whitepoint_CIELAB_d50_tl } { 0.9642 ~ 1 ~ 0.8251 }
+\tl_const:cn { c_@@_model_whitepoint_CIELAB_d55_tl } { 0.9568 ~ 1 ~ 0.9214 }
+\tl_const:cn { c_@@_model_whitepoint_CIELAB_d65_tl } { 0.9504 ~ 1 ~ 1.0888 }
+\tl_const:cn { c_@@_model_whitepoint_CIELAB_d75_tl } { 0.9497 ~ 1 ~ 1.2261 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_model_range_CIELAB_tl}
+% The range for CIELAB color spaces.
+% \begin{macrocode}
+\tl_const:Nn \c_@@_model_range_CIELAB_tl { 0 ~ 100 ~ -128 ~ 127 ~ -128 ~ 127 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_alternative_model_prop}
+% For tracking the alternative model set up for separations, etc.
+% \begin{macrocode}
+\prop_new:N \g_@@_alternative_model_prop
+\clist_map_inline:nn { cyan , magenta , yellow , black }
+ { \prop_gput:Nnn \g_@@_alternative_model_prop {#1} { cmyk } }
+\clist_map_inline:nn { red , green , blue }
+ { \prop_gput:Nnn \g_@@_alternative_model_prop {#1} { rgb } }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_alternative_values_prop}
+% Same for the values: a bit more involved.
+% \begin{macrocode}
+\prop_new:N \g_@@_alternative_values_prop
+\prop_gput:Nnn \g_@@_alternative_values_prop { cyan } { 1 , 0 , 0 , 0 }
+\prop_gput:Nnn \g_@@_alternative_values_prop { magenta } { 0 , 1 , 0 , 0 }
+\prop_gput:Nnn \g_@@_alternative_values_prop { yellow } { 0 , 0 , 1 , 0 }
+\prop_gput:Nnn \g_@@_alternative_values_prop { black } { 0 , 0 , 0 , 1 }
+\prop_gput:Nnn \g_@@_alternative_values_prop { red } { 1 , 0 , 0 }
+\prop_gput:Nnn \g_@@_alternative_values_prop { green } { 0 , 1 , 0 }
+\prop_gput:Nnn \g_@@_alternative_values_prop { blue } { 0 , 0 , 1 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\color_model_new:nnn, \@@_model_new:nnn}
+% Set up a new model: in general this has to be handled by a family-dependent
+% function. To avoid some \enquote{interesting} questions with casing, we
+% fold the case of the family name. The key--value list should always be
+% present, so we convert it up-front to a |prop|, then deal with the detail
+% on a per-family basis.
+% \begin{macrocode}
+\cs_new_protected:Npn \color_model_new:nnn #1#2#3
+ {
+ \exp_args:Nee \@@_model_new:nnn
+ { \tl_to_str:n {#1} }
+ { \str_casefold:n {#2} } {#3}
+ }
+\cs_new_protected:Npn \@@_model_new:nnn #1#2#3
+ {
+ \cs_if_exist:cTF { @@_parse_model_ #1 :w }
+ {
+ \msg_error:nnn { color } { model-already-defined } {#1}
+ }
+ {
+ \cs_if_exist:cTF { @@_model_ #2 :n }
+ {
+ \prop_set_from_keyval:Nn \l_@@_internal_prop {#3}
+ \use:c { @@_model_ #2 :n } {#1}
+ }
+ {
+ \msg_error:nnn { color } { unknown-model-type } {#2}
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_model_init:nnn, \@@_model_init:nne}
+% A shared auxiliary to do the basics of setting up a new model: reserve a
+% number, create a white-equivalent, set up links to the backend.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_init:nnn #1#2#3
+ {
+ \int_gincr:N \g_@@_model_int
+ \clist_map_inline:nn { fill , stroke , select }
+ {
+ \cs_new_protected:cpe { @@_backend_ ##1 _ #1 :n } ####1
+ {
+ \exp_not:c { @@_backend_ ##1 _ #2 :nn }
+ { color \int_use:N \g_@@_model_int } {####1}
+ }
+ }
+ \cs_new_protected:cpe { @@_model_ #1 _white: }
+ {
+ \prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#1}
+ { \exp_not:n {#3} }
+ \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0
+ { \group_insert_after:N \exp_not:c { @@_model_ #1 _ white: } }
+ }
+ \use:c { @@_model_ #1 _white: }
+ }
+\cs_generate_variant:Nn \@@_model_init:nnn { nne }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_model_separation:n}
+% \begin{macro}{\@@_model_separation:nn}
+% \begin{macro}{\@@_model_separation:nnn}
+% \begin{macro}{\@@_model_separation:w}
+% \begin{macro}
+% {
+% \@@_model_separation_cmyk:nnnnnn ,
+% \@@_model_separation_gray:nnnnnn ,
+% \@@_model_separation_rgb:nnnnnn
+% }
+% \begin{macro}{\@@_model_convert:nnn}
+% \begin{macro}{\@@_model_separation_CIELAB:nnnnnn}
+% \begin{macro}{\@@_model_separation_CIELAB:nnnnnnn}
+% Separations must have a \enquote{real} name, which is pretty easy to find.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_separation:n #1
+ {
+ \prop_get:NnNTF \l_@@_internal_prop { name }
+ \l_@@_internal_tl
+ {
+ \exp_args:NV \@@_model_separation:nn
+ \l_@@_internal_tl {#1}
+ }
+ {
+ \msg_error:nnn { color }
+ { separation-requires-name } {#1}
+ }
+ }
+% \end{macrocode}
+% We have two keys to find at this stage: the alternative space model
+% and linked values.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_separation:nn #1#2
+ {
+ \prop_get:NnNTF \l_@@_internal_prop { alternative-model }
+ \l_@@_internal_tl
+ {
+ \exp_args:NV \@@_model_separation:nnn
+ \l_@@_internal_tl {#2} {#1}
+ }
+ {
+ \msg_error:nnn { color }
+ { separation-alternative-model } {#2}
+ }
+ }
+\cs_new_protected:Npn \@@_model_separation:nnn #1#2#3
+ {
+ \cs_if_exist:cTF { @@_model_separation_ #1 :nnnnnn }
+ {
+ \prop_get:NnNTF \l_@@_internal_prop { alternative-values }
+ \l_@@_internal_tl
+ {
+ \exp_after:wN \@@_model_separation:w \l_@@_internal_tl
+ , 0 , 0 , 0 , 0 \s_@@_stop {#2} {#3} {#1}
+ }
+ {
+ \msg_error:nnn { color }
+ { separation-alternative-values } {#2}
+ }
+ }
+ {
+ \msg_error:nnn { color }
+ { unknown-alternative-model } {#1}
+ }
+ }
+% \end{macrocode}
+% As each alternative space leads to a different requirement for conversion,
+% and as there are only a small number of choices, we manually split the data
+% and then set up. Notice that mixing tints is really just the same
+% as mixing \texttt{gray}. The \texttt{white} color is special, as it allows
+% tints to be adjusted without an additional color space. To make sure the
+% data is set for that at all group levels, we need to work on a per-level
+% basis. Within the output, only the set-up needs the \enquote{real} name
+% of the colorspace: we use a simple tracking number for general usage
+% as this is a clear namespace without issues of escaping chars.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_separation:w
+ #1 , #2 , #3 , #4 , #5 \s_@@_stop #6#7#8
+ {
+ \@@_model_init:nnn {#6} { separation } { 0 }
+ \cs_new_eq:cN { @@_parse_mix_ #6 :nw } \@@_parse_mix_gray:nw
+ \cs_new:cpn { @@_parse_model_ #6 :w } ##1 , ##2 \s_@@_stop
+ { {#6} { \@@_parse_number:n {##1} } }
+ \use:c { @@_model_separation_ #8 :nnnnnn }
+ {#6} {#7} {#1} {#2} {#3} {#4}
+ \prop_gput:Nnn \g_@@_alternative_model_prop {#6} {#8}
+ \prop_gput:Nne \g_@@_colorants_prop {#6}
+ { \str_convert_pdfname:n {#7} }
+ }
+\cs_new_protected:Npn \@@_model_separation_cmyk:nnnnnn #1#2#3#4#5#6
+ {
+ \tl_const:cn { c_@@_fallback_ #1 _tl } { cmyk }
+ \cs_new:cpn { @@_convert_ #1 _cmyk:w } ##1 \s_@@_stop
+ {
+ \fp_eval:n {##1 * #3} ~
+ \fp_eval:n {##1 * #4} ~
+ \fp_eval:n {##1 * #5} ~
+ \fp_eval:n {##1 * #6}
+ }
+ \cs_new:cpn { @@_convert_cmyk_ #1 :w } ##1 \s_@@_stop { 1 }
+ \prop_gput:Nnn \g_@@_alternative_values_prop {#1} { #3 , #4 , #5 , #6 }
+ \@@_backend_separation_init:nnnnn {#2} { /DeviceCMYK } { }
+ { 0 ~ 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 ~ #6 }
+ }
+\cs_new_protected:Npn \@@_model_separation_rgb:nnnnnn #1#2#3#4#5#6
+ {
+ \tl_const:cn { c_@@_fallback_ #1 _tl } { rgb }
+ \cs_new:cpn { @@_convert_ #1 _rgb:w } ##1 \s_@@_stop
+ {
+ \fp_eval:n {##1 * #3} ~
+ \fp_eval:n {##1 * #4} ~
+ \fp_eval:n {##1 * #5}
+ }
+ \cs_new:cpn { @@_convert_rgb_ #1 :w } ##1 \s_@@_stop { 1 }
+ \prop_gput:Nnn \g_@@_alternative_values_prop {#1} { #3 , #4 , #5 }
+ \@@_backend_separation_init:nnnnn {#2} { /DeviceRGB } { }
+ { 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 }
+ }
+\cs_new_protected:Npn \@@_model_separation_gray:nnnnnn #1#2#3#4#5#6
+ {
+ \tl_const:cn { c_@@_fallback_ #1 _tl } { gray }
+ \cs_new:cpn { @@_convert_ #1 _gray:w } ##1 \s_@@_stop
+ { \fp_eval:n {##1 * #3} }
+ \cs_new:cpn { @@_convert_gray_ #1 :w } ##1 \s_@@_stop { 1 }
+ \prop_gput:Nnn \g_@@_alternative_values_prop {#1} {#3}
+ \@@_backend_separation_init:nnnnn {#2} { /DeviceGray } { } { 0 } {#3}
+ }
+% \end{macrocode}
+% Generic model conversion \emph{via} an alternative intermediate.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_convert:nnn #1#2#3
+ {
+ \cs_new:cpe { @@_convert_ #1 _ #3 :w } ##1 \s_@@_stop
+ {
+ \exp_not:N \exp_args:NNe \exp_not:N \use:nn
+ \exp_not:c { @@_convert_ #2 _ #3 :w }
+ { \exp_not:c { @@_convert_ #1 _ #2 :w } ##1 \s_@@_stop }
+ \c_space_tl \exp_not:N \s_@@_stop
+ }
+ }
+% \end{macrocode}
+% Setting up for CIELAB needs a bit more work: there is the illuminant and
+% the need for an appropriate object.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_separation_CIELAB:nnnnnn #1#2#3#4#5#6
+ {
+ \prop_get:NnNF \l_@@_internal_prop { illuminant }
+ \l_@@_internal_tl
+ {
+ \msg_error:nnn { color }
+ { CIELAB-requires-illuminant } {#1}
+ \tl_set:Nn \l_@@_internal_tl { d50 }
+ }
+ \exp_args:NV \@@_model_separation_CIELAB:nnnnnnn
+ \l_@@_internal_tl {#1} {#2} {#3} {#4} {#5} {#6}
+ }
+% \end{macrocode}
+% If a CIELAB space is being set up, we need the illuminant, then create
+% the appropriate set up. At present, this doesn't include \texttt{BlackPoint}
+% or \texttt{Range} data, but that may be added later. As CIELAB colors
+% cannot be converted to anything else, we fallback to producing black in the
+% gray colorspace: the user should set up a second model for colors set up this way.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_separation_CIELAB:nnnnnnn #1#2#3#4#5#6#7
+ {
+ \tl_if_exist:cTF { c_@@_model_whitepoint_CIELAB_ #1 _tl }
+ {
+ \@@_backend_separation_init_CIELAB:nnn {#1} {#3} { #4 ~ #5 ~ #6 }
+ \tl_const:cn { c_@@_fallback_ #2 _tl } { gray }
+ \cs_new:cpn { @@_convert_ #2 _gray:w } ##1 \s_@@_stop
+ { 0 }
+ \cs_new:cpn { @@_convert_gray_ #2 :w } ##1 \s_@@_stop
+ { 1 }
+ }
+ {
+ \msg_error:nnn { color }
+ { unknown-CIELAB-illuminant } {#1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_model_devicen:n}
+% \begin{macro}{\@@_model_devicen:nn}
+% \begin{macro}{\@@_model_devicen:nnn}
+% \begin{macro}{\@@_model_devicen:nnnn}
+% \begin{macro}
+% {
+% \@@_model_devicen_parse_1:nn ,
+% \@@_model_devicen_parse_2:nn ,
+% \@@_model_devicen_parse_3:nn ,
+% \@@_model_devicen_parse_4:nn ,
+% \@@_model_devicen_parse_generic:nn
+% }
+% \begin{macro}[EXP]{\@@_model_devicen_parse:nw}
+% \begin{macro}[EXP]{\@@_model_devicen_mix:nw}
+% \begin{macro}{\@@_model_devicen_init:nnn}
+% \begin{macro}{\@@_model_devicen_init:nnnn}
+% \begin{macro}{\@@_model_devicen_tranform:w}
+% \begin{macro}
+% {
+% \@@_model_devicen_tranform_1:nnnnn ,
+% \@@_model_devicen_tranform_3:nnnnn ,
+% \@@_model_devicen_tranform_4:nnnnn ,
+% }
+% \begin{macro}{\@@_model_devicen_tranform:nnn}
+% \begin{macro}[EXP]{\@@_model_devicen_colorant:n}
+% \begin{macro}{\@@_model_devicen_convert:nnn}
+% \begin{macro}
+% {
+% \@@_model_devicen_convert_cmyk:n ,
+% \@@_model_devicen_convert_gray:n ,
+% \@@_model_devicen_convert_rgb:n
+% }
+% \begin{macro}{\@@_model_devicen_convert:nnnn}
+% \begin{macro}[EXP]{\@@_model_devicen_convert:n, \@@_model_devicen_convert_aux:n}
+% \begin{macro}[EXP]{\@@_model_devicen_convert:w}
+% \begin{macro}[EXP]{\@@_convert_devicen_cmyk:nnnnw}
+% \begin{macro}[EXP]{\@@_convert_devicen_cmyk:nnnnnnnnn}
+% \begin{macro}[EXP]{\@@_convert_devicen_cmyk_aux:nnnnw}
+% \begin{macro}[EXP]{\@@_convert_devicen_gray:nw}
+% \begin{macro}[EXP]{\@@_convert_devicen_gray:nnn}
+% \begin{macro}[EXP]{\@@_convert_devicen_gray_aux:nw}
+% \begin{macro}[EXP]{\@@_convert_devicen_rgb:nnnw}
+% \begin{macro}[EXP]{\@@_convert_devicen_rgb:nnnnnnn}
+% \begin{macro}[EXP]{\@@_convert_devicen_rgb_aux:nnnw}
+% We require a list of component names here: one might call them colorants,
+% but it's convenient to use \TeX{} names instead so we slightly adjust the
+% terminology.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_devicen:n #1
+ {
+ \prop_get:NnNTF \l_@@_internal_prop { names }
+ \l_@@_internal_tl
+ {
+ \exp_args:NV \@@_model_devicen:nn
+ \l_@@_internal_tl {#1}
+ }
+ {
+ \msg_error:nnn { color }
+ { DeviceN-requires-names } {#1}
+ }
+ }
+% \end{macrocode}
+% All valid models will have an alternative listed, either hard-coded for
+% the core device ones, or dynamically added for Separations, etc.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_devicen:nn #1#2
+ {
+ \tl_clear:N \l_@@_model_tl
+ \clist_map_inline:nn {#1}
+ {
+ \prop_get:NnNTF \g_@@_alternative_model_prop {##1}
+ \l_@@_internal_tl
+ {
+ \tl_if_empty:NTF \l_@@_model_tl
+ { \tl_set_eq:NN \l_@@_model_tl \l_@@_internal_tl }
+ {
+ \str_if_eq:VVF \l_@@_model_tl \l_@@_internal_tl
+ {
+ \msg_error:nnn { color }
+ { DeviceN-inconsistent-alternative }
+ {#2}
+ \clist_map_break:n { \use_none:nnnn }
+ }
+ }
+ }
+ {
+ \str_if_eq:nnF {##1} { none }
+ {
+ \msg_error:nnn { color }
+ { DeviceN-no-alternative }
+ {#2}
+ }
+ }
+ }
+ \tl_if_empty:NTF \l_@@_model_tl
+ {
+ \msg_error:nnn { color }
+ { DeviceN-no-alternative } {#2}
+ }
+ { \exp_args:NV \@@_model_devicen:nnn \l_@@_model_tl {#1} {#2} }
+ }
+% \end{macrocode}
+% We now complete the data we require by first finding out how many
+% colorants there are, then moving on to begin constructing the function
+% required to map to the alternative color space.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_devicen:nnn #1#2#3
+ {
+ \exp_args:Ne \@@_model_devicen:nnnn
+ { \clist_count:n {#2} } {#1} {#2} {#3}
+ }
+% \end{macrocode}
+% At this stage, we have checked everything is in place, so we can set up
+% the \TeX{} and backend data structures. As for separations, it's not really
+% possible in general to have a fallback, so we simply provide
+% \enquote{black} for each element.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_devicen:nnnn #1#2#3#4
+ {
+ \@@_model_init:nne {#4} { devicen }
+ {
+ 0 \prg_replicate:nn { #1 - 1 } { ~ 0 }
+ }
+ \cs_if_exist_use:cF { @@_model_devicen_parse_ #1 :nn }
+ { \@@_model_devicen_parse_generic:nn }
+ {#4} {#1}
+ \@@_model_devicen_init:nnn {#1} {#2} {#3}
+ \@@_model_devicen_convert:nnne {#4} {#2} {#3}
+ {
+ 1 \prg_replicate:nn { #1 - 1 } { ~ 1 }
+ }
+ }
+% \end{macrocode}
+% For short lists of DeviceN colors, we can use hand-tuned parsing. This
+% lines up with other models, where we allow for up to four components. For
+% larger spaces, rather than limit artificially, we use a somewhat slow
+% approach based on open-ended commas-lists.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_model_devicen_parse_1:nn } #1#2
+ {
+ \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 \s_@@_stop
+ { {#1} { \@@_parse_number:n {##1} } }
+ \cs_new_eq:cN { @@_parse_mix_ #1 :nw } \@@_parse_mix_gray:nw
+ }
+\cs_new_protected:cpn { @@_model_devicen_parse_2:nn } #1#2
+ {
+ \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 , ##3 \s_@@_stop
+ { {#1} { \@@_parse_number:n {##1} ~ \@@_parse_number:n {##2} } }
+ \cs_new:cpn { @@_parse_mix_ #1 :nw }
+ ##1##2 ~ ##3 \s_@@_mark ##4 ~ ##5 \s_@@_stop
+ {
+ \fp_eval:n { ##2 * ##1 + ##4 * ( 1 - ##1 ) } \c_space_tl
+ \fp_eval:n { ##3 * ##1 + ##5 * ( 1 - ##1 ) }
+ }
+ }
+\cs_new_protected:cpn { @@_model_devicen_parse_3:nn } #1#2
+ {
+ \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 , ##3 , ##4 \s_@@_stop
+ {
+ {#1}
+ {
+ \@@_parse_number:n {##1} ~
+ \@@_parse_number:n {##2} ~
+ \@@_parse_number:n {##3}
+ }
+ }
+ \cs_new_eq:cN { @@_parse_mix_ #1 :nw } \@@_parse_mix_rgb:nw
+ }
+\cs_new_protected:cpn { @@_model_devicen_parse_4:nn } #1#2
+ {
+ \cs_new:cpn { @@_parse_model_ #1 :w }
+ ##1 , ##2 , ##3 , ##4 , ##5 \s_@@_stop
+ {
+ {#1}
+ {
+ \@@_parse_number:n {##1} ~
+ \@@_parse_number:n {##2} ~
+ \@@_parse_number:n {##3} ~
+ \@@_parse_number:n {##4}
+ }
+ }
+ \cs_new_eq:cN { @@_parse_mix_ #1 :nw } \@@_parse_mix_cmyk:nw
+ }
+\cs_new_protected:Npn \@@_model_devicen_parse_generic:nn #1#2
+ {
+ \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 \s_@@_stop
+ {
+ {#1}
+ { \@@_model_devicen_parse:nw {#2} ##1 , ##2 , \q_nil , \s_@@_stop }
+ }
+ \cs_new:cpe { @@_parse_mix_ #1 :nw }
+ ##1 ##2 \s_@@_mark ##3 \s_@@_stop
+ {
+ \exp_not:N \@@_model_devicen_mix:nw {##1}
+ ##2 \c_space_tl \exp_not:N \q_nil \c_space_tl \exp_not:N \s_@@_mark
+ ##3 \c_space_tl \exp_not:N \q_nil \c_space_tl \exp_not:N \s_@@_stop
+ }
+ }
+\cs_new:Npn \@@_model_devicen_parse:nw #1#2 , #3 \s_@@_stop
+ {
+ \int_compare:nNnT {#1} > 0
+ {
+ \quark_if_nil:nTF {#2}
+ { \prg_replicate:nn {#1} { 0 ~ } }
+ {
+ \@@_parse_number:n {#2}
+ \int_compare:nNnT {#1} > 1 { ~ }
+ \exp_args:Nf \@@_model_devicen_parse:nw
+ { \int_eval:n { #1 - 1 } } #3 \s_@@_stop
+ }
+ }
+ }
+\cs_new:Npn \@@_model_devicen_mix:nw #1#2 ~ #3 \s_@@_mark #4 ~ #5 \s_@@_stop
+ {
+ \fp_eval:n { #2 * #1 + #4 * ( 1 - #1 ) }
+ \quark_if_nil:oF { \tl_head:w #3 \q_stop }
+ {
+ \c_space_tl
+ \@@_model_devicen_mix:nw {#1} #3 \s_@@_mark #5 \s_@@_stop
+ }
+ }
+% \end{macrocode}
+% To construct the tint transformation, we have to use PostScript. The
+% aim is to have the final tint for each device colorant as
+% \[
+% 1 - \prod_{n} (1 - X_{n} D_{X_{n}})
+% \]
+% where $X$ is a DeviceN colorant and $D$ is the amount of device colorant
+% that the DeviceN colorant maps to. At the start of the process, the
+% PostScript stack will contain the $X_{n}$ values, whilst we have the
+% $D$ values on a per-DeviceN colorant basis. The more convenient approach
+% for us is therefore to take each DeviceN colorant in turn and find the
+% value $1 - X_{n} D_{X_{n}}$, multiplying as we go, and finalise with the
+% subtraction. That contrasts to \pkg{colorspace}: it splits the process
+% up by process color, which works better when you have a fixed list
+% of colorants. (\pkg{colorspace} only supports up to $4$ DeviceN colors,
+% and only \texttt{cmyk} as the alternative space.) To set this up,
+% we first need to know the number of values in the target color space:
+% this is easily handled as there are a very small range of possibles.
+% Once we have that information, it's relatively easy to build the required
+% PostScript using some generic code.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_devicen_init:nnn #1#2#3
+ {
+ \exp_args:Ne \@@_model_devicen_init:nnnn
+ {
+ \str_case:nn {#2}
+ {
+ { cmyk } { 4 }
+ { gray } { 1 }
+ { rgb } { 3 }
+ }
+ }
+ {#1} {#2} {#3}
+ }
+% \end{macrocode}
+% As we always need to split the alternative values into parts, we use a
+% shared auxiliary and only use a minimal difference between code paths.
+% Construction of the tint transformation is as far as possible done using
+% loops, which means there are some inefficiencies for device colors in
+% the \texttt{DeviceN} space: we roll the stack one-at-a-time even if there
+% is a potential shortcut. However, that way there is nothing to special-case.
+% Once this is sorted, we can write the tint transform object, which will
+% remain as the last object until we sort out the final step: the colorant
+% list.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_devicen_init:nnnn #1#2#3#4
+ {
+ \tl_set:Ne \l_@@_internal_tl
+ { \prg_replicate:nn {#1} { 1.0 ~ } }
+ \int_zero:N \l_@@_internal_int
+ \clist_map_inline:nn {#4}
+ {
+ \int_incr:N \l_@@_internal_int
+ \prop_get:NnN \g_@@_alternative_values_prop {##1}
+ \l_@@_value_tl
+ \exp_after:wN \@@_model_devicen_transform:w
+ \l_@@_value_tl , 0 , 0 , 0 , \s_@@_stop {#1} {#2}
+ }
+ \tl_put_right:Ne \l_@@_internal_tl
+ {
+ \prg_replicate:nn {#1}
+ { neg ~ 1.0 ~ add ~ #1 ~ -1 ~ roll ~ }
+ \int_eval:n { #2 + #1 } ~ #1 ~ roll
+ \prg_replicate:nn {#2} { ~ pop } ~
+ #1 ~ 1 ~ roll
+ }
+ \use:e
+ {
+ \@@_backend_devicen_init:nnn
+ {
+ \clist_map_function:nN {#4}
+ \@@_model_devicen_colorant:n
+ }
+ {
+ \str_case:nn {#3}
+ {
+ { cmyk } { /DeviceCMYK }
+ { gray } { /DeviceGray }
+ { rgb } { /DeviceRGB }
+ }
+ }
+ { \exp_not:V \l_@@_internal_tl }
+ }
+ }
+\cs_new_protected:Npn \@@_model_devicen_transform:w
+ #1 , #2 , #3 , #4 , #5 \s_@@_stop #6#7
+ {
+ \use:c { @@_model_devicen_transform_ #6 :nnnnn }
+ {#1} {#2} {#3} {#4} {#7}
+ }
+\cs_new_protected:cpn { @@_model_devicen_transform_1:nnnnn } #1#2#3#4#5
+ { \@@_model_devicen_transform:nnn {#5} { 1 } {#1} }
+\cs_new_protected:cpn { @@_model_devicen_transform_3:nnnnn } #1#2#3#4#5
+ {
+ \clist_map_inline:nn { #1 , #2 , #3 }
+ { \@@_model_devicen_transform:nnn {#5} { 3 } {##1} }
+ }
+\cs_new_protected:cpn { @@_model_devicen_transform_4:nnnnn } #1#2#3#4#5
+ {
+ \clist_map_inline:nn { #1 , #2 , #3 , #4 }
+ { \@@_model_devicen_transform:nnn {#5} { 4 } {##1} }
+ }
+\cs_new_protected:Npn \@@_model_devicen_transform:nnn #1#2#3
+ {
+ \tl_put_right:Ne \l_@@_internal_tl
+ {
+ \fp_compare:nNnF {#3} = \c_zero_fp
+ {
+ \int_eval:n { #1 - \l_@@_internal_int + #2 } ~ index ~
+ -#3 ~ mul ~ 1.0 ~ add ~ mul ~
+ }
+ #2 ~ -1 ~ roll ~
+ }
+ }
+\cs_new:Npn \@@_model_devicen_colorant:n #1
+ {
+ / \prop_item:Nn \g_@@_colorants_prop {#1} ~
+ }
+% \end{macrocode}
+% Here we need to set up conversion from the DeviceN space to the alternative
+% at the \TeX{} level. This also means supplying methods for inter-converting
+% to other parameter-based spaces. Essentially the approach is exactly the same
+% as the PostScript, just expressed in \TeX{} terms.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_devicen_convert:nnnn #1#2#3
+ {
+ \use:c { @@_model_devicen_convert_ #2 :nnn } {#1} {#3}
+ }
+\cs_generate_variant:Nn \@@_model_devicen_convert:nnnn { nnne }
+\cs_new_protected:Npn \@@_model_devicen_convert_cmyk:nnn #1#2
+ {
+ \tl_const:cn { c_@@_fallback_ #1 _tl } { cmyk }
+ \@@_model_devicen_convert:nnnnn {#1} { cmyk } { 4 } {#2}
+ }
+\cs_new_protected:Npn \@@_model_devicen_convert_gray:nnn #1#2
+ {
+ \tl_const:cn { c_@@_fallback_ #1 _tl } { gray }
+ \@@_model_devicen_convert:nnnnn {#1} { gray } { 1 } {#2}
+ }
+\cs_new_protected:Npn \@@_model_devicen_convert_rgb:nnn #1#2
+ {
+ \tl_const:cn { c_@@_fallback_ #1 _tl } { rgb }
+ \@@_model_devicen_convert:nnnnn {#1} { rgb } { 3 } {#2}
+ }
+\cs_new_protected:Npn \@@_model_devicen_convert:nnnnn #1#2#3#4#5
+ {
+ \cs_new:cpn { @@_convert_ #2 _ #1 :w } ##1 \s_@@_stop {#5}
+ \cs_new:cpe { @@_convert_ #1 _ #2 :w } ##1 \s_@@_stop
+ {
+ \exp_not:c { @@_convert_devicen_ #2 : \prg_replicate:nn {#3} { n } w }
+ \prg_replicate:nn {#3} { { 1 } }
+ ##1 ~ \exp_not:N \s_@@_mark
+ \clist_map_function:nN {#4} \@@_model_devicen_convert:n
+ {}
+ \exp_not:N \s_@@_stop
+ }
+ }
+\cs_new:Npn \@@_model_devicen_convert:n #1
+ {
+ {
+ \exp_args:Ne \@@_model_devicen_convert_aux:n
+ { \prop_item:Nn \g_@@_alternative_values_prop {#1} }
+ }
+ }
+\cs_new:Npn \@@_model_devicen_convert_aux:n #1
+ { \@@_model_devicen_convert_aux:w #1 , , , , \s_@@_stop }
+\cs_new:Npn \@@_model_devicen_convert_aux:w #1 , #2 , #3 , #4 , #5 \s_@@_stop
+ {
+ {#1}
+ \tl_if_blank:nF {#2}
+ {
+ {#2}
+ \tl_if_blank:nF {#3}
+ {
+ {#3}
+ \tl_if_blank:nF {#4} { {#4} }
+ }
+ }
+ }
+\cs_new:Npn \@@_convert_devicen_cmyk:nnnnw
+ #1#2#3#4#5 ~ #6 \s_@@_mark #7#8 \s_@@_stop
+ {
+ \@@_convert_devicen_cmyk:nnnnnnnnn {#5} {#1} {#2} {#3} {#4} #7
+ #6 \s_@@_mark #8 \s_@@_stop
+ }
+\cs_new:Npn \@@_convert_devicen_cmyk:nnnnnnnnn #1#2#3#4#5#6#7#8#9
+ {
+ \use:e
+ {
+ \exp_not:N \@@_convert_devicen_cmyk_aux:nnnnw
+ { \fp_eval:n { #2 * (1 - (#1 * #6)) } }
+ { \fp_eval:n { #3 * (1 - (#1 * #7)) } }
+ { \fp_eval:n { #4 * (1 - (#1 * #8)) } }
+ { \fp_eval:n { #5 * (1 - (#1 * #9)) } }
+ }
+ }
+\cs_new:Npn \@@_convert_devicen_cmyk_aux:nnnnw
+ #1#2#3#4 #5 \s_@@_mark #6 \s_@@_stop
+ {
+ \tl_if_blank:nTF {#5}
+ {
+ \fp_eval:n { 1 - #1 } ~
+ \fp_eval:n { 1 - #2 } ~
+ \fp_eval:n { 1 - #3 } ~
+ \fp_eval:n { 1 - #4 }
+ }
+ {
+ \@@_convert_devicen_cmyk:nnnnw {#1} {#2} {#3} {#4}
+ #5 \s_@@_mark #6 \s_@@_stop
+ }
+ }
+\cs_new:Npn \@@_convert_devicen_gray:nw
+ #1#2 ~ #3 \s_@@_mark #4#5 \s_@@_stop
+ {
+ \@@_convert_devicen_gray:nnn {#2} {#1} #4
+ #3 \s_@@_mark #5 \s_@@_stop
+ }
+\cs_new:Npn \@@_convert_devicen_gray:nnn #1#2#3
+ {
+ \exp_arsgs:Ne \@@_convert_devicen_gray_aux:nw
+ { \fp_eval:n { #2 * (1 - (#1 * #3)) } }
+ }
+\cs_new:Npn \@@_convert_devicen_gray_aux:nw
+ #1 #2 \s_@@_mark #3 \s_@@_stop
+ {
+ \tl_if_blank:nTF {#2}
+ { \fp_eval:n { 1 - #1 } }
+ {
+ \@@_convert_devicen_gray:nw {#1}
+ #2 \s_@@_mark #3 \s_@@_stop
+ }
+ }
+\cs_new:Npn \@@_convert_devicen_rgb:nnnw
+ #1#2#3#4 ~ #5 \s_@@_mark #6#7 \s_@@_stop
+ {
+ \@@_convert_devicen_rgb:nnnnnnn {#4} {#1} {#2} {#3} #6
+ #5 \s_@@_mark #7 \s_@@_stop
+ }
+\cs_new:Npn \@@_convert_devicen_rgb:nnnnnnn #1#2#3#4#5#6#7
+ {
+ \use:e
+ {
+ \exp_not:N \@@_convert_devicen_rgb_aux:nnnw
+ { \fp_eval:n { #2 * (1 - (#1 * #5)) } }
+ { \fp_eval:n { #3 * (1 - (#1 * #6)) } }
+ { \fp_eval:n { #4 * (1 - (#1 * #7)) } }
+ }
+ }
+\cs_new:Npn \@@_convert_devicen_rgb_aux:nnnw
+ #1#2#3 #4 \s_@@_mark #5 \s_@@_stop
+ {
+ \tl_if_blank:nTF {#4}
+ {
+ \fp_eval:n { 1 - #1 } ~
+ \fp_eval:n { 1 - #2 } ~
+ \fp_eval:n { 1 - #3 }
+ }
+ {
+ \@@_convert_devicen_rgb:nnnw {#1} {#2} {#3}
+ #4 \s_@@_mark #5 \s_@@_stop
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\c_@@_icc_colorspace_signatures_prop}
+% The signatures in the ICC file header indicating the underlying
+% colorspace. We map it to three values: The number of components,
+% the values corresponding to white, and the range.
+% \begin{macrocode}
+\prop_const_from_keyval:Nn \c_@@_icc_colorspace_signatures_prop
+ {
+% Gray
+ 47524159 = {1} {1} {0} {},
+% RGB
+ 52474220 = {3} {0~0~0} {1~1~1} {},
+% CMYK
+ 434D594B = {4} {0~0~0~1} {0~0~0~0} {},
+% Lab
+ 4C616220 = {3} {0~0~0} {100~0~0} {0~100~-128~127~-128~127}
+ }
+% \end{macrocode}
+% \end{variable}
+% \begin{macro}{\@@_model_iccbased:n}
+% \begin{macro}{\@@_model_iccbased:nn}
+% \begin{macro}{\@@_model_iccbased:nnn, \@@_model_iccbased_aux:nnn}
+% For an ICC profile, we need a file name and a number of components. The
+% file name is processed here so the backend can treat it as a string.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_iccbased:n #1
+ {
+ \prop_get:NnNTF \l_@@_internal_prop { file }
+ \l_@@_internal_tl
+ {
+ \exp_args:NV \@@_model_iccbased:nn
+ \l_@@_internal_tl {#1}
+ }
+ {
+ \msg_error:nnn { color }
+ { ICCBased-requires-file } {#1}
+ }
+ }
+\cs_new_protected:Npn \@@_model_iccbased:nn #1#2
+ {
+ \prop_get:NeNTF \c_@@_icc_colorspace_signatures_prop
+ { \file_hex_dump:nnn { #1 } { 17 } { 20 } } \l_@@_internal_tl
+ {
+ \exp_last_unbraced:NV \@@_model_iccbased_aux:nnnnnn
+ \l_@@_internal_tl { #2 } { #1 }
+ }
+ {
+ \msg_error:nnn { color }
+ { ICCBased-unsupported-colorspace } {#2}
+ }
+ }
+% \end{macrocode}
+% Here, we can use the same internals as for DeviceN approach as we know the
+% number of components. No conversion is possible, so there is no need
+% to worry about that at all.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_iccbased_aux:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_model_init:nnn {#5} { iccbased } {#3}
+ \tl_const:cn { c_@@_fallback_ #5 _tl } { gray }
+ \cs_new:cpn { @@_convert_ #5 _gray:w } ##1 \s_@@_stop { 0 }
+ \cs_new:cpn { @@_convert_gray_ #5 :w } ##1 \s_@@_stop { #2 }
+ \use:c { @@_model_devicen_parse_ #1 :nn } {#5} {#1}
+ \exp_args:Ne \@@_backend_iccbased_init:nnn
+ { \file_full_name:n {#6} } {#1} {#4}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Applying profiles}
+%
+% \begin{macro}{\color_profile_apply:nn, \@@_profile_apply:nn}
+% \begin{macro}
+% {
+% \@@_profile_apply_gray:n ,
+% \@@_profile_apply_rgb:n ,
+% \@@_profile_apply_cmyk:n
+% }
+% With a limited range of outcomes, this is largely about getting data to the
+% backend.
+% \begin{macrocode}
+\cs_new_protected:Npn \color_profile_apply:nn #1#2
+ {
+ \exp_args:Ne \@@_profile_apply:nn
+ { \file_full_name:n {#1} } {#2}
+ }
+\cs_new_protected:Npn \@@_profile_apply:nn #1#2
+ {
+ \cs_if_exist_use:cF { @@_profile_apply_ \tl_to_str:n {#2} :n }
+ {
+ \msg_error:nnn { color } { ICC-Device-unknown } {#2}
+ \use_none:n
+ }
+ {#1}
+ }
+\cs_new_protected:Npn \@@_profile_apply_gray:n #1
+ {
+ \int_gincr:N \g_@@_model_int
+ \@@_backend_iccbased_device:nnn {#1} { Gray } { 1 }
+ }
+\cs_new_protected:Npn \@@_profile_apply_rgb:n #1
+ {
+ \int_gincr:N \g_@@_model_int
+ \@@_backend_iccbased_device:nnn {#1} { RGB } { 3 }
+ }
+\cs_new_protected:Npn \@@_profile_apply_cmyk:n #1
+ {
+ \int_gincr:N \g_@@_model_int
+ \@@_backend_iccbased_device:nnn {#1} { CMYK } { 4 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Diagnostics}
+%
+% \begin{macro}{\color_show:n, \color_log:n, \@@_show:Nn}
+% \begin{macro}[EXP]{\@@_show:n}
+% Extract the information about a color and format for the user: the approach
+% is similar to the keys module here.
+% \begin{macrocode}
+\cs_new_protected:Npn \color_show:n
+ { \@@_show:Nn \msg_show:nneeee }
+\cs_new_protected:Npn \color_log:n
+ { \@@_show:Nn \msg_log:nneeee }
+\cs_new_protected:Npn \@@_show:Nn #1#2
+ {
+ #1 { color } { show }
+ {#2}
+ {
+ \color_if_exist:nT {#2}
+ {
+ \exp_args:Nv \@@_show:n { l_@@_named_ #2 _tl }
+ \prop_map_function:cN
+ { l_@@_named_ #2 _prop }
+ \msg_show_item_unbraced:nn
+ }
+ }
+ { }
+ { }
+ }
+\cs_new:Npn \@@_show:n #1
+ {
+ \msg_show_item_unbraced:nn { model } {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% \begin{macrocode}
+\msg_new:nnnn { color } { CIELAB-requires-illuminant }
+ { CIELAB~color~space~'#1'~require~an~illuminant. }
+ {
+ LaTeX~has~been~asked~to~create~a~separation~color~space~using~
+ CIELAB~specifications,~but~no~\\ \\
+ \iow_indent:n { illuminant~=~<basis> }
+ \\ \\
+ key~was~given~with~the~correct~information.~LaTeX~will~use~illuminant~
+ 'd50'~for~recovery.
+ }
+\msg_new:nnnn { color } { conversion-not-available }
+ { No~model~conversion~available~from~'#1'~to~'#2'. }
+ {
+ LaTeX~has~been~asked~to~convert~a~color~from~model~'#1'~
+ to~model'#2',~but~there~is~no~method~available~to~do~that.
+ }
+\msg_new:nnnn { color } { DeviceN-inconsistent-alternative }
+ { DeviceN~color~spaces~require~a~single~alternative~space. }
+ {
+ LaTeX~has~been~asked~to~create~a~DeviceN~color~space~'#1',~
+ but~the~constituent~colors~do~not~have~a~common~alternative~
+ color.
+ }
+\msg_new:nnnn { color } { DeviceN-no-alternative }
+ { DeviceN~color~spaces~require~an~alternative~space. }
+ {
+ LaTeX~has~been~asked~to~create~a~DeviceN~color~space~'#1',~
+ but~the~constituent~colors~do~not~all~have~a~device-based~alternative.
+ }
+\msg_new:nnnn { color } { DeviceN-requires-names }
+ { DeviceN~color~space~'#1'~require~a~list~of~names. }
+ {
+ LaTeX~has~been~asked~to~create~a~DeviceN~color~space,~
+ but~no~\\ \\
+ \iow_indent:n { names~=~<names> }
+ \\ \\
+ key~was~given~with~the~correct~information.
+ }
+\msg_new:nnnn { color } { ICC-Device-unknown }
+ { Unknown~device~color~space~'#1'. }
+ {
+ LaTeX~has~been~asked~to~apply~an~ICC~profile~but~the~device~color~space~
+ '#1'~is~unknown.
+ }
+\msg_new:nnnn { color } { ICCBased-unsupported-colorspace }
+ { ICCBased~color~space~'#1'~uses~an~unsupported~data~color~space. }
+ {
+ LaTeX~has~been~asked~to~create~a~ICCBased~colorspace,~but~the~
+ used~data~colorspace~is~not~supported.~ICC~profiles~used~for~
+ defining~a~ICCBased~colorspace~should~use~a~Lab,~RGB,~or~
+ CMYK~data~colorspace.~LaTeX~will~ignore~this~request.
+ }
+\msg_new:nnnn { color } { ICCBased-requires-file }
+ { ICCBased~color~space~'#1'~require~an~file. }
+ {
+ LaTeX~has~been~asked~to~create~an~ICCBased~color~space,~but~no~\\ \\
+ \iow_indent:n { file~=~<name> }
+ \\ \\
+ key~was~given~with~the~correct~information.~LaTeX~will~ignore~this~
+ request.
+ }
+\msg_new:nnnn { color } { model-already-defined }
+ { Color~model~'#1'~already~defined. }
+ {
+ LaTeX~was~asked~to~define~a~new~color~model~called~'#1',~but~
+ this~color~model~already~exists.
+ }
+\msg_new:nnnn { color } { out-of-range }
+ { Input~value~#1~out~of~range~[#2,~#3]. }
+ {
+ LaTeX~was~expecting~a~value~in~the~range~[#2,~#3]~as~part~of~a~color,~
+ but~you~gave~#1.~LaTeX~will~assume~you~meant~the~limit~of~the~range~
+ and~continue.
+ }
+\msg_new:nnnn { color } { separation-alternative-model }
+ { Separation~color~space~'#1'~require~an~alternative~model. }
+ {
+ LaTeX~has~been~asked~to~create~a~separation~color~space,~
+ but~no~\\ \\
+ \iow_indent:n { alternative-model~=~<model> }
+ \\ \\
+ key~was~given~with~the~correct~information.
+ }
+\msg_new:nnnn { color } { separation-alternative-values }
+ { Separation~color~space~'#1'~require~values~for~the~alternative~space. }
+ {
+ LaTeX~has~been~asked~to~create~a~separation~color~space,~
+ but~no~\\ \\
+ \iow_indent:n { alternative-values~=~<model> }
+ \\ \\
+ key~was~given~with~the~correct~information.
+ }
+\msg_new:nnnn { color } { separation-requires-name }
+ { Separation~color~space~'#1'~require~a~formal~name. }
+ {
+ LaTeX~has~been~asked~to~create~a~separation~color~space,~
+ but~no~\\ \\
+ \iow_indent:n { name~=~<formal~name> }
+ \\ \\
+ key~was~given~with~the~correct~information.
+ }
+\msg_new:nnn { color } { unhandled-model }
+ {
+ Unhandled~color~model~in~LaTeX2e~value~"#1":
+ \\ \\
+ falling~back~on~grayscale.
+ }
+\msg_new:nnnn { color } { unknown-color }
+ { Unknown~color~'#1'. }
+ {
+ LaTeX~has~been~asked~to~use~a~color~named~'#1',~
+ but~this~has~never~been~defined.
+ }
+\msg_new:nnnn { color } { unknown-alternative-model }
+ { Separation~color~space~'#1'~require~an~valid~alternative~space. }
+ {
+ LaTeX~has~been~asked~to~create~a~separation~color~space,~
+ but~the~model~given~as\\ \\
+ \iow_indent:n { alternative-model~=~<model> }
+ \\ \\
+ is~unknown.
+ }
+\msg_new:nnnn { color } { unknown-export-format }
+ { Unknown~export~format~'#1'. }
+ {
+ LaTeX~has~been~asked~to~export~a~color~in~format~'#1',~
+ but~this~has~never~been~defined.
+ }
+\msg_new:nnnn { color } { unknown-CIELAB-illuminant }
+ { Unknown~illuminant~model~'#1'. }
+ {
+ LaTeX~has~been~asked~to~use~create~a~color~space~using~CIELAB~
+ illuminant~'#1',~but~this~does~not~exist.
+ }
+\msg_new:nnnn { color } { unknown-model }
+ { Unknown~color~model~'#1'. }
+ {
+ LaTeX~has~been~asked~to~use~a~color~model~called~'#1',~
+ but~this~model~is~not~set~up.
+ }
+\msg_new:nnnn { color } { unknown-model-type }
+ { Unknown~color~model~type~'#1'. }
+ {
+ LaTeX~has~been~asked~to~create~a~new~color~model~called~'#1',~
+ but~this~type~of~model~was~never~set~up.
+ }
+\prop_gput:Nnn \g_msg_module_name_prop { color } { LaTeX }
+\prop_gput:Nnn \g_msg_module_type_prop { color } { }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnn { color } { show }
+ {
+ The~color~#1~
+ \tl_if_empty:nTF {#2}
+ { is~undefined. }
+ { has~the~properties: #2 }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3debug.dtx b/macros/latex-dev/required/l3kernel/l3debug.dtx
new file mode 100644
index 0000000000..6dbe13f96e
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3debug.dtx
@@ -0,0 +1,1478 @@
+% \iffalse meta-comment
+%
+%% File: l3debug.dtx
+%
+% Copyright (C) 2019-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3debug} module\\ Debugging support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3debug} implementation}
+%
+% Internal kernel functions that are only defined here are listed in
+% \pkg{l3kernel-functions},
+% see~\ref{sec:l3kernel-functions:l3debug-internals}.
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=debug>
+% \end{macrocode}
+%
+% Standard file identification.
+% \begin{macrocode}
+\ProvidesExplFile{l3debug.def}{2024-04-11}{}{L3 Debugging support}
+% \end{macrocode}
+%
+% \begin{variable}{\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_use_i_delimit_by_s_stop:nw}
+% Functions to gobble up to a scan mark.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_i_delimit_by_s_stop:nw #1 #2 \s_@@_stop {#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\q_@@_recursion_tail,\q_@@_recursion_stop}
+% Internal quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_recursion_tail
+\quark_new:N \q_@@_recursion_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_if_recursion_tail_stop:N}
+% Functions to query recursion quarks.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_none_delimit_by_q_recursion_stop:w
+ #1 \q_@@_recursion_stop { }
+\__kernel_quark_new_test:N \@@_if_recursion_tail_stop:N
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\debug_on:n, \debug_off:n, \@@_all_on:, \@@_all_off:}
+% \begin{macrocode}
+\cs_gset_protected:Npn \debug_on:n #1
+ {
+ \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} }
+ {
+ \cs_if_exist_use:cF { @@_ ##1 _on: }
+ { \msg_error:nnn { debug } { debug } {##1} }
+ }
+ }
+\cs_gset_protected:Npn \debug_off:n #1
+ {
+ \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} }
+ {
+ \cs_if_exist_use:cF { @@_ ##1 _off: }
+ { \msg_error:nnn { debug } { debug } {##1} }
+ }
+ }
+\cs_new_protected:Npn \@@_all_on:
+ {
+ \debug_on:n
+ {
+ check-declarations ,
+ check-expressions ,
+ deprecation ,
+ log-functions ,
+ }
+ }
+\cs_new_protected:Npn \@@_all_off:
+ {
+ \debug_off:n
+ {
+ check-declarations ,
+ check-expressions ,
+ deprecation ,
+ log-functions ,
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\debug_suspend:, \debug_resume:}
+% \begin{macro}{\@@_suspended:T}
+% \begin{macro}{\l_@@_suspended_tl}
+% Suspend and resume locally all debug-related errors and logging
+% except deprecation errors. The \cs{debug_suspend:} and \cs{debug_resume:}
+% pairs can be nested. We keep track of nesting in a token list
+% containing a number of periods. At first begin with the
+% \enquote{non-suspended} version of \cs{@@_suspended:T}.
+% \begin{macrocode}
+\tl_new:N \l_@@_suspended_tl { }
+\cs_gset_protected:Npn \debug_suspend:
+ {
+ \tl_put_right:Nn \l_@@_suspended_tl { . }
+ \cs_set_eq:NN \@@_suspended:T \use:n
+ }
+\cs_gset_protected:Npn \debug_resume:
+ {
+ \__kernel_tl_set:Nx \l_@@_suspended_tl
+ { \tl_tail:N \l_@@_suspended_tl }
+ \tl_if_empty:NT \l_@@_suspended_tl
+ {
+ \cs_set_eq:NN \@@_suspended:T \use_none:n
+ }
+ }
+\cs_new_eq:NN \@@_suspended:T \use_none:n
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_check-declarations_on:, \@@_check-declarations_off:}
+% \begin{macro}
+% {
+% \__kernel_chk_var_exist:N,
+% \__kernel_chk_cs_exist:N,
+% \__kernel_chk_cs_exist:c
+% }
+% \begin{macro}[EXP]{\__kernel_chk_flag_exist:NN}
+% \begin{macro}{\__kernel_chk_var_local:N, \__kernel_chk_var_global:N}
+% \begin{macro}{\__kernel_chk_var_scope:NN}
+% When debugging is enabled these two functions set up functions that
+% test their argument (when \texttt{check-declarations} is active)
+% \begin{itemize}
+% \item \cs{__kernel_chk_var_exist:N} and \cs{__kernel_chk_cs_exist:N}, two
+% functions that test that their argument is defined;
+% \item \cs{__kernel_chk_var_scope:NN} that checks that its argument |#2|
+% has scope |#1|.
+% \item \cs{__kernel_chk_var_local:N} and \cs{__kernel_chk_var_global:N} that
+% perform both checks.
+% \end{itemize}
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_chk_var_exist:N #1 { }
+\cs_new_protected:Npn \__kernel_chk_cs_exist:N #1 { }
+\cs_generate_variant:Nn \__kernel_chk_cs_exist:N { c }
+\cs_new:Npn \__kernel_chk_flag_exist:NN { }
+\cs_new_protected:Npn \__kernel_chk_var_local:N #1 { }
+\cs_new_protected:Npn \__kernel_chk_var_global:N #1 { }
+\cs_new_protected:Npn \__kernel_chk_var_scope:NN #1#2 { }
+\cs_new_protected:cpn { @@_check-declarations_on: }
+ {
+ \cs_set_protected:Npn \__kernel_chk_var_exist:N ##1
+ {
+ \@@_suspended:T \use_none:nnn
+ \cs_if_exist:NF ##1
+ {
+ \msg_error:nne { debug } { non-declared-variable }
+ { \token_to_str:N ##1 }
+ }
+ }
+ \cs_set_protected:Npn \__kernel_chk_cs_exist:N ##1
+ {
+ \@@_suspended:T \use_none:nnn
+ \cs_if_exist:NF ##1
+ {
+ \msg_error:nne { kernel } { command-not-defined }
+ { \token_to_str:N ##1 }
+ }
+ }
+ \cs_set:Npn \__kernel_chk_flag_exist:NN ##1##2
+ {
+ \@@_suspended:T \use_iii:nnnn
+ \flag_if_exist:NTF ##2
+ { ##1 ##2 }
+ {
+ \msg_expandable_error:nnn { kernel } { bad-variable } {##2}
+ ##1 \l_tmpa_flag
+ }
+ }
+ \cs_set_protected:Npn \__kernel_chk_var_scope:NN
+ {
+ \@@_suspended:T \use_none:nnn
+ \@@_chk_var_scope_aux:NN
+ }
+ \cs_set_protected:Npn \__kernel_chk_var_local:N ##1
+ {
+ \@@_suspended:T \use_none:nnnnn
+ \__kernel_chk_var_exist:N ##1
+ \@@_chk_var_scope_aux:NN l ##1
+ }
+ \cs_set_protected:Npn \__kernel_chk_var_global:N ##1
+ {
+ \@@_suspended:T \use_none:nnnnn
+ \__kernel_chk_var_exist:N ##1
+ \@@_chk_var_scope_aux:NN g ##1
+ }
+ }
+\cs_new_protected:cpn { @@_check-declarations_off: }
+ {
+ \cs_set_protected:Npn \__kernel_chk_var_exist:N ##1 { }
+ \cs_set_protected:Npn \__kernel_chk_cs_exist:N ##1 { }
+ \cs_set:Npn \__kernel_chk_flag_exist:NN { }
+ \cs_set_protected:Npn \__kernel_chk_var_local:N ##1 { }
+ \cs_set_protected:Npn \__kernel_chk_var_global:N ##1 { }
+ \cs_set_protected:Npn \__kernel_chk_var_scope:NN ##1##2 { }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_chk_var_scope_aux:NN}
+% \begin{macro}{\@@_chk_var_scope_aux:Nn}
+% \begin{macro}{\@@_chk_var_scope_aux:NNn}
+% First check whether the name of the variable |#2| starts with
+% \meta{letter}|_|. If it does then pass that letter, the
+% \meta{scope}, and the variable name to
+% \cs{@@_chk_var_scope_aux:NNn}. That function compares the two
+% letters and triggers an error if they differ (the \cs{scan_stop:}
+% case is not reachable here). If the second character was not |_|
+% then pass the same data to the same auxiliary, except for its first
+% argument which is now a control sequence. That control sequence is
+% actually a token list (but to avoid triggering the checking code we
+% manipulate it using \cs{cs_set_nopar:Npn}) containing a single
+% letter \meta{scope} according to what the first assignment to the
+% given variable was.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_chk_var_scope_aux:NN #1#2
+ { \exp_args:NNf \@@_chk_var_scope_aux:Nn #1 { \cs_to_str:N #2 } }
+\cs_new_protected:Npn \@@_chk_var_scope_aux:Nn #1#2
+ {
+ \if:w _ \use_i:nn \@@_use_i_delimit_by_s_stop:nw #2 ? ? \s_@@_stop
+ \exp_after:wN \@@_chk_var_scope_aux:NNn
+ \@@_use_i_delimit_by_s_stop:nw #2 ? \s_@@_stop
+ #1 {#2}
+ \else:
+ \exp_args:Nc \@@_chk_var_scope_aux:NNn
+ { @@_chk_/ #2 }
+ #1 {#2}
+ \fi:
+ }
+\cs_new_protected:Npn \@@_chk_var_scope_aux:NNn #1#2#3
+ {
+ \if:w #1 #2
+ \else:
+ \if:w #1 \scan_stop:
+ \cs_gset_nopar:Npn #1 {#2}
+ \else:
+ \msg_error:nneee { debug } { local-global }
+ {#1} {#2} { \iow_char:N \\ #3 }
+ \fi:
+ \fi:
+ }
+\use:c { @@_check-declarations_off: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_log-functions_on:, \@@_log-functions_off:}
+% \begin{macro}{\__kernel_debug_log:e}
+% These two functions (corresponding to the \pkg{expl3} option
+% \texttt{log-functions}) control whether \cs{__kernel_debug_log:e}
+% writes to the log file or not. By default, logging is off.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_log-functions_on: }
+ {
+ \cs_set_protected:Npn \__kernel_debug_log:e
+ { \@@_suspended:T \use_none:nn \iow_log:e }
+ }
+\cs_new_protected:cpn { @@_log-functions_off: }
+ { \cs_set_protected:Npn \__kernel_debug_log:e { \use_none:n } }
+\cs_new_protected:Npn \__kernel_debug_log:e { \use_none:n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_check-expressions_on:, \@@_check-expressions_off:}
+% \begin{macro}{\__kernel_chk_expr:nNnN}
+% \begin{macro}{\@@_chk_expr_aux:nNnN}
+% When debugging is enabled these two functions set
+% \cs{__kernel_chk_expr:nNnN} to test or not whether the given
+% expression is valid. The idea is to evaluate the expression within
+% a brace group (to catch trailing \cs{use_none:nn} or similar), then
+% test that the result is what we expect. This is done by turning it
+% to an integer and hitting that with \cs{tex_romannumeral:D} after
+% replacing the first character by |-0|. If all goes well, that
+% primitive finds a non-positive integer and gives an empty output.
+% If the original expression evaluation stopped early it leaves a
+% trailing \cs{tex_relax:D}, which stops the second evaluation (used
+% to convert to integer) before it encounters the final
+% \cs{tex_relax:D}. Since \cs{tex_romannumeral:D} does not absorb
+% \cs{tex_relax:D} the output will be nonempty. Note that |#3| is
+% empty except for mu expressions for which it is \cs{tex_mutoglue:D}
+% to avoid an \enquote{incompatible glue units} error. Note also that
+% if we had omitted the first \cs{tex_relax:D} then for instance
+% |1+2\relax+3| would incorrectly be accepted as a valid integer
+% expression.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_check-expressions_on: }
+ {
+ \cs_set:Npn \__kernel_chk_expr:nNnN ##1##2
+ {
+ \@@_suspended:T { ##1 \use_none:nnnnnnn }
+ \exp_after:wN \@@_chk_expr_aux:nNnN
+ \exp_after:wN { \tex_the:D ##2 ##1 \scan_stop: }
+ ##2
+ }
+ }
+\cs_new_protected:cpn { @@_check-expressions_off: }
+ { \cs_set:Npn \__kernel_chk_expr:nNnN ##1##2##3##4 {##1} }
+\cs_new:Npn \__kernel_chk_expr:nNnN #1#2#3#4 {#1}
+\cs_new:Npn \@@_chk_expr_aux:nNnN #1#2#3#4
+ {
+ \tl_if_empty:oF
+ {
+ \tex_romannumeral:D - 0
+ \exp_after:wN \use_none:n
+ \int_value:w #3 #2 #1 \scan_stop:
+ }
+ {
+ \msg_expandable_error:nnnn
+ { debug } { expr } {#4} {#1}
+ }
+ #1
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_deprecation_on:, \@@_deprecation_off:}
+% Make deprecated commands throw errors if the user requests it.
+% This relies on two token lists, filled up in \pkg{l3deprecation} by
+% calls to \cs{__kernel_deprecation_code:nn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_deprecation_on:
+ { \g_@@_deprecation_on_tl }
+\cs_new_protected:Npn \@@_deprecation_off:
+ { \g_@@_deprecation_off_tl }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{
+% \l_@@_internal_tl,
+% \l_@@_tmpa_tl,
+% \l_@@_tmpb_tl,
+% }
+% For patching.
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_tl
+\tl_new:N \l_@@_tmpa_tl
+\tl_new:N \l_@@_tmpb_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{
+% \@@_generate_parameter_list:NNN,
+% \@@_build_parm_text:n,
+% \@@_build_arg_list:n,
+% \@@_arg_list_from_signature:nNN,
+% \@@_arg_check_invalid:N,
+% \@@_parm_terminate:w,
+% \@@_arg_if_braced:n,
+% \@@_get_base_form:N,
+% \@@_arg_return:N,
+% }
+% \begin{macro}[TF]{\@@_arg_if_braced:N}
+% Some functions don't take the arguments their signature indicates.
+% For instance, \cs{clist_concat:NNN} doesn't take (directly) any
+% argument, so patching it with something that uses |#1|, |#2|, or
+% |#3| results in ``Illegal parameter number in definition of
+% \cs{clist_concat:NNN}''.
+%
+% Instead of changing \emph{the} definition of the macros, we'll
+% create a copy of such macros, say, \cs[no-index]{@@_clist_concat:NNN} which
+% will be defined as
+% |<debug code with #1, #2 and #3>\clist_concat:NNN#1#2#3|. For that
+% we need to identify the signature of every function and build the
+% appropriate parameter list.
+%
+% \cs{@@_generate_parameter_list:NNN} takes a function in |#1| and
+% returns teo parameter lists: |#2| contains the simple |#1#2#3| as
+% would be used in the \meta{parameter~text} of the definition and
+% |#3| contains the same parameters but with braces where necessary.
+%
+% With the current implementation the resulting |#3| is, for example
+% for |\some_function:NnNn|, |#1{#2}#3{#4}|. While this is correct,
+% it might be unnecessary. Bracing everything will usually have the
+% same outcome (unless the function was misused in the first place).
+% What should be done?
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_generate_parameter_list:NNN #1#2#3
+ {
+ \__kernel_tl_set:Nx \l_@@_internal_tl
+ { \exp_last_unbraced:Nf \use_ii:nnn \cs_split_function:N #1 }
+ \__kernel_tl_set:Nx #2
+ { \exp_args:NV \@@_build_parm_text:n \l_@@_internal_tl }
+ \__kernel_tl_set:Nx #3
+ { \exp_args:NV \@@_build_arg_list:n \l_@@_internal_tl }
+ }
+\cs_new:Npn \@@_build_parm_text:n #1
+ {
+ \@@_arg_list_from_signature:nNN { 1 } \c_false_bool #1
+ \q_@@_recursion_tail \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_build_arg_list:n #1
+ {
+ \@@_arg_list_from_signature:nNN { 1 } \c_true_bool #1
+ \q_@@_recursion_tail \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_arg_list_from_signature:nNN #1 #2 #3
+ {
+ \@@_if_recursion_tail_stop:N #3
+ \@@_arg_check_invalid:N #3
+ \bool_if:NT #2 { \@@_arg_if_braced:NT #3 { \use_none:n } }
+ \use:n { \c_hash_str \int_eval:n {#1} }
+ \exp_args:Nf \@@_arg_list_from_signature:nNN
+ { \int_eval:n {#1+1} } #2
+ }
+% \end{macrocode}
+% Argument types |w|, |p|, |T|, and |F| shouldn't be included in the
+% parameter lists, so we abort the loop if either is found.
+% \begin{macrocode}
+\cs_new:Npn \@@_arg_check_invalid:N #1
+ {
+ \if:w w #1 \@@_parm_terminate:w \else:
+ \if:w p #1 \@@_parm_terminate:w \else:
+ \if:w T #1 \@@_parm_terminate:w \else:
+ \if:w F #1 \@@_parm_terminate:w \else:
+ \exp:w
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \exp_end:
+ }
+\cs_new:Npn \@@_parm_terminate:w
+ { \exp_after:wN \@@_use_none_delimit_by_q_recursion_stop:w \exp:w }
+\prg_new_conditional:Npnn \@@_arg_if_braced:N #1 { T }
+ { \exp_args:Nf \@@_arg_if_braced:n { \@@_get_base_form:N #1 } }
+\cs_new:Npn \@@_arg_if_braced:n #1
+ {
+ \if:w n #1 \prg_return_true: \else:
+ \if:w N #1 \prg_return_false: \else:
+ \msg_expandable_error:nnn
+ { debug } { bad-arg-type } {#1}
+ \fi:
+ \fi:
+ }
+\msg_new:nnn { debug } { bad-arg-type }
+ { Wrong~argument~type~#1. }
+% \end{macrocode}
+% The macro below gets the base form of an
+% argument type given a variant. It serves only to differentiate
+% arguments which should be braced from ones which shouldn't. If all
+% were to be braced this would be unnecessary. I moved the |n| and |N|
+% variants to the beginning of the test as the are much more common
+% here.
+% \begin{macrocode}
+\cs_new:Npn \@@_get_base_form:N #1
+ {
+ \if:w n #1 \@@_arg_return:N n \else:
+ \if:w N #1 \@@_arg_return:N N \else:
+ \if:w c #1 \@@_arg_return:N N \else:
+ \if:w o #1 \@@_arg_return:N n \else:
+ \if:w V #1 \@@_arg_return:N n \else:
+ \if:w v #1 \@@_arg_return:N n \else:
+ \if:w f #1 \@@_arg_return:N n \else:
+ \if:w e #1 \@@_arg_return:N n \else:
+ \if:w x #1 \@@_arg_return:N n \else:
+ \@@_arg_return:N \scan_stop:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \exp_stop_f:
+ }
+\cs_new:Npn \@@_arg_return:N #1
+ { \exp_after:wN #1 \exp:w \exp_end_continue_f:w }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{
+% \__kernel_patch:nnn,
+% \__kernel_patch_aux:nnn,
+% \@@_setup_debug_code:Nnn,
+% \@@_add_to_debug_code:Nnn,
+% \@@_insert_debug_code:Nnn,
+% \__kernel_patch_weird:nnn,
+% \__kernel_patch_weird_aux:nnn,
+% \@@_patch_weird:Nnn,
+% }
+% Simple patching by adding material at the start and end of (a
+% collection of) functions is straight-forward as we know the catcode
+% set up. The approach is essentially that in \pkg{etoolbox}. Notice
+% the need to worry about spaces: those are otherwise lost as normally
+% in \pkg{expl3} code they would be~|~|.
+%
+% As discussed above, some functions don't take arguments, so we can't
+% patch something that uses an argument in them. For these functions
+% \cs{__kernel_patch:nnn} is used. It starts by creating a copy of the
+% function (say, \cs{clist_concat:NNN}) with a |__debug_| prefix in
+% the name. This copy won't be changed. The code redefines the
+% original function to take the exact same arguments as advertised in
+% its signature (see \cs{@@_generate_parameter_list:NNN} above).
+% The redefined function also contains the debug code in the proper
+% position. If a function with the same name and the |__debug_| prefix
+% was already defined, then the macro patches that definition by
+% adding more debug code to it.
+% \begin{macrocode}
+\group_begin:
+ \cs_set_protected:Npn \__kernel_patch:nnn
+ {
+ \group_begin:
+ \char_set_catcode_other:N \#
+ \__kernel_patch_aux:nnn
+ }
+ \cs_set_protected:Npn \__kernel_patch_aux:nnn #1#2#3
+ {
+ \char_set_catcode_parameter:N \#
+ \char_set_catcode_space:N \ %
+ \tex_endlinechar:D -1 \scan_stop:
+ \tl_map_inline:nn {#3}
+ {
+ \cs_if_exist:cTF { @@_ \cs_to_str:N ##1 }
+ { \@@_add_to_debug_code:Nnn }
+ { \@@_setup_debug_code:Nnn }
+ ##1 {#1} {#2}
+ }
+ \group_end:
+ }
+ \cs_set_protected:Npn \@@_setup_debug_code:Nnn #1#2#3
+ {
+ \cs_gset_eq:cN { @@_ \cs_to_str:N #1 } #1
+ \@@_generate_parameter_list:NNN #1 \l_@@_tmpa_tl \l_@@_tmpb_tl
+ \exp_args:Ne \tex_scantokens:D
+ {
+ \tex_global:D \cs_prefix_spec:N #1
+ \tex_def:D \exp_not:N #1
+ \tl_use:N \l_@@_tmpa_tl
+ {
+ \tl_to_str:n {#2}
+ \exp_not:c { @@_ \cs_to_str:N #1 }
+ \tl_use:N \l_@@_tmpb_tl
+ \tl_to_str:n {#3}
+ }
+ }
+ }
+ \cs_set_protected:Npn \@@_add_to_debug_code:Nnn #1#2#3
+ {
+ \use:e
+ {
+ \cs_set:Npn \exp_not:N \@@_tmp:w
+ ##1 \tl_to_str:n { macro: }
+ ##2 \tl_to_str:n { -> }
+ ##3 \c_backslash_str \tl_to_str:n { @@_ }
+ \cs_to_str:N #1
+ ##4 \s_@@_stop
+ {
+ \exp_not:N \exp_args:Ne \exp_not:N \tex_scantokens:D
+ {
+ \tex_global:D ##1
+ \tex_def:D \exp_not:N #1 ##2
+ {
+ ##3 \tl_to_str:n {#2}
+ \c_backslash_str @@_ \cs_to_str:N #1
+ ##4 \tl_to_str:n {#3}
+ }
+ }
+ }
+ }
+ \exp_after:wN \@@_tmp:w \cs_meaning:N #1 \s_@@_stop
+ }
+% \end{macrocode}
+% Some functions, however, won't work with the signature reading setup
+% above because their signature contains |w|eird arguments. These
+% functions need to be patched using \cs{__kernel_patch_weird:nnn},
+% which won't make a copy of the function, rather it will patch the
+% debug code directly into it. This means that whatever argument the
+% debug code uses must be actually used by the patched function.
+% \begin{macrocode}
+ \cs_set_protected:Npn \__kernel_patch_weird:nnn
+ {
+ \group_begin:
+ \char_set_catcode_other:N \#
+ \__kernel_patch_weird_aux:nnn
+ }
+ \cs_set_protected:Npn \__kernel_patch_weird_aux:nnn #1#2#3
+ {
+ \char_set_catcode_parameter:N \#
+ \char_set_catcode_space:N \ %
+ \tex_endlinechar:D -1 \scan_stop:
+ \tl_map_inline:nn {#3}
+ { \@@_patch_weird:Nnn ##1 {#1} {#2} }
+ \group_end:
+ }
+ \cs_set_protected:Npn \@@_patch_weird:Nnn #1#2#3
+ {
+ \use:e
+ {
+ \tex_endlinechar:D -1 \scan_stop:
+ \exp_not:N \tex_scantokens:D
+ {
+ \tex_global:D \cs_prefix_spec:N #1
+ \tex_def:D \exp_not:N #1
+ \cs_parameter_spec:N #1
+ {
+ \tl_to_str:n {#2}
+ \cs_replacement_spec:N #1
+ \tl_to_str:n {#3}
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% Patching the second argument to ensure it exists. This happens before
+% we alter |#1| so the ordering is correct. For many variable types
+% such as \texttt{int} a low-level error occurs when |#2| is unknown, so
+% adding a check is not needed.
+% \begin{macrocode}
+ \__kernel_patch:nnn
+ { \__kernel_chk_var_exist:N #2 }
+ { }
+ {
+ \bool_set_eq:NN
+ \bool_gset_eq:NN
+ \clist_set_eq:NN
+ \clist_gset_eq:NN
+ \fp_set_eq:NN
+ \fp_gset_eq:NN
+ \prop_set_eq:NN
+ \prop_gset_eq:NN
+ \seq_set_eq:NN
+ \seq_gset_eq:NN
+ \str_set_eq:NN
+ \str_gset_eq:NN
+ \tl_set_eq:NN
+ \tl_gset_eq:NN
+ }
+% \end{macrocode}
+%
+% Patching both second and third arguments.
+% \begin{macrocode}
+ \__kernel_patch:nnn
+ {
+ \__kernel_chk_var_exist:N #2
+ \__kernel_chk_var_exist:N #3
+ }
+ { }
+ {
+ \clist_concat:NNN
+ \clist_gconcat:NNN
+ \prop_concat:NNN
+ \prop_gconcat:NNN
+ \seq_concat:NNN
+ \seq_gconcat:NNN
+ \str_concat:NNN
+ \str_gconcat:NNN
+ \tl_concat:NNN
+ \tl_gconcat:NNN
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\cs_gset_protected:Npn \__kernel_tl_set:Nx { \cs_set_nopar:Npe }
+\cs_gset_protected:Npn \__kernel_tl_gset:Nx { \cs_gset_nopar:Npe }
+% \end{macrocode}
+%
+% Patching where the first argument to a function needs scope-checking:
+% either local or global (so two lists).
+% \begin{macrocode}
+ \__kernel_patch:nnn
+ { \__kernel_chk_var_local:N #1 }
+ { }
+ {
+ \bool_set:Nn
+ \bool_set_eq:NN
+ \bool_set_true:N
+ \bool_set_false:N
+ \box_set_eq:NN
+ \box_set_eq_drop:NN
+ \box_set_to_last:N
+ \clist_clear:N
+ \clist_set_eq:NN
+ \dim_zero:N
+ \dim_set:Nn
+ \dim_set_eq:NN
+ \dim_add:Nn
+ \dim_sub:Nn
+ \fp_set_eq:NN
+ \int_zero:N
+ \int_set_eq:NN
+ \int_add:Nn
+ \int_sub:Nn
+ \int_incr:N
+ \int_decr:N
+ \int_set:Nn
+ \hbox_set:Nn
+ \hbox_set_to_wd:Nnn
+ \hbox_set:Nw
+ \hbox_set_to_wd:Nnw
+ \muskip_zero:N
+ \muskip_set:Nn
+ \muskip_add:Nn
+ \muskip_sub:Nn
+ \muskip_set_eq:NN
+ \prop_clear:N
+ \prop_concat:NNN
+ \prop_pop:NnN
+ \prop_pop:NnNT
+ \prop_pop:NnNF
+ \prop_pop:NnNTF
+ \prop_put:Nnn
+ \prop_put_if_not_in:Nnn
+ \prop_put_from_keyval:Nn
+ \prop_remove:Nn
+ \prop_set_eq:NN
+ \prop_set_from_keyval:Nn
+ \seq_set_eq:NN
+ \skip_zero:N
+ \skip_set:Nn
+ \skip_set_eq:NN
+ \skip_add:Nn
+ \skip_sub:Nn
+ \str_clear:N
+ \str_set_eq:NN
+ \str_put_left:Nn
+ \str_put_right:Nn
+ \__kernel_tl_set:Nx
+ \tl_clear:N
+ \tl_set_eq:NN
+ \tl_put_left:Nn
+ \tl_put_left:NV
+ \tl_put_left:Nv
+ \tl_put_left:Ne
+ \tl_put_left:No
+ \tl_put_right:Nn
+ \tl_put_right:NV
+ \tl_put_right:Nv
+ \tl_put_right:Ne
+ \tl_put_right:No
+ \tl_build_begin:N
+ \tl_build_put_right:Nn
+ \tl_build_put_left:Nn
+ \vbox_set:Nn
+ \vbox_set_top:Nn
+ \vbox_set_to_ht:Nnn
+ \vbox_set:Nw
+ \vbox_set_to_ht:Nnw
+ \vbox_set_split_to_ht:NNn
+ }
+ \__kernel_patch:nnn
+ { \__kernel_chk_var_global:N #1 }
+ { }
+ {
+ \bool_gset:Nn
+ \bool_gset_eq:NN
+ \bool_gset_true:N
+ \bool_gset_false:N
+ \box_gset_eq:NN
+ \box_gset_eq_drop:NN
+ \box_gset_to_last:N
+ \cctab_gset:Nn
+ \clist_gclear:N
+ \clist_gset_eq:NN
+ \dim_gset_eq:NN
+ \dim_gzero:N
+ \dim_gset:Nn
+ \dim_gadd:Nn
+ \dim_gsub:Nn
+ \fp_gset_eq:NN
+ \int_gzero:N
+ \int_gset_eq:NN
+ \int_gadd:Nn
+ \int_gsub:Nn
+ \int_gincr:N
+ \int_gdecr:N
+ \int_gset:Nn
+ \hbox_gset:Nn
+ \hbox_gset_to_wd:Nnn
+ \hbox_gset:Nw
+ \hbox_gset_to_wd:Nnw
+ \muskip_gzero:N
+ \muskip_gset:Nn
+ \muskip_gadd:Nn
+ \muskip_gsub:Nn
+ \muskip_gset_eq:NN
+ \prop_gclear:N
+ \prop_gconcat:NNN
+ \prop_gpop:NnN
+ \prop_gpop:NnNT
+ \prop_gpop:NnNF
+ \prop_gpop:NnNTF
+ \prop_gput:Nnn
+ \prop_gput_if_not_in:Nnn
+ \prop_gput_from_keyval:Nn
+ \prop_gremove:Nn
+ \prop_gset_eq:NN
+ \prop_gset_from_keyval:Nn
+ \seq_gset_eq:NN
+ \skip_gzero:N
+ \skip_gset:Nn
+ \skip_gset_eq:NN
+ \skip_gadd:Nn
+ \skip_gsub:Nn
+ \str_gclear:N
+ \str_gset_eq:NN
+ \str_gput_left:Nn
+ \str_gput_right:Nn
+ \__kernel_tl_gset:Nx
+ \tl_gclear:N
+ \tl_gset_eq:NN
+ \tl_gput_left:Nn
+ \tl_gput_left:NV
+ \tl_gput_left:Nv
+ \tl_gput_left:Ne
+ \tl_gput_left:No
+ \tl_gput_right:Nn
+ \tl_gput_right:NV
+ \tl_gput_right:Nv
+ \tl_gput_right:Ne
+ \tl_gput_right:No
+ \tl_build_gbegin:N
+ \tl_build_gput_right:Nn
+ \tl_build_gput_left:Nn
+ \vbox_gset:Nn
+ \vbox_gset_top:Nn
+ \vbox_gset_to_ht:Nnn
+ \vbox_gset:Nw
+ \vbox_gset_to_ht:Nnw
+ \vbox_gset_split_to_ht:NNn
+ }
+% \end{macrocode}
+%
+% Scoping for constants.
+% \begin{macrocode}
+ \__kernel_patch:nnn
+ { \__kernel_chk_var_scope:NN c #1 }
+ { }
+ {
+ \bool_const:Nn
+ \cctab_const:Nn
+ \dim_const:Nn
+ \int_const:Nn
+ \intarray_const_from_clist:Nn
+ \muskip_const:Nn
+ \prop_const_from_keyval:Nn
+ \prop_const_linked_from_keyval:Nn
+ \skip_const:Nn
+ \str_const:Nn
+ \tl_const:Nn
+ }
+% \end{macrocode}
+%
+% Flag functions.
+% \begin{macrocode}
+ \__kernel_patch:nnn
+ { \__kernel_chk_flag_exist:NN }
+ { }
+ {
+ \flag_ensure_raised:N
+ \flag_height:N
+ \flag_if_raised:NT
+ \flag_if_raised:NF
+ \flag_if_raised:NTF
+ \flag_if_raised_p:N
+ \flag_raise:N
+ }
+% \end{macrocode}
+%
+% Various one-offs.
+% \begin{macrocode}
+ \__kernel_patch:nnn
+ { \__kernel_chk_cs_exist:N #1 }
+ { }
+ { \cs_generate_variant:Nn }
+ \__kernel_patch:nnn
+ { \__kernel_chk_var_scope:NN g #1 }
+ { }
+ { \cctab_new:N }
+ \__kernel_patch:nnn
+ { \__kernel_chk_var_scope:NN l #1 }
+ { }
+ { \flag_new:N }
+ \__kernel_patch:nnn
+ {
+ \__kernel_chk_var_scope:NN l #1
+ \__kernel_chk_flag_exist:NN
+ }
+ { }
+ { \flag_clear:N }
+ \__kernel_patch:nnn
+ { \__kernel_chk_var_scope:NN g #1 }
+ { }
+ { \intarray_new:Nn }
+ \__kernel_patch:nnn
+ { \__kernel_chk_var_scope:NN q #1 }
+ { }
+ { \quark_new:N }
+ \__kernel_patch:nnn
+ { \__kernel_chk_var_scope:NN s #1 }
+ { }
+ { \scan_new:N }
+% \end{macrocode}
+%
+% Patch various internal commands to log definitions of functions.
+% First, a kernel internal. Then internals from the \pkg{cs},
+% \pkg{keys} and \pkg{msg} modules.
+% \begin{macrocode}
+ \__kernel_patch:nnn
+ { }
+ {
+ \__kernel_debug_log:e
+ { Defining~\token_to_str:N #1~ \msg_line_context: }
+ }
+ { \__kernel_chk_if_free_cs:N }
+%<@@=cs>
+ \__kernel_patch_weird:nnn
+ {
+ \cs_if_free:NF #4
+ {
+ \__kernel_debug_log:e
+ {
+ Variant~\token_to_str:N #4~%
+ already~defined;~ not~ changing~ it~ \msg_line_context:
+ }
+ }
+ }
+ { }
+ { \@@_generate_variant:wwNN }
+%<@@=keys>
+ \__kernel_patch:nnn
+ {
+ \cs_if_exist:cF { \c_@@_code_root_str #1 }
+ { \__kernel_debug_log:e { Defining~key~#1~\msg_line_context: } }
+ }
+ { }
+ { \@@_cmd_set_direct:nn }
+%<@@=msg>
+ \__kernel_patch:nnn
+ { }
+ {
+ \__kernel_debug_log:e
+ { Defining~message~ #1 / #2 ~\msg_line_context: }
+ }
+ { \@@_chk_free:nn }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=prg>
+% \end{macrocode}
+% Internal functions from \pkg{prg} module.
+% \begin{macrocode}
+ \__kernel_patch_weird:nnn
+ { \__kernel_chk_cs_exist:c { #5 _p : #6 } }
+ { }
+ { \@@_set_eq_conditional_p_form:wNnnnn }
+ \__kernel_patch_weird:nnn
+ { \__kernel_chk_cs_exist:c { #5 : #6 TF } }
+ { }
+ { \@@_set_eq_conditional_TF_form:wNnnnn }
+ \__kernel_patch_weird:nnn
+ { \__kernel_chk_cs_exist:c { #5 : #6 T } }
+ { }
+ { \@@_set_eq_conditional_T_form:wNnnnn }
+ \__kernel_patch_weird:nnn
+ { \__kernel_chk_cs_exist:c { #5 : #6 F } }
+ { }
+ { \@@_set_eq_conditional_F_form:wNnnnn }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=regex>
+% \end{macrocode}
+% Internal functions from \pkg{regex} module.
+% \begin{macrocode}
+ \__kernel_patch:nnn
+ {
+ \@@_trace_push:nnN { regex } { 1 } \@@_escape_use:nnnn
+ \group_begin:
+ \__kernel_tl_set:Nx \l_@@_internal_a_tl
+ { \@@_trace_pop:nnN { regex } { 1 } \@@_escape_use:nnnn }
+ \use_none:nnn
+ }
+ { }
+ { \@@_escape_use:nnn }
+ \__kernel_patch:nnn
+ { \@@_trace_push:nnN { regex } { 1 } \@@_build:N }
+ {
+ \@@_trace_states:n { 2 }
+ \@@_trace_pop:nnN { regex } { 1 } \@@_build:N
+ }
+ { \@@_build:N }
+ \__kernel_patch:nnn
+ { \@@_trace_push:nnN { regex } { 1 } \@@_build_for_cs:n }
+ {
+ \@@_trace_states:n { 2 }
+ \@@_trace_pop:nnN { regex } { 1 } \@@_build_for_cs:n
+ }
+ { \@@_build_for_cs:n }
+ \__kernel_patch:nnn
+ {
+ \@@_trace:nne { regex } { 2 }
+ {
+ regex~new~state~
+ L=\int_use:N \l_@@_left_state_int ~ -> ~
+ R=\int_use:N \l_@@_right_state_int ~ -> ~
+ M=\int_use:N \l_@@_max_state_int ~ -> ~
+ \int_eval:n { \l_@@_max_state_int + 1 }
+ }
+ }
+ { }
+ { \@@_build_new_state: }
+ \__kernel_patch:nnn
+ { \@@_trace_push:nnN { regex } { 1 } \@@_group_aux:nnnnN }
+ { \@@_trace_pop:nnN { regex } { 1 } \@@_group_aux:nnnnN }
+ { \@@_group_aux:nnnnN }
+ \__kernel_patch:nnn
+ { \@@_trace_push:nnN { regex } { 1 } \@@_branch:n }
+ { \@@_trace_pop:nnN { regex } { 1 } \@@_branch:n }
+ { \@@_branch:n }
+ \__kernel_patch:nnn
+ {
+ \@@_trace_push:nnN { regex } { 1 } \@@_match:n
+ \@@_trace:nne { regex } { 1 } { analyzing~query~token~list }
+ }
+ { \@@_trace_pop:nnN { regex } { 1 } \@@_match:n }
+ { \@@_match:n }
+ \__kernel_patch:nnn
+ {
+ \@@_trace_push:nnN { regex } { 1 } \@@_match_cs:n
+ \@@_trace:nne { regex } { 1 } { analyzing~query~token~list }
+ }
+ { \@@_trace_pop:nnN { regex } { 1 } \@@_match_cs:n }
+ { \@@_match_cs:n }
+ \__kernel_patch:nnn
+ { \@@_trace:nne { regex } { 1 } { initializing } }
+ { }
+ { \@@_match_init: }
+ \__kernel_patch:nnn
+ {
+ \@@_trace:nne { regex } { 2 }
+ { state~\int_use:N \l_@@_curr_state_int }
+ }
+ { }
+ { \@@_use_state: }
+ \__kernel_patch:nnn
+ { \@@_trace_push:nnN { regex } { 1 } \@@_replacement:n }
+ { \@@_trace_pop:nnN { regex } { 1 } \@@_replacement:n }
+ { \@@_replacement:n }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\group_end:
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=debug>
+% \end{macrocode}
+%
+% Patching arguments is a bit more involved: we do these one at a time.
+% The basic idea is the same, using a |#| token that is a string.
+% \begin{macrocode}
+\group_begin:
+ \cs_set_protected:Npn \__kernel_patch:Nn #1
+ {
+ \group_begin:
+ \char_set_catcode_other:N \#
+ \__kernel_patch_aux:Nn #1
+ }
+ \cs_set_protected:Npn \__kernel_patch_aux:Nn #1#2
+ {
+ \char_set_catcode_parameter:N \#
+ \tex_endlinechar:D -1 \scan_stop:
+ \exp_args:Ne \tex_scantokens:D
+ {
+ \tex_global:D \cs_prefix_spec:N #1 \tex_def:D \exp_not:N #1
+ \cs_parameter_spec:N #1
+ { \exp_args:No \tl_to_str:n { #1 #2 } }
+ }
+ \group_end:
+ }
+% \end{macrocode}
+%
+% The functions here can get a bit repetitive, so we define a helper
+% which can re-use the same patch code repeatedly. The main part of the
+% patch is the same, so we just have to deal with the part which varies
+% depending on the type of expression.
+% \begin{macrocode}
+ \cs_set_protected:Npn \__kernel_patch_eval:nn #1#2
+ {
+ \tl_map_inline:nn {#1}
+ {
+ \exp_args:NNe \__kernel_patch:Nn ##1
+ {
+ { \c_hash_str 1 }
+ {
+ \exp_not:N \__kernel_chk_expr:nNnN { \c_hash_str 2 }
+ \exp_not:n {#2}
+ \exp_not:N ##1
+ }
+ }
+ }
+ }
+%<@@=dim>
+ \__kernel_patch_eval:nn
+ {
+ \dim_set:Nn
+ \dim_gset:Nn
+ \dim_add:Nn
+ \dim_gadd:Nn
+ \dim_sub:Nn
+ \dim_gsub:Nn
+ \dim_const:Nn
+ }
+ { \@@_eval:w { } }
+%<@@=int>
+ \__kernel_patch_eval:nn
+ {
+ \int_set:Nn
+ \int_gset:Nn
+ \int_add:Nn
+ \int_gadd:Nn
+ \int_sub:Nn
+ \int_gsub:Nn
+ \int_const:Nn
+ }
+ { \@@_eval:w { } }
+ \__kernel_patch_eval:nn
+ {
+ \muskip_set:Nn
+ \muskip_gset:Nn
+ \muskip_add:Nn
+ \muskip_gadd:Nn
+ \muskip_sub:Nn
+ \muskip_gsub:Nn
+ \muskip_const:Nn
+ }
+ { \tex_muexpr:D { \tex_mutoglue:D } }
+ \__kernel_patch_eval:nn
+ {
+ \skip_set:Nn
+ \skip_gset:Nn
+ \skip_add:Nn
+ \skip_gadd:Nn
+ \skip_sub:Nn
+ \skip_gsub:Nn
+ \skip_const:Nn
+ }
+ { \tex_glueexpr:D { } }
+% \end{macrocode}
+%
+% Patching expandable expressions, first the one-argument versions,
+% then the two-argument ones.
+% \begin{macrocode}
+ \cs_set_protected:Npn \__kernel_patch_eval:nn #1#2
+ {
+ \tl_map_inline:nn {#1}
+ {
+ \exp_args:NNe \__kernel_patch:Nn ##1
+ {
+ {
+ \exp_not:N \__kernel_chk_expr:nNnN { \c_hash_str 1 }
+ \exp_not:n {#2}
+ \exp_not:N ##1
+ }
+ }
+ }
+ }
+%<@@=box>
+ \__kernel_patch_eval:nn
+ { \@@_dim_eval:n }
+ { \@@_dim_eval:w { } }
+%<@@=dim>
+ \__kernel_patch_eval:nn
+ {
+ \dim_eval:n
+ \dim_to_decimal:n
+ \dim_to_decimal_in_sp:n
+ \dim_abs:n
+ \dim_sign:n
+ }
+ { \@@_eval:w { } }
+%<@@=int>
+ \__kernel_patch_eval:nn
+ {
+ \int_eval:n
+ \int_abs:n
+ \int_sign:n
+ }
+ { \@@_eval:w { } }
+ \__kernel_patch_eval:nn
+ {
+ \skip_eval:n
+ \skip_horizontal:n
+ \skip_vertical:n
+ }
+ { \tex_glueexpr:D { } }
+ \__kernel_patch_eval:nn
+ {
+ \muskip_eval:n
+ }
+ { \tex_muexpr:D { \tex_mutoglue:D } }
+ \cs_set_protected:Npn \__kernel_patch_eval:nn #1#2
+ {
+ \tl_map_inline:nn {#1}
+ {
+ \exp_args:NNe \__kernel_patch:Nn ##1
+ {
+ {
+ \exp_not:N \__kernel_chk_expr:nNnN { \c_hash_str 1 }
+ \exp_not:n {#2}
+ \exp_not:N ##1
+ }
+ {
+ \exp_not:N \__kernel_chk_expr:nNnN { \c_hash_str 2 }
+ \exp_not:n {#2}
+ \exp_not:N ##1
+ }
+ }
+ }
+ }
+%<@@=dim>
+ \__kernel_patch_eval:nn
+ {
+ \dim_max:nn
+ \dim_min:nn
+ }
+ { \@@_eval:w { } }
+%<@@=int>
+ \__kernel_patch_eval:nn
+ {
+ \int_max:nn
+ \int_min:nn
+ \int_div_truncate:nn
+ \int_mod:nn
+ }
+ { \@@_eval:w { } }
+% \end{macrocode}
+%
+% Conditionals: three argument ones then one argument ones
+% \begin{macrocode}
+ \cs_set_protected:Npn \__kernel_patch_cond:nn #1#2
+ {
+ \clist_map_inline:nn { :nNnT , :nNnF , :nNnTF , _p:nNn }
+ {
+ \exp_args:Nce \__kernel_patch:Nn { #1 ##1 }
+ {
+ {
+ \exp_not:N \__kernel_chk_expr:nNnN { \c_hash_str 1 }
+ \exp_not:n {#2}
+ \exp_not:c { #1 ##1 }
+ }
+ { \c_hash_str 2 }
+ {
+ \exp_not:N \__kernel_chk_expr:nNnN { \c_hash_str 3 }
+ \exp_not:n {#2}
+ \exp_not:c { #1 ##1 }
+ }
+ }
+ }
+ }
+%<@@=dim>
+ \__kernel_patch_cond:nn { dim_compare } { \@@_eval:w { } }
+%<@@=int>
+ \__kernel_patch_cond:nn { int_compare } { \@@_eval:w { } }
+ \cs_set_protected:Npn \__kernel_patch_cond:nn #1#2
+ {
+ \clist_map_inline:nn { :nT , :nF , :nTF , _p:n }
+ {
+ \exp_args:Nce \__kernel_patch:Nn { #1 ##1 }
+ {
+ {
+ \exp_not:N \__kernel_chk_expr:nNnN { \c_hash_str 1 }
+ \exp_not:n {#2}
+ \exp_not:c { #1 ##1 }
+ }
+ }
+ }
+ }
+%<@@=int>
+ \__kernel_patch_cond:nn { int_if_even } { \@@_eval:w { } }
+ \__kernel_patch_cond:nn { int_if_odd } { \@@_eval:w { } }
+% \end{macrocode}
+%
+% Step functions.
+% \begin{macrocode}
+%<@@=dim>
+ \__kernel_patch:Nn \dim_step_function:nnnN
+ {
+ {
+ \__kernel_chk_expr:nNnN {#1} \@@_eval:w { }
+ \dim_step_function:nnnN
+ }
+ {
+ \__kernel_chk_expr:nNnN {#2} \@@_eval:w { }
+ \dim_step_function:nnnN
+ }
+ {
+ \__kernel_chk_expr:nNnN {#3} \@@_eval:w { }
+ \dim_step_function:nnnN
+ }
+ }
+%<@@=int>
+ \__kernel_patch:Nn \int_step_function:nnnN
+ {
+ {
+ \__kernel_chk_expr:nNnN {#1} \@@_eval:w { }
+ \int_step_function:nnnN
+ }
+ {
+ \__kernel_chk_expr:nNnN {#2} \@@_eval:w { }
+ \int_step_function:nnnN
+ }
+ {
+ \__kernel_chk_expr:nNnN {#3} \@@_eval:w { }
+ \int_step_function:nnnN
+ }
+ }
+% \end{macrocode}
+%
+% Odds and ends
+% \begin{macrocode}
+ \__kernel_patch:Nn \dim_to_fp:n { { (#1) } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\group_end:
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=skip>
+% \end{macrocode}
+% This one has catcode changes so must be done by hand.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \prg_set_conditional:Npnn \skip_if_finite:n ##1 { p , T , F , TF }
+ {
+ \exp_after:wN \@@_if_finite:wwNw
+ \skip_use:N \tex_glueexpr:D
+ \__kernel_chk_expr:nNnN
+ {##1} \tex_glueexpr:D { } \skip_if_finite:n
+ ; \prg_return_false:
+ #1 ; \prg_return_true: \s_@@_stop
+ }
+ }
+\exp_args:No \@@_tmp:w { \tl_to_str:n { fil } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=msg>
+% \end{macrocode}
+%
+% Messages.
+% \begin{macrocode}
+\msg_new:nnnn { debug } { debug }
+ { The~debugging~option~'#1'~does~not~exist~\msg_line_context:. }
+ {
+ The~functions~'\iow_char:N\\debug_on:n'~and~
+ '\iow_char:N\\debug_off:n'~only~accept~the~arguments~
+ 'all',~'check-declarations',~'check-expressions',~
+ 'deprecation',~'log-functions',~not~'#1'.
+ }
+\msg_new:nnn { debug } { expr } { '#2'~in~#1 }
+\msg_new:nnnn { debug } { local-global }
+ { Inconsistent~local/global~assignment }
+ {
+ \c_@@_coding_error_text_tl
+ \if:w l #2 Local
+ \else:
+ \if:w g #2 Global \else: Constant \fi:
+ \fi:
+ \ %
+ assignment~to~a~
+ \if:w l #1 local
+ \else:
+ \if:w g #1 global \else: constant \fi:
+ \fi:
+ \ %
+ variable~'#3'.
+ }
+\msg_new:nnnn { debug } { non-declared-variable }
+ { The~variable~#1~has~not~been~declared~\msg_line_context:. }
+ {
+ \c_@@_coding_error_text_tl
+ Checking~is~active,~and~you~have~tried~do~so~something~like: \\
+ \ \ \tl_set:Nn ~ #1 ~ \{ ~ ... ~ \} \\
+ without~first~having: \\
+ \ \ \tl_new:N ~ #1 \\
+ \\
+ LaTeX~will~continue,~creating~the~variable~where~it~is~the~one~being~set.
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\__kernel_if_debug:TF}
+% Flip the switch for deprecated code.
+% \begin{macrocode}
+\cs_set_protected:Npn \__kernel_if_debug:TF #1#2 {#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3deprecation.dtx b/macros/latex-dev/required/l3kernel/l3deprecation.dtx
new file mode 100644
index 0000000000..7af8700df7
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3deprecation.dtx
@@ -0,0 +1,691 @@
+% \iffalse meta-comment
+%
+%% File: l3deprecation.dtx
+%
+% Copyright (C) 2017-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3deprecation} module\\ Deprecation errors^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{\pkg{l3deprecation} documentation}
+%
+% A few commands have had to be deprecated over the years.
+% All commands deprecated before release 2022-01-12 were already
+% removed; commands deprecated since then will no longer be removed.
+% Instead, this module defines them to produce errors.
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3deprecation} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=deprecation>
+% \end{macrocode}
+%
+% \subsection{Patching definitions to deprecate}
+%
+% \begin{quote}
+% \cs{__kernel_patch_deprecation:nnNNpn} \Arg{date} \Arg{replacement}
+% \meta{definition} \meta{function} \meta{parameters} \Arg{code}
+% \end{quote}
+% defines the \meta{function} to produce an error and run its
+% \meta{code}.
+%
+% We make \cs{debug_on:n} |{deprecation}| turn the \meta{function} into
+% an \tn{outer} error, and \cs{debug_off:n} |{deprecation}| restore
+% whatever the behaviour was without \cs{debug_on:n} |{deprecation}|.
+%
+% In the explanations below, \meta{definition} \meta{function}
+% \meta{parameters} \Arg{code} or assignments that only differ in the
+% scope of the \meta{definition} will be called \enquote{the standard
+% definition}.
+%
+% \begin{macro}
+% {
+% \__kernel_patch_deprecation:nnNNpn, \@@_patch_aux:nnNNnn,
+% \@@_warn_once:nnNnn,
+% \@@_patch_aux:Nn,
+% \@@_just_error:nnNN
+% }
+% (The parameter text is grabbed using |#5#|.) The arguments of
+% \cs{__kernel_deprecation_code:nn} are run upon \cs{debug_on:n}
+% |{deprecation}| and \cs{debug_off:n} |{deprecation}|, respectively.
+% In both scenarios we the \meta{function} may be \tn{outer} so we
+% undefine it with \cs{tex_let:D} before redefining it, with
+% \cs{__kernel_deprecation_error:Nnn} or with some code added shortly.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_patch_deprecation:nnNNpn #1#2#3#4#5#
+ { \@@_patch_aux:nnNNnn {#1} {#2} #3 #4 {#5} }
+\cs_new_protected:Npn \@@_patch_aux:nnNNnn #1#2#3#4#5#6
+ {
+ \__kernel_deprecation_code:nn
+ {
+ \tex_let:D #4 \scan_stop:
+ \__kernel_deprecation_error:Nnn #4 {#2} {#1}
+ }
+ { \tex_let:D #4 \scan_stop: }
+ \cs_if_eq:NNTF #3 \cs_gset_protected:Npn
+ { \@@_warn_once:nnNnn {#1} {#2} #4 {#5} {#6} }
+ { \@@_patch_aux:Nn #3 { #4 #5 {#6} } }
+ }
+% \end{macrocode}
+% In case we want a warning, the \meta{function} is defined to produce
+% such a warning without grabbing any argument, then redefine itself
+% to the standard definition that the \meta{function} should have,
+% with arguments, and call that definition. The \texttt{e}-type
+% expansion and \cs{exp_not:n} avoid needing to double the~|#|, which
+% we could not do anyways. We then deal with the code for
+% \cs{debug_off:n} |{deprecation}|: presumably someone doing that does
+% not need the warning so we simply do the standard definition.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_warn_once:nnNnn #1#2#3#4#5
+ {
+ \cs_gset_protected:Npe #3
+ {
+ \__kernel_if_debug:TF
+ {
+ \exp_not:N \msg_warning:nneee
+ { deprecation } { deprecated-command }
+ {#1}
+ { \token_to_str:N #3 }
+ { \tl_to_str:n {#2} }
+ }
+ { }
+ \exp_not:n { \cs_gset_protected:Npn #3 #4 {#5} }
+ \exp_not:N #3
+ }
+ \__kernel_deprecation_code:nn { }
+ { \cs_set_protected:Npn #3 #4 {#5} }
+ }
+% \end{macrocode}
+% In case we want neither warning nor error, the \meta{function} is
+% given its standard definition. Here |#1| is \cs{cs_new:Npn} or
+% \cs{cs_new_protected:Npn}) and |#2| is \meta{function}
+% \meta{parameters} \Arg{code}, so |#1#2| performs the assignment.
+% For \cs{debug_off:n} |{deprecation}| we want to use the same
+% assignment but with a different scope, hence the \cs{cs_if_eq:NNTF}
+% test.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_aux:Nn #1#2
+ {
+ #1 #2
+ \cs_if_eq:NNTF #1 \cs_gset_protected:Npn
+ { \__kernel_deprecation_code:nn { } { \cs_set_protected:Npn #2 } }
+ { \__kernel_deprecation_code:nn { } { \cs_set:Npn #2 } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_deprecation_error:Nnn}
+% The \tn{outer} definition here ensures the command cannot appear
+% in an argument.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_deprecation_error:Nnn #1#2#3
+ {
+ \tex_protected:D \tex_outer:D \tex_edef:D #1
+ {
+ \exp_not:N \msg_expandable_error:nnnnn
+ { deprecation } { deprecated-command }
+ { \tl_to_str:n {#3} } { \token_to_str:N #1 } { \tl_to_str:n {#2} }
+ \exp_not:N \msg_error:nneee
+ { deprecation } { deprecated-command }
+ { \tl_to_str:n {#3} } { \token_to_str:N #1 } { \tl_to_str:n {#2} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\msg_new:nnn { deprecation } { deprecated-command }
+ {
+ \tl_if_blank:nF {#3} { Use~ \tl_trim_spaces:n {#3} ~not~ }
+ #2~deprecated~on~#1.
+ }
+% \end{macrocode}
+%
+% \subsection{Deprecated \pkg{l3basics} functions}
+%
+% \begin{macrocode}
+%<@@=cs>
+% \end{macrocode}
+%
+% \begin{macro}[EXP, deprecated]{\cs_argument_spec:N}
+% For the present, do not deprecate fully as \LaTeXe{} will need to catch
+% up: one for Fall 2022.
+% \begin{macrocode}
+%\__kernel_patch_deprecation:nnNNpn { 2022-06-24 } { \cs_parameter_spec:N }
+\cs_new:Npn \cs_argument_spec:N { \cs_parameter_spec:N }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3file} functions}
+%
+% \begin{macrocode}
+%<@@=file>
+% \end{macrocode}
+%
+% \begin{macro}[deprecated]
+% {
+% \iow_shipout_x:Nn, \iow_shipout_x:Nx,
+% \iow_shipout_x:cn, \iow_shipout_x:cx
+% }
+% Previously described as \texttt{x}-type, but the hash behaviour is really
+% \texttt{e}-type. Currently not \enquote{live} as we need to have a transition.
+% \begin{macrocode}
+% \__kernel_patch_deprecation:nnNNpn { 2023-10-10 } { \iow_shipout_e:Nn }
+\cs_new_protected:Npn \iow_shipout_x:Nn { \iow_shipout_e:Nn }
+\cs_generate_variant:Nn \iow_shipout_x:Nn { Nx , c, cx }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3keys} functions}
+%
+% \begin{macrocode}
+%<@@=keys>
+% \end{macrocode}
+%
+% \begin{macro}[deprecated]{.str_set_x:N, .str_set_x:c}
+% \begin{macro}[deprecated]{.str_gset_x:N, .str_gset_x:c}
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .str_set_x:N } #1
+ { \@@_variable_set:NnnN #1 { str } { } x }
+\cs_new_protected:cpn { \c_@@_props_root_str .str_set_x:c } #1
+ { \@@_variable_set:cnnN {#1} { str } { } x }
+\cs_new_protected:cpn { \c_@@_props_root_str .str_gset_x:N } #1
+ { \@@_variable_set:NnnN #1 { str } { g } x }
+\cs_new_protected:cpn { \c_@@_props_root_str .str_gset_x:c } #1
+ { \@@_variable_set:cnnN {#1} { str } { g } x }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[deprecated]{.tl_set_x:N, .tl_set_x:c}
+% \begin{macro}[deprecated]{.tl_gset_x:N, .tl_gset_x:c}
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .tl_set_x:N } #1
+ { \@@_variable_set:NnnN #1 { tl } { } x }
+\cs_new_protected:cpn { \c_@@_props_root_str .tl_set_x:c } #1
+ { \@@_variable_set:cnnN {#1} { tl } { } x }
+\cs_new_protected:cpn { \c_@@_props_root_str .tl_gset_x:N } #1
+ { \@@_variable_set:NnnN #1 { tl } { g } x }
+\cs_new_protected:cpn { \c_@@_props_root_str .tl_gset_x:c } #1
+ { \@@_variable_set:cnnN {#1} { tl } { g } x }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[deprecated]
+% {
+% \keys_set_filter:nnnN, \keys_set_filter:nnVN,
+% \keys_set_filter:nnvN, \keys_set_filter:nnoN
+% }
+% \begin{macro}[deprecated]
+% {
+% \keys_set_filter:nnnnN, \keys_set_filter:nnVnN,
+% \keys_set_filter:nnvnN, \keys_set_filter:nnonN
+% }
+% \begin{macro}[deprecated]
+% {
+% \keys_set_filter:nnn, \keys_set_filter:nnV,
+% \keys_set_filter:nnv, \keys_set_filter:nno
+% }
+% We need a transition here so for the present this is commented out:
+% only needed for \texttt{latex-lab} code so this should not last for
+% too long.
+% \begin{macrocode}
+%\__kernel_patch_deprecation:nnNNpn { 2024-01-10 } { \keys_set_exclude_groups:nnn }
+\cs_new_protected:Npn \keys_set_filter:nnn { \keys_set_exclude_groups:nnn }
+\cs_generate_variant:Nn \keys_set_filter:nnn { nnV , nnv , nno }
+%\__kernel_patch_deprecation:nnNNpn { 2024-01-10 } { \keys_set_exclude_groups:nnnN }
+\cs_new_protected:Npn \keys_set_filter:nnnN { \keys_set_exclude_groups:nnnN }
+\cs_generate_variant:Nn \keys_set_filter:nnnN { nnV , nnv , nno }
+%\__kernel_patch_deprecation:nnNNpn { 2024-01-10 } { \keys_set_exclude_groups:nnnnN }
+\cs_new_protected:Npn \keys_set_filter:nnnnN { \keys_set_exclude_groups:nnnnN }
+\cs_generate_variant:Nn \keys_set_filter:nnnnN { nnV , nnv , nno }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3msg} functions}
+%
+% \begin{macrocode}
+%<@@=msg>
+% \end{macrocode}
+%
+% \begin{macro}[deprecated]{\msg_gset:nnnn, \msg_gset:nnn}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2024-02-13 } { \msg_set:nnnn }
+\cs_new_protected:Npn \msg_gset:nnnn { \msg_set:nnnn }
+\__kernel_patch_deprecation:nnNNpn { 2024-02-13 } { \msg_set:nnn }
+\cs_new_protected:Npn \msg_gset:nnn { \msg_set:nnn }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3pdf} functions}
+%
+% \begin{macrocode}
+%<@@=pdf>
+% \end{macrocode}
+%
+% \begin{variable}[deprecated]{\g_@@_object_prop}
+% For tracking objects.
+% \begin{macrocode}
+\prop_new:N \g_@@_object_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[deprecated]
+% {\pdf_object_new:nn, \pdf_object_write:nn, \pdf_object_write:nx}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2022-08-30 } { [\pdf_object_new:n] }
+\cs_new_protected:Npn \pdf_object_new:nn #1#2
+ {
+ \prop_gput:Nnn \g_@@_object_prop {#1} {#2}
+ \@@_backend_object_new:n {#1}
+ }
+\__kernel_patch_deprecation:nnNNpn { 2022-08-30 } { [\pdf_object_write:n] }
+\cs_new_protected:Npn \pdf_object_write:nn #1#2
+ {
+ \exp_args:Nne \@@_backend_object_write:nnn
+ {#1} { \prop_item:Nn \g_@@_object_prop {#1} } {#2}
+ \bool_gset_true:N \g_@@_init_bool
+ }
+\cs_generate_variant:Nn \pdf_object_write:nn { nx }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3prg} functions}
+%
+% \begin{macrocode}
+%<@@=cs>
+% \end{macrocode}
+%
+% \begin{macro}[EXP, noTF, deprecated]{\bool_case_true:n}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2023-05-03 } { \bool_case:n }
+\cs_new:Npn \bool_case_true:n { \bool_case:n }
+\__kernel_patch_deprecation:nnNNpn { 2023-05-03 } { \bool_case:nT }
+\cs_new:Npn \bool_case_true:nT { \bool_case:nT }
+\__kernel_patch_deprecation:nnNNpn { 2023-05-03 } { \bool_case:nF }
+\cs_new:Npn \bool_case_true:nF { \bool_case:nF }
+\__kernel_patch_deprecation:nnNNpn { 2023-05-03 } { \bool_case:nTF }
+\cs_new:Npn \bool_case_true:nTF { \bool_case:nTF }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3str} functions}
+%
+% \begin{macrocode}
+%<@@=str>
+% \end{macrocode}
+%
+% \begin{macro}[EXP, deprecated]
+% {
+% \str_lower_case:n, \str_lower_case:f,
+% \str_upper_case:n, \str_upper_case:f,
+% \str_fold_case:n, \str_fold_case:V
+% }
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \str_lowercase:n }
+\cs_new:Npn \str_lower_case:n { \str_lowercase:n }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \str_lowercase:f }
+\cs_new:Npn \str_lower_case:f { \str_lowercase:f }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \str_uppercase:n }
+\cs_new:Npn \str_upper_case:n { \str_uppercase:n }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \str_uppercase:f }
+\cs_new:Npn \str_upper_case:f { \str_uppercase:f }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \str_casefold:n }
+\cs_new:Npn \str_fold_case:n { \str_casefold:n }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \str_casefold:V }
+\cs_new:Npn \str_fold_case:V { \str_casefold:V }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, deprecated]
+% {\str_foldcase:n, \str_foldcase:V}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-10-17 } { \str_casefold:n }
+\cs_new:Npn \str_foldcase:n { \str_casefold:n }
+\__kernel_patch_deprecation:nnNNpn { 2022-10-17 } { \str_casefold:V }
+\cs_new:Npn \str_foldcase:V { \str_casefold:V }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, deprecated]
+% {\str_declare_eight_bit_encoding:nnn}
+% This command was made internal, with one more argument. There is no
+% easy way to compute a reasonable value for that extra argument so we
+% take a value that is big enough to accommodate all of Unicode.
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-08-20 } { }
+\cs_new_protected:Npn \str_declare_eight_bit_encoding:nnn #1
+ { \@@_declare_eight_bit_encoding:nnnn {#1} { 1114112 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3seq} functions}
+%
+% \begin{macrocode}
+%<@@=seq>
+% \end{macrocode}
+%
+% \begin{macro}[deprecated]{\seq_indexed_map_inline:Nn}
+% \begin{macro}[EXP, deprecated]{ \seq_indexed_map_function:NN}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-06-18 } { \seq_map_indexed_inline:Nn }
+\cs_new_protected:Npn \seq_indexed_map_inline:Nn { \seq_map_indexed_inline:Nn }
+\__kernel_patch_deprecation:nnNNpn { 2020-06-18 } { \seq_map_indexed_function:NN }
+\cs_new:Npn \seq_indexed_map_function:NN { \seq_map_indexed_function:NN }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[deprecated]{\seq_mapthread_function:NNN}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2023-05-10 } { \seq_map_pairwise_function:NNN }
+\cs_new:Npn \seq_mapthread_function:NNN { \seq_map_pairwise_function:NNN }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[deprecated]{\seq_set_map_x:NNn, \seq_gset_map_x:NNn}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2023-10-26 } { \seq_set_map_e:NNn }
+\cs_new_protected:Npn \seq_set_map_x:NNn { \seq_set_map_e:NNn }
+\__kernel_patch_deprecation:nnNNpn { 2023-10-26 } { \seq_gset_map_e:NNn }
+\cs_new_protected:Npn \seq_gset_map_x:NNn { \seq_gset_map_e:NNn }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3sys} functions}
+%
+% \begin{macrocode}
+%<@@=sys>
+% \end{macrocode}
+%
+% \begin{macro}[deprecated]{\sys_load_deprecation:}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2021-01-11 } { (no~longer~required) }
+\cs_new_protected:Npn \sys_load_deprecation: { }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3text} functions}
+%
+% \begin{macrocode}
+%<@@=text>
+% \end{macrocode}
+%
+% \begin{macro}[EXP, deprecated]{\text_titlecase:n}
+% \begin{macro}[EXP, deprecated]{\text_titlecase:nn}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2023-07-08 } { \text_titlecase_first:n }
+\cs_new:Npn \text_titlecase:n #1
+ { \text_titlecase_first:n { \text_lowercase:n {#1} } }
+\__kernel_patch_deprecation:nnNNpn { 2023-07-08 } { \text_titlecase_first:nn }
+\cs_new:Npn \text_titlecase:nn #1#2
+ { \text_titlecase_first:nn {#1} { \text_lowercase:n {#2} } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3tl} functions}
+%
+% \begin{macrocode}
+%<@@=tl>
+% \end{macrocode}
+%
+% \begin{macro}[deprecated]
+% {
+% \tl_lower_case:n, \tl_lower_case:nn,
+% \tl_upper_case:n, \tl_upper_case:nn,
+% \tl_mixed_case:n, \tl_mixed_case:nn,
+% }
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \text_lowercase:n }
+\cs_new:Npn \tl_lower_case:n #1
+ { \text_lowercase:n {#1} }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \text_lowercase:nn }
+\cs_new:Npn \tl_lower_case:nn #1#2
+ { \text_lowercase:nn {#1} {#2} }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \text_uppercase:n }
+\cs_new:Npn \tl_upper_case:n #1
+ { \text_uppercase:n {#1} }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \text_uppercase:nn }
+\cs_new:Npn \tl_upper_case:nn #1#2
+ { \text_uppercase:nn {#1} {#2} }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \text_titlecase_first:n }
+\cs_new:Npn \tl_mixed_case:n #1
+ { \text_titlecase_first:n {#1} }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \text_titlecase_first:nn }
+\cs_new:Npn \tl_mixed_case:nn #1#2
+ { \text_titlecase_first:nn {#1} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[noTF, deprecated]{\tl_case:Nn, \tl_case:cn}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2022-05-23 } { \token_case_meaning:Nn }
+\cs_new:Npn \tl_case:Nn { \token_case_meaning:Nn }
+\__kernel_patch_deprecation:nnNNpn { 2022-05-23 } { \token_case_meaning:NnT }
+\cs_new:Npn \tl_case:NnT { \token_case_meaning:NnT }
+\__kernel_patch_deprecation:nnNNpn { 2022-05-23 } { \token_case_meaning:NnF }
+\cs_new:Npn \tl_case:NnF { \token_case_meaning:NnF }
+\__kernel_patch_deprecation:nnNNpn { 2022-05-23 } { \token_case_meaning:NnTF }
+\cs_new:Npn \tl_case:NnTF { \token_case_meaning:NnTF }
+\cs_generate_variant:Nn \tl_case:Nn { c }
+\prg_generate_conditional_variant:Nnn \tl_case:Nn
+ { c } { T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[deprecated]{\tl_build_clear:N, \tl_build_gclear:N}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2023-10-18 } { \tl_build_begin:N }
+\cs_new_protected:Npn \tl_build_clear:N { \tl_build_begin:N }
+\__kernel_patch_deprecation:nnNNpn { 2023-10-18 } { \tl_build_gbegin:N }
+\cs_new_protected:Npn \tl_build_gclear:N { \tl_build_gbegin:N }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[deprecated]{\tl_build_get:NN}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2023-10-25 } { \tl_build_get_intermediate:NN }
+\cs_new_protected:Npn \tl_build_get:NN { \tl_build_get_intermediate:NN }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3token} functions}
+%
+% \begin{macrocode}
+%<@@=char>
+% \end{macrocode}
+%
+% \begin{macro}[EXP, deprecated]{\char_to_utfviii_bytes:n}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2022-10-09 } { [ \codepoint_generate:nn ] }
+\cs_new:Npn \char_to_utfviii_bytes:n { \__kernel_codepoint_to_bytes:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, deprecated]{\char_to_nfd:N, \char_to_nfd:n}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2022-10-09 } { \codepoint_to_nfd:n }
+\cs_new:Npn \char_to_nfd:N #1 { \codepoint_to_nfd:n {`#1} }
+\__kernel_patch_deprecation:nnNNpn { 2022-10-09 } { \codepoint_to_nfd:n }
+\cs_new:Npn \char_to_nfd:n { \codepoint_to_nfd:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, deprecated]
+% {
+% \char_lower_case:N, \char_upper_case:N,
+% \char_mixed_case:Nn, \char_fold_case:N,
+% \char_str_lower_case:N, \char_str_upper_case:N,
+% \char_str_mixed_case:Nn, \char_str_fold_case:N,
+% }
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \text_lowercase:n }
+\cs_new:Npn \char_lower_case:N { \text_lowercase:n }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \text_uppercase:n }
+\cs_new:Npn \char_upper_case:N { \text_uppercase:n }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \text_titlecase_first:n }
+\cs_new:Npn \char_mixed_case:N { \text_titlecase_first:n }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \str_casefold:n }
+\cs_new:Npn \char_fold_case:N { \str_casefold:n }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \str_lowercase:n }
+\cs_new:Npn \char_str_lower_case:N { \str_lowercase:n }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \str_uppercase:n }
+\cs_new:Npn \char_str_upper_case:N { \str_uppercase:n }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \str_titlecase:n }
+\cs_new:Npn \char_str_mixed_case:N { \str_titlecase:n }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \str_casefold:n }
+\cs_new:Npn \char_str_fold_case:N { \str_casefold:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, deprecated]
+% {
+% \char_lowercase:N, \char_titlecase:N, \char_uppercase:N,
+% \char_foldcase:N,
+% \char_str_lowercase:N, \char_str_titlecase:N, \char_str_uppercase:N,
+% \char_str_foldcase:N,
+% }
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2022-10-17 } { \text_lowercase:n }
+\cs_new:Npn \char_lowercase:N { \text_lowercase:n }
+\__kernel_patch_deprecation:nnNNpn { 2022-10-17 } { \text_uppercase:n }
+\cs_new:Npn \char_uppercase:N { \text_uppercase:n }
+\__kernel_patch_deprecation:nnNNpn { 2022-10-17 } { \text_titlecase_first:n }
+\cs_new:Npn \char_titlecase:N { \text_titlecase_first:n }
+\__kernel_patch_deprecation:nnNNpn { 2022-10-17 } { \str_casefold:n }
+\cs_new:Npn \char_foldcase:N { \str_casefold:n }
+\__kernel_patch_deprecation:nnNNpn { 2022-10-17 } { \str_lowercase:n }
+\cs_new:Npn \char_str_lowercase:N { \str_lowercase:n }
+\__kernel_patch_deprecation:nnNNpn { 2022-10-17 }
+ { \tl_to_str:e { \text_titlecase_first:n } }
+\cs_new:Npn \char_str_titlecase:N #1
+ { \tl_to_str:e { \text_titlecase_first:n {#1} } }
+\__kernel_patch_deprecation:nnNNpn { 2022-10-17 } { \str_uppercase:n }
+\cs_new:Npn \char_str_uppercase:N { \str_uppercase:n }
+\__kernel_patch_deprecation:nnNNpn { 2022-10-17 } { \str_casefold:n }
+\cs_new:Npn \char_str_foldcase:N { \str_casefold:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF, deprecated]
+% {
+% \peek_catcode_ignore_spaces:N, \peek_catcode_remove_ignore_spaces:N,
+% \peek_charcode_ignore_spaces:N, \peek_charcode_remove_ignore_spaces:N,
+% \peek_meaning_ignore_spaces:N, \peek_meaning_remove_ignore_spaces:N
+% }
+% A little extra fun here to deal with the expansion.
+% \begin{macrocode}
+\tl_map_inline:nn
+ {
+ { catcode } { catcode_remove }
+ { charcode } { charcode_remove }
+ { meaning } { meaning_remove }
+ }
+ {
+ \use:e
+ {
+ \__kernel_patch_deprecation:nnNNpn { 2022-01-11 } { \peek_remove_spaces:n }
+ \cs_gset_protected:Npn \exp_not:c { peek_ #1 _ignore_spaces:NTF } ##1##2##3
+ {
+ \peek_remove_spaces:n
+ { \exp_not:c { peek_ #1 :NTF } ##1 {##2} {##3} }
+ }
+ \__kernel_patch_deprecation:nnNNpn { 2022-01-11 } { \peek_remove_spaces:n }
+ \cs_gset_protected:Npn \exp_not:c { peek_ #1 _ignore_spaces:NT } ##1##2
+ {
+ \peek_remove_spaces:n
+ { \exp_not:c { peek_ #1 :NT } ##1 {##2} }
+ }
+ \__kernel_patch_deprecation:nnNNpn { 2022-01-11 } { \peek_remove_spaces:n }
+ \cs_gset_protected:Npn \exp_not:c { peek_ #1 _ignore_spaces:NF } ##1##2
+ {
+ \peek_remove_spaces:n
+ { \exp_not:c { peek_ #1 :NF } ##1 {##2} }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3prop} functions}
+%
+% \begin{macro}[deprecated]
+% {
+% \prop_put_if_new:Nnn, \prop_put_if_new:NVn, \prop_put_if_new:NnV,
+% \prop_put_if_new:cnn, \prop_put_if_new:cVn, \prop_put_if_new:cnV,
+% \prop_gput_if_new:Nnn, \prop_gput_if_new:NVn, \prop_gput_if_new:NnV,
+% \prop_gput_if_new:cnn, \prop_gput_if_new:cVn, \prop_gput_if_new:cnV
+% }
+% \begin{macrocode}
+%\__kernel_patch_deprecation:nnNNpn { 2024-03-30 } { \prop_put_if_not_in:Nnn }
+\cs_new_protected:Npn \prop_put_if_new:Nnn { \prop_put_if_not_in:Nnn }
+%\__kernel_patch_deprecation:nnNNpn { 2024-03-30 } { \prop_gput_if_not_in:Nnn }
+\cs_new_protected:Npn \prop_gput_if_new:Nnn { \prop_gput_if_not_in:Nnn }
+\cs_generate_variant:Nn \prop_put_if_new:Nnn
+ { NnV , NV , c , cnV , cV }
+\cs_generate_variant:Nn \prop_gput_if_new:Nnn
+ { NnV , NV , c , cnV , cV }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3doc.dtx b/macros/latex-dev/required/l3kernel/l3doc.dtx
new file mode 100644
index 0000000000..9156bd385e
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3doc.dtx
@@ -0,0 +1,4802 @@
+% \iffalse meta-comment
+%
+%% File: l3doc.dtx
+%
+% Copyright (C) 1990-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+ \expandafter\begingroup
+\fi
+\input docstrip %
+\askforoverwritefalse
+\preamble
+
+Copyright (C) 1990-2024 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of
+the LaTeX Project Public License (LPPL), either version 1.3c of
+this license or (at your option) any later version. The latest
+version of this license is in the file:
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3kernel bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+\endpreamble
+% stop docstrip adding \endinput
+\postamble
+\endpostamble
+\generate{\file{l3doc.cls}{\from{l3doc.dtx}{class,cfg}}}
+%\generate{\file{l3doc.ist}{\from{l3doc.dtx}{docist}}}
+\ifx\fmtname\nameofplainTeX
+ \expandafter\endbatchfile
+\else
+ \expandafter\endgroup
+\fi
+%</driver>
+%
+%<*driver|class>
+\RequirePackage{calc}
+%</driver|class>
+%
+%<*driver>
+\documentclass{l3doc}
+\usepackage{framed}
+\begin{document}
+ \DocInput{l3doc.dtx}
+\end{document}
+%</driver>
+%
+% This isn't included in the typeset documentation because it's a bit
+% ugly:
+%<*class>
+\ProvidesExplClass{l3doc}{2024-04-11}{}
+ {L3 Experimental documentation class}
+%</class>
+% \fi
+%
+% \title{The \cls{l3doc} class -- experimental\thanks{%
+% On popular request we now distribute the document for this
+% experimental class. However, please note that it is by no means
+% in final state and is \emph{likely} to undergo modifications,
+% even \emph{incompatible ones}! Thus, using it might therefore
+% require you to do updates, if the class changes.}}
+%
+% \author{\Team}
+% \date{Released 2024-04-11}
+% \maketitle
+% \tableofcontents
+%
+% \begin{documentation}
+%
+%
+% \section{Introduction}
+%
+% Code and documentation for this class have been written prior to the
+% change of \pkg{doc} from version 2 to version 3, which already shows
+% how far behind this class currently is. So take the following
+% warning seriously please:
+%
+% \begin{quote}
+% \textbf{It is much less stable than the main \pkg{expl3} packages.\\
+% Use at own risk!}
+% \end{quote}
+%
+% This is an ad-hoc class for documenting the \pkg{expl3} bundle, a
+% collection of modules or packages that make up \LaTeX3's programming
+% environment. Eventually it will replace the \cls{ltxdoc} class for
+% \LaTeX3, but not before the good ideas in \pkg{hypdoc}, \cls{xdoc2},
+% \pkg{docmfp}, and \cls{gmdoc} are incorporated.
+%
+% It is written as a \enquote{self-contained} docstrip file: executing
+% |latex l3doc.dtx| generates the \file{l3doc.cls} file and typesets
+% this documentation; execute |tex l3doc.dtx| to only generate
+% \file{l3doc.cls}.
+%
+% \section{Features of other packages}
+%
+% This class builds on the \pkg{ltxdoc} class and the \pkg{doc} package,
+% but in the time since they were originally written some improvements
+% and replacements have appeared that we would like to use as
+% inspiration.
+%
+% These packages or classes are \pkg{hypdoc}, \pkg{docmfp}, \pkg{gmdoc},
+% and \pkg{xdoc}. I have summarised them below in order to work out
+% what sort of features we should aim at a minimum for \pkg{l3doc}.
+%
+% \subsection{The \pkg{hypdoc} package}
+%
+% This package provides hyperlink support for the \pkg{doc} package. I
+% have included it in this list to remind me that cross-referencing
+% between documentation and implementation of methods is not very
+% good. (\emph{E.g.}, it would be nice to be able to automatically
+% hyperlink the documentation for a function from its implementation and
+% vice-versa.)
+%
+% \subsection{The \pkg{docmfp} package}
+%
+% \begin{itemize}
+% \item Provides \cs{DescribeRoutine} and the \env{routine}
+% environment (\emph{etc.}) for MetaFont and MetaPost code.
+% \item Provides \cs{DescribeVariable} and the \env{variable}
+% environment (\emph{etc.}) for more general code.
+% \item Provides \cs{Describe} and the \env{Code} environment
+% (\emph{etc.}) as a generalisation of the above two
+% instantiations.
+% \item Small tweaks to the DocStrip system to aid non-\LaTeX{} use.
+% \end{itemize}
+%
+% \subsection{The \pkg{xdoc2} package}
+%
+% \begin{itemize}
+% \item Two-sided printing.
+% \item \cs{NewMacroEnvironment}, \cs{NewDescribeEnvironment}; similar
+% idea to \pkg{docmfp} but more comprehensive.
+% \item Tons of small improvements.
+% \end{itemize}
+%
+% \subsection{The \pkg{gmdoc} package}
+%
+% Radical re-implementation of \pkg{doc} as a package or class.
+% \begin{itemize}
+% \item Requires no |\begin{macrocode}| blocks!
+% \item Automatically inserts |\begin{macro}| blocks!
+% \item And a whole bunch of other little things.
+% \end{itemize}
+%
+% \section{Problems \& Todo}
+%
+% Problems at the moment:
+% (1)~not flexible in the types of things that can be documented;
+% (2)~no obvious link between the |\begin{function}| environment for
+% documenting things to the |\begin{macro}| function that's used
+% analogously in the implementation.
+%
+% The \env{macro} should probably be renamed to \env{function} when it
+% is used within an implementation section. But they should have the
+% same syntax before that happens!
+%
+% Furthermore, we need another \enquote{layer} of documentation commands
+% to account for \enquote{user-macro} as opposed to
+% \enquote{code-functions}; the \pkg{expl3} functions should be
+% documented differently, probably, to the \pkg{ltcmd} user macros (at
+% least in terms of indexing).
+%
+% In no particular order, a list of things to do:
+% \begin{itemize}
+% \item Rename \env{function}/\env{macro} environments to better
+% describe their use.
+% \item Generalise \env{function}/\env{macro} for documenting
+% \enquote{other things}, such as environment names, package
+% options, even keyval options.
+% \item New function like \tn{part} but for files (remove awkward
+% \enquote{File} as \tn{partname}).
+% \item Something better to replace \cs{StopEventually}; I'm thinking
+% two environments \env{documentation} and \env{implementation} that
+% can conditionally typeset/ignore their material. (This has been
+% implemented but needs further consideration.)
+% \item Hyperlink documentation and implementation of macros (see the
+% \textsc{dtx} file of \pkg{svn-multi} v2 as an example). This is
+% partially done, now, but should be improved.
+% \end{itemize}
+%
+% \section{Documentation}
+%
+% \subsection{Configuration}
+%
+% Before class options are processed, \pkg{l3doc} loads a configuration
+% file \file{l3doc.cfg} if it exists, allowing you to customise the
+% behaviour of the class without having to change the documentation
+% source files.
+%
+% For example, to produce documentation on letter-sized paper instead of
+% the default A4 size, create \file{l3doc.cfg} and include the line
+% \begin{verbatim}
+% \PassOptionsToClass{letterpaper}{l3doc}
+% \end{verbatim}
+%
+% By default, \pkg{l3doc} selects the |T1| font encoding and loads the
+% Latin Modern fonts. To prevent this, use the class option
+% |cm-default|.
+%
+% \subsection{Class options}
+%
+% The class recognises a number of options, some of which are generally
+% useful and some of which are aimed squarely at use by the kernel team only.
+%
+% \DescribeOption{full}
+% \DescribeOption{onlydoc}
+% When the \texttt{full} option is set (the standard setting), both the
+% documentation and implementation parts of the source are typeset. If on the
+% other hand the \texttt{onlydoc} option is set, only the documentation part
+% is typeset.
+%
+% \DescribeOption{lm-default}
+% Selects whether the standard font set up is Latin Modern in the \texttt{T1}
+% encoding (the standard setting) or leaves the font setup unchanged.
+%
+% \DescribeOption{kernel}
+% Determines whether \pkg{l3doc} treats internal functions and variables
+% belonging to |kernel| module as allowable in code, for instance
+% \cs{__kernel_tl_to_str:w}, \cs{c__kernel_expl_date_tl}, and
+% \cs{l__kernel_expl_bool}. In general,
+% \emph{no} internal material from outside the current module is allowed.
+% However, for bootstrapping the \pkg{expl3} kernel, a small number of
+% cross-module functions are needed. To suppress the error message that
+% would otherwise arise, the class option \texttt{kernel} may be given.
+%
+% \DescribeOption{check}
+% When the \texttt{check} option is given, the class will record all commands
+% defined and documented in a \texttt{\meta{name}.cmds} file. This will show
+% which are both documented and defined, which are only documented and which
+% are only defined. (Here, \enquote{defined} means listed using a
+% \texttt{macro} or \texttt{variable} environment in the implementation part of
+% the source file).
+%
+% \DescribeOption{checktest}
+% When \texttt{checktest} is given as an option, the class will check that each
+% function entry in the implementation part of the source is marked using
+% \cs{UnitTest}.
+%
+% \DescribeOption{show-notes}
+% \DescribeOption{hide-notes}
+% These complementary options determine if the information given using the
+% \cs{NB} and \cs{NOTE} commands is printed.
+%
+% \DescribeOption{cs-break}
+% \DescribeOption{cs-break-nohyphen}
+% The commands \cs{cmd} and \cs{cs} allow hyphenation of control sequences
+% after (most) underscores. By default, a hyphen is used to mark the
+% hyphenation, but this can be changed with the \texttt{cs-break-nohyphen}
+% class option. To disable hyphenation of control sequences entirely, use
+% \texttt{cs-break = false}.
+%
+% By default, class options
+% \begin{verbatim}
+% full , check = false , checktest = false , lm-default
+% \end{verbatim}
+% are set.
+%
+% \subsection{Partitioning documentation and implementation}
+%
+% \pkg{doc} uses the \cs{OnlyDocumentation}/\cs{AlsoImplementation}
+% macros to guide the use of \cs{StopEventually}|{}|, which is intended
+% to be placed to partition the documentation and implementation within
+% a single \file{.dtx} file.
+%
+% This isn't very flexible, since it assumes that we \emph{always} want
+% to print the documentation. For the \pkg{expl3} sources, I wanted to
+% be able to input \file{.dtx} files in two modes: only displaying
+% the documentation, and only displaying the implementation. For
+% example:
+% \begin{verbatim}
+% \DisableImplementation
+% \DocInput{l3basics,l3prg,...}
+% \EnableImplementation
+% \DisableDocumentation
+% \DocInputAgain
+% \end{verbatim}
+%
+% The idea being that the entire \pkg{expl3} bundle can be documented,
+% with the implementation included at the back. Now, this isn't
+% perfect, but it's a start.
+%
+% Use |\begin{documentation}...\end{documentation}| around the
+% documentation, and |\begin{implementation}...\end{implementation}|
+% around the implementation. The
+% \cs{EnableDocumentation}/\cs{EnableImplementation} causes them to
+% be typeset when the \file{.dtx} file is \cs{DocInput}; use
+% \cs{DisableDocumentation}/\cs{DisableImplementation} to omit the
+% contents of those environments.
+%
+% Note that \cs{DocInput} now takes comma-separated arguments, and
+% \cs{DocInputAgain} can be used to re-input all \file{.dtx} files
+% previously input in this way.
+%
+% \subsection{General text markup}
+%
+% Many of the commands in this section come from \pkg{ltxdoc} with some
+% improvements.
+%
+% \begin{function}{\cmd, \cs}
+% \begin{syntax}
+% \cmd{\cmd} \oarg{options} \meta{control sequence}\\
+% \cs{cs} \oarg{options} \marg{csname}
+% \end{syntax}
+% These commands are provided to typeset control sequences.
+% |\cmd\foo| produces \enquote{\cmd\foo} and |\cs{foo}| produces the
+% same. In general, \cs{cs} is more robust since
+% it doesn't rely on catcodes being \enquote{correct} and is therefore
+% recommended.
+%
+% These commands are aware of the |@@| \pkg{DocStrip} syntax and
+% replace such instances correctly in the typeset documentation.
+% This only happens after a |%<@@=|\meta{module}|>| declaration.
+%
+% Additionally, commands can be used in the argument of \cs{cs}. For
+% instance, |\cs{\meta{name}:\meta{signature}}| produces
+% \cs[no-index]{\meta{name}:\meta{signature}}.
+%
+% The \meta{options} are a key--value list which can contain the
+% following keys:
+% \begin{itemize}
+% \item |index=|\meta{name}: the \meta{csname} is indexed as if
+% one had written \cs{cs}\Arg{name}.
+% \item |no-index|: the \meta{csname} is not indexed.
+% \item |module=|\meta{module}: the \meta{csname} is indexed in
+% the list of commands from the \meta{module}; the \meta{module}
+% can in particular be |TeX| for \enquote{\TeX{} and \LaTeXe{}}
+% commands, or empty for commands which should be placed in the
+% main index. By default, the \meta{module} is deduced
+% automatically from the command name.
+% \item |replace| is a boolean key (\texttt{true} by default) which
+% indicates whether to replace |@@| as \pkg{DocStrip} does.
+% \end{itemize}
+% These commands allow hyphenation of control sequences after (most) underscores.
+% By default, a hyphen is used to mark the hyphenation, but this can be changed with
+% the \texttt{cs-break-nohyphen} class option.
+% To disable hyphenation of control sequences entirely, use
+% \texttt{cs-break = false}.
+% \end{function}
+%
+%
+% \begin{function}{\tn}
+% \begin{syntax}
+% \cs{tn} \oarg{options} \marg{csname}
+% \end{syntax}
+% Analoguous to \cs{cs} but intended for \enquote{traditional} \TeX{}
+% or \LaTeXe{} commands; they are indexed accordingly. This is in
+% fact equivalent to \cs{cs} |[module=TeX, replace=false,|
+% \meta{options}|]| \Arg{csname}.
+% \end{function}
+%
+% \begin{function}{\meta}
+% \begin{syntax}
+% \cs{meta} \Arg{name}
+% \end{syntax}
+% \cs{meta} typesets the \meta{name} italicised in \meta{angle
+% brackets}. Within a \env{function} environment or similar, angle
+% brackets |<...>| are set up to be a shorthand for |\meta{...}|.
+%
+% This function has additional functionality over its \pkg{ltxdoc}
+% versions; underscores can be used to subscript material as in math
+% mode. For example, |\meta{arg_{xy}}| produces
+% \enquote{\meta{arg_{xy}}}.
+% \end{function}
+%
+% \begin{function}{\Arg, \marg, \oarg, \parg}
+% \begin{syntax}
+% |\Arg| \Arg{name}
+% \end{syntax}
+% Typesets the \meta{name} as for \cs{meta} and wraps it in braces.
+%
+% The \cs{marg}/\cs{oarg}/\cs{parg} versions follow from \pkg{ltxdoc}
+% in being used for \enquote{mandatory} or \enquote{optional} or
+% \enquote{picture} brackets as per \LaTeXe{} syntax.
+% \end{function}
+%
+% \begin{function}{\file, \env, \pkg, \cls}
+% \begin{syntax}
+% \cs{pkg} \Arg{name}
+% \end{syntax}
+% These all take one argument and are intended to be used as semantic
+% commands for representing files, environments, package names, and
+% class names, respectively.
+% \end{function}
+%
+% \begin{function}{\NB, \NOTE}
+% \begin{syntax}
+% \cs{NB} \marg{tag} \marg{comments}
+% \verb|\begin{NOTE}| \marg{tag}
+% \qquad\meta{comments}
+% \verb|\end{NOTE}|
+% \end{syntax}
+% Make notes in the source that are not typeset by default. When the \verb|show-notes|
+% class option is active, the comments are typeset in a detokenized and verbatim mode, respectively.
+% \end{function}
+%
+% \subsection{Describing functions in the documentation}
+%
+% \DescribeEnv{function}
+% \DescribeEnv{variable}
+% Two heavily-used environments are defined to describe \pkg{expl3} functions
+% and variables. If describing a variable, use the latter environment; it
+% behaves identically to the \env{function} environment.
+% \DescribeEnv{syntax}
+% Both of the above environments are typically combined with the \env{syntax}
+% environment, to describe their syntax.
+% \begin{framed}
+% \vspace{-\baselineskip}
+% \begin{verbatim}
+% \begin{function}{\package_function_one:N, \package_function_two:n}
+% \begin{syntax}
+% \cs{package_function_one:N} \meta{cs}
+% \cs{package_function_two:n} \marg{Argument}
+% \end{syntax}
+% Descriptive text here ...
+% \end{function}
+% \end{verbatim}
+% \hrulefill
+% \par
+% \hspace*{0.25\textwidth}
+% \begin{minipage}{0.5\textwidth}
+% \begin{function}{\package_function_one:N, \package_function_two:n}
+% \begin{syntax}
+% \cs[no-index]{package_function_one:N} \meta{cs}
+% \cs[no-index]{package_function_two:n} \marg{Argument}
+% \end{syntax}
+% \emph{Descriptive text here …}
+% \end{function}
+% \end{minipage}
+% \end{framed}
+%
+% Function environments take an optional argument to indicate whether
+% the function(s) it describes are expandable (use |EXP|) or
+% restricted-expandable (use |rEXP|) or defined in conditional forms
+% (use |TF|, |pTF|, or |noTF|). Note that |pTF| implies |EXP| since
+% predicates must always be expandable, and that |noTF| means that the
+% function without |TF| should be documented in addition to |TF|. For
+% the conditional forms |TF| and |pTF|, the argument of the
+% \env{function} environment is \emph{not} in fact a command that
+% exists: in the example below, \cs[no-index]{tl_if_empty:N} does not
+% exist, but its conditional forms \cs{tl_if_empty:NT},
+% \cs{tl_if_empty:NF}, \cs{tl_if_empty:NTF} and predicate form
+% \cs{tl_if_empty_p:N} exist:
+% \begin{framed}
+% \vspace{-\baselineskip}
+% \begin{verbatim}
+% \begin{function}[pTF]{\tl_if_empty:N, \tl_if_empty:c}
+% \begin{syntax}
+% \cs{tl_if_empty_p:N} \meta{tl~var}
+% \cs{tl_if_empty:NTF} \meta{tl~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list variable} is entirely empty
+% (\emph{i.e.}~contains no tokens at all).
+% \end{function}
+% \end{verbatim}
+% \hrulefill
+% \par
+% \hspace*{0.25\textwidth}
+% \begin{minipage}{0.5\textwidth}
+% \begin{function}[pTF]{\tl_if_empty:N, \tl_if_empty:c}
+% \begin{syntax}
+% \cs{tl_if_empty_p:N} \meta{tl~var}
+% \cs{tl_if_empty:NTF} \meta{tl~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list variable} is entirely empty
+% (\emph{i.e.}~contains no tokens at all).
+% \end{function}
+% \end{minipage}
+% \end{framed}
+%
+% \DescribeEnv{texnote}
+% This environment is used to call out sections within \env{function}
+% and similar environments that are only of interest to seasoned
+% \TeX{} developers.
+%
+% \subsection{Describing functions in the implementation}
+%
+% \DescribeEnv{macro}
+% The well-used environment from \LaTeXe{} for marking up the
+% implementation of macros/functions remains the \env{macro}
+% environment. Some changes in \pkg{l3doc}: it now accepts
+% comma-separated lists of functions, to avoid a very large number of
+% consecutive |\end{macro}| statements.
+% Spaces and new lines are ignored (the option |[verb]| prevents this).
+% \begin{verbatim}
+% % \begin{macro}{\foo:N, \foo:c}
+% % \begin{macrocode}
+% ... code for \foo:N and \foo:c ...
+% % \end{macrocode}
+% % \end{macro}
+% \end{verbatim}
+% If you are documenting an auxiliary macro, it's generally not
+% necessary to highlight it as much and you also don't need to check it
+% for, say, having a test function and having a documentation chunk
+% earlier in a \env{function} environment. \pkg{l3doc} will pick up these
+% cases from the presence of |__| in the name, or you may force marking
+% as internal by using |\begin{macro}[int]| to mark it as such. The margin
+% call-out is then printed in grey for such cases.
+%
+% For documenting \pkg{expl3}-type conditionals, you may also pass this
+% environment a |TF| option (and omit it from the function name) to
+% denote that the function is provided with |T|, |F|, and |TF| suffixes.
+% A similar |pTF| option prints both |TF| and |_p| predicate forms.
+% An option |noTF| prints both the |TF| forms and a form with neither
+% |T| nor |F|, to document functions such as \cs[no-index]{prop_get:NN}
+% which also have conditional forms (\cs[no-index]{prop_get:NNTF}).
+%
+% In a very small number of cases, there is no user documentation for
+% a \enquote{public} function. In these rare cases, the option
+% |no-user-doc| may be added to suppress the undefined reference that
+% would otherwise then arises.
+%
+% \DescribeMacro{\TestFiles}
+% \cs{TestFiles}\marg{list of files} is used to indicate which test
+% files are used for the current code; they are printed in the
+% documentation.
+%
+% \DescribeMacro{\UnitTested}
+% Within a \env{macro} environment, it is a good idea to mark whether a
+% unit test has been created for the commands it defines. This is
+% indicated by writing \cs{UnitTested} anywhere within |\begin{macro}|
+% \dots |\end{macro}|.
+%
+% If the class option |checktest| is enabled, then it is an \emph{error}
+% to have a \env{macro} environment without a call to
+% \file{Testfiles}. This is intended for large packages such as
+% \pkg{expl3} that should have absolutely comprehensive tests suites and
+% whose authors may not always be as sharp at adding new tests with new
+% code as they should be.
+%
+% \DescribeMacro{\TestMissing}
+% If a function is missing a test, this may be flagged by writing (as
+% many times as needed) \cs{TestMissing} \marg{explanation of test
+% required}. These missing tests are summarised in the listing
+% printed at the end of the compilation run.
+%
+% \DescribeEnv{variable}
+% When documenting variable definitions, use the \env{variable}
+% environment instead. Here it behaves identically to the
+% \env{macro} environment, except that if the class option |checktest|
+% is enabled, variables are not required to have a test file.
+%
+% \DescribeEnv{arguments}
+% Within a \env{macro} environment, you may use the \env{arguments}
+% environment to describe the arguments taken by the function(s). It
+% behaves like a modified enumerate environment.
+% \begin{verbatim}
+% % \begin{macro}{\foo:nn, \foo:VV}
+% % \begin{arguments}
+% % \item Name of froozle to be frazzled
+% % \item Name of muble to be jubled
+% % \end{arguments}
+% % \begin{macrocode}
+% ... code for \foo:nn and \foo:VV ...
+% % \end{macrocode}
+% % \end{macro}
+% \end{verbatim}
+%
+%
+% \subsection{Keeping things consistent}
+%
+% Whenever a function is either documented or defined with
+% \env{function} and \env{macro} respectively, its name is stored in a
+% sequence for later processing.
+%
+% At the end of the document (\emph{i.e.}, after the \file{.dtx} file
+% has finished processing), the list of names is analysed to check
+% whether all defined functions have been documented and vice versa. The
+% results are printed in the console output.
+%
+% If you need to do more serious work with these lists of names, take a
+% look at the implementation for the data structures and methods used to
+% store and access them directly.
+%
+% \subsection{Documenting templates}
+%
+% The following macros are provided for documenting templates; might end
+% up being something completely different but who knows.
+% \begin{quote}\parskip=0pt\obeylines
+% |\begin{TemplateInterfaceDescription}| \Arg{template type name}
+% | \TemplateArgument{none}{---}|
+% \textsc{or one or more of these:}
+% | \TemplateArgument| \Arg{arg no} \Arg{meaning}
+% \textsc{and}
+% |\TemplateSemantics|
+% | | \meta{text describing the template type semantics}
+% |\end{TemplateInterfaceDescription}|
+% \end{quote}
+%
+% \begin{quote}\parskip=0pt\obeylines
+% |\begin{TemplateDescription}| \Arg{template type name} \Arg{name}
+% \textsc{one or more of these:}
+% | \TemplateKey| \marg{key name} \marg{type of key}
+% | |\marg{textual description of meaning}
+% | |\marg{default value if any}
+% \textsc{and}
+% |\TemplateSemantics|
+% | | \meta{text describing special additional semantics of the template}
+% |\end{TemplateDescription}|
+% \end{quote}
+%
+% \begin{quote}\parskip=0pt\obeylines
+% |\begin{InstanceDescription}| \oarg{text to specify key column width (optional)}
+% \hfill\marg{template type name}\marg{instance name}\marg{template name}
+% \textsc{one or more of these:}
+% | \InstanceKey| \marg{key name} \marg{value}
+% \textsc{and}
+% |\InstanceSemantics|
+% | | \meta{text describing the result of this instance}
+% |\end{InstanceDescription}|
+% \end{quote}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3doc} implementation}
+%
+% \begin{macrocode}
+%<*class>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=codedoc>
+% \end{macrocode}
+%
+% \subsection{Variables}
+%
+% \begin{variable}{\g_docinput_clist}
+% The list of files which have been input through \cs{DocInput}.
+% \begin{macrocode}
+\clist_new:N \g_docinput_clist
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_doc_functions_seq, \g_doc_macros_seq}
+% All functions documented through \env{function}, and all macros
+% introduced through \env{macro}. They can be compared to see what
+% documentation or code is missing.
+% \begin{macrocode}
+\seq_new:N \g_doc_functions_seq
+\seq_new:N \g_doc_macros_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_detect_internals_bool, \l_@@_detect_internals_tl}
+% If \texttt{true}, \pkg{l3doc} will check for use of internal
+% commands \cs[no-index]{__\meta{pkg}_\ldots{}} from other packages in
+% the argument of the \texttt{macro} environment, and in the code typeset in
+% \texttt{macrocode} environments, but not in~\cs{cs}. Also a token list
+% to store temporary data for this purpose.
+% \begin{macrocode}
+\bool_new:N \l_@@_detect_internals_bool
+\bool_set_true:N \l_@@_detect_internals_bool
+\tl_new:N \l_@@_detect_internals_tl
+\tl_new:N \l_@@_detect_internals_cs_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_output_coffin}
+% The \env{function} environment is typeset by combining coffins
+% containing various pieces (function names, description, \emph{etc.})
+% into this coffin.
+% \begin{macrocode}
+\coffin_new:N \l_@@_output_coffin
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {\l_@@_functions_coffin, \l_@@_descr_coffin, \l_@@_syntax_coffin}
+% These coffins contain respectively the list of function names
+% (argument of the \env{function} environment), the text between
+% |\begin{function}| and |\end{function}|, and the syntax given in the
+% \env{syntax} environment.
+% \begin{macrocode}
+\coffin_new:N \l_@@_functions_coffin
+\coffin_new:N \l_@@_descr_coffin
+\coffin_new:N \l_@@_syntax_coffin
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_syntax_box}
+% The contents of the \env{syntax} environment are typeset in this box
+% before being transferred to \cs{l_@@_syntax_coffin}.
+% \begin{macrocode}
+\box_new:N \g_@@_syntax_box
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_in_function_bool}
+% True when inside a \texttt{function} or \texttt{variable}
+% environment. Used by the \texttt{syntax} environment to determine
+% its behaviour.
+% \begin{macrocode}
+\bool_new:N \l_@@_in_function_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_long_name_bool, \l_@@_trial_width_dim}
+% The boolean \cs{l_@@_long_name_bool} is \texttt{true} if the width
+% \cs{l_@@_trial_width_dim} of the coffin \cs{l_@@_functions_coffin}
+% (containing the current function names) is bigger than the space
+% available in the margin.
+% \begin{macrocode}
+\bool_new:N \l_@@_long_name_bool
+\dim_new:N \l_@@_trial_width_dim
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_nested_macro_int}
+% The nesting of \env{macro} environments (this is now~$0$ outside a
+% \env{macro} environment).
+% \begin{macrocode}
+\int_new:N \l_@@_nested_macro_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \l_@@_macro_tested_bool,
+% \g_@@_missing_tests_prop,
+% \g_@@_not_tested_seq,
+% \g_@@_testfiles_seq,
+% }
+% A boolean describing whether the current macro has tests, and some
+% global structures which contain information about test files and
+% which tests are missing.
+% \begin{macrocode}
+\bool_new:N \l_@@_macro_tested_bool
+\prop_new:N \g_@@_missing_tests_prop
+\seq_new:N \g_@@_not_tested_seq
+\seq_new:N \g_@@_testfiles_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \l_@@_macro_deprecated_bool ,
+% \l_@@_macro_internal_bool,
+% \l_@@_macro_nodoc_bool ,
+% \l_@@_macro_TF_bool,
+% \l_@@_macro_pTF_bool,
+% \l_@@_macro_noTF_bool,
+% \l_@@_macro_EXP_bool,
+% \l_@@_macro_rEXP_bool,
+% \l_@@_macro_var_bool,
+% \l_@@_override_module_tl,
+% \l_@@_macro_documented_tl,
+% }
+% Contain information about some options of function/macro
+% environments. We initialize \cs{l_@@_override_module_tl} to avoid
+% overriding module names by an empty name (meaning no module).
+% \begin{macrocode}
+\bool_new:N \l_@@_macro_deprecated_bool
+\bool_new:N \l_@@_macro_internal_bool
+\bool_new:N \l_@@_macro_nodoc_bool
+\bool_new:N \l_@@_macro_TF_bool
+\bool_new:N \l_@@_macro_pTF_bool
+\bool_new:N \l_@@_macro_noTF_bool
+\bool_new:N \l_@@_macro_EXP_bool
+\bool_new:N \l_@@_macro_rEXP_bool
+\bool_new:N \l_@@_macro_var_bool
+\tl_new:N \l_@@_override_module_tl
+\tl_set:Nn \l_@@_override_module_tl { \q_no_value }
+\tl_new:N \l_@@_macro_documented_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \g_@@_lmodern_bool,
+% \g_@@_checkfunc_bool,
+% \g_@@_checktest_bool,
+% \g_@@_cs_break_bool,
+% \g_@@_show_notes_bool,
+% \g_@@_kernel_bool
+% }
+% Information about package options.
+% \begin{macrocode}
+\bool_new:N \g_@@_lmodern_bool
+\bool_new:N \g_@@_checkfunc_bool
+\bool_new:N \g_@@_checktest_bool
+\bool_new:N \g_@@_kernel_bool
+\bool_new:N \g_@@_cs_break_bool
+\bool_new:N \g_@@_show_notes_bool
+\bool_gset_true:N \g_@@_cs_break_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_tmpa_tl, \l_@@_tmpb_tl, \l_@@_tmpa_int, \l_@@_tmpa_seq}
+% Some temporary variables.
+% \begin{macrocode}
+\tl_new:N \l_@@_tmpa_tl
+\tl_new:N \l_@@_tmpb_tl
+\int_new:N \l_@@_tmpa_int
+\int_new:N \l_@@_tmpa_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_names_block_tl}
+% List of local sequence variables (produced through
+% \cs{@@_lseq_name:n}), one for each set of variants in a
+% \env{function} or \env{macro} environment. More precisely these
+% sequences are named after the base forms, such as \cs{clist_count:n}
+% or \cs{clist_count:N} (which are not variants). Each of these
+% sequences have the base name (without any signature) as their first
+% item, followed by the list of variant's signatures, or
+% \cs{scan_stop:} to denote the absence of signature (no colon).
+% \begin{macrocode}
+\tl_new:N \l_@@_names_block_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_variants_seq}
+% Stores rather temporarily the list of variants (signatures only) of
+% a function/macro that is being documented. It is global because we
+% need it to keep its value throughout cells of an alignment.
+% \begin{macrocode}
+\seq_new:N \g_@@_variants_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_names_verb_bool}
+% Set to |true| if the main argument of a macro/function environment
+% should be used as is, without removing any comma or space.
+% \begin{macrocode}
+\bool_new:N \l_@@_names_verb_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_names_seq}
+% List of functions/environments/\ldots{} appearing as arguments of a
+% given \env{function} or \env{macro} environment. These are the
+% names after conversion of |_@@| and |@@| to |__|\meta{module name}
+% and other sanitizing.
+% \begin{macrocode}
+\seq_new:N \l_@@_names_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_nested_names_seq}
+% Collects all macros in nested \env{macro} environments, to use them
+% in the \enquote{End definition} text.
+% \begin{macrocode}
+\seq_new:N \g_@@_nested_names_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \l_@@_index_macro_tl, \l_@@_index_key_tl,
+% \l_@@_index_module_tl, \l_@@_index_internal_bool,
+% \l_@@_macro_do_not_index_tl
+% }
+% When analyzing a control sequence found within a \env{macrocode}
+% environment, \cs{l_@@_index_macro_tl} holds the control sequence
+% (partially a string), \cs{l_@@_index_key_tl} holds the future
+% sort key in the index, and \cs{l_@@_index_module_tl} is the
+% subindex in which the control sequence should be listed.
+% \cs{l_@@_index_internal_bool} indicates when the control sequence is
+% internal and should be indexed in a slightly different subindex.
+% Finally, \cs{l_@@_macro_do_not_index_tl} indicates control sequences
+% which should not be indexed in a specifiv \env{macro} envronment.
+% \begin{macrocode}
+\tl_new:N \l_@@_index_macro_tl
+\tl_new:N \l_@@_index_key_tl
+\tl_new:N \l_@@_index_module_tl
+\tl_new:N \l_@@_macro_do_not_index_tl
+\bool_new:N \l_@@_index_internal_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_module_name_tl}
+% The module name, set when reading a line |<@@=|\meta{module}|>|.
+% \begin{macrocode}
+\tl_new:N \g_@@_module_name_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_iow_rule_tl, \c_@@_iow_midrule_tl}
+% $40$~equal signs.
+% \begin{macrocode}
+\tl_const:Nn \c_@@_iow_rule_tl
+ { ======================================== }
+\tl_const:Nn \c_@@_iow_mid_rule_tl
+ { -------------------------------------- }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {\l_@@_macro_box, \l_@@_macro_index_box, \l_@@_macro_int}
+% A vertical box in which the names given to the macro environment are
+% typeset, a horizontal box in which we store the targets created by
+% indexing commands, and the number of macros so far (including those
+% from surrounding \env{macro} environments).
+% \begin{macrocode}
+\box_new:N \l_@@_macro_box
+\box_new:N \l_@@_macro_index_box
+\int_new:N \l_@@_macro_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \l_@@_cmd_tl,
+% \l_@@_cmd_index_tl,
+% \l_@@_cmd_module_tl,
+% \l_@@_cmd_noindex_bool,
+% \l_@@_cmd_replace_bool,
+% }
+% Variables used to control the behaviour of \cs{cmd}, \cs{cs} and
+% \cs{tn}.
+% \begin{macrocode}
+\tl_new:N \l_@@_cmd_tl
+\tl_new:N \l_@@_cmd_index_tl
+\tl_new:N \l_@@_cmd_module_tl
+\bool_new:N \l_@@_cmd_noindex_bool
+\bool_new:N \l_@@_cmd_replace_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_in_implementation_bool}
+% This boolean is \texttt{true} within the \env{implementation}
+% environment, and \texttt{false} anywhere else.
+% \begin{macrocode}
+\bool_new:N \l_@@_in_implementation_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \g_@@_typeset_documentation_bool,
+% \g_@@_typeset_implementation_bool
+% }
+% These booleans control whether the documentation/implementation
+% should be typeset. By default both should be.
+% \begin{macrocode}
+\bool_new:N \g_@@_typeset_documentation_bool
+\bool_new:N \g_@@_typeset_implementation_bool
+\bool_set_true:N \g_@@_typeset_documentation_bool
+\bool_set_true:N \g_@@_typeset_implementation_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_base_name_tl, \l_@@_variants_prop}
+% The name of the macro which is being documented (without its
+% signature), and a property list mapping base forms of variants to
+% all variants which have the same base form.
+% \begin{macrocode}
+\tl_new:N \g_@@_base_name_tl
+\prop_new:N \l_@@_variants_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_function_label_clist, \l_@@_no_label_bool}
+% Option of a \env{function} environment which replaces the label that
+% would normally be inserted by labels for the given list of control
+% sequences. This is only useful to avoid duplicate labels when a
+% function's documentation appears multiple times.
+% \begin{macrocode}
+\clist_new:N \l_@@_function_label_clist
+\bool_new:N \l_@@_no_label_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_date_added_tl, \l_@@_date_updated_tl}
+% Values of some options of the \env{function} environment.
+% \begin{macrocode}
+\tl_new:N \l_@@_date_added_tl
+\tl_new:N \l_@@_date_updated_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_macro_argument_tl}
+% Save the argument of a \env{macro} or \env{function} environment for
+% use in error messages.
+% \begin{macrocode}
+\tl_new:N \l_@@_macro_argument_tl
+% \end{macrocode}
+% \end{variable}
+%
+% ^^A Bruno: what does the next line do?
+% \begin{macrocode}
+% \int_new:N \c@CodelineNo
+% \end{macrocode}
+%
+% \subsection{Variants and helpers}
+%
+% \begin{macro}{\@@_tmpa:w, \@@_tmpb:w}
+% Auxiliary macros for temporary use.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_tmpa:w ?
+\cs_new_eq:NN \@@_tmpb:w ?
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \seq_set_split:NoV,
+% \tl_to_str:f
+% }
+% A few missing variants.
+% \begin{macrocode}
+\cs_generate_variant:Nn \seq_set_split:Nnn { NoV }
+\cs_generate_variant:Nn \tl_to_str:n { f }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\@@_if_almost_str:n}
+% Used to test if the argument of |\cmd| or other macros to be indexed
+% is almost a string or not: for instance this is \texttt{false} if |#1|
+% contains |\meta{...}|. The surprising |f|-expansion is there to
+% cope with the case of |#1| starting with \cs{c_backslash_str}
+% which should be expanded and considered to be \enquote{normal}.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \@@_if_almost_str:n #1 { TF , T , F }
+ {
+ \int_compare:nNnTF
+ { \tl_count:n {#1} }
+ < { \tl_count:e { \tl_to_str:f {#1} } }
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+\prg_generate_conditional_variant:Nnn \@@_if_almost_str:n { V } { T }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_trim_right:Nn, \@@_trim_right:No}
+% Removes all material after |#2| in the token list variable~|#1|.
+% Perhaps combine with \cs{@@_key_trim_module:n}?
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_trim_right:Nn #1#2
+ {
+ \cs_set:Npn \@@_tmp:w ##1 #2 ##2 \q_stop { \exp_not:n {##1} }
+ \__kernel_tl_set:Nx #1 { \exp_after:wN \@@_tmp:w #1 #2 \q_stop }
+ }
+\cs_generate_variant:Nn \@@_trim_right:Nn { No }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\@@_str_if_begin:nn, \@@_str_if_begin:oo}
+% True if the first string starts with the second.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \@@_str_if_begin:nn #1#2 { TF , T , F }
+ {
+ \tl_if_in:ooTF
+ { \exp_after:wN \scan_stop: \tl_to_str:n {#1} }
+ { \exp_after:wN \scan_stop: \tl_to_str:n {#2} }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn \@@_str_if_begin:nn
+ { oo } { TF , T , F }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replace_at_at:N}
+% \begin{macro}{\@@_replace_at_at_aux:Nn}
+% The goal is to replace |@@| by the current module name. We take
+% advantage of this function to also detect internal macros. If there is
+% no \meta{module~name}, do nothing. Otherwise, sanitize the catcodes
+% of |@| and~|_|, temporarily change |@@@@| to |aa| with different catcodes and later to |@@|, and replace |__@@| and |_@@| and |@@| by
+% |__|\meta{module~name}. The result contains |_| with category
+% code letter because this is what the |macrocode| environment
+% expects. Other use cases can apply \cs{tl_to_str:n} if needed.
+% Note that we include spaces between the
+% |@| in the code below, since it is also processed through the same
+% replacement rules.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replace_at_at:N #1
+ {
+ \tl_if_empty:NF \g_@@_module_name_tl
+ {
+ \exp_args:NNo \@@_replace_at_at_aux:Nn
+ #1 \g_@@_module_name_tl
+ }
+ }
+\cs_new_protected:Npe \@@_replace_at_at_aux:Nn #1#2
+ {
+ \tl_replace_all:Nnn #1 { \token_to_str:N @ } { @ }
+ \tl_replace_all:Nnn #1 { \token_to_str:N _ } { _ }
+ \tl_replace_all:Nnn #1 { @ @ @ @ } { \token_to_str:N a a }
+ \tl_replace_all:Nnn #1 { _ _ @ @ } { _ _ #2 }
+ \tl_replace_all:Nnn #1 { _ @ @ } { _ _ #2 }
+ \tl_replace_all:Nnn #1 { @ @ } { _ _ #2 }
+ \tl_replace_all:Nnn #1 { \token_to_str:N a a } { @ @ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_detect_internals:N,
+% \@@_detect_internals_aux:N,
+% \@@_if_detect_internals_ok:NF
+% }
+% After splitting at each |__| and removing the leading item from the
+% sequence (since it does not follow |__|), remove everything after
+% any space or end-of-line to get a good approximation of the control
+% sequence (for the warning message). Then check if that starts with
+% something allowed: |@@| module name and |:| or |_|, or if the
+% relevant boolean is set |kernel_| (it seems safe to assume we will
+% not define a |\__kernel:...| command). For the message itself
+% remove anything after any |_| or |:| (with either catcode) to get a
+% guess of the module name.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_detect_internals:N #1
+ {
+ \bool_if:NT \l_@@_detect_internals_bool
+ { \@@_detect_internals_aux:N #1 }
+ }
+\group_begin:
+ \char_set_catcode_active:N \^^M
+ \cs_new_protected:Npn \@@_detect_internals_aux:N #1
+ {
+ \tl_set_eq:NN \l_@@_detect_internals_tl #1
+ \tl_replace_all:NVn \l_@@_detect_internals_tl \c_underscore_str { _ }
+ \seq_set_split:NnV \l_@@_tmpa_seq { _ _ } \l_@@_detect_internals_tl
+ \seq_pop_left:NN \l_@@_tmpa_seq \l_@@_detect_internals_tl
+ \seq_map_variable:NNn \l_@@_tmpa_seq \l_@@_detect_internals_tl
+ {
+ \@@_trim_right:No \l_@@_detect_internals_tl
+ \c_catcode_active_space_tl
+ \@@_trim_right:Nn \l_@@_detect_internals_tl ^^M
+ \@@_if_detect_internals_ok:NF \l_@@_detect_internals_tl
+ {
+ \tl_set_eq:NN \l_@@_detect_internals_cs_tl \l_@@_detect_internals_tl
+ \@@_trim_right:Nn \l_@@_detect_internals_tl _
+ \@@_trim_right:Nn \l_@@_detect_internals_tl :
+ \@@_trim_right:No \l_@@_detect_internals_tl { \token_to_str:N : }
+ \msg_warning:nneee { l3doc } { foreign-internal }
+ { \tl_to_str:N \l_@@_detect_internals_cs_tl }
+ { \tl_to_str:N \l_@@_detect_internals_tl }
+ { \tl_to_str:N \g_@@_module_name_tl }
+ }
+ }
+ }
+\group_end:
+\prg_new_protected_conditional:Npnn \@@_if_detect_internals_ok:N #1 { F }
+ {
+ \@@_str_if_begin:ooTF {#1} { \g_@@_module_name_tl _ }
+ { \prg_return_true: }
+ {
+ \@@_str_if_begin:ooTF {#1} { \g_@@_module_name_tl : }
+ { \prg_return_true: }
+ {
+ \bool_if:NTF \g_@@_kernel_bool
+ {
+ \@@_str_if_begin:ooTF {#1} { kernel _ }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_signature_base_form:n}
+% \begin{macro}
+% {\@@_signature_base_form_aux:n, \@@_signature_base_form_aux:w}
+% Expands to the \enquote{base form} of the signature. For instance,
+% given |noxcfvV| it would obtain |nnnNnnn|, or given |ow| it would
+% obtain |nw|. The loop stops at the first token that is not
+% recognized; the rest is enclosed in \cs{exp_not:n}.
+% \begin{macrocode}
+\cs_new:Npn \@@_signature_base_form:n #1
+ { \@@_signature_base_form_aux:n #1 \q_stop }
+\cs_new:Npn \@@_signature_base_form_aux:n #1
+ {
+ \str_case:nnTF {#1}
+ {
+ { N } { N }
+ { c } { N }
+ { n } { n }
+ { o } { n }
+ { f } { n }
+ { e } { n }
+ { x } { n }
+ { V } { n }
+ { v } { n }
+ }
+ { \@@_signature_base_form_aux:n }
+ { \@@_signature_base_form_aux:w #1 }
+ }
+\cs_new:Npn \@@_signature_base_form_aux:w #1 \q_stop
+ { \exp_not:n {#1} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_predicate_from_base:n}
+% Get predicate from a function's base name. The code is not broken
+% by functions with no signature. The |n|-type version can be used
+% for keys and other non-control sequences. The output after
+% |e|-expansion is a string.
+% \begin{macrocode}
+\cs_new:Npn \@@_predicate_from_base:n #1
+ {
+ \@@_get_function_name:n {#1}
+ \tl_to_str:n { _p: }
+ \@@_get_function_signature:n {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_split_function_do:nn, \@@_split_function_do:on}
+% \begin{macro}{\@@_get_function_name:n, \@@_get_function_signature:n}
+% \begin{macro}{\@@_split_function_auxi:w, \@@_split_function_auxii:w}
+% Similar to internal functions defined in \pkg{l3basics}, but here we
+% operate on strings directly rather than control sequences.
+% \begin{macrocode}
+\cs_new:Npn \@@_get_function_name:n #1
+ { \@@_split_function_do:nn {#1} { \use_i:nnn } }
+\cs_new:Npn \@@_get_function_signature:n #1
+ { \@@_split_function_do:nn {#1} { \use_ii:nnn } }
+\cs_set_protected:Npn \@@_tmpa:w #1
+ {
+ \cs_new:Npn \@@_split_function_do:nn ##1
+ {
+ \exp_after:wN \@@_split_function_auxi:w
+ \tl_to_str:n {##1} \q_mark \c_true_bool
+ #1 \q_mark \c_false_bool
+ \q_stop
+ }
+ \cs_new:Npn \@@_split_function_auxi:w
+ ##1 #1 ##2 \q_mark ##3##4 \q_stop ##5
+ { \@@_split_function_auxii:w {##5} ##1 \q_mark \q_stop {##2} ##3 }
+ \cs_new:Npn \@@_split_function_auxii:w
+ ##1##2 \q_mark ##3 \q_stop
+ { ##1 {##2} }
+ }
+\exp_args:No \@@_tmpa:w { \token_to_str:N : }
+\cs_generate_variant:Nn \@@_split_function_do:nn { o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_key_get_base:nN}
+% Get the base form of a function and store it. As part of getting
+% the base form, change trailing |T| or |F| to |TF|, skipping that
+% change if the function contains no colon to avoid changing for
+% instance some names ending in \texttt{PDF} or similar. The various
+% letters |z| serve as end-delimiters different from any outcome of
+% \cs{tl_to_str:n}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_key_get_base:nN #1#2
+ {
+ \@@_if_almost_str:nTF {#1}
+ {
+ \@@_key_get_base_TF:nN {#1} \l_@@_tmpa_tl
+ \__kernel_tl_set:Nx #2
+ { \@@_split_function_do:on \l_@@_tmpa_tl { \@@_base_form_aux:nnN } }
+ }
+ { \tl_set:Nn #2 {#1} }
+ }
+\cs_new:Npe \@@_key_get_base_TF:nN #1#2
+ {
+ \__kernel_tl_set:Nx #2 { \exp_not:N \tl_to_str:n {#1} }
+ \tl_if_in:NoF #2 { \tl_to_str:n {:} }
+ { \exp_not:N \prg_break: }
+ \tl_if_in:onT { #2 z } { \tl_to_str:n {TF} z }
+ { \exp_not:N \prg_break: }
+ \tl_if_in:onT { #2 z } { \tl_to_str:n {T} z }
+ {
+ \tl_put_right:Nn #2 { \tl_to_str:n {F} }
+ \exp_not:N \prg_break:
+ }
+ \tl_if_in:onT { #2 z } { \tl_to_str:n {F} z }
+ {
+ \tl_put_right:Nn #2 { z }
+ \tl_replace_once:Nnn #2 { \tl_to_str:n {F} z } { \tl_to_str:n {TF} }
+ \exp_not:N \prg_break:
+ }
+ \exp_not:N \prg_break_point:
+ }
+\cs_new:Npn \@@_base_form_aux:nnN #1#2#3
+ {
+ \exp_not:n {#1}
+ \bool_if:NT #3
+ {
+ \token_to_str:N :
+ \bool_lazy_or:nnTF
+ { \str_if_eq_p:nn { #1 ~ } { \exp_args } }
+ { \str_if_eq_p:nn { #1 ~ } { \exp_last_unbraced } }
+ { \exp_not:n {#2} }
+ { \@@_signature_base_form:n {#2} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_base_form_signature_do:nnn}
+% Do |#2{#1}| if there is no signature, or if |#1| contains two colons
+% in a row (this covers the weird function |\::N| and so on).
+% Otherwise apply |#3| with the following two arguments: the base form
+% of |#1|, and the original signature with an extra pair of braces.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_base_form_signature_do:nnn #1#2#3
+ {
+ \@@_split_function_do:nn {#1}
+ { \@@_base_form_aux:nnnnnN {#1} {#2} {#3} }
+ }
+\cs_new_protected:Npn \@@_base_form_aux:nnnnnN #1#2#3#4#5#6
+ {
+ \bool_if:NTF #6
+ {
+ \tl_if_head_eq_charcode:nNTF {#4} :
+ { #2 {#1} }
+ {
+ \use:e
+ {
+ \exp_not:n {#3}
+ { \@@_base_form_aux:nnN {#4} {#5} #6 }
+ }
+ {#4} {#5}
+ }
+ }
+ { #2 {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\@@_date_compare:nNn}
+% \begin{macro}{\@@_date_compare_aux:nnnNnnn, \@@_date_compare_aux:w}
+% Expects |#1| and |#3| to be dates in the format YYYY-MM-DD (but
+% accepts YYYY or YYYY-MM too). Compares them using |#2| (one of |<|,
+% |=|, |>|), filling in zeros for missing data.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_date_compare:nNn #1#2#3 { TF , T , F , p }
+ { \@@_date_compare_aux:w #1--- \q_mark #2 #3--- \q_stop }
+\cs_new:Npn \@@_date_compare_aux:w
+ #1 - #2 - #3 - #4 \q_mark #5 #6 - #7 - #8 - #9 \q_stop
+ {
+ \@@_date_compare_aux:nnnNnnn
+ { \tl_if_empty:nTF {#1} { 0 } {#1} }
+ { \tl_if_empty:nTF {#2} { 0 } {#2} }
+ { \tl_if_empty:nTF {#3} { 0 } {#3} }
+ #5
+ { \tl_if_empty:nTF {#6} { 0 } {#6} }
+ { \tl_if_empty:nTF {#7} { 0 } {#7} }
+ { \tl_if_empty:nTF {#8} { 0 } {#8} }
+ }
+\cs_new:Npn \@@_date_compare_aux:nnnNnnn #1#2#3#4#5#6#7
+ {
+ \int_compare:nNnTF {#1} = {#5}
+ {
+ \int_compare:nNnTF {#2} = {#6}
+ {
+ \int_compare:nNnTF {#3} #4 {#7}
+ { \prg_return_true: } { \prg_return_false: }
+ }
+ {
+ \int_compare:nNnTF {#2} #4 {#6}
+ { \prg_return_true: } { \prg_return_false: }
+ }
+ }
+ {
+ \int_compare:nNnTF {#1} #4 {#5}
+ { \prg_return_true: } { \prg_return_false: }
+ }
+ \use_none:n
+ \q_stop
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_gprop_name:n, \@@_lseq_name:n}
+% We need to keep track of some information about control sequences
+% (and other strings) that are being (or have been) documented. Some
+% is stored into global props and some into local seqs, whose name
+% does not follow conventions: it is \cs[no-index]{g_@@} or
+% \cs[no-index]{l_@@} followed by a space and by the string, which can
+% be arbitrary. We cannot reasonably use a single big |prop| for
+% speed reasons.
+% \begin{macrocode}
+\cs_new:Npn \@@_gprop_name:n #1 { g_@@ ~ \tl_to_str:n {#1} }
+\cs_new:Npn \@@_lseq_name:n #1 { l_@@ ~ \tl_to_str:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% \begin{macrocode}
+\msg_new:nnnn { l3doc } { no-signature-TF }
+ { Function/macro~'#1'~cannot~be~turned~into~a~conditional. }
+ {
+ A~function~or~macro~environment~with~option~pTF,~TF~or~noTF~
+ received~the~argument~'#1'.~This~function's~name~has~no~
+ ':'~hence~it~is~not~clear~where~to~add~'_p'~or~'TF'.~
+ Please~follow~expl3~naming~conventions.
+ }
+\msg_new:nnn { l3doc } { date-format }
+ { The~date~'#1'~should~be~given~in~YYYY-MM-DD~format. }
+\msg_new:nnn { l3doc } { future-date }
+ { The~added/updated~date~'#2'~of~'#1'~is~in~the~future. }
+\msg_new:nnn { l3doc } { syntax-nested-function }
+ {
+ The~'syntax'~environment~should~be~used~in~the~
+ innermost~'function'~environment.
+ }
+\msg_new:nnn { l3doc } { multiple-syntax }
+ {
+ The~'syntax'~environment~should~only~be~used~once~in~
+ a~'function'~environment.
+ }
+\msg_new:nnn { l3doc } { deprecated-option }
+ { The~option~'#1'~has~been~deprecated~for~'#2'. }
+\msg_new:nnn { l3doc } { foreign-internal }
+ {
+ A~control~sequence~of~the~form~'...__#1'~was~used.~
+ It~should~only~be~used~in~the~module~'#2'
+ \tl_if_empty:nF {#3} { ,~not~in~'#3' } .
+ }
+% \end{macrocode}
+%
+% \subsection{Options and configuration}
+%
+% \begin{macrocode}
+\DeclareKeys [ l3doc / options ]
+ {
+ a5paper .code:n = \@latexerr { Option~not~supported } { } ,
+ full .code:n =
+ {
+ \bool_gset_true:N \g_@@_typeset_documentation_bool
+ \bool_gset_true:N \g_@@_typeset_implementation_bool
+ } ,
+ onlydoc .code:n =
+ {
+ \bool_gset_true:N \g_@@_typeset_documentation_bool
+ \bool_gset_false:N \g_@@_typeset_implementation_bool
+ } ,
+ check .bool_gset:N = \g_@@_checkfunc_bool ,
+ checktest .bool_gset:N = \g_@@_checktest_bool ,
+ kernel .bool_gset:N = \g_@@_kernel_bool ,
+ stdmodule .bool_gset_inverse:N = \g_@@_kernel_bool ,
+ lm-default .bool_gset:N = \g_@@_lmodern_bool ,
+ cs-break .bool_gset_inverse:N = \g_@@_cs_break_bool ,
+ cs-break-nohyphen .code:n = \PassOptionsToPackage{nohyphen}{underscore} ,
+ show-notes .bool_gset:N = \g_@@_show_notes_bool,
+ hide-notes .bool_gset_inverse:N = \g_@@_show_notes_bool
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareUnknownKeyHandler [ l3doc / options ]
+ { \PassOptionsToClass { \CurrentOption } { article } }
+\SetKeys [ l3doc / options ]
+ { full , check = false , checktest = false , lm-default }
+\PassOptionsToClass { a4paper } { article }
+% \end{macrocode}
+%
+% Input a local configuration file, if it exists, with a message to the
+% console that this has happened. Since we distribute a \file{.cfg} file
+% with the class, this should usually always be true. Therefore, check
+% for \cs{ExplMakeTitle} (defined in \enquote{our} \file{.cfg} file) and
+% only output the informational message if it's not found.
+%
+% \begin{macrocode}
+\msg_new:nnn { l3doc } { input-cfg }
+ { Local~config~file~l3doc.cfg~loaded. }
+\file_if_exist:nT { l3doc.cfg }
+ {
+ \file_input:n { l3doc.cfg }
+ \cs_if_exist:cF { ExplMakeTitle }
+ { \msg_info:nn { l3doc } { input-cfg } }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ProcessKeyOptions [ l3doc / options ]
+% \end{macrocode}
+%
+%
+% \subsection{Class and package loading}
+%
+% \begin{macrocode}
+\LoadClass{article}
+\RequirePackage{doc}
+\RequirePackage
+ {
+ array,
+ alphalph,
+ amsmath,
+ amssymb,
+ booktabs,
+ color,
+ colortbl,
+ hologo,
+ enumitem,
+ pifont,
+ textcomp,
+ trace,
+ csquotes,
+ fancyvrb,
+ underscore,
+ verbatim
+ }
+\raggedbottom
+% \end{macrocode}
+%
+% Depending on the option, load the package \pkg{lmodern} to set the
+% font. Then replace the italic typewriter font with the oblique shape
+% instead; the former makes my skin crawl. (Will, Aug 2011)
+% \begin{macrocode}
+\bool_if:NT \g_@@_lmodern_bool
+ {
+ \RequirePackage[T1]{fontenc}
+ \RequirePackage{lmodern}
+ \group_begin:
+ \ttfamily
+ \DeclareFontShape{T1}{lmtt}{m}{it}{<->ec-lmtto10}{}
+ \group_end:
+ }
+% \end{macrocode}
+%
+% Must be last, as usual.
+% \begin{macrocode}
+\RequirePackage{hypdoc}
+% \end{macrocode}
+%
+% \subsection{Configuration and tweaks}
+%
+% \begin{macro}{\MakePrivateLetters}
+% A few more letters are \enquote{private} in a \LaTeX3 programming
+% environment.
+% \begin{macrocode}
+\cs_gset:Npn \MakePrivateLetters
+ {
+ \char_set_catcode_letter:N \@
+ \char_set_catcode_letter:N \_
+ \char_set_catcode_letter:N \:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{CodelineNo}
+% Some configurations which have to do with line numbering.
+% \begin{macrocode}
+\setcounter{StandardModuleDepth}{1}
+\@addtoreset{CodelineNo}{part}
+\tl_replace_once:Nnn \theCodelineNo
+ { \HDorg@theCodelineNo }
+ { \textcolor[gray]{0.5} { \sffamily\tiny\arabic{CodelineNo} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\verbatim, \endverbatim}
+% In \file{.dtx} documents, the \env{verbatim} environment adds extra
+% space because it only removes the first \enquote{\%} sign, and not
+% the indentation (typically a space). Fix it with \pkg{fancyvrb}:
+% \begin{macrocode}
+\fvset{gobble=2}
+\cs_gset_eq:NN \verbatim \Verbatim
+\cs_gset_eq:NN \endverbatim \endVerbatim
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ifnot@excluded}
+% This function tests whether a macro name stored in
+% \tn{macro@namepart} was excluded from indexing by \tn{DoNotIndex}.
+% Rather than trying to fix catcodes that come into here, turn
+% everything to string catcodes. This is slightly inefficient as we
+% could have ensured that \tn{index@excludelist} has string catcodes
+% in the first place.
+% \begin{macrocode}
+\cs_set_protected:Npn \ifnot@excluded
+ {
+ \exp_args:Nee \expanded@notin
+ { \c_backslash_str \tl_to_str:N \macro@namepart , }
+ { \exp_args:NV \tl_to_str:n \index@excludelist }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\pdfstringnewline}
+% \begin{macro}{\@@_pdfstring_newline:w}
+% We avoid some hyperref warnings by making |\\| (almost) trivial in
+% bookmarks: more precisely it might be used with a star and an
+% optional argument, which we thus remove using an \pkg{ltcmd}
+% expandable command. Since there cannot be trailing optional
+% arguments, pick up an extra mandatory one and put it back.
+% \begin{macrocode}
+\cs_new:Npn \pdfstringnewline { : ~ }
+\DeclareExpandableDocumentCommand
+ { \@@_pdfstring_newline:w } { s o m } { \pdfstringnewline #3 }
+\pdfstringdefDisableCommands
+ { \cs_set_eq:NN \\ \@@_pdfstring_newline:w }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Design}
+%
+% Increase the text width slightly so that width the standard fonts
+% 72~columns of code may appear in a \env{macrocode} environment.
+% Increase the marginpar width slightly, for long command names. And
+% increase the left margin by a similar amount.
+% \begin{macrocode}
+\setlength \textwidth { 385pt }
+\addtolength \marginparwidth { 30pt }
+\addtolength \oddsidemargin { 20pt }
+\addtolength \evensidemargin { 20pt }
+% \end{macrocode}
+% (These were introduced when \cls{article} was the documentclass, but
+% I've left them here for now to remind me to do something about them
+% later.)
+%
+% \begin{macro}{\list}
+% \begin{macro}{\@@_oldlist:nn}
+% Customise lists.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_oldlist:nn \list
+\cs_gset:Npn \list #1 #2
+ { \@@_oldlist:nn {#1} { #2 \dim_zero:N \listparindent } }
+\setlength \parindent { 2em }
+\setlength \itemindent { 0pt }
+\setlength \parskip { 0pt plus 3pt minus 0pt }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\partname}
+% Use \enquote{File} as a name in Part titles.
+% \begin{macrocode}
+\tl_gset:Nn \partname {File}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l@section, \l@subsection}
+% Customise the table of contents (as we have so many sections).
+% Different design and/or structure is called for.
+% \begin{macrocode}
+\@addtoreset{section}{part}
+\cs_gset:Npn \l@section #1#2
+ {
+ \ifnum \c@tocdepth >\z@
+ \addpenalty\@secpenalty
+ \addvspace{1.0em \@plus\p@}
+ \setlength\@tempdima{2.5em} % was 1.5em
+ \begingroup
+ \parindent \z@ \rightskip \@pnumwidth
+ \parfillskip -\@pnumwidth
+ \leavevmode \bfseries
+ \advance\leftskip\@tempdima
+ \hskip -\leftskip
+ #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
+ \endgroup
+ \fi
+ }
+\cs_gset:Npn \l@subsection
+ { \@dottedtocline{2}{2.5em}{2.3em} } % #2 = 1.5em
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Text markup}
+%
+% Make "|" and |"| be \enquote{short verb} characters, but not in the
+% document preamble, where an active character may interfere with
+% packages that are loaded. Remove these short-hands at the end of the
+% document before reading the \file{.aux} file, as they may appear in
+% labels (for instance, \pkg{l3fp} documents an operation "||").
+% \begin{macrocode}
+\AtBeginDocument
+ {
+ \MakeShortVerb \"
+ \MakeShortVerb \|
+ }
+\AtEndDocument
+ {
+ \DeleteShortVerb \"
+ \DeleteShortVerb \|
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\eTeX, \IniTeX, \Lua, \LuaTeX, \pdfTeX, \XeTeX,
+% \pTeX, \upTeX, \epTeX, \eupTeX}
+% Some commands for logos.
+% \begin{macrocode}
+\providecommand*\eTeX{\hologo{eTeX}}
+\providecommand*\IniTeX{\hologo{iniTeX}}
+\providecommand*\Lua{Lua}
+\providecommand*\LuaTeX{\hologo{LuaTeX}}
+\providecommand*\pdfTeX{\hologo{pdfTeX}}
+\providecommand*\XeTeX{\hologo{XeTeX}}
+\providecommand*\pTeX{p\kern-.2em\hologo{TeX}}
+\providecommand*\upTeX{up\kern-.2em\hologo{TeX}}
+\providecommand*\epTeX{$\varepsilon$-\pTeX}
+\providecommand*\eupTeX{$\varepsilon$-\upTeX}
+\providecommand*\ConTeXt{\hologo{ConTeXt}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cmd, \cs, \tn}
+% They rely on a common auxiliary \cs{@@_cmd:nn} which receives as
+% arguments the options and some tokens whose string representation
+% starts with a backslash (to support cases such as |\cs{pkg_\ldots}|,
+% we do not turn the whole argument into a string).
+% \begin{macrocode}
+\DeclareDocumentCommand \cmd { O{} m }
+ { \@@_cmd:no {#1} { \token_to_str:N #2 } }
+\DeclareDocumentCommand \cs { O{} m }
+ { \@@_cmd:no {#1} { \c_backslash_str #2 } }
+\DeclareDocumentCommand \tn { O{} m }
+ {
+ \@@_cmd:no
+ { module = TeX , replace = false , #1 }
+ { \c_backslash_str #2 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\meta}
+% A document-level command.
+% \begin{macrocode}
+\DeclareDocumentCommand \meta { m }
+ { \texttt{ \@@_meta:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_pdfstring_cmd:w,
+% \@@_pdfstring_cs:w,
+% \@@_pdfstring_meta:w
+% }
+% To work within a bookmark, these commands must be expandable.
+% \begin{macrocode}
+\DeclareExpandableDocumentCommand
+ { \@@_pdfstring_cmd:w } { o m } { \token_to_str:N #2 }
+\DeclareExpandableDocumentCommand
+ { \@@_pdfstring_cs:w } { o m } { \textbackslash \tl_to_str:n {#2} }
+\cs_new:Npn \@@_pdfstring_meta:w #1
+ { < \tl_to_str:n {#1} > }
+\pdfstringdefDisableCommands
+ {
+ \cs_set_eq:NN \cmd \@@_pdfstring_cmd:w
+ \cs_set_eq:NN \cs \@@_pdfstring_cs:w
+ \cs_set_eq:NN \tn \@@_pdfstring_cs:w
+ \cs_set_eq:NN \meta \@@_pdfstring_meta:w
+ \cs_set_eq:NN \@@_meta:n \@@_pdfstring_meta:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\Arg, \marg, \oarg, \parg}
+% |\marg{text}| prints \marg{text}, \enquote{mandatory argument}.\\
+% |\oarg{text}| prints \oarg{text}, \enquote{optional argument}.\\
+% |\parg{te,xt}| prints \parg{te,xt}, \enquote{picture mode argument}.
+% Finally, \cs{Arg} is the same as \cs{marg}.
+% \begin{macrocode}
+\newcommand\Arg[1]
+ { \texttt{\char`\{} \@@_meta:n {#1} \texttt{\char`\}} }
+\providecommand\marg[1]{ \Arg{#1} }
+\providecommand\oarg[1]{ \texttt[ \@@_meta:n {#1} \texttt] }
+\providecommand\parg[1]{ \texttt( \@@_meta:n {#1} \texttt) }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\file, \env, \pkg, \cls}
+% This list may change\dots this is just my preference for markup.
+% \begin{macrocode}
+\DeclareRobustCommand \file {\nolinkurl}
+\DeclareRobustCommand \env {\texttt}
+\DeclareRobustCommand \pkg {\textsf}
+\DeclareRobustCommand \cls {\textsf}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\EnableDocumentation, \EnableImplementation}
+% \begin{macro}{\DisableDocumentation, \DisableImplementation}
+% Control whether to typeset the documentation/implementation or not.
+% These simply set two switches.
+% \begin{macrocode}
+\NewDocumentCommand \EnableDocumentation { }
+ { \bool_gset_true:N \g_@@_typeset_documentation_bool }
+\NewDocumentCommand \EnableImplementation { }
+ { \bool_gset_true:N \g_@@_typeset_implementation_bool }
+\NewDocumentCommand \DisableDocumentation { }
+ { \bool_gset_false:N \g_@@_typeset_documentation_bool }
+\NewDocumentCommand \DisableImplementation { }
+ { \bool_gset_false:N \g_@@_typeset_implementation_bool }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{environment}{documentation}
+% \begin{environment}{implementation}
+% If the documentation/implementation should be typeset, then simply
+% set the boolean \cs{l_@@_in_implementation_bool} which indicates
+% whether we are within the implementation section. Otherwise use
+% \cs{comment} (and a paired \cs{endcomment}).
+% \begin{macrocode}
+\NewDocumentEnvironment { documentation } { }
+ {
+ \bool_if:NTF \g_@@_typeset_documentation_bool
+ { \bool_set_false:N \l_@@_in_implementation_bool }
+ { \comment }
+ }
+ { \bool_if:NF \g_@@_typeset_documentation_bool { \endcomment } }
+\NewDocumentEnvironment { implementation } { }
+ {
+ \bool_if:NTF \g_@@_typeset_implementation_bool
+ { \bool_set_true:N \l_@@_in_implementation_bool }
+ { \comment }
+ }
+ { \bool_if:NF \g_@@_typeset_implementation_bool { \endcomment } }
+% \end{macrocode}
+% \end{environment}
+% \end{environment}
+%
+% \begin{environment}{variable}
+% The \env{variable} environment behaves as a \env{function} or
+% \env{macro} environment depending on the part of the document.
+% \begin{macrocode}
+\DeclareDocumentEnvironment { variable } { O{} +v }
+ {
+ \bool_if:NTF \l_@@_in_implementation_bool
+ { \@@_macro:nnw { var , #1 } {#2} }
+ { \@@_function:nnw {#1} {#2} }
+ }
+ {
+ \bool_if:NTF \l_@@_in_implementation_bool
+ { \@@_macro_end: }
+ { \@@_function_end: }
+ }
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{function}
+% \begin{environment}{macro}
+% Environment for documenting function(s), and environment for
+% documenting the implementation of a macro.
+% \begin{macrocode}
+\DeclareDocumentEnvironment { function } { O{} +v }
+ { \@@_function:nnw {#1} {#2} }
+ { \@@_function_end: }
+\DeclareDocumentEnvironment { macro } { O{} +v }
+ { \@@_macro:nnw {#1} {#2} }
+ { \@@_macro_end: }
+% \end{macrocode}
+% \end{environment}
+% \end{environment}
+%
+% \begin{environment}{syntax}
+% Syntax block placed next to the list of functions to illustrate
+% their use. TODO: test that the \env{syntax} environment is only
+% used inside the \env{function} environment, and that it only appears
+% once.
+% \begin{macrocode}
+\NewDocumentEnvironment { syntax } { }
+ { \@@_syntax:w }
+ {
+ \@@_syntax_end:
+ \ignorespacesafterend
+ }
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{texnote}
+% Used to describe information destined to \TeX{} experts only.
+% \begin{macrocode}
+\NewDocumentEnvironment { texnote } { }
+ {
+ \endgraf
+ \vspace{3mm}
+ \small\textbf{\TeX~hackers~note:}
+ }
+ {
+ \vspace{3mm}
+ }
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{arguments}
+% This environment is designed to be used within a \env{macro}
+% environment to describe the arguments of the macro/function.
+% \begin{macrocode}
+\NewDocumentEnvironment { arguments } { }
+ {
+ \enumerate [
+ nolistsep ,
+ label = \texttt{\#\arabic*} ~ : ,
+ labelsep = * ,
+ ]
+ }
+ {
+ \endenumerate
+ }
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\CodedocExplain, \CodedocExplainEXP, \CodedocExplainREXP, \CodedocExplainTF}
+% Explanation of stars and |TF| notations, for use in third-party
+% packages.
+% \begin{macrocode}
+\NewDocumentCommand { \CodedocExplain } { }
+ { \CodedocExplainEXP \ \CodedocExplainREXP \ \CodedocExplainTF }
+\NewDocumentCommand { \CodedocExplainEXP } { }
+ {
+ \raisebox{\baselineskip}[0pt][0pt]{\hypertarget{expstar}{}}%
+ \write \@auxout { \def \string \Codedoc@expstar { } }
+ \@@_typeset_exp:\ indicates~fully~expandable~functions,~which~
+ can~be~used~within~an~\texttt{e}-type~argument~(inside~an~\tn{expanded}),~
+ \texttt{x}-type~argument~(in~plain~\TeX{}~terms,~inside~an~\tn{edef}),~
+ as~well~as~within~an~\texttt{f}-type~argument.
+ }
+\NewDocumentCommand { \CodedocExplainREXP } { }
+ {
+ \raisebox{\baselineskip}[0pt][0pt]{\hypertarget{rexpstar}{}}%
+ \write \@auxout { \def \string \Codedoc@rexpstar { } }
+ \@@_typeset_rexp:\ indicates~
+ restricted~expandable~functions,~which~can~be~used~within~an~
+ \texttt{x}-type~argument~or~an~\texttt{e}-type~argument,~
+ but~cannot~be~fully~expanded~within~an~\texttt{f}-type~argument.
+ }
+\NewDocumentCommand { \CodedocExplainTF } { }
+ {
+ \raisebox{\baselineskip}[0pt][0pt]{\hypertarget{explTF}{}}%
+ \write \@auxout { \def \string \Codedoc@explTF { } }
+ \@@_typeset_TF:\ indicates~conditional~(\texttt{if})~functions~
+ whose~variants~with~\texttt{T},~\texttt{F}~and~\texttt{TF}~
+ argument~specifiers~expect~different~
+ \enquote{true}/\enquote{false}~branches.
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Implementing text markup}
+%
+% Keys for \cs{cmd}, \cs{cs} and \cs{tn}.
+% \begin{macrocode}
+\keys_define:nn { l3doc/cmd }
+ {
+ index .tl_set:N = \l_@@_cmd_index_tl ,
+ module .tl_set:N = \l_@@_cmd_module_tl ,
+ no-index .bool_set:N = \l_@@_cmd_noindex_bool ,
+ replace .bool_set:N = \l_@@_cmd_replace_bool ,
+ }
+% \end{macrocode}
+%
+% \begin{macro}[do-not-index={\\,\_,\1,\c,\2}]{\@@_cmd:nn, \@@_cmd:no}
+% Apply the key--value \meta{options}~|#1| after setting some
+% default values. Then (unless |replace=false|) replace |@@| in~|#2|,
+% which is a bit tricky: the |_| must be given the catcode expected by
+% \cs{@@_replace_at_at:N}, but should be reverted to their original
+% catcode (normally active, needed for line-breaking) without
+% rescanning the whole argument. Then typeset the command in
+% \tn{verbatim@font}, after turning it to harmless characters if
+% needed (and keeping the underscore breakable); in any case, spaces
+% must be turned into \tn{@xobeysp} and we must use \tn{@} to avoid
+% longer spaces after a control sequence that ends for instance with a
+% colon (empty signature). Finally, produce an index entry.
+% Indexing is suppressed when \cs{l_@@_cmd_noindex_bool} is true.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cmd:nn #1#2
+ {
+ \bool_set_false:N \l_@@_cmd_noindex_bool
+ \bool_set_true:N \l_@@_cmd_replace_bool
+ \tl_set:Nn \l_@@_cmd_index_tl { \q_no_value }
+ \tl_set:Nn \l_@@_cmd_module_tl { \q_no_value }
+ \keys_set:nn { l3doc/cmd } {#1}
+ \tl_set:Nn \l_@@_cmd_tl {#2}
+ \bool_if:NT \l_@@_cmd_replace_bool
+ {
+ \tl_set_rescan:Nnn \l_@@_tmpb_tl { } { _ }
+ \tl_replace_all:NVn \l_@@_cmd_tl \l_@@_tmpb_tl { _ }
+ \@@_replace_at_at:N \l_@@_cmd_tl
+ \tl_replace_all:NnV \l_@@_cmd_tl { _ } \l_@@_tmpb_tl
+ }
+% \end{macrocode}
+% Typesetting.
+% Note the replacement for the underscore is to permit linebreaks.
+% The \texttt{underscore} package adds the linebreak,
+% and the regex results in applying the breakable underscore only to the \emph{last}
+% of a run of underscores, and not if the underscore follows a backslash.
+% \begin{macrocode}
+ \mode_if_math:T { \mbox }
+ {
+ \bool_if:NT \l_@@_allow_indexing_bool { \@@_target: }
+ \verbatim@font
+ \@@_if_almost_str:VT \l_@@_cmd_tl
+ {
+ \__kernel_tl_set:Nx \l_@@_cmd_tl { \tl_to_str:N \l_@@_cmd_tl }
+ \bool_if:NT \g_@@_cs_break_bool
+ {
+ \regex_replace_all:nnN
+ { ([^\\\_]\_*) \_ ([^\_]) }
+ { \1 \c{BreakableUnderscore} \2 }
+ \l_@@_cmd_tl
+ }
+ }
+ \tl_replace_all:Nnn \l_@@_cmd_tl { ~ } { \@xobeysp }
+ \l_@@_cmd_tl
+ \@
+ }
+% \end{macrocode}
+% Indexing.
+% \begin{macrocode}
+ \bool_if:NT \l_@@_allow_indexing_bool
+ {
+ \bool_if:NF \l_@@_cmd_noindex_bool
+ {
+ \quark_if_no_value:NF \l_@@_cmd_index_tl
+ {
+ \__kernel_tl_set:Nx \l_@@_cmd_tl
+ { \c_backslash_str \exp_not:o { \l_@@_cmd_index_tl } }
+ }
+ \exp_args:No \@@_key_get:n { \l_@@_cmd_tl }
+ \quark_if_no_value:NF \l_@@_cmd_module_tl
+ {
+ \__kernel_tl_set:Nx \l_@@_index_module_tl
+ { \tl_to_str:N \l_@@_cmd_module_tl }
+ }
+ \@@_special_index_module:ooonN
+ { \l_@@_index_key_tl }
+ { \l_@@_index_macro_tl }
+ { \l_@@_index_module_tl }
+ { usage }
+ \l_@@_index_internal_bool
+ }
+ }
+ }
+\cs_generate_variant:Nn \@@_cmd:nn { no }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_meta:n,
+% \@@_ensuremath_sb:n,
+% \@@_meta_original:n
+% }
+% Store |#1| in \cs{l_@@_tmpa_tl} and replaces every underscore,
+% regardless of its category (\enquote{math toggle},
+% \enquote{alignment}, \enquote{superscript}, \enquote{subscript},
+% \enquote{letter}, \enquote{other}, or \enquote{active}) by
+% \cs{@@_ensuremath_sb:n} (which creates math subscripts), then runs
+% the code used for \tn{meta} in \pkg{doc.sty}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_meta:n #1
+ {
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_map_inline:nn
+ { { 3 } { 4 } { 7 } { 8 } { 11 } { 12 } { 13 } }
+ {
+ \tl_set_rescan:Nnn \l_@@_tmpb_tl
+ { \char_set_catcode:nn { `_ } {##1} } { _ }
+ \tl_replace_all:NVn \l_@@_tmpa_tl \l_@@_tmpb_tl
+ { \@@_ensuremath_sb:n }
+ }
+ \exp_args:NV \@@_meta_original:n \l_@@_tmpa_tl
+ }
+\cs_new_protected:Npn \@@_ensuremath_sb:n #1
+ { \ensuremath { \sb {#1} } }
+\cs_new_protected:Npn \@@_meta_original:n #1
+ {
+ \ensuremath \langle
+ \mode_if_math:T { \nfss@text }
+ {
+ \meta@font@select
+ \edef \meta@hyphen@restore
+ { \hyphenchar \the \font \the \hyphenchar \font }
+ \hyphenchar \font \m@ne
+ \language \l@nohyphenation
+ #1 \/
+ \meta@hyphen@restore
+ }
+ \ensuremath \rangle
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Common between \env{macro} and \env{function}}
+%
+% \begin{macro}
+% {
+% \@@_typeset_exp:, \@@_typeset_rexp:,
+% \@@_typeset_TF:, \@@_typeset_aux:n
+% }
+% Used by \cs{@@_macro_single:nNN} and in the \env{function} environment
+% to typeset conditionals and auxiliary functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_typeset_exp:
+ {
+ \cs_if_exist:NTF \Codedoc@expstar
+ { \hyperlink { expstar } }
+ { \mbox }
+ {$\star$}
+ }
+\cs_new_protected:Npn \@@_typeset_rexp:
+ {
+ \cs_if_exist:NTF \Codedoc@rexpstar
+ { \hyperlink { rexpstar } }
+ { \mbox }
+ { \ding { 73 } } % hollow star
+ }
+\cs_new_protected:Npn \@@_typeset_TF:
+ {
+ \cs_if_exist:NTF \Codedoc@explTF
+ { \hyperlink { explTF } }
+ { \mbox }
+ {
+ \itshape TF
+ \makebox[0pt][r]
+ {
+ \underline { \phantom{\itshape TF} \kern-0.1em }
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_typeset_aux:n #1
+ {
+ { \color[gray]{0.5} #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_get_hyper_target:nN, \@@_get_hyper_target:oN, \@@_get_hyper_target:eN}
+% Create a \pkg{hyperref} anchor from a macro name~|#1| and stores it
+% in the token list variable~|#2|. For instance, |\prg_replicate:nn|
+% gives |doc/function//prg/replicate:nn|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_get_hyper_target:nN #1#2
+ {
+ \__kernel_tl_set:Nx #2 { \tl_to_str:n {#1} }
+ \tl_replace_all:NVn #2 \c_underscore_str { / }
+ \tl_remove_all:NV #2 \c_backslash_str
+ \tl_put_left:Nn #2 { doc/function// }
+ }
+\cs_generate_variant:Nn \@@_get_hyper_target:nN { o , e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_names_get_seq:nN}
+% The argument~|#1| (argument of a |function| or |macro| environment)
+% has catcodes $10$ (space), $12$ (other) and $13$ (active). Sanitize
+% catcodes. If the |verb| option was used, output a one-item
+% sequence. Otherwise, remove any \enquote{\%} character at the
+% beginning of a line. Remove tabs and newlines. Finally, convert
+% |_@@| and |@@| to |__|\meta{module name} (if it is non-empty). At
+% this point, \cs{l_@@_tmpa_tl} contains a comma-delimited list of
+% names, where |@| and~|_| have category code letter. Turn it to a
+% string, parse it as a comma-delimited list (in particular this
+% removes spaces), and output a sequence of function/macro names.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_names_get_seq:nN #1#2
+ {
+ \__kernel_tl_set:Nx \l_@@_tmpa_tl { \tl_to_str:n {#1} }
+ \bool_if:NTF \l_@@_names_verb_bool
+ {
+ \seq_clear:N #2
+ \seq_put_right:NV #2 \l_@@_tmpa_tl
+ }
+ {
+ \tl_remove_all:Ne \l_@@_tmpa_tl
+ { \iow_char:N \^^M \c_percent_str }
+ \tl_remove_all:Ne \l_@@_tmpa_tl
+ { \token_to_str:N \obeyedline \c_space_tl \c_percent_str }
+ \tl_remove_all:Ne \l_@@_tmpa_tl { \tl_to_str:n { ^ ^ A } }
+ \tl_remove_all:Ne \l_@@_tmpa_tl { \iow_char:N \^^I }
+ \tl_remove_all:Ne \l_@@_tmpa_tl { \iow_char:N \^^M }
+ \@@_detect_internals:N \l_@@_tmpa_tl
+ \@@_replace_at_at:N \l_@@_tmpa_tl
+ \exp_args:NNe \seq_set_from_clist:Nn #2
+ { \tl_to_str:N \l_@@_tmpa_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_names_parse:, \@@_names_parse_one:n}
+% The goal is to group variants together. We populate
+% \cs{l_@@_names_block_tl} with local sequence variable named with
+% \cs{@@_lseq_name:n} after the base forms. When encountering a new
+% base form, set the corresponding local sequence to hold the
+% \meta{base name} (stripped of the signature) and add the local
+% sequence to the list \cs{l_@@_names_block_tl}. In all cases append
+% the signature to the local sequence, which thus takes the form
+% \meta{base name}, \meta{signature_1}, \meta{signature_2} and so on.
+% If the original function had no signature (no colon) then use
+% \cs{scan_stop:} as the signature (there can be no variant). We
+% special case commands |#1| starting with |\::|, namely weird
+% functions named |\::N| and the like.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_names_parse:
+ {
+ \tl_clear:N \l_@@_names_block_tl
+ \seq_map_function:NN
+ \l_@@_names_seq
+ \@@_names_parse_one:n
+ }
+\cs_new_protected:Npn \@@_names_parse_one:n #1
+ {
+ \@@_split_function_do:nn {#1}
+ { \@@_names_parse_one_aux:nnNn }
+ {#1}
+ }
+\cs_new_protected:Npn \@@_names_parse_one_aux:nnNn #1#2#3#4
+ {
+ \bool_if:NTF #3
+ {
+ \tl_if_head_eq_charcode:nNTF {#2} :
+ { \@@_names_parse_aux:nnn {#4} {#4} { \scan_stop: } }
+ {
+ \exp_args:Ne \@@_names_parse_aux:nnn
+ { \@@_base_form_aux:nnN {#1} {#2} #3 }
+ {#1} {#2}
+ }
+ }
+ {
+ \bool_if:NT \l_@@_macro_TF_bool
+ { \msg_error:nne { l3doc } { no-signature-TF } {#4} }
+ \@@_names_parse_aux:nnn {#4} {#4} { \scan_stop: }
+ }
+ }
+\cs_new_protected:Npn \@@_names_parse_aux:nnn #1
+ { \exp_args:Nc \@@_names_parse_aux:Nnn { \@@_lseq_name:n {#1} } }
+\cs_new_protected:Npn \@@_names_parse_aux:Nnn #1#2#3
+ {
+ \tl_if_in:NnF \l_@@_names_block_tl {#1}
+ {
+ \tl_put_right:Nn \l_@@_names_block_tl {#1}
+ \seq_clear_new:N #1
+ \seq_put_right:Nn #1 {#2}
+ }
+ \seq_put_right:Nn #1 {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_names_typeset:}
+% \begin{macro}{\@@_names_typeset_auxi:n}
+% This code is in particular used when typesetting function names in a
+% \env{function} environment. The mapping over \cs{l_@@_names_block_tl}
+% cannot use \cs{tl_map_inline:Nn} because the code following |\\|
+% would not be expandable, thus breaking \tn{bottomrule}.
+%
+% Call \cs{@@_names_typeset_auxi:n} on each local sequence (which
+% holds a set of variants). The first step is to pop the base form
+% and change spaces to category other so
+% that they get displayed eventually. Then store the variants in
+% \cs{g_@@_variants_seq}, remove the first, which will be displayed
+% more prominently, and reconstruct the actual name, passing it to
+% \cs{@@_names_typeset_auxii:n}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_names_typeset:
+ {
+ \tl_map_function:NN \l_@@_names_block_tl
+ \@@_names_typeset_auxi:n
+ }
+\cs_new_protected:Npn \@@_names_typeset_auxi:n #1
+ {
+ \seq_pop:NN #1 \l_@@_tmpa_tl
+ \tl_gset_eq:NN \g_@@_base_name_tl \l_@@_tmpa_tl
+ \tl_greplace_all:NnV \g_@@_base_name_tl
+ { ~ } \c_catcode_other_space_tl
+ \seq_get:NN #1 \l_@@_tmpa_tl
+ \str_if_eq:VnTF \l_@@_tmpa_tl { \scan_stop: }
+ {
+ \seq_gclear:N \g_@@_variants_seq
+ \@@_names_typeset_auxii:e { \g_@@_base_name_tl }
+ }
+ {
+ \seq_gset_eq:NN \g_@@_variants_seq #1
+ \seq_gpop:NN \g_@@_variants_seq \l_@@_tmpb_tl
+ \@@_names_typeset_auxii:e
+ { \g_@@_base_name_tl : \l_@@_tmpb_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_names_typeset_auxii:n, \@@_names_typeset_auxii:e}
+% In case the option |pTF| was given, typeset predicates before the
+% |TF| functions. In case the option |noTF| was given, typeset the
+% non-|TF| function as well. Pass the relevant boolean in both cases
+% to control whether to append |TF|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_names_typeset_auxii:n #1
+ {
+ \bool_if:NT \l_@@_macro_pTF_bool
+ {
+ \@@_names_typeset_block:eN
+ { \@@_predicate_from_base:n {#1} }
+ \c_false_bool
+ }
+ \bool_if:NT \l_@@_macro_noTF_bool
+ { \@@_names_typeset_block:nN {#1} \c_false_bool }
+ \@@_names_typeset_block:nN {#1} \l_@@_macro_TF_bool
+ }
+\cs_generate_variant:Nn \@@_names_typeset_auxii:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_names_typeset_block:nN, \@@_names_typeset_block:eN}
+% Names in \env{function} and \env{macro} environments are typeset
+% differently. To distinguish the two note that
+% \cs{l_@@_nested_macro_int} is at least one when in an \env{macro}
+% environment (we assume \env{function} is not nested inside it). A
+% block is a function with all its variants.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_names_typeset_block:nN
+ {
+ \int_compare:nNnTF \l_@@_nested_macro_int = 0
+ { \@@_typeset_function_block:nN }
+ { \@@_macro_typeset_block:nN }
+ }
+\cs_generate_variant:Nn \@@_names_typeset_block:nN { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\@@_if_macro_internal:n}
+% \begin{macro}[EXP]{\@@_if_macro_internal_aux:w}
+% Determines whether the given macro should be considered internal or
+% public. If an option such as |int| was given then the answer is
+% \cs{l_@@_macro_internal_bool}, otherwise check for whether the macro
+% name contains~|__|.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_if_macro_internal:n #1 { p , T , F , TF }
+ {
+ \bool_if:NTF \l_@@_macro_internal_bool
+ { \prg_return_true: }
+ {
+ \tl_if_empty:eTF
+ {
+ \exp_after:wN \@@_if_macro_internal_aux:w
+ \tl_to_str:n { #1 ~ __ }
+ }
+ { \prg_return_false: } { \prg_return_true: }
+ }
+ }
+\exp_last_unbraced:NNNNo
+ \cs_new:Npn \@@_if_macro_internal_aux:w #1 { \tl_to_str:n { __ } } { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_names_block_base_map:N}
+% The \cs{l_@@_names_block_tl} contains sequence variables
+% corresponding to different base functions and their variants. For
+% each such sequence, put the first and second items in
+% \cs{l_@@_tmpa_tl} and \cs{l_@@_tmpb_tl} and build the base
+% function's name.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_names_block_base_map:N #1
+ {
+ \tl_map_inline:Nn \l_@@_names_block_tl
+ {
+ \group_begin:
+ \seq_set_eq:NN \l_@@_tmpa_seq ##1
+ \seq_pop:NN \l_@@_tmpa_seq \l_@@_tmpa_tl
+ \seq_get:NN \l_@@_tmpa_seq \l_@@_tmpb_tl
+ \exp_args:NNe
+ \group_end:
+ #1
+ {
+ \l_@@_tmpa_tl
+ \str_if_eq:VnF \l_@@_tmpb_tl { \scan_stop: }
+ { : \l_@@_tmpb_tl }
+ \bool_if:NT \l_@@_macro_TF_bool { TF }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{The \env{function} environment}
+%
+% \begin{macrocode}
+\keys_define:nn { l3doc/function }
+ {
+ TF .value_forbidden:n = true ,
+ TF .code:n =
+ {
+ \bool_set_true:N \l_@@_macro_TF_bool
+ } ,
+ EXP .value_forbidden:n = true ,
+ EXP .code:n =
+ {
+ \bool_set_true:N \l_@@_macro_EXP_bool
+ \bool_set_false:N \l_@@_macro_rEXP_bool
+ } ,
+ rEXP .value_forbidden:n = true ,
+ rEXP .code:n =
+ {
+ \bool_set_false:N \l_@@_macro_EXP_bool
+ \bool_set_true:N \l_@@_macro_rEXP_bool
+ } ,
+ pTF .value_forbidden:n = true ,
+ pTF .code:n =
+ {
+ \bool_set_true:N \l_@@_macro_pTF_bool
+ \bool_set_true:N \l_@@_macro_TF_bool
+ \bool_set_true:N \l_@@_macro_EXP_bool
+ \bool_set_false:N \l_@@_macro_rEXP_bool
+ } ,
+ noTF .value_forbidden:n = true ,
+ noTF .code:n =
+ {
+ \bool_set_true:N \l_@@_macro_noTF_bool
+ \bool_set_true:N \l_@@_macro_TF_bool
+ } ,
+ added .code:n = { \@@_date_set_past:Nn \l_@@_date_added_tl {#1} },
+ updated .code:n = { \@@_date_set_past:Nn \l_@@_date_updated_tl {#1} } ,
+ deprecated .bool_set:N = \l_@@_macro_deprecated_bool ,
+ no-user-doc .bool_set:N = \l_@@_macro_nodoc_bool ,
+ tested .code:n = { } ,
+ label .code:n =
+ {
+ \clist_set:Nn \l_@@_function_label_clist {#1}
+ \bool_set_true:N \l_@@_no_label_bool
+ } ,
+ verb .value_forbidden:n = true ,
+ verb .bool_set:N = \l_@@_names_verb_bool ,
+ module .tl_set:N = \l_@@_override_module_tl ,
+ }
+% \end{macrocode}
+%
+% \begin{macro}[do-not-index={\A,\Z,\d,\1,\2,\3}]
+% {\@@_date_set:Nn,\@@_date_set_past:Nn}
+% Normalize the date into the format \texttt{YYYY-MM-DD}; more
+% precisely month and day are allowed to be single digits. The
+% \cs{@@_date_set_past:Nn} function only allows dates in the past (or
+% same day).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_date_set:Nn #1#2
+ {
+ \tl_set:Nn #1 {#2}
+ \regex_replace_once:nnNF
+ { \A(\d\d\d\d)[-/](\d\d?)[-/](\d\d?)\Z } { \1-\2-\3 } #1
+ {
+ \msg_error:nnn { l3doc } { date-format } {#2}
+ \tl_set:Nn #1 { 1970-01-01 }
+ }
+ }
+\cs_new_protected:Npn \@@_date_set_past:Nn #1#2
+ {
+ \@@_date_set:Nn #1 {#2}
+ \exp_args:No \@@_date_compare:nNnT
+ {#1} > { \c_sys_year_int - \c_sys_month_int - \c_sys_day_int }
+ {
+ \msg_error:nnee { l3doc } { future-date }
+ { \tl_to_str:N \l_@@_macro_argument_tl }
+ {#1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_function:nnw}
+% \begin{arguments}
+% \item Key--value list.
+% \item Comma-separated list of functions; input has already been
+% sanitised by catcode changes before reading the argument.
+% \end{arguments}
+% \begin{macro}{\@@_function_end:}
+% Make sure any paragraph is finished, and similar safe practices at
+% the beginning of an environment which will typeset material.
+% Initialize some variables. Parse the key--value list. Clean up the
+% list of functions, then go through them to extract some data. After
+% this, typeset the function names in the coffin
+% \cs{l_@@_functions_coffin} and measure it to know if it fits in the
+% margin. Finally, start a vertical coffin for the main part of the
+% environment. This coffin stops when the environment ends, then all
+% the pieces are assembled into a single coffin, which is typeset.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_function:nnw #1#2
+ {
+ \@@_function_typeset_start:
+ \@@_function_init:
+ \tl_set:Nn \l_@@_macro_argument_tl {#2}
+ \keys_set:nn { l3doc/function } {#1}
+ \@@_names_get_seq:nN {#2} \l_@@_names_seq
+ \@@_names_parse:
+ \@@_function_typeset:
+ \@@_function_reset:
+ \@@_function_descr_start:w
+ }
+\cs_new_protected:Npn \@@_function_end:
+ {
+ \@@_function_descr_stop:
+ \@@_function_assemble:
+ \@@_function_typeset_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_function_typeset_start:, \@@_function_typeset_stop:}
+% At the start of the \env{function} environment, before performing
+% any assignment, close the last paragraph, and set up the typesetting
+% scene. Further code typesets a coffin, so we end the paragraph and
+% allow a page break.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_function_typeset_start:
+ {
+ \par \bigskip \noindent
+ }
+\cs_new_protected:Npn \@@_function_typeset_stop:
+ {
+ \par
+ \dim_set:Nn \prevdepth { \box_dp:N \l_@@_descr_coffin }
+ \allowbreak
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_function_init:}
+% Complain if \texttt{function} environments are nested. Clear
+% various variables.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_function_init:
+ {
+ \box_if_empty:NF \g_@@_syntax_box
+ { \msg_error:nn { l3doc } { syntax-nested-function } }
+ \coffin_clear:N \l_@@_descr_coffin
+ \box_gclear:N \g_@@_syntax_box
+ \coffin_clear:N \l_@@_syntax_coffin
+ \coffin_clear:N \l_@@_functions_coffin
+ \bool_set_false:N \l_@@_macro_TF_bool
+ \bool_set_false:N \l_@@_macro_pTF_bool
+ \bool_set_false:N \l_@@_macro_noTF_bool
+ \bool_set_false:N \l_@@_macro_EXP_bool
+ \bool_set_false:N \l_@@_macro_rEXP_bool
+ \bool_set_false:N \l_@@_no_label_bool
+ \bool_set_false:N \l_@@_names_verb_bool
+ \bool_set_true:N \l_@@_in_function_bool
+ \clist_clear:N \l_@@_function_label_clist
+ \tl_set:Nn \l_@@_override_module_tl { \q_no_value }
+ \char_set_active_eq:NN \< \@@_shorthand_meta:
+ \char_set_catcode_active:N \<
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_shorthand_meta:, \@@_shorthand_meta:w}
+% Allow |<...>| to be used as markup for |\meta{...}|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_shorthand_meta:
+ { \mode_if_math:TF { < } { \@@_shorthand_meta:w } }
+\cs_new_protected_nopar:Npn \@@_shorthand_meta:w #1 > { \meta {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_function_reset:}
+% Clear some variables.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_function_reset:
+ {
+ \tl_set:Nn \l_@@_override_module_tl { \q_no_value }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_function_typeset:}
+% Typeset in the coffin \cs{l_@@_functions_coffin} the functions listed in
+% \cs{l_@@_names_block_tl} and the relevant dates, then set
+% \cs{l_@@_long_name_bool} to be \texttt{true} if this coffin is
+% larger than the available width in the margin. The function
+% \cs{@@_typeset_functions:} is quite involved hence given later.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_function_typeset:
+ {
+ \dim_zero:N \l_@@_trial_width_dim
+ \hcoffin_set:Nn \l_@@_functions_coffin { \@@_typeset_functions: }
+ \dim_set:Nn \l_@@_trial_width_dim
+ { \box_wd:N \l_@@_functions_coffin }
+ \bool_set:Nn \l_@@_long_name_bool
+ { \dim_compare_p:nNn \l_@@_trial_width_dim > \marginparwidth }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_function_descr_start:w, \@@_function_descr_stop:}
+% The last step in \cs{@@_function:nnw} (the beginning of a
+% \env{function} environment) is to open a coffin which will capture
+% the description of the function, namely the body of the
+% \env{function} environment. This is closed by \cs{@@_function_end:}
+% (the end of a \env{function} environment).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_function_descr_start:w
+ {
+ \vcoffin_set:Nnw \l_@@_descr_coffin { \textwidth }
+ \noindent \ignorespaces
+ }
+\cs_new_protected:Npn \@@_function_descr_stop:
+ { \vcoffin_set_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_function_assemble:}
+% The box \cs{g_@@_syntax_box} contains the contents of the syntax
+% environment if it was used. Now that we have all the pieces, join
+% together the syntax coffin, the names coffin, and the description
+% coffin. The relative positions depend on whether the names coffin
+% fits in the margin. Then typeset the combination.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_function_assemble:
+ {
+ \hcoffin_set:Nn \l_@@_syntax_coffin
+ { \box_use_drop:N \g_@@_syntax_box }
+ \bool_if:NTF \l_@@_long_name_bool
+ {
+ \coffin_join:NnnNnnnn
+ \l_@@_output_coffin {hc} {vc}
+ \l_@@_syntax_coffin {l} {T}
+ {0pt} {0pt}
+ \coffin_join:NnnNnnnn
+ \l_@@_output_coffin {l} {t}
+ \l_@@_functions_coffin {r} {t}
+ {-\marginparsep} {0pt}
+ \coffin_join:NnnNnnnn
+ \l_@@_output_coffin {l} {b}
+ \l_@@_descr_coffin {l} {t}
+ {0.75\marginparwidth + \marginparsep} {-\medskipamount}
+ \coffin_typeset:Nnnnn \l_@@_output_coffin
+ {\l_@@_descr_coffin-l} {\l_@@_descr_coffin-t}
+ {0pt} {0pt}
+ }
+ {
+ \coffin_join:NnnNnnnn
+ \l_@@_output_coffin {hc} {vc}
+ \l_@@_syntax_coffin {l} {t}
+ {0pt} {0pt}
+ \coffin_join:NnnNnnnn
+ \l_@@_output_coffin {l} {b}
+ \l_@@_descr_coffin {l} {t}
+ {0pt} {-\medskipamount}
+ \coffin_join:NnnNnnnn
+ \l_@@_output_coffin {l} {t}
+ \l_@@_functions_coffin {r} {t}
+ {-\marginparsep} {0pt}
+ \coffin_typeset:Nnnnn \l_@@_output_coffin
+ {\l_@@_syntax_coffin-l} {\l_@@_syntax_coffin-T}
+ {0pt} {0pt}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_typeset_functions:}
+% This function builds the \cs{l_@@_functions_coffin} by typesetting the
+% function names (with variants) and the relevant dates in a
+% \env{tabular} environment. The use of rules \tn{toprule},
+% \tn{midrule} and \tn{bottomrule} requires whatever lies between the
+% last |\\| and the rule to be expandable, making our lives a bit
+% complicated.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_typeset_functions:
+ {
+ \small\ttfamily
+ \@@_target:
+ \Hy@MakeCurrentHref { HD. \int_use:N \c@HD@hypercount }
+ \begin{tabular} [t] { @{} l @{} >{\hspace{\tabcolsep}} r @{} }
+ \toprule
+ \@@_function_extra_labels:
+ \@@_names_typeset:
+ \@@_typeset_dates:
+ \bottomrule
+ \end{tabular}
+ \normalfont\normalsize
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A TODO: collect all index targets from a given function environment in a box and stick it at the top.
+% \begin{macro}
+% {\@@_typeset_function_block:nN, \@@_typeset_function_block:eN}
+% \begin{macro}{\@@_function_index:n, \@@_function_index:e}
+% |#1| is a csname, |#2| a boolean indicating whether to add |TF| or not.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_typeset_function_block:nN #1#2
+ {
+ \@@_function_index:e
+ { #1 \bool_if:NT #2 { \tl_to_str:n {TF} } }
+ \@@_function_label:eN {#1} #2
+ #1
+ \bool_if:NT #2 { \@@_typeset_TF: }
+ \@@_typeset_expandability:
+ \seq_if_empty:NF \g_@@_variants_seq
+ { \@@_typeset_variant_list:nN {#1} #2 }
+ \\
+ }
+\cs_generate_variant:Nn \@@_typeset_function_block:nN { e }
+\cs_new_protected:Npn \@@_function_index:n #1
+ {
+ \seq_gput_right:Nn \g_doc_functions_seq {#1}
+ \@@_special_index:nn {#1} { usage }
+ }
+\cs_generate_variant:Nn \@@_function_index:n { e }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_typeset_expandability:
+ {
+ &
+ \bool_if:NT \l_@@_macro_EXP_bool { \@@_typeset_exp: }
+ \bool_if:NT \l_@@_macro_rEXP_bool { \@@_typeset_rexp: }
+ }
+% \end{macrocode}
+%
+% |#1| is the function, |#2| whether to add |TF|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_typeset_variant_list:nN #1#2
+ {
+ \\
+ \@@_typeset_aux:n { \@@_get_function_name:n {#1} }
+ :
+ \int_compare:nTF { \seq_count:N \g_@@_variants_seq == 1 }
+ {
+ \seq_use:Nn \g_@@_variants_seq { }
+ \bool_if:NT #2 { \@@_typeset_TF: }
+ }
+ {
+ \hbox_set:Nn \l_tmpa_box
+ { \seq_use:Nn \g__@@_variants_seq { \textrm| \nolinebreak[2] } }
+ \textrm(
+% \end{macrocode}
+%
+% Set long variant lists in a parbox, short lists set natural length.
+% \begin{macrocode}
+ \dim_compare:nNnTF { \box_wd:N \l_tmpa_box } > { .4\columnwidth }
+ {
+ \parbox[t]{.4\columnwidth}
+ {
+ \raggedright
+ \hbox_unpack_drop:N \l_tmpa_box
+ \textrm)
+ \bool_if:NT #2 { \@@_typeset_TF: }
+ }
+ }
+ {
+ \hbox_unpack_drop:N \l_tmpa_box
+ \textrm)
+ \bool_if:NT #2 { \@@_typeset_TF: }
+ }
+ }
+ \@@_typeset_expandability:
+ }
+% \end{macrocode}
+%
+% |#1| is the function name, |#2| whether to add |TF|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_function_extra_labels:
+ {
+ \bool_if:NT \l_@@_no_label_bool
+ {
+ \clist_map_inline:Nn \l_@@_function_label_clist
+ {
+ \@@_get_hyper_target:oN { \token_to_str:N ##1 }
+ \l_@@_tmpa_tl
+ \exp_args:No \label { \l_@@_tmpa_tl }
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_function_label:nN #1#2
+ {
+ \bool_if:NF \l_@@_no_label_bool
+ {
+ \@@_get_hyper_target:eN
+ {
+ \exp_not:n {#1}
+ \bool_if:NT #2 { \tl_to_str:n {TF} }
+ }
+ \l_@@_tmpa_tl
+ \exp_args:No \label { \l_@@_tmpa_tl }
+ }
+ }
+\cs_generate_variant:Nn \@@_function_label:nN { e }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_typeset_dates:}
+% To display metadata for when functions are added/modified.
+% This function must be expandable since it produces rules for use in
+% alignments.
+% \begin{macrocode}
+\cs_new:Npn \@@_typeset_dates:
+ {
+ \bool_lazy_and:nnF
+ { \tl_if_empty_p:N \l_@@_date_added_tl }
+ { \tl_if_empty_p:N \l_@@_date_updated_tl }
+ { \midrule }
+ \tl_if_empty:NF \l_@@_date_added_tl
+ {
+ \multicolumn { 2 } { @{} r @{} }
+ { \scriptsize New: \, \l_@@_date_added_tl } \\
+ }
+
+ \tl_if_empty:NF \l_@@_date_updated_tl
+ {
+ \multicolumn { 2 } { @{} r @{} }
+ { \scriptsize Updated: \, \l_@@_date_updated_tl } \\
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_syntax:w, \@@_syntax_end:}
+% Implement the \env{syntax} environment.
+% \begin{macrocode}
+\dim_new:N \l_@@_syntax_dim
+\cs_new_protected:Npn \@@_syntax:w
+ {
+ \box_if_empty:NF \g_@@_syntax_box
+ { \msg_error:nn { l3doc } { multiple-syntax } }
+ \dim_set:Nn \l_@@_syntax_dim
+ {
+ \textwidth
+ \bool_if:NT \l_@@_long_name_bool
+ { + 0.75 \marginparwidth - \l_@@_trial_width_dim }
+ }
+ \hbox_gset:Nw \g_@@_syntax_box
+ \small \ttfamily
+ \arrayrulecolor{white}
+ \begin{tabular} { @{} l @{} }
+ \toprule
+ \begin{minipage}[t]{\l_@@_syntax_dim}
+ \raggedright
+ \obeyspaces
+ \obeylines
+ }
+\cs_new_protected:Npn \@@_syntax_end:
+ {
+ \end{minipage}
+ \end{tabular}
+ \arrayrulecolor{black}
+ \hbox_gset_end:
+ \bool_if:NF \l_@@_in_function_bool
+ {
+ \begin{quote}
+ \mode_leave_vertical:
+ \box_use_drop:N \g_@@_syntax_box
+ \end{quote}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{The \env{macro} environment}
+%
+% Keyval for the \env{macro} environment.
+% TODO: provide document command for documenting keys.
+% \begin{macrocode}
+\keys_define:nn { l3doc/macro }
+ {
+ aux .value_forbidden:n = true ,
+ aux .code:n =
+ {
+ \msg_warning:nnnn { l3doc } { deprecated-option }
+ { aux } { function/macro }
+ } ,
+ deprecated .bool_set:N = \l_@@_macro_deprecated_bool ,
+ internal .value_forbidden:n = true ,
+ internal .code:n =
+ { \bool_set_true:N \l_@@_macro_internal_bool } ,
+ int .value_forbidden:n = true ,
+ int .code:n =
+ { \bool_set_true:N \l_@@_macro_internal_bool } ,
+ no-user-doc .bool_set:N = \l_@@_macro_nodoc_bool ,
+ var .value_forbidden:n = true ,
+ var .code:n =
+ { \bool_set_true:N \l_@@_macro_var_bool } ,
+ TF .value_forbidden:n = true ,
+ TF .code:n =
+ { \bool_set_true:N \l_@@_macro_TF_bool } ,
+ pTF .value_forbidden:n = true ,
+ pTF .code:n =
+ {
+ \bool_set_true:N \l_@@_macro_TF_bool
+ \bool_set_true:N \l_@@_macro_pTF_bool
+ \bool_set_true:N \l_@@_macro_EXP_bool
+ \bool_set_false:N \l_@@_macro_rEXP_bool
+ } ,
+ noTF .value_forbidden:n = true ,
+ noTF .code:n =
+ {
+ \bool_set_true:N \l_@@_macro_TF_bool
+ \bool_set_true:N \l_@@_macro_noTF_bool
+ } ,
+ EXP .value_forbidden:n = true ,
+ EXP .code:n =
+ {
+ \bool_set_true:N \l_@@_macro_EXP_bool
+ \bool_set_false:N \l_@@_macro_rEXP_bool
+ } ,
+ rEXP .value_forbidden:n = true ,
+ rEXP .code:n =
+ {
+ \bool_set_false:N \l_@@_macro_EXP_bool
+ \bool_set_true:N \l_@@_macro_rEXP_bool
+ } ,
+ tested .code:n =
+ {
+ \bool_set_true:N \l_@@_macro_tested_bool
+ } ,
+ added .code:n = {} , % TODO
+ updated .code:n = {} , % TODO
+ verb .bool_set:N = \l_@@_names_verb_bool ,
+ module .tl_set:N = \l_@@_override_module_tl ,
+ documented-as .tl_set:N = \l_@@_macro_documented_tl ,
+ do-not-index .value_required:n = true ,
+ do-not-index .tl_set:N = \l_@@_macro_do_not_index_tl ,
+ % do-not-index .default:n = \q_no_value ,
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\@@_macro:nnw}
+% The arguments are a key--value list of \meta{options} and a
+% comma-list of \meta{names}, read verbatim by \pkg{ltcmd}. First
+% initialize some variables before applying the \meta{options}, then
+% parse the \meta{names} to get a sequence of macro names, then apply
+% \cs{@@_macro_single:nNN} to each (this step is more subtle than
+% \cs{seq_map_function:NN} because of |TF|/|pTF|/|noTF|). Finally typeset
+% the macro names in the margin.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_macro:nnw #1#2
+ {
+ \@@_macro_init:
+ \tl_set:Nn \l_@@_macro_argument_tl {#2}
+ \keys_set:nn { l3doc/macro } {#1}
+ \@@_names_get_seq:nN {#2} \l_@@_names_seq
+ \@@_names_parse:
+ \@@_macro_exclude_index:
+ \@@_macro_save_names:
+ \@@_names_typeset:
+ \@@_macro_dump:
+ \@@_macro_reset:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_macro_init:}
+% The booleans hold various key--value options,
+% \cs{l_@@_nested_macro_int} counts the number of \env{macro}
+% environments around the current point (is $0$ outside).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_macro_init:
+ {
+ \int_incr:N \l_@@_nested_macro_int
+ \bool_set_false:N \l_@@_macro_deprecated_bool
+ \bool_set_false:N \l_@@_macro_internal_bool
+ \bool_set_false:N \l_@@_macro_TF_bool
+ \bool_set_false:N \l_@@_macro_pTF_bool
+ \bool_set_false:N \l_@@_macro_noTF_bool
+ \bool_set_false:N \l_@@_macro_EXP_bool
+ \bool_set_false:N \l_@@_macro_rEXP_bool
+ \bool_set_false:N \l_@@_macro_var_bool
+ \bool_set_false:N \l_@@_macro_tested_bool
+ \bool_set_false:N \l_@@_names_verb_bool
+ \tl_set:Nn \l_@@_override_module_tl { \q_no_value }
+ \tl_clear:N \l_@@_macro_documented_tl
+ \cs_set_eq:NN \testfile \@@_print_testfile:n
+ \box_clear:N \l_@@_macro_index_box
+ \vbox_set:Nn \l_@@_macro_box
+ {
+ \hbox:n
+ {
+ \strut
+ \int_compare:nNnT \l_@@_macro_int = 0 { \@@_target: }
+ }
+ \vskip \int_eval:n { \l_@@_macro_int - 1 } \baselineskip
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_macro_reset:}
+% We ensure that \cs{cs} commands nested inside a macro whose module
+% is imposed are not affected.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_macro_reset:
+ {
+ \tl_set:Nn \l_@@_override_module_tl { \q_no_value }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_macro_save_names:}
+% \begin{macro}[EXP]{\@@_macro_save_names_aux:w}
+% The list of names defined in a set of \env{macro} environments is
+% eventually used to display on which page they are documented. If
+% the |documented-as| key is given, use that, otherwise find names in
+% \cs{l_@@_names_block_tl}. The |documented-as| needs to be detokenized
+% without adding a space, so it has to be treated in a slightly awkward
+% way.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_macro_save_names:
+ {
+ \tl_if_empty:NTF \l_@@_macro_documented_tl
+ { \@@_names_block_base_map:N \@@_macro_save_names_aux:n }
+ {
+ \seq_gput_right:Ne \g_@@_nested_names_seq
+ {
+ \exp_after:wN \@@_macro_save_names_aux:w
+ \l_@@_macro_documented_tl \q_@@_stop
+ }
+ }
+ }
+\cs_new:Npn \@@_macro_save_names_aux:w #1#2 \q_@@_stop
+ { \token_to_str:N #1 \tl_to_str:n {#2} }
+\cs_new_protected:Npn \@@_macro_save_names_aux:n #1
+ { \seq_gput_right:Nn \g_@@_nested_names_seq {#1} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_macro_exclude_index:}
+% Some control sequences in a \env{macrocode} environment shouldn't
+% be indexed, for different reasons. This macro parses the argument
+% of the |do-not-index| option and locally removes the given macros
+% from the index.
+%
+% The optional argument to \env{macro} is not scanned with verbatim
+% catcodes, so we use \cs{tl_set_rescan:NnV} to rescan the commands
+% with the same catcodes as \cs{DoNotIndex}. The scanned token list
+% contains spaces after control sequences, which are not there when
+% \cs{DoNotIndex} is used. Since \cs{seq_set_from_clist:Nn} removes
+% spaces around the items, we can abuse that and \cs{seq_use:Nn} to
+% normalise each item. After that \cs{DoNotIndex} can do its thing.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_macro_exclude_index:
+ {
+ \tl_if_empty:NF \l_@@_macro_do_not_index_tl
+ {
+ \tl_set_rescan:NnV \l_@@_macro_do_not_index_tl
+ { \MakePrivateLetters \catcode`\\12 }
+ \l_@@_macro_do_not_index_tl
+ \exp_args:NNV \seq_set_from_clist:Nn
+ \l_@@_tmpa_seq \l_@@_macro_do_not_index_tl
+ \__kernel_tl_set:Nx \l_@@_macro_do_not_index_tl
+ { \seq_use:Nn \l_@@_tmpa_seq { , } }
+ \exp_args:NV \DoNotIndex \l_@@_macro_do_not_index_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_macro_dump:}
+% This calls |\makelabel{}|
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_macro_dump:
+ {
+ \topsep\MacroTopsep
+ \trivlist
+ \cs_set:Npn \makelabel ##1
+ {
+ \llap
+ {
+ \hbox_unpack_drop:N \l_@@_macro_index_box
+ \vtop to \baselineskip
+ {
+ \vbox_unpack_drop:N \l_@@_macro_box
+ \vss
+ }
+ }
+ }
+ \item [ ]
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_macro_typeset_block:nN}
+% Used to typeset a macro and its variants. |#1| is the macro name,
+% |#2| is a boolean controlling whether to add |TF|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_macro_typeset_block:nN #1#2
+ {
+ \@@_macro_single:nNN {#1} \c_true_bool #2
+ \seq_if_empty:NF \g_@@_variants_seq
+ {
+ \@@_macro_typeset_variant_list:eN
+ { \@@_get_function_name:n {#1} } #2
+ }
+ }
+\cs_new_protected:Npn \@@_macro_typeset_variant_list:nN #1#2
+ {
+ \seq_map_inline:Nn \g_@@_variants_seq
+ { \@@_macro_single:nNN { #1 : ##1 } \c_false_bool #2 }
+ }
+\cs_generate_variant:Nn \@@_macro_typeset_variant_list:nN { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_macro_single:nNN}
+% The arguments are |#1| a macro name (without |TF|), |#2| a boolean
+% determining whether or not to index, and |#3| whether or not to add |TF|.
+% Let's start to mess around with \cls{doc}'s \env{macro} environment.
+% See \file{doc.dtx} for a full explanation of the original
+% environment. It's rather \emph{enthusiastically} commented.
+% \begin{arguments}
+% \item Macro/function/whatever name; input has already been
+% sanitised.
+% \end{arguments}
+% The assignments to \cs{saved@macroname} and \cs{saved@indexname}
+% are used by \pkg{doc}'s \cs{changes} mechanism.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_macro_single:nNN #1#2#3
+ {
+ \tl_set:Nn \saved@macroname {#1}
+ \@@_macro_typeset_one:nN {#1} #3
+ \bool_if:NT #3 { \DoNotIndex {#1} }
+ \exp_args:Ne \@@_macro_index:nN
+ { #1 \bool_if:NT #3 { \tl_to_str:n { TF } } }
+ #2
+ }
+\cs_new_protected:Npn \@@_macro_index:nN #1#2
+ {
+ \DoNotIndex {#1}
+ \bool_if:NT #2
+ {
+ \bool_lazy_any:nF
+ {
+ { \@@_if_macro_internal_p:n {#1} }
+ { \l_@@_macro_deprecated_bool }
+ { \l_@@_macro_nodoc_bool }
+ }
+ { \seq_gput_right:Nn \g_doc_macros_seq {#1} }
+ \hbox_set:Nw \l_@@_macro_index_box
+ \hbox_unpack_drop:N \l_@@_macro_index_box
+ \int_gincr:N \c@CodelineNo
+ \@@_special_index:nn {#1} { main }
+ \int_gdecr:N \c@CodelineNo
+ \exp_args:NNNo \hbox_set_end:
+ \tl_set:Nn \saved@indexname { \l_@@_index_key_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_macro_typeset_one:nN}
+% For a long time, \cls{l3doc} collected the macro names as labels in
+% the first items of nested \tn{trivlist}, but these were not closed
+% properly with \tn{endtrivlist}. Also, it interacted in surprising
+% ways with \pkg{hyperref} targets. Now, we collect typeset macro
+% names by hand in the box \cs{l_@@_macro_box}. The fixed-size space
+% |\MacroFont\ | could be replaced by an customizable horizontal
+% space; it is important for it to be the same for all macros.
+% |#1| is the macro name, |#2| whether to add |TF|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_macro_typeset_one:nN #1#2
+ {
+ \vbox_set:Nn \l_@@_macro_box
+ {
+ \vbox_unpack_drop:N \l_@@_macro_box
+ \hbox { \llap { \@@_print_macroname:nN {#1} #2
+ \MacroFont \
+ } }
+ }
+ \int_incr:N \l_@@_macro_int
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_print_macroname:nN}
+% In the name, spaces are replaced by other spaces to ensure they get
+% displayed in case there are any.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print_macroname:nN #1#2
+ {
+ \strut
+ \@@_get_hyper_target:eN
+ {
+ \exp_not:n {#1}
+ \bool_if:NT #2 { \tl_to_str:n {TF} }
+ }
+ \l_@@_tmpa_tl
+ \cs_if_exist:cTF { r@ \l_@@_tmpa_tl }
+ { \exp_last_unbraced:NNo \hyperref [ \l_@@_tmpa_tl ] }
+ { \use:n }
+ {
+ \int_compare:nTF { \str_count:n {#1} <= 28 }
+ { \MacroFont } { \MacroLongFont }
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_replace_all:NnV \l_@@_tmpa_tl
+ { ~ } \c_catcode_other_space_tl
+ \@@_print_macroname_aux:on
+ \l_@@_tmpa_tl { \bool_if:NT #2 { \@@_typeset_TF: } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_print_macroname_aux:nn}
+% |#1| is prefix, |#2| is optional |TF| suffix.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print_macroname_aux:nn #1#2
+ {
+ \@@_if_macro_internal:nTF {#1}
+ { \@@_typeset_aux:n { #1 #2 } } { #1 #2 }
+ }
+\cs_generate_variant:Nn \@@_print_macroname_aux:nn { o }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\MacroLongFont}
+% \begin{macrocode}
+\providecommand \MacroLongFont
+ {
+ \fontfamily{lmtt}\fontseries{lc}\small
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_print_testfile:n, \@@_print_testfile_aux:n}
+% Used to show that a macro has a test, somewhere.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print_testfile:n #1
+ {
+ \bool_set_true:N \l_@@_macro_tested_bool
+ \tl_if_eq:nnF {#1} {*}
+ {
+ \seq_if_in:NnF \g_@@_testfiles_seq {#1}
+ {
+ \seq_gput_right:Nn \g_@@_testfiles_seq {#1}
+ \par
+ \@@_print_testfile_aux:n {#1}
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_print_testfile_aux:n #1
+ {
+ \footnotesize
+ (
+ \textit
+ {
+ The~ test~ suite~ for~ this~ command,~
+ and~ others~ in~ this~ file,~ is~ \textsf{#1}
+ }.
+ )\par
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\TestFiles}
+% \begin{macrocode}
+\DeclareDocumentCommand \TestFiles {m}
+ {
+ \par
+ \textit
+ {
+ The~ following~ test~ files~ are~
+ used~ for~ this~ code:~ \textsf{#1}.
+ }
+ \par \ignorespaces
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\UnitTested}
+% \begin{macrocode}
+\DeclareDocumentCommand \UnitTested { } { \testfile* }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\TestMissing}
+% \begin{macrocode}
+\DeclareDocumentCommand \TestMissing { m }
+ { \@@_test_missing:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_test_missing:n}
+% Keys in \cs{g_@@_missing_tests_prop} are lists of macros given as
+% arguments of one \env{macro} environment. Values are pairs of a
+% file name and a comment about the missing tests.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_test_missing:n #1
+ {
+ \@@_test_missing_aux:Nen
+ \g_@@_missing_tests_prop
+ { \seq_use:Nn \l_@@_names_seq { , } }
+ { { \g_file_curr_name_str \c_space_tl (#1) } }
+ }
+\cs_new_protected:Npn \@@_test_missing_aux:Nnn #1#2#3
+ {
+ \prop_get:NnNTF #1 {#2} \l_@@_tmpa_tl
+ { \tl_put_right:Nn \l_@@_tmpa_tl { , #3 } }
+ { \tl_set:Nn \l_@@_tmpa_tl {#3} }
+ \prop_put:Nno #1 {#2} \l_@@_tmpa_tl
+ }
+\cs_generate_variant:Nn \@@_test_missing_aux:Nnn { Ne }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_macro_end:}
+% It is too late for anyone to declare a test file for this macro, so
+% we can check now whether the macro is tested. If the \env{macro}
+% environment which is being ended is the outermost one, then wrap
+% each macro in \tn{texttt} (with the addition of |TF| if relevant)
+% and typeset two informations: that this ends the definition of some
+% macros, and that they are documented on some page.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_macro_end:
+ {
+ \endtrivlist
+ \@@_macro_end_check_tested:
+ \int_compare:nNnT \l_@@_nested_macro_int = 1
+ { \@@_macro_end_style:n { \@@_print_end_definition: } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_macro_end_check_tested:}
+% If the |checktest| option was issued and the macro is not an
+% auxiliary nor a variable (and it does not have a test), then add it
+% to the sequence of non-tested macros.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_macro_end_check_tested:
+ {
+ \bool_lazy_all:nT
+ {
+ { \g_@@_checktest_bool }
+ { ! \l_@@_macro_var_bool }
+ { ! \l_@@_macro_tested_bool }
+ }
+ {
+ \seq_set_filter:NNn \l_@@_tmpa_seq \l_@@_names_seq
+ { ! \@@_if_macro_internal_p:n {##1} }
+ \seq_gput_right:Ne \g_@@_not_tested_seq
+ {
+ \seq_use:Nn \l_@@_tmpa_seq { , }
+ \bool_if:NTF \l_@@_macro_pTF_bool {~(pTF)}
+ { \bool_if:NT \l_@@_macro_TF_bool {~(TF)} }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_macro_end_style:n}
+% Style for the extra information at the end of a top-level
+% \env{macro} environment.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_macro_end_style:n #1
+ {
+ \nobreak \noindent
+ { \footnotesize ( \emph{#1} ) \par }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_print_end_definition:,
+% \@@_macro_end_wrap_item:n,
+% \@@_print_documented:
+% }
+% Surround each item by \tn{texttt}, replacing |_|
+% by \tn{_} as well. Then list the
+% macro names through \cs{seq_use:Nnnn}, unless there are too many.
+% Finally, if the macro is neither auxiliary nor internal, add a link
+% to where it is documented.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_macro_end_wrap_item:n #1
+ {
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_replace_all:NVn \l_@@_tmpa_tl
+ \c_underscore_str { \_ }
+ \texttt { \l_@@_tmpa_tl }
+ }
+\cs_new_protected:Npn \@@_print_end_definition:
+ {
+ \seq_set_map:NNn \l_@@_tmpa_seq
+ \g_@@_nested_names_seq
+ { \@@_macro_end_wrap_item:n {##1} }
+ End~ of~ definition~ for~
+ \int_compare:nTF { \seq_count:N \l_@@_tmpa_seq <= 3 }
+ {
+ \seq_use:Nnnn \l_@@_tmpa_seq
+ { \,~and~ } { \,,~ } { \,,~and~ }
+ }
+ { \seq_item:Nn \l_@@_tmpa_seq {1}\,~and~others }
+ \@.
+ \@@_print_documented:
+ }
+\cs_new_protected:Npn \@@_print_documented:
+ {
+ \seq_gset_filter:NNn \g_@@_nested_names_seq
+ \g_@@_nested_names_seq
+ {
+ ! \bool_lazy_any_p:n
+ {
+ { \@@_if_macro_internal_p:n {##1} }
+ { \l_@@_macro_deprecated_bool }
+ { \l_@@_macro_nodoc_bool }
+ }
+ }
+ \seq_if_empty:NF \g_@@_nested_names_seq
+ {
+ \int_set:Nn \l_@@_tmpa_int
+ { \seq_count:N \g_@@_nested_names_seq }
+ \int_compare:nNnTF \l_@@_tmpa_int = 1 {~This~} {~These~}
+ \bool_if:NTF \l_@@_macro_var_bool {variable} {function}
+ \int_compare:nNnTF \l_@@_tmpa_int = 1 {~is~} {s~are~}
+ documented~on~page~
+ \@@_get_hyper_target:eN
+ { \seq_item:Nn \g_@@_nested_names_seq { 1 } }
+ \l_@@_tmpa_tl
+ \exp_args:Ne \pageref { \l_@@_tmpa_tl } .
+ }
+ \seq_gclear:N \g_@@_nested_names_seq
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Misc}
+%
+% \begin{macro}{\DescribeOption}
+% For describing package options: retained for consistency, but updated for
+% \pkg{doc}~v3.
+% \begin{macrocode}
+\NewDocElement[idxtype = option, idxgroup = options]{Option}{optionenv}
+% \end{macrocode}
+% \end{macro}
+%
+% Here are some definitions for additional markup that helps to
+% structure your documentation.
+%
+% \begin{environment}{danger}
+% \begin{environment}{ddanger}
+% \begin{syntax}
+% |\begin{[d]danger}|\\
+% dangerous code\\
+% |\end{[d]danger}|
+% \end{syntax}
+% \begin{danger}
+% Provides a danger bend, as known from the \TeX{}book.
+% \end{danger}
+% The actual character from the font |manfnt|:
+% \begin{macrocode}
+\font \manual = manfnt \scan_stop:
+\cs_gset:Npn \dbend { {\manual\char127} }
+% \end{macrocode}
+%
+% Defines the single danger bend. Use it whenever there is a feature in
+% your package that might be tricky to use. FIXME: Has to be fixed when
+% in combination with a macro-definition.
+% \begin{macrocode}
+\newenvironment {danger}
+ {
+ \begin{trivlist}\item[]\noindent
+ \begingroup\hangindent=2pc\hangafter=-2
+ \cs_set:Npn \par{\endgraf\endgroup}
+ \hbox to0pt{\hskip-\hangindent\dbend\hfill}\ignorespaces
+ }
+ {
+ \par\end{trivlist}
+ }
+% \end{macrocode}
+%
+% \begin{ddanger}
+% Use the double danger bend if there is something which could cause
+% serious problems when used in a wrong way. Better the normal user
+% does not know about such things.
+% \end{ddanger}
+% \begin{macrocode}
+\newenvironment {ddanger}
+ {
+ \begin{trivlist}\item[]\noindent
+ \begingroup\hangindent=3.5pc\hangafter=-2
+ \cs_set:Npn \par{\endgraf\endgroup}
+ \hbox to0pt{\hskip-\hangindent\dbend\kern2pt\dbend\hfill}\ignorespaces
+ }{
+ \par\end{trivlist}
+ }
+% \end{macrocode}
+% \end{environment}
+% \end{environment}
+%
+% \subsubsection{NB and NOTE}
+%
+% These macros are intended for additional notes added to the source that are not typeset.
+%
+% \begin{macro}{\NB}
+% \NB{wspr}{this is what I think about this!}
+% \begin{verbatim}
+% \NB{wspr}{this is what I think about this!}
+% \end{verbatim}
+% \begin{macrocode}
+\bool_if:NTF \g_@@_show_notes_bool
+ {
+ \NewDocumentCommand\NB{mm}
+ {
+ (\emph{Note}\footnote{\ttfamily [#1]:~\detokenize{#2}})
+ }
+ }
+ {
+ \NewDocumentCommand\NB{mm}{}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{NOTE}
+% \begin{NOTE}{wspr}
+% this is what I #$%& think about this!
+% \end{NOTE}
+% \begin{verbatim}
+% \begin{NOTE}{wspr}
+% this is what I #$%& think about this!
+% \end{NOTE}
+% \end{verbatim}
+% \begin{macrocode}
+\bool_if:NTF \g_@@_show_notes_bool
+ {
+ \NewDocumentEnvironment{NOTE}{m}
+ {
+ \par\noindent (\emph{Note}~[\texttt{#1}]:\par
+ \verbatim
+ }
+ {
+ \endverbatim
+ \par\noindent \emph{Note~end})\par
+ }
+ }
+ {
+ \NewDocumentEnvironment{NOTE}{m}{\comment}{\endcomment}
+ }
+% \end{macrocode}
+% \end{environment}
+%
+% \subsection{Footnote support}
+% The environments \env{function} and \env{variable} are boxes
+% and so looses footnotes. The following implements support.
+% It relies currently on an internal from hyperref to get the correct targets.
+%
+% \begin{macrocode}
+\providecommand\Hy@footnote@currentHref{}
+\prop_new:N\g_@@_fnmark_prop
+\cs_new_protected:Npn \@@_fn_store:
+ {
+ \prop_gput:Nee\g_@@_fnmark_prop
+ {fn\int_use:N\c@footnote}{{\Hy@footnote@currentHref}{\int_use:N\c@footnote}}
+ }
+\cs_new_protected:Npn \@@_fn_restore:n #1
+ {
+ \prop_get:NnN \g_@@_fnmark_prop {fn#1}\l_@@_tmpa_tl
+ \tl_gset:Ne\Hy@footnote@currentHref
+ {\exp_last_unbraced:NV\use_i:nn \l_@@_tmpa_tl }
+ \setcounter{footnote}{\exp_last_unbraced:NV\use_ii:nn \l_@@_tmpa_tl}
+ }
+
+\cs_generate_variant:Nn \hook_gput_next_code:nn {ne}
+\cs_new_protected:Npn \@@_fn_footnote:nn #1 #2
+ {
+ \footnotemark
+ \@@_fn_store:
+ \hook_gput_next_code:ne {env/#1/after}
+ {\exp_not:N\@@_fn_restore:n{\int_use:N\c@footnote}{\exp_not:n{\footnotetext{#2}}}}}
+
+\AddToHook{env/function/begin}{\def\footnote{\@@_fn_footnote:nn{function}}}
+\AddToHook{env/variable/begin}{\def\footnote{\@@_fn_footnote:nn{variable}}}
+% \end{macrocode}
+%
+% \subsection{Documenting templates}
+%
+% \begin{macrocode}
+\newenvironment{TemplateInterfaceDescription}[1]
+ {
+ \subsection{The~object~type~`#1'}
+ \begingroup
+ \@beginparpenalty\@M
+ \description
+ \def\TemplateArgument##1##2{\item[Arg:~##1]##2\par}
+ \def\TemplateSemantics
+ {
+ \enddescription\endgroup
+ \subsubsection*{Semantics:}
+ }
+ }
+ {
+ \par\bigskip
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newenvironment{TemplateDescription}[2]
+ {
+ \subsection{The~template~`#2'~(object~type~#1)}
+ \subsubsection*{Attributes:}
+ \begingroup
+ \@beginparpenalty\@M
+ \description
+ \def\TemplateKey##1##2##3##4
+ {
+ \item[##1~(##2)]##3%
+ \ifx\TemplateKey##4\TemplateKey\else
+% \hskip0ptplus3em\penalty-500\hskip 0pt plus 1filll Default:~##4%
+ \hfill\penalty500\hbox{}\hfill Default:~##4%
+ \nobreak\hskip-\parfillskip\hskip0pt\relax
+ \fi
+ \par
+ }
+ \def\TemplateSemantics
+ {
+ \enddescription\endgroup
+ \subsubsection*{Semantics~\&~Comments:}
+ }
+ }
+ { \par \bigskip }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newenvironment{InstanceDescription}[4][xxxxxxxxxxxxxxx]
+ {
+ \subsubsection{The~instance~`#3'~(template~#2/#4)}
+ \subsubsection*{Attribute~values:}
+ \begingroup
+ \@beginparpenalty\@M
+ \def\InstanceKey##1##2{\>\textbf{##1}\>##2\\}
+ \def\InstanceSemantics{\endtabbing\endgroup
+ \vskip-30pt\vskip0pt
+ \subsubsection*{Layout~description~\&~Comments:}}
+ \tabbing
+ xxxx\=#1\=\kill
+ }
+ { \par \bigskip }
+% \end{macrocode}
+%
+% \subsection{Inheriting doc}
+%
+% Code here is taken from \pkg{doc}, stripped of comments and translated
+% into \pkg{expl3} syntax. New features are added in various places.
+%
+% \begin{macro}
+% {\StopEventually, \MaybeStop, \Finale, \AlsoImplementation, \OnlyDescription}
+% \begin{variable}{\g_@@_finale_tl}
+% TODO: remove these four commands altogether, document that it is
+% better to use the \env{documentation} and \env{implementation}
+% environments.
+% \begin{macrocode}
+\DeclareDocumentCommand \OnlyDescription { }
+ { \bool_gset_false:N \g_@@_typeset_implementation_bool }
+\DeclareDocumentCommand \AlsoImplementation { }
+ { \bool_gset_true:N \g_@@_typeset_implementation_bool }
+\DeclareDocumentCommand \StopEventually { m }
+ {
+ \bool_if:NTF \g_@@_typeset_implementation_bool
+ {
+ \@bsphack
+ \tl_gset:Nn \g_@@_finale_tl { #1 \check@checksum }
+ \init@checksum
+ \@esphack
+ }
+ { #1 \endinput }
+ }
+% \end{macrocode}
+% We also need to support doc V3 \cs{MaybeStop} if it is around
+% (which may not be the case).
+% \begin{macrocode}
+\cs_if_exist:NT \MaybeStop
+ { \RenewCommandCopy \MaybeStop \StopEventually }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareDocumentCommand \Finale { }
+ { \tl_use:N \g_@@_finale_tl }
+\tl_new:N \g_@@_finale_tl
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}{\@@_input:n}
+% Inputting a file, with some setup: the module name should be empty
+% before the first |<@@=|\meta{module}|>| line in the file.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_input:n #1
+ {
+ \tl_gclear:N \g_@@_module_name_tl
+ \MakePercentIgnore
+ \input{#1}
+ \MakePercentComment
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DocInput}
+% Modified from \pkg{doc} to accept comma-list input (who has commas
+% in filenames?).
+% \begin{macrocode}
+\DeclareDocumentCommand \DocInput { m }
+ {
+ \clist_map_inline:nn {#1}
+ {
+ \clist_put_right:Nn \g_docinput_clist {##1}
+ \@@_input:n {##1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DocInputAgain}
+% Uses \cs{g_docinput_clist} to re-input whatever's already been
+% \tn{DocInput}-ed until now. May be used multiple times.
+% \begin{macrocode}
+\DeclareDocumentCommand \DocInputAgain { }
+ { \clist_map_function:NN \g_docinput_clist \@@_input:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DocInclude}
+% More or less exactly the same as \tn{include}, but uses
+% \tn{DocInput} on a \file{.fdd} or \file{.dtx} file (without file
+% extension), not \tn{input} on a \file{.tex} file.
+%
+% \begin{macrocode}
+\msg_new:nnn { l3doc } { missing-endgroup }
+ {
+ \str_if_eq:VnTF \@currenvir { document }
+ {
+ There~are~\int_use:N \tex_currentgrouplevel:D
+ \c_space_tl unclosed~groups~in~#1.
+ }
+ {
+ The~\@currenvir \c_space_tl environment~on~line~\@currenvline
+ \c_space_tl doesn't~have~a~matching~\iow_char:N\\end{\@currenvir}.
+ }
+ }
+\NewDocumentCommand \DocInclude { m }
+ {
+ \relax\clearpage
+ \docincludeaux
+ \IfFileExists{#1.fdd}
+ { \cs_set:Npn \currentfile{#1.fdd} }
+ { \cs_set:Npn \currentfile{#1.dtx} }
+ \int_compare:nNnTF \@auxout = \@partaux
+ { \@latexerr{\string\include\space cannot~be~nested}\@eha }
+ { \@docinclude {#1} }
+ % check missing \endgroup, e.g., missing "\end{macro}" in time
+ \int_compare:nNnF { \tex_currentgrouplevel:D } = { 0 }
+ {
+ \int_compare:nNnT { \tex_interactionmode:D } = { 0 }
+ { \int_gset:Nn \tex_interactionmode:D { 1 } }
+ \msg_fatal:nne { l3doc } { missing-endgroup } { \currentfile }
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_gset:Npn \@docinclude #1
+ {
+ \clearpage
+ \immediate\write\@mainaux{\string\@input{#1.aux}}
+ \@tempswatrue
+ \if@partsw
+ \@tempswafalse
+ \cs_set:Npe \@tempb {#1}
+ \clist_map_inline:Nn \@partlist
+ {
+ \if_meaning:w \@tempa \@tempb
+ \@tempswatrue
+ \fi:
+ }
+ \fi
+ \if@tempswa
+ \cs_set_eq:NN \@auxout \@partaux
+ \immediate\openout\@partaux #1.aux
+ \immediate\write\@partaux{\relax}
+ \cs_set_eq:NN \@ltxdoc@PrintIndex \PrintIndex
+ \cs_set_eq:NN \PrintIndex \relax
+ \cs_set_eq:NN \@ltxdoc@PrintChanges \PrintChanges
+ \cs_set_eq:NN \PrintChanges \relax
+ \cs_set_eq:NN \@ltxdoc@theglossary \theglossary
+ \cs_set_eq:NN \@ltxdoc@endtheglossary \endtheglossary
+ \part{\currentfile}
+ {
+ \cs_set_eq:NN \ttfamily\relax
+ \cs_gset:Npe \filekey
+ { \filekey,~ \thepart = { \ttfamily \currentfile } }
+ }
+ \DocInput{\currentfile}
+ \cs_set_eq:NN \PrintIndex \@ltxdoc@PrintIndex
+ \cs_set_eq:NN \PrintChanges \@ltxdoc@PrintChanges
+ \cs_set_eq:NN \theglossary \@ltxdoc@theglossary
+ \cs_set_eq:NN \endtheglossary \@ltxdoc@endtheglossary
+ \clearpage
+ \@writeckpt{#1}
+ \immediate \closeout \@partaux
+ \else
+ \@nameuse{cp@#1}
+ \fi
+ \cs_set_eq:NN \@auxout \@mainaux
+ }
+% \end{macrocode}
+%
+% Here, |MMMMI| (for page references) and |MMMMV| (for codeline
+% references) are interpreted by |makeindex| as an uppercase Roman
+% number pages, and should be large enough to avoid collisions with
+% other uses of uppercase Roman number pages. Two subtle differences
+% between \cs{@wrindex} and \cs{codeline@wrindex} are that the first
+% must be a delayed write because the page number is not known yet, and
+% it must close a group and finish some space-hack.
+%
+% We also provide versions for our use that refer
+% \begin{macrocode}
+\cs_gset_protected:Npn \@wrindex #1
+ {
+ \protected@write \@indexfile {}
+ { \string \indexentry {#1} { MMMMI - \thepage } }
+ \endgroup \@esphack
+ }
+\cs_gset_protected:Npn \codeline@wrindex #1
+ {
+ \immediate\write\@indexfile
+ {
+ \string\indexentry{#1}
+ { MMMMV - \filesep \int_use:N \c@CodelineNo }
+ }
+ }
+\tl_gclear:N \filesep
+\cs_new_protected:Npn \@@_index_page_hc:nn #1#2
+ {
+ \protected@write \@indexfile {}
+ {
+ \string \indexentry { #1 \encapchar hdpindex{#2} }
+ { MMMMI - \thepage }
+ }
+ }
+\cs_new_protected:Npn \@@_index_codeline_hc:nn #1#2
+ {
+ \immediate\write\@indexfile
+ {
+ \string \indexentry { #1 \encapchar hdclindex{\the\c@HD@hypercount}{#2} }
+ { MMMMV - \filesep \int_use:N \c@CodelineNo - MMMD - \the\c@HD@hypercount - M }
+ }
+ }
+% \end{macrocode}
+% We already have a single |HD.xx| target per code line. It would be
+% better to have a target |CL.\the\c@CodelineNo| per code line and
+% change |hdclindex{\the\c@HD@hypercount}| to a mechanism closer to
+% |hdpindex|, but we need to understand better the different types of
+% indexings, and there are subtleties with indexing |\{| and |\}|.
+% \end{macro}
+%
+% \begin{macro}{\docincludeaux}
+% \begin{macrocode}
+\cs_gset:Npn \docincludeaux
+ {
+ \tl_set:Nn \thepart { \alphalph { part } }
+ \tl_set:Nn \filesep { \thepart - }
+ \cs_set_eq:NN \filekey \use_none:n
+ \tl_gput_right:Nn \index@prologue
+ {
+ \cs_gset:Npn \@oddfoot
+ {
+ \parbox { \textwidth }
+ {
+ \strut \footnotesize
+ \raggedright { \bfseries File~Key: } ~ \filekey
+ }
+ }
+ \cs_set_eq:NN \@evenfoot \@oddfoot
+ }
+ \cs_gset_eq:NN \docincludeaux \relax
+ \cs_gset:Npn \@oddfoot
+ {
+ \cs_if_exist:cTF { ver @ \currentfile }
+ { File~\thepart :~{\ttfamily\currentfile}~ }
+ {
+ \GetFileInfo{\currentfile}
+ File~\thepart :~{\ttfamily\filename}~
+ Date:~\ExplFileDate\ % space
+ Version~\ExplFileVersion
+ }
+ \hfill \thepage
+ }
+ \cs_set_eq:NN \@evenfoot \@oddfoot
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{The \env{macrocode} environment}
+%
+% \begin{macro}{\xmacro@code, \@@_xmacro_code:n, \@@_xmacro_code:w}
+% Hook into the \texttt{macrocode} environment in a dirty way:
+% \tn{xmacro@code} is responsible for grabbing (and tokenizing) the
+% body of the environment. Redefine it to pass what it grabs to
+% \cs{@@_xmacro_code:n}. This new macro replaces all |@@| by the
+% appropriate module name. One exceptional case is the
+% |<@@=|\meta{module}|>| lines themselves, where |@@| should not be
+% modified. Actually, we search for such lines, to set the module
+% name automatically. We need to be careful: no |<@@=| should appear
+% as such in the code below since \pkg{l3doc} is also typeset using
+% this code.
+% At each |<@@=| found, replace the \meta{module} in the code behind
+% it, update the \meta{module}, and loop to check for further
+% occurrences of |<@@=|.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_other:N \^^A
+ \char_set_catcode_active:N \^^S
+ \char_set_catcode_active:N \^^B
+ \char_set_catcode_other:N \^^L
+ \char_set_catcode_other:N \^^R
+ \char_set_lccode:nn { `\^^A } { `\% }
+ \char_set_lccode:nn { `\^^S } { `\ }
+ \char_set_lccode:nn { `\^^B } { `\\ }
+ \char_set_lccode:nn { `\^^L } { `\{ }
+ \char_set_lccode:nn { `\^^R } { `\} }
+ \tex_lowercase:D
+ {
+ \group_end:
+ \cs_set_protected:Npn \xmacro@code
+ #1 ^^A ^^S^^S^^S^^S ^^Bend ^^Lmacrocode^^R
+ { \@@_xmacro_code:n {#1} \end{macrocode} }
+ }
+\group_begin:
+ \char_set_catcode_active:N \<
+ \char_set_catcode_active:N \>
+ \cs_new_protected:Npn \@@_xmacro_code:n #1
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_if_in:nnTF {#1} { < @ @ = }
+ { \@@_xmacro_code:w #1 < @ @ = \q_recursion_tail > \q_recursion_stop }
+ {
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \@@_detect_internals:N \l_@@_tmpa_tl
+ \@@_replace_at_at:N \l_@@_tmpa_tl
+ \tl_use:N \l_@@_tmpa_tl
+ }
+ }
+ \cs_new_protected:Npn \@@_xmacro_code:w #1 < @ @ = #2 >
+ {
+ % Add code before <@@@@=...>
+ \tl_set:Nn \l_@@_tmpb_tl {#1}
+ \@@_detect_internals:N \l_@@_tmpb_tl
+ \@@_replace_at_at:N \l_@@_tmpb_tl
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl
+ % Check for \q_recursion_tail
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ { \tl_use:N \l_@@_tmpa_tl }
+ % Change module name and add <@@@@=#2> to typeset output
+ \tl_gset:Nn \g_@@_module_name_tl {#2}
+ \tl_put_right:Nn \l_@@_tmpa_tl { < \text { \verbatim@font @ @ = #2 } > }
+ % Loop
+ \@@_xmacro_code:w
+ }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{At end document}
+%
+% Print all defined and documented macros/functions.
+%
+% \begin{macrocode}
+\iow_new:N \g_@@_func_iow
+% \end{macrocode}
+%
+% \begin{macrocode}
+\tl_new:N \l_@@_doc_def_tl
+\tl_new:N \l_@@_doc_undef_tl
+\tl_new:N \l_@@_undoc_def_tl
+\tl_const:Nn \c_@@_iow_separator_tl { ---- }
+\tl_const:Nn \c_@@_iow_midrule_tl { -- }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show_functions_defined:
+ {
+ \bool_lazy_and:nnT
+ { \g_@@_typeset_implementation_bool } { \g_@@_checkfunc_bool }
+ {
+ \iow_term:e { \c_@@_iow_separator_tl \iow_newline: }
+ \iow_open:Nn \g_@@_func_iow { \c_sys_jobname_str .cmds }
+
+ \tl_clear:N \l_@@_doc_def_tl
+ \tl_clear:N \l_@@_doc_undef_tl
+ \tl_clear:N \l_@@_undoc_def_tl
+ \seq_gremove_duplicates:N \g_doc_functions_seq
+ \seq_gremove_duplicates:N \g_doc_macros_seq
+ \seq_map_inline:Nn \g_doc_functions_seq
+ {
+ \seq_if_in:NnTF \g_doc_macros_seq {##1}
+ {
+ \tl_put_right:Ne \l_@@_doc_def_tl
+ { \iow_newline: > ~ ##1 }
+ }
+ {
+ \tl_put_right:Ne \l_@@_doc_undef_tl
+ { \iow_newline: ! ~ ##1 }
+ }
+ }
+ \seq_map_inline:Nn \g_doc_macros_seq
+ {
+ \seq_if_in:NnF \g_doc_functions_seq {##1}
+ {
+ \tl_put_right:Ne \l_@@_undoc_def_tl
+ { \iow_newline: ? ~ ##1 }
+ }
+ }
+ \@@_functions_typeout:nN
+ {
+ Functions~both~documented~and~defined: \iow_newline:
+ (In~order~of~being~documented)
+ }
+ \l_@@_doc_def_tl
+ \@@_functions_typeout:nN
+ { Functions~documented~but~not~defined: }
+ \l_@@_doc_undef_tl
+ \@@_functions_typeout:nN
+ { Functions~defined~but~not~documented: }
+ \l_@@_undoc_def_tl
+
+ \iow_close:N \g_@@_func_iow
+ \iow_term:e { \c_@@_iow_separator_tl }
+ }
+ }
+\AtEndDocument { \@@_show_functions_defined: }
+% \end{macrocode}
+%
+% TODO: use \cs{iow_term:e}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_functions_typeout:nN #1#2
+ {
+ \tl_if_empty:NF #2
+ {
+ \iow_now:Ne \g_@@_func_iow
+ {
+ \c_@@_iow_midrule_tl \iow_newline:
+ #1 \iow_newline:
+ \c_@@_iow_midrule_tl
+ #2
+ }
+ \tl_clear:N #2
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show_not_tested:
+ {
+ \bool_if:NT \g_@@_checktest_bool
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ \prop_if_empty:NF \g_@@_missing_tests_prop
+ {
+ \cs_set:Npn \@@_tmpa:w ##1##2
+ {
+ \iow_newline:
+ \space\space\space\space \exp_not:n {##1}
+ \clist_map_function:nN {##2} \@@_tmpb:w
+ }
+ \cs_set:Npn \@@_tmpb:w ##1
+ {
+ \iow_newline:
+ \space\space\space\space\space\space * ~ ##1
+ }
+ \tl_put_right:Ne \l_@@_tmpa_tl
+ {
+ \iow_newline: \iow_newline:
+ The~ following~ macro(s)~ have~ incomplete~ tests:
+ \iow_newline:
+ \prop_map_function:NN
+ \g_@@_missing_tests_prop \@@_tmpa:w
+ }
+ }
+ \seq_if_empty:NF \g_@@_not_tested_seq
+ {
+ \cs_set:Npn \@@_tmpa:w ##1
+ { \clist_map_function:nN {##1} \@@_tmpb:w }
+ \cs_set:Npn \@@_tmpb:w ##1
+ {
+ \iow_newline:
+ \space\space\space\space ##1
+ }
+ \tl_put_right:Ne \l_@@_tmpa_tl
+ {
+ \iow_newline:
+ \iow_newline:
+ The~ following~ macro(s)~ do~ not~ have~ any~ tests:
+ \iow_newline:
+ \seq_map_function:NN
+ \g_@@_not_tested_seq \@@_tmpa:w
+ }
+ }
+ \tl_if_empty:NF \l_@@_tmpa_tl
+ {
+ \int_set:Nn \l_@@_tmpa_int { \tex_interactionmode:D }
+ \errorstopmode
+ \ClassError { l3doc } { \l_@@_tmpa_tl } { }
+ \int_gset:Nn \tex_interactionmode:D { \l_@@_tmpa_int }
+ }
+ }
+ }
+\AtEndDocument { \@@_show_not_tested: }
+% \end{macrocode}
+%
+% \subsection{Indexing}
+%
+% \subsubsection{Necessary patching}
+%
+% The following is useful to set up \pkg{hyperref} targets, for instance
+% for the purpose of indexing. Contrarily to \pkg{hypdoc} we do not try
+% to save pdf destinations, as this leads to too many \pdfTeX{} warnings
+% on early runs.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_target:
+ {
+ \mode_leave_vertical:
+ \group_begin:
+ \HD@savedestfalse \HD@target
+ \group_end:
+ }
+% \end{macrocode}
+% Force targets on every code line.
+% \begin{macrocode}
+\cs_set_nopar:Npe \theCodelineNo
+ {
+ \group_begin:
+ \exp_not:N \HD@savedestfalse
+ \exp_not:o \theCodelineNo
+ \group_end:
+ }
+% \end{macrocode}
+%
+% Inside the table of contents (and other similar lists introduced by
+% \cs{@starttoc}), we suppress indexing. This is because \cs{cmd},
+% \cs{cs}, or \cs{tn} appearing in titles only gets typeset in the
+% second run, and getting their indexing right would require even more
+% runs than we already need. Besides, it is not useful to index uses of
+% some command in the table of contents.
+% \begin{macrocode}
+\bool_new:N \l_@@_allow_indexing_bool
+\bool_set_true:N \l_@@_allow_indexing_bool
+\use:e
+ {
+ \exp_not:n { \cs_set_nopar:Npn \@starttoc #1 }
+ {
+ \group_begin:
+ \bool_set_false:N \l_@@_allow_indexing_bool
+ \exp_not:o { \@starttoc {#1} }
+ \group_end:
+ }
+ }
+% \end{macrocode}
+%
+% \subsubsection{Userspace commands}
+%
+% Fix index (for now):
+% \begin{macrocode}
+\g@addto@macro \theindex { \MakePrivateLetters }
+\cs_gset:Npn \verbatimchar {&}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\setcounter { IndexColumns } { 2 }
+% \end{macrocode}
+%
+% Set up the Index to use \tn{part}
+% \begin{macrocode}
+\IndexPrologue
+ {
+ \part*{Index}
+ \markboth{Index}{Index}
+ \addcontentsline{toc}{part}{Index}
+ The~italic~numbers~denote~the~pages~where~the~
+ corresponding~entry~is~described,~
+ numbers~underlined~point~to~the~definition,~
+ all~others~indicate~the~places~where~it~is~used.
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\SpecialIndex}
+% An attempt at affecting how commands which appear within the
+% \env{macrocode} environment are treated in the index.
+% \begin{macrocode}
+\cs_gset_protected:Npn \SpecialIndex #1
+ {
+ \@bsphack
+ \@@_special_index:nn {#1} { }
+ \@esphack
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\msg_new:nnn { l3doc } { print-index-howto }
+ {
+ Generate~the~index~by~executing\\
+ \iow_indent:n
+ { makeindex~-s~gind.ist~-o~\c_sys_jobname_str.ind~\c_sys_jobname_str.idx }
+ }
+\tl_gput_right:Nn \PrintIndex
+ { \AtEndDocument { \msg_info:nn { l3doc } { print-index-howto } } }
+% \end{macrocode}
+%
+% \subsubsection{Internal index commands}
+%
+% \begin{macro}{\it@is@a}
+% The index of one-character commands within the \env{macrocode}
+% environment is produced using \tn{it@is@a} \meta{char}. Alter that
+% command.
+% \begin{macrocode}
+\cs_gset_protected:Npn \it@is@a #1
+ {
+ \use:e
+ {
+ \@@_special_index_module:nnnnN
+ {#1}
+ { \bslash #1 }
+ { }
+ { }
+ \c_false_bool
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_special_index:nn}
+% ^^A TODO this override is somewhat a hack
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_special_index:nn #1#2
+ {
+ \@@_key_get:n {#1}
+ \quark_if_no_value:NF \l_@@_override_module_tl
+ { \tl_set_eq:NN \l_@@_index_module_tl \l_@@_override_module_tl }
+ \@@_special_index_module:ooonN
+ { \l_@@_index_key_tl }
+ { \l_@@_index_macro_tl }
+ { \l_@@_index_module_tl }
+ {#2}
+ \l_@@_index_internal_bool
+ }
+\cs_generate_variant:Nn \@@_special_index:nn { o }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_special_index_module:nnnnN,
+% \@@_special_index_module:ooonN,
+% \@@_special_index_aux:nnnnnn,
+% \@@_special_index_set:Nn,
+% }
+% Remotely based on Heiko's replacement to play nicely with
+% \pkg{hypdoc}. We use \tn{verb} or a \tn{verbatim@font} construction
+% depending on whether the number of tokens in |#2| is equal to its
+% number of characters: if it is not then that suggests that there is
+% a construct such as |\meta{...}|.
+% \begin{macrocode}
+\tl_new:N \l_@@_index_escaped_macro_tl
+\tl_new:N \l_@@_index_escaped_key_tl
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_special_index_module:nnnnN #1#2#3#4#5
+% \end{macrocode}
+% \begin{arguments}
+% \item key
+% \item macro
+% \item module
+% \item index `type' (\texttt{main}/\texttt{usage}/\emph{etc.})
+% \item boolean whether internal command
+% \end{arguments}
+% \begin{macrocode}
+ {
+ \use:e
+ {
+ \exp_not:n { \@@_special_index_aux:nnnnnn {#1} {#2} }
+ \tl_if_empty:nTF {#3}
+ { { } { } { } }
+ {
+ \str_if_eq:nnTF {#3} { TeX }
+ {
+ { TeX~and~LaTeX2e }
+ { \string\TeX{}~and~\string\LaTeXe{} }
+ }
+ {
+ {#3}
+ { \string\pkg{#3} }
+ }
+ { \bool_if:NT #5 { ~internal } ~commands: }
+ }
+ }
+ {#4}
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \@@_special_index_module:nnnnN { ooo }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_special_index_aux:nnnnnn #1#2#3#4#5#6
+% \end{macrocode}
+% \begin{arguments}
+% \item key
+% \item macro
+% \item index subheading string
+% \item index subheading text
+% \item index subheading suffix (appended to both arg 3 and 4)
+% \item index `type' (\texttt{main}/\texttt{usage}/\emph{etc.})
+% \end{arguments}
+% \begin{macrocode}
+ {
+ \tl_set:Nn \l_@@_index_escaped_key_tl {#1}
+ \@@_quote_special_char:N \l_@@_index_escaped_key_tl
+ \@@_special_index_set:Nn \l_@@_index_escaped_macro_tl {#2}
+ \str_if_eq:onTF { \@currenvir } { macrocode }
+ { \@@_index_codeline_hc:nn }
+ {
+ \str_case:nnF {#6}
+ {
+ { main } { \@@_index_codeline_hc:nn }
+ { usage } { \@@_index_page_hc:nn }
+ }
+ { \@@_target: \@@_index_page_hc:nn }
+ }
+ {
+ \tl_if_empty:nF { #3 #4 #5 }
+ { #3 #5 \actualchar #4 #5 \levelchar }
+ \l_@@_index_escaped_key_tl
+ \actualchar
+ {
+ \token_to_str:N \verbatim@font \c_space_tl
+ \l_@@_index_escaped_macro_tl
+ }
+ }
+ {#6}
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\hdpindex, \@@_old_hdpindex:nn, \hdclindex, \@@_old_hdclindex:nnn, \@@_hdindex:nn, \c_@@_active_minus_tl, \@@_hdindex_aux:nn, \@@_hdindex_aux:w}
+% Note that |#3| here could contain |MMMMI-| or |MMMMV-| more than once
+% if several successive code lines have been merged into a range
+% somehow. Note incidentally that the dash is active in some of our
+% sources, like |interface3.tex| or |source2e.tex|.
+% \begin{macrocode}
+\group_begin:
+\char_set_active_eq:NN - \scan_stop:
+\tl_const:Ne \c_@@_active_minus_tl { \char_generate:nn { `- } { 13 } }
+\group_end:
+\cs_new_eq:NN \@@_old_hdpindex:nn \hdpindex
+\cs_new_eq:NN \@@_old_hdclindex:nnn \hdclindex
+\cs_gset_protected:Npn \hdpindex #1
+ { \@@_hdindex:nn { \@@_old_hdpindex:nn {#1} } }
+\cs_gset_protected:Npn \hdclindex #1#2
+ { \@@_hdindex:nn { \@@_old_hdclindex:nnn {#1} {#2} } }
+\cs_new_protected:Npn \@@_hdindex:nn #1#2
+ {
+ \tl_set:Nn \l_@@_tmpa_tl {#2}
+ \tl_replace_all:Nen \l_@@_tmpa_tl
+ { \exp_not:V \c_@@_active_minus_tl \exp_not:V \c_@@_active_minus_tl }
+ { -- }
+ \seq_set_split:NnV \l_@@_tmpa_seq { -- } \l_@@_tmpa_tl
+ \seq_set_map:NNn \l_@@_tmpa_seq \l_@@_tmpa_seq
+ { \@@_hdindex_aux:nn {#1} {##1} }
+ \seq_use:Nn \l_@@_tmpa_seq { -- }
+ }
+\cs_new_protected:Npn \@@_hdindex_aux:nn #1#2
+ {
+ \tl_set:Nn \l_@@_tmpa_tl {#2}
+ \tl_replace_all:Nnn \l_@@_tmpa_tl { MMMM } { \use_none:nn }
+ \tl_if_in:NnT \l_@@_tmpa_tl { MMMD }
+ {
+ \tl_replace_all:Nen \l_@@_tmpa_tl
+ { \exp_not:V \c_@@_active_minus_tl MMMD } { - MMMD }
+ \tl_replace_all:Nnn \l_@@_tmpa_tl { - MMMD } { \@@_hdindex_aux:w }
+ }
+ \use:e { \exp_not:n {#1} { \exp_not:V \l_@@_tmpa_tl } }
+ }
+\cs_new_protected:Npn \@@_hdindex_aux:w #1 M { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_special_index_set:Nn #1#2
+ {
+ \__kernel_tl_set:Nx #1 { \tl_to_str:n {#2} }
+ \@@_if_almost_str:nTF {#2}
+ {
+ \tl_replace_all:Nen #1 { \tl_to_str:n { __ } }
+ {
+ \verbatimchar
+ \token_to_str:N \_ \token_to_str:N \_
+ \token_to_str:N \verb * \verbatimchar
+ }
+ \exp_args:Ne \tl_map_inline:nn
+ { \tl_to_str:N \verbatimchar \token_to_str:N _ }
+ {
+ \tl_replace_all:Nnn #1 {##1}
+ {
+ \verbatimchar \c_backslash_str ##1
+ \token_to_str:N \verb * \verbatimchar
+ }
+ }
+ \__kernel_tl_set:Nx #1
+ {
+ \token_to_str:N \verb * \verbatimchar
+ #1 \verbatimchar
+ }
+ }
+ {
+ \tl_set:Nn #1 {#2}
+ \tl_replace_all:NVn #1
+ \c_backslash_str
+ { \token_to_str:N \bslash \c_space_tl }
+ }
+ \@@_quote_special_char:N #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_quote_special_char:N}
+% Quote some special characters.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_quote_special_char:N #1
+ {
+ \tl_map_inline:nn { \quotechar \actualchar \encapchar \levelchar \bslash }
+ {
+ \tl_replace_all:Nen #1
+ { \tl_to_str:N ##1 } { \quotechar \tl_to_str:N ##1 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Finding sort-key and module}
+%
+% \begin{macro}{\@@_key_get:n}
+% Sets \cs{l_@@_index_macro_tl}, \cs{l_@@_index_key_tl}, and
+% \cs{l_@@_index_module_tl} from |#1|. The base function is stored by
+% \cs{@@_key_get_base:nN} in \cs{l_@@_index_macro_tl}, falling back to
+% |#1| if it contains markup or has no signature.
+%
+% The starting point for the \meta{key} is \cs{l_@@_index_key_tl} as a
+% string. If it the first character is a backslash, remove
+% it. Then recognize |expl| functions and variables by the presence
+% of |:| or~|_| and \TeX{}/\LaTeXe{} commands by the presence of~|@|.
+% For |expl| names, we call \cs{@@_key_func:} or \cs{@@_key_var:},
+% which are responsible for removing some characters and finding the
+% module name, while for \TeX{}/\LaTeXe{} commands the module name is
+% |TeX|, and others have an empty module name.
+% \begin{macrocode}
+\cs_new_protected:Npe \@@_key_get:n #1
+ {
+ \exp_not:N \@@_key_get_base:nN {#1} \exp_not:N \l_@@_index_macro_tl
+ \__kernel_tl_set:Nx \exp_not:N \l_@@_index_key_tl
+ { \exp_not:N \tl_to_str:N \exp_not:N \l_@@_index_macro_tl }
+ \tl_clear:N \exp_not:N \l_@@_index_module_tl
+ \tl_if_in:NnTF \exp_not:N \l_@@_index_key_tl { \tl_to_str:n { __ } }
+ { \bool_set_true:N \exp_not:N \l_@@_index_internal_bool }
+ { \bool_set_false:N \exp_not:N \l_@@_index_internal_bool }
+ \exp_not:N \tl_if_head_eq_charcode:VNT
+ \exp_not:N \l_@@_index_key_tl \c_backslash_str
+ { \exp_not:N \@@_key_pop: }
+ \tl_if_in:NnTF \exp_not:N \l_@@_index_key_tl { \token_to_str:N : }
+ { \exp_not:N \@@_key_func: }
+ {
+ \tl_if_in:NnTF \exp_not:N \l_@@_index_key_tl { \token_to_str:N _ }
+ { \exp_not:N \@@_key_var: }
+ {
+ \tl_if_in:NnT \exp_not:N \l_@@_index_key_tl { \token_to_str:N @ }
+ { \tl_set:Nn \exp_not:N \l_@@_index_module_tl { TeX } }
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_key_pop:
+ {
+ \__kernel_tl_set:Nx \l_@@_index_key_tl
+ { \tl_tail:N \l_@@_index_key_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_key_trim_module:n, \@@_key_drop_underscores:}
+% Helper that removes from \cs{l_@@_index_module_tl} everything after
+% the first occurence of |#1|. Helper that removes any leading
+% underscore from \cs{l_@@_index_key_tl}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_key_trim_module:n #1
+ {
+ \cs_set:Npn \@@_tmpa:w ##1 #1 ##2 \q_stop
+ { \exp_not:n {##1} }
+ \__kernel_tl_set:Nx \l_@@_index_module_tl
+ { \exp_after:wN \@@_tmpa:w \l_@@_index_module_tl #1 \q_stop }
+ }
+\cs_new_protected:Npn \@@_key_drop_underscores:
+ {
+ \tl_if_head_eq_charcode:VNT \l_@@_index_key_tl _
+ { \@@_key_pop: \@@_key_drop_underscores: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_key_func:}
+% The function \cs{@@_key_func:} is used if there is a colon, so
+% either for usual \pkg{expl3} functions or for keys from
+% \pkg{l3keys}. After removing from the key a leading dot (for the
+% latter case), and any leading underscore, the module name is the
+% part before any colon or underscore.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_key_func:
+ {
+ \tl_if_head_eq_charcode:VNT \l_@@_index_key_tl .
+ { \@@_key_pop: }
+ \@@_key_drop_underscores:
+ \tl_set_eq:NN \l_@@_index_module_tl \l_@@_index_key_tl
+ \exp_args:No \@@_key_trim_module:n { \token_to_str:N : }
+ \exp_args:No \@@_key_trim_module:n { \token_to_str:N _ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_key_var:, \@@_key_get_module:}
+% The function \cs{@@_key_var:} covers cases with no~|:| but with~|_|,
+% typically variables but occasionally non-\pkg{expl3} functions such
+% as \Lua{} function with underscores. First test the second
+% character: if that is~|_| then assume we have a proper variable,
+% otherwise use the part before any underscore as the module name.
+% For variables, distinguish quarks and scan marks (starting with |q|
+% and~|s|), then drop the first letter (local/global/constant marker)
+% and underscores to improve the index sorting.
+% Then get the module as the first (underscore-delimited) \enquote{word}.
+% In the past, we distinguished according to how many such words there
+% were, to detect commands like \cs[no-index]{c_zero}, which should be
+% sorted as |int| variables, and \cs[no-index]{l_tmpa_dim}, which should
+% be sorted in the |dim| and not the |tmpa| module.
+% Now the first case has been deprecated for some time, while |tmpa| and
+% similar are special-cased through an explicit list given below.
+% The way it works is that if the module is in a list of special names
+% that are not valid modules, then we try the last word, and if that
+% also fails (for instance in the deprecated \cs[no-index]{c_one_hundred})
+% we empty the module completely.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_key_var:
+ {
+ \exp_args:Ne \tl_if_head_eq_charcode:nNTF
+ { \exp_args:No \str_tail:n \l_@@_index_key_tl } _
+ {
+ \str_case:en { \str_head:N \l_@@_index_key_tl }
+ {
+ { q } { \tl_set:Nn \l_@@_index_module_tl { quark } }
+ { s } { \tl_set:Nn \l_@@_index_module_tl { scan } }
+ }
+ \@@_key_pop:
+ \@@_key_pop:
+ \@@_key_drop_underscores:
+ \tl_if_empty:NT \l_@@_index_module_tl
+ {
+ \seq_set_split:NoV \l_@@_tmpa_seq
+ { \token_to_str:N _ } \l_@@_index_key_tl
+ \seq_get_left:NN \l_@@_tmpa_seq \l_@@_index_module_tl
+ \clist_if_in:NoT \g_@@_non_modules_clist \l_@@_index_module_tl
+ {
+ \seq_get_right:NN \l_@@_tmpa_seq \l_@@_index_module_tl
+ \clist_if_in:NoT \g_@@_non_modules_clist \l_@@_index_module_tl
+ {
+ \tl_clear:N \l_@@_index_module_tl
+ }
+ }
+ }
+ }
+ {
+ \tl_set_eq:NN \l_@@_index_module_tl \l_@@_index_key_tl
+ \exp_args:No \@@_key_trim_module:n { \token_to_str:N _ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_non_modules_clist}
+% List of names that appear as the first word in an \pkg{expl3}
+% command, but that are not true modules, so that they should be
+% sorted differently in an index.
+% \begin{macrocode}
+\clist_new:N \g_@@_non_modules_clist
+\clist_gset:Ne \g_@@_non_modules_clist
+ {
+ \tl_to_str:n
+ {
+
+ alignment, ampersand, atsign, backslash, catcode, circumflex,
+ code, colon, document, dollar, e, empty, false, hash, inf,
+ initex, job, left, log, math, mark, max, minus, nan, nil, no,
+ novalue, other, parameter, percent, pi, recursion, right, space,
+ stop, term, tilde, tmpa, tmpb, true, underscore, zero, one, two,
+ three, four, five, six, seven, eight, nine, ten, eleven, twelve,
+ thirteen, fourteen, fifteen, sixteen, thirty, hundred
+
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Change history}
+%
+% Set the change history to use \tn{part}.
+% Allow control names to be hyphenated in here\dots
+% \begin{macrocode}
+\GlossaryPrologue
+ {
+ \part*{Change~History}
+ {\GlossaryParms\ttfamily\hyphenchar\font=`\-}
+ \markboth{Change~History}{Change~History}
+ \addcontentsline{toc}{part}{Change~History}
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnn { l3doc } { print-changes-howto }
+ {
+ Generate~the~change~list~by~executing\\
+ \iow_indent:n
+ { makeindex~-s~gglo.ist~-o~\c_sys_jobname_str.gls~\c_sys_jobname_str.glo }
+ }
+\tl_gput_right:Nn \PrintChanges
+ { \AtEndDocument { \msg_info:nn { l3doc } { print-changes-howto } } }
+% \end{macrocode}
+%
+%^^A The standard \changes command modified slightly to better cope with
+%^^A this multiple file document.
+%^^A\def\changes@#1#2#3{%
+%^^A \let\protect\@unexpandable@protect
+%^^A \edef\@tempa{\noexpand\glossary{#2\space\currentfile\space#1\levelchar
+%^^A \ifx\saved@macroname\@empty
+%^^A \space
+%^^A \actualchar
+%^^A \generalname
+%^^A \else
+%^^A \expandafter\@gobble
+%^^A \saved@macroname
+%^^A \actualchar
+%^^A \string\verb\quotechar*%
+%^^A \verbatimchar\saved@macroname
+%^^A \verbatimchar
+%^^A \fi
+%^^A :\levelchar #3}}%
+%^^A \@tempa\endgroup\@esphack}
+%
+% \subsection{Default configuration}
+%
+% \begin{macrocode}
+\bool_if:NTF \g_@@_typeset_implementation_bool
+ {
+ \RecordChanges
+ \CodelineIndex
+ \EnableCrossrefs
+ \AlsoImplementation
+ }
+ {
+ \CodelineNumbered
+ \DisableCrossrefs
+ \OnlyDescription
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+%</class>
+% \end{macrocode}
+%
+% \subsection{Internal macros for \LaTeX3 sources}
+%
+% These definitions are only used by the \LaTeX3 documentation; they are
+% not necessary for third-party users of \cls{l3doc}. In time this will
+% be broken into a separate package that is specifically loaded in the
+% various \pkg{expl3} modules, \emph{etc.}
+%
+% \begin{macrocode}
+%<*cfg>
+% \end{macrocode}
+%
+% The Guilty Parties.
+% \begin{macrocode}
+\tl_const:Nn \Team
+ {
+ The~\LaTeX3~Project\thanks
+ {\url{https://www.latex-project.org/latex3/}}
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\NewDocumentCommand{\ExplMakeTitle}{mm}
+ {
+ \title
+ {
+ The~\pkg{#1}~package \\ #2
+ }
+ \author
+ {
+ The~\LaTeX3~Project\thanks{E-mail:~
+ \href{mailto:latex-l@listserv.uni-heidelberg.de}
+ {latex-l@listserv.uni-heidelberg.de}}
+ }
+ \date{Released~\ExplFileDate}
+ \maketitle
+ }
+% \end{macrocode}
+%
+% \subsection{Math extras}
+%
+% For \pkg{l3fp}.
+%
+% \begin{macrocode}
+\AtBeginDocument
+ {
+ \clist_map_inline:nn
+ {
+ asin, acos, atan, acot,
+ asinh, acosh, atanh, acoth, round, floor, ceil
+ }
+ { \exp_args:Nc \DeclareMathOperator{#1}{#1} }
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\nan}
+% \begin{macrocode}
+\NewDocumentCommand { \nan } { } { \text { \texttt { nan } } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</cfg>
+% \end{macrocode}
+%
+%
+% \subsection{Makeindex configuration}
+%
+% \begin{macrocode}
+%<*docist>
+% \end{macrocode}
+%
+% The makeindex style \file{l3doc.ist} is used in place of the usual
+% \file{gind.ist} to ensure that |I| is used in the sequence |I J K| not
+% |I II II|, which would be the default makeindex behaviour.
+%
+% Will: Do we need this?
+%
+% Frank: at the moment we do not distribute or generate this file.
+% \file{gind.ist} is used instead.
+%
+% \begin{macro}[do-not-index={\\,\n}]{}
+% \begin{macrocode}
+actual '='
+quote '!'
+level '>'
+preamble
+"\n \\begin{theindex} \n \\makeatletter\\scan@allowedfalse\n"
+postamble
+"\n\n \\end{theindex}\n"
+item_x1 "\\efill \n \\subitem "
+item_x2 "\\efill \n \\subsubitem "
+delim_0 "\\pfill "
+delim_1 "\\pfill "
+delim_2 "\\pfill "
+% The next lines will produce some warnings when
+% running Makeindex as they try to cover two different
+% versions of the program:
+lethead_prefix "{\\bfseries\\hfil "
+lethead_suffix "\\hfil}\\nopagebreak\n"
+lethead_flag 1
+heading_prefix "{\\bfseries\\hfil "
+heading_suffix "\\hfil}\\nopagebreak\n"
+headings_flag 1
+
+% and just for source3:
+% Remove R so I is treated in sequence I J K not I II III
+page_precedence "rnaA"
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</docist>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3doc.pdf b/macros/latex-dev/required/l3kernel/l3doc.pdf
new file mode 100644
index 0000000000..604acf43b6
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3doc.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3docstrip.dtx b/macros/latex-dev/required/l3kernel/l3docstrip.dtx
new file mode 100644
index 0000000000..c2733e810e
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3docstrip.dtx
@@ -0,0 +1,96 @@
+% \iffalse
+%
+%% File l3dosctrip.dtx
+%
+% Copyright (C) 2012-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver|program>
+%</driver|program>
+%<*driver>
+% The same approach as used in \textsf{DocStrip}: if \cs{documentclass}
+% is undefined then skip the driver, allowing the file to be used to extract
+% \texttt{l3docstrip.tex} from \texttt{l3docstrip.dtx} directly. This works
+% as the \cs{fi} is only seen if \LaTeX{} is not in use. The odd \cs{jobname}
+% business allows the extraction to work with \LaTeX{} provided an appropriate
+% \texttt{.ins} file is set up.
+%<*gobble>
+\ifx\jobname\relax\let\documentclass\undefined\fi
+\ifx\documentclass\undefined
+\else \csname fi\endcsname
+%</gobble>
+ \def\filename{docstrip.dtx}
+ \documentclass[full,kernel]{l3doc}
+ \ExplSyntaxOn
+ \cs_set_eq:NN \__codedoc_replace_at_at:N \use_none:n
+ \ExplSyntaxOff
+ \begin{document}
+ \DocInput{\jobname.dtx}
+ \end{document}
+%<*gobble>
+\fi
+%</gobble>
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3docstrip} module\\ Code extraction and manipulation^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% This is a stub file to allow extraction of \texttt{l3docstrip}: all
+% functionality has been moved to the main DocStrip program.
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3docstrip} implementation}
+%
+% \begin{macrocode}
+%<*program>
+% \end{macrocode}
+%
+% Simply input DocStrip.
+% \begin{macrocode}
+\input docstrip %
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</program>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3docstrip.pdf b/macros/latex-dev/required/l3kernel/l3docstrip.pdf
new file mode 100644
index 0000000000..e68f61dcc5
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3docstrip.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3expan.dtx b/macros/latex-dev/required/l3kernel/l3expan.dtx
new file mode 100644
index 0000000000..e79b5f32b9
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3expan.dtx
@@ -0,0 +1,2398 @@
+% \iffalse meta-comment
+%
+%% File: l3expan.dtx
+%
+% Copyright (C) 1990-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3expan} module\\ Argument expansion^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% This module provides generic methods for expanding \TeX{} arguments in a
+% systematic manner. The functions in this module all have prefix |exp|.
+%
+% Not all possible variations are implemented for every base
+% function. Instead only those that are used within the \LaTeX3 kernel
+% or otherwise seem to be of general interest are implemented.
+% Consult the module description to find out which functions are
+% actually defined. The next section explains how to define missing
+% variants.
+%
+% \section{Defining new variants}
+% \label{sec:l3expan:defining-variants}
+%
+% The definition of variant forms for base functions may be necessary
+% when writing new functions or when applying a kernel function in a
+% situation that we haven't thought of before.
+%
+% Internally preprocessing of arguments is done with functions of the form
+% \cs[no-index]{exp_\ldots{}}. They all look alike, an example would be
+% \cs{exp_args:NNo}. This function has three arguments, the first and the
+% second are a single tokens, while the third argument should be given
+% in braces. Applying \cs{exp_args:NNo} expands the content of third
+% argument once before any expansion of the first and second arguments.
+% If \cs{seq_gpush:No} was not defined it could be coded in the following way:
+% \begin{verbatim}
+% \exp_args:NNo \seq_gpush:Nn
+% \g_file_name_stack
+% { \l_tmpa_tl }
+% \end{verbatim}
+% In other words, the first argument to \cs{exp_args:NNo} is the base
+% function and the other arguments are preprocessed and then passed to
+% this base function. In the example the first argument to the base
+% function should be a single token which is left unchanged while the
+% second argument is expanded once. From this example we can also see
+% how the variants are defined. They just expand into the appropriate
+% |\exp_| function followed by the desired base function, \emph{e.g.}
+% \begin{quote}
+% |\cs_generate_variant:Nn \seq_gpush:Nn { No } |
+% \end{quote}
+% results in the definition of |\seq_gpush:No|
+% \begin{quote}
+% |\cs_new:Npn \seq_gpush:No { \exp_args:NNo \seq_gpush:Nn }|
+% \end{quote}
+% Providing variants in this way in style files is safe as the
+% \cs{cs_generate_variant:Nn} function will only create new definitions if
+% there is not already one available. Therefore adding
+% such definition to later releases of the kernel will not make such
+% style files obsolete.
+%
+% The steps above may be automated by using the function
+% \cs{cs_generate_variant:Nn}, described next.
+%
+% \section{Methods for defining variants}
+% \label{sec:l3expan:variants-method}
+%
+% We recall the set of available argument specifiers.
+% \begin{itemize}
+% \item |N|~is used for single-token arguments while |c|~constructs a
+% control sequence from its name and passes it to a parent function as
+% an |N|-type argument.
+% \item Many argument types extract or expand some tokens and provide it
+% as an |n|-type argument, namely a braced multiple-token argument:
+% |V|~extracts the value of a variable, |v|~extracts the value from
+% the name of a variable, |n|~uses the argument as it is, |o|~expands
+% once, |f|~expands fully the front of the token list, |e| and
+% |x|~expand fully all tokens (differences are explained later).
+% \item A few odd argument types remain: |T|~and |F|~for conditional
+% processing, otherwise identical to |n|-type arguments,
+% |p|~for the parameter text
+% in definitions, |w|~for arguments with a specific syntax, and |D|~to
+% denote primitives that should not be used directly.
+% \end{itemize}
+%
+% \begin{function}[updated = 2017-11-28]
+% {\cs_generate_variant:Nn, \cs_generate_variant:cn}
+% \begin{syntax}
+% \cs{cs_generate_variant:Nn} \meta{parent control sequence} \Arg{variant argument specifiers}
+% \end{syntax}
+% This function is used to define argument-specifier variants of the
+% \meta{parent control sequence} for \LaTeX3 code-level macros. The
+% \meta{parent control sequence} is first separated into the
+% \meta{base name} and \meta{original argument specifier}. The
+% comma-separated list of \meta{variant argument specifiers} is
+% then used to define variants of the
+% \meta{original argument specifier} if these are not already
+% defined; entries which correspond to existing functions are silently
+% ingored. For each \meta{variant} given, a function is created
+% that expands its arguments as detailed and passes them
+% to the \meta{parent control sequence}. So for example
+% \begin{verbatim}
+% \cs_set:Npn \foo:Nn #1#2 { code here }
+% \cs_generate_variant:Nn \foo:Nn { c }
+% \end{verbatim}
+% creates a new function |\foo:cn| which expands its first
+% argument into a control sequence name and passes the result to
+% |\foo:Nn|. Similarly
+% \begin{verbatim}
+% \cs_generate_variant:Nn \foo:Nn { NV , cV }
+% \end{verbatim}
+% generates the functions |\foo:NV| and |\foo:cV| in the same
+% way. The \cs{cs_generate_variant:Nn} function should only be applied if
+% the \meta{parent control sequence} is already defined. (This is only
+% enforced if debugging support \texttt{check-declarations} is enabled.)
+% If the \meta{parent
+% control sequence} is protected or if the \meta{variant} involves any
+% |x|~argument, then the \meta{variant control sequence} is also
+% protected. The \meta{variant} is created globally, as is any
+% \cs[no-index]{exp_args:N\meta{variant}} function needed to carry out the
+% expansion. There is no need to re-apply \cs{cs_generate_variant:Nn} after
+% changing the definition of the parent function: the variant will always
+% use the current definition of the parent. Providing variants repeatedly is
+% safe as \cs{cs_generate_variant:Nn} will only create new definitions if
+% there is not already one available.
+%
+% Only |n|~and |N| arguments can be changed to other types. The only
+% allowed changes are
+% \begin{itemize}
+% \item |c|~variant of an |N|~parent;
+% \item |o|, |V|, |v|, |f|, |e|, or~|x| variant of an |n|~parent;
+% \item |N|, |n|, |T|, |F|, or |p| argument unchanged.
+% \end{itemize}
+% This means the \meta{parent} of a \meta{variant} form is always
+% unambiguous, even in cases where both an |n|-type parent and an
+% |N|-type parent exist, such as for \cs{tl_count:n} and
+% \cs{tl_count:N}.
+%
+% When creating variants for conditional functions,
+% \cs{prg_generate_conditional_variant:Nnn} provides a convenient way
+% of handling the related function set.
+%
+% For backward compatibility it is currently possible to make |n|,
+% |o|, |V|, |v|, |f|, |e|, or |x|-type variants of an |N|-type argument or
+% |N| or |c|-type variants of an |n|-type argument. Both are
+% deprecated. The first because passing more than one token to an
+% |N|-type argument will typically break the parent function's code.
+% The second because programmers who use that most often want to
+% access the value of a variable given its name, hence should use a
+% |V|-type or |v|-type variant instead of |c|-type. In those cases,
+% using the lower-level \cs{exp_args:No} or \cs{exp_args:Nc}
+% functions explicitly is preferred to defining confusing variants.
+% \end{function}
+%
+% \begin{function}[added = 2018-04-04, updated = 2019-02-08]
+% {\exp_args_generate:n}
+% \begin{syntax}
+% \cs{exp_args_generate:n} \Arg{variant argument specifiers}
+% \end{syntax}
+% Defines \cs[no-index]{exp_args:N\meta{variant}} functions for each
+% \meta{variant} given in the comma list \Arg{variant argument
+% specifiers}. Each \meta{variant} should consist of the letters |N|,
+% |c|, |n|, |V|, |v|, |o|, |f|, |e|, |x|, |p| and the resulting function is
+% protected if the letter |x| appears in the \meta{variant}. This is
+% only useful for cases where \cs{cs_generate_variant:Nn} is not
+% applicable.
+% \end{function}
+%
+% \section{Introducing the variants}
+%
+% The |V| type returns the value of a register, which can be one of
+% |tl|, |clist|, |int|, |skip|, |dim|, |muskip|, or built-in \TeX{}
+% registers. The |v| type is the same except it first creates a
+% control sequence out of its argument before returning the
+% value.
+%
+% In general, the programmer should not need to be concerned with
+% expansion control. When simply using the content of a variable,
+% functions with a |V| specifier should be used. For those referred to by
+% (cs)name, the |v| specifier is available for the same purpose. Only when
+% specific expansion steps are needed, such as when using delimited
+% arguments, should the lower-level functions with |o| specifiers be employed.
+%
+% The |e| type expands all tokens fully, starting from the first. More
+% precisely the expansion is identical to that of \TeX{}'s \tn{message}
+% (in particular |#| needs not be doubled). It relies on the
+% primitive \tn{expanded} hence is fast.
+%
+% The |x| type expands all tokens fully, starting from the first. In
+% contrast to |e|, all macro parameter characters |#| must be doubled,
+% and omitting this leads to low-level errors. In addition this type of
+% expansion is not expandable, namely functions that have |x| in their
+% signature do not themselves expand when appearing inside |e| or |x|
+% expansion.
+%
+% The |f| type is so special that it deserves an example. It is
+% typically used in contexts where only expandable commands are allowed.
+% Then |x|-expansion cannot be used, and |f|-expansion provides an
+% alternative that expands the front of the token list
+% as much as can be done in such contexts. For
+% instance, say that we want to evaluate the integer expression $3 + 4$
+% and pass the result $7$ as an argument to an expandable function
+% |\example:n|. For this, one should define a variant using
+% \cs{cs_generate_variant:Nn} |\example:n| |{| |f| |}|, then do
+% \begin{quote}
+% |\example:f { \int_eval:n { 3 + 4 } }|
+% \end{quote}
+% Note that |x|-expansion would also expand \cs{int_eval:n} fully to its
+% result~$7$, but the variant |\example:x| cannot be expandable. Note
+% also that |o|-expansion would not expand \cs{int_eval:n} fully to its
+% result since that function requires several expansions. Besides the
+% fact that |x|-expansion is protected rather than expandable, another
+% difference between |f|-expansion and |x|-expansion is that
+% |f|-expansion expands tokens from the beginning and stops as soon as a
+% non-expandable token is encountered, while |x|-expansion continues
+% expanding further tokens. Thus, for instance
+% \begin{quote}
+% |\example:f { \int_eval:n { 1 + 2 } , \int_eval:n { 3 + 4 } }|
+% \end{quote}
+% results in the call
+% \begin{quote}
+% |\example:n { 3 , \int_eval:n { 3 + 4 } }|
+% \end{quote}
+% while using |\example:x| or |\example:e| instead results in
+% \begin{quote}
+% |\example:n { 3 , 7 }|
+% \end{quote}
+% at the cost of being protected for |x|-type.
+% If you use |f| type expansion in conditional processing then
+% you should stick to using |TF| type functions only as the expansion
+% does not finish any |\if... \fi:| itself!
+%
+% It is important to note that both \texttt{f}- and \texttt{o}-type
+% expansion are concerned with the expansion of tokens from left to
+% right in their arguments. In particular, \texttt{o}-type expansion
+% applies to the first \emph{token} in the argument it receives: it
+% is conceptually similar to
+% \begin{verbatim}
+% \exp_after:wN <base function> \exp_after:wN { <argument> }
+% \end{verbatim}
+% At the same time, \texttt{f}-type expansion stops at the \emph{first}
+% non-expandable token. This means for example that both
+% \begin{verbatim}
+% \tl_set:No \l_tmpa_tl { { \g_tmpb_tl } }
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% \tl_set:Nf \l_tmpa_tl { { \g_tmpb_tl } }
+% \end{verbatim}
+% leave |\g_tmpb_tl| unchanged: |{| is the first token in the
+% argument and is non-expandable.
+%
+% It is usually best to keep the following in mind when using variant
+% forms.
+% \begin{itemize}
+% \item
+% Variants with |x|-type arguments (that are fully expanded before
+% being passed to the |n|-type base function) are never expandable
+% even when the base function is. Such variants cannot work
+% correctly in arguments that are themselves subject to expansion.
+% Consider using |f| or |e| expansion.
+% \item
+% In contrast, |e|~expansion (full expansion, almost like~|x| except
+% for the treatment of~|#|) does not prevent variants from being
+% expandable (if the base function is).
+% \item
+% Finally |f|~expansion only expands the front of the token list,
+% stopping at the first non-expandable token. This may fail to
+% fully expand the argument.
+% \end{itemize}
+%
+% When speed is essential (for functions that do very little work and
+% whose variants are used numerous times in a document) the following
+% considerations apply because the speed of internal functions that
+% expand the arguments of a base function depend on what needs doing
+% with each argument and where this happens in the list of arguments:
+% \begin{itemize}
+% \item for fastest processing any |c|-type arguments should come first
+% followed by all other modified arguments;
+% \item unchanged |N|-type args that appear before modified ones have
+% a small performance hit;
+% \item unchanged |n|-type args that appear before modified ones have
+% a relative larger performance hit.
+% \end{itemize}
+%
+% \section{Manipulating the first argument}
+%
+% These functions are described in detail: expansion of multiple tokens follows
+% the same rules but is described in a shorter fashion.
+%
+% \begin{function}[EXP]{\exp_args:Nc, \exp_args:cc}
+% \begin{syntax}
+% \cs{exp_args:Nc} \meta{function} \Arg{tokens}
+% \end{syntax}
+% This function absorbs two arguments (the \meta{function} name and
+% the \meta{tokens}). The \meta{tokens} are expanded until only characters
+% remain, and are then turned into a control sequence.
+% The result is inserted into the input stream \emph{after} reinsertion
+% of the \meta{function}. Thus the \meta{function} may take more than
+% one argument: all others are left unchanged.
+%
+% The |:cc| variant constructs the \meta{function} name in the same
+% manner as described for the \meta{tokens}.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_args:No}
+% \begin{syntax}
+% \cs{exp_args:No} \meta{function} \Arg{tokens} ...
+% \end{syntax}
+% This function absorbs two arguments (the \meta{function} name and
+% the \meta{tokens}). The \meta{tokens} are expanded once, and the result
+% is inserted in braces into the input stream \emph{after} reinsertion
+% of the \meta{function}. Thus the \meta{function} may take more than
+% one argument: all others are left unchanged.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_args:NV}
+% \begin{syntax}
+% \cs{exp_args:NV} \meta{function} \meta{variable}
+% \end{syntax}
+% This function absorbs two arguments (the names of the \meta{function} and
+% the \meta{variable}). The content of the \meta{variable} are recovered
+% and placed inside braces into the input stream \emph{after} reinsertion
+% of the \meta{function}. Thus the \meta{function} may take more than
+% one argument: all others are left unchanged.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_args:Nv}
+% \begin{syntax}
+% \cs{exp_args:Nv} \meta{function} \Arg{tokens}
+% \end{syntax}
+% This function absorbs two arguments (the \meta{function} name and
+% the \meta{tokens}). The \meta{tokens} are expanded until only characters
+% remain, and are then turned into a control sequence.
+% This control sequence should
+% be the name of a \meta{variable}. The content of the \meta{variable} are
+% recovered and placed inside braces into the input stream \emph{after}
+% reinsertion of the \meta{function}. Thus the \meta{function} may take more
+% than one argument: all others are left unchanged.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2018-05-15]{\exp_args:Ne}
+% \begin{syntax}
+% \cs{exp_args:Ne} \meta{function} \Arg{tokens}
+% \end{syntax}
+% This function absorbs two arguments (the \meta{function} name and
+% the \meta{tokens}) and exhaustively expands the \meta{tokens}.
+% The result is inserted in braces into the input stream
+% \emph{after} reinsertion of the \meta{function}.
+% Thus the \meta{function} may take more
+% than one argument: all others are left unchanged.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_args:Nf}
+% \begin{syntax}
+% \cs{exp_args:Nf} \meta{function} \Arg{tokens}
+% \end{syntax}
+% This function absorbs two arguments (the \meta{function} name and
+% the \meta{tokens}). The \meta{tokens} are fully expanded until the
+% first non-expandable token is found (if that is a space it is
+% removed), and the result
+% is inserted in braces into the input stream \emph{after} reinsertion
+% of the \meta{function}. Thus the \meta{function} may take more than
+% one argument: all others are left unchanged.
+% \end{function}
+%
+% \begin{function}{\exp_args:Nx}
+% \begin{syntax}
+% \cs{exp_args:Nx} \meta{function} \Arg{tokens}
+% \end{syntax}
+% This function absorbs two arguments (the \meta{function} name and
+% the \meta{tokens}) and exhaustively expands the \meta{tokens}.
+% The result is inserted in braces into the input stream
+% \emph{after} reinsertion of the \meta{function}.
+% Thus the \meta{function} may take more
+% than one argument: all others are left unchanged.
+% \end{function}
+%
+% \section{Manipulating two arguments}
+%
+% \begin{function}[EXP, updated = 2018-05-15]
+% {
+% \exp_args:NNc,
+% \exp_args:NNo,
+% \exp_args:NNV,
+% \exp_args:NNv,
+% \exp_args:NNe,
+% \exp_args:NNf,
+% \exp_args:Ncc,
+% \exp_args:Nco,
+% \exp_args:NcV,
+% \exp_args:Ncv,
+% \exp_args:Ncf,
+% \exp_args:NVV
+% }
+% \begin{syntax}
+% \cs{exp_args:NNc} \meta{token_1} \meta{token_2} \Arg{tokens}
+% \end{syntax}
+% These optimized functions absorb three arguments and expand the second and
+% third as detailed by their argument specifier. The first argument
+% of the function is then the next item on the input stream, followed
+% by the expansion of the second and third arguments.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2018-05-15]
+% {
+% \exp_args:Nnc,
+% \exp_args:Nno,
+% \exp_args:NnV,
+% \exp_args:Nnv,
+% \exp_args:Nne,
+% \exp_args:Nnf,
+% \exp_args:Noc,
+% \exp_args:Noo,
+% \exp_args:Nof,
+% \exp_args:NVo,
+% \exp_args:Nfo,
+% \exp_args:Nff,
+% \exp_args:Nee,
+% }
+% \begin{syntax}
+% \cs{exp_args:Noo} \meta{token} \Arg{tokens_1} \Arg{tokens_2}
+% \end{syntax}
+% These functions absorb three arguments and expand the second and
+% third as detailed by their argument specifier. The first argument
+% of the function is then the next item on the input stream, followed
+% by the expansion of the second and third arguments.
+% \end{function}
+%
+% \begin{function}
+% {
+% \exp_args:NNx,
+% \exp_args:Ncx,
+% \exp_args:Nnx,
+% \exp_args:Nox,
+% \exp_args:Nxo,
+% \exp_args:Nxx
+% }
+% \begin{syntax}
+% \cs{exp_args:NNx} \meta{token_1} \meta{token_2} \Arg{tokens}
+% \end{syntax}
+% These functions absorb three arguments and expand the second and
+% third as detailed by their argument specifier. The first argument
+% of the function is then the next item on the input stream, followed
+% by the expansion of the second and third arguments. These functions
+% are not expandable due to their |x|-type argument.
+% \end{function}
+%
+% \section{Manipulating three arguments}
+%
+% \begin{function}[EXP]
+% {
+% \exp_args:NNNo,
+% \exp_args:NNNV,
+% \exp_args:NNNv,
+% \exp_args:NNNe,
+% \exp_args:Nccc,
+% \exp_args:NcNc,
+% \exp_args:NcNo,
+% \exp_args:Ncco
+% }
+% \begin{syntax}
+% \cs{exp_args:NNNo} \meta{token_1} \meta{token_2} \meta{token_3} \Arg{tokens}
+% \end{syntax}
+% These optimized functions absorb four arguments and expand the second, third
+% and fourth as detailed by their argument specifier. The first
+% argument of the function is then the next item on the input stream,
+% followed by the expansion of the second argument, \emph{etc}.
+% \end{function}
+%
+% \begin{function}[EXP]
+% {
+% \exp_args:NNcf,
+% \exp_args:NNno,
+% \exp_args:NNnV,
+% \exp_args:NNoo,
+% \exp_args:NNVV,
+% \exp_args:Ncno,
+% \exp_args:NcnV,
+% \exp_args:Ncoo,
+% \exp_args:NcVV,
+% \exp_args:Nnnc,
+% \exp_args:Nnno,
+% \exp_args:Nnnf,
+% \exp_args:Nnff,
+% \exp_args:Nooo,
+% \exp_args:Noof,
+% \exp_args:Nffo,
+% \exp_args:Neee
+% }
+% \begin{syntax}
+% \cs{exp_args:NNoo} \meta{token_1} \meta{token_2} \Arg{token_3} \Arg{tokens}
+% \end{syntax}
+% These functions absorb four arguments and expand the second, third
+% and fourth as detailed by their argument specifier. The first
+% argument of the function is then the next item on the input stream,
+% followed by the expansion of the second argument, \emph{etc}.
+% \end{function}
+%
+% \begin{function}[added = 2015-08-12]
+% {
+% \exp_args:NNNx,
+% \exp_args:NNnx,
+% \exp_args:NNox,
+% \exp_args:Nccx,
+% \exp_args:Ncnx,
+% \exp_args:Nnnx,
+% \exp_args:Nnox,
+% \exp_args:Noox,
+% }
+% \begin{syntax}
+% \cs{exp_args:NNnx} \meta{token_1} \meta{token_2} \Arg{tokens_1} \Arg{tokens_2}
+% \end{syntax}
+% These functions absorb four arguments and expand the second, third
+% and fourth as detailed by their argument specifier. The first
+% argument of the function is then the next item on the input stream,
+% followed by the expansion of the second argument, \emph{etc.}
+% \end{function}
+%
+% \section{Unbraced expansion}
+%
+% \begin{function}[EXP, updated = 2018-05-15]
+% {
+% \exp_last_unbraced:No,
+% \exp_last_unbraced:NV,
+% \exp_last_unbraced:Nv,
+% \exp_last_unbraced:Ne,
+% \exp_last_unbraced:Nf,
+% \exp_last_unbraced:NNo,
+% \exp_last_unbraced:NNV,
+% \exp_last_unbraced:NNf,
+% \exp_last_unbraced:Nco,
+% \exp_last_unbraced:NcV,
+% \exp_last_unbraced:Nno,
+% \exp_last_unbraced:Nnf,
+% \exp_last_unbraced:Noo,
+% \exp_last_unbraced:Nfo,
+% \exp_last_unbraced:NNNo,
+% \exp_last_unbraced:NNNV,
+% \exp_last_unbraced:NNNf,
+% \exp_last_unbraced:NnNo,
+% \exp_last_unbraced:NNNNo,
+% \exp_last_unbraced:NNNNf,
+% }
+% \begin{syntax}
+% \cs{exp_last_unbraced:Nno} \meta{token} \Arg{tokens_1} \Arg{tokens_2}
+% \end{syntax}
+% These functions absorb the number of arguments given by their
+% specification, carry out the expansion
+% indicated and leave the results in the input stream, with the
+% last argument not surrounded by the usual braces.
+% Of these, the |:Nno|, |:Noo|, |:Nfo| and |:NnNo|
+% variants need slower processing.
+% \begin{texnote}
+% As an optimization, the last argument is unbraced by some
+% of those functions before expansion. This can cause problems
+% if the argument is empty: for instance,
+% \cs{exp_last_unbraced:Nf} |\foo_bar:w| |{ }| \cs{q_stop}
+% leads to an infinite loop, as the quark is \texttt{f}-expanded.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\exp_last_unbraced:Nx}
+% \begin{syntax}
+% \cs{exp_last_unbraced:Nx} \meta{function} \Arg{tokens}
+% \end{syntax}
+% This function fully expands the \meta{tokens} and leaves the result
+% in the input stream after reinsertion of the \meta{function}.
+% This function is not expandable.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_last_two_unbraced:Noo}
+% \begin{syntax}
+% \cs{exp_last_two_unbraced:Noo} \meta{token} \Arg{tokens_1} \Arg{tokens_2}
+% \end{syntax}
+% This function absorbs three arguments and expands the second and third
+% once. The first argument of the function is then the next item on the
+% input stream, followed by the expansion of the second and third arguments,
+% which are not wrapped in braces.
+% This function needs special (slower) processing.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_after:wN}
+% \begin{syntax}
+% \cs{exp_after:wN} \meta{token_1} \meta{token_2}
+% \end{syntax}
+% Carries out a single expansion of \meta{token_2} (which may consume
+% arguments) prior to the expansion of \meta{token_1}. If \meta{token_2} has
+% no expansion (for example, if it is a character) then it is left
+% unchanged. It is important to notice that \meta{token_1} may be
+% \emph{any} single token, including group-opening and -closing
+% tokens (|{| or |}| assuming normal \TeX{} category codes). Unless
+% specifically required this should be avoided: expansion should be carried out using an
+% appropriate argument specifier variant or the appropriate
+% \cs[no-index]{exp_args:N\meta{variant}} function.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{expandafter}.
+% \end{texnote}
+% \end{function}
+%
+%
+% \section{Preventing expansion}
+%
+% Despite the fact that the following functions are all about preventing
+% expansion, they're designed to be used in an expandable context and hence
+% are all marked as being `expandable' since they themselves disappear
+% after the expansion has completed.
+%
+% \begin{function}[EXP]{\exp_not:N}
+% \begin{syntax}
+% \cs{exp_not:N} \meta{token}
+% \end{syntax}
+% Prevents expansion of the \meta{token} in a context where it would
+% otherwise be expanded, for example an |e|-type or |x|-type argument or
+% the first token in an |o|-type or |f|-type argument.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{noexpand}. It only prevents
+% expansion. At the beginning of an |f|-type argument, a space
+% \meta{token} is removed even if it appears as \cs{exp_not:N}
+% \cs{c_space_token}. In an |e|-expanding definition
+% (\cs{cs_new:Npe}), a macro parameter introduces an argument even
+% if it appears as \cs{exp_not:N} |#| |1|. This differs from
+% \cs{exp_not:n}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_not:c}
+% \begin{syntax}
+% \cs{exp_not:c} \Arg{tokens}
+% \end{syntax}
+% Expands the \meta{tokens} until only characters remain, and then
+% converts this into a control sequence.
+% Further expansion of this control sequence is then inhibited using
+% \cs{exp_not:N}.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_not:n}
+% \begin{syntax}
+% \cs{exp_not:n} \Arg{tokens}
+% \end{syntax}
+% Prevents expansion of the \meta{tokens} in an |e|-type or |x|-type argument.
+% In all other cases the \meta{tokens} continue to be expanded, for
+% example in the input stream or in other types of arguments such as
+% \texttt{c}, \texttt{f}, \texttt{v}. The argument of \cs{exp_not:n}
+% \emph{must} be surrounded by braces.
+% \begin{texnote}
+% This is the \eTeX{} primitive \tn{unexpanded}. In an
+% |e|-expanding definition (\cs{cs_new:Npe}), \cs{exp_not:n}~|{#1}|
+% is equivalent to |##1| rather than to~|#1|, namely it inserts the
+% two characters |#| and~|1|, and
+% \cs{exp_not:n}~|{#}| is equivalent to |#|, namely it inserts the
+% character~|#|.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_not:o}
+% \begin{syntax}
+% \cs{exp_not:o} \Arg{tokens}
+% \end{syntax}
+% Expands the \meta{tokens} once, then prevents any further expansion
+% in |e|-type or |x|-type arguments using \cs{exp_not:n}.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_not:V}
+% \begin{syntax}
+% \cs{exp_not:V} \meta{variable}
+% \end{syntax}
+% Recovers the content of the \meta{variable}, then prevents expansion
+% of this material in |e|-type or |x|-type arguments using \cs{exp_not:n}.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_not:v}
+% \begin{syntax}
+% \cs{exp_not:v} \Arg{tokens}
+% \end{syntax}
+% Expands the \meta{tokens} until only characters remains, and then
+% converts this into a control sequence which should be a \meta{variable}
+% name.
+% The content of the \meta{variable} is recovered, and further
+% expansion in |e|-type or |x|-type arguments is prevented using \cs{exp_not:n}.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_not:e}
+% \begin{syntax}
+% \cs{exp_not:e} \Arg{tokens}
+% \end{syntax}
+% Expands \meta{tokens} exhaustively, then protects the result of the
+% expansion (including any tokens which were not expanded) from
+% further expansion in |e|-type or |x|-type arguments using \cs{exp_not:n}.
+% This is very rarely useful but is provided for consistency.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_not:f}
+% \begin{syntax}
+% \cs{exp_not:f} \Arg{tokens}
+% \end{syntax}
+% Expands \meta{tokens} fully until the first unexpandable token is
+% found (if it is a space it is removed). Expansion then stops, and
+% the result of the expansion (including any tokens which were not
+% expanded) is protected from further expansion in |e|-type or |x|-type arguments
+% using \cs{exp_not:n}.
+% \end{function}
+%
+% \begin{function}[updated = 2011-06-03, EXP]{\exp_stop_f:}
+% \begin{syntax}
+% |\foo_bar:f| \{ \meta{tokens} \cs{exp_stop_f:} \meta{more tokens} \}
+% \end{syntax}
+% This function terminates an \texttt{f}-type expansion. Thus if
+% a function |\foo_bar:f| starts an \texttt{f}-type expansion
+% and all of \meta{tokens} are expandable \cs{exp_stop_f:}
+% terminates the expansion of tokens even if \meta{more tokens}
+% are also expandable. The function itself is an implicit space
+% token. Inside an \texttt{e}-type or \texttt{x}-type expansion, it retains its
+% form, but when typeset it produces the underlying space (\verb*| |).
+% \end{function}
+%
+%
+% \section{Controlled expansion}
+%
+% The \pkg{expl3} language makes all efforts to hide the complexity of
+% \TeX{} expansion from the programmer by providing concepts that
+% evaluate/expand arguments of functions prior to calling the \enquote{base}
+% functions. Thus, instead of using many \tn{expandafter} calls and
+% other trickery it is usually a matter of choosing the right variant
+% of a function to achieve a desired result.
+%
+% Of course, deep down \TeX{} is using expansion as always and there
+% are cases where a programmer needs to control that expansion
+% directly; typical situations are basic data manipulation tools. This
+% section documents the functions for that level. These
+% commands are used throughout the kernel code, but we hope that outside
+% the kernel there will be little need to resort to them. Instead the
+% argument manipulation methods document above should usually be sufficient.
+%
+% While \cs{exp_after:wN} expands one token (out of order) it is
+% sometimes necessary to expand several tokens in one go. The next set
+% of commands provide this functionality. Be aware that it is
+% absolutely required that the programmer has full control over the
+% tokens to be expanded, i.e., it is not possible to use these
+% functions to expand unknown input as part of
+% \meta{expandable-tokens} as that will break badly if unexpandable
+% tokens are encountered in that place!
+%
+% \begin{function}[added=2015-08-23,EXP]
+% {
+% \exp:w ,
+% \exp_end:
+% }
+% \begin{syntax}
+% \cs{exp:w} \meta{expandable tokens} \cs{exp_end:} \\
+% \end{syntax}
+% Expands \meta{expandable-tokens} until reaching \cs{exp_end:} at
+% which point expansion stops.
+% The full expansion of \meta{expandable tokens} has to be empty.
+% If any token in \meta{expandable tokens} or any token generated by
+% expanding the tokens therein is not expandable the expansion will end
+% prematurely and as a result \cs{exp_end:} will be misinterpreted
+% later on.\footnotemark
+%
+% In typical use cases the \cs{exp_end:} is hidden somewhere
+% in the replacement text of \meta{expandable-tokens} rather than
+% being on the same expansion level than \cs{exp:w}, e.g., you may
+% see code such as
+%\begin{verbatim}
+% \exp:w \@@_case:NnTF #1 {#2} { } { }
+%\end{verbatim}
+% where somewhere during the expansion of |\@@_case:NnTF| the
+% \cs{exp_end:} gets generated.
+% \begin{texnote}
+% The current implementation uses \tn{romannumeral} hence ignores
+% space tokens and explicit signs |+| and |-| in the expansion of the
+% \meta{expandable tokens}, but this should not be relied upon.
+% \end{texnote}
+% \end{function}
+% \footnotetext{Due to the implementation you might get the character
+% in position 0 in the current font (typically \enquote{\texttt{`}})
+% in the output without any error message!}
+%
+% \begin{function}[added=2015-08-23, EXP, label = \exp_end_continue_f:w]
+% {
+% \exp:w ,
+% \exp_end_continue_f:w
+% }
+% \begin{syntax}
+% \cs{exp:w} \meta{expandable-tokens} \cs{exp_end_continue_f:w} \meta{further-tokens}
+% \end{syntax}
+% Expands \meta{expandable-tokens} until reaching \cs{exp_end_continue_f:w} at
+% which point expansion continues as an \texttt{f}-type expansion expanding
+% \meta{further-tokens} until an unexpandable token is encountered (or
+% the \texttt{f}-type expansion is explicitly terminated by
+% \cs{exp_stop_f:}). As with all \texttt{f}-type expansions a space ending
+% the expansion gets removed.
+%
+% The full expansion of \meta{expandable-tokens} has to be empty.
+% If any token in \meta{expandable-tokens} or any token generated by
+% expanding the tokens therein is not expandable the expansion will end
+% prematurely and as a result \cs{exp_end_continue_f:w} will be misinterpreted
+% later on.\footnotemark
+%
+%
+% In typical use cases \meta{expandable-tokens} contains no tokens at all,
+% e.g., you will see code such as
+%\begin{verbatim}
+% \exp_after:wN { \exp:w \exp_end_continue_f:w #2 }
+%\end{verbatim}
+% where the \cs{exp_after:wN} triggers an \texttt{f}-expansion of the tokens
+% in |#2|. For technical reasons this has to happen using two tokens
+% (if they would be hidden inside another command \cs{exp_after:wN}
+% would only expand the command but not trigger any additional
+% |f|-expansion).
+%
+% You might wonder why there are two different approaches available,
+% after all the effect of
+% \begin{quote}
+% \cs{exp:w} \meta{expandable-tokens} \cs{exp_end:}
+% \end{quote}
+% can be alternatively achieved through an \texttt{f}-type expansion by using
+% \cs{exp_stop_f:}, i.e.
+% \begin{quote}
+% \cs{exp:w} \cs{exp_end_continue_f:w} \meta{expandable-tokens} \cs{exp_stop_f:}
+% \end{quote}
+% The reason is simply that the first approach is slightly faster
+% (one less token to parse and less expansion internally)
+% so in places where such performance really matters and where we
+% want to explicitly stop the expansion at a defined point the first
+% form is preferable.
+% \end{function}
+% \footnotetext{In this particular case you may get a character into
+% the output as well as an error message.}
+%
+% \begin{function}[added=2015-08-23, EXP, label = \exp_end_continue_f:nw]
+% {
+% \exp:w ,
+% \exp_end_continue_f:nw
+% }
+% \begin{syntax}
+% \cs{exp:w} \meta{expandable-tokens} \cs{exp_end_continue_f:nw} \meta{further-tokens}
+% \end{syntax}
+% The difference to \cs{exp_end_continue_f:w} is that we first we pick
+% up an argument which is then returned to the input stream. If
+% \meta{further-tokens} starts with space tokens then these space
+% tokens are removed while searching for the argument. If it starts
+% with a brace group then the braces are removed. Thus such spaces or
+% braces will not terminate the \texttt{f}-type expansion.
+% \end{function}
+%
+% \section{Internal functions}
+%
+% \begin{function}{\::n, \::N, \::p, \::c, \::o, \::e, \::f, \::x, \::v, \::V, \:::}
+% \begin{syntax}
+% |\cs_new:Npn \exp_args:Ncof { \::c \::o \::f \::: }|
+% \end{syntax}
+% Internal forms for the base expansion types. These names do \emph{not}
+% conform to the general \LaTeX3 approach as this makes them more readily
+% visible in the log and so forth. They should not be used outside this module.
+% \end{function}
+%
+% \begin{function}
+% {\::o_unbraced, \::e_unbraced, \::f_unbraced, \::x_unbraced, \::v_unbraced, \::V_unbraced}
+% \begin{syntax}
+% |\cs_new:Npn \exp_last_unbraced:Nno { \::n \::o_unbraced \::: }|
+% \end{syntax}
+% Internal forms for the expansion types which leave the terminal argument
+% unbraced. These names do \emph{not}
+% conform to the general \LaTeX3 approach as this makes them more readily
+% visible in the log and so forth. They should not be used outside this module.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3expan} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=exp>
+% \end{macrocode}
+%
+% \begin{variable}{\l_@@_internal_tl}
+% The |\exp_| module has its private variable to temporarily store the
+% result of |x|-type argument expansion. This is done to avoid interference
+% with other functions using temporary variables.
+% \end{variable}
+%
+% \begin{macro}{\exp_after:wN}
+% \begin{macro}{\exp_not:N}
+% \begin{macro}{\exp_not:n}
+% These are defined in \pkg{l3basics}, as they are needed
+% \enquote{early}. This is just a reminder of that fact!
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{General expansion}
+%
+% In this section a general mechanism for defining functions that handle
+% arguments is defined. These general expansion functions are
+% expandable unless |x| is used. (Any version of |x| is going to have
+% to use one of the \LaTeX3 names for \cs{cs_set:Npx} at some
+% point, and so is never going to be expandable.)
+%
+% The definition of expansion functions with this technique happens
+% in section~\ref{sec:l3expan:gendef}.
+% In section~\ref{sec:l3expan:handtune} some common cases are coded by a more direct
+% method for efficiency, typically using calls to \cs{exp_after:wN}.
+%
+% \begin{variable}{\l_@@_internal_tl}
+% This scratch token list variable is defined in \pkg{l3basics}.
+% \end{variable}
+%
+% This code uses internal functions with names that start with |\::| to
+% perform the expansions. All macros are |long| since the tokens
+% undergoing expansion may be arbitrary user input.
+%
+% An argument manipulator |\::|\meta{Z} always has signature |#1\:::#2#3|
+% where |#1| holds the remaining argument manipulations to be performed,
+% \cs{:::} serves as an end marker for the list of manipulations, |#2|
+% is the carried over result of the previous expansion steps and |#3| is
+% the argument about to be processed.
+% One exception to this rule is \cs{::p}, which has to grab an argument
+% delimited by a left brace.
+%
+% \begin{macro}[EXP]{\@@_arg_next:nnn}
+% \begin{macro}[EXP]{\@@_arg_next:Nnn}
+% |#1| is the result of an expansion step, |#2| is the remaining
+% argument manipulations and |#3| is the current result of the
+% expansion chain. This auxiliary function moves |#1| back after
+% |#3| in the input stream and checks if any expansion is left to
+% be done by calling |#2|. In by far the most cases we need
+% to add a set of braces to the result of an argument manipulation
+% so it is more effective to do it directly here. Actually, so far
+% only the |c| of the final argument manipulation variants does not
+% require a set of braces.
+% \begin{macrocode}
+\cs_new:Npn \@@_arg_next:nnn #1#2#3 { #2 \::: { #3 {#1} } }
+\cs_new:Npn \@@_arg_next:Nnn #1#2#3 { #2 \::: { #3 #1 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\:::}
+% The end marker is just another name for the identity function.
+% \begin{macrocode}
+\cs_new:Npn \::: #1 {#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\::n}
+% This function is used to skip an argument that doesn't need to
+% be expanded.
+% \begin{macrocode}
+\cs_new:Npn \::n #1 \::: #2#3 { #1 \::: { #2 {#3} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\::N}
+% This function is used to skip an argument that consists of a
+% single token and doesn't need to be expanded.
+% \begin{macrocode}
+\cs_new:Npn \::N #1 \::: #2#3 { #1 \::: {#2#3} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\::p}
+% This function is used to skip an argument that is delimited by a
+% left brace and doesn't need to be expanded. It is not
+% wrapped in braces in the result.
+% \begin{macrocode}
+\cs_new:Npn \::p #1 \::: #2#3# { #1 \::: {#2#3} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\::c}
+% This function is used to skip an argument that is turned into
+% a control sequence without expansion.
+% \begin{macrocode}
+\cs_new:Npn \::c #1 \::: #2#3
+ { \exp_after:wN \@@_arg_next:Nnn \cs:w #3 \cs_end: {#1} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\::o}
+% This function is used to expand an argument once.
+% \begin{macrocode}
+\cs_new:Npn \::o #1 \::: #2#3
+ { \exp_after:wN \@@_arg_next:nnn \exp_after:wN {#3} {#1} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\::e}
+% With the \tn{expanded} primitive available, just expand.
+% \begin{macrocode}
+\cs_new:Npn \::e #1 \::: #2#3
+ { \tex_expanded:D { \exp_not:n { #1 \::: } { \exp_not:n {#2} {#3} } } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\::f}
+% \begin{macro}{\exp_stop_f:}
+% This function is used to expand a token list until the first
+% unexpandable token is found. This is achieved through \cs{exp:w}
+% \cs{exp_end_continue_f:w} that expands everything in its way
+% following it. This scanning procedure is terminated once the
+% expansion hits something non-expandable (if that is a space it is
+% removed). We introduce \cs{exp_stop_f:} to mark such an
+% end-of-expansion marker. For example, |f|-expanding
+% |\cs_set_eq:Nc \aaa { b \l_tmpa_tl b }| where |\l_tmpa_tl| contains
+% the characters |lur| gives |\tex_let:D \aaa = \blurb| which then
+% turns out to start with the non-expandable token |\tex_let:D|.
+% Since the expansion of \cs{exp:w} \cs{exp_end_continue_f:w} is
+% empty, we wind up with a fully expanded list, only \TeX{} has not
+% tried to execute any of the non-expandable tokens. This is what
+% differentiates this function from the |e| and |x| argument type.
+% \begin{macrocode}
+\cs_new:Npn \::f #1 \::: #2#3
+ {
+ \exp_after:wN \@@_arg_next:nnn
+ \exp_after:wN { \exp:w \exp_end_continue_f:w #3 }
+ {#1} {#2}
+ }
+\use:nn { \cs_new_eq:NN \exp_stop_f: } { ~ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\::x}
+% This function is used to expand an argument fully.
+% We build in the expansion of \cs{@@_arg_next:nnn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \::x #1 \::: #2#3
+ {
+ \cs_set_nopar:Npe \l_@@_internal_tl
+ { \exp_not:n { #1 \::: } { \exp_not:n {#2} {#3} } }
+ \l_@@_internal_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\::v}
+% \begin{macro}[EXP]{\::V}
+% These functions return the value of a register, i.e., one of
+% |tl|, |clist|, |int|, |skip|, |dim|, |muskip|, or built-in
+% \TeX{} register. The |V| version
+% expects a single token whereas |v| like |c| creates a csname from
+% its argument given in braces and then evaluates it as if it was a
+% |V|. The \cs{exp:w} sets off an expansion
+% similar to an |f|-type expansion, which we terminate using
+% \cs{exp_end:}. The argument is returned in braces.
+% \begin{macrocode}
+\cs_new:Npn \::V #1 \::: #2#3
+ {
+ \exp_after:wN \@@_arg_next:nnn
+ \exp_after:wN { \exp:w \@@_eval_register:N #3 }
+ {#1} {#2}
+}
+\cs_new:Npn \::v #1 \::: #2#3
+ {
+ \exp_after:wN \@@_arg_next:nnn
+ \exp_after:wN { \exp:w \@@_eval_register:c {#3} }
+ {#1} {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_eval_register:N, \@@_eval_register:c}
+% \begin{macro}[EXP]{\@@_eval_error_msg:w}
+% This function evaluates a register. Now a register might exist as
+% one of two things: A parameter-less macro or a built-in \TeX{}
+% register such as |\count|. For the \TeX{} registers we have to
+% utilize a \tn{the} whereas for the macros we merely have to
+% expand them once. The trick is to find out when to use
+% \tn{the} and when not to. What we want here is to find out
+% whether the token expands to something else when hit with
+% \cs{exp_after:wN}. The technique is to compare the meaning of the
+% token in question when it has been prefixed with \cs{exp_not:N}
+% and the token itself. If it is a macro, the prefixed
+% \cs{exp_not:N} temporarily turns it into the primitive
+% \cs{scan_stop:}.
+% \begin{macrocode}
+\cs_new:Npn \@@_eval_register:N #1
+ {
+ \exp_after:wN \if_meaning:w \exp_not:N #1 #1
+% \end{macrocode}
+% If the token was not a macro it may be a malformed variable from a
+% |c| expansion in which case it is equal to the primitive
+% \cs{scan_stop:}. In that case we throw an error. We could let \TeX{}
+% do it for us but that would result in the rather obscure
+% \begin{quote}
+% |! You can't use `\relax' after \the.|
+% \end{quote}
+% which while quite true doesn't give many hints as to what actually
+% went wrong. We provide something more sensible.
+% \begin{macrocode}
+ \if_meaning:w \scan_stop: #1
+ \@@_eval_error_msg:w
+ \fi:
+% \end{macrocode}
+% The next bit requires some explanation. The function must be
+% initiated by \cs{exp:w} and we want to
+% terminate this expansion chain by inserting the \cs{exp_end:}
+% token.
+% However, we have to expand the register |#1| before we do
+% that. If it is a \TeX{} register, we need to execute the sequence
+% |\exp_after:wN \exp_end: \tex_the:D #1| and if it is a macro we
+% need to execute |\exp_after:wN \exp_end: #1|. We therefore issue
+% the longer of the two sequences and if the register is a macro, we
+% remove the \cs{tex_the:D}.
+% \begin{macrocode}
+ \else:
+ \exp_after:wN \use_i_ii:nnn
+ \fi:
+ \exp_after:wN \exp_end: \tex_the:D #1
+ }
+\cs_new:Npn \@@_eval_register:c #1
+ { \exp_after:wN \@@_eval_register:N \cs:w #1 \cs_end: }
+% \end{macrocode}
+% Clean up nicely, then call the undefined control sequence. The
+% result is an error message looking like this:
+% \begin{verbatim}
+% ! Undefined control sequence.
+% <argument> \LaTeX3 error:
+% Erroneous variable used!
+% l.55 \tl_set:Nv \l_tmpa_tl {undefined_tl}
+% \end{verbatim}
+% \begin{macrocode}
+\cs_new:Npn \@@_eval_error_msg:w #1 \tex_the:D #2
+ {
+ \fi:
+ \fi:
+ \msg_expandable_error:nnn { kernel } { bad-variable } {#2}
+ \exp_end:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Hand-tuned definitions}
+% \label{sec:l3expan:handtune}
+%
+% One of the most important features of these functions is that they
+% are fully expandable.
+%
+% \begin{macro}[EXP]{\exp_args:Nc, \exp_args:cc}
+% In \pkg{l3basics}.
+% \end{macro}
+%
+% \begin{macro}[EXP]{\exp_args:NNc, \exp_args:Ncc, \exp_args:Nccc}
+% Here are the functions that turn their argument into csnames but are
+% expandable.
+% \begin{macrocode}
+\cs_new:Npn \exp_args:NNc #1#2#3
+ { \exp_after:wN #1 \exp_after:wN #2 \cs:w # 3\cs_end: }
+\cs_new:Npn \exp_args:Ncc #1#2#3
+ { \exp_after:wN #1 \cs:w #2 \exp_after:wN \cs_end: \cs:w #3 \cs_end: }
+\cs_new:Npn \exp_args:Nccc #1#2#3#4
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \cs:w #3 \exp_after:wN \cs_end:
+ \cs:w #4 \cs_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\exp_args:No}
+% \begin{macro}[EXP]{\exp_args:NNo}
+% \begin{macro}[EXP]{\exp_args:NNNo}
+% Those lovely runs of expansion!
+% \begin{macrocode}
+\cs_new:Npn \exp_args:No #1#2 { \exp_after:wN #1 \exp_after:wN {#2} }
+\cs_new:Npn \exp_args:NNo #1#2#3
+ { \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN {#3} }
+\cs_new:Npn \exp_args:NNNo #1#2#3#4
+ { \exp_after:wN #1 \exp_after:wN#2 \exp_after:wN #3 \exp_after:wN {#4} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\exp_args:Ne}
+% When the \tn{expanded} primitive is available, use it.
+% \begin{macrocode}
+\cs_new:Npn \exp_args:Ne #1#2
+ { \exp_after:wN #1 \tex_expanded:D { {#2} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\exp_args:Nf, \exp_args:NV, \exp_args:Nv}
+% \begin{macrocode}
+\cs_new:Npn \exp_args:Nf #1#2
+ { \exp_after:wN #1 \exp_after:wN { \exp:w \exp_end_continue_f:w #2 } }
+\cs_new:Npn \exp_args:Nv #1#2
+ {
+ \exp_after:wN #1 \exp_after:wN
+ { \exp:w \@@_eval_register:c {#2} }
+ }
+\cs_new:Npn \exp_args:NV #1#2
+ {
+ \exp_after:wN #1 \exp_after:wN
+ { \exp:w \@@_eval_register:N #2 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \exp_args:NNV, \exp_args:NNv, \exp_args:NNe, \exp_args:NNf,
+% \exp_args:Nco, \exp_args:NcV, \exp_args:Ncv, \exp_args:Ncf,
+% \exp_args:NVV,
+% }
+% Some more hand-tuned function with three arguments.
+% If we forced that an |o| argument always has braces,
+% we could implement \cs{exp_args:Nco} with less tokens
+% and only two arguments.
+% \begin{macrocode}
+\cs_new:Npn \exp_args:NNV #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN { \exp:w \@@_eval_register:N #3 }
+ }
+\cs_new:Npn \exp_args:NNv #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN { \exp:w \@@_eval_register:c {#3} }
+ }
+\cs_new:Npn \exp_args:NNe #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \tex_expanded:D { {#3} }
+ }
+\cs_new:Npn \exp_args:NNf #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN { \exp:w \exp_end_continue_f:w #3 }
+ }
+\cs_new:Npn \exp_args:Nco #1#2#3
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp_after:wN {#3}
+ }
+\cs_new:Npn \exp_args:NcV #1#2#3
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp_after:wN { \exp:w \@@_eval_register:N #3 }
+ }
+\cs_new:Npn \exp_args:Ncv #1#2#3
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp_after:wN { \exp:w \@@_eval_register:c {#3} }
+ }
+\cs_new:Npn \exp_args:Ncf #1#2#3
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp_after:wN { \exp:w \exp_end_continue_f:w #3 }
+ }
+\cs_new:Npn \exp_args:NVV #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN { \exp:w \exp_after:wN
+ \@@_eval_register:N \exp_after:wN #2 \exp_after:wN }
+ \exp_after:wN { \exp:w \@@_eval_register:N #3 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \exp_args:NNNV, \exp_args:NNNv, \exp_args:NNNe,
+% \exp_args:NcNc, \exp_args:NcNo,
+% \exp_args:Ncco,
+% }
+% A few more that we can hand-tune.
+% \begin{macrocode}
+\cs_new:Npn \exp_args:NNNV #1#2#3#4
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \exp_after:wN { \exp:w \@@_eval_register:N #4 }
+ }
+\cs_new:Npn \exp_args:NNNv #1#2#3#4
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \exp_after:wN { \exp:w \@@_eval_register:c {#4} }
+ }
+\cs_new:Npn \exp_args:NNNe #1#2#3#4
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \tex_expanded:D { {#4} }
+ }
+\cs_new:Npn \exp_args:NcNc #1#2#3#4
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp_after:wN #3
+ \cs:w #4 \cs_end:
+ }
+\cs_new:Npn \exp_args:NcNo #1#2#3#4
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp_after:wN #3
+ \exp_after:wN {#4}
+ }
+\cs_new:Npn \exp_args:Ncco #1#2#3#4
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \cs:w #3 \exp_after:wN \cs_end:
+ \exp_after:wN {#4}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\exp_args:Nx}
+% \begin{macrocode}
+\cs_new_protected:Npn \exp_args:Nx #1#2
+ { \use:x { \exp_not:N #1 {#2} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Last-unbraced versions}
+%
+% \begin{macro}[EXP]{\@@_arg_last_unbraced:nn}
+% \begin{macro}[EXP]{\::o_unbraced}
+% \begin{macro}[EXP]{\::V_unbraced}
+% \begin{macro}[EXP]{\::v_unbraced}
+% \begin{macro}[EXP]{\::e_unbraced}
+% \begin{macro}[EXP]{\::f_unbraced}
+% \begin{macro}[EXP]{\::x_unbraced}
+% There are a few places where the last argument needs to be available
+% unbraced. First some helper macros.
+% \begin{macrocode}
+\cs_new:Npn \@@_arg_last_unbraced:nn #1#2 { #2#1 }
+\cs_new:Npn \::o_unbraced \::: #1#2
+ { \exp_after:wN \@@_arg_last_unbraced:nn \exp_after:wN {#2} {#1} }
+\cs_new:Npn \::V_unbraced \::: #1#2
+ {
+ \exp_after:wN \@@_arg_last_unbraced:nn
+ \exp_after:wN { \exp:w \@@_eval_register:N #2 } {#1}
+ }
+\cs_new:Npn \::v_unbraced \::: #1#2
+ {
+ \exp_after:wN \@@_arg_last_unbraced:nn
+ \exp_after:wN { \exp:w \@@_eval_register:c {#2} } {#1}
+ }
+\cs_new:Npn \::e_unbraced \::: #1#2
+ { \tex_expanded:D { \exp_not:n {#1} #2 } }
+\cs_new:Npn \::f_unbraced \::: #1#2
+ {
+ \exp_after:wN \@@_arg_last_unbraced:nn
+ \exp_after:wN { \exp:w \exp_end_continue_f:w #2 } {#1}
+ }
+\cs_new_protected:Npn \::x_unbraced \::: #1#2
+ {
+ \cs_set_nopar:Npe \l_@@_internal_tl { \exp_not:n {#1} #2 }
+ \l_@@_internal_tl
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \exp_last_unbraced:No,
+% \exp_last_unbraced:NV,
+% \exp_last_unbraced:Nv,
+% \exp_last_unbraced:Ne,
+% \exp_last_unbraced:Nf,
+% \exp_last_unbraced:NNo,
+% \exp_last_unbraced:NNV,
+% \exp_last_unbraced:NNf,
+% \exp_last_unbraced:Nco,
+% \exp_last_unbraced:NcV,
+% \exp_last_unbraced:NNNo,
+% \exp_last_unbraced:NNNV,
+% \exp_last_unbraced:NNNf,
+% \exp_last_unbraced:Nno,
+% \exp_last_unbraced:Nnf,
+% \exp_last_unbraced:Noo,
+% \exp_last_unbraced:Nfo,
+% \exp_last_unbraced:NnNo,
+% \exp_last_unbraced:NNNNo,
+% \exp_last_unbraced:NNNNf,
+% }
+% \begin{macro}{\exp_last_unbraced:Nx}
+% Now the business end: most of these are hand-tuned for speed, but the
+% general system is in place.
+% \begin{macrocode}
+\cs_new:Npn \exp_last_unbraced:No #1#2 { \exp_after:wN #1 #2 }
+\cs_new:Npn \exp_last_unbraced:NV #1#2
+ { \exp_after:wN #1 \exp:w \@@_eval_register:N #2 }
+\cs_new:Npn \exp_last_unbraced:Nv #1#2
+ { \exp_after:wN #1 \exp:w \@@_eval_register:c {#2} }
+\cs_new:Npn \exp_last_unbraced:Ne #1#2
+ { \exp_after:wN #1 \tex_expanded:D {#2} }
+\cs_new:Npn \exp_last_unbraced:Nf #1#2
+ { \exp_after:wN #1 \exp:w \exp_end_continue_f:w #2 }
+\cs_new:Npn \exp_last_unbraced:NNo #1#2#3
+ { \exp_after:wN #1 \exp_after:wN #2 #3 }
+\cs_new:Npn \exp_last_unbraced:NNV #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp:w \@@_eval_register:N #3
+ }
+\cs_new:Npn \exp_last_unbraced:NNf #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp:w \exp_end_continue_f:w #3
+ }
+\cs_new:Npn \exp_last_unbraced:Nco #1#2#3
+ { \exp_after:wN #1 \cs:w #2 \exp_after:wN \cs_end: #3 }
+\cs_new:Npn \exp_last_unbraced:NcV #1#2#3
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp:w \@@_eval_register:N #3
+ }
+\cs_new:Npn \exp_last_unbraced:NNNo #1#2#3#4
+ { \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN #3 #4 }
+\cs_new:Npn \exp_last_unbraced:NNNV #1#2#3#4
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \exp:w \@@_eval_register:N #4
+ }
+\cs_new:Npn \exp_last_unbraced:NNNf #1#2#3#4
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \exp:w \exp_end_continue_f:w #4
+ }
+\cs_new:Npn \exp_last_unbraced:Nno { \::n \::o_unbraced \::: }
+\cs_new:Npn \exp_last_unbraced:Nnf { \::n \::f_unbraced \::: }
+\cs_new:Npn \exp_last_unbraced:Noo { \::o \::o_unbraced \::: }
+\cs_new:Npn \exp_last_unbraced:Nfo { \::f \::o_unbraced \::: }
+\cs_new:Npn \exp_last_unbraced:NnNo { \::n \::N \::o_unbraced \::: }
+\cs_new:Npn \exp_last_unbraced:NNNNo #1#2#3#4#5
+ { \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN #3 \exp_after:wN #4 #5 }
+\cs_new:Npn \exp_last_unbraced:NNNNf #1#2#3#4#5
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \exp_after:wN #4
+ \exp:w \exp_end_continue_f:w #5
+ }
+\cs_new_protected:Npn \exp_last_unbraced:Nx { \::x_unbraced \::: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\exp_last_two_unbraced:Noo}
+% \begin{macro}[EXP]{\@@_last_two_unbraced:noN}
+% If |#2| is a single token then this can be implemented as
+% \begin{verbatim}
+% \cs_new:Npn \exp_last_two_unbraced:Noo #1 #2 #3
+% { \exp_after:wN \exp_after:wN \exp_after:wN #1 \exp_after:wN #2 #3 }
+% \end{verbatim}
+% However, for robustness this is not suitable. Instead, a bit of a
+% shuffle is used to ensure that |#2| can be multiple tokens.
+% \begin{macrocode}
+\cs_new:Npn \exp_last_two_unbraced:Noo #1#2#3
+ { \exp_after:wN \@@_last_two_unbraced:noN \exp_after:wN {#3} {#2} #1 }
+\cs_new:Npn \@@_last_two_unbraced:noN #1#2#3
+ { \exp_after:wN #3 #2 #1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Preventing expansion}
+%
+% \begin{macro}{\__kernel_exp_not:w}
+% At the kernel level, we need the primitive behaviour to allow expansion
+% \emph{before} the brace group.
+% \begin{macrocode}
+\cs_new_eq:NN \__kernel_exp_not:w \tex_unexpanded:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\exp_not:c}
+% \begin{macro}[EXP]{\exp_not:o}
+% \begin{macro}[EXP]{\exp_not:e}
+% \begin{macro}[EXP]{\exp_not:f}
+% \begin{macro}[EXP]{\exp_not:V}
+% \begin{macro}[EXP]{\exp_not:v}
+% All these except \cs{exp_not:c} call the kernel-internal
+% \cs{__kernel_exp_not:w} namely \cs{tex_unexpanded:D}.
+% \begin{macrocode}
+\cs_new:Npn \exp_not:c #1 { \exp_after:wN \exp_not:N \cs:w #1 \cs_end: }
+\cs_new:Npn \exp_not:o #1 { \__kernel_exp_not:w \exp_after:wN {#1} }
+\cs_new:Npn \exp_not:e #1
+ { \__kernel_exp_not:w \tex_expanded:D { {#1} } }
+\cs_new:Npn \exp_not:f #1
+ { \__kernel_exp_not:w \exp_after:wN { \exp:w \exp_end_continue_f:w #1 } }
+\cs_new:Npn \exp_not:V #1
+ {
+ \__kernel_exp_not:w \exp_after:wN
+ { \exp:w \@@_eval_register:N #1 }
+ }
+\cs_new:Npn \exp_not:v #1
+ {
+ \__kernel_exp_not:w \exp_after:wN
+ { \exp:w \@@_eval_register:c {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Controlled expansion}
+%
+% \begin{macro}{\exp:w}
+% \begin{macro}{\exp_end:}
+% \begin{macro}{\exp_end_continue_f:w}
+% \begin{macro}{\exp_end_continue_f:nw}
+% To trigger a sequence of \enquote{arbitrarily} many expansions we
+% need a method to invoke \TeX's expansion mechanism in such a way
+% that (a) we are able to stop it in a controlled manner and (b) the
+% result of what triggered the expansion in the first place is null,
+% i.e.\@, that we do not get any unwanted side effects. There aren't
+% that many possibilities in \TeX{}; in fact the one explained below
+% might well be the only one (as normally the result of expansion is
+% not null).
+%
+% The trick here is to make use of the fact that
+% \cs{tex_romannumeral:D} expands the tokens following it when looking
+% for a number and that its expansion is null if that number turns out
+% to be zero or negative. So we use that to start the expansion
+% sequence: \cs{exp:w} is set equal to \cs{tex_romannumeral:D} in
+% \pkg{l3basics}. To stop the expansion sequence in a controlled way
+% all we need to provide is a constant integer zero as part of
+% expanded tokens. As this is an integer constant it immediately stops
+% \cs{tex_romannumeral:D}'s search for a number. Again, the
+% definition of \cs{exp_end:} as the integer constant zero is in
+% \pkg{l3basics}. (Note that according to our specification all
+% tokens we expand initiated by \cs{exp:w} are supposed to be
+% expandable (as well as their replacement text in the expansion) so
+% we will not encounter a \enquote{number} that actually result in a
+% roman numeral being generated. Or if we do then the programmer made
+% a mistake.)
+%
+% If on the other hand we want to stop the initial expansion sequence
+% but continue with an \texttt{f}-type expansion we provide the
+% alphabetic constant |`^^@| that also represents |0| but this time
+% \TeX's syntax for a \meta{number} continues searching for an
+% optional space (and it continues expansion doing that) --- see
+% \TeX{}book page~269 for details.
+% \begin{macrocode}
+\group_begin:
+ \tex_catcode:D `\^^@ = 13
+ \cs_new_protected:Npn \exp_end_continue_f:w { `^^@ }
+% \end{macrocode}
+% If the above definition ever appears outside its proper context
+% the active character |^^@| will be executed so we turn this into an
+% error. The test for existence covers the (unlikely) case that some
+% other code has already defined |^^@|: this is true for example for
+% \texttt{xmltex.tex}.
+% \begin{macrocode}
+ \if_cs_exist:N ^^@
+ \else:
+ \cs_new:Npn ^^@
+ { \msg_expandable_error:nn { kernel } { bad-exp-end-f } }
+ \fi:
+% \end{macrocode}
+% The same but grabbing an argument to remove spaces and braces.
+% \begin{macrocode}
+ \cs_new:Npn \exp_end_continue_f:nw #1 { `^^@ #1 }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Defining function variants}
+%
+% \begin{macrocode}
+%<@@=cs>
+% \end{macrocode}
+%
+% \begin{variable}{\s_@@_mark,\s_@@_stop}
+% Internal scan marks. No \pkg{l3quark} yet, so do things by hand.
+% \begin{macrocode}
+\cs_new_eq:NN \s_@@_mark \scan_stop:
+\cs_new_eq:NN \s_@@_stop \scan_stop:
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\q_@@_recursion_stop}
+% Internal recursion quarks. No \pkg{l3quark} yet, so do things by hand.
+% \begin{macrocode}
+\cs_new:Npn \q_@@_recursion_stop { \q_@@_recursion_stop }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{
+% \@@_use_none_delimit_by_s_stop:w,
+% \@@_use_i_delimit_by_s_stop:nw,
+% \@@_use_none_delimit_by_q_recursion_stop:w
+% }
+% Internal scan marks.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_none_delimit_by_s_stop:w #1 \s_@@_stop { }
+\cs_new:Npn \@@_use_i_delimit_by_s_stop:nw #1 #2 \s_@@_stop {#1}
+\cs_new:Npn \@@_use_none_delimit_by_q_recursion_stop:w
+ #1 \q_@@_recursion_stop { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cs_generate_variant:Nn, \cs_generate_variant:cn}
+% \begin{arguments}
+% \item Base form of a function; \emph{e.g.},~\cs{tl_set:Nn}
+% \item One or more variant argument specifiers; e.g., |{Nx,c,cx}|
+% \end{arguments}
+% After making sure that the base form exists, test whether it is
+% protected or not and define \cs{@@_tmp:w} as either
+% \cs{cs_new:Npe} or \cs{cs_new_protected:Npe}, which is
+% then used to define all the variants (except those involving
+% \texttt{x}-expansion, always protected). Split up the original base
+% function only once, to grab its name and signature. Then we wish to
+% iterate through the comma list of variant argument specifiers, which
+% we first convert to a string: the reason is explained later.
+% \begin{macrocode}
+\cs_new_protected:Npn \cs_generate_variant:Nn #1#2
+ {
+ \@@_generate_variant:N #1
+ \use:e
+ {
+ \@@_generate_variant:nnNN
+ \cs_split_function:N #1
+ \exp_not:N #1
+ \tl_to_str:n {#2} ,
+ \exp_not:N \scan_stop: ,
+ \exp_not:N \q_@@_recursion_stop
+ }
+ }
+\cs_new_protected:Npn \cs_generate_variant:cn
+ { \exp_args:Nc \cs_generate_variant:Nn }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_generate_variant:N}
+% \begin{macro}{\@@_generate_variant:ww, \@@_generate_variant:wwNw}
+% The goal here is to pick up protected parent functions. There are
+% four cases: the parent function can be a primitive or a macro, and
+% can be expandable or not. For non-expandable primitives, all
+% variants should be protected; skipping the \cs{else:} branch is safe
+% because non-expandable primitives cannot be \TeX{} conditionals.
+%
+% The other case where variants should be protected is when the parent
+% function is a protected macro: then |protected| appears in the
+% meaning before the first occurrence of |macro|. The |ww| auxiliary
+% removes everything in the meaning string after the first |ma|. We
+% use |ma| rather than the full |macro| because the meaning of the
+% \tn{firstmark} primitive (and four others) can contain an arbitrary
+% string after a leading |firstmark:|. Then, look for |pr| in the
+% part we extracted: no need to look for anything longer: the only
+% strings we can have are an empty string, \verb*|\long |,
+% \verb*|\protected |, \verb*|\protected\long |, |\first|, |\top|,
+% |\bot|, |\splittop|, or |\splitbot|, with |\| replaced by the
+% appropriate escape character. If |pr| appears in the part before
+% |ma|, the first \cs{s_@@_mark} is taken as an argument of the |wwNw|
+% auxiliary, and |#3| is \cs{cs_new_protected:Npe}, otherwise it
+% is \cs{cs_new:Npe}.
+% \begin{macrocode}
+\cs_new_protected:Npe \@@_generate_variant:N #1
+ {
+ \exp_not:N \exp_after:wN \exp_not:N \if_meaning:w
+ \exp_not:N \exp_not:N #1 #1
+ \cs_set_eq:NN \exp_not:N \@@_tmp:w \cs_new_protected:Npe
+ \exp_not:N \else:
+ \exp_not:N \exp_after:wN \exp_not:N \@@_generate_variant:ww
+ \exp_not:N \token_to_meaning:N #1 \tl_to_str:n { ma }
+ \s_@@_mark
+ \s_@@_mark \cs_new_protected:Npe
+ \tl_to_str:n { pr }
+ \s_@@_mark \cs_new:Npe
+ \s_@@_stop
+ \exp_not:N \fi:
+ }
+\exp_last_unbraced:NNNNo
+ \cs_new_protected:Npn \@@_generate_variant:ww
+ #1 { \tl_to_str:n { ma } } #2 \s_@@_mark
+ { \@@_generate_variant:wwNw #1 }
+\exp_last_unbraced:NNNNo
+ \cs_new_protected:Npn \@@_generate_variant:wwNw
+ #1 { \tl_to_str:n { pr } } #2 \s_@@_mark #3 #4 \s_@@_stop
+ { \cs_set_eq:NN \@@_tmp:w #3 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_generate_variant:nnNN}
+% \begin{arguments}
+% \item Base name.
+% \item Base signature.
+% \item Boolean.
+% \item Base function.
+% \end{arguments}
+% If the boolean is \cs{c_false_bool}, the base function has no colon
+% and we abort with an error; otherwise, set off a loop through the
+% desired variant forms. The original function is retained as |#4| for
+% efficiency.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_generate_variant:nnNN #1#2#3#4
+ {
+ \if_meaning:w \c_false_bool #3
+ \msg_error:nne { kernel } { missing-colon }
+ { \token_to_str:c {#1} }
+ \exp_after:wN \@@_use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ \@@_generate_variant:Nnnw #4 {#1}{#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_generate_variant:Nnnw}
+% \begin{arguments}
+% \item Base function.
+% \item Base name.
+% \item Base signature.
+% \item Beginning of variant signature.
+% \end{arguments}
+% First check whether to terminate the loop over variant forms. Then,
+% for each variant form, construct a new function name using the
+% original base name, the variant signature consisting of $l$ letters
+% and the last $k-l$ letters of the base signature (of length $k$).
+% For example, for a base function \cs{prop_put:Nnn} which needs a
+% |cV| variant form, we want the new signature to be |cVn|.
+%
+% There are further subtleties:
+% \begin{itemize}
+% \item In \cs{cs_generate_variant:Nn} |\foo:nnTF| |{xxTF}|, we must define
+% |\foo:xxTF| using |\exp_args:Nxx|,
+% rather than a hypothetical |\exp_args:NxxTF|. Thus, we wish to
+% trim a common trailing part from the base signature and the
+% variant signature.
+% \item In \cs{cs_generate_variant:Nn} |\foo:on| |{ox}|, the
+% function |\foo:ox| must be defined using |\exp_args:Nnx|, not
+% |\exp_args:Nox|, to avoid double |o| expansion.
+% \item Lastly, \cs{cs_generate_variant:Nn} |\foo:on| |{xn}| must
+% trigger an error, because we do not have a means to replace
+% |o|-expansion by |x|-expansion.
+% More generally, we can only convert |N| to |c|, or convert |n|
+% to |V|, |v|, |o|, |e|, |f|, or |x|.
+% \end{itemize}
+% All this boils down to a few rules. Only |n| and |N|-type
+% arguments can be replaced by \cs{cs_generate_variant:Nn}. Other
+% argument types are allowed to be passed unchanged from the base
+% form to the variant: in the process they are changed to |n|
+% except for |N| and |p|-type arguments. A common trailing
+% part is ignored.
+%
+% We compare the base and variant signatures one character at a time
+% within |e|-expansion. The result is given to
+% \cs{@@_generate_variant:wwNN} (defined later) in the form
+% \meta{processed variant signature} \cs{s_@@_mark} \meta{errors}
+% \cs{s_@@_stop} \meta{base function} \meta{new function}. If all went
+% well, \meta{errors} is empty; otherwise, it is a kernel error
+% message and some clean-up code.
+%
+% Note the space after |#3| and after the following brace group.
+% Those are ignored by \TeX{} when fetching the last argument for
+% \cs{@@_generate_variant_loop:nNwN}, but can be used as a delimiter
+% for \cs{@@_generate_variant_loop_end:nwwwNNnn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_generate_variant:Nnnw #1#2#3#4 ,
+ {
+ \if_meaning:w \scan_stop: #4
+ \exp_after:wN \@@_use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ \use:e
+ {
+ \exp_not:N \@@_generate_variant:wwNN
+ \@@_generate_variant_loop:nNwN { }
+ #4
+ \@@_generate_variant_loop_end:nwwwNNnn
+ \s_@@_mark
+ #3 ~
+ { ~ { } \fi: \@@_generate_variant_loop_long:wNNnn } ~
+ { }
+ \s_@@_stop
+ \exp_not:N #1 {#2} {#4}
+ }
+ \@@_generate_variant:Nnnw #1 {#2} {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {
+% \@@_generate_variant_loop:nNwN,
+% \@@_generate_variant_loop_base:N,
+% \@@_generate_variant_loop_same:w,
+% \@@_generate_variant_loop_end:nwwwNNnn,
+% \@@_generate_variant_loop_long:wNNnn,
+% \@@_generate_variant_loop_invalid:NNwNNnn,
+% \@@_generate_variant_loop_special:NNwNNnn
+% }
+% \begin{arguments}
+% \item Last few consecutive letters common between the base and
+% variant (more precisely, \cs{@@_generate_variant_same:N}
+% \meta{letter} for each letter).
+% \item Next variant letter.
+% \item Remainder of variant form.
+% \item Next base letter.
+% \end{arguments}
+% The first argument is populated by
+% \cs{@@_generate_variant_loop_same:w} when a variant letter and a
+% base letter match. It is flushed into the input stream whenever the
+% two letters are different: if the loop ends before, the argument is
+% dropped, which means that trailing common letters are ignored.
+%
+% The case where the two letters are different is only allowed if the
+% base is |N| and the variant is |c|, or when the base is |n| and the
+% variant is |V|, |v|, |o|, |e|, |f|, or |x|. Otherwise, call
+% \cs{@@_generate_variant_loop_invalid:NNwNNnn} to remove the end of
+% the loop, get arguments at the end of the loop, and place an
+% appropriate error message as a second argument of
+% \cs{@@_generate_variant:wwNN}. If the letters are distinct and the
+% base letter is indeed |n| or |N|, leave in the input stream whatever
+% argument |#1| was collected, and the next variant letter |#2|, then
+% loop by calling \cs{@@_generate_variant_loop:nNwN}.
+%
+% The loop can stop in three ways.
+% \begin{itemize}
+% \item If the end of the variant form is encountered first, |#2| is
+% \cs{@@_generate_variant_loop_end:nwwwNNnn} (expanded by the
+% conditional \cs{if:w}), which inserts some tokens to end the
+% conditional; grabs the \meta{base name} as |#7|, the
+% \meta{variant signature} |#8|, the \meta{next base letter} |#1|
+% and the part |#3| of the base signature that wasn't read yet;
+% and combines those into the \meta{new function} to be defined.
+% \item If the end of the base form is encountered first, |#4| is
+% |~{}\fi:| which ends the conditional (with an empty expansion),
+% followed by \cs{@@_generate_variant_loop_long:wNNnn}, which
+% places an error as the second argument of
+% \cs{@@_generate_variant:wwNN}.
+% \item The loop can be interrupted early if the requested expansion
+% is unavailable, namely when the variant and base letters differ
+% and the base is not the right one (|n| or |N| to support the
+% variant). In that case too an error is placed as the second
+% argument of \cs{@@_generate_variant:wwNN}.
+% \end{itemize}
+% Note that if the variant form has the same length as the base form,
+% |#2| is as described in the first point, and |#4| as described in
+% the second point above. The \cs{@@_generate_variant_loop_end:nwwwNNnn}
+% breaking function takes the empty brace group in |#4| as its first
+% argument: this empty brace group produces the correct signature for
+% the full variant.
+% \begin{macrocode}
+\cs_new:Npn \@@_generate_variant_loop:nNwN #1#2#3 \s_@@_mark #4
+ {
+ \if:w #2 #4
+ \exp_after:wN \@@_generate_variant_loop_same:w
+ \else:
+ \if:w #4 \@@_generate_variant_loop_base:N #2 \else:
+ \if:w 0
+ \if:w N #4 \else: \if:w n #4 \else: 1 \fi: \fi:
+ \if:w \scan_stop: \@@_generate_variant_loop_base:N #2 1 \fi:
+ 0
+ \@@_generate_variant_loop_special:NNwNNnn #4#2
+ \else:
+ \@@_generate_variant_loop_invalid:NNwNNnn #4#2
+ \fi:
+ \fi:
+ \fi:
+ #1
+ \prg_do_nothing:
+ #2
+ \@@_generate_variant_loop:nNwN { } #3 \s_@@_mark
+ }
+\cs_new:Npn \@@_generate_variant_loop_base:N #1
+ {
+ \if:w c #1 N \else:
+ \if:w o #1 n \else:
+ \if:w V #1 n \else:
+ \if:w v #1 n \else:
+ \if:w f #1 n \else:
+ \if:w e #1 n \else:
+ \if:w x #1 n \else:
+ \if:w n #1 n \else:
+ \if:w N #1 N \else:
+ \scan_stop:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ }
+\cs_new:Npn \@@_generate_variant_loop_same:w
+ #1 \prg_do_nothing: #2#3#4
+ { #3 { #1 \@@_generate_variant_same:N #2 } }
+\cs_new:Npn \@@_generate_variant_loop_end:nwwwNNnn
+ #1#2 \s_@@_mark #3 ~ #4 \s_@@_stop #5#6#7#8
+ {
+ \scan_stop: \scan_stop: \fi:
+ \s_@@_mark \s_@@_stop
+ \exp_not:N #6
+ \exp_not:c { #7 : #8 #1 #3 }
+ }
+\cs_new:Npn \@@_generate_variant_loop_long:wNNnn #1 \s_@@_stop #2#3#4#5
+ {
+ \exp_not:n
+ {
+ \s_@@_mark
+ \msg_error:nnee { kernel } { variant-too-long }
+ {#5} { \token_to_str:N #3 }
+ \use_none:nnn
+ \s_@@_stop
+ #3
+ #3
+ }
+ }
+\cs_new:Npn \@@_generate_variant_loop_invalid:NNwNNnn
+ #1#2 \fi: \fi: \fi: #3 \s_@@_stop #4#5#6#7
+ {
+ \fi: \fi: \fi:
+ \exp_not:n
+ {
+ \s_@@_mark
+ \msg_error:nneeee { kernel } { invalid-variant }
+ {#7} { \token_to_str:N #5 } {#1} {#2}
+ \use_none:nnn
+ \s_@@_stop
+ #5
+ #5
+ }
+ }
+\cs_new:Npn \@@_generate_variant_loop_special:NNwNNnn
+ #1#2#3 \s_@@_stop #4#5#6#7
+ {
+ #3 \s_@@_stop #4 #5 {#6} {#7}
+ \exp_not:n
+ {
+ \msg_error:nneeee
+ { kernel } { deprecated-variant }
+ {#7} { \token_to_str:N #5 } {#1} {#2}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_generate_variant_same:N}
+% When the base and variant letters are identical, don't do any
+% expansion. For most argument types, we can use the |n|-type
+% no-expansion, but the |N| and |p| types require a slightly different
+% behaviour with respect to braces. For |V|-type this function could
+% output |N| to avoid adding useless braces but that is not a problem.
+% \begin{macrocode}
+\cs_new:Npn \@@_generate_variant_same:N #1
+ {
+ \if:w N #1 #1 \else:
+ \if:w p #1 #1 \else:
+ \token_to_str:N n
+ \if:w n #1 \else:
+ \@@_generate_variant_loop_special:NNwNNnn #1#1
+ \fi:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_generate_variant:wwNN}
+% If the variant form has already been defined, log its existence
+% (provided \texttt{log-functions} is active).
+% Otherwise, make sure that the |\exp_args:N #3| form is defined, and
+% if it contains |x|, change \cs{@@_tmp:w} locally to
+% \cs{cs_new_protected:Npe}. Then define the variant by
+% combining the |\exp_args:N #3| variant and the base function.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_generate_variant:wwNN
+ #1 \s_@@_mark #2 \s_@@_stop #3#4
+ {
+ #2
+ \cs_if_free:NT #4
+ {
+ \group_begin:
+ \@@_generate_internal_variant:n {#1}
+ \@@_tmp:w #4 { \exp_not:c { exp_args:N #1 } \exp_not:N #3 }
+ \group_end:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_generate_internal_variant:n}
+% \begin{macro}[rEXP]{\@@_generate_internal_variant_loop:n}
+% First test for the presence of |x| (this is where working with
+% strings makes our lives easier), as the result should be protected,
+% and the next variant to be defined using that internal variant
+% should be protected (done by setting \cs{@@_tmp:w}). Then call
+% \cs{@@_generate_internal_variant:NNn} with arguments
+% \cs{cs_new_protected:cpn} \cs{use:x} (for protected) or
+% \cs{cs_new:cpn} \cs{tex_expanded:D} (expandable) and the signature. If |p|
+% appears in the signature, or if the function to be defined is
+% expandable and the primitive \tn{expanded} is not available, or if there
+% are more than $8$ arguments, call
+% some fall-back code that just puts the appropriate |\::| commands.
+% Otherwise, call \cs{@@_generate_internal_one_go:NNn} to construct
+% the \cs[no-index]{exp_args:N\dots} function as a macro taking up to
+% $9$~arguments and expanding them using \cs{use:x} or \cs{tex_expanded:D}.
+% \begin{macrocode}
+\cs_new_protected:Npe \@@_generate_internal_variant:n #1
+ {
+ \exp_not:N \@@_generate_internal_variant:wwnNwn
+ #1 \s_@@_mark
+ { \cs_set_eq:NN \exp_not:N \@@_tmp:w \cs_new_protected:Npe }
+ \cs_new_protected:cpn
+ \use:x
+ \token_to_str:N x \s_@@_mark
+ { }
+ \cs_new:cpn
+ \exp_not:N \tex_expanded:D
+ \s_@@_stop
+ {#1}
+ }
+\exp_last_unbraced:NNNNo
+ \cs_new_protected:Npn \@@_generate_internal_variant:wwnNwn #1
+ { \token_to_str:N x } #2 \s_@@_mark #3#4#5#6 \s_@@_stop #7
+ {
+ #3
+ \cs_if_free:cT { exp_args:N #7 }
+ { \@@_generate_internal_variant:NNn #4 #5 {#7} }
+ }
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \cs_new_protected:Npn \@@_generate_internal_variant:NNn ##1##2##3
+ {
+ \if_catcode:w X \use_none:nnnnnnnn ##3
+ \prg_do_nothing: \prg_do_nothing: \prg_do_nothing:
+ \prg_do_nothing: \prg_do_nothing: \prg_do_nothing:
+ \prg_do_nothing: \prg_do_nothing: X
+ \exp_after:wN \@@_generate_internal_test:Nw \exp_after:wN ##2
+ \else:
+ \exp_after:wN \@@_generate_internal_test_aux:w \exp_after:wN #1
+ \fi:
+ ##3
+ \s_@@_mark
+ {
+ \use:e
+ {
+ ##1 { exp_args:N ##3 }
+ { \@@_generate_internal_variant_loop:n ##3 { : \use_i:nn } }
+ }
+ }
+ #1
+ \s_@@_mark
+ { \exp_not:n { \@@_generate_internal_one_go:NNn ##1 ##2 {##3} } }
+ \s_@@_stop
+ }
+ \cs_new_protected:Npn \@@_generate_internal_test_aux:w
+ ##1 #1 ##2 \s_@@_mark ##3 ##4 \s_@@_stop {##3}
+ \cs_new_eq:NN \@@_generate_internal_test:Nw
+ \@@_generate_internal_test_aux:w
+ }
+\exp_args:No \@@_tmp:w { \token_to_str:N p }
+\cs_new_protected:Npn \@@_generate_internal_one_go:NNn #1#2#3
+ {
+ \@@_generate_internal_loop:nwnnw
+ { \exp_not:N ##1 } 1 . { } { }
+ #3 { ? \@@_generate_internal_end:w } X ;
+ 23456789 { ? \@@_generate_internal_long:w } ;
+ #1 #2 {#3}
+ }
+\cs_new_protected:Npn \@@_generate_internal_loop:nwnnw #1#2 . #3#4#5#6 ; #7
+ {
+ \use_none:n #5
+ \use_none:n #7
+ \cs_if_exist_use:cF { @@_generate_internal_#5:NN }
+ { \@@_generate_internal_other:NN }
+ #5 #7
+ #7 .
+ { #3 #1 } { #4 ## #2 }
+ #6 ;
+ }
+\cs_new_protected:Npn \@@_generate_internal_N:NN #1#2
+ { \@@_generate_internal_loop:nwnnw { \exp_not:N ###2 } }
+\cs_new_protected:Npn \@@_generate_internal_c:NN #1#2
+ { \exp_args:No \@@_generate_internal_loop:nwnnw { \exp_not:c {###2} } }
+\cs_new_protected:Npn \@@_generate_internal_n:NN #1#2
+ { \@@_generate_internal_loop:nwnnw { { \exp_not:n {###2} } } }
+\cs_new_protected:Npn \@@_generate_internal_x:NN #1#2
+ { \@@_generate_internal_loop:nwnnw { {###2} } }
+\cs_new_protected:Npn \@@_generate_internal_other:NN #1#2
+ {
+ \exp_args:No \@@_generate_internal_loop:nwnnw
+ {
+ \exp_after:wN
+ {
+ \exp:w \exp_args:NNc \exp_after:wN \exp_end:
+ { exp_not:#1 } {###2}
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_generate_internal_end:w #1 . #2#3#4 ; #5 ; #6#7#8
+ { #6 { exp_args:N #8 } #3 { #7 {#2} } }
+\cs_new_protected:Npn \@@_generate_internal_long:w #1 N #2#3 . #4#5#6#
+ {
+ \exp_args:Nx \@@_generate_internal_long:nnnNNn
+ { \@@_generate_internal_variant_loop:n #2 #6 { : \use_i:nn } }
+ {#4} {#5}
+ }
+\cs_new:Npn \@@_generate_internal_long:nnnNNn #1#2#3#4 ; ; #5#6#7
+ { #5 { exp_args:N #7 } #3 { #6 { \exp_not:n {#1} {#2} } } }
+% \end{macrocode}
+% This command grabs char by char outputting |\::#1| (not expanded
+% further). We avoid tests by putting a trailing |: \use_i:nn|, which
+% leaves \cs{cs_end:} and removes the looping macro. The colon is in
+% fact also turned into \cs{:::} so that the required structure for
+% |\exp_args:N...| commands is correctly terminated.
+% \begin{macrocode}
+\cs_new:Npn \@@_generate_internal_variant_loop:n #1
+ {
+ \exp_after:wN \exp_not:N \cs:w :: #1 \cs_end:
+ \@@_generate_internal_variant_loop:n
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \prg_generate_conditional_variant:Nnn,
+% \@@_generate_variant:nnNnn,
+% \@@_generate_variant:w,
+% \@@_generate_variant:n,
+% \@@_generate_variant_p_form:nnn,
+% \@@_generate_variant_T_form:nnn,
+% \@@_generate_variant_F_form:nnn,
+% \@@_generate_variant_TF_form:nnn,
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \prg_generate_conditional_variant:Nnn #1
+ {
+ \use:e
+ {
+ \@@_generate_variant:nnNnn
+ \cs_split_function:N #1
+ }
+ }
+\cs_new_protected:Npn \@@_generate_variant:nnNnn #1#2#3#4#5
+ {
+ \if_meaning:w \c_false_bool #3
+ \msg_error:nne { kernel } { missing-colon }
+ { \token_to_str:c {#1} }
+ \@@_use_i_delimit_by_s_stop:nw
+ \fi:
+ \exp_after:wN \@@_generate_variant:w
+ \tl_to_str:n {#5} , \scan_stop: , \q_@@_recursion_stop
+ \@@_use_none_delimit_by_s_stop:w \s_@@_mark {#1} {#2} {#4} \s_@@_stop
+ }
+\cs_new_protected:Npn \@@_generate_variant:w
+ #1 , #2 \s_@@_mark #3#4#5
+ {
+ \if_meaning:w \scan_stop: #1 \scan_stop:
+ \if_meaning:w \q_@@_nil #1 \q_@@_nil
+ \use_i:nnn
+ \fi:
+ \exp_after:wN \@@_use_none_delimit_by_q_recursion_stop:w
+ \else:
+ \cs_if_exist_use:cTF { @@_generate_variant_#1_form:nnn }
+ { {#3} {#4} {#5} }
+ {
+ \msg_error:nnee
+ { kernel } { conditional-form-unknown }
+ {#1} { \token_to_str:c { #3 : #4 } }
+ }
+ \fi:
+ \@@_generate_variant:w #2 \s_@@_mark {#3} {#4} {#5}
+ }
+\cs_new_protected:Npn \@@_generate_variant_p_form:nnn #1#2
+ { \cs_generate_variant:cn { #1 _p : #2 } }
+\cs_new_protected:Npn \@@_generate_variant_T_form:nnn #1#2
+ { \cs_generate_variant:cn { #1 : #2 T } }
+\cs_new_protected:Npn \@@_generate_variant_F_form:nnn #1#2
+ { \cs_generate_variant:cn { #1 : #2 F } }
+\cs_new_protected:Npn \@@_generate_variant_TF_form:nnn #1#2
+ { \cs_generate_variant:cn { #1 : #2 TF } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\exp_args_generate:n}
+% This function is not used in the kernel hence we can use functions
+% that are defined in later modules. It also does not need to be fast
+% so use inline mappings. For each requested variant we check that
+% there are no characters besides |NnpcofVvx|, in particular that
+% there are no spaces. Then we just call the internal function.
+% \begin{macrocode}
+\cs_new_protected:Npn \exp_args_generate:n #1
+ {
+ \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} }
+ {
+ \str_map_inline:nn {##1}
+ {
+ \str_if_in:nnF { NnpcofeVvx } {####1}
+ {
+ \msg_error:nnnn { kernel } { invalid-exp-args }
+ {####1} {##1}
+ \str_map_break:n { \use_none:nn }
+ }
+ }
+ \@@_generate_internal_variant:n {##1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Definitions with the automated technique}
+% \label{sec:l3expan:gendef}
+%
+% Some of these could be done more efficiently, but the complexity of
+% coding then becomes an issue. Notice that the auto-generated functions
+% actually take no arguments themselves.
+%
+% \begin{macro}[EXP]
+% {
+% \exp_args:Nnc, \exp_args:Nno, \exp_args:NnV, \exp_args:Nnv, \exp_args:Nne, \exp_args:Nnf,
+% \exp_args:Noc, \exp_args:Noo, \exp_args:Nof,
+% \exp_args:NVo, \exp_args:Nfo, \exp_args:Nff, \exp_args:Nee
+% }
+% \begin{macro}
+% {
+% \exp_args:NNx, \exp_args:Ncx, \exp_args:Nnx,
+% \exp_args:Nox, \exp_args:Nxo, \exp_args:Nxx,
+% }
+% Here are the actual function definitions, using the helper
+% functions above. The group is used because
+% \cs{@@_generate_internal_variant:n} redefines \cs{@@_tmp:w} locally.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \group_begin:
+ \exp_args:No \@@_generate_internal_variant:n
+ { \tl_to_str:n {#1} }
+ \group_end:
+ }
+\@@_tmp:w { nc }
+\@@_tmp:w { no }
+\@@_tmp:w { nV }
+\@@_tmp:w { nv }
+\@@_tmp:w { ne }
+\@@_tmp:w { nf }
+\@@_tmp:w { oc }
+\@@_tmp:w { oo }
+\@@_tmp:w { of }
+\@@_tmp:w { Vo }
+\@@_tmp:w { fo }
+\@@_tmp:w { ff }
+\@@_tmp:w { ee }
+\@@_tmp:w { Nx }
+\@@_tmp:w { cx }
+\@@_tmp:w { nx }
+\@@_tmp:w { ox }
+\@@_tmp:w { xo }
+\@@_tmp:w { xx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \exp_args:NNcf,
+% \exp_args:NNno, \exp_args:NNnV, \exp_args:NNoo, \exp_args:NNVV,
+% \exp_args:Ncno, \exp_args:NcnV, \exp_args:Ncoo, \exp_args:NcVV,
+% \exp_args:Nnnc, \exp_args:Nnno, \exp_args:Nnnf, \exp_args:Nnff,
+% \exp_args:Nooo, \exp_args:Noof, \exp_args:Nffo, \exp_args:Neee
+% }
+% \begin{macro}
+% {
+% \exp_args:NNNx, \exp_args:NNnx, \exp_args:NNox,
+% \exp_args:Nccx, \exp_args:Ncnx,
+% \exp_args:Nnnx, \exp_args:Nnox, \exp_args:Noox,
+% }
+% \begin{macrocode}
+\@@_tmp:w { Ncf }
+\@@_tmp:w { Nno }
+\@@_tmp:w { NnV }
+\@@_tmp:w { Noo }
+\@@_tmp:w { NVV }
+\@@_tmp:w { cno }
+\@@_tmp:w { cnV }
+\@@_tmp:w { coo }
+\@@_tmp:w { cVV }
+\@@_tmp:w { nnc }
+\@@_tmp:w { nno }
+\@@_tmp:w { nnf }
+\@@_tmp:w { nff }
+\@@_tmp:w { ooo }
+\@@_tmp:w { oof }
+\@@_tmp:w { ffo }
+\@@_tmp:w { eee }
+\@@_tmp:w { NNx }
+\@@_tmp:w { Nnx }
+\@@_tmp:w { Nox }
+\@@_tmp:w { nnx }
+\@@_tmp:w { nox }
+\@@_tmp:w { ccx }
+\@@_tmp:w { cnx }
+\@@_tmp:w { oox }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Held-over variant generation}
+%
+% \begin{macro}[documented-as = \cs_generate_from_arg_count:NNnn]
+% {\cs_generate_from_arg_count:NNno}
+% \begin{macro}[documented-as = \cs_replacement_spec:N]{\cs_replacement_spec:c}
+% A couple of variants that are from early functions.
+% \begin{macrocode}
+\cs_generate_variant:Nn \cs_generate_from_arg_count:NNnn { NNno }
+\cs_generate_variant:Nn \cs_replacement_spec:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3file.dtx b/macros/latex-dev/required/l3kernel/l3file.dtx
new file mode 100644
index 0000000000..6111d270ca
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3file.dtx
@@ -0,0 +1,4026 @@
+% \iffalse meta-comment
+%
+%% File: l3file.dtx
+%
+% Copyright (C) 1990-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+\DocInput{\jobname.dtx}
+\PrintIndex
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3file} module\\ File and I/O operations^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% This module provides functions for working with external files. Some of these
+% functions apply to an entire file, and have prefix \cs[no-index]{file_\ldots}, while
+% others are used to work with files on a line by line basis and have prefix
+% \cs[no-index]{ior_\ldots} (reading) or \cs[no-index]{iow_\ldots} (writing).
+%
+% It is important to remember that when reading external files \TeX{}
+% attempts to locate them using both the operating system path and entries in the
+% \TeX{} file database (most \TeX{} systems use such a database). Thus the
+% \enquote{current path} for \TeX{} is somewhat broader than that for other
+% programs.
+%
+% For functions which expect a \meta{file name} argument, this argument
+% may contain both literal items and expandable content, which should on
+% full expansion be the desired file name. Active characters (as
+% declared in \cs{l_char_active_seq}) are \emph{not} expanded,
+% allowing the direct use of these in file names. Quote tokens (|"|) are
+% not permitted in file names as they are reserved for internal use by some
+% \TeX{} primitives.
+%
+% Spaces are trimmed at the beginning and end of the file name:
+% this reflects the fact that some file systems do not allow or interact
+% unpredictably with spaces in these positions. When no extension is given,
+% this will trim spaces from the start of the name only.
+%
+% \section{Input--output stream management}
+%
+% As \TeX{} engines have a limited number of input and output streams, direct
+% use of the streams by the programmer is not supported in \LaTeX3. Instead, an
+% internal pool of streams is maintained, and these are allocated and
+% deallocated as needed by other modules. As a result, the programmer should
+% close streams when they are no longer needed, to release them for other
+% processes.
+%
+% Note that I/O operations are global: streams should all be declared
+% with global names and treated accordingly.
+%
+% \begin{function}[added = 2011-09-26, updated = 2011-12-27]
+% {\ior_new:N, \ior_new:c, \iow_new:N, \iow_new:c}
+% \begin{syntax}
+% \cs{ior_new:N} \meta{stream}
+% \cs{iow_new:N} \meta{stream}
+% \end{syntax}
+% Globally reserves the name of the \meta{stream}, either for reading
+% or for writing as appropriate. The \meta{stream} is not opened until
+% the appropriate \cs[no-index]{\ldots_open:Nn} function is used. Attempting to
+% use a \meta{stream} which has not been opened is an error, and the
+% \meta{stream} will behave as the corresponding \cs[no-index]{c_term_\ldots}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-02-10]{\ior_open:Nn, \ior_open:cn}
+% \begin{syntax}
+% \cs{ior_open:Nn} \meta{stream} \Arg{file name}
+% \end{syntax}
+% Opens \meta{file name} for reading using \meta{stream} as the
+% control sequence for file access. If the \meta{stream} was already
+% open it is closed before the new operation begins. The
+% \meta{stream} is available for access immediately and will remain
+% allocated to \meta{file name} until an \cs{ior_close:N} instruction
+% is given or the \TeX{} run ends.
+% If the file is not found, an error is raised.
+% \end{function}
+%
+% \begin{function}[added = 2013-01-12, TF]{\ior_open:Nn, \ior_open:cn}
+% \begin{syntax}
+% \cs{ior_open:NnTF} \meta{stream} \Arg{file name} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Opens \meta{file name} for reading using \meta{stream} as the
+% control sequence for file access. If the \meta{stream} was already
+% open it is closed before the new operation begins. The
+% \meta{stream} is available for access immediately and will remain
+% allocated to \meta{file name} until a \cs{ior_close:N} instruction
+% is given or the \TeX{} run ends. The \meta{true code} is then inserted
+% into the input stream. If the file is not found, no error is raised and
+% the \meta{false code} is inserted into the input stream.
+% \end{function}
+%
+% \begin{function}[updated = 2012-02-09]
+% {\iow_open:Nn, \iow_open:NV, \iow_open:cn, \iow_open:cV}
+% \begin{syntax}
+% \cs{iow_open:Nn} \meta{stream} \Arg{file name}
+% \end{syntax}
+% Opens \meta{file name} for writing using \meta{stream} as the
+% control sequence for file access. If the \meta{stream} was already
+% open it is closed before the new operation begins. The
+% \meta{stream} is available for access immediately and will remain
+% allocated to \meta{file name} until a \cs{iow_close:N} instruction
+% is given or the \TeX{} run ends. Opening a file for writing clears
+% any existing content in the file (\emph{i.e.}~writing is \emph{not}
+% additive).
+% \end{function}
+%
+% \begin{function}[added = 2019-05-08]{\ior_shell_open:Nn}
+% \begin{syntax}
+% \cs{ior_shell_open:Nn} \meta{stream} \Arg{shell~command}
+% \end{syntax}
+% Opens the \emph{pseudo}-file created by the output of the
+% \meta{shell command} for reading using \meta{stream} as the
+% control sequence for access. If the \meta{stream} was already
+% open it is closed before the new operation begins. The
+% \meta{stream} is available for access immediately and will remain
+% allocated to \meta{shell command} until a \cs{ior_close:N} instruction
+% is given or the \TeX{} run ends.
+% If piped system calls are disabled an error is raised.
+%
+% For details of handling of the \meta{shell command}, see
+% \cs{sys_get_shell:nnNTF}.
+% \end{function}
+%
+% \begin{function}[added = 2023-05-25]{\iow_shell_open:Nn}
+% \begin{syntax}
+% \cs{iow_shell_open:Nn} \meta{stream} \Arg{shell~command}
+% \end{syntax}
+% Opens the \emph{pseudo}-file created by the output of the
+% \meta{shell command} for writing using \meta{stream} as the
+% control sequence for access. If the \meta{stream} was already
+% open it is closed before the new operation begins. The
+% \meta{stream} is available for access immediately and will remain
+% allocated to \meta{shell command} until an \cs{iow_close:N} instruction
+% is given or the \TeX{} run ends.
+% If piped system calls are disabled an error is raised.
+%
+% For details of handling of the \meta{shell command}, see
+% \cs{sys_get_shell:nnNTF}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-07-31]
+% {\ior_close:N, \ior_close:c, \iow_close:N, \iow_close:c}
+% \begin{syntax}
+% \cs{ior_close:N} \meta{stream}
+% \cs{iow_close:N} \meta{stream}
+% \end{syntax}
+% Closes the \meta{stream}. Streams should always be closed when
+% they are finished with as this ensures that they remain available
+% to other programmers.
+% \end{function}
+%
+% \begin{function}[added = 2021-05-11]
+% {
+% \ior_show:N, \ior_show:c, \ior_log:N, \ior_log:c,
+% \iow_show:N, \iow_show:c, \iow_log:N, \iow_log:c
+% }
+% \begin{syntax}
+% \cs{ior_show:N} \meta{stream}
+% \cs{ior_log:N} \meta{stream}
+% \cs{iow_show:N} \meta{stream}
+% \cs{iow_log:N} \meta{stream}
+% \end{syntax}
+% Display (to the terminal or log file) the file name associated to
+% the (read or write) \meta{stream}.
+% \end{function}
+%
+% \begin{function}[added = 2017-06-27]
+% {
+% \ior_show_list:, \ior_log_list:,
+% \iow_show_list:, \iow_log_list:
+% }
+% \begin{syntax}
+% \cs{ior_show_list:}
+% \cs{ior_log_list:}
+% \cs{iow_show_list:}
+% \cs{iow_log_list:}
+% \end{syntax}
+% Display (to the terminal or log file) a list of the file names
+% associated with each open (read or write) stream. This is intended
+% for tracking down problems.
+% \end{function}
+%
+% \subsection{Reading from files}
+%
+% Reading from files and reading from the terminal are separate processes in
+% \pkg{expl3}. The functions \cs{ior_get:NN} and \cs{ior_str_get:NN}, and their
+% branching equivalents, are designed to work with \emph{files}.
+%
+% \begin{function}[noTF, added = 2012-06-24, updated = 2019-03-23]{\ior_get:NN}
+% \begin{syntax}
+% \cs{ior_get:NN} \meta{stream} \meta{token list variable}
+% \cs{ior_get:NNTF} \meta{stream} \meta{token list variable} \meta{true code} \meta{false code}
+% \end{syntax}
+% Function that reads one or more lines (until an equal number of left
+% and right braces are found) from the file input \meta{stream} and stores
+% the result locally in the \meta{token list} variable.
+% The material read from the \meta{stream} is tokenized by \TeX{}
+% according to the category codes and \tn{endlinechar} in force when
+% the function is used. Assuming normal settings, any lines which do
+% not end in a comment character~|%| have the line ending
+% converted to a space, so for example input
+% \begin{verbatim}
+% a b c
+% \end{verbatim}
+% results in a token list \verb*|a b c |. Any blank line is
+% converted to the token \cs{par}. Therefore, blank lines can be
+% skipped by using a test such as
+% \begin{verbatim}
+% \ior_get:NN \l_my_stream \l_tmpa_tl
+% \tl_set:Nn \l_tmpb_tl { \par }
+% \tl_if_eq:NNF \l_tmpa_tl \l_tmpb_tl
+% ...
+% \end{verbatim}
+% Also notice that if multiple lines are read to match braces
+% then the resulting token list can contain \cs{par} tokens.
+% In the non-branching version, where the \meta{stream} is not open
+% the \meta{tl var} is set to \cs{q_no_value}.
+% \begin{texnote}
+% This protected macro is a wrapper around the \TeX{} primitive
+% \tn{read}. Regardless of settings, \TeX{} replaces trailing space
+% and tab characters (character codes 32 and~9) in each line by an
+% end-of-line character (character code \tn{endlinechar}, omitted if
+% \tn{endlinechar} is negative or too large) before turning
+% characters into tokens according to current category codes. With
+% default settings, spaces appearing at the beginning of lines are
+% also ignored.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[noTF, added = 2016-12-04, updated = 2019-03-23]
+% {\ior_str_get:NN}
+% \begin{syntax}
+% \cs{ior_str_get:NN} \meta{stream} \meta{token list variable}
+% \cs{ior_str_get:NNTF} \meta{stream} \meta{token list variable} \meta{true code} \meta{false code}
+% \end{syntax}
+% Function that reads one line from the file input \meta{stream} and stores
+% the result locally in the \meta{token list} variable.
+% The material is read from the \meta{stream} as a series of tokens with
+% category code $12$ (other), with the exception of space
+% characters which are given category code $10$ (space).
+% Multiple whitespace characters are retained by this process. It
+% always only reads one line and any blank lines in the input
+% result in the \meta{token list variable} being empty. Unlike
+% \cs{ior_get:NN}, line ends do not receive any special treatment. Thus
+% input
+% \begin{verbatim}
+% a b c
+% \end{verbatim}
+% results in a token list |a b c| with the letters |a|, |b|, and |c|
+% having category code~12.
+% In the non-branching version, where the\meta{stream} is not open
+% the \meta{tl var} is set to \cs{q_no_value}.
+% \begin{texnote}
+% This protected macro is a wrapper around the \eTeX{} primitive
+% \tn{readline}. Regardless of settings, \TeX{} removes trailing
+% space and tab characters (character codes 32 and~9). However, the
+% end-line character normally added by this primitive is not
+% included in the result of \cs{ior_str_get:NN}.
+% \end{texnote}
+% \end{function}
+%
+% All mappings are done at the current group level, \emph{i.e.}~any
+% local assignments made by the \meta{function} or \meta{code} discussed
+% below remain in effect after the loop.
+%
+% \begin{function}[added = 2012-02-11]{\ior_map_inline:Nn}
+% \begin{syntax}
+% \cs{ior_map_inline:Nn} \meta{stream} \Arg{inline function}
+% \end{syntax}
+% Applies the \meta{inline function} to each set of \meta{lines}
+% obtained by calling \cs{ior_get:NN} until reaching the end of the
+% file. \TeX{} ignores any trailing new-line marker from the file it
+% reads. The \meta{inline function} should consist of code which
+% receives the \meta{line} as |#1|.
+% \end{function}
+%
+% \begin{function}[added = 2012-02-11]{\ior_str_map_inline:Nn}
+% \begin{syntax}
+% \cs{ior_str_map_inline:Nn} \meta{stream} \Arg{inline function}
+% \end{syntax}
+% Applies the \meta{inline function} to every \meta{line}
+% in the \meta{stream}. The material is read from the \meta{stream}
+% as a series of tokens with category code $12$ (other), with the
+% exception of space characters which are given category code $10$
+% (space). The \meta{inline function} should consist of code which
+% receives the \meta{line} as |#1|.
+% Note that \TeX{} removes trailing space and tab characters
+% (character codes 32 and 9) from every line upon input. \TeX{} also
+% ignores any trailing new-line marker from the file it reads.
+% \end{function}
+%
+% \begin{function}[added = 2019-01-13]{\ior_map_variable:NNn}
+% \begin{syntax}
+% \cs{ior_map_variable:NNn} \meta{stream} \meta{tl~var} \Arg{code}
+% \end{syntax}
+% For each set of \meta{lines} obtained by calling \cs{ior_get:NN}
+% until reaching the end of the file, stores the \meta{lines} in the
+% \meta{tl~var} then applies the \meta{code}. The \meta{code} will
+% usually make use of the \meta{variable}, but this is not enforced.
+% The assignments to the \meta{variable} are local.
+% Its value after the loop is the last set of \meta{lines}, or its
+% original value if the \meta{stream} is empty. \TeX{} ignores
+% any trailing new-line marker from the file it reads.
+% This function is typically faster than \cs{ior_map_inline:Nn}.
+% \end{function}
+%
+% \begin{function}[added = 2019-01-13]{\ior_str_map_variable:NNn}
+% \begin{syntax}
+% \cs{ior_str_map_variable:NNn} \meta{stream} \meta{variable} \Arg{code}
+% \end{syntax}
+% For each \meta{line} in the \meta{stream}, stores the \meta{line} in
+% the \meta{variable} then applies the \meta{code}. The material is
+% read from the \meta{stream} as a series of tokens with category code
+% $12$ (other), with the exception of space characters which are given
+% category code $10$ (space). The \meta{code} will usually make use
+% of the \meta{variable}, but this is not enforced. The assignments
+% to the \meta{variable} are local. Its value after the loop is the
+% last \meta{line}, or its original value if the \meta{stream} is
+% empty. Note that \TeX{} removes trailing
+% space and tab characters (character codes 32 and 9) from every line
+% upon input. \TeX{} also ignores any trailing new-line marker from
+% the file it reads.
+% This function is typically faster than \cs{ior_str_map_inline:Nn}.
+% \end{function}
+%
+% \begin{function}[added = 2012-06-29]{\ior_map_break:}
+% \begin{syntax}
+% \cs{ior_map_break:}
+% \end{syntax}
+% Used to terminate a \cs[no-index]{ior_map_\ldots} function before all
+% lines from the \meta{stream} have been processed. This
+% normally takes place within a conditional statement, for example
+% \begin{verbatim}
+% \ior_map_inline:Nn \l_my_ior
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \ior_map_break: }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs[no-index]{ior_map_\ldots} scenario leads to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted
+% before further items are taken
+% from the input stream. This depends on the design of the mapping
+% function.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2012-06-29]{\ior_map_break:n}
+% \begin{syntax}
+% \cs{ior_map_break:n} \Arg{code}
+% \end{syntax}
+% Used to terminate a \cs[no-index]{ior_map_\ldots} function before all
+% lines in the \meta{stream} have been processed, inserting
+% the \meta{code} after the mapping has ended. This
+% normally takes place within a conditional statement, for example
+% \begin{verbatim}
+% \ior_map_inline:Nn \l_my_ior
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \ior_map_break:n { <code> } }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs[no-index]{ior_map_\ldots} scenario leads to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted
+% before the \meta{code} is
+% inserted into the input stream.
+% This depends on the design of the mapping function.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[updated = 2012-02-10, EXP, pTF]{\ior_if_eof:N}
+% \begin{syntax}
+% \cs{ior_if_eof_p:N} \meta{stream} \\
+% \cs{ior_if_eof:NTF} \meta{stream} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the end of a file \meta{stream} has been reached during a reading
+% operation. The test also returns a \texttt{true} value if
+% the \meta{stream} is not open.
+% \end{function}
+%
+% \subsection{Reading from the terminal}
+%
+% \begin{function}[added = 2019-03-23]{\ior_get_term:nN, \ior_str_get_term:nN}
+% \begin{syntax}
+% \cs{ior_get_term:nN} \meta{prompt} \meta{token list variable}
+% \end{syntax}
+% Function that reads one or more lines (until an equal number of left
+% and right braces are found) from the terminal and stores
+% the result locally in the \meta{token list} variable. Tokenization
+% occurs as described for \cs{ior_get:NN} or \cs{ior_str_get:NN}, respectively.
+% When the \meta{prompt}
+% is empty, \TeX{} will wait for input without any other indication:
+% typically the programmer will have provided a suitable text using
+% e.g.~\cs{iow_term:n}. Where the \meta{prompt} is given, it will appear
+% in the terminal followed by an |=|, e.g.
+% \begin{verbatim}
+% prompt=
+% \end{verbatim}
+% \end{function}
+%
+% \subsection{Writing to files}
+%
+% \begin{function}[updated = 2012-06-05]
+% {
+% \iow_now:Nn, \iow_now:NV, \iow_now:Ne,
+% \iow_now:cn, \iow_now:cV, \iow_now:ce
+% }
+% \begin{syntax}
+% \cs{iow_now:Nn} \meta{stream} \Arg{tokens}
+% \end{syntax}
+% This function writes \meta{tokens} to the specified
+% \meta{stream} immediately (\emph{i.e.}~the write operation is called
+% on expansion of \cs{iow_now:Nn}).
+% \end{function}
+%
+% \begin{function}{\iow_log:n, \iow_log:e}
+% \begin{syntax}
+% \cs{iow_log:n} \Arg{tokens}
+% \end{syntax}
+% This function writes the given \meta{tokens} to the log (transcript)
+% file immediately: it is a dedicated version of \cs{iow_now:Nn}.
+% \end{function}
+%
+% \begin{function}{\iow_term:n, \iow_term:e}
+% \begin{syntax}
+% \cs{iow_term:n} \Arg{tokens}
+% \end{syntax}
+% This function writes the given \meta{tokens} to the terminal
+% file immediately: it is a dedicated version of \cs{iow_now:Nn}.
+% \end{function}
+%
+% \begin{function}
+% {
+% \iow_shipout:Nn, \iow_shipout:Ne,
+% \iow_shipout:cn, \iow_shipout:ce
+% }
+% \begin{syntax}
+% \cs{iow_shipout:Nn} \meta{stream} \Arg{tokens}
+% \end{syntax}
+% This function writes \meta{tokens} to the specified
+% \meta{stream} when the current page is finalised (\emph{i.e.}~at
+% shipout). The \texttt{e}-type variants expand the \meta{tokens}
+% at the point where the function is used but \emph{not} when the
+% resulting tokens are written to the \meta{stream}
+% (\emph{cf.}~\cs{iow_shipout_e:Nn}).
+% \begin{texnote}
+% When using \pkg{expl3} with a format other than \LaTeX{}, new line
+% characters inserted using \cs{iow_newline:} or using the
+% line-wrapping code \cs{iow_wrap:nnnN} are not recognized in
+% the argument of \cs{iow_shipout:Nn}. This may lead to the
+% insertion of additional unwanted line-breaks.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[updated = 2023-09-17]
+% {
+% \iow_shipout_e:Nn, \iow_shipout_e:Ne,
+% \iow_shipout_e:cn, \iow_shipout_e:ce
+% }
+% \begin{syntax}
+% \cs{iow_shipout_e:Nn} \meta{stream} \Arg{tokens}
+% \end{syntax}
+% This function writes \meta{tokens} to the specified
+% \meta{stream} when the current page is finalised (\emph{i.e.}~at
+% shipout). The \meta{tokens} are expanded at the time of writing
+% in addition to any expansion when the function is used. This makes
+% these functions suitable for including material finalised during
+% the page building process (such as the page number integer).
+% \begin{texnote}
+% This is a wrapper around the \TeX{} primitive \tn{write}.
+% When using \pkg{expl3} with a format other than \LaTeX{}, new line
+% characters inserted using \cs{iow_newline:} or using the
+% line-wrapping code \cs{iow_wrap:nnnN} are not recognized in
+% the argument of \cs{iow_shipout:Nn}. This may lead to the
+% insertion of additional unwanted line-breaks.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\iow_char:N}
+% \begin{syntax}
+% \cs{iow_char:N} |\|\meta{char}
+% \end{syntax}
+% Inserts \meta{char} into the output stream. Useful when trying to
+% write difficult characters such as |%|, |{|, |}|,
+% \emph{etc.}~in messages, for example:
+% \begin{verbatim}
+% \iow_now:Ne \g_my_iow { \iow_char:N \{ text \iow_char:N \} }
+% \end{verbatim}
+% The function has no effect if writing is taking place without
+% expansion (\emph{e.g.}~in the second argument of \cs{iow_now:Nn}).
+% \end{function}
+%
+% \begin{function}[EXP]{\iow_newline:}
+% \begin{syntax}
+% \cs{iow_newline:}
+% \end{syntax}
+% Function to add a new line within the \meta{tokens} written to a
+% file. The function has no effect if writing is taking place without
+% expansion (\emph{e.g.}~in the second argument of \cs{iow_now:Nn}).
+% \begin{texnote}
+% When using \pkg{expl3} with a format other than \LaTeX{}, the
+% character inserted by \cs{iow_newline:} is not recognized by
+% \TeX{}, which may lead to the insertion of additional unwanted
+% line-breaks. This issue only affects \cs{iow_shipout:Nn},
+% \cs{iow_shipout_e:Nn} and direct uses of primitive operations.
+% \end{texnote}
+% \end{function}
+%
+% \subsection{Wrapping lines in output}
+%
+% \begin{function}[added = 2012-06-28, updated = 2017-12-04]
+% {\iow_wrap:nnnN, \iow_wrap:nenN}
+% \begin{syntax}
+% \cs{iow_wrap:nnnN} \Arg{text} \Arg{run-on text} \Arg{set up} \meta{function}
+% \end{syntax}
+% This function wraps the \meta{text} to a fixed number of
+% characters per line. At the start of each line which is wrapped,
+% the \meta{run-on text} is inserted. The line character count
+% targeted is the value of \cs{l_iow_line_count_int} minus the
+% number of characters in the \meta{run-on text} for all lines except
+% the first, for which the target number of characters is simply
+% \cs{l_iow_line_count_int} since there is no run-on text. The
+% \meta{text} and \meta{run-on text} are exhaustively expanded by the
+% function, with the following substitutions:
+% \begin{itemize}
+% \item |\\| or \cs{iow_newline:} may be used to force a new line,
+% \item \verb*|\ | may be used to represent a forced space
+% (for example after a control sequence),
+% \item |\#|, |\%|, |\{|, |\}|, |\~| may be used to represent
+% the corresponding character,
+% \item \cs{iow_wrap_allow_break:} may be used to allow a line-break
+% without inserting a space,
+% \item \cs{iow_indent:n} may be used to indent a part of the
+% \meta{text} (not the \meta{run-on text}).
+% \end{itemize}
+% Additional functions may be added to the wrapping by using the
+% \meta{set up}, which is executed before the wrapping takes place: this
+% may include overriding the substitutions listed.
+%
+% Any expandable material in the \meta{text} which is not to be expanded
+% on wrapping should be converted to a string using \cs{token_to_str:N},
+% \cs{tl_to_str:n}, \cs{tl_to_str:N}, \emph{etc.}
+%
+% The result of the wrapping operation is passed as a braced argument to the
+% \meta{function}, which is typically a wrapper around a write
+% operation. The output of \cs{iow_wrap:nnnN} (\emph{i.e.}~the argument
+% passed to the \meta{function}) consists of characters of category
+% \enquote{other} (category code~12), with the exception of spaces which
+% have category \enquote{space} (category code~10). This means that the
+% output does \emph{not} expand further when written to a file.
+%
+% \begin{texnote}
+% Internally, \cs{iow_wrap:nnnN} carries out an \texttt{e}-type expansion
+% on the \meta{text} to expand it. This is done in such a way that
+% \cs{exp_not:N} or \cs{exp_not:n} \emph{could} be used to prevent
+% expansion of material. However, this is less conceptually clear than
+% conversion to a string, which is therefore the supported method for
+% handling expandable material in the \meta{text}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2023-04-25]{\iow_wrap_allow_break:}
+% \begin{syntax}
+% \cs{iow_wrap_allow_break:}
+% \end{syntax}
+% In the first argument of \cs{iow_wrap:nnnN} (for instance in
+% messages), inserts a break-point that allows a line break. If
+% no break occurs, this function adds nothing to the output.
+% \end{function}
+%
+% \begin{function}[added = 2011-09-21]{\iow_indent:n}
+% \begin{syntax}
+% \cs{iow_indent:n} \Arg{text}
+% \end{syntax}
+% In the first argument of \cs{iow_wrap:nnnN} (for instance in messages),
+% indents \meta{text} by four spaces. This function does not cause
+% a line break, and only affects lines which start within the scope
+% of the \meta{text}. In case the indented \meta{text} should appear
+% on separate lines from the surrounding text, use |\\| to force
+% line breaks.
+% \end{function}
+%
+% \begin{variable}[added = 2012-06-24]{\l_iow_line_count_int}
+% The maximum number of characters in a line to be written
+% by the \cs{iow_wrap:nnnN}
+% function. This value depends on the \TeX{} system in use: the standard
+% value is $78$, which is typically correct for unmodified \TeX{} Live
+% and \hologo{MiKTeX} systems.
+% \end{variable}
+%
+% \subsection{Constant input--output streams, and variables}
+%
+% \begin{variable}[added = 2017-12-11]{\g_tmpa_ior, \g_tmpb_ior}
+% Scratch input stream for global use. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\c_log_iow, \c_term_iow}
+% Constant output streams for writing to the log and to the terminal
+% (plus the log), respectively.
+% \end{variable}
+%
+% \begin{variable}[added = 2017-12-11]{\g_tmpa_iow, \g_tmpb_iow}
+% Scratch output stream for global use. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \subsection{Primitive conditionals}
+%
+% \begin{function}[EXP]{\if_eof:w}
+% \begin{syntax}
+% \cs{if_eof:w} \meta{stream}
+% ~~\meta{true code}
+% \cs{else:}
+% ~~\meta{false code}
+% \cs{fi:}
+% \end{syntax}
+% Tests if the \meta{stream} returns \enquote{end of file}, which is true
+% for non-existent files. The \cs{else:} branch is optional.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifeof}.
+% \end{texnote}
+% \end{function}
+%
+% \section{File opertions}
+%
+% \subsection{Basic file operations}
+%
+% \begin{variable}[added = 2017-06-21]
+% {
+% \g_file_curr_dir_str,
+% \g_file_curr_name_str,
+% \g_file_curr_ext_str
+% }
+% Contain the directory, name and extension of the current file. The
+% directory is empty if the file was loaded without an explicit
+% path (\emph{i.e.}~if it is in the \TeX{} search path), and does
+% \emph{not} end in |/| other than the case that it is exactly equal
+% to the root directory. The \meta{name} and \meta{ext} parts together
+% make up the file name, thus the \meta{name} part may be thought of
+% as the \enquote{job name} for the current file.
+%
+% Note that \TeX{} does not provide information on the \meta{dir} and
+% \meta{ext} part for the main (top level) file and that this file
+% always has empty \meta{dir} and \meta{ext} components.
+% Also, the \meta{name} here will be equal to \cs{c_sys_jobname_str},
+% which may be different from the real file name (if set using
+% |--jobname|, for example).
+% \end{variable}
+%
+% \begin{variable}[added = 2017-06-18, updated = 2023-06-15]
+% {\l_file_search_path_seq}
+% Each entry is the path to a directory which should be searched when
+% seeking a file. Each path can be relative or absolute, and need
+% not include the trailing slash. Spaces need not be quoted.
+%
+% \begin{texnote}
+% When working as a package in \LaTeXe{}, \pkg{expl3} will
+% automatically append the current \tn{input@path} to the
+% set of values from \cs{l_file_search_path_seq}.
+% \end{texnote}
+% \end{variable}
+%
+% \begin{function}[EXP, pTF, updated = 2023-09-18]
+% {\file_if_exist:n, \file_if_exist:V}
+% \begin{syntax}
+% \cs{file_if_exist_p:n} \Arg{file name}
+% \cs{file_if_exist:nTF} \Arg{file name} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{file name} is found in the path as detailed for
+% \cs{file_if_exist:nTF}.
+% \end{function}
+%
+% \subsection{Information about files and file contents}
+%
+% Functions in this section return information about files as \pkg{expl3}
+% \texttt{str} data, \emph{except} that the non-expandable functions set their
+% return \emph{token list} to \cs{q_no_value} if the file requested is not
+% found. As such, comparison of file names, hashes, sizes, etc., should use
+% \cs{str_if_eq:nnTF} rather than \cs{tl_if_eq:nnTF} and so on.
+%
+% \begin{function}[rEXP, added = 2019-11-19]
+% {
+% \file_hex_dump:n, \file_hex_dump:V,
+% \file_hex_dump:nnn, \file_hex_dump:Vnn
+% }
+% \begin{syntax}
+% \cs{file_hex_dump:n} \Arg{file name}
+% \cs{file_hex_dump:nnn} \Arg{file name} \Arg{start index} \Arg{end index}
+% \end{syntax}
+% Searches for \meta{file name} using the current \TeX{} search
+% path and the additional paths controlled by \cs{l_file_search_path_seq}.
+% It then expands to leave the hexadecimal dump of the file content in the
+% input stream. The file is read as bytes, which means that in
+% contrast to most \TeX{} behaviour there will be a difference in result
+% depending on the line endings used in text files. The same file will
+% produce the same result between different engines: the algorithm used
+% is the same in all cases. When the file is not found, the result of
+% expansion is empty. The \Arg{start index} and \Arg{end index} values
+% work as described for \cs{str_range:nnn}.
+% \end{function}
+%
+% \begin{function}[noTF, added = 2019-11-19]
+% {
+% \file_get_hex_dump:nN, \file_get_hex_dump:VN,
+% \file_get_hex_dump:nnnN, \file_get_hex_dump:VnnN
+% }
+% \begin{syntax}
+% \cs{file_get_hex_dump:nN} \Arg{file name} \meta{tl var}
+% \cs{file_get_hex_dump:nnnN} \Arg{file name} \Arg{start index} \Arg{end index} \meta{tl var}
+% \end{syntax}
+% Sets the \meta{tl var} to the result of applying
+% \cs{file_hex_dump:n}/\cs{file_hex_dump:nnn} to the \meta{file}.
+% If the file is not found, the \meta{tl var} will be set to \cs{q_no_value}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2019-09-03]
+% {\file_mdfive_hash:n, \file_mdfive_hash:V}
+% \begin{syntax}
+% \cs{file_mdfive_hash:n} \Arg{file name}
+% \end{syntax}
+% Searches for \meta{file name} using the current \TeX{} search
+% path and the additional paths controlled by \cs{l_file_search_path_seq}.
+% It then expands to leave the MD5 sum generated from the contents of
+% the file in the input stream. The file is read as bytes, which means that in
+% contrast to most \TeX{} behaviour there will be a difference in result
+% depending on the line endings used in text files. The same file will
+% produce the same result between different engines: the algorithm used
+% is the same in all cases. When the file is not found, the result of
+% expansion is empty.
+% \end{function}
+%
+% \begin{function}[noTF, added = 2017-07-11, updated = 2019-02-16]
+% {\file_get_mdfive_hash:nN, \file_get_mdfive_hash:VN}
+% \begin{syntax}
+% \cs{file_get_mdfive_hash:nN} \Arg{file name} \meta{tl var}
+% \end{syntax}
+% Sets the \meta{tl var} to the result of applying
+% \cs{file_mdfive_hash:n} to the \meta{file}. If the file is not found,
+% the \meta{tl var} will be set to \cs{q_no_value}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2019-09-03]{\file_size:n, \file_size:V}
+% \begin{syntax}
+% \cs{file_size:n} \Arg{file name}
+% \end{syntax}
+% Searches for \meta{file name} using the current \TeX{} search
+% path and the additional paths controlled by \cs{l_file_search_path_seq}.
+% It then expands to leave the size of the file in bytes in the input stream.
+% When the file is not found, the result of expansion is empty.
+% \end{function}
+%
+% \begin{function}[noTF, added = 2017-07-09, updated = 2019-02-16]
+% {\file_get_size:nN, \file_get_size:VN}
+% \begin{syntax}
+% \cs{file_get_size:nN} \Arg{file name} \meta{tl var}
+% \end{syntax}
+% Sets the \meta{tl var} to the result of applying
+% \cs{file_size:n} to the \meta{file}. If the file is not found,
+% the \meta{tl var} will be set to \cs{q_no_value}.
+% This is not available in older versions of \XeTeX{}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2019-09-03]
+% {\file_timestamp:n, \file_timestamp:V}
+% \begin{syntax}
+% \cs{file_timestamp:n} \Arg{file name}
+% \end{syntax}
+% Searches for \meta{file name} using the current \TeX{} search
+% path and the additional paths controlled by \cs{l_file_search_path_seq}.
+% It then expands to leave the modification timestamp of
+% the file in the input stream. The timestamp is of the form
+% |D:|\meta{year}\meta{month}\meta{day}\meta{hour}^^A
+% \meta{minute}\meta{second}\meta{offset}, where the latter may be |Z|
+% (UTC) or \meta{plus-minus}\meta{hours}|'|\meta{minutes}|'|.
+% When the file is not found, the result of expansion is empty.
+% This is not available in older versions of \XeTeX{}.
+% \end{function}
+%
+% \begin{function}[noTF, added = 2017-07-09, updated = 2019-02-16]
+% {\file_get_timestamp:nN, \file_get_timestamp:VN}
+% \begin{syntax}
+% \cs{file_get_timestamp:nN} \Arg{file name} \meta{tl var}
+% \end{syntax}
+% Sets the \meta{tl var} to the result of applying
+% \cs{file_timestamp:n} to the \meta{file}. If the file is not found,
+% the \meta{tl var} will be set to \cs{q_no_value}.
+% This is not available in older versions of \XeTeX{}.
+% \end{function}
+%
+% \begin{function}[added = 2019-05-13, updated = 2019-09-20, pTF, EXP]
+% {
+% \file_compare_timestamp:nNn,
+% \file_compare_timestamp:nNV,
+% \file_compare_timestamp:VNn,
+% \file_compare_timestamp:VNV
+% }
+% \begin{syntax}
+% \cs{file_compare_timestamp_p:nNn} \Arg{file-1} \meta{comparator} \Arg{file-2}
+% \cs{file_compare_timestamp:nNnTF} \Arg{file-1} \meta{comparator} \Arg{file-2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Compares the file stamps on the two \meta{files} as indicated by
+% the \meta{comparator}, and inserts either the \meta{true code}
+% or \meta{false case} as required. A file which is not found
+% is treated as older than any file which is found. This allows for
+% example the construct
+% \begin{verbatim}
+% \file_compare_timestamp:nNnT { source-file } > { derived-file }
+% {
+% % Code to regenerate derived file
+% }
+% \end{verbatim}
+% to work when the derived file is entirely absent. The timestamp
+% of two absent files is regarded as different.
+% This is not available in older versions of \XeTeX{}.
+% \end{function}
+%
+% \begin{function}[noTF, updated = 2019-02-16]
+% {\file_get_full_name:nN, \file_get_full_name:VN}
+% \begin{syntax}
+% \cs{file_get_full_name:nN} \Arg{file name} \meta{tl}
+% \cs{file_get_full_name:nNTF} \Arg{file name} \meta{tl} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Searches for \meta{file name} in the path as detailed for
+% \cs{file_if_exist:nTF}, and if found sets the \meta{tl var} the
+% fully-qualified name of the file, \emph{i.e.}~the path and file name.
+% This includes an extension |.tex| when the given \meta{file name}
+% has no extension but the file found has that extension.
+% In the non-branching version, the \meta{tl var} will be set to
+% \cs{q_no_value} in the case that the file does not exist.
+% \end{function}
+%
+% \begin{function}[added = 2019-09-03, rEXP]{\file_full_name:n, \file_full_name:V}
+% \begin{syntax}
+% \cs{file_full_name:n} \Arg{file name}
+% \end{syntax}
+% Searches for \meta{file name} in the path as detailed for
+% \cs{file_if_exist:nTF}, and if found leaves the
+% fully-qualified name of the file, \emph{i.e.}~the path and file name,
+% in the input stream.
+% This includes an extension |.tex| when the given \meta{file name}
+% has no extension but the file found has that extension.
+% If the file is not found on the path, the expansion is empty.
+% \end{function}
+%
+% \begin{function}[added = 2017-06-23, updated = 2020-06-24]
+% {\file_parse_full_name:nNNN, \file_parse_full_name:VNNN}
+% \begin{syntax}
+% \cs{file_parse_full_name:nNNN} \Arg{full name} \meta{dir} \meta{name} \meta{ext}
+% \end{syntax}
+% Parses the \meta{full name} and splits it into three parts, each of
+% which is returned by setting the appropriate local string variable:
+% \begin{itemize}
+% \item The \meta{dir}: everything up to the last |/| (path separator)
+% in the \meta{file path}. As with system \texttt{PATH} variables
+% and related functions, the \meta{dir} does \emph{not} include the
+% trailing |/| unless it points to the root directory. If there is no path (only
+% a file name), \meta{dir} is empty.
+% \item The \meta{name}: everything after the last |/| up to the last |.|,
+% where both of those characters are optional. The \meta{name} may
+% contain multiple |.| characters. It is empty if \meta{full name}
+% consists only of a directory name.
+% \item The \meta{ext}: everything after the last |.| (including the dot).
+% The \meta{ext} is empty if there is no |.| after the last |/|.
+% \end{itemize}
+%
+% Before parsing, the \meta{full name} is expanded until only non-expandable
+% tokens remain, except that active characters are also not expanded.
+% Quotes (|"|) are invalid in file names and are discarded from the input.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2020-06-24]
+% {\file_parse_full_name:n, \file_parse_full_name:V}
+% \begin{syntax}
+% \cs{file_parse_full_name:n} \Arg{full name}
+% \end{syntax}
+% Parses the \meta{full name} as described for \cs{file_parse_full_name:nNNN},
+% and leaves \meta{dir}, \meta{name}, and \meta{ext} in the input stream,
+% each inside a pair of braces.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2020-06-24]
+% {\file_parse_full_name_apply:nN, \file_parse_full_name_apply:VN}
+% \begin{syntax}
+% \cs{file_parse_full_name_apply:nN} \Arg{full name} \meta{function}
+% \end{syntax}
+% Parses the \meta{full name} as described for \cs{file_parse_full_name:nNNN},
+% and passes \meta{dir}, \meta{name}, and \meta{ext} as arguments to \meta{function},
+% as an \texttt{n}-type argument each, in this order.
+% \end{function}
+%
+% \subsection{Accessing file contents}
+%
+% \begin{function}[noTF, added = 2019-01-16, updated = 2019-02-16]
+% {\file_get:nnN, \file_get:VnN}
+% \begin{syntax}
+% \cs{file_get:nnN} \Arg{file name} \Arg{setup} \meta{tl}
+% \cs{file_get:nnNTF} \Arg{file name} \Arg{setup} \meta{tl} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Defines \meta{tl} to the contents of \meta{file name}.
+% Category codes may need to be set appropriately via the \meta{setup}
+% argument.
+% The non-branching version sets the \meta{tl} to \cs{q_no_value} if the file is
+% not found. The branching version runs the \meta{true code} after the
+% assignment to \meta{tl} if the file is found, and \meta{false code}
+% otherwise. The file content will be tokenized using the current
+% category code régime,
+% \end{function}
+%
+% \begin{function}[updated = 2017-06-26]{\file_input:n, \file_input:V}
+% \begin{syntax}
+% \cs{file_input:n} \Arg{file name}
+% \end{syntax}
+% Searches for \meta{file name} in the path as detailed for
+% \cs{file_if_exist:nTF}, and if found reads in the file as
+% additional \LaTeX{} source. All files read are recorded
+% for information and the file name stack is updated by this
+% function. An error is raised if the file is not found.
+% \end{function}
+%
+% \begin{function}[added = 2023-05-18, EXP]
+% {\file_input_raw:n, \file_input_raw:V}
+% \begin{syntax}
+% \cs{file_input_raw:n} \Arg{file name}
+% \end{syntax}
+% Searches for \meta{file name} in the path as detailed for
+% \cs{file_if_exist:nTF}, and if found reads in the file as
+% additional \TeX{} source. No data concerning the file is
+% tracked. If the file is not found, no action is taken.
+% \begin{texnote}
+% This function is intended only for contexts where files must
+% be read purely by expansion, for example at the start of a
+% table cell in an \tn{halign}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2014-07-02]
+% {
+% \file_if_exist_input:n,
+% \file_if_exist_input:V,
+% \file_if_exist_input:nF,
+% \file_if_exist_input:VF
+% }
+% \begin{syntax}
+% \cs{file_if_exist_input:n} \Arg{file name}
+% \cs{file_if_exist_input:nF} \Arg{file name} \Arg{false code}
+% \end{syntax}
+% Searches for \meta{file name} using the current \TeX{} search
+% path and the additional paths included in \cs{l_file_search_path_seq}.
+% If found then
+% reads in the file as additional \LaTeX{} source as described for
+% \cs{file_input:n}, otherwise inserts the \meta{false code}.
+% Note that these functions do not raise
+% an error if the file is not found, in contrast to \cs{file_input:n}.
+% \end{function}
+%
+% \begin{function}[added = 2017-07-07]{\file_input_stop:}
+% \begin{syntax}
+% \cs{file_input_stop:}
+% \end{syntax}
+% Ends the reading of a file started by \cs{file_input:n} or similar before
+% the end of the file is reached. Where the file reading is being terminated
+% due to an error, \cs[index = msg_critical:nn]{msg_critical:nn(nn)}
+% should be preferred.
+% \begin{texnote}
+% This function must be used on a line on its own: \TeX{} reads files
+% line-by-line and so any additional tokens in the \enquote{current} line
+% will still be read.
+%
+% This is also true if the function is hidden inside another function
+% (which will be the normal case), i.e., all tokens on the same line
+% in the source file are still processed. Putting it on a line by itself
+% in the definition doesn't help as it is the line where it is used that
+% counts!
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\file_show_list:, \file_log_list:}
+% \begin{syntax}
+% \cs{file_show_list:}
+% \cs{file_log_list:}
+% \end{syntax}
+% These functions list all files loaded by \LaTeXe{} commands that
+% populate \tn{@filelist} or by \cs{file_input:n}. While
+% \cs{file_show_list:} displays the list in the terminal,
+% \cs{file_log_list:} outputs it to the log file only.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3file} implementation}
+%
+% \TestFiles{m3file001}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \subsection{Input operations}
+%
+% \begin{macrocode}
+%<@@=ior>
+% \end{macrocode}
+%
+% \subsubsection{Variables and constants}
+%
+% \begin{variable}{\l_@@_internal_tl}
+% Used as a short-term scratch variable.
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_term_ior}
+% Reading from the terminal (with a prompt) is done using a positive
+% but non-existent stream number. Unlike writing, there is no concept
+% of reading from the log.
+% \begin{macrocode}
+\int_const:Nn \c_@@_term_ior { 16 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_streams_seq}
+% A list of the currently-available input streams to be used as a
+% stack.
+% \begin{macrocode}
+\seq_new:N \g_@@_streams_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_stream_tl}
+% Used to recover the raw stream number from the stack.
+% \begin{macrocode}
+\tl_new:N \l_@@_stream_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_streams_prop}
+% The name of the file attached to each stream is tracked in a property
+% list. To get the correct number of reserved streams in package mode the
+% underlying mechanism needs to be queried. For \LaTeXe{} and plain \TeX{}
+% this data is stored in |\count16|: with the \pkg{etex} package loaded
+% we need to subtract $1$ as the register holds the number of the next
+% stream to use. In \ConTeXt{}, we need to look at |\count38| but there
+% is no subtraction: like the original plain \TeX{}/\LaTeXe{} mechanism
+% it holds the value of the \emph{last} stream allocated.
+% \begin{macrocode}
+\prop_new:N \g_@@_streams_prop
+\int_step_inline:nnn
+ { 0 }
+ {
+ \cs_if_exist:NTF \contextversion
+ { \tex_count:D 38 ~ }
+ {
+ \tex_count:D 16 ~ %
+ \cs_if_exist:NT \loccount { - 1 }
+ }
+ }
+ {
+ \prop_gput:Nnn \g_@@_streams_prop {#1} { Reserved~by~format }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Stream management}
+%
+% \begin{macro}{\ior_new:N, \ior_new:c}
+% Reserving a new stream is done by defining the name as equal to using the
+% terminal.
+% \begin{macrocode}
+\cs_new_protected:Npn \ior_new:N #1 { \cs_new_eq:NN #1 \c_@@_term_ior }
+\cs_generate_variant:Nn \ior_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_tmpa_ior, \g_tmpb_ior}
+% The usual scratch space.
+% \begin{macrocode}
+\ior_new:N \g_tmpa_ior
+\ior_new:N \g_tmpb_ior
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\ior_open:Nn, \ior_open:cn}
+% Use the conditional version, with an error if the file is not found.
+% \begin{macrocode}
+\cs_new_protected:Npn \ior_open:Nn #1#2
+ { \ior_open:NnF #1 {#2} { \__kernel_file_missing:n {#2} } }
+\cs_generate_variant:Nn \ior_open:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_file_name_tl}
+% Data storage.
+% \begin{macrocode}
+\tl_new:N \l_@@_file_name_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[TF]{\ior_open:Nn, \ior_open:cn}
+% An auxiliary searches for the file in the \TeX{}, \LaTeXe{} and
+% \LaTeX3 paths. Then pass the file found to the lower-level function
+% which deals with streams. The |full_name| is empty when the file is
+% not found.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \ior_open:Nn #1#2 { T , F , TF }
+ {
+ \file_get_full_name:nNTF {#2} \l_@@_file_name_tl
+ {
+ \__kernel_ior_open:No #1 \l_@@_file_name_tl
+ \prg_return_true:
+ }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn \ior_open:Nn { c } { T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_new:N}
+% Streams are reserved using \tn{newread} before they
+% can be managed by \pkg{ior}. To prevent \pkg{ior} from being
+% affected by redefinitions of \tn{newread} (such as done by the
+% third-party package \pkg{morewrites}), this macro is saved here
+% under a private name. The complicated code ensures that
+% \cs{@@_new:N} is not \tn{outer} despite plain \TeX{}'s \tn{newread}
+% being \tn{outer}. For \ConTeXt{}, we have to deal with the fact
+% that \tn{newread} works like our own: it actually checks before
+% altering definition.
+% \begin{macrocode}
+\exp_args:NNf \cs_new_protected:Npn \@@_new:N
+ { \exp_args:NNc \exp_after:wN \exp_stop_f: { newread } }
+\cs_if_exist:NT \contextversion
+ {
+ \cs_new_eq:NN \@@_new_aux:N \@@_new:N
+ \cs_gset_protected:Npn \@@_new:N #1
+ {
+ \cs_undefine:N #1
+ \@@_new_aux:N #1
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_ior_open:Nn, \__kernel_ior_open:No}
+% \begin{macro}{\@@_open_stream:Nn}
+% The stream allocation itself uses the fact that there is a list of all of
+% those available. Life gets more complex as it's
+% important to keep things in sync. That is done using a two-part approach:
+% any streams that have already been taken up by \pkg{ior} but are now free
+% are tracked, so we first try those. If that fails, ask plain \TeX{} or \LaTeXe{}
+% for a new stream and use that number (after a bit of conversion).
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_ior_open:Nn #1#2
+ {
+ \ior_close:N #1
+ \seq_gpop:NNTF \g_@@_streams_seq \l_@@_stream_tl
+ { \@@_open_stream:Nn #1 {#2} }
+ {
+ \@@_new:N #1
+ \__kernel_tl_set:Nx \l_@@_stream_tl { \int_eval:n {#1} }
+ \@@_open_stream:Nn #1 {#2}
+ }
+ }
+\cs_generate_variant:Nn \__kernel_ior_open:Nn { No }
+% \end{macrocode}
+% Here, we act defensively in case \LuaTeX{} is in use with an
+% extensionless file name.
+% \begin{macrocode}
+\cs_new_protected:Npe \@@_open_stream:Nn #1#2
+ {
+ \tex_global:D \tex_chardef:D #1 = \exp_not:N \l_@@_stream_tl \scan_stop:
+ \prop_gput:NVn \exp_not:N \g_@@_streams_prop #1 {#2}
+ \tex_openin:D #1
+ \sys_if_engine_luatex:TF
+ { {#2} }
+ { \exp_not:N \__kernel_file_name_quote:n {#2} \scan_stop: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ior_shell_open:Nn}
+% \begin{macro}{\@@_shell_open:nN, \@@_shell_open:oN}
+% Actually much easier than either the standard open or input versions!
+% When calling \cs{__kernel_ior_open:Nn} the file the pipe is added to
+% signal a shell command, but the quotes are not added yet---they are
+% added later by \cs{__kernel_file_name_quote:n}.
+% \begin{macrocode}
+\cs_new_protected:Npn \ior_shell_open:Nn #1#2
+ {
+ \sys_if_shell:TF
+ { \@@_shell_open:oN { \tl_to_str:n {#2} } #1 }
+ { \msg_error:nn { kernel } { pipe-failed } }
+ }
+\cs_new_protected:Npn \@@_shell_open:nN #1#2
+ {
+ \tl_if_in:nnTF {#1} { " }
+ {
+ \msg_error:nne
+ { kernel } { quote-in-shell } {#1}
+ }
+ { \__kernel_ior_open:Nn #2 { |#1 } }
+ }
+\cs_generate_variant:Nn \@@_shell_open:nN { o }
+\msg_new:nnnn { kernel } { pipe-failed }
+ { Cannot~run~piped~system~commands. }
+ {
+ LaTeX~tried~to~call~a~system~process~but~this~was~not~possible.\\
+ Try~the~"--shell-escape"~(or~"--enable-pipes")~option.
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ior_close:N, \ior_close:c}
+% Closing a stream means getting rid of it at the \TeX{} level and
+% removing from the various data structures. Unless the name passed
+% is an invalid stream number (outside the range $[0,15]$), it can be
+% closed. On the other hand, it only gets added to the stack if it
+% was not already there, to avoid duplicates building up.
+% \begin{macrocode}
+\cs_new_protected:Npn \ior_close:N #1
+ {
+ \int_compare:nT { -1 < #1 < \c_@@_term_ior }
+ {
+ \tex_closein:D #1
+ \prop_gremove:NV \g_@@_streams_prop #1
+ \seq_if_in:NVF \g_@@_streams_seq #1
+ { \seq_gpush:NV \g_@@_streams_seq #1 }
+ \cs_gset_eq:NN #1 \c_@@_term_ior
+ }
+ }
+\cs_generate_variant:Nn \ior_close:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ior_show:N, \ior_log:N, \@@_show:NN}
+% Seek the stream in the \cs{g_@@_streams_prop} list, then show the
+% stream as open or closed accordingly.
+% \begin{macrocode}
+\cs_new_protected:Npn \ior_show:N { \@@_show:NN \tl_show:n }
+\cs_generate_variant:Nn \ior_show:N { c }
+\cs_new_protected:Npn \ior_log:N { \@@_show:NN \tl_log:n }
+\cs_generate_variant:Nn \ior_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_chk_defined:NT #2
+ {
+ \prop_get:NVNTF \g_@@_streams_prop #2 \l_@@_internal_tl
+ {
+ \exp_args:Ne #1
+ { \token_to_str:N #2 ~ open: ~ \l_@@_internal_tl }
+ }
+ { \exp_args:Ne #1 { \token_to_str:N #2 ~ closed } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ior_show_list:, \ior_log_list:}
+% \begin{macro}{\@@_list:N}
+% Show the property lists, but with some \enquote{pretty printing}.
+% See the \pkg{l3msg} module. The first argument of the message is
+% |ior| (as opposed to |iow|) and the second is empty if no read
+% stream is open and non-empty (the list of streams formatted using
+% \cs{msg_show_item_unbraced:nn}) otherwise. The code of the message
+% \texttt{show-streams} takes care of translating |ior|/|iow| to
+% English.
+% \begin{macrocode}
+\cs_new_protected:Npn \ior_show_list: { \@@_list:N \msg_show:nneeee }
+\cs_new_protected:Npn \ior_log_list: { \@@_list:N \msg_log:nneeee }
+\cs_new_protected:Npn \@@_list:N #1
+ {
+ #1 { kernel } { show-streams }
+ { ior }
+ {
+ \prop_map_function:NN \g_@@_streams_prop
+ \msg_show_item_unbraced:nn
+ }
+ { } { }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Reading input}
+%
+% \begin{macro}{\if_eof:w}
+% The primitive conditional
+% \begin{macrocode}
+\cs_new_eq:NN \if_eof:w \tex_ifeof:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\ior_if_eof:N}
+% To test if some particular input stream is exhausted the following
+% conditional is provided. The primitive test can only deal with
+% numbers in the range $[0,15]$ so we catch outliers (they are
+% exhausted).
+% \begin{macrocode}
+\prg_new_conditional:Npnn \ior_if_eof:N #1 { p , T , F , TF }
+ {
+ \if_int_compare:w -1 < #1
+ \if_int_compare:w #1 < \c_@@_term_ior
+ \if_eof:w #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ \else:
+ \prg_return_true:
+ \fi:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ior_get:NN, \@@_get:NN}
+% \begin{macro}[TF]{\ior_get:NN}
+% And here we read from files.
+% \begin{macrocode}
+\cs_new_protected:Npn \ior_get:NN #1#2
+ { \ior_get:NNF #1 #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_new_protected:Npn \@@_get:NN #1#2
+ { \tex_read:D #1 to #2 }
+\prg_new_protected_conditional:Npnn \ior_get:NN #1#2 { T , F , TF }
+ {
+ \ior_if_eof:NTF #1
+ { \prg_return_false: }
+ {
+ \@@_get:NN #1 #2
+ \prg_return_true:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ior_str_get:NN, \@@_str_get:NN}
+% \begin{macro}[TF]{\ior_str_get:NN}
+% Reading as strings is a more complicated wrapper, as we wish to
+% remove the endline character and restore it afterwards.
+% \begin{macrocode}
+\cs_new_protected:Npn \ior_str_get:NN #1#2
+ { \ior_str_get:NNF #1 #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_new_protected:Npn \@@_str_get:NN #1#2
+ {
+ \exp_args:Nno \use:n
+ {
+ \int_set:Nn \tex_endlinechar:D { -1 }
+ \tex_readline:D #1 to #2
+ \int_set:Nn \tex_endlinechar:D
+ } { \int_use:N \tex_endlinechar:D }
+ }
+\prg_new_protected_conditional:Npnn \ior_str_get:NN #1#2 { T , F , TF }
+ {
+ \ior_if_eof:NTF #1
+ { \prg_return_false: }
+ {
+ \@@_str_get:NN #1 #2
+ \prg_return_true:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\c_@@_term_noprompt_ior}
+% For reading without a prompt.
+% \begin{macrocode}
+\int_const:Nn \c_@@_term_noprompt_ior { -1 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\ior_get_term:nN, \ior_str_get_term:nN}
+% \begin{macro}{\@@_get_term:NnN}
+% Getting from the terminal is better with pretty-printing.
+% \begin{macrocode}
+\cs_new_protected:Npn \ior_get_term:nN #1#2
+ { \@@_get_term:NnN \@@_get:NN {#1} #2 }
+\cs_new_protected:Npn \ior_str_get_term:nN #1#2
+ { \@@_get_term:NnN \@@_str_get:NN {#1} #2 }
+\cs_new_protected:Npn \@@_get_term:NnN #1#2#3
+ {
+ \group_begin:
+ \tex_escapechar:D = -1 \scan_stop:
+ \tl_if_blank:nTF {#2}
+ { \exp_args:NNc #1 \c_@@_term_noprompt_ior }
+ { \exp_args:NNc #1 \c_@@_term_ior }
+ {#2}
+ \exp_args:NNNv \group_end:
+ \tl_set:Nn #3 {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\ior_map_break:, \ior_map_break:n}
+% Usual map breaking functions.
+% \begin{macrocode}
+\cs_new:Npn \ior_map_break:
+ { \prg_map_break:Nn \ior_map_break: { } }
+\cs_new:Npn \ior_map_break:n
+ { \prg_map_break:Nn \ior_map_break: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ior_map_inline:Nn, \ior_str_map_inline:Nn}
+% \begin{macro}{\@@_map_inline:NNn}
+% \begin{macro}{\@@_map_inline:NNNn}
+% \begin{macro}{\@@_map_inline_loop:NNN}
+% Mapping over an input stream can be done on either a token or a string
+% basis, hence the set up. Within that, there is a check to avoid reading
+% past the end of a file, hence the two applications of \cs{ior_if_eof:N}
+% and its lower-level analogue \cs{if_eof:w}.
+% This mapping cannot be nested with twice the same stream, as the
+% stream has only one \enquote{current line}.
+% \begin{macrocode}
+\cs_new_protected:Npn \ior_map_inline:Nn
+ { \@@_map_inline:NNn \@@_get:NN }
+\cs_new_protected:Npn \ior_str_map_inline:Nn
+ { \@@_map_inline:NNn \@@_str_get:NN }
+\cs_new_protected:Npn \@@_map_inline:NNn
+ {
+ \int_gincr:N \g__kernel_prg_map_int
+ \exp_args:Nc \@@_map_inline:NNNn
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :n }
+ }
+\cs_new_protected:Npn \@@_map_inline:NNNn #1#2#3#4
+ {
+ \cs_gset_protected:Npn #1 ##1 {#4}
+ \ior_if_eof:NF #3 { \@@_map_inline_loop:NNN #1#2#3 }
+ \prg_break_point:Nn \ior_map_break:
+ { \int_gdecr:N \g__kernel_prg_map_int }
+ }
+\cs_new_protected:Npn \@@_map_inline_loop:NNN #1#2#3
+ {
+ #2 #3 \l_@@_internal_tl
+ \if_eof:w #3
+ \exp_after:wN \ior_map_break:
+ \fi:
+ \exp_args:No #1 \l_@@_internal_tl
+ \@@_map_inline_loop:NNN #1#2#3
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ior_map_variable:NNn, \ior_str_map_variable:NNn}
+% \begin{macro}{\@@_map_variable:NNNn}
+% \begin{macro}{\@@_map_variable_loop:NNNn}
+% Since the \TeX{} primitive (\tn{read} or \tn{readline}) assigns the
+% tokens read in the same way as a token list assignment, we simply
+% call the appropriate primitive. The end-of-loop is checked using
+% the primitive conditional for speed.
+% \begin{macrocode}
+\cs_new_protected:Npn \ior_map_variable:NNn
+ { \@@_map_variable:NNNn \ior_get:NN }
+\cs_new_protected:Npn \ior_str_map_variable:NNn
+ { \@@_map_variable:NNNn \ior_str_get:NN }
+\cs_new_protected:Npn \@@_map_variable:NNNn #1#2#3#4
+ {
+ \ior_if_eof:NF #2 { \@@_map_variable_loop:NNNn #1#2#3 {#4} }
+ \prg_break_point:Nn \ior_map_break: { }
+ }
+\cs_new_protected:Npn \@@_map_variable_loop:NNNn #1#2#3#4
+ {
+ #1 #2 #3
+ \if_eof:w #2
+ \exp_after:wN \ior_map_break:
+ \fi:
+ #4
+ \@@_map_variable_loop:NNNn #1#2#3 {#4}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Output operations}
+%
+% \begin{macrocode}
+%<@@=iow>
+% \end{macrocode}
+%
+% There is a lot of similarity here to the input operations, at least for
+% many of the basics. Thus quite a bit is copied from the earlier material
+% with minor alterations.
+%
+% \subsubsection{Variables and constants}
+%
+% \begin{variable}{\l_@@_internal_tl}
+% Used as a short-term scratch variable.
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_log_iow, \c_term_iow}
+% Here we allocate two output streams for writing to the transcript
+% file only (\cs{c_log_iow}) and to both the terminal and transcript
+% file (\cs{c_term_iow}). Recent \LuaTeX{} provide $128$ write
+% streams; we also use \cs{c_term_iow} as the first non-allowed write
+% stream so its value depends on the engine.
+% \begin{macrocode}
+\int_const:Nn \c_log_iow { -1 }
+\int_const:Nn \c_term_iow
+ {
+ \bool_lazy_and:nnTF
+ { \sys_if_engine_luatex_p: }
+ { \int_compare_p:nNn \tex_luatexversion:D > { 80 } }
+ { 128 }
+ { 16 }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_streams_seq}
+% A list of the currently-available output streams to be used as a
+% stack.
+% \begin{macrocode}
+\seq_new:N \g_@@_streams_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_stream_tl}
+% Used to recover the raw stream number from the stack.
+% \begin{macrocode}
+\tl_new:N \l_@@_stream_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_streams_prop}
+% As for reads with the appropriate adjustment of the register numbers to
+% check on.
+% \begin{macrocode}
+\prop_new:N \g_@@_streams_prop
+\int_step_inline:nnn
+ { 0 }
+ {
+ \cs_if_exist:NTF \contextversion
+ { \tex_count:D 39 ~ }
+ {
+ \tex_count:D 17 ~
+ \cs_if_exist:NT \loccount { - 1 }
+ }
+ }
+ {
+ \prop_gput:Nnn \g_@@_streams_prop {#1} { Reserved~by~format }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Internal auxiliaries}
+%
+% \begin{variable}{\s_@@_mark,\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_use_i_delimit_by_s_stop:nw}
+% Functions to gobble up to a scan mark.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_i_delimit_by_s_stop:nw #1 #2 \s_@@_stop {#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\q_@@_nil}
+% Internal quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_nil
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Stream management}
+%
+% \begin{macro}{\iow_new:N, \iow_new:c}
+% Reserving a new stream is done by defining the name as equal to writing
+% to the terminal: odd but at least consistent.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_new:N #1 { \cs_new_eq:NN #1 \c_term_iow }
+\cs_generate_variant:Nn \iow_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_tmpa_iow, \g_tmpb_iow}
+% The usual scratch space.
+% \begin{macrocode}
+\iow_new:N \g_tmpa_iow
+\iow_new:N \g_tmpb_iow
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_new:N}
+% As for read streams, copy \tn{newwrite}, making sure
+% that it is not \tn{outer}. For \ConTeXt{}, we have to
+% deal with the fact that \tn{newwrite} works like our
+% own: it actually checks before altering definition.
+% \begin{macrocode}
+\exp_args:NNf \cs_new_protected:Npn \@@_new:N
+ { \exp_args:NNc \exp_after:wN \exp_stop_f: { newwrite } }
+\cs_if_exist:NT \contextversion
+ {
+ \cs_new_eq:NN \@@_new_aux:N \@@_new:N
+ \cs_gset_protected:Npn \@@_new:N #1
+ {
+ \cs_undefine:N #1
+ \@@_new_aux:N #1
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_file_name_tl}
+% Data storage.
+% \begin{macrocode}
+\tl_new:N \l_@@_file_name_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\iow_open:Nn, \iow_open:NV, \iow_open:cn, \iow_open:cV}
+% \begin{macro}{\__kernel_iow_open:Nn, \__kernel_iow_open:No}
+% \begin{macro}{\@@_open_stream:Nn, \@@_open_stream:NV}
+% The same idea as for reading, but without the path and without the need
+% to allow for a conditional version.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_open:Nn #1#2
+ {
+ \__kernel_tl_set:Nx \l_@@_file_name_tl
+ { \__kernel_file_name_sanitize:n {#2} }
+ \__kernel_iow_open:No #1 \l_@@_file_name_tl
+ }
+\cs_generate_variant:Nn \iow_open:Nn { NV , c , cV }
+\cs_new_protected:Npn \__kernel_iow_open:Nn #1#2
+ {
+ \iow_close:N #1
+ \seq_gpop:NNTF \g_@@_streams_seq \l_@@_stream_tl
+ { \@@_open_stream:Nn #1 {#2} }
+ {
+ \@@_new:N #1
+ \__kernel_tl_set:Nx \l_@@_stream_tl { \int_eval:n {#1} }
+ \@@_open_stream:Nn #1 {#2}
+ }
+ }
+\cs_generate_variant:Nn \__kernel_iow_open:Nn { No }
+\cs_new_protected:Npn \@@_open_stream:Nn #1#2
+ {
+ \tex_global:D \tex_chardef:D #1 = \l_@@_stream_tl \scan_stop:
+ \prop_gput:NVn \g_@@_streams_prop #1 {#2}
+ \tex_immediate:D \tex_openout:D
+ #1 \__kernel_file_name_quote:n {#2} \scan_stop:
+ }
+\cs_generate_variant:Nn \@@_open_stream:Nn { NV }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\iow_shell_open:Nn}
+% \begin{macro}{\@@_shell_open:nN, \@@_shell_open:oN}
+% Very similar to the \texttt{ior} version
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_shell_open:Nn #1#2
+ {
+ \sys_if_shell:TF
+ { \@@_shell_open:oN { \tl_to_str:n {#2} } #1 }
+ { \msg_error:nn { kernel } { pipe-failed } }
+ }
+\cs_new_protected:Npn \@@_shell_open:nN #1#2
+ {
+ \tl_if_in:nnTF {#1} { " }
+ {
+ \msg_error:nne
+ { kernel } { quote-in-shell } {#1}
+ }
+ { \__kernel_iow_open:Nn #2 { |#1 } }
+ }
+\cs_generate_variant:Nn \@@_shell_open:nN { o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\iow_close:N, \iow_close:c}
+% Closing a stream is not quite the reverse of opening one. First,
+% the close operation is easier than the open one, and second as the
+% stream is actually a number we can use it directly to show that the
+% slot has been freed up.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_close:N #1
+ {
+ \int_compare:nT { \c_log_iow < #1 < \c_term_iow }
+ {
+ \tex_immediate:D \tex_closeout:D #1
+ \prop_gremove:NV \g_@@_streams_prop #1
+ \seq_if_in:NVF \g_@@_streams_seq #1
+ { \seq_gpush:NV \g_@@_streams_seq #1 }
+ \cs_gset_eq:NN #1 \c_term_iow
+ }
+ }
+\cs_generate_variant:Nn \iow_close:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\iow_show:N, \iow_log:N, \@@_show:NN}
+% Seek the stream in the \cs{g_@@_streams_prop} list, then show the
+% stream as open or closed accordingly.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_show:N { \@@_show:NN \tl_show:n }
+\cs_generate_variant:Nn \iow_show:N { c }
+\cs_new_protected:Npn \iow_log:N { \@@_show:NN \tl_log:n }
+\cs_generate_variant:Nn \iow_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_chk_defined:NT #2
+ {
+ \prop_get:NVNTF \g_@@_streams_prop #2 \l_@@_internal_tl
+ {
+ \exp_args:Ne #1
+ { \token_to_str:N #2 ~ open: ~ \l_@@_internal_tl }
+ }
+ { \exp_args:Ne #1 { \token_to_str:N #2 ~ closed } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\iow_show_list:, \iow_log_list:}
+% \begin{macro}{\@@_list:N}
+% Done as for input, but with a copy of the auxiliary so the name is correct.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_show_list: { \@@_list:N \msg_show:nneeee }
+\cs_new_protected:Npn \iow_log_list: { \@@_list:N \msg_log:nneeee }
+\cs_new_protected:Npn \@@_list:N #1
+ {
+ #1 { kernel } { show-streams }
+ { iow }
+ {
+ \prop_map_function:NN \g_@@_streams_prop
+ \msg_show_item_unbraced:nn
+ }
+ { } { }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Deferred writing}
+%
+% \begin{macro}
+% {
+% \iow_shipout_e:Nn, \iow_shipout_e:Ne,
+% \iow_shipout_e:cn, \iow_shipout_e:ce
+% }
+% First the easy part, this is the primitive, which expects its
+% argument to be braced.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_shipout_e:Nn #1#2
+ { \tex_write:D #1 {#2} }
+\cs_generate_variant:Nn \iow_shipout_e:Nn { Ne , c, ce }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \iow_shipout:Nn, \iow_shipout:Ne,
+% \iow_shipout:Nx,
+% \iow_shipout:cn, \iow_shipout:ce,
+% \iow_shipout:cx
+% }
+% With \eTeX{} available deferred writing without expansion is easy.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_shipout:Nn #1#2
+ { \tex_write:D #1 { \exp_not:n {#2} } }
+\cs_generate_variant:Nn \iow_shipout:Nn { Ne , c, ce }
+\cs_generate_variant:Nn \iow_shipout:Nn { Nx , cx }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Immediate writing}
+%
+% \begin{macro}{\__kernel_iow_with:Nnn}
+% \begin{macro}{\@@_with:nNnn, \@@_with:oNnn}
+% If the integer~|#1| is equal to~|#2|, just leave~|#3| in the input
+% stream. Otherwise, pass the old value to an auxiliary, which sets
+% the integer to the new value, runs the code, and restores the
+% integer.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_iow_with:Nnn #1#2
+ {
+ \int_compare:nNnTF {#1} = {#2}
+ { \use:n }
+ { \@@_with:oNnn { \int_use:N #1 } #1 {#2} }
+ }
+\cs_new_protected:Npn \@@_with:nNnn #1#2#3#4
+ {
+ \int_set:Nn #2 {#3}
+ #4
+ \int_set:Nn #2 {#1}
+ }
+\cs_generate_variant:Nn \@@_with:nNnn { o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \iow_now:Nn, \iow_now:NV, \iow_now:Ne,
+% \iow_now:Nx,
+% \iow_now:cn, \iow_now:cV, \iow_now:ce,
+% \iow_now:cx
+% }
+% This routine writes the second argument onto the output stream without
+% expansion. If this stream isn't open, the output goes to the terminal
+% instead. If the first argument is no output stream at all, we get an
+% internal error. We don't use the expansion done by \tn{write} to
+% get the |Nx| variant, because it differs in subtle ways from
+% \texttt{x}-expansion, namely, macro parameter characters would not
+% need to be doubled. We set the \tn{newlinechar} to~$10$ using
+% \cs{__kernel_iow_with:Nnn} to support formats such as plain \TeX{}: otherwise,
+% \cs{iow_newline:} would not work. We do not do this for
+% \cs{iow_shipout:Nn} or \cs{iow_shipout_x:Nn}, as \TeX{} looks at the
+% value of the \tn{newlinechar} at shipout time in those cases.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_now:Nn #1#2
+ {
+ \__kernel_iow_with:Nnn \tex_newlinechar:D { `\^^J }
+ { \tex_immediate:D \tex_write:D #1 { \exp_not:n {#2} } }
+ }
+\cs_generate_variant:Nn \iow_now:Nn { NV , Ne , c , cV , ce }
+\cs_generate_variant:Nn \iow_now:Nn { Nx , cx }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\iow_log:n, \iow_log:e, \iow_log:x}
+% \begin{macro}{\iow_term:n, \iow_term:e, \iow_term:x}
+% Writing to the log and the terminal directly are relatively easy;
+% as we need the two \texttt{e}-type variants for bootstrapping,
+% they are redefinitions here.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_log:n { \iow_now:Nn \c_log_iow }
+\cs_set_protected:Npn \iow_log:e { \iow_now:Ne \c_log_iow }
+\cs_generate_variant:Nn \iow_log:n { x }
+\cs_new_protected:Npn \iow_term:n { \iow_now:Nn \c_term_iow }
+\cs_set_protected:Npn \iow_term:e { \iow_now:Ne \c_term_iow }
+\cs_generate_variant:Nn \iow_term:n { x }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Special characters for writing}
+%
+% \begin{macro}{\iow_newline:}
+% Global variable holding the character that forces a new line when
+% something is written to an output stream.
+% \begin{macrocode}
+\cs_new:Npn \iow_newline: { ^^J }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\iow_char:N}
+% Function to write any escaped char to an output stream.
+% \begin{macrocode}
+\cs_new_eq:NN \iow_char:N \cs_to_str:N
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Hard-wrapping lines to a character count}
+%
+% The code here implements a generic hard-wrapping function. This is
+% used by the messaging system, but is designed such that it is
+% available for other uses.
+%
+% \begin{variable}{\l_iow_line_count_int}
+% This is the \enquote{raw} number of characters in a line which
+% can be written to the terminal.
+% The standard value is the line length typically used by
+% \TeX{} Live and \hologo{MiKTeX}.
+% \begin{macrocode}
+\int_new:N \l_iow_line_count_int
+\int_set:Nn \l_iow_line_count_int { 78 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_newline_tl}
+% The token list inserted to produce a new line, with the
+% \meta{run-on text}.
+% \begin{macrocode}
+\tl_new:N \l_@@_newline_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_line_target_int}
+% This stores the target line count: the full number of characters
+% in a line, minus any part for a leader at the start of each line.
+% \begin{macrocode}
+\int_new:N \l_@@_line_target_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_set_indent:n}
+% \begin{macro}{\@@_unindent:w}
+% \begin{variable}{\l_@@_one_indent_tl, \l_@@_one_indent_int}
+% The \texttt{one_indent} variables hold one indentation marker and
+% its length. The \cs{@@_unindent:w} auxiliary removes one
+% indentation. The function \cs{@@_set_indent:n} (that could possibly
+% be public) sets the indentation in a consistent way. We set it to
+% four spaces by default.
+% \begin{macrocode}
+\tl_new:N \l_@@_one_indent_tl
+\int_new:N \l_@@_one_indent_int
+\cs_new:Npn \@@_unindent:w { }
+\cs_new_protected:Npn \@@_set_indent:n #1
+ {
+ \__kernel_tl_set:Nx \l_@@_one_indent_tl
+ { \exp_args:No \__kernel_str_to_other_fast:n { \tl_to_str:n {#1} } }
+ \int_set:Nn \l_@@_one_indent_int
+ { \str_count:N \l_@@_one_indent_tl }
+ \exp_last_unbraced:NNo
+ \cs_set:Npn \@@_unindent:w \l_@@_one_indent_tl { }
+ }
+\exp_args:Ne \@@_set_indent:n { \prg_replicate:nn { 4 } { ~ } }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_indent_tl, \l_@@_indent_int}
+% The current indentation (some copies of \cs{l_@@_one_indent_tl}) and
+% its number of characters.
+% \begin{macrocode}
+\tl_new:N \l_@@_indent_tl
+\int_new:N \l_@@_indent_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_line_tl, \l_@@_line_part_tl}
+% These hold the current line of text and a partial line to be added
+% to it, respectively.
+% \begin{macrocode}
+\tl_new:N \l_@@_line_tl
+\tl_new:N \l_@@_line_part_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_line_break_bool}
+% Indicates whether the line was broken precisely at a chunk boundary.
+% \begin{macrocode}
+\bool_new:N \l_@@_line_break_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_wrap_tl}
+% Used for the expansion step before detokenizing, and for the output
+% from wrapping text: fully expanded and with lines which are not
+% overly long.
+% \begin{macrocode}
+\tl_new:N \l_@@_wrap_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_wrap_marker_tl}
+% \begin{variable}
+% {
+% \c_@@_wrap_end_marker_tl,
+% \c_@@_wrap_newline_marker_tl,
+% \c_@@_wrap_allow_break_marker_tl,
+% \c_@@_wrap_indent_marker_tl,
+% \c_@@_wrap_unindent_marker_tl
+% }
+% Every special action of the wrapping code is starts with
+% the same recognizable string, \cs{c_@@_wrap_marker_tl}.
+% Upon seeing that \enquote{word}, the wrapping code reads
+% one space-delimited argument to know what operation to
+% perform. The setting of \tn{escapechar} here is not
+% very important, but makes \cs{c_@@_wrap_marker_tl} look
+% marginally nicer.
+% \begin{macrocode}
+\group_begin:
+ \int_set:Nn \tex_escapechar:D { -1 }
+ \tl_const:Ne \c_@@_wrap_marker_tl
+ { \tl_to_str:n { \^^I \^^O \^^W \^^_ \^^W \^^R \^^A \^^P } }
+\group_end:
+\tl_map_inline:nn
+ { { end } { newline } { allow_break } { indent } { unindent } }
+ {
+ \tl_const:ce { c_@@_wrap_ #1 _marker_tl }
+ {
+ \c_@@_wrap_marker_tl
+ #1
+ \c_catcode_other_space_tl
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}{\iow_wrap_allow_break:}
+% \begin{macro}[EXP]{\@@_wrap_allow_break:}
+% \begin{macro}[EXP]{\@@_wrap_allow_break_error:}
+% We set \cs{iow_wrap_allow_break:n} to produce an error when outside
+% messages. Within wrapped message, it is set to \cs{@@_wrap_allow_break:}
+% when valid and otherwise to \cs{@@_wrap_allow_break_error:}. The second
+% produces an error expandably.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_wrap_allow_break:
+ {
+ \msg_error:nnnn { kernel } { iow-indent }
+ { \iow_wrap:nnnN } { \iow_wrap_allow_break: }
+ }
+\cs_new:Npe \@@_wrap_allow_break: { \c_@@_wrap_allow_break_marker_tl }
+\cs_new:Npn \@@_wrap_allow_break_error:
+ {
+ \msg_expandable_error:nnnn { kernel } { iow-indent }
+ { \iow_wrap:nnnN } { \iow_wrap_allow_break: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\iow_indent:n}
+% \begin{macro}[EXP]{\@@_indent:n}
+% \begin{macro}[EXP]{\@@_indent_error:n}
+% We set \cs{iow_indent:n} to produce an error when outside
+% messages. Within wrapped message, it is set to \cs{@@_indent:n} when
+% valid and otherwise to \cs{@@_indent_error:n}. The first places the
+% instruction for increasing the indentation before its argument, and
+% the instruction for unindenting afterwards. The second produces an
+% error expandably. Note that there are no forced line-break, so
+% the indentation only changes when the next line is started.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_indent:n #1
+ {
+ \msg_error:nnnnn { kernel } { iow-indent }
+ { \iow_wrap:nnnN } { \iow_indent:n } {#1}
+ #1
+ }
+\cs_new:Npe \@@_indent:n #1
+ {
+ \c_@@_wrap_indent_marker_tl
+ #1
+ \c_@@_wrap_unindent_marker_tl
+ }
+\cs_new:Npn \@@_indent_error:n #1
+ {
+ \msg_expandable_error:nnnnn { kernel } { iow-indent }
+ { \iow_wrap:nnnN } { \iow_indent:n } {#1}
+ #1
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\iow_wrap:nnnN, \iow_wrap:nenN}
+% The main wrapping function works as follows. First give |\\|,
+% \verb*|\ | and other formatting commands the correct definition for
+% messages and perform the given setup~|#3|. The definition of
+% \verb*|\ | uses an \enquote{other} space rather than a normal space,
+% because the latter might be absorbed by \TeX{} to end a number or
+% other \texttt{f}-type expansions.
+% Use \cs{conditionally@traceoff} if defined; it is introduced by the
+% \pkg{trace} package and suppresses uninteresting tracing of the
+% wrapping code.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_wrap:nnnN #1#2#3#4
+ {
+ \group_begin:
+ \cs_if_exist_use:N \conditionally@traceoff
+ \int_set:Nn \tex_escapechar:D { -1 }
+ \cs_set:Npe \{ { \token_to_str:N \{ }
+ \cs_set:Npe \# { \token_to_str:N \# }
+ \cs_set:Npe \} { \token_to_str:N \} }
+ \cs_set:Npe \% { \token_to_str:N \% }
+ \cs_set:Npe \~ { \token_to_str:N \~ }
+ \int_set:Nn \tex_escapechar:D { 92 }
+ \cs_set_eq:NN \\ \iow_newline:
+ \cs_set_eq:NN \ \c_catcode_other_space_tl
+ \cs_set_eq:NN \iow_wrap_allow_break: \@@_wrap_allow_break:
+ \cs_set_eq:NN \iow_indent:n \@@_indent:n
+ #3
+% \end{macrocode}
+% Then fully-expand the input: in package mode, the expansion uses
+% \LaTeXe{}'s \tn{protect} mechanism in the same way as \tn{typeout}.
+% In generic mode this setting is useless but harmless. As soon as
+% the expansion is done, reset \cs{iow_indent:n} to its error
+% definition: it only works in the first argument of
+% \cs{iow_wrap:nnnN}.
+% \begin{macrocode}
+ \cs_set_eq:NN \protect \token_to_str:N
+ \__kernel_tl_set:Nx \l_@@_wrap_tl {#1}
+ \cs_set_eq:NN \iow_wrap_allow_break: \@@_wrap_allow_break_error:
+ \cs_set_eq:NN \iow_indent:n \@@_indent_error:n
+% \end{macrocode}
+% Afterwards, set the newline marker (two assignments to fully expand,
+% then convert to a string) and initialize the target count for lines
+% (the first line has target count \cs{l_iow_line_count_int} instead).
+% \begin{macrocode}
+ \__kernel_tl_set:Nx \l_@@_newline_tl { \iow_newline: #2 }
+ \__kernel_tl_set:Nx \l_@@_newline_tl { \tl_to_str:N \l_@@_newline_tl }
+ \int_set:Nn \l_@@_line_target_int
+ { \l_iow_line_count_int - \str_count:N \l_@@_newline_tl + 1 }
+% \end{macrocode}
+% Sanity check.
+% \begin{macrocode}
+ \int_compare:nNnT { \l_@@_line_target_int } < 0
+ {
+ \tl_set:Nn \l_@@_newline_tl { \iow_newline: }
+ \int_set:Nn \l_@@_line_target_int
+ { \l_iow_line_count_int + 1 }
+ }
+% \end{macrocode}
+% There is then a loop over the input, which stores the wrapped
+% result in \cs{l_@@_wrap_tl}. After the loop, the resulting text is
+% passed on to the function which has been given as a post-processor.
+% The \cs{tl_to_str:N} step converts the \enquote{other} spaces back
+% to normal spaces. The \texttt{f}-expansion removes a leading space
+% from \cs{l_@@_wrap_tl}.
+% \begin{macrocode}
+ \@@_wrap_do:
+ \exp_args:NNf \group_end:
+ #4 { \tl_to_str:N \l_@@_wrap_tl }
+ }
+\cs_generate_variant:Nn \iow_wrap:nnnN { ne }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_wrap_do:, \@@_wrap_fix_newline:w, \@@_wrap_start:w}
+% Escape spaces and change newlines to \cs{c_@@_wrap_newline_marker_tl}.
+% Set up a few variables, in particular the initial
+% value of \cs{l_@@_wrap_tl}: the space stops the
+% \texttt{f}-expansion of the main wrapping function and
+% \cs{use_none:n} removes a newline marker inserted by later code.
+% The main loop consists of repeatedly calling the \texttt{chunk}
+% auxiliary to wrap chunks delimited by (newline or indentation)
+% markers.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_wrap_do:
+ {
+ \__kernel_tl_set:Nx \l_@@_wrap_tl
+ {
+ \exp_args:No \__kernel_str_to_other_fast:n \l_@@_wrap_tl
+ \c_@@_wrap_end_marker_tl
+ }
+ \__kernel_tl_set:Nx \l_@@_wrap_tl
+ {
+ \exp_after:wN \@@_wrap_fix_newline:w \l_@@_wrap_tl
+ ^^J \q_@@_nil ^^J \s_@@_stop
+ }
+ \exp_after:wN \@@_wrap_start:w \l_@@_wrap_tl
+ }
+\cs_new:Npn \@@_wrap_fix_newline:w #1 ^^J #2 ^^J
+ {
+ #1
+ \if_meaning:w \q_@@_nil #2
+ \@@_use_i_delimit_by_s_stop:nw
+ \fi:
+ \c_@@_wrap_newline_marker_tl
+ \@@_wrap_fix_newline:w #2 ^^J
+ }
+\cs_new_protected:Npn \@@_wrap_start:w
+ {
+ \bool_set_false:N \l_@@_line_break_bool
+ \tl_clear:N \l_@@_line_tl
+ \tl_clear:N \l_@@_line_part_tl
+ \tl_set:Nn \l_@@_wrap_tl { ~ \use_none:n }
+ \int_zero:N \l_@@_indent_int
+ \tl_clear:N \l_@@_indent_tl
+ \@@_wrap_chunk:nw { \l_iow_line_count_int }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_wrap_chunk:nw, \@@_wrap_next:nw}
+% The \texttt{chunk} and \texttt{next} auxiliaries are defined
+% indirectly to obtain the expansions of \cs{c_catcode_other_space_tl}
+% and \cs{c_@@_wrap_marker_tl} in their definition. The \texttt{next}
+% auxiliary calls a function corresponding to the type of marker (its
+% |##2|), which can be \texttt{newline} or \texttt{indent} or
+% \texttt{unindent} or \texttt{end}. The first argument of the
+% \texttt{chunk} auxiliary is a target number of characters and the
+% second is some string to wrap. If the chunk is empty simply call
+% \texttt{next}. Otherwise, set up a call to \cs{@@_wrap_line:nw},
+% including the indentation if the current line is empty, and
+% including a trailing space (|#1|) before the
+% \cs{@@_wrap_end_chunk:w} auxiliary.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1#2
+ {
+ \cs_new_protected:Npn \@@_wrap_chunk:nw ##1##2 #2
+ {
+ \tl_if_empty:nTF {##2}
+ {
+ \tl_clear:N \l_@@_line_part_tl
+ \@@_wrap_next:nw {##1}
+ }
+ {
+ \tl_if_empty:NTF \l_@@_line_tl
+ {
+ \@@_wrap_line:nw
+ { \l_@@_indent_tl }
+ ##1 - \l_@@_indent_int ;
+ }
+ { \@@_wrap_line:nw { } ##1 ; }
+ ##2 #1
+ \@@_wrap_end_chunk:w 7 6 5 4 3 2 1 0 \s_@@_stop
+ }
+ }
+ \cs_new_protected:Npn \@@_wrap_next:nw ##1##2 #1
+ { \use:c { @@_wrap_##2:n } {##1} }
+ }
+\exp_args:NVV \@@_tmp:w \c_catcode_other_space_tl \c_@@_wrap_marker_tl
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_wrap_line:nw}
+% \begin{macro}[EXP]
+% {
+% \@@_wrap_line_loop:w,
+% \@@_wrap_line_aux:Nw,
+% \@@_wrap_line_seven:nnnnnnn,
+% \@@_wrap_line_end:NnnnnnnnN,
+% \@@_wrap_line_end:nw,
+% \@@_wrap_end_chunk:w
+% }
+% This is followed by \Arg{string} \meta{int expr} |;|. It stores the
+% \meta{string} and up to \meta{int expr} characters from the current
+% chunk into \cs{l_@@_line_part_tl}. Characters are grabbed 8~at a
+% time and left in \cs{l_@@_line_part_tl} by the \texttt{line_loop}
+% auxiliary. When $k<8$ remain to be found, the \texttt{line_aux}
+% auxiliary calls the \texttt{line_end} auxiliary followed by (the
+% single digit) $k$, then $7-k$ empty brace groups, then the chunk's
+% remaining characters. The \texttt{line_end} auxiliary leaves
+% $k$~characters from the chunk in the line part, then ends the
+% assignment. Ignore the \cs{use_none:nnnnn} line for now. If the
+% next character is a space the line can be broken there:
+% store what we found into the result and get the next line.
+% Otherwise some work is needed to find a break-point. So far we have
+% ignored what happens if the chunk is shorter than the requested
+% number of characters: this is dealt with by the \texttt{end_chunk}
+% auxiliary, which gets treated like a character by the rest of the
+% code. It ends up being called either as one of the arguments
+% |#2|--|#9| of the \texttt{line_loop} auxiliary or as one of the
+% arguments |#2|--|#8| of the \texttt{line_end} auxiliary. In both
+% cases stop the assignment and work out how many characters are still
+% needed. Notice that when we have exactly seven arguments to clean up,
+% a \cs{exp_stop_f:} has to be inserted to stop the \cs{exp:w}.
+% The weird \cs{use_none:nnnnn} ensures that the required
+% data is in the right place.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_wrap_line:nw #1
+ {
+ \tex_edef:D \l_@@_line_part_tl { \if_false: } \fi:
+ #1
+ \exp_after:wN \@@_wrap_line_loop:w
+ \int_value:w \int_eval:w
+ }
+\cs_new:Npn \@@_wrap_line_loop:w #1 ; #2#3#4#5#6#7#8#9
+ {
+ \if_int_compare:w #1 < 8 \exp_stop_f:
+ \@@_wrap_line_aux:Nw #1
+ \fi:
+ #2 #3 #4 #5 #6 #7 #8 #9
+ \exp_after:wN \@@_wrap_line_loop:w
+ \int_value:w \int_eval:w #1 - 8 ;
+ }
+\cs_new:Npn \@@_wrap_line_aux:Nw #1#2#3 \exp_after:wN #4 ;
+ {
+ #2
+ \exp_after:wN \@@_wrap_line_end:NnnnnnnnN
+ \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w
+ \exp_after:wN \exp_after:wN
+ \if_case:w #1 \exp_stop_f:
+ \prg_do_nothing:
+ \or: \use_none:n
+ \or: \use_none:nn
+ \or: \use_none:nnn
+ \or: \use_none:nnnn
+ \or: \use_none:nnnnn
+ \or: \use_none:nnnnnn
+ \or: \@@_wrap_line_seven:nnnnnnn
+ \fi:
+ { } { } { } { } { } { } { } #3
+ }
+\cs_new:Npn \@@_wrap_line_seven:nnnnnnn #1#2#3#4#5#6#7 { \exp_stop_f: }
+\cs_new:Npn \@@_wrap_line_end:NnnnnnnnN #1#2#3#4#5#6#7#8#9
+ {
+ #2 #3 #4 #5 #6 #7 #8
+ \use_none:nnnnn \int_eval:w 8 - ; #9
+ \token_if_eq_charcode:NNTF \c_space_token #9
+ { \@@_wrap_line_end:nw { } }
+ { \if_false: { \fi: } \@@_wrap_break:w #9 }
+ }
+\cs_new:Npn \@@_wrap_line_end:nw #1
+ {
+ \if_false: { \fi: }
+ \@@_wrap_store_do:n {#1}
+ \@@_wrap_next_line:w
+ }
+\cs_new:Npn \@@_wrap_end_chunk:w
+ #1 \int_eval:w #2 - #3 ; #4#5 \s_@@_stop
+ {
+ \if_false: { \fi: }
+ \exp_args:Nf \@@_wrap_next:nw { \int_eval:n { #2 - #4 } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_wrap_break:w}
+% \begin{macro}[EXP]
+% {
+% \@@_wrap_break_first:w,
+% \@@_wrap_break_none:w,
+% \@@_wrap_break_loop:w,
+% \@@_wrap_break_end:w,
+% }
+% Functions here are defined indirectly: \cs{@@_tmp:w} is eventually
+% called with an \enquote{other} space as its argument. The goal is
+% to remove from \cs{l_@@_line_part_tl} the part after the last space.
+% In most cases this is done by repeatedly calling the
+% \texttt{break_loop} auxiliary, which leaves \enquote{words}
+% (delimited by spaces) until it hits the trailing space: then its
+% argument |##3| is |?| \cs{@@_wrap_break_end:w} instead of a single
+% token, and that \texttt{break_end} auxiliary leaves in the
+% assignment the line until the last space, then calls
+% \cs{@@_wrap_line_end:nw} to finish up the line and move on to the
+% next. If there is no space in \cs{l_@@_line_part_tl} then the
+% \texttt{break_first} auxiliary calls the \texttt{break_none}
+% auxiliary. In that case, if the current line is empty, the complete
+% word (including |##4|, characters beyond what we had grabbed) is
+% added to the line, making it over-long. Otherwise, the word is
+% used for the following line (and the last space of the line so far
+% is removed because it was inserted due to the presence of a marker).
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \cs_new:Npn \@@_wrap_break:w
+ {
+ \tex_edef:D \l_@@_line_part_tl
+ { \if_false: } \fi:
+ \exp_after:wN \@@_wrap_break_first:w
+ \l_@@_line_part_tl
+ #1
+ { ? \@@_wrap_break_end:w }
+ \s_@@_mark
+ }
+ \cs_new:Npn \@@_wrap_break_first:w ##1 #1 ##2
+ {
+ \use_none:nn ##2 \@@_wrap_break_none:w
+ \@@_wrap_break_loop:w ##1 #1 ##2
+ }
+ \cs_new:Npn \@@_wrap_break_none:w ##1##2 #1 ##3 \s_@@_mark ##4 #1
+ {
+ \tl_if_empty:NTF \l_@@_line_tl
+ { ##2 ##4 \@@_wrap_line_end:nw { } }
+ { \@@_wrap_line_end:nw { \@@_wrap_trim:N } ##2 ##4 #1 }
+ }
+ \cs_new:Npn \@@_wrap_break_loop:w ##1 #1 ##2 #1 ##3
+ {
+ \use_none:n ##3
+ ##1 #1
+ \@@_wrap_break_loop:w ##2 #1 ##3
+ }
+ \cs_new:Npn \@@_wrap_break_end:w ##1 #1 ##2 ##3 #1 ##4 \s_@@_mark
+ { ##1 \@@_wrap_line_end:nw { } ##3 }
+ }
+\exp_args:NV \@@_tmp:w \c_catcode_other_space_tl
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_wrap_next_line:w}
+% The special case where the end of a line coincides with the end of a
+% chunk is detected here, to avoid a spurious empty line. Otherwise,
+% call \cs{@@_wrap_line:nw} to find characters for the next line
+% (remembering to account for the indentation).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_wrap_next_line:w #1#2 \s_@@_stop
+ {
+ \tl_clear:N \l_@@_line_tl
+ \token_if_eq_meaning:NNTF #1 \@@_wrap_end_chunk:w
+ {
+ \tl_clear:N \l_@@_line_part_tl
+ \bool_set_true:N \l_@@_line_break_bool
+ \@@_wrap_next:nw { \l_@@_line_target_int }
+ }
+ {
+ \@@_wrap_line:nw
+ { \l_@@_indent_tl }
+ \l_@@_line_target_int - \l_@@_indent_int ;
+ #1 #2 \s_@@_stop
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_wrap_allow_break:n}
+% This is called after a chunk has been wrapped. The
+% \cs{l_@@_line_part_tl} typically ends with a space (except at the
+% beginning of a line?), which we remove since the
+% \texttt{allow\_break} marker should not insert a space. Then move
+% on with the next chunk, making sure to adjust the target number of
+% characters for the line in case we did remove a space.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_wrap_allow_break:n #1
+ {
+ \__kernel_tl_set:Nx \l_@@_line_tl
+ { \l_@@_line_tl \@@_wrap_trim:N \l_@@_line_part_tl }
+ \bool_set_false:N \l_@@_line_break_bool
+ \tl_if_empty:NTF \l_@@_line_part_tl
+ { \@@_wrap_chunk:nw {#1} }
+ { \exp_args:Nf \@@_wrap_chunk:nw { \int_eval:n { #1 + 1 } } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_wrap_indent:n, \@@_wrap_unindent:n}
+% These functions are called after a chunk has been wrapped, when
+% encountering \texttt{indent}/\texttt{unindent} markers. Add the
+% line part (last line part of the previous chunk) to the line so far
+% and reset a boolean denoting the presence of a line-break. Most
+% importantly, add or remove one indent from the current indent (both
+% the integer and the token list). Finally, continue wrapping.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_wrap_indent:n #1
+ {
+ \tl_put_right:Ne \l_@@_line_tl { \l_@@_line_part_tl }
+ \bool_set_false:N \l_@@_line_break_bool
+ \int_add:Nn \l_@@_indent_int { \l_@@_one_indent_int }
+ \tl_put_right:No \l_@@_indent_tl { \l_@@_one_indent_tl }
+ \@@_wrap_chunk:nw {#1}
+ }
+\cs_new_protected:Npn \@@_wrap_unindent:n #1
+ {
+ \tl_put_right:Ne \l_@@_line_tl { \l_@@_line_part_tl }
+ \bool_set_false:N \l_@@_line_break_bool
+ \int_sub:Nn \l_@@_indent_int { \l_@@_one_indent_int }
+ \__kernel_tl_set:Nx \l_@@_indent_tl
+ { \exp_after:wN \@@_unindent:w \l_@@_indent_tl }
+ \@@_wrap_chunk:nw {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_wrap_newline:n, \@@_wrap_end:n}
+% These functions are called after a chunk has been line-wrapped, when
+% encountering a \texttt{newline}/\texttt{end} marker. Unless we just
+% took a line-break, store the line part and the line so far into the
+% whole \cs{l_@@_wrap_tl}, trimming a trailing space. In the
+% \texttt{newline} case look for a new line (of length
+% \cs{l_@@_line_target_int}) in a new chunk.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_wrap_newline:n #1
+ {
+ \bool_if:NF \l_@@_line_break_bool
+ { \@@_wrap_store_do:n { \@@_wrap_trim:N } }
+ \bool_set_false:N \l_@@_line_break_bool
+ \@@_wrap_chunk:nw { \l_@@_line_target_int }
+ }
+\cs_new_protected:Npn \@@_wrap_end:n #1
+ {
+ \bool_if:NF \l_@@_line_break_bool
+ { \@@_wrap_store_do:n { \@@_wrap_trim:N } }
+ \bool_set_false:N \l_@@_line_break_bool
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_wrap_store_do:n}
+% First add the last line part to the line, then append it to
+% \cs{l_@@_wrap_tl} with the appropriate new line (with
+% \enquote{run-on} text), possibly with its last space removed (|#1|
+% is empty or \cs{@@_wrap_trim:N}).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_wrap_store_do:n #1
+ {
+ \__kernel_tl_set:Nx \l_@@_line_tl
+ { \l_@@_line_tl \l_@@_line_part_tl }
+ \__kernel_tl_set:Nx \l_@@_wrap_tl
+ {
+ \l_@@_wrap_tl
+ \l_@@_newline_tl
+ #1 \l_@@_line_tl
+ }
+ \tl_clear:N \l_@@_line_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_wrap_trim:N, \@@_wrap_trim:w, \@@_wrap_trim_aux:w}
+% Remove one trailing \enquote{other} space from the argument if present.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \cs_new:Npn \@@_wrap_trim:N ##1
+ { \exp_after:wN \@@_wrap_trim:w ##1 \s_@@_mark #1 \s_@@_mark \s_@@_stop }
+ \cs_new:Npn \@@_wrap_trim:w ##1 #1 \s_@@_mark
+ { \@@_wrap_trim_aux:w ##1 \s_@@_mark }
+ \cs_new:Npn \@@_wrap_trim_aux:w ##1 \s_@@_mark ##2 \s_@@_stop {##1}
+ }
+\exp_args:NV \@@_tmp:w \c_catcode_other_space_tl
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%<@@=file>
+% \end{macrocode}
+%
+% \subsection{File operations}
+%
+% \begin{variable}{\l_@@_internal_tl}
+% Used as a short-term scratch variable.
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \g_file_curr_dir_str ,
+% \g_file_curr_ext_str ,
+% \g_file_curr_name_str
+% }
+% The name of the current file should be available at all times:
+% the name itself is set dynamically.
+% \begin{macrocode}
+\str_new:N \g_file_curr_dir_str
+\str_new:N \g_file_curr_ext_str
+\str_new:N \g_file_curr_name_str
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_stack_seq}
+% The input list of files is stored as a sequence stack. In package
+% mode we can recover the information from the details held by
+% \LaTeXe{} (we must be in the preamble and loaded using \tn{usepackage}
+% or \tn{RequirePackage}). As \LaTeXe{} doesn't store directory and
+% name separately, we stick to the same convention here. In pre-loading,
+% \tn{@currnamestack} is empty so is skipped.
+% \begin{macrocode}
+\seq_new:N \g_@@_stack_seq
+\group_begin:
+ \cs_set_protected:Npn \@@_tmp:w #1#2#3
+ {
+ \tl_if_blank:nTF {#1}
+ {
+ \cs_set:Npn \@@_tmp:w ##1 " ##2 " ##3 \s_@@_stop
+ { { } {##2} { } }
+ \seq_gput_right:Ne \g_@@_stack_seq
+ {
+ \exp_after:wN \@@_tmp:w \tex_jobname:D
+ " \tex_jobname:D " \s_@@_stop
+ }
+ }
+ {
+ \seq_gput_right:Nn \g_@@_stack_seq { { } {#1} {#2} }
+ \@@_tmp:w
+ }
+ }
+ \cs_if_exist:NT \@currnamestack
+ {
+ \tl_if_empty:NF \@currnamestack
+ { \exp_after:wN \@@_tmp:w \@currnamestack }
+ }
+\group_end:
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_record_seq}
+% The total list of files used is recorded separately from the current
+% file stack, as nothing is ever popped from this list. The current
+% file name should be included in the file list! We
+% will eventually copy the contents of \cs{@filelist}.
+% \begin{macrocode}
+\seq_new:N \g_@@_record_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_base_name_tl, \l_@@_full_name_tl}
+% For storing the basename and full path whilst passing data internally.
+% \begin{macrocode}
+\tl_new:N \l_@@_base_name_tl
+\tl_new:N \l_@@_full_name_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_dir_str, \l_@@_ext_str, \l_@@_name_str}
+% Used in parsing a path into parts: in contrast to the above, these are
+% never used outside of the current module.
+% \begin{macrocode}
+\str_new:N \l_@@_dir_str
+\str_new:N \l_@@_ext_str
+\str_new:N \l_@@_name_str
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_file_search_path_seq}
+% The current search path.
+% \begin{macrocode}
+\seq_new:N \l_file_search_path_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_tmp_seq}
+% Scratch space for comma list conversion.
+% \begin{macrocode}
+\seq_new:N \l_@@_tmp_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Internal auxiliaries}
+%
+% \begin{variable}{\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\q_@@_nil}
+% Internal quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_nil
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[pTF]{\@@_quark_if_nil:n}
+% Branching quark conditional.
+% \begin{macrocode}
+\__kernel_quark_new_conditional:Nn \@@_quark_if_nil:n { TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\q_@@_recursion_tail,\q_@@_recursion_stop}
+% Internal recursion quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_recursion_tail
+\quark_new:N \q_@@_recursion_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{
+% \@@_if_recursion_tail_break:NN,
+% \@@_if_recursion_tail_stop_do:Nn
+% }
+% Functions to query recursion quarks.
+% \begin{macrocode}
+\__kernel_quark_new_test:N \@@_if_recursion_tail_stop:N
+\__kernel_quark_new_test:N \@@_if_recursion_tail_stop_do:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\__kernel_file_name_sanitize:n}
+% \begin{macro}[EXP]{
+% \@@_name_expand:n,
+% \@@_name_expand_cleanup:Nw,
+% \@@_name_expand_cleanup:w,
+% \@@_name_expand_end:,
+% \@@_name_expand_error:Nw,
+% \@@_name_expand_error_aux:Nw,
+% }
+% \begin{macro}[EXP]{
+% \@@_name_strip_quotes:n,
+% \@@_name_strip_quotes:nnnw,
+% \@@_name_strip_quotes:nnn,
+% }
+% \begin{macro}[EXP]{
+% \@@_name_trim_spaces:n,
+% \@@_name_trim_spaces:nw,
+% \@@_name_trim_spaces_aux:n,
+% \@@_name_trim_spaces_aux:w,
+% }
+% Expanding the file name uses a \tn{csname}-based approach, and
+% relies on active characters (for example from UTF-8 characters)
+% being properly set up to expand to a expansion-safe version using
+% \cs{ifcsname}. This is less conservative than the token-by-token
+% approach used before, but it is much faster.
+% \begin{macrocode}
+\cs_new:Npn \__kernel_file_name_sanitize:n #1
+ {
+ \exp_args:Ne \@@_name_trim_spaces:n
+ {
+ \exp_args:Ne \@@_name_strip_quotes:n
+ { \@@_name_expand:n {#1} }
+ }
+ }
+% \end{macrocode}
+%
+% We'll use \cs{cs:w} to start expanding the file name, and to avoid
+% creating csnames equal to \tn{relax} with \enquote{common} names,
+% there's a prefix |__file_name=| to the csname. There's also a guard
+% token at the end so we can check if there was an error during the
+% process and (try to) clean up gracefully.
+% \begin{macrocode}
+\cs_new:Npn \@@_name_expand:n #1
+ {
+ \exp_after:wN \@@_name_expand_cleanup:Nw
+ \cs:w @@_name = #1 \cs_end:
+ \@@_name_expand_end:
+ }
+% \end{macrocode}
+% With the csname built, we grab it, and grab the remaining tokens
+% delimited by \cs{@@_name_expand_end:}. If there are any remaining
+% tokens, something bad happened, so we'll call the error procedure
+% \cs{@@_name_expand_error:Nw}.
+% If everything went according to plan, then use \cs{token_to_str:N}
+% on the csname built, and call \cs{@@_name_expand_cleanup:w} to
+% remove the prefix we added a while back.
+% \cs{@@_name_expand_cleanup:w} takes a leading argument so we don't
+% have to bother about the value of \cs{tex_escapechar:D}.
+% \begin{macrocode}
+\cs_new:Npn \@@_name_expand_cleanup:Nw #1 #2 \@@_name_expand_end:
+ {
+ \tl_if_empty:nF {#2}
+ { \@@_name_expand_error:Nw #2 \@@_name_expand_end: }
+ \exp_after:wN \@@_name_expand_cleanup:w \token_to_str:N #1
+ }
+\exp_last_unbraced:NNNNo
+\cs_new:Npn \@@_name_expand_cleanup:w #1 \tl_to_str:n { @@_name = } { }
+% \end{macrocode}
+% In non-error cases \cs{@@_name_expand_end:} should not expand. It
+% will only do so in case there is a \cs{csname} too much in the file
+% name, so it will throw an error (while expanding), then insert the
+% missing \cs{cs_end:} and yet another \cs{@@_name_expand_end:} that
+% will be used as a delimiter by \cs{@@_name_expand_cleanup:Nw} (or
+% that will expand again if yet another \cs{endcsname} is missing).
+% \begin{macrocode}
+\cs_new:Npn \@@_name_expand_end:
+ {
+ \msg_expandable_error:nn
+ { kernel } { filename-missing-endcsname }
+ \cs_end: \@@_name_expand_end:
+ }
+% \end{macrocode}
+% Now to the error case. \cs{@@_name_expand_error:Nw} adds an extra
+% \cs{cs_end:} so that in case there was an extra \tn{csname} in the
+% file name, then \cs{@@_name_expand_error_aux:Nw} throws the error.
+% \begin{macrocode}
+\cs_new:Npn \@@_name_expand_error:Nw #1 #2 \@@_name_expand_end:
+ { \@@_name_expand_error_aux:Nw #1 #2 \cs_end: \@@_name_expand_end: }
+\cs_new:Npn \@@_name_expand_error_aux:Nw #1 #2 \cs_end: #3
+ \@@_name_expand_end:
+ {
+ \msg_expandable_error:nnff
+ { kernel } { filename-chars-lost }
+ { \token_to_str:N #1 } { \exp_stop_f: #2 }
+ }
+% \end{macrocode}
+% Quoting file name uses basically the same approach as for
+% \texttt{luaquotejobname}: count the |"| tokens and remove them.
+% \begin{macrocode}
+\cs_new:Npn \@@_name_strip_quotes:n #1
+ {
+ \@@_name_strip_quotes:nw { 0 }
+ #1 " \q_@@_recursion_tail " \q_@@_recursion_stop {#1}
+ }
+\cs_new:Npn \@@_name_strip_quotes:nw #1#2 "
+ {
+ \if_meaning:w \q_@@_recursion_tail #2
+ \@@_name_strip_quotes_end:wnwn
+ \fi:
+ #2
+ \@@_name_strip_quotes:nw { #1 + 1 }
+ }
+\cs_new:Npn \@@_name_strip_quotes_end:wnwn \fi: #1
+ \@@_name_strip_quotes:nw #2 \q_@@_recursion_stop #3
+ {
+ \fi:
+ \int_if_odd:nT {#2}
+ {
+ \msg_expandable_error:nnn
+ { kernel } { unbalanced-quote-in-filename } {#3}
+ }
+ }
+% \end{macrocode}
+% Spaces need to be trimmed from the start of the name and from the end of
+% any extension. However, the name we are passed might not have an extension:
+% that means we have to look for one. If there is no extension, we still use
+% the standard trimming function but deliberately prevent any spaces being
+% removed at the end.
+% \begin{macrocode}
+\cs_new:Npn \@@_name_trim_spaces:n #1
+ { \@@_name_trim_spaces:nw {#1} #1 . \q_@@_nil . \s_@@_stop }
+\cs_new:Npn \@@_name_trim_spaces:nw #1#2 . #3 . #4 \s_@@_stop
+ {
+ \@@_quark_if_nil:nTF {#3}
+ {
+ \tl_trim_spaces_apply:nN { #1 \s_@@_stop }
+ \@@_name_trim_spaces_aux:n
+ }
+ { \tl_trim_spaces:n {#1} }
+ }
+\cs_new:Npn \@@_name_trim_spaces_aux:n #1
+ { \@@_name_trim_spaces_aux:w #1 }
+\cs_new:Npn \@@_name_trim_spaces_aux:w #1 \s_@@_stop {#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\__kernel_file_name_quote:n}
+% \begin{macro}[EXP]{\@@_name_quote:nw}
+% \begin{macrocode}
+\cs_new:Npn \__kernel_file_name_quote:n #1
+ { \@@_name_quote:nw {#1} #1 ~ \q_@@_nil \s_@@_stop }
+\cs_new:Npn \@@_name_quote:nw #1 #2 ~ #3 \s_@@_stop
+ {
+ \@@_quark_if_nil:nTF {#3}
+ { #1 }
+ { "#1" }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\c_@@_marker_tl}
+% The same idea as the marker for rescanning token lists: this pair of
+% tokens cannot appear in a file that is being input.
+% \begin{macrocode}
+\tl_const:Ne \c_@@_marker_tl { : \token_to_str:N : }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[TF]{\file_get:nnN, \file_get:VnN}
+% \begin{macro}{\file_get:nnN,\@@_get_aux:nnN,\@@_get_do:Nw}
+% The approach here is similar to that for \cs{tl_set_rescan:Nnn}.
+% The file contents are grabbed as an argument delimited by
+% \cs{c_@@_marker_tl}. A few subtleties: braces in \cs{if_false:}
+% \ldots{} \cs{fi:} to deal with possible alignment tabs,
+% \tn{tracingnesting} to avoid a warning about a group being closed
+% inside the \tn{scantokens}, and \cs{prg_return_true:} is placed
+% after the end-of-file marker.
+% \begin{macrocode}
+\cs_new_protected:Npn \file_get:nnN #1#2#3
+ {
+ \file_get:nnNF {#1} {#2} #3
+ { \tl_set:Nn #3 { \q_no_value } }
+ }
+\cs_generate_variant:Nn \file_get:nnN { V }
+\prg_new_protected_conditional:Npnn \file_get:nnN #1#2#3 { T , F , TF }
+ {
+ \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
+ {
+ \exp_args:NV \@@_get_aux:nnN
+ \l_@@_full_name_tl
+ {#2} #3
+ \prg_return_true:
+ }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn \file_get:nnN { V } { T , F , TF }
+\cs_new_protected:Npe \@@_get_aux:nnN #1#2#3
+ {
+ \exp_not:N \if_false: { \exp_not:N \fi:
+ \group_begin:
+ \int_set_eq:NN \tex_tracingnesting:D \c_zero_int
+ \exp_not:N \exp_args:No \tex_everyeof:D
+ { \exp_not:N \c_@@_marker_tl }
+ #2 \scan_stop:
+ \exp_not:N \exp_after:wN \exp_not:N \@@_get_do:Nw
+ \exp_not:N \exp_after:wN #3
+ \exp_not:N \exp_after:wN \exp_not:N \prg_do_nothing:
+ \exp_not:N \tex_input:D
+ \sys_if_engine_luatex:TF
+ { {#1} }
+ { \exp_not:N \__kernel_file_name_quote:n {#1} \scan_stop: }
+ \exp_not:N \if_false: } \exp_not:N \fi:
+ }
+\exp_args:Nno \use:nn
+ { \cs_new_protected:Npn \@@_get_do:Nw #1#2 }
+ { \c_@@_marker_tl }
+ {
+ \group_end:
+ \tl_set:No #1 {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_size:n}
+% A copy of the primitive where it's available.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_size:n \tex_filesize:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\file_full_name:n, \@@_full_name:n, \@@_full_name_aux:n}
+% \begin{macro}[EXP]{\@@_full_name_auxi:nn, \@@_full_name_auxii:nn}
+% \begin{macro}[EXP]{\@@_full_name_aux:Nnn}
+% \begin{macro}[EXP]{\@@_full_name_slash:n}
+% \begin{macro}[EXP]{\@@_full_name_slash:w}
+% \begin{macro}[EXP]{\@@_full_name_aux:nN}
+% \begin{macro}[EXP]{\@@_full_name_aux:nnN}
+% \begin{macro}[EXP]{\@@_name_cleanup:w}
+% \begin{macro}[EXP]{\@@_name_end:}
+% \begin{macro}[EXP]{\@@_name_ext_check:nn}
+% \begin{macro}[EXP]{\@@_name_ext_check:nnw}
+% \begin{macro}[EXP]{\@@_name_ext_check:nnnw}
+% \begin{macro}[EXP]{\@@_name_ext_check:nnn}
+% \begin{macro}[EXP]{\@@_name_ext_check:nnnn}
+% File searching can be carried out if the \tn{pdffilesize} primitive
+% or an equivalent is available. That of course means we need to
+% arrange for everything else to here to be done by expansion too.
+% We start off by sanitizing the name and quoting if required: we
+% may need to remove those quotes, so the raw name is passed too.
+% \begin{macrocode}
+\cs_new:Npn \file_full_name:n #1
+ {
+ \exp_args:Ne \@@_full_name:n
+ { \__kernel_file_name_sanitize:n {#1} }
+ }
+\cs_generate_variant:Nn \file_full_name:n { V }
+% \end{macrocode}
+% First, we check of the file is just here: no mapping so we do not
+% need the break part of the broader auxiliary. We are using the fact
+% that the primitive here returns nothing if the file is entirely absent.
+% To avoid unnecessary filesystem lookups, the result of \tn{pdffilesize}
+% is kept available as an argument.
+% For package mode, \tn{input@path} is a token list not a sequence.
+% \begin{macrocode}
+\cs_new:Npn \@@_full_name:n #1
+ {
+ \tl_if_blank:nF {#1}
+ { \exp_args:Nne \@@_full_name_auxii:nn {#1} { \@@_full_name_aux:n {#1} } }
+ }
+% \end{macrocode}
+% To avoid repeated reading of files we need to cache the loading:
+% this is important as the code here is used by \emph{all} file checks.
+% The same marker is used in the \LaTeXe{} kernel, meaning that we get a
+% double-saving with for example \cs{IfFileExists}. As this is all about
+% performance, we use the low-level approach for the conditionals. For
+% a file already seen, the size is reported as $-1$ so it's distinct from
+% any non-cached ones.
+% \begin{macrocode}
+\cs_new:Npn \@@_full_name_aux:n #1
+ {
+ \if_cs_exist:w @@_seen_ \tl_to_str:n {#1} : \cs_end:
+ -1
+ \else:
+ \exp_args:Ne \@@_full_name_auxi:nn { \@@_size:n {#1} } {#1}
+ \fi:
+ }
+% \end{macrocode}
+% We will need the size of files later, and we have to avoid the
+% \cs{scan_stop:} causing issues if we are raising the flag. Thus there is
+% a slightly odd gobble here.
+% \begin{macrocode}
+\cs_new:Npn \@@_full_name_auxi:nn #1#2
+ {
+ \if:w \scan_stop: #1 \scan_stop:
+ \else:
+ \exp_after:wN \use_none:n
+ \cs:w @@_seen_ \tl_to_str:n {#2} : \cs_end:
+ #1
+ \fi:
+ }
+\cs_new:Npn \@@_full_name_auxii:nn #1 #2
+ {
+ \tl_if_blank:nTF {#2}
+ {
+ \seq_map_tokens:Nn \l_file_search_path_seq
+ { \@@_full_name_aux:Nnn \seq_map_break:n {#1} }
+ \cs_if_exist:NT \input@path
+ {
+ \tl_map_tokens:Nn \input@path
+ { \@@_full_name_aux:Nnn \tl_map_break:n {#1} }
+ }
+ \@@_name_end:
+ }
+ { \@@_ext_check:nn {#1} {#2} }
+ }
+% \end{macrocode}
+% Two pars to the auxiliary here so we can avoid doing quoting
+% twice in the event we find the right file.
+% \begin{macrocode}
+\cs_new:Npn \@@_full_name_aux:Nnn #1#2#3
+ {
+ \exp_args:Ne \@@_full_name_aux:nN
+ { \@@_full_name_slash:n {#3} #2 }
+ #1
+ }
+\cs_new:Npn \@@_full_name_slash:n #1
+ {
+ \@@_full_name_slash:nw {#1} #1 \q_nil / \q_nil / \q_nil \q_stop
+ }
+\cs_new:Npn \@@_full_name_slash:nw #1#2 / \q_nil / #3 \q_stop
+ {
+ \quark_if_nil:nTF {#3}
+ { #1 / }
+ { #2 / }
+ }
+\cs_new:Npn \@@_full_name_aux:nN #1
+ { \exp_args:Nne \@@_full_name_aux:nnN {#1} { \@@_full_name_aux:n {#1} } }
+\cs_new:Npn \@@_full_name_aux:nnN #1 #2 #3
+ {
+ \tl_if_blank:nF {#2}
+ {
+ #3
+ {
+ \@@_ext_check:nn {#1} {#2}
+ \@@_name_cleanup:w
+ }
+ }
+ }
+\cs_new:Npn \@@_name_cleanup:w #1 \@@_name_end: { }
+\cs_new:Npn \@@_name_end: { }
+% \end{macrocode}
+% As \TeX{} automatically adds |.tex| if there is no extension,
+% there is a little clean up to do here. First, make sure we are not in the
+% directory part, saving that. Then check for an extension.
+% \begin{macrocode}
+\cs_new:Npn \@@_ext_check:nn #1 #2
+{ \@@_ext_check:nnw {#2} { / } #1 / \q_@@_nil / \s_@@_stop }
+\cs_new:Npn \@@_ext_check:nnw #1 #2 #3 / #4 / #5 \s_@@_stop
+ {
+ \@@_quark_if_nil:nTF {#4}
+ {
+ \exp_args:No \@@_ext_check:nnnw
+ { \use_none:n #2 } {#1} {#3} #3 . \q_@@_nil . \s_@@_stop
+ }
+ { \@@_ext_check:nnw {#1} { #2 #3 / } #4 / #5 \s_@@_stop }
+ }
+\cs_new:Npe \@@_ext_check:nnnw #1#2#3#4 . #5 . #6 \s_@@_stop
+ {
+ \exp_not:N \@@_quark_if_nil:nTF {#5}
+ {
+ \exp_not:N \@@_ext_check:nnn
+ { #1 #3 \tl_to_str:n { .tex } } { #1 #3 } {#2}
+ }
+ { #1 #3 }
+ }
+\cs_new:Npn \@@_ext_check:nnn #1
+ { \exp_args:Nne \@@_ext_check:nnnn {#1} { \@@_full_name_aux:n {#1} } }
+\cs_new:Npn \@@_ext_check:nnnn #1#2#3#4
+ {
+ \tl_if_blank:nTF {#2}
+ {#3}
+ {
+ \bool_lazy_or:nnTF
+ { \int_compare_p:nNn {#4} = {#2} }
+ { \int_compare_p:nNn {#2} = { -1 } }
+ {#1}
+ {#3}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\file_get_full_name:nN, \file_get_full_name:VN}
+% \begin{macro}[TF]{\file_get_full_name:nN, \file_get_full_name:VN}
+% \begin{macro}{\@@_get_full_name_search:nN}
+% These functions pre-date using \cs{tex_filesize:D} for file searching,
+% so are |get| functions with protection. To avoid having different
+% search set ups, they are simply wrappers around the code above.
+% \begin{macrocode}
+\cs_new_protected:Npn \file_get_full_name:nN #1#2
+ {
+ \file_get_full_name:nNF {#1} #2
+ { \tl_set:Nn #2 { \q_no_value } }
+ }
+\cs_generate_variant:Nn \file_get_full_name:nN { V }
+\prg_new_protected_conditional:Npnn \file_get_full_name:nN #1#2 { T , F , TF }
+ {
+ \__kernel_tl_set:Nx #2
+ { \file_full_name:n {#1} }
+ \tl_if_empty:NTF #2
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+\prg_generate_conditional_variant:Nnn \file_get_full_name:nN
+ { V } { T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_internal_ior}
+% A reserved stream to test for opening a shell.
+% \begin{macrocode}
+\ior_new:N \g_@@_internal_ior
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[rEXP]
+% {
+% \file_mdfive_hash:n, \file_mdfive_hash:V,
+% \file_size:n, \file_size:V,
+% \file_timestamp:n, \file_timestamp:V
+% }
+% \begin{macro}[rEXP]{\@@_details:nn, \@@_details_aux:nn}
+% \begin{macro}[rEXP]{\@@_mdfive_hash:n}
+% Getting file details by expansion is relatively easy if a bit repetitive.
+% As the MD5 function has a slightly different syntax from the other commands,
+% there is a little cleaning up to do.
+% \begin{macrocode}
+\cs_new:Npn \file_size:n #1
+ { \@@_details:nn {#1} { size } }
+\cs_generate_variant:Nn \file_size:n { V }
+\cs_new:Npn \file_timestamp:n #1
+ { \@@_details:nn {#1} { moddate } }
+\cs_generate_variant:Nn \file_timestamp:n { V }
+\cs_new:Npn \@@_details:nn #1#2
+ {
+ \exp_args:Ne \@@_details_aux:nn
+ { \file_full_name:n {#1} } {#2}
+ }
+\cs_new:Npn \@@_details_aux:nn #1#2
+ {
+ \tl_if_blank:nF {#1}
+ { \use:c { tex_file #2 :D } {#1} }
+ }
+\cs_new:Npn \file_mdfive_hash:n #1
+ { \exp_args:Ne \@@_mdfive_hash:n { \file_full_name:n {#1} } }
+\cs_generate_variant:Nn \file_mdfive_hash:n { V }
+\cs_new:Npn \@@_mdfive_hash:n #1
+ { \tex_mdfivesum:D file {#1} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\file_hex_dump:nnn, \file_hex_dump:Vnn, \@@_hex_dump_auxi:nnn}
+% \begin{macro}[rEXP]{\@@_hex_dump_auxii:nnnn, \@@_hex_dump_auxiii:nnnn}
+% \begin{macro}[rEXP]{\@@_hex_dump_auxiiv:nnn}
+% \begin{macro}[rEXP]{\file_hex_dump:n, \file_hex_dump:V, \@@_hex_dump:n}
+% These are separate as they need multiple arguments \emph{or} the
+% file size. For \LuaTeX{}, the emulation does not need the file
+% size so we save a little on expansion.
+% \begin{macrocode}
+\cs_new:Npn \file_hex_dump:nnn #1#2#3
+ {
+ \exp_args:Neee \@@_hex_dump_auxi:nnn
+ { \file_full_name:n {#1} }
+ { \int_eval:n {#2} }
+ { \int_eval:n {#3} }
+ }
+\cs_generate_variant:Nn \file_hex_dump:nnn { V }
+\cs_new:Npn \@@_hex_dump_auxi:nnn #1#2#3
+ {
+ \bool_lazy_any:nF
+ {
+ { \tl_if_blank_p:n {#1} }
+ { \int_compare_p:nNn {#2} = 0 }
+ { \int_compare_p:nNn {#3} = 0 }
+ }
+ {
+ \exp_args:Ne \@@_hex_dump_auxii:nnnn
+ { \@@_details_aux:nn {#1} { size } }
+ {#1} {#2} {#3}
+ }
+ }
+\cs_new:Npn \@@_hex_dump_auxii:nnnn #1#2#3#4
+ {
+ \int_compare:nNnTF {#3} > 0
+ { \@@_hex_dump_auxiii:nnnn {#3} }
+ {
+ \exp_args:Ne \@@_hex_dump_auxiii:nnnn
+ { \int_eval:n { #1 + #3 } }
+ }
+ {#1} {#2} {#4}
+ }
+\cs_new:Npn \@@_hex_dump_auxiii:nnnn #1#2#3#4
+ {
+ \int_compare:nNnTF {#4} > 0
+ { \@@_hex_dump_auxiv:nnn {#4} }
+ {
+ \exp_args:Ne \@@_hex_dump_auxiv:nnn
+ { \int_eval:n { #2 + #4 } }
+ }
+ {#1} {#3}
+ }
+\cs_new:Npn \@@_hex_dump_auxiv:nnn #1#2#3
+ {
+ \tex_filedump:D
+ offset ~ \int_eval:n { #2 - 1 } ~
+ length ~ \int_eval:n { #1 - #2 + 1 }
+ {#3}
+ }
+\cs_new:Npn \file_hex_dump:n #1
+ { \exp_args:Ne \@@_hex_dump:n { \file_full_name:n {#1} } }
+\cs_generate_variant:Nn \file_hex_dump:n { V }
+\sys_if_engine_luatex:TF
+ {
+ \cs_new:Npn \@@_hex_dump:n #1
+ {
+ \tl_if_blank:nF {#1}
+ { \tex_filedump:D whole {#1} {#1} }
+ }
+ }
+ {
+ \cs_new:Npn \@@_hex_dump:n #1
+ {
+ \tl_if_blank:nF {#1}
+ { \tex_filedump:D length \tex_filesize:D {#1} {#1} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[noTF]
+% {
+% \file_get_hex_dump:nN, \file_get_hex_dump:VN,
+% \file_get_mdfive_hash:nN, \file_get_mdfive_hash:VN,
+% \file_get_size:nN, \file_get_size:VN,
+% \file_get_timestamp:nN, \file_get_timestamp:VN
+% }
+% \begin{macro}{\@@_get_details:nnN}
+% Non-expandable wrappers around the above in the case where appropriate
+% primitive support exists.
+% \begin{macrocode}
+\cs_new_protected:Npn \file_get_hex_dump:nN #1#2
+ { \file_get_hex_dump:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_generate_variant:Nn \file_get_hex_dump:nN { V }
+\cs_new_protected:Npn \file_get_mdfive_hash:nN #1#2
+ { \file_get_mdfive_hash:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_generate_variant:Nn \file_get_mdfive_hash:nN { V }
+\cs_new_protected:Npn \file_get_size:nN #1#2
+ { \file_get_size:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_generate_variant:Nn \file_get_size:nN { V }
+\cs_new_protected:Npn \file_get_timestamp:nN #1#2
+ { \file_get_timestamp:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_generate_variant:Nn \file_get_timestamp:nN { V }
+\prg_new_protected_conditional:Npnn \file_get_hex_dump:nN #1#2 { T , F , TF }
+ { \@@_get_details:nnN {#1} { hex_dump } #2 }
+\prg_generate_conditional_variant:Nnn \file_get_hex_dump:nN
+ { V } { T , F , TF }
+\prg_new_protected_conditional:Npnn \file_get_mdfive_hash:nN #1#2 { T , F , TF }
+ { \@@_get_details:nnN {#1} { mdfive_hash } #2 }
+\prg_generate_conditional_variant:Nnn \file_get_mdfive_hash:nN
+ { V } { T , F , TF }
+\prg_new_protected_conditional:Npnn \file_get_size:nN #1#2 { T , F , TF }
+ { \@@_get_details:nnN {#1} { size } #2 }
+\prg_generate_conditional_variant:Nnn \file_get_size:nN
+ { V } { T , F , TF }
+\prg_new_protected_conditional:Npnn \file_get_timestamp:nN #1#2 { T , F , TF }
+ { \@@_get_details:nnN {#1} { timestamp } #2 }
+\prg_generate_conditional_variant:Nnn \file_get_timestamp:nN
+ { V } { T , F , TF }
+\cs_new_protected:Npn \@@_get_details:nnN #1#2#3
+ {
+ \__kernel_tl_set:Nx #3
+ { \use:c { file_ #2 :n } {#1} }
+ \tl_if_empty:NTF #3
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[noTF]{\file_get_hex_dump:nnnN, \file_get_hex_dump:VnnN}
+% Custom code due to the additional arguments.
+% \begin{macrocode}
+\cs_new_protected:Npn \file_get_hex_dump:nnnN #1#2#3#4
+ {
+ \file_get_hex_dump:nnnNF {#1} {#2} {#3} #4
+ { \tl_set:Nn #4 { \q_no_value } }
+ }
+\cs_generate_variant:Nn \file_get_hex_dump:nnnN { V }
+\prg_new_protected_conditional:Npnn \file_get_hex_dump:nnnN #1#2#3#4
+ { T , F , TF }
+ {
+ \__kernel_tl_set:Nx #4
+ { \file_hex_dump:nnn {#1} {#2} {#3} }
+ \tl_if_empty:NTF #4
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+\prg_generate_conditional_variant:Nnn \file_get_hex_dump:nnnN
+ { V } { T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_str_cmp:nn}
+% As we are doing a fixed-length \enquote{big} integer comparison, it
+% is easiest to use the low-level behavior of string comparisons.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_str_cmp:nn \tex_strcmp:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, pTF]
+% {
+% \file_compare_timestamp:nNn,
+% \file_compare_timestamp:nNV,
+% \file_compare_timestamp:VNn,
+% \file_compare_timestamp:VNV
+% }
+% \begin{macro}[EXP]{\@@_compare_timestamp:nnN}
+% \begin{macro}[EXP]{\@@_timestamp:n}
+% Comparison of file date can be done by using the low-level nature of the
+% string comparison functions.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \file_compare_timestamp:nNn #1#2#3
+ { p , T , F , TF }
+ {
+ \exp_args:Nee \@@_compare_timestamp:nnN
+ { \file_full_name:n {#1} }
+ { \file_full_name:n {#3} }
+ #2
+ }
+\prg_generate_conditional_variant:Nnn \file_compare_timestamp:nNn
+ { nNV , V , VNV } { p , T , F , TF }
+\cs_new:Npn \@@_compare_timestamp:nnN #1#2#3
+ {
+ \tl_if_blank:nTF {#1}
+ {
+ \if_charcode:w #3 <
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ {
+ \tl_if_blank:nTF {#2}
+ {
+ \if_charcode:w #3 >
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ {
+ \if_int_compare:w
+ \@@_str_cmp:nn
+ { \@@_timestamp:n {#1} }
+ { \@@_timestamp:n {#2} }
+ #3 \c_zero_int
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ }
+ }
+\cs_new_eq:NN \@@_timestamp:n \tex_filemoddate:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\file_if_exist:n, \file_if_exist:V}
+% The test for the existence of a file is a wrapper around the function to
+% add a path to a file. If the file was found, the path contains
+% something, whereas if the file was not located then the return value
+% is empty.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \file_if_exist:n #1 { p , T , F , TF }
+ {
+ \tl_if_blank:eTF { \file_full_name:n {#1} }
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+\prg_generate_conditional_variant:Nnn \file_if_exist:n { V } { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \file_if_exist_input:n,
+% \file_if_exist_input:V,
+% \file_if_exist_input:nF,
+% \file_if_exist_input:VF
+% }
+% Input of a file with a test for existence. We do not define the |T|
+% or |TF| variants because the most useful place to place the
+% \meta{true code} would be inconsistent with other conditionals.
+% \begin{macrocode}
+\cs_new_protected:Npn \file_if_exist_input:n #1
+ {
+ \file_get_full_name:nNT {#1} \l_@@_full_name_tl
+ { \@@_input:V \l_@@_full_name_tl }
+ }
+\cs_generate_variant:Nn \file_if_exist_input:n { V }
+\cs_new_protected:Npn \file_if_exist_input:nF #1#2
+ {
+ \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
+ { \@@_input:V \l_@@_full_name_tl }
+ {#2}
+ }
+\cs_generate_variant:Nn \file_if_exist_input:nF { V }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\file_input_stop:}
+% A simple rename.
+% \begin{macrocode}
+\cs_new_protected:Npn \file_input_stop: { \tex_endinput:D }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_file_missing:n}
+% An error message for a missing file, also used in \cs{ior_open:Nn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_file_missing:n #1
+ {
+ \msg_error:nne { kernel } { file-not-found }
+ { \__kernel_file_name_sanitize:n {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\file_input:n, \file_input:V}
+% \begin{macro}{\@@_input:n, \@@_input:V}
+% \begin{macro}{\@@_input_push:n, \__kernel_file_input_push:n}
+% \begin{macro}{\@@_input_pop:, \__kernel_file_input_pop:}
+% \begin{macro}{\@@_input_pop:nnn}
+% Loading a file is done in a safe way, checking first that the file
+% exists and loading only if it does. Push the file name on the
+% \cs{g_@@_stack_seq}, and add it to the file list, either
+% \cs{g_@@_record_seq}, or \cs{@filelist} in package mode.
+% \begin{macrocode}
+\cs_new_protected:Npn \file_input:n #1
+ {
+ \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
+ { \@@_input:V \l_@@_full_name_tl }
+ { \__kernel_file_missing:n {#1} }
+ }
+\cs_generate_variant:Nn \file_input:n { V }
+\cs_new_protected:Npe \@@_input:n #1
+ {
+ \exp_not:N \clist_if_exist:NTF \exp_not:N \@filelist
+ { \exp_not:N \@addtofilelist {#1} }
+ { \seq_gput_right:Nn \exp_not:N \g_@@_record_seq {#1} }
+ \exp_not:N \@@_input_push:n {#1}
+ \exp_not:N \tex_input:D
+ \sys_if_engine_luatex:TF
+ { {#1} }
+ { \exp_not:N \__kernel_file_name_quote:n {#1} \scan_stop: }
+ \exp_not:N \@@_input_pop:
+ }
+\cs_generate_variant:Nn \@@_input:n { V }
+% \end{macrocode}
+% Keeping a track of the file data is easy enough: we store the separated
+% parts so we do not need to parse them twice.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_input_push:n #1
+ {
+ \seq_gpush:Ne \g_@@_stack_seq
+ {
+ { \g_file_curr_dir_str }
+ { \g_file_curr_name_str }
+ { \g_file_curr_ext_str }
+ }
+ \file_parse_full_name:nNNN {#1}
+ \l_@@_dir_str \l_@@_name_str \l_@@_ext_str
+ \str_gset_eq:NN \g_file_curr_dir_str \l_@@_dir_str
+ \str_gset_eq:NN \g_file_curr_name_str \l_@@_name_str
+ \str_gset_eq:NN \g_file_curr_ext_str \l_@@_ext_str
+ }
+\cs_new_eq:NN \__kernel_file_input_push:n \@@_input_push:n
+\cs_new_protected:Npn \@@_input_pop:
+ {
+ \seq_gpop:NN \g_@@_stack_seq \l_@@_internal_tl
+ \exp_after:wN \@@_input_pop:nnn \l_@@_internal_tl
+ }
+\cs_new_eq:NN \__kernel_file_input_pop: \@@_input_pop:
+\cs_new_protected:Npn \@@_input_pop:nnn #1#2#3
+ {
+ \str_gset:Nn \g_file_curr_dir_str {#1}
+ \str_gset:Nn \g_file_curr_name_str {#2}
+ \str_gset:Nn \g_file_curr_ext_str {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\file_input_raw:n, \file_input_raw:V, \@@_input_raw:nn}
+% No error checking, no tracking.
+% \begin{macrocode}
+\cs_new:Npn \file_input_raw:n #1
+ { \exp_args:Ne \@@_input_raw:nn { \file_full_name:n {#1} } {#1} }
+\cs_generate_variant:Nn \file_input_raw:n { V }
+\cs_new:Npe \@@_input_raw:nn #1#2
+ {
+ \exp_not:N \tl_if_blank:nTF {#1}
+ {
+ \exp_not:N \exp_args:Nnne \exp_not:N \msg_expandable_error:nnn
+ { kernel } { file-not-found }
+ { \exp_not:N \__kernel_file_name_sanitize:n {#2} }
+ }
+ {
+ \exp_not:N \tex_input:D
+ \sys_if_engine_luatex:TF
+ { {#1} }
+ { \exp_not:N \__kernel_file_name_quote:n {#1} \scan_stop: }
+ }
+ }
+\exp_args_generate:n { nne }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\file_parse_full_name:n, \file_parse_full_name:V}
+% \begin{macro}{\file_parse_full_name_apply:nN, \file_parse_full_name_apply:VN}
+% The main parsing macro \cs{file_parse_full_name_apply:nN} passes the
+% file name |#1| through \cs{__kernel_file_name_sanitize:n} so that we
+% have a single normalised way to treat files internally.
+% \cs{file_parse_full_name:n} uses the former, with
+% \cs{prg_do_nothing:} to
+% leave each part of the name within a pair of braces.
+% \begin{macrocode}
+\cs_new:Npn \file_parse_full_name:n #1
+ {
+ \file_parse_full_name_apply:nN {#1}
+ \prg_do_nothing:
+ }
+\cs_generate_variant:Nn \file_parse_full_name:n { V }
+\cs_new:Npn \file_parse_full_name_apply:nN #1
+ {
+ \exp_args:Ne \@@_parse_full_name_auxi:nN
+ { \__kernel_file_name_sanitize:n {#1} }
+ }
+\cs_generate_variant:Nn \file_parse_full_name_apply:nN { V }
+% \end{macrocode}
+%
+% \begin{macro}{\@@_parse_full_name_auxi:nN}
+% \begin{macro}{\@@_parse_full_name_area:nw}
+% \cs{@@_parse_full_name_area:nw} splits the file name into chunks
+% separated by |/|, until the last one is reached. The last chunk is
+% the file name plus the extension, and everything before that is the
+% path. When \cs{@@_parse_full_name_area:nw} is done, it leaves
+% the path within braces after the scan mark \cs{s_@@_stop} and
+% proceeds parsing the actual file name.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_full_name_auxi:nN #1
+ {
+ \@@_parse_full_name_area:nw { } #1
+ / \s_@@_stop
+ }
+\cs_new:Npn \@@_parse_full_name_area:nw #1 #2 / #3 \s_@@_stop
+ {
+ \tl_if_empty:nTF {#3}
+ { \@@_parse_full_name_base:nw { } #2 . \s_@@_stop {#1} }
+ { \@@_parse_full_name_area:nw { #1 / #2 } #3 \s_@@_stop }
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\@@_parse_full_name_base:nw}
+% \cs{@@_parse_full_name_base:nw} does roughly the same as above, but
+% it separates the chunks at each period. However here there's some
+% extra complications: In case |#1| is empty, it is assumed that the
+% extension is actually empty, and the file name is |#2|. Besides, an
+% extra |.| has to be added to |#2| because it is later removed in
+% \cs{@@_parse_full_name_tidy:nnnN}. In any case, if there's an
+% extension, it is returned with a leading |.|.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_full_name_base:nw #1 #2 . #3 \s_@@_stop
+ {
+ \tl_if_empty:nTF {#3}
+ {
+ \tl_if_empty:nTF {#1}
+ {
+ \tl_if_empty:nTF {#2}
+ { \@@_parse_full_name_tidy:nnnN { } { } }
+ { \@@_parse_full_name_tidy:nnnN { .#2 } { } }
+ }
+ { \@@_parse_full_name_tidy:nnnN {#1} { .#2 } }
+ }
+ { \@@_parse_full_name_base:nw { #1 . #2 } #3 \s_@@_stop }
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\@@_parse_full_name_tidy:nnnN}
+% Now we just need to tidy some bits left loose before. The loop
+% used in the two macros above start with a leading |/| and |.| in the
+% file path an name, so here we need to remove them, except in the
+% path, if it is a single |/|, in which case it's left as is. After
+% all's done, pass to |#4|.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_full_name_tidy:nnnN #1 #2 #3 #4
+ {
+ \exp_args:Nee #4
+ {
+ \str_if_eq:nnF {#3} { / } { \use_none:n }
+ #3 \prg_do_nothing:
+ }
+ { \use_none:n #1 \prg_do_nothing: }
+ {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\file_parse_full_name:nNNN, \file_parse_full_name:VNNN}
+% \begin{macrocode}
+\cs_new_protected:Npn \file_parse_full_name:nNNN #1 #2 #3 #4
+ {
+ \file_parse_full_name_apply:nN {#1}
+ \@@_full_name_assign:nnnNNN #2 #3 #4
+ }
+\cs_new_protected:Npn \@@_full_name_assign:nnnNNN #1 #2 #3 #4 #5 #6
+ {
+ \str_set:Nn #4 {#1}
+ \str_set:Nn #5 {#2}
+ \str_set:Nn #6 {#3}
+ }
+\cs_generate_variant:Nn \file_parse_full_name:nNNN { V }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\file_show_list:, \file_log_list:, \@@_list:N}
+% \begin{macro}[EXP]{\@@_list_aux:n}
+% A function to list all files used to the log, without duplicates.
+% In package mode, if \cs{@filelist} is still defined, we need to take
+% this list of file names into account (we capture it
+% \cs{AtBeginDocument} into \cs{g_@@_record_seq}), turning it to a
+% string (this does not affect the commas of this comma list).
+% \begin{macrocode}
+\cs_new_protected:Npn \file_show_list: { \@@_list:N \msg_show:nneeee }
+\cs_new_protected:Npn \file_log_list: { \@@_list:N \msg_log:nneeee }
+\cs_new_protected:Npn \@@_list:N #1
+ {
+ \seq_clear:N \l_@@_tmp_seq
+ \clist_if_exist:NT \@filelist
+ {
+ \exp_args:NNe \seq_set_from_clist:Nn \l_@@_tmp_seq
+ { \tl_to_str:N \@filelist }
+ }
+ \seq_concat:NNN \l_@@_tmp_seq \l_@@_tmp_seq \g_@@_record_seq
+ \seq_remove_duplicates:N \l_@@_tmp_seq
+ #1 { kernel } { file-list }
+ { \seq_map_function:NN \l_@@_tmp_seq \@@_list_aux:n }
+ { } { } { }
+ }
+\cs_new:Npn \@@_list_aux:n #1 { \iow_newline: #1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% When used as a package, there is a need to hold onto the standard file
+% list as well as the new one here. File names recorded in
+% \cs{@filelist} must be turned to strings before being added to
+% \cs{g_@@_record_seq}.
+% \begin{macrocode}
+\cs_if_exist:NT \@filelist
+ {
+ \AtBeginDocument
+ {
+ \exp_args:NNe \seq_set_from_clist:Nn \l_@@_tmp_seq
+ { \tl_to_str:N \@filelist }
+ \seq_gconcat:NNN
+ \g_@@_record_seq
+ \g_@@_record_seq
+ \l_@@_tmp_seq
+ }
+ }
+% \end{macrocode}
+%
+% \subsection{GetIdInfo}
+%
+% \begin{macro}{\GetIdInfo}
+% \begin{macro}{\@@_id_info_auxi:w, \@@_id_info_auxii:w, \@@_id_info_auxiii:w}
+% As documented in \pkg{expl3.dtx} this function extracts file name
+% etc from an \textsc{svn} \texttt{Id} line. This used to be how we
+% got version number and so on in all modules, so it had to be defined
+% in \pkg{l3bootstrap}. Now it's more convenient to define it after
+% we have set up quite a lot of tools, and \pkg{l3file} seems the
+% least unreasonable place for it.
+%
+% The idea here is to extract out the information needed from a standard
+% \textsc{svn} \texttt{Id} line, but to avoid a line that would get
+% changed when the file is checked in. Hence the fact that none of the
+% lines here include both a dollar sign and the \texttt{Id} keyword!
+% \begin{macrocode}
+\cs_new_protected:Npn \GetIdInfo
+ {
+ \tl_clear_new:N \ExplFileDescription
+ \tl_clear_new:N \ExplFileDate
+ \tl_clear_new:N \ExplFileName
+ \tl_clear_new:N \ExplFileExtension
+ \tl_clear_new:N \ExplFileVersion
+ \group_begin:
+ \char_set_catcode_space:n { 32 }
+ \exp_after:wN
+ \group_end:
+ \@@_id_info_auxi:w
+ }
+% \end{macrocode}
+% A first check for a completely empty \textsc{svn} field. If that is
+% not the case, there is a second case when a file created using
+% \texttt{svn cp} but has not been checked in. That leaves a special
+% marker \texttt{-1} version, which has no further data. Dealing
+% correctly with that is the reason for the space in the line to use
+% \cs{@@_id_info_auxii:w}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_id_info_auxi:w $ #1 $ #2
+ {
+ \tl_set:Nn \ExplFileDescription {#2}
+ \str_if_eq:nnTF {#1} { Id }
+ {
+ \tl_set:Nn \ExplFileDate { 0000/00/00 }
+ \tl_set:Nn \ExplFileName { [unknown] }
+ \tl_set:Nn \ExplFileExtension { [unknown~extension] }
+ \tl_set:Nn \ExplFileVersion {-1}
+ }
+ { \@@_id_info_auxii:w #1 ~ \s_@@_stop }
+ }
+% \end{macrocode}
+% Here, |#1| is |Id|, |#2| is the file name, |#3| is the extension,
+% |#4| is the version, |#5| is the check in date and |#6| is the check
+% in time and user, plus some trailing spaces. If |#4| is the marker
+% |-1| value then |#5| and |#6| are empty.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_id_info_auxii:w
+ #1 ~ #2.#3 ~ #4 ~ #5 ~ #6 \s_@@_stop
+ {
+ \tl_set:Nn \ExplFileName {#2}
+ \tl_set:Nn \ExplFileExtension {#3}
+ \tl_set:Nn \ExplFileVersion {#4}
+ \str_if_eq:nnTF {#4} {-1}
+ { \tl_set:Nn \ExplFileDate { 0000/00/00 } }
+ { \@@_id_info_auxiii:w #5 - 0 - 0 - \s_@@_stop }
+ }
+% \end{macrocode}
+% Convert an \textsc{svn}-style date into a \LaTeX{}-style one.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_id_info_auxiii:w #1 - #2 - #3 - #4 \s_@@_stop
+ { \tl_set:Nn \ExplFileDate { #1/#2/#3 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Checking the version of kernel dependencies}
+%
+% \begin{macro}{\__kernel_dependency_version_check:Nn}
+% \begin{macro}{\__kernel_dependency_version_check:nn}
+% \begin{macro}{\@@_kernel_dependency_compare:nnn,\@@_parse_version:w}
+% This function is responsible for checking if dependencies of the
+% \LaTeX3 kernel match the version preloaded in the \LaTeXe{} kernel.
+% If versions don't match, the function attempts to tell why by
+% searching for a possible stray format file.
+%
+% The function starts by checking that the kernel date is defined, and
+% if not zero is used to force the error route. The kernel date is
+% then compared with the argument requested date (ususally the
+% packaging date of the dependency). If the kernel date is less than
+% the required date, it's an error and the loading should abort.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_dependency_version_check:Nn #1
+ { \exp_args:NV \__kernel_dependency_version_check:nn #1 }
+\cs_new_protected:Npn \__kernel_dependency_version_check:nn #1
+ {
+ \cs_if_exist:NTF \c__kernel_expl_date_tl
+ {
+ \exp_args:NV \@@_kernel_dependency_compare:nnn
+ \c__kernel_expl_date_tl {#1}
+ }
+ { \@@_kernel_dependency_compare:nnn { 0000-00-00 } {#1} }
+ }
+\cs_new_protected:Npn \@@_kernel_dependency_compare:nnn #1 #2 #3
+ {
+ \int_compare:nNnT
+ { \@@_parse_version:w #1 \s_@@_stop } <
+ { \@@_parse_version:w #2 \s_@@_stop }
+ { \@@_mismatched_dependency_error:nn {#2} {#3} }
+ }
+\cs_new:Npn \@@_parse_version:w #1 - #2 - #3 \s_@@_stop {#1#2#3}
+% \end{macrocode}
+%
+% \begin{macro}{\@@_mismatched_dependency_error:nn}
+% If the versions differ, then we try to give the user some guidance.
+% This function starts by taking the engine name \cs{c_sys_engine_str}
+% and replacing |tex| by |latex|, then building a command of the form:
+% \begin{texttt}
+% kpsewhich --all --engine=\meta{engine} \meta{format}[-dev].fmt
+% \end{texttt}
+% to query the format files available. A shell is opened and each
+% line is read into a sequence.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_mismatched_dependency_error:nn #1 #2
+ {
+ \exp_args:NNe \ior_shell_open:Nn \g_@@_internal_ior
+ {
+ kpsewhich ~ --all ~
+ --engine = \c_sys_engine_exec_str
+ \c_space_tl \c_sys_engine_format_str
+ \bool_lazy_and:nnT
+ { \tl_if_exist_p:N \development@branch@name }
+ { ! \tl_if_empty_p:N \development@branch@name }
+ { -dev } .fmt
+ }
+ \seq_clear:N \l_@@_tmp_seq
+ \ior_map_inline:Nn \g_@@_internal_ior
+ { \seq_put_right:Nn \l_@@_tmp_seq {##1} }
+ \ior_close:N \g_@@_internal_ior
+ \msg_error:nnnn { kernel } { mismatched-support-file }
+ {#1} {#2}
+% \end{macrocode}
+% And finish by ending the current file.
+% \begin{macrocode}
+ \tex_endinput:D
+ }
+% \end{macrocode}
+%
+% Now define the actual error message:
+% \begin{macrocode}
+\msg_new:nnnn { kernel } { mismatched-support-file }
+ {
+ Mismatched~LaTeX~support~files~detected. \\
+ Loading~'#2'~aborted!
+% \end{macrocode}
+% \cs{c__kernel_expl_date_tl} may not exist, due to an older format,
+% so only print the dates when the sentinel token list exists:
+% \begin{macrocode}
+ \tl_if_exist:NT \c__kernel_expl_date_tl
+ {
+ \\ \\
+ The~L3~programming~layer~in~the~LaTeX~format \\
+ is~dated~\c__kernel_expl_date_tl,~but~in~your~TeX~
+ tree~the~files~require \\ at~least~#1.
+ }
+ }
+ {
+% \end{macrocode}
+% The sequence containing the format files should have exactly one
+% item: the format file currently being run. If that's the case, the
+% cause of the error is not that, so print a generic help with some
+% possible causes. If more than one format file was found, then print
+% the list to the user, with appropriate indications of what's in the
+% system and what's in the user tree.
+% \begin{macrocode}
+ \int_compare:nNnTF { \seq_count:N \l_@@_tmp_seq } > 1
+ {
+ The~cause~seems~to~be~an~old~format~file~in~the~user~tree. \\
+ LaTeX~found~these~files:
+ \seq_map_tokens:Nn \l_@@_tmp_seq { \\~-~\use:n } \\
+ Try~deleting~the~file~in~the~user~tree~then~run~LaTeX~again.
+ }
+ {
+ The~most~likely~causes~are:
+ \\~-~A~recent~format~generation~failed;
+ \\~-~A~stray~format~file~in~the~user~tree~which~needs~
+ to~be~removed~or~rebuilt;
+ \\~-~You~are~running~a~manually~installed~version~of~#2 \\
+ \ \ \ which~is~incompatible~with~the~version~in~LaTeX. \\
+ }
+ \\
+ LaTeX~will~abort~loading~the~incompatible~support~files~
+ but~this~may~lead~to \\ later~errors.~Please~ensure~that~
+ your~LaTeX~format~is~correctly~regenerated.
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% \begin{macrocode}
+\msg_new:nnnn { kernel } { file-not-found }
+ { File~'#1'~not~found. }
+ {
+ The~requested~file~could~not~be~found~in~the~current~directory,~
+ in~the~TeX~search~path~or~in~the~LaTeX~search~path.
+ }
+\msg_new:nnn { kernel } { file-list }
+ {
+ >~File~List~<
+ #1 \\
+ .............
+ }
+\msg_new:nnnn { kernel } { filename-chars-lost }
+ { #1~invalid~in~file~name.~Lost:~#2. }
+ {
+ There~was~an~invalid~token~in~the~file~name~that~caused~
+ the~characters~following~it~to~be~lost.
+ }
+\msg_new:nnnn { kernel } { filename-missing-endcsname }
+ { Missing~\iow_char:N\\endcsname~inserted~in~filename. }
+ {
+ The~file~name~had~more~\iow_char:N\\csname~commands~than~
+ \iow_char:N\\endcsname~ones.~LaTeX~will~add~the~missing~
+ \iow_char:N\\endcsname~and~try~to~continue~as~best~as~it~can.
+ }
+\msg_new:nnnn { kernel } { unbalanced-quote-in-filename }
+ { Unbalanced~quotes~in~file~name~'#1'. }
+ {
+ File~names~must~contain~balanced~numbers~of~quotes~(").
+ }
+\msg_new:nnnn { kernel } { iow-indent }
+ { Only~#1 allows~#2 }
+ {
+ The~command~#2 can~only~be~used~in~messages~
+ which~will~be~wrapped~using~#1.
+ \tl_if_empty:nF {#3} { ~ It~was~called~with~argument~'#3'. }
+ }
+% \end{macrocode}
+%
+% \subsection{Functions delayed from earlier modules}
+%
+%<@@=sys>
+%
+% \begin{variable}{\c_sys_platform_str}
+% Detecting the platform on \LuaTeX{} is easy: for other engines, we use
+% the fact that the two common cases have special null files. It is possible
+% to probe further (see package \pkg{platform}), but that requires shell
+% escape and seems unlikely to be useful. This is set up here as it requires
+% file searching.
+% \begin{macrocode}
+\sys_if_engine_luatex:TF
+ {
+ \str_const:Ne \c_sys_platform_str
+ { \tex_directlua:D { tex.print(os.type) } }
+ }
+ {
+ \file_if_exist:nTF { nul: }
+ {
+ \file_if_exist:nF { /dev/null }
+ { \str_const:Nn \c_sys_platform_str { windows } }
+ }
+ {
+ \file_if_exist:nT { /dev/null }
+ { \str_const:Nn \c_sys_platform_str { unix } }
+ }
+ }
+\cs_if_exist:NF \c_sys_platform_str
+ { \str_const:Nn \c_sys_platform_str { unknown } }
+% \end{macrocode}
+% \end{variable}
+% \begin{macro}[pTF]{\sys_if_platform_unix:}
+% \begin{macro}[pTF]{\sys_if_platform_windows:}
+% We can now set up the tests.
+% \begin{macrocode}
+\clist_map_inline:nn { unix , windows }
+ {
+ \@@_const:nn { sys_if_platform_ #1 }
+ { \str_if_eq_p:Vn \c_sys_platform_str { #1 } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3flag.dtx b/macros/latex-dev/required/l3kernel/l3flag.dtx
new file mode 100644
index 0000000000..c3bd4a5085
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3flag.dtx
@@ -0,0 +1,396 @@
+% \iffalse meta-comment
+%
+%% File: l3flag.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3flag} module\\ Expandable flags^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% Flags are the only data-type that can be modified in expansion-only
+% contexts. This module is meant mostly for kernel use: in almost all
+% cases, booleans or integers should be preferred to flags because they
+% are very significantly faster.
+%
+% A flag can hold any (small) non-negative value, which we call its
+% \meta{height}. In expansion-only contexts, a flag can only be
+% \enquote{raised}: this increases the \meta{height} by $1$. The \meta{height}
+% can also be queried expandably. However, decreasing it, or setting it
+% to zero requires non-expandable assignments.
+%
+% Flag variables are always local.
+%
+% A typical use case of flags would be to keep track of whether an
+% exceptional condition has occurred during expandable processing, and
+% produce a meaningful (non-expandable) message after the end of the
+% expandable processing. This is exemplified by \pkg{l3str-convert},
+% which for performance reasons performs conversions of individual
+% characters expandably and for readability reasons produces a single
+% error message describing incorrect inputs that were encountered.
+%
+% Flags should not be used without carefully considering the fact that
+% raising a flag takes a time and memory proportional to its height and
+% that the memory cannot be reclaimed even if the flag is cleared.
+% Flags should not be used unless it is unavoidable.
+%
+% In earlier versions, flags were referenced by an \texttt{n}-type
+% \meta{flag name} such as \texttt{fp_overflow}, used as part of
+% \cs{use:c} constructions. All of the commands described below have
+% \texttt{n}-type analogues that can still appear in old code, but the
+% \texttt{N}-type commands are to be preferred moving forward. The
+% \texttt{n}-type \meta{flag name} is simply mapped to
+% \cs[no-index]{l_\meta{flag name}_flag}, which makes it easier for
+% packages using public flags (such as \pkg{l3fp}) to retain backwards
+% compatibility.
+%
+% \section{Setting up flags}
+%
+% \begin{function}[added = 2024-01-12]{\flag_new:N, \flag_new:c}
+% \begin{syntax}
+% \cs{flag_new:N} \meta{flag~var}
+% \end{syntax}
+% Creates a new \meta{flag~var}, or raises an error if the name is
+% already taken. The declaration is global, but flags are always local
+% variables. The \meta{flag~var} initially has zero height.
+% \end{function}
+%
+% \begin{function}[added = 2024-01-12]{\flag_clear:N, \flag_clear:c}
+% \begin{syntax}
+% \cs{flag_clear:N} \meta{flag~var}
+% \end{syntax}
+% Sets the height of the \meta{flag~var} to zero. The assignment is local.
+% \end{function}
+%
+% \begin{function}[added = 2024-01-12]{\flag_clear_new:N, \flag_clear_new:c}
+% \begin{syntax}
+% \cs{flag_clear_new:N} \meta{flag~var}
+% \end{syntax}
+% Ensures that the \meta{flag~var} exists globally by applying
+% \cs{flag_new:N} if necessary, then applies \cs{flag_clear:N}, setting
+% the height to zero locally.
+% \end{function}
+%
+% \begin{function}[added = 2024-01-12]{\flag_show:N, \flag_show:c}
+% \begin{syntax}
+% \cs{flag_show:N} \meta{flag~var}
+% \end{syntax}
+% Displays the height of the \meta{flag~var} in the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2024-01-12]{\flag_log:N, \flag_log:c}
+% \begin{syntax}
+% \cs{flag_log:N} \meta{flag~var}
+% \end{syntax}
+% Writes the height of the \meta{flag~var} in the log file.
+% \end{function}
+%
+% \section{Expandable flag commands}
+%
+% \begin{function}[EXP, pTF, added = 2024-01-12]{\flag_if_exist:N, \flag_if_exist:c}
+% \begin{syntax}
+% \cs{flag_if_exist_p:N} \meta{flag~var}
+% \cs{flag_if_exist:NTF} \meta{flag~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function returns \texttt{true} if the \meta{flag~var} is
+% currently defined, and \texttt{false} otherwise. This does not check
+% that the \meta{flag~var} really is a flag variable.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added = 2024-01-12]{\flag_if_raised:N, \flag_if_raised:c}
+% \begin{syntax}
+% \cs{flag_if_raised_p:N} \meta{flag~var}
+% \cs{flag_if_raised:NTF} \meta{flag~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function returns \texttt{true} if the \meta{flag~var} has non-zero
+% height, and \texttt{false} if the \meta{flag~var} has zero height.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2024-01-12]{\flag_height:N, \flag_height:c}
+% \begin{syntax}
+% \cs{flag_height:N} \meta{flag~var}
+% \end{syntax}
+% Expands to the height of the \meta{flag~var} as an integer denotation.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2024-01-12]{\flag_raise:N, \flag_raise:c}
+% \begin{syntax}
+% \cs{flag_raise:N} \meta{flag~var}
+% \end{syntax}
+% The height of \meta{flag~var} is increased by $1$ locally.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2024-01-12]{\flag_ensure_raised:N, \flag_ensure_raised:c}
+% \begin{syntax}
+% \cs{flag_ensure_raised:N} \meta{flag~var}
+% \end{syntax}
+% Ensures the \meta{flag~var} is raised by making its height at least~$1$,
+% locally.
+% \end{function}
+%
+% \begin{variable}[added = 2024-01-12]{\l_tmpa_flag, \l_tmpb_flag}
+% Scratch flag for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3flag} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=flag>
+% \end{macrocode}
+%
+% \TestFiles{m3flag001}
+%
+% \subsection{Protected flag commands}
+%
+% The height $h$ of a flag (which is initially zero) is stored by
+% setting control sequences of the form \cs[no-index]{\meta{flag
+% name}\meta{integer}} to \tn{relax} for $0\leq\meta{integer}<h$. These
+% control sequences are produced by \cs{cs:w} \meta{flag~var}
+% \meta{integer} \cs{cs_end:}, namely the \meta{flag~var} is actually a
+% (protected) macro expanding to its own csname.
+%
+% \begin{macro}{\flag_new:N, \flag_new:c}
+% Evaluate the csname of~|#1| for use in constructing the various
+% indexed macros.
+% \begin{macrocode}
+\cs_new_protected:Npn \flag_new:N #1
+ { \cs_new_protected:Npe #1 { \cs_to_str:N #1 } }
+\cs_generate_variant:Nn \flag_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_tmpa_flag, \l_tmpb_flag}
+% Two flag variables for scratch use.
+% \begin{macrocode}
+\flag_new:N \l_tmpa_flag
+\flag_new:N \l_tmpb_flag
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\flag_clear:N, \flag_clear:c}
+% \begin{macro}{\@@_clear:wN}
+% Undefine control sequences, starting from the |0| flag, upwards,
+% until reaching an undefined control sequence. We don't use
+% \cs{cs_undefine:c} because that would act globally.
+% \begin{macrocode}
+\cs_new_protected:Npn \flag_clear:N #1
+ {
+ \@@_clear:wN 0 ; #1
+ \prg_break_point:
+ }
+\cs_generate_variant:Nn \flag_clear:N { c }
+\cs_new_protected:Npn \@@_clear:wN #1 ; #2
+ {
+ \if_cs_exist:w #2 #1 \cs_end: \else:
+ \prg_break:n
+ \fi:
+ \cs_set_eq:cN { #2 #1 } \tex_undefined:D
+ \exp_after:wN \@@_clear:wN
+ \int_value:w \int_eval:w \c_one_int + #1 ; #2
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\flag_clear_new:N, \flag_clear_new:c}
+% As for other datatypes, clear the \meta{flag~var} or create a new one,
+% as appropriate.
+% \begin{macrocode}
+\cs_new_protected:Npn \flag_clear_new:N #1
+ { \flag_if_exist:NTF #1 { \flag_clear:N } { \flag_new:N } #1 }
+\cs_generate_variant:Nn \flag_clear_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\flag_show:N, \flag_show:c, \flag_log:N, \flag_log:c, \@@_show:NN}
+% Show the height (terminal or log file) using appropriate \pkg{l3msg}
+% auxiliaries.
+% \begin{macrocode}
+\cs_new_protected:Npn \flag_show:N { \@@_show:NN \tl_show:n }
+\cs_generate_variant:Nn \flag_show:N { c }
+\cs_new_protected:Npn \flag_log:N { \@@_show:NN \tl_log:n }
+\cs_generate_variant:Nn \flag_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_chk_defined:NT #2
+ { \exp_args:Ne #1 { \tl_to_str:n { #2 height } = \flag_height:N #2 } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Expandable flag commands}
+%
+% \begin{macro}[EXP, pTF]{\flag_if_exist:N, \flag_if_exist:c}
+% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \flag_if_exist:N \cs_if_exist:N
+ { TF , T , F , p }
+\prg_new_eq_conditional:NNn \flag_if_exist:c \cs_if_exist:c
+ { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, pTF]{\flag_if_raised:N, \flag_if_raised:c}
+% Test if the flag has a non-zero height, by checking the |0| control sequence.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \flag_if_raised:N #1 { p , T , F , TF }
+ {
+ \if_cs_exist:w #1 0 \cs_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_generate_conditional_variant:Nnn \flag_if_raised:N
+ { c } { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\flag_height:N, \flag_height:c}
+% \begin{macro}[EXP]{\@@_height_loop:wN, \@@_height_end:wN}
+% Extract the value of the flag by going through all of the
+% control sequences starting from |0|.
+% \begin{macrocode}
+\cs_new:Npn \flag_height:N #1 { \@@_height_loop:wN 0; #1 }
+\cs_new:Npn \@@_height_loop:wN #1 ; #2
+ {
+ \if_cs_exist:w #2 #1 \cs_end: \else:
+ \exp_after:wN \@@_height_end:wN
+ \fi:
+ \exp_after:wN \@@_height_loop:wN
+ \int_value:w \int_eval:w \c_one_int + #1 ; #2
+ }
+\cs_new:Npn \@@_height_end:wN #1 + #2 ; #3 {#2}
+\cs_generate_variant:Nn \flag_height:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\flag_raise:N, \flag_raise:c}
+% Change the appropriate control sequence to \tn{relax} by expanding a
+% \cs{cs:w} \ldots{} \cs{cs_end:} construction, then pass it to
+% \cs{use_none:n} to avoid leaving anything in the input stream.
+% \begin{macrocode}
+\cs_new:Npn \flag_raise:N #1
+ { \exp_after:wN \use_none:n \cs:w #1 \flag_height:N #1 \cs_end: }
+\cs_generate_variant:Nn \flag_raise:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\flag_ensure_raised:N, \flag_ensure_raised:c}
+% Pass the control sequence with name \meta{flag name}\texttt{0} to
+% \cs{use_none:n}. Constructing the control sequence ensures that it
+% changes from being undefined (if it was so) to being \tn{relax}.
+% \begin{macrocode}
+\cs_new:Npn \flag_ensure_raised:N #1
+ { \exp_after:wN \use_none:n \cs:w #1 0 \cs_end: }
+\cs_generate_variant:Nn \flag_ensure_raised:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Old \texttt{n}-type flag commands}
+%
+% Here we keep the old flag commands since our policy is to no longer
+% delete deprecated functions. The idea is to simply map \meta{flag
+% name} to \cs[no-index]{l_\meta{flag name}_flag}. When the debugging
+% code is activated, it checks existence of the \texttt{N}-type flag
+% variables that result.
+%
+% \begin{macro}[no-user-doc]{\flag_new:n, \flag_clear:n, \flag_clear_new:n}
+% \begin{macro}[EXP, pTF, no-user-doc]{\flag_if_exist:n, \flag_if_raised:n}
+% \begin{macro}[EXP, no-user-doc]{\flag_height:n, \flag_raise:n, \flag_ensure_raised:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \flag_new:n #1 { \flag_new:c { l_#1_flag } }
+\cs_new_protected:Npn \flag_clear:n #1 { \flag_clear:c { l_#1_flag } }
+\cs_new_protected:Npn \flag_clear_new:n #1 { \flag_clear_new:c { l_#1_flag } }
+\cs_new:Npn \flag_if_exist_p:n #1 { \flag_if_exist_p:c { l_#1_flag } }
+\cs_new:Npn \flag_if_exist:nT #1 { \flag_if_exist:cT { l_#1_flag } }
+\cs_new:Npn \flag_if_exist:nF #1 { \flag_if_exist:cF { l_#1_flag } }
+\cs_new:Npn \flag_if_exist:nTF #1 { \flag_if_exist:cTF { l_#1_flag } }
+\cs_new:Npn \flag_if_raised_p:n #1 { \flag_if_raised_p:c { l_#1_flag } }
+\cs_new:Npn \flag_if_raised:nT #1 { \flag_if_raised:cT { l_#1_flag } }
+\cs_new:Npn \flag_if_raised:nF #1 { \flag_if_raised:cF { l_#1_flag } }
+\cs_new:Npn \flag_if_raised:nTF #1 { \flag_if_raised:cTF { l_#1_flag } }
+\cs_new:Npn \flag_height:n #1 { \flag_height:c { l_#1_flag } }
+\cs_new:Npn \flag_raise:n #1 { \flag_raise:c { l_#1_flag } }
+\cs_new:Npn \flag_ensure_raised:n #1 { \flag_ensure_raised:c { l_#1_flag } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[no-user-doc]{\flag_show:n, \flag_log:n, \@@_show:Nn}
+% To avoid changing the output here we mostly keep the old code.
+% \begin{macrocode}
+\cs_new_protected:Npn \flag_show:n { \@@_show:Nn \tl_show:n }
+\cs_new_protected:Npn \flag_log:n { \@@_show:Nn \tl_log:n }
+\cs_new_protected:Npn \@@_show:Nn #1#2
+ {
+ \exp_args:Nc \__kernel_chk_defined:NT { l_#2_flag }
+ {
+ \exp_args:Ne #1
+ { \tl_to_str:n { flag~#2~height } = \flag_height:n {#2} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-assign.dtx b/macros/latex-dev/required/l3kernel/l3fp-assign.dtx
new file mode 100644
index 0000000000..d54f092085
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-assign.dtx
@@ -0,0 +1,316 @@
+% \iffalse meta-comment
+%
+%% File: l3fp-assign.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-assign} module\\
+% Floating point expressions^^A
+% }
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+% \date{Released 2024-04-11}
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp-assign} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% \subsection{Assigning values}
+%
+% \begin{macro}{\fp_new:N}
+% Floating point variables are initialized to be $+0$.
+% \begin{macrocode}
+\cs_new_protected:Npn \fp_new:N #1
+ { \cs_new_eq:NN #1 \c_zero_fp }
+\cs_generate_variant:Nn \fp_new:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \fp_set:Nn, \fp_set:cn,
+% \fp_gset:Nn, \fp_gset:cn,
+% \fp_const:Nn, \fp_const:cn
+% }
+% Simply use \cs{@@_parse:n} within various \texttt{f}-expanding
+% assignments.
+% \begin{macrocode}
+\cs_new_protected:Npn \fp_set:Nn #1#2
+ { \__kernel_tl_set:Nx #1 { \exp_not:f { \@@_parse:n {#2} } } }
+\cs_new_protected:Npn \fp_gset:Nn #1#2
+ { \__kernel_tl_gset:Nx #1 { \exp_not:f { \@@_parse:n {#2} } } }
+\cs_new_protected:Npn \fp_const:Nn #1#2
+ { \tl_const:Ne #1 { \exp_not:f { \@@_parse:n {#2} } } }
+\cs_generate_variant:Nn \fp_set:Nn {c}
+\cs_generate_variant:Nn \fp_gset:Nn {c}
+\cs_generate_variant:Nn \fp_const:Nn {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \fp_set_eq:NN , \fp_set_eq:cN , \fp_set_eq:Nc , \fp_set_eq:cc,
+% \fp_gset_eq:NN, \fp_gset_eq:cN, \fp_gset_eq:Nc, \fp_gset_eq:cc
+% }
+% Copying a floating point is the same as copying the underlying token
+% list.
+% \begin{macrocode}
+\cs_new_eq:NN \fp_set_eq:NN \tl_set_eq:NN
+\cs_new_eq:NN \fp_gset_eq:NN \tl_gset_eq:NN
+\cs_generate_variant:Nn \fp_set_eq:NN { c , Nc , cc }
+\cs_generate_variant:Nn \fp_gset_eq:NN { c , Nc , cc }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp_zero:N, \fp_zero:c, \fp_gzero:N, \fp_gzero:c}
+% Setting a floating point to zero: copy \cs{c_zero_fp}.
+% \begin{macrocode}
+\cs_new_protected:Npn \fp_zero:N #1 { \fp_set_eq:NN #1 \c_zero_fp }
+\cs_new_protected:Npn \fp_gzero:N #1 { \fp_gset_eq:NN #1 \c_zero_fp }
+\cs_generate_variant:Nn \fp_zero:N { c }
+\cs_generate_variant:Nn \fp_gzero:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\fp_zero_new:N, \fp_zero_new:c, \fp_gzero_new:N, \fp_gzero_new:c}
+% Set the floating point to zero, or define it if needed.
+% \begin{macrocode}
+\cs_new_protected:Npn \fp_zero_new:N #1
+ { \fp_if_exist:NTF #1 { \fp_zero:N #1 } { \fp_new:N #1 } }
+\cs_new_protected:Npn \fp_gzero_new:N #1
+ { \fp_if_exist:NTF #1 { \fp_gzero:N #1 } { \fp_new:N #1 } }
+\cs_generate_variant:Nn \fp_zero_new:N { c }
+\cs_generate_variant:Nn \fp_gzero_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Updating values}
+%
+% These match the equivalent functions in \pkg{l3int} and \pkg{l3skip}.
+%
+% \begin{macro}
+% {
+% \fp_add:Nn, \fp_add:cn, \fp_gadd:Nn, \fp_gadd:cn,
+% \fp_sub:Nn, \fp_sub:cn, \fp_gsub:Nn, \fp_gsub:cn,
+% }
+% \begin{macro}{\@@_add:NNNn}
+% For the sake of error recovery we should not simply set |#1| to
+% $|#1| \pm (|#2|)$: for instance, if |#2| is % ^^A(
+% |0)+2|, the parsing error would be raised at the last closing
+% parenthesis rather than at the closing parenthesis in the user
+% argument. Thus we evaluate |#2| instead of just putting
+% parentheses. As an optimization we use \cs{@@_parse:n} rather than
+% \cs{fp_eval:n}, which would convert the result away from the
+% internal representation and back.
+% \begin{macrocode}
+\cs_new_protected:Npn \fp_add:Nn { \@@_add:NNNn \fp_set:Nn + }
+\cs_new_protected:Npn \fp_gadd:Nn { \@@_add:NNNn \fp_gset:Nn + }
+\cs_new_protected:Npn \fp_sub:Nn { \@@_add:NNNn \fp_set:Nn - }
+\cs_new_protected:Npn \fp_gsub:Nn { \@@_add:NNNn \fp_gset:Nn - }
+\cs_new_protected:Npn \@@_add:NNNn #1#2#3#4
+ { #1 #3 { #3 #2 \@@_parse:n {#4} } }
+\cs_generate_variant:Nn \fp_add:Nn { c }
+\cs_generate_variant:Nn \fp_gadd:Nn { c }
+\cs_generate_variant:Nn \fp_sub:Nn { c }
+\cs_generate_variant:Nn \fp_gsub:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Showing values}
+%
+% \begin{macro}{\fp_show:N, \fp_show:c, \fp_log:N, \fp_log:c, \@@_show:NN}
+% This shows the result of computing its argument by
+% passing the right data to \cs{tl_show:n} or \cs{tl_log:n}.
+% \begin{macrocode}
+\cs_new_protected:Npn \fp_show:N { \@@_show:NN \tl_show:n }
+\cs_generate_variant:Nn \fp_show:N { c }
+\cs_new_protected:Npn \fp_log:N { \@@_show:NN \tl_log:n }
+\cs_generate_variant:Nn \fp_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_chk_tl_type:NnnT #2 { fp }
+ { \exp_args:No \@@_show_validate:n #2 }
+ { \exp_args:Ne #1 { \token_to_str:N #2 = \fp_to_tl:N #2 } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_show_validate:n, \@@_show_validate_aux:n, \@@_show_validate:nn,
+% }
+% \begin{macro}[EXP]
+% {
+% \@@_show_validate:w,
+% \@@_tuple_show_validate:w,
+% \@@_symbolic_show_validate:w
+% }
+% To support symbolic expression, validation has to be done recursively.
+% Two |\@@_show_validate:nn| wrappers are used to distinguish between
+% initial and recursive calls, in which the former provides a demo of
+% possible forms a |fp| variable would have.
+% \begin{macrocode}
+\cs_new:Npn \@@_show_validate:n #1
+ {
+ \@@_show_validate:nn { #1 }
+ {
+ \s_@@ \@@_chk:w ??? ;~ or \iow_newline:
+ \s_@@_tuple \_@@_tuple_chk:w ? ;~ or \iow_newline:
+ \s_@@_symbolic \@@_symbolic_chk:w ? , ? ;
+ }
+ }
+\cs_new:Npn \@@_show_validate_aux:n #1
+ {
+ \@@_show_validate:nn { #1 } { }
+ }
+\cs_new:Npn \@@_show_validate:nn #1#2
+ {
+ \tl_if_empty:nF { #1 }
+ {
+ \str_case:enF { \tl_head:n { #1 } }
+ {
+ { \s_@@ }
+ {
+ \@@_show_validate:w #1 \s_@@
+ \@@_chk:w ??? ; \s_@@_stop
+ }
+ { \s_@@_tuple }
+ {
+ \@@_tuple_show_validate:w #1
+ \s_@@_tuple \_@@_tuple_chk:w ?? ; \s_@@_stop
+ }
+ { \s_@@_symbolic }
+ {
+ \@@_symbolic_show_validate:w #1
+ \s_@@_symbolic \@@_symbolic_chk:w ? , ?? ; \s_@@_stop
+ }
+ }
+ { #2 }
+ }
+ }
+\cs_new:Npn \@@_show_validate:w
+ #1 \s_@@ \@@_chk:w #2#3#4#5 ; #6 \s_@@_stop
+ {
+ \str_if_eq:nnF { #2 } {?}
+ {
+ \token_if_eq_meaning:NNTF #2 1
+ { \s_@@ \@@_chk:w #2 #3 { #4 } #5 ; }
+ { \s_@@ \@@_chk:w #2 #3 #4 #5 ; }
+ \@@_show_validate_aux:n { #6 }
+ }
+ }
+\cs_new:Npn \@@_tuple_show_validate:w
+ #1 \s_@@_tuple \_@@_tuple_chk:w #2#3 ; #4 \s_@@_stop
+ {
+ \str_if_eq:nnF { #2 } {?}
+ { \s_@@_tuple \@@_tuple_chk:w { \@@_show_validate_aux:n { #2 } } ; }
+ }
+\cs_new:Npn \@@_symbolic_show_validate:w
+ #1 \s_@@_symbolic \@@_symbolic_chk:w #2 , #3#4 ; #5 \s_@@_stop
+ {
+ \str_if_eq:nnF { #2 } {?}
+ {
+ \s_@@_symbolic \@@_symbolic_chk:w \exp_not:n { #2 } ,
+ { \@@_show_validate_aux:n { #3 } };
+ \@@_show_validate_aux:n { #5 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_show:n, \fp_log:n}
+% Use general tools.
+% \begin{macrocode}
+\cs_new_protected:Npn \fp_show:n
+ { \__kernel_msg_show_eval:Nn \fp_to_tl:n }
+\cs_new_protected:Npn \fp_log:n
+ { \__kernel_msg_log_eval:Nn \fp_to_tl:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Some useful constants and scratch variables}
+%
+% \begin{variable}{\c_one_fp, \c_e_fp}
+% Some constants.
+% \begin{macrocode}
+\fp_const:Nn \c_e_fp { 2.718 2818 2845 9045 }
+\fp_const:Nn \c_one_fp { 1 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_pi_fp, \c_one_degree_fp}
+% We simply round $\pi$ to and $\pi/180$ to $16$ significant digits.
+% \begin{macrocode}
+\fp_const:Nn \c_pi_fp { 3.141 5926 5358 9793 }
+\fp_const:Nn \c_one_degree_fp { 0.0 1745 3292 5199 4330 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_tmpa_fp, \l_tmpb_fp, \g_tmpa_fp, \g_tmpb_fp}
+% Scratch variables are simply initialized there.
+% \begin{macrocode}
+\fp_new:N \l_tmpa_fp
+\fp_new:N \l_tmpb_fp
+\fp_new:N \g_tmpa_fp
+\fp_new:N \g_tmpb_fp
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintChanges
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-aux.dtx b/macros/latex-dev/required/l3kernel/l3fp-aux.dtx
new file mode 100644
index 0000000000..c9d0c228f5
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-aux.dtx
@@ -0,0 +1,1291 @@
+% \iffalse meta-comment
+%
+%% File: l3fp-aux.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-aux} module\\ Support for floating points^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp-aux} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% ^^A todo: make sanitize and pack more homogeneous between modules.
+%
+% \subsection{Access to primitives}
+%
+% \begin{macro}{\@@_int_eval:w, \@@_int_eval_end:, \@@_int_to_roman:w}
+% Largely for performance reasons, we need to directly access primitives
+% rather than use \cs{int_eval:n}. This happens \emph{a lot}, so we
+% use private names. The same is true for \tn{romannumeral}, although it
+% is used much less widely.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_int_eval:w \tex_numexpr:D
+\cs_new_eq:NN \@@_int_eval_end: \scan_stop:
+\cs_new_eq:NN \@@_int_to_roman:w \tex_romannumeral:D
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Internal representation}
+%
+% Internally, a floating point number \meta{X} is a
+% token list containing
+% \begin{quote}
+% \cs{s_@@} \cs{@@_chk:w} \meta{case} \meta{sign} \meta{body} |;|
+% \end{quote}
+% Let us explain each piece separately.
+%
+% Internal floating point numbers are used in expressions,
+% and in this context are subject to \texttt{f}-expansion. They must
+% leave a recognizable mark after \texttt{f}-expansion, to prevent the
+% floating point number from being re-parsed. Thus, \cs{s_@@}
+% is simply another name for \tn{relax}.
+%
+% When used directly without an accessor function, floating points
+% should produce an error: this is the role of \cs{@@_chk:w}. We could
+% make floating point variables be protected to prevent them from
+% expanding under \texttt{e}/\texttt{x}-expansion, but it seems more
+% convenient to treat them as a subcase of token list variables.
+%
+% The (decimal part of the) IEEE-754-2008 standard requires the format
+% to be able to represent special floating point numbers besides the
+% usual positive and negative cases. We distinguish the various
+% possibilities by their \meta{case}, which is a single digit:
+% \begin{itemize}
+% \item[0] zeros: |+0| and |-0|,
+% \item[1] \enquote{normal} numbers (positive and negative),
+% \item[2] infinities: |+inf| and |-inf|,
+% \item[3] quiet and signalling \texttt{nan}.
+% \end{itemize}
+% The \meta{sign} is |0| (positive) or |2| (negative),
+% except in the case of \texttt{nan}, which have $\meta{sign} = 1$.
+% This ensures that changing the \meta{sign} digit to $2-\meta{sign}$
+% is exactly equivalent to changing the sign of the number.
+%
+% Special floating point numbers have the form
+% \begin{quote}
+% \cs{s_@@} \cs{@@_chk:w} \meta{case} \meta{sign} \cs[no-index]{s_@@_\ldots} |;|
+% \end{quote}
+% where \cs[no-index]{s_@@_\ldots} is a scan mark carrying information about how the
+% number was formed (useful for debugging).
+%
+% Normal floating point numbers ($\meta{case} = 1$) have the form
+% \begin{quote}
+% \cs{s_@@} \cs{@@_chk:w} 1 \meta{sign} \Arg{exponent}
+% \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} |;|
+% \end{quote}
+% Here, the \meta{exponent} is an integer, between
+% $-\ExplSyntaxOn\int_use:N\c__fp_minus_min_exponent_int$ and
+% $\ExplSyntaxOn\int_use:N\c__fp_max_exponent_int$. The body consists
+% in four blocks of exactly $4$ digits,
+% $0000 \leq \meta{X_i} \leq 9999$, and the floating point is
+% \[
+% (-1)^{\meta{sign}/2} \meta{X_1}\meta{X_2}\meta{X_3}\meta{X_4}\cdot 10^{\meta{exponent}-16}
+% \]
+% where we have concatenated the $16$ digits. Currently, floating point numbers are normalized such that
+% the \meta{exponent} is minimal, in other words, $1000 \leq \meta{X_1} \leq 9999$.
+%
+% \begin{table}\centering
+% \caption{Internal representation of floating point numbers.}
+% \label{tab:fp-convert-special}
+% \begin{tabular}{ll}
+% \toprule
+% \multicolumn{1}{c}{Representation} & Meaning \\
+% \midrule
+% 0 0 \cs[no-index]{s_@@_\ldots} \texttt{;} & Positive zero. \\
+% 0 2 \cs[no-index]{s_@@_\ldots} \texttt{;} & Negative zero. \\
+% 1 0 \Arg{exponent} \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} \texttt{;}
+% & Positive floating point. \\
+% 1 2 \Arg{exponent} \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} \texttt{;}
+% & Negative floating point. \\
+% 2 0 \cs[no-index]{s_@@_\ldots} \texttt{;} & Positive infinity. \\
+% 2 2 \cs[no-index]{s_@@_\ldots} \texttt{;} & Negative infinity. \\
+% 3 1 \cs[no-index]{s_@@_\ldots} \texttt{;} & Quiet \texttt{nan}. \\
+% 3 1 \cs[no-index]{s_@@_\ldots} \texttt{;} & Signalling \texttt{nan}. \\
+% \bottomrule
+% \end{tabular}
+% \end{table}
+%
+% Calculations are done in base $10000$, \emph{i.e.} one myriad.
+%
+% \subsection{Using arguments and semicolons}
+%
+% \begin{macro}[EXP]{\@@_use_none_stop_f:n}
+% This function removes an argument (typically a digit) and replaces
+% it by \cs{exp_stop_f:}, a marker which stops \texttt{f}-type
+% expansion.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_none_stop_f:n #1 { \exp_stop_f: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_use_s:n, \@@_use_s:nn}
+% Those functions place a semicolon after one or two arguments
+% (typically digits).
+% \begin{macrocode}
+\cs_new:Npn \@@_use_s:n #1 { #1; }
+\cs_new:Npn \@@_use_s:nn #1#2 { #1#2; }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_use_none_until_s:w, \@@_use_i_until_s:nw, \@@_use_ii_until_s:nnw}
+% Those functions select specific arguments among a set of arguments
+% delimited by a semicolon.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_none_until_s:w #1; { }
+\cs_new:Npn \@@_use_i_until_s:nw #1#2; {#1}
+\cs_new:Npn \@@_use_ii_until_s:nnw #1#2#3; {#2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_reverse_args:Nww}
+% Many internal functions take arguments delimited by semicolons, and
+% it is occasionally useful to swap two such arguments.
+% \begin{macrocode}
+\cs_new:Npn \@@_reverse_args:Nww #1 #2; #3; { #1 #3; #2; }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_rrot:www}
+% Rotate three arguments delimited by semicolons. This is the inverse
+% (or the square) of the Forth primitive |ROT|, hence the name.
+% \begin{macrocode}
+\cs_new:Npn \@@_rrot:www #1; #2; #3; { #2; #3; #1; }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_use_i:ww, \@@_use_i:www}
+% Many internal functions take arguments delimited by semicolons, and
+% it is occasionally useful to remove one or two such arguments.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_i:ww #1; #2; { #1; }
+\cs_new:Npn \@@_use_i:www #1; #2; #3; { #1; }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Constants, and structure of floating points}
+%
+% \begin{macro}{\@@_misused:n}
+% This receives a floating point object (floating point number or
+% tuple) and generates an error stating that it was misused. This is
+% called when for instance an |fp| variable is left in the input
+% stream and its contents reach \TeX{}'s stomach.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_misused:n #1
+ { \msg_error:nne { fp } { misused } { \fp_to_tl:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\s_@@, \@@_chk:w}
+% Floating points numbers all start with \cs{s_@@} \cs{@@_chk:w},
+% where \cs{s_@@} is equal to the \TeX{} primitive \tn{relax}, and
+% \cs{@@_chk:w} is protected. The rest of the floating point number
+% is made of characters (or \tn{relax}). This ensures that nothing
+% expands under \texttt{f}-expansion, nor under
+% \texttt{e}/\texttt{x}-expansion.
+% However, when typeset, \cs{s_@@} does nothing, and \cs{@@_chk:w} is
+% expanded. We define \cs{@@_chk:w} to produce an error.
+% \begin{macrocode}
+\scan_new:N \s_@@
+\cs_new_protected:Npn \@@_chk:w #1 ;
+ { \@@_misused:n { \s_@@ \@@_chk:w #1 ; } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\s_@@_expr_mark, \s_@@_expr_stop}
+% Aliases of \cs{tex_relax:D}, used to terminate expressions.
+% \begin{macrocode}
+\scan_new:N \s_@@_expr_mark
+\scan_new:N \s_@@_expr_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\s_@@_mark, \s_@@_stop}
+% Generic scan marks used throughout the module.
+% \begin{macrocode}
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_use_i_delimit_by_s_stop:nw}
+% Functions to gobble up to a scan mark.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_i_delimit_by_s_stop:nw #1 #2 \s_@@_stop {#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \s_@@_invalid, \s_@@_underflow, \s_@@_overflow,
+% \s_@@_division, \s_@@_exact
+% }
+% A couple of scan marks used to indicate where special floating point
+% numbers come from.
+% \begin{macrocode}
+\scan_new:N \s_@@_invalid
+\scan_new:N \s_@@_underflow
+\scan_new:N \s_@@_overflow
+\scan_new:N \s_@@_division
+\scan_new:N \s_@@_exact
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}
+% {\c_zero_fp, \c_minus_zero_fp, \c_inf_fp, \c_minus_inf_fp, \c_nan_fp}
+% The special floating points. We define the floating points here as \enquote{exact}.
+% \begin{macrocode}
+\tl_const:Nn \c_zero_fp { \s_@@ \@@_chk:w 0 0 \s_@@_exact ; }
+\tl_const:Nn \c_minus_zero_fp { \s_@@ \@@_chk:w 0 2 \s_@@_exact ; }
+\tl_const:Nn \c_inf_fp { \s_@@ \@@_chk:w 2 0 \s_@@_exact ; }
+\tl_const:Nn \c_minus_inf_fp { \s_@@ \@@_chk:w 2 2 \s_@@_exact ; }
+\tl_const:Nn \c_nan_fp { \s_@@ \@@_chk:w 3 1 \s_@@_exact ; }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_prec_int, \c_@@_half_prec_int, \c_@@_block_int}
+% The number of digits of floating points.
+% \begin{macrocode}
+\int_const:Nn \c_@@_prec_int { 16 }
+\int_const:Nn \c_@@_half_prec_int { 8 }
+\int_const:Nn \c_@@_block_int { 4 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_myriad_int}
+% Blocks have $4$~digits so this integer is useful.
+% \begin{macrocode}
+\int_const:Nn \c_@@_myriad_int { 10000 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_minus_min_exponent_int, \c_@@_max_exponent_int}
+% Normal floating point numbers have an exponent between $-$
+% \texttt{minus_min_exponent} and \texttt{max_exponent} inclusive.
+% Larger numbers are rounded to $\pm\infty$. Smaller numbers are
+% rounded to $\pm 0$. It would be more natural to define a
+% \texttt{min_exponent} with the opposite sign but that would waste
+% one \TeX{} count.
+% \begin{macrocode}
+\int_const:Nn \c_@@_minus_min_exponent_int { 10000 }
+\int_const:Nn \c_@@_max_exponent_int { 10000 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_max_exp_exponent_int}
+% If a number's exponent is larger than that, its exponential
+% overflows/underflows.
+% \begin{macrocode}
+\int_const:Nn \c_@@_max_exp_exponent_int { 5 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_overflowing_fp}
+% A floating point number that is bigger than all normal floating
+% point numbers. This replaces infinities when converting to formats
+% that do not support infinities.
+% \begin{macrocode}
+\tl_const:Ne \c_@@_overflowing_fp
+ {
+ \s_@@ \@@_chk:w 1 0
+ { \int_eval:n { \c_@@_max_exponent_int + 1 } }
+ {1000} {0000} {0000} {0000} ;
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_zero_fp:N, \@@_inf_fp:N}
+% In case of overflow or underflow, we have to output
+% a zero or infinity with a given sign.
+% \begin{macrocode}
+\cs_new:Npn \@@_zero_fp:N #1
+ { \s_@@ \@@_chk:w 0 #1 \s_@@_underflow ; }
+\cs_new:Npn \@@_inf_fp:N #1
+ { \s_@@ \@@_chk:w 2 #1 \s_@@_overflow ; }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_exponent:w}
+% For normal numbers, the function expands to the exponent, otherwise
+% to $0$. This is used in \pkg{l3str-format}.
+% \begin{macrocode}
+\cs_new:Npn \@@_exponent:w \s_@@ \@@_chk:w #1
+ {
+ \if_meaning:w 1 #1
+ \exp_after:wN \@@_use_ii_until_s:nnw
+ \else:
+ \exp_after:wN \@@_use_i_until_s:nw
+ \exp_after:wN 0
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_neg_sign:N}
+% When appearing in an integer expression or after \cs{int_value:w},
+% this expands to the sign opposite to |#1|, namely $0$ (positive) is
+% turned to $2$ (negative), $1$ (\texttt{nan}) to $1$, and $2$ to $0$.
+% \begin{macrocode}
+\cs_new:Npn \@@_neg_sign:N #1
+ { \@@_int_eval:w 2 - #1 \@@_int_eval_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_kind:w}
+% Expands to $0$ for zeros, $1$ for normal floating point numbers, $2$
+% for infinities, $3$ for \nan{}, $4$ for tuples.
+% \begin{macrocode}
+\cs_new:Npn \@@_kind:w #1
+ {
+ \@@_if_type_fp:NTwFw
+ #1 \@@_use_ii_until_s:nnw
+ \s_@@ { \@@_use_i_until_s:nw 4 }
+ \s_@@_stop
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Overflow, underflow, and exact zero}
+%
+%^^A todo: the sign of exact zeros should depend on the rounding mode.
+%
+% \begin{macro}[EXP]{\@@_sanitize:Nw, \@@_sanitize:wN}
+% \begin{macro}[EXP]{\@@_sanitize_zero:w}
+% Expects the sign and the exponent in some order, then the
+% significand (which we don't touch). Outputs the corresponding
+% floating point number, possibly underflowed to $\pm 0$ or overflowed
+% to $\pm\infty$. The functions \cs{@@_underflow:w} and
+% \cs{@@_overflow:w} are defined in \pkg{l3fp-traps}.
+% \begin{macrocode}
+\cs_new:Npn \@@_sanitize:Nw #1 #2;
+ {
+ \if_case:w
+ \if_int_compare:w #2 > \c_@@_max_exponent_int 1 ~ \else:
+ \if_int_compare:w #2 < - \c_@@_minus_min_exponent_int 2 ~ \else:
+ \if_meaning:w 1 #1 3 ~ \fi: \fi: \fi: 0 ~
+ \or: \exp_after:wN \@@_overflow:w
+ \or: \exp_after:wN \@@_underflow:w
+ \or: \exp_after:wN \@@_sanitize_zero:w
+ \fi:
+ \s_@@ \@@_chk:w 1 #1 {#2}
+ }
+\cs_new:Npn \@@_sanitize:wN #1; #2 { \@@_sanitize:Nw #2 #1; }
+\cs_new:Npn \@@_sanitize_zero:w \s_@@ \@@_chk:w #1 #2 #3;
+ { \c_zero_fp }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Expanding after a floating point number}
+%
+% \begin{macro}[EXP]{\@@_exp_after_o:w}
+% \begin{macro}[EXP]{\@@_exp_after_f:nw}
+% \begin{syntax}
+% \cs{@@_exp_after_o:w} \meta{floating point}
+% \cs{@@_exp_after_f:nw} \Arg{tokens} \meta{floating point}
+% \end{syntax}
+% Places \meta{tokens} (empty in the case of \cs{@@_exp_after_o:w})
+% between the \meta{floating point} and the following tokens, then
+% hits those tokens with \texttt{o} or \texttt{f}-expansion, and
+% leaves the floating point number unchanged.
+%
+% We first distinguish normal floating points, which have a significand,
+% from the much simpler special floating points.
+% \begin{macrocode}
+\cs_new:Npn \@@_exp_after_o:w \s_@@ \@@_chk:w #1
+ {
+ \if_meaning:w 1 #1
+ \exp_after:wN \@@_exp_after_normal:nNNw
+ \else:
+ \exp_after:wN \@@_exp_after_special:nNNw
+ \fi:
+ { }
+ #1
+ }
+\cs_new:Npn \@@_exp_after_f:nw #1 \s_@@ \@@_chk:w #2
+ {
+ \if_meaning:w 1 #2
+ \exp_after:wN \@@_exp_after_normal:nNNw
+ \else:
+ \exp_after:wN \@@_exp_after_special:nNNw
+ \fi:
+ { \exp:w \exp_end_continue_f:w #1 }
+ #2
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_exp_after_special:nNNw}
+% \begin{syntax}
+% \cs{@@_exp_after_special:nNNw} \Arg{after} \meta{case} \meta{sign} \meta{scan mark} |;|
+% \end{syntax}
+% Special floating point numbers are easy to jump over since they
+% contain few tokens.
+% \begin{macrocode}
+\cs_new:Npn \@@_exp_after_special:nNNw #1#2#3#4;
+ {
+ \exp_after:wN \s_@@
+ \exp_after:wN \@@_chk:w
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \exp_after:wN #4
+ \exp_after:wN ;
+ #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_exp_after_normal:nNNw}
+% For normal floating point numbers, life is slightly harder, since we
+% have many tokens to jump over. Here it would be slightly better if
+% the digits were not braced but instead were delimited arguments (for
+% instance delimited by |,|). That may be changed some day.
+% \begin{macrocode}
+\cs_new:Npn \@@_exp_after_normal:nNNw #1 1 #2 #3 #4#5#6#7;
+ {
+ \exp_after:wN \@@_exp_after_normal:Nwwwww
+ \exp_after:wN #2
+ \int_value:w #3 \exp_after:wN ;
+ \int_value:w 1 #4 \exp_after:wN ;
+ \int_value:w 1 #5 \exp_after:wN ;
+ \int_value:w 1 #6 \exp_after:wN ;
+ \int_value:w 1 #7 \exp_after:wN ; #1
+ }
+\cs_new:Npn \@@_exp_after_normal:Nwwwww
+ #1 #2; 1 #3 ; 1 #4 ; 1 #5 ; 1 #6 ;
+ { \s_@@ \@@_chk:w 1 #1 {#2} {#3} {#4} {#5} {#6} ; }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Other floating point types}
+%
+% \begin{macro}{\s_@@_tuple, \@@_tuple_chk:w}
+% \begin{variable}{\c_@@_empty_tuple_fp}
+% Floating point tuples take the form \cs{s_@@_tuple}
+% \cs{@@_tuple_chk:w} |{| \meta{fp 1} \meta{fp 2} \dots |}| |;| where
+% each \meta{fp} is a floating point number or tuple, hence ends with
+% |;| itself. When a tuple is typeset, \cs{@@_tuple_chk:w} produces
+% an error, just like usual floating point numbers.
+% Tuples may have zero or one element.
+% \begin{macrocode}
+\scan_new:N \s_@@_tuple
+\cs_new_protected:Npn \@@_tuple_chk:w #1 ;
+ { \@@_misused:n { \s_@@_tuple \@@_tuple_chk:w #1 ; } }
+\tl_const:Nn \c_@@_empty_tuple_fp
+ { \s_@@_tuple \@@_tuple_chk:w { } ; }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_tuple_count:w, \@@_array_count:n}
+% \begin{macro}[EXP]{\@@_tuple_count_loop:Nw}
+% Count the number of items in a tuple of floating points by counting
+% semicolons. The technique is very similar to \cs{tl_count:n}, but
+% with the loop built-in. Checking for the end of the loop is done
+% with the |\use_none:n #1| construction.
+% \begin{macrocode}
+\cs_new:Npn \@@_array_count:n #1
+ { \@@_tuple_count:w \s_@@_tuple \@@_tuple_chk:w {#1} ; }
+\cs_new:Npn \@@_tuple_count:w \s_@@_tuple \@@_tuple_chk:w #1 ;
+ {
+ \int_value:w \@@_int_eval:w 0
+ \@@_tuple_count_loop:Nw #1 { ? \prg_break: } ;
+ \prg_break_point:
+ \@@_int_eval_end:
+ }
+\cs_new:Npn \@@_tuple_count_loop:Nw #1#2;
+ { \use_none:n #1 + 1 \@@_tuple_count_loop:Nw }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_if_type_fp:NTwFw}
+% Used as \cs{@@_if_type_fp:NTwFw} \meta{marker} \Arg{true code}
+% \cs{s_@@} \Arg{false code} \cs{s_@@_stop}, this test whether the
+% \meta{marker} is \cs{s_@@} or not and runs the appropriate
+% \meta{code}. The very unusual syntax is for optimization purposes
+% as that function is used for all floating point operations.
+% \begin{macrocode}
+\cs_new:Npn \@@_if_type_fp:NTwFw #1 \s_@@ #2 #3 \s_@@_stop {#2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_array_if_all_fp:nTF, \@@_array_if_all_fp_loop:w}
+% True if all items are floating point numbers. Used for |min|.
+% \begin{macrocode}
+\cs_new:Npn \@@_array_if_all_fp:nTF #1
+ {
+ \@@_array_if_all_fp_loop:w #1 { \s_@@ \prg_break: } ;
+ \prg_break_point: \use_i:nn
+ }
+\cs_new:Npn \@@_array_if_all_fp_loop:w #1#2 ;
+ {
+ \@@_if_type_fp:NTwFw
+ #1 \@@_array_if_all_fp_loop:w
+ \s_@@ { \prg_break:n \use_iii:nnn }
+ \s_@@_stop
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_type_from_scan:N, \@@_type_from_scan_other:N, \@@_type_from_scan:w}
+% Used as \cs{@@_type_from_scan:N} \meta{token}.
+% Grabs the pieces of the stringified \meta{token} which lies after
+% the first |s__fp|. If the \meta{token} does not contain that
+% string, the result is |_?|.
+% \begin{macrocode}
+\cs_new:Npn \@@_type_from_scan:N #1
+ {
+ \@@_if_type_fp:NTwFw
+ #1 { }
+ \s_@@ { \@@_type_from_scan_other:N #1 }
+ \s_@@_stop
+ }
+\cs_new:Npe \@@_type_from_scan_other:N #1
+ {
+ \exp_not:N \exp_after:wN \exp_not:N \@@_type_from_scan:w
+ \exp_not:N \token_to_str:N #1 \s_@@_mark
+ \tl_to_str:n { s_@@ _? } \s_@@_mark \s_@@_stop
+ }
+\exp_last_unbraced:NNNNo
+ \cs_new:Npn \@@_type_from_scan:w #1
+ { \tl_to_str:n { s_@@ } } #2 \s_@@_mark #3 \s_@@_stop {#2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_change_func_type:NNN}
+% \begin{macro}[EXP]{\@@_change_func_type_aux:w, \@@_change_func_type_chk:NNN}
+% Arguments are \meta{type marker} \meta{function} \meta{recovery}.
+% This gives the function obtained by placing the type after |@@|. If
+% the function is not defined then \meta{recovery} \meta{function} is
+% used instead; however that test is not run when the \meta{type
+% marker} is \cs{s_@@}.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_func_type:NNN #1#2#3
+ {
+ \@@_if_type_fp:NTwFw
+ #1 #2
+ \s_@@
+ {
+ \exp_after:wN \@@_change_func_type_chk:NNN
+ \cs:w
+ @@ \@@_type_from_scan_other:N #1
+ \exp_after:wN \@@_change_func_type_aux:w \token_to_str:N #2
+ \cs_end:
+ #2 #3
+ }
+ \s_@@_stop
+ }
+\exp_last_unbraced:NNNNo
+ \cs_new:Npn \@@_change_func_type_aux:w #1 { \tl_to_str:n { @@ } } { }
+\cs_new:Npn \@@_change_func_type_chk:NNN #1#2#3
+ {
+ \if_meaning:w \scan_stop: #1
+ \exp_after:wN #3 \exp_after:wN #2
+ \else:
+ \exp_after:wN #1
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_exp_after_any_f:Nnw, \@@_exp_after_any_f:nw}
+% \begin{macro}[EXP]{\@@_exp_after_expr_stop_f:nw}
+% The |Nnw| function simply dispatches to the appropriate
+% \cs[no-index]{@@_exp_after\ldots{}_f:nw} with \enquote{\ldots{}}
+% (either empty or |_|\meta{type}) extracted from |#1|, which should
+% start with |\s__fp|. If it doesn't start with |\s__fp| the function
+% \cs{@@_exp_after_?_f:nw} defined in \pkg{l3fp-parse} gives an error;
+% another special \meta{type} is |stop|, useful for loops, see below.
+% The |nw| function has an important optimization for floating points
+% numbers; it also fetches its type marker |#2| from the floating
+% point.
+% \begin{macrocode}
+\cs_new:Npn \@@_exp_after_any_f:Nnw #1
+ { \cs:w @@_exp_after \@@_type_from_scan_other:N #1 _f:nw \cs_end: }
+\cs_new:Npn \@@_exp_after_any_f:nw #1#2
+ {
+ \@@_if_type_fp:NTwFw
+ #2 \@@_exp_after_f:nw
+ \s_@@ { \@@_exp_after_any_f:Nnw #2 }
+ \s_@@_stop
+ {#1} #2
+ }
+\cs_new_eq:NN \@@_exp_after_expr_stop_f:nw \use_none:nn
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_exp_after_tuple_o:w}
+% \begin{macro}[EXP]{\@@_exp_after_tuple_f:nw, \@@_exp_after_array_f:w}
+% The loop works by using the |n| argument of
+% \cs{@@_exp_after_any_f:nw} to place the loop macro after the next
+% item in the tuple and expand it.
+% \begin{quote}
+% \cs{@@_exp_after_array_f:w}\\
+% \meta{fp_1} |;|\\
+% \ldots{}\\
+% \meta{fp_n} |;|\\
+% \cs{s_@@_expr_stop}
+% \end{quote}
+% \begin{macrocode}
+\cs_new:Npn \@@_exp_after_tuple_o:w
+ { \@@_exp_after_tuple_f:nw { \exp_after:wN \exp_stop_f: } }
+\cs_new:Npn \@@_exp_after_tuple_f:nw
+ #1 \s_@@_tuple \@@_tuple_chk:w #2 ;
+ {
+ \exp_after:wN \s_@@_tuple
+ \exp_after:wN \@@_tuple_chk:w
+ \exp_after:wN {
+ \exp:w \exp_end_continue_f:w
+ \@@_exp_after_array_f:w #2 \s_@@_expr_stop
+ \exp_after:wN }
+ \exp_after:wN ;
+ \exp:w \exp_end_continue_f:w #1
+ }
+\cs_new:Npn \@@_exp_after_array_f:w
+ { \@@_exp_after_any_f:nw { \@@_exp_after_array_f:w } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Packing digits}
+%
+% When a positive integer |#1| is known to be less than $10^8$, the
+% following trick splits it into two blocks of $4$ digits, padding
+% with zeros on the left.
+% \begin{verbatim}
+% \cs_new:Npn \pack:NNNNNw #1 #2#3#4#5 #6; { {#2#3#4#5} {#6} }
+% \exp_after:wN \pack:NNNNNw
+% \__fp_int_value:w \__fp_int_eval:w 1 0000 0000 + #1 ;
+% \end{verbatim}
+% The idea is that adding $10^8$ to the number ensures that it has
+% exactly $9$ digits, and can then easily find which digits correspond
+% to what position in the number. Of course, this can be modified
+% for any number of digits less or equal to~$9$ (we are limited by
+% \TeX{}'s integers). This method is very heavily relied upon in
+% \texttt{l3fp-basics}.
+%
+% More specifically, the auxiliary inserts |+ #1#2#3#4#5 ; {#6}|, which
+% allows us to compute several blocks of $4$ digits in a nested manner,
+% performing carries on the fly. Say we want to compute $1\,2345 \times
+% 6677\,8899$. With simplified names, we would do
+% \begin{verbatim}
+% \exp_after:wN \post_processing:w
+% \__fp_int_value:w \__fp_int_eval:w - 5 0000
+% \exp_after:wN \pack:NNNNNw
+% \__fp_int_value:w \__fp_int_eval:w 4 9995 0000
+% + 12345 * 6677
+% \exp_after:wN \pack:NNNNNw
+% \__fp_int_value:w \__fp_int_eval:w 5 0000 0000
+% + 12345 * 8899 ;
+% \end{verbatim}
+% The \cs{exp_after:wN} triggers \cs{int_value:w} \cs{@@_int_eval:w}, which
+% starts a first computation, whose initial value is $- 5\,0000$ (the
+% \enquote{leading shift}). In that computation appears an
+% \cs{exp_after:wN}, which triggers the nested computation
+% \cs{int_value:w} \cs{@@_int_eval:w} with starting value $4\,9995\,0000$ (the
+% \enquote{middle shift}). That, in turn, expands \cs{exp_after:wN}
+% which triggers the third computation. The third computation's value
+% is $5\,0000\,0000 + 12345 \times 8899$, which has $9$ digits. Adding
+% $5\cdot 10^{8}$ to the product allowed us to know how many digits to
+% expect as long as the numbers to multiply are not too big; it
+% also works to some extent with negative results. The \texttt{pack}
+% function puts the last $4$ of those $9$ digits into a brace group,
+% moves the semi-colon delimiter, and inserts a |+|, which combines the
+% carry with the previous computation. The shifts nicely combine into
+% $5\,0000\,0000 / 10^{4} + 4\,9995\,0000 = 5\,0000\,0000$. As long as
+% the operands are in some range, the result of this second computation
+% has $9$ digits. The corresponding \texttt{pack} function,
+% expanded after the result is computed, braces the last $4$ digits, and
+% leaves |+| \meta{5 digits} for the initial computation. The
+% \enquote{leading shift} cancels the combination of the other shifts,
+% and the |\post_processing:w| takes care of packing the last few
+% digits.
+%
+% Admittedly, this is quite intricate. It is probably the key in making
+% \pkg{l3fp} as fast as other pure \TeX{} floating point units despite
+% its increased precision. In fact, this is used so much that we
+% provide different sets of packing functions and shifts, depending on
+% ranges of input.
+%
+% \begin{macro}[EXP]{\@@_pack:NNNNNw}
+% \begin{variable}
+% {
+% \c_@@_trailing_shift_int ,
+% \c_@@_middle_shift_int ,
+% \c_@@_leading_shift_int ,
+% }
+% This set of shifts allows for computations involving results in the
+% range $[-4\cdot 10^{8}, 5\cdot 10^{8}-1]$. Shifted values all have
+% exactly $9$ digits.
+% \begin{macrocode}
+\int_const:Nn \c_@@_leading_shift_int { - 5 0000 }
+\int_const:Nn \c_@@_middle_shift_int { 5 0000 * 9999 }
+\int_const:Nn \c_@@_trailing_shift_int { 5 0000 * 10000 }
+\cs_new:Npn \@@_pack:NNNNNw #1 #2#3#4#5 #6; { + #1#2#3#4#5 ; {#6} }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_pack_big:NNNNNNw}
+% \begin{variable}
+% {
+% \c_@@_big_trailing_shift_int ,
+% \c_@@_big_middle_shift_int ,
+% \c_@@_big_leading_shift_int ,
+% }
+% This set of shifts allows for computations involving results in the
+% range $[-5\cdot 10^{8}, 6\cdot 10^{8}-1]$ (actually a bit more).
+% Shifted values all have exactly $10$ digits. Note that the upper
+% bound is due to \TeX{}'s limit of $2^{31}-1$ on integers. The
+% shifts are chosen to be roughly the mid-point of $10^{9}$ and
+% $2^{31}$, the two bounds on $10$-digit integers in \TeX{}.
+% \begin{macrocode}
+\int_const:Nn \c_@@_big_leading_shift_int { - 15 2374 }
+\int_const:Nn \c_@@_big_middle_shift_int { 15 2374 * 9999 }
+\int_const:Nn \c_@@_big_trailing_shift_int { 15 2374 * 10000 }
+\cs_new:Npn \@@_pack_big:NNNNNNw #1#2 #3#4#5#6 #7;
+ { + #1#2#3#4#5#6 ; {#7} }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% ^^A \@@_pack_Bigg:NNNNNNw = \@@_pack_big:NNNNNNw ?
+% \begin{macro}[EXP]{\@@_pack_Bigg:NNNNNNw}
+% \begin{variable}
+% {
+% \c_@@_Bigg_trailing_shift_int ,
+% \c_@@_Bigg_middle_shift_int ,
+% \c_@@_Bigg_leading_shift_int ,
+% }
+% This set of shifts allows for computations with results in the
+% range $[-1\cdot 10^{9}, 147483647]$; the end-point is $2^{31} - 1 -
+% 2\cdot 10^{9} \simeq 1.47\cdot 10^{8}$. Shifted values all have
+% exactly $10$ digits.
+% \begin{macrocode}
+\int_const:Nn \c_@@_Bigg_leading_shift_int { - 20 0000 }
+\int_const:Nn \c_@@_Bigg_middle_shift_int { 20 0000 * 9999 }
+\int_const:Nn \c_@@_Bigg_trailing_shift_int { 20 0000 * 10000 }
+\cs_new:Npn \@@_pack_Bigg:NNNNNNw #1#2 #3#4#5#6 #7;
+ { + #1#2#3#4#5#6 ; {#7} }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_pack_twice_four:wNNNNNNNN}
+% \begin{syntax}
+% \cs{@@_pack_twice_four:wNNNNNNNN} \meta{tokens} |;| \meta{$\geq 8$ digits}
+% \end{syntax}
+% Grabs two sets of $4$ digits and places them before the semi-colon
+% delimiter. Putting several copies of this function before a
+% semicolon packs more digits since each takes the digits
+% packed by the others in its first argument.
+% \begin{macrocode}
+\cs_new:Npn \@@_pack_twice_four:wNNNNNNNN #1; #2#3#4#5 #6#7#8#9
+ { #1 {#2#3#4#5} {#6#7#8#9} ; }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_pack_eight:wNNNNNNNN}
+% \begin{syntax}
+% \cs{@@_pack_eight:wNNNNNNNN} \meta{tokens} |;| \meta{$\geq 8$ digits}
+% \end{syntax}
+% Grabs one set of $8$ digits and places them before the semi-colon
+% delimiter as a single group. Putting several copies of this
+% function before a semicolon packs more digits since each
+% takes the digits packed by the others in its first argument.
+% \begin{macrocode}
+\cs_new:Npn \@@_pack_eight:wNNNNNNNN #1; #2#3#4#5 #6#7#8#9
+ { #1 {#2#3#4#5#6#7#8#9} ; }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_basics_pack_low:NNNNNw,
+% \@@_basics_pack_high:NNNNNw,
+% \@@_basics_pack_high_carry:w
+% }
+% Addition and multiplication of significands are done in two steps:
+% first compute a (more or less) exact result, then round and pack
+% digits in the final (braced) form. These functions take care of the
+% packing, with special attention given to the case where rounding has
+% caused a carry. Since rounding can only shift the final digit by
+% $1$, a carry always produces an exact power of $10$. Thus,
+% \cs{@@_basics_pack_high_carry:w} is always followed by four times
+% |{0000}|.
+%
+% This is used in \pkg{l3fp-basics} and \pkg{l3fp-extended}.
+% \begin{macrocode}
+\cs_new:Npn \@@_basics_pack_low:NNNNNw #1 #2#3#4#5 #6;
+ { + #1 - 1 ; {#2#3#4#5} {#6} ; }
+\cs_new:Npn \@@_basics_pack_high:NNNNNw #1 #2#3#4#5 #6;
+ {
+ \if_meaning:w 2 #1
+ \@@_basics_pack_high_carry:w
+ \fi:
+ ; {#2#3#4#5} {#6}
+ }
+\cs_new:Npn \@@_basics_pack_high_carry:w \fi: ; #1
+ { \fi: + 1 ; {1000} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_basics_pack_weird_low:NNNNw,
+% \@@_basics_pack_weird_high:NNNNNNNNw
+% }
+% This is used in \pkg{l3fp-basics} for additions and
+% divisions. Their syntax is confusing, hence the name.
+% \begin{macrocode}
+\cs_new:Npn \@@_basics_pack_weird_low:NNNNw #1 #2#3#4 #5;
+ {
+ \if_meaning:w 2 #1
+ + 1
+ \fi:
+ \@@_int_eval_end:
+ #2#3#4; {#5} ;
+ }
+\cs_new:Npn \@@_basics_pack_weird_high:NNNNNNNNw
+ 1 #1#2#3#4 #5#6#7#8 #9; { ; {#1#2#3#4} {#5#6#7#8} {#9} }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Decimate (dividing by a power of 10)}
+%
+% ^^A begin[todo]
+% \begin{macro}[EXP]{\@@_decimate:nNnnnn}
+% \begin{syntax}
+% \cs{@@_decimate:nNnnnn} \Arg{shift} \meta{f_1}
+% ~~\Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4}
+% \end{syntax}
+% Each \meta{X_i} consists in $4$ digits exactly,
+% and $1000\leq\meta{X_1}<9999$. The first argument determines
+% by how much we shift the digits. \meta{f_1} is called as follows:
+% \begin{syntax}
+% \meta{f_1} \meta{rounding} \Arg{X'_1} \Arg{X'_2} \meta{extra-digits} |;|
+% \end{syntax}
+% where $0\leq\meta{X'_i}<10^{8}-1$ are $8$ digit integers,
+% forming the truncation of our number. In other words,
+% \[
+% \left(
+% \sum_{i=1}^{4} \meta{X_i} \cdot 10^{-4i} \cdot 10^{-\meta{shift}}
+% \right)
+% - \bigl( \meta{X'_1} \cdot 10^{-8} + \meta{X'_2} \cdot 10^{-16} \bigr)
+% = 0.\meta{extra-digits} \cdot 10^{-16}
+% \in [0,10^{-16}).
+% \]
+% To round properly later, we need to remember some information
+% about the difference. The \meta{rounding} digit is $0$ if and
+% only if the difference is exactly $0$, and $5$ if and only if
+% the difference is exactly $0.5\cdot 10^{-16}$. Otherwise, it
+% is the (non-$0$, non-$5$) digit closest to $10^{17}$ times the
+% difference. In particular, if the shift is $17$ or more, all
+% the digits are dropped, \meta{rounding} is $1$ (not $0$), and
+% \meta{X'_1} and \meta{X'_2} are both zero.
+%
+% If the shift is $1$, the \meta{rounding} digit is simply the
+% only digit that was pushed out of the brace groups (this is
+% important for subtraction). It would be more natural for the
+% \meta{rounding} digit to be placed after the \meta{X'_i},
+% but the choice we make involves less reshuffling.
+%
+% Note that this function treats negative \meta{shift} as $0$.
+% \begin{macrocode}
+\cs_new:Npn \@@_decimate:nNnnnn #1
+ {
+ \cs:w
+ @@_decimate_
+ \if_int_compare:w \@@_int_eval:w #1 > \c_@@_prec_int
+ tiny
+ \else:
+ \@@_int_to_roman:w \@@_int_eval:w #1
+ \fi:
+ :Nnnnn
+ \cs_end:
+ }
+% \end{macrocode}
+% Each of the auxiliaries see the function \meta{f_1},
+% followed by $4$ blocks of $4$ digits.
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_decimate_:Nnnnn, \@@_decimate_tiny:Nnnnn}
+% If the \meta{shift} is zero, or too big, life is very easy.
+% \begin{macrocode}
+\cs_new:Npn \@@_decimate_:Nnnnn #1 #2#3#4#5
+ { #1 0 {#2#3} {#4#5} ; }
+\cs_new:Npn \@@_decimate_tiny:Nnnnn #1 #2#3#4#5
+ { #1 1 { 0000 0000 } { 0000 0000 } 0 #2#3#4#5 ; }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_decimate_auxi:Nnnnn, \@@_decimate_auxii:Nnnnn,
+% \@@_decimate_auxiii:Nnnnn, \@@_decimate_auxiv:Nnnnn,
+% \@@_decimate_auxv:Nnnnn, \@@_decimate_auxvi:Nnnnn,
+% \@@_decimate_auxvii:Nnnnn, \@@_decimate_auxviii:Nnnnn,
+% \@@_decimate_auxix:Nnnnn, \@@_decimate_auxx:Nnnnn,
+% \@@_decimate_auxxi:Nnnnn, \@@_decimate_auxxii:Nnnnn,
+% \@@_decimate_auxxiii:Nnnnn, \@@_decimate_auxxiv:Nnnnn,
+% \@@_decimate_auxxv:Nnnnn, \@@_decimate_auxxvi:Nnnnn
+% }
+% \begin{syntax}
+% \cs{@@_decimate_auxi:Nnnnn} \meta{f_1} \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4}
+% \end{syntax}
+% Shifting happens in two steps: compute the \meta{rounding} digit,
+% and repack digits into two blocks of $8$. The sixteen functions
+% are very similar, and defined through \cs{@@_tmp:w}.
+% The arguments are as follows: |#1| indicates which function is
+% being defined; after one step of expansion, |#2| yields the
+% \enquote{extra digits} which are then converted by
+% \cs{@@_round_digit:Nw} to the \meta{rounding} digit (note the |+|
+% separating blocks of digits to avoid overflowing \TeX{}'s integers).
+% This triggers the \texttt{f}-expansion of
+% \cs{@@_decimate_pack:nnnnnnnnnnw},\footnote{No, the argument
+% spec is not a mistake: the function calls an auxiliary to
+% do half of the job.} responsible for building two blocks of
+% $8$ digits, and removing the rest. For this to work, |#3|
+% alternates between braced and unbraced blocks of $4$ digits,
+% in such a way that the $5$ first and $5$ next token groups
+% yield the correct blocks of $8$ digits.
+% \begin{macrocode}
+\cs_new:Npn \@@_tmp:w #1 #2 #3
+ {
+ \cs_new:cpn { @@_decimate_ #1 :Nnnnn } ##1 ##2##3##4##5
+ {
+ \exp_after:wN ##1
+ \int_value:w
+ \exp_after:wN \@@_round_digit:Nw #2 ;
+ \@@_decimate_pack:nnnnnnnnnnw #3 ;
+ }
+ }
+\@@_tmp:w {i} {\use_none:nnn #50}{ 0{#2}#3{#4}#5 }
+\@@_tmp:w {ii} {\use_none:nn #5 }{ 00{#2}#3{#4}#5 }
+\@@_tmp:w {iii} {\use_none:n #5 }{ 000{#2}#3{#4}#5 }
+\@@_tmp:w {iv} { #5 }{ {0000}#2{#3}#4 #5 }
+\@@_tmp:w {v} {\use_none:nnn #4#5 }{ 0{0000}#2{#3}#4 #5 }
+\@@_tmp:w {vi} {\use_none:nn #4#5 }{ 00{0000}#2{#3}#4 #5 }
+\@@_tmp:w {vii} {\use_none:n #4#5 }{ 000{0000}#2{#3}#4 #5 }
+\@@_tmp:w {viii}{ #4#5 }{ {0000}0000{#2}#3 #4 #5 }
+\@@_tmp:w {ix} {\use_none:nnn #3#4+#5}{ 0{0000}0000{#2}#3 #4 #5 }
+\@@_tmp:w {x} {\use_none:nn #3#4+#5}{ 00{0000}0000{#2}#3 #4 #5 }
+\@@_tmp:w {xi} {\use_none:n #3#4+#5}{ 000{0000}0000{#2}#3 #4 #5 }
+\@@_tmp:w {xii} { #3#4+#5}{ {0000}0000{0000}#2 #3 #4 #5 }
+\@@_tmp:w {xiii}{\use_none:nnn#2#3+#4#5}{ 0{0000}0000{0000}#2 #3 #4 #5 }
+\@@_tmp:w {xiv} {\use_none:nn #2#3+#4#5}{ 00{0000}0000{0000}#2 #3 #4 #5 }
+\@@_tmp:w {xv} {\use_none:n #2#3+#4#5}{ 000{0000}0000{0000}#2 #3 #4 #5 }
+\@@_tmp:w {xvi} { #2#3+#4#5}{{0000}0000{0000}0000 #2 #3 #4 #5}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_decimate_pack:nnnnnnnnnnw}
+% The computation of the \meta{rounding} digit leaves an unfinished
+% \cs{int_value:w}, which expands the following functions. This
+% allows us to repack nicely the digits we keep. Those digits come
+% as an alternation of unbraced and braced blocks of $4$ digits,
+% such that the first $5$ groups of token consist in $4$ single digits,
+% and one brace group (in some order), and the next $5$ have the same
+% structure. This is followed by some digits and a semicolon.
+% \begin{macrocode}
+\cs_new:Npn \@@_decimate_pack:nnnnnnnnnnw #1#2#3#4#5
+ { \@@_decimate_pack:nnnnnnw { #1#2#3#4#5 } }
+\cs_new:Npn \@@_decimate_pack:nnnnnnw #1 #2#3#4#5#6
+ { {#1} {#2#3#4#5#6} }
+% \end{macrocode}
+% \end{macro}
+% ^^A end[todo]
+%
+% \subsection{Functions for use within primitive conditional branches}
+%
+% The functions described in this section are not pretty and can easily
+% be misused. When correctly used, each of them removes one \cs{fi:} as
+% part of its parameter text, and puts one back as part of its
+% replacement text.
+%
+% Many computation functions in \pkg{l3fp} must perform tests on the
+% type of floating points that they receive. This is often done in an
+% \cs{if_case:w} statement or another conditional statement, and only a
+% few cases lead to actual computations: most of the special cases are
+% treated using a few standard functions which we define now. A typical
+% use context for those functions would be
+% \begin{syntax}
+% \cs{if_case:w} \meta{integer} \cs{exp_stop_f:}
+% | |\cs{@@_case_return_o:Nw} \meta{fp var}
+% \cs{or:} \cs{@@_case_use:nw} \Arg{some computation}
+% \cs{or:} \cs{@@_case_return_same_o:w}
+% \cs{or:} \cs{@@_case_return:nw} \Arg{something}
+% \cs{fi:}
+% \meta{junk}
+% \meta{floating point}
+% \end{syntax}
+% In this example, the case $0$ returns the floating point
+% \meta{fp~var}, expanding once after that floating point. Case $1$
+% does \meta{some computation} using the \meta{floating point}
+% (presumably compute the operation requested by the user in that
+% non-trivial case). Case $2$ returns the \meta{floating point}
+% without modifying it, removing the \meta{junk} and expanding once
+% after. Case $3$ closes the conditional, removes the \meta{junk}
+% and the \meta{floating point}, and expands \meta{something} next. In
+% other cases, the \enquote{\meta{junk}} is expanded, performing some
+% other operation on the \meta{floating point}. We provide similar
+% functions with two trailing \meta{floating points}.
+%
+% \begin{macro}[EXP]{\@@_case_use:nw}
+% This function ends a \TeX{} conditional, removes junk until the next
+% floating point, and places its first argument before that floating
+% point, to perform some operation on the floating point.
+% \begin{macrocode}
+\cs_new:Npn \@@_case_use:nw #1#2 \fi: #3 \s_@@ { \fi: #1 \s_@@ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_case_return:nw}
+% This function ends a \TeX{} conditional, removes junk and a floating
+% point, and places its first argument in the input stream. A quirk
+% is that we don't define this function requiring a floating point to
+% follow, simply anything ending in a semicolon. This, in turn, means
+% that the \meta{junk} may not contain semicolons.
+% \begin{macrocode}
+\cs_new:Npn \@@_case_return:nw #1#2 \fi: #3 ; { \fi: #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_case_return_o:Nw}
+% This function ends a \TeX{} conditional, removes junk and a floating
+% point, and returns its first argument (an \meta{fp~var}) then expands
+% once after it.
+% \begin{macrocode}
+\cs_new:Npn \@@_case_return_o:Nw #1#2 \fi: #3 \s_@@ #4 ;
+ { \fi: \exp_after:wN #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_case_return_same_o:w}
+% This function ends a \TeX{} conditional, removes junk, and returns
+% the following floating point, expanding once after it.
+% \begin{macrocode}
+\cs_new:Npn \@@_case_return_same_o:w #1 \fi: #2 \s_@@
+ { \fi: \@@_exp_after_o:w \s_@@ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_case_return_o:Nww}
+% Same as \cs{@@_case_return_o:Nw} but with two trailing floating
+% points.
+% \begin{macrocode}
+\cs_new:Npn \@@_case_return_o:Nww #1#2 \fi: #3 \s_@@ #4 ; #5 ;
+ { \fi: \exp_after:wN #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_case_return_i_o:ww, \@@_case_return_ii_o:ww}
+% Similar to \cs{@@_case_return_same_o:w}, but this returns the first
+% or second of two trailing floating point numbers, expanding once
+% after the result.
+% \begin{macrocode}
+\cs_new:Npn \@@_case_return_i_o:ww #1 \fi: #2 \s_@@ #3 ; \s_@@ #4 ;
+ { \fi: \@@_exp_after_o:w \s_@@ #3 ; }
+\cs_new:Npn \@@_case_return_ii_o:ww #1 \fi: #2 \s_@@ #3 ;
+ { \fi: \@@_exp_after_o:w }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Integer floating points}
+%
+% \begin{macro}[EXP, pTF]{\@@_int:w}
+% Tests if the floating point argument is an integer. For normal
+% floating point numbers, this holds if the rounding digit resulting
+% from \cs{@@_decimate:nNnnnn} is~$0$.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_int:w \s_@@ \@@_chk:w #1 #2 #3 #4;
+ { TF , T , F , p }
+ {
+ \if_case:w #1 \exp_stop_f:
+ \prg_return_true:
+ \or:
+ \if_charcode:w 0
+ \@@_decimate:nNnnnn { \c_@@_prec_int - #3 }
+ \@@_use_i_until_s:nw #4
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ \else: \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Small integer floating points}
+%
+% \begin{macro}[EXP]{\@@_small_int:wTF}
+% \begin{macro}[EXP]
+% {
+% \@@_small_int_true:wTF,
+% \@@_small_int_normal:NnwTF,
+% \@@_small_int_test:NnnwNTF
+% }
+% Tests if the floating point argument is an integer or $\pm\infty$.
+% If so, it is clipped to an integer in the range $[-10^{8},10^{8}]$
+% and fed as a braced argument to the \meta{true code}.
+% Otherwise, the \meta{false code} is performed.
+%
+% First filter special cases: zeros and infinities are integers,
+% \texttt{nan} is not. For normal numbers, decimate. If the rounding
+% digit is not $0$ run the \meta{false code}. If it is, then the
+% integer is |#2| |#3|; use |#3| if |#2| vanishes and otherwise
+% $10^{8}$.
+% \begin{macrocode}
+\cs_new:Npn \@@_small_int:wTF \s_@@ \@@_chk:w #1#2
+ {
+ \if_case:w #1 \exp_stop_f:
+ \@@_case_return:nw { \@@_small_int_true:wTF 0 ; }
+ \or: \exp_after:wN \@@_small_int_normal:NnwTF
+ \or:
+ \@@_case_return:nw
+ {
+ \exp_after:wN \@@_small_int_true:wTF \int_value:w
+ \if_meaning:w 2 #2 - \fi: 1 0000 0000 ;
+ }
+ \else: \@@_case_return:nw \use_ii:nn
+ \fi:
+ #2
+ }
+\cs_new:Npn \@@_small_int_true:wTF #1; #2#3 { #2 {#1} }
+\cs_new:Npn \@@_small_int_normal:NnwTF #1#2#3;
+ {
+ \@@_decimate:nNnnnn { \c_@@_prec_int - #2 }
+ \@@_small_int_test:NnnwNw
+ #3 #1
+ }
+\cs_new:Npn \@@_small_int_test:NnnwNw #1#2#3#4; #5
+ {
+ \if_meaning:w 0 #1
+ \exp_after:wN \@@_small_int_true:wTF
+ \int_value:w \if_meaning:w 2 #5 - \fi:
+ \if_int_compare:w #2 > \c_zero_int
+ 1 0000 0000
+ \else:
+ #3
+ \fi:
+ \exp_after:wN ;
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Fast string comparison}
+%
+% \begin{macro}{\@@_str_if_eq:nn}
+% A private version of the low-level string comparison function.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_str_if_eq:nn \tex_strcmp:D
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Name of a function from its \pkg{l3fp-parse} name}
+%
+% \begin{macro}[EXP]{\@@_func_to_name:N, \@@_func_to_name_aux:w}
+% The goal is to convert for instance \cs{@@_sin_o:w} to |sin|.
+% This is used in error messages hence does not need to be fast.
+% \begin{macrocode}
+\cs_new:Npn \@@_func_to_name:N #1
+ {
+ \exp_last_unbraced:Nf
+ \@@_func_to_name_aux:w { \cs_to_str:N #1 } X
+ }
+\cs_set_protected:Npn \@@_tmp:w #1 #2
+ { \cs_new:Npn \@@_func_to_name_aux:w ##1 #1 ##2 #2 ##3 X {##2} }
+\exp_args:Nff \@@_tmp:w { \tl_to_str:n { @@_ } }
+ { \tl_to_str:n { _o: } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% Using a floating point directly is an error.
+% \begin{macrocode}
+\msg_new:nnnn { fp } { misused }
+ { A~floating~point~with~value~'#1'~was~misused. }
+ {
+ To~obtain~the~value~of~a~floating~point~variable,~use~
+ '\token_to_str:N \fp_to_decimal:N',~
+ '\token_to_str:N \fp_to_tl:N',~or~other~
+ conversion~functions.
+ }
+\prop_gput:Nnn \g_msg_module_name_prop { fp } { LaTeX }
+\prop_gput:Nnn \g_msg_module_type_prop { fp } { }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintChanges
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-basics.dtx b/macros/latex-dev/required/l3kernel/l3fp-basics.dtx
new file mode 100644
index 0000000000..d3dcb68dde
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-basics.dtx
@@ -0,0 +1,2181 @@
+% \iffalse meta-comment
+%
+%% File: l3fp-basics.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-basics} module\\
+% Floating point arithmetic^^A
+% }
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp-basics} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% The \pkg{l3fp-basics} module implements addition, subtraction,
+% multiplication, and division of two floating points, and the absolute
+% value and sign-changing operations on one floating point.
+% All operations implemented in this module yield the outcome of
+% rounding the infinitely precise result of the operation to the
+% nearest floating point.
+%
+% Some algorithms used below end up being quite similar to some
+% described in \enquote{What Every Computer Scientist Should Know About
+% Floating Point Arithmetic}, by David Goldberg, which can be found at
+% \texttt{http://cr.yp.to/2005-590/goldberg.pdf}.
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_word_abs:N ,
+% \@@_parse_word_logb:N ,
+% \@@_parse_word_sign:N ,
+% \@@_parse_word_sqrt:N ,
+% }
+% Unary functions.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_word_abs:N
+ { \@@_parse_unary_function:NNN \@@_set_sign_o:w 0 }
+\cs_new:Npn \@@_parse_word_logb:N
+ { \@@_parse_unary_function:NNN \@@_logb_o:w ? }
+\cs_new:Npn \@@_parse_word_sign:N
+ { \@@_parse_unary_function:NNN \@@_sign_o:w ? }
+\cs_new:Npn \@@_parse_word_sqrt:N
+ { \@@_parse_unary_function:NNN \@@_sqrt_o:w ? }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Addition and subtraction}
+%
+% We define here two functions, \cs{@@_-_o:ww} and \cs{@@_+_o:ww}, which
+% perform the subtraction and addition of their two floating point
+% operands, and expand the tokens following the result once.
+%
+% A more obscure function, \cs{@@_add_big_i_o:wNww}, is used in
+% \pkg{l3fp-expo}.
+%
+% The logic goes as follows:
+% \begin{itemize}
+% \item \cs{@@_-_o:ww} calls \cs{@@_+_o:ww} to do the work, with the
+% sign of the second operand flipped;
+% \item \cs{@@_+_o:ww} dispatches depending on the type of floating
+% point, calling specialized auxiliaries;
+% \item in all cases except summing two normal floating point numbers,
+% we return one or the other operands depending on the signs, or
+% detect an invalid operation in the case of $\infty - \infty$;
+% \item for normal floating point numbers, compare the signs;
+% \item to add two floating point numbers of the same sign or of
+% opposite signs, shift the significand of the smaller one to match the
+% bigger one, perform the addition or subtraction of significands,
+% check for a carry, round, and pack using the
+% \cs[no-index]{@@_basics_pack_\ldots{}} functions.
+% \end{itemize}
+% The trickiest part is to round correctly when adding or subtracting
+% normal floating point numbers.
+%
+% \subsubsection{Sign, exponent, and special numbers}
+%
+% \begin{macro}[EXP]{\@@_-_o:ww}
+% The \cs{@@_+_o:ww} auxiliary has a hook: it takes one argument
+% between the first \cs{s_@@} and \cs{@@_chk:w}, which is applied to
+% the sign of the second operand. Positioning the hook there means
+% that \cs{@@_+_o:ww} can still perform the sanity check that it was
+% followed by \cs{s_@@}.
+% \begin{macrocode}
+\cs_new:cpe { @@_-_o:ww } \s_@@
+ {
+ \exp_not:c { @@_+_o:ww }
+ \exp_not:n { \s_@@ \@@_neg_sign:N }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_+_o:ww}
+% This function is either called directly with an empty |#1| to
+% compute an addition, or it is called by \cs{@@_-_o:ww} with
+% \cs{@@_neg_sign:N} as |#1| to compute a subtraction, in which case
+% the second operand's sign should be changed. If the
+% \meta{types} |#2| and |#4| are the same, dispatch to case |#2| ($0$,
+% $1$, $2$, or $3$), where we call specialized functions: thanks to
+% \cs{int_value:w}, those receive the tweaked \meta{sign_2}
+% (expansion of |#1#5|) as an argument. If the \meta{types} are
+% distinct, the result is simply the floating point number with the
+% highest \meta{type}. Since case $3$ (used for two \texttt{nan})
+% also picks the first operand, we can also use it when \meta{type_1}
+% is greater than \meta{type_2}. Also note that we don't need to
+% worry about \meta{sign_2} in that case since the second operand is
+% discarded.
+% \begin{macrocode}
+\cs_new:cpn { @@_+_o:ww }
+ \s_@@ #1 \@@_chk:w #2 #3 ; \s_@@ \@@_chk:w #4 #5
+ {
+ \if_case:w
+ \if_meaning:w #2 #4
+ #2
+ \else:
+ \if_int_compare:w #2 > #4 \exp_stop_f:
+ 3
+ \else:
+ 4
+ \fi:
+ \fi:
+ \exp_stop_f:
+ \exp_after:wN \@@_add_zeros_o:Nww \int_value:w
+ \or: \exp_after:wN \@@_add_normal_o:Nww \int_value:w
+ \or: \exp_after:wN \@@_add_inf_o:Nww \int_value:w
+ \or: \@@_case_return_i_o:ww
+ \else: \exp_after:wN \@@_add_return_ii_o:Nww \int_value:w
+ \fi:
+ #1 #5
+ \s_@@ \@@_chk:w #2 #3 ;
+ \s_@@ \@@_chk:w #4 #5
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_add_return_ii_o:Nww}
+% Ignore the first operand, and return the second, but using the sign
+% |#1| rather than |#4|. As usual, expand after the floating point.
+% \begin{macrocode}
+\cs_new:Npn \@@_add_return_ii_o:Nww #1 #2 ; \s_@@ \@@_chk:w #3 #4
+ { \@@_exp_after_o:w \s_@@ \@@_chk:w #3 #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_add_zeros_o:Nww}
+% Adding two zeros yields \cs{c_zero_fp}, except if both zeros were
+% $-0$.
+% \begin{macrocode}
+\cs_new:Npn \@@_add_zeros_o:Nww #1 \s_@@ \@@_chk:w 0 #2
+ {
+ \if_int_compare:w #2 #1 = 20 \exp_stop_f:
+ \exp_after:wN \@@_add_return_ii_o:Nww
+ \else:
+ \@@_case_return_i_o:ww
+ \fi:
+ #1
+ \s_@@ \@@_chk:w 0 #2
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_add_inf_o:Nww}
+% If both infinities have the same sign, just return that infinity,
+% otherwise, it is an invalid operation. We find out if that invalid
+% operation is an addition or a subtraction by testing whether the
+% tweaked \meta{sign_2} (|#1|) and the \meta{sign_2} (|#4|) are
+% identical.
+% \begin{macrocode}
+\cs_new:Npn \@@_add_inf_o:Nww
+ #1 \s_@@ \@@_chk:w 2 #2 #3; \s_@@ \@@_chk:w 2 #4
+ {
+ \if_meaning:w #1 #2
+ \@@_case_return_i_o:ww
+ \else:
+ \@@_case_use:nw
+ {
+ \exp_last_unbraced:Nf \@@_invalid_operation_o:Nww
+ { \token_if_eq_meaning:NNTF #1 #4 + - }
+ }
+ \fi:
+ \s_@@ \@@_chk:w 2 #2 #3;
+ \s_@@ \@@_chk:w 2 #4
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_add_normal_o:Nww}
+% \begin{quote}
+% \cs{@@_add_normal_o:Nww} \meta{sign_2}
+% \cs{s_@@} \cs{@@_chk:w} |1| \meta{sign_1}
+% \meta{exp_1} \meta{body_1} |;|
+% \cs{s_@@} \cs{@@_chk:w} |1| \meta{initial sign_2}
+% \meta{exp_2} \meta{body_2} |;|
+% \end{quote}
+% We now have two normal numbers to add, and we have to check signs
+% and exponents more carefully before performing the addition.
+% \begin{macrocode}
+\cs_new:Npn \@@_add_normal_o:Nww #1 \s_@@ \@@_chk:w 1 #2
+ {
+ \if_meaning:w #1#2
+ \exp_after:wN \@@_add_npos_o:NnwNnw
+ \else:
+ \exp_after:wN \@@_sub_npos_o:NnwNnw
+ \fi:
+ #2
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Absolute addition}
+%
+% In this subsection, we perform the addition of two positive normal
+% numbers.
+%
+% \begin{macro}[EXP]{\@@_add_npos_o:NnwNnw}
+% \begin{quote}
+% \cs{@@_add_npos_o:NnwNnw} \meta{sign_1} \meta{exp_1} \meta{body_1}
+% |;| \cs{s_@@} \cs{@@_chk:w} |1| \meta{initial sign_2} \meta{exp_2}
+% \meta{body_2} |;|
+% \end{quote}
+% Since we are doing an addition, the final sign is \meta{sign_1}.
+% Start an \cs{@@_int_eval:w}, responsible for computing the exponent:
+% the result, and the \meta{final sign} are then given to
+% \cs{@@_sanitize:Nw} which checks for overflow. The exponent is
+% computed as the largest exponent |#2| or |#5|, incremented if there
+% is a carry. To add the significands, we decimate the smaller number by
+% the difference between the exponents. This is done by
+% \cs{@@_add_big_i:wNww} or \cs{@@_add_big_ii:wNww}. We need to bring
+% the final sign with us in the midst of the calculation to round
+% properly at the end.
+% \begin{macrocode}
+\cs_new:Npn \@@_add_npos_o:NnwNnw #1#2#3 ; \s_@@ \@@_chk:w 1 #4 #5
+ {
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN #1
+ \int_value:w \@@_int_eval:w
+ \if_int_compare:w #2 > #5 \exp_stop_f:
+ #2
+ \exp_after:wN \@@_add_big_i_o:wNww \int_value:w -
+ \else:
+ #5
+ \exp_after:wN \@@_add_big_ii_o:wNww \int_value:w
+ \fi:
+ \@@_int_eval:w #5 - #2 ; #1 #3;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_add_big_i_o:wNww}
+% \begin{macro}[rEXP]{\@@_add_big_ii_o:wNww}
+% \begin{quote}
+% \cs{@@_add_big_i_o:wNww} \meta{shift} |;| \meta{final sign}
+% \meta{body_1} |;| \meta{body_2} |;|
+% \end{quote}
+% Used in \pkg{l3fp-expo}.
+% Shift the significand of the small number, then add with
+% \cs{@@_add_significand_o:NnnwnnnnN}.
+% \begin{macrocode}
+\cs_new:Npn \@@_add_big_i_o:wNww #1; #2 #3; #4;
+ {
+ \@@_decimate:nNnnnn {#1}
+ \@@_add_significand_o:NnnwnnnnN
+ #4
+ #3
+ #2
+ }
+\cs_new:Npn \@@_add_big_ii_o:wNww #1; #2 #3; #4;
+ {
+ \@@_decimate:nNnnnn {#1}
+ \@@_add_significand_o:NnnwnnnnN
+ #3
+ #4
+ #2
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_add_significand_o:NnnwnnnnN}
+% \begin{macro}[rEXP]
+% {\@@_add_significand_pack:NNNNNNN, \@@_add_significand_test_o:N}
+% \begin{quote}\raggedright
+% \cs{@@_add_significand_o:NnnwnnnnN}
+% \meta{rounding digit}
+% \Arg{Y'_1} \Arg{Y'_2} \meta{extra-digits} |;|
+% \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4}
+% \meta{final sign}
+% \end{quote}
+% To round properly, we must know at which digit the rounding
+% should occur. This requires to know whether the addition
+% produces an overall carry or not. Thus, we do the computation
+% now and check for a carry, then go back and do the rounding.
+% The rounding may cause a carry in very rare cases such as
+% $0.99\cdots 95 \to 1.00\cdots 0$, but this situation always
+% give an exact power of $10$, for which it is easy to correct
+% the result at the end.
+% \begin{macrocode}
+\cs_new:Npn \@@_add_significand_o:NnnwnnnnN #1 #2#3 #4; #5#6#7#8
+ {
+ \exp_after:wN \@@_add_significand_test_o:N
+ \int_value:w \@@_int_eval:w 1#5#6 + #2
+ \exp_after:wN \@@_add_significand_pack:NNNNNNN
+ \int_value:w \@@_int_eval:w 1#7#8 + #3 ; #1
+ }
+\cs_new:Npn \@@_add_significand_pack:NNNNNNN #1 #2#3#4#5#6#7
+ {
+ \if_meaning:w 2 #1
+ + 1
+ \fi:
+ ; #2 #3 #4 #5 #6 #7 ;
+ }
+\cs_new:Npn \@@_add_significand_test_o:N #1
+ {
+ \if_meaning:w 2 #1
+ \exp_after:wN \@@_add_significand_carry_o:wwwNN
+ \else:
+ \exp_after:wN \@@_add_significand_no_carry_o:wwwNN
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_add_significand_no_carry_o:wwwNN}
+% \begin{quote}
+% \cs{@@_add_significand_no_carry_o:wwwNN}
+% \meta{8d} |;| \meta{6d} |;| \meta{2d} |;|
+% \meta{rounding digit} \meta{sign}
+% \end{quote}
+% If there's no carry, grab all the digits again and round. The
+% packing function \cs{@@_basics_pack_high:NNNNNw} takes care of the
+% case where rounding brings a carry.
+% \begin{macrocode}
+\cs_new:Npn \@@_add_significand_no_carry_o:wwwNN
+ #1; #2; #3#4 ; #5#6
+ {
+ \exp_after:wN \@@_basics_pack_high:NNNNNw
+ \int_value:w \@@_int_eval:w 1 #1
+ \exp_after:wN \@@_basics_pack_low:NNNNNw
+ \int_value:w \@@_int_eval:w 1 #2 #3#4
+ + \@@_round:NNN #6 #4 #5
+ \exp_after:wN ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_add_significand_carry_o:wwwNN}
+% \begin{quote}
+% \cs{@@_add_significand_carry_o:wwwNN}
+% \meta{8d} |;| \meta{6d} |;| \meta{2d} |;|
+% \meta{rounding digit} \meta{sign}
+% \end{quote}
+% The case where there is a carry is very similar. Rounding can even
+% raise the first digit from $1$ to $2$, but we don't care.
+% \begin{macrocode}
+\cs_new:Npn \@@_add_significand_carry_o:wwwNN
+ #1; #2; #3#4; #5#6
+ {
+ + 1
+ \exp_after:wN \@@_basics_pack_weird_high:NNNNNNNNw
+ \int_value:w \@@_int_eval:w 1 1 #1
+ \exp_after:wN \@@_basics_pack_weird_low:NNNNw
+ \int_value:w \@@_int_eval:w 1 #2#3 +
+ \exp_after:wN \@@_round:NNN
+ \exp_after:wN #6
+ \exp_after:wN #3
+ \int_value:w \@@_round_digit:Nw #4 #5 ;
+ \exp_after:wN ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Absolute subtraction}
+%
+% \begin{macro}[EXP]{\@@_sub_npos_o:NnwNnw}
+% \begin{macro}[EXP]{\@@_sub_eq_o:Nnwnw, \@@_sub_npos_ii_o:Nnwnw}
+% \begin{quote}
+% \cs{@@_sub_npos_o:NnwNnw}
+% \meta{sign_1} \meta{exp_1} \meta{body_1} |;|
+% \cs{s_@@} \cs{@@_chk:w} |1|
+% \meta{initial sign_2} \meta{exp_2} \meta{body_2} |;|
+% \end{quote}
+% Rounding properly in some modes requires to know what the sign of
+% the result will be. Thus, we start by comparing the exponents and
+% significands. If the numbers coincide, return zero. If the second
+% number is larger, swap the numbers and call
+% \cs{@@_sub_npos_i_o:Nnwnw} with the opposite of \meta{sign_1}.
+% \begin{macrocode}
+\cs_new:Npn \@@_sub_npos_o:NnwNnw #1#2#3; \s_@@ \@@_chk:w 1 #4#5#6;
+ {
+ \if_case:w \@@_compare_npos:nwnw {#2} #3; {#5} #6; \exp_stop_f:
+ \exp_after:wN \@@_sub_eq_o:Nnwnw
+ \or:
+ \exp_after:wN \@@_sub_npos_i_o:Nnwnw
+ \else:
+ \exp_after:wN \@@_sub_npos_ii_o:Nnwnw
+ \fi:
+ #1 {#2} #3; {#5} #6;
+ }
+\cs_new:Npn \@@_sub_eq_o:Nnwnw #1#2; #3; { \exp_after:wN \c_zero_fp }
+\cs_new:Npn \@@_sub_npos_ii_o:Nnwnw #1 #2; #3;
+ {
+ \exp_after:wN \@@_sub_npos_i_o:Nnwnw
+ \int_value:w \@@_neg_sign:N #1
+ #3; #2;
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_sub_npos_i_o:Nnwnw}
+% After the computation is done, \cs{@@_sanitize:Nw} checks for
+% overflow/underflow. It expects the \meta{final sign} and the
+% \meta{exponent} (delimited by |;|). Start an integer expression for
+% the exponent, which starts with the exponent of the largest number,
+% and may be decreased if the two numbers are very close. If the two
+% numbers have the same exponent, call the \texttt{near} auxiliary.
+% Otherwise, decimate $y$, then call the \texttt{far} auxiliary to
+% evaluate the difference between the two significands. Note that we
+% decimate by $1$ less than one could expect.
+% \begin{macrocode}
+\cs_new:Npn \@@_sub_npos_i_o:Nnwnw #1 #2#3; #4#5;
+ {
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN #1
+ \int_value:w \@@_int_eval:w
+ #2
+ \if_int_compare:w #2 = #4 \exp_stop_f:
+ \exp_after:wN \@@_sub_back_near_o:nnnnnnnnN
+ \else:
+ \exp_after:wN \@@_decimate:nNnnnn \exp_after:wN
+ { \int_value:w \@@_int_eval:w #2 - #4 - 1 \exp_after:wN }
+ \exp_after:wN \@@_sub_back_far_o:NnnwnnnnN
+ \fi:
+ #5
+ #3
+ #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_sub_back_near_o:nnnnnnnnN}
+% \begin{macro}[rEXP]
+% {\@@_sub_back_near_pack:NNNNNNw, \@@_sub_back_near_after:wNNNNw}
+% \begin{quote}
+% \cs{@@_sub_back_near_o:nnnnnnnnN}
+% \Arg{Y_1} \Arg{Y_2} \Arg{Y_3} \Arg{Y_4}
+% \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4}
+% \meta{final sign}
+% \end{quote}
+% In this case, the subtraction is exact, so we discard the
+% \meta{final sign} |#9|. The very large shifts of $10^{9}$ and
+% $1.1\cdot10^{9}$ are unnecessary here, but allow the auxiliaries to
+% be reused later. Each integer expression produces a $10$ digit
+% result. If the resulting $16$ digits start with a $0$, then we need
+% to shift the group, padding with trailing zeros.
+% \begin{macrocode}
+\cs_new:Npn \@@_sub_back_near_o:nnnnnnnnN #1#2#3#4 #5#6#7#8 #9
+ {
+ \exp_after:wN \@@_sub_back_near_after:wNNNNw
+ \int_value:w \@@_int_eval:w 10#5#6 - #1#2 - 11
+ \exp_after:wN \@@_sub_back_near_pack:NNNNNNw
+ \int_value:w \@@_int_eval:w 11#7#8 - #3#4 \exp_after:wN ;
+ }
+\cs_new:Npn \@@_sub_back_near_pack:NNNNNNw #1#2#3#4#5#6#7 ;
+ { + #1#2 ; {#3#4#5#6} {#7} ; }
+\cs_new:Npn \@@_sub_back_near_after:wNNNNw 10 #1#2#3#4 #5 ;
+ {
+ \if_meaning:w 0 #1
+ \exp_after:wN \@@_sub_back_shift:wnnnn
+ \fi:
+ ; {#1#2#3#4} {#5}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_sub_back_shift:wnnnn}
+% \begin{macro}[rEXP]
+% {
+% \@@_sub_back_shift_ii:ww,
+% \@@_sub_back_shift_iii:NNNNNNNNw,
+% \@@_sub_back_shift_iv:nnnnw
+% }
+% \begin{quote}
+% \cs{@@_sub_back_shift:wnnnn} |;|
+% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} |;|
+% \end{quote}
+% This function is called with $\meta{Z_1}\leq 999$. Act with
+% \tn{number} to trim leading zeros from \meta{Z_1} \meta{Z_2} (we
+% don't do all four blocks at once, since non-zero blocks would then
+% overflow \TeX{}'s integers). If the first two blocks are zero, the
+% auxiliary receives an empty |#1| and trims |#2#30| from leading
+% zeros, yielding a total shift between $7$ and~$16$ to the exponent.
+% Otherwise we get the shift from |#1| alone, yielding a result
+% between $1$ and~$6$. Once the exponent is taken care of, trim
+% leading zeros from |#1#2#3| (when |#1| is empty, the space before
+% |#2#3| is ignored), get four blocks of $4$~digits and finally clean
+% up. Trailing zeros are added so that digits can be grabbed safely.
+% \begin{macrocode}
+\cs_new:Npn \@@_sub_back_shift:wnnnn ; #1#2
+ {
+ \exp_after:wN \@@_sub_back_shift_ii:ww
+ \int_value:w #1 #2 0 ;
+ }
+\cs_new:Npn \@@_sub_back_shift_ii:ww #1 0 ; #2#3 ;
+ {
+ \if_meaning:w @ #1 @
+ - 7
+ - \exp_after:wN \use_i:nnn
+ \exp_after:wN \@@_sub_back_shift_iii:NNNNNNNNw
+ \int_value:w #2#3 0 ~ 123456789;
+ \else:
+ - \@@_sub_back_shift_iii:NNNNNNNNw #1 123456789;
+ \fi:
+ \exp_after:wN \@@_pack_twice_four:wNNNNNNNN
+ \exp_after:wN \@@_pack_twice_four:wNNNNNNNN
+ \exp_after:wN \@@_sub_back_shift_iv:nnnnw
+ \exp_after:wN ;
+ \int_value:w
+ #1 ~ #2#3 0 ~ 0000 0000 0000 000 ;
+ }
+\cs_new:Npn \@@_sub_back_shift_iii:NNNNNNNNw #1#2#3#4#5#6#7#8#9; {#8}
+\cs_new:Npn \@@_sub_back_shift_iv:nnnnw #1 ; #2 ; { ; #1 ; }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_sub_back_far_o:NnnwnnnnN}
+% \begin{quote}\raggedright
+% \cs{@@_sub_back_far_o:NnnwnnnnN}
+% \meta{rounding} \Arg{Y'_1} \Arg{Y'_2} \meta{extra-digits} |;|
+% \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4}
+% \meta{final sign}
+% \end{quote}
+% If the difference is greater than $10^{\meta{expo_x}}$, call the
+% \texttt{very_far} auxiliary. If the result is less than
+% $10^{\meta{expo_x}}$, call the \texttt{not_far} auxiliary. If it is
+% too close a call to know yet, namely if $1 \meta{Y'_1} \meta{Y'_2} =
+% \meta{X_1} \meta{X_2} \meta{X_3} \meta{X_4} 0$, then call the
+% \texttt{quite_far} auxiliary. We use the odd combination of space
+% and semi-colon delimiters to allow the \texttt{not_far} auxiliary to
+% grab each piece individually, the \texttt{very_far} auxiliary to use
+% \cs{@@_pack_eight:wNNNNNNNN}, and the \texttt{quite_far} to ignore
+% the significands easily (using the |;| delimiter).
+% \begin{macrocode}
+\cs_new:Npn \@@_sub_back_far_o:NnnwnnnnN #1 #2#3 #4; #5#6#7#8
+ {
+ \if_case:w
+ \if_int_compare:w 1 #2 = #5#6 \use_i:nnnn #7 \exp_stop_f:
+ \if_int_compare:w #3 = \use_none:n #7#8 0 \exp_stop_f:
+ 0
+ \else:
+ \if_int_compare:w #3 > \use_none:n #7#8 0 - \fi: 1
+ \fi:
+ \else:
+ \if_int_compare:w 1 #2 > #5#6 \use_i:nnnn #7 - \fi: 1
+ \fi:
+ \exp_stop_f:
+ \exp_after:wN \@@_sub_back_quite_far_o:wwNN
+ \or: \exp_after:wN \@@_sub_back_very_far_o:wwwwNN
+ \else: \exp_after:wN \@@_sub_back_not_far_o:wwwwNN
+ \fi:
+ #2 ~ #3 ; #5 #6 ~ #7 #8 ; #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_sub_back_quite_far_o:wwNN}
+% \begin{macro}[EXP]{\@@_sub_back_quite_far_ii:NN}
+% The easiest case is when $x-y$ is extremely close to a power of
+% $10$, namely the first digit of $x$ is $1$, and all others vanish
+% when subtracting $y$. Then the \meta{rounding} |#3| and the
+% \meta{final sign} |#4| control whether we get $1$ or $0.9999 9999
+% 9999 9999$. In the usual round-to-nearest mode, we get $1$
+% whenever the \meta{rounding} digit is less than or equal to $5$
+% (remember that the \meta{rounding} digit is only equal to $5$ if
+% there was no further non-zero digit).
+% \begin{macrocode}
+\cs_new:Npn \@@_sub_back_quite_far_o:wwNN #1; #2; #3#4
+ {
+ \exp_after:wN \@@_sub_back_quite_far_ii:NN
+ \exp_after:wN #3
+ \exp_after:wN #4
+ }
+\cs_new:Npn \@@_sub_back_quite_far_ii:NN #1#2
+ {
+ \if_case:w \@@_round_neg:NNN #2 0 #1
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ { ; {1000} {0000} {0000} {0000} ; }
+ { - 1 ; {9999} {9999} {9999} {9999} ; }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_sub_back_not_far_o:wwwwNN}
+% In the present case, $x$ and $y$ have different exponents, but
+% $y$~is large enough that $x-y$ has a smaller exponent than~$x$.
+% Decrement the exponent (with |-1|). Then proceed in a way
+% similar to the \texttt{near} auxiliaries seen earlier, but
+% multiplying $x$ by~$10$ (|#30| and |#40| below), and with the added
+% quirk that the \meta{rounding} digit has to be taken into account.
+% Namely, we may have to decrease the result by one unit if
+% \cs{@@_round_neg:NNN} returns~$1$. This function expects the
+% \meta{final sign}~|#6|, the last digit of |1100000000+#40-#2|, and
+% the \meta{rounding} digit. Instead of redoing the computation for
+% the second argument, we note that \cs{@@_round_neg:NNN} only cares
+% about its parity, which is identical to that of the last digit
+% of~|#2|.
+% \begin{macrocode}
+\cs_new:Npn \@@_sub_back_not_far_o:wwwwNN #1 ~ #2; #3 ~ #4; #5#6
+ {
+ - 1
+ \exp_after:wN \@@_sub_back_near_after:wNNNNw
+ \int_value:w \@@_int_eval:w 1#30 - #1 - 11
+ \exp_after:wN \@@_sub_back_near_pack:NNNNNNw
+ \int_value:w \@@_int_eval:w 11 0000 0000 + #40 - #2
+ - \exp_after:wN \@@_round_neg:NNN
+ \exp_after:wN #6
+ \use_none:nnnnnnn #2 #5
+ \exp_after:wN ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_sub_back_very_far_o:wwwwNN}
+% \begin{macro}[EXP]{\@@_sub_back_very_far_ii_o:nnNwwNN}
+% The case where $x-y$ and $x$ have the same exponent is a bit more
+% tricky, mostly because it cannot reuse the same auxiliaries. Shift
+% the $y$~significand by adding a leading~$0$. Then the logic is similar
+% to the \texttt{not_far} functions above. Rounding is a bit more
+% complicated: we have two \meta{rounding} digits |#3| and |#6| (from
+% the decimation, and from the new shift) to take into account, and
+% getting the parity of the main result requires a computation. The
+% first \cs{int_value:w} triggers the second one because the number
+% is unfinished; we can thus not use $0$ in place of $2$ there.
+% \begin{macrocode}
+\cs_new:Npn \@@_sub_back_very_far_o:wwwwNN #1#2#3#4#5#6#7
+ {
+ \@@_pack_eight:wNNNNNNNN
+ \@@_sub_back_very_far_ii_o:nnNwwNN
+ { 0 #1#2#3 #4#5#6#7 }
+ ;
+ }
+\cs_new:Npn \@@_sub_back_very_far_ii_o:nnNwwNN #1#2 ; #3 ; #4 ~ #5; #6#7
+ {
+ \exp_after:wN \@@_basics_pack_high:NNNNNw
+ \int_value:w \@@_int_eval:w 1#4 - #1 - 1
+ \exp_after:wN \@@_basics_pack_low:NNNNNw
+ \int_value:w \@@_int_eval:w 2#5 - #2
+ - \exp_after:wN \@@_round_neg:NNN
+ \exp_after:wN #7
+ \int_value:w
+ \if_int_odd:w \@@_int_eval:w #5 - #2 \@@_int_eval_end:
+ 1 \else: 2 \fi:
+ \int_value:w \@@_round_digit:Nw #3 #6 ;
+ \exp_after:wN ;
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Multiplication}
+%
+% \subsubsection{Signs, and special numbers}
+%
+% \begin{macro}[EXP]{\@@_*_o:ww}
+% We go through an auxiliary, which is common with \cs{@@_/_o:ww}.
+% The first argument is the operation, used for the invalid operation
+% exception. The second is inserted in a formula to dispatch cases
+% slightly differently between multiplication and division. The third
+% is the operation for normal floating points. The fourth is there
+% for extra cases needed in \cs{@@_/_o:ww}.
+% \begin{macrocode}
+\cs_new:cpn { @@_*_o:ww }
+ {
+ \@@_mul_cases_o:NnNnww
+ *
+ { - 2 + }
+ \@@_mul_npos_o:Nww
+ { }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_mul_cases_o:nNnnww}
+% Split into $10$ cases ($12$ for division).
+% If both numbers are normal, go to case $0$
+% (same sign) or case $1$ (opposite signs): in both cases, call
+% \cs{@@_mul_npos_o:Nww} to do the work. If the first operand is
+% \texttt{nan}, go to case $2$, in which the second operand is
+% discarded; if the second operand is \texttt{nan}, go to case $3$, in
+% which the first operand is discarded (note the weird interaction
+% with the final test on signs). Then we separate the case where the
+% first number is normal and the second is zero: this goes to cases
+% $4$ and $5$ for multiplication, $10$ and $11$ for division.
+% Otherwise, we do a computation which
+% dispatches the products $0\times 0 = 0\times 1 = 1\times 0 = 0$ to
+% case $4$ or $5$ depending on the combined sign, the products
+% $0\times\infty$ and $\infty\times0$ to case $6$ or $7$ (invalid
+% operation), and the products $1\times\infty = \infty\times1 =
+% \infty\times\infty = \infty$ to cases $8$ and $9$. Note that the
+% code for these two cases (which return $\pm\infty$) is inserted as
+% argument |#4|, because it differs in the case of divisions.
+% \begin{macrocode}
+\cs_new:Npn \@@_mul_cases_o:NnNnww
+ #1#2#3#4 \s_@@ \@@_chk:w #5#6#7; \s_@@ \@@_chk:w #8#9
+ {
+ \if_case:w \@@_int_eval:w
+ \if_int_compare:w #5 #8 = 11 ~
+ 1
+ \else:
+ \if_meaning:w 3 #8
+ 3
+ \else:
+ \if_meaning:w 3 #5
+ 2
+ \else:
+ \if_int_compare:w #5 #8 = 10 ~
+ 9 #2 - 2
+ \else:
+ (#5 #2 #8) / 2 * 2 + 7
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \if_meaning:w #6 #9 - 1 \fi:
+ \@@_int_eval_end:
+ \@@_case_use:nw { #3 0 }
+ \or: \@@_case_use:nw { #3 2 }
+ \or: \@@_case_return_i_o:ww
+ \or: \@@_case_return_ii_o:ww
+ \or: \@@_case_return_o:Nww \c_zero_fp
+ \or: \@@_case_return_o:Nww \c_minus_zero_fp
+ \or: \@@_case_use:nw { \@@_invalid_operation_o:Nww #1 }
+ \or: \@@_case_use:nw { \@@_invalid_operation_o:Nww #1 }
+ \or: \@@_case_return_o:Nww \c_inf_fp
+ \or: \@@_case_return_o:Nww \c_minus_inf_fp
+ #4
+ \fi:
+ \s_@@ \@@_chk:w #5 #6 #7;
+ \s_@@ \@@_chk:w #8 #9
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Absolute multiplication}
+%
+% In this subsection, we perform the multiplication
+% of two positive normal numbers.
+%
+% \begin{macro}[EXP]{\@@_mul_npos_o:Nww}
+% \begin{quote}
+% \cs{@@_mul_npos_o:Nww} \meta{final sign}
+% \cs{s_@@} \cs{@@_chk:w} |1| \meta{sign_1} \Arg{exp_1} \meta{body_1} |;|
+% \cs{s_@@} \cs{@@_chk:w} |1| \meta{sign_2} \Arg{exp_2} \meta{body_2} |;|
+% \end{quote}
+% After the computation, \cs{@@_sanitize:Nw} checks for overflow or
+% underflow. As we did for addition, \cs{@@_int_eval:w} computes the
+% exponent, catching any shift coming from the computation in the
+% significand. The \meta{final sign} is needed to do the rounding
+% properly in the significand computation. We setup the post-expansion
+% here, triggered by \cs{@@_mul_significand_o:nnnnNnnnn}.
+%
+% This is also used in \pkg{l3fp-convert}.
+% \begin{macrocode}
+\cs_new:Npn \@@_mul_npos_o:Nww
+ #1 \s_@@ \@@_chk:w #2 #3 #4 #5 ; \s_@@ \@@_chk:w #6 #7 #8 #9 ;
+ {
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN #1
+ \int_value:w \@@_int_eval:w
+ #4 + #8
+ \@@_mul_significand_o:nnnnNnnnn #5 #1 #9
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_mul_significand_o:nnnnNnnnn}
+% \begin{macro}[EXP]
+% {\@@_mul_significand_drop:NNNNNw, \@@_mul_significand_keep:NNNNNw}
+% \begin{quote}
+% \cs{@@_mul_significand_o:nnnnNnnnn}
+% \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} \meta{sign}
+% \Arg{Y_1} \Arg{Y_2} \Arg{Y_3} \Arg{Y_4}
+% \end{quote}
+% Note the three semicolons at the end of the definition. One is for
+% the last \cs{@@_mul_significand_drop:NNNNNw}; one is for
+% \cs{@@_round_digit:Nw} later on; and one, preceded by
+% \cs{exp_after:wN}, which is correctly expanded (within an
+% \cs{@@_int_eval:w}), is used by \cs{@@_basics_pack_low:NNNNNw}.
+%
+% The product of two $16$ digit integers has $31$ or $32$ digits,
+% but it is impossible to know which one before computing. The place
+% where we round depends on that number of digits, and may depend
+% on all digits until the last in some rare cases. The approach is
+% thus to compute the $5$ first blocks of $4$ digits (the first one
+% is between $100$ and $9999$ inclusive), and a compact version of
+% the remaining $3$ blocks. Afterwards, the number of digits is
+% known, and we can do the rounding within yet another set of
+% \cs{@@_int_eval:w}.
+% \begin{macrocode}
+\cs_new:Npn \@@_mul_significand_o:nnnnNnnnn #1#2#3#4 #5 #6#7#8#9
+ {
+ \exp_after:wN \@@_mul_significand_test_f:NNN
+ \exp_after:wN #5
+ \int_value:w \@@_int_eval:w 99990000 + #1*#6 +
+ \exp_after:wN \@@_mul_significand_keep:NNNNNw
+ \int_value:w \@@_int_eval:w 99990000 + #1*#7 + #2*#6 +
+ \exp_after:wN \@@_mul_significand_keep:NNNNNw
+ \int_value:w \@@_int_eval:w 99990000 + #1*#8 + #2*#7 + #3*#6 +
+ \exp_after:wN \@@_mul_significand_drop:NNNNNw
+ \int_value:w \@@_int_eval:w 99990000 + #1*#9 + #2*#8 +
+ #3*#7 + #4*#6 +
+ \exp_after:wN \@@_mul_significand_drop:NNNNNw
+ \int_value:w \@@_int_eval:w 99990000 + #2*#9 + #3*#8 +
+ #4*#7 +
+ \exp_after:wN \@@_mul_significand_drop:NNNNNw
+ \int_value:w \@@_int_eval:w 99990000 + #3*#9 + #4*#8 +
+ \exp_after:wN \@@_mul_significand_drop:NNNNNw
+ \int_value:w \@@_int_eval:w 100000000 + #4*#9 ;
+ ; \exp_after:wN ;
+ }
+\cs_new:Npn \@@_mul_significand_drop:NNNNNw #1#2#3#4#5 #6;
+ { #1#2#3#4#5 ; + #6 }
+\cs_new:Npn \@@_mul_significand_keep:NNNNNw #1#2#3#4#5 #6;
+ { #1#2#3#4#5 ; #6 ; }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_mul_significand_test_f:NNN}
+% \begin{quote}
+% \cs{@@_mul_significand_test_f:NNN} \meta{sign} |1|
+% \meta{digits 1--8} |;| \meta{digits 9--12} |;| \meta{digits 13--16} |;|
+% |+| \meta{digits 17--20} |+| \meta{digits 21--24}
+% |+| \meta{digits 25--28} |+| \meta{digits 29--32} |;|
+% \cs{exp_after:wN} |;|
+% \end{quote}
+% If the \meta{digit 1} is non-zero, then for rounding we only care
+% about the digits $16$ and $17$, and whether further digits are zero
+% or not (check for exact ties). On the other hand, if \meta{digit 1}
+% is zero, we care about digits $17$ and $18$, and whether further
+% digits are zero.
+% \begin{macrocode}
+\cs_new:Npn \@@_mul_significand_test_f:NNN #1 #2 #3
+ {
+ \if_meaning:w 0 #3
+ \exp_after:wN \@@_mul_significand_small_f:NNwwwN
+ \else:
+ \exp_after:wN \@@_mul_significand_large_f:NwwNNNN
+ \fi:
+ #1 #3
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_mul_significand_large_f:NwwNNNN}
+% In this branch, \meta{digit 1} is non-zero. The result is thus
+% \meta{digits 1--16}, plus some rounding which depends on the digits
+% $16$, $17$, and whether all subsequent digits are zero or not.
+% Here, \cs{@@_round_digit:Nw} takes digits $17$ and further (as an
+% integer expression), and replaces it by a \meta{rounding digit},
+% suitable for \cs{@@_round:NNN}.
+% \begin{macrocode}
+\cs_new:Npn \@@_mul_significand_large_f:NwwNNNN #1 #2; #3; #4#5#6#7; +
+ {
+ \exp_after:wN \@@_basics_pack_high:NNNNNw
+ \int_value:w \@@_int_eval:w 1#2
+ \exp_after:wN \@@_basics_pack_low:NNNNNw
+ \int_value:w \@@_int_eval:w 1#3#4#5#6#7
+ + \exp_after:wN \@@_round:NNN
+ \exp_after:wN #1
+ \exp_after:wN #7
+ \int_value:w \@@_round_digit:Nw
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_mul_significand_small_f:NNwwwN}
+% In this branch, \meta{digit 1} is zero. Our result is thus
+% \meta{digits 2--17}, plus some rounding which depends on the digits
+% $17$, $18$, and whether all subsequent digits are zero or not.
+% The $8$ digits |1#3| are followed, after expansion of the
+% \texttt{small_pack} auxiliary, by the next digit, to form a $9$
+% digit number.
+% \begin{macrocode}
+\cs_new:Npn \@@_mul_significand_small_f:NNwwwN #1 #2#3; #4#5; #6; + #7
+ {
+ - 1
+ \exp_after:wN \@@_basics_pack_high:NNNNNw
+ \int_value:w \@@_int_eval:w 1#3#4
+ \exp_after:wN \@@_basics_pack_low:NNNNNw
+ \int_value:w \@@_int_eval:w 1#5#6#7
+ + \exp_after:wN \@@_round:NNN
+ \exp_after:wN #1
+ \exp_after:wN #7
+ \int_value:w \@@_round_digit:Nw
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Division}
+%
+% \subsubsection{Signs, and special numbers}
+%
+% Time is now ripe to tackle the hardest of the four elementary
+% operations: division.
+%
+% \begin{macro}[EXP]{\@@_/_o:ww}
+% Filtering special floating point is very similar to what we did for
+% multiplications, with a few variations. Invalid operation
+% exceptions display |/| rather than |*|. In the formula for
+% dispatch, we replace |- 2 +| by |-|. The case of normal
+% numbers is treated using \cs{@@_div_npos_o:Nww} rather than
+% \cs{@@_mul_npos_o:Nww}. There are two additional cases: if the
+% first operand is normal and the second is a zero, then the division
+% by zero exception is raised: cases $10$ and $11$ of the
+% \cs{if_case:w} construction in \cs{@@_mul_cases_o:NnNnww} are
+% provided as the fourth argument here.
+% \begin{macrocode}
+\cs_new:cpn { @@_/_o:ww }
+ {
+ \@@_mul_cases_o:NnNnww
+ /
+ { - }
+ \@@_div_npos_o:Nww
+ {
+ \or:
+ \@@_case_use:nw
+ { \@@_division_by_zero_o:NNww \c_inf_fp / }
+ \or:
+ \@@_case_use:nw
+ { \@@_division_by_zero_o:NNww \c_minus_inf_fp / }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_div_npos_o:Nww}
+% \begin{quote}
+% \cs{@@_div_npos_o:Nww} \meta{final sign}
+% \cs{s_@@} \cs{@@_chk:w} |1| \meta{sign_A} \Arg{exp A}
+% \Arg{A_1} \Arg{A_2} \Arg{A_3} \Arg{A_4} |;|
+% \cs{s_@@} \cs{@@_chk:w} |1| \meta{sign_Z} \Arg{exp Z}
+% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} |;|
+% \end{quote}
+% We want to compute $A/Z$. As for multiplication,
+% \cs{@@_sanitize:Nw} checks for overflow or underflow; we provide it
+% with the \meta{final sign}, and an integer expression in which we
+% compute the exponent. We set up the arguments of
+% \cs{@@_div_significand_i_o:wnnw}, namely an integer \meta{y} obtained
+% by adding $1$ to the first $5$ digits of $Z$ (explanation given soon
+% below), then the four \Arg{A_{i}}, then the four \Arg{Z_{i}}, a
+% semi-colon, and the \meta{final sign}, used for rounding at the end.
+% \begin{macrocode}
+\cs_new:Npn \@@_div_npos_o:Nww
+ #1 \s_@@ \@@_chk:w 1 #2 #3 #4 ; \s_@@ \@@_chk:w 1 #5 #6 #7#8#9;
+ {
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN #1
+ \int_value:w \@@_int_eval:w
+ #3 - #6
+ \exp_after:wN \@@_div_significand_i_o:wnnw
+ \int_value:w \@@_int_eval:w #7 \use_i:nnnn #8 + 1 ;
+ #4
+ {#7}{#8}#9 ;
+ #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Work plan}
+%
+% In this subsection, we explain how to avoid overflowing \TeX{}'s
+% integers when performing the division of two positive normal numbers.
+%
+% We are given two numbers, $A=0.A_{1}A_{2}A_{3}A_{4}$ and
+% $Z=0.Z_{1}Z_{2}Z_{3}Z_{4}$, in blocks of $4$ digits, and we know that
+% the first digits of $A_{1}$ and of $Z_{1}$ are non-zero. To compute
+% $A/Z$, we proceed as follows.
+% \begin{itemize}
+% \item Find an integer $Q_{A} \simeq 10^{4} A / Z$.
+% \item Replace $A$ by $B = 10^{4} A - Q_{A} Z$.
+% \item Find an integer $Q_{B} \simeq 10^{4} B / Z$.
+% \item Replace $B$ by $C = 10^{4} B - Q_{B} Z$.
+% \item Find an integer $Q_{C} \simeq 10^{4} C / Z$.
+% \item Replace $C$ by $D = 10^{4} C - Q_{C} Z$.
+% \item Find an integer $Q_{D} \simeq 10^{4} D / Z$.
+% \item Consider $E = 10^{4} D - Q_{D} Z$, and ensure
+% correct rounding.
+% \end{itemize}
+% The result is then $Q = 10^{-4} Q_{A} + 10^{-8} Q_{B} + 10^{-12} Q_{C}
+% + 10^{-16} Q_{D} + \text{rounding}$. Since the $Q_{i}$ are integers,
+% $B$, $C$, $D$, and~$E$ are all exact multiples of $10^{-16}$, in other
+% words, computing with $16$ digits after the decimal separator yields
+% exact results. The problem is the risk of overflow: in general $B$, $C$,
+% $D$, and $E$ may be greater than $1$.
+%
+% Unfortunately, things are not as easy as they seem. In particular, we
+% want all intermediate steps to be positive, since negative results
+% would require extra calculations at the end. This requires that
+% $Q_{A} \leq 10^{4} A / Z$ \emph{etc.} A reasonable attempt would be
+% to define $Q_{A}$ as
+% \begin{equation*}
+% \cs{int_eval:n} \left\{
+% \frac{ A_{1} A_{2} }{ Z_{1} + 1 } - 1 \right\}
+% \leq 10^{4} \frac{A}{Z}
+% \end{equation*}
+% Subtracting $1$ at the end takes care of the fact that \eTeX{}'s
+% \cs{@@_int_eval:w} rounds divisions instead of truncating (really,
+% $1/2$ would be sufficient, but we work with integers). We add $1$ to
+% $Z_{1}$ because $Z_{1} \leq 10^{4}Z < Z_{1}+1$ and we need $Q_{A}$ to
+% be an underestimate. However, we are now underestimating $Q_{A}$ too
+% much: it can be wrong by up to $100$, for instance when $Z = 0.1$ and
+% $A \simeq 1$. Then $B$ could take values up to $10$ (maybe more), and
+% a few steps down the line, we would run into arithmetic overflow,
+% since \TeX{} can only handle integers less than roughly $2\cdot
+% 10^{9}$.
+%
+% A better formula is to take
+% \begin{equation*}
+% Q_{A} = \cs{int_eval:n} \left\{
+% \frac{ 10 \cdot A_{1} A_{2} }
+% { \left\lfloor 10^{-3} \cdot Z_{1} Z_{2} \right\rfloor + 1 }
+% - 1 \right\}.
+% \end{equation*}
+% This is always less than $10^{9} A / (10^{5} Z)$, as we wanted. In
+% words, we take the $5$ first digits of $Z$ into account, and the $8$
+% first digits of $A$, using $0$ as a $9$-th digit rather than the true
+% digit for efficiency reasons. We shall prove that using this formula
+% to define all the $Q_{i}$ avoids any overflow. For convenience, let
+% us denote
+% \begin{equation*}
+% y = \left\lfloor 10^{-3} \cdot Z_{1} Z_{2} \right\rfloor + 1,
+% \end{equation*}
+% so that, taking into account the fact that \eTeX{} rounds ties away
+% from zero,
+% \begin{align*}
+% Q_{A}
+% &= \left\lfloor \frac{A_{1}A_{2}0}{y} - \frac{1}{2} \right\rfloor
+% \\
+% &>\frac{A_{1}A_{2}0}{y} - \frac{3}{2}.
+% \end{align*}
+% Note that $10^{4}<y\leq 10^{5}$, and $999 \leq Q_{A} \leq 99989$.
+% Also note that this formula does not cause an overflow as long as $A <
+% (2^{31}-1) / 10^{9} \simeq 2.147\cdots$, since the numerator involves an
+% integer slightly smaller than $10^{9} A$.
+%
+% Let us bound $B$:
+% \begin{align*}
+% 10^{5} B
+% &=
+% A_{1}A_{2}0 + 10 \cdot 0.A_{3}A_{4}
+% - 10 \cdot Z_{1}.Z_{2}Z_{3}Z_{4} \cdot Q_{A}
+% \\
+% &<
+% A_{1}A_{2}0
+% \cdot \left( 1 - 10 \cdot \frac{Z_{1}.Z_{2}Z_{3}Z_{4}}{y} \right)
+% + \frac{3}{2} \cdot 10 \cdot Z_{1}.Z_{2}Z_{3}Z_{4} + 10
+% \\
+% &\leq
+% \frac{A_{1}A_{2}0 \cdot (y - 10 \cdot Z_{1}.Z_{2}Z_{3}Z_{4})}{y}
+% + \frac{3}{2} y + 10
+% \\
+% &\leq
+% \frac{A_{1}A_{2}0\cdot 1}{y} + \frac{3}{2} y + 10
+% \leq
+% \frac{10^{9} A}{y} + 1.6\cdot y.
+% \end{align*}
+% At the last step, we hide $10$ into the second term for later
+% convenience. The same reasoning yields
+% \begin{align*}
+% 10^{5} B &< 10^{9} A/y + 1.6 y, \\
+% 10^{5} C &< 10^{9} B/y + 1.6 y, \\
+% 10^{5} D &< 10^{9} C/y + 1.6 y, \\
+% 10^{5} E &< 10^{9} D/y + 1.6 y. \\
+% \end{align*}
+% The goal is now to prove that none of $B$, $C$, $D$, and $E$ can go
+% beyond $(2^{31}-1) / 10^{9} = 2.147\cdots$.
+%
+% Combining the various inequalities together with $A<1$, we get
+% \begin{align*}
+% 10^{5} B &< 10^{9}/y + 1.6 y, \\
+% 10^{5} C &< 10^{13}/y^{2} + 1.6 (y + 10^{4}), \\
+% 10^{5} D &< 10^{17}/y^{3} + 1.6 (y + 10^{4} + 10^{8}/y), \\
+% 10^{5} E &< 10^{21}/y^{4} + 1.6 (y + 10^{4} + 10^{8}/y + 10^{12}/y^{2}). \\
+% \end{align*}
+% All of those bounds are convex functions of $y$ (since every power of
+% $y$ involved is convex, and the coefficients are positive), and thus
+% maximal at one of the end-points of the allowed range $10^{4} < y \leq
+% 10^{5}$. Thus,
+% \begin{align*}
+% 10^{5} B &< \mathrm{max} ( 1.16\cdot 10^{5}, 1.7 \cdot 10^{5}), \\
+% 10^{5} C &< \mathrm{max} ( 1.32\cdot 10^{5}, 1.77 \cdot 10^{5}), \\
+% 10^{5} D &< \mathrm{max} ( 1.48\cdot 10^{5}, 1.777 \cdot 10^{5}), \\
+% 10^{5} E &< \mathrm{max} ( 1.64\cdot 10^{5}, 1.7777 \cdot 10^{5}). \\
+% \end{align*}
+% All of those bounds are less than $2.147\cdot 10^{5}$, and we are thus
+% within \TeX{}'s bounds in all cases!
+%
+% We later need to have a bound on the $Q_{i}$. Their definitions
+% imply that $Q_{A} < 10^{9} A/y - 1/2 < 10^{5} A$ and similarly for the
+% other $Q_{i}$. Thus, all of them are less than $177770$.
+%
+% The last step is to ensure correct rounding. We have
+% \begin{equation*}
+% A/Z = \sum_{i=1}^{4} \left(10^{-4i} Q_{i}\right) + 10^{-16} E/Z
+% \end{equation*}
+% exactly. Furthermore, we know that the result is in $[0.1,10)$,
+% hence will be rounded to a multiple of $10^{-16}$ or of $10^{-15}$, so
+% we only need to know the integer part of $E/Z$, and a
+% \enquote{rounding} digit encoding the rest. Equivalently, we need to
+% find the integer part of $2E/Z$, and determine whether it was an
+% exact integer or not (this serves to detect ties). Since
+% \begin{equation*}
+% \frac{2E}{Z} = 2\frac{10^{5} E}{10^{5} Z}
+% \leq 2\frac{10^{5} E}{10^{4}} < 36,
+% \end{equation*}
+% this integer part is between $0$ and $35$ inclusive. We let \eTeX{}
+% round
+% \begin{equation*}
+% P = \cs{int_eval:n} \left\{
+% \frac{2\cdot E_{1}E_{2}}{Z_{1}Z_{2}} \right\},
+% \end{equation*}
+% which differs from $2E/Z$ by at most
+% \begin{equation*}
+% \frac{1}{2}
+% + 2 \left\lvert \frac{E}{Z} - \frac{E}{10^{-8} Z_{1}Z_{2}}\right\rvert
+% + 2 \left\lvert \frac{10^{8} E - E_{1}E_{2}}{Z_{1}Z_{2}}\right\rvert
+% < 1,
+% \end{equation*}
+% ($1/2$ comes from \eTeX{}'s rounding) because each absolute value is
+% less than $10^{-7}$. Thus $P$ is either the correct integer part, or
+% is off by $1$; furthermore, if $2 E / Z$ is an integer, $P = 2 E / Z$.
+% We will check the sign of $2 E - P Z$. If it is negative, then $E / Z
+% \in \big((P - 1) / 2, P / 2\big)$. If it is zero, then $E / Z = P /
+% 2$. If it is positive, then $E / Z \in \big(P / 2, (P - 1) / 2\big)$.
+% In each case, we know how to round to an integer, depending on the
+% parity of $P$, and the rounding mode.
+%
+% \subsubsection{Implementing the significand division}
+%
+% \begin{macro}[rEXP]{\@@_div_significand_i_o:wnnw}
+% \begin{quote}
+% \cs{@@_div_significand_i_o:wnnw} \meta{y} |;|
+% \Arg{A_1} \Arg{A_2} \Arg{A_3} \Arg{A_4}
+% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} |;| \meta{sign}
+% \end{quote}
+% Compute $10^{6} + Q_{A}$ (a $7$~digit number thanks to the shift),
+% unbrace \meta{A_1} and \meta{A_2}, and prepare the
+% \meta{continuation} arguments for $4$ consecutive calls to
+% \cs{@@_div_significand_calc:wwnnnnnnn}. Each of these calls needs
+% \meta{y} (|#1|), and it turns out that we need post-expansion there,
+% hence the \cs{int_value:w}. Here, |#4| is six brace groups, which
+% give the six first |n|-type arguments of the \texttt{calc} function.
+% \begin{macrocode}
+\cs_new:Npn \@@_div_significand_i_o:wnnw #1 ; #2#3 #4 ;
+ {
+ \exp_after:wN \@@_div_significand_test_o:w
+ \int_value:w \@@_int_eval:w
+ \exp_after:wN \@@_div_significand_calc:wwnnnnnnn
+ \int_value:w \@@_int_eval:w 999999 + #2 #3 0 / #1 ;
+ #2 #3 ;
+ #4
+ { \exp_after:wN \@@_div_significand_ii:wwn \int_value:w #1 }
+ { \exp_after:wN \@@_div_significand_ii:wwn \int_value:w #1 }
+ { \exp_after:wN \@@_div_significand_ii:wwn \int_value:w #1 }
+ { \exp_after:wN \@@_div_significand_iii:wwnnnnn \int_value:w #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_div_significand_calc:wwnnnnnnn}
+% \begin{macro}[rEXP]
+% {
+% \@@_div_significand_calc_i:wwnnnnnnn,
+% \@@_div_significand_calc_ii:wwnnnnnnn,
+% }
+% \begin{quote}
+% \cs{@@_div_significand_calc:wwnnnnnnn} \meta{$10^{6}+{}$Q_{A}} |;|
+% \meta{A_1} \meta{A_2} |;| \Arg{A_3} \Arg{A_4}
+% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4}
+% \Arg{continuation}
+% \end{quote}
+% expands to
+% \begin{quote}
+% \meta{$10^{6}+{}$Q_{A}} \meta{continuation} |;|
+% \meta{B_1} \meta{B_2} |;| \Arg{B_3} \Arg{B_4}
+% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4}
+% \end{quote}
+% where $B = 10^{4} A - Q_{A} \cdot Z$. This function is also used to
+% compute $C$, $D$, $E$ (with the input shifted accordingly), and is
+% used in \pkg{l3fp-expo}.
+%
+% We know that $0<Q_{A}<1.8\cdot 10^{5}$, so the product of $Q_{A}$
+% with each $Z_{i}$ is within \TeX{}'s bounds. However, it is a
+% little bit too large for our purposes: we would not be able to use
+% the usual trick of adding a large power of $10$ to ensure that the
+% number of digits is fixed.
+%
+% The bound on $Q_{A}$, implies that $10^{6}+Q_{A}$ starts with the
+% digit $1$, followed by $0$ or $1$. We test, and call different
+% auxiliaries for the two cases. An earlier implementation did the
+% tests within the computation, but since we added a
+% \meta{continuation}, this is not possible because the macro has $9$
+% parameters.
+%
+% The result we want is then (the overall power of $10$ is arbitrary):
+% \begin{align*}
+% &10^{-4} ( \#2 - \#1 \cdot \#5 - 10 \cdot \meta{i} \cdot \#5\#6 )
+% + 10^{-8} ( \#3 - \#1 \cdot \#6 - 10 \cdot \meta{i} \cdot \#7 ) \\
+% &+ 10^{-12}( \#4 - \#1 \cdot \#7 - 10 \cdot \meta{i} \cdot \#8 )
+% + 10^{-16}( - \#1 \cdot \#8 ),
+% \end{align*}
+% where \meta{i} stands for the $10^{5}$ digit of $Q_{A}$, which is
+% $0$ or~$1$, and $\#1$, $\#2$, \emph{etc.\@} are the parameters of
+% either auxiliary. The factors of $10$ come from the fact that
+% $Q_{A} = 10\cdot 10^{4} \cdot \meta{i} + \#1$. As usual, to combine
+% all the terms, we need to choose some shifts which must ensure that
+% the number of digits of the second, third, and fourth terms are each
+% fixed. Here, the positive contributions are at most $10^{8}$ and
+% the negative contributions can go up to $10^{9}$. Indeed, for the
+% auxiliary with $\meta{i}=1$, |#1| is at most $80000$, leading to
+% contributions of at worse $-8\cdot 10^{8}4$, while the other
+% negative term is very small $<10^{6}$ (except in the first
+% expression, where we don't care about the number of digits); for the
+% auxiliary with $\meta{i}=0$, |#1| can go up to $99999$, but there is
+% no other negative term. Hence, a good choice is $2\cdot 10^{9}$,
+% which produces totals in the range $[10^{9}, 2.1\cdot 10^{9}]$. We
+% are flirting with \TeX{}'s limits once more.
+% \begin{macrocode}
+\cs_new:Npn \@@_div_significand_calc:wwnnnnnnn 1#1
+ {
+ \if_meaning:w 1 #1
+ \exp_after:wN \@@_div_significand_calc_i:wwnnnnnnn
+ \else:
+ \exp_after:wN \@@_div_significand_calc_ii:wwnnnnnnn
+ \fi:
+ }
+\cs_new:Npn \@@_div_significand_calc_i:wwnnnnnnn
+ #1; #2;#3#4 #5#6#7#8 #9
+ {
+ 1 1 #1
+ #9 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w \c_@@_Bigg_leading_shift_int
+ + #2 - #1 * #5 - #5#60
+ \exp_after:wN \@@_pack_Bigg:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_Bigg_middle_shift_int
+ + #3 - #1 * #6 - #70
+ \exp_after:wN \@@_pack_Bigg:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_Bigg_middle_shift_int
+ + #4 - #1 * #7 - #80
+ \exp_after:wN \@@_pack_Bigg:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_Bigg_trailing_shift_int
+ - #1 * #8 ;
+ {#5}{#6}{#7}{#8}
+ }
+\cs_new:Npn \@@_div_significand_calc_ii:wwnnnnnnn
+ #1; #2;#3#4 #5#6#7#8 #9
+ {
+ 1 0 #1
+ #9 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w \c_@@_Bigg_leading_shift_int
+ + #2 - #1 * #5
+ \exp_after:wN \@@_pack_Bigg:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_Bigg_middle_shift_int
+ + #3 - #1 * #6
+ \exp_after:wN \@@_pack_Bigg:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_Bigg_middle_shift_int
+ + #4 - #1 * #7
+ \exp_after:wN \@@_pack_Bigg:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_Bigg_trailing_shift_int
+ - #1 * #8 ;
+ {#5}{#6}{#7}{#8}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_div_significand_ii:wwn}
+% \begin{quote}
+% \cs{@@_div_significand_ii:wwn} \meta{y} |;|
+% \meta{B_1} |;| \Arg{B_2} \Arg{B_3} \Arg{B_4}
+% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4}
+% \meta{continuations} \meta{sign}
+% \end{quote}
+% Compute $Q_{B}$ by evaluating $\meta{B_1}\meta{B_2}0 / y - 1$. The
+% result is output to the left, in an \cs{@@_int_eval:w} which we
+% start now. Once that is evaluated (and the other $Q_{i}$ also,
+% since later expansions are triggered by this one), a packing
+% auxiliary takes care of placing the digits of $Q_{B}$ in an
+% appropriate way for the final addition to obtain $Q$. This
+% auxiliary is also used to compute $Q_{C}$ and $Q_{D}$ with the
+% inputs $C$ and $D$ instead of $B$.
+% \begin{macrocode}
+\cs_new:Npn \@@_div_significand_ii:wwn #1; #2;#3
+ {
+ \exp_after:wN \@@_div_significand_pack:NNN
+ \int_value:w \@@_int_eval:w
+ \exp_after:wN \@@_div_significand_calc:wwnnnnnnn
+ \int_value:w \@@_int_eval:w 999999 + #2 #3 0 / #1 ; #2 #3 ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_div_significand_iii:wwnnnnn}
+% \begin{quote}
+% \cs{@@_div_significand_iii:wwnnnnn} \meta{y} |;|
+% \meta{E_1} |;| \Arg{E_2} \Arg{E_3} \Arg{E_4}
+% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} \meta{sign}
+% \end{quote}
+% We compute $P \simeq 2E/Z$ by rounding $2 E_{1} E_{2}/Z_{1}Z_{2}$.
+% Note the first $0$, which multiplies $Q_{D}$ by $10$: we later
+% add (roughly) $5\cdot P$, which amounts to adding $P/2 \simeq E/Z$
+% to $Q_{D}$, the appropriate correction from a hypothetical $Q_{E}$.
+% \begin{macrocode}
+\cs_new:Npn \@@_div_significand_iii:wwnnnnn #1; #2;#3#4#5 #6#7
+ {
+ 0
+ \exp_after:wN \@@_div_significand_iv:wwnnnnnnn
+ \int_value:w \@@_int_eval:w ( 2 * #2 #3) / #6 #7 ; % <- P
+ #2 ; {#3} {#4} {#5}
+ {#6} {#7}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {
+% \@@_div_significand_iv:wwnnnnnnn,
+% \@@_div_significand_v:NNw,
+% \@@_div_significand_vi:Nw
+% }
+% \begin{quote}
+% \cs{@@_div_significand_iv:wwnnnnnnn} \meta{P} |;|
+% \meta{E_1} |;| \Arg{E_2} \Arg{E_3} \Arg{E_4}
+% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} \meta{sign}
+% \end{quote}
+% This adds to the current expression ($10^{7} + 10\cdot Q_{D}$) a
+% contribution of $5 \cdot P + \operatorname{sign}(T)$ with $T = 2 E -
+% P Z$. This amounts to adding $P / 2$ to $Q_{D}$, with an extra
+% \meta{rounding} digit. This \meta{rounding} digit is $0$ or $5$ if
+% $T$ does not contribute, \emph{i.e.,} if $0 = T = 2 E - P Z$, in
+% other words if $10^{16} A / Z$ is an integer or half-integer.
+% Otherwise it is in the appropriate range, $[1,4]$ or $[6,9]$. This
+% is precise enough for rounding purposes (in any mode).
+%
+% It seems an overkill to compute $T$ exactly as I do here, but I see
+% no faster way right now.
+%
+% Once more, we need to be careful and show that the calculation
+% $\#1\cdot\#6\#7$ below does not cause an overflow: naively, $P$ can
+% be up to $35$, and $\#6\#7$ up to $10^{8}$, but both cannot happen
+% simultaneously. To show that things are fine, we split in two
+% (non-disjoint) cases.
+% \begin{itemize}
+% \item For $P < 10$, the product obeys $P\cdot\#6\#7 < 10^{8} \cdot P
+% < 10^{9} $.
+% \item For large $P\geq 3$, the rounding error on $P$, which is at
+% most $1$, is less than a factor of $2$, hence $P\leq 4E/Z$. Also,
+% $\#6\#7 \leq 10^{8} \cdot Z$, hence $P\cdot \#6\#7 \leq 4E\cdot
+% 10^{8} < 10^{9}$.
+% \end{itemize}
+% Both inequalities could be made tighter if needed.
+%
+% Note however that $P\cdot \#8\#9$ may overflow, since the two
+% factors are now independent, and the result may reach $3.5\cdot
+% 10^{9}$. Thus we compute the two lower levels separately. The rest
+% is standard, except that we use |+| as a separator (ending integer
+% expressions explicitly). $T$ is negative if the first character is
+% |-|, it is positive if the first character is neither |0| nor |-|.
+% It is also positive if the first character is |0| and second
+% argument of \cs{@@_div_significand_vi:Nw}, a sum of several terms, is
+% also zero. Otherwise, there was an exact agreement: $T = 0$.
+% \begin{macrocode}
+\cs_new:Npn \@@_div_significand_iv:wwnnnnnnn #1; #2;#3#4#5 #6#7#8#9
+ {
+ + 5 * #1
+ \exp_after:wN \@@_div_significand_vi:Nw
+ \int_value:w \@@_int_eval:w -50 + 2*#2#3 - #1*#6#7 +
+ \exp_after:wN \@@_div_significand_v:NN
+ \int_value:w \@@_int_eval:w 499950 + 2*#4 - #1*#8 +
+ \exp_after:wN \@@_div_significand_v:NN
+ \int_value:w \@@_int_eval:w 500000 + 2*#5 - #1*#9 ;
+ }
+\cs_new:Npn \@@_div_significand_v:NN #1#2 { #1#2 \@@_int_eval_end: + }
+\cs_new:Npn \@@_div_significand_vi:Nw #1#2;
+ {
+ \if_meaning:w 0 #1
+ \if_int_compare:w \@@_int_eval:w #2 > 0 + 1 \fi:
+ \else:
+ \if_meaning:w - #1 - \else: + \fi: 1
+ \fi:
+ ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_div_significand_pack:NNN}
+% At this stage, we are in the following situation: \TeX{} is in the
+% process of expanding several integer expressions, thus functions at
+% the bottom expand before those above.
+% \begin{quote}
+% \cs{@@_div_significand_test_o:w} $10^{6} + Q_{A}$
+% \cs{@@_div_significand_pack:NNN} $10^{6} + Q_{B}$
+% \cs{@@_div_significand_pack:NNN} $10^{6} + Q_{C}$
+% \cs{@@_div_significand_pack:NNN}
+% $10^{7} + 10\cdot Q_{D} + 5 \cdot P + \varepsilon$ |;| \meta{sign}
+% \end{quote}
+% Here, $\varepsilon = \operatorname{sign}(T)$ is $0$ in case $2E=PZ$,
+% $1$ in case $2E>PZ$, which means that $P$ was the correct value, but
+% not with an exact quotient, and $-1$ if $2E<PZ$, \emph{i.e.}, $P$
+% was an overestimate. The packing function we define now does
+% nothing special: it removes the $10^{6}$ and carries two digits (for
+% the $10^{5}$'s and the $10^{4}$'s).
+% \begin{macrocode}
+\cs_new:Npn \@@_div_significand_pack:NNN 1 #1 #2 { + #1 #2 ; }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_div_significand_test_o:w}
+% \begin{quote}
+% \cs{@@_div_significand_test_o:w} |1| |0| \meta{5d} |;|
+% ~~\meta{4d} |;| \meta{4d} |;| \meta{5d} |;| \meta{sign}
+% \end{quote}
+% The reason we know that the first two digits are |1| and |0| is that
+% the final result is known to be between $0.1$ (inclusive) and $10$,
+% hence $\widetilde{Q_{A}}$ (the tilde denoting the contribution from
+% the other $Q_{i}$) is at most $99999$, and $10^{6}+\widetilde{Q_{A}}
+% = 10\cdots$.
+%
+% It is now time to round. This depends on how many digits the final
+% result will have.
+% \begin{macrocode}
+\cs_new:Npn \@@_div_significand_test_o:w 10 #1
+ {
+ \if_meaning:w 0 #1
+ \exp_after:wN \@@_div_significand_small_o:wwwNNNNwN
+ \else:
+ \exp_after:wN \@@_div_significand_large_o:wwwNNNNwN
+ \fi:
+ #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_div_significand_small_o:wwwNNNNwN}
+% \begin{quote}
+% \cs{@@_div_significand_small_o:wwwNNNNwN} |0| \meta{4d} |;|
+% ~~\meta{4d} |;| \meta{4d} |;| \meta{5d} |;| \meta{final sign}
+% \end{quote}
+% Standard use of the functions \cs{@@_basics_pack_low:NNNNNw} and
+% \cs{@@_basics_pack_high:NNNNNw}. We finally get to use the
+% \meta{final sign} which has been sitting there for a while.
+% \begin{macrocode}
+\cs_new:Npn \@@_div_significand_small_o:wwwNNNNwN
+ 0 #1; #2; #3; #4#5#6#7#8; #9
+ {
+ \exp_after:wN \@@_basics_pack_high:NNNNNw
+ \int_value:w \@@_int_eval:w 1 #1#2
+ \exp_after:wN \@@_basics_pack_low:NNNNNw
+ \int_value:w \@@_int_eval:w 1 #3#4#5#6#7
+ + \@@_round:NNN #9 #7 #8
+ \exp_after:wN ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_div_significand_large_o:wwwNNNNwN}
+% \begin{quote}
+% \cs{@@_div_significand_large_o:wwwNNNNwN} \meta{5d} |;|
+% ~~\meta{4d} |;| \meta{4d} |;| \meta{5d} |;| \meta{sign}
+% \end{quote}
+% We know that the final result cannot reach $10$, hence |1#1#2|,
+% together with contributions from the level below, cannot reach
+% $2\cdot 10^{9}$. For rounding, we build the \meta{rounding digit}
+% from the last two of our $18$ digits.
+% \begin{macrocode}
+\cs_new:Npn \@@_div_significand_large_o:wwwNNNNwN
+ #1; #2; #3; #4#5#6#7#8; #9
+ {
+ + 1
+ \exp_after:wN \@@_basics_pack_weird_high:NNNNNNNNw
+ \int_value:w \@@_int_eval:w 1 #1 #2
+ \exp_after:wN \@@_basics_pack_weird_low:NNNNw
+ \int_value:w \@@_int_eval:w 1 #3 #4 #5 #6 +
+ \exp_after:wN \@@_round:NNN
+ \exp_after:wN #9
+ \exp_after:wN #6
+ \int_value:w \@@_round_digit:Nw #7 #8 ;
+ \exp_after:wN ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Square root}
+%
+% \begin{macro}[EXP]{\@@_sqrt_o:w}
+% Zeros are unchanged: $\sqrt{-0} = -0$ and $\sqrt{+0} = +0$.
+% Negative numbers (other than $-0$) have no real square root.
+% Positive infinity, and \texttt{nan}, are unchanged. Finally, for
+% normal positive numbers, there is some work to do.
+% \begin{macrocode}
+\cs_new:Npn \@@_sqrt_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+ {
+ \if_meaning:w 0 #2 \@@_case_return_same_o:w \fi:
+ \if_meaning:w 2 #3
+ \@@_case_use:nw { \@@_invalid_operation_o:nw { sqrt } }
+ \fi:
+ \if_meaning:w 1 #2 \else: \@@_case_return_same_o:w \fi:
+ \@@_sqrt_npos_o:w
+ \s_@@ \@@_chk:w #2 #3 #4;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_sqrt_npos_o:w}
+% \begin{macro}[rEXP]
+% {\@@_sqrt_npos_auxi_o:wwnnN, \@@_sqrt_npos_auxii_o:wNNNNNNNN}
+% Prepare \cs{@@_sanitize:Nw} to receive the final sign~|0| (the
+% result is always positive) and the exponent, equal to half of the
+% exponent~|#1| of the argument. If the exponent~|#1| is even, find a
+% first approximation of the square root of the significand $10^{8}
+% a_1 + a_2 = 10^{8} |#2#3| + |#4#5|$ through Newton's method,
+% starting at $x = 57234133 \simeq 10^{7.75}$. Otherwise, first shift
+% the significand of the argument by one digit, getting
+% $a_1'\in[10^{6}, 10^{7})$ instead of $[10^{7}, 10^{8})$, then use
+% Newton's method starting at $17782794 \simeq 10^{7.25}$.
+% \begin{macrocode}
+\cs_new:Npn \@@_sqrt_npos_o:w \s_@@ \@@_chk:w 1 0 #1#2#3#4#5;
+ {
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN 0
+ \int_value:w \@@_int_eval:w
+ \if_int_odd:w #1 \exp_stop_f:
+ \exp_after:wN \@@_sqrt_npos_auxi_o:wwnnN
+ \fi:
+ #1 / 2
+ \@@_sqrt_Newton_o:wwn 56234133; 0; {#2#3} {#4#5} 0
+ }
+\cs_new:Npn \@@_sqrt_npos_auxi_o:wwnnN #1 / 2 #2; 0; #3#4#5
+ {
+ ( #1 + 1 ) / 2
+ \@@_pack_eight:wNNNNNNNN
+ \@@_sqrt_npos_auxii_o:wNNNNNNNN
+ ;
+ 0 #3 #4
+ }
+\cs_new:Npn \@@_sqrt_npos_auxii_o:wNNNNNNNN #1; #2#3#4#5#6#7#8#9
+ { \@@_sqrt_Newton_o:wwn 17782794; 0; {#1} {#2#3#4#5#6#7#8#9} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_sqrt_Newton_o:wwn}
+% Newton's method maps $x\mapsto\bigl[(x + [10^{8} a_1 / x])/2\bigr]$
+% in each iteration, where $[b/c]$ denotes \eTeX{}'s division. This
+% division rounds the real number $b/c$ to the closest integer,
+% rounding ties away from zero, hence when $c$~is even,
+% $b/c - 1/2 + 1/c \leq [b/c] \leq b/c + 1/2$
+% and when $c$~is odd,
+% $b/c - 1/2 + 1/(2c) \leq [b/c] \leq b/c + 1/2 - 1/(2c)$.
+% For all~$c$, $b/c - 1/2 + 1/(2c) \leq [b/c] \leq b/c + 1/2$.
+%
+% Let us prove that the method converges when implemented with \eTeX{}
+% integer division, for any $10^{6} \leq a_1 < 10^{8}$ and starting
+% value $10^{6} \leq x < 10^{8}$. Using the inequalities above and
+% the arithmetic--geometric inequality $(x+t)/2 \geq \sqrt{xt}$ for $t
+% = 10^{8} a_1 / x$, we find
+% \[
+% x'
+% = \left[\frac{x + [10^{8} a_1 / x]}{2}\right]
+% \geq \frac{x + 10^{8} a_1 / x - 1/2 + 1/(2x)}{2}
+% \geq \sqrt{10^{8} a_1} - \frac{1}{4} + \frac{1}{4x} \,.
+% \]
+% After any step of iteration, we thus have $\delta = x - \sqrt{10^{8}
+% a_1} \geq -0.25 + 0.25 \cdot 10^{-8}$. The new difference
+% $\delta' = x' - \sqrt{10^{8} a_1}$ after one step is bounded above
+% as
+% \[
+% x' - \sqrt{10^{8} a_1}
+% \leq \frac{x + 10^{8} a_1 / x + 1/2}{2} + \frac{1}{2}
+% - \sqrt{10^{8} a_1}
+% \leq \frac{\delta}{2} \frac{\delta}{\sqrt{10^{8} a_1} + \delta}
+% + \frac{3}{4} \,.
+% \]
+% For $\delta > 3/2$, this last expression is
+% $\leq\delta/2+3/4<\delta$, hence $\delta$~decreases at each step:
+% since all~$x$ are integers, $\delta$~must reach a value
+% $-1/4<\delta\leq 3/2$. In this range of values, we get $\delta'
+% \leq \frac{3}{4} \frac{3}{2\sqrt{10^{8} a_1}} + \frac{3}{4} \leq
+% 0.75 + 1.125 \cdot 10^{-7}$. We deduce that the difference $\delta
+% = x - \sqrt{10^{8} a_1}$ eventually reaches a value in the interval
+% $[-0.25 + 0.25\cdot 10^{-8}, 0.75 + 11.25 \cdot 10^{-8}]$, whose
+% width is $1 + 11 \cdot 10^{-8}$. The corresponding interval for~$x$
+% may contain two integers, hence $x$~might oscillate between those
+% two values.
+%
+% However, the fact that $x\mapsto x-1$ and $x-1 \mapsto x$ puts
+% stronger constraints, which are not compatible: the first implies
+% \[
+% x + [10^{8} a_1 / x] \leq 2x - 2
+% \]
+% hence $10^{8} a_1 / x \leq x - 3/2$, while the second implies
+% \[
+% x - 1 + [10^{8} a_1 / (x - 1)] \geq 2x - 1
+% \]
+% hence $10^{8} a_1 / (x - 1) \geq x - 1/2$. Combining the two
+% inequalities yields $x^2 - 3x/2 \geq 10^{8} a_1 \geq x - 3x/2 +
+% 1/2$, which cannot hold. Therefore, the iteration always converges
+% to a single integer~$x$. To stop the iteration when two consecutive
+% results are equal, the function \cs{@@_sqrt_Newton_o:wwn} receives
+% the newly computed result as~|#1|, the previous result as~|#2|, and
+% $a_1$ as~|#3|. Note that \eTeX{} combines the computation of a
+% multiplication and a following division, thus avoiding overflow in
+% |#3 * 100000000 / #1|. In any case, the result is within $[10^{7},
+% 10^{8}]$.
+% \begin{macrocode}
+\cs_new:Npn \@@_sqrt_Newton_o:wwn #1; #2; #3
+ {
+ \if_int_compare:w #1 = #2 \exp_stop_f:
+ \exp_after:wN \@@_sqrt_auxi_o:NNNNwnnN
+ \int_value:w \@@_int_eval:w 9999 9999 +
+ \exp_after:wN \@@_use_none_until_s:w
+ \fi:
+ \exp_after:wN \@@_sqrt_Newton_o:wwn
+ \int_value:w \@@_int_eval:w (#1 + #3 * 1 0000 0000 / #1) / 2 ;
+ #1; {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_sqrt_auxi_o:NNNNwnnN}
+% This function is followed by $10^{8}+x-1$, which has~$9$ digits
+% starting with~$1$, then |;| \Arg{a_1} \Arg{a_2} \meta{a'}. Here, $x
+% \simeq \sqrt{10^{8} a_1}$ and we want to estimate the square root of
+% $a = 10^{-8} a_1 + 10^{-16} a_2 + 10^{-17} a'$. We set up an
+% initial underestimate
+% \[
+% y = (x - 1) 10^{-8} + 0.2499998875 \cdot 10^{-8} \lesssim \sqrt{a}\,.
+% \]
+% From the inequalities shown earlier, we know that $y \leq
+% \sqrt{10^{-8} a_1} \leq \sqrt{a}$ and that $\sqrt{10^{-8} a_1} \leq
+% y + 10^{-8} + 11\cdot 10^{-16}$ hence (using $0.1\leq y\leq
+% \sqrt{a}\leq 1$)
+% \[
+% a - y^2 \leq 10^{-8} a_1 + 10^{-8} - y^2
+% \leq (y + 10^{-8} + 11\cdot 10^{-16})^2 - y^2 + 10^{-8}
+% < 3.2 \cdot 10^{-8} \,,
+% \]
+% and $\sqrt{a} - y = (a - y^2)/(\sqrt{a} + y) \leq 16 \cdot 10^{-8}$.
+% Next, \cs{@@_sqrt_auxii_o:NnnnnnnnN} is called several times to
+% get closer and closer underestimates of~$\sqrt{a}$. By
+% construction, the underestimates~$y$ are always increasing, $a - y^2
+% < 3.2 \cdot 10^{-8}$ for all. Also, $y<1$.
+% \begin{macrocode}
+\cs_new:Npn \@@_sqrt_auxi_o:NNNNwnnN 1 #1#2#3#4#5;
+ {
+ \@@_sqrt_auxii_o:NnnnnnnnN
+ \@@_sqrt_auxiii_o:wnnnnnnnn
+ {#1#2#3#4} {#5} {2499} {9988} {7500}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_sqrt_auxii_o:NnnnnnnnN}
+% This receives a continuation function~|#1|, then five blocks of~$4$
+% digits for~$y$, then two $8$-digit blocks and a single digit
+% for~$a$. A common estimate of $\sqrt{a} - y = (a - y^2) / (\sqrt{a}
+% + y)$ is $(a - y^2)/(2y)$, which leads to alternating overestimates
+% and underestimates. We tweak this, to only work with underestimates
+% (no need then to worry about signs in the computation). Each step
+% finds the largest integer $j\leq 6$ such that $10^{4j}(a-y^2) <
+% 2\cdot 10^{8}$, then computes the integer (with \eTeX{}'s rounding
+% division)
+% \[
+% 10^{4j} z =
+% \Bigl[\bigl(\lfloor 10^{4j}(a-y^2)\rfloor - 257\bigr)
+% \cdot (0.5\cdot 10^{8})
+% \Bigm/ \lfloor 10^{8} y + 1\rfloor\Bigr] \,.
+% \]
+% The choice of~$j$ ensures that $10^{4j} z < 2\cdot 10^{8} \cdot
+% 0.5\cdot 10^{8} / 10^{7} = 10^{9}$, thus $10^{9} + 10^{4j} z$ has
+% exactly $10$~digits, does not overflow \TeX{}'s integer range, and
+% starts with~$1$. Incidentally, since all $a - y^2 \leq 3.2\cdot
+% 10^{-8}$, we know that $j\geq 3$.
+%
+% Let us show that $z$ is an underestimate of $\sqrt{a} - y$. On the
+% one hand, $\sqrt{a} - y \leq 16\cdot 10^{-8}$ because this holds for
+% the initial~$y$ and values of~$y$ can only increase. On the other
+% hand, the choice of~$j$ implies that $\sqrt{a} - y \leq
+% 5(\sqrt{a}+y)(\sqrt{a}-y) = 5(a - y^2) < 10^{9-4j}$. For $j=3$, the
+% first bound is better, while for larger~$j$, the second bound is
+% better. For all $j\in[3,6]$, we find $\sqrt{a}-y < 16\cdot
+% 10^{-2j}$. From this, we deduce that
+% \[
+% 10^{4j} (\sqrt{a}-y)
+% = \frac{10^{4j}\bigl(a-y^2-(\sqrt{a}-y)^2\bigr)}{2y}
+% \geq \frac{\bigl\lfloor 10^{4j}(a-y^2)\bigr\rfloor-257}
+% {2\cdot 10^{-8} \lfloor 10^{8}y+1\rfloor}
+% + \frac{1}{2}
+% \]
+% where we have replaced the bound $10^{4j}(16\cdot 10^{-2j}) = 256$
+% by~$257$ and extracted the corresponding term $1/\bigl(2\cdot
+% 10^{-8} \lfloor 10^{8}y+1\rfloor\bigr) \geq 1/2$. Given that
+% \eTeX{}'s integer division obeys $[b/c] \leq b/c + 1/2$, we deduce
+% that $10^{4j} z \leq 10^{4j} (\sqrt{a}-y)$, hence $y+z\leq\sqrt{a}$
+% is an underestimate of~$\sqrt{a}$, as claimed. One implementation
+% detail: because the computation involves |-#4*#4| |-| |2*#3*#5| |-|
+% |2*#2*#6| which may be as low as $-5\cdot 10^{8}$, we need to use
+% the \texttt{pack_big} functions, and the \texttt{big} shifts.
+% \begin{macrocode}
+\cs_new:Npn \@@_sqrt_auxii_o:NnnnnnnnN #1 #2#3#4#5#6 #7#8#9
+ {
+ \exp_after:wN #1
+ \int_value:w \@@_int_eval:w \c_@@_big_leading_shift_int
+ + #7 - #2 * #2
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int
+ - 2 * #2 * #3
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int
+ + #8 - #3 * #3 - 2 * #2 * #4
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int
+ - 2 * #3 * #4 - 2 * #2 * #5
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int
+ + #9 000 0000 - #4 * #4 - 2 * #3 * #5 - 2 * #2 * #6
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int
+ - 2 * #4 * #5 - 2 * #3 * #6
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int
+ - #5 * #5 - 2 * #4 * #6
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w
+ \c_@@_big_middle_shift_int
+ - 2 * #5 * #6
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w
+ \c_@@_big_trailing_shift_int
+ - #6 * #6 ;
+ % (
+ - 257 ) * 5000 0000 / (#2#3 + 1) + 10 0000 0000 ;
+ {#2}{#3}{#4}{#5}{#6} {#7}{#8}#9
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {
+% \@@_sqrt_auxiii_o:wnnnnnnnn,
+% \@@_sqrt_auxiv_o:NNNNNw,
+% \@@_sqrt_auxv_o:NNNNNw,
+% \@@_sqrt_auxvi_o:NNNNNw,
+% \@@_sqrt_auxvii_o:NNNNNw
+% }
+% We receive here the difference $a-y^2=d=\sum_i d_i \cdot 10^{-4i}$,
+% as \meta{d_2} |;| \Arg{d_3} \ldots{} \Arg{d_{10}}, where each block
+% has~$4$ digits, except \meta{d_2}. This function finds the largest
+% $j\leq 6$ such that $10^{4j}(a-y^2) < 2\cdot 10^{8}$, then leaves an
+% open parenthesis and the integer
+% $\bigl\lfloor 10^{4j}(a-y^2)\bigr\rfloor$ in an integer
+% expression. The closing parenthesis is provided by the caller
+% \cs{@@_sqrt_auxii_o:NnnnnnnnN}, which completes the expression
+% \[
+% 10^{4j} z =
+% \Bigl[\bigl(\lfloor 10^{4j}(a-y^2)\rfloor - 257\bigr)
+% \cdot (0.5\cdot 10^{8})
+% \Bigm/ \lfloor 10^{8} y + 1\rfloor\Bigr]
+% \]
+% for an estimate of $10^{4j} (\sqrt{a} - y)$. If $d_2\geq 2$, $j=3$
+% and the \texttt{auxiv} auxiliary receives $10^{12} z$. If $d_2\leq
+% 1$ but $10^{4} d_2 + d_3 \geq 2$, $j=4$ and the \texttt{auxv}
+% auxiliary is called, and receives $10^{16} z$, and so on. In all
+% those cases, the \texttt{auxviii} auxiliary is set up to add~$z$
+% to~$y$, then go back to the \texttt{auxii} step with continuation
+% \texttt{auxiii} (the function we are currently describing). The
+% maximum value of $j$ is~$6$, regardless of whether $10^{12} d_2 +
+% 10^{8} d_3 + 10^{4} d_4 + d_5 \geq 1$. In this last case, we detect
+% when $10^{24} z < 10^{7}$, which essentially means $\sqrt{a} - y
+% \lesssim 10^{-17}$: once this threshold is reached, there is enough
+% information to find the correctly rounded~$\sqrt{a}$ with only one
+% more call to \cs{@@_sqrt_auxii_o:NnnnnnnnN}. Note that the
+% iteration cannot be stuck before reaching $j=6$, because for $j<6$,
+% one has $2\cdot 10^{8}\leq 10^{4(j+1)}(a-y^2)$, hence
+% \[
+% 10^{4j} z
+% \geq \frac{(20000-257)(0.5\cdot 10^{8})}{\lfloor 10^{8} y + 1\rfloor}
+% \geq (20000-257)\cdot 0.5 > 0 \,.
+% \]
+% \begin{macrocode}
+\cs_new:Npn \@@_sqrt_auxiii_o:wnnnnnnnn
+ #1; #2#3#4#5#6#7#8#9
+ {
+ \if_int_compare:w #1 > \c_one_int
+ \exp_after:wN \@@_sqrt_auxiv_o:NNNNNw
+ \int_value:w \@@_int_eval:w (#1#2 %)
+ \else:
+ \if_int_compare:w #1#2 > \c_one_int
+ \exp_after:wN \@@_sqrt_auxv_o:NNNNNw
+ \int_value:w \@@_int_eval:w (#1#2#3 %)
+ \else:
+ \if_int_compare:w #1#2#3 > \c_one_int
+ \exp_after:wN \@@_sqrt_auxvi_o:NNNNNw
+ \int_value:w \@@_int_eval:w (#1#2#3#4 %)
+ \else:
+ \exp_after:wN \@@_sqrt_auxvii_o:NNNNNw
+ \int_value:w \@@_int_eval:w (#1#2#3#4#5 %)
+ \fi:
+ \fi:
+ \fi:
+ }
+\cs_new:Npn \@@_sqrt_auxiv_o:NNNNNw 1#1#2#3#4#5#6;
+ { \@@_sqrt_auxviii_o:nnnnnnn {#1#2#3#4#5#6} {00000000} }
+\cs_new:Npn \@@_sqrt_auxv_o:NNNNNw 1#1#2#3#4#5#6;
+ { \@@_sqrt_auxviii_o:nnnnnnn {000#1#2#3#4#5} {#60000} }
+\cs_new:Npn \@@_sqrt_auxvi_o:NNNNNw 1#1#2#3#4#5#6;
+ { \@@_sqrt_auxviii_o:nnnnnnn {0000000#1} {#2#3#4#5#6} }
+\cs_new:Npn \@@_sqrt_auxvii_o:NNNNNw 1#1#2#3#4#5#6;
+ {
+ \if_int_compare:w #1#2 = \c_zero_int
+ \exp_after:wN \@@_sqrt_auxx_o:Nnnnnnnn
+ \fi:
+ \@@_sqrt_auxviii_o:nnnnnnn {00000000} {000#1#2#3#4#5}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {\@@_sqrt_auxviii_o:nnnnnnn, \@@_sqrt_auxix_o:wnwnw}
+% Simply add the two $8$-digit blocks of~$z$, aligned to the last four
+% of the five $4$-digit blocks of~$y$, then call the \texttt{auxii}
+% auxiliary to evaluate $y'^{2} = (y+z)^{2}$.
+% \begin{macrocode}
+\cs_new:Npn \@@_sqrt_auxviii_o:nnnnnnn #1#2 #3#4#5#6#7
+ {
+ \exp_after:wN \@@_sqrt_auxix_o:wnwnw
+ \int_value:w \@@_int_eval:w #3
+ \exp_after:wN \@@_basics_pack_low:NNNNNw
+ \int_value:w \@@_int_eval:w #1 + 1#4#5
+ \exp_after:wN \@@_basics_pack_low:NNNNNw
+ \int_value:w \@@_int_eval:w #2 + 1#6#7 ;
+ }
+\cs_new:Npn \@@_sqrt_auxix_o:wnwnw #1; #2#3; #4#5;
+ {
+ \@@_sqrt_auxii_o:NnnnnnnnN
+ \@@_sqrt_auxiii_o:wnnnnnnnn {#1}{#2}{#3}{#4}{#5}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {\@@_sqrt_auxx_o:Nnnnnnnn, \@@_sqrt_auxxi_o:wwnnN}
+% At this stage, $j=6$ and $10^{24} z < 10^{7}$, hence
+% \[
+% 10^{7} + 1/2 > 10^{24} z + 1/2 \geq
+% \bigl(10^{24}(a-y^2) - 258\bigr) \cdot (0.5\cdot 10^{8})
+% \Bigm/ (10^{8} y + 1) \,,
+% \]
+% then $10^{24}(a-y^2) - 258 < 2 (10^{7} + 1/2) (y + 10^{-8})$, and
+% \[
+% 10^{24}(a-y^2)
+% < (10^{7} + 1290.5) (1 + 10^{-8}/y) (2y)
+% < (10^{7} + 1290.5) (1 + 10^{-7}) (y + \sqrt{a}) \,,
+% \]
+% which finally implies $0\leq\sqrt{a}-y < 0.2\cdot 10^{-16}$. In
+% particular, $y$~is an underestimate of~$\sqrt{a}$ and $y+0.5\cdot
+% 10^{-16}$ is a (strict) overestimate. There is at exactly one
+% multiple $m$~of $0.5\cdot 10^{-16}$ in the interval $[y, y+0.5\cdot
+% 10^{-16})$. If $m^2>a$, then the square root is inexact and is
+% obtained by rounding $m-\epsilon$ to a multiple of $10^{-16}$ (the
+% precise shift $0<\epsilon<0.5\cdot 10^{-16}$ is irrelevant for
+% rounding). If $m^2=a$ then the square root is exactly~$m$, and
+% there is no rounding. If $m^2<a$ then we round $m+\epsilon$. For
+% now, discard a few irrelevant arguments |#1|, |#2|, |#3|, and find
+% the multiple of $0.5\cdot 10^{-16}$ within $[y, y+0.5\cdot
+% 10^{-16})$; rather, only the last $4$~digits |#8| of~$y$ are
+% considered, and we do not perform any carry yet. The \texttt{auxxi}
+% auxiliary sets up \texttt{auxii} with a continuation function
+% \texttt{auxxii} instead of \texttt{auxiii} as before. To prevent
+% \texttt{auxii} from giving a negative results $a-m^2$, we compute
+% $a+10^{-16}-m^2$ instead, always positive since $m<\sqrt{a}+0.5\cdot
+% 10^{-16}$ and $a\leq 1-10^{-16}$.
+% \begin{macrocode}
+\cs_new:Npn \@@_sqrt_auxx_o:Nnnnnnnn #1#2#3 #4#5#6#7#8
+ {
+ \exp_after:wN \@@_sqrt_auxxi_o:wwnnN
+ \int_value:w \@@_int_eval:w
+ (#8 + 2499) / 5000 * 5000 ;
+ {#4} {#5} {#6} {#7} ;
+ }
+\cs_new:Npn \@@_sqrt_auxxi_o:wwnnN #1; #2; #3#4#5
+ {
+ \@@_sqrt_auxii_o:NnnnnnnnN
+ \@@_sqrt_auxxii_o:nnnnnnnnw
+ #2 {#1}
+ {#3} { #4 + 1 } #5
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {\@@_sqrt_auxxii_o:nnnnnnnnw, \@@_sqrt_auxxiii_o:w}
+% The difference $0\leq a+10^{-16}-m^2\leq
+% 10^{-16}+(\sqrt{a}-m)(\sqrt{a}+m)\leq 2\cdot 10^{-16}$ was just
+% computed: its first $8$~digits vanish, as do the next four,~|#1|,
+% and most of the following four,~|#2|. The guess~$m$ is an
+% overestimate if $a+10^{-16}-m^2 < 10^{-16}$, that is, |#1#2|
+% vanishes. Otherwise it is an underestimate, unless
+% $a+10^{-16}-m^2=10^{-16}$ exactly. For an underestimate, call the
+% \texttt{auxxiv} function with argument~$9998$. For an exact result
+% call it with~$9999$, and for an overestimate call it with~$10000$.
+% \begin{macrocode}
+\cs_new:Npn \@@_sqrt_auxxii_o:nnnnnnnnw 0; #1#2#3#4#5#6#7#8 #9;
+ {
+ \if_int_compare:w #1#2 > \c_zero_int
+ \if_int_compare:w #1#2 = \c_one_int
+ \if_int_compare:w #3#4 = \c_zero_int
+ \if_int_compare:w #5#6 = \c_zero_int
+ \if_int_compare:w #7#8 = \c_zero_int
+ \@@_sqrt_auxxiii_o:w
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \exp_after:wN \@@_sqrt_auxxiv_o:wnnnnnnnN
+ \int_value:w 9998
+ \else:
+ \exp_after:wN \@@_sqrt_auxxiv_o:wnnnnnnnN
+ \int_value:w 10000
+ \fi:
+ ;
+ }
+\cs_new:Npn \@@_sqrt_auxxiii_o:w \fi: \fi: \fi: \fi: #1 \fi: ;
+ {
+ \fi: \fi: \fi: \fi: \fi:
+ \@@_sqrt_auxxiv_o:wnnnnnnnN 9999 ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_sqrt_auxxiv_o:wnnnnnnnN}
+% This receives $9998$, $9999$ or $10000$ as~|#1| when $m$~is an
+% underestimate, exact, or an overestimate, respectively. Then
+% comes~$m$ as five blocks of~$4$ digits, but where the last
+% block~|#6| may be $0$, $5000$, or~$10000$. In the latter case, we
+% need to add a carry, unless $m$~is an overestimate (|#1|~is then
+% $10000$). Then comes~$a$ as three arguments. Rounding is done by
+% \cs{@@_round:NNN}, whose first argument is the final sign~$0$
+% (square roots are positive). We fake its second argument. It
+% should be the last digit kept, but this is only used when ties are
+% \enquote{rounded to even}, and only when the result is exactly
+% half-way between two representable numbers rational square roots of
+% numbers with $16$~significant digits have: this situation never
+% arises for the square root, as any exact square root of a $16$~digit
+% number has at most $8$~significant digits. Finally, the last
+% argument is the next digit, possibly shifted by~$1$ when there are
+% further nonzero digits. This is achieved by \cs{@@_round_digit:Nw},
+% which receives (after removal of the $10000$'s digit) one of $0000$,
+% $0001$, $4999$, $5000$, $5001$, or~$9999$, which it converts to $0$,
+% $1$, $4$, $5$, $6$, and~$9$, respectively.
+% \begin{macrocode}
+\cs_new:Npn \@@_sqrt_auxxiv_o:wnnnnnnnN #1; #2#3#4#5#6 #7#8#9
+ {
+ \exp_after:wN \@@_basics_pack_high:NNNNNw
+ \int_value:w \@@_int_eval:w 1 0000 0000 + #2#3
+ \exp_after:wN \@@_basics_pack_low:NNNNNw
+ \int_value:w \@@_int_eval:w 1 0000 0000
+ + #4#5
+ \if_int_compare:w #6 > #1 \exp_stop_f: + 1 \fi:
+ + \exp_after:wN \@@_round:NNN
+ \exp_after:wN 0
+ \exp_after:wN 0
+ \int_value:w
+ \exp_after:wN \use_i:nn
+ \exp_after:wN \@@_round_digit:Nw
+ \int_value:w \@@_int_eval:w #6 + 19999 - #1 ;
+ \exp_after:wN ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{About the sign and exponent}
+%
+% \begin{macro}[EXP]{\@@_logb_o:w, \@@_logb_aux_o:w}
+% The exponent of a normal number is its \meta{exponent} minus one.
+% \begin{macrocode}
+\cs_new:Npn \@@_logb_o:w ? \s_@@ \@@_chk:w #1#2; @
+ {
+ \if_case:w #1 \exp_stop_f:
+ \@@_case_use:nw
+ { \@@_division_by_zero_o:Nnw \c_minus_inf_fp { logb } }
+ \or: \exp_after:wN \@@_logb_aux_o:w
+ \or: \@@_case_return_o:Nw \c_inf_fp
+ \else: \@@_case_return_same_o:w
+ \fi:
+ \s_@@ \@@_chk:w #1 #2;
+ }
+\cs_new:Npn \@@_logb_aux_o:w \s_@@ \@@_chk:w #1 #2 #3 #4 ;
+ {
+ \exp_after:wN \@@_parse:n \exp_after:wN
+ { \int_value:w \int_eval:w #3 - 1 \exp_after:wN }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_sign_o:w}
+% \begin{macro}[EXP]{\@@_sign_aux_o:w}
+% Find the sign of the floating point: \texttt{nan}, |+0|, |-0|, |+1| or |-1|.
+% \begin{macrocode}
+\cs_new:Npn \@@_sign_o:w ? \s_@@ \@@_chk:w #1#2; @
+ {
+ \if_case:w #1 \exp_stop_f:
+ \@@_case_return_same_o:w
+ \or: \exp_after:wN \@@_sign_aux_o:w
+ \or: \exp_after:wN \@@_sign_aux_o:w
+ \else: \@@_case_return_same_o:w
+ \fi:
+ \s_@@ \@@_chk:w #1 #2;
+ }
+\cs_new:Npn \@@_sign_aux_o:w \s_@@ \@@_chk:w #1 #2 #3 ;
+ { \exp_after:wN \@@_set_sign_o:w \exp_after:wN #2 \c_one_fp @ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_set_sign_o:w}
+% This function is used for the unary minus and for \texttt{abs}. It
+% leaves the sign of \texttt{nan} invariant, turns negative numbers
+% (sign~$2$) to positive numbers (sign~$0$) and positive numbers
+% (sign~$0$) to positive or negative numbers depending on~|#1|. It
+% also expands after itself in the input stream, just like
+% \cs{@@_+_o:ww}.
+% \begin{macrocode}
+\cs_new:Npn \@@_set_sign_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+ {
+ \exp_after:wN \@@_exp_after_o:w
+ \exp_after:wN \s_@@
+ \exp_after:wN \@@_chk:w
+ \exp_after:wN #2
+ \int_value:w
+ \if_case:w #3 \exp_stop_f: #1 \or: 1 \or: 0 \fi: \exp_stop_f:
+ #4;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Operations on tuples}
+%
+% \begin{macro}[EXP]{\@@_tuple_set_sign_o:w}
+% \begin{macro}[EXP]{\@@_tuple_set_sign_aux_o:Nnw, \@@_tuple_set_sign_aux_o:w}
+% Two cases: |abs(|\meta{tuple}|)| for which |#1| is $0$ (invalid for
+% tuples) and |-|\meta{tuple} for which |#1| is $2$. In that case,
+% map over all items in the tuple an auxiliary that dispatches to the
+% type-appropriate sign-flipping function.
+% \begin{macrocode}
+\cs_new:Npn \@@_tuple_set_sign_o:w #1#2 @
+ {
+ \if_meaning:w 2 #1
+ \exp_after:wN \@@_tuple_set_sign_aux_o:Nnw
+ \fi:
+ \@@_invalid_operation_o:nw { abs }
+ #2
+ }
+\cs_new:Npn \@@_tuple_set_sign_aux_o:Nnw #1#2
+ { \@@_tuple_map_o:nw \@@_tuple_set_sign_aux_o:w }
+\cs_new:Npn \@@_tuple_set_sign_aux_o:w #1#2 ;
+ {
+ \@@_change_func_type:NNN #1 \@@_set_sign_o:w
+ \@@_parse_apply_unary_error:NNw
+ 2 #1 #2 ; @
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_*_tuple_o:ww, \@@_tuple_*_o:ww, \@@_tuple_/_o:ww}
+% For \meta{number}|*|\meta{tuple} and \meta{tuple}|*|\meta{number}
+% and \meta{tuple}|/|\meta{number}, loop through the \meta{tuple} some
+% code that multiplies or divides by the appropriate \meta{number}.
+% Importantly we need to dispatch according to the type, and we make
+% sure to apply the operator in the correct order.
+% \begin{macrocode}
+\cs_new:cpn { @@_*_tuple_o:ww } #1 ;
+ { \@@_tuple_map_o:nw { \@@_binary_type_o:Nww * #1 ; } }
+\cs_new:cpn { @@_tuple_*_o:ww } #1 ; #2 ;
+ { \@@_tuple_map_o:nw { \@@_binary_rev_type_o:Nww * #2 ; } #1 ; }
+\cs_new:cpn { @@_tuple_/_o:ww } #1 ; #2 ;
+ { \@@_tuple_map_o:nw { \@@_binary_rev_type_o:Nww / #2 ; } #1 ; }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_tuple_+_tuple_o:ww, \@@_tuple_-_tuple_o:ww}
+% Check the two tuples have the same number of items and map through
+% these a helper that dispatches appropriately depending on the types.
+% This means |(1,2)+((1,1),2)| gives |(nan,4)|.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \cs_new:cpn { @@_tuple_#1_tuple_o:ww }
+ \s_@@_tuple \@@_tuple_chk:w ##1 ;
+ \s_@@_tuple \@@_tuple_chk:w ##2 ;
+ {
+ \int_compare:nNnTF
+ { \@@_array_count:n {##1} } = { \@@_array_count:n {##2} }
+ { \@@_tuple_mapthread_o:nww { \@@_binary_type_o:Nww #1 } }
+ { \@@_invalid_operation_o:nww #1 }
+ \s_@@_tuple \@@_tuple_chk:w {##1} ;
+ \s_@@_tuple \@@_tuple_chk:w {##2} ;
+ }
+ }
+\@@_tmp:w +
+\@@_tmp:w -
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintChanges
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-convert.dtx b/macros/latex-dev/required/l3kernel/l3fp-convert.dtx
new file mode 100644
index 0000000000..a0536c1299
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-convert.dtx
@@ -0,0 +1,630 @@
+% \iffalse meta-comment
+%
+%% File: l3fp-convert.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-convert} module\\ Floating point conversion^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\texttt{l3fp-convert} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% \subsection{Dealing with tuples}
+%
+% \begin{macro}[EXP]
+% {\@@_tuple_convert:Nw, \@@_tuple_convert_loop:nNw, \@@_tuple_convert_end:w}
+% The first argument is for instance \cs{@@_to_tl_dispatch:w}, which
+% converts any floating point object to the appropriate
+% representation. We loop through all items, putting |,~| between all
+% of them and making sure to remove the leading |,~|.
+% \begin{macrocode}
+\cs_new:Npn \@@_tuple_convert:Nw #1 \s_@@_tuple \@@_tuple_chk:w #2 ;
+ {
+ \int_case:nnF { \@@_array_count:n {#2} }
+ {
+ { 0 } { ( ) }
+ { 1 } { \@@_tuple_convert_end:w @ { #1 #2 , } }
+ }
+ {
+ \@@_tuple_convert_loop:nNw { } #1
+ #2 { ? \@@_tuple_convert_end:w } ;
+ @ { \use_none:nn }
+ }
+ }
+\cs_new:Npn \@@_tuple_convert_loop:nNw #1#2#3#4; #5 @ #6
+ {
+ \use_none:n #3
+ \exp_args:Nf \@@_tuple_convert_loop:nNw { #2 #3#4 ; } #2 #5
+ @ { #6 , ~ #1 }
+ }
+\cs_new:Npn \@@_tuple_convert_end:w #1 @ #2
+ { \exp_after:wN ( \exp:w \exp_end_continue_f:w #2 ) }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Trimming trailing zeros}
+%
+% \begin{macro}[EXP]{\@@_trim_zeros:w}
+% \begin{macro}[EXP]
+% {\@@_trim_zeros_loop:w, \@@_trim_zeros_dot:w, \@@_trim_zeros_end:w}
+% If |#1| ends with a $0$, the \texttt{loop} auxiliary takes that zero
+% as an end-delimiter for its first argument, and the second argument
+% is the same \texttt{loop} auxiliary. Once the last trailing zero is
+% reached, the second argument is the \texttt{dot} auxiliary,
+% which removes a trailing dot if any. We then clean-up with the
+% \texttt{end} auxiliary, keeping only the number.
+% \begin{macrocode}
+\cs_new:Npn \@@_trim_zeros:w #1 ;
+ {
+ \@@_trim_zeros_loop:w #1
+ ; \@@_trim_zeros_loop:w 0; \@@_trim_zeros_dot:w .; \s_@@_stop
+ }
+\cs_new:Npn \@@_trim_zeros_loop:w #1 0; #2 { #2 #1 ; #2 }
+\cs_new:Npn \@@_trim_zeros_dot:w #1 .; { \@@_trim_zeros_end:w #1 ; }
+\cs_new:Npn \@@_trim_zeros_end:w #1 ; #2 \s_@@_stop { #1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Scientific notation}
+%
+% \begin{macro}[EXP]
+% {\fp_to_scientific:N, \fp_to_scientific:c, \fp_to_scientific:n}
+% The three public functions evaluate their argument, then pass it to
+% \cs{@@_to_scientific_dispatch:w}.
+% \begin{macrocode}
+\cs_new:Npn \fp_to_scientific:N #1
+ { \exp_after:wN \@@_to_scientific_dispatch:w #1 }
+\cs_generate_variant:Nn \fp_to_scientific:N { c }
+\cs_new:Npn \fp_to_scientific:n
+ {
+ \exp_after:wN \@@_to_scientific_dispatch:w
+ \exp:w \exp_end_continue_f:w \@@_parse:n
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_to_scientific_dispatch:w, \@@_to_scientific_recover:w, \@@_tuple_to_scientific:w}
+% We allow tuples.
+% \begin{macrocode}
+\cs_new:Npn \@@_to_scientific_dispatch:w #1
+ {
+ \@@_change_func_type:NNN
+ #1 \@@_to_scientific:w \@@_to_scientific_recover:w
+ #1
+ }
+\cs_new:Npn \@@_to_scientific_recover:w #1 #2 ;
+ {
+ \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+ nan
+ }
+\cs_new:Npn \@@_tuple_to_scientific:w
+ { \@@_tuple_convert:Nw \@@_to_scientific_dispatch:w }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_to_scientific:w,
+% \@@_to_scientific_normal:wnnnnn,
+% \@@_to_scientific_normal:wNw
+% }
+% Expressing an internal floating point number in scientific notation
+% is quite easy: no rounding, and the format is very well defined.
+% First cater for the sign: negative numbers ($|#2|=2$) start
+% with~|-|; we then only need to care about positive numbers and
+% \texttt{nan}. Then filter the special cases: $\pm0$~are represented
+% as~|0|; infinities are converted to a number slightly larger than
+% the largest after an \enquote{invalid_operation} exception;
+% \texttt{nan} is represented as~|0| after an
+% \enquote{invalid_operation} exception. In the normal case,
+% decrement the exponent and unbrace the $4$ brace groups, then in a
+% second step grab the first digit (previously hidden in braces) to
+% order the various parts correctly.
+% \begin{macrocode}
+\cs_new:Npn \@@_to_scientific:w \s_@@ \@@_chk:w #1#2
+ {
+ \if_meaning:w 2 #2 \exp_after:wN - \exp:w \exp_end_continue_f:w \fi:
+ \if_case:w #1 \exp_stop_f:
+ \@@_case_return:nw { 0.000000000000000e0 }
+ \or: \exp_after:wN \@@_to_scientific_normal:wnnnnn
+ \or:
+ \@@_case_use:nw
+ {
+ \@@_invalid_operation:nnw
+ { \fp_to_scientific:N \c_@@_overflowing_fp }
+ { fp_to_scientific }
+ }
+ \or:
+ \@@_case_use:nw
+ {
+ \@@_invalid_operation:nnw
+ { \fp_to_scientific:N \c_zero_fp }
+ { fp_to_scientific }
+ }
+ \fi:
+ \s_@@ \@@_chk:w #1 #2
+ }
+\cs_new:Npn \@@_to_scientific_normal:wnnnnn
+ \s_@@ \@@_chk:w 1 #1 #2 #3#4#5#6 ;
+ {
+ \exp_after:wN \@@_to_scientific_normal:wNw
+ \exp_after:wN e
+ \int_value:w \@@_int_eval:w #2 - 1
+ ; #3 #4 #5 #6 ;
+ }
+\cs_new:Npn \@@_to_scientific_normal:wNw #1 ; #2#3;
+ { #2.#3 #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Decimal representation}
+%
+% \begin{macro}[EXP]
+% {\fp_to_decimal:N, \fp_to_decimal:c, \fp_to_decimal:n}
+% All three public variants are based on the same
+% \cs{@@_to_decimal_dispatch:w}
+% after evaluating their argument to an internal floating point.
+% \begin{macrocode}
+\cs_new:Npn \fp_to_decimal:N #1
+ { \exp_after:wN \@@_to_decimal_dispatch:w #1 }
+\cs_generate_variant:Nn \fp_to_decimal:N { c }
+\cs_new:Npn \fp_to_decimal:n
+ {
+ \exp_after:wN \@@_to_decimal_dispatch:w
+ \exp:w \exp_end_continue_f:w \@@_parse:n
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_to_decimal_dispatch:w, \@@_to_decimal_recover:w, \@@_tuple_to_decimal:w}
+% We allow tuples.
+% \begin{macrocode}
+\cs_new:Npn \@@_to_decimal_dispatch:w #1
+ {
+ \@@_change_func_type:NNN
+ #1 \@@_to_decimal:w \@@_to_decimal_recover:w
+ #1
+ }
+\cs_new:Npn \@@_to_decimal_recover:w #1 #2 ;
+ {
+ \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+ nan
+ }
+\cs_new:Npn \@@_tuple_to_decimal:w
+ { \@@_tuple_convert:Nw \@@_to_decimal_dispatch:w }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_to_decimal:w,
+% \@@_to_decimal_normal:wnnnnn,
+% \@@_to_decimal_large:Nnnw,
+% \@@_to_decimal_huge:wnnnn,
+% }
+% The structure is similar to \cs{@@_to_scientific:w}.
+% Insert |-| for
+% negative numbers. Zero gives $0$, $\pm\infty$ and \nan{} yield an
+% \enquote{invalid operation} exception; note that $\pm\infty$
+% produces a very large output, which we don't expand now since it
+% most likely won't be needed. Normal numbers with an exponent in the
+% range $[1,15]$ have that number of digits before the decimal
+% separator: \enquote{decimate} them, and remove leading zeros with
+% \cs{int_value:w}, then trim trailing zeros and dot. Normal
+% numbers with an exponent $16$ or larger have no decimal separator,
+% we only need to add trailing zeros. When the exponent is
+% non-positive, the result should be $0.\meta{zeros}\meta{digits}$,
+% trimmed.
+% \begin{macrocode}
+\cs_new:Npn \@@_to_decimal:w \s_@@ \@@_chk:w #1#2
+ {
+ \if_meaning:w 2 #2 \exp_after:wN - \exp:w \exp_end_continue_f:w \fi:
+ \if_case:w #1 \exp_stop_f:
+ \@@_case_return:nw { 0 }
+ \or: \exp_after:wN \@@_to_decimal_normal:wnnnnn
+ \or:
+ \@@_case_use:nw
+ {
+ \@@_invalid_operation:nnw
+ { \fp_to_decimal:N \c_@@_overflowing_fp }
+ { fp_to_decimal }
+ }
+ \or:
+ \@@_case_use:nw
+ {
+ \@@_invalid_operation:nnw
+ { 0 }
+ { fp_to_decimal }
+ }
+ \fi:
+ \s_@@ \@@_chk:w #1 #2
+ }
+\cs_new:Npn \@@_to_decimal_normal:wnnnnn
+ \s_@@ \@@_chk:w 1 #1 #2 #3#4#5#6 ;
+ {
+ \int_compare:nNnTF {#2} > 0
+ {
+ \int_compare:nNnTF {#2} < \c_@@_prec_int
+ {
+ \@@_decimate:nNnnnn { \c_@@_prec_int - #2 }
+ \@@_to_decimal_large:Nnnw
+ }
+ {
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_to_decimal_huge:wnnnn
+ \prg_replicate:nn { #2 - \c_@@_prec_int } { 0 } ;
+ }
+ {#3} {#4} {#5} {#6}
+ }
+ {
+ \exp_after:wN \@@_trim_zeros:w
+ \exp_after:wN 0
+ \exp_after:wN .
+ \exp:w \exp_end_continue_f:w \prg_replicate:nn { - #2 } { 0 }
+ #3#4#5#6 ;
+ }
+ }
+\cs_new:Npn \@@_to_decimal_large:Nnnw #1#2#3#4;
+ {
+ \exp_after:wN \@@_trim_zeros:w \int_value:w
+ \if_int_compare:w #2 > \c_zero_int
+ #2
+ \fi:
+ \exp_stop_f:
+ #3.#4 ;
+ }
+\cs_new:Npn \@@_to_decimal_huge:wnnnn #1; #2#3#4#5 { #2#3#4#5 #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Token list representation}
+%
+% \begin{macro}[EXP]{\fp_to_tl:N, \fp_to_tl:c, \fp_to_tl:n}
+% These three public functions evaluate their argument, then pass it
+% to \cs{@@_to_tl_dispatch:w}.
+% \begin{macrocode}
+\cs_new:Npn \fp_to_tl:N #1 { \exp_after:wN \@@_to_tl_dispatch:w #1 }
+\cs_generate_variant:Nn \fp_to_tl:N { c }
+\cs_new:Npn \fp_to_tl:n
+ {
+ \exp_after:wN \@@_to_tl_dispatch:w
+ \exp:w \exp_end_continue_f:w \@@_parse:n
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_to_tl_dispatch:w, \@@_to_tl_recover:w, \@@_tuple_to_tl:w}
+% We allow tuples.
+% \begin{macrocode}
+\cs_new:Npn \@@_to_tl_dispatch:w #1
+ { \@@_change_func_type:NNN #1 \@@_to_tl:w \@@_to_tl_recover:w #1 }
+\cs_new:Npn \@@_to_tl_recover:w #1 #2 ;
+ {
+ \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+ nan
+ }
+\cs_new:Npn \@@_tuple_to_tl:w
+ { \@@_tuple_convert:Nw \@@_to_tl_dispatch:w }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_to_tl:w, \@@_to_tl_normal:nnnnn,
+% \@@_to_tl_scientific:wnnnnn, \@@_to_tl_scientific:wNw
+% }
+% A structure similar to \cs{@@_to_scientific_dispatch:w} and
+% \cs{@@_to_decimal_dispatch:w}, but without the \enquote{invalid operation}
+% exception. First filter special cases. We express normal numbers
+% in decimal notation if the exponent is in the range $[-2,16]$, and
+% otherwise use scientific notation.
+% \begin{macrocode}
+\cs_new:Npn \@@_to_tl:w \s_@@ \@@_chk:w #1#2
+ {
+ \if_meaning:w 2 #2 \exp_after:wN - \exp:w \exp_end_continue_f:w \fi:
+ \if_case:w #1 \exp_stop_f:
+ \@@_case_return:nw { 0 }
+ \or: \exp_after:wN \@@_to_tl_normal:nnnnn
+ \or: \@@_case_return:nw { inf }
+ \else: \@@_case_return:nw { nan }
+ \fi:
+ }
+\cs_new:Npn \@@_to_tl_normal:nnnnn #1
+ {
+ \int_compare:nTF
+ { -2 <= #1 <= \c_@@_prec_int }
+ { \@@_to_decimal_normal:wnnnnn }
+ { \@@_to_tl_scientific:wnnnnn }
+ \s_@@ \@@_chk:w 1 0 {#1}
+ }
+\cs_new:Npn \@@_to_tl_scientific:wnnnnn
+ \s_@@ \@@_chk:w 1 #1 #2 #3#4#5#6 ;
+ {
+ \exp_after:wN \@@_to_tl_scientific:wNw
+ \exp_after:wN e
+ \int_value:w \@@_int_eval:w #2 - 1
+ ; #3 #4 #5 #6 ;
+ }
+\cs_new:Npn \@@_to_tl_scientific:wNw #1 ; #2#3;
+ { \@@_trim_zeros:w #2.#3 ; #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Formatting}
+%
+% This is not implemented yet, as it is not yet clear what a correct
+% interface would be, for this kind of structured conversion from a
+% floating point (or other types of variables) to a string. Ideas
+% welcome.
+%
+% \subsection{Convert to dimension or integer}
+%
+% \begin{macro}[EXP]{\fp_to_dim:N, \fp_to_dim:c, \fp_to_dim:n}
+% \begin{macro}[EXP]{\@@_to_dim_dispatch:w, \@@_to_dim_recover:w, \@@_to_dim:w}
+% All three public variants are based on the same
+% \cs{@@_to_dim_dispatch:w} after evaluating their argument to an
+% internal floating point.
+% We only allow floating point numbers, not tuples.
+% \begin{macrocode}
+\cs_new:Npn \fp_to_dim:N #1
+ { \exp_after:wN \@@_to_dim_dispatch:w #1 }
+\cs_generate_variant:Nn \fp_to_dim:N { c }
+\cs_new:Npn \fp_to_dim:n
+ {
+ \exp_after:wN \@@_to_dim_dispatch:w
+ \exp:w \exp_end_continue_f:w \@@_parse:n
+ }
+\cs_new:Npn \@@_to_dim_dispatch:w #1#2 ;
+ {
+ \@@_change_func_type:NNN #1 \@@_to_dim:w \@@_to_dim_recover:w
+ #1 #2 ;
+ }
+\cs_new:Npn \@@_to_dim_recover:w #1
+ { \@@_invalid_operation:nnw { 0pt } { fp_to_dim } }
+\cs_new:Npn \@@_to_dim:w #1 ; { \@@_to_decimal:w #1 ; pt }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\fp_to_int:N, \fp_to_int:c, \fp_to_int:n}
+% \begin{macro}[EXP]{\@@_to_int_dispatch:w, \@@_to_int_recover:w}
+% For the most part identical to \cs{fp_to_dim:N} but without |pt|,
+% and where \cs{@@_to_int:w} does more work.
+% To convert to an integer, first round to $0$ places (to the nearest
+% integer), then express the result as a decimal number: the
+% definition of \cs{@@_to_decimal_dispatch:w} is such that there are no
+% trailing dot nor zero.
+% \begin{macrocode}
+\cs_new:Npn \fp_to_int:N #1 { \exp_after:wN \@@_to_int_dispatch:w #1 }
+\cs_generate_variant:Nn \fp_to_int:N { c }
+\cs_new:Npn \fp_to_int:n
+ {
+ \exp_after:wN \@@_to_int_dispatch:w
+ \exp:w \exp_end_continue_f:w \@@_parse:n
+ }
+\cs_new:Npn \@@_to_int_dispatch:w #1#2 ;
+ {
+ \@@_change_func_type:NNN #1 \@@_to_int:w \@@_to_int_recover:w
+ #1 #2 ;
+ }
+\cs_new:Npn \@@_to_int_recover:w #1
+ { \@@_invalid_operation:nnw { 0 } { fp_to_int } }
+\cs_new:Npn \@@_to_int:w #1;
+ {
+ \exp_after:wN \@@_to_decimal:w \exp:w \exp_end_continue_f:w
+ \@@_round:Nwn \@@_round_to_nearest:NNN #1; { 0 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Convert from a dimension}
+%
+% \begin{macro}[EXP]{\dim_to_fp:n}
+% \begin{macro}[EXP]
+% {
+% \@@_from_dim_test:ww,
+% \@@_from_dim:wNw,
+% \@@_from_dim:wNNnnnnnn,
+% \@@_from_dim:wnnnnwNw,
+% }
+% The dimension expression (which can in fact be a glue expression) is
+% evaluated, converted to a number (\emph{i.e.}, expressed in scaled
+% points), then multiplied by $2^{-16} = 0.0000152587890625$ to give a
+% value expressed in points. The auxiliary \cs{@@_mul_npos_o:Nww}
+% expects the desired \meta{final sign} and two floating point
+% operands (of the form \cs{s_@@} \ldots{} |;|) as arguments.
+% This set of functions is also used to convert dimension registers to
+% floating points while parsing expressions: in this context there is
+% an additional exponent, which is the first argument of
+% \cs{@@_from_dim_test:ww}, and is combined with the exponent $-4$
+% of $2^{-16}$. There is also a need to expand afterwards: this is
+% performed by \cs{@@_mul_npos_o:Nww}, and cancelled by
+% \cs{prg_do_nothing:} here.
+% \begin{macrocode}
+\cs_new:Npn \dim_to_fp:n #1
+ {
+ \exp_after:wN \@@_from_dim_test:ww
+ \exp_after:wN 0
+ \exp_after:wN ,
+ \int_value:w \tex_glueexpr:D #1 ;
+ }
+\cs_new:Npn \@@_from_dim_test:ww #1, #2
+ {
+ \if_meaning:w 0 #2
+ \@@_case_return:nw { \exp_after:wN \c_zero_fp }
+ \else:
+ \exp_after:wN \@@_from_dim:wNw
+ \int_value:w \@@_int_eval:w #1 - 4
+ \if_meaning:w - #2
+ \exp_after:wN , \exp_after:wN 2 \int_value:w
+ \else:
+ \exp_after:wN , \exp_after:wN 0 \int_value:w #2
+ \fi:
+ \fi:
+ }
+\cs_new:Npn \@@_from_dim:wNw #1,#2#3;
+ {
+ \@@_pack_twice_four:wNNNNNNNN \@@_from_dim:wNNnnnnnn ;
+ #3 000 0000 00 {10}987654321; #2 {#1}
+ }
+\cs_new:Npn \@@_from_dim:wNNnnnnnn #1; #2#3#4#5#6#7#8#9
+ { \@@_from_dim:wnnnnwNn #1 {#2#300} {0000} ; }
+\cs_new:Npn \@@_from_dim:wnnnnwNn #1; #2#3#4#5#6; #7#8
+ {
+ \@@_mul_npos_o:Nww #7
+ \s_@@ \@@_chk:w 1 #7 {#5} #1 ;
+ \s_@@ \@@_chk:w 1 0 {#8} {1525} {8789} {0625} {0000} ;
+ \prg_do_nothing:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Use and eval}
+%
+% \begin{macro}[EXP]{\fp_use:N, \fp_use:c, \fp_eval:n}
+% Those public functions are simple copies of the decimal conversions.
+% \begin{macrocode}
+\cs_new_eq:NN \fp_use:N \fp_to_decimal:N
+\cs_generate_variant:Nn \fp_use:N { c }
+\cs_new_eq:NN \fp_eval:n \fp_to_decimal:n
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp_sign:n}
+% Trivial but useful. See the implementation of \cs{fp_add:Nn} for an
+% explanation of why to use \cs{@@_parse:n}, namely, for better error
+% reporting.
+% \begin{macrocode}
+\cs_new:Npn \fp_sign:n #1
+ { \fp_to_decimal:n { sign \@@_parse:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\fp_abs:n}
+% Trivial but useful. See the implementation of \cs{fp_add:Nn} for an
+% explanation of why to use \cs{@@_parse:n}, namely, for better error
+% reporting.
+% \begin{macrocode}
+\cs_new:Npn \fp_abs:n #1
+ { \fp_to_decimal:n { abs \@@_parse:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\fp_max:nn, \fp_min:nn}
+% Similar to \cs{fp_abs:n}, for consistency with \cs{int_max:nn}, \emph{etc.}
+% \begin{macrocode}
+\cs_new:Npn \fp_max:nn #1#2
+ { \fp_to_decimal:n { max ( \@@_parse:n {#1} , \@@_parse:n {#2} ) } }
+\cs_new:Npn \fp_min:nn #1#2
+ { \fp_to_decimal:n { min ( \@@_parse:n {#1} , \@@_parse:n {#2} ) } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Convert an array of floating points to a comma list}
+%
+% \begin{macro}[EXP]{\@@_array_to_clist:n}
+% \begin{macro}[EXP]{\@@_array_to_clist_loop:Nw}
+% Converts an array of floating point numbers to a comma-list. If
+% speed here ends up irrelevant, we can simplify the code for the
+% auxiliary to become
+% \begin{verbatim}
+% \cs_new:Npn \__fp_array_to_clist_loop:Nw #1#2;
+% {
+% \use_none:n #1
+% { , ~ } \fp_to_tl:n { #1 #2 ; }
+% \__fp_array_to_clist_loop:Nw
+% }
+% \end{verbatim}
+% The \cs{use_ii:nn} function is expanded after \cs{@@_expand:n} is
+% done, and it removes |,~| from the start of the representation.
+% \begin{macrocode}
+\cs_new:Npn \@@_array_to_clist:n #1
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \exp_last_unbraced:Ne \use_ii:nn
+ {
+ \@@_array_to_clist_loop:Nw #1 { ? \prg_break: } ;
+ \prg_break_point:
+ }
+ }
+ }
+\cs_new:Npn \@@_array_to_clist_loop:Nw #1#2;
+ {
+ \use_none:n #1
+ , ~
+ \exp_not:f { \@@_to_tl_dispatch:w #1 #2 ; }
+ \@@_array_to_clist_loop:Nw
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintChanges
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-expo.dtx b/macros/latex-dev/required/l3kernel/l3fp-expo.dtx
new file mode 100644
index 0000000000..6fbc9de52c
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-expo.dtx
@@ -0,0 +1,1380 @@
+% \iffalse meta-comment
+%
+%% File: l3fp-expo.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-expo} module\\
+% Floating point exponential-related functions^^A
+% }
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp-expo} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_word_exp:N ,
+% \@@_parse_word_ln:N ,
+% \@@_parse_word_fact:N,
+% }
+% Unary functions.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_word_exp:N
+ { \@@_parse_unary_function:NNN \@@_exp_o:w ? }
+\cs_new:Npn \@@_parse_word_ln:N
+ { \@@_parse_unary_function:NNN \@@_ln_o:w ? }
+\cs_new:Npn \@@_parse_word_fact:N
+ { \@@_parse_unary_function:NNN \@@_fact_o:w ? }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Logarithm}
+%
+% \subsubsection{Work plan}
+%
+% As for many other functions, we filter out special cases in
+% \cs{@@_ln_o:w}. Then \cs{@@_ln_npos_o:w} receives a positive normal
+% number, which we write in the form $a\cdot 10^{b}$ with $a\in[0.1,1)$.
+%
+% \emph{The rest of this section is actually not in sync with the code.
+% Or is the code not in sync with the section? In the current code,
+% $c\in [1,10]$ is such that $0.7\leq ac < 1.4$.}
+%
+% We are given a positive normal number, of the form $a\cdot 10^{b}$
+% with $a\in[0.1,1)$. To compute its logarithm, we find a small integer
+% $5\leq c < 50$ such that $0.91 \leq a c / 5 < 1.1$, and use the
+% relation
+% \begin{equation*}
+% \ln (a \cdot 10^b) = b \cdot \ln (10) - \ln (c/5) + \ln (ac/5).
+% \end{equation*}
+% The logarithms $\ln(10)$ and $\ln(c/5)$ are looked up in a table. The
+% last term is computed using the following Taylor series of $\ln$ near
+% $1$:
+% \begin{equation*}
+% \ln\left(\frac{ac}{5}\right)
+% = \ln\left(\frac{1+t}{1-t}\right)
+% = 2t\left(1 + t^2 \left(\frac{1}{3} + t^2 \left(\frac{1}{5}
+% + t^2 \left(\frac{1}{7} + t^2 \left( \frac{1}{9} + \cdots
+% \right)\right)\right)\right)\right)
+% \end{equation*}
+% where $t=1-10/(ac+5)$. We can now see one reason for the choice of
+% $ac\sim 5$: then $ac+5=10(1-\epsilon)$ with $-0.05<\epsilon\leq
+% 0.045$, hence
+% \begin{equation*}
+% t = \frac{\epsilon}{1-\epsilon}
+% = \epsilon (1+\epsilon)(1+\epsilon^2)(1+\epsilon^4)\ldots,
+% \end{equation*}
+% is not too difficult to compute.
+%
+% \subsubsection{Some constants}
+%
+% \begin{variable}
+% {
+% \c_@@_ln_i_fixed_tl ,
+% \c_@@_ln_ii_fixed_tl ,
+% \c_@@_ln_iii_fixed_tl ,
+% \c_@@_ln_iv_fixed_tl ,
+% \c_@@_ln_vi_fixed_tl ,
+% \c_@@_ln_vii_fixed_tl ,
+% \c_@@_ln_viii_fixed_tl ,
+% \c_@@_ln_ix_fixed_tl ,
+% \c_@@_ln_x_fixed_tl,
+% }
+% A few values of the logarithm as extended fixed point numbers.
+% Those are needed in the implementation. It turns out that we don't
+% need the value of $\ln(5)$.
+% \begin{macrocode}
+\tl_const:Nn \c_@@_ln_i_fixed_tl { {0000}{0000}{0000}{0000}{0000}{0000};}
+\tl_const:Nn \c_@@_ln_ii_fixed_tl { {6931}{4718}{0559}{9453}{0941}{7232};}
+\tl_const:Nn \c_@@_ln_iii_fixed_tl {{10986}{1228}{8668}{1096}{9139}{5245};}
+\tl_const:Nn \c_@@_ln_iv_fixed_tl {{13862}{9436}{1119}{8906}{1883}{4464};}
+\tl_const:Nn \c_@@_ln_vi_fixed_tl {{17917}{5946}{9228}{0550}{0081}{2477};}
+\tl_const:Nn \c_@@_ln_vii_fixed_tl {{19459}{1014}{9055}{3133}{0510}{5353};}
+\tl_const:Nn \c_@@_ln_viii_fixed_tl{{20794}{4154}{1679}{8359}{2825}{1696};}
+\tl_const:Nn \c_@@_ln_ix_fixed_tl {{21972}{2457}{7336}{2193}{8279}{0490};}
+\tl_const:Nn \c_@@_ln_x_fixed_tl {{23025}{8509}{2994}{0456}{8401}{7991};}
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Sign, exponent, and special numbers}
+%
+% \begin{macro}[EXP]{\@@_ln_o:w}
+% The logarithm of negative numbers (including $-\infty$ and $-0$)
+% raises the \enquote{invalid} exception. The logarithm of $+0$ is
+% $-\infty$, raising a division by zero exception. The logarithm of
+% $+\infty$ or a \texttt{nan} is itself. Positive normal numbers call
+% \cs{@@_ln_npos_o:w}.
+% \begin{macrocode}
+\cs_new:Npn \@@_ln_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+ {
+ \if_meaning:w 2 #3
+ \@@_case_use:nw { \@@_invalid_operation_o:nw { ln } }
+ \fi:
+ \if_case:w #2 \exp_stop_f:
+ \@@_case_use:nw
+ { \@@_division_by_zero_o:Nnw \c_minus_inf_fp { ln } }
+ \or:
+ \else:
+ \@@_case_return_same_o:w
+ \fi:
+ \@@_ln_npos_o:w \s_@@ \@@_chk:w #2#3#4;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Absolute ln}
+%
+% \begin{macro}[EXP]{\@@_ln_npos_o:w}
+% We catch the case of a significand very close to $0.1$ or to $1$.
+% In all other cases, the final result is at least $10^{-4}$, and
+% then an error of $0.5\cdot 10^{-20}$ is acceptable.
+% \begin{macrocode}
+\cs_new:Npn \@@_ln_npos_o:w \s_@@ \@@_chk:w 10#1#2#3;
+ { %^^A todo: ln(1) should be "exact zero", not "underflow"
+ \exp_after:wN \@@_sanitize:Nw
+ \int_value:w % for the overall sign
+ \if_int_compare:w #1 < \c_one_int
+ 2
+ \else:
+ 0
+ \fi:
+ \exp_after:wN \exp_stop_f:
+ \int_value:w \@@_int_eval:w % for the exponent
+ \@@_ln_significand:NNNNnnnN #2#3
+ \@@_ln_exponent:wn {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_ln_significand:NNNNnnnN}
+% \begin{syntax}
+% \cs{@@_ln_significand:NNNNnnnN} \meta{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} \meta{continuation}
+% \end{syntax}
+% This function expands to
+% \begin{syntax}
+% \meta{continuation} \Arg{Y_1} \Arg{Y_2} \Arg{Y_3} \Arg{Y_4} \Arg{Y_5} \Arg{Y_6} |;|
+% \end{syntax}
+% where $Y = - \ln(X)$ as an extended fixed point.
+% \begin{macrocode}
+\cs_new:Npn \@@_ln_significand:NNNNnnnN #1#2#3#4
+ {
+ \exp_after:wN \@@_ln_x_ii:wnnnn
+ \int_value:w
+ \if_case:w #1 \exp_stop_f:
+ \or:
+ \if_int_compare:w #2 < 4 \exp_stop_f:
+ \@@_int_eval:w 10 - #2
+ \else:
+ 6
+ \fi:
+ \or: 4
+ \or: 3
+ \or: 2
+ \or: 2
+ \or: 2
+ \else: 1
+ \fi:
+ ; { #1 #2 #3 #4 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_ln_x_ii:wnnnn}
+% We have thus found $c \in [1,10]$ such that $0.7\leq ac < 1.4$
+% in all cases. Compute $ 1 + x = 1 + ac \in [1.7,2.4)$.
+% \begin{macrocode}
+\cs_new:Npn \@@_ln_x_ii:wnnnn #1; #2#3#4#5
+ {
+ \exp_after:wN \@@_ln_div_after:Nw
+ \cs:w c_@@_ln_ \@@_int_to_roman:w #1 _fixed_tl \exp_after:wN \cs_end:
+ \int_value:w
+ \exp_after:wN \@@_ln_x_iv:wnnnnnnnn
+ \int_value:w \@@_int_eval:w
+ \exp_after:wN \@@_ln_x_iii_var:NNNNNw
+ \int_value:w \@@_int_eval:w 9999 9990 + #1*#2#3 +
+ \exp_after:wN \@@_ln_x_iii:NNNNNNw
+ \int_value:w \@@_int_eval:w 10 0000 0000 + #1*#4#5 ;
+ {20000} {0000} {0000} {0000}
+ } %^^A todo: reoptimize (a generalization attempt failed).
+\cs_new:Npn \@@_ln_x_iii:NNNNNNw #1#2 #3#4#5#6 #7;
+ { #1#2; {#3#4#5#6} {#7} }
+\cs_new:Npn \@@_ln_x_iii_var:NNNNNw #1 #2#3#4#5 #6;
+ {
+ #1#2#3#4#5 + 1 ;
+ {#1#2#3#4#5} {#6}
+ }
+% \end{macrocode}
+% The Taylor series to be used is expressed in terms of
+% $t = (x-1)/(x+1) = 1 - 2/(x+1)$. We now compute the
+% quotient with extended precision, reusing some code
+% from \cs{@@_/_o:ww}. Note that $1+x$ is known exactly.
+%
+% To reuse notations from \pkg{l3fp-basics}, we want to
+% compute $ A / Z $ with $ A = 2 $ and $ Z = x + 1 $.
+% In \pkg{l3fp-basics}, we considered the case where
+% both $A$ and $Z$ are arbitrary, in the range $[0.1,1)$,
+% and we had to monitor the growth of the sequence of
+% remainders $A$, $B$, $C$, etc. to ensure that no overflow
+% occurred during the computation of the next quotient.
+% The main source of risk was our choice to define the
+% quotient as roughly $10^9 \cdot A / 10^5 \cdot Z$: then
+% $A$ was bound to be below $2.147\cdots$, and this limit
+% was never far.
+%
+% In our case, we can simply work with $10^8 \cdot A$ and
+% $10^4 \cdot Z$, because our reason to work with higher
+% powers has gone: we needed the integer $y \simeq 10^5 \cdot Z$
+% to be at least $10^4$, and now, the definition
+% $y \simeq 10^4 \cdot Z$ suffices.
+%
+% Let us thus define $y = \left\lfloor 10^4 \cdot Z \right\rfloor + 1
+% \in ( 1.7 \cdot 10^4, 2.4 \cdot 10^4 ] $, and
+% \[
+% Q_{1}
+% =
+% \left\lfloor
+% \frac {\left\lfloor 10^8 \cdot A\right\rfloor} {y} - \frac{1}{2}
+% \right\rfloor.
+% \]
+% (The $1/2$ comes from how \eTeX{} rounds.) As for division, it is
+% easy to see that $Q_{1} \leq 10^4 A / Z$, \emph{i.e.}, $Q_{1}$
+% is an underestimate.
+%
+% Exactly as we did for division, we set $B = 10^4 A - Q_{1}Z$. Then
+% \begin{align*}
+% 10^4 B
+% & \leq
+% A_{1}A_{2}.A_{3}A_{4}
+% - \left( \frac{A_{1}A_{2}}{y} - \frac{3}{2} \right) 10^4 Z
+% \\
+% & \leq
+% A_{1}A_{2} \left( 1 - \frac{10^4 Z}{y} \right) + 1 + \frac{3}{2} y
+% \\
+% & \leq
+% 10^8 \frac{A}{y} + 1 + \frac{3}{2} y
+% \end{align*}
+% In the same way, and using $1.7\cdot 10^4\leq y\leq 2.4\cdot 10^4$,
+% and convexity, we get
+% \begin{align*}
+% 10^4 A &= 2\cdot 10^4 \\
+% 10^4 B &\leq 10^8 \frac{A}{y} + 1.6 y \leq 4.7\cdot 10^4\\
+% 10^4 C &\leq 10^8 \frac{B}{y} + 1.6 y \leq 5.8\cdot 10^4\\
+% 10^4 D &\leq 10^8 \frac{C}{y} + 1.6 y \leq 6.3\cdot 10^4\\
+% 10^4 E &\leq 10^8 \frac{D}{y} + 1.6 y \leq 6.5\cdot 10^4\\
+% 10^4 F &\leq 10^8 \frac{E}{y} + 1.6 y \leq 6.6\cdot 10^4\\
+% \end{align*}
+% Note that we compute more steps than for division: since $t$ is
+% not the end result, we need to know it with more accuracy
+% (on the other hand, the ending is much simpler, as we don't
+% need an exact rounding for transcendental functions, but just
+% a faithful rounding).
+% ^^A todo: doc
+%
+% \begin{syntax}
+% \cs{@@_ln_x_iv:wnnnnnnnn} \meta{1 or 2} \meta{8d} |;| \Arg{4d} \Arg{4d} \meta{fixed-tl}
+% \end{syntax}
+% The number is $x$. Compute $y$ by adding 1 to the five first digits.
+% \begin{macrocode}
+\cs_new:Npn \@@_ln_x_iv:wnnnnnnnn #1; #2#3#4#5 #6#7#8#9
+ {
+ \exp_after:wN \@@_div_significand_pack:NNN
+ \int_value:w \@@_int_eval:w
+ \@@_ln_div_i:w #1 ;
+ #6 #7 ; {#8} {#9}
+ {#2} {#3} {#4} {#5}
+ { \exp_after:wN \@@_ln_div_ii:wwn \int_value:w #1 }
+ { \exp_after:wN \@@_ln_div_ii:wwn \int_value:w #1 }
+ { \exp_after:wN \@@_ln_div_ii:wwn \int_value:w #1 }
+ { \exp_after:wN \@@_ln_div_ii:wwn \int_value:w #1 }
+ { \exp_after:wN \@@_ln_div_vi:wwn \int_value:w #1 }
+ }
+\cs_new:Npn \@@_ln_div_i:w #1;
+ {
+ \exp_after:wN \@@_div_significand_calc:wwnnnnnnn
+ \int_value:w \@@_int_eval:w 999999 + 2 0000 0000 / #1 ; % Q1
+ }
+\cs_new:Npn \@@_ln_div_ii:wwn #1; #2;#3 % y; B1;B2 <- for k=1
+ {
+ \exp_after:wN \@@_div_significand_pack:NNN
+ \int_value:w \@@_int_eval:w
+ \exp_after:wN \@@_div_significand_calc:wwnnnnnnn
+ \int_value:w \@@_int_eval:w 999999 + #2 #3 / #1 ; % Q2
+ #2 #3 ;
+ }
+\cs_new:Npn \@@_ln_div_vi:wwn #1; #2;#3#4#5 #6#7#8#9 %y;F1;F2F3F4x1x2x3x4
+ {
+ \exp_after:wN \@@_div_significand_pack:NNN
+ \int_value:w \@@_int_eval:w 1000000 + #2 #3 / #1 ; % Q6
+ }
+% \end{macrocode}
+% We now have essentially
+% ^^A todo: determine error on $Q_{6}$ (probably $6.7$),
+% ^^A todo: conclude the final result is off by $<10^{-23}$
+% \begin{syntax}
+% \cs{@@_ln_div_after:Nw} \meta{fixed tl}
+% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{1}$
+% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{2}$
+% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{3}$
+% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{4}$
+% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{5}$
+% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{6}$ |;|
+% \meta{exponent} |;| \meta{continuation}
+% \end{syntax}
+% where \meta{fixed tl} holds the logarithm of a number
+% in $[1,10]$, and \meta{exponent} is
+% the exponent. Also, the expansion is done backwards. Then
+% \cs{@@_div_significand_pack:NNN} puts things in the
+% correct order to add the $Q_{i}$ together and put semicolons
+% between each piece. Once those have been expanded, we get
+% \begin{syntax}
+% \cs{@@_ln_div_after:Nw} \meta{fixed-tl} \meta{1d} |;| \meta{4d} |;| \meta{4d} |;|
+% ~~\meta{4d} |;| \meta{4d} |;| \meta{4d} |;| \meta{4d} |;| \meta{exponent} |;|
+% \end{syntax}
+% ^^A todo: redoc.
+% Just as with division, we know that the first two digits
+% are |1| and |0| because of bounds on the final result of
+% the division $2/(x+1)$, which is between roughly $0.8$ and $1.2$.
+% We then compute $1-2/(x+1)$, after testing whether $2/(x+1)$ is
+% greater than or smaller than $1$.
+% \begin{macrocode}
+\cs_new:Npn \@@_ln_div_after:Nw #1#2;
+ {
+ \if_meaning:w 0 #2
+ \exp_after:wN \@@_ln_t_small:Nw
+ \else:
+ \exp_after:wN \@@_ln_t_large:NNw
+ \exp_after:wN -
+ \fi:
+ #1
+ }
+\cs_new:Npn \@@_ln_t_small:Nw #1 #2; #3; #4; #5; #6; #7;
+ {
+ \exp_after:wN \@@_ln_t_large:NNw
+ \exp_after:wN + % <sign>
+ \exp_after:wN #1
+ \int_value:w \@@_int_eval:w 9999 - #2 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w 9999 - #3 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w 9999 - #4 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w 9999 - #5 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w 9999 - #6 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w 1 0000 - #7 ;
+ }
+% \end{macrocode}
+%
+% \begin{syntax}
+% \cs{@@_ln_t_large:NNw} \meta{sign} \meta{fixed tl}
+% ~~\meta{t_1}|;| \meta{t_2} |;| \meta{t_3}|;| \meta{t_4}|;| \meta{t_5} |;| \meta{t_6}|;|
+% ~~\meta{exponent} |;| \meta{continuation}
+% \end{syntax}
+% Compute the square $|t|^2$, and keep $|t|$ at the end with its
+% sign. We know that $|t|<0.1765$, so every piece has at most $4$
+% digits. However, since we were not careful in \cs{@@_ln_t_small:w},
+% they can have less than $4$ digits.
+% \begin{macrocode}
+\cs_new:Npn \@@_ln_t_large:NNw #1 #2 #3; #4; #5; #6; #7; #8;
+ {
+ \exp_after:wN \@@_ln_square_t_after:w
+ \int_value:w \@@_int_eval:w 9999 0000 + #3*#3
+ \exp_after:wN \@@_ln_square_t_pack:NNNNNw
+ \int_value:w \@@_int_eval:w 9999 0000 + 2*#3*#4
+ \exp_after:wN \@@_ln_square_t_pack:NNNNNw
+ \int_value:w \@@_int_eval:w 9999 0000 + 2*#3*#5 + #4*#4
+ \exp_after:wN \@@_ln_square_t_pack:NNNNNw
+ \int_value:w \@@_int_eval:w 9999 0000 + 2*#3*#6 + 2*#4*#5
+ \exp_after:wN \@@_ln_square_t_pack:NNNNNw
+ \int_value:w \@@_int_eval:w
+ 1 0000 0000 + 2*#3*#7 + 2*#4*#6 + #5*#5
+ + (2*#3*#8 + 2*#4*#7 + 2*#5*#6) / 1 0000
+ % ; ; ;
+ \exp_after:wN \@@_ln_twice_t_after:w
+ \int_value:w \@@_int_eval:w -1 + 2*#3
+ \exp_after:wN \@@_ln_twice_t_pack:Nw
+ \int_value:w \@@_int_eval:w 9999 + 2*#4
+ \exp_after:wN \@@_ln_twice_t_pack:Nw
+ \int_value:w \@@_int_eval:w 9999 + 2*#5
+ \exp_after:wN \@@_ln_twice_t_pack:Nw
+ \int_value:w \@@_int_eval:w 9999 + 2*#6
+ \exp_after:wN \@@_ln_twice_t_pack:Nw
+ \int_value:w \@@_int_eval:w 9999 + 2*#7
+ \exp_after:wN \@@_ln_twice_t_pack:Nw
+ \int_value:w \@@_int_eval:w 10000 + 2*#8 ; ;
+ { \@@_ln_c:NwNw #1 }
+ #2
+ }
+\cs_new:Npn \@@_ln_twice_t_pack:Nw #1 #2; { + #1 ; {#2} }
+\cs_new:Npn \@@_ln_twice_t_after:w #1; { ;;; {#1} }
+\cs_new:Npn \@@_ln_square_t_pack:NNNNNw #1 #2#3#4#5 #6;
+ { + #1#2#3#4#5 ; {#6} }
+\cs_new:Npn \@@_ln_square_t_after:w 1 0 #1#2#3 #4;
+ { \@@_ln_Taylor:wwNw {0#1#2#3} {#4} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_ln_Taylor:wwNw}
+% Denoting $T=t^2$, we get
+% \begin{syntax}
+% \cs{@@_ln_Taylor:wwNw}
+% ~~\Arg{T_1} \Arg{T_2} \Arg{T_3} \Arg{T_4} \Arg{T_5} \Arg{T_6} |;| |;|
+% ~~\Arg{(2t)_1} \Arg{(2t)_2} \Arg{(2t)_3} \Arg{(2t)_4} \Arg{(2t)_5} \Arg{(2t)_6} |;|
+% ~~|{| \cs{@@_ln_c:NwNw} \meta{sign} |}|
+% ~~\meta{fixed tl} \meta{exponent} |;| \meta{continuation}
+% \end{syntax}
+% And we want to compute
+% \[
+% \ln\left(\frac{1+t}{1-t}\right)
+% = 2t\left(1 + T \left(\frac{1}{3} + T \left(\frac{1}{5}
+% + T \left(\frac{1}{7} + T \left( \frac{1}{9} + \cdots
+% \right)\right)\right)\right)\right)
+% \]
+% The process looks as follows
+% \begin{verbatim}
+% \loop 5; A;
+% \div_int 5; 1.0; \add A; \mul T; {\loop \eval 5-2;}
+% \add 0.2; A; \mul T; {\loop \eval 5-2;}
+% \mul B; T; {\loop 3;}
+% \loop 3; C;
+% \end{verbatim}
+% ^^A todo: doc
+%
+% This uses the routine for dividing a number by a small integer
+% (${}<10^4$).
+% \begin{macrocode}
+\cs_new:Npn \@@_ln_Taylor:wwNw
+ { \@@_ln_Taylor_loop:www 21 ; {0000}{0000}{0000}{0000}{0000}{0000} ; }
+\cs_new:Npn \@@_ln_Taylor_loop:www #1; #2; #3;
+ {
+ \if_int_compare:w #1 = \c_one_int
+ \@@_ln_Taylor_break:w
+ \fi:
+ \exp_after:wN \@@_fixed_div_int:wwN \c_@@_one_fixed_tl #1;
+ \@@_fixed_add:wwn #2;
+ \@@_fixed_mul:wwn #3;
+ {
+ \exp_after:wN \@@_ln_Taylor_loop:www
+ \int_value:w \@@_int_eval:w #1 - 2 ;
+ }
+ #3;
+ }
+\cs_new:Npn \@@_ln_Taylor_break:w \fi: #1 \@@_fixed_add:wwn #2#3; #4 ;;
+ {
+ \fi:
+ \exp_after:wN \@@_fixed_mul:wwn
+ \exp_after:wN { \int_value:w \@@_int_eval:w 10000 + #2 } #3;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_ln_c:NwNw}
+% \begin{syntax}
+% \cs{@@_ln_c:NwNw} \meta{sign}
+% ~~\Arg{r_1} \Arg{r_2} \Arg{r_3} \Arg{r_4} \Arg{r_5} \Arg{r_6} |;|
+% ~~\meta{fixed tl} \meta{exponent} |;| \meta{continuation}
+% \end{syntax}
+% We are now reduced to finding $\ln(c)$ and $\meta{exponent}\ln(10)$
+% in a table, and adding it to the mixture. The first step is to
+% get $\ln(c) - \ln(x) = - \ln(a)$, then we get $|b|\ln(10)$ and add
+% or subtract.
+%
+% For now, $\ln(x)$ is given as $\cdot 10^0$. Unless both the exponent
+% is $1$ and $c=1$, we shift to working in units of $\cdot 10^4$,
+% since the final result is at least $\ln(10/7) \simeq 0.35$.
+% \begin{macrocode}
+\cs_new:Npn \@@_ln_c:NwNw #1 #2; #3
+ {
+ \if_meaning:w + #1
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_fixed_sub:wwn
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_fixed_add:wwn
+ \fi:
+ #3 #2 ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_ln_exponent:wn}
+% \begin{syntax}
+% \cs{@@_ln_exponent:wn}
+% ~~\Arg{s_1} \Arg{s_2} \Arg{s_3} \Arg{s_4} \Arg{s_5} \Arg{s_6} |;|
+% ~~\Arg{exponent}
+% \end{syntax}
+% Compute \meta{exponent} times $\ln(10)$. Apart from the cases where
+% \meta{exponent} is $0$ or $1$, the result is necessarily at
+% least $\ln(10) \simeq 2.3$ in magnitude. We can thus drop the least
+% significant $4$ digits. In the case of a very large (positive or
+% negative) exponent, we can (and we need to) drop $4$ additional
+% digits, since the result is of order $10^4$. Naively, one would
+% think that in both cases we can drop $4$ more digits than we do,
+% but that would be slightly too tight for rounding to happen correctly.
+% Besides, we already have addition and subtraction for $24$ digits
+% fixed point numbers.
+% \begin{macrocode}
+\cs_new:Npn \@@_ln_exponent:wn #1; #2
+ {
+ \if_case:w #2 \exp_stop_f:
+ 0 \@@_case_return:nw { \@@_fixed_to_float_o:Nw 2 }
+ \or:
+ \exp_after:wN \@@_ln_exponent_one:ww \int_value:w
+ \else:
+ \if_int_compare:w #2 > \c_zero_int
+ \exp_after:wN \@@_ln_exponent_small:NNww
+ \exp_after:wN 0
+ \exp_after:wN \@@_fixed_sub:wwn \int_value:w
+ \else:
+ \exp_after:wN \@@_ln_exponent_small:NNww
+ \exp_after:wN 2
+ \exp_after:wN \@@_fixed_add:wwn \int_value:w -
+ \fi:
+ \fi:
+ #2; #1;
+ }
+% \end{macrocode}
+% Now we painfully write all the cases.\footnote{Bruno: do rounding.}
+% No overflow nor underflow can happen, except when computing \texttt{ln(1)}.
+% \begin{macrocode}
+\cs_new:Npn \@@_ln_exponent_one:ww 1; #1;
+ {
+ 0
+ \exp_after:wN \@@_fixed_sub:wwn \c_@@_ln_x_fixed_tl #1;
+ \@@_fixed_to_float_o:wN 0
+ }
+% \end{macrocode}
+% For small exponents, we just drop one block of digits, and set the
+% exponent of the log to $4$ (minus any shift coming from leading zeros
+% in the conversion from fixed point to floating point). Note that here
+% the exponent has been made positive.
+% \begin{macrocode}
+\cs_new:Npn \@@_ln_exponent_small:NNww #1#2#3; #4#5#6#7#8#9;
+ {
+ 4
+ \exp_after:wN \@@_fixed_mul:wwn
+ \c_@@_ln_x_fixed_tl
+ {#3}{0000}{0000}{0000}{0000}{0000} ;
+ #2
+ {0000}{#4}{#5}{#6}{#7}{#8};
+ \@@_fixed_to_float_o:wN #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Exponential}
+%
+% \subsubsection{Sign, exponent, and special numbers}
+%
+% \begin{macro}[EXP]{\@@_exp_o:w}
+% \begin{macrocode}
+\cs_new:Npn \@@_exp_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+ {
+ \if_case:w #2 \exp_stop_f:
+ \@@_case_return_o:Nw \c_one_fp
+ \or:
+ \exp_after:wN \@@_exp_normal_o:w
+ \or:
+ \if_meaning:w 0 #3
+ \exp_after:wN \@@_case_return_o:Nw
+ \exp_after:wN \c_inf_fp
+ \else:
+ \exp_after:wN \@@_case_return_o:Nw
+ \exp_after:wN \c_zero_fp
+ \fi:
+ \or:
+ \@@_case_return_same_o:w
+ \fi:
+ \s_@@ \@@_chk:w #2#3#4;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_exp_normal_o:w, \@@_exp_pos_o:Nnwnw, \@@_exp_overflow:NN}
+% \begin{macrocode}
+\cs_new:Npn \@@_exp_normal_o:w \s_@@ \@@_chk:w 1#1
+ {
+ \if_meaning:w 0 #1
+ \@@_exp_pos_o:NNwnw + \@@_fixed_to_float_o:wN
+ \else:
+ \@@_exp_pos_o:NNwnw - \@@_fixed_inv_to_float_o:wN
+ \fi:
+ }
+\cs_new:Npn \@@_exp_pos_o:NNwnw #1#2#3 \fi: #4#5;
+ {
+ \fi:
+ \if_int_compare:w #4 > \c_@@_max_exp_exponent_int
+ \token_if_eq_charcode:NNTF + #1
+ { \@@_exp_overflow:NN \@@_overflow:w \c_inf_fp }
+ { \@@_exp_overflow:NN \@@_underflow:w \c_zero_fp }
+ \exp:w
+ \else:
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN 0
+ \int_value:w #1 \@@_int_eval:w
+ \if_int_compare:w #4 < \c_zero_int
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ 0
+ \@@_decimate:nNnnnn { - #4 }
+ \@@_exp_Taylor:Nnnwn
+ }
+ {
+ \@@_decimate:nNnnnn { \c_@@_prec_int - #4 }
+ \@@_exp_pos_large:NnnNwn
+ }
+ #5
+ {#4}
+ #1 #2 0
+ \exp:w
+ \fi:
+ \exp_after:wN \exp_end:
+ }
+\cs_new:Npn \@@_exp_overflow:NN #1#2
+ {
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN #1
+ \exp_after:wN #2
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_exp_Taylor:Nnnwn}
+% \begin{macro}[EXP]{\@@_exp_Taylor_loop:www, \@@_exp_Taylor_break:Nww}
+% This function is called for numbers in the range $[10^{-9},
+% 10^{-1})$. We compute $10$ terms of the Taylor series. The
+% first argument is irrelevant (rounding digit used by some other
+% functions). The next three arguments, at least $16$ digits,
+% delimited by a semicolon, form a fixed point number, so we pack it
+% in blocks of $4$ digits.
+% \begin{macrocode}
+\cs_new:Npn \@@_exp_Taylor:Nnnwn #1#2#3 #4; #5 #6
+ {
+ #6
+ \@@_pack_twice_four:wNNNNNNNN
+ \@@_pack_twice_four:wNNNNNNNN
+ \@@_pack_twice_four:wNNNNNNNN
+ \@@_exp_Taylor_ii:ww
+ ; #2#3#4 0000 0000 ;
+ }
+\cs_new:Npn \@@_exp_Taylor_ii:ww #1; #2;
+ { \@@_exp_Taylor_loop:www 10 ; #1 ; #1 ; \s_@@_stop }
+\cs_new:Npn \@@_exp_Taylor_loop:www #1; #2; #3;
+ {
+ \if_int_compare:w #1 = \c_one_int
+ \exp_after:wN \@@_exp_Taylor_break:Nww
+ \fi:
+ \@@_fixed_div_int:wwN #3 ; #1 ;
+ \@@_fixed_add_one:wN
+ \@@_fixed_mul:wwn #2 ;
+ {
+ \exp_after:wN \@@_exp_Taylor_loop:www
+ \int_value:w \@@_int_eval:w #1 - 1 ;
+ #2 ;
+ }
+ }
+\cs_new:Npn \@@_exp_Taylor_break:Nww #1 #2; #3 \s_@@_stop
+ { \@@_fixed_add_one:wN #2 ; }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\c_@@_exp_intarray}
+% The integer array has $6\times 9\times 4=216$ items encoding the
+% values of $\exp(j\times 10^i)$ for $j=1,\dots,9$ and $i=-1,\dots,4$.
+% Each value is expressed as $\simeq 10^p \times 0.m_1m_2m_3$ with
+% three $8$-digit blocks $m_1$, $m_2$, $m_3$ and an integer
+% exponent~$p$ (one more than the scientific exponent), and these are
+% stored in the integer array as four items: $p$, $10^8+m_1$,
+% $10^8+m_2$, $10^8+m_3$. The various exponentials are stored in
+% increasing order of $j\times 10^i$.
+%
+% Storing this data in an integer array makes it slightly harder to
+% access (slower, too), but uses $16$ bytes of memory per exponential
+% stored, while storing as tokens used around $40$ tokens; tokens have
+% an especially large footprint in Unicode-aware engines.
+% \begin{macrocode}
+\intarray_const_from_clist:Nn \c_@@_exp_intarray
+ {
+ 1 , 1 1105 1709 , 1 1807 5647 , 1 6248 1171 ,
+ 1 , 1 1221 4027 , 1 5816 0169 , 1 8339 2107 ,
+ 1 , 1 1349 8588 , 1 0757 6003 , 1 1039 8374 ,
+ 1 , 1 1491 8246 , 1 9764 1270 , 1 3178 2485 ,
+ 1 , 1 1648 7212 , 1 7070 0128 , 1 1468 4865 ,
+ 1 , 1 1822 1188 , 1 0039 0508 , 1 9748 7537 ,
+ 1 , 1 2013 7527 , 1 0747 0476 , 1 5216 2455 ,
+ 1 , 1 2225 5409 , 1 2849 2467 , 1 6045 7954 ,
+ 1 , 1 2459 6031 , 1 1115 6949 , 1 6638 0013 ,
+ 1 , 1 2718 2818 , 1 2845 9045 , 1 2353 6029 ,
+ 1 , 1 7389 0560 , 1 9893 0650 , 1 2272 3043 ,
+ 2 , 1 2008 5536 , 1 9231 8766 , 1 7740 9285 ,
+ 2 , 1 5459 8150 , 1 0331 4423 , 1 9078 1103 ,
+ 3 , 1 1484 1315 , 1 9102 5766 , 1 0342 1116 ,
+ 3 , 1 4034 2879 , 1 3492 7351 , 1 2260 8387 ,
+ 4 , 1 1096 6331 , 1 5842 8458 , 1 5992 6372 ,
+ 4 , 1 2980 9579 , 1 8704 1728 , 1 2747 4359 ,
+ 4 , 1 8103 0839 , 1 2757 5384 , 1 0077 1000 ,
+ 5 , 1 2202 6465 , 1 7948 0671 , 1 6516 9579 ,
+ 9 , 1 4851 6519 , 1 5409 7902 , 1 7796 9107 ,
+ 14 , 1 1068 6474 , 1 5815 2446 , 1 2146 9905 ,
+ 18 , 1 2353 8526 , 1 6837 0199 , 1 8540 7900 ,
+ 22 , 1 5184 7055 , 1 2858 7072 , 1 4640 8745 ,
+ 27 , 1 1142 0073 , 1 8981 5684 , 1 2836 6296 ,
+ 31 , 1 2515 4386 , 1 7091 9167 , 1 0062 6578 ,
+ 35 , 1 5540 6223 , 1 8439 3510 , 1 0525 7117 ,
+ 40 , 1 1220 4032 , 1 9431 7840 , 1 8020 0271 ,
+ 44 , 1 2688 1171 , 1 4181 6135 , 1 4484 1263 ,
+ 87 , 1 7225 9737 , 1 6812 5749 , 1 2581 7748 ,
+ 131 , 1 1942 4263 , 1 9524 1255 , 1 9365 8421 ,
+ 174 , 1 5221 4696 , 1 8976 4143 , 1 9505 8876 ,
+ 218 , 1 1403 5922 , 1 1785 2837 , 1 4107 3977 ,
+ 261 , 1 3773 0203 , 1 0092 9939 , 1 8234 0143 ,
+ 305 , 1 1014 2320 , 1 5473 5004 , 1 5094 5533 ,
+ 348 , 1 2726 3745 , 1 7211 2566 , 1 5673 6478 ,
+ 391 , 1 7328 8142 , 1 2230 7421 , 1 7051 8866 ,
+ 435 , 1 1970 0711 , 1 1401 7046 , 1 9938 8888 ,
+ 869 , 1 3881 1801 , 1 9428 4368 , 1 5764 8232 ,
+ 1303 , 1 7646 2009 , 1 8905 4704 , 1 8893 1073 ,
+ 1738 , 1 1506 3559 , 1 7005 0524 , 1 9009 7592 ,
+ 2172 , 1 2967 6283 , 1 8402 3667 , 1 0689 6630 ,
+ 2606 , 1 5846 4389 , 1 5650 2114 , 1 7278 5046 ,
+ 3041 , 1 1151 7900 , 1 5080 6878 , 1 2914 4154 ,
+ 3475 , 1 2269 1083 , 1 0850 6857 , 1 8724 4002 ,
+ 3909 , 1 4470 3047 , 1 3316 5442 , 1 6408 6591 ,
+ 4343 , 1 8806 8182 , 1 2566 2921 , 1 5872 6150 ,
+ 8686 , 1 7756 0047 , 1 2598 6861 , 1 0458 3204 ,
+ 13029 , 1 6830 5723 , 1 7791 4884 , 1 1932 7351 ,
+ 17372 , 1 6015 5609 , 1 3095 3052 , 1 3494 7574 ,
+ 21715 , 1 5297 7951 , 1 6443 0315 , 1 3251 3576 ,
+ 26058 , 1 4665 6719 , 1 0099 3379 , 1 5527 2929 ,
+ 30401 , 1 4108 9724 , 1 3326 3186 , 1 5271 5665 ,
+ 34744 , 1 3618 6973 , 1 3140 0875 , 1 3856 4102 ,
+ 39087 , 1 3186 9209 , 1 6113 3900 , 1 6705 9685 ,
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[rEXP]
+% {
+% \@@_exp_pos_large:NnnNwn ,
+% \@@_exp_large_after:wwn ,
+% \@@_exp_large:NwN ,
+% \@@_exp_intarray:w ,
+% \@@_exp_intarray_aux:w ,
+% }
+% The first two arguments are irrelevant (a rounding digit, and a
+% brace group with $8$ zeros). The third argument is the integer part
+% of our number, then we have the decimal part delimited by a
+% semicolon, and finally the exponent, in the range $[0,5]$. Remove
+% leading zeros from the integer part: putting |#4| in there too
+% ensures that an integer part of $0$ is also removed. Then read
+% digits one by one, looking up $\exp(\meta{digit}\cdot
+% 10^{\meta{exponent}})$ in a table, and multiplying that to the
+% current total. The loop is done by \cs{@@_exp_large:NwN}, whose
+% |#1| is the \meta{exponent}, |#2| is the current mantissa, and |#3|
+% is the \meta{digit}. At the end, \cs{@@_exp_large_after:wwn} moves
+% on to the Taylor series, eventually multiplied with the mantissa
+% that we have just computed.
+% \begin{macrocode}
+\cs_new:Npn \@@_exp_pos_large:NnnNwn #1#2#3 #4#5; #6
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_exp_large:NwN
+ \exp_after:wN \exp_after:wN \exp_after:wN #6
+ \exp_after:wN \c_@@_one_fixed_tl
+ \int_value:w #3 #4 \exp_stop_f:
+ #5 00000 ;
+ }
+\cs_new:Npn \@@_exp_large:NwN #1#2; #3
+ {
+ \if_case:w #3 ~
+ \exp_after:wN \@@_fixed_continue:wn
+ \else:
+ \exp_after:wN \@@_exp_intarray:w
+ \int_value:w \@@_int_eval:w 36 * #1 + 4 * #3 \exp_after:wN ;
+ \fi:
+ #2;
+ {
+ \if_meaning:w 0 #1
+ \exp_after:wN \@@_exp_large_after:wwn
+ \else:
+ \exp_after:wN \@@_exp_large:NwN
+ \int_value:w \@@_int_eval:w #1 - 1 \exp_after:wN \scan_stop:
+ \fi:
+ }
+ }
+\cs_new:Npn \@@_exp_intarray:w #1 ;
+ {
+ +
+ \__kernel_intarray_item:Nn \c_@@_exp_intarray
+ { \@@_int_eval:w #1 - 3 \scan_stop: }
+ \exp_after:wN \use_i:nnn
+ \exp_after:wN \@@_fixed_mul:wwn
+ \int_value:w 0
+ \exp_after:wN \@@_exp_intarray_aux:w
+ \int_value:w \__kernel_intarray_item:Nn
+ \c_@@_exp_intarray { \@@_int_eval:w #1 - 2 }
+ \exp_after:wN \@@_exp_intarray_aux:w
+ \int_value:w \__kernel_intarray_item:Nn
+ \c_@@_exp_intarray { \@@_int_eval:w #1 - 1 }
+ \exp_after:wN \@@_exp_intarray_aux:w
+ \int_value:w \__kernel_intarray_item:Nn \c_@@_exp_intarray {#1} ; ;
+ }
+\cs_new:Npn \@@_exp_intarray_aux:w 1 #1#2#3#4#5 ; { ; {#1#2#3#4} {#5} }
+\cs_new:Npn \@@_exp_large_after:wwn #1; #2; #3
+ {
+ \@@_exp_Taylor:Nnnwn ? { } { } 0 #2; {} #3
+ \@@_fixed_mul:wwn #1;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Power}
+%
+% Raising a number $a$ to a power $b$ leads to many distinct situations.
+% \begin{center}\def\abs#1{\lvert #1\rvert}
+% \begin{tabular}{>{$}c<{$}|*8{>{$}l<{$}}}
+% a^b &-\infty &(-\infty,-0) &-\text{integer} &\pm 0 &+\text{integer} &(0,\infty) &+\infty &\nan \\ \hline
+% +\infty &+0 &\multicolumn{2}{c}{$+0$} &+1 &\multicolumn{2}{c}{$+\infty$} &+\infty &\nan \\
+% (1,\infty) &+0 &\multicolumn{2}{c}{$+\abs{a}^{b}$} &+1 &\multicolumn{2}{c}{$+\abs{a}^{b}$} &+\infty &\nan \\
+% +1 &+1 &\multicolumn{2}{c}{$+1$} &+1 &\multicolumn{2}{c}{$+1$} &+1 &+1 \\
+% (0,1) &+\infty &\multicolumn{2}{c}{$+\abs{a}^{b}$} &+1 &\multicolumn{2}{c}{$+\abs{a}^{b}$} &+0 &\nan \\
+% +0 &+\infty &\multicolumn{2}{c}{$+\infty$} &+1 &\multicolumn{2}{c}{$+0$} &+0 &\nan \\
+% -0 &+\infty &\nan &(-1)^b\infty &+1 &(-1)^b 0 &+0 &+0 &\nan \\
+% (-1,0) &+\infty &\nan &(-1)^b\abs{a}^{b} &+1 &(-1)^b\abs{a}^{b} &\nan &+0 &\nan \\
+% -1 &+1 &\nan &(-1)^b &+1 &(-1)^b &\nan &+1 &\nan \\
+% (-\infty,-1) &+0 &\nan &(-1)^b\abs{a}^{b} &+1 &(-1)^b\abs{a}^{b} &\nan &+\infty &\nan \\
+% -\infty &+0 &+0 &(-1)^b 0 &+1 &(-1)^b\infty &\nan &+\infty &\nan \\
+% \nan &\nan &\nan &\nan &+1 &\nan &\nan &\nan &\nan \\
+% \end{tabular}
+% \end{center}
+% We distinguished in this table the cases of finite (positive or
+% negative) integer exponents, as $(-1)^b$ is defined in that case.
+% One peculiarity of this operation is that $\nan^0 = 1^\nan = 1$,
+% because this relation is obeyed for any number, even $\pm\infty$.
+%
+% \begin{macro}[EXP]+\@@_^_o:ww+
+% We cram most of the tests into a single function to save csnames.
+% First treat the case $b=0$: $a^0=1$ for any $a$, even \texttt{nan}.
+% Then test the sign of $a$.
+% \begin{itemize}
+% \item If it is positive, and $a$ is a normal number, call
+% \cs{@@_pow_normal_o:ww} followed by the two \texttt{fp} $a$ and $b$.
+% For $a=+0$ or $+\inf$, call \cs{@@_pow_zero_or_inf:ww} instead, to
+% return either $+0$ or $+\infty$ as appropriate.
+% \item If $a$ is a \texttt{nan}, then skip to the next semicolon
+% (which happens to be conveniently the end of $b$) and return
+% \texttt{nan}.
+% \item Finally, if $a$ is negative, compute $|a|^b$
+% (\cs{@@_pow_normal_o:ww} which ignores the sign of its first
+% operand), and keep an extra copy of $a$ and $b$ (the second brace
+% group, containing \{~$b$~$a$~\}, is inserted between $a$ and $b$).
+% Then do some tests to find the final sign of the result if it
+% exists.
+% \end{itemize}
+% \begin{macrocode}
+\cs_new:cpn { @@_ \iow_char:N \^ _o:ww }
+ \s_@@ \@@_chk:w #1#2#3; \s_@@ \@@_chk:w #4#5#6;
+ {
+ \if_meaning:w 0 #4
+ \@@_case_return_o:Nw \c_one_fp
+ \fi:
+ \if_case:w #2 \exp_stop_f:
+ \exp_after:wN \use_i:nn
+ \or:
+ \@@_case_return_o:Nw \c_nan_fp
+ \else:
+ \exp_after:wN \@@_pow_neg:www
+ \exp:w \exp_end_continue_f:w \exp_after:wN \use:nn
+ \fi:
+ {
+ \if_meaning:w 1 #1
+ \exp_after:wN \@@_pow_normal_o:ww
+ \else:
+ \exp_after:wN \@@_pow_zero_or_inf:ww
+ \fi:
+ \s_@@ \@@_chk:w #1#2#3;
+ }
+ { \s_@@ \@@_chk:w #4#5#6; \s_@@ \@@_chk:w #1#2#3; }
+ \s_@@ \@@_chk:w #4#5#6;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_pow_zero_or_inf:ww}
+% Raising $-0$ or $-\infty$ to \texttt{nan} yields \texttt{nan}. For
+% other powers, the result is $+0$ if $0$ is raised to a positive
+% power or $\infty$ to a negative power, and $+\infty$ otherwise.
+% Thus, if the type of $a$ and the sign of $b$ coincide, the result
+% is~$0$, since those conveniently take the same possible values, $0$
+% and~$2$. Otherwise, either $a=\pm\infty$ and $b>0$ and the result
+% is $+\infty$, or $a=\pm 0$ with $b<0$ and we have a division by zero
+% unless $b=-\infty$.
+% \begin{macrocode}
+\cs_new:Npn \@@_pow_zero_or_inf:ww
+ \s_@@ \@@_chk:w #1#2; \s_@@ \@@_chk:w #3#4
+ {
+ \if_meaning:w 1 #4
+ \@@_case_return_same_o:w
+ \fi:
+ \if_meaning:w #1 #4
+ \@@_case_return_o:Nw \c_zero_fp
+ \fi:
+ \if_meaning:w 2 #1
+ \@@_case_return_o:Nw \c_inf_fp
+ \fi:
+ \if_meaning:w 2 #3
+ \@@_case_return_o:Nw \c_inf_fp
+ \else:
+ \@@_case_use:nw
+ {
+ \@@_division_by_zero_o:NNww \c_inf_fp ^
+ \s_@@ \@@_chk:w #1 #2 ;
+ }
+ \fi:
+ \s_@@ \@@_chk:w #3#4
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_pow_normal_o:ww}
+% We have in front of us $a$, and $b\neq 0$, we know that $a$ is a
+% normal number, and we wish to compute $\lvert a\rvert^{b}$. If
+% $\lvert a\rvert=1$, we return $1$, unless $a=-1$ and $b$ is
+% \texttt{nan}. Indeed, returning $1$ at this point would wrongly
+% raise \enquote{invalid} when the sign is considered. If $\lvert
+% a\rvert\neq 1$, test the type of $b$:
+% \begin{itemize}
+% \item[0] Impossible, we already filtered $b=\pm 0$.
+% \item[1] Call \cs{@@_pow_npos_o:Nww}.
+% \item[2] Return $+\infty$ or $+0$ depending on the sign of $b$ and
+% whether the exponent of $a$ is positive or not.
+% \item[3] Return $b$.
+% \end{itemize}
+% \begin{macrocode}
+\cs_new:Npn \@@_pow_normal_o:ww
+ \s_@@ \@@_chk:w 1 #1#2#3; \s_@@ \@@_chk:w #4#5
+ {
+ \if:w 0 \@@_str_if_eq:nn { #2 #3 } { 1 {1000} {0000} {0000} {0000} }
+ \if_int_compare:w #4 #1 = 32 \exp_stop_f:
+ \exp_after:wN \@@_case_return_ii_o:ww
+ \fi:
+ \@@_case_return_o:Nww \c_one_fp
+ \fi:
+ \if_case:w #4 \exp_stop_f:
+ \or:
+ \exp_after:wN \@@_pow_npos_o:Nww
+ \exp_after:wN #5
+ \or:
+ \if_meaning:w 2 #5 \exp_after:wN \reverse_if:N \fi:
+ \if_int_compare:w #2 > \c_zero_int
+ \exp_after:wN \@@_case_return_o:Nww
+ \exp_after:wN \c_inf_fp
+ \else:
+ \exp_after:wN \@@_case_return_o:Nww
+ \exp_after:wN \c_zero_fp
+ \fi:
+ \or:
+ \@@_case_return_ii_o:ww
+ \fi:
+ \s_@@ \@@_chk:w 1 #1 {#2} #3 ;
+ \s_@@ \@@_chk:w #4 #5
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A todo: check that we compute ln to 21 digits!
+% \begin{macro}[EXP]{\@@_pow_npos_o:Nww}
+% We now know that $a\neq\pm 1$ is a normal number, and $b$ is a
+% normal number too. We want to compute $\lvert a\rvert^{b} = (\lvert
+% x\rvert\cdot 10^{n})^{y\cdot 10^{p}} = \exp((\ln\lvert x\rvert + n
+% \ln(10))\cdot y \cdot 10^{p}) = \exp(z)$. To compute the
+% exponential accurately, we need to know the digits of $z$ up to the
+% $16$-th position. Since the exponential of $10^{5}$ is infinite, we
+% only need at most $21$ digits, hence the fixed point result of
+% \cs{@@_ln_o:w} is precise enough for our needs. Start an integer
+% expression for the decimal exponent of $e^{\lvert z\rvert}$. If $z$
+% is negative, negate that decimal exponent, and prepare to take the
+% inverse when converting from the fixed point to the floating point result.
+% \begin{macrocode}
+\cs_new:Npn \@@_pow_npos_o:Nww #1 \s_@@ \@@_chk:w 1#2#3
+ {
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN 0
+ \int_value:w
+ \if:w #1 \if_int_compare:w #3 > \c_zero_int 0 \else: 2 \fi:
+ \exp_after:wN \@@_pow_npos_aux:NNnww
+ \exp_after:wN +
+ \exp_after:wN \@@_fixed_to_float_o:wN
+ \else:
+ \exp_after:wN \@@_pow_npos_aux:NNnww
+ \exp_after:wN -
+ \exp_after:wN \@@_fixed_inv_to_float_o:wN
+ \fi:
+ {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%^^A begin[todo]
+% \begin{macro}[EXP]{\@@_pow_npos_aux:NNnww}
+% The first argument is the conversion function from fixed point to
+% float. Then comes an exponent and the $4$ brace groups of $x$,
+% followed by $b$. Compute $-\ln(x)$.
+% \begin{macrocode}
+\cs_new:Npn \@@_pow_npos_aux:NNnww #1#2#3#4#5; \s_@@ \@@_chk:w 1#6#7#8;
+ {
+ #1
+ \@@_int_eval:w
+ \@@_ln_significand:NNNNnnnN #4#5
+ \@@_pow_exponent:wnN {#3}
+ \@@_fixed_mul:wwn #8 {0000}{0000} ;
+ \@@_pow_B:wwN #7;
+ #1 #2 0 % fixed_to_float_o:wN
+ }
+\cs_new:Npn \@@_pow_exponent:wnN #1; #2
+ {
+ \if_int_compare:w #2 > \c_zero_int
+ \exp_after:wN \@@_pow_exponent:Nwnnnnnw % n\ln(10) - (-\ln(x))
+ \exp_after:wN +
+ \else:
+ \exp_after:wN \@@_pow_exponent:Nwnnnnnw % -(|n|\ln(10) + (-\ln(x)))
+ \exp_after:wN -
+ \fi:
+ #2; #1;
+ }
+\cs_new:Npn \@@_pow_exponent:Nwnnnnnw #1#2; #3#4#5#6#7#8;
+ { %^^A todo: use that in ln.
+ \exp_after:wN \@@_fixed_mul_after:wwn
+ \int_value:w \@@_int_eval:w \c_@@_leading_shift_int
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ #1#2*23025 - #1 #3
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ #1 #2*8509 - #1 #4
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ #1 #2*2994 - #1 #5
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ #1 #2*0456 - #1 #6
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_trailing_shift_int
+ #1 #2*8401 - #1 #7
+ #1 ( #2*7991 - #8 ) / 1 0000 ; ;
+ }
+\cs_new:Npn \@@_pow_B:wwN #1#2#3#4#5#6; #7;
+ {
+ \if_int_compare:w #7 < \c_zero_int
+ \exp_after:wN \@@_pow_C_neg:w \int_value:w -
+ \else:
+ \if_int_compare:w #7 < 22 \exp_stop_f:
+ \exp_after:wN \@@_pow_C_pos:w \int_value:w
+ \else:
+ \exp_after:wN \@@_pow_C_overflow:w \int_value:w
+ \fi:
+ \fi:
+ #7 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w 10 0000 + #1 \@@_int_eval_end:
+ #2#3#4#5#6 0000 0000 0000 0000 0000 0000 ; %^^A todo: how many 0?
+ }
+\cs_new:Npn \@@_pow_C_overflow:w #1; #2; #3
+ {
+ + 2 * \c_@@_max_exponent_int
+ \exp_after:wN \@@_fixed_continue:wn \c_@@_one_fixed_tl
+ }
+\cs_new:Npn \@@_pow_C_neg:w #1 ; 1
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_pow_C_pack:w
+ \prg_replicate:nn {#1} {0}
+ }
+\cs_new:Npn \@@_pow_C_pos:w #1; 1
+ { \@@_pow_C_pos_loop:wN #1; }
+\cs_new:Npn \@@_pow_C_pos_loop:wN #1; #2
+ {
+ \if_meaning:w 0 #1
+ \exp_after:wN \@@_pow_C_pack:w
+ \exp_after:wN #2
+ \else:
+ \if_meaning:w 0 #2
+ \exp_after:wN \@@_pow_C_pos_loop:wN \int_value:w
+ \else:
+ \exp_after:wN \@@_pow_C_overflow:w \int_value:w
+ \fi:
+ \@@_int_eval:w #1 - 1 \exp_after:wN ;
+ \fi:
+ }
+\cs_new:Npn \@@_pow_C_pack:w
+ {
+ \exp_after:wN \@@_exp_large:NwN
+ \exp_after:wN 5
+ \c_@@_one_fixed_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%^^A end[todo]
+%
+% \begin{macro}[EXP]{\@@_pow_neg:www, \@@_pow_neg_aux:wNN}
+% This function is followed by three floating point numbers: $|a|^b$,
+% $a\in[-\infty,-0]$, and $b$. If $b$ is an even integer (case $-1$),
+% $a^b=|a|^b$. If $b$ is an odd integer (case $0$), $a^b=-|a|^b$,
+% obtained by a call to \cs{@@_pow_neg_aux:wNN}. Otherwise, the sign is
+% undefined. This is invalid, unless $|a|^b$ turns out to be $+0$ or
+% \texttt{nan}, in which case we return that as $a^b$. In particular,
+% since the underflow detection occurs before \cs{@@_pow_neg:www} is
+% called, |(-0.1)**(12345.67)| gives $+0$ rather than complaining
+% that the sign is not defined.
+% \begin{macrocode}
+\cs_new:Npn \@@_pow_neg:www \s_@@ \@@_chk:w #1#2; #3; #4;
+ {
+ \if_case:w \@@_pow_neg_case:w #4 ;
+ \exp_after:wN \@@_pow_neg_aux:wNN
+ \or:
+ \if_int_compare:w \@@_int_eval:w #1 / 2 = \c_one_int
+ \@@_invalid_operation_o:Nww ^ #3; #4;
+ \exp:w \exp_end_continue_f:w
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_use_none_until_s:w
+ \fi:
+ \fi:
+ \@@_exp_after_o:w
+ \s_@@ \@@_chk:w #1#2;
+ }
+\cs_new:Npn \@@_pow_neg_aux:wNN #1 \s_@@ \@@_chk:w #2#3
+ {
+ \exp_after:wN \@@_exp_after_o:w
+ \exp_after:wN \s_@@
+ \exp_after:wN \@@_chk:w
+ \exp_after:wN #2
+ \int_value:w \@@_int_eval:w 2 - #3 \@@_int_eval_end:
+ }
+% \end{macrocode}
+% ^^A todo: is this \@@_exp_after_o:w necessary? Appropriate?
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {
+% \@@_pow_neg_case:w, \@@_pow_neg_case_aux:nnnnn,
+% \@@_pow_neg_case_aux:Nnnw
+% }
+% This function expects a floating point number, and determines its
+% \enquote{parity}. It should be used after \cs{if_case:w} or in an
+% integer expression. It gives $-1$ if the number is an even integer,
+% $0$~if the number is an odd integer, and $1$~otherwise. Zeros and
+% $\pm\infty$ are even (because very large finite floating points are
+% even), while \texttt{nan} is a non-integer. The sign of normal
+% numbers is irrelevant to parity. After \cs{@@_decimate:nNnnnn} the
+% argument |#1| of \cs{@@_pow_neg_case_aux:Nnnw} is a rounding digit,
+% |0|~if and only if the number was an integer, and |#3| is the $8$
+% least significant digits of that integer.
+% \begin{macrocode}
+\cs_new:Npn \@@_pow_neg_case:w \s_@@ \@@_chk:w #1#2#3;
+ {
+ \if_case:w #1 \exp_stop_f:
+ -1
+ \or: \@@_pow_neg_case_aux:nnnnn #3
+ \or: -1
+ \else: 1
+ \fi:
+ \exp_stop_f:
+ }
+\cs_new:Npn \@@_pow_neg_case_aux:nnnnn #1#2#3#4#5
+ {
+ \if_int_compare:w #1 > \c_@@_prec_int
+ -1
+ \else:
+ \@@_decimate:nNnnnn { \c_@@_prec_int - #1 }
+ \@@_pow_neg_case_aux:Nnnw
+ {#2} {#3} {#4} {#5}
+ \fi:
+ }
+\cs_new:Npn \@@_pow_neg_case_aux:Nnnw #1#2#3#4 ;
+ {
+ \if_meaning:w 0 #1
+ \if_int_odd:w #3 \exp_stop_f:
+ 0
+ \else:
+ -1
+ \fi:
+ \else:
+ 1
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Factorial}
+%
+% \begin{variable}{\c_@@_fact_max_arg_int}
+% The maximum integer whose factorial fits in the exponent range is
+% $3248$, as $3249!\sim 10^{10000.8}$
+% \begin{macrocode}
+\int_const:Nn \c_@@_fact_max_arg_int { 3248 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_fact_o:w}
+% First detect $\pm 0$ and $+\infty$ and \texttt{nan}. Then note that
+% factorial of anything with a negative sign (except $-0$) is
+% undefined. Then call \cs{@@_small_int:wTF} to get an integer as the
+% argument, and start a loop. This is not the most efficient way of
+% computing the factorial, but it works all right. Of course we work
+% with $24$ digits instead of~$16$. It is easy to check that
+% computing factorials with this precision is enough.
+% \begin{macrocode}
+\cs_new:Npn \@@_fact_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+ {
+ \if_case:w #2 \exp_stop_f:
+ \@@_case_return_o:Nw \c_one_fp
+ \or:
+ \or:
+ \if_meaning:w 0 #3
+ \exp_after:wN \@@_case_return_same_o:w
+ \fi:
+ \or:
+ \@@_case_return_same_o:w
+ \fi:
+ \if_meaning:w 2 #3
+ \@@_case_use:nw { \@@_invalid_operation_o:fw { fact } }
+ \fi:
+ \@@_fact_pos_o:w
+ \s_@@ \@@_chk:w #2 #3 #4 ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_fact_pos_o:w, \@@_fact_int_o:w}
+% Then check the input is an integer, and call
+% \cs{@@_facorial_int_o:n} with that \texttt{int} as an argument. If
+% it's too big the factorial overflows. Otherwise call
+% \cs{@@_sanitize:Nw} with a positive sign marker~|0| and an integer
+% expression that will mop up any exponent in the calculation.
+% \begin{macrocode}
+\cs_new:Npn \@@_fact_pos_o:w #1;
+ {
+ \@@_small_int:wTF #1;
+ { \@@_fact_int_o:n }
+ { \@@_invalid_operation_o:fw { fact } #1; }
+ }
+\cs_new:Npn \@@_fact_int_o:n #1
+ {
+ \if_int_compare:w #1 > \c_@@_fact_max_arg_int
+ \@@_case_return:nw
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_overflow:w
+ \exp_after:wN \c_inf_fp
+ }
+ \fi:
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN 0
+ \int_value:w \@@_int_eval:w
+ \@@_fact_loop_o:w #1 . 4 , { 1 } { } { } { } { } { } ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_fact_loop_o:w}
+% The loop receives an integer |#1| whose factorial we want to
+% compute, which we progressively decrement, and the result so far as
+% an extended-precision number |#2| in the form
+% \meta{exponent}|,|\meta{mantissa}|;|. The loop goes in steps of two
+% because we compute |#1*#1-1| as an integer expression (it must fit
+% since |#1| is at most $3248$), then multiply with the result so far.
+% We don't need to fill in most of the mantissa with zeros because
+% \cs{@@_ep_mul:wwwwn} first normalizes the extended precision number
+% to avoid loss of precision. When reaching a small enough number
+% simply use a table of factorials less than $10^8$. This limit is
+% chosen because the normalization step cannot deal with larger
+% integers.
+% \begin{macrocode}
+\cs_new:Npn \@@_fact_loop_o:w #1 . #2 ;
+ {
+ \if_int_compare:w #1 < 12 \exp_stop_f:
+ \@@_fact_small_o:w #1
+ \fi:
+ \exp_after:wN \@@_ep_mul:wwwwn
+ \exp_after:wN 4 \exp_after:wN ,
+ \exp_after:wN { \int_value:w \@@_int_eval:w #1 * (#1 - 1) }
+ { } { } { } { } { } ;
+ #2 ;
+ {
+ \exp_after:wN \@@_fact_loop_o:w
+ \int_value:w \@@_int_eval:w #1 - 2 .
+ }
+ }
+\cs_new:Npn \@@_fact_small_o:w #1 \fi: #2 ; #3 ; #4
+ {
+ \fi:
+ \exp_after:wN \@@_ep_mul:wwwwn
+ \exp_after:wN 4 \exp_after:wN ,
+ \exp_after:wN
+ {
+ \int_value:w
+ \if_case:w #1 \exp_stop_f:
+ 1 \or: 1 \or: 2 \or: 6 \or: 24 \or: 120 \or: 720 \or: 5040
+ \or: 40320 \or: 362880 \or: 3628800 \or: 39916800
+ \fi:
+ } { } { } { } { } { } ;
+ #3 ;
+ \@@_ep_to_float_o:wwN 0
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintChanges
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-extended.dtx b/macros/latex-dev/required/l3kernel/l3fp-extended.dtx
new file mode 100644
index 0000000000..356c32b232
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-extended.dtx
@@ -0,0 +1,1275 @@
+% \iffalse meta-comment
+%
+%% File: l3fp-extended.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-extended} module\\
+% Manipulating numbers with extended precision, for internal use^^A
+% }
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp-extended} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% \subsection{Description of fixed point numbers}
+%
+% This module provides a few functions to manipulate positive floating
+% point numbers with extended precision ($24$ digits), but mostly
+% provides functions for fixed-point numbers with this precision ($24$
+% digits). Those are used in the computation of
+% Taylor series for the logarithm, exponential, and trigonometric
+% functions. Since we eventually only care about the $16$ first digits
+% of the final result, some of the calculations are not performed with
+% the full $24$-digit precision. In other words, the last two blocks of
+% each fixed point number may be wrong as long as the error is small
+% enough to be rounded away when converting back to a floating point
+% number. The fixed point numbers are expressed as
+% \begin{quote}
+% \Arg{a_1} \Arg{a_2} \Arg{a_3} \Arg{a_4} \Arg{a_5} \Arg{a_6} |;|
+% \end{quote}
+% where each \meta{a_i} is exactly $4$ digits (ranging from |0000| to
+% |9999|), except \meta{a_1}, which may be any \enquote{not-too-large}
+% non-negative integer, with or without leading zeros. Here,
+% \enquote{not-too-large} depends on the specific function (see the
+% corresponding comments for details). Checking for overflow is the
+% responsibility of the code calling those functions. The fixed point
+% number $a$ corresponding to the representation above is $a =
+% \sum_{i=1}^{6} \meta{a_i} \cdot 10^{-4i}$.
+%
+% Most functions we define here have the form
+% \begin{syntax}
+% \cs{@@_fixed_\meta{calculation}:wwn} \meta{operand_1} |;| \meta{operand_2} |;| \Arg{continuation}
+% \end{syntax}
+% They perform the \meta{calculation} on the two \meta{operands}, then
+% feed the result ($6$ brace groups followed by a semicolon) to the
+% \meta{continuation}, responsible for the next step of the calculation.
+% Some functions only accept an \texttt{N}-type \meta{continuation}.
+% This allows constructions such as
+% \begin{quote}
+% \cs{@@_fixed_add:wwn} \meta{X_1} |;| \meta{X_2} |;| \\
+% \cs{@@_fixed_mul:wwn} \meta{X_3} |;| \\
+% \cs{@@_fixed_add:wwn} \meta{X_4} |;| \\
+% \end{quote}
+% to compute $(X_1+X_2)\cdot X_3 + X_4$. This turns out to be very
+% appropriate for computing continued fractions and Taylor series.
+%
+% At the end of the calculation, the result is turned back to a floating
+% point number using \cs{@@_fixed_to_float_o:wN}. This function has to
+% change the exponent of the floating point number: it must be used
+% after starting an integer expression for the overall exponent of the
+% result.
+%
+% \subsection{Helpers for numbers with extended precision}
+%
+% \begin{variable}{\c_@@_one_fixed_tl}
+% The fixed-point number~$1$, used in \pkg{l3fp-expo}.
+% \begin{macrocode}
+\tl_const:Nn \c_@@_one_fixed_tl
+ { {10000} {0000} {0000} {0000} {0000} {0000} ; }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_fixed_continue:wn}
+% This function simply calls the next function.
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_continue:wn #1; #2 { #2 #1; }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_fixed_add_one:wN}
+% \begin{syntax}
+% \cs{@@_fixed_add_one:wN} \meta{a} |;| \meta{continuation}
+% \end{syntax}
+% This function adds $1$ to the fixed point \meta{a}, by changing
+% $a_1$ to $10000+a_1$, then calls the \meta{continuation}. This
+% requires $a_1 + 10000 < 2^{31}$.
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_add_one:wN #1#2; #3
+ {
+ \exp_after:wN #3 \exp_after:wN
+ { \int_value:w \@@_int_eval:w \c_@@_myriad_int + #1 } #2 ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_fixed_div_myriad:wn}
+% Divide a fixed point number by $10000$. This is a little bit more
+% subtle than just removing the last group and adding a leading group
+% of zeros: the first group~|#1| may have any number of digits, and we
+% must split~|#1| into the new first group and a second group of
+% exactly $4$~digits. The choice of shifts allows~|#1| to be in the
+% range $[0, 5\cdot 10^{8}-1]$.
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_div_myriad:wn #1#2#3#4#5#6;
+ {
+ \exp_after:wN \@@_fixed_mul_after:wwn
+ \int_value:w \@@_int_eval:w \c_@@_leading_shift_int
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_trailing_shift_int
+ + #1 ; {#2}{#3}{#4}{#5};
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_fixed_mul_after:wwn}
+% The fixed point operations which involve multiplication end by
+% calling this auxiliary. It braces the last block of digits, and
+% places the \meta{continuation} |#3| in front.
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_mul_after:wwn #1; #2; #3 { #3 {#1} #2; }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Multiplying a fixed point number by a short one}
+%
+% \begin{macro}[EXP]{\@@_fixed_mul_short:wwn}
+% \begin{syntax}\parskip=0pt\obeylines
+% \cs{@@_fixed_mul_short:wwn}
+% | |\Arg{a_1} \Arg{a_2} \Arg{a_3} \Arg{a_4} \Arg{a_5} \Arg{a_6} |;|
+% | |\Arg{b_0} \Arg{b_1} \Arg{b_2} |;| \Arg{continuation}
+% \end{syntax}
+% Computes the product $c=ab$ of $a=\sum_i \meta{a_i} 10^{-4i}$ and
+% $b=\sum_i \meta{b_i} 10^{-4i}$, rounds it to the closest multiple of
+% $10^{-24}$, and leaves \meta{continuation} \Arg{c_1} \ldots{}
+% \Arg{c_6} |;| in the input stream, where each of the \meta{c_i} are
+% blocks of $4$~digits, except \meta{c_1}, which is any \TeX{}
+% integer. Note that indices for \meta{b} start at~$0$: for instance
+% a second operand of |{0001}{0000}{0000}| leaves the first operand
+% unchanged (rather than dividing it by $10^{4}$, as
+% \cs{@@_fixed_mul:wwn} would).
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_mul_short:wwn #1#2#3#4#5#6; #7#8#9;
+ {
+ \exp_after:wN \@@_fixed_mul_after:wwn
+ \int_value:w \@@_int_eval:w \c_@@_leading_shift_int
+ + #1*#7
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ + #1*#8 + #2*#7
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ + #1*#9 + #2*#8 + #3*#7
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ + #2*#9 + #3*#8 + #4*#7
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ + #3*#9 + #4*#8 + #5*#7
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_trailing_shift_int
+ + #4*#9 + #5*#8 + #6*#7
+ + ( #5*#9 + #6*#8 + #6*#9 / \c_@@_myriad_int )
+ / \c_@@_myriad_int ; ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Dividing a fixed point number by a small integer}
+%
+% \begin{macro}[EXP]{\@@_fixed_div_int:wwN}
+% \begin{macro}[EXP]
+% {
+% \@@_fixed_div_int:wnN, \@@_fixed_div_int_auxi:wnn,
+% \@@_fixed_div_int_auxii:wnn, \@@_fixed_div_int_pack:Nw,
+% \@@_fixed_div_int_after:Nw
+% }
+% \begin{syntax}
+% \cs{@@_fixed_div_int:wwN} \meta{a} |;| \meta{n} |;| \meta{continuation}
+% \end{syntax}
+% Divides the fixed point number \meta{a} by the (small) integer
+% $0<\meta{n}<10^4$ and feeds the result to the \meta{continuation}.
+% There is no bound on $a_1$.
+%
+% The arguments of the \texttt{i} auxiliary are 1: one of the $a_{i}$,
+% 2: $n$, 3: the \texttt{ii} or the \texttt{iii} auxiliary. It
+% computes a (somewhat tight) lower bound $Q_{i}$ for the ratio
+% $a_{i}/n$.
+%
+% The \texttt{ii} auxiliary receives $Q_{i}$, $n$, and $a_{i}$ as
+% arguments. It adds $Q_{i}$ to a surrounding integer expression, and
+% starts a new one with the initial value $9999$, which ensures that
+% the result of this expression has $5$ digits. The auxiliary
+% also computes $a_{i}-n\cdot Q_{i}$, placing the result in front of
+% the $4$ digits of $a_{i+1}$. The resulting $a'_{i+1} = 10^{4}
+% (a_{i} - n \cdot Q_{i}) + a_{i+1}$ serves as the first argument for
+% a new call to the \texttt{i} auxiliary.
+%
+% When the \texttt{iii} auxiliary is called, the situation looks like
+% this:
+% \begin{quote}
+% \cs{@@_fixed_div_int_after:Nw} \meta{continuation} \\
+% $-1 + Q_{1}$ \\
+% \cs{@@_fixed_div_int_pack:Nw} $9999 + Q_{2}$ \\
+% \cs{@@_fixed_div_int_pack:Nw} $9999 + Q_{3}$ \\
+% \cs{@@_fixed_div_int_pack:Nw} $9999 + Q_{4}$ \\
+% \cs{@@_fixed_div_int_pack:Nw} $9999 + Q_{5}$ \\
+% \cs{@@_fixed_div_int_pack:Nw} $9999$ \\
+% \cs{@@_fixed_div_int_auxii:wnn} $Q_{6}$ |;| \Arg{n} \Arg{a_{6}}
+% \end{quote}
+% where expansion is happening from the last line up. The
+% \texttt{iii} auxiliary adds $Q_{6} + 2 \simeq a_{6}/n + 1$ to the
+% last $9999$, giving the integer closest to $10000 + a_{6}/n$.
+%
+% Each \texttt{pack} auxiliary receives $5$ digits followed by a
+% semicolon. The first digit is added as a carry to the integer
+% expression above, and the $4$ other digits are braced. Each call to
+% the \texttt{pack} auxiliary thus produces one brace group. The last
+% brace group is produced by the \texttt{after} auxiliary, which
+% places the \meta{continuation} as appropriate.
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_div_int:wwN #1#2#3#4#5#6 ; #7 ; #8
+ {
+ \exp_after:wN \@@_fixed_div_int_after:Nw
+ \exp_after:wN #8
+ \int_value:w \@@_int_eval:w - 1
+ \@@_fixed_div_int:wnN
+ #1; {#7} \@@_fixed_div_int_auxi:wnn
+ #2; {#7} \@@_fixed_div_int_auxi:wnn
+ #3; {#7} \@@_fixed_div_int_auxi:wnn
+ #4; {#7} \@@_fixed_div_int_auxi:wnn
+ #5; {#7} \@@_fixed_div_int_auxi:wnn
+ #6; {#7} \@@_fixed_div_int_auxii:wnn ;
+ }
+\cs_new:Npn \@@_fixed_div_int:wnN #1; #2 #3
+ {
+ \exp_after:wN #3
+ \int_value:w \@@_int_eval:w #1 / #2 - 1 ;
+ {#2}
+ {#1}
+ }
+\cs_new:Npn \@@_fixed_div_int_auxi:wnn #1; #2 #3
+ {
+ + #1
+ \exp_after:wN \@@_fixed_div_int_pack:Nw
+ \int_value:w \@@_int_eval:w 9999
+ \exp_after:wN \@@_fixed_div_int:wnN
+ \int_value:w \@@_int_eval:w #3 - #1*#2 \@@_int_eval_end:
+ }
+\cs_new:Npn \@@_fixed_div_int_auxii:wnn #1; #2 #3 { + #1 + 2 ; }
+\cs_new:Npn \@@_fixed_div_int_pack:Nw #1 #2; { + #1; {#2} }
+\cs_new:Npn \@@_fixed_div_int_after:Nw #1 #2; { #1 {#2} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Adding and subtracting fixed points}
+%
+% \begin{macro}[EXP]{\@@_fixed_add:wwn, \@@_fixed_sub:wwn}
+% \begin{macro}[EXP]
+% {
+% \@@_fixed_add:Nnnnnwnn,
+% \@@_fixed_add:nnNnnnwn,
+% \@@_fixed_add_pack:NNNNNwn,
+% \@@_fixed_add_after:NNNNNwn
+% }
+% \begin{syntax}
+% \cs{@@_fixed_add:wwn} \meta{a} |;| \meta{b} |;| \Arg{continuation}
+% \end{syntax}
+% Computes $a+b$ (resp.\ $a-b$) and feeds the result to the
+% \meta{continuation}. This function requires $0\leq a_{1},b_{1}\leq
+% 114748$, its result must be positive (this happens automatically for
+% addition) and its first group must have at most~$5$ digits: $(a\pm
+% b)_{1}<100000$. The two functions only differ by
+% a sign, hence use a common auxiliary. It would be nice to grab the
+% $12$ brace groups in one go; only $9$ parameters are allowed. Start
+% by grabbing the sign, $a_{1}, \ldots, a_{4}$, the rest of $a$,
+% and $b_{1}$ and $b_{2}$. The second auxiliary receives the rest of
+% $a$, the sign multiplying $b$, the rest of $b$, and the
+% \meta{continuation} as arguments. After going down through the
+% various level, we go back up, packing digits and bringing the
+% \meta{continuation} (|#8|, then |#7|) from the end of the argument
+% list to its start.
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_add:wwn { \@@_fixed_add:Nnnnnwnn + }
+\cs_new:Npn \@@_fixed_sub:wwn { \@@_fixed_add:Nnnnnwnn - }
+\cs_new:Npn \@@_fixed_add:Nnnnnwnn #1 #2#3#4#5 #6; #7#8
+ {
+ \exp_after:wN \@@_fixed_add_after:NNNNNwn
+ \int_value:w \@@_int_eval:w 9 9999 9998 + #2#3 #1 #7#8
+ \exp_after:wN \@@_fixed_add_pack:NNNNNwn
+ \int_value:w \@@_int_eval:w 1 9999 9998 + #4#5
+ \@@_fixed_add:nnNnnnwn #6 #1
+ }
+\cs_new:Npn \@@_fixed_add:nnNnnnwn #1#2 #3 #4#5 #6#7 ; #8
+ {
+ #3 #4#5
+ \exp_after:wN \@@_fixed_add_pack:NNNNNwn
+ \int_value:w \@@_int_eval:w 2 0000 0000 #3 #6#7 + #1#2 ; {#8} ;
+ }
+\cs_new:Npn \@@_fixed_add_pack:NNNNNwn #1 #2#3#4#5 #6; #7
+ { + #1 ; {#7} {#2#3#4#5} {#6} }
+\cs_new:Npn \@@_fixed_add_after:NNNNNwn 1 #1 #2#3#4#5 #6; #7
+ { #7 {#1#2#3#4#5} {#6} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Multiplying fixed points}
+%
+% ^^A todo: may a_1 or b_1 be = 10000? Used in ediv_epsi later.
+% \begin{macro}[EXP]{\@@_fixed_mul:wwn}
+% \begin{macro}[EXP]{\@@_fixed_mul:nnnnnnnw}
+% \begin{syntax}
+% \cs{@@_fixed_mul:wwn} \meta{a} |;| \meta{b} |;| \Arg{continuation}
+% \end{syntax}
+% Computes $a\times b$ and feeds the result to \meta{continuation}.
+% This function requires $0\leq a_{1}, b_{1} < 10000$. Once more, we
+% need to play around the limit of $9$ arguments for \TeX{} macros.
+% Note that we don't need to obtain an exact rounding, contrarily to
+% the |*| operator, so things could be harder. We wish to perform
+% carries in
+% \begin{align*}
+% a \times b =
+% & a_{1} \cdot b_{1} \cdot 10^{-8} \\
+% & + (a_{1} \cdot b_{2} + a_{2} \cdot b_{1}) \cdot 10^{-12} \\
+% & + (a_{1} \cdot b_{3} + a_{2} \cdot b_{2}
+% + a_{3} \cdot b_{1}) \cdot 10^{-16} \\
+% & + (a_{1} \cdot b_{4} + a_{2} \cdot b_{3}
+% + a_{3} \cdot b_{2} + a_{4} \cdot b_{1}) \cdot 10^{-20} \\
+% & + \Bigl(a_{2} \cdot b_{4} + a_{3} \cdot b_{3} + a_{4} \cdot b_{2}
+% \\ & \qquad
+% + \frac{a_{3} \cdot b_{4} + a_{4} \cdot b_{3}
+% + a_{1} \cdot b_{6} + a_{2} \cdot b_{5}
+% + a_{5} \cdot b_{2} + a_{6} \cdot b_{1}}{10^{4}}
+% \\ & \qquad
+% + a_{1} \cdot b_{5} + a_{5} \cdot b_{1}\Bigr) \cdot 10^{-24}
+% + O(10^{-24}),
+% \end{align*}
+% where the $O(10^{-24})$ stands for terms which are at most $5\cdot
+% 10^{-24}$; ignoring those leads to an error of at most
+% $5$~\texttt{ulp}. Note how the first $15$~terms only depend on
+% $a_{1},\ldots{},a_{4}$ and $b_{1},\ldots,b_{4}$, while the last
+% $6$~terms only depend on $a_{1},a_{2},a_{5},a_{6}$, and the
+% corresponding parts of~$b$. Hence, the first function grabs
+% $a_{1},\ldots,a_{4}$, the rest of $a$, and $b_{1},\ldots,b_{4}$, and
+% writes the $15$ first terms of the expression, including a left
+% parenthesis for the fraction. The \texttt{i} auxiliary receives
+% $a_{5}$, $a_{6}$, $b_{1}$, $b_{2}$, $a_{1}$, $a_{2}$, $b_{5}$,
+% $b_{6}$ and finally the \meta{continuation} as arguments. It writes
+% the end of the expression, including the right parenthesis and the
+% denominator of the fraction. The \meta{continuation}
+% is finally placed in front of the $6$ brace groups by
+% \cs{@@_fixed_mul_after:wwn}.
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_mul:wwn #1#2#3#4 #5; #6#7#8#9
+ {
+ \exp_after:wN \@@_fixed_mul_after:wwn
+ \int_value:w \@@_int_eval:w \c_@@_leading_shift_int
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ + #1*#6
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ + #1*#7 + #2*#6
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ + #1*#8 + #2*#7 + #3*#6
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ + #1*#9 + #2*#8 + #3*#7 + #4*#6
+ \exp_after:wN \@@_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_trailing_shift_int
+ + #2*#9 + #3*#8 + #4*#7
+ + ( #3*#9 + #4*#8
+ + \@@_fixed_mul:nnnnnnnw #5 {#6}{#7} {#1}{#2}
+ }
+\cs_new:Npn \@@_fixed_mul:nnnnnnnw #1#2 #3#4 #5#6 #7#8 ;
+ {
+ #1*#4 + #2*#3 + #5*#8 + #6*#7 ) / \c_@@_myriad_int
+ + #1*#3 + #5*#7 ; ;
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Combining product and sum of fixed points}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_fixed_mul_add:wwwn,
+% \@@_fixed_mul_sub_back:wwwn,
+% \@@_fixed_mul_one_minus_mul:wwn,
+% }
+% \begin{syntax}
+% \cs{@@_fixed_mul_add:wwwn} \meta{a} |;| \meta{b} |;| \meta{c} |;| \Arg{continuation}
+% \cs{@@_fixed_mul_sub_back:wwwn} \meta{a} |;| \meta{b} |;| \meta{c} |;| \Arg{continuation}
+% \cs{@@_fixed_one_minus_mul:wwn} \meta{a} |;| \meta{b} |;| \Arg{continuation}
+% \end{syntax}
+% Sometimes called |FMA| (fused multiply-add), these functions
+% compute $a\times b + c$, $c - a\times b$, and $1 - a\times b$ and
+% feed the result to the \meta{continuation}. Those functions require
+% $0\leq a_{1}, b_{1}, c_{1} \leq 10000$. Since those functions are
+% at the heart of the computation of Taylor expansions, we
+% over-optimize them a bit, and in particular we do not factor out the
+% common parts of the three functions.
+%
+% For definiteness, consider the task of computing $a\times b + c$.
+% We perform carries in
+% \begin{align*}
+% a \times b + c =
+% & (a_{1} \cdot b_{1} + c_{1} c_{2})\cdot 10^{-8} \\
+% & + (a_{1} \cdot b_{2} + a_{2} \cdot b_{1}) \cdot 10^{-12} \\
+% & + (a_{1} \cdot b_{3} + a_{2} \cdot b_{2} + a_{3} \cdot b_{1}
+% + c_{3} c_{4}) \cdot 10^{-16} \\
+% & + (a_{1} \cdot b_{4} + a_{2} \cdot b_{3} + a_{3} \cdot b_{2}
+% + a_{4} \cdot b_{1}) \cdot 10^{-20} \\
+% & + \Big(a_{2} \cdot b_{4} + a_{3} \cdot b_{3} + a_{4} \cdot b_{2}
+% \\ & \qquad
+% + \frac{a_{3} \cdot b_{4} + a_{4} \cdot b_{3}
+% + a_{1} \cdot b_{6} + a_{2} \cdot b_{5}
+% + a_{5} \cdot b_{2} + a_{6} \cdot b_{1}}{10^{4}}
+% \\ & \qquad
+% + a_{1} \cdot b_{5} + a_{5} \cdot b_{1}
+% + c_{5} c_{6} \Big) \cdot 10^{-24}
+% + O(10^{-24}),
+% \end{align*}
+% where $c_{1} c_{2}$, $c_{3} c_{4}$, $c_{5} c_{6}$ denote the
+% $8$-digit number obtained by juxtaposing the two blocks of digits of
+% $c$, and $\cdot$ denotes multiplication. The task is obviously
+% tough because we have $18$ brace groups in front of us.
+%
+% Each of the three function starts the first two levels (the first,
+% corresponding to $10^{-4}$, is empty), with $c_{1} c_{2}$ in the
+% first level, calls the \texttt{i} auxiliary with arguments described
+% later, and adds a trailing ${} + c_{5}c_{6}$ |;|
+% \Arg{continuation}~|;|. The ${} + c_{5}c_{6}$ piece, which is
+% omitted for \cs{@@_fixed_one_minus_mul:wwn}, is taken in the
+% integer expression for the $10^{-24}$ level.
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_mul_add:wwwn #1; #2; #3#4#5#6#7#8;
+ {
+ \exp_after:wN \@@_fixed_mul_after:wwn
+ \int_value:w \@@_int_eval:w \c_@@_big_leading_shift_int
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int + #3 #4
+ \@@_fixed_mul_add:Nwnnnwnnn +
+ + #5 #6 ; #2 ; #1 ; #2 ; +
+ + #7 #8 ; ;
+ }
+\cs_new:Npn \@@_fixed_mul_sub_back:wwwn #1; #2; #3#4#5#6#7#8;
+ {
+ \exp_after:wN \@@_fixed_mul_after:wwn
+ \int_value:w \@@_int_eval:w \c_@@_big_leading_shift_int
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int + #3 #4
+ \@@_fixed_mul_add:Nwnnnwnnn -
+ + #5 #6 ; #2 ; #1 ; #2 ; -
+ + #7 #8 ; ;
+ }
+\cs_new:Npn \@@_fixed_one_minus_mul:wwn #1; #2;
+ {
+ \exp_after:wN \@@_fixed_mul_after:wwn
+ \int_value:w \@@_int_eval:w \c_@@_big_leading_shift_int
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int +
+ 1 0000 0000
+ \@@_fixed_mul_add:Nwnnnwnnn -
+ ; #2 ; #1 ; #2 ; -
+ ; ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_fixed_mul_add:Nwnnnwnnn}
+% \begin{syntax}
+% \cs{@@_fixed_mul_add:Nwnnnwnnn} \meta{op} |+| \meta{c_3} \meta{c_4} |;|
+% ~~\meta{b} |;| \meta{a} |;| \meta{b} |;| \meta{op}
+% ~~|+| \meta{c_5} \meta{c_6} |;|
+% \end{syntax}
+% Here, \meta{op} is either |+| or |-|. Arguments |#3|, |#4|, |#5|
+% are \meta{b_1}, \meta{b_2}, \meta{b_3}; arguments |#7|, |#8|, |#9|
+% are \meta{a_1}, \meta{a_2}, \meta{a_3}. We can build three levels:
+% $a_{1} \cdot b_{1}$ for $10^{-8}$, $(a_{1} \cdot b_{2} + a_{2} \cdot
+% b_{1})$ for $10^{-12}$, and $(a_{1} \cdot b_{3} + a_{2} \cdot b_{2}
+% + a_{3} \cdot b_{1} + c_{3} c_{4})$ for $10^{-16}$. The $a$--$b$
+% products use the sign |#1|. Note that |#2| is empty for
+% \cs{@@_fixed_one_minus_mul:wwn}. We call the \texttt{ii} auxiliary
+% for levels $10^{-20}$ and $10^{-24}$, keeping the pieces of \meta{a}
+% we've read, but not \meta{b}, since there is another copy later in
+% the input stream.
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_mul_add:Nwnnnwnnn #1 #2; #3#4#5#6; #7#8#9
+ {
+ #1 #7*#3
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int
+ #1 #7*#4 #1 #8*#3
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int
+ #1 #7*#5 #1 #8*#4 #1 #9*#3 #2
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int
+ #1 \@@_fixed_mul_add:nnnnwnnnn {#7}{#8}{#9}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_fixed_mul_add:nnnnwnnnn}
+% \begin{syntax}
+% \cs{@@_fixed_mul_add:nnnnwnnnn} \meta{a} |;| \meta{b} |;| \meta{op}
+% ~~|+| \meta{c_5} \meta{c_6} |;|
+% \end{syntax}
+% Level $10^{-20}$ is $(a_{1} \cdot b_{4} + a_{2} \cdot b_{3} + a_{3}
+% \cdot b_{2} + a_{4} \cdot b_{1})$, multiplied by the sign, which was
+% inserted by the \texttt{i} auxiliary. Then we prepare level
+% $10^{-24}$. We don't have access to all parts of \meta{a} and
+% \meta{b} needed to make all products. Instead, we prepare the
+% partial expressions
+% \begin{align*}
+% & b_{1} + a_{4} \cdot b_{2} + a_{3} \cdot b_{3} + a_{2} \cdot b_{4} + a_{1} \\
+% & b_{2} + a_{4} \cdot b_{3} + a_{3} \cdot b_{4} + a_{2} .
+% \end{align*}
+% Obviously, those expressions make no mathematical sense: we
+% complete them with $a_{5} \cdot {}$ and ${} \cdot b_{5}$, and with
+% $a_{6} \cdot b_{1} + a_{5} \cdot {}$ and ${} \cdot b_{5} + a_{1}
+% \cdot b_{6}$, and of course with the trailing ${} + c_{5} c_{6}$.
+% To do all this, we keep $a_{1}$, $a_{5}$, $a_{6}$, and the
+% corresponding pieces of \meta{b}.
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_mul_add:nnnnwnnnn #1#2#3#4#5; #6#7#8#9
+ {
+ ( #1*#9 + #2*#8 + #3*#7 + #4*#6 )
+ \exp_after:wN \@@_pack_big:NNNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_big_trailing_shift_int
+ \@@_fixed_mul_add:nnnnwnnwN
+ { #6 + #4*#7 + #3*#8 + #2*#9 + #1 }
+ { #7 + #4*#8 + #3*#9 + #2 }
+ {#1} #5;
+ {#6}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_fixed_mul_add:nnnnwnnwN}
+% \begin{syntax}
+% \cs{@@_fixed_mul_add:nnnnwnnwN} \Arg{partial_1} \Arg{partial_2}
+% ~~\Arg{a_1} \Arg{a_5} \Arg{a_6} |;| \Arg{b_1} \Arg{b_5} \Arg{b_6} |;|
+% ~~\meta{op} |+| \meta{c_5} \meta{c_6} |;|
+% \end{syntax}
+% Complete the \meta{partial_1} and \meta{partial_2} expressions as
+% explained for the \texttt{ii} auxiliary. The second one is divided
+% by $10000$: this is the carry from level $10^{-28}$. The trailing
+% ${} + c_{5} c_{6}$ is taken into the expression for level
+% $10^{-24}$. Note that the total of level $10^{-24}$ is in the
+% interval $[-5\cdot 10^{8}, 6\cdot 10^{8}$ (give or take a couple of
+% $10000$), hence adding it to the shift gives a $10$-digit number, as
+% expected by the packing auxiliaries. See \pkg{l3fp-aux} for the
+% definition of the shifts and packing auxiliaries.
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_mul_add:nnnnwnnwN #1#2 #3#4#5; #6#7#8; #9
+ {
+ #9 (#4* #1 *#7)
+ #9 (#5*#6+#4* #2 *#7+#3*#8) / \c_@@_myriad_int
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Extended-precision floating point numbers}
+%
+% In this section we manipulate floating point numbers with roughly $24$
+% significant figures (\enquote{extended-precision} numbers, in short,
+% \enquote{ep}), which take the form of an integer exponent, followed by a
+% comma, then six groups of digits, ending with a semicolon. The first
+% group of digit may be any non-negative integer, while other groups of
+% digits have $4$~digits. In other words, an extended-precision number
+% is an exponent ending in a comma, then a fixed point number. The
+% corresponding value is $0.\meta{digits}\cdot 10^{\meta{exponent}}$.
+% This convention differs from floating points.
+%
+% \begin{macro}[EXP]{\@@_ep_to_fixed:wwn}
+% \begin{macro}[EXP]
+% {\@@_ep_to_fixed_auxi:www, \@@_ep_to_fixed_auxii:nnnnnnnwn}
+% Converts an extended-precision number with an exponent at most~$4$
+% and a first block less than $10^{8}$ to a fixed point number whose
+% first block has $12$~digits, hopefully starting with many zeros.
+% \begin{macrocode}
+\cs_new:Npn \@@_ep_to_fixed:wwn #1,#2
+ {
+ \exp_after:wN \@@_ep_to_fixed_auxi:www
+ \int_value:w \@@_int_eval:w 1 0000 0000 + #2 \exp_after:wN ;
+ \exp:w \exp_end_continue_f:w
+ \prg_replicate:nn { 4 - \int_max:nn {#1} { -32 } } { 0 } ;
+ }
+\cs_new:Npn \@@_ep_to_fixed_auxi:www 1#1; #2; #3#4#5#6#7;
+ {
+ \@@_pack_eight:wNNNNNNNN
+ \@@_pack_twice_four:wNNNNNNNN
+ \@@_pack_twice_four:wNNNNNNNN
+ \@@_pack_twice_four:wNNNNNNNN
+ \@@_ep_to_fixed_auxii:nnnnnnnwn ;
+ #2 #1#3#4#5#6#7 0000 !
+ }
+\cs_new:Npn \@@_ep_to_fixed_auxii:nnnnnnnwn #1#2#3#4#5#6#7; #8! #9
+ { #9 {#1#2}{#3}{#4}{#5}{#6}{#7}; }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% ^^A todo: make it work when the arg is zero.
+% \begin{macro}[EXP]{\@@_ep_to_ep:wwN}
+% \begin{macro}[rEXP]{\@@_ep_to_ep_loop:N, \@@_ep_to_ep_end:www}
+% \begin{macro}[EXP]{\@@_ep_to_ep_zero:ww}
+% Normalize an extended-precision number. More precisely, leading
+% zeros are removed from the mantissa of the argument, decreasing its
+% exponent as appropriate. Then the digits are packed into $6$~groups
+% of~$4$ (discarding any remaining digit, not rounding). Finally, the
+% continuation~|#8| is placed before the resulting exponent--mantissa
+% pair. The input exponent may in fact be given as an integer
+% expression. The \texttt{loop} auxiliary grabs a digit: if it
+% is~$0$, decrement the exponent and continue looping, and otherwise
+% call the \texttt{end} auxiliary, which places all digits in the
+% right order (the digit that was not~$0$, and any remaining digits),
+% followed by some~$0$, then packs them up neatly in $3\times2=6$
+% blocks of four. At the end of the day, remove with \cs{@@_use_i:ww}
+% any digit that did not make it in the final mantissa (typically only
+% zeros, unless the original first block has more than~$4$ digits).
+% \begin{macrocode}
+\cs_new:Npn \@@_ep_to_ep:wwN #1,#2#3#4#5#6#7; #8
+ {
+ \exp_after:wN #8
+ \int_value:w \@@_int_eval:w #1 + 4
+ \exp_after:wN \use_i:nn
+ \exp_after:wN \@@_ep_to_ep_loop:N
+ \int_value:w \@@_int_eval:w 1 0000 0000 + #2 \@@_int_eval_end:
+ #3#4#5#6#7 ; ; !
+ }
+\cs_new:Npn \@@_ep_to_ep_loop:N #1
+ {
+ \if_meaning:w 0 #1
+ - 1
+ \else:
+ \@@_ep_to_ep_end:www #1
+ \fi:
+ \@@_ep_to_ep_loop:N
+ }
+\cs_new:Npn \@@_ep_to_ep_end:www
+ #1 \fi: \@@_ep_to_ep_loop:N #2; #3!
+ {
+ \fi:
+ \if_meaning:w ; #1
+ - 2 * \c_@@_max_exponent_int
+ \@@_ep_to_ep_zero:ww
+ \fi:
+ \@@_pack_twice_four:wNNNNNNNN
+ \@@_pack_twice_four:wNNNNNNNN
+ \@@_pack_twice_four:wNNNNNNNN
+ \@@_use_i:ww , ;
+ #1 #2 0000 0000 0000 0000 0000 0000 ;
+ }
+\cs_new:Npn \@@_ep_to_ep_zero:ww \fi: #1; #2; #3;
+ { \fi: , {1000}{0000}{0000}{0000}{0000}{0000} ; }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_ep_compare:wwww}
+% \begin{macro}[EXP]{\@@_ep_compare_aux:wwww}
+% In \pkg{l3fp-trig} we need to compare two extended-precision
+% numbers. This is based on the same function for positive floating
+% point numbers, with an extra test if comparing only $16$ decimals is
+% not enough to distinguish the numbers. Note that this function only
+% works if the numbers are normalized so that their first block is
+% in~$[1000,9999]$.
+% \begin{macrocode}
+\cs_new:Npn \@@_ep_compare:wwww #1,#2#3#4#5#6#7;
+ { \@@_ep_compare_aux:wwww {#1}{#2}{#3}{#4}{#5}; #6#7; }
+\cs_new:Npn \@@_ep_compare_aux:wwww #1;#2;#3,#4#5#6#7#8#9;
+ {
+ \if_case:w
+ \@@_compare_npos:nwnw #1; {#3}{#4}{#5}{#6}{#7}; \exp_stop_f:
+ \if_int_compare:w #2 = #8#9 \exp_stop_f:
+ 0
+ \else:
+ \if_int_compare:w #2 < #8#9 - \fi: 1
+ \fi:
+ \or: 1
+ \else: -1
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% ^^A todo: doc that neither operand may be zero (or fix ep_to_ep above)
+% \begin{macro}[EXP]{\@@_ep_mul:wwwwn, \@@_ep_mul_raw:wwwwN}
+% Multiply two extended-precision numbers: first normalize them to
+% avoid losing too much precision, then multiply the mantissas |#2|
+% and~|#4| as fixed point numbers, and sum the exponents |#1|
+% and~|#3|. The result's first block is in $[100,9999]$.
+% \begin{macrocode}
+\cs_new:Npn \@@_ep_mul:wwwwn #1,#2; #3,#4;
+ {
+ \@@_ep_to_ep:wwN #3,#4;
+ \@@_fixed_continue:wn
+ {
+ \@@_ep_to_ep:wwN #1,#2;
+ \@@_ep_mul_raw:wwwwN
+ }
+ \@@_fixed_continue:wn
+ }
+\cs_new:Npn \@@_ep_mul_raw:wwwwN #1,#2; #3,#4; #5
+ {
+ \@@_fixed_mul:wwn #2; #4;
+ { \exp_after:wN #5 \int_value:w \@@_int_eval:w #1 + #3 , }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Dividing extended-precision numbers}
+%
+% \newcommand{\eTeXfrac}[2]{\left[\frac{#1}{#2}\right]}
+%
+% Divisions of extended-precision numbers are difficult to perform with
+% exact rounding: the technique used in \pkg{l3fp-basics} for $16$-digit
+% floating point numbers does not generalize easily to $24$-digit
+% numbers. Thankfully, there is no need for exact rounding.
+%
+% Let us call \meta{n} the numerator and \meta{d} the denominator.
+% After a simple normalization step, we can assume that
+% $\meta{n}\in[0.1,1)$ and $\meta{d}\in[0.1,1)$, and compute
+% $\meta{n}/(10\meta{d})\in(0.01,1)$. In terms of the $6$~blocks of
+% digits $\meta{n_1}\cdots\meta{n_6}$ and the $6$~blocks
+% $\meta{d_1}\cdots\meta{d_6}$, the condition translates to
+% $\meta{n_1},\meta{d_1}\in[1000,9999]$.
+%
+% We first find an integer estimate $a \simeq 10^{8} / \meta{d}$ by
+% computing
+% \begin{align*}
+% \alpha &= \eTeXfrac{10^{9}}{\meta{d_1}+1} \\
+% \beta &= \eTeXfrac{10^{9}}{\meta{d_1}} \\
+% a &= 10^{3} \alpha + (\beta-\alpha) \cdot
+% \left(10^{3}-\eTeXfrac{\meta{d_2}}{10}\right) - 1250,
+% \end{align*}
+% where $\eTeXfrac{\bullet}{\bullet}$ denotes \eTeX{}'s rounding
+% division, which rounds ties away from zero. The idea is to
+% interpolate between $10^{3}\alpha$ and $10^{3}\beta$ with a parameter
+% $\meta{d_2}/10^{4}$, so that when $\meta{d_2}=0$ one gets $a =
+% 10^{3}\beta-1250 \simeq 10^{12} / \meta{d_1} \simeq 10^{8} /
+% \meta{d}$, while when $\meta{d_2}=9999$ one gets $a =
+% 10^{3}\alpha-1250 \simeq 10^{12} / (\meta{d_1} + 1) \simeq 10^{8} /
+% \meta{d}$. The shift by $1250$ helps to ensure that $a$ is an
+% underestimate of the correct value. We shall prove that
+% \[
+% 1 - 1.755\cdot 10^{-5} < \frac{\meta{d}a}{10^{8}} < 1 .
+% \]
+% We can then compute the inverse of $\meta{d}a/10^{8} = 1 - \epsilon$
+% using the relation $1/(1-\epsilon) \simeq (1+\epsilon)(1+\epsilon^{2})
+% + \epsilon^{4}$, which is correct up to a relative error of
+% $\epsilon^5 < 1.6\cdot 10^{-24}$. This allows us to find the desired
+% ratio as
+% \[
+% \frac{\meta{n}}{\meta{d}}
+% = \frac{\meta{n}a}{10^{8}}
+% \bigl( (1+\epsilon)(1+\epsilon^{2}) + \epsilon^{4}\bigr) .
+% \]
+%
+% Let us prove the upper bound first (multiplied by $10^{15}$). Note
+% that $10^{7} \meta{d} < 10^{3} \meta{d_1} + 10^{-1} (\meta{d_2} + 1)$,
+% and that \eTeX{}'s division $\eTeXfrac{\meta{d_2}}{10}$ underestimates
+% $10^{-1}(\meta{d_2} + 1)$ by $0.5$ at most, as can be checked
+% for each possible last digit of \meta{d_2}. Then,
+% \begin{align}
+% 10^{7} \meta{d}a
+% & <
+% \left(10^{3}\meta{d_1}
+% + \eTeXfrac{\meta{d_2}}{10} + \frac{1}{2}\right)
+% \left(\left(10^{3}-\eTeXfrac{\meta{d_2}}{10}\right) \beta
+% + \eTeXfrac{\meta{d_2}}{10} \alpha - 1250\right)
+% \\
+% & <
+% \left(10^{3}\meta{d_1}
+% + \eTeXfrac{\meta{d_2}}{10} + \frac{1}{2}\right)
+% \\ & \qquad
+% \left(
+% \left(10^{3}-\eTeXfrac{\meta{d_2}}{10}\right)
+% \left(\frac{10^{9}}{\meta{d_1}} + \frac{1}{2} \right)
+% + \eTeXfrac{\meta{d_2}}{10}
+% \left(\frac{10^{9}}{\meta{d_1}+1} + \frac{1}{2} \right)
+% - 1250
+% \right)
+% \\
+% & <
+% \left(10^{3} \meta{d_1}
+% + \eTeXfrac{\meta{d_2}}{10} + \frac{1}{2}\right)
+% \left(\frac{10^{12}}{\meta{d_1}}
+% - \eTeXfrac{\meta{d_2}}{10}
+% \frac{10^{9}}{\meta{d_1}(\meta{d_1}+1)}
+% - 750\right)
+% \end{align}
+% We recognize a quadratic polynomial in $[\meta{d_2}/10]$ with a
+% negative leading coefficient: this polynomial is bounded above,
+% according to $([\meta{d_2}/10]+a)(b-c[\meta{d_2}/10]) \leq
+% (b+ca)^2/(4c)$. Hence,
+% \[
+% 10^{7} \meta{d}a
+% < \frac{10^{15}}{\meta{d_1}(\meta{d_1}+1)} \left(
+% \meta{d_1} + \frac{1}{2} + \frac{1}{4} 10^{-3}
+% - \frac{3}{8} \cdot 10^{-9} \meta{d_1}(\meta{d_1}+1) \right)^2
+% \]
+% Since \meta{d_1} takes integer values within $[1000,9999]$, it is a
+% simple programming exercise to check that the squared expression is
+% always less than $\meta{d_1}(\meta{d_1}+1)$, hence $10^{7} \meta{d} a
+% < 10^{15}$. The upper bound is proven. We also find that
+% $\frac{3}{8}$ can be replaced by slightly smaller numbers, but nothing
+% less than $0.374563\ldots$, and going back through the derivation of
+% the upper bound, we find that $1250$ is as small a shift as we can
+% obtain without breaking the bound.
+%
+% Now, the lower bound. The same computation as for the upper bound
+% implies
+% \[
+% 10^{7} \meta{d}a
+% > \left(10^{3} \meta{d_1} + \eTeXfrac{\meta{d_2}}{10}
+% - \frac{1}{2}\right)
+% \left(\frac{10^{12}}{\meta{d_1}}
+% - \eTeXfrac{\meta{d_2}}{10} \frac{10^{9}}{\meta{d_1}(\meta{d_1}+1)}
+% - 1750\right)
+% \]
+% This time, we want to find the minimum of this quadratic polynomial.
+% Since the leading coefficient is still negative, the minimum is
+% reached for one of the extreme values $[y/10]=0$ or $[y/10]=100$, and
+% we easily check the bound for those values.
+%
+% We have proven that the algorithm gives us a precise enough
+% answer. Incidentally, the upper bound that we derived tells us that
+% $a < 10^{8}/\meta{d} \leq 10^{9}$, hence we can compute $a$ safely as
+% a \TeX{} integer, and even add $10^{9}$ to it to ease grabbing of all
+% the digits. The lower bound implies $10^{8} - 1755 < a$, which we do
+% not care about.
+%
+% ^^A todo: provide ep_inv, not ep_div?
+% ^^A todo: make extra sure that the result's first block cannot be 99
+% ^^A todo: doc that neither operand may be zero (or fix ep_to_ep)
+% \begin{macro}[EXP]{\@@_ep_div:wwwwn}
+% Compute the ratio of two extended-precision numbers. The result is
+% an extended-precision number whose first block lies in the range
+% $[100,9999]$, and is placed after the \meta{continuation} once we
+% are done. First normalize the inputs so that both first block lie
+% in $[1000,9999]$, then call \cs{@@_ep_div_esti:wwwwn}
+% \meta{denominator} \meta{numerator}, responsible for estimating the
+% inverse of the denominator.
+% \begin{macrocode}
+\cs_new:Npn \@@_ep_div:wwwwn #1,#2; #3,#4;
+ {
+ \@@_ep_to_ep:wwN #1,#2;
+ \@@_fixed_continue:wn
+ {
+ \@@_ep_to_ep:wwN #3,#4;
+ \@@_ep_div_esti:wwwwn
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_ep_div_esti:wwwwn,
+% \@@_ep_div_estii:wwnnwwn,
+% \@@_ep_div_estiii:NNNNNwwwn
+% }
+% The \texttt{esti} function evaluates $\alpha=10^{9} / (\meta{d_1} +
+% 1)$, which is used twice in the expression for $a$, and combines the
+% exponents |#1| and~|#4| (with a shift by~$1$ because we later compute
+% $\meta{n}/(10\meta{d})$. Then the \texttt{estii} function evaluates
+% $10^{9} + a$, and puts the exponent~|#2| after the
+% continuation~|#7|: from there on we can forget exponents and focus
+% on the mantissa. The \texttt{estiii} function multiplies the
+% denominator~|#7| by $10^{-8}a$ (obtained as $a$ split into the
+% single digit~|#1| and two blocks of $4$~digits, |#2#3#4#5|
+% and~|#6|). The result $10^{-8}a\meta{d}=(1-\epsilon)$, and a
+% partially packed $10^{-9}a$ (as a block of four digits, and five
+% individual digits, not packed by lack of available macro parameters
+% here) are passed to \cs{@@_ep_div_epsi:wnNNNNn}, which computes
+% $10^{-9}a/(1-\epsilon)$, that is, $1/(10\meta{d})$ and we finally
+% multiply this by the numerator~|#8|.
+% \begin{macrocode}
+\cs_new:Npn \@@_ep_div_esti:wwwwn #1,#2#3; #4,
+ {
+ \exp_after:wN \@@_ep_div_estii:wwnnwwn
+ \int_value:w \@@_int_eval:w 10 0000 0000 / ( #2 + 1 )
+ \exp_after:wN ;
+ \int_value:w \@@_int_eval:w #4 - #1 + 1 ,
+ {#2} #3;
+ }
+\cs_new:Npn \@@_ep_div_estii:wwnnwwn #1; #2,#3#4#5; #6; #7
+ {
+ \exp_after:wN \@@_ep_div_estiii:NNNNNwwwn
+ \int_value:w \@@_int_eval:w 10 0000 0000 - 1750
+ + #1 000 + (10 0000 0000 / #3 - #1) * (1000 - #4 / 10) ;
+ {#3}{#4}#5; #6; { #7 #2, }
+ }
+\cs_new:Npn \@@_ep_div_estiii:NNNNNwwwn 1#1#2#3#4#5#6; #7;
+ {
+ \@@_fixed_mul_short:wwn #7; {#1}{#2#3#4#5}{#6};
+ \@@_ep_div_epsi:wnNNNNNn {#1#2#3#4}#5#6
+ \@@_fixed_mul:wwn
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_ep_div_epsi:wnNNNNNn,
+% \@@_ep_div_eps_pack:NNNNNw,
+% \@@_ep_div_epsii:wwnNNNNNn,
+% }
+% The bounds shown above imply that the \texttt{epsi} function's first
+% operand is $(1-\epsilon)$ with $\epsilon\in[0,1.755\cdot 10^{-5}]$.
+% The \texttt{epsi} function computes $\epsilon$ as $1-(1-\epsilon)$.
+% Since $\epsilon<10^{-4}$, its first block vanishes and there is no
+% need to explicitly use~|#1| (which is $9999$). Then \texttt{epsii}
+% evaluates $10^{-9}a/(1-\epsilon)$ as
+% $(1+\epsilon^2)(1+\epsilon)(10^{-9}a \epsilon) + 10^{-9}a$.
+% Importantly, we compute $10^{-9}a \epsilon$ before multiplying it
+% with the rest, rather than multiplying by $\epsilon$ and then
+% $10^{-9}a$, as this second option loses more precision. Also, the
+% combination of \texttt{short_mul} and \texttt{div_myriad} is both
+% faster and more precise than a simple \texttt{mul}.
+% \begin{macrocode}
+\cs_new:Npn \@@_ep_div_epsi:wnNNNNNn #1#2#3#4#5#6;
+ {
+ \exp_after:wN \@@_ep_div_epsii:wwnNNNNNn
+ \int_value:w \@@_int_eval:w 1 9998 - #2
+ \exp_after:wN \@@_ep_div_eps_pack:NNNNNw
+ \int_value:w \@@_int_eval:w 1 9999 9998 - #3#4
+ \exp_after:wN \@@_ep_div_eps_pack:NNNNNw
+ \int_value:w \@@_int_eval:w 2 0000 0000 - #5#6 ; ;
+ }
+\cs_new:Npn \@@_ep_div_eps_pack:NNNNNw #1#2#3#4#5#6;
+ { + #1 ; {#2#3#4#5} {#6} }
+\cs_new:Npn \@@_ep_div_epsii:wwnNNNNNn 1#1; #2; #3#4#5#6#7#8
+ {
+ \@@_fixed_mul:wwn {0000}{#1}#2; {0000}{#1}#2;
+ \@@_fixed_add_one:wN
+ \@@_fixed_mul:wwn {10000} {#1} #2 ;
+ {
+ \@@_fixed_mul_short:wwn {0000}{#1}#2; {#3}{#4#5#6#7}{#8000};
+ \@@_fixed_div_myriad:wn
+ \@@_fixed_mul:wwn
+ }
+ \@@_fixed_add:wwn {#3}{#4#5#6#7}{#8000}{0000}{0000}{0000};
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Inverse square root of extended precision numbers}
+%
+% The idea here is similar to division. Normalize the input,
+% multiplying by powers of $100$ until we have $x\in[0.01,1)$. Then
+% find an integer approximation $r \in [101, 1003]$ of
+% $10^{2}/\sqrt{x}$, as the fixed point of iterations of the Newton
+% method: essentially $r \mapsto (r + 10^{8} / (x_{1} r)) / 2$, starting
+% from a guess that optimizes the number of steps before convergence.
+% In fact, just as there is a slight shift when computing divisions to
+% ensure that some inequalities hold, we replace $10^{8}$ by a
+% slightly larger number which ensures that $r^2 x \geq 10^{4}$.
+% This also causes $r \in [101, 1003]$. Another correction to the above
+% is that the input is actually normalized to $[0.1,1)$, and we use
+% either $10^{8}$ or $10^{9}$ in the Newton method, depending on the
+% parity of the exponent. Skipping those technical hurdles, once we
+% have the approximation~$r$, we set $y = 10^{-4} r^{2} x$ (or rather,
+% the correct power of~$10$ to get $y\simeq 1$) and compute $y^{-1/2}$
+% through another application of Newton's method. This time, the
+% starting value is $z=1$, each step maps $z \mapsto z(1.5-0.5yz^2)$,
+% and we perform a fixed number of steps. Our final result combines~$r$
+% with $y^{-1/2}$ as $x^{-1/2} = 10^{-2} r y^{-1/2}$.
+%
+% ^^A todo: doc that the operand may not be zero (or fix ep_to_ep above)
+% \begin{macro}[EXP]{\@@_ep_isqrt:wwn}
+% \begin{macro}[EXP]
+% {\@@_ep_isqrt_aux:wwn, \@@_ep_isqrt_auxii:wwnnnwn}
+% First normalize the input, then check the parity of the
+% exponent~|#1|. If it is even, the result's exponent will be
+% $-|#1|/2$, otherwise it will be $(|#1|-1)/2$ (except in the case
+% where the input was an exact power of $100$). The \texttt{auxii}
+% function receives as~|#1| the result's exponent just computed, as
+% |#2| the starting value for the iteration giving~$r$ (the
+% values~$168$ and~$535$ lead to the least number of iterations before
+% convergence, on average), as |#3| and~|#4| one empty argument and
+% one~|0|, depending on the parity of the original exponent, as |#5|
+% and~|#6| the normalized mantissa ($|#5|\in[1000,9999]$), and as |#7|
+% the continuation. It sets up the iteration giving~$r$: the
+% \texttt{esti} function thus receives the initial two guesses |#2|
+% and~$0$, an approximation~|#5| of~$10^{4}x$ (its first block of
+% digits), and the empty/zero arguments |#3| and~|#4|, followed by the
+% mantissa and an altered continuation where we have stored the
+% result's exponent.
+% \begin{macrocode}
+\cs_new:Npn \@@_ep_isqrt:wwn #1,#2;
+ {
+ \@@_ep_to_ep:wwN #1,#2;
+ \@@_ep_isqrt_auxi:wwn
+ }
+\cs_new:Npn \@@_ep_isqrt_auxi:wwn #1,
+ {
+ \exp_after:wN \@@_ep_isqrt_auxii:wwnnnwn
+ \int_value:w \@@_int_eval:w
+ \int_if_odd:nTF {#1}
+ { (1 - #1) / 2 , 535 , { 0 } { } }
+ { 1 - #1 / 2 , 168 , { } { 0 } }
+ }
+\cs_new:Npn \@@_ep_isqrt_auxii:wwnnnwn #1, #2, #3#4 #5#6; #7
+ {
+ \@@_ep_isqrt_esti:wwwnnwn #2, 0, #5, {#3} {#4}
+ {#5} #6 ; { #7 #1 , }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_ep_isqrt_esti:wwwnnwn,
+% \@@_ep_isqrt_estii:wwwnnwn,
+% \@@_ep_isqrt_estiii:NNNNNwwwn
+% }
+% If the last two approximations gave the same result, we are done:
+% call the \texttt{estii} function to clean up. Otherwise, evaluate
+% $(\meta{prev} + 1.005 \cdot 10^{\text{$8$ or $9$}} / (\meta{prev}
+% \cdot x)) / 2$, as the next approximation: omitting the $1.005$
+% factor, this would be Newton's method. We can check by brute force
+% that if |#4| is empty (the original exponent was even), the process
+% computes an integer slightly larger than $100 / \sqrt{x}$, while if
+% |#4| is~$0$ (the original exponent was odd), the result is an
+% integer slightly larger than $100 / \sqrt{x/10}$. Once we are done,
+% we evaluate $100 r^2 / 2$ or $10 r^2 / 2$ (when the exponent is even
+% or odd, respectively) and feed that to \texttt{estiii}. This third
+% auxiliary finds $y_{\text{even}} / 2 = 10^{-4} r^2 x / 2$ or
+% $y_{\text{odd}} / 2 = 10^{-5} r^2 x / 2$ (again, depending on
+% earlier parity). A simple program shows that $y\in [1, 1.0201]$.
+% The number $y/2$ is fed to \cs{@@_ep_isqrt_epsi:wN}, which computes
+% $1/\sqrt{y}$, and we finally multiply the result by~$r$.
+% \begin{macrocode}
+\cs_new:Npn \@@_ep_isqrt_esti:wwwnnwn #1, #2, #3, #4
+ {
+ \if_int_compare:w #1 = #2 \exp_stop_f:
+ \exp_after:wN \@@_ep_isqrt_estii:wwwnnwn
+ \fi:
+ \exp_after:wN \@@_ep_isqrt_esti:wwwnnwn
+ \int_value:w \@@_int_eval:w
+ (#1 + 1 0050 0000 #4 / (#1 * #3)) / 2 ,
+ #1, #3, {#4}
+ }
+\cs_new:Npn \@@_ep_isqrt_estii:wwwnnwn #1, #2, #3, #4#5
+ {
+ \exp_after:wN \@@_ep_isqrt_estiii:NNNNNwwwn
+ \int_value:w \@@_int_eval:w 1000 0000 + #2 * #2 #5 * 5
+ \exp_after:wN , \int_value:w \@@_int_eval:w 10000 + #2 ;
+ }
+\cs_new:Npn \@@_ep_isqrt_estiii:NNNNNwwwn 1#1#2#3#4#5#6, 1#7#8; #9;
+ {
+ \@@_fixed_mul_short:wwn #9; {#1} {#2#3#4#5} {#600} ;
+ \@@_ep_isqrt_epsi:wN
+ \@@_fixed_mul_short:wwn {#7} {#80} {0000} ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_ep_isqrt_epsi:wN, \@@_ep_isqrt_epsii:wwN}
+% Here, we receive a fixed point number $y/2$ with $y\in[1,1.0201]$.
+% Starting from $z = 1$ we iterate $z \mapsto z(3/2 - z^2 y/2)$. In
+% fact, we start from the first iteration $z=3/2-y/2$ to avoid useless
+% multiplications. The \texttt{epsii} auxiliary receives $z$ as~|#1|
+% and $y$ as~|#2|.
+% \begin{macrocode}
+\cs_new:Npn \@@_ep_isqrt_epsi:wN #1;
+ {
+ \@@_fixed_sub:wwn {15000}{0000}{0000}{0000}{0000}{0000}; #1;
+ \@@_ep_isqrt_epsii:wwN #1;
+ \@@_ep_isqrt_epsii:wwN #1;
+ \@@_ep_isqrt_epsii:wwN #1;
+ }
+\cs_new:Npn \@@_ep_isqrt_epsii:wwN #1; #2;
+ {
+ \@@_fixed_mul:wwn #1; #1;
+ \@@_fixed_mul_sub_back:wwwn #2;
+ {15000}{0000}{0000}{0000}{0000}{0000};
+ \@@_fixed_mul:wwn #1;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Converting from fixed point to floating point}
+% ^^A todo: doc
+%
+% After computing Taylor series, we wish to convert the result from
+% extended precision (with or without an exponent) to the public
+% floating point format. The functions here should be called within an
+% integer expression for the overall exponent of the floating point.
+%
+% \begin{macro}[rEXP]{\@@_ep_to_float_o:wwN, \@@_ep_inv_to_float_o:wwN}
+% An extended-precision number is simply a comma-delimited exponent
+% followed by a fixed point number. Leave the exponent in the current
+% integer expression then convert the fixed point number.
+% \begin{macrocode}
+\cs_new:Npn \@@_ep_to_float_o:wwN #1,
+ { + \@@_int_eval:w #1 \@@_fixed_to_float_o:wN }
+\cs_new:Npn \@@_ep_inv_to_float_o:wwN #1,#2;
+ {
+ \@@_ep_div:wwwwn 1,{1000}{0000}{0000}{0000}{0000}{0000}; #1,#2;
+ \@@_ep_to_float_o:wwN
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_fixed_inv_to_float_o:wN}
+% Another function which reduces to converting an extended precision
+% number to a float.
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_inv_to_float_o:wN
+ { \@@_ep_inv_to_float_o:wwN 0, }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_fixed_to_float_rad_o:wN}
+% Converts the fixed point number~|#1| from degrees to radians then to
+% a floating point number. This could perhaps remain in
+% \pkg{l3fp-trig}.
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_to_float_rad_o:wN #1;
+ {
+ \@@_fixed_mul:wwn #1; {5729}{5779}{5130}{8232}{0876}{7981};
+ { \@@_ep_to_float_o:wwN 2, }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A todo: make exponents end in ',' consistently throughout l3fp
+% \begin{macro}[rEXP]
+% {\@@_fixed_to_float_o:wN, \@@_fixed_to_float_o:Nw}
+% \begin{syntax}
+% \ldots{} \cs{@@_int_eval:w} \meta{exponent} \cs{@@_fixed_to_float_o:wN} \Arg{a_1} \Arg{a_2} \Arg{a_3} \Arg{a_4} \Arg{a_5} \Arg{a_6} |;| \meta{sign}
+% \end{syntax}
+% yields
+% \begin{quote}
+% \meta{exponent'} |;| \Arg{a'_1} \Arg{a'_2} \Arg{a'_3} \Arg{a'_4} |;|
+% \end{quote}
+% And the \texttt{to_fixed} version gives six brace groups instead of
+% $4$, ensuring that $1000\leq\meta{a'_1}\leq 9999$. At this stage, we
+% know that \meta{a_1} is positive (otherwise, it is sign of an error
+% before), and we assume that it is less than $10^8$.\footnote{Bruno:
+% I must double check this assumption.}
+%
+%^^A todo: round properly when rounding to infinity: I need the sign.
+% \begin{macrocode}
+\cs_new:Npn \@@_fixed_to_float_o:Nw #1#2;
+ { \@@_fixed_to_float_o:wN #2; #1 }
+\cs_new:Npn \@@_fixed_to_float_o:wN #1#2#3#4#5#6; #7
+ { % for the 8-digit-at-the-start thing
+ + \@@_int_eval:w \c_@@_block_int
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_fixed_to_loop:N
+ \exp_after:wN \use_none:n
+ \int_value:w \@@_int_eval:w
+ 1 0000 0000 + #1 \exp_after:wN \@@_use_none_stop_f:n
+ \int_value:w 1#2 \exp_after:wN \@@_use_none_stop_f:n
+ \int_value:w 1#3#4 \exp_after:wN \@@_use_none_stop_f:n
+ \int_value:w 1#5#6
+ \exp_after:wN ;
+ \exp_after:wN ;
+ }
+\cs_new:Npn \@@_fixed_to_loop:N #1
+ {
+ \if_meaning:w 0 #1
+ - 1
+ \exp_after:wN \@@_fixed_to_loop:N
+ \else:
+ \exp_after:wN \@@_fixed_to_loop_end:w
+ \exp_after:wN #1
+ \fi:
+ }
+\cs_new:Npn \@@_fixed_to_loop_end:w #1 #2 ;
+ {
+ \if_meaning:w ; #1
+ \exp_after:wN \@@_fixed_to_float_zero:w
+ \else:
+ \exp_after:wN \@@_pack_twice_four:wNNNNNNNN
+ \exp_after:wN \@@_pack_twice_four:wNNNNNNNN
+ \exp_after:wN \@@_fixed_to_float_pack:ww
+ \exp_after:wN ;
+ \fi:
+ #1 #2 0000 0000 0000 0000 ;
+ }
+\cs_new:Npn \@@_fixed_to_float_zero:w ; 0000 0000 0000 0000 ;
+ {
+ - 2 * \c_@@_max_exponent_int ;
+ {0000} {0000} {0000} {0000} ;
+ }
+\cs_new:Npn \@@_fixed_to_float_pack:ww #1 ; #2#3 ; ;
+ {
+ \if_int_compare:w #2 > 4 \exp_stop_f:
+ \exp_after:wN \@@_fixed_to_float_round_up:wnnnnw
+ \fi:
+ ; #1 ;
+ }
+\cs_new:Npn \@@_fixed_to_float_round_up:wnnnnw ; #1#2#3#4 ;
+ {
+ \exp_after:wN \@@_basics_pack_high:NNNNNw
+ \int_value:w \@@_int_eval:w 1 #1#2
+ \exp_after:wN \@@_basics_pack_low:NNNNNw
+ \int_value:w \@@_int_eval:w 1 #3#4 + 1 ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintChanges
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-functions.dtx b/macros/latex-dev/required/l3kernel/l3fp-functions.dtx
new file mode 100644
index 0000000000..f6c9ec346f
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-functions.dtx
@@ -0,0 +1,288 @@
+% \iffalse
+%
+%% File l3fp-functions.dtx (C) Copyright 2012-2018,2020,2021,2023 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full]{l3doc}
+\usepackage{amsmath}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-functions} module\\ Floating point functions^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp-functions} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% \subsection{Declaring functions}
+%
+% \begin{macro}{\fp_new_function:n}
+% \begin{macro}{\@@_new_function:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \fp_new_function:n #1
+ { \exp_args:No \@@_new_function:n { \tl_to_str:n {#1} } }
+\cs_new_protected:Npn \@@_new_function:n #1
+ {
+ \@@_id_if_invalid:nTF {#1}
+ { \msg_error:nnn { fp } { id-invalid } {#1} }
+ {
+ \cs_if_exist:cT { @@_parse_word_#1:N }
+ {
+ \msg_error:nnn
+ { fp } { id-already-defined } {#1}
+ \cs_undefine:c { @@_parse_word_#1:N }
+ \cs_undefine:c { @@_#1_o:w }
+ }
+ \@@_function_set_parsing:Nn \cs_gset_eq:NN {#1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_function_set_parsing:Nn, \@@_function_set_parsing_aux:NNn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_function_set_parsing:Nn #1#2
+ {
+ \exp_args:NNc \@@_function_set_parsing_aux:NNn #1
+ { @@_parse_word_#2:N } {#2}
+ }
+\cs_new_protected:Npn \@@_function_set_parsing_aux:NNn #1#2#3
+ {
+ \cs_set:Npe \@@_tmp:w
+ {
+ \exp_not:N \@@_parse_function:NNN
+ \exp_not:N \@@_function_o:w
+ \exp_not:c { @@_#3_o:w }
+ }
+ \cs_if_eq:NNF #2 \@@_tmp:w
+ {
+ \cs_if_exist:NTF #2
+ {
+ \msg_warning:nnnn
+ { fp } { id-used-elsewhere } {#3} { function }
+ #1 #2 \@@_tmp:w
+ }
+ {
+ \cs_new_eq:NN #2 \scan_stop: % to declare the function
+ #1 #2 \@@_tmp:w
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_function_o:w}
+% \begin{macrocode}
+\cs_new:Npn \@@_function_o:w #1#2 @
+ {
+ \cs_if_exist:NTF #1
+ { #1 #2 @ }
+ {
+ \exp_after:wN \s_@@_symbolic
+ \exp_after:wN \@@_symbolic_chk:w
+ \exp_after:wN \@@_function_o:w
+ \exp_after:wN #1
+ \exp_after:wN ,
+ \exp_after:wN {
+ \exp:w \exp_end_continue_f:w
+ \@@_exp_after_array_f:w #2 \s_@@_expr_stop
+ \exp_after:wN
+ }
+ \exp_after:wN ;
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Defining functions by their expression}
+%
+% \begin{variable}{\l_@@_function_arg_int}
+% Labels the arguments of a function being defined.
+% \begin{macrocode}
+\int_new:N \l_@@_function_arg_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\fp_set_function:nnn}
+% \begin{macro}{\@@_set_function:Nnnn}
+% \begin{syntax}
+% \cs{fp_set_function:nnn} \Arg{identifier}
+% \Arg{comma-list of variables} \Arg{expression}
+% \end{syntax}
+% Defines the \meta{identifier} to stand for a function which expects
+% some arguments defined by the \meta{comma-list of variables}, and
+% evaluates to the \meta{expression}.
+% \begin{macrocode}
+\cs_new_protected:Npn \fp_set_function:nnn #1
+ {
+ \exp_args:NNo \@@_set_function:Nnnn \cs_set_eq:cN
+ { \tl_to_str:n {#1} }
+ }
+\cs_new_protected:Npn \@@_set_function:Nnnn #1#2#3#4
+ {
+ \@@_id_if_invalid:nTF {#2}
+ { \msg_error:nnn { fp } { id-invalid } {#2} }
+ {
+ \cs_if_exist:cF { @@_parse_word_#2:N }
+ { \@@_function_set_parsing:Nn \cs_set_eq:NN {#2} }
+ \group_begin:
+ \int_zero:N \l_@@_function_arg_int
+ \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#3} }
+ {
+ \int_incr:N \l_@@_function_arg_int
+ \exp_args:Ne \@@_clear_variable_aux:n
+ {
+ \c_underscore_str \tex_romannumeral:D \l_@@_function_arg_int
+ }
+ \fp_clear_variable:n {##1}
+ \cs_set_nopar:cpe { l_@@_variable_##1_fp }
+ {
+ \exp_not:N \s__fp_symbolic
+ \exp_not:N \@@_symbolic_chk:w
+ \exp_not:N \@@_function_arg_o:w
+ \int_use:N \l_@@_function_arg_int
+ ########1 , { } ;
+ }
+ }
+ \cs_set:Npn \@@_function_arg_o:w ##1 @
+ {
+ \exp_after:wN \s_@@_symbolic
+ \exp_after:wN \@@_symbolic_chk:w
+ \exp_after:wN \@@_function_arg_o:w
+ \tex_romannumeral:D
+ \@@_exp_after_symbolic_loop:N ##1
+ { , \tex_romannumeral:D \use_none:nn }
+ \exp_after:wN \c_zero_int
+ \exp_after:wN { \exp_after:wN } \exp_after:wN ;
+ }
+ \fp_set:Nn \l_@@_symbolic_fp {#4}
+ \use:e
+ {
+ \exp_not:n { \cs_gset:Npn \@@_tmp:w ##1 }
+ { \exp_not:o { \l_@@_symbolic_fp } }
+ }
+ \use:e
+ {
+ \exp_not:n { \cs_gset:Npn \@@_tmp:w ##1 @ }
+ {
+ \exp_not:N \@@_exp_after_symbolic_f:nw
+ \exp_not:n { { \exp_after:wN \exp_stop_f: } }
+ \exp_not:o { \@@_tmp:w { . , {##1} } }
+ }
+ }
+ \group_end:
+ #1 { @@_#2_o:w } \@@_tmp:w
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_function_arg_o:w,
+% \@@_function_arg_few:w,
+% \@@_function_arg_get:w
+% }
+% \begin{macrocode}
+\cs_new:Npn \@@_function_arg_o:w #1. #2
+ {
+ \if_meaning:w @ #2
+ \exp_after:wN \@@_function_arg_few:w
+ \fi:
+ \if_int_compare:w #1 = \c_one_int
+ \exp_after:wN \@@_function_arg_get:w
+ \fi:
+ \@@_use_i_until_s:nw
+ {
+ \exp_after:wN \@@_function_arg_o:w
+ \int_value:w \int_eval:n { #1 - 1 } .
+ }
+ #2
+ }
+\cs_new:Npn \@@_function_arg_few:w #1 @ { \exp_after:wN \c_nan_fp }
+\cs_new:Npn \@@_function_arg_get:w #1#2#3; #4 @
+ {
+ \@@_exp_after_array_f:w #3; \s_@@_expr_stop
+ \exp_after:wN \exp_stop_f:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_clear_function:n}
+% \begin{macro}{\@@_clear_function:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \fp_clear_function:n #1
+ { \exp_args:No \@@_clear_function:n { \tl_to_str:n {#1} } }
+\cs_new_protected:Npn \@@_clear_function:n #1
+ {
+ \@@_id_if_invalid:nTF {#1}
+ { \msg_error:nnn { fp } { id-invalid } {#1} }
+ {
+ \cs_set_eq:cN { @@_#1_o:w } \tex_undefine:D
+ \@@_function_set_parsing:Nn \cs_set_eq:NN {#1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% ^^A todo: add check for number of args
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-logic.dtx b/macros/latex-dev/required/l3kernel/l3fp-logic.dtx
new file mode 100644
index 0000000000..9df6a4730a
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-logic.dtx
@@ -0,0 +1,750 @@
+% \iffalse meta-comment
+%
+%% File: l3fp-logic.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-logic} module\\
+% Floating point conditionals^^A
+% }
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp-logic} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% \begin{macro}[EXP]{\@@_parse_word_max:N , \@@_parse_word_min:N}
+% Those functions may receive a variable number of arguments.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_word_max:N
+ { \@@_parse_function:NNN \@@_minmax_o:Nw 2 }
+\cs_new:Npn \@@_parse_word_min:N
+ { \@@_parse_function:NNN \@@_minmax_o:Nw 0 }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Syntax of internal functions}
+%
+% \begin{itemize}
+% \item \cs{@@_compare_npos:nwnw} \Arg{expo_1} \meta{body_1} |;|
+% \Arg{expo_2} \meta{body_2} |;|
+% \item \cs{@@_minmax_o:Nw} \meta{sign} \meta{floating point array}
+% \item \cs{@@_not_o:w} |?| \meta{floating point array} (with one floating point number only)
+% \item \cs{@@_&_o:ww} \meta{floating point} \meta{floating point}
+% \item \cs{@@_|_o:ww} \meta{floating point} \meta{floating point}
+% \item \cs{@@_ternary:NwwN}, \cs{@@_ternary_auxi:NwwN},
+% \cs{@@_ternary_auxii:NwwN} have to be understood.
+% \end{itemize}
+%
+% \subsection{Tests}
+%
+% \begin{macro}[pTF]{\fp_if_exist:N, \fp_if_exist:c}
+% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \fp_if_exist:N \cs_if_exist:N { TF , T , F , p }
+\prg_new_eq_conditional:NNn \fp_if_exist:c \cs_if_exist:c { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\fp_if_nan:n}
+% Evaluate and check if the result is a floating point of the same
+% kind as \nan{}.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \fp_if_nan:n #1 { TF , T , F , p }
+ {
+ \if:w 3 \exp_last_unbraced:Nf \@@_kind:w { \@@_parse:n {#1} }
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Comparison}
+%
+% \begin{macro}[pTF, EXP]{\fp_compare:n}
+% \begin{macro}[EXP]{\@@_compare_return:w}
+% Within floating point expressions, comparison operators are treated
+% as operations, so we evaluate |#1|, then compare with $\pm 0$.
+% Tuples are \texttt{true}.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \fp_compare:n #1 { p , T , F , TF }
+ {
+ \exp_after:wN \@@_compare_return:w
+ \exp:w \exp_end_continue_f:w \@@_parse:n {#1}
+ }
+\cs_new:Npn \@@_compare_return:w #1#2#3;
+ {
+ \if_charcode:w 0
+ \@@_if_type_fp:NTwFw
+ #1 { \@@_use_i_delimit_by_s_stop:nw #3 \s_@@_stop }
+ \s_@@ 1 \s_@@_stop
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF, EXP]{\fp_compare:nNn}
+% \begin{macro}[EXP]{\@@_compare_aux:wn}
+% Evaluate |#1| and |#3|, using an auxiliary to expand both, and feed
+% the two floating point numbers swapped to \cs{@@_compare_back_any:ww},
+% defined below. Compare the result with |`#2-`=|, which is $-1$ for
+% |<|, $0$ for |=|, $1$ for |>| and $2$ for |?|.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \fp_compare:nNn #1#2#3 { p , T , F , TF }
+ {
+ \if_int_compare:w
+ \exp_after:wN \@@_compare_aux:wn
+ \exp:w \exp_end_continue_f:w \@@_parse:n {#1} {#3}
+ = \@@_int_eval:w `#2 - `= \@@_int_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:Npn \@@_compare_aux:wn #1; #2
+ {
+ \exp_after:wN \@@_compare_back_any:ww
+ \exp:w \exp_end_continue_f:w \@@_parse:n {#2} #1;
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_compare_back:ww, \@@_bcmp:ww, \@@_compare_back_any:ww, \@@_compare_nan:w}
+% \begin{quote}
+% \cs{@@_compare_back_any:ww} \meta{y} |;| \meta{x} |;|
+% \end{quote}
+% Expands (in the same way as \cs{int_eval:n}) to $-1$ if $x<y$, $0$
+% if $x=y$, $1$ if $x>y$, and $2$ otherwise (denoted as $x?y$). If
+% either operand is \texttt{nan}, stop the comparison with
+% \cs{@@_compare_nan:w} returning $2$. If $x$ is negative, swap the
+% outputs $1$ and $-1$ (\emph{i.e.}, $>$ and $<$); we can henceforth
+% assume that $x\geq 0$. If $y\geq 0$, and they have the same type,
+% either they are normal and we compare them with
+% \cs{@@_compare_npos:nwnw}, or they are equal. If $y\geq 0$, but of
+% a different type, the highest type is a larger number. Finally, if
+% $y\leq 0$, then $x>y$, unless both are zero.
+% \begin{macrocode}
+\cs_new:Npn \@@_compare_back:ww #1#2; #3#4;
+ {
+ \cs:w
+ @@
+ \@@_type_from_scan:N #1
+ _bcmp
+ \@@_type_from_scan:N #3
+ :ww
+ \cs_end:
+ #1#2; #3#4;
+ }
+\cs_new:Npn \@@_compare_back_any:ww #1#2; #3
+ {
+ \@@_if_type_fp:NTwFw
+ #1 { \@@_if_type_fp:NTwFw #3 \use_i:nn \s_@@ \use_ii:nn \s_@@_stop }
+ \s_@@ \use_ii:nn \s_@@_stop
+ \@@_compare_back:ww
+ {
+ \cs:w
+ @@
+ \@@_type_from_scan:N #1
+ _compare_back
+ \@@_type_from_scan:N #3
+ :ww
+ \cs_end:
+ }
+ #1#2 ; #3
+ }
+\cs_new:Npn \@@_bcmp:ww
+ \s_@@ \@@_chk:w #1 #2 #3;
+ \s_@@ \@@_chk:w #4 #5 #6;
+ {
+ \int_value:w
+ \if_meaning:w 3 #1 \exp_after:wN \@@_compare_nan:w \fi:
+ \if_meaning:w 3 #4 \exp_after:wN \@@_compare_nan:w \fi:
+ \if_meaning:w 2 #5 - \fi:
+ \if_meaning:w #2 #5
+ \if_meaning:w #1 #4
+ \if_meaning:w 1 #1
+ \@@_compare_npos:nwnw #6; #3;
+ \else:
+ 0
+ \fi:
+ \else:
+ \if_int_compare:w #4 < #1 - \fi: 1
+ \fi:
+ \else:
+ \if_int_compare:w #1#4 = \c_zero_int
+ 0
+ \else:
+ 1
+ \fi:
+ \fi:
+ \exp_stop_f:
+ }
+\cs_new:Npn \@@_compare_nan:w #1 \fi: \exp_stop_f: { 2 \exp_stop_f: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_compare_back_tuple:ww, \@@_tuple_compare_back:ww, \@@_tuple_compare_back_tuple:ww}
+% \begin{macro}[EXP]{\@@_tuple_compare_back_loop:w}
+% Tuple and floating point numbers are not comparable so return $2$ in
+% mixed cases or when tuples have a different number of items.
+% Otherwise compare pairs of items with \cs{@@_compare_back_any:ww}
+% and if any don't match return~$2$ (as \cs{int_value:w} |02|
+% \cs{exp_stop_f:}).
+% \begin{macrocode}
+\cs_new:Npn \@@_compare_back_tuple:ww #1; #2; { 2 }
+\cs_new:Npn \@@_tuple_compare_back:ww #1; #2; { 2 }
+\cs_new:Npn \@@_tuple_compare_back_tuple:ww
+ \s_@@_tuple \@@_tuple_chk:w #1;
+ \s_@@_tuple \@@_tuple_chk:w #2;
+ {
+ \int_compare:nNnTF { \@@_array_count:n {#1} } =
+ { \@@_array_count:n {#2} }
+ {
+ \int_value:w 0
+ \@@_tuple_compare_back_loop:w
+ #1 { \s_@@ \prg_break: } ; @
+ #2 { \s_@@ \prg_break: } ;
+ \prg_break_point:
+ \exp_stop_f:
+ }
+ { 2 }
+ }
+\cs_new:Npn \@@_tuple_compare_back_loop:w #1#2 ; #3 @ #4#5 ;
+ {
+ \use_none:n #1
+ \use_none:n #4
+ \if_int_compare:w
+ \@@_compare_back_any:ww #1 #2 ; #4 #5 ; = \c_zero_int
+ \else:
+ 2 \exp_after:wN \prg_break:
+ \fi:
+ \@@_tuple_compare_back_loop:w #3 @
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_compare_npos:nwnw}
+% \begin{macro}[EXP]{\@@_compare_significand:nnnnnnnn}
+% \begin{quote}
+% \cs{@@_compare_npos:nwnw}
+% \Arg{expo_1} \meta{body_1} |;|
+% \Arg{expo_2} \meta{body_2} |;|
+% \end{quote}
+% Within an \cs{int_value:w} \ldots{} \cs{exp_stop_f:} construction,
+% this expands to $0$ if the two numbers are equal, $-1$ if the first
+% is smaller, and $1$ if the first is bigger. First compare the
+% exponents: the larger one denotes the larger number. If they are
+% equal, we must compare significands. If both the first $8$ digits and
+% the next $8$ digits coincide, the numbers are equal. If only the
+% first $8$ digits coincide, the next $8$ decide. Otherwise, the
+% first $8$ digits are compared.
+% \begin{macrocode}
+\cs_new:Npn \@@_compare_npos:nwnw #1#2; #3#4;
+ {
+ \if_int_compare:w #1 = #3 \exp_stop_f:
+ \@@_compare_significand:nnnnnnnn #2 #4
+ \else:
+ \if_int_compare:w #1 < #3 - \fi: 1
+ \fi:
+ }
+\cs_new:Npn \@@_compare_significand:nnnnnnnn #1#2#3#4#5#6#7#8
+ {
+ \if_int_compare:w #1#2 = #5#6 \exp_stop_f:
+ \if_int_compare:w #3#4 = #7#8 \exp_stop_f:
+ 0
+ \else:
+ \if_int_compare:w #3#4 < #7#8 - \fi: 1
+ \fi:
+ \else:
+ \if_int_compare:w #1#2 < #5#6 - \fi: 1
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Floating point expression loops}
+%
+% \begin{macro}[rEXP]
+% {
+% \fp_do_until:nn, \fp_do_while:nn,
+% \fp_until_do:nn, \fp_while_do:nn
+% }
+% These are quite easy given the above functions. The |do_until| and
+% |do_while| versions execute the body, then test. The |until_do| and
+% |while_do| do it the other way round.
+% \begin{macrocode}
+\cs_new:Npn \fp_do_until:nn #1#2
+ {
+ #2
+ \fp_compare:nF {#1}
+ { \fp_do_until:nn {#1} {#2} }
+ }
+\cs_new:Npn \fp_do_while:nn #1#2
+ {
+ #2
+ \fp_compare:nT {#1}
+ { \fp_do_while:nn {#1} {#2} }
+ }
+\cs_new:Npn \fp_until_do:nn #1#2
+ {
+ \fp_compare:nF {#1}
+ {
+ #2
+ \fp_until_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \fp_while_do:nn #1#2
+ {
+ \fp_compare:nT {#1}
+ {
+ #2
+ \fp_while_do:nn {#1} {#2}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {
+% \fp_do_until:nNnn, \fp_do_while:nNnn,
+% \fp_until_do:nNnn, \fp_while_do:nNnn
+% }
+% As above but not using the |nNn| syntax.
+% \begin{macrocode}
+\cs_new:Npn \fp_do_until:nNnn #1#2#3#4
+ {
+ #4
+ \fp_compare:nNnF {#1} #2 {#3}
+ { \fp_do_until:nNnn {#1} #2 {#3} {#4} }
+ }
+\cs_new:Npn \fp_do_while:nNnn #1#2#3#4
+ {
+ #4
+ \fp_compare:nNnT {#1} #2 {#3}
+ { \fp_do_while:nNnn {#1} #2 {#3} {#4} }
+ }
+\cs_new:Npn \fp_until_do:nNnn #1#2#3#4
+ {
+ \fp_compare:nNnF {#1} #2 {#3}
+ {
+ #4
+ \fp_until_do:nNnn {#1} #2 {#3} {#4}
+ }
+ }
+\cs_new:Npn \fp_while_do:nNnn #1#2#3#4
+ {
+ \fp_compare:nNnT {#1} #2 {#3}
+ {
+ #4
+ \fp_while_do:nNnn {#1} #2 {#3} {#4}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\fp_step_function:nnnN, \fp_step_function:nnnc}
+% \begin{macro}[EXP]{\@@_step:wwwN, \@@_step_fp:wwwN}
+% \begin{macro}[EXP]{\@@_step:NnnnnN, \@@_step:NfnnnN}
+% The approach here is somewhat similar to
+% \cs{int_step_function:nnnN}. There are two subtleties: we use the
+% internal parser \cs{@@_parse:n} to avoid converting back and forth
+% from the internal representation; and (due to rounding) even a
+% non-zero step does not guarantee that the loop counter increases.
+% \begin{macrocode}
+\cs_new:Npn \fp_step_function:nnnN #1#2#3
+ {
+ \exp_after:wN \@@_step:wwwN
+ \exp:w \exp_end_continue_f:w \@@_parse_o:n {#1}
+ \exp:w \exp_end_continue_f:w \@@_parse_o:n {#2}
+ \exp:w \exp_end_continue_f:w \@@_parse:n {#3}
+ }
+\cs_generate_variant:Nn \fp_step_function:nnnN { nnnc }
+% \end{macrocode}
+% Only floating point numbers (not tuples) are allowed arguments.
+% Only \enquote{normal} floating points (not $\pm 0$,
+% $\pm\texttt{inf}$, \texttt{nan}) can be used as step; if positive,
+% call \cs{@@_step:NnnnnN} with argument |>| otherwise~|<|. This
+% function has one more argument than its integer counterpart, namely
+% the previous value, to catch the case where the loop has made no
+% progress. Conversion to decimal is done just before calling the
+% user's function.
+% \begin{macrocode}
+\cs_new:Npn \@@_step:wwwN #1#2; #3#4; #5#6; #7
+ {
+ \@@_if_type_fp:NTwFw #1 { } \s_@@ \prg_break: \s_@@_stop
+ \@@_if_type_fp:NTwFw #3 { } \s_@@ \prg_break: \s_@@_stop
+ \@@_if_type_fp:NTwFw #5 { } \s_@@ \prg_break: \s_@@_stop
+ \use_i:nnnn { \@@_step_fp:wwwN #1#2; #3#4; #5#6; #7 }
+ \prg_break_point:
+ \use:n
+ {
+ \@@_error:nfff { step-tuple } { \fp_to_tl:n { #1#2 ; } }
+ { \fp_to_tl:n { #3#4 ; } } { \fp_to_tl:n { #5#6 ; } }
+ }
+ }
+\cs_new:Npn \@@_step_fp:wwwN #1 ; \s_@@ \@@_chk:w #2#3#4 ; #5; #6
+ {
+ \token_if_eq_meaning:NNTF #2 1
+ {
+ \token_if_eq_meaning:NNTF #3 0
+ { \@@_step:NnnnnN > }
+ { \@@_step:NnnnnN < }
+ }
+ {
+ \token_if_eq_meaning:NNTF #2 0
+ {
+ \msg_expandable_error:nnn { kernel }
+ { zero-step } {#6}
+ }
+ {
+ \@@_error:nnfn { bad-step } { }
+ { \fp_to_tl:n { \s_@@ \@@_chk:w #2#3#4 ; } } {#6}
+ }
+ \use_none:nnnnn
+ }
+ { #1 ; } { \c_nan_fp } { \s_@@ \@@_chk:w #2#3#4 ; } { #5 ; } #6
+ }
+\cs_new:Npn \@@_step:NnnnnN #1#2#3#4#5#6
+ {
+ \fp_compare:nNnTF {#2} = {#3}
+ {
+ \@@_error:nffn { tiny-step }
+ { \fp_to_tl:n {#3} } { \fp_to_tl:n {#4} } {#6}
+ }
+ {
+ \fp_compare:nNnF {#2} #1 {#5}
+ {
+ \exp_args:Nf #6 { \@@_to_decimal_dispatch:w #2 }
+ \@@_step:NfnnnN
+ #1 { \@@_parse:n { #2 + #4 } } {#2} {#4} {#5} #6
+ }
+ }
+ }
+\cs_generate_variant:Nn \@@_step:NnnnnN { Nf }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_step_inline:nnnn, \fp_step_variable:nnnNn}
+% \begin{macro}{\@@_step:NNnnnn}
+% As for \cs{int_step_inline:nnnn}, create a global function and apply it,
+% following up with a break point.
+% \begin{macrocode}
+\cs_new_protected:Npn \fp_step_inline:nnnn
+ {
+ \int_gincr:N \g__kernel_prg_map_int
+ \exp_args:NNc \@@_step:NNnnnn
+ \cs_gset_protected:Npn
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
+ }
+\cs_new_protected:Npn \fp_step_variable:nnnNn #1#2#3#4#5
+ {
+ \int_gincr:N \g__kernel_prg_map_int
+ \exp_args:NNc \@@_step:NNnnnn
+ \cs_gset_protected:Npe
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
+ {#1} {#2} {#3}
+ {
+ \tl_set:Nn \exp_not:N #4 {##1}
+ \exp_not:n {#5}
+ }
+ }
+\cs_new_protected:Npn \@@_step:NNnnnn #1#2#3#4#5#6
+ {
+ #1 #2 ##1 {#6}
+ \fp_step_function:nnnN {#3} {#4} {#5} #2
+ \prg_break_point:Nn \scan_stop: { \int_gdecr:N \g__kernel_prg_map_int }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+\msg_new:nnn { fp } { step-tuple }
+ { Tuple~argument~in~fp_step_...~{#1}{#2}{#3}. }
+\msg_new:nnn { fp } { bad-step }
+ { Invalid~step~size~#2~for~function~#3. }
+\msg_new:nnn { fp } { tiny-step }
+ { Tiny~step~size~(#1+#2=#1)~for~function~#3. }
+% \end{macrocode}
+%
+% \subsection{Extrema}
+%
+% \begin{macro}[EXP]{\@@_minmax_o:Nw, \@@_minmax_aux_o:Nw}
+% First check all operands are floating point numbers.
+% The argument~|#1| is $2$~to find the maximum of an array~|#2| of
+% floating point numbers, and $0$~to find the minimum. We read
+% numbers sequentially, keeping track of the largest (smallest) number
+% found so far. If numbers are equal (for instance~$\pm0$), the first
+% is kept. We append $-\infty$ ($\infty$), for the case of an empty
+% array. Since no number is smaller (larger) than that, this
+% additional item only affects the maximum (minimum) in the case of
+% |max()| and |min()| with no argument. The weird
+% fp-like trailing marker breaks the loop correctly: see the precise
+% definition of \cs{@@_minmax_loop:Nww}.
+% \begin{macrocode}
+\cs_new:Npn \@@_minmax_o:Nw #1
+ {
+ \@@_parse_function_all_fp_o:fnw
+ { \token_if_eq_meaning:NNTF 0 #1 { min } { max } }
+ { \@@_minmax_aux_o:Nw #1 }
+ }
+\cs_new:Npn \@@_minmax_aux_o:Nw #1#2 @
+ {
+ \if_meaning:w 0 #1
+ \exp_after:wN \@@_minmax_loop:Nww \exp_after:wN +
+ \else:
+ \exp_after:wN \@@_minmax_loop:Nww \exp_after:wN -
+ \fi:
+ #2
+ \s_@@ \@@_chk:w 2 #1 \s_@@_exact ;
+ \s_@@ \@@_chk:w { 3 \@@_minmax_break_o:w } ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_minmax_loop:Nww}
+% The first argument is $-$ or $+$ to denote the case where the
+% currently largest (smallest) number found (first floating point
+% argument) should be replaced by the new number (second floating
+% point argument). If the new number is \texttt{nan}, keep that as
+% the extremum, unless that extremum is already a \texttt{nan}.
+% Otherwise, compare the two numbers. If the new number is larger (in
+% the case of |max|) or smaller (in the case of |min|), the test
+% yields \texttt{true}, and we keep the second number as a new
+% maximum; otherwise we keep the first number. Then loop.
+% \begin{macrocode}
+\cs_new:Npn \@@_minmax_loop:Nww
+ #1 \s_@@ \@@_chk:w #2#3; \s_@@ \@@_chk:w #4#5;
+ {
+ \if_meaning:w 3 #4
+ \if_meaning:w 3 #2
+ \@@_minmax_auxi:ww
+ \else:
+ \@@_minmax_auxii:ww
+ \fi:
+ \else:
+ \if_int_compare:w
+ \@@_compare_back:ww
+ \s_@@ \@@_chk:w #4#5;
+ \s_@@ \@@_chk:w #2#3;
+ = #1 1 \exp_stop_f:
+ \@@_minmax_auxii:ww
+ \else:
+ \@@_minmax_auxi:ww
+ \fi:
+ \fi:
+ \@@_minmax_loop:Nww #1
+ \s_@@ \@@_chk:w #2#3;
+ \s_@@ \@@_chk:w #4#5;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_minmax_auxi:ww, \@@_minmax_auxii:ww}
+% Keep the first/second number, and remove the other.
+% \begin{macrocode}
+\cs_new:Npn \@@_minmax_auxi:ww #1 \fi: \fi: #2 \s_@@ #3 ; \s_@@ #4;
+ { \fi: \fi: #2 \s_@@ #3 ; }
+\cs_new:Npn \@@_minmax_auxii:ww #1 \fi: \fi: #2 \s_@@ #3 ;
+ { \fi: \fi: #2 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_minmax_break_o:w}
+% This function is called from within an \cs{if_meaning:w} test. Skip
+% to the end of the tests, close the current test with \cs{fi:}, clean
+% up, and return the appropriate number with one post-expansion.
+% \begin{macrocode}
+\cs_new:Npn \@@_minmax_break_o:w #1 \fi: \fi: #2 \s_@@ #3; #4;
+ { \fi: \@@_exp_after_o:w \s_@@ #3; }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Boolean operations}
+%
+% \begin{macro}[EXP]{\@@_not_o:w, \@@_tuple_not_o:w}
+% Return \texttt{true} or \texttt{false}, with two expansions, one to
+% exit the conditional, and one to please \pkg{l3fp-parse}. The first
+% argument is provided by \pkg{l3fp-parse} and is ignored.
+% \begin{macrocode}
+\cs_new:Npn \@@_not_o:w #1 \s_@@ \@@_chk:w #2#3; @
+ {
+ \if_meaning:w 0 #2
+ \exp_after:wN \exp_after:wN \exp_after:wN \c_one_fp
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \c_zero_fp
+ \fi:
+ }
+\cs_new:Npn \@@_tuple_not_o:w #1 @ { \exp_after:wN \c_zero_fp }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_&_o:ww, \@@_tuple_&_o:ww, \@@_&_tuple_o:ww, \@@_tuple_&_tuple_o:ww}
+% \begin{macro}[EXP]{\@@_|_o:ww, \@@_tuple_|_o:ww, \@@_|_tuple_o:ww, \@@_tuple_|_tuple_o:ww}
+% \begin{macro}[EXP]{\@@_and_return:wNw}
+% For \texttt{and}, if the first number is zero, return it (with the
+% same sign). Otherwise, return the second one. For \texttt{or}, the
+% logic is reversed: if the first number is non-zero, return it,
+% otherwise return the second number: we achieve that by hi-jacking
+% \cs{@@_&_o:ww}, inserting an extra argument, \cs{else:}, before
+% \cs{s_@@}. In all cases, expand after the floating point number.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_letter:N &
+ \char_set_catcode_letter:N |
+ \cs_new:Npn \@@_&_o:ww #1 \s_@@ \@@_chk:w #2#3;
+ {
+ \if_meaning:w 0 #2 #1
+ \@@_and_return:wNw \s_@@ \@@_chk:w #2#3;
+ \fi:
+ \@@_exp_after_o:w
+ }
+ \cs_new:Npn \@@_&_tuple_o:ww #1 \s_@@ \@@_chk:w #2#3;
+ {
+ \if_meaning:w 0 #2 #1
+ \@@_and_return:wNw \s_@@ \@@_chk:w #2#3;
+ \fi:
+ \@@_exp_after_tuple_o:w
+ }
+ \cs_new:Npn \@@_tuple_&_o:ww #1; { \@@_exp_after_o:w }
+ \cs_new:Npn \@@_tuple_&_tuple_o:ww #1; { \@@_exp_after_tuple_o:w }
+ \cs_new:Npn \@@_|_o:ww { \@@_&_o:ww \else: }
+ \cs_new:Npn \@@_|_tuple_o:ww { \@@_&_tuple_o:ww \else: }
+ \cs_new:Npn \@@_tuple_|_o:ww #1; #2; { \@@_exp_after_tuple_o:w #1; }
+ \cs_new:Npn \@@_tuple_|_tuple_o:ww #1; #2;
+ { \@@_exp_after_tuple_o:w #1; }
+\group_end:
+\cs_new:Npn \@@_and_return:wNw #1; \fi: #2;
+ { \fi: \@@_exp_after_o:w #1; }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Ternary operator}
+%
+% \begin{macro}[EXP]
+% {\@@_ternary:NwwN, \@@_ternary_auxi:NwwN, \@@_ternary_auxii:NwwN}
+% The first function receives the test and the true branch of the |?:|
+% ternary operator. It calls \cs{@@_ternary_auxii:NwwN} if the test
+% branch is a floating point number $\pm 0$, and otherwise calls
+% \cs{@@_ternary_auxi:NwwN}. These functions select one of their two
+% arguments.
+% \begin{macrocode}
+\cs_new:Npn \@@_ternary:NwwN #1 #2#3@ #4@ #5
+ {
+ \if_meaning:w \@@_parse_infix_::N #5
+ \if_charcode:w 0
+ \@@_if_type_fp:NTwFw
+ #2 { \use_i:nn \@@_use_i_delimit_by_s_stop:nw #3 \s_@@_stop }
+ \s_@@ 1 \s_@@_stop
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_ternary_auxii:NwwN
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_ternary_auxi:NwwN
+ \fi:
+ \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w
+ \@@_exp_after_array_f:w #4 \s_@@_expr_stop
+ \exp_after:wN @
+ \exp:w
+ \@@_parse_operand:Nw \c_@@_prec_colon_int
+ \@@_parse_expand:w
+ \else:
+ \msg_expandable_error:nnnn
+ { fp } { missing } { : } { ~for~?: }
+ \exp_after:wN \@@_parse_continue:NwN
+ \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w
+ \@@_exp_after_array_f:w #4 \s_@@_expr_stop
+ \exp_after:wN #5
+ \exp_after:wN #1
+ \fi:
+ }
+\cs_new:Npn \@@_ternary_auxi:NwwN #1#2@#3@#4
+ {
+ \exp_after:wN \@@_parse_continue:NwN
+ \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w
+ \@@_exp_after_array_f:w #2 \s_@@_expr_stop
+ #4 #1
+ }
+\cs_new:Npn \@@_ternary_auxii:NwwN #1#2@#3@#4
+ {
+ \exp_after:wN \@@_parse_continue:NwN
+ \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w
+ \@@_exp_after_array_f:w #3 \s_@@_expr_stop
+ #4 #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintChanges
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-parse.dtx b/macros/latex-dev/required/l3kernel/l3fp-parse.dtx
new file mode 100644
index 0000000000..ee2eedbc22
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-parse.dtx
@@ -0,0 +1,2899 @@
+% \iffalse meta-comment
+%
+%% File: l3fp-parse.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-parse} module\\
+% Floating point expression parsing^^A
+% }
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp-parse} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% \subsection{Work plan}
+%
+% The task at hand is non-trivial, and some previous failed attempts
+% show that the code leads to unreadable logs, so we had better get it
+% (almost) right the first time. Let us first describe our goal, then
+% discuss the design precisely before writing any code.
+%
+% In this file at least, a \meta{floating point object} is a floating
+% point number or tuple. This can be extended to anything that starts
+% with \cs{s_@@} or \cs{s_@@_\meta{type}} and ends with |;| with some
+% internal structure that depends on the \meta{type}.
+%
+% \begin{macro}[EXP]{\@@_parse:n}
+% \begin{syntax}
+% \cs{@@_parse:n} \Arg{fp expr}
+% \end{syntax}
+% Evaluates the \meta{fp expr} and leaves the result
+% in the input stream as a floating point object. This
+% function forms the basis of almost all public \pkg{l3fp} functions.
+% During evaluation, each token is fully \texttt{f}-expanded.
+%
+% \cs{@@_parse_o:n} does the same but expands once after its result.
+% \begin{texnote}
+% Registers (integers, toks, etc.) are automatically unpacked,
+% without requiring a function such as \cs{int_use:N}. Invalid
+% tokens remaining after \texttt{f}-expansion lead to
+% unrecoverable low-level \TeX{} errors.
+% \end{texnote}
+% \end{macro}
+%
+% \begin{variable}
+% {
+% \c_@@_prec_func_int,
+% \c_@@_prec_hatii_int,
+% \c_@@_prec_hat_int,
+% \c_@@_prec_not_int,
+% \c_@@_prec_juxt_int,
+% \c_@@_prec_times_int,
+% \c_@@_prec_plus_int,
+% \c_@@_prec_comp_int,
+% \c_@@_prec_and_int,
+% \c_@@_prec_or_int,
+% \c_@@_prec_quest_int,
+% \c_@@_prec_colon_int,
+% \c_@@_prec_comma_int,
+% \c_@@_prec_tuple_int,
+% \c_@@_prec_end_int,
+% }
+% Floating point expressions are composed of numbers, given in various
+% forms, infix operators, such as |+|, |**|, or~|,| (which joins two
+% numbers into a list), and prefix operators, such as the unary~|-|,
+% functions, or opening parentheses. Here is a list of precedences
+% which control the order of evaluation (some distinctions are
+% irrelevant for the order of evaluation, but serve as signals), from
+% the tightest binding to the loosest binding.
+% \begin{itemize}
+% \item[16] Function calls.
+% \item[13/14] Binary |**| and~|^| (right to left).
+% \item[12] Unary |+|, |-|, |!| (right to left).
+% \item[11] Juxtaposition (implicit~|*|) with no parenthesis.
+% \item[10] Binary |*| and~|/|.
+% \item[9] Binary |+| and~|-|.
+% \item[7] Comparisons.
+% \item[6] Logical \texttt{and}, denoted by~|&&|.
+% \item[5] Logical \texttt{or}, denoted by~\verb*+||+.
+% \item[4] Ternary operator |?:|, piece~|?|.
+% \item[3] Ternary operator |?:|, piece~|:|.
+% \item[2] Commas.
+% \item[1] Place where a comma is allowed and generates a tuple.
+% \item[0] Start and end of the expression.
+% \end{itemize}
+% \begin{macrocode}
+\int_const:Nn \c_@@_prec_func_int { 16 }
+\int_const:Nn \c_@@_prec_hatii_int { 14 }
+\int_const:Nn \c_@@_prec_hat_int { 13 }
+\int_const:Nn \c_@@_prec_not_int { 12 }
+\int_const:Nn \c_@@_prec_juxt_int { 11 }
+\int_const:Nn \c_@@_prec_times_int { 10 }
+\int_const:Nn \c_@@_prec_plus_int { 9 }
+\int_const:Nn \c_@@_prec_comp_int { 7 }
+\int_const:Nn \c_@@_prec_and_int { 6 }
+\int_const:Nn \c_@@_prec_or_int { 5 }
+\int_const:Nn \c_@@_prec_quest_int { 4 }
+\int_const:Nn \c_@@_prec_colon_int { 3 }
+\int_const:Nn \c_@@_prec_comma_int { 2 }
+\int_const:Nn \c_@@_prec_tuple_int { 1 }
+\int_const:Nn \c_@@_prec_end_int { 0 }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Storing results}
+%
+% The main question in parsing expressions expandably is to decide where
+% to put the intermediate results computed for various subexpressions.
+%
+% One option is to store the values at the start of the expression, and
+% carry them together as the first argument of each macro. However, we
+% want to \texttt{f}-expand tokens one by one in the expression (as
+% \cs{int_eval:n} does), and with this approach, expanding the next
+% unread token forces us to jump with \cs{exp_after:wN} over every value
+% computed earlier in the expression. With this approach, the run-time
+% grows at least quadratically in the length of the expression, if
+% not as its cube (inserting the \cs{exp_after:wN} is tricky and slow).
+%
+% A second option is to place those values at the end of the expression.
+% Then expanding the next unread token is straightforward, but this
+% still hits a performance issue: for long expressions we would be
+% reaching all the way to the end of the expression at every step of the
+% calculation. The run-time is again quadratic.
+%
+% A variation of the above attempts to place the intermediate results
+% which appear when computing a parenthesized expression near the
+% closing parenthesis. This still lets us expand tokens as we go, and
+% avoids performance problems as long as there are enough parentheses.
+% However, it would be better to avoid requiring the closing
+% parenthesis to be present as soon as the corresponding opening
+% parenthesis is read: the closing parenthesis may still be hidden in a
+% macro yet to be expanded.
+%
+% Hence, we need to go for some fine expansion control: the result is
+% stored \emph{before} the start!
+%
+% Let us illustrate this idea in a simple model: adding positive
+% integers which may be resulting from the expansion of macros, or may
+% be values of registers. Assume that one number, say, $12345$, has
+% already been found, and that we want to parse the next number. The
+% current status of the code may look as follows.
+% \begin{syntax}
+% \cs{exp_after:wN} |\add:ww| \cs{int_value:w} 12345 \cs{exp_after:wN} ;
+% \cs{exp:w} |\operand:w| \meta{stuff}
+% \end{syntax}
+% One step of expansion expands \cs{exp_after:wN}, which triggers the
+% primitive \cs{int_value:w}, which reads the five digits we have
+% already found, |12345|. This integer is unfinished, causing the
+% second \cs{exp_after:wN} to expand, and to trigger the construction
+% \cs{exp:w}, which expands |\operand:w|, defined to read
+% what follows and make a number out of it, then leave \cs{exp_end:}, the
+% number, and a semicolon in the input stream. Once |\operand:w| is
+% done expanding, we obtain essentially
+% \begin{syntax}
+% \cs{exp_after:wN} |\add:ww| \cs{int_value:w} 12345 ;
+% \cs{exp:w} \cs{exp_end:} 333444 ;
+% \end{syntax}
+% where in fact \cs{exp_after:wN} has already been expanded,
+% \cs{int_value:w} has already seen |12345|, and
+% \cs{exp:w} is still looking for a number. It finds
+% \cs{exp_end:}, hence expands to nothing. Now, \cs{int_value:w} sees
+% the \texttt{;}, which cannot be part of a number. The expansion
+% stops, and we are left with
+% \begin{syntax}
+% |\add:ww| 12345 ; 333444 ;
+% \end{syntax}
+% which can safely perform the addition by grabbing two arguments
+% delimited by~|;|.
+%
+% If we were to continue parsing the expression, then the following
+% number should also be cleaned up before the next use of a binary
+% operation such as |\add:ww|. Just like \cs{int_value:w} |12345|
+% \cs{exp_after:wN}~|;| expanded what follows once, we need |\add:ww|
+% to do the calculation, and in the process to expand the following
+% once. This is also true in our real application: all the functions of
+% the form \cs[no-index]{@@_\ldots_o:ww} expand what follows once. This comes at the
+% cost of leaving tokens in the input stack, and we need to be
+% careful not to waste this memory. All of our discussion above is nice
+% but simplistic, as operations should not simply be performed in the
+% order they appear.
+%
+% \subsubsection{Precedence and infix operators}
+%
+% The various operators we will encounter have different precedences,
+% which influence the order of calculations: $1+2\times 3 = 1+(2\times
+% 3)$ because $\times$~has a higher precedence than~$+$. The true
+% analog of our macro |\operand:w| must thus take care of that. When
+% looking for an operand, it needs to perform calculations until
+% reaching an operator which has lower precedence than the one which
+% called |\operand:w|. This means that |\operand:w| must know what the
+% previous binary operator is, or rather, its precedence: we thus rename
+% it |\operand:Nw|. Let us describe as an example how we plan to do
+% the calculation |41-2^3*4+5|. More precisely we describe how to
+% perform the first operation in this expression. Here, we abuse
+% notations: the first argument of |\operand:Nw| should be an integer
+% constant (\cs{c_@@_prec_plus_int}, \ldots{}) equal to the precedence
+% of the given operator, not directly the operator itself.
+% \begin{itemize}
+% \item Clean up~|41| and find~|-|. We call |\operand:Nw|~|-| to find
+% the second operand.
+% \item Clean up~|2| and find~|^|.
+% \item Compare the precedences of |-| and~|^|. Since the latter is
+% higher, we need to compute the exponentiation. For this, find the
+% second operand with a nested call to |\operand:Nw|~|^|.
+% \item Clean up~|3| and find~|*|.
+% \item Compare the precedences of |^| and~|*|. Since the former is
+% higher, |\operand:Nw|~|^| has found the second operand of the
+% exponentiation, which is computed: $2^{3} = 8$.
+% \item We now have |41-8*4+5|, and |\operand:Nw|~|-| is still
+% looking for a second operand for the subtraction. Is it~$8$?
+% \item Compare the precedences of |-| and~|*|. Since the latter is
+% higher, we are not done with~$8$. Call |\operand:Nw|~|*| to find
+% the second operand of the multiplication.
+% \item Clean up~|4|, and find~|+|.
+% \item Compare the precedences of |*| and~|+|. Since the former is
+% higher, |\operand:Nw|~|*| has found the second operand of the
+% multiplication, which is computed: $8*4 = 32$.
+% \item We now have |41-32+5|, and |\operand:Nw|~|-| is still looking
+% for a second operand for the subtraction. Is it~$32$?
+% \item Compare the precedences of |-| and~|+|. Since they are equal,
+% |\operand:Nw|~|-| has found the second operand for the
+% subtraction, which is computed: $41-32=9$.
+% \item We now have |9+5|.
+% \end{itemize}
+% The procedure above stops short of performing all computations, but
+% adding a surrounding call to |\operand:Nw| with a very low precedence
+% ensures that all computations are performed before |\operand:Nw|
+% is done. Adding a trailing marker with the same very low precedence
+% prevents the surrounding |\operand:Nw| from going beyond the marker.
+%
+% The pattern above to find an operand for a given operator, is to find
+% one number and the next operator, then compare precedences to know if
+% the next computation should be done. If it should, then perform it
+% after finding its second operand, and look at the next operator, then
+% compare precedences to know if the next computation should be done.
+% This continues until we find that the next computation should not be
+% done. Then, we stop.
+%
+% We are now ready to get a bit more technical and describe which of the
+% \pkg{l3fp-parse} functions correspond to each step above.
+%
+% First, \cs{@@_parse_operand:Nw} is the |\operand:Nw| function above,
+% with small modifications due to expansion issues discussed later. We
+% denote by \meta{precedence} the argument of \cs{@@_parse_operand:Nw},
+% that is, the precedence of the binary operator whose operand we are
+% trying to find. The basic action is to read numbers from the input
+% stream. This is done by \cs{@@_parse_one:Nw}. A first approximation
+% of this function is that it reads one \meta{number}, performing no
+% computation, and finds the following binary \meta{operator}. Then it
+% expands to
+% \begin{quote}
+% \meta{number}\\
+% | \__fp_parse_infix_|\meta{operator}|:N| \meta{precedence}
+% \end{quote}
+% expanding the \texttt{infix} auxiliary before leaving the above in the
+% input stream.
+%
+% We now explain the \texttt{infix} auxiliaries. We need some
+% flexibility in how we treat the case of equal precedences: most often,
+% the first operation encountered should be performed, such as |1-2-3|
+% being computed as |(1-2)-3|, but |2^3^4| should be evaluated as
+% |2^(3^4)| instead. For this reason, and to support the equivalence
+% between |**| and~|^| more easily, each binary operator is converted to
+% a control sequence |\__fp_parse_infix_|\meta{operator}|:N| when it is
+% encountered for the first time. Instead of passing both precedences
+% to a test function to do the comparison steps above, we pass the
+% \meta{precedence} (of the earlier operator) to the \texttt{infix}
+% auxiliary for the following \meta{operator}, to know whether to
+% perform the computation of the \meta{operator}. If it should not be
+% performed, the \texttt{infix} auxiliary expands to
+% \begin{syntax}
+% |@| \cs{use_none:n} |\__fp_parse_infix_|\meta{operator}|:N|
+% \end{syntax}
+% and otherwise it calls \cs{@@_parse_operand:Nw} with the precedence of
+% the \meta{operator} to find its second operand \meta{number_2} and the
+% next \meta{operator_2}, and expands to
+% \begin{syntax}
+% |@| \cs{@@_parse_apply_binary:NwNwN}
+% ~~~~\meta{operator} \meta{number_2}
+% |@| |\__fp_parse_infix_|\meta{operator_2}|:N|
+% \end{syntax}
+% The \texttt{infix} function is responsible for comparing precedences,
+% but cannot directly call the computation functions, because the first
+% operand \meta{number} is before the \texttt{infix} function in the
+% input stream. This is why we stop the expansion here and give control
+% to another function to close the loop.
+%
+% A definition of \cs{@@_parse_operand:Nw} \meta{precedence} with some
+% of the expansion control removed is
+% \begin{syntax}
+% \cs{exp_after:wN} \cs{@@_parse_continue:NwN}
+% \cs{exp_after:wN} \meta{precedence}
+% \cs{exp:w} \cs{exp_end_continue_f:w}
+% ~~\cs{@@_parse_one:Nw} \meta{precedence}
+% \end{syntax}
+% This expands \cs{@@_parse_one:Nw} \meta{precedence} completely, which
+% finds a number, wraps the next \meta{operator} into an \texttt{infix}
+% function, feeds this function the \meta{precedence}, and expands it,
+% yielding either
+% \begin{syntax}
+% \cs{@@_parse_continue:NwN} \meta{precedence}
+% \meta{number} |@|
+% \cs{use_none:n} |\__fp_parse_infix_|\meta{operator}|:N|
+% \end{syntax}
+% or
+% \begin{syntax}
+% \cs{@@_parse_continue:NwN} \meta{precedence}
+% \meta{number} |@|
+% \cs{@@_parse_apply_binary:NwNwN}
+% ~~\meta{operator} \meta{number_2}
+% |@| |\__fp_parse_infix_|\meta{operator_2}|:N|
+% \end{syntax}
+% The definition of \cs{@@_parse_continue:NwN} is then very simple:
+% \begin{syntax}
+% |\cs_new:Npn \__fp_parse_continue:NwN #1#2@#3 { #3 #1 #2 @ }|
+% \end{syntax}
+% In the first case, |#3|~is \cs{use_none:n}, yielding
+% \begin{syntax}
+% \cs{use_none:n} \meta{precedence} \meta{number} |@|
+% |\__fp_parse_infix_|\meta{operator}|:N|
+% \end{syntax}
+% then \meta{number} |@| |\__fp_parse_infix_|\meta{operator}|:N|. In
+% the second case, |#3|~is \cs{@@_parse_apply_binary:NwNwN}, whose role
+% is to compute \meta{number} \meta{operator} \meta{number_2} and to
+% prepare for the next comparison of precedences: first we get
+% \begin{syntax}
+% \cs{@@_parse_apply_binary:NwNwN}
+% ~~\meta{precedence} \meta{number} |@|
+% ~~\meta{operator} \meta{number_2}
+% |@| |\__fp_parse_infix_|\meta{operator_2}|:N|
+% \end{syntax}
+% then
+% \begin{syntax}
+% \cs{exp_after:wN} \cs{@@_parse_continue:NwN}
+% \cs{exp_after:wN} \meta{precedence}
+% \cs{exp:w} \cs{exp_end_continue_f:w}
+% |\__fp_|\meta{operator}|_o:ww| \meta{number} \meta{number_2}
+% \cs{exp:w} \cs{exp_end_continue_f:w}
+% |\__fp_parse_infix_|\meta{operator_2}|:N| \meta{precedence}
+% \end{syntax}
+% where |\__fp_|\meta{operator}|_o:ww| computes \meta{number}
+% \meta{operator} \meta{number_2} and expands after the result, thus
+% triggers the comparison of the precedence of the \meta{operator_2} and
+% the \meta{precedence}, continuing the loop.
+%
+% We have introduced the most important functions here, and the next few
+% paragraphs we describe various subtleties.
+%
+% \subsubsection{Prefix operators, parentheses, and functions}
+%
+% Prefix operators (unary |-|, |+|,~|!|) and parentheses are taken care
+% of by the same mechanism, and functions (\texttt{sin}, \texttt{exp},
+% etc.) as well. Finding the argument of the unary~|-|, for instance,
+% is very similar to grabbing the second operand of a binary infix
+% operator, with a subtle precedence explained below. Once that operand
+% is found, the operator can be applied to it (for the unary~|-|, this
+% simply flips the sign). A left parenthesis is just a prefix operator
+% with a very low precedence equal to that of the closing parenthesis
+% (which is treated as an infix operator, since it normally appears just
+% after numbers), so that all computations are performed until the
+% closing parenthesis. The prefix operator associated to the left
+% parenthesis does not alter its argument, but it removes the closing
+% parenthesis (with some checks).
+%
+% Prefix operators are the reason why we only summarily described the
+% function \cs{@@_parse_one:Nw} earlier. This function is responsible
+% for reading in the input stream the first possible \meta{number} and
+% the next infix \meta{operator}. If what follows \cs{@@_parse_one:Nw}
+% \meta{precedence} is a prefix operator, then we must find the operand
+% of this prefix operator through a nested call to
+% \cs{@@_parse_operand:Nw} with the appropriate precedence, then apply
+% the operator to the operand found to yield the result of
+% \cs{@@_parse_one:Nw}. So far, all is simple.
+%
+% The unary operators |+|, |-|,~|!| complicate things a little bit:
+% |-3**2| should be $-(3^2)=-9$, and not $(-3)^2=9$. This would easily
+% be done by giving~|-| a lower precedence, equal to that of the infix
+% |+| and~|-|. Unfortunately, this fails in cases such as |3**-2*4|,
+% yielding $3^{-2\times 4}$ instead of the correct $3^{-2}\times 4$. A
+% second attempt would be to call \cs{@@_parse_operand:Nw} with the
+% \meta{precedence} of the previous operator, but |0>-2+3| is then
+% parsed as |0>-(2+3)|: the addition is performed because it binds more
+% tightly than the comparision which precedes~|-|. The correct approach
+% is for a unary~|-| to perform operations whose precedence is greater
+% than both that of the previous operation, and that of the unary~|-|
+% itself. The unary~|-| is given a precedence higher than
+% multiplication and division. This does not lead to any surprising
+% result, since $-(x/y) = (-x)/y$ and similarly for multiplication, and
+% it reduces the number of nested calls to \cs{@@_parse_operand:Nw}.
+%
+% Functions are implemented as prefix operators with very high
+% precedence, so that their argument is the first number that can
+% possibly be built.
+%
+% Note that contrarily to the \texttt{infix} functions discussed
+% earlier, the \texttt{prefix} functions do perform tests on the
+% previous \meta{precedence} to decide whether to find an argument or
+% not, since we know that we need a number, and must never stop there.
+%
+% \subsubsection{Numbers and reading tokens one by one}
+%
+% So far, we have glossed over one important point: what is a
+% \enquote{number}? A number is typically given in the form
+% \meta{significand}|e|\meta{exponent}, where the \meta{significand} is
+% any non-empty string composed of decimal digits and at most one
+% decimal separator (a period), the exponent
+% \enquote{\texttt{e}\meta{exponent}} is optional and is composed of an
+% exponent mark~|e| followed by a possibly empty string of signs
+% |+| or~|-| and a non-empty string of decimal digits. The
+% \meta{significand} can also be an integer, dimension, skip, or muskip
+% variable, in which case dimensions are converted from points (or mu
+% units) to floating points, and the \meta{exponent} can also be an
+% integer variable. Numbers can also be given as floating point
+% variables, or as named constants such as |nan|, |inf| or~|pi|. We may
+% add more types in the future.
+%
+% When \cs{@@_parse_one:Nw} is looking for a \enquote{number}, here is
+% what happens.
+% \begin{itemize}
+% \item If the next token is a control sequence with the meaning of
+% \cs{scan_stop:}, it can be: \cs{s_@@}, in which case our job is
+% done, as what follows is an internal floating point number, or
+% \cs{s_@@_expr_mark}, in which case the expression has come to an early
+% end, as we are still looking for a number here, or something else,
+% in which case we consider the control sequence to be a bad
+% variable resulting from \texttt{c}-expansion.
+% \item If the next token is a control sequence with a different
+% meaning, we assume that it is a register, unpack it with
+% \cs{tex_the:D}, and use its value (in \texttt{pt} for dimensions
+% and skips, \texttt{mu} for muskips) as the \meta{significand} of a
+% number: we look for an exponent.
+% \item If the next token is a digit, we remove any leading zeros,
+% then read a significand larger than~$1$ if the next character is a
+% digit, read a significand smaller than~$1$ if the next character
+% is a period, or we have found a significand equal to~$0$
+% otherwise, and look for an exponent.
+% \item If the next token is a letter, we collect more letters until
+% the first non-letter: the resulting word may denote a function
+% such as |asin|, a constant such as |pi| or be unknown. In the
+% first case, we call \cs{@@_parse_operand:Nw} to find the argument
+% of the function, then apply the function, before declaring that we
+% are done. Otherwise, we are done, either with the value of the
+% constant, or with the value |nan| for unknown words.
+% \item If the next token is anything else, we check whether it is a
+% known prefix operator, in which case \cs{@@_parse_operand:Nw}
+% finds its operand. If it is not known, then either a number is
+% missing (if the token is a known infix operator) or the token is
+% simply invalid in floating point expressions.
+% \end{itemize}
+% Once a number is found, \cs{@@_parse_one:Nw} also finds an infix
+% operator. This goes as follows.
+% \begin{itemize}
+% \item If the next token is a control sequence, it could be the
+% special marker \cs{s_@@_expr_mark}, and
+% otherwise it is a case of juxtaposing numbers, such as
+% |2\c_zero_int|, with an implied multiplication.
+% \item If the next token is a letter, it is also a case of
+% juxtaposition, as letters cannot be proper infix operators.
+% \item Otherwise (including in the case of digits), if the token is a
+% known infix operator, the appropriate
+% |\__fp_infix_|\meta{operator}|:N| function is built, and if it
+% does not exist, we complain. In particular, the juxtaposition
+% |\c_zero_int 2| is disallowed.
+% \end{itemize}
+%
+% In the above, we need to test whether a character token~|#1| is a
+% digit:
+% \begin{verbatim}
+% \if_int_compare:w 9 < 1 \token_to_str:N #1 \exp_stop_f:
+% is a digit
+% \else:
+% not a digit
+% \fi:
+% \end{verbatim}
+% To exclude |0|, replace |9| by |10|. The use of
+% \cs{token_to_str:N} ensures that a digit with any catcode is detected.
+% To test if a character token is a letter, we need to work with its
+% character code, testing if |`#1| lies in $[65,90]$ (uppercase letters)
+% or $[97,112]$ (lowercase letters)
+% \begin{verbatim}
+% \if_int_compare:w \__fp_int_eval:w
+% ( `#1 \if_int_compare:w `#1 > `Z - 32 \fi: ) / 26 = 3 \exp_stop_f:
+% is a letter
+% \else:
+% not a letter
+% \fi:
+% \end{verbatim}
+% At all steps, we try to accept all category codes: when |#1|~is kept
+% to be used later, it is almost always converted to category code other
+% through \cs{token_to_str:N}. More precisely, catcodes $\{3, 6, 7, 8,
+% 11, 12\}$ should work without trouble, but not $\{1, 2, 4, 10, 13\}$,
+% and of course $\{0, 5, 9\}$ cannot become tokens.
+%
+% Floating point expressions should behave as much as possible like
+% \eTeX{}-based integer expressions and dimension expressions. In
+% particular, \texttt{f}-expansion should be performed as the expression
+% is read, token by token, forcing the expansion of protected macros,
+% and ignoring spaces. One advantage of expanding at every step is that
+% restricted expandable functions can then be used in floating point
+% expressions just as they can be in other kinds of expressions.
+% Problematically, spaces stop \texttt{f}-expansion: for instance, the
+% macro~|\X| below would not be expanded if we simply performed
+% \texttt{f}-expansion.
+% \begin{verbatim}
+% \DeclareDocumentCommand {\test} {m} { \fp_eval:n {#1} }
+% \ExplSyntaxOff
+% \test { 1 + \X }
+% \end{verbatim}
+% Of course, spaces typically do not appear in a code setting, but may very
+% easily come in document-level input, from which some expressions may
+% come. To avoid this problem, at every step, we do essentially what
+% \cs{use:f} would do: take an argument, put it back in the input
+% stream, then \texttt{f}-expand it. This is not a complete solution,
+% since a macro's expansion could contain leading spaces which would stop
+% the \texttt{f}-expansion before further macro calls are performed.
+% However, in practice it should be enough: in particular, floating
+% point numbers are correctly expanded to the underlying \cs{s_@@}
+% \ldots{} structure. The \texttt{f}-expansion is performed by
+% \cs{@@_parse_expand:w}.
+%
+% ^^A begin[todo]
+%
+% \subsection{Main auxiliary functions}
+%
+% \begin{macro}[rEXP]{\@@_parse_operand:Nw}
+% \begin{syntax}
+% \cs{exp:w} \cs{@@_parse_operand:Nw} \meta{precedence} \cs{@@_parse_expand:w}
+% \end{syntax}
+% Reads the \enquote{\ttfamily\ldots{}}, performing every computation
+% with a precedence higher than \meta{precedence}, then expands to
+% \begin{syntax}
+% \meta{result} |@| |\__fp_parse_infix_|\meta{operation}|:N| \ldots{}
+% \end{syntax}
+% where the \meta{operation} is the first operation with a lower
+% precedence, possibly \texttt{end}, and the
+% \enquote{\ttfamily\ldots{}} start just after the \meta{operation}.
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_infix_+:N}
+% \begin{syntax}
+% \cs{@@_parse_infix_+:N} \meta{precedence} \ldots{}
+% \end{syntax}
+% If |+|~has a precedence higher than the \meta{precedence}, cleans up
+% a second \meta{operand} and finds the \meta{operation_2} which
+% follows, and expands to
+% \begin{syntax}
+% |@| \cs{@@_parse_apply_binary:NwNwN} |+| \meta{operand} |@| \cs{@@_parse_infix_\meta{operation_2}:N} \ldots{}
+% \end{syntax}
+% Otherwise expands to
+% \begin{syntax}
+% |@| \cs{use_none:n} \cs{@@_parse_infix_+:N} \ldots{}
+% \end{syntax}
+% A similar function exists for each infix operator.
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_one:Nw}
+% \begin{syntax}
+% \cs{@@_parse_one:Nw} \meta{precedence} \ldots{}
+% \end{syntax}
+% Cleans up one or two operands depending on how the precedence of the
+% next operation compares to the \meta{precedence}. If the following
+% \meta{operation} has a precedence higher than \meta{precedence},
+% expands to
+% \begin{syntax}
+% \meta{operand_1} |@| \cs{@@_parse_apply_binary:NwNwN} \meta{operation} \meta{operand_2} |@| |\__fp_parse_infix_|\meta{operation_2}|:N| \ldots{}
+% \end{syntax}
+% and otherwise expands to
+% \begin{syntax}
+% \meta{operand} |@| \cs{use_none:n} |\__fp_parse_infix_|\meta{operation}|:N| \ldots{}
+% \end{syntax}
+% \end{macro}
+%
+% ^^A end[todo]
+%
+% \subsection{Helpers}
+%
+% \begin{macro}[rEXP]{\@@_parse_expand:w}
+% \begin{syntax}
+% \cs{exp:w} \cs{@@_parse_expand:w} \meta{tokens}
+% \end{syntax}
+% This function must always come within a \cs{exp:w} expansion.
+% The \meta{tokens} should be the part of the expression that we have
+% not yet read. This requires in particular closing all conditionals
+% properly before expanding.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_expand:w #1 { \exp_end_continue_f:w #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_return_semicolon:w}
+% This very odd function swaps its position with the following
+% \cs{fi:} and removes \cs{@@_parse_expand:w} normally responsible for
+% expansion. That turns out to be useful.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_return_semicolon:w
+ #1 \fi: \@@_parse_expand:w { \fi: ; #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {
+% \@@_parse_digits_vii:N ,
+% \@@_parse_digits_vi:N ,
+% \@@_parse_digits_v:N ,
+% \@@_parse_digits_iv:N ,
+% \@@_parse_digits_iii:N ,
+% \@@_parse_digits_ii:N ,
+% \@@_parse_digits_i:N ,
+% \@@_parse_digits_:N
+% }
+% These functions must be called within an \cs{int_value:w} or
+% \cs{@@_int_eval:w} construction. The first token which follows must
+% be \texttt{f}-expanded prior to calling those functions. The
+% functions read tokens one by one, and output digits into the input
+% stream, until meeting a non-digit, or up to a number of digits equal
+% to their index. The full expansion is
+% \begin{syntax}
+% \meta{digits} |;| \meta{filling 0} |;| \meta{length}
+% \end{syntax}
+% where \meta{filling 0} is a string of zeros such that \meta{digits}
+% \meta{filling 0} has the length given by the index of the function,
+% and \meta{length} is the number of zeros in the \meta{filling 0}
+% string. Each function puts a digit into the input stream and calls
+% the next function, until we find a non-digit. We are careful to
+% pass the tested tokens through \cs{token_to_str:N} to normalize
+% their category code.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1 #2 #3
+ {
+ \cs_new:cpn { @@_parse_digits_ #1 :N } ##1
+ {
+ \if_int_compare:w 9 < 1 \token_to_str:N ##1 \exp_stop_f:
+ \token_to_str:N ##1 \exp_after:wN #2 \exp:w
+ \else:
+ \@@_parse_return_semicolon:w #3 ##1
+ \fi:
+ \@@_parse_expand:w
+ }
+ }
+\@@_tmp:w {vii} \@@_parse_digits_vi:N { 0000000 ; 7 }
+\@@_tmp:w {vi} \@@_parse_digits_v:N { 000000 ; 6 }
+\@@_tmp:w {v} \@@_parse_digits_iv:N { 00000 ; 5 }
+\@@_tmp:w {iv} \@@_parse_digits_iii:N { 0000 ; 4 }
+\@@_tmp:w {iii} \@@_parse_digits_ii:N { 000 ; 3 }
+\@@_tmp:w {ii} \@@_parse_digits_i:N { 00 ; 2 }
+\@@_tmp:w {i} \@@_parse_digits_:N { 0 ; 1 }
+\cs_new:Npn \@@_parse_digits_:N { ; ; 0 }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Parsing one number}
+%
+% \begin{macro}[EXP]{\@@_parse_one:Nw}
+% This function finds one number, and packs the symbol which follows
+% in an \cs[no-index]{@@_parse_infix_\ldots{}} csname.
+% |#1|~is the previous \meta{precedence},
+% and |#2|~the first token of the operand. We distinguish four cases:
+% |#2|~is equal to \cs{scan_stop:} in meaning, |#2|~is a different
+% control sequence, |#2|~is a digit, and |#2|~is something else (this
+% last case is split further later). Despite the earlier
+% \texttt{f}-expansion, |#2|~may still be expandable if it was
+% protected by \cs{exp_not:N}, as may happen with the \LaTeXe{} command
+% \tn{protect}. Using a well placed \cs{reverse_if:N}, this case is
+% sent to \cs{@@_parse_one_fp:NN} which deals with it robustly.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_one:Nw #1 #2
+ {
+ \if_catcode:w \scan_stop: \exp_not:N #2
+ \exp_after:wN \if_meaning:w \exp_not:N #2 #2 \else:
+ \exp_after:wN \reverse_if:N
+ \fi:
+ \if_meaning:w \scan_stop: #2
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_parse_one_fp:NN
+ \else:
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_parse_one_register:NN
+ \fi:
+ \else:
+ \if_int_compare:w 9 < 1 \token_to_str:N #2 \exp_stop_f:
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_parse_one_digit:NN
+ \else:
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_parse_one_other:NN
+ \fi:
+ \fi:
+ #1 #2
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_one_fp:NN,
+% \@@_exp_after_expr_mark_f:nw,
+% \@@_exp_after_?_f:nw
+% }
+% This function receives a \meta{precedence} and a control sequence
+% equal to \cs{scan_stop:} in meaning. There are three cases.
+% \begin{itemize}
+% \item \cs{s_@@} starts a floating point number, and we call
+% \cs{@@_exp_after_f:nw}, which |f|-expands after the floating
+% point.
+% \item \cs{s_@@_expr_mark} is a premature end, we call
+% \cs{@@_exp_after_expr_mark_f:nw}, which triggers an |fp-early-end|
+% error.
+% \item For a control sequence not containing \cs[no-index]{s_@@}, we call
+% \cs{@@_exp_after_?_f:nw}, causing a |bad-variable| error.
+% \end{itemize}
+% This scheme is extensible: additional types can be added by starting
+% the variables with a scan mark of the form \cs[no-index]{s_@@_\meta{type}} and
+% defining |\__fp_exp_after_|\meta{type}|_f:nw|. In all cases, we
+% make sure that the second argument of \cs{@@_parse_infix:NN} is
+% correctly expanded.
+% A special case only enabled in \LaTeXe{} is that if \tn{protect} is
+% encountered then the error message mentions the control sequence
+% which follows it rather than \tn{protect} itself. The test for
+% \LaTeXe{} uses \tn{@unexpandable@protect} rather than \tn{protect}
+% because \tn{protect} is often \cs{scan_stop:} hence \enquote{does
+% not exist}.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_one_fp:NN #1
+ {
+ \@@_exp_after_any_f:nw
+ {
+ \exp_after:wN \@@_parse_infix:NN
+ \exp_after:wN #1 \exp:w \@@_parse_expand:w
+ }
+ }
+\cs_new:Npn \@@_exp_after_expr_mark_f:nw #1
+ {
+ \int_case:nnF { \exp_after:wN \use_i:nnn \use_none:nnn #1 }
+ {
+ \c_@@_prec_comma_int { }
+ \c_@@_prec_tuple_int { }
+ \c_@@_prec_end_int
+ {
+ \exp_after:wN \c_@@_empty_tuple_fp
+ \exp:w \exp_end_continue_f:w
+ }
+ }
+ {
+ \msg_expandable_error:nn { fp } { early-end }
+ \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w
+ }
+ #1
+ }
+\cs_new:cpn { @@_exp_after_?_f:nw } #1#2
+ {
+ \msg_expandable_error:nnn { kernel } { bad-variable }
+ {#2}
+ \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w #1
+ }
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \cs_if_exist:NT #1
+ {
+ \cs_gset:cpn { @@_exp_after_?_f:nw } ##1##2
+ {
+ \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w ##1
+ \str_if_eq:nnTF {##2} { \protect }
+ {
+ \cs_if_eq:NNTF ##2 #1 { \use_i:nn } { \use:n }
+ {
+ \msg_expandable_error:nnn { fp }
+ { robust-cmd }
+ }
+ }
+ {
+ \msg_expandable_error:nnn { kernel }
+ { bad-variable } {##2}
+ }
+ }
+ }
+ }
+\exp_args:Nc \@@_tmp:w { @unexpandable@protect }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_one_register:NN,
+% \@@_parse_one_register_aux:Nw,
+% \@@_parse_one_register_auxii:wwwNw,
+% \@@_parse_one_register_int:www,
+% \@@_parse_one_register_mu:www,
+% \@@_parse_one_register_dim:ww,
+% }
+% This is called whenever~|#2| is a control sequence other than
+% \cs{scan_stop:} in meaning. We special-case \tn{wd}, \tn{ht}, \tn{dp}
+% (see later) and otherwise assume that it is a register, but
+% carefully unpack it with \cs{tex_the:D} within braces. First, we
+% find the exponent following~|#2|. Then we unpack~|#2| with
+% \cs{tex_the:D}, and the \texttt{auxii} auxiliary distinguishes
+% integer registers from dimensions/skips from muskips, according to
+% the presence of a period and/or of |pt|. For integers, simply
+% convert \meta{value}|e|\meta{exponent} to a floating point number
+% with \cs{@@_parse:n} (this is somewhat wasteful). For other
+% registers, the decimal rounding provided by \TeX{} does not
+% accurately represent the binary value that it manipulates, so we
+% extract this binary value as a number of scaled points with
+% \cs{int_value:w} \cs{dim_to_decimal_in_sp:n} |{| \meta{decimal value} |pt| |}|, and
+% use an auxiliary of \cs{dim_to_fp:n}, which performs the
+% multiplication by $2^{-16}$, correctly rounded.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_one_register:NN #1#2
+ {
+ \exp_after:wN \@@_parse_infix_after_operand:NwN
+ \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w
+ \@@_parse_one_register_special:N #2
+ \exp_after:wN \@@_parse_one_register_aux:Nw
+ \exp_after:wN #2
+ \int_value:w
+ \exp_after:wN \@@_parse_exponent:N
+ \exp:w \@@_parse_expand:w
+ }
+\cs_new:Npe \@@_parse_one_register_aux:Nw #1
+ {
+ \exp_not:n
+ {
+ \exp_after:wN \use:nn
+ \exp_after:wN \@@_parse_one_register_auxii:wwwNw
+ }
+ \exp_not:N \exp_after:wN { \exp_not:N \tex_the:D #1 }
+ ; \exp_not:N \@@_parse_one_register_dim:ww
+ \tl_to_str:n { pt } ; \exp_not:N \@@_parse_one_register_mu:www
+ . \tl_to_str:n { pt } ; \exp_not:N \@@_parse_one_register_int:www
+ \s_@@_stop
+ }
+\exp_args:Nno \use:nn
+ { \cs_new:Npn \@@_parse_one_register_auxii:wwwNw #1 . #2 }
+ { \tl_to_str:n { pt } #3 ; #4#5 \s_@@_stop }
+ { #4 #1.#2; }
+\exp_args:Nno \use:nn
+ { \cs_new:Npn \@@_parse_one_register_mu:www #1 }
+ { \tl_to_str:n { mu } ; #2 ; }
+ { \@@_parse_one_register_dim:ww #1 ; }
+\cs_new:Npn \@@_parse_one_register_int:www #1; #2.; #3;
+ { \@@_parse:n { #1 e #3 } }
+\cs_new:Npn \@@_parse_one_register_dim:ww #1; #2;
+ {
+ \exp_after:wN \@@_from_dim_test:ww
+ \int_value:w #2 \exp_after:wN ,
+ \int_value:w \dim_to_decimal_in_sp:n { #1 pt } ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_parse_one_register_special:N,
+% \@@_parse_one_register_math:NNw,
+% \@@_parse_one_register_wd:w,
+% \@@_parse_one_register_wd:Nw
+% }
+% The \tn{wd}, \tn{dp}, \tn{ht} primitives expect an integer argument.
+% We abuse the exponent parser to find the integer argument: simply
+% include the exponent marker~|e|. Once that \enquote{exponent} is
+% found, use \cs{tex_the:D} to find the box dimension and then copy
+% what we did for dimensions.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_one_register_special:N #1
+ {
+ \if_meaning:w \box_wd:N #1 \@@_parse_one_register_wd:w \fi:
+ \if_meaning:w \box_ht:N #1 \@@_parse_one_register_wd:w \fi:
+ \if_meaning:w \box_dp:N #1 \@@_parse_one_register_wd:w \fi:
+ \if_meaning:w \infty #1
+ \@@_parse_one_register_math:NNw \infty #1
+ \fi:
+ \if_meaning:w \pi #1
+ \@@_parse_one_register_math:NNw \pi #1
+ \fi:
+ }
+\cs_new:Npn \@@_parse_one_register_math:NNw
+ #1#2#3#4 \@@_parse_expand:w
+ {
+ #3
+ \str_if_eq:nnTF {#1} {#2}
+ {
+ \msg_expandable_error:nnn
+ { fp } { infty-pi } {#1}
+ \c_nan_fp
+ }
+ { #4 \@@_parse_expand:w }
+ }
+\cs_new:Npn \@@_parse_one_register_wd:w
+ #1#2 \exp_after:wN #3#4 \@@_parse_expand:w
+ {
+ #1
+ \exp_after:wN \@@_parse_one_register_wd:Nw
+ #4 \@@_parse_expand:w e
+ }
+\cs_new:Npn \@@_parse_one_register_wd:Nw #1#2 ;
+ {
+ \exp_after:wN \@@_from_dim_test:ww
+ \exp_after:wN 0 \exp_after:wN ,
+ \int_value:w \dim_to_decimal_in_sp:n { #1 #2 } ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_one_digit:NN}
+% A digit marks the beginning of an explicit floating point number.
+% Once the number is found, we catch the case of overflow and
+% underflow with \cs{@@_sanitize:wN}, then
+% \cs{@@_parse_infix_after_operand:NwN} expands \cs{@@_parse_infix:NN}
+% after the number we find, to wrap the following infix operator as
+% required. Finding the number itself begins by removing leading
+% zeros: further steps are described later.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_one_digit:NN #1
+ {
+ \exp_after:wN \@@_parse_infix_after_operand:NwN
+ \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w
+ \exp_after:wN \@@_sanitize:wN
+ \int_value:w \@@_int_eval:w 0 \@@_parse_trim_zeros:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_one_other:NN}
+% For this function, |#2|~is a character token which is not a digit.
+% If it is an \textsc{ascii} letter, \cs{@@_parse_letters:N} beyond this one and give
+% the result to \cs{@@_parse_word:Nw}. Otherwise, the character is
+% assumed to be a prefix operator, and we build
+% |\__fp_parse_prefix_|\meta{operator}|:Nw|.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_one_other:NN #1 #2
+ {
+ \if_int_compare:w
+ \@@_int_eval:w
+ ( `#2 \if_int_compare:w `#2 > `Z - 32 \fi: ) / 26
+ = 3 \exp_stop_f:
+ \exp_after:wN \@@_parse_word:Nw
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp:w \exp_after:wN \@@_parse_letters:N
+ \exp:w
+ \else:
+ \exp_after:wN \@@_parse_prefix:NNN
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \cs:w
+ @@_parse_prefix_ \token_to_str:N #2 :Nw
+ \exp_after:wN
+ \cs_end:
+ \exp:w
+ \fi:
+ \@@_parse_expand:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_word:Nw}
+% \begin{macro}[rEXP]{\@@_parse_letters:N}
+% Finding letters is a simple recursion. Once \cs{@@_parse_letters:N}
+% has done its job, we try to build a control sequence from the
+% word~|#2|. If it is a known word, then the corresponding action is
+% taken, and otherwise, we complain about an unknown word, yield
+% \cs{c_nan_fp}, and look for the following infix operator. Note that
+% the unknown word could be a mistyped function as well as a mistyped
+% constant, so there is no way to tell whether to look for arguments;
+% we do not.
+% The standard requires \enquote{inf} and \enquote{infinity} and
+% \enquote{nan} to be recognized regardless of case, but we probably
+% don't want to allow every \pkg{l3fp} word to have an arbitrary
+% mixture of lower and upper case, so we test and use a
+% differently-named control sequence.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_word:Nw #1#2;
+ {
+ \cs_if_exist_use:cF { @@_parse_word_#2:N }
+ {
+ \cs_if_exist_use:cF
+ { @@_parse_caseless_ \str_casefold:n {#2} :N }
+ {
+ \msg_expandable_error:nnn
+ { fp } { unknown-fp-word } {#2}
+ \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w
+ \@@_parse_infix:NN
+ }
+ }
+ #1
+ }
+\cs_new:Npn \@@_parse_letters:N #1
+ {
+ \exp_end_continue_f:w
+ \if_int_compare:w
+ \if_catcode:w \scan_stop: \exp_not:N #1
+ 0
+ \else:
+ \@@_int_eval:w
+ ( `#1 \if_int_compare:w `#1 > `Z - 32 \fi: ) / 26
+ \fi:
+ = 3 \exp_stop_f:
+ \exp_after:wN #1
+ \exp:w \exp_after:wN \@@_parse_letters:N
+ \exp:w
+ \else:
+ \@@_parse_return_semicolon:w #1
+ \fi:
+ \@@_parse_expand:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_parse_prefix:NNN, \@@_parse_prefix_unknown:NNN}
+% For this function, |#1|~is the previous \meta{precedence}, |#2|~is
+% the operator just seen, and |#3|~is a control sequence which
+% implements the operator if it is a known operator. If this control
+% sequence is \cs{scan_stop:}, then the operator is in fact unknown.
+% Either the expression is missing a number there (if the operator is
+% valid as an infix operator), and we put \texttt{nan}, wrapping the
+% infix operator in a csname as appropriate, or the character is
+% simply invalid in floating point expressions, and we continue
+% looking for a number, starting again from \cs{@@_parse_one:Nw}.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_prefix:NNN #1#2#3
+ {
+ \if_meaning:w \scan_stop: #3
+ \exp_after:wN \@@_parse_prefix_unknown:NNN
+ \exp_after:wN #2
+ \fi:
+ #3 #1
+ }
+\cs_new:Npn \@@_parse_prefix_unknown:NNN #1#2#3
+ {
+ \cs_if_exist:cTF { @@_parse_infix_ \token_to_str:N #1 :N }
+ {
+ \msg_expandable_error:nnn
+ { fp } { missing-number } {#1}
+ \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w
+ \@@_parse_infix:NN #3 #1
+ }
+ {
+ \msg_expandable_error:nnn
+ { fp } { unknown-symbol } {#1}
+ \@@_parse_one:Nw #3
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Numbers: trimming leading zeros}
+%
+% Numbers are parsed as follows: first we trim leading zeros, then
+% if the next character is a digit, start reading a significand $\geq 1$
+% with the set of functions |\__fp_parse_large|\ldots{}; if it is a
+% period, the significand is~$<1$; and otherwise it is zero. In the
+% second case, trim additional zeros after the period, counting them for
+% an exponent shift $\meta{exp_1}<0$, then read the significand with the
+% set of functions |\__fp_parse_small|\ldots{} Once the significand is
+% read, read the exponent if |e|~is present.
+%
+% \begin{macro}[rEXP]{\@@_parse_trim_zeros:N, \@@_parse_trim_end:w}
+% This function expects an already expanded token. It removes any
+% leading zero, then distinguishes three cases: if the first non-zero
+% token is a digit, then call \cs{@@_parse_large:N} (the significand
+% is $\geq 1$); if it is |.|, then continue trimming zeros with
+% \cs{@@_parse_strim_zeros:N}; otherwise, our number is exactly zero,
+% and we call \cs{@@_parse_zero:} to take care of that case.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_trim_zeros:N #1
+ {
+ \if:w 0 \exp_not:N #1
+ \exp_after:wN \@@_parse_trim_zeros:N
+ \exp:w
+ \else:
+ \if:w . \exp_not:N #1
+ \exp_after:wN \@@_parse_strim_zeros:N
+ \exp:w
+ \else:
+ \@@_parse_trim_end:w #1
+ \fi:
+ \fi:
+ \@@_parse_expand:w
+ }
+\cs_new:Npn \@@_parse_trim_end:w #1 \fi: \fi: \@@_parse_expand:w
+ {
+ \fi:
+ \fi:
+ \if_int_compare:w 9 < 1 \token_to_str:N #1 \exp_stop_f:
+ \exp_after:wN \@@_parse_large:N
+ \else:
+ \exp_after:wN \@@_parse_zero:
+ \fi:
+ #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {\@@_parse_strim_zeros:N, \@@_parse_strim_end:w}
+% If we have removed all digits until a period (or if the body started
+% with a period), then enter the \enquote{\texttt{small_trim}} loop
+% which outputs $-1$ for each removed~$0$. Those $-1$ are added to an
+% integer expression waiting for the exponent. If the first non-zero
+% token is a digit, call \cs{@@_parse_small:N} (our significand is
+% smaller than~$1$), and otherwise, the number is an exact zero. The
+% name \texttt{strim} stands for \enquote{small trim}.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_strim_zeros:N #1
+ {
+ \if:w 0 \exp_not:N #1
+ - 1
+ \exp_after:wN \@@_parse_strim_zeros:N \exp:w
+ \else:
+ \@@_parse_strim_end:w #1
+ \fi:
+ \@@_parse_expand:w
+ }
+\cs_new:Npn \@@_parse_strim_end:w #1 \fi: \@@_parse_expand:w
+ {
+ \fi:
+ \if_int_compare:w 9 < 1 \token_to_str:N #1 \exp_stop_f:
+ \exp_after:wN \@@_parse_small:N
+ \else:
+ \exp_after:wN \@@_parse_zero:
+ \fi:
+ #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_zero:}
+% After reading a significand of~$0$, find any exponent, then put a
+% sign of~|1| for \cs{@@_sanitize:wN}, which removes everything
+% and leaves an exact zero.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_zero:
+ {
+ \exp_after:wN ; \exp_after:wN 1
+ \int_value:w \@@_parse_exponent:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Number: small significand}
+%
+% \begin{macro}[rEXP]{\@@_parse_small:N}
+% This function is called after we have passed the decimal separator
+% and removed all leading zeros from the significand. It is followed
+% by a non-zero digit (with any catcode). The goal is to read up to
+% $16$ digits. But we can't do that all at once, because
+% \cs{int_value:w} (which allows us to collect digits and continue
+% expanding) can only go up to $9$ digits. Hence we grab digits in
+% two steps of $8$ digits. Since |#1| is a digit, read seven more
+% digits using \cs{@@_parse_digits_vii:N}. The \texttt{small_leading}
+% auxiliary leaves those digits in the \cs{int_value:w}, and
+% grabs some more, or stops if there are no more digits. Then the
+% \texttt{pack_leading} auxiliary puts the various parts in the
+% appropriate order for the processing further up.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_small:N #1
+ {
+ \exp_after:wN \@@_parse_pack_leading:NNNNNww
+ \int_value:w \@@_int_eval:w 1 \token_to_str:N #1
+ \exp_after:wN \@@_parse_small_leading:wwNN
+ \int_value:w 1
+ \exp_after:wN \@@_parse_digits_vii:N
+ \exp:w \@@_parse_expand:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_parse_small_leading:wwNN}
+% \begin{syntax}
+% \cs{@@_parse_small_leading:wwNN} |1| \meta{digits} |;| \meta{zeros} |;| \meta{number~of~zeros}
+% \end{syntax}
+% We leave \meta{digits} \meta{zeros} in the input stream: the
+% functions used to grab digits are such that this constitutes digits
+% $1$ through~$8$ of the significand. Then prepare to pack $8$~more
+% digits, with an exponent shift of zero (this shift is used in
+% the case of a large significand). If |#4|~is a digit, leave it
+% behind for the packing function, and read $6$~more digits to reach a
+% total of $15$~digits: further digits are involved in the rounding.
+% Otherwise put $8$~zeros in to complete the significand, then look
+% for an exponent.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_small_leading:wwNN 1 #1 ; #2; #3 #4
+ {
+ #1 #2
+ \exp_after:wN \@@_parse_pack_trailing:NNNNNNww
+ \exp_after:wN 0
+ \int_value:w \@@_int_eval:w 1
+ \if_int_compare:w 9 < 1 \token_to_str:N #4 \exp_stop_f:
+ \token_to_str:N #4
+ \exp_after:wN \@@_parse_small_trailing:wwNN
+ \int_value:w 1
+ \exp_after:wN \@@_parse_digits_vi:N
+ \exp:w
+ \else:
+ 0000 0000 \@@_parse_exponent:Nw #4
+ \fi:
+ \@@_parse_expand:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_parse_small_trailing:wwNN}
+% \begin{syntax}
+% \cs{@@_parse_small_trailing:wwNN} |1| \meta{digits} |;| \meta{zeros} |;| \meta{number~of~zeros} \meta{next~token}
+% \end{syntax}
+% Leave digits $10$ to~$15$ (arguments |#1| and |#2|) in the input
+% stream. If the \meta{next~token} is a digit, it is the $16$th
+% digit, we keep it, then the \texttt{small_round} auxiliary considers
+% this digit and all further digits to perform the rounding: the
+% function expands to nothing, to |+0| or to |+1|.
+% Otherwise, there is no $16$-th digit, so we put a~$0$, and look for
+% an exponent.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_small_trailing:wwNN 1 #1 ; #2; #3 #4
+ {
+ #1 #2
+ \if_int_compare:w 9 < 1 \token_to_str:N #4 \exp_stop_f:
+ \token_to_str:N #4
+ \exp_after:wN \@@_parse_small_round:NN
+ \exp_after:wN #4
+ \exp:w
+ \else:
+ 0 \@@_parse_exponent:Nw #4
+ \fi:
+ \@@_parse_expand:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {
+% \@@_parse_pack_trailing:NNNNNNww ,
+% \@@_parse_pack_leading:NNNNNww ,
+% \@@_parse_pack_carry:w
+% }
+% Those functions are expanded after all the digits are found, we took
+% care of the rounding, as well as the exponent. The last argument is
+% the exponent. The previous five arguments are $8$~digits which we
+% pack in groups of~$4$, and the argument before that is~$1$, except
+% in the rare case where rounding lead to a carry, in which case the
+% argument is~$2$. The \texttt{trailing} function has an exponent
+% shift as its first argument, which we add to the exponent found in
+% the |e...| syntax. If the trailing digits cause a carry, the
+% integer expression for the leading digits is incremented (|+1|
+% in the code below). If the leading digits propagate this carry all
+% the way up, the function \cs{@@_parse_pack_carry:w} increments the
+% exponent, and changes the significand from |0000...| to |1000...|:
+% this is simple because such a carry can only occur to give rise to a
+% power of~$10$.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_pack_trailing:NNNNNNww #1 #2 #3#4#5#6 #7; #8 ;
+ {
+ \if_meaning:w 2 #2 + 1 \fi:
+ ; #8 + #1 ; {#3#4#5#6} {#7};
+ }
+\cs_new:Npn \@@_parse_pack_leading:NNNNNww #1 #2#3#4#5 #6; #7;
+ {
+ + #7
+ \if_meaning:w 2 #1 \@@_parse_pack_carry:w \fi:
+ ; 0 {#2#3#4#5} {#6}
+ }
+\cs_new:Npn \@@_parse_pack_carry:w \fi: ; 0 #1
+ { \fi: + 1 ; 0 {1000} }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Number: large significand}
+%
+% Parsing a significand larger than~$1$ is a little bit more difficult
+% than parsing small significands. We need to count the number of
+% digits before the decimal separator, and add that to the final
+% exponent. We also need to test for the presence of a dot each time we
+% run out of digits, and branch to the appropriate \texttt{parse_small}
+% function in those cases.
+%
+% \begin{macro}[EXP]{\@@_parse_large:N}
+% This function is followed by the first non-zero digit of a
+% \enquote{large} significand ($\geq 1$). It is called within an
+% integer expression for the exponent. Grab up to $7$~more digits,
+% for a total of $8$~digits.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_large:N #1
+ {
+ \exp_after:wN \@@_parse_large_leading:wwNN
+ \int_value:w 1 \token_to_str:N #1
+ \exp_after:wN \@@_parse_digits_vii:N
+ \exp:w \@@_parse_expand:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_parse_large_leading:wwNN}
+% \begin{syntax}
+% \cs{@@_parse_large_leading:wwNN} |1| \meta{digits} |;| \meta{zeros} |;| \meta{number~of~zeros} \meta{next~token}
+% \end{syntax}
+% We shift the exponent by the number of digits in~|#1|, namely the
+% target number, $8$, minus the \meta{number of zeros} (number of
+% digits missing). Then prepare to pack the $8$~first digits. If the
+% \meta{next token} is a digit, read up to $6$~more digits (digits
+% $10$ to~$15$). If it is a period, try to grab the end of our
+% $8$~first digits, branching to the \texttt{small} functions since
+% the number of digit does not affect the exponent anymore. Finally,
+% if this is the end of the significand, insert the \meta{zeros} to
+% complete the $8$~first digits, insert $8$~more, and look for an
+% exponent.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_large_leading:wwNN 1 #1 ; #2; #3 #4
+ {
+ + \c_@@_half_prec_int - #3
+ \exp_after:wN \@@_parse_pack_leading:NNNNNww
+ \int_value:w \@@_int_eval:w 1 #1
+ \if_int_compare:w 9 < 1 \token_to_str:N #4 \exp_stop_f:
+ \exp_after:wN \@@_parse_large_trailing:wwNN
+ \int_value:w 1 \token_to_str:N #4
+ \exp_after:wN \@@_parse_digits_vi:N
+ \exp:w
+ \else:
+ \if:w . \exp_not:N #4
+ \exp_after:wN \@@_parse_small_leading:wwNN
+ \int_value:w 1
+ \cs:w
+ @@_parse_digits_
+ \@@_int_to_roman:w #3
+ :N \exp_after:wN
+ \cs_end:
+ \exp:w
+ \else:
+ #2
+ \exp_after:wN \@@_parse_pack_trailing:NNNNNNww
+ \exp_after:wN 0
+ \int_value:w 1 0000 0000
+ \@@_parse_exponent:Nw #4
+ \fi:
+ \fi:
+ \@@_parse_expand:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_large_trailing:wwNN}
+% \begin{syntax}
+% \cs{@@_parse_large_trailing:wwNN} |1| \meta{digits} |;| \meta{zeros} |;| \meta{number~of~zeros} \meta{next~token}
+% \end{syntax}
+% We have just read $15$~digits. If the \meta{next token} is a digit,
+% then the exponent shift caused by this block of $8$~digits is~$8$,
+% first argument to the \texttt{pack_trailing} function. We keep the
+% \meta{digits} and this $16$-th digit, and find how this should be
+% rounded using \cs{@@_parse_large_round:NN}. Otherwise, the exponent
+% shift is the number of \meta{digits}, $7$~minus the \meta{number of
+% zeros}, and we test for a decimal point. This case happens in
+% |123451234512345.67| with exactly $15$ digits before the decimal
+% separator. Then branch to the appropriate \texttt{small} auxiliary,
+% grabbing a few more digits to complement the digits we already
+% grabbed. Finally, if this is truly the end of the significand, look
+% for an exponent after using the \meta{zeros} and providing a $16$-th
+% digit of~$0$.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_large_trailing:wwNN 1 #1 ; #2; #3 #4
+ {
+ \if_int_compare:w 9 < 1 \token_to_str:N #4 \exp_stop_f:
+ \exp_after:wN \@@_parse_pack_trailing:NNNNNNww
+ \exp_after:wN \c_@@_half_prec_int
+ \int_value:w \@@_int_eval:w 1 #1 \token_to_str:N #4
+ \exp_after:wN \@@_parse_large_round:NN
+ \exp_after:wN #4
+ \exp:w
+ \else:
+ \exp_after:wN \@@_parse_pack_trailing:NNNNNNww
+ \int_value:w \@@_int_eval:w 7 - #3 \exp_stop_f:
+ \int_value:w \@@_int_eval:w 1 #1
+ \if:w . \exp_not:N #4
+ \exp_after:wN \@@_parse_small_trailing:wwNN
+ \int_value:w 1
+ \cs:w
+ @@_parse_digits_
+ \@@_int_to_roman:w #3
+ :N \exp_after:wN
+ \cs_end:
+ \exp:w
+ \else:
+ #2 0 \@@_parse_exponent:Nw #4
+ \fi:
+ \fi:
+ \@@_parse_expand:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Number: beyond 16 digits, rounding}
+%
+% \begin{macro}[rEXP]{\@@_parse_round_loop:N, \@@_parse_round_up:N}
+% This loop is called when rounding a number (whether the mantissa is
+% small or large). It should appear in an integer expression. This
+% function reads digits one by one, until reaching a non-digit, and
+% adds~$1$ to the integer expression for each digit. If all digits
+% found are~$0$, the function ends the expression by |;0|,
+% otherwise by |;1|. This is done by switching the loop to
+% |round_up| at the first non-zero digit, thus we avoid to test
+% whether digits are~$0$ or not once we see a first non-zero digit.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_round_loop:N #1
+ {
+ \if_int_compare:w 9 < 1 \token_to_str:N #1 \exp_stop_f:
+ + 1
+ \if:w 0 \token_to_str:N #1
+ \exp_after:wN \@@_parse_round_loop:N
+ \exp:w
+ \else:
+ \exp_after:wN \@@_parse_round_up:N
+ \exp:w
+ \fi:
+ \else:
+ \@@_parse_return_semicolon:w 0 #1
+ \fi:
+ \@@_parse_expand:w
+ }
+\cs_new:Npn \@@_parse_round_up:N #1
+ {
+ \if_int_compare:w 9 < 1 \token_to_str:N #1 \exp_stop_f:
+ + 1
+ \exp_after:wN \@@_parse_round_up:N
+ \exp:w
+ \else:
+ \@@_parse_return_semicolon:w 1 #1
+ \fi:
+ \@@_parse_expand:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_parse_round_after:wN}
+% After the loop \cs{@@_parse_round_loop:N}, this function fetches an
+% exponent with \cs{@@_parse_exponent:N}, and combines it with the
+% number of digits counted by \cs{@@_parse_round_loop:N}. At the same
+% time, the result |0| or |1| is added to the
+% surrounding integer expression.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_round_after:wN #1; #2
+ {
+ + #2 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w #1 + \@@_parse_exponent:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {\@@_parse_small_round:NN, \@@_parse_round_after:wN}
+% Here, |#1|~is the digit that we are currently rounding (we only care
+% whether it is even or odd). If |#2|~is not a digit, then fetch an
+% exponent and expand to |;|\meta{exponent} only. Otherwise, we
+% expand to |+0| or |+1|, then |;|\meta{exponent}. To
+% decide which, call \cs{@@_round_s:NNNw} to know whether to round up,
+% giving it as arguments a sign~$0$ (all explicit numbers are
+% positive), the digit |#1|~to round, the first following digit~|#2|,
+% and either |+0| or |+1| depending on whether the
+% following digits are all zero or not. This last argument is
+% obtained by \cs{@@_parse_round_loop:N}, whose number of digits we
+% discard by multiplying it by~$0$. The exponent which follows the
+% number is also fetched by \cs{@@_parse_round_after:wN}.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_small_round:NN #1#2
+ {
+ \if_int_compare:w 9 < 1 \token_to_str:N #2 \exp_stop_f:
+ +
+ \exp_after:wN \@@_round_s:NNNw
+ \exp_after:wN 0
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \int_value:w \@@_int_eval:w
+ \exp_after:wN \@@_parse_round_after:wN
+ \int_value:w \@@_int_eval:w 0 * \@@_int_eval:w 0
+ \exp_after:wN \@@_parse_round_loop:N
+ \exp:w
+ \else:
+ \@@_parse_exponent:Nw #2
+ \fi:
+ \@@_parse_expand:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}[rEXP]
+% {
+% \@@_parse_large_round:NN,
+% \@@_parse_large_round_test:NN,
+% \@@_parse_large_round_aux:wNN,
+% }
+% Large numbers are harder to round, as there may be a period in the
+% way. Again, |#1|~is the digit that we are currently rounding (we
+% only care whether it is even or odd). If there are no more digits
+% (|#2|~is not a digit), then we must test for a period: if there is
+% one, then switch to the rounding function for small significands,
+% otherwise fetch an exponent. If there are more digits (|#2|~is a
+% digit), then round, checking with \cs{@@_parse_round_loop:N} if all
+% further digits vanish, or some are non-zero. This loop is not
+% enough, as it is stopped by a period. After the loop, the
+% \texttt{aux} function tests for a period: if it is present, then we
+% must continue looking for digits, this time discarding the number of
+% digits we find.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_large_round:NN #1#2
+ {
+ \if_int_compare:w 9 < 1 \token_to_str:N #2 \exp_stop_f:
+ +
+ \exp_after:wN \@@_round_s:NNNw
+ \exp_after:wN 0
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \int_value:w \@@_int_eval:w
+ \exp_after:wN \@@_parse_large_round_aux:wNN
+ \int_value:w \@@_int_eval:w 1
+ \exp_after:wN \@@_parse_round_loop:N
+ \else: %^^A could be dot, or e, or other
+ \exp_after:wN \@@_parse_large_round_test:NN
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \fi:
+ }
+\cs_new:Npn \@@_parse_large_round_test:NN #1#2
+ {
+ \if:w . \exp_not:N #2
+ \exp_after:wN \@@_parse_small_round:NN
+ \exp_after:wN #1
+ \exp:w
+ \else:
+ \@@_parse_exponent:Nw #2
+ \fi:
+ \@@_parse_expand:w
+ }
+\cs_new:Npn \@@_parse_large_round_aux:wNN #1 ; #2 #3
+ {
+ + #2
+ \exp_after:wN \@@_parse_round_after:wN
+ \int_value:w \@@_int_eval:w #1
+ \if:w . \exp_not:N #3
+ + 0 * \@@_int_eval:w 0
+ \exp_after:wN \@@_parse_round_loop:N
+ \exp:w \exp_after:wN \@@_parse_expand:w
+ \else:
+ \exp_after:wN ;
+ \exp_after:wN 0
+ \exp_after:wN #3
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Number: finding the exponent}
+%
+% Expansion is a little bit tricky here, in part because we accept input
+% where multiplication is implicit.
+% \begin{syntax}
+% \cs{@@_parse:n} |{ 3.2 erf(0.1) }|
+% \cs{@@_parse:n} |{ 3.2 e\l_my_int }|
+% \cs{@@_parse:n} |{ 3.2 \c_pi_fp }|
+% \end{syntax}
+% The first case indicates that just looking one character ahead for an
+% \enquote{\texttt{e}} is not enough, since we would mistake the
+% function \texttt{erf} for an exponent of \enquote{\texttt{rf}}. An
+% alternative would be to look two tokens ahead and check if what
+% follows is a sign or a digit, considering in that case that we must be
+% finding an exponent. But taking care of the second case requires that
+% we unpack registers after \texttt{e}. However, blindly expanding the
+% two tokens ahead completely would break the third example (unpacking
+% is even worse). Indeed, in the course of reading $3.2$, \cs{c_pi_fp}
+% is expanded to \cs{s_@@} \cs{@@_chk:w} |1| |0| |{-1}| |{3141}|
+% $\cdots$ |;| and \cs{s_@@} stops the expansion. Expanding two tokens
+% ahead would then force the expansion of \cs{@@_chk:w} (despite it
+% being protected), and that function tries to produce an error.
+%
+% What can we do? Really, the reason why this last case breaks is that
+% just as \TeX{} does, we should read ahead as little as possible.
+% Here, the only case where there may be an exponent is if the first
+% token ahead is |e|. Then we expand (and possibly unpack) the second
+% token.
+%
+% \begin{macro}[rEXP]{\@@_parse_exponent:Nw}
+% This auxiliary is convenient to smuggle some material through
+% \cs{fi:} ending conditional processing. We place those \cs{fi:}
+% (argument~|#2|) at a very odd place because this allows us to insert
+% \cs{@@_int_eval:w} \ldots{} there if needed.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_exponent:Nw #1 #2 \@@_parse_expand:w
+ {
+ \exp_after:wN ;
+ \int_value:w #2 \@@_parse_exponent:N #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {\@@_parse_exponent:N, \@@_parse_exponent_aux:NN}
+% This function should be called within an \cs{int_value:w}
+% expansion (or within an integer expression). It leaves digits of the
+% exponent behind it in the input stream, and terminates the expansion
+% with a semicolon. If there is no~|e| (or~|E|), leave an exponent of~$0$. If
+% there is an~|e| or~|E|, expand the next token to run some tests on it. The
+% first rough test is that if the character code of~|#1| is greater
+% than that of~|9| (largest code valid for an exponent, less than any
+% code valid for an identifier), there was in fact no exponent;
+% otherwise, we search for the sign of the exponent.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_exponent:N #1
+ {
+ \if:w e \if:w E \exp_not:N #1 e \else: \exp_not:N #1 \fi:
+ \exp_after:wN \@@_parse_exponent_aux:NN
+ \exp_after:wN #1
+ \exp:w
+ \else:
+ 0 \@@_parse_return_semicolon:w #1
+ \fi:
+ \@@_parse_expand:w
+ }
+\cs_new:Npn \@@_parse_exponent_aux:NN #1#2
+ {
+ \if_int_compare:w \if_catcode:w \scan_stop: \exp_not:N #2
+ 0 \else: `#2 \fi: > `9 \exp_stop_f:
+ 0 \exp_after:wN ; \exp_after:wN #1
+ \else:
+ \exp_after:wN \@@_parse_exponent_sign:N
+ \fi:
+ #2
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_parse_exponent_sign:N}
+% Read signs one by one (if there is any).
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_exponent_sign:N #1
+ {
+ \if:w + \if:w - \exp_not:N #1 + \fi: \token_to_str:N #1
+ \exp_after:wN \@@_parse_exponent_sign:N
+ \exp:w \exp_after:wN \@@_parse_expand:w
+ \else:
+ \exp_after:wN \@@_parse_exponent_body:N
+ \exp_after:wN #1
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_parse_exponent_body:N}
+% An exponent can be an explicit integer (most common case), or
+% various other things (most of which are invalid).
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_exponent_body:N #1
+ {
+ \if_int_compare:w 9 < 1 \token_to_str:N #1 \exp_stop_f:
+ \token_to_str:N #1
+ \exp_after:wN \@@_parse_exponent_digits:N
+ \exp:w
+ \else:
+ \@@_parse_exponent_keep:NTF #1
+ { \@@_parse_return_semicolon:w #1 }
+ {
+ \exp_after:wN ;
+ \exp:w
+ }
+ \fi:
+ \@@_parse_expand:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_parse_exponent_digits:N}
+% Read digits one by one, and leave them behind in the input stream.
+% When finding a non-digit, stop, and insert a semicolon. Note that
+% we do not check for overflow of the exponent, hence there can be a
+% \TeX{} error. It is mostly harmless, except when parsing
+% |0e9876543210|, which should be a valid representation of $0$, but
+% is not.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_exponent_digits:N #1
+ {
+ \if_int_compare:w 9 < 1 \token_to_str:N #1 \exp_stop_f:
+ \token_to_str:N #1
+ \exp_after:wN \@@_parse_exponent_digits:N
+ \exp:w
+ \else:
+ \@@_parse_return_semicolon:w #1
+ \fi:
+ \@@_parse_expand:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_parse_exponent_keep:NTF}
+% This is the last building block for parsing exponents. The
+% argument~|#1| is already fully expanded, and neither |+| nor~|-| nor
+% a digit. It can be:
+% \begin{itemize}
+% \item \cs{s_@@}, marking the start of an internal floating point,
+% invalid here;
+% \item another control sequence equal to \tn{relax}, probably a bad
+% variable;
+% \item a register: in this case we make sure that it is an integer
+% register, not a dimension;
+% \item a character other than |+|, |-| or digits, again, an error.
+% \end{itemize}
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_parse_exponent_keep:N #1 { TF }
+ {
+ \if_catcode:w \scan_stop: \exp_not:N #1
+ \if_meaning:w \scan_stop: #1
+ \if:w 0 \@@_str_if_eq:nn { \s_@@ } { \exp_not:N #1 }
+ 0
+ \msg_expandable_error:nnn
+ { fp } { after-e } { floating~point~ }
+ \prg_return_true:
+ \else:
+ 0
+ \msg_expandable_error:nnn
+ { kernel } { bad-variable } {#1}
+ \prg_return_false:
+ \fi:
+ \else:
+ \if:w 0 \@@_str_if_eq:nn { \int_value:w #1 } { \tex_the:D #1 }
+ \int_value:w #1
+ \else:
+ 0
+ \msg_expandable_error:nnn
+ { fp } { after-e } { dimension~#1 }
+ \fi:
+ \prg_return_false:
+ \fi:
+ \else:
+ 0
+ \msg_expandable_error:nnn
+ { fp } { missing } { exponent }
+ \prg_return_true:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Constants, functions and prefix operators}
+%
+% \subsubsection{Prefix operators}
+%
+% \begin{macro}[EXP]{\@@_parse_prefix_+:Nw}
+% A unary~|+| does nothing: we should continue looking for a number.
+% \begin{macrocode}
+\cs_new_eq:cN { @@_parse_prefix_+:Nw } \@@_parse_one:Nw
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_apply_function:NNNwN}
+% Here, |#1| is a precedence, |#2| is some extra data used by some
+% functions, |#3| is \emph{e.g.}, \cs{@@_sin_o:w}, and expands once
+% after the calculation, |#4| is the operand, and |#5| is a
+% \cs[no-index]{@@_parse_infix_\ldots{}:N} function. We feed the data~|#2|, and the
+% argument~|#4|, to the function~|#3|, which expands
+% \cs{exp:w} thus the \texttt{infix} function~|#5|.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_apply_function:NNNwN #1#2#3#4@#5
+ {
+ #3 #2 #4 @
+ \exp:w \exp_end_continue_f:w #5 #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_apply_unary:NNNwN}
+% \begin{macro}[EXP]{\@@_parse_apply_unary_chk:NwNw, \@@_parse_apply_unary_chk:nNNNw}
+% \begin{macro}[EXP]{\@@_parse_apply_unary_type:NNN, \@@_parse_apply_unary_error:NNw}
+% In contrast to \cs{@@_parse_apply_function:NNNwN}, this checks that
+% the operand |#4| is a single argument (namely there is a single
+% |;|). We use the fact that any floating point starts with a
+% \enquote{safe} token like \cs{s_@@}. If there is no argument
+% produce the |fp-no-arg| error; if there are at least two produce
+% |fp-multi-arg|. For the error message extract the mathematical
+% function name (such as |sin|) from the \pkg{expl3} function that
+% computes it, such as \cs{@@_sin_o:w}.
+%
+% In addition, since there is a single argument we can dispatch on
+% type and check that the resulting function exists. This catches
+% things like |sin((1,2))| where it does not make sense to take the
+% sine of a tuple.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_apply_unary:NNNwN #1#2#3#4@#5
+ {
+ \@@_parse_apply_unary_chk:NwNw #4 @ ; . \s_@@_stop
+ \@@_parse_apply_unary_type:NNN
+ #3 #2 #4 @
+ \exp:w \exp_end_continue_f:w #5 #1
+ }
+\cs_new:Npn \@@_parse_apply_unary_chk:NwNw #1#2 ; #3#4 \s_@@_stop
+ {
+ \if_meaning:w @ #3 \else:
+ \token_if_eq_meaning:NNTF . #3
+ { \@@_parse_apply_unary_chk:nNNNNw { no } }
+ { \@@_parse_apply_unary_chk:nNNNNw { multi } }
+ \fi:
+ }
+\cs_new:Npn \@@_parse_apply_unary_chk:nNNNNw #1#2#3#4#5#6 @
+ {
+ #2
+ \@@_error:nffn { #1-arg } { \@@_func_to_name:N #4 } { } { }
+ \exp_after:wN #4 \exp_after:wN #5 \c_nan_fp @
+ }
+\cs_new:Npn \@@_parse_apply_unary_type:NNN #1#2#3
+ {
+ \@@_change_func_type:NNN #3 #1 \@@_parse_apply_unary_error:NNw
+ #2 #3
+ }
+\cs_new:Npn \@@_parse_apply_unary_error:NNw #1#2#3 @
+ { \@@_invalid_operation_o:fw { \@@_func_to_name:N #1 } #3 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_prefix_-:Nw, \@@_parse_prefix_!:Nw}
+% The unary~|-| and boolean not are harder: we parse the operand using
+% a precedence equal to the maximum of the previous precedence~|##1|
+% and the precedence \cs{c_@@_prec_not_int} of the unary operator, then call
+% the appropriate |\__fp_|\meta{operation}|_o:w| function,
+% where the \meta{operation} is |set_sign| or |not|.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1#2#3#4
+ {
+ \cs_new:cpn { @@_parse_prefix_ #1 :Nw } ##1
+ {
+ \exp_after:wN \@@_parse_apply_unary:NNNwN
+ \exp_after:wN ##1
+ \exp_after:wN #4
+ \exp_after:wN #3
+ \exp:w
+ \if_int_compare:w #2 < ##1
+ \@@_parse_operand:Nw ##1
+ \else:
+ \@@_parse_operand:Nw #2
+ \fi:
+ \@@_parse_expand:w
+ }
+ }
+\@@_tmp:w - \c_@@_prec_not_int \@@_set_sign_o:w 2
+\@@_tmp:w ! \c_@@_prec_not_int \@@_not_o:w ?
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_prefix_.:Nw}
+% Numbers which start with a decimal separator (a~period) end up here.
+% Of course, we do not look for an operand, but for the rest of the
+% number. This function is very similar to \cs{@@_parse_one_digit:NN}
+% but calls \cs{@@_parse_strim_zeros:N} to trim zeros after the
+% decimal point, rather than the \texttt{trim_zeros} function for
+% zeros before the decimal point.
+% \begin{macrocode}
+\cs_new:cpn { @@_parse_prefix_.:Nw } #1
+ {
+ \exp_after:wN \@@_parse_infix_after_operand:NwN
+ \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w
+ \exp_after:wN \@@_sanitize:wN
+ \int_value:w \@@_int_eval:w 0 \@@_parse_strim_zeros:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_parse_prefix_(:Nw, \@@_parse_lparen_after:NwN}
+% The left parenthesis is treated as a unary prefix operator because
+% it appears in exactly the same settings. If the previous precedence
+% is \cs{c_@@_prec_func_int} we are parsing arguments of a function
+% and commas should not build tuples; otherwise commas should build
+% tuples. We distinguish these cases by precedence:
+% \cs{c_@@_prec_comma_int} for the case of arguments,
+% \cs{c_@@_prec_tuple_int} for the case of tuples.
+% Once the operand is found, the \texttt{lparen_after} auxiliary makes
+% sure that there was a closing parenthesis (otherwise it complains),
+% and leaves in the input stream an operand,
+% fetching the following infix operator.
+% \begin{macrocode}
+\cs_new:cpn { @@_parse_prefix_(:Nw } #1
+ {
+ \exp_after:wN \@@_parse_lparen_after:NwN
+ \exp_after:wN #1
+ \exp:w
+ \if_int_compare:w #1 = \c_@@_prec_func_int
+ \@@_parse_operand:Nw \c_@@_prec_comma_int
+ \else:
+ \@@_parse_operand:Nw \c_@@_prec_tuple_int
+ \fi:
+ \@@_parse_expand:w
+ }
+\cs_new:Npe \@@_parse_lparen_after:NwN #1#2 @ #3
+ {
+ \exp_not:N \token_if_eq_meaning:NNTF #3
+ \exp_not:c { @@_parse_infix_):N }
+ {
+ \exp_not:N \@@_exp_after_array_f:w #2 \s_@@_expr_stop
+ \exp_not:N \exp_after:wN
+ \exp_not:N \@@_parse_infix_after_paren:NN
+ \exp_not:N \exp_after:wN #1
+ \exp_not:N \exp:w
+ \exp_not:N \@@_parse_expand:w
+ }
+ {
+ \exp_not:N \msg_expandable_error:nnn
+ { fp } { missing } { ) }
+ \exp_not:N \tl_if_empty:nT {#2} \exp_not:N \c_@@_empty_tuple_fp
+ #2 @
+ \exp_not:N \use_none:n #3
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_prefix_):Nw}
+% The right parenthesis can appear as a prefix in two similar cases:
+% in an empty tuple or tuple ending with a comma, or in an empty
+% argument list or argument list ending with a comma, such as in
+% |max(1,2,)| or in |rand()|.
+% \begin{macrocode}
+\cs_new:cpn { @@_parse_prefix_):Nw } #1
+ {
+ \if_int_compare:w #1 = \c_@@_prec_comma_int
+ \else:
+ \if_int_compare:w #1 = \c_@@_prec_tuple_int
+ \exp_after:wN \c_@@_empty_tuple_fp \exp:w
+ \else:
+ \msg_expandable_error:nnn
+ { fp } { missing-number } { ) }
+ \exp_after:wN \c_nan_fp \exp:w
+ \fi:
+ \exp_end_continue_f:w
+ \fi:
+ \@@_parse_infix_after_paren:NN #1 )
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Constants}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_word_inf:N , \@@_parse_word_nan:N ,
+% \@@_parse_word_pi:N , \@@_parse_word_deg:N ,
+% \@@_parse_word_true:N , \@@_parse_word_false:N ,
+% }
+% Some words correspond to constant floating points. The floating
+% point constant is left as a result of \cs{@@_parse_one:Nw} after
+% expanding \cs{@@_parse_infix:NN}.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1 #2
+ {
+ \cs_new:cpn { @@_parse_word_#1:N }
+ { \exp_after:wN #2 \exp:w \exp_end_continue_f:w \@@_parse_infix:NN }
+ }
+\@@_tmp:w { inf } \c_inf_fp
+\@@_tmp:w { nan } \c_nan_fp
+\@@_tmp:w { pi } \c_pi_fp
+\@@_tmp:w { deg } \c_one_degree_fp
+\@@_tmp:w { true } \c_one_fp
+\@@_tmp:w { false } \c_zero_fp
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_caseless_inf:N,
+% \@@_parse_caseless_infinity:N,
+% \@@_parse_caseless_nan:N
+% }
+% Copies of \cs[no-index]{@@_parse_word_\ldots{}:N} commands, to allow
+% arbitrary case as mandated by the standard.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_parse_caseless_inf:N \@@_parse_word_inf:N
+\cs_new_eq:NN \@@_parse_caseless_infinity:N \@@_parse_word_inf:N
+\cs_new_eq:NN \@@_parse_caseless_nan:N \@@_parse_word_nan:N
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_word_pt:N , \@@_parse_word_in:N ,
+% \@@_parse_word_pc:N , \@@_parse_word_cm:N , \@@_parse_word_mm:N ,
+% \@@_parse_word_dd:N , \@@_parse_word_cc:N , \@@_parse_word_nd:N ,
+% \@@_parse_word_nc:N , \@@_parse_word_bp:N , \@@_parse_word_sp:N ,
+% }
+% Dimension units are also floating point constants but their value is
+% not stored as a floating point constant. We give the values
+% explicitly here.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1 #2
+ {
+ \cs_new:cpn { @@_parse_word_#1:N }
+ {
+ \@@_exp_after_f:nw { \@@_parse_infix:NN }
+ \s_@@ \@@_chk:w 10 #2 ;
+ }
+ }
+\@@_tmp:w {pt} { {1} {1000} {0000} {0000} {0000} }
+\@@_tmp:w {in} { {2} {7227} {0000} {0000} {0000} }
+\@@_tmp:w {pc} { {2} {1200} {0000} {0000} {0000} }
+\@@_tmp:w {cm} { {2} {2845} {2755} {9055} {1181} }
+\@@_tmp:w {mm} { {1} {2845} {2755} {9055} {1181} }
+\@@_tmp:w {dd} { {1} {1070} {0085} {6496} {0630} }
+\@@_tmp:w {cc} { {2} {1284} {0102} {7795} {2756} }
+\@@_tmp:w {nd} { {1} {1066} {9783} {4645} {6693} }
+\@@_tmp:w {nc} { {2} {1280} {3740} {1574} {8031} }
+\@@_tmp:w {bp} { {1} {1003} {7500} {0000} {0000} }
+\@@_tmp:w {sp} { {-4} {1525} {8789} {0625} {0000} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_word_em:N, \@@_parse_word_ex:N}
+% The font-dependent units |em| and |ex| must be evaluated on the fly.
+% We reuse an auxiliary of \cs{dim_to_fp:n}.
+% \begin{macrocode}
+\tl_map_inline:nn { {em} {ex} }
+ {
+ \cs_new:cpn { @@_parse_word_#1:N }
+ {
+ \exp_after:wN \@@_from_dim_test:ww
+ \exp_after:wN 0 \exp_after:wN ,
+ \int_value:w \dim_to_decimal_in_sp:n { 1 #1 } \exp_after:wN ;
+ \exp:w \exp_end_continue_f:w \@@_parse_infix:NN
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Functions}
+%
+% ^^A begin[todo]
+%
+% \begin{macro}[EXP]
+% {\@@_parse_unary_function:NNN, \@@_parse_function:NNN}
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_unary_function:NNN #1#2#3
+ {
+ \exp_after:wN \@@_parse_apply_unary:NNNwN
+ \exp_after:wN #3
+ \exp_after:wN #2
+ \exp_after:wN #1
+ \exp:w
+ \@@_parse_operand:Nw \c_@@_prec_func_int \@@_parse_expand:w
+ }
+\cs_new:Npn \@@_parse_function:NNN #1#2#3
+ {
+ \exp_after:wN \@@_parse_apply_function:NNNwN
+ \exp_after:wN #3
+ \exp_after:wN #2
+ \exp_after:wN #1
+ \exp:w
+ \@@_parse_operand:Nw \c_@@_prec_func_int \@@_parse_expand:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Main functions}
+%
+% \begin{macro}[EXP]{\@@_parse:n, \@@_parse_o:n}
+% \begin{macro}[EXP]{\@@_parse_after:ww}
+% Start an \cs{exp:w} expansion so that \cs{@@_parse:n} expands
+% in two steps. The \cs{@@_parse_operand:Nw} function performs
+% computations until reaching an operation with precedence
+% \cs{c_@@_prec_end_int} or less, namely, the end of the expression. The
+% marker \cs{s_@@_expr_mark} indicates that the next token is an already
+% parsed version of an infix operator, and \cs{@@_parse_infix_end:N}
+% has infinitely negative precedence. Finally, clean up a
+% (well-defined) set of extra tokens and stop the initial expansion
+% with \cs{exp_end:}.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse:n #1
+ {
+ \exp:w
+ \exp_after:wN \@@_parse_after:ww
+ \exp:w
+ \@@_parse_operand:Nw \c_@@_prec_end_int
+ \@@_parse_expand:w #1
+ \s_@@_expr_mark \@@_parse_infix_end:N
+ \s_@@_expr_stop
+ \exp_end:
+ }
+\cs_new:Npn \@@_parse_after:ww
+ #1@ \@@_parse_infix_end:N \s_@@_expr_stop #2 { #2 #1 }
+\cs_new:Npn \@@_parse_o:n #1
+ {
+ \exp:w
+ \exp_after:wN \@@_parse_after:ww
+ \exp:w
+ \@@_parse_operand:Nw \c_@@_prec_end_int
+ \@@_parse_expand:w #1
+ \s_@@_expr_mark \@@_parse_infix_end:N
+ \s_@@_expr_stop
+ {
+ \exp_end_continue_f:w
+ \@@_exp_after_any_f:nw { \exp_after:wN \exp_stop_f: }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_operand:Nw}
+% \begin{macro}[EXP]{\@@_parse_continue:NwN}
+% This is just a shorthand which sets up both \cs{@@_parse_continue:NwN}
+% and \cs{@@_parse_one:Nw} with the same precedence. Note the
+% trailing \cs{exp:w}.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_operand:Nw #1
+ {
+ \exp_end_continue_f:w
+ \exp_after:wN \@@_parse_continue:NwN
+ \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w
+ \exp_after:wN \@@_parse_one:Nw
+ \exp_after:wN #1
+ \exp:w
+ }
+\cs_new:Npn \@@_parse_continue:NwN #1 #2 @ #3 { #3 #1 #2 @ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_apply_binary:NwNwN}
+% \begin{macro}[EXP]
+% {\@@_parse_apply_binary_chk:NN, \@@_parse_apply_binary_error:NNN}
+% Receives \meta{precedence} \meta{operand_1} |@| \meta{operation}
+% \meta{operand_2} |@| \meta{infix command}. Builds the appropriate
+% call to the \meta{operation}~|#3|, dispatching on both types.
+% If the resulting control sequence does not exist, the operation is
+% not allowed.
+%
+% This is redefined in \pkg{l3fp-extras}.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_apply_binary:NwNwN #1 #2#3@ #4 #5#6@ #7
+ {
+ \exp_after:wN \@@_parse_continue:NwN
+ \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w
+ \exp_after:wN \@@_parse_apply_binary_chk:NN
+ \cs:w
+ @@
+ \@@_type_from_scan:N #2
+ _#4
+ \@@_type_from_scan:N #5
+ _o:ww
+ \cs_end:
+ #4
+ #2#3 #5#6
+ \exp:w \exp_end_continue_f:w #7 #1
+ }
+\cs_new:Npn \@@_parse_apply_binary_chk:NN #1#2
+ {
+ \if_meaning:w \scan_stop: #1
+ \@@_parse_apply_binary_error:NNN #2
+ \fi:
+ #1
+ }
+\cs_new:Npn \@@_parse_apply_binary_error:NNN #1#2#3
+ {
+ #2
+ \@@_invalid_operation_o:Nww #1
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_binary_type_o:Nww, \@@_binary_rev_type_o:Nww}
+% Applies the operator |#1| to its two arguments, dispatching
+% according to their types, and expands once after the result.
+% The |rev| version swaps its arguments before doing this.
+% \begin{macrocode}
+\cs_new:Npn \@@_binary_type_o:Nww #1 #2#3 ; #4
+ {
+ \exp_after:wN \@@_parse_apply_binary_chk:NN
+ \cs:w
+ @@
+ \@@_type_from_scan:N #2
+ _ #1
+ \@@_type_from_scan:N #4
+ _o:ww
+ \cs_end:
+ #1
+ #2 #3 ; #4
+ }
+\cs_new:Npn \@@_binary_rev_type_o:Nww #1 #2#3 ; #4#5 ;
+ {
+ \exp_after:wN \@@_parse_apply_binary_chk:NN
+ \cs:w
+ @@
+ \@@_type_from_scan:N #4
+ _ #1
+ \@@_type_from_scan:N #2
+ _o:ww
+ \cs_end:
+ #1
+ #4 #5 ; #2 #3 ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Infix operators}
+%
+% \begin{macro}[EXP]{\@@_parse_infix_after_operand:NwN}
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_infix_after_operand:NwN #1 #2;
+ {
+ \@@_exp_after_f:nw { \@@_parse_infix:NN #1 }
+ #2;
+ }
+\cs_new:Npn \@@_parse_infix:NN #1 #2
+ {
+ \if_catcode:w \scan_stop: \exp_not:N #2
+ \if:w 0 \@@_str_if_eq:nn { \s_@@_expr_mark } { \exp_not:N #2 }
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_parse_infix_mark:NNN
+ \else:
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_parse_infix_juxt:N
+ \fi:
+ \else:
+ \if_int_compare:w
+ \@@_int_eval:w
+ ( `#2 \if_int_compare:w `#2 > `Z - 32 \fi: ) / 26
+ = 3 \exp_stop_f:
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_parse_infix_juxt:N
+ \else:
+ \exp_after:wN \@@_parse_infix_check:NNN
+ \cs:w
+ @@_parse_infix_ \token_to_str:N #2 :N
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \cs_end:
+ \fi:
+ \fi:
+ #1
+ #2
+ }
+\cs_new:Npn \@@_parse_infix_check:NNN #1#2#3
+ {
+ \if_meaning:w \scan_stop: #1
+ \msg_expandable_error:nnn
+ { fp } { missing } { * }
+ \exp_after:wN \@@_parse_infix_mul:N
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \else:
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp:w \exp_after:wN \@@_parse_expand:w
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_parse_infix_after_paren:NN}
+% Variant of \cs{@@_parse_infix:NN} for use after a closing
+% parenthesis. The only difference is that \cs{@@_parse_infix_juxt:N}
+% is replaced by \cs{@@_parse_infix_mul:N}.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_infix_after_paren:NN #1 #2
+ {
+ \if_catcode:w \scan_stop: \exp_not:N #2
+ \if:w 0 \@@_str_if_eq:nn { \s_@@_expr_mark } { \exp_not:N #2 }
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_parse_infix_mark:NNN
+ \else:
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_parse_infix_mul:N
+ \fi:
+ \else:
+ \if_int_compare:w
+ \@@_int_eval:w
+ ( `#2 \if_int_compare:w `#2 > `Z - 32 \fi: ) / 26
+ = 3 \exp_stop_f:
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_parse_infix_mul:N
+ \else:
+ \exp_after:wN \@@_parse_infix_check:NNN
+ \cs:w
+ @@_parse_infix_ \token_to_str:N #2 :N
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \cs_end:
+ \fi:
+ \fi:
+ #1
+ #2
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Closing parentheses and commas}
+%
+% \begin{macro}[EXP]{\@@_parse_infix_mark:NNN}
+% As an infix operator, \cs{s_@@_expr_mark} means that the next
+% token~(|#3|) has already gone through \cs{@@_parse_infix:NN} and
+% should be provided the precedence~|#1|. The scan mark~|#2| is
+% discarded.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_infix_mark:NNN #1#2#3 { #3 #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_infix_end:N}
+% This one is a little bit odd: force every previous operator to end,
+% regardless of the precedence.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_infix_end:N #1
+ { @ \use_none:n \@@_parse_infix_end:N }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]+\@@_parse_infix_):N+
+% This is very similar to \cs{@@_parse_infix_end:N}, complaining about
+% an extra closing parenthesis if the previous operator was the
+% beginning of the expression, with precedence \cs{c_@@_prec_end_int}.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \cs_new:Npn #1 ##1
+ {
+ \if_int_compare:w ##1 > \c_@@_prec_end_int
+ \exp_after:wN @
+ \exp_after:wN \use_none:n
+ \exp_after:wN #1
+ \else:
+ \msg_expandable_error:nnn { fp } { extra } { ) }
+ \exp_after:wN \@@_parse_infix:NN
+ \exp_after:wN ##1
+ \exp:w \exp_after:wN \@@_parse_expand:w
+ \fi:
+ }
+ }
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_):N }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[verb, EXP]{\__fp_parse_infix_,:N}
+% \begin{macro}[EXP]{\@@_parse_infix_comma:w, \@@_parse_apply_comma:NwNwN}
+% As for other infix operations, if the previous operations has higher
+% precedence the comma waits. Otherwise we call
+% \cs{@@_parse_operand:Nw} to read more comma-delimited arguments that
+% \cs{@@_parse_infix_comma:w} simply concatenates into a |@|-delimited
+% array. The first comma in a tuple that is not a function argument
+% is distinguished: in that case call \cs{@@_parse_apply_comma:NwNwN}
+% whose job is to convert the first item of the tuple and an array of
+% the remaining items into a tuple. In contrast to
+% \cs{@@_parse_apply_binary:NwNwN} this function's operands are not
+% single-object arrays.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \cs_new:Npn #1 ##1
+ {
+ \if_int_compare:w ##1 > \c_@@_prec_comma_int
+ \exp_after:wN @
+ \exp_after:wN \use_none:n
+ \exp_after:wN #1
+ \else:
+ \if_int_compare:w ##1 < \c_@@_prec_comma_int
+ \exp_after:wN @
+ \exp_after:wN \@@_parse_apply_comma:NwNwN
+ \exp_after:wN ,
+ \exp:w
+ \else:
+ \exp_after:wN \@@_parse_infix_comma:w
+ \exp:w
+ \fi:
+ \@@_parse_operand:Nw \c_@@_prec_comma_int
+ \exp_after:wN \@@_parse_expand:w
+ \fi:
+ }
+ }
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_,:N }
+\cs_new:Npn \@@_parse_infix_comma:w #1 @
+ { #1 @ \use_none:n }
+\cs_new:Npn \@@_parse_apply_comma:NwNwN #1 #2@ #3 #4@ #5
+ {
+ \exp_after:wN \@@_parse_continue:NwN
+ \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w
+ \@@_exp_after_tuple_f:nw { }
+ \s_@@_tuple \@@_tuple_chk:w { #2 #4 } ;
+ #5 #1
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Usual infix operators}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_infix_+:N, \@@_parse_infix_-:N,
+% \@@_parse_infix_juxt:N,
+% \@@_parse_infix_/:N, \@@_parse_infix_mul:N,
+% \@@_parse_infix_and:N, \@@_parse_infix_or:N,
+% }
+% \begin{macro}[EXP]+\@@_parse_infix_^:N+
+% As described in the \enquote{work plan}, each infix operator has an
+% associated |\..._infix_...| function, a computing function, and
+% precedence, given as arguments to \cs{@@_tmp:w}. Using the general
+% mechanism for arithmetic operations. The power operation must be
+% associative in the opposite order from all others. For this, we use
+% two distinct precedences.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1#2#3#4
+ {
+ \cs_new:Npn #1 ##1
+ {
+ \if_int_compare:w ##1 < #3
+ \exp_after:wN @
+ \exp_after:wN \@@_parse_apply_binary:NwNwN
+ \exp_after:wN #2
+ \exp:w
+ \@@_parse_operand:Nw #4
+ \exp_after:wN \@@_parse_expand:w
+ \else:
+ \exp_after:wN @
+ \exp_after:wN \use_none:n
+ \exp_after:wN #1
+ \fi:
+ }
+ }
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_^:N } ^
+ \c_@@_prec_hatii_int \c_@@_prec_hat_int
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_juxt:N } *
+ \c_@@_prec_juxt_int \c_@@_prec_juxt_int
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_/:N } /
+ \c_@@_prec_times_int \c_@@_prec_times_int
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_mul:N } *
+ \c_@@_prec_times_int \c_@@_prec_times_int
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_-:N } -
+ \c_@@_prec_plus_int \c_@@_prec_plus_int
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_+:N } +
+ \c_@@_prec_plus_int \c_@@_prec_plus_int
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_and:N } &
+ \c_@@_prec_and_int \c_@@_prec_and_int
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_or:N } |
+ \c_@@_prec_or_int \c_@@_prec_or_int
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Juxtaposition}
+%
+% \begin{macro}[EXP]+\@@_parse_infix_(:N+
+% When an opening parenthesis appears where we expect an infix
+% operator, we compute the product of the previous operand and the
+% contents of the parentheses using \cs{@@_parse_infix_mul:N}.
+% \begin{macrocode}
+\cs_new:cpn { @@_parse_infix_(:N } #1
+ { \@@_parse_infix_mul:N #1 ( }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Multi-character cases}
+%
+% \begin{macro}[EXP]{\@@_parse_infix_*:N}
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \cs_new:cpn { @@_parse_infix_*:N } ##1##2
+ {
+ \if:w * \exp_not:N ##2
+ \exp_after:wN #1
+ \exp_after:wN ##1
+ \else:
+ \exp_after:wN \@@_parse_infix_mul:N
+ \exp_after:wN ##1
+ \exp_after:wN ##2
+ \fi:
+ }
+ }
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_^:N }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]+\@@_parse_infix_|:Nw+
+% \begin{macro}[EXP]+\@@_parse_infix_&:Nw+
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1#2#3
+ {
+ \cs_new:Npn #1 ##1##2
+ {
+ \if:w #2 \exp_not:N ##2
+ \exp_after:wN #1
+ \exp_after:wN ##1
+ \exp:w \exp_after:wN \@@_parse_expand:w
+ \else:
+ \exp_after:wN #3
+ \exp_after:wN ##1
+ \exp_after:wN ##2
+ \fi:
+ }
+ }
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_|:N } | \@@_parse_infix_or:N
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_&:N } & \@@_parse_infix_and:N
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Ternary operator}
+%
+% \begin{macro}[EXP]{\@@_parse_infix_?:N, \@@_parse_infix_::N}
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1#2#3#4
+ {
+ \cs_new:Npn #1 ##1
+ {
+ \if_int_compare:w ##1 < \c_@@_prec_quest_int
+ #4
+ \exp_after:wN @
+ \exp_after:wN #2
+ \exp:w
+ \@@_parse_operand:Nw #3
+ \exp_after:wN \@@_parse_expand:w
+ \else:
+ \exp_after:wN @
+ \exp_after:wN \use_none:n
+ \exp_after:wN #1
+ \fi:
+ }
+ }
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_?:N }
+ \@@_ternary:NwwN \c_@@_prec_quest_int { }
+\exp_args:Nc \@@_tmp:w { @@_parse_infix_::N }
+ \@@_ternary_auxii:NwwN \c_@@_prec_colon_int
+ {
+ \msg_expandable_error:nnnn
+ { fp } { missing } { ? } { ~for~?: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Comparisons}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_infix_<:N, \@@_parse_infix_=:N,
+% \@@_parse_infix_>:N, \@@_parse_infix_!:N
+% }
+% \begin{macro}[EXP]
+% {
+% \@@_parse_excl_error:,
+% \@@_parse_compare:NNNNNNN,
+% \@@_parse_compare_auxi:NNNNNNN,
+% \@@_parse_compare_auxii:NNNNN,
+% \@@_parse_compare_end:NNNNw,
+% \@@_compare:wNNNNw,
+% }
+% \begin{macrocode}
+\cs_new:cpn { @@_parse_infix_<:N } #1
+ { \@@_parse_compare:NNNNNNN #1 1 0 0 0 0 < }
+\cs_new:cpn { @@_parse_infix_=:N } #1
+ { \@@_parse_compare:NNNNNNN #1 1 0 0 0 0 = }
+\cs_new:cpn { @@_parse_infix_>:N } #1
+ { \@@_parse_compare:NNNNNNN #1 1 0 0 0 0 > }
+\cs_new:cpn { @@_parse_infix_!:N } #1
+ {
+ \exp_after:wN \@@_parse_compare:NNNNNNN
+ \exp_after:wN #1
+ \exp_after:wN 0
+ \exp_after:wN 1
+ \exp_after:wN 1
+ \exp_after:wN 1
+ \exp_after:wN 1
+ }
+\cs_new:Npn \@@_parse_excl_error:
+ {
+ \msg_expandable_error:nnnn
+ { fp } { missing } { = } { ~after~!. }
+ }
+\cs_new:Npn \@@_parse_compare:NNNNNNN #1
+ {
+ \if_int_compare:w #1 < \c_@@_prec_comp_int
+ \exp_after:wN \@@_parse_compare_auxi:NNNNNNN
+ \exp_after:wN \@@_parse_excl_error:
+ \else:
+ \exp_after:wN @
+ \exp_after:wN \use_none:n
+ \exp_after:wN \@@_parse_compare:NNNNNNN
+ \fi:
+ }
+\cs_new:Npn \@@_parse_compare_auxi:NNNNNNN #1#2#3#4#5#6#7
+ {
+ \if_case:w
+ \@@_int_eval:w \exp_after:wN ` \token_to_str:N #7 - `<
+ \@@_int_eval_end:
+ \@@_parse_compare_auxii:NNNNN #2#2#4#5#6
+ \or: \@@_parse_compare_auxii:NNNNN #2#3#2#5#6
+ \or: \@@_parse_compare_auxii:NNNNN #2#3#4#2#6
+ \or: \@@_parse_compare_auxii:NNNNN #2#3#4#5#2
+ \else: #1 \@@_parse_compare_end:NNNNw #3#4#5#6#7
+ \fi:
+ }
+\cs_new:Npn \@@_parse_compare_auxii:NNNNN #1#2#3#4#5
+ {
+ \exp_after:wN \@@_parse_compare_auxi:NNNNNNN
+ \exp_after:wN \prg_do_nothing:
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \exp_after:wN #4
+ \exp_after:wN #5
+ \exp:w \exp_after:wN \@@_parse_expand:w
+ }
+\cs_new:Npn \@@_parse_compare_end:NNNNw #1#2#3#4#5 \fi:
+ {
+ \fi:
+ \exp_after:wN @
+ \exp_after:wN \@@_parse_apply_compare:NwNNNNNwN
+ \exp_after:wN \c_one_fp
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \exp_after:wN #4
+ \exp:w
+ \@@_parse_operand:Nw \c_@@_prec_comp_int \@@_parse_expand:w #5
+ }
+\cs_new:Npn \@@_parse_apply_compare:NwNNNNNwN
+ #1 #2@ #3 #4#5#6#7 #8@ #9
+ {
+ \if_int_odd:w
+ \if_meaning:w \c_zero_fp #3
+ 0
+ \else:
+ \if_case:w \@@_compare_back_any:ww #8 #2 \exp_stop_f:
+ #5 \or: #6 \or: #7 \else: #4
+ \fi:
+ \fi:
+ \exp_stop_f:
+ \exp_after:wN \@@_parse_apply_compare_aux:NNwN
+ \exp_after:wN \c_one_fp
+ \else:
+ \exp_after:wN \@@_parse_apply_compare_aux:NNwN
+ \exp_after:wN \c_zero_fp
+ \fi:
+ #1 #8 #9
+ }
+\cs_new:Npn \@@_parse_apply_compare_aux:NNwN #1 #2 #3; #4
+ {
+ \if_meaning:w \@@_parse_compare:NNNNNNN #4
+ \exp_after:wN \@@_parse_continue_compare:NNwNN
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp:w \exp_end_continue_f:w
+ \@@_exp_after_o:w #3;
+ \exp:w \exp_end_continue_f:w
+ \else:
+ \exp_after:wN \@@_parse_continue:NwN
+ \exp_after:wN #2
+ \exp:w \exp_end_continue_f:w
+ \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w
+ \fi:
+ #4 #2
+ }
+\cs_new:Npn \@@_parse_continue_compare:NNwNN #1#2 #3@ #4#5
+ { #4 #2 #3@ #1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Tools for functions}
+%
+% \begin{macro}[EXP]{\@@_parse_function_all_fp_o:fnw}
+% Followed by \Arg{function name} \Arg{code} \meta{float array} |@|
+% this checks all floats are floating point numbers (no tuples).
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_function_all_fp_o:fnw #1#2#3 @
+ {
+ \@@_array_if_all_fp:nTF {#3}
+ { #2 #3 @ }
+ {
+ \@@_error:nffn { bad-args }
+ {#1}
+ { \fp_to_tl:n { \s_@@_tuple \@@_tuple_chk:w {#3} ; } }
+ { }
+ \exp_after:wN \c_nan_fp
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_parse_function_one_two:nnw}
+% \begin{macro}[EXP]
+% {
+% \@@_parse_function_one_two_error_o:w,
+% \@@_parse_function_one_two_aux:nnw,
+% \@@_parse_function_one_two_auxii:nnw
+% }
+% This is followed by \Arg{function name} \Arg{code} \meta{float
+% array} |@|. It checks that the \meta{float array} consists of one
+% or two floating point numbers (not tuples), then leaves the
+% \meta{code} (if there is one float) or its tail (if there are two
+% floats) followed by the \meta{float array}. The \meta{code} should
+% start with a single token such as \cs{@@_atan_default:w} that deals
+% with the single-float case.
+%
+% The first \cs{@@_if_type_fp:NTwFw} test catches the case of no
+% argument and the case of a tuple argument. The next one
+% distinguishes the case of a single argument (no error, just add
+% \cs{c_one_fp}) from a tuple second argument. Finally check there is
+% no further argument.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_function_one_two:nnw #1#2#3
+ {
+ \@@_if_type_fp:NTwFw
+ #3 { } \s_@@ \@@_parse_function_one_two_error_o:w \s_@@_stop
+ \@@_parse_function_one_two_aux:nnw {#1} {#2} #3
+ }
+\cs_new:Npn \@@_parse_function_one_two_error_o:w #1#2#3#4 @
+ {
+ \@@_error:nffn { bad-args }
+ {#2}
+ { \fp_to_tl:n { \s_@@_tuple \@@_tuple_chk:w {#4} ; } }
+ { }
+ \exp_after:wN \c_nan_fp
+ }
+\cs_new:Npn \@@_parse_function_one_two_aux:nnw #1#2 #3; #4
+ {
+ \@@_if_type_fp:NTwFw
+ #4 { }
+ \s_@@
+ {
+ \if_meaning:w @ #4
+ \exp_after:wN \use_iv:nnnn
+ \fi:
+ \@@_parse_function_one_two_error_o:w
+ }
+ \s_@@_stop
+ \@@_parse_function_one_two_auxii:nnw {#1} {#2} #3; #4
+ }
+\cs_new:Npn \@@_parse_function_one_two_auxii:nnw #1#2#3; #4; #5
+ {
+ \if_meaning:w @ #5 \else:
+ \exp_after:wN \@@_parse_function_one_two_error_o:w
+ \fi:
+ \use_ii:nn {#1} { \use_none:n #2 } #3; #4; #5
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_tuple_map_o:nw, \@@_tuple_map_loop_o:nw}
+% Apply |#1| to all items in the following tuple and expand once
+% afterwards. The code |#1| should itself expand once after its
+% result.
+% \begin{macrocode}
+\cs_new:Npn \@@_tuple_map_o:nw #1 \s_@@_tuple \@@_tuple_chk:w #2 ;
+ {
+ \exp_after:wN \s_@@_tuple
+ \exp_after:wN \@@_tuple_chk:w
+ \exp_after:wN {
+ \exp:w \exp_end_continue_f:w
+ \@@_tuple_map_loop_o:nw {#1} #2
+ { \s_@@ \prg_break: } ;
+ \prg_break_point:
+ \exp_after:wN } \exp_after:wN ;
+ }
+\cs_new:Npn \@@_tuple_map_loop_o:nw #1#2#3 ;
+ {
+ \use_none:n #2
+ #1 #2 #3 ;
+ \exp:w \exp_end_continue_f:w
+ \@@_tuple_map_loop_o:nw {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_tuple_mapthread_o:nww, \@@_tuple_mapthread_loop_o:nw}
+% Apply |#1| to pairs of items in the two following tuples and expand once
+% afterwards.
+% \begin{macrocode}
+\cs_new:Npn \@@_tuple_mapthread_o:nww #1
+ \s_@@_tuple \@@_tuple_chk:w #2 ;
+ \s_@@_tuple \@@_tuple_chk:w #3 ;
+ {
+ \exp_after:wN \s_@@_tuple
+ \exp_after:wN \@@_tuple_chk:w
+ \exp_after:wN {
+ \exp:w \exp_end_continue_f:w
+ \@@_tuple_mapthread_loop_o:nw {#1}
+ #2 { \s_@@ \prg_break: } ; @
+ #3 { \s_@@ \prg_break: } ;
+ \prg_break_point:
+ \exp_after:wN } \exp_after:wN ;
+ }
+\cs_new:Npn \@@_tuple_mapthread_loop_o:nw #1#2#3 ; #4 @ #5#6 ;
+ {
+ \use_none:n #2
+ \use_none:n #5
+ #1 #2 #3 ; #5 #6 ;
+ \exp:w \exp_end_continue_f:w
+ \@@_tuple_mapthread_loop_o:nw {#1} #4 @
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% ^^A end[todo]
+%
+% \subsection{Messages}
+%
+% \begin{macrocode}
+\msg_new:nnn { fp } { deprecated }
+ { '#1'~deprecated;~use~'#2' }
+\msg_new:nnn { fp } { unknown-fp-word }
+ { Unknown~fp~word~#1. }
+\msg_new:nnn { fp } { missing }
+ { Missing~#1~inserted #2. }
+\msg_new:nnn { fp } { extra }
+ { Extra~#1~ignored. }
+\msg_new:nnn { fp } { early-end }
+ { Premature~end~in~fp~expression. }
+\msg_new:nnn { fp } { after-e }
+ { Cannot~use~#1 after~'e'. }
+\msg_new:nnn { fp } { missing-number }
+ { Missing~number~before~'#1'. }
+\msg_new:nnn { fp } { unknown-symbol }
+ { Unknown~symbol~#1~ignored. }
+\msg_new:nnn { fp } { extra-comma }
+ { Unexpected~comma~turned~to~nan~result. }
+\msg_new:nnn { fp } { no-arg }
+ { #1~got~no~argument;~used~nan. }
+\msg_new:nnn { fp } { multi-arg }
+ { #1~got~more~than~one~argument;~used~nan. }
+\msg_new:nnn { fp } { num-args }
+ { #1~expects~between~#2~and~#3~arguments. }
+\msg_new:nnn { fp } { bad-args }
+ { Arguments~in~#1#2~are~invalid. }
+\msg_new:nnn { fp } { infty-pi }
+ { Math~command~#1 is~not~an~fp }
+\cs_if_exist:cT { @unexpandable@protect }
+ {
+ \msg_new:nnn { fp } { robust-cmd }
+ { Robust~command~#1 invalid~in~fp~expression! }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintChanges
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-random.dtx b/macros/latex-dev/required/l3kernel/l3fp-random.dtx
new file mode 100644
index 0000000000..ce5a0c48f7
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-random.dtx
@@ -0,0 +1,629 @@
+% \iffalse meta-comment
+%
+%% File: l3fp-random.dtx
+%
+% Copyright (C) 2016-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-random} module\\
+% Floating point random numbers
+% }
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp-random} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% \begin{macro}[EXP]{\@@_parse_word_rand:N , \@@_parse_word_randint:N}
+% Those functions may receive a variable number of arguments. We
+% won't use the argument~|?|.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_word_rand:N
+ { \@@_parse_function:NNN \@@_rand_o:Nw ? }
+\cs_new:Npn \@@_parse_word_randint:N
+ { \@@_parse_function:NNN \@@_randint_o:Nw ? }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Engine support}
+%
+% Obviously, every word \enquote{random} below means
+% \enquote{pseudo-random}, as we have no access to entropy (except a
+% very unreliable source of entropy: the time it takes to run some
+% code).
+%
+% The primitive random number generator (RNG) is provided as
+% \cs{tex_uniformdeviate:D}. Under the hood, it maintains an array of
+% $55$ $28$-bit numbers, updated with a linear recursion relation
+% (similar to Fibonacci numbers) modulo $2^{28}$. When
+% \cs{tex_uniformdeviate:D} \meta{integer} is called (for brevity denote
+% by~$N$ the \meta{integer}), the next $28$-bit number is read from the
+% array, scaled by $N/2^{28}$, and rounded. To prevent $0$ and $N$ from
+% appearing half as often as other numbers, they are both mapped to the
+% result~$0$.
+%
+% This process means that \cs{tex_uniformdeviate:D} only gives a uniform
+% distribution from $0$ to $N-1$ if $N$ is a divisor of $2^{28}$, so we
+% will mostly call the RNG with such power of~$2$ arguments. If $N$
+% does not divide $2^{28}$, then the relative non-uniformity (difference
+% between probabilities of getting different numbers) is about
+% $N/2^{28}$. This implies that detecting deviation from $1/N$ of the
+% probability of a fixed value X requires about $2^{56}/N$ random
+% trials. But collective patterns can reduce this to about
+% $2^{56}/N^2$. For instance with $N=3\times 2^{k}$, the modulo~$3$
+% repartition of such random numbers is biased with a non-uniformity
+% about $2^k/2^{28}$ (which is much worse than the circa $3/2^{28}$
+% non-uniformity from taking directly $N=3$). This is detectable after
+% about $2^{56}/2^{2k} = 9\cdot 2^{56}/N^2$ random numbers. For $k=15$,
+% $N=98304$, this means roughly $2^{26}$ calls to the RNG
+% (experimentally this takes at the very least 16 seconds on a 2 giga-hertz
+% processor). While this bias is not quite problematic, it is
+% uncomfortably close to being so, and it becomes worse as $N$ is
+% increased. In our code, we shall thus combine several results from
+% the RNG\@.
+%
+% The RNG has three types of unexpected correlations. First, everything
+% is linear modulo~$2^{28}$, hence the lowest $k$ bits of the random
+% numbers only depend on the lowest $k$ bits of the seed (and of course
+% the number of times the RNG was called since setting the seed). The
+% recommended way to get a number from $0$ to $N-1$ is thus to scale the
+% raw $28$-bit integer, as the engine's RNG does. We will go further
+% and in fact typically we discard some of the lowest bits.
+%
+% Second, suppose that we call the RNG with the same argument~$N$ to get
+% a set of $K$ integers in $[0,N-1]$ (throwing away repeats), and
+% suppose that $N>K^3$ and $K>55$. The recursion used to construct more
+% $28$-bit numbers from previous ones is linear:
+% $x_n = x_{n-55} - x_{n-24}$ or $x_n = x_{n-55}-x_{n-24}+2^{28}$.
+% After rescaling and rounding we find that the result $N_n\in[0,N-1]$
+% is among $N_{n-55} - N_{n-24} + \{-1,0,1\}$ modulo~$N$ (a more
+% detailed analysis shows that $0$ appears with frequency close
+% to~$3/4$). The resulting set thus has more triplets $(a,b,c)$ than
+% expected obeying $a=b+c$ modulo~$N$. Namely it will have of order
+% $(K-55)\times 3/4$ such triplets, when one would expect $K^3/(6N)$.
+% This starts to be detectable around $N=2^{18}>55^3$ (earlier if one
+% keeps track of positions too, but this is more subtle than it looks
+% because the array of $28$-bit integers is read backwards by the
+% engine). Hopefully the correlation is subtle enough to not affect
+% realistic documents so we do not specifically mitigate against this.
+% Since we typically use two calls to the RNG per \cs{int_rand:nn} we
+% would need to investigate linear relations between the $x_{2n}$ on the
+% one hand and between the $x_{2n+1}$ on the other hand. Such relations
+% will have more complicated coefficients than $\pm 1$, which alleviates
+% the issue.
+%
+% Third, consider successive batches of $165$ calls to the RNG (with
+% argument $2^{28}$ or with argument~$2$ for instance), then most
+% batches have more odd than even numbers. Note that this does not mean
+% that there are more odd than even numbers overall. Similar issues are
+% discussed in Knuth's TAOCP volume 2 near exercise 3.3.2-31. We do not
+% have any mitigation strategy for this.
+%
+% Ideally, our algorithm should be:
+% \begin{itemize}
+% \item Uniform. The result should be as uniform as possible assuming
+% that the RNG's underlying $28$-bit integers are uniform.
+% \item Uncorrelated. The result should not have detectable
+% correlations between different seeds, similar to the lowest-bit ones
+% mentioned earlier.
+% \item Quick. The algorithm should be fast in \TeX{}, so no
+% \enquote{bit twiddling}, but \enquote{digit twiddling} is ok.
+% \item Simple. The behaviour must be documentable precisely.
+% \item Predictable. The number of calls to the RNG should be the same
+% for any \cs{int_rand:nn}, because then the algorithm can be modified
+% later without changing the result of other uses of the RNG\@.
+% \item Robust. It should work even for \cs{int_rand:nn} |{| |-|
+% \cs{c_max_int} |}| |{| \cs{c_max_int} |}| where the range is not
+% representable as an integer. In fact, we also provide later a
+% floating-point |randint| whose range can go all the way up to
+% $2\times 10^{16}-1$ possible values.
+% \end{itemize}
+% Some of these requirements conflict. For instance, uniformity cannot
+% be achieved with a fixed number of calls to the RNG\@.
+%
+% Denote by $\operatorname{random}(N)$ one call to
+% \cs{tex_uniformdeviate:D} with argument~$N$, and by
+% $\operatorname{ediv}(p,q)$ the \eTeX{} rounding division giving
+% $\lfloor p/q+1/2\rfloor$. Denote by $\meta{min}$, $\meta{max}$ and
+% $R=\meta{max}-\meta{min}+1$ the arguments of \cs{int_min:nn} and the
+% number of possible outcomes. Note that $R\in [1,2^{32}-1]$ cannot
+% necessarily be represented as an integer (however, $R-2^{31}$ can).
+% Our strategy is to get two $28$-bit integers $X$ and $Y$ from the RNG,
+% split each into $14$-bit integers, as $X=X_1\times 2^{14}+X_0$ and
+% $Y=Y_1\times 2^{14}+Y_0$ then return essentially
+% $\meta{min} + \lfloor R (X_1\times 2^{-14} + Y_1\times 2^{-28} +
+% Y_0\times 2^{-42} + X_0\times 2^{-56})\rfloor$. For small~$R$ the
+% $X_0$ term has a tiny effect so we ignore it and we can compute
+% $R\times Y/2^{28}$ much more directly by $\operatorname{random}(R)$.
+% \begin{itemize}
+% \item If $R \leq 2^{17}-1$ then return
+% $\operatorname{ediv}(R\operatorname{random}(2^{14}) +
+% \operatorname{random}(R) + 2^{13}, 2^{14}) - 1 + \meta{min}$. The
+% shifts by $2^{13}$ and $-1$ convert \eTeX{} division to truncated
+% division. The bound on $R$ ensures that the number obtained after
+% the shift is less than \cs{c_max_int}. The non-uniformity is at
+% most of order $2^{17}/2^{42} = 2^{-25}$.
+% \item Split $R=R_2\times 2^{28}+R_1\times 2^{14}+R_0$, where
+% $R_2\in [0,15]$. Compute
+% $\meta{min} + R_2 X_1 2^{14} + (R_2 Y_1 + R_1 X_1) +
+% \operatorname{ediv}(R_2 Y_0 + R_1 Y_1 + R_0 X_1 +
+% \operatorname{ediv}(R_2 X_0 + R_0 Y_1 + \operatorname{ediv}((2^{14}
+% R_1 + R_0) (2^{14} Y_0 + X_0), 2^{28}), 2^{14}), 2^{14})$ then map a
+% result of $\meta{max}+1$ to $\meta{min}$. Writing each
+% $\operatorname{ediv}$ in terms of truncated division with a shift,
+% and using
+% $\lfloor(p+\lfloor r/s\rfloor)/q\rfloor =
+% \lfloor(ps+r)/(sq)\rfloor$, what we compute is equal to
+% $\lfloor\meta{exact}+2^{-29}+2^{-15}+2^{-1}\rfloor$ with
+% $\meta{exact}=\meta{min} + R \times 0.X_1Y_1Y_0X_0$. Given we map
+% $\meta{max}+1$ to $\meta{min}$, the shift has no effect on
+% uniformity. The non-uniformity is bounded by $R/2^{56}<2^{-24}$. It
+% may be possible to speed up the code by dropping tiny terms such as
+% $R_0 X_0$, but the analysis of non-uniformity proves too difficult.
+%
+% To avoid the overflow when the computation yields $\meta{max}+1$
+% with $\meta{max}=2^{31}-1$ (note that $R$ is then arbitrary), we
+% compute the result in two pieces. Compute
+% $\meta{first} = \meta{min} + R_2 X_1 2^{14}$ if $R_2<8$ or
+% $\meta{min} + 8 X_1 2^{14} + (R_2-8) X_1 2^{14}$ if $R_2\geq 8$, the
+% expressions being chosen to avoid overflow. Compute
+% $\meta{second} = R_2 Y_1 + R_1 X_1 + \operatorname{ediv}({\dots})$,
+% at most
+% $R_2 2^{14} + R_1 2^{14} + R_0\leq 2^{28} + 15\times 2^{14} - 1$,
+% not at risk of overflowing. We have
+% $\meta{first}+\meta{second}=\meta{max}+1=\meta{min}+R$ if and only
+% if $\meta{second} = R1 2^{14} + R_0 + R_2 2^{14}$ and
+% $2^{14} R_2 X_1 = 2^{28} R_2 - 2^{14} R_2$ (namely $R_2=0$ or
+% $X_1=2^{14}-1$). In that case, return \meta{min}, otherwise return
+% $\meta{first}+\meta{second}$, which is safe because it is at most
+% \meta{max}. Note that the decision of what to return does not need
+% \meta{first} explicitly so we don't actually compute it, just put it
+% in an integer expression in which \meta{second} is eventually added
+% (or not).
+% \item To get a floating point number in $[0,1)$ just call the
+% $R=10000\leq 2^{17}-1$ procedure above to produce four blocks of four
+% digits.
+% \item To get an integer floating point number in a range (whose size
+% can be up to $2\times 10^{16}-1$), work with fixed-point numbers:
+% get six times four digits to build a fixed point number, multiply by
+% $R$ and add $\meta{min}$. This requires some care because
+% \pkg{l3fp-extended} only supports non-negative numbers.
+% \end{itemize}
+%
+% \begin{variable}{\c__kernel_randint_max_int}
+% Constant equal to $2^{17}-1$, the maximal size of a range that
+% \cs{int_range:nn} can do with its \enquote{simple} algorithm.
+% \begin{macrocode}
+\int_const:Nn \c__kernel_randint_max_int { 131071 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\__kernel_randint:n}
+% Used in an integer expression, \cs{__kernel_randint:n} |{|$R$|}|
+% gives a random number
+% $1+\lfloor(R\operatorname{random}(2^{14}) +
+% \operatorname{random}(R))/2^{14}\rfloor$ that is in $[1,R]$.
+% Previous code was computing $\lfloor p/2^{14}\rfloor$ as
+% $\operatorname{ediv}(p-2^{13},2^{14})$ but that wrongly gives $-1$
+% for $p=0$.
+% \begin{macrocode}
+\cs_new:Npn \__kernel_randint:n #1
+ {
+ (#1 * \tex_uniformdeviate:D 16384
+ + \tex_uniformdeviate:D #1 + 8192 ) / 16384
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_rand_myriads:n, \@@_rand_myriads_loop:w, \@@_rand_myriads_get:w}
+% Used as \cs{@@_rand_myriads:n} |{XXX}| with one letter |X|
+% (specifically) per block of four digit we want; it expands to |;|
+% followed by the requested number of brace groups, each containing
+% four (pseudo-random) digits. Digits are produced as a random number
+% in $[10000,19999]$ for the usual reason of preserving leading zeros.
+% \begin{macrocode}
+\cs_new:Npn \@@_rand_myriads:n #1
+ { \@@_rand_myriads_loop:w #1 \prg_break: X \prg_break_point: ; }
+\cs_new:Npn \@@_rand_myriads_loop:w #1 X
+ {
+ #1
+ \exp_after:wN \@@_rand_myriads_get:w
+ \int_value:w \@@_int_eval:w 9999 +
+ \__kernel_randint:n { 10000 }
+ \@@_rand_myriads_loop:w
+ }
+\cs_new:Npn \@@_rand_myriads_get:w 1 #1 ; { ; {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Random floating point}
+%
+% \begin{macro}[EXP]{\@@_rand_o:Nw, \@@_rand_o:w}
+% First we check that |random| was called without argument. Then get
+% four blocks of four digits and convert that fixed point number to a
+% floating point number (this correctly sets the exponent). This has
+% a minor bug: if all of the random numbers are zero then the result
+% is correctly~$0$ but it raises the \texttt{underflow} flag; it
+% should not do that.
+% \begin{macrocode}
+\cs_new:Npn \@@_rand_o:Nw ? #1 @
+ {
+ \tl_if_empty:nTF {#1}
+ {
+ \exp_after:wN \@@_rand_o:w
+ \exp:w \exp_end_continue_f:w
+ \@@_rand_myriads:n { XXXX } { 0000 } { 0000 } ; 0
+ }
+ {
+ \msg_expandable_error:nnnnn
+ { fp } { num-args } { rand() } { 0 } { 0 }
+ \exp_after:wN \c_nan_fp
+ }
+ }
+\cs_new:Npn \@@_rand_o:w ;
+ {
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN 0
+ \int_value:w \@@_int_eval:w \c_zero_int
+ \@@_fixed_to_float_o:wN
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Random integer}
+%
+% \begin{macro}[EXP]{\@@_randint_o:Nw}
+% \begin{macro}[EXP]
+% {
+% \@@_randint_default:w,
+% \@@_randint_badarg:w,
+% \@@_randint_o:w,
+% \@@_randint_auxi_o:ww,
+% \@@_randint_auxii:wn,
+% \@@_randint_auxiii_o:ww,
+% \@@_randint_auxiv_o:ww,
+% \@@_randint_auxv_o:w,
+% }
+% Enforce that there is one argument (then add first argument~$1$)
+% or two arguments. Call \cs{@@_randint_badarg:w} on each; this
+% function inserts |1| \cs{exp_stop_f:} to end the \cs{if_case:w}
+% statement if either the argument is not an integer or if its
+% absolute value is $\geq 10^{16}$. Also bail out if
+% \cs{@@_compare_back:ww} yields~|1|, meaning that the bounds are
+% not in the right order. Otherwise an auxiliary converts each
+% argument times $10^{-16}$ (hence the shift in exponent) to a
+% $24$-digit fixed point number (see \pkg{l3fp-extended}).
+% Then compute the number of choices, $\meta{max}+1-\meta{min}$.
+% Create a random $24$-digit fixed-point number with
+% \cs{@@_rand_myriads:n}, then use a fused multiply-add instruction
+% to multiply the number of choices to that random number and add it
+% to \meta{min}. Then truncate to $16$ digits (namely select the
+% integer part of $10^{16}$ times the result) before converting back
+% to a floating point number (\cs{@@_sanitize:Nw} takes care of zero).
+% To avoid issues with negative numbers, add $1$ to all fixed point
+% numbers (namely $10^{16}$ to the integers they represent), except
+% of course when it is time to convert back to a float.
+% \begin{macrocode}
+\cs_new:Npn \@@_randint_o:Nw ?
+ {
+ \@@_parse_function_one_two:nnw
+ { randint }
+ { \@@_randint_default:w \@@_randint_o:w }
+ }
+\cs_new:Npn \@@_randint_default:w #1 { \exp_after:wN #1 \c_one_fp }
+\cs_new:Npn \@@_randint_badarg:w \s_@@ \@@_chk:w #1#2#3;
+ {
+ \@@_int:wTF \s_@@ \@@_chk:w #1#2#3;
+ {
+ \if_meaning:w 1 #1
+ \if_int_compare:w
+ \@@_use_i_until_s:nw #3 ; > \c_@@_prec_int
+ \c_one_int
+ \fi:
+ \fi:
+ }
+ { \c_one_int }
+ }
+\cs_new:Npn \@@_randint_o:w #1; #2; @
+ {
+ \if_case:w
+ \@@_randint_badarg:w #1;
+ \@@_randint_badarg:w #2;
+ \if:w 1 \@@_compare_back:ww #2; #1; \c_one_int \fi:
+ \c_zero_int
+ \@@_randint_auxi_o:ww #1; #2;
+ \or:
+ \@@_invalid_operation_tl_o:ff
+ { randint } { \@@_array_to_clist:n { #1; #2; } }
+ \exp:w
+ \fi:
+ \exp_after:wN \exp_end:
+ }
+\cs_new:Npn \@@_randint_auxi_o:ww #1 ; #2 ; #3 \exp_end:
+ {
+ \fi:
+ \@@_randint_auxii:wn #2 ;
+ { \@@_randint_auxii:wn #1 ; \@@_randint_auxiii_o:ww }
+ }
+\cs_new:Npn \@@_randint_auxii:wn \s_@@ \@@_chk:w #1#2#3#4 ;
+ {
+ \if_meaning:w 0 #1
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ { \exp_after:wN \@@_fixed_continue:wn \c_@@_one_fixed_tl }
+ {
+ \exp_after:wN \@@_ep_to_fixed:wwn
+ \int_value:w \@@_int_eval:w
+ #3 - \c_@@_prec_int , #4 {0000} {0000} ;
+ {
+ \if_meaning:w 0 #2
+ \exp_after:wN \use_i:nnnn
+ \exp_after:wN \@@_fixed_add_one:wN
+ \fi:
+ \exp_after:wN \@@_fixed_sub:wwn \c_@@_one_fixed_tl
+ }
+ \@@_fixed_continue:wn
+ }
+ }
+\cs_new:Npn \@@_randint_auxiii_o:ww #1 ; #2 ;
+ {
+ \@@_fixed_add:wwn #2 ;
+ {0000} {0000} {0000} {0001} {0000} {0000} ;
+ \@@_fixed_sub:wwn #1 ;
+ {
+ \exp_after:wN \use_i:nn
+ \exp_after:wN \@@_fixed_mul_add:wwwn
+ \exp:w \exp_end_continue_f:w \@@_rand_myriads:n { XXXXXX } ;
+ }
+ #1 ;
+ \@@_randint_auxiv_o:ww
+ #2 ;
+ \@@_randint_auxv_o:w #1 ; @
+ }
+\cs_new:Npn \@@_randint_auxiv_o:ww #1#2#3#4#5 ; #6#7#8#9
+ {
+ \if_int_compare:w
+ \if_int_compare:w #1#2 > #6#7 \exp_stop_f: 1 \else:
+ \if_int_compare:w #1#2 < #6#7 \exp_stop_f: - \fi: \fi:
+ #3#4 > #8#9 \exp_stop_f:
+ \@@_use_i_until_s:nw
+ \fi:
+ \@@_randint_auxv_o:w {#1}{#2}{#3}{#4}#5
+ }
+\cs_new:Npn \@@_randint_auxv_o:w #1#2#3#4#5 ; #6 @
+ {
+ \exp_after:wN \@@_sanitize:Nw
+ \int_value:w
+ \if_int_compare:w #1 < 10000 \exp_stop_f:
+ 2
+ \else:
+ 0
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_reverse_args:Nww
+ \fi:
+ \exp_after:wN \@@_fixed_sub:wwn \c_@@_one_fixed_tl
+ {#1} {#2} {#3} {#4} {0000} {0000} ;
+ {
+ \exp_after:wN \exp_stop_f:
+ \int_value:w \@@_int_eval:w \c_@@_prec_int
+ \@@_fixed_to_float_o:wN
+ }
+ 0
+ \exp:w \exp_after:wN \exp_end:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_rand:nn, \@@_randint:ww}
+% Evaluate the argument and filter out the case where the lower
+% bound~|#1| is more than the upper bound~|#2|. Then determine
+% whether the range is narrower than \cs{c__kernel_randint_max_int};
+% |#2-#1| may overflow for very large positive~|#2| and negative~|#1|.
+% If the range is narrow, call \cs{__kernel_randint:n} \Arg{choices}
+% where \meta{choices} is the number of possible outcomes. If the
+% range is wide, use somewhat slower code.
+% \begin{macrocode}
+\cs_new:Npn \int_rand:nn #1#2
+ {
+ \int_eval:n
+ {
+ \exp_after:wN \@@_randint:ww
+ \int_value:w \int_eval:n {#1} \exp_after:wN ;
+ \int_value:w \int_eval:n {#2} ;
+ }
+ }
+\cs_new:Npn \@@_randint:ww #1; #2;
+ {
+ \if_int_compare:w #1 > #2 \exp_stop_f:
+ \msg_expandable_error:nnnn
+ { kernel } { randint-backward-range } {#1} {#2}
+ \@@_randint:ww #2; #1;
+ \else:
+ \if_int_compare:w \@@_int_eval:w #2
+ \if_int_compare:w #1 > \c_zero_int
+ - #1 < \@@_int_eval:w
+ \else:
+ < \@@_int_eval:w #1 +
+ \fi:
+ \c__kernel_randint_max_int
+ \@@_int_eval_end:
+ \__kernel_randint:n
+ { \@@_int_eval:w #2 - #1 + 1 \@@_int_eval_end: }
+ - 1 + #1
+ \else:
+ \__kernel_randint:nn {#1} {#2}
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \__kernel_randint:nn, \@@_randint_split_o:Nw, \@@_randint_split_aux:w,
+% \@@_randinat_wide_aux:w, \@@_randinat_wide_auxii:w,
+% }
+% Any $n\in[-2^{31}+1,2^{31}-1]$ is uniquely written as
+% $2^{14}n_1+n_2$ with $n_1\in[-2^{17},2^{17}-1]$ and
+% $n_2\in[0,2^{14}-1]$. Calling \cs{@@_randint_split_o:Nw} $n$ |;|
+% gives $n_1$|;| $n_2$|;| and expands the next token once. We do this
+% for two random numbers and apply \cs{@@_randint_split_o:Nw} twice to
+% fully decompose the range~$R$. One subtlety is that we compute
+% $R-2^{31}=\meta{max}-\meta{min}-(2^{31}-1)\in[-2^{31}+1,2^{31}-1]$
+% rather than $R$ to avoid overflow.
+%
+% Then we have \cs{@@_randint_wide_aux:w} \meta{X_1}|;|\meta{X_0}|;|
+% \meta{Y_1}|;|\meta{Y_0}|;| \meta{R_2}|;|\meta{R_1}|;|\meta{R_0}|;.|
+% and we apply the algorithm described earlier.
+% \begin{macrocode}
+\cs_new:Npn \__kernel_randint:nn #1#2
+ {
+ #1
+ \exp_after:wN \@@_randint_wide_aux:w
+ \int_value:w
+ \exp_after:wN \@@_randint_split_o:Nw
+ \tex_uniformdeviate:D 268435456 ;
+ \int_value:w
+ \exp_after:wN \@@_randint_split_o:Nw
+ \tex_uniformdeviate:D 268435456 ;
+ \int_value:w
+ \exp_after:wN \@@_randint_split_o:Nw
+ \int_value:w \@@_int_eval:w 131072 +
+ \exp_after:wN \@@_randint_split_o:Nw
+ \int_value:w
+ \__kernel_int_add:nnn {#2} { -#1 } { -\c_max_int } ;
+ .
+ }
+\cs_new:Npn \@@_randint_split_o:Nw #1#2 ;
+ {
+ \if_meaning:w 0 #1
+ 0 \exp_after:wN ; \int_value:w 0
+ \else:
+ \exp_after:wN \@@_randint_split_aux:w
+ \int_value:w \@@_int_eval:w (#1#2 - 8192) / 16384 ;
+ + #1#2
+ \fi:
+ \exp_after:wN ;
+ }
+\cs_new:Npn \@@_randint_split_aux:w #1 ;
+ {
+ #1 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w - #1 * 16384
+ }
+\cs_new:Npn \@@_randint_wide_aux:w #1;#2; #3;#4; #5;#6;#7; .
+ {
+ \exp_after:wN \@@_randint_wide_auxii:w
+ \int_value:w \@@_int_eval:w #5 * #3 + #6 * #1 +
+ (#5 * #4 + #6 * #3 + #7 * #1 +
+ (#5 * #2 + #7 * #3 +
+ (16384 * #6 + #7) * (16384 * #4 + #2) / 268435456) / 16384
+ ) / 16384 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w (#5 + #6) * 16384 + #7 ;
+ #1 ; #5 ;
+ }
+\cs_new:Npn \@@_randint_wide_auxii:w #1; #2; #3; #4;
+ {
+ \if_int_odd:w 0
+ \if_int_compare:w #1 = #2 \else: \exp_stop_f: \fi:
+ \if_int_compare:w #4 = \c_zero_int 1 \fi:
+ \if_int_compare:w #3 = 16383 ~ 1 \fi:
+ \exp_stop_f:
+ \exp_after:wN \prg_break:
+ \fi:
+ \if_int_compare:w #4 < 8 \exp_stop_f:
+ + #4 * #3 * 16384
+ \else:
+ + 8 * #3 * 16384 + (#4 - 8) * #3 * 16384
+ \fi:
+ + #1
+ \prg_break_point:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_rand:n, \@@_randint:n}
+% Similar to \cs{int_rand:nn}, but needs fewer checks.
+% \begin{macrocode}
+\cs_new:Npn \int_rand:n #1
+ {
+ \int_eval:n
+ { \exp_args:Nf \@@_randint:n { \int_eval:n {#1} } }
+ }
+\cs_new:Npn \@@_randint:n #1
+ {
+ \if_int_compare:w #1 < \c_one_int
+ \msg_expandable_error:nnnn
+ { kernel } { randint-backward-range } { 1 } {#1}
+ \@@_randint:ww #1; 1;
+ \else:
+ \if_int_compare:w #1 > \c__kernel_randint_max_int
+ \__kernel_randint:nn { 1 } {#1}
+ \else:
+ \__kernel_randint:n {#1}
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintChanges
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-round.dtx b/macros/latex-dev/required/l3kernel/l3fp-round.dtx
new file mode 100644
index 0000000000..48ae82730c
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-round.dtx
@@ -0,0 +1,592 @@
+% \iffalse meta-comment
+%
+%% File: l3fp-round.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-round} module\\ Rounding floating points^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp-round} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% ^^A todo: provide an interface for rounding modes.
+% ^^A todo: provide a \l_@@_rounding_mode_int giving the current mode.
+% ^^A todo: make transcendental function obey the correct rounding mode.
+% ^^A todo: optimize all rounding functions for various rounding modes.
+% ^^A todo: reduce the number of almost identical functions.
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_word_trunc:N,
+% \@@_parse_word_floor:N,
+% \@@_parse_word_ceil:N
+% }
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_word_trunc:N
+ { \@@_parse_function:NNN \@@_round_o:Nw \@@_round_to_zero:NNN }
+\cs_new:Npn \@@_parse_word_floor:N
+ { \@@_parse_function:NNN \@@_round_o:Nw \@@_round_to_ninf:NNN }
+\cs_new:Npn \@@_parse_word_ceil:N
+ { \@@_parse_function:NNN \@@_round_o:Nw \@@_round_to_pinf:NNN }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_word_round:N, \@@_parse_round:Nw,
+% }
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_word_round:N #1#2
+ {
+ \@@_parse_function:NNN
+ \@@_round_o:Nw \@@_round_to_nearest:NNN #1
+ #2
+ }
+\cs_new:Npn \@@_parse_round:Nw #1 #2 \@@_round_to_nearest:NNN #3#4
+ { #2 #1 #3 }
+
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Rounding tools}
+%
+% \begin{variable}{\c_@@_five_int}
+% This is used as the half-point for which numbers are rounded
+% up/down.
+% \begin{macrocode}
+\int_const:Nn \c_@@_five_int { 5 }
+% \end{macrocode}
+% \end{variable}
+%
+% Floating point operations often yield a result that cannot be exactly
+% represented in a significand with $16$ digits. In that case, we need to
+% round the exact result to a representable number. The \textsc{ieee}
+% standard defines four rounding modes:
+% \begin{itemize}
+% \item Round to nearest: round to the representable floating point
+% number whose absolute difference with the exact result is the
+% smallest. If the exact result lies exactly at the mid-point
+% between two consecutive representable floating point numbers,
+% round to the floating point number whose last digit is even.
+% \item Round towards negative infinity: round to the greatest
+% floating point number not larger than the exact result.
+% \item Round towards zero: round to a floating point number with the
+% same sign as the exact result, with the largest absolute value not
+% larger than the absolute value of the exact result.
+% \item Round towards positive infinity: round to the least floating
+% point number not smaller than the exact result.
+% \end{itemize}
+% This is not fully implemented in \pkg{l3fp} yet, and transcendental
+% functions fall back on the \enquote{round to nearest} mode. All
+% rounding for basic algebra is done through the functions defined in
+% this module, which can be redefined to change their rounding behaviour
+% (but there is not interface for that yet).
+%
+% The rounding tools available in this module are many variations on a
+% base function \cs{@@_round:NNN}, which expands to |0\exp_stop_f:| or
+% |1\exp_stop_f:| depending on whether the final result should be rounded up
+% or down.
+% \begin{itemize}
+% \item \cs{@@_round:NNN} \meta{sign} \meta{digit_1} \meta{digit_2}
+% can expand to |0\exp_stop_f:| or |1\exp_stop_f:|.
+% \item \cs{@@_round_s:NNNw} \meta{sign} \meta{digit_1} \meta{digit_2}
+% \meta{more digits}|;| can expand to |0\exp_stop_f:;| or |1\exp_stop_f:;|.
+% \item \cs{@@_round_neg:NNN} \meta{sign} \meta{digit_1} \meta{digit_2}
+% can expand to |0\exp_stop_f:| or |1\exp_stop_f:|.
+% \end{itemize}
+% See implementation comments for details on the syntax.
+%
+% \begin{macro}[rEXP]{\@@_round:NNN}
+% \begin{macro}[rEXP]
+% {
+% \@@_round_to_nearest:NNN,
+% \@@_round_to_nearest_ninf:NNN,
+% \@@_round_to_nearest_zero:NNN,
+% \@@_round_to_nearest_pinf:NNN,
+% \@@_round_to_ninf:NNN,
+% \@@_round_to_zero:NNN,
+% \@@_round_to_pinf:NNN
+% }
+% \begin{syntax}
+% \cs{@@_round:NNN} \meta{final sign} \meta{digit_1} \meta{digit_2}
+% \end{syntax}
+% If rounding the number $\meta{final sign}
+% \meta{digit_1}.\meta{digit_2}$ to an integer rounds it towards zero
+% (truncates it), this function expands to |0\exp_stop_f:|, and otherwise
+% to |1\exp_stop_f:|. Typically used within the scope of an
+% \cs{@@_int_eval:w}, to add~$1$ if needed, and thereby round
+% correctly. The result depends on the rounding mode.
+%
+% It is very important that \meta{final sign} be the final sign of the
+% result. Otherwise, the result would be incorrect in the case of
+% rounding towards~$-\infty$ or towards~$+\infty$. Also recall that
+% \meta{final sign} is~$0$ for positive, and~$2$ for negative.
+%
+% By default, the functions below return |0\exp_stop_f:|, but this is
+% superseded by \cs{@@_round_return_one:}, which instead returns
+% |1\exp_stop_f:|, expanding everything and removing |0\exp_stop_f:| in the
+% process. In the case of rounding towards~$\pm\infty$ or
+% towards~$0$, this is not really useful, but it prepares us for the
+% \enquote{round to nearest, ties to even} mode.
+%
+% The \enquote{round to nearest} mode is the default. If the
+% \meta{digit_2} is larger than~$5$, then round up. If it is less
+% than~$5$, round down. If it is exactly $5$, then round such that
+% \meta{digit_1} plus the result is even. In other words, round up if
+% \meta{digit_1} is odd.
+%
+% The \enquote{round to nearest} mode has three variants, which differ
+% in how ties are rounded: down towards $-\infty$, truncated towards $0$,
+% or up towards $+\infty$.
+% \begin{macrocode}
+\cs_new:Npn \@@_round_return_one:
+ { \exp_after:wN 1 \exp_after:wN \exp_stop_f: \exp:w }
+\cs_new:Npn \@@_round_to_ninf:NNN #1 #2 #3
+ {
+ \if_meaning:w 2 #1
+ \if_int_compare:w #3 > \c_zero_int
+ \@@_round_return_one:
+ \fi:
+ \fi:
+ \c_zero_int
+ }
+\cs_new:Npn \@@_round_to_zero:NNN #1 #2 #3 { \c_zero_int }
+\cs_new:Npn \@@_round_to_pinf:NNN #1 #2 #3
+ {
+ \if_meaning:w 0 #1
+ \if_int_compare:w #3 > \c_zero_int
+ \@@_round_return_one:
+ \fi:
+ \fi:
+ \c_zero_int
+ }
+\cs_new:Npn \@@_round_to_nearest:NNN #1 #2 #3
+ {
+ \if_int_compare:w #3 > \c_@@_five_int
+ \@@_round_return_one:
+ \else:
+ \if_meaning:w 5 #3
+ \if_int_odd:w #2 \exp_stop_f:
+ \@@_round_return_one:
+ \fi:
+ \fi:
+ \fi:
+ \c_zero_int
+ }
+\cs_new:Npn \@@_round_to_nearest_ninf:NNN #1 #2 #3
+ {
+ \if_int_compare:w #3 > \c_@@_five_int
+ \@@_round_return_one:
+ \else:
+ \if_meaning:w 5 #3
+ \if_meaning:w 2 #1
+ \@@_round_return_one:
+ \fi:
+ \fi:
+ \fi:
+ \c_zero_int
+ }
+\cs_new:Npn \@@_round_to_nearest_zero:NNN #1 #2 #3
+ {
+ \if_int_compare:w #3 > \c_@@_five_int
+ \@@_round_return_one:
+ \fi:
+ \c_zero_int
+ }
+\cs_new:Npn \@@_round_to_nearest_pinf:NNN #1 #2 #3
+ {
+ \if_int_compare:w #3 > \c_@@_five_int
+ \@@_round_return_one:
+ \else:
+ \if_meaning:w 5 #3
+ \if_meaning:w 0 #1
+ \@@_round_return_one:
+ \fi:
+ \fi:
+ \fi:
+ \c_zero_int
+ }
+\cs_new_eq:NN \@@_round:NNN \@@_round_to_nearest:NNN
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_round_s:NNNw}
+% \begin{syntax}
+% \cs{@@_round_s:NNNw} \meta{final sign} \meta{digit} \meta{more digits} |;|
+% \end{syntax}
+% Similar to \cs{@@_round:NNN}, but with an extra semicolon, this
+% function expands to |0\exp_stop_f:;| if rounding $\meta{final sign}
+% \meta{digit}.\meta{more digits}$ to an integer truncates, and to
+% |1\exp_stop_f:;| otherwise. The \meta{more digits} part must be a digit,
+% followed by something that does not overflow a \cs{int_use:N}
+% \cs{@@_int_eval:w} construction. The only relevant information about
+% this piece is whether it is zero or not.
+% \begin{macrocode}
+\cs_new:Npn \@@_round_s:NNNw #1 #2 #3 #4;
+ {
+ \exp_after:wN \@@_round:NNN
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \int_value:w \@@_int_eval:w
+ \if_int_odd:w 0 \if_meaning:w 0 #3 1 \fi:
+ \if_meaning:w 5 #3 1 \fi:
+ \exp_stop_f:
+ \if_int_compare:w \@@_int_eval:w #4 > \c_zero_int
+ 1 +
+ \fi:
+ \fi:
+ #3
+ ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_round_digit:Nw}
+% \begin{syntax}
+% \cs{int_value:w} \cs{@@_round_digit:Nw} \meta{digit} \meta{int expr} |;|
+% \end{syntax}
+% This function should always be called within an \cs{int_value:w}
+% or \cs{@@_int_eval:w} expansion; it may add an extra
+% \cs{@@_int_eval:w}, which means that the integer or integer
+% expression should not be ended with a synonym of \tn{relax}, but
+% with a semi-colon for instance.
+% \begin{macrocode}
+\cs_new:Npn \@@_round_digit:Nw #1 #2;
+ {
+ \if_int_odd:w \if_meaning:w 0 #1 1 \else:
+ \if_meaning:w 5 #1 1 \else:
+ 0 \fi: \fi: \exp_stop_f:
+ \if_int_compare:w \@@_int_eval:w #2 > \c_zero_int
+ \@@_int_eval:w 1 +
+ \fi:
+ \fi:
+ #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_round_neg:NNN}
+% \begin{macro}[EXP]
+% {
+% \@@_round_to_nearest_neg:NNN,
+% \@@_round_to_nearest_ninf_neg:NNN,
+% \@@_round_to_nearest_zero_neg:NNN,
+% \@@_round_to_nearest_pinf_neg:NNN,
+% \@@_round_to_ninf_neg:NNN,
+% \@@_round_to_zero_neg:NNN,
+% \@@_round_to_pinf_neg:NNN
+% }
+% \begin{syntax}
+% \cs{@@_round_neg:NNN} \meta{final sign} \meta{digit_1} \meta{digit_2}
+% \end{syntax}
+% This expands to |0\exp_stop_f:| or |1\exp_stop_f:| after doing the following
+% test. Starting from a number of
+% the form $ \meta{final sign}0.\meta{15 digits}\meta{digit_1} $ with exactly
+% $15$ (non-all-zero) digits before \meta{digit_1}, subtract from it
+% $\meta{final sign}0.0\ldots{}0\meta{digit_2}$, where there are $16$~zeros.
+% If in the current rounding mode the result should be rounded down,
+% then this function returns |1\exp_stop_f:|. Otherwise, \emph{i.e.},
+% if the result is rounded back to the first operand, then this function
+% returns |0\exp_stop_f:|.
+%
+% It turns out that this negative \enquote{round to nearest}
+% is identical to the positive one. And this is the default mode.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_round_to_ninf_neg:NNN \@@_round_to_pinf:NNN
+\cs_new:Npn \@@_round_to_zero_neg:NNN #1 #2 #3
+ {
+ \if_int_compare:w #3 > \c_zero_int
+ \@@_round_return_one:
+ \fi:
+ \c_zero_int
+ }
+\cs_new_eq:NN \@@_round_to_pinf_neg:NNN \@@_round_to_ninf:NNN
+\cs_new_eq:NN \@@_round_to_nearest_neg:NNN \@@_round_to_nearest:NNN
+\cs_new_eq:NN \@@_round_to_nearest_ninf_neg:NNN
+ \@@_round_to_nearest_pinf:NNN
+\cs_new:Npn \@@_round_to_nearest_zero_neg:NNN #1 #2 #3
+ {
+ \if_int_compare:w #3 < \c_@@_five_int \else:
+ \@@_round_return_one:
+ \fi:
+ \c_zero_int
+ }
+\cs_new_eq:NN \@@_round_to_nearest_pinf_neg:NNN
+ \@@_round_to_nearest_ninf:NNN
+\cs_new_eq:NN \@@_round_neg:NNN \@@_round_to_nearest_neg:NNN
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{The \texttt{round} function}
+%
+% ^^A todo: This macro is intermingled with l3fp-parse.
+% ^^A todo: Add explanations.
+% \begin{macro}[EXP]{\@@_round_o:Nw, \@@_round_aux_o:Nw}
+% First check that all arguments are floating point numbers.
+% The |trunc|, |ceil| and |floor| functions expect one or two
+% arguments (the second is $0$ by default), and the |round| function
+% also accepts a third argument (\texttt{nan} by default), which
+% changes |#1| from \cs{@@_round_to_nearest:NNN} to one of its
+% analogues.
+% \begin{macrocode}
+\cs_new:Npn \@@_round_o:Nw #1
+ {
+ \@@_parse_function_all_fp_o:fnw
+ { \@@_round_name_from_cs:N #1 }
+ { \@@_round_aux_o:Nw #1 }
+ }
+\cs_new:Npn \@@_round_aux_o:Nw #1#2 @
+ {
+ \if_case:w
+ \@@_int_eval:w \@@_array_count:n {#2} \@@_int_eval_end:
+ \@@_round_no_arg_o:Nw #1 \exp:w
+ \or: \@@_round:Nwn #1 #2 {0} \exp:w
+ \or: \@@_round:Nww #1 #2 \exp:w
+ \else: \@@_round:Nwww #1 #2 @ \exp:w
+ \fi:
+ \exp_after:wN \exp_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_round_no_arg_o:Nw}
+% \begin{macrocode}
+\cs_new:Npn \@@_round_no_arg_o:Nw #1
+ {
+ \cs_if_eq:NNTF #1 \@@_round_to_nearest:NNN
+ { \@@_error:nnnn { num-args } { round () } { 1 } { 3 } }
+ {
+ \@@_error:nffn { num-args }
+ { \@@_round_name_from_cs:N #1 () } { 1 } { 2 }
+ }
+ \exp_after:wN \c_nan_fp
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_round:Nwww}
+% Having three arguments is only allowed for |round|, not |trunc|,
+% |ceil|, |floor|, so check for that case. If all is well, construct
+% one of \cs{@@_round_to_nearest:NNN}, \cs{@@_round_to_nearest_zero:NNN},
+% \cs{@@_round_to_nearest_ninf:NNN}, \cs{@@_round_to_nearest_pinf:NNN}
+% and act accordingly.
+% \begin{macrocode}
+\cs_new:Npn \@@_round:Nwww #1#2 ; #3 ; \s_@@ \@@_chk:w #4#5#6 ; #7 @
+ {
+ \cs_if_eq:NNTF #1 \@@_round_to_nearest:NNN
+ {
+ \tl_if_empty:nTF {#7}
+ {
+ \exp_args:Nc \@@_round:Nww
+ {
+ @@_round_to_nearest
+ \if_meaning:w 0 #4 _zero \else:
+ \if_case:w #5 \exp_stop_f: _pinf \or: \else: _ninf \fi: \fi:
+ :NNN
+ }
+ #2 ; #3 ;
+ }
+ {
+ \@@_error:nnnn { num-args } { round () } { 1 } { 3 }
+ \exp_after:wN \c_nan_fp
+ }
+ }
+ {
+ \@@_error:nffn { num-args }
+ { \@@_round_name_from_cs:N #1 () } { 1 } { 2 }
+ \exp_after:wN \c_nan_fp
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_round_name_from_cs:N}
+% \begin{macrocode}
+\cs_new:Npn \@@_round_name_from_cs:N #1
+ {
+ \cs_if_eq:NNTF #1 \@@_round_to_zero:NNN { trunc }
+ {
+ \cs_if_eq:NNTF #1 \@@_round_to_ninf:NNN { floor }
+ {
+ \cs_if_eq:NNTF #1 \@@_round_to_pinf:NNN { ceil }
+ { round }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_round:Nww, \@@_round:Nwn}
+% \begin{macro}[EXP]
+% {
+% \@@_round_normal:NwNNnw ,
+% \@@_round_normal:NnnwNNnn ,
+% \@@_round_pack:Nw ,
+% \@@_round_normal:NNwNnn ,
+% \@@_round_normal_end:wwNnn ,
+% \@@_round_special:NwwNnn ,
+% \@@_round_special_aux:Nw
+% }
+% If the number of digits to round to is an integer or infinity all is
+% good; if it is \texttt{nan} then just produce a \texttt{nan};
+% otherwise invalid as we have something like |round(1,3.14)| where
+% the number of digits is not an integer.
+% \begin{macrocode}
+\cs_new:Npn \@@_round:Nww #1#2 ; #3 ;
+ {
+ \@@_small_int:wTF #3; { \@@_round:Nwn #1#2; }
+ {
+ \if:w 3 \@@_kind:w #3 ;
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ { \exp_after:wN \c_nan_fp }
+ {
+ \@@_invalid_operation_tl_o:ff
+ { \@@_round_name_from_cs:N #1 }
+ { \@@_array_to_clist:n { #2; #3; } }
+ }
+ }
+ }
+\cs_new:Npn \@@_round:Nwn #1 \s_@@ \@@_chk:w #2#3#4; #5
+ {
+ \if_meaning:w 1 #2
+ \exp_after:wN \@@_round_normal:NwNNnw
+ \exp_after:wN #1
+ \int_value:w #5
+ \else:
+ \exp_after:wN \@@_exp_after_o:w
+ \fi:
+ \s_@@ \@@_chk:w #2#3#4;
+ }
+\cs_new:Npn \@@_round_normal:NwNNnw #1#2 \s_@@ \@@_chk:w 1#3#4#5;
+ {
+ \@@_decimate:nNnnnn { \c_@@_prec_int - #4 - #2 }
+ \@@_round_normal:NnnwNNnn #5 #1 #3 {#4} {#2}
+ }
+\cs_new:Npn \@@_round_normal:NnnwNNnn #1#2#3#4; #5#6
+ {
+ \exp_after:wN \@@_round_normal:NNwNnn
+ \int_value:w \@@_int_eval:w
+ \if_int_compare:w #2 > \c_zero_int
+ 1 \int_value:w #2
+ \exp_after:wN \@@_round_pack:Nw
+ \int_value:w \@@_int_eval:w 1#3 +
+ \else:
+ \if_int_compare:w #3 > \c_zero_int
+ 1 \int_value:w #3 +
+ \fi:
+ \fi:
+ \exp_after:wN #5
+ \exp_after:wN #6
+ \use_none:nnnnnnn #3
+ #1
+ \@@_int_eval_end:
+ 0000 0000 0000 0000 ; #6
+ }
+\cs_new:Npn \@@_round_pack:Nw #1
+ { \if_meaning:w 2 #1 + 1 \fi: \@@_int_eval_end: }
+\cs_new:Npn \@@_round_normal:NNwNnn #1 #2
+ {
+ \if_meaning:w 0 #2
+ \exp_after:wN \@@_round_special:NwwNnn
+ \exp_after:wN #1
+ \fi:
+ \@@_pack_twice_four:wNNNNNNNN
+ \@@_pack_twice_four:wNNNNNNNN
+ \@@_round_normal_end:wwNnn
+ ; #2
+ }
+\cs_new:Npn \@@_round_normal_end:wwNnn #1;#2;#3#4#5
+ {
+ \exp_after:wN \@@_exp_after_o:w \exp:w \exp_end_continue_f:w
+ \@@_sanitize:Nw #3 #4 ; #1 ;
+ }
+\cs_new:Npn \@@_round_special:NwwNnn #1#2;#3;#4#5#6
+ {
+ \if_meaning:w 0 #1
+ \@@_case_return:nw
+ { \exp_after:wN \@@_zero_fp:N \exp_after:wN #4 }
+ \else:
+ \exp_after:wN \@@_round_special_aux:Nw
+ \exp_after:wN #4
+ \int_value:w \@@_int_eval:w 1
+ \if_meaning:w 1 #1 -#6 \else: +#5 \fi:
+ \fi:
+ ;
+ }
+\cs_new:Npn \@@_round_special_aux:Nw #1#2;
+ {
+ \exp_after:wN \@@_exp_after_o:w \exp:w \exp_end_continue_f:w
+ \@@_sanitize:Nw #1#2; {1000}{0000}{0000}{0000};
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintChanges
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-symbolic.dtx b/macros/latex-dev/required/l3kernel/l3fp-symbolic.dtx
new file mode 100644
index 0000000000..901ce7a27c
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-symbolic.dtx
@@ -0,0 +1,688 @@
+% \iffalse
+%
+%% File l3fp-symbolic.dtx (C) Copyright 2012-2015,2017,2018,2020,2021,2023 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full]{l3doc}
+\usepackage{amsmath}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-symbolic} module\\ Symbolic expressions^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp-symbolic} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% \subsection{Misc}
+%
+% \begin{variable}{\l_@@_symbolic_fp}
+% Scratch floating point.
+% \begin{macrocode}
+\fp_new:N \l_@@_symbolic_fp
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Building blocks for expressions}
+%
+% Every symbolic expression has the form \cs{s_@@_symbolic}
+% \cs{@@_symbolic_chk:w} \meta{operation} |,| \Arg{operands} \meta{junk}
+% |;| where the \meta{operation} is a list of \texttt{N}-type tokens,
+% the \meta{operands} is an array of floating point objects, and the
+% \meta{junk} is to be discarded. If the outermost operator (last to be
+% evaluated) is unary, the expression has the form
+% \begin{quote}
+% \cs{s_@@_symbolic} \cs{@@_symbolic_chk:w} \\
+% \cs{@@_types_unary:NNw} |\__fp_|\meta{op}|_o:w| \meta{token} |,| \\
+% |{| \meta{operand} |}| \meta{junk} |;|
+% \end{quote}
+% where the \meta{op} is a unary operation (|set_sign|, |cos|,
+% \ldots{}), and the \meta{token} and \meta{operand} are used as
+% arguments for \cs{@@_\meta{op}_o:w} (or the type-specific analog of
+% this function). If the outermost operator is binary, the expression
+% has the form
+% \begin{quote}
+% \cs{s_@@_symbolic} \cs{@@_symbolic_chk:w} \\
+% \cs{@@_types_binary:Nww} |\__fp_|\meta{op}|_o:ww| |,| \\
+% |{| \meta{operand_1} \meta{operand_2} |}| \meta{junk} |;|
+% \end{quote}
+% where the \meta{op} is an operation (|+|, |&|, \ldots{}), and
+% |\__fp_|\meta{op}|_o:ww| receives the \meta{operands} as arguments.
+% If the expression consists of a single variable, it is stored as
+% \begin{quote}
+% \cs{s_@@_symbolic} \cs{@@_symbolic_chk:w} \\
+% \cs{@@_variable_o:w} \meta{identifier} |,| \\
+% |{| |}| \meta{junk} |;|
+% \end{quote}
+%
+% Symbolic expressions are stored in a prefix form. When encountering a
+% symbolic expression in a floating point computation, we attempt to
+% evaluate the operands as much as possible, and if that yields floating
+% point numbers rather than expressions, we apply the operator which
+% follows (if the function is known).
+%
+% For instance, the expression |a + b * sin(c)| is stored as
+% \begin{verbatim}
+% \s__fp_symbolic \__fp_symbolic_chk:w
+% \__fp_types_binary:Nww \__fp_+_o:ww ,
+% {
+% \s__fp_symbolic \__fp_symbolic_chk:w
+% \__fp_variable_o:w a , { } ;
+% \s__fp_symbolic \__fp_symbolic_chk:w
+% \__fp_types_binary:Nww \__fp_*_o:ww ,
+% {
+% \s__fp_symbolic \__fp_symbolic_chk:w
+% \__fp_variable_o:w b , { } ;
+% \s__fp_symbolic \__fp_symbolic_chk:w
+% \__fp_types_unary:NNw \__fp_sin_o:w \use_i:nn ,
+% {
+% \s__fp_symbolic \__fp_symbolic_chk:w
+% \__fp_variable_o:w c , { } ;
+% } ;
+% } ;
+% } ;
+% \end{verbatim}
+%
+% \begin{variable}{\s_@@_symbolic}
+% Scan mark indicating the start of a symbolic expression.
+% \begin{macrocode}
+\scan_new:N \s_@@_symbolic
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_symbolic_chk:w}
+% Analog of \cs{@@_chk:w} for symbolic expressions.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_symbolic_chk:w #1,#2#3;
+ {
+ \msg_error:nne { fp } { misused-fp }
+ {
+ \@@_to_tl_dispatch:w
+ \s_@@_symbolic \@@_symbolic_chk:w #1,{#2};
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Expanding after a symbolic expression}
+%
+% \begin{macro}[EXP]
+% {\@@_if_has_symbolic:nTF, \@@_if_has_symbolic_aux:w}
+% Tests if |#1| contains \cs{s_@@_symbolic} at top-level. This test
+% should be precise enough to determine if a given array contains a
+% symbolic expression or only consists of floating points. Used in
+% \cs{@@_exp_after_symbolic_f:nw}.
+% \begin{macrocode}
+\cs_new:Npn \@@_if_has_symbolic:nTF #1
+ {
+ \@@_if_has_symbolic_aux:w
+ #1 \s_@@_mark \use_i:nn
+ \s_@@_symbolic \s_@@_mark \use_ii:nn
+ \s_@@_stop
+ }
+\cs_new:Npn \@@_if_has_symbolic_aux:w
+ #1 \s_@@_symbolic #2 \s_@@_mark #3#4 \s_@@_stop { #3 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_exp_after_symbolic_f:nw}
+% \begin{macro}[EXP]
+% {\@@_exp_after_symbolic_aux:w, \@@_exp_after_symbolic_loop:N}
+% This function does two things: trigger an \texttt{f}-expansion of
+% the argument~|#1| after the following symbolic expression, and
+% evaluate all pieces of the expression which can be evaluated.
+% \begin{macrocode}
+\cs_new:Npn \@@_exp_after_symbolic_f:nw
+ #1 \s_@@_symbolic \@@_symbolic_chk:w #2, #3#4;
+ {
+ \exp_after:wN \@@_exp_after_symbolic_aux:w
+ \exp:w
+ \@@_exp_after_symbolic_loop:N #2
+ { , \exp:w \use_none:nn }
+ \exp_after:wN \exp_end: \exp_after:wN
+ {
+ \exp:w \exp_end_continue_f:w
+ \@@_exp_after_array_f:w #3 \s_@@_expr_stop
+ \exp_after:wN
+ }
+ \exp_after:wN ;
+ \exp:w \exp_end_continue_f:w #1
+ }
+\cs_new:Npn \@@_exp_after_symbolic_aux:w #1, #2;
+ {
+ \@@_if_has_symbolic:nTF {#2}
+ { \s_@@_symbolic \@@_symbolic_chk:w #1, {#2} ; }
+ { #1 #2 @ \prg_do_nothing: }
+ }
+\cs_new:Npn \@@_exp_after_symbolic_loop:N #1
+ {
+ \exp_after:wN \exp_end:
+ \exp_after:wN #1
+ \exp:w
+ \@@_exp_after_symbolic_loop:N
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Applying infix operators to expressions}
+%
+% \begin{macro}[EXP]{\@@_symbolic_binary_o:Nww}
+% Used when applying infix operators to expressions.
+% \begin{macrocode}
+\cs_new:Npn \@@_symbolic_binary_o:Nww #1 #2; #3;
+ {
+ \@@_exp_after_symbolic_f:nw { \exp_after:wN \exp_stop_f: }
+ \s_@@_symbolic \@@_symbolic_chk:w
+ \@@_types_binary:Nww #1 , { #2; #3; } ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{@makeother}{^} %^^A Hack!
+% \begin{@makeother}{|} %^^A Hack!
+% \begin{@makeother}{&} %^^A Hack!
+% \begin{macro}[EXP]
+% {
+% \@@_symbolic_+_symbolic_o:ww,
+% \@@_symbolic_+_o:ww,
+% \@@_+_symbolic_o:ww,
+% \@@_symbolic_-_symbolic_o:ww,
+% \@@_symbolic_-_o:ww,
+% \@@_-_symbolic_o:ww,
+% \@@_symbolic_*_symbolic_o:ww,
+% \@@_symbolic_*_o:ww,
+% \@@_*_symbolic_o:ww,
+% \@@_symbolic_/_symbolic_o:ww,
+% \@@_symbolic_/_o:ww,
+% \@@_/_symbolic_o:ww,
+% \@@_symbolic_^_symbolic_o:ww,
+% \@@_symbolic_^_o:ww,
+% \@@_^_symbolic_o:ww,
+% \@@_symbolic_|_symbolic_o:ww,
+% \@@_symbolic_|_o:ww,
+% \@@_|_symbolic_o:ww,
+% \@@_symbolic_&_symbolic_o:ww,
+% \@@_symbolic_&_o:ww,
+% \@@_&_symbolic_o:ww,
+% }
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1#2
+ {
+ \cs_new:cpn
+ { @@_symbolic_#2_symbolic_o:ww }
+ { \@@_symbolic_binary_o:Nww #1 }
+ \cs_new_eq:cc
+ { @@_symbolic_#2 _o:ww }
+ { @@_symbolic_#2_symbolic_o:ww }
+ \cs_new_eq:cc
+ { @@ _#2_symbolic_o:ww }
+ { @@_symbolic_#2_symbolic_o:ww }
+ }
+\tl_map_inline:nn { + - * / ^ & | }
+ { \exp_args:Nc \@@_tmp:w { @@_#1_o:ww } {#1} }
+% \end{macrocode}
+% \end{macro}
+% \end{@makeother}
+% \end{@makeother}
+% \end{@makeother}
+%
+% \subsection{Applying prefix functions to expressions}
+%
+% \begin{macro}[EXP]{\@@_symbolic_unary_o:NNw}
+% Used when applying infix operators to expressions.
+% \begin{macrocode}
+\cs_new:Npn \@@_symbolic_unary_o:NNw #1#2#3; @
+ {
+ \@@_exp_after_symbolic_f:nw { \exp_after:wN \exp_stop_f: }
+ \s_@@_symbolic \@@_symbolic_chk:w
+ \@@_types_unary:NNw #1#2 , { #3; } ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_symbolic_acos_o:w ,
+% \@@_symbolic_acsc_o:w ,
+% \@@_symbolic_asec_o:w ,
+% \@@_symbolic_asin_o:w ,
+% \@@_symbolic_cos_o:w ,
+% \@@_symbolic_cot_o:w ,
+% \@@_symbolic_csc_o:w ,
+% \@@_symbolic_exp_o:w ,
+% \@@_symbolic_ln_o:w ,
+% \@@_symbolic_not_o:w ,
+% \@@_symbolic_sec_o:w ,
+% \@@_symbolic_set_sign_o:w ,
+% \@@_symbolic_sin_o:w ,
+% \@@_symbolic_tan_o:w ,
+% }
+% \begin{macrocode}
+\tl_map_inline:nn
+ {
+ {acos} {acsc} {asec} {asin} {cos} {cot} {csc} {exp} {ln}
+ {not} {sec} {set_sign} {sin} {sqrt} {tan}
+ }
+ {
+ \cs_new:cpe { @@_symbolic_#1_o:w }
+ {
+ \exp_not:N \@@_symbolic_unary_o:NNw
+ \exp_not:c { @@_#1_o:w }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Conversions}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_symbolic_to_decimal:w,
+% \@@_symbolic_to_int:w,
+% \@@_symbolic_to_scientific:w
+% }
+% \begin{macro}[EXP]{\@@_symbolic_convert:wnnN}
+% Symbolic expressions cannot be converted to decimal, integer, or
+% scientific notation unless they can be reduced to
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1#2#3
+ {
+ \cs_new:cpn { @@_symbolic_to_#1:w }
+ {
+ \exp_after:wN \@@_symbolic_convert:wnnN
+ \exp:w \exp_end_continue_f:w
+ \@@_exp_after_symbolic_f:nw { { #2 } { fp_to_#1 } #3 }
+ }
+ }
+\@@_tmp:w { decimal } { 0 } \@@_to_decimal_dispatch:w
+\@@_tmp:w { int } { 0 } \@@_to_int_dispatch:w
+\@@_tmp:w { scientific } { nan } \@@_to_scientific_dispatch:w
+\cs_new:Npn \@@_symbolic_convert:wnnN #1#2; #3#4#5
+ {
+ \str_if_eq:nnTF {#1} { \s_@@_symbolic }
+ { \@@_invalid_operation:nnw {#3} {#4} #1#2; }
+ { #5 #1#2; }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_symbolic_cs_arg_to_fn:NN, \@@_symbolic_op_arg_to_fn:nN}
+% \begin{macrocode}
+\cs_new:Npn \@@_symbolic_cs_arg_to_fn:NN #1
+ {
+ \exp_args:Nf \@@_symbolic_op_arg_to_fn:nN
+ { \@@_types_cs_to_op:N #1 }
+ }
+\cs_new:Npn \@@_symbolic_op_arg_to_fn:nN #1#2
+ {
+ \str_case:nnF { #1 #2 }
+ {
+ { not ? } { ! }
+ { set_sign 0 } { abs }
+ { set_sign 2 } { - }
+ }
+ {
+ \token_if_eq_meaning:NNTF #2 \use_ii:nn
+ { #1 d } {#1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_symbolic_to_tl:w}
+% \begin{macro}[rEXP]
+% {
+% \@@_symbolic_unary_to_tl:NNw,
+% \@@_symbolic_binary_to_tl:Nww,
+% \@@_symbolic_function_to_tl:Nw
+% }
+% Converting a symbolic expression to a token list is possible.
+% \begin{macrocode}
+\cs_new:Npn \@@_symbolic_to_tl:w
+ \s_@@_symbolic \@@_symbolic_chk:w #1#2, #3#4;
+ {
+ \str_case:nnTF {#1}
+ {
+ { \@@_types_unary:NNw } { \@@_symbolic_unary_to_tl:NNw }
+ { \@@_types_binary:Nww } { \@@_symbolic_binary_to_tl:Nww }
+ { \@@_function_o:w } { \@@_symbolic_function_to_tl:Nw }
+ }
+ { #2, #3 @ }
+ { \tl_to_str:n {#2} }
+ }
+\cs_new:Npn \@@_symbolic_unary_to_tl:NNw #1#2 , #3 @
+ {
+ \use:e
+ {
+ \@@_symbolic_cs_arg_to_fn:NN #1#2
+ ( \@@_to_tl_dispatch:w #3 )
+ }
+ }
+\cs_new:Npn \@@_symbolic_binary_to_tl:Nww #1, #2; #3; @
+ {
+ \use:e
+ {
+ ( \@@_to_tl_dispatch:w #2; )
+ \@@_types_cs_to_op:N #1
+ ( \@@_to_tl_dispatch:w #3; )
+ }
+ }
+\cs_new:Npn \@@_symbolic_function_to_tl:Nw #1, #2@
+ {
+ \use:e
+ {
+ \@@_types_cs_to_op:N #1
+ ( \@@_array_to_clist:n {#2} )
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Identifiers}
+%
+% Functions defined here are not necessarily tied to symbolic
+% expressions.
+%
+% \begin{macro}[TF]{\@@_id_if_invalid:n}
+% \begin{macro}[EXP]{\@@_id_if_invalid_aux:N}
+% If |#1| contains a space, it is not a valid identifier. Otherwise,
+% loop through letters in |#1|: if it is not a letter, break the loop
+% and return \texttt{true}. If the end of the loop is reached
+% without finding any non-letter, return \texttt{false}.
+% Note |#1| must be a str (i.e., resulted from \cs{tl_to_str:n}).
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn
+ \@@_id_if_invalid:n #1 { T , F , TF }
+ {
+ \tl_if_empty:nTF {#1}
+ { \prg_return_true: }
+ {
+ \tl_if_in:nnTF { #1 } { ~ }
+ { \prg_return_true: }
+ {
+ \@@_id_if_invalid_aux:N #1
+ { ? \prg_break:n \prg_return_false: }
+ \prg_break_point:
+ }
+ }
+ }
+\cs_new:Npn \@@_id_if_invalid_aux:N #1
+ {
+ \use_none:n #1
+ \int_compare:nF { `a <= `#1 <= `z }
+ {
+ \int_compare:nF { `A <= `#1 <= `Z }
+ { \prg_break:n \prg_return_true: }
+ }
+ \@@_id_if_invalid_aux:N
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Declaring variables and assigning values}
+%
+% \begin{macro}[EXP]{\@@_variable_o:w}
+% We do not use \cs{exp_last_unbraced:Nv} to extract the value of
+% |\l__fp_variable_#1_fp| because in \cs{fp_set_variable:nn} we define
+% this \texttt{fp} variable to be something which \texttt{f}-expands
+% to an actual floating point, rather than a genuine floating point.
+% \begin{macrocode}
+\cs_new:Npn \@@_variable_o:w #1 @ #2
+ {
+ \fp_if_exist:cTF { l_@@_variable_#1_fp }
+ {
+ \exp_last_unbraced:Nf \@@_exp_after_array_f:w
+ { \use:c { l_@@_variable_#1_fp } } \s_@@_expr_stop
+ \exp_after:wN \exp_stop_f: #2
+ }
+ {
+ \token_if_eq_meaning:NNTF #2 \prg_do_nothing:
+ {
+ \s_@@_symbolic \@@_symbolic_chk:w
+ \@@_variable_o:w #1 , { } ;
+ }
+ {
+ \exp_after:wN \s_@@_symbolic
+ \exp_after:wN \@@_symbolic_chk:w
+ \exp_after:wN \@@_variable_o:w
+ \exp:w
+ \@@_exp_after_symbolic_loop:N #1
+ { , \exp:w \use_none:nn }
+ \exp_after:wN \exp_end:
+ \exp_after:wN { \exp_after:wN } \exp_after:wN ;
+ #2
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_variable_set_parsing:Nn, \@@_variable_set_parsing_aux:NNn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_variable_set_parsing:Nn #1#2
+ {
+ \cs_set:Npn \@@_tmp:w
+ {
+ \@@_exp_after_symbolic_f:nw { \@@_parse_infix:NN }
+ \s_@@_symbolic \@@_symbolic_chk:w
+ \@@_variable_o:w #2 , { } ;
+ }
+ \exp_args:NNc \@@_variable_set_parsing_aux:NNn #1
+ { @@_parse_word_#2:N } {#2}
+ }
+\cs_new_protected:Npn \@@_variable_set_parsing_aux:NNn #1#2#3
+ {
+ \cs_if_eq:NNF #2 \@@_tmp:w
+ {
+ \cs_if_exist:NTF #2
+ {
+ \msg_warning:nnnn
+ { fp } { id-used-elsewhere } {#3} { variable }
+ #1 #2 \@@_tmp:w
+ }
+ {
+ \cs_new_eq:NN #2 \scan_stop: % to declare the function
+ #1 #2 \@@_tmp:w
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \fp_clear_variable:n,
+% \@@_clear_variable:n, \@@_clear_variable_aux:n
+% }
+% We need local undefining, so have to do it low-level.
+% \cs{@@_clear_variable_aux:n} is needed by \cs{@@_set_function:Nnnn}
+% to skip \cs{@@_id_if_invalid:nTF}.
+% \begin{macrocode}
+\cs_new_protected:Npn \fp_clear_variable:n #1
+ {
+ \exp_args:No \@@_clear_variable:n { \tl_to_str:n {#1} }
+ }
+\cs_new_protected:Npn \@@_clear_variable:n #1
+ {
+ \@@_id_if_invalid:nTF {#1}
+ { \msg_error:nnn { fp } { id-invalid } {#1} }
+ { \@@_clear_variable_aux:n {#1} }
+ }
+\cs_new_protected:Npn \@@_clear_variable_aux:n #1
+ {
+ \cs_set_eq:cN { l_@@_variable_#1_fp } \tex_undefined:D
+ \@@_variable_set_parsing:Nn \cs_set_eq:NN {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp_new_variable:n}
+% \begin{macro}{\@@_new_variable:n}
+% Check that |#1| is a valid identifier. If the identifier is already
+% in use, complain. Then set |\__fp_parse_word_#1:N| to use
+% |\__fp_variable_o:w|.
+% \begin{macrocode}
+\cs_new_protected:Npn \fp_new_variable:n #1
+ {
+ \exp_args:No \@@_new_variable:n { \tl_to_str:n {#1} }
+ }
+\cs_new_protected:Npn \@@_new_variable:n #1
+ {
+ \@@_id_if_invalid:nTF {#1}
+ { \msg_error:nnn { fp } { id-invalid } {#1} }
+ {
+ \cs_if_exist:cT { @@_parse_word_#1:N }
+ {
+ \msg_error:nnn
+ { fp } { id-already-defined } {#1}
+ \cs_undefine:c { @@_parse_word_#1:N }
+ \cs_set_eq:cN { l_@@_variable_#1_fp } \tex_undefined:D
+ }
+ \@@_variable_set_parsing:Nn \cs_gset_eq:NN {#1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_symbolic_flag}
+% \begin{macro}{\fp_set_variable:nn, \@@_set_variable:nn}
+% Refuse invalid identifiers. If the variable does not exist yet,
+% define it just as in \cs{fp_new_variable:n} (but without unnecessary
+% checks). Then evaluate~|#2|. If the result contains the
+% identifier~|#1|, we would later get a loop in cases such as
+% \begin{quote}
+% \cs{fp_set_variable:nn} |{A}| |{A}|\\
+% \cs{fp_show:n} |{A}|
+% \end{quote}
+% To detect this, define |\l__fp_variable_#1_fp| to raise an
+% internal flag and evaluate to \texttt{nan}. Then re-evaluate
+% \cs{l_@@_symbolic_fp}, and store the result in~|#1|. If the flag is
+% raised, |#1|~was present in \cs{l_@@_symbolic_fp}. In all cases,
+% the |#1|-free result ends up in |\l__fp_variable_#1_fp|.
+% \begin{macrocode}
+\flag_new:N \l_@@_symbolic_flag
+\cs_new_protected:Npn \fp_set_variable:nn #1
+ {
+ \exp_args:No \@@_set_variable:nn { \tl_to_str:n {#1} }
+ }
+\cs_new_protected:Npn \@@_set_variable:nn #1#2
+ {
+ \@@_id_if_invalid:nTF {#1}
+ { \msg_error:nnn { fp } { id-invalid } {#1} }
+ {
+ \@@_variable_set_parsing:Nn \cs_set_eq:NN {#1}
+ \fp_set:Nn \l_@@_symbolic_fp {#2}
+ \cs_set_nopar:cpn { l_@@_variable_#1_fp }
+ { \flag_ensure_raised:N \l_@@_symbolic_flag \c_nan_fp }
+ \flag_clear:N \l_@@_symbolic_flag
+ \fp_set:cn { l_@@_variable_#1_fp } { \l_@@_symbolic_fp }
+ \flag_if_raised:NT \l_@@_symbolic_flag
+ {
+ \msg_error:nneee { fp } { id-loop }
+ { #1 }
+ { \tl_to_str:n {#2} }
+ { \fp_to_tl:N \l_@@_symbolic_fp }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{variable}
+%
+% \subsection{Messages}
+%
+% \begin{macrocode}
+\msg_new:nnnn { fp } { id-invalid }
+ { Floating~point~identifier~'#1'~invalid. }
+ {
+ LaTeX~has~been~asked~to~create~a~new~floating~point~identifier~'#1'~
+ but~this~may~only~contain~ASCII~letters.
+ }
+\msg_new:nnnn { fp } { id-already-defined }
+ { Floating~point~identifier~'#1'~already~defined. }
+ {
+ LaTeX~has~been~asked~to~create~a~new~floating~point~identifier~'#1'~
+ but~this~name~has~already~been~used~elsewhere.
+ }
+\msg_new:nnnn { fp } { id-used-elsewhere }
+ { Floating~point~identifier~'#1'~already~used~for~something~else. }
+ {
+ LaTeX~has~been~asked~to~create~a~new~floating~point~identifier~'#1'~
+ but~this~name~is~used,~and~is~not~a~user-defined~#2.
+ }
+\msg_new:nnnn { fp } { id-loop }
+ { Variable~'#1'~used~in~the~definition~of~'#1'. }
+ {
+ LaTeX~has~been~asked~to~set~the~floating~point~identifier~'#1'~
+ to~the~expression~'#2'.~Evaluating~this~expression~yields~'#3',~
+ which~contains~'#1'~itself.
+ }
+% \end{macrocode}
+%
+% \subsection{Road-map}
+%
+% The following functions are not implemented: |min|, |max|, |?:|,
+% comparisons, |round|, |atan|, |acot|.
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-traps.dtx b/macros/latex-dev/required/l3kernel/l3fp-traps.dtx
new file mode 100644
index 0000000000..5a4a3b41f9
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-traps.dtx
@@ -0,0 +1,402 @@
+% \iffalse meta-comment
+%
+%% File: l3fp-traps.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-traps} module\\
+% Trapping floating-point exceptions^^A
+% }
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+% \date{Released 2024-04-11}
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp-traps} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% Exceptions should be accessed by an \texttt{n}-type argument, among
+% \begin{itemize}
+% \item \texttt{invalid_operation}
+% \item \texttt{division_by_zero}
+% \item \texttt{overflow}
+% \item \texttt{underflow}
+% \item \texttt{inexact} (actually never used).
+% \end{itemize}
+%
+% \subsection{Flags}
+%
+% \begin{variable}[module = fp]
+% {
+% \l_fp_invalid_operation_flag,
+% \l_fp_division_by_zero_flag,
+% \l_fp_overflow_flag,
+% \l_fp_underflow_flag
+% }
+% Flags to denote exceptions.
+% \begin{macrocode}
+\flag_new:N \l_fp_invalid_operation_flag
+\flag_new:N \l_fp_division_by_zero_flag
+\flag_new:N \l_fp_overflow_flag
+\flag_new:N \l_fp_underflow_flag
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Traps}
+%
+% Exceptions can be trapped to obtain custom behaviour. When an invalid
+% operation or a division by zero is trapped, the trap receives as
+% arguments the result as an |N|-type floating point number, the
+% function name (multiple letters for prefix operations, or a single
+% symbol for infix operations), and the operand(s). When an overflow or
+% underflow is trapped, the trap receives the resulting overly large or
+% small floating point number if it is not too big, otherwise it
+% receives $+\infty$. Currently, the inexact exception is entirely
+% ignored.
+%
+% The behaviour when an exception occurs is controlled by the
+% definitions of the functions
+% \begin{itemize}
+% \item \cs{@@_invalid_operation:nnw},
+% \item \cs{@@_invalid_operation_o:Nww},
+% \item \cs{@@_invalid_operation_tl_o:ff},
+% \item \cs{@@_division_by_zero_o:Nnw},
+% \item \cs{@@_division_by_zero_o:NNww},
+% \item \cs{@@_overflow:w},
+% \item \cs{@@_underflow:w}.
+% \end{itemize}
+% Rather than changing them directly, we provide a user interface as
+% \cs{fp_trap:nn} \Arg{exception} \Arg{way of trapping}, where the
+% \meta{way of trapping} is one of \texttt{error}, \texttt{flag}, or
+% \texttt{none}.
+%
+% We also provide \cs{@@_invalid_operation_o:nw}, defined in terms of
+% \cs{@@_invalid_operation:nnw}.
+%
+% \begin{macro}{\fp_trap:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \fp_trap:nn #1#2
+ {
+ \cs_if_exist_use:cF { @@_trap_#1_set_#2: }
+ {
+ \clist_if_in:nnTF
+ { invalid_operation , division_by_zero , overflow , underflow }
+ {#1}
+ {
+ \msg_error:nnee { fp }
+ { unknown-fpu-trap-type } {#1} {#2}
+ }
+ {
+ \msg_error:nne
+ { fp } { unknown-fpu-exception } {#1}
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_trap_invalid_operation_set_error: ,
+% \@@_trap_invalid_operation_set_flag: ,
+% \@@_trap_invalid_operation_set_none: ,
+% \@@_trap_invalid_operation_set:N ,
+% }
+% We provide three types of trapping for invalid operations: either
+% produce an error and raise the relevant flag; or only raise the
+% flag; or don't even raise the flag. In most cases, the function
+% produces as a result its first argument, possibly with
+% post-expansion.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_trap_invalid_operation_set_error:
+ { \@@_trap_invalid_operation_set:N \prg_do_nothing: }
+\cs_new_protected:Npn \@@_trap_invalid_operation_set_flag:
+ { \@@_trap_invalid_operation_set:N \use_none:nnnnn }
+\cs_new_protected:Npn \@@_trap_invalid_operation_set_none:
+ { \@@_trap_invalid_operation_set:N \use_none:nnnnnnn }
+\cs_new_protected:Npn \@@_trap_invalid_operation_set:N #1
+ {
+ \exp_args:Nno \use:n
+ { \cs_set:Npn \@@_invalid_operation:nnw ##1##2##3; }
+ {
+ #1
+ \@@_error:nnfn { invalid } {##2} { \fp_to_tl:n { ##3; } } { }
+ \flag_ensure_raised:N \l_fp_invalid_operation_flag
+ ##1
+ }
+ \exp_args:Nno \use:n
+ { \cs_set:Npn \@@_invalid_operation_o:Nww ##1##2; ##3; }
+ {
+ #1
+ \@@_error:nffn { invalid-ii }
+ { \fp_to_tl:n { ##2; } } { \fp_to_tl:n { ##3; } } {##1}
+ \flag_ensure_raised:N \l_fp_invalid_operation_flag
+ \exp_after:wN \c_nan_fp
+ }
+ \exp_args:Nno \use:n
+ { \cs_set:Npn \@@_invalid_operation_tl_o:ff ##1##2 }
+ {
+ #1
+ \@@_error:nffn { invalid } {##1} {##2} { }
+ \flag_ensure_raised:N \l_fp_invalid_operation_flag
+ \exp_after:wN \c_nan_fp
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_trap_division_by_zero_set_error: ,
+% \@@_trap_division_by_zero_set_flag: ,
+% \@@_trap_division_by_zero_set_none: ,
+% \@@_trap_division_by_zero_set:N ,
+% }
+% We provide three types of trapping for invalid operations and
+% division by zero: either produce an error and raise the relevant
+% flag; or only raise the flag; or don't even raise the flag. In all
+% cases, the function must produce a result, namely its first
+% argument, $\pm\infty$ or \nan{}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_trap_division_by_zero_set_error:
+ { \@@_trap_division_by_zero_set:N \prg_do_nothing: }
+\cs_new_protected:Npn \@@_trap_division_by_zero_set_flag:
+ { \@@_trap_division_by_zero_set:N \use_none:nnnnn }
+\cs_new_protected:Npn \@@_trap_division_by_zero_set_none:
+ { \@@_trap_division_by_zero_set:N \use_none:nnnnnnn }
+\cs_new_protected:Npn \@@_trap_division_by_zero_set:N #1
+ {
+ \exp_args:Nno \use:n
+ { \cs_set:Npn \@@_division_by_zero_o:Nnw ##1##2##3; }
+ {
+ #1
+ \@@_error:nnfn { zero-div } {##2} { \fp_to_tl:n { ##3; } } { }
+ \flag_ensure_raised:N \l_fp_division_by_zero_flag
+ \exp_after:wN ##1
+ }
+ \exp_args:Nno \use:n
+ { \cs_set:Npn \@@_division_by_zero_o:NNww ##1##2##3; ##4; }
+ {
+ #1
+ \@@_error:nffn { zero-div-ii }
+ { \fp_to_tl:n { ##3; } } { \fp_to_tl:n { ##4; } } {##2}
+ \flag_ensure_raised:N \l_fp_division_by_zero_flag
+ \exp_after:wN ##1
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_trap_overflow_set_error: ,
+% \@@_trap_overflow_set_flag: ,
+% \@@_trap_overflow_set_none: ,
+% \@@_trap_overflow_set:N ,
+% }
+% \begin{macro}
+% {
+% \@@_trap_underflow_set_error: ,
+% \@@_trap_underflow_set_flag: ,
+% \@@_trap_underflow_set_none: ,
+% \@@_trap_underflow_set:N ,
+% }
+% \begin{macro}{\@@_trap_overflow_set:NnNn}
+% Just as for invalid operations and division by zero, the three
+% different behaviours are obtained by feeding \cs{prg_do_nothing:},
+% \cs{use_none:nnnnn} or \cs{use_none:nnnnnnn} to an auxiliary, with a
+% further auxiliary common to overflow and underflow functions. In
+% most cases, the argument of the \cs{@@_overflow:w} and
+% \cs{@@_underflow:w} functions will be an (almost) normal number
+% (with an exponent outside the allowed range), and the error message
+% thus displays that number together with the result to which it
+% overflowed or underflowed. For extreme cases such as \texttt{10 **
+% 1e9999}, the exponent would be too large for \TeX{}, and
+% \cs{@@_overflow:w} receives $\pm \infty$ (\cs{@@_underflow:w} would
+% receive $\pm 0$); then we cannot do better than simply say an
+% overflow or underflow occurred.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_trap_overflow_set_error:
+ { \@@_trap_overflow_set:N \prg_do_nothing: }
+\cs_new_protected:Npn \@@_trap_overflow_set_flag:
+ { \@@_trap_overflow_set:N \use_none:nnnnn }
+\cs_new_protected:Npn \@@_trap_overflow_set_none:
+ { \@@_trap_overflow_set:N \use_none:nnnnnnn }
+\cs_new_protected:Npn \@@_trap_overflow_set:N #1
+ { \@@_trap_overflow_set:NnNn #1 { overflow } \@@_inf_fp:N { inf } }
+\cs_new_protected:Npn \@@_trap_underflow_set_error:
+ { \@@_trap_underflow_set:N \prg_do_nothing: }
+\cs_new_protected:Npn \@@_trap_underflow_set_flag:
+ { \@@_trap_underflow_set:N \use_none:nnnnn }
+\cs_new_protected:Npn \@@_trap_underflow_set_none:
+ { \@@_trap_underflow_set:N \use_none:nnnnnnn }
+\cs_new_protected:Npn \@@_trap_underflow_set:N #1
+ { \@@_trap_overflow_set:NnNn #1 { underflow } \@@_zero_fp:N { 0 } }
+\cs_new_protected:Npn \@@_trap_overflow_set:NnNn #1#2#3#4
+ {
+ \exp_args:Nno \use:n
+ { \cs_set:cpn { @@_ #2 :w } \s_@@ \@@_chk:w ##1##2##3; }
+ {
+ #1
+ \@@_error:nffn
+ { flow \if_meaning:w 1 ##1 -to \fi: }
+ { \fp_to_tl:n { \s_@@ \@@_chk:w ##1##2##3; } }
+ { \token_if_eq_meaning:NNF 0 ##2 { - } #4 }
+ {#2}
+ \flag_ensure_raised:c { l_fp_#2_flag }
+ #3 ##2
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_invalid_operation:nnw, \@@_invalid_operation_o:Nww,
+% \@@_invalid_operation_tl_o:ff,
+% \@@_division_by_zero_o:Nnw, \@@_division_by_zero_o:NNww,
+% \@@_overflow:w , \@@_underflow:w
+% }
+% Initialize the control sequences (to log properly their
+% existence). Then set invalid operations to trigger an error, and
+% division by zero, overflow, and underflow to act silently on their
+% flag.
+% \begin{macrocode}
+\cs_new:Npn \@@_invalid_operation:nnw #1#2#3; { }
+\cs_new:Npn \@@_invalid_operation_o:Nww #1#2; #3; { }
+\cs_new:Npn \@@_invalid_operation_tl_o:ff #1 #2 { }
+\cs_new:Npn \@@_division_by_zero_o:Nnw #1#2#3; { }
+\cs_new:Npn \@@_division_by_zero_o:NNww #1#2#3; #4; { }
+\cs_new:Npn \@@_overflow:w { }
+\cs_new:Npn \@@_underflow:w { }
+\fp_trap:nn { invalid_operation } { error }
+\fp_trap:nn { division_by_zero } { flag }
+\fp_trap:nn { overflow } { flag }
+\fp_trap:nn { underflow } { flag }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_invalid_operation_o:nw, \@@_invalid_operation_o:fw}
+% Convenient short-hands for returning \cs{c_nan_fp} for a unary or
+% binary operation, and expanding after.
+% \begin{macrocode}
+\cs_new:Npn \@@_invalid_operation_o:nw
+ { \@@_invalid_operation:nnw { \exp_after:wN \c_nan_fp } }
+\cs_generate_variant:Nn \@@_invalid_operation_o:nw { f }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Errors}
+%
+% \begin{macro}[EXP]{\@@_error:nnnn, \@@_error:nnfn, \@@_error:nffn, \@@_error:nfff}
+% \begin{macrocode}
+\cs_new:Npn \@@_error:nnnn
+ { \msg_expandable_error:nnnnn { fp } }
+\cs_generate_variant:Nn \@@_error:nnnn { nnf, nff , nfff }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% Some messages.
+% \begin{macrocode}
+\msg_new:nnnn { fp } { unknown-fpu-exception }
+ {
+ The~FPU~exception~'#1'~is~not~known:~
+ that~trap~will~never~be~triggered.
+ }
+ {
+ The~only~exceptions~to~which~traps~can~be~attached~are \\
+ \iow_indent:n
+ {
+ * ~ invalid_operation \\
+ * ~ division_by_zero \\
+ * ~ overflow \\
+ * ~ underflow
+ }
+ }
+\msg_new:nnnn { fp } { unknown-fpu-trap-type }
+ { The~FPU~trap~type~'#2'~is~not~known. }
+ {
+ The~trap~type~must~be~one~of \\
+ \iow_indent:n
+ {
+ * ~ error \\
+ * ~ flag \\
+ * ~ none
+ }
+ }
+\msg_new:nnn { fp } { flow }
+ { An ~ #3 ~ occurred. }
+\msg_new:nnn { fp } { flow-to }
+ { #1 ~ #3 ed ~ to ~ #2 . }
+\msg_new:nnn { fp } { zero-div }
+ { Division~by~zero~in~ #1 (#2) }
+\msg_new:nnn { fp } { zero-div-ii }
+ { Division~by~zero~in~ (#1) #3 (#2) }
+\msg_new:nnn { fp } { invalid }
+ { Invalid~operation~ #1 (#2) }
+\msg_new:nnn { fp } { invalid-ii }
+ { Invalid~operation~ (#1) #3 (#2) }
+\msg_new:nnn { fp } { unknown-type }
+ { Unknown~type~for~'#1' }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintChanges
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-trig.dtx b/macros/latex-dev/required/l3kernel/l3fp-trig.dtx
new file mode 100644
index 0000000000..d8585ebe66
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-trig.dtx
@@ -0,0 +1,1700 @@
+% \iffalse meta-comment
+%
+%% File: l3fp-trig.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-trig} module\\
+% Floating point trigonometric functions^^A
+% }
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp-trig} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_word_acos:N ,
+% \@@_parse_word_acosd:N ,
+% \@@_parse_word_acsc:N ,
+% \@@_parse_word_acscd:N ,
+% \@@_parse_word_asec:N ,
+% \@@_parse_word_asecd:N ,
+% \@@_parse_word_asin:N ,
+% \@@_parse_word_asind:N ,
+% \@@_parse_word_cos:N ,
+% \@@_parse_word_cosd:N ,
+% \@@_parse_word_cot:N ,
+% \@@_parse_word_cotd:N ,
+% \@@_parse_word_csc:N ,
+% \@@_parse_word_cscd:N ,
+% \@@_parse_word_sec:N ,
+% \@@_parse_word_secd:N ,
+% \@@_parse_word_sin:N ,
+% \@@_parse_word_sind:N ,
+% \@@_parse_word_tan:N ,
+% \@@_parse_word_tand:N ,
+% }
+% Unary functions.
+% \begin{macrocode}
+\tl_map_inline:nn
+ {
+ {acos} {acsc} {asec} {asin}
+ {cos} {cot} {csc} {sec} {sin} {tan}
+ }
+ {
+ \cs_new:cpe { @@_parse_word_#1:N }
+ {
+ \exp_not:N \@@_parse_unary_function:NNN
+ \exp_not:c { @@_#1_o:w }
+ \exp_not:N \use_i:nn
+ }
+ \cs_new:cpe { @@_parse_word_#1d:N }
+ {
+ \exp_not:N \@@_parse_unary_function:NNN
+ \exp_not:c { @@_#1_o:w }
+ \exp_not:N \use_ii:nn
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_word_acot:N , \@@_parse_word_acotd:N,
+% \@@_parse_word_atan:N , \@@_parse_word_atand:N,
+% }
+% Those functions may receive a variable number of arguments.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_word_acot:N
+ { \@@_parse_function:NNN \@@_acot_o:Nw \use_i:nn }
+\cs_new:Npn \@@_parse_word_acotd:N
+ { \@@_parse_function:NNN \@@_acot_o:Nw \use_ii:nn }
+\cs_new:Npn \@@_parse_word_atan:N
+ { \@@_parse_function:NNN \@@_atan_o:Nw \use_i:nn }
+\cs_new:Npn \@@_parse_word_atand:N
+ { \@@_parse_function:NNN \@@_atan_o:Nw \use_ii:nn }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Direct trigonometric functions}
+%
+% The approach for all trigonometric functions (sine, cosine, tangent,
+% cotangent, cosecant, and secant), with arguments given in radians or
+% in degrees, is the same.
+% \begin{itemize}
+% \item Filter out special cases ($\pm 0$, $\pm\inf$ and \nan{}).
+% \item Keep the sign for later, and work with the absolute value
+% $\lvert x\rvert$ of the argument.
+% \item Small numbers ($\lvert x\rvert<1$ in radians, $\lvert
+% x\rvert<10$ in degrees) are converted to fixed point numbers (and
+% to radians if $\lvert x\rvert$ is in degrees).
+% \item For larger numbers, we need argument reduction. Subtract a
+% multiple of $\pi/2$ (in degrees,~$90$) to bring the number to the
+% range to $[0, \pi/2)$ (in degrees, $[0,90)$).
+% \item Reduce further to $[0, \pi/4]$ (in degrees, $[0,45]$) using
+% $\sin x = \cos (\pi/2-x)$, and when working in degrees, convert to
+% radians.
+% \item Use the appropriate power series depending on the octant
+% $\lfloor\frac{|x|}{\pi/4}\rfloor \mod 8$ (in degrees, the same
+% formula with $\pi/4\to 45$), the sign, and the function to
+% compute.
+% \end{itemize}
+%
+% \subsubsection{Filtering special cases}
+%
+% \begin{macro}[EXP]{\@@_sin_o:w}
+% This function, and its analogs for \texttt{cos}, \texttt{csc},
+% \texttt{sec}, \texttt{tan}, and \texttt{cot} instead of
+% \texttt{sin}, are followed either by \cs{use_i:nn} and a float in
+% radians or by \cs{use_ii:nn} and a float in degrees. The sine of
+% $\pm 0$ or \nan{} is the same float. The sine of $\pm\infty$ raises
+% an invalid operation exception with the appropriate function name.
+% Otherwise, call the \texttt{trig} function to perform argument
+% reduction and if necessary convert the reduced argument to radians.
+% Then, \cs{@@_sin_series_o:NNwwww} is called to compute the
+% Taylor series: this function receives a sign~|#3|, an initial octant
+% of~$0$, and the function \cs{@@_ep_to_float_o:wwN} which converts the
+% result of the series to a floating point directly rather than taking
+% its inverse, since $\sin(x) = \#3 \sin\lvert x\rvert$.
+% \begin{macrocode}
+\cs_new:Npn \@@_sin_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+ {
+ \if_case:w #2 \exp_stop_f:
+ \@@_case_return_same_o:w
+ \or: \@@_case_use:nw
+ {
+ \@@_trig:NNNNNwn #1 \@@_sin_series_o:NNwwww
+ \@@_ep_to_float_o:wwN #3 0
+ }
+ \or: \@@_case_use:nw
+ { \@@_invalid_operation_o:fw { #1 { sin } { sind } } }
+ \else: \@@_case_return_same_o:w
+ \fi:
+ \s_@@ \@@_chk:w #2 #3 #4;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_cos_o:w}
+% The cosine of $\pm 0$ is $1$. The cosine of $\pm\infty$ raises an
+% invalid operation exception. The cosine of \nan{} is itself.
+% Otherwise, the \texttt{trig} function reduces the argument to at
+% most half a right-angle and converts if necessary to radians. We
+% then call the same series as for sine, but using a positive
+% sign~|0| regardless of the sign of~$x$, and with an initial octant
+% of~$2$, because $\cos(x) = + \sin(\pi/2 + \lvert x\rvert)$.
+% \begin{macrocode}
+\cs_new:Npn \@@_cos_o:w #1 \s_@@ \@@_chk:w #2#3; @
+ {
+ \if_case:w #2 \exp_stop_f:
+ \@@_case_return_o:Nw \c_one_fp
+ \or: \@@_case_use:nw
+ {
+ \@@_trig:NNNNNwn #1 \@@_sin_series_o:NNwwww
+ \@@_ep_to_float_o:wwN 0 2
+ }
+ \or: \@@_case_use:nw
+ { \@@_invalid_operation_o:fw { #1 { cos } { cosd } } }
+ \else: \@@_case_return_same_o:w
+ \fi:
+ \s_@@ \@@_chk:w #2 #3;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_csc_o:w}
+% The cosecant of $\pm 0$ is $\pm \infty$ with the same sign, with a
+% division by zero exception (see \cs{@@_cot_zero_o:Nfw} defined
+% below), which requires the function name. The cosecant of
+% $\pm\infty$ raises an invalid operation exception. The cosecant of
+% \nan{} is itself. Otherwise, the \texttt{trig} function performs
+% the argument reduction, and converts if necessary to radians before
+% calling the same series as for sine, using the sign~|#3|, a starting
+% octant of~$0$, and inverting during the conversion from the fixed
+% point sine to the floating point result, because $\csc(x) = \#3
+% \big( \sin\lvert x\rvert\big)^{-1}$.
+% \begin{macrocode}
+\cs_new:Npn \@@_csc_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+ {
+ \if_case:w #2 \exp_stop_f:
+ \@@_cot_zero_o:Nfw #3 { #1 { csc } { cscd } }
+ \or: \@@_case_use:nw
+ {
+ \@@_trig:NNNNNwn #1 \@@_sin_series_o:NNwwww
+ \@@_ep_inv_to_float_o:wwN #3 0
+ }
+ \or: \@@_case_use:nw
+ { \@@_invalid_operation_o:fw { #1 { csc } { cscd } } }
+ \else: \@@_case_return_same_o:w
+ \fi:
+ \s_@@ \@@_chk:w #2 #3 #4;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_sec_o:w}
+% The secant of $\pm 0$ is $1$. The secant of $\pm \infty$ raises an
+% invalid operation exception. The secant of \nan{} is itself.
+% Otherwise, the \texttt{trig} function reduces the argument and turns
+% it to radians before calling the same series as for sine, using a
+% positive sign~$0$, a starting octant of~$2$, and inverting upon
+% conversion, because $\sec(x) = + 1 / \sin(\pi/2 + \lvert x\rvert)$.
+% \begin{macrocode}
+\cs_new:Npn \@@_sec_o:w #1 \s_@@ \@@_chk:w #2#3; @
+ {
+ \if_case:w #2 \exp_stop_f:
+ \@@_case_return_o:Nw \c_one_fp
+ \or: \@@_case_use:nw
+ {
+ \@@_trig:NNNNNwn #1 \@@_sin_series_o:NNwwww
+ \@@_ep_inv_to_float_o:wwN 0 2
+ }
+ \or: \@@_case_use:nw
+ { \@@_invalid_operation_o:fw { #1 { sec } { secd } } }
+ \else: \@@_case_return_same_o:w
+ \fi:
+ \s_@@ \@@_chk:w #2 #3;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_tan_o:w}
+% The tangent of $\pm 0$ or \nan{} is the same floating point number.
+% The tangent of $\pm\infty$ raises an invalid operation exception.
+% Once more, the \texttt{trig} function does the argument reduction
+% step and conversion to radians before calling
+% \cs{@@_tan_series_o:NNwwww}, with a sign~|#3| and an initial octant
+% of~$1$ (this shift is somewhat arbitrary). See \cs{@@_cot_o:w} for
+% an explanation of the $0$~argument.
+% \begin{macrocode}
+\cs_new:Npn \@@_tan_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+ {
+ \if_case:w #2 \exp_stop_f:
+ \@@_case_return_same_o:w
+ \or: \@@_case_use:nw
+ {
+ \@@_trig:NNNNNwn #1
+ \@@_tan_series_o:NNwwww 0 #3 1
+ }
+ \or: \@@_case_use:nw
+ { \@@_invalid_operation_o:fw { #1 { tan } { tand } } }
+ \else: \@@_case_return_same_o:w
+ \fi:
+ \s_@@ \@@_chk:w #2 #3 #4;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_cot_o:w}
+% \begin{macro}[EXP]{\@@_cot_zero_o:Nfw}
+% The cotangent of $\pm 0$ is $\pm \infty$ with the same sign, with a
+% division by zero exception (see \cs{@@_cot_zero_o:Nfw}. The
+% cotangent of $\pm\infty$ raises an invalid operation exception. The
+% cotangent of \nan{} is itself. We use $\cot x = - \tan (\pi/2 +
+% x)$, and the initial octant for the tangent was chosen to be $1$, so
+% the octant here starts at $3$. The change in sign is obtained by
+% feeding \cs{@@_tan_series_o:NNwwww} two signs rather than just the
+% sign of the argument: the first of those indicates whether we
+% compute tangent or cotangent. Those signs are eventually combined.
+% \begin{macrocode}
+\cs_new:Npn \@@_cot_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+ {
+ \if_case:w #2 \exp_stop_f:
+ \@@_cot_zero_o:Nfw #3 { #1 { cot } { cotd } }
+ \or: \@@_case_use:nw
+ {
+ \@@_trig:NNNNNwn #1
+ \@@_tan_series_o:NNwwww 2 #3 3
+ }
+ \or: \@@_case_use:nw
+ { \@@_invalid_operation_o:fw { #1 { cot } { cotd } } }
+ \else: \@@_case_return_same_o:w
+ \fi:
+ \s_@@ \@@_chk:w #2 #3 #4;
+ }
+\cs_new:Npn \@@_cot_zero_o:Nfw #1#2#3 \fi:
+ {
+ \fi:
+ \token_if_eq_meaning:NNTF 0 #1
+ { \exp_args:NNf \@@_division_by_zero_o:Nnw \c_inf_fp }
+ { \exp_args:NNf \@@_division_by_zero_o:Nnw \c_minus_inf_fp }
+ {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Distinguishing small and large arguments}
+%
+% \begin{macro}[EXP]{\@@_trig:NNNNNwn}
+% The first argument is \cs{use_i:nn} if the operand is in radians and
+% \cs{use_ii:nn} if it is in degrees. Arguments |#2| to~|#5| control
+% what trigonometric function we compute, and |#6| to~|#8| are pieces
+% of a normal floating point number. Call the \texttt{_series}
+% function~|#2|, with arguments |#3|, either a conversion function
+% (\cs{@@_ep_to_float_o:wN} or \cs{@@_ep_inv_to_float_o:wN}) or a sign $0$
+% or~$2$ when computing tangent or cotangent; |#4|, a sign $0$ or~$2$;
+% the octant, computed in an integer expression starting with~|#5| and
+% stopped by a period; and a fixed point number obtained from the
+% floating point number by argument reduction (if necessary) and
+% conversion to radians (if necessary). Any argument reduction
+% adjusts the octant accordingly by leaving a (positive) shift into
+% its integer expression. Let us explain the integer comparison. Two
+% of the four \cs{exp_after:wN} are expanded, the expansion hits the
+% test, which is true if the float is at least~$1$ when working in
+% radians, and at least $10$ when working in degrees. Then one of the
+% remaining \cs{exp_after:wN} hits |#1|, which picks the \texttt{trig}
+% or \texttt{trigd} function in whichever branch of the conditional
+% was taken. The final \cs{exp_after:wN} closes the conditional. At
+% the end of the day, a number is \texttt{large} if it is $\geq 1$ in
+% radians or $\geq 10$ in degrees, and \texttt{small} otherwise. All
+% four \texttt{trig}/\texttt{trigd} auxiliaries receive the operand as
+% an extended-precision number.
+% \begin{macrocode}
+\cs_new:Npn \@@_trig:NNNNNwn #1#2#3#4#5 \s_@@ \@@_chk:w 1#6#7#8;
+ {
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \exp_after:wN #4
+ \int_value:w \@@_int_eval:w #5
+ \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN
+ \if_int_compare:w #7 > #1 0 1 \exp_stop_f:
+ #1 \@@_trig_large:ww \@@_trigd_large:ww
+ \else:
+ #1 \@@_trig_small:ww \@@_trigd_small:ww
+ \fi:
+ #7,#8{0000}{0000};
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Small arguments}
+%
+% \begin{macro}[EXP]{\@@_trig_small:ww}
+% This receives a small extended-precision number in radians and
+% converts it to a fixed point number. Some trailing digits may be
+% lost in the conversion, so we keep the original floating point
+% number around: when computing sine or tangent (or their inverses),
+% the last step is to multiply by the floating point number (as
+% an extended-precision number) rather than the fixed point number.
+% The period serves to end the integer expression for the octant.
+% \begin{macrocode}
+\cs_new:Npn \@@_trig_small:ww #1,#2;
+ { \@@_ep_to_fixed:wwn #1,#2; . #1,#2; }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_trigd_small:ww}
+% Convert the extended-precision number to radians, then call
+% \cs{@@_trig_small:ww} to massage it in the form appropriate for the
+% \texttt{_series} auxiliary.
+% \begin{macrocode}
+\cs_new:Npn \@@_trigd_small:ww #1,#2;
+ {
+ \@@_ep_mul_raw:wwwwN
+ -1,{1745}{3292}{5199}{4329}{5769}{2369}; #1,#2;
+ \@@_trig_small:ww
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Argument reduction in degrees}
+%
+% \begin{macro}[rEXP]
+% {
+% \@@_trigd_large:ww, \@@_trigd_large_auxi:nnnnwNNNN,
+% \@@_trigd_large_auxii:wNw, \@@_trigd_large_auxiii:www
+% }
+% Note that $25\times 360 = 9000$, so $10^{k+1} \equiv 10^{k}
+% \pmod{360}$ for $k\geq 3$. When the exponent~|#1| is very large, we
+% can thus safely replace it by~$22$ (or even~$19$). We turn the
+% floating point number into a fixed point number with two blocks of
+% $8$~digits followed by five blocks of $4$~digits. The original
+% float is $100\times\meta{block_1}\cdots\meta{block_3}.
+% \meta{block_4}\cdots\meta{block_7}$, or is equal to it modulo~$360$
+% if the exponent~|#1| is very large. The first auxiliary finds
+% $\meta{block_1} + \meta{block_2} \pmod{9}$, a single digit, and
+% prepends it to the $4$~digits of \meta{block_3}. It also unpacks
+% \meta{block_4} and grabs the $4$~digits of \meta{block_7}. The
+% second auxiliary grabs the \meta{block_3} plus any contribution from
+% the first two blocks as~|#1|, the first digit of \meta{block_4}
+% (just after the decimal point in hundreds of degrees) as~|#2|, and
+% the three other digits as~|#3|. It finds the quotient and remainder
+% of |#1#2| modulo~$9$, adds twice the quotient to the integer
+% expression for the octant, and places the remainder (between $0$
+% and~$8$) before |#3| to form a new \meta{block_4}. The resulting
+% fixed point number is $x\in [0, 0.9]$. If $x\geq 0.45$, we add~$1$
+% to the octant and feed $0.9-x$ with an exponent of~$2$ (to
+% compensate the fact that we are working in units of hundreds of
+% degrees rather than degrees) to \cs{@@_trigd_small:ww}. Otherwise,
+% we feed it~$x$ with an exponent of~$2$. The third auxiliary also
+% discards digits which were not packed into the various
+% \meta{blocks}. Since the original exponent~|#1| is at least~$2$,
+% those are all~$0$ and no precision is lost (|#6| and~|#7| are
+% four~$0$ each).
+% \begin{macrocode}
+\cs_new:Npn \@@_trigd_large:ww #1, #2#3#4#5#6#7;
+ {
+ \exp_after:wN \@@_pack_eight:wNNNNNNNN
+ \exp_after:wN \@@_pack_eight:wNNNNNNNN
+ \exp_after:wN \@@_pack_twice_four:wNNNNNNNN
+ \exp_after:wN \@@_pack_twice_four:wNNNNNNNN
+ \exp_after:wN \@@_trigd_large_auxi:nnnnwNNNN
+ \exp_after:wN ;
+ \exp:w \exp_end_continue_f:w
+ \prg_replicate:nn { \int_max:nn { 22 - #1 } { 0 } } { 0 }
+ #2#3#4#5#6#7 0000 0000 0000 !
+ }
+\cs_new:Npn \@@_trigd_large_auxi:nnnnwNNNN #1#2#3#4#5; #6#7#8#9
+ {
+ \exp_after:wN \@@_trigd_large_auxii:wNw
+ \int_value:w \@@_int_eval:w #1 + #2
+ - (#1 + #2 - 4) / 9 * 9 \@@_int_eval_end:
+ #3;
+ #4; #5{#6#7#8#9};
+ }
+\cs_new:Npn \@@_trigd_large_auxii:wNw #1; #2#3;
+ {
+ + (#1#2 - 4) / 9 * 2
+ \exp_after:wN \@@_trigd_large_auxiii:www
+ \int_value:w \@@_int_eval:w #1#2
+ - (#1#2 - 4) / 9 * 9 \@@_int_eval_end: #3 ;
+ }
+\cs_new:Npn \@@_trigd_large_auxiii:www #1; #2; #3!
+ {
+ \if_int_compare:w #1 < 4500 \exp_stop_f:
+ \exp_after:wN \@@_use_i_until_s:nw
+ \exp_after:wN \@@_fixed_continue:wn
+ \else:
+ + 1
+ \fi:
+ \@@_fixed_sub:wwn {9000}{0000}{0000}{0000}{0000}{0000};
+ {#1}#2{0000}{0000};
+ { \@@_trigd_small:ww 2, }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Argument reduction in radians}
+%
+% Arguments greater or equal to~$1$ need to be reduced to a range where
+% we only need a few terms of the Taylor series. We reduce to the range
+% $[0,2\pi]$ by subtracting multiples of~$2\pi$, then to the smaller
+% range $[0,\pi/2]$ by subtracting multiples of~$\pi/2$ (keeping track
+% of how many times~$\pi/2$ is subtracted), then to $[0,\pi/4]$ by
+% mapping $x\to \pi/2 - x$ if appropriate. When the argument is very
+% large, say, $10^{100}$, an equally large multiple of~$2\pi$ must be
+% subtracted, hence we must work with a very good approximation
+% of~$2\pi$ in order to get a sensible remainder modulo~$2\pi$.
+%
+% Specifically, we multiply the argument by an approximation
+% of~$1/(2\pi)$ with $\ExplSyntaxOn\int_eval:n { \c__fp_max_exponent_int
+% + 48 }\ExplSyntaxOff$~digits, then discard the integer part of the
+% result, keeping $52$~digits of the fractional part. From the
+% fractional part of $x/(2\pi)$ we deduce the octant (quotient of the
+% first three digits by~$125$). We then multiply by $8$ or~$-8$ (the
+% latter when the octant is odd), ignore any integer part (related to
+% the octant), and convert the fractional part to an extended precision
+% number, before multiplying by~$\pi/4$ to convert back to a value in
+% radians in $[0,\pi/4]$.
+%
+% It is possible to prove that given the precision of floating points
+% and their range of exponents, the $52$~digits may start at most with
+% $24$~zeros. The $5$~last digits are affected by carries from
+% computations which are not done, hence we are left with at least $52 -
+% 24 - 5 = 23$ significant digits, enough to round correctly up to
+% $0.6\cdot\text{ulp}$ in all cases.
+%
+% \begin{variable}[EXP]{\c_@@_trig_intarray}
+% This integer array stores blocks of $8$~decimals of
+% $10^{-16}/(2\pi)$. Each entry is $10^8$ plus an $8$~digit number
+% storing $8$ decimals. In total we store $10112$~decimals of
+% $10^{-16}/(2\pi)$. The number of decimals we really need is the
+% maximum exponent plus the number of digits we later need,~$52$,
+% plus~$12$ ($4-1$~groups of $4$~digits). The memory footprint ($1/2$
+% byte per digit) is the same as an earlier method of storing the data
+% as a control sequence name, but the major advantage is that we can
+% unpack specific subsets of the digits without unpacking the $10112$
+% decimals.
+% \begin{macrocode}
+\intarray_const_from_clist:Nn \c_@@_trig_intarray
+ {
+ 100000000, 100000000, 115915494, 130918953, 135768883, 176337251,
+ 143620344, 159645740, 145644874, 176673440, 158896797, 163422653,
+ 150901138, 102766253, 108595607, 128427267, 157958036, 189291184,
+ 161145786, 152877967, 141073169, 198392292, 139966937, 140907757,
+ 130777463, 196925307, 168871739, 128962173, 197661693, 136239024,
+ 117236290, 111832380, 111422269, 197557159, 140461890, 108690267,
+ 139561204, 189410936, 193784408, 155287230, 199946443, 140024867,
+ 123477394, 159610898, 132309678, 130749061, 166986462, 180469944,
+ 186521878, 181574786, 156696424, 110389958, 174139348, 160998386,
+ 180991999, 162442875, 158517117, 188584311, 117518767, 116054654,
+ 175369880, 109739460, 136475933, 137680593, 102494496, 163530532,
+ 171567755, 103220324, 177781639, 171660229, 146748119, 159816584,
+ 106060168, 103035998, 113391198, 174988327, 186654435, 127975507,
+ 100162406, 177564388, 184957131, 108801221, 199376147, 168137776,
+ 147378906, 133068046, 145797848, 117613124, 127314069, 196077502,
+ 145002977, 159857089, 105690279, 167851315, 125210016, 131774602,
+ 109248116, 106240561, 145620314, 164840892, 148459191, 143521157,
+ 154075562, 100871526, 160680221, 171591407, 157474582, 172259774,
+ 162853998, 175155329, 139081398, 117724093, 158254797, 107332871,
+ 190406999, 175907657, 170784934, 170393589, 182808717, 134256403,
+ 166895116, 162545705, 194332763, 112686500, 126122717, 197115321,
+ 112599504, 138667945, 103762556, 108363171, 116952597, 158128224,
+ 194162333, 143145106, 112353687, 185631136, 136692167, 114206974,
+ 169601292, 150578336, 105311960, 185945098, 139556718, 170995474,
+ 165104316, 123815517, 158083944, 129799709, 199505254, 138756612,
+ 194458833, 106846050, 178529151, 151410404, 189298850, 163881607,
+ 176196993, 107341038, 199957869, 118905980, 193737772, 106187543,
+ 122271893, 101366255, 126123878, 103875388, 181106814, 106765434,
+ 108282785, 126933426, 179955607, 107903860, 160352738, 199624512,
+ 159957492, 176297023, 159409558, 143011648, 129641185, 157771240,
+ 157544494, 157021789, 176979240, 194903272, 194770216, 164960356,
+ 153181535, 144003840, 168987471, 176915887, 163190966, 150696440,
+ 147769706, 187683656, 177810477, 197954503, 153395758, 130188183,
+ 186879377, 166124814, 195305996, 155802190, 183598751, 103512712,
+ 190432315, 180498719, 168687775, 194656634, 162210342, 104440855,
+ 149785037, 192738694, 129353661, 193778292, 187359378, 143470323,
+ 102371458, 137923557, 111863634, 119294601, 183182291, 196416500,
+ 187830793, 131353497, 179099745, 186492902, 167450609, 189368909,
+ 145883050, 133703053, 180547312, 132158094, 131976760, 132283131,
+ 141898097, 149822438, 133517435, 169898475, 101039500, 168388003,
+ 197867235, 199608024, 100273901, 108749548, 154787923, 156826113,
+ 199489032, 168997427, 108349611, 149208289, 103776784, 174303550,
+ 145684560, 183671479, 130845672, 133270354, 185392556, 120208683,
+ 193240995, 162211753, 131839402, 109707935, 170774965, 149880868,
+ 160663609, 168661967, 103747454, 121028312, 119251846, 122483499,
+ 111611495, 166556037, 196967613, 199312829, 196077608, 127799010,
+ 107830360, 102338272, 198790854, 102387615, 157445430, 192601191,
+ 100543379, 198389046, 154921248, 129516070, 172853005, 122721023,
+ 160175233, 113173179, 175931105, 103281551, 109373913, 163964530,
+ 157926071, 180083617, 195487672, 146459804, 173977292, 144810920,
+ 109371257, 186918332, 189588628, 139904358, 168666639, 175673445,
+ 114095036, 137327191, 174311388, 106638307, 125923027, 159734506,
+ 105482127, 178037065, 133778303, 121709877, 134966568, 149080032,
+ 169885067, 141791464, 168350828, 116168533, 114336160, 173099514,
+ 198531198, 119733758, 144420984, 116559541, 152250643, 139431286,
+ 144403838, 183561508, 179771645, 101706470, 167518774, 156059160,
+ 187168578, 157939226, 123475633, 117111329, 198655941, 159689071,
+ 198506887, 144230057, 151919770, 156900382, 118392562, 120338742,
+ 135362568, 108354156, 151729710, 188117217, 195936832, 156488518,
+ 174997487, 108553116, 159830610, 113921445, 144601614, 188452770,
+ 125114110, 170248521, 173974510, 138667364, 103872860, 109967489,
+ 131735618, 112071174, 104788993, 168886556, 192307848, 150230570,
+ 157144063, 163863202, 136852010, 174100574, 185922811, 115721968,
+ 100397824, 175953001, 166958522, 112303464, 118773650, 143546764,
+ 164565659, 171901123, 108476709, 193097085, 191283646, 166919177,
+ 169387914, 133315566, 150669813, 121641521, 100895711, 172862384,
+ 126070678, 145176011, 113450800, 169947684, 122356989, 162488051,
+ 157759809, 153397080, 185475059, 175362656, 149034394, 145420581,
+ 178864356, 183042000, 131509559, 147434392, 152544850, 167491429,
+ 108647514, 142303321, 133245695, 111634945, 167753939, 142403609,
+ 105438335, 152829243, 142203494, 184366151, 146632286, 102477666,
+ 166049531, 140657343, 157553014, 109082798, 180914786, 169343492,
+ 127376026, 134997829, 195701816, 119643212, 133140475, 176289748,
+ 140828911, 174097478, 126378991, 181699939, 148749771, 151989818,
+ 172666294, 160183053, 195832752, 109236350, 168538892, 128468247,
+ 125997252, 183007668, 156937583, 165972291, 198244297, 147406163,
+ 181831139, 158306744, 134851692, 185973832, 137392662, 140243450,
+ 119978099, 140402189, 161348342, 173613676, 144991382, 171541660,
+ 163424829, 136374185, 106122610, 186132119, 198633462, 184709941,
+ 183994274, 129559156, 128333990, 148038211, 175011612, 111667205,
+ 119125793, 103552929, 124113440, 131161341, 112495318, 138592695,
+ 184904438, 146807849, 109739828, 108855297, 104515305, 139914009,
+ 188698840, 188365483, 166522246, 168624087, 125401404, 100911787,
+ 142122045, 123075334, 173972538, 114940388, 141905868, 142311594,
+ 163227443, 139066125, 116239310, 162831953, 123883392, 113153455,
+ 163815117, 152035108, 174595582, 101123754, 135976815, 153401874,
+ 107394340, 136339780, 138817210, 104531691, 182951948, 179591767,
+ 139541778, 179243527, 161740724, 160593916, 102732282, 187946819,
+ 136491289, 149714953, 143255272, 135916592, 198072479, 198580612,
+ 169007332, 118844526, 179433504, 155801952, 149256630, 162048766,
+ 116134365, 133992028, 175452085, 155344144, 109905129, 182727454,
+ 165911813, 122232840, 151166615, 165070983, 175574337, 129548631,
+ 120411217, 116380915, 160616116, 157320000, 183306114, 160618128,
+ 103262586, 195951602, 146321661, 138576614, 180471993, 127077713,
+ 116441201, 159496011, 106328305, 120759583, 148503050, 179095584,
+ 198298218, 167402898, 138551383, 123957020, 180763975, 150429225,
+ 198476470, 171016426, 197438450, 143091658, 164528360, 132493360,
+ 143546572, 137557916, 113663241, 120457809, 196971566, 134022158,
+ 180545794, 131328278, 100552461, 132088901, 187421210, 192448910,
+ 141005215, 149680971, 113720754, 100571096, 134066431, 135745439,
+ 191597694, 135788920, 179342561, 177830222, 137011486, 142492523,
+ 192487287, 113132021, 176673607, 156645598, 127260957, 141566023,
+ 143787436, 129132109, 174858971, 150713073, 191040726, 143541417,
+ 197057222, 165479803, 181512759, 157912400, 125344680, 148220261,
+ 173422990, 101020483, 106246303, 137964746, 178190501, 181183037,
+ 151538028, 179523433, 141955021, 135689770, 191290561, 143178787,
+ 192086205, 174499925, 178975690, 118492103, 124206471, 138519113,
+ 188147564, 102097605, 154895793, 178514140, 141453051, 151583964,
+ 128232654, 106020603, 131189158, 165702720, 186250269, 191639375,
+ 115278873, 160608114, 155694842, 110322407, 177272742, 116513642,
+ 134366992, 171634030, 194053074, 180652685, 109301658, 192136921,
+ 141431293, 171341061, 157153714, 106203978, 147618426, 150297807,
+ 186062669, 169960809, 118422347, 163350477, 146719017, 145045144,
+ 161663828, 146208240, 186735951, 102371302, 190444377, 194085350,
+ 134454426, 133413062, 163074595, 113830310, 122931469, 134466832,
+ 185176632, 182415152, 110179422, 164439571, 181217170, 121756492,
+ 119644493, 196532222, 118765848, 182445119, 109401340, 150443213,
+ 198586286, 121083179, 139396084, 143898019, 114787389, 177233102,
+ 186310131, 148695521, 126205182, 178063494, 157118662, 177825659,
+ 188310053, 151552316, 165984394, 109022180, 163144545, 121212978,
+ 197344714, 188741258, 126822386, 102360271, 109981191, 152056882,
+ 134723983, 158013366, 106837863, 128867928, 161973236, 172536066,
+ 185216856, 132011948, 197807339, 158419190, 166595838, 167852941,
+ 124187182, 117279875, 106103946, 106481958, 157456200, 160892122,
+ 184163943, 173846549, 158993202, 184812364, 133466119, 170732430,
+ 195458590, 173361878, 162906318, 150165106, 126757685, 112163575,
+ 188696307, 145199922, 100107766, 176830946, 198149756, 122682434,
+ 179367131, 108412102, 119520899, 148191244, 140487511, 171059184,
+ 141399078, 189455775, 118462161, 190415309, 134543802, 180893862,
+ 180732375, 178615267, 179711433, 123241969, 185780563, 176301808,
+ 184386640, 160717536, 183213626, 129671224, 126094285, 140110963,
+ 121826276, 151201170, 122552929, 128965559, 146082049, 138409069,
+ 107606920, 103954646, 119164002, 115673360, 117909631, 187289199,
+ 186343410, 186903200, 157966371, 103128612, 135698881, 176403642,
+ 152540837, 109810814, 183519031, 121318624, 172281810, 150845123,
+ 169019064, 166322359, 138872454, 163073727, 128087898, 130041018,
+ 194859136, 173742589, 141812405, 167291912, 138003306, 134499821,
+ 196315803, 186381054, 124578934, 150084553, 128031351, 118843410,
+ 107373060, 159565443, 173624887, 171292628, 198074235, 139074061,
+ 178690578, 144431052, 174262641, 176783005, 182214864, 162289361,
+ 192966929, 192033046, 169332843, 181580535, 164864073, 118444059,
+ 195496893, 153773183, 167266131, 130108623, 158802128, 180432893,
+ 144562140, 147978945, 142337360, 158506327, 104399819, 132635916,
+ 168734194, 136567839, 101281912, 120281622, 195003330, 112236091,
+ 185875592, 101959081, 122415367, 194990954, 148881099, 175891989,
+ 108115811, 163538891, 163394029, 123722049, 184837522, 142362091,
+ 100834097, 156679171, 100841679, 157022331, 178971071, 102928884,
+ 189701309, 195339954, 124415335, 106062584, 139214524, 133864640,
+ 134324406, 157317477, 155340540, 144810061, 177612569, 108474646,
+ 114329765, 143900008, 138265211, 145210162, 136643111, 197987319,
+ 102751191, 144121361, 169620456, 193602633, 161023559, 162140467,
+ 102901215, 167964187, 135746835, 187317233, 110047459, 163339773,
+ 124770449, 118885134, 141536376, 100915375, 164267438, 145016622,
+ 113937193, 106748706, 128815954, 164819775, 119220771, 102367432,
+ 189062690, 170911791, 194127762, 112245117, 123546771, 115640433,
+ 135772061, 166615646, 174474627, 130562291, 133320309, 153340551,
+ 138417181, 194605321, 150142632, 180008795, 151813296, 175497284,
+ 167018836, 157425342, 150169942, 131069156, 134310662, 160434122,
+ 105213831, 158797111, 150754540, 163290657, 102484886, 148697402,
+ 187203725, 198692811, 149360627, 140384233, 128749423, 132178578,
+ 177507355, 171857043, 178737969, 134023369, 102911446, 196144864,
+ 197697194, 134527467, 144296030, 189437192, 154052665, 188907106,
+ 162062575, 150993037, 199766583, 167936112, 181374511, 104971506,
+ 115378374, 135795558, 167972129, 135876446, 130937572, 103221320,
+ 124605656, 161129971, 131027586, 191128460, 143251843, 143269155,
+ 129284585, 173495971, 150425653, 199302112, 118494723, 121323805,
+ 116549802, 190991967, 168151180, 122483192, 151273721, 199792134,
+ 133106764, 121874844, 126215985, 112167639, 167793529, 182985195,
+ 185453921, 106957880, 158685312, 132775454, 133229161, 198905318,
+ 190537253, 191582222, 192325972, 178133427, 181825606, 148823337,
+ 160719681, 101448145, 131983362, 137910767, 112550175, 128826351,
+ 183649210, 135725874, 110356573, 189469487, 154446940, 118175923,
+ 106093708, 128146501, 185742532, 149692127, 164624247, 183221076,
+ 154737505, 168198834, 156410354, 158027261, 125228550, 131543250,
+ 139591848, 191898263, 104987591, 115406321, 103542638, 190012837,
+ 142615518, 178773183, 175862355, 117537850, 169565995, 170028011,
+ 158412588, 170150030, 117025916, 174630208, 142412449, 112839238,
+ 105257725, 114737141, 123102301, 172563968, 130555358, 132628403,
+ 183638157, 168682846, 143304568, 105994018, 170010719, 152092970,
+ 117799058, 132164175, 179868116, 158654714, 177489647, 116547948,
+ 183121404, 131836079, 184431405, 157311793, 149677763, 173989893,
+ 102277656, 107058530, 140837477, 152640947, 143507039, 152145247,
+ 101683884, 107090870, 161471944, 137225650, 128231458, 172995869,
+ 173831689, 171268519, 139042297, 111072135, 107569780, 137262545,
+ 181410950, 138270388, 198736451, 162848201, 180468288, 120582913,
+ 153390138, 135649144, 130040157, 106509887, 192671541, 174507066,
+ 186888783, 143805558, 135011967, 145862340, 180595327, 124727843,
+ 182925939, 157715840, 136885940, 198993925, 152416883, 178793572,
+ 179679516, 154076673, 192703125, 164187609, 162190243, 104699348,
+ 159891990, 160012977, 174692145, 132970421, 167781726, 115178506,
+ 153008552, 155999794, 102099694, 155431545, 127458567, 104403686,
+ 168042864, 184045128, 181182309, 179349696, 127218364, 192935516,
+ 120298724, 169583299, 148193297, 183358034, 159023227, 105261254,
+ 121144370, 184359584, 194433836, 138388317, 175184116, 108817112,
+ 151279233, 137457721, 193398208, 119005406, 132929377, 175306906,
+ 160741530, 149976826, 147124407, 176881724, 186734216, 185881509,
+ 191334220, 175930947, 117385515, 193408089, 157124410, 163472089,
+ 131949128, 180783576, 131158294, 100549708, 191802336, 165960770,
+ 170927599, 101052702, 181508688, 197828549, 143403726, 142729262,
+ 110348701, 139928688, 153550062, 106151434, 130786653, 196085995,
+ 100587149, 139141652, 106530207, 100852656, 124074703, 166073660,
+ 153338052, 163766757, 120188394, 197277047, 122215363, 138511354,
+ 183463624, 161985542, 159938719, 133367482, 104220974, 149956672,
+ 170250544, 164232439, 157506869, 159133019, 137469191, 142980999,
+ 134242305, 150172665, 121209241, 145596259, 160554427, 159095199,
+ 168243130, 184279693, 171132070, 121049823, 123819574, 171759855,
+ 119501864, 163094029, 175943631, 194450091, 191506160, 149228764,
+ 132319212, 197034460, 193584259, 126727638, 168143633, 109856853,
+ 127860243, 132141052, 133076065, 188414958, 158718197, 107124299,
+ 159592267, 181172796, 144388537, 196763139, 127431422, 179531145,
+ 100064922, 112650013, 132686230, 121550837,
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[rEXP]
+% {
+% \@@_trig_large:ww,
+% \@@_trig_large_auxi:w,
+% \@@_trig_large_auxii:w,
+% \@@_trig_large_auxiii:w,
+% }
+% The exponent~|#1| is between $1$ and~$\ExplSyntaxOn \int_use:N
+% \c__fp_max_exponent_int$. We wish to look up decimals
+% $10^{\text{\texttt{\#1}}-16}/(2\pi)$ starting from the digit
+% $|#1|+1$. Since they are stored in batches of~$8$, compute
+% $\lfloor|#1|/8\rfloor$ and fetch blocks of $8$ digits starting
+% there. The numbering of items in \cs{c_@@_trig_intarray} starts
+% at~$1$, so the block $\lfloor|#1|/8\rfloor+1$ contains the digit we
+% want, at one of the eight positions. Each call to \cs{int_value:w}
+% \cs{__kernel_intarray_item:Nn} expands the next, until being stopped
+% by \cs{@@_trig_large_auxiii:w} using \cs{exp_stop_f:}. Once all
+% these blocks are unpacked, the \cs{exp_stop_f:} and $0$ to $7$
+% digits are removed by \cs[no-index]{use_none:n\ldots{}n}.
+% Finally, \cs{@@_trig_large_auxii:w} packs $64$ digits (there are
+% between $65$ and $72$ at this point) into groups of~$4$ and the
+% \texttt{auxv} auxiliary is called.
+% \begin{macrocode}
+\cs_new:Npn \@@_trig_large:ww #1, #2#3#4#5#6;
+ {
+ \exp_after:wN \@@_trig_large_auxi:w
+ \int_value:w \@@_int_eval:w (#1 - 4) / 8 \exp_after:wN ,
+ \int_value:w #1 , ;
+ {#2}{#3}{#4}{#5} ;
+ }
+\cs_new:Npn \@@_trig_large_auxi:w #1, #2,
+ {
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_trig_large_auxii:w
+ \cs:w
+ use_none:n \prg_replicate:nn { #2 - #1 * 8 } { n }
+ \exp_after:wN
+ \cs_end:
+ \int_value:w
+ \__kernel_intarray_item:Nn \c_@@_trig_intarray
+ { \@@_int_eval:w #1 + 1 \scan_stop: }
+ \exp_after:wN \@@_trig_large_auxiii:w \int_value:w
+ \__kernel_intarray_item:Nn \c_@@_trig_intarray
+ { \@@_int_eval:w #1 + 2 \scan_stop: }
+ \exp_after:wN \@@_trig_large_auxiii:w \int_value:w
+ \__kernel_intarray_item:Nn \c_@@_trig_intarray
+ { \@@_int_eval:w #1 + 3 \scan_stop: }
+ \exp_after:wN \@@_trig_large_auxiii:w \int_value:w
+ \__kernel_intarray_item:Nn \c_@@_trig_intarray
+ { \@@_int_eval:w #1 + 4 \scan_stop: }
+ \exp_after:wN \@@_trig_large_auxiii:w \int_value:w
+ \__kernel_intarray_item:Nn \c_@@_trig_intarray
+ { \@@_int_eval:w #1 + 5 \scan_stop: }
+ \exp_after:wN \@@_trig_large_auxiii:w \int_value:w
+ \__kernel_intarray_item:Nn \c_@@_trig_intarray
+ { \@@_int_eval:w #1 + 6 \scan_stop: }
+ \exp_after:wN \@@_trig_large_auxiii:w \int_value:w
+ \__kernel_intarray_item:Nn \c_@@_trig_intarray
+ { \@@_int_eval:w #1 + 7 \scan_stop: }
+ \exp_after:wN \@@_trig_large_auxiii:w \int_value:w
+ \__kernel_intarray_item:Nn \c_@@_trig_intarray
+ { \@@_int_eval:w #1 + 8 \scan_stop: }
+ \exp_after:wN \@@_trig_large_auxiii:w \int_value:w
+ \__kernel_intarray_item:Nn \c_@@_trig_intarray
+ { \@@_int_eval:w #1 + 9 \scan_stop: }
+ \exp_stop_f:
+ }
+\cs_new:Npn \@@_trig_large_auxii:w
+ {
+ \@@_pack_twice_four:wNNNNNNNN \@@_pack_twice_four:wNNNNNNNN
+ \@@_pack_twice_four:wNNNNNNNN \@@_pack_twice_four:wNNNNNNNN
+ \@@_pack_twice_four:wNNNNNNNN \@@_pack_twice_four:wNNNNNNNN
+ \@@_pack_twice_four:wNNNNNNNN \@@_pack_twice_four:wNNNNNNNN
+ \@@_trig_large_auxv:www ;
+ }
+\cs_new:Npn \@@_trig_large_auxiii:w 1 { \exp_stop_f: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {
+% \@@_trig_large_auxv:www,
+% \@@_trig_large_auxvi:wnnnnnnnn,
+% \@@_trig_large_pack:NNNNNw
+% }
+% First come the first $64$~digits of the fractional part of
+% $10^{\text{\texttt{\#1}}-16}/(2\pi)$, arranged in $16$~blocks
+% of~$4$, and ending with a semicolon. Then a few more digits of the
+% same fractional part, ending with a semicolon, then $4$~blocks of
+% $4$~digits holding the significand of the original argument.
+% Multiply the $16$-digit significand with the $64$-digit fractional
+% part: the \texttt{auxvi} auxiliary receives the significand
+% as~|#2#3#4#5| and $16$~digits of the fractional part as~|#6#7#8#9|,
+% and computes one step of the usual ladder of \texttt{pack} functions
+% we use for multiplication (see \emph{e.g.,} \cs{@@_fixed_mul:wwn}),
+% then discards one block of the fractional part to set things up for
+% the next step of the ladder. We perform $13$~such steps, replacing
+% the last \texttt{middle} shift by the appropriate \texttt{trailing}
+% shift, then discard the significand and remaining $3$~blocks from
+% the fractional part, as there are not enough digits to compute any
+% more step in the ladder. The last semicolon closes the ladder, and
+% we return control to the \texttt{auxvii} auxiliary.
+% \begin{macrocode}
+\cs_new:Npn \@@_trig_large_auxv:www #1; #2; #3;
+ {
+ \exp_after:wN \@@_use_i_until_s:nw
+ \exp_after:wN \@@_trig_large_auxvii:w
+ \int_value:w \@@_int_eval:w \c_@@_leading_shift_int
+ \prg_replicate:nn { 13 }
+ { \@@_trig_large_auxvi:wnnnnnnnn }
+ + \c_@@_trailing_shift_int - \c_@@_middle_shift_int
+ \@@_use_i_until_s:nw
+ ; #3 #1 ; ;
+ }
+\cs_new:Npn \@@_trig_large_auxvi:wnnnnnnnn #1; #2#3#4#5#6#7#8#9
+ {
+ \exp_after:wN \@@_trig_large_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ + #2*#9 + #3*#8 + #4*#7 + #5*#6
+ #1; {#2}{#3}{#4}{#5} {#7}{#8}{#9}
+ }
+\cs_new:Npn \@@_trig_large_pack:NNNNNw #1#2#3#4#5#6;
+ { + #1#2#3#4#5 ; #6 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {
+% \@@_trig_large_auxvii:w,
+% \@@_trig_large_auxviii:w,
+% }
+% \begin{macro}[EXP]
+% {
+% \@@_trig_large_auxix:Nw,
+% \@@_trig_large_auxx:wNNNNN,
+% \@@_trig_large_auxxi:w
+% }
+% The \texttt{auxvii} auxiliary is followed by $52$~digits and a
+% semicolon. We find the octant as the integer part of $8$~times what
+% follows, or equivalently as the integer part of $|#1#2#3|/125$, and
+% add it to the surrounding integer expression for the octant. We
+% then compute $8$~times the $52$-digit number, with a minus sign if
+% the octant is odd. Again, the last \texttt{middle} shift is
+% converted to a \texttt{trailing} shift. Any integer part (including
+% negative values which come up when the octant is odd) is discarded
+% by \cs{@@_use_i_until_s:nw}. The resulting fractional part should
+% then be converted to radians by multiplying by~$2\pi/8$, but first,
+% build an extended precision number by abusing
+% \cs{@@_ep_to_ep_loop:N} with the appropriate trailing markers.
+% Finally, \cs{@@_trig_small:ww} sets up the argument for the
+% functions which compute the Taylor series.
+% \begin{macrocode}
+\cs_new:Npn \@@_trig_large_auxvii:w #1#2#3
+ {
+ \exp_after:wN \@@_trig_large_auxviii:ww
+ \int_value:w \@@_int_eval:w (#1#2#3 - 62) / 125 ;
+ #1#2#3
+ }
+\cs_new:Npn \@@_trig_large_auxviii:ww #1;
+ {
+ + #1
+ \if_int_odd:w #1 \exp_stop_f:
+ \exp_after:wN \@@_trig_large_auxix:Nw
+ \exp_after:wN -
+ \else:
+ \exp_after:wN \@@_trig_large_auxix:Nw
+ \exp_after:wN +
+ \fi:
+ }
+\cs_new:Npn \@@_trig_large_auxix:Nw
+ {
+ \exp_after:wN \@@_use_i_until_s:nw
+ \exp_after:wN \@@_trig_large_auxxi:w
+ \int_value:w \@@_int_eval:w \c_@@_leading_shift_int
+ \prg_replicate:nn { 13 }
+ { \@@_trig_large_auxx:wNNNNN }
+ + \c_@@_trailing_shift_int - \c_@@_middle_shift_int
+ ;
+ }
+\cs_new:Npn \@@_trig_large_auxx:wNNNNN #1; #2 #3#4#5#6
+ {
+ \exp_after:wN \@@_trig_large_pack:NNNNNw
+ \int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ #2 8 * #3#4#5#6
+ #1; #2
+ }
+\cs_new:Npn \@@_trig_large_auxxi:w #1;
+ {
+ \exp_after:wN \@@_ep_mul_raw:wwwwN
+ \int_value:w \@@_int_eval:w 0 \@@_ep_to_ep_loop:N #1 ; ; !
+ 0,{7853}{9816}{3397}{4483}{0961}{5661};
+ \@@_trig_small:ww
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Computing the power series}
+%
+% \begin{macro}[EXP]
+% {\@@_sin_series_o:NNwwww, \@@_sin_series_aux_o:NNnwww}
+% Here we receive a conversion function \cs{@@_ep_to_float_o:wwN} or
+% \cs{@@_ep_inv_to_float_o:wwN}, a \meta{sign} ($0$ or~$2$), a
+% (non-negative) \meta{octant} delimited by a dot, a \meta{fixed
+% point} number delimited by a semicolon, and an extended-precision
+% number. The auxiliary receives:
+% \begin{itemize}
+% \item the conversion function~|#1|;
+% \item the final sign, which depends on the octant~|#3| and the
+% sign~|#2|;
+% \item the octant~|#3|, which controls the series we use;
+% \item the square |#4 * #4| of the argument as a fixed point number,
+% computed with \cs{@@_fixed_mul:wwn};
+% \item the number itself as an extended-precision number.
+% \end{itemize}
+% If the octant is in $\{1,2,5,6,\ldots{}\}$, we are near an extremum
+% of the function and we use the series
+% \[
+% \cos(x) = 1 - x^2 \bigg( \frac{1}{2!} - x^2 \bigg( \frac{1}{4!}
+% - x^2 \bigg( \cdots \bigg) \bigg) \bigg) .
+% \]
+% Otherwise, the series
+% \[
+% \sin(x) = x \bigg( 1 - x^2 \bigg( \frac{1}{3!} - x^2 \bigg(
+% \frac{1}{5!} - x^2 \bigg( \cdots \bigg) \bigg) \bigg) \bigg)
+% \]
+% is used. Finally, the extended-precision number is converted to a
+% floating point number with the given sign, and \cs{@@_sanitize:Nw}
+% checks for overflow and underflow.
+% \begin{macrocode}
+\cs_new:Npn \@@_sin_series_o:NNwwww #1#2#3. #4;
+ {
+ \@@_fixed_mul:wwn #4; #4;
+ {
+ \exp_after:wN \@@_sin_series_aux_o:NNnwww
+ \exp_after:wN #1
+ \int_value:w
+ \if_int_odd:w \@@_int_eval:w (#3 + 2) / 4 \@@_int_eval_end:
+ #2
+ \else:
+ \if_meaning:w #2 0 2 \else: 0 \fi:
+ \fi:
+ {#3}
+ }
+ }
+\cs_new:Npn \@@_sin_series_aux_o:NNnwww #1#2#3 #4; #5,#6;
+ {
+ \if_int_odd:w \@@_int_eval:w #3 / 2 \@@_int_eval_end:
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ { % 1/18!
+ \@@_fixed_mul_sub_back:wwwn {0000}{0000}{0000}{0001}{5619}{2070};
+ #4;{0000}{0000}{0000}{0477}{9477}{3324};
+ \@@_fixed_mul_sub_back:wwwn #4;{0000}{0000}{0011}{4707}{4559}{7730};
+ \@@_fixed_mul_sub_back:wwwn #4;{0000}{0000}{2087}{6756}{9878}{6810};
+ \@@_fixed_mul_sub_back:wwwn #4;{0000}{0027}{5573}{1922}{3985}{8907};
+ \@@_fixed_mul_sub_back:wwwn #4;{0000}{2480}{1587}{3015}{8730}{1587};
+ \@@_fixed_mul_sub_back:wwwn #4;{0013}{8888}{8888}{8888}{8888}{8889};
+ \@@_fixed_mul_sub_back:wwwn #4;{0416}{6666}{6666}{6666}{6666}{6667};
+ \@@_fixed_mul_sub_back:wwwn #4;{5000}{0000}{0000}{0000}{0000}{0000};
+ \@@_fixed_mul_sub_back:wwwn#4;{10000}{0000}{0000}{0000}{0000}{0000};
+ { \@@_fixed_continue:wn 0, }
+ }
+ { % 1/17!
+ \@@_fixed_mul_sub_back:wwwn {0000}{0000}{0000}{0028}{1145}{7254};
+ #4;{0000}{0000}{0000}{7647}{1637}{3182};
+ \@@_fixed_mul_sub_back:wwwn #4;{0000}{0000}{0160}{5904}{3836}{8216};
+ \@@_fixed_mul_sub_back:wwwn #4;{0000}{0002}{5052}{1083}{8544}{1719};
+ \@@_fixed_mul_sub_back:wwwn #4;{0000}{0275}{5731}{9223}{9858}{9065};
+ \@@_fixed_mul_sub_back:wwwn #4;{0001}{9841}{2698}{4126}{9841}{2698};
+ \@@_fixed_mul_sub_back:wwwn #4;{0083}{3333}{3333}{3333}{3333}{3333};
+ \@@_fixed_mul_sub_back:wwwn #4;{1666}{6666}{6666}{6666}{6666}{6667};
+ \@@_fixed_mul_sub_back:wwwn#4;{10000}{0000}{0000}{0000}{0000}{0000};
+ { \@@_ep_mul:wwwwn 0, } #5,#6;
+ }
+ {
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN #2
+ \int_value:w \@@_int_eval:w #1
+ }
+ #2
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_tan_series_o:NNwwww, \@@_tan_series_aux_o:Nnwww}
+% Contrarily to \cs{@@_sin_series_o:NNwwww} which received a
+% conversion auxiliary as~|#1|, here, |#1| is $0$ for tangent
+% and $2$ for
+% cotangent. Consider first the case of the tangent. The octant |#3|
+% starts at $1$, which means that it is $1$ or $2$ for $\lvert
+% x\rvert\in[0,\pi/2]$, it is $3$ or $4$ for $\lvert
+% x\rvert\in[\pi/2,\pi]$, and so on: the intervals on which
+% $\tan\lvert x\rvert\geq 0$ coincide with those for which $\lfloor
+% (|#3| + 1) / 2\rfloor$ is odd. We also have to take into account
+% the original sign of $x$ to get the sign of the final result; it is
+% straightforward to check that the first \cs{int_value:w} expansion
+% produces $0$ for a positive final result, and $2$ otherwise. A
+% similar story holds for $\cot(x)$.
+%
+% The auxiliary receives the sign, the octant, the square of the
+% (reduced) input, and the (reduced) input (an extended-precision
+% number) as arguments. It then
+% computes the numerator and denominator of
+% \[
+% \tan(x) \simeq
+% \frac{x (1 - x^2 (a_1 - x^2 (a_2 - x^2 (a_3 - x^2 (a_4 - x^2 a_5)))))}
+% {1 - x^2 (b_1 - x^2 (b_2 - x^2 (b_3 - x^2 (b_4 - x^2 b_5))))} .
+% \]
+% The ratio is computed by \cs{@@_ep_div:wwwwn}, then converted to a
+% floating point number. For octants~|#3| (really, quadrants) next to
+% a pole of the
+% functions, the fixed point numerator and denominator are exchanged
+% before computing the ratio. Note that this \cs{if_int_odd:w} test
+% relies on the fact that the octant is at least~$1$.
+% \begin{macrocode}
+\cs_new:Npn \@@_tan_series_o:NNwwww #1#2#3. #4;
+ {
+ \@@_fixed_mul:wwn #4; #4;
+ {
+ \exp_after:wN \@@_tan_series_aux_o:Nnwww
+ \int_value:w
+ \if_int_odd:w \@@_int_eval:w #3 / 2 \@@_int_eval_end:
+ \exp_after:wN \reverse_if:N
+ \fi:
+ \if_meaning:w #1#2 2 \else: 0 \fi:
+ {#3}
+ }
+ }
+\cs_new:Npn \@@_tan_series_aux_o:Nnwww #1 #2 #3; #4,#5;
+ {
+ \@@_fixed_mul_sub_back:wwwn {0000}{0000}{1527}{3493}{0856}{7059};
+ #3; {0000}{0159}{6080}{0274}{5257}{6472};
+ \@@_fixed_mul_sub_back:wwwn #3; {0002}{4571}{2320}{0157}{2558}{8481};
+ \@@_fixed_mul_sub_back:wwwn #3; {0115}{5830}{7533}{5397}{3168}{2147};
+ \@@_fixed_mul_sub_back:wwwn #3; {1929}{8245}{6140}{3508}{7719}{2982};
+ \@@_fixed_mul_sub_back:wwwn #3;{10000}{0000}{0000}{0000}{0000}{0000};
+ { \@@_ep_mul:wwwwn 0, } #4,#5;
+ {
+ \@@_fixed_mul_sub_back:wwwn {0000}{0007}{0258}{0681}{9408}{4706};
+ #3;{0000}{2343}{7175}{1399}{6151}{7670};
+ \@@_fixed_mul_sub_back:wwwn #3;{0019}{2638}{4588}{9232}{8861}{3691};
+ \@@_fixed_mul_sub_back:wwwn #3;{0536}{6357}{0691}{4344}{6852}{4252};
+ \@@_fixed_mul_sub_back:wwwn #3;{5263}{1578}{9473}{6842}{1052}{6315};
+ \@@_fixed_mul_sub_back:wwwn#3;{10000}{0000}{0000}{0000}{0000}{0000};
+ {
+ \reverse_if:N \if_int_odd:w
+ \@@_int_eval:w (#2 - 1) / 2 \@@_int_eval_end:
+ \exp_after:wN \@@_reverse_args:Nww
+ \fi:
+ \@@_ep_div:wwwwn 0,
+ }
+ }
+ {
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN #1
+ \int_value:w \@@_int_eval:w \@@_ep_to_float_o:wwN
+ }
+ #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Inverse trigonometric functions}
+%
+% All inverse trigonometric functions (arcsine, arccosine, arctangent,
+% arccotangent, arccosecant, and arcsecant) are based on a function
+% often denoted \texttt{atan2}. This function is accessed directly by
+% feeding two arguments to arctangent, and is defined by \(\operatorname{atan}(y, x) =
+% \operatorname{atan}(y/x)\) for generic \(y\) and~\(x\). Its advantages over the
+% conventional arctangent is that it takes values in $[-\pi,\pi]$ rather
+% than $[-\pi/2,\pi/2]$, and that it is better behaved in boundary
+% cases. Other inverse trigonometric functions are expressed in terms
+% of \(\operatorname{atan}\) as
+% \begin{align}
+% \operatorname{acos} x & = \operatorname{atan}(\sqrt{1-x^2}, x) \\
+% \operatorname{asin} x & = \operatorname{atan}(x, \sqrt{1-x^2}) \\
+% \operatorname{asec} x & = \operatorname{atan}(\sqrt{x^2-1}, 1) \\
+% \operatorname{acsc} x & = \operatorname{atan}(1, \sqrt{x^2-1}) \\
+% \operatorname{atan} x & = \operatorname{atan}(x, 1) \\
+% \operatorname{acot} x & = \operatorname{atan}(1, x) .
+% \end{align}
+% Rather than introducing a new function, \texttt{atan2}, the arctangent
+% function \texttt{atan} is overloaded: it can take one or two
+% arguments. In the comments below, following many texts, we call the
+% first argument~$y$ and the second~$x$, because $\operatorname{atan}(y, x) = \operatorname{atan}(y
+% / x)$ is the angular coordinate of the point $(x, y)$.
+%
+% As for direct trigonometric functions, the first step in computing
+% $\operatorname{atan}(y, x)$ is argument reduction. The sign of~$y$ gives that
+% of the result. We distinguish eight regions where the point $(x,
+% \lvert y\rvert)$ can lie, of angular size roughly $\pi/8$,
+% characterized by their \enquote{octant}, between $0$ and~$7$ included. In
+% each region, we compute an arctangent as a Taylor series, then shift
+% this arctangent by the appropriate multiple of $\pi/4$ and sign to get
+% the result. Here is a list of octants, and how we compute the
+% arctangent (we assume $y>0$: otherwise replace $y$ by~$-y$ below):
+% \begin{itemize}
+% \item[0] $0 < \lvert y\rvert < 0.41421 x$, then
+% $\operatorname{atan}\frac{\lvert y\rvert}{x}$
+% is given by a nicely convergent Taylor series;
+% \item[1] $0 < 0.41421 x < \lvert y\rvert < x$, then
+% $\operatorname{atan}\frac{\lvert y\rvert}{x}
+% = \frac{\pi}{4}-\operatorname{atan}\frac{x-\lvert y\rvert}{x+\lvert y\rvert}$;
+% \item[2] $0 < 0.41421 \lvert y\rvert < x < \lvert y\rvert$, then
+% $\operatorname{atan}\frac{\lvert y\rvert}{x}
+% = \frac{\pi}{4}+\operatorname{atan}\frac{-x+\lvert y\rvert}{x+\lvert y\rvert}$;
+% \item[3] $0 < x < 0.41421 \lvert y\rvert$, then
+% $\operatorname{atan}\frac{\lvert y\rvert}{x}
+% = \frac{\pi}{2}-\operatorname{atan}\frac{x}{\lvert y\rvert}$;
+% \item[4] $0 < -x < 0.41421 \lvert y\rvert$, then
+% $\operatorname{atan}\frac{\lvert y\rvert}{x}
+% = \frac{\pi}{2}+\operatorname{atan}\frac{-x}{\lvert y\rvert}$;
+% \item[5] $0 < 0.41421 \lvert y\rvert < -x < \lvert y\rvert$, then
+% $\operatorname{atan}\frac{\lvert y\rvert}{x}
+% =\frac{3\pi}{4}-\operatorname{atan}\frac{x+\lvert y\rvert}{-x+\lvert y\rvert}$;
+% \item[6] $0 < -0.41421 x < \lvert y\rvert < -x$, then
+% $\operatorname{atan}\frac{\lvert y\rvert}{x}
+% =\frac{3\pi}{4}+\operatorname{atan}\frac{-x-\lvert y\rvert}{-x+\lvert y\rvert}$;
+% \item[7] $0 < \lvert y\rvert < -0.41421 x$, then
+% $\operatorname{atan}\frac{\lvert y\rvert}{x}
+% = \pi-\operatorname{atan}\frac{\lvert y\rvert}{-x}$.
+% \end{itemize}
+% In the following, we denote by~$z$ the ratio among
+% $\lvert\frac{y}{x}\rvert$, $\lvert\frac{x}{y}\rvert$,
+% $\lvert\frac{x+y}{x-y}\rvert$, $\lvert\frac{x-y}{x+y}\rvert$ which
+% appears in the right-hand side above.
+%
+% \subsubsection{Arctangent and arccotangent}
+%
+% \begin{macro}[EXP]{\@@_atan_o:Nw, \@@_acot_o:Nw, \@@_atan_default:w}
+% The parsing step manipulates \texttt{atan} and \texttt{acot} like
+% \texttt{min} and \texttt{max}, reading in an array of operands, but
+% also leaves \cs{use_i:nn} or \cs{use_ii:nn} depending on whether the
+% result should be given in radians or in degrees. The helper
+% \cs{@@_parse_function_one_two:nnw} checks that the operand is one or
+% two floating point numbers (not tuples) and leaves its second
+% argument or its tail accordingly (its first argument is used for
+% error messages). More precisely if we are given a single floating
+% point number \cs{@@_atan_default:w} places \cs{c_one_fp} (expanded)
+% after it; otherwise \cs{@@_atan_default:w} is omitted by
+% \cs{@@_parse_function_one_two:nnw}.
+% \begin{macrocode}
+\cs_new:Npn \@@_atan_o:Nw #1
+ {
+ \@@_parse_function_one_two:nnw
+ { #1 { atan } { atand } }
+ { \@@_atan_default:w \@@_atanii_o:Nww #1 }
+ }
+\cs_new:Npn \@@_acot_o:Nw #1
+ {
+ \@@_parse_function_one_two:nnw
+ { #1 { acot } { acotd } }
+ { \@@_atan_default:w \@@_acotii_o:Nww #1 }
+ }
+\cs_new:Npe \@@_atan_default:w #1#2#3 @ { #1 #2 #3 \c_one_fp @ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_atanii_o:Nww, \@@_acotii_o:Nww}
+% If either operand is \texttt{nan}, we return it. If both are
+% normal, we call \cs{@@_atan_normal_o:NNnwNnw}. If both are zero or
+% both infinity, we call \cs{@@_atan_inf_o:NNNw} with argument~$2$,
+% leading to a result among $\{\pm\pi/4, \pm 3\pi/4\}$ (in degrees,
+% $\{\pm 45, \pm 135\}$). Otherwise, one is much bigger than the
+% other, and we call \cs{@@_atan_inf_o:NNNw} with either an argument
+% of~$4$, leading to the values $\pm\pi/2$ (in degrees,~$\pm 90$),
+% or~$0$, leading to $\{\pm 0, \pm\pi\}$ (in degrees, $\{\pm 0,\pm
+% 180\}$). Since $\operatorname{acot}(x, y) = \operatorname{atan}(y, x)$,
+% \cs{@@_acotii_o:ww} simply reverses its two arguments.
+% \begin{macrocode}
+\cs_new:Npn \@@_atanii_o:Nww
+ #1 \s_@@ \@@_chk:w #2#3#4; \s_@@ \@@_chk:w #5 #6 @
+ {
+ \if_meaning:w 3 #2 \@@_case_return_i_o:ww \fi:
+ \if_meaning:w 3 #5 \@@_case_return_ii_o:ww \fi:
+ \if_case:w
+ \if_meaning:w #2 #5
+ \if_meaning:w 1 #2 10 \else: 0 \fi:
+ \else:
+ \if_int_compare:w #2 > #5 \exp_stop_f: 1 \else: 2 \fi:
+ \fi:
+ \exp_stop_f:
+ \@@_case_return:nw { \@@_atan_inf_o:NNNw #1 #3 2 }
+ \or: \@@_case_return:nw { \@@_atan_inf_o:NNNw #1 #3 4 }
+ \or: \@@_case_return:nw { \@@_atan_inf_o:NNNw #1 #3 0 }
+ \fi:
+ \@@_atan_normal_o:NNnwNnw #1
+ \s_@@ \@@_chk:w #2#3#4;
+ \s_@@ \@@_chk:w #5 #6
+ }
+\cs_new:Npn \@@_acotii_o:Nww #1#2; #3;
+ { \@@_atanii_o:Nww #1#3; #2; }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_atan_inf_o:NNNw}
+% This auxiliary is called whenever one number is $\pm 0$ or
+% $\pm\infty$ (and neither is \nan{}). Then the result only depends
+% on the signs, and its value is a multiple of $\pi/4$. We use the
+% same auxiliary as for normal numbers,
+% \cs{@@_atan_combine_o:NwwwwwN}, with arguments the final sign~|#2|;
+% the octant~|#3|; $\operatorname{atan} z/z=1$ as a fixed point number; $z=0$~as a
+% fixed point number; and $z=0$~as an extended-precision number.
+% Given the values we provide, $\operatorname{atan} z$ is computed to be~$0$,
+% and the result is $[|#3|/2]\cdot\pi/4$ if the sign~|#5| of~$x$
+% is positive, and $[(7-|#3|)/2]\cdot\pi/4$ for negative~$x$, where
+% the divisions are rounded up.
+% \begin{macrocode}
+\cs_new:Npn \@@_atan_inf_o:NNNw #1#2#3 \s_@@ \@@_chk:w #4#5#6;
+ {
+ \exp_after:wN \@@_atan_combine_o:NwwwwwN
+ \exp_after:wN #2
+ \int_value:w \@@_int_eval:w
+ \if_meaning:w 2 #5 7 - \fi: #3 \exp_after:wN ;
+ \c_@@_one_fixed_tl
+ {0000}{0000}{0000}{0000}{0000}{0000};
+ 0,{0000}{0000}{0000}{0000}{0000}{0000}; #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_atan_normal_o:NNnwNnw}
+% Here we simply reorder the floating point data into a pair of signed
+% extended-precision numbers, that is, a sign, an exponent ending with
+% a comma, and a six-block mantissa ending with a semi-colon. This
+% extended precision is required by other inverse trigonometric
+% functions, to compute things like $\operatorname{atan}(x,\sqrt{1-x^2})$ without
+% intermediate rounding errors.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_atan_normal_o:NNnwNnw
+ #1 \s_@@ \@@_chk:w 1#2#3#4; \s_@@ \@@_chk:w 1#5#6#7;
+ {
+ \@@_atan_test_o:NwwNwwN
+ #2 #3, #4{0000}{0000};
+ #5 #6, #7{0000}{0000}; #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_atan_test_o:NwwNwwN}
+% This receives: the sign~|#1| of~$y$, its exponent~|#2|, its $24$
+% digits~|#3| in groups of~$4$, and similarly for~$x$. We prepare to
+% call \cs{@@_atan_combine_o:NwwwwwN} which expects the sign~|#1|, the
+% octant, the ratio $(\operatorname{atan} z)/z = 1 - \cdots$, and the value of~$z$,
+% both as a fixed point number and as an extended-precision floating
+% point number with a mantissa in $[0.01,1)$. For now, we place |#1|
+% as a first argument, and start an integer expression for the octant.
+% The sign of $x$ does not affect~$z$, so we simply leave
+% a contribution to the octant: $\meta{octant} \to 7 - \meta{octant}$
+% for negative~$x$. Then we order $\lvert y\rvert$ and $\lvert
+% x\rvert$ in a non-decreasing order: if $\lvert y\rvert > \lvert
+% x\rvert$, insert $3-$ in the expression for the octant, and swap the
+% two numbers. The finer test with $0.41421$ is done by
+% \cs{@@_atan_div:wnwwnw} after the operands have been ordered.
+% \begin{macrocode}
+\cs_new:Npn \@@_atan_test_o:NwwNwwN #1#2,#3; #4#5,#6;
+ {
+ \exp_after:wN \@@_atan_combine_o:NwwwwwN
+ \exp_after:wN #1
+ \int_value:w \@@_int_eval:w
+ \if_meaning:w 2 #4
+ 7 - \@@_int_eval:w
+ \fi:
+ \if_int_compare:w
+ \@@_ep_compare:wwww #2,#3; #5,#6; > \c_zero_int
+ 3 -
+ \exp_after:wN \@@_reverse_args:Nww
+ \fi:
+ \@@_atan_div:wnwwnw #2,#3; #5,#6;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_atan_div:wnwwnw, \@@_atan_near:wwwn}
+% \begin{macro}[EXP]{\@@_atan_near_aux:wwn}
+% This receives two positive numbers $a$ and~$b$ (equal to $\lvert
+% x\rvert$ and~$\lvert y\rvert$ in some order), each as an exponent
+% and $6$~blocks of $4$~digits, such that $0<a<b$. If $0.41421b<a$,
+% the two numbers are \enquote{near}, hence the point $(y,x)$ that we
+% started with is closer to the diagonals $\{\lvert y\rvert = \lvert
+% x\rvert\}$ than to the axes $\{xy = 0\}$. In that case, the octant
+% is~$1$ (possibly combined with the $7-$ and $3-$ inserted earlier)
+% and we wish to compute $\operatorname{atan}\frac{b-a}{a+b}$. Otherwise, the
+% octant is~$0$ (again, combined with earlier terms) and we wish to
+% compute $\operatorname{atan}\frac{a}{b}$. In any case, call \cs{@@_atan_auxi:ww}
+% followed by~$z$, as a comma-delimited exponent and a fixed point
+% number.
+% \begin{macrocode}
+\cs_new:Npn \@@_atan_div:wnwwnw #1,#2#3; #4,#5#6;
+ {
+ \if_int_compare:w
+ \@@_int_eval:w 41421 * #5 < #2 000
+ \if_case:w \@@_int_eval:w #4 - #1 \@@_int_eval_end:
+ 00 \or: 0 \fi:
+ \exp_stop_f:
+ \exp_after:wN \@@_atan_near:wwwn
+ \fi:
+ 0
+ \@@_ep_div:wwwwn #1,{#2}#3; #4,{#5}#6;
+ \@@_atan_auxi:ww
+ }
+\cs_new:Npn \@@_atan_near:wwwn
+ 0 \@@_ep_div:wwwwn #1,#2; #3,
+ {
+ 1
+ \@@_ep_to_fixed:wwn #1 - #3, #2;
+ \@@_atan_near_aux:wwn
+ }
+\cs_new:Npn \@@_atan_near_aux:wwn #1; #2;
+ {
+ \@@_fixed_add:wwn #1; #2;
+ { \@@_fixed_sub:wwn #2; #1; { \@@_ep_div:wwwwn 0, } 0, }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_atan_auxi:ww, \@@_atan_auxii:w}
+% Convert~$z$ from a representation as an exponent and a fixed point
+% number in $[0.01,1)$ to a fixed point number only, then set up the
+% call to \cs{@@_atan_Taylor_loop:www}, followed by the fixed point
+% representation of~$z$ and the old representation.
+% \begin{macrocode}
+\cs_new:Npn \@@_atan_auxi:ww #1,#2;
+ { \@@_ep_to_fixed:wwn #1,#2; \@@_atan_auxii:w #1,#2; }
+\cs_new:Npn \@@_atan_auxii:w #1;
+ {
+ \@@_fixed_mul:wwn #1; #1;
+ {
+ \@@_atan_Taylor_loop:www 39 ;
+ {0000}{0000}{0000}{0000}{0000}{0000} ;
+ }
+ ! #1;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_atan_Taylor_loop:www, \@@_atan_Taylor_break:w}
+% We compute the series of $(\operatorname{atan} z)/z$. A typical intermediate
+% stage has $|#1|=2k-1$, $|#2| =
+% \frac{1}{2k+1}-z^2(\frac{1}{2k+3}-z^2(\cdots-z^2\frac{1}{39}))$, and
+% $|#3|=z^2$. To go to the next step $k\to k-1$, we compute
+% $\frac{1}{2k-1}$, then subtract from it $z^2$ times |#2|. The loop
+% stops when $k=0$: then |#2| is $(\operatorname{atan} z)/z$, and there is a need to
+% clean up all the unnecessary data, end the integer expression
+% computing the octant with a semicolon, and leave the result~|#2|
+% afterwards.
+% \begin{macrocode}
+\cs_new:Npn \@@_atan_Taylor_loop:www #1; #2; #3;
+ {
+ \if_int_compare:w #1 = - \c_one_int
+ \@@_atan_Taylor_break:w
+ \fi:
+ \exp_after:wN \@@_fixed_div_int:wwN \c_@@_one_fixed_tl #1;
+ \@@_rrot:www \@@_fixed_mul_sub_back:wwwn #2; #3;
+ {
+ \exp_after:wN \@@_atan_Taylor_loop:www
+ \int_value:w \@@_int_eval:w #1 - 2 ;
+ }
+ #3;
+ }
+\cs_new:Npn \@@_atan_Taylor_break:w
+ \fi: #1 \@@_fixed_mul_sub_back:wwwn #2; #3 !
+ { \fi: ; #2 ; }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_atan_combine_o:NwwwwwN, \@@_atan_combine_aux:ww}
+% This receives a \meta{sign}, an \meta{octant}, a fixed point value
+% of $(\operatorname{atan} z)/z$, a fixed point number~$z$, and another
+% representation of~$z$, as an \meta{exponent} and the fixed point
+% number $10^{-\meta{exponent}} z$, followed by either \cs{use_i:nn}
+% (when working in radians) or \cs{use_ii:nn} (when working in
+% degrees). The function computes the floating point result
+% \begin{equation}
+% \meta{sign} \left(
+% \left\lceil\frac{\meta{octant}}{2}\right\rceil
+% \frac{\pi}{4}
+% + (-1)^{\meta{octant}} \frac{\operatorname{atan} z}{z} \cdot z\right) \,,
+% \end{equation}
+% multiplied by $180/\pi$ if working in degrees, and using in any case
+% the most appropriate representation of~$z$. The floating point
+% result is passed to \cs{@@_sanitize:Nw}, which checks for overflow
+% or underflow. If the octant is~$0$, leave the exponent~|#5| for
+% \cs{@@_sanitize:Nw}, and multiply $|#3|=\frac{\operatorname{atan} z}{z}$
+% with~|#6|, the adjusted~$z$. Otherwise, multiply $|#3|=\frac{\operatorname{atan}
+% z}{z}$ with $|#4|=z$, then compute the appropriate multiple of
+% $\frac{\pi}{4}$ and add or subtract the product $|#3|\cdot|#4|$. In
+% both cases, convert to a floating point with
+% \cs{@@_fixed_to_float_o:wN}.
+% \begin{macrocode}
+\cs_new:Npn \@@_atan_combine_o:NwwwwwN #1 #2; #3; #4; #5,#6; #7
+ {
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN #1
+ \int_value:w \@@_int_eval:w
+ \if_meaning:w 0 #2
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ { #5 \@@_fixed_mul:wwn #3; #6; }
+ {
+ \@@_fixed_mul:wwn #3; #4;
+ {
+ \exp_after:wN \@@_atan_combine_aux:ww
+ \int_value:w \@@_int_eval:w #2 / 2 ; #2;
+ }
+ }
+ { #7 \@@_fixed_to_float_o:wN \@@_fixed_to_float_rad_o:wN }
+ #1
+ }
+\cs_new:Npn \@@_atan_combine_aux:ww #1; #2;
+ {
+ \@@_fixed_mul_short:wwn
+ {7853}{9816}{3397}{4483}{0961}{5661};
+ {#1}{0000}{0000};
+ {
+ \if_int_odd:w #2 \exp_stop_f:
+ \exp_after:wN \@@_fixed_sub:wwn
+ \else:
+ \exp_after:wN \@@_fixed_add:wwn
+ \fi:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Arcsine and arccosine}
+%
+% \begin{macro}[EXP]{\@@_asin_o:w}
+% Again, the first argument provided by \pkg{l3fp-parse} is
+% \cs{use_i:nn} if we are to work in radians and \cs{use_ii:nn} for
+% degrees. Then comes a floating point number. The arcsine of $\pm
+% 0$ or \nan{} is the same floating point number. The arcsine of
+% $\pm\infty$ raises an invalid operation exception. Otherwise, call
+% an auxiliary common with \cs{@@_acos_o:w}, feeding it information
+% about what function is being performed (for \enquote{invalid operation}
+% exceptions).
+% \begin{macrocode}
+\cs_new:Npn \@@_asin_o:w #1 \s_@@ \@@_chk:w #2#3; @
+ {
+ \if_case:w #2 \exp_stop_f:
+ \@@_case_return_same_o:w
+ \or:
+ \@@_case_use:nw
+ { \@@_asin_normal_o:NfwNnnnnw #1 { #1 { asin } { asind } } }
+ \or:
+ \@@_case_use:nw
+ { \@@_invalid_operation_o:fw { #1 { asin } { asind } } }
+ \else:
+ \@@_case_return_same_o:w
+ \fi:
+ \s_@@ \@@_chk:w #2 #3;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_acos_o:w}
+% The arccosine of $\pm 0$ is $\pi / 2$ (in degrees,~$90$). The
+% arccosine of $\pm\infty$ raises an invalid operation exception. The
+% arccosine of \nan{} is itself. Otherwise, call an auxiliary common
+% with \cs{@@_sin_o:w}, informing it that it was called by
+% \texttt{acos} or \texttt{acosd}, and preparing to swap some
+% arguments down the line.
+% \begin{macrocode}
+\cs_new:Npn \@@_acos_o:w #1 \s_@@ \@@_chk:w #2#3; @
+ {
+ \if_case:w #2 \exp_stop_f:
+ \@@_case_use:nw { \@@_atan_inf_o:NNNw #1 0 4 }
+ \or:
+ \@@_case_use:nw
+ {
+ \@@_asin_normal_o:NfwNnnnnw #1 { #1 { acos } { acosd } }
+ \@@_reverse_args:Nww
+ }
+ \or:
+ \@@_case_use:nw
+ { \@@_invalid_operation_o:fw { #1 { acos } { acosd } } }
+ \else:
+ \@@_case_return_same_o:w
+ \fi:
+ \s_@@ \@@_chk:w #2 #3;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_asin_normal_o:NfwNnnnnw}
+% If the exponent~|#5| is at most $0$, the operand lies
+% within $(-1,1)$ and the operation is permitted: call
+% \cs{@@_asin_auxi_o:NnNww} with the appropriate arguments. If the
+% number is exactly~$\pm 1$ (the test works because we know that
+% $|#5|\geq 1$, $|#6#7|\geq 10000000$, $|#8#9|\geq 0$, with equality
+% only for $\pm 1$), we also call \cs{@@_asin_auxi_o:NnNww}.
+% Otherwise, \cs{@@_use_i:ww} gets rid of the \texttt{asin} auxiliary,
+% and raises instead an invalid operation, because the operand is
+% outside the domain of arcsine or arccosine.
+% \begin{macrocode}
+\cs_new:Npn \@@_asin_normal_o:NfwNnnnnw
+ #1#2#3 \s_@@ \@@_chk:w 1#4#5#6#7#8#9;
+ {
+ \if_int_compare:w #5 < \c_one_int
+ \exp_after:wN \@@_use_none_until_s:w
+ \fi:
+ \if_int_compare:w \@@_int_eval:w #5 + #6#7 + #8#9 = 1000 0001 ~
+ \exp_after:wN \@@_use_none_until_s:w
+ \fi:
+ \@@_use_i:ww
+ \@@_invalid_operation_o:fw {#2}
+ \s_@@ \@@_chk:w 1#4{#5}{#6}{#7}{#8}{#9};
+ \@@_asin_auxi_o:NnNww
+ #1 {#3} #4 #5,{#6}{#7}{#8}{#9}{0000}{0000};
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_asin_auxi_o:NnNww, \@@_asin_isqrt:wn}
+% We compute $x/\sqrt{1-x^2}$. This function is used by \texttt{asin}
+% and \texttt{acos}, but also by \texttt{acsc} and \texttt{asec} after
+% inverting the operand, thus it must manipulate extended-precision
+% numbers. First evaluate $1-x^2$ as $(1+x)(1-x)$: this behaves
+% better near~$x=1$. We do the addition/subtraction with fixed point
+% numbers (they are not implemented for extended-precision floats),
+% but go back to extended-precision floats to multiply and compute the
+% inverse square root $1/\sqrt{1-x^2}$. Finally, multiply by the
+% (positive) extended-precision float $\lvert x\rvert$, and feed the
+% (signed) result, and the number~$+1$, as arguments to the arctangent
+% function. When computing the arccosine, the arguments
+% $x/\sqrt{1-x^2}$ and~$+1$ are swapped by~|#2|
+% (\cs{@@_reverse_args:Nww} in that case) before
+% \cs{@@_atan_test_o:NwwNwwN} is evaluated. Note that the arctangent
+% function requires normalized arguments, hence the need for
+% \texttt{ep_to_ep} and \texttt{continue} after \texttt{ep_mul}.
+% \begin{macrocode}
+\cs_new:Npn \@@_asin_auxi_o:NnNww #1#2#3#4,#5;
+ {
+ \@@_ep_to_fixed:wwn #4,#5;
+ \@@_asin_isqrt:wn
+ \@@_ep_mul:wwwwn #4,#5;
+ \@@_ep_to_ep:wwN
+ \@@_fixed_continue:wn
+ { #2 \@@_atan_test_o:NwwNwwN #3 }
+ 0 1,{1000}{0000}{0000}{0000}{0000}{0000}; #1
+ }
+\cs_new:Npn \@@_asin_isqrt:wn #1;
+ {
+ \exp_after:wN \@@_fixed_sub:wwn \c_@@_one_fixed_tl #1;
+ {
+ \@@_fixed_add_one:wN #1;
+ \@@_fixed_continue:wn { \@@_ep_mul:wwwwn 0, } 0,
+ }
+ \@@_ep_isqrt:wwn
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Arccosecant and arcsecant}
+%
+% \begin{macro}[EXP]{\@@_acsc_o:w}
+% Cases are mostly labelled by~|#2|, except when |#2| is~$2$: then we
+% use |#3#2|, which is $02=2$ when the number is $+\infty$ and
+% $22$~when the number is $-\infty$. The arccosecant of $\pm 0$
+% raises an invalid operation exception. The arccosecant of
+% $\pm\infty$ is $\pm 0$ with the same sign. The arcosecant of \nan{}
+% is itself. Otherwise, \cs{@@_acsc_normal_o:NfwNnw} does some more
+% tests, keeping the function name (\texttt{acsc} or \texttt{acscd})
+% as an argument for invalid operation exceptions.
+% \begin{macrocode}
+\cs_new:Npn \@@_acsc_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+ {
+ \if_case:w \if_meaning:w 2 #2 #3 \fi: #2 \exp_stop_f:
+ \@@_case_use:nw
+ { \@@_invalid_operation_o:fw { #1 { acsc } { acscd } } }
+ \or: \@@_case_use:nw
+ { \@@_acsc_normal_o:NfwNnw #1 { #1 { acsc } { acscd } } }
+ \or: \@@_case_return_o:Nw \c_zero_fp
+ \or: \@@_case_return_same_o:w
+ \else: \@@_case_return_o:Nw \c_minus_zero_fp
+ \fi:
+ \s_@@ \@@_chk:w #2 #3 #4;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_asec_o:w}
+% The arcsecant of $\pm 0$ raises an invalid operation exception. The
+% arcsecant of $\pm\infty$ is $\pi / 2$ (in degrees,~$90$). The
+% arcosecant of \nan{} is itself. Otherwise, do some more tests,
+% keeping the function name \texttt{asec} (or \texttt{asecd}) as an
+% argument for invalid operation exceptions, and a
+% \cs{@@_reverse_args:Nww} following precisely that appearing in
+% \cs{@@_acos_o:w}.
+% \begin{macrocode}
+\cs_new:Npn \@@_asec_o:w #1 \s_@@ \@@_chk:w #2#3; @
+ {
+ \if_case:w #2 \exp_stop_f:
+ \@@_case_use:nw
+ { \@@_invalid_operation_o:fw { #1 { asec } { asecd } } }
+ \or:
+ \@@_case_use:nw
+ {
+ \@@_acsc_normal_o:NfwNnw #1 { #1 { asec } { asecd } }
+ \@@_reverse_args:Nww
+ }
+ \or: \@@_case_use:nw { \@@_atan_inf_o:NNNw #1 0 4 }
+ \else: \@@_case_return_same_o:w
+ \fi:
+ \s_@@ \@@_chk:w #2 #3;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_acsc_normal_o:NfwNnw}
+% If the exponent is non-positive, the operand is less than~$1$ in
+% absolute value, which is always an invalid operation: complain.
+% Otherwise, compute the inverse of the operand, and feed it to
+% \cs{@@_asin_auxi_o:NnNww} (with all the appropriate arguments). This
+% computes what we want thanks to
+% $\operatorname{acsc}(x)=\operatorname{asin}(1/x)$ and
+% $\operatorname{asec}(x)=\operatorname{acos}(1/x)$.
+% \begin{macrocode}
+\cs_new:Npn \@@_acsc_normal_o:NfwNnw #1#2#3 \s_@@ \@@_chk:w 1#4#5#6;
+ {
+ \int_compare:nNnTF {#5} < 1
+ {
+ \@@_invalid_operation_o:fw {#2}
+ \s_@@ \@@_chk:w 1#4{#5}#6;
+ }
+ {
+ \@@_ep_div:wwwwn
+ 1,{1000}{0000}{0000}{0000}{0000}{0000};
+ #5,#6{0000}{0000};
+ { \@@_asin_auxi_o:NnNww #1 {#3} #4 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintChanges
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp-types.dtx b/macros/latex-dev/required/l3kernel/l3fp-types.dtx
new file mode 100644
index 0000000000..2c23c61393
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp-types.dtx
@@ -0,0 +1,184 @@
+% \iffalse
+%
+%% File l3fp-types.dtx (C) Copyright 2012-2015,2017,2018,2020,2021,2023 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full]{l3doc}
+\usepackage{amsmath}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp-types} module\\ Floating point types^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp-types} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% \subsection{Support for types}
+%
+% Despite lack of documentation, the \pkg{l3fp} internals support types.
+% Each additional type must define
+% \begin{itemize}
+% \item |\s__fp_|\meta{type} and |\__fp_|\meta{type}|_chk:w|;
+% \item |\__fp_exp_after_|\meta{type}|_f:nw|;
+% \item |\__fp_|\meta{type}|_to_|\meta{out}|:w| for \meta{out} among
+% |decimal|, |scientific|, |tl|;
+% \end{itemize}
+% and may define
+% \begin{itemize}
+% \item |\__fp_|\meta{type}|_to_int:w| and |\__fp_|\meta{type}|_to_dim:w|;
+% \item |\__fp_|\meta{op}|_|\meta{type}|_o:w| for any of the \meta{op}
+% that the type implements, among |acos|, |acsc|, |asec|, |asin|,
+% |cos|, |cot|, |csc|, |exp|, |ln|, |not|, |sec|, |set_sign|, |sin|,
+% |tan|;
+% \item |\__fp_|\meta{type_1}|_|\meta{op}|_|\meta{type_2}|_o:ww| for
+% \meta{op} among |^*/-+&|\verb"|" and for every pair of types;
+% \item |\__fp_|\meta{type_1}|_bcmp_|\meta{type_2}|:ww| for every
+% pair of types.
+% \end{itemize}
+% The latter is set up in \pkg{l3fp-logic}.
+%
+% \subsection{Dispatch according to the type}
+%
+% \begin{macro}[EXP]
+% {\@@_types_cs_to_op:N, \@@_types_cs_to_op_auxi:wwwn}
+% From |\__fp_|\meta{op}|_o:w| produce \meta{op}, otherwise~|?|.
+% \begin{macrocode}
+\cs_new:Npe \@@_types_cs_to_op:N #1
+ {
+ \exp_not:N \exp_after:wN \exp_not:N \@@_types_cs_to_op_auxi:wwwn
+ \exp_not:N \token_to_str:N #1 \s_@@_mark
+ \exp_not:N \@@_use_i_delimit_by_s_stop:nw
+ \tl_to_str:n { @@_ _o:w } \s_@@_mark
+ { \exp_not:N \@@_use_i_delimit_by_s_stop:nw ? }
+ \s_@@_stop
+ }
+\use:e
+ {
+ \cs_new:Npn \exp_not:N \@@_types_cs_to_op_auxi:wwwn
+ #1 \tl_to_str:n { @@_ } #2
+ \tl_to_str:n { _o:w } #3 \s_@@_mark #4 { #4 {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_types_unary:NNw}
+% \begin{macro}[EXP]
+% {\@@_types_unary_auxi:nNw, \@@_types_unary_auxii:NnNw}
+% \begin{syntax}
+% \cs{@@_types_unary:NNw} |\__fp_|\meta{function}|_o:w|
+% ~~\meta{token} \meta{operand} |@|
+% \end{syntax}
+% \begin{macrocode}
+\cs_new:Npn \@@_types_unary:NNw #1
+ {
+ \exp_args:Nf \@@_types_unary_auxi:nNw
+ { \@@_types_cs_to_op:N #1 }
+ }
+\cs_new:Npn \@@_types_unary_auxi:nNw #1#2#3
+ {
+ \exp_after:wN \@@_types_unary_auxii:NnNw
+ \cs:w @@_#1 \@@_type_from_scan:N #3 _o:w \cs_end:
+ {#1}
+ #2#3
+ }
+\cs_new:Npn \@@_types_unary_auxii:NnNw #1#2#3
+ {
+ \token_if_eq_meaning:NNTF \scan_stop: #1
+ { \@@_invalid_operation_o:nw {#2} }
+ { #1 #3 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_types_binary:Nww}
+% \begin{macro}[EXP]
+% {\@@_types_binary_auxi:Nww, \@@_types_binary_auxii:NNww}
+% \begin{syntax}
+% \cs{@@_types_binary:Nww} |\__fp_|\meta{binop}|_o:ww|
+% ~~\meta{operand_1} \meta{operand_2} |@|
+% \end{syntax}
+% \begin{macrocode}
+\cs_new:Npn \@@_types_binary:Nww #1
+ {
+ \exp_last_unbraced:Nf \@@_types_binary_auxi:Nww
+ { \@@_types_cs_to_op:N #1 }
+ }
+\cs_new:Npn \@@_types_binary_auxi:Nww #1#2#3; #4#5; @
+ {
+ \exp_after:wN \@@_types_binary_auxii:NNww
+ \cs:w
+ @@
+ \@@_type_from_scan:N #2
+ _#1
+ \@@_type_from_scan:N #4
+ _o:ww
+ \cs_end:
+ #1 #2#3; #4#5;
+ }
+\cs_new:Npn \@@_types_binary_auxii:NNww #1#2
+ {
+ \token_if_eq_meaning:NNTF \scan_stop: #1
+ { \@@_invalid_operation_o:Nww #2 }
+ {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fp.dtx b/macros/latex-dev/required/l3kernel/l3fp.dtx
new file mode 100644
index 0000000000..7cef573970
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fp.dtx
@@ -0,0 +1,1663 @@
+% \iffalse meta-comment
+%
+%% File: l3fp.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\usepackage{amsmath}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% ^^A need to provide this inside the file:
+%
+% \providecommand\nan{\texttt{NaN}}
+%
+%
+% \title{^^A
+% The \pkg{l3fp} module\\ Floating points^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% A decimal floating point number is one which is stored as a significand and a
+% separate exponent. The module implements expandably a wide set of
+% arithmetic, trigonometric, and other operations on decimal floating point
+% numbers, to be used within floating point expressions. \emph{Floating point
+% expressions} (\enquote{\meta{fp expr}}) support the following operations with their usual
+% precedence.
+% \begin{itemize}
+% \item Basic arithmetic: addition $x+y$, subtraction $x-y$,
+% multiplication $x*y$, division $x/y$, square root~$\sqrt{x}$,
+% and parentheses.
+% \item Comparison operators: $x\mathop{\mathtt{<}}y$,
+% $x\mathop{\mathtt{<=}}y$, $x\mathop{\mathtt{>?}}y$,
+% $x\mathop{\mathtt{!=}}y$ \emph{etc.}
+% \item Boolean logic: sign $\operatorname{sign} x$,
+% negation $\mathop{!}x$, conjunction
+% $x\mathop{\&\&}y$, disjunction $x\mathop{\vert\vert}y$, ternary
+% operator $x\mathop{?}y\mathop{:}z$.
+% \item Exponentials: $\exp x$, $\ln x$, $x^y$, $\operatorname{logb} x$.
+% \item Integer factorial: $\operatorname{fact} x$.
+% \item Trigonometry: $\sin x$, $\cos x$, $\tan x$, $\cot x$, $\sec
+% x$, $\csc x$ expecting their arguments in radians, and
+% $\operatorname{sind} x$, $\operatorname{cosd} x$,
+% $\operatorname{tand} x$, $\operatorname{cotd} x$,
+% $\operatorname{secd} x$, $\operatorname{cscd} x$ expecting their
+% arguments in degrees.
+% \item Inverse trigonometric functions: $\operatorname{asin} x$,
+% $\operatorname{acos} x$, $\operatorname{atan} x$,
+% $\operatorname{acot} x$, $\operatorname{asec} x$,
+% $\operatorname{acsc} x$ giving a result in radians, and
+% $\operatorname{asind} x$, $\operatorname{acosd} x$,
+% $\operatorname{atand} x$, $\operatorname{acotd} x$,
+% $\operatorname{asecd} x$, $\operatorname{acscd} x$ giving a result
+% in degrees.
+% \item [\emph{(not yet)}] Hyperbolic functions and their inverse
+% functions: $\sinh x$, $\cosh x$, $\tanh x$, $\coth x$,
+% $\operatorname{sech} x$, $\operatorname{csch}$, and
+% $\operatorname{asinh} x$, $\operatorname{acosh} x$,
+% $\operatorname{atanh} x$, $\operatorname{acoth} x$,
+% $\operatorname{asech} x$, $\operatorname{acsch} x$.
+% \item Extrema: $\max(x_{1},x_{2},\ldots)$, $\min(x_{1},x_{2},\ldots)$,
+% $\operatorname{abs}(x)$.
+% \item Rounding functions, controlled by two optional
+% values, $n$ (number of places, $0$ by default) and
+% $t$ (behavior on a tie, $\nan$ by default):
+% \begin{itemize}
+% \item $\operatorname{trunc}(x,n)$ rounds towards zero,
+% \item $\operatorname{floor}(x,n)$ rounds towards~$-\infty$,
+% \item $\operatorname{ceil}(x,n)$ rounds towards~$+\infty$,
+% \item $\operatorname{round}(x,n,t)$ rounds to the closest value, with
+% ties rounded to an even value by default, towards zero if $t=0$,
+% towards $+\infty$ if $t>0$ and towards $-\infty$ if $t<0$.
+% \end{itemize}
+% And \emph{(not yet)} modulo, and \enquote{quantize}.
+% \item Random numbers: $\mathop{rand}()$, $\mathop{randint}(m,n)$.
+% \item Constants: \texttt{pi}, \texttt{deg} (one degree in radians).
+% \item Dimensions, automatically expressed in points, \emph{e.g.},
+% \texttt{pc} is~$12$.
+% \item Automatic conversion (no need for \cs[no-index]{\meta{type}_use:N}) of
+% integer, dimension, and skip variables to floating point numbers,
+% expressing dimensions in points and ignoring the stretch and
+% shrink components of skips.
+% \item Tuples: $(x_1,\ldots{},x_n)$ that can be stored in variables,
+% added together, multiplied or divided by a floating point number,
+% and nested.
+% \end{itemize}
+% Floating point numbers can be given either explicitly (in a form such
+% as |1.234e-34|, or |-.0001|), or as a stored floating point variable,
+% which is automatically replaced by its current value.
+% A \enquote{floating point} is a floating point number or a tuple thereof. See
+% section~\ref{sec:l3fp:fp-floats} for a description of what a floating point is,
+% section~\ref{sec:l3fp:fp-precedence} for details about how an expression is
+% parsed, and section~\ref{sec:l3fp:fp-operations} to know what the various
+% operations do. Some operations may raise exceptions (error messages),
+% described in section~\ref{sec:l3fp:fp-exceptions}.
+%
+% An example of use could be the following.
+% \begin{verbatim}
+% \LaTeX{} can now compute: $ \frac{\sin (3.5)}{2} + 2\cdot 10^{-3}
+% = \ExplSyntaxOn \fp_to_decimal:n {sin(3.5)/2 + 2e-3} $.
+% \end{verbatim}
+% The operation \texttt{round} can be used to limit the result's
+% precision. Adding $+0$ avoids the possibly undesirable output |-0|,
+% replacing it by |+0|. However, the \pkg{l3fp} module is mostly meant
+% as an underlying tool for higher-level commands. For example, one
+% could provide a function to typeset nicely the result of floating
+% point computations.
+% \begin{verbatim}
+% \documentclass{article}
+% \usepackage{siunitx}
+% \ExplSyntaxOn
+% \NewDocumentCommand { \calcnum } { m }
+% { \num { \fp_to_scientific:n {#1} } }
+% \ExplSyntaxOff
+% \begin{document}
+% \calcnum { 2 pi * sin ( 2.3 ^ 5 ) }
+% \end{document}
+% \end{verbatim}
+% See the documentation of \pkg{siunitx} for various options of
+% \cs{num}.
+%
+% \section{Creating and initialising floating point variables}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp001]
+% {\fp_new:N, \fp_new:c}
+% \begin{syntax}
+% \cs{fp_new:N} \meta{fp~var}
+% \end{syntax}
+% Creates a new \meta{fp~var} or raises an error if the name is
+% already taken. The declaration is global. The \meta{fp~var} is
+% initially~$+0$.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp001]
+% {\fp_const:Nn, \fp_const:cn}
+% \begin{syntax}
+% \cs{fp_const:Nn} \meta{fp~var} \Arg{fp expr}
+% \end{syntax}
+% Creates a new constant \meta{fp~var} or raises an error if the name
+% is already taken. The \meta{fp~var} is set globally equal to
+% the result of evaluating the \meta{fp expr}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp001]
+% {\fp_zero:N, \fp_zero:c, \fp_gzero:N, \fp_gzero:c}
+% \begin{syntax}
+% \cs{fp_zero:N} \meta{fp~var}
+% \end{syntax}
+% Sets the \meta{fp~var} to~$+0$.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp001]
+% {\fp_zero_new:N, \fp_zero_new:c, \fp_gzero_new:N, \fp_gzero_new:c}
+% \begin{syntax}
+% \cs{fp_zero_new:N} \meta{fp~var}
+% \end{syntax}
+% Ensures that the \meta{fp~var} exists globally
+% by applying \cs{fp_new:N} if necessary, then applies
+% \cs[index=fp_zero:N]{fp_(g)zero:N} to leave the \meta{fp~var} set to~$+0$.
+% \end{function}
+%
+% \section{Setting floating point variables}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp002]
+% {\fp_set:Nn, \fp_set:cn, \fp_gset:Nn, \fp_gset:cn}
+% \begin{syntax}
+% \cs{fp_set:Nn} \meta{fp~var} \Arg{fp expr}
+% \end{syntax}
+% Sets \meta{fp~var} equal to the result of computing the
+% \meta{fp expr}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp002]
+% {
+% \fp_set_eq:NN , \fp_set_eq:cN , \fp_set_eq:Nc , \fp_set_eq:cc ,
+% \fp_gset_eq:NN, \fp_gset_eq:cN, \fp_gset_eq:Nc, \fp_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{fp_set_eq:NN} \meta{fp~var_1} \meta{fp~var_2}
+% \end{syntax}
+% Sets the floating point variable \meta{fp~var_1} equal to the current
+% value of \meta{fp~var_2}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp002]
+% {\fp_add:Nn, \fp_add:cn, \fp_gadd:Nn, \fp_gadd:cn}
+% \begin{syntax}
+% \cs{fp_add:Nn} \meta{fp~var} \Arg{fp expr}
+% \end{syntax}
+% Adds the result of computing the \meta{fp expr} to
+% the \meta{fp~var}.
+% This also applies if \meta{fp~var} and \meta{floating point
+% expression} evaluate to tuples of the same size.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp002]
+% {\fp_sub:Nn, \fp_sub:cn, \fp_gsub:Nn, \fp_gsub:cn}
+% \begin{syntax}
+% \cs{fp_sub:Nn} \meta{fp~var} \Arg{fp expr}
+% \end{syntax}
+% Subtracts the result of computing the \meta{floating point
+% expression} from the \meta{fp~var}.
+% This also applies if \meta{fp~var} and \meta{floating point
+% expression} evaluate to tuples of the same size.
+% \end{function}
+%
+% \section{Using floating points}
+%
+% \begin{function}[EXP, added = 2012-05-08, updated = 2012-07-08,
+% tested = m3fp-convert003]{\fp_eval:n}
+% \begin{syntax}
+% \cs{fp_eval:n} \Arg{fp expr}
+% \end{syntax}
+% Evaluates the \meta{fp expr} and expresses the
+% result as a decimal number with no
+% exponent. Leading or trailing zeros may be inserted to compensate
+% for the exponent. Non-significant trailing zeros are trimmed, and
+% integers are expressed without a decimal separator. The values
+% $\pm\infty$ and \nan{} trigger an \enquote{invalid operation}
+% exception.
+% For a tuple, each item is converted using \cs{fp_eval:n} and they are combined as
+% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
+% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
+% This function is identical to \cs{fp_to_decimal:n}.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2018-11-03]{\fp_sign:n}
+% \begin{syntax}
+% \cs{fp_sign:n} \Arg{fp expr}
+% \end{syntax}
+% Evaluates the \meta{fp expr} and leaves its sign in the input stream
+% using \cs{fp_eval:n} |{sign(|\meta{result}|)}|: $+1$ for positive
+% numbers and for $+\infty$, $-1$ for negative numbers and for
+% $-\infty$, $\pm 0$ for $\pm 0$. If the operand is a tuple or is
+% \nan{}, then \enquote{invalid operation} occurs and the result
+% is~$0$.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2012-05-08, updated = 2012-07-08]
+% {\fp_to_decimal:N, \fp_to_decimal:c, \fp_to_decimal:n}
+% \begin{syntax}
+% \cs{fp_to_decimal:N} \meta{fp~var}
+% \cs{fp_to_decimal:n} \Arg{fp expr}
+% \end{syntax}
+% Evaluates the \meta{fp expr} and expresses the
+% result as a decimal number with no
+% exponent. Leading or trailing zeros may be inserted to compensate
+% for the exponent. Non-significant trailing zeros are trimmed, and
+% integers are expressed without a decimal separator. The values
+% $\pm\infty$ and~\nan{} trigger an \enquote{invalid operation}
+% exception.
+% For a tuple, each item is converted using \cs{fp_to_decimal:n} and they are combined as
+% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
+% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2016-03-22]
+% {\fp_to_dim:N, \fp_to_dim:c, \fp_to_dim:n}
+% \begin{syntax}
+% \cs{fp_to_dim:N} \meta{fp~var}
+% \cs{fp_to_dim:n} \Arg{fp expr}
+% \end{syntax}
+% Evaluates the \meta{fp expr} and expresses the
+% result as a dimension (in~\texttt{pt}) suitable for use in dimension
+% expressions. The output is identical to \cs{fp_to_decimal:n}, with
+% an additional trailing~\texttt{pt} (both letter tokens).
+% In particular, the result may
+% be outside the range $[- 2^{14} + 2^{-17}, 2^{14} - 2^{-17}]$ of
+% valid \TeX{} dimensions, leading to overflow errors if used as a
+% dimension. Tuples, as well as the values $\pm\infty$ and~\nan{},
+% trigger an \enquote{invalid operation} exception.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2012-07-08]
+% {\fp_to_int:N, \fp_to_int:c, \fp_to_int:n}
+% \begin{syntax}
+% \cs{fp_to_int:N} \meta{fp~var}
+% \cs{fp_to_int:n} \Arg{fp expr}
+% \end{syntax}
+% Evaluates the \meta{fp expr}, and rounds the
+% result to the closest integer, rounding exact ties to an even
+% integer.
+% The result may be outside the range $[- 2^{31} + 1, 2^{31} - 1]$ of
+% valid \TeX{}~integers, leading to overflow errors if used in an
+% integer expression. Tuples, as well as the values $\pm\infty$
+% and~\nan{}, trigger an \enquote{invalid operation} exception.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2012-05-08, updated = 2016-03-22]
+% {\fp_to_scientific:N, \fp_to_scientific:c, \fp_to_scientific:n}
+% \begin{syntax}
+% \cs{fp_to_scientific:N} \meta{fp~var}
+% \cs{fp_to_scientific:n} \Arg{fp expr}
+% \end{syntax}
+% Evaluates the \meta{fp expr} and expresses the
+% result in scientific notation:
+% \begin{quote}
+% \meta{optional \texttt{-}}\meta{digit}\texttt{.}\meta{15 digits}\texttt{e}\meta{optional sign}\meta{exponent}
+% \end{quote}
+% The leading \meta{digit} is non-zero except in the case of $\pm 0$.
+% The values $\pm\infty$ and~\nan{} trigger an \enquote{invalid
+% operation} exception. Normal category codes apply: thus the |e| is
+% category code~$11$ (a letter).
+% For a tuple, each item is converted using \cs{fp_to_scientific:n} and they are combined as
+% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
+% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2016-03-22]
+% {\fp_to_tl:N, \fp_to_tl:c, \fp_to_tl:n}
+% \begin{syntax}
+% \cs{fp_to_tl:N} \meta{fp~var}
+% \cs{fp_to_tl:n} \Arg{fp expr}
+% \end{syntax}
+% Evaluates the \meta{fp expr} and expresses the
+% result in (almost) the shortest possible form. Numbers in the
+% ranges $(0,10^{-3})$ and $[10^{16},\infty)$ are expressed in
+% scientific notation with trailing zeros trimmed and no decimal
+% separator when there is a single significant digit (this differs from
+% \cs{fp_to_scientific:n}). Numbers in the range $[10^{-3},10^{16})$
+% are expressed in a decimal notation without exponent, with trailing
+% zeros trimmed, and no decimal separator for integer values (see
+% \cs{fp_to_decimal:n}. Negative numbers start with~|-|. The
+% special values $\pm 0$, $\pm\infty$ and~\nan{} are rendered as
+% |0|, |-0|, \texttt{inf}, \texttt{-inf}, and~\texttt{nan}
+% respectively. Normal category codes apply and thus \texttt{inf} or
+% \texttt{nan}, if produced, are made up of letters.
+% For a tuple, each item is converted using \cs{fp_to_tl:n} and they are combined as
+% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
+% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2012-07-08]
+% {\fp_use:N, \fp_use:c}
+% \begin{syntax}
+% \cs{fp_use:N} \meta{fp~var}
+% \end{syntax}
+% Inserts the value of the \meta{fp~var} into the input stream as a
+% decimal number with no exponent.
+% Leading or trailing zeros may be inserted to compensate for the
+% exponent. Non-significant trailing zeros are trimmed. Integers are
+% expressed without a decimal separator. The values $\pm\infty$
+% and~\nan{} trigger an \enquote{invalid operation} exception.
+% For a tuple, each item is converted using \cs{fp_to_decimal:n} and they are combined as
+% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
+% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
+% This function is identical to \cs{fp_to_decimal:N}.
+% \end{function}
+%
+% \section{Floating point conditionals}
+%
+% \begin{function}[EXP, pTF, updated = 2012-05-08, tested = m3fp002]
+% {\fp_if_exist:N, \fp_if_exist:c}
+% \begin{syntax}
+% \cs{fp_if_exist_p:N} \meta{fp~var}
+% \cs{fp_if_exist:NTF} \meta{fp~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{fp~var} is currently defined. This does not
+% check that the \meta{fp~var} really is a floating point variable.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, updated = 2012-05-08,
+% tested = m3fp-logic001]{\fp_compare:nNn}
+% \begin{syntax}
+% \cs{fp_compare_p:nNn} \Arg{fp expr_1} \meta{relation} \Arg{fp expr_2}
+% \cs{fp_compare:nNnTF} \Arg{fp expr_1} \meta{relation} \Arg{fp expr_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Compares the \meta{fp expr_1} and the \meta{fp expr_2}, and returns
+% \texttt{true} if the \meta{relation} is obeyed. Two floating points
+% $x$ and~$y$ may obey four mutually exclusive relations:
+% $x<y$, $x=y$, $x>y$, or $x?y$ (\enquote{not ordered}). The last
+% case occurs exactly if one or both operands is~\nan{} or is a tuple,
+% unless they are equal tuples. Note that a~\nan{} is distinct from
+% any value, even another~\nan{}, hence $x=x$ is not true for
+% a~\nan{}. To test if a value is~\nan{}, compare it to an arbitrary
+% number with the \enquote{not ordered} relation.
+% \begin{verbatim}
+% \fp_compare:nNnTF { <value> } ? { 0 }
+% { } % <value> is nan
+% { } % <value> is not nan
+% \end{verbatim}
+% Tuples are equal if they have the same number of items and items
+% compare equal (in particular there must be no~\nan{}).
+% At present any other comparison with tuples yields |?| (not ordered).
+% This is experimental.
+%
+% This function is less flexible than \cs{fp_compare:nTF} but slightly
+% faster. It is provided for consistency with \cs{int_compare:nNnTF}
+% and \cs{dim_compare:nNnTF}.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, updated = 2013-12-14,
+% tested = m3fp-logic001]{\fp_compare:n}
+% \begin{syntax}
+% \cs{fp_compare_p:n} \\
+% ~~\{ \\
+% ~~~~\meta{fp expr_1} \meta{relation_1} \\
+% ~~~~\ldots{} \\
+% ~~~~\meta{fp expr_N} \meta{relation_N} \\
+% ~~~~\meta{fp expr_{N+1}} \\
+% ~~\} \\
+% \cs{fp_compare:nTF}
+% ~~\{ \\
+% ~~~~\meta{fp expr_1} \meta{relation_1} \\
+% ~~~~\ldots{} \\
+% ~~~~\meta{fp expr_N} \meta{relation_N} \\
+% ~~~~\meta{fp expr_{N+1}} \\
+% ~~\} \\
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Evaluates the \meta{fp exprs} as described for
+% \cs{fp_eval:n} and compares consecutive result using the
+% corresponding \meta{relation}, namely it compares \meta{fp expr_1}
+% and \meta{fp expr_2} using the \meta{relation_1}, then
+% \meta{fp expr_2} and \meta{fp expr_3} using the \meta{relation_2},
+% until finally comparing \meta{fp expr_N} and \meta{fp expr_{N+1}}
+% using the \meta{relation_N}. The test yields \texttt{true} if all
+% comparisons are \texttt{true}. Each \meta{floating point
+% expression} is evaluated only once. Contrarily to
+% \cs{int_compare:nTF}, all \meta{fp exprs} are
+% computed, even if one comparison is \texttt{false}. Two floating
+% points $x$ and~$y$ may obey four mutually exclusive
+% relations: $x<y$, $x=y$, $x>y$, or $x?y$ (\enquote{not ordered}).
+% The last case occurs exactly if one or both operands is~\nan{} or is
+% a tuple, unless they are equal tuples. Each \meta{relation}
+% can be any (non-empty) combination of |<|, |=|, |>|, and~|?|, plus
+% an optional leading~|!| (which negates the \meta{relation}), with
+% the restriction that the \meta{relation} may not start with~|?|, as
+% this symbol has a different meaning (in combination with~|:|) within
+% floating point expressions. The comparison $x$~\meta{relation}~$y$
+% is then \texttt{true} if the \meta{relation} does not start with~|!|
+% and the actual relation (|<|, |=|, |>|, or~|?|) between $x$ and~$y$
+% appears within the \meta{relation}, or on the contrary if the
+% \meta{relation} starts with~|!| and the relation between $x$ and~$y$
+% does not appear within the \meta{relation}. Common choices of
+% \meta{relation} include |>=|~(greater or equal), |!=|~(not equal),
+% |!?|~or~|<=>| (comparable).
+%
+% This function is more flexible than \cs{fp_compare:nNnTF} and only
+% slightly slower.
+% \end{function}
+%
+% \begin{function}[pTF, added = 2019-08-25]{\fp_if_nan:n}
+% \begin{syntax}
+% \cs{fp_if_nan_p:n} \Arg{fp expr}
+% \cs{fp_if_nan:nTF} \Arg{fp expr} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Evaluates the \meta{fp expr} and tests whether the result is exactly
+% \nan{}. The test returns \texttt{false} for any other result, even
+% a tuple containing \nan{}.
+% \end{function}
+%
+% \section{Floating point expression loops}
+%
+% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003]
+% {\fp_do_until:nNnn}
+% \begin{syntax}
+% \cs{fp_do_until:nNnn} \Arg{fp expr_1} \meta{relation} \Arg{fp expr_2} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process,
+% and then evaluates the relationship between the two \meta{floating
+% point expressions} as described for \cs{fp_compare:nNnTF}. If the
+% test is \texttt{false} then the \meta{code} is inserted into
+% the input stream again and a loop occurs until the
+% \meta{relation} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003]
+% {\fp_do_while:nNnn}
+% \begin{syntax}
+% \cs{fp_do_while:nNnn} \Arg{fp expr_1} \meta{relation} \Arg{fp expr_2} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process,
+% and then evaluates the relationship between the two \meta{floating
+% point expressions} as described for \cs{fp_compare:nNnTF}. If the
+% test is \texttt{true} then the \meta{code} is inserted into the
+% input stream again and a loop occurs until the \meta{relation}
+% is \texttt{false}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003]
+% {\fp_until_do:nNnn}
+% \begin{syntax}
+% \cs{fp_until_do:nNnn} \Arg{fp expr_1} \meta{relation} \Arg{fp expr_2} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{floating point
+% expressions} as described for \cs{fp_compare:nNnTF}, and then
+% places the \meta{code} in the input stream if the \meta{relation} is
+% \texttt{false}. After the \meta{code} has been processed by \TeX{}
+% the test is repeated, and a loop occurs until the test is
+% \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003]
+% {\fp_while_do:nNnn}
+% \begin{syntax}
+% \cs{fp_while_do:nNnn} \Arg{fp expr_1} \meta{relation} \Arg{fp expr_2} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{floating point
+% expressions} as described for \cs{fp_compare:nNnTF}, and then
+% places the \meta{code} in the input stream if the \meta{relation} is
+% \texttt{true}. After the \meta{code} has been processed by \TeX{}
+% the test is repeated, and a loop occurs until the test is
+% \texttt{false}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2012-08-16, updated = 2013-12-14, tested = m3fp-logic003]
+% {\fp_do_until:nn}
+% \begin{syntax}
+% \cs{fp_do_until:nn} \{ \meta{fp expr_1} \meta{relation} \meta{fp expr_2} \} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process,
+% and then evaluates the relationship between the two \meta{floating
+% point expressions} as described for \cs{fp_compare:nTF}. If the
+% test is \texttt{false} then the \meta{code} is inserted into
+% the input stream again and a loop occurs until the
+% \meta{relation} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2012-08-16, updated = 2013-12-14, tested = m3fp-logic003]
+% {\fp_do_while:nn}
+% \begin{syntax}
+% \cs{fp_do_while:nn} \{ \meta{fp expr_1} \meta{relation} \meta{fp expr_2} \} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process,
+% and then evaluates the relationship between the two \meta{floating
+% point expressions} as described for \cs{fp_compare:nTF}. If the
+% test is \texttt{true} then the \meta{code} is inserted into the
+% input stream again and a loop occurs until the \meta{relation}
+% is \texttt{false}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2012-08-16, updated = 2013-12-14, tested = m3fp-logic003]
+% {\fp_until_do:nn}
+% \begin{syntax}
+% \cs{fp_until_do:nn} \{ \meta{fp expr_1} \meta{relation} \meta{fp expr_2} \} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{floating point
+% expressions} as described for \cs{fp_compare:nTF}, and then places
+% the \meta{code} in the input stream if the \meta{relation} is
+% \texttt{false}. After the \meta{code} has been processed by \TeX{}
+% the test is repeated, and a loop occurs until the test is
+% \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2012-08-16, updated = 2013-12-14, tested = m3fp-logic003]
+% {\fp_while_do:nn}
+% \begin{syntax}
+% \cs{fp_while_do:nn} \{ \meta{fp expr_1} \meta{relation} \meta{fp expr_2} \} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{floating point
+% expressions} as described for \cs{fp_compare:nTF}, and then places
+% the \meta{code} in the input stream if the \meta{relation} is
+% \texttt{true}. After the \meta{code} has been processed by \TeX{}
+% the test is repeated, and a loop occurs until the test is
+% \texttt{false}.
+% \end{function}
+%
+% \begin{function}[added = 2016-11-21, updated = 2016-12-06, rEXP]
+% {\fp_step_function:nnnN, \fp_step_function:nnnc}
+% \begin{syntax}
+% \cs{fp_step_function:nnnN} \Arg{initial value} \Arg{step} \Arg{final value} \meta{function}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, each of which should be a floating point
+% expression evaluating to a floating point number, not a tuple.
+% The \meta{function} is then placed in front of each \meta{value}
+% from the \meta{initial value} to the \meta{final value} in turn
+% (using \meta{step} between each \meta{value}). The \meta{step} must
+% be non-zero. If the \meta{step} is positive, the loop stops when
+% the \meta{value} becomes larger than the \meta{final value}. If the
+% \meta{step} is negative, the loop stops when the \meta{value}
+% becomes smaller than the \meta{final value}. The \meta{function}
+% should absorb one numerical argument. For example
+% \begin{verbatim}
+% \cs_set:Npn \my_func:n #1 { [I~saw~#1] \quad }
+% \fp_step_function:nnnN { 1.0 } { 0.1 } { 1.5 } \my_func:n
+% \end{verbatim}
+% would print
+% \begin{quote}
+% [I saw 1.0] \quad
+% [I saw 1.1] \quad
+% [I saw 1.2] \quad
+% [I saw 1.3] \quad
+% [I saw 1.4] \quad
+% [I saw 1.5] \quad
+% \end{quote}
+% \begin{texnote}
+% Due to rounding, it may happen that adding the \meta{step} to the
+% \meta{value} does not change the \meta{value}; such cases give an
+% error, as they would otherwise lead to an infinite loop.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2016-11-21, updated = 2016-12-06]
+% {\fp_step_inline:nnnn}
+% \begin{syntax}
+% \cs{fp_step_inline:nnnn} \Arg{initial value} \Arg{step} \Arg{final value} \Arg{code}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, all of which should be floating point
+% expressions evaluating to a floating point number, not a tuple.
+% Then for each \meta{value} from the \meta{initial value} to the
+% \meta{final value} in turn (using \meta{step} between each
+% \meta{value}), the \meta{code} is inserted into the input stream
+% with |#1| replaced by the current \meta{value}. Thus the
+% \meta{code} should define a function of one argument~(|#1|).
+% \end{function}
+%
+% \begin{function}[added = 2017-04-12]{\fp_step_variable:nnnNn}
+% \begin{syntax}
+% \cs{fp_step_variable:nnnNn} \\
+% ~~\Arg{initial value} \Arg{step} \Arg{final value} \meta{tl~var} \Arg{code}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, all of which should be floating point
+% expressions evaluating to a floating point number, not a tuple.
+% Then for each \meta{value} from the \meta{initial value} to the
+% \meta{final value} in turn (using \meta{step} between each
+% \meta{value}), the \meta{code} is inserted into the input stream,
+% with the \meta{tl~var} defined as the current \meta{value}. Thus
+% the \meta{code} should make use of the \meta{tl~var}.
+% \end{function}
+%
+% \section{Symbolic expressions}
+%
+% Floating point expressions support variables: these can only be set locally,
+% so act like standard \cs[no-index]{l_\dots} variables.
+% \begin{quote}\let\obeyedline=\newline\obeylines^^A
+% \cs{fp_new_variable:n} |{ A }|
+% \cs{fp_set:Nn} \cs{l_tmpb_fp} |{ 1 * sin(A) + 3**2 }|
+% \cs{fp_show:n} |{| \cs{l_tmpb_fp} |}|
+% \cs{fp_show:N} \cs{l_tmpb_fp}
+% \cs{fp_set_variable:nn} |{ A }| |{ pi/2 }|
+% \cs{fp_show:n} |{| \cs{l_tmpb_fp} |}|
+% \cs{fp_show:N} \cs{l_tmpb_fp}
+% \cs{fp_set_variable:nn} |{ A }| |{ 0 }|
+% \cs{fp_show:n} |{| \cs{l_tmpb_fp} |}|
+% \cs{fp_show:N} \cs{l_tmpb_fp}
+% \end{quote}
+% defines~|A| to be a variable, then defines \cs{l_tmpb_fp} to stand for
+% |1*sin(A)+9| (note that |3**2| is evaluated, but the |1*|~product is
+% not simplified away). Until \cs{l_tmpb_fp} is changed, \cs{fp_show:N}
+% \cs{l_tmpb_fp} will show |((1*sin(A))+9)| regardless of the value
+% of~|A|. The next step defines~|A| to be equal to~|pi/2|: then
+% \cs{fp_show:n} |{| \cs{l_tmpb_fp} |}| will evaluate \cs{l_tmpb_fp} and
+% show~|10|. We then redefine~|A| to be~|0|: since \cs{l_tmpb_fp} still
+% stands for |1*sin(A)+9|, the value shown is then~|9|. Variables can
+% be set with \cs{fp_set_variable:nn} to arbitrary floating point
+% expressions including other variables.
+%
+% \begin{function}[added = 2023-10-19]{\fp_new_variable:n}
+% \begin{syntax}
+% \cs{fp_new_variable:n} \Arg{identifier}
+% \end{syntax}
+% Declares the \meta{identifier} as a variable, which allows it to be
+% used in floating point expressions. For instance,
+% \begin{quote}
+% \cs{fp_new_variable:n} |{ A }| \\
+% \cs{fp_show:n} |{ A**2 - A + 1 }|
+% \end{quote}
+% shows |(((A^2)-A)+1)|. If the declaration was missing, the parser
+% would complain about an \enquote{\texttt{Unknown fp word 'A'}}. The
+% \meta{identifier} must consist entirely of Latin letters among
+% |[a-zA-Z]|.
+% \end{function}
+%
+% \begin{function}[added = 2023-10-19]{\fp_set_variable:nn}
+% \begin{syntax}
+% \cs{fp_set_variable:nn} \Arg{identifier} \Arg{fp expr}
+% \end{syntax}
+% Defines the \meta{identifier} to stand in any further expression for
+% the result of evaluating the \meta{floating point expression} as
+% much as possible. The result may contain other variables, which are
+% then replaced by their values if they have any. For instance,
+% \begin{quote}\let\obeyedline=\newline\obeylines^^A
+% \cs{fp_new_variable:n} |{ A }|
+% \cs{fp_new_variable:n} |{ B }|
+% \cs{fp_new_variable:n} |{ C }|
+% \cs{fp_set_variable:nn} |{ A } { 3 }|
+% \cs{fp_set_variable:nn} |{ C } { A ** 2 + B * 1 }|
+% \cs{fp_show:n} |{ C + 4 }|
+% \cs{fp_set_variable:nn} |{ A } { 4 }|
+% \cs{fp_show:n} |{ C + 4 }|
+% \end{quote}
+% shows |((9+(B*1))+4)| twice: changing the value of~|A| to~|4| does
+% not alter~|C| because |A|~was replaced by its value~|3| when
+% evaluating |A**2+B*1|.
+% \end{function}
+%
+% \begin{function}[added = 2023-10-19]{\fp_clear_variable:n}
+% \begin{syntax}
+% \cs{fp_clear_variable:n} \Arg{identifier}
+% \end{syntax}
+% Removes any value given by \cs{fp_set_variable:nn} to the variable
+% with this \meta{identifier}. For instance,
+% \begin{quote}\let\obeyedline=\newline\obeylines^^A
+% \cs{fp_new_variable:n} |{ A }|
+% \cs{fp_set_variable:nn} |{ A } { 3 }|
+% \cs{fp_show:n} |{ A ^ 2 }|
+% \cs{fp_clear_variable:n} |{ A }|
+% \cs{fp_show:n} |{ A ^ 2 }|
+% \end{quote}
+% shows~|9|, then~|(A^2)|.
+% \end{function}
+%
+% \section{User-defined functions}
+%
+% It is possible to define new user functions which can be used inside
+% the argument to \cs{fp_eval:n}, etc. These functions may take one or
+% more named arguments, and should be implemented using expansion methods
+% only.
+%
+% \begin{function}[added = 2023-10-19]{\fp_new_function:n}
+% \begin{syntax}
+% \cs{fp_new_function:n} \Arg{identifier}
+% \end{syntax}
+% Declares the \meta{identifier} as a function, which allows it to be
+% used in floating point expressions. For instance,
+% \begin{quote}
+% \cs{fp_new_function:n} |{ foo }| \\
+% \cs{fp_show:n} |{ foo ( 1 + 2 , foo(3), A ) ** 2 } }|
+% \end{quote}
+% shows |(foo(3, foo(3), A))^(2)|. If the declaration was missing,
+% the parser would complain about an \enquote{\texttt{Unknown fp word 'foo'}}.
+% The \meta{identifier} must consist entirely of Latin letters |[a-zA-Z]|.
+% \end{function}
+%
+% \begin{function}[added = 2023-10-19]{\fp_set_function:nnn}
+% \begin{syntax}
+% \cs{fp_set_function:nnn} \Arg{identifier} \Arg{vars} \Arg{fp expr}
+% \end{syntax}
+% Defines the \meta{identifier} to stand in any further expression for
+% the result of evaluating the \meta{floating point expression}, with
+% the \meta{identifier} accepting the \meta{vars} (a non-empty
+% comma-separated list).
+% The result may contain other functions, which are
+% then replaced by their results if they have any. For instance,
+% \begin{quote}
+% \cs{fp_new_function:n} |{ foo }| \\
+% \cs{fp_set_function:nnn} |{ npow } { a,b } { a**b }| \\
+% \cs{fp_show:n} |{ npow(16,0.25) } }|
+% \end{quote}
+% shows |2|. The names of the \meta{vars} must
+% consist entirely of Latin letters |[a-zA-Z]|, but are otherwise not
+% restricted: in particular, they are independent of any variables
+% declared by \cs{fp_new_variable:n}.
+% \end{function}
+%
+% \begin{function}[added = 2023-10-19]{\fp_clear_function:n}
+% \begin{syntax}
+% \cs{fp_clear_function:n} \Arg{identifier}
+% \end{syntax}
+% Removes any definition given by \cs{fp_set_function:nnn} to the function
+% with this \meta{identifier}.
+% \end{function}
+%
+% \section{Some useful constants, and scratch variables}
+%
+% \begin{variable}[added = 2012-05-08, module = fp]{\c_zero_fp, \c_minus_zero_fp}
+% Zero, with either sign.
+% \end{variable}
+%
+% \begin{variable}[added = 2012-05-08, module = fp]{\c_one_fp}
+% One as an \texttt{fp}: useful for comparisons in some places.
+% \end{variable}
+%
+% \begin{variable}[added = 2012-05-08, module = fp]{\c_inf_fp, \c_minus_inf_fp}
+% Infinity, with either sign. These can be input directly in a
+% floating point expression as \texttt{inf} and \texttt{-inf}.
+% \end{variable}
+%
+% \begin{variable}[added = 2012-05-08, module = fp]{\c_nan_fp}
+% Not a number. This can be input directly in a floating point expression
+% as \texttt{nan}.
+% \end{variable}
+%
+% \begin{variable}[updated = 2012-05-08, module = fp]{\c_e_fp}
+% The value of the base of the natural logarithm, $\mathrm{e} = \exp(1)$.
+% \end{variable}
+%
+% \begin{variable}[updated = 2013-11-17, module = fp]{\c_pi_fp}
+% The value of~$\pi$. This can be input directly in a floating point
+% expression as~\texttt{pi}.
+% \end{variable}
+%
+% \begin{variable}[added = 2012-05-08, updated = 2013-11-17, module = fp]
+% {\c_one_degree_fp}
+% The value of $1^{\circ}$ in radians. Multiply an angle given in
+% degrees by this value to obtain a result in radians. Note that
+% trigonometric functions expecting an argument in radians or in
+% degrees are both available. Within floating point expressions, this
+% can be accessed as \texttt{deg}.
+% \end{variable}
+%
+% \section{Scratch variables}
+%
+% \begin{variable}[module = fp]{\l_tmpa_fp, \l_tmpb_fp}
+% Scratch floating points for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}[module = fp]{\g_tmpa_fp, \g_tmpb_fp}
+% Scratch floating points for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Floating point exceptions}
+% \label{sec:l3fp:fp-exceptions}
+%
+% \emph{The functions defined in this section are experimental, and
+% their functionality may be altered or removed altogether.}
+%
+% \enquote{Exceptions} may occur when performing some floating point
+% operations, such as \texttt{0 / 0}, or \texttt{10 ** 1e9999}. The
+% relevant \textsc{IEEE} standard defines $5$ types of exceptions,
+% of which we implement~$4$.
+% \begin{itemize}
+% \item \emph{Overflow} occurs whenever the result of an operation is
+% too large to be represented as a normal floating point number. This
+% results in $\pm \infty$.
+% \item \emph{Underflow} occurs whenever the result of an operation is
+% too close to $0$ to be represented as a normal floating point
+% number. This results in $\pm 0$.
+% \item \emph{Invalid operation} occurs for operations with no defined
+% outcome, for instance $0/0$ or $\sin(\infty)$, and results in a \nan{}.
+% It also occurs for conversion functions whose target type does not
+% have the appropriate infinite or \nan{} value (\emph{e.g.},
+% \cs{fp_to_dim:n}).
+% \item \emph{Division by zero} occurs when dividing a non-zero number
+% by $0$, or when evaluating functions at poles, \emph{e.g.},
+% $\ln(0)$ or $\cot(0)$. This results in $\pm\infty$.
+% \item [\emph{(not yet)}] \emph{Inexact} occurs whenever the result of
+% a computation is not exact, in other words, almost always. At the
+% moment, this exception is entirely ignored in \LaTeX3.
+% \end{itemize}
+% To each exception we associate a \enquote{flag}: \cs{l_fp_overflow_flag},
+% \cs{l_fp_underflow_flag}, \cs{l_fp_invalid_operation_flag} and
+% \cs{l_fp_division_by_zero_flag}. The state of these flags can be tested
+% and modified with commands from \pkg{l3flag}
+%
+% By default, the \enquote{invalid operation} exception triggers an
+% (expandable) error, and raises the corresponding flag. Other
+% exceptions raise the corresponding flag but do not trigger an error.
+% The behaviour when an exception occurs can be modified (using
+% \cs{fp_trap:nn}) to either produce an error and raise the flag, or
+% only raise the flag, or do nothing at all.
+%
+% \begin{function}[added = 2012-07-19, updated = 2017-02-13,
+% tested = m3fp-traps001]{\fp_trap:nn}
+% \begin{syntax}
+% \cs{fp_trap:nn} \Arg{exception} \Arg{trap type}
+% \end{syntax}
+% All occurrences of the \meta{exception} (\texttt{overflow},
+% \texttt{underflow}, \texttt{invalid_operation} or
+% \texttt{division_by_zero}) within the current
+% group are treated as \meta{trap type}, which can be
+% \begin{itemize}
+% \item \texttt{none}: the \meta{exception} will be entirely
+% ignored, and leave no trace;
+% \item \texttt{flag}: the \meta{exception} will turn the
+% corresponding flag on when it occurs;
+% \item \texttt{error}: additionally, the \meta{exception} will halt
+% the \TeX{} run and display some information about the current
+% operation in the terminal.
+% \end{itemize}
+% \emph{This function is experimental, and may be altered or removed.}
+% \end{function}
+%
+% \begin{variable}
+% {
+% \l_fp_overflow_flag,
+% \l_fp_underflow_flag,
+% \l_fp_invalid_operation_flag,
+% \l_fp_division_by_zero_flag
+% }
+% Flags denoting the occurrence of various floating-point exceptions.
+% \end{variable}
+%
+% \section{Viewing floating points}
+%
+% \begin{function}[added = 2012-05-08, updated = 2021-04-29,
+% tested = m3fp002]{\fp_show:N, \fp_show:c, \fp_show:n}
+% \begin{syntax}
+% \cs{fp_show:N} \meta{fp~var}
+% \cs{fp_show:n} \Arg{fp expr}
+% \end{syntax}
+% Evaluates the \meta{fp expr} and displays the
+% result in the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2021-04-29]
+% {\fp_log:N, \fp_log:c, \fp_log:n}
+% \begin{syntax}
+% \cs{fp_log:N} \meta{fp~var}
+% \cs{fp_log:n} \Arg{fp expr}
+% \end{syntax}
+% Evaluates the \meta{fp expr} and writes the
+% result in the log file.
+% \end{function}
+%
+% \section{Floating point expressions}
+%
+% \subsection{Input of floating point numbers} \label{sec:l3fp:fp-floats}
+%
+% We support four types of floating point numbers:
+% \begin{itemize}
+% \item $\pm m \cdot 10^{n}$, a floating
+% point number, with integer $1\leq m\leq 10^{16}$, and
+% $-{\ExplSyntaxOn\int_use:N\c__fp_minus_min_exponent_int}\leq
+% n\leq {\ExplSyntaxOn\int_use:N\c__fp_max_exponent_int}$;
+% \item $\pm 0$, zero, with a given sign;
+% \item $\pm \infty$, infinity, with a given sign;
+% \item \nan{}, is \enquote{not a number}, and can be either quiet
+% or signalling (\emph{not yet}: this distinction is currently
+% unsupported);
+% \end{itemize}
+% Normal floating point numbers are stored in base $10$, with up to $16$
+% significant figures.
+%
+% On input, a normal floating point number consists of:
+% \begin{itemize}
+% \item \meta{sign}: a possibly empty string of |+| and |-| characters;
+% \item \meta{significand}: a non-empty string of digits together with zero
+% or one dot;
+% \item \meta{exponent} optionally: the character |e| or |E|, followed by a
+% possibly empty string of |+|~and~|-| tokens, and a non-empty string
+% of digits.
+% \end{itemize}
+% The sign of the resulting number is |+| if \meta{sign} contains an
+% even number of |-|, and |-| otherwise, hence, an empty \meta{sign}
+% denotes a non-negative input. The stored significand is obtained from
+% \meta{significand} by omitting the decimal separator and leading zeros,
+% and rounding to $16$ significant digits, filling with trailing zeros
+% if necessary. In particular, the value stored is exact if the input
+% \meta{significand} has at most $16$ digits. The stored \meta{exponent}
+% is obtained by combining the input \meta{exponent} ($0$ if absent)
+% with a shift depending on the position of the significand and the number
+% of leading zeros.
+%
+% A special case arises if the resulting \meta{exponent} is either too
+% large or too small for the floating point number to be
+% represented. This results either in an overflow (the number is then
+% replaced by $\pm\infty$), or an underflow (resulting in $\pm 0$).
+%
+% The result is thus $\pm 0$ if and only if \meta{significand} contains no
+% non-zero digit (\emph{i.e.}, consists only in characters~|0|, and an
+% optional period), or if there is an underflow. Note that a
+% single dot is currently a valid floating point number, equal to~$+0$,
+% but that is not guaranteed to remain true.
+%
+% The \meta{significand} must be non-empty, so |e1| and |e-1| are not
+% valid floating point numbers. Note that the latter could be mistaken
+% with the difference of \enquote{\texttt{e}} and $1$. To avoid
+% confusions, the base of natural logarithms cannot be input as |e| and
+% should be input as \texttt{exp(1)} or \cs[module = fp]{c_e_fp} (which is faster).
+%
+% Special numbers are input as follows:
+% \begin{itemize}
+% \item \texttt{inf} represents $+\infty$, and can be preceded by any
+% \meta{sign}, yielding $\pm\infty$ as appropriate.
+% \item \texttt{nan} represents a (quiet) non-number. It can be
+% preceded by any sign, but that sign is ignored.
+% \item Any unrecognizable string triggers an error, and produces a
+% \nan{}.
+% \item Note that commands such as \tn{infty}, \tn{pi}, or \tn{sin}
+% \emph{do not} work in floating point expressions. They may
+% silently be interpreted as completely unexpected numbers, because
+% integer constants (allowed in expressions) are commonly stored as
+% mathematical characters.
+% \end{itemize}
+%
+% \subsection{Precedence of operators}
+% \label{sec:l3fp:fp-precedence}
+%
+% We list here all the operations supported in floating point
+% expressions, in order of decreasing precedence: operations listed
+% earlier bind more tightly than operations listed below them.
+% \begin{itemize}
+% \item Function calls (\texttt{sin}, \texttt{ln}, \emph{etc}).
+% \item Binary |**| and |^| (right associative).
+% \item Unary |+|, |-|, |!|.
+% \item Implicit multiplication by juxtaposition (\texttt{2pi})
+% when neither factor is in parentheses.
+% \item Binary |*| and |/|, implicit multiplication by juxtaposition with parentheses (for instance \texttt{3(4+5)}).
+% \item Binary |+| and |-|.
+% \item Comparisons |>=|, |!=|, |<?|, \emph{etc}.
+% \item Logical \texttt{and}, denoted by |&&|.
+% \item Logical \texttt{or}, denoted by \verb+||+.
+% \item Ternary operator |?:| (right associative).
+% \item Comma (to build tuples).
+% \end{itemize}
+% The precedence of operations can be overridden using parentheses.
+% In particular, the precedence of juxtaposition implies that
+% \begin{align*}
+% \mathtt{1/2pi} & = 1/(2\pi), \\
+% \mathtt{1/2pi(pi+pi)} & = (2\pi)^{-1}(\pi+\pi) \simeq 1, \\
+% \mathtt{sin 2pi} & = \sin(2)\pi \neq 0, \\
+% \mathtt{2\char`\^2max(3,5)} & = 2^2 \max(3,5) = 20, \\
+% \mathtt{1in/1cm} & = (1\mathrm{in})/(1\mathrm{cm}) = 2.54 .
+% \end{align*}
+% Functions are called on the value of their argument, contrarily to
+% \TeX{} macros.
+%
+% \subsection{Operations} \label{sec:l3fp:fp-operations}
+%
+% We now present the various operations allowed in floating point
+% expressions, from the lowest precedence to the highest. When used as
+% a truth value, a floating point expression is \texttt{false} if it is
+% $\pm 0$, and \texttt{true} otherwise, including when it is \nan{} or a
+% tuple such as $(0,0)$. Tuples are only supported to some extent by
+% operations that work with truth values (|?:|, \verb"||", |&&|, |!|),
+% by comparisons (|!<=>?|), and by |+|, |-|, |*|, |/|. Unless otherwise
+% specified, providing a tuple as an argument of any other operation
+% yields the \enquote{invalid operation} exception and a \nan{} result.
+%
+% \begin{function}[tested = m3fp-logic002, module = {}]{?:}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ \meta{operand_1} |?| \meta{operand_2} |:| \meta{operand_3} \}
+% \end{syntax}
+% The ternary operator |?:| results in \meta{operand_2} if
+% \meta{operand_1} is true (not $\pm 0$), and \meta{operand_3} if \meta{operand_1}
+% is false ($\pm 0$). All three \meta{operands} are evaluated in all
+% cases; they may be tuples. The operator is right associative, hence
+% \begin{verbatim}
+% \fp_eval:n
+% {
+% 1 + 3 > 4 ? 1 :
+% 2 + 4 > 5 ? 2 :
+% 3 + 5 > 6 ? 3 : 4
+% }
+% \end{verbatim}
+% first tests whether $1 + 3 > 4$; since this isn't true, the branch
+% following |:| is taken, and $2 + 4 > 5$ is compared; since this is
+% true, the branch before |:| is taken, and everything else is
+% (evaluated then) ignored. That allows testing for various cases in
+% a concise manner, with the drawback that all computations are made
+% in all cases.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-logic002]{||}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ \meta{operand_1} \verb"||" \meta{operand_2} \}
+% \end{syntax}
+% If \meta{operand_1} is true (not $\pm 0$), use that value, otherwise the
+% value of \meta{operand_2}. Both \meta{operands} are evaluated in all
+% cases; they may be tuples. In \meta{operand_1} \verb"||"
+% \meta{operand_2} \verb"||" \ldots{} \verb"||" \meta{operands_n}, the
+% first true (nonzero) \meta{operand} is used and if all are zero the
+% last one ($\pm 0$) is used.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-logic002]{&&}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ \meta{operand_1} |&&| \meta{operand_2} \}
+% \end{syntax}
+% If \meta{operand_1} is false (equal to~$\pm 0$), use that value,
+% otherwise the value of \meta{operand_2}. Both \meta{operands} are
+% evaluated in all cases; they may be tuples. In \meta{operand_1}
+% |&&| \meta{operand_2} |&&| \ldots{} |&&| \meta{operands_n}, the
+% first false ($\pm 0$) \meta{operand} is used and if none is zero the
+% last one is used.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-logic001, updated = 2013-12-14]
+% {<, =, >, ?}
+% \begin{syntax}
+% \cs{fp_eval:n} \\
+% ~~\{ \\
+% ~~~~\meta{operand_1} \meta{relation_1} \\
+% ~~~~\ldots{} \\
+% ~~~~\meta{operand_N} \meta{relation_N} \\
+% ~~~~\meta{operand_{N+1}} \\
+% ~~\}
+% \end{syntax}
+% Each \meta{relation} consists of a non-empty string of |<|, |=|,
+% |>|, and~|?|, optionally preceded by~|!|, and may not start
+% with~|?|. This evaluates to $+1$ if all comparisons
+% \meta{operand_i} \meta{relation_i} \meta{operand_{i+1}} are true, and
+% $+0$ otherwise. All \meta{operands} are evaluated (once) in all cases.
+% See \cs{fp_compare:nTF} for details.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-basics001]{+, -}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ \meta{operand_1} |+| \meta{operand_2} \}
+% \cs{fp_eval:n} \{ \meta{operand_1} |-| \meta{operand_2} \}
+% \end{syntax}
+% Computes the sum or the difference of its two \meta{operands}. The
+% \enquote{invalid operation} exception occurs for $\infty-\infty$.
+% \enquote{Underflow} and \enquote{overflow} occur when appropriate.
+% These operations supports the itemwise addition or subtraction of
+% two tuples, but if they have a different number of items the
+% \enquote{invalid operation} exception occurs and the result is \nan{}.
+% \end{function}
+%
+% \begin{function}[tested = {m3fp-basics002, m3fp-basics003}]{*, /}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ \meta{operand_1} |*| \meta{operand_2} \}
+% \cs{fp_eval:n} \{ \meta{operand_1} |/| \meta{operand_2} \}
+% \end{syntax}
+% Computes the product or the ratio of its two \meta{operands}. The
+% \enquote{invalid operation} exception occurs for $\infty/\infty$,
+% $0/0$, or $0*\infty$. \enquote{Division by zero} occurs when
+% dividing a finite non-zero number by $\pm 0$. \enquote{Underflow}
+% and \enquote{overflow} occur when appropriate.
+% When \meta{operand_1} is a tuple and \meta{operand_2} is a floating
+% point number, each item of \meta{operand_1} is multiplied or divided
+% by \meta{operand_2}. Multiplication also supports the case where
+% \meta{operand_1} is a floating point number and \meta{operand_2} a
+% tuple. Other combinations yield an \enquote{invalid operation}
+% exception and a \nan{} result.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-basics004, label = !]{+, -, !}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |+| \meta{operand} \}
+% \cs{fp_eval:n} \{ |-| \meta{operand} \}
+% \cs{fp_eval:n} \{ |!| \meta{operand} \}
+% \end{syntax}
+% The unary |+| does nothing, the unary |-| changes the sign of the
+% \meta{operand} (for a tuple, of all its components), and
+% |!| \meta{operand} evaluates to $1$ if \meta{operand} is false
+% (is $\pm 0$) and $0$ otherwise (this is the \texttt{not}
+% boolean function). Those operations never raise exceptions.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-expo001]{**, ^}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ \meta{operand_1} |**| \meta{operand_2} \}
+% \cs{fp_eval:n} \{ \meta{operand_1} |^| \meta{operand_2} \}
+% \end{syntax}
+% Raises \meta{operand_1} to the power \meta{operand_2}. This
+% operation is right associative, hence \texttt{2 ** 2 ** 3} equals
+% $2^{2^{3}} = 256$. If \meta{operand_1} is negative or $-0$ then:
+% the result's sign is $+$ if the \meta{operand_2} is infinite and
+% $(-1)^p$ if the \meta{operand_2} is $p/5^q$ with $p$, $q$ integers;
+% the result is $+0$ if
+% |abs(|\meta{operand_1}|)^|\meta{operand_2} evaluates to zero; in
+% other cases the \enquote{invalid operation} exception occurs because
+% the sign cannot be determined. \enquote{Division by zero} occurs
+% when raising $\pm 0$ to a finite strictly negative power.
+% \enquote{Underflow} and \enquote{overflow} occur when appropriate.
+% If either operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-basics004]{abs}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |abs(| \meta{fp expr} |)| \}
+% \end{syntax}
+% Computes the absolute value of the \meta{fp expr}. If the operand is
+% a tuple, \enquote{invalid operation} occurs. This operation does
+% not raise exceptions in other cases. See also \cs{fp_abs:n}.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-expo001]{exp}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |exp(| \meta{fp expr} |)| \}
+% \end{syntax}
+% Computes the exponential of the \meta{fp expr}. \enquote{Underflow}
+% and \enquote{overflow} occur when appropriate.
+% If the operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-expo001]{fact}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |fact(| \meta{fp expr} |)| \}
+% \end{syntax}
+% Computes the factorial of the \meta{fp expr}. If the \meta{fp expr}
+% is an integer between $-0$ and $3248$ included, the result is finite
+% and correctly rounded. Larger positive integers give $+\infty$ with
+% \enquote{overflow}, while $|fact(|{+\infty}|)|=+\infty$ and
+% $|fact(nan)|=|nan|$ with no exception. All other inputs give \nan{}
+% with the \enquote{invalid operation} exception.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-expo001]{ln}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |ln(| \meta{fp expr} |)| \}
+% \end{syntax}
+% Computes the natural logarithm of the \meta{fp expr}. Negative
+% numbers have no (real) logarithm, hence the \enquote{invalid
+% operation} is raised in that case, including for $\ln(-0)$.
+% \enquote{Division by zero} occurs when evaluating
+% $\ln(+0) = -\infty$. \enquote{Underflow} and \enquote{overflow}
+% occur when appropriate. If the operand is a tuple, \enquote{invalid
+% operation} occurs.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2018-11-03]{logb}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |logb(| \meta{fp expr} |)| \}
+% \end{syntax}
+% Determines the exponent of the \meta{fp expr}, namely the floor of
+% the base-$10$ logarithm of its absolute value. \enquote{Division by
+% zero} occurs when evaluating $\operatorname{logb}(\pm 0) = -\infty$.
+% Other special values are $\operatorname{logb}(\pm\infty)=+\infty$
+% and $\operatorname{logb}(\nan{})=\nan{}$. If the operand is a tuple
+% or is \nan{}, then \enquote{invalid operation} occurs and the result
+% is \nan{}.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-logic002]{max, min}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |max(| \meta{fp expr_1} |,| \meta{fp expr_2} |,| \ldots{} |)| \}
+% \cs{fp_eval:n} \{ |min(| \meta{fp expr_1} |,| \meta{fp expr_2} |,| \ldots{} |)| \}
+% \end{syntax}
+% Evaluates each \meta{fp expr} and computes the largest (smallest) of
+% those. If any of the \meta{fp expr} is a \nan{} or tuple, the result
+% is \nan{}. If any operand is a tuple, \enquote{invalid operation}
+% occurs; these operations do not raise exceptions in other cases.
+% \end{function}
+%
+% \begin{function}
+% [tested = {m3fp-round001, m3fp-round002}, added = 2013-12-14, updated = 2015-08-08]
+% {round, trunc, ceil, floor}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |round| |(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |round| |(| \meta{fp expr_1} , \meta{fp expr_2} |)| \}
+% \cs{fp_eval:n} \{ |round| |(| \meta{fp expr_1} , \meta{fp expr_2} , \meta{fp expr_3} |)| \}
+% \end{syntax}
+% Only |round| accepts a third argument.
+% Evaluates $\meta{fp expr_1}=x$ and $\meta{fp expr_2}=n$ and $\meta{fp expr_3}=t$ then rounds
+% $x$~to $n$~places. If $n$~is an integer, this rounds~$x$ to a
+% multiple of~$10^{-n}$; if $n=+\infty$, this always yields~$x$; if
+% $n=-\infty$, this yields one of $\pm 0$, $\pm\infty$, or~\nan{}; if
+% $n=\nan{}$, this yields \nan{}; if
+% $n$~is neither $\pm\infty$ nor an integer, then an \enquote{invalid
+% operation} exception is raised. When \meta{fp expr_2} is omitted,
+% $n=0$, \emph{i.e.}, \meta{fp expr_1} is rounded to an integer. The
+% rounding direction depends on the function.
+% \begin{itemize}
+% \item |round| yields the multiple of~$10^{-n}$ closest to~$x$,
+% with ties ($x$ half-way between two such multiples) rounded
+% as follows. If $t$ is \texttt{nan} (or not given) the even
+% multiple is chosen (\enquote{ties to even}), if $t=\pm 0$ the
+% multiple closest to $0$ is chosen (\enquote{ties to zero}),
+% if $t$ is positive/negative the multiple closest to $\infty$/$-\infty$ is chosen
+% (\enquote{ties towards positive/negative infinity}).
+% \item |floor| yields the largest
+% multiple of~$10^{-n}$ smaller or equal to~$x$ (\enquote{round
+% towards negative infinity});
+% \item |ceil| yields the smallest
+% multiple of~$10^{-n}$ greater or equal to~$x$ (\enquote{round
+% towards positive infinity});
+% \item |trunc| yields a multiple
+% of~$10^{-n}$ with the same sign as~$x$ and with the largest
+% absolute value less than that of~$x$ (\enquote{round towards
+% zero}).
+% \end{itemize}
+% \enquote{Overflow} occurs if $x$~is finite and the result is
+% infinite (this can only happen if $\meta{fp expr_2}\string<-9984$).
+% If any operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-logic002]{sign}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |sign(| \meta{fp expr} |)| \}
+% \end{syntax}
+% Evaluates the \meta{fp expr} and determines its sign: $+1$ for
+% positive numbers and for $+\infty$, $-1$ for negative numbers and
+% for $-\infty$, $\pm 0$ for $\pm 0$, and \nan{} for \nan{}.
+% If the operand is a tuple, \enquote{invalid operation} occurs.
+% This operation does not raise exceptions in other cases.
+% \end{function}
+%
+% \begin{function}[updated = 2013-11-17, tested = m3fp-trig001]
+% {sin, cos, tan, cot, csc, sec}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |sin(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |cos(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |tan(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |cot(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |csc(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |sec(| \meta{fp expr} |)| \}
+% \end{syntax}
+% Computes the sine, cosine, tangent, cotangent, cosecant, or secant
+% of the \meta{fp expr} given in radians. For arguments given in
+% degrees, see \texttt{sind}, \texttt{cosd}, \emph{etc.} Note that
+% since $\pi$~is irrational, $\operatorname{sin}(8\mathrm{pi})$ is not quite
+% zero, while its analogue $\operatorname{sind}(8\times 180)$ is exactly
+% zero. The trigonometric functions are undefined for
+% an argument of $\pm\infty$, leading to the \enquote{invalid
+% operation} exception. Additionally, evaluating tangent,
+% cotangent, cosecant, or secant at one of their poles leads to a
+% \enquote{division by zero} exception. \enquote{Underflow} and
+% \enquote{overflow} occur when appropriate.
+% If the operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[added = 2013-11-02, tested = m3fp-trig003]
+% {sind, cosd, tand, cotd, cscd, secd}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |sind(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |cosd(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |tand(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |cotd(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |cscd(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |secd(| \meta{fp expr} |)| \}
+% \end{syntax}
+% Computes the sine, cosine, tangent, cotangent, cosecant, or secant
+% of the \meta{fp expr} given in degrees. For arguments given in
+% radians, see \texttt{sin}, \texttt{cos}, \emph{etc.} Note that
+% since $\pi$~is irrational, $\operatorname{sin}(8\mathrm{pi})$ is not quite
+% zero, while its analogue $\operatorname{sind}(8\times 180)$ is exactly
+% zero. The trigonometric functions are undefined for
+% an argument of $\pm\infty$, leading to the \enquote{invalid
+% operation} exception. Additionally, evaluating tangent,
+% cotangent, cosecant, or secant at one of their poles leads to a
+% \enquote{division by zero} exception. \enquote{Underflow} and
+% \enquote{overflow} occur when appropriate.
+% If the operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[added = 2013-11-02, tested = m3fp-trig002]
+% {asin, acos, acsc, asec}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |asin(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |acos(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |acsc(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |asec(| \meta{fp expr} |)| \}
+% \end{syntax}
+% Computes the arcsine, arccosine, arccosecant, or arcsecant of the
+% \meta{fp expr} and returns the result in radians, in the range
+% $[-\pi/2,\pi/2]$ for \texttt{asin} and \texttt{acsc} and $[0,\pi]$
+% for \texttt{acos} and \texttt{asec}. For a result in degrees, use
+% \texttt{asind}, \emph{etc.} If the argument of |asin| or |acos|
+% lies outside the range $[-1,1]$, or the argument of |acsc| or |asec|
+% inside the range $(-1,1)$, an \enquote{invalid operation} exception
+% is raised. \enquote{Underflow} and \enquote{overflow} occur when
+% appropriate.
+% If the operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[added = 2013-11-02, tested = m3fp-trig004]
+% {asind, acosd, acscd, asecd}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |asind(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |acosd(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |acscd(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |asecd(| \meta{fp expr} |)| \}
+% \end{syntax}
+% Computes the arcsine, arccosine, arccosecant, or arcsecant of the
+% \meta{fp expr} and returns the result in degrees, in the range
+% $[-90,90]$ for \texttt{asind} and \texttt{acscd} and $[0,180]$ for
+% \texttt{acosd} and \texttt{asecd}. For a result in radians, use
+% \texttt{asin}, \emph{etc.} If the argument of |asind| or |acosd| lies
+% outside the range $[-1,1]$, or the argument of |acscd| or |asecd|
+% inside the range $(-1,1)$, an \enquote{invalid operation} exception
+% is raised. \enquote{Underflow} and \enquote{overflow} occur when
+% appropriate.
+% If the operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[added = 2013-11-02, tested = m3fp-trig002]
+% {atan, acot}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |atan(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |atan(| \meta{fp expr_1} , \meta{fp expr_2} |)| \}
+% \cs{fp_eval:n} \{ |acot(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |acot(| \meta{fp expr_1} , \meta{fp expr_2} |)| \}
+% \end{syntax}
+% Those functions yield an angle in radians: \texttt{atand} and
+% \texttt{acotd} are their analogs in degrees. The one-argument
+% versions compute the arctangent or arccotangent of the
+% \meta{fp expr}: arctangent takes values in the range
+% $[-\pi/2,\pi/2]$, and arccotangent in the range $[0,\pi]$. The
+% two-argument arctangent computes the angle in polar coordinates of
+% the point with Cartesian coordinates $(\meta{fp expr_2},
+% \meta{fp expr_1})$: this is the arctangent of
+% $\meta{fp expr_1}/\meta{fp expr_2}$, possibly shifted by~$\pi$
+% depending on the signs of \meta{fp expr_1} and \meta{fp expr_2}. The
+% two-argument arccotangent computes the angle in polar coordinates of
+% the point $(\meta{fp expr_1}, \meta{fp expr_2})$, equal to the
+% arccotangent of $\meta{fp expr_1}/\meta{fp expr_2}$, possibly shifted
+% by~$\pi$. Both two-argument functions take values in the wider
+% range $[-\pi,\pi]$. The ratio $\meta{fp expr_1}/\meta{fp expr_2}$
+% need not be defined for the two-argument arctangent: when both
+% expressions yield~$\pm 0$, or when both yield~$\pm\infty$, the
+% resulting angle is one of $\{\pm\pi/4,\pm 3\pi/4\}$ depending on
+% signs. The \enquote{underflow} exception can occur.
+% If any operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[added = 2013-11-02, tested = m3fp-trig004]
+% {atand, acotd}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |atand(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |atand(| \meta{fp expr_1} , \meta{fp expr_2} |)| \}
+% \cs{fp_eval:n} \{ |acotd(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |acotd(| \meta{fp expr_1} , \meta{fp expr_2} |)| \}
+% \end{syntax}
+% Those functions yield an angle in degrees: \texttt{atan} and
+% \texttt{acot} are their analogs in radians. The one-argument
+% versions compute the arctangent or arccotangent of the
+% \meta{fp expr}: arctangent takes values in the range $[-90,90]$, and
+% arccotangent in the range $[0,180]$. The two-argument arctangent
+% computes the angle in polar coordinates of the point with Cartesian
+% coordinates $(\meta{fp expr_2}, \meta{fp expr_1})$: this is the
+% arctangent of $\meta{fp expr_1}/\meta{fp expr_2}$, possibly shifted
+% by~$180$ depending on the signs of \meta{fp expr_1} and
+% \meta{fp expr_2}. The two-argument arccotangent computes the angle
+% in polar coordinates of the point $(\meta{fp expr_1},
+% \meta{fp expr_2})$, equal to the arccotangent of
+% $\meta{fp expr_1}/\meta{fp expr_2}$, possibly shifted by~$180$. Both
+% two-argument functions take values in the wider range $[-180,180]$.
+% The ratio $\meta{fp expr_1}/\meta{fp expr_2}$ need not be defined for
+% the two-argument arctangent: when both expressions yield~$\pm 0$, or
+% when both yield~$\pm\infty$, the resulting angle is one of $\{\pm
+% 45,\pm 135\}$ depending on signs. The \enquote{underflow}
+% exception can occur.
+% If any operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[added = 2013-12-14, tested = m3fp-basics005]{sqrt}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |sqrt(| \meta{fp expr} |)| \}
+% \end{syntax}
+% Computes the square root of the \meta{fp expr}. The \enquote{invalid
+% operation} is raised when the \meta{fp expr} is negative or is a tuple; no other
+% exception can occur. Special values yield $\sqrt{-0} = -0$,
+% $\sqrt{+0} = +0$, $\sqrt{+\infty} = +\infty$ and
+% $\sqrt{\text{\nan{}}}=\text{\nan{}}$.
+% \end{function}
+%
+% \begin{function}[added = 2016-12-05]{rand}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |rand()| \}
+% \end{syntax}
+% Produces a pseudo-random floating-point number (multiple of
+% $10^{-16}$) between $0$~included and $1$~excluded. This is not available
+% in older versions of \XeTeX{}. The random seed can be queried using
+% \cs{sys_rand_seed:} and set using \cs{sys_gset_rand_seed:n}.
+% \begin{texnote}
+% This is based on pseudo-random numbers provided by the engine's
+% primitive \tn{pdfuniformdeviate} in \pdfTeX{}, \pTeX{}, \upTeX{}
+% and \tn{uniformdeviate} in \LuaTeX{} and \XeTeX{}. The underlying code is
+% based on Metapost, which follows an additive scheme recommended in
+% Section 3.6 of \enquote{The Art of Computer Programming,
+% Volume~2}.
+%
+% While we are more careful than \tn{uniformdeviate} to preserve
+% uniformity of the underlying stream of $28$-bit pseudo-random
+% integers, these pseudo-random numbers should of course not be
+% relied upon for serious numerical computations nor cryptography.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2016-12-05]{randint}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |randint(| \meta{fp expr} |)| \}
+% \cs{fp_eval:n} \{ |randint(| \meta{fp expr_1} , \meta{fp expr_2} |)| \}
+% \end{syntax}
+% Produces a pseudo-random integer between $1$~and \meta{fp expr} or
+% between \meta{fp expr_1} and \meta{fp expr_2} inclusive. The bounds
+% must be integers in the range $(-10^{16},10^{16})$ and the first
+% must be smaller or equal to the second. See \texttt{rand} for
+% important comments on how these pseudo-random numbers are generated.
+% \end{function}
+%
+% \begin{variable}[tested = m3fp-parse001]{inf, nan}
+% The special values $+\infty$, $-\infty$, and \nan{} are represented
+% as \texttt{inf}, \texttt{-inf} and \texttt{nan} (see \cs[module = fp]{c_inf_fp},
+% \cs[module = fp]{c_minus_inf_fp} and \cs[module = fp]{c_nan_fp}).
+% \end{variable}
+%
+% \begin{variable}[tested = m3fp-parse001]{pi}
+% The value of $\pi$ (see \cs[module = fp]{c_pi_fp}).
+% \end{variable}
+%
+% \begin{variable}[tested = m3fp-parse001]{deg}
+% The value of $1^{\circ}$ in radians (see \cs[module = fp]{c_one_degree_fp}).
+% \end{variable}
+%
+% \begin{variable}[tested = m3fp-parse001]
+% {em, ex, in, pt, pc, cm, mm, dd, cc, nd, nc, bp, sp}
+% \newcommand{\unit}[1]{\ifmmode\,\fi\text{\texttt{#1}}}
+% Those units of measurement are equal to their values in \unit{pt},
+% namely
+% \begin{align*}
+% 1 \unit{in} & = 72.27 \unit{pt} \\
+% 1 \unit{pt} & = 1 \unit{pt} \\
+% 1 \unit{pc} & = 12 \unit{pt} \\
+% 1 \unit{cm} & = \frac{1}{2.54} \unit{in} = 28.45275590551181 \unit{pt} \\
+% 1 \unit{mm} & = \frac{1}{25.4} \unit{in} = 2.845275590551181 \unit{pt} \\
+% 1 \unit{dd} & = 0.376065 \unit{mm} = 1.07000856496063 \unit{pt} \\
+% 1 \unit{cc} & = 12 \unit{dd} = 12.84010277952756 \unit{pt} \\
+% 1 \unit{nd} & = 0.375 \unit{mm} = 1.066978346456693 \unit{pt} \\
+% 1 \unit{nc} & = 12 \unit{nd} = 12.80374015748031 \unit{pt} \\
+% 1 \unit{bp} & = \frac{1}{72} \unit{in} = 1.00375 \unit{pt} \\
+% 1 \unit{sp} & = 2^{-16} \unit{pt} = 1.52587890625 \times 10^{-5} \unit{pt}.
+% \end{align*}
+% The values of the (font-dependent) units \unit{em} and \unit{ex} are
+% gathered from \TeX{} when the surrounding floating point expression
+% is evaluated.
+% \end{variable}
+%
+% \begin{variable}[tested = m3fp-parse001]{true, false}
+% Other names for $1$ and $+0$.
+% \end{variable}
+%
+% \begin{function}[EXP, added = 2012-05-14, updated = 2012-07-08,
+% tested = m3fp-convert003]{\fp_abs:n}
+% \begin{syntax}
+% \cs{fp_abs:n} \Arg{fp expr}
+% \end{syntax}
+% Evaluates the \meta{fp expr} as described for
+% \cs{fp_eval:n} and leaves the absolute value of the result in the
+% input stream. If the argument is $\pm\infty$, \nan{} or a tuple,
+% \enquote{invalid operation} occurs. Within floating point
+% expressions, |abs()| can be used; it accepts $\pm\infty$ and \nan{}
+% as arguments.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2012-09-26, tested = m3fp-convert003]
+% {\fp_max:nn, \fp_min:nn}
+% \begin{syntax}
+% \cs{fp_max:nn} \Arg{fp expr_1} \Arg{fp expr_2}
+% \end{syntax}
+% Evaluates the \meta{fp exprs} as described for
+% \cs{fp_eval:n} and leaves the resulting larger (\texttt{max}) or
+% smaller (\texttt{min}) value in the input stream. If the argument
+% is a tuple, \enquote{invalid operation} occurs, but no other case
+% raises exceptions. Within floating point expressions, |max()| and
+% |min()| can be used.
+% \end{function}
+%
+% \section{Disclaimer and roadmap}
+%
+% This module may break if the escape character is among
+% |0123456789_+|, or if it receives a \TeX{} primitive conditional affected
+% by \cs{exp_not:N}.
+%
+% The following need to be done. I'll try to time-order the items.
+% \begin{itemize}
+% \item Function to count items in a tuple (and to determine if something is a tuple).
+% \item Decide what exponent range to consider.
+% \item Support signalling \texttt{nan}.
+% \item Modulo and remainder, and rounding function |quantize| (and its friends analogous to |trunc|, |ceil|, |floor|).
+% \item \cs{fp_format:nn} \Arg{fp expr} \Arg{format}, but what should
+% \meta{format} be? More general pretty printing?
+% \item Add |and|, |or|, |xor|? Perhaps under the names \texttt{all},
+% \texttt{any}, and \texttt{xor}?
+% \item Add $\log(x,b)$ for logarithm of $x$ in base $b$.
+% \item \texttt{hypot} (Euclidean length).
+% Cartesian-to-polar transform.
+% \item Hyperbolic functions \texttt{cosh}, \texttt{sinh}, \texttt{tanh}.
+% \item Inverse hyperbolics.
+% \item Base conversion, input such as \texttt{0xAB.CDEF}.
+% \item Factorial (not with |!|), gamma function.
+% \item Improve coefficients of the \texttt{sin} and \texttt{tan}
+% series.
+% \item Treat upper and lower case letters identically in
+% identifiers, and ignore underscores.
+% \item Add an |array(1,2,3)| and |i=complex(0,1)|.
+% \item Provide an experimental |map| function? Perhaps easier to
+% implement if it is a single character, |@sin(1,2)|?
+% \item Provide an |isnan| function analogue of \cs{fp_if_nan:nTF}?
+% \item Support keyword arguments?
+% \end{itemize}
+% \pkg{Pgfmath} also provides box-measurements (depth, height, width), but
+% boxes are not possible expandably.
+%
+% Bugs, and tests to add.
+% \begin{itemize}
+% \item Check that functions are monotonic when they should.
+% \item Add exceptions to |?:|, |!<=>?|, |&&|, \verb"||", and |!|.
+% \item Logarithms of numbers very close to $1$ are inaccurate.
+% \item When rounding towards $-\infty$, |\dim_to_fp:n {0pt}| should
+% return $-0$, not $+0$.
+% \item The result of $(\pm0)+(\pm0)$, of $x+(-x)$, and of $(-x)+x$
+% should depend on the rounding mode.
+% \item \texttt{0e9999999999} gives a \TeX{} \enquote{number too
+% large} error.
+% \item Subnormals are not implemented.
+% \end{itemize}
+%
+% Possible optimizations/improvements.
+% \begin{itemize}
+% \item Document that \pkg{l3trial/l3fp-types} introduces tools for
+% adding new types.
+% \item In subsection~\ref{sec:l3fp:fp-floats}, write a grammar.
+% \item It would be nice if the \texttt{parse} auxiliaries for each
+% operation were set up in the corresponding module, rather than
+% centralizing in \pkg{l3fp-parse}.
+% \item Some functions should get an |_o| ending to indicate that they
+% expand after their result.
+% \item More care should be given to distinguish expandable/restricted
+% expandable (auxiliary and internal) functions.
+% \item The code for the \texttt{ternary} set of functions is ugly.
+% \item There are many |~| missing in the doc to avoid bad line-breaks.
+% \item The algorithm for computing the logarithm of the significand
+% could be made to use a $5$ terms Taylor series instead of $10$
+% terms by taking $c = 2000/(\lfloor 200x\rfloor +1) \in [10,95]$
+% instead of $c\in [1,10]$. Also, it would then be possible to
+% simplify the computation of $t$. However, we would then have to
+% hard-code the logarithms of $44$ small integers instead of $9$.
+% \item Improve notations in the explanations of the division
+% algorithm (\pkg{l3fp-basics}).
+% \item Understand and document \cs[no-index]{__fp_basics_pack_weird_low:NNNNw}
+% and \cs[no-index]{__fp_basics_pack_weird_high:NNNNNNNNw} better. Move the
+% other \texttt{basics_pack} auxiliaries to \pkg{l3fp-aux} under a
+% better name.
+% \item Find out if underflow can really occur for trigonometric
+% functions, and redoc as appropriate.
+% \item Add bibliography. Some of Kahan's articles, some previous
+% \TeX{} fp packages, the international standards,\ldots{}
+% \item Also take into account the \enquote{inexact} exception?
+% \item Support multi-character prefix operators (\emph{e.g.}, |@/| or
+% whatever)?
+% \end{itemize}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp} implementation}
+%
+% Nothing to see here: everything is in the subfiles!
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3fparray.dtx b/macros/latex-dev/required/l3kernel/l3fparray.dtx
new file mode 100644
index 0000000000..24f4ac85f8
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3fparray.dtx
@@ -0,0 +1,427 @@
+% \iffalse meta-comment
+%
+%% File: l3fparray.dtx
+%
+% Copyright (C) 2018-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+%
+% \title{^^A
+% The \pkg{l3fparray} module\\ Fast global floating point arrays^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% For applications requiring heavy use of floating points, this module
+% provides arrays which can be accessed in constant time (contrast
+% \pkg{l3seq}, where access time is linear). The interface is very
+% close to that of \pkg{l3intarray}. The size of the array is fixed and
+% must be given at point of initialisation
+%
+% \section{Creating and initialising floating point array variables}
+%
+% \begin{function}[added = 2018-05-05]{\fparray_new:Nn, \fparray_new:cn}
+% \begin{syntax}
+% \cs{fparray_new:Nn} \meta{fparray~var} \Arg{size}
+% \end{syntax}
+% Evaluates the integer expression \meta{size} and allocates an
+% \meta{floating point array variable} with that number of (zero)
+% entries. The variable name should start with |\g_| because
+% assignments are always global.
+% \end{function}
+%
+% \begin{function}[added = 2018-05-05]{\fparray_gzero:N, \fparray_gzero:c}
+% \begin{syntax}
+% \cs{fparray_gzero:N} \meta{fparray~var}
+% \end{syntax}
+% Sets all entries of the \meta{floating point array variable} to
+% $+0$. Assignments are always global.
+% \end{function}
+%
+% \section{Adding data to floating point arrays}
+%
+% \begin{function}[added = 2018-05-05]{\fparray_gset:Nnn, \fparray_gset:cnn}
+% \begin{syntax}
+% \cs{fparray_gset:Nnn} \meta{fparray~var} \Arg{position} \Arg{value}
+% \end{syntax}
+% Stores the result of evaluating the floating point expression
+% \meta{value} into the \meta{floating point array variable} at the
+% (integer expression) \meta{position}. If the \meta{position} is not
+% between $1$ and the \cs{fparray_count:N}, an error occurs.
+% Assignments are always global.
+% \end{function}
+%
+% \section{Couting entries in floating point arrays}
+%
+% \begin{function}[EXP, added = 2018-05-05]{\fparray_count:N, \fparray_count:c}
+% \begin{syntax}
+% \cs{fparray_count:N} \meta{fparray~var}
+% \end{syntax}
+% Expands to the number of entries in the \meta{floating point array
+% variable}. This is performed in constant time.
+% \end{function}
+%
+% \section{Using a single entry}
+%
+% \begin{function}[EXP, added = 2018-05-05]
+% {
+% \fparray_item:Nn, \fparray_item:cn,
+% \fparray_item_to_tl:Nn, \fparray_item_to_tl:cn
+% }
+% \begin{syntax}
+% \cs{fparray_item:Nn} \meta{fparray~var} \Arg{position}
+% \end{syntax}
+% Applies \cs{fp_use:N} or \cs{fp_to_tl:N} (respectively) to the
+% floating point entry stored at the (integer expression)
+% \meta{position} in the \meta{floating point array variable}. If the
+% \meta{position} is not between $1$ and the
+% \cs{fparray_count:N} \meta{fparray~var}, an error occurs.
+% \end{function}
+%
+% \section{Floating point array conditional}
+%
+% \begin{function}[pTF, added = 2024-03-31]
+% {\fparray_if_exist:N, \fparray_if_exist:c}
+% \begin{syntax}
+% \cs{fparray_if_exist_p:N} \meta{fparray~var}
+% \cs{fparray_if_exist:NTF} \meta{fparray~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{fparray~var} is currently defined. This
+% does not check that the \meta{fparray~var} really is a floating
+% point array variable.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fparray} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=fp>
+% \end{macrocode}
+%
+% In analogy to \pkg{l3intarray} it would make sense to have
+% |<@@=fparray>|, but we need direct access to \cs{@@_parse:n} from
+% \pkg{l3fp-parse}, and a few other (less crucial) internals of the
+% \pkg{l3fp} family.
+%
+% \subsection{Allocating arrays}
+%
+% There are somewhat more than $(2^{31}-1)^2$ floating point numbers so
+% we store each floating point number as three entries in integer
+% arrays. To avoid having to multiply indices by three or to add 1 etc,
+% a floating point array is just a token list consisting of three
+% tokens: integer arrays of the same size.
+%
+% \begin{variable}{\g_@@_array_int}
+% Used to generate unique names for the three integer arrays.
+% \begin{macrocode}
+\int_new:N \g_@@_array_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_array_loop_int}
+% Used to loop in \cs{@@_array_gzero:N}.
+% \begin{macrocode}
+\int_new:N \l_@@_array_loop_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\fparray_new:Nn, \fparray_new:cn}
+% \begin{macro}{\@@_array_new:nNNN}
+% Build a three-token token list, then define all three tokens to be
+% integer arrays of the same size. No need to initialize the data:
+% the integer arrays start with zeros, and three zeros denote
+% precisely \cs{c_zero_fp}, as we want.
+% \begin{macrocode}
+\cs_new_protected:Npn \fparray_new:Nn #1#2
+ {
+ \tl_new:N #1
+ \prg_replicate:nn { 3 }
+ {
+ \int_gincr:N \g_@@_array_int
+ \exp_args:NNc \tl_gput_right:Nn #1
+ { g_@@_array_ \@@_int_to_roman:w \g_@@_array_int _intarray }
+ }
+ \exp_last_unbraced:Nfo \@@_array_new:nNNNN
+ { \int_eval:n {#2} } #1 #1
+ }
+\cs_generate_variant:Nn \fparray_new:Nn { c }
+\cs_new_protected:Npn \@@_array_new:nNNNN #1#2#3#4#5
+ {
+ \int_compare:nNnTF {#1} < 0
+ {
+ \msg_error:nnn { kernel } { negative-array-size } {#1}
+ \cs_undefine:N #1
+ \int_gsub:Nn \g_@@_array_int { 3 }
+ }
+ {
+ \intarray_new:Nn #2 {#1}
+ \intarray_new:Nn #3 {#1}
+ \intarray_new:Nn #4 {#1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\fparray_count:N, \fparray_count:c}
+% Size of any of the intarrays, here we pick the third.
+% \begin{macrocode}
+\cs_new:Npn \fparray_count:N #1
+ {
+ \exp_after:wN \use_i:nnn
+ \exp_after:wN \intarray_count:N #1
+ }
+\cs_generate_variant:Nn \fparray_count:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Array items}
+%
+% \begin{macro}[EXP]{\@@_array_bounds:NNnTF, \@@_array_bounds_error:NNn}
+% See the \pkg{l3intarray} analogue: only names change.
+% The functions \cs{fparray_gset:Nnn} and \cs{fparray_item:Nn} share
+% bounds checking. The |T| branch is used if |#3| is within bounds of
+% the array |#2|.
+% \begin{macrocode}
+\cs_new:Npn \@@_array_bounds:NNnTF #1#2#3#4#5
+ {
+ \if_int_compare:w 1 > #3 \exp_stop_f:
+ \@@_array_bounds_error:NNn #1 #2 {#3}
+ #5
+ \else:
+ \if_int_compare:w #3 > \fparray_count:N #2 \exp_stop_f:
+ \@@_array_bounds_error:NNn #1 #2 {#3}
+ #5
+ \else:
+ #4
+ \fi:
+ \fi:
+ }
+\cs_new:Npn \@@_array_bounds_error:NNn #1#2#3
+ {
+ #1 { kernel } { out-of-bounds }
+ { \token_to_str:N #2 } {#3} { \fparray_count:N #2 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fparray_gset:Nnn, \fparray_gset:cnn}
+% \begin{macro}
+% {
+% \@@_array_gset:NNNNww, \@@_array_gset:w,
+% \@@_array_gset_recover:Nw, \@@_array_gset_special:nnNNN,
+% \@@_array_gset_normal:w
+% }
+% Evaluate, then store exponent in one intarray, sign and $8$ digits
+% of mantissa in the next, and $8$ trailing digits in the last.
+% \begin{macrocode}
+\cs_new_protected:Npn \fparray_gset:Nnn #1#2#3
+ {
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_array_gset:NNNNww
+ \exp_after:wN #1
+ \exp_after:wN #1
+ \int_value:w \int_eval:n {#2} \exp_after:wN ;
+ \exp:w \exp_end_continue_f:w \@@_parse:n {#3}
+ }
+\cs_generate_variant:Nn \fparray_gset:Nnn { c }
+\cs_new_protected:Npn \@@_array_gset:NNNNww #1#2#3#4#5 ; #6 ;
+ {
+ \@@_array_bounds:NNnTF \msg_error:nneee #4 {#5}
+ {
+ \exp_after:wN \@@_change_func_type:NNN
+ \@@_use_i_until_s:nw #6 ;
+ \@@_array_gset:w
+ \@@_array_gset_recover:Nw
+ #6 ; {#5} #1 #2 #3
+ }
+ { }
+ }
+\cs_new_protected:Npn \@@_array_gset_recover:Nw #1#2 ;
+ {
+ \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+ \exp_after:wN #1 \c_nan_fp
+ }
+\cs_new_protected:Npn \@@_array_gset:w \s_@@ \@@_chk:w #1#2
+ {
+ \if_case:w #1 \exp_stop_f:
+ \@@_case_return:nw { \@@_array_gset_special:nnNNN {#2} }
+ \or: \exp_after:wN \@@_array_gset_normal:w
+ \or: \@@_case_return:nw { \@@_array_gset_special:nnNNN { #2 3 } }
+ \or: \@@_case_return:nw { \@@_array_gset_special:nnNNN { 1 } }
+ \fi:
+ \s_@@ \@@_chk:w #1 #2
+ }
+\cs_new_protected:Npn \@@_array_gset_normal:w
+ \s_@@ \@@_chk:w 1 #1 #2 #3#4#5 ; #6#7#8#9
+ {
+ \__kernel_intarray_gset:Nnn #7 {#6} {#2}
+ \__kernel_intarray_gset:Nnn #8 {#6}
+ { \if_meaning:w 2 #1 3 \else: 1 \fi: #3#4 }
+ \__kernel_intarray_gset:Nnn #9 {#6} { 1 \use:nn #5 }
+ }
+\cs_new_protected:Npn \@@_array_gset_special:nnNNN #1#2#3#4#5
+ {
+ \__kernel_intarray_gset:Nnn #3 {#2} {#1}
+ \__kernel_intarray_gset:Nnn #4 {#2} {0}
+ \__kernel_intarray_gset:Nnn #5 {#2} {0}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fparray_gzero:N, \fparray_gzero:c}
+% \begin{macrocode}
+\cs_new_protected:Npn \fparray_gzero:N #1
+ {
+ \int_zero:N \l_@@_array_loop_int
+ \prg_replicate:nn { \fparray_count:N #1 }
+ {
+ \int_incr:N \l_@@_array_loop_int
+ \exp_after:wN \@@_array_gset_special:nnNNN
+ \exp_after:wN 0
+ \exp_after:wN \l_@@_array_loop_int
+ #1
+ }
+ }
+\cs_generate_variant:Nn \fparray_gzero:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \fparray_item:Nn,
+% \fparray_item:cn,
+% \fparray_item_to_tl:Nn,
+% \fparray_item_to_tl:cn,
+% }
+% \begin{macro}[EXP]
+% {
+% \@@_array_item:NwN,
+% \@@_array_item:NNNnN,
+% \@@_array_item:N,
+% \@@_array_item:w,
+% \@@_array_item_special:w,
+% \@@_array_item_normal:w
+% }
+% \begin{macrocode}
+\cs_new:Npn \fparray_item:Nn #1#2
+ {
+ \exp_after:wN \@@_array_item:NwN
+ \exp_after:wN #1
+ \int_value:w \int_eval:n {#2} ;
+ \@@_to_decimal:w
+ }
+\cs_generate_variant:Nn \fparray_item:Nn { c }
+\cs_new:Npn \fparray_item_to_tl:Nn #1#2
+ {
+ \exp_after:wN \@@_array_item:NwN
+ \exp_after:wN #1
+ \int_value:w \int_eval:n {#2} ;
+ \@@_to_tl:w
+ }
+\cs_generate_variant:Nn \fparray_item_to_tl:Nn { c }
+\cs_new:Npn \@@_array_item:NwN #1#2 ; #3
+ {
+ \@@_array_bounds:NNnTF \msg_expandable_error:nnfff #1 {#2}
+ { \exp_after:wN \@@_array_item:NNNnN #1 {#2} #3 }
+ { \exp_after:wN #3 \c_nan_fp }
+ }
+\cs_new:Npn \@@_array_item:NNNnN #1#2#3#4
+ {
+ \exp_after:wN \@@_array_item:N
+ \int_value:w \__kernel_intarray_item:Nn #2 {#4} \exp_after:wN ;
+ \int_value:w \__kernel_intarray_item:Nn #3 {#4} \exp_after:wN ;
+ \int_value:w \__kernel_intarray_item:Nn #1 {#4} ;
+ }
+\cs_new:Npn \@@_array_item:N #1
+ {
+ \if_meaning:w 0 #1 \exp_after:wN \@@_array_item_special:w \fi:
+ \@@_array_item:w #1
+ }
+\cs_new:Npn \@@_array_item:w #1 #2#3#4#5 #6 ; 1 #7 ;
+ {
+ \exp_after:wN \@@_array_item_normal:w
+ \int_value:w \if_meaning:w #1 1 0 \else: 2 \fi: \exp_stop_f:
+ #7 ; {#2#3#4#5} {#6} ;
+ }
+\cs_new:Npn \@@_array_item_special:w #1 ; #2 ; #3 ; #4
+ {
+ \exp_after:wN #4
+ \exp:w \exp_end_continue_f:w
+ \if_case:w #3 \exp_stop_f:
+ \exp_after:wN \c_zero_fp
+ \or: \exp_after:wN \c_nan_fp
+ \or: \exp_after:wN \c_minus_zero_fp
+ \or: \exp_after:wN \c_inf_fp
+ \else: \exp_after:wN \c_minus_inf_fp
+ \fi:
+ }
+\cs_new:Npn \@@_array_item_normal:w #1 #2#3#4#5 #6 ; #7 ; #8 ; #9
+ { #9 \s_@@ \@@_chk:w 1 #1 {#8} #7 {#2#3#4#5} {#6} ; }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\fparray_if_exist:N, \fparray_if_exist:c}
+% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \fparray_if_exist:N \cs_if_exist:N
+ { TF , T , F , p }
+\prg_new_eq_conditional:NNn \fparray_if_exist:c \cs_if_exist:c
+ { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3int.dtx b/macros/latex-dev/required/l3kernel/l3int.dtx
new file mode 100644
index 0000000000..a1c9458436
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3int.dtx
@@ -0,0 +1,2679 @@
+% \iffalse meta-comment
+%
+%% File: l3int.dtx
+%
+% Copyright (C) 1990-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3int} module\\ Integers^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% Calculation and comparison of integer values can be carried out
+% using literal numbers, \texttt{int} registers, constants and
+% integers stored in token list variables. The standard operators
+% \texttt{+}, \texttt{-}, \texttt{/} and \texttt{*} and
+% parentheses can be used within such expressions to carry
+% arithmetic operations. This module carries out these functions
+% on \emph{integer expressions} (\enquote{\meta{int expr}}).
+%
+% \section{Integer expressions}
+%
+% Throughout this module, (almost) all \texttt{n}-type argument allow
+% for an \meta{intexpr} argument with the following syntax. The
+% \meta{integer expression} should consist,
+% after expansion, of \texttt{+}, \texttt{-}, \texttt{*}, \texttt{/},
+% \texttt{(}, \texttt{)} and of course integer operands. The result
+% is calculated by applying standard mathematical rules with the
+% following peculiarities:
+% \begin{itemize}
+% \item \texttt{/} denotes division rounded to the closest integer with
+% ties rounded away from zero;
+% \item there is an error and the overall expression evaluates to zero
+% whenever the absolute value of any intermediate result exceeds
+% $2^{31}-1$, except in the case of scaling operations
+% $a$\texttt{*}$b$\texttt{/}$c$, for which $a$\texttt{*}$b$ may be
+% arbitrarily large (but the operands $a$, $b$, $c$ are still
+% constrained to an absolute value at most $2^{31}-1$);
+% \item parentheses may not appear after unary \texttt{+} or
+% \texttt{-}, namely placing \texttt{+(} or \texttt{-(} at the start
+% of an expression or after \texttt{+}, \texttt{-}, \texttt{*},
+% \texttt{/} or~\texttt{(} leads to an error.
+% \end{itemize}
+% Each integer operand can be either an integer variable (with no need
+% for \cs{int_use:N}) or an integer denotation. For example both
+% \begin{verbatim}
+% \int_show:n { 5 + 4 * 3 - ( 3 + 4 * 5 ) }
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% \tl_new:N \l_my_tl
+% \tl_set:Nn \l_my_tl { 5 }
+% \int_new:N \l_my_int
+% \int_set:Nn \l_my_int { 4 }
+% \int_show:n { \l_my_tl + \l_my_int * 3 - ( 3 + 4 * 5 ) }
+% \end{verbatim}
+% show the same result $-6$ because \cs[no-index]{l_my_tl} expands to
+% the integer denotation~|5| while the integer variable \cs[no-index]{l_my_int}
+% takes the value~$4$. As the \meta{integer expression} is fully
+% expanded from left to right during evaluation, fully expandable and
+% restricted-expandable functions can both be used, and \cs{exp_not:n}
+% and its variants have no effect while \cs{exp_not:N} may incorrectly
+% interrupt the expression.
+% \begin{texnote}
+% Exactly two expansions are needed to evaluate \cs{int_eval:n}.
+% The result is \emph{not} an \meta{internal integer}, and therefore
+% should be terminated by a space if used in \cs{int_value:w} or in
+% a \TeX{}-style integer assignment.
+%
+% As all \TeX{} integers, integer operands can also be:
+% \tn{value}\Arg{\LaTeXe{} counter}; dimension or skip variables,
+% converted to integers in~\texttt{sp}; the character code of some
+% character given as \texttt{`}\meta{char} or
+% \texttt{`\textbackslash}\meta{char}; octal numbers given as
+% \texttt{'} followed by digits from \texttt{0} to \texttt{7}; or
+% hexadecimal numbers given as |"| followed by digits and upper case
+% letters from \texttt{A} to~\texttt{F}.
+% \end{texnote}
+%
+% \begin{function}[EXP]{\int_eval:n}
+% \begin{syntax}
+% \cs{int_eval:n} \Arg{int expr}
+% \end{syntax}
+% Evaluates the \meta{int expr} and leaves the result in the
+% input stream as an integer denotation: for positive results an
+% explicit sequence of decimal digits not starting with~\texttt{0},
+% for negative results \texttt{-}~followed by such a sequence, and
+% \texttt{0}~for zero. The \meta{int expr} should consist,
+% after expansion, of \texttt{+}, \texttt{-}, \texttt{*}, \texttt{/},
+% \texttt{(}, \texttt{)} and of course integer operands. The result
+% is calculated by applying standard mathematical rules with the
+% following peculiarities:
+% \begin{itemize}
+% \item \texttt{/} denotes division rounded to the closest integer with
+% ties rounded away from zero;
+% \item there is an error and the overall expression evaluates to zero
+% whenever the absolute value of any intermediate result exceeds
+% $2^{31}-1$, except in the case of scaling operations
+% $a$\texttt{*}$b$\texttt{/}$c$, for which $a$\texttt{*}$b$ may be
+% arbitrarily large;
+% \item parentheses may not appear after unary \texttt{+} or
+% \texttt{-}, namely placing \texttt{+(} or \texttt{-(} at the start
+% of an expression or after \texttt{+}, \texttt{-}, \texttt{*},
+% \texttt{/} or~\texttt{(} leads to an error.
+% \end{itemize}
+% Each integer operand can be either an integer variable (with no need
+% for \cs{int_use:N}) or an integer denotation. For example both
+% \begin{verbatim}
+% \int_eval:n { 5 + 4 * 3 - ( 3 + 4 * 5 ) }
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% \tl_new:N \l_my_tl
+% \tl_set:Nn \l_my_tl { 5 }
+% \int_new:N \l_my_int
+% \int_set:Nn \l_my_int { 4 }
+% \int_eval:n { \l_my_tl + \l_my_int * 3 - ( 3 + 4 * 5 ) }
+% \end{verbatim}
+% evaluate to $-6$ because \cs[no-index]{l_my_tl} expands to the
+% integer denotation~|5|. As the \meta{int expr} is fully
+% expanded from left to right during evaluation, fully expandable and
+% restricted-expandable functions can both be used, and \cs{exp_not:n}
+% and its variants have no effect while \cs{exp_not:N} may incorrectly
+% interrupt the expression.
+% \begin{texnote}
+% Exactly two expansions are needed to evaluate \cs{int_eval:n}.
+% The result is \emph{not} an \meta{internal integer}, and therefore
+% requires suitable termination if used in a \TeX{}-style integer
+% assignment.
+%
+% As all \TeX{} integers, integer operands can also be dimension or
+% skip variables, converted to integers in~\texttt{sp}, or octal
+% numbers given as \texttt{'} followed by digits other than
+% \texttt{8} and \texttt{9}, or hexadecimal numbers given as
+% |"| followed by digits or upper case letters from
+% \texttt{A} to~\texttt{F}, or the character code of some character
+% or one-character control sequence, given as \texttt{`}\meta{char}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2018-03-30]{\int_eval:w}
+% \begin{syntax}
+% \cs{int_eval:w} \meta{int expr}
+% \end{syntax}
+% Evaluates the \meta{int expr} as described for
+% \cs{int_eval:n}. The end of the expression is the first token
+% encountered that cannot form part of such an expression. If that
+% token is \cs{scan_stop:} it is removed, otherwise not. Spaces do
+% \emph{not} terminate the expression. However, spaces terminate
+% explict integers, and this may terminate the expression: for
+% instance, \cs{int_eval:w} \verb*|1 + 1 9| (with explicit space
+% tokens inserted using |~| in a code setting) expands to \texttt{29}
+% since the digit~\texttt{9} is not part of the expression. Expansion
+% details, etc., are as given for \cs{int_eval:n}.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2018-11-03]{\int_sign:n}
+% \begin{syntax}
+% \cs{int_sign:n} \Arg{int expr}
+% \end{syntax}
+% Evaluates the \meta{int expr} then leaves $1$ or $0$ or
+% $-1$ in the input stream according to the sign of the result.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2012-09-26]{\int_abs:n}
+% \begin{syntax}
+% \cs{int_abs:n} \Arg{int expr}
+% \end{syntax}
+% Evaluates the \meta{int expr} as described for
+% \cs{int_eval:n} and leaves the absolute value of the result in
+% the input stream as an \meta{integer denotation} after two
+% expansions.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2012-09-26]{\int_div_round:nn}
+% \begin{syntax}
+% \cs{int_div_round:nn} \Arg{int expr_1} \Arg{int expr_2}
+% \end{syntax}
+% Evaluates the two \meta{int expr}s as described earlier,
+% then divides the first value by the second, and rounds the result
+% to the closest integer. Ties are rounded away from zero.
+% Note that this is identical to using
+% |/| directly in an \meta{int expr}. The result is left in
+% the input stream as an \meta{integer denotation} after two expansions.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2012-02-09]{\int_div_truncate:nn}
+% \begin{syntax}
+% \cs{int_div_truncate:nn} \Arg{int expr_1} \Arg{int expr_2}
+% \end{syntax}
+% Evaluates the two \meta{int expr}s as described earlier,
+% then divides the first value by the second, and rounds the result
+% towards zero. Note that division using |/|
+% rounds to the closest integer instead.
+% The result is left in the input stream as an
+% \meta{integer denotation} after two expansions.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2012-09-26]{\int_max:nn, \int_min:nn}
+% \begin{syntax}
+% \cs{int_max:nn} \Arg{int expr_1} \Arg{int expr_2}
+% \cs{int_min:nn} \Arg{int expr_1} \Arg{int expr_2}
+% \end{syntax}
+% Evaluates the \meta{int expr}s as described for
+% \cs{int_eval:n} and leaves either the larger or smaller value
+% in the input stream as an \meta{integer denotation} after two
+% expansions.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2012-09-26]{\int_mod:nn}
+% \begin{syntax}
+% \cs{int_mod:nn} \Arg{int expr_1} \Arg{int expr_2}
+% \end{syntax}
+% Evaluates the two \meta{int expr}s as described earlier,
+% then calculates the integer remainder of dividing the first
+% expression by the second. This is obtained by subtracting
+% \cs{int_div_truncate:nn} \Arg{int expr_1} \Arg{int expr_2} times
+% \meta{int expr_2} from \meta{int expr_1}. Thus, the result has the
+% same sign as \meta{int expr_1} and its absolute value is strictly
+% less than that of \meta{int expr_2}. The result is left in the input
+% stream as an \meta{integer denotation} after two expansions.
+% \end{function}
+%
+% \section{Creating and initialising integers}
+%
+% \begin{function}{\int_new:N, \int_new:c}
+% \begin{syntax}
+% \cs{int_new:N} \meta{integer}
+% \end{syntax}
+% Creates a new \meta{integer} or raises an error if the name is
+% already taken. The declaration is global. The \meta{integer} is
+% initially equal to $0$.
+% \end{function}
+%
+% \begin{function}[updated = 2011-10-22]{\int_const:Nn, \int_const:cn}
+% \begin{syntax}
+% \cs{int_const:Nn} \meta{integer} \Arg{int expr}
+% \end{syntax}
+% Creates a new constant \meta{integer} or raises an error if the name
+% is already taken. The value of the \meta{integer} is set
+% globally to the \meta{int expr}.
+% \end{function}
+%
+% \begin{function}{\int_zero:N, \int_zero:c, \int_gzero:N, \int_gzero:c}
+% \begin{syntax}
+% \cs{int_zero:N} \meta{integer}
+% \end{syntax}
+% Sets \meta{integer} to $0$.
+% \end{function}
+%
+% \begin{function}[added = 2011-12-13]
+% {\int_zero_new:N, \int_zero_new:c, \int_gzero_new:N, \int_gzero_new:c}
+% \begin{syntax}
+% \cs{int_zero_new:N} \meta{integer}
+% \end{syntax}
+% Ensures that the \meta{integer} exists globally by applying
+% \cs{int_new:N} if necessary, then applies
+% \cs[index=int_zero:N]{int_(g)zero:N} to leave
+% the \meta{integer} set to zero.
+% \end{function}
+%
+% \begin{function}
+% {
+% \int_set_eq:NN, \int_set_eq:cN, \int_set_eq:Nc, \int_set_eq:cc,
+% \int_gset_eq:NN, \int_gset_eq:cN, \int_gset_eq:Nc, \int_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{int_set_eq:NN} \meta{integer_1} \meta{integer_2}
+% \end{syntax}
+% Sets the content of \meta{integer_1} equal to that of
+% \meta{integer_2}.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added=2012-03-03]
+% {\int_if_exist:N, \int_if_exist:c}
+% \begin{syntax}
+% \cs{int_if_exist_p:N} \meta{int}
+% \cs{int_if_exist:NTF} \meta{int} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{int} is currently defined. This does not
+% check that the \meta{int} really is an integer variable.
+% \end{function}
+%
+% \section{Setting and incrementing integers}
+%
+% \begin{function}[updated = 2011-10-22]
+% {\int_add:Nn, \int_add:cn, \int_gadd:Nn, \int_gadd:cn}
+% \begin{syntax}
+% \cs{int_add:Nn} \meta{integer} \Arg{int expr}
+% \end{syntax}
+% Adds the result of the \meta{int expr} to the current
+% content of the \meta{integer}.
+% \end{function}
+%
+% \begin{function}{\int_decr:N, \int_decr:c, \int_gdecr:N, \int_gdecr:c}
+% \begin{syntax}
+% \cs{int_decr:N} \meta{integer}
+% \end{syntax}
+% Decreases the value stored in \meta{integer} by $1$.
+% \end{function}
+%
+% \begin{function}{\int_incr:N, \int_incr:c, \int_gincr:N, \int_gincr:c}
+% \begin{syntax}
+% \cs{int_incr:N} \meta{integer}
+% \end{syntax}
+% Increases the value stored in \meta{integer} by $1$.
+% \end{function}
+%
+% \begin{function}[updated = 2011-10-22]
+% {\int_set:Nn, \int_set:cn, \int_gset:Nn, \int_gset:cn}
+% \begin{syntax}
+% \cs{int_set:Nn} \meta{integer} \Arg{int expr}
+% \end{syntax}
+% Sets \meta{integer} to the value of \meta{int expr},
+% which must evaluate to an integer (as described for
+% \cs{int_eval:n}).
+% \end{function}
+%
+% \begin{function}[updated = 2011-10-22]
+% {\int_sub:Nn, \int_sub:cn, \int_gsub:Nn, \int_gsub:cn}
+% \begin{syntax}
+% \cs{int_sub:Nn} \meta{integer} \Arg{int expr}
+% \end{syntax}
+% Subtracts the result of the \meta{int expr} from the
+% current content of the \meta{integer}.
+% \end{function}
+%
+% \section{Using integers}
+%
+% \begin{function}[updated = 2011-10-22, EXP]{\int_use:N, \int_use:c}
+% \begin{syntax}
+% \cs{int_use:N} \meta{integer}
+% \end{syntax}
+% Recovers the content of an \meta{integer} and places it directly
+% in the input stream. An error is raised if the variable does
+% not exist or if it is invalid. Can be omitted in places where an
+% \meta{integer} is required (such as in the first and third arguments
+% of \cs{int_compare:nNnTF}).
+% \begin{texnote}
+% \cs{int_use:N} is the \TeX{} primitive \tn{the}: this is one of
+% several \LaTeX3 names for this primitive.
+% \end{texnote}
+% \end{function}
+%
+% \section{Integer expression conditionals}
+%
+% \begin{function}[EXP,pTF]{\int_compare:nNn}
+% \begin{syntax}
+% \cs{int_compare_p:nNn} \Arg{int expr_1} \meta{relation} \Arg{int expr_2} \\
+% \cs{int_compare:nNnTF}
+% ~~\Arg{int expr_1} \meta{relation} \Arg{int expr_2}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function first evaluates each of the \meta{int expr}s
+% as described for \cs{int_eval:n}. The two results are then
+% compared using the \meta{relation}:
+% \begin{center}
+% \begin{tabular}{ll}
+% Equal & |=| \\
+% Greater than & |>| \\
+% Less than & |<| \\
+% \end{tabular}
+% \end{center}
+% This function is less flexible than \cs{int_compare:nTF} but around
+% $5$~times faster.
+% \end{function}
+%
+% \begin{function}[updated = 2013-01-13, EXP, pTF]{\int_compare:n}
+% \begin{syntax}
+% \cs{int_compare_p:n} \\
+% ~~\{ \\
+% ~~~~\meta{int expr_1} \meta{relation_1} \\
+% ~~~~\ldots{} \\
+% ~~~~\meta{int expr_N} \meta{relation_N} \\
+% ~~~~\meta{int expr_{N+1}} \\
+% ~~\} \\
+% \cs{int_compare:nTF}
+% ~~\{ \\
+% ~~~~\meta{int expr_1} \meta{relation_1} \\
+% ~~~~\ldots{} \\
+% ~~~~\meta{int expr_N} \meta{relation_N} \\
+% ~~~~\meta{int expr_{N+1}} \\
+% ~~\} \\
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function evaluates the \meta{int expr}s as described
+% for \cs{int_eval:n} and compares consecutive result using the
+% corresponding \meta{relation}, namely it compares \meta{int expr_1}
+% and \meta{int expr_2} using the \meta{relation_1}, then
+% \meta{int expr_2} and \meta{int expr_3} using the \meta{relation_2},
+% until finally comparing \meta{int expr_N} and \meta{int expr_{N+1}}
+% using the \meta{relation_N}. The test yields \texttt{true} if all
+% comparisons are \texttt{true}. Each \meta{int expr} is
+% evaluated only once, and the evaluation is lazy, in the sense that
+% if one comparison is \texttt{false}, then no other \meta{integer
+% expression} is evaluated and no other comparison is performed.
+% The \meta{relations} can be any of the following:
+% \begin{center}
+% \begin{tabular}{ll}
+% Equal & |=| or |==| \\
+% Greater than or equal to & |>=| \\
+% Greater than & |>| \\
+% Less than or equal to & |<=| \\
+% Less than & |<| \\
+% Not equal & |!=| \\
+% \end{tabular}
+% \end{center}
+% This function is more flexible than \cs{int_compare:nNnTF} but
+% around $5$~times slower.
+% \end{function}
+%
+% \begin{function}[added = 2013-07-24, EXP, noTF]{\int_case:nn}
+% \begin{syntax}
+% \cs{int_case:nnTF} \Arg{test int expr} \\
+% ~~|{| \\
+% ~~~~\Arg{int expr case_1} \Arg{code case_1} \\
+% ~~~~\Arg{int expr case_2} \Arg{code case_2} \\
+% ~~~~\ldots \\
+% ~~~~\Arg{int expr case_n} \Arg{code case_n} \\
+% ~~|}| \\
+% ~~\Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% This function evaluates the \meta{test int expr} and
+% compares this in turn to each of the
+% \meta{int expr cases}. If the two are equal then the
+% associated \meta{code} is left in the input stream
+% and other cases are discarded. If any of the
+% cases are matched, the \meta{true code} is also inserted into the
+% input stream (after the code for the appropriate case), while if none
+% match then the \meta{false code} is inserted. The function
+% \cs{int_case:nn}, which does nothing if there is no match, is also
+% available. For example
+% \begin{verbatim}
+% \int_case:nnF
+% { 2 * 5 }
+% {
+% { 5 } { Small }
+% { 4 + 6 } { Medium }
+% { -2 * 10 } { Negative }
+% }
+% { No idea! }
+% \end{verbatim}
+% leaves \enquote{\texttt{Medium}} in the input stream.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\int_if_even:n, \int_if_odd:n}
+% \begin{syntax}
+% \cs{int_if_odd_p:n} \Arg{int expr}
+% \cs{int_if_odd:nTF} \Arg{int expr}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function first evaluates the \meta{int expr}
+% as described for \cs{int_eval:n}. It then evaluates if this
+% is odd or even, as appropriate.
+% \end{function}
+%
+% \begin{function}[EXP,pTF, added = 2023-05-17]{\int_if_zero:n}
+% \begin{syntax}
+% \cs{int_if_zero_p:n} \Arg{int expr}
+% \cs{int_if_zero:nTF} \Arg{int expr}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function first evaluates the \meta{int expr}
+% as described for \cs{int_eval:n}. It then evaluates if this
+% is zero or not.
+% \end{function}
+%
+% \section{Integer expression loops}
+%
+% \begin{function}[rEXP]{\int_do_until:nNnn}
+% \begin{syntax}
+% \cs{int_do_until:nNnn} \Arg{int expr_1} \meta{relation} \Arg{int expr_2} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the relationship between the two
+% \meta{int expr}s as described for \cs{int_compare:nNnTF}.
+% If the test is \texttt{false} then the \meta{code} is inserted
+% into the input stream again and a loop occurs until the
+% \meta{relation} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP]{\int_do_while:nNnn}
+% \begin{syntax}
+% \cs{int_do_while:nNnn} \Arg{int expr_1} \meta{relation} \Arg{int expr_2} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the relationship between the two
+% \meta{int expr}s as described for \cs{int_compare:nNnTF}.
+% If the test is \texttt{true} then the \meta{code} is inserted
+% into the input stream again and a loop occurs until the
+% \meta{relation} is \texttt{false}.
+% \end{function}
+%
+% \begin{function}[rEXP]{\int_until_do:nNnn}
+% \begin{syntax}
+% \cs{int_until_do:nNnn} \Arg{int expr_1} \meta{relation} \Arg{int expr_2} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{int expr}s
+% as described for \cs{int_compare:nNnTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{false}. After the \meta{code} has been processed by \TeX{} the
+% test is repeated, and a loop occurs until the test is
+% \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP]{\int_while_do:nNnn}
+% \begin{syntax}
+% \cs{int_while_do:nNnn} \Arg{int expr_1} \meta{relation} \Arg{int expr_2} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{int expr}s
+% as described for \cs{int_compare:nNnTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{true}. After the \meta{code} has been processed by \TeX{} the
+% test is repeated, and a loop occurs until the test is
+% \texttt{false}.
+% \end{function}
+%
+% \begin{function}[updated = 2013-01-13, rEXP]{\int_do_until:nn}
+% \begin{syntax}
+% \cs{int_do_until:nn} \Arg{integer relation} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the \meta{integer relation}
+% as described for \cs{int_compare:nTF}.
+% If the test is \texttt{false} then the \meta{code} is inserted
+% into the input stream again and a loop occurs until the
+% \meta{relation} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[updated = 2013-01-13, rEXP]{\int_do_while:nn}
+% \begin{syntax}
+% \cs{int_do_while:nn} \Arg{integer relation} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the \meta{integer relation}
+% as described for \cs{int_compare:nTF}.
+% If the test is \texttt{true} then the \meta{code} is inserted
+% into the input stream again and a loop occurs until the
+% \meta{relation} is \texttt{false}.
+% \end{function}
+%
+% \begin{function}[updated = 2013-01-13, rEXP]{\int_until_do:nn}
+% \begin{syntax}
+% \cs{int_until_do:nn} \Arg{integer relation} \Arg{code}
+% \end{syntax}
+% Evaluates the \meta{integer relation}
+% as described for \cs{int_compare:nTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{false}. After the \meta{code} has been processed by \TeX{} the
+% test is repeated, and a loop occurs until the test is
+% \texttt{true}.
+% \end{function}
+%
+% \begin{function}[updated = 2013-01-13, rEXP]{\int_while_do:nn}
+% \begin{syntax}
+% \cs{int_while_do:nn} \Arg{integer relation} \Arg{code}
+% \end{syntax}
+% Evaluates the \meta{integer relation}
+% as described for \cs{int_compare:nTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{true}. After the \meta{code} has been processed by \TeX{} the
+% test is repeated, and a loop occurs until the test is
+% \texttt{false}.
+% \end{function}
+%
+% \section{Integer step functions}
+%
+% \begin{function}[added = 2012-06-04, updated = 2018-04-22, rEXP]
+% {\int_step_function:nN, \int_step_function:nnN, \int_step_function:nnnN}
+% \begin{syntax}
+% \cs{int_step_function:nN} \Arg{final value} \meta{function}
+% \cs{int_step_function:nnN} \Arg{initial value} \Arg{final value} \meta{function}
+% \cs{int_step_function:nnnN} \Arg{initial value} \Arg{step} \Arg{final value} \meta{function}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, all of which should be integer expressions.
+% The \meta{function} is then placed in front of each \meta{value}
+% from the \meta{initial value} to the \meta{final value} in turn
+% (using \meta{step} between each \meta{value}). The \meta{step} must
+% be non-zero. If the \meta{step} is positive, the loop stops when
+% the \meta{value} becomes larger than the \meta{final value}. If the
+% \meta{step} is negative, the loop stops when the \meta{value}
+% becomes smaller than the \meta{final value}. The \meta{function}
+% should absorb one numerical argument. For example
+% \begin{verbatim}
+% \cs_set:Npn \my_func:n #1 { [I~saw~#1] \quad }
+% \int_step_function:nnnN { 1 } { 1 } { 5 } \my_func:n
+% \end{verbatim}
+% would print
+% \begin{quote}
+% [I saw 1] \quad
+% [I saw 2] \quad
+% [I saw 3] \quad
+% [I saw 4] \quad
+% [I saw 5] \quad
+% \end{quote}
+%
+% The functions \cs{int_step_function:nN} and \cs{int_step_function:nnN}
+% both use a fixed \meta{step} of $1$, and in the case of
+% \cs{int_step_function:nN} the \meta{initial value} is also fixed as
+% $1$. These functions are provided as simple short-cuts for code clarity.
+% \end{function}
+%
+% \begin{function}[added = 2012-06-04, updated = 2018-04-22]
+% {\int_step_inline:nn, \int_step_inline:nnn, \int_step_inline:nnnn}
+% \begin{syntax}
+% \cs{int_step_inline:nn} \Arg{final value} \Arg{code}
+% \cs{int_step_inline:nnn} \Arg{initial value} \Arg{final value} \Arg{code}
+% \cs{int_step_inline:nnnn} \Arg{initial value} \Arg{step} \Arg{final value} \Arg{code}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, all of which should be integer expressions.
+% Then for each \meta{value} from the \meta{initial value} to the
+% \meta{final value} in turn (using \meta{step} between each
+% \meta{value}), the \meta{code} is inserted into the input stream
+% with |#1| replaced by the current \meta{value}. Thus the
+% \meta{code} should define a function of one argument~(|#1|).
+%
+% The functions \cs{int_step_inline:nn} and \cs{int_step_inline:nnn}
+% both use a fixed \meta{step} of $1$, and in the case of
+% \cs{int_step_inline:nn} the \meta{initial value} is also fixed as
+% $1$. These functions are provided as simple short-cuts for code clarity.
+% \end{function}
+%
+% \begin{function}[added = 2012-06-04, updated = 2018-04-22]
+% {\int_step_variable:nNn, \int_step_variable:nnNn, \int_step_variable:nnnNn}
+% \begin{syntax}
+% \cs{int_step_variable:nNn} \Arg{final value} \meta{tl~var} \Arg{code}
+% \cs{int_step_variable:nnNn} \Arg{initial value} \Arg{final value} \meta{tl~var} \Arg{code}
+% \cs{int_step_variable:nnnNn} \Arg{initial value} \Arg{step} \Arg{final value} \meta{tl~var} \Arg{code}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, all of which should be integer expressions.
+% Then for each \meta{value} from the \meta{initial value} to the
+% \meta{final value} in turn (using \meta{step} between each
+% \meta{value}), the \meta{code} is inserted into the input stream,
+% with the \meta{tl~var} defined as the current \meta{value}. Thus
+% the \meta{code} should make use of the \meta{tl~var}.
+%
+% The functions \cs{int_step_variable:nNn} and \cs{int_step_variable:nnNn}
+% both use a fixed \meta{step} of $1$, and in the case of
+% \cs{int_step_variable:nNn} the \meta{initial value} is also fixed as
+% $1$. These functions are provided as simple short-cuts for code clarity.
+% \end{function}
+%
+% \section{Formatting integers}
+%
+% Integers can be placed into the output stream with formatting. These
+% conversions apply to any integer expressions.
+%
+% \begin{function}[updated = 2011-10-22, EXP]{\int_to_arabic:n, \int_to_arabic:v}
+% \begin{syntax}
+% \cs{int_to_arabic:n} \Arg{int expr}
+% \end{syntax}
+% Places the value of the \meta{int expr} in the input
+% stream as digits, with category code $12$ (other).
+% \end{function}
+%
+% \begin{function}[updated = 2011-09-17, EXP]{\int_to_alph:n, \int_to_Alph:n}
+% \begin{syntax}
+% \cs{int_to_alph:n} \Arg{int expr}
+% \end{syntax}
+% Evaluates the \meta{int expr} and converts the result
+% into a series of letters, which are then left in the input stream.
+% The conversion rule uses the $26$ letters of the English
+% alphabet, in order, adding letters when necessary to increase the total
+% possible range of representable numbers. Thus
+% \begin{verbatim}
+% \int_to_alph:n { 1 }
+% \end{verbatim}
+% places |a| in the input stream,
+% \begin{verbatim}
+% \int_to_alph:n { 26 }
+% \end{verbatim}
+% is represented as |z| and
+% \begin{verbatim}
+% \int_to_alph:n { 27 }
+% \end{verbatim}
+% is converted to |aa|. For conversions using other alphabets, use
+% \cs{int_to_symbols:nnn} to define an alphabet-specific
+% function. The basic \cs{int_to_alph:n} and \cs{int_to_Alph:n}
+% functions should not be modified.
+% The resulting tokens are digits with category code $12$ (other) and
+% letters with category code $11$ (letter).
+% \end{function}
+%
+% \begin{function}[updated = 2011-09-17, EXP]{\int_to_symbols:nnn}
+% \begin{syntax}
+% \cs{int_to_symbols:nnn}
+% ~~\Arg{int expr} \Arg{total symbols}
+% ~~\Arg{value to symbol mapping}
+% \end{syntax}
+% This is the low-level function for conversion of an
+% \meta{int expr} into a symbolic form (often
+% letters). The \meta{total symbols} available should be given
+% as an integer expression. Values are actually converted to symbols
+% according to the \meta{value to symbol mapping}. This should be given
+% as \meta{total symbols} pairs of entries, a number and the
+% appropriate symbol. Thus the \cs{int_to_alph:n} function is defined
+% as
+% \begin{verbatim}
+% \cs_new:Npn \int_to_alph:n #1
+% {
+% \int_to_symbols:nnn {#1} { 26 }
+% {
+% { 1 } { a }
+% { 2 } { b }
+% ...
+% { 26 } { z }
+% }
+% }
+% \end{verbatim}
+% \end{function}
+%
+% \begin{function}[added = 2014-02-11, EXP]{\int_to_bin:n}
+% \begin{syntax}
+% \cs{int_to_bin:n} \Arg{int expr}
+% \end{syntax}
+% Calculates the value of the \meta{int expr} and places
+% the binary representation of the result in the input stream.
+% \end{function}
+%
+% \begin{function}[added = 2014-02-11, EXP]{\int_to_hex:n, \int_to_Hex:n}
+% \begin{syntax}
+% \cs{int_to_hex:n} \Arg{int expr}
+% \end{syntax}
+% Calculates the value of the \meta{int expr} and places
+% the hexadecimal (base~$16$) representation of the result in the
+% input stream. Letters are used for digits beyond~$9$: lower
+% case letters for \cs{int_to_hex:n} and upper case ones for
+% \cs{int_to_Hex:n}.
+% The resulting tokens are digits with category code $12$ (other) and
+% letters with category code $11$ (letter).
+% \end{function}
+%
+% \begin{function}[added = 2014-02-11, EXP]{\int_to_oct:n}
+% \begin{syntax}
+% \cs{int_to_oct:n} \Arg{int expr}
+% \end{syntax}
+% Calculates the value of the \meta{int expr} and places
+% the octal (base~$8$) representation of the result in the input
+% stream.
+% The resulting tokens are digits with category code $12$ (other) and
+% letters with category code $11$ (letter).
+% \end{function}
+%
+% \begin{function}[updated = 2014-02-11, EXP]
+% {\int_to_base:nn, \int_to_Base:nn}
+% \begin{syntax}
+% \cs{int_to_base:nn} \Arg{int expr} \Arg{base}
+% \end{syntax}
+% Calculates the value of the \meta{int expr} and
+% converts it into the appropriate representation in the \meta{base};
+% the later may be given as an integer expression. For bases greater
+% than $10$ the higher \enquote{digits} are represented by
+% letters from the English alphabet: lower
+% case letters for \cs{int_to_base:n} and upper case ones for
+% \cs{int_to_Base:n}.
+% The maximum \meta{base} value is $36$.
+% The resulting tokens are digits with category code $12$ (other) and
+% letters with category code $11$ (letter).
+% \begin{texnote}
+% This is a generic version of \cs{int_to_bin:n}, \emph{etc.}
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[updated = 2011-10-22, rEXP]{\int_to_roman:n, \int_to_Roman:n}
+% \begin{syntax}
+% \cs{int_to_roman:n} \Arg{int expr}
+% \end{syntax}
+% Places the value of the \meta{int expr} in the input
+% stream as Roman numerals, either lower case (\cs{int_to_roman:n}) or
+% upper case (\cs{int_to_Roman:n}). If the value is negative or zero,
+% the output is empty. The Roman numerals are letters with category
+% code $11$ (letter). The letters used are |mdclxvi|, repeated as
+% needed: the notation with bars (such as $\bar{\mbox{v}}$ for $5000$)
+% is \emph{not} used. For instance \cs{int_to_roman:n} |{| 8249 |}|
+% expands to |mmmmmmmmccxlix|.
+% \end{function}
+%
+% \section{Converting from other formats to integers}
+%
+% \begin{function}[updated = 2014-08-25, EXP]{\int_from_alph:n}
+% \begin{syntax}
+% \cs{int_from_alph:n} \Arg{letters}
+% \end{syntax}
+% Converts the \meta{letters} into the integer (base~$10$)
+% representation and leaves this in the input stream. The
+% \meta{letters} are first converted to a string, with no expansion.
+% Lower and upper case letters from the English alphabet may be used,
+% with \enquote{a} equal to $1$ through to \enquote{z} equal to $26$.
+% The function also accepts a leading sign, made of |+| and~|-|. This
+% is the inverse function of \cs{int_to_alph:n} and
+% \cs{int_to_Alph:n}.
+% \end{function}
+%
+% \begin{function}[added = 2014-02-11, updated = 2014-08-25, EXP]
+% {\int_from_bin:n}
+% \begin{syntax}
+% \cs{int_from_bin:n} \Arg{binary number}
+% \end{syntax}
+% Converts the \meta{binary number} into the integer (base~$10$)
+% representation and leaves this in the input stream.
+% The \meta{binary number} is first converted to a string, with no
+% expansion. The function accepts a leading sign, made of |+|
+% and~|-|, followed by binary digits. This is the inverse function
+% of \cs{int_to_bin:n}.
+% \end{function}
+%
+% \begin{function}[added = 2014-02-11, updated = 2014-08-25, EXP]
+% {\int_from_hex:n}
+% \begin{syntax}
+% \cs{int_from_hex:n} \Arg{hexadecimal number}
+% \end{syntax}
+% Converts the \meta{hexadecimal number} into the integer (base~$10$)
+% representation and leaves this in the input stream. Digits greater
+% than $9$ may be represented in the \meta{hexadecimal number} by
+% upper or lower case letters. The \meta{hexadecimal number} is first
+% converted to a string, with no expansion. The function also accepts
+% a leading sign, made of |+| and~|-|. This is the inverse function
+% of \cs{int_to_hex:n} and \cs{int_to_Hex:n}.
+% \end{function}
+%
+% \begin{function}[added = 2014-02-11, updated = 2014-08-25, EXP]
+% {\int_from_oct:n}
+% \begin{syntax}
+% \cs{int_from_oct:n} \Arg{octal number}
+% \end{syntax}
+% Converts the \meta{octal number} into the integer (base~$10$)
+% representation and leaves this in the input stream.
+% The \meta{octal number} is first converted to a string, with no
+% expansion. The function accepts a leading sign, made of |+|
+% and~|-|, followed by octal digits. This is the inverse function
+% of \cs{int_to_oct:n}.
+% \end{function}
+%
+% \begin{function}[updated = 2014-08-25, updated = 2014-08-25, EXP]
+% {\int_from_roman:n}
+% \begin{syntax}
+% \cs{int_from_roman:n} \Arg{roman numeral}
+% \end{syntax}
+% Converts the \meta{roman numeral} into the integer (base~$10$)
+% representation and leaves this in the input stream. The \meta{roman
+% numeral} is first converted to a string, with no expansion. The
+% \meta{roman numeral} may be in upper or lower case; if the numeral
+% contains characters besides |mdclxvi| or |MDCLXVI| then the
+% resulting value is $-1$. This is the inverse function of
+% \cs{int_to_roman:n} and \cs{int_to_Roman:n}.
+% \end{function}
+%
+% \begin{function}[updated = 2014-08-25, EXP]{\int_from_base:nn}
+% \begin{syntax}
+% \cs{int_from_base:nn} \Arg{number} \Arg{base}
+% \end{syntax}
+% Converts the \meta{number} expressed in \meta{base} into the
+% appropriate value in base $10$. The \meta{number} is first
+% converted to a string, with no expansion. The \meta{number} should
+% consist of digits and letters (either lower or upper case), plus
+% optionally a leading sign. The maximum \meta{base} value is $36$.
+% This is the inverse function of \cs{int_to_base:nn} and
+% \cs{int_to_Base:nn}.
+% \end{function}
+%
+% \section{Random integers}
+%
+% \begin{function}[EXP, added = 2016-12-06, updated = 2018-04-27]{\int_rand:nn}
+% \begin{syntax}
+% \cs{int_rand:nn} \Arg{int expr_1} \Arg{int expr_2}
+% \end{syntax}
+% Evaluates the two \meta{int expr}s and produces a
+% pseudo-random number between the two (with bounds included).
+% This is not available in older versions of \XeTeX{}.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2018-05-05]{\int_rand:n}
+% \begin{syntax}
+% \cs{int_rand:n} \Arg{int expr}
+% \end{syntax}
+% Evaluates the \meta{int expr} then produces a
+% pseudo-random number between $1$ and the \meta{int expr} (included).
+% This is not available in older versions of \XeTeX{}.
+% \end{function}
+%
+% \section{Viewing integers}
+%
+% \begin{function}{\int_show:N, \int_show:c}
+% \begin{syntax}
+% \cs{int_show:N} \meta{integer}
+% \end{syntax}
+% Displays the value of the \meta{integer} on the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2011-11-22, updated = 2015-08-07]{\int_show:n}
+% \begin{syntax}
+% \cs{int_show:n} \Arg{int expr}
+% \end{syntax}
+% Displays the result of evaluating the \meta{int expr}
+% on the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2015-08-03]{\int_log:N, \int_log:c}
+% \begin{syntax}
+% \cs{int_log:N} \meta{integer}
+% \end{syntax}
+% Writes the value of the \meta{integer} in the log file.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2015-08-07]{\int_log:n}
+% \begin{syntax}
+% \cs{int_log:n} \Arg{int expr}
+% \end{syntax}
+% Writes the result of evaluating the \meta{int expr}
+% in the log file.
+% \end{function}
+%
+% \section{Constant integers}
+%
+% \begin{variable}[added = 2018-05-07]{\c_zero_int, \c_one_int}
+% Integer values used with primitive tests and assignments: their
+% self-terminating nature makes these more convenient and faster than
+% literal numbers.
+% \end{variable}
+%
+% \begin{variable}[module = int]{\c_max_int}
+% The maximum value that can be stored as an integer.
+% \end{variable}
+%
+% \begin{variable}[module = int]{\c_max_register_int}
+% Maximum number of registers.
+% \end{variable}
+%
+% \begin{variable}[module = int]{\c_max_char_int}
+% Maximum character code completely supported by the engine.
+% \end{variable}
+%
+% \section{Scratch integers}
+%
+% \begin{variable}{\l_tmpa_int, \l_tmpb_int}
+% Scratch integer for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_int, \g_tmpb_int}
+% Scratch integer for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Direct number expansion}
+%
+% \begin{function}[EXP, added = 2018-03-27]{\int_value:w}
+% \begin{syntax}
+% \cs{int_value:w} \meta{integer}
+% \cs{int_value:w} \meta{integer denotation} \meta{optional space}
+% \end{syntax}
+% Expands the following tokens until an \meta{integer} is formed, and
+% leaves a normalized form (no leading sign except for negative
+% numbers, no leading digit~|0| except for zero) in the input stream
+% as category code $12$ (other) characters. The \meta{integer} can
+% consist of any number of signs (with intervening spaces) followed
+% by
+% \begin{itemize}
+% \item an integer variable (in fact, any \TeX{} register except
+% \tn{toks}) or
+% \item explicit digits (or by |'|\meta{octal digits} or |"|\meta{hexadecimal digits} or |`|\meta{character}).
+% \end{itemize}
+% In this last case expansion stops once a non-digit is found; if that is a
+% space it is removed as in \texttt{f}-expansion, and so \cs{exp_stop_f:}
+% may be employed as an end marker. Note that protected functions
+% \emph{are} expanded by this process.
+%
+% This function requires exactly one expansion to produce a value, and so
+% is suitable for use in cases where a number is required \enquote{directly}.
+% In general, \cs{int_eval:n} is the preferred approach to generating
+% numbers.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{number}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Primitive conditionals}
+%
+% \begin{function}[EXP]{\if_int_compare:w}
+% \begin{syntax}
+% \cs{if_int_compare:w} \meta{integer_1} \meta{relation} \meta{integer_2}
+% ~~\meta{true code}
+% \cs{else:}
+% ~~\meta{false code}
+% \cs{fi:}
+% \end{syntax}
+% Compare two integers using \meta{relation}, which must be one of
+% |=|, |<| or |>| with category code $12$.
+% The \cs{else:} branch is optional.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifnum}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\if_case:w, \or:}
+% \begin{syntax}
+% \cs{if_case:w} \meta{integer} \meta{case_0}
+% ~~\cs{or:} \meta{case_1}
+% ~~\cs{or:} |...|
+% ~~\cs{else:} \meta{default}
+% \cs{fi:}
+% \end{syntax}
+% Selects a case to execute based on the value of the \meta{integer}. The
+% first case (\meta{case_0}) is executed if \meta{integer} is $0$, the second
+% (\meta{case_1}) if the \meta{integer} is $1$, \emph{etc.} The
+% \meta{integer} may be a literal, a constant or an integer
+% expression (\emph{e.g.}~using \cs{int_eval:n}).
+% \begin{texnote}
+% These are the \TeX{} primitives \tn{ifcase} and \tn{or}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\if_int_odd:w}
+% \begin{syntax}
+% \cs{if_int_odd:w} \meta{tokens} \meta{optional space}
+% ~~\meta{true code}
+% \cs{else:}
+% ~~\meta{true code}
+% \cs{fi:}
+% \end{syntax}
+% Expands \meta{tokens} until a non-numeric token or a space is found, and
+% tests whether the resulting \meta{integer} is odd. If so, \meta{true code}
+% is executed. The \cs{else:} branch is optional.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifodd}.
+% \end{texnote}
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3int} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=int>
+% \end{macrocode}
+%
+% \TestFiles{m3int001,m3int002,m3int03}
+%
+% \begin{variable}{\c_max_register_int}
+% Done in \pkg{l3basics}.
+% \end{variable}
+%
+% \begin{macro}{\@@_to_roman:w}
+% \begin{macro}{\if_int_compare:w}
+% Done in \pkg{l3basics}.
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\or:}
+% Done in \pkg{l3basics}.
+% \end{macro}
+%
+% \begin{macro}{\int_value:w}
+% \begin{macro}{\@@_eval:w}
+% \begin{macro}{\@@_eval_end:}
+% \begin{macro}{\if_int_odd:w}
+% \begin{macro}{\if_case:w}
+% Here are the remaining primitives for number comparisons and
+% expressions.
+% \begin{macrocode}
+\cs_new_eq:NN \int_value:w \tex_number:D
+\cs_new_eq:NN \@@_eval:w \tex_numexpr:D
+\cs_new_eq:NN \@@_eval_end: \tex_relax:D
+\cs_new_eq:NN \if_int_odd:w \tex_ifodd:D
+\cs_new_eq:NN \if_case:w \tex_ifcase:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\s_@@_mark,\s_@@_stop}
+% Scan marks used throughout the module.
+% \begin{macrocode}
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_use_none_delimit_by_s_stop:w}
+% Function to gobble until a scan mark.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_none_delimit_by_s_stop:w #1 \s_@@_stop { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\q_@@_recursion_tail,\q_@@_recursion_stop}
+% Quarks for recursion.
+% \begin{macrocode}
+\quark_new:N \q_@@_recursion_tail
+\quark_new:N \q_@@_recursion_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_if_recursion_tail_stop_do:Nn,\@@_if_recursion_tail_stop:N}
+% Functions to query quarks.
+% \begin{macrocode}
+\__kernel_quark_new_test:N \@@_if_recursion_tail_stop_do:Nn
+\__kernel_quark_new_test:N \@@_if_recursion_tail_stop:N
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Integer expressions}
+%
+% \begin{macro}{\int_eval:n}
+% \begin{macro}{\int_eval:w}
+% Wrapper for \cs{@@_eval:w}: can be used in an integer expression or
+% directly in the input stream. It is very slightly faster to use
+% \tn{the} rather than \tn{number} to turn the expression to a number.
+% When debugging, we introduce parentheses to catch early termination (see \pkg{l3debug}).
+% \begin{macrocode}
+\cs_new:Npn \int_eval:n #1
+ { \tex_the:D \@@_eval:w #1 \@@_eval_end: }
+\cs_new:Npn \int_eval:w { \tex_the:D \@@_eval:w }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\int_sign:n, \@@_sign:Nw}
+% See \cs{int_abs:n}. Evaluate the expression once (and when
+% debugging is enabled, check that the expression is well-formed),
+% then test the first character to determine the sign. This is
+% wrapped in \cs{int_value:w} \ldots{} \cs{exp_stop_f:} to ensure a
+% fixed number of expansions and to avoid dealing with closing the
+% conditionals.
+% \begin{macrocode}
+\cs_new:Npn \int_sign:n #1
+ {
+ \int_value:w \exp_after:wN \@@_sign:Nw
+ \int_value:w \@@_eval:w #1 \@@_eval_end: ;
+ \exp_stop_f:
+ }
+\cs_new:Npn \@@_sign:Nw #1#2 ;
+ {
+ \if_meaning:w 0 #1
+ 0
+ \else:
+ \if_meaning:w - #1 - \fi: 1
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\int_abs:n}
+% \begin{macro}[EXP]{\@@_abs:N}
+% \UnitTested
+% \begin{macro}[EXP]{\int_max:nn}
+% \begin{macro}[EXP]{\int_min:nn}
+% \begin{macro}[EXP]{\@@_maxmin:wwN}
+% \UnitTested
+% \UnitTested
+% Functions for $\min$, $\max$, and absolute value with only one
+% evaluation. The absolute value is obtained by removing a leading
+% sign if any. All three functions expand in two steps.
+% \begin{macrocode}
+\cs_new:Npn \int_abs:n #1
+ {
+ \int_value:w \exp_after:wN \@@_abs:N
+ \int_value:w \@@_eval:w #1 \@@_eval_end:
+ \exp_stop_f:
+ }
+\cs_new:Npn \@@_abs:N #1
+ { \if_meaning:w - #1 \else: \exp_after:wN #1 \fi: }
+\cs_new:Npn \int_max:nn #1#2
+ {
+ \int_value:w \exp_after:wN \@@_maxmin:wwN
+ \int_value:w \@@_eval:w #1 \exp_after:wN ;
+ \int_value:w \@@_eval:w #2 ;
+ >
+ \exp_stop_f:
+ }
+\cs_new:Npn \int_min:nn #1#2
+ {
+ \int_value:w \exp_after:wN \@@_maxmin:wwN
+ \int_value:w \@@_eval:w #1 \exp_after:wN ;
+ \int_value:w \@@_eval:w #2 ;
+ <
+ \exp_stop_f:
+ }
+\cs_new:Npn \@@_maxmin:wwN #1 ; #2 ; #3
+ {
+ \if_int_compare:w #1 #3 #2 ~
+ #1
+ \else:
+ #2
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\int_div_truncate:nn}
+% \UnitTested
+% \begin{macro}[EXP]{\int_div_round:nn}
+% \UnitTested
+% \begin{macro}[EXP]{\int_mod:nn}
+% \UnitTested
+% \begin{macro}[EXP]{\@@_div_truncate:NwNw}
+% \begin{macro}[EXP]{\@@_mod:ww}
+% As \cs{@@_eval:w} rounds the result of a division we also provide a
+% version that truncates the result. We use an auxiliary to make sure
+% numerator and denominator are only evaluated once: this comes in
+% handy when those are more expressions are expensive to evaluate
+% (\emph{e.g.}, \cs{tl_count:n}). If the numerator |#1#2| is $0$,
+% then we divide $0$ by the denominator (this ensures that $0/0$ is
+% correctly reported as an error). Otherwise, shift the numerator
+% |#1#2| towards $0$ by $(\left\vert\texttt{\#3\#4}\right\vert-1)/2$, which we
+% round away from zero. It turns out that this quantity exactly
+% compensates the difference between \eTeX{}'s rounding and the
+% truncating behaviour that we want. The details are thanks to Heiko
+% Oberdiek: getting things right in all cases is not so easy.
+% \begin{macrocode}
+\cs_new:Npn \int_div_truncate:nn #1#2
+ {
+ \int_value:w \@@_eval:w
+ \exp_after:wN \@@_div_truncate:NwNw
+ \int_value:w \@@_eval:w #1 \exp_after:wN ;
+ \int_value:w \@@_eval:w #2 ;
+ \@@_eval_end:
+ }
+\cs_new:Npn \@@_div_truncate:NwNw #1#2; #3#4;
+ {
+ \if_meaning:w 0 #1
+ 0
+ \else:
+ (
+ #1#2
+ \if_meaning:w - #1 + \else: - \fi:
+ ( \if_meaning:w - #3 - \fi: #3#4 - 1 ) / 2
+ )
+ \fi:
+ / #3#4
+ }
+% \end{macrocode}
+% For the sake of completeness:
+% \begin{macrocode}
+\cs_new:Npn \int_div_round:nn #1#2
+ { \int_value:w \@@_eval:w ( #1 ) / ( #2 ) \@@_eval_end: }
+% \end{macrocode}
+% Finally there's the modulus operation.
+% \begin{macrocode}
+\cs_new:Npn \int_mod:nn #1#2
+ {
+ \int_value:w \@@_eval:w \exp_after:wN \@@_mod:ww
+ \int_value:w \@@_eval:w #1 \exp_after:wN ;
+ \int_value:w \@@_eval:w #2 ;
+ \@@_eval_end:
+ }
+\cs_new:Npn \@@_mod:ww #1; #2;
+ { #1 - ( \@@_div_truncate:NwNw #1 ; #2 ; ) * #2 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\__kernel_int_add:nnn}
+% Equivalent to \cs{int_eval:n} |{#1+#2+#3}| except that overflow only
+% occurs if the final result overflows $[-2^{31}+1,2^{31}-1]$. The
+% idea is to choose the order in which the three numbers are added
+% together. If |#1| and |#2| have opposite signs (one is in
+% $[-2^{31}+1,-1]$ and the other in $[0,2^{31}-1]$) then |#1+#2|
+% cannot overflow so we compute the result as |#1+#2+#3|. If they
+% have the same sign, then either |#3| has the same sign and the order
+% does not matter, or |#3| has the opposite sign and any order in
+% which |#3| is not last will work. We use |#1+#3+#2|.
+% \begin{macrocode}
+\cs_new:Npn \__kernel_int_add:nnn #1#2#3
+ {
+ \int_value:w \@@_eval:w #1
+ \if_int_compare:w #2 < \c_zero_int \exp_after:wN \reverse_if:N \fi:
+ \if_int_compare:w #1 < \c_zero_int + #2 + #3 \else: + #3 + #2 \fi:
+ \@@_eval_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Creating and initialising integers}
+%
+% \begin{macro}{\int_new:N, \int_new:c}
+% \UnitTested
+% Two ways to do this: one for the format and one for the \LaTeXe{}
+% package. In plain \TeX{}, \cs{newcount} (and other allocators) are
+% \cs{outer}: to allow the code here to work in \enquote{generic} mode
+% this is therefore accessed by name. (The same applies to \cs{newbox},
+% \cs{newdimen} and so on.)
+% \begin{macrocode}
+\cs_new_protected:Npn \int_new:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \cs:w newcount \cs_end: #1
+ }
+\cs_generate_variant:Nn \int_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_const:Nn, \int_const:cn}
+% \begin{macro}{\@@_const:nN, \@@_const:eN}
+% \begin{macro}{\@@_constdef:Nw}
+% \begin{variable}{\c_@@_max_constdef_int}
+% \UnitTested
+% As stated, most constants can be defined as \tn{chardef} or
+% \tn{mathchardef} but that's engine dependent. As a result, there is some
+% set up code to determine what can be done. No full engine testing just yet
+% so everything is a little awkward.
+% We cannot use \cs{int_gset:Nn} because (when |check-declarations| is
+% enabled) this runs some checks that constants would fail.
+% \begin{macrocode}
+\cs_new_protected:Npn \int_const:Nn #1#2
+ { \@@_const:eN { \int_eval:n {#2} } #1 }
+\cs_generate_variant:Nn \int_const:Nn { c }
+\cs_new_protected:Npn \@@_const:nN #1#2
+ {
+ \int_compare:nNnTF {#1} < \c_zero_int
+ {
+ \int_new:N #2
+ \tex_global:D
+ }
+ {
+ \int_compare:nNnTF {#1} > \c_@@_max_constdef_int
+ {
+ \int_new:N #2
+ \tex_global:D
+ }
+ {
+ \__kernel_chk_if_free_cs:N #2
+ \tex_global:D \@@_constdef:Nw
+ }
+ }
+ #2 = \@@_eval:w #1 \@@_eval_end:
+ }
+\cs_generate_variant:Nn \@@_const:nN { e }
+\if_int_odd:w 0
+ \cs_if_exist:NT \tex_luatexversion:D { 1 }
+ \cs_if_exist:NT \tex_omathchardef:D { 1 }
+ \cs_if_exist:NT \tex_XeTeXversion:D { 1 } ~
+ \cs_if_exist:NTF \tex_omathchardef:D
+ { \cs_new_eq:NN \@@_constdef:Nw \tex_omathchardef:D }
+ { \cs_new_eq:NN \@@_constdef:Nw \tex_chardef:D }
+ \tex_global:D \@@_constdef:Nw \c_@@_max_constdef_int 1114111 ~
+\else:
+ \cs_new_eq:NN \@@_constdef:Nw \tex_mathchardef:D
+ \tex_global:D \@@_constdef:Nw \c_@@_max_constdef_int 32767 ~
+\fi:
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_zero:N, \int_zero:c}
+% \UnitTested
+% \begin{macro}{\int_gzero:N, \int_gzero:c}
+% \UnitTested
+% Functions that reset an \meta{integer} register to zero.
+% \begin{macrocode}
+\cs_new_protected:Npn \int_zero:N #1 { #1 = \c_zero_int }
+\cs_new_protected:Npn \int_gzero:N #1 { \tex_global:D #1 = \c_zero_int }
+\cs_generate_variant:Nn \int_zero:N { c }
+\cs_generate_variant:Nn \int_gzero:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\int_zero_new:N, \int_zero_new:c, \int_gzero_new:N, \int_gzero_new:c}
+% Create a register if needed, otherwise clear it.
+% \begin{macrocode}
+\cs_new_protected:Npn \int_zero_new:N #1
+ { \int_if_exist:NTF #1 { \int_zero:N #1 } { \int_new:N #1 } }
+\cs_new_protected:Npn \int_gzero_new:N #1
+ { \int_if_exist:NTF #1 { \int_gzero:N #1 } { \int_new:N #1 } }
+\cs_generate_variant:Nn \int_zero_new:N { c }
+\cs_generate_variant:Nn \int_gzero_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_set_eq:NN, \int_set_eq:cN, \int_set_eq:Nc, \int_set_eq:cc}
+% \UnitTested
+% \begin{macro}
+% {\int_gset_eq:NN, \int_gset_eq:cN, \int_gset_eq:Nc, \int_gset_eq:cc}
+% \UnitTested
+% Setting equal means using one integer inside the set function of
+% another. Check that assigned integer is local/global. No need to
+% check that the other one is defined as \TeX{} does it for us.
+% \begin{macrocode}
+\cs_new_protected:Npn \int_set_eq:NN #1#2 { #1 = #2 }
+\cs_generate_variant:Nn \int_set_eq:NN { c , Nc , cc }
+\cs_new_protected:Npn \int_gset_eq:NN #1#2 { \tex_global:D #1 = #2 }
+\cs_generate_variant:Nn \int_gset_eq:NN { c , Nc , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\int_if_exist:N, \int_if_exist:c}
+% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \int_if_exist:N \cs_if_exist:N
+ { TF , T , F , p }
+\prg_new_eq_conditional:NNn \int_if_exist:c \cs_if_exist:c
+ { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Setting and incrementing integers}
+%
+% \begin{macro}{\int_add:Nn, \int_add:cn}
+% \UnitTested
+% \begin{macro}{\int_gadd:Nn, \int_gadd:cn}
+% \UnitTested
+% \begin{macro}{\int_sub:Nn, \int_sub:cn}
+% \UnitTested
+% \begin{macro}{\int_gsub:Nn, \int_gsub:cn}
+% \UnitTested
+% Adding and subtracting to and from a counter.
+% Including here the optional |by| would slow down these operations
+% by a few percent.
+% \begin{macrocode}
+\cs_new_protected:Npn \int_add:Nn #1#2
+ { \tex_advance:D #1 \@@_eval:w #2 \@@_eval_end: }
+\cs_new_protected:Npn \int_sub:Nn #1#2
+ { \tex_advance:D #1 - \@@_eval:w #2 \@@_eval_end: }
+\cs_new_protected:Npn \int_gadd:Nn #1#2
+ { \tex_global:D \tex_advance:D #1 \@@_eval:w #2 \@@_eval_end: }
+\cs_new_protected:Npn \int_gsub:Nn #1#2
+ { \tex_global:D \tex_advance:D #1 - \@@_eval:w #2 \@@_eval_end: }
+\cs_generate_variant:Nn \int_add:Nn { c }
+\cs_generate_variant:Nn \int_gadd:Nn { c }
+\cs_generate_variant:Nn \int_sub:Nn { c }
+\cs_generate_variant:Nn \int_gsub:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_incr:N, \int_incr:c}
+% \UnitTested
+% \begin{macro}{\int_gincr:N, \int_gincr:c}
+% \UnitTested
+% \begin{macro}{\int_decr:N, \int_decr:c}
+% \UnitTested
+% \begin{macro}{\int_gdecr:N, \int_gdecr:c}
+% \UnitTested
+% Incrementing and decrementing of integer registers is done with
+% the following functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \int_incr:N #1
+ { \tex_advance:D #1 \c_one_int }
+\cs_new_protected:Npn \int_decr:N #1
+ { \tex_advance:D #1 - \c_one_int }
+\cs_new_protected:Npn \int_gincr:N #1
+ { \tex_global:D \tex_advance:D #1 \c_one_int }
+\cs_new_protected:Npn \int_gdecr:N #1
+ { \tex_global:D \tex_advance:D #1 - \c_one_int }
+\cs_generate_variant:Nn \int_incr:N { c }
+\cs_generate_variant:Nn \int_decr:N { c }
+\cs_generate_variant:Nn \int_gincr:N { c }
+\cs_generate_variant:Nn \int_gdecr:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_set:Nn, \int_set:cn}
+% \UnitTested
+% \begin{macro}{\int_gset:Nn, \int_gset:cn}
+% \UnitTested
+% As integers are register-based \TeX{} issues an error
+% if they are not defined. While the |=| sign is optional, this
+% version with |=| is slightly quicker than without, while adding the
+% optional space after |=| slows things down minutely.
+% \begin{macrocode}
+\cs_new_protected:Npn \int_set:Nn #1#2
+ { #1 = \@@_eval:w #2 \@@_eval_end: }
+\cs_new_protected:Npn \int_gset:Nn #1#2
+ { \tex_global:D #1 = \@@_eval:w #2 \@@_eval_end: }
+\cs_generate_variant:Nn \int_set:Nn { c }
+\cs_generate_variant:Nn \int_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using integers}
+%
+% \begin{macro}{\int_use:N, \int_use:c}
+% \UnitTested
+% Here is how counters are accessed.
+% We hand-code the |c| variant for some speed gain.
+% \begin{macrocode}
+\cs_new_eq:NN \int_use:N \tex_the:D
+\cs_new:Npn \int_use:c #1 { \tex_the:D \cs:w #1 \cs_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Integer expression conditionals}
+%
+% \begin{macro}[EXP]{\@@_compare_error:, \@@_compare_error:Nw}
+% Those functions are used for comparison tests which use a simple
+% syntax where only one set of braces is required and additional
+% operators such as |!=| and |>=| are supported. The tests first
+% evaluate their left-hand side, with a trailing
+% \cs{@@_compare_error:}. This marker is normally not expanded,
+% but if the relation symbol is missing from the test's argument, then
+% the marker inserts |=| (and itself) after triggering the relevant
+% \TeX{} error. If the first token which appears after evaluating and
+% removing the left-hand side is not a known relation symbol, then a
+% judiciously placed \cs{@@_compare_error:Nw} gets expanded,
+% cleaning up the end of the test and telling the user what the
+% problem was.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compare_error:
+ {
+ \if_int_compare:w \c_zero_int \c_zero_int \fi:
+ =
+ \@@_compare_error:
+ }
+\cs_new:Npn \@@_compare_error:Nw
+ #1#2 \s_@@_stop
+ {
+ { }
+ \c_zero_int \fi:
+ \msg_expandable_error:nnn
+ { kernel } { unknown-comparison } {#1}
+ \prg_return_false:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF, EXP]{\int_compare:n}
+% \begin{macro}[EXP]
+% {\@@_compare:w, \@@_compare:Nw, \@@_compare:NNw, \@@_compare:nnN}
+% \begin{macro}[EXP]
+% {
+% \@@_compare_end_=:NNw,
+% \@@_compare_=:NNw,
+% \@@_compare_<:NNw,
+% \@@_compare_>:NNw,
+% \@@_compare_==:NNw,
+% \@@_compare_!=:NNw,
+% \@@_compare_<=:NNw,
+% \@@_compare_>=:NNw
+% }
+% Comparison tests using a simple syntax where only one set of braces
+% is required, additional operators such as |!=| and |>=| are
+% supported, and multiple comparisons can be performed at once, for
+% instance |0 < 5 <= 1|. The idea is to loop through the argument,
+% finding one operand at a time, and comparing it to the previous one.
+% The looping auxiliary \cs{@@_compare:Nw} reads one \meta{operand}
+% and one \meta{comparison} symbol, and leaves roughly
+% \begin{quote}
+% \meta{operand} \cs{prg_return_false:} \cs{fi:} \\
+% \cs{reverse_if:N} \cs{if_int_compare:w} \meta{operand} \meta{comparison} \\
+% \cs{@@_compare:Nw}
+% \end{quote}
+% in the input stream. Each call to this auxiliary provides the
+% second operand of the last call's \cs{if_int_compare:w}. If one of
+% the \meta{comparisons} is \texttt{false}, the \texttt{true} branch
+% of the \TeX{} conditional is taken (because of \cs{reverse_if:N}),
+% immediately returning \texttt{false} as the result of the test.
+% There is no \TeX{} conditional waiting the first operand, so we add
+% an \cs{if_false:} and expand by hand with \cs{int_value:w}, thus
+% skipping \cs{prg_return_false:} on the first iteration.
+%
+% Before starting the loop, the first step is to make sure that there
+% is at least one relation symbol. We first let \TeX{} evaluate this
+% left hand side of the (in)equality using \cs{@@_eval:w}. Since the
+% relation symbols |<|, |>|, |=| and |!| are not allowed in integer
+% expressions, they would terminate the expression. If the argument contains no
+% relation symbol, \cs{@@_compare_error:} is expanded,
+% inserting~|=| and itself after an error. In all cases,
+% \cs{@@_compare:w} receives as its argument an integer, a relation
+% symbol, and some more tokens. We then setup the loop, which is
+% ended by the two odd-looking items |e| and |{=nd_}|, with a trailing
+% \cs{s_@@_stop} used to grab the entire argument when necessary.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \int_compare:n #1 { p , T , F , TF }
+ {
+ \exp_after:wN \@@_compare:w
+ \int_value:w \@@_eval:w #1 \@@_compare_error:
+ }
+\cs_new:Npn \@@_compare:w #1 \@@_compare_error:
+ {
+ \exp_after:wN \if_false: \int_value:w
+ \@@_compare:Nw #1 e { = nd_ } \s_@@_stop
+ }
+% \end{macrocode}
+% The goal here is to find an \meta{operand} and a \meta{comparison}.
+% The \meta{operand} is already evaluated, but we cannot yet grab it
+% as an argument. To access the following relation symbol, we remove
+% the number by applying \cs{@@_to_roman:w}, after making sure that
+% the argument becomes non-positive: its roman numeral representation
+% is then empty. Then probe the first two tokens with
+% \cs{@@_compare:NNw} to determine the relation symbol, building a
+% control sequence from it (\cs{token_to_str:N} gives better errors if
+% |#1| is not a character). All the extended forms have an extra |=|
+% hence the test for that as a second token. If the relation symbol
+% is unknown, then the control sequence is turned by \TeX{} into
+% \cs{scan_stop:}, ignored thanks to \tn{unexpanded}, and
+% \cs{@@_compare_error:Nw} raises an error.
+% \begin{macrocode}
+\cs_new:Npn \@@_compare:Nw #1#2 \s_@@_stop
+ {
+ \exp_after:wN \@@_compare:NNw
+ \@@_to_roman:w - 0 #2 \s_@@_mark
+ #1#2 \s_@@_stop
+ }
+\cs_new:Npn \@@_compare:NNw #1#2#3 \s_@@_mark
+ {
+ \__kernel_exp_not:w
+ \use:c
+ {
+ @@_compare_ \token_to_str:N #1
+ \if_meaning:w = #2 = \fi:
+ :NNw
+ }
+ \@@_compare_error:Nw #1
+ }
+% \end{macrocode}
+% When the last \meta{operand} is seen, \cs{@@_compare:NNw} receives
+% |e| and |=nd_| as arguments, hence calling
+% \cs{@@_compare_end_=:NNw} to end the loop: return the result of the
+% last comparison (involving the operand that we just found). When a
+% normal relation is found, the appropriate auxiliary calls
+% \cs{@@_compare:nnN} where |#1| is \cs{if_int_compare:w} or
+% \cs{reverse_if:N} \cs{if_int_compare:w}, |#2| is the \meta{operand},
+% and |#3| is one of |<|, |=|, or~|>|. As announced earlier, we leave
+% the \meta{operand} for the previous conditional. If this
+% conditional is true the result of the test is known, so we remove
+% all tokens and return \texttt{false}. Otherwise, we apply the
+% conditional |#1| to the \meta{operand} |#2| and the comparison |#3|,
+% and call \cs{@@_compare:Nw} to look for additional operands, after
+% evaluating the following expression.
+% \begin{macrocode}
+\cs_new:cpn { @@_compare_end_=:NNw } #1#2#3 e #4 \s_@@_stop
+ {
+ {#3} \exp_stop_f:
+ \prg_return_false: \else: \prg_return_true: \fi:
+ }
+\cs_new:Npn \@@_compare:nnN #1#2#3
+ {
+ {#2} \exp_stop_f:
+ \prg_return_false: \exp_after:wN \@@_use_none_delimit_by_s_stop:w
+ \fi:
+ #1 #2 #3 \exp_after:wN \@@_compare:Nw \int_value:w \@@_eval:w
+ }
+% \end{macrocode}
+% The actual comparisons are then simple function calls, using the
+% relation as delimiter for a delimited argument and discarding
+% \cs{@@_compare_error:Nw} \meta{token} responsible for error
+% detection.
+% \begin{macrocode}
+\cs_new:cpn { @@_compare_=:NNw } #1#2#3 =
+ { \@@_compare:nnN { \reverse_if:N \if_int_compare:w } {#3} = }
+\cs_new:cpn { @@_compare_<:NNw } #1#2#3 <
+ { \@@_compare:nnN { \reverse_if:N \if_int_compare:w } {#3} < }
+\cs_new:cpn { @@_compare_>:NNw } #1#2#3 >
+ { \@@_compare:nnN { \reverse_if:N \if_int_compare:w } {#3} > }
+\cs_new:cpn { @@_compare_==:NNw } #1#2#3 ==
+ { \@@_compare:nnN { \reverse_if:N \if_int_compare:w } {#3} = }
+\cs_new:cpn { @@_compare_!=:NNw } #1#2#3 !=
+ { \@@_compare:nnN { \if_int_compare:w } {#3} = }
+\cs_new:cpn { @@_compare_<=:NNw } #1#2#3 <=
+ { \@@_compare:nnN { \if_int_compare:w } {#3} > }
+\cs_new:cpn { @@_compare_>=:NNw } #1#2#3 >=
+ { \@@_compare:nnN { \if_int_compare:w } {#3} < }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\int_compare:nNn}
+% \UnitTested
+% More efficient but less natural in typing.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \int_compare:nNn #1#2#3 { p , T , F , TF }
+ {
+ \if_int_compare:w \@@_eval:w #1 #2 \@@_eval:w #3 \@@_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\int_if_zero:n}
+% \begin{macrocode}
+\prg_new_conditional:Npnn \int_if_zero:n #1 { p , T , F , TF }
+ {
+ \if_int_compare:w \@@_eval:w #1 = \c_zero_int
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, noTF]{\int_case:nn}
+% \begin{macro}{\@@_case:nnTF}
+% \begin{macro}{\@@_case:nw, \@@_case_end:nw}
+% For integer cases, the first task to fully expand the check
+% condition. The over all idea is then much the same as for
+% \cs{str_case:nnTF} as described in \pkg{l3str}.
+% \begin{macrocode}
+\cs_new:Npn \int_case:nnTF #1
+ {
+ \exp:w
+ \exp_args:Nf \@@_case:nnTF { \int_eval:n {#1} }
+ }
+\cs_new:Npn \int_case:nnT #1#2#3
+ {
+ \exp:w
+ \exp_args:Nf \@@_case:nnTF { \int_eval:n {#1} } {#2} {#3} { }
+ }
+\cs_new:Npn \int_case:nnF #1#2
+ {
+ \exp:w
+ \exp_args:Nf \@@_case:nnTF { \int_eval:n {#1} } {#2} { }
+ }
+\cs_new:Npn \int_case:nn #1#2
+ {
+ \exp:w
+ \exp_args:Nf \@@_case:nnTF { \int_eval:n {#1} } {#2} { } { }
+ }
+\cs_new:Npn \@@_case:nnTF #1#2#3#4
+ { \@@_case:nw {#1} #2 {#1} { } \s_@@_mark {#3} \s_@@_mark {#4} \s_@@_stop }
+\cs_new:Npn \@@_case:nw #1#2#3
+ {
+ \int_compare:nNnTF {#1} = {#2}
+ { \@@_case_end:nw {#3} }
+ { \@@_case:nw {#1} }
+ }
+\cs_new:Npn \@@_case_end:nw #1#2#3 \s_@@_mark #4#5 \s_@@_stop
+ { \exp_end: #1 #4 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\int_if_odd:n}
+% \UnitTested
+% \begin{macro}[pTF]{\int_if_even:n}
+% \UnitTested
+% A predicate function.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \int_if_odd:n #1 { p , T , F , TF}
+ {
+ \if_int_odd:w \@@_eval:w #1 \@@_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_new_conditional:Npnn \int_if_even:n #1 { p , T , F , TF}
+ {
+ \reverse_if:N \if_int_odd:w \@@_eval:w #1 \@@_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Integer expression loops}
+%
+% \begin{macro}{\int_while_do:nn}
+% \UnitTested
+% \TestMissing{Boundary cases}
+% \begin{macro}{\int_until_do:nn}
+% \UnitTested
+% \TestMissing{Boundary cases}
+% \begin{macro}{\int_do_while:nn}
+% \UnitTested
+% \TestMissing{Boundary cases}
+% \begin{macro}{\int_do_until:nn}
+% \UnitTested
+% \TestMissing{Boundary cases}
+% These are quite easy given the above functions. The |while| versions
+% test first and then execute the body. The |do_while| does it the
+% other way round.
+% \begin{macrocode}
+\cs_new:Npn \int_while_do:nn #1#2
+ {
+ \int_compare:nT {#1}
+ {
+ #2
+ \int_while_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \int_until_do:nn #1#2
+ {
+ \int_compare:nF {#1}
+ {
+ #2
+ \int_until_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \int_do_while:nn #1#2
+ {
+ #2
+ \int_compare:nT {#1}
+ { \int_do_while:nn {#1} {#2} }
+ }
+\cs_new:Npn \int_do_until:nn #1#2
+ {
+ #2
+ \int_compare:nF {#1}
+ { \int_do_until:nn {#1} {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_while_do:nNnn}
+% \begin{macro}{\int_until_do:nNnn}
+% \begin{macro}{\int_do_while:nNnn}
+% \begin{macro}{\int_do_until:nNnn}
+% As above but not using the more natural syntax.
+% \begin{macrocode}
+\cs_new:Npn \int_while_do:nNnn #1#2#3#4
+ {
+ \int_compare:nNnT {#1} #2 {#3}
+ {
+ #4
+ \int_while_do:nNnn {#1} #2 {#3} {#4}
+ }
+ }
+\cs_new:Npn \int_until_do:nNnn #1#2#3#4
+ {
+ \int_compare:nNnF {#1} #2 {#3}
+ {
+ #4
+ \int_until_do:nNnn {#1} #2 {#3} {#4}
+ }
+ }
+\cs_new:Npn \int_do_while:nNnn #1#2#3#4
+ {
+ #4
+ \int_compare:nNnT {#1} #2 {#3}
+ { \int_do_while:nNnn {#1} #2 {#3} {#4} }
+ }
+\cs_new:Npn \int_do_until:nNnn #1#2#3#4
+ {
+ #4
+ \int_compare:nNnF {#1} #2 {#3}
+ { \int_do_until:nNnn {#1} #2 {#3} {#4} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Integer step functions}
+%
+% \begin{macro}{\int_step_function:nnnN}
+% \begin{macro}{\@@_step:wwwN, \@@_step:NwnnN}
+% \begin{macro}{\int_step_function:nN}
+% \begin{macro}{\int_step_function:nnN}
+% Before all else, evaluate the initial value, step, and final value.
+% Repeating a function by steps first needs a check on the direction
+% of the steps. After that, do the function for the start value then
+% step and loop around. It would be more symmetrical to test for a
+% step size of zero before checking the sign, but we optimize for the
+% most frequent case (positive step).
+% \begin{macrocode}
+\cs_new:Npn \int_step_function:nnnN #1#2#3
+ {
+ \exp_after:wN \@@_step:wwwN
+ \int_value:w \@@_eval:w #1 \exp_after:wN ;
+ \int_value:w \@@_eval:w #2 \exp_after:wN ;
+ \int_value:w \@@_eval:w #3 ;
+ }
+\cs_new:Npn \@@_step:wwwN #1; #2; #3; #4
+ {
+ \int_compare:nNnTF {#2} > \c_zero_int
+ { \@@_step:NwnnN > }
+ {
+ \int_compare:nNnTF {#2} = \c_zero_int
+ {
+ \msg_expandable_error:nnn
+ { kernel } { zero-step } {#4}
+ \prg_break:
+ }
+ { \@@_step:NwnnN < }
+ }
+ #1 ; {#2} {#3} #4
+ \prg_break_point:
+ }
+\cs_new:Npn \@@_step:NwnnN #1#2 ; #3#4#5
+ {
+ \if_int_compare:w #2 #1 #4 \exp_stop_f:
+ \prg_break:n
+ \fi:
+ #5 {#2}
+ \exp_after:wN \@@_step:NwnnN
+ \exp_after:wN #1
+ \int_value:w \@@_eval:w #2 + #3 ; {#3} {#4} #5
+ }
+\cs_new:Npn \int_step_function:nN
+ { \int_step_function:nnnN { 1 } { 1 } }
+\cs_new:Npn \int_step_function:nnN #1
+ { \int_step_function:nnnN {#1} { 1 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_step_inline:nn, \int_step_inline:nnn, \int_step_inline:nnnn}
+% \begin{macro}{\int_step_variable:nNn, \int_step_variable:nnNn, \int_step_variable:nnnNn}
+% \UnitTested
+% \begin{macro}{\@@_step:NNnnnn}
+% The approach here is to build a function, with a global integer
+% required to make the nesting safe (as seen in other in line
+% functions), and map that function using \cs{int_step_function:nnnN}.
+% We put a \cs{prg_break_point:Nn} so that \texttt{map_break}
+% functions from other modules correctly decrement \cs{g__kernel_prg_map_int}
+% before looking for their own break point. The first argument is
+% \cs{scan_stop:}, so that no breaking function recognizes this break
+% point as its own.
+% \begin{macrocode}
+\cs_new_protected:Npn \int_step_inline:nn
+ { \int_step_inline:nnnn { 1 } { 1 } }
+\cs_new_protected:Npn \int_step_inline:nnn #1
+ { \int_step_inline:nnnn {#1} { 1 } }
+\cs_new_protected:Npn \int_step_inline:nnnn
+ {
+ \int_gincr:N \g__kernel_prg_map_int
+ \exp_args:NNc \@@_step:NNnnnn
+ \cs_gset_protected:Npn
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
+ }
+\cs_new_protected:Npn \int_step_variable:nNn
+ { \int_step_variable:nnnNn { 1 } { 1 } }
+\cs_new_protected:Npn \int_step_variable:nnNn #1
+ { \int_step_variable:nnnNn {#1} { 1 } }
+\cs_new_protected:Npn \int_step_variable:nnnNn #1#2#3#4#5
+ {
+ \int_gincr:N \g__kernel_prg_map_int
+ \exp_args:NNc \@@_step:NNnnnn
+ \cs_gset_protected:Npe
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
+ {#1}{#2}{#3}
+ {
+ \tl_set:Nn \exp_not:N #4 {##1}
+ \exp_not:n {#5}
+ }
+ }
+\cs_new_protected:Npn \@@_step:NNnnnn #1#2#3#4#5#6
+ {
+ #1 #2 ##1 {#6}
+ \int_step_function:nnnN {#3} {#4} {#5} #2
+ \prg_break_point:Nn \scan_stop: { \int_gdecr:N \g__kernel_prg_map_int }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Formatting integers}
+%
+% \begin{macro}{\int_to_arabic:n, \int_to_arabic:v}
+% \UnitTested
+% Nothing exciting here.
+% \begin{macrocode}
+\cs_new_eq:NN \int_to_arabic:n \int_eval:n
+\cs_generate_variant:Nn \int_to_arabic:n { v }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_to_symbols:nnn}
+% \UnitTested
+% \begin{macro}{\@@_to_symbols:nnnn, \@@_to_symbols:ennn}
+% For conversion of integers to arbitrary symbols the method is in
+% general as follows. The input number (|#1|) is compared to the total
+% number of symbols available at each place (|#2|). If the input is larger
+% than the total number of symbols available then the modulus is needed,
+% with one added so that the positions don't have to number from
+% zero. Using an \texttt{f}-type expansion, this is done so that the system
+% is recursive. The actual conversion function therefore gets a `nice'
+% number at each stage. Of course, if the initial input was small enough
+% then there is no problem and everything is easy.
+% \begin{macrocode}
+\cs_new:Npn \int_to_symbols:nnn #1#2#3
+ {
+ \int_compare:nNnTF {#1} > {#2}
+ {
+ \@@_to_symbols:ennn
+ {
+ \int_case:nn
+ { 1 + \int_mod:nn { #1 - 1 } {#2} }
+ {#3}
+ }
+ {#1} {#2} {#3}
+ }
+ { \int_case:nn {#1} {#3} }
+ }
+\cs_new:Npn \@@_to_symbols:nnnn #1#2#3#4
+ {
+ \exp_args:Nf \int_to_symbols:nnn
+ { \int_div_truncate:nn { #2 - 1 } {#3} } {#3} {#4}
+ #1
+ }
+\cs_generate_variant:Nn \@@_to_symbols:nnnn { e }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_to_alph:n, \int_to_Alph:n}
+% \UnitTested
+% These both use the above function with input functions that make sense
+% for the alphabet in English.
+% \begin{macrocode}
+\cs_new:Npn \int_to_alph:n #1
+ {
+ \int_to_symbols:nnn {#1} { 26 }
+ {
+ { 1 } { a }
+ { 2 } { b }
+ { 3 } { c }
+ { 4 } { d }
+ { 5 } { e }
+ { 6 } { f }
+ { 7 } { g }
+ { 8 } { h }
+ { 9 } { i }
+ { 10 } { j }
+ { 11 } { k }
+ { 12 } { l }
+ { 13 } { m }
+ { 14 } { n }
+ { 15 } { o }
+ { 16 } { p }
+ { 17 } { q }
+ { 18 } { r }
+ { 19 } { s }
+ { 20 } { t }
+ { 21 } { u }
+ { 22 } { v }
+ { 23 } { w }
+ { 24 } { x }
+ { 25 } { y }
+ { 26 } { z }
+ }
+ }
+\cs_new:Npn \int_to_Alph:n #1
+ {
+ \int_to_symbols:nnn {#1} { 26 }
+ {
+ { 1 } { A }
+ { 2 } { B }
+ { 3 } { C }
+ { 4 } { D }
+ { 5 } { E }
+ { 6 } { F }
+ { 7 } { G }
+ { 8 } { H }
+ { 9 } { I }
+ { 10 } { J }
+ { 11 } { K }
+ { 12 } { L }
+ { 13 } { M }
+ { 14 } { N }
+ { 15 } { O }
+ { 16 } { P }
+ { 17 } { Q }
+ { 18 } { R }
+ { 19 } { S }
+ { 20 } { T }
+ { 21 } { U }
+ { 22 } { V }
+ { 23 } { W }
+ { 24 } { X }
+ { 25 } { Y }
+ { 26 } { Z }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_to_base:nn, \int_to_Base:nn}
+% \UnitTested
+% \begin{macro}{\@@_to_base:nn, \@@_to_Base:nn,
+% \@@_to_base:nnN, \@@_to_Base:nnN, \@@_to_base:nnnN, \@@_to_Base:nnnN}
+% \begin{macro}{\@@_to_letter:n, \@@_to_Letter:n}
+% \UnitTested
+% Converting from base ten (|#1|) to a second base (|#2|) starts with
+% computing |#1|: if it is a complicated calculation, we shouldn't
+% perform it twice. Then check the sign, store it, either \texttt{-}
+% or \cs{c_empty_tl}, and feed the absolute value to the next auxiliary
+% function.
+% \begin{macrocode}
+\cs_new:Npn \int_to_base:nn #1
+ { \exp_args:Nf \@@_to_base:nn { \int_eval:n {#1} } }
+\cs_new:Npn \int_to_Base:nn #1
+ { \exp_args:Nf \@@_to_Base:nn { \int_eval:n {#1} } }
+\cs_new:Npn \@@_to_base:nn #1#2
+ {
+ \int_compare:nNnTF {#1} < 0
+ { \exp_args:No \@@_to_base:nnN { \use_none:n #1 } {#2} - }
+ { \@@_to_base:nnN {#1} {#2} \c_empty_tl }
+ }
+\cs_new:Npn \@@_to_Base:nn #1#2
+ {
+ \int_compare:nNnTF {#1} < 0
+ { \exp_args:No \@@_to_Base:nnN { \use_none:n #1 } {#2} - }
+ { \@@_to_Base:nnN {#1} {#2} \c_empty_tl }
+ }
+% \end{macrocode}
+% Here, the idea is to provide a recursive system to deal with the
+% input. The output is built up after the end of the function.
+% At each pass, the value in |#1| is checked to see if it is less
+% than the new base (|#2|). If it is, then it is converted directly,
+% putting the sign back in front.
+% On the other hand, if the value to convert is greater than or equal
+% to the new base then the modulus and remainder values are found. The
+% modulus is converted to a symbol and put on the right,
+% and the remainder is carried forward to the next round.
+% \begin{macrocode}
+\cs_new:Npn \@@_to_base:nnN #1#2#3
+ {
+ \int_compare:nNnTF {#1} < {#2}
+ { \exp_last_unbraced:Nf #3 { \@@_to_letter:n {#1} } }
+ {
+ \exp_args:Nf \@@_to_base:nnnN
+ { \@@_to_letter:n { \int_mod:nn {#1} {#2} } }
+ {#1}
+ {#2}
+ #3
+ }
+ }
+\cs_new:Npn \@@_to_base:nnnN #1#2#3#4
+ {
+ \exp_args:Nf \@@_to_base:nnN
+ { \int_div_truncate:nn {#2} {#3} }
+ {#3}
+ #4
+ #1
+ }
+\cs_new:Npn \@@_to_Base:nnN #1#2#3
+ {
+ \int_compare:nNnTF {#1} < {#2}
+ { \exp_last_unbraced:Nf #3 { \@@_to_Letter:n {#1} } }
+ {
+ \exp_args:Nf \@@_to_Base:nnnN
+ { \@@_to_Letter:n { \int_mod:nn {#1} {#2} } }
+ {#1}
+ {#2}
+ #3
+ }
+ }
+\cs_new:Npn \@@_to_Base:nnnN #1#2#3#4
+ {
+ \exp_args:Nf \@@_to_Base:nnN
+ { \int_div_truncate:nn {#2} {#3} }
+ {#3}
+ #4
+ #1
+ }
+% \end{macrocode}
+% Convert to a letter only if necessary, otherwise simply return the
+% value unchanged. It would be cleaner to use \cs{int_case:nn},
+% but in our case, the cases are contiguous, so it is forty times faster
+% to use the \cs{if_case:w} primitive. The first \cs{exp_after:wN}
+% expands the conditional, jumping to the correct case, the second one
+% expands after the resulting character to close the conditional.
+% Since |#1| might be an expression, and not directly a single digit,
+% we need to evaluate it properly, and expand the trailing \cs{fi:}.
+% \begin{macrocode}
+\cs_new:Npn \@@_to_letter:n #1
+ {
+ \exp_after:wN \exp_after:wN
+ \if_case:w \@@_eval:w #1 - 10 \@@_eval_end:
+ a
+ \or: b
+ \or: c
+ \or: d
+ \or: e
+ \or: f
+ \or: g
+ \or: h
+ \or: i
+ \or: j
+ \or: k
+ \or: l
+ \or: m
+ \or: n
+ \or: o
+ \or: p
+ \or: q
+ \or: r
+ \or: s
+ \or: t
+ \or: u
+ \or: v
+ \or: w
+ \or: x
+ \or: y
+ \or: z
+ \else: \int_value:w \@@_eval:w #1 \exp_after:wN \@@_eval_end:
+ \fi:
+ }
+\cs_new:Npn \@@_to_Letter:n #1
+ {
+ \exp_after:wN \exp_after:wN
+ \if_case:w \@@_eval:w #1 - 10 \@@_eval_end:
+ A
+ \or: B
+ \or: C
+ \or: D
+ \or: E
+ \or: F
+ \or: G
+ \or: H
+ \or: I
+ \or: J
+ \or: K
+ \or: L
+ \or: M
+ \or: N
+ \or: O
+ \or: P
+ \or: Q
+ \or: R
+ \or: S
+ \or: T
+ \or: U
+ \or: V
+ \or: W
+ \or: X
+ \or: Y
+ \or: Z
+ \else: \int_value:w \@@_eval:w #1 \exp_after:wN \@@_eval_end:
+ \fi:
+ }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+% \begin{macro}{\int_to_bin:n, \int_to_hex:n, \int_to_Hex:n, \int_to_oct:n}
+% \UnitTested
+% Wrappers around the generic function.
+% \begin{macrocode}
+\cs_new:Npn \int_to_bin:n #1
+ { \int_to_base:nn {#1} { 2 } }
+\cs_new:Npn \int_to_hex:n #1
+ { \int_to_base:nn {#1} { 16 } }
+\cs_new:Npn \int_to_Hex:n #1
+ { \int_to_Base:nn {#1} { 16 } }
+\cs_new:Npn \int_to_oct:n #1
+ { \int_to_base:nn {#1} { 8 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_to_roman:n, \int_to_Roman:n}
+% \UnitTested
+% \begin{macro}{\@@_to_roman:N, \@@_to_roman:N}
+% \begin{macro}
+% {
+% \@@_to_roman_i:w, \@@_to_roman_v:w, \@@_to_roman_x:w,
+% \@@_to_roman_l:w, \@@_to_roman_c:w, \@@_to_roman_d:w,
+% \@@_to_roman_m:w, \@@_to_roman_Q:w,
+% \@@_to_Roman_i:w, \@@_to_Roman_v:w, \@@_to_Roman_x:w,
+% \@@_to_Roman_l:w, \@@_to_Roman_c:w, \@@_to_Roman_d:w,
+% \@@_to_Roman_m:w, \@@_to_Roman_Q:w,
+% }
+% The \cs{@@_to_roman:w} primitive creates tokens of category
+% code $12$ (other). Usually, what is actually wanted is letters.
+% The approach here is to convert the output of the primitive into
+% letters using appropriate control sequence names. That keeps
+% everything expandable. The loop is terminated by the conversion
+% of the |Q|.
+% \begin{macrocode}
+\cs_new:Npn \int_to_roman:n #1
+ {
+ \exp_after:wN \@@_to_roman:N
+ \@@_to_roman:w \int_eval:n {#1} Q
+ }
+\cs_new:Npn \@@_to_roman:N #1
+ {
+ \use:c { @@_to_roman_ #1 :w }
+ \@@_to_roman:N
+ }
+\cs_new:Npn \int_to_Roman:n #1
+ {
+ \exp_after:wN \@@_to_Roman_aux:N
+ \@@_to_roman:w \int_eval:n {#1} Q
+ }
+\cs_new:Npn \@@_to_Roman_aux:N #1
+ {
+ \use:c { @@_to_Roman_ #1 :w }
+ \@@_to_Roman_aux:N
+ }
+\cs_new:Npn \@@_to_roman_i:w { i }
+\cs_new:Npn \@@_to_roman_v:w { v }
+\cs_new:Npn \@@_to_roman_x:w { x }
+\cs_new:Npn \@@_to_roman_l:w { l }
+\cs_new:Npn \@@_to_roman_c:w { c }
+\cs_new:Npn \@@_to_roman_d:w { d }
+\cs_new:Npn \@@_to_roman_m:w { m }
+\cs_new:Npn \@@_to_roman_Q:w #1 { }
+\cs_new:Npn \@@_to_Roman_i:w { I }
+\cs_new:Npn \@@_to_Roman_v:w { V }
+\cs_new:Npn \@@_to_Roman_x:w { X }
+\cs_new:Npn \@@_to_Roman_l:w { L }
+\cs_new:Npn \@@_to_Roman_c:w { C }
+\cs_new:Npn \@@_to_Roman_d:w { D }
+\cs_new:Npn \@@_to_Roman_m:w { M }
+\cs_new:Npn \@@_to_Roman_Q:w #1 { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Converting from other formats to integers}
+%
+% \begin{macro}[rEXP]{\@@_pass_signs:wn, \@@_pass_signs_end:wn}
+% Called as \cs{@@_pass_signs:wn} \meta{signs and digits} \cs{s_@@_stop}
+% \Arg{code}, this function leaves in the input stream any sign it
+% finds, then inserts the \meta{code} before the first non-sign token
+% (and removes \cs{s_@@_stop}). More precisely, it deletes any~|+| and
+% passes any~|-| to the input stream, hence should be called in an
+% integer expression.
+% \begin{macrocode}
+\cs_new:Npn \@@_pass_signs:wn #1
+ {
+ \if:w + \if:w - \exp_not:N #1 + \fi: \exp_not:N #1
+ \exp_after:wN \@@_pass_signs:wn
+ \else:
+ \exp_after:wN \@@_pass_signs_end:wn
+ \exp_after:wN #1
+ \fi:
+ }
+\cs_new:Npn \@@_pass_signs_end:wn #1 \s_@@_stop #2 { #2 #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_from_alph:n}
+% \UnitTested
+% \begin{macro}{\@@_from_alph:nN, \@@_from_alph:N}
+% First take care of signs then loop through the input using the
+% \texttt{recursion} quarks. The \cs{@@_from_alph:nN} auxiliary
+% collects in its first argument the value obtained so far, and the
+% auxiliary \cs{@@_from_alph:N} converts one letter to an expression
+% which evaluates to the correct number.
+% \begin{macrocode}
+\cs_new:Npn \int_from_alph:n #1
+ {
+ \int_eval:n
+ {
+ \exp_after:wN \@@_pass_signs:wn \tl_to_str:n {#1}
+ \s_@@_stop { \@@_from_alph:nN { 0 } }
+ \q_@@_recursion_tail \q_@@_recursion_stop
+ }
+ }
+\cs_new:Npn \@@_from_alph:nN #1#2
+ {
+ \@@_if_recursion_tail_stop_do:Nn #2 {#1}
+ \exp_args:Nf \@@_from_alph:nN
+ { \int_eval:n { #1 * 26 + \@@_from_alph:N #2 } }
+ }
+\cs_new:Npn \@@_from_alph:N #1
+ { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 64 } { 96 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_from_base:nn}
+% \UnitTested
+% \begin{macro}{\@@_from_base:nnN, \@@_from_base:N}
+% Leave the signs into the integer expression, then loop through
+% characters, collecting the value found so far in the first argument
+% of \cs{@@_from_base:nnN}. To convert a single character,
+% \cs{@@_from_base:N} checks first for digits, then distinguishes
+% lower from upper case letters, turning them into the appropriate
+% number. Note that this auxiliary does not use \cs{int_eval:n},
+% hence is not safe for general use.
+% \begin{macrocode}
+\cs_new:Npn \int_from_base:nn #1#2
+ {
+ \int_eval:n
+ {
+ \exp_after:wN \@@_pass_signs:wn \tl_to_str:n {#1}
+ \s_@@_stop { \@@_from_base:nnN { 0 } {#2} }
+ \q_@@_recursion_tail \q_@@_recursion_stop
+ }
+ }
+\cs_new:Npn \@@_from_base:nnN #1#2#3
+ {
+ \@@_if_recursion_tail_stop_do:Nn #3 {#1}
+ \exp_args:Nf \@@_from_base:nnN
+ { \int_eval:n { #1 * #2 + \@@_from_base:N #3 } }
+ {#2}
+ }
+\cs_new:Npn \@@_from_base:N #1
+ {
+ \int_compare:nNnTF { `#1 } < { 58 }
+ {#1}
+ { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 55 } { 87 } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_from_bin:n, \int_from_hex:n, \int_from_oct:n}
+% \UnitTested
+% Wrappers around the generic function.
+% \begin{macrocode}
+\cs_new:Npn \int_from_bin:n #1
+ { \int_from_base:nn {#1} { 2 } }
+\cs_new:Npn \int_from_hex:n #1
+ { \int_from_base:nn {#1} { 16 } }
+\cs_new:Npn \int_from_oct:n #1
+ { \int_from_base:nn {#1} { 8 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}
+% {
+% \c_@@_from_roman_i_int, \c_@@_from_roman_v_int,
+% \c_@@_from_roman_x_int, \c_@@_from_roman_l_int,
+% \c_@@_from_roman_c_int, \c_@@_from_roman_d_int,
+% \c_@@_from_roman_m_int,
+% \c_@@_from_roman_I_int, \c_@@_from_roman_V_int,
+% \c_@@_from_roman_X_int, \c_@@_from_roman_L_int,
+% \c_@@_from_roman_C_int, \c_@@_from_roman_D_int,
+% \c_@@_from_roman_M_int
+% }
+% Constants used to convert from Roman numerals to integers.
+% \begin{macrocode}
+\int_const:cn { c_@@_from_roman_i_int } { 1 }
+\int_const:cn { c_@@_from_roman_v_int } { 5 }
+\int_const:cn { c_@@_from_roman_x_int } { 10 }
+\int_const:cn { c_@@_from_roman_l_int } { 50 }
+\int_const:cn { c_@@_from_roman_c_int } { 100 }
+\int_const:cn { c_@@_from_roman_d_int } { 500 }
+\int_const:cn { c_@@_from_roman_m_int } { 1000 }
+\int_const:cn { c_@@_from_roman_I_int } { 1 }
+\int_const:cn { c_@@_from_roman_V_int } { 5 }
+\int_const:cn { c_@@_from_roman_X_int } { 10 }
+\int_const:cn { c_@@_from_roman_L_int } { 50 }
+\int_const:cn { c_@@_from_roman_C_int } { 100 }
+\int_const:cn { c_@@_from_roman_D_int } { 500 }
+\int_const:cn { c_@@_from_roman_M_int } { 1000 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\int_from_roman:n}
+% \UnitTested
+% \TestMissing{boundary cases / wrong input?}
+% \begin{macro}{\@@_from_roman:NN}
+% \begin{macro}{\@@_from_roman_error:w}
+% The method here is to iterate through the input, finding the
+% appropriate value for each letter and building up a sum. This is
+% then evaluated by \TeX{}. If any unknown letter is found, skip to
+% the closing parenthesis and insert |*0-1| afterwards, to replace the
+% value by $-1$.
+% \begin{macrocode}
+\cs_new:Npn \int_from_roman:n #1
+ {
+ \int_eval:n
+ {
+ (
+ 0
+ \exp_after:wN \@@_from_roman:NN \tl_to_str:n {#1}
+ \q_@@_recursion_tail \q_@@_recursion_tail \q_@@_recursion_stop
+ )
+ }
+ }
+\cs_new:Npn \@@_from_roman:NN #1#2
+ {
+ \@@_if_recursion_tail_stop:N #1
+ \int_if_exist:cF { c_@@_from_roman_ #1 _int }
+ { \@@_from_roman_error:w }
+ \@@_if_recursion_tail_stop_do:Nn #2
+ { + \use:c { c_@@_from_roman_ #1 _int } }
+ \int_if_exist:cF { c_@@_from_roman_ #2 _int }
+ { \@@_from_roman_error:w }
+ \int_compare:nNnTF
+ { \use:c { c_@@_from_roman_ #1 _int } }
+ <
+ { \use:c { c_@@_from_roman_ #2 _int } }
+ {
+ + \use:c { c_@@_from_roman_ #2 _int }
+ - \use:c { c_@@_from_roman_ #1 _int }
+ \@@_from_roman:NN
+ }
+ {
+ + \use:c { c_@@_from_roman_ #1 _int }
+ \@@_from_roman:NN #2
+ }
+ }
+\cs_new:Npn \@@_from_roman_error:w #1 \q_@@_recursion_stop #2
+ { #2 * 0 - 1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Viewing integer}
+%
+% \begin{macro}{\int_show:N, \int_show:c}
+% \UnitTested
+% \begin{macro}{\@@_show:nN}
+% Diagnostics.
+% \begin{macrocode}
+\cs_new_eq:NN \int_show:N \__kernel_register_show:N
+\cs_generate_variant:Nn \int_show:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_show:n}
+% \UnitTested
+% We don't use the \TeX{} primitive \tn{showthe} to show integer
+% expressions: this gives a more unified output.
+% \begin{macrocode}
+\cs_new_protected:Npn \int_show:n
+ { \__kernel_msg_show_eval:Nn \int_eval:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_log:N, \int_log:c}
+% Diagnostics.
+% \begin{macrocode}
+\cs_new_eq:NN \int_log:N \__kernel_register_log:N
+\cs_generate_variant:Nn \int_log:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_log:n}
+% Similar to \cs{int_show:n}.
+% \begin{macrocode}
+\cs_new_protected:Npn \int_log:n
+ { \__kernel_msg_log_eval:Nn \int_eval:n }
+% \end{macrocode}
+% \end{macro}
+%
+%\subsection{Random integers}
+%
+% \begin{macro}{\int_rand:nn}
+% Defined in \pkg{l3fp-random}.
+% \end{macro}
+%
+% \subsection{Constant integers}
+%
+% \begin{variable}{\c_zero_int, \c_one_int}
+% The zero is defined in \pkg{l3basics}.
+% \begin{macrocode}
+\int_const:Nn \c_one_int { 1 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_max_int}
+% The largest number allowed is $2^{31}-1$
+% \begin{macrocode}
+\int_const:Nn \c_max_int { 2 147 483 647 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_max_char_int}
+% The largest character code is $1114111$ (hexadecimal |10FFFF|) in
+% \XeTeX{} and \LuaTeX{} and $255$ in other engines. In many places
+% \pTeX{} and \upTeX{} support larger character codes but for instance
+% the values of \tn{lccode} are restricted to $[0,255]$.
+% \begin{macrocode}
+\int_const:Nn \c_max_char_int
+ {
+ \if_int_odd:w 0
+ \cs_if_exist:NT \tex_luatexversion:D { 1 }
+ \cs_if_exist:NT \tex_XeTeXversion:D { 1 } ~
+ "10FFFF
+ \else:
+ "FF
+ \fi:
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Scratch integers}
+%
+% \begin{variable}{\l_tmpa_int, \l_tmpb_int}
+% \begin{variable}{\g_tmpa_int, \g_tmpb_int}
+% We provide two local and two global scratch counters, maybe we
+% need more or less.
+% \begin{macrocode}
+\int_new:N \l_tmpa_int
+\int_new:N \l_tmpb_int
+\int_new:N \g_tmpa_int
+\int_new:N \g_tmpb_int
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \subsection{Integers for earlier modules}
+%
+%<@@=seq>
+%
+% \begin{variable}{\l_@@_internal_a_int, \l_@@_internal_b_int}
+% \begin{macrocode}
+\int_new:N \l_@@_internal_a_int
+\int_new:N \l_@@_internal_b_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3intarray.dtx b/macros/latex-dev/required/l3kernel/l3intarray.dtx
new file mode 100644
index 0000000000..bbc41c0cdb
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3intarray.dtx
@@ -0,0 +1,974 @@
+% \iffalse meta-comment
+%
+%% File: l3intarray.dtx
+%
+% Copyright (C) 2017-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+%
+% \title{^^A
+% The \pkg{l3intarray} module\\ Fast global integer arrays^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% For applications requiring heavy use of integers, this module provides
+% arrays which can be accessed in constant time (contrast \pkg{l3seq},
+% where access time is linear). These arrays have several important
+% features
+% \begin{itemize}
+% \item The size of the array is fixed and must be given at
+% point of initialisation
+% \item The absolute value of each entry has maximum $2^{30}-1$
+% (\emph{i.e.}~one power lower than the usual \cs{c_max_int}
+% ceiling of $2^{31}-1$)
+% \end{itemize}
+% The use of \texttt{intarray} data is therefore recommended for cases where
+% the need for fast access is of paramount importance.
+%
+% \section{Creating and initialising integer array variables}
+%
+% \begin{function}[added = 2018-03-29]{\intarray_new:Nn, \intarray_new:cn}
+% \begin{syntax}
+% \cs{intarray_new:Nn} \meta{intarray~var} \Arg{size}
+% \end{syntax}
+% Evaluates the integer expression \meta{size} and allocates an
+% \meta{integer array variable} with that number of (zero) entries.
+% The variable name should start with |\g_| because assignments are
+% always global.
+% \end{function}
+%
+% \begin{function}[added = 2018-05-04]
+% {\intarray_const_from_clist:Nn, \intarray_const_from_clist:cn}
+% \begin{syntax}
+% \cs{intarray_const_from_clist:Nn} \meta{intarray~var} \meta{int expr clist}
+% \end{syntax}
+% Creates a new constant \meta{integer array variable} or raises an
+% error if the name is already taken. The \meta{integer array
+% variable} is set (globally) to contain as its items the results of
+% evaluating each \meta{integer expression} in the \meta{comma list}.
+% \end{function}
+%
+% \begin{function}[added = 2018-05-04]{\intarray_gzero:N, \intarray_gzero:c}
+% \begin{syntax}
+% \cs{intarray_gzero:N} \meta{intarray~var}
+% \end{syntax}
+% Sets all entries of the \meta{integer array variable} to zero.
+% Assignments are always global.
+% \end{function}
+%
+% \section{Adding data to integer arrays}
+%
+% \begin{function}[added = 2018-03-29]{\intarray_gset:Nnn, \intarray_gset:cnn}
+% \begin{syntax}
+% \cs{intarray_gset:Nnn} \meta{intarray~var} \Arg{position} \Arg{value}
+% \end{syntax}
+% Stores the result of evaluating the integer expression \meta{value}
+% into the \meta{integer array variable} at the (integer expression)
+% \meta{position}. If the \meta{position} is not between $1$ and the
+% \cs{intarray_count:N}, or the \meta{value}'s absolute value is
+% bigger than $2^{30}-1$, an error occurs. Assignments are always
+% global.
+% \end{function}
+%
+% \section{Couting entries in integer arrays}
+%
+% \begin{function}[EXP, added = 2018-03-29]{\intarray_count:N, \intarray_count:c}
+% \begin{syntax}
+% \cs{intarray_count:N} \meta{intarray~var}
+% \end{syntax}
+% Expands to the number of entries in the \meta{integer array variable}.
+% Contrarily to \cs{seq_count:N} this is performed in constant time.
+% \end{function}
+%
+% \section{Using a single entry}
+%
+% \begin{function}[EXP, added = 2018-03-29]{\intarray_item:Nn, \intarray_item:cn}
+% \begin{syntax}
+% \cs{intarray_item:Nn} \meta{intarray~var} \Arg{position}
+% \end{syntax}
+% Expands to the integer entry stored at the (integer expression)
+% \meta{position} in the \meta{integer array variable}. If the
+% \meta{position} is not between $1$ and the \cs{intarray_count:N}, an
+% error occurs.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2018-05-05]
+% {\intarray_rand_item:N, \intarray_rand_item:c}
+% \begin{syntax}
+% \cs{intarray_rand_item:N} \meta{intarray~var}
+% \end{syntax}
+% Selects a pseudo-random item of the \meta{integer array}. If the
+% \meta{integer array} is empty, produce an error.
+% \end{function}
+%
+% \section{Integer array conditional}
+%
+% \begin{function}[pTF, added = 2024-03-31]
+% {\intarray_if_exist:N, \intarray_if_exist:c}
+% \begin{syntax}
+% \cs{intarray_if_exist_p:N} \meta{intarray~var}
+% \cs{intarray_if_exist:NTF} \meta{intarray~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{intarray~var} is currently defined. This
+% does not check that the \meta{intarray~var} really is an integer
+% array variable.
+% \end{function}
+%
+% \section{Viewing integer arrays}
+%
+% \begin{function}[added = 2018-05-04]
+% {\intarray_show:N, \intarray_show:c, \intarray_log:N, \intarray_log:c}
+% \begin{syntax}
+% \cs{intarray_show:N} \meta{intarray~var}
+% \cs{intarray_log:N} \meta{intarray~var}
+% \end{syntax}
+% Displays the items in the \meta{integer array variable} in the
+% terminal or writes them in the log file.
+% \end{function}
+%
+% \section{Implementation notes}
+%
+% It is a wrapper around the \tn{fontdimen} primitive, used to store
+% arrays of integers (with a restricted range: absolute value at most
+% $2^{30}-1$). In contrast to \pkg{l3seq} sequences the access to
+% individual entries is done in constant time rather than linear time,
+% but only integers can be stored. More precisely, the primitive
+% \tn{fontdimen} stores dimensions but the \pkg{l3intarray} module
+% transparently converts these from/to integers. Assignments are always
+% global.
+%
+% While \LuaTeX{}'s memory is extensible, other engines can
+% \enquote{only} deal with a bit less than $4\times 10^6$ entries in all
+% \tn{fontdimen} arrays combined (with default \TeX{} Live settings).
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3intarray} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=intarray>
+% \end{macrocode}
+%
+% There are two implementations for this module: One \cs{fontdimen} based one
+% for more traditional \TeX\ engines and a Lua based one for engines with Lua support.
+%
+% Both versions do not allow negative array sizes.
+% \begin{macrocode}
+%<*tex>
+\msg_new:nnn { kernel } { negative-array-size }
+ { Size~of~array~may~not~be~negative:~#1 }
+% \end{macrocode}
+%
+% \begin{variable}{\l_@@_loop_int}
+% A loop index.
+% \begin{macrocode}
+\int_new:N \l_@@_loop_int
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Lua implementation}
+% First, let's look at the Lua variant:
+%
+% We select the Lua version if the Lua helpers were defined. This can be detected by
+% the presence of \cs{@@_gset_count:Nw}.
+%
+% \begin{macrocode}
+\cs_if_exist:NTF \@@_gset_count:Nw
+ {
+% \end{macrocode}
+%
+% \subsubsection{Allocating arrays}
+%
+% \begin{variable}{\g_@@_table_int, \l_@@_bad_index_int}
+% Used to differentiate intarrays in Lua and to record an invalid index.
+% \begin{macrocode}
+ \int_new:N \g_@@_table_int
+ \int_new:N \l_@@_bad_index_int
+%</tex>
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@:w}
+% Used as marker for intarrays in Lua. Followed by an unbraced number
+% identifying the array and a single space. This format is used to make it
+% easy to scan from Lua.
+% \begin{macrocode}
+%<*lua>
+luacmd('@@:w', function()
+ scan_int()
+ tex.error'LaTeX Error: Isolated intarray ignored'
+end, 'protected', 'global')
+%</lua>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\intarray_new:Nn, \intarray_new:cn}
+% \begin{macro}{\@@_new:N}
+% Declare |#1| as a tokenlist with the scanmark and a unique number.
+% Pass the array's size to the Lua helper.
+% Every \texttt{intarray} must be global; it's enough to run this
+% check in \cs{intarray_new:Nn}.
+% \begin{macrocode}
+%<*tex>
+ \cs_new_protected:Npn \@@_new:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \int_gincr:N \g_@@_table_int
+ \cs_gset_nopar:Npe #1 { \@@:w \int_use:N \g_@@_table_int \c_space_tl }
+ }
+ \cs_new_protected:Npn \intarray_new:Nn #1#2
+ {
+ \@@_new:N #1
+ \@@_gset_count:Nw #1 \int_eval:n {#2} \scan_stop:
+ \int_compare:nNnT { \intarray_count:N #1 } < 0
+ {
+ \msg_error:nne { kernel } { negative-array-size }
+ { \intarray_count:N #1 }
+ }
+ }
+ \cs_generate_variant:Nn \intarray_new:Nn { c }
+%</tex>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Before we get to the first command implmented in Lua, we first need some
+% definitions. Since \texttt{token.create} only works correctly if \TeX{}
+% has seen the tokens before, we first run a short \TeX{} sequence to ensure
+% that all relevant control sequences are known.
+% \begin{macrocode}
+%<*lua>
+
+local scan_token = token.scan_token
+local put_next = token.put_next
+local intarray_marker = token_create_safe'@@:w'
+local use_none = token_create_safe'use_none:n'
+local use_i = token_create_safe'use:n'
+local expand_after_scan_stop = {token_create_safe'exp_after:wN',
+ token_create_safe'scan_stop:'}
+local comma = token_create(string.byte',')
+% \end{macrocode}
+%
+% \begin{macro}{@@_table}
+% Internal helper to scan an intarray token, extract the associated
+% Lua table and return an error if the input is invalid.
+%
+% \begin{macrocode}
+local @@_table do
+ local tables = get_luadata and get_luadata'@@' or {[0] = {}}
+ function @@_table()
+ local t = scan_token()
+ if t ~= intarray_marker then
+ put_next(t)
+ tex.error'LaTeX Error: intarray expected'
+ return tables[0]
+ end
+ local i = scan_int()
+ local current_table = tables[i]
+ if current_table then return current_table end
+ current_table = {}
+ tables[i] = current_table
+ return current_table
+ end
+% \end{macrocode}
+% Since in \LaTeX{} this is loaded in the format, we want to preserve any intarrays
+% which are created while format building for the actual run.
+%
+% To do this, we use the \texttt{register_luadata} mechanism from \pkg{l3luatex}:
+% Directly before the format get dumped, the following function gets invoked and serializes
+% all existing tables into a string. This string gets compiled and dumped into the format and
+% is made available at the beginning of regular runs as \texttt{get_luadata'@@'}.
+% \begin{macrocode}
+ if register_luadata then
+ register_luadata('@@', function()
+ local t = "{[0]={},"
+ for i=1, #tables do
+ t = string.format("%s{%s},", t, table.concat(tables[i], ','))
+ end
+ return t .. "}"
+ end)
+ end
+end
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\intarray_count:N, \intarray_count:c}
+% \begin{macro}[EXP]{\@@_gset_count:Nw}
+% Set and get the size of an array. ``Setting the size'' means in this context that
+% we add zeros until we reach the desired size.
+% \begin{macrocode}
+
+local sprint = tex.sprint
+
+luacmd('@@_gset_count:Nw', function()
+ local t = @@_table()
+ local n = scan_int()
+ for i=#t+1, n do t[i] = 0 end
+end, 'protected', 'global')
+
+luacmd('intarray_count:N', function()
+ sprint(-2, #@@_table())
+end, 'global')
+%</lua>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*tex>
+ \cs_generate_variant:Nn \intarray_count:N { c }
+%</tex>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Array items}
+%
+% \begin{macro}{\@@_gset:wF, \@@_gset:w}
+% The setter provided by Lua. The argument order somewhat emulates the |\fontdimen|:
+% First the array index, followed by the intarray and then the new value.
+% This has been chosen over a more conventional order to provide a delimiter for the numbers.
+% \begin{macrocode}
+%<*lua>
+luacmd('@@_gset:wF', function()
+ local i = scan_int()
+ local t = @@_table()
+ if t[i] then
+ t[i] = scan_int()
+ put_next(use_none)
+ else
+ tex.count.l_@@_bad_index_int = i
+ scan_int()
+ put_next(use_i)
+ end
+end, 'protected', 'global')
+
+luacmd('@@_gset:w', function()
+ local i = scan_int()
+ local t = @@_table()
+ t[i] = scan_int()
+end, 'protected', 'global')
+%</lua>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\intarray_gset:Nnn, \intarray_gset:cnn, \__kernel_intarray_gset:Nnn}
+% The \cs{__kernel_intarray_gset:Nnn} function does not use
+% \cs{int_eval:n}, namely its arguments must be suitable for
+% \cs{int_value:w}. The user version checks the position and value
+% are within bounds.
+% \begin{macrocode}
+%<*tex>
+ \cs_new_protected:Npn \__kernel_intarray_gset:Nnn #1#2#3
+ { \@@_gset:w #2 #1 #3 \scan_stop: }
+ \cs_new_protected:Npn \intarray_gset:Nnn #1#2#3
+ {
+ \@@_gset:wF \int_eval:n {#2} #1 \int_eval:n{#3}
+ {
+ \msg_error:nneee { kernel } { out-of-bounds }
+ { \token_to_str:N #1 } { \int_use:N \l_@@_bad_index_int } { \intarray_count:N #1 }
+ }
+ }
+ \cs_generate_variant:Nn \intarray_gset:Nnn { c }
+%</tex>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\intarray_gzero:N, \intarray_gzero:c}
+% Set the appropriate array entry to zero. No bound checking
+% needed.
+% \begin{macrocode}
+%<*lua>
+luacmd('intarray_gzero:N', function()
+ local t = @@_table()
+ for i=1, #t do
+ t[i] = 0
+ end
+end, 'global', 'protected')
+%</lua>
+%<*tex>
+ \cs_generate_variant:Nn \intarray_gzero:N { c }
+%</tex>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\intarray_item:Nn, \intarray_item:cn, \__kernel_intarray_item:Nn}
+% \begin{macro}{\@@_item:wF,\@@_item:w}
+% Get the appropriate entry and perform bound checks. The
+% \cs{__kernel_intarray_item:Nn} function omits bound checks and omits
+% \cs{int_eval:n}, namely its argument must be a \TeX{} integer
+% suitable for \cs{int_value:w}.
+% \begin{macrocode}
+%<*lua>
+luacmd('@@_item:wF', function()
+ local i = scan_int()
+ local t = @@_table()
+ local item = t[i]
+ if item then
+ put_next(use_none)
+ else
+ tex.l_@@_bad_index_int = i
+ put_next(use_i)
+ end
+ put_next(expand_after_scan_stop)
+ scan_token()
+ if item then
+ sprint(-2, item)
+ end
+end, 'global')
+
+luacmd('@@_item:w', function()
+ local i = scan_int()
+ local t = @@_table()
+ sprint(-2, t[i])
+end, 'global')
+%</lua>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*tex>
+ \cs_new:Npn \__kernel_intarray_item:Nn #1#2
+ { \@@_item:w #2 #1 }
+ \cs_new:Npn \intarray_item:Nn #1#2
+ {
+ \@@_item:wF \int_eval:n {#2} #1
+ {
+ \msg_expandable_error:nnfff { kernel } { out-of-bounds }
+ { \token_to_str:N #1 } { \int_use:N \l_@@_bad_index_int } { \intarray_count:N #1 }
+ 0
+ }
+ }
+ \cs_generate_variant:Nn \intarray_item:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\intarray_rand_item:N, \intarray_rand_item:c}
+% Importantly, \cs{intarray_item:Nn} only evaluates its argument once.
+% \begin{macrocode}
+ \cs_new:Npn \intarray_rand_item:N #1
+ { \intarray_item:Nn #1 { \int_rand:n { \intarray_count:N #1 } } }
+ \cs_generate_variant:Nn \intarray_rand_item:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Working with contents of integer arrays}
+%
+% \begin{macro}{\intarray_const_from_clist:Nn, \intarray_const_from_clist:cn}
+% We use the \cs{__kernel_intarray_gset:Nnn} which does not do bounds checking
+% and instead automatically resizes the array.
+% This is not implemented in Lua to ensure that the clist parsing is consistent
+% with the clist module.
+% \begin{macrocode}
+ \cs_new_protected:Npn \intarray_const_from_clist:Nn #1#2
+ {
+ \@@_new:N #1
+ \int_zero:N \l_@@_loop_int
+ \clist_map_inline:nn {#2}
+ {
+ \int_incr:N \l_@@_loop_int
+ \__kernel_intarray_gset:Nnn #1 \l_@@_loop_int { \int_eval:n {##1} } }
+ }
+ \cs_generate_variant:Nn \intarray_const_from_clist:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_to_clist:Nn, \@@_to_clist:w}
+% The \cs{@@_to_clist:Nn} auxiliary allows to choose the delimiter and
+% is also used in \cs{intarray_show:N}. Here we just pass the information
+% to Lua and let \texttt{table.concat} do the actual work.
+% We discard the category codes of the passed delimiter but this is not
+% an issue since the delimiter is always just a comma or a comma and a space.
+% In both cases \texttt{sprint(2, ...)} provides the right catcodes.
+% \begin{macrocode}
+%</tex>
+%<*lua>
+local concat = table.concat
+luacmd('@@_to_clist:Nn', function()
+ local t = @@_table()
+ local sep = token.scan_string()
+ sprint(-2, concat(t, sep))
+end, 'global')
+%</lua>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\__kernel_intarray_range_to_clist:Nnn, \@@_range_to_clist:w}
+% Loop through part of the array.
+% \begin{macrocode}
+%<*tex>
+ \cs_new:Npn \__kernel_intarray_range_to_clist:Nnn #1#2#3
+ {
+ \@@_range_to_clist:w #1
+ \int_eval:n {#2} ~ \int_eval:n {#3} ~
+ }
+%</tex>
+%<*lua>
+luacmd('@@_range_to_clist:w', function()
+ local t = @@_table()
+ local from = scan_int()
+ local to = scan_int()
+ sprint(-2, concat(t, ',', from, to))
+end, 'global')
+%</lua>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_intarray_gset_range_from_clist:Nnn, \@@_gset_range:nNw}
+% Loop through part of the array. We allow additional commas at the end.
+% \begin{macrocode}
+%<*tex>
+ \cs_new_protected:Npn \__kernel_intarray_gset_range_from_clist:Nnn #1#2#3
+ {
+ \@@_gset_range:w \int_eval:w #2 #1 #3 , , \scan_stop:
+ }
+%</tex>
+%<*lua>
+luacmd('@@_gset_range:w', function()
+ local from = scan_int()
+ local t = @@_table()
+ while true do
+ local tok = scan_token()
+ if tok == comma then
+ repeat
+ tok = scan_token()
+ until tok ~= comma
+ break
+ else
+ put_next(tok)
+ end
+ t[from] = scan_int()
+ scan_token()
+ from = from + 1
+ end
+ end, 'global', 'protected')
+%</lua>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_gset_overflow_test:nw}
+% In order to allow some code sharing later we provide the
+% \cs{@@_gset_overflow_test:nw} name here. It doesn't actually test anything
+% since the Lua implementation accepts all integers which could be tested with
+% \cs{tex_ifabsnum:D}.
+% \begin{macrocode}
+%<*tex>
+ \cs_new_protected:Npn \@@_gset_overflow_test:nw #1
+ {
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Font dimension based implementation}
+%
+% Go to the false branch of the conditional above.
+% \begin{macrocode}
+ }
+ {
+% \end{macrocode}
+%
+% \subsubsection{Allocating arrays}
+%
+% \begin{macro}{\@@_entry:w, \@@_count:w}
+% We use these primitives quite a lot in this module.
+% \begin{macrocode}
+ \cs_new_eq:NN \@@_entry:w \tex_fontdimen:D
+ \cs_new_eq:NN \@@_count:w \tex_hyphenchar:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\c_@@_sp_dim}
+% Used to convert integers to dimensions fast.
+% \begin{macrocode}
+ \dim_const:Nn \c_@@_sp_dim { 1 sp }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_font_int}
+% Used to assign one font per array.
+% \begin{macrocode}
+ \int_new:N \g_@@_font_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\intarray_new:Nn, \intarray_new:cn}
+% \begin{macro}{\@@_new:N}
+% Declare |#1| to be a font (arbitrarily |cmr10| at a never-used
+% size). Store the array's size as the \tn{hyphenchar} of that font
+% and make sure enough \tn{fontdimen} are allocated, by setting the
+% last one. Then clear any \tn{fontdimen} that |cmr10| starts with.
+% It seems \LuaTeX{}'s |cmr10| has an extra \tn{fontdimen} parameter
+% number $8$ compared to other engines (for a math font we would
+% replace $8$ by $22$ or some such).
+% Every \texttt{intarray} must be global; it's enough to run this
+% check in \cs{intarray_new:Nn}.
+% \begin{macrocode}
+ \cs_new_protected:Npn \@@_new:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \int_gincr:N \g_@@_font_int
+ \tex_global:D \tex_font:D #1
+ = cmr10~at~ \g_@@_font_int \c_@@_sp_dim \scan_stop:
+ \int_step_inline:nn { 8 }
+ { \__kernel_intarray_gset:Nnn #1 {##1} \c_zero_int }
+ }
+ \cs_new_protected:Npn \intarray_new:Nn #1#2
+ {
+ \@@_new:N #1
+ \@@_count:w #1 = \int_eval:n {#2} \scan_stop:
+ \int_compare:nNnT { \intarray_count:N #1 } < 0
+ {
+ \msg_error:nne { kernel } { negative-array-size }
+ { \intarray_count:N #1 }
+ }
+ \int_compare:nNnT { \intarray_count:N #1 } > 0
+ { \__kernel_intarray_gset:Nnn #1 { \intarray_count:N #1 } { 0 } }
+ }
+ \cs_generate_variant:Nn \intarray_new:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\intarray_count:N, \intarray_count:c}
+% Size of an array.
+% \begin{macrocode}
+ \cs_new:Npn \intarray_count:N #1 { \int_value:w \@@_count:w #1 }
+ \cs_generate_variant:Nn \intarray_count:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Array items}
+%
+% \begin{macro}[EXP]{\@@_signed_max_dim:n}
+% Used when an item to be stored is larger than \cs{c_max_dim} in
+% absolute value; it is replaced by $\pm\cs{c_max_dim}$.
+% \begin{macrocode}
+ \cs_new:Npn \@@_signed_max_dim:n #1
+ { \int_value:w \int_compare:nNnT {#1} < 0 { - } \c_max_dim }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_bounds:NNnTF, \@@_bounds_error:NNnw}
+% The functions \cs{intarray_gset:Nnn} and \cs{intarray_item:Nn} share
+% bounds checking. The |T| branch is used if |#3| is within bounds of
+% the array |#2|.
+% \begin{macrocode}
+ \cs_new:Npn \@@_bounds:NNnTF #1#2#3
+ {
+ \if_int_compare:w 1 > #3 \exp_stop_f:
+ \@@_bounds_error:NNnw #1 #2 {#3}
+ \else:
+ \if_int_compare:w #3 > \intarray_count:N #2 \exp_stop_f:
+ \@@_bounds_error:NNnw #1 #2 {#3}
+ \fi:
+ \fi:
+ \use_i:nn
+ }
+ \cs_new:Npn \@@_bounds_error:NNnw #1#2#3#4 \use_i:nn #5#6
+ {
+ #4
+ #1 { kernel } { out-of-bounds }
+ { \token_to_str:N #2 } {#3} { \intarray_count:N #2 }
+ #6
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\intarray_gset:Nnn, \intarray_gset:cnn, \__kernel_intarray_gset:Nnn}
+% \begin{macro}{\@@_gset:Nnn, \@@_gset_overflow:Nnn}
+% Set the appropriate \tn{fontdimen}. The
+% \cs{__kernel_intarray_gset:Nnn} function does not use
+% \cs{int_eval:n}, namely its arguments must be suitable for
+% \cs{int_value:w}. The user version checks the position and value
+% are within bounds.
+% \begin{macrocode}
+ \cs_new_protected:Npn \__kernel_intarray_gset:Nnn #1#2#3
+ { \@@_entry:w #2 #1 #3 \c_@@_sp_dim }
+ \cs_new_protected:Npn \intarray_gset:Nnn #1#2#3
+ {
+ \exp_after:wN \@@_gset:Nww
+ \exp_after:wN #1
+ \int_value:w \int_eval:n {#2} \exp_after:wN ;
+ \int_value:w \int_eval:n {#3} ;
+ }
+ \cs_generate_variant:Nn \intarray_gset:Nnn { c }
+ \cs_new_protected:Npn \@@_gset:Nww #1#2 ; #3 ;
+ {
+ \@@_bounds:NNnTF \msg_error:nneee #1 {#2}
+ {
+ \@@_gset_overflow_test:nw {#3}
+ \__kernel_intarray_gset:Nnn #1 {#2} {#3}
+ }
+ { }
+ }
+ \cs_if_exist:NTF \tex_ifabsnum:D
+ {
+ \cs_new_protected:Npn \@@_gset_overflow_test:nw #1
+ {
+ \tex_ifabsnum:D #1 > \c_max_dim
+ \exp_after:wN \@@_gset_overflow:NNnn
+ \fi:
+ }
+ }
+ {
+ \cs_new_protected:Npn \@@_gset_overflow_test:nw #1
+ {
+ \if_int_compare:w \int_abs:n {#1} > \c_max_dim
+ \exp_after:wN \@@_gset_overflow:NNnn
+ \fi:
+ }
+ }
+ \cs_new_protected:Npn \@@_gset_overflow:NNnn #1#2#3#4
+ {
+ \msg_error:nneeee { kernel } { overflow }
+ { \token_to_str:N #2 } {#3} {#4} { \@@_signed_max_dim:n {#4} }
+ #1 #2 {#3} { \@@_signed_max_dim:n {#4} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\intarray_gzero:N, \intarray_gzero:c}
+% Set the appropriate \tn{fontdimen} to zero. No bound checking
+% needed. The \cs{prg_replicate:nn} possibly uses quite a lot of
+% memory, but this is somewhat comparable to the size of the array,
+% and it is much faster than an \cs{int_step_inline:nn} loop.
+% \begin{macrocode}
+ \cs_new_protected:Npn \intarray_gzero:N #1
+ {
+ \int_zero:N \l_@@_loop_int
+ \prg_replicate:nn { \intarray_count:N #1 }
+ {
+ \int_incr:N \l_@@_loop_int
+ \@@_entry:w \l_@@_loop_int #1 \c_zero_dim
+ }
+ }
+ \cs_generate_variant:Nn \intarray_gzero:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\intarray_item:Nn, \intarray_item:cn, \__kernel_intarray_item:Nn}
+% \begin{macro}{\@@_item:Nw}
+% Get the appropriate \tn{fontdimen} and perform bound checks. The
+% \cs{__kernel_intarray_item:Nn} function omits bound checks and omits
+% \cs{int_eval:n}, namely its argument must be a \TeX{} integer
+% suitable for \cs{int_value:w}.
+% \begin{macrocode}
+ \cs_new:Npn \__kernel_intarray_item:Nn #1#2
+ { \int_value:w \@@_entry:w #2 #1 }
+ \cs_new:Npn \intarray_item:Nn #1#2
+ {
+ \exp_after:wN \@@_item:Nw
+ \exp_after:wN #1
+ \int_value:w \int_eval:n {#2} ;
+ }
+ \cs_generate_variant:Nn \intarray_item:Nn { c }
+ \cs_new:Npn \@@_item:Nw #1#2 ;
+ {
+ \@@_bounds:NNnTF \msg_expandable_error:nnfff #1 {#2}
+ { \__kernel_intarray_item:Nn #1 {#2} }
+ { 0 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\intarray_rand_item:N, \intarray_rand_item:c}
+% Importantly, \cs{intarray_item:Nn} only evaluates its argument once.
+% \begin{macrocode}
+ \cs_new:Npn \intarray_rand_item:N #1
+ { \intarray_item:Nn #1 { \int_rand:n { \intarray_count:N #1 } } }
+ \cs_generate_variant:Nn \intarray_rand_item:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Working with contents of integer arrays}
+%
+% \begin{macro}{\intarray_const_from_clist:Nn, \intarray_const_from_clist:cn}
+% \begin{macro}{\@@_const_from_clist:nN}
+% Similar to \cs{intarray_new:Nn} (which we don't use because when
+% debugging is enabled that function checks the variable name starts
+% with |g_|). We make use of the fact that \TeX{} allows allocation
+% of successive \tn{fontdimen} as long as no other font has been
+% declared: no need to count the comma list items first. We need the
+% code in \cs{intarray_gset:Nnn} that checks the item value is not too
+% big, namely \cs{@@_gset_overflow_test:nw}, but not the code that
+% checks bounds. At the end, set the size of the intarray.
+% \begin{macrocode}
+ \cs_new_protected:Npn \intarray_const_from_clist:Nn #1#2
+ {
+ \@@_new:N #1
+ \int_zero:N \l_@@_loop_int
+ \clist_map_inline:nn {#2}
+ { \exp_args:Nf \@@_const_from_clist:nN { \int_eval:n {##1} } #1 }
+ \@@_count:w #1 \l_@@_loop_int
+ }
+ \cs_generate_variant:Nn \intarray_const_from_clist:Nn { c }
+ \cs_new_protected:Npn \@@_const_from_clist:nN #1#2
+ {
+ \int_incr:N \l_@@_loop_int
+ \@@_gset_overflow_test:nw {#1}
+ \__kernel_intarray_gset:Nnn #2 \l_@@_loop_int {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_to_clist:Nn, \@@_to_clist:w}
+% Loop through the array, putting a comma before each item. Remove
+% the leading comma with |f|-expansion. We also use the auxiliary in
+% \cs{intarray_show:N} with argument comma, space.
+% \begin{macrocode}
+ \cs_new:Npn \@@_to_clist:Nn #1#2
+ {
+ \int_compare:nNnF { \intarray_count:N #1 } = \c_zero_int
+ {
+ \exp_last_unbraced:Nf \use_none:n
+ { \@@_to_clist:w 1 ; #1 {#2} \prg_break_point: }
+ }
+ }
+ \cs_new:Npn \@@_to_clist:w #1 ; #2#3
+ {
+ \if_int_compare:w #1 > \@@_count:w #2
+ \prg_break:n
+ \fi:
+ #3 \__kernel_intarray_item:Nn #2 {#1}
+ \exp_after:wN \@@_to_clist:w
+ \int_value:w \int_eval:w #1 + \c_one_int ; #2 {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\__kernel_intarray_range_to_clist:Nnn, \@@_range_to_clist:ww}
+% Loop through part of the array.
+% \begin{macrocode}
+ \cs_new:Npn \__kernel_intarray_range_to_clist:Nnn #1#2#3
+ {
+ \exp_last_unbraced:Nf \use_none:n
+ {
+ \exp_after:wN \@@_range_to_clist:ww
+ \int_value:w \int_eval:w #2 \exp_after:wN ;
+ \int_value:w \int_eval:w #3 ;
+ #1 \prg_break_point:
+ }
+ }
+ \cs_new:Npn \@@_range_to_clist:ww #1 ; #2 ; #3
+ {
+ \if_int_compare:w #1 > #2 \exp_stop_f:
+ \prg_break:n
+ \fi:
+ , \__kernel_intarray_item:Nn #3 {#1}
+ \exp_after:wN \@@_range_to_clist:ww
+ \int_value:w \int_eval:w #1 + \c_one_int ; #2 ; #3
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_intarray_gset_range_from_clist:Nnn, \@@_gset_range:Nw}
+% Loop through part of the array.
+% \begin{macrocode}
+ \cs_new_protected:Npn \__kernel_intarray_gset_range_from_clist:Nnn #1#2#3
+ {
+ \int_set:Nn \l_@@_loop_int {#2}
+ \@@_gset_range:Nw #1 #3 , , \prg_break_point:
+ }
+ \cs_new_protected:Npn \@@_gset_range:Nw #1 #2 ,
+ {
+ \if_catcode:w \scan_stop: \tl_to_str:n {#2} \scan_stop:
+ \prg_break:n
+ \fi:
+ \__kernel_intarray_gset:Nnn #1 \l_@@_loop_int {#2}
+ \int_incr:N \l_@@_loop_int
+ \@@_gset_range:Nw #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+ }
+% \end{macrocode}
+%
+% \subsection{Common parts}
+%
+% \begin{macro}[pTF]{\intarray_if_exist:N, \intarray_if_exist:c}
+% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \intarray_if_exist:N \cs_if_exist:N
+ { TF , T , F , p }
+\prg_new_eq_conditional:NNn \intarray_if_exist:c \cs_if_exist:c
+ { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\intarray_show:N, \intarray_show:c, \intarray_log:N, \intarray_log:c}
+% Convert the list to a comma list (with spaces after each comma)
+% \begin{macrocode}
+\cs_new_protected:Npn \intarray_show:N { \@@_show:NN \msg_show:nneeee }
+\cs_generate_variant:Nn \intarray_show:N { c }
+\cs_new_protected:Npn \intarray_log:N { \@@_show:NN \msg_log:nneeee }
+\cs_generate_variant:Nn \intarray_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_chk_defined:NT #2
+ {
+ #1 { intarray } { show }
+ { \token_to_str:N #2 }
+ { \intarray_count:N #2 }
+ { >~ \@@_to_clist:Nn #2 { , ~ } }
+ { }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</tex>
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3kernel-functions.dtx b/macros/latex-dev/required/l3kernel/l3kernel-functions.dtx
new file mode 100644
index 0000000000..1706bb594a
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3kernel-functions.dtx
@@ -0,0 +1,739 @@
+% \iffalse meta-comment
+%
+%% File: l3kernel-functions.dtx
+%
+% Copyright (C) 2018-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3kernel-functions} module\\ Kernel-reserved functions^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3kernel-functions}: kernel-reserved functions}
+%
+% \subsection{Internal \pkg{l3debug} kernel functions}
+% \label{sec:l3kernel-functions:l3debug-internals}
+%
+% These function are only created if debugging is enabled, hence they are
+% actually defined in \pkg{l3debug}.
+%
+% \begin{function}{\__kernel_chk_var_local:N, \__kernel_chk_var_global:N}
+% \begin{syntax}
+% \cs{__kernel_chk_var_local:N} \meta{var}
+% \cs{__kernel_chk_var_global:N} \meta{var}
+% \end{syntax}
+% Applies \cs{__kernel_chk_var_exist:N} \meta{var} as well as
+% \cs{__kernel_chk_var_scope:NN} \meta{scope} \meta{var}, where
+% \meta{scope} is |l| or~|g|.
+% \end{function}
+%
+% \begin{function}{\__kernel_chk_var_scope:NN}
+% \begin{syntax}
+% \cs{__kernel_chk_var_scope:NN} \meta{scope} \meta{var}
+% \end{syntax}
+% Checks the \meta{var} has the correct \meta{scope}, and if not
+% raises a kernel-level error.
+% The \meta{scope} is a single letter |l|, |g|,
+% |c| denoting local variables, global variables, or constants. More
+% precisely, if the variable name starts with a letter and an
+% underscore (normal \pkg{expl3} convention) the function checks that
+% this single letter matches the \meta{scope}. Otherwise the function
+% cannot know the scope \meta{var} the first time: instead, it defines
+% |\__debug_chk_/|\meta{var name} to store that information for the
+% next call. Thus, if a given \meta{var} is subject to assignments of
+% different scopes a kernel error will result.
+% \end{function}
+%
+% \begin{function}
+% {
+% \__kernel_chk_cs_exist:N,
+% \__kernel_chk_cs_exist:c,
+% \__kernel_chk_var_exist:N
+% }
+% \begin{syntax}
+% \cs{__kernel_chk_cs_exist:N} \meta{cs}
+% \cs{__kernel_chk_var_exist:N} \meta{var}
+% \end{syntax}
+% Checks that their argument is defined according to the criteria for
+% \cs{cs_if_exist_p:N},
+% and if not raises a kernel-level error. Error messages are
+% different.
+% \end{function}
+%
+% \begin{function}[EXP]{\__kernel_chk_flag_exist:NN}
+% \begin{syntax}
+% \cs{__kernel_chk_flag_exist:NN}
+% \meta{function} \meta{flag}
+% \end{syntax}
+% Checks that the \meta{flag} is defined according to the criterion for
+% \cs{flag_if_exist_p:N}, and if not raises a kernel-level error and
+% calls the function with the argument \cs{l_tmpa_flag} to proceed
+% somehow without producing too many errors.
+% \end{function}
+%
+% \begin{function}{\__kernel_debug_log:e}
+% \begin{syntax}
+% \cs{__kernel_debug_log:e} \Arg{message text}
+% \end{syntax}
+% If the \texttt{log-functions} option is active, this function writes
+% the \meta{message text} to the log file using \cs{iow_log:e}.
+% Otherwise, the \meta{message text} is ignored using \cs{use_none:n}.
+% \end{function}
+%
+% \subsection{Internal kernel functions}
+%
+% \begin{function}{\__kernel_chk_defined:NT}
+% \begin{syntax}
+% \cs{__kernel_chk_defined:NT} \meta{variable} \Arg{true code}
+% \end{syntax}
+% If \meta{variable} is not defined (according to
+% \cs{cs_if_exist:NTF}), this triggers an error, otherwise the
+% \meta{true code} is run.
+% \end{function}
+%
+% \begin{function}{\__kernel_chk_expr:nNnN}
+% \begin{syntax}
+% \cs{__kernel_chk_expr:nNnN} \Arg{expr} \meta{eval} \Arg{convert} \meta{caller}
+% \end{syntax}
+% This function is only created if debugging is enabled. By default
+% it is equivalent to \cs{use_i:nnnn}. When expression checking is
+% enabled, it leaves in the input stream the result of \cs{tex_the:D}
+% \meta{eval} \meta{expr} \cs{tex_relax:D} after checking that no
+% token was left over. If any token was not taken as part of the
+% expression, there is an error message displaying the result of the
+% evaluation as well as the \meta{caller}. For instance \meta{eval}
+% can be \cs{__int_eval:w} and \meta{caller} can be \cs{int_eval:n} or
+% \cs{int_set:Nn}. The argument \meta{convert} is empty except for mu
+% expressions where it is \cs{tex_mutoglue:D}, used for internal
+% purposes.
+% \end{function}
+%
+% \begin{function}{\__kernel_chk_tl_type:NnnT}
+% \begin{syntax}\parskip=0pt\obeylines
+% \cs{__kernel_chk_tl_type:NnnT} \meta{control sequence} \Arg{specific type} \\
+% | |\Arg{reconstruction} \Arg{true code}
+% \end{syntax}
+% Helper to test that the \meta{control sequence} is a variable of the
+% given \meta{specific type} of token list. Produces suitable error
+% messages if the \meta{control sequence} does not exist, or if it is
+% not a token list variable at all, or if the \meta{control sequence}
+% differs from the result of |e|-expanding \meta{reconstruction}. If
+% all of these tests succeed then the \meta{true code} is run.
+% \end{function}
+%
+% \begin{function}[EXP]{\__kernel_codepoint_to_bytes:n}
+% \begin{syntax}
+% \cs{__kernel_codepoint_to_bytes:n} \Arg{codepoint}
+% \end{syntax}
+% Converts the \meta{codepoint} to UTF-8 bytes. The expansion
+% of this function comprises four brace groups, each of which will contain
+% a hexadecimal value: the appropriate byte. As UTF-8 is a variable-length,
+% one or more of the groups may be empty: the bytes read in the logical order,
+% such that a two-byte codepoint will have groups |#1| and |#2| filled
+% and |#3| and |#4| empty.
+% \end{function}
+%
+% \begin{function}{\__kernel_cs_parm_from_arg_count:nnF}
+% \begin{syntax}
+% \cs{__kernel_cs_parm_from_arg_count:nnF} \Arg{follow-on} \Arg{args} \Arg{false code}
+% \end{syntax}
+% Evaluates the number of \meta{args} and leaves the \meta{follow-on} code
+% followed by a brace group containing the required number of primitive
+% parameter markers (|#1|, \emph{etc}.). If the number of \meta{args} is outside
+% the range $[0,9]$, the \meta{false code} is inserted \emph{instead} of
+% the \meta{follow-on}.
+% \end{function}
+%
+% \begin{function}{
+% \__kernel_dependency_version_check:Nn,
+% \__kernel_dependency_version_check:nn,
+% }
+% \begin{syntax}
+% \cs{__kernel_dependency_version_check:Nn} \Arg{\cs{date}} \Arg{file}
+% \cs{__kernel_dependency_version_check:nn} \Arg{date} \Arg{file}
+% \end{syntax}
+% Checks if the loaded version of the \pkg{expl3} kernel is at least \meta{date},
+% required by \meta{file}. If the kernel date is older than \meta{date}, the
+% loading of \meta{file} is aborted and an error is raised.
+% \end{function}
+%
+% \begin{function}{\__kernel_deprecation_code:nn}
+% \begin{syntax}
+% \cs{__kernel_deprecation_code:nn} \Arg{error code} \Arg{working code}
+% \end{syntax}
+% Stores both an \meta{error} and \meta{working} definition for given material
+% such that they can be exchanged by \cs{debug_on:n} and \cs{debug_off:n}.
+% \end{function}
+%
+% \begin{function}[EXP]{\__kernel_exp_not:w}
+% \begin{syntax}
+% \cs{__kernel_exp_not:w} \meta{expandable tokens} \Arg{content}
+% \end{syntax}
+% Carries out expansion on the \meta{expandable tokens} before preventing
+% further expansion of the \meta{content} as for \cs{exp_not:n}. Typically,
+% the \meta{expandable tokens} will alter the nature of the \meta{content},
+% \emph{i.e.}~allow it to be generated in some way.
+% \end{function}
+%
+% \begin{variable}{\l__kernel_expl_bool}
+% A boolean which records the current code syntax status: \texttt{true} if
+% currently inside a code environment. This variable should only be
+% set by \cs{ExplSyntaxOn}/\cs{ExplSyntaxOff}.
+% \end{variable}
+%
+% \begin{variable}{\c__kernel_expl_date_tl}
+% A token list containing the release date of the \pkg{l3kernel} preloaded
+% in \LaTeXe{} used to check if dependencies match.
+% \end{variable}
+%
+% \begin{function}{\__kernel_file_missing:n}
+% \begin{syntax}
+% \cs{__kernel_file_missing:n} \Arg{name}
+% \end{syntax}
+% Expands the \meta{name} as per \cs{__kernel_file_name_sanitize:n} then
+% produces an error message indicating that this file was not found.
+% \end{function}
+%
+% \begin{function}[EXP,updated = 2021-04-17]{\__kernel_file_name_sanitize:n}
+% \begin{syntax}
+% \cs{__kernel_file_name_sanitize:n} \Arg{name}
+% \end{syntax}
+% Expands the file name using a \tn{csname}-based approach, and
+% relies on active characters (for example from UTF-8 characters)
+% being properly set up to expand to a expansion-safe version using
+% \cs{ifcsname}. This is less conservative than the token-by-token
+% approach used before, but it is much faster.
+% \end{function}
+%
+% \begin{function}{\__kernel_file_input_push:n, \__kernel_file_input_pop:}
+% \begin{syntax}
+% \cs{__kernel_file_input_push:n} \Arg{name}
+% \cs{__kernel_file_input_pop:}
+% \end{syntax}
+% Used to push and pop data from the internal file stack: needed only
+% in package mode, where interfacing with the \LaTeXe{} kernel is necessary.
+% \end{function}
+%
+% \begin{function}[EXP]{\__kernel_int_add:nnn}
+% \begin{syntax}
+% \cs{__kernel_int_add:nnn} \Arg{integer_1} \Arg{integer_2} \Arg{integer_3}
+% \end{syntax}
+% Expands to the result of adding the three \meta{integers} (which
+% must be suitable input for \cs{int_eval:w}), avoiding intermediate
+% overflow. Overflow occurs only if the overall result is outside
+% $[-2^{31}+1,2^{31}-1]$. The \meta{integers} may be of the form
+% \cs{int_eval:w} \dots{} \cs{scan_stop:} but may be evaluated more
+% than once.
+% \end{function}
+%
+% \begin{function}[added = 2018-03-31]{\__kernel_intarray_gset:Nnn}
+% \begin{syntax}
+% \cs{__kernel_intarray_gset:Nnn} \meta{intarray~var} \Arg{index} \Arg{value}
+% \end{syntax}
+% Faster version of \cs{intarray_gset:Nnn}. Stores the \meta{value}
+% into the \meta{integer array variable} at the \meta{position}. The
+% \meta{index} and \meta{value} must be suitable for a direct
+% assignment to a \TeX{} count register, for instance expanding to an
+% integer denotation or obtained through the primitive \tn{numexpr}
+% (which may be un-terminated). No bound checking is performed: the
+% caller is responsible for ensuring that the \meta{position} is
+% between $1$ and the \cs{intarray_count:N}, and the \meta{value}'s
+% absolute value is at most $2^{30}-1$. Assignments are always
+% global.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2018-03-31]{\__kernel_intarray_item:Nn}
+% \begin{syntax}
+% \cs{__kernel_intarray_item:Nn} \meta{intarray~var} \Arg{index}
+% \end{syntax}
+% Faster version of \cs{intarray_item:Nn}. Expands to the integer
+% entry stored at the \meta{index} in the \meta{integer array
+% variable}. The \meta{index} must be suitable for a direct
+% assignment to a \TeX{} count register and must be between $1$ and
+% the \cs{intarray_count:N}, lest a low-level \TeX{} error occur.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2020-07-12]{\__kernel_intarray_range_to_clist:Nnn}
+% \begin{syntax}
+% \cs{__kernel_intarray_range_to_clist:Nnn} \meta{intarray~var} \Arg{start index} \Arg{end index}
+% \end{syntax}
+% Converts to integer denotations separated by commas the entries of
+% the \meta{intarray} from positions \meta{start index} to \meta{end
+% index} included. The \meta{start index} and \meta{end index} must
+% be suitable for a direct assignment to a \TeX{} count register, must
+% be between $1$ and the \cs{intarray_count:N}, and be suitably
+% ordered. All tokens have category code other.
+% \end{function}
+%
+% \begin{function}[added = 2020-07-12]{\__kernel_intarray_gset_range_from_clist:Nnn}
+% \begin{syntax}
+% \cs{__kernel_intarray_gset_range_from_clist:Nnn} \meta{intarray~var} \Arg{start index} \Arg{integer clist}
+% \end{syntax}
+% Stores the entries of the \meta{clist} as entries of the
+% \meta{intarray~var} starting from the \meta{start index}, upwards.
+% This is done without any bound checking. The \meta{start index} and
+% all entries of the \meta{integer comma list} (which do not undergo
+% space trimming and brace stripping as in normal clist mappings) must
+% be suitable for a direct assignment to a \TeX{} count register. An
+% empty entry may stop the loop.
+% \end{function}
+%
+% \begin{function}{\__kernel_ior_open:Nn, \__kernel_ior_open:No}
+% \begin{syntax}
+% \cs{__kernel_ior_open:Nn} \meta{stream} \Arg{file name}
+% \end{syntax}
+% This function has identical syntax to the public version. However,
+% is does not take precautions against active characters in the
+% \meta{file name}, and it does not attempt to add a \meta{path} to
+% the \meta{file name}: it is therefore intended to be used by
+% higher-level
+% functions which have already fully expanded the \meta{file name} and which
+% need to perform multiple open or close operations. See for example the
+% implementation of \cs{ior_shell_open:Nn}.
+% \end{function}
+%
+% \begin{function}{\__kernel_iow_open:Nn, \__kernel_iow_open:No}
+% \begin{syntax}
+% \cs{__kernel_iow_open:Nn} \meta{stream} \Arg{file name}
+% \end{syntax}
+% This function has identical syntax to the public version. However,
+% is does not take precautions against active characters in the
+% \meta{file name}, and it does not attempt to add a \meta{path} to
+% the \meta{file name}: it is therefore intended to be used by
+% higher-level
+% functions which have already fully expanded the \meta{file name} and which
+% need to perform multiple open or close operations. See for example the
+% implementation of \cs{iow_shell_open:Nn}.
+% \end{function}
+%
+% \begin{function}{\__kernel_iow_with:Nnn}
+% \begin{syntax}
+% \cs{__kernel_iow_with:Nnn} \meta{integer} \Arg{value} \Arg{code}
+% \end{syntax}
+% If the \meta{integer} is equal to the \meta{value} then this
+% function simply runs the \meta{code}. Otherwise it saves the
+% current value of the \meta{integer}, sets it to the \meta{value},
+% runs the \meta{code}, and restores the \meta{integer} to its former
+% value. This is used to ensure that the \tn{newlinechar} is~$10$
+% when writing to a stream, which lets \cs{iow_newline:} work, and
+% that \tn{errorcontextlines} is $-1$ when displaying a message.
+% \end{function}
+%
+% \begin{variable}{\__kernel_kern:n}
+% \begin{syntax}
+% \cs{__kernel_kern:n} \Arg{length}
+% \end{syntax}
+% Inserts a kern of the specified \meta{length}, a dimension expression.
+% \end{variable}
+%
+% \begin{function}{\__kernel_msg_show_eval:Nn, \__kernel_msg_log_eval:Nn}
+% \begin{syntax}
+% \cs{__kernel_msg_show_eval:Nn} \meta{function} \Arg{expression}
+% \end{syntax}
+% Shows or logs the \meta{expression} (turned into a string), an equal
+% sign, and the result of applying the \meta{function} to the
+% \Arg{expression} (with \texttt{f}-expansion). For instance, if the
+% \meta{function} is \cs{int_eval:n} and the \meta{expression} is
+% |1+2| then this logs |> 1+2=3.|
+% \end{function}
+%
+% \begin{function}[EXP]{\__kernel_pdf_object_id:n, \__kernel_pdf_object_id_indexed:nn}
+% \begin{syntax}
+% \cs{__kernel_pdf_object_id:n} \Arg{object}
+% \cs{__kernel_pdf_object_id_indexed:nn} \Arg{class} \Arg{number}
+% \end{syntax}
+% Expands to the ID of \meta{object} (or object of \meta{number} within
+% the \meta{class}), in for example page resource allocation. Depending on
+% the backend, the result may be the same as
+% \cs{pdf_object_id:n}/\cs{pdf_object_id_indexed:nn}.
+% \end{function}
+%
+% \begin{variable}{\g__kernel_prg_map_int}
+% This integer is used by non-expandable mapping functions to track
+% the level of nesting in force. The functions
+% \cs[no-index]{\meta{type}_map_1:w},
+% \cs[no-index]{\meta{type}_map_2:w}, \emph{etc.}, labelled by
+% \cs{g__kernel_prg_map_int}
+% hold functions to be mapped over various list datatypes in inline
+% and variable mappings.
+% \end{variable}
+%
+% \begin{function}{\__kernel_quark_new_test:N}
+% \begin{syntax}
+% \cs{__kernel_quark_new_test:N} \cs[no-index]{\meta{name}:\meta{arg spec}}
+% \end{syntax}
+% Defines a quark-test function \cs[no-index]{\meta{name}:\meta{arg spec}}
+% which tests if its argument is \cs[no-index]{q__\meta{namespace}_recursion_tail},
+% then acts accordingly, as described below for each possible
+% \meta{arg spec}.
+%
+% The \meta{namespace} is determined as the first (nonempty)
+% |_|-delimited word in \meta{name} and is used internally
+% in the definition of auxiliaries. The function
+% \cs{__kernel_quark_new_test:N} does \emph{not} define
+% the \cs[no-index]{q__\meta{namespace}_recursion_tail} and
+% \cs[no-index]{q__\meta{namespace}_recursion_stop} quarks.
+% They should be manually defined with \cs{quark_new:N}.
+%
+% There are $6$ different types of quark-test functions. Which one is
+% defined depends on the \meta{arg spec}, which \emph{must} be one of
+% the options listed now. Four of them are modeled after
+% \cs[no-index]{quark_if_recursion_tail:(N|n)} and
+% \cs[no-index]{quark_if_recursion_tail_do:(N|n)n}.
+% \begin{description}
+% \def\makelabel#1{\texttt{#1}}
+% \item[n] defines \cs[no-index]{\meta{name}:n} such that it
+% checks if |#1| contains only \cs[no-index]{q__\meta{namespace}_recursion_tail}, and
+% if so consumes all tokens up to \cs[no-index]{q__\meta{namespace}_recursion_stop}
+% (\emph{c.f.}~\cs{quark_if_recursion_tail_stop:n}).
+% \item[nn] defines \cs[no-index]{\meta{name}:nn} such that it
+% checks if |#1| contains only \cs[no-index]{q__\meta{namespace}_recursion_tail}, and
+% if so consumes all tokens up to \cs[no-index]{q__\meta{namespace}_recursion_stop},
+% then executes the code |#2| after that
+% (\emph{c.f.}~\cs{quark_if_recursion_tail_stop_do:nn}).
+% \item[N] defines \cs[no-index]{\meta{name}:N} such that it
+% checks if |#1| is \cs[no-index]{q__\meta{namespace}_recursion_tail}, and if so consumes
+% all tokens up to \cs[no-index]{q__\meta{namespace}_recursion_stop}
+% (\emph{c.f.}~\cs{quark_if_recursion_tail_stop:N}).
+% \item[Nn] defines \cs[no-index]{\meta{name}:Nn} such that it
+% checks if |#1| is \cs[no-index]{q__\meta{namespace}_recursion_tail}, and if so consumes
+% all tokens up to \cs[no-index]{q__\meta{namespace}_recursion_stop}, then executes
+% the code |#2| after that
+% (\emph{c.f.}~\cs{quark_if_recursion_tail_stop_do:Nn}).
+% \end{description}
+% The last two are modeled after
+% \cs[no-index]{quark_if_recursion_tail_break:(n|N)N}, and in those
+% cases the quark \cs[no-index]{q__\meta{namespace}_recursion_stop} is
+% not used (and thus needs not be defined).
+% \begin{description}
+% \def\makelabel#1{\texttt{#1}}
+% \item[nN] defines \cs[no-index]{\meta{name}:nN} such that it
+% checks if |#1| contains only \cs[no-index]{q__\meta{namespace}_recursion_tail}, and
+% if so uses the \cs[no-index]{\meta{type}_map_break:} function |#2|.
+% \item[NN] defines \cs[no-index]{\meta{name}:NN} such that it
+% checks if |#1| is \cs[no-index]{q__\meta{namespace}_recursion_tail}, and if so uses
+% the \cs[no-index]{\meta{type}_map_break:} function |#2|.
+% \end{description}
+% Any other signature, as well as a function without signature
+% are errors, and in such case the definition is aborted.
+% \end{function}
+%
+% \begin{function}{\__kernel_quark_new_conditional:Nn}
+% \begin{syntax}
+% \cs{__kernel_quark_new_conditional:Nn} \cs[no-index]{__\meta{namespace}_quark_if_\meta{name}:\meta{arg spec}} \Arg{conditions}
+% \end{syntax}
+% Defines a collection of quark conditionals that test if their
+% argument is the quark \cs[no-index]{q__\meta{namespace}_\meta{name}}
+% and perform suitable actions. The \meta{conditions} are a
+% comma-separated list of one or more of |p|, |T|, |F|, and |TF|, and
+% one conditional is defined for each \meta{condition} in the list, as
+% described for \cs{prg_new_conditional:Npnn}. The conditionals are
+% defined using \cs{prg_new_conditional:Npnn}, so that their name is
+% obtained by adding |p|, |T|, |F|, or |TF| to the base name
+% \cs[no-index]{__\meta{namespace}_quark_if_\meta{name}:\meta{arg spec}}.
+%
+% The first argument of \cs{__kernel_quark_new_conditional:Nn} must
+% contain |_quark_if_| and |:|, as these markers are used to determine
+% the \meta{name} of the quark
+% \cs[no-index]{q__\meta{namespace}_\meta{name}} to be tested. This
+% quark should be manually defined with \cs{quark_new:N}, as
+% \cs{__kernel_quark_new_conditional:Nn} does \emph{not} define it.
+%
+% The function \cs{__kernel_quark_new_conditional:Nn} can define $2$
+% different types of quark conditionals. Which one is defined depends
+% on the \meta{arg spec}, which \emph{must} be one of the following
+% options, modeled after \cs[index=quark_if_nil:NTF]{quark_if_nil:(N|n)(TF)}.
+% \begin{description}
+% \def\makelabel#1{\texttt{#1}}
+% \item[n] defines \cs[no-index]{__\meta{namespace}_quark_if_\meta{name}:n(TF)} such that it
+% checks if |#1| contains only \cs[no-index]{q__\meta{namespace}_\meta{name}}, and
+% executes the proper conditional branch.
+% \item[N] defines \cs[no-index]{__\meta{namespace}_quark_if_\meta{name}:N(TF)} such that it
+% checks if |#1| is \cs[no-index]{q__\meta{namespace}_\meta{name}}, and
+% executes the proper conditional branch.
+% \end{description}
+% Any other signature, as well as a function without signature
+% are errors, and in such case the definition is aborted.
+% \end{function}
+%
+% \begin{function}{\__kernel_sys_everyjob:}
+% \begin{syntax}
+% \cs{__kernel_sys_everyjob:}
+% \end{syntax}
+% Inserts the internal token list required at the start of every run (job).
+% \end{function}
+%
+% \begin{variable}{\c__kernel_randint_max_int}
+% Maximal allowed argument to \cs{__kernel_randint:n}. Equal to
+% $2^{17}-1$.
+% \end{variable}
+%
+% \begin{function}{\__kernel_randint:n}
+% \begin{syntax}
+% \cs{__kernel_randint:n} \Arg{max}
+% \end{syntax}
+% Used in an integer expression this gives a pseudo-random number
+% between $1$ and $\meta{max}$ included. One must have
+% $\meta{max}\leq 2^{17}-1$. The \meta{max} must be suitable for
+% \cs{int_value:w} (and any \cs{int_eval:w} must be terminated by
+% \cs{scan_stop:} or equivalent).
+% \end{function}
+%
+% \begin{function}{\__kernel_randint:nn}
+% \begin{syntax}
+% \cs{__kernel_randint:nn} \Arg{min} \Arg{max}
+% \end{syntax}
+% Used in an integer expression this gives a pseudo-random number
+% between $\meta{min}$ and $\meta{max}$ included. The \meta{min} and
+% \meta{max} must be suitable for \cs{int_value:w} (and any
+% \cs{int_eval:w} must be terminated by \cs{scan_stop:} or
+% equivalent). For small ranges
+% $R=\meta{max}-\meta{min}+1\leq 2^{17}-1$,
+% $\meta{min} - 1 + \cs{__kernel_randint:n} |{|R|}|$ is faster.
+% \end{function}
+%
+% \begin{function}{\__kernel_register_show:N, \__kernel_register_show:c}
+% \begin{syntax}
+% \cs{__kernel_register_show:N} \meta{register}
+% \end{syntax}
+% Used to show the contents of a \TeX{} register at the terminal, formatted
+% such that internal parts of the mechanism are not visible.
+% \end{function}
+%
+% \begin{function}
+% {\__kernel_register_log:N, \__kernel_register_log:c}
+% \begin{syntax}
+% \cs{__kernel_register_log:N} \meta{register}
+% \end{syntax}
+% Used to write the contents of a \TeX{} register to the log file in a
+% form similar to \cs{__kernel_register_show:N}.
+% \end{function}
+%
+% \begin{function}[EXP]{\__kernel_str_to_other:n}
+% \begin{syntax}
+% \cs{__kernel_str_to_other:n} \Arg{token list}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{other string}, where
+% spaces have category code \enquote{other}. This function can be
+% \texttt{f}-expanded without fear of losing a leading space, since
+% spaces do not have category code $10$ in its result. It takes a
+% time quadratic in the character count of the string.
+% \end{function}
+%
+% \begin{function}[rEXP]{\__kernel_str_to_other_fast:n}
+% \begin{syntax}
+% \cs{__kernel_str_to_other_fast:n} \Arg{token list}
+% \end{syntax}
+% Same behaviour \cs{__kernel_str_to_other:n} but only restricted-expandable.
+% It takes a time linear in the character count of the string.
+% \end{function}
+%
+% \begin{function}[EXP]{\__kernel_tl_to_str:w}
+% \begin{syntax}
+% \cs{__kernel_tl_to_str:w} \meta{expandable tokens} \Arg{tokens}
+% \end{syntax}
+% Carries out expansion on the \meta{expandable tokens} before conversion of
+% the \meta{tokens} to a string as describe for \cs{tl_to_str:n}. Typically,
+% the \meta{expandable tokens} will alter the nature of the \meta{tokens},
+% \emph{i.e.}~allow it to be generated in some way. This function requires
+% only a single expansion.
+% \end{function}
+%
+% \begin{function}{\__kernel_tl_set:Nx, \__kernel_tl_gset:Nx}
+% \begin{syntax}
+% \cs{__kernel_tl_set:Nx} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Fully expands \meta{tokens} and assigns the result to \meta{tl~var}.
+% \meta{tokens} must be given in braces and there must be no token between
+% \meta{tl~var} and \meta{tokens}.
+% \end{function}
+%
+% \begin{function}[EXP]{\__kernel_codepoint_data:nn}
+% \begin{syntax}
+% \cs{__kernel_codepoint_data:nn} \Arg{type} \Arg{codepoint}
+% \end{syntax}
+% Expands to the appropriate value for the \meta{type} of data
+% requested for a \meta{codepoint}. The current list of \meta{types} and
+% results are
+% \begin{description}
+% \item[\texttt{lowercase}] The \emph{single} codepoint specified by
+% \texttt{UnicodeData.txt} for lowercase mapping of the codepoint:
+% will be equal to the input \meta{codepoint} if there is no mapping
+% specified in \texttt{UnicodeData.txt}
+% \item[\texttt{uppercase}] The \emph{single} codepoint specified by
+% \texttt{UnicodeData.txt} for uppercase mapping of the codepoint:
+% will be equal to the input \meta{codepoint} if there is no mapping
+% specified in \texttt{UnicodeData.txt}
+% \end{description}
+% \end{function}
+%
+% \begin{function}[EXP]{\__kernel_codepoint_case:nn}
+% \begin{syntax}
+% \cs{__kernel_codepoint_case:nn} \Arg{mapping} \Arg{codepoint}
+% \end{syntax}
+% Expands to a list of three balanced text, of which at least the first
+% will contain a codepoint. This list of up to three codepoints specifies
+% the full case mapping for the input \meta{codepoint}. The \meta{mapping}
+% should be one of
+% \begin{itemize}
+% \item \texttt{casefold}
+% \item \texttt{lowercase}
+% \item \texttt{titlecase}
+% \item \texttt{uppercase}
+% \end{itemize}
+% \end{function}
+%
+% \subsection{Kernel backend functions}
+%
+% These functions are required to pass information to the backend. The nature
+% of these means that they are defined only when the relevant backend is in
+% use.
+%
+% \begin{function}
+% {
+% \__kernel_backend_literal:n,
+% \__kernel_backend_literal:e,
+% \__kernel_backend_literal:e
+% }
+% \begin{syntax}
+% \cs{__kernel_backend_literal:n} \Arg{content}
+% \end{syntax}
+% Adds the \meta{content} literally to the current vertical list as a
+% whatsit. The nature of the \meta{content} will depend on the backend in
+% use.
+% \end{function}
+%
+% \begin{function}
+% {
+% \__kernel_backend_literal_postscript:n,
+% \__kernel_backend_literal_postscript:e
+% }
+% \begin{syntax}
+% \cs{__kernel_backend_literal_postscript:n} \Arg{PostScript}
+% \end{syntax}
+% Adds the \meta{PostScript} literally to the current vertical list as a
+% whatsit. No positioning is applied.
+% \end{function}
+%
+% \begin{function}
+% {
+% \__kernel_backend_literal_pdf:n,
+% \__kernel_backend_literal_pdf:e
+% }
+% \begin{syntax}
+% \cs{__kernel_backend_literal_pdf:n} \Arg{PDF instructions}
+% \end{syntax}
+% Adds the \meta{PDF instructions} literally to the current vertical list as
+% a whatsit. No positioning is applied.
+% \end{function}
+%
+% \begin{function}
+% {
+% \__kernel_backend_literal_svg:n,
+% \__kernel_backend_literal_svg:e
+% }
+% \begin{syntax}
+% \cs{__kernel_backend_literal_svg:n} \Arg{SVG instructions}
+% \end{syntax}
+% Adds the \meta{SVG instructions} literally to the current vertical list as
+% a whatsit. No positioning is applied.
+% \end{function}
+%
+% \begin{function}
+% {
+% \__kernel_backend_postscript:n,
+% \__kernel_backend_postscript:e
+% }
+% \begin{syntax}
+% \cs{__kernel_backend_postscript:n} \Arg{PostScript}
+% \end{syntax}
+% Adds the \meta{PostScript} to the current vertical list as a
+% whatsit. The PostScript reference point is adjusted to match the
+% current position. The PostScript is inserted inside a |SDict begin|/|end|
+% pair.
+% \end{function}
+%
+% \begin{function}{\__kernel_backend_align_begin:, \__kernel_backend_align_end:}
+% \begin{syntax}
+% \cs{__kernel_backend_align_begin:}
+% \meta{PostScript literals}
+% \cs{__kernel_backend_align_end:}
+% \end{syntax}
+% Arranges to align the PostScript and DVI current positions and scales.
+% \end{function}
+%
+% \begin{function}{\__kernel_backend_scope_begin:, \__kernel_backend_scope_end:}
+% \begin{syntax}
+% \cs{__kernel_backend_scope_begin:}
+% \meta{content}
+% \cs{__kernel_backend_scope_end:}
+% \end{syntax}
+% Creates a scope for instructions at the backend level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \__kernel_backend_matrix:n,
+% \__kernel_backend_matrix:e
+% }
+% \begin{syntax}
+% \cs{__kernel_backend_matrix:n} \Arg{matrix}
+% \end{syntax}
+% Applies the \meta{matrix} to the current transformation matrix.
+% \end{function}
+%
+% \begin{function}{\g__kernel_backend_header_bool}
+% Specifies whether to write headers for the backend.
+% \end{function}
+%
+% \begin{function}{\l__kernel_color_stack_int}
+% The color stack used in \pdfTeX{} and \LuaTeX{} for the main color.
+% \end{function}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3keys.dtx b/macros/latex-dev/required/l3kernel/l3keys.dtx
new file mode 100644
index 0000000000..a1d2c01169
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3keys.dtx
@@ -0,0 +1,3649 @@
+% \iffalse meta-comment
+%
+%% File: l3keys.dtx
+%
+% Copyright (C) 2006-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3keys} module\\ Key--value interfaces^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% The key--value method is a popular system for creating large numbers
+% of settings for controlling function or package behaviour. The
+% system normally results in input of the form
+% \begin{verbatim}
+% \MyModuleSetup{
+% key-one = value one,
+% key-two = value two
+% }
+% \end{verbatim}
+% or
+% \begin{verbatim}
+% \MyModuleMacro[
+% key-one = value one,
+% key-two = value two
+% ]{argument}
+% \end{verbatim}
+% for the user.
+%
+% The high level functions here are intended as a method to create
+% key--value controls. Keys are themselves created using a key--value
+% interface, minimising the number of functions and arguments
+% required. Each key is created by setting one or more \emph{properties}
+% of the key:
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% {
+% key-one .code:n = code including parameter #1,
+% key-two .tl_set:N = \l_mymodule_store_tl
+% }
+% \end{verbatim}
+% These values can then be set as with other key--value approaches:
+% \begin{verbatim}
+% \keys_set:nn { mymodule }
+% {
+% key-one = value one,
+% key-two = value two
+% }
+% \end{verbatim}
+% As illustrated, keys are created inside a \meta{module}: a set of related
+% keys, typically those for a single module/\LaTeXe{} package. See
+% Section~\ref{sec:l3keys:subdivision} for suggestions on how to divide
+% large numbers of keys for a single module.
+%
+% At a document level, \cs{keys_set:nn} is used within a
+% document function, for example
+% \begin{verbatim}
+% \DeclareDocumentCommand \MyModuleSetup { m }
+% { \keys_set:nn { mymodule } { #1 } }
+% \DeclareDocumentCommand \MyModuleMacro { o m }
+% {
+% \group_begin:
+% \keys_set:nn { mymodule } { #1 }
+% % Main code for \MyModuleMacro
+% \group_end:
+% }
+% \end{verbatim}
+%
+% Key names may contain any tokens, as they are handled internally
+% using \cs{tl_to_str:n}. As discussed in
+% section~\ref{sec:l3keys:subdivision}, it is suggested that the character
+% |/| is reserved for sub-division of keys into different subsets.
+% Functions and variables are \emph{not} expanded when creating
+% key names, and so
+% \begin{verbatim}
+% \tl_set:Nn \l_mymodule_tmp_tl { key }
+% \keys_define:nn { mymodule }
+% {
+% \l_mymodule_tmp_tl .code:n = code
+% }
+% \end{verbatim}
+% creates a key called |\l_mymodule_tmp_tl|, and not one called
+% \texttt{key}.
+%
+% \section{Creating keys}
+%
+% \begin{function}[updated = 2017-11-14]
+% {\keys_define:nn, \keys_define:ne}
+% \begin{syntax}
+% \cs{keys_define:nn} \Arg{module} \Arg{keyval list}
+% \end{syntax}
+% Parses the \meta{keyval list} and defines the keys listed there for
+% \meta{module}. The \meta{module} name is treated as a string.
+% In practice the
+% \meta{module} should be chosen to be unique to the module in question
+% (unless deliberately adding keys to an existing module).
+%
+% The \meta{keyval list} should consist of one or more key names along
+% with an associated key \emph{property}. The properties of a key
+% determine how it acts. The individual properties are described
+% in the following text; a typical use of \cs{keys_define:nn} might
+% read
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% {
+% keyname .code:n = Some~code~using~#1,
+% keyname .value_required:n = true
+% }
+% \end{verbatim}
+% where the properties of the key begin from the |.| after the key
+% name.
+% \end{function}
+%
+% The various properties available take either no arguments at
+% all, or require one or more arguments. This is indicated in the
+% name of the property using an argument specification. In the following
+% discussion, each property is illustrated attached to an
+% arbitrary \meta{key}, which when used may be supplied with a
+% \meta{value}. All key \emph{definitions} are local.
+%
+% Key properties are applied in the reading order and so the ordering
+% is significant. Key properties which define \enquote{actions}, such
+% as |.code:n|, |.tl_set:N|, \emph{etc.}, override one another.
+% Some other properties are mutually exclusive, notably |.value_required:n|
+% and |.value_forbidden:n|, and so they replace one another. However,
+% properties covering non-exclusive behaviours may be given in any order. Thus
+% for example the following definitions are equivalent.
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% {
+% keyname .code:n = Some~code~using~#1,
+% keyname .value_required:n = true
+% }
+% \keys_define:nn { mymodule }
+% {
+% keyname .value_required:n = true,
+% keyname .code:n = Some~code~using~#1
+% }
+% \end{verbatim}
+% Note that all key properties define the key within the current \TeX{} group,
+% with an exception that the special |.undefine:| property \emph{undefines} the
+% key within the current \TeX{} group.
+%
+% \begin{function}[updated = 2013-07-08]
+% {.bool_set:N, .bool_set:c, .bool_gset:N, .bool_gset:c}
+% \begin{syntax}
+% \meta{key} .bool_set:N = \meta{boolean variable}
+% \end{syntax}
+% Defines \meta{key} to set \meta{boolean variable} to \meta{value} (which
+% must be either \enquote{\texttt{true}} or \enquote{\texttt{false}}). If the variable
+% does not exist, it will be created globally at the point that
+% the key is set up.
+% \end{function}
+%
+% \begin{function}[added = 2011-08-28, updated = 2013-07-08]
+% {
+% .bool_set_inverse:N, .bool_set_inverse:c,
+% .bool_gset_inverse:N, .bool_gset_inverse:c
+% }
+% \begin{syntax}
+% \meta{key} .bool_set_inverse:N = \meta{boolean variable}
+% \end{syntax}
+% Defines \meta{key} to set \meta{boolean variable} to the logical
+% inverse of \meta{value} (which must be either \enquote{\texttt{true}} or
+% \enquote{\texttt{false}}).
+% If the \meta{boolean variable} does not exist, it will be created globally
+% at the point that the key is set up.
+% \end{function}
+%
+% \begin{function}{.choice:}
+% \begin{syntax}
+% \meta{key} .choice:
+% \end{syntax}
+% Sets \meta{key} to act as a choice key. Each valid choice
+% for \meta{key} must then be created, as discussed in
+% section~\ref{sec:l3keys:choice}.
+% \end{function}
+%
+% \begin{function}[added = 2011-08-21, updated = 2013-07-10]
+% {.choices:nn, .choices:Vn, .choices:en, .choices:on}
+% \begin{syntax}
+% \meta{key} .choices:nn = \Arg{choices} \Arg{code}
+% \end{syntax}
+% Sets \meta{key} to act as a choice key, and defines a series \meta{choices}
+% which are implemented using the \meta{code}. Inside \meta{code},
+% \cs{l_keys_choice_tl} will be the name of the choice made, and
+% \cs{l_keys_choice_int} will be the position of the choice in the list
+% of \meta{choices} (indexed from~$1$).
+% Choices are discussed in detail in section~\ref{sec:l3keys:choice}.
+% \end{function}
+%
+% \begin{function}[added = 2011-09-11]
+% {.clist_set:N, .clist_set:c, .clist_gset:N, .clist_gset:c}
+% \begin{syntax}
+% \meta{key} .clist_set:N = \meta{comma list variable}
+% \end{syntax}
+% Defines \meta{key} to set \meta{comma list variable} to \meta{value}.
+% Spaces around commas and empty items will be stripped.
+% If the variable does not exist, it
+% is created globally at the point that the key is set up.
+% \end{function}
+%
+% \begin{function}[updated = 2013-07-10]{.code:n}
+% \begin{syntax}
+% \meta{key} .code:n = \Arg{code}
+% \end{syntax}
+% Stores the \meta{code} for execution when \meta{key} is used.
+% The \meta{code} can include one parameter (|#1|), which will be the
+% \meta{value} given for the \meta{key}.
+% \end{function}
+%
+% \begin{function}[added = 2020-01-11]
+% {
+% .cs_set:Np, .cs_set:cp,
+% .cs_set_protected:Np, .cs_set_protected:cp,
+% .cs_gset:Np, .cs_gset:cp,
+% .cs_gset_protected:Np, .cs_gset_protected:cp,
+% }
+% \begin{syntax}
+% \meta{key} .cs_set:Np = \meta{control sequence} \meta{arg.~spec.}
+% \end{syntax}
+% Defines \meta{key} to set \meta{control sequence} to have \meta{arg.~spec.}
+% and replacement text \meta{value}.
+% \end{function}
+%
+% \begin{function}[updated = 2013-07-09]
+% {.default:n, .default:V, .default:e, .default:o}
+% \begin{syntax}
+% \meta{key} .default:n = \Arg{default}
+% \end{syntax}
+% Creates a \meta{default} value for \meta{key}, which is used if no
+% value is given. This will be used if only the key name is given,
+% but not if a blank \meta{value} is given:
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% {
+% key .code:n = Hello~#1,
+% key .default:n = World
+% }
+% \keys_set:nn { mymodule }
+% {
+% key = Fred, % Prints 'Hello Fred'
+% key, % Prints 'Hello World'
+% key = , % Prints 'Hello '
+% }
+% \end{verbatim}
+% The default does not affect keys where values are required or
+% forbidden. Thus a required value cannot be supplied by a default
+% value, and giving a default value for a key which cannot take a value
+% does not trigger an error.
+%
+% When no value is given for a key as part of \cs{keys_set:nn}, the
+% \texttt{.default:n} value provides the value before key properties are
+% considered. The only exception is when the \texttt{.value_required:n}
+% property is active: a required value cannot be supplied by the default,
+% and must be explicitly given as part of \cs{keys_set:nn}.
+% \end{function}
+%
+% \begin{function}[updated = 2020-01-17]
+% {.dim_set:N, .dim_set:c, .dim_gset:N, .dim_gset:c}
+% \begin{syntax}
+% \meta{key} .dim_set:N = \meta{dimension}
+% \end{syntax}
+% Defines \meta{key} to set \meta{dimension} to \meta{value} (which
+% must a dimension expression). If the variable does not exist, it
+% is created globally at the point that the key is set up. The key will
+% require a value at point-of-use unless a default is set.
+% \end{function}
+%
+% \begin{function}[updated = 2020-01-17]
+% {.fp_set:N, .fp_set:c, .fp_gset:N, .fp_gset:c}
+% \begin{syntax}
+% \meta{key} .fp_set:N = \meta{floating point}
+% \end{syntax}
+% Defines \meta{key} to set \meta{floating point} to \meta{value}
+% (which must a floating point expression). If the variable does not exist,
+% it is created globally at the point that the key is set up. The key will
+% require a value at point-of-use unless a default is set.
+% \end{function}
+%
+% \begin{function}[added = 2013-07-14]
+% {.groups:n}
+% \begin{syntax}
+% \meta{key} .groups:n = \Arg{groups}
+% \end{syntax}
+% Defines \meta{key} as belonging to the \meta{groups} (a
+% comma-separated list). Groups
+% provide a \enquote{secondary axis} for selectively setting keys, and are
+% described in Section~\ref{sec:l3keys:selective}.
+% \begin{texnote}
+% The \meta{groups} argument is turned into a string then
+% interpreted as a comma-separated list, so group names cannot
+% contain commas nor start or end with a space character.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2016-11-22]{.inherit:n}
+% \begin{syntax}
+% \meta{key} .inherit:n = \Arg{parents}
+% \end{syntax}
+% Specifies that the \meta{key} path should inherit the keys listed
+% as any of the \meta{parents} (a comma list), which can be a module
+% or a sub-division thereof. For example, after setting
+% \begin{verbatim}
+% \keys_define:nn { foo } { test .code:n = \tl_show:n {#1} }
+% \keys_define:nn { } { bar .inherit:n = foo }
+% \end{verbatim}
+% setting
+% \begin{verbatim}
+% \keys_set:nn { bar } { test = a }
+% \end{verbatim}
+% will be equivalent to
+% \begin{verbatim}
+% \keys_set:nn { foo } { test = a }
+% \end{verbatim}
+% Inheritance applies at point of use, not at definition, thus keys may
+% be added to the \meta{parent} after the use of \texttt{.inherit:n}
+% and will be active.
+% If more than one \meta{parent} is specified, the presence of the
+% \meta{key} will be tested for each in turn, with the first successful
+% hit taking priority.
+% \end{function}
+%
+% \begin{function}[updated = 2013-07-09]
+% {.initial:n, .initial:V, .initial:e, .initial:o}
+% \begin{syntax}
+% \meta{key} .initial:n = \Arg{value}
+% \end{syntax}
+% Initialises the \meta{key} with the \meta{value}, equivalent to
+% \begin{quote}
+% \cs{keys_set:nn} \Arg{module} \{ \meta{key} = \meta{value} \}
+% \end{quote}
+% \end{function}
+%
+% \begin{function}[updated = 2020-01-17]
+% {.int_set:N, .int_set:c, .int_gset:N, .int_gset:c}
+% \begin{syntax}
+% \meta{key} .int_set:N = \meta{integer}
+% \end{syntax}
+% Defines \meta{key} to set \meta{integer} to \meta{value} (which
+% must be an integer expression). If the variable does not exist, it
+% is created globally at the point that the key is set up. The key will
+% require a value at point-of-use unless a default is set.
+% \end{function}
+%
+% \begin{function}[updated = 2022-01-15]
+% {
+% .legacy_if_set:n, .legacy_if_gset:n,
+% .legacy_if_set_inverse:n, .legacy_if_gset_inverse:n
+% }
+% \begin{syntax}
+% \meta{key} .legacy_if_set:n = \meta{switch}
+% \end{syntax}
+% Defines \meta{key} to set legacy \cs[no-index]{if\meta{switch}} to \meta{value}
+% (which must be either \enquote{\texttt{true}} or \enquote{\texttt{false}}).
+% The \meta{switch} is the name of the switch \emph{without the leading
+% \texttt{if}}.
+%
+% The \texttt{inverse} versions will set the \meta{switch} to the logical
+% opposite of the \meta{value}.
+% \end{function}
+%
+% \begin{function}[updated = 2013-07-10]{.meta:n}
+% \begin{syntax}
+% \meta{key} .meta:n = \Arg{keyval list}
+% \end{syntax}
+% Makes \meta{key} a meta-key, which will set \meta{keyval list} in
+% one go. The \meta{keyval list} can refer as |#1| to the value given
+% at the time the \meta{key} is used (or, if no value is given, the
+% \meta{key}'s default value).
+% \end{function}
+%
+% \begin{function}[added = 2013-07-10]{.meta:nn}
+% \begin{syntax}
+% \meta{key} .meta:nn = \Arg{path} \Arg{keyval list}
+% \end{syntax}
+% Makes \meta{key} a meta-key, which will set \meta{keyval list} in
+% one go using the \meta{path} in place of the current one. The
+% \meta{keyval list} can refer as |#1| to the value given at the time
+% the \meta{key} is used (or, if no value is given, the \meta{key}'s
+% default value).
+% \end{function}
+%
+% \begin{function}[added = 2011-08-21]{.multichoice:}
+% \begin{syntax}
+% \meta{key} .multichoice:
+% \end{syntax}
+% Sets \meta{key} to act as a multiple choice key. Each valid choice
+% for \meta{key} must then be created, as discussed in
+% section~\ref{sec:l3keys:choice}.
+% \end{function}
+%
+% \begin{function}[added = 2011-08-21, updated = 2013-07-10]
+% {.multichoices:nn, .multichoices:Vn, .multichoices:en, .multichoices:on}
+% \begin{syntax}
+% \meta{key} .multichoices:nn \Arg{choices} \Arg{code}
+% \end{syntax}
+% Sets \meta{key} to act as a multiple choice key, and defines a series
+% \meta{choices}
+% which are implemented using the \meta{code}. Inside \meta{code},
+% \cs{l_keys_choice_tl} will be the name of the choice made, and
+% \cs{l_keys_choice_int} will be the position of the choice in the list
+% of \meta{choices} (indexed from~$1$).
+% Choices are discussed in detail in section~\ref{sec:l3keys:choice}.
+% \end{function}
+%
+% \begin{function}[added = 2019-05-05, updated = 2020-01-17]
+% {.muskip_set:N, .muskip_set:c, .muskip_gset:N, .muskip_gset:c}
+% \begin{syntax}
+% \meta{key} .muskip_set:N = \meta{muskip}
+% \end{syntax}
+% Defines \meta{key} to set \meta{muskip} to \meta{value} (which
+% must be a muskip expression). If the variable does not exist, it
+% is created globally at the point that the key is set up. The key will
+% require a value at point-of-use unless a default is set.
+% \end{function}
+%
+% \begin{function}[added = 2019-01-31]
+% {.prop_put:N, .prop_put:c, .prop_gput:N, .prop_gput:c}
+% \begin{syntax}
+% \meta{key} .prop_put:N = \meta{property list}
+% \end{syntax}
+% Defines \meta{key} to put the \meta{value} onto the \meta{property list}
+% stored under the \meta{key}.
+% If the variable does not exist, it
+% is created globally at the point that the key is set up.
+% \end{function}
+%
+% \begin{function}[updated = 2020-01-17]
+% {.skip_set:N, .skip_set:c, .skip_gset:N, .skip_gset:c}
+% \begin{syntax}
+% \meta{key} .skip_set:N = \meta{skip}
+% \end{syntax}
+% Defines \meta{key} to set \meta{skip} to \meta{value} (which
+% must be a skip expression). If the variable does not exist, it
+% is created globally at the point that the key is set up. The key will
+% require a value at point-of-use unless a default is set.
+% \end{function}
+%
+% \begin{function}[added = 2021-10-30]
+% {.str_set:N, .str_set:c, .str_gset:N, .str_gset:c}
+% \begin{syntax}
+% \meta{key} .str_set:N = \meta{string variable}
+% \end{syntax}
+% Defines \meta{key} to set \meta{string variable} to \meta{value}.
+% If the variable does not exist, it is created globally
+% at the point that the key is set up.
+% \end{function}
+%
+% \begin{function}[added = 2023-09-18]
+% {.str_set_e:N, .str_set_e:c, .str_gset_e:N, .str_gset_e:c}
+% \begin{syntax}
+% \meta{key} .str_set_e:N = \meta{string variable}
+% \end{syntax}
+% Defines \meta{key} to set \meta{string variable} to \meta{value},
+% which will be subjected to an \texttt{e}-type expansion
+% (\emph{i.e.}~using \cs{str_set:Ne}). If the variable does not exist,
+% it is created globally at the point that the key is set up.
+% \end{function}
+%
+% \begin{function}{.tl_set:N, .tl_set:c, .tl_gset:N, .tl_gset:c}
+% \begin{syntax}
+% \meta{key} .tl_set:N = \meta{token list variable}
+% \end{syntax}
+% Defines \meta{key} to set \meta{token list variable} to \meta{value}.
+% If the variable does not exist, it is created globally
+% at the point that the key is set up.
+% \end{function}
+%
+% \begin{function}[added = 2023-09-18]
+% {.tl_set_e:N, .tl_set_e:c, .tl_gset_e:N, .tl_gset_e:c}
+% \begin{syntax}
+% \meta{key} .tl_set_e:N = \meta{token list variable}
+% \end{syntax}
+% Defines \meta{key} to set \meta{token list variable} to \meta{value},
+% which will be subjected to an \texttt{e}-type expansion
+% (\emph{i.e.}~using \cs{tl_set:Ne}). If the variable does not exist,
+% it is created globally at the point that the key is set up.
+% \end{function}
+%
+% \begin{function}[added = 2015-07-14]{.undefine:}
+% \begin{syntax}
+% \meta{key} .undefine:
+% \end{syntax}
+% Removes the definition of the \meta{key} within the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}[added = 2015-07-14]{.value_forbidden:n}
+% \begin{syntax}
+% \meta{key} .value_forbidden:n = \texttt{true\string|false}
+% \end{syntax}
+% Specifies that \meta{key} cannot receive a \meta{value} when used.
+% If a \meta{value} is given then an error will be issued. Setting
+% the property \enquote{\texttt{false}} cancels the restriction.
+% \end{function}
+%
+% \begin{function}[added = 2015-07-14]{.value_required:n}
+% \begin{syntax}
+% \meta{key} .value_required:n = \texttt{true\string|false}
+% \end{syntax}
+% Specifies that \meta{key} must receive a \meta{value} when used.
+% If a \meta{value} is not given then an error will be issued. Setting
+% the property \enquote{\texttt{false}} cancels the restriction.
+% \end{function}
+%
+% \section{Sub-dividing keys}
+% \label{sec:l3keys:subdivision}
+%
+% When creating large numbers of keys, it may be desirable to divide
+% them into several subsets for a given module. This can be achieved
+% either by adding a sub-division to the module name:
+% \begin{verbatim}
+% \keys_define:nn { mymodule / subset }
+% { key .code:n = code }
+% \end{verbatim}
+% or to the key name:
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% { subset / key .code:n = code }
+% \end{verbatim}
+% As illustrated, the best choice of token for sub-dividing keys in
+% this way is |/|. This is because of the method that is
+% used to represent keys internally. Both of the above code fragments
+% set the same key, which has full name \texttt{mymodule/subset/key}.
+%
+% As illustrated in the next section, this subdivision is
+% particularly relevant to making multiple choices.
+%
+% \section{Choice and multiple choice keys}
+% \label{sec:l3keys:choice}
+%
+% The \pkg{l3keys} system supports two types of choice key, in which a series
+% of pre-defined input values are linked to varying implementations. Choice
+% keys are usually created so that the various values are mutually-exclusive:
+% only one can apply at any one time. \enquote{Multiple} choice keys are also
+% supported: these allow a selection of values to be chosen at the same time.
+%
+% Mutually-exclusive choices are created by setting the \texttt{.choice:}
+% property:
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% { key .choice: }
+% \end{verbatim}
+% For keys which are set up as choices, the valid choices are generated
+% by creating sub-keys of the choice key. This can be carried out in
+% two ways.
+%
+% In many cases, choices execute similar code which is dependant only
+% on the name of the choice or the position of the choice in the
+% list of all possibilities. Here, the keys can share the same code, and can
+% be rapidly created using the \texttt{.choices:nn} property.
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% {
+% key .choices:nn =
+% { choice-a, choice-b, choice-c }
+% {
+% You~gave~choice~'\tl_use:N \l_keys_choice_tl',~
+% which~is~in~position~\int_use:N \l_keys_choice_int \c_space_tl
+% in~the~list.
+% }
+% }
+% \end{verbatim}
+% The index \cs{l_keys_choice_int} in the list of choices starts at~$1$.
+%
+% \begin{variable}{\l_keys_choice_int, \l_keys_choice_tl}
+% Inside the code block for a choice generated using \texttt{.choices:nn},
+% the variables \cs{l_keys_choice_tl} and \cs{l_keys_choice_int} are
+% available to indicate the name of the current choice, and its position in
+% the comma list. The position is indexed from~$1$. Note that, as with
+% standard key code generated using \texttt{.code:n}, the value passed to
+% the key (i.e.~the choice name) is also available as |#1|.
+% \end{variable}
+%
+% On the other hand, it is sometimes useful to create choices which
+% use entirely different code from one another. This can be achieved
+% by setting the \texttt{.choice:} property of a key, then manually
+% defining sub-keys.
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% {
+% key .choice:,
+% key / choice-a .code:n = code-a,
+% key / choice-b .code:n = code-b,
+% key / choice-c .code:n = code-c,
+% }
+% \end{verbatim}
+%
+% It is possible to mix the two methods, but manually-created choices
+% should \emph{not} use \cs{l_keys_choice_tl} or \cs{l_keys_choice_int}.
+% These variables do not have defined behaviour when used outside of
+% code created using \texttt{.choices:nn}
+% (\emph{i.e.}~anything might happen).
+%
+% It is possible to allow choice keys to take values which have not previously
+% been defined by adding code for the special \texttt{unknown} choice. The
+% general behavior of the \texttt{unknown} key is described in
+% Section~\ref{sec:l3keys:unknown}. A typical example in the case of a choice
+% would be to issue a custom error message:
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% {
+% key .choice:,
+% key / choice-a .code:n = code-a,
+% key / choice-b .code:n = code-b,
+% key / choice-c .code:n = code-c,
+% key / unknown .code:n =
+% \msg_error:nneee { mymodule } { unknown-choice }
+% { key } % Name of choice key
+% { choice-a , choice-b , choice-c } % Valid choices
+% { \exp_not:n {#1} } % Invalid choice given
+% %
+% %
+% }
+% \end{verbatim}
+%
+% Multiple choices are created in a very similar manner to mutually-exclusive
+% choices, using the properties \texttt{.multichoice:} and
+% \texttt{.multichoices:nn}. As with mutually exclusive choices, multiple
+% choices are define as sub-keys. Thus both
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% {
+% key .multichoices:nn =
+% { choice-a, choice-b, choice-c }
+% {
+% You~gave~choice~'\tl_use:N \l_keys_choice_tl',~
+% which~is~in~position~
+% \int_use:N \l_keys_choice_int \c_space_tl
+% in~the~list.
+% }
+% }
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% {
+% key .multichoice:,
+% key / choice-a .code:n = code-a,
+% key / choice-b .code:n = code-b,
+% key / choice-c .code:n = code-c,
+% }
+% \end{verbatim}
+% are valid.
+%
+% When a multiple choice key is set
+% \begin{verbatim}
+% \keys_set:nn { mymodule }
+% {
+% key = { a , b , c } % 'key' defined as a multiple choice
+% }
+% \end{verbatim}
+% each choice is applied in turn, equivalent to a \texttt{clist} mapping or
+% to applying each value individually:
+% \begin{verbatim}
+% \keys_set:nn { mymodule }
+% {
+% key = a ,
+% key = b ,
+% key = c ,
+% }
+% \end{verbatim}
+% Thus each separate choice will have passed to it the
+% \cs{l_keys_choice_tl} and \cs{l_keys_choice_int} in exactly
+% the same way as described for \texttt{.choices:nn}.
+%
+% \section{Key usage scope}
+%
+% Some keys will be used as settings which have a strictly limited scope
+% of usage. Some will be only available once, others will only be valid
+% until typesetting begins. To allow formats to support this in a structured
+% way, \pkg{l3keys} allows this information to be specified using the
+% \texttt{.usage:n} property.
+%
+% \begin{function}[added = 2022-01-10]{.usage:n}
+% \begin{syntax}
+% \meta{key} .usage:n = \meta{scope}
+% \end{syntax}
+% Defines the \meta{key} to have usage within the \meta{scope}, which
+% should be one of \texttt{general}, \texttt{preamble} or \texttt{load}.
+% \end{function}
+%
+% \begin{variable}[added = 2022-01-10]
+% {\l_keys_usage_load_prop, \l_keys_usage_preamble_prop}
+% \pkg{l3keys} itself does \emph{not} attempt to redefine keys based on the
+% usage scope. Rather, this information is made available with these
+% two property lists. These hold an entry for each module (prefix); the
+% value of each entry is a comma-separated list of the usage-restricted
+% key(s).
+% \end{variable}
+%
+% \section{Setting keys}
+%
+% \begin{function}[updated = 2017-11-14]
+% {
+% \keys_set:nn, \keys_set:nV, \keys_set:nv, \keys_set:ne,
+% \keys_set:no,
+% }
+% \begin{syntax}
+% \cs{keys_set:nn} \Arg{module} \Arg{keyval list}
+% \end{syntax}
+% Parses the \meta{keyval list}, and sets those keys which are defined
+% for \meta{module}. The behaviour on finding an unknown key can be set
+% by defining a special \texttt{unknown} key: this is illustrated
+% later.
+% \end{function}
+%
+% \begin{variable}[updated = 2020-02-08]
+% {\l_keys_path_str, \l_keys_key_str, \l_keys_value_tl}
+% For each key processed, information of the full \emph{path} of the
+% key, the \emph{name} of the key and the \emph{value} of the key is
+% available within two string and one token list variables.
+% These may be used within the code of the key.
+%
+% The \emph{path} of the key is a \enquote{full} description of the key,
+% and is unique for each key. It consists of the module and full key name,
+% thus for example
+% \begin{verbatim}
+% \keys_set:nn { mymodule } { key-a = some-value }
+% \end{verbatim}
+% has path \texttt{mymodule/key-a} while
+% \begin{verbatim}
+% \keys_set:nn { mymodule } { subset / key-a = some-value }
+% \end{verbatim}
+% has path \texttt{mymodule/subset/key-a}. This information is stored in
+% \cs{l_keys_path_str}.
+%
+% The \emph{name} of the key is the part of the path after the last
+% \texttt{/}, and thus is not unique. In the preceding examples, both keys
+% have name \texttt{key-a} despite having different paths. This information
+% is stored in \cs{l_keys_key_str}.
+%
+% The \emph{value} is everything after the \texttt{=}, which may be
+% empty if no value was given. This is stored in \cs{l_keys_value_tl}, and
+% is not processed in any way by \cs{keys_set:nn}.
+% \end{variable}
+%
+% \section{Handling of unknown keys}
+% \label{sec:l3keys:unknown}
+%
+% If a key has not previously been defined (is unknown), \cs{keys_set:nn}
+% looks for a special \texttt{unknown} key for the same module, and if this is
+% not defined raises an error indicating that the key name was unknown. This
+% mechanism can be used for example to issue custom error texts. The
+% \texttt{unknown} key also supports the \texttt{.default:n} property.
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% {
+% unknown .code:n =
+% You~tried~to~set~key~'\l_keys_key_str'~to~'#1'. ,
+% unknown .default:V = \c_novalue_tl
+% }
+% \end{verbatim}
+%
+% \begin{function}[added = 2011-08-23, updated = 2019-01-29]
+% {
+% \keys_set_known:nn, \keys_set_known:nV,
+% \keys_set_known:nv, \keys_set_known:ne,
+% \keys_set_known:no,
+% \keys_set_known:nnN, \keys_set_known:nVN,
+% \keys_set_known:nvN, \keys_set_known:neN,
+% \keys_set_known:noN,
+% \keys_set_known:nnnN, \keys_set_known:nVnN,
+% \keys_set_known:nvnN, \keys_set_known:nenN,
+% \keys_set_known:nonN
+% }
+% \begin{syntax}
+% \cs{keys_set_known:nn} \Arg{module} \Arg{keyval list}
+% \cs{keys_set_known:nnN} \Arg{module} \Arg{keyval list} \meta{tl}
+% \cs{keys_set_known:nnnN} \Arg{module} \Arg{keyval list} \Arg{root} \meta{tl}
+% \end{syntax}
+% These functions set keys which are known for the \meta{module}, and
+% simply ignore other keys. The \cs{keys_set_known:nn} function parses the
+% \meta{keyval list}, and sets those keys which are defined for
+% \meta{module}. Any keys which are unknown are not processed further by
+% the parser. In addition, \cs{keys_set_known:nnN} stores the key--value
+% pairs in the \meta{tl} in comma-separated form (\emph{i.e.}~an edited
+% version of the \meta{keyval list}). When a \meta{root} is given
+% (\cs{keys_set_known:nnnN}), the key--value entries are returned
+% relative to this point in the key tree. When it is absent, only the
+% key name and value are provided. The correct list is returned by
+% nested calls.
+% \end{function}
+%
+% \section{Selective key setting}
+% \label{sec:l3keys:selective}
+%
+% In some cases it may be useful to be able to select only some keys for
+% setting, even though these keys have the same path. For example, with
+% a set of keys defined using
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% {
+% key-one .code:n = { \my_func:n {#1} } ,
+% key-two .tl_set:N = \l_my_a_tl ,
+% key-three .tl_set:N = \l_my_b_tl ,
+% key-four .fp_set:N = \l_my_a_fp ,
+% }
+% \end{verbatim}
+% the use of \cs{keys_set:nn} attempts to set all four keys. However, in
+% some contexts it may only be sensible to set some keys, or to control the
+% order of setting. To do this, keys may be assigned to \emph{groups}:
+% arbitrary sets which are independent of the key tree. Thus modifying the
+% example to read
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% {
+% key-one .code:n = { \my_func:n {#1} } ,
+% key-one .groups:n = { first } ,
+% key-two .tl_set:N = \l_my_a_tl ,
+% key-two .groups:n = { first } ,
+% key-three .tl_set:N = \l_my_b_tl ,
+% key-three .groups:n = { second } ,
+% key-four .fp_set:N = \l_my_a_fp ,
+% }
+% \end{verbatim}
+% assigns \texttt{key-one} and \texttt{key-two} to group \texttt{first},
+% \texttt{key-three} to group \texttt{second}, while \texttt{key-four} is
+% not assigned to a group.
+%
+% Selective key setting may be achieved either by selecting one or more
+% groups to be made \enquote{active}, or by marking one or more groups to
+% be ignored in key setting.
+%
+% \begin{function}[added = 2024-01-10]
+% {
+% \keys_set_exclude_groups:nnn, \keys_set_exclude_groups:nnV,
+% \keys_set_exclude_groups:nnv, \keys_set_exclude_groups:nno,
+% \keys_set_exclude_groups:nnnN, \keys_set_exclude_groups:nnVN,
+% \keys_set_exclude_groups:nnvN, \keys_set_exclude_groups:nnoN,
+% \keys_set_exclude_groups:nnnnN, \keys_set_exclude_groups:nnVnN,
+% \keys_set_exclude_groups:nnvnN, \keys_set_exclude_groups:nnonN,
+% }
+% \begin{syntax}
+% \cs{keys_set_exclude_groups:nnn} \Arg{module} \Arg{groups} \Arg{keyval list}
+% \cs{keys_set_exclude_groups:nnnN} \Arg{module} \Arg{groups} \Arg{keyval list} \meta{tl}
+% \cs{keys_set_exclude_groups:nnnnN} \Arg{module} \Arg{groups} \Arg{keyval list} \meta{root} \meta{tl}
+% \end{syntax}
+% Sets keys by excluding those in the specificied \meta{groups}.
+% The \meta{groups} are
+% given as a comma-separated list. Unknown keys are not assigned to any
+% group and are thus always set. The key--value pairs for each
+% key which is filtered out are stored in the \meta{tl} in a
+% comma-separated form (\emph{i.e.}~an edited version of the \meta{keyval
+% list}). The \cs{keys_set_exclude_groups:nnn} version skips this stage.
+%
+% Use of \cs{keys_set_exclude_groups:nnnN} can be nested, with the correct residual
+% \meta{keyval list} returned at each stage. In the version which takes
+% a \meta{root} argument, the key list is returned relative to that point
+% in the key tree. In the cases without a \meta{root} argument, only
+% the key names and values are returned.
+% \end{function}
+%
+% \begin{function}[added = 2013-07-14, updated = 2017-05-27]
+% {
+% \keys_set_groups:nnn, \keys_set_groups:nnV,
+% \keys_set_groups:nnv, \keys_set_groups:nno
+% }
+% \begin{syntax}
+% \cs{keys_set_groups:nnn} \Arg{module} \Arg{groups} \Arg{keyval list}
+% \end{syntax}
+% Activates key filtering in an \enquote{opt-in} sense: only keys assigned to
+% one or more of the \meta{groups} specified are set. The \meta{groups} are
+% given as a comma-separated list. Unknown keys are not assigned to any
+% group and are thus never set.
+% \end{function}
+%
+% \section{Digesting keys}
+%
+% \begin{function}[added = 2022-03-09]{\keys_precompile:nnN}
+% \begin{syntax}
+% \cs{keys_precompile:nnN} \Arg{module} \Arg{keyval list} \meta{tl}
+% \end{syntax}
+% Parses the \meta{keyval list} as for \cs{keys_set:nn}, placing the
+% resulting code for those which set variables or functions into the
+% \meta{tl}. Thus this function \enquote{precompiles} the keyval list into
+% a set of results which can be applied rapidly.
+% \end{function}
+%
+% \section{Utility functions for keys}
+%
+% \begin{function}[EXP, pTF, updated = 2022-01-10]
+% {\keys_if_exist:nn, \keys_if_exist:ne}
+% \begin{syntax}
+% \cs{keys_if_exist_p:nn} \Arg{module} \Arg{key} \\
+% \cs{keys_if_exist:nnTF} \Arg{module} \Arg{key} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{key} exists for \meta{module}, \emph{i.e.}~if any code
+% has been defined for \meta{key}.
+% \end{function}
+%
+% \begin{function}[added = 2011-08-21,EXP,pTF, updated = 2017-11-14]
+% {\keys_if_choice_exist:nnn}
+% \begin{syntax}
+% \cs{keys_if_choice_exist_p:nnn} \Arg{module} \Arg{key} \Arg{choice} \\
+% \cs{keys_if_choice_exist:nnnTF} \Arg{module} \Arg{key} \Arg{choice} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{choice} is defined for the \meta{key} within the
+% \meta{module}, \emph{i.e.}~if any code has been defined for
+% \meta{key}/\meta{choice}. The test is \texttt{false} if the \meta{key}
+% itself is not defined.
+% \end{function}
+%
+% \begin{function}[updated = 2015-08-09]{\keys_show:nn}
+% \begin{syntax}
+% \cs{keys_show:nn} \Arg{module} \Arg{key}
+% \end{syntax}
+% Displays in the terminal
+% the information associated to the \meta{key} for a \meta{module},
+% including the function which is used to actually implement it.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2015-08-09]{\keys_log:nn}
+% \begin{syntax}
+% \cs{keys_log:nn} \Arg{module} \Arg{key}
+% \end{syntax}
+% Writes in the log file the information associated to the \meta{key}
+% for a \meta{module}. See also \cs{keys_show:nn} which displays the
+% result in the terminal.
+% \end{function}
+%
+% \section{Low-level interface for parsing key--val lists}
+%
+% To re-cap from earlier, a key--value list is input of the form
+% \begin{verbatim}
+% KeyOne = ValueOne ,
+% KeyTwo = ValueTwo ,
+% KeyThree
+% \end{verbatim}
+% where each key--value pair is separated by a comma from the rest of
+% the list, and each key--value pair does not necessarily contain an
+% equals sign or a value! Processing this type of input correctly
+% requires a number of careful steps, to correctly account for
+% braces, spaces and the category codes of separators.
+%
+% While the functions described earlier are used as a high-level interface
+% for processing such input, in special circumstances you may wish to use
+% a lower-level approach.
+% The low-level parsing system converts a \meta{key--value list}
+% into \meta{keys} and associated \meta{values}. After the parsing phase
+% is completed, the resulting keys and values (or keys alone) are
+% available for further processing. This processing is not carried out by the
+% low-level parser itself, and so the parser requires the names of
+% two functions along with the key--value list. One function is
+% needed to process key--value pairs (it receives two arguments),
+% and a second function is required for keys given without any value
+% (it is called with a single argument).
+%
+% The parser does not double |#| tokens or expand any input. Active
+% tokens |=| and |,| appearing at the outer level of braces are converted
+% to category \enquote{other} (12) so that the parser does not \enquote{miss}
+% any due to category code changes. Spaces are removed from the ends
+% of the keys and values. Keys and values which are given in braces
+% have exactly one set removed (after space trimming), thus
+% \begin{verbatim}
+% key = {value here},
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% key = value here,
+% \end{verbatim}
+% are treated identically.
+%
+% \begin{function}[rEXP, added=2020-12-19, updated = 2021-05-10]
+% {\keyval_parse:nnn, \keyval_parse:nnV, \keyval_parse:nnv}
+% \begin{syntax}
+% \cs{keyval_parse:nnn} \Arg{code_1} \Arg{code_2} \Arg{key--value list}
+% \end{syntax}
+% Parses the \meta{key--value list} into a series of \meta{keys} and
+% associated \meta{values}, or keys alone (if no \meta{value} was
+% given). \meta{code_1} receives each \meta{key} (with no \meta{value}) as a
+% trailing brace group, whereas \meta{code_2} is appended by two brace groups,
+% the \meta{key} and \meta{value}.
+% The order of the \meta{keys} in the \meta{key--value list}
+% is preserved. Thus
+% \begin{verbatim}
+% \keyval_parse:nnn
+% { \use_none:nn { code 1 } }
+% { \use_none:nnn { code 2 } }
+% { key1 = value1 , key2 = value2, key3 = , key4 }
+% \end{verbatim}
+% is converted into an input stream
+% \begin{verbatim}
+% \use_none:nnn { code 2 } { key1 } { value1 }
+% \use_none:nnn { code 2 } { key2 } { value2 }
+% \use_none:nnn { code 2 } { key3 } { }
+% \use_none:nn { code 1 } { key4 }
+% \end{verbatim}
+% Note that there is a difference between an empty value (an equals
+% sign followed by nothing) and a missing value (no equals sign at
+% all). Spaces are trimmed from the ends of the \meta{key} and \meta{value},
+% then one \emph{outer} set of braces is removed from the \meta{key}
+% and \meta{value} as part of the processing. If you need exactly the output
+% shown above, you'll need to either \texttt{e}-type or \texttt{x}-type expand
+% the function.
+% \begin{texnote}
+% The result of each list element is returned within \cs{exp_not:n}, which
+% means that the converted input stream does not expand further when
+% appearing in an \texttt{e}-type or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[rEXP, updated = 2021-05-10]
+% {\keyval_parse:NNn, \keyval_parse:NNV, \keyval_parse:NNv}
+% \begin{syntax}
+% \cs{keyval_parse:NNn} \meta{function_1} \meta{function_2} \Arg{key--value list}
+% \end{syntax}
+% Parses the \meta{key--value list} into a series of \meta{keys} and
+% associated \meta{values}, or keys alone (if no \meta{value} was
+% given). \meta{function_1} should take one argument, while
+% \meta{function_2} should absorb two arguments. After
+% \cs{keyval_parse:NNn} has parsed the \meta{key--value list},
+% \meta{function_1} is used to process keys given with no value
+% and \meta{function_2} is used to process keys given with a
+% value. The order of the \meta{keys} in the \meta{key--value list}
+% is preserved. Thus
+% \begin{verbatim}
+% \keyval_parse:NNn \function:n \function:nn
+% { key1 = value1 , key2 = value2, key3 = , key4 }
+% \end{verbatim}
+% is converted into an input stream
+% \begin{verbatim}
+% \function:nn { key1 } { value1 }
+% \function:nn { key2 } { value2 }
+% \function:nn { key3 } { }
+% \function:n { key4 }
+% \end{verbatim}
+% Note that there is a difference between an empty value (an equals
+% sign followed by nothing) and a missing value (no equals sign at
+% all). Spaces are trimmed from the ends of the \meta{key} and \meta{value},
+% then one \emph{outer} set of braces is removed from the \meta{key}
+% and \meta{value} as part of the processing.
+%
+% This shares the implementation of \cs{keyval_parse:nnn}, the difference is
+% only semantically.
+% \begin{texnote}
+% The result is returned within \cs{exp_not:n}, which means that the
+% converted input stream does not expand further when appearing in an
+% \texttt{e}-type or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3keys} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \subsection{Low-level interface}
+%
+% The low-level key parser's implementation is based heavily on \pkg{expkv}.
+% Compared to \pkg{keyval} it adds a number of additional \enquote{safety}
+% requirements and allows to process the parsed list of key--value pairs in a
+% variety of ways. The net result is that this code needs around one and a half
+% the amount of time as \pkg{keyval} to parse the same list of keys. To optimise
+% speed as far as reasonably practical, a number of lower-level approaches are
+% taken rather than using the higher-level \pkg{expl3} interfaces.
+%
+% \begin{macrocode}
+%<@@=keyval>
+% \end{macrocode}
+%
+% \begin{variable}{\s_@@_nil,\s_@@_mark,\s_@@_stop,\s_@@_tail}
+% \begin{macrocode}
+\scan_new:N \s_@@_nil
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+\scan_new:N \s_@@_tail
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l__kernel_keyval_allow_blank_keys_bool}
+% The general behavior of the \pkg{l3keys} module is to throw an error on
+% blank key names. However to support the usage of \cs{keyval_parse:nnn} in
+% the \pkg{l3prop} module we allow this error to be switched off temporarily
+% and just ignore blank names.
+% \begin{macrocode}
+\bool_new:N \l__kernel_keyval_allow_blank_keys_bool
+% \end{macrocode}
+% \end{variable}
+%
+% This temporary macro will be used since some of the definitions will need an
+% active comma or equals sign. Inside of this macro |#1| will be the active
+% comma and |#2| will be the active equals sign.
+% \begin{macrocode}
+\group_begin:
+ \cs_set_protected:Npn \@@_tmp:w #1#2
+ {
+% \end{macrocode}
+%
+% \begin{macro}[EXP]
+% {
+% \keyval_parse:nnn, \keyval_parse:nnV, \keyval_parse:nnv,
+% \keyval_parse:NNn, \keyval_parse:NNV, \keyval_parse:NNv
+% }
+% The main function starts the first of two loops. The outer loop splits the
+% key--value list at active commas, the inner loop will do so at other commas.
+% The use of \cs{s_@@_mark} here prevents loss of braces from the key
+% argument.
+% \begin{macrocode}
+ \cs_new:Npn \keyval_parse:nnn ##1 ##2 ##3
+ {
+ \__kernel_exp_not:w \tex_expanded:D
+ {
+ {
+ \@@_loop_active:nnw {##1} {##2}
+ \s_@@_mark ##3 #1 \s_@@_tail #1
+ }
+ }
+ }
+ \cs_new_eq:NN \keyval_parse:NNn \keyval_parse:nnn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_loop_active:nnw}
+% First a fast test for the end of the loop is done, it'll gobble everything
+% up to a \cs{s_@@_tail}. The loop ending macro will gobble everything to the
+% last comma in this definition.
+% If the end isn't reached yet, start the second loop splitting at other
+% commas, the next iteration of this first loop will be inserted by the end of
+% \cs{@@_loop_other:nnw}.
+% \begin{macrocode}
+ \cs_new:Npn \@@_loop_active:nnw ##1 ##2 ##3 #1
+ {
+ \@@_if_recursion_tail:w ##3
+ \@@_end_loop_active:w \s_@@_tail
+ \@@_loop_other:nnw {##1} {##2} ##3 , \s_@@_tail ,
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_split_other:w, \@@_split_active:w}
+% These two macros allow to split at the first equals sign of category 12 or
+% 13. At the same time they also execute branching by inserting the first
+% token following \cs{s_@@_mark} that followed the equals sign. Hence they
+% also test for the presence of such an equals sign simultaneously.
+% \begin{macrocode}
+ \cs_new:Npn \@@_split_other:w ##1 = ##2 \s_@@_mark ##3
+ { ##3 ##1 \s_@@_stop \s_@@_mark ##2 }
+ \cs_new:Npn \@@_split_active:w ##1 #2 ##2 \s_@@_mark ##3
+ { ##3 ##1 \s_@@_stop \s_@@_mark ##2 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_loop_other:nnw}
+% The second loop uses the same test for its end as the first loop, next it
+% splits at the first active equals sign using \cs{@@_split_active:w}. The
+% \cs{s_@@_nil} prevents accidental brace stripping and acts as a delimiter in
+% the next steps. First testing for an active equals sign will reduce the
+% number of necessary expansion steps for the expected average use case of
+% other equals signs and hence perform better on average.
+% \begin{macrocode}
+ \cs_new:Npn \@@_loop_other:nnw ##1 ##2 ##3 ,
+ {
+ \@@_if_recursion_tail:w ##3
+ \@@_end_loop_other:w \s_@@_tail
+ \@@_split_active:w ##3 \s_@@_nil
+ \s_@@_mark \@@_split_active_auxi:w
+ #2 \s_@@_mark \@@_clean_up_active:w
+ {##1} {##2}
+ \s_@@_mark
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_split_active_auxi:w}
+% \begin{macro}[EXP]{\@@_split_active_auxii:w}
+% \begin{macro}[EXP]{\@@_split_active_auxiii:w}
+% \begin{macro}[EXP]{\@@_split_active_auxiv:w}
+% \begin{macro}[EXP]{\@@_split_active_auxv:w}
+% After \cs{@@_split_active:w} the following will only be called if there was
+% at least one active equals sign in the current key--value pair. Therefore
+% this is the execution branch for a key--value pair with an active equals
+% sign. |##1| will be everything up to the first active equals sign. First it
+% tests for other equals signs in the key name, which will eventually throw an
+% error via \cs{@@_misplaced_equal_after_active_error:w}. If none was found we
+% forward the key to \cs{@@_split_active_auxii:w}.
+% \begin{macrocode}
+ \cs_new:Npn \@@_split_active_auxi:w ##1 \s_@@_stop
+ {
+ \@@_split_other:w ##1 \s_@@_nil
+ \s_@@_mark \@@_misplaced_equal_after_active_error:w
+ = \s_@@_mark \@@_split_active_auxii:w
+ }
+% \end{macrocode}
+% \cs{@@_split_active_auxii:w} gets the correct key name with a leading
+% \cs{s_@@_mark} as |##1|. It has to sanitise the remainder of the previous
+% test and trims the key name which will be forwarded to
+% \cs{@@_split_active_auxiii:w}.
+% \begin{macrocode}
+ \cs_new:Npn \@@_split_active_auxii:w
+ ##1 \s_@@_nil \s_@@_mark \@@_misplaced_equal_after_active_error:w
+ \s_@@_stop \s_@@_mark
+ ##2 \s_@@_nil #2 \s_@@_mark \@@_clean_up_active:w
+ { \@@_trim:nN {##1} \@@_split_active_auxiii:w ##2 \s_@@_nil }
+% \end{macrocode}
+% Next we test for a misplaced active equals sign in the value, if none is
+% found \cs{@@_split_active_auxiv:w} will be called.
+% \begin{macrocode}
+ \cs_new:Npn \@@_split_active_auxiii:w ##1 ##2 \s_@@_nil
+ {
+ \@@_split_active:w ##2 \s_@@_nil
+ \s_@@_mark \@@_misplaced_equal_in_split_error:w
+ #2 \s_@@_mark \@@_split_active_auxiv:w
+ {##1}
+ }
+% \end{macrocode}
+% This runs the last test after sanitising the remainder of the previous one.
+% This time test for a misplaced equals sign of category 12 in the value.
+% Finally the last auxiliary macro will be called.
+% \begin{macrocode}
+ \cs_new:Npn \@@_split_active_auxiv:w
+ ##1 \s_@@_nil \s_@@_mark \@@_misplaced_equal_in_split_error:w
+ \s_@@_stop \s_@@_mark
+ {
+ \@@_split_other:w ##1 \s_@@_nil
+ \s_@@_mark \@@_misplaced_equal_in_split_error:w
+ = \s_@@_mark \@@_split_active_auxv:w
+ }
+% \end{macrocode}
+% This last macro in this execution branch sanitises the last test, trims the
+% value and passes it to \cs{@@_pair:nnnn}.
+% \begin{macrocode}
+ \cs_new:Npn \@@_split_active_auxv:w
+ ##1 \s_@@_nil \s_@@_mark \@@_misplaced_equal_in_split_error:w
+ \s_@@_stop \s_@@_mark
+ { \@@_trim:nN { ##1 } \@@_pair:nnnn }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_clean_up_active:w}
+% The following is the branch taken if the key--value pair doesn't contain an
+% active equals sign. The remainder of that test will be cleaned up by
+% \cs{@@_clean_up_active:w} which will then split at an equals sign of
+% category other.
+% \begin{macrocode}
+ \cs_new:Npn \@@_clean_up_active:w
+ ##1 \s_@@_nil \s_@@_mark \@@_split_active_auxi:w \s_@@_stop \s_@@_mark
+ {
+ \@@_split_other:w ##1 \s_@@_nil
+ \s_@@_mark \@@_split_other_auxi:w
+ = \s_@@_mark \@@_clean_up_other:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_split_other_auxi:w}
+% \begin{macro}[EXP]{\@@_split_other_auxii:w}
+% \begin{macro}[EXP]{\@@_split_other_auxiii:w}
+% This is executed if the key--value pair doesn't contain an active equals
+% sign but at least one other. |##1| of \cs{@@_split_other_auxi:w} will
+% contain the complete key name, which is trimmed and forwarded to the next
+% auxiliary macro.
+% \begin{macrocode}
+ \cs_new:Npn \@@_split_other_auxi:w ##1 \s_@@_stop
+ { \@@_trim:nN { ##1 } \@@_split_other_auxii:w }
+% \end{macrocode}
+% We know that the value doesn't contain misplaced active equals signs but we
+% have to test for others. Also we need to sanitise the previous test, which
+% is done here and not earlier to avoid superfluous argument grabbing.
+% \begin{macrocode}
+ \cs_new:Npn \@@_split_other_auxii:w
+ ##1 ##2 \s_@@_nil = \s_@@_mark \@@_clean_up_other:w
+ {
+ \@@_split_other:w ##2 \s_@@_nil
+ \s_@@_mark \@@_misplaced_equal_in_split_error:w
+ = \s_@@_mark \@@_split_other_auxiii:w
+ { ##1 }
+ }
+% \end{macrocode}
+% \cs{@@_split_other_auxiii:w} sanitises the test for other equals signs,
+% trims the value and forwards it to \cs{@@_pair:nnnn}.
+% \begin{macrocode}
+ \cs_new:Npn \@@_split_other_auxiii:w
+ ##1 \s_@@_nil \s_@@_mark \@@_misplaced_equal_in_split_error:w
+ \s_@@_stop \s_@@_mark
+ { \@@_trim:nN { ##1 } \@@_pair:nnnn }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_clean_up_other:w}
+% \cs{@@_clean_up_other:w} is the last branch that might exist. It is called
+% if no equals sign was found, hence the only possibilities left are a blank
+% list element, which is to be skipped, or a lonely key. If it's no empty list
+% element this will trim the key name and forward it to \cs{@@_key:nn}.
+% \begin{macrocode}
+ \cs_new:Npn \@@_clean_up_other:w
+ ##1 \s_@@_nil \s_@@_mark \@@_split_other_auxi:w \s_@@_stop \s_@@_mark
+ {
+ \@@_if_blank:w ##1 \s_@@_nil \s_@@_stop \@@_blank_true:w
+ \s_@@_mark \s_@@_stop
+ \@@_trim:nN { ##1 } \@@_key:nn
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_misplaced_equal_after_active_error:w}
+% \begin{macro}[EXP]{\@@_misplaced_equal_in_split_error:w}
+% All these two macros do is gobble the remainder of the current other loop
+% execution and throw an error. Afterwards they have to insert the next loop
+% iteration.
+% \begin{macrocode}
+ \cs_new:Npn \@@_misplaced_equal_after_active_error:w
+ \s_@@_mark ##1 \s_@@_stop \s_@@_mark ##2 \s_@@_nil
+ = \s_@@_mark \@@_split_active_auxii:w
+ \s_@@_mark ##3 \s_@@_nil
+ #2 \s_@@_mark \@@_clean_up_active:w
+ {
+ \msg_expandable_error:nn
+ { keyval } { misplaced-equals-sign }
+ \@@_loop_other:nnw
+ }
+ \cs_new:Npn \@@_misplaced_equal_in_split_error:w
+ \s_@@_mark ##1 \s_@@_stop \s_@@_mark ##2 \s_@@_nil
+ ##3 \s_@@_mark ##4 ##5
+ {
+ \msg_expandable_error:nn
+ { keyval } { misplaced-equals-sign }
+ \@@_loop_other:nnw
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_end_loop_other:w, \@@_end_loop_active:w}
+% All that's left for the parsing loops are the macros which end the
+% recursion. Both just gobble the remaining tokens of the respective loop
+% including the next recursion call. \cs{@@_end_loop_other:w} also has to
+% insert the next iteration of the active loop.
+% \begin{macrocode}
+ \cs_new:Npn \@@_end_loop_other:w
+ \s_@@_tail
+ \@@_split_active:w
+ \s_@@_mark \s_@@_tail
+ \s_@@_nil \s_@@_mark
+ \@@_split_active_auxi:w
+ #2 \s_@@_mark \@@_clean_up_active:w
+ { \@@_loop_active:nnw }
+ \cs_new:Npn \@@_end_loop_active:w
+ \s_@@_tail
+ \@@_loop_other:nnw ##1 \s_@@_mark \s_@@_tail , \s_@@_tail ,
+ { }
+% \end{macrocode}
+% \end{macro}
+%
+% The parsing loops are done, so here ends the definition of \cs{@@_tmp:w},
+% which will finally set up the macros.
+% \begin{macrocode}
+ }
+ \char_set_catcode_active:n { `\, }
+ \char_set_catcode_active:n { `\= }
+ \@@_tmp:w , =
+\group_end:
+\cs_generate_variant:Nn \keyval_parse:NNn { NNV , NNv }
+\cs_generate_variant:Nn \keyval_parse:nnn { nnV , nnv }
+% \end{macrocode}
+%
+% \begin{macro}[EXP]{\@@_pair:nnnn, \@@_key:nn}
+% These macros will be called on the parsed keys and values of the key--value
+% list. All arguments are completely trimmed. They test for blank key names
+% and call the functions passed to \cs{keyval_parse:nnn} inside of
+% \cs{exp_not:n} with the correct arguments. Afterwards they insert the next
+% iteration of the other loop.
+% \begin{macrocode}
+\group_begin:
+ \cs_set_protected:Npn \@@_tmp:w #1#2
+ {
+ \cs_new:Npn \@@_pair:nnnn ##1 ##2 ##3 ##4
+ {
+ \@@_if_blank:w \s_@@_mark ##2 \s_@@_nil \s_@@_stop \@@_blank_key_error:w
+ \s_@@_mark \s_@@_stop
+ #1
+ \exp_not:n { ##4 {##2} {##1} }
+ #2
+ \@@_loop_other:nnw {##3} {##4}
+ }
+ \cs_new:Npn \@@_key:nn ##1 ##2
+ {
+ \@@_if_blank:w \s_@@_mark ##1 \s_@@_nil \s_@@_stop \@@_blank_key_error:w
+ \s_@@_mark \s_@@_stop
+ #1
+ \exp_not:n { ##2 {##1} }
+ #2
+ \@@_loop_other:nnw {##2}
+ }
+ }
+ \@@_tmp:w { } { }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_if_empty:w,\@@_if_blank:w,\@@_if_recursion_tail:w}
+% All these tests work by gobbling tokens until a certain combination is met,
+% which makes them pretty fast. The test for a blank argument should be called
+% with an arbitrary token following the argument. Each of these utilize the
+% fact that the argument will contain a leading \cs{s_@@_mark}.
+% \begin{macrocode}
+\cs_new:Npn \@@_if_empty:w #1 \s_@@_mark \s_@@_stop { }
+\cs_new:Npn \@@_if_blank:w \s_@@_mark #1 { \@@_if_empty:w \s_@@_mark }
+\cs_new:Npn \@@_if_recursion_tail:w \s_@@_mark #1 \s_@@_tail { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_blank_true:w,\@@_blank_key_error:w}
+% These macros will be called if the tests above didn't gobble them, they
+% execute the branching.
+% \begin{macrocode}
+\cs_new:Npn \@@_blank_true:w \s_@@_mark \s_@@_stop \@@_trim:nN #1 \@@_key:nn
+ { \@@_loop_other:nnw }
+\cs_new:Npn \@@_blank_key_error:w \s_@@_mark \s_@@_stop #1 \@@_loop_other:nnw
+ {
+ \bool_if:NTF \l__kernel_keyval_allow_blank_keys_bool
+ { #1 }
+ { \msg_expandable_error:nn { keyval } { blank-key-name } }
+ \@@_loop_other:nnw
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% Two messages for the low level parsing system.
+% \begin{macrocode}
+\msg_new:nnn { keyval } { misplaced-equals-sign }
+ { Misplaced~'='~in~key-value~input~\msg_line_context: }
+\msg_new:nnn { keyval } { blank-key-name }
+ { Blank~key~name~in~key-value~input~\msg_line_context: }
+\prop_gput:Nnn \g_msg_module_name_prop { keyval } { LaTeX }
+\prop_gput:Nnn \g_msg_module_type_prop { keyval } { }
+% \end{macrocode}
+%
+% \begin{macro}[EXP]{\@@_trim:nN}
+% \begin{macro}[EXP]
+% {\@@_trim_auxi:w,\@@_trim_auxii:w,\@@_trim_auxiii:w,\@@_trim_auxiv:w}
+% And an adapted version of \cs{__tl_trim_spaces:nn} which is a bit faster for
+% our use case, as it can strip the braces at the end. This is pretty much the
+% same concept, so I won't comment on it here. The speed gain by using this
+% instead of \cs{tl_trim_spaces_apply:nN} is about 10\,\% of the total time for
+% \cs{keyval_parse:NNn} with one key and one key--value pair, so I think it's
+% worth it.
+% \begin{macrocode}
+\group_begin:
+ \cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \cs_new:Npn \@@_trim:nN ##1
+ {
+ \@@_trim_auxi:w
+ ##1
+ \s_@@_nil
+ \s_@@_mark #1 { }
+ \s_@@_mark \@@_trim_auxii:w
+ \@@_trim_auxiii:w
+ #1 \s_@@_nil
+ \@@_trim_auxiv:w
+ }
+ \cs_new:Npn \@@_trim_auxi:w ##1 \s_@@_mark #1 ##2 \s_@@_mark ##3
+ {
+ ##3
+ \@@_trim_auxi:w
+ \s_@@_mark
+ ##2
+ \s_@@_mark #1 {##1}
+ }
+ \cs_new:Npn \@@_trim_auxii:w \@@_trim_auxi:w \s_@@_mark \s_@@_mark ##1
+ {
+ \@@_trim_auxiii:w
+ ##1
+ }
+ \cs_new:Npn \@@_trim_auxiii:w ##1 #1 \s_@@_nil ##2
+ {
+ ##2
+ ##1 \s_@@_nil
+ \@@_trim_auxiii:w
+ }
+% \end{macrocode}
+% This is the one macro which differs from the original definition.
+% \begin{macrocode}
+ \cs_new:Npn \@@_trim_auxiv:w
+ \s_@@_mark ##1 \s_@@_nil
+ \@@_trim_auxiii:w \s_@@_nil \@@_trim_auxiii:w
+ ##2
+ { ##2 { ##1 } }
+ }
+ \@@_tmp:w { ~ }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Constants and variables}
+%
+% \begin{macrocode}
+%<@@=keys>
+% \end{macrocode}
+%
+% \begin{variable}
+% {
+% \c_@@_code_root_str ,
+% \c_@@_check_root_str ,
+% \c_@@_default_root_str ,
+% \c_@@_groups_root_str ,
+% \c_@@_inherit_root_str ,
+% \c_@@_type_root_str
+% }
+% Various storage areas for the different data which make up keys.
+% \begin{macrocode}
+\str_const:Nn \c_@@_code_root_str { key~code~>~ }
+\str_const:Nn \c_@@_check_root_str { key~check~>~ }
+\str_const:Nn \c_@@_default_root_str { key~default~>~ }
+\str_const:Nn \c_@@_groups_root_str { key~groups~>~ }
+\str_const:Nn \c_@@_inherit_root_str { key~inherit~>~ }
+\str_const:Nn \c_@@_type_root_str { key~type~>~ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_props_root_str}
+% The prefix for storing properties.
+% \begin{macrocode}
+\str_const:Nn \c_@@_props_root_str { key~prop~>~ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_keys_choice_int, \l_keys_choice_tl}
+% Publicly accessible data on which choice is being used when several
+% are generated as a set.
+% \begin{macrocode}
+\int_new:N \l_keys_choice_int
+\tl_new:N \l_keys_choice_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_groups_clist}
+% Used for storing and recovering the list of groups which apply to a key:
+% set as a comma list but at one point we have to use this for a token
+% list recovery.
+% \begin{macrocode}
+\clist_new:N \l_@@_groups_clist
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_inherit_clist}
+% For normalisation.
+% \begin{macrocode}
+\clist_new:N \l_@@_inherit_clist
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_keys_key_str}
+% The name of a key itself: needed when setting keys.
+% \begin{macrocode}
+\str_new:N \l_keys_key_str
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}[deprecated]{\l_keys_key_tl}
+% The |tl| version is deprecated but has to be handled manually.
+% \begin{macrocode}
+\tl_new:N \l_keys_key_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_module_str}
+% The module for an entire set of keys.
+% \begin{macrocode}
+\str_new:N \l_@@_module_str
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_no_value_bool}
+% A marker is needed internally to show if only a key or a key plus a
+% value was seen: this is recorded here.
+% \begin{macrocode}
+\bool_new:N \l_@@_no_value_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_only_known_bool}
+% Used to track if only \enquote{known} keys are being set.
+% \begin{macrocode}
+\bool_new:N \l_@@_only_known_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_keys_path_str}
+% The \enquote{path} of the current key is stored here: this is
+% available to the programmer and so is public.
+% \begin{macrocode}
+\str_new:N \l_keys_path_str
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}[deprecated]{\l_keys_path_tl}
+% The older version is deprecated but has to be handled manually.
+% \begin{macrocode}
+\tl_new:N \l_keys_path_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_inherit_str}
+% \begin{macrocode}
+\str_new:N \l_@@_inherit_str
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_relative_tl}
+% The relative path for passing keys back to the user. As this can
+% be explicitly no-value, it must be a token list.
+% \begin{macrocode}
+\tl_new:N \l_@@_relative_tl
+\tl_set:Nn \l_@@_relative_tl { \q_@@_no_value }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_property_str}
+% The \enquote{property} begin set for a key at definition time is
+% stored here.
+% \begin{macrocode}
+\str_new:N \l_@@_property_str
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_selective_bool, \l_@@_filtered_bool}
+% Two booleans for using key groups: one to indicate that \enquote{selective}
+% setting is active, a second to specify which type (\enquote{opt-in}
+% or \enquote{opt-out}).
+% \begin{macrocode}
+\bool_new:N \l_@@_selective_bool
+\bool_new:N \l_@@_filtered_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_selective_seq}
+% The list of key groups being filtered in or out during selective setting.
+% \begin{macrocode}
+\seq_new:N \l_@@_selective_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_unused_clist}
+% Used when setting only some keys to store those left over.
+% \begin{macrocode}
+\clist_new:N \l_@@_unused_clist
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_keys_value_tl}
+% The value given for a key: may be empty if no value was given.
+% \begin{macrocode}
+\tl_new:N \l_keys_value_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_tmp_bool, \l_@@_tmpa_tl, \l_@@_tmpb_tl}
+% Scratch space.
+% \begin{macrocode}
+\bool_new:N \l_@@_tmp_bool
+\tl_new:N \l_@@_tmpa_tl
+\tl_new:N \l_@@_tmpb_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_precompile_bool, \l_@@_precompile_tl}
+% For digesting keys.
+% \begin{macrocode}
+\bool_new:N \l_@@_precompile_bool
+\tl_new:N \l_@@_precompile_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_keys_usage_load_prop, \l_keys_usage_preamble_prop}
+% Global data for document-level information.
+% \begin{macrocode}
+\prop_new:N \l_keys_usage_load_prop
+\prop_new:N \l_keys_usage_preamble_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Internal auxiliaries}
+%
+% \begin{variable}{\s_@@_nil,\s_@@_mark,\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_nil
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\q_@@_no_value}
+% Internal quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_no_value
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[pTF]{\@@_quark_if_no_value:N}
+% Branching quark conditional.
+% \begin{macrocode}
+\__kernel_quark_new_conditional:Nn \@@_quark_if_no_value:N { TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_precompile:n}
+% An auxiliary to allow cleaner showing of code.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_precompile:n #1
+ {
+ \bool_if:NTF \l_@@_precompile_bool
+ { \tl_put_right:Nn \l_@@_precompile_tl }
+ { \use:n }
+ {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_cs_undefine:c}
+% Local version of \cs{cs_undefine:c} to avoid sprinkling
+% \cs{tex_undefined:D} everywhere.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cs_undefine:c #1
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \else:
+ \use_i:nnnn
+ \fi:
+ \cs_set_eq:cN {#1} \tex_undefined:D
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{The key defining mechanism}
+%
+% \begin{macro}{\keys_define:nn, \keys_define:ne, \keys_define:nx}
+% \begin{macro}{\@@_define:nnn, \@@_define:onn}
+% The public function for definitions is just a wrapper for the lower
+% level mechanism, more or less. The outer function is designed to
+% keep a track of the current module, to allow safe nesting. The module is set
+% removing any leading |/| (which is not needed here).
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_define:nn
+ { \@@_define:onn \l_@@_module_str }
+\cs_generate_variant:Nn \keys_define:nn { ne , nx }
+\cs_new_protected:Npn \@@_define:nnn #1#2#3
+ {
+ \str_set:Ne \l_@@_module_str { \@@_trim_spaces:n {#2} }
+ \keyval_parse:NNn \@@_define:n \@@_define:nn {#3}
+ \str_set:Nn \l_@@_module_str {#1}
+ }
+\cs_generate_variant:Nn \@@_define:nnn { o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_define:n}
+% \begin{macro}{\@@_define:nn}
+% \begin{macro}{\@@_define_aux:nn}
+% The outer functions here record whether a value was given and then
+% converge on a common internal mechanism. There is first a search for
+% a property in the current key name, then a check to make sure it is
+% known before the code hands off to the next step.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_define:n #1
+ {
+ \bool_set_true:N \l_@@_no_value_bool
+ \@@_define_aux:nn {#1} { }
+ }
+\cs_new_protected:Npn \@@_define:nn #1#2
+ {
+ \bool_set_false:N \l_@@_no_value_bool
+ \@@_define_aux:nn {#1} {#2}
+ }
+\cs_new_protected:Npn \@@_define_aux:nn #1#2
+ {
+ \@@_property_find:n {#1}
+ \cs_if_exist:cTF { \c_@@_props_root_str \l_@@_property_str }
+ { \@@_define_code:n {#2} }
+ {
+ \str_if_empty:NF \l_@@_property_str
+ {
+ \msg_error:nnee { keys } { property-unknown }
+ \l_@@_property_str \l_keys_path_str
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_property_find:n}
+% \begin{macro}[EXP]{\@@_property_find_auxi:w}
+% \begin{macro}{\@@_property_find_auxii:w}
+% \begin{macro}[EXP]
+% {
+% \@@_property_find_auxiii:w ,
+% \@@_property_find_auxiv:w
+% }
+% \begin{macro}{\@@_property_find_err:w}
+% Searching for a property means finding the last |.| in the input,
+% and storing the text before and after it. Everything is first turned into
+% strings, so there is no problem using \cs{cs_set_nopar:Npe} instead of
+% \cs{str_set:Ne} to set \cs{l_keys_path_str}. To gain further speed, brace
+% tricks are used and \cs{@@_property_find_auxiv:w} is defined as expandable.
+% Since spaces will already be trimmed from the module we can omit it from the
+% argument to \cs{@@_trim_spaces:n}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_property_find:n #1
+ {
+ \exp_after:wN \@@_property_find_auxi:w \tl_to_str:n {#1}
+ \s_@@_nil \@@_property_find_auxii:w
+ . \s_@@_nil \@@_property_find_err:w
+ }
+\cs_new:Npn \@@_property_find_auxi:w #1 . #2 \s_@@_nil #3
+ {
+ #3 #1 \s_@@_mark #2 \s_@@_nil #3
+ }
+\cs_new_protected:Npn \@@_property_find_auxii:w
+ #1 \s_@@_mark #2 \s_@@_nil \@@_property_find_auxii:w . \s_@@_nil
+ \@@_property_find_err:w
+ {
+ \cs_set_nopar:Npe \l_keys_path_str
+ {
+ \str_if_empty:NF \l_@@_module_str { \l_@@_module_str / }
+ \exp_after:wN \@@_trim_spaces:n \tex_expanded:D {{
+ #1
+ \if_false: }}} \fi:
+ \@@_property_find_auxi:w #2 \s_@@_nil \@@_property_find_auxiii:w
+ . \s_@@_nil \@@_property_find_auxiv:w
+ }
+\cs_new:Npn \@@_property_find_auxiii:w #1 \s_@@_mark #2 . #3 \s_@@_nil #4
+ {
+ . #1 #4 #2 \s_@@_mark #3 \s_@@_nil #4
+ }
+\cs_new:Npn \@@_property_find_auxiv:w
+ #1 \s_@@_nil \@@_property_find_auxiii:w
+ \s_@@_mark \s_@@_nil \@@_property_find_auxiv:w
+ {
+ \if_false: {{{ \fi: }}}
+ \cs_set_nopar:Npe \l_@@_property_str { . #1 }
+ \tl_set_eq:NN \l_keys_path_tl \l_keys_path_str
+ }
+\cs_new_protected:Npn \@@_property_find_err:w
+ #1 \s_@@_nil #2 \@@_property_find_err:w
+ {
+ \str_clear:N \l_@@_property_str
+ \msg_error:nnn { keys } { no-property } {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_define_code:n}
+% \begin{macro}[EXP]{\@@_define_code:w}
+% Two possible cases. If there is a value for the key, then just use
+% the function. If not, then a check to make sure there is no need for
+% a value with the property. If there should be one then complain,
+% otherwise execute it. There is no need to check for a |:| as if it
+% was missing the earlier tests would have failed.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_define_code:n #1
+ {
+ \bool_if:NTF \l_@@_no_value_bool
+ {
+ \exp_after:wN \@@_define_code:w
+ \l_@@_property_str \s_@@_stop
+ { \use:c { \c_@@_props_root_str \l_@@_property_str } }
+ {
+ \msg_error:nnee { keys } { property-requires-value }
+ \l_@@_property_str \l_keys_path_str
+ }
+ }
+ { \use:c { \c_@@_props_root_str \l_@@_property_str } {#1} }
+ }
+\exp_last_unbraced:NNNNo
+ \cs_new:Npn \@@_define_code:w #1 \c_colon_str #2 \s_@@_stop
+ { \tl_if_empty:nTF {#2} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Turning properties into actions}
+%
+% \begin{macro}
+% {
+% \@@_bool_set:Nn, \@@_bool_set:cn,
+% \@@_bool_set_inverse:Nn, \@@_bool_set_inverse:cn
+% }
+% \begin{macro}{\@@_bool_set:Nnnn}
+% Boolean keys are really just choices, but all done by hand. The
+% second argument here is the scope: either empty or \texttt{ g } for
+% global.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_bool_set:Nn #1#2
+ { \@@_bool_set:Nnnn #1 {#2} { true } { false } }
+\cs_generate_variant:Nn \@@_bool_set:Nn { c }
+\cs_new_protected:Npn \@@_bool_set_inverse:Nn #1#2
+ { \@@_bool_set:Nnnn #1 {#2} { false } { true } }
+\cs_generate_variant:Nn \@@_bool_set_inverse:Nn { c }
+\cs_new_protected:Npn \@@_bool_set:Nnnn #1#2#3#4
+ {
+ \bool_if_exist:NF #1 { \bool_new:N #1 }
+ \@@_choice_make:
+ \@@_cmd_set:ne { \l_keys_path_str / true }
+ { \exp_not:c { bool_ #2 set_ #3 :N } \exp_not:N #1 }
+ \@@_cmd_set:ne { \l_keys_path_str / false }
+ { \exp_not:c { bool_ #2 set_ #4 :N } \exp_not:N #1 }
+ \@@_cmd_set_direct:nn { \l_keys_path_str / unknown }
+ {
+ \msg_error:nne { keys } { boolean-values-only }
+ \l_keys_path_str
+ }
+ \@@_default_set:n { true }
+ }
+\cs_generate_variant:Nn \@@_bool_set:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_choice_make:, \@@_multichoice_make:}
+% \begin{macro}{\@@_choice_make:N}
+% \begin{macro}{\@@_choice_make_aux:N}
+% To make a choice from a key, two steps: set the code, and set the
+% unknown key. As multichoices and choices are essentially the same bar one
+% function, the code is given together.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_choice_make:
+ { \@@_choice_make:N \@@_choice_find:n }
+\cs_new_protected:Npn \@@_multichoice_make:
+ { \@@_choice_make:N \@@_multichoice_find:n }
+\cs_new_protected:Npn \@@_choice_make:N #1
+ {
+ \cs_if_exist:cTF
+ { \c_@@_type_root_str \@@_parent:o \l_keys_path_str }
+ {
+ \str_if_eq:vnTF
+ { \c_@@_type_root_str \@@_parent:o \l_keys_path_str }
+ { choice }
+ {
+ \msg_error:nnee { keys } { nested-choice-key }
+ \l_keys_path_tl { \@@_parent:o \l_keys_path_str }
+ }
+ { \@@_choice_make_aux:N #1 }
+ }
+ { \@@_choice_make_aux:N #1 }
+ }
+\cs_new_protected:Npn \@@_choice_make_aux:N #1
+ {
+ \cs_set_nopar:cpn { \c_@@_type_root_str \l_keys_path_str }
+ { choice }
+ \@@_cmd_set_direct:nn \l_keys_path_str { #1 {##1} }
+ \@@_cmd_set_direct:nn { \l_keys_path_str / unknown }
+ {
+ \msg_error:nnee { keys } { choice-unknown }
+ \l_keys_path_str {##1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_choices_make:nn, \@@_multichoices_make:nn}
+% \begin{macro}{\@@_choices_make:Nnn}
+% Auto-generating choices means setting up the root key as a choice, then
+% defining each choice in turn.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_choices_make:nn
+ { \@@_choices_make:Nnn \@@_choice_make: }
+\cs_new_protected:Npn \@@_multichoices_make:nn
+ { \@@_choices_make:Nnn \@@_multichoice_make: }
+\cs_new_protected:Npn \@@_choices_make:Nnn #1#2#3
+ {
+ #1
+ \int_zero:N \l_keys_choice_int
+ \clist_map_inline:nn {#2}
+ {
+ \int_incr:N \l_keys_choice_int
+ \@@_cmd_set:ne
+ { \l_keys_path_str / \@@_trim_spaces:n {##1} }
+ {
+ \tl_set:Nn \exp_not:N \l_keys_choice_tl {##1}
+ \int_set:Nn \exp_not:N \l_keys_choice_int
+ { \int_use:N \l_keys_choice_int }
+ \exp_not:n {#3}
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_cmd_set:nn, \@@_cmd_set:Vn, \@@_cmd_set:ne, \@@_cmd_set:Vo,
+% \@@_cmd_set_direct:nn
+% }
+% Setting the code for a key first logs if appropriate that we are
+% defining a new key, then saves the code.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cmd_set:nn #1#2
+ { \@@_cmd_set_direct:nn {#1} { \@@_precompile:n {#2} } }
+\cs_generate_variant:Nn \@@_cmd_set:nn { ne , Vn , Vo }
+\cs_new_protected:Npn \@@_cmd_set_direct:nn #1#2
+ { \cs_set_protected:cpn { \c_@@_code_root_str #1 } ##1 {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_cs_set:NNpn, \@@_cs_set:Ncpn}
+% Creating control sequences is a bit more tricky than other cases as
+% we need to pick up the |p| argument. To make the internals look clearer,
+% the trailing |n| argument here is just for appearance.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cs_set:NNpn #1#2#3#
+ {
+ \cs_set_protected:cpe { \c_@@_code_root_str \l_keys_path_str } ##1
+ {
+ \@@_precompile:n
+ { #1 \exp_not:N #2 \exp_not:n {#3} {##1} }
+ }
+ \use_none:n
+ }
+\cs_generate_variant:Nn \@@_cs_set:NNpn { Nc }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_default_set:n}
+% Setting a default value is easy. These are stored using \cs{cs_set_nopar:cpe} as this
+% avoids any worries about whether a token list exists.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_default_set:n #1
+ {
+ \tl_if_empty:nTF {#1}
+ {
+ \@@_cs_undefine:c
+ { \c_@@_default_root_str \l_keys_path_str }
+ }
+ {
+ \cs_set_nopar:cpe
+ { \c_@@_default_root_str \l_keys_path_str }
+ { \exp_not:n {#1} }
+ \@@_value_requirement:nn { required } { false }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_groups_set:n}
+% Assigning a key to one or more groups uses comma lists. As the list of
+% groups only exists if there is anything to do, the setting is done using
+% a scratch list. For the usual grouping reasons we use the low-level
+% approach to undefining a list. We also use the low-level approach for
+% the other case to avoid tripping up the |check-declarations| code.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_groups_set:n #1
+ {
+ \clist_set:Ne \l_@@_groups_clist { \tl_to_str:n {#1} }
+ \clist_if_empty:NTF \l_@@_groups_clist
+ {
+ \@@_cs_undefine:c
+ { \c_@@_groups_root_str \l_keys_path_str }
+ }
+ {
+ \cs_set_eq:cN { \c_@@_groups_root_str \l_keys_path_str }
+ \l_@@_groups_clist
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_inherit:n}
+% Inheritance means ignoring anything already said about the key:
+% zap the lot and set up.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_inherit:n #1
+ {
+ \@@_undefine:
+ \clist_set:Nn \l_@@_inherit_clist {#1}
+ \cs_set_eq:cN { \c_@@_inherit_root_str \l_keys_path_str }
+ \l_@@_inherit_clist
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_initialise:n}
+% A set up for initialisation: just run the code if it exists.
+% We need to set the key string here, using the deprecated \texttt{tl}
+% as a piece of scratch space.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_initialise:n #1
+ {
+ \cs_if_exist:cTF
+ { \c_@@_inherit_root_str \@@_parent:o \l_keys_path_str }
+ { \@@_execute_inherit: }
+ {
+ \str_clear:N \l_@@_inherit_str
+ \cs_if_exist:cT { \c_@@_code_root_str \l_keys_path_str }
+ {
+ \exp_after:wN \@@_find_key_module:wNN
+ \l_keys_path_str \s_@@_stop
+ \l_keys_key_tl \l_keys_key_str
+ \tl_set_eq:NN \l_keys_key_tl \l_keys_key_str
+ \tl_set:Nn \l_keys_value_tl {#1}
+ \@@_execute:no \l_keys_path_str \l_keys_value_tl
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_legacy_if_set:nn, \@@_legacy_if_inverse:nn}
+% \begin{macro}{\@@_legacy_if_inverse:nnnn}
+% Much the same as \pkg{expl3} booleans, except we assume that the switch
+% exists.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_legacy_if_set:nn #1#2
+ { \@@_legacy_if_set:nnnn {#1} {#2} { true } { false } }
+\cs_new_protected:Npn \@@_legacy_if_set_inverse:nn #1#2
+ { \@@_legacy_if_set:nnnn {#1} {#2} { false } { true } }
+\cs_new_protected:Npn \@@_legacy_if_set:nnnn #1#2#3#4
+ {
+ \@@_choice_make:
+ \@@_cmd_set:ne { \l_keys_path_str / true }
+ { \exp_not:c { legacy_if_#2 set_ #3 :n } { \exp_not:n {#1} } }
+ \@@_cmd_set:ne { \l_keys_path_str / false }
+ { \exp_not:c { legacy_if_#2 set_ #4 :n } { \exp_not:n {#1} } }
+ \@@_cmd_set:nn { \l_keys_path_str / unknown }
+ {
+ \msg_error:nne { keys } { boolean-values-only }
+ \l_keys_path_str
+ }
+ \@@_default_set:n { true }
+ \cs_if_exist:cF { if#1 }
+ {
+ \cs:w newif \exp_after:wN \cs_end:
+ \cs:w if#1 \cs_end:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_meta_make:n}
+% \begin{macro}{\@@_meta_make:nn}
+% To create a meta-key, simply set up to pass data through. The internal
+% function is used here as a meta key should respect the prevailing
+% filtering, etc.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_meta_make:n #1
+ {
+ \exp_args:NVo \@@_cmd_set_direct:nn \l_keys_path_str
+ {
+ \exp_after:wN \@@_set:nn \exp_after:wN
+ { \l_@@_module_str } {#1}
+ }
+ }
+\cs_new_protected:Npn \@@_meta_make:nn #1#2
+ {
+ \exp_args:NV \@@_cmd_set_direct:nn
+ \l_keys_path_str { \@@_set:nn {#1} {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_prop_put:Nn, \@@_prop_put:cn}
+% Much the same as other variables, but needs a dedicated auxiliary.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_prop_put:Nn #1#2
+ {
+ \prop_if_exist:NF #1 { \prop_new:N #1 }
+ \exp_after:wN \@@_find_key_module:wNN \l_keys_path_str \s_@@_stop
+ \l_@@_tmpa_tl \l_@@_tmpb_tl
+ \@@_cmd_set:ne \l_keys_path_str
+ {
+ \exp_not:c { prop_ #2 put:Nnn }
+ \exp_not:N #1
+ { \l_@@_tmpb_tl }
+ \exp_not:n { {##1} }
+ }
+ }
+\cs_generate_variant:Nn \@@_prop_put:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_undefine:}
+% Undefining a key has to be done without \cs{cs_undefine:c} as that
+% function acts globally.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_undefine:
+ {
+ \clist_map_inline:nn
+ { code , default , groups , inherit , type , check }
+ {
+ \@@_cs_undefine:c
+ { \tl_use:c { c_@@_ ##1 _root_str } \l_keys_path_str }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_value_requirement:nn}
+% \begin{macro}{\@@_check_forbidden:, \@@_check_required:}
+% Validating key input is done using a second function which runs before
+% the main key code. Setting that up means setting it equal to a generic
+% stub which does the check. This approach makes the lookup very fast at
+% the cost of one additional csname per key that needs it. The cleanup here
+% has to know the structure of the following code.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_value_requirement:nn #1#2
+ {
+ \str_case:nnF {#2}
+ {
+ { true }
+ {
+ \cs_set_eq:cc
+ { \c_@@_check_root_str \l_keys_path_str }
+ { @@_check_ #1 : }
+ }
+ { false }
+ {
+ \cs_if_eq:ccT
+ { \c_@@_check_root_str \l_keys_path_str }
+ { @@_check_ #1 : }
+ {
+ \@@_cs_undefine:c
+ { \c_@@_check_root_str \l_keys_path_str }
+ }
+ }
+ }
+ {
+ \msg_error:nne { keys }
+ { boolean-values-only }
+ { .value_ #1 :n }
+ }
+ }
+\cs_new_protected:Npn \@@_check_forbidden:
+ {
+ \bool_if:NF \l_@@_no_value_bool
+ {
+ \msg_error:nnee { keys } { value-forbidden }
+ \l_keys_path_str \l_keys_value_tl
+ \use_none:nnn
+ }
+ }
+\cs_new_protected:Npn \@@_check_required:
+ {
+ \bool_if:NT \l_@@_no_value_bool
+ {
+ \msg_error:nne { keys } { value-required }
+ \l_keys_path_str
+ \use_none:nnn
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_usage:n}
+% \begin{macro}{\@@_usage:NN}
+% \begin{macro}{\@@_usage:w}
+% Save the relevant data.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_usage:n #1
+ {
+ \str_case:nnF {#1}
+ {
+ { general }
+ {
+ \@@_usage:NN \l_keys_usage_load_prop
+ \c_false_bool
+ \@@_usage:NN \l_keys_usage_preamble_prop
+ \c_false_bool
+ }
+ { load }
+ {
+ \@@_usage:NN \l_keys_usage_load_prop
+ \c_true_bool
+ \@@_usage:NN \l_keys_usage_preamble_prop
+ \c_false_bool
+ }
+ { preamble }
+ {
+ \@@_usage:NN \l_keys_usage_load_prop
+ \c_false_bool
+ \@@_usage:NN \l_keys_usage_preamble_prop
+ \c_true_bool
+ }
+ }
+ {
+ \msg_error:nnnn { keys }
+ { choice-unknown }
+ { .usage:n }
+ {#1}
+ }
+ }
+\cs_new_protected:Npn \@@_usage:NN #1#2
+ {
+ \prop_get:NVNF #1 \l_@@_module_str \l_@@_tmpa_tl
+ { \tl_clear:N \l_@@_tmpa_tl }
+ \tl_set:Ne \l_@@_tmpb_tl
+ { \exp_after:wN \@@_usage:w \l_keys_path_str \s_@@_stop }
+ \bool_if:NTF #2
+ { \clist_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl }
+ { \clist_remove_all:NV \l_@@_tmpa_tl \l_@@_tmpb_tl }
+ \prop_put:NVV #1 \l_@@_module_str
+ \l_@@_tmpa_tl
+ }
+\cs_new:Npn \@@_usage:w #1 / #2 \s_@@_stop {#2}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_variable_set:NnnN, \@@_variable_set:cnnN}
+% \begin{macro}{\@@_variable_set_required:NnnN, \@@_variable_set_required:cnnN}
+% Setting a variable takes the type and scope separately so that
+% it is easy to make a new variable if needed.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_variable_set:NnnN #1#2#3#4
+ {
+ \use:c { #2_if_exist:NF } #1 { \use:c { #2 _new:N } #1 }
+ \@@_cmd_set:ne \l_keys_path_str
+ {
+ \exp_not:c { #2 _ #3 set:N #4 }
+ \exp_not:N #1
+ \exp_not:n { {##1} }
+ }
+ }
+\cs_generate_variant:Nn \@@_variable_set:NnnN { c }
+\cs_new_protected:Npn \@@_variable_set_required:NnnN #1#2#3#4
+ {
+ \@@_variable_set:NnnN #1 {#2} {#3} #4
+ \@@_value_requirement:nn { required } { true }
+ }
+\cs_generate_variant:Nn \@@_variable_set_required:NnnN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Creating key properties}
+%
+% The key property functions are all wrappers for internal functions,
+% meaning that things stay readable and can also be altered later on.
+%
+% Importantly, while key properties have \enquote{normal} argument specs, the
+% underlying code always supplies one braced argument to these. As such, argument
+% expansion is handled by hand rather than using the standard tools. This shows
+% up particularly for the two-argument properties, where things would otherwise
+% go badly wrong.
+%
+% \begin{macro}{.bool_set:N, .bool_set:c}
+% \begin{macro}{.bool_gset:N, .bool_gset:c}
+% One function for this.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .bool_set:N } #1
+ { \@@_bool_set:Nn #1 { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .bool_set:c } #1
+ { \@@_bool_set:cn {#1} { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .bool_gset:N } #1
+ { \@@_bool_set:Nn #1 { g } }
+\cs_new_protected:cpn { \c_@@_props_root_str .bool_gset:c } #1
+ { \@@_bool_set:cn {#1} { g } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{.bool_set_inverse:N, .bool_set_inverse:c}
+% \begin{macro}{.bool_gset_inverse:N, .bool_gset_inverse:c}
+% One function for this.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .bool_set_inverse:N } #1
+ { \@@_bool_set_inverse:Nn #1 { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .bool_set_inverse:c } #1
+ { \@@_bool_set_inverse:cn {#1} { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .bool_gset_inverse:N } #1
+ { \@@_bool_set_inverse:Nn #1 { g } }
+\cs_new_protected:cpn { \c_@@_props_root_str .bool_gset_inverse:c } #1
+ { \@@_bool_set_inverse:cn {#1} { g } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{.choice:}
+% Making a choice is handled internally, as it is also needed by
+% \texttt{.generate_choices:n}.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .choice: }
+ { \@@_choice_make: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.choices:nn, .choices:Vn, .choices:en, .choices:on, .choices:xn}
+% For auto-generation of a series of mutually-exclusive choices.
+% Here, |#1| consists of two separate
+% arguments, hence the slightly odd-looking implementation.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .choices:nn } #1
+ { \@@_choices_make:nn #1 }
+\cs_new_protected:cpn { \c_@@_props_root_str .choices:Vn } #1
+ { \exp_args:NV \@@_choices_make:nn #1 }
+\cs_new_protected:cpn { \c_@@_props_root_str .choices:en } #1
+ { \exp_args:Ne \@@_choices_make:nn #1 }
+\cs_new_protected:cpn { \c_@@_props_root_str .choices:on } #1
+ { \exp_args:No \@@_choices_make:nn #1 }
+\cs_new_protected:cpn { \c_@@_props_root_str .choices:xn } #1
+ { \exp_args:Nx \@@_choices_make:nn #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.code:n}
+% Creating code is simply a case of passing through to the underlying
+% \texttt{set} function.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .code:n } #1
+ { \@@_cmd_set:nn \l_keys_path_str {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.clist_set:N, .clist_set:c}
+% \begin{macro}{.clist_gset:N, .clist_gset:c}
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .clist_set:N } #1
+ { \@@_variable_set:NnnN #1 { clist } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .clist_set:c } #1
+ { \@@_variable_set:cnnN {#1} { clist } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .clist_gset:N } #1
+ { \@@_variable_set:NnnN #1 { clist } { g } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .clist_gset:c } #1
+ { \@@_variable_set:cnnN {#1} { clist } { g } n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {.cs_set:Np, .cs_set:cp, .cs_set_protected:Np, .cs_set_protected:cp}
+% \begin{macro}
+% {.cs_gset:Np, .cs_gset:cp, .cs_gset_protected:Np, .cs_gset_protected:cp}
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .cs_set:Np } #1
+ { \@@_cs_set:NNpn \cs_set:Npn #1 { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .cs_set:cp } #1
+ { \@@_cs_set:Ncpn \cs_set:Npn #1 { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .cs_set_protected:Np } #1
+ { \@@_cs_set:NNpn \cs_set_protected:Npn #1 { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .cs_set_protected:cp } #1
+ { \@@_cs_set:Ncpn \cs_set_protected:Npn #1 { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .cs_gset:Np } #1
+ { \@@_cs_set:NNpn \cs_gset:Npn #1 { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .cs_gset:cp } #1
+ { \@@_cs_set:Ncpn \cs_gset:Npn #1 { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .cs_gset_protected:Np } #1
+ { \@@_cs_set:NNpn \cs_gset_protected:Npn #1 { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .cs_gset_protected:cp } #1
+ { \@@_cs_set:Ncpn \cs_gset_protected:Npn #1 { } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{.default:n, .default:V, .default:e, .default:o, .default:x}
+% Expansion is left to the internal functions.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .default:n } #1
+ { \@@_default_set:n {#1} }
+\cs_new_protected:cpn { \c_@@_props_root_str .default:V } #1
+ { \exp_args:NV \@@_default_set:n #1 }
+\cs_new_protected:cpn { \c_@@_props_root_str .default:e } #1
+ { \exp_args:Ne \@@_default_set:n {#1} }
+\cs_new_protected:cpn { \c_@@_props_root_str .default:o } #1
+ { \exp_args:No \@@_default_set:n {#1} }
+\cs_new_protected:cpn { \c_@@_props_root_str .default:x } #1
+ { \exp_args:Nx \@@_default_set:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.dim_set:N, .dim_set:c}
+% \begin{macro}{.dim_gset:N, .dim_gset:c}
+% Setting a variable is very easy: just pass the data along.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .dim_set:N } #1
+ { \@@_variable_set_required:NnnN #1 { dim } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .dim_set:c } #1
+ { \@@_variable_set_required:cnnN {#1} { dim } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .dim_gset:N } #1
+ { \@@_variable_set_required:NnnN #1 { dim } { g } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .dim_gset:c } #1
+ { \@@_variable_set_required:cnnN {#1} { dim } { g } n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{.fp_set:N, .fp_set:c}
+% \begin{macro}{.fp_gset:N, .fp_gset:c}
+% Setting a variable is very easy: just pass the data along.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .fp_set:N } #1
+ { \@@_variable_set_required:NnnN #1 { fp } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .fp_set:c } #1
+ { \@@_variable_set_required:cnnN {#1} { fp } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .fp_gset:N } #1
+ { \@@_variable_set_required:NnnN #1 { fp } { g } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .fp_gset:c } #1
+ { \@@_variable_set_required:cnnN {#1} { fp } { g } n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{.groups:n}
+% A single property to create groups of keys.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .groups:n } #1
+ { \@@_groups_set:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.inherit:n}
+% Nothing complex: only one variant at the moment!
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .inherit:n } #1
+ { \@@_inherit:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.initial:n, .initial:V, .initial:e, .initial:o, .initial:x}
+% The standard hand-off approach.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .initial:n } #1
+ { \@@_initialise:n {#1} }
+\cs_new_protected:cpn { \c_@@_props_root_str .initial:V } #1
+ { \exp_args:NV \@@_initialise:n #1 }
+\cs_new_protected:cpn { \c_@@_props_root_str .initial:e } #1
+ { \exp_args:Ne \@@_initialise:n {#1} }
+\cs_new_protected:cpn { \c_@@_props_root_str .initial:o } #1
+ { \exp_args:No \@@_initialise:n {#1} }
+\cs_new_protected:cpn { \c_@@_props_root_str .initial:x } #1
+ { \exp_args:Nx \@@_initialise:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.int_set:N, .int_set:c}
+% \begin{macro}{.int_gset:N, .int_gset:c}
+% Setting a variable is very easy: just pass the data along.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .int_set:N } #1
+ { \@@_variable_set_required:NnnN #1 { int } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .int_set:c } #1
+ { \@@_variable_set_required:cnnN {#1} { int } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .int_gset:N } #1
+ { \@@_variable_set_required:NnnN #1 { int } { g } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .int_gset:c } #1
+ { \@@_variable_set_required:cnnN {#1} { int } { g } n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% .legacy_if_set:n, .legacy_if_gset:n,
+% .legacy_if_set_inverse:n, .legacy_if_gset_inverse:n
+% }
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .legacy_if_set:n } #1
+ { \@@_legacy_if_set:nn {#1} { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .legacy_if_gset:n } #1
+ { \@@_legacy_if_set:nn {#1} { g } }
+\cs_new_protected:cpn { \c_@@_props_root_str .legacy_if_set_inverse:n } #1
+ { \@@_legacy_if_set_inverse:nn {#1} { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .legacy_if_gset_inverse:n } #1
+ { \@@_legacy_if_set_inverse:nn {#1} { g } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.meta:n}
+% Making a meta is handled internally.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .meta:n } #1
+ { \@@_meta_make:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.meta:nn}
+% Meta with path: potentially lots of variants, but for the moment
+% no so many defined.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .meta:nn } #1
+ { \@@_meta_make:nn #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.multichoice:}
+% \begin{macro}{.multichoices:nn, .multichoices:Vn, .multichoices:en, .multichoices:on, .multichoices:xn}
+% The same idea as \texttt{.choice:} and \texttt{.choices:nn}, but
+% where more than one choice is allowed.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .multichoice: }
+ { \@@_multichoice_make: }
+\cs_new_protected:cpn { \c_@@_props_root_str .multichoices:nn } #1
+ { \@@_multichoices_make:nn #1 }
+\cs_new_protected:cpn { \c_@@_props_root_str .multichoices:Vn } #1
+ { \exp_args:NV \@@_multichoices_make:nn #1 }
+\cs_new_protected:cpn { \c_@@_props_root_str .multichoices:en } #1
+ { \exp_args:Ne \@@_multichoices_make:nn #1 }
+\cs_new_protected:cpn { \c_@@_props_root_str .multichoices:on } #1
+ { \exp_args:No \@@_multichoices_make:nn #1 }
+\cs_new_protected:cpn { \c_@@_props_root_str .multichoices:xn } #1
+ { \exp_args:Nx \@@_multichoices_make:nn #1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{.muskip_set:N, .muskip_set:c, .muskip_gset:N, .muskip_gset:c}
+% Setting a variable is very easy: just pass the data along.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .muskip_set:N } #1
+ { \@@_variable_set_required:NnnN #1 { muskip } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .muskip_set:c } #1
+ { \@@_variable_set_required:cnnN {#1} { muskip } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .muskip_gset:N } #1
+ { \@@_variable_set_required:NnnN #1 { muskip } { g } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .muskip_gset:c } #1
+ { \@@_variable_set_required:cnnN {#1} { muskip } { g } n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.prop_put:N, .prop_put:c, .prop_gput:N, .prop_gput:c}
+% Setting a variable is very easy: just pass the data along.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .prop_put:N } #1
+ { \@@_prop_put:Nn #1 { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .prop_put:c } #1
+ { \@@_prop_put:cn {#1} { } }
+\cs_new_protected:cpn { \c_@@_props_root_str .prop_gput:N } #1
+ { \@@_prop_put:Nn #1 { g } }
+\cs_new_protected:cpn { \c_@@_props_root_str .prop_gput:c } #1
+ { \@@_prop_put:cn {#1} { g } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.skip_set:N, .skip_set:c}
+% \begin{macro}{.skip_gset:N, .skip_gset:c}
+% Setting a variable is very easy: just pass the data along.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .skip_set:N } #1
+ { \@@_variable_set_required:NnnN #1 { skip } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .skip_set:c } #1
+ { \@@_variable_set_required:cnnN {#1} { skip } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .skip_gset:N } #1
+ { \@@_variable_set_required:NnnN #1 { skip } { g } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .skip_gset:c } #1
+ { \@@_variable_set_required:cnnN {#1} { skip } { g } n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{.str_set:N, .str_set:c}
+% \begin{macro}{.str_gset:N, .str_gset:c}
+% \begin{macro}{.str_set_e:N, .str_set_e:c}
+% \begin{macro}{.str_gset_e:N, .str_gset_e:c}
+% Setting a variable is very easy: just pass the data along.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .str_set:N } #1
+ { \@@_variable_set:NnnN #1 { str } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .str_set:c } #1
+ { \@@_variable_set:cnnN {#1} { str } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .str_set_e:N } #1
+ { \@@_variable_set:NnnN #1 { str } { } e }
+\cs_new_protected:cpn { \c_@@_props_root_str .str_set_e:c } #1
+ { \@@_variable_set:cnnN {#1} { str } { } e }
+\cs_new_protected:cpn { \c_@@_props_root_str .str_gset:N } #1
+ { \@@_variable_set:NnnN #1 { str } { g } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .str_gset:c } #1
+ { \@@_variable_set:cnnN {#1} { str } { g } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .str_gset_e:N } #1
+ { \@@_variable_set:NnnN #1 { str } { g } e }
+\cs_new_protected:cpn { \c_@@_props_root_str .str_gset_e:c } #1
+ { \@@_variable_set:cnnN {#1} { str } { g } e }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{.tl_set:N, .tl_set:c}
+% \begin{macro}{.tl_gset:N, .tl_gset:c}
+% \begin{macro}{.tl_set_e:N, .tl_set_e:c}
+% \begin{macro}{.tl_gset_e:N, .tl_gset_e:c}
+% Setting a variable is very easy: just pass the data along.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .tl_set:N } #1
+ { \@@_variable_set:NnnN #1 { tl } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .tl_set:c } #1
+ { \@@_variable_set:cnnN {#1} { tl } { } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .tl_set_e:N } #1
+ { \@@_variable_set:NnnN #1 { tl } { } e }
+\cs_new_protected:cpn { \c_@@_props_root_str .tl_set_e:c } #1
+ { \@@_variable_set:cnnN {#1} { tl } { } e }
+\cs_new_protected:cpn { \c_@@_props_root_str .tl_gset:N } #1
+ { \@@_variable_set:NnnN #1 { tl } { g } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .tl_gset:c } #1
+ { \@@_variable_set:cnnN {#1} { tl } { g } n }
+\cs_new_protected:cpn { \c_@@_props_root_str .tl_gset_e:N } #1
+ { \@@_variable_set:NnnN #1 { tl } { g } e }
+\cs_new_protected:cpn { \c_@@_props_root_str .tl_gset_e:c } #1
+ { \@@_variable_set:cnnN {#1} { tl } { g } e }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{.undefine:}
+% Another simple wrapper.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .undefine: }
+ { \@@_undefine: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.usage:n}
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .usage:n } #1
+ { \@@_usage:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.value_forbidden:n}
+% \begin{macro}{.value_required:n}
+% These are very similar, so both call the same function.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .value_forbidden:n } #1
+ { \@@_value_requirement:nn { forbidden } {#1} }
+\cs_new_protected:cpn { \c_@@_props_root_str .value_required:n } #1
+ { \@@_value_requirement:nn { required } {#1} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Setting keys}
+%
+% \begin{macro}
+% {
+% \keys_set:nn, \keys_set:nV, \keys_set:nv, \keys_set:ne,
+% \keys_set:no, \keys_set:nx,
+% \@@_set:nn
+% }
+% \begin{macro}{\@@_set:nnn}
+% A simple wrapper allowing for nesting.
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_set:nn #1#2
+ {
+ \use:e
+ {
+ \bool_set_false:N \exp_not:N \l_@@_only_known_bool
+ \bool_set_false:N \exp_not:N \l_@@_filtered_bool
+ \bool_set_false:N \exp_not:N \l_@@_selective_bool
+ \tl_set:Nn \exp_not:N \l_@@_relative_tl
+ { \exp_not:N \q_@@_no_value }
+ \@@_set:nn \exp_not:n { {#1} {#2} }
+ \bool_if:NT \l_@@_only_known_bool
+ { \bool_set_true:N \exp_not:N \l_@@_only_known_bool }
+ \bool_if:NT \l_@@_filtered_bool
+ { \bool_set_true:N \exp_not:N \l_@@_filtered_bool }
+ \bool_if:NT \l_@@_selective_bool
+ { \bool_set_true:N \exp_not:N \l_@@_selective_bool }
+ \tl_set:Nn \exp_not:N \l_@@_relative_tl
+ { \exp_not:o \l_@@_relative_tl }
+ }
+ }
+\cs_generate_variant:Nn \keys_set:nn { nV , nv , ne , no , nx }
+\cs_new_protected:Npn \@@_set:nn #1#2
+ { \exp_args:No \@@_set:nnn \l_@@_module_str {#1} {#2} }
+\cs_new_protected:Npn \@@_set:nnn #1#2#3
+ {
+ \str_set:Ne \l_@@_module_str { \@@_trim_spaces:n {#2} }
+ \keyval_parse:NNn \@@_set_keyval:n \@@_set_keyval:nn {#3}
+ \str_set:Nn \l_@@_module_str {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \keys_set_known:nnN, \keys_set_known:nVN,
+% \keys_set_known:nvN, \keys_set_known:neN,
+% \keys_set_known:noN
+% }
+% \begin{macro}
+% {
+% \keys_set_known:nnnN, \keys_set_known:nVnN,
+% \keys_set_known:nvnN, \keys_set_known:nenN,
+% \keys_set_known:nonN
+% }
+% \begin{macro}{\@@_set_known:nnnnN}
+% \begin{macro}
+% {
+% \keys_set_known:nn, \keys_set_known:nV,
+% \keys_set_known:nv, \keys_set_known:ne,
+% \keys_set_known:no
+% }
+% \begin{macro}{\@@_set_known:nnn}
+% Setting known keys simply means setting the appropriate boolean, then
+% running the standard code. To allow for nested setting, any existing
+% value of \cs{l_@@_unused_clist} is saved on the stack and reset
+% afterwards. Note that for speed/simplicity reasons we use a \texttt{tl}
+% operation to set the \texttt{clist} here!
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_set_known:nnN #1#2#3
+ {
+ \exp_args:No \@@_set_known:nnnnN
+ \l_@@_unused_clist \q_@@_no_value {#1} {#2} #3
+ }
+\cs_generate_variant:Nn \keys_set_known:nnN { nV , nv , ne , no }
+\cs_new_protected:Npn \keys_set_known:nnnN #1#2#3#4
+ {
+ \exp_args:No \@@_set_known:nnnnN
+ \l_@@_unused_clist {#3} {#1} {#2} #4
+ }
+\cs_generate_variant:Nn \keys_set_known:nnnN { nV , nv , ne , no }
+\cs_new_protected:Npn \@@_set_known:nnnnN #1#2#3#4#5
+ {
+ \clist_clear:N \l_@@_unused_clist
+ \@@_set_known:nnn {#2} {#3} {#4}
+ \__kernel_tl_set:Nx #5 { \exp_not:o \l_@@_unused_clist }
+ \__kernel_tl_set:Nx \l_@@_unused_clist { \exp_not:n {#1} }
+ }
+\cs_new_protected:Npn \keys_set_known:nn #1#2
+ { \@@_set_known:nnn \q_@@_no_value {#1} {#2} }
+\cs_generate_variant:Nn \keys_set_known:nn { nV , nv , ne , no }
+\cs_new_protected:Npn \@@_set_known:nnn #1#2#3
+ {
+ \use:e
+ {
+ \bool_set_true:N \exp_not:N \l_@@_only_known_bool
+ \bool_set_false:N \exp_not:N \l_@@_filtered_bool
+ \bool_set_false:N \exp_not:N \l_@@_selective_bool
+ \tl_set:Nn \exp_not:N \l_@@_relative_tl { \exp_not:n {#1} }
+ \@@_set:nn \exp_not:n { {#2} {#3} }
+ \bool_if:NF \l_@@_only_known_bool
+ { \bool_set_false:N \exp_not:N \l_@@_only_known_bool }
+ \bool_if:NT \l_@@_filtered_bool
+ { \bool_set_true:N \exp_not:N \l_@@_filtered_bool }
+ \bool_if:NT \l_@@_selective_bool
+ { \bool_set_true:N \exp_not:N \l_@@_selective_bool }
+ \tl_set:Nn \exp_not:N \l_@@_relative_tl
+ { \exp_not:o \l_@@_relative_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \keys_set_exclude_groups:nnnN, \keys_set_exclude_groups:nnVN,
+% \keys_set_exclude_groups:nnvN, \keys_set_exclude_groups:nnoN
+% }
+% \begin{macro}
+% {
+% \keys_set_exclude_groups:nnnnN, \keys_set_exclude_groups:nnVnN,
+% \keys_set_exclude_groups:nnvnN, \keys_set_exclude_groups:nnonN
+% }
+% \begin{macro}{\@@_set_exclude_groups:nnnnnN}
+% \begin{macro}
+% {
+% \keys_set_exclude_groups:nnn, \keys_set_exclude_groups:nnV,
+% \keys_set_exclude_groups:nnv, \keys_set_exclude_groups:nno
+% }
+% \begin{macro}{\@@_set_exclude_groups:nnnn}
+% \begin{macro}
+% {
+% \keys_set_groups:nnn, \keys_set_groups:nnV, \keys_set_groups:nnv,
+% \keys_set_groups:nno
+% }
+% \begin{macro}{\@@_set_selective:nnn}
+% \begin{macro}{\@@_set_selective:nnnn}
+% The idea of setting keys in a selective manner again uses booleans
+% wrapped around the basic code. The comments on \cs{keys_set_known:nnN}
+% also apply here. We have a bit more shuffling to do to keep everything
+% nestable.
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_set_exclude_groups:nnnN #1#2#3#4
+ {
+ \exp_args:No \@@_set_exclude_groups:nnnnnN
+ \l_@@_unused_clist
+ \q_@@_no_value {#1} {#2} {#3} #4
+ }
+\cs_generate_variant:Nn \keys_set_exclude_groups:nnnN { nnV , nnv , nno }
+\cs_new_protected:Npn \keys_set_exclude_groups:nnnnN #1#2#3#4#5
+ {
+ \exp_args:No \@@_set_exclude_groups:nnnnnN
+ \l_@@_unused_clist {#4} {#1} {#2} {#3} #5
+ }
+\cs_generate_variant:Nn \keys_set_exclude_groups:nnnnN { nnV , nnv , nno }
+\cs_new_protected:Npn \@@_set_exclude_groups:nnnnnN #1#2#3#4#5#6
+ {
+ \clist_clear:N \l_@@_unused_clist
+ \@@_set_exclude_groups:nnnn {#2} {#3} {#4} {#5}
+ \__kernel_tl_set:Nx #6 { \exp_not:o \l_@@_unused_clist }
+ \__kernel_tl_set:Nx \l_@@_unused_clist { \exp_not:n {#1} }
+ }
+\cs_new_protected:Npn \keys_set_exclude_groups:nnn #1#2#3
+ {\@@_set_exclude_groups:nnnn \q_@@_no_value {#1} {#2} {#3} }
+\cs_generate_variant:Nn \keys_set_exclude_groups:nnn { nnV , nnv , nno }
+\cs_new_protected:Npn \@@_set_exclude_groups:nnnn #1#2#3#4
+ {
+ \use:e
+ {
+ \bool_set_false:N \exp_not:N \l_@@_only_known_bool
+ \bool_set_true:N \exp_not:N \l_@@_filtered_bool
+ \bool_set_true:N \exp_not:N \l_@@_selective_bool
+ \tl_set:Nn \exp_not:N \l_@@_relative_tl { \exp_not:n {#1} }
+ \@@_set_selective:nnn \exp_not:n { {#2} {#3} {#4} }
+ \bool_if:NT \l_@@_only_known_bool
+ { \bool_set_true:N \exp_not:N \l_@@_only_known_bool }
+ \bool_if:NF \l_@@_filtered_bool
+ { \bool_set_false:N \exp_not:N \l_@@_filtered_bool }
+ \bool_if:NF \l_@@_selective_bool
+ { \bool_set_false:N \exp_not:N \l_@@_selective_bool }
+ \tl_set:Nn \exp_not:N \l_@@_relative_tl
+ { \exp_not:o \l_@@_relative_tl }
+ }
+ }
+\cs_new_protected:Npn \keys_set_groups:nnn #1#2#3
+ {
+ \use:e
+ {
+ \bool_set_false:N \exp_not:N \l_@@_only_known_bool
+ \bool_set_false:N \exp_not:N \l_@@_filtered_bool
+ \bool_set_true:N \exp_not:N \l_@@_selective_bool
+ \tl_set:Nn \exp_not:N \l_@@_relative_tl
+ { \exp_not:N \q_@@_no_value }
+ \@@_set_selective:nnn \exp_not:n { {#1} {#2} {#3} }
+ \bool_if:NT \l_@@_only_known_bool
+ { \bool_set_true:N \exp_not:N \l_@@_only_known_bool }
+ \bool_if:NF \l_@@_filtered_bool
+ { \bool_set_true:N \exp_not:N \l_@@_filtered_bool }
+ \bool_if:NF \l_@@_selective_bool
+ { \bool_set_false:N \exp_not:N \l_@@_selective_bool }
+ \tl_set:Nn \exp_not:N \l_@@_relative_tl
+ { \exp_not:o \l_@@_relative_tl }
+ }
+ }
+\cs_generate_variant:Nn \keys_set_groups:nnn { nnV , nnv , nno }
+\cs_new_protected:Npn \@@_set_selective:nnn
+ { \exp_args:No \@@_set_selective:nnnn \l_@@_selective_seq }
+\cs_new_protected:Npn \@@_set_selective:nnnn #1#2#3#4
+ {
+ \exp_args:NNe \seq_set_from_clist:Nn
+ \l_@@_selective_seq { \tl_to_str:n {#3} }
+ \@@_set:nn {#2} {#4}
+ \tl_set:Nn \l_@@_selective_seq {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\keys_precompile:nnN}
+% A simple wrapper.
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_precompile:nnN #1#2#3
+ {
+ \bool_set_true:N \l_@@_precompile_bool
+ \tl_clear:N \l_@@_precompile_tl
+ \keys_set:nn {#1} {#2}
+ \bool_set_false:N \l_@@_precompile_bool
+ \tl_set_eq:NN #3 \l_@@_precompile_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_set_keyval:n, \@@_set_keyval:nn}
+% \begin{macro}{\@@_set_keyval:nnn, \@@_set_keyval:onn}
+% \begin{macro}{\@@_find_key_module:wNN}
+% \begin{macro}
+% {
+% \@@_find_key_module_auxi:Nw ,
+% \@@_find_key_module_auxii:Nw ,
+% \@@_find_key_module_auxiii:Nn ,
+% \@@_find_key_module_auxiv:Nw
+% }
+% \begin{macro}{\@@_set_selective:}
+% A shared system once again. First, set the current path and add a
+% default if needed. There are then checks to see if a value is
+% required or forbidden. If everything passes, move on to execute the
+% code.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_keyval:n #1
+ {
+ \bool_set_true:N \l_@@_no_value_bool
+ \@@_set_keyval:onn \l_@@_module_str {#1} { }
+ }
+\cs_new_protected:Npn \@@_set_keyval:nn #1#2
+ {
+ \bool_set_false:N \l_@@_no_value_bool
+ \@@_set_keyval:onn \l_@@_module_str {#1} {#2}
+ }
+% \end{macrocode}
+% The key path here can be fully defined, after which there is a search
+% for the key and module names: the user may have passed them with part
+% of what is actually the module (for our purposes) in the key name. As
+% that happens on a per-key basis, we use the stack approach to restore
+% the module name without a group.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_keyval:nnn #1#2#3
+ {
+ \__kernel_tl_set:Nx \l_keys_path_str
+ {
+ \tl_if_blank:nF {#1}
+ { #1 / }
+ \@@_trim_spaces:n {#2}
+ }
+ \str_clear:N \l_@@_module_str
+ \str_clear:N \l_@@_inherit_str
+ \exp_after:wN \@@_find_key_module:wNN \l_keys_path_str \s_@@_stop
+ \l_@@_module_str \l_keys_key_str
+ \tl_set_eq:NN \l_keys_key_tl \l_keys_key_str
+ \@@_value_or_default:n {#3}
+ \bool_if:NTF \l_@@_selective_bool
+ \@@_set_selective:
+ \@@_execute:
+ \str_set:Nn \l_@@_module_str {#1}
+ }
+\cs_generate_variant:Nn \@@_set_keyval:nnn { o }
+% \end{macrocode}
+% This function uses \cs{cs_set_nopar:Npe} internally for performance reasons,
+% the argument |#1| is already a string in every usage, so turning it into a
+% string again seems unnecessary.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_find_key_module:wNN #1 \s_@@_stop #2 #3
+ {
+ \@@_find_key_module_auxi:Nw #2 #1 \s_@@_nil \@@_find_key_module_auxii:Nw
+ / \s_@@_nil \@@_find_key_module_auxiv:Nw #3
+ }
+\cs_new_protected:Npn \@@_find_key_module_auxi:Nw #1 #2 / #3 \s_@@_nil #4
+ {
+ #4 #1 #2 \s_@@_mark #3 \s_@@_nil #4
+ }
+\cs_new_protected:Npn \@@_find_key_module_auxii:Nw
+ #1 #2 \s_@@_mark #3 \s_@@_nil \@@_find_key_module_auxii:Nw
+ {
+ \cs_set_nopar:Npe #1 { \tl_if_empty:NF #1 { #1 / } #2 }
+ \@@_find_key_module_auxi:Nw #1 #3 \s_@@_nil \@@_find_key_module_auxiii:Nw
+ }
+\cs_new_protected:Npn \@@_find_key_module_auxiii:Nw #1 #2 \s_@@_mark
+ {
+ \cs_set_nopar:Npe #1 { \tl_if_empty:NF #1 { #1 / } #2 }
+ \@@_find_key_module_auxi:Nw #1
+ }
+\cs_new_protected:Npn \@@_find_key_module_auxiv:Nw
+ #1 #2 \s_@@_nil #3 \s_@@_mark
+ \s_@@_nil \@@_find_key_module_auxiv:Nw #4
+ {
+ \cs_set_nopar:Npn #4 { #2 }
+ }
+% \end{macrocode}
+% If selective setting is active, there are a number of possible sub-cases
+% to consider. The key name may not be known at all or if it is, it may not
+% have any groups assigned. There is then the question of whether the
+% selection is opt-in or opt-out.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_selective:
+ {
+ \cs_if_exist:cTF { \c_@@_groups_root_str \l_keys_path_str }
+ {
+ \clist_set_eq:Nc \l_@@_groups_clist
+ { \c_@@_groups_root_str \l_keys_path_str }
+ \@@_check_groups:
+ }
+ {
+ \bool_if:NTF \l_@@_filtered_bool
+ \@@_execute:
+ \@@_store_unused:
+ }
+ }
+% \end{macrocode}
+% In the case where selective setting requires a comparison of the list
+% of groups which apply to a key with the list of those which have been
+% set active. That requires two mappings, and again a different outcome
+% depending on whether opt-in or opt-out is set.
+% It is safe to use \cs{clist_if_in:NnTF} because
+% both \cs{l_@@_selective_seq} and \cs{l_@@_groups_clist} contain the
+% groups as strings, without leading/trailing spaces in any item,
+% since the \pkg{l3clist} functions were applied to the result of
+% applying \cs{tl_to_str:n}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_check_groups:
+ {
+ \bool_set_false:N \l_@@_tmp_bool
+ \seq_map_inline:Nn \l_@@_selective_seq
+ {
+ \clist_if_in:NnT \l_@@_groups_clist {##1}
+ {
+ \bool_set_true:N \l_@@_tmp_bool
+ \seq_map_break:
+ }
+ }
+ \bool_if:NTF \l_@@_tmp_bool
+ {
+ \bool_if:NTF \l_@@_filtered_bool
+ \@@_store_unused:
+ \@@_execute:
+ }
+ {
+ \bool_if:NTF \l_@@_filtered_bool
+ \@@_execute:
+ \@@_store_unused:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_value_or_default:n}
+% \begin{macro}{\@@_default_inherit:}
+% If a value is given, return it as |#1|, otherwise send a default if
+% available.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_value_or_default:n #1
+ {
+ \bool_if:NTF \l_@@_no_value_bool
+ {
+ \cs_if_exist:cTF { \c_@@_default_root_str \l_keys_path_str }
+ {
+ \tl_set_eq:Nc
+ \l_keys_value_tl
+ { \c_@@_default_root_str \l_keys_path_str }
+ }
+ {
+ \tl_clear:N \l_keys_value_tl
+ \cs_if_exist:cT
+ { \c_@@_inherit_root_str \@@_parent:o \l_keys_path_str }
+ { \@@_default_inherit: }
+ }
+ }
+ { \tl_set:Nn \l_keys_value_tl {#1} }
+ }
+\cs_new_protected:Npn \@@_default_inherit:
+ {
+ \clist_map_inline:cn
+ { \c_@@_inherit_root_str \@@_parent:o \l_keys_path_str }
+ {
+ \cs_if_exist:cT
+ { \c_@@_default_root_str ##1 / \l_keys_key_str }
+ {
+ \tl_set_eq:Nc
+ \l_keys_value_tl
+ { \c_@@_default_root_str ##1 / \l_keys_key_str }
+ \clist_map_break:
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_execute:, \@@_execute_inherit:, \@@_execute_unknown:}
+% \begin{macro}[EXP]{\@@_execute:nn, \@@_execute:no}
+% \begin{macro}{\@@_store_unused:,\@@_store_unused_aux:}
+% Actually executing a key is done in two parts. First, look for the
+% key itself, then look for the \texttt{unknown} key with the same
+% path. If both of these fail, complain. What exactly happens if a key
+% is unknown depends on whether unknown keys are being skipped or if
+% an error should be raised.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_execute:
+ {
+ \cs_if_exist:cTF { \c_@@_code_root_str \l_keys_path_str }
+ {
+ \cs_if_exist_use:c { \c_@@_check_root_str \l_keys_path_str }
+ \@@_execute:no \l_keys_path_str \l_keys_value_tl
+ }
+ {
+ \cs_if_exist:cTF
+ { \c_@@_inherit_root_str \@@_parent:o \l_keys_path_str }
+ { \@@_execute_inherit: }
+ { \@@_execute_unknown: }
+ }
+ }
+% \end{macrocode}
+% To deal with the case where there is no hit, we leave
+% \cs{@@_execute_unknown:} in the input stream and clean it up using the
+% break function: that avoids needing a boolean.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_execute_inherit:
+ {
+ \clist_map_inline:cn
+ { \c_@@_inherit_root_str \@@_parent:o \l_keys_path_str }
+ {
+ \cs_if_exist:cT
+ { \c_@@_code_root_str ##1 / \l_keys_key_str }
+ {
+ \str_set:Nn \l_@@_inherit_str {##1}
+ \cs_if_exist_use:c { \c_@@_check_root_str ##1 / \l_keys_key_str }
+ \@@_execute:no { ##1 / \l_keys_key_str } \l_keys_value_tl
+ \clist_map_break:n \use_none:n
+ }
+ }
+ \@@_execute_unknown:
+ }
+\cs_new_protected:Npn \@@_execute_unknown:
+ {
+ \bool_if:NTF \l_@@_only_known_bool
+ { \@@_store_unused: }
+ {
+ \cs_if_exist:cTF
+ { \c_@@_code_root_str \l_@@_module_str / unknown }
+ {
+ \bool_if:NT \l_@@_no_value_bool
+ {
+ \cs_if_exist:cT
+ { \c_@@_default_root_str \l_@@_module_str / unknown }
+ {
+ \tl_set_eq:Nc
+ \l_keys_value_tl
+ { \c_@@_default_root_str \l_@@_module_str / unknown }
+ }
+ }
+ \@@_execute:no { \l_@@_module_str / unknown } \l_keys_value_tl
+ }
+ {
+ \msg_error:nnee { keys } { unknown }
+ \l_keys_path_str \l_@@_module_str
+ }
+ }
+ }
+% \end{macrocode}
+% A key's code is in the control sequence with csname
+% \cs{c_@@_code_root_str} |#1|. We expand it once to get the
+% replacement text (with argument |#2|) and call \cs{use:n}
+% with this replacement as its argument. This ensures that any
+% undefined control sequence error in the key's code will lead to an
+% error message of the form |<argument>|\ldots{}\meta{control
+% sequence} in which one can read the (undefined) \meta{control
+% sequence} in full, rather than an error message that starts with the
+% potentially very long key name, which would make the (undefined)
+% \meta{control sequence} be truncated or sometimes completely hidden.
+% See \url{https://github.com/latex3/latex2e/issues/351}.
+% \begin{macrocode}
+\cs_new:Npn \@@_execute:nn #1#2
+ { \@@_execute:no {#1} { \prg_do_nothing: #2 } }
+\cs_new:Npn \@@_execute:no #1#2
+ {
+ \exp_args:NNo \exp_args:No \use:n
+ {
+ \cs:w \c_@@_code_root_str #1 \exp_after:wN \cs_end:
+ \exp_after:wN {#2}
+ }
+ }
+% \end{macrocode}
+% When there is no relative path, things here are easy: just save the key
+% name and value. When we are working with a relative path, first we
+% need to turn it into a string: that can't happen earlier as we need
+% to store \cs{q_@@_no_value}. Then, use a standard delimited approach to fish
+% out the partial path.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_store_unused:
+ {
+ \@@_quark_if_no_value:NTF \l_@@_relative_tl
+ {
+ \clist_put_right:Ne \l_@@_unused_clist
+ {
+ \l_keys_key_str
+ \bool_if:NF \l_@@_no_value_bool
+ { = { \exp_not:o \l_keys_value_tl } }
+ }
+ }
+ {
+ \tl_if_empty:NTF \l_@@_relative_tl
+ {
+ \clist_put_right:Ne \l_@@_unused_clist
+ {
+ \l_keys_path_str
+ \bool_if:NF \l_@@_no_value_bool
+ { = { \exp_not:o \l_keys_value_tl } }
+ }
+ }
+ { \@@_store_unused_aux: }
+ }
+ }
+\cs_new_protected:Npn \@@_store_unused_aux:
+ {
+ \__kernel_tl_set:Nx \l_@@_relative_tl
+ { \exp_args:No \@@_trim_spaces:n \l_@@_relative_tl }
+ \use:e
+ {
+ \cs_set_protected:Npn \@@_store_unused:w
+ ##1 \l_@@_relative_tl /
+ ##2 \l_@@_relative_tl /
+ ##3 \s_@@_stop
+ }
+ {
+ \tl_if_blank:nF {##1}
+ {
+ \msg_error:nnee { keys } { bad-relative-key-path }
+ \l_keys_path_str
+ \l_@@_relative_tl
+ }
+ \clist_put_right:Ne \l_@@_unused_clist
+ {
+ \exp_not:n {##2}
+ \bool_if:NF \l_@@_no_value_bool
+ { = { \exp_not:o \l_keys_value_tl } }
+ }
+ }
+ \use:e
+ {
+ \@@_store_unused:w \l_keys_path_str
+ \l_@@_relative_tl / \l_@@_relative_tl /
+ \s_@@_stop
+ }
+ }
+\cs_new_protected:Npn \@@_store_unused:w { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_choice_find:n}
+% \begin{macro}[EXP]{\@@_choice_find:nn}
+% \begin{macro}[EXP]{\@@_multichoice_find:n}
+% Executing a choice has two parts. First, try the choice given, then
+% if that fails call the unknown key. That always exists, as it is created
+% when a choice is first made. So there is no need for any escape code.
+% For multiple choices, the same code ends up used in a mapping.
+% \begin{macrocode}
+\cs_new:Npn \@@_choice_find:n #1
+ {
+ \str_if_empty:NTF \l_@@_inherit_str
+ { \@@_choice_find:nn \l_keys_path_str {#1} }
+ {
+ \@@_choice_find:nn
+ { \l_@@_inherit_str / \l_keys_key_str } {#1}
+ }
+ }
+\cs_new:Npn \@@_choice_find:nn #1#2
+ {
+ \cs_if_exist:cTF { \c_@@_code_root_str #1 / \@@_trim_spaces:n {#2} }
+ { \@@_execute:nn { #1 / \@@_trim_spaces:n {#2} } {#2} }
+ { \@@_execute:nn { #1 / unknown } {#2} }
+ }
+\cs_new:Npn \@@_multichoice_find:n #1
+ { \clist_map_function:nN {#1} \@@_choice_find:n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Utilities}
+%
+% \begin{macro}[EXP]{\@@_parent:o}
+% \begin{macro}[EXP]
+% {
+% \@@_parent_auxi:w ,
+% \@@_parent_auxii:w ,
+% \@@_parent_auxiii:n ,
+% \@@_parent_auxiv:w
+% }
+% Used to strip off the ending part of the key path after the last~|/|.
+% \begin{macrocode}
+\cs_new:Npn \@@_parent:o #1
+ {
+ \exp_after:wN \@@_parent_auxi:w #1 \q_nil \@@_parent_auxii:w
+ / \q_nil \@@_parent_auxiv:w
+ }
+\cs_new:Npn \@@_parent_auxi:w #1 / #2 \q_nil #3
+ {
+ #3 { #1 } #2 \q_nil #3
+ }
+\cs_new:Npn \@@_parent_auxii:w #1 #2 \q_nil \@@_parent_auxii:w
+ {
+ #1 \@@_parent_auxi:w #2 \q_nil \@@_parent_auxiii:n
+ }
+\cs_new:Npn \@@_parent_auxiii:n #1
+ {
+ / #1 \@@_parent_auxi:w
+ }
+\cs_new:Npn \@@_parent_auxiv:w #1 \q_nil \@@_parent_auxiv:w
+ {
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_trim_spaces:n}
+% \begin{macro}[EXP]
+% {
+% \@@_trim_spaces_auxi:w ,
+% \@@_trim_spaces_auxii:w ,
+% \@@_trim_spaces_auxiii:w
+% }
+% Space stripping has to allow for the fact that the key here might have
+% several parts, and spaces need to be stripped from each part. Since the key
+% name is turned into a string groups can't be stripped accidentally and the
+% precautions of \cs{tl_trim_spaces:n} aren't necessary, in this case it is
+% much faster to just directly strip spaces around |/|.
+% \begin{macrocode}
+\group_begin:
+ \cs_set:Npn \@@_tmp:w #1
+ {
+ \cs_new:Npn \@@_trim_spaces:n ##1
+ {
+ \exp_after:wN \@@_trim_spaces_auxi:w \tl_to_str:n { / ##1 } /
+ \s_@@_nil \@@_trim_spaces_auxi:w
+ \s_@@_mark \@@_trim_spaces_auxii:w
+ #1 / #1
+ \s_@@_nil \@@_trim_spaces_auxii:w
+ \s_@@_mark \@@_trim_spaces_auxiii:w
+ }
+ }
+ \@@_tmp:w { ~ }
+\group_end:
+\cs_new:Npn \@@_trim_spaces_auxi:w #1 ~ / #2 \s_@@_nil #3
+ {
+ #3 #1 / #2 \s_@@_nil #3
+ }
+\cs_new:Npn \@@_trim_spaces_auxii:w #1 / ~ #2 \s_@@_mark #3
+ {
+ #3 #1 / #2 \s_@@_mark #3
+ }
+\cs_new:Npn \@@_trim_spaces_auxiii:w
+ / #1 /
+ \s_@@_nil \@@_trim_spaces_auxi:w
+ \s_@@_mark \@@_trim_spaces_auxii:w
+ /
+ \s_@@_nil \@@_trim_spaces_auxii:w
+ \s_@@_mark \@@_trim_spaces_auxiii:w
+ {
+ #1
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\keys_if_exist:nn}
+% A utility for others to see if a key exists.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \keys_if_exist:nn #1#2 { p , T , F , TF }
+ {
+ \cs_if_exist:cTF
+ { \c_@@_code_root_str \@@_trim_spaces:n { #1 / #2 } }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn \keys_if_exist:nn { ne } { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\keys_if_choice_exist:nnn}
+% Just an alternative view on \cs{keys_if_exist:nnTF}.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \keys_if_choice_exist:nnn #1#2#3
+ { p , T , F , TF }
+ {
+ \cs_if_exist:cTF
+ { \c_@@_code_root_str \@@_trim_spaces:n { #1 / #2 / #3 } }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\keys_show:nn, \keys_log:nn}
+% \begin{macro}{\@@_show:Nnn}
+% \begin{macro}{\@@_show:n}
+% \begin{macro}{\@@_show:w}
+% \begin{macro}{\@@_show:Nw}
+% To show a key, show its code using a message.
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_show:nn
+ { \@@_show:Nnn \msg_show:nneeee }
+\cs_new_protected:Npn \keys_log:nn
+ { \@@_show:Nnn \msg_log:nneeee }
+\cs_new_protected:Npn \@@_show:Nnn #1#2#3
+ {
+ #1 { keys } { show-key }
+ { \@@_trim_spaces:n { #2 / #3 } }
+ {
+ \keys_if_exist:nnT {#2} {#3}
+ {
+ \exp_args:Nnf \msg_show_item_unbraced:nn { code }
+ {
+ \exp_args:Ne \@@_show:n
+ {
+ \exp_args:Nc \cs_replacement_spec:N
+ {
+ \c_@@_code_root_str
+ \@@_trim_spaces:n { #2 / #3 }
+ }
+ }
+ }
+ }
+ }
+ { } { }
+ }
+\cs_new:Npe \@@_show:n #1
+ {
+ \exp_not:N \@@_show:w
+ #1
+ \tl_to_str:n { \@@_precompile:n }
+ #1
+ \tl_to_str:n { \@@_precompile:n }
+ \exp_not:N \s_@@_stop
+ }
+\use:e
+ {
+ \cs_new:Npn \exp_not:N \@@_show:w
+ #1 \tl_to_str:n { \@@_precompile:n }
+ #2 \tl_to_str:n { \@@_precompile:n }
+ #3 \exp_not:N \s_@@_stop
+ }
+ {
+ \tl_if_blank:nTF {#2}
+ {#1}
+ { \@@_show:Nw #2 \s_@@_stop }
+ }
+\use:e
+ {
+ \cs_new:Npn \exp_not:N \@@_show:Nw #1#2
+ \c_right_brace_str \exp_not:N \s_@@_stop
+ }
+ {#2}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% For when there is a need to complain.
+% \begin{macrocode}
+\msg_new:nnnn { keys } { bad-relative-key-path }
+ { The~key~'#1'~is~not~inside~the~'#2'~path. }
+ { The~key~'#1'~cannot~be~expressed~relative~to~path~'#2'. }
+\msg_new:nnnn { keys } { boolean-values-only }
+ { Key~'#1'~accepts~boolean~values~only. }
+ { The~key~'#1'~only~accepts~the~values~'true'~and~'false'. }
+\msg_new:nnnn { keys } { choice-unknown }
+ { Key~'#1'~accepts~only~a~fixed~set~of~choices. }
+ {
+ The~key~'#1'~only~accepts~predefined~values,~
+ and~'#2'~is~not~one~of~these.
+ }
+\msg_new:nnnn { keys } { unknown }
+ { The~key~'#1'~is~unknown~and~is~being~ignored. }
+ {
+ The~module~'#2'~does~not~have~a~key~called~'#1'.\\
+ Check~that~you~have~spelled~the~key~name~correctly.
+ }
+\msg_new:nnnn { keys } { nested-choice-key }
+ { Attempt~to~define~'#1'~as~a~nested~choice~key. }
+ {
+ The~key~'#1'~cannot~be~defined~as~a~choice~as~the~parent~key~'#2'~is~
+ itself~a~choice.
+ }
+\msg_new:nnnn { keys } { value-forbidden }
+ { The~key~'#1'~does~not~take~a~value. }
+ {
+ The~key~'#1'~should~be~given~without~a~value.\\
+ The~value~'#2'~was~present:~the~key~will~be~ignored.
+ }
+\msg_new:nnnn { keys } { value-required }
+ { The~key~'#1'~requires~a~value. }
+ {
+ The~key~'#1'~must~have~a~value.\\
+ No~value~was~present:~the~key~will~be~ignored.
+ }
+\msg_new:nnn { keys } { show-key }
+ {
+ The~key~#1~
+ \tl_if_empty:nTF {#2}
+ { is~undefined. }
+ { has~the~properties: #2 . }
+ }
+\prop_gput:Nnn \g_msg_module_name_prop { keys } { LaTeX }
+\prop_gput:Nnn \g_msg_module_type_prop { keys } { }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+%\end{implementation}
+%
+%\PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3legacy.dtx b/macros/latex-dev/required/l3kernel/l3legacy.dtx
new file mode 100644
index 0000000000..ed7dadf222
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3legacy.dtx
@@ -0,0 +1,161 @@
+% \iffalse meta-comment
+%
+%% File: l3legacy.dtx
+%
+% Copyright (C) 2019-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3legacy} module\\ Interfaces to legacy concepts^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% There are a small number of \TeX{} or \LaTeXe{} concepts which are not used
+% in \pkg{expl3} code but which need to be manipulated when working as a \LaTeXe{}
+% package. To allow these to be integrated cleanly into \pkg{expl3} code, a set
+% of legacy interfaces are provided here.
+%
+% \begin{function}[EXP,pTF]{\legacy_if:n}
+% \begin{syntax}
+% \cs{legacy_if_p:n} \Arg{name}
+% \cs{legacy_if:nTF} \Arg{name} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \LaTeXe{}/plain \TeX{} conditional (generated by \tn{newif})
+% is \texttt{true} or \texttt{false} and branches accordingly. The
+% \meta{name} of the conditional should \emph{omit} the leading \texttt{if}.
+% \end{function}
+%
+% \begin{function}[added = 2021-05-10]
+% {
+% \legacy_if_set_true:n, \legacy_if_set_false:n,
+% \legacy_if_gset_true:n, \legacy_if_gset_false:n
+% }
+% \begin{syntax}
+% \cs{legacy_if_set_true:n} \Arg{name}
+% \cs{legacy_if_set_false:n} \Arg{name}
+% \end{syntax}
+% Sets the \LaTeXe{}/plain \TeX{} conditional |\if|\meta{name}
+% (generated by \tn{newif}) to be \texttt{true} or \texttt{false}.
+% \end{function}
+%
+% \begin{function}[added = 2021-05-10]{\legacy_if_set:nn, \legacy_if_gset:nn}
+% \begin{syntax}
+% \cs{legacy_if_set:nn} \Arg{name} \Arg{boolexpr}
+% \end{syntax}
+% Sets the \LaTeXe{}/plain \TeX{} conditional |\if|\meta{name}
+% (generated by \tn{newif}) to the result of evaluating the
+% \meta{boolean expression}.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3legacy} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=legacy>
+% \end{macrocode}
+%
+% \begin{macro}[EXP,pTF]{\legacy_if:n}
+% A friendly wrapper. We need to use the \cs{if:w} approach here, rather than
+% testing against \tn{iftrue}/\tn{iffalse} as the latter approach fails for
+% primitive conditionals such as \tn{ifmmode}. The \cs{reverse_if:N} here
+% means that we get a slightly more useful error if the name is undefined.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \legacy_if:n #1 { p , T , F , TF }
+ {
+ \exp_after:wN \reverse_if:N
+ \cs:w if#1 \cs_end:
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \legacy_if_set_true:n, \legacy_if_set_false:n,
+% \legacy_if_gset_true:n, \legacy_if_gset_false:n
+% }
+% A friendly wrapper.
+% \begin{macrocode}
+\cs_new_protected:Npn \legacy_if_set_true:n #1
+ { \cs_set_eq:cN { if#1 } \if_true: }
+\cs_new_protected:Npn \legacy_if_set_false:n #1
+ { \cs_set_eq:cN { if#1 } \if_false: }
+\cs_new_protected:Npn \legacy_if_gset_true:n #1
+ { \cs_gset_eq:cN { if#1 } \if_true: }
+\cs_new_protected:Npn \legacy_if_gset_false:n #1
+ { \cs_gset_eq:cN { if#1 } \if_false: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\legacy_if_set:nn, \legacy_if_gset:nn}
+% A more elaborate wrapper.
+% \begin{macrocode}
+\cs_new_protected:Npn \legacy_if_set:nn #1#2
+ {
+ \bool_if:nTF {#2} \legacy_if_set_true:n \legacy_if_set_false:n
+ {#1}
+ }
+\cs_new_protected:Npn \legacy_if_gset:nn #1#2
+ {
+ \bool_if:nTF {#2} \legacy_if_gset_true:n \legacy_if_gset_false:n
+ {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3luatex.dtx b/macros/latex-dev/required/l3kernel/l3luatex.dtx
new file mode 100644
index 0000000000..f0107d465b
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3luatex.dtx
@@ -0,0 +1,750 @@
+% \iffalse meta-comment
+%
+%% File: l3luatex.dtx
+%
+% Copyright (C) 2010-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3luatex} module\\ \LuaTeX-specific functions^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% The \LuaTeX{} engine provides access to the \Lua{} programming language,
+% and with it access to the \enquote{internals} of \TeX{}. In order to use
+% this within the framework provided here, a family of functions is
+% available. When used with \pdfTeX{}, \pTeX{}, \upTeX{} or \XeTeX{} these raise an
+% error: use \cs{sys_if_engine_luatex:T} to avoid this. Details on using
+% \Lua{} with the \LuaTeX{} engine are given in the \LuaTeX{} manual.
+%
+% \section{Breaking out to \Lua{}}
+%
+% \begin{function}[EXP, added = 2018-06-18]{\lua_now:n, \lua_now:e}
+% \begin{syntax}
+% \cs{lua_now:n} \Arg{token list}
+% \end{syntax}
+% The \meta{token list} is first tokenized by \TeX{}, which includes
+% converting line ends to spaces in the usual \TeX{} manner and which
+% respects currently-applicable \TeX{} category codes. The resulting
+% \meta{\Lua{} input} is passed to the \Lua{} interpreter for processing.
+% Each \cs{lua_now:n} block is treated by \Lua{} as a separate chunk.
+% The \Lua{} interpreter executes the \meta{\Lua{} input} immediately,
+% and in an expandable manner.
+% \begin{texnote}
+% \cs{lua_now:e} is a macro wrapper around \tn{directlua}: when
+% \LuaTeX{} is in use two expansions are required to yield the
+% result of the \Lua{} code.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2018-06-18]{\lua_shipout_e:n, \lua_shipout:n}
+% \begin{syntax}
+% \cs{lua_shipout:n} \Arg{token list}
+% \end{syntax}
+% The \meta{token list} is first tokenized by \TeX{}, which includes
+% converting line ends to spaces in the usual \TeX{} manner and which
+% respects currently-applicable \TeX{} category codes. The resulting
+% \meta{\Lua{} input} is passed to the \Lua{} interpreter when the
+% current page is finalised (\emph{i.e.}~at shipout). Each
+% \cs{lua_shipout:n} block is treated by \Lua{} as a separate chunk.
+% The \Lua{} interpreter will execute the \meta{\Lua{} input} during the
+% page-building routine: no \TeX{} expansion of the \meta{\Lua{} input}
+% will occur at this stage.
+%
+% In the case of the \cs{lua_shipout_e:n} version the input is fully
+% expanded by \TeX{} in an \texttt{e}-type manner during the shipout
+% operation.
+% \begin{texnote}
+% At a \TeX{} level, the \meta{\Lua{} input} is stored as a
+% \enquote{whatsit}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2015-06-29]{\lua_escape:n, \lua_escape:e}
+% \begin{syntax}
+% \cs{lua_escape:n} \Arg{token list}
+% \end{syntax}
+% Converts the \meta{token list} such that it can safely be passed to
+% \Lua{}: embedded backslashes, double and single quotes, and newlines
+% and carriage returns are escaped. This is done by prepending an extra
+% token consisting of a backslash with category code~$12$, and for the line
+% endings, converting them to |\n| and |\r|, respectively.
+% \begin{texnote}
+% \cs{lua_escape:e} is a macro wrapper around \tn{luaescapestring}:
+% when \LuaTeX{} is in use two expansions are required to yield the
+% result of the \Lua{} code.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2022-05-14]{\lua_load_module:n}
+% \begin{syntax}
+% \cs{lua_load_module:n} \Arg{Lua module name}
+% \end{syntax}
+% Loads a Lua module into the Lua interpreter.
+%
+% \cs{lua_now:n} passes its \Arg{token list} argument to the Lua interpreter
+% as a single line, with characters interpreted under the current catcode
+% regime. These two facts mean that \cs{lua_now:n} rarely behaves as expected
+% for larger pieces of code. Therefore, package authors should \textbf{not}
+% write significant amounts of Lua code in the arguments to \cs{lua_now:n}.
+% Instead, it is strongly recommended that they write the majorty of their Lua
+% code in a separate file, and then load it using \cs{lua_load_module:n}.
+% \begin{texnote}
+% This is a wrapper around the Lua call |require '|\meta{module}|'|.
+% \end{texnote}
+% \end{function}
+%
+% \section{Lua interfaces}
+%
+% As well as interfaces for \TeX{}, there are a small number of Lua functions
+% provided here.
+%
+% \begin{function}{ltx.utils}
+% Most public interfaces provided by the module are stored within the
+% |ltx.utils| table.
+% \end{function}
+%
+% \begin{function}{ltx.utils.filedump}
+% \begin{syntax}
+% \meta{dump}| = ltx.utils.filedump(|\meta{file}|,|\meta{offset}|,|\meta{length}|)| \\
+% \end{syntax}
+% Returns the uppercase hexadecimal representation of the content of the
+% \meta{file} read as bytes. If the \meta{length} is given, only this part
+% of the file is returned; similarly, one may specify the \meta{offset} from
+% the start of the file. If the \meta{length} is not given, the entire file
+% is read starting at the \meta{offset}.
+% \end{function}
+%
+% \begin{function}{ltx.utils.filemd5sum}
+% \begin{syntax}
+% \meta{hash}| = ltx.utils.filemd5sum(|\meta{file}|)| \\
+% \end{syntax}
+% Returns the MD5 sum of the file contents read as bytes; note that
+% the result will depend on the nature of the line endings used in the file,
+% in contrast to normal \TeX{} behaviour. If the \meta{file} is not found,
+% nothing is returned with \emph{no error raised}.
+% \end{function}
+%
+% \begin{function}{ltx.utils.filemoddate}
+% \begin{syntax}
+% \meta{date}| = ltx.utils.filemoddate(|\meta{file}|)| \\
+% \end{syntax}
+% Returns the date/time of last modification of the \meta{file} in the
+% format
+% \begin{quote}
+% |D:|\meta{year}\meta{month}\meta{day}\meta{hour}\meta{minute}^^A
+% \meta{second}\meta{offset}
+% \end{quote}
+% where the latter may be |Z| (UTC) or
+% \meta{plus-minus}\meta{hours}|'|\meta{minutes}|'|. If the \meta{file} is
+% not found, nothing is returned with \emph{no error raised}.
+% \end{function}
+%
+% \begin{function}{ltx.utils.filesize}
+% \begin{syntax}
+% |size = ltx.utils.filesize(|\meta{file}|)| \\
+% \end{syntax}
+% Returns the size of the \meta{file} in bytes. If the \meta{file} is not
+% found, nothing is returned with \emph{no error raised}.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3luatex} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \subsection{Breaking out to \Lua{}}
+%
+% \begin{macrocode}
+%<*tex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=lua>
+% \end{macrocode}
+%
+% \begin{macro}[EXP]{\@@_escape:n, \@@_now:n, \@@_shipout:n}
+% Copies of primitives.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_escape:n \tex_luaescapestring:D
+\cs_new_eq:NN \@@_now:n \tex_directlua:D
+\cs_new_eq:NN \@@_shipout:n \tex_latelua:D
+% \end{macrocode}
+% \end{macro}
+%
+% These functions are set up in \pkg{l3str} for bootstrapping: we want to
+% replace them with a \enquote{proper} version at this stage, so clean up.
+% \begin{macrocode}
+\cs_undefine:N \lua_escape:e
+\cs_undefine:N \lua_now:e
+% \end{macrocode}
+%
+% \begin{macro}[EXP]{\lua_now:n, \lua_now:e}
+% \begin{macro}{\lua_shipout_e:n, \lua_shipout:n}
+% \begin{macro}[EXP]{\lua_escape:n, \lua_escape:e}
+% Wrappers around the primitives.
+% \begin{macrocode}
+\cs_new:Npn \lua_now:e #1 { \@@_now:n {#1} }
+\cs_new:Npn \lua_now:n #1 { \lua_now:e { \exp_not:n {#1} } }
+\cs_new_protected:Npn \lua_shipout_e:n #1 { \@@_shipout:n {#1} }
+\cs_new_protected:Npn \lua_shipout:n #1
+ { \lua_shipout_e:n { \exp_not:n {#1} } }
+\cs_new:Npn \lua_escape:e #1 { \@@_escape:n {#1} }
+\cs_new:Npn \lua_escape:n #1 { \lua_escape:e { \exp_not:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\lua_load_module:n}
+% Wrapper around |require'|\meta{module}|'|.
+% \begin{macrocode}
+\str_new:N \l_@@_err_msg_str
+\cs_new_protected:Npn \lua_load_module:n #1
+ {
+ \bool_if:nF { \@@_load_module_p:n { #1 } }
+ {
+ \msg_error:nnnV
+ { luatex } { module-not-found } { #1 } \l_@@_err_msg_str
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% As with engines other than \LuaTeX{}
+% these have to be macros, we give them the same status in all cases.
+% When \LuaTeX{} is not in use, simply give an error message/
+% \begin{macrocode}
+\sys_if_engine_luatex:F
+ {
+ \clist_map_inline:nn
+ {
+ \lua_escape:n , \lua_escape:e ,
+ \lua_now:n , \lua_now:e
+ }
+ {
+ \cs_gset:Npn #1 ##1
+ {
+ \msg_expandable_error:nnn
+ { luatex } { luatex-required } { #1 }
+ }
+ }
+ \clist_map_inline:nn
+ { \lua_shipout_e:n , \lua_shipout:n, \lua_load_module:n }
+ {
+ \cs_gset_protected:Npn #1 ##1
+ {
+ \msg_error:nnn
+ { luatex } { luatex-required } { #1 }
+ }
+ }
+ }
+% \end{macrocode}
+% \subsection{Messages}
+%
+% \begin{macrocode}
+\msg_new:nnnn { luatex } { luatex-required }
+ { LuaTeX~engine~not~in~use!~Ignoring~#1. }
+ {
+ The~feature~you~are~using~is~only~available~
+ with~the~LuaTeX~engine.~LaTeX3~ignored~'#1'.
+ }
+
+\msg_new:nnnn { luatex } { module-not-found }
+ { Lua~module~`#1'~not~found. }
+ {
+ The~file~`#1.lua'~could~not~be~found.~Please~ensure~
+ that~the~file~was~properly~installed~and~that~the~
+ filename~database~is~current. \\ \\
+ The~Lua~loader~provided~this~additional~information: \\
+ #2
+ }
+
+\prop_gput:Nnn \g_msg_module_name_prop { luatex } { LaTeX }
+\prop_gput:Nnn \g_msg_module_type_prop { luatex } { }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</tex>
+% \end{macrocode}
+%
+% \subsection{\Lua{} functions for internal use}
+%
+% \begin{macrocode}
+%<*lua>
+% \end{macrocode}
+%
+% Most of the emulation of \pdfTeX{} here is based heavily on Heiko Oberdiek's
+% \pkg{pdftexcmds} package.
+%
+% \begin{macro}{ltx.utils}
+% Create a table for the kernel's own use.
+% \begin{macrocode}
+ltx = ltx or {utils={}}
+ltx.utils = ltx.utils or { }
+local ltxutils = ltx.utils
+% \end{macrocode}
+% \end{macro}
+%
+% Local copies of global tables.
+% \begin{macrocode}
+local io = io
+local kpse = kpse
+local lfs = lfs
+local math = math
+local md5 = md5
+local os = os
+local string = string
+local tex = tex
+local texio = texio
+local tonumber = tonumber
+% \end{macrocode}
+%
+% Local copies of standard functions.
+% \begin{macrocode}
+local abs = math.abs
+local byte = string.byte
+local floor = math.floor
+local format = string.format
+local gsub = string.gsub
+local lfs_attr = lfs.attributes
+local open = io.open
+local os_date = os.date
+local setcatcode = tex.setcatcode
+local sprint = tex.sprint
+local cprint = tex.cprint
+local write = tex.write
+local write_nl = texio.write_nl
+local utf8_char = utf8.char
+local package_loaded = package.loaded
+local package_searchers = package.searchers
+local table_concat = table.concat
+
+local scan_int = token.scan_int or token.scan_integer
+local scan_string = token.scan_string
+local scan_keyword = token.scan_keyword
+local put_next = token.put_next
+local token_create = token.create
+local token_new = token.new
+local set_macro = token.set_macro
+% \end{macrocode}
+%
+% Since token.create only returns useful values after the tokens
+% has been added to TeX's hash table, we define a variant which
+% defines it first if necessary.
+% \begin{macrocode}
+local token_create_safe
+do
+ local is_defined = token.is_defined
+ local set_char = token.set_char
+ local runtoks = tex.runtoks
+ local let_token = token_create'let'
+
+ function token_create_safe(s)
+ local orig_token = token_create(s)
+ if is_defined(s, true) then
+ return orig_token
+ end
+ set_char(s, 0)
+ local new_token = token_create(s)
+ runtoks(function()
+ put_next(let_token, new_token, orig_token)
+ end)
+ return new_token
+ end
+end
+
+local true_tok = token_create_safe'prg_return_true:'
+local false_tok = token_create_safe'prg_return_false:'
+% \end{macrocode}
+% In Con\TeX{}t lmtx \texttt{token.command_id} does not exist,
+% but it can easily be emulated with Con\TeX{}t's \texttt{tokens.commands}.
+% \begin{macrocode}
+local command_id = token.command_id
+if not command_id and tokens and tokens.commands then
+ local id_map = tokens.commands
+ function command_id(name)
+ return id_map[name]
+ end
+end
+% \end{macrocode}
+%
+% Deal with Con\TeX{}t: doesn't use |kpse| library.
+% \begin{macrocode}
+local kpse_find = (resolvers and resolvers.findfile) or kpse.find_file
+% \end{macrocode}
+%
+% \begin{macro}[int]{escapehex}
+% An internal auxiliary to convert a string to the matching hex escape.
+% This works on a byte basis: extension to handled UTF-8 input is
+% covered in \pkg{pdftexcmds} but is not currently required here.
+% \begin{macrocode}
+local function escapehex(str)
+ return (gsub(str, ".",
+ function (ch) return format("%02X", byte(ch)) end))
+end
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ltx.utils.filedump}
+% Similar comments here to the next function: read the file in binary mode
+% to avoid any line-end weirdness.
+% \begin{macrocode}
+local function filedump(name,offset,length)
+ local file = kpse_find(name,"tex",true)
+ if not file then return end
+ local f = open(file,"rb")
+ if not f then return end
+ if offset and offset > 0 then
+ f:seek("set", offset)
+ end
+ local data = f:read(length or 'a')
+ f:close()
+ return escapehex(data)
+end
+ltxutils.filedump = filedump
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{md5.HEX}
+% Hash a string and return the hash in uppercase hexadecimal format.
+% In some engines, this is build-in. For traditional \LuaTeX{}, the conversion
+% to hexadecimal has to be done by us.
+% \begin{macrocode}
+local md5_HEX = md5.HEX
+if not md5_HEX then
+ local md5_sum = md5.sum
+ function md5_HEX(data)
+ return escapehex(md5_sum(data))
+ end
+ md5.HEX = md5_HEX
+end
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{ltx.utils.filemd5sum}
+% Read an entire file and hash it: the hash function itself is a built-in.
+% As Lua is byte-based there is no work needed here in terms of UTF-8
+% (see \pkg{pdftexcmds} and how it handles strings that have passed through
+% \LuaTeX{}). The file is read in binary mode so that no line ending
+% normalisation occurs.
+% \begin{macrocode}
+local function filemd5sum(name)
+ local file = kpse_find(name, "tex", true) if not file then return end
+ local f = open(file, "rb") if not f then return end
+
+ local data = f:read("*a")
+ f:close()
+ return md5_HEX(data)
+end
+ltxutils.filemd5sum = filemd5sum
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ltx.utils.filemoddate}
+% There are two cases: If the C standard library is C99 compliant,
+% we can use |%z| to get the timezone in almost the right format.
+% We only have to add primes and replace a zero or missing offset
+% with |Z|.
+%
+% Of course this would be boring, so Windows does things differently.
+% There we have to manually calculate the offset.
+% See procedure \texttt{makepdftime} in \texttt{utils.c} of
+% \pdfTeX{}.
+% \begin{macrocode}
+local filemoddate
+if os_date'%z':match'^[+-]%d%d%d%d$' then
+ local pattern = lpeg.Cs(16 *
+ (lpeg.Cg(lpeg.S'+-' * '0000' * lpeg.Cc'Z')
+ + 3 * lpeg.Cc"'" * 2 * lpeg.Cc"'"
+ + lpeg.Cc'Z')
+ * -1)
+ function filemoddate(name)
+ local file = kpse_find(name, "tex", true)
+ if not file then return end
+ local date = lfs_attr(file, "modification")
+ if not date then return end
+ return pattern:match(os_date("D:%Y%m%d%H%M%S%z", date))
+ end
+else
+ local function filemoddate(name)
+ local file = kpse_find(name, "tex", true)
+ if not file then return end
+ local date = lfs_attr(file, "modification")
+ if not date then return end
+ local d = os_date("*t", date)
+ local u = os_date("!*t", date)
+ local off = 60 * (d.hour - u.hour) + d.min - u.min
+ if d.year ~= u.year then
+ if d.year > u.year then
+ off = off + 1440
+ else
+ off = off - 1440
+ end
+ elseif d.yday ~= u.yday then
+ if d.yday > u.yday then
+ off = off + 1440
+ else
+ off = off - 1440
+ end
+ end
+ local timezone
+ if off == 0 then
+ timezone = "Z"
+ else
+ if off < 0 then
+ timezone = "-"
+ off = -off
+ else
+ timezone = "+"
+ end
+ timezone = format("%s%02d'%02d'", timezone, hours // 60, hours % 60)
+ end
+ return format("D:%04d%02d%02d%02d%02d%02d%s",
+ d.year, d.month, d.day, d.hour, d.min, d.sec, timezone)
+ end
+end
+ltxutils.filemoddate = filemoddate
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ltx.utils.filesize}
+% A simple disk lookup.
+% \begin{macrocode}
+local function filesize(name)
+ local file = kpse_find(name, "tex", true)
+ if file then
+ local size = lfs_attr(file, "size")
+ if size then
+ return size
+ end
+ end
+end
+ltxutils.filesize = filesize
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{luadef}
+% An internal function for defining control sequences form Lua which behave
+% like primitives. This acts as a wrapper around |token.set_lua| which accepts
+% a function instead of an index into the functions table.
+% \begin{macrocode}
+local luacmd do
+ local set_lua = token.set_lua
+ local undefined_cs = command_id'undefined_cs'
+
+ if not context and not luatexbase then require'ltluatex' end
+ if luatexbase then
+ local new_luafunction = luatexbase.new_luafunction
+ local functions = lua.get_functions_table()
+ function luacmd(name, func, ...)
+ local id
+ local tok = token_create(name)
+ if tok.command == undefined_cs then
+ id = new_luafunction(name)
+ set_lua(name, id, ...)
+ else
+ id = tok.index or tok.mode
+ end
+ functions[id] = func
+ end
+ elseif context then
+ local register = context.functions.register
+ local functions = context.functions.known
+ function luacmd(name, func, ...)
+ local tok = token_create(name)
+ if tok.command == undefined_cs then
+ token.set_lua(name, register(func), ...)
+ else
+ functions[tok.index or tok.mode] = func
+ end
+ end
+ end
+end
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{try_require}
+% Loads a Lua module. This function loads the module similarly to the standard
+% Lua global function |require|, with a few differences. On success,
+% |try_require| returns |true, module|. If the module cannot be found, it
+% returns |false, err_msg|. If the module is found, but something goes wrong
+% when loading it, the function throws an error.
+% \begin{macrocode}
+local function try_require(name)
+ if package_loaded[name] then
+ return true, package_loaded[name]
+ end
+
+ local failure_details = {}
+ for _, searcher in ipairs(package_searchers) do
+ local loader, data = searcher(name)
+ if type(loader) == 'function' then
+ package_loaded[name] = loader(name, data) or true
+ return true, package_loaded[name]
+ elseif type(loader) == 'string' then
+ failure_details[#failure_details + 1] = loader
+ end
+ end
+
+ return false, table_concat(failure_details, '\n')
+end
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_load_module_p:n}
+% Check to see if we can load a module using |require|. If we
+% can load the module, then we load it immediately. Otherwise, we save the
+% error message in |\l_@@_err_msg_str|.
+% \begin{macrocode}
+local char_given = command_id'char_given'
+local c_true_bool = token_create(1, char_given)
+local c_false_bool = token_create(0, char_given)
+local c_str_cctab = token_create('c_str_cctab').mode
+
+luacmd('@@_load_module_p:n', function()
+ local success, result = try_require(scan_string())
+ if success then
+ set_macro(c_str_cctab, 'l_@@_err_msg_str', '')
+ put_next(c_true_bool)
+ else
+ set_macro(c_str_cctab, 'l_@@_err_msg_str', result)
+ put_next(c_false_bool)
+ end
+end)
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Preserving iniTeX Lua data for runs}
+%
+% \begin{macrocode}
+%<@@=lua>
+% \end{macrocode}
+%
+% The Lua state is not dumped when a forat is written, therefore any Lua
+% variables filled doing format building need to be restored in order to
+% be accessible during normal runs.
+%
+% We provide some kernel-internal helpers for this. They will only be available if
+% \texttt{luatexbase} is available. This is not a big restriction though, because
+% Con\TeX{}t (which does not use \texttt{luatexbase}) does not load \pkg{expl3}
+% in the format.
+%
+% \begin{macrocode}
+local register_luadata, get_luadata
+
+if luatexbase then
+ local register = token_create'@expl@luadata@bytecode'.index
+ if status.ini_version then
+% \end{macrocode}
+%
+% \begin{macro}[int]{register_luadata}
+% \texttt{register_luadata} is only available during format generation.
+% It accept a string which uniquely identifies the data object and has to be
+% provided to retrieve it later. Additionally it accepts a function which is
+% called in the \texttt{pre_dump} callback and which has to return a string that
+% evaluates to a valid Lua object to be preserved.
+% \begin{macrocode}
+ local luadata, luadata_order = {}, {}
+
+ function register_luadata(name, func)
+ if luadata[name] then
+ error(format("LaTeX error: data name %q already in use", name))
+ end
+ luadata[name] = func
+ luadata_order[#luadata_order + 1] = func and name
+ end
+% \end{macrocode}
+% \end{macro}
+%
+% The actual work is done in \texttt{pre_dump}. The \texttt{luadata_order} is used
+% to ensure that the order is consistent over multiple runs.
+% \begin{macrocode}
+ luatexbase.add_to_callback("pre_dump", function()
+ if next(luadata) then
+ local str = "return {"
+ for i=1, #luadata_order do
+ local name = luadata_order[i]
+ str = format('%s[%q]=%s,', str, name, luadata[name]())
+ end
+ lua.bytecode[register] = assert(load(str .. "}"))
+ end
+ end, "ltx.luadata")
+ else
+% \end{macrocode}
+%
+% \begin{macro}[int]{get_luadata}
+% \texttt{get_luadata} is only available if data should be restored.
+% It accept the identifier which was used when the data object was registered and
+% returns the associated object. Every object can only be retrieved once.
+% \begin{macrocode}
+ local luadata = lua.bytecode[register]
+ if luadata then
+ lua.bytecode[register] = nil
+ luadata = luadata()
+ end
+ function get_luadata(name)
+ if not luadata then return end
+ local data = luadata[name]
+ luadata[name] = nil
+ return data
+ end
+ end
+end
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</lua>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+%\end{implementation}
+%
+%\PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3msg.dtx b/macros/latex-dev/required/l3kernel/l3msg.dtx
new file mode 100644
index 0000000000..ab4d882dcb
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3msg.dtx
@@ -0,0 +1,2443 @@
+% \iffalse meta-comment
+%
+%% File: l3msg.dtx
+%
+% Copyright (C) 2009-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3msg} module\\ Messages^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% Messages need to be passed to the user by modules, either when errors
+% occur or to indicate how the code is proceeding. The \pkg{l3msg}
+% module provides a consistent method for doing this (as opposed to
+% writing directly to the terminal or log).
+%
+% The system used by \pkg{l3msg} to create messages divides the process
+% into two distinct parts. Named messages are created in the first part
+% of the process; at this stage, no decision is made about the type of
+% output that the message will produce. The second part of the process
+% is actually producing a message. At this stage a choice of message
+% \emph{class} has to be made, for example \texttt{error},
+% \texttt{warning} or \texttt{info}.
+%
+% By separating out the creation and use of messages, several benefits
+% are available. First, the messages can be altered later without
+% needing details of where they are used in the code. This makes it
+% possible to alter the language used, the detail level and so on.
+% Secondly, the output which results from a given message can be
+% altered. This can be done on a message class, module or message name
+% basis. In this way, message behaviour can be altered and messages can
+% be entirely suppressed.
+%
+% \section{Creating new messages}
+%
+% All messages have to be created before they can be used.
+% The text of messages is automatically wrapped to the length
+% available in the console. As a result, formatting is only needed
+% where it helps to show meaning. In particular, |\\| may be
+% used to force a new line and \verb*|\ | forces an explicit space.
+% Additionally, |\{|, |\#|, |\}|, |\%| and |\~| can be used to produce
+% the corresponding character.
+%
+% Messages may be subdivided \emph{by one level} using the~|/|
+% character. This is used within the message filtering system to allow
+% for example the \LaTeX{} kernel messages to belong to the module
+% \texttt{LaTeX} while still being filterable at a more granular level.
+% Thus for example
+% \begin{verbatim}
+% \msg_new:nnnn { mymodule } { submodule / message } ...
+% \end{verbatim}
+% will allow to filter out specifically messages from the \texttt{submodule}.
+%
+% Some authors may find the need to include spaces as |~| characters
+% tedious. This can be avoided by locally reseting the cateogry code
+% of \verb*| |.
+% \begin{verbatim}
+% \char_set_catcode_space:n { `\ }
+% \msg_new:nnn { foo } { bar }
+% {Some message text using '#1' and usual message shorthands \{ \ \ \}.}
+% \char_set_catcode_ignore:n { `\ }
+% \end{verbatim}
+% although in general this may be confusing; simply writing the messages
+% using |~| characters is the method favored by the team.
+%
+% \begin{function}[updated = 2011-08-16]
+% {
+% \msg_new:nnnn, \msg_new:nnee,
+% \msg_new:nnn, \msg_new:nne
+% }
+% \begin{syntax}
+% \cs{msg_new:nnnn} \Arg{module} \Arg{message} \Arg{text} \Arg{more text}
+% \end{syntax}
+% Creates a \meta{message} for a given \meta{module}.
+% The message is defined to first give \meta{text} and then
+% \meta{more text} if the user requests it. If no \meta{more text} is
+% available then a standard text is given instead. Within \meta{text}
+% and \meta{more text} four parameters (|#1| to |#4|) can be used:
+% these will be supplied at the time the message is
+% used. An error is raised if the \meta{message} already exists.
+% \end{function}
+%
+% \begin{function}{\msg_set:nnnn, \msg_set:nnn}
+% \begin{syntax}
+% \cs{msg_set:nnnn} \Arg{module} \Arg{message} \Arg{text} \Arg{more text}
+% \end{syntax}
+% Sets up the text for a \meta{message} for a given \meta{module}.
+% The message is defined to first give \meta{text} and then
+% \meta{more text} if the user requests it. If no \meta{more text} is
+% available then a standard text is given instead. Within \meta{text}
+% and \meta{more text} four parameters (|#1| to |#4|) can be used:
+% these will be supplied at the time the message is used.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added = 2012-03-03]{\msg_if_exist:nn}
+% \begin{syntax}
+% \cs{msg_if_exist_p:nn} \Arg{module} \Arg{message}
+% \cs{msg_if_exist:nnTF} \Arg{module} \Arg{message} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{message} for the \meta{module} is currently
+% defined.
+% \end{function}
+%
+% \section{Customizable information for message modules}
+%
+% \begin{function}[EXP, added = 2018-10-10]{\msg_module_name:n}
+% \begin{syntax}
+% \cs{msg_module_name:n} \Arg{module}
+% \end{syntax}
+% Expands to the public name of the \meta{module} as defined by
+% \cs{g_msg_module_name_prop} (or otherwise leaves the \meta{module}
+% unchanged).
+% \end{function}
+%
+% \begin{function}[EXP, added = 2018-10-10]{\msg_module_type:n}
+% \begin{syntax}
+% \cs{msg_module_type:n} \Arg{module}
+% \end{syntax}
+% Expands to the description which applies to the \meta{module},
+% for example a |Package| or |Class|. The information here is defined
+% in \cs{g_msg_module_type_prop}, and will default to |Package| if an
+% entry is not present.
+% \end{function}
+%
+% \begin{variable}[added = 2018-10-10]{\g_msg_module_name_prop}
+% Provides a mapping between the module name used for messages, and that
+% for documentation.
+% \end{variable}
+%
+% \begin{variable}[added = 2018-10-10]{\g_msg_module_type_prop}
+% Provides a mapping between the module name used for messages, and that
+% type of module. For example, for \LaTeX{}3 core messages, an empty entry
+% is set here meaning that they are not described using the standard
+% |Package| text.
+% \end{variable}
+%
+% \section{Contextual information for messages}
+%
+% \begin{function}[rEXP]{\msg_line_context:}
+% \begin{syntax}
+% \cs{msg_line_context:}
+% \end{syntax}
+% Prints the current line number when a message is given, and
+% thus suitable for giving context to messages. The number itself
+% is proceeded by the text |on line|.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_line_number:}
+% \begin{syntax}
+% \cs{msg_line_number:}
+% \end{syntax}
+% Prints the current line number when a message is given.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_fatal_text:n}
+% \begin{syntax}
+% \cs{msg_fatal_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text
+% \begin{quote}
+% \ttfamily
+% Fatal Package \meta{module} Error
+% \end{quote}
+% This function can be redefined to alter the language in which the
+% message is given, using |#1| as the name of the \meta{module} to
+% be included.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_critical_text:n}
+% \begin{syntax}
+% \cs{msg_critical_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text
+% \begin{quote}
+% \ttfamily
+% Critical Package \meta{module} Error
+% \end{quote}
+% This function can be redefined to alter the language in which the
+% message is given, using |#1| as the name of the \meta{module} to
+% be included.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_error_text:n}
+% \begin{syntax}
+% \cs{msg_error_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text
+% \begin{quote}
+% \ttfamily
+% Package \meta{module} Error
+% \end{quote}
+% This function can be redefined to alter the language in which the
+% message is given, using |#1| as the name of the \meta{module} to
+% be included.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_warning_text:n}
+% \begin{syntax}
+% \cs{msg_warning_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text
+% \begin{quote}
+% \ttfamily
+% Package \meta{module} Warning
+% \end{quote}
+% This function can be redefined to alter the language in which the
+% message is given, using |#1| as the name of the \meta{module} to
+% be included. The \meta{type} of \meta{module} may be adjusted:
+% |Package| is the standard outcome: see \cs{msg_module_type:n}.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_info_text:n}
+% \begin{syntax}
+% \cs{msg_info_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text:
+% \begin{quote}
+% \ttfamily
+% Package \meta{module} Info
+% \end{quote}
+% This function can be redefined to alter the language in which the
+% message is given, using |#1| as the name of the \meta{module} to
+% be included. The \meta{type} of \meta{module} may be adjusted:
+% |Package| is the standard outcome: see \cs{msg_module_type:n}.
+% \end{function}
+%
+% \begin{function}[EXP,updated = 2018-09-30]{\msg_see_documentation_text:n}
+% \begin{syntax}
+% \cs{msg_see_documentation_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text
+% \begin{quote}
+% \ttfamily
+%
+% See the \meta{module} documentation for further information.
+% \end{quote}
+% This function can be redefined to alter the language in which the
+% message is given, using |#1| as the name of the \meta{module} to
+% be included. The name of the \meta{module} is produced using
+% \cs{msg_module_name:n}.
+% \end{function}
+%
+% \section{Issuing messages}
+%
+% Messages behave differently depending on the message class. In all cases,
+% the message may be issued supplying~$0$ to~$4$ arguments. If the number of
+% arguments supplied here does not match the number in the definition of the
+% message, extra arguments are ignored, or empty arguments added (of
+% course the sense of the message may be impaired). The four arguments are
+% converted to strings before being added to the message text: the
+% \texttt{e}-type variants should be used to expand material.
+% Note that this expansion takes place with the standard definitions in
+% effect, which means that shorthands such as |\~| or |\\| are
+% \emph{not} available; instead one should use \cs{iow_char:N} |\~| and
+% \cs{iow_newline:}, respectively.
+% The following message classes exist:
+% \begin{itemize}
+% \item \texttt{fatal}, ending the \TeX{} run;
+% \item \texttt{critical}, ending the file being input;
+% \item \texttt{error}, interrupting the \TeX{} run without ending it;
+% \item \texttt{warning}, written to terminal and log file, for
+% important messages that may require corrections by the user;
+% \item \texttt{note} (less common than \texttt{info}) for important
+% information messages written to the terminal and log file;
+% \item \texttt{info} for normal information messages written to the log
+% file only;
+% \item \texttt{term} and \texttt{log} for un-decorated messages written
+% to the terminal and log file, or to the log file only;
+% \item \texttt{none} for suppressed messages.
+% \end{itemize}
+%
+% \begin{function}[updated = 2012-08-11]
+% {
+% \msg_fatal:nnnnnn ,
+% \msg_fatal:nnnnn ,
+% \msg_fatal:nnnn ,
+% \msg_fatal:nnn ,
+% \msg_fatal:nn ,
+% \msg_fatal:nnVV ,
+% \msg_fatal:nnVn ,
+% \msg_fatal:nnnV ,
+% \msg_fatal:nnV ,
+% \msg_fatal:nneeee ,
+% \msg_fatal:nneee ,
+% \msg_fatal:nnnee ,
+% \msg_fatal:nnee ,
+% \msg_fatal:nnne ,
+% \msg_fatal:nne
+% }
+% \begin{syntax}
+% \cs{msg_fatal:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} error \meta{message}, passing \meta{arg one} to
+% \meta{arg four} to the text-creating functions. After issuing a
+% fatal error the \TeX{} run halts. No PDF file will be produced in
+% this case (DVI mode runs may produce a truncated DVI file).
+% \end{function}
+%
+% \begin{function}[updated = 2012-08-11]
+% {
+% \msg_critical:nnnnnn ,
+% \msg_critical:nnnnn ,
+% \msg_critical:nnnn ,
+% \msg_critical:nnn ,
+% \msg_critical:nn ,
+% \msg_critical:nnVV ,
+% \msg_critical:nnVn ,
+% \msg_critical:nnnV ,
+% \msg_critical:nnV ,
+% \msg_critical:nneeee ,
+% \msg_critical:nneee ,
+% \msg_critical:nnnee ,
+% \msg_critical:nnee ,
+% \msg_critical:nnne ,
+% \msg_critical:nne
+% }
+% \begin{syntax}
+% \cs{msg_critical:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} error \meta{message}, passing \meta{arg one} to
+% \meta{arg four} to the text-creating functions. After issuing a
+% critical error, \TeX{} stops reading the current input file.
+% This may halt the \TeX{} run (if the current file is the main file)
+% or may abort reading a sub-file.
+% \begin{texnote}
+% The \TeX{} \tn{endinput} primitive is used to exit the file. In
+% particular, the rest of the current line remains in the input
+% stream.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[updated = 2012-08-11]
+% {
+% \msg_error:nnnnnn ,
+% \msg_error:nnnnn ,
+% \msg_error:nnnn ,
+% \msg_error:nnn ,
+% \msg_error:nn ,
+% \msg_error:nnVV ,
+% \msg_error:nnVn ,
+% \msg_error:nnnV ,
+% \msg_error:nnV ,
+% \msg_error:nneeee ,
+% \msg_error:nneee ,
+% \msg_error:nnnee ,
+% \msg_error:nnee ,
+% \msg_error:nnne ,
+% \msg_error:nne
+% }
+% \begin{syntax}
+% \cs{msg_error:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} error \meta{message}, passing \meta{arg one} to
+% \meta{arg four} to the text-creating functions. The error
+% interrupts processing and issues the text at the terminal. After user
+% input, the run continues.
+% \end{function}
+%
+% \begin{function}[updated = 2012-08-11]
+% {
+% \msg_warning:nnnnnn ,
+% \msg_warning:nnnnn ,
+% \msg_warning:nnnn ,
+% \msg_warning:nnn ,
+% \msg_warning:nn ,
+% \msg_warning:nnVV ,
+% \msg_warning:nnVn ,
+% \msg_warning:nnnV ,
+% \msg_warning:nnV ,
+% \msg_warning:nneeee ,
+% \msg_warning:nneee ,
+% \msg_warning:nnnee ,
+% \msg_warning:nnee ,
+% \msg_warning:nnne ,
+% \msg_warning:nne
+% }
+% \begin{syntax}
+% \cs{msg_warning:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} warning \meta{message}, passing \meta{arg one}
+% to \meta{arg four} to the text-creating functions. The warning text
+% is added to the log file and the terminal, but the \TeX{} run
+% is not interrupted.
+% \end{function}
+%
+% \begin{function}[added = 2021-05-18]
+% {
+% \msg_note:nnnnnn ,
+% \msg_note:nnnnn ,
+% \msg_note:nnnn ,
+% \msg_note:nnn ,
+% \msg_note:nn ,
+% \msg_note:nnVV ,
+% \msg_note:nnVn ,
+% \msg_note:nnnV ,
+% \msg_note:nnV ,
+% \msg_note:nneeee ,
+% \msg_note:nneee ,
+% \msg_note:nnnee ,
+% \msg_note:nnee ,
+% \msg_note:nnne ,
+% \msg_note:nne ,
+% \msg_info:nnnnnn ,
+% \msg_info:nnnnn ,
+% \msg_info:nnnn ,
+% \msg_info:nnn ,
+% \msg_info:nn ,
+% \msg_info:nnVV ,
+% \msg_info:nnVn ,
+% \msg_info:nnnV ,
+% \msg_info:nnV ,
+% \msg_info:nneeee ,
+% \msg_info:nneee ,
+% \msg_info:nnnee ,
+% \msg_info:nnee ,
+% \msg_info:nnne ,
+% \msg_info:nne
+% }
+% \begin{syntax}
+% \cs{msg_note:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \cs{msg_info:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} information \meta{message}, passing
+% \meta{arg one} to \meta{arg four} to the text-creating functions.
+% For the more common \cs{msg_info:nnnnnn}, the information text is
+% added to the log file only, while \cs{msg_note:nnnnnn} adds the
+% info text to both the log file and the terminal. The \TeX{} run is
+% not interrupted.
+% \end{function}
+%
+% \begin{function}[updated = 2012-08-11]
+% {
+% \msg_term:nnnnnn ,
+% \msg_term:nnnnn ,
+% \msg_term:nnnn ,
+% \msg_term:nnn ,
+% \msg_term:nn ,
+% \msg_term:nnVV ,
+% \msg_term:nnVn ,
+% \msg_term:nnnV ,
+% \msg_term:nnV ,
+% \msg_term:nneeee ,
+% \msg_term:nneee ,
+% \msg_term:nnnee ,
+% \msg_term:nnee ,
+% \msg_term:nnne ,
+% \msg_term:nne ,
+% \msg_log:nnnnnn ,
+% \msg_log:nnnnn ,
+% \msg_log:nnnn ,
+% \msg_log:nnn ,
+% \msg_log:nn ,
+% \msg_log:nnVV ,
+% \msg_log:nnVn ,
+% \msg_log:nnnV ,
+% \msg_log:nnV ,
+% \msg_log:nneeee ,
+% \msg_log:nneee ,
+% \msg_log:nnnee ,
+% \msg_log:nnee ,
+% \msg_log:nnne ,
+% \msg_log:nne
+% }
+% \begin{syntax}
+% \cs{msg_term:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \cs{msg_log:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} information \meta{message}, passing
+% \meta{arg one} to \meta{arg four} to the text-creating functions.
+% The output is briefer than \cs{msg_info:nnnnnn}, omitting for
+% instance the module name. It is added to the log file by
+% \cs{msg_log:nnnnnn} while \cs{msg_term:nnnnnn} also prints it on the
+% terminal.
+% \end{function}
+%
+% \begin{function}[updated = 2012-08-11]
+% {
+% \msg_none:nnnnnn ,
+% \msg_none:nnnnn ,
+% \msg_none:nnnn ,
+% \msg_none:nnn ,
+% \msg_none:nn ,
+% \msg_none:nnVV ,
+% \msg_none:nnVn ,
+% \msg_none:nnnV ,
+% \msg_none:nnV ,
+% \msg_none:nneeee ,
+% \msg_none:nneee ,
+% \msg_none:nnnee ,
+% \msg_none:nnee ,
+% \msg_none:nnne ,
+% \msg_none:nne
+% }
+% \begin{syntax}
+% \cs{msg_none:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Does nothing: used as a message class to prevent any output at
+% all (see the discussion of message redirection).
+% \end{function}
+%
+% \subsection{Messages for showing material}
+%
+% \begin{function}[added = 2017-12-04]
+% {
+% \msg_show:nnnnnn ,
+% \msg_show:nnnnn ,
+% \msg_show:nnnn ,
+% \msg_show:nnn ,
+% \msg_show:nn ,
+% \msg_show:nnVV ,
+% \msg_show:nnVn ,
+% \msg_show:nnnV ,
+% \msg_show:nnV ,
+% \msg_show:nneeee ,
+% \msg_show:nneee ,
+% \msg_show:nnnee ,
+% \msg_show:nnee ,
+% \msg_show:nnne ,
+% \msg_show:nne
+% }
+% \begin{syntax}
+% \cs{msg_show:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} information \meta{message}, passing \meta{arg
+% one} to \meta{arg four} to the text-creating functions. The
+% information text is shown on the terminal and the \TeX{} run is
+% interrupted in a manner similar to \cs{tl_show:n}. This is used in
+% conjunction with \cs{msg_show_item:n} and similar functions to print
+% complex variable contents completely. If the formatted text does
+% not contain |>~| at the start of a line, an additional line |>~.|
+% will be put at the end. In addition, a final period is added if not
+% present.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2017-12-04]
+% {\msg_show_item:n, \msg_show_item_unbraced:n, \msg_show_item:nn, \msg_show_item_unbraced:nn}
+% \begin{syntax}
+% \cs{seq_map_function:NN} \meta{seq} \cs{msg_show_item:n}
+% \cs{prop_map_function:NN} \meta{prop} \cs{msg_show_item:nn}
+% \end{syntax}
+% Used in the text of messages for \cs{msg_show:nnnnnn} to show or log
+% a list of items or key--value pairs. The output of
+% \cs{msg_show_item:n} produces a newline, the prefix |>|, two spaces,
+% then the braced string representation of its argument.
+% The two-argument versions separates the key and value using
+% \verb*| => |, and the \texttt{unbraced} versions don't print the
+% surrounding braces.
+%
+% These functions are suitable for usage with iterator functions like
+% \cs{seq_map_function:NN}, \cs{prop_map_function:NN}, etc. For
+% example, with a sequence \cs[no-index]{l_tmpa_seq} containing |a|,
+% |{b}| and |\c|,
+% \begin{verbatim}
+% \seq_map_function:NN \l_tmpa_seq \msg_show_item:n
+% \end{verbatim}
+% would expand to three lines:
+% \begin{quotation}
+% \noindent\verb*|> {a}|\\
+% \verb*|> {{b}}|\\
+% \verb*|> {\c }|
+% \end{quotation}
+% \end{function}
+%
+% \subsection{Expandable error messages}
+%
+% In very rare cases it may be necessary to produce errors in an
+% expansion-only context. The functions in this section should only be
+% used if there is no alternative approach using \cs{msg_error:nnnnnn}
+% or other non-expandable commands from the previous section. Despite
+% having a similar interface as non-expandable messages, expandable
+% errors must be handled internally very differently from normal error
+% messages, as none of the tools to print to the terminal or the log
+% file are expandable. As a result, short-hands such as |\{| or |\\| do
+% not work, and messages must be very short (with default settings,
+% they are truncated after approximately 50 characters). It is
+% advisable to ensure that the message is understandable even when
+% truncated, by putting the most important information up front.
+% Another particularity of expandable messages is that they
+% cannot be redirected or turned off by the user.
+%
+% \begin{function}[EXP, added = 2015-08-06, updated = 2019-02-28]
+% {
+% \msg_expandable_error:nnnnnn ,
+% \msg_expandable_error:nnnnn ,
+% \msg_expandable_error:nnnn ,
+% \msg_expandable_error:nnn ,
+% \msg_expandable_error:nn ,
+% \msg_expandable_error:nnffff ,
+% \msg_expandable_error:nnfff ,
+% \msg_expandable_error:nnff ,
+% \msg_expandable_error:nnf ,
+% }
+% \begin{syntax}
+% \cs{msg_expandable_error:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues an \enquote{Undefined error} message from \TeX{} itself
+% using the undefined control sequence \cs{???} then prints
+% \enquote{! \meta{module}: }\meta{error message}, which should be
+% short. With default settings, anything beyond approximately $60$
+% characters long (or bytes in some engines) is cropped. A leading
+% space might be removed as well.
+% \end{function}
+%
+% \section{Redirecting messages}
+%
+% Each message has a \enquote{name}, which can be used to alter the behaviour
+% of the message when it is given. Thus we might have
+% \begin{verbatim}
+% \msg_new:nnnn { module } { my-message } { Some~text } { Some~more~text }
+% \end{verbatim}
+% to define a message, with
+% \begin{verbatim}
+% \msg_error:nn { module } { my-message }
+% \end{verbatim}
+% when it is used. With no filtering, this raises an error. However, we
+% could alter the behaviour with
+% \begin{verbatim}
+% \msg_redirect_class:nn { error } { warning }
+% \end{verbatim}
+% to turn all errors into warnings, or with
+% \begin{verbatim}
+% \msg_redirect_module:nnn { module } { error } { warning }
+% \end{verbatim}
+% to alter only messages from that module, or even
+% \begin{verbatim}
+% \msg_redirect_name:nnn { module } { my-message } { warning }
+% \end{verbatim}
+% to target just one message. Redirection applies first to individual messages,
+% then to messages from one module and finally to messages of one class. Thus
+% it is possible to select out an individual message for special treatment
+% even if the entire class is already redirected.
+%
+% Multiple redirections are possible. Redirections can be cancelled by
+% providing an empty argument for the target class. Redirection to a
+% missing class raises an error immediately. Infinite loops are
+% prevented by eliminating the redirection starting from the target of
+% the redirection that caused the loop to appear. Namely, if
+% redirections are requested as $A \to B$, $B \to C$ and $C \to A$ in
+% this order, then the $A \to B$ redirection is cancelled.
+%
+% \begin{function}[updated = 2012-04-27]{\msg_redirect_class:nn}
+% \begin{syntax}
+% \cs{msg_redirect_class:nn} \Arg{class one} \Arg{class two}
+% \end{syntax}
+% Changes the behaviour of messages of \meta{class one} so that they
+% are processed using the code for those of \meta{class two}.
+% Each \meta{class} can be one of \texttt{fatal}, \texttt{critical},
+% \texttt{error}, \texttt{warning}, \texttt{note}, \texttt{info},
+% \texttt{term}, \texttt{log}, \texttt{none}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-04-27]{\msg_redirect_module:nnn}
+% \begin{syntax}
+% \cs{msg_redirect_module:nnn} \Arg{module} \Arg{class one} \Arg{class two}
+% \end{syntax}
+% Redirects message of \meta{class one} for \meta{module} to act as
+% though they were from \meta{class two}. Messages of \meta{class one}
+% from sources other than \meta{module} are not affected by this
+% redirection. This function can be used to make some messages
+% \enquote{silent} by default. For example, all of the
+% \texttt{warning} messages of \meta{module} could be turned off with:
+% \begin{verbatim}
+% \msg_redirect_module:nnn { module } { warning } { none }
+% \end{verbatim}
+% \end{function}
+%
+% \begin{function}[updated = 2012-04-27]{\msg_redirect_name:nnn}
+% \begin{syntax}
+% \cs{msg_redirect_name:nnn} \Arg{module} \Arg{message} \Arg{class}
+% \end{syntax}
+% Redirects a specific \meta{message} from a specific \meta{module} to
+% act as a member of \meta{class} of messages. No further redirection
+% is performed. This function can be used to make a selected message
+% \enquote{silent} without changing global parameters:
+% \begin{verbatim}
+% \msg_redirect_name:nnn { module } { annoying-message } { none }
+% \end{verbatim}
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3msg} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=msg>
+% \end{macrocode}
+%
+% \begin{variable}{\l_@@_internal_tl}
+% A general scratch for the module.
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_name_str, \l_@@_text_str}
+% Used to save module info when creating messages.
+% \begin{macrocode}
+\str_new:N \l_@@_name_str
+\str_new:N \l_@@_text_str
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Internal auxiliaries}
+%
+% \begin{variable}{\s_@@_mark,\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_use_none_delimit_by_s_stop:w}
+% Functions to gobble up to a scan mark.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_none_delimit_by_s_stop:w #1 \s_@@_stop { }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Creating messages}
+%
+% Messages are created and used separately, so there two parts to
+% the code here. First, a mechanism for creating message text.
+% This is pretty simple, as there is not actually a lot to do.
+%
+% \begin{variable}{\c_@@_text_prefix_tl, \c_@@_more_text_prefix_tl}
+% Locations for the text of messages.
+% \begin{macrocode}
+\tl_const:Nn \c_@@_text_prefix_tl { msg~text~>~ }
+\tl_const:Nn \c_@@_more_text_prefix_tl { msg~extra~text~>~ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP,pTF]{\msg_if_exist:nn}
+% Test whether the control sequence containing the message text exists
+% or not.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \msg_if_exist:nn #1#2 { p , T , F , TF }
+ {
+ \cs_if_exist:cTF { \c_@@_text_prefix_tl #1 / #2 }
+ { \prg_return_true: } { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_chk_if_free:nn}
+% This auxiliary is similar to \cs{__kernel_chk_if_free_cs:N}, and is used when
+% defining messages with \cs{msg_new:nnnn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_chk_free:nn #1#2
+ {
+ \msg_if_exist:nnT {#1} {#2}
+ {
+ \msg_error:nnnn { msg } { already-defined }
+ {#1} {#2}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_new:nnnn, \msg_new:nnee, \msg_new:nnxx,
+% \msg_new:nnn, \msg_new:nne, \msg_new:nnx
+% }
+% \begin{macro}{\msg_set:nnnn, \msg_set:nnn}
+% Setting a message simply means saving the appropriate text
+% into two functions. A sanity check first.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_new:nnnn #1#2#3#4
+ {
+ \@@_chk_free:nn {#1} {#2}
+ \cs_gset:cpn { \c_@@_text_prefix_tl #1 / #2 }
+ ##1##2##3##4 {#3}
+ \cs_gset:cpn { \c_@@_more_text_prefix_tl #1 / #2 }
+ ##1##2##3##4 {#4}
+ }
+\cs_generate_variant:Nn \msg_new:nnnn { nnee , nnxx }
+\cs_new_protected:Npn \msg_new:nnn #1#2#3
+ { \msg_new:nnnn {#1} {#2} {#3} { } }
+\cs_generate_variant:Nn \msg_new:nnn { nne , nnx }
+\cs_new_protected:Npn \msg_set:nnnn #1#2#3#4
+ {
+ \cs_set:cpn { \c_@@_text_prefix_tl #1 / #2 }
+ ##1##2##3##4 {#3}
+ \cs_set:cpn { \c_@@_more_text_prefix_tl #1 / #2 }
+ ##1##2##3##4 {#4}
+ }
+\cs_new_protected:Npn \msg_set:nnn #1#2#3
+ { \msg_set:nnnn {#1} {#2} {#3} { } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Messages: support functions and text}
+%
+% \begin{variable}
+% {
+% \c_@@_coding_error_text_tl ,
+% \c_@@_continue_text_tl ,
+% \c_@@_critical_text_tl ,
+% \c_@@_fatal_text_tl ,
+% \c_@@_help_text_tl ,
+% \c_@@_no_info_text_tl ,
+% \c_@@_on_line_text_tl ,
+% \c_@@_return_text_tl ,
+% \c_@@_trouble_text_tl
+% }
+% Simple pieces of text for messages.
+% \begin{macrocode}
+\tl_const:Nn \c_@@_coding_error_text_tl
+ {
+ This~is~a~coding~error.
+ \\ \\
+ }
+\tl_const:Nn \c_@@_continue_text_tl
+ { Type~<return>~to~continue }
+\tl_const:Nn \c_@@_critical_text_tl
+ { Reading~the~current~file~'\g_file_curr_name_str'~will~stop. }
+\tl_const:Nn \c_@@_fatal_text_tl
+ { This~is~a~fatal~error:~LaTeX~will~abort. }
+\tl_const:Nn \c_@@_help_text_tl
+ { For~immediate~help~type~H~<return> }
+\tl_const:Nn \c_@@_no_info_text_tl
+ {
+ LaTeX~does~not~know~anything~more~about~this~error,~sorry.
+ \c_@@_return_text_tl
+ }
+\tl_const:Nn \c_@@_on_line_text_tl { on~line }
+\tl_const:Nn \c_@@_return_text_tl
+ {
+ \\ \\
+ Try~typing~<return>~to~proceed.
+ \\
+ If~that~doesn't~work,~type~X~<return>~to~quit.
+ }
+\tl_const:Nn \c_@@_trouble_text_tl
+ {
+ \\ \\
+ More~errors~will~almost~certainly~follow: \\
+ the~LaTeX~run~should~be~aborted.
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\msg_line_number:, \msg_line_context:}
+% For writing the line number nicely. \cs{msg_line_context:} was set up
+% earlier, so this is not \texttt{new}.
+% \begin{macrocode}
+\cs_new:Npn \msg_line_number: { \int_use:N \tex_inputlineno:D }
+\cs_gset:Npn \msg_line_context:
+ {
+ \c_@@_on_line_text_tl
+ \c_space_tl
+ \msg_line_number:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Showing messages: low level mechanism}
+%
+% \begin{macro}{\@@_interrupt:Nnnn}
+% \begin{macro}{\@@_no_more_text:nnnn}
+% The low-level interruption macro is rather opaque, unfortunately.
+% Depending on the availability of more information there is a choice
+% of how to set up the further help. We feed the extra help text and
+% the message itself to a wrapping auxiliary, in this order because we
+% must first setup \TeX{}'s \tn{errhelp} register before issuing an
+% \tn{errmessage}. To deal with the various cases of critical or fatal
+% errors with and without help text, there is a bit of argument-passing
+% to do.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_interrupt:NnnnN #1#2#3#4#5
+ {
+ \str_set:Ne \l_@@_text_str { #1 {#2} }
+ \str_set:Ne \l_@@_name_str { \msg_module_name:n {#2} }
+ \cs_if_eq:cNTF
+ { \c_@@_more_text_prefix_tl #2 / #3 }
+ \@@_no_more_text:nnnn
+ {
+ \@@_interrupt_wrap:nnn
+ { \use:c { \c_@@_text_prefix_tl #2 / #3 } #4 }
+ { \c_@@_continue_text_tl }
+ {
+ \c_@@_no_info_text_tl
+ \tl_if_empty:NF #5
+ { \\ \\ #5 }
+ }
+ }
+ {
+ \@@_interrupt_wrap:nnn
+ { \use:c { \c_@@_text_prefix_tl #2 / #3 } #4 }
+ { \c_@@_help_text_tl }
+ {
+ \use:c { \c_@@_more_text_prefix_tl #2 / #3 } #4
+ \tl_if_empty:NF #5
+ { \\ \\ #5 }
+ }
+ }
+ }
+\cs_new:Npn \@@_no_more_text:nnnn #1#2#3#4 { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_interrupt_wrap:nnn}
+% \begin{macro}{\@@_interrupt_text:n, \@@_interrupt_more_text:n}
+% First setup \TeX{}'s \tn{errhelp} register with the extra help |#1|,
+% then build a nice-looking error message with |#2|. Everything is
+% done using \texttt{e}-type expansion as the new line markers are
+% different for the two type of text and need to be correctly set up.
+% The auxiliary \cs{@@_interrupt_more_text:n} receives its argument
+% as a line-wrapped string, which is thus unaffected by expansion.
+% We ave to split the main text into two parts as only the \enquote{message}
+% itself is wrapped with a leader: the generic help is wrapped at full
+% width. We also have to allow for the two characters used by \tn{errmessage}
+% itself.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_interrupt_wrap:nnn #1#2#3
+ {
+ \iow_wrap:nnnN { \\ #3 } { } { } \@@_interrupt_more_text:n
+ \group_begin:
+ \int_sub:Nn \l_iow_line_count_int { 2 }
+ \iow_wrap:nenN { \l_@@_text_str : ~ #1 }
+ {
+ ( \l_@@_name_str )
+ \prg_replicate:nn
+ {
+ \str_count:N \l_@@_text_str
+ - \str_count:N \l_@@_name_str
+ + 2
+ }
+ { ~ }
+ }
+ { } \@@_interrupt_text:n
+ \iow_wrap:nnnN { \l_@@_internal_tl \\ \\ #2 } { } { }
+ \@@_interrupt:n
+ }
+\cs_new_protected:Npn \@@_interrupt_text:n #1
+ {
+ \group_end:
+ \tl_set:Nn \l_@@_internal_tl {#1}
+ }
+\cs_new_protected:Npn \@@_interrupt_more_text:n #1
+ { \exp_args:Ne \tex_errhelp:D { #1 \iow_newline: } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_interrupt:n}
+% The business end of the process starts by producing some visual
+% separation of the message from the main part of the log. The error
+% message needs to be printed with everything made
+% \enquote{invisible}: \TeX{}'s own information involves the macro in
+% which \tn{errmessage} is called, and the end of the argument of the
+% \tn{errmessage}, including the closing brace. We use an active |!|
+% to call the \tn{errmessage} primitive, and end its argument with
+% \cs{use_none:n} \Arg{spaces} which fills the output with spaces. Two
+% trailing closing braces are turned into spaces to hide them as well.
+% The group in which we alter the definition of the active |!| is
+% closed before producing the message: this ensures that tokens
+% inserted by typing |I| in the command-line are inserted after
+% the message is entirely cleaned up.
+%
+% The \cs{__kernel_iow_with:Nnn} auxiliary, defined in \pkg{l3file}, expects
+% an \meta{integer variable}, an integer \meta{value}, and some
+% \meta{code}. It runs the \meta{code} after ensuring that the
+% \meta{integer variable} takes the given \meta{value}, then restores
+% the former value of the \meta{integer variable} if needed. We use
+% it to ensure that the \tn{newlinechar} is $10$, as needed for
+% \cs{iow_newline:} to work, and that \tn{errorcontextlines} is $-1$,
+% to avoid showing irrelevant context. Note that restoring the former
+% value of these integers requires inserting tokens after the
+% \tn{errmessage}, which go in the way of tokens which could be
+% inserted by the user. This is unavoidable.
+% \begin{macrocode}
+\group_begin:
+ \char_set_lccode:nn { 38 } { 32 } % &
+ \char_set_lccode:nn { 46 } { 32 } % .
+ \char_set_lccode:nn { 123 } { 32 } % {
+ \char_set_lccode:nn { 125 } { 32 } % }
+ \char_set_catcode_active:N \&
+\tex_lowercase:D
+ {
+ \group_end:
+ \cs_new_protected:Npn \@@_interrupt:n #1
+ {
+ \iow_term:n { }
+ \__kernel_iow_with:Nnn \tex_newlinechar:D { `\^^J }
+ {
+ \__kernel_iow_with:Nnn \tex_errorcontextlines:D { -1 }
+ {
+ \group_begin:
+ \cs_set_protected:Npn &
+ {
+ \tex_errmessage:D
+ {
+ #1
+ \use_none:n
+ { ............................................ }
+ }
+ }
+ \exp_after:wN
+ \group_end:
+ &
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Displaying messages}
+%
+% \LaTeX{} is handling error messages and so the \TeX{} ones are disabled.
+% \begin{macrocode}
+\int_gset:Nn \tex_errorcontextlines:D { -1 }
+% \end{macrocode}
+%
+% \begin{macro}[EXP]
+% {
+% \msg_fatal_text:n ,
+% \msg_critical_text:n ,
+% \msg_error_text:n ,
+% \msg_warning_text:n ,
+% \msg_info_text:n
+% }
+% \begin{macro}[EXP]{\@@_text:nn}
+% \begin{macro}[EXP]{\@@_text:n}
+% A function for issuing messages: both the text and order could
+% in principle vary. The module name may be empty for kernel messages,
+% hence the slightly contorted code path for a space.
+% \begin{macrocode}
+\cs_new:Npn \msg_fatal_text:n #1
+ {
+ Fatal ~
+ \msg_error_text:n {#1}
+ }
+\cs_new:Npn \msg_critical_text:n #1
+ {
+ Critical ~
+ \msg_error_text:n {#1}
+ }
+\cs_new:Npn \msg_error_text:n #1
+ { \@@_text:nn {#1} { Error } }
+\cs_new:Npn \msg_warning_text:n #1
+ { \@@_text:nn {#1} { Warning } }
+\cs_new:Npn \msg_info_text:n #1
+ { \@@_text:nn {#1} { Info } }
+\cs_new:Npn \@@_text:nn #1#2
+ {
+ \exp_args:Nf \@@_text:n { \msg_module_type:n {#1} }
+ \exp_args:Nf \@@_text:n { \msg_module_name:n {#1} }
+ #2
+ }
+\cs_new:Npn \@@_text:n #1
+ {
+ \tl_if_blank:nF {#1}
+ { #1 ~ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\g_msg_module_name_prop, \g_msg_module_type_prop}
+% For storing public module information: the kernel data is set up
+% in advance.
+% \begin{macrocode}
+\prop_new:N \g_msg_module_name_prop
+\prop_new:N \g_msg_module_type_prop
+\prop_gput:Nnn \g_msg_module_type_prop { LaTeX } { }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\msg_module_type:n}
+% Contextual footer information, with the potential to give modules an
+% alternative name.
+% \begin{macrocode}
+\cs_new:Npn \msg_module_type:n #1
+ {
+ \prop_if_in:NnTF \g_msg_module_type_prop {#1}
+ { \prop_item:Nn \g_msg_module_type_prop {#1} }
+ { Package }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\msg_module_name:n, \msg_see_documentation_text:n}
+% Contextual footer information, with the potential to give modules an
+% alternative name.
+% \begin{macrocode}
+\cs_new:Npn \msg_module_name:n #1
+ {
+ \prop_if_in:NnTF \g_msg_module_name_prop {#1}
+ { \prop_item:Nn \g_msg_module_name_prop {#1} }
+ {#1}
+ }
+\cs_new:Npn \msg_see_documentation_text:n #1
+ {
+ See~the~ \msg_module_name:n {#1} ~
+ documentation~for~further~information.
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_class_new:nn}
+% \begin{macrocode}
+\group_begin:
+ \cs_set_protected:Npn \@@_class_new:nn #1#2
+ {
+ \prop_new:c { l_@@_redirect_ #1 _prop }
+ \cs_new_protected:cpn { @@_ #1 _code:nnnnnn }
+ ##1##2##3##4##5##6 {#2}
+ \cs_new_protected:cpn { msg_ #1 :nnnnnn } ##1##2##3##4##5##6
+ {
+ \use:e
+ {
+ \exp_not:n { \@@_use:nnnnnnn {#1} {##1} {##2} }
+ { \tl_to_str:n {##3} } { \tl_to_str:n {##4} }
+ { \tl_to_str:n {##5} } { \tl_to_str:n {##6} }
+ }
+ }
+ \cs_new_protected:cpe { msg_ #1 :nnnnn } ##1##2##3##4##5
+ { \exp_not:c { msg_ #1 :nnnnnn } {##1} {##2} {##3} {##4} {##5} { } }
+ \cs_new_protected:cpe { msg_ #1 :nnnn } ##1##2##3##4
+ { \exp_not:c { msg_ #1 :nnnnnn } {##1} {##2} {##3} {##4} { } { } }
+ \cs_new_protected:cpe { msg_ #1 :nnn } ##1##2##3
+ { \exp_not:c { msg_ #1 :nnnnnn } {##1} {##2} {##3} { } { } { } }
+ \cs_new_protected:cpe { msg_ #1 :nn } ##1##2
+ { \exp_not:c { msg_ #1 :nnnnnn } {##1} {##2} { } { } { } { } }
+ \cs_generate_variant:cn { msg_ #1 :nnn }
+ { nnV , nne , nnx }
+ \cs_generate_variant:cn { msg_ #1 :nnnn }
+ { nnVV , nnVn , nnnV , nnne , nnnx , nnee , nnxx }
+ \cs_generate_variant:cn { msg_ #1 :nnnnn }
+ { nnnee , nnnxx , nneee , nnxxx }
+ \cs_generate_variant:cn { msg_ #1 :nnnnnn } { nneeee , nnxxxx }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_fatal:nnnnnn ,
+% \msg_fatal:nnnnn ,
+% \msg_fatal:nnnn ,
+% \msg_fatal:nnn ,
+% \msg_fatal:nn ,
+% \msg_fatal:nnVV ,
+% \msg_fatal:nnVn ,
+% \msg_fatal:nnnV ,
+% \msg_fatal:nnV ,
+% \msg_fatal:nneeee ,
+% \msg_fatal:nneee ,
+% \msg_fatal:nnxxxx ,
+% \msg_fatal:nnxxx ,
+% \msg_fatal:nnnee ,
+% \msg_fatal:nnee ,
+% \msg_fatal:nnnxx ,
+% \msg_fatal:nnxx ,
+% \msg_fatal:nnnx ,
+% \msg_fatal:nnne ,
+% \msg_fatal:nne ,
+% \msg_fatal:nnx
+% }
+% \begin{macro}{\@@_fatal_exit:}
+% For fatal errors, after the error message \TeX{} bails out. We force
+% a bail out rather than using \tn{end} as this means it does not
+% matter if we are in a context where normally the run cannot end.
+% \begin{macrocode}
+ \@@_class_new:nn { fatal }
+ {
+ \@@_interrupt:NnnnN
+ \msg_fatal_text:n {#1} {#2}
+ { {#3} {#4} {#5} {#6} }
+ \c_@@_fatal_text_tl
+ \@@_fatal_exit:
+ }
+ \cs_new_protected:Npn \@@_fatal_exit:
+ {
+ \tex_batchmode:D
+ \tex_read:D -1 to \l_@@_internal_tl
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_critical:nnnnnn ,
+% \msg_critical:nnnnn ,
+% \msg_critical:nnnn ,
+% \msg_critical:nnn ,
+% \msg_critical:nn ,
+% \msg_critical:nnVV ,
+% \msg_critical:nnVn ,
+% \msg_critical:nnnV ,
+% \msg_critical:nnV ,
+% \msg_critical:nneeee ,
+% \msg_critical:nneee ,
+% \msg_critical:nnxxxx ,
+% \msg_critical:nnxxx ,
+% \msg_critical:nnnee ,
+% \msg_critical:nnee ,
+% \msg_critical:nnnxx ,
+% \msg_critical:nnxx ,
+% \msg_critical:nnnx ,
+% \msg_critical:nnne ,
+% \msg_critical:nne ,
+% \msg_critical:nnx
+% }
+% Not quite so bad: just end the current file.
+% \begin{macrocode}
+ \@@_class_new:nn { critical }
+ {
+ \@@_interrupt:NnnnN
+ \msg_critical_text:n {#1} {#2}
+ { {#3} {#4} {#5} {#6} }
+ \c_@@_critical_text_tl
+ \tex_endinput:D
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_error:nnnnnn ,
+% \msg_error:nnnnn ,
+% \msg_error:nnnn ,
+% \msg_error:nnn ,
+% \msg_error:nn ,
+% \msg_error:nnVV ,
+% \msg_error:nnVn ,
+% \msg_error:nnnV ,
+% \msg_error:nnV ,
+% \msg_error:nneeee ,
+% \msg_error:nneee ,
+% \msg_error:nnxxxx ,
+% \msg_error:nnxxx ,
+% \msg_error:nnnee ,
+% \msg_error:nnee ,
+% \msg_error:nnnxx ,
+% \msg_error:nnxx ,
+% \msg_error:nnnx ,
+% \msg_error:nnne ,
+% \msg_error:nne ,
+% \msg_error:nnx
+% }
+% For an error, the interrupt routine is called. We check if there is
+% a \enquote{more text} by comparing that control sequence with a
+% permanently empty text. We have to undefine the bootstrap versions
+% here.
+% \begin{macrocode}
+ \cs_undefine:N \msg_error:nnee
+ \cs_undefine:N \msg_error:nne
+ \cs_undefine:N \msg_error:nn
+ \@@_class_new:nn { error }
+ {
+ \@@_interrupt:NnnnN
+ \msg_error_text:n {#1} {#2}
+ { {#3} {#4} {#5} {#6} }
+ \c_empty_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_info_aux:NNnnnnnn ,
+% \msg_warning:nnnnnn ,
+% \msg_warning:nnnnn ,
+% \msg_warning:nnnn ,
+% \msg_warning:nnn ,
+% \msg_warning:nn ,
+% \msg_warning:nnVV ,
+% \msg_warning:nnVn ,
+% \msg_warning:nnnV ,
+% \msg_warning:nnV ,
+% \msg_warning:nneeee ,
+% \msg_warning:nneee ,
+% \msg_warning:nnxxxx ,
+% \msg_warning:nnxxx ,
+% \msg_warning:nnnee ,
+% \msg_warning:nnee ,
+% \msg_warning:nnnxx ,
+% \msg_warning:nnxx ,
+% \msg_warning:nnnx ,
+% \msg_warning:nnne ,
+% \msg_warning:nne ,
+% \msg_warning:nnx ,
+% \msg_note:nnnnnn ,
+% \msg_note:nnnnn ,
+% \msg_note:nnnn ,
+% \msg_note:nnn ,
+% \msg_note:nn ,
+% \msg_note:nnVV ,
+% \msg_note:nnVn ,
+% \msg_note:nnnV ,
+% \msg_note:nnV ,
+% \msg_note:nneeee ,
+% \msg_note:nneee ,
+% \msg_note:nnxxxx ,
+% \msg_note:nnxxx ,
+% \msg_note:nnnee ,
+% \msg_note:nnee ,
+% \msg_note:nnnxx ,
+% \msg_note:nnxx ,
+% \msg_note:nnnx ,
+% \msg_note:nnne ,
+% \msg_note:nne ,
+% \msg_note:nnx ,
+% \msg_info:nnnnnn ,
+% \msg_info:nnnnn ,
+% \msg_info:nnnn ,
+% \msg_info:nnn ,
+% \msg_info:nn ,
+% \msg_info:nnVV ,
+% \msg_info:nnVn ,
+% \msg_info:nnnV ,
+% \msg_info:nnV ,
+% \msg_info:nneeee ,
+% \msg_info:nneee ,
+% \msg_info:nnxxxx ,
+% \msg_info:nnxxx ,
+% \msg_info:nnnee ,
+% \msg_info:nnee ,
+% \msg_info:nnnxx ,
+% \msg_info:nnxx ,
+% \msg_info:nnnx ,
+% \msg_info:nnne ,
+% \msg_info:nne ,
+% \msg_info:nnx
+% }
+% Warnings and information messages have no decoration. Warnings are
+% printed to the terminal while information can either go to the log
+% or both log and terminal.
+% \begin{macrocode}
+ \cs_new_protected:Npn \@@_info_aux:NNnnnnnn #1#2#3#4#5#6#7#8
+ {
+ \str_set:Ne \l_@@_text_str { #2 {#3} }
+ \str_set:Ne \l_@@_name_str { \msg_module_name:n {#3} }
+ #1 { }
+ \iow_wrap:nenN
+ {
+ \l_@@_text_str : ~
+ \use:c { \c_@@_text_prefix_tl #3 / #4 } {#5} {#6} {#7} {#8}
+ }
+ {
+ ( \l_@@_name_str )
+ \prg_replicate:nn
+ {
+ \str_count:N \l_@@_text_str
+ - \str_count:N \l_@@_name_str
+ }
+ { ~ }
+ }
+ { } #1
+ #1 { }
+ }
+ \@@_class_new:nn { warning }
+ {
+ \@@_info_aux:NNnnnnnn \iow_term:n \msg_warning_text:n
+ {#1} {#2} {#3} {#4} {#5} {#6}
+ }
+ \@@_class_new:nn { note }
+ {
+ \@@_info_aux:NNnnnnnn \iow_term:n \msg_info_text:n
+ {#1} {#2} {#3} {#4} {#5} {#6}
+ }
+ \@@_class_new:nn { info }
+ {
+ \@@_info_aux:NNnnnnnn \iow_log:n \msg_info_text:n
+ {#1} {#2} {#3} {#4} {#5} {#6}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_term:nnnnnn ,
+% \msg_term:nnnnn ,
+% \msg_term:nnnn ,
+% \msg_term:nnn ,
+% \msg_term:nn ,
+% \msg_term:nnVV ,
+% \msg_term:nnVn ,
+% \msg_term:nnnV ,
+% \msg_term:nnV ,
+% \msg_term:nneeee ,
+% \msg_term:nneee ,
+% \msg_term:nnxxxx ,
+% \msg_term:nnxxx ,
+% \msg_term:nnnee ,
+% \msg_term:nnee ,
+% \msg_term:nnnxx ,
+% \msg_term:nnxx ,
+% \msg_term:nnnx ,
+% \msg_term:nnne ,
+% \msg_term:nne ,
+% \msg_term:nnx ,
+% \msg_log:nnnnnn ,
+% \msg_log:nnnnn ,
+% \msg_log:nnnn ,
+% \msg_log:nnn ,
+% \msg_log:nn ,
+% \msg_log:nnVV ,
+% \msg_log:nnVn ,
+% \msg_log:nnnV ,
+% \msg_log:nnV ,
+% \msg_log:nneeee ,
+% \msg_log:nneee ,
+% \msg_log:nnxxxx ,
+% \msg_log:nnxxx ,
+% \msg_log:nnnee ,
+% \msg_log:nnee ,
+% \msg_log:nnnxx ,
+% \msg_log:nnxx ,
+% \msg_log:nnnx ,
+% \msg_log:nnne ,
+% \msg_log:nne ,
+% \msg_log:nnx
+% }
+% \enquote{Log} data is very similar to information, but with no extras
+% added.
+% \enquote{Term} is used for communicating with the user through the
+% terminal, like diagnostic messages, and debugging. This is similar
+% to \enquote{log} messages, but uses the terminal output.
+% \begin{macrocode}
+ \@@_class_new:nn { log }
+ {
+ \iow_wrap:nnnN
+ { \use:c { \c_@@_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6} }
+ { } { } \iow_log:n
+ }
+ \@@_class_new:nn { term }
+ {
+ \iow_wrap:nnnN
+ { \use:c { \c_@@_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6} }
+ { } { } \iow_term:n
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_none:nnnnnn ,
+% \msg_none:nnnnn ,
+% \msg_none:nnnn ,
+% \msg_none:nnn ,
+% \msg_none:nn ,
+% \msg_none:nnVV ,
+% \msg_none:nnVn ,
+% \msg_none:nnnV ,
+% \msg_none:nnV ,
+% \msg_none:nneeee ,
+% \msg_none:nneee ,
+% \msg_none:nnxxxx ,
+% \msg_none:nnxxx ,
+% \msg_none:nnnee ,
+% \msg_none:nnee ,
+% \msg_none:nnnxx ,
+% \msg_none:nnxx ,
+% \msg_none:nnnx ,
+% \msg_none:nnne ,
+% \msg_none:nne ,
+% \msg_none:nnx
+% }
+% The \texttt{none} message type is needed so that input can be gobbled.
+% \begin{macrocode}
+ \@@_class_new:nn { none } { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_show:nnnnnn ,
+% \msg_show:nnnnn ,
+% \msg_show:nnnn ,
+% \msg_show:nnn ,
+% \msg_show:nn ,
+% \msg_show:nnVV ,
+% \msg_show:nnVn ,
+% \msg_show:nnnV ,
+% \msg_show:nnV ,
+% \msg_show:nneeee ,
+% \msg_show:nneee ,
+% \msg_show:nnxxxx ,
+% \msg_show:nnxxx ,
+% \msg_show:nnnee ,
+% \msg_show:nnee ,
+% \msg_show:nnnxx ,
+% \msg_show:nnxx ,
+% \msg_show:nnnx ,
+% \msg_show:nnne ,
+% \msg_show:nne ,
+% \msg_show:nnx
+% }
+% \begin{macro}{\@@_show:n, \@@_show:w, \@@_show_dot:w, \@@_show:nn}
+% The \texttt{show} message type is used for \cs{seq_show:N} and
+% similar complicated data structures. Wrap the given text with a
+% trailing dot (important later) then pass it to \cs{@@_show:n}. If
+% there is |\\>~| (or if the whole thing starts with |>~|) we split
+% there, print the first part and show the second part using
+% \tn{showtokens} (the \cs{exp_after:wN} ensure a nice display). Note
+% that this primitive adds a leading |>~| and trailing dot. That is
+% why we included a trailing dot before wrapping and removed it
+% afterwards. If there is no |\\>~| do the same but with an empty
+% second part which adds a spurious but inevitable |>~.|
+% \begin{macrocode}
+ \@@_class_new:nn { show }
+ {
+ \iow_wrap:nnnN
+ { \use:c { \c_@@_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6} }
+ { } { } \@@_show:n
+ }
+ \cs_new_protected:Npn \@@_show:n #1
+ {
+ \tl_if_in:nnTF { ^^J #1 } { ^^J > ~ }
+ {
+ \tl_if_in:nnTF { #1 \s_@@_mark } { . \s_@@_mark }
+ { \@@_show_dot:w } { \@@_show:w }
+ ^^J #1 \s_@@_stop
+ }
+ { \@@_show:nn { ? #1 } { } }
+ }
+ \cs_new:Npn \@@_show_dot:w #1 ^^J > ~ #2 . \s_@@_stop
+ { \@@_show:nn {#1} {#2} }
+ \cs_new:Npn \@@_show:w #1 ^^J > ~ #2 \s_@@_stop
+ { \@@_show:nn {#1} {#2} }
+ \cs_new_protected:Npn \@@_show:nn #1#2
+ {
+ \tl_if_empty:nF {#1}
+ { \exp_args:No \iow_term:n { \use_none:n #1 } }
+ \tl_set:Nn \l_@@_internal_tl {#2}
+ \__kernel_iow_with:Nnn \tex_newlinechar:D { 10 }
+ {
+ \__kernel_iow_with:Nnn \tex_errorcontextlines:D { -1 }
+ {
+ \tex_showtokens:D \exp_after:wN \exp_after:wN \exp_after:wN
+ { \exp_after:wN \l_@@_internal_tl }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% End the group to eliminate \cs{@@_class_new:nn}.
+% \begin{macrocode}
+\group_end:
+% \end{macrocode}
+%
+% \begin{macro}[EXP]{\msg_show_item:n}
+% \begin{macro}[EXP]{\msg_show_item_unbraced:n}
+% \begin{macro}[EXP]{\msg_show_item:nn}
+% \begin{macro}[EXP]{\msg_show_item_unbraced:nn}
+% Each item in the variable is formatted using one of the following
+% functions. We cannot use |\\| and so on because these short-hands
+% cannot be used inside the arguments of messages, only when defining
+% the messages. We need to use |^^J| here directly as \pkg{l3file} is
+% not yet loaded.
+% \begin{macrocode}
+\cs_new:Npe \msg_show_item:n #1
+ { ^^J > ~ \c_space_tl \exp_not:N \tl_to_str:n { {#1} } }
+\cs_new:Npe \msg_show_item_unbraced:n #1
+ { ^^J > ~ \c_space_tl \exp_not:N \tl_to_str:n {#1} }
+\cs_new:Npe \msg_show_item:nn #1#2
+ {
+ ^^J > \use:nn { ~ } { ~ }
+ \exp_not:N \tl_to_str:n { {#1} }
+ \use:nn { ~ } { ~ } => \use:nn { ~ } { ~ }
+ \exp_not:N \tl_to_str:n { {#2} }
+ }
+\cs_new:Npe \msg_show_item_unbraced:nn #1#2
+ {
+ ^^J > \use:nn { ~ } { ~ }
+ \exp_not:N \tl_to_str:n {#1}
+ \use:nn { ~ } { ~ } => \use:nn { ~ } { ~ }
+ \exp_not:N \tl_to_str:n {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_class_chk_exist:nT}
+% Checking that a message class exists. We build this from
+% \cs{cs_if_free:cTF} rather than \cs{cs_if_exist:cTF} because that
+% avoids reading the second argument earlier than necessary.
+% \begin{macrocode}
+\cs_new:Npn \@@_class_chk_exist:nT #1
+ {
+ \cs_if_free:cTF { @@_ #1 _code:nnnnnn }
+ { \msg_error:nnn { msg } { class-unknown } {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_class_tl, \l_@@_current_class_tl}
+% Support variables needed for the redirection system.
+% \begin{macrocode}
+\tl_new:N \l_@@_class_tl
+\tl_new:N \l_@@_current_class_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_redirect_prop}
+% For redirection of individually-named messages
+% \begin{macrocode}
+\prop_new:N \l_@@_redirect_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_hierarchy_seq}
+% During redirection, split the message name into a sequence:
+% |{/module/submodule}|, |{/module}|, and |{}|.
+% \begin{macrocode}
+\seq_new:N \l_@@_hierarchy_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_class_loop_seq}
+% Classes encountered when following redirections to check for loops.
+% \begin{macrocode}
+\seq_new:N \l_@@_class_loop_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_use:nnnnnnn}
+% \begin{macro}
+% {
+% \@@_use_redirect_name:n , \@@_use_hierarchy:nwwN ,
+% \@@_use_redirect_module:n, \@@_use_code:
+% }
+% Actually using a message is a multi-step process. First, some
+% safety checks on the message and class requested. The code and
+% arguments are then stored to avoid passing them around. The
+% assignment to \cs{@@_use_code:} is similar to \cs{tl_set:Nn}.
+% The message is eventually produced with whatever \cs{l_@@_class_tl}
+% is when \cs{@@_use_code:} is called.
+% Here is also a good place to suppress tracing output if the
+% \pkg{trace} package is loaded since all (non-expandable) messages go
+% through this auxiliary.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_use:nnnnnnn #1#2#3#4#5#6#7
+ {
+ \cs_if_exist_use:N \conditionally@traceoff
+ \msg_if_exist:nnTF {#2} {#3}
+ {
+ \@@_class_chk_exist:nT {#1}
+ {
+ \tl_set:Nn \l_@@_current_class_tl {#1}
+ \cs_set_protected:Npe \@@_use_code:
+ {
+ \exp_not:n
+ {
+ \use:c { @@_ \l_@@_class_tl _code:nnnnnn }
+ {#2} {#3} {#4} {#5} {#6} {#7}
+ }
+ }
+ \@@_use_redirect_name:n { #2 / #3 }
+ }
+ }
+ { \msg_error:nnnn { msg } { unknown } {#2} {#3} }
+ \cs_if_exist_use:N \conditionally@traceon
+ }
+\cs_new_protected:Npn \@@_use_code: { }
+% \end{macrocode}
+% The first check is for a individual message redirection. If this
+% applies then no further redirection is attempted. Otherwise, split
+% the message name into \meta{module}, \meta{submodule} and \meta{message}
+% (with an
+% arbitrary number of slashes), and store |{/module/submodule}|,
+% |{/module}| and |{}| into \cs{l_@@_hierarchy_seq}. We then
+% map through this sequence, applying the most specific redirection.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_use_redirect_name:n #1
+ {
+ \prop_get:NnNTF \l_@@_redirect_prop { / #1 } \l_@@_class_tl
+ { \@@_use_code: }
+ {
+ \seq_clear:N \l_@@_hierarchy_seq
+ \@@_use_hierarchy:nwwN { }
+ #1 \s_@@_mark \@@_use_hierarchy:nwwN
+ / \s_@@_mark \@@_use_none_delimit_by_s_stop:w
+ \s_@@_stop
+ \@@_use_redirect_module:n { }
+ }
+ }
+\cs_new_protected:Npn \@@_use_hierarchy:nwwN #1#2 / #3 \s_@@_mark #4
+ {
+ \seq_put_left:Nn \l_@@_hierarchy_seq {#1}
+ #4 { #1 / #2 } #3 \s_@@_mark #4
+ }
+% \end{macrocode}
+% At this point, the items of \cs{l_@@_hierarchy_seq} are the
+% various levels at which we should look for a redirection.
+% Redirections which are less specific than the argument of
+% \cs{@@_use_redirect_module:n} are not attempted. This argument is
+% empty for a class redirection, \texttt{/module} for a module
+% redirection, \emph{etc.} Loop through the sequence to find the most
+% specific redirection, with module |##1|. The loop is interrupted
+% after testing for a redirection for |##1| equal to the argument |#1|
+% (least specific redirection allowed). When a redirection is found,
+% break the mapping, then if the redirection targets the same class,
+% output the code with that class, and otherwise set the target as the
+% new current class, and search for further redirections. Those
+% redirections should be at least as specific as |##1|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_use_redirect_module:n #1
+ {
+ \seq_map_inline:Nn \l_@@_hierarchy_seq
+ {
+ \prop_get:cnNTF { l_@@_redirect_ \l_@@_current_class_tl _prop }
+ {##1} \l_@@_class_tl
+ {
+ \seq_map_break:n
+ {
+ \tl_if_eq:NNTF \l_@@_current_class_tl \l_@@_class_tl
+ { \@@_use_code: }
+ {
+ \tl_set_eq:NN \l_@@_current_class_tl \l_@@_class_tl
+ \@@_use_redirect_module:n {##1}
+ }
+ }
+ }
+ {
+ \str_if_eq:nnT {##1} {#1}
+ {
+ \tl_set_eq:NN \l_@@_class_tl \l_@@_current_class_tl
+ \seq_map_break:n { \@@_use_code: }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\msg_redirect_name:nnn}
+% Named message always use the given class even if that class is
+% redirected further. An empty target class cancels any existing
+% redirection for that message.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_redirect_name:nnn #1#2#3
+ {
+ \tl_if_empty:nTF {#3}
+ { \prop_remove:Nn \l_@@_redirect_prop { / #1 / #2 } }
+ {
+ \@@_class_chk_exist:nT {#3}
+ { \prop_put:Nnn \l_@@_redirect_prop { / #1 / #2 } {#3} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\msg_redirect_class:nn, \msg_redirect_module:nnn}
+% \begin{macro}{\@@_redirect:nnn, \@@_redirect_loop_chk:nnn}
+% \begin{macro}{\@@_redirect_loop_list:n}
+% If the target class is empty, eliminate the corresponding
+% redirection. Otherwise, add the redirection. We must then check
+% for a loop: as an initialization, we start by storing the initial
+% class in \cs{l_@@_current_class_tl}.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_redirect_class:nn
+ { \@@_redirect:nnn { } }
+\cs_new_protected:Npn \msg_redirect_module:nnn #1
+ { \@@_redirect:nnn { / #1 } }
+\cs_new_protected:Npn \@@_redirect:nnn #1#2#3
+ {
+ \@@_class_chk_exist:nT {#2}
+ {
+ \tl_if_empty:nTF {#3}
+ { \prop_remove:cn { l_@@_redirect_ #2 _prop } {#1} }
+ {
+ \@@_class_chk_exist:nT {#3}
+ {
+ \prop_put:cnn { l_@@_redirect_ #2 _prop } {#1} {#3}
+ \tl_set:Nn \l_@@_current_class_tl {#2}
+ \seq_clear:N \l_@@_class_loop_seq
+ \@@_redirect_loop_chk:nnn {#2} {#3} {#1}
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% Since multiple redirections can only happen with increasing
+% specificity, a loop requires that all steps are of the same
+% specificity. The new redirection can thus only create a loop with
+% other redirections for the exact same module, |#1|, and not
+% submodules. After some initialization above, follow redirections
+% with \cs{l_@@_class_tl}, and keep track in
+% \cs{l_@@_class_loop_seq} of the various classes encountered. A
+% redirection from a class to itself, or the absence of redirection
+% both mean that there is no loop. A redirection to the initial class
+% marks a loop. To break it, we must decide which redirection to
+% cancel. The user most likely wants the newly added redirection to
+% hold with no further redirection. We thus remove the redirection
+% starting from |#2|, target of the new redirection. Note that no
+% message is emitted by any of the underlying functions: otherwise we
+% may get an infinite loop because of a message from the message
+% system itself.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_redirect_loop_chk:nnn #1#2#3
+ {
+ \seq_put_right:Nn \l_@@_class_loop_seq {#1}
+ \prop_get:cnNT { l_@@_redirect_ #1 _prop } {#3} \l_@@_class_tl
+ {
+ \str_if_eq:VnF \l_@@_class_tl {#1}
+ {
+ \tl_if_eq:NNTF \l_@@_class_tl \l_@@_current_class_tl
+ {
+ \prop_put:cnn { l_@@_redirect_ #2 _prop } {#3} {#2}
+ \msg_warning:nneeee
+ { msg } { redirect-loop }
+ { \seq_item:Nn \l_@@_class_loop_seq { 1 } }
+ { \seq_item:Nn \l_@@_class_loop_seq { 2 } }
+ {#3}
+ {
+ \seq_map_function:NN \l_@@_class_loop_seq
+ \@@_redirect_loop_list:n
+ { \seq_item:Nn \l_@@_class_loop_seq { 1 } }
+ }
+ }
+ { \@@_redirect_loop_chk:onn \l_@@_class_tl {#2} {#3} }
+ }
+ }
+ }
+\cs_generate_variant:Nn \@@_redirect_loop_chk:nnn { o }
+\cs_new:Npn \@@_redirect_loop_list:n #1 { {#1} ~ => ~ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Kernel-specific functions}
+%
+% \begin{macro}{\__kernel_msg_show_eval:Nn, \__kernel_msg_log_eval:Nn, \@@_show_eval:nnN}
+% A short-hand used for \cs{int_show:n} and similar functions that
+% passes to \cs{tl_show:n} the result of applying |#1| (a
+% function such as \cs{int_eval:n}) to the expression |#2|. The use of
+% \texttt{f}-expansion ensures that |#1| is expanded in the scope in which the
+% show command is called, rather than in the group created by
+% \cs{iow_wrap:nnnN}. This is only important for expressions
+% involving the \tn{currentgrouplevel} or \tn{currentgrouptype}.
+% On the other hand we want the expression to be converted to a string
+% with the usual escape character, hence within the wrapping code.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_msg_show_eval:Nn #1#2
+ { \exp_args:Nf \@@_show_eval:nnN { #1 {#2} } {#2} \tl_show:n }
+\cs_new_protected:Npn \__kernel_msg_log_eval:Nn #1#2
+ { \exp_args:Nf \@@_show_eval:nnN { #1 {#2} } {#2} \tl_log:n }
+\cs_new_protected:Npn \@@_show_eval:nnN #1#2#3 { #3 { #2 = #1 } }
+% \end{macrocode}
+% \end{macro}
+%
+% These are all retained purely for older \pkg{xparse} support.
+%
+% \begin{macro}{\__kernel_msg_new:nnnn, \__kernel_msg_new:nnn}
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_msg_new:nnnn #1
+ { \msg_new:nnnn { LaTeX / #1 } }
+\cs_new_protected:Npn \__kernel_msg_new:nnn #1
+ { \msg_new:nnn { LaTeX / #1 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \__kernel_msg_info:nnxx ,
+% \__kernel_msg_warning:nnx ,
+% \__kernel_msg_warning:nnxx ,
+% \__kernel_msg_error:nnx ,
+% \__kernel_msg_error:nnxx ,
+% \__kernel_msg_error:nnxxx
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_msg_info:nnxx #1
+ { \msg_info:nnee { LaTeX / #1 } }
+\cs_new_protected:Npn \__kernel_msg_warning:nnx #1
+ { \msg_warning:nne { LaTeX / #1 } }
+\cs_new_protected:Npn \__kernel_msg_warning:nnxx #1
+ { \msg_warning:nnee { LaTeX / #1 } }
+\cs_new_protected:Npn \__kernel_msg_error:nnx #1
+ { \msg_error:nne { LaTeX / #1 } }
+\cs_new_protected:Npn \__kernel_msg_error:nnxx #1
+ { \msg_error:nnee { LaTeX / #1 } }
+\cs_new_protected:Npn \__kernel_msg_error:nnxxx #1
+ { \msg_error:nneee { LaTeX / #1 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \__kernel_msg_expandable_error:nnn ,
+% \__kernel_msg_expandable_error:nnf ,
+% \__kernel_msg_expandable_error:nnff
+% }
+% \begin{macrocode}
+\cs_new:Npn \__kernel_msg_expandable_error:nnn #1
+ { \msg_expandable_error:nnn { LaTeX / #1 } }
+\cs_new:Npn \__kernel_msg_expandable_error:nnf #1
+ { \msg_expandable_error:nnf { LaTeX / #1 } }
+\cs_new:Npn \__kernel_msg_expandable_error:nnff #1
+ { \msg_expandable_error:nnff { LaTeX / #1 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Internal messages}
+%
+% Error messages needed to actually implement the message system
+% itself.
+% \begin{macrocode}
+\msg_new:nnnn { msg } { already-defined }
+ { Message~'#2'~for~module~'#1'~already~defined. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~was~asked~to~define~a~new~message~called~'#2'\\
+ by~the~module~'#1':~this~message~already~exists.
+ \c_@@_return_text_tl
+ }
+\msg_new:nnnn { msg } { unknown }
+ { Unknown~message~'#2'~for~module~'#1'. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~was~asked~to~display~a~message~called~'#2'\\
+ by~the~module~'#1':~this~message~does~not~exist.
+ \c_@@_return_text_tl
+ }
+\msg_new:nnnn { msg } { class-unknown }
+ { Unknown~message~class~'#1'. }
+ {
+ LaTeX~has~been~asked~to~redirect~messages~to~a~class~'#1':\\
+ this~was~never~defined.
+ \c_@@_return_text_tl
+ }
+\msg_new:nnnn { msg } { redirect-loop }
+ {
+ Message~redirection~loop~caused~by~ {#1} ~=>~ {#2}
+ \tl_if_empty:nF {#3} { ~for~module~' \use_none:n #3 ' } .
+ }
+ {
+ Adding~the~message~redirection~ {#1} ~=>~ {#2}
+ \tl_if_empty:nF {#3} { ~for~the~module~' \use_none:n #3 ' } ~
+ created~an~infinite~loop\\\\
+ \iow_indent:n { #4 \\\\ }
+ }
+% \end{macrocode}
+%
+% Messages for earlier kernel modules plus a few for \pkg{l3keys} which
+% cover coding errors.
+% \begin{macrocode}
+\msg_new:nnnn { kernel } { bad-number-of-arguments }
+ { Function~'#1'~cannot~be~defined~with~#2~arguments. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~has~been~asked~to~define~a~function~'#1'~with~
+ #2~arguments.~
+ TeX~allows~between~0~and~9~arguments~for~a~single~function.
+ }
+\msg_new:nnnn { kernel } { command-already-defined }
+ { Control~sequence~#1~already~defined. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~has~been~asked~to~create~a~new~control~sequence~'#1'~
+ but~this~name~has~already~been~used~elsewhere. \\ \\
+ The~current~meaning~is:\\
+ \ \ #2
+ }
+\msg_new:nnnn { kernel } { command-not-defined }
+ { Control~sequence~#1~undefined. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~has~been~asked~to~use~a~control~sequence~'#1':\\
+ this~has~not~been~defined~yet.
+ }
+\msg_new:nnnn { kernel } { empty-search-pattern }
+ { Empty~search~pattern. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~has~been~asked~to~replace~an~empty~pattern~by~'#1':~that~
+ would~lead~to~an~infinite~loop!
+ }
+\cs_if_exist:NF \tex_elapsedtime:D
+ {
+ \msg_new:nnnn { kernel } { no-elapsed-time }
+ { No~clock~detected~for~#1. }
+ { The~current~engine~provides~no~way~to~access~the~system~time. }
+ }
+\msg_new:nnnn { kernel } { non-base-function }
+ { Function~'#1'~is~not~a~base~function }
+ {
+ \c_@@_coding_error_text_tl
+ Functions~defined~through~\iow_char:N\\cs_new:Nn~must~have~
+ a~signature~consisting~of~only~normal~arguments~'N'~and~'n'.~
+ The~signature~'#2'~of~'#1'~contains~other~arguments~'#3'.~
+ To~define~variants~use~\iow_char:N\\cs_generate_variant:Nn~
+ and~to~define~other~functions~use~\iow_char:N\\cs_new:Npn.
+ }
+\msg_new:nnnn { kernel } { missing-colon }
+ { Function~'#1'~contains~no~':'. }
+ {
+ \c_@@_coding_error_text_tl
+ Code-level~functions~must~contain~':'~to~separate~the~
+ argument~specification~from~the~function~name.~This~is~
+ needed~when~defining~conditionals~or~variants,~or~when~building~a~
+ parameter~text~from~the~number~of~arguments~of~the~function.
+ }
+\msg_new:nnnn { kernel } { overflow }
+ { Integers~larger~than~2^{30}-1~cannot~be~stored~in~arrays. }
+ {
+ An~attempt~was~made~to~store~#3~
+ \tl_if_empty:nF {#2} { at~position~#2~ } in~the~array~'#1'.~
+ The~largest~allowed~value~#4~will~be~used~instead.
+ }
+\msg_new:nnnn { kernel } { out-of-bounds }
+ { Access~to~an~entry~beyond~an~array's~bounds. }
+ {
+ An~attempt~was~made~to~access~or~store~data~at~position~#2~of~the~
+ array~'#1',~but~this~array~has~entries~at~positions~from~1~to~#3.
+ }
+\msg_new:nnnn { kernel } { protected-predicate }
+ { Predicate~'#1'~must~be~expandable. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~has~been~asked~to~define~'#1'~as~a~protected~predicate.~
+ Only~expandable~tests~can~have~a~predicate~version.
+ }
+\msg_new:nnn { kernel } { randint-backward-range }
+ { Wrong~order~of~bounds~in~\iow_char:N\\int_rand:nn{#1}{#2}. }
+\msg_new:nnnn { kernel } { conditional-form-unknown }
+ { Conditional~form~'#1'~for~function~'#2'~unknown. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~has~been~asked~to~define~the~conditional~form~'#1'~of~
+ the~function~'#2',~but~only~'TF',~'T',~'F',~and~'p'~forms~exist.
+ }
+\msg_new:nnnn { kernel } { variant-too-long }
+ { Variant~form~'#1'~longer~than~base~signature~of~'#2'. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~
+ with~a~signature~starting~with~'#1',~but~that~is~longer~than~
+ the~signature~(part~after~the~colon)~of~'#2'.
+ }
+\msg_new:nnnn { kernel } { invalid-variant }
+ { Variant~form~'#1'~invalid~for~base~form~'#2'. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~
+ with~a~signature~starting~with~'#1',~but~cannot~change~an~argument~
+ from~type~'#3'~to~type~'#4'.
+ }
+\msg_new:nnnn { kernel } { invalid-exp-args }
+ { Invalid~variant~specifier~'#1'~in~'#2'. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~has~been~asked~to~create~an~\iow_char:N\\exp_args:N...~
+ function~with~signature~'N#2'~but~'#1'~is~not~a~valid~argument~
+ specifier.
+ }
+\msg_new:nnn { kernel } { deprecated-variant }
+ {
+ Variant~form~'#1'~deprecated~for~base~form~'#2'.~
+ One~should~not~change~an~argument~from~type~'#3'~to~type~'#4'
+ \str_case:nnF {#3}
+ {
+ { n } { :~use~a~'\token_if_eq_charcode:NNTF #4 c v V'~variant? }
+ { N } { :~base~form~only~accepts~a~single~token~argument. }
+ {#4} { :~base~form~is~already~a~variant. }
+ } { . }
+ }
+\msg_new:nnn { char } { active }
+ { Cannot~generate~active~chars. }
+\msg_new:nnn { char } { invalid-catcode }
+ { Invalid~catcode~for~char~generation. }
+\msg_new:nnn { char } { null-space }
+ { Cannot~generate~null~char~as~a~space. }
+\msg_new:nnn { char } { out-of-range }
+ { Charcode~requested~out~of~engine~range. }
+\msg_new:nnn { dim } { zero-unit }
+ { Zero~unit~in~conversion. }
+\msg_new:nnnn { kernel } { quote-in-shell }
+ { Quotes~in~shell~command~'#1'. }
+ { Shell~commands~cannot~contain~quotes~("). }
+\msg_new:nnnn { keys } { no-property }
+ { No~property~given~in~definition~of~key~'#1'. }
+ {
+ \c_@@_coding_error_text_tl
+ Inside~\keys_define:nn each~key~name~
+ needs~a~property: \\ \\
+ \iow_indent:n { #1 .<property> } \\ \\
+ LaTeX~did~not~find~a~'.'~to~indicate~the~start~of~a~property.
+ }
+\msg_new:nnnn { keys } { property-boolean-values-only }
+ { The~property~'#1'~accepts~boolean~values~only. }
+ {
+ \c_@@_coding_error_text_tl
+ The~property~'#1'~only~accepts~the~values~'true'~and~'false'.
+ }
+\msg_new:nnnn { keys } { property-requires-value }
+ { The~property~'#1'~requires~a~value. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~was~asked~to~set~property~'#1'~for~key~'#2'.\\
+ No~value~was~given~for~the~property,~and~one~is~required.
+ }
+\msg_new:nnnn { keys } { property-unknown }
+ { The~key~property~'#1'~is~unknown. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~has~been~asked~to~set~the~property~'#1'~for~key~'#2':~
+ this~property~is~not~defined.
+ }
+\msg_new:nnnn { quark } { invalid-function }
+ { Quark~test~function~'#1'~is~invalid. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~has~been~asked~to~create~quark~test~function~'#1'~
+ \tl_if_empty:nTF {#2}
+ { but~that~name~ }
+ { with~signature~'#2',~but~that~signature~ }
+ is~not~valid.
+ }
+\__kernel_msg_new:nnn { quark } { invalid }
+ { Invalid~quark~variable~'#1'. }
+\msg_new:nnnn { scanmark } { already-defined }
+ { Scan~mark~#1~already~defined. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~has~been~asked~to~create~a~new~scan~mark~'#1'~
+ but~this~name~has~already~been~used~for~a~scan~mark.
+ }
+\msg_new:nnnn { seq } { item-too-large }
+ { Sequence~'#1'~does~not~have~an~item~#3 }
+ {
+ An~attempt~was~made~to~push~or~pop~the~item~at~position~#3~
+ of~'#1',~but~this~
+ \int_compare:nTF { #3 = 0 }
+ { position~does~not~exist. }
+ { sequence~only~has~#2~item \int_compare:nF { #2 = 1 } {s}. }
+ }
+\msg_new:nnnn { seq } { shuffle-too-large }
+ { The~sequence~#1~is~too~long~to~be~shuffled~by~TeX. }
+ {
+ TeX~has~ \int_eval:n { \c_max_register_int + 1 } ~
+ toks~registers:~this~only~allows~to~shuffle~up~to~
+ \int_use:N \c_max_register_int \ items.~
+ The~list~will~not~be~shuffled.
+ }
+\msg_new:nnnn { kernel } { variable-not-defined }
+ { Variable~#1~undefined. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~has~been~asked~to~show~a~variable~#1,~but~this~has~not~
+ been~defined~yet.
+ }
+\msg_new:nnnn { kernel } { bad-type }
+ { Variable~'#1'~is~not~a~valid~#3. }
+ {
+ \c_@@_coding_error_text_tl
+ The~variable~'#1'~with~\tl_if_empty:nTF {#4} {meaning} {value}\\\\
+ \iow_indent:n {#2}\\\\
+ should~be~a~#3~variable,~but~
+ \tl_if_empty:nTF {#4}
+ { it~is~not \str_if_eq:nnF {#3} { bool } { ~a~short~macro } . }
+ {
+ it~does~not~have~the~correct~
+ \str_if_eq:nnTF {#2} {#4}
+ { category~codes. }
+ { internal~structure:\\\\\iow_indent:n {#4} }
+ }
+ }
+\msg_new:nnnn { prop } { bad-link }
+ { Variable~'#1'~is~not~a~valid~(linked)~prop. }
+ {
+ \c_@@_coding_error_text_tl
+ The~variable~'#1'~has~an~incorrect~internal~structure.~
+ Its~internal~entry~'#2'~points~to~'#3',~whose~name~is~not~of~the~
+ form~'#4~<key>'.
+ }
+\msg_new:nnnn { clist } { non-clist }
+ { Variable~'#1'~is~not~a~valid~clist. }
+ {
+ \c_@@_coding_error_text_tl
+ The~variable~'#1'~with~value\\\\
+ \iow_indent:n {#2}\\\\
+ should~be~a~clist~variable,~but~it~includes~empty~or~blank~items~
+ without~braces.
+ }
+\msg_new:nnnn { prop } { misused }
+ { A~property~list~was~misused. }
+ {
+ \c_@@_coding_error_text_tl
+ A~property~list~variable~was~used~without~an~accessor~function.~
+ It~
+ \tl_if_empty:nTF {#1}
+ { is~empty. }
+ { contains~the~key-value~pairs \use_none:n #1 . }
+ }
+\msg_new:nnnn { prop } { inner-make }
+ { '#1'~ cannot~ be~ used~ in~ a~ group. }
+ {
+ \c_@@_coding_error_text_tl
+ The~ command~ '#1'~ was~ applied~ to~ the~ property~ list~
+ variable~ '#2', but~ the~ storage~ type~ can~ only~ be~ changed~
+ at~ the~ outermost~ group~ level.
+ }
+% \end{macrocode}
+%
+% Some errors only appear in expandable settings,
+% hence don't need a \enquote{more-text} argument.
+% \begin{macrocode}
+\msg_new:nnn { kernel } { bad-exp-end-f }
+ { Misused~\exp_end_continue_f:w or~:nw }
+\msg_new:nnn { kernel } { bad-variable }
+ { Erroneous~variable~#1 used! }
+\msg_new:nnn { seq } { misused }
+ { A~sequence~was~misused. }
+\msg_new:nnn { prg } { negative-replication }
+ { Negative~argument~for~\iow_char:N\\prg_replicate:nn. }
+\msg_new:nnn { prop } { prop-keyval }
+ { Missing~'='~in~'#1'~(in~'..._keyval:Nn') }
+\msg_new:nnn { kernel } { unknown-comparison }
+ { Relation~'#1'~not~among~=,<,>,==,!=,<=,>=. }
+\msg_new:nnn { kernel } { zero-step }
+ { Zero~step~size~for~function~#1. }
+% \end{macrocode}
+%
+% Messages used by the \enquote{\texttt{show}} functions.
+% \begin{macrocode}
+\msg_new:nnn { clist } { show }
+ {
+ The~comma~list~ \tl_if_empty:nF {#1} { #1 ~ }
+ \tl_if_empty:nTF {#2}
+ { is~empty \\>~ . }
+ { contains~the~items~(without~outer~braces): #2 . }
+ }
+\msg_new:nnn { intarray } { show }
+ { The~integer~array~#1~contains~#2~items: \\ #3 . }
+\msg_new:nnn { prop } { show }
+ {
+ The~ \str_if_eq:nnF {#3} { flat } { #3~ }
+ property~list~#1~
+ \tl_if_empty:nTF {#2}
+ { is~empty \\>~ . }
+ { contains~the~pairs~(without~outer~braces): #2 . }
+ }
+\msg_new:nnn { seq } { show }
+ {
+ The~sequence~#1~
+ \tl_if_empty:nTF {#2}
+ { is~empty \\>~ . }
+ { contains~the~items~(without~outer~braces): #2 . }
+ }
+\msg_new:nnn { kernel } { show-streams }
+ {
+ \tl_if_empty:nTF {#2} { No~ } { The~following~ }
+ \str_case:nn {#1}
+ {
+ { ior } { input ~ }
+ { iow } { output ~ }
+ }
+ streams~are~
+ \tl_if_empty:nTF {#2} { open } { in~use: #2 . }
+ }
+% \end{macrocode}
+%
+% System layer messages
+% \begin{macrocode}
+\msg_new:nnnn { sys } { backend-set }
+ { Backend~configuration~already~set. }
+ {
+ Run-time~backend~selection~may~only~be~carried~out~once~during~a~run.~
+ This~second~attempt~to~set~them~will~be~ignored.
+ }
+\msg_new:nnnn { sys } { load-debug-in-preamble }
+ { Load~debug~support~in~the~preamble. }
+ {
+ Debugging~requires~support~loaded~in~the~preamble: \\
+ Use~\sys_load_debug:~before~\begin{document}.
+ }
+\msg_new:nnnn { sys } { wrong-backend }
+ { Backend~request~inconsistent~with~engine:~using~'#2'~backend. }
+ {
+ You~have~requested~backend~'#1',~but~this~is~not~suitable~for~use~with~the~
+ active~engine.~LaTeX~will~use~the~'#2'~backend~instead.
+ }
+% \end{macrocode}
+%
+% \subsection{Expandable errors}
+%
+% \begin{macro}{\@@_expandable_error:nn}
+% In expansion only context, we cannot use the normal means of
+% reporting errors. Instead, we rely on a low-level \TeX{} error
+% caused by expanding a macro \cs{???} with parameter text ``|?|''
+% (this could be any token) which we used followed by something else
+% (here, a space). This shows
+% the context, which thanks to the odd-looking \cs{use:n} is
+% \begin{verbatim}
+% <argument> \???
+% ! mypkg Error: The error message.
+% \end{verbatim}
+% In other words, \TeX{} is processing the argument of \cs{use:n},
+% which is \cs{???} \meta{space} |!| \meta{error type} |:| \meta{error message}.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \cs_new:Npn #1 ? { }
+ \cs_new:Npn \@@_expandable_error:nn ##1##2
+ {
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_use_none_delimit_by_s_stop:w
+ \use:n { #1 ~ ! ~ ##2 : ~ ##1 } \s_@@_stop
+ }
+ }
+\exp_args:Nc \@@_tmp:w { ??? }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \msg_expandable_error:nnnnnn ,
+% \msg_expandable_error:nnnnn ,
+% \msg_expandable_error:nnnn ,
+% \msg_expandable_error:nnn ,
+% \msg_expandable_error:nn ,
+% \msg_expandable_error:nnffff ,
+% \msg_expandable_error:nnfff ,
+% \msg_expandable_error:nnff ,
+% \msg_expandable_error:nnf
+% }
+% The command built from the csname
+% \cs{c_@@_text_prefix_tl} |#1 / #2|
+% takes four arguments and builds the error text, which is fed to
+% \cs{@@_expandable_error:n} with appropriate expansion: just as for
+% usual messages the arguments are first turned to strings, then the
+% message is fully expanded. The module name also has to be determined.
+% \begin{macrocode}
+\exp_args_generate:n { oooo }
+\cs_new:Npn \msg_expandable_error:nnnnnn #1#2#3#4#5#6
+ {
+ \exp_args:Nee \@@_expandable_error:nn
+ {
+ \exp_args:Nc \exp_args:Noooo
+ { \c_@@_text_prefix_tl #1 / #2 }
+ { \tl_to_str:n {#3} }
+ { \tl_to_str:n {#4} }
+ { \tl_to_str:n {#5} }
+ { \tl_to_str:n {#6} }
+ }
+ { \msg_error_text:n {#1} }
+ }
+\cs_new:Npn \msg_expandable_error:nnnnn #1#2#3#4#5
+ { \msg_expandable_error:nnnnnn {#1} {#2} {#3} {#4} {#5} { } }
+\cs_new:Npn \msg_expandable_error:nnnn #1#2#3#4
+ { \msg_expandable_error:nnnnnn {#1} {#2} {#3} {#4} { } { } }
+\cs_new:Npn \msg_expandable_error:nnn #1#2#3
+ { \msg_expandable_error:nnnnnn {#1} {#2} {#3} { } { } { } }
+\cs_new:Npn \msg_expandable_error:nn #1#2
+ { \msg_expandable_error:nnnnnn {#1} {#2} { } { } { } { } }
+\cs_generate_variant:Nn \msg_expandable_error:nnnnnn { nnffff }
+\cs_generate_variant:Nn \msg_expandable_error:nnnnn { nnfff }
+\cs_generate_variant:Nn \msg_expandable_error:nnnn { nnff }
+\cs_generate_variant:Nn \msg_expandable_error:nnn { nnf }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Message formatting}
+%
+% \begin{macrocode}
+\prop_gput:Nnn \g_msg_module_name_prop { kernel } { LaTeX }
+\prop_gput:Nnn \g_msg_module_type_prop { kernel } { }
+\clist_map_inline:nn
+ {
+ char , clist , coffin , debug , deprecation , dim, msg ,
+ quark , prg , prop , scanmark , seq , sys
+ }
+ {
+ \prop_gput:Nnn \g_msg_module_name_prop {#1} { LaTeX }
+ \prop_gput:Nnn \g_msg_module_type_prop {#1} { }
+ }
+\prop_gput:Nnn \g_msg_module_name_prop { LaTeX / cmd } { LaTeX }
+\prop_gput:Nnn \g_msg_module_type_prop { LaTeX / cmd } { }
+\prop_gput:Nnn \g_msg_module_name_prop { LaTeX / ltcmd } { LaTeX }
+\prop_gput:Nnn \g_msg_module_type_prop { LaTeX / ltcmd } { }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3names.dtx b/macros/latex-dev/required/l3kernel/l3names.dtx
new file mode 100644
index 0000000000..468481c28c
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3names.dtx
@@ -0,0 +1,1568 @@
+% \iffalse meta-comment
+%
+%% File: l3names.dtx
+%
+% Copyright (C) 1990-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3names} module\\ Namespace for primitives^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{Setting up the \LaTeX3 programming language}
+%
+% This module is at the core of the \LaTeX3 programming language. It
+% performs the following tasks:
+% \begin{itemize}
+% \item defines new names for all \TeX{} primitives;
+% \item emulate required primitives not provided by default in \LuaTeX;
+% \item switches to the category code r{\'e}gime for programming;
+% \end{itemize}
+%
+% This module is entirely dedicated to primitives (and emulations of
+% these), which should not be used directly within \LaTeX3 code
+% (outside of \enquote{kernel-level} code). As such, the primitives
+% are not documented here: \emph{The \TeX{}book}, \emph{\TeX{} by
+% Topic} and the manuals for \pdfTeX{}, \XeTeX{}, \LuaTeX{}, \pTeX{}
+% and \upTeX{} should be consulted for details of the primitives.
+% These are named \cs[no-index]{tex_\meta{name}:D}, typically based
+% on the primitive's \meta{name} in \pdfTeX{} and omitting a leading
+% |pdf| when the primitive is not related to pdf output.
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3names} implementation}
+%
+% \begin{macrocode}
+%<*package&tex>
+% \end{macrocode}
+%
+% The prefix here is \texttt{kernel}. A few places need |@@| to be left
+% as is; this is obtained as |@@@@|.
+% \begin{macrocode}
+%<@@=kernel>
+% \end{macrocode}
+%
+% The code here simply renames all of the primitives to new, internal,
+% names.
+%
+% The \tn{let} primitive is renamed by hand first as it is essential for
+% the entire process to follow. This also uses \tn{global}, as that way
+% we avoid leaving an unneeded csname in the hash table.
+% \begin{macrocode}
+\let \tex_global:D \global
+\let \tex_let:D \let
+% \end{macrocode}
+%
+% Everything is inside a (rather long) group, which keeps
+% \cs{@@_primitive:NN} trapped.
+% \begin{macrocode}
+\begingroup
+% \end{macrocode}
+%
+% \begin{macro}{\@@_primitive:NN}
+% A temporary function to actually do the renaming.
+% \begin{macrocode}
+ \long \def \@@_primitive:NN #1#2
+ { \tex_global:D \tex_let:D #2 #1 }
+% \end{macrocode}
+%\end{macro}
+%
+% To allow extracting \enquote{just the names}, a bit of DocStrip fiddling.
+% \begin{macrocode}
+%</package&tex>
+%<*names|tex>
+%<*names|package>
+% \end{macrocode}
+%
+% In the current incarnation of this module, all \TeX{} primitives
+% are given a new name of the form |\tex_|\emph{oldname}|:D|.
+% But first three special cases which have symbolic original names.
+% These are given modified new names, so that they may be entered
+% without catcode tricks.
+% \begin{macrocode}
+ \@@_primitive:NN \ \tex_space:D
+ \@@_primitive:NN \/ \tex_italiccorrection:D
+ \@@_primitive:NN \- \tex_hyphen:D
+% \end{macrocode}
+%
+% Now all the other primitives.
+% \begin{macrocode}
+ \@@_primitive:NN \above \tex_above:D
+ \@@_primitive:NN \abovedisplayshortskip \tex_abovedisplayshortskip:D
+ \@@_primitive:NN \abovedisplayskip \tex_abovedisplayskip:D
+ \@@_primitive:NN \abovewithdelims \tex_abovewithdelims:D
+ \@@_primitive:NN \accent \tex_accent:D
+ \@@_primitive:NN \adjdemerits \tex_adjdemerits:D
+ \@@_primitive:NN \advance \tex_advance:D
+ \@@_primitive:NN \afterassignment \tex_afterassignment:D
+ \@@_primitive:NN \aftergroup \tex_aftergroup:D
+ \@@_primitive:NN \atop \tex_atop:D
+ \@@_primitive:NN \atopwithdelims \tex_atopwithdelims:D
+ \@@_primitive:NN \badness \tex_badness:D
+ \@@_primitive:NN \baselineskip \tex_baselineskip:D
+ \@@_primitive:NN \batchmode \tex_batchmode:D
+ \@@_primitive:NN \begingroup \tex_begingroup:D
+ \@@_primitive:NN \belowdisplayshortskip \tex_belowdisplayshortskip:D
+ \@@_primitive:NN \belowdisplayskip \tex_belowdisplayskip:D
+ \@@_primitive:NN \binoppenalty \tex_binoppenalty:D
+ \@@_primitive:NN \botmark \tex_botmark:D
+ \@@_primitive:NN \box \tex_box:D
+ \@@_primitive:NN \boxmaxdepth \tex_boxmaxdepth:D
+ \@@_primitive:NN \brokenpenalty \tex_brokenpenalty:D
+ \@@_primitive:NN \catcode \tex_catcode:D
+ \@@_primitive:NN \char \tex_char:D
+ \@@_primitive:NN \chardef \tex_chardef:D
+ \@@_primitive:NN \cleaders \tex_cleaders:D
+ \@@_primitive:NN \closein \tex_closein:D
+ \@@_primitive:NN \closeout \tex_closeout:D
+ \@@_primitive:NN \clubpenalty \tex_clubpenalty:D
+ \@@_primitive:NN \copy \tex_copy:D
+ \@@_primitive:NN \count \tex_count:D
+ \@@_primitive:NN \countdef \tex_countdef:D
+ \@@_primitive:NN \cr \tex_cr:D
+ \@@_primitive:NN \crcr \tex_crcr:D
+ \@@_primitive:NN \csname \tex_csname:D
+ \@@_primitive:NN \day \tex_day:D
+ \@@_primitive:NN \deadcycles \tex_deadcycles:D
+ \@@_primitive:NN \def \tex_def:D
+ \@@_primitive:NN \defaulthyphenchar \tex_defaulthyphenchar:D
+ \@@_primitive:NN \defaultskewchar \tex_defaultskewchar:D
+ \@@_primitive:NN \delcode \tex_delcode:D
+ \@@_primitive:NN \delimiter \tex_delimiter:D
+ \@@_primitive:NN \delimiterfactor \tex_delimiterfactor:D
+ \@@_primitive:NN \delimitershortfall \tex_delimitershortfall:D
+ \@@_primitive:NN \dimen \tex_dimen:D
+ \@@_primitive:NN \dimendef \tex_dimendef:D
+ \@@_primitive:NN \discretionary \tex_discretionary:D
+ \@@_primitive:NN \displayindent \tex_displayindent:D
+ \@@_primitive:NN \displaylimits \tex_displaylimits:D
+ \@@_primitive:NN \displaystyle \tex_displaystyle:D
+ \@@_primitive:NN \displaywidowpenalty \tex_displaywidowpenalty:D
+ \@@_primitive:NN \displaywidth \tex_displaywidth:D
+ \@@_primitive:NN \divide \tex_divide:D
+ \@@_primitive:NN \doublehyphendemerits \tex_doublehyphendemerits:D
+ \@@_primitive:NN \dp \tex_dp:D
+ \@@_primitive:NN \dump \tex_dump:D
+ \@@_primitive:NN \edef \tex_edef:D
+ \@@_primitive:NN \else \tex_else:D
+ \@@_primitive:NN \emergencystretch \tex_emergencystretch:D
+ \@@_primitive:NN \end \tex_end:D
+ \@@_primitive:NN \endcsname \tex_endcsname:D
+ \@@_primitive:NN \endgroup \tex_endgroup:D
+ \@@_primitive:NN \endinput \tex_endinput:D
+ \@@_primitive:NN \endlinechar \tex_endlinechar:D
+ \@@_primitive:NN \eqno \tex_eqno:D
+ \@@_primitive:NN \errhelp \tex_errhelp:D
+ \@@_primitive:NN \errmessage \tex_errmessage:D
+ \@@_primitive:NN \errorcontextlines \tex_errorcontextlines:D
+ \@@_primitive:NN \errorstopmode \tex_errorstopmode:D
+ \@@_primitive:NN \escapechar \tex_escapechar:D
+ \@@_primitive:NN \everycr \tex_everycr:D
+ \@@_primitive:NN \everydisplay \tex_everydisplay:D
+ \@@_primitive:NN \everyhbox \tex_everyhbox:D
+ \@@_primitive:NN \everyjob \tex_everyjob:D
+ \@@_primitive:NN \everymath \tex_everymath:D
+ \@@_primitive:NN \everypar \tex_everypar:D
+ \@@_primitive:NN \everyvbox \tex_everyvbox:D
+ \@@_primitive:NN \exhyphenpenalty \tex_exhyphenpenalty:D
+ \@@_primitive:NN \expandafter \tex_expandafter:D
+ \@@_primitive:NN \fam \tex_fam:D
+ \@@_primitive:NN \fi \tex_fi:D
+ \@@_primitive:NN \finalhyphendemerits \tex_finalhyphendemerits:D
+ \@@_primitive:NN \firstmark \tex_firstmark:D
+ \@@_primitive:NN \floatingpenalty \tex_floatingpenalty:D
+ \@@_primitive:NN \font \tex_font:D
+ \@@_primitive:NN \fontdimen \tex_fontdimen:D
+ \@@_primitive:NN \fontname \tex_fontname:D
+ \@@_primitive:NN \futurelet \tex_futurelet:D
+ \@@_primitive:NN \gdef \tex_gdef:D
+ \@@_primitive:NN \global \tex_global:D
+ \@@_primitive:NN \globaldefs \tex_globaldefs:D
+ \@@_primitive:NN \halign \tex_halign:D
+ \@@_primitive:NN \hangafter \tex_hangafter:D
+ \@@_primitive:NN \hangindent \tex_hangindent:D
+ \@@_primitive:NN \hbadness \tex_hbadness:D
+ \@@_primitive:NN \hbox \tex_hbox:D
+ \@@_primitive:NN \hfil \tex_hfil:D
+ \@@_primitive:NN \hfill \tex_hfill:D
+ \@@_primitive:NN \hfilneg \tex_hfilneg:D
+ \@@_primitive:NN \hfuzz \tex_hfuzz:D
+ \@@_primitive:NN \hoffset \tex_hoffset:D
+ \@@_primitive:NN \holdinginserts \tex_holdinginserts:D
+ \@@_primitive:NN \hrule \tex_hrule:D
+ \@@_primitive:NN \hsize \tex_hsize:D
+ \@@_primitive:NN \hskip \tex_hskip:D
+ \@@_primitive:NN \hss \tex_hss:D
+ \@@_primitive:NN \ht \tex_ht:D
+ \@@_primitive:NN \hyphenation \tex_hyphenation:D
+ \@@_primitive:NN \hyphenchar \tex_hyphenchar:D
+ \@@_primitive:NN \hyphenpenalty \tex_hyphenpenalty:D
+ \@@_primitive:NN \if \tex_if:D
+ \@@_primitive:NN \ifcase \tex_ifcase:D
+ \@@_primitive:NN \ifcat \tex_ifcat:D
+ \@@_primitive:NN \ifdim \tex_ifdim:D
+ \@@_primitive:NN \ifeof \tex_ifeof:D
+ \@@_primitive:NN \iffalse \tex_iffalse:D
+ \@@_primitive:NN \ifhbox \tex_ifhbox:D
+ \@@_primitive:NN \ifhmode \tex_ifhmode:D
+ \@@_primitive:NN \ifinner \tex_ifinner:D
+ \@@_primitive:NN \ifmmode \tex_ifmmode:D
+ \@@_primitive:NN \ifnum \tex_ifnum:D
+ \@@_primitive:NN \ifodd \tex_ifodd:D
+ \@@_primitive:NN \iftrue \tex_iftrue:D
+ \@@_primitive:NN \ifvbox \tex_ifvbox:D
+ \@@_primitive:NN \ifvmode \tex_ifvmode:D
+ \@@_primitive:NN \ifvoid \tex_ifvoid:D
+ \@@_primitive:NN \ifx \tex_ifx:D
+ \@@_primitive:NN \ignorespaces \tex_ignorespaces:D
+ \@@_primitive:NN \immediate \tex_immediate:D
+ \@@_primitive:NN \indent \tex_indent:D
+ \@@_primitive:NN \input \tex_input:D
+ \@@_primitive:NN \inputlineno \tex_inputlineno:D
+ \@@_primitive:NN \insert \tex_insert:D
+ \@@_primitive:NN \insertpenalties \tex_insertpenalties:D
+ \@@_primitive:NN \interlinepenalty \tex_interlinepenalty:D
+ \@@_primitive:NN \jobname \tex_jobname:D
+ \@@_primitive:NN \kern \tex_kern:D
+ \@@_primitive:NN \language \tex_language:D
+ \@@_primitive:NN \lastbox \tex_lastbox:D
+ \@@_primitive:NN \lastkern \tex_lastkern:D
+ \@@_primitive:NN \lastpenalty \tex_lastpenalty:D
+ \@@_primitive:NN \lastskip \tex_lastskip:D
+ \@@_primitive:NN \lccode \tex_lccode:D
+ \@@_primitive:NN \leaders \tex_leaders:D
+ \@@_primitive:NN \left \tex_left:D
+ \@@_primitive:NN \lefthyphenmin \tex_lefthyphenmin:D
+ \@@_primitive:NN \leftskip \tex_leftskip:D
+ \@@_primitive:NN \leqno \tex_leqno:D
+ \@@_primitive:NN \let \tex_let:D
+ \@@_primitive:NN \limits \tex_limits:D
+ \@@_primitive:NN \linepenalty \tex_linepenalty:D
+ \@@_primitive:NN \lineskip \tex_lineskip:D
+ \@@_primitive:NN \lineskiplimit \tex_lineskiplimit:D
+ \@@_primitive:NN \long \tex_long:D
+ \@@_primitive:NN \looseness \tex_looseness:D
+ \@@_primitive:NN \lower \tex_lower:D
+ \@@_primitive:NN \lowercase \tex_lowercase:D
+ \@@_primitive:NN \mag \tex_mag:D
+ \@@_primitive:NN \mark \tex_mark:D
+ \@@_primitive:NN \mathaccent \tex_mathaccent:D
+ \@@_primitive:NN \mathbin \tex_mathbin:D
+ \@@_primitive:NN \mathchar \tex_mathchar:D
+ \@@_primitive:NN \mathchardef \tex_mathchardef:D
+ \@@_primitive:NN \mathchoice \tex_mathchoice:D
+ \@@_primitive:NN \mathclose \tex_mathclose:D
+ \@@_primitive:NN \mathcode \tex_mathcode:D
+ \@@_primitive:NN \mathinner \tex_mathinner:D
+ \@@_primitive:NN \mathop \tex_mathop:D
+ \@@_primitive:NN \mathopen \tex_mathopen:D
+ \@@_primitive:NN \mathord \tex_mathord:D
+ \@@_primitive:NN \mathpunct \tex_mathpunct:D
+ \@@_primitive:NN \mathrel \tex_mathrel:D
+ \@@_primitive:NN \mathsurround \tex_mathsurround:D
+ \@@_primitive:NN \maxdeadcycles \tex_maxdeadcycles:D
+ \@@_primitive:NN \maxdepth \tex_maxdepth:D
+ \@@_primitive:NN \meaning \tex_meaning:D
+ \@@_primitive:NN \medmuskip \tex_medmuskip:D
+ \@@_primitive:NN \message \tex_message:D
+ \@@_primitive:NN \mkern \tex_mkern:D
+ \@@_primitive:NN \month \tex_month:D
+ \@@_primitive:NN \moveleft \tex_moveleft:D
+ \@@_primitive:NN \moveright \tex_moveright:D
+ \@@_primitive:NN \mskip \tex_mskip:D
+ \@@_primitive:NN \multiply \tex_multiply:D
+ \@@_primitive:NN \muskip \tex_muskip:D
+ \@@_primitive:NN \muskipdef \tex_muskipdef:D
+ \@@_primitive:NN \newlinechar \tex_newlinechar:D
+ \@@_primitive:NN \noalign \tex_noalign:D
+ \@@_primitive:NN \noboundary \tex_noboundary:D
+ \@@_primitive:NN \noexpand \tex_noexpand:D
+ \@@_primitive:NN \noindent \tex_noindent:D
+ \@@_primitive:NN \nolimits \tex_nolimits:D
+ \@@_primitive:NN \nonscript \tex_nonscript:D
+ \@@_primitive:NN \nonstopmode \tex_nonstopmode:D
+ \@@_primitive:NN \nulldelimiterspace \tex_nulldelimiterspace:D
+ \@@_primitive:NN \nullfont \tex_nullfont:D
+ \@@_primitive:NN \number \tex_number:D
+ \@@_primitive:NN \omit \tex_omit:D
+ \@@_primitive:NN \openin \tex_openin:D
+ \@@_primitive:NN \openout \tex_openout:D
+ \@@_primitive:NN \or \tex_or:D
+ \@@_primitive:NN \outer \tex_outer:D
+ \@@_primitive:NN \output \tex_output:D
+ \@@_primitive:NN \outputpenalty \tex_outputpenalty:D
+ \@@_primitive:NN \over \tex_over:D
+ \@@_primitive:NN \overfullrule \tex_overfullrule:D
+ \@@_primitive:NN \overline \tex_overline:D
+ \@@_primitive:NN \overwithdelims \tex_overwithdelims:D
+ \@@_primitive:NN \pagedepth \tex_pagedepth:D
+ \@@_primitive:NN \pagefilllstretch \tex_pagefilllstretch:D
+ \@@_primitive:NN \pagefillstretch \tex_pagefillstretch:D
+ \@@_primitive:NN \pagefilstretch \tex_pagefilstretch:D
+ \@@_primitive:NN \pagegoal \tex_pagegoal:D
+ \@@_primitive:NN \pageshrink \tex_pageshrink:D
+ \@@_primitive:NN \pagestretch \tex_pagestretch:D
+ \@@_primitive:NN \pagetotal \tex_pagetotal:D
+ \@@_primitive:NN \par \tex_par:D
+ \@@_primitive:NN \parfillskip \tex_parfillskip:D
+ \@@_primitive:NN \parindent \tex_parindent:D
+ \@@_primitive:NN \parshape \tex_parshape:D
+ \@@_primitive:NN \parskip \tex_parskip:D
+ \@@_primitive:NN \patterns \tex_patterns:D
+ \@@_primitive:NN \pausing \tex_pausing:D
+ \@@_primitive:NN \penalty \tex_penalty:D
+ \@@_primitive:NN \postdisplaypenalty \tex_postdisplaypenalty:D
+ \@@_primitive:NN \predisplaypenalty \tex_predisplaypenalty:D
+ \@@_primitive:NN \predisplaysize \tex_predisplaysize:D
+ \@@_primitive:NN \pretolerance \tex_pretolerance:D
+ \@@_primitive:NN \prevdepth \tex_prevdepth:D
+ \@@_primitive:NN \prevgraf \tex_prevgraf:D
+ \@@_primitive:NN \radical \tex_radical:D
+ \@@_primitive:NN \raise \tex_raise:D
+ \@@_primitive:NN \read \tex_read:D
+ \@@_primitive:NN \relax \tex_relax:D
+ \@@_primitive:NN \relpenalty \tex_relpenalty:D
+ \@@_primitive:NN \right \tex_right:D
+ \@@_primitive:NN \righthyphenmin \tex_righthyphenmin:D
+ \@@_primitive:NN \rightskip \tex_rightskip:D
+ \@@_primitive:NN \romannumeral \tex_romannumeral:D
+ \@@_primitive:NN \scriptfont \tex_scriptfont:D
+ \@@_primitive:NN \scriptscriptfont \tex_scriptscriptfont:D
+ \@@_primitive:NN \scriptscriptstyle \tex_scriptscriptstyle:D
+ \@@_primitive:NN \scriptspace \tex_scriptspace:D
+ \@@_primitive:NN \scriptstyle \tex_scriptstyle:D
+ \@@_primitive:NN \scrollmode \tex_scrollmode:D
+ \@@_primitive:NN \setbox \tex_setbox:D
+ \@@_primitive:NN \setlanguage \tex_setlanguage:D
+ \@@_primitive:NN \sfcode \tex_sfcode:D
+ \@@_primitive:NN \shipout \tex_shipout:D
+ \@@_primitive:NN \show \tex_show:D
+ \@@_primitive:NN \showbox \tex_showbox:D
+ \@@_primitive:NN \showboxbreadth \tex_showboxbreadth:D
+ \@@_primitive:NN \showboxdepth \tex_showboxdepth:D
+ \@@_primitive:NN \showlists \tex_showlists:D
+ \@@_primitive:NN \showthe \tex_showthe:D
+ \@@_primitive:NN \skewchar \tex_skewchar:D
+ \@@_primitive:NN \skip \tex_skip:D
+ \@@_primitive:NN \skipdef \tex_skipdef:D
+ \@@_primitive:NN \spacefactor \tex_spacefactor:D
+ \@@_primitive:NN \spaceskip \tex_spaceskip:D
+ \@@_primitive:NN \span \tex_span:D
+ \@@_primitive:NN \special \tex_special:D
+ \@@_primitive:NN \splitbotmark \tex_splitbotmark:D
+ \@@_primitive:NN \splitfirstmark \tex_splitfirstmark:D
+ \@@_primitive:NN \splitmaxdepth \tex_splitmaxdepth:D
+ \@@_primitive:NN \splittopskip \tex_splittopskip:D
+ \@@_primitive:NN \string \tex_string:D
+ \@@_primitive:NN \tabskip \tex_tabskip:D
+ \@@_primitive:NN \textfont \tex_textfont:D
+ \@@_primitive:NN \textstyle \tex_textstyle:D
+ \@@_primitive:NN \the \tex_the:D
+ \@@_primitive:NN \thickmuskip \tex_thickmuskip:D
+ \@@_primitive:NN \thinmuskip \tex_thinmuskip:D
+ \@@_primitive:NN \time \tex_time:D
+ \@@_primitive:NN \toks \tex_toks:D
+ \@@_primitive:NN \toksdef \tex_toksdef:D
+ \@@_primitive:NN \tolerance \tex_tolerance:D
+ \@@_primitive:NN \topmark \tex_topmark:D
+ \@@_primitive:NN \topskip \tex_topskip:D
+ \@@_primitive:NN \tracingcommands \tex_tracingcommands:D
+ \@@_primitive:NN \tracinglostchars \tex_tracinglostchars:D
+ \@@_primitive:NN \tracingmacros \tex_tracingmacros:D
+ \@@_primitive:NN \tracingonline \tex_tracingonline:D
+ \@@_primitive:NN \tracingoutput \tex_tracingoutput:D
+ \@@_primitive:NN \tracingpages \tex_tracingpages:D
+ \@@_primitive:NN \tracingparagraphs \tex_tracingparagraphs:D
+ \@@_primitive:NN \tracingrestores \tex_tracingrestores:D
+ \@@_primitive:NN \tracingstats \tex_tracingstats:D
+ \@@_primitive:NN \uccode \tex_uccode:D
+ \@@_primitive:NN \uchyph \tex_uchyph:D
+ \@@_primitive:NN \underline \tex_underline:D
+ \@@_primitive:NN \unhbox \tex_unhbox:D
+ \@@_primitive:NN \unhcopy \tex_unhcopy:D
+ \@@_primitive:NN \unkern \tex_unkern:D
+ \@@_primitive:NN \unpenalty \tex_unpenalty:D
+ \@@_primitive:NN \unskip \tex_unskip:D
+ \@@_primitive:NN \unvbox \tex_unvbox:D
+ \@@_primitive:NN \unvcopy \tex_unvcopy:D
+ \@@_primitive:NN \uppercase \tex_uppercase:D
+ \@@_primitive:NN \vadjust \tex_vadjust:D
+ \@@_primitive:NN \valign \tex_valign:D
+ \@@_primitive:NN \vbadness \tex_vbadness:D
+ \@@_primitive:NN \vbox \tex_vbox:D
+ \@@_primitive:NN \vcenter \tex_vcenter:D
+ \@@_primitive:NN \vfil \tex_vfil:D
+ \@@_primitive:NN \vfill \tex_vfill:D
+ \@@_primitive:NN \vfilneg \tex_vfilneg:D
+ \@@_primitive:NN \vfuzz \tex_vfuzz:D
+ \@@_primitive:NN \voffset \tex_voffset:D
+ \@@_primitive:NN \vrule \tex_vrule:D
+ \@@_primitive:NN \vsize \tex_vsize:D
+ \@@_primitive:NN \vskip \tex_vskip:D
+ \@@_primitive:NN \vsplit \tex_vsplit:D
+ \@@_primitive:NN \vss \tex_vss:D
+ \@@_primitive:NN \vtop \tex_vtop:D
+ \@@_primitive:NN \wd \tex_wd:D
+ \@@_primitive:NN \widowpenalty \tex_widowpenalty:D
+ \@@_primitive:NN \write \tex_write:D
+ \@@_primitive:NN \xdef \tex_xdef:D
+ \@@_primitive:NN \xleaders \tex_xleaders:D
+ \@@_primitive:NN \xspaceskip \tex_xspaceskip:D
+ \@@_primitive:NN \year \tex_year:D
+% \end{macrocode}
+% Primitives introduced by \eTeX{}.
+% \begin{macrocode}
+ \@@_primitive:NN \beginL \tex_beginL:D
+ \@@_primitive:NN \beginR \tex_beginR:D
+ \@@_primitive:NN \botmarks \tex_botmarks:D
+ \@@_primitive:NN \clubpenalties \tex_clubpenalties:D
+ \@@_primitive:NN \currentgrouplevel \tex_currentgrouplevel:D
+ \@@_primitive:NN \currentgrouptype \tex_currentgrouptype:D
+ \@@_primitive:NN \currentifbranch \tex_currentifbranch:D
+ \@@_primitive:NN \currentiflevel \tex_currentiflevel:D
+ \@@_primitive:NN \currentiftype \tex_currentiftype:D
+ \@@_primitive:NN \detokenize \tex_detokenize:D
+ \@@_primitive:NN \dimexpr \tex_dimexpr:D
+ \@@_primitive:NN \displaywidowpenalties \tex_displaywidowpenalties:D
+ \@@_primitive:NN \endL \tex_endL:D
+ \@@_primitive:NN \endR \tex_endR:D
+ \@@_primitive:NN \eTeXrevision \tex_eTeXrevision:D
+ \@@_primitive:NN \eTeXversion \tex_eTeXversion:D
+ \@@_primitive:NN \everyeof \tex_everyeof:D
+ \@@_primitive:NN \firstmarks \tex_firstmarks:D
+ \@@_primitive:NN \fontchardp \tex_fontchardp:D
+ \@@_primitive:NN \fontcharht \tex_fontcharht:D
+ \@@_primitive:NN \fontcharic \tex_fontcharic:D
+ \@@_primitive:NN \fontcharwd \tex_fontcharwd:D
+ \@@_primitive:NN \glueexpr \tex_glueexpr:D
+ \@@_primitive:NN \glueshrink \tex_glueshrink:D
+ \@@_primitive:NN \glueshrinkorder \tex_glueshrinkorder:D
+ \@@_primitive:NN \gluestretch \tex_gluestretch:D
+ \@@_primitive:NN \gluestretchorder \tex_gluestretchorder:D
+ \@@_primitive:NN \gluetomu \tex_gluetomu:D
+ \@@_primitive:NN \ifcsname \tex_ifcsname:D
+ \@@_primitive:NN \ifdefined \tex_ifdefined:D
+ \@@_primitive:NN \iffontchar \tex_iffontchar:D
+ \@@_primitive:NN \interactionmode \tex_interactionmode:D
+ \@@_primitive:NN \interlinepenalties \tex_interlinepenalties:D
+ \@@_primitive:NN \lastlinefit \tex_lastlinefit:D
+ \@@_primitive:NN \lastnodetype \tex_lastnodetype:D
+ \@@_primitive:NN \marks \tex_marks:D
+ \@@_primitive:NN \middle \tex_middle:D
+ \@@_primitive:NN \muexpr \tex_muexpr:D
+ \@@_primitive:NN \mutoglue \tex_mutoglue:D
+ \@@_primitive:NN \numexpr \tex_numexpr:D
+ \@@_primitive:NN \pagediscards \tex_pagediscards:D
+ \@@_primitive:NN \parshapedimen \tex_parshapedimen:D
+ \@@_primitive:NN \parshapeindent \tex_parshapeindent:D
+ \@@_primitive:NN \parshapelength \tex_parshapelength:D
+ \@@_primitive:NN \predisplaydirection \tex_predisplaydirection:D
+ \@@_primitive:NN \protected \tex_protected:D
+ \@@_primitive:NN \readline \tex_readline:D
+ \@@_primitive:NN \savinghyphcodes \tex_savinghyphcodes:D
+ \@@_primitive:NN \savingvdiscards \tex_savingvdiscards:D
+ \@@_primitive:NN \scantokens \tex_scantokens:D
+ \@@_primitive:NN \showgroups \tex_showgroups:D
+ \@@_primitive:NN \showifs \tex_showifs:D
+ \@@_primitive:NN \showtokens \tex_showtokens:D
+ \@@_primitive:NN \splitbotmarks \tex_splitbotmarks:D
+ \@@_primitive:NN \splitdiscards \tex_splitdiscards:D
+ \@@_primitive:NN \splitfirstmarks \tex_splitfirstmarks:D
+ \@@_primitive:NN \TeXXeTstate \tex_TeXXeTstate:D
+ \@@_primitive:NN \topmarks \tex_topmarks:D
+ \@@_primitive:NN \tracingassigns \tex_tracingassigns:D
+ \@@_primitive:NN \tracinggroups \tex_tracinggroups:D
+ \@@_primitive:NN \tracingifs \tex_tracingifs:D
+ \@@_primitive:NN \tracingnesting \tex_tracingnesting:D
+ \@@_primitive:NN \tracingscantokens \tex_tracingscantokens:D
+ \@@_primitive:NN \unexpanded \tex_unexpanded:D
+ \@@_primitive:NN \unless \tex_unless:D
+ \@@_primitive:NN \widowpenalties \tex_widowpenalties:D
+% \end{macrocode}
+% Post-\eTeX{} primitives do not always end up with the same name in all
+% engines, if indeed they are available cross-engine anyway. We therefore
+% take the approach of preferring the shortest name that makes sense. First,
+% we deal with the primitives introduced by \pdfTeX{} which directly
+% relate to PDF output: these are copied with the names unchanged.
+% \begin{macrocode}
+ \@@_primitive:NN \pdfannot \tex_pdfannot:D
+ \@@_primitive:NN \pdfcatalog \tex_pdfcatalog:D
+ \@@_primitive:NN \pdfcompresslevel \tex_pdfcompresslevel:D
+ \@@_primitive:NN \pdfcolorstack \tex_pdfcolorstack:D
+ \@@_primitive:NN \pdfcolorstackinit \tex_pdfcolorstackinit:D
+ \@@_primitive:NN \pdfdecimaldigits \tex_pdfdecimaldigits:D
+ \@@_primitive:NN \pdfdest \tex_pdfdest:D
+ \@@_primitive:NN \pdfdestmargin \tex_pdfdestmargin:D
+ \@@_primitive:NN \pdfendlink \tex_pdfendlink:D
+ \@@_primitive:NN \pdfendthread \tex_pdfendthread:D
+ \@@_primitive:NN \pdffakespace \tex_pdffakespace:D
+ \@@_primitive:NN \pdffontattr \tex_pdffontattr:D
+ \@@_primitive:NN \pdffontname \tex_pdffontname:D
+ \@@_primitive:NN \pdffontobjnum \tex_pdffontobjnum:D
+ \@@_primitive:NN \pdfgamma \tex_pdfgamma:D
+ \@@_primitive:NN \pdfgentounicode \tex_pdfgentounicode:D
+ \@@_primitive:NN \pdfglyphtounicode \tex_pdfglyphtounicode:D
+ \@@_primitive:NN \pdfhorigin \tex_pdfhorigin:D
+ \@@_primitive:NN \pdfimageapplygamma \tex_pdfimageapplygamma:D
+ \@@_primitive:NN \pdfimagegamma \tex_pdfimagegamma:D
+ \@@_primitive:NN \pdfimagehicolor \tex_pdfimagehicolor:D
+ \@@_primitive:NN \pdfimageresolution \tex_pdfimageresolution:D
+ \@@_primitive:NN \pdfincludechars \tex_pdfincludechars:D
+ \@@_primitive:NN \pdfinclusioncopyfonts \tex_pdfinclusioncopyfonts:D
+ \@@_primitive:NN \pdfinclusionerrorlevel
+ \tex_pdfinclusionerrorlevel:D
+ \@@_primitive:NN \pdfinfo \tex_pdfinfo:D
+ \@@_primitive:NN \pdfinfoomitdate \tex_pdfinfoomitdate:D
+ \@@_primitive:NN \pdfinterwordspaceoff \tex_pdfinterwordspaceoff:D
+ \@@_primitive:NN \pdfinterwordspaceon \tex_pdfinterwordspaceon:D
+ \@@_primitive:NN \pdflastannot \tex_pdflastannot:D
+ \@@_primitive:NN \pdflastlink \tex_pdflastlink:D
+ \@@_primitive:NN \pdflastobj \tex_pdflastobj:D
+ \@@_primitive:NN \pdflastxform \tex_pdflastxform:D
+ \@@_primitive:NN \pdflastximage \tex_pdflastximage:D
+ \@@_primitive:NN \pdflastximagecolordepth
+ \tex_pdflastximagecolordepth:D
+ \@@_primitive:NN \pdflastximagepages \tex_pdflastximagepages:D
+ \@@_primitive:NN \pdflinkmargin \tex_pdflinkmargin:D
+ \@@_primitive:NN \pdfliteral \tex_pdfliteral:D
+ \@@_primitive:NN \pdfmapfile \tex_pdfmapfile:D
+ \@@_primitive:NN \pdfmapline \tex_pdfmapline:D
+ \@@_primitive:NN \pdfmajorversion \tex_pdfmajorversion:D
+ \@@_primitive:NN \pdfminorversion \tex_pdfminorversion:D
+ \@@_primitive:NN \pdfnames \tex_pdfnames:D
+ \@@_primitive:NN \pdfnobuiltintounicode \tex_pdfnobuiltintounicode:D
+ \@@_primitive:NN \pdfobj \tex_pdfobj:D
+ \@@_primitive:NN \pdfobjcompresslevel \tex_pdfobjcompresslevel:D
+ \@@_primitive:NN \pdfomitcharset \tex_pdfomitcharset:D
+ \@@_primitive:NN \pdfoutline \tex_pdfoutline:D
+ \@@_primitive:NN \pdfoutput \tex_pdfoutput:D
+ \@@_primitive:NN \pdfpageattr \tex_pdfpageattr:D
+ \@@_primitive:NN \pdfpagesattr \tex_pdfpagesattr:D
+ \@@_primitive:NN \pdfpagebox \tex_pdfpagebox:D
+ \@@_primitive:NN \pdfpageref \tex_pdfpageref:D
+ \@@_primitive:NN \pdfpageresources \tex_pdfpageresources:D
+ \@@_primitive:NN \pdfpagesattr \tex_pdfpagesattr:D
+ \@@_primitive:NN \pdfrefobj \tex_pdfrefobj:D
+ \@@_primitive:NN \pdfrefxform \tex_pdfrefxform:D
+ \@@_primitive:NN \pdfrefximage \tex_pdfrefximage:D
+ \@@_primitive:NN \pdfrestore \tex_pdfrestore:D
+ \@@_primitive:NN \pdfretval \tex_pdfretval:D
+ \@@_primitive:NN \pdfrunninglinkoff \tex_pdfrunninglinkoff:D
+ \@@_primitive:NN \pdfrunninglinkon \tex_pdfrunninglinkon:D
+ \@@_primitive:NN \pdfsave \tex_pdfsave:D
+ \@@_primitive:NN \pdfsetmatrix \tex_pdfsetmatrix:D
+ \@@_primitive:NN \pdfstartlink \tex_pdfstartlink:D
+ \@@_primitive:NN \pdfstartthread \tex_pdfstartthread:D
+ \@@_primitive:NN \pdfsuppressptexinfo \tex_pdfsuppressptexinfo:D
+ \@@_primitive:NN \pdfsuppresswarningdupdest
+ \tex_pdfsuppresswarningdupdest:D
+ \@@_primitive:NN \pdfsuppresswarningdupmap
+ \tex_pdfsuppresswarningdupmap:D
+ \@@_primitive:NN \pdfsuppresswarningpagegroup
+ \tex_pdfsuppresswarningpagegroup:D
+ \@@_primitive:NN \pdfthread \tex_pdfthread:D
+ \@@_primitive:NN \pdfthreadmargin \tex_pdfthreadmargin:D
+ \@@_primitive:NN \pdftrailer \tex_pdftrailer:D
+ \@@_primitive:NN \pdftrailerid \tex_pdftrailerid:D
+ \@@_primitive:NN \pdfuniqueresname \tex_pdfuniqueresname:D
+ \@@_primitive:NN \pdfvorigin \tex_pdfvorigin:D
+ \@@_primitive:NN \pdfxform \tex_pdfxform:D
+ \@@_primitive:NN \pdfxformname \tex_pdfxformname:D
+ \@@_primitive:NN \pdfximage \tex_pdfximage:D
+ \@@_primitive:NN \pdfximagebbox \tex_pdfximagebbox:D
+% \end{macrocode}
+% These are not related to PDF output and either already appear in other
+% engines without the |\pdf| prefix, or might reasonably do so at some
+% future stage. We therefore drop the leading |pdf| here.
+% \begin{macrocode}
+ \@@_primitive:NN \ifpdfabsdim \tex_ifabsdim:D
+ \@@_primitive:NN \ifpdfabsnum \tex_ifabsnum:D
+ \@@_primitive:NN \ifpdfprimitive \tex_ifprimitive:D
+ \@@_primitive:NN \pdfadjustinterwordglue
+ \tex_adjustinterwordglue:D
+ \@@_primitive:NN \pdfadjustspacing \tex_adjustspacing:D
+ \@@_primitive:NN \pdfappendkern \tex_appendkern:D
+ \@@_primitive:NN \pdfcopyfont \tex_copyfont:D
+ \@@_primitive:NN \pdfcreationdate \tex_creationdate:D
+ \@@_primitive:NN \pdfdraftmode \tex_draftmode:D
+ \@@_primitive:NN \pdfeachlinedepth \tex_eachlinedepth:D
+ \@@_primitive:NN \pdfeachlineheight \tex_eachlineheight:D
+ \@@_primitive:NN \pdfelapsedtime \tex_elapsedtime:D
+ \@@_primitive:NN \pdfescapehex \tex_escapehex:D
+ \@@_primitive:NN \pdfescapename \tex_escapename:D
+ \@@_primitive:NN \pdfescapestring \tex_escapestring:D
+ \@@_primitive:NN \pdffirstlineheight \tex_firstlineheight:D
+ \@@_primitive:NN \pdffontexpand \tex_fontexpand:D
+ \@@_primitive:NN \pdffontsize \tex_fontsize:D
+ \@@_primitive:NN \pdfignoreddimen \tex_ignoreddimen:D
+ \@@_primitive:NN \pdfinsertht \tex_insertht:D
+ \@@_primitive:NN \pdflastlinedepth \tex_lastlinedepth:D
+ \@@_primitive:NN \pdflastmatch \tex_lastmatch:D
+ \@@_primitive:NN \pdflastxpos \tex_lastxpos:D
+ \@@_primitive:NN \pdflastypos \tex_lastypos:D
+ \@@_primitive:NN \pdfmatch \tex_match:D
+ \@@_primitive:NN \pdfnoligatures \tex_noligatures:D
+ \@@_primitive:NN \pdfnormaldeviate \tex_normaldeviate:D
+ \@@_primitive:NN \pdfpageheight \tex_pageheight:D
+ \@@_primitive:NN \pdfpagewidth \tex_pagewidth:D
+ \@@_primitive:NN \pdfpkmode \tex_pkmode:D
+ \@@_primitive:NN \pdfpkresolution \tex_pkresolution:D
+ \@@_primitive:NN \pdfprimitive \tex_primitive:D
+ \@@_primitive:NN \pdfprependkern \tex_prependkern:D
+ \@@_primitive:NN \pdfprotrudechars \tex_protrudechars:D
+ \@@_primitive:NN \pdfpxdimen \tex_pxdimen:D
+ \@@_primitive:NN \pdfrandomseed \tex_randomseed:D
+ \@@_primitive:NN \pdfresettimer \tex_resettimer:D
+ \@@_primitive:NN \pdfsavepos \tex_savepos:D
+ \@@_primitive:NN \pdfsetrandomseed \tex_setrandomseed:D
+ \@@_primitive:NN \pdfshellescape \tex_shellescape:D
+ \@@_primitive:NN \pdftracingfonts \tex_tracingfonts:D
+ \@@_primitive:NN \pdfunescapehex \tex_unescapehex:D
+ \@@_primitive:NN \pdfuniformdeviate \tex_uniformdeviate:D
+% \end{macrocode}
+% The version primitives are not related to PDF mode but are
+% \pdfTeX{}-specific, so again are carried forward unchanged.
+% \begin{macrocode}
+ \@@_primitive:NN \pdftexbanner \tex_pdftexbanner:D
+ \@@_primitive:NN \pdftexrevision \tex_pdftexrevision:D
+ \@@_primitive:NN \pdftexversion \tex_pdftexversion:D
+% \end{macrocode}
+% These ones appear in \pdfTeX{} but don't have |pdf| in the name at all:
+% no decisions to make.
+% \begin{macrocode}
+ \@@_primitive:NN \efcode \tex_efcode:D
+ \@@_primitive:NN \ifincsname \tex_ifincsname:D
+ \@@_primitive:NN \knaccode \tex_knaccode:D
+ \@@_primitive:NN \knbccode \tex_knbccode:D
+ \@@_primitive:NN \knbscode \tex_knbscode:D
+ \@@_primitive:NN \leftmarginkern \tex_leftmarginkern:D
+ \@@_primitive:NN \letterspacefont \tex_letterspacefont:D
+ \@@_primitive:NN \lpcode \tex_lpcode:D
+ \@@_primitive:NN \quitvmode \tex_quitvmode:D
+ \@@_primitive:NN \rightmarginkern \tex_rightmarginkern:D
+ \@@_primitive:NN \rpcode \tex_rpcode:D
+ \@@_primitive:NN \shbscode \tex_shbscode:D
+ \@@_primitive:NN \stbscode \tex_stbscode:D
+ \@@_primitive:NN \synctex \tex_synctex:D
+ \@@_primitive:NN \tagcode \tex_tagcode:D
+% \end{macrocode}
+% Post \pdfTeX{} primitive availability gets more complex. Both \XeTeX{} and
+% \LuaTeX{} have varying names for some primitives from \pdfTeX{}. Particularly
+% for \LuaTeX{} tracking all of that would be hard. Instead, we now check that
+% we only save primitives if they actually exist.
+% \begin{macrocode}
+%</names|package>
+%<*package>
+ \tex_long:D \tex_def:D \use_ii:nn #1#2 {#2}
+ \tex_long:D \tex_def:D \use_none:n #1 { }
+ \tex_long:D \tex_def:D \@@_primitive:NN #1#2
+ {
+ \tex_ifdefined:D #1
+ \tex_expandafter:D \use_ii:nn
+ \tex_fi:D
+ \use_none:n { \tex_global:D \tex_let:D #2 #1 }
+ }
+%</package>
+%<*names|package>
+% \end{macrocode}
+% Some \pdfTeX{} primitives are handled here because they got dropped in
+% \LuaTeX{} but the corresponding internal names are emulated later. The
+% Lua code is already loaded at this point, so we shouldn't overwrite them.
+% \begin{macrocode}
+ \@@_primitive:NN \pdfstrcmp \tex_strcmp:D
+ \@@_primitive:NN \pdffilesize \tex_filesize:D
+ \@@_primitive:NN \pdfmdfivesum \tex_mdfivesum:D
+ \@@_primitive:NN \pdffilemoddate \tex_filemoddate:D
+ \@@_primitive:NN \pdffiledump \tex_filedump:D
+% \end{macrocode}
+% \XeTeX{}-specific primitives. Note that \XeTeX{}'s \tn{strcmp} is
+% handled earlier and is \enquote{rolled up} into \tn{pdfstrcmp}.
+% A few cross-compatibility names which lack
+% the |pdf| of the original are handled later.
+% \begin{macrocode}
+ \@@_primitive:NN \suppressfontnotfounderror
+ \tex_suppressfontnotfounderror:D
+ \@@_primitive:NN \XeTeXcharclass \tex_XeTeXcharclass:D
+ \@@_primitive:NN \XeTeXcharglyph \tex_XeTeXcharglyph:D
+ \@@_primitive:NN \XeTeXcountfeatures \tex_XeTeXcountfeatures:D
+ \@@_primitive:NN \XeTeXcountglyphs \tex_XeTeXcountglyphs:D
+ \@@_primitive:NN \XeTeXcountselectors \tex_XeTeXcountselectors:D
+ \@@_primitive:NN \XeTeXcountvariations \tex_XeTeXcountvariations:D
+ \@@_primitive:NN \XeTeXdefaultencoding \tex_XeTeXdefaultencoding:D
+ \@@_primitive:NN \XeTeXdashbreakstate \tex_XeTeXdashbreakstate:D
+ \@@_primitive:NN \XeTeXfeaturecode \tex_XeTeXfeaturecode:D
+ \@@_primitive:NN \XeTeXfeaturename \tex_XeTeXfeaturename:D
+ \@@_primitive:NN \XeTeXfindfeaturebyname
+ \tex_XeTeXfindfeaturebyname:D
+ \@@_primitive:NN \XeTeXfindselectorbyname
+ \tex_XeTeXfindselectorbyname:D
+ \@@_primitive:NN \XeTeXfindvariationbyname
+ \tex_XeTeXfindvariationbyname:D
+ \@@_primitive:NN \XeTeXfirstfontchar \tex_XeTeXfirstfontchar:D
+ \@@_primitive:NN \XeTeXfonttype \tex_XeTeXfonttype:D
+ \@@_primitive:NN \XeTeXgenerateactualtext
+ \tex_XeTeXgenerateactualtext:D
+ \@@_primitive:NN \XeTeXglyph \tex_XeTeXglyph:D
+ \@@_primitive:NN \XeTeXglyphbounds \tex_XeTeXglyphbounds:D
+ \@@_primitive:NN \XeTeXglyphindex \tex_XeTeXglyphindex:D
+ \@@_primitive:NN \XeTeXglyphname \tex_XeTeXglyphname:D
+ \@@_primitive:NN \XeTeXinputencoding \tex_XeTeXinputencoding:D
+ \@@_primitive:NN \XeTeXinputnormalization
+ \tex_XeTeXinputnormalization:D
+ \@@_primitive:NN \XeTeXinterchartokenstate
+ \tex_XeTeXinterchartokenstate:D
+ \@@_primitive:NN \XeTeXinterchartoks \tex_XeTeXinterchartoks:D
+ \@@_primitive:NN \XeTeXisdefaultselector
+ \tex_XeTeXisdefaultselector:D
+ \@@_primitive:NN \XeTeXisexclusivefeature
+ \tex_XeTeXisexclusivefeature:D
+ \@@_primitive:NN \XeTeXlastfontchar \tex_XeTeXlastfontchar:D
+ \@@_primitive:NN \XeTeXlinebreakskip \tex_XeTeXlinebreakskip:D
+ \@@_primitive:NN \XeTeXlinebreaklocale \tex_XeTeXlinebreaklocale:D
+ \@@_primitive:NN \XeTeXlinebreakpenalty \tex_XeTeXlinebreakpenalty:D
+ \@@_primitive:NN \XeTeXOTcountfeatures \tex_XeTeXOTcountfeatures:D
+ \@@_primitive:NN \XeTeXOTcountlanguages \tex_XeTeXOTcountlanguages:D
+ \@@_primitive:NN \XeTeXOTcountscripts \tex_XeTeXOTcountscripts:D
+ \@@_primitive:NN \XeTeXOTfeaturetag \tex_XeTeXOTfeaturetag:D
+ \@@_primitive:NN \XeTeXOTlanguagetag \tex_XeTeXOTlanguagetag:D
+ \@@_primitive:NN \XeTeXOTscripttag \tex_XeTeXOTscripttag:D
+ \@@_primitive:NN \XeTeXpdffile \tex_XeTeXpdffile:D
+ \@@_primitive:NN \XeTeXpdfpagecount \tex_XeTeXpdfpagecount:D
+ \@@_primitive:NN \XeTeXpicfile \tex_XeTeXpicfile:D
+ \@@_primitive:NN \XeTeXrevision \tex_XeTeXrevision:D
+ \@@_primitive:NN \XeTeXselectorname \tex_XeTeXselectorname:D
+ \@@_primitive:NN \XeTeXtracingfonts \tex_XeTeXtracingfonts:D
+ \@@_primitive:NN \XeTeXupwardsmode \tex_XeTeXupwardsmode:D
+ \@@_primitive:NN \XeTeXuseglyphmetrics \tex_XeTeXuseglyphmetrics:D
+ \@@_primitive:NN \XeTeXvariation \tex_XeTeXvariation:D
+ \@@_primitive:NN \XeTeXvariationdefault \tex_XeTeXvariationdefault:D
+ \@@_primitive:NN \XeTeXvariationmax \tex_XeTeXvariationmax:D
+ \@@_primitive:NN \XeTeXvariationmin \tex_XeTeXvariationmin:D
+ \@@_primitive:NN \XeTeXvariationname \tex_XeTeXvariationname:D
+ \@@_primitive:NN \XeTeXversion \tex_XeTeXversion:D
+ \@@_primitive:NN \XeTeXselectorcode \tex_XeTeXselectorcode:D
+ \@@_primitive:NN \XeTeXinterwordspaceshaping
+ \tex_XeTeXinterwordspaceshaping:D
+ \@@_primitive:NN \XeTeXhyphenatablelength
+ \tex_XeTeXhyphenatablelength:D
+% \end{macrocode}
+% Primitives from \pdfTeX{} that \XeTeX{} renames: also helps with
+% \LuaTeX{}.
+% \begin{macrocode}
+ \@@_primitive:NN \creationdate \tex_creationdate:D
+ \@@_primitive:NN \elapsedtime \tex_elapsedtime:D
+ \@@_primitive:NN \filedump \tex_filedump:D
+ \@@_primitive:NN \filemoddate \tex_filemoddate:D
+ \@@_primitive:NN \filesize \tex_filesize:D
+ \@@_primitive:NN \mdfivesum \tex_mdfivesum:D
+ \@@_primitive:NN \ifprimitive \tex_ifprimitive:D
+ \@@_primitive:NN \primitive \tex_primitive:D
+ \@@_primitive:NN \resettimer \tex_resettimer:D
+ \@@_primitive:NN \shellescape \tex_shellescape:D
+ \@@_primitive:NN \XeTeXprotrudechars \tex_protrudechars:D
+% \end{macrocode}
+% Primitives from \LuaTeX{}, some of which have been ported back to
+% \XeTeX{}.
+% \begin{macrocode}
+ \@@_primitive:NN \alignmark \tex_alignmark:D
+ \@@_primitive:NN \aligntab \tex_aligntab:D
+ \@@_primitive:NN \attribute \tex_attribute:D
+ \@@_primitive:NN \attributedef \tex_attributedef:D
+ \@@_primitive:NN \automaticdiscretionary
+ \tex_automaticdiscretionary:D
+ \@@_primitive:NN \automatichyphenmode \tex_automatichyphenmode:D
+ \@@_primitive:NN \automatichyphenpenalty
+ \tex_automatichyphenpenalty:D
+ \@@_primitive:NN \begincsname \tex_begincsname:D
+ \@@_primitive:NN \bodydir \tex_bodydir:D
+ \@@_primitive:NN \bodydirection \tex_bodydirection:D
+ \@@_primitive:NN \boundary \tex_boundary:D
+ \@@_primitive:NN \boxdir \tex_boxdir:D
+ \@@_primitive:NN \boxdirection \tex_boxdirection:D
+ \@@_primitive:NN \breakafterdirmode \tex_breakafterdirmode:D
+ \@@_primitive:NN \catcodetable \tex_catcodetable:D
+ \@@_primitive:NN \clearmarks \tex_clearmarks:D
+% \@@_primitive:NN \compoundhyphenmode
+% \tex_compoundhyphenmode:D % not documented in manual
+ \@@_primitive:NN \crampeddisplaystyle \tex_crampeddisplaystyle:D
+ \@@_primitive:NN \crampedscriptscriptstyle
+ \tex_crampedscriptscriptstyle:D
+ \@@_primitive:NN \crampedscriptstyle \tex_crampedscriptstyle:D
+ \@@_primitive:NN \crampedtextstyle \tex_crampedtextstyle:D
+ \@@_primitive:NN \csstring \tex_csstring:D
+ \@@_primitive:NN \deferred \tex_deferred:D
+ \@@_primitive:NN \discretionaryligaturemode
+ \tex_discretionaryligaturemode:D
+ \@@_primitive:NN \directlua \tex_directlua:D
+ \@@_primitive:NN \dviextension \tex_dviextension:D
+ \@@_primitive:NN \dvifeedback \tex_dvifeedback:D
+ \@@_primitive:NN \dvivariable \tex_dvivariable:D
+ \@@_primitive:NN \eTeXglueshrinkorder \tex_eTeXglueshrinkorder:D
+ \@@_primitive:NN \eTeXgluestretchorder \tex_eTeXgluestretchorder:D
+ \@@_primitive:NN \endlocalcontrol \tex_endlocalcontrol:D
+ \@@_primitive:NN \etoksapp \tex_etoksapp:D
+ \@@_primitive:NN \etokspre \tex_etokspre:D
+ \@@_primitive:NN \exceptionpenalty \tex_exceptionpenalty:D
+ \@@_primitive:NN \exhyphenchar \tex_exhyphenchar:D
+ \@@_primitive:NN \explicithyphenpenalty \tex_explicithyphenpenalty:D
+ \@@_primitive:NN \expanded \tex_expanded:D
+ \@@_primitive:NN \explicitdiscretionary \tex_explicitdiscretionary:D
+ \@@_primitive:NN \firstvalidlanguage \tex_firstvalidlanguage:D
+% \@@_primitive:NN \fixupboxesmode
+% \tex_fixupboxesmode:D % not documented in manual
+ \@@_primitive:NN \fontid \tex_fontid:D
+ \@@_primitive:NN \formatname \tex_formatname:D
+ \@@_primitive:NN \hjcode \tex_hjcode:D
+ \@@_primitive:NN \hpack \tex_hpack:D
+ \@@_primitive:NN \hyphenationbounds \tex_hyphenationbounds:D
+ \@@_primitive:NN \hyphenationmin \tex_hyphenationmin:D
+ \@@_primitive:NN \hyphenpenaltymode \tex_hyphenpenaltymode:D
+ \@@_primitive:NN \gleaders \tex_gleaders:D
+ \@@_primitive:NN \glet \tex_glet:D
+ \@@_primitive:NN \glyphdimensionsmode \tex_glyphdimensionsmode:D
+ \@@_primitive:NN \gtoksapp \tex_gtoksapp:D
+ \@@_primitive:NN \gtokspre \tex_gtokspre:D
+ \@@_primitive:NN \ifcondition \tex_ifcondition:D
+ \@@_primitive:NN \immediateassigned \tex_immediateassigned:D
+ \@@_primitive:NN \immediateassignment \tex_immediateassignment:D
+ \@@_primitive:NN \initcatcodetable \tex_initcatcodetable:D
+ \@@_primitive:NN \lastnamedcs \tex_lastnamedcs:D
+ \@@_primitive:NN \latelua \tex_latelua:D
+ \@@_primitive:NN \lateluafunction \tex_lateluafunction:D
+ \@@_primitive:NN \leftghost \tex_leftghost:D
+ \@@_primitive:NN \letcharcode \tex_letcharcode:D
+ \@@_primitive:NN \linedir \tex_linedir:D
+ \@@_primitive:NN \linedirection \tex_linedirection:D
+ \@@_primitive:NN \localbrokenpenalty \tex_localbrokenpenalty:D
+ \@@_primitive:NN \localinterlinepenalty \tex_localinterlinepenalty:D
+ \@@_primitive:NN \luabytecode \tex_luabytecode:D
+ \@@_primitive:NN \luabytecodecall \tex_luabytecodecall:D
+ \@@_primitive:NN \luacopyinputnodes \tex_luacopyinputnodes:D
+ \@@_primitive:NN \luadef \tex_luadef:D
+ \@@_primitive:NN \localleftbox \tex_localleftbox:D
+ \@@_primitive:NN \localrightbox \tex_localrightbox:D
+ \@@_primitive:NN \luaescapestring \tex_luaescapestring:D
+ \@@_primitive:NN \luafunction \tex_luafunction:D
+ \@@_primitive:NN \luafunctioncall \tex_luafunctioncall:D
+ \@@_primitive:NN \luatexbanner \tex_luatexbanner:D
+ \@@_primitive:NN \luatexrevision \tex_luatexrevision:D
+ \@@_primitive:NN \luatexversion \tex_luatexversion:D
+ \@@_primitive:NN \mathdefaultsmode \tex_mathdefaultsmode:D
+ \@@_primitive:NN \mathdelimitersmode \tex_mathdelimitersmode:D
+ \@@_primitive:NN \mathdir \tex_mathdir:D
+ \@@_primitive:NN \mathdirection \tex_mathdirection:D
+ \@@_primitive:NN \mathdisplayskipmode \tex_mathdisplayskipmode:D
+ \@@_primitive:NN \matheqdirmode \tex_matheqdirmode:D
+ \@@_primitive:NN \matheqnogapstep \tex_matheqnogapstep:D
+ \@@_primitive:NN \mathflattenmode \tex_mathflattenmode:D
+ \@@_primitive:NN \mathitalicsmode \tex_mathitalicsmode:D
+ \@@_primitive:NN \mathnolimitsmode \tex_mathnolimitsmode:D
+ \@@_primitive:NN \mathoption \tex_mathoption:D
+ \@@_primitive:NN \mathpenaltiesmode \tex_mathpenaltiesmode:D
+ \@@_primitive:NN \mathrulesfam \tex_mathrulesfam:D
+% \@@_primitive:NN \mathrulesmode
+% \tex_mathrulesmode:D % not documented in manual
+% \@@_primitive:NN \mathrulethicknessmode
+% \tex_mathrulethicknessmode:D % not documented in manual
+ \@@_primitive:NN \mathscriptsmode \tex_mathscriptsmode:D
+ \@@_primitive:NN \mathscriptboxmode \tex_mathscriptboxmode:D
+ \@@_primitive:NN \mathscriptcharmode \tex_mathscriptcharmode:D
+ \@@_primitive:NN \mathstyle \tex_mathstyle:D
+ \@@_primitive:NN \mathsurroundmode \tex_mathsurroundmode:D
+ \@@_primitive:NN \mathsurroundskip \tex_mathsurroundskip:D
+ \@@_primitive:NN \nohrule \tex_nohrule:D
+ \@@_primitive:NN \nokerns \tex_nokerns:D
+ \@@_primitive:NN \noligs \tex_noligs:D
+ \@@_primitive:NN \nospaces \tex_nospaces:D
+ \@@_primitive:NN \novrule \tex_novrule:D
+ \@@_primitive:NN \outputbox \tex_outputbox:D
+ \@@_primitive:NN \pagebottomoffset \tex_pagebottomoffset:D
+ \@@_primitive:NN \pagedir \tex_pagedir:D
+ \@@_primitive:NN \pagedirection \tex_pagedirection:D
+ \@@_primitive:NN \pageleftoffset \tex_pageleftoffset:D
+ \@@_primitive:NN \pagerightoffset \tex_pagerightoffset:D
+ \@@_primitive:NN \pagetopoffset \tex_pagetopoffset:D
+ \@@_primitive:NN \pardir \tex_pardir:D
+ \@@_primitive:NN \pardirection \tex_pardirection:D
+ \@@_primitive:NN \pdfextension \tex_pdfextension:D
+ \@@_primitive:NN \pdffeedback \tex_pdffeedback:D
+ \@@_primitive:NN \pdfvariable \tex_pdfvariable:D
+ \@@_primitive:NN \postexhyphenchar \tex_postexhyphenchar:D
+ \@@_primitive:NN \posthyphenchar \tex_posthyphenchar:D
+ \@@_primitive:NN \prebinoppenalty \tex_prebinoppenalty:D
+ \@@_primitive:NN \predisplaygapfactor \tex_predisplaygapfactor:D
+ \@@_primitive:NN \preexhyphenchar \tex_preexhyphenchar:D
+ \@@_primitive:NN \prehyphenchar \tex_prehyphenchar:D
+ \@@_primitive:NN \prerelpenalty \tex_prerelpenalty:D
+ \@@_primitive:NN \protrusionboundary \tex_protrusionboundary:D
+ \@@_primitive:NN \rightghost \tex_rightghost:D
+ \@@_primitive:NN \savecatcodetable \tex_savecatcodetable:D
+ \@@_primitive:NN \scantextokens \tex_scantextokens:D
+ \@@_primitive:NN \setfontid \tex_setfontid:D
+ \@@_primitive:NN \shapemode \tex_shapemode:D
+ \@@_primitive:NN \suppressifcsnameerror \tex_suppressifcsnameerror:D
+ \@@_primitive:NN \suppresslongerror \tex_suppresslongerror:D
+ \@@_primitive:NN \suppressmathparerror \tex_suppressmathparerror:D
+ \@@_primitive:NN \suppressoutererror \tex_suppressoutererror:D
+ \@@_primitive:NN \suppressprimitiveerror
+ \tex_suppressprimitiveerror:D
+ \@@_primitive:NN \textdir \tex_textdir:D
+ \@@_primitive:NN \textdirection \tex_textdirection:D
+ \@@_primitive:NN \toksapp \tex_toksapp:D
+ \@@_primitive:NN \tokspre \tex_tokspre:D
+ \@@_primitive:NN \tpack \tex_tpack:D
+ \@@_primitive:NN \variablefam \tex_variablefam:D
+ \@@_primitive:NN \vpack \tex_vpack:D
+ \@@_primitive:NN \wordboundary \tex_wordboundary:D
+ \@@_primitive:NN \xtoksapp \tex_xtoksapp:D
+ \@@_primitive:NN \xtokspre \tex_xtokspre:D
+% \end{macrocode}
+% Primitives from \pdfTeX{} that \LuaTeX{} renames.
+% \begin{macrocode}
+ \@@_primitive:NN \adjustspacing \tex_adjustspacing:D
+ \@@_primitive:NN \copyfont \tex_copyfont:D
+ \@@_primitive:NN \draftmode \tex_draftmode:D
+ \@@_primitive:NN \expandglyphsinfont \tex_fontexpand:D
+ \@@_primitive:NN \ifabsdim \tex_ifabsdim:D
+ \@@_primitive:NN \ifabsnum \tex_ifabsnum:D
+ \@@_primitive:NN \ignoreligaturesinfont \tex_ignoreligaturesinfont:D
+ \@@_primitive:NN \insertht \tex_insertht:D
+ \@@_primitive:NN \lastsavedboxresourceindex
+ \tex_pdflastxform:D
+ \@@_primitive:NN \lastsavedimageresourceindex
+ \tex_pdflastximage:D
+ \@@_primitive:NN \lastsavedimageresourcepages
+ \tex_pdflastximagepages:D
+ \@@_primitive:NN \lastxpos \tex_lastxpos:D
+ \@@_primitive:NN \lastypos \tex_lastypos:D
+ \@@_primitive:NN \normaldeviate \tex_normaldeviate:D
+ \@@_primitive:NN \outputmode \tex_pdfoutput:D
+ \@@_primitive:NN \pageheight \tex_pageheight:D
+ \@@_primitive:NN \pagewidth \tex_pagewidth:D
+ \@@_primitive:NN \protrudechars \tex_protrudechars:D
+ \@@_primitive:NN \pxdimen \tex_pxdimen:D
+ \@@_primitive:NN \randomseed \tex_randomseed:D
+ \@@_primitive:NN \useboxresource \tex_pdfrefxform:D
+ \@@_primitive:NN \useimageresource \tex_pdfrefximage:D
+ \@@_primitive:NN \savepos \tex_savepos:D
+ \@@_primitive:NN \saveboxresource \tex_pdfxform:D
+ \@@_primitive:NN \saveimageresource \tex_pdfximage:D
+ \@@_primitive:NN \setrandomseed \tex_setrandomseed:D
+ \@@_primitive:NN \tracingfonts \tex_tracingfonts:D
+ \@@_primitive:NN \uniformdeviate \tex_uniformdeviate:D
+% \end{macrocode}
+% The set of Unicode math primitives were introduced by \XeTeX{} and \LuaTeX{}
+% in a somewhat complex fashion: a few first as |\XeTeX...| which were then
+% renamed with \LuaTeX{} having a lot more. These names now all start
+% |\U...| and mainly |\Umath...|.
+% \begin{macrocode}
+ \@@_primitive:NN \Uchar \tex_Uchar:D
+ \@@_primitive:NN \Ucharcat \tex_Ucharcat:D
+ \@@_primitive:NN \Udelcode \tex_Udelcode:D
+ \@@_primitive:NN \Udelcodenum \tex_Udelcodenum:D
+ \@@_primitive:NN \Udelimiter \tex_Udelimiter:D
+ \@@_primitive:NN \Udelimiterover \tex_Udelimiterover:D
+ \@@_primitive:NN \Udelimiterunder \tex_Udelimiterunder:D
+ \@@_primitive:NN \Uhextensible \tex_Uhextensible:D
+ \@@_primitive:NN \Uleft \tex_Uleft:D
+ \@@_primitive:NN \Umathaccent \tex_Umathaccent:D
+ \@@_primitive:NN \Umathaxis \tex_Umathaxis:D
+ \@@_primitive:NN \Umathbinbinspacing \tex_Umathbinbinspacing:D
+ \@@_primitive:NN \Umathbinclosespacing \tex_Umathbinclosespacing:D
+ \@@_primitive:NN \Umathbininnerspacing \tex_Umathbininnerspacing:D
+ \@@_primitive:NN \Umathbinopenspacing \tex_Umathbinopenspacing:D
+ \@@_primitive:NN \Umathbinopspacing \tex_Umathbinopspacing:D
+ \@@_primitive:NN \Umathbinordspacing \tex_Umathbinordspacing:D
+ \@@_primitive:NN \Umathbinpunctspacing \tex_Umathbinpunctspacing:D
+ \@@_primitive:NN \Umathbinrelspacing \tex_Umathbinrelspacing:D
+ \@@_primitive:NN \Umathchar \tex_Umathchar:D
+ \@@_primitive:NN \Umathcharclass \tex_Umathcharclass:D
+ \@@_primitive:NN \Umathchardef \tex_Umathchardef:D
+ \@@_primitive:NN \Umathcharfam \tex_Umathcharfam:D
+ \@@_primitive:NN \Umathcharnum \tex_Umathcharnum:D
+ \@@_primitive:NN \Umathcharnumdef \tex_Umathcharnumdef:D
+ \@@_primitive:NN \Umathcharslot \tex_Umathcharslot:D
+ \@@_primitive:NN \Umathclosebinspacing \tex_Umathclosebinspacing:D
+ \@@_primitive:NN \Umathcloseclosespacing
+ \tex_Umathcloseclosespacing:D
+ \@@_primitive:NN \Umathcloseinnerspacing
+ \tex_Umathcloseinnerspacing:D
+ \@@_primitive:NN \Umathcloseopenspacing \tex_Umathcloseopenspacing:D
+ \@@_primitive:NN \Umathcloseopspacing \tex_Umathcloseopspacing:D
+ \@@_primitive:NN \Umathcloseordspacing \tex_Umathcloseordspacing:D
+ \@@_primitive:NN \Umathclosepunctspacing
+ \tex_Umathclosepunctspacing:D
+ \@@_primitive:NN \Umathcloserelspacing \tex_Umathcloserelspacing:D
+ \@@_primitive:NN \Umathcode \tex_Umathcode:D
+ \@@_primitive:NN \Umathcodenum \tex_Umathcodenum:D
+ \@@_primitive:NN \Umathconnectoroverlapmin
+ \tex_Umathconnectoroverlapmin:D
+ \@@_primitive:NN \Umathfractiondelsize \tex_Umathfractiondelsize:D
+ \@@_primitive:NN \Umathfractiondenomdown
+ \tex_Umathfractiondenomdown:D
+ \@@_primitive:NN \Umathfractiondenomvgap
+ \tex_Umathfractiondenomvgap:D
+ \@@_primitive:NN \Umathfractionnumup \tex_Umathfractionnumup:D
+ \@@_primitive:NN \Umathfractionnumvgap \tex_Umathfractionnumvgap:D
+ \@@_primitive:NN \Umathfractionrule \tex_Umathfractionrule:D
+ \@@_primitive:NN \Umathinnerbinspacing \tex_Umathinnerbinspacing:D
+ \@@_primitive:NN \Umathinnerclosespacing
+ \tex_Umathinnerclosespacing:D
+ \@@_primitive:NN \Umathinnerinnerspacing
+ \tex_Umathinnerinnerspacing:D
+ \@@_primitive:NN \Umathinneropenspacing \tex_Umathinneropenspacing:D
+ \@@_primitive:NN \Umathinneropspacing \tex_Umathinneropspacing:D
+ \@@_primitive:NN \Umathinnerordspacing \tex_Umathinnerordspacing:D
+ \@@_primitive:NN \Umathinnerpunctspacing
+ \tex_Umathinnerpunctspacing:D
+ \@@_primitive:NN \Umathinnerrelspacing \tex_Umathinnerrelspacing:D
+ \@@_primitive:NN \Umathlimitabovebgap \tex_Umathlimitabovebgap:D
+ \@@_primitive:NN \Umathlimitabovekern \tex_Umathlimitabovekern:D
+ \@@_primitive:NN \Umathlimitabovevgap \tex_Umathlimitabovevgap:D
+ \@@_primitive:NN \Umathlimitbelowbgap \tex_Umathlimitbelowbgap:D
+ \@@_primitive:NN \Umathlimitbelowkern \tex_Umathlimitbelowkern:D
+ \@@_primitive:NN \Umathlimitbelowvgap \tex_Umathlimitbelowvgap:D
+ \@@_primitive:NN \Umathnolimitsubfactor \tex_Umathnolimitsubfactor:D
+ \@@_primitive:NN \Umathnolimitsupfactor \tex_Umathnolimitsupfactor:D
+ \@@_primitive:NN \Umathopbinspacing \tex_Umathopbinspacing:D
+ \@@_primitive:NN \Umathopclosespacing \tex_Umathopclosespacing:D
+ \@@_primitive:NN \Umathopenbinspacing \tex_Umathopenbinspacing:D
+ \@@_primitive:NN \Umathopenclosespacing \tex_Umathopenclosespacing:D
+ \@@_primitive:NN \Umathopeninnerspacing \tex_Umathopeninnerspacing:D
+ \@@_primitive:NN \Umathopenopenspacing \tex_Umathopenopenspacing:D
+ \@@_primitive:NN \Umathopenopspacing \tex_Umathopenopspacing:D
+ \@@_primitive:NN \Umathopenordspacing \tex_Umathopenordspacing:D
+ \@@_primitive:NN \Umathopenpunctspacing \tex_Umathopenpunctspacing:D
+ \@@_primitive:NN \Umathopenrelspacing \tex_Umathopenrelspacing:D
+ \@@_primitive:NN \Umathoperatorsize \tex_Umathoperatorsize:D
+ \@@_primitive:NN \Umathopinnerspacing \tex_Umathopinnerspacing:D
+ \@@_primitive:NN \Umathopopenspacing \tex_Umathopopenspacing:D
+ \@@_primitive:NN \Umathopopspacing \tex_Umathopopspacing:D
+ \@@_primitive:NN \Umathopordspacing \tex_Umathopordspacing:D
+ \@@_primitive:NN \Umathoppunctspacing \tex_Umathoppunctspacing:D
+ \@@_primitive:NN \Umathoprelspacing \tex_Umathoprelspacing:D
+ \@@_primitive:NN \Umathordbinspacing \tex_Umathordbinspacing:D
+ \@@_primitive:NN \Umathordclosespacing \tex_Umathordclosespacing:D
+ \@@_primitive:NN \Umathordinnerspacing \tex_Umathordinnerspacing:D
+ \@@_primitive:NN \Umathordopenspacing \tex_Umathordopenspacing:D
+ \@@_primitive:NN \Umathordopspacing \tex_Umathordopspacing:D
+ \@@_primitive:NN \Umathordordspacing \tex_Umathordordspacing:D
+ \@@_primitive:NN \Umathordpunctspacing \tex_Umathordpunctspacing:D
+ \@@_primitive:NN \Umathordrelspacing \tex_Umathordrelspacing:D
+ \@@_primitive:NN \Umathoverbarkern \tex_Umathoverbarkern:D
+ \@@_primitive:NN \Umathoverbarrule \tex_Umathoverbarrule:D
+ \@@_primitive:NN \Umathoverbarvgap \tex_Umathoverbarvgap:D
+ \@@_primitive:NN \Umathoverdelimiterbgap
+ \tex_Umathoverdelimiterbgap:D
+ \@@_primitive:NN \Umathoverdelimitervgap
+ \tex_Umathoverdelimitervgap:D
+ \@@_primitive:NN \Umathpunctbinspacing \tex_Umathpunctbinspacing:D
+ \@@_primitive:NN \Umathpunctclosespacing
+ \tex_Umathpunctclosespacing:D
+ \@@_primitive:NN \Umathpunctinnerspacing
+ \tex_Umathpunctinnerspacing:D
+ \@@_primitive:NN \Umathpunctopenspacing \tex_Umathpunctopenspacing:D
+ \@@_primitive:NN \Umathpunctopspacing \tex_Umathpunctopspacing:D
+ \@@_primitive:NN \Umathpunctordspacing \tex_Umathpunctordspacing:D
+ \@@_primitive:NN \Umathpunctpunctspacing
+ \tex_Umathpunctpunctspacing:D
+ \@@_primitive:NN \Umathpunctrelspacing \tex_Umathpunctrelspacing:D
+ \@@_primitive:NN \Umathquad \tex_Umathquad:D
+ \@@_primitive:NN \Umathradicaldegreeafter
+ \tex_Umathradicaldegreeafter:D
+ \@@_primitive:NN \Umathradicaldegreebefore
+ \tex_Umathradicaldegreebefore:D
+ \@@_primitive:NN \Umathradicaldegreeraise
+ \tex_Umathradicaldegreeraise:D
+ \@@_primitive:NN \Umathradicalkern \tex_Umathradicalkern:D
+ \@@_primitive:NN \Umathradicalrule \tex_Umathradicalrule:D
+ \@@_primitive:NN \Umathradicalvgap \tex_Umathradicalvgap:D
+ \@@_primitive:NN \Umathrelbinspacing \tex_Umathrelbinspacing:D
+ \@@_primitive:NN \Umathrelclosespacing \tex_Umathrelclosespacing:D
+ \@@_primitive:NN \Umathrelinnerspacing \tex_Umathrelinnerspacing:D
+ \@@_primitive:NN \Umathrelopenspacing \tex_Umathrelopenspacing:D
+ \@@_primitive:NN \Umathrelopspacing \tex_Umathrelopspacing:D
+ \@@_primitive:NN \Umathrelordspacing \tex_Umathrelordspacing:D
+ \@@_primitive:NN \Umathrelpunctspacing \tex_Umathrelpunctspacing:D
+ \@@_primitive:NN \Umathrelrelspacing \tex_Umathrelrelspacing:D
+ \@@_primitive:NN \Umathskewedfractionhgap
+ \tex_Umathskewedfractionhgap:D
+ \@@_primitive:NN \Umathskewedfractionvgap
+ \tex_Umathskewedfractionvgap:D
+ \@@_primitive:NN \Umathspaceafterscript \tex_Umathspaceafterscript:D
+ \@@_primitive:NN \Umathstackdenomdown \tex_Umathstackdenomdown:D
+ \@@_primitive:NN \Umathstacknumup \tex_Umathstacknumup:D
+ \@@_primitive:NN \Umathstackvgap \tex_Umathstackvgap:D
+ \@@_primitive:NN \Umathsubshiftdown \tex_Umathsubshiftdown:D
+ \@@_primitive:NN \Umathsubshiftdrop \tex_Umathsubshiftdrop:D
+ \@@_primitive:NN \Umathsubsupshiftdown \tex_Umathsubsupshiftdown:D
+ \@@_primitive:NN \Umathsubsupvgap \tex_Umathsubsupvgap:D
+ \@@_primitive:NN \Umathsubtopmax \tex_Umathsubtopmax:D
+ \@@_primitive:NN \Umathsupbottommin \tex_Umathsupbottommin:D
+ \@@_primitive:NN \Umathsupshiftdrop \tex_Umathsupshiftdrop:D
+ \@@_primitive:NN \Umathsupshiftup \tex_Umathsupshiftup:D
+ \@@_primitive:NN \Umathsupsubbottommax \tex_Umathsupsubbottommax:D
+ \@@_primitive:NN \Umathunderbarkern \tex_Umathunderbarkern:D
+ \@@_primitive:NN \Umathunderbarrule \tex_Umathunderbarrule:D
+ \@@_primitive:NN \Umathunderbarvgap \tex_Umathunderbarvgap:D
+ \@@_primitive:NN \Umathunderdelimiterbgap
+ \tex_Umathunderdelimiterbgap:D
+ \@@_primitive:NN \Umathunderdelimitervgap
+ \tex_Umathunderdelimitervgap:D
+ \@@_primitive:NN \Umiddle \tex_Umiddle:D
+ \@@_primitive:NN \Unosubscript \tex_Unosubscript:D
+ \@@_primitive:NN \Unosuperscript \tex_Unosuperscript:D
+ \@@_primitive:NN \Uoverdelimiter \tex_Uoverdelimiter:D
+ \@@_primitive:NN \Uradical \tex_Uradical:D
+ \@@_primitive:NN \Uright \tex_Uright:D
+ \@@_primitive:NN \Uroot \tex_Uroot:D
+ \@@_primitive:NN \Uskewed \tex_Uskewed:D
+ \@@_primitive:NN \Uskewedwithdelims \tex_Uskewedwithdelims:D
+ \@@_primitive:NN \Ustack \tex_Ustack:D
+ \@@_primitive:NN \Ustartdisplaymath \tex_Ustartdisplaymath:D
+ \@@_primitive:NN \Ustartmath \tex_Ustartmath:D
+ \@@_primitive:NN \Ustopdisplaymath \tex_Ustopdisplaymath:D
+ \@@_primitive:NN \Ustopmath \tex_Ustopmath:D
+ \@@_primitive:NN \Usubscript \tex_Usubscript:D
+ \@@_primitive:NN \Usuperscript \tex_Usuperscript:D
+ \@@_primitive:NN \Uunderdelimiter \tex_Uunderdelimiter:D
+ \@@_primitive:NN \Uvextensible \tex_Uvextensible:D
+% \end{macrocode}
+% Primitives from \pTeX{}.
+% \begin{macrocode}
+ \@@_primitive:NN \autospacing \tex_autospacing:D
+ \@@_primitive:NN \autoxspacing \tex_autoxspacing:D
+ \@@_primitive:NN \currentcjktoken \tex_currentcjktoken:D
+ \@@_primitive:NN \currentspacingmode \tex_currentspacingmode:D
+ \@@_primitive:NN \currentxspacingmode \tex_currentxspacingmode:D
+ \@@_primitive:NN \disinhibitglue \tex_disinhibitglue:D
+ \@@_primitive:NN \dtou \tex_dtou:D
+ \@@_primitive:NN \epTeXinputencoding \tex_epTeXinputencoding:D
+ \@@_primitive:NN \epTeXversion \tex_epTeXversion:D
+ \@@_primitive:NN \euc \tex_euc:D
+ \@@_primitive:NN \hfi \tex_hfi:D
+ \@@_primitive:NN \ifdbox \tex_ifdbox:D
+ \@@_primitive:NN \ifddir \tex_ifddir:D
+ \@@_primitive:NN \ifjfont \tex_ifjfont:D
+ \@@_primitive:NN \ifmbox \tex_ifmbox:D
+ \@@_primitive:NN \ifmdir \tex_ifmdir:D
+ \@@_primitive:NN \iftbox \tex_iftbox:D
+ \@@_primitive:NN \iftfont \tex_iftfont:D
+ \@@_primitive:NN \iftdir \tex_iftdir:D
+ \@@_primitive:NN \ifybox \tex_ifybox:D
+ \@@_primitive:NN \ifydir \tex_ifydir:D
+ \@@_primitive:NN \inhibitglue \tex_inhibitglue:D
+ \@@_primitive:NN \inhibitxspcode \tex_inhibitxspcode:D
+ \@@_primitive:NN \jcharwidowpenalty \tex_jcharwidowpenalty:D
+ \@@_primitive:NN \jfam \tex_jfam:D
+ \@@_primitive:NN \jfont \tex_jfont:D
+ \@@_primitive:NN \jis \tex_jis:D
+ \@@_primitive:NN \kanjiskip \tex_kanjiskip:D
+ \@@_primitive:NN \kansuji \tex_kansuji:D
+ \@@_primitive:NN \kansujichar \tex_kansujichar:D
+ \@@_primitive:NN \kcatcode \tex_kcatcode:D
+ \@@_primitive:NN \kuten \tex_kuten:D
+ \@@_primitive:NN \lastnodechar \tex_lastnodechar:D
+ \@@_primitive:NN \lastnodefont \tex_lastnodefont:D
+ \@@_primitive:NN \lastnodesubtype \tex_lastnodesubtype:D
+ \@@_primitive:NN \noautospacing \tex_noautospacing:D
+ \@@_primitive:NN \noautoxspacing \tex_noautoxspacing:D
+ \@@_primitive:NN \pagefistretch \tex_pagefistretch:D
+ \@@_primitive:NN \postbreakpenalty \tex_postbreakpenalty:D
+ \@@_primitive:NN \prebreakpenalty \tex_prebreakpenalty:D
+ \@@_primitive:NN \ptexfontname \tex_ptexfontname:D
+ \@@_primitive:NN \ptexlineendmode \tex_lineendmode:D
+ \@@_primitive:NN \ptexminorversion \tex_ptexminorversion:D
+ \@@_primitive:NN \ptexrevision \tex_ptexrevision:D
+ \@@_primitive:NN \ptextracingfonts \tex_ptextracingfonts:D
+ \@@_primitive:NN \ptexversion \tex_ptexversion:D
+ \@@_primitive:NN \readpapersizespecial \tex_readpapersizespecial:D
+ \@@_primitive:NN \scriptbaselineshiftfactor
+ \tex_scriptbaselineshiftfactor:D
+ \@@_primitive:NN \scriptscriptbaselineshiftfactor
+ \tex_scriptscriptbaselineshiftfactor:D
+ \@@_primitive:NN \showmode \tex_showmode:D
+ \@@_primitive:NN \sjis \tex_sjis:D
+ \@@_primitive:NN \tate \tex_tate:D
+ \@@_primitive:NN \tbaselineshift \tex_tbaselineshift:D
+ \@@_primitive:NN \textbaselineshiftfactor
+ \tex_textbaselineshiftfactor:D
+ \@@_primitive:NN \tfont \tex_tfont:D
+ \@@_primitive:NN \tojis \tex_tojis:D
+ \@@_primitive:NN \toucs \tex_toucs:D
+ \@@_primitive:NN \ucs \tex_ucs:D
+ \@@_primitive:NN \xkanjiskip \tex_xkanjiskip:D
+ \@@_primitive:NN \xspcode \tex_xspcode:D
+ \@@_primitive:NN \ybaselineshift \tex_ybaselineshift:D
+ \@@_primitive:NN \yoko \tex_yoko:D
+ \@@_primitive:NN \vfi \tex_vfi:D
+% \end{macrocode}
+% Primitives from \upTeX{}.
+% \begin{macrocode}
+ \@@_primitive:NN \currentcjktoken \tex_currentcjktoken:D
+ \@@_primitive:NN \disablecjktoken \tex_disablecjktoken:D
+ \@@_primitive:NN \enablecjktoken \tex_enablecjktoken:D
+ \@@_primitive:NN \forcecjktoken \tex_forcecjktoken:D
+ \@@_primitive:NN \kchar \tex_kchar:D
+ \@@_primitive:NN \kchardef \tex_kchardef:D
+ \@@_primitive:NN \kuten \tex_kuten:D
+ \@@_primitive:NN \uptexrevision \tex_uptexrevision:D
+ \@@_primitive:NN \uptexversion \tex_uptexversion:D
+% \end{macrocode}
+% Omega primitives provided by \pTeX{} (listed separately mainly to allow
+% understanding of their source).
+% \begin{macrocode}
+ \@@_primitive:NN \odelcode \tex_odelcode:D
+ \@@_primitive:NN \odelimiter \tex_odelimiter:D
+ \@@_primitive:NN \omathaccent \tex_omathaccent:D
+ \@@_primitive:NN \omathchar \tex_omathchar:D
+ \@@_primitive:NN \omathchardef \tex_omathchardef:D
+ \@@_primitive:NN \omathcode \tex_omathcode:D
+ \@@_primitive:NN \oradical \tex_oradical:D
+% \end{macrocode}
+% Newer cross-engine primitives.
+% \begin{macrocode}
+ \@@_primitive:NN \partokencontext \tex_partokencontext:D
+ \@@_primitive:NN \partokenname \tex_partokenname:D
+ \@@_primitive:NN \showstream \tex_showstream:D
+ \@@_primitive:NN \tracingstacklevels \tex_tracingstacklevels:D
+% \end{macrocode}
+% End of the \enquote{just the names} part of the source.
+% \begin{macrocode}
+%</names|package>
+%</names|tex>
+%<*package>
+%<*tex>
+% \end{macrocode}
+%
+% The job is done: close the group (using the primitive renamed!).
+% \begin{macrocode}
+\tex_endgroup:D
+% \end{macrocode}
+%
+% \LaTeXe{} moves a few primitives, so these are sorted out.
+% In newer versions of \LaTeXe{}, \pkg{expl3} is loaded rather early, so
+% only some primitives are already renamed, so we need two tests here.
+% At the beginning of the \LaTeXe{} format, the primitives \tn{end} and
+% \tn{input} are renamed, and only later on the other ones.
+% \begin{macrocode}
+\tex_ifdefined:D \@@@@end
+ \tex_let:D \tex_end:D \@@@@end
+ \tex_let:D \tex_input:D \@@@@input
+\tex_fi:D
+% \end{macrocode}
+%
+% If \tn{@@@@hyph} is defined, we are loading \pkg{expl3} in a
+% pre-2020/10/01 release of \LaTeXe{}, so a few other primitives have to
+% be tested as well.
+% \begin{macrocode}
+\tex_ifdefined:D \@@@@hyph
+ \tex_let:D \tex_everydisplay:D \frozen@everydisplay
+ \tex_let:D \tex_everymath:D \frozen@everymath
+ \tex_let:D \tex_hyphen:D \@@@@hyph
+ \tex_let:D \tex_italiccorrection:D \@@@@italiccorr
+ \tex_let:D \tex_underline:D \@@@@underline
+% \end{macrocode}
+% The \tn{shipout} primitive is particularly tricky as a number of packages
+% want to hook in here. First, we see if a sufficiently-new kernel has saved
+% a copy: if it has, just use that. Otherwise, we need to check each of the
+% possible packages/classes that might move it: here, we are looking for those
+% which do \emph{not} delay action to the \tn{AtBeginDocument} hook. (We
+% cannot use \tn{primitive} as that doesn't
+% allow us to make a direct copy of the primitive \emph{itself}.) As we know
+% that \LaTeXe{} is in use, we use it's \tn{@tfor} loop here.
+% \begin{macrocode}
+ \tex_ifdefined:D \@@@@shipout
+ \tex_let:D \tex_shipout:D \@@@@shipout
+ \tex_fi:D
+ \tex_begingroup:D
+ \tex_edef:D \l_tmpa_tl { \tex_string:D \shipout }
+ \tex_edef:D \l_tmpb_tl { \tex_meaning:D \shipout }
+ \tex_ifx:D \l_tmpa_tl \l_tmpb_tl
+ \tex_else:D
+ \tex_expandafter:D \@tfor \tex_expandafter:D \@tempa \tex_string:D :=
+ \CROP@shipout
+ \dup@shipout
+ \GPTorg@shipout
+ \LL@shipout
+ \mem@oldshipout
+ \opem@shipout
+ \pgfpages@originalshipout
+ \pr@shipout
+ \Shipout
+ \verso@orig@shipout
+ \do
+ {
+ \tex_edef:D \l_tmpb_tl
+ { \tex_expandafter:D \tex_meaning:D \@tempa }
+ \tex_ifx:D \l_tmpa_tl \l_tmpb_tl
+ \tex_global:D \tex_expandafter:D \tex_let:D
+ \tex_expandafter:D \tex_shipout:D \@tempa
+ \tex_fi:D
+ }
+ \tex_fi:D
+ \tex_endgroup:D
+% \end{macrocode}
+% Some tidying up is needed for \tn[index=tracingfonts]{(pdf)tracingfonts}.
+% Newer \LuaTeX{} has
+% this simply as \tn{tracingfonts}, but that is overwritten by
+% the \LaTeXe{} kernel. So any spurious definition has to be removed, then
+% the real version saved either from the \pdfTeX{} name or from \LuaTeX{}.
+% In the latter case, we leave \tn{@@tracingfonts} available: this might
+% be useful and almost all \LaTeXe{} users will have \pkg{expl3} loaded by
+% \pkg{fontspec}. (We follow the usual kernel convention that |@@| is used
+% for saved primitives.)
+% \begin{macrocode}
+ \tex_let:D \tex_tracingfonts:D \tex_undefined:D
+ \tex_ifdefined:D \pdftracingfonts
+ \tex_let:D \tex_tracingfonts:D \pdftracingfonts
+ \tex_else:D
+ \tex_ifdefined:D \tex_directlua:D
+ \tex_directlua:D { tex.enableprimitives("@@@@", {"tracingfonts"}) }
+ \tex_let:D \tex_tracingfonts:D \@@@@tracingfonts
+ \tex_fi:D
+ \tex_fi:D
+\tex_fi:D
+% \end{macrocode}
+% Only \pdfTeX{} and \LuaTeX{} define \tn{pdfmapfile} and \tn{pdfmapline}:
+% Tidy up the fact that some format-building processes leave
+% a couple of questionable decisions about that!
+% \begin{macrocode}
+\tex_ifnum:D 0
+ \tex_ifdefined:D \tex_pdftexversion:D 1 \tex_fi:D
+ \tex_ifdefined:D \tex_luatexversion:D 1 \tex_fi:D
+ = 0 %
+ \tex_let:D \tex_pdfmapfile:D \tex_undefined:D
+ \tex_let:D \tex_pdfmapline:D \tex_undefined:D
+\tex_fi:D
+% \end{macrocode}
+% A few packages do unfortunate things to date-related primitives.
+% \begin{macrocode}
+\tex_begingroup:D
+ \tex_edef:D \l_tmpa_tl { \tex_meaning:D \tex_time:D }
+ \tex_edef:D \l_tmpb_tl { \tex_string:D \time }
+ \tex_ifx:D \l_tmpa_tl \l_tmpb_tl
+ \tex_else:D
+ \tex_global:D \tex_let:D \tex_time:D \tex_undefined:D
+ \tex_fi:D
+ \tex_edef:D \l_tmpa_tl { \tex_meaning:D \tex_day:D }
+ \tex_edef:D \l_tmpb_tl { \tex_string:D \day }
+ \tex_ifx:D \l_tmpa_tl \l_tmpb_tl
+ \tex_else:D
+ \tex_global:D \tex_let:D \tex_day:D \tex_undefined:D
+ \tex_fi:D
+ \tex_edef:D \l_tmpa_tl { \tex_meaning:D \tex_month:D }
+ \tex_edef:D \l_tmpb_tl { \tex_string:D \month }
+ \tex_ifx:D \l_tmpa_tl \l_tmpb_tl
+ \tex_else:D
+ \tex_global:D \tex_let:D \tex_month:D \tex_undefined:D
+ \tex_fi:D
+ \tex_edef:D \l_tmpa_tl { \tex_meaning:D \tex_year:D }
+ \tex_edef:D \l_tmpb_tl { \tex_string:D \year }
+ \tex_ifx:D \l_tmpa_tl \l_tmpb_tl
+ \tex_else:D
+ \tex_global:D \tex_let:D \tex_year:D \tex_undefined:D
+ \tex_fi:D
+\tex_endgroup:D
+% \end{macrocode}
+% \pkg{cslatex} moves a couple of primitives which we recover here; as there
+% is no other marker, we can only work by looking for the names.
+% \begin{macrocode}
+\tex_ifdefined:D \orieveryjob
+ \tex_let:D \tex_everyjob:D \orieveryjob
+\tex_fi:D
+\tex_ifdefined:D \oripdfoutput
+ \tex_let:D \tex_pdfoutput:D \oripdfoutput
+\tex_fi:D
+% \end{macrocode}
+%
+% For \ConTeXt{}, two tests are needed. Both Mark~II and Mark~IV move several
+% primitives: these are all covered by the first test, again using \cs{end}
+% as a marker. For Mark~IV, a few more primitives are moved: they are
+% implemented using some Lua code in the current \ConTeXt{}.
+% \begin{macrocode}
+\tex_ifdefined:D \normalend
+ \tex_let:D \tex_end:D \normalend
+ \tex_let:D \tex_everyjob:D \normaleveryjob
+ \tex_let:D \tex_input:D \normalinput
+ \tex_let:D \tex_language:D \normallanguage
+ \tex_let:D \tex_mathop:D \normalmathop
+ \tex_let:D \tex_month:D \normalmonth
+ \tex_let:D \tex_outer:D \normalouter
+ \tex_let:D \tex_over:D \normalover
+ \tex_let:D \tex_vcenter:D \normalvcenter
+ \tex_let:D \tex_unexpanded:D \normalunexpanded
+ \tex_let:D \tex_expanded:D \normalexpanded
+\tex_fi:D
+\tex_ifdefined:D \normalitaliccorrection
+ \tex_let:D \tex_hoffset:D \normalhoffset
+ \tex_let:D \tex_italiccorrection:D \normalitaliccorrection
+ \tex_let:D \tex_voffset:D \normalvoffset
+ \tex_let:D \tex_showtokens:D \normalshowtokens
+ \tex_let:D \tex_bodydir:D \spac_directions_normal_body_dir
+ \tex_let:D \tex_pagedir:D \spac_directions_normal_page_dir
+\tex_fi:D
+\tex_ifdefined:D \normalleft
+ \tex_let:D \tex_left:D \normalleft
+ \tex_let:D \tex_middle:D \normalmiddle
+ \tex_let:D \tex_right:D \normalright
+\tex_fi:D
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</tex>
+% \end{macrocode}
+%
+% In \LuaTeX{}, we additionally emulate some primitives using Lua code.
+% \begin{macrocode}
+%<*lua>
+% \end{macrocode}
+%
+% \begin{macro}[no-user-doc]{\tex_strcmp:D}
+% Compare two strings, expanding to |0| if they are equal,
+% |-1| if the first one is smaller and |1| if the second one is smaller.
+% Here \enquote{smaller} refers to codepoint order which does not correspond to
+% the user expected order for most non-ASCII strings.
+% \begin{macrocode}
+local minus_tok = token_new(string.byte'-', 12)
+local zero_tok = token_new(string.byte'0', 12)
+local one_tok = token_new(string.byte'1', 12)
+luacmd('tex_strcmp:D', function()
+ local first = scan_string()
+ local second = scan_string()
+ if first < second then
+ put_next(minus_tok, one_tok)
+ else
+ put_next(first == second and zero_tok or one_tok)
+ end
+end, 'global')
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[no-user-doc]{\tex_Ucharcat:D}
+% Creating arbitrary chars using |tex.cprint|.
+% The alternative approach using |token.new(...)| is about 10\% slower
+% but needed to create arbitrary space tokens.
+% \begin{macrocode}
+local sprint = tex.sprint
+local cprint = tex.cprint
+luacmd('tex_Ucharcat:D', function()
+ local charcode = scan_int()
+ local catcode = scan_int()
+ if catcode == 10 then
+ sprint(token_new(charcode, 10))
+ else
+ cprint(catcode, utf8_char(charcode))
+ end
+end, 'global')
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[no-user-doc]{\tex_filesize:D}
+% Wrap the function from |ltxutils|.
+% \begin{macrocode}
+luacmd('tex_filesize:D', function()
+ local size = filesize(scan_string())
+ if size then write(size) end
+end, 'global')
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[no-user-doc]{\tex_mdfivesum:D}
+% There are two cases: Either hash a file or a string.
+% Both are already implemented in l3luatex or built-in.
+% \begin{macrocode}
+luacmd('tex_mdfivesum:D', function()
+ local hash
+ if scan_keyword"file" then
+ hash = filemd5sum(scan_string())
+ else
+ hash = md5_HEX(scan_string())
+ end
+ if hash then write(hash) end
+end, 'global')
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[no-user-doc]{\tex_filemoddate:D}
+% A primitive for getting the modification date of a file.
+% \begin{macrocode}
+luacmd('tex_filemoddate:D', function()
+ local date = filemoddate(scan_string())
+ if date then write(date) end
+end, 'global')
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[no-user-doc]{\tex_filedump:D}
+% An emulated primitive for getting a hexdump from a (partial) file.
+% The length has a default of |0|. This is consistent with
+% \pdfTeX, but it effectivly makes the primitive useless without an
+% explicit |length|. Therefore we allow the keyword |whole| to be used
+% instead of a length, indicating that the whole remaining file should
+% be read.
+% \begin{macrocode}
+luacmd('tex_filedump:D', function()
+ local offset = scan_keyword'offset' and scan_int() or nil
+ local length = scan_keyword'length' and scan_int()
+ or not scan_keyword'whole' and 0 or nil
+ local data = filedump(scan_string(), offset, length)
+ if data then write(data) end
+end, 'global')
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</lua>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3news.pdf b/macros/latex-dev/required/l3kernel/l3news.pdf
new file mode 100644
index 0000000000..591ab927d3
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news.tex b/macros/latex-dev/required/l3kernel/l3news.tex
new file mode 100644
index 0000000000..b8f0de5c72
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news.tex
@@ -0,0 +1,187 @@
+% Copyright 2019-2021 The LaTeX Project
+
+\providecommand*{\lastissue}{12}
+
+\documentclass{ltnews}
+
+\AtBeginDocument{%
+ \renewcommand{\LaTeXNews}{\LaTeX3~News}%
+ \RaggedRight
+ \setlength\parindent{1em}%
+}
+\usepackage{catchfile}
+\usepackage{csquotes}
+\usepackage{enumitem}
+\usepackage{fancyvrb}
+\usepackage{hologo}
+\usepackage{metalogo}
+\usepackage{multicol}
+\usepackage{ragged2e}
+\usepackage{siunitx}
+\usepackage{tikz}
+\usepackage{underscore}
+\usepackage{xparse}
+\usepackage{hyperref}
+\hypersetup{colorlinks}
+\usepackage{bookmark}
+
+\MakeOuterQuote{"}
+
+\pdfstringdefDisableCommands
+ {%
+ \RenewExpandableDocumentCommand \cs { O{} m }
+ {\textbackslash#2}%
+ }
+
+\makeatletter
+\newcounter{issue}
+\renewcommand*{\theissue}{%
+ \ifnum\value{issue}<10 0\fi
+ \number\value{issue}%
+}
+\newcommand*{\MonthJanuary}{01}
+\newcommand*{\MonthFebruary}{02}
+\newcommand*{\MonthMarch}{03}
+\newcommand*{\MonthApril}{04}
+\newcommand*{\MonthMay}{05}
+\newcommand*{\MonthJune}{06}
+\newcommand*{\MonthJuly}{07}
+\newcommand*{\MonthAugust}{08}
+\newcommand*{\MonthSeptember}{09}
+\newcommand*{\MonthOctober}{10}
+\newcommand*{\MonthNovember}{11}
+\newcommand*{\MonthDecember}{12}
+\newcommand*{\printissue}{%
+ Issue %
+ \texorpdfstring{\number\value{issue}}{\theissue}, %
+ \texorpdfstring{\@month\space\@year}{\@year/\@nameuse{Month\@month}}%
+}
+\let\l@part\l@section
+\let\l@section\l@subsection
+\let\l@subsection\l@subsubsection
+\let\l@subsubsection\l@paragraph
+\let\l@paragraph\l@subparagraph
+\newcommand*{\makefirsttitle}{%
+ \twocolumn[{%
+ \parbox[t][4\baselineskip]{\textwidth}{%
+ \@titlefont\@title, Issues 1--\lastissue
+ }%
+ }]%
+}
+
+% show the page number on first page of issues:
+
+\renewcommand{\ps@titlepage}{%
+ \renewcommand{\@oddhead}{\hfill}%
+ \renewcommand{\@evenhead}{\hfill}%
+ \renewcommand{\@oddfoot}{\@indiciafont\@indicia\hfill --\thepage}%
+ \renewcommand{\@evenfoot}{\@indiciafont\@indicia\hfill --\thepage}%
+}
+
+% only needed if the old ltnews class is used
+\renewcommand{\@oddfoot}{\@indiciafont\mbox{}\hfill --\thepage}%
+\renewcommand{\@evenfoot}{\@indiciafont\mbox{}\hfill --\thepage}%
+
+
+\makeatother
+
+\begin{document}
+
+%%% Title and Table of Contents
+
+\makefirsttitle
+\pdfbookmark[0]{\contentsname}{toc}
+\tableofcontents
+\clearpage
+
+\begingroup
+ \renewcommand*{\AtBeginDocument}[1]{#1}%
+ \renewcommand*{\PassOptionsToPackage}[2]{}%
+ \renewcommand*{\usepackage}[2][]{}%
+ \renewcommand*{\RequirePackage}[2][]{}%
+ \renewcommand*{\documentclass}[2][]{%
+ \setcounter{footnote}{0}%
+ \gobbleopt
+ }%
+ \newcommand*{\gobbleopt}[1][]{}%
+ \makeatletter
+ \let\org@twocolumn\twocolumn
+ \renewenvironment{document}{%
+ \clearpage
+ \ifnum\@issue=20 %
+ \addtocontents{toc}{\protect\setcounter{tocdepth}{5}}%
+ \addtocontents{toc}{%
+ \protect\makeatletter
+ }%
+ \addtocontents{toc}{%
+ \let\protect\saved@l@paragraph\protect\l@paragraph
+ }%
+ \addtocontents{toc}{%
+ \let\protect\l@paragraph\protect\l@subsection
+ }%
+ \fi
+ \ifnum\@issue>9\space % we may have issue tocs ...
+ \addtocontents{toc}{%
+ \let\protect\l@paragraph\protect\saved@l@paragraph
+ }%
+ \def\toclevel@subsection{1}%
+ \def\toclevel@subsubsection{2}%
+ \addtocontents{toc}{\protect\setcounter{tocdepth}{4}}%
+ \renewcommand*{\tableofcontents}{%
+ \section*{\contentsname}%
+ \@starttoc{toc\theissue}%
+ }%
+ \let\saved@addtocontents\addtocontents
+ \renewcommand*{\addtocontents}[2]{%
+ \saved@addtocontents{##1}{##2}%
+ \def\temp@toc{toc}%
+ \def\temp@param{##1}%
+ \ifx\temp@toc\temp@param
+ \saved@addtocontents{toc\theissue}{##2}%
+ \fi
+ }%
+ \let\l@subsubsection\l@subsection
+ \let\l@subsection\l@section
+ \let\l@section\l@part
+ \let\l@part\@gobbletwo
+ \fi
+ \def\twocolumn[{%
+ \let\twocolumn\org@twocolumn
+ \org@twocolumn[%
+ {% because of optional argument of \twocolumn
+ \pdfbookmark[0]{\printissue}{issue\theissue}%
+ }%
+ \begingroup
+ \let\WriteBookmarks\relax
+ \@firstofone{% inside opt. arg. of \twocolumn: protect "]"
+ \renewcommand*{\Hy@writebookmark}[5]{}%
+ }%
+ \phantomsection
+ \addcontentsline{toc}{part}{\printissue}%
+ \endgroup
+ }%
+ }{%
+ \clearpage
+ }%
+ \def\MakeOuterQuote#1{%
+ \if\noexpand"\noexpand#1%
+ \else
+ \@latex@error{Unexpected \string\MakeOuterQuote
+ {\detokenize{#1}}\MessageBreak%
+ Check if output is valid in `l3news\theissue.tex'}%
+ \fi}
+ \makeatother
+ \loop
+ \ifnum\value{issue}<\lastissue
+ \stepcounter{issue}%
+ \input{l3news\theissue}%
+ \repeat
+ \stepcounter{issue}%
+ \IfFileExists{l3news\theissue}{%
+ \@latex@error{\jobname.tex is out of date,\MessageBreak
+ there is `l3news\theissue.tex'%
+ }\@ehc
+ }{}%
+\endgroup
+
+\end{document}
diff --git a/macros/latex-dev/required/l3kernel/l3news01.pdf b/macros/latex-dev/required/l3kernel/l3news01.pdf
new file mode 100644
index 0000000000..c8a490c9cb
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news01.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news01.tex b/macros/latex-dev/required/l3kernel/l3news01.tex
new file mode 100644
index 0000000000..b4841ac24b
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news01.tex
@@ -0,0 +1,102 @@
+% Copyright 2009 The LaTeX Project
+\documentclass{ltnews}
+\PassOptionsToPackage{colorlinks}{hyperref}
+
+\usepackage{metalogo,ragged2e}
+
+\AtBeginDocument{
+ \renewcommand{\LaTeXNews}{\LaTeX3~News}
+ \RaggedRight
+}
+
+\publicationmonth{February}
+\publicationyear{2009}
+\publicationissue{1}
+
+\begin{document}
+\maketitle
+
+\section{Welcome to \LaTeX3}
+
+Momentum is again starting to build behind The \LaTeX{} Project. For the
+last few releases of \TeX~Live, the experimental programming foundation for
+\LaTeX3 has been available under the name \package{expl3}. Despite large
+warnings that the code would probably change in the future, we wanted to show
+that there was progress being made, no matter how slowly. Since then, some
+people have looked at the code, provided feedback, and~--- most
+importantly~--- actually tried using it. Although it is yet early days, we
+believe that the ideas behind the code are sound and there are only `cosmetic
+improvements' that need to be made before \package{expl3} is ready for the
+\LaTeX~package author masses.
+
+\section{What currently exists}
+
+The current \LaTeX3 code consists of two main branches: the
+\package{expl3} modules that define the underlying programming environment,
+and the `\package{xpackage}s', which are a suite of packages that are written
+with the \package{expl3} programming interface and provide some higher-level
+functionality for what will one day become \LaTeX3 proper. Both \package{expl3} and
+parts of the \package{xpackages} are designed to be used \emph{on top} of
+\LaTeXe, so new packages can take advantage of the new features while still
+allowing to be used alongside many of the vast number of \LaTeXe\ packages on
+\textsc{ctan}.
+
+\section{What's happening now}
+
+In preparation for a minor overhaul of the \package{expl3} code, we are
+writing a comprehensive test suite for each module. These tests allow us to
+make implementation changes and then test if the code still works as before.
+They are also highlighting any minor shortcomings or omissions in the code.
+As the tests are being written, our assumptions about what should be called
+what and the underlying naming conventions for the functions and datatypes are
+being questioned, challenged, and noted for further rumination.
+
+At the time of writing, we are approximately half-way through writing the test
+suite. Once this task is complete, which we plan for the first
+half of 2009, we will be ready to make changes without worrying about breaking
+anything.
+
+\section{What's happening soon}
+
+So what do we want to change? The current \package{expl3} codebase has
+portions that date to the pre-\LaTeXe\ days, while other modules have been
+more recently conceived. It is quite apparent when reading through the sources
+that some unification and tidying up would improve the simplicity and
+consistency of the code. In many cases, such changes will mean nothing more
+than a tweak or a rename.
+
+Beyond these minor changes, we are also re-thinking the exact notation behind
+the way functions are defined. There are currently a handful of different
+types of arguments that functions may be passed (from an untouched single
+token to a complete expansion of a token list) and we're not entirely happy
+with how the original choices have evolved now that the system has grown
+somewhat. We have received good feedback from several people on ways that we
+could improve the argument syntax, and as part of the upcoming changes to the
+\package{expl3} packages we hope to address the problems that we currently
+perceive in the present syntax.
+
+\section{What's happening later}
+
+After the changes discussed above are finished, we will begin freezing the core
+interface of the \package{expl3} modules, and we hope that more package
+authors will be interested in using the new ideas to write their own code.
+While the core functions will then remain unchanged, more features and new
+modules will be added as \LaTeX3 starts to grow.
+
+Some new and/or experimental packages will be changing to use the
+\package{expl3} programming interface, including \package{breqn},
+\package{mathtools}, \package{empheq}, \package{fontspec}, and
+\package{unicode-math}. (Which is one reason for the lack of progress in
+these latter two in recent times.) There will also be a version of the
+\package{siunitx} package written in \package{expl3}, in parallel to the
+current \LaTeXe\ version. These developments will provide improvements to
+everyday \LaTeX\ users who haven't even heard of The \LaTeX{} Project.
+
+Looking towards the long term, \LaTeX3 as a document preparation system needs
+to be written almost from scratch. A high-level user syntax needs to be
+designed and scores of packages will be used as inspiration for the
+`out-of-the-box' default document templates. \LaTeXe\ has stood up to the test
+of time~--- some fifteen years and still going strong~--- and it is now time
+to write a successor that will survive another score.
+
+\end{document}
diff --git a/macros/latex-dev/required/l3kernel/l3news02.pdf b/macros/latex-dev/required/l3kernel/l3news02.pdf
new file mode 100644
index 0000000000..f3ab2dbd18
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news02.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news02.tex b/macros/latex-dev/required/l3kernel/l3news02.tex
new file mode 100644
index 0000000000..a3d5467c8e
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news02.tex
@@ -0,0 +1,153 @@
+% Copyright 2009 The LaTeX Project
+\documentclass{ltnews}
+\PassOptionsToPackage{colorlinks}{hyperref}
+
+\usepackage{metalogo,ragged2e}
+
+\AtBeginDocument{
+ \renewcommand{\LaTeXNews}{\LaTeX3~News}
+ \RaggedRight
+}
+
+\usepackage{url}
+\newcommand\TUG[1]{\textsc{tug}~#1}
+
+\publicationmonth{June}
+\publicationyear{2009}
+\publicationissue{2}
+
+\begin{document}
+\maketitle
+
+\section{\TeX~Live and the \textsf{expl3} code}
+
+\TeX~Live 2009 is almost upon us, and the \LaTeX3 team have been
+readying a new release of the experimental \LaTeX3 code for this.
+Very dramatic changes have occurred since the
+last public release of the code in \TeX~Live~2008; no backwards compatibility has been
+maintained (as warned in the beginning of the documentation) but we
+believe the changes made are all much for the better. Almost every
+single part of \textsf{expl3} has been scrutinized, resulting in a far
+more coherent code base.
+
+The \textsf{expl3} code is now considered to be much more stable than
+it was before; a comprehensive test suite has been written that helps
+to ensure that we don't make any mistakes as we change things in the
+future. In the process of writing the test
+suite, many minor bugs were fixed; we recommend such test suites for
+all similar developmental projects!
+Some small underlying changes are still expected in the
+\textsf{expl3} code, but major, disruptive, changes aren't planned.
+
+\section{Planned updates}
+
+Until now, the last update to \textsc{ctan} of the \textsf{expl3}
+bundle was for \TeX~Live~2008. Now that work on the code is happening
+on a semi-steady basis, we plan to keep updates rolling out to
+\textsc{ctan} more frequently. This will allow anyone who wishes to
+experiment with the new code to use the \TeX~Live or MiK\TeX\
+updaters to install a recent version without having to `check out' the
+\textsc{svn} repository and install the packages manually.
+
+\section{New members}
+
+We didn't say anything about it in the last status update, but Joseph
+Wright and Will Robertson are now members of the \LaTeX\ Team. They
+have been working fairly exclusively on the \textsf{expl3} code.
+
+It's worth repeating that \LaTeXe\ is essentially frozen in order to
+prevent any backwards compatibility problems. As desirable as it is
+to benefit from the new features offered by new engines \XeTeX\ and
+Lua\TeX, we cannot risk the stability of production servers running
+older versions of \LaTeXe\ which will inevitably end up processing
+documents written into the future.
+
+\LaTeX3 will not be inheriting the same restraints, so stay tuned.
+
+\newpage
+
+\section{Some specifics}
+
+Morten H\o gholm will be presenting the recent changes in much more detail at
+\TUG{2009}. Here are some quick specifics for those interested. New code written
+and broad changes made to the \textsf{expl3} modules:
+\begin{description}
+\item [More logical function names]
+ Many function names that were hold-outs from the \TeX\ naming system
+ have been changed to fit into the more logical scheme of \textsf{expl3}; e.g.,
+ \verb|\def:Npn| and \verb|\let:NN| are now \verb|\cs_set:Npn| and
+ \verb|\cs_set_eq:NN|.
+
+\item [Defining functions and conditionals]
+ Much thought was put into new ways to define
+ functions and conditionals with a minimum of code.
+ See \verb|\cs_set:Nn| and \verb|\prg_set_conditional:Nnn|.
+
+\item [Smart comparisons]
+ Comparisons can be made much more easily now, with familiar notation such as
+ \verb|\intexpr_compare_p:n{ #1+3 != \l_tmpa_int }|.
+
+\item [Data from variables] A new function argument specifier \texttt{V} has
+ been added for extracting information from variables of different types,
+ without needing to know the underlying variable structure. Some other
+ tidy-ups on the argument specifiers offered, partially as a result of the
+ addition of this new one.
+
+\item [l3msg] New module to deal with communication between \LaTeX3 code
+ and the user (info messages, warnings, and errors), including message
+ filtering partially inspired by the \textsf{silence} package.
+ \end{description}
+
+\section{The next six months}
+
+Having overhauled the \textsf{expl3} code, we now plan to perform an
+analogous process with the foundations of the
+\textsf{xpackages}. These are the higher-level packages that will
+provide the basic needs such as control of the page layout and rich
+document-level interaction with the user. As the groundwork for this
+layer of the document processing matures, we will be able to start
+building more packages for a \LaTeX3 kernel; these packages will also
+be usable on top of \LaTeXe\ and serve as broadly customisable
+templates for future document design.
+
+As gaps in the functionality offered by \textsf{expl3} are found (in
+some cases, we know that they exist already), the programming layer
+will be extended to support our needs. In other cases, wrappers around
+\TeX\ functions that can be more usefully handled at a higher level
+will be written.
+
+In terms of what we're planning to work on next, three \textsf{xpackage}s
+will take the focus of our attention.
+\begin{description}
+\item [xbase]
+ `\textsf{xbase}' is actually two packages: \textsf{xparse} and
+ \textsf{template}. These contain code for, respectively, defining new
+ document commands (such that a user would use; e.g., \verb|\section|,
+ \verb|\makebox|, \dots) and for handling keyval lists for user input and
+ document specification. \textsf{xparse} was presented at \TUG{1999}%
+ \footnote{\url{http://www.latex-project.org/papers/tug99.pdf}}
+ and Lars Hellstr\"om wrote some notes on \textsf{template} in 2000%
+ \footnote{\url{http://www.latex-project.org/papers/template-notes.pdf}}.
+ Functionality coverage for these packages is good but concepts need a good
+ ``airing''. There are various approaches taken for keyval input, some more
+ recent than the \textsf{template} code, so there are some alternatives to
+ evaluate.
+\item [galley2] Sophisticated handling for \mbox{constructing} paragraphs and
+ other document elements. Morten spoke on this at \TUG{2008}%
+ \footnote{\url{http://river-valley.tv/the-galley-module/}}.
+ Design needs to be revisited after some stress testing.
+\item [xor] This is the \LaTeX3 output routine for splitting the galley into
+ page and sub-page sized chunks. Ideas and code need work to move to
+ ``production ready'' status. Early developments with this package were
+ published by Frank in 2000%
+ \footnote{\url{http://www.latex-project.org/papers/xo-pfloat.pdf}}.
+\end{description}
+
+Expect to hear again from us at Christmas. If you'd like to discuss any
+of these ideas, please join us on the \textsc{latex-l} mailing list%
+\footnote{\url{http://www.latex-project.org/code.html}}.
+
+\end{document}
+
+
+
diff --git a/macros/latex-dev/required/l3kernel/l3news03.pdf b/macros/latex-dev/required/l3kernel/l3news03.pdf
new file mode 100644
index 0000000000..268bfdca04
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news03.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news03.tex b/macros/latex-dev/required/l3kernel/l3news03.tex
new file mode 100644
index 0000000000..e3e245f051
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news03.tex
@@ -0,0 +1,128 @@
+% Copyright 2009,2010 The LaTeX Project
+\documentclass{ltnews}
+\PassOptionsToPackage{colorlinks}{hyperref}
+
+\usepackage{metalogo,ragged2e}
+
+\AtBeginDocument{
+ \renewcommand{\LaTeXNews}{\LaTeX3~News}
+ \RaggedRight
+}
+
+\usepackage{url}
+
+\publicationmonth{January}
+\publicationyear{2010}
+\publicationissue{3}
+
+\begin{document}
+\maketitle
+\raisefirstsection
+
+\section{Happy New Year}
+
+Welcome to the holiday season edition of `news of our activities' for
+the \LaTeX3 team.
+
+\section{Recent developments}
+
+The last six months has seen two significant releases in the \LaTeX3 code.
+In the \textsc{ctan} repository for the \pkg{xpackages},\footnote{\url{http://mirror.ctan.org/tex-archive/macros/latex/contrib/xpackages/}} you'll find two items of interest:
+\begin{itemize}
+\item A revised version of \textsf{xparse}; and
+\item The new package \textsf{xtemplate}, a re-implementation of \textsf{template} with a new syntax.
+\end{itemize}
+Special thanks to Joseph Wright who handled the implementations above almost single-handedly (with lots of input and feedback from other members of the team and members of the \textsc{latex-l} mailing list).
+
+These two packages are designed for the \LaTeX\ package author who wishes to define document commands and designer interfaces in a high-level manner.
+
+\paragraph{\textsf{xparse}}
+This package allows complex document commands to be constructed with all sorts of optional arguments and flags. Think of how \verb|\newcommand| allows you to create a command with a single optional argument and \textsf{xparse} is a generalisation of that idea.
+
+\paragraph{\textsf{xtemplate}}
+This package requires more explanation.
+\textsf{Xtemplate} is designed to separate the logical information in a
+document from its visual representation. `Templates' are constructed to fulfil
+individual typesetting requirements for each set of arguments; to change
+the look of a certain part of a document, instantiations of templates can be
+swapped out for another without (a) having to change the markup of the source
+document, or (b) having to edit some internal \LaTeX\ macro.
+
+
+\LaTeXe{} packages, such as \textsf{geometry} or \textsf{titlesec}, already provide
+parameterized interfaces to specific document elements. For example,
+one may use \textsf{titlesec} to change the
+layout of a \verb|\section|: one modifies its layout parameters via \verb|\titleformat| and \verb|\titlespacing|.
+In a way, such packages define a template for a specific document element and
+some manipulation commands to instantiate it.
+\pagebreak
+However, the moment the intended
+layout is not achievable with one package you are on your own: either you have
+to resort to low-level programming or find some other high-level package which, of course, comes with its own set of conventions and manipulation commands.
+
+The \textsf{xtemplate} package can be thought of a generalization of such
+ideas. It provides a uniform interface for defining and managing templates for
+any kind of document element and most importantly provides a uniform interface
+for instantiating the layout.
+
+Thus the designer activity of defining or modifying a document class is
+limited to selecting the document elements that should be provided by the
+class (e.g., \verb|\chapter|, \verb|\section| \verb|\footnote|, lists, \ldots), selecting
+appropriate ``named'' templates for each of them, and instantiating these
+templates by specifying values for their layout parameters. If a desired
+layout can't be achieved with a given template a different template for the
+same document element can be selected.
+
+Programming is only necessary
+if no suitable template for the intended layout is available.
+It is then that a \LaTeX{} programmer has to build a new template
+that supports the layout requirements. Once this task is complete, the
+template may be
+added to the selection of templates that designers and users may choose from
+to define or adjust document layouts seamlessly.
+
+This is a slight gloss over the complexities of the package itself, which you can read about in the documentation. We've tried to document \textsf{xtemplate} clearly but we'd love feedback on whether the ideas make sense to you.
+
+As an addendum to the introduction of \textsf{xtemplate}, the older \textsf{template} package will be retired in the near future. To our knowledge there is only a single package on \textsc{ctan} that uses \textsf{template}, namely \textsf{xfrac}, and members of the \LaTeX\ team are in the process of switching this package over to \textsf{xtemplate}. If you have any private code that uses \textsf{template}, please let us know!
+
+
+\section{Upcoming plans}
+
+Having announced the updated \textsf{xparse} and the new \textsf{xtemplate}, the next stage of development will revolve around using these two systems in the other components of the \textsf{xpackages}, feeding back our experience in practise with the original ideas behind the designs and evaluating if the packages are meeting our expectations.
+
+\subsection{Packages to tackle}
+
+\paragraph{\textsf{xhead}}
+The first work will be to create a new \textsf{xpackage} (probably called \textsf{xhead}), for typesetting section headings and other document divisions.
+Section headings are one of the more complex areas to work with, so
+the work should stress \textsf{xtemplate} enough to know if its
+current design is sufficient for most needs. Nothing has been
+released yet, but we'll announce further developments on the
+\textsc{latex-l} mailing
+list\footnote{For details, see
+ \url{http://www.latex-project.org/code.html}} in the
+mean time.
+
+
+\paragraph{\textsf{galley}}
+We also need to give \textsf{galley} the same treatment as
+\textsf{xparse} and \textsf{xtemplate} have already had. That is, we have an
+older implementation (in fact two) that needs some work before we're ready to release it to \textsc{ctan}.
+
+The \textsf{galley} package is used to place material into the
+vertical list while typesetting but before page breaks occur. Since it
+works at such a low level, it is important to solidify this package
+before writing higher level design templates.
+
+An issue we have to face is that to achieve best results,
+\textsf{galley} cannot be used in concert with \LaTeXe\ code. This
+could limit its usefulness, and we may decide that it's better to
+scale back the features we're attempting, to allow better
+interoperability for existing packages and documents. More work
+remains before we can decide between these options.
+
+
+\end{document}
+
+
+
diff --git a/macros/latex-dev/required/l3kernel/l3news04.pdf b/macros/latex-dev/required/l3kernel/l3news04.pdf
new file mode 100644
index 0000000000..b70a04f2bd
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news04.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news04.tex b/macros/latex-dev/required/l3kernel/l3news04.tex
new file mode 100644
index 0000000000..a0fc82f3de
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news04.tex
@@ -0,0 +1,123 @@
+% Copyright 2009,2010 The LaTeX Project
+\documentclass{ltnews}
+\PassOptionsToPackage{colorlinks}{hyperref}
+
+\usepackage{metalogo,ragged2e}
+
+\AtBeginDocument{
+ \renewcommand{\LaTeXNews}{\LaTeX3~News}
+ \RaggedRight
+}
+
+\usepackage{url,hologo}
+
+\publicationmonth{July}
+\publicationyear{2010}
+\publicationissue{4}
+
+\begin{document}
+\maketitle
+
+\noindent
+Now that we're back from the \TeX\ Users Group conference in San
+Francisco, it's time to discuss what's been going on over the last six months.
+Due to some extra travel plans after the conference, this issue is slightly
+late in coming out.
+
+
+\section{\textsf{expl3} in practice}
+
+Joseph Wright and Will Robertson have both released significant new versions
+of their packages, resp., \textsf{siunitx} and \textsf{fontspec}. These have
+been re-written in the \LaTeX3 programming language \textsf{expl3}, which we
+have discussed here previously. Using \textsf{expl3} for production code has
+been very successful, both in demonstrating that the concepts are sound and
+highlighting areas that still need some attention.
+% The \textsf{expl3}
+% code will continue to evolve as more people use it for their work.
+
+In the case of \textsf{fontspec}, \textsf{expl3} programming is being used to
+target \LaTeX\ running on either \XeTeX\ and \hologo{LuaTeX}. In the latter
+case, the package is a mixture of Lua code and \pkg{expl3} code; Will
+presented the \pkg{unicode-math} package at TUG~2010, which is developed in
+the same style.
+
+
+\section{New \textsf{xpackages}}
+
+Frank Mittelbach has started to work on a new experimental \LaTeX3 package
+\textsf{xhead} that provides templates for one of the most complex areas of
+document design: section headings and document divisions. This
+is the beginning of an ambitious idea to map out the requirements for
+typesetting most documents currently processed with \LaTeX.
+
+One of the challenges here is providing a ``natural'' design language for
+describing the two-dimensional spatial relationships of objects participating
+in the design, e.g., the placement of a heading number in relation to the
+heading title, a possible sub-title, etc. In answer to this challenge Frank
+developed the \textsf{xcoffin} package, which he presented at TUG~2010. It is
+designed as a high-level interface for placing and aligning boxes on a page,
+allowing a `designer's approach' for indicating the positional relationship
+between boxes. (A `coffin' is a box with handles.) As an example, it is
+possible to represent ideas such as `align the lower-left corner of box A with
+the upper-right corner of box B after rotating it ninety degrees', without
+having to calculate the intermediate positions.
+
+We expect a future version of \textsf{xcoffin} (after some further work on its
+interface layer and its internal implementation) to play a major role in all
+packages providing layout templates for higher-level document objects, such as
+table of contents designs, floats, etc.
+
+Finally,
+Joseph Wright has begun work with the current `galley' packages, producing the
+new, minimal, \textsf{xgalley} based on \textsf{xfm-galley} as a testbed for
+what we need and what will work.
+
+
+\section{Developments with \textsf{expl3}}
+
+Meanwhile, Joseph's \emph{also} been writing a new floating-point calculation
+module, called \textsf{l3fp}, for \pkg{expl3}. This module allows manipulation
+and calculation of numbers with a much larger range than \TeX\ allows
+naturally. The \textsf{l3fp} module has already been utilised in the
+\pkg{xcoffin} code for calculatations such as coordinate rotations and
+intersection points of vectors.
+
+The modules \pkg{l3io} and \pkg{l3file} have been revised, rethinking the way
+that read and write streams are dealt with. \TeX\ has a hard limit of sixteen
+input and output streams open at any one time, and the new implementation for
+\pkg{expl3} provides more flexibility in how they are allocated; there's now
+much less chance of running into a `\verb|No room for a new \read|' (or
+\verb|\write|) error.
+
+Sometimes we discuss ideas for \textsf{expl3} that \emph{don't} end up making
+it into the final code. One example of this is the concept of having `local
+registers' for integers, boxes, and so on, that do not survive outside of the
+group they are defined in (in contrast to Plain \TeX\ and \LaTeX, where
+allocators such as \verb|\newcount| and \verb|\newbox| are always global).
+Despite the scope for some small benefit, we decided that the extra complexity
+that the additional functions required, in both syntax and documentation, was
+not justified.
+
+
+\section{TUG 2010 reflections}
+
+% added most of it back in: -fmi
+
+%% Most of the active \LaTeX3 Project team were able to attend the TUG~2010
+%% conference and (for Will) meet everyone in person for the first time.
+
+Our interpretation of the broad themes discussed at the conference are that
+\TeX-based systems are still thriving and there are some big problems to solve
+with robust solutions to transform \LaTeX\ source, including mathematics, into
+a form such as HTML. While there are big pushes for standardising various aspects
+of the \LaTeX\ syntax, we also believe that it is \LaTeX's very
+flexibility---its inherently non-standardised markup---that has allowed it to
+survive for so many years. There is a delicate trade-off here between moving
+forward into more standards-based territory while also retaining the
+extensibility of the third-party package system.
+
+\end{document}
+
+
+
diff --git a/macros/latex-dev/required/l3kernel/l3news05.pdf b/macros/latex-dev/required/l3kernel/l3news05.pdf
new file mode 100644
index 0000000000..87c46a0c2a
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news05.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news05.tex b/macros/latex-dev/required/l3kernel/l3news05.tex
new file mode 100644
index 0000000000..43ec2a8d19
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news05.tex
@@ -0,0 +1,64 @@
+% Copyright 2011 The LaTeX Project
+\documentclass{ltnews}
+\PassOptionsToPackage{colorlinks}{hyperref}
+
+\usepackage{metalogo,ragged2e}
+
+\AtBeginDocument{
+ \renewcommand{\LaTeXNews}{\LaTeX3~News}
+ \RaggedRight
+}
+
+\usepackage{hologo}
+
+\publicationmonth{January}
+\publicationyear{2011}
+\publicationissue{5}
+
+\begin{document}
+\maketitle
+
+
+\section{Happy new year}
+
+Seasons greetings for 2011!
+As the previous news issue was released late, this season's issue will be shorter than usual.
+
+\section{The LPPL is now OSI-approved}
+
+We are happy to report that earlier this year the \LaTeX\ Project Public License (LPPL) has been approved by the OSI as an open source licence.\footnote{\url{http://www.opensource.org/licenses/lppl}} Frank Mittelbach will be publishing further details on this news in a retrospective on the LPPL in an upcoming TUGboat article.
+
+\section{Reflections on 2010}
+
+We are pleased to see the continued development and discussion in the \TeX\ world.
+The \LaTeX\ ecosystem continues to see new developments and a selection of notable news from the second half of last year include:
+\begin{itemize}
+\item[June] The TUG~2010 conference was held very successfully in San
+Francisco; videos, slides, and papers from \LaTeX3 Project members are available from our website.\footnote{\url{http://www.latex-project.org/papers/}}
+\item[Aug.]
+The \TeX\ Stack Exchange\footnote{\url{http://tex.stackexchange.com}} question\,\&\,answer website was created and has since grown quickly. At time of writing, some 2800 people have asked 2600 questions with 5600 answers total, and 2200 users are currently visiting daily.
+\item[Sept.] \TeX\ Live 2010 was released: each year the shipping date is earlier; the production process is becoming more streamlined and we congratulate all involved for their hard work. One of the most notable new components of \TeX\ Live 2010 includes the `restricted shell escape' feature to allow, among other things, automatic EPS figure conversion for pdf\LaTeX\ documents.
+\item[Oct.] TLContrib\footnote{\url{http://tlcontrib.metatex.org/}} was opened by Taco Hoekwater as a way to update a \TeX~Live installation with material that is not distributable through \verb|tlmgr| itself. Such material includes executables (e.g., new versions of Lua\TeX), non-free code, or test versions of packages.
+\item[Nov.] Philipp Lehman released the first stable version of \textsf{biblatex}. One of the most ambitious \LaTeX\ packages in recent memory, \textsf{biblatex} is a highly flexible package for managing citation cross-referencing and bibliography typesetting. In `beta' status for some years now, reaching this point is a great milestone.
+\item[Dec.] Lua\TeX\ 0.65. We are happy to see Lua\TeX\ development steadily continuing. \LaTeX\ users may use Lua\TeX\ with the \verb|lualatex| program. Like \verb|xelatex|, this allows \LaTeX\ documents to use multilingual OpenType fonts and Unicode text input.
+\end{itemize}
+
+\section{Current progress}
+
+The \textsf{expl3} programming modules continue to see revision and expansion; we have added a Lua\TeX\ module, but \textsf{expl3} continues to support all three of pdf\LaTeX, \XeLaTeX, and Lua\LaTeX\ equally.
+
+The \textsf{l3fp} module for performing floating-point arithmetic has been extended and improved. Floating point maths is important for some of the calculations required for complex box typesetting performed in the new `coffins' code.
+The \textsf{l3coffin} module has been added based on the original \textsf{xcoffins} package introduced at TUG~2010 as reported in the last news issue; this code is now available from CTAN for testing and feedback.
+
+We have consolidated the \textsf{l3int} and \textsf{l3intexpr} modules (which were separate for historical purposes); all integer/count-related functions are now contained within the `\textsf{int}' code and have prefix \verb|\int_|. Backwards compatibility is provided for, but eventually we will drop support for the older \verb|\intexpr_| function names.
+
+\section{Plans for 2011}
+
+In the following year, we plan to use the current \LaTeX3 infrastructure to continue work in building high-level code for designing \LaTeX\ documents using the \textsf{xtemplate} package. Our first priority is to look at section headings and document divisions, as we see this area as one of the most difficult, design-wise, of the areas to address. From there we will broaden our scope to more document elements.
+
+We will also do some low-level work on the `galley', which is the code that \LaTeX3 uses to build material for constructing pages, and we will continue to extend \textsf{expl3} into a more complete system from which we can, one day, create a pure \LaTeX3 format.
+
+\end{document}
+
+
+
diff --git a/macros/latex-dev/required/l3kernel/l3news06.pdf b/macros/latex-dev/required/l3kernel/l3news06.pdf
new file mode 100644
index 0000000000..d4c6ce71a1
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news06.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news06.tex b/macros/latex-dev/required/l3kernel/l3news06.tex
new file mode 100644
index 0000000000..63ee6c7c75
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news06.tex
@@ -0,0 +1,141 @@
+% Copyright 2011 The LaTeX Project
+\documentclass{ltnews}
+\PassOptionsToPackage{colorlinks}{hyperref}
+
+\usepackage{metalogo,ragged2e}
+
+\AtBeginDocument{
+ \renewcommand{\LaTeXNews}{\LaTeX3~News}
+ \RaggedRight
+}
+
+\usepackage{hologo}
+
+\publicationmonth{June}
+\publicationyear{2011}
+\publicationissue{6}
+
+\begin{document}
+\maketitle
+
+\noindent
+A key aim of releasing `stable' \LaTeX3 material to CTAN is to allow users to
+benefit from new ideas \emph{now}, and also to raise the profile of usable
+\LaTeX3 ideas. This is clearly being successful, with \pkg{xparse} being of
+particular utility to end users. This increase in interest has been
+particularly notable on the new
+\href{http://tex.stackexchange.com/}{TeX.SX Q\&A site}.
+
+\section{The \LaTeX3 Team expands}
+
+Raising interest in \LaTeX3 developments has inevitably led to feedback on
+cases where the code base has required attention. It has also attracted new
+programmers to using \LaTeX3 ideas, some more than others! Bruno Le Floch has
+over the past few months made many useful contributions to \LaTeX3, and we are
+very pleased that he has recently joined The \LaTeX{} Project.
+
+Bruno has taken a particular interest in improving the performance and
+reliability of the \pkg{expl3} language. This has already resulted in new
+implementations for the \texttt{prop} and \texttt{seq} data types. At the same
+time, he has identified and fixed several edge-case issues in core \pkg{expl3}
+macros.
+
+\section{The `Big Bang'}
+
+In parallel to Bruno's improvements, Joseph Wright initiated a series of `Big
+Bang' improvements to \LaTeX3. The aim of the Big Bang was to address a number
+of long-standing issues with the \LaTeX3 code base. Development has taken place
+over many years, with the status of some of the resulting code being less
+than clear, even to members of The \LaTeX{} Project! At the same time, different
+conventions had been applied to different parts of the code, which made reading
+some of the code rather `interesting'. A key part of the Big Bang has been to
+address these issues, cleaning up the existing code and ensuring that the
+status of each part is clear.
+
+The arrangement of \LaTeX3 code is now the same in the development
+repository and on CTAN, and splits the code into three parts.
+\begin{description}
+ \item[\pkg{l3kernel}] The core of \LaTeX3, code which
+ is expected to be used in a \LaTeX3 kernel in more or less the
+ current form. Currently, this part is made up of the \LaTeX3
+ programming layer, \pkg{expl3}.
+ \item[\pkg{l3packages}] \LaTeXe{} packages making use of \LaTeX3
+ concepts and with stable interfaces. The \pkg{xparse} and
+ \pkg{xtemplate} packages are the core of this area. While many of
+ the \emph{ideas} explored here may eventually appear in a \LaTeX3
+ kernel, the interfaces here are tied to \LaTeXe{}.
+ \item[\pkg{l3experimental}] \LaTeXe{} packages which explore more
+ experimental \LaTeX3 ideas, and which may see interface changes as
+ development continues. Over time, we expect code to move from this area
+ to either \pkg{l3kernel} or \pkg{l3packages}, as appropriate.
+\end{description}
+
+In addition to these release areas, the development code also features a
+\pkg{l3trial} section for exploring code ideas. Code in \pkg{l3trial} may be
+used to improve or replace other parts of \LaTeX3, or may simply be dropped!
+
+As well as these improvements to the \emph{code} used in \LaTeX3, much of the
+documentation for \pkg{expl3} has been made more precise as part of the Big
+Bang. This means that \texttt{source3.pdf} is now rather longer than it was
+previously, but also should mean that many of the inaccuracies in earlier
+versions have been removed. Of course, we are very pleased to receive
+suggestions for further improvement.
+
+\section{\LaTeX3 on GitHub}
+
+The core development repository for \LaTeX3 is held in an SVN repository, which
+is \href{http://www.latex-project.org/code.html}{publicly viewable \emph{via}
+the Project website}. However, this interface misses out on some of the `bells
+and whistles' of newer code-hosting sites such as
+\href{http://gitbug.com/}{GitHub} and \href{http://bitbucket.org/}{BitBucket}.
+We have therefore established a mirror of the master repository on GitHub%
+\footnote{\url{http://github.com/latex3/svn-mirror}}. This is kept in
+synchronisation with the main SVN repository by Will Robertson (or at least
+by his laptop!).
+
+The GitHub mirror offers several useful features for people who wish to
+follow the \LaTeX3 code changes. GitHub offers facilities such as highlighted
+differences and notification of changes. It also makes it possible for
+non-Team members to submit patches for \LaTeX3 as `pull requests' on
+GitHub.
+
+As well as offering a convenient interface to the \LaTeX3 code, the GitHub
+site also includes an issue database\footnote{%
+\url{http://github.com/latex3/svn-mirror/issues}}. Given the very
+active nature of \LaTeX3 development, and the transitory nature of many
+of the issues, this provides a better approach to tracking issues than
+the main \LaTeX{} bug database\footnote{\url{http://www.latex-project.org/bugs.html}}.
+Developers and users are
+therefore asked to report any issues with \LaTeX3 code \emph{via} the GitHub
+database, rather than on the main Project homepage.
+Discussion on the \href{http://www.latex-project.org/code.html}{\mbox{LaTeX-L} mailing list}
+is also encouraged.
+
+\section{Next steps}
+
+The `Big Bang' involves making a number of changes to \pkg{expl3} function
+names, and is likely to break at least some third-party code. As a result,
+the updates will not appear on the \TeX{} Live 2011 DVD release, but will
+instead be added to \TeX{} Live once regular updates restart (probably
+August).
+
+Bruno is working on a significant overhaul of the \pkg{l3fp} floating-point
+unit for \LaTeX3. He has developed an approach which allows expandable
+parsing of floating-point expressions, which will eventually allow syntax
+such as
+\begin{verbatim}
+ \fp_parse:n { 3 * 4 ( ln(5) + 1 ) }
+\end{verbatim}
+This will result in some changes in the interface for floating-point numbers, but
+we feel that the long-term benefit is worth a small amount of recoding in other
+areas.
+
+Joseph has completed documentation of the \pkg{xgalley} module, and this is
+currently being discussed. Joseph is hoping to move on to implement other
+more visible ideas based on the \pkg{xtemplate} concept over the next few
+months.
+
+\end{document}
+
+
+
diff --git a/macros/latex-dev/required/l3kernel/l3news07.pdf b/macros/latex-dev/required/l3kernel/l3news07.pdf
new file mode 100644
index 0000000000..f11e905a9b
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news07.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news07.tex b/macros/latex-dev/required/l3kernel/l3news07.tex
new file mode 100644
index 0000000000..2b433da4c4
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news07.tex
@@ -0,0 +1,111 @@
+% Copyright 2012 The LaTeX3 Project
+\documentclass{ltnews}
+\PassOptionsToPackage{colorlinks}{hyperref}
+
+\usepackage{metalogo,ragged2e}
+
+\AtBeginDocument{
+ \renewcommand{\LaTeXNews}{\LaTeX3~News}
+ \RaggedRight
+}
+
+\publicationmonth{February}
+\publicationyear{2012}
+\publicationissue{7}
+
+\begin{document}
+\maketitle
+
+\section{After the `Big Bang'}
+
+The last \LaTeX3 News gave details of the `Big Bang', in which the team have
+revised the layout and coverage of the \LaTeX3 codebase. This process has
+made the status of different modules clearer, so that both the team themselves
+and everyone else know what is going on.
+
+The `Big Bang' changes were not shipped to \textsc{ctan} until after the \TeX{}
+Live 2011 freeze, as we did not want to end up with a \textsc{dvd} containing
+badly broken code. The update went to \textsc{ctan} soon after \TeX{} Live 2011
+shipped, and has now propagated around the world. The new package naming
+(\pkg{l3kernel}, \pkg{l3packages} and \pkg{l3experimental}) has caused some
+surprises for a small number of users, but there have not been any major
+issues with the changes at the code level.
+
+The `Big Bang' has attracted attention from programmers outside of the
+\LaTeX3 team, with useful feedback arriving on the
+\texttt{LaTeX-L} list and TeX.sx, in particular. One area that this has
+highlighted is the need to document carefully when changes to the `stable'
+parts of the \LaTeX3 codebase occur. All changes to \pkg{l3kernel} now
+come with an explicit date for the change in the documentation, which means
+that programmers can check exactly when the features they want were introduced.
+
+Another key part of supporting \LaTeX3 use beyond the team is making it easy
+to check on the version of \LaTeX3 installed. To support that, the file date
+of the main \pkg{expl3} package is now set each time there is a release of the
+\LaTeX3 material to \textsc{ctan}. This means that the \LaTeXe{}
+\cs{@ifpackagelater} test can be used reliably to detect if the installed
+version of \LaTeX3 is going to supply the functions that a programmer is
+using.
+
+\section{Deforming boxes}
+
+Additions to both the \LaTeX3 stable material and more experimental modules
+continue. Joseph Wright has been working on adding `native' drivers for
+\LaTeX3 to support box transformations. These allow box rotation, clipping
+and scaling with the drivers \texttt{dvips}, \texttt{xdvipdfmx} and direct
+\textsc{pdf} output.
+
+The development of clipping support for the \texttt{xdvipdfmx} driver has also allowed
+us to suggest improvements to the \LaTeXe{} graphics drivers, enabling clipping
+with the \XeTeX{} engine.
+
+\section{A \TeX{}-based regex engine}
+
+Bruno Le Floch has been %working across the codebase, %% omitted to avoid page break
+improving the efficiency
+and robustness of a number of \LaTeX3 functions. Most notably, he has
+created a purely \TeX{}-based regular expression (regex) system for \LaTeX3.
+This is currently experimental, but is already proving useful and will
+hopefully stabilise over the coming months.
+
+Bruno's regex system works with all of the supported engines (pdf\TeX{},
+\XeTeX{} and \LuaTeX{}). He has implemented the core ideas of standard
+regex systems, along with some \TeX{}-specifics to allow matching and
+replacing
+the content of token lists % correct?
+by category code.
+
+\section{\pkg{xparse} improves}
+
+The \pkg{xparse} module has been overhauled, making the internal code
+more efficient and adding additional argument types. This has also allowed
+us to deal with a number of internal bugs, meaning that argument grabbing
+is now more reliable.
+
+The argument grabbers themselves have been reworked so that in the event of an error,
+the user will normally get a meaningful message from \TeX{} rather than
+one pointing to \pkg{xparse} internal function names. This should help
+in tracking down erroneous input in real documents.
+
+\section{The galley}
+
+As detailed in the last issue, work on the galley module has been continuing.
+Discussion of Joseph's reimplementation of the galley concepts highlighted
+some important areas to work on, with the nature of the template concept
+being particularly significant.
+
+More work is still needed to finalise the galley concepts, but it is clear that
+some of this will require feedback from other areas. Joseph therefore hopes
+to finish work on the current round of galley improvements by the end of
+February, and to return to them once some other areas have been addressed.
+
+\section{Relationships between document items}
+
+The \textsc{tug}2011 meeting took place in October in India. Frank Mittelbach
+spoke there about ideas for describing the design relationship between document elements.
+% omit calling it "ldb" here because that name will likely change (last I heard?)
+These ideas allow a document designer to specify the design of a document element
+based on its context within a document, and progress in this area will likely
+lead to an extension in the \pkg{xtemplate} system.
+
+\end{document}
diff --git a/macros/latex-dev/required/l3kernel/l3news08.pdf b/macros/latex-dev/required/l3kernel/l3news08.pdf
new file mode 100644
index 0000000000..a56eff92d2
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news08.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news08.tex b/macros/latex-dev/required/l3kernel/l3news08.tex
new file mode 100644
index 0000000000..17107f8360
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news08.tex
@@ -0,0 +1,170 @@
+% Copyright 2012 The LaTeX3 Project
+\documentclass{ltnews}
+
+\PassOptionsToPackage{colorlinks}{hyperref}
+
+\usepackage{metalogo,ragged2e}
+
+\AtBeginDocument{
+ \renewcommand{\LaTeXNews}{\LaTeX3~News}
+ \RaggedRight
+}
+
+\usepackage{expl3,siunitx,catchfile}
+\usepackage{hologo}
+\usepackage{verbatim}% avoid ltnews' "special" verbatim processing
+
+\publicationmonth{July}
+\publicationyear{2012}
+\publicationissue{8}
+
+\def\DTX{\texttt{.dtx}}
+\def\STY{\texttt{.sty}}
+
+\ExplSyntaxOn
+\NewDocumentCommand { \calcnum } { m }
+ { \num { \fp_to_scientific:n {#1} } }
+\ExplSyntaxOff
+
+\begin{document}
+\maketitle
+
+\raisefirstsection
+\section{Extended floating point support}
+
+Bruno Le Floch has been re-writing the floating point module to function in an `expandable' manner. This allows floating point calculations to be computed far more flexibly and efficiently than before.
+The expandable nature of the new code allows its use inside operations such as writing to external files, for which previously any such calculations would have to be pre-calculated before any of the writing operations began.
+
+Bruno's work on the floating point module has been officially released into the main \textsc{svn} repository for \texttt{l3kernel}; \TeX\ Live 2012 will contain the `old' code for stability while this year is spent testing the new code in production environments and ironing out any wrinkles.
+
+Here's a neat example as suggested in the documentation, which produces `\calcnum { round ( 200 pi * sin ( 2.3 ^ 5 ) , 2 ) }':
+
+\begin{verbatim}
+\usepackage{xparse, siunitx}
+\ExplSyntaxOn
+\NewDocumentCommand { \calcnum } { m }
+ { \num { \fp_to_scientific:n {#1} } }
+\ExplSyntaxOff
+
+\calcnum {
+ round ( 200 pi * sin ( 2.3 ^ 5 ) , 2 )
+}
+\end{verbatim}
+
+This feature is invaluable for simple (and not-so-simple) calculations in document and package authoring, and has been lacking a robust solution for many years.
+While \hologo{LuaLaTeX} can perform similar tasks within its Lua environment, the floating point support is written using the \texttt{expl3} programming language only, and is thus available in \hologo{pdfLaTeX} and \hologo{XeLaTeX} as well.
+
+\section{Regular expressions in \TeX}
+
+As if expandable floating point support wasn't enough, Bruno has also written a complete regular expression engine in \texttt{expl3} as well.
+% [Ed: Consider my mind blown.]
+Many reading this will be familiar with the quote attributed to Jamie Zawinski:
+\begin{quote}\itshape
+Some people, when confronted with a problem, think
+``I know, I'll use regular expressions.''
+Now they have two problems.
+\end{quote}
+And as humorous as the saying is, it's still fair to say that regular expressions are a great tool for manipulating streams of text.
+We desperately hope that people will \emph{not} start using the regex code to do things like parse \textsc{xml} documents; however, for general search--replace duties, there's never been anything like \texttt{l3regex} for the \LaTeX\ world.
+As a trivial example, there are
+\CatchFileDef\thisfile{\jobname.tex}{}%
+\ExplSyntaxOn
+\exp_args:Nno \regex_count:nnN { \b (?i) W e \b } {\thisfile} \l_tmpa_int
+\int_use:N \l_tmpa_int
+\ExplSyntaxOff
+~instances of the word `We' or `we' in this document (including those two).
+This value is counted automatically in two lines of code.
+
+And again, it is available for \hologo{pdfLaTeX} and \hologo{XeLaTeX} users as well as \hologo{LuaLaTeX} ones; it also bears noting that this provides an easy solution for applying regular expression processing to \LaTeX\ documents and text data even on the Windows operating system that does not have native support for such things.
+
+
+\section{Separating internal and external code}
+
+\LaTeX\ packages are written by a wide range of package authors and consist of code and commands for various purposes.
+Some of these commands will be intended for use by document authors (such as \verb|\pbox| from the \textsf{pbox} package); others are intended for use by other package writers (such as \verb|\@ifmtarg| from the \textsf{ifmtarg} package).
+
+However, a large portion of them are internal, i.e., are intended to
+be used only within the package or within the \LaTeX{} kernel and
+should not be used elsewhere. For example, \verb|\@float| is the
+\LaTeX{} kernel interface for floats to be used in class files, but
+the actual work is done by a command called \verb|\@xfloat| which
+should not be used directly. Unfortunately the \LaTeXe{} language
+makes no clear distinction between the two, so it is tempting for
+programmers to directly call the latter to save some ``unnecessary''
+parsing activity.
+
+The downside of this is that the ``internal'' commands suddenly act as
+interfaces and a reimplementation or fix in any of them would then
+break add-on packages as they rely on internal behavior. Over the
+course of the last twenty years probably 80\% of such ``internal''
+commands have found their way into one or another package. The
+consequences of this is that nowadays it is next to impossible to
+change anything in the \LaTeXe{} kernel (even if it is clearly just an
+internal command) without breaking something.
+
+
+In \LaTeX3 we hope to improve this situation drastically by
+clearly separating public interfaces (that extension packages can use
+and rely on) and private functions and variables (that should not
+appear outside of their module). There is (nearly) no way to enforce
+this without severe computing overhead, so we implement it only
+through a naming convention, and some support mechanisms. However, we
+think that this naming convention is easy to understand and to follow,
+so that we are confident that this will be adopted and provides the
+desired results.
+
+\subsection{Naming convention for internals}
+
+We've been throwing around some ideas for this for a number of years but nothing quite fit; the issue comes down to the fact that \TeX\ does not have a `name-spacing' mechanism so any internal command needs to have a specific prefix to avoid clashing with other packages' commands.
+The prefix we have finally decided on for \textsf{expl3} code is a double underscore, such that functions like \verb|\seq_count:N| are intended for external use and \verb|\__seq_item:n| is an internal command that should not be used or relied upon by others.
+
+All this is well and good, but it can be inconvenient to type long prefixes such as \verb|\__seq_| before all command names, especially in a package for which nearly \emph{all} package functions are internal.
+
+We therefore also extended \textsf{DocStrip} slightly by adding a `shorthand' for internal package prefixes.
+Commands and variables in \DTX\ code may now contain \texttt{@@} which is expanded to the function prefix when the \STY\ file is extracted.
+As an example, writing
+\begin{verbatim}
+ %<@@=seq>
+ \cs_new:Npn \@@_item:n
+ ...
+\end{verbatim}
+is equivalent to
+\begin{verbatim}
+ \cs_new:Npn \__seq_item:n
+ ...
+\end{verbatim}
+There are clear advantages to this syntax.
+Function names are shorter and therefore easier to type, and code can still be prototyped using the \texttt{@@} syntax
+(e.g., pasting code between a \DTX\ file and a regular \texttt{.tex} document).
+Most importantly, it is explicitly clear from the code source which commands are intended to be used externally and which should be avoided.
+
+We hope that this syntax will prove popular; in our initial experiments we think it works very well. In fact we found a good number of smaller errors when being forced to think about what is internal and what is an external function.
+
+\section{Continual revolution---the `small bang'}
+
+In addition to the major additions introduced above, Frank Mittelbach has been examining \texttt{expl3} with a fresh eye to resolve any outstanding issues in the consistency or logic of the names of functions.
+
+We are very mindful of the fact that for people to find \texttt{expl3} a useful tool, it must have a stable interface.
+This said, there are still some musty corners that we can show where people simply haven't been using certain functions.
+In select cases, we're re-assessing whether all of the (sometimes esoteric) odds and ends that have been added to \texttt{expl3} really belong; in other cases, it's now clear that some naming or behaviour choices weren't correct the first time around.
+
+To address this tarnish, we're carefully making some minor changes to parts of the \texttt{expl3} interface and we'd like to allay any fears that \texttt{expl3} isn't stable.
+The \texttt{expl3} language now offers a wide range of functions plus their variants, and we're talking about changing but a very small percentage of these, and not common ones at that.
+We don't want it to become a mess, so we think it's better to tidy things up as we go.
+Follow the \texttt{LaTeX-L} mailing list for such details as they arise.
+
+\end{document}
+
+
+dropped/replaced:
+
+The \LaTeX3 codebases ranges between these two extremes; the packages
+in \texttt{l3packages} are largely the former while the modules
+composing \textsf{expl3} are largely the latter type. In both cases,
+the `external' commands (whether for document author or package
+writer) are usually defined in terms of other internal package
+commands that should not be used by anyone else, but often when
+reading the internal package code it's not always clear which is
+which.
+
+For \LaTeX3 we are experimenting with an extension to the \textsf{DocStrip} mechanism to provide a clear distinction between internal and external package commands.
diff --git a/macros/latex-dev/required/l3kernel/l3news09.pdf b/macros/latex-dev/required/l3kernel/l3news09.pdf
new file mode 100644
index 0000000000..660eae9025
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news09.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news09.tex b/macros/latex-dev/required/l3kernel/l3news09.tex
new file mode 100644
index 0000000000..55ed700a2c
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news09.tex
@@ -0,0 +1,1433 @@
+% Copyright 2014 The LaTeX3 Project
+\documentclass{ltnews}
+
+\PassOptionsToPackage{colorlinks}{hyperref}
+\usepackage{metalogo,ragged2e}
+
+\AtBeginDocument{
+ \renewcommand{\LaTeXNews}{\LaTeX3~News}
+ \RaggedRight
+ \setlength\parindent{1em}
+}
+
+\hbadness=10000
+\def\Dash{\,---\,}
+
+\providecommand\LuaLaTeX{Lua\LaTeX}
+\setcounter{tocdepth}{2}
+
+\usepackage{enumitem,csquotes}
+\MakeOuterQuote{"}
+\usepackage{fancyvrb}% to allow \Verb"<ul>" to typeset properly since ltnews patches \verb
+
+\makeatletter
+\renewcommand{\@subheadingfont}{%
+ \sffamily\slshape
+ \let\LaTeX\cmssLaTeX\let\TeX\cmssTeX
+}
+\renewcommand{\subsection}{%
+ \@startsection
+ {subsection}{2}{\z@}{-1.3ex \@plus -1ex \@minus -.2ex}%
+ {0.8ex \@plus.2ex}{\@subheadingfont}%
+}
+\makeatother
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\RequirePackage{tikz}
+\definecolor{basecolor}{RGB}{0,128,128}
+\definecolor{maincolor}{RGB}{55,200,113}
+
+
+\newcommand \explbanner{%
+\begin{tikzpicture}[y=0.80pt,x=0.80pt,yscale=-1, inner sep=0pt, outer sep=0pt]
+ \path[fill=basecolor,rounded corners=0.0000cm] (248.7785,295.7529) rectangle
+ (465.3586,478.5802);
+ \path[fill=white,rounded corners=0.0000cm] (257.9199,304.5427) rectangle
+ (456.2172,469.7905);
+ \path[fill=basecolor] (283.2386,478.5760) -- (289.5259,453.4125) .. controls
+ (302.2770,439.6121) and (314.0060,425.3008) .. (319.5695,407.9067) .. controls
+ (355.0759,401.0374) and (383.7853,403.5174) .. (413.7371,404.2858) .. controls
+ (411.0072,403.8309) and (322.2852,388.7992) .. (322.2852,388.7992) .. controls
+ (298.7181,356.5528) and (264.6380,373.5409) .. (249.0663,403.2205) --
+ (248.7470,478.6397) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=1.253pt]
+ (288.4249,394.4251) -- (288.2061,394.8313) .. controls (287.2860,396.5455) and
+ (285.7381,397.6863) .. (283.5499,398.3938) .. controls (281.3616,399.1013) and
+ (278.5647,399.3476) .. (275.2999,399.2063) -- (273.2374,399.1126) --
+ (274.7061,400.5501) .. controls (275.4640,401.2791) and (275.6960,401.8541) ..
+ (275.7061,402.3626) .. controls (275.7162,402.8712) and (275.5103,403.4284) ..
+ (275.0186,404.0501) .. controls (274.0353,405.2935) and (272.0593,406.6472) ..
+ (270.2374,408.0189) -- (269.6749,408.4564) -- (270.0499,409.0501) .. controls
+ (271.5698,411.3818) and (272.2617,413.2035) .. (272.4249,414.5814) .. controls
+ (272.5880,415.9592) and (272.2796,416.9162) .. (271.6436,417.7689) .. controls
+ (270.3717,419.4743) and (267.6257,420.6198) .. (265.1124,422.0501) --
+ (264.6124,422.3314) -- (264.7061,422.8626) .. controls (264.9221,424.1742) and
+ (264.5793,425.2316) .. (263.6436,426.3001) .. controls (262.7079,427.3687) and
+ (261.1571,428.4020) .. (259.0498,429.3001) -- (258.4873,429.5189) --
+ (258.5810,430.1126) .. controls (259.0013,432.9207) and (259.8134,435.3978) ..
+ (261.5810,436.9564) .. controls (263.1945,438.3790) and (265.6272,438.7418) ..
+ (268.7373,438.1126) .. controls (269.2811,441.1124) and (270.0885,443.8463) ..
+ (271.8935,445.6439) .. controls (273.7365,447.4793) and (276.5967,448.0631) ..
+ (280.5185,447.0189) .. controls (281.3879,449.0885) and (282.6104,450.5771) ..
+ (284.0498,451.5501) .. controls (285.6426,452.6269) and (287.4312,453.1746) ..
+ (289.1435,453.7064) -- (289.5810,452.2376) .. controls (287.8816,451.7099) and
+ (286.2778,451.1522) .. (284.9248,450.2376) .. controls (283.5718,449.3230) and
+ (282.4412,448.0628) .. (281.6748,445.8939) -- (281.4248,445.1751) --
+ (280.7060,445.3939) .. controls (276.7309,446.6155) and (274.5047,446.0613) ..
+ (272.9873,444.5501) .. controls (271.4699,443.0389) and (270.6337,440.3179) ..
+ (270.1123,437.1439) -- (269.9873,436.3001) -- (269.1435,436.5189) .. controls
+ (265.8672,437.3737) and (263.9323,436.9328) .. (262.6123,435.7689) .. controls
+ (261.3919,434.6928) and (260.6559,432.7860) .. (260.2373,430.4251) .. controls
+ (262.1657,429.5404) and (263.7732,428.5395) .. (264.8310,427.3314) .. controls
+ (265.8589,426.1576) and (266.3097,424.7444) .. (266.2373,423.2376) .. controls
+ (268.5457,421.9725) and (271.2938,420.8514) .. (272.8935,418.7064) .. controls
+ (273.7344,417.5788) and (274.1920,416.1226) .. (273.9873,414.3939) .. controls
+ (273.8023,412.8317) and (273.0178,411.0042) .. (271.7060,408.8626) .. controls
+ (273.3411,407.6578) and (275.1128,406.4408) .. (276.2373,405.0189) .. controls
+ (276.8610,404.2302) and (277.3196,403.3287) .. (277.2998,402.3314) .. controls
+ (277.2890,401.7896) and (277.0912,401.2653) .. (276.7998,400.7376) .. controls
+ (279.5102,400.7514) and (281.9952,400.5582) .. (284.0498,399.8939) .. controls
+ (286.3053,399.1646) and (288.0426,397.8495) .. (289.2060,396.0189) .. controls
+ (292.5635,396.0371) and (296.0636,396.7806) .. (299.5810,397.2376) .. controls
+ (303.1955,397.7073) and (306.8484,397.8601) .. (310.3310,396.3314) --
+ (309.7060,394.8939) .. controls (306.6247,396.2464) and (303.2846,396.1632) ..
+ (299.7685,395.7064) .. controls (296.2524,395.2495) and (292.5819,394.3984) ..
+ (288.8935,394.4251) -- (288.4248,394.4251) -- cycle;
+ \path[fill=white] (301.5159,393.8637) .. controls (301.5159,397.5244) and
+ (298.5484,400.4920) .. (294.8877,400.4920) .. controls (291.2270,400.4920) and
+ (288.2595,397.5244) .. (288.2595,393.8637) .. controls (288.2595,390.2031) and
+ (291.2270,387.2355) .. (294.8877,387.2355) .. controls (298.5484,387.2355) and
+ (301.5159,390.2031) .. (301.5159,393.8637) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=1.253pt]
+ (321.0186,387.9251) .. controls (315.0680,395.6662) and (313.8600,393.4088) ..
+ (310.2374,394.7063) -- (309.6124,394.9251) -- (309.7374,395.5813) .. controls
+ (311.1321,403.3566) and (315.5160,405.7238) .. (319.1124,408.5501) --
+ (320.0811,407.3313) .. controls (316.4798,404.5012) and (312.9249,402.6094) ..
+ (311.4874,396.0188) .. controls (314.1361,395.3813) and (316.6278,396.2007) ..
+ (322.2686,388.8626) -- (321.0186,387.9251) -- cycle;
+ \path[fill=maincolor] (301.5159,393.8637) .. controls (301.5159,397.5244) and
+ (298.5484,400.4920) .. (294.8877,400.4920) .. controls (291.2270,400.4920) and
+ (288.2595,397.5244) .. (288.2595,393.8637) .. controls (288.2595,390.2031) and
+ (291.2270,387.2355) .. (294.8877,387.2355) .. controls (298.5484,387.2355) and
+ (301.5159,390.2031) .. (301.5159,393.8637) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=1.253pt]
+ (294.8936,386.4563) .. controls (290.8098,386.4563) and (287.4874,389.7788) ..
+ (287.4874,393.8626) .. controls (287.4874,397.9464) and (290.8098,401.2688) ..
+ (294.8936,401.2688) .. controls (298.9774,401.2688) and (302.2999,397.9464) ..
+ (302.2999,393.8626) .. controls (302.2999,389.7788) and (298.9774,386.4563) ..
+ (294.8936,386.4563) -- cycle(294.8936,388.0188) .. controls
+ (298.1312,388.0188) and (300.7374,390.6250) .. (300.7374,393.8626) .. controls
+ (300.7374,397.1002) and (298.1312,399.7063) .. (294.8936,399.7063) .. controls
+ (291.6560,399.7063) and (289.0499,397.1002) .. (289.0499,393.8626) .. controls
+ (289.0499,390.6250) and (291.6560,388.0188) .. (294.8936,388.0188) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=1.253pt]
+ (291.5499,370.7063) .. controls (288.4841,370.7722) and (285.4193,371.2673) ..
+ (282.4249,372.1438) .. controls (269.6164,375.8932) and (256.6677,387.2311) ..
+ (248.7622,400.8596) -- (248.7662,404.0176) .. controls (256.4832,389.5161) and
+ (269.8419,377.4553) .. (282.8625,373.6438) .. controls (286.1465,372.6825) and
+ (289.4914,372.1880) .. (292.8312,372.2376) .. controls (302.8507,372.3862) and
+ (312.9146,377.4187) .. (321.6437,389.3626) -- (321.8312,389.6126) --
+ (322.1437,389.6751) .. controls (322.1437,389.6751) and (383.4924,400.0668) ..
+ (402.2375,403.2376) .. controls (376.3035,402.3430) and (350.4290,401.2333) ..
+ (319.3937,407.2376) -- (318.9250,407.3313) -- (318.8000,407.7688) .. controls
+ (313.2958,424.9775) and (301.6553,439.2096) .. (288.9250,452.9875) --
+ (288.8000,453.1125) -- (288.7375,453.3313) -- (282.4611,478.5810) --
+ (283.9307,478.5810) -- (290.2375,453.8937) .. controls (302.8375,440.2444) and
+ (314.4843,426.0036) .. (320.1437,408.7062) .. controls (355.3332,401.9651) and
+ (383.8501,404.4090) .. (413.7062,405.1750) -- (413.8312,403.6125) .. controls
+ (413.8282,403.6120) and (413.7403,403.6129) .. (413.7375,403.6125) .. controls
+ (410.8928,403.1379) and (323.2219,388.2676) .. (322.6750,388.1750) .. controls
+ (313.7728,376.1342) and (303.2902,370.9006) .. (292.8625,370.7062) .. controls
+ (292.4247,370.6982) and (291.9880,370.6972) .. (291.5500,370.7062) -- cycle;
+ \path[fill=maincolor,miter limit=4.00,line width=0.977pt] (370.0353,433.6332) --
+ (333.5033,433.6332) -- (333.5033,428.6205) .. controls (334.6678,428.5193) and
+ (335.9083,428.4180) .. (337.2248,428.3167) .. controls (338.5413,428.1648) and
+ (339.6299,427.9623) .. (340.4907,427.7091) .. controls (341.9084,427.2534) and
+ (342.9717,426.4686) .. (343.6806,425.3547) .. controls (344.3895,424.1901) and
+ (344.7439,422.6964) .. (344.7439,420.8736) -- (344.7439,334.1385) .. controls
+ (344.7439,332.3158) and (344.3388,330.6195) .. (343.5287,329.0498) .. controls
+ (342.7692,327.4296) and (341.7565,326.1638) .. (340.4907,325.2523) .. controls
+ (339.5793,324.6448) and (337.9084,324.0878) .. (335.4780,323.5814) .. controls
+ (333.0476,323.0752) and (331.0982,322.7714) .. (329.6298,322.6700) --
+ (329.6298,317.8092) -- (357.8073,316.0623) -- (358.8706,317.2016) --
+ (358.8706,419.9622) .. controls (358.8706,421.7344) and (359.1997,423.2028) ..
+ (359.8580,424.3673) .. controls (360.5162,425.4813) and (361.5795,426.3420) ..
+ (363.0479,426.9496) .. controls (364.1618,427.4560) and (365.2504,427.8357) ..
+ (366.3138,428.0889) .. controls (367.4277,428.3420) and (368.6682,428.5193) ..
+ (370.0353,428.6205) -- (370.0353,433.6332);
+ \path[color=black,fill=white,nonzero rule,line width=0.977pt]
+ (357.7812,315.4375) -- (329.5938,317.1875) -- (329.0312,317.2500) --
+ (329.0312,317.8125) -- (329.0312,322.6562) -- (329.0312,323.2500) --
+ (329.5938,323.2813) .. controls (331.0155,323.3795) and (332.9294,323.6847) ..
+ (335.3438,324.1875) .. controls (337.7273,324.6842) and (339.3512,325.2404) ..
+ (340.1250,325.7500) .. controls (340.1300,325.7530) and (340.1517,325.7471) ..
+ (340.1563,325.7500) .. controls (341.3216,326.5942) and (342.2496,327.7784) ..
+ (342.9688,329.3125) -- (343.0001,329.3438) .. controls (343.7660,330.8280) and
+ (344.1251,332.3928) .. (344.1251,334.1251) -- (344.1251,420.8751) .. controls
+ (344.1251,422.6188) and (343.7916,423.9876) .. (343.1563,425.0313) .. controls
+ (342.5262,426.0216) and (341.6206,426.7047) .. (340.3126,427.1251) .. controls
+ (339.5087,427.3615) and (338.4639,427.5701) .. (337.1876,427.7188) .. controls
+ (337.1753,427.7198) and (337.1687,427.7178) .. (337.1563,427.7188) .. controls
+ (335.8502,427.8194) and (334.5947,427.8995) .. (333.4375,428.0001) --
+ (332.9063,428.0626) -- (332.9063,428.6251) -- (332.9063,433.6251) --
+ (332.9063,434.2501) -- (333.5000,434.2501) -- (370.0313,434.2501) --
+ (370.0313,433.6251) -- (370.6563,433.6251) -- (370.6563,428.6251) --
+ (370.6563,428.0626) -- (370.0938,428.0001) .. controls (368.7631,427.9015) and
+ (367.5404,427.7420) .. (366.4688,427.5001) .. controls (366.4598,427.4981) and
+ (366.4466,427.5021) .. (366.4375,427.5001) .. controls (365.4251,427.2570) and
+ (364.3851,426.8939) .. (363.3125,426.4063) -- (363.2812,426.3750) .. controls
+ (361.9048,425.8055) and (360.9567,425.0472) .. (360.3750,424.0625) .. controls
+ (359.7820,423.0135) and (359.4687,421.6654) .. (359.4687,419.9688) --
+ (359.4687,317.1875) -- (359.4687,316.9688) -- (359.3125,316.7813) --
+ (358.2500,315.6563) -- (358.0625,315.4375) -- (357.7812,315.4375) --
+ cycle(357.5625,316.6875) -- (358.2500,317.4062) -- (358.2500,419.9688) ..
+ controls (358.2500,421.8165) and (358.5889,423.3762) .. (359.3125,424.6562) --
+ (359.3438,424.6875) .. controls (360.0742,425.9238) and (361.2340,426.8546) ..
+ (362.7813,427.5000) .. controls (362.7903,427.5041) and (362.8037,427.4960) ..
+ (362.8126,427.5000) .. controls (363.9485,428.0145) and (365.0908,428.4264) ..
+ (366.1876,428.6875) .. controls (367.1668,428.9101) and (368.2823,429.0175) ..
+ (369.4376,429.1250) -- (369.4376,433.0313) -- (334.1251,433.0313) --
+ (334.1251,429.1875) .. controls (335.1314,429.1017) and (336.1652,429.0234) ..
+ (337.2813,428.9375) .. controls (338.6211,428.7830) and (339.7464,428.5489) ..
+ (340.6563,428.2813) -- (340.6876,428.2813) .. controls (342.2151,427.7903) and
+ (343.4000,426.9252) .. (344.1876,425.6875) .. controls (344.9701,424.4021) and
+ (345.3439,422.7770) .. (345.3439,420.8750) -- (345.3439,334.1250) .. controls
+ (345.3439,332.2119) and (344.9169,330.4366) .. (344.0626,328.7813) --
+ (344.0939,328.7813) .. controls (343.2978,327.0829) and (342.2020,325.7280) ..
+ (340.8439,324.7500) .. controls (339.7893,324.0471) and (338.0571,323.4821) ..
+ (335.5939,322.9688) .. controls (333.3923,322.5102) and (331.6955,322.2871) ..
+ (330.2502,322.1563) -- (330.2502,318.3750) -- (357.5627,316.6875) -- cycle;
+ \path[fill=basecolor,miter limit=4.00,line width=0.977pt] (411.1244,461.3551) ..
+ controls (406.3648,461.3550) and (402.0103,460.7474) .. (398.0609,459.5323) ..
+ controls (394.1115,458.3677) and (390.7191,456.7727) .. (387.8836,454.7474) ..
+ controls (385.0481,452.7220) and (382.8456,450.3929) .. (381.2759,447.7600) ..
+ controls (379.7569,445.1270) and (378.9974,442.4181) .. (378.9974,439.6333) ..
+ controls (378.9974,437.1523) and (379.6050,434.9244) .. (380.8202,432.9497) ..
+ controls (382.0354,430.9244) and (383.9848,429.9117) .. (386.6684,429.9117) ..
+ controls (389.7064,429.9117) and (392.0102,430.6712) .. (393.5799,432.1902) ..
+ controls (395.2001,433.6586) and (396.0103,435.3548) .. (396.0103,437.2789) ..
+ controls (396.0103,438.8991) and (395.7318,440.9498) .. (395.1748,443.4308) ..
+ controls (394.6685,445.9118) and (394.2634,447.6840) .. (393.9596,448.7473) ..
+ controls (394.3140,449.2030) and (394.9470,449.8106) .. (395.8584,450.5701) ..
+ controls (396.8204,451.3296) and (397.9850,452.0132) .. (399.3521,452.6208) ..
+ controls (400.9723,453.3803) and (402.6686,453.9879) .. (404.4408,454.4436) ..
+ controls (406.2129,454.8993) and (408.7192,455.1271) .. (411.9598,455.1272) ..
+ controls (414.9978,455.1271) and (417.9092,454.6208) .. (420.6941,453.6081) ..
+ controls (423.5295,452.5955) and (426.0106,450.9752) .. (428.1372,448.7473) ..
+ controls (430.3650,446.4182) and (432.0866,443.6840) .. (433.3018,440.5447) ..
+ controls (434.5676,437.4561) and (435.2005,433.3801) .. (435.2006,428.3167) ..
+ controls (435.2005,425.5825) and (434.8967,422.8736) .. (434.2892,420.1901) ..
+ controls (433.7322,417.5065) and (432.6689,415.1774) .. (431.0993,413.2026) ..
+ controls (429.5296,411.2280) and (427.3777,409.7090) .. (424.6435,408.6456) ..
+ controls (421.9599,407.5317) and (418.5421,406.9747) .. (414.3902,406.9747) --
+ (404.4408,406.9747) -- (404.4408,398.2404) -- (411.0484,398.2404) .. controls
+ (418.0358,398.2405) and (423.0738,396.3164) .. (426.1625,392.4682) .. controls
+ (429.2511,388.6201) and (430.7954,382.8226) .. (430.7955,375.0756) .. controls
+ (430.7954,368.7465) and (429.3017,363.9870) .. (426.3144,360.7970) .. controls
+ (423.3270,357.5565) and (419.0991,355.9363) .. (413.6307,355.9362) .. controls
+ (410.9978,355.9363) and (408.8205,356.2654) .. (407.0990,356.9235) .. controls
+ (405.4281,357.5312) and (404.0610,358.1388) .. (402.9977,358.7463) .. controls
+ (401.7318,359.4553) and (400.6939,360.2401) .. (399.8838,361.1008) .. controls
+ (399.0736,361.9616) and (398.4660,362.5946) .. (398.0609,362.9995) .. controls
+ (398.4153,364.6199) and (398.8457,366.6199) .. (399.3521,368.9996) .. controls
+ (399.8584,371.3288) and (400.1116,373.5567) .. (400.1116,375.6832) .. controls
+ (400.1116,377.5567) and (399.3014,379.2529) .. (397.6812,380.7719) .. controls
+ (396.1115,382.2403) and (393.7824,382.9745) .. (390.6938,382.9744) .. controls
+ (388.0102,382.9745) and (386.0355,382.0125) .. (384.7697,380.0883) .. controls
+ (383.5544,378.1643) and (382.9468,375.9365) .. (382.9469,373.4047) .. controls
+ (382.9468,370.7718) and (383.6810,368.0883) .. (385.1494,365.3540) .. controls
+ (386.6178,362.6199) and (388.7950,360.0629) .. (391.6811,357.6830) .. controls
+ (394.5672,355.3033) and (398.0862,353.3793) .. (402.2382,351.9108) .. controls
+ (406.3901,350.4425) and (411.1750,349.7083) .. (416.5928,349.7083) .. controls
+ (422.8207,349.7083) and (427.9599,350.6451) .. (432.0107,352.5184) .. controls
+ (436.1119,354.3413) and (439.3271,356.5692) .. (441.6564,359.2020) .. controls
+ (443.9348,361.7844) and (445.5044,364.4933) .. (446.3653,367.3287) .. controls
+ (447.2260,370.1642) and (447.6564,372.5947) .. (447.6564,374.6199) .. controls
+ (447.6563,377.1517) and (447.3019,379.7087) .. (446.5931,382.2909) .. controls
+ (445.8842,384.8226) and (444.7196,387.1771) .. (443.0994,389.3543) .. controls
+ (441.3272,391.7341) and (438.9727,393.9113) .. (436.0360,395.8860) .. controls
+ (433.1499,397.8101) and (429.5043,399.3797) .. (425.0992,400.5949) --
+ (425.0992,401.8101) .. controls (427.9346,402.0633) and (430.9473,402.6962) ..
+ (434.1373,403.7089) .. controls (437.3778,404.7216) and (440.2892,406.2152) ..
+ (442.8716,408.1899) .. controls (445.5551,410.2659) and (447.7576,412.9495) ..
+ (449.4792,416.2406) .. controls (451.2007,419.4812) and (452.0615,423.6078) ..
+ (452.0615,428.6205) .. controls (452.0615,438.3422) and (448.1627,446.2156) ..
+ (440.3652,452.2410) .. controls (432.5676,458.3170) and (422.8207,461.3550) ..
+ (411.1244,461.3551);
+ \path[color=black,fill=white,nonzero rule,line width=0.977pt]
+ (416.5938,349.0938) .. controls (411.1208,349.0938) and (406.2619,349.8476) ..
+ (402.0312,351.3438) .. controls (397.8235,352.8319) and (394.2307,354.7869) ..
+ (391.2812,357.2188) .. controls (388.3458,359.6393) and (386.1373,362.2465) ..
+ (384.6250,365.0625) .. controls (383.1180,367.8687) and (382.3437,370.6599) ..
+ (382.3438,373.4062) .. controls (382.3437,376.0357) and (382.9702,378.3800) ..
+ (384.2500,380.4062) -- (384.2500,380.4375) .. controls (385.6247,382.5272) and
+ (387.8580,383.5938) .. (390.6875,383.5938) .. controls (393.8729,383.5938) and
+ (396.3782,382.8237) .. (398.0938,381.2188) .. controls (399.8054,379.6142) and
+ (400.7187,377.7371) .. (400.7188,375.6875) .. controls (400.7187,373.5126) and
+ (400.4520,371.2419) .. (399.9375,368.8750) .. controls (399.4598,366.6301) and
+ (399.0615,364.7892) .. (398.7188,363.2188) .. controls (399.1249,362.8074) and
+ (399.6263,362.2937) .. (400.3438,361.5313) .. controls (401.1024,360.7253) and
+ (402.0588,359.9659) .. (403.2812,359.2813) -- (403.3125,359.2813) .. controls
+ (404.3323,358.6986) and (405.6639,358.0996) .. (407.3125,357.5000) .. controls
+ (408.9371,356.8790) and (411.0429,356.5314) .. (413.6250,356.5313) .. controls
+ (418.9728,356.5314) and (423.0134,358.1148) .. (425.8750,361.2188) .. controls
+ (428.7247,364.2617) and (430.1875,368.8295) .. (430.1875,375.0625) .. controls
+ (430.1875,382.7284) and (428.6509,388.4017) .. (425.6875,392.0938) .. controls
+ (422.7395,395.7667) and (417.9378,397.6251) .. (411.0625,397.6250) --
+ (404.4375,397.6250) -- (403.8438,397.6250) -- (403.8438,398.2500) --
+ (403.8438,406.9688) -- (403.8438,407.5938) -- (404.4375,407.5938) --
+ (414.3750,407.5938) .. controls (418.4724,407.5938) and (421.8256,408.1476) ..
+ (424.4063,409.2188) -- (424.4376,409.2188) .. controls (427.0895,410.2502) and
+ (429.1296,411.7125) .. (430.6251,413.5938) .. controls (432.1327,415.4906) and
+ (433.1477,417.7115) .. (433.6876,420.3125) .. controls (434.2853,422.9526) and
+ (434.5938,425.6236) .. (434.5938,428.3125) .. controls (434.5938,433.3250) and
+ (433.9715,437.3322) .. (432.7501,440.3125) -- (432.7188,440.3125) .. controls
+ (431.5305,443.3821) and (429.8590,446.0423) .. (427.6875,448.3125) .. controls
+ (425.6226,450.4758) and (423.2475,452.0501) .. (420.5000,453.0313) .. controls
+ (417.7822,454.0196) and (414.9389,454.5313) .. (411.9688,454.5313) .. controls
+ (408.7568,454.5313) and (406.2790,454.2771) .. (404.5938,453.8438) .. controls
+ (402.8574,453.3973) and (401.2103,452.8056) .. (399.6250,452.0625) --
+ (399.5938,452.0625) .. controls (398.2643,451.4717) and (397.1638,450.8152) ..
+ (396.2500,450.0938) .. controls (395.4421,449.4205) and (394.9503,448.9158) ..
+ (394.6250,448.5313) .. controls (394.9285,447.4218) and (395.3093,445.8751) ..
+ (395.7812,443.5625) .. controls (396.3444,441.0538) and (396.6250,438.9715) ..
+ (396.6250,437.2813) .. controls (396.6250,435.1859) and (395.7186,433.3075) ..
+ (394.0000,431.7500) .. controls (392.2889,430.0942) and (389.7960,429.3125) ..
+ (386.6562,429.3125) .. controls (383.8191,429.3125) and (381.5985,430.4297) ..
+ (380.2812,432.6250) -- (380.3125,432.6250) .. controls (379.0375,434.6970) and
+ (378.3750,437.0443) .. (378.3750,439.6250) .. controls (378.3750,442.5209) and
+ (379.1845,445.3489) .. (380.7500,448.0625) .. controls (382.3672,450.7752) and
+ (384.6374,453.1829) .. (387.5313,455.2500) .. controls (390.4308,457.3211) and
+ (393.8715,458.9445) .. (397.8750,460.1250) .. controls (401.8903,461.3605) and
+ (406.3135,461.9688) .. (411.1250,461.9688) .. controls (422.9271,461.9688) and
+ (432.8357,458.8858) .. (440.7500,452.7188) .. controls (448.6732,446.5963) and
+ (452.6875,438.5099) .. (452.6875,428.6250) .. controls (452.6875,423.5424) and
+ (451.8139,419.3245) .. (450.0313,415.9688) .. controls (448.2737,412.6089) and
+ (446.0071,409.8517) .. (443.2500,407.7188) .. controls (440.6098,405.6999) and
+ (437.6168,404.1577) .. (434.3125,403.1250) .. controls (431.2903,402.1656) and
+ (428.4437,401.5684) .. (425.7188,401.2813) -- (425.7188,401.0313) .. controls
+ (429.9462,399.8234) and (433.5316,398.3019) .. (436.3750,396.4063) .. controls
+ (439.3588,394.4000) and (441.7734,392.1633) .. (443.5938,389.7188) .. controls
+ (445.2562,387.4849) and (446.4583,385.0731) .. (447.1875,382.4688) --
+ (447.1875,382.4375) .. controls (447.9098,379.8061) and (448.2812,377.2137) ..
+ (448.2813,374.6250) .. controls (448.2812,372.5132) and (447.8100,370.0304) ..
+ (446.9375,367.1562) .. controls (446.0482,364.2269) and (444.4516,361.4494) ..
+ (442.1250,358.8125) .. controls (439.7295,356.1046) and (436.4304,353.8164) ..
+ (432.2813,351.9688) .. controls (432.2733,351.9647) and (432.2585,351.9728) ..
+ (432.2500,351.9688) .. controls (428.0952,350.0532) and (422.8701,349.0938) ..
+ (416.5938,349.0938) -- cycle(416.5938,350.3125) .. controls
+ (422.7604,350.3126) and (427.8075,351.2392) .. (431.7500,353.0625) .. controls
+ (435.7908,354.8585) and (438.9298,357.0417) .. (441.1875,359.5938) .. controls
+ (443.4178,362.1216) and (444.9489,364.7586) .. (445.7812,367.5000) .. controls
+ (446.6302,370.2969) and (447.0312,372.6862) .. (447.0312,374.6250) .. controls
+ (447.0312,377.0998) and (446.6953,379.5919) .. (446.0000,382.1250) .. controls
+ (445.3114,384.5842) and (444.2030,386.8795) .. (442.6250,389.0000) .. controls
+ (440.9009,391.3151) and (438.5771,393.4320) .. (435.6875,395.3750) .. controls
+ (432.8713,397.2525) and (429.2959,398.7977) .. (424.9375,400.0000) --
+ (424.5000,400.1250) -- (424.5000,400.5938) -- (424.5000,401.8125) --
+ (424.5000,402.3750) -- (425.0312,402.4063) .. controls (427.8151,402.6549) and
+ (430.7833,403.2800) .. (433.9375,404.2813) -- (433.9688,404.2813) .. controls
+ (437.1455,405.2741) and (439.9756,406.7571) .. (442.5000,408.6875) .. controls
+ (445.1100,410.7067) and (447.2519,413.3089) .. (448.9375,416.5313) .. controls
+ (450.5978,419.6567) and (451.4375,423.6822) .. (451.4375,428.6250) .. controls
+ (451.4375,438.1834) and (447.6718,445.8218) .. (440.0000,451.7500) .. controls
+ (432.3192,457.7351) and (422.7156,460.7500) .. (411.1250,460.7500) .. controls
+ (406.4174,460.7500) and (402.1335,460.1325) .. (398.2500,458.9375) --
+ (398.2188,458.9375) .. controls (394.3234,457.7889) and (391.0214,456.2296) ..
+ (388.2500,454.2500) .. controls (385.4806,452.2719) and (383.3338,450.0134) ..
+ (381.8125,447.4688) .. controls (381.8075,447.4598) and (381.8175,447.4462) ..
+ (381.8125,447.4375) .. controls (380.3501,444.8937) and (379.5938,442.2897) ..
+ (379.5938,439.6250) .. controls (379.5938,437.2436) and (380.1884,435.1587) ..
+ (381.3438,433.2812) -- (381.3438,433.2500) .. controls (382.4569,431.3946) and
+ (384.1263,430.5312) .. (386.6562,430.5312) .. controls (389.5925,430.5312) and
+ (391.7280,431.2428) .. (393.1562,432.6250) -- (393.1562,432.6562) .. controls
+ (394.6782,434.0355) and (395.4062,435.5285) .. (395.4062,437.2812) .. controls
+ (395.4062,438.8316) and (395.1445,440.8592) .. (394.5938,443.3125) --
+ (394.5625,443.3125) .. controls (394.0575,445.7868) and (393.6689,447.5649) ..
+ (393.3750,448.5938) -- (393.2812,448.8750) -- (393.4688,449.1250) .. controls
+ (393.8779,449.6511) and (394.5411,450.2582) .. (395.4688,451.0312) --
+ (395.4688,451.0625) .. controls (396.4790,451.8601) and (397.6889,452.5632) ..
+ (399.0938,453.1875) .. controls (400.7490,453.9634) and (402.4733,454.5664) ..
+ (404.2812,455.0313) .. controls (406.1403,455.5093) and (408.6995,455.7500) ..
+ (411.9688,455.7500) .. controls (415.0746,455.7500) and (418.0544,455.2246) ..
+ (420.9062,454.1875) .. controls (423.8297,453.1434) and (426.4054,451.4488) ..
+ (428.5938,449.1563) .. controls (430.8716,446.7748) and (432.6333,443.9792) ..
+ (433.8750,440.7813) .. controls (433.8780,440.7723) and (433.8720,440.7589) ..
+ (433.8750,440.7500) .. controls (435.1781,437.5565) and (435.8124,433.4132) ..
+ (435.8125,428.3125) .. controls (435.8124,425.5331) and (435.4924,422.7896) ..
+ (434.8750,420.0625) .. controls (434.3008,417.2964) and (433.1940,414.8651) ..
+ (431.5625,412.8125) .. controls (429.9186,410.7444) and (427.6914,409.1578) ..
+ (424.8750,408.0625) -- (424.8750,408.0938) .. controls (422.0884,406.9371) and
+ (418.5815,406.3751) .. (414.3750,406.3750) -- (405.0625,406.3750) --
+ (405.0625,398.8438) -- (411.0625,398.8438) .. controls (418.1619,398.8438) and
+ (423.3956,396.8673) .. (426.6250,392.8438) .. controls (429.8388,388.8397) and
+ (431.4062,382.8907) .. (431.4062,375.0625) .. controls (431.4062,368.6374) and
+ (429.8750,363.7121) .. (426.7500,360.3750) .. controls (423.6367,356.9981) and
+ (419.2140,355.3126) .. (413.6250,355.3125) .. controls (410.9412,355.3126) and
+ (408.6935,355.6486) .. (406.8750,356.3438) .. controls (405.1817,356.9596) and
+ (403.7942,357.5864) .. (402.6875,358.2188) .. controls (401.3782,358.9521) and
+ (400.2991,359.7722) .. (399.4375,360.6875) .. controls (398.6294,361.5462) and
+ (398.0210,362.1666) .. (397.6250,362.5625) -- (397.4062,362.8125) --
+ (397.4688,363.1250) .. controls (397.8228,364.7437) and (398.2438,366.7461) ..
+ (398.7500,369.1250) .. controls (399.2481,371.4166) and (399.5000,373.6095) ..
+ (399.5000,375.6875) .. controls (399.5000,377.3850) and (398.7789,378.8793) ..
+ (397.2500,380.3125) .. controls (395.8262,381.6445) and (393.6794,382.3751) ..
+ (390.6875,382.3750) .. controls (388.1498,382.3751) and (386.4382,381.5087) ..
+ (385.2812,379.7500) .. controls (384.1306,377.9283) and (383.5625,375.8403) ..
+ (383.5625,373.4063) .. controls (383.5625,370.8869) and (384.2578,368.3186) ..
+ (385.6875,365.6563) .. controls (387.1119,363.0040) and (389.2257,360.4955) ..
+ (392.0625,358.1563) .. controls (394.8853,355.8288) and (398.3413,353.9488) ..
+ (402.4375,352.5000) .. controls (406.5107,351.0596) and (411.2311,350.3126) ..
+ (416.5938,350.3125) -- cycle;
+\end{tikzpicture}
+}
+
+
+
+\newcommand \explogo{%
+\begin{tikzpicture}[y=0.45pt,x=0.45pt,yscale=-1, inner sep=0pt, outer sep=0pt]
+ \path[fill=black] (188.1546,427.4287) .. controls (190.5345,431.7164) and
+ (193.0099,435.4077) .. (195.5921,438.5850) -- (195.6233,438.6163) .. controls
+ (195.6323,438.6274) and (195.6455,438.6365) .. (195.6545,438.6476) .. controls
+ (194.4650,438.4740) and (193.2397,438.3529) .. (191.9670,438.3663) .. controls
+ (189.4530,438.3928) and (186.7534,438.8247) .. (183.8420,439.7413) .. controls
+ (188.8419,443.9283) and (193.0993,446.9893) .. (196.8420,449.3663) .. controls
+ (196.7505,449.3362) and (196.6520,449.3022) .. (196.5607,449.2726) --
+ (196.8420,449.4289) .. controls (191.0442,447.6143) and (184.7895,447.3923) ..
+ (177.4670,450.8664) .. controls (182.7247,454.1565) and (187.1369,456.5570) ..
+ (191.0295,458.3664) .. controls (190.9155,458.3495) and (190.7995,458.3198) ..
+ (190.6857,458.3039) -- (190.9670,458.4601) .. controls (184.8999,457.4153) and
+ (178.6035,458.0026) .. (171.7482,462.5226) .. controls (176.2179,464.5144) and
+ (180.1011,466.0179) .. (183.5607,467.1789) -- (183.5919,467.1789) --
+ (183.8107,467.3039) .. controls (178.0253,467.5288) and (172.2917,469.3302) ..
+ (166.6857,474.6476) .. controls (171.5829,475.8624) and (175.7757,476.6736) ..
+ (179.4669,477.2101) .. controls (179.3633,477.2310) and (179.2580,477.2503) ..
+ (179.1544,477.2726) .. controls (179.0103,477.2696) and (178.8604,477.2746) ..
+ (178.7169,477.2726) -- (178.8732,477.3351) .. controls (174.5605,478.3144) and
+ (170.3552,480.4767) .. (166.2482,484.6164) .. controls (169.5756,485.3353) and
+ (172.5696,485.8937) .. (175.3107,486.3039) .. controls (171.9361,487.9351) and
+ (168.7309,490.4629) .. (165.8107,494.3351) .. controls (169.6449,494.6328) and
+ (173.0419,494.7600) .. (176.0919,494.7726) .. controls (172.4017,496.4801) and
+ (168.9244,499.1610) .. (165.8419,503.4914) .. controls (171.3184,503.7651) and
+ (175.8960,503.7533) .. (179.8419,503.5226) .. controls (179.7681,503.5528) and
+ (179.6968,503.5855) .. (179.6232,503.6163) .. controls (179.3834,503.6377) and
+ (179.1427,503.6531) .. (178.9044,503.6788) -- (179.2482,503.8038) .. controls
+ (175.1462,505.6048) and (171.3495,508.5232) .. (168.0919,513.4600) .. controls
+ (174.8980,513.5594) and (180.2892,513.2381) .. (184.8107,512.6788) .. controls
+ (184.6730,512.7162) and (184.5417,512.7645) .. (184.4044,512.8038) .. controls
+ (184.2299,512.8144) and (184.0455,512.8223) .. (183.8732,512.8350) --
+ (184.0919,512.8975) .. controls (178.7598,514.4860) and (173.8363,517.5457) ..
+ (169.7482,523.7412) .. controls (175.2461,523.8214) and (179.8367,523.6133) ..
+ (183.7794,523.2412) .. controls (183.6938,523.2879) and (183.6146,523.3500) ..
+ (183.5294,523.3975) .. controls (178.8190,526.0253) and (174.7697,529.9721) ..
+ (172.0919,536.6475) .. controls (176.9272,535.7317) and (180.9801,534.7653) ..
+ (184.4982,533.7412) .. controls (184.4398,533.7875) and (184.3686,533.8191) ..
+ (184.3107,533.8662) -- (184.5294,533.8350) .. controls (180.9081,536.5374) and
+ (177.8636,540.3240) .. (175.8107,545.9288) .. controls (179.1397,545.1929) and
+ (182.1140,544.4194) .. (184.7794,543.6475) .. controls (182.3867,546.5404) and
+ (180.5386,550.1515) .. (179.4982,554.8975) .. controls (183.1131,553.5663) and
+ (186.2487,552.2854) .. (189.0294,551.0225) .. controls (188.9958,551.0619) and
+ (188.9691,551.1079) .. (188.9357,551.1475) .. controls (188.8789,551.1923) and
+ (188.8034,551.2277) .. (188.7482,551.2725) -- (188.8419,551.2413) .. controls
+ (186.2910,554.2981) and (184.3447,558.1421) .. (183.3732,563.2413) .. controls
+ (188.4628,561.2062) and (192.6027,559.2529) .. (196.0919,557.3976) .. controls
+ (195.9933,557.4930) and (195.8722,557.5825) .. (195.7794,557.6788) --
+ (195.8731,557.6476) .. controls (192.7873,561.0321) and (190.4833,565.3800) ..
+ (189.5606,571.3664) .. controls (195.5682,568.7142) and (200.1972,566.2494) ..
+ (203.9981,563.9289) .. controls (203.9580,563.9700) and (203.9127,564.0127) ..
+ (203.8731,564.0539) -- (204.1231,563.9289) .. controls (199.8075,567.6248) and
+ (196.4969,572.5288) .. (195.3419,580.0226) .. controls (203.4387,576.4482) and
+ (209.1016,573.2112) .. (213.4981,570.2101) .. controls (211.6101,574.0286) and
+ (210.6125,578.4777) .. (211.0919,584.0539) .. controls (218.9172,578.0502) and
+ (223.8713,573.2098) .. (227.5606,568.9289) .. controls (227.5546,568.9906) and
+ (227.5656,569.0545) .. (227.5606,569.1164) .. controls (227.3369,571.8296) and
+ (227.5060,574.7714) .. (228.3106,578.0226) .. controls (232.9500,570.0520) and
+ (237.5899,566.7480) .. (242.3106,564.0226) .. controls (236.4069,567.8493) and
+ (237.4669,570.9503) .. (237.4669,574.4914) .. controls (244.4870,567.0983) and
+ (254.2537,559.2459) .. (257.2481,554.3351) .. controls (253.2445,560.3478) and
+ (251.6457,566.0579) .. (250.5919,571.0851) .. controls (230.1065,581.9187) and
+ (217.6060,584.7541) .. (203.6231,589.0851) .. controls (209.0471,591.0745) and
+ (214.8691,593.0070) .. (212.4669,595.7726) -- (206.0606,602.1789) .. controls
+ (210.1567,600.9056) and (214.3405,599.0697) .. (217.9669,601.5539) .. controls
+ (217.6110,604.9137) and (213.3733,606.6264) .. (209.7481,608.5851) .. controls
+ (216.1304,606.2854) and (217.5075,606.8270) .. (219.1856,607.3664) .. controls
+ (220.0240,611.3923) and (217.1123,613.5511) .. (215.2169,616.2101) .. controls
+ (231.2927,603.9867) and (252.2574,594.3357) .. (267.0294,590.3039) .. controls
+ (287.8076,583.3065) and (314.6175,576.0122) .. (321.9044,558.2726) --
+ (329.1856,529.0226) .. controls (337.7280,519.7775) and (345.5838,510.2065) ..
+ (349.3108,498.5539) .. controls (373.0973,493.9520) and (392.3393,495.6016) ..
+ (412.4046,496.1164) .. controls (410.5758,495.8116) and (351.1546,485.7414) ..
+ (351.1546,485.7414) .. controls (333.7856,461.9756) and (307.8721,478.1391) ..
+ (299.3421,501.6164) .. controls (297.1891,507.5420) and (284.9022,507.5289) ..
+ (281.3421,501.5852) .. controls (267.2670,471.2820) and (224.5286,439.2367) ..
+ (188.1546,427.4289) -- cycle;
+ \path[fill=basecolor] (187.7346,425.7215) .. controls (190.1312,430.0392) and
+ (192.6231,433.7232) .. (195.2248,436.9158) .. controls (194.0353,436.7423) and
+ (192.8098,436.6402) .. (191.5371,436.6536) .. controls (189.0231,436.6801) and
+ (186.3356,437.0974) .. (183.4241,438.0140) .. controls (188.5047,442.2685) and
+ (192.7982,445.3733) .. (196.5852,447.7660) .. controls (190.7343,445.8972) and
+ (184.4338,445.6311) .. (177.0321,449.1427) .. controls (182.4382,452.5257) and
+ (186.9760,454.9705) .. (190.9471,456.7968) .. controls (184.7555,455.6556) and
+ (178.3356,456.1756) .. (171.3284,460.7959) .. controls (175.9548,462.8576) and
+ (179.9558,464.4054) .. (183.5061,465.5818) .. controls (177.6784,465.7855) and
+ (171.9101,467.5854) .. (166.2639,472.9408) .. controls (171.1611,474.1557) and
+ (175.3568,474.9612) .. (179.0480,475.4977) .. controls (174.5307,476.4104) and
+ (170.0996,478.5772) .. (165.8050,482.9059) .. controls (169.1324,483.6248) and
+ (172.1275,484.1674) .. (174.8686,484.5777) .. controls (171.4940,486.2088) and
+ (168.2990,488.7365) .. (165.3788,492.6087) .. controls (169.2130,492.9064) and
+ (172.6053,493.0386) .. (175.6553,493.0512) .. controls (171.9650,494.7587) and
+ (168.5104,497.4567) .. (165.4280,501.7871) .. controls (170.9044,502.0608) and
+ (175.4790,502.0342) .. (179.4250,501.8034) .. controls (175.0884,503.5763) and
+ (171.0915,506.5720) .. (167.6734,511.7521) .. controls (174.4795,511.8515) and
+ (179.8697,511.5247) .. (184.3911,510.9654) .. controls (178.7800,512.4888) and
+ (173.5859,515.5521) .. (169.3124,522.0286) .. controls (174.8103,522.1088) and
+ (179.3994,521.9089) .. (183.3421,521.5369) .. controls (178.5221,524.1635) and
+ (174.3823,528.1477) .. (171.6562,534.9438) .. controls (176.6186,534.0040) and
+ (180.7774,532.9979) .. (184.3583,531.9445) .. controls (180.6281,534.6591) and
+ (177.4926,538.4719) .. (175.3930,544.2041) .. controls (178.7220,543.4682) and
+ (181.6765,542.6978) .. (184.3419,541.9259) .. controls (181.9491,544.8188) and
+ (180.1048,548.4397) .. (179.0644,553.1858) .. controls (182.6793,551.8545) and
+ (185.8062,550.5643) .. (188.5869,549.3014) .. controls (185.9451,552.3928) and
+ (183.9273,556.3063) .. (182.9324,561.5282) .. controls (188.0220,559.4931) and
+ (192.1617,557.5487) .. (195.6510,555.6934) .. controls (192.4524,559.1128) and
+ (190.0726,563.5113) .. (189.1278,569.6412) .. controls (195.3243,566.9057) and
+ (200.0785,564.3715) .. (203.9442,561.9871) .. controls (199.5047,565.7077) and
+ (196.0910,570.6550) .. (194.9134,578.2951) .. controls (203.0102,574.7206) and
+ (208.6604,571.4786) .. (213.0570,568.4775) .. controls (211.1690,572.2961) and
+ (210.1683,576.7672) .. (210.6477,582.3434) .. controls (218.4730,576.3397) and
+ (223.4302,571.4800) .. (227.1195,567.1991) .. controls (226.8707,569.9634) and
+ (227.0669,572.9701) .. (227.8899,576.2955) .. controls (233.5078,566.6437) and
+ (239.0905,563.8256) .. (244.8678,560.6045) .. controls (235.6654,565.2375) and
+ (237.0296,568.7253) .. (237.0296,572.7723) .. controls (244.0497,565.3793) and
+ (253.8400,557.5393) .. (256.8344,552.6285) .. controls (252.8308,558.6412) and
+ (251.2011,564.3353) .. (250.1474,569.3626) .. controls (229.6620,580.1962) and
+ (217.1896,583.0276) .. (203.2067,587.3587) .. controls (208.6306,589.3481) and
+ (214.4431,591.2965) .. (212.0409,594.0622) -- (205.6324,600.4542) .. controls
+ (209.7285,599.1810) and (213.9051,597.3636) .. (217.5315,599.8478) .. controls
+ (217.1756,603.2077) and (212.9289,604.9040) .. (209.3037,606.8627) .. controls
+ (215.6860,604.5630) and (217.0662,605.0941) .. (218.7443,605.6335) .. controls
+ (219.5827,609.6594) and (216.6733,611.8250) .. (214.7780,614.4840) .. controls
+ (230.8537,602.2606) and (251.8308,592.6034) .. (266.6028,588.5716) .. controls
+ (287.3810,581.5741) and (314.1729,574.3016) .. (321.4598,556.5621) --
+ (328.7697,527.3061) .. controls (337.3119,518.0610) and (345.1694,508.4736) ..
+ (348.8965,496.8210) .. controls (372.6829,492.2191) and (391.9159,493.8805) ..
+ (411.9812,494.3952) .. controls (410.1524,494.0905) and (350.7157,484.0204) ..
+ (350.7157,484.0204) .. controls (333.3467,460.2547) and (307.4537,476.4086) ..
+ (298.9237,499.8859) .. controls (296.7707,505.8115) and (284.4877,505.8133) ..
+ (280.9276,499.8695) .. controls (266.8525,469.5663) and (224.1086,437.5293) ..
+ (187.7346,425.7216) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (328.0690,487.7425) -- (327.9127,487.9925) .. controls (327.2963,489.1409) and
+ (326.2537,489.9248) .. (324.7877,490.3988) .. controls (323.3218,490.8728) and
+ (321.4437,491.0247) .. (319.2565,490.9300) -- (317.8815,490.8675) --
+ (318.8815,491.8363) .. controls (319.3892,492.3246) and (319.5310,492.7144) ..
+ (319.5377,493.0550) .. controls (319.5447,493.3957) and (319.3983,493.7636) ..
+ (319.0690,494.1800) .. controls (318.4103,495.0130) and (317.1020,495.9174) ..
+ (315.8815,496.8363) -- (315.4752,497.1175) -- (315.7565,497.5238) .. controls
+ (316.7747,499.0858) and (317.2409,500.2883) .. (317.3502,501.2113) .. controls
+ (317.4595,502.1343) and (317.2450,502.7963) .. (316.8190,503.3675) .. controls
+ (315.9669,504.5101) and (314.0965,505.2843) .. (312.4127,506.2425) --
+ (312.1002,506.3988) -- (312.1627,506.7738) .. controls (312.3075,507.6524) and
+ (312.0708,508.3704) .. (311.4440,509.0863) .. controls (310.8171,509.8021) and
+ (309.7619,510.4847) .. (308.3502,511.0863) -- (307.9752,511.2425) --
+ (308.0377,511.6488) .. controls (308.3193,513.5300) and (308.8848,515.1671) ..
+ (310.0690,516.2113) .. controls (311.1523,517.1665) and (312.7911,517.4184) ..
+ (314.8815,516.9925) .. controls (315.2459,518.9979) and (315.7682,520.8217) ..
+ (316.9752,522.0238) .. controls (318.1986,523.2421) and (320.1355,523.6024) ..
+ (322.7252,522.9300) .. controls (323.3080,524.3346) and (324.1596,525.3355) ..
+ (325.1315,525.9925) .. controls (326.1986,526.7139) and (327.5930,527.0049) ..
+ (328.7401,527.3612) -- (329.4197,526.6303) .. controls (328.2812,526.2767) and
+ (326.6004,525.7302) .. (325.6940,525.1175) .. controls (324.7876,524.5048) and
+ (324.0512,523.6643) .. (323.5377,522.2113) -- (323.3815,521.7113) --
+ (322.8815,521.8675) .. controls (320.2185,522.6859) and (318.7418,522.3174) ..
+ (317.7252,521.3050) .. controls (316.7087,520.2927) and (316.1370,518.4626) ..
+ (315.7877,516.3363) -- (315.6940,515.7738) -- (315.1315,515.9300) .. controls
+ (312.9366,516.5027) and (311.6408,516.2098) .. (310.7565,515.4300) .. controls
+ (309.9304,514.7016) and (309.4415,513.4103) .. (309.1628,511.8050) .. controls
+ (310.4344,511.2171) and (311.5245,510.5741) .. (312.2253,509.7738) .. controls
+ (312.9099,508.9919) and (313.2063,508.0267) .. (313.1628,507.0238) .. controls
+ (314.7142,506.1705) and (316.5854,505.4372) .. (317.6628,503.9925) .. controls
+ (318.2261,503.2372) and (318.5187,502.2444) .. (318.3815,501.0863) .. controls
+ (318.2568,500.0326) and (317.7408,498.8152) .. (316.8503,497.3675) .. controls
+ (317.9434,496.5623) and (319.1300,495.7554) .. (319.8815,494.8050) .. controls
+ (320.2994,494.2767) and (320.6136,493.6919) .. (320.6003,493.0238) .. controls
+ (320.5933,492.6554) and (320.2387,492.3198) .. (320.0378,491.9613) .. controls
+ (321.9389,491.9861) and (323.6709,491.8609) .. (325.1003,491.3988) .. controls
+ (326.6062,490.9119) and (327.7892,490.0245) .. (328.5690,488.8050) .. controls
+ (330.8191,488.8168) and (333.1492,489.3112) .. (335.5065,489.6175) .. controls
+ (337.9280,489.9322) and (340.3922,490.0166) .. (342.7253,488.9925) --
+ (342.2878,488.0238) .. controls (340.2235,488.9299) and (338.0183,488.8923) ..
+ (335.6628,488.5863) .. controls (333.3073,488.2802) and (330.8524,487.7246) ..
+ (328.3815,487.7425) -- cycle;
+ \path[draw=white,fill=white,miter limit=4.00,line width=0.839pt]
+ (336.8186,487.3469) .. controls (336.8186,489.7993) and (334.8306,491.7873) ..
+ (332.3782,491.7873) .. controls (329.9259,491.7873) and (327.9379,489.7993) ..
+ (327.9379,487.3469) .. controls (327.9379,484.8946) and (329.9259,482.9065) ..
+ (332.3782,482.9065) .. controls (334.8306,482.9065) and (336.8186,484.8945) ..
+ (336.8186,487.3469) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (350.0784,483.1829) .. controls (346.0920,488.3688) and (345.0896,487.0295) ..
+ (342.6627,487.8988) -- (342.2565,488.0550) -- (342.3190,488.4925) .. controls
+ (343.2534,493.7013) and (346.3404,495.3564) .. (348.7497,497.2498) --
+ (348.8842,496.8285) -- (349.5255,496.7063) .. controls (347.1103,494.8083) and
+ (344.4675,493.2007) .. (343.5065,488.7738) .. controls (345.2738,488.3557) and
+ (346.9603,488.8903) .. (350.7252,483.9925) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (196.5832,447.7548) .. controls (204.1159,452.4256) and (216.5138,457.2421) ..
+ (224.4752,462.2738) .. controls (228.8554,465.0628) and (232.7896,467.8418) ..
+ (235.8502,470.2425) .. controls (238.9108,472.6433) and (241.1740,475.1236) ..
+ (242.0065,475.9300) .. controls (242.8390,476.7364) and (243.4041,476.3554) ..
+ (242.8502,475.3050) .. controls (242.2964,474.2547) and (239.5701,471.8264) ..
+ (236.4752,469.3988) .. controls (233.3804,466.9712) and (229.4438,464.2043) ..
+ (225.0377,461.3988) .. controls (216.2255,455.7878) and (205.8833,450.7708) ..
+ (196.5832,447.7548) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (195.2242,436.9074) .. controls (198.3819,437.6366) and (203.0426,440.3298) ..
+ (208.2252,443.2113) .. controls (213.4079,446.0928) and (219.0564,449.6386) ..
+ (224.2252,453.0863) .. controls (229.3940,456.5340) and (233.3791,459.5515) ..
+ (236.5649,461.9823) .. controls (239.5902,464.5711) and (241.0838,466.2475) ..
+ (241.6627,466.2425) .. controls (241.7421,466.2585) and (241.8203,466.2597) ..
+ (241.9440,466.2425) .. controls (242.0677,466.2253) and (242.2764,466.1299) ..
+ (242.3815,465.9300) .. controls (242.4865,465.7302) and (242.4459,465.5623) ..
+ (242.4128,465.4613) .. controls (242.3796,465.3603) and (242.3618,465.3067) ..
+ (242.3191,465.2425) .. controls (242.1482,464.9858) and (241.8873,464.7454) ..
+ (241.5066,464.3988) .. controls (240.7451,463.7056) and (239.4870,462.6862) ..
+ (237.8816,461.4613) .. controls (234.6708,459.0114) and (230.0051,455.6705) ..
+ (224.8191,452.2113) .. controls (219.6331,448.7521) and (213.9447,445.1757) ..
+ (208.7253,442.2738) .. controls (206.8700,441.5863) and (197.7714,436.7746) ..
+ (195.2243,436.9074) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (190.9046,456.7968) .. controls (200.5728,460.7431) and (214.3261,465.3785) ..
+ (223.5065,471.1488) .. controls (228.4392,474.2811) and (232.7356,477.4014) ..
+ (235.9440,479.9613) .. controls (237.5482,481.2412) and (238.8881,482.3917) ..
+ (239.8815,483.3050) .. controls (240.8749,484.2184) and (241.4352,485.0475) ..
+ (241.7565,485.2738) .. controls (242.4289,485.7475) and (242.9436,485.4328) ..
+ (242.6315,484.6800) .. controls (242.3958,484.1116) and (241.6181,483.4596) ..
+ (240.6002,482.5238) .. controls (239.5823,481.5880) and (238.2198,480.4410) ..
+ (236.6002,479.1488) .. controls (233.3611,476.5644) and (229.0363,473.3968) ..
+ (224.0690,470.2425) .. controls (214.1344,463.9341) and (202.2573,458.3877) ..
+ (190.9046,456.7968) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (183.4711,465.5716) .. controls (191.0060,465.5766) and (206.5713,472.4735) ..
+ (213.1315,475.9300) .. controls (223.7689,481.6031) and (233.4415,488.8954) ..
+ (238.7877,493.9925) .. controls (239.3805,494.5577) and (240.2465,494.0588) ..
+ (239.5690,493.2738) .. controls (234.6033,487.5198) and (224.3477,480.7388) ..
+ (213.6315,475.0238) .. controls (202.9153,469.3087) and (191.8189,465.5632) ..
+ (183.4711,465.5716) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (179.1133,475.4956) .. controls (190.4411,477.1531) and (204.0196,481.7255) ..
+ (213.9127,486.6800) .. controls (219.4336,489.4832) and (224.3566,492.4856) ..
+ (228.1315,495.1488) .. controls (231.9064,497.8120) and (234.6937,500.8104) ..
+ (235.3815,501.5863) .. controls (236.0693,502.3622) and (236.8886,502.3945) ..
+ (236.2565,501.0238) .. controls (235.6244,499.6531) and (232.5499,496.9721) ..
+ (228.7252,494.2738) .. controls (224.9006,491.5755) and (219.9456,488.5676) ..
+ (214.3815,485.7425) .. controls (203.2533,480.0924) and (190.5800,475.6473) ..
+ (179.1133,475.4956) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (182.8502,483.9300) .. controls (180.0362,483.6845) and (177.5032,484.2615) ..
+ (174.9224,484.5841) .. controls (184.9876,483.6409) and (199.0622,488.2631) ..
+ (208.4440,492.5863) .. controls (219.4960,497.7676) and (228.6734,504.8810) ..
+ (233.0690,509.3988) .. controls (233.7572,510.1061) and (234.2435,509.2048) ..
+ (233.8815,508.7425) .. controls (229.7881,503.5164) and (220.0397,496.8487) ..
+ (208.8815,491.6175) .. controls (200.5128,487.6942) and (191.2924,484.6668) ..
+ (182.8502,483.9300) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (175.7074,492.9973) .. controls (185.6124,493.7315) and (198.8738,496.1032) ..
+ (208.1627,500.3675) .. controls (217.5053,504.7372) and (224.5953,510.4032) ..
+ (228.1627,513.6175) .. controls (228.7116,514.1121) and (229.6823,513.7617) ..
+ (228.9127,512.8675) .. controls (225.6572,509.0849) and (218.0877,503.8529) ..
+ (208.6315,499.4300) .. controls (199.1753,495.0072) and (187.6892,492.1744) ..
+ (175.7074,492.9973) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (184.6002,501.2425) .. controls (182.5105,501.1718) and (181.5301,501.5628) ..
+ (179.5141,501.7805) .. controls (186.2367,502.0768) and (196.9195,503.8647) ..
+ (202.8190,505.8675) .. controls (210.4747,508.5236) and (216.7699,512.5245) ..
+ (220.3502,515.6488) .. controls (221.0416,516.2521) and (221.5570,515.4427) ..
+ (221.1002,514.9300) .. controls (217.7467,511.1667) and (210.9312,507.5627) ..
+ (203.1627,504.8675) .. controls (197.3364,502.8461) and (190.8693,501.4545) ..
+ (184.6002,501.2425) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (184.3157,510.9926) .. controls (198.6871,511.9623) and (207.3770,514.4944) ..
+ (214.0377,520.4613) .. controls (214.5368,520.9084) and (215.3247,520.2930) ..
+ (214.7877,519.7113) .. controls (207.9520,512.3054) and (194.4933,510.2417) ..
+ (184.3157,510.9926) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (195.3815,519.6175) .. controls (191.0251,519.2671) and (187.3797,520.2191) ..
+ (183.4094,521.5412) .. controls (195.0282,519.6893) and (199.8590,520.5773) ..
+ (208.6627,524.7113) .. controls (209.6662,525.1825) and (209.6073,524.0723) ..
+ (209.1627,523.8050) .. controls (204.4864,520.9942) and (199.7378,519.9679) ..
+ (195.3815,519.6175) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (194.9584,527.7065) .. controls (190.8394,528.0717) and (187.3420,529.4861) ..
+ (184.4584,531.8315) .. controls (195.9645,527.3967) and (199.1447,528.2791) ..
+ (207.9440,530.7738) .. controls (209.1013,531.1019) and (208.7417,529.9871) ..
+ (208.2877,529.8050) .. controls (203.0183,527.6924) and (199.0774,527.3413) ..
+ (194.9584,527.7065) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (217.7565,534.8363) .. controls (211.6177,534.1725) and (204.7011,534.9170) ..
+ (198.6315,536.0238) .. controls (192.5618,537.1306) and (187.3415,539.3794) ..
+ (184.3947,541.7762) .. controls (194.4866,537.5140) and (196.3258,537.5231) ..
+ (198.8190,537.0550) .. controls (204.7989,535.9646) and (210.7264,535.5394) ..
+ (217.6940,535.8675) .. controls (218.3258,535.8973) and (218.2935,534.8944) ..
+ (217.7565,534.8363) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (221.3190,539.8050) .. controls (214.6662,539.5537) and (207.7944,541.2000) ..
+ (201.8502,542.8988) .. controls (195.9061,544.5976) and (191.4940,546.9158) ..
+ (188.5846,549.2822) .. controls (194.4716,546.4504) and (199.9499,544.5335) ..
+ (202.1315,543.8988) .. controls (207.9926,542.2237) and (213.9052,540.7736) ..
+ (221.3815,540.8675) .. controls (221.9623,540.8745) and (222.3377,539.8435) ..
+ (221.3190,539.8050) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (226.7565,543.8988) .. controls (220.4907,544.8239) and (213.9208,546.6745) ..
+ (208.1940,548.6175) .. controls (202.4671,550.5606) and (198.3906,552.8682) ..
+ (195.7313,555.6308) .. controls (202.5433,551.7206) and (206.2895,550.3495) ..
+ (208.5065,549.5863) .. controls (214.1631,547.6670) and (219.4450,546.3315) ..
+ (226.9440,544.9300) .. controls (227.8440,544.7618) and (227.1212,543.8449) ..
+ (226.7565,543.8988) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (229.9440,549.1175) .. controls (217.3782,551.1190) and (209.2362,556.5404) ..
+ (204.0606,561.9168) .. controls (212.0814,555.8737) and (217.6610,552.6260) ..
+ (230.1627,550.1488) .. controls (230.9540,549.9920) and (230.7150,548.9947) ..
+ (229.9440,549.1175) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (236.0690,553.7113) .. controls (223.4309,555.6581) and (216.1430,563.3408) ..
+ (213.1075,568.4120) .. controls (221.1036,560.4242) and (227.3269,556.0769) ..
+ (236.2877,554.7425) .. controls (237.1946,554.6075) and (236.9632,553.5735) ..
+ (236.0690,553.7113) -- cycle;
+ \path[color=black,fill=white,nonzero rule,line width=0.839pt]
+ (239.8815,557.7113) .. controls (237.9104,557.9574) and (235.2282,559.3533) ..
+ (232.6940,560.9613) .. controls (230.1598,562.5693) and (228.2477,564.5258) ..
+ (227.1075,567.0466) .. controls (230.1601,563.8962) and (231.3821,563.0437) ..
+ (233.2565,561.8363) .. controls (235.6896,560.2924) and (238.1414,559.3201) ..
+ (240.1315,558.7425) .. controls (241.0644,558.4718) and (240.3594,557.6516) ..
+ (239.8815,557.7113) -- cycle;
+ \path[draw=white,fill=white,miter limit=4.00,line width=0.839pt]
+ (336.8186,487.3469) .. controls (336.8186,489.7993) and (334.8306,491.7873) ..
+ (332.3782,491.7873) .. controls (329.9259,491.7873) and (327.9379,489.7993) ..
+ (327.9379,487.3469) .. controls (327.9379,484.8946) and (329.9259,482.9065) ..
+ (332.3782,482.9065) .. controls (334.8306,482.9065) and (336.8186,484.8945) ..
+ (336.8186,487.3469) -- cycle;
+ \path[draw=white,fill=maincolor,miter limit=4.00,line width=0.839pt]
+ (336.8186,487.3469) .. controls (336.8186,489.7993) and (334.8306,491.7873) ..
+ (332.3782,491.7873) .. controls (329.9259,491.7873) and (327.9379,489.7993) ..
+ (327.9379,487.3469) .. controls (327.9379,484.8946) and (329.9259,482.9065) ..
+ (332.3782,482.9065) .. controls (334.8306,482.9065) and (336.8186,484.8945) ..
+ (336.8186,487.3469) -- cycle;
+ \path[fill=black] (240.9977,587.6605) .. controls (237.8583,593.6353) and
+ (233.6558,598.3948) .. (228.3899,601.9391) .. controls (223.1240,605.4835) and
+ (217.0733,607.2556) .. (210.2379,607.2556) .. controls (204.2124,607.2556) and
+ (198.9212,606.1923) .. (194.3643,604.0657) .. controls (189.8579,601.9391) and
+ (186.1363,599.0530) .. (183.1996,595.4074) .. controls (180.2628,591.7618) and
+ (178.0603,587.5086) .. (176.5919,582.6478) .. controls (175.1742,577.7870) and
+ (174.4653,572.6477) .. (174.4653,567.2299) .. controls (174.4653,562.3691) and
+ (175.2248,557.6096) .. (176.7438,552.9512) .. controls (178.3134,548.2424) and
+ (180.5919,544.0145) .. (183.5793,540.2676) .. controls (186.4654,536.6727) and
+ (190.0351,533.7866) .. (194.2883,531.6092) .. controls (198.5921,529.3814) and
+ (203.4023,528.2675) .. (208.7188,528.2674) .. controls (214.1872,528.2675) and
+ (218.8708,529.1283) .. (222.7696,530.8497) .. controls (226.6684,532.5713) and
+ (229.8329,534.9258) .. (232.2634,537.9131) .. controls (234.5925,540.7486) and
+ (236.3140,544.0905) .. (237.4280,547.9385) .. controls (238.5925,551.7867) and
+ (239.1748,555.9640) .. (239.1749,560.4703) -- (239.1749,565.4830) --
+ (189.5794,565.4830) .. controls (189.5794,570.3945) and (190.0351,574.8503) ..
+ (190.9465,578.8503) .. controls (191.9085,582.8503) and (193.4022,586.3694) ..
+ (195.4276,589.4073) .. controls (197.4022,592.3441) and (199.9845,594.6732) ..
+ (203.1745,596.3948) .. controls (206.3644,598.0657) and (210.1619,598.9011) ..
+ (214.5670,598.9011) .. controls (219.0733,598.9011) and (222.9468,597.8631) ..
+ (226.1874,595.7872) .. controls (229.4785,593.6606) and (232.6431,589.8631) ..
+ (235.6812,584.3946) -- (240.9977,587.6605)(224.2127,559.1032) .. controls
+ (224.2126,556.2678) and (223.9595,553.2298) .. (223.4532,549.9892) .. controls
+ (222.9974,546.7487) and (222.2379,544.0398) .. (221.1747,541.8625) .. controls
+ (220.0101,539.5334) and (218.4151,537.6347) .. (216.3898,536.1663) .. controls
+ (214.3644,534.6980) and (211.7568,533.9638) .. (208.5669,533.9637) .. controls
+ (203.2504,533.9638) and (198.8200,536.1916) .. (195.2757,540.6473) .. controls
+ (191.7819,545.0525) and (189.8832,551.2044) .. (189.5794,559.1032) --
+ (224.2127,559.1032);
+ \path[fill=black] (321.9606,605.2809) -- (287.6311,605.2809) --
+ (287.6311,600.2682) .. controls (289.9096,600.0151) and (291.8336,599.7619) ..
+ (293.4033,599.5087) .. controls (295.0236,599.2556) and (295.8337,598.5973) ..
+ (295.8337,597.5340) .. controls (295.8337,597.0783) and (295.5805,596.3695) ..
+ (295.0742,595.4074) .. controls (294.5679,594.4454) and (294.0615,593.5593) ..
+ (293.5552,592.7492) .. controls (292.2893,590.7745) and (290.5425,588.1415) ..
+ (288.3147,584.8503) .. controls (286.1374,581.5086) and (283.4538,577.5338) ..
+ (280.2639,572.9262) .. controls (277.6310,576.2174) and (275.2006,579.4326) ..
+ (272.9727,582.5718) .. controls (270.7448,585.6605) and (268.4157,588.9517) ..
+ (265.9853,592.4454) .. controls (265.6309,592.9517) and (265.2511,593.5846) ..
+ (264.8460,594.3441) .. controls (264.4916,595.1036) and (264.3144,595.7112) ..
+ (264.3144,596.1669) .. controls (264.3144,597.2809) and (265.0232,598.2176) ..
+ (266.4410,598.9771) .. controls (267.9093,599.6860) and (270.0866,600.1670) ..
+ (272.9727,600.4201) -- (272.9727,605.2809) -- (245.2509,605.2809) --
+ (245.2509,600.5720) .. controls (248.6940,599.5594) and (251.4535,598.3442) ..
+ (253.5295,596.9264) .. controls (255.6561,595.4581) and (257.6054,593.6606) ..
+ (259.3776,591.5340) .. controls (260.9472,589.5086) and (263.1245,586.7238) ..
+ (265.9093,583.1794) .. controls (268.7448,579.6351) and (272.3904,574.8249) ..
+ (276.8462,568.7489) .. controls (274.2638,565.0527) and (271.0993,560.5463) ..
+ (267.3524,555.2298) .. controls (263.6561,549.8627) and (260.5928,545.4069) ..
+ (258.1624,541.8625) .. controls (256.8459,539.9385) and (255.3269,538.3942) ..
+ (253.6054,537.2296) .. controls (251.9345,536.0144) and (249.5547,535.4068) ..
+ (246.4661,535.4068) -- (246.4661,530.3940) -- (279.0487,530.3940) --
+ (279.0487,535.4068) .. controls (277.4284,535.4068) and (275.8335,535.5081) ..
+ (274.2639,535.7106) .. controls (272.6942,535.9132) and (271.9094,536.3689) ..
+ (271.9094,537.0777) .. controls (271.9094,537.5334) and (272.0613,538.0398) ..
+ (272.3651,538.5967) .. controls (272.6689,539.1537) and (273.0486,539.7613) ..
+ (273.5044,540.4195) .. controls (274.6183,542.1411) and (276.3398,544.7993) ..
+ (278.6690,548.3942) .. controls (281.0487,551.9893) and (283.6057,555.7868) ..
+ (286.3400,559.7868) .. controls (288.1121,557.3564) and (290.1627,554.5209) ..
+ (292.4919,551.2803) .. controls (294.8716,548.0399) and (297.0489,544.9512) ..
+ (299.0236,542.0144) .. controls (299.2261,541.6600) and (299.4286,541.2297) ..
+ (299.6312,540.7233) .. controls (299.8337,540.1664) and (299.9350,539.6347) ..
+ (299.9350,539.1283) .. controls (299.9350,538.0651) and (299.0489,537.2296) ..
+ (297.2768,536.6220) .. controls (295.5552,535.9638) and (293.9096,535.5081) ..
+ (292.3400,535.2549) -- (292.3400,530.3940) -- (319.9859,530.3940) --
+ (319.9859,535.1030) .. controls (316.0870,536.1157) and (313.0490,537.3309) ..
+ (310.8719,538.7486) .. controls (308.6946,540.1157) and (306.8464,541.7107) ..
+ (305.3275,543.5334) .. controls (303.6565,545.6095) and (301.6565,548.1664) ..
+ (299.3274,551.2044) .. controls (297.0489,554.2425) and (293.8337,558.4957) ..
+ (289.6818,563.9640) .. controls (294.2894,570.4451) and (298.0362,575.7617) ..
+ (300.9224,579.9136) .. controls (303.8084,584.0655) and (306.7199,588.3441) ..
+ (309.6567,592.7492) .. controls (311.1250,594.9770) and (312.7452,596.7492) ..
+ (314.5175,598.0657) .. controls (316.3402,599.3315) and (318.8212,600.0657) ..
+ (321.9606,600.2682) -- (321.9606,605.2809);
+ \path[fill=black] (396.9235,539.2802) .. controls (399.9107,542.8246) and
+ (402.2146,546.9512) .. (403.8349,551.6601) .. controls (405.5057,556.3184) and
+ (406.3412,561.6602) .. (406.3413,567.6856) .. controls (406.3412,573.6097) and
+ (405.3538,579.0275) .. (403.3792,583.9389) .. controls (401.4044,588.7998) and
+ (398.7968,592.9517) .. (395.5563,596.3948) .. controls (392.1638,599.8885) and
+ (388.3916,602.5721) .. (384.2398,604.4455) .. controls (380.0878,606.3189) and
+ (375.6826,607.2556) .. (371.0244,607.2556) .. controls (366.5180,607.2556) and
+ (362.8218,606.7493) .. (359.9357,605.7366) .. controls (357.0495,604.7240) and
+ (354.6951,603.5341) .. (352.8723,602.1670) -- (352.2647,602.1670) --
+ (352.2647,624.6482) .. controls (352.2647,626.4710) and (352.6191,627.9900) ..
+ (353.3280,629.2053) .. controls (354.0369,630.4204) and (355.1255,631.3065) ..
+ (356.5939,631.8635) .. controls (357.8090,632.3192) and (359.5306,632.7496) ..
+ (361.7585,633.1547) .. controls (364.0370,633.6103) and (365.9104,633.8635) ..
+ (367.3788,633.9142) -- (367.3788,639.0028) -- (325.5302,639.0028) --
+ (325.5302,633.9142) .. controls (327.0999,633.8129) and (328.6189,633.6863) ..
+ (330.0873,633.5344) .. controls (331.5556,633.3825) and (332.8721,633.1293) ..
+ (334.0367,632.7749) .. controls (335.5557,632.2686) and (336.6190,631.3825) ..
+ (337.2266,630.1167) .. controls (337.8342,628.8508) and (338.1380,627.3571) ..
+ (338.1380,625.6356) -- (338.1380,545.9638) .. controls (338.1380,544.4449) and
+ (337.7582,542.9765) .. (336.9987,541.5587) .. controls (336.2392,540.1410) and
+ (335.2519,539.0018) .. (334.0367,538.1410) .. controls (333.1253,537.5334) and
+ (331.8594,537.0777) .. (330.2392,536.7739) .. controls (328.6189,536.4195) and
+ (327.0492,536.1916) .. (325.5302,536.0903) -- (325.5302,531.1535) --
+ (351.0495,529.4826) -- (352.1128,530.3940) -- (352.1128,538.8245) --
+ (352.7204,538.9764) .. controls (355.3533,535.9385) and (358.6192,533.4068) ..
+ (362.5180,531.3814) .. controls (366.4167,529.3561) and (370.2902,528.3435) ..
+ (374.1384,528.3434) .. controls (378.7966,528.3435) and (383.0498,529.3308) ..
+ (386.8980,531.3054) .. controls (390.7967,533.2802) and (394.1385,535.9385) ..
+ (396.9234,539.2802)(384.5436,593.1289) .. controls (386.5688,589.9896) and
+ (388.0625,586.3440) .. (389.0246,582.1921) .. controls (389.9866,578.0402) and
+ (390.4676,573.4072) .. (390.4677,568.2932) .. controls (390.4676,564.5464) and
+ (390.0625,560.7235) .. (389.2525,556.8247) .. controls (388.4423,552.9260) and
+ (387.1764,549.5335) .. (385.4550,546.6474) .. controls (383.7334,543.7107) and
+ (381.4802,541.3309) .. (378.6954,539.5081) .. controls (375.9105,537.6853) and
+ (372.5687,536.7739) .. (368.6700,536.7739) .. controls (364.9230,536.7739) and
+ (361.7331,537.6094) .. (359.1002,539.2802) .. controls (356.4673,540.9005) and
+ (354.1888,542.8499) .. (352.2647,545.1284) -- (352.2647,589.4073) .. controls
+ (352.7204,590.7745) and (353.4546,592.1922) .. (354.4673,593.6606) .. controls
+ (355.5305,595.1289) and (356.6951,596.3948) .. (357.9610,597.4581) .. controls
+ (359.5306,598.7239) and (361.2268,599.7619) .. (363.0496,600.5720) .. controls
+ (364.8724,601.3315) and (367.1003,601.7113) .. (369.7333,601.7113) .. controls
+ (372.5687,601.7113) and (375.3029,600.9771) .. (377.9359,599.5087) .. controls
+ (380.5688,597.9897) and (382.7713,595.8631) .. (384.5436,593.1289);
+ \path[fill=black] (452.5949,605.2809) -- (416.0629,605.2809) --
+ (416.0629,600.2682) .. controls (417.2275,600.1670) and (418.4680,600.0657) ..
+ (419.7845,599.9644) .. controls (421.1009,599.8125) and (422.1895,599.6100) ..
+ (423.0503,599.3568) .. controls (424.4680,598.9011) and (425.5313,598.1163) ..
+ (426.2402,597.0024) .. controls (426.9491,595.8378) and (427.3035,594.3441) ..
+ (427.3035,592.5213) -- (427.3035,505.7862) .. controls (427.3035,503.9635) and
+ (426.8985,502.2672) .. (426.0883,500.6975) .. controls (425.3288,499.0773) and
+ (424.3161,497.8115) .. (423.0503,496.9000) .. controls (422.1389,496.2925) and
+ (420.4680,495.7355) .. (418.0376,495.2291) .. controls (415.6072,494.7229) and
+ (413.6578,494.4191) .. (412.1894,494.3177) -- (412.1894,489.4569) --
+ (440.3670,487.7100) -- (441.4303,488.8493) -- (441.4303,591.6099) .. controls
+ (441.4302,593.3821) and (441.7593,594.8505) .. (442.4176,596.0150) .. controls
+ (443.0758,597.1290) and (444.1391,597.9897) .. (445.6075,598.5973) .. controls
+ (446.7214,599.1037) and (447.8100,599.4834) .. (448.8734,599.7366) .. controls
+ (449.9873,599.9897) and (451.2278,600.1670) .. (452.5949,600.2682) --
+ (452.5949,605.2809);
+ \path[fill=black] (493.6840,633.0028) .. controls (488.9244,633.0027) and
+ (484.5700,632.3951) .. (480.6206,631.1800) .. controls (476.6711,630.0154) and
+ (473.2787,628.4204) .. (470.4432,626.3951) .. controls (467.6078,624.3697) and
+ (465.4052,622.0406) .. (463.8356,619.4077) .. controls (462.3166,616.7747) and
+ (461.5571,614.0658) .. (461.5571,611.2810) .. controls (461.5571,608.8000) and
+ (462.1647,606.5721) .. (463.3799,604.5974) .. controls (464.5951,602.5721) and
+ (466.5445,601.5594) .. (469.2280,601.5594) .. controls (472.2660,601.5594) and
+ (474.5699,602.3189) .. (476.1395,603.8379) .. controls (477.7598,605.3063) and
+ (478.5699,607.0025) .. (478.5699,608.9266) .. controls (478.5699,610.5468) and
+ (478.2914,612.5975) .. (477.7345,615.0785) .. controls (477.2281,617.5596) and
+ (476.8230,619.3317) .. (476.5193,620.3950) .. controls (476.8737,620.8507) and
+ (477.5066,621.4583) .. (478.4180,622.2178) .. controls (479.3800,622.9773) and
+ (480.5446,623.6609) .. (481.9117,624.2685) .. controls (483.5320,625.0280) and
+ (485.2282,625.6356) .. (487.0004,626.0913) .. controls (488.7725,626.5470) and
+ (491.2789,626.7748) .. (494.5195,626.7749) .. controls (497.5574,626.7748) and
+ (500.4689,626.2685) .. (503.2537,625.2559) .. controls (506.0892,624.2432) and
+ (508.5702,622.6229) .. (510.6969,620.3950) .. controls (512.9247,618.0659) and
+ (514.6462,615.3317) .. (515.8615,612.1924) .. controls (517.1272,609.1038) and
+ (517.7602,605.0278) .. (517.7602,599.9644) .. controls (517.7602,597.2302) and
+ (517.4564,594.5213) .. (516.8488,591.8378) .. controls (516.2918,589.1542) and
+ (515.2285,586.8251) .. (513.6589,584.8503) .. controls (512.0892,582.8757) and
+ (509.9373,581.3566) .. (507.2031,580.2933) .. controls (504.5195,579.1794) and
+ (501.1018,578.6224) .. (496.9499,578.6224) -- (487.0004,578.6224) --
+ (487.0004,569.8881) -- (493.6081,569.8881) .. controls (500.5954,569.8882) and
+ (505.6335,567.9641) .. (508.7221,564.1159) .. controls (511.8107,560.2678) and
+ (513.3551,554.4703) .. (513.3551,546.7233) .. controls (513.3551,540.3942) and
+ (511.8614,535.6347) .. (508.8740,532.4447) .. controls (505.8866,529.2042) and
+ (501.6587,527.5840) .. (496.1904,527.5839) .. controls (493.5574,527.5840) and
+ (491.3801,527.9131) .. (489.6586,528.5712) .. controls (487.9877,529.1789) and
+ (486.6206,529.7865) .. (485.5573,530.3940) .. controls (484.2915,531.1030) and
+ (483.2535,531.8878) .. (482.4434,532.7485) .. controls (481.6332,533.6093) and
+ (481.0256,534.2423) .. (480.6206,534.6472) .. controls (480.9750,536.2676) and
+ (481.4054,538.2676) .. (481.9117,540.6473) .. controls (482.4180,542.9765) and
+ (482.6712,545.2044) .. (482.6712,547.3309) .. controls (482.6712,549.2044) and
+ (481.8611,550.9006) .. (480.2408,552.4196) .. controls (478.6712,553.8880) and
+ (476.3420,554.6222) .. (473.2534,554.6222) .. controls (470.5698,554.6222) and
+ (468.5951,553.6602) .. (467.3293,551.7360) .. controls (466.1141,549.8120) and
+ (465.5065,547.5842) .. (465.5065,545.0524) .. controls (465.5065,542.4195) and
+ (466.2407,539.7360) .. (467.7090,537.0017) .. controls (469.1774,534.2676) and
+ (471.3546,531.7106) .. (474.2408,529.3307) .. controls (477.1268,526.9510) and
+ (480.6459,525.0270) .. (484.7978,523.5585) .. controls (488.9497,522.0902) and
+ (493.7346,521.3560) .. (499.1524,521.3560) .. controls (505.3803,521.3560) and
+ (510.5196,522.2928) .. (514.5703,524.1661) .. controls (518.6716,525.9890) and
+ (521.8868,528.2169) .. (524.2160,530.8497) .. controls (526.4944,533.4321) and
+ (528.0641,536.1410) .. (528.9249,538.9764) .. controls (529.7856,541.8119) and
+ (530.2160,544.2424) .. (530.2161,546.2676) .. controls (530.2160,548.7994) and
+ (529.8615,551.3563) .. (529.1527,553.9386) .. controls (528.4438,556.4703) and
+ (527.2792,558.8248) .. (525.6590,561.0020) .. controls (523.8868,563.3818) and
+ (521.5323,565.5590) .. (518.5957,567.5337) .. controls (515.7095,569.4578) and
+ (512.0639,571.0274) .. (507.6588,572.2426) -- (507.6588,573.4578) .. controls
+ (510.4943,573.7110) and (513.5070,574.3439) .. (516.6969,575.3566) .. controls
+ (519.9374,576.3693) and (522.8488,577.8629) .. (525.4312,579.8376) .. controls
+ (528.1147,581.9136) and (530.3172,584.5972) .. (532.0389,587.8883) .. controls
+ (533.7603,591.1289) and (534.6211,595.2555) .. (534.6212,600.2682) .. controls
+ (534.6211,609.9898) and (530.7223,617.8633) .. (522.9248,623.8887) .. controls
+ (515.1272,629.9647) and (505.3803,633.0027) .. (493.6840,633.0028);
+ \path[fill=maincolor] (239.7096,586.3724) .. controls (236.5703,592.3472) and
+ (232.3677,597.1067) .. (227.1019,600.6510) .. controls (221.8359,604.1954) and
+ (215.7852,605.9676) .. (208.9498,605.9676) .. controls (202.9244,605.9676) and
+ (197.6332,604.9043) .. (193.0762,602.7777) .. controls (188.5698,600.6510) and
+ (184.8482,597.7649) .. (181.9115,594.1193) .. controls (178.9748,590.4737) and
+ (176.7722,586.2205) .. (175.3038,581.3597) .. controls (173.8861,576.4989) and
+ (173.1772,571.3596) .. (173.1772,565.9418) .. controls (173.1772,561.0810) and
+ (173.9367,556.3215) .. (175.4557,551.6632) .. controls (177.0254,546.9543) and
+ (179.3039,542.7264) .. (182.2913,538.9795) .. controls (185.1773,535.3846) and
+ (188.7470,532.4985) .. (193.0002,530.3212) .. controls (197.3040,528.0934) and
+ (202.1142,526.9794) .. (207.4308,526.9794) .. controls (212.8991,526.9794) and
+ (217.5827,527.8402) .. (221.4816,529.5617) .. controls (225.3803,531.2833) and
+ (228.5449,533.6377) .. (230.9753,536.6250) .. controls (233.3044,539.4606) and
+ (235.0259,542.8024) .. (236.1399,546.6505) .. controls (237.3045,550.4987) and
+ (237.8867,554.6759) .. (237.8868,559.1822) -- (237.8868,564.1950) --
+ (188.2913,564.1950) .. controls (188.2913,569.1064) and (188.7470,573.5622) ..
+ (189.6584,577.5622) .. controls (190.6204,581.5623) and (192.1141,585.0813) ..
+ (194.1395,588.1193) .. controls (196.1142,591.0560) and (198.6965,593.3852) ..
+ (201.8864,595.1067) .. controls (205.0763,596.7776) and (208.8738,597.6131) ..
+ (213.2789,597.6130) .. controls (217.7853,597.6131) and (221.6587,596.5751) ..
+ (224.8993,594.4991) .. controls (228.1904,592.3725) and (231.3550,588.5750) ..
+ (234.3931,583.1066) -- (239.7096,586.3724)(222.9246,557.8151) .. controls
+ (222.9246,554.9797) and (222.6714,551.9417) .. (222.1651,548.7011) .. controls
+ (221.7094,545.4606) and (220.9499,542.7517) .. (219.8866,540.5744) .. controls
+ (218.7220,538.2454) and (217.1270,536.3466) .. (215.1017,534.8782) .. controls
+ (213.0764,533.4099) and (210.4687,532.6757) .. (207.2789,532.6756) .. controls
+ (201.9623,532.6757) and (197.5319,534.9036) .. (193.9876,539.3592) .. controls
+ (190.4939,543.7644) and (188.5951,549.9164) .. (188.2913,557.8151) --
+ (222.9246,557.8151);
+ \path[fill=maincolor] (320.6725,603.9929) -- (286.3430,603.9929) --
+ (286.3430,598.9801) .. controls (288.6215,598.7270) and (290.5456,598.4738) ..
+ (292.1152,598.2206) .. controls (293.7355,597.9675) and (294.5456,597.3093) ..
+ (294.5457,596.2459) .. controls (294.5456,595.7902) and (294.2924,595.0814) ..
+ (293.7862,594.1193) .. controls (293.2798,593.1573) and (292.7734,592.2712) ..
+ (292.2672,591.4611) .. controls (291.0013,589.4864) and (289.2544,586.8535) ..
+ (287.0266,583.5623) .. controls (284.8493,580.2205) and (282.1657,576.2457) ..
+ (278.9759,571.6381) .. controls (276.3429,574.9293) and (273.9125,578.1445) ..
+ (271.6846,581.2838) .. controls (269.4567,584.3724) and (267.1276,587.6636) ..
+ (264.6972,591.1573) .. controls (264.3428,591.6636) and (263.9630,592.2965) ..
+ (263.5580,593.0560) .. controls (263.2035,593.8155) and (263.0263,594.4231) ..
+ (263.0263,594.8788) .. controls (263.0263,595.9928) and (263.7352,596.9295) ..
+ (265.1529,597.6890) .. controls (266.6213,598.3979) and (268.7985,598.8789) ..
+ (271.6846,599.1321) -- (271.6846,603.9929) -- (243.9628,603.9929) --
+ (243.9628,599.2840) .. controls (247.4059,598.2713) and (250.1654,597.0561) ..
+ (252.2414,595.6383) .. controls (254.3680,594.1700) and (256.3174,592.3725) ..
+ (258.0896,590.2459) .. controls (259.6592,588.2206) and (261.8364,585.4357) ..
+ (264.6213,581.8914) .. controls (267.4567,578.3470) and (271.1023,573.5369) ..
+ (275.5581,567.4608) .. controls (272.9758,563.7646) and (269.8112,559.2582) ..
+ (266.0643,553.9417) .. controls (262.3681,548.5746) and (259.3047,544.1188) ..
+ (256.8744,540.5744) .. controls (255.5579,538.6504) and (254.0389,537.1061) ..
+ (252.3173,535.9415) .. controls (250.6464,534.7263) and (248.2667,534.1187) ..
+ (245.1780,534.1187) -- (245.1780,529.1060) -- (277.7607,529.1060) --
+ (277.7607,534.1187) .. controls (276.1404,534.1187) and (274.5454,534.2200) ..
+ (272.9758,534.4225) .. controls (271.4061,534.6251) and (270.6213,535.0808) ..
+ (270.6213,535.7896) .. controls (270.6213,536.2453) and (270.7732,536.7517) ..
+ (271.0770,537.3086) .. controls (271.3808,537.8656) and (271.7606,538.4732) ..
+ (272.2163,539.1314) .. controls (273.3302,540.8530) and (275.0517,543.5112) ..
+ (277.3809,547.1062) .. controls (279.7606,550.7012) and (282.3176,554.4987) ..
+ (285.0519,558.4987) .. controls (286.8240,556.0683) and (288.8747,553.2329) ..
+ (291.2038,549.9923) .. controls (293.5836,546.7518) and (295.7608,543.6631) ..
+ (297.7356,540.7263) .. controls (297.9380,540.3720) and (298.1406,539.9416) ..
+ (298.3432,539.4352) .. controls (298.5456,538.8783) and (298.6469,538.3466) ..
+ (298.6470,537.8402) .. controls (298.6469,536.7770) and (297.7608,535.9415) ..
+ (295.9887,535.3339) .. controls (294.2671,534.6757) and (292.6215,534.2200) ..
+ (291.0519,533.9668) -- (291.0519,529.1060) -- (318.6978,529.1060) --
+ (318.6978,533.8149) .. controls (314.7990,534.8276) and (311.7610,536.0428) ..
+ (309.5838,537.4605) .. controls (307.4065,538.8277) and (305.5584,540.4226) ..
+ (304.0394,542.2453) .. controls (302.3685,544.3214) and (300.3684,546.8784) ..
+ (298.0394,549.9163) .. controls (295.7608,552.9544) and (292.5456,557.2076) ..
+ (288.3937,562.6760) .. controls (293.0013,569.1571) and (296.7482,574.4736) ..
+ (299.6343,578.6255) .. controls (302.5204,582.7775) and (305.4318,587.0560) ..
+ (308.3686,591.4611) .. controls (309.8369,593.6890) and (311.4572,595.4611) ..
+ (313.2294,596.7776) .. controls (315.0521,598.0434) and (317.5332,598.7776) ..
+ (320.6725,598.9801) -- (320.6725,603.9929);
+ \path[fill=maincolor] (395.6354,537.9921) .. controls (398.6227,541.5365) and
+ (400.9265,545.6632) .. (402.5468,550.3720) .. controls (404.2177,555.0303) and
+ (405.0531,560.3722) .. (405.0532,566.3975) .. controls (405.0531,572.3216) and
+ (404.0658,577.7394) .. (402.0911,582.6508) .. controls (400.1164,587.5117) and
+ (397.5087,591.6636) .. (394.2683,595.1067) .. controls (390.8758,598.6004) and
+ (387.1036,601.2840) .. (382.9517,603.1574) .. controls (378.7997,605.0308) and
+ (374.3946,605.9676) .. (369.7363,605.9676) .. controls (365.2299,605.9676) and
+ (361.5337,605.4612) .. (358.6476,604.4486) .. controls (355.7615,603.4359) and
+ (353.4070,602.2460) .. (351.5843,600.8789) -- (350.9766,600.8789) --
+ (350.9766,623.3602) .. controls (350.9766,625.1829) and (351.3311,626.7019) ..
+ (352.0400,627.9172) .. controls (352.7488,629.1323) and (353.8374,630.0184) ..
+ (355.3058,630.5754) .. controls (356.5210,631.0311) and (358.2425,631.4615) ..
+ (360.4704,631.8666) .. controls (362.7489,632.3223) and (364.6223,632.5754) ..
+ (366.0907,632.6261) -- (366.0907,637.7147) -- (324.2422,637.7147) --
+ (324.2422,632.6261) .. controls (325.8118,632.5248) and (327.3308,632.3982) ..
+ (328.7992,632.2463) .. controls (330.2676,632.0944) and (331.5840,631.8412) ..
+ (332.7486,631.4868) .. controls (334.2676,630.9805) and (335.3309,630.0944) ..
+ (335.9385,628.8286) .. controls (336.5461,627.5627) and (336.8499,626.0690) ..
+ (336.8499,624.3475) -- (336.8499,544.6758) .. controls (336.8499,543.1568) and
+ (336.4701,541.6884) .. (335.7107,540.2706) .. controls (334.9511,538.8530) and
+ (333.9638,537.7137) .. (332.7486,536.8529) .. controls (331.8372,536.2453) and
+ (330.5714,535.7896) .. (328.9511,535.4858) .. controls (327.3308,535.1314) and
+ (325.7612,534.9036) .. (324.2422,534.8022) -- (324.2422,529.8655) --
+ (349.7614,528.1945) -- (350.8247,529.1060) -- (350.8247,537.5364) --
+ (351.4323,537.6883) .. controls (354.0653,534.6504) and (357.3311,532.1187) ..
+ (361.2299,530.0933) .. controls (365.1287,528.0680) and (369.0021,527.0554) ..
+ (372.8503,527.0553) .. controls (377.5085,527.0554) and (381.7617,528.0427) ..
+ (385.6099,530.0174) .. controls (389.5087,531.9921) and (392.8505,534.6504) ..
+ (395.6354,537.9921)(383.2555,591.8408) .. controls (385.2808,588.7016) and
+ (386.7744,585.0560) .. (387.7365,580.9040) .. controls (388.6985,576.7521) and
+ (389.1795,572.1191) .. (389.1796,567.0051) .. controls (389.1795,563.2583) and
+ (388.7745,559.4354) .. (387.9644,555.5366) .. controls (387.1542,551.6379) and
+ (385.8884,548.2455) .. (384.1669,545.3593) .. controls (382.4453,542.4226) and
+ (380.1921,540.0428) .. (377.4073,538.2200) .. controls (374.6224,536.3972) and
+ (371.2806,535.4858) .. (367.3819,535.4858) .. controls (363.6350,535.4858) and
+ (360.4451,536.3213) .. (357.8122,537.9921) .. controls (355.1792,539.6125) and
+ (352.9007,541.5618) .. (350.9766,543.8403) -- (350.9766,588.1193) .. controls
+ (351.4323,589.4864) and (352.1665,590.9041) .. (353.1792,592.3725) .. controls
+ (354.2425,593.8409) and (355.4070,595.1067) .. (356.6729,596.1700) .. controls
+ (358.2425,597.4358) and (359.9387,598.4738) .. (361.7616,599.2839) .. controls
+ (363.5843,600.0434) and (365.8122,600.4232) .. (368.4452,600.4232) .. controls
+ (371.2806,600.4232) and (374.0148,599.6890) .. (376.6478,598.2206) .. controls
+ (379.2807,596.7016) and (381.4833,594.5750) .. (383.2555,591.8408);
+ \path[fill=basecolor] (451.3069,603.9929) -- (414.7748,603.9929) --
+ (414.7748,598.9801) .. controls (415.9394,598.8789) and (417.1799,598.7776) ..
+ (418.4964,598.6763) .. controls (419.8128,598.5245) and (420.9015,598.3219) ..
+ (421.7622,598.0687) .. controls (423.1800,597.6130) and (424.2433,596.8282) ..
+ (424.9521,595.7143) .. controls (425.6610,594.5497) and (426.0154,593.0560) ..
+ (426.0155,591.2332) -- (426.0155,504.4981) .. controls (426.0154,502.6754) and
+ (425.6104,500.9792) .. (424.8002,499.4094) .. controls (424.0407,497.7893) and
+ (423.0281,496.5234) .. (421.7622,495.6119) .. controls (420.8508,495.0044) and
+ (419.1799,494.4475) .. (416.7495,493.9410) .. controls (414.3191,493.4348) and
+ (412.3697,493.1310) .. (410.9014,493.0296) -- (410.9014,488.1688) --
+ (439.0789,486.4219) -- (440.1422,487.5612) -- (440.1422,590.3218) .. controls
+ (440.1422,592.0940) and (440.4713,593.5624) .. (441.1295,594.7269) .. controls
+ (441.7877,595.8409) and (442.8510,596.7016) .. (444.3195,597.3092) .. controls
+ (445.4334,597.8156) and (446.5220,598.1953) .. (447.5853,598.4485) .. controls
+ (448.6992,598.7017) and (449.9397,598.8789) .. (451.3069,598.9801) --
+ (451.3069,603.9929);
+ \path[fill=basecolor] (492.3959,631.7147) .. controls (487.6364,631.7147) and
+ (483.2819,631.1071) .. (479.3325,629.8919) .. controls (475.3831,628.7273) and
+ (471.9906,627.1323) .. (469.1552,625.1070) .. controls (466.3197,623.0817) and
+ (464.1171,620.7525) .. (462.5475,618.1196) .. controls (461.0285,615.4866) and
+ (460.2690,612.7778) .. (460.2690,609.9929) .. controls (460.2690,607.5119) and
+ (460.8766,605.2840) .. (462.0918,603.3093) .. controls (463.3070,601.2840) and
+ (465.2564,600.2713) .. (467.9400,600.2713) .. controls (470.9780,600.2713) and
+ (473.2818,601.0308) .. (474.8514,602.5498) .. controls (476.4717,604.0182) and
+ (477.2818,605.7144) .. (477.2819,607.6385) .. controls (477.2818,609.2587) and
+ (477.0033,611.3094) .. (476.4464,613.7904) .. controls (475.9400,616.2715) and
+ (475.5350,618.0436) .. (475.2312,619.1069) .. controls (475.5856,619.5626) and
+ (476.2185,620.1702) .. (477.1300,620.9298) .. controls (478.0920,621.6892) and
+ (479.2565,622.3728) .. (480.6237,622.9804) .. controls (482.2439,623.7399) and
+ (483.9401,624.3475) .. (485.7123,624.8032) .. controls (487.4845,625.2589) and
+ (489.9908,625.4868) .. (493.2314,625.4868) .. controls (496.2694,625.4868) and
+ (499.1808,624.9804) .. (501.9657,623.9678) .. controls (504.8011,622.9551) and
+ (507.2821,621.3348) .. (509.4088,619.1069) .. controls (511.6366,616.7778) and
+ (513.3581,614.0436) .. (514.5734,610.9043) .. controls (515.8392,607.8157) and
+ (516.4721,603.7397) .. (516.4721,598.6763) .. controls (516.4721,595.9421) and
+ (516.1683,593.2333) .. (515.5607,590.5497) .. controls (515.0037,587.8661) and
+ (513.9404,585.5370) .. (512.3708,583.5622) .. controls (510.8011,581.5876) and
+ (508.6492,580.0686) .. (505.9151,579.0052) .. controls (503.2314,577.8913) and
+ (499.8137,577.3344) .. (495.6618,577.3343) -- (485.7123,577.3343) --
+ (485.7123,568.6001) -- (492.3200,568.6001) .. controls (499.3074,568.6001) and
+ (504.3454,566.6760) .. (507.4341,562.8279) .. controls (510.5227,558.9797) and
+ (512.0670,553.1822) .. (512.0670,545.4352) .. controls (512.0670,539.1061) and
+ (510.5733,534.3466) .. (507.5860,531.1566) .. controls (504.5985,527.9162) and
+ (500.3707,526.2959) .. (494.9023,526.2958) .. controls (492.2693,526.2959) and
+ (490.0921,526.6250) .. (488.3706,527.2831) .. controls (486.6996,527.8908) and
+ (485.3325,528.4984) .. (484.2693,529.1060) .. controls (483.0034,529.8149) and
+ (481.9654,530.5997) .. (481.1553,531.4604) .. controls (480.3451,532.3213) and
+ (479.7375,532.9542) .. (479.3325,533.3592) .. controls (479.6869,534.9795) and
+ (480.1173,536.9795) .. (480.6237,539.3592) .. controls (481.1300,541.6884) and
+ (481.3831,543.9163) .. (481.3832,546.0429) .. controls (481.3831,547.9164) and
+ (480.5730,549.6126) .. (478.9527,551.1315) .. controls (477.3831,552.5999) and
+ (475.0539,553.3341) .. (471.9653,553.3341) .. controls (469.2817,553.3341) and
+ (467.3070,552.3721) .. (466.0412,550.4480) .. controls (464.8260,548.5240) and
+ (464.2184,546.2961) .. (464.2184,543.7643) .. controls (464.2184,541.1315) and
+ (464.9526,538.4479) .. (466.4210,535.7136) .. controls (467.8893,532.9795) and
+ (470.0666,530.4225) .. (472.9527,528.0426) .. controls (475.8388,525.6630) and
+ (479.3578,523.7389) .. (483.5098,522.2704) .. controls (487.6617,520.8021) and
+ (492.4465,520.0680) .. (497.8643,520.0679) .. controls (504.0922,520.0680) and
+ (509.2315,521.0047) .. (513.2822,522.8780) .. controls (517.3835,524.7009) and
+ (520.5987,526.9288) .. (522.9279,529.5617) .. controls (525.2064,532.1440) and
+ (526.7760,534.8529) .. (527.6368,537.6883) .. controls (528.4975,540.5239) and
+ (528.9279,542.9543) .. (528.9280,544.9795) .. controls (528.9279,547.5113) and
+ (528.5735,550.0683) .. (527.8647,552.6505) .. controls (527.1557,555.1822) and
+ (525.9912,557.5367) .. (524.3710,559.7139) .. controls (522.5987,562.0937) and
+ (520.2443,564.2709) .. (517.3076,566.2456) .. controls (514.4214,568.1697) and
+ (510.7758,569.7393) .. (506.3708,570.9545) -- (506.3708,572.1697) .. controls
+ (509.2062,572.4229) and (512.2189,573.0558) .. (515.4088,574.0685) .. controls
+ (518.6493,575.0812) and (521.5607,576.5749) .. (524.1431,578.5495) .. controls
+ (526.8266,580.6255) and (529.0292,583.3091) .. (530.7508,586.6003) .. controls
+ (532.4722,589.8408) and (533.3330,593.9674) .. (533.3331,598.9801) .. controls
+ (533.3330,608.7018) and (529.4342,616.5753) .. (521.6368,622.6007) .. controls
+ (513.8391,628.6766) and (504.0922,631.7147) .. (492.3959,631.7147);
+\end{tikzpicture}
+}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\publicationmonth{March}
+\publicationyear{2014}
+\publicationissue{9}
+
+\usepackage{multicol}
+\usepackage{xparse}
+\newcommand\ctanpkg[1]{\href{http://ctan.org/pkg/#1}{\pkg{#1}}}
+
+\begin{document}
+\maketitle
+
+\raisefirstsection
+
+\tableofcontents % could drop this and raise first section instead
+
+\section{Hiatus?}
+
+Well, it's been a busy couple of years.
+Work has slowed on the \LaTeX3 codebase as all active members of the team have been\Dash shall we say\Dash busily occupied with more pressing concerns in their day-to-day activities.
+
+Nonetheless, Joseph and Bruno have continued to fine-tune the \LaTeX3 kernel and add-on packages.
+Browsing through the commit history shows bug fixes and improvements to documentation, test files, and internal code across the entire breadth of the codebase.
+
+Members of the team have presented at two TUG conferences since the last \LaTeX3 news. (Has it really been so long?)
+In July 2012, Frank and Will travelled to Boston; Frank discussed the challenges faced in the past and continuing to the present day due to the limits of the various \TeX\ engines; and, Frank and Will together covered a brief history and recent developments of the \pkg{expl3} code.
+
+In 2013, Joseph and Frank wrote a talk on complex layouts, and the "layers" ideas discussed in \LaTeX3; Frank went to Tokyo in October to present the work.
+Slides of and recordings from these talks are available on the \LaTeX3 website.
+
+These conferences are good opportunities to introduce the \pkg{expl3} language to a wider group of people; in many cases, explaining the rationale behind why \pkg{expl3} looks a little strange at first helps to convince the audience that it's not so weird after all.
+In our experience, anyone that's been exposed to some of the more awkward expansion aspects of \TeX\ programming appreciates how \pkg{expl3} makes life much easier for us.
+
+\section{\pkg{expl3} in the community}
+
+While things have been slightly quieter for the team, more and more people are adopting \pkg{expl3} for their own use.
+A search on the \TeX\ Stack Exchange website for either "\texttt{expl3}" or "\texttt{latex3}" at time of writing yield around one thousand results each.
+
+In order to help standardise the prefixes used in \pkg{expl3} modules, we have developed a registration procedure for package authors (which amounts to little more than notifying us that their package uses a specific prefix, which will often be the name of the package itself).
+Please contact us via the \texttt{latex-l} mailing list to register your module prefixes and package names; we ask that you avoid using package names that begin with \texttt{l3...}\ since \pkg{expl3} packages use this internally.
+Some authors have started using the package prefix \texttt{lt3...}\ as a way of indicating their package builds on \pkg{expl3} in some way but is not maintained by the \LaTeX3 team.
+
+In the prefix database at present, some thirty package prefixes are registered by fifteen separate individuals (unrelated to The \LaTeX{} Project\Dash the number of course grows if you include packages by members of the team).
+These packages cover a broad range of functionality:
+\begin{description}
+\item[\ctanpkg{acro}] Interface for creating (classes of) acronyms
+\item[\ctanpkg{hobby}]
+Hobby's algorithm in PGF/TiKZ for drawing optimally smooth curves.
+\item[\ctanpkg{chemmacros}] Typesetting in the field of chemistry.
+\item[\ctanpkg{classics}] Traditional-style citations for the classics.
+\item[\ctanpkg{conteq}] Continued (in)equalities in mathematics.
+\item[\ctanpkg{ctex}] A collection of macro packages and document classes for Chinese typesetting.
+\item[\ctanpkg{endiagram}] Draw potential energy curve diagrams.
+\item[\ctanpkg{enotez}] Support for end-notes.
+\item[\ctanpkg{exsheets}] Question sheets and exams with metadata.
+%(Note to self: remember to use this for teaching this semester!)
+\item[\ctanpkg{lt3graph}] A graph data structure.
+\item[\ctanpkg{newlfm}] The venerable class for memos and letters.
+\item[\ctanpkg{fnpct}] Interaction between footnotes and punctuation.
+\item[\ctanpkg{GS1}] Barcodes and so forth.
+\item[\ctanpkg{hobete}] Beamer theme for the Univ.\ of Hohenheim.
+\item[\ctanpkg{kantlipsum}] Generate sentences in Kant's style.
+\item[\ctanpkg{lualatex-math}] Extended support for mathematics in \LuaLaTeX.
+\item[\ctanpkg{media9}] Multimedia inclusion for Adobe Reader.
+\item[\ctanpkg{pkgloader}] Managing the options and loading order of other packages.
+\item[\ctanpkg{substances}] Lists of chemicals, etc., in a document.
+\item[\ctanpkg{withargs}] Ephemeral macro use.
+\item[\ctanpkg{xecjk}] Support for CJK documents in \XeLaTeX.
+\item[\ctanpkg{xpatch}, \ctanpkg{regexpatch}] Patch command definitions.
+\item[\ctanpkg{xpeek}] Commands that peek ahead in the input stream.
+\item[\ctanpkg{xpinjin}] Automatically add pinyin to Chinese characters
+\item[\ctanpkg{zhnumber}] Typeset Chinese representations of numbers
+\item[\ctanpkg{zxjatype}] Standards-conforming typesetting of Japanese for \XeLaTeX.
+\end{description}
+Some of these packages are marked by their authors as experimental, but it is clear that these packages have been developed to solve specific needs for typesetting and document production.
+
+The \pkg{expl3} language has well and truly gained traction after many years of waiting patiently.
+
+\section[Logo for the \LaTeX3 Programming Language]
+ {A logo for the \LaTeX3 Programming Language}
+
+To show that \pkg{expl3} is ready for general use Paulo Cereda drew up a nice logo for us, showing a \mbox{hummingbird} (agile and fast\Dash but needs huge amounts of energy) picking at "l3". Big thanks to Paulo!
+\begin{center}
+\explogo
+\end{center}
+
+\section{Recent activity}
+
+\LaTeX3 work has only slowed, not ground to a halt.
+While changes have tended to be minor in recent times, there are a number of improvements worth discussing explicitly.
+\begin{enumerate}
+\item
+Bruno has extended the floating point code to cover additional functions such as inverse trigonometric functions.
+These additions round out the functionality well and make it viable for use in most cases needing floating point mathematics.
+\item
+Joseph's refinement of the experimental galley code now allows separation of paragraph shapes from margins/cutouts.
+This still needs some testing!
+\item
+For some time now \pkg{expl3} has provided "native" drivers although they have not been selected by default in most cases.
+These have been revised to improve robustness, which makes them probably ready to enable by default.
+The improvements made to the drivers have also fed back to more "general" \LaTeX\ code.
+\end{enumerate}
+
+
+\section{Work in progress}
+
+We're still actively discussing a variety of areas to tackle next.
+We are aware of various "odds and ends" in \pkg{expl3} that still need sorting out.
+In particular, some experimental functions have been working quite well and it's time to assess moving them into the "stable" modules, in particular the \pkg{l3str} module for dealing with catcode-twelve token lists more commonly known in \pkg{expl3} as \emph{strings}.
+
+Areas of active discussion including issues around uppercasing and lowercasing (and the esoteric ways that this can be achieved in \TeX) and space skipping (or not) in commands and environments with optional arguments.
+These two issues are discussed next.
+
+\subsection{Uppercasing and lowercasing}
+
+The commands \verb"\tl_to_lowercase:n" and \verb"\tl_to_uppercase:n" have long been overdue for a good hard look.
+From a traditional \TeX\ viewpoint, these commands are simply the primitive \verb"\lowercase" and \verb"\uppercase", and in practice it's well known that there are various limitations and peculiarities associated with them.
+We know these commands are good, to one extent or another, for three things:
+\begin{enumerate}
+\item
+Uppercasing text for typesetting purposes such as all-uppercase titles.
+\item
+Lowercasing text for normalisation in sorting and other applications such as filename comparisons.
+\item
+Achieving special effects, in concert with manipulating \verb"\uccode" and the like, such as defining commands that contain characters with different catcodes than usual.
+\end{enumerate}
+We are working on providing a set of commands to achieve all three of these functions in a more direct and easy-to-use fashion, including support for Unicode in \LuaLaTeX\ and \XeLaTeX.
+
+\pagebreak
+
+\subsection{Space-skipping in \pkg{xparse}}
+
+We have also re-considered the behaviour of space-skipping in \pkg{xparse}.
+Consider the following examples:
+\begin{verbatim}
+\begin{dmath} \begin{dmath}[label=foo]
+[x y z] = [1 2 3] x^2 + y^2 = z^2
+\end{dmath} \end{dmath}
+\end{verbatim}
+In the first case, we are typesetting some mathematics that contains square brackets.
+In the second, we are assigning a label to the equation using an optional argument, which also uses brackets.
+The fact that both work correctly is due to behaviour that is specifically programmed into the workings of the \texttt{dmath} environment of \pkg{breqn}: spaces before an optional argument are explicitly forbidden.
+At present, this is also how commands and environments defined using \pkg{xparse} behave.
+But consider a \pkg{pgfplots} environment:
+\begin{verbatim}
+\begin{pgfplot}
+ [
+ % plot options
+ ]
+ \begin{axis}
+ [
+ % axis options
+ ]
+ ...
+ \end{axis}
+\end{pgfplot}
+\end{verbatim}
+This would seem like quite a natural way to write such environments, but with the current state of \pkg{xparse} this syntax would be incorrect. One would have to write either of these instead:
+\begin{multicols}{2}
+\begin{verbatim}
+\begin{pgfplot}%
+ [
+ % plot options
+ ]
+\end{verbatim}
+\begin{verbatim}
+\begin{pgfplot}[
+ % plot options
+ ]
+\end{verbatim}
+\end{multicols}
+Is this an acceptable compromise?
+We're not entirely sure here\Dash we're in a corner because the humble \texttt{[} has ended up being part of both the syntax and semantics of a \LaTeX\ document.
+
+%There is one further matter to consider and that is how "control symbols" such as \verb"\\" behave in such matters.
+%Because \TeX\ does not skip spaces after control symbols, neither does \pkg{xparse}; therefore control symbols are a solution if one desires a command to use in a mathematics context where an optional argument could cause issues.
+%An example for this from \pkg{amsmath} is line breaks in multi-line display equations:
+%\begin{verbatim}
+%\begin{align}
+%a &= b+c \\
+%[x y z] &= [1 2 3]
+%\end{align}
+%\end{verbatim}
+%In \pkg{amsmath} this requires specific measures to be taken to allow \verb"\\" to behave correctly; with \pkg{xparse} this functionality is built in.
+
+Despite the current design covering most regular use-cases, we have considered adding a further option to \pkg{xparse} to define the space-skipping behaviour as desired by a package author.
+But at this very moment we've rejected adding this additional complexity, because environments that change their parsing behaviour based on their intended use make a \LaTeX-based language more difficult to predict; one could imagine such behaviour causing difficulties down the road for automatic syntax checkers and so forth.
+However, we don't make such decisions in a vacuum and we're always happy to continue to discuss such matters.
+
+
+\section{\ldots and for 2014 onwards}
+
+There is one (understandable) misconception that shows up once in a while with people claiming that
+\[
+ \textrm{\pkg{expl3}} = \textrm{\LaTeX3}.
+\]
+However, the correct relation would be a subset,
+\[
+ \textrm{\pkg{expl3}} \subset \textrm{\LaTeX3},
+\]
+with \pkg{expl3} forming the Core Language Layer on which there will eventually be several other layers on top that \mbox{provide}
+\begin{itemize}
+\item higher-level concepts for typesetting (Typesetting Foundation Layer),
+\item a designer interface for specifying document structures and layouts (Designer Layer),
+\item and finally a Document Representation Layer that implements document level syntax.
+\end{itemize}
+Of those four layers, the lowest one\Dash\pkg{expl3}\Dash is available for use and with \pkg{xparse} we have an instance of the Document Representation Layer modeled largely after \LaTeXe{} syntax (there could be others). Both can be successfully used within the current \LaTeXe{} framework and as mentioned above this is increasingly happening.
+
+The middle layers, however, where the rubber meets the road, are still at the level of prototypes and ideas (templates, \pkg{ldb}, galley, \pkg{xor} and all the good stuff) that need to be revised and further developed to arrive at a \LaTeX3 environment that can stand on its own and that is to where we want to return in 2014.
+
+An overview on this can be found in the answer to "What can *I* do to help The \LaTeX{} Project?"\ on Stack Exchange,\footnote{\url{http://tex.stackexchange.com/questions/45838}}
+which is reproduced below in slightly abridged form.
+This is of course not the first time that we have discussed such matters, and you can find similar material in other publications such as those at \url{http://latex-project.org}; e.g., the architecture talk given at the TUG 2011 conference.
+
+\bigskip
+
+\begin{center}
+\explbanner
+\end{center}
+
+\newpage
+\section{What can you do for The \LaTeX{} Project?}
+\textbf{By Frank Mittelbach}
+
+My vision of \LaTeX3 is really a system with multiple layers that provide interfaces for different kinds of roles. These layers are
+\begin{itemize}
+\item the underlying engine (some \TeX\ variant)
+\item the programming layer (the core language, i.e., \pkg{expl3})
+\item the typesetting foundation layer (providing higher-level concepts for typesetting)
+\item the typesetting element layer (templates for all types of document elements)
+\item the designer interface foundation layer
+\item the class designer layer (where instances of document elements with specific settings are defined)
+\item document representation layer (that provides the input syntax, i.e., how the author uses elements)
+\end{itemize}
+If you look at it from the perspective of user roles then there are at least three or four roles that you can clearly distinguish:
+\begin{itemize}
+\item The Programmer (template and functionality provider)
+\item The Document Type Designer (defines which elements are available; abstract syntax and semantics)
+\item The Designer (typography and layout)
+\item The Author (content)
+\end{itemize}
+As a consequence The \LaTeX{} Project needs different kinds of help depending on what layer or role we are looking at.
+
+The "Author" is using, say, list structures by specifying something like \verb"\begin{itemize} \item" in his documents. Or perhaps by writing \Verb|<ul> ... </ul>| or whatever the UI representation offers to him.
+
+The "Document Type Designer" defines what kind of abstract document elements are available, and what attributes or arguments those elements provide at the author level. E.g., he may specify that a certain class of documents provides the display lists "enumerate", "itemize" and "description".
+
+The "Programmer" on the other hand implements templates (that offer customizations) for such document elements, e.g., for display lists. What kind of customization possibilities should be provided by the "Programmer" is the domain of the "Document Designer"; he drives what kind of flexibility he needs for the design. In most cases the "Document Designer" should be able to simply select templates (already written) from a template library and only focus on the design, i.e., instantiating the templates with values so that the desired layout for "itemize" lists, etc., is created.
+
+In real life a single person may end up playing more than one role, but it is important to recognise that all of them come with different requirements with respect to interfaces and functionality.
+
+\subsection{Programming Layer}
+
+The programming layer consists of a core language layer (called \pkg{expl3} (EXP erimental L aTeX 3) for historical reasons and now we are stuck with it \texttt{:-)}) and two more components: the "Typesetting Foundation Layer" that we are currently working on and the "Typesetting Element Layer" that is going to provide customizable objects for the design layer. While \pkg{expl3} is in many parts already fairly complete and usable the other two are under construction.
+
+Help is needed for the programming layer in
+\begin{itemize}
+\item helping by extending and completing the regression test suite for \pkg{expl3}
+\item helping with providing good or better documentation, including tutorials
+\item possibly helping in coding additional core functionality\Dash but that requires, in contrast to the first two points, a good amount of commitment and experience with the core language as otherwise the danger is too high that the final results will end up being inconsistent
+\end{itemize}
+Once we are a bit further along with the "Typesetting Foundation Layer" we would need help in
+providing higher-level functionality, perhaps rewriting existing packages/code for elements making use of extended possibilities.
+Two steps down the road (once the "\mbox{Designer} Layer" is closer to being finalized) we would need help with developing templates for all kinds of elements.
+
+In summary for this part, we need help from people interested in programming in \TeX\ and \pkg{expl3} and/or interested in providing documentation (but for this a thorough understanding of the programming concepts is necessary too).
+
+\subsection{Design Layer}
+
+The intention of the design layer is to provide interfaces that allow specifying layout and typography styles in a declarative way. On the implementation side there are a number of prototypes (most notably \pkg{xtemplate} and the recent reimplementation of \pkg{ldb}).
+These need to be unified into a common model which requires some more experimentation and probably also some further thoughts.
+
+But the real importance of this layer is not the implementation of its interfaces but the conceptual view of it: provisioning a rich declarative method (or methods) to describe design and layout. I.e., enabling a designer to think not in programs but in visual representations and relationships.
+
+So here is the big area where people who do not feel they can or want to program \TeX's bowels can help. What would be extremely helpful (and in fact not just for \LaTeX3) would be
+\begin{itemize}
+\item collecting and classifying a \emph{huge} set of layouts and designs
+\begin{itemize}[nosep]
+\item designs for individual document elements (such as headings, TOCs, etc)
+\item document designs that include relationships between document elements
+\end{itemize}
+\item thinking about good, declarative ways to specify such designs
+\begin{itemize}[nosep]
+\item what needs to be specified
+\item to what extent and with what flexibility
+\end{itemize}
+\end{itemize}
+I believe that this is a huge task (but rewarding in itself) and already the first part of collecting existing design specifications will be a major undertaking and will need coordination and probably a lot of work. But it will be a huge asset towards testing any implementations and interfaces for this layer later on.
+
+\subsection{Document Interface Layer}
+
+If we get the separation done correctly, then this layer should effectively offer nothing more than a front end for parsing the document syntax and transforming it into an internal standardised form. This means that on this layer one should not see any (or not much) coding or computation.
+
+It is envisioned that alternative document syntax models can be provided.
+At the moment we have a draft solution in \pkg{xparse}.
+This package offers a document syntax in the style of \LaTeXe, that is with \verb|*|-forms, optional arguments in brackets, etc., but with a few more bells and whistles such as a more generalized concept of default values, support for additional delimiters for arguments, verbatim-style arguments, and so on.
+It is fairly conventional though.
+In addition when it was written the clear separation of layers wasn't well-defined and so the package also contains components for conditional programming that I no longer think should be there.
+
+Bottom line on what is needed for this layer is to
+\begin{itemize}
+\item think about good syntax for providing document content from "the author" perspective
+\item think about good syntax for providing document content from an "application to typesetting" perspective, i.e., the syntax and structure for automated typesetting where the content is prepared by a system/application rather than by a human
+\end{itemize}
+These two areas most likely need strict structure (as automation works much better with structures that do not have a lot of alternative possibilities and shortcuts, etc.) and even when just looking at the human author a lot of open questions need answering.
+And these answers may or may not be to painfully stick with existing \LaTeXe\ conventions in all cases (or perhaps with any?).
+
+None of this requires coding or \pkg{expl3} experience. What it requires is familiarity with existing input concepts, a feel for where the pain points currently are and the willingness to think and discuss what alternatives and extensions could look like.
+
+\subsection{In Summary}
+
+Basically help is possible on any level and it doesn't need to involve programming. Thoughts are sprinkled throughout this article, but here are a few more highlights:
+\begin{itemize}
+\item help with developing/improving the core programming layer by
+\begin{itemize}[nosep]
+\item joining the effort to improve the test suite
+\item help improving the existing (or not existing) documentation
+\item joining the effort to produce core or auxiliary code modules
+\end{itemize}
+\item help on the design layer by
+\begin{itemize}[nosep]
+\item collecting and classifying design tasks
+\item thinking and suggesting ways to describe layout requirements in a declarative manner
+\end{itemize}
+\item help on shaping the document interface layer
+\end{itemize}
+These concepts, as well as their implementation, are under discussion on the list \texttt{latex-l}.\footnote{Instructions for joining and browsing archives at:\\ \url{http://latex-project.org/code.html}}
+The list has only a fairly low level of traffic right now as actual implementation and development tasks are typically discussed directly among the few active implementors. But this might change if more people join.
+
+\subsection{And something else \dots}
+
+The people on the \LaTeX3 team are also committed to keeping \LaTeXe\ stable and even while there isn't that much to do these days there remains the need to resolve bug reports (if they concern the 2e core), provide new distributions once in a while, etc. All this is work that takes effort or remains undone or incomplete. Thus here too, it helps the \LaTeX3 efforts if we get help to free up resources.
+
+\end{document}
+
+
+
diff --git a/macros/latex-dev/required/l3kernel/l3news10.pdf b/macros/latex-dev/required/l3kernel/l3news10.pdf
new file mode 100644
index 0000000000..f33607fe58
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news10.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news10.tex b/macros/latex-dev/required/l3kernel/l3news10.tex
new file mode 100644
index 0000000000..88291e848f
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news10.tex
@@ -0,0 +1,220 @@
+% Copyright 2016 The LaTeX3 Project
+\documentclass{ltnews}
+
+\PassOptionsToPackage{colorlinks}{hyperref}
+
+\usepackage{csquotes}
+\usepackage{hologo}
+\usepackage{ragged2e}
+\usepackage{underscore}
+
+\AtBeginDocument{%
+ \renewcommand*{\LaTeXNews}{\LaTeX3~News}%
+ \RaggedRight
+ \setlength\parindent{1em}%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\publicationmonth{November}
+\publicationyear{2016}
+\publicationissue{10}
+
+% Avoid hyphenation of csnames
+\makeatletter
+\protected\edef\cs#1{%
+ \noexpand\path{\@backslashchar#1}%
+}
+\makeatother
+
+\begin{document}
+
+\maketitle
+
+There has been something of a gap since the last \LaTeX3 News, but this does
+not mean that work has not been going on. The Team have been working on a
+number of areas, many of which reflect wider take-up of \pkg{expl3}. There have
+also been a number of significant new developments in the \LaTeX3
+\enquote{sphere} in the last two years.
+
+\section{\pkg{l3build}: Testing \LaTeX{} packages}
+
+Testing has been an important part of the work of the team since they assumed
+maintenance of \LaTeX{} over twenty years ago. Various scripts have been used
+over that time by the team for testing, but these have until recently not been
+set up for wider use.
+
+With the general availability of \hologo{LuaTeX} it is now possible to be sure
+that every \TeX{} user has a powerful general scripting language available:
+Lua. The team have used this to create a new general testing system for \TeX{}
+code, \pkg{l3build}. This \emph{is} designed to be used beyond the team, so is
+now available in \TeX{} Live and \hologo{MiKTeX} and is fully documented.
+Testing using \pkg{l3build} makes use of a normalised version of the
+\texttt{.log} file, so can test any aspect of \TeX{} output (e.g., by using
+\cs{showbox}) or its algorithms (by displaying results in the \texttt{.log}).
+
+Part of the remit for creating \pkg{l3build} was to enable the team to work
+truly cross-platform and to allow testing using multiple \TeX{} engines
+(earlier systems were limited to a single engine, normally \eTeX{}). The new
+testing system means we are in a much stronger position to support a variety of
+engines (see below). It has also enabled us to give useful feedback on
+development of the \hologo{LuaTeX} engine.
+
+As well as the core capability in testing, \pkg{l3build} also provides a
+\enquote{one stop} script for creating release bundles. The script is
+sufficiently flexible that for many common \LaTeX{} package structures, setting
+up for creating releases will require only a few lines of configuration.
+
+In addition to the documentation distributed with \pkg{l3build}, the project
+website~\cite[publications in 2014]{10:project-publications} contains some
+articles, videos and conference presentations that explain how to use
+\pkg{l3build} to manage and test any type of (\LaTeX{}) package.
+
+\section{Automating \pkg{expl3} testing}
+
+As well as developing \pkg{l3build} for local use, the team have also set up
+integration testing for \pkg{expl3} using the Travis-CI system. This means that
+\emph{every} commit to the \LaTeX3 code base now results in a full set of tests
+being run. This has allowed us to significantly reduce the number of occasions
+where \pkg{expl3} needs attention before being released to CTAN.
+
+Automated testing has also enabled us to check that \pkg{expl3} updates do not
+break a number of key third-party packages which use the programming
+environment.
+
+\section{Refining \pkg{expl3}}
+
+Work continues to improve \pkg{expl3} both in scope and robustness. Increased
+use of the programming environment means that code which has to-date been
+under-explored is being used, and this sometimes requires changes to the code.
+
+The team have extended formal support in \pkg{expl3} to cover the engines
+p\TeX{} and up\TeX{}, principally used by Japanese \TeX{} users. This has been
+possible in part due to the \pkg{l3build} system discussed above.
+Engine-dependent variations between \hologo{pdfTeX}, \hologo{XeTeX},
+\hologo{LuaTeX} and (u)p\TeX{} are now well-understood and documented. As part
+of this process, the \enquote{low-level} part of \pkg{expl3}, which saves all
+primitives, now covers essentially all primitives found in all of these
+engines.
+
+The code in \pkg{expl3} is now entirely self-contained, loading no other
+third-party packages, and can also be loaded as a generic package with plain
+\TeX{}, \emph{etc.} These changes make it much easier to diagnose problems and
+make \pkg{expl3} more useful. In particular it can be used as a programming
+language for generic packages, that then can run without modifications under
+different formats!
+
+The team have made a range of small refinements to both internals and
+\pkg{expl3} interfaces. Internal self-consistency has also been improved, for
+example removing almost all use of \texttt{nopar} functions. Performance
+enhancements to the \pkg{l3keys} part of \pkg{expl3} are ongoing and should
+result in significantly faster key setting. As keyval methods are increasingly
+widely used in defining behaviours, this will have an impact on compile times
+for end users.
+
+\section{Replacing \cs{lowercase} and \cs{uppercase}}
+
+As discussed in the last \LaTeX3 News, the team have for some time been keen to
+provide new interfaces which do not directly expose (or in some cases even use)
+the \TeX{} primitives \cs{lowercase} and \cs{uppercase}. We have now created a
+series of different interfaces that provide support for the different
+conceptual uses which may flow from the primitives:
+\begin{itemize}
+ \item For case changing text, \cs{tl_upper_case:n}, \cs{tl_lower_case:n},
+ \cs{tl_mixed_case:n} and related language-aware functions. These are
+ Unicode-capable and designed for working with text. They also allow for
+ accents, expansion of stored text and leaving math mode unchanged. At
+ present some of the interface decisions are not finalised so they are
+ marked as experimental, but the team expect the core concept to be stable.
+ \item For case changing programming strings, \cs{str_upper_case:n},
+ \cs{str_lower_case:n} and \cs{str_fold_case:n}. Again these are
+ Unicode-aware, but in contrast to the functions for text are not
+ context-dependent. They are intended for caseless comparisons, constructing
+ command names on-the-fly and so forth.
+ \item For creating arbitrary character tokens, \cs{char_generate:nn}. This
+ is based on the \cs{Ucharcat} primitive introduced by \hologo{XeTeX}, but
+ with the ideas extended to other engines. This function can be used to
+ create almost any reasonable token.
+ \item For defining active characters, \cs{char_set_active_eq:NN} and
+ related functions. The concept here is that active characters should be
+ equivalent to some named function, so one does not directly define the
+ active character.
+\end{itemize}
+
+\section{Extending \pkg{xparse}}
+
+After discussions at TUG2015 and some experimentation, the team have added a
+new argument type, \texttt{e} (\enquote{embellishment}), to \pkg{xparse}.
+This allows arguments similar to
+\TeX{} primitive sub- and superscripts to be accepted. Thus
+\begin{verbatim}
+\DeclareDocumentCommand\foo{e{^_}}
+ {\showtokens{"#1"}}
+\foo^{Hello} world
+\end{verbatim}
+will show
+\begin{verbatim}
+"{Hello}{-NoValue-}".
+\end{verbatim}
+
+At present, this argument type is experimental: there are a number of models
+which may make sense for this interface.
+
+\section{A new \cs{parshape} model}
+
+As part of development of \pkg{l3galley}, Joseph Wright has proposed a new
+model for splitting up the functions of the \cs{parshape} primitive into three
+logical elements:
+\begin{itemize}
+ \item Margins between the edges of the galley and the paragraph (for example
+ an indented block);
+ \item Cut-out sections running over a fixed number of lines, to support
+ \enquote{in place} figures and so forth;
+ \item Running or single-paragraph shape.
+\end{itemize}
+
+There are additional elements to consider here, for example whether lines are
+the best way to model the length of shaping, how to handle headings, cut-outs
+at page breaks, \emph{etc.}
+
+
+\section{Globally optimized pagination of documents}
+
+Throughout 2016 Frank Mittelbach has worked on methods and algorithms for
+globally optimizing the pagination of documents including those that contain
+floats. Early research results have been presented at Bacho\TeX{} 2016, TUG
+2016 in Toronto and later in the year at \mbox{DocEng'16}, the ACM Symposium on
+Document Engineering in Vienna. A link to the ACM paper (that allows a download
+free of charge) can be found on the project
+website~\cite{10:project-publications}. The site also holds the speaker notes from
+Toronto and will host a link to a video of the presentation once it becomes
+available.
+
+The framework developed by Frank is based on the extended functionality
+provided by \hologo{LuaTeX}, in particular its callback functions that allow
+interacting with the typesetting process at various points. The algorithm that
+determines the optimal pagination of a given document is implemented in {Lua}
+and its results are then used to direct the formatting done by the \TeX{}
+engine.
+
+At the current point in time this a working prototype but not yet anywhere near
+a production-ready system. However, the work so far shows great potential and
+Frank is fairly confident that it will eventually become a generally usable
+solution.
+
+\section{Looking forward}
+
+The \hologo{LuaTeX} engine has recently reached version~1.0. This may presage a
+stable \hologo{LuaTeX} and is likely to result in wider use of this engine in
+production documents.If that happens we expect to implement some of the more
+complex functionality (such as complex pagination requirements and models) only
+for \hologo{LuaTeX}.
+
+\begin{thebibliography}{10}
+ \raggedright
+ \bibitem{10:project-publications}
+ Links to various publications by members of the \LaTeX{} Project Team.
+ \newblock \url{https://www.latex-project.org/publications}.
+\end{thebibliography}
+
+\end{document}
diff --git a/macros/latex-dev/required/l3kernel/l3news11.pdf b/macros/latex-dev/required/l3kernel/l3news11.pdf
new file mode 100644
index 0000000000..192d1d97cc
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news11.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news11.tex b/macros/latex-dev/required/l3kernel/l3news11.tex
new file mode 100644
index 0000000000..a1fd8a129c
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news11.tex
@@ -0,0 +1,208 @@
+% Copyright 2017-2018 The LaTeX3 Project
+
+\documentclass{ltnews}
+
+\PassOptionsToPackage{colorlinks}{hyperref}
+
+\usepackage{csquotes}
+\usepackage{hologo}
+\usepackage{ragged2e}
+\usepackage{underscore}
+
+
+%%% wrong in ltnews.cls ... so some tmp fix here at the moment:
+\makeatletter
+\renewcommand{\subsubsection}{%
+ \@startsection
+ {subsubsection}{2}{\leftmargini}{-1.5ex \@plus -1ex \@minus -.2ex}%
+ {1sp}{\@subheadingfont}%
+}
+\makeatother
+
+
+\AtBeginDocument{%
+ \renewcommand*{\LaTeXNews}{\LaTeX3~News}%
+ \RaggedRight
+ \setlength\parindent{1em}%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\publicationmonth{February}
+\publicationyear{2018}
+\publicationissue{11}
+
+% Avoid hyphenation of csnames
+\makeatletter
+\protected\edef\cs#1{%
+ \noexpand\path{\@backslashchar#1}%
+}
+\makeatother
+\hyphenpenalty=10000 \exhyphenpenalty=10000
+
+\begin{document}
+
+\maketitle
+
+\tableofcontents
+
+\section{Move of sources from Subversion to Git}
+
+The \LaTeX{} team have used a variety of version control systems over the life
+of the \LaTeX3 sources. For a long time we maintained the \LaTeX3 sources in
+Subversion (\texttt{svn}) but also provided a read-only clone of them on GitHub using
+SubGit from TMate Software~\cite{SubGit} to synchronize the two
+repositories---a solution that worked very well.
+
+We have now retired the Subversion repository and completely moved over to Git,
+with the master \LaTeX3 repository hosted on GitHub:
+\url{https://github.com/latex3/latex3}. This new approach means we are (slowly)
+adopting some new approaches to development, for example branches and accepting
+pull requests.
+
+\subsection{Version identifiers}
+
+Following this change, we have removed Subversion \verb=$Id= lines from the
+\LaTeX3 sources. At present, we will be retaining \cs{GetIdInfo} as there are
+several possible use cases. The \LaTeX3 sources now have only release date
+strings as identifiers. However, the team recommend that package authors
+include version information directly in \cs{ProvidesExplPackage} (or similar)
+lines.
+
+\section{\pkg{expl3} updates and extensions}
+
+Work has continued on the codebase over the last year, with both small
+changes/fixes and more substantial changes taking place. The following sections
+summarise some of the more notable changes.
+
+\subsection{\pkg{l3sort} moves to the kernel}
+
+Sorting is an important ability, and for some time the team have provided a
+stand-alone \pkg{l3sort} to support this. The functionality has seen wide take
+up, and so has now been integrated directly into the kernel. This took place in
+parallel with some interface changes to \enquote{round out} the code.
+
+\subsection{Boolean functions}
+
+For some time, the team have been aware that boolean expressions can fail in
+certain circumstances, leading to low-level errors. This is linked to two
+features of the long-standing \cs{bool_if:n(TF)} function: expandable operation
+and short-circuit evaluation.
+
+Addressing that has meant two changes: altering \cs{bool_if:n(TF)} to
+\emph{always} evaluate each part of the expression, and introducing new
+short-circuit functions without the issue. The latter are \verb|lazy| in \pkg{expl3}
+terms:
+\begin{itemize}
+\item \cs{bool_lazy_all:n(TF)}
+\item \cs{bool_lazy_and:nn(TF)}
+\item \cs{bool_lazy_any:n(TF)}
+\item \cs{bool_lazy_or:nn(TF)}
+\end{itemize}
+These new, stable functions are now the recommended way of handling boolean
+evaluations. Package authors are encouraged to employ these new functions as
+appropriate.
+
+\subsection{Revision of \pkg{l3file}}
+
+Large parts of \pkg{l3file} have been revised to give a better separation of
+path/file/extension. This has resulted in the addition of a number of new support
+functions and variables.
+
+At the same time, new experimental functions have been added to utilise a
+number of useful primitives in \hologo{pdfTeX}{}: \cs{file_get_mdfive_hash:nN},
+\cs{file_get_size:nN} and \cs{file_get_timestamp:nN}. Currently, \hologo{XeTeX}
+does not support getting file size/timestamp information: this is available in
+other engines.
+
+Paralleling these changes, we have added (experimental) support for shell
+escape to the \pkg{l3sys} module, most notably \cs{sys_shell_now:n}. A range of
+test booleans are also available to check whether shell escape is enabled.
+
+\subsection{Detection of \cs{cs_generate_variant:Nn} errors}
+
+The ability to generate variants is an important feature of \pkg{expl3}. At
+the same time, there are crucial aspects of this approach that can be
+misunderstood by users. In particular, the requirement that variants map
+correctly to an underlying \verb|N|- or \verb|n|-type base function is sometimes
+misunderstood.
+
+To help detect and correct these cases, \cs{cs_generate_variant:Nn} now
+carries out error checking on its arguments, and raises a warning where
+it is mis-applied. At present, the team have avoided making this an error
+as it is likely to be seen by end users rather than directly by package
+developers. In time, we are likely to revisit this and tighten up
+further on this key requirement.
+
+\subsection{Accessing random data}
+
+To support randomised data selection, we have introduced a family of
+experimental functions which use under\-lying engine support for random values,
+and provide one entry at random from the data type.
+
+At the same time, we have addressed some issues with uniformity stemming from
+the random number function used by \hologo{pdfTeX}{} and inherited by other
+engines. This means that \pkg{expl3}'s FPU will generate \emph{pseudo}-random
+values across the range of possible outputs.
+
+\subsection{More powerful debugging}
+
+A new set of debugging functions have been added to the kernel. These allow
+debug code to be enabled locally using the new option \verb|enable-debug| along
+with functions \cs{debug_on:n} and \cs{debug_off:n}. Accompanying this change, we
+have improved the handling of global/local consistency in variable setting.
+
+\subsection{Mark-up changes in \pkg{l3doc}}
+
+Since the introduction of the \verb|__| syntax to mark internal functions, the
+need for explicit markup of internal material in sources has been negated.
+As such, we have now dropped the requirement to mark internal material with
+\verb|[aux]| when using \pkg{l3doc}. Instead, the status of functions and
+variables is auto-detected from the presence of \verb|__|. For cases where
+non-standard names are used for internal code, the mark-up \verb|[int]| is
+retained, \emph{e.g.}
+\begin{verbatim}
+\begin{macro}[int]{\l@expl@enable@debug@bool}
+\end{verbatim}
+
+\newpage
+\section{\pkg{l3build} updates}
+
+Work on \pkg{l3build} has continued in parallel with \pkg{expl3} work, in
+particular continuing to develop features to allow wider use of the tool.
+
+Paralleling the move of the \LaTeX3 codebase to Git, \pkg{l3build} now has its
+own separate Git repository: \url{https://github.com/latex3/l3build}. This will
+enable us to involve other developers in the Lua code required for the build
+system. At the same time, we have split the code into a number of small source
+files, again to ease development both for the team ourselves and for potential
+collaborators.
+
+Another major change is that \pkg{l3build} can now retain the structure of
+source repositories when creating a CTAN archive. Whilst the team favor `flat'
+source setups, other users prefer structured approaches. Most notably, this
+new \pkg{l3build} functionality means that it is now used to carry out
+\pkg{beamer} releases.
+
+The other major new feature is a new approach to multiple test setups, which
+replaces the older \verb|--testfiledir| option. In the new approach, separate
+configuration files are listed in the main \verb|build.lua| script, and can be
+selected manually using a new \verb|--config| switch. This new approach allows
+complex test setups to be run in a totally automated fashion, which is
+important for kernel testing.
+
+Some changes to the normalisation routines have been carried out, some to deal
+with upcoming \hologo{LuaTeX} changes, others to address aspects which show up
+only in some tests. This has required \verb|.tlg| updates in some cases: as far
+as possible, we strive to avoid requiring changes to the reference files.
+
+\begin{thebibliography}{10}
+ \raggedright
+ \bibitem{SubGit}
+ \emph{SubGit}, TMate Software, \url{https://subgit.com}
+ \bibitem{11:project-publications}
+ Links to various publications by members of the \LaTeX{} Project Team.
+ \newblock \url{https://www.latex-project.org/publications}
+\end{thebibliography}
+
+\end{document}
diff --git a/macros/latex-dev/required/l3kernel/l3news12.pdf b/macros/latex-dev/required/l3kernel/l3news12.pdf
new file mode 100644
index 0000000000..c974194673
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news12.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news12.tex b/macros/latex-dev/required/l3kernel/l3news12.tex
new file mode 100644
index 0000000000..f41e4b3690
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3news12.tex
@@ -0,0 +1,383 @@
+% Copyright 2019 The LaTeX3 Project
+\documentclass{ltnews}
+
+\usepackage{csquotes}
+\usepackage{hologo}
+\usepackage{ragged2e}
+
+\PassOptionsToPackage{colorlinks}{hyperref}
+
+%%% wrong in ltnews.cls ... so some tmp fix here at the moment:
+\makeatletter
+\renewcommand{\subsubsection}{%
+ \@startsection
+ {subsubsection}{2}{\leftmargini}{-1.5ex \@plus -1ex \@minus -.2ex}%
+ {1sp}{\@subheadingfont}%
+}
+\makeatother
+
+\AtBeginDocument{%
+ \renewcommand*{\LaTeXNews}{\LaTeX3~News}%
+ \RaggedRight
+ \setlength\parindent{1em}%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\publicationmonth{January}
+\publicationyear{2020}
+\publicationissue{12}
+
+% Avoid hyphenation of csnames
+\makeatletter
+\protected\edef\cs#1{%
+ \noexpand\path{\@backslashchar#1}%
+}
+\makeatother
+\hyphenpenalty=10000
+\exhyphenpenalty=10000
+\hbadness=2500
+
+\makeatletter
+\renewcommand*\l@section[2]{%
+ \ifnum \c@tocdepth >\z@
+ \addpenalty\@secpenalty
+ \addvspace{0.7em \@plus\p@}% reduce from 1.0em
+ \setlength\@tempdima{1.5em}%
+ \begingroup
+ \parindent \z@ \rightskip \@pnumwidth
+ \parfillskip -\@pnumwidth
+ \leavevmode \bfseries
+ \advance\leftskip\@tempdima
+ \hskip -\leftskip
+ #1\nobreak\hfil
+ \nobreak\hb@xt@\@pnumwidth{\hss #2%
+ \kern-\p@\kern\p@}\par
+ \endgroup
+ \fi}
+\makeatother
+
+\newenvironment{compactitemize}%
+ {\begin{itemize}%
+ \setlength{\itemsep}{0pt}%
+ \setlength{\parskip}{0pt}%
+ \setlength{\parsep} {0pt}%
+ }%
+ {\end{itemize}}
+
+
+\begin{document}
+
+\maketitle
+
+\tableofcontents
+
+\section{Introduction}
+
+There has been quite a gap since the last \emph{\LaTeX3 News} (Issue~11,
+February 2018), and so there is quite a bit to cover here. Luckily, one of the
+things there \emph{is} to cover is that we are using a more formalised approach
+for logging changes, so writing up what has happened is a bit easier.
+(By mistake \LaTeX3 News~11 itself did not get \emph{published} when written, but is
+now available: we have kept the information it contains separate as it
+is a good summary of the work that had happened in 2017.)
+
+Work has continued apace across the \LaTeX3 codebase in the last (nearly) two
+years. A lot of this is ultimately focussed on making the core of \pkg{expl3}
+even more stable: \emph{squeezing} out more experimental ideas, refining
+ones we have and making it a serious option for core \LaTeX{} programming.
+
+As a result of these activities, the \LaTeX3 programming layer will be
+available as part of the kernel of \LaTeXe{} from 2020-02-02 onwards, i.e., can
+be used without explicitly loading \pkg{expl3}. See \emph{\LaTeX{}
+ News~31}~\cite{12:site-news} for more details on this.
+
+\section{New features in \pkg{expl3}}
+
+\subsection{A new argument specifier: \texttt{e}-type}
+
+During 2018, the team worked with the \TeX{} Live, \hologo{XeTeX} and
+(u)p\TeX{} developers to add the \cs{expanded} primitive to \hologo{pdfTeX}{},
+\hologo{XeTeX} and (u)p\TeX{}. This primitive was originally suggested for
+\hologo{pdfTeX}{} v1.50 (never released), and was present in \hologo{LuaTeX}{}
+from the start of that project.
+
+Adding \cs{expanded} lets us create a new argument specifier: \texttt{e}-type
+expansion. This is \emph{almost} the same as \texttt{x}-type, but is itself
+expandable. (It also doesn't need doubled \verb|#| tokens.) That's incredibly
+useful for creating function-like macros: you can ensure that \emph{everything}
+is expanded in an argument before you go near it, with not an \cs{expandafter}
+in sight.
+
+\subsection{New functions}
+
+New programming tools have appeared in various places across \pkg{expl3}.
+The highlights are
+\begin{compactitemize}
+ \item Shuffling of sequences to allow randomization
+ \item Arrays of integers and floating point values; these have constant-time
+ access
+ \item Functions to return values after system shell usage
+ \item Expandable access to file information, including file size, MD5
+ hash and modification date
+\end{compactitemize}
+
+For the latter, we have revised handling of file names considerably. There is
+now support for finding files in expansion contexts (by using the
+\cs{(pdf)filesize} primitive). Spaces and quotes in file names are now fully
+normalised, in a similar manner to the approach used by the latest \LaTeXe{}
+kernel.
+
+\subsection{String conversion moves to \pkg{expl3}}
+
+In addition to entirely new functions, the team have moved the
+\pkg{l3str-convert} module from the \pkg{l3experimental} bundle into the
+\pkg{expl3} core. This module is essential for dealing with the need to produce
+UTF-16 and UTF-32 strings in some contexts, and also offers
+built-in escape for url and PDF strings.
+
+\subsection{Case changing of text}
+
+Within \pkg{expl3}, the team have renamed and reworked the ideas from
+\cs{tl_upper_case:n} and so on, creating a new module \pkg{l3text}. This is a
+\enquote{final} home for functions to manipulate \emph{text}; token lists that
+can reasonably be expected to expand to plain text plus limited markup, for
+example emphasis and labels/references. Moving these functions, we have also
+made a small number of changes in other modules to give consistent names to
+functions: see the change log for full details.
+
+Over time, we anticipate that functions for other textual manipulation will be
+added to this module.
+
+\section{Notable fixes and changes}
+
+\subsection{File name parsing}
+
+The functions for parsing file names have been entirely rewritten, partly as
+this is required for the expandable access to file information mentioned above.
+The new code correctly deals with spaces and quote marks in file names and
+splits the path/name/extension.
+
+\subsection{Message formatting}
+
+The format of messages in \pkg{expl3} was originally quite text-heavy, the idea
+being that they would stand out in the \texttt{.log} file. However, this made
+them hard to find by a regular expression search, and was very different from
+the \LaTeXe{} message approach. The formatting of \pkg{expl3} messages has been
+aligned with that from the \LaTeXe{} kernel, such that IDE scripts and
+similar will be able to find and extract them directly.
+
+\subsection{Key inheritance}
+
+A number of changes have been made to the inheritance code for keys,
+to allow inheritance to work \enquote{as expected} in (almost) all
+cases.
+
+\subsection{Floating point juxtaposition}
+
+Implicit multiplication by juxtaposition, such as \verb|2pi|, is now handled
+separately from parenthetic values. Thus for example \verb|1in/1cm| is treated
+as equal to \verb|(1in)/(1cm)| and thus yields \verb|2.54|, and \verb|1/2(pi+pi)| is
+equal to \verb|pi|.
+
+\subsection{Changing box dimensions}
+
+\TeX{}'s handling of boxes is subtly different from other registers, and this
+shows up in particular when you want to resize a box. To bring treatment of
+boxes, or rather the grouping behavior of boxes, into line with other
+registers, we have made some internal changes to how functions such as
+\cs{box_set_wd:N} are implemented. This will be transparent for
+\enquote{well-behaved} use cases of these functions.
+
+\subsection{More functions moved to stable}
+
+A large number of functions which were introduced as candidates have been
+evaluated and moved to stable status. The team hopes to move all functions
+in \pkg{expl3} to stable status, or move them out of the core, over the coming
+months.
+
+\subsection{Deprecations}
+
+There have been two notable sets of deprecations over the past 18 months.
+First, we have rationalised all of the \enquote{raw} primitive names to the
+form \cs{tex_<name>:D}. This means that the older names, starting
+\mbox{\cs{pdftex_...}}, \cs{xetex_...}, etc., have been removed.
+
+Secondly, the use of integer constants, which dates back to the earliest days
+of \pkg{expl3}, is today more likely to make the code harder to read than
+anything else. Speed improvements in engines mean that the tiny enhancements in
+reading such constants are no longer required. Thus for example \cs{c_two} is
+deprecated in favour of simply using \texttt{2}.
+
+In parallel with this, a number of older \texttt{.sty} files have been removed.
+These older files provided legacy stubs for files which have now been
+integrated in the \pkg{expl3} core. They have now had sufficient time to allow
+users to update their code.
+
+\section{Internal improvements}
+
+\subsection{Cross-module functions}
+
+The team introduced the idea of internal module functions some time ago. Within
+the kernel, there are places where functions need to be used in multiple
+modules. To make the nature of the kernel interactions clearer, we have worked
+on several aspects
+\begin{compactitemize}
+ \item Reducing as far as possible cross-module functions
+ \item Making more generally-useful functions public, for example
+ scan marks
+ \item Creating an explicit cross-kernel naming convention for
+ functions which are internal but are essential to use in multiple
+ kernel modules
+\end{compactitemize}
+
+\subsection{The backend}
+
+Creating graphics, working with color, setting up hyperlinks and so on require
+backend-specific code. Here, backends are for example \texttt{dvips},
+\texttt{xdvipdfmx} and the direct PDF mode in \hologo{pdfTeX} and
+\hologo{LuaTeX}. These functions are needed across the \LaTeX3 codebase and
+have to be updated separately from the \pkg{expl3} core. To facilitate that, we
+have split those sources into a separate bundle, which can be updated as
+required.
+
+At the same time, the code these files contain is very low-level and is best
+described as internal. We have re-structured how the entire set of functions
+are referred to such that they are now internal for the area they implement,
+for example image inclusion, box affine transformations, etc.
+
+\section{Better support for (u)p\texorpdfstring{\kern-.05em}{}\TeX{}}
+
+The developers behind (u)p\TeX{} (Japanese \TeX{}) have recently enhanced their
+English documentation (see \url{https://github.com/texjporg/ptex-manual}).
+Using this new information, we have been able to make internal adjustments to
+\pkg{expl3} to better support these engines.
+
+\section{Options}
+
+A new option \texttt{undo-recent-deprecations} is now available for cases where
+a document (or package) requires some \pkg{expl3} functions that have been
+formally removed after deprecation. This is to allow \emph{temporary}
+work-arounds for documents to be compiled whilst code is begin updated.
+
+The \enquote{classical} options for selecting backends (\texttt{dvips},
+\texttt{pdftex}, etc.)\ are now recognised in addition to the native key--value
+versions. This should make it much easier to use the \pkg{expl3} image and color
+support as it is brought up to fully-workable standards.
+
+\section{Engine requirements}
+
+The minimum engine versions needed to use \pkg{expl3} have been
+incremented a little:
+\begin{compactitemize}
+ \item \hologo{pdfTeX} v1.40
+ \item \hologo{XeTeX} v0.99992
+ \item \hologo{LuaTeX} v0.95
+ \item $\varepsilon$-(u)p\TeX{} mid-2012
+\end{compactitemize}
+
+The team have also worked with the \hologo{XeTeX} and (u)p\TeX{} developers to
+standardise the set of post-\eTeX{} utility primitives that are available: the
+so-called \enquote{\hologo{pdfTeX} utilities}. These are now available in all
+supported engines, and in time will all be \emph{required}. This primarily
+impacts \hologo{XeTeX}, which gained most of these primitives in the 2019
+\TeX{} Live cycle. (Examples are the random number primitives and expandable
+file data provision.) See \emph{\LaTeX{} News~31}~\cite{12:site-news}
+for more.
+
+\section{Documentation}
+
+\subsection{News}
+
+The \emph{\LaTeX3 News} files were until recently only used to create
+PDF files on the team website~\cite{12:site}. We have now
+integrated those into the \pkg{l3kernel} (\pkg{expl3} core)
+bundle. The news files cover all of \LaTeX3 files, as the core files
+are always available.
+
+\subsection{ChangeLog}
+
+Since the start of 2018, the team have commenced a comprehensive
+change log for each of the bundles which make up the \LaTeX3 code.
+These are simple Markdown text files, which means that they can be displayed
+formatted in web views.
+
+\section{Changes in \pkg{xparse}}
+
+A number of new features have been added to \pkg{xparse}. To allow
+handling of the fact that skipping spaces may be required only in
+some cases when searching for optional arguments, a new modifier
+\texttt{!} is available in argument specifiers. This causes
+\pkg{xparse} to \emph{require} that an optional argument follows
+immediately with no intervening spaces.
+
+There is a new argument type purely for environments: \texttt{b}-type
+for collecting a \cs{begin}\texttt{...}\cs{end} pair, i.e., collecting the body of
+an environment. This is similar in concept to the \pkg{environ} package,
+but is integrated directly into \pkg{xparse}.
+
+Finally, it is now possible to refer to one argument as the
+default for another optional one, for example
+\begin{verbatim}
+\NewDocumentCommand{\caption}{O{#2} m} ...
+\end{verbatim}
+
+\section{New experimental modules}
+
+A number of new experimental modules have been added within the
+\pkg{l3experimental} bundle:
+\begin{description}
+ \item[\pkg{l3benchmark}] Performance-testing system using the timing
+ function in modern \TeX{} engines
+ \item[\pkg{l3cctab}] Category code tables for all engines, not
+ just \hologo{LuaTeX}
+ \item[\pkg{l3color}] Color support, similar in interface to \pkg{xcolor}
+ \item[\pkg{l3draw}] Creation of drawings, inspired by \pkg{pgf}, but
+ using the \LaTeX3 FPU for calculations
+ \item[\pkg{l3pdf}] Support for PDF features such as compression,
+ hyperlinks, etc.
+ \item[\pkg{l3sys-shell}] Shell escape functions for file manipulation
+\end{description}
+
+\section{\pkg{l3build} changes}
+
+The \pkg{l3build} tool for testing and releasing \TeX{} packages
+has seen a number of incremental improvements. It is now available directly
+as a script in \TeX{} Live and MiK\TeX{}, meaning you can call it simply
+as
+\begin{verbatim}
+l3build <target>
+\end{verbatim}
+Accompanying this, we have added support for installing scripts and script
+\texttt{man} files.
+
+There is a new \texttt{upload} target that can take a zip file and send it to
+CTAN: you just have to fill in release information for \emph{this}
+upload at the prompts.
+
+Testing using PDF files rather than logs has been heavily revised:
+this is vital for work on PDF tagging.
+
+There is also better support for complex directory structures, including the
+ability to manually specify TDS location for all installed files. This
+is particularly targeted at packages with both generic and format-specific files
+to install.
+
+
+\begin{thebibliography}{9}
+
+\fontsize{9.9}{11.9}\selectfont
+
+
+\bibitem{12:site}
+ \emph{\LaTeX{} Project Website}.
+ \hfil\break\url{https://latex-project.org/}
+
+\bibitem{12:site-news}
+ \emph{\LaTeXe{} release newsletters on the \LaTeX{} Project Website}.
+ \url{https://latex-project.org/news/latex2e-news/}
+
+
+\end{thebibliography}
+
+\end{document}
diff --git a/macros/latex-dev/required/l3kernel/l3pdf.dtx b/macros/latex-dev/required/l3kernel/l3pdf.dtx
new file mode 100644
index 0000000000..b0b17f2690
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3pdf.dtx
@@ -0,0 +1,831 @@
+% \iffalse meta-comment
+%
+%% File: l3pdf.dtx
+%
+% Copyright(C) 2019-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3pdf} module\\ Core PDF support^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{Objects}
+%
+% \subsection{Named objects}
+%
+% An \meta{object} name should fully expand to tokens suitable for use in a
+% label-like context.
+%
+% \begin{function}[added = 2022-08-23]{\pdf_object_new:n}
+% \begin{syntax}
+% \cs{pdf_object_new:n} \Arg{object}
+% \end{syntax}
+% Declares \meta{object} as a PDF object. The object may be referenced
+% from this point on, and written later using \cs{pdf_object_write:nnn}.
+% \end{function}
+%
+% \begin{function}[added = 2022-08-23]
+% {\pdf_object_write:nnn, \pdf_object_write:nne}
+% \begin{syntax}
+% \cs{pdf_object_write:nnn} \Arg{object} \Arg{type} \Arg{content}
+% \end{syntax}
+% Writes the \meta{content} as content of the \meta{object}. Depending on the
+% \meta{type} declared for the object, the format required for the
+% \meta{data} will vary
+% \begin{itemize}
+% \item[\texttt{array}] A space-separated list of values
+% \item[\texttt{dict}] Key--value pairs in the form
+% \texttt{/\meta{key} \meta{value}}
+% \item[\texttt{fstream}] Two brace groups: \meta{file name} and
+% \meta{file content}
+% \item[\texttt{stream}] Two brace groups: \meta{attributes (dictionary)}
+% and \meta{stream contents}
+% \end{itemize}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2021-02-10]{\pdf_object_ref:n}
+% \begin{syntax}
+% \cs{pdf_object_ref:n} \Arg{object}
+% \end{syntax}
+% Inserts the appropriate information to reference the \meta{object}
+% in for example page resource allocation. If the \meta{object} does
+% not exist then the function expands to a reference to object zero;
+% no PDF indirect object ever has this number, so this is a marker for
+% error.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added = 2020-05-15]{\pdf_object_if_exist:n}
+% \begin{syntax}
+% \cs{pdf_object_if_exist_p:n} \Arg{object}
+% \cs{pdf_object_if_exist:nTF} \Arg{object} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether an object with name \Arg{object} has been defined.
+% \end{function}
+%
+% \subsection{Indexed objects}
+%
+% Objects can also be created using a pair of \meta{class} and \emph{index};
+% the \meta{class} argument should expand to character tokens, whilst the
+% \meta{index} is an \meta{int expr} and starts at $1$. For large
+% families of objects, this approach is more efficient than using
+% individual names.
+%
+% \begin{function}[added = 2024-04-01]{\pdf_object_new_indexed:nn}
+% \begin{syntax}
+% \cs{pdf_object_new_indexed:nn} \Arg{class} \Arg{index}
+% \end{syntax}
+% Declares a PDF object of \meta{class} and \meta{index}. The object may be
+% referenced from this point on, and written later using
+% \cs{pdf_object_write_indexed:nnnn}.
+% \end{function}
+%
+% \begin{function}[added = 2024-04-01]
+% {\pdf_object_write_indexed:nnnn, \pdf_object_write_indexed:nnne}
+% \begin{syntax}
+% \cs{pdf_object_write_indexed:nnnn} \Arg{class} \Arg{index} \Arg{type} \Arg{content}
+% \end{syntax}
+% Writes the \meta{content} as content of the object of \meta{class} and
+% \meta{index}. Depending on the
+% \meta{type} declared for the object, the format required for the
+% \meta{content} will vary
+% \begin{itemize}
+% \item[\texttt{array}] A space-separated list of values
+% \item[\texttt{dict}] Key--value pairs in the form
+% \texttt{/\meta{key} \meta{value}}
+% \item[\texttt{fstream}] Two brace groups: \meta{file name} and
+% \meta{file content}
+% \item[\texttt{stream}] Two brace groups: \meta{attributes (dictionary)}
+% and \meta{stream contents}
+% \end{itemize}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2024-04-01]{\pdf_object_ref_indexed:nn}
+% \begin{syntax}
+% \cs{pdf_object_ref_indexed:nn} \Arg{class} \Arg{index}
+% \end{syntax}
+% Inserts the appropriate information to reference the object of \meta{class}
+% and \meta{index} in for example page resource allocation. If the
+% \meta{class}/\meta{index} combination does
+% not exist then the function expands to a reference to object zero;
+% no PDF indirect object ever has this number, so this is a marker for
+% error.
+% \end{function}
+%
+% \subsection{General functions}
+%
+% \begin{function}[added = 2021-02-10]
+% {\pdf_object_unnamed_write:nn, \pdf_object_unnamed_write:ne}
+% \begin{syntax}
+% \cs{pdf_object_unnamed_write:nn} \Arg{type} \Arg{content}
+% \end{syntax}
+% Writes the \meta{content} as content of an anonymous object. Depending on the
+% \meta{type}, the format required for the \meta{data} will vary
+% \begin{itemize}
+% \item[\texttt{array}] A space-separated list of values
+% \item[\texttt{dict}] Key--value pairs in the form
+% \texttt{/\meta{key} \meta{value}}
+% \item[\texttt{fstream}] Two brace groups: \meta{attributes (dictionary)}
+% and \meta{file name}
+% \item[\texttt{stream}] Two brace groups: \meta{attributes (dictionary)}
+% and \meta{stream contents}
+% \end{itemize}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2021-02-10]{\pdf_object_ref_last:}
+% \begin{syntax}
+% \cs{pdf_object_ref_last:}
+% \end{syntax}
+% Inserts the appropriate information to reference the last \meta{object}
+% created. This is particularly useful for anonymous objects.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2021-02-10]{\pdf_pageobject_ref:n}
+% \begin{syntax}
+% \cs{pdf_pagobject_ref:n} \Arg{pageobject}
+% \end{syntax}
+% Inserts the appropriate information to reference the \meta{pageobject}.
+% \end{function}
+%
+% \section{Version}
+%
+% \begin{function}[pTF, EXP, added = 2021-02-10]{\pdf_version_compare:Nn}
+% \begin{syntax}
+% \cs{pdf_version_compare_p:Nn} \meta{comparator} \Arg{version}
+% \cs{pdf_version_compare:NnTF} \meta{comparator} \Arg{version} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Compares the version of the PDF being created with the \meta{version}
+% string specified, using the \meta{comparator}. Either the \meta{true code}
+% or \meta{false code} will be left in the output stream.
+% \end{function}
+%
+% \begin{function}[added = 2021-02-10]
+% {\pdf_version_gset:n, \pdf_version_min_gset:n}
+% \begin{syntax}
+% \cs{pdf_version_gset:n} \Arg{version}
+% \end{syntax}
+% Sets the \meta{version} of the PDF being created. The |min| version will
+% not alter the output version unless it is currently lower than the
+% \meta{version} requested.
+%
+% This function may only be used up to the point where the PDF file is
+% initialised. With dvips it sets \cs{pdf_version_major:} and \cs{pdf_version_minor:}
+% and allows to compare the values with \cs{pdf_version_compare:Nn}, but the
+% PDF version itself still has to be set with the command line option
+% |-dCompatibilityLevel| of |ps2pdf|.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2021-02-10]
+% {\pdf_version:, \pdf_version_major:, \pdf_version_minor:}
+% \begin{syntax}
+% \cs{pdf_version:}
+% \end{syntax}
+% Expands to the currently-active PDF version.
+% \end{function}
+%
+% \section{Page (media) size}
+%
+% \begin{function}[added = 2023-01-14]{\pdf_pagesize_gset:nn}
+% \begin{syntax}
+% \cs{pdf_pagesize_gset:nn} \Arg{width} \Arg{height}
+% \end{syntax}
+% Sets the page size (mediabox) of the PDF being created to the
+% \meta{width} and \meta{height}, both of which are \meta{dimexpr}.
+% \end{function}
+%
+% \section{Compression}
+%
+% \begin{function}[added = 2021-02-10]{\pdf_uncompress:}
+% \begin{syntax}
+% \cs{pdf_uncompress:}
+% \end{syntax}
+% Disables any compression of the PDF, where possible.
+%
+% This function may only be used up to the point where the PDF file is
+% initialised.
+% \end{function}
+%
+% \section{Destinations}
+%
+% Destinations are the places a link jumped too.
+% Unlike the name may suggest they don't described
+% an exact location in the PDF. Instead a destination contains a reference to
+% a page along with an instruction how to display this page.
+% The normally used \enquote{XYZ \textit{top left zoom}} for example instructs
+% the viewer to show the page with the given \textit{zoom} and
+% the top left corner at the \textit{top left} coordinates---which then gives
+% the impression that there is an anchor at this position.
+%
+% If an instruction takes a coordinate, it is calculated by the following
+% commands relative to the location the command is issued.
+% So to get a specific coordinate one has to move the command to the right place.
+%
+% \begin{function}[added = 2021-01-03]
+% {\pdf_destination:nn}
+% \begin{syntax}
+% \cs{pdf_destination:nn} \Arg{name} \Arg{type or integer}
+% \end{syntax}
+% This creates a destination. \Arg{type or integer} can be one of |fit|, |fith|,
+% |fitv|, |fitb|, |fitbh|, |fitbv|, |fitr|, |xyz|
+% or an integer representing a scale factor in percent.
+% |fitr| here gives only a lightweight version of |/FitR|:
+% The backend code defines |fitr| so that it will with pdf\LaTeX{} and
+% Lua\LaTeX{} use the coordinates of the surrounding box,
+% with \texttt{dvips} and \texttt{dvipdfmx} it falls back to |fit|.
+% For full control use \cs{pdf_destination:nnnn}.
+%
+% The keywords match to the PDF names as described in the following tabular.
+%
+% \medskip
+% \noindent\begin{tabular}{ll>{\raggedright\arraybackslash}p{6cm}}
+% \toprule
+% Keyword & PDF & Remarks \\ \midrule
+% |fit| & |/Fit|
+% & Fits the page to the window\\
+% |fith| & |/FitH| \textit{top}
+% & Fits the width of the page to the window \\
+% |fitv| & |/FitV| \textit{left}
+% & Fits the height of the page to the window \\
+% |fitb| & |/FitB|
+% & Fits the page bounding box to the window \\
+% |fitbh|& |/FitBH| \textit{top}
+% & Fits the width of the page bounding box to the window. \\
+% |fitbv|& |/FitBV| \textit{left}
+% & Fits the height of the page bounding box to the window. \\
+% |fitr| & |/FitR| \textit{left bottom right top}
+% & Fits the rectangle specified by the four coordinates to the window
+% (see above for the restrictions)\\
+% |xyz| & |/XYZ| \textit{left top} null
+% & Sets a coordinate but doesn't change the zoom.\\
+% \Arg{integer} & |/XYZ| \textit{left top zoom}
+% & Sets a coordinate and a zoom meaning \Arg{integer}\%.
+% \\\bottomrule
+% \end{tabular}
+%
+% \end{function}
+%
+% \begin{function}[added = 2021-01-17]
+% {\pdf_destination:nnnn}
+% \begin{syntax}
+% \cs{pdf_destination:nnnn} \Arg{name} \Arg{width} \Arg{height} \Arg{depth}
+% \end{syntax}
+% This creates a destination with |/FitR| type with the given dimensions relative
+% to the current location. The destination is in a box of size zero, but it doesn't
+% switch to horizontal mode.
+% \end{function}
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3pdf} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=pdf>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*tex>
+% \end{macrocode}
+%
+% \begin{variable}{\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_init_bool}
+% A boolean so we have some chance of avoiding setting things we are not
+% allowed to. As we are potentially early in the format, we have to work
+% a bit harder than ideal.
+% \begin{macrocode}
+\bool_new:N \g_@@_init_bool
+\bool_lazy_and:nnT
+ { \str_if_eq_p:Vn \fmtname { LaTeX2e } }
+ { \tl_if_exist_p:N \@expl@finalise@setup@@@@ }
+ {
+ \tl_gput_right:Nn \@expl@finalise@setup@@@@
+ {
+ \tl_gput_right:Nn \@kernel@after@begindocument
+ { \bool_gset_true:N \g_@@_init_bool }
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Compression}
+%
+% \begin{macro}{\pdf_uncompress:}
+% Simple to do.
+% \begin{macrocode}
+\cs_new_protected:Npn \pdf_uncompress:
+ {
+ \bool_if:NF \g_@@_init_bool
+ {
+ \@@_backend_compresslevel:n { 0 }
+ \@@_backend_compress_objects:n { \c_false_bool }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Objects}
+%
+% \begin{variable}{\g_@@_backend_object_int}
+% For returning object numbers.
+% \begin{macrocode}
+\int_new:N \g_@@_backend_object_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\pdf_object_new:n}
+% \begin{macro}
+% {\pdf_object_write:nnn, \pdf_object_write:nne, \pdf_object_write:nnx}
+% \begin{macro}{\pdf_object_ref:n}
+% \begin{macro}{\__kernel_pdf_object_id:n}
+% Simple to do: all objects create a constant |int| so it is not a
+% backend-specific name.
+% \begin{macrocode}
+\cs_new_protected:Npn \pdf_object_new:n #1
+ {
+ \@@_backend_object_new:
+ \@@_object_record:nN {#1} \g_@@_backend_object_int
+ }
+\cs_new_protected:Npn \pdf_object_write:nnn #1#2#3
+ {
+ \exp_args:Ne \@@_backend_object_write:nnn
+ { \@@_object_retrieve:n {#1} } {#2} {#3}
+ \bool_gset_true:N \g_@@_init_bool
+ }
+\cs_generate_variant:Nn \pdf_object_write:nnn { nne , nnx }
+\cs_new:Npn \pdf_object_ref:n #1
+ {
+ \exp_args:Ne \@@_backend_object_ref:n
+ { \@@_object_retrieve:n {#1} }
+ }
+\cs_new:Npn \__kernel_pdf_object_id:n #1
+ {
+ \exp_args:Ne \@@_backend_object_id:n
+ { \@@_object_retrieve:n {#1} }
+ }
+%</tex>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\@@_object_record:nN}
+% \begin{macro}[EXP]{\@@_object_retrieve:n}
+% \begin{macro}{ltx.pdf.object_id}
+% Object mappings are tracked in Lua for \LuaTeX{} as this makes retrieving
+% them much easier; as a result, there is a split in approaches. In Lua we
+% store values in a table indexed by name. The Lua function here is set up
+% to deal with both named and indexed objects: fits the Lua idiom well.
+% \begin{macrocode}
+%<*lua>
+
+local scan_int = token.scan_int
+local scan_string = token.scan_string
+local cprint = tex.cprint
+
+local @@_objects_named = {}
+local @@_objects_indexed = {}
+
+luacmd('@@_object_record:nN', function()
+ local name = scan_string()
+ local n = scan_int()
+ @@_objects_named[name] = n
+end,'protected','global')
+
+local function object_id(name,index)
+ if index then
+ return @@_objects_indexed[name][index] or 0
+ else
+ return @@_objects_named[name] or 0
+ end
+end
+
+luacmd('@@_object_retrieve:n', function()
+ local name = scan_string()
+ return cprint(12,tostring(object_id(name)))
+end,'global')
+
+ltx.pdf = ltx.pdf or {}
+ltx.pdf.object_id = object_id
+
+%</lua>
+% \end{macrocode}
+% Whereas in \TeX{} we use integer constants.
+% \begin{macrocode}
+%<*tex>
+\sys_if_engine_luatex:F
+ {
+ \cs_new_protected:Npn \@@_object_record:nN #1#2
+ {
+ \int_const:cn
+ { c_@@_object_ #1 _int } {#2}
+ }
+ \cs_new:Npn \@@_object_retrieve:n #1
+ {
+ \int_if_exist:cTF { c_@@_object_ #1 _int }
+ {
+ \int_use:c
+ { c_@@_object_ #1 _int }
+ }
+ { 0 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}[pTF,EXP]{\pdf_object_if_exist:n}
+% \begin{macrocode}
+\prg_new_conditional:Npnn \pdf_object_if_exist:n #1 { p , T , F , TF }
+ {
+ \int_compare:nNnTF { \@@_object_retrieve:n {#1} } = 0
+ \prg_return_false:
+ \prg_return_true:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\pdf_object_new_indexed:nn}
+% \begin{macro}{\pdf_object_write_indexed:nnnn, \pdf_object_write_indexed:nnne}
+% \begin{macro}[EXP]{\pdf_object_ref_indexed:nn}
+% \begin{macro}[EXP]{\__kernel_pdf_object_id_indexed:nn}
+% Again we split between the common code and the macro- or Lua-based
+% implementation. To make life easier for the Lua route, all of the
+% potential expressions are expanded to braced numbers.
+% \begin{macrocode}
+\cs_new_protected:Npn \pdf_object_new_indexed:nn #1#2
+ {
+ \@@_backend_object_new:
+ \@@_object_record:neN {#1}
+ { \int_eval:n {#2} } \g_@@_backend_object_int
+ }
+\cs_new_protected:Npn \pdf_object_write_indexed:nnnn #1#2#3#4
+ {
+ \exp_args:Ne \@@_backend_object_write:nnn
+ { \@@_object_retrieve:ne {#1} { \int_eval:n {#2} } } {#3} {#4}
+ \bool_gset_true:N \g_@@_init_bool
+ }
+\cs_generate_variant:Nn \pdf_object_write_indexed:nnnn { nnne }
+\cs_new:Npn \pdf_object_ref_indexed:nn #1#2
+ {
+ \exp_args:Ne \@@_backend_object_ref:n
+ { \@@_object_retrieve:ne {#1} { \int_eval:n {#2} } }
+ }
+\cs_new:Npn \__kernel_pdf_object_id_indexed:nn #1#2
+ {
+ \exp_args:Ne \@@_backend_object_id:n
+ { \@@_object_retrieve:ne {#1} { \int_eval:n {#2} } }
+ }
+%</tex>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\@@_object_record:nnN, \@@_object_record:neN}
+% \begin{macro}[EXP]{\@@_object_retrieve:nn}
+% \begin{macro}{\@@_object_record:NnN}
+% \begin{macro}[EXP]{\@@_object_retrieve:Nn}
+% Again we split for Lua: the same idea as above but with nested tables.
+% As we've arranged above that the \TeX{} code passes a braced number,
+% we can use |tonumber(scan_string())| rather than |scan_int()|
+% for the index.
+% \begin{macrocode}
+%<*lua>
+
+luacmd('@@_object_record:nnN', function()
+ local name = scan_string()
+ local index = tonumber(scan_string())
+ local n = scan_int()
+ @@_objects_indexed[name] = @@_objects_indexed[name] or {}
+ @@_objects_indexed[name][index] = n
+end,'protected','global')
+
+luacmd('@@_object_retrieve:nn', function()
+ local name = scan_string()
+ local index = tonumber(scan_string())
+ return cprint(12,tostring(object_id(name,index)))
+end,'global')
+
+%</lua>
+% \end{macrocode}
+% The non-Lua approach is to divide the range into blocks, and store in integer
+% arrays that can simulate dynamic assignment.
+% \begin{macrocode}
+%<*tex>
+\sys_if_engine_luatex:F
+ {
+ \cs_new_protected:Npn \@@_object_record:nnN #1#2#3
+ {
+ \use:e
+ {
+ \@@_object_record:NnN
+ \@@_object_index_split:nn {#1} {#2}
+ \exp_not:N #3
+ }
+ }
+ \cs_new_protected:Npn \@@_object_record:NnN #1#2#3
+ {
+ \intarray_if_exist:NF #1
+ { \intarray_new:Nn #1 \c_@@_object_block_size_int }
+ \intarray_gset:Nnn #1 {#2} #3
+ }
+ \cs_new:Npn \@@_object_retrieve:nn #1#2
+ {
+ \use:e
+ {
+ \exp_not:N \@@_object_retrieve:Nn
+ \@@_object_index_split:nn {#1} {#2}
+ }
+ }
+ \cs_new:Npn \@@_object_retrieve:Nn #1#2
+ { \intarray_item:Nn #1 {#2} }
+% \end{macrocode}
+% As we want blocks to start from one, and within the block for the top value
+% to be \enquote{in} the block, we do a little bit of manipulation. By shifting
+% down by one, we keep the values \enquote{in} the block, then we adjust the
+% block/index number to get back on track.
+% \begin{macrocode}
+ \cs_new:Npn \@@_object_index_split:nn #1#2
+ {
+ \exp_not:c
+ {
+ g_@@_object_ #1 _
+ \int_eval:n
+ {
+ \int_div_truncate:nn { #2 - 1 }
+ \c_@@_object_block_size_int + 1
+ }
+ _intarray
+ }
+ {
+ \int_eval:n
+ { \int_mod:nn { #2 - 1 } \c_@@_object_block_size_int + 1 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{variable}{\c_@@_object_block_size_int}
+% Sets the block size used for managing indexed objects.
+% \begin{macrocode}
+ \int_const:Nn \c_@@_object_block_size_int { 10000 }
+ }
+% \end{macrocode}
+% \end{variable}
+% \begin{macro}{\@@_object_record:neN}
+% \begin{macro}[EXP]{\@@_object_retrieve:ne}
+% Common variants.
+% \begin{macrocode}
+\cs_generate_variant:Nn \@@_object_record:nnN { ne }
+\cs_generate_variant:Nn \@@_object_retrieve:nn { ne }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \pdf_object_unnamed_write:nn, \pdf_object_unnamed_write:ne,
+% \pdf_object_unnamed_write:nx
+% }
+% No tracking needed here.
+% \begin{macrocode}
+\cs_new_protected:Npn \pdf_object_unnamed_write:nn #1#2
+ {
+ \exp_args:Ne \@@_backend_object_now:nn {#1} {#2}
+ \bool_gset_true:N \g_@@_init_bool
+ }
+\cs_generate_variant:Nn \pdf_object_unnamed_write:nn { ne , nx }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\pdf_object_ref_last:}
+% A one-step wrapper for consistency.
+% \begin{macrocode}
+\cs_new:Npn \pdf_object_ref_last: { \@@_backend_object_last: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\pdf_pageobject_ref:n}
+% \begin{macrocode}
+\cs_new:Npn \pdf_pageobject_ref:n #1
+ { \@@_backend_pageobject_ref:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Version}
+%
+% \begin{macro}[pTF,EXP]{\pdf_version_compare:Nn}
+% \begin{macro}
+% {
+% @@_version_compare_=:w ,
+% @@_version_compare_<:w ,
+% @@_version_compare_>:w
+% }
+% To compare version, we need to split the given value then deal with both
+% major and minor version
+% \begin{macrocode}
+\prg_new_conditional:Npnn \pdf_version_compare:Nn #1#2 { p , T , F , TF }
+ { \use:c { @@_version_compare_ #1 :w } #2 . . \s_@@_stop }
+\cs_new:cpn { @@_version_compare_=:w } #1 . #2 . #3 \s_@@_stop
+ {
+ \bool_lazy_and:nnTF
+ { \int_compare_p:nNn \@@_backend_version_major: = {#1} }
+ { \int_compare_p:nNn \@@_backend_version_minor: = {#2} }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\cs_new:cpn { @@_version_compare_<:w } #1 . #2 . #3 \s_@@_stop
+ {
+ \bool_lazy_or:nnTF
+ { \int_compare_p:nNn \@@_backend_version_major: < {#1} }
+ {
+ \bool_lazy_and_p:nn
+ { \int_compare_p:nNn \@@_backend_version_major: = {#1} }
+ { \int_compare_p:nNn \@@_backend_version_minor: < {#2} }
+ }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\cs_new:cpn { @@_version_compare_>:w } #1 . #2 . #3 \s_@@_stop
+ {
+ \bool_lazy_or:nnTF
+ { \int_compare_p:nNn \@@_backend_version_major: > {#1} }
+ {
+ \bool_lazy_and_p:nn
+ { \int_compare_p:nNn \@@_backend_version_major: = {#1} }
+ { \int_compare_p:nNn \@@_backend_version_minor: > {#2} }
+ }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\pdf_version_gset:n, \pdf_version_min_gset:n}
+% \begin{macro}{\@@_version_gset:w}
+% Split the version and set.
+% \begin{macrocode}
+\cs_new_protected:Npn \pdf_version_gset:n #1
+ { \@@_version_gset:w #1 . . \s_@@_stop }
+\cs_new_protected:Npn \pdf_version_min_gset:n #1
+ {
+ \pdf_version_compare:NnT < {#1}
+ { \@@_version_gset:w #1 . . \s_@@_stop }
+ }
+\cs_new_protected:Npn \@@_version_gset:w #1 . #2 . #3\s_@@_stop
+ {
+ \bool_if:NF \g_@@_init_bool
+ {
+ \@@_backend_version_major_gset:n {#1}
+ \@@_backend_version_minor_gset:n {#2}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\pdf_version:, \pdf_version_major:, \pdf_version_minor:}
+% Wrappers.
+% \begin{macrocode}
+\cs_new:Npn \pdf_version:
+ { \@@_backend_version_major: . \@@_backend_version_minor: }
+\cs_new:Npn \pdf_version_major: { \@@_backend_version_major: }
+\cs_new:Npn \pdf_version_minor: { \@@_backend_version_minor: }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Page size}
+%
+% \begin{macro}{\pdf_pagesize_gset:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \pdf_pagesize_gset:nn #1#2
+ { \@@_backend_pagesize_gset:nn {#1} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Destinations}
+%
+% \begin{macro}{\pdf_destination:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \pdf_destination:nn #1#2
+ { \@@_backend_destination:nn {#1} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\pdf_destination:nnnn}
+% \begin{macrocode}
+\cs_new_protected:Npn \pdf_destination:nnnn #1#2#3#4
+ {
+ \hbox_to_zero:n
+ { \@@_backend_destination:nnnn {#1} {#2} {#3} {#4} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{PDF Page size (media box)}
+%
+% Everything here is delayed to the start of the document so that the
+% backend will definitely be loaded.
+% \begin{macrocode}
+\cs_if_exist:NT \@kernel@before@begindocument
+ {
+ \tl_gput_right:Nn \@kernel@before@begindocument
+ {
+ \bool_lazy_all:nT
+ {
+ { \cs_if_exist_p:N \stockheight }
+ { \cs_if_exist_p:N \stockwidth }
+ { \cs_if_exist_p:N \IfDocumentMetadataTF }
+ { \IfDocumentMetadataTF { \c_true_bool } { \c_false_bool } }
+ { \int_compare_p:nNn \tex_mag:D = { 1000 } }
+ }
+ {
+ \bool_lazy_and:nnTF
+ { \dim_compare_p:nNn \stockheight > { 0pt } }
+ { \dim_compare_p:nNn \stockwidth > { 0pt } }
+ {
+ \@@_backend_pagesize_gset:nn
+ \stockwidth \stockheight
+ }
+ {
+ \bool_lazy_or:nnF
+ { \dim_compare_p:nNn \stockheight < { 0pt } }
+ { \dim_compare_p:nNn \stockwidth < { 0pt } }
+ {
+ \bool_lazy_and:nnT
+ { \dim_compare_p:nNn \paperheight > { 0pt } }
+ { \dim_compare_p:nNn \paperwidth > { 0pt } }
+ {
+ \@@_backend_pagesize_gset:nn
+ \paperwidth \paperheight
+ }
+ }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</tex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3prefixes.csv b/macros/latex-dev/required/l3kernel/l3prefixes.csv
new file mode 100644
index 0000000000..54fb41bdeb
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3prefixes.csv
@@ -0,0 +1,296 @@
+Prefix,Module or package,Registrant,Homepage,Source repository,Issue tracker,First registered,Last update,Notes
+ENdiagram,endiagram,Clemens Niederberger,https://bitbucket.org/cgnieder/endiagram/,git@bitbucket.org:cgnieder/endiagram.git,https://bitbucket.org/cgnieder/endiagram/issues,2013-03-16,2013-03-16,
+GS,gs1,Markus Kohm,,,,2013-03-16,2013-03-16,
+MOdiagram,modiagram,Clemens Niederberger,https://bitbucket.org/cgnieder/modiagram/,git@bitbucket.org:cgnieder/modiagram.git,https://bitbucket.org/cgnieder/modiagram/issues,2013-03-16,2013-03-16,
+UFca,citeall,Ulrike Fischer,,,,2015-04-09,2016-02-26,
+acro,acro,Clemens Niederberger,https://github.com/cgnieder/acro/,https://github.com/cgnieder/acro.git,https://github.com/cgnieder/acro/issues,2013-03-16,2020-04-14,
+affiliations,langsci-affiliations,Felix Kopecky,https://ctan.org/pkg/langsci-affiliations,https://github.com/langsci/langsci-affiliations,https://github.com/langsci/langsci-affiliations/issues,2021-02-18,2021-02-18,
+akshar,akshar,Vu Van Dung,https://github.com/joulev/akshar,https://github.com/joulev/akshar.git,https://github.com/joulev/akshar/issues,2020-05-27,2020-05-27,
+algobox,algobox,Julien Rivaud,,,,2018-06-13,2018-06-13,
+alignment,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+alloc,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,Internal only but reserved
+ampersand,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+apfs,apfontspec,Qing Lee,https://github.com/CTeX-org/apfontspec,https://github.com/CTeX-org/apfontspec.git,https://github.com/CTeX-org/apfontspec/issues,2020-05-17,2020-05-17,
+arch,archaeologie,Lukas C. Bossert,http://www.biblatex-archaeologie.de,https://github.com/LukasCBossert/biblatex-archaeologie.git,https://github.com/LukasCBossert/biblatex-archaeologie/issues,2017-03-24,2017-03-24,
+array,hobby,Andrew Stacey,https://github.com/loopspace/hobby,https://github.com/loopspace/hobby,https://github.com/loopspace/hobby/issues,2013-03-16,2020-10-29,
+arsenal,arsenal,Boris Veytsman,https://github.com/borisveytsman/arsenal,https://github.com/borisveytsman/arsenal,https://github.com/borisveytsman/arsenal/issues,2023-09-04,2023-09-04,
+atsign,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+avm,langsci-avm,Felix Kopecky,https://ctan.org/pkg/langsci-avm,https://github.com/langsci/langsci-avm,https://github.com/langsci/langsci-avm/issues,2020-03-11,2020-03-11,
+babellatin,babel-latin,Keno Wehr,https://ctan.org/pkg/babel-latin,https://github.com/wehro/babel-latin,https://github.com/wehro/babel-latin/issues,2021-08-23,2021-08-23,
+backend,l3backend,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2019-06-04,2019-06-04,
+backslash,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+bearwear,bearwear,Ulrike Fischer,https://github.com/u-fischer/bearwear,https://github.com/u-fischer/bearwear,https://github.com/u-fischer/bearwear/issues,2020-04-24,2020-04-24,
+beuron,beuron,Keno Wehr,https://ctan.org/pkg/beuron,,,2021-08-23,2021-08-23,
+bitset,l3kernel,The LaTeX3 Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2020-12-26,2020-12-26,
+block,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2023-10-17,2023-10-17,
+bool,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+box,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+bxjh,BXjaholiday,Takuto Asakura,https://github.com/wtsnjp/BXjaholiday,https://github.com/wtsnjp/BXjaholiday.git,https://github.com/wtsnjp/BXjaholiday/issues,2018-02-02,2019-02-02,
+cascade,cascade,F. Pantigny,,,,2020-07-21,2020-07-21,
+catcode,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+cctab,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28,
+cellprops,cellprops,Julien Rivaud,,,,2018-06-13,2018-06-13,
+chaos,"chaos,schleuderpackung",Marei Peischl,https://ds.ccc.de/,,,2021-05-28,2021-05-28,
+char,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+chemformula,chemformula,Clemens Niederberger,https://github.com/cgnieder/chemformula/,https://github.com/cgnieder/chemformula.git,https://github.com/cgnieder/chemformula/issues,2013-03-16,2020-04-14,
+chemmacros,chemmacros,Clemens Niederberger,https://github.com/cgnieder/chemmacros/,https://github.com/cgnieder/chemmacros.git,https://github.com/cgnieder/chemmacros/issues,2013-03-16,2020-04-14,
+chemnum,chemnum,Clemens Niederberger,https://github.com/cgnieder/chemnum/,https://github.com/cgnieder/chemnum.git,https://github.com/cgnieder/chemnum/issues,2013-03-16,2020-04-14,
+chk,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,Currently internal-only but reserved
+circumflex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+classics,classics,Eduardo C. Lourenço de Lima,,,,2013-03-16,2013-03-16,
+clist,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+cmd,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-01-20,2021-03-03,
+code,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23,
+codedesc,codedescribe,Alceu Frigeri,https://github.com/alceu-frigeri/codedescribe,https://github.com/alceu-frigeri/codedescribe,https://github.com/alceu-frigeri/codedescribe/issues,2023-05-15,2023-05-15,
+codedoc,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,Somewhat experimental: may change
+codehigh,codehigh,Jianrui Lyu,https://github.com/lvjr/codehigh,https://github.com/lvjr/codehigh.git,https://github.com/lvjr/codehigh/issues,2022-04-02,2022-04-02,
+codelist,codelisting,Alceu Frigeri,https://github.com/alceu-frigeri/codedescribe,https://github.com/alceu-frigeri/codedescribe,https://github.com/alceu-frigeri/codedescribe/issues,2023-05-15,2023-05-15,
+codepoint,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+coffin,"l3kernel,xcoffins",The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+colon,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+color,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+conteq,conteq,Joachim Breitner,https://github.com/nomeata/conteq,https://github.com/nomeata/conteq.git,https://github.com/nomeata/conteq/issues,2013-05-26,2013-05-27,
+cookingunits,cooking-units,Ben Vitecek,https://github.com/Vidabe/cooking-units,https://github.com/Vidabe/cooking-units.git,https://github.com/Vidabe/cooking-units/issues,2018-09-26,2018-09-26,
+cs,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+csl,citation-style-language,Zeping Lee,https://github.com/zepinglee/citeproc-lua,https://github.com/zepinglee/citeproc-lua.git,https://github.com/zepinglee/citeproc-lua/issues,2022-05-09,2022-05-09,
+csvsim,csvsimple,Thomas F. Sturm,https://github.com/T-F-S/csvsimple,https://github.com/T-F-S/csvsimple.git,https://github.com/T-F-S/csvsimple/issues,2020-02-19,2020-02-19,
+ctex,ctex,Qing Lee,https://github.com/CTeX-org/ctex-kit,https://github.com/CTeX-org/ctex-kit.git,https://github.com/CTeX-org/ctex-kit/issues,2014-03-08,2014-03-08,
+ctuthesis,ctuthesis,Tom Hejda,https://github.com/tohecz/ctuthesis,https://github.com/tohecz/ctuthesis.git,https://github.com/tohecz/ctuthesis/issues,2015-07-26,2015-07-26,
+debug,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2017-07-15,2017-07-15,
+denisbdoc,denisbdoc,Denis Bitouzé,https://github.com/dbitouze/denisbdoc,git@github.com:dbitouze/denisbdoc.git,,2020-05-13,2020-05-13,
+deriv,derivative,Simon Jensen,,,,2019-07-24,2019-07-24,
+didec,didec,Thomas F. Sturm,https://github.com/T-F-S/didec,https://github.com/T-F-S/didec.git,https://github.com/T-F-S/didec/issues,2024-02-02,2024-02-02,
+diffcoeff,diffcoeff,Andrew Parsloe,,,,2019-08-26,2019-08-26,
+dim,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+document,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2019-06-02,2019-06-02,
+dollar,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+driver,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+dry,dry,Michiel Helvensteijn,,,,2013-01-18,2013-01-18,
+ducksay,ducksay,Jonathan P. Spratte,https://github.com/Skillmon/ltx_ducksay,git@github.com:Skillmon/ltx_ducksay.git,https://github.com/Skillmon/ltx_ducksay/issues,2019-06-07,2019-06-07,
+duckuments,duckuments,Jonathan P. Spratte,https://github.com/Skillmon/ltx_duckuments,git@github.com:Skillmon/ltx_duckuments.git,https://github.com/Skillmon/ltx_duckuments/issues,2019-06-07,2019-06-07,
+e,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+else,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28,
+emoji,emoji,Xiangdong Zeng,https://github.com/stone-zeng/latex-emoji,https://github.com/stone-zeng/latex-emoji.git,https://github.com/stone-zeng/latex-emoji/issues,2020-03-08,2020-03-08,
+emojicite,emojicite,Leon Sixt,https://github.com/berleon/emojicite,https://github.com/berleon/emojicite.git,https://github.com/berleon/emojicite/issues/,2020-04-14,2020-04-20,
+empty,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+enotez,enotez,Clemens Niederberger,https://github.com/cgnieder/enotez/,https://github.com/cgnieder/enotez.git,https://github.com/cgnieder/enotez/issues,2013-03-16,2020-04-14,
+etex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+etl,etl,Jonathan P. Spratte,https://github.com/Skillmon/ltx_etl,git@github.com:Skillmon/ltx_etl.git,https://github.com/Skillmon/ltx_etl/issues,2021-08-16,2021-08-16,
+exp,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+expl,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+exsheets,exsheets,Clemens Niederberger,https://bitbucket.org/cgnieder/exsheets/,git@bitbucket.org:cgnieder/exsheets.git,https://bitbucket.org/cgnieder/exsheets/issues,2013-03-16,2013-03-16,
+extblx,biblatex-ext,Moritz Wemheuer,https://github.com/moewew/biblatex-ext/,https://github.com/moewew/biblatex-ext.git,https://github.com/moewew/biblatex-ext/issues,2020-02-09,2020-02-09,
+exwf,exwrapfig,Takuto Asakura,https://github.com/wtsnjp/exwrapfig,https://github.com/wtsnjp/exwrapfig.git,https://github.com/wtsnjp/exwrapfig/issues,2018-06-07,2018-06-07,
+false,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23,
+fdu,fduthesis,Xiangdong Zeng,https://github.com/stone-zeng/fduthesis,https://github.com/stone-zeng/fduthesis.git,https://github.com/stone-zeng/fduthesis/issues,2018-06-14,2020-03-08,
+fdudoc,fduthesis,Xiangdong Zeng,https://github.com/stone-zeng/fduthesis,https://github.com/stone-zeng/fduthesis.git,https://github.com/stone-zeng/fduthesis/issues,2018-06-14,2020-03-08,
+fdulogo,fduthesis,Xiangdong Zeng,https://github.com/stone-zeng/fduthesis,https://github.com/stone-zeng/fduthesis.git,https://github.com/stone-zeng/fduthesis/issues,2018-06-14,2020-03-08,
+fi,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28,
+file,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+filehook,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2020-10-01,2021-03-03,
+fingering,recorder-fingering,Alan Munn,https://github.com/amunn/recorder-fingering,https://github.com/amunn/recorder-fingering,https://github.com/amunn/recorder-fingering/issues,2023-02-17,2023-02-17,
+flag,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2017-02-13,
+fltr,newlfm,Paul Thomson,,,,2013-01-29,2013-01-29,
+fmdug,dashundergaps,Frank Mittelbach,https://www.latex-project.org/,https://github.com/FrankMittelbach/fmitex-dashundergaps.git,https://github.com/FrankMittelbach/fmitex-dashundergaps/issues,2018-06-24,2021-10-11,
+fmuft,unicodefonttable,Frank Mittelbach,https://www.latex-project.org/,https://github.com/FrankMittelbach/fmitex-unicodefonttable.git,https://github.com/FrankMittelbach/fmitex-unicodefonttable/issues,2020-02-17,2021-10-11,
+fmwao,widows-and-orphans,Frank Mittelbach,https://www.latex-project.org/,https://github.com/FrankMittelbach/fmitex-widows-and-orphans.git,https://github.com/FrankMittelbach/fmitex-widows-and-orphans/issues,2018-09-26,2018-09-26,
+fnote,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2023-10-17,2023-10-17,
+fnpct,fnpct,Clemens Niederberger,https://github.com/cgnieder/fnpct/,https://github.com/cgnieder/fnpct.git,https://github.com/cgnieder/fnpct/issues,2013-03-16,2020-04-14,
+fontsizes,fontsizes,Julien Rivaud,,,,,2018-06-13,
+fontspec,fontspec,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/fontspec.git,https://github.com/latex3/fontspec/issues,2013-03-16,2024-02-15,
+fp,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+fun,functional,Jianrui Lyu,https://github.com/lvjr/functional,https://github.com/lvjr/functional.git,https://github.com/lvjr/functional/issues,2022-04-02,2022-04-02,
+galley,l3galley,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+gatherenum,gatherenum,Julien Rivaud,,,,2018-06-13,2018-06-14,
+getree,genealogytree,Thomas F. Sturm,https://github.com/T-F-S/genealogytree,https://github.com/T-F-S/genealogytree.git,https://github.com/T-F-S/genealogytree/issues,2020-02-19,2020-02-19,
+ghsystem,ghsystem,Clemens Niederberger,https://github.com/cgnieder/ghsystem/,https://github.com/cgnieder/ghsystem.git,https://github.com/cgnieder/ghsystem/issues,2013-03-16,2020-04-14,
+graph,lt3graph,Michiel Helvensteijn,,,,2014-02-05,2014-02-05,
+group,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+gtl,gtl,Bruno Le Floch,https://github.com/blefloch/latex-gtl,https://github.com/blefloch/latex-gtl.git,https://github.com/blefloch/latex-gtl/issues,2015-09-22,2015-09-22,
+gzt,gzt,Denis Bitouzé,https://github.com/dbitouze/gzt,git@github.com:dbitouze/gzt.git,,2020-05-13,2020-05-13,
+hash,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+hbox,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+hcoffin,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28,
+hobete,hobete,Tobias Görlach,http://www.disk0s1.de,,,2012-11-07,2012-11-07,
+hook,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2019-06-03,2021-03-03,
+hyp,hyperref,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/hyperref.git,https://github.com/latex3/hyperref/issues,2020-11-27,2020-11-27,
+if,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+incgra,incgraph,Thomas F. Sturm,https://github.com/T-F-S/incgraph,https://github.com/T-F-S/incgraph.git,https://github.com/T-F-S/incgraph/issues,2021-10-11,2021-10-11,
+inf,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+initex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23,
+insert,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28,
+int,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+intarray,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-04-06,2018-04-06,
+ior,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+iot,iot,Island of TeX,https://islandoftex.gitlab.io,https://gitlab.com/islandoftex/texmf,https://gitlab.com/groups/islandoftex/texmf/-/issues,2023-07-18,2023-07-18,
+iow,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+iwonamath,iwonamath,Boris Veytsman,https://github.com/borisveytsman/iwonamath,https://github.com/borisveytsman/iwonamath,https://github.com/borisveytsman/iwonamath/issues,2023-09-04,2023-09-04,
+jiazhu,jiazhu,Qing Lee,https://github.com/CTeX-org/ctex-kit,https://github.com/CTeX-org/ctex-kit.git,https://github.com/CTeX-org/ctex-kit/issues,2020-05-17,2020-05-17,
+job,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23,
+kernel,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+keys,"l3kernel,l3keys2e,ltkeys",The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+keyval,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+kgl,kantlipsum,Enrico Gregorio,,,,2013-03-16,2013-03-16,
+kivitendo,"kiviletter, kivitables",Marei Peischl for Kivitendo,https://www.kivitendo.de/,https://github.com/kivitendo/kivitendo-erp,https://forum.kivitendo.de/,2021-05-28,2021-05-28,
+langsci,langscibook,Language Science Press,https://langsci-press.org,https://github.com/langsci/langscibook,https://github.com/langsci/langscibook/issues,2021-07-20,2021-07-21,
+left,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+lltxmath,lualatex-math,Philipp Stephani,https://github.com/phst/lualatex-math,https://github.com/phst/lualatex-math.git,https://github.com/phst/lualatex-math/issues,2012-11-07,2012-11-07,
+log,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+lua,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+luabridge,lt3luabridge,Vít Novotný,https://ctan.org/pkg/lt3luabridge,https://github.com/witiko/lt3luabridge.git,https://github.com/witiko/lt3luabridge/issues,2022-06-25,2022-06-25,
+luatex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+lwc,lua-widow-control,Max Chernoff,https://github.com/gucci-on-fleek/lua-widow-control,https://github.com/gucci-on-fleek/lua-widow-control.git,https://github.com/gucci-on-fleek/lua-widow-control/issues,2022-02-24,2022-02-24,
+mark,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+markdown,markdown,Vít Novotný,https://ctan.org/pkg/markdown,https://github.com/witiko/markdown.git,https://github.com/witiko/markdown/issues,2021-09-08,2021-09-08,
+marks,l3kernel/xmarks,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2020-02-17,2020-02-17,
+marks,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-03-03,2021-03-03,
+math,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+mathcolor,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2022-01-20,2022-01-20,
+max,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+mcrule,multicolrule,Karl Hagen,https://github.com/polysyllabic/multicolrule,https://github.com/polysyllabic/multicolrule.git,https://github.com/polysyllabic/multicolrule/issues,2018-12-24,2018-12-24,
+mermap,mercatormap,Thomas F. Sturm,https://github.com/T-F-S/mercatormap,https://github.com/T-F-S/mercatormap.git,https://github.com/T-F-S/mercatormap/issues,2020-02-19,2020-02-19,
+meta,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2022-01-20,2022-01-20,
+metrix,metrix,Tobias Weh,https://github.com/tweh/metrix,git@github.com:tweh/metrix.git,https://github.com/tweh/metrix/issues,2020-10-31,2019-10-09,
+mhchem,mhchem,Martin Hensel,,,,2014-02-05,2014-02-05,
+minibox,minibox,Will Robertson,,https://github.com/wspr/will2e.git,https://github.com/wspr/will2e/issues,2020-04-24,2020-04-24,
+minus,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+mix,media9,Alexander Grahn,,https://gitlab.com/agrahn/media9,https://gitlab.com/agrahn/media9/issues,2013-01-18,2020-04-15,
+mode,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+morewrites,morewrites,Bruno Le Floch,https://github.com/blefloch/latex-morewrites,https://github.com/blefloch/latex-morewrites.git,https://github.com/blefloch/latex-morewrites/issues,2013-03-16,2015-09-22,
+msg,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+msvg,media4svg,Alexander Grahn,,https://gitlab.com/agrahn/media4svg,https://gitlab.com/agrahn/media4svg/issues,2020-04-15,2020-04-15,
+muskip,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+namedef,namedef,Phelype Oleinik,https://github.com/PhelypeOleinik/namedef,https://github.com/PhelypeOleinik/namedef.git,https://github.com/PhelypeOleinik/namedef/issues,2020-06-22,2020-06-22,
+nan,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+nicematrix,nicematrix,François Pantigny,,,,2019-12-19,2019-12-19,
+nil,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+ninecolors,ninecolors,Jianrui Lyu,https://github.com/lvjr/ninecolors,https://github.com/lvjr/ninecolors.git,https://github.com/lvjr/ninecolors/issues,2022-04-02,2022-04-02,
+nmc,numerica,Andrew Parsloe,,,,2021-06-30,2021-06-30,
+no,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+notestobib,notes2bib,Joseph Wright,https://github.com/josephwright/notes2bib,https://github.com/josephwright/notes2bib.git,https://github.com/josephwright/notes2bib/issues,2012-11-07,2012-11-07,
+novalue,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+nwejm,nwejm,Denis Bitouzé,https://github.com/dbitouze/nwejm,git@github.com:dbitouze/nwejm.git,,2020-05-13,2020-05-13,
+ocgbase,ocgx2,Alexander Grahn,,https://gitlab.com/agrahn/ocgx2,https://gitlab.com/agrahn/ocgx2/issues,2016-02-26,2020-04-15,
+ocgxii,ocgx2,Alexander Grahn,,https://gitlab.com/agrahn/ocgx2,https://gitlab.com/agrahn/ocgx2/issues,2016-02-26,2020-04-15,
+one,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+or,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28,
+other,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23,
+overleaf,overleaf,Overleaf,https://www.overleaf.com/about,,support+tex-dev@overleaf.com,2020-05-27,2020-05-27,
+para,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-03-03,2021-03-03,
+parameter,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+pbs,media9,Alexander Grahn,,https://gitlab.com/agrahn/media9,https://gitlab.com/agrahn/media9/issues,2016-02-26,2020-04-15,
+pdf,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2019-06-02,2019-06-02,
+pdfannot,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-02-23,2021-02-23,
+pdffile,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-02-23,2021-02-23,
+pdfmanagement,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2020-11-27,2020-11-27,
+pdfmeta,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-02-23,2021-02-23,
+pdfoverlay,pdfoverlay,David Purton,https://github.com/dcpurton/pdfoverlay,https://github.com/dcpurton/pdfoverlay.git,https://github.com/dcpurton/pdfoverlay/issues,2020-06-22,2020-06-22,
+pdftex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+pdfxform,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-02-23,2021-02-23,
+peek,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+percent,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+pgf,pgf,The PGF/TikZ Team,https://pgf-tikz.github.io,https://github.com/pgf-tikz/pgf,https://github.com/pgf-tikz/pgf/issues,2020-07-03,2020-07-03,
+pgfmxfp,pgfmath-xfp,Jonathan P. Spratte,https://github.com/Skillmon/ltx_pgfmath-xfp,https://github.com/Skillmon/ltx_pgfmath-xfp,https://github.com/Skillmon/ltx_pgfmath-xfp/issues,2021-05-20,2021-05-20,
+phone,phonenumbers,Keno Wehr,https://ctan.org/pkg/phonenumbers,https://github.com/wehro/phonenumbers,https://github.com/wehro/phonenumbers/issues,2021-08-23,2021-08-23,
+pi,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+piton,piton,François Pantigny,,,,29/09/2022,29/09/2022,
+pkgploader,pkgploader,Michiel Helvensteijn,,,,2014-02-05,2014-02-05,
+platex,platex,Japanese TeX Development Community,https://github.com/texjporg/platex,https://github.com/texjporg/platex.git,https://github.com/texjporg/platex/issues,2020-09-30,2020-09-30,
+polyglossia,polyglossia,Arthur Reutenauer,https://www.polyglossia.org/,https://github.com/reutenauer/polyglossia,https://github.com/reutenauer/polyglossia/issues,2019-09-03,,
+postnotes,postnotes,gusbrs,https://github.com/gusbrs/postnotes,https://github.com/gusbrs/postnotes.git,https://github.com/gusbrs/postnotes/issues,2022-04-23,2022-04-23,
+prelim,prelim2e,Marei Peischl,https://github.com/TeXhackse/prelim2e,https://github.com/TeXhackse/prelim2e.git,https://github.com/TeXhackse/prelim2e/issues,2020-11-24,2020-11-24,
+prg,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+primargs,morewrites,Bruno Le Floch,https://github.com/blefloch/latex-morewrites,https://github.com/blefloch/latex-morewrites.git,https://github.com/blefloch/latex-morewrites/issues,2013-03-16,2015-09-22,
+prop,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+property,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-01-20,2021-03-03,
+pseudo,pseudo,Magnus Lie Hetland,https://github.com/mlhetland/pseudo.sty,https://github.com/mlhetland/pseudo.sty.git,https://github.com/mlhetland/pseudo.sty/issues,2019-06-24,2019-06-24,
+ptex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2015-07-28,2015-07-28,
+ptxcd,ptxcd,Marei Peischl,,,,2020-07-27,2020-07-27,Used for specific corporate design templates
+qrbill,qrbill,Marei Peischl,https://github.com/peiTeX/qrbill,https://github.com/peiTeX/qrbill.git,https://github.com/peiTeX/qrbill/issues,2020-06-27,2020-06-27,
+quark,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+rainbow,beamertheme-rainbow,samcarter,https://github.com/samcarter/beamertheme-rainbow,https://github.com/samcarter/beamertheme-rainbow,https://github.com/samcarter/beamertheme-rainbow/issues,2023-07-04,2023-07-04,
+randomwalk,randomwalk,Bruno Le Floch,https://github.com/blefloch/latex-randomwalk,https://github.com/blefloch/latex-randomwalk.git,https://github.com/blefloch/latex-randomwalk/issues,2013-03-16,2015-09-22,
+rawobjects,rawobjects,Paolo De Donato,https://github.com/Loara/lt3rawobjects,https://github.com/Loara/lt3rawobjects/lt3rawobjects.git,https://github.com/Loara/lt3rawobjects/issues,2022-07-19,2022-07-19,
+recursion,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+ref,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2020-12-24,2020-12-24,
+regex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2018-04-06,
+reverse,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28,
+right,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+rivbook,rivbook,Julien Rivaud,,,,2018-06-13,2018-06-14,
+rivmath,rivmath,Julien Rivaud,,,,2018-06-13,2018-06-13,
+sanuml,sanitize-umlaut,Thomas F. Sturm,https://github.com/T-F-S/sanitize-umlaut,https://github.com/T-F-S/sanitize-umlaut.git,https://github.com/T-F-S/sanitize-umlaut/issues,2022-07-19,2022-07-19,
+scan,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+schulma,schulmathematik,Keno Wehr,https://ctan.org/pkg/schulmathematik,,,2021-08-23,2021-08-23,
+scontents,scontents,Pablo González,https://github.com/pablgonz/scontents,git@github.com:pablgonz/scontents.git,https://github.com/pablgonz/scontents/issues,2019-12-05,2019-12-05,
+scripture,scripture,David Purton,https://github.com/dcpurton/scripture,https://github.com/dcpurton/scripture.git,https://github.com/dcpurton/scripture/issues,2022-07-27,2022-07-27,
+sdaps,sdaps,Benjamin Berg,https://sdaps.org,https://github.com/sdaps/sdaps-class.git,https://github.com/sdaps/sdaps-class/issues,2020-02-17,2020-02-17,
+seq,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+shipout,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2020-10-01,2021-03-03,
+silly,sillypage,Paulo Cereda,https://github.com/cereda/sillypage,https://github.com/cereda/sillypage.git,https://github.com/cereda/sillypage/issues,2022-02-01,2022-02-01,
+siunitx,siunitx,Joseph Wright,https://github.com/josephwright/siunitx,https://github.com/josephwright/siunitx.git,https://github.com/josephwright/siunitx/issues,2012-11-04,2012-11-04,
+skel,skeldoc,Magnus Lie Hetland,https://github.com/mlhetland/skeldoc.sty,https://github.com/mlhetland/skeldoc.sty.git,https://github.com/mlhetland/skeldoc.sty/issues,2021-01-04,2021-01-04,
+skip,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+slcd,se2thesis,Stephan Lukasczyk,https://github.com/se2p/se2thesis,https://github.com/se2p/se2thesis,https://github.com/se2p/se2thesis/issues,2023-10-18,2023-10-18,
+socket,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2023-10-17,2023-10-17,
+sort,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2017-02-13,
+space,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+starray,starray,Alceu Frigeri,https://github.com/alceu-frigeri/starray,https://github.com/alceu-frigeri/starray,https://github.com/alceu-frigeri/starray/issues,2023-05-15,2023-05-15,
+statistics,statistics,Julien Rivaud,https://gitlab.com/frnchfrgg-latex/statistics,https://gitlab.com/frnchfrgg-latex/statistics.git,https://gitlab.com/frnchfrgg-latex/statistics/issues,2018-06-25,2018-06-25,
+stm,lt3-stm,CV Radhakrishnan,http://www.cvr.cc/,,,2014-02-26,2014-02-26,
+stop,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+str,"l3kernel,l3str-format",The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+stycmd,styledcmd,Paolo De Donato,https://github.com/Loara/styledcmd,https://github.com/Loara/styledcmd.git,https://github.com/Loara/styledcmd/issues,2021-08-30,2021-08-30,
+substances,substances,Clemens Niederberger,https://github.com/cgnieder/substances/,https://github.com/cgnieder/substances.git,https://github.com/cgnieder/substances/issues,2013-03-16,2020-04-14,
+sys,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2015-09-07,2015-09-08,
+tag,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2019-06-02,2019-06-02,
+tasks,tasks,Clemens Niederberger,https://github.com/cgnieder/tasks/,https://github.com/cgnieder/tasks.git,https://github.com/cgnieder/cgnieder/tasks/issues,2013-03-16,2020-04-14,
+tbl,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2023-10-23,2023-10-23,
+tblr,tabularray,Jianrui Lyu,https://github.com/lvjr/tabularray,https://github.com/lvjr/tabularray.git,https://github.com/lvjr/tabularray/issues,2022-04-02,2022-04-02,
+tcobox,tcolorbox,Thomas F. Sturm,https://github.com/T-F-S/tcolorbox,https://github.com/T-F-S/tcolorbox.git,https://github.com/T-F-S/tcolorbox/issues,2020-02-19,2020-02-19,
+template,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-01-20,2021-03-03,
+term,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+tex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+text,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2020-01-15,2020-01-15,
+tikzfill,tikzfill,Thomas F. Sturm,https://github.com/T-F-S/tikzfill,https://github.com/T-F-S/tikzfill.git,https://github.com/T-F-S/tikzfill/issues,2022-07-19,2022-07-19,
+tikzlings,tikzlings,samcarter,https://github.com/samcarter/tikzlings,git@github.com:samcarter/tikzlings.git,https://github.com/samcarter/tikzlings/issues,2023-02-17,2023-02-17,
+tikzsymbols,tikzsymbols,Ben Vitecek,https://github.com/Vidabe/tikzsymbols,https://github.com/Vidabe/tikzsymbols.git,https://github.com/Vidabe/tikzsymbols/issues,2018-09-26,2018-09-26,
+tilde,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+tl,"l3kernel,l3tl-build",The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+tmpa,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+tmpb,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+token,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+true,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23,
+twmk,menukeys,Tobias Weh,https://github.com/tweh/menukeys,git@github.com:tweh/menukeys.git,https://github.com/tweh/menukeys/issues,2020-10-31,2020-10-31,“classic†L2 package using only some expl3 code
+ufcombo,combofont,Ulrike Fischer,https://github.com/u-fischer/combofont,https://github.com/u-fischer/combofont,https://github.com/u-fischer/combofont/issues,2020-04-24,2020-04-24,
+ufgrid,returntogrid,Ulrike Fischer,https://github.com/u-fischer/returntogrid,https://github.com/u-fischer/returntogrid,https://github.com/u-fischer/returntogrid/issues,2020-04-24,2020-04-24,
+uftag,tagpdf,Ulrike Fischer,,,,2018-07-15,2018-07-15,
+um,unicode-math,Will Robertson,https://github.com/wspr/unicode-math,https://github.com/wspr/unicode-math.git,https://github.com/wspr/unicode-math/issues,2013-03-16,2013-03-16,
+underscore,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+unravel,unravel,Bruno Le Floch,https://github.com/blefloch/latex-unravel,https://github.com/blefloch/latex-unravel.git,https://github.com/blefloch/latex-unravel/issues,2015-09-22,2015-09-22,
+uptex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2015-07-28,2015-07-28,
+use,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+utex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2015-07-28,2015-07-28,
+vbox,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+vcoffin,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28,
+wheelchart,wheelchart,Matthias Floré,,,,2023-12-07,2023-12-07,
+withargs,withargs,Michiel Helvensteijn,,,,2014-02-05,2014-02-05,
+witharrows,witharrows,François Pantigny,,,,2019-12-19,2019-12-19,
+xeCJK,xecjk,Qing Lee,https://github.com/CTeX-org/ctex-kit,https://github.com/CTeX-org/ctex-kit.git,https://github.com/CTeX-org/ctex-kit/issues,2013-05-26,2013-05-26,
+xetex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+xfrac,xfrac,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/xfrac.git,https://github.com/latex3/xfrac/issues,2012-09-27,2024-02-14,
+xmarks,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-03-03,2021-03-03,
+xparse,xparse,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+xpatch,"regexpatch,xpatch",Enrico Gregorio,,,,2013-03-16,2013-03-16,
+xpeek,xpeek,Joel C. Salomon,,,,2013-03-16,2013-03-16,
+xpinyin,xpinyin,Qing Lee,https://github.com/CTeX-org/ctex-kit,https://github.com/CTeX-org/ctex-kit.git,https://github.com/CTeX-org/ctex-kit/issues,2013-03-16,2013-05-26,
+xsb,xsavebox,Alexander Grahn,,https://gitlab.com/agrahn/xsavebox,https://gitlab.com/agrahn/xsavebox/issues,2016-02-26,2020-04-15,
+xsim,xsim,Clemens Niederberger,https://github.com/cgnieder/xsim/,https://github.com/cgnieder/xsim.git,https://github.com/cgnieder/xsim/issues,2020-04-14,2020-04-14,
+xtemplate,xtemplate,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+yoin,yoin,Tom Hejda,https://github.com/tohecz/yoin,https://github.com/tohecz/yoin.git,https://github.com/tohecz/yoin/issues,2016-02-22,2016-02-22,
+zero,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+zhlipsum,zhlipsum,Xiangdong Zeng,https://github.com/stone-zeng/zhlipsum,https://github.com/stone-zeng/zhlipsum.git,https://github.com/stone-zeng/zhlipsum/issues,2018-06-14,2018-06-14,
+zhnum,zhnumber,Qing Lee,https://github.com/CTeX-org/ctex-kit,https://github.com/CTeX-org/ctex-kit.git,https://github.com/CTeX-org/ctex-kit/issues,2013-03-16,2013-05-26,
+zrefcheck,zref-check,gusbrs,https://github.com/gusbrs/zref-check,https://github.com/gusbrs/zref-check,https://github.com/gusbrs/zref-check/issues,2021-08-05,2021-08-05,
+zrefclever,zref-clever,gusbrs,https://github.com/gusbrs/zref-clever,https://github.com/gusbrs/zref-clever,https://github.com/gusbrs/zref-clever/issues,2021-11-29,2021-11-29,
+zrefvario,zref-vario,gusbrs,https://github.com/gusbrs/zref-vario,https://github.com/gusbrs/zref-vario,https://github.com/gusbrs/zref-vario/issues,2022-02-02,2022-02-02,
+zxjt,zxjatype,Takayuki Yato,,,,2013-03-16,2013-03-16,
diff --git a/macros/latex-dev/required/l3kernel/l3prefixes.pdf b/macros/latex-dev/required/l3kernel/l3prefixes.pdf
new file mode 100644
index 0000000000..f3241dfd65
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3prefixes.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3prefixes.tex b/macros/latex-dev/required/l3kernel/l3prefixes.tex
new file mode 100644
index 0000000000..6c7cf24244
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3prefixes.tex
@@ -0,0 +1,91 @@
+\iffalse meta-comment
+
+File:l3prefixes.tex
+
+Copyright (C) 2019,2021 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this
+license or (at your option) any later version. The latest version
+of this license is in the file
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3kernel bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+The released version of this bundle is available from CTAN.
+
+-----------------------------------------------------------------------
+
+The development version of the bundle can be found at
+
+ https://github.com/latex3/latex3
+
+for those people who are interested.
+
+\fi
+
+\documentclass{article}
+\usepackage{expl3}
+\usepackage{array}
+\usepackage{booktabs}
+\usepackage{longtable}
+\ExplSyntaxOn
+\cs_new_protected:Npn \__prefix_readi:w #1 " #2 " #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \__prefix_readii:w #1 \q_stop }
+ { \__prefix_readi:w #1 {#2} #3 \q_stop }
+ }
+\cs_new_protected:Npn \__prefix_readii:w #1 , #2 , #3 , #4 \q_stop
+ { \__prefix_readiii:nnw {#1} {#3} #2 , \q_stop }
+\cs_new_protected:Npn \__prefix_readiii:nnw #1 #2 #3 , #4 \q_stop
+ {
+ \tl_put_right:Nn \l_tmpb_tl { #1 & #3 & #2 \\ }
+ \tl_if_blank:nF {#4}
+ { \clist_map_inline:nn {#4} { \tl_put_right:Nn \l_tmpb_tl { & ##1 \\ } } }
+ }
+\ior_new:N \l_tmpa_ior
+\ior_open:Nn \l_tmpa_ior { l3prefixes.csv }
+\ior_get:NN \l_tmpa_ior \l_tmpa_tl % Throw away
+\cs_new_protected:Npn \PrintTable
+ {
+ \tl_set:Nn \l_tmpb_tl
+ {
+ \begin { longtable } { @{} *{2}{>{\ttfamily}l} l @{} }
+ \toprule
+ \multicolumn{1}{@{}l}{Prefix}
+ & \multicolumn{1}{l@{}}{Module}
+ & Registrant \\
+ \midrule
+ \endhead
+ \bottomrule
+ \endfoot
+ }
+ \ior_map_inline:Nn \l_tmpa_ior
+ { \__prefix_readi:w ##1 " \q_nil " \q_stop }
+ \tl_put_right:Nn \l_tmpb_tl { \end { longtable } }
+ \tl_replace_all:Nnn \l_tmpb_tl { LaTeX3 } { \LaTeX3 }
+ \tl_use:N \l_tmpb_tl
+ }
+\ExplSyntaxOff
+\begin{document}
+
+This file lists the prefixes which have been registered with the \LaTeX{}
+team for use in \textsf{expl3} code. Programmers are invited to register their
+(public) prefix use by contacting the team at
+\begin{quote}
+ \texttt{modules@latex-project.org}
+\end{quote}
+with the relevant information for the \texttt{.csv} file, i.e.,
+\textit{Prefix, Module or package, Registrant, Homepage, Source repository, Issue tracker}.
+
+
+We recommend that short prefixes are avoided as there are a limited
+number of these very general names available. The
+file \texttt{l3prefixes.csv} contains more details on each module, for
+example any information on source repository or issue tracker.
+
+\PrintTable
+\end{document}
diff --git a/macros/latex-dev/required/l3kernel/l3prg.dtx b/macros/latex-dev/required/l3kernel/l3prg.dtx
new file mode 100644
index 0000000000..ea76955d82
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3prg.dtx
@@ -0,0 +1,1829 @@
+% \iffalse meta-comment
+%
+%% File: l3prg.dtx
+%
+% Copyright (C) 2005-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3prg} module\\ Control structures^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% Conditional processing in \LaTeX3 is defined as something that
+% performs a series of tests, possibly involving assignments and
+% calling other functions that do not read further ahead in the input
+% stream. After processing the input, a \emph{state} is returned. The
+% states returned are \meta{true} and \meta{false}.
+%
+% \LaTeX3 has two forms of conditional flow processing based
+% on these states. The first form is predicate functions that turn the
+% returned state into a boolean \meta{true} or \meta{false}. For
+% example, the function \cs{cs_if_free_p:N} checks whether the control
+% sequence given as its argument is free and then returns the boolean
+% \meta{true} or \meta{false} values to be used in testing with
+% \cs{if_predicate:w} or in functions to be described below. The second form
+% is the kind of functions choosing a particular argument from the
+% input stream based on the result of the testing as in
+% \cs{cs_if_free:NTF} which also takes one argument (the |N|) and then
+% executes either \texttt{true} or \texttt{false} depending on the
+% result.
+%
+% \begin{texnote}
+% The arguments are executed after exiting the underlying
+% |\if...\fi:| structure.
+% \end{texnote}
+%
+% \section{Defining a set of conditional functions}
+% \label{sec:l3prg:new-conditional-functions}
+%
+% \begin{function}[updated = 2022-11-01]
+% {
+% \prg_new_conditional:Npnn, \prg_set_conditional:Npnn, \prg_gset_conditional:Npnn,
+% \prg_new_conditional:Nnn, \prg_set_conditional:Nnn, \prg_gset_conditional:Nnn
+% }
+% \begin{syntax}
+% \cs{prg_new_conditional:Npnn} \cs[no-index]{\meta{name}:\meta{arg spec}} \meta{parameters} \Arg{conditions} \Arg{code} \\
+% \cs{prg_new_conditional:Nnn} \cs[no-index]{\meta{name}:\meta{arg spec}} \Arg{conditions} \Arg{code}
+% \end{syntax}
+% These functions create a family of conditionals using the same
+% \Arg{code} to perform the test created. Those conditionals are
+% expandable if \meta{code} is. The \texttt{new} versions check
+% for existing definitions and perform assignments globally
+% (\emph{cf.}~\cs{cs_new:Npn}) whereas the \texttt{set} versions do no
+% check and perform assignments locally (\emph{cf.}~\cs{cs_set:Npn}).
+% The conditionals created are dependent on the comma-separated list
+% of \meta{conditions}, which should be one or more of \texttt{p},
+% \texttt{T}, \texttt{F} and \texttt{TF}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-02-06]
+% {
+% \prg_new_protected_conditional:Npnn, \prg_set_protected_conditional:Npnn, \prg_gset_protected_conditional:Npnn,
+% \prg_new_protected_conditional:Nnn, \prg_set_protected_conditional:Nnn, \prg_gset_protected_conditional:Nnn
+% }
+% \begin{syntax}
+% \cs{prg_new_protected_conditional:Npnn} \cs[no-index]{\meta{name}:\meta{arg spec}} \meta{parameters} \Arg{conditions} \Arg{code} \\
+% \cs{prg_new_protected_conditional:Nnn} \cs[no-index]{\meta{name}:\meta{arg spec}} \Arg{conditions} \Arg{code}
+% \end{syntax}
+% These functions create a family of protected conditionals using the
+% same \Arg{code} to perform the test created. The \meta{code} does
+% not need to be expandable. The \texttt{new} version check for
+% existing definitions and perform assignments globally
+% (\emph{cf.}~\cs{cs_new:Npn}) whereas the \texttt{set} version do
+% not (\emph{cf.}~\cs{cs_set:Npn}). The conditionals created are
+% depended on the comma-separated list of \meta{conditions}, which
+% should be one or more of \texttt{T}, \texttt{F} and \texttt{TF} (not
+% \texttt{p}).
+% \end{function}
+%
+% The conditionals are defined by \cs{prg_new_conditional:Npnn} and
+% friends as:
+% \begin{itemize}
+% \item \cs[no-index]{\meta{name}_p:\meta{arg spec}} --- a predicate function
+% which will supply either a logical \texttt{true} or logical
+% \texttt{false}. This function is intended for use in cases where
+% one or more logical tests are combined to lead to a final outcome.
+% This function cannot be defined for \texttt{protected}
+% conditionals.
+% \item \cs[no-index]{\meta{name}:\meta{arg spec}T} --- a function with one more
+% argument than the original \meta{arg spec} demands. The \meta{true
+% branch} code in this additional argument will be left on the
+% input stream only if the test is \texttt{true}.
+% \item \cs[no-index]{\meta{name}:\meta{arg spec}F} --- a function with one more
+% argument than the original \meta{arg spec} demands. The
+% \meta{false branch} code in this additional argument will be left
+% on the input stream only if the test is \texttt{false}.
+% \item \cs[no-index]{\meta{name}:\meta{arg spec}TF} --- a function with two
+% more argument than the original \meta{arg spec} demands. The
+% \meta{true branch} code in the first additional argument will be
+% left on the input stream if the test is \texttt{true}, while the
+% \meta{false branch} code in the second argument will be left on
+% the input stream if the test is \texttt{false}.
+% \end{itemize}
+% The \meta{code} of the test may use \meta{parameters} as specified by
+% the second argument to \cs{prg_set_conditional:Npnn}: this should
+% match the \meta{argument specification} but this is not enforced. The
+% |Nnn| versions infer the number of arguments from the argument
+% specification given (\emph{cf.}~\cs{cs_new:Nn}, \emph{etc.}). Within
+% the \meta{code}, the functions \cs{prg_return_true:} and
+% \cs{prg_return_false:} are used to indicate the logical outcomes of
+% the test.
+%
+% An example can easily clarify matters here:
+% \begin{verbatim}
+% \prg_set_conditional:Npnn \foo_if_bar:NN #1#2 { p , T , TF }
+% {
+% \if_meaning:w \l_tmpa_tl #1
+% \prg_return_true:
+% \else:
+% \if_meaning:w \l_tmpa_tl #2
+% \prg_return_true:
+% \else:
+% \prg_return_false:
+% \fi:
+% \fi:
+% }
+% \end{verbatim}
+% This defines the function |\foo_if_bar_p:NN|, |\foo_if_bar:NNTF| and
+% |\foo_if_bar:NNT| but not |\foo_if_bar:NNF| (because |F| is missing
+% from the \meta{conditions} list). The return statements take care of
+% resolving the remaining \cs{else:} and \cs{fi:} before returning the
+% state. There must be a return statement for each branch; failing to do
+% so will result in erroneous output if that branch is executed.
+%
+% The special case where the code of a conditional ends with
+% \cs{prg_return_true:} \cs{else:} \cs{prg_return_false:} \cs{fi:} is
+% optimized.
+%
+% \begin{function}[updated = 2023-05-26]
+% {
+% \prg_new_eq_conditional:NNn,
+% \prg_set_eq_conditional:NNn,
+% \prg_gset_eq_conditional:NNn
+% }
+% \begin{syntax}
+% \cs{prg_new_eq_conditional:NNn} \cs[no-index]{\meta{name_1}:\meta{arg spec_1}} \cs[no-index]{\meta{name_2}:\meta{arg spec_2}} \Arg{conditions}
+% \end{syntax}
+% These functions copy a family of conditionals. The \texttt{new} version
+% checks for existing definitions (\emph{cf.}~\cs{cs_new_eq:NN}) whereas
+% the \texttt{set} version does not (\emph{cf.}~\cs{cs_set_eq:NN}). The
+% conditionals copied are depended on the comma-separated list of
+% \meta{conditions}, which should be one or more of \texttt{p}, \texttt{T},
+% \texttt{F} and \texttt{TF}.
+% \end{function}
+%
+% \begin{function}[EXP]{\prg_return_true:, \prg_return_false:}
+% \begin{syntax}
+% \cs{prg_return_true:}
+% \cs{prg_return_false:}
+% \end{syntax}
+% These \enquote{return} functions define the logical state of a conditional statement.
+% They appear within the code for a conditional
+% function generated by \cs{prg_set_conditional:Npnn}, \emph{etc}, to indicate
+% when a true or false branch should be taken.
+% While they may appear multiple times each within the code of such conditionals,
+% the execution of the conditional must result in the expansion of one of these
+% two functions \emph{exactly once}.
+%
+% The return functions trigger what is internally an \texttt{f}-expansion process to complete
+% the evaluation of the conditional. Therefore, after \cs{prg_return_true:} or \cs{prg_return_false:}
+% there must be no non-expandable material in the input stream for the remainder of
+% the expansion of the conditional code. This includes other instances of either of these functions.
+% \end{function}
+%
+% \begin{function}[added = 2017-12-12]{\prg_generate_conditional_variant:Nnn}
+% \begin{syntax}
+% \cs{prg_generate_conditional_variant:Nnn} \cs[no-index]{\meta{name}:\meta{arg spec}} \Arg{variant argument specifiers} \Arg{condition specifiers}
+% \end{syntax}
+% Defines argument-specifier variants of conditionals. This is
+% equivalent to running \cs{cs_generate_variant:Nn} \meta{conditional}
+% \Arg{variant argument specifiers} on each \meta{conditional}
+% described by the \meta{condition specifiers}. These base-form
+% \meta{conditionals} are obtained from the \meta{name} and \meta{arg
+% spec} as described for \cs{prg_new_conditional:Npnn}, and they
+% should be defined.
+% \end{function}
+%
+% \section{The boolean data type}
+%
+% This section describes a boolean data type which is closely
+% connected to conditional processing as sometimes you want to
+% execute some code depending on the value of a switch
+% (\emph{e.g.},~draft/final) and other times you perhaps want to use it as a
+% predicate function in an \cs{if_predicate:w} test. The problem of the
+% primitive \cs{if_false:} and \cs{if_true:} tokens is that it is not
+% always safe to pass them around as they may interfere with scanning
+% for termination of primitive conditional processing. Therefore, we
+% employ two canonical booleans: \cs{c_true_bool} or
+% \cs{c_false_bool}. Besides preventing problems as described above, it
+% also allows us to implement a simple boolean parser supporting the
+% logical operations And, Or, Not, \emph{etc.}\ which can then be used on
+% both the boolean type and predicate functions.
+%
+% All conditional |\bool_| functions except assignments are expandable
+% and expect the input to also be fully expandable (which generally
+% means being constructed from predicate functions and booleans, possibly nested).
+%
+% \begin{texnote}
+% The \texttt{bool} data type is not implemented using the
+% \tn{iffalse}/\tn{iftrue} primitives, in contrast to \tn{newif},
+% \emph{etc.}, in plain \TeX{}, \LaTeXe{} and so on. Programmers should
+% not base use of \texttt{bool} switches on any particular expectation
+% of the implementation.
+% \end{texnote}
+%
+% \begin{function}{\bool_new:N, \bool_new:c}
+% \begin{syntax}
+% \cs{bool_new:N} \meta{boolean}
+% \end{syntax}
+% Creates a new \meta{boolean} or raises an error if the
+% name is already taken. The declaration is global. The
+% \meta{boolean} is initially \texttt{false}.
+% \end{function}
+%
+% \begin{function}[added = 2017-11-28]{\bool_const:Nn, \bool_const:cn}
+% \begin{syntax}
+% \cs{bool_const:Nn} \meta{boolean} \Arg{boolexpr}
+% \end{syntax}
+% Creates a new constant \meta{boolean} or raises an error if the name
+% is already taken. The value of the \meta{boolean} is set globally to
+% the result of evaluating the \meta{boolexpr}.
+% \end{function}
+%
+% \begin{function}
+% {
+% \bool_set_false:N , \bool_set_false:c ,
+% \bool_gset_false:N, \bool_gset_false:c
+% }
+% \begin{syntax}
+% \cs{bool_set_false:N} \meta{boolean}
+% \end{syntax}
+% Sets \meta{boolean} logically \texttt{false}.
+% \end{function}
+%
+% \begin{function}
+% {
+% \bool_set_true:N , \bool_set_true:c ,
+% \bool_gset_true:N , \bool_gset_true:c
+% }
+% \begin{syntax}
+% \cs{bool_set_true:N} \meta{boolean}
+% \end{syntax}
+% Sets \meta{boolean} logically \texttt{true}.
+% \end{function}
+%
+% \begin{function}
+% {
+% \bool_set_eq:NN , \bool_set_eq:cN , \bool_set_eq:Nc , \bool_set_eq:cc ,
+% \bool_gset_eq:NN, \bool_gset_eq:cN, \bool_gset_eq:Nc, \bool_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{bool_set_eq:NN} \meta{boolean_1} \meta{boolean_2}
+% \end{syntax}
+% Sets \meta{boolean_1} to the current value of \meta{boolean_2}.
+% \end{function}
+%
+% \begin{function}[updated = 2017-07-15]
+% {\bool_set:Nn, \bool_set:cn, \bool_gset:Nn, \bool_gset:cn}
+% \begin{syntax}
+% \cs{bool_set:Nn} \meta{boolean} \Arg{boolexpr}
+% \end{syntax}
+% Evaluates the \meta{boolean expression} as described for
+% \cs{bool_if:nTF}, and sets the \meta{boolean} variable to
+% the logical truth of this evaluation.
+% \end{function}
+%
+% \begin{function}[added = 2018-05-10]
+% {
+% \bool_set_inverse:N , \bool_set_inverse:c ,
+% \bool_gset_inverse:N, \bool_gset_inverse:c
+% }
+% \begin{syntax}
+% \cs{bool_set_inverse:N} \meta{boolean}
+% \end{syntax}
+% Toggles the \meta{boolean} from \texttt{true} to \texttt{false} and
+% conversely: sets it to the inverse of its current value.
+% \end{function}
+%
+% \begin{function}[EXP,pTF, updated = 2017-07-15]{\bool_if:N, \bool_if:c}
+% \begin{syntax}
+% \cs{bool_if_p:N} \meta{boolean}
+% \cs{bool_if:NTF} \meta{boolean} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests the current truth of \meta{boolean}, and continues expansion
+% based on this result.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2021-11-01, updated = 2023-11-14]
+% {\bool_to_str:N, \bool_to_str:c, \bool_to_str:n}
+% \begin{syntax}
+% \cs{bool_to_str:N} \meta{boolean}
+% \cs{bool_to_str:n} \meta{boolean expression}
+% \end{syntax}
+% Expands to the string \texttt{true} or \texttt{false} depending on
+% the logical truth of the \meta{boolean} or \meta{boolean
+% expression}.
+% \end{function}
+%
+% \begin{function}[added = 2012-02-09, updated = 2021-04-29]{\bool_show:N, \bool_show:c}
+% \begin{syntax}
+% \cs{bool_show:N} \meta{boolean}
+% \end{syntax}
+% Displays the logical truth of the \meta{boolean} on the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2012-02-09, updated = 2017-07-15]{\bool_show:n}
+% \begin{syntax}
+% \cs{bool_show:n} \Arg{boolean expression}
+% \end{syntax}
+% Displays the logical truth of the \meta{boolean expression} on the
+% terminal.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2021-04-29]{\bool_log:N, \bool_log:c}
+% \begin{syntax}
+% \cs{bool_log:N} \meta{boolean}
+% \end{syntax}
+% Writes the logical truth of the \meta{boolean} in the log file.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2017-07-15]{\bool_log:n}
+% \begin{syntax}
+% \cs{bool_log:n} \Arg{boolean expression}
+% \end{syntax}
+% Writes the logical truth of the \meta{boolean expression} in the log
+% file.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added=2012-03-03]
+% {\bool_if_exist:N, \bool_if_exist:c}
+% \begin{syntax}
+% \cs{bool_if_exist_p:N} \meta{boolean}
+% \cs{bool_if_exist:NTF} \meta{boolean} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{boolean} is currently defined. This does not
+% check that the \meta{boolean} really is a boolean variable.
+% \end{function}
+%
+% \subsection{Constant and scratch booleans}
+%
+% \begin{variable}{\c_true_bool, \c_false_bool}
+% Constants that represent |true| and |false|, respectively. Used to
+% implement predicates.
+% \end{variable}
+%
+% \begin{variable}{\l_tmpa_bool, \l_tmpb_bool}
+% A scratch boolean for local assignment. It is never used by
+% the kernel code, and so is safe for use with any \LaTeX3-defined
+% function. However, it may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_bool, \g_tmpb_bool}
+% A scratch boolean for global assignment. It is never used by
+% the kernel code, and so is safe for use with any \LaTeX3-defined
+% function. However, it may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Boolean expressions}
+%
+% As we have a boolean datatype and predicate functions returning
+% boolean \meta{true} or \meta{false} values, it seems only fitting
+% that we also provide a parser for \meta{boolean expressions}.
+%
+% A boolean expression is an expression which given input in the form
+% of predicate functions and boolean variables, return boolean
+% \meta{true} or \meta{false}. It supports the logical operations And,
+% Or and Not as the well-known infix operators |&&| and \verb"||" and prefix~|!|
+% with their usual precedences (namely, |&&| binds more tightly than
+% \verb"||"). In addition to this, parentheses can be used to isolate
+% sub-expressions. For example,
+% \begin{verbatim}
+% \int_compare_p:n { 1 = 1 } &&
+% (
+% \int_compare_p:n { 2 = 3 } ||
+% \int_compare_p:n { 4 <= 4 } ||
+% \str_if_eq_p:nn { abc } { def }
+% ) &&
+% ! \int_compare_p:n { 2 = 4 }
+% \end{verbatim}
+% is a valid boolean expression.
+%
+% Contrarily to some other programming languages, the operators |&&| and
+% \verb"||" evaluate both operands in all cases, even when the first
+% operand is enough to determine the result. This \enquote{eager}
+% evaluation should be contrasted with the \enquote{lazy} evaluation of
+% \cs[no-index]{bool_lazy_\ldots{}} functions.
+%
+% \begin{texnote}
+% The eager evaluation of boolean expressions is unfortunately
+% necessary in \TeX{}. Indeed, a lazy parser can get confused if |&&|
+% or \verb"||" or parentheses appear as (unbraced) arguments of some
+% predicates. For instance, the innocuous-looking expression below
+% would break (in a lazy parser) if |#1| were a closing parenthesis
+% and \cs[no-index]{l_tmpa_bool} were \texttt{true}.
+% \begin{verbatim}
+% ( \l_tmpa_bool || \token_if_eq_meaning_p:NN X #1 )
+% \end{verbatim}
+% \end{texnote}
+%
+% Minimal (lazy) evaluation can be obtained using the conditionals
+% \cs{bool_lazy_all:nTF}, \cs{bool_lazy_and:nnTF}, \cs{bool_lazy_any:nTF}, or
+% \cs{bool_lazy_or:nnTF}, which only evaluate their boolean expression
+% arguments when they are needed to determine the resulting truth
+% value. For example, when evaluating the boolean expression
+% \begin{verbatim}
+% \bool_lazy_and_p:nn
+% {
+% \bool_lazy_any_p:n
+% {
+% { \int_compare_p:n { 2 = 3 } }
+% { \int_compare_p:n { 4 <= 4 } }
+% { \int_compare_p:n { 1 = \error } } % skipped
+% }
+% }
+% { ! \int_compare_p:n { 2 = 4 } }
+% \end{verbatim}
+% the line marked with |skipped| is not expanded because the result
+% of \cs{bool_lazy_any_p:n} is known once the second boolean expression is
+% found to be logically \texttt{true}. On the other hand, the last
+% line is expanded because its logical value is needed to determine the
+% result of \cs{bool_lazy_and_p:nn}.
+%
+% \begin{function}[EXP, pTF, updated = 2017-07-15]{\bool_if:n}
+% \begin{syntax}
+% \cs{bool_if_p:n} \Arg{boolean expression}
+% \cs{bool_if:nTF} \Arg{boolean expression} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests the current truth of \meta{boolean expression}, and
+% continues expansion based on this result. The
+% \meta{boolean expression} should consist of a series of predicates
+% or boolean variables with the logical relationship between these
+% defined using |&&| (\enquote{And}), \verb"||" (\enquote{Or}),
+% |!| (\enquote{Not}) and parentheses. The logical Not applies to
+% the next predicate or group.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added = 2015-11-15, updated = 2017-07-15]{\bool_lazy_all:n}
+% \begin{syntax}
+% \cs{bool_lazy_all_p:n} \{ \Arg{boolexpr_1} \Arg{boolexpr_2} $\cdots$ \Arg{boolexpr_N} \}
+% \cs{bool_lazy_all:nTF} \{ \Arg{boolexpr_1} \Arg{boolexpr_2} $\cdots$ \Arg{boolexpr_N} \} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Implements the \enquote{And} operation on the \meta{boolean
+% expressions}, hence is \texttt{true} if all of them are
+% \texttt{true} and \texttt{false} if any of them is \texttt{false}.
+% Contrarily to the infix operator |&&|, only the \meta{boolean
+% expressions} which are needed to determine the result of
+% \cs{bool_lazy_all:nTF} are evaluated. See also \cs{bool_lazy_and:nnTF}
+% when there are only two \meta{boolean expressions}.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added = 2015-11-15, updated = 2017-07-15]{\bool_lazy_and:nn}
+% \begin{syntax}
+% \cs{bool_lazy_and_p:nn} \Arg{boolexpr_1} \Arg{boolexpr_2}
+% \cs{bool_lazy_and:nnTF} \Arg{boolexpr_1} \Arg{boolexpr_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Implements the \enquote{And} operation between two boolean
+% expressions, hence is \texttt{true} if both are \texttt{true}.
+% Contrarily to the infix operator |&&|, the \meta{boolexpr_2} is only
+% evaluated if it is needed to determine the result of
+% \cs{bool_lazy_and:nnTF}. See also \cs{bool_lazy_all:nTF} when there are more
+% than two \meta{boolean expressions}.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added = 2015-11-15, updated = 2017-07-15]{\bool_lazy_any:n}
+% \begin{syntax}
+% \cs{bool_lazy_any_p:n} \{ \Arg{boolexpr_1} \Arg{boolexpr_2} $\cdots$ \Arg{boolexpr_N} \}
+% \cs{bool_lazy_any:nTF} \{ \Arg{boolexpr_1} \Arg{boolexpr_2} $\cdots$ \Arg{boolexpr_N} \} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Implements the \enquote{Or} operation on the \meta{boolean
+% expressions}, hence is \texttt{true} if any of them is
+% \texttt{true} and \texttt{false} if all of them are \texttt{false}.
+% Contrarily to the infix operator \verb"||", only the \meta{boolean
+% expressions} which are needed to determine the result of
+% \cs{bool_lazy_any:nTF} are evaluated. See also \cs{bool_lazy_or:nnTF}
+% when there are only two \meta{boolean expressions}.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added = 2015-11-15, updated = 2017-07-15]{\bool_lazy_or:nn}
+% \begin{syntax}
+% \cs{bool_lazy_or_p:nn} \Arg{boolexpr_1} \Arg{boolexpr_2}
+% \cs{bool_lazy_or:nnTF} \Arg{boolexpr_1} \Arg{boolexpr_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Implements the \enquote{Or} operation between two boolean
+% expressions, hence is \texttt{true} if either one is \texttt{true}.
+% Contrarily to the infix operator \verb"||", the \meta{boolexpr_2}
+% is only evaluated if it is needed to determine the result of
+% \cs{bool_lazy_or:nnTF}. See also \cs{bool_lazy_any:nTF} when there are more
+% than two \meta{boolean expressions}.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2017-07-15]{\bool_not_p:n}
+% \begin{syntax}
+% \cs{bool_not_p:n} \Arg{boolean expression}
+% \end{syntax}
+% Function version of |!(|\meta{boolean expression}|)| within a boolean
+% expression.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added = 2018-05-09]{\bool_xor:nn}
+% \begin{syntax}
+% \cs{bool_xor_p:nn} \Arg{boolexpr_1} \Arg{boolexpr_2}
+% \cs{bool_xor:nnTF} \Arg{boolexpr_1} \Arg{boolexpr_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Implements an \enquote{exclusive or} operation between two boolean
+% expressions. There is no infix operation for this logical operation.
+% \end{function}
+%
+% \section{Logical loops}
+%
+% Loops using either boolean expressions or stored boolean values.
+%
+% \begin{function}[rEXP, updated = 2017-07-15]{\bool_do_until:Nn, \bool_do_until:cn}
+% \begin{syntax}
+% \cs{bool_do_until:Nn} \meta{boolean} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process,
+% and then checks the logical value of the \meta{boolean}. If it is
+% \texttt{false} then the \meta{code} is inserted into the input
+% stream again and the process loops until the \meta{boolean} is
+% \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP, updated = 2017-07-15]{\bool_do_while:Nn, \bool_do_while:cn}
+% \begin{syntax}
+% \cs{bool_do_while:Nn} \meta{boolean} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process,
+% and then checks the logical value of the \meta{boolean}. If it is
+% \texttt{true} then the \meta{code} is inserted into the input
+% stream again and the process loops until the \meta{boolean} is
+% \texttt{false}.
+% \end{function}
+%
+% \begin{function}[rEXP, updated = 2017-07-15]{\bool_until_do:Nn, \bool_until_do:cn}
+% \begin{syntax}
+% \cs{bool_until_do:Nn} \meta{boolean} \Arg{code}
+% \end{syntax}
+% This function first checks the logical value of the \meta{boolean}.
+% If it is \texttt{false} the \meta{code} is placed in the input stream
+% and expanded. After the completion of the \meta{code} the truth
+% of the \meta{boolean} is re-evaluated. The process then loops
+% until the \meta{boolean} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP, updated = 2017-07-15]{\bool_while_do:Nn, \bool_while_do:cn}
+% \begin{syntax}
+% \cs{bool_while_do:Nn} \meta{boolean} \Arg{code}
+% \end{syntax}
+% This function first checks the logical value of the \meta{boolean}.
+% If it is \texttt{true} the \meta{code} is placed in the input stream
+% and expanded. After the completion of the \meta{code} the truth
+% of the \meta{boolean} is re-evaluated. The process then loops
+% until the \meta{boolean} is \texttt{false}.
+% \end{function}
+%
+% \begin{function}[rEXP, updated = 2017-07-15]{\bool_do_until:nn}
+% \begin{syntax}
+% \cs{bool_do_until:nn} \Arg{boolean expression} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process,
+% and then checks the logical value of the \meta{boolean expression}
+% as described for \cs{bool_if:nTF}. If it is \texttt{false} then the
+% \meta{code} is inserted into the input stream again and the
+% process loops until the \meta{boolean expression} evaluates to
+% \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP, updated = 2017-07-15]{\bool_do_while:nn}
+% \begin{syntax}
+% \cs{bool_do_while:nn} \Arg{boolean expression} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process,
+% and then checks the logical value of the \meta{boolean expression}
+% as described for \cs{bool_if:nTF}. If it is \texttt{true} then the
+% \meta{code} is inserted into the input stream again and the
+% process loops until the \meta{boolean expression} evaluates to
+% \texttt{false}.
+% \end{function}
+%
+% \begin{function}[rEXP, updated = 2017-07-15]{\bool_until_do:nn}
+% \begin{syntax}
+% \cs{bool_until_do:nn} \Arg{boolean expression} \Arg{code}
+% \end{syntax}
+% This function first checks the logical value of the
+% \meta{boolean expression} (as described for \cs{bool_if:nTF}).
+% If it is \texttt{false} the \meta{code} is placed in the input stream
+% and expanded. After the completion of the \meta{code} the truth
+% of the \meta{boolean expression} is re-evaluated. The process
+% then loops until the \meta{boolean expression} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP, updated = 2017-07-15]{\bool_while_do:nn}
+% \begin{syntax}
+% \cs{bool_while_do:nn} \Arg{boolean expression} \Arg{code}
+% \end{syntax}
+% This function first checks the logical value of the
+% \meta{boolean expression} (as described for \cs{bool_if:nTF}).
+% If it is \texttt{true} the \meta{code} is placed in the input stream
+% and expanded. After the completion of the \meta{code} the truth
+% of the \meta{boolean expression} is re-evaluated. The process
+% then loops until the \meta{boolean expression} is \texttt{false}.
+% \end{function}
+%
+% \begin{function}[added = 2023-05-03, EXP, noTF]{\bool_case:n}
+% \begin{syntax}
+% \cs{bool_case:nTF} \\
+% ~~|{| \\
+% ~~~~\Arg{boolexpr case_1} \Arg{code case_1} \\
+% ~~~~\Arg{boolexpr case_2} \Arg{code case_2} \\
+% ~~~~\ldots \\
+% ~~~~\Arg{boolexpr case_n} \Arg{code case_n} \\
+% ~~|}| \\
+% ~~\Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Evaluates in turn each of the \meta{boolean expression cases} until
+% the first one that evaluates to \texttt{true}.
+% The \meta{code} associated to this first case is left in the input
+% stream, followed by the \meta{true code}, and other cases are
+% discarded. If none of the cases match then only the \meta{false
+% code} is inserted. The function \cs{bool_case:n},
+% which does nothing if there is no match, is
+% also available. For example
+% \begin{verbatim}
+% \bool_case:nF
+% {
+% { \dim_compare_p:n { \l__mypkg_wd_dim <= 10pt } }
+% { Fits }
+% { \int_compare_p:n { \l__mypkg_total_int >= 10 } }
+% { Many }
+% { \l__mypkg_special_bool }
+% { Special }
+% }
+% { No idea! }
+% \end{verbatim}
+% leaves \enquote{\texttt{Fits}} or \enquote{\texttt{Many}} or
+% \enquote{\texttt{Special}} or \enquote{\texttt{No idea!}} in the
+% input stream, in a way similar to some other language's
+% \enquote{\texttt{if} \ldots\ \texttt{elseif} \ldots\ \texttt{elseif} \ldots\
+% \texttt{else} \ldots}.
+% \end{function}
+%
+% \section{Producing multiple copies}
+%
+% \begin{function}[updated = 2011-07-04, EXP]{\prg_replicate:nn}
+% \begin{syntax}
+% \cs{prg_replicate:nn} \Arg{integer expression} \Arg{tokens}
+% \end{syntax}
+% Evaluates the \meta{integer expression} (which should be
+% zero or positive) and creates the resulting number of copies
+% of the \meta{tokens}. The function is both expandable and safe for
+% nesting. It yields its result after two expansion steps.
+% \end{function}
+%
+% \section{Detecting \TeX{}'s mode}
+%
+% \begin{function}[EXP,pTF]{\mode_if_horizontal:}
+% \begin{syntax}
+% \cs{mode_if_horizontal_p:}
+% \cs{mode_if_horizontal:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Detects if \TeX{} is currently in horizontal mode.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\mode_if_inner:}
+% \begin{syntax}
+% \cs{mode_if_inner_p:}
+% \cs{mode_if_inner:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Detects if \TeX{} is currently in inner mode.
+% \end{function}
+%
+% \begin{function}[updated = 2011-09-05, EXP,pTF]{\mode_if_math:}
+% \begin{syntax}
+% \cs{mode_if_math_p:}
+% \cs{mode_if_math:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Detects if \TeX{} is currently in maths mode.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\mode_if_vertical:}
+% \begin{syntax}
+% \cs{mode_if_vertical_p:}
+% \cs{mode_if_vertical:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Detects if \TeX{} is currently in vertical mode.
+% \end{function}
+%
+% \section{Primitive conditionals}
+%
+% \begin{function}[EXP]{\if_predicate:w}
+% \begin{syntax}
+% \cs{if_predicate:w} \meta{predicate} \meta{true code} \cs{else:} \meta{false code} \cs{fi:}
+% \end{syntax}
+% This function takes a predicate function and
+% branches according to the result. (In practice this function would also
+% accept a single boolean variable in place of the \meta{predicate} but to make the
+% coding clearer this should be done through \cs{if_bool:N}.)
+% \end{function}
+%
+% \begin{function}[EXP]{\if_bool:N}
+% \begin{syntax}
+% \cs{if_bool:N} \meta{boolean} \meta{true code} \cs{else:} \meta{false code} \cs{fi:}
+% \end{syntax}
+% This function takes a boolean variable and
+% branches according to the result.
+% \end{function}
+%
+% \section{Nestable recursions and mappings}
+%
+% There are a number of places where recursion or mapping constructs are used in
+% \pkg{expl3}. At a low-level, these typically require insertion of tokens
+% at the end of the content to allow \enquote{clean up}. To support such
+% mappings in a nestable form, the following functions are provided.
+%
+% \begin{function}[EXP, added = 2018-03-26]{\prg_break_point:Nn}
+% \begin{syntax}
+% \cs{prg_break_point:Nn} \cs[no-index]{\meta{type}_map_break:} \Arg{code}
+% \end{syntax}
+% Used to mark the end of a recursion or mapping: the functions
+% \cs[no-index]{\meta{type}_map_break:} and
+% \cs[no-index]{\meta{type}_map_break:n} use this to break out of the loop
+% (see \cs{prg_map_break:Nn} for how to set these up).
+% After the loop ends, the \meta{code} is inserted into the input stream. This
+% occurs even if the break functions are \emph{not} applied:
+% \cs{prg_break_point:Nn} is functionally-equivalent in these cases
+% to \cs{use_ii:nn}.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2018-03-26]{\prg_map_break:Nn}
+% \begin{syntax}
+% \cs{prg_map_break:Nn} \cs[no-index]{\meta{type}_map_break:} \Arg{user code}
+% \ldots{}
+% \cs{prg_break_point:Nn} \cs[no-index]{\meta{type}_map_break:} \Arg{ending code}
+% \end{syntax}
+% Breaks a recursion in mapping contexts, inserting in the input
+% stream the \meta{user code} after the \meta{ending code} for the
+% loop. The function breaks loops, inserting their \meta{ending
+% code}, until reaching a loop with the same \meta{type} as its
+% first argument. This \cs[no-index]{\meta{type}_map_break:} argument
+% must be defined; it is simply used as a recognizable marker for the \meta{type}.
+%
+% For types with mappings defined in the kernel,
+% \cs[no-index]{\meta{type}_map_break:} and \cs[no-index]{\meta{type}_map_break:n}
+% are defined as \cs{prg_map_break:Nn} \cs[no-index]{\meta{type}_map_break:} |{}|
+% and the same with |{}| omitted.
+% \end{function}
+%
+% \subsection{Simple mappings}
+%
+% In addition to the more complex mappings above, non-nestable mappings are
+% used in a number of locations and support is provided for these.
+%
+% \begin{function}[EXP, added = 2018-03-27]{\prg_break_point:}
+% This copy of \cs{prg_do_nothing:} is used to mark the end of a fast
+% short-term recursion: the function \cs{prg_break:n} uses this to
+% break out of the loop.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2018-03-27]{\prg_break:, \prg_break:n}
+% \begin{syntax}
+% \cs{prg_break:n} \Arg{code} \ldots{} \cs{prg_break_point:}
+% \end{syntax}
+% Breaks a recursion which has no \meta{ending code} and which is not
+% a user-breakable mapping (see for instance
+% implementation of \cs{int_step_function:nnnN}), and
+% inserts the \meta{code} in the input stream.
+% \end{function}
+%
+% \section{Internal programming functions}
+%
+% \begin{function}[updated = 2011-08-11, EXP]
+% {\group_align_safe_begin:, \group_align_safe_end:}
+% \begin{syntax}
+% \cs{group_align_safe_begin:}
+% \ldots
+% \cs{group_align_safe_end:}
+% \end{syntax}
+% These functions are used to enclose material in a \TeX{} alignment
+% environment within a specially-constructed group. This group is
+% designed in such a way that it does not add brace groups to the
+% output but does act as a group for the |&| token inside
+% \tn{halign}. This is necessary to allow grabbing of tokens
+% for testing purposes, as \TeX{} uses group level to determine the
+% effect of alignment tokens. Without the special grouping, the use of
+% a function such as \cs{peek_after:Nw} would result in a forbidden
+% comparison of the internal \tn{endtemplate} token, yielding a
+% fatal error. Each \cs{group_align_safe_begin:} must be matched by a
+% \cs{group_align_safe_end:}, although this does not have to occur
+% within the same function.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3prg} implementation}
+%
+% \TestFiles{m3prg001.lvt,m3prg002.lvt,m3prg003.lvt}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \subsection{Primitive conditionals}
+%
+% \begin{macro}{\if_bool:N}
+% \begin{macro}{\if_predicate:w}
+% Those two primitive \TeX{} conditionals are synonyms.
+% \cs{if_bool:N} is defined in \pkg{l3basics}, as it's needed
+% earlier to define quark test functions.
+% \begin{macrocode}
+\cs_new_eq:NN \if_predicate:w \tex_ifodd:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Defining a set of conditional functions}
+%
+% \begin{macro}
+% {
+% \prg_set_conditional:Npnn,
+% \prg_new_conditional:Npnn,
+% \prg_set_protected_conditional:Npnn,
+% \prg_new_protected_conditional:Npnn
+% }
+% \begin{macro}
+% {
+% \prg_set_conditional:Nnn,
+% \prg_new_conditional:Nnn,
+% \prg_set_protected_conditional:Nnn,
+% \prg_new_protected_conditional:Nnn
+% }
+% \begin{macro}{\prg_set_eq_conditional:NNn, \prg_new_eq_conditional:NNn}
+% \begin{macro}{\prg_return_true:}
+% \TestMissing
+% {This function is implicitly tested with all other conditionals!}
+% \begin{macro}{\prg_return_false:}
+% \TestMissing
+% {This function is also implicitly tested with all other conditionals!}
+% These are all defined in \pkg{l3basics}, as they are needed
+% \enquote{early}. This is just a reminder!
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{The boolean data type}
+%
+% \begin{macrocode}
+%<@@=bool>
+% \end{macrocode}
+%
+% \begin{macro}{\bool_new:N, \bool_new:c}
+% \UnitTested
+% Boolean variables have to be initiated when they are created. Other
+% than that there is not much to say here.
+% \begin{macrocode}
+\cs_new_protected:Npn \bool_new:N #1 { \cs_new_eq:NN #1 \c_false_bool }
+\cs_generate_variant:Nn \bool_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[added = 2017-11-28]{\bool_const:Nn, \bool_const:cn}
+% A merger between \cs{tl_const:Nn} and \cs{bool_set:Nn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \bool_const:Nn #1#2
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \tex_global:D \tex_chardef:D #1 = \bool_if_p:n {#2}
+ }
+\cs_generate_variant:Nn \bool_const:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \bool_set_true:N, \bool_set_true:c,
+% \bool_gset_true:N, \bool_gset_true:c,
+% \bool_set_false:N, \bool_set_false:c,
+% \bool_gset_false:N, \bool_gset_false:c
+% }
+% \UnitTested
+% Setting is already pretty easy.
+% When \texttt{check-declarations} is active, the definitions are patched to
+% make sure the boolean exists. This is needed because booleans are
+% not based on token lists nor on \TeX{} registers.
+% \begin{macrocode}
+\cs_new_protected:Npn \bool_set_true:N #1
+ { \cs_set_eq:NN #1 \c_true_bool }
+\cs_new_protected:Npn \bool_set_false:N #1
+ { \cs_set_eq:NN #1 \c_false_bool }
+\cs_new_protected:Npn \bool_gset_true:N #1
+ { \cs_gset_eq:NN #1 \c_true_bool }
+\cs_new_protected:Npn \bool_gset_false:N #1
+ { \cs_gset_eq:NN #1 \c_false_bool }
+\cs_generate_variant:Nn \bool_set_true:N { c }
+\cs_generate_variant:Nn \bool_set_false:N { c }
+\cs_generate_variant:Nn \bool_gset_true:N { c }
+\cs_generate_variant:Nn \bool_gset_false:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \bool_set_eq:NN, \bool_set_eq:cN,
+% \bool_set_eq:Nc, \bool_set_eq:cc,
+% \bool_gset_eq:NN, \bool_gset_eq:cN,
+% \bool_gset_eq:Nc, \bool_gset_eq:cc
+% }
+% \UnitTested
+% The usual copy code. While it would be cleaner semantically to copy
+% the \cs{cs_set_eq:NN} family of functions, we copy \cs{tl_set_eq:NN}
+% because that has the correct checking code.
+% \begin{macrocode}
+\cs_new_eq:NN \bool_set_eq:NN \tl_set_eq:NN
+\cs_new_eq:NN \bool_gset_eq:NN \tl_gset_eq:NN
+\cs_generate_variant:Nn \bool_set_eq:NN { Nc, cN, cc }
+\cs_generate_variant:Nn \bool_gset_eq:NN { Nc, cN, cc }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\bool_set:Nn, \bool_set:cn}
+% \begin{macro}{\bool_gset:Nn, \bool_gset:cn}
+% This function evaluates a boolean expression and assigns the first
+% argument the meaning \cs{c_true_bool} or \cs{c_false_bool}. Again,
+% we include some checking code. It is important to evaluate the
+% expression before applying the \tn{chardef} primitive, because that
+% primitive sets the left-hand side to \cs{scan_stop:} before looking
+% for the right-hand side.
+% \begin{macrocode}
+\cs_new_protected:Npn \bool_set:Nn #1#2
+ {
+ \exp_last_unbraced:NNNf
+ \tex_chardef:D #1 = { \bool_if_p:n {#2} }
+ }
+\cs_new_protected:Npn \bool_gset:Nn #1#2
+ {
+ \exp_last_unbraced:NNNNf
+ \tex_global:D \tex_chardef:D #1 = { \bool_if_p:n {#2} }
+ }
+\cs_generate_variant:Nn \bool_set:Nn { c }
+\cs_generate_variant:Nn \bool_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[added = 2018-05-10]
+% {\bool_set_inverse:N, \bool_set_inverse:c, \bool_gset_inverse:N, \bool_gset_inverse:c}
+% Set to \texttt{false} or \texttt{true} locally or globally.
+% \begin{macrocode}
+\cs_new_protected:Npn \bool_set_inverse:N #1
+ { \bool_if:NTF #1 { \bool_set_false:N } { \bool_set_true:N } #1 }
+\cs_generate_variant:Nn \bool_set_inverse:N { c }
+\cs_new_protected:Npn \bool_gset_inverse:N #1
+ { \bool_if:NTF #1 { \bool_gset_false:N } { \bool_gset_true:N } #1 }
+\cs_generate_variant:Nn \bool_gset_inverse:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Internal auxiliaries}
+%
+% \begin{variable}{\q_@@_recursion_tail,\q_@@_recursion_stop}
+% Internal recursion quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_recursion_tail
+\quark_new:N \q_@@_recursion_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_use_i_delimit_by_q_recursion_stop:nw}
+% Functions to gobble up to a quark.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_i_delimit_by_q_recursion_stop:nw
+ #1 #2 \q_@@_recursion_stop {#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_if_recursion_tail_stop_do:nn}
+% Functions to query recursion quarks.
+% \begin{macrocode}
+\__kernel_quark_new_test:N \@@_if_recursion_tail_stop_do:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\bool_if:N, \bool_if:c}
+% \UnitTested
+% Straight forward here. We could optimize here if we wanted to as
+% the boolean can just be input directly.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \bool_if:N #1 { p , T , F , TF }
+ {
+ \if_bool:N #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_generate_conditional_variant:Nnn \bool_if:N { c } { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\bool_to_str:N, \bool_to_str:c, \bool_to_str:n}
+% Expands to string literal \texttt{true} or \texttt{false}.
+% \begin{macrocode}
+\cs_new:Npe \bool_to_str:N #1
+ {
+ \exp_not:N \bool_if:NTF #1
+ { \tl_to_str:n { true } } { \tl_to_str:n { false } }
+ }
+\cs_generate_variant:Nn \bool_to_str:N { c }
+\cs_new:Npe \bool_to_str:n #1
+ {
+ \exp_not:N \bool_if:nTF {#1}
+ { \tl_to_str:n { true } } { \tl_to_str:n { false } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\bool_show:n, \bool_log:n}
+% Show the truth value of the boolean.
+% \begin{macrocode}
+\cs_new_protected:Npn \bool_show:n
+ { \__kernel_msg_show_eval:Nn \bool_to_str:n }
+\cs_new_protected:Npn \bool_log:n
+ { \__kernel_msg_log_eval:Nn \bool_to_str:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\bool_show:N, \bool_show:c, \bool_log:N, \bool_log:c, \@@_show:NN}
+% Show the truth value of the boolean, as \texttt{true} or
+% \texttt{false}.
+% \begin{macrocode}
+\cs_new_protected:Npn \bool_show:N { \@@_show:NN \tl_show:n }
+\cs_generate_variant:Nn \bool_show:N { c }
+\cs_new_protected:Npn \bool_log:N { \@@_show:NN \tl_log:n }
+\cs_generate_variant:Nn \bool_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_chk_defined:NT #2
+ {
+ \token_case_meaning:NnF #2
+ {
+ \c_true_bool { \exp_args:Ne #1 { \token_to_str:N #2 = true } }
+ \c_false_bool { \exp_args:Ne #1 { \token_to_str:N #2 = false } }
+ }
+ {
+ \msg_error:nneee { kernel } { bad-type }
+ { \token_to_str:N #2 } { \token_to_meaning:N #2 } { bool }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_tmpa_bool, \l_tmpb_bool, \g_tmpa_bool, \g_tmpb_bool}
+% A few booleans just if you need them.
+% \begin{macrocode}
+\bool_new:N \l_tmpa_bool
+\bool_new:N \l_tmpb_bool
+\bool_new:N \g_tmpa_bool
+\bool_new:N \g_tmpb_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[pTF]{\bool_if_exist:N, \bool_if_exist:c}
+% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \bool_if_exist:N \cs_if_exist:N
+ { TF , T , F , p }
+\prg_new_eq_conditional:NNn \bool_if_exist:c \cs_if_exist:c
+ { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Boolean expressions}
+%
+% \begin{macro}[pTF]{\bool_if:n}
+% \UnitTested
+% Evaluating the truth value of a list of predicates is done using an
+% input syntax somewhat similar to the one found in other programming
+% languages with |(| and |)| for grouping, |!| for logical
+% \enquote{Not}, |&&| for logical \enquote{And} and \verb"||" for
+% logical \enquote{Or}. However, they perform eager evaluation.
+% We shall use the terms Not, And, Or, Open and
+% Close for these operations.
+%
+% Any expression is terminated by a Close operation. Evaluation
+% happens from left to right in the following manner using a GetNext
+% function:
+% \begin{itemize}
+% \item If an Open is seen, start evaluating a new expression using
+% the Eval function and call GetNext again.
+% \item If a Not is seen, remove the |!| and call a GetNext
+% function with the logic reversed.
+% \item If none of the above, reinsert the token found (this is
+% supposed to be a predicate function) in front of an Eval
+% function, which evaluates it to the boolean value \meta{true} or
+% \meta{false}.
+% \end{itemize}
+% The Eval function then contains a post-processing operation which
+% grabs the instruction following the predicate. This is either And,
+% Or or Close. In each case the truth value is used to determine
+% where to go next. The following situations can arise:
+% \begin{description}
+% \item[\meta{true}And] Current truth value is true, logical And
+% seen, continue with GetNext to examine truth value of next
+% boolean (sub-)expression.
+% \item[\meta{false}And] Current truth value is false, logical And
+% seen, stop using the values of predicates within this
+% sub-expression until the next Close. Then return \meta{false}.
+% \item[\meta{true}Or] Current truth value is true, logical Or seen,
+% stop using the values of predicates within this sub-expression
+% until the nearest Close. Then return \meta{true}.
+% \item[\meta{false}Or] Current truth value is false, logical Or
+% seen, continue with GetNext to examine truth value of next
+% boolean (sub-)expression.
+% \item[\meta{true}Close] Current truth value is true, Close
+% seen, return \meta{true}.
+% \item[\meta{false}Close] Current truth value is false, Close
+% seen, return \meta{false}.
+% \end{description}
+% \begin{macrocode}
+\prg_new_conditional:Npnn \bool_if:n #1 { T , F , TF }
+ {
+ \if_predicate:w \bool_if_p:n {#1}
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\bool_if_p:n, \@@_if_p:n, \@@_if_p_aux:w}
+% To speed up the case of a single predicate, \texttt{f}-expand and
+% check whether the result is one token (possibly surrounded by
+% spaces), which must be \cs{c_true_bool} or \cs{c_false_bool}. We
+% use a version of \cs{tl_if_single:nTF} optimized for speed since we
+% know that an empty~|#1| is an error. The auxiliary
+% \cs{@@_if_p_aux:w} removes the trailing parenthesis and gets rid of
+% any space, then returns \cs{c_true_bool} or \cs{c_false_bool} as
+% appropriate. This extra work around is because in a
+% \cs{bool_set:Nn}, the underlying \tn{chardef} turns the bool being
+% set temporarily equal to \tn{relax}, thus assigning a boolean to
+% itself would fail (gh/1055). For the general case, first issue a
+% \cs{group_align_safe_begin:} as we are using |&&| as
+% syntax shorthand for the And operation and we need to hide it for
+% \TeX{}. This group is closed after \cs{@@_get_next:NN} returns
+% \cs{c_true_bool} or \cs{c_false_bool}. That function requires the
+% trailing parenthesis to know where the expression ends.
+% \begin{macrocode}
+\cs_new:Npn \bool_if_p:n { \exp_args:Nf \@@_if_p:n }
+\cs_new:Npn \@@_if_p:n #1
+ {
+ \tl_if_empty:oT { \use_none:nn #1 . } { \@@_if_p_aux:w }
+ \group_align_safe_begin:
+ \exp_after:wN
+ \group_align_safe_end:
+ \exp:w \exp_end_continue_f:w % (
+ \@@_get_next:NN \use_i:nnnn #1 )
+ }
+\cs_new:Npn \@@_if_p_aux:w #1 \use_i:nnnn #2#3
+ { \bool_if:NTF #2 \c_true_bool \c_false_bool }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_get_next:NN}
+% The GetNext operation. Its first argument is \cs{use_i:nnnn},
+% \cs{use_ii:nnnn}, \cs{use_iii:nnnn}, or \cs{use_iv:nnnn} (we call
+% these \enquote{states}). In the first state, this function
+% eventually expand to the truth value \cs{c_true_bool} or
+% \cs{c_false_bool} of the expression which follows until the next
+% unmatched closing parenthesis. For instance
+% \enquote{\cs{@@_get_next:NN} \cs{use_i:nnnn} \cs{c_true_bool}
+% \texttt{\&\&} \cs{c_true_bool} \texttt{)}} (including the closing
+% parenthesis) expands to \cs{c_true_bool}. In the second state
+% (after a |!|) the logic is reversed. We call these two states
+% \enquote{normal} and the next two \enquote{skipping}. In the third
+% state (after \cs{c_true_bool}\verb"||") it always returns
+% \cs{c_true_bool}. In the fourth state (after \cs{c_false_bool}|&&|)
+% it always returns \cs{c_false_bool} and also stops when encountering
+% \verb"||", not only parentheses. This code itself is a switch: if
+% what follows is neither |!| nor |(|, we assume it is a predicate.
+% \begin{macrocode}
+\cs_new:Npn \@@_get_next:NN #1#2
+ {
+ \use:c
+ {
+ @@_
+ \if_meaning:w !#2 ! \else: \if_meaning:w (#2 ( \else: p \fi: \fi:
+ :Nw
+ }
+ #1 #2
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_!:Nw}
+% The Not operation reverses the logic: it discards the |!|~token and
+% calls the GetNext operation with the appropriate first argument.
+% Namely the first and second states are interchanged, but after
+% \cs{c_true_bool}\verb"||" or \cs{c_false_bool}|&&| the |!|~is
+% ignored.
+% \begin{macrocode}
+\cs_new:cpn { @@_!:Nw } #1#2
+ {
+ \exp_after:wN \@@_get_next:NN
+ #1 \use_ii:nnnn \use_i:nnnn \use_iii:nnnn \use_iv:nnnn
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_(:Nw}
+% The Open operation starts a sub-expression after discarding the open
+% parenthesis. This is done by calling GetNext (which eventually
+% discards the corresponding closing parenthesis), with a
+% post-processing step which looks for And, Or or Close after the
+% group.
+% \begin{macrocode}
+\cs_new:cpn { @@_(:Nw } #1#2
+ {
+ \exp_after:wN \@@_choose:NNN \exp_after:wN #1
+ \int_value:w \@@_get_next:NN \use_i:nnnn
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_p:Nw}
+% If what follows GetNext is neither |!| nor |(|, evaluate the
+% predicate using the primitive \cs{int_value:w}. The canonical
+% \texttt{true} and \texttt{false} values have numerical values $1$
+% and $0$ respectively. Look for And, Or or Close afterwards.
+% \begin{macrocode}
+\cs_new:cpn { @@_p:Nw } #1
+ { \exp_after:wN \@@_choose:NNN \exp_after:wN #1 \int_value:w }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_choose:NNN}
+% \begin{macro}+\@@_)_0:+
+% \begin{macro}+\@@_)_1:+
+% \begin{macro}+\@@_)_2:+
+% \begin{macro}+\@@_&_0:+
+% \begin{macro}+\@@_&_1:+
+% \begin{macro}+\@@_&_2:+
+% \begin{macro}+\@@_|_0:+
+% \begin{macro}+\@@_|_1:+
+% \begin{macro}+\@@_|_2:+
+% The arguments are |#1|: a function such as \cs{use_i:nnnn}, |#2|:
+% $0$ or $1$ encoding the current truth value, |#3|: the next
+% operation, And, Or or Close. We distinguish three cases according
+% to a combination of |#1| and |#2|. Case~2 is when |#1| is
+% \cs{use_iii:nnnn} (state~3), namely after
+% \cs{c_true_bool}~\verb"||". Case~1 is when |#1| is \cs{use_i:nnnn}
+% and |#2| is \texttt{true} or when |#1| is \cs{use_ii:nnnn} and |#2|
+% is \texttt{false}, for instance for |!|\cs{c_false_bool}. Case~0
+% includes the same with \texttt{true}/\texttt{false} interchanged and
+% the case where |#1| is \cs{use_iv:nnnn} namely after
+% \cs{c_false_bool}~|&&|.
+%
+% When seeing~|)| the current subexpression is done, leave the
+% appropriate boolean. When seeing~|&| in case~0 go into state~4,
+% equivalent to having seen \cs{c_false_bool}~|&&|. In case~1, namely
+% when the argument is \texttt{true} and we are in a normal state
+% continue in the normal state~1. In case~2, namely when skipping
+% alternatives in an Or, continue in the same state. When
+% seeing~\verb"|" in case~0, continue in a normal state; in particular
+% stop skipping for \cs{c_false_bool}~|&&| because that binds more
+% tightly than~\verb"||". In the other two cases start skipping for
+% \cs{c_true_bool}~\verb"||".
+% \begin{macrocode}
+\cs_new:Npn \@@_choose:NNN #1#2#3
+ {
+ \use:c
+ {
+ @@_ \token_to_str:N #3 _
+ #1 #2 { \if_meaning:w 0 #2 1 \else: 0 \fi: } 2 0 :
+ }
+ }
+\cs_new:cpn { @@_)_0: } { \c_false_bool }
+\cs_new:cpn { @@_)_1: } { \c_true_bool }
+\cs_new:cpn { @@_)_2: } { \c_true_bool }
+\cs_new:cpn { @@_&_0: } & { \@@_get_next:NN \use_iv:nnnn }
+\cs_new:cpn { @@_&_1: } & { \@@_get_next:NN \use_i:nnnn }
+\cs_new:cpn { @@_&_2: } & { \@@_get_next:NN \use_iii:nnnn }
+\cs_new:cpn { @@_|_0: } | { \@@_get_next:NN \use_i:nnnn }
+\cs_new:cpn { @@_|_1: } | { \@@_get_next:NN \use_iii:nnnn }
+\cs_new:cpn { @@_|_2: } | { \@@_get_next:NN \use_iii:nnnn }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\bool_lazy_all:n}
+% \begin{macro}{\@@_lazy_all:n}
+% \UnitTested
+% Go through the list of expressions, stopping whenever an expression
+% is \texttt{false}. If the end is reached without finding any
+% \texttt{false} expression, then the result is \texttt{true}.
+% \begin{macrocode}
+\cs_new:Npn \bool_lazy_all_p:n #1
+ { \@@_lazy_all:n #1 \q_@@_recursion_tail \q_@@_recursion_stop }
+\prg_new_conditional:Npnn \bool_lazy_all:n #1 { T , F , TF }
+ {
+ \if_predicate:w \bool_lazy_all_p:n {#1}
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:Npn \@@_lazy_all:n #1
+ {
+ \@@_if_recursion_tail_stop_do:nn {#1} { \c_true_bool }
+ \bool_if:nF {#1}
+ { \@@_use_i_delimit_by_q_recursion_stop:nw { \c_false_bool } }
+ \@@_lazy_all:n
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\bool_lazy_and:nn}
+% \UnitTested
+% Only evaluate the second expression if the first is \texttt{true}.
+% Note that |#2| must be removed as an argument, not just by skipping
+% to the \cs{else:} branch of the conditional since |#2| may contain
+% unbalanced \TeX{} conditionals.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \bool_lazy_and:nn #1#2 { p , T , F , TF }
+ {
+ \if_predicate:w
+ \bool_if:nTF {#1} { \bool_if_p:n {#2} } { \c_false_bool }
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\bool_lazy_any:n}
+% \begin{macro}{\@@_lazy_any:n}
+% \UnitTested
+% Go through the list of expressions, stopping whenever an expression
+% is \texttt{true}. If the end is reached without finding any
+% \texttt{true} expression, then the result is \texttt{false}.
+% \begin{macrocode}
+\cs_new:Npn \bool_lazy_any_p:n #1
+ { \@@_lazy_any:n #1 \q_@@_recursion_tail \q_@@_recursion_stop }
+\prg_new_conditional:Npnn \bool_lazy_any:n #1 { T , F , TF }
+ {
+ \if_predicate:w \bool_lazy_any_p:n {#1}
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:Npn \@@_lazy_any:n #1
+ {
+ \@@_if_recursion_tail_stop_do:nn {#1} { \c_false_bool }
+ \bool_if:nT {#1}
+ { \@@_use_i_delimit_by_q_recursion_stop:nw { \c_true_bool } }
+ \@@_lazy_any:n
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\bool_lazy_or:nn}
+% \UnitTested
+% Only evaluate the second expression if the first is \texttt{false}.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \bool_lazy_or:nn #1#2 { p , T , F , TF }
+ {
+ \if_predicate:w
+ \bool_if:nTF {#1} { \c_true_bool } { \bool_if_p:n {#2} }
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\bool_not_p:n}
+% \UnitTested
+% The Not variant just reverses the outcome of \cs{bool_if_p:n}. Can
+% be optimized but this is nice and simple and according to the
+% implementation plan. Not even particularly useful to have it when
+% the infix notation is easier to use.
+% \begin{macrocode}
+\cs_new:Npn \bool_not_p:n #1 { \bool_if_p:n { ! ( #1 ) } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\bool_xor:nn}
+% \UnitTested
+% Exclusive or. If the boolean expressions have same truth value,
+% return \texttt{false}, otherwise return \texttt{true}.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \bool_xor:nn #1#2 { p , T , F , TF }
+ {
+ \bool_if:nT {#1} \reverse_if:N
+ \if_predicate:w \bool_if_p:n {#2}
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Logical loops}
+%
+% \begin{macro}{\bool_while_do:Nn, \bool_while_do:cn}
+% \UnitTested
+% \begin{macro}{\bool_until_do:Nn, \bool_until_do:cn}
+% \UnitTested
+% A |while| loop where the boolean is tested before executing the
+% statement. The \enquote{while} version executes the code as long as the
+% boolean is true; the \enquote{until} version executes the code as
+% long as the boolean is false.
+% \begin{macrocode}
+\cs_new:Npn \bool_while_do:Nn #1#2
+ { \bool_if:NT #1 { #2 \bool_while_do:Nn #1 {#2} } }
+\cs_new:Npn \bool_until_do:Nn #1#2
+ { \bool_if:NF #1 { #2 \bool_until_do:Nn #1 {#2} } }
+\cs_generate_variant:Nn \bool_while_do:Nn { c }
+\cs_generate_variant:Nn \bool_until_do:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\bool_do_while:Nn, \bool_do_while:cn}
+% \UnitTested
+% \begin{macro}{\bool_do_until:Nn, \bool_do_until:cn}
+% \UnitTested
+% A |do-while| loop where the body is performed at least once and the
+% boolean is tested after executing the body. Otherwise identical to
+% the above functions.
+% \begin{macrocode}
+\cs_new:Npn \bool_do_while:Nn #1#2
+ { #2 \bool_if:NT #1 { \bool_do_while:Nn #1 {#2} } }
+\cs_new:Npn \bool_do_until:Nn #1#2
+ { #2 \bool_if:NF #1 { \bool_do_until:Nn #1 {#2} } }
+\cs_generate_variant:Nn \bool_do_while:Nn { c }
+\cs_generate_variant:Nn \bool_do_until:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \bool_while_do:nn, \bool_do_while:nn ,
+% \bool_until_do:nn, \bool_do_until:nn
+% }
+% \UnitTested
+% Loop functions with the test either before or after the first body
+% expansion.
+% \begin{macrocode}
+\cs_new:Npn \bool_while_do:nn #1#2
+ {
+ \bool_if:nT {#1}
+ {
+ #2
+ \bool_while_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \bool_do_while:nn #1#2
+ {
+ #2
+ \bool_if:nT {#1} { \bool_do_while:nn {#1} {#2} }
+ }
+\cs_new:Npn \bool_until_do:nn #1#2
+ {
+ \bool_if:nF {#1}
+ {
+ #2
+ \bool_until_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \bool_do_until:nn #1#2
+ {
+ #2
+ \bool_if:nF {#1} { \bool_do_until:nn {#1} {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\s_@@_mark,\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP, noTF]{\bool_case:n}
+% \begin{macro}{\@@_case:NnTF}
+% \begin{macro}{\@@_case:w,a\@@_case_end:nw}
+% For boolean cases the overall idea is the same as for
+% \cs{str_case:nnTF} as described in \pkg{l3str}.
+% \begin{macrocode}
+\cs_new:Npn \bool_case:nTF
+ { \exp:w \@@_case:nTF }
+\cs_new:Npn \bool_case:nT #1#2
+ { \exp:w \@@_case:nTF {#1} {#2} { } }
+\cs_new:Npn \bool_case:nF #1
+ { \exp:w \@@_case:nTF {#1} { } }
+\cs_new:Npn \bool_case:n #1
+ { \exp:w \@@_case:nTF {#1} { } { } }
+\cs_new:Npn \@@_case:nTF #1#2#3
+ {
+ \@@_case:w
+ #1 \c_true_bool { } \s_@@_mark {#2} \s_@@_mark {#3} \s_@@_stop
+ }
+\cs_new:Npn \@@_case:w #1#2
+ {
+ \bool_if:nTF {#1}
+ { \@@_case_end:nw {#2} }
+ { \@@_case:w }
+ }
+\cs_new:Npn \@@_case_end:nw #1#2#3 \s_@@_mark #4#5 \s_@@_stop
+ { \exp_end: #1 #4 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Producing multiple copies}
+%
+% \begin{macrocode}
+%<@@=prg>
+% \end{macrocode}
+%
+% \begin{macro}{\prg_replicate:nn}
+% \UnitTested
+% \begin{macro}{\@@_replicate:N, \@@_replicate_first:N}
+% \begin{macro}{\@@_replicate_}
+% \begin{macro}
+% {
+% \@@_replicate_0:n,
+% \@@_replicate_1:n,
+% \@@_replicate_2:n,
+% \@@_replicate_3:n,
+% \@@_replicate_4:n,
+% \@@_replicate_5:n,
+% \@@_replicate_6:n,
+% \@@_replicate_7:n,
+% \@@_replicate_8:n,
+% \@@_replicate_9:n
+% }
+% \begin{macro}
+% {
+% \@@_replicate_first_-:n,
+% \@@_replicate_first_0:n,
+% \@@_replicate_first_1:n,
+% \@@_replicate_first_2:n,
+% \@@_replicate_first_3:n,
+% \@@_replicate_first_4:n,
+% \@@_replicate_first_5:n,
+% \@@_replicate_first_6:n,
+% \@@_replicate_first_7:n,
+% \@@_replicate_first_8:n,
+% \@@_replicate_first_9:n
+% }
+% This function uses a cascading csname technique by David Kastrup
+% (who else :-)
+%
+% The idea is to make the input |25| result in first adding five, and
+% then 20 copies of the code to be replicated. The technique uses
+% cascading csnames which means that we start building several csnames
+% so we end up with a list of functions to be called in reverse
+% order. This is important here (and other places) because it means
+% that we can for instance make the function that inserts five copies
+% of something to also hand down ten to the next function in
+% line. This is exactly what happens here: in the example with |25|
+% then the next function is the one that inserts two copies but it
+% sees the ten copies handed down by the previous function. In order
+% to avoid the last function to insert say, $100$ copies of the original
+% argument just to gobble them again we define separate functions to
+% be inserted first. These functions also close the expansion of
+% \cs{exp:w}, which ensures that \cs{prg_replicate:nn} only
+% requires two steps of expansion.
+%
+% This function has one flaw though: Since it constantly passes down
+% ten copies of its previous argument it severely affects the main
+% memory once you start demanding hundreds of thousands of copies. Now
+% I don't think this is a real limitation for any ordinary use, and if
+% necessary, it is possible to write \cs{prg_replicate:nn} |{1000}|
+% |{| \cs{prg_replicate:nn} |{1000}| \Arg{code}~|}|. An
+% alternative approach is to create a string of |m|'s with
+% \cs{exp:w} which can be done with just four macros but that
+% method has its own problems since it can exhaust the string
+% pool. Also, it is considerably slower than what we use here so the
+% few extra csnames are well spent I would say.
+% \begin{macrocode}
+\cs_new:Npn \prg_replicate:nn #1
+ {
+ \exp:w
+ \exp_after:wN \@@_replicate_first:N
+ \int_value:w \int_eval:n {#1}
+ \cs_end:
+ }
+\cs_new:Npn \@@_replicate:N #1
+ { \cs:w @@_replicate_#1 :n \@@_replicate:N }
+\cs_new:Npn \@@_replicate_first:N #1
+ { \cs:w @@_replicate_first_ #1 :n \@@_replicate:N }
+% \end{macrocode}
+% Then comes all the functions that do the hard work of inserting all
+% the copies. The first function takes |:n| as a parameter.
+% \begin{macrocode}
+\cs_new:Npn \@@_replicate_ :n #1 { \cs_end: }
+\cs_new:cpn { @@_replicate_0:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} }
+\cs_new:cpn { @@_replicate_1:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1 }
+\cs_new:cpn { @@_replicate_2:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1 }
+\cs_new:cpn { @@_replicate_3:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1 }
+\cs_new:cpn { @@_replicate_4:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1 }
+\cs_new:cpn { @@_replicate_5:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1 }
+\cs_new:cpn { @@_replicate_6:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1#1 }
+\cs_new:cpn { @@_replicate_7:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1#1#1 }
+\cs_new:cpn { @@_replicate_8:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1#1#1#1 }
+\cs_new:cpn { @@_replicate_9:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1#1#1#1#1 }
+% \end{macrocode}
+% Users shouldn't ask for something to be replicated once or even
+% not at all but\dots
+% \begin{macrocode}
+\cs_new:cpn { @@_replicate_first_-:n } #1
+ {
+ \exp_end:
+ \msg_expandable_error:nn { prg } { negative-replication }
+ }
+\cs_new:cpn { @@_replicate_first_0:n } #1 { \exp_end: }
+\cs_new:cpn { @@_replicate_first_1:n } #1 { \exp_end: #1 }
+\cs_new:cpn { @@_replicate_first_2:n } #1 { \exp_end: #1#1 }
+\cs_new:cpn { @@_replicate_first_3:n } #1 { \exp_end: #1#1#1 }
+\cs_new:cpn { @@_replicate_first_4:n } #1 { \exp_end: #1#1#1#1 }
+\cs_new:cpn { @@_replicate_first_5:n } #1 { \exp_end: #1#1#1#1#1 }
+\cs_new:cpn { @@_replicate_first_6:n } #1 { \exp_end: #1#1#1#1#1#1 }
+\cs_new:cpn { @@_replicate_first_7:n } #1 { \exp_end: #1#1#1#1#1#1#1 }
+\cs_new:cpn { @@_replicate_first_8:n } #1 { \exp_end: #1#1#1#1#1#1#1#1 }
+\cs_new:cpn { @@_replicate_first_9:n } #1
+ { \exp_end: #1#1#1#1#1#1#1#1#1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Detecting \TeX{}'s mode}
+%
+% \begin{macro}[pTF]{\mode_if_vertical:}
+% \UnitTested
+% For testing vertical mode. Strikes me here on the bus with David,
+% that as long as we are just talking about returning true and
+% false states, we can just use the primitive conditionals for this
+% and gobbling the \cs{exp_end:} in the input stream. However this
+% requires knowledge of the implementation so we keep things nice
+% and clean and use the return statements.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \mode_if_vertical: { p , T , F , TF }
+ { \if_mode_vertical: \prg_return_true: \else: \prg_return_false: \fi: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\mode_if_horizontal:}
+% \UnitTested
+% For testing horizontal mode.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \mode_if_horizontal: { p , T , F , TF }
+ { \if_mode_horizontal: \prg_return_true: \else: \prg_return_false: \fi: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\mode_if_inner:}
+% \UnitTested
+% For testing inner mode.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \mode_if_inner: { p , T , F , TF }
+ { \if_mode_inner: \prg_return_true: \else: \prg_return_false: \fi: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\mode_if_math:}
+% \UnitTested
+% For testing math mode. At the beginning of an alignment cell,
+% this should be used only inside a non-expandable function.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \mode_if_math: { p , T , F , TF }
+ { \if_mode_math: \prg_return_true: \else: \prg_return_false: \fi: }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Internal programming functions}
+%
+% \begin{macro}{\group_align_safe_begin:, \group_align_safe_end:}
+% \TeX{}'s alignment structures present many problems. As Knuth says
+% himself in \emph{\TeX : The Program}: \enquote{It's sort of a miracle
+% whenever \tn{halign} or \tn{valign} work, [\ldots]} One problem relates
+% to commands that internally issue a \tn{cr} but also peek ahead for
+% the next character for use in, say, an optional argument. If the
+% next token happens to be a |&| with category code~4 we get some
+% sort of weird error message because the underlying
+% \tn{futurelet} stores the token at the end of the alignment
+% template. This could be a |&|$_4$ giving a message like
+% |! Misplaced \cr.| or even worse: it could be the \tn{endtemplate}
+% token causing even more trouble! To solve this we have to open a
+% special group so that \TeX{} still thinks it's on safe ground but at
+% the same time we don't want to introduce any brace group that may
+% find its way to the output. The following functions help with this
+% by using behaviour documented only in Appendix~D of
+% \emph{The \TeX{}book}\dots
+% In short evaluating |`{| and |`}| as numbers will not change the counter
+% \TeX{} uses to keep track of its state in an alignment, whereas gobbling a
+% brace using \cs{if_false:} will affect \TeX's state without producing any
+% real group.
+% We place the \cs{if_false:} |{| \cs{fi:} part at that place so
+% that the successive expansions of \cs{group_align_safe_begin/end:}
+% are always brace balanced.
+% \begin{macrocode}
+\group_begin:
+\tex_catcode:D `\^^@ = 2 \exp_stop_f:
+\cs_new:Npn \group_align_safe_begin:
+ { \exp:w \if_false: { \fi: `^^@ \exp_stop_f: }
+\tex_catcode:D `\^^@ = 1 \exp_stop_f:
+\cs_new:Npn \group_align_safe_end:
+ { \exp:w `^^@ \if_false: } \fi: \exp_stop_f: }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g__kernel_prg_map_int}
+% A nesting counter for mapping.
+% \begin{macrocode}
+\int_new:N \g__kernel_prg_map_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\prg_break_point:Nn}
+% \begin{macro}{\prg_map_break:Nn}
+% These are defined in \pkg{l3basics}, as they are needed
+% \enquote{early}. This is just a reminder that is the case!
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prg_break_point:}
+% \begin{macro}{\prg_break:, \prg_break:n}
+% Also done in \pkg{l3basics}.
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3prop.dtx b/macros/latex-dev/required/l3kernel/l3prop.dtx
new file mode 100644
index 0000000000..6d8054e956
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3prop.dtx
@@ -0,0 +1,2602 @@
+% \iffalse meta-comment
+%
+%% File: l3prop.dtx
+%
+% Copyright (C) 1990-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3prop} module\\ Property lists^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \pkg{expl3} implements a \enquote{property list} data type, which contain
+% an unordered list of entries each of which consists of a \meta{key} (string)
+% and an associated \meta{value} (token list). The \meta{key} and \meta{value}
+% may both be given as any balanced text, and the \meta{key} is processed using
+% \cs{tl_to_str:n}, meaning that category codes are ignored. Entries can be
+% manipulated individually, as well as collectively by applying a function to
+% every key--value pair within the list.
+%
+% Each entry in a property list must have a unique \meta{key}: if an entry is
+% added to a property list which already contains the \meta{key} then the new
+% entry overwrites the existing one. The \meta{keys} are compared on a
+% string basis, using the same method as \cs{str_if_eq:nnTF}.
+%
+% Property lists are intended for storing key-based information for use within
+% code. They can be converted from and to key--value lists, which are a form of
+% \emph{input} parsed by the \pkg{l3keys} module. If a key--value list contains
+% a \meta{key} multiple times, only the last \meta{value} associated to it will
+% be kept in the conversion to a property list.
+%
+% Internally, property lists can use two distinct implementations with different
+% data storage, which are decided when declaring the property list variable
+% using \cs{prop_new:N} (\enquote{flat} storage) or \cs{prop_new_linked:N}
+% (\enquote{linked} storage). After a property list is declared with
+% \cs{prop_new:N} or \cs{prop_new_linked:N}, the type of internal data storage
+% can be changed by \cs{prop_make_flat:N} or \cs{prop_make_linked:N}, but only
+% at the outermost group level. All other \pkg{l3prop} functions transparently
+% manipulate either storage method and convert as needed.
+% \begin{itemize}
+% \item
+% The (default) \enquote{flat} storage method is suited for a relatively
+% small number of entries, or when the property list is likely to be
+% manipulated (copied, mapped) as a whole rather than entry-wise. It is
+% significantly faster for \cs{prop_set_eq:NN}, and only slightly faster for
+% \cs{prop_clear:N}, \cs{prop_concat:NNN}, and mapping functions
+% \cs[no-index]{prop_map_\ldots{}}.
+%
+% \item
+% The \enquote{linked} storage method is meant for property lists with a
+% large numbers of entries. It takes up more of \TeX{}'s memory during a run, but is
+% significantly faster (for long lists) when accessing or modifying
+% individual entries using functions such as \cs{prop_if_in:Nn},
+% \cs{prop_item:Nn}, \cs{prop_put:Nnn}, \cs{prop_get:NnN},
+% \cs{prop_pop:NnN}, \cs{prop_remove:Nn}, as it takes a constant
+% time for these operations (rather than the number of items for a
+% \enquote{flat} property list). A technical drawback is that
+% memory is permanently used\footnote{Until the end of the run, that
+% is.} by \meta{keys} stored in a \enquote{linked} property list,
+% even after they are removed and the property list is deleted.
+% \end{itemize}
+%
+% \section{Creating and initialising property lists}
+%
+% \begin{function}{\prop_new:N, \prop_new:c}
+% \begin{syntax}
+% \cs{prop_new:N} \meta{property list}
+% \end{syntax}
+% Creates a new \enquote{flat} \meta{property list} or raises an error if the
+% name is already taken. The declaration is global. The \meta{property list}
+% initially contains no entries. See also \cs{prop_new_linked:N}.
+% \end{function}
+%
+% \begin{function}[added = 2024-02-12]{\prop_new_linked:N, \prop_new_linked:c}
+% \begin{syntax}
+% \cs{prop_new_linked:N} \meta{property list}
+% \end{syntax}
+% Creates a new \enquote{linked} \meta{property list} or raises an error if
+% the name is already taken. The declaration is global. The \meta{property
+% list} initially contains no entries. The internal data storage differs from
+% that produced by \cs{prop_new:N} and it is optimized for property lists with
+% a large number of entries.
+% \end{function}
+%
+% \begin{function}
+% {\prop_clear:N, \prop_clear:c, \prop_gclear:N, \prop_gclear:c}
+% \begin{syntax}
+% \cs{prop_clear:N} \meta{property list}
+% \end{syntax}
+% Clears all entries from the \meta{property list}.
+% \end{function}
+%
+% \begin{function}
+% {
+% \prop_clear_new:N, \prop_clear_new:c,
+% \prop_gclear_new:N, \prop_gclear_new:c
+% }
+% \begin{syntax}
+% \cs{prop_clear_new:N} \meta{property list}
+% \end{syntax}
+% Ensures that the \meta{property list} exists globally by applying
+% \cs{prop_new:N} if necessary, then applies
+% \cs[index=prop_clear:N]{prop_(g)clear:N} to leave the list empty.
+% \begin{texnote}
+% If the property list exists and is of \enquote{linked} type, it
+% is cleared but not made into a flat property list.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2024-02-12]
+% {
+% \prop_clear_new_linked:N, \prop_clear_new_linked:c,
+% \prop_gclear_new_linked:N, \prop_gclear_new_linked:c
+% }
+% \begin{syntax}
+% \cs{prop_clear_new_linked:N} \meta{property list}
+% \end{syntax}
+% Ensures that the \meta{property list} exists globally by applying
+% \cs{prop_new_linked:N} if necessary, then applies
+% \cs[index=prop_clear:N]{prop_(g)clear:N} to leave the list empty.
+% \begin{texnote}
+% If the property list exists and is of \enquote{flat} type, it
+% is cleared but not made into a linked property list.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}
+% {
+% \prop_set_eq:NN, \prop_set_eq:cN, \prop_set_eq:Nc, \prop_set_eq:cc,
+% \prop_gset_eq:NN, \prop_gset_eq:cN, \prop_gset_eq:Nc, \prop_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{prop_set_eq:NN} \meta{property list_1} \meta{property list_2}
+% \end{syntax}
+% Sets the content of \meta{property list_1} equal to that of \meta{property
+% list_2}. This converts as needed between the two storage types.
+% \end{function}
+%
+% \begin{function}[added = 2017-11-28, updated = 2021-11-07]
+% {
+% \prop_set_from_keyval:Nn, \prop_set_from_keyval:cn,
+% \prop_gset_from_keyval:Nn, \prop_gset_from_keyval:cn,
+% }
+% \begin{syntax}
+% \cs{prop_set_from_keyval:Nn} \meta{property list}
+% \{
+% \meta{key1} |=| \meta{value1} |,|
+% \meta{key2} |=| \meta{value2} |,| \ldots{}
+% \}
+% \end{syntax}
+% Sets \meta{property list} to contain key--value pairs given in the second
+% argument. If duplicate keys appear only the last of the values is kept.
+% In contrast to most keyval lists (\emph{e.g.}~those in \pkg{l3keys}), each
+% key here \emph{must} be followed with an \texttt{=} sign even to specify an
+% empty \meta{value}.
+%
+% Spaces are trimmed around every \meta{key} and every \meta{value},
+% and if the result of trimming spaces consists of a single brace
+% group then a set of outer braces is removed. This enables both the
+% \meta{key} and the \meta{value} to contain spaces, commas or equal
+% signs. The \meta{key} is then processed by \cs{tl_to_str:n}.
+% This function correctly detects the |=| and |,| signs provided they
+% have the standard category code~$12$ or they are active.
+% \end{function}
+%
+% \begin{function}[added = 2017-11-28, updated = 2021-11-07]
+% {\prop_const_from_keyval:Nn, \prop_const_from_keyval:cn}
+% \begin{syntax}
+% \cs{prop_const_from_keyval:Nn} \meta{property list}
+% \{
+% \meta{key1} |=| \meta{value1} |,|
+% \meta{key2} |=| \meta{value2} |,| \ldots{}
+% \}
+% \end{syntax}
+% Creates a new constant \enquote{flat} \meta{property list} or raises
+% an error if the
+% name is already taken. The \meta{property list} is set globally to
+% contain key--value pairs given in the second argument, processed in
+% the way described for \cs{prop_set_from_keyval:Nn}. If duplicate
+% keys appear only the last of the values is kept.
+% This function correctly detects the |=| and |,| signs provided they
+% have the standard category code~$12$ or they are active.
+% \end{function}
+%
+% \begin{function}[added = 2024-02-12]
+% {\prop_const_linked_from_keyval:Nn, \prop_const_linked_from_keyval:cn}
+% \begin{syntax}
+% \cs{prop_const_linked_from_keyval:Nn} \meta{prop~var}
+% \{
+% \meta{key1} |=| \meta{value1} |,|
+% \meta{key2} |=| \meta{value2} |,| \ldots{}
+% \}
+% \end{syntax}
+% Creates a new constant \enquote{linked} \meta{prop~var} or raises an
+% error if the
+% name is already taken. The \meta{prop~var} is set globally to
+% contain key--value pairs given in the second argument, processed in
+% the way described for \cs{prop_set_from_keyval:Nn}. If duplicate
+% keys appear only the last of the values is kept.
+% This function correctly detects the |=| and |,| signs provided they
+% have the standard category code~$12$ or they are active.
+% \end{function}
+%
+% \begin{function}[added = 2024-02-12]{\prop_make_flat:N, \prop_make_flat:c}
+% \begin{syntax}
+% \cs{prop_make_flat:N} \meta{property list}
+% \end{syntax}
+% Changes the internal storage type of the \meta{property list} to be
+% the same \enquote{flat} storage as \cs{prop_new:N}. The key--value
+% pairs of the \meta{property list} are preserved by the change. If
+% the property list was already flat then nothing is done. This
+% function can only be used at the outermost group level.
+% \end{function}
+%
+% \begin{function}[added = 2024-02-12]{\prop_make_linked:N, \prop_make_linked:c}
+% \begin{syntax}
+% \cs{prop_make_linked:N} \meta{property list}
+% \end{syntax}
+% Changes the internal storage type of the \meta{property list} to be
+% the same \enquote{linked} storage as \cs{prop_new_linked:N}. The
+% key--value pairs of the \meta{property list} are preserved by the
+% change. If the property list was already linked then nothing is
+% done. This function can only be used at the outermost group level.
+% \end{function}
+%
+% \section{Adding and updating property list entries}
+%
+% \begin{function}[updated = 2012-07-09]
+% {
+% \prop_put:Nnn, \prop_put:NnV, \prop_put:Nnv, \prop_put:Nne,
+% \prop_put:NVn, \prop_put:NVV, \prop_put:NVv, \prop_put:NVe,
+% \prop_put:Nvn, \prop_put:NvV, \prop_put:Nvv, \prop_put:Nve,
+% \prop_put:Nen, \prop_put:NeV, \prop_put:Nev, \prop_put:Nee,
+% \prop_put:Nno, \prop_put:Non, \prop_put:Noo,
+% \prop_put:cnn, \prop_put:cnV, \prop_put:cnv, \prop_put:cne,
+% \prop_put:cVn, \prop_put:cVV, \prop_put:cVv, \prop_put:cVe,
+% \prop_put:cvn, \prop_put:cvV, \prop_put:cvv, \prop_put:cve,
+% \prop_put:cen, \prop_put:ceV, \prop_put:cev, \prop_put:cee,
+% \prop_put:cno, \prop_put:con, \prop_put:coo,
+% \prop_gput:Nnn, \prop_gput:NnV, \prop_gput:Nnv, \prop_gput:Nne,
+% \prop_gput:NVn, \prop_gput:NVV, \prop_gput:NVv, \prop_gput:NVe,
+% \prop_gput:Nvn, \prop_gput:NvV, \prop_gput:Nvv, \prop_gput:Nve,
+% \prop_gput:Nen, \prop_gput:NeV, \prop_gput:Nev, \prop_gput:Nee,
+% \prop_gput:Nno, \prop_gput:Non, \prop_gput:Noo,
+% \prop_gput:cnn, \prop_gput:cnV, \prop_gput:cnv, \prop_gput:cne,
+% \prop_gput:cVn, \prop_gput:cVV, \prop_gput:cVv, \prop_gput:cVe,
+% \prop_gput:cvn, \prop_gput:cvV, \prop_gput:cvv, \prop_gput:cve,
+% \prop_gput:cen, \prop_gput:ceV, \prop_gput:cev, \prop_gput:cee,
+% \prop_gput:cno, \prop_gput:con, \prop_gput:coo
+% }
+% \begin{syntax}
+% \cs{prop_put:Nnn} \meta{property list} \Arg{key} \Arg{value}
+% \end{syntax}
+% Adds an entry to the \meta{property list} which may be accessed
+% using the \meta{key} and which has \meta{value}. If the \meta{key}
+% is already present in the \meta{property list}, the existing entry
+% is overwritten by the new \meta{value}. Both the \meta{key} and
+% \meta{value} may contain any \meta{balanced text}. The \meta{key} is
+% stored after processing with \cs{tl_to_str:n}, meaning that category
+% codes are ignored.
+% \end{function}
+%
+% \begin{function}[added = 2024-03-30]
+% {
+% \prop_put_if_not_in:Nnn, \prop_put_if_not_in:NVn, \prop_put_if_not_in:NnV,
+% \prop_put_if_not_in:cnn, \prop_put_if_not_in:cVn, \prop_put_if_not_in:cnV,
+% \prop_gput_if_not_in:Nnn, \prop_gput_if_not_in:NVn, \prop_gput_if_not_in:NnV,
+% \prop_gput_if_not_in:cnn, \prop_gput_if_not_in:cVn, \prop_gput_if_not_in:cnV
+% }
+% \begin{syntax}
+% \cs{prop_put_if_not_in:Nnn} \meta{property list} \Arg{key} \Arg{value}
+% \end{syntax}
+% If the \meta{key} is present in the \meta{property list} then no
+% action is taken. Otherwise, a new entry is added as described for
+% \cs{prop_put:Nnn}.
+% \end{function}
+%
+% \begin{function}[added = 2021-05-16]
+% {
+% \prop_concat:NNN, \prop_concat:ccc,
+% \prop_gconcat:NNN, \prop_gconcat:ccc
+% }
+% \begin{syntax}
+% \cs{prop_concat:NNN} \meta{property list_1} \meta{property list_2} \meta{property list3}
+% \end{syntax}
+% Combines the key--value pairs of \meta{property list_2} and
+% \meta{property list_3}, and saves the result in \meta{property list_1}. If a
+% key appears in both \meta{property list_2} and \meta{property list_3} then the
+% last value, namely the value in \meta{property list_3} is kept.
+% This converts as needed between the two storage types.
+% \end{function}
+%
+% \begin{function}[added = 2021-05-16, updated = 2021-11-07]
+% {
+% \prop_put_from_keyval:Nn, \prop_put_from_keyval:cn,
+% \prop_gput_from_keyval:Nn, \prop_gput_from_keyval:cn,
+% }
+% \begin{syntax}
+% \cs{prop_put_from_keyval:Nn} \meta{property list}
+% \{
+% \meta{key1} |=| \meta{value1} |,|
+% \meta{key2} |=| \meta{value2} |,| \ldots{}
+% \}
+% \end{syntax}
+% Updates the \meta{property list} by adding entries for each key--value
+% pair given in the second argument. The addition is done through
+% \cs{prop_put:Nnn}, hence if the \meta{property list} already contains
+% some of the keys, the corresponding values are discarded and
+% replaced by those given in the key--value list. If duplicate keys
+% appear in the key--value list then only the last of the values is kept.
+%
+% The function is equivalent to storing the key--value pairs in a
+% temporary property list using \cs{prop_set_from_keyval:Nn}, then
+% combining \meta{property list} with the temporary variable using
+% \cs{prop_concat:NNN}. In particular, the \meta{keys} and
+% \meta{values} are space-trimmed and unbraced as described in
+% \cs{prop_set_from_keyval:Nn}.
+% This function correctly detects the |=| and |,| signs provided they
+% have the standard category code~$12$ or they are active.
+% \end{function}
+%
+% \section{Recovering values from property lists}
+%
+% \begin{function}[updated = 2011-08-28]
+% {
+% \prop_get:NnN, \prop_get:NVN, \prop_get:NvN, \prop_get:NeN,
+% \prop_get:NoN,
+% \prop_get:cnN, \prop_get:cVN, \prop_get:cvN, \prop_get:ceN,
+% \prop_get:coN,
+% \prop_get:cnc
+% }
+% \begin{syntax}
+% \cs{prop_get:NnN} \meta{property list} \Arg{key} \meta{tl var}
+% \end{syntax}
+% Recovers the \meta{value} stored with \meta{key} from the
+% \meta{property list}, and places this in the \meta{token list
+% variable}. If the \meta{key} is not found in the
+% \meta{property list} then the \meta{token list variable} is set
+% to the special marker \cs{q_no_value}. The \meta{token list
+% variable} is set within the current \TeX{} group. See also
+% \cs{prop_get:NnNTF}.
+% \end{function}
+%
+% \begin{function}[updated = 2011-08-18]
+% {
+% \prop_pop:NnN, \prop_pop:NVN,
+% \prop_pop:NoN,
+% \prop_pop:cnN, \prop_pop:cVN,
+% \prop_pop:coN
+% }
+% \begin{syntax}
+% \cs{prop_pop:NnN} \meta{property list} \Arg{key} \meta{tl var}
+% \end{syntax}
+% Recovers the \meta{value} stored with \meta{key} from the
+% \meta{property list}, and places this in the \meta{token list
+% variable}. If the \meta{key} is not found in the
+% \meta{property list} then the \meta{token list variable} is set
+% to the special marker \cs{q_no_value}. The \meta{key} and
+% \meta{value} are then deleted from the property list. Both
+% assignments are local. See also \cs{prop_pop:NnNTF}.
+% \end{function}
+%
+% \begin{function}[updated = 2011-08-18]
+% {
+% \prop_gpop:NnN, \prop_gpop:NVN,
+% \prop_gpop:NoN,
+% \prop_gpop:cnN, \prop_gpop:cVN,
+% \prop_gpop:coN
+% }
+% \begin{syntax}
+% \cs{prop_gpop:NnN} \meta{property list} \Arg{key} \meta{tl var}
+% \end{syntax}
+% Recovers the \meta{value} stored with \meta{key} from the
+% \meta{property list}, and places this in the \meta{token list
+% variable}. If the \meta{key} is not found in the
+% \meta{property list} then the \meta{token list variable} is set
+% to the special marker \cs{q_no_value}. The \meta{key} and
+% \meta{value} are then deleted from the property list.
+% The \meta{property list} is modified globally, while the assignment of
+% the \meta{token list variable} is local. See also \cs{prop_gpop:NnNTF}.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2014-07-17]
+% {
+% \prop_item:Nn, \prop_item:NV, \prop_item:Ne, \prop_item:No,
+% \prop_item:cn, \prop_item:cV, \prop_item:ce, \prop_item:co
+% }
+% \begin{syntax}
+% \cs{prop_item:Nn} \meta{property list} \Arg{key}
+% \end{syntax}
+% Expands to the \meta{value} corresponding to the \meta{key} in
+% the \meta{property list}. If the \meta{key} is missing, this has
+% an empty expansion.
+% \begin{texnote}
+% For \enquote{flat} property lists, this expandable function iterates
+% through every key--value pair and is therefore slower than a
+% non-expandable approach based on \cs{prop_get:NnN}.
+% (For \enquote{linked} property lists both functions are fast.)
+%
+% The result is returned within the \tn{unexpanded}
+% primitive (\cs{exp_not:n}), which means that the \meta{value}
+% does not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\prop_count:N, \prop_count:c}
+% \begin{syntax}
+% \cs{prop_count:N} \meta{property list}
+% \end{syntax}
+% Leaves the number of key--value pairs in the \meta{property list} in
+% the input stream as an \meta{integer denotation}.
+% \end{function}
+%
+% \begin{function}[EXP]{\prop_to_keyval:N}
+% \begin{syntax}
+% \cs{prop_to_keyval:N} \meta{property list}
+% \end{syntax}
+% Expands to the \meta{property list} in a key--value notation. Keep in mind
+% that a \meta{property list} is \emph{unordered}, while key--value interfaces
+% are not necessarily, so this cannot be used for arbitrary interfaces.
+% \begin{texnote}
+% The result is returned within the \tn{unexpanded} primitive
+% (\cs{exp_not:n}), which means that the key--value list does not expand
+% further when appearing in an \texttt{e}-type or \texttt{x}-type argument expansion.
+% It also needs exactly two steps of expansion.
+% \end{texnote}
+% \end{function}
+%
+% \section{Modifying property lists}
+%
+% \begin{function}[added = 2012-05-12]
+% {
+% \prop_remove:Nn, \prop_remove:NV, \prop_remove:Ne,
+% \prop_remove:cn, \prop_remove:cV, \prop_remove:ce,
+% \prop_gremove:Nn, \prop_gremove:NV, \prop_gremove:Ne,
+% \prop_gremove:cn, \prop_gremove:cV, \prop_gremove:ce,
+% }
+% \begin{syntax}
+% \cs{prop_remove:Nn} \meta{property list} \Arg{key}
+% \end{syntax}
+% Removes the entry listed under \meta{key} from the
+% \meta{property list}. If the \meta{key} is
+% not found in the \meta{property list} no change occurs,
+% \emph{i.e}~there is no need to test for the existence of a key before
+% deleting it.
+% \end{function}
+%
+% \section{Property list conditionals}
+%
+% \begin{function}[EXP, pTF, added = 2012-03-03]
+% {\prop_if_exist:N, \prop_if_exist:c}
+% \begin{syntax}
+% \cs{prop_if_exist_p:N} \meta{property list}
+% \cs{prop_if_exist:NTF} \meta{property list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{property list} is currently defined. This does not
+% check that the \meta{property list} really is a property list variable.
+% \end{function}
+%
+% \begin{function}[EXP, pTF]{\prop_if_empty:N, \prop_if_empty:c}
+% \begin{syntax}
+% \cs{prop_if_empty_p:N} \meta{property list}
+% \cs{prop_if_empty:NTF} \meta{property list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{property list} is empty (containing no entries).
+% \end{function}
+%
+% \begin{function}[EXP, pTF, updated = 2011-09-15]
+% {
+% \prop_if_in:Nn, \prop_if_in:NV, \prop_if_in:Ne, \prop_if_in:No,
+% \prop_if_in:cn, \prop_if_in:cV, \prop_if_in:ce, \prop_if_in:co
+% }
+% \begin{syntax}
+% \cs{prop_if_in_p:Nn} \meta{property list} \Arg{key}
+% \cs{prop_if_in:NnTF} \meta{property list} \Arg{key} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{key} is present in the \meta{property list},
+% making the comparison using the method described by \cs{str_if_eq:nnTF}.
+% \begin{texnote}
+% For \enquote{flat} property lists, this expandable function iterates
+% through every key--value pair and is therefore slower than a
+% non-expandable approach based on \cs{prop_get:NnNTF}.
+% (For \enquote{linked} property lists both functions are fast.)
+% \end{texnote}
+% \end{function}
+%
+% \section{Recovering values from property lists with branching}
+%
+% The functions in this section combine tests for the presence of a key
+% in a property list with recovery of the associated valued. This makes them
+% useful for cases where different code follows depending on the presence
+% or absence of a key in a property list. They offer increased readability
+% and performance over separate testing and recovery phases.
+%
+% \begin{function}[TF, updated = 2012-05-19]
+% {
+% \prop_get:NnN, \prop_get:NVN, \prop_get:NvN, \prop_get:NeN,
+% \prop_get:NoN,
+% \prop_get:cnN, \prop_get:cVN, \prop_get:cvN, \prop_get:ceN,
+% \prop_get:coN,
+% \prop_get:cnc
+% }
+% \begin{syntax}
+% \cs{prop_get:NnNTF} \meta{property list} \Arg{key} \meta{token list variable} \\
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{key} is not present in the \meta{property list}, leaves
+% the \meta{false code} in the input stream. The value of the
+% \meta{token list variable} is not defined in this case and should
+% not be relied upon. If the \meta{key} is present in the
+% \meta{property list}, stores the corresponding \meta{value} in the
+% \meta{token list variable} without removing it from the
+% \meta{property list}, then leaves the \meta{true code} in the input
+% stream. The \meta{token list variable} is assigned locally.
+% \end{function}
+%
+% \begin{function}[TF, added = 2011-08-18, updated = 2012-05-19]
+% {
+% \prop_pop:NnN, \prop_pop:NVN,
+% \prop_pop:NoN,
+% \prop_pop:cnN, \prop_pop:cVN,
+% \prop_pop:coN
+% }
+% \begin{syntax}
+% \cs{prop_pop:NnNTF} \meta{property list} \Arg{key} \meta{token list variable} \\
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{key} is not present in the \meta{property list}, leaves
+% the \meta{false code} in the input stream. The value of the
+% \meta{token list variable} is not defined in this case and should
+% not be relied upon. If the \meta{key} is present in
+% the \meta{property list}, pops the corresponding \meta{value}
+% in the \meta{token list variable}, \emph{i.e.}~removes the item from
+% the \meta{property list}.
+% Both the \meta{property list} and the \meta{token list variable}
+% are assigned locally.
+% \end{function}
+%
+% \begin{function}[TF, added = 2011-08-18, updated = 2012-05-19]
+% {
+% \prop_gpop:NnN, \prop_gpop:NVN,
+% \prop_gpop:NoN,
+% \prop_gpop:cnN, \prop_gpop:cVN,
+% \prop_gpop:coN
+% }
+% \begin{syntax}
+% \cs{prop_gpop:NnNTF} \meta{property list} \Arg{key} \meta{token list variable} \\
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{key} is not present in the \meta{property list}, leaves
+% the \meta{false code} in the input stream. The value of the
+% \meta{token list variable} is not defined in this case and should
+% not be relied upon. If the \meta{key} is present in
+% the \meta{property list}, pops the corresponding \meta{value}
+% in the \meta{token list variable}, \emph{i.e.}~removes the item from
+% the \meta{property list}.
+% The \meta{property list} is modified globally, while the
+% \meta{token list variable} is assigned locally.
+% \end{function}
+%
+% \section{Mapping over property lists}
+%
+% All mappings are done at the current group level, \emph{i.e.}~any
+% local assignments made by the \meta{function} or \meta{code} discussed
+% below remain in effect after the loop.
+%
+% \begin{function}[rEXP, updated = 2013-01-08]
+% {\prop_map_function:NN, \prop_map_function:cN}
+% \begin{syntax}
+% \cs{prop_map_function:NN} \meta{property list} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every \meta{entry} stored in the
+% \meta{property list}. The \meta{function} receives two arguments for
+% each iteration: the \meta{key} and associated \meta{value}.
+% The order in which \meta{entries} are returned is not defined and
+% should not be relied upon.
+% To pass further arguments to the \meta{function}, see
+% \cs{prop_map_inline:Nn} (non-expandable) or \cs{prop_map_tokens:Nn}.
+% \end{function}
+%
+% \begin{function}[updated = 2013-01-08]
+% {\prop_map_inline:Nn, \prop_map_inline:cn}
+% \begin{syntax}
+% \cs{prop_map_inline:Nn} \meta{property list} \Arg{inline function}
+% \end{syntax}
+% Applies \meta{inline function} to every \meta{entry} stored
+% within the \meta{property list}. The \meta{inline function} should
+% consist of code which receives the \meta{key} as |#1| and the
+% \meta{value} as |#2|.
+% The order in which \meta{entries} are returned is not defined and
+% should not be relied upon.
+% \end{function}
+%
+% \begin{function}[rEXP]
+% {\prop_map_tokens:Nn, \prop_map_tokens:cn}
+% \begin{syntax}
+% \cs{prop_map_tokens:Nn} \meta{property list} \Arg{code}
+% \end{syntax}
+% Analogue of \cs{prop_map_function:NN} which maps several tokens
+% instead of a single function. The \meta{code} receives each
+% key--value pair in the \meta{property list} as two trailing brace
+% groups. For instance,
+% \begin{verbatim}
+% \prop_map_tokens:Nn \l_my_prop { \str_if_eq:nnT { mykey } }
+% \end{verbatim}
+% expands to the value corresponding to \texttt{mykey}: for each
+% pair in |\l_my_prop| the function \cs{str_if_eq:nnT} receives
+% \texttt{mykey}, the \meta{key} and the \meta{value} as its three
+% arguments. For that specific task, \cs{prop_item:Nn} is faster.
+% \end{function}
+%
+% \begin{function}[rEXP, updated = 2012-06-29]{\prop_map_break:}
+% \begin{syntax}
+% \cs{prop_map_break:}
+% \end{syntax}
+% Used to terminate a \cs[no-index]{prop_map_\ldots} function before all
+% entries in the \meta{property list} have been processed. This
+% normally takes place within a conditional statement, for example
+% \begin{verbatim}
+% \prop_map_inline:Nn \l_my_prop
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \prop_map_break: }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs[no-index]{prop_map_\ldots} scenario leads to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted
+% before further items are taken
+% from the input stream. This depends on the design of the mapping
+% function.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[rEXP, updated = 2012-06-29]{\prop_map_break:n}
+% \begin{syntax}
+% \cs{prop_map_break:n} \Arg{code}
+% \end{syntax}
+% Used to terminate a \cs[no-index]{prop_map_\ldots} function before all
+% entries in the \meta{property list} have been processed, inserting
+% the \meta{code} after the mapping has ended. This
+% normally takes place within a conditional statement, for example
+% \begin{verbatim}
+% \prop_map_inline:Nn \l_my_prop
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \prop_map_break:n { <code> } }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs[no-index]{prop_map_\ldots} scenario leads to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted
+% before the \meta{code} is
+% inserted into the input stream.
+% This depends on the design of the mapping function.
+% \end{texnote}
+% \end{function}
+%
+% \section{Viewing property lists}
+%
+% \begin{function}[updated = 2021-04-29]{\prop_show:N, \prop_show:c}
+% \begin{syntax}
+% \cs{prop_show:N} \meta{property list}
+% \end{syntax}
+% Displays the entries in the \meta{property list} in the terminal,
+% and specifies its storage type.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-12, updated = 2021-04-29]{\prop_log:N, \prop_log:c}
+% \begin{syntax}
+% \cs{prop_log:N} \meta{property list}
+% \end{syntax}
+% Writes the entries in the \meta{property list} in the log file,
+% and specifies its storage type.
+% \end{function}
+%
+% \section{Scratch property lists}
+%
+% There is no need to include both flat and linked property lists as
+% scratch variables. We arbitrarily pick the older implementation.
+%
+% \begin{variable}[added = 2012-06-23]{\l_tmpa_prop, \l_tmpb_prop}
+% Scratch \enquote{flat} property lists for local assignment.
+% These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}[added = 2012-06-23]{\g_tmpa_prop, \g_tmpb_prop}
+% Scratch \enquote{flat} property lists for global assignment.
+% These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Constants}
+%
+% \begin{variable}{\c_empty_prop}
+% A permanently-empty property list used for internal comparisons.
+% \end{variable}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3prop} implementation}
+%
+% \TestFiles{m3prop001, m3prop002, m3prop003, m3prop004, m3show001}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=prop>
+% \end{macrocode}
+%
+% With the (default) flat data storage, a property list is a macro whose
+% top-level expansion is of the form
+% \begin{quote}
+% \cs{s_@@} \cs{@@_chk:w}
+% \cs{@@_pair:wn} \meta{key_1} \cs{s_@@} \Arg{value_1} \\
+% \ldots{} \\
+% \cs{@@_pair:wn} \meta{key_n} \cs{s_@@} \Arg{value_n} \\
+% \end{quote}
+% where \cs{s_@@} is a scan mark (equal to \cs{scan_stop:}), \cs{@@_chk:w}
+% produces a suitable error if the property list is used directly in the input
+% stream, and \cs{@@_pair:wn} can be used to map through the property list.
+%
+% With the linked data storage, each property list entry
+% \meta{key_i}--\meta{value_i} is stored into a token list
+% \cs[no-index]{@@~\meta{prefix}~\meta{key_i}}. The \meta{prefix} is one or
+% more characters (no spaces), constructed automatically only once, when the
+% property list is initially declared. The control sequence name does not
+% conform to standard naming for variables because (1) this is an internal
+% control sequence, not really a \pkg{expl3} variable; (2) keeping track of the
+% scope |l| or~|g| throughout all functions would be a pretty big mess,
+% especially if users accidentally mix local and global use (we would have to
+% always check for such mistakes, rather than only checking when suitable debug
+% options are set); (3) shorter control sequence names use less memory and are
+% quicker in case of hash collisions, which may matter since we are using many
+% control sequences.
+%
+% We need to enable mapping through such a property list, but without storing a
+% list of all entries anywhere: this is achieved by making each of these token
+% lists also store a pointer to the next entry. To enable efficient deletion,
+% the token lists also store a pointer to the previous entry. This means we
+% have a doubly-linked list. To avoid having to special-case the two ends of
+% the doubly-linked list when deleting entries, we include as a zeroth entry in
+% the doubly-linked list the property list variable itself, and we include as an
+% $(n+1)$-th entry in the doubly-linked list an end-pointer
+% \cs{@@~\meta{prefix}} (no trailing space, so it differs from an empty key).
+% The space before \meta{prefix} ensures there is no collision with
+% other \pkg{l3prop} internal functions, even if we have very many
+% linked property lists being defined.
+%
+% The property list variable itself is a token list of the form
+% \begin{quote}
+% \cs{@@_flatten:w} \cs{@@~\meta{prefix}} \cs{s_@@} \Arg{prefix}
+% \cs[no-index]{@@~\meta{prefix}~\meta{key_1}}
+% \end{quote}
+% Here, \cs{@@_flatten:w} serves as an efficiently recognized marker, and when
+% \texttt{f}-expanded it is tasked with fully unpacking the property list into
+% the same form as the default data storage so as to ease conversion. The
+% \meta{prefix} is used when looking up an entry. The token list
+% \cs{@@~\meta{prefix}} (see below) contains a pointer to the last key to help
+% insert a new entry. The pointer to \meta{key_1} is needed to start a mapping.
+% The token list labeled by \meta{key_i} is of the form
+% \begin{quote}
+% \cs{use_none:n} \cs[no-index]{@@~\meta{prefix}~\meta{key$_{i-1}$}}
+% \cs{@@_pair:wn} \meta{key_i} \cs{s_@@} \Arg{value_i}
+% \cs[no-index]{@@~\meta{prefix}~\meta{key$_{i+1}$}}
+% \end{quote}
+% where the pointer to \meta{key$_{i-1}$} is needed when deleting the
+% \meta{key_i}. Expanding this will run \cs{@@_pair:wn} on the
+% \meta{key_i}--\meta{value_i} pair (for speed, \meta{key_i} is kept as explicit
+% tokens rather than slowly extracting it from a control sequence name), then
+% move on to the next key, thus mapping through the whole list. The mapping is
+% ended upon expanding \cs{@@~\meta{prefix}}, which is the token list
+% \begin{quote}
+% \cs{use_none:n} \cs[no-index]{@@~\meta{prefix}~\meta{key_n}}
+% \end{quote}
+% Let us think about deleting the \meta{key_i}. We need to update the
+% \meta{key$_{i-1}$} and \meta{key$_{i+1}$} to point to each other
+% instead of \meta{key_i}. To edit the corresponding token lists, it is
+% important that \cs[no-index]{@@~\meta{prefix}~\meta{key_i}} be at the
+% \enquote{same place} in the token lists also in the boundary cases
+% $i=1$ or $i=n$, namely as the second token, or as the second argument
+% after \cs{s_@@}.
+%
+% \subsection{Internal auxiliaries}
+%
+% \begin{macro}{\@@_tmp:w}
+% Scratch macro, defined as needed, for instance to save \cs{@@_pair:wn} when
+% concatenating.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_tmp:w ?
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_internal_tl}
+% Token list used in various places: for the prefix; when converting from flat
+% to linked props; and to store the new key--value pair inserted by
+% \cs{prop_put:Nnn}.
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\s_@@_mark,\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\q_@@_recursion_tail,\q_@@_recursion_stop}
+% Internal recursion quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_recursion_tail
+\quark_new:N \q_@@_recursion_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_if_recursion_tail_stop:n}
+% \begin{macro}[EXP]{\@@_if_recursion_tail_stop:o}
+% Functions to query recursion quarks.
+% \begin{macrocode}
+\__kernel_quark_new_test:N \@@_if_recursion_tail_stop:n
+\cs_generate_variant:Nn \@@_if_recursion_tail_stop:n { o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Structure of a property list}
+%
+% \begin{macro}{\s_@@}
+% A private scan mark is used as a marker after each key, and at the
+% very beginning of the property list.
+% \begin{macrocode}
+\scan_new:N \s_@@
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_chk:w, \@@_chk_loop:nw, \@@_chk_get:nw}
+% This removes the flat property list from the input stream and complains
+% about a bad use of a property list. Since property lists do not have an
+% end-marker, we slowly peek ahead in a loop. Speed does not matter since
+% this is for an error situation. While \cs{@@_pair:wn} does not keep a fixed
+% definition, it always includes the internal \cs{s_@@} in its argument
+% specification, so that there is no risk of accidentally picking up a public
+% token instead of \cs{@@_pair:wn} when doing a meaning test. We collect the
+% keys and values to produce a more useful error message.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_chk:w { \@@_chk_loop:nw { } }
+\cs_new_protected:Npn \@@_chk_loop:nw #1
+ {
+ \peek_meaning:NTF \@@_pair:wn
+ { \@@_chk_get:nw {#1} }
+ { \msg_error:nne { prop } { misused } {#1} }
+ }
+\cs_new_protected:Npn \@@_chk_get:nw #1 \@@_pair:wn #2 \s_@@ #3
+ { \@@_chk_loop:nw { #1 , ~ {#2} = { \tl_to_str:n {#3} } } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_pair:wn}
+% Used as \cs{@@_pair:wn} \meta{key} \cs{s_@@} \Arg{item} for both storage
+% types, this internal token starts each key--value pair in the property list.
+% This default definition is changed globally by any mapping function, so
+% there is not much point trying to make it an error. Instead, the error is
+% produced by \cs{@@_chk:w}.
+% \begin{macrocode}
+\cs_new:Npn \@@_pair:wn #1 \s_@@ #2 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_flatten:w}
+% We implement here the fact that \texttt{f}-expanding a linked property list
+% gives a flat property list.
+% Leaving a linked property list in the input stream will turn it into a flat
+% property list so that the error implemented by \cs{@@_chk:w} will correctly
+% be triggered.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_flatten:w #1 \s_@@ #2#3
+ { \use:e { \@@_flatten_aux:N #3 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {\@@_flatten:N, \@@_flatten_aux:w, \@@_flatten_aux:N, \@@_flatten_loop:w}
+% The main function \cs{@@_flatten:N} receives a linked property list and
+% flattens it. The auxiliary \cs{@@_flatten_aux:N} receives a pointer to the
+% first key and flattens the linked property list into a flat property list.
+% This is only restricted-expandable as it involves mapping through all of the
+% property list's entries starting from \meta{key_1}. The looping function
+% \cs{@@_flatten_loop:w} removes \cs{use_none:n} and a backwards pointer~|#2|,
+% leaves the key--value pair for \cs{use:e} to receive, and calls itself
+% again after expanding the next key's token list. Its argument |#3| is
+% empty, except at the end where it is the \cs{use_none:nnnn} appearing in the
+% definition of~\cs{@@_flatten_aux:N}, which ends the loop.
+% \begin{macrocode}
+\cs_new:Npn \@@_flatten:N #1
+ { \exp_after:wN \@@_flatten_aux:w #1 }
+\cs_new:Npn \@@_flatten_aux:w #1 \s_@@ #2 { \@@_flatten_aux:N }
+\cs_new:Npn \@@_flatten_aux:N #1
+ {
+ \s_@@ \@@_chk:w
+ \exp_after:wN \@@_flatten_loop:w #1
+ \use_none:nnnn \@@_pair:wn \s_@@ { }
+ }
+\cs_new:Npn \@@_flatten_loop:w #1#2#3 \@@_pair:wn #4 \s_@@ #5
+ {
+ #3
+ \exp_not:n { \@@_pair:wn #4 \s_@@ {#5} }
+ \exp_after:wN \@@_flatten_loop:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_prefix_int, \c_@@_basis_int}
+% Used to assign prefixes for each linked property list. It is converted to
+% base \cs{c_@@_basis_int}, then each digit is converted to a character,
+% starting at |!| (the character after space).
+% \begin{macrocode}
+\int_new:N \g_@@_prefix_int
+\int_const:Nn \c_@@_basis_int { \c_max_char_int - `\! }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_next_prefix:, \@@_to_prefix:n}
+% Store in \cs{l_@@_internal_tl} the conversion of \cs{g_@@_prefix_int} to
+% characters, and increment this integer for use in the next linked property
+% list. No need to optimize since this is only used when declaring the
+% property list the first time.
+% The aim here is to make this string as short as we can, given the
+% range of distinct characters available. This speeds up the work of
+% \cs{cs:w} \ldots{} \cs{cs_end:} that looks up keys in the hash table.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_next_prefix:
+ {
+ \tl_set:Ne \l_@@_internal_tl
+ { \@@_to_prefix:n { \g_@@_prefix_int } }
+ \int_gincr:N \g_@@_prefix_int
+ }
+\cs_new:Npn \@@_to_prefix:n #1
+ {
+ \int_compare:nNnTF {#1} > \c_@@_basis_int
+ {
+ \exp_args:Nf \@@_to_prefix:n
+ { \int_div_truncate:nn {#1} \c_@@_basis_int }
+ \exp_args:Nf \@@_to_prefix:n
+ { \int_mod:nn {#1} \c_@@_basis_int }
+ }
+ { \char_generate:nn { `\! + #1 } { 12 } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_if_flat:NTF, \@@_if_flat_aux:w}
+% We could either test for the presence of \cs{@@_chk:w} (flat
+% property list) or of \cs{@@_flatten:w} (linked property list). We
+% make the second choice; this way props that are accidentally
+% \tn{relax} are treated as they were before. The auxiliary receives
+% \cs{use_i:nn} or \cs{use_ii:nn} as~|#3|.
+% As a transitional fix we avoid erroring in case the prop is undefined (the \cs{exp_after:wN} is omitted in that case, taking the flat branch).
+% \begin{macrocode}
+\cs_new:Npn \@@_if_flat:NTF #1
+ {
+ \prop_if_exist:NT #1
+ \exp_after:wN \@@_if_flat_aux:w #1
+ \s_@@_mark \use_ii:nn
+ \@@_flatten:w \s_@@_mark \use_i:nn \s_@@_stop
+ }
+\cs_new:Npn \@@_if_flat_aux:w
+ #1 \@@_flatten:w #2 \s_@@_mark #3 #4 \s_@@_stop {#3}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Allocation and initialisation}
+%
+% \begin{variable}[tested = m3prop004]{\c_empty_prop}
+% An empty flat prop.
+% \begin{macrocode}
+\tl_const:Nn \c_empty_prop { \s_@@ \@@_chk:w }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[tested = m3prop001]{\prop_new:N, \prop_new:c}
+% Flat property lists are initialized with the value \cs{c_empty_prop}.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_new:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \cs_gset_eq:NN #1 \c_empty_prop
+ }
+\cs_generate_variant:Nn \prop_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[tested = m3prop001]{\prop_new_linked:N, \prop_new_linked:c}
+% \begin{macro}{\@@_new_linked:N}
+% The auxiliary is used in \cs{prop_make_linked:N}.
+% For linked property lists, get a new prefix in \cs{l_@@_internal_tl}, then
+% use it to set up the internal structure: the last token in~|#1| is usually a
+% pointer to the first key, which is here the end-pointer. That end-pointer
+% has a pointer to the previous key (usually the last key), which is the
+% variable~|#1| itself that begins the doubly-linked list.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_new_linked:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \@@_new_linked:N #1
+ }
+\cs_new_protected:Npn \@@_new_linked:N #1
+ {
+ \@@_next_prefix:
+ \cs_gset_nopar:Npe #1
+ {
+ \@@_flatten:w
+ \exp_not:c { @@ ~ \l_@@_internal_tl }
+ \s_@@ { \l_@@_internal_tl }
+ \exp_not:c { @@ ~ \l_@@_internal_tl }
+ }
+ \cs_gset_nopar:cpe { @@ ~ \l_@@_internal_tl }
+ {
+ \exp_not:N \use_none:n
+ \exp_not:N #1
+ }
+ }
+\cs_generate_variant:Nn \prop_new_linked:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[tested = m3prop001]{\prop_clear:N, \prop_clear:c}
+% \begin{macro}[tested = m3prop001]{\prop_gclear:N, \prop_gclear:c}
+% \begin{macro}{\@@_clear:NNN, \@@_clear:wNNN, \@@_clear_loop:Nw}
+% Clearing a flat property list is like declaring it anew, simply setting it
+% equal to \cs{c_empty_prop}. For linked property lists we must clear all of
+% the variables storing individual keys, which requires a loop. At each step
+% of the loop, \cs{@@_clear_loop:Nw} receives
+% \cs[index=cs_set_eq:NN]{cs_(g)set_eq:NN}, \cs{use_none:n}, the backwards
+% pointer, an empty~|#4| (except at the end of the loop), and the key--value
+% pair |#5=#6| which we disregard. The looping auxiliary undefines the
+% previous key's token list (this includes the main token list, but that is
+% fine because it is restored at the end) and calls itself after expanding the
+% next key's token list. The loop ends when |#4| is \cs{use_none:nnnn}.
+% After the loop, \cs{@@_clear:wNNN} correctly sets up the main variable~|#6|
+% and the end-pointer~|#1|. Importantly, this is done using
+% \cs[index=cs_set_nopar:Npe]{cs_(g)set_nopar:Npe} and \cs{exp_not:n} because
+% the almost-equivalent \cs{tl_set:Nn} would complain in debug mode about the
+% fact that the main variable is undefined at this stage. Importantly,
+% \cs{@@_clear_entries:NN} is used in the implementation of
+% \cs{prop_set_eq:NN}.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_clear:N
+ { \@@_clear:NNN \cs_set_eq:NN \cs_set_nopar:Npe }
+\cs_generate_variant:Nn \prop_clear:N { c }
+\cs_new_protected:Npn \prop_gclear:N
+ { \@@_clear:NNN \cs_gset_eq:NN \cs_gset_nopar:Npe }
+\cs_generate_variant:Nn \prop_gclear:N { c }
+\cs_new_protected:Npn \@@_clear:NNN #1#2#3
+ {
+ \@@_if_flat:NTF #3
+ { #1 #3 \c_empty_prop }
+ { \exp_after:wN \@@_clear:wNNN #3 #1 #2 #3 }
+ }
+\cs_new_protected:Npn \@@_clear:wNNN
+ \@@_flatten:w #1 \s_@@ #2#3#4#5#6
+ {
+ \@@_clear_entries:NN #4 #3
+ #5 #6 { \exp_not:n { \@@_flatten:w #1 \s_@@ {#2} #1 } }
+ #5 #1 { \exp_not:n { \use_none:n #6 } }
+ }
+\cs_new_protected:Npn \@@_clear_entries:NN #1#2
+ {
+ \exp_after:wN \@@_clear_loop:Nw \exp_after:wN #1 #2
+ \use_none:nnnn \@@_pair:wn \s_@@ { }
+ }
+\cs_new_protected:Npn \@@_clear_loop:Nw
+ #1#2#3#4 \@@_pair:wn #5 \s_@@ #6
+ {
+ #1 #3 \tex_undefined:D
+ #4
+ \exp_after:wN \@@_clear_loop:Nw
+ \exp_after:wN #1
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[tested = m3prop001]
+% {
+% \prop_clear_new:N, \prop_clear_new:c,
+% \prop_gclear_new:N, \prop_gclear_new:c,
+% \prop_clear_new_linked:N, \prop_clear_new_linked:c,
+% \prop_gclear_new_linked:N, \prop_gclear_new_linked:c
+% }
+% A simple variation of the token list functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_clear_new:N #1
+ { \prop_if_exist:NTF #1 { \prop_clear:N #1 } { \prop_new:N #1 } }
+\cs_generate_variant:Nn \prop_clear_new:N { c }
+\cs_new_protected:Npn \prop_gclear_new:N #1
+ { \prop_if_exist:NTF #1 { \prop_gclear:N #1 } { \prop_new:N #1 } }
+\cs_generate_variant:Nn \prop_gclear_new:N { c }
+\cs_new_protected:Npn \prop_clear_new_linked:N #1
+ { \prop_if_exist:NTF #1 { \prop_clear:N #1 } { \prop_new_linked:N #1 } }
+\cs_generate_variant:Nn \prop_clear_new_linked:N { c }
+\cs_new_protected:Npn \prop_gclear_new_linked:N #1
+ { \prop_if_exist:NTF #1 { \prop_gclear:N #1 } { \prop_new_linked:N #1 } }
+\cs_generate_variant:Nn \prop_gclear_new_linked:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[tested = m3prop001]
+% {\prop_set_eq:NN, \prop_set_eq:cN, \prop_set_eq:Nc, \prop_set_eq:cc}
+% \begin{macro}[tested = m3prop001]
+% {\prop_gset_eq:NN, \prop_gset_eq:cN, \prop_gset_eq:Nc, \prop_gset_eq:cc}
+% \begin{macro}
+% {
+% \@@_set_eq:NNNN, \@@_set_eq:wNNNN, \@@_set_eq:nNnNN,
+% \@@_set_eq_loop:NNnw, \@@_set_eq_end:w
+% }
+% If both variables are accidentally the same variable (or equal flat property
+% lists, as it turns out) we do nothing, otherwise the following code would
+% lose all entries. If the target variable~|#3| is a flat prop, either copy
+% directly or flatten before copying. If it is a linked prop, we must clear
+% it, then go through the entries in~|#4| to add them to~|#3|.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_set_eq:NN
+ { \@@_set_eq:NNNN \cs_set_eq:NN \cs_set_nopar:Npe }
+\cs_generate_variant:Nn \prop_set_eq:NN { Nc , cN , cc }
+\cs_new_protected:Npn \prop_gset_eq:NN
+ { \@@_set_eq:NNNN \cs_gset_eq:NN \cs_gset_nopar:Npe }
+\cs_generate_variant:Nn \prop_gset_eq:NN { Nc , cN , cc }
+\cs_new_protected:Npn \@@_set_eq:NNNN #1#2#3#4
+ {
+ \cs_if_eq:NNF #3#4
+ {
+ \@@_if_flat:NTF #3
+ {
+ \@@_if_flat:NTF #4
+ { #1 #3 #4 }
+ { #2 #3 { \@@_flatten:N #4 } }
+ }
+ { \exp_after:wN \@@_set_eq:wNNNN #3 #1#2#3#4 }
+ }
+ }
+\cs_new_protected:Npn \@@_set_eq:wNNNN
+ \@@_flatten:w #1 \s_@@ #2#3#4#5#6#7
+ {
+ \@@_clear_entries:NN #4 #3
+ \exp_args:Nf \@@_set_eq:nNnNN {#7} #1 {#2} #5 #6
+ }
+% \end{macrocode}
+% We have used that |f|-expanding either type of prop gives a flat prop. At
+% this stage \cs{@@_set_eq:nNnNN} receives the second variable as a flat prop,
+% the end-pointer, the prefix, the suitable
+% \cs[index=cs_set_nopar:Npe]{cs_(g)set_nopar:Npe} assignment, and the first
+% variable itself. Remove the leading \cs{s_@@} and \cs{@@_chk:w} with
+% \cs{use_i:nnn}, then start the loop.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_eq:nNnNN #1#2#3#4#5
+ {
+ \use_i:nnn
+ {
+ \@@_set_eq_loop:NNnw #5 #4 {#3}
+ \@@_flatten:w #2 \s_@@ {#3}
+ }
+ #1
+ \use_none:n \@@_pair:wn ? \s_@@
+ }
+% \end{macrocode}
+% The looping function receives the current pointer~|#1| (initially the
+% variable itself), the defining function~|#2| and the prefix~|#3|, then a
+% partial definition~|#4| (which in later stages includes the backwards
+% pointer), followed by the current value as \cs{s_@@} |{#5}|. It seeks the
+% next key~|#7| to construct in \cs{l_@@_internal_tl} the next pointer
+% \cs[no-index]{@@~\meta{prefix}~\meta{next key}} (the
+% argument~|#6| is empty, except at the end of the loop, where it is
+% \cs{use_none:n} in such a way as to delete the \meta{space} and \meta{next
+% key}). Then the token list (current pointer)~|#1| is set-up to contain the
+% partial definition and current value, as well as the newly constructed next
+% pointer. After a line responsible for correctly ending the loop with
+% \cs{@@_set_eq_end:w}, we loop, setting up the next definition, which starts
+% with \cs{use_none:n} and a backwards pointer to~|#1| followed by the
+% \meta{next key}~|#7| and so on.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_eq_loop:NNnw
+ #1#2#3#4 \s_@@ #5#6 \@@_pair:wn #7 \s_@@
+ {
+ \tl_set:Ne \l_@@_internal_tl { \exp_not:c { @@ ~ #3 #6 ~ #7 } }
+ #2 #1 { \exp_not:n { #4 \s_@@ {#5} } \exp_not:o \l_@@_internal_tl }
+ \use_none:n #6 \@@_set_eq_end:w
+ \exp_after:wN \@@_set_eq_loop:NNnw \l_@@_internal_tl #2 {#3}
+ \use_none:n #1 \@@_pair:wn #7 \s_@@
+ }
+% \end{macrocode}
+% The end-code picks up what is needed to correctly assign the last token
+% list (the end pointer), which is simply \cs{use_none:n}
+% \cs[no-index]{@@_\meta{prefix}\meta{space}\meta{key_n}}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_eq_end:w
+ \exp_after:wN \@@_set_eq_loop:NNnw #1#2#3
+ \use_none:n #4#5 \s_@@
+ {
+ \exp_after:wN #2 \l_@@_internal_tl { \exp_not:n { \use_none:n #4 } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prop_make_flat:N, \prop_make_flat:c \@@_make_flat:Nn}
+% The only interesting case is when given a linked prop. Clear the
+% linked property list using \cs{@@_clear:wNNN} with local assignments
+% (it does not matter since we are at the outermost group level, and
+% \cs{cs_set_eq:NN} is very slightly faster than its global version.
+% Then store the contents (expanded preventively by \cs{exp_args:NNf})
+% with an assignment \cs{cs_set_nopar:Npe} that does not perform
+% \pkg{l3debug} checks.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_make_flat:N #1
+ {
+ \int_compare:nNnTF { \tex_currentgrouplevel:D } = 0
+ {
+ \@@_if_flat:NTF #1 { }
+ { \exp_args:NNf \@@_make_flat:Nn #1 {#1} }
+ }
+ {
+ \msg_error:nnee { prop } { inner-make }
+ { \token_to_str:N \prop_make_flat:N } { \token_to_str:N #1 }
+ }
+ }
+\cs_generate_variant:Nn \prop_make_flat:N { c }
+\cs_new_protected:Npn \@@_make_flat:Nn #1#2
+ {
+ \exp_after:wN \@@_clear:wNNN #1 \cs_set_eq:NN \cs_set_nopar:Npe #1
+ \cs_set_nopar:Npe #1 { \exp_not:n {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prop_make_linked:N, \prop_make_linked:c, \@@_make_linked:Nn}
+% The only interesting case is when given a flat prop. We expand the
+% contents for later use. Then \cs{@@_new_linked:N} disregards that
+% previous value of~|#1| and initializes the linked prop. We can then
+% use an auxiliary \cs{@@_set_eq:wNNNN} underlying
+% \cs{prop_set_eq:NN}, with the prop contents saved as
+% \cs{l_@@_internal_tl}. That step is a bit unsafe, as
+% \cs{l_@@_internal_tl} (really, a flat prop here) is used within
+% \cs{@@_set_eq:wNNNN} itself, but it is in fact expanded early enough
+% to be ok.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_make_linked:N #1
+ {
+ \int_compare:nNnTF { \tex_currentgrouplevel:D } = 0
+ {
+ \@@_if_flat:NTF #1
+ { \exp_args:NNo \@@_make_linked:Nn #1 {#1} } { }
+ }
+ {
+ \msg_error:nnee { prop } { inner-make }
+ { \token_to_str:N \prop_make_linked:N } { \token_to_str:N #1 }
+ }
+ }
+\cs_generate_variant:Nn \prop_make_linked:N { c }
+\cs_new_protected:Npn \@@_make_linked:Nn #1#2
+ {
+ \@@_new_linked:N #1
+ \tl_set:Nn \l_@@_internal_tl {#2}
+ \exp_after:wN \@@_set_eq:wNNNN #1
+ \cs_set_eq:NN \cs_set_nopar:Npe #1 \l_@@_internal_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}[tested = m3prop004]{\l_tmpa_prop, \l_tmpb_prop}
+% \begin{variable}[tested = m3prop004]{\g_tmpa_prop, \g_tmpb_prop}
+% We can now initialize the scratch variables.
+% \begin{macrocode}
+\prop_new:N \l_tmpa_prop
+\prop_new:N \l_tmpb_prop
+\prop_new:N \g_tmpa_prop
+\prop_new:N \g_tmpb_prop
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \prop_concat:NNN, \prop_concat:ccc,
+% \prop_gconcat:NNN, \prop_gconcat:ccc,
+% \@@_concat:NNNNN, \@@_concat:nNNN
+% }
+% The basic strategy is to copy the first variable into the target,
+% then loop through the second variable, calling
+% \cs[index=prop_put:Nnn]{prop_(g)put:Nnn} on each item. To avoid
+% running the \pkg{l3debug} scope checks on each of these steps, we
+% use the auxiliaries that underly \cs{prop_set_eq:NN} and
+% \cs{prop_put:Nnn}, whose syntax is a bit unwieldy.
+% We work directly with the target prop |#3| as a scratch space,
+% because copying over from a temporary variable to |#3| would be slow
+% in the linked case. If |#5| is |#3| itself we have to be careful
+% not to lose the data, and we even take the opportunity to skip the
+% copying step completely. To keep the correct version of the
+% duplicate keys we use the code underlying \cs{prop_put_if_not_in:Nnn},
+% which involves passing \cs{use_none:nnn} to the auxiliary instead of
+% nothing.
+% There is no need to check for the case where |#3| is equal to~|#4|
+% because in that case \cs[index=prop_set_eq:NN]{prop_(g)set_eq:NN}
+% |#3| |#4| (or rather the underlying auxiliary) is correctly set up
+% to do no needless work.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_concat:NNN
+ { \@@_concat:NNNNN \cs_set_eq:NN \cs_set_nopar:Npe }
+\cs_generate_variant:Nn \prop_concat:NNN { ccc }
+\cs_new_protected:Npn \prop_gconcat:NNN
+ { \@@_concat:NNNNN \cs_gset_eq:NN \cs_gset_nopar:Npe }
+\cs_generate_variant:Nn \prop_gconcat:NNN { ccc }
+\cs_new_protected:Npn \@@_concat:NNNNN #1#2#3#4#5
+ {
+ \cs_if_eq:NNTF #3 #5
+ { \@@_concat:nNNN \use_none:nnn #2 #3 #4 }
+ {
+ \@@_set_eq:NNNN #1 #2 #3 #4
+ \@@_concat:nNNN { } #2 #3 #5
+ }
+ }
+\cs_new_protected:Npn \@@_concat:nNNN #1#2#3#4
+ {
+ \cs_gset_eq:NN \@@_tmp:w \@@_pair:wn
+ \cs_gset_protected:Npn \@@_pair:wn ##1 \s_@@
+ { \@@_put:nNNnn {#1} #2 #3 {##1} }
+ \exp_last_unbraced:Nf \use_none:nn #4
+ \cs_gset_eq:NN \@@_pair:wn \@@_tmp:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \prop_put_from_keyval:Nn, \prop_put_from_keyval:cn,
+% \prop_gput_from_keyval:Nn, \prop_gput_from_keyval:cn,
+% \@@_from_keyval:nn, \@@_from_keyval:Nnn,
+% \@@_missing_eq:n
+% }
+% The core is a call to \cs{keyval_parse:nnn}, with an error message
+% \cs{@@_missing_eq:n} for entries without~|=|, and a call to (essentially)
+% \cs[index=prop_put:Nnn]{prop_(g)put:Nnn} for valid key--value pairs.
+% To avoid repeated scope checks (and errors) when \pkg{l3debug} is
+% active, we instead use the auxiliary underlying \cs{prop_put:Nnn}.
+% Because blank keys are valid here, in contrast to \pkg{l3keys}, we set and
+% restore \cs{l__kernel_keyval_allow_blank_keys_bool}.
+% The key--value argument may be quite large so we avoid reading it until it
+% is really necessary.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_put_from_keyval:Nn #1
+ { \@@_from_keyval:nn { \@@_put:nNNnn { } \cs_set_nopar:Npe #1 } }
+\cs_generate_variant:Nn \prop_put_from_keyval:Nn { c }
+\cs_new_protected:Npn \prop_gput_from_keyval:Nn #1
+ { \@@_from_keyval:nn { \@@_put:nNNnn { } \cs_gset_nopar:Npe #1 } }
+\cs_generate_variant:Nn \prop_gput_from_keyval:Nn { c }
+\cs_new_protected:Npn \@@_from_keyval:nn
+ {
+ \bool_if:NTF \l__kernel_keyval_allow_blank_keys_bool
+ { \@@_from_keyval:Nnn \c_true_bool }
+ { \@@_from_keyval:Nnn \c_false_bool }
+ }
+\cs_new_protected:Npn \@@_from_keyval:Nnn #1#2#3
+ {
+ \bool_set_eq:NN \l__kernel_keyval_allow_blank_keys_bool \c_true_bool
+ \keyval_parse:nnn \@@_missing_eq:n {#2} {#3}
+ \bool_set_eq:NN \l__kernel_keyval_allow_blank_keys_bool #1
+ }
+\cs_new_protected:Npn \@@_missing_eq:n
+ { \msg_error:nnn { prop } { prop-keyval } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \prop_set_from_keyval:Nn, \prop_set_from_keyval:cn,
+% \prop_gset_from_keyval:Nn, \prop_gset_from_keyval:cn,
+% }
+% Just empty the prop (with the auxiliary underlying
+% \cs{prop_clear:N} to avoid \pkg{l3debug} problems) and push
+% key--value entries using
+% \cs[index=prop_put_from_keyval:Nn]{prop_(g)put_from_keyval:Nn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_set_from_keyval:Nn #1
+ {
+ \@@_clear:NNN \cs_set_eq:NN \cs_set_nopar:Npe #1
+ \prop_put_from_keyval:Nn #1
+ }
+\cs_generate_variant:Nn \prop_set_from_keyval:Nn { c }
+\cs_new_protected:Npn \prop_gset_from_keyval:Nn #1
+ {
+ \@@_clear:NNN \cs_gset_eq:NN \cs_gset_nopar:Npe #1
+ \prop_gput_from_keyval:Nn #1
+ }
+\cs_generate_variant:Nn \prop_gset_from_keyval:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \prop_const_from_keyval:Nn, \prop_const_from_keyval:cn,
+% \prop_const_linked_from_keyval:Nn, \prop_const_linked_from_keyval:cn
+% }
+% For both flat and linked constant props, we create |#1| then use the
+% same auxiliary as for \cs{prop_gput_from_keyval:Nn}. It is most
+% natural to use the already packaged \cs{prop_gput:Nnn}, but that
+% would mean doing an assignment on a supposedly constant property
+% list. To avoid errors when \pkg{l3debug} is activated, we use the
+% auxiliary underlying \cs{prop_gput:Nnn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_const_from_keyval:Nn #1
+ {
+ \prop_new:N #1
+ \@@_from_keyval:nn { \@@_put:nNNnn { } \cs_gset_nopar:Npe #1 }
+ }
+\cs_generate_variant:Nn \prop_const_from_keyval:Nn { c }
+\cs_new_protected:Npn \prop_const_linked_from_keyval:Nn #1
+ {
+ \prop_new_linked:N #1
+ \@@_from_keyval:nn { \@@_put:nNNnn { } \cs_gset_nopar:Npe #1 }
+ }
+\cs_generate_variant:Nn \prop_const_linked_from_keyval:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Accessing data in property lists}
+%
+% Accessing/deleting/adding entries is mostly done by \cs{@@_split:NnTFn}, which
+% must be fast because it is used in many \pkg{l3prop} functions. Its syntax is
+% as follows.
+% \begin{quote}
+% \cs{@@_split:NnTFn} \meta{property list} \Arg{key} \\
+% ~~\Arg{true code} \Arg{false code} \Arg{link code}
+% \end{quote}
+% If the \meta{property list} uses the linked data storage, then it runs
+% the \meta{link code}, otherwise it does as follows.
+%
+% It splits the \meta{property list} at the \meta{key}, giving three
+% token lists: the \meta{entries before} the \meta{key}, the
+% \meta{value} associated with the \meta{key} and the \meta{entries
+% after} the \meta{key}. Both the \meta{entries before} and the
+% \meta{entries after} can be empty or consist of some number of
+% consecutive entries \cs{@@_pair:wn} \meta{key_i} \cs{s_@@}
+% \Arg{value_i}. If the \meta{key} is present in the \meta{property
+% list} then the \meta{true code} is left in the input stream, with
+% |#1|, |#2|, and |#3| replaced by the \meta{entries before},
+% \meta{value}, and \meta{entries after}. If the \meta{key} is not
+% present in the \meta{property list} then the \meta{false code} is left
+% in the input stream. Only the \meta{true code} is used in the
+% replacement text of a macro defined internally, which requires
+% |##|~doubling.
+%
+% \begin{macro}
+% {
+% \@@_split:NnTFn, \@@_split_aux:nNTFn, \@@_split_test:wn,
+% \@@_split_flat:w, \@@_split_linked:w, \@@_split_wrong:Nw
+% }
+% The aim is to distinguish four cases: a flat prop that contains the
+% given \meta{key}, a flat prop that does not contain it, a linked
+% prop, and an invalid prop. The last case includes those that are
+% set to \tn{relax} by \texttt{c}-expansion, as well as unrelated
+% token list variables since these unfortunately used to
+% \enquote{work} in earlier implementations.
+% In the first three cases we run the \texttt{T}, \texttt{F}, and
+% \texttt{n} arguments, and in the last case we raise an error, set
+% the variable to a known state (empty prop), and run the \texttt{F}
+% code (some conditionals such as \cs{prop_pop:NnNTF} otherwise blow
+% up pretty badly).
+%
+% The first distinction between these cases is done by
+% \cs{@@_split_test:wn}, which looks for the argument after \cs{s_@@}.
+% For a flat prop it will be \cs{@@_chk:w}, which leads to running
+% \cs{@@_split_flat:w}, explained below. For a linked prop it is the
+% prefix, consisting of characters, so we end up running
+% \cs{@@_split_linked:w}, which cleans up and selects the
+% aforementioned \texttt{n} argument. For invalid props, or rather,
+% variables that do not contain \cs{s_@@}, the argument includes
+% \cs{fi:}, and we end up calling \cs{@@_split_wrong:Nw}, which calls
+% \cs{prop_show:N} to raise a detailed error stating how the variable
+% is wrong.
+%
+% Let us return to \cs{@@_split_flat:w}. This function is defined
+% dynamically as
+% \begin{quote}
+% \cs{cs_set:Npn} \cs{@@_split_flat:w} \cs{@@_split_linked:w} |#1| \\
+% \quad \cs{@@_pair:wn} \meta{key} \cs{s_@@} |#2| \\
+% \quad |#3| \cs{s_@@_mark} |#4| |#5| \cs{s_@@_stop} \\
+% \quad |{| |#4| \Arg{true code} |}|
+% \end{quote}
+% Its job is to seek the \meta{key} in the property list (known to be
+% flat at this stage) by using an argument |#1| delimited essentially
+% by that key. If indeed the variable contained the \meta{key}, then
+% |#1|~is the \meta{extract_1} before the key--value pair, |#2|~is the
+% \meta{value} associated with the \meta{key}, |#3|~is the
+% \meta{extract_2} after the key--value pair, |#4|~is \cs{use_i:nnn},
+% and we run \cs{use_i:nnn} \Arg{true code} \Arg{false code} \Arg{link
+% code}, selecting the \meta{true code}. Otherwise, the whole
+% property list together with \cs{s_@@_mark} \cs{use_i:nnn} is taken
+% in as |#1|, then |#2| is some tokens |?| \cs{fi:}
+% \cs{@@_split_wrong:Nw} \meta{variable} that were only useful in the
+% case of invalid props, |#3|~is empty, and most importantly |#4| is
+% \cs{use_ii:nnn}. This command selects the \meta{false code}.
+%
+% Note that we define \cs{@@_split_flat:w} in all cases even though it
+% is only used in the flat case. Indeed, to avoid taking in the whole
+% property list (which may be large) as an argument more than strictly
+% necessary, we would have to keep the \meta{true code} positioned
+% before the expansion of the prop variable in order to use it in the
+% definition. The only way to do that is to store it using an
+% assignment so we might as well just perform the assignment that we
+% can actually use in the flat case.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_split:NnTFn #1#2
+ {
+ \exp_after:wN \@@_split_aux:nNTFn
+ \exp_after:wN { \tl_to_str:n {#2} } #1
+ }
+\cs_new_protected:Npn \@@_split_aux:nNTFn #1#2#3
+ {
+ \cs_set:Npn \@@_split_flat:w \@@_split_linked:w ##1
+ \@@_pair:wn #1 \s_@@ ##2 ##3 \s_@@_mark ##4 ##5 \s_@@_stop
+ { ##4 {#3} }
+ \exp_after:wN \@@_split_test:wn #2 \s_@@_mark \use_i:nnn
+ \@@_pair:wn #1 \s_@@ { ? \fi: \@@_split_wrong:Nw #2 }
+ \s_@@_mark \use_ii:nnn
+ \s_@@_stop
+ }
+\cs_new:Npn \@@_split_flat:w { }
+\cs_new_protected:Npn \@@_split_test:wn #1 \s_@@ #2
+ {
+ \if_meaning:w \@@_chk:w #2 \exp_after:wN \@@_split_flat:w \fi:
+ \@@_split_linked:w
+ }
+\cs_new_protected:Npn \@@_split_linked:w #1 \s_@@_stop #2#3 {#3}
+\cs_new_protected:Npn \@@_split_wrong:Nw #1#2 \s_@@_stop #3#4
+ {
+ \prop_show:N #1
+ \cs_gset_eq:NN #1 \c_empty_prop
+ #3
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[tested = m3prop002]
+% {
+% \prop_get:NnN, \prop_get:NVN, \prop_get:NvN, \prop_get:NeN,
+% \prop_get:NoN, \prop_get:NxN,
+% \prop_get:cnN, \prop_get:cVN, \prop_get:cvN, \prop_get:ceN,
+% \prop_get:coN, \prop_get:cxN,
+% \prop_get:cnc
+% }
+% \begin{macro}[TF, tested = m3prop004]
+% {
+% \prop_get:NnN, \prop_get:NVN, \prop_get:NvN, \prop_get:NeN,
+% \prop_get:NoN, \prop_get:NxN,
+% \prop_get:cnN, \prop_get:cVN, \prop_get:cvN, \prop_get:ceN,
+% \prop_get:coN, \prop_get:cxN,
+% \prop_get:cnc
+% }
+% \begin{macro}{\@@_get:NnnTF}
+% \begin{macro}[EXP]{\@@_get_linked:w, \@@_get_linked_aux:w}
+% Here we implement both \cs{prop_get:NnN} and its branching version through
+% \cs{@@_get:NnnTF}. It receives the prop and key, followed by an assignment
+% used when the value is found, \meta{true code} to run after the assignment,
+% and some fall-back \meta{false code} for absent values. It relies on
+% \cs{@@_split:NnTFn}. For a flat prop, the first four arguments of
+% \cs{@@_split:NnTFn} are used, and run either the assignment~|#3{##3}| and
+% \meta{true code}~|#4|, or the \meta{false code}~|#5|.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_get:NnN #1#2#3
+ {
+ \@@_get:NnnTF #1 {#2}
+ { \tl_set:Nn #3 } { } { \tl_set:Nn #3 { \q_no_value } }
+ }
+\cs_generate_variant:Nn \prop_get:NnN { NV , Nv , Ne , c , cV , cv , ce }
+\cs_generate_variant:Nn \prop_get:NnN { No , Nx , co , cx }
+\cs_generate_variant:Nn \prop_get:NnN { cnc }
+\prg_new_protected_conditional:Npnn \prop_get:NnN #1#2#3 { T , F , TF }
+ {
+ \@@_get:NnnTF #1 {#2}
+ { \tl_set:Nn #3 } \prg_return_true: \prg_return_false:
+ }
+\prg_generate_conditional_variant:Nnn \prop_get:NnN
+ { NV , Nv , Ne , c , cV , cv , ce } { T , F , TF }
+\prg_generate_conditional_variant:Nnn \prop_get:NnN
+ { No , Nx , co , cx } { T , F , TF }
+\prg_generate_conditional_variant:Nnn \prop_get:NnN
+ { cnc } { T , F , TF }
+\cs_new_protected:Npn \@@_get:NnnTF #1#2#3#4#5
+ {
+ \@@_split:NnTFn #1 {#2}
+ { #3 {##2} #4 }
+ {#5}
+ { \exp_after:wN \@@_get_linked:w #1 {#2} {#3} {#4} {#5} }
+ }
+% \end{macrocode}
+% For a linked prop we must work a bit: \cs{@@_get_linked:w} is followed by
+% the expansion of the prop, then by four brace groups: the key~|#4|, the
+% assignment code~|#5|, \meta{true code}~|#6|, and \meta{false code}~|#7|. If
+% the key is present, its value is stored in the token list
+% \cs[no-index]{@@_}|#2~#4|. If that token list exists,
+% \cs{@@_get_linked_aux:w} gets called followed by the expansion of that token
+% list and we grab as~|#2| the value associated to that key, which we feed to
+% the assignment code and follow-up code. If the key is absent the token list
+% can be \tn{undefined} or \tn{relax}. In both cases \cs{@@_get_linked_aux:w}
+% finds an empty brace group as~|#2|, \cs{use_none:n} as~|#4| and the
+% \meta{false code} as~|#5|.
+% Note that we made \cs{@@_get_linked:w} and subsequent auxiliaries
+% expandable, because they are also used in \cs{prop_item:Nn}.
+% \begin{macrocode}
+\cs_new:Npn \@@_get_linked:w
+ \@@_flatten:w #1 \s_@@ #2#3#4#5#6#7
+ {
+ \if_cs_exist:w @@ ~ #2 ~ \tl_to_str:n {#4} \cs_end:
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_get_linked_aux:w
+ \cs:w @@ ~ #2 ~ \tl_to_str:n {#4} \exp_after:wN \cs_end:
+ \else:
+ \exp_after:wN \@@_get_linked_aux:w
+ \fi:
+ \s_@@_mark {#5} {#6}
+ \s_@@ { } \s_@@_mark \use_none:n {#7}
+ \s_@@_stop
+ }
+\cs_new:Npn \@@_get_linked_aux:w
+ #1 \s_@@ #2 #3 \s_@@_mark #4 #5 #6 \s_@@_stop { #4 {#2} #5 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \prop_item:Nn, \prop_item:NV, \prop_item:No, \prop_item:Ne,
+% \prop_item:cn, \prop_item:cV, \prop_item:co, \prop_item:ce
+% }
+% \begin{macro}[EXP]{\@@_item:nnn}
+% Getting the value corresponding to a key in a flat property list in an
+% expandable fashion simply uses \cs{prop_map_tokens:Nn} to go through
+% the property list. The auxiliary \cs{@@_item:nnn} receives the
+% search string~|#1|, the key~|#2| and the value~|#3| and returns as
+% appropriate.
+% \begin{macrocode}
+\cs_new:Npn \prop_item:Nn #1#2
+ {
+ \@@_if_flat:NTF #1
+ {
+ \exp_args:NNo \prop_map_tokens:Nn #1
+ {
+ \exp_after:wN \@@_item:nnn
+ \exp_after:wN { \tl_to_str:n {#2} }
+ }
+ }
+ { \exp_after:wN \@@_get_linked:w #1 {#2} \use:n { } { } }
+ }
+\cs_new:Npn \@@_item:nnn #1#2#3
+ {
+ \str_if_eq:eeT {#1} {#2}
+ { \prop_map_break:n { \exp_not:n {#3} } }
+ }
+\cs_generate_variant:Nn \prop_item:Nn { NV , No , Ne , c , cV , co , ce }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Removing data from property lists}
+%
+% \begin{macro}
+% {
+% \@@_pop:NnNNnTF,
+% \@@_pop_linked:wnNNnTF, \@@_pop_linked:NNNn,
+% \@@_pop_linked:w,
+% \@@_pop_linked_prev:w, \@@_pop_linked_next:w
+% }
+% This auxiliary is used by both the \cs[no-index]{prop_pop} family and
+% the \cs[no-index]{prop_remove} family of functions.
+% It receives a \meta{prop} and a \Arg{key}, three assignment functions
+% (\cs{tl_set:Nn} \cs{cs_set_eq:NN} \cs{cs_set_nopar:Npe} or their global
+% versions), then \Arg{code} \Arg{true code} \Arg{false code}.
+%
+% For a flat prop, split it. If the \meta{key} is there, reconstruct the rest
+% of the prop from the two extracts |##2| |##4| and assign using
+% \cs[index=tl_set:Nn]{tl_(g)set:Nn}, then run \meta{code} \Arg{value} with
+% the \meta{value} found, and run the \meta{true code}. If the \meta{key} is
+% absent, run the \meta{false code}.
+%
+% For a linked prop, the removal is done by \cs{@@_pop_linked:wnNNnTF}, which
+% removes the key--value pair from the doubly-linked list and runs its last
+% three arguments \Arg{code} \Arg{true code} \Arg{false code} depending on
+% whether the key--value is found, in the same way as for flat props.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_pop:NnNNnTF #1#2#3#4#5#6#7
+ {
+ \@@_split:NnTFn #1 {#2}
+ {
+ #4 #1 { \exp_not:n { \s_@@ \@@_chk:w ##1 ##3 } }
+ #5 {##2}
+ #6
+ }
+ {#7}
+ {
+ \exp_after:wN \@@_pop_linked:wnNNnTF #1 {#2}
+ #3 #4 {#5} {#6} {#7}
+ }
+ }
+% \end{macrocode}
+% The next auxiliary \cs{@@_pop_linked:wnNNnTF}, together with the |NNNn|
+% auxiliary, checks if the key is present in the \meta{linked prop}, then the
+% corresponding value (if present) is passed as a braced argument to the
+% \meta{code} and the \meta{true code} or \meta{false code} is run as
+% appropriate. Before that, there are also three assignments: the token lists
+% for the previous key and next key are made to point to each other, cf.\
+% \cs{@@_pop_linked:w}, and the token list for the given key is made
+% undefined.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_pop_linked:wnNNnTF
+ \@@_flatten:w #1 \s_@@ #2#3#4#5#6#7
+ {
+ \if_cs_exist:w @@ ~ #2 ~ \tl_to_str:n {#4} \cs_end:
+ \exp_after:wN \@@_pop_linked:NNNn
+ \cs:w @@ ~ #2 ~ \tl_to_str:n {#4} \cs_end:
+ #5 #6 {#7}
+ \else:
+ \exp_after:wN \use_iii:nnn
+ \fi:
+ \use_i:nn
+ }
+\cs_new_protected:Npn \@@_pop_linked:NNNn #1#2#3#4
+ {
+ \if_meaning:w \scan_stop: #1
+ \exp_after:wN \exp_after:wN \exp_after:wN \use_iii:nnn
+ \else:
+ \exp_after:wN \@@_pop_linked:w #1 #1 #2 #3 {#4}
+ \fi:
+ }
+\cs_new_protected:Npn \@@_pop_linked:w
+ \use_none:n #1#2 \s_@@ #3#4#5#6#7#8
+ {
+ #6 #5 \tex_undefined:D
+ #7 #1
+ {
+ \exp_after:wN \@@_pop_linked_prev:w #1
+ \exp_not:N #4
+ }
+ #7 #4
+ {
+ \exp_not:n { \use_none:n #1 }
+ \exp_not:f { \exp_after:wN \@@_pop_linked_next:w #4 }
+ }
+ #8 {#3}
+ }
+\cs_new:Npn \@@_pop_linked_prev:w #1 \s_@@ #2#3
+ { \exp_not:n { #1 \s_@@ {#2} } }
+\cs_new:Npn \@@_pop_linked_next:w \use_none:n #1 { \exp_stop_f: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[tested = m3prop002]
+% {
+% \prop_remove:Nn, \prop_remove:NV, \prop_remove:Ne,
+% \prop_remove:cn, \prop_remove:cV, \prop_remove:ce
+% }
+% \begin{macro}[tested = m3prop002]
+% {
+% \prop_gremove:Nn, \prop_gremove:NV, \prop_gremove:Ne,
+% \prop_gremove:cn, \prop_gremove:cV, \prop_gremove:ce
+% }
+% Deleting from a property relies on \cs{@@_pop:NnNNnTF}. The three
+% assignment functions are suitably local or global. The last three arguments
+% are \cs{use_none:n} and two empty brace groups: if the key is found we get
+% \cs{use_none:n} \Arg{key} \meta{empty}, which expands to nothing, and
+% otherwise we just get \meta{empty}. The auxiliary takes care of actually
+% removing the entry from the prop.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_remove:Nn #1#2
+ {
+ \@@_pop:NnNNnTF #1 {#2}
+ \cs_set_eq:NN \cs_set_nopar:Npe
+ \use_none:n { } { }
+ }
+\cs_new_protected:Npn \prop_gremove:Nn #1#2
+ {
+ \@@_pop:NnNNnTF #1 {#2}
+ \cs_gset_eq:NN \cs_gset_nopar:Npe
+ \use_none:n { } { }
+ }
+\cs_generate_variant:Nn \prop_remove:Nn { NV , Ne , c , cV , ce }
+\cs_generate_variant:Nn \prop_gremove:Nn { NV , Ne , c , cV , ce }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[tested = m3prop002]
+% {
+% \prop_pop:NnN, \prop_pop:NVN, \prop_pop:NoN,
+% \prop_pop:cnN, \prop_pop:cVN, \prop_pop:coN,
+% \prop_gpop:NnN, \prop_gpop:NVN, \prop_gpop:NoN,
+% \prop_gpop:cnN, \prop_gpop:cVN, \prop_gpop:coN,
+% }
+% \begin{macro}[TF, tested = m3prop004]
+% {
+% \prop_pop:NnN, \prop_pop:NVN, \prop_pop:NoN,
+% \prop_pop:cnN, \prop_pop:cVN, \prop_pop:coN,
+% \prop_gpop:NnN, \prop_gpop:NVN, \prop_gpop:NoN,
+% \prop_gpop:cnN, \prop_gpop:cVN, \prop_gpop:coN,
+% }
+% Popping a value is almost the same, but the value found is kept.
+% For the non-branching version, we additionally set the target token list to
+% \cs{q_no_value}, while for the branching version we must produce
+% \cs{prg_return_true:} or \cs{prg_return_false:}.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_pop:NnN #1#2#3
+ {
+ \@@_pop:NnNNnTF #1 {#2}
+ \cs_set_eq:NN \cs_set_nopar:Npe
+ { \tl_set:Nn #3 } { } { \tl_set:Nn #3 { \q_no_value } }
+ }
+\cs_new_protected:Npn \prop_gpop:NnN #1#2#3
+ {
+ \@@_pop:NnNNnTF #1 {#2}
+ \cs_gset_eq:NN \cs_gset_nopar:Npe
+ { \tl_set:Nn #3 } { } { \tl_set:Nn #3 { \q_no_value } }
+ }
+\cs_generate_variant:Nn \prop_pop:NnN { NV , No }
+\cs_generate_variant:Nn \prop_pop:NnN { c , cV , co }
+\cs_generate_variant:Nn \prop_gpop:NnN { NV , No }
+\cs_generate_variant:Nn \prop_gpop:NnN { c , cV , co }
+\prg_new_protected_conditional:Npnn \prop_pop:NnN #1#2#3 { T , F , TF }
+ {
+ \@@_pop:NnNNnTF #1 {#2}
+ \cs_set_eq:NN \cs_set_nopar:Npe
+ { \tl_set:Nn #3 } \prg_return_true: \prg_return_false:
+ }
+\prg_new_protected_conditional:Npnn \prop_gpop:NnN #1#2#3 { T , F , TF }
+ {
+ \@@_pop:NnNNnTF #1 {#2}
+ \cs_gset_eq:NN \cs_gset_nopar:Npe
+ { \tl_set:Nn #3 } \prg_return_true: \prg_return_false:
+ }
+\prg_generate_conditional_variant:Nnn \prop_pop:NnN
+ { NV , No , c , cV , co } { T , F , TF }
+\prg_generate_conditional_variant:Nnn \prop_gpop:NnN
+ { NV , No , c , cV , co } { T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Adding data to property lists}
+%
+% \begin{macro}[tested = m3prop002]
+% {
+% \prop_put:Nnn, \prop_put:NnV, \prop_put:Nnv, \prop_put:Nne,
+% \prop_put:NVn, \prop_put:NVV, \prop_put:NVv, \prop_put:NVe,
+% \prop_put:Nvn, \prop_put:NvV, \prop_put:Nvv, \prop_put:Nve,
+% \prop_put:Nen, \prop_put:NeV, \prop_put:Nev, \prop_put:Nee,
+% \prop_put:Nno, \prop_put:Non, \prop_put:Noo,
+% \prop_put:Nnx, \prop_put:NVx, \prop_put:NxV, \prop_put:Nxx,
+% \prop_put:cnn, \prop_put:cnV, \prop_put:cnv, \prop_put:cne,
+% \prop_put:cVn, \prop_put:cVV, \prop_put:cVv, \prop_put:cVe,
+% \prop_put:cvn, \prop_put:cvV, \prop_put:cvv, \prop_put:cve,
+% \prop_put:cen, \prop_put:ceV, \prop_put:cev, \prop_put:cee,
+% \prop_put:cno, \prop_put:con, \prop_put:coo,
+% \prop_put:cnx, \prop_put:cVx, \prop_put:cxV, \prop_put:cxx
+% }
+% \begin{macro}[tested = m3prop002]
+% {
+% \prop_gput:Nnn, \prop_gput:NnV, \prop_gput:Nnv, \prop_gput:Nne,
+% \prop_gput:NVn, \prop_gput:NVV, \prop_gput:NVv, \prop_gput:NVe,
+% \prop_gput:Nvn, \prop_gput:NvV, \prop_gput:Nvv, \prop_gput:Nve,
+% \prop_gput:Nen, \prop_gput:NeV, \prop_gput:Nev, \prop_gput:Nee,
+% \prop_gput:Nno, \prop_gput:Non, \prop_gput:Noo,
+% \prop_gput:Nnx, \prop_gput:NVx, \prop_gput:NxV, \prop_gput:Nxx,
+% \prop_gput:cnn, \prop_gput:cnV, \prop_gput:cnv, \prop_gput:cne,
+% \prop_gput:cVn, \prop_gput:cVV, \prop_gput:cVv, \prop_gput:cVe,
+% \prop_gput:cvn, \prop_gput:cvV, \prop_gput:cvv, \prop_gput:cve,
+% \prop_gput:cen, \prop_gput:ceV, \prop_gput:cev, \prop_gput:cee,
+% \prop_gput:cno, \prop_gput:con, \prop_gput:coo,
+% \prop_gput:cnx, \prop_gput:cVx, \prop_gput:cxV, \prop_gput:cxx
+% }
+% \begin{macro}[tested = m3prop002]
+% {
+% \prop_put_if_not_in:Nnn, \prop_put_if_not_in:NVn, \prop_put_if_not_in:NnV,
+% \prop_put_if_not_in:cnn, \prop_put_if_not_in:cVn, \prop_put_if_not_in:cnV,
+% \prop_gput_if_not_in:Nnn, \prop_gput_if_not_in:NVn, \prop_gput_if_not_in:NnV,
+% \prop_gput_if_not_in:cnn, \prop_gput_if_not_in:cVn, \prop_gput_if_not_in:cnV
+% }
+% \begin{macro}[tested = m3prop002]
+% {
+% \@@_put:NNNnn, \@@_put_linked:wnNN,
+% \@@_put_linked:NNNN, \@@_put_linked_old:w,
+% \@@_put_linked_new:w
+% }
+% All of the \cs[no-index]{prop_(g)put(_if_new):Nnn} functions are
+% based on the same auxiliary, which receives \meta{code} and an
+% \enquote{assignment}, followed by \meta{prop} \Arg{key} \Arg{new
+% value}. The
+% assignment \cs[index=cs_set_nopar:Npe]{cs_(g)set_nopar:Npe} is the
+% primitive assignment without any checking: in the case of linked
+% props it is applied to individual
+% pieces of the linked prop, which are typically not yet defined.
+% Debugging the scope of the variable is done at a higher level by
+% letting \pkg{l3debug} change \cs{prop_put:Nnn} and friends. This
+% allows other \pkg{l3prop} commands to directly call the underlying
+% auxiliary to skip this checking step and avoid getting multiple
+% error messages for the same error.
+% The \meta{code} (empty for |put| and \cs{use_none:nnn} for
+% |put_if_not_in|) is placed before the assignment in cases where the key
+% is already present, in order to suppress the assignment in the
+% |put_if_not_in| case.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_put:Nnn
+ { \@@_put:nNNnn { } \cs_set_nopar:Npe }
+\cs_new_protected:Npn \prop_gput:Nnn
+ { \@@_put:nNNnn { } \cs_gset_nopar:Npe }
+\cs_new_protected:Npn \prop_put_if_not_in:Nnn
+ { \@@_put:nNNnn \use_none:nnn \cs_set_nopar:Npe }
+\cs_new_protected:Npn \prop_gput_if_not_in:Nnn
+ { \@@_put:nNNnn \use_none:nnn \cs_gset_nopar:Npe }
+\cs_generate_variant:Nn \prop_put:Nnn
+ {
+ NnV , Nnv , Nne , NV , NVV , NVv , NVe ,
+ Nv , NvV , Nvv , Nve , Ne , NeV , Nev , Nee
+ }
+\cs_generate_variant:Nn \prop_put:Nnn
+ { Nno , No , Noo , Nnx , NVx , NxV , Nxx }
+\cs_generate_variant:Nn \prop_put:Nnn
+ {
+ c , cnV , cnv , cne , cV , cVV , cVv , cVe ,
+ cv , cvV , cvv , cve , ce , ceV , cev , cee
+ }
+\cs_generate_variant:Nn \prop_put:Nnn
+ { cno , co , coo , cnx , cVx , cxV , cxx }
+\cs_generate_variant:Nn \prop_gput:Nnn
+ {
+ NnV , Nnv , Nne , NV , NVV , NVv , NVe ,
+ Nv , NvV , Nvv , Nve , Ne , NeV , Nev , Nee
+ }
+\cs_generate_variant:Nn \prop_gput:Nnn
+ { Nno , No , Noo , Nnx , NVx , NxV , Nxx }
+\cs_generate_variant:Nn \prop_gput:Nnn
+ {
+ c , cnV , cnv , cne , cV , cVV , cVv , cVe ,
+ cv , cvV , cvv , cve , ce , ceV , cev , cee
+ }
+\cs_generate_variant:Nn \prop_gput:Nnn
+ { cno , co , coo , cnx , cVx , cxV , cxx }
+\cs_generate_variant:Nn \prop_put_if_not_in:Nnn
+ { NnV , NV , c , cnV , cV }
+\cs_generate_variant:Nn \prop_gput_if_not_in:Nnn
+ { NnV , NV , c , cnV , cV }
+% \end{macrocode}
+% Since the true branch of \cs{@@_split:NnTFn} is used as the
+% replacement text of an internal macro, and since the \meta{key} and
+% new \meta{value} may contain arbitrary tokens, it is not safe to
+% include them in the argument of \cs{@@_split:NnTFn}. We thus start
+% by storing in \cs{l_@@_internal_tl} tokens which (after
+% \texttt{x}-expansion) encode the key--value pair. This variable can
+% safely be used in \cs{@@_split:NnTFn}. For a flat prop, if the
+% \meta{key} was absent, append the new key--value to the list;
+% otherwise concatenate the extracts |##2| and |##4| with the new
+% key--value pair \cs{l_@@_internal_tl}. The updated entry is placed
+% at the same spot as the original \meta{key} in the property list,
+% preserving the order of entries. For a linked prop, call
+% \cs{@@_put_linked:wnNN}, which constructs the control sequence in
+% which we will place the new value. If it matches \cs{scan_stop:}
+% then the key was not yet there and we add it using
+% \cs{@@_put_linked_new:w}, otherwise it was already there and we use
+% \cs{@@_put_linked_old:w}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_put:nNNnn #1#2#3#4#5
+ {
+ \tl_set:Nn \l_@@_internal_tl
+ {
+ \exp_not:N \@@_pair:wn \tl_to_str:n {#4}
+ \s_@@ { \exp_not:n {#5} }
+ }
+ \@@_split:NnTFn #3 {#4}
+ {
+ #1 #2 #3
+ {
+ \s_@@ \@@_chk:w \exp_not:n {##1}
+ \l_@@_internal_tl \exp_not:n {##3}
+ }
+ }
+ { #2 #3 { \exp_not:o {#3} \l_@@_internal_tl } }
+ { \exp_after:wN \@@_put_linked:wnnN #3 {#4} {#1} #2 }
+ }
+\cs_new_protected:Npn \@@_put_linked:wnnN
+ \@@_flatten:w #1 \s_@@ #2#3#4
+ {
+ \exp_after:wN \@@_put_linked:NNnN
+ \cs:w @@ ~ #2 ~ \tl_to_str:n {#4} \cs_end:
+ #1
+ }
+\cs_new_protected:Npn \@@_put_linked:NNnN #1#2#3#4
+ {
+ \if_meaning:w \scan_stop: #1
+ \exp_after:wN \@@_put_linked_new:w #2 #1 #2 #4
+ \else:
+ \exp_after:wN \@@_put_linked_old:w #1 { #3 #4 #1 }
+ \fi:
+ }
+% \end{macrocode}
+% To add a new entry, \cs{@@_put_linked_new:w} receives the expansion
+% of the end-pointer, namely \cs{use_none:n} \meta{last key pointer},
+% followed by the new key pointer~|#2|, the end pointer~|#3|, and an
+% assignment function~|#4|. Set up the doubly-linked list in the
+% order |#1|, |#2|, |#3|, placing the key--value pair
+% \cs{l_@@_internal_tl} in~|#2|. To replace an old entry,
+% \cs{@@_put_linked_old:w} receives the expansion of that entry, and
+% it reassigns it (|#5|) using the assignment~|#6|, by simply
+% replacing the payload |#2| \cs{s_@@} |#3| by \cs{l_@@_internal_tl}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_put_linked_new:w
+ \use_none:n #1#2#3#4
+ {
+ #4 #1
+ {
+ \exp_after:wN \@@_pop_linked_prev:w #1
+ \exp_not:N #2
+ }
+ #4 #2
+ {
+ \exp_not:n { \use_none:n #1 }
+ \l_@@_internal_tl
+ \exp_not:N #3
+ }
+ #4 #3 { \exp_not:n { \use_none:n #2 } }
+ }
+\cs_new_protected:Npn \@@_put_linked_old:w
+ \use_none:n #1#2 \s_@@ #3#4#5
+ {
+ #5
+ {
+ \exp_not:n { \use_none:n #1 }
+ \l_@@_internal_tl
+ \exp_not:N #4
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Property list conditionals}
+%
+% \begin{macro}[pTF, tested = m3prop004]{\prop_if_exist:N, \prop_if_exist:c}
+% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \prop_if_exist:N \cs_if_exist:N
+ { TF , T , F , p }
+\prg_new_eq_conditional:NNn \prop_if_exist:c \cs_if_exist:c
+ { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF, tested = m3prop003]{\prop_if_empty:N, \prop_if_empty:c}
+% \begin{macro}{\@@_if_empty_return:w}
+% A flat property list is empty if it matches \cs{c_empty_prop}. A linked
+% property list is empty if its second token (the end pointer) and last token
+% (the first key pointer) are equal. There cannot be false positives because
+% the end pointer takes the form \cs{use_none:n} \meta{pointer} while the
+% other pointers have more elaborate structure. The subtle code branch here
+% is when a non-empty flat property list is given: then \cs{@@_if_empty:w}
+% reads the whole property list as~|#1| and |#2|, |#3|, |#4| are |2|, |3|,
+% |4|, respectively.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \prop_if_empty:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \c_empty_prop
+ \prg_return_true:
+ \else:
+ \exp_after:wN \@@_if_empty_return:w #1
+ \@@_flatten:w 2 \s_@@ 34 \s_@@_stop
+ \fi:
+ }
+\cs_new:Npn \@@_if_empty_return:w
+ #1 \@@_flatten:w #2 \s_@@ #3#4#5 \s_@@_stop
+ {
+ \if_meaning:w #2 #4
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_generate_conditional_variant:Nnn \prop_if_empty:N
+ { c } { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF, tested = m3prop003]
+% {
+% \prop_if_in:Nn, \prop_if_in:NV, \prop_if_in:Ne, \prop_if_in:No,
+% \prop_if_in:cn, \prop_if_in:cV, \prop_if_in:ce, \prop_if_in:co
+% }
+% \begin{macro}[EXP]{\@@_if_in_flat:nnn}
+% For a linked prop, use \cs{@@_get_linked:w} to look up whether the control
+% sequence constructed from the prefix and the sought-after key exists; this
+% auxiliary calls \cs{use_none:n} \Arg{value} \cs{prg_return_true:} if the key
+% is found, and otherwise \cs{prg_return_false:}. For a flat prop, testing
+% expandably if a key is there requires to go through the key--value pairs one
+% by one. This is rather slow, and a faster test would be
+% \begin{verbatim}
+% \prg_new_protected_conditional:Npnn \prop_if_in:Nn #1 #2
+% {
+% \@@_split:NnTFn #1 {#2}
+% { \prg_return_true: }
+% { \prg_return_false: }
+% { ... }
+% }
+% \end{verbatim}
+% but \cs{@@_split:NnTFn} is non-expandable.
+% Instead, we use \cs{prop_map_tokens:Nn} to compare the search key to
+% each key in turn using \cs{str_if_eq:ee}, which is expandable.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \prop_if_in:Nn #1#2 { p , T , F , TF }
+ {
+ \@@_if_flat:NTF #1
+ {
+ \exp_after:wN \prop_map_tokens:Nn \exp_after:wN #1
+ {
+ \exp_after:wN \@@_if_in_flat:nnn
+ \exp_after:wN { \tl_to_str:n {#2} }
+ }
+ \prg_return_false:
+ }
+ {
+ \exp_after:wN \@@_get_linked:w #1 {#2}
+ \use_none:n \prg_return_true: \prg_return_false:
+ }
+ }
+\cs_new:Npn \@@_if_in_flat:nnn #1#2#3
+ {
+ \str_if_eq:eeT {#1} {#2}
+ { \prop_map_break:n { \use_i:nn \prg_return_true: } }
+ }
+\prg_generate_conditional_variant:Nnn \prop_if_in:Nn
+ { NV , Ne , No , c , cV , ce , co } { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Mapping over property lists}
+%
+% \begin{macro}[tested = m3prop003]
+% {
+% \prop_map_function:NN, \prop_map_function:Nc,
+% \prop_map_function:cN, \prop_map_function:cc
+% }
+% \begin{macro}{\@@_map_function:Nw}
+% We first |f|-expand to flatten~|#1| in case it was a linked list.
+% The \cs{use_i:nnn} removes the leading \cs{s_@@} \cs{@@_chk:w} of
+% the flattened prop.
+% The even-numbered arguments of \cs{@@_map_function:Nw} are keys,
+% hence have string catcodes, except at the end where they are
+% \cs{fi:} \cs{prop_map_break:}. The \cs{fi:} ends the \cs{if_false:}
+% |#|\meta{even} \cs{fi:} construction and we jump out of the loop.
+% No need for any quark test.
+% \begin{macrocode}
+\cs_new:Npn \prop_map_function:NN #1#2
+ {
+ \exp_last_unbraced:Nnf
+ \use_i:nnn { \@@_map_function:Nw #2 } #1
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
+ \prg_break_point:Nn \prop_map_break: { }
+ }
+\cs_new:Npn \@@_map_function:Nw #1
+ \@@_pair:wn #2 \s_@@ #3
+ \@@_pair:wn #4 \s_@@ #5
+ \@@_pair:wn #6 \s_@@ #7
+ \@@_pair:wn #8 \s_@@ #9
+ {
+ \if_false: #2 \fi: #1 {#2} {#3}
+ \if_false: #4 \fi: #1 {#4} {#5}
+ \if_false: #6 \fi: #1 {#6} {#7}
+ \if_false: #8 \fi: #1 {#8} {#9}
+ \@@_map_function:Nw #1
+ }
+\cs_generate_variant:Nn \prop_map_function:NN { Nc , c , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[tested = m3prop003]{\prop_map_inline:Nn, \prop_map_inline:cn}
+% Mapping in line requires a nesting level counter. Store the current
+% definition of \cs{@@_pair:wn}, and define it anew. At the end of
+% the loop, revert to the earlier definition. Note that besides pairs
+% of the form \cs{@@_pair:wn} \meta{key} \cs{s_@@} \Arg{value}, there
+% are a leading and a trailing tokens, but both are equal to
+% \cs{scan_stop:}, hence have no effect in such inline mapping.
+% Such \cs{scan_stop:} could have affected ligatures if they appeared
+% during the mapping.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_map_inline:Nn #1#2
+ {
+ \cs_gset_eq:cN
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :wn } \@@_pair:wn
+ \int_gincr:N \g__kernel_prg_map_int
+ \cs_gset_protected:Npn \@@_pair:wn ##1 \s_@@ ##2 {#2}
+ \exp_last_unbraced:Nf \use_none:nn #1
+ \prg_break_point:Nn \prop_map_break:
+ {
+ \int_gdecr:N \g__kernel_prg_map_int
+ \cs_gset_eq:Nc \@@_pair:wn
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :wn }
+ }
+ }
+\cs_generate_variant:Nn \prop_map_inline:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\prop_map_tokens:Nn, \prop_map_tokens:cn}
+% \begin{macro}{\@@_map_tokens:nw}
+% The mapping is very similar to \cs{prop_map_function:NN}.
+% The odd construction
+% |\use:n {#1}| allows |#1| to contain any token without interfering
+% with \cs{prop_map_break:}. The loop stops when the \meta{key}
+% between \cs{@@_pair:wn} and \cs{s_@@} is \cs{fi:}
+% \cs{prop_map_break:} instead of being a string.
+% \begin{macrocode}
+\cs_new:Npn \prop_map_tokens:Nn #1#2
+ {
+ \exp_last_unbraced:Nnf
+ \use_i:nnn { \@@_map_tokens:nw {#2} } #1
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
+ \prg_break_point:Nn \prop_map_break: { }
+ }
+\cs_new:Npn \@@_map_tokens:nw #1
+ \@@_pair:wn #2 \s_@@ #3
+ \@@_pair:wn #4 \s_@@ #5
+ \@@_pair:wn #6 \s_@@ #7
+ \@@_pair:wn #8 \s_@@ #9
+ {
+ \if_false: #2 \fi: \use:n {#1} {#2} {#3}
+ \if_false: #4 \fi: \use:n {#1} {#4} {#5}
+ \if_false: #6 \fi: \use:n {#1} {#6} {#7}
+ \if_false: #8 \fi: \use:n {#1} {#8} {#9}
+ \@@_map_tokens:nw {#1}
+ }
+\cs_generate_variant:Nn \prop_map_tokens:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}[tested = m3prop003]{\prop_map_break:}
+% \begin{macro}[tested = m3prop003]{\prop_map_break:n}
+% The break statements are based on the general \cs{prg_map_break:Nn}.
+% \begin{macrocode}
+\cs_new:Npn \prop_map_break:
+ { \prg_map_break:Nn \prop_map_break: { } }
+\cs_new:Npn \prop_map_break:n
+ { \prg_map_break:Nn \prop_map_break: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Uses of mapping over property lists}
+%
+% \begin{macro}[EXP]{\prop_count:N, \prop_count:c}
+% \begin{macro}[EXP]{\@@_count:nn}
+% Counting the key--value pairs in a property list is done using the
+% same approach as for other count functions: turn each entry into a
+% \texttt{+1} then use integer evaluation to actually do the
+% mathematics.
+% \begin{macrocode}
+\cs_new:Npn \prop_count:N #1
+ {
+ \int_eval:n
+ {
+ 0
+ \prop_map_function:NN #1 \@@_count:nn
+ }
+ }
+\cs_new:Npn \@@_count:nn #1#2 { + 1 }
+\cs_generate_variant:Nn \prop_count:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\prop_to_keyval:N}
+% \begin{macro}[EXP]
+% {\@@_to_keyval_exp_after:wN, \@@_to_keyval:nn, \@@_to_keyval:nnw}
+% Each property name and value pair will be returned in the form
+% \verb*| |\marg{name}\verb*|= |\marg{value}. As one of the main use cases for
+% this macro is to pass the \meta{property list} on to a key--value parser, we
+% have to make sure that the behaviour is as good as possible. Using a space
+% before the opening brace we get the correct brace stripping behaviour for
+% most of the key--value parsers available in \LaTeX{}.
+% Iterate over the
+% \meta{property list} and remove the leading comma afterwards. Only the value
+% has to be protected in \cs{__kernel_exp_not:w} as the property name is
+% always a string. After the loop the leading comma is removed by
+% \cs{use_none:n} and afterwards \cs{__kernel_exp_not:w} eventually finds the
+% opening brace of its argument.
+% \begin{macrocode}
+\cs_new:Npn \prop_to_keyval:N #1
+ {
+ \__kernel_exp_not:w
+ \prop_if_empty:NTF #1
+ { {} }
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ {
+ \tex_expanded:D
+ {
+ \exp_not:N \use_none:n
+ \prop_map_function:NN #1 \@@_to_keyval:nn
+ }
+ }
+ }
+ }
+\cs_new:Npn \@@_to_keyval:nn #1#2
+ { , ~ {#1} =~ { \__kernel_exp_not:w {#2} } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Viewing property lists}
+%
+% \begin{macro}[tested = m3show001]
+% {\prop_show:N, \prop_show:c, \prop_log:N, \prop_log:c}
+% \begin{macro}{\@@_show:NN, \@@_show_finally:NNn, \@@_show_prepare:w, \@@_show_loop:NNw, \@@_show_bad_name:NNN, \@@_show_end:NNN, \@@_show_loop_key:wNNN}
+% \begin{macro}[rEXP]{\@@_show_flat:w, \@@_show_linked:w}
+% Experience shows one source of problems is very hard to debug: when
+% a data structure such as a |seq| or~|prop| gets corrupted. In the
+% past, \cs{prop_show:N} would in some cases happily show items of
+% such a |prop|, even though other more demanding \pkg{l3prop}
+% functions would choke. It is thus best to make \cs{prop_show:N}
+% check very thoroughly the structure and flag issues, even though
+% that is very painful for linked props. Throughout the code below,
+% we strive to remain as safe as possible, but in the explanations we
+% only state what the arguments are when the prop is correctly formed,
+% rather than saying at every step that various arguments can be
+% arbitrary junk, made safe by using \cs{tl_to_str:n} generously.
+%
+% The general \cs{__kernel_chk_tl_type:NnnT} checks that its first
+% argument is a token list, and if it is, then it \texttt{e}-expands
+% its second argument and compares with the contents of its first
+% argument. Thus, within this \texttt{e}-expansion it is safe to use
+% \cs{@@_if_flat:NTF} to check if the prop is flat or linked. In the
+% flat case we simply reconstruct the expected structure using
+% \cs{@@_show_flat:w}, which loops through the prop and correctly
+% turns all keys to strings for instance. In the linked case, we use
+% \cs{@@_show_linked:w}, which ensures the form \cs{@@_flatten:w}
+% \cs[no-index]{@@~\meta{prefix}} \cs{s_@@} \Arg{prefix} \meta{rest},
+% where \meta{prefix} is made into a string and \meta{rest} cannot be
+% a brace group or multiple tokens since \cs{@@_show_linked:w} would
+% in such cases give a different result from the original token list.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_show:N { \@@_show:NN \msg_show:nneeee }
+\cs_generate_variant:Nn \prop_show:N { c }
+\cs_new_protected:Npn \prop_log:N { \@@_show:NN \msg_log:nneeee }
+\cs_generate_variant:Nn \prop_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_chk_tl_type:NnnT #2 { prop }
+ {
+ \@@_if_flat:NTF #2
+ {
+ \s_@@ \@@_chk:w
+ \exp_after:wN \@@_show_flat:w #2
+ \s_@@ { }
+ \@@_pair:wn \q_@@_recursion_tail \s_@@ { }
+ \q_@@_recursion_stop
+ }
+ { \exp_after:wN \@@_show_linked:w #2 \s_@@ ! ? \s_@@_stop }
+ }
+ {
+ \@@_if_flat:NTF #2
+ { \@@_show_finally:NNn #1 #2 { flat } }
+ {
+ \tl_set:Nn \l_@@_internal_tl { #1 #2 }
+ \exp_after:wN \@@_show_prepare:w #2 #2
+ }
+ }
+ }
+\cs_new:Npn \@@_show_flat:w #1 \@@_pair:wn #2 \s_@@ #3
+ {
+ \@@_if_recursion_tail_stop:n {#2}
+ \exp_not:N \@@_pair:wn \tl_to_str:n {#2} \s_@@ \exp_not:n { {#3} }
+ \@@_show_flat:w
+ }
+\cs_new:Npn \@@_show_linked:w #1 \s_@@ #2#3#4 \s_@@_stop
+ {
+ \exp_not:N \@@_flatten:w
+ \exp_not:c { @@ ~ \tl_to_str:n {#2} }
+ \s_@@ { \tl_to_str:n {#2} }
+ \exp_not:n {#3}
+ }
+% \end{macrocode}
+% For flat props we are done by using \cs{msg_show:nneeee} or
+% \cs{msg_log:nneeee}. The auxiliary \cs{@@_show_finally:NNn} is
+% eventually also used in the linked case after some more tests. To
+% avoid having to bring along the message function and the property
+% list, we store them into \cs{l_@@_internal_tl}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show_finally:NNn #1#2#3
+ {
+ #1 { prop } { show }
+ { \token_to_str:N #2 }
+ { \prop_map_function:NN #2 \msg_show_item:nn }
+ {#3} { }
+ }
+% \end{macrocode}
+% For linked props, we now know they have a reasonable form so that we
+% are calling \cs{@@_show_prepare:w} \cs{@@_flatten:w}
+% \cs[no-index]{@@~\meta{prefix}} \cs{s_@@} \Arg{prefix} \meta{token}
+% \meta{property list}, and the task is to loop through the linked
+% list and check integrity. We first set things up: the auxiliary
+% \cs{@@_tmp:w} will be in charge of checking that various tokens
+% start with \cs[no-index]{@@~\meta{prefix}} (in the sense of string
+% representations), and calling one of \cs{@@_show_loop_key:wNNN},
+% \cs{@@_show_end:NNN}, \cs{@@_show_bad_name:NNN}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show_prepare:w
+ \@@_flatten:w #1 \s_@@ #2#3#4
+ {
+ \use:e
+ {
+ \cs_set_nopar:Npn \exp_not:N \@@_tmp:w
+ ##1 \token_to_str:N #1 ##2 \s_@@_mark ##3 \s_@@_stop
+ {
+ \exp_not:N \tl_if_empty:nTF {##1}
+ {
+ \exp_not:N \tl_if_head_is_space:nTF {##2}
+ { \exp_not:N \exp_args:Nf \@@_show_loop_key:wNNN }
+ { \exp_not:N \tl_if_empty:nTF }
+ {##2}
+ }
+ { \exp_not:N \use_ii:nn }
+ \@@_show_end:NNN
+ \@@_show_bad_name:NNN
+ }
+ }
+ \exp_last_unbraced:NNNo \@@_show_loop:NNw #1 #4 #4
+ }
+% \end{macrocode}
+% The loop will consist of calls to \cs{@@_show_loop:NNw}
+% \cs[no-index]{@@~\meta{prefix}} \meta{token} \meta{expansion}, where
+% \meta{token} is one of the items in the list, specifically the key
+% container for \meta{key$_{i-1}$} (starting at $i=1$ with the
+% property list variable itself), and \meta{expansion} stands for the
+% expansion of that token, which has already been checked, and takes
+% the form \meta{junk} \cs{s_@@} \Arg{value}
+% \cs[no-index]{@@~\meta{prefix}~\meta{key_i}}. Thus, the loop
+% auxiliary receives the prefix command as |#1|, and the $(i-1)$-th
+% and $i$-th key containers as |#2| and~|#5|. Then \cs{@@_tmp:w}
+% checks that the name of the $i$-th key container is valid.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show_loop:NNw #1#2 #3 \s_@@ #4#5
+ {
+ \exp_last_two_unbraced:Noo \@@_tmp:w
+ { \token_to_str:N #5 \s_@@_mark }
+ { \token_to_str:N #1 \s_@@_mark \s_@@_stop }
+ #1 #2 #5
+ }
+% \end{macrocode}
+% If the $i$-th key container has the wrong name we get
+% \cs{@@_show_bad_name:NNN} \cs[no-index]{@@~\meta{prefix}}
+% \meta{previous container} \meta{current container with bad name}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show_bad_name:NNN #1#2#3
+ {
+ \msg_error:nneeee { prop } { bad-link }
+ { \tl_tail:N \l_@@_internal_tl }
+ { \token_to_str:N #2 }
+ { \token_to_str:N #3 }
+ { \token_to_str:N #1 }
+ }
+% \end{macrocode}
+% If the $i$-th key container has the name
+% \cs[no-index]{@@~\meta{prefix}} (without space), it is the trailing
+% one. We check that it is the right kind of macro to be a token
+% list, and that it has the right contents \cs{use_none:n}
+% \meta{previous container}. If so, we are done checking everything,
+% and we display the property list using the message function and
+% property list name stored in \cs{l_@@_internal_tl}. Note that we
+% also use this \cs{l_@@_internal_tl} in the type argument of
+% \cs{__kernel_chk_tl_type:NnnT}, to build up the name
+% \enquote{\meta{property list} prop entry} used in error messages.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show_end:NNN #1#2#3
+ {
+ \__kernel_chk_tl_type:NnnT #3
+ { \tl_tail:N \l_@@_internal_tl prop~entry }
+ { \exp_not:n { \use_none:n #2 } }
+ {
+ \exp_after:wN \@@_show_finally:NNn
+ \l_@@_internal_tl { linked }
+ }
+ }
+% \end{macrocode}
+% If the $i$-th container has a name \cs[no-index]{@@~\meta{prefix}
+% \meta{key}} (with a space before the key), then we have a call to
+% \cs{@@_show_loop_key:wNNN} \Arg{key} \meta{junk_1} \meta{junk_2}
+% \cs[no-index]{@@~\meta{prefix}} \meta{previous container}
+% \meta{current container}. (with an \texttt{f}-expansion to eliminate
+% the space). The first argument is the \meta{key} without a leading
+% space, thanks to a judicious \texttt{f}-expansion earlier on. We
+% check that the \meta{current container} is a token list with the
+% expected structure \cs{use_none:n} \meta{previous container}
+% \cs{@@_pair:wn} \meta{string} \cs{s_@@} \Arg{anything} \meta{single
+% token}. The auxiliary \cs{@@_show_flat:w} is reused to produce the
+% \cs{@@_pair:wn} part, and the last token is produced by
+% \cs{tl_item:Nn} (we don't waste a specialized auxiliary to speed
+% that up). If the check succeed, move on to the next item.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show_loop_key:wNNN #1#2#3#4#5#6
+ {
+ \__kernel_chk_tl_type:NnnT #6
+ { \tl_tail:N \l_@@_internal_tl prop~entry }
+ {
+ \exp_not:n { \use_none:n #5 }
+ \exp_after:wN \@@_show_flat:w #6 \s_@@ { }
+ \@@_pair:wn \q_@@_recursion_tail \s_@@ { }
+ \q_@@_recursion_stop
+ \tl_item:Nn #6 { -1 }
+ }
+ { \exp_last_unbraced:NNNo \@@_show_loop:NNw #4 #6 #6 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3quark.dtx b/macros/latex-dev/required/l3kernel/l3quark.dtx
new file mode 100644
index 0000000000..6dba950462
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3quark.dtx
@@ -0,0 +1,1008 @@
+% \iffalse meta-comment
+%
+%% File: l3quark.dtx
+%
+% Copyright (C) 1990-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3quark} module\\ Quarks and scan marks^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% Two special types of constants in \LaTeX3 are \enquote{quarks} and
+% \enquote{scan marks}. By convention all constants of type quark
+% start out with |\q_|, and scan marks start with |\s_|.
+%
+% \section{Quarks}
+%
+% Quarks are control sequences (and in fact, token lists) that expand
+% to themselves and should
+% therefore \emph{never} be executed directly in the code.
+% This would result in an endless loop!
+%
+% They are meant to be used as delimiter in weird functions, the most
+% common use case being the `stop token' (\emph{i.e.}~\cs{q_stop}).
+% For example, when writing a macro to parse a user-defined date
+% \begin{verbatim}
+% \date_parse:n {19/June/1981}
+% \end{verbatim}
+% one might write a command such as
+% \begin{verbatim}
+% \cs_new:Npn \date_parse:n #1 { \date_parse_aux:w #1 \q_stop }
+% \cs_new:Npn \date_parse_aux:w #1 / #2 / #3 \q_stop
+% { <do something with the date> }
+% \end{verbatim}
+%
+% Quarks are sometimes also used as error return values for functions
+% that receive erroneous input.
+% For example, in the function \cs{prop_get:NnN} to retrieve a value stored
+% in some key of a property list, if the key does not exist then the return value
+% is the quark \cs{q_no_value}.
+% As mentioned above, such quarks are extremely fragile and it is imperative
+% when using such functions that code is carefully written to check for
+% pathological cases to avoid leakage of a quark into an uncontrolled
+% environment.
+%
+% Quarks also permit the
+% following ingenious trick when parsing tokens:
+% when you pick up a token in a temporary variable
+% and you want to know whether you have picked up a particular quark,
+% all you have to do is compare the temporary variable to the quark using
+% \cs{tl_if_eq:NNTF}. A set of special quark testing functions is set up
+% below. All the quark testing functions are expandable although the
+% ones testing only single tokens are much faster.
+%
+% \section{Defining quarks}
+%
+% \begin{function}{\quark_new:N}
+% \begin{syntax}
+% \cs{quark_new:N} \meta{quark}
+% \end{syntax}
+% Creates a new \meta{quark} which expands only to \meta{quark}.
+% The \meta{quark} is defined globally, and an error message
+% is raised if the name was already taken.
+% \end{function}
+%
+% \begin{variable}{\q_stop}
+% Used as a marker for delimited arguments, such as
+% \begin{verbatim}
+% \cs_set:Npn \tmp:w #1#2 \q_stop {#1}
+% \end{verbatim}
+% \end{variable}
+%
+% \begin{variable}{\q_mark}
+% Used as a marker for delimited arguments when \cs{q_stop} is
+% already in use.
+% \end{variable}
+%
+% \begin{variable}{\q_nil}
+% Quark to mark a null value in structured variables or functions. Used
+% as an end delimiter when this may itself need to be tested
+% (in contrast to \cs{q_stop}, which is only ever used as a delimiter).
+% \end{variable}
+%
+% \begin{variable}{\q_no_value}
+% A canonical value for a missing value, when one is requested from
+% a data structure. This is therefore used as a \enquote{return} value
+% by functions such as \cs{prop_get:NnN} if there is no data to
+% return.
+% \end{variable}
+%
+% \section{Quark tests}
+%
+% The method used to define quarks means that the single token (\texttt{N})
+% tests are faster than the multi-token (\texttt{n}) tests. The latter
+% should therefore only be used when the argument can definitely take
+% more than a single token.
+%
+% \begin{function}[EXP,pTF]{\quark_if_nil:N}
+% \begin{syntax}
+% \cs{quark_if_nil_p:N} \meta{token}
+% \cs{quark_if_nil:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is equal to \cs{q_nil}.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\quark_if_nil:n, \quark_if_nil:o, \quark_if_nil:V}
+% \begin{syntax}
+% \cs{quark_if_nil_p:n} \Arg{token list} \\
+% \cs{quark_if_nil:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} contains only \cs{q_nil} (distinct
+% from \meta{token list} being empty or containing \cs{q_nil} plus one
+% or more other tokens).
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\quark_if_no_value:N, \quark_if_no_value:c}
+% \begin{syntax}
+% \cs{quark_if_no_value_p:N} \meta{token} \\
+% \cs{quark_if_no_value:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is equal to \cs{q_no_value}.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\quark_if_no_value:n}
+% \begin{syntax}
+% \cs{quark_if_no_value_p:n} \Arg{token list} \\
+% \cs{quark_if_no_value:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} contains only \cs{q_no_value}
+% (distinct from \meta{token list} being empty or containing
+% \cs{q_no_value} plus one or more other tokens).
+% \end{function}
+%
+% \section{Recursion}
+%
+% This module provides a uniform interface to intercepting and
+% terminating loops as when one is doing tail recursion. The building
+% blocks follow below and an example is shown in
+% Section~\ref{sec:l3quark:quark-example}.
+%
+% \begin{variable}{\q_recursion_tail}
+% This quark is appended to the data structure in question and
+% appears as a real element there. This means it gets any list
+% separators around it.
+% \end{variable}
+%
+% \begin{variable}{\q_recursion_stop}
+% This quark is added \emph{after} the data structure. Its purpose
+% is to make it possible to terminate the recursion at any point
+% easily.
+% \end{variable}
+%
+% \begin{function}[EXP]{\quark_if_recursion_tail_stop:N}
+% \begin{syntax}
+% \cs{quark_if_recursion_tail_stop:N} \meta{token}
+% \end{syntax}
+% Tests if \meta{token} contains only the marker
+% \cs{q_recursion_tail}, and if so uses
+% \cs{use_none_delimit_by_q_recursion_stop:w} to terminate the
+% recursion that this belongs to. The
+% recursion input must include the marker tokens \cs{q_recursion_tail}
+% and \cs{q_recursion_stop} as the last two items.
+% \end{function}
+%
+% \begin{function}[EXP,updated = 2011-09-06]
+% {\quark_if_recursion_tail_stop:n, \quark_if_recursion_tail_stop:o}
+% \begin{syntax}
+% \cs{quark_if_recursion_tail_stop:n} \Arg{token list}
+% \end{syntax}
+% Tests if the \meta{token list} contains only
+% \cs{q_recursion_tail}, and if so uses
+% \cs{use_none_delimit_by_q_recursion_stop:w} to terminate the
+% recursion that this belongs to. The
+% recursion input must include the marker tokens \cs{q_recursion_tail}
+% and \cs{q_recursion_stop} as the last two items.
+% \end{function}
+%
+% \begin{function}[EXP]{\quark_if_recursion_tail_stop_do:Nn}
+% \begin{syntax}
+% \cs{quark_if_recursion_tail_stop_do:Nn} \meta{token} \Arg{insertion}
+% \end{syntax}
+% Tests if \meta{token} contains only the marker
+% \cs{q_recursion_tail}, and if so uses
+% \cs{use_i_delimit_by_q_recursion_stop:w} to terminate the
+% recursion that this belongs to. The
+% recursion input must include the marker tokens \cs{q_recursion_tail}
+% and \cs{q_recursion_stop} as the last two items. The \meta{insertion}
+% code is then added to the input stream after the recursion has
+% ended.
+% \end{function}
+%
+% \begin{function}[EXP,updated = 2011-09-06]
+% {\quark_if_recursion_tail_stop_do:nn, \quark_if_recursion_tail_stop_do:on}
+% \begin{syntax}
+% \cs{quark_if_recursion_tail_stop_do:nn} \Arg{token list} \Arg{insertion}
+% \end{syntax}
+% Tests if the \meta{token list} contains only
+% \cs{q_recursion_tail}, and if so uses
+% \cs{use_i_delimit_by_q_recursion_stop:w} to terminate the
+% recursion that this belongs to. The
+% recursion input must include the marker tokens \cs{q_recursion_tail}
+% and \cs{q_recursion_stop} as the last two items. The \meta{insertion}
+% code is then added to the input stream after the recursion has
+% ended.
+% \end{function}
+%
+%
+% \begin{function}[EXP,added = 2018-04-10]
+% {
+% \quark_if_recursion_tail_break:NN,
+% \quark_if_recursion_tail_break:nN
+% }
+% \begin{syntax}
+% \cs{quark_if_recursion_tail_break:nN} \Arg{token list} \cs[no-index]{\meta{type}_map_break:}
+% \end{syntax}
+% Tests if \meta{token list} contains only \cs{q_recursion_tail}, and
+% if so terminates the recursion using \cs[no-index]{\meta{type}_map_break:}.
+% The recursion end should be marked by \cs{prg_break_point:Nn}
+% \cs[no-index]{\meta{type}_map_break:}.
+% \end{function}
+%
+% \subsection{An example of recursion with quarks}
+% \label{sec:l3quark:quark-example}
+%
+% Quarks are mainly used internally in the \pkg{expl3} code to define
+% recursion functions such as \cs{tl_map_inline:nn} and so on.
+% Here is a small example to demonstrate how to use quarks in this fashion.
+% We shall define a command called |\my_map_dbl:nn| which takes a token list
+% and applies an operation to every \emph{pair} of tokens.
+% For example, |\my_map_dbl:nn {abcd} {[--#1--#2--]~}| would produce
+% \enquote{\ttfamily [--a--b--]~[--c--d--]~}.
+% Using quarks to define such functions simplifies their logic and ensures
+% robustness in many cases.
+%
+%
+% Here's the definition of |\my_map_dbl:nn|.
+% First of all, define the function that does the processing based on the
+% inline function argument |#2|.
+% Then initiate the recursion using an internal function.
+% The token list |#1| is terminated using \cs{q_recursion_tail}, with
+% delimiters according to the type of recursion (here a pair of
+% \cs{q_recursion_tail}), concluding with \cs{q_recursion_stop}.
+% These quarks are used to mark the end of the token list being operated upon.
+%\begin{verbatim}
+% \cs_new:Npn \my_map_dbl:nn #1#2
+% {
+% \cs_set:Npn \__my_map_dbl_fn:nn ##1 ##2 {#2}
+% \__my_map_dbl:nn #1 \q_recursion_tail \q_recursion_tail
+% \q_recursion_stop
+% }
+%\end{verbatim}
+%
+% The definition of the internal recursion function follows.
+% First check if either of the input tokens are the termination quarks.
+% Then, if not, apply the inline function to the two arguments.
+%\begin{verbatim}
+% \cs_new:Nn \__my_map_dbl:nn
+% {
+% \quark_if_recursion_tail_stop:n {#1}
+% \quark_if_recursion_tail_stop:n {#2}
+% \__my_map_dbl_fn:nn {#1} {#2}
+%\end{verbatim}
+% Finally, recurse:
+%\begin{verbatim}
+% \__my_map_dbl:nn
+% }
+%\end{verbatim}
+% Note that contrarily to \LaTeX3 built-in mapping functions, this
+% mapping function cannot be nested, since the second map would overwrite
+% the definition of |\__my_map_dbl_fn:nn|.
+%
+% \section{Scan marks}
+%
+% Scan marks are control sequences set equal to \cs{scan_stop:},
+% hence never expand in an expansion context and are (largely)
+% invisible if they are encountered in a typesetting context.
+%
+% Like quarks, they can be used as delimiters in weird functions
+% and are often safer to use for this purpose.
+% Since they are harmless when executed by \TeX{} in non-expandable
+% contexts, they can be used to mark the end of a set of instructions.
+% This allows to skip to that point if the end of the instructions
+% should not be performed (see \pkg{l3regex}).
+%
+% \begin{function}[added = 2018-04-01]{\scan_new:N}
+% \begin{syntax}
+% \cs{scan_new:N} \meta{scan mark}
+% \end{syntax}
+% Creates a new \meta{scan mark} which is set equal to \cs{scan_stop:}.
+% The \meta{scan mark} is defined globally, and an error message
+% is raised if the name was already taken by another scan mark.
+% \end{function}
+%
+% \begin{variable}[added = 2018-04-01]{\s_stop}
+% Used at the end of a set of instructions, as a marker
+% that can be jumped to using \cs{use_none_delimit_by_s_stop:w}.
+% \end{variable}
+%
+% \begin{function}[EXP,added = 2018-04-01]{\use_none_delimit_by_s_stop:w}
+% \begin{syntax}
+% \cs{use_none_delimit_by_s_stop:w} \meta{tokens} \cs{s_stop}
+% \end{syntax}
+% Removes the \meta{tokens} and \cs{s_stop} from the input stream.
+% This leads to a low-level \TeX{} error if \cs{s_stop} is absent.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3quark} implementation}
+%
+% \TestFiles{m3quark001.lvt}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \subsection{Quarks}
+%
+% \begin{macrocode}
+%<@@=quark>
+% \end{macrocode}
+%
+% \begin{macro}{\quark_new:N}
+% \UnitTested
+% Allocate a new quark.
+% \begin{macrocode}
+\cs_new_protected:Npn \quark_new:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \cs_gset_nopar:Npn #1 {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\q_nil, \q_mark, \q_no_value, \q_stop}
+% Some \enquote{public} quarks. \cs{q_stop} is an \enquote{end of
+% argument} marker, \cs{q_nil} is a empty value and \cs{q_no_value}
+% marks an empty argument.
+% \begin{macrocode}
+\quark_new:N \q_nil
+\quark_new:N \q_mark
+\quark_new:N \q_no_value
+\quark_new:N \q_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\q_recursion_tail, \q_recursion_stop}
+% Quarks for ending recursions. Only ever used there!
+% \cs{q_recursion_tail} is appended to whatever list structure we are
+% doing recursion on, meaning it is added as a proper list item with
+% whatever list separator is in use. \cs{q_recursion_stop} is placed
+% directly after the list.
+% \begin{macrocode}
+\quark_new:N \q_recursion_tail
+\quark_new:N \q_recursion_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\s_@@}
+% Private scan mark used in \pkg{l3quark}. We don't have \pkg{l3scan}
+% yet, so we declare the scan mark here and add it to the scan mark pool
+% later.
+% \begin{macrocode}
+\cs_new_eq:NN \s_@@ \scan_stop:
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\q_@@_nil}
+% Private quark use for some tests.
+% \begin{macrocode}
+\quark_new:N \q_@@_nil
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\quark_if_recursion_tail_stop:N}
+% \UnitTested
+% \begin{macro}[EXP]{\quark_if_recursion_tail_stop_do:Nn}
+% \UnitTested
+% When doing recursions, it is easy to spend a lot of time testing if the
+% end marker has been found. To avoid this, a dedicated end marker is used
+% each time a recursion is set up. Thus if the marker is found everything
+% can be wrapper up and finished off. The simple case is when the test
+% can guarantee that only a single token is being tested. In this case,
+% there is just a dedicated copy of the standard quark test. Both a gobbling
+% version and one inserting end code are provided.
+% \begin{macrocode}
+\cs_new:Npn \quark_if_recursion_tail_stop:N #1
+ {
+ \if_meaning:w \q_recursion_tail #1
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ }
+\cs_new:Npn \quark_if_recursion_tail_stop_do:Nn #1
+ {
+ \if_meaning:w \q_recursion_tail #1
+ \exp_after:wN \use_i_delimit_by_q_recursion_stop:nw
+ \else:
+ \exp_after:wN \use_none:n
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\quark_if_recursion_tail_stop:n, \quark_if_recursion_tail_stop:o}
+% \UnitTested
+% \begin{macro}[EXP]
+% {\quark_if_recursion_tail_stop_do:nn, \quark_if_recursion_tail_stop_do:on}
+% \UnitTested
+% \begin{macro}[EXP]{\@@_if_recursion_tail:w}
+% See \cs{quark_if_nil:nTF} for the details. Expanding
+% \cs{@@_if_recursion_tail:w} once in front of the tokens chosen here
+% gives an empty result if and only if |#1|~is exactly
+% \cs{q_recursion_tail}.
+% \begin{macrocode}
+\cs_new:Npn \quark_if_recursion_tail_stop:n #1
+ {
+ \tl_if_empty:oTF
+ { \@@_if_recursion_tail:w {} #1 {} ?! \q_recursion_tail ??! }
+ { \use_none_delimit_by_q_recursion_stop:w }
+ { }
+ }
+\cs_new:Npn \quark_if_recursion_tail_stop_do:nn #1
+ {
+ \tl_if_empty:oTF
+ { \@@_if_recursion_tail:w {} #1 {} ?! \q_recursion_tail ??! }
+ { \use_i_delimit_by_q_recursion_stop:nw }
+ { \use_none:n }
+ }
+\cs_new:Npn \@@_if_recursion_tail:w
+ #1 \q_recursion_tail #2 ? #3 ?! { #1 #2 }
+\cs_generate_variant:Nn \quark_if_recursion_tail_stop:n { o }
+\cs_generate_variant:Nn \quark_if_recursion_tail_stop_do:nn { o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\quark_if_recursion_tail_break:NN}
+% \begin{macro}[EXP]{\quark_if_recursion_tail_break:nN}
+% Analogues of the \cs[index=quark_if_recursion_tail_stop:n]
+% {quark_if_recursion_tail_stop\ldots{}} functions.
+% Break the mapping using |#2|.
+% \begin{macrocode}
+\cs_new:Npn \quark_if_recursion_tail_break:NN #1#2
+ {
+ \if_meaning:w \q_recursion_tail #1
+ \exp_after:wN #2
+ \fi:
+ }
+\cs_new:Npn \quark_if_recursion_tail_break:nN #1#2
+ {
+ \tl_if_empty:oT
+ { \@@_if_recursion_tail:w {} #1 {} ?! \q_recursion_tail ??! }
+ {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\quark_if_nil:N}
+% \UnitTested
+% \begin{macro}[pTF]{\quark_if_no_value:N, \quark_if_no_value:c}
+% \UnitTested
+% Here we test if we found a special quark as the first argument.
+% We better start with \cs{q_no_value} as the first argument since
+% the whole thing may otherwise loop if |#1| is wrongly given
+% a string like |aabc| instead of a single token.\footnote{It may
+% still loop in special circumstances however!}
+% \begin{macrocode}
+\prg_new_conditional:Npnn \quark_if_nil:N #1 { p, T , F , TF }
+ {
+ \if_meaning:w \q_nil #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_new_conditional:Npnn \quark_if_no_value:N #1 { p, T , F , TF }
+ {
+ \if_meaning:w \q_no_value #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_generate_conditional_variant:Nnn \quark_if_no_value:N
+ { c } { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\quark_if_nil:n, \quark_if_nil:V, \quark_if_nil:o}
+% \UnitTested
+% \begin{macro}[pTF]{\quark_if_no_value:n}
+% \UnitTested
+% \begin{macro}{\@@_if_nil:w, \@@_if_no_value:w}
+% \begin{macro}[EXP]{\@@_if_empty_if:o}
+% Let us explain \cs{quark_if_nil:nTF}. Expanding \cs{@@_if_nil:w}
+% once is safe thanks to the trailing \cs{q_nil} |??!|. The result of
+% expanding once is empty if and only if both delimited arguments |#1|
+% and~|#2| are empty and |#3|~is delimited by the last tokens~|?!|.
+% Thanks to the leading~|{}|, the argument~|#1| is empty if and only
+% if the argument of \cs{quark_if_nil:n} starts with \cs{q_nil}. The
+% argument~|#2| is empty if and only if this \cs{q_nil} is followed
+% immediately by~|?| or by~|{}?|, coming either from the trailing
+% tokens in the definition of \cs{quark_if_nil:n}, or from its
+% argument. In the first case, \cs{@@_if_nil:w} is followed by
+% |{}\q_nil| |{}?| |!\q_nil|~|??!|, hence |#3|~is delimited by the
+% final~|?!|, and the test returns \texttt{true} as wanted. In the
+% second case, the result is not empty since the first~|?!| in the
+% definition of \cs{quark_if_nil:n} stop~|#3|. The auxiliary here
+% is the same as \cs{__tl_if_empty_if:o}, with the same comments
+% applying.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \quark_if_nil:n #1 { p, T , F , TF }
+ {
+ \@@_if_empty_if:o
+ { \@@_if_nil:w {} #1 {} ? ! \q_nil ? ? ! }
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:Npn \@@_if_nil:w #1 \q_nil #2 ? #3 ? ! { #1 #2 }
+\prg_new_conditional:Npnn \quark_if_no_value:n #1 { p, T , F , TF }
+ {
+ \@@_if_empty_if:o
+ { \@@_if_no_value:w {} #1 {} ? ! \q_no_value ? ? ! }
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:Npn \@@_if_no_value:w #1 \q_no_value #2 ? #3 ? ! { #1 #2 }
+\prg_generate_conditional_variant:Nnn \quark_if_nil:n
+ { V , o } { p , TF , T , F }
+\cs_new:Npn \@@_if_empty_if:o #1
+ {
+ \exp_after:wN \if_meaning:w \exp_after:wN \q_nil
+ \__kernel_tl_to_str:w \exp_after:wN {#1} \q_nil
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_quark_new_test:N}
+% The function \cs{__kernel_quark_new_test:N} defines |#1| in a
+% similar way as \cs[no-index]{quark_if_recursion_tail_...} functions
+% (as described below), using
+% \cs[no-index]{q__\meta{namespace}_recursion_tail} as the test quark
+% and \cs[no-index]{q__\meta{namespace}_recursion_stop} as the
+% delimiter quark, where the \meta{namespace} is determined as the
+% first |_|-delimited part in~|#1|.
+%
+% There are six possible function types which this function can define,
+% and which is defined depends on the signature of the function being
+% defined:
+% \begin{description}
+% \def\makelabel#1{\texttt{:#1}~}
+% \item[n] gives an analogue of \cs{quark_if_recursion_tail_stop:n}
+% \item[nn] gives an analogue of \cs{quark_if_recursion_tail_stop_do:nn}
+% \item[nN] gives an analogue of \cs{quark_if_recursion_tail_break:nN}
+% \item[N] gives an analogue of \cs{quark_if_recursion_tail_stop:N}
+% \item[Nn] gives an analogue of \cs{quark_if_recursion_tail_stop_do:Nn}
+% \item[NN] gives an analogue of \cs{quark_if_recursion_tail_break:NN}
+% \end{description}
+% Any other signature causes an error, as does a function without signature.
+%
+% \begin{macro}{\__kernel_quark_new_conditional:Nn}
+% Similar to \cs{__kernel_quark_new_test:N}, but defines quark
+% branching conditionals like \cs{quark_if_nil:nTF} that test for the
+% quark \cs[no-index]{q__\meta{namespace}_\meta{name}}.
+% The \meta{namespace} and \meta{name} are determined from the
+% conditional~|#1|, which must take the rather rigid form
+% \cs[no-index]{__\meta{namespace}_quark_if_\meta{name}:\meta{arg spec}}.
+% There are only two cases for the \meta{arg spec} here:
+% \begin{description}
+% \def\makelabel#1{\texttt{:#1}~}
+% \item[n] gives an analogue of \cs{quark_if_nil:nTF}
+% \item[N] gives an analogue of \cs{quark_if_nil:NTF}
+% \end{description}
+% Any other signature causes an error, as does a function without signature.
+% We use low-level emptiness tests as \pkg{l3tl} is not available yet when these
+% functions are used; thankfully we only care about whether strings
+% are empty so a simple \cs{if_meaning:w} \cs{q_nil} \meta{string}
+% \cs{q_nil} suffices.
+%
+% \begin{macro}{\@@_new_test:NNNn, \@@_new_test:Nccn,
+% \@@_new_test_aux:nnNNnnnn}
+% \begin{macro}{\@@_new_conditional:Nnnn, \@@_new_conditional:Neen}
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_quark_new_test:N #1
+ { \@@_new_test_aux:Ne #1 { \@@_module_name:N #1 } }
+\cs_new_protected:Npn \@@_new_test_aux:Nn #1 #2
+ {
+ \if_meaning:w \q_nil #2 \q_nil
+ \msg_error:nne { quark } { invalid-function }
+ { \token_to_str:N #1 }
+ \else:
+ \@@_new_test:Nccn #1
+ { q__#2_recursion_tail } { q__#2_recursion_stop } { __#2 }
+ \fi:
+ }
+\cs_generate_variant:Nn \@@_new_test_aux:Nn { Ne }
+\cs_new_protected:Npn \@@_new_test:NNNn #1
+ {
+ \exp_last_unbraced:Nf \@@_new_test_aux:nnNNnnnn
+ { \cs_split_function:N #1 }
+ #1 { test }
+ }
+\cs_generate_variant:Nn \@@_new_test:NNNn { Ncc }
+\cs_new_protected:Npn \__kernel_quark_new_conditional:Nn #1
+ {
+ \@@_new_conditional:Neen #1
+ { \@@_quark_conditional_name:N #1 }
+ { \@@_module_name:N #1 }
+ }
+\cs_new_protected:Npn \@@_new_conditional:Nnnn #1#2#3#4
+ {
+ \if_meaning:w \q_nil #2 \q_nil
+ \msg_error:nne { quark } { invalid-function }
+ { \token_to_str:N #1 }
+ \else:
+ \if_meaning:w \q_nil #3 \q_nil
+ \msg_error:nne { quark } { invalid-function }
+ { \token_to_str:N #1 }
+ \else:
+ \exp_last_unbraced:Nf \@@_new_test_aux:nnNNnnnn
+ { \cs_split_function:N #1 }
+ #1 { conditional }
+ {#2} {#3} {#4}
+ \fi:
+ \fi:
+ }
+\cs_generate_variant:Nn \@@_new_conditional:Nnnn { Nee }
+\cs_new_protected:Npn \@@_new_test_aux:nnNNnnnn #1 #2 #3 #4 #5
+ {
+ \cs_if_exist_use:cTF { @@_new_#5_#2:Nnnn } { #4 }
+ {
+ \msg_error:nnee { quark } { invalid-function }
+ { \token_to_str:N #4 } {#2}
+ \use_none:nnn
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{
+% \@@_new_test_n:Nnnn, \@@_new_test_nn:Nnnn,
+% \@@_new_test_N:Nnnn, \@@_new_test_Nn:Nnnn,
+% \@@_new_test_NN:Nnnn, \@@_new_test_NN:Nnnn,
+% }
+% These macros implement the six possibilities mentioned above, passing
+% the right arguments to \cs{@@_new_test_aux_do:nNNnnnnNNn},
+% which defines some auxiliaries, and then to
+% \cs{@@_new_test_define_tl:nNnNNn} (|:n(n)| variants) or to
+% \cs{@@_new_test_define_ifx:nNnNNn} (|:N(n)|) which define the
+% main conditionals.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_new_test_n:Nnnn #1 #2 #3 #4
+ {
+ \@@_new_test_aux_do:nNNnnnnNNn {#4} #2 #3 { none } { } { } { }
+ \@@_new_test_define_tl:nNnNNn #1 { }
+ }
+\cs_new_protected:Npn \@@_new_test_nn:Nnnn #1 #2 #3 #4
+ {
+ \@@_new_test_aux_do:nNNnnnnNNn {#4} #2 #3 { i } { n } {##1} {##2}
+ \@@_new_test_define_tl:nNnNNn #1 { \use_none:n }
+ }
+\cs_new_protected:Npn \@@_new_test_nN:Nnnn #1 #2 #3 #4
+ {
+ \@@_new_test_aux_do:nNNnnnnNNn {#4} #2 #3 { i } { n } {##1} {##2}
+ \@@_new_test_define_break_tl:nNNNNn #1 { }
+ }
+\cs_new_protected:Npn \@@_new_test_N:Nnnn #1 #2 #3 #4
+ {
+ \@@_new_test_aux_do:nNNnnnnNNn {#4} #2 #3 { none } { } { } { }
+ \@@_new_test_define_ifx:nNnNNn #1 { }
+ }
+\cs_new_protected:Npn \@@_new_test_Nn:Nnnn #1 #2 #3 #4
+ {
+ \@@_new_test_aux_do:nNNnnnnNNn {#4} #2 #3 { i } { n } {##1} {##2}
+ \@@_new_test_define_ifx:nNnNNn #1
+ { \else: \exp_after:wN \use_none:n }
+ }
+\cs_new_protected:Npn \@@_new_test_NN:Nnnn #1 #2 #3 #4
+ {
+ \@@_new_test_aux_do:nNNnnnnNNn {#4} #2 #3 { i } { n } {##1} {##2}
+ \@@_new_test_define_break_ifx:nNNNNn #1 { }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \@@_new_test_aux_do:nNNnnnnNNn,
+% \@@_test_define_aux:NNNNnnNNn
+% }
+% \cs{@@_new_test_aux_do:nNNnnnnNNn} makes the control sequence names
+% which will be used by \cs{@@_test_define_aux:NNNNnnNNn}, and then later
+% by \cs{@@_new_test_define_tl:nNnNNn} or
+% \cs{@@_new_test_define_ifx:nNnNNn}. The control sequences defined
+% here are analogous to \cs{@@_if_recursion_tail:w} and to
+% \cs[no-index]{use_(none|i)_delimit_by_q_recursion_stop:(|n)w}.
+%
+% The name is composed by the name-space and the name of the quarks.
+% Suppose \cs{__kernel_quark_new_test:N} was used with:
+% \begin{verbatim}
+% \__kernel_quark_new_test:N \__test_quark_tail:n
+% \end{verbatim}
+% then the first auxiliary will be \cs[no-index]{__test_quark_recursion_tail:w},
+% and the second one will be
+% \cs[no-index]{__test_use_none_delimit_by_q_recursion_stop:w}.
+%
+% Note that the actual quarks are \emph{not} defined here. They should
+% be defined separately using \cs{quark_new:N}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_new_test_aux_do:nNNnnnnNNn #1 #2 #3 #4 #5
+ {
+ \exp_args:Ncc \@@_test_define_aux:NNNNnnNNn
+ { #1 _quark_recursion_tail:w }
+ { #1 _use_ #4 _delimit_by_q_recursion_stop: #5 w }
+ #2 #3
+ }
+\cs_new_protected:Npn \@@_test_define_aux:NNNNnnNNn #1 #2 #3 #4 #5 #6 #7
+ {
+ \cs_gset:Npn #1 ##1 #3 ##2 ? ##3 ?! { ##1 ##2 }
+ \cs_gset:Npn #2 ##1 #6 #4 {#5}
+ #7 {##1} #1 #2 #3
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \@@_new_test_define_tl:nNnNNn,
+% \@@_new_test_define_ifx:nNnNNn
+% }
+% \begin{macro}{
+% \@@_new_test_define_break_tl:nNNNNn,
+% \@@_new_test_define_break_ifx:nNNNNn
+% }
+% Finally, these two macros define the main conditional function using
+% what's been set up before.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_new_test_define_tl:nNnNNn #1 #2 #3 #4 #5 #6
+ {
+ \cs_new:Npn #5 #1
+ {
+ \tl_if_empty:oTF
+ { #2 {} ##1 {} ?! #4 ??! }
+ {#3} {#6}
+ }
+ }
+\cs_new_protected:Npn \@@_new_test_define_ifx:nNnNNn #1 #2 #3 #4 #5 #6
+ {
+ \cs_new:Npn #5 #1
+ {
+ \if_meaning:w #4 ##1
+ \exp_after:wN #3
+ #6
+ \fi:
+ }
+ }
+\cs_new_protected:Npn \@@_new_test_define_break_tl:nNNNNn #1 #2 #3
+ { \@@_new_test_define_tl:nNnNNn {##1##2} #2 {##2} }
+\cs_new_protected:Npn \@@_new_test_define_break_ifx:nNNNNn #1 #2 #3
+ { \@@_new_test_define_ifx:nNnNNn {##1##2} #2 {##2} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{
+% \@@_new_conditional_n:Nnnn,
+% \@@_new_conditional_N:Nnnn,
+% \@@_new_conditional_n_aux:NNNn,
+% \@@_new_conditional_N_aux:NNNn
+% }
+% These macros implement the two possibilities for branching quark
+% conditionals. To avoid constructing without defining the
+% \cs[no-index]{__\meta{type}_if_quark_\meta{name}:w} helper,
+% \texttt{N}-type function accepts a \cs{prg_do_nothing:} as
+% a placeholder.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_new_conditional_n:Nnnn #1 #2 #3
+ {
+ \exp_args:Ncc \@@_new_conditional_n_aux:NNNn
+ { __ #3 _if_quark_ #2 :w } { q__ #3 _ #2 } #1
+ }
+\cs_new_protected:Npn \@@_new_conditional_N:Nnnn #1 #2 #3
+ {
+ \exp_args:NNc \@@_new_conditional_N_aux:NNNn
+ \prg_do_nothing: { q__ #3 _ #2 } #1
+ }
+\cs_new_protected:Npn \@@_new_conditional_n_aux:NNNn #1 #2 #3 #4
+ {
+ \cs_gset:Npn #1 ##1 #2 ##2 ? ##3 ?! { ##1##2 }
+ \prg_new_conditional:Npnn #3 ##1 {#4}
+ {
+ \@@_if_empty_if:o { #1 {} ##1 {} ?! #2 ??! }
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ }
+\cs_new_protected:Npn \@@_new_conditional_N_aux:NNNn #1 #2 #3 #4
+ {
+ \prg_new_conditional:Npnn #3 ##1 {#4}
+ {
+ \if_meaning:w #2 ##1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_module_name:N}
+% \begin{macro}[EXP]{
+% \@@_module_name:w,
+% \@@_module_name_loop:w,
+% \@@_module_name_end:w
+% }
+% \cs{@@_module_name:N} takes a control sequence and returns its
+% \meta{module} name, determined as the first non-empty
+% non-single-character word, separated by |_| or~|:|. These rules
+% give the correct result for public functions
+% \cs[no-index]{\meta{module}_\ldots{}}, private functions
+% \cs[no-index]{__\meta{module}_\ldots{}}, and variables such as
+% \cs[no-index]{l_\meta{module}_\ldots{}}. If no valid module is
+% found the result is an empty string. The approach is to first cut
+% off everything after the (first) |:| if any is present, then
+% repeatedly grab |_|-delimited words until finding one of length at
+% least~$2$ (we use low-level tests as \pkg{l3tl} is not fully
+% available when \cs{__kernel_quark_new_test:N} is first used.
+% If no \meta{module} is found (such as in \cs{::n}) we
+% get the trailing marker \cs{use_none:n} |{}|, which expands to
+% nothing.
+% \begin{macrocode}
+\cs_set:Npn \@@_tmp:w #1#2
+ {
+ \cs_new:Npn \@@_module_name:N ##1
+ {
+ \exp_last_unbraced:Nf \@@_module_name:w
+ { \cs_to_str:N ##1 } #1 \s_@@
+ }
+ \cs_new:Npn \@@_module_name:w ##1 #1 ##2 \s_@@
+ { \@@_module_name_loop:w ##1 #2 \use_none:n { } #2 \s_@@ }
+ \cs_new:Npn \@@_module_name_loop:w ##1 #2
+ {
+ \use_i_ii:nnn \if_meaning:w \prg_do_nothing:
+ ##1 \prg_do_nothing: \prg_do_nothing:
+ \exp_after:wN \@@_module_name_loop:w
+ \else:
+ \@@_module_name_end:w ##1
+ \fi:
+ }
+ \cs_new:Npn \@@_module_name_end:w
+ ##1 \fi: ##2 \s_@@ { \fi: ##1 }
+ }
+\exp_after:wN \@@_tmp:w \tl_to_str:n { : _ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_quark_conditional_name:N, \@@_quark_conditional_name:w}
+% \cs{@@_quark_conditional_name:N} determines the quark name that the quark
+% conditional function~|##1| queries, as the part of the function name
+% between |_quark_if_| and the trailing~|:|. Again we define it
+% through \cs{@@_tmp:w}, which receives |:| as |#1| and |_quark_if_|
+% as |#2|. The auxiliary \cs{@@_quark_conditional_name:w} returns the part
+% between the first |_quark_if_| and the next~|:|, and we apply this
+% auxiliary to the function name followed by |:| (in case the function
+% name is lacking a signature), and |_quark_if_:| so that
+% \cs{@@_quark_conditional_name:N} returns an empty string if |_quark_if_| is
+% not present.
+% \begin{macrocode}
+\cs_set:Npn \@@_tmp:w #1 #2 \s_@@
+ {
+ \cs_new:Npn \@@_quark_conditional_name:N ##1
+ {
+ \exp_last_unbraced:Nf \@@_quark_conditional_name:w
+ { \cs_to_str:N ##1 } #1 #2 #1 \s_@@
+ }
+ \cs_new:Npn \@@_quark_conditional_name:w
+ ##1 #2 ##2 #1 ##3 \s_@@ {##2}
+ }
+\exp_after:wN \@@_tmp:w \tl_to_str:n { : _quark_if_ } \s_@@
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Scan marks}
+%
+% \begin{macrocode}
+%<@@=scan>
+% \end{macrocode}
+%
+% \begin{macro}{\scan_new:N}
+% \UnitTested
+% Check whether the variable is already a scan mark,
+% then declare it to be equal to \cs{scan_stop:} globally.
+% \begin{macrocode}
+\cs_new_protected:Npn \scan_new:N #1
+ {
+ \tl_if_in:NnTF \g_@@_marks_tl { #1 }
+ {
+ \msg_error:nne { scanmark } { already-defined }
+ { \token_to_str:N #1 }
+ }
+ {
+ \tl_gput_right:Nn \g_@@_marks_tl {#1}
+ \cs_new_eq:NN #1 \scan_stop:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\s_stop}
+% \begin{variable}{\g_@@_marks_tl}
+% \UnitTested
+% We only declare one scan mark here, more can be defined
+% by specific modules.
+% Can't use \cs{scan_new:N} yet because \pkg{l3tl} isn't loaded,
+% so define \cs{s_stop} by hand and add it to \cs{g_@@_marks_tl}.
+% We also add the scan marks declared earlier to the pool here.
+% Since they lives in a different namespace, a little \pkg{DocStrip}
+% cheating is necessary.
+% \begin{macrocode}
+\cs_new_eq:NN \s_stop \scan_stop:
+\cs_gset_nopar:Npn \g_@@_marks_tl
+ {
+ \s_stop
+%<@@=quark>
+ \s_@@
+%<@@=cs>
+ \s_@@_mark
+ \s_@@_stop
+%<@@=scan>
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\use_none_delimit_by_s_stop:w}
+% \UnitTested
+% Similar to \cs{use_none_delimit_by_q_stop:w}.
+% \begin{macrocode}
+\cs_new:Npn \use_none_delimit_by_s_stop:w #1 \s_stop { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3regex.dtx b/macros/latex-dev/required/l3kernel/l3regex.dtx
new file mode 100644
index 0000000000..ce85b56262
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3regex.dtx
@@ -0,0 +1,8205 @@
+% \iffalse meta-comment
+%
+%% File: l3regex.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3regex} module\\ Regular expressions in \TeX{}^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+% \newenvironment{l3regex-syntax}
+% {\begin{itemize}\def\\{\char`\\}\def\makelabel##1{\hss\llap{\ttfamily##1}}}
+% {\end{itemize}}
+%
+% The \pkg{l3regex} module provides regular expression testing,
+% extraction of submatches, splitting, and replacement, all acting
+% on token lists. The syntax of regular expressions is mostly a subset
+% of the \textsc{pcre} syntax (and very close to \textsc{posix}),
+% with some additions
+% due to the fact that \TeX{} manipulates tokens rather than characters.
+% For performance reasons, only a limited set of features are implemented.
+% Notably, back-references are not supported.
+%
+% Let us give a few examples. After
+% \begin{verbatim}
+% \tl_set:Nn \l_my_tl { That~cat. }
+% \regex_replace_once:nnN { at } { is } \l_my_tl
+% \end{verbatim}
+% the token list variable \cs[no-index]{l_my_tl} holds the text
+% \enquote{\texttt{This cat.}}, where the first
+% occurrence of \enquote{\texttt{at}} was replaced
+% by \enquote{\texttt{is}}. A more complicated example is
+% a pattern to emphasize each word and add a comma after it:
+% \begin{verbatim}
+% \regex_replace_all:nnN { \w+ } { \c{emph}\cB\{ \0 \cE\} , } \l_my_tl
+% \end{verbatim}
+% The |\w| sequence represents any \enquote{word} character, and |+|
+% indicates that the |\w| sequence should be repeated as many times as
+% possible (at least once), hence matching a word in the input token
+% list. In the replacement text, |\0| denotes the full match (here, a
+% word). The command |\emph| is inserted using |\c{emph}|, and its
+% argument |\0| is put between braces |\cB\{| and |\cE\}|.
+%
+% If a regular expression is to be used several times,
+% it can be compiled once, and stored in a regex
+% variable using \cs{regex_set:Nn}. For example,
+% \begin{verbatim}
+% \regex_new:N \l_foo_regex
+% \regex_set:Nn \l_foo_regex { \c{begin} \cB. (\c[^BE].*) \cE. }
+% \end{verbatim}
+% stores in \cs[no-index]{l_foo_regex} a regular expression which matches the
+% starting marker for an environment: \cs[no-index]{begin}, followed by a
+% begin-group token (|\cB.|), then any number of tokens which are
+% neither begin-group nor end-group character tokens (|\c[^BE].*|),
+% ending with an end-group token (|\cE.|). As explained in the next
+% section, the parentheses \enquote{capture} the result of |\c[^BE].*|,
+% giving us access to the name of the environment when doing
+% replacements.
+%
+% \section{Syntax of regular expressions}
+%
+% \subsection{Regular expression examples}
+%
+% We start with a few examples, and encourage the reader to apply
+% \cs{regex_show:n} to these regular expressions.
+% \begin{itemize}
+% \item |Cat| matches the word \enquote{Cat} capitalized in this way,
+% but also matches the beginning of the word \enquote{Cattle}: use
+% |\bCat\b| to match a complete word only.
+% \item |[abc]| matches one letter among \enquote{a}, \enquote{b},
+% \enquote{c}; the pattern \verb"(a|b|c)" matches the same three
+% possible letters (but see the discussion of submatches below).
+% \item |[A-Za-z]*| matches any number (due to the quantifier
+% \verb"*") of Latin letters (not accented).
+% \item |\c{[A-Za-z]*}| matches a control sequence made of Latin
+% letters.
+% \item |\_[^\_]*\_| matches an underscore, any number of characters
+% other than underscore, and another underscore; it is equivalent to
+% |\_.*?\_| where |.| matches arbitrary characters and the
+% lazy quantifier |*?| means to match as few characters as
+% possible, thus avoiding matching underscores.
+% \item |[\+\-]?\d+| matches an explicit integer with at most one
+% sign.
+% \item \verb*"[\+\-\ ]*\d+\ *" matches an explicit integer with any
+% number of $+$ and $-$ signs, with spaces allowed except within the
+% mantissa, and surrounded by spaces.
+% \item \verb*"[\+\-\ ]*(\d+|\d*\.\d+)\ *" matches an explicit integer or
+% decimal number; using \verb*"[.,]" instead of \verb*"\." would allow
+% the comma as a decimal marker.
+% \item
+% \verb*"[\+\-\ ]*(\d+|\d*\.\d+)\ *((?i)pt|in|[cem]m|ex|[bs]p|[dn]d|[pcn]c)\ *"
+% \allowbreak matches an explicit dimension with any unit that \TeX{} knows, where
+% \verb*"(?i)" means to treat lowercase and uppercase letters
+% identically.
+% \item \verb*"[\+\-\ ]*((?i)nan|inf|(\d+|\d*\.\d+)(\ *e[\+\-\ ]*\d+)?)\ *"
+% matches an explicit floating point number or the special values
+% \verb*"nan" and \verb*"inf" (with signs and spaces allowed).
+% \item \verb*"[\+\-\ ]*(\d+|\cC.)\ *" matches an explicit integer or
+% control sequence (without checking whether it is an integer
+% variable).
+% \item |\G.*?\K| at the beginning of a regular expression matches and
+% discards (due to |\K|) everything between the end of the previous
+% match (|\G|) and what is matched by the rest of the regular
+% expression; this is useful in \cs{regex_replace_all:nnN} when the
+% goal is to extract matches or submatches in a finer way than with
+% \cs{regex_extract_all:nnN}.
+% \end{itemize}
+% While it is impossible for a regular expression to match only integer
+% expressions, \verb*"[\+\-\(]*\d+\)*([\+\-*/][\+\-\(]*\d+\)*)*" matches among
+% other things all valid integer expressions (made only with explicit
+% integers). One should follow it with further testing.
+%
+% \subsection{Characters in regular expressions}
+%
+% Most characters match exactly themselves,
+% with an arbitrary category code. Some characters are
+% special and must be escaped with a backslash (\emph{e.g.}, |\*|
+% matches a star character). Some escape sequences of
+% the form backslash--letter also have a special meaning
+% (for instance |\d| matches any digit). As a rule,
+% \begin{itemize}
+% \item every alphanumeric character (\texttt{A}--\texttt{Z},
+% \texttt{a}--\texttt{z}, \texttt{0}--\texttt{9}) matches
+% exactly itself, and should not be escaped, because
+% |\A|, |\B|, \ldots{} have special meanings;
+% \item non-alphanumeric printable ascii characters can (and should)
+% always be escaped: many of them have special meanings (\emph{e.g.},
+% use |\(|, |\)|, |\?|, |\.|, |\^|);
+% \item spaces should always be escaped (even in character
+% classes);
+% \item any other character may be escaped or not, without any
+% effect: both versions match exactly that character.
+% \end{itemize}
+% Note that these rules play nicely with the fact that many
+% non-alphanumeric characters are difficult to input into \TeX{}
+% under normal category codes. For instance, |\\abc\%|
+% matches the characters |\abc%| (with arbitrary category codes),
+% but does not match the control sequence |\abc| followed by a
+% percent character. Matching control sequences can be done
+% using the |\c|\Arg{regex} syntax (see below).
+%
+% Any special character which appears at a place where its special
+% behaviour cannot apply matches itself instead (for instance, a
+% quantifier appearing at the beginning of a string), after raising a
+% warning.
+%
+% Characters.
+% \begin{l3regex-syntax}
+% \item[\\x\{hh\ldots{}\}] Character with hex code \texttt{hh\ldots{}}
+% \item[\\xhh] Character with hex code \texttt{hh}.
+% \item[\\a] Alarm (hex 07).
+% \item[\\e] Escape (hex 1B).
+% \item[\\f] Form-feed (hex 0C).
+% \item[\\n] New line (hex 0A).
+% \item[\\r] Carriage return (hex 0D).
+% \item[\\t] Horizontal tab (hex 09).
+% \end{l3regex-syntax}
+%
+% \subsection{Characters classes}
+%
+% Character properties.
+% \begin{l3regex-syntax}
+% \item[.] A single period matches any token.
+% \item[\\d] Any decimal digit.
+% \item[\\h] Any horizontal space character,
+% equivalent to |[\ \^^I]|: space and tab.
+% \item[\\s] Any space character,
+% equivalent to |[\ \^^I\^^J\^^L\^^M]|.
+% \item[\\v] Any vertical space character,
+% equivalent to |[\^^J\^^K\^^L\^^M]|. Note that |\^^K| is a vertical space,
+% but not a space, for compatibility with Perl.
+% \item[\\w] Any word character, \emph{i.e.},
+% alphanumerics and underscore, equivalent to the explicit
+% class |[A-Za-z0-9\_]|.
+% \item[\\D] Any token not matched by |\d|.
+% \item[\\H] Any token not matched by |\h|.
+% \item[\\N] Any token other than the |\n| character (hex 0A).
+% \item[\\S] Any token not matched by |\s|.
+% \item[\\V] Any token not matched by |\v|.
+% \item[\\W] Any token not matched by |\w|.
+% \end{l3regex-syntax}
+% Of those, |.|, |\D|, |\H|, |\N|, |\S|, |\V|, and |\W| match arbitrary
+% control sequences.
+%
+% Character classes match exactly one token in the subject.
+% \begin{l3regex-syntax}
+% \item[{[\ldots{}]}] Positive character class.
+% Matches any of the specified tokens.
+% \item[{[\char`\^\ldots{}]}] Negative character class.
+% Matches any token other than the specified characters.
+% \item[{[x-y]}] Within a character class, this denotes a range (can be
+% used with escaped characters).
+% \item[{[:\meta{name}:]}] Within a character class (one more set of
+% brackets), this denotes the \textsc{posix} character class
+% \meta{name}, which can be \texttt{alnum}, \texttt{alpha},
+% \texttt{ascii}, \texttt{blank}, \texttt{cntrl}, \texttt{digit},
+% \texttt{graph}, \texttt{lower}, \texttt{print}, \texttt{punct},
+% \texttt{space}, \texttt{upper}, \texttt{word}, or \texttt{xdigit}.
+% \item[{[:\char`\^\meta{name}:]}] Negative \textsc{posix} character class.
+% \end{l3regex-syntax}
+% For instance, |[a-oq-z\cC.]| matches any lowercase latin letter
+% except |p|, as well as control sequences (see below for a description
+% of |\c|).
+%
+% In character classes, only |[|, |^|, |-|, |]|, |\| and spaces are
+% special, and should be escaped. Other non-alphanumeric characters can
+% still be escaped without harm. Any escape sequence which matches a
+% single character (|\d|, |\D|, \emph{etc.}) is supported in character
+% classes. If the first character is |^|, then
+% the meaning of the character class is inverted; |^| appearing anywhere
+% else in the range is not special. If the first character (possibly
+% following a leading |^|) is |]| then it does not need to be escaped
+% since ending the range there would make it empty.
+% Ranges of characters
+% can be expressed using |-|, for instance, |[\D 0-5]| and |[^6-9]| are
+% equivalent.
+%
+% \subsection{Structure: alternatives, groups, repetitions}
+%
+% Quantifiers (repetition).
+% \begin{l3regex-syntax}
+% \item[?] $0$ or $1$, greedy.
+% \item[??] $0$ or $1$, lazy.
+% \item[*] $0$ or more, greedy.
+% \item[*?] $0$ or more, lazy.
+% \item[+] $1$ or more, greedy.
+% \item[+?] $1$ or more, lazy.
+% \item[\{$n$\}] Exactly $n$.
+% \item[\{$n,$\}] $n$ or more, greedy.
+% \item[\{$n,$\}?] $n$ or more, lazy.
+% \item[\{$n,m$\}] At least $n$, no more than $m$, greedy.
+% \item[\{$n,m$\}?] At least $n$, no more than $m$, lazy.
+% \end{l3regex-syntax}
+% For greedy quantifiers the regex code will first investigate matches
+% that involve as many repetitions as possible, while for lazy
+% quantifiers it investigates matches with as few repetitions as
+% possible first.
+%
+% Alternation and capturing groups.
+% \begin{l3regex-syntax}
+% \item[A\char`|B\char`|C] Either one of \texttt{A}, \texttt{B},
+% or \texttt{C}, investigating \texttt{A} first.
+% \item[(\ldots{})] Capturing group.
+% \item[(?:\ldots{})] Non-capturing group.
+% \item[(?\char`|\ldots{})] Non-capturing group which resets
+% the group number for capturing groups in each alternative.
+% The following group is numbered with the first unused
+% group number.
+% \end{l3regex-syntax}
+%
+% Capturing groups are a means of extracting information about the
+% match. Parenthesized groups are labelled in the order of their
+% opening parenthesis, starting at $1$. The contents of those groups
+% corresponding to the \enquote{best} match (leftmost longest)
+% can be extracted and stored in a sequence of token lists using for
+% instance \cs{regex_extract_once:nnNTF}.
+%
+% The |\K| escape sequence resets the beginning of the match to the
+% current position in the token list. This only affects what is reported
+% as the full match. For instance,
+% \begin{verbatim}
+% \regex_extract_all:nnN { a \K . } { a123aaxyz } \l_foo_seq
+% \end{verbatim}
+% results in \cs[no-index]{l_foo_seq} containing the items |{1}| and |{a}|: the
+% true matches are |{a1}| and |{aa}|, but they are trimmed by the use of
+% |\K|. The |\K| command does not affect capturing groups: for instance,
+% \begin{verbatim}
+% \regex_extract_once:nnN { (. \K c)+ \d } { acbc3 } \l_foo_seq
+% \end{verbatim}
+% results in \cs[no-index]{l_foo_seq} containing the items |{c3}| and |{bc}|: the
+% true match is |{acbc3}|, with first submatch |{bc}|, but |\K| resets
+% the beginning of the match to the last position where it appears.
+%
+% \subsection{Matching exact tokens}
+%
+% The |\c| escape sequence allows to test the category code of tokens,
+% and match control sequences. Each character category is represented
+% by a single uppercase letter:
+% \begin{itemize}
+% \item |C| for control sequences;
+% \item |B| for begin-group tokens;
+% \item |E| for end-group tokens;
+% \item |M| for math shift;
+% \item |T| for alignment tab tokens;
+% \item |P| for macro parameter tokens;
+% \item |U| for superscript tokens (up);
+% \item |D| for subscript tokens (down);
+% \item |S| for spaces;
+% \item |L| for letters;
+% \item |O| for others; and
+% \item |A| for active characters.
+% \end{itemize}
+% The |\c| escape sequence is used as follows.
+% \begin{l3regex-syntax}
+% \item[\\c\Arg{regex}] A control sequence whose csname matches the
+% \meta{regex}, anchored at the beginning and end, so that |\c{begin}|
+% matches exactly \cs[no-index]{begin}, and nothing else.
+% \item[\\cX] Applies to the next object, which can be a character,
+% escape character sequence such as |\x{0A}|, character class, or
+% group, and forces this object to only match tokens with category
+% |X| (any of |CBEMTPUDSLOA|. For instance, |\cL[A-Z\d]| matches
+% uppercase letters and digits of category code letter, |\cC.|
+% matches any control sequence, and |\cO(abc)| matches |abc| where
+% each character has category other.\footnote{This last example also
+% captures \enquote{\texttt{abc}} as a regex group; to avoid this
+% use a non-capturing group \texttt{\textbackslash cO(?:abc)}.}
+% \item[{\\c[XYZ]}] Applies to the next object, and forces it to only
+% match tokens with category |X|, |Y|, or |Z| (each being any of
+% |CBEMTPUDSLOA|). For instance, |\c[LSO](..)| matches two tokens of
+% category letter, space, or other.
+% \item[{\\c[\char`\^XYZ]}] Applies to the next object and prevents it
+% from matching any token with category |X|, |Y|, or |Z| (each being
+% any of |CBEMTPUDSLOA|). For instance, |\c[^O]\d| matches digits
+% which have any category different from other.
+% \end{l3regex-syntax}
+% The category code tests can be used inside classes; for instance,
+% |[\cO\d \c[LO][A-F]]| matches what \TeX{} considers as hexadecimal
+% digits, namely digits with category other, or uppercase letters from
+% |A| to |F| with category either letter or other. Within a group
+% affected by a category code test, the outer test can be overridden by
+% a nested test: for instance, |\cL(ab\cO\*cd)| matches |ab*cd| where
+% all characters are of category letter, except |*| which has category
+% other.
+%
+% The |\u| escape sequence allows to insert the contents of a token list
+% directly into a regular expression or a replacement, avoiding the need
+% to escape special characters. Namely, |\u|\Arg{var~name} matches
+% the exact contents (both character codes and category codes) of the
+% variable \cs[no-index]{\meta{var~name}},
+% which are obtained by applying \cs{exp_not:v} \Arg{var~name} at the
+% time the regular expression is compiled. Within a |\c{...}|
+% control sequence matching, the |\u| escape sequence only expands its
+% argument once, in effect performing \cs{tl_to_str:v}.
+% Quantifiers are supported.
+%
+% The |\ur| escape sequence allows to insert the contents of a |regex|
+% variable into a larger regular expression. For instance,
+% |A\ur{l_tmpa_regex}D| matches the tokens |A| and |D| separated by
+% something that matches the regular expression
+% \cs[no-index]{l_tmpa_regex}. This behaves as if a non-capturing group
+% were surrounding \cs[no-index]{l_tmpa_regex}, and any group contained
+% in \cs[no-index]{l_tmpa_regex} is converted to a non-capturing group.
+% Quantifiers are supported.
+%
+% For instance, if \cs[no-index]{l_tmpa_regex} has value \verb"B|C",
+% then |A\ur{l_tmpa_regex}D| is equivalent to \verb"A(?:B|C)D" (matching
+% |ABD| or |ACD|) and not to \verb"AB|CD" (matching |AB| or |CD|). To
+% get the latter effect, it is simplest to use \TeX{}'s expansion
+% machinery directly: if \cs[no-index]{l_mymodule_BC_tl} contains
+% \verb"B|C" then the following two lines show the same result:
+% \begin{quote}
+% \cs{regex_show:n} |{ A \u{l_mymodule_BC_tl} D }| \\
+% \cs{regex_show:n} \verb"{ A B | C D }"
+% \end{quote}
+%
+% \subsection{Miscellaneous}
+%
+% Anchors and simple assertions.
+% \begin{l3regex-syntax}
+% \item[\\b] Word boundary: either the previous token is matched by
+% |\w| and the next by |\W|, or the opposite. For this purpose,
+% the ends of the token list are considered as |\W|.
+% \item[\\B] Not a word boundary: between two |\w| tokens
+% or two |\W| tokens (including the boundary).
+% \item[\char`^ \textrm{or} \\A]
+% Start of the subject token list.
+% \item[\char`$\textrm{,} \\Z \textrm{or} \\z] ^^A $
+% End of the subject token list.
+% \item[\\G] Start of the current match. This is only different from |^|
+% in the case of multiple matches: for instance
+% |\regex_count:nnN { \G a } { aaba } \l_tmpa_int| yields $2$, but
+% replacing |\G| by |^| would result in \cs{l_tmpa_int} holding the
+% value $1$.
+% \end{l3regex-syntax}
+%
+% The option |(?i)| makes the match case insensitive (treating
+% \texttt{A}--\texttt{Z} and \texttt{a}--\texttt{z} as equivalent, with
+% no support yet for Unicode case changing). This
+% applies until the end of the group in which it appears, and
+% can be reverted using |(?-i)|. For instance, in
+% \verb"(?i)(a(?-i)b|c)d", the letters |a| and |d| are affected by the
+% |i| option. Characters within ranges and classes are affected
+% individually: |(?i)[\?-B]| is equivalent to |[\?@ABab]|
+% (and differs from the much larger class |[\?-b]|), and
+% |(?i)[^aeiou]| matches any character which is not a vowel.
+% The |i|~option has no effect on |\c{...}|, on |\u{...}|, on character
+% properties, or on character classes, for instance it has no effect at
+% all in |(?i)\u{l_foo_tl}\d\d[[:lower:]]|.
+%
+% \section{Syntax of the replacement text}
+%
+% Most of the features described in regular expressions do not make
+% sense within the replacement text. Backslash introduces various
+% special constructions, described further below:
+% \begin{itemize}
+% \item |\0| is the whole match;
+% \item |\1| is the submatch that was matched by the first (capturing)
+% group |(...)|; similarly for |\2|, \ldots{}, |\9| and
+% |\g{|\meta{number}|}|;
+% \item \verb*|\ | inserts a space (spaces are ignored when not
+% escaped);
+% \item |\a|, |\e|, |\f|, |\n|, |\r|, |\t|, |\xhh|, |\x{hhh}|
+% correspond to single characters as in regular expressions;
+% \item |\c|\Arg{cs~name} inserts a control sequence;
+% \item |\c|\meta{category}\meta{character} (see below);
+% \item |\u|\Arg{tl~var~name} inserts the contents of the
+% \meta{tl~var} (see below).
+% \end{itemize}
+% Characters other than backslash and space are simply inserted in the
+% result (but since the replacement text is first converted to a string,
+% one should also escape characters that are special for \TeX{}, for
+% instance use~|\#|). Non-alphanumeric characters can always be safely
+% escaped with a backslash.
+%
+% For instance,
+% \begin{verbatim}
+% \tl_set:Nn \l_my_tl { Hello,~world! }
+% \regex_replace_all:nnN { ([er]?l|o) . } { (\0--\1) } \l_my_tl
+% \end{verbatim}
+% results in \cs[no-index]{l_my_tl} holding |H(ell--el)(o,--o) w(or--o)(ld--l)!|
+%
+% The submatches are numbered according to the order in which the
+% opening parenthesis of capturing groups appear in the regular
+% expression to match. The $n$-th submatch is empty if there are fewer
+% than $n$ capturing groups or for capturing groups that appear in
+% alternatives that were not used for the match. In case a capturing
+% group matches several times during a match (due to quantifiers) only
+% the last match is used in the replacement text. Submatches always keep
+% the same category codes as in the original token list.
+%
+% By default, the category code of characters inserted by the
+% replacement are determined by the prevailing category code regime at
+% the time where the replacement is made, with two exceptions:
+% \begin{itemize}
+% \item space characters (with character code $32$) inserted with
+% \verb*|\ | or |\x20| or |\x{20}| have category code~$10$ regardless
+% of the prevailing category code regime;
+% \item if the category code would be $0$~(escape), $5$~(newline),
+% $9$~(ignore), $14$~(comment) or $15$~(invalid), it is replaced by
+% $12$~(other) instead.
+% \end{itemize}
+% The escape sequence |\c| allows to insert characters
+% with arbitrary category codes, as well as control sequences.
+% \begin{l3regex-syntax}
+% \item[\\cX(\ldots{})] Produces the characters \enquote{\ldots{}} with
+% category~|X|, which must be one of |CBEMTPUDSLOA| as in regular
+% expressions. Parentheses are optional for a single character (which
+% can be an escape sequence). When nested, the innermost category
+% code applies, for instance |\cL(Hello\cS\ world)!| gives this text
+% with standard category codes.
+% \item[\\c\Arg{text}] Produces the control sequence with csname
+% \meta{text}. The \meta{text} may contain references to the
+% submatches |\0|, |\1|, and so on, as in the example for |\u| below.
+% \end{l3regex-syntax}
+%
+% The escape sequence |\u|\Arg{var~name} allows to insert the
+% contents of the variable with name \meta{var~name} directly into
+% the replacement, giving an easier control of category codes. When
+% nested in |\c{|\ldots{}|}| and |\u{|\ldots{}|}| constructions, the
+% |\u| and |\c|~escape sequences perform \cs{tl_to_str:v}, namely
+% extract the value of the control sequence and turn it into a string.
+% Matches can also be used within the arguments of |\c| and |\u|. For
+% instance,
+% \begin{verbatim}
+% \tl_set:Nn \l_my_one_tl { first }
+% \tl_set:Nn \l_my_two_tl { \emph{second} }
+% \tl_set:Nn \l_my_tl { one , two , one , one }
+% \regex_replace_all:nnN { [^,]+ } { \u{l_my_\0_tl} } \l_my_tl
+% \end{verbatim}
+% results in \cs[no-index]{l_my_tl} holding |first,\emph{second},first,first|.
+%
+% Regex replacement is also a convenient way to produce token lists
+% with arbitrary category codes. For instance
+% \begin{verbatim}
+% \tl_clear:N \l_tmpa_tl
+% \regex_replace_all:nnN { } { \cU\% \cA\~ } \l_tmpa_tl
+% \end{verbatim}
+% results in \cs[no-index]{l_tmpa_tl} containing the percent character
+% with category code~$7$ (superscript) and an active tilde character.
+%
+% \section{Pre-compiling regular expressions}
+%
+% If a regular expression is to be used several times,
+% it is better to compile it once rather than doing it
+% each time the regular expression is used. The compiled
+% regular expression is stored in a variable. All
+% of the \pkg{l3regex} module's functions can be given their
+% regular expression argument either as an explicit string
+% or as a compiled regular expression.
+%
+% \begin{function}[added = 2017-05-26]{\regex_new:N}
+% \begin{syntax}
+% \cs{regex_new:N} \meta{regex~var}
+% \end{syntax}
+% Creates a new \meta{regex~var} or raises an error if the
+% name is already taken. The declaration is global. The
+% \meta{regex~var} is initially such that it never matches.
+% \end{function}
+%
+% \begin{function}[added = 2017-05-26]{\regex_set:Nn, \regex_gset:Nn}
+% \begin{syntax}
+% \cs{regex_set:Nn} \meta{regex~var} \Arg{regex}
+% \end{syntax}
+% Stores a compiled version of the \meta{regular expression} in the
+% \meta{regex~var}. The assignment is local for \cs{regex_set:Nn} and
+% global for \cs{regex_gset:Nn}. For instance, this function can be
+% used as
+% \begin{verbatim}
+% \regex_new:N \l_my_regex
+% \regex_set:Nn \l_my_regex { my\ (simple\ )? reg(ex|ular\ expression) }
+% \end{verbatim}
+% \end{function}
+%
+% \begin{function}[added = 2017-05-26]{\regex_const:Nn}
+% \begin{syntax}
+% \cs{regex_const:Nn} \meta{regex~var} \Arg{regex}
+% \end{syntax}
+% Creates a new constant \meta{regex~var} or raises an error if the name
+% is already taken. The value of the \meta{regex~var} is set
+% globally to the compiled version of the \meta{regular expression}.
+% \end{function}
+%
+% \begin{function}[added = 2021-04-26, updated = 2021-04-29]
+% {\regex_show:N, \regex_show:n, \regex_log:N, \regex_log:n}
+% \begin{syntax}
+% \cs{regex_show:n} \Arg{regex}
+% \cs{regex_log:n} \Arg{regex}
+% \end{syntax}
+% Displays in the terminal or writes in the log file (respectively)
+% how \pkg{l3regex} interprets the \meta{regex}. For instance,
+% \cs{regex_show:n} \verb+{\A X|Y}+ shows
+% \begin{verbatim}
+% +-branch
+% anchor at start (\A)
+% char code 88 (X)
+% +-branch
+% char code 89 (Y)
+% \end{verbatim}
+% indicating that the anchor |\A| only applies to the first branch:
+% the second branch is not anchored to the beginning of the match.
+% \end{function}
+%
+% \section{Matching}
+%
+% All regular expression functions are available in both |:n| and |:N|
+% variants. The former require a \enquote{standard} regular expression,
+% while the later require a compiled expression as generated by
+% \cs{regex_set:Nn}.
+%
+% \begin{function}[TF, added = 2017-05-26]
+% {
+% \regex_match:nn, \regex_match:nV,
+% \regex_match:Nn, \regex_match:NV
+% }
+% \begin{syntax}
+% \cs{regex_match:nnTF} \Arg{regex} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{regular expression} matches any part
+% of the \meta{token list}. For instance,
+% \begin{verbatim}
+% \regex_match:nnTF { b [cde]* } { abecdcx } { TRUE } { FALSE }
+% \regex_match:nnTF { [b-dq-w] } { example } { TRUE } { FALSE }
+% \end{verbatim}
+% leaves \texttt{TRUE} then \texttt{FALSE} in the input stream.
+% \end{function}
+%
+% \begin{function}[added = 2017-05-26]
+% {
+% \regex_count:nnN, \regex_count:nVN,
+% \regex_count:NnN, \regex_count:NVN
+% }
+% \begin{syntax}
+% \cs{regex_count:nnN} \Arg{regex} \Arg{token list} \meta{int var}
+% \end{syntax}
+% Sets \meta{int var} within the current \TeX{} group level
+% equal to the number of times
+% \meta{regular expression} appears in \meta{token list}.
+% The search starts by finding the left-most longest match,
+% respecting greedy and lazy (non-greedy) operators. Then the search
+% starts again from the character following the last character
+% of the previous match, until reaching the end of the token list.
+% Infinite loops are prevented in the case where the regular expression
+% can match an empty token list: then we count one match between each
+% pair of characters.
+% For instance,
+% \begin{verbatim}
+% \int_new:N \l_foo_int
+% \regex_count:nnN { (b+|c) } { abbababcbb } \l_foo_int
+% \end{verbatim}
+% results in \cs[no-index]{l_foo_int} taking the value $5$.
+% \end{function}
+%
+% \begin{function}[noTF, added = 2022-01-10]{\regex_match_case:nn}
+% \begin{syntax}
+% \cs{regex_match_case:nnTF}
+% ~~|{| \\
+% ~~~~\Arg{regex_1} \Arg{code case_1} \\
+% ~~~~\Arg{regex_2} \Arg{code case_2} \\
+% ~~~~\ldots \\
+% ~~~~\Arg{regex_n} \Arg{code case_n} \\
+% ~~|}| \Arg{token list}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Determines which of the \meta{regular expressions} matches at the
+% earliest point in the \meta{token list}, and leaves the
+% corresponding \meta{code_i} followed by the \meta{true code} in the
+% input stream. If several \meta{regex} match starting at the same
+% point, then the first one in the list is selected and the others are
+% discarded. If none of the \meta{regex} match, the \meta{false code}
+% is left in the input stream. Each \meta{regex} can either be given
+% as a regex variable or as an explicit regular expression.
+%
+% In detail, for each starting position in the \meta{token list}, each
+% of the \meta{regex} is searched in turn. If one of them matches
+% then the corresponding \meta{code} is used and everything else is
+% discarded, while if none of the \meta{regex} match at a given
+% position then the next starting position is attempted. If none of
+% the \meta{regex} match anywhere in the \meta{token list} then
+% nothing is left in the input stream. Note that this differs from
+% nested \cs{regex_match:nnTF} statements since all \meta{regex} are
+% attempted at each position rather than attempting to match
+% \meta{regex_1} at every position before moving on to \meta{regex_2}.
+% \end{function}
+%
+% \section{Submatch extraction}
+%
+% \begin{function}[noTF, added = 2017-05-26]
+% {
+% \regex_extract_once:nnN, \regex_extract_once:nVN,
+% \regex_extract_once:NnN, \regex_extract_once:NVN
+% }
+% \begin{syntax}
+% \cs{regex_extract_once:nnN} \Arg{regex} \Arg{token list} \meta{seq~var}
+% \cs{regex_extract_once:nnNTF} \Arg{regex} \Arg{token list} \meta{seq~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Finds the first match of the \meta{regular expression} in the
+% \meta{token list}. If it exists, the match is stored as the first
+% item of the \meta{seq~var}, and further items are the contents of
+% capturing groups, in the order of their opening parenthesis. The
+% \meta{seq~var} is assigned locally. If there is no match, the
+% \meta{seq~var} is cleared. The testing versions insert the
+% \meta{true code} into the input stream if a match was found, and the
+% \meta{false code} otherwise.
+%
+% For instance, assume that you type
+% \begin{verbatim}
+% \regex_extract_once:nnNTF { \A(La)?TeX(!*)\Z } { LaTeX!!! } \l_foo_seq
+% { true } { false }
+% \end{verbatim}
+% Then the regular expression (anchored at the start with |\A| and
+% at the end with |\Z|) must match the whole token list. The first
+% capturing group, |(La)?|, matches |La|, and the second capturing
+% group, |(!*)|, matches |!!!|. Thus, \cs[no-index]{l_foo_seq} contains as a result
+% the items |{LaTeX!!!}|, |{La}|, and |{!!!}|, and the \texttt{true}
+% branch is left in the input stream.
+% Note that the $n$-th item of \cs[no-index]{l_foo_seq}, as obtained using
+% \cs{seq_item:Nn}, correspond to the submatch numbered $(n-1)$ in
+% functions such as \cs{regex_replace_once:nnN}.
+% \end{function}
+%
+% \begin{function}[noTF, added = 2017-05-26]
+% {
+% \regex_extract_all:nnN, \regex_extract_all:nVN,
+% \regex_extract_all:NnN, \regex_extract_all:NVN
+% }
+% \begin{syntax}
+% \cs{regex_extract_all:nnN} \Arg{regex} \Arg{token list} \meta{seq~var}
+% \cs{regex_extract_all:nnNTF} \Arg{regex} \Arg{token list} \meta{seq~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Finds all matches of the \meta{regular expression}
+% in the \meta{token list}, and stores all the submatch information
+% in a single sequence (concatenating the results of
+% multiple \cs{regex_extract_once:nnN} calls).
+% The \meta{seq~var} is assigned locally. If there is no match,
+% the \meta{seq~var} is cleared.
+% The testing versions insert the \meta{true code} into the input
+% stream if a match was found, and the \meta{false code} otherwise.
+% For instance, assume that you type
+% \begin{verbatim}
+% \regex_extract_all:nnNTF { \w+ } { Hello,~world! } \l_foo_seq
+% { true } { false }
+% \end{verbatim}
+% Then the regular expression matches twice, the resulting
+% sequence contains the two items |{Hello}| and |{world}|,
+% and the \texttt{true} branch is left in the input stream.
+% \end{function}
+%
+% \begin{function}[noTF, added = 2017-05-26]
+% {
+% \regex_split:nnN, \regex_split:nVN,
+% \regex_split:NnN, \regex_split:NVN,
+% }
+% \begin{syntax}
+% \cs{regex_split:nnN} \Arg{regular expression} \Arg{token list} \meta{seq~var}
+% \cs{regex_split:nnNTF} \Arg{regular expression} \Arg{token list} \meta{seq~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Splits the \meta{token list} into a sequence of parts, delimited by
+% matches of the \meta{regular expression}. If the \meta{regular expression}
+% has capturing groups, then the token lists that they match are stored as
+% items of the sequence as well. The assignment to \meta{seq~var} is local.
+% If no match is found the resulting \meta{seq~var} has the
+% \meta{token list} as its sole item. If the \meta{regular expression}
+% matches the empty token list, then the \meta{token list} is split
+% into single tokens.
+% The testing versions insert the \meta{true code} into the input
+% stream if a match was found, and the \meta{false code} otherwise.
+% For example, after
+% \begin{verbatim}
+% \seq_new:N \l_path_seq
+% \regex_split:nnNTF { / } { the/path/for/this/file.tex } \l_path_seq
+% { true } { false }
+% \end{verbatim}
+% the sequence |\l_path_seq| contains the items |{the}|, |{path}|,
+% |{for}|, |{this}|, and |{file.tex}|, and the \texttt{true} branch
+% is left in the input stream.
+% \end{function}
+%
+% \section{Replacement}
+%
+% \begin{function}[noTF, added = 2017-05-26]
+% {
+% \regex_replace_once:nnN,\regex_replace_once:nVN,
+% \regex_replace_once:NnN,\regex_replace_once:NVN
+% }
+% \begin{syntax}
+% \cs{regex_replace_once:nnN} \Arg{regular expression} \Arg{replacement} \meta{tl~var}
+% \cs{regex_replace_once:nnNTF} \Arg{regular expression} \Arg{replacement} \meta{tl~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Searches for the \meta{regular expression} in the contents of the
+% \meta{tl~var} and replaces the first match with the
+% \meta{replacement}. In the \meta{replacement},
+% |\0| represents the full match, |\1| represent the contents of the
+% first capturing group, |\2| of the second, \emph{etc.}
+% The result is assigned locally to \meta{tl~var}.
+% \end{function}
+%
+% \begin{function}[noTF, added = 2017-05-26]
+% {
+% \regex_replace_all:nnN,\regex_replace_all:nVN,
+% \regex_replace_all:NnN,\regex_replace_all:NVN
+% }
+% \begin{syntax}
+% \cs{regex_replace_all:nnN} \Arg{regular expression} \Arg{replacement} \meta{tl~var}
+% \cs{regex_replace_all:nnNTF} \Arg{regular expression} \Arg{replacement} \meta{tl~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Replaces all occurrences of the \meta{regular expression} in the
+% contents of the \meta{tl~var}
+% by the \meta{replacement}, where |\0| represents
+% the full match, |\1| represent the contents of the first capturing
+% group, |\2| of the second, \emph{etc.} Every match is treated
+% independently, and matches cannot overlap. The result is assigned
+% locally to \meta{tl~var}.
+% \end{function}
+%
+% \begin{function}[noTF, added = 2022-01-10]{\regex_replace_case_once:nN}
+% \begin{syntax}
+% \cs{regex_replace_case_once:nNTF}
+% ~~|{| \\
+% ~~~~\Arg{regex_1} \Arg{replacement_1} \\
+% ~~~~\Arg{regex_2} \Arg{replacement_2} \\
+% ~~~~\ldots \\
+% ~~~~\Arg{regex_n} \Arg{replacement_n} \\
+% ~~|}| \meta{tl~var}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Replaces the earliest match of the regular expression
+% "(?|"\meta{regex_1}"|"\dots"|"\meta{regex_n}")" in the \meta{token
+% list variable} by the \meta{replacement} corresponding to which
+% \meta{regex_i} matched, then leaves the \meta{true code} in the
+% input stream. If none of the \meta{regex} match, then the
+% \meta{tl~var} is not modified, and the \meta{false code} is left in
+% the input stream. Each \meta{regex} can either be given as a regex
+% variable or as an explicit regular expression.
+%
+% In detail, for each starting position in the \meta{token list}, each
+% of the \meta{regex} is searched in turn. If one of them matches
+% then it is replaced by the corresponding \meta{replacement} as
+% described for \cs{regex_replace_once:nnN}. This is equivalent to
+% checking with \cs{regex_match_case:nn} which \meta{regex} matches,
+% then performing the replacement with \cs{regex_replace_once:nnN}.
+% \end{function}
+%
+% \begin{function}[noTF, added = 2022-01-10]{\regex_replace_case_all:nN}
+% \begin{syntax}
+% \cs{regex_replace_case_all:nNTF}
+% ~~|{| \\
+% ~~~~\Arg{regex_1} \Arg{replacement_1} \\
+% ~~~~\Arg{regex_2} \Arg{replacement_2} \\
+% ~~~~\ldots \\
+% ~~~~\Arg{regex_n} \Arg{replacement_n} \\
+% ~~|}| \meta{tl~var}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Replaces all occurrences of all \meta{regex} in the \meta{token
+% list} by the corresponding \meta{replacement}. Every match is
+% treated independently, and matches cannot overlap. The result is
+% assigned locally to \meta{tl~var}, and the \meta{true code} or
+% \meta{false code} is left in the input stream depending on whether
+% any replacement was made or not.
+%
+% In detail, for each starting position in the \meta{token list}, each
+% of the \meta{regex} is searched in turn. If one of them matches
+% then it is replaced by the corresponding \meta{replacement}, and the
+% search resumes at the position that follows this match (and
+% replacement). For instance
+% \begin{verbatim}
+% \tl_set:Nn \l_tmpa_tl { Hello,~world! }
+% \regex_replace_case_all:nN
+% {
+% { [A-Za-z]+ } { ``\0'' }
+% { \b } { --- }
+% { . } { [\0] }
+% } \l_tmpa_tl
+% \end{verbatim}
+% results in \cs{l_tmpa_tl} having the contents
+% \verb*|``Hello''---[,][ ]``world''---[!]|. Note in particular that
+% the word-boundary assertion |\b| did not match at the start of words
+% because the case |[A-Za-z]+| matched at these positions. To change
+% this, one could simply swap the order of the two cases in the
+% argument of \cs{regex_replace_case_all:nN}.
+% \end{function}
+%
+% \section{Scratch regular expressions}
+%
+% \begin{variable}[added = 2017-12-11]{\l_tmpa_regex, \l_tmpb_regex}
+% Scratch regex for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}[added = 2017-12-11]{\g_tmpa_regex, \g_tmpb_regex}
+% Scratch regex for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Bugs, misfeatures, future work, and other possibilities}
+%
+% The following need to be done now.
+% \begin{itemize}
+% \item Rewrite the documentation in a more ordered way, perhaps add a
+% \textsc{bnf}?
+% \end{itemize}
+%
+% Additional error-checking to come.
+% \begin{itemize}
+% \item Clean up the use of messages.
+% \item Cleaner error reporting in the replacement phase.
+% \item Add tracing information.
+% \item Detect attempts to use back-references and other
+% non-implemented syntax.
+% \item Test for the maximum register \cs[no-index]{c_max_register_int}.
+% \item Find out whether the fact that |\W| and friends match the
+% end-marker leads to bugs. Possibly update \cs[no-index]{__regex_item_reverse:n}.
+% \item The empty cs should be matched by |\c{}|, not by
+% |\c{csname.?endcsname\s?}|.
+% \end{itemize}
+%
+% Code improvements to come.
+% \begin{itemize}
+% \item Shift arrays so that the useful information starts at
+% position~$1$.
+% \item Only build |\c{...}| once.
+% \item Use arrays for the left and right state stacks when
+% compiling a regex.
+% \item Should \cs[no-index]{__regex_action_free_group:n} only be used for greedy
+% |{n,}| quantifier? (I think not.)
+% \item Quantifiers for |\u| and assertions.
+% \item When matching, keep track of an explicit stack of
+% \texttt{curr_state} and \texttt{curr_submatches}.
+% \item If possible, when a state is reused by the same thread, kill
+% other subthreads.
+% \item Use an array rather than \cs[no-index]{g__regex_balance_tl}
+% to build the function \cs[no-index]{__regex_replacement_balance_one_match:n}.
+% \item Reduce the number of epsilon-transitions in alternatives.
+% \item Optimize simple strings: use less states (|abcade| should give
+% two states, for |abc| and |ade|). [Does that really make sense?]
+% \item Optimize groups with no alternative.
+% \item Optimize states with a single \cs[no-index]{__regex_action_free:n}.
+% \item Optimize the use of \cs[no-index]{__regex_action_success:} by inserting it
+% in state $2$ directly instead of having an extra transition.
+% \item Optimize the use of \cs[no-index]{int_step_...} functions.
+% \item Groups don't capture within regexes for csnames; optimize and
+% document.
+% \item Better \enquote{show} for anchors, properties, and catcode tests.
+% \item Does |\K| really need a new state for itself?
+% \item When compiling, use a boolean \texttt{in_cs} and less magic
+% numbers.
+% \end{itemize}
+%
+% The following features are likely to be implemented at some point
+% in the future.
+% \begin{itemize}
+% \item General look-ahead/behind assertions.
+% \item Regex matching on external files.
+% \item Conditional subpatterns with look ahead/behind: \enquote{if
+% what follows is [\ldots{}], then [\ldots{}]}.
+% \item |(*..)| and |(?..)| sequences to set some options.
+% \item UTF-8 mode for \pdfTeX{}.
+% \item Newline conventions are not done.
+% In particular, we should have an option for |.| not to match newlines.
+% Also, |\A| should differ from |^|, and |\Z|, |\z| and |$| should
+% differ.
+% \item Unicode properties: |\p{..}| and |\P{..}|;
+% |\X| which should match any \enquote{extended} Unicode sequence.
+% This requires to manipulate a lot of data, probably using tree-boxes.
+% \end{itemize}
+%
+% The following features of \textsc{pcre} or Perl may or may not be
+% implemented.
+% \begin{itemize}
+% \item Callout with |(?C...)| or other syntax: some internal code
+% changes make that possible, and it can be useful for instance in
+% the replacement code to stop a regex replacement when some marker
+% has been found; this raises the question of a potential
+% |\regex_break:| and then of playing well with \cs{tl_map_break:}
+% called from within the code in a regex. It also raises the
+% question of nested calls to the regex machinery, which is a
+% problem since \tn{fontdimen} are global.
+% \item Conditional subpatterns (other than with a look-ahead or
+% look-behind condition): this is non-regular, isn't it?
+% \item Named subpatterns: \TeX{} programmers have lived so far
+% without any need for named macro parameters.
+% \end{itemize}
+%
+% The following features of \textsc{pcre} or Perl will definitely not be
+% implemented.
+% \begin{itemize}
+% \item Back-references: non-regular feature, this requires
+% backtracking, which is prohibitively slow.
+% \item Recursion: this is a non-regular feature.
+% \item Atomic grouping, possessive quantifiers: those tools, mostly
+% meant to fix catastrophic backtracking, are unnecessary in a
+% non-backtracking algorithm, and difficult to implement.
+% \item Subroutine calls: this syntactic sugar is difficult to include
+% in a non-backtracking algorithm, in particular because the
+% corresponding group should be treated as atomic.
+% \item Backtracking control verbs: intrinsically tied to
+% backtracking.
+% \item |\ddd|, matching the character with octal code \texttt{ddd}:
+% we already have |\x{...}| and the syntax is confusingly close to
+% what we could have used for backreferences (|\1|, |\2|, \ldots{}),
+% making it harder to produce useful error message.
+% \item |\cx|, similar to \TeX{}'s own |\^^x|.
+% \item Comments: \TeX{} already has its own system for comments.
+% \item |\Q...\E| escaping: this would require to read the argument
+% verbatim, which is not in the scope of this module.
+% \item |\C| single byte in UTF-8 mode: \XeTeX{} and \LuaTeX{} serve
+% us characters directly, and splitting those into bytes is tricky,
+% encoding dependent, and most likely not useful anyways.
+% \end{itemize}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3regex} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=regex>
+% \end{macrocode}
+%
+% \subsection{Plan of attack}
+%
+% Most regex engines use backtracking. This allows to provide very
+% powerful features (back-references come to mind first), but it is
+% costly, and raises the problem of catastrophic backtracking. Since
+% \TeX{} is not first and foremost a programming language, complicated
+% code tends to run slowly, and we must use faster, albeit slightly more
+% restrictive, techniques, coming from automata theory.
+%
+% Given a regular expression of $n$ characters, we do the following:
+% \begin{itemize}
+% \item (Compiling.) Analyse the regex, finding invalid input, and
+% convert it to an internal representation.
+% \item (Building.) Convert the compiled regex to a non-deterministic
+% finite automaton (\textsc{nfa}) with $O(n)$ states which
+% accepts precisely token lists matching that regex.
+% \item (Matching.) Loop through the query token list one token (one
+% \enquote{position}) at a time, exploring in parallel every
+% possible path (\enquote{active thread}) through the \textsc{nfa},
+% considering active threads in an order determined by the
+% quantifiers' greediness.
+% \end{itemize}
+%
+% We use the following vocabulary in the code comments (and in variable
+% names).
+% \begin{itemize}
+% \item \emph{Group}: index of the capturing group, $-1$ for
+% non-capturing groups. ^^A start/end index?
+% \item \emph{Position}: each token in the query is labelled by an
+% integer \meta{position}, with $\texttt{min_pos} - 1 \leq
+% \meta{position} \leq \texttt{max_pos}$. The lowest and highest
+% positions $\texttt{min_pos} - 1$ and $\texttt{max_pos}$
+% correspond to imaginary begin and end markers (with
+% non-existent category code and character code).
+% $\texttt{max_pos}$ is only set quite late in the processing.
+% \item \emph{Query}: the token list to which we apply the regular
+% expression.
+% \item \emph{State}: each state of the \textsc{nfa} is labelled by an
+% integer \meta{state} with $\texttt{min_state} \leq \meta{state} <
+% \texttt{max_state}$.
+% \item \emph{Active thread}: state of the \textsc{nfa} that is reached
+% when reading the query token list for the matching. Those threads
+% are ordered according to the greediness of quantifiers.
+% \item \emph{Step}: used when matching, starts at $0$, incremented
+% every time a character is read, and is not reset when searching
+% for repeated matches. The integer \cs{l_@@_step_int} is a
+% unique id for all the steps of the matching algorithm.
+% \end{itemize}
+%
+% We use \pkg{l3intarray} to manipulate arrays of integers.
+% We also abuse \TeX{}'s
+% \tn{toks} registers, by accessing them directly by number rather than
+% tying them to control sequence using the \tn{newtoks} allocation
+% functions. Specifically, these arrays and \tn{toks} are used as
+% follows. When building,
+% \tn{toks}\meta{state} holds the tests and actions to perform in the
+% \meta{state} of the \textsc{nfa}. When matching,
+% \begin{itemize}
+% \item \cs{g_@@_state_active_intarray} holds the last \meta{step} in
+% which each \meta{state} was active.
+% \item \cs{g_@@_thread_info_intarray} consists of blocks for each
+% \meta{thread} (with $\texttt{min_thread} \leq \meta{thread} <
+% \texttt{max_thread}$). Each block has
+% $1+2\cs{l_@@_capturing_group_int}$ entries: the \meta{state} in
+% which the \meta{thread} currently is, followed by the beginnings
+% of all submatches, and then the ends of all submatches. The
+% \meta{threads} are ordered starting from the best to the least
+% preferred.
+% \item \cs{g_@@_submatch_prev_intarray}, \cs{g_@@_submatch_begin_intarray}
+% and \cs{g_@@_submatch_end_intarray} hold, for each submatch (as would
+% be extracted by \cs{regex_extract_all:nnN}), the place where the
+% submatch started to be looked for and its two end-points. For
+% historical reasons, the minimum index is twice \texttt{max_state},
+% and the used registers go up to \cs{l_@@_submatch_int}. They are
+% organized in blocks of \cs{l_@@_capturing_group_int} entries, each
+% block corresponding to one match with all its submatches stored in
+% consecutive entries.
+% \end{itemize}
+% When actually building the result,
+% \begin{itemize}
+% \item \tn{toks}\meta{position} holds \meta{tokens} which \texttt{o}-
+% and \texttt{e}-expand to the \meta{position}-th token in the query.
+% \item \cs{g_@@_balance_intarray} holds the balance of begin-group and
+% end-group character tokens which appear before that point in the
+% token list.
+% \end{itemize}
+%
+% The code is structured as follows. Variables are introduced in the
+% relevant section. First we present some generic helper functions. Then
+% comes the code for compiling a regular expression, and for showing the
+% result of the compilation. The building phase converts a compiled
+% regex to \textsc{nfa} states, and the automaton is run by the code in
+% the following section. The only remaining brick is parsing the
+% replacement text and performing the replacement. We are then ready for
+% all the user functions. Finally, messages, and a little bit of tracing
+% code.
+%
+% \subsection{Helpers}
+%
+% \begin{macro}{\@@_int_eval:w}
+% Access the primitive: performance is key here, so we do not use
+% the slower route \emph{via} \cs{int_eval:n}.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_int_eval:w \tex_numexpr:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_standard_escapechar:}
+% Make the \tn{escapechar} into the standard backslash.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_standard_escapechar:
+ { \int_set:Nn \tex_escapechar:D { `\\ } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_toks_use:w}
+% Unpack a \tn{toks} given its number.
+% \begin{macrocode}
+\cs_new:Npn \@@_toks_use:w { \tex_the:D \tex_toks:D }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_toks_clear:N, \@@_toks_set:Nn, \@@_toks_set:No}
+% Empty a \tn{toks} or set it to a value, given its number.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_toks_clear:N #1
+ { \tex_toks:D #1 = { } }
+\cs_new_eq:NN \@@_toks_set:Nn \tex_toks:D
+\cs_new_protected:Npn \@@_toks_set:No #1
+ { \tex_toks:D #1 = \exp_after:wN }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_toks_memcpy:NNn}
+% Copy |#3| \tn{toks} registers from |#2| onwards to |#1| onwards,
+% like |C|'s |memcpy|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_toks_memcpy:NNn #1#2#3
+ {
+ \prg_replicate:nn {#3}
+ {
+ \tex_toks:D #1 = \tex_toks:D #2
+ \int_incr:N #1
+ \int_incr:N #2
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_toks_put_left:Ne}
+% \begin{macro}{\@@_toks_put_right:Ne, \@@_toks_put_right:Nn}
+% During the building phase we wish to add \texttt{e}-expanded
+% material to \tn{toks}, either to the left or to the right. The
+% expansion is done \enquote{by hand} for optimization (these
+% operations are used quite a lot). The \texttt{Nn} version of
+% \cs{@@_toks_put_right:Ne} is provided because it is more
+% efficient than \texttt{e}-expanding with \cs{exp_not:n}.
+% \begin{macrocode}
+\cs_if_exist:NTF \tex_etokspre:D
+ { \cs_new_eq:NN \@@_toks_put_left:Ne \tex_etokspre:D }
+ {
+ \cs_new_protected:Npn \@@_toks_put_left:Ne #1#2
+ { \tex_toks:D #1 = \tex_expanded:D {{ #2 \tex_the:D \tex_toks:D #1 }} }
+ }
+\cs_if_exist:NTF \tex_etoksapp:D
+ { \cs_new_eq:NN \@@_toks_put_right:Ne \tex_etoksapp:D }
+ {
+ \cs_new_protected:Npn \@@_toks_put_right:Ne #1#2
+ { \tex_toks:D #1 = \tex_expanded:D {{ \tex_the:D \tex_toks:D #1 #2 }} }
+ }
+\cs_if_exist:NTF \tex_toksapp:D
+ { \cs_new_eq:NN \@@_toks_put_right:Nn \tex_toksapp:D }
+ {
+ \cs_new_protected:Npn \@@_toks_put_right:Nn #1#2
+ { \tex_toks:D #1 = \exp_after:wN { \tex_the:D \tex_toks:D #1 #2 } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_curr_cs_to_str:}
+% Expands to the string representation of the token (known to be a
+% control sequence) at the current position \cs{l_@@_curr_pos_int}.
+% It should only be used in \texttt{e}/\texttt{x}-expansion to avoid losing a
+% leading space.
+% \begin{macrocode}
+\cs_new:Npn \@@_curr_cs_to_str:
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \cs_to_str:N
+ \l_@@_curr_token_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_intarray_item:NnF, \@@_intarray_item_aux:nNF}
+% Item of intarray, with a default value.
+% \begin{macrocode}
+\cs_new:Npn \@@_intarray_item:NnF #1#2
+ { \exp_args:No \@@_intarray_item_aux:nNF { \tex_the:D \@@_int_eval:w #2 } #1 }
+\cs_new:Npn \@@_intarray_item_aux:nNF #1#2
+ {
+ \if_int_compare:w #1 > \c_zero_int
+ \exp_after:wN \use_ii:nnn
+ \fi:
+ \use_ii:nn { \__kernel_intarray_item:Nn #2 {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_maplike_break:}
+% Analogous to \cs{tl_map_break:}, this correctly exits
+% \cs{tl_map_inline:nn} and similar constructions and jumps to the
+% matching \cs{prg_break_point:Nn} \cs{@@_maplike_break:} |{| |}|.
+% \begin{macrocode}
+\cs_new:Npn \@@_maplike_break:
+ { \prg_map_break:Nn \@@_maplike_break: { } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_tl_odd_items:n, \@@_tl_even_items:n, \@@_tl_even_items_loop:nn}
+% Map through a token list one pair at a time, leaving the
+% odd-numbered or even-numbered items (the first item is
+% numbered~$1$).
+% \begin{macrocode}
+\cs_new:Npn \@@_tl_odd_items:n #1 { \@@_tl_even_items:n { ? #1 } }
+\cs_new:Npn \@@_tl_even_items:n #1
+ {
+ \@@_tl_even_items_loop:nn #1 \q_@@_nil \q_@@_nil
+ \prg_break_point:
+ }
+\cs_new:Npn \@@_tl_even_items_loop:nn #1#2
+ {
+ \@@_use_none_delimit_by_q_nil:w #2 \prg_break: \q_@@_nil
+ { \exp_not:n {#2} }
+ \@@_tl_even_items_loop:nn
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Constants and variables}
+%
+% \begin{macro}{\@@_tmp:w}
+% Temporary function used for various short-term purposes.
+% \begin{macrocode}
+\cs_new:Npn \@@_tmp:w { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}
+% {
+% \l_@@_internal_a_tl, \l_@@_internal_b_tl,
+% \l_@@_internal_a_int, \l_@@_internal_b_int,
+% \l_@@_internal_c_int, \l_@@_internal_bool,
+% \l_@@_internal_seq, \g_@@_internal_tl,
+% }
+% Temporary variables used for various purposes.
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_a_tl
+\tl_new:N \l_@@_internal_b_tl
+\int_new:N \l_@@_internal_a_int
+\int_new:N \l_@@_internal_b_int
+\int_new:N \l_@@_internal_c_int
+\bool_new:N \l_@@_internal_bool
+\seq_new:N \l_@@_internal_seq
+\tl_new:N \g_@@_internal_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_build_tl}
+% This temporary variable is specifically for use with the |tl_build|
+% machinery.
+% \begin{macrocode}
+\tl_new:N \l_@@_build_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_no_match_regex}
+% This regular expression matches nothing, but is still a valid
+% regular expression. We could use a failing assertion, but I went for
+% an empty class. It is used as the initial value for regular
+% expressions declared using \cs{regex_new:N}.
+% \begin{macrocode}
+\tl_const:Nn \c_@@_no_match_regex
+ {
+ \@@_branch:n
+ { \@@_class:NnnnN \c_true_bool { } { 1 } { 0 } \c_true_bool }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_balance_int}
+% During this phase, \cs{l_@@_balance_int} counts the balance of
+% begin-group and end-group character tokens which appear before a
+% given point in the token list. This variable is also used to keep
+% track of the balance in the replacement text.
+% \begin{macrocode}
+\int_new:N \l_@@_balance_int
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Testing characters}
+%
+% \begin{macro}{\c_@@_ascii_min_int, \c_@@_ascii_max_control_int, \c_@@_ascii_max_int}
+% \begin{macrocode}
+\int_const:Nn \c_@@_ascii_min_int { 0 }
+\int_const:Nn \c_@@_ascii_max_control_int { 31 }
+\int_const:Nn \c_@@_ascii_max_int { 127 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\c_@@_ascii_lower_int}
+% \begin{macrocode}
+\int_const:Nn \c_@@_ascii_lower_int { `a - `A }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Internal auxiliaries}
+%
+% \begin{variable}{\q_@@_recursion_stop}
+% Internal recursion quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_recursion_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\q_@@_nil}
+% Internal quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_nil
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{
+% \@@_use_none_delimit_by_q_recursion_stop:w,
+% \@@_use_i_delimit_by_q_recursion_stop:nw,
+% \@@_use_none_delimit_by_q_nil:w,
+% }
+% Functions to gobble up to a quark.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_none_delimit_by_q_recursion_stop:w
+ #1 \q_@@_recursion_stop { }
+\cs_new:Npn \@@_use_i_delimit_by_q_recursion_stop:nw
+ #1 #2 \q_@@_recursion_stop {#1}
+\cs_new:Npn \@@_use_none_delimit_by_q_nil:w #1 \q_@@_nil { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\@@_quark_if_nil:n}
+% Branching quark conditional.
+% \begin{macrocode}
+\__kernel_quark_new_conditional:Nn \@@_quark_if_nil:N { F }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_break_point:TF}
+% \begin{macro}{\@@_break_true:w}
+% When testing whether a character of the query token list matches
+% a given character class in the regular expression, we often
+% have to test it against several ranges of characters, checking
+% if any one of those matches. This is done with a structure like
+% \begin{quote}
+% \meta{test1} \ldots{} \meta{test$\sb{n}$} \\
+% \cs{@@_break_point:TF} \Arg{true code} \Arg{false code}
+% \end{quote}
+% If any of the tests succeeds, it calls \cs{@@_break_true:w},
+% which cleans up and leaves \meta{true code} in the input stream.
+% Otherwise, \cs{@@_break_point:TF} leaves the \meta{false code}
+% in the input stream.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_break_true:w
+ #1 \@@_break_point:TF #2 #3 {#2}
+\cs_new_protected:Npn \@@_break_point:TF #1 #2 { #2 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_item_reverse:n}
+% This function makes showing regular expressions easier, and lets us
+% define |\D| in terms of |\d| for instance. There is a subtlety: the
+% end of the query is marked by $-2$, and thus matches |\D| and
+% other negated properties; this case is caught by another part of
+% the code.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_item_reverse:n #1
+ {
+ #1
+ \@@_break_point:TF { } \@@_break_true:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_item_caseful_equal:n, \@@_item_caseful_range:nn}
+% Simple comparisons triggering \cs{@@_break_true:w} when true.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_item_caseful_equal:n #1
+ {
+ \if_int_compare:w #1 = \l_@@_curr_char_int
+ \exp_after:wN \@@_break_true:w
+ \fi:
+ }
+\cs_new_protected:Npn \@@_item_caseful_range:nn #1 #2
+ {
+ \reverse_if:N \if_int_compare:w #1 > \l_@@_curr_char_int
+ \reverse_if:N \if_int_compare:w #2 < \l_@@_curr_char_int
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_break_true:w
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_item_caseless_equal:n, \@@_item_caseless_range:nn}
+% For caseless matching, we perform the test both on the
+% \texttt{curr_char} and on the \texttt{case_changed_char}. Before
+% doing the second set of tests, we make sure that
+% \texttt{case_changed_char} has been computed.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_item_caseless_equal:n #1
+ {
+ \if_int_compare:w #1 = \l_@@_curr_char_int
+ \exp_after:wN \@@_break_true:w
+ \fi:
+ \@@_maybe_compute_ccc:
+ \if_int_compare:w #1 = \l_@@_case_changed_char_int
+ \exp_after:wN \@@_break_true:w
+ \fi:
+ }
+\cs_new_protected:Npn \@@_item_caseless_range:nn #1 #2
+ {
+ \reverse_if:N \if_int_compare:w #1 > \l_@@_curr_char_int
+ \reverse_if:N \if_int_compare:w #2 < \l_@@_curr_char_int
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_break_true:w
+ \fi:
+ \fi:
+ \@@_maybe_compute_ccc:
+ \reverse_if:N \if_int_compare:w #1 > \l_@@_case_changed_char_int
+ \reverse_if:N \if_int_compare:w #2 < \l_@@_case_changed_char_int
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_break_true:w
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compute_case_changed_char:}
+% This function is called when \cs{l_@@_case_changed_char_int} has
+% not yet been computed. If the current character code is in the range
+% $[65,90]$ (upper-case), then add $32$, making it lowercase. If it is
+% in the lower-case letter range $[97,122]$, subtract $32$.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compute_case_changed_char:
+ {
+ \int_set_eq:NN \l_@@_case_changed_char_int \l_@@_curr_char_int
+ \if_int_compare:w \l_@@_curr_char_int > `Z \exp_stop_f:
+ \if_int_compare:w \l_@@_curr_char_int > `z \exp_stop_f: \else:
+ \if_int_compare:w \l_@@_curr_char_int < `a \exp_stop_f: \else:
+ \int_sub:Nn \l_@@_case_changed_char_int \c_@@_ascii_lower_int
+ \fi:
+ \fi:
+ \else:
+ \if_int_compare:w \l_@@_curr_char_int < `A \exp_stop_f: \else:
+ \int_add:Nn \l_@@_case_changed_char_int \c_@@_ascii_lower_int
+ \fi:
+ \fi:
+ \cs_set_eq:NN \@@_maybe_compute_ccc: \prg_do_nothing:
+ }
+\cs_new_eq:NN \@@_maybe_compute_ccc: \@@_compute_case_changed_char:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_item_equal:n, \@@_item_range:nn}
+% Those must always be defined to expand to a \texttt{caseful}
+% (default) or \texttt{caseless} version, and not be protected: they
+% must expand when compiling, to hard-code which tests are caseless or
+% caseful.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_item_equal:n ?
+\cs_new_eq:NN \@@_item_range:nn ?
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_item_catcode:nT, \@@_item_catcode_reverse:nT}
+% \begin{macro}{\@@_item_catcode:}
+% The argument is a sum of powers of $4$ with exponents given by the
+% allowed category codes (between $0$ and $13$). Dividing by a given
+% power of $4$ gives an odd result if and only if that category code
+% is allowed. If the catcode does not match, then skip the character
+% code tests which follow.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_item_catcode:
+ {
+ "
+ \if_case:w \l_@@_curr_catcode_int
+ 1 \or: 4 \or: 10 \or: 40
+ \or: 100 \or: \or: 1000 \or: 4000
+ \or: 10000 \or: \or: 100000 \or: 400000
+ \or: 1000000 \or: 4000000 \else: 1*0
+ \fi:
+ }
+\prg_new_protected_conditional:Npnn \@@_item_catcode:n #1 { T }
+ {
+ \if_int_odd:w \@@_int_eval:w #1 / \@@_item_catcode: \scan_stop:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new_protected:Npn \@@_item_catcode_reverse:nT #1#2
+ { \@@_item_catcode:nT {#1} { \@@_item_reverse:n {#2} } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_item_exact:nn, \@@_item_exact_cs:n}
+% This matches an exact \meta{category}-\meta{character code} pair, or
+% an exact control sequence, more precisely one of several possible
+% control sequences, separated by \cs{scan_stop:}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_item_exact:nn #1#2
+ {
+ \if_int_compare:w #1 = \l_@@_curr_catcode_int
+ \if_int_compare:w #2 = \l_@@_curr_char_int
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_break_true:w
+ \fi:
+ \fi:
+ }
+\cs_new_protected:Npn \@@_item_exact_cs:n #1
+ {
+ \int_compare:nNnTF \l_@@_curr_catcode_int = \c_zero_int
+ {
+ \__kernel_tl_set:Nx \l_@@_internal_a_tl
+ { \scan_stop: \@@_curr_cs_to_str: \scan_stop: }
+ \tl_if_in:noTF { \scan_stop: #1 \scan_stop: }
+ \l_@@_internal_a_tl
+ { \@@_break_true:w } { }
+ }
+ { }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_item_cs:n}
+% Match a control sequence (the argument is a compiled regex).
+% First test the catcode of the current token to be zero.
+% Then perform the matching test, and break if the csname
+% indeed matches.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_item_cs:n #1
+ {
+ \int_compare:nNnT \l_@@_curr_catcode_int = \c_zero_int
+ {
+ \group_begin:
+ \@@_single_match:
+ \@@_disable_submatches:
+ \@@_build_for_cs:n {#1}
+ \bool_set_eq:NN \l_@@_saved_success_bool
+ \g_@@_success_bool
+ \exp_args:Ne \@@_match_cs:n { \@@_curr_cs_to_str: }
+ \if_meaning:w \c_true_bool \g_@@_success_bool
+ \group_insert_after:N \@@_break_true:w
+ \fi:
+ \bool_gset_eq:NN \g_@@_success_bool
+ \l_@@_saved_success_bool
+ \group_end:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Character property tests}
+%
+% \begin{macro}
+% {
+% \@@_prop_d:, \@@_prop_h:, \@@_prop_s:,
+% \@@_prop_v:, \@@_prop_w:, \@@_prop_N:
+% }
+% Character property tests for |\d|, |\W|, \emph{etc.} These character
+% properties are not affected by the |(?i)| option. The characters
+% recognized by each one are as follows: |\d=[0-9]|,
+% |\w=[0-9A-Z_a-z]|, \verb*+\s=[\ \^^I\^^J\^^L\^^M]+,
+% \verb*+\h=[\ \^^I]+, |\v=[\^^J-\^^M]|, and the upper case
+% counterparts match anything that the lower case does not match. The
+% order in which the various tests appear is optimized for usual
+% mostly lower case letter text.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_prop_d:
+ { \@@_item_caseful_range:nn { `0 } { `9 } }
+\cs_new_protected:Npn \@@_prop_h:
+ {
+ \@@_item_caseful_equal:n { `\ }
+ \@@_item_caseful_equal:n { `\^^I }
+ }
+\cs_new_protected:Npn \@@_prop_s:
+ {
+ \@@_item_caseful_equal:n { `\ }
+ \@@_item_caseful_equal:n { `\^^I }
+ \@@_item_caseful_equal:n { `\^^J }
+ \@@_item_caseful_equal:n { `\^^L }
+ \@@_item_caseful_equal:n { `\^^M }
+ }
+\cs_new_protected:Npn \@@_prop_v:
+ { \@@_item_caseful_range:nn { `\^^J } { `\^^M } } % lf, vtab, ff, cr
+\cs_new_protected:Npn \@@_prop_w:
+ {
+ \@@_item_caseful_range:nn { `a } { `z }
+ \@@_item_caseful_range:nn { `A } { `Z }
+ \@@_item_caseful_range:nn { `0 } { `9 }
+ \@@_item_caseful_equal:n { `_ }
+ }
+\cs_new_protected:Npn \@@_prop_N:
+ {
+ \@@_item_reverse:n
+ { \@@_item_caseful_equal:n { `\^^J } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_posix_alnum:, \@@_posix_alpha:, \@@_posix_ascii:,
+% \@@_posix_blank:, \@@_posix_cntrl:, \@@_posix_digit:,
+% \@@_posix_graph:, \@@_posix_lower:, \@@_posix_print:,
+% \@@_posix_punct:, \@@_posix_space:, \@@_posix_upper:,
+% \@@_posix_word: , \@@_posix_xdigit:
+% }
+% \textsc{posix} properties. No surprise.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_posix_alnum:
+ { \@@_posix_alpha: \@@_posix_digit: }
+\cs_new_protected:Npn \@@_posix_alpha:
+ { \@@_posix_lower: \@@_posix_upper: }
+\cs_new_protected:Npn \@@_posix_ascii:
+ {
+ \@@_item_caseful_range:nn
+ \c_@@_ascii_min_int
+ \c_@@_ascii_max_int
+ }
+\cs_new_eq:NN \@@_posix_blank: \@@_prop_h:
+\cs_new_protected:Npn \@@_posix_cntrl:
+ {
+ \@@_item_caseful_range:nn
+ \c_@@_ascii_min_int
+ \c_@@_ascii_max_control_int
+ \@@_item_caseful_equal:n \c_@@_ascii_max_int
+ }
+\cs_new_eq:NN \@@_posix_digit: \@@_prop_d:
+\cs_new_protected:Npn \@@_posix_graph:
+ { \@@_item_caseful_range:nn { `! } { `\~ } }
+\cs_new_protected:Npn \@@_posix_lower:
+ { \@@_item_caseful_range:nn { `a } { `z } }
+\cs_new_protected:Npn \@@_posix_print:
+ { \@@_item_caseful_range:nn { `\ } { `\~ } }
+\cs_new_protected:Npn \@@_posix_punct:
+ {
+ \@@_item_caseful_range:nn { `! } { `/ }
+ \@@_item_caseful_range:nn { `: } { `@ }
+ \@@_item_caseful_range:nn { `[ } { `` }
+ \@@_item_caseful_range:nn { `\{ } { `\~ }
+ }
+\cs_new_protected:Npn \@@_posix_space:
+ {
+ \@@_item_caseful_equal:n { `\ }
+ \@@_item_caseful_range:nn { `\^^I } { `\^^M }
+ }
+\cs_new_protected:Npn \@@_posix_upper:
+ { \@@_item_caseful_range:nn { `A } { `Z } }
+\cs_new_eq:NN \@@_posix_word: \@@_prop_w:
+\cs_new_protected:Npn \@@_posix_xdigit:
+ {
+ \@@_posix_digit:
+ \@@_item_caseful_range:nn { `A } { `F }
+ \@@_item_caseful_range:nn { `a } { `f }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Simple character escape}
+%
+% Before actually parsing the regular expression or the replacement
+% text, we go through them once, converting |\n| to the character $10$,
+% \emph{etc.} In this pass, we also convert any special character
+% (\texttt{*}, \texttt{?}, \texttt{\{}, etc.) or escaped alphanumeric
+% character into a marker indicating that this was a special sequence,
+% and replace escaped special characters and non-escaped alphanumeric
+% characters by markers indicating that those were \enquote{raw}
+% characters. The rest of the code can then avoid caring about escaping
+% issues (those can become quite complex to handle in combination with
+% ranges in character classes).
+%
+% Usage: \cs{@@_escape_use:nnnn} \meta{inline~1} \meta{inline~2}
+% \meta{inline~3} \Arg{token list} The \meta{token list} is converted to
+% a string, then read from left to right, interpreting backslashes as
+% escaping the next character. Unescaped characters are fed to the
+% function \meta{inline~1}, and escaped characters are fed to the function
+% \meta{inline~2} within an \texttt{e}-expansion context (typically those
+% functions perform some tests on their argument to decide how to output
+% them). The escape sequences |\a|, |\e|, |\f|, |\n|, |\r|, |\t| and
+% |\x| are recognized, and those are replaced by the corresponding
+% character, then fed to \meta{inline~3}. The result is then left in the
+% input stream. Spaces are ignored unless escaped.
+%
+% The conversion is done within an \texttt{e}-expanding assignment.
+%
+% \begin{macro}{\@@_escape_use:nnnn}
+% The result is built in \cs{l_@@_internal_a_tl}, which is then left
+% in the input stream. Tracing code is added as appropriate inside
+% this token list. Go through |#4| once, applying |#1|,
+% |#2|, or |#3| as relevant to each character (after de-escaping
+% it).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_escape_use:nnnn #1#2#3#4
+ {
+ \group_begin:
+ \tl_clear:N \l_@@_internal_a_tl
+ \cs_set:Npn \@@_escape_unescaped:N ##1 { #1 }
+ \cs_set:Npn \@@_escape_escaped:N ##1 { #2 }
+ \cs_set:Npn \@@_escape_raw:N ##1 { #3 }
+ \@@_standard_escapechar:
+ \__kernel_tl_gset:Nx \g_@@_internal_tl
+ { \__kernel_str_to_other_fast:n {#4} }
+ \tl_put_right:Ne \l_@@_internal_a_tl
+ {
+ \exp_after:wN \@@_escape_loop:N \g_@@_internal_tl
+ \scan_stop: \prg_break_point:
+ }
+ \exp_after:wN
+ \group_end:
+ \l_@@_internal_a_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_escape_loop:N}
+% \begin{macro}+\@@_escape_\:w+
+% \cs{@@_escape_loop:N} reads one character: if it is special
+% (space, backslash, or end-marker), perform the associated action,
+% otherwise it is simply an unescaped character. After a backslash,
+% the same is done, but unknown characters are \enquote{escaped}.
+% \begin{macrocode}
+\cs_new:Npn \@@_escape_loop:N #1
+ {
+ \cs_if_exist_use:cF { @@_escape_\token_to_str:N #1:w }
+ { \@@_escape_unescaped:N #1 }
+ \@@_escape_loop:N
+ }
+\cs_new:cpn { @@_escape_ \c_backslash_str :w }
+ \@@_escape_loop:N #1
+ {
+ \cs_if_exist_use:cF { @@_escape_/\token_to_str:N #1:w }
+ { \@@_escape_escaped:N #1 }
+ \@@_escape_loop:N
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_escape_unescaped:N, \@@_escape_escaped:N, \@@_escape_raw:N}
+% Those functions are never called before being given a new meaning,
+% so their definitions here don't matter.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_escape_unescaped:N ?
+\cs_new_eq:NN \@@_escape_escaped:N ?
+\cs_new_eq:NN \@@_escape_raw:N ?
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_escape_\scan_stop::w, \@@_escape_/\scan_stop::w,
+% \@@_escape_/a:w, \@@_escape_/e:w, \@@_escape_/f:w,
+% \@@_escape_/n:w, \@@_escape_/r:w, \@@_escape_/t:w
+% }
+% \begin{macro}+\@@_escape_ :w+
+% The loop is ended upon seeing the end-marker
+% \enquote{\texttt{break}}, with an error if the string ended in a
+% backslash. Spaces are ignored, and |\a|, |\e|, |\f|, |\n|, |\r|,
+% |\t| take their meaning here.
+% \begin{macrocode}
+\cs_new_eq:cN { @@_escape_ \iow_char:N\\scan_stop: :w } \prg_break:
+\cs_new:cpn { @@_escape_/ \iow_char:N\\scan_stop: :w }
+ {
+ \msg_expandable_error:nn { regex } { trailing-backslash }
+ \prg_break:
+ }
+\cs_new:cpn { @@_escape_~:w } { }
+\cs_new:cpe { @@_escape_/a:w }
+ { \exp_not:N \@@_escape_raw:N \iow_char:N \^^G }
+\cs_new:cpe { @@_escape_/t:w }
+ { \exp_not:N \@@_escape_raw:N \iow_char:N \^^I }
+\cs_new:cpe { @@_escape_/n:w }
+ { \exp_not:N \@@_escape_raw:N \iow_char:N \^^J }
+\cs_new:cpe { @@_escape_/f:w }
+ { \exp_not:N \@@_escape_raw:N \iow_char:N \^^L }
+\cs_new:cpe { @@_escape_/r:w }
+ { \exp_not:N \@@_escape_raw:N \iow_char:N \^^M }
+\cs_new:cpe { @@_escape_/e:w }
+ { \exp_not:N \@@_escape_raw:N \iow_char:N \^^[ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_escape_/x:w}
+% \begin{macro}{\@@_escape_x_end:w, \@@_escape_x_large:n}
+% When |\x| is encountered, \cs{@@_escape_x_test:N} is responsible for
+% grabbing some hexadecimal digits, and feeding the result to
+% \cs{@@_escape_x_end:w}. If the number is too big interrupt the
+% assignment and produce an error, otherwise call \cs{@@_escape_raw:N}
+% on the corresponding character token.
+% \begin{macrocode}
+\cs_new:cpn { @@_escape_/x:w } \@@_escape_loop:N
+ {
+ \exp_after:wN \@@_escape_x_end:w
+ \int_value:w "0 \@@_escape_x_test:N
+ }
+\cs_new:Npn \@@_escape_x_end:w #1 ;
+ {
+ \int_compare:nNnTF {#1} > \c_max_char_int
+ {
+ \msg_expandable_error:nnff { regex } { x-overflow }
+ {#1} { \int_to_Hex:n {#1} }
+ }
+ {
+ \exp_last_unbraced:Nf \@@_escape_raw:N
+ { \char_generate:nn {#1} { 12 } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_escape_x_test:N, \@@_escape_x_testii:N}
+% Find out whether the first character is a left brace (allowing any
+% number of hexadecimal digits), or not (allowing up to two
+% hexadecimal digits). We need to check for the end-of-string marker.
+% Eventually, call either \cs{@@_escape_x_loop:N} or
+% \cs{@@_escape_x:N}.
+% \begin{macrocode}
+\cs_new:Npn \@@_escape_x_test:N #1
+ {
+ \if_meaning:w \scan_stop: #1
+ \exp_after:wN \use_i:nnn \exp_after:wN ;
+ \fi:
+ \use:n
+ {
+ \if_charcode:w \c_space_token #1
+ \exp_after:wN \@@_escape_x_test:N
+ \else:
+ \exp_after:wN \@@_escape_x_testii:N
+ \exp_after:wN #1
+ \fi:
+ }
+ }
+\cs_new:Npn \@@_escape_x_testii:N #1
+ {
+ \if_charcode:w \c_left_brace_str #1
+ \exp_after:wN \@@_escape_x_loop:N
+ \else:
+ \@@_hexadecimal_use:NTF #1
+ { \exp_after:wN \@@_escape_x:N }
+ { ; \exp_after:wN \@@_escape_loop:N \exp_after:wN #1 }
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_escape_x:N}
+% This looks for the second digit in the unbraced case.
+% \begin{macrocode}
+\cs_new:Npn \@@_escape_x:N #1
+ {
+ \if_meaning:w \scan_stop: #1
+ \exp_after:wN \use_i:nnn \exp_after:wN ;
+ \fi:
+ \use:n
+ {
+ \@@_hexadecimal_use:NTF #1
+ { ; \@@_escape_loop:N }
+ { ; \@@_escape_loop:N #1 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_escape_x_loop:N, \@@_escape_x_loop_error:}
+% Grab hexadecimal digits, skip spaces, and at the end, check that
+% there is a right brace, otherwise raise an error outside the
+% assignment.
+% \begin{macrocode}
+\cs_new:Npn \@@_escape_x_loop:N #1
+ {
+ \if_meaning:w \scan_stop: #1
+ \exp_after:wN \use_ii:nnn
+ \fi:
+ \use_ii:nn
+ { ; \@@_escape_x_loop_error:n { } {#1} }
+ {
+ \@@_hexadecimal_use:NTF #1
+ { \@@_escape_x_loop:N }
+ {
+ \token_if_eq_charcode:NNTF \c_space_token #1
+ { \@@_escape_x_loop:N }
+ {
+ ;
+ \exp_after:wN
+ \token_if_eq_charcode:NNTF \c_right_brace_str #1
+ { \@@_escape_loop:N }
+ { \@@_escape_x_loop_error:n {#1} }
+ }
+ }
+ }
+ }
+\cs_new:Npn \@@_escape_x_loop_error:n #1
+ {
+ \msg_expandable_error:nnn { regex } { x-missing-rbrace } {#1}
+ \@@_escape_loop:N #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_hexadecimal_use:NTF}
+% \TeX{} detects uppercase hexadecimal digits for us but not the
+% lowercase letters, which we need to detect and replace by their
+% uppercase counterpart.
+% \begin{macrocode}
+\cs_new:Npn \@@_hexadecimal_use:NTF #1
+ {
+ \if_int_compare:w \c_one_int < "1 \token_to_str:N #1 \exp_stop_f:
+ #1
+ \else:
+ \if_case:w
+ \@@_int_eval:w \exp_after:wN ` \token_to_str:N #1 - `a \scan_stop:
+ A
+ \or: B
+ \or: C
+ \or: D
+ \or: E
+ \or: F
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \use_iii:nnn
+ \fi:
+ \fi:
+ \use_i:nn
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_char_if_alphanumeric:NTF, \@@_char_if_special:NTF}
+% These two tests are used in the first pass when parsing a regular
+% expression. That pass is responsible for finding escaped and
+% non-escaped characters, and recognizing which ones have special
+% meanings and which should be interpreted as \enquote{raw}
+% characters. Namely,
+% \begin{itemize}
+% \item alphanumerics are \enquote{raw} if they are not escaped, and
+% may have a special meaning when escaped;
+% \item non-alphanumeric printable ascii characters are
+% \enquote{raw} if they are escaped, and may have a special
+% meaning when not escaped;
+% \item characters other than printable ascii are always
+% \enquote{raw}.
+% \end{itemize}
+% The code is ugly, and highly based on magic numbers and the ascii
+% codes of characters. This is mostly unavoidable for performance
+% reasons. Maybe the tests can be optimized a little bit more.
+% Here, \enquote{alphanumeric} means \texttt{0}--\texttt{9},
+% \texttt{A}--\texttt{Z}, \texttt{a}--\texttt{z};
+% \enquote{special} character means non-alphanumeric
+% but printable ascii, from space (hex \texttt{20}) to
+% \texttt{del} (hex \texttt{7E}).
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_char_if_special:N #1 { TF }
+ {
+ \if:w
+ T
+ \if_int_compare:w `#1 > `Z \exp_stop_f:
+ \if_int_compare:w `#1 > `z \exp_stop_f:
+ \if_int_compare:w `#1 < \c_@@_ascii_max_int
+ \else: F \fi:
+ \else:
+ \if_int_compare:w `#1 < `a \exp_stop_f:
+ \else: F \fi:
+ \fi:
+ \else:
+ \if_int_compare:w `#1 > `9 \exp_stop_f:
+ \if_int_compare:w `#1 < `A \exp_stop_f:
+ \else: F \fi:
+ \else:
+ \if_int_compare:w `#1 < `0 \exp_stop_f:
+ \if_int_compare:w `#1 < `\ \exp_stop_f:
+ F \fi:
+ \else: F \fi:
+ \fi:
+ \fi:
+ T
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_new_conditional:Npnn \@@_char_if_alphanumeric:N #1 { TF }
+ {
+ \if:w
+ T
+ \if_int_compare:w `#1 > `Z \exp_stop_f:
+ \if_int_compare:w `#1 > `z \exp_stop_f:
+ F
+ \else:
+ \if_int_compare:w `#1 < `a \exp_stop_f:
+ F \fi:
+ \fi:
+ \else:
+ \if_int_compare:w `#1 > `9 \exp_stop_f:
+ \if_int_compare:w `#1 < `A \exp_stop_f:
+ F \fi:
+ \else:
+ \if_int_compare:w `#1 < `0 \exp_stop_f:
+ F \fi:
+ \fi:
+ \fi:
+ T
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Compiling}
+%
+% A regular expression starts its life as a string of characters. In
+% this section, we convert it to internal instructions, resulting in a
+% \enquote{compiled} regular expression. This compiled expression is
+% then turned into states of an automaton in the building
+% phase. Compiled regular expressions consist of the following:
+% \begin{itemize}
+% \item \cs{@@_class:NnnnN} \meta{boolean} \Arg{tests} \Arg{min}
+% \Arg{more} \meta{lazyness}
+% \item \cs{@@_group:nnnN} \Arg{branches} \Arg{min} \Arg{more}
+% \meta{lazyness}, also \cs{@@_group_no_capture:nnnN} and
+% \cs{@@_group_resetting:nnnN} with the same syntax.
+% \item \cs{@@_branch:n} \Arg{contents}
+% \item \cs{@@_command_K:}
+% \item \cs{@@_assertion:Nn} \meta{boolean} \Arg{assertion test},
+% where the \meta{assertion test} is \cs{@@_b_test:} or
+% \cs{@@_Z_test:} or \cs{@@_A_test:} or \cs{@@_G_test:}
+% \end{itemize}
+% Tests can be the following:
+% \begin{itemize}
+% \item \cs{@@_item_caseful_equal:n} \Arg{char code}
+% \item \cs{@@_item_caseless_equal:n} \Arg{char code}
+% \item \cs{@@_item_caseful_range:nn} \Arg{min} \Arg{max}
+% \item \cs{@@_item_caseless_range:nn} \Arg{min} \Arg{max}
+% \item \cs{@@_item_catcode:nT} \Arg{catcode bitmap} \Arg{tests}
+% \item \cs{@@_item_catcode_reverse:nT} \Arg{catcode bitmap} \Arg{tests}
+% \item \cs{@@_item_reverse:n} \Arg{tests}
+% \item \cs{@@_item_exact:nn} \Arg{catcode} \Arg{char code}
+% \item \cs{@@_item_exact_cs:n} \Arg{csnames}, more precisely given as
+% \meta{csname} \cs{scan_stop:} \meta{csname} \cs{scan_stop:}
+% \meta{csname} and so on in a brace group.
+% \item \cs{@@_item_cs:n} \Arg{compiled regex}
+% \end{itemize}
+%
+% \subsubsection{Variables used when compiling}
+%
+% \begin{variable}{\l_@@_group_level_int}
+% We make sure to open the same number of groups as we close.
+% \begin{macrocode}
+\int_new:N \l_@@_group_level_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_mode_int}
+% \begin{variable}
+% {
+% \c_@@_cs_in_class_mode_int,
+% \c_@@_cs_mode_int,
+% \c_@@_outer_mode_int,
+% \c_@@_catcode_mode_int,
+% \c_@@_class_mode_int,
+% \c_@@_catcode_in_class_mode_int
+% }
+% While compiling, ten modes are recognized, labelled $-63$, $-23$,
+% $-6$, $-2$, $0$, $2$, $3$, $6$, $23$, $63$. See
+% section~\ref{sec:regex-modes}. We only define some of these as
+% constants.
+% \begin{macrocode}
+\int_new:N \l_@@_mode_int
+\int_const:Nn \c_@@_cs_in_class_mode_int { -6 }
+\int_const:Nn \c_@@_cs_mode_int { -2 }
+\int_const:Nn \c_@@_outer_mode_int { 0 }
+\int_const:Nn \c_@@_catcode_mode_int { 2 }
+\int_const:Nn \c_@@_class_mode_int { 3 }
+\int_const:Nn \c_@@_catcode_in_class_mode_int { 6 }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_catcodes_int, \l_@@_default_catcodes_int}
+% \begin{variable}{\l_@@_catcodes_bool}
+% We wish to allow constructions such as |\c[^BE](..\cL[a-z]..)|,
+% where the outer catcode test applies to the whole group, but is
+% superseded by the inner catcode test. For this to work, we need to
+% keep track of lists of allowed category codes:
+% \cs{l_@@_catcodes_int} and \cs{l_@@_default_catcodes_int} are
+% bitmaps, sums of $4^c$, for all allowed catcodes $c$. The latter is
+% local to each capturing group, and we reset
+% \cs{l_@@_catcodes_int} to that value after each character or
+% class, changing it only when encountering a |\c| escape. The boolean
+% records whether the list of categories of a catcode test has to be
+% inverted: compare |\c[^BE]| and |\c[BE]|.
+% \begin{macrocode}
+\int_new:N \l_@@_catcodes_int
+\int_new:N \l_@@_default_catcodes_int
+\bool_new:N \l_@@_catcodes_bool
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \c_@@_catcode_C_int, \c_@@_catcode_B_int, \c_@@_catcode_E_int,
+% \c_@@_catcode_M_int, \c_@@_catcode_T_int, \c_@@_catcode_P_int,
+% \c_@@_catcode_U_int, \c_@@_catcode_D_int, \c_@@_catcode_S_int,
+% \c_@@_catcode_L_int, \c_@@_catcode_O_int, \c_@@_catcode_A_int
+% }
+% \begin{variable}{\c_@@_all_catcodes_int}
+% Constants: $4^c$ for each category, and the sum of all powers of $4$.
+% \begin{macrocode}
+\int_const:Nn \c_@@_catcode_C_int { "1 }
+\int_const:Nn \c_@@_catcode_B_int { "4 }
+\int_const:Nn \c_@@_catcode_E_int { "10 }
+\int_const:Nn \c_@@_catcode_M_int { "40 }
+\int_const:Nn \c_@@_catcode_T_int { "100 }
+\int_const:Nn \c_@@_catcode_P_int { "1000 }
+\int_const:Nn \c_@@_catcode_U_int { "4000 }
+\int_const:Nn \c_@@_catcode_D_int { "10000 }
+\int_const:Nn \c_@@_catcode_S_int { "100000 }
+\int_const:Nn \c_@@_catcode_L_int { "400000 }
+\int_const:Nn \c_@@_catcode_O_int { "1000000 }
+\int_const:Nn \c_@@_catcode_A_int { "4000000 }
+\int_const:Nn \c_@@_all_catcodes_int { "5515155 }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_internal_regex}
+% The compilation step stores its result in this variable.
+% \begin{macrocode}
+\cs_new_eq:NN \l_@@_internal_regex \c_@@_no_match_regex
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_show_prefix_seq}
+% This sequence holds the prefix that makes up the line displayed to
+% the user. The various items must be removed from the right, which is
+% tricky with a token list, hence we use a sequence.
+% \begin{macrocode}
+\seq_new:N \l_@@_show_prefix_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_show_lines_int}
+% A hack. To know whether a given class has a single item in it or
+% not, we count the number of lines when showing the class.
+% \begin{macrocode}
+\int_new:N \l_@@_show_lines_int
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Generic helpers used when compiling}
+%
+% \begin{macro}{\@@_two_if_eq:NNNNTF}
+% Used to compare pairs of things like \cs{@@_compile_special:N} |?|
+% together. It's often inconvenient to get the catcodes of the
+% character to match so we just compare the character code.
+% Besides, the expanding behaviour of \cs{if:w} is very useful as that
+% means we can use \cs{c_left_brace_str} and the like.
+% \begin{macrocode}
+\cs_new:Npn \@@_two_if_eq:NNNNTF #1#2#3#4
+ {
+ \if_meaning:w #1 #3
+ \if:w #2 #4
+ \exp_after:wN \exp_after:wN \exp_after:wN \use_ii:nnn
+ \fi:
+ \fi:
+ \use_ii:nn
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_get_digits:NTFw}
+% \begin{macro}[rEXP]{\@@_get_digits_loop:w}
+% If followed by some raw digits, collect them one by one in the
+% integer variable |#1|, and take the \texttt{true} branch. Otherwise,
+% take the \texttt{false} branch.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_get_digits:NTFw #1#2#3#4#5
+ {
+ \@@_if_raw_digit:NNTF #4 #5
+ { #1 = #5 \@@_get_digits_loop:nw {#2} }
+ { #3 #4 #5 }
+ }
+\cs_new:Npn \@@_get_digits_loop:nw #1#2#3
+ {
+ \@@_if_raw_digit:NNTF #2 #3
+ { #3 \@@_get_digits_loop:nw {#1} }
+ { \scan_stop: #1 #2 #3 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_if_raw_digit:NNTF}
+% Test used when grabbing digits for the |{m,n}| quantifier.
+% It only accepts non-escaped digits.
+% \begin{macrocode}
+\cs_new:Npn \@@_if_raw_digit:NNTF #1#2
+ {
+ \if_meaning:w \@@_compile_raw:N #1
+ \if_int_compare:w \c_one_int < 1 #2 \exp_stop_f:
+ \exp_after:wN \exp_after:wN \exp_after:wN \use_ii:nnn
+ \fi:
+ \fi:
+ \use_ii:nn
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Mode}
+% \label{sec:regex-modes}
+%
+% When compiling the \textsc{nfa} corresponding to a given regex string,
+% we can be in ten distinct modes, which we label by some magic numbers:
+% \begin{itemize}
+% \item[-6] |[\c{...}]| control sequence in a class,
+% \item[-2] |\c{...}| control sequence,
+% \item[0] |...| outer,
+% \item[2] |\c...| catcode test,
+% \item[6] |[\c...]| catcode test in a class,
+% \item[-63] |[\c{[...]}]| class inside mode $-6$,
+% \item[-23] |\c{[...]}| class inside mode $-2$,
+% \item[3] |[...]| class inside mode $0$,
+% \item[23] |\c[...]| class inside mode $2$,
+% \item[63] |[\c[...]]| class inside mode $6$.
+% \end{itemize}
+% This list is exhaustive, because |\c| escape sequences cannot be
+% nested, and character classes cannot be nested directly. The choice of
+% numbers is such as to optimize the most useful tests, and make
+% transitions from one mode to another as simple as possible.
+% \begin{itemize}
+% \item Even modes mean that we are not directly in a character class.
+% In this case, a left bracket appends $3$ to the mode. In a
+% character class, a right bracket changes the mode as $m\to
+% (m-15)/13$, truncated.
+% \item Grouping, assertion, and anchors are allowed in non-positive
+% even modes ($0$, $-2$, $-6$), and do not change the
+% mode. Otherwise, they trigger an error.
+% \item A left bracket is special in even modes, appending $3$ to the
+% mode; in those modes, quantifiers and the dot are recognized, and
+% the right bracket is normal. In odd modes (within classes), the
+% left bracket is normal, but the right bracket ends the class,
+% changing the mode from $m$ to $(m-15)/13$, truncated; also, ranges
+% are recognized.
+% \item In non-negative modes, left and right braces are normal. In
+% negative modes, however, left braces trigger a warning; right
+% braces end the control sequence, going from $-2$ to $0$ or $-6$ to
+% $3$, with error recovery for odd modes.
+% \item Properties (such as the |\d| character class) can appear in
+% any mode.
+% \end{itemize}
+%
+% \begin{macro}[EXP]{\@@_if_in_class:TF}
+% Test whether we are directly in a character class (at the innermost
+% level of nesting). There, many escape sequences are not recognized,
+% and special characters are normal. Also, for every raw character, we
+% must look ahead for a possible raw dash.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_if_in_class: { TF }
+ {
+ \if_int_odd:w \l_@@_mode_int
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_if_in_cs:TF}
+% Right braces are special only directly inside control sequences (at
+% the inner-most level of nesting, not counting groups).
+% \begin{macrocode}
+\cs_new:Npn \@@_if_in_cs:TF
+ {
+ \if_int_odd:w \l_@@_mode_int
+ \else:
+ \if_int_compare:w \l_@@_mode_int < \c_@@_outer_mode_int
+ \exp_after:wN \exp_after:wN \exp_after:wN \use_ii:nnn
+ \fi:
+ \fi:
+ \use_ii:nn
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_if_in_class_or_catcode:TF}
+% Assertions are only allowed in modes $0$, $-2$, and $-6$,
+% \emph{i.e.}, even, non-positive modes.
+% \begin{macrocode}
+\cs_new:Npn \@@_if_in_class_or_catcode:TF
+ {
+ \if_int_odd:w \l_@@_mode_int
+ \else:
+ \if_int_compare:w \l_@@_mode_int > \c_@@_outer_mode_int
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \use_iii:nnn
+ \fi:
+ \fi:
+ \use_i:nn
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_if_within_catcode:TF}
+% This test takes the true branch if we are in a catcode test, either
+% immediately following it (modes $2$ and $6$) or in a class on which
+% it applies (modes $23$ and $63$). This is used to tweak how left
+% brackets behave in modes $2$ and $6$.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_if_within_catcode: { TF }
+ {
+ \if_int_compare:w \l_@@_mode_int > \c_@@_outer_mode_int
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_chk_c_allowed:T}
+% The |\c| escape sequence is only allowed in modes $0$ and $3$,
+% \emph{i.e.}, not within any other |\c| escape sequence.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_chk_c_allowed:T
+ {
+ \if_int_compare:w \l_@@_mode_int = \c_@@_outer_mode_int
+ \else:
+ \if_int_compare:w \l_@@_mode_int = \c_@@_class_mode_int
+ \else:
+ \msg_error:nn { regex } { c-bad-mode }
+ \exp_after:wN \use_i:nnn
+ \fi:
+ \fi:
+ \use:n
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_mode_quit_c:}
+% This function changes the mode as it is needed just after a catcode
+% test.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_mode_quit_c:
+ {
+ \if_int_compare:w \l_@@_mode_int = \c_@@_catcode_mode_int
+ \int_set_eq:NN \l_@@_mode_int \c_@@_outer_mode_int
+ \else:
+ \if_int_compare:w \l_@@_mode_int =
+ \c_@@_catcode_in_class_mode_int
+ \int_set_eq:NN \l_@@_mode_int \c_@@_class_mode_int
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Framework}
+%
+% \begin{macro}{\@@_compile:w, \@@_compile_end:}
+% Used when compiling a user regex or a regex for the |\c{...}| escape
+% sequence within another regex. Start building a token list within a
+% group (with \texttt{e}-expansion at the outset), and set a few
+% variables (group level, catcodes), then start the first branch. At
+% the end, make sure there are no dangling classes nor groups, close
+% the last branch: we are done building \cs{l_@@_internal_regex}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile:w
+ {
+ \group_begin:
+ \tl_build_begin:N \l_@@_build_tl
+ \int_zero:N \l_@@_group_level_int
+ \int_set_eq:NN \l_@@_default_catcodes_int
+ \c_@@_all_catcodes_int
+ \int_set_eq:NN \l_@@_catcodes_int \l_@@_default_catcodes_int
+ \cs_set:Npn \@@_item_equal:n { \@@_item_caseful_equal:n }
+ \cs_set:Npn \@@_item_range:nn { \@@_item_caseful_range:nn }
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \@@_branch:n { \if_false: } \fi: }
+ }
+\cs_new_protected:Npn \@@_compile_end:
+ {
+ \@@_if_in_class:TF
+ {
+ \msg_error:nn { regex } { missing-rbrack }
+ \use:c { @@_compile_]: }
+ \prg_do_nothing: \prg_do_nothing:
+ }
+ { }
+ \if_int_compare:w \l_@@_group_level_int > \c_zero_int
+ \msg_error:nne { regex } { missing-rparen }
+ { \int_use:N \l_@@_group_level_int }
+ \prg_replicate:nn
+ \l_@@_group_level_int
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl
+ {
+ \if_false: { \fi: }
+ \if_false: { \fi: } { 1 } { 0 } \c_true_bool
+ }
+ \tl_build_end:N \l_@@_build_tl
+ \exp_args:NNNo
+ \group_end:
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \l_@@_build_tl }
+ }
+ \fi:
+ \tl_build_put_right:Nn \l_@@_build_tl { \if_false: { \fi: } }
+ \tl_build_end:N \l_@@_build_tl
+ \exp_args:NNNe
+ \group_end:
+ \tl_set:Nn \l_@@_internal_regex { \l_@@_build_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile:n}
+% The compilation is done between \cs{@@_compile:w} and
+% \cs{@@_compile_end:}, starting in mode~$0$. Then
+% \cs{@@_escape_use:nnnn} distinguishes special characters, escaped
+% alphanumerics, and raw characters, interpreting |\a|, |\x| and other
+% sequences. The $4$ trailing \cs{prg_do_nothing:} are needed because
+% some functions defined later look up to $4$ tokens ahead. Before
+% ending, make sure that any |\c{...}| is properly closed. No need to
+% check that brackets are closed properly since \cs{@@_compile_end:}
+% does that. However, catch the case of a trailing |\cL|
+% construction.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile:n #1
+ {
+ \@@_compile:w
+ \@@_standard_escapechar:
+ \int_set_eq:NN \l_@@_mode_int \c_@@_outer_mode_int
+ \@@_escape_use:nnnn
+ {
+ \@@_char_if_special:NTF ##1
+ \@@_compile_special:N \@@_compile_raw:N ##1
+ }
+ {
+ \@@_char_if_alphanumeric:NTF ##1
+ \@@_compile_escaped:N \@@_compile_raw:N ##1
+ }
+ { \@@_compile_raw:N ##1 }
+ { #1 }
+ \prg_do_nothing: \prg_do_nothing:
+ \prg_do_nothing: \prg_do_nothing:
+ \int_compare:nNnT \l_@@_mode_int = \c_@@_catcode_mode_int
+ { \msg_error:nn { regex } { c-trailing } }
+ \int_compare:nNnT \l_@@_mode_int < \c_@@_outer_mode_int
+ {
+ \msg_error:nn { regex } { c-missing-rbrace }
+ \@@_compile_end_cs:
+ \prg_do_nothing: \prg_do_nothing:
+ \prg_do_nothing: \prg_do_nothing:
+ }
+ \@@_compile_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_use:n}
+% Use a regex, regardless of whether it is given as a string (in which
+% case we need to compile) or as a regex variable. This is used for
+% \cs{regex_match_case:nn} and related functions to allow a mixture of
+% explicit regex and regex variables.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_use:n #1
+ {
+ \tl_if_single_token:nT {#1}
+ {
+ \exp_after:wN \@@_compile_use_aux:w
+ \token_to_meaning:N #1 ~ \q_@@_nil
+ }
+ \@@_compile:n {#1} \l_@@_internal_regex
+ }
+\cs_new_protected:Npn \@@_compile_use_aux:w #1 ~ #2 \q_@@_nil
+ {
+ \str_if_eq:nnT { #1 ~ } { macro:->\@@_branch:n }
+ { \use_ii:nnn }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_escaped:N, \@@_compile_special:N}
+% If the special character or escaped alphanumeric has a particular
+% meaning in regexes, the corresponding function is used. Otherwise,
+% it is interpreted as a raw character. We distinguish special
+% characters from escaped alphanumeric characters because they behave
+% differently when appearing as an end-point of a range.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_special:N #1
+ {
+ \cs_if_exist_use:cF { @@_compile_#1: }
+ { \@@_compile_raw:N #1 }
+ }
+\cs_new_protected:Npn \@@_compile_escaped:N #1
+ {
+ \cs_if_exist_use:cF { @@_compile_/#1: }
+ { \@@_compile_raw:N #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_one:n}
+% This is used after finding one \enquote{test}, such as |\d|, or a
+% raw character. If that followed a catcode test (\emph{e.g.}, |\cL|),
+% then restore the mode. If we are not in a class, then the test is
+% \enquote{standalone}, and we need to add \cs{@@_class:NnnnN} and
+% search for quantifiers. In any case, insert the test, possibly
+% together with a catcode test if appropriate.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_one:n #1
+ {
+ \@@_mode_quit_c:
+ \@@_if_in_class:TF { }
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \@@_class:NnnnN \c_true_bool { \if_false: } \fi: }
+ }
+ \tl_build_put_right:Ne \l_@@_build_tl
+ {
+ \if_int_compare:w \l_@@_catcodes_int <
+ \c_@@_all_catcodes_int
+ \@@_item_catcode:nT { \int_use:N \l_@@_catcodes_int }
+ { \exp_not:N \exp_not:n {#1} }
+ \else:
+ \exp_not:N \exp_not:n {#1}
+ \fi:
+ }
+ \int_set_eq:NN \l_@@_catcodes_int \l_@@_default_catcodes_int
+ \@@_if_in_class:TF { } { \@@_compile_quantifier:w }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_compile_abort_tokens:n, \@@_compile_abort_tokens:e}
+% This function places the collected tokens back in the input stream,
+% each as a raw character. Spaces are not preserved.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_abort_tokens:n #1
+ {
+ \use:e
+ {
+ \exp_args:No \tl_map_function:nN { \tl_to_str:n {#1} }
+ \@@_compile_raw:N
+ }
+ }
+\cs_generate_variant:Nn \@@_compile_abort_tokens:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Quantifiers}
+%
+% \begin{macro}{\@@_compile_if_quantifier:TFw}
+% This looks ahead and checks whether there are any quantifier
+% (special character equal to either of \texttt{?+*\{}). This is
+% useful for the |\u| and |\ur| escape sequences.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_if_quantifier:TFw #1#2#3#4
+ {
+ \token_if_eq_meaning:NNTF #3 \@@_compile_special:N
+ { \cs_if_exist:cTF { @@_compile_quantifier_#4:w } }
+ { \use_ii:nn }
+ {#1} {#2} #3 #4
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_quantifier:w}
+% This looks ahead and finds any quantifier (special character equal
+% to either of \texttt{?+*\{}).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_quantifier:w #1#2
+ {
+ \token_if_eq_meaning:NNTF #1 \@@_compile_special:N
+ {
+ \cs_if_exist_use:cF { @@_compile_quantifier_#2:w }
+ { \@@_compile_quantifier_none: #1 #2 }
+ }
+ { \@@_compile_quantifier_none: #1 #2 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_quantifier_none:}
+% \begin{macro}{\@@_compile_quantifier_abort:eNN}
+% Those functions are called whenever there is no quantifier, or a
+% braced construction is invalid (equivalent to no quantifier, and
+% whatever characters were grabbed are left raw).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_quantifier_none:
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \if_false: { \fi: } { 1 } { 0 } \c_false_bool }
+ }
+\cs_new_protected:Npn \@@_compile_quantifier_abort:eNN #1#2#3
+ {
+ \@@_compile_quantifier_none:
+ \msg_warning:nnee { regex } { invalid-quantifier } {#1} {#3}
+ \@@_compile_abort_tokens:e {#1}
+ #2 #3
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_quantifier_lazyness:nnNN}
+% Once the \enquote{main} quantifier (\texttt{?}, \texttt{*},
+% \texttt{+} or a braced construction) is found, we check whether it
+% is lazy (followed by a question mark). We then add to the compiled
+% regex a closing brace (ending \cs{@@_class:NnnnN} and friends),
+% the start-point of the range, its end-point, and a boolean,
+% \texttt{true} for lazy and \texttt{false} for greedy operators.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_quantifier_lazyness:nnNN #1#2#3#4
+ {
+ \@@_two_if_eq:NNNNTF #3 #4 \@@_compile_special:N ?
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \if_false: { \fi: } { #1 } { #2 } \c_true_bool }
+ }
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \if_false: { \fi: } { #1 } { #2 } \c_false_bool }
+ #3 #4
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_compile_quantifier_?:w,
+% \@@_compile_quantifier_*:w,
+% \@@_compile_quantifier_+:w
+% }
+% For each \enquote{basic} quantifier, |?|, |*|, |+|, feed the correct
+% arguments to \cs{@@_compile_quantifier_lazyness:nnNN}, $-1$ means
+% that there is no upper bound on the number of repetitions.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_quantifier_?:w }
+ { \@@_compile_quantifier_lazyness:nnNN { 0 } { 1 } }
+\cs_new_protected:cpn { @@_compile_quantifier_*:w }
+ { \@@_compile_quantifier_lazyness:nnNN { 0 } { -1 } }
+\cs_new_protected:cpn { @@_compile_quantifier_+:w }
+ { \@@_compile_quantifier_lazyness:nnNN { 1 } { -1 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}+\@@_compile_quantifier_{:w+ ^^A}
+% \begin{macro}
+% {
+% \@@_compile_quantifier_braced_auxi:w,
+% \@@_compile_quantifier_braced_auxii:w,
+% \@@_compile_quantifier_braced_auxiii:w,
+% }
+% Three possible syntaxes: \texttt{\{\meta{int}\}},
+% \texttt{\{\meta{int},\}}, or \texttt{\{\meta{int},\meta{int}\}}. Any
+% other syntax causes us to abort and put whatever we collected back
+% in the input stream, as \texttt{raw} characters, including the
+% opening brace. Grab a number into \cs{l_@@_internal_a_int}. If
+% the number is followed by a right brace, the range is $[a,a]$. If
+% followed by a comma, grab one more number, and call the \texttt{_ii}
+% or \texttt{_iii} auxiliary. Those auxiliaries check for a closing
+% brace, leading to the range $[a,\infty]$ or $[a,b]$, encoded as
+% $\{a\}\{-1\}$ and $\{a\}\{b-a\}$.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_quantifier_ \c_left_brace_str :w }
+ {
+ \@@_get_digits:NTFw \l_@@_internal_a_int
+ { \@@_compile_quantifier_braced_auxi:w }
+ { \@@_compile_quantifier_abort:eNN { \c_left_brace_str } }
+ }
+\cs_new_protected:Npn \@@_compile_quantifier_braced_auxi:w #1#2
+ {
+ \str_case_e:nnF { #1 #2 }
+ {
+ { \@@_compile_special:N \c_right_brace_str }
+ {
+ \exp_args:No \@@_compile_quantifier_lazyness:nnNN
+ { \int_use:N \l_@@_internal_a_int } 0
+ }
+ { \@@_compile_special:N , }
+ {
+ \@@_get_digits:NTFw \l_@@_internal_b_int
+ { \@@_compile_quantifier_braced_auxiii:w }
+ { \@@_compile_quantifier_braced_auxii:w }
+ }
+ }
+ {
+ \@@_compile_quantifier_abort:eNN
+ { \c_left_brace_str \int_use:N \l_@@_internal_a_int }
+ #1 #2
+ }
+ }
+\cs_new_protected:Npn \@@_compile_quantifier_braced_auxii:w #1#2
+ {
+ \@@_two_if_eq:NNNNTF #1 #2 \@@_compile_special:N \c_right_brace_str
+ {
+ \exp_args:No \@@_compile_quantifier_lazyness:nnNN
+ { \int_use:N \l_@@_internal_a_int } { -1 }
+ }
+ {
+ \@@_compile_quantifier_abort:eNN
+ { \c_left_brace_str \int_use:N \l_@@_internal_a_int , }
+ #1 #2
+ }
+ }
+\cs_new_protected:Npn \@@_compile_quantifier_braced_auxiii:w #1#2
+ {
+ \@@_two_if_eq:NNNNTF #1 #2 \@@_compile_special:N \c_right_brace_str
+ {
+ \if_int_compare:w \l_@@_internal_a_int >
+ \l_@@_internal_b_int
+ \msg_error:nnee { regex } { backwards-quantifier }
+ { \int_use:N \l_@@_internal_a_int }
+ { \int_use:N \l_@@_internal_b_int }
+ \int_zero:N \l_@@_internal_b_int
+ \else:
+ \int_sub:Nn \l_@@_internal_b_int \l_@@_internal_a_int
+ \fi:
+ \exp_args:Noo \@@_compile_quantifier_lazyness:nnNN
+ { \int_use:N \l_@@_internal_a_int }
+ { \int_use:N \l_@@_internal_b_int }
+ }
+ {
+ \@@_compile_quantifier_abort:eNN
+ {
+ \c_left_brace_str
+ \int_use:N \l_@@_internal_a_int ,
+ \int_use:N \l_@@_internal_b_int
+ }
+ #1 #2
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Raw characters}
+%
+% \begin{macro}{\@@_compile_raw_error:N}
+% Within character classes, and following catcode tests, some escaped
+% alphanumeric sequences such as |\b| do not have any meaning. They
+% are replaced by a raw character, after spitting out an error.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_raw_error:N #1
+ {
+ \msg_error:nne { regex } { bad-escape } {#1}
+ \@@_compile_raw:N #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_raw:N}
+% If we are in a character class and the next character is an
+% unescaped dash, this denotes a range. Otherwise, the current
+% character |#1| matches itself.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_raw:N #1#2#3
+ {
+ \@@_if_in_class:TF
+ {
+ \@@_two_if_eq:NNNNTF #2 #3 \@@_compile_special:N -
+ { \@@_compile_range:Nw #1 }
+ {
+ \@@_compile_one:n
+ { \@@_item_equal:n { \int_value:w `#1 } }
+ #2 #3
+ }
+ }
+ {
+ \@@_compile_one:n
+ { \@@_item_equal:n { \int_value:w `#1 } }
+ #2 #3
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_range:Nw, \@@_if_end_range:NNTF}
+% We have just read a raw character followed by a dash; this should be
+% followed by an end-point for the range. Valid end-points are: any
+% raw character; any special character, except a right bracket. In
+% particular, escaped characters are forbidden.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_if_end_range:NNTF #1#2
+ {
+ \if_meaning:w \@@_compile_raw:N #1
+ \else:
+ \if_meaning:w \@@_compile_special:N #1
+ \if_charcode:w ] #2
+ \use_i:nn
+ \fi:
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \use_iii:nnn
+ \fi:
+ \fi:
+ \use_i:nn
+ }
+\cs_new_protected:Npn \@@_compile_range:Nw #1#2#3
+ {
+ \@@_if_end_range:NNTF #2 #3
+ {
+ \if_int_compare:w `#1 > `#3 \exp_stop_f:
+ \msg_error:nnee { regex } { range-backwards } {#1} {#3}
+ \else:
+ \tl_build_put_right:Ne \l_@@_build_tl
+ {
+ \if_int_compare:w `#1 = `#3 \exp_stop_f:
+ \@@_item_equal:n
+ \else:
+ \@@_item_range:nn { \int_value:w `#1 }
+ \fi:
+ { \int_value:w `#3 }
+ }
+ \fi:
+ }
+ {
+ \msg_warning:nnee { regex } { range-missing-end }
+ {#1} { \c_backslash_str #3 }
+ \tl_build_put_right:Ne \l_@@_build_tl
+ {
+ \@@_item_equal:n { \int_value:w `#1 \exp_stop_f: }
+ \@@_item_equal:n { \int_value:w `- \exp_stop_f: }
+ }
+ #2#3
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Character properties}
+%
+% \begin{macro}{\@@_compile_.:, \@@_prop_.:}
+% In a class, the dot has no special meaning. Outside, insert
+% \cs{@@_prop_.:}, which matches any character or control
+% sequence, and refuses $-2$ (end-marker).
+% \begin{macrocode}
+\cs_new_protected:cpe { @@_compile_.: }
+ {
+ \exp_not:N \@@_if_in_class:TF
+ { \@@_compile_raw:N . }
+ { \@@_compile_one:n \exp_not:c { @@_prop_.: } }
+ }
+\cs_new_protected:cpn { @@_prop_.: }
+ {
+ \if_int_compare:w \l_@@_curr_char_int > - 2 \exp_stop_f:
+ \exp_after:wN \@@_break_true:w
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_compile_/d:, \@@_compile_/D:,
+% \@@_compile_/h:, \@@_compile_/H:,
+% \@@_compile_/s:, \@@_compile_/S:,
+% \@@_compile_/v:, \@@_compile_/V:,
+% \@@_compile_/w:, \@@_compile_/W:,
+% \@@_compile_/N:,
+% }
+% The constants \cs{@@_prop_d:}, \emph{etc.} hold
+% a list of tests which match the corresponding character
+% class, and jump to the \cs{@@_break_point:TF} marker.
+% As for a normal character, we check for quantifiers.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1#2
+ {
+ \cs_new_protected:cpe { @@_compile_/#1: }
+ { \@@_compile_one:n \exp_not:c { @@_prop_#1: } }
+ \cs_new_protected:cpe { @@_compile_/#2: }
+ {
+ \@@_compile_one:n
+ { \@@_item_reverse:n { \exp_not:c { @@_prop_#1: } } }
+ }
+ }
+\@@_tmp:w d D
+\@@_tmp:w h H
+\@@_tmp:w s S
+\@@_tmp:w v V
+\@@_tmp:w w W
+\cs_new_protected:cpn { @@_compile_/N: }
+ { \@@_compile_one:n \@@_prop_N: }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Anchoring and simple assertions}
+%
+% \begin{macro}{\@@_compile_anchor_letter:NNN}
+% \begin{macro}{\@@_compile_/A:, \@@_compile_/G:, \@@_compile_/Z:, \@@_compile_/z:, \@@_compile_/b:, \@@_compile_/B:}
+% \begin{macro}+\@@_compile_^:+
+% \begin{macro}+\@@_compile_$:+
+% In modes where assertions are forbidden, anchors such as |\A|
+% produce an error (|\A|~is invalid in classes); otherwise they add an
+% \cs{@@_assertion:Nn} test as appropriate (the only negative
+% assertion is~|\B|). The test functions are defined later. The
+% implementation for
+% |$| and |^| is only different from |\A| etc because these are valid
+% in a class.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_anchor_letter:NNN #1#2#3
+ {
+ \@@_if_in_class_or_catcode:TF { \@@_compile_raw_error:N #1 }
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \@@_assertion:Nn #2 {#3} }
+ }
+ }
+\cs_new_protected:cpn { @@_compile_/A: }
+ { \@@_compile_anchor_letter:NNN A \c_true_bool \@@_A_test: }
+\cs_new_protected:cpn { @@_compile_/G: }
+ { \@@_compile_anchor_letter:NNN G \c_true_bool \@@_G_test: }
+\cs_new_protected:cpn { @@_compile_/Z: }
+ { \@@_compile_anchor_letter:NNN Z \c_true_bool \@@_Z_test: }
+\cs_new_protected:cpn { @@_compile_/z: }
+ { \@@_compile_anchor_letter:NNN z \c_true_bool \@@_Z_test: }
+\cs_new_protected:cpn { @@_compile_/b: }
+ { \@@_compile_anchor_letter:NNN b \c_true_bool \@@_b_test: }
+\cs_new_protected:cpn { @@_compile_/B: }
+ { \@@_compile_anchor_letter:NNN B \c_false_bool \@@_b_test: }
+\cs_set_protected:Npn \@@_tmp:w #1#2
+ {
+ \cs_new_protected:cpn { @@_compile_#1: }
+ {
+ \@@_if_in_class_or_catcode:TF { \@@_compile_raw:N #1 }
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \@@_assertion:Nn \c_true_bool {#2} }
+ }
+ }
+ }
+\exp_args:Ne \@@_tmp:w { \iow_char:N \^ } { \@@_A_test: }
+\exp_args:Ne \@@_tmp:w { \iow_char:N \$ } { \@@_Z_test: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Character classes}
+%
+% \begin{macro}{\@@_compile_]:}
+% Outside a class, right brackets have no meaning. In a class, change
+% the mode ($m\to (m-15)/13$, truncated) to reflect the fact that we
+% are leaving the class. Look for quantifiers, unless we are still in
+% a class after leaving one (the case of |[...\cL[...]...]|).
+% quantifiers.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_]: }
+ {
+ \@@_if_in_class:TF
+ {
+ \if_int_compare:w \l_@@_mode_int >
+ \c_@@_catcode_in_class_mode_int
+ \tl_build_put_right:Nn \l_@@_build_tl { \if_false: { \fi: } }
+ \fi:
+ \tex_advance:D \l_@@_mode_int - 15 \exp_stop_f:
+ \tex_divide:D \l_@@_mode_int 13 \exp_stop_f:
+ \if_int_odd:w \l_@@_mode_int \else:
+ \exp_after:wN \@@_compile_quantifier:w
+ \fi:
+ }
+ { \@@_compile_raw:N ] }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_[:}
+% In a class, left brackets might introduce a \textsc{posix} character
+% class, or mean nothing. Immediately following |\c|\meta{category},
+% we must insert the appropriate catcode test, then parse the class; we
+% pre-expand the catcode as an optimization. Otherwise (modes $0$,
+% $-2$ and $-6$) just parse the class. The mode is updated later.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_[: }
+ {
+ \@@_if_in_class:TF
+ { \@@_compile_class_posix_test:w }
+ {
+ \@@_if_within_catcode:TF
+ {
+ \exp_after:wN \@@_compile_class_catcode:w
+ \int_use:N \l_@@_catcodes_int ;
+ }
+ { \@@_compile_class_normal:w }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_class_normal:w}
+% In the \enquote{normal} case, we insert \cs{@@_class:NnnnN}
+% \meta{boolean} in the compiled code. The \meta{boolean} is true for
+% positive classes, and false for negative classes, characterized by a
+% leading |^|. The auxiliary \cs{@@_compile_class:TFNN} also
+% checks for a leading |]| which has a special meaning.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_class_normal:w
+ {
+ \@@_compile_class:TFNN
+ { \@@_class:NnnnN \c_true_bool }
+ { \@@_class:NnnnN \c_false_bool }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_class_catcode:w}
+% This function is called for a left bracket in modes $2$ or $6$
+% (catcode test, and catcode test within a class). In mode $2$ the
+% whole construction needs to be put in a class (like single
+% character). Then determine if the class is positive or negative,
+% inserting \cs{@@_item_catcode:nT} or the \texttt{reverse} variant
+% as appropriate, each with the current catcodes bitmap |#1| as an
+% argument, and reset the catcodes.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_class_catcode:w #1;
+ {
+ \if_int_compare:w \l_@@_mode_int = \c_@@_catcode_mode_int
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \@@_class:NnnnN \c_true_bool { \if_false: } \fi: }
+ \fi:
+ \int_set_eq:NN \l_@@_catcodes_int \l_@@_default_catcodes_int
+ \@@_compile_class:TFNN
+ { \@@_item_catcode:nT {#1} }
+ { \@@_item_catcode_reverse:nT {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_compile_class:TFNN, \@@_compile_class:NN}
+% If the first character is |^|, then the class is negative (use
+% |#2|), otherwise it is positive (use |#1|). If the next character
+% is a right bracket, then it should be changed to a raw one.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_class:TFNN #1#2#3#4
+ {
+ \l_@@_mode_int = \int_value:w \l_@@_mode_int 3 \exp_stop_f:
+ \@@_two_if_eq:NNNNTF #3 #4 \@@_compile_special:N ^
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl { #2 { \if_false: } \fi: }
+ \@@_compile_class:NN
+ }
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl { #1 { \if_false: } \fi: }
+ \@@_compile_class:NN #3 #4
+ }
+ }
+\cs_new_protected:Npn \@@_compile_class:NN #1#2
+ {
+ \token_if_eq_charcode:NNTF #2 ]
+ { \@@_compile_raw:N #2 }
+ { #1 #2 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_compile_class_posix_test:w,
+% \@@_compile_class_posix:NNNNw,
+% \@@_compile_class_posix_loop:w,
+% \@@_compile_class_posix_end:w
+% }
+% Here we check for a syntax such as |[:alpha:]|. We also detect |[=|
+% and |[.| which have a meaning in \textsc{posix} regular expressions,
+% but are not implemented in \pkg{l3regex}. In case we see |[:|, grab
+% raw characters until hopefully reaching |:]|. If that's missing, or
+% the \textsc{posix} class is unknown, abort. If all is right, add the
+% test to the current class, with an extra \cs{@@_item_reverse:n}
+% for negative classes (we make sure to wrap its argument in braces
+% otherwise \cs{regex_show:N} would not recognize the regex as valid).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_class_posix_test:w #1#2
+ {
+ \token_if_eq_meaning:NNT \@@_compile_special:N #1
+ {
+ \str_case:nn { #2 }
+ {
+ : { \@@_compile_class_posix:NNNNw }
+ = {
+ \msg_warning:nne { regex }
+ { posix-unsupported } { = }
+ }
+ . {
+ \msg_warning:nne { regex }
+ { posix-unsupported } { . }
+ }
+ }
+ }
+ \@@_compile_raw:N [ #1 #2
+ }
+\cs_new_protected:Npn \@@_compile_class_posix:NNNNw #1#2#3#4#5#6
+ {
+ \@@_two_if_eq:NNNNTF #5 #6 \@@_compile_special:N ^
+ {
+ \bool_set_false:N \l_@@_internal_bool
+ \__kernel_tl_set:Nx \l_@@_internal_a_tl { \if_false: } \fi:
+ \@@_compile_class_posix_loop:w
+ }
+ {
+ \bool_set_true:N \l_@@_internal_bool
+ \__kernel_tl_set:Nx \l_@@_internal_a_tl { \if_false: } \fi:
+ \@@_compile_class_posix_loop:w #5 #6
+ }
+ }
+\cs_new:Npn \@@_compile_class_posix_loop:w #1#2
+ {
+ \token_if_eq_meaning:NNTF \@@_compile_raw:N #1
+ { #2 \@@_compile_class_posix_loop:w }
+ { \if_false: { \fi: } \@@_compile_class_posix_end:w #1 #2 }
+ }
+\cs_new_protected:Npn \@@_compile_class_posix_end:w #1#2#3#4
+ {
+ \@@_two_if_eq:NNNNTF #1 #2 \@@_compile_special:N :
+ { \@@_two_if_eq:NNNNTF #3 #4 \@@_compile_special:N ] }
+ { \use_ii:nn }
+ {
+ \cs_if_exist:cTF { @@_posix_ \l_@@_internal_a_tl : }
+ {
+ \@@_compile_one:n
+ {
+ \bool_if:NTF \l_@@_internal_bool \use:n \@@_item_reverse:n
+ { \exp_not:c { @@_posix_ \l_@@_internal_a_tl : } }
+ }
+ }
+ {
+ \msg_warning:nne { regex } { posix-unknown }
+ { \l_@@_internal_a_tl }
+ \@@_compile_abort_tokens:e
+ {
+ [: \bool_if:NF \l_@@_internal_bool { ^ }
+ \l_@@_internal_a_tl :]
+ }
+ }
+ }
+ {
+ \msg_error:nnee { regex } { posix-missing-close }
+ { [: \l_@@_internal_a_tl } { #2 #4 }
+ \@@_compile_abort_tokens:e { [: \l_@@_internal_a_tl }
+ #1 #2 #3 #4
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Groups and alternations}
+%
+% \begin{macro}{\@@_compile_group_begin:N, \@@_compile_group_end:}
+% The contents of a regex group are turned into compiled code in
+% \cs{l_@@_build_tl}, which ends up with items of the form
+% \cs{@@_branch:n} \Arg{concatenation}. This construction is done
+% using \cs[no-index]{tl_build_\ldots{}} functions within a \TeX{} group, which automatically
+% makes sure that options (case-sensitivity and default catcode) are
+% reset at the end of the group. The argument |#1| is
+% \cs{@@_group:nnnN} or a variant thereof. A small subtlety to
+% support |\cL(abc)| as a shorthand for |(\cLa\cLb\cLc)|: exit any
+% pending catcode test, save the category code at the start of the
+% group as the default catcode for that group, and make sure that the
+% catcode is restored to the default outside the group.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_group_begin:N #1
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl { #1 { \if_false: } \fi: }
+ \@@_mode_quit_c:
+ \group_begin:
+ \tl_build_begin:N \l_@@_build_tl
+ \int_set_eq:NN \l_@@_default_catcodes_int \l_@@_catcodes_int
+ \int_incr:N \l_@@_group_level_int
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \@@_branch:n { \if_false: } \fi: }
+ }
+\cs_new_protected:Npn \@@_compile_group_end:
+ {
+ \if_int_compare:w \l_@@_group_level_int > \c_zero_int
+ \tl_build_put_right:Nn \l_@@_build_tl { \if_false: { \fi: } }
+ \tl_build_end:N \l_@@_build_tl
+ \exp_args:NNNe
+ \group_end:
+ \tl_build_put_right:Nn \l_@@_build_tl { \l_@@_build_tl }
+ \int_set_eq:NN \l_@@_catcodes_int \l_@@_default_catcodes_int
+ \exp_after:wN \@@_compile_quantifier:w
+ \else:
+ \msg_warning:nn { regex } { extra-rparen }
+ \exp_after:wN \@@_compile_raw:N \exp_after:wN )
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_(:}
+% In a class, parentheses are not special. In a catcode test inside a
+% class, a left parenthesis gives an error, to catch |[a\cL(bcd)e]|.
+% Otherwise check for a |?|, denoting special groups, and run the code
+% for the corresponding special group.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_(: }
+ {
+ \@@_if_in_class:TF { \@@_compile_raw:N ( }
+ {
+ \if_int_compare:w \l_@@_mode_int =
+ \c_@@_catcode_in_class_mode_int
+ \msg_error:nn { regex } { c-lparen-in-class }
+ \exp_after:wN \@@_compile_raw:N \exp_after:wN (
+ \else:
+ \exp_after:wN \@@_compile_lparen:w
+ \fi:
+ }
+ }
+\cs_new_protected:Npn \@@_compile_lparen:w #1#2#3#4
+ {
+ \@@_two_if_eq:NNNNTF #1 #2 \@@_compile_special:N ?
+ {
+ \cs_if_exist_use:cF
+ { @@_compile_special_group_\token_to_str:N #4 :w }
+ {
+ \msg_warning:nne { regex } { special-group-unknown }
+ { (? #4 }
+ \@@_compile_group_begin:N \@@_group:nnnN
+ \@@_compile_raw:N ? #3 #4
+ }
+ }
+ {
+ \@@_compile_group_begin:N \@@_group:nnnN
+ #1 #2 #3 #4
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}+\@@_compile_|:+
+% In a class, the pipe is not special. Otherwise, end the current
+% branch and open another one.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_|: }
+ {
+ \@@_if_in_class:TF { \@@_compile_raw:N | }
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \if_false: { \fi: } \@@_branch:n { \if_false: } \fi: }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_):}
+% Within a class, parentheses are not special. Outside, close a group.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_): }
+ {
+ \@@_if_in_class:TF { \@@_compile_raw:N ) }
+ { \@@_compile_group_end: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_special_group_::w}
+% \begin{macro}+\@@_compile_special_group_|:w+
+% Non-capturing, and resetting groups are easy to take care of during
+% compilation; for those groups, the harder parts come when building.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_special_group_::w }
+ { \@@_compile_group_begin:N \@@_group_no_capture:nnnN }
+\cs_new_protected:cpn { @@_compile_special_group_|:w }
+ { \@@_compile_group_begin:N \@@_group_resetting:nnnN }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_compile_special_group_i:w, \@@_compile_special_group_-:w}
+% The match can be made case-insensitive by setting the option with
+% \texttt{(?i)}; the original behaviour is restored by \texttt{(?-i)}.
+% This is the only supported option.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_special_group_i:w #1#2
+ {
+ \@@_two_if_eq:NNNNTF #1 #2 \@@_compile_special:N )
+ {
+ \cs_set:Npn \@@_item_equal:n
+ { \@@_item_caseless_equal:n }
+ \cs_set:Npn \@@_item_range:nn
+ { \@@_item_caseless_range:nn }
+ }
+ {
+ \msg_warning:nne { regex } { unknown-option } { (?i #2 }
+ \@@_compile_raw:N (
+ \@@_compile_raw:N ?
+ \@@_compile_raw:N i
+ #1 #2
+ }
+ }
+\cs_new_protected:cpn { @@_compile_special_group_-:w } #1#2#3#4
+ {
+ \@@_two_if_eq:NNNNTF #1 #2 \@@_compile_raw:N i
+ { \@@_two_if_eq:NNNNTF #3 #4 \@@_compile_special:N ) }
+ { \use_ii:nn }
+ {
+ \cs_set:Npn \@@_item_equal:n
+ { \@@_item_caseful_equal:n }
+ \cs_set:Npn \@@_item_range:nn
+ { \@@_item_caseful_range:nn }
+ }
+ {
+ \msg_warning:nne { regex } { unknown-option } { (?-#2#4 }
+ \@@_compile_raw:N (
+ \@@_compile_raw:N ?
+ \@@_compile_raw:N -
+ #1 #2 #3 #4
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Catcodes and csnames}
+%
+% \begin{macro}{\@@_compile_/c:, \@@_compile_c_test:NN}
+% The |\c| escape sequence can be followed by a capital letter
+% representing a character category, by a left bracket which starts a
+% list of categories, or by a brace group holding a regular expression
+% for a control sequence name. Otherwise, raise an error.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_/c: }
+ { \@@_chk_c_allowed:T { \@@_compile_c_test:NN } }
+\cs_new_protected:Npn \@@_compile_c_test:NN #1#2
+ {
+ \token_if_eq_meaning:NNTF #1 \@@_compile_raw:N
+ {
+ \int_if_exist:cTF { c_@@_catcode_#2_int }
+ {
+ \int_set_eq:Nc \l_@@_catcodes_int
+ { c_@@_catcode_#2_int }
+ \l_@@_mode_int
+ = \if_case:w \l_@@_mode_int
+ \c_@@_catcode_mode_int
+ \else:
+ \c_@@_catcode_in_class_mode_int
+ \fi:
+ \token_if_eq_charcode:NNT C #2 { \@@_compile_c_C:NN }
+ }
+ }
+ { \cs_if_exist_use:cF { @@_compile_c_#2:w } }
+ {
+ \msg_error:nne { regex } { c-missing-category } {#2}
+ #1 #2
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_c_C:NN}
+% If |\cC| is not followed by |.| or |(...)| then complain because
+% that construction cannot match anything, except in cases like
+% |\cC[\c{...}]|, where it has no effect.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_c_C:NN #1#2
+ {
+ \token_if_eq_meaning:NNTF #1 \@@_compile_special:N
+ {
+ \token_if_eq_charcode:NNTF #2 .
+ { \use_none:n }
+ { \token_if_eq_charcode:NNF #2 ( } % )
+ }
+ { \use:n }
+ { \msg_error:nnn { regex } { c-C-invalid } {#2} }
+ #1 #2
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_compile_c_[:w,
+% \@@_compile_c_lbrack_loop:NN,
+% \@@_compile_c_lbrack_add:N,
+% \@@_compile_c_lbrack_end:,
+% }
+% When encountering |\c[|, the task is to collect uppercase letters
+% representing character categories. First check for |^| which negates
+% the list of category codes.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_c_[:w } #1#2
+ {
+ \l_@@_mode_int
+ = \if_case:w \l_@@_mode_int
+ \c_@@_catcode_mode_int
+ \else:
+ \c_@@_catcode_in_class_mode_int
+ \fi:
+ \int_zero:N \l_@@_catcodes_int
+ \@@_two_if_eq:NNNNTF #1 #2 \@@_compile_special:N ^
+ {
+ \bool_set_false:N \l_@@_catcodes_bool
+ \@@_compile_c_lbrack_loop:NN
+ }
+ {
+ \bool_set_true:N \l_@@_catcodes_bool
+ \@@_compile_c_lbrack_loop:NN
+ #1 #2
+ }
+ }
+\cs_new_protected:Npn \@@_compile_c_lbrack_loop:NN #1#2
+ {
+ \token_if_eq_meaning:NNTF #1 \@@_compile_raw:N
+ {
+ \int_if_exist:cTF { c_@@_catcode_#2_int }
+ {
+ \exp_args:Nc \@@_compile_c_lbrack_add:N
+ { c_@@_catcode_#2_int }
+ \@@_compile_c_lbrack_loop:NN
+ }
+ }
+ {
+ \token_if_eq_charcode:NNTF #2 ]
+ { \@@_compile_c_lbrack_end: }
+ }
+ {
+ \msg_error:nne { regex } { c-missing-rbrack } {#2}
+ \@@_compile_c_lbrack_end:
+ #1 #2
+ }
+ }
+\cs_new_protected:Npn \@@_compile_c_lbrack_add:N #1
+ {
+ \if_int_odd:w \@@_int_eval:w \l_@@_catcodes_int / #1 \scan_stop:
+ \else:
+ \int_add:Nn \l_@@_catcodes_int {#1}
+ \fi:
+ }
+\cs_new_protected:Npn \@@_compile_c_lbrack_end:
+ {
+ \if_meaning:w \c_false_bool \l_@@_catcodes_bool
+ \int_set:Nn \l_@@_catcodes_int
+ { \c_@@_all_catcodes_int - \l_@@_catcodes_int }
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}+\@@_compile_c_{:+
+% The case of a left brace is easy, based on what we have done so far:
+% in a group, compile the regular expression, after changing the mode
+% to forbid nesting |\c|. Additionally, disable submatch tracking
+% since groups don't escape the scope of |\c{...}|.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_c_ \c_left_brace_str :w }
+ {
+ \@@_compile:w
+ \@@_disable_submatches:
+ \l_@@_mode_int
+ = \if_case:w \l_@@_mode_int
+ \c_@@_cs_mode_int
+ \else:
+ \c_@@_cs_in_class_mode_int
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}+\@@_compile_{:+
+% We forbid unescaped left braces inside a |\c{...}| escape because
+% they otherwise lead to the confusing question of whether the first
+% right brace in |\c{{}x}| should end |\c| or whether one should
+% match braces.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_ \c_left_brace_str : }
+ {
+ \@@_if_in_cs:TF
+ { \msg_error:nnn { regex } { cu-lbrace } { c } }
+ { \exp_after:wN \@@_compile_raw:N \c_left_brace_str }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_cs_flag}
+% \begin{macro}+\@@_compile_}:+
+% \begin{macro}{\@@_compile_end_cs:}
+% \begin{macro}[EXP]{\@@_compile_cs_aux:Nn, \@@_compile_cs_aux:NNnnnN}
+% Non-escaped right braces are only special if they appear when
+% compiling the regular expression for a csname, but not within a
+% class: |\c{[{}]}| matches the control sequences |\{| and |\}|. So,
+% end compiling the inner regex (this closes any dangling class or
+% group). Then insert the corresponding test in the outer regex. As
+% an optimization, if the control sequence test simply consists of
+% several explicit possibilities (branches) then use
+% \cs{@@_item_exact_cs:n} with an argument consisting of all
+% possibilities separated by \cs{scan_stop:}.
+% \begin{macrocode}
+\flag_new:N \l_@@_cs_flag
+\cs_new_protected:cpn { @@_compile_ \c_right_brace_str : }
+ {
+ \@@_if_in_cs:TF
+ { \@@_compile_end_cs: }
+ { \exp_after:wN \@@_compile_raw:N \c_right_brace_str }
+ }
+\cs_new_protected:Npn \@@_compile_end_cs:
+ {
+ \@@_compile_end:
+ \flag_clear:N \l_@@_cs_flag
+ \__kernel_tl_set:Nx \l_@@_internal_a_tl
+ {
+ \exp_after:wN \@@_compile_cs_aux:Nn \l_@@_internal_regex
+ \q_@@_nil \q_@@_nil \q_@@_recursion_stop
+ }
+ \exp_args:Ne \@@_compile_one:n
+ {
+ \flag_if_raised:NTF \l_@@_cs_flag
+ { \@@_item_cs:n { \exp_not:o \l_@@_internal_regex } }
+ {
+ \@@_item_exact_cs:n
+ { \tl_tail:N \l_@@_internal_a_tl }
+ }
+ }
+ }
+\cs_new:Npn \@@_compile_cs_aux:Nn #1#2
+ {
+ \cs_if_eq:NNTF #1 \@@_branch:n
+ {
+ \scan_stop:
+ \@@_compile_cs_aux:NNnnnN #2
+ \q_@@_nil \q_@@_nil \q_@@_nil
+ \q_@@_nil \q_@@_nil \q_@@_nil \q_@@_recursion_stop
+ \@@_compile_cs_aux:Nn
+ }
+ {
+ \@@_quark_if_nil:NF #1 { \flag_ensure_raised:N \l_@@_cs_flag }
+ \@@_use_none_delimit_by_q_recursion_stop:w
+ }
+ }
+\cs_new:Npn \@@_compile_cs_aux:NNnnnN #1#2#3#4#5#6
+ {
+ \bool_lazy_all:nTF
+ {
+ { \cs_if_eq_p:NN #1 \@@_class:NnnnN }
+ {#2}
+ { \tl_if_head_eq_meaning_p:nN {#3} \@@_item_caseful_equal:n }
+ { \int_compare_p:nNn { \tl_count:n {#3} } = { 2 } }
+ { \int_compare_p:nNn {#5} = \c_zero_int }
+ }
+ {
+ \prg_replicate:nn {#4}
+ { \char_generate:nn { \use_ii:nn #3 } {12} }
+ \@@_compile_cs_aux:NNnnnN
+ }
+ {
+ \@@_quark_if_nil:NF #1
+ {
+ \flag_ensure_raised:N \l_@@_cs_flag
+ \@@_use_i_delimit_by_q_recursion_stop:nw
+ }
+ \@@_use_none_delimit_by_q_recursion_stop:w
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{variable}
+%
+% \subsubsection{Raw token lists with \cs[no-index]{u}}
+%
+% \begin{macro}{\@@_compile_/u:}
+% The |\u| escape is invalid in classes and directly following a
+% catcode test. Otherwise test for a following |r| (for |\ur|), and
+% call an auxiliary responsible for finding the variable name.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_/u: } #1#2
+ {
+ \@@_if_in_class_or_catcode:TF
+ { \@@_compile_raw_error:N u #1 #2 }
+ {
+ \@@_two_if_eq:NNNNTF #1 #2 \@@_compile_raw:N r
+ { \@@_compile_u_brace:NNN \@@_compile_ur_end: }
+ { \@@_compile_u_brace:NNN \@@_compile_u_end: #1 #2 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_u_brace:NNN}
+% This enforces the presence of a left brace, then starts a loop to
+% find the variable name.
+% \begin{macrocode}
+\cs_new:Npn \@@_compile_u_brace:NNN #1#2#3
+ {
+ \@@_two_if_eq:NNNNTF #2 #3 \@@_compile_special:N \c_left_brace_str
+ {
+ \tl_set:Nn \l_@@_internal_b_tl {#1}
+ \__kernel_tl_set:Nx \l_@@_internal_a_tl { \if_false: } \fi:
+ \@@_compile_u_loop:NN
+ }
+ {
+ \msg_error:nn { regex } { u-missing-lbrace }
+ \token_if_eq_meaning:NNTF #1 \@@_compile_ur_end:
+ { \@@_compile_raw:N u \@@_compile_raw:N r }
+ { \@@_compile_raw:N u }
+ #2 #3
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_compile_u_loop:NN}
+% We collect the characters for the argument of |\u| within an
+% \texttt{e}-expanding assignment. In principle we could just wait to
+% encounter a right brace, but this is unsafe: if the right brace was
+% missing, then we would reach the end-markers of the regex, and
+% continue, leading to obscure fatal errors. Instead, we only allow
+% raw and special characters, and stop when encountering a special
+% right brace, any escaped character, or the end-marker.
+% \begin{macrocode}
+\cs_new:Npn \@@_compile_u_loop:NN #1#2
+ {
+ \token_if_eq_meaning:NNTF #1 \@@_compile_raw:N
+ { #2 \@@_compile_u_loop:NN }
+ {
+ \token_if_eq_meaning:NNTF #1 \@@_compile_special:N
+ {
+ \exp_after:wN \token_if_eq_charcode:NNTF \c_right_brace_str #2
+ { \if_false: { \fi: } \l_@@_internal_b_tl }
+ {
+ \if_charcode:w \c_left_brace_str #2
+ \msg_expandable_error:nnn { regex } { cu-lbrace } { u }
+ \else:
+ #2
+ \fi:
+ \@@_compile_u_loop:NN
+ }
+ }
+ {
+ \if_false: { \fi: }
+ \msg_error:nne { regex } { u-missing-rbrace } {#2}
+ \l_@@_internal_b_tl
+ #1 #2
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_ur_end:, \@@_compile_ur:n}
+% \begin{macro}[EXP]{\@@_compile_ur_aux:w}
+% For the |\ur{...}| construction, once we have extracted the
+% variable's name, we replace all groups by non-capturing groups in
+% the compiled regex (passed as the
+% argument of \cs{@@_compile_ur:n}). If that has a single branch
+% (namely \cs{tl_if_empty:oTF} is false) and there is no quantifier,
+% then simply insert the contents of this branch (obtained by
+% \cs{use_ii:nn}, which is expanded later). In all other cases,
+% insert a non-capturing group and look for quantifiers to determine
+% the number of repetition etc.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_ur_end:
+ {
+ \group_begin:
+ \cs_set:Npn \@@_group:nnnN { \@@_group_no_capture:nnnN }
+ \cs_set:Npn \@@_group_resetting:nnnN { \@@_group_no_capture:nnnN }
+ \exp_args:NNe
+ \group_end:
+ \@@_compile_ur:n { \use:c { \l_@@_internal_a_tl } }
+ }
+\cs_new_protected:Npn \@@_compile_ur:n #1
+ {
+ \tl_if_empty:oTF { \@@_compile_ur_aux:w #1 {} ? ? \q_@@_nil }
+ { \@@_compile_if_quantifier:TFw }
+ { \use_i:nn }
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \@@_group_no_capture:nnnN { \if_false: } \fi: #1 }
+ \@@_compile_quantifier:w
+ }
+ { \tl_build_put_right:Nn \l_@@_build_tl { \use_ii:nn #1 } }
+ }
+\cs_new:Npn \@@_compile_ur_aux:w \@@_branch:n #1#2#3 \q_@@_nil {#2}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_u_end:, \@@_compile_u_payload:}
+% Once we have extracted the variable's name, we check for
+% quantifiers, in which case we set up a non-capturing group with a
+% single branch. Inside this branch (we omit it and the group if
+% there is no quantifier), \cs{@@_compile_u_payload:} puts
+% the right tests corresponding to the contents of the variable, which
+% we store in \cs{l_@@_internal_a_tl}. The behaviour of |\u|
+% then depends on whether we are within a |\c{...}| escape (in this
+% case, the variable is turned to a string), or not.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_u_end:
+ {
+ \@@_compile_if_quantifier:TFw
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl
+ {
+ \@@_group_no_capture:nnnN { \if_false: } \fi:
+ \@@_branch:n { \if_false: } \fi:
+ }
+ \@@_compile_u_payload:
+ \tl_build_put_right:Nn \l_@@_build_tl { \if_false: { \fi: } }
+ \@@_compile_quantifier:w
+ }
+ { \@@_compile_u_payload: }
+ }
+\cs_new_protected:Npn \@@_compile_u_payload:
+ {
+ \tl_set:Nv \l_@@_internal_a_tl { \l_@@_internal_a_tl }
+ \if_int_compare:w \l_@@_mode_int = \c_@@_outer_mode_int
+ \@@_compile_u_not_cs:
+ \else:
+ \@@_compile_u_in_cs:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_u_in_cs:}
+% When |\u| appears within a control sequence, we convert the variable
+% to a string with escaped spaces. Then for each character insert a
+% class matching exactly that character, once.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_u_in_cs:
+ {
+ \__kernel_tl_gset:Nx \g_@@_internal_tl
+ {
+ \exp_args:No \__kernel_str_to_other_fast:n
+ { \l_@@_internal_a_tl }
+ }
+ \tl_build_put_right:Ne \l_@@_build_tl
+ {
+ \tl_map_function:NN \g_@@_internal_tl
+ \@@_compile_u_in_cs_aux:n
+ }
+ }
+\cs_new:Npn \@@_compile_u_in_cs_aux:n #1
+ {
+ \@@_class:NnnnN \c_true_bool
+ { \@@_item_caseful_equal:n { \int_value:w `#1 } }
+ { 1 } { 0 } \c_false_bool
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_u_not_cs:}
+% In mode $0$, the |\u| escape adds one state to the NFA for each
+% token in \cs{l_@@_internal_a_tl}. If a given \meta{token} is a
+% control sequence, then insert a string comparison test, otherwise,
+% \cs{@@_item_exact:nn} which compares catcode and character code.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_u_not_cs:
+ {
+ \tl_analysis_map_inline:Nn \l_@@_internal_a_tl
+ {
+ \tl_build_put_right:Ne \l_@@_build_tl
+ {
+ \@@_class:NnnnN \c_true_bool
+ {
+ \if_int_compare:w "##3 = \c_zero_int
+ \@@_item_exact_cs:n
+ { \exp_after:wN \cs_to_str:N ##1 }
+ \else:
+ \@@_item_exact:nn { \int_value:w "##3 } { ##2 }
+ \fi:
+ }
+ { 1 } { 0 } \c_false_bool
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Other}
+%
+% \begin{macro}{\@@_compile_/K:}
+% The |\K| control sequence is currently the only \enquote{command},
+% which performs some action, rather than matching something. It is
+% allowed in the same contexts as |\b|. At the compilation stage, we
+% leave it as a single control sequence, defined later.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_/K: }
+ {
+ \int_compare:nNnTF \l_@@_mode_int = \c_@@_outer_mode_int
+ { \tl_build_put_right:Nn \l_@@_build_tl { \@@_command_K: } }
+ { \@@_compile_raw_error:N K }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Showing regexes}
+%
+% \begin{macro}[rEXP]
+% {
+% \@@_clean_bool:n, \@@_clean_int:n, \@@_clean_int_aux:N,
+% \@@_clean_regex:n, \@@_clean_regex_loop:w, \@@_clean_branch:n,
+% \@@_clean_branch_loop:n, \@@_clean_assertion:Nn,
+% \@@_clean_class:NnnnN, \@@_clean_group:nnnN, \@@_clean_class:n,
+% \@@_clean_class_loop:nnn, \@@_clean_exact_cs:n,
+% \@@_clean_exact_cs:w
+% }
+% Before showing a regex we check that it is \enquote{clean} in the
+% sense that it has the correct internal structure. We do this (in
+% the implementation of \cs{regex_show:N} and \cs{regex_log:N}) by
+% comparing it with a cleaned-up version of the same regex. Along the
+% way we also need similar functions for other types: all
+% \cs[no-index]{@@_clean_\meta{type}:n} functions produce valid
+% \meta{type} tokens (bool, explicit integer, etc.\@) from arbitrary
+% input, and the output coincides with the input if that was valid.
+% \begin{macrocode}
+\cs_new:Npn \@@_clean_bool:n #1
+ {
+ \tl_if_single:nTF {#1}
+ { \bool_if:NTF #1 \c_true_bool \c_false_bool }
+ { \c_true_bool }
+ }
+\cs_new:Npn \@@_clean_int:n #1
+ {
+ \tl_if_head_eq_meaning:nNTF {#1} -
+ { - \exp_args:No \@@_clean_int:n { \use_none:n #1 } }
+ { \int_eval:n { 0 \str_map_function:nN {#1} \@@_clean_int_aux:N } }
+ }
+\cs_new:Npn \@@_clean_int_aux:N #1
+ {
+ \if_int_compare:w \c_one_int < 1 #1 ~
+ #1
+ \else:
+ \str_map_break:n
+ \fi:
+ }
+\cs_new:Npn \@@_clean_regex:n #1
+ {
+ \@@_clean_regex_loop:w #1
+ \@@_branch:n { \q_recursion_tail } \q_recursion_stop
+ }
+\cs_new:Npn \@@_clean_regex_loop:w #1 \@@_branch:n #2
+ {
+ \quark_if_recursion_tail_stop:n {#2}
+ \@@_branch:n { \@@_clean_branch:n {#2} }
+ \@@_clean_regex_loop:w
+ }
+\cs_new:Npn \@@_clean_branch:n #1
+ {
+ \@@_clean_branch_loop:n #1
+ ? ? ? ? ? ? \prg_break_point:
+ }
+\cs_new:Npn \@@_clean_branch_loop:n #1
+ {
+ \tl_if_single:nF {#1} \prg_break:
+ \token_case_meaning:NnF #1
+ {
+ \@@_command_K: { #1 \@@_clean_branch_loop:n }
+ \@@_assertion:Nn { #1 \@@_clean_assertion:Nn }
+ \@@_class:NnnnN { #1 \@@_clean_class:NnnnN }
+ \@@_group:nnnN { #1 \@@_clean_group:nnnN }
+ \@@_group_no_capture:nnnN { #1 \@@_clean_group:nnnN }
+ \@@_group_resetting:nnnN { #1 \@@_clean_group:nnnN }
+ }
+ \prg_break:
+ }
+\cs_new:Npn \@@_clean_assertion:Nn #1#2
+ {
+ \@@_clean_bool:n {#1}
+ \tl_if_single:nF {#2} { { \@@_A_test: } \prg_break: }
+ \token_case_meaning:NnTF #2
+ {
+ \@@_A_test: { }
+ \@@_G_test: { }
+ \@@_Z_test: { }
+ \@@_b_test: { }
+ }
+ { {#2} }
+ { { \@@_A_test: } \prg_break: }
+ \@@_clean_branch_loop:n
+ }
+\cs_new:Npn \@@_clean_class:NnnnN #1#2#3#4#5
+ {
+ \@@_clean_bool:n {#1}
+ { \@@_clean_class:n {#2} }
+ { \int_max:nn \c_zero_int { \@@_clean_int:n {#3} } }
+ { \int_max:nn { -\c_one_int } { \@@_clean_int:n {#4} } }
+ \@@_clean_bool:n {#5}
+ \@@_clean_branch_loop:n
+ }
+\cs_new:Npn \@@_clean_group:nnnN #1#2#3#4
+ {
+ { \@@_clean_regex:n {#1} }
+ { \int_max:nn \c_zero_int { \@@_clean_int:n {#2} } }
+ { \int_max:nn { -\c_one_int } { \@@_clean_int:n {#3} } }
+ \@@_clean_bool:n {#4}
+ \@@_clean_branch_loop:n
+ }
+\cs_new:Npn \@@_clean_class:n #1
+ { \@@_clean_class_loop:nnn #1 ????? \prg_break_point: }
+% \end{macrocode}
+% When cleaning a class there are many cases, including a dozen or so
+% like \cs{@@_prop_d:} or \cs{@@_posix_alpha:}. To avoid listing all of
+% them we allow any command that starts with the
+% $13$ characters |__regex_prop_| or |__regex_posix| (handily these have
+% the same length, except for the trailing underscore).
+% \begin{macrocode}
+\cs_new:Npn \@@_clean_class_loop:nnn #1#2#3
+ {
+ \tl_if_single:nF {#1} \prg_break:
+ \token_case_meaning:NnTF #1
+ {
+ \@@_item_cs:n { #1 { \@@_clean_regex:n {#2} } }
+ \@@_item_exact_cs:n { #1 { \@@_clean_exact_cs:n {#2} } }
+ \@@_item_caseful_equal:n { #1 { \@@_clean_int:n {#2} } }
+ \@@_item_caseless_equal:n { #1 { \@@_clean_int:n {#2} } }
+ \@@_item_reverse:n { #1 { \@@_clean_class:n {#2} } }
+ }
+ { \@@_clean_class_loop:nnn {#3} }
+ {
+ \token_case_meaning:NnTF #1
+ {
+ \@@_item_caseful_range:nn { }
+ \@@_item_caseless_range:nn { }
+ \@@_item_exact:nn { }
+ }
+ {
+ #1 { \@@_clean_int:n {#2} } { \@@_clean_int:n {#3} }
+ \@@_clean_class_loop:nnn
+ }
+ {
+ \token_case_meaning:NnTF #1
+ {
+ \@@_item_catcode:nT { }
+ \@@_item_catcode_reverse:nT { }
+ }
+ {
+ #1 { \@@_clean_int:n {#2} } { \@@_clean_class:n {#3} }
+ \@@_clean_class_loop:nnn
+ }
+ {
+ \exp_args:Ne \str_case:nnTF
+ {
+ \exp_args:Ne \str_range:nnn
+ { \cs_to_str:N #1 } \c_one_int { 13 }
+ }
+ {
+ { @@_prop_ } { }
+ { @@_posix } { }
+ }
+ {
+ #1
+ \@@_clean_class_loop:nnn {#2} {#3}
+ }
+ \prg_break:
+ }
+ }
+ }
+ }
+\cs_new:Npn \@@_clean_exact_cs:n #1
+ {
+ \exp_last_unbraced:Nf \use_none:n
+ {
+ \@@_clean_exact_cs:w #1
+ \scan_stop: \q_recursion_tail \scan_stop:
+ \q_recursion_stop
+ }
+ }
+\cs_new:Npn \@@_clean_exact_cs:w #1 \scan_stop:
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ \scan_stop: \tl_to_str:n {#1}
+ \@@_clean_exact_cs:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_show:N}
+% Within a group and within \cs{tl_build_begin:N} \ldots{} \cs{tl_build_end:N} we
+% redefine all the function that can appear in a compiled regex, then
+% run the regex. The result stored in \cs{l_@@_internal_a_tl} is then
+% meant to be shown.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show:N #1
+ {
+ \group_begin:
+ \tl_build_begin:N \l_@@_build_tl
+ \cs_set_protected:Npn \@@_branch:n
+ {
+ \seq_pop_right:NN \l_@@_show_prefix_seq
+ \l_@@_internal_a_tl
+ \@@_show_one:n { +-branch }
+ \seq_put_right:No \l_@@_show_prefix_seq
+ \l_@@_internal_a_tl
+ \use:n
+ }
+ \cs_set_protected:Npn \@@_group:nnnN
+ { \@@_show_group_aux:nnnnN { } }
+ \cs_set_protected:Npn \@@_group_no_capture:nnnN
+ { \@@_show_group_aux:nnnnN { ~(no~capture) } }
+ \cs_set_protected:Npn \@@_group_resetting:nnnN
+ { \@@_show_group_aux:nnnnN { ~(resetting) } }
+ \cs_set_eq:NN \@@_class:NnnnN \@@_show_class:NnnnN
+ \cs_set_protected:Npn \@@_command_K:
+ { \@@_show_one:n { reset~match~start~(\iow_char:N\\K) } }
+ \cs_set_protected:Npn \@@_assertion:Nn ##1##2
+ {
+ \@@_show_one:n
+ { \bool_if:NF ##1 { negative~ } assertion:~##2 }
+ }
+ \cs_set:Npn \@@_b_test: { word~boundary }
+ \cs_set:Npn \@@_Z_test: { anchor~at~end~(\iow_char:N\\Z) }
+ \cs_set:Npn \@@_A_test: { anchor~at~start~(\iow_char:N\\A) }
+ \cs_set:Npn \@@_G_test: { anchor~at~start~of~match~(\iow_char:N\\G) }
+ \cs_set_protected:Npn \@@_item_caseful_equal:n ##1
+ { \@@_show_one:n { char~code~\@@_show_char:n{##1} } }
+ \cs_set_protected:Npn \@@_item_caseful_range:nn ##1##2
+ {
+ \@@_show_one:n
+ { range~[\@@_show_char:n{##1}, \@@_show_char:n{##2}] }
+ }
+ \cs_set_protected:Npn \@@_item_caseless_equal:n ##1
+ { \@@_show_one:n { char~code~\@@_show_char:n{##1}~(caseless) } }
+ \cs_set_protected:Npn \@@_item_caseless_range:nn ##1##2
+ {
+ \@@_show_one:n
+ { Range~[\@@_show_char:n{##1}, \@@_show_char:n{##2}]~(caseless) }
+ }
+ \cs_set_protected:Npn \@@_item_catcode:nT
+ { \@@_show_item_catcode:NnT \c_true_bool }
+ \cs_set_protected:Npn \@@_item_catcode_reverse:nT
+ { \@@_show_item_catcode:NnT \c_false_bool }
+ \cs_set_protected:Npn \@@_item_reverse:n
+ { \@@_show_scope:nn { Reversed~match } }
+ \cs_set_protected:Npn \@@_item_exact:nn ##1##2
+ { \@@_show_one:n { char~\@@_show_char:n{##2},~catcode~##1 } }
+ \cs_set_eq:NN \@@_item_exact_cs:n \@@_show_item_exact_cs:n
+ \cs_set_protected:Npn \@@_item_cs:n
+ { \@@_show_scope:nn { control~sequence } }
+ \cs_set:cpn { @@_prop_.: } { \@@_show_one:n { any~token } }
+ \seq_clear:N \l_@@_show_prefix_seq
+ \@@_show_push:n { ~ }
+ \cs_if_exist_use:N #1
+ \tl_build_end:N \l_@@_build_tl
+ \exp_args:NNNo
+ \group_end:
+ \tl_set:Nn \l_@@_internal_a_tl { \l_@@_build_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_show_char:n}
+% Show a single character, together with its ascii representation if available.
+% This could be extended to beyond ascii. It is not ideal for parentheses themselves.
+% \begin{macrocode}
+\cs_new:Npn \@@_show_char:n #1
+ {
+ \int_eval:n {#1}
+ \int_compare:nT { 32 <= #1 <= 126 }
+ { ~ ( \char_generate:nn {#1} {12} ) }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_show_one:n}
+% Every part of the final message go through this function, which adds
+% one line to the output, with the appropriate prefix.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show_one:n #1
+ {
+ \int_incr:N \l_@@_show_lines_int
+ \tl_build_put_right:Ne \l_@@_build_tl
+ {
+ \exp_not:N \iow_newline:
+ \seq_map_function:NN \l_@@_show_prefix_seq \use:n
+ #1
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_show_push:n, \@@_show_pop:, \@@_show_scope:nn}
+% Enter and exit levels of nesting. The \texttt{scope} function prints
+% its first argument as an \enquote{introduction}, then performs its
+% second argument in a deeper level of nesting.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show_push:n #1
+ { \seq_put_right:Ne \l_@@_show_prefix_seq { #1 ~ } }
+\cs_new_protected:Npn \@@_show_pop:
+ { \seq_pop_right:NN \l_@@_show_prefix_seq \l_@@_internal_a_tl }
+\cs_new_protected:Npn \@@_show_scope:nn #1#2
+ {
+ \@@_show_one:n {#1}
+ \@@_show_push:n { ~ }
+ #2
+ \@@_show_pop:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_show_group_aux:nnnnN}
+% We display all groups in the same way, simply adding a message,
+% \texttt{(no capture)} or \texttt{(resetting)}, to special groups.
+% The odd \cs{use_ii:nn} avoids printing a spurious \texttt{+-branch}
+% for the first branch.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show_group_aux:nnnnN #1#2#3#4#5
+ {
+ \@@_show_one:n { ,-group~begin #1 }
+ \@@_show_push:n { | }
+ \use_ii:nn #2
+ \@@_show_pop:
+ \@@_show_one:n
+ { `-group~end \@@_msg_repeated:nnN {#3} {#4} #5 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_show_class:NnnnN}
+% I'm entirely unhappy about this function: I couldn't find a way to
+% test if a class is a single test. Instead, collect the
+% representation of the tests in the class. If that had more than one
+% line, write \texttt{Match} or \texttt{Don't match} on its own line,
+% with the repeating information if any. Then the various tests on
+% lines of their own, and finally a line. Otherwise, we need to
+% evaluate the representation of the tests again (since the prefix is
+% incorrect). That's clunky, but not too expensive, since it's only
+% one test.
+% \begin{macrocode}
+\cs_new:Npn \@@_show_class:NnnnN #1#2#3#4#5
+ {
+ \group_begin:
+ \tl_build_begin:N \l_@@_build_tl
+ \int_zero:N \l_@@_show_lines_int
+ \@@_show_push:n {~}
+ #2
+ \int_compare:nTF { \l_@@_show_lines_int = \c_zero_int }
+ {
+ \group_end:
+ \@@_show_one:n { \bool_if:NTF #1 { Fail } { Pass } }
+ }
+ {
+ \bool_if:nTF
+ { #1 && \int_compare_p:n { \l_@@_show_lines_int = \c_one_int } }
+ {
+ \group_end:
+ #2
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \@@_msg_repeated:nnN {#3} {#4} #5 }
+ }
+ {
+ \tl_build_end:N \l_@@_build_tl
+ \exp_args:NNNo
+ \group_end:
+ \tl_set:Nn \l_@@_internal_a_tl \l_@@_build_tl
+ \@@_show_one:n
+ {
+ \bool_if:NTF #1 { Match } { Don't~match }
+ \@@_msg_repeated:nnN {#3} {#4} #5
+ }
+ \tl_build_put_right:Ne \l_@@_build_tl
+ { \exp_not:o \l_@@_internal_a_tl }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_show_item_catcode:NnT}
+% Produce a sequence of categories which the catcode bitmap |#2|
+% contains, and show it, indenting the tests on which this catcode
+% constraint applies.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show_item_catcode:NnT #1#2
+ {
+ \seq_set_split:Nnn \l_@@_internal_seq { } { CBEMTPUDSLOA }
+ \seq_set_filter:NNn \l_@@_internal_seq \l_@@_internal_seq
+ { \int_if_odd_p:n { #2 / \int_use:c { c_@@_catcode_##1_int } } }
+ \@@_show_scope:nn
+ {
+ categories~
+ \seq_map_function:NN \l_@@_internal_seq \use:n
+ , ~
+ \bool_if:NF #1 { negative~ } class
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_show_item_exact_cs:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_show_item_exact_cs:n #1
+ {
+ \seq_set_split:Nnn \l_@@_internal_seq { \scan_stop: } {#1}
+ \seq_set_map_e:NNn \l_@@_internal_seq
+ \l_@@_internal_seq { \iow_char:N\\##1 }
+ \@@_show_one:n
+ { control~sequence~ \seq_use:Nn \l_@@_internal_seq { ~or~ } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Building}
+%
+% \subsubsection{Variables used while building}
+%
+% \begin{variable}{\l_@@_min_state_int, \l_@@_max_state_int}
+% The last state that was allocated is
+% $\cs{l_@@_max_state_int}-1$, so that \cs{l_@@_max_state_int} always
+% points to a free state. The \texttt{min_state} variable is
+% $1$ to begin with, but gets shifted in nested calls to the matching
+% code, namely in |\c{...}| constructions.
+% \begin{macrocode}
+\int_new:N \l_@@_min_state_int
+\int_set:Nn \l_@@_min_state_int { 1 }
+\int_new:N \l_@@_max_state_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_left_state_int, \l_@@_right_state_int}
+% \begin{variable}{\l_@@_left_state_seq, \l_@@_right_state_seq}
+% Alternatives are implemented by branching from a \texttt{left} state
+% into the various choices, then merging those into a \texttt{right}
+% state. We store information about those states in two sequences.
+% Those states are also used to implement group quantifiers. Most
+% often, the left and right pointers only differ by~$1$.
+% \begin{macrocode}
+\int_new:N \l_@@_left_state_int
+\int_new:N \l_@@_right_state_int
+\seq_new:N \l_@@_left_state_seq
+\seq_new:N \l_@@_right_state_seq
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_capturing_group_int}
+% \cs{l_@@_capturing_group_int} is the next \textsc{id} number to
+% be assigned to a capturing group. This starts
+% at $0$ for the group enclosing the full regular expression, and
+% groups are counted in the order of their left parenthesis, except
+% when encountering \texttt{resetting} groups.
+% \begin{macrocode}
+\int_new:N \l_@@_capturing_group_int
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Framework}
+%
+% This phase is about going from a compiled regex to an \textsc{nfa}.
+% Each state of the \textsc{nfa} is stored in a \tn{toks}. The
+% operations which can appear in the \tn{toks} are
+% \begin{itemize}
+% \item \cs{@@_action_start_wildcard:N} \meta{boolean} inserted at the
+% start of the regular expression, where a \texttt{true}
+% \meta{boolean} makes it unanchored.
+% \item \cs{@@_action_success:} marks the exit state of the
+% \textsc{nfa}.
+% \item \cs{@@_action_cost:n} \Arg{shift} is a transition from the
+% current \meta{state} to $\meta{state}+\meta{shift}$, which
+% consumes the current character: the target state is saved and will
+% be considered again when matching at the next position.
+% \item \cs{@@_action_free:n} \Arg{shift}, and
+% \cs{@@_action_free_group:n} \Arg{shift} are free transitions,
+% which immediately perform the actions for the state
+% $\meta{state}+\meta{shift}$ of the \textsc{nfa}. They differ in
+% how they detect and avoid infinite loops. For now, we just need to
+% know that the \texttt{group} variant must be used for transitions
+% back to the start of a group.
+% \item \cs{@@_action_submatch:nN} \Arg{group} \meta{key} where the
+% \meta{key} is |<| or |>| for the beginning or end of group
+% numbered \meta{group}. This causes the current position in the
+% query to be stored as the \meta{key} submatch boundary.
+% \item One of these actions, within a conditional.
+% \end{itemize}
+%
+% We strive to preserve the following properties while building.
+% \begin{itemize}
+% \item The current capturing group is
+% $\text{\texttt{capturing_group}}-1$, and if a group opened now
+% it would be labelled \texttt{capturing_group}.
+% \item The last allocated state is $\text{\texttt{max_state}}-1$, so
+% \texttt{max_state} is a free state.
+% \item The \texttt{left_state} points to a state to the left of the
+% current group or of the last class.
+% \item The \texttt{right_state} points to a newly created,
+% empty state, with some transitions leading to it.
+% \item The \texttt{left/right} sequences hold a list of the
+% corresponding end-points of nested groups.
+% \end{itemize}
+%
+% \begin{macro}{\@@_build:n, \@@_build_aux:Nn, \@@_build:N, \@@_build_aux:NN}
+% The \texttt{n}-type function first compiles its argument. Reset some
+% variables. Allocate two states, and put a wildcard in state $0$
+% (transitions to state $1$ and $0$ state). Then build the regex
+% within a (capturing) group numbered $0$ (current
+% value of \texttt{capturing_group}). Finally, if the match reaches the
+% last state, it is successful. A \texttt{false} boolean for argument
+% |#1| for the auxiliaries will suppress the wildcard and make the
+% match anchored: used for \cs{peek_regex:nTF} and similar.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_build:n
+ { \@@_build_aux:Nn \c_true_bool }
+\cs_new_protected:Npn \@@_build:N
+ { \@@_build_aux:NN \c_true_bool }
+\cs_new_protected:Npn \@@_build_aux:Nn #1#2
+ {
+ \@@_compile:n {#2}
+ \@@_build_aux:NN #1 \l_@@_internal_regex
+ }
+\cs_new_protected:Npn \@@_build_aux:NN #1#2
+ {
+ \@@_standard_escapechar:
+ \int_zero:N \l_@@_capturing_group_int
+ \int_set_eq:NN \l_@@_max_state_int \l_@@_min_state_int
+ \@@_build_new_state:
+ \@@_build_new_state:
+ \@@_toks_put_right:Nn \l_@@_left_state_int
+ { \@@_action_start_wildcard:N #1 }
+ \@@_group:nnnN {#2} { 1 } { 0 } \c_false_bool
+ \@@_toks_put_right:Nn \l_@@_right_state_int
+ { \@@_action_success: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_case_int}
+% Case number that was successfully matched in
+% \cs{regex_match_case:nn} and related functions.
+% \begin{macrocode}
+\int_new:N \g_@@_case_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_case_max_group_int}
+% The largest group number appearing in any of the \meta{regex} in the
+% argument of \cs{regex_match_case:nn} and related functions.
+% \begin{macrocode}
+\int_new:N \l_@@_case_max_group_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_case_build:n, \@@_case_build:e, \@@_case_build_aux:Nn, \@@_case_build_loop:n}
+% See \cs{@@_build:n}, but with a loop.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_case_build:n #1
+ {
+ \@@_case_build_aux:Nn \c_true_bool {#1}
+ \int_gzero:N \g_@@_case_int
+ }
+\cs_generate_variant:Nn \@@_case_build:n { e }
+\cs_new_protected:Npn \@@_case_build_aux:Nn #1#2
+ {
+ \@@_standard_escapechar:
+ \int_set_eq:NN \l_@@_max_state_int \l_@@_min_state_int
+ \@@_build_new_state:
+ \@@_build_new_state:
+ \@@_toks_put_right:Nn \l_@@_left_state_int
+ { \@@_action_start_wildcard:N #1 }
+ %
+ \@@_build_new_state:
+ \@@_toks_put_left:Ne \l_@@_left_state_int
+ { \@@_action_submatch:nN \c_zero_int < }
+ \@@_push_lr_states:
+ \int_zero:N \l_@@_case_max_group_int
+ \int_gzero:N \g_@@_case_int
+ \tl_map_inline:nn {#2}
+ {
+ \int_gincr:N \g_@@_case_int
+ \@@_case_build_loop:n {##1}
+ }
+ \int_set_eq:NN \l_@@_capturing_group_int \l_@@_case_max_group_int
+ \@@_pop_lr_states:
+ }
+\cs_new_protected:Npn \@@_case_build_loop:n #1
+ {
+ \int_set_eq:NN \l_@@_capturing_group_int \c_one_int
+ \@@_compile_use:n {#1}
+ \int_set:Nn \l_@@_case_max_group_int
+ { \int_max:nn \l_@@_case_max_group_int \l_@@_capturing_group_int }
+ \seq_pop:NN \l_@@_right_state_seq \l_@@_internal_a_tl
+ \int_set:Nn \l_@@_right_state_int \l_@@_internal_a_tl
+ \@@_toks_put_left:Ne \l_@@_right_state_int
+ {
+ \@@_action_submatch:nN \c_zero_int >
+ \int_gset:Nn \g_@@_case_int
+ { \int_use:N \g_@@_case_int }
+ \@@_action_success:
+ }
+ \@@_toks_clear:N \l_@@_max_state_int
+ \seq_push:No \l_@@_right_state_seq
+ { \int_use:N \l_@@_max_state_int }
+ \int_incr:N \l_@@_max_state_int
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_build_for_cs:n}
+% The matching code relies on some global intarray variables, but only
+% uses a range of their entries. Specifically,
+% \begin{itemize}
+% \item \cs{g_@@_state_active_intarray} from \cs{l_@@_min_state_int}
+% to $\cs{l_@@_max_state_int}-1$;
+% \end{itemize}
+% Here, in this nested call to the
+% matching code, we need the new versions of this range to involve
+% completely new entries of the intarray variables, so we begin by
+% setting (the new) \cs{l_@@_min_state_int} to (the old)
+% \cs{l_@@_max_state_int} to use higher entries.
+%
+% When using a regex to match a cs, we don't insert a wildcard, we
+% anchor at the end, and since we ignore submatches, there is no need
+% to surround the expression with a group. However, for branches to
+% work properly at the outer level, we need to put the appropriate
+% \texttt{left} and \texttt{right} states in their sequence.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_build_for_cs:n #1
+ {
+ \int_set_eq:NN \l_@@_min_state_int \l_@@_max_state_int
+ \@@_build_new_state:
+ \@@_build_new_state:
+ \@@_push_lr_states:
+ #1
+ \@@_pop_lr_states:
+ \@@_toks_put_right:Nn \l_@@_right_state_int
+ {
+ \if_int_compare:w -2 = \l_@@_curr_char_int
+ \exp_after:wN \@@_action_success:
+ \fi:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Helpers for building an \textsc{nfa}}
+%
+% \begin{macro}{\@@_push_lr_states:, \@@_pop_lr_states:}
+% When building the regular expression, we keep track of pointers to
+% the left-end and right-end of each group without help from \TeX{}'s
+% grouping.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_push_lr_states:
+ {
+ \seq_push:No \l_@@_left_state_seq
+ { \int_use:N \l_@@_left_state_int }
+ \seq_push:No \l_@@_right_state_seq
+ { \int_use:N \l_@@_right_state_int }
+ }
+\cs_new_protected:Npn \@@_pop_lr_states:
+ {
+ \seq_pop:NN \l_@@_left_state_seq \l_@@_internal_a_tl
+ \int_set:Nn \l_@@_left_state_int \l_@@_internal_a_tl
+ \seq_pop:NN \l_@@_right_state_seq \l_@@_internal_a_tl
+ \int_set:Nn \l_@@_right_state_int \l_@@_internal_a_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_build_transition_left:NNN,
+% \@@_build_transition_right:nNn
+% }
+% Add a transition from |#2| to |#3| using the function |#1|. The
+% \texttt{left} function is used for higher priority transitions, and
+% the \texttt{right} function for lower priority transitions (which
+% should be performed later). The signatures differ to reflect the
+% differing usage later on. Both functions could be optimized.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_build_transition_left:NNN #1#2#3
+ { \@@_toks_put_left:Ne #2 { #1 { \tex_the:D \@@_int_eval:w #3 - #2 } } }
+\cs_new_protected:Npn \@@_build_transition_right:nNn #1#2#3
+ { \@@_toks_put_right:Ne #2 { #1 { \tex_the:D \@@_int_eval:w #3 - #2 } } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_build_new_state:}
+% Add a new empty state to the \textsc{nfa}. Then update the
+% \texttt{left}, \texttt{right}, and \texttt{max} states, so that the
+% \texttt{right} state is the new empty state, and the \texttt{left}
+% state points to the previously \enquote{current} state.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_build_new_state:
+ {
+ \@@_toks_clear:N \l_@@_max_state_int
+ \int_set_eq:NN \l_@@_left_state_int \l_@@_right_state_int
+ \int_set_eq:NN \l_@@_right_state_int \l_@@_max_state_int
+ \int_incr:N \l_@@_max_state_int
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_build_transitions_lazyness:NNNNN}
+% This function creates a new state, and puts two transitions starting
+% from the old current state. The order of the transitions is
+% controlled by |#1|, true for lazy quantifiers, and false for greedy
+% quantifiers.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_build_transitions_lazyness:NNNNN #1#2#3#4#5
+ {
+ \@@_build_new_state:
+ \@@_toks_put_right:Ne \l_@@_left_state_int
+ {
+ \if_meaning:w \c_true_bool #1
+ #2 { \tex_the:D \@@_int_eval:w #3 - \l_@@_left_state_int }
+ #4 { \tex_the:D \@@_int_eval:w #5 - \l_@@_left_state_int }
+ \else:
+ #4 { \tex_the:D \@@_int_eval:w #5 - \l_@@_left_state_int }
+ #2 { \tex_the:D \@@_int_eval:w #3 - \l_@@_left_state_int }
+ \fi:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Building classes}
+%
+% \begin{macro}{\@@_class:NnnnN}
+% \begin{macro}[rEXP]{\@@_tests_action_cost:n}
+% The arguments are: \meta{boolean} \Arg{tests} \Arg{min} \Arg{more}
+% \meta{lazyness}. First store the tests with a trailing
+% \cs{@@_action_cost:n}, in the true branch of
+% \cs{@@_break_point:TF} for positive classes, or the false branch
+% for negative classes. The integer \meta{more} is $0$ for fixed
+% repetitions, $-1$ for unbounded repetitions, and
+% $\meta{max}-\meta{min}$ for a range of repetitions.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_class:NnnnN #1#2#3#4#5
+ {
+ \cs_set:Npe \@@_tests_action_cost:n ##1
+ {
+ \exp_not:n { \exp_not:n {#2} }
+ \bool_if:NTF #1
+ { \@@_break_point:TF { \@@_action_cost:n {##1} } { } }
+ { \@@_break_point:TF { } { \@@_action_cost:n {##1} } }
+ }
+ \if_case:w - #4 \exp_stop_f:
+ \@@_class_repeat:n {#3}
+ \or: \@@_class_repeat:nN {#3} #5
+ \else: \@@_class_repeat:nnN {#3} {#4} #5
+ \fi:
+ }
+\cs_new:Npn \@@_tests_action_cost:n { \@@_action_cost:n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_class_repeat:n}
+% This is used for a fixed number of repetitions. Build one state for
+% each repetition, with a transition controlled by the tests that we
+% have collected. That works just fine for |#1|${}=0$ repetitions:
+% nothing is built.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_class_repeat:n #1
+ {
+ \prg_replicate:nn {#1}
+ {
+ \@@_build_new_state:
+ \@@_build_transition_right:nNn \@@_tests_action_cost:n
+ \l_@@_left_state_int \l_@@_right_state_int
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_class_repeat:nN}
+% This implements unbounded repetitions of a single class (\emph{e.g.}
+% the |*| and |+| quantifiers). If the minimum number |#1| of
+% repetitions is $0$, then build a transition from the current state
+% to itself governed by the tests, and a free transition to a new
+% state (hence skipping the tests). Otherwise, call
+% \cs{@@_class_repeat:n} for the code to match |#1| repetitions,
+% and add free transitions from the last state to the previous one,
+% and to a new one. In both cases, the order of transitions is
+% controlled by the lazyness boolean |#2|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_class_repeat:nN #1#2
+ {
+ \if_int_compare:w #1 = \c_zero_int
+ \@@_build_transitions_lazyness:NNNNN #2
+ \@@_action_free:n \l_@@_right_state_int
+ \@@_tests_action_cost:n \l_@@_left_state_int
+ \else:
+ \@@_class_repeat:n {#1}
+ \int_set_eq:NN \l_@@_internal_a_int \l_@@_left_state_int
+ \@@_build_transitions_lazyness:NNNNN #2
+ \@@_action_free:n \l_@@_right_state_int
+ \@@_action_free:n \l_@@_internal_a_int
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_class_repeat:nnN}
+% We want to build the code to match from |#1| to $|#1|+|#2|$
+% repetitions. Match |#1| repetitions (can be $0$). Compute the final
+% state of the next construction as \texttt{a}. Build $|#2|>0$ states,
+% each with a transition to the next state governed by the tests, and
+% a transition to the final state \texttt{a}. The computation of
+% \texttt{a} is safe because states are allocated in order, starting
+% from \texttt{max_state}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_class_repeat:nnN #1#2#3
+ {
+ \@@_class_repeat:n {#1}
+ \int_set:Nn \l_@@_internal_a_int
+ { \l_@@_max_state_int + #2 - \c_one_int }
+ \prg_replicate:nn { #2 }
+ {
+ \@@_build_transitions_lazyness:NNNNN #3
+ \@@_action_free:n \l_@@_internal_a_int
+ \@@_tests_action_cost:n \l_@@_right_state_int
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Building groups}
+%
+% \begin{macro}{\@@_group_aux:nnnnN}
+% Arguments: \Arg{label} \Arg{contents} \Arg{min} \Arg{more}
+% \meta{lazyness}. If \meta{min} is $0$, we need to add a state before
+% building the group, so that the thread which skips the group does
+% not also set the start-point of the submatch. After adding one more
+% state, the \texttt{left_state} is the left end of the group, from
+% which all branches stem, and the \texttt{right_state} is the
+% right end of the group, and all branches end their course in that
+% state. We store those two integers to be queried for each branch, we
+% build the \textsc{nfa} states for the contents |#2| of the group,
+% and we forget about the two integers. Once this is done, perform the
+% repetition: either exactly |#3| times, or |#3| or more times, or
+% between |#3| and $|#3|+|#4|$ times, with lazyness |#5|. The
+% \meta{label} |#1| is used for submatch tracking. Each of the three
+% auxiliaries expects \texttt{left_state} and \texttt{right_state} to
+% be set properly.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_group_aux:nnnnN #1#2#3#4#5
+ {
+ \if_int_compare:w #3 = \c_zero_int
+ \@@_build_new_state:
+ \@@_build_transition_right:nNn \@@_action_free_group:n
+ \l_@@_left_state_int \l_@@_right_state_int
+ \fi:
+ \@@_build_new_state:
+ \@@_push_lr_states:
+ #2
+ \@@_pop_lr_states:
+ \if_case:w - #4 \exp_stop_f:
+ \@@_group_repeat:nn {#1} {#3}
+ \or: \@@_group_repeat:nnN {#1} {#3} #5
+ \else: \@@_group_repeat:nnnN {#1} {#3} {#4} #5
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_group:nnnN, \@@_group_no_capture:nnnN}
+% Hand to \cs{@@_group_aux:nnnnnN} the label of that group
+% (expanded), and the group itself, with some extra commands to
+% perform.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_group:nnnN #1
+ {
+ \exp_args:No \@@_group_aux:nnnnN
+ { \int_use:N \l_@@_capturing_group_int }
+ {
+ \int_incr:N \l_@@_capturing_group_int
+ #1
+ }
+ }
+\cs_new_protected:Npn \@@_group_no_capture:nnnN
+ { \@@_group_aux:nnnnN { -1 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_group_resetting:nnnN}
+% \begin{macro}{\@@_group_resetting_loop:nnNn}
+% Again, hand the label $-1$ to \cs{@@_group_aux:nnnnN}, but this
+% time we work a little bit harder to keep track of the maximum group
+% label at the end of any branch, and to reset the group number at
+% each branch. This relies on the fact that a compiled regex always is
+% a sequence of items of the form \cs{@@_branch:n} \Arg{branch}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_group_resetting:nnnN #1
+ {
+ \@@_group_aux:nnnnN { -1 }
+ {
+ \exp_args:Noo \@@_group_resetting_loop:nnNn
+ { \int_use:N \l_@@_capturing_group_int }
+ { \int_use:N \l_@@_capturing_group_int }
+ #1
+ { ?? \prg_break:n } { }
+ \prg_break_point:
+ }
+ }
+\cs_new_protected:Npn \@@_group_resetting_loop:nnNn #1#2#3#4
+ {
+ \use_none:nn #3 { \int_set:Nn \l_@@_capturing_group_int {#1} }
+ \int_set:Nn \l_@@_capturing_group_int {#2}
+ #3 {#4}
+ \exp_args:Ne \@@_group_resetting_loop:nnNn
+ { \int_max:nn {#1} \l_@@_capturing_group_int }
+ {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_branch:n}
+% Add a free transition from the left state of the current group to a
+% brand new state, starting point of this branch. Once the branch is
+% built, add a transition from its last state to the right state of
+% the group. The left and right states of the group are extracted from
+% the relevant sequences.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_branch:n #1
+ {
+ \@@_build_new_state:
+ \seq_get:NN \l_@@_left_state_seq \l_@@_internal_a_tl
+ \int_set:Nn \l_@@_left_state_int \l_@@_internal_a_tl
+ \@@_build_transition_right:nNn \@@_action_free:n
+ \l_@@_left_state_int \l_@@_right_state_int
+ #1
+ \seq_get:NN \l_@@_right_state_seq \l_@@_internal_a_tl
+ \@@_build_transition_right:nNn \@@_action_free:n
+ \l_@@_right_state_int \l_@@_internal_a_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_group_repeat:nn}
+% This function is called to repeat a group a fixed number of times
+% |#2|; if this is $0$ we remove the group altogether (but don't reset
+% the \texttt{capturing_group} label). Otherwise, the auxiliary
+% \cs{@@_group_repeat_aux:n} copies |#2| times the \tn{toks} for
+% the group, and leaves \texttt{internal_a} pointing to the left end
+% of the last repetition. We only record the submatch information at
+% the last repetition. Finally, add a state at the end (the transition
+% to it has been taken care of by the replicating auxiliary).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_group_repeat:nn #1#2
+ {
+ \if_int_compare:w #2 = \c_zero_int
+ \int_set:Nn \l_@@_max_state_int
+ { \l_@@_left_state_int - \c_one_int }
+ \@@_build_new_state:
+ \else:
+ \@@_group_repeat_aux:n {#2}
+ \@@_group_submatches:nNN {#1}
+ \l_@@_internal_a_int \l_@@_right_state_int
+ \@@_build_new_state:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_group_submatches:nNN}
+% This inserts in states |#2| and |#3| the code for tracking
+% submatches of the group |#1|, unless inhibited by a label of $-1$.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_group_submatches:nNN #1#2#3
+ {
+ \if_int_compare:w #1 > - \c_one_int
+ \@@_toks_put_left:Ne #2 { \@@_action_submatch:nN {#1} < }
+ \@@_toks_put_left:Ne #3 { \@@_action_submatch:nN {#1} > }
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_group_repeat_aux:n}
+% Here we repeat \tn{toks} ranging from \texttt{left_state} to
+% \texttt{max_state}, $|#1|>0$ times. First add a transition so that
+% the copies \enquote{chain} properly. Compute the shift
+% \texttt{c} between the original copy and the last copy we
+% want. Shift the \texttt{right_state} and \texttt{max_state} to their
+% final values. We then want to perform \texttt{c} copy operations. At
+% the end, \texttt{b} is equal to the \texttt{max_state}, and
+% \texttt{a} points to the left of the last copy of the group.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_group_repeat_aux:n #1
+ {
+ \@@_build_transition_right:nNn \@@_action_free:n
+ \l_@@_right_state_int \l_@@_max_state_int
+ \int_set_eq:NN \l_@@_internal_a_int \l_@@_left_state_int
+ \int_set_eq:NN \l_@@_internal_b_int \l_@@_max_state_int
+ \if_int_compare:w \@@_int_eval:w #1 > \c_one_int
+ \int_set:Nn \l_@@_internal_c_int
+ {
+ ( #1 - \c_one_int )
+ * ( \l_@@_internal_b_int - \l_@@_internal_a_int )
+ }
+ \int_add:Nn \l_@@_right_state_int \l_@@_internal_c_int
+ \int_add:Nn \l_@@_max_state_int \l_@@_internal_c_int
+ \@@_toks_memcpy:NNn
+ \l_@@_internal_b_int
+ \l_@@_internal_a_int
+ \l_@@_internal_c_int
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_group_repeat:nnN}
+% This function is called to repeat a group at least $n$ times; the
+% case $n=0$ is very different from $n>0$. Assume first that $n=0$.
+% Insert submatch tracking information at the start and end of the
+% group, add a free transition from the right end to the
+% \enquote{true} left state \texttt{a} (remember: in this case we had
+% added an extra state before the left state). This forms the loop,
+% which we break away from by adding a free transition from \texttt{a}
+% to a new state.
+%
+% Now consider the case $n>0$. Repeat the group $n$ times, chaining
+% various copies with a free transition. Add submatch tracking only to
+% the last copy, then add a free transition from the right end back to
+% the left end of the last copy, either before or after the transition
+% to move on towards the rest of the \textsc{nfa}. This transition can
+% end up before submatch tracking, but that is irrelevant since it
+% only does so when going again through the group, recording new
+% matches. Finally, add a state; we already have a transition pointing
+% to it from \cs{@@_group_repeat_aux:n}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_group_repeat:nnN #1#2#3
+ {
+ \if_int_compare:w #2 = \c_zero_int
+ \@@_group_submatches:nNN {#1}
+ \l_@@_left_state_int \l_@@_right_state_int
+ \int_set:Nn \l_@@_internal_a_int
+ { \l_@@_left_state_int - \c_one_int }
+ \@@_build_transition_right:nNn \@@_action_free:n
+ \l_@@_right_state_int \l_@@_internal_a_int
+ \@@_build_new_state:
+ \if_meaning:w \c_true_bool #3
+ \@@_build_transition_left:NNN \@@_action_free:n
+ \l_@@_internal_a_int \l_@@_right_state_int
+ \else:
+ \@@_build_transition_right:nNn \@@_action_free:n
+ \l_@@_internal_a_int \l_@@_right_state_int
+ \fi:
+ \else:
+ \@@_group_repeat_aux:n {#2}
+ \@@_group_submatches:nNN {#1}
+ \l_@@_internal_a_int \l_@@_right_state_int
+ \if_meaning:w \c_true_bool #3
+ \@@_build_transition_right:nNn \@@_action_free_group:n
+ \l_@@_right_state_int \l_@@_internal_a_int
+ \else:
+ \@@_build_transition_left:NNN \@@_action_free_group:n
+ \l_@@_right_state_int \l_@@_internal_a_int
+ \fi:
+ \@@_build_new_state:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_group_repeat:nnnN}
+% We wish to repeat the group between |#2| and $|#2|+|#3|$ times, with
+% a lazyness controlled by |#4|. We insert submatch tracking up front:
+% in principle, we could avoid recording submatches for the first |#2|
+% copies of the group, but that forces us to treat specially the case
+% $|#2|=0$. Repeat that group with submatch tracking $|#2|+|#3|$ times
+% (the maximum number of repetitions). Then our goal is to add |#3|
+% transitions from the end of the |#2|-th group, and each subsequent
+% groups, to the end. For a lazy quantifier, we add those transitions
+% to the left states, before submatch tracking. For the greedy case,
+% we add the transitions to the right states, after submatch tracking
+% and the transitions which go on with more repetitions. In the greedy
+% case with $|#2|=0$, the transition which skips over all copies of
+% the group must be added separately, because its starting state does
+% not follow the normal pattern: we had to add it \enquote{by hand}
+% earlier.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_group_repeat:nnnN #1#2#3#4
+ {
+ \@@_group_submatches:nNN {#1}
+ \l_@@_left_state_int \l_@@_right_state_int
+ \@@_group_repeat_aux:n { #2 + #3 }
+ \if_meaning:w \c_true_bool #4
+ \int_set_eq:NN \l_@@_left_state_int \l_@@_max_state_int
+ \prg_replicate:nn { #3 }
+ {
+ \int_sub:Nn \l_@@_left_state_int
+ { \l_@@_internal_b_int - \l_@@_internal_a_int }
+ \@@_build_transition_left:NNN \@@_action_free:n
+ \l_@@_left_state_int \l_@@_max_state_int
+ }
+ \else:
+ \prg_replicate:nn { #3 - \c_one_int }
+ {
+ \int_sub:Nn \l_@@_right_state_int
+ { \l_@@_internal_b_int - \l_@@_internal_a_int }
+ \@@_build_transition_right:nNn \@@_action_free:n
+ \l_@@_right_state_int \l_@@_max_state_int
+ }
+ \if_int_compare:w #2 = \c_zero_int
+ \int_set:Nn \l_@@_right_state_int
+ { \l_@@_left_state_int - \c_one_int }
+ \else:
+ \int_sub:Nn \l_@@_right_state_int
+ { \l_@@_internal_b_int - \l_@@_internal_a_int }
+ \fi:
+ \@@_build_transition_right:nNn \@@_action_free:n
+ \l_@@_right_state_int \l_@@_max_state_int
+ \fi:
+ \@@_build_new_state:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Others}
+%
+% \begin{macro}{\@@_assertion:Nn, \@@_b_test:, \@@_A_test:, \@@_G_test:, \@@_Z_test:}
+% Usage: \cs{@@_assertion:Nn} \meta{boolean} \Arg{test}, where the
+% \meta{test} is either of the two other functions. Add a free
+% transition to a new state, conditionally to the assertion test. The
+% \cs{@@_b_test:} test is used by the |\b| and |\B| escape: check
+% if the last character was a word character or not, and do the same
+% to the current character. The boundary-markers of the string are
+% non-word characters for this purpose.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_assertion:Nn #1#2
+ {
+ \@@_build_new_state:
+ \@@_toks_put_right:Ne \l_@@_left_state_int
+ {
+ \exp_not:n {#2}
+ \@@_break_point:TF
+ \bool_if:NF #1 { { } }
+ {
+ \@@_action_free:n
+ {
+ \tex_the:D \@@_int_eval:w
+ \l_@@_right_state_int - \l_@@_left_state_int
+ }
+ }
+ \bool_if:NT #1 { { } }
+ }
+ }
+\cs_new_protected:Npn \@@_b_test:
+ {
+ \group_begin:
+ \int_set_eq:NN \l_@@_curr_char_int \l_@@_last_char_int
+ \@@_prop_w:
+ \@@_break_point:TF
+ { \group_end: \@@_item_reverse:n { \@@_prop_w: } }
+ { \group_end: \@@_prop_w: }
+ }
+\cs_new_protected:Npn \@@_Z_test:
+ {
+ \if_int_compare:w -2 = \l_@@_curr_char_int
+ \exp_after:wN \@@_break_true:w
+ \fi:
+ }
+\cs_new_protected:Npn \@@_A_test:
+ {
+ \if_int_compare:w -2 = \l_@@_last_char_int
+ \exp_after:wN \@@_break_true:w
+ \fi:
+ }
+\cs_new_protected:Npn \@@_G_test:
+ {
+ \if_int_compare:w \l_@@_curr_pos_int = \l_@@_start_pos_int
+ \exp_after:wN \@@_break_true:w
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_command_K:}
+% Change the starting point of the $0$-th submatch (full match), and
+% transition to a new state, pretending that this is a fresh thread.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_command_K:
+ {
+ \@@_build_new_state:
+ \@@_toks_put_right:Ne \l_@@_left_state_int
+ {
+ \@@_action_submatch:nN \c_zero_int <
+ \bool_set_true:N \l_@@_fresh_thread_bool
+ \@@_action_free:n
+ {
+ \tex_the:D \@@_int_eval:w
+ \l_@@_right_state_int - \l_@@_left_state_int
+ }
+ \bool_set_false:N \l_@@_fresh_thread_bool
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Matching}
+%
+% We search for matches by running all the execution threads through the
+% \textsc{nfa} in parallel, reading one token of the query at each step.
+% The \textsc{nfa} contains \enquote{free} transitions to other states,
+% and transitions which \enquote{consume} the current token. For free
+% transitions, the instruction at the new state of the \textsc{nfa} is
+% performed immediately. When a transition consumes a character, the
+% new state is appended to a list of \enquote{active states}, stored in
+% \cs{g_@@_thread_info_intarray} (together with submatch information):
+% this thread is made active again when the next
+% token is read from the query. At every step (for each token in the
+% query), we unpack that list of active states and the corresponding
+% submatch props, and empty those.
+%
+% If two paths through the \textsc{nfa} \enquote{collide} in the sense
+% that they reach the same state after reading a given token, then they
+% only differ in how they previously matched, and any future execution
+% would be identical for both. (Note that this would be wrong in the
+% presence of back-references.) Hence, we only need to keep one of the
+% two threads: the thread with the highest priority. Our \textsc{nfa} is
+% built in such a way that higher priority actions always come before
+% lower priority actions, which makes things work.
+%
+% The explanation in the previous paragraph may make us think that we
+% simply need to keep track of which states were visited at a given
+% step: after all, the loop generated when matching |(a?)*| against |a|
+% is broken, isn't it? No. The group first matches |a|, as it should,
+% then repeats; it attempts to match |a| again but fails; it skips |a|,
+% and finds out that this state has already been seen at this position
+% in the query: the match stops. The capturing group is (wrongly) |a|.
+% What went wrong is that a thread collided with itself, and the later
+% version, which has gone through the group one more times with an empty
+% match, should have a higher priority than not going through the group.
+%
+% We solve this by distinguishing \enquote{normal} free transitions
+% \cs{@@_action_free:n} from transitions
+% \cs{@@_action_free_group:n} which go back to the start of the
+% group. The former keeps threads unless they have been visited by a
+% \enquote{completed} thread, while the latter kind of transition also
+% prevents going back to a state visited by the current thread.
+%
+% \subsubsection{Variables used when matching}
+%
+% \begin{variable}
+% {
+% \l_@@_min_pos_int,
+% \l_@@_max_pos_int,
+% \l_@@_curr_pos_int,
+% \l_@@_start_pos_int,
+% \l_@@_success_pos_int,
+% }
+% The tokens in the query are indexed from \texttt{min_pos} for the
+% first to $\texttt{max_pos}-1$ for the last, and their information is
+% stored in several arrays and \tn{toks} registers with those numbers.
+% We match
+% without backtracking, keeping all threads in lockstep at the
+% \texttt{curr_pos} in the query. The starting point of the current
+% match attempt is \texttt{start_pos}, and \texttt{success_pos},
+% updated whenever a thread succeeds, is used as the next starting
+% position.
+% \begin{macrocode}
+\int_new:N \l_@@_min_pos_int
+\int_new:N \l_@@_max_pos_int
+\int_new:N \l_@@_curr_pos_int
+\int_new:N \l_@@_start_pos_int
+\int_new:N \l_@@_success_pos_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \l_@@_curr_char_int,
+% \l_@@_curr_catcode_int,
+% \l_@@_curr_token_tl,
+% \l_@@_last_char_int,
+% \l_@@_last_char_success_int,
+% \l_@@_case_changed_char_int
+% }
+% The character and category codes of the token at the current
+% position and a token list expanding to that token; the character
+% code of the token at the previous position;
+% the character code of the token just before a successful match;
+% and the character code of the result of changing the case of the
+% current token (|A-Z|$\leftrightarrow$|a-z|). This last integer is
+% only computed when necessary, and is otherwise \cs{c_max_int}. The
+% \texttt{curr_char} variable is also used in various other phases
+% to hold a character code.
+% \begin{macrocode}
+\int_new:N \l_@@_curr_char_int
+\int_new:N \l_@@_curr_catcode_int
+\tl_new:N \l_@@_curr_token_tl
+\int_new:N \l_@@_last_char_int
+\int_new:N \l_@@_last_char_success_int
+\int_new:N \l_@@_case_changed_char_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_curr_state_int}
+% For every character in the token list, each of the active states is
+% considered in turn. The variable \cs{l_@@_curr_state_int}
+% holds the state of the \textsc{nfa} which is currently considered:
+% transitions are then given as shifts relative to the current state.
+% \begin{macrocode}
+\int_new:N \l_@@_curr_state_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {\l_@@_curr_submatches_tl, \l_@@_success_submatches_tl}
+% The submatches for the thread which is currently active are stored
+% in the \texttt{curr_submatches} list, which is almost a comma list,
+% but ends with a comma. This list is stored by \cs{@@_store_state:n}
+% into an intarray variable, to be retrieved when matching at the next
+% position. When a thread succeeds, this list is copied to
+% \cs{l_@@_success_submatches_tl}: only the last successful thread
+% remains there.
+% \begin{macrocode}
+\tl_new:N \l_@@_curr_submatches_tl
+\tl_new:N \l_@@_success_submatches_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_step_int}
+% This integer, always even, is increased every time a character in
+% the query is read, and not reset when doing multiple matches. We
+% store in \cs{g_@@_state_active_intarray} the last step in which each
+% \meta{state} in the \textsc{nfa} was encountered. This lets us break
+% infinite loops by not visiting the same state twice in the same
+% step. In fact, the step we store is equal to \texttt{step} when we
+% have started performing the operations of \tn{toks}\meta{state}, but
+% not finished yet. However, once we finish, we store
+% $\text{\texttt{step}}+1$ in \cs{g_@@_state_active_intarray}. This is
+% needed to track submatches
+% properly (see building phase). The \texttt{step} is also used to
+% attach each set of submatch information to a given iteration (and
+% automatically discard it when it corresponds to a past step).
+% \begin{macrocode}
+\int_new:N \l_@@_step_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_min_thread_int, \l_@@_max_thread_int}
+% All the currently active threads are kept in order of precedence in
+% \cs{g_@@_thread_info_intarray} together with the corresponding
+% submatch information. Data in this intarray is organized as blocks
+% from \texttt{min_thread} (included) to \texttt{max_thread}
+% (excluded). At the start of every step, the whole array is
+% unpacked, so that the space can immediately be reused, and
+% \texttt{max_thread} is reset to \texttt{min_thread}, effectively
+% clearing the array.
+% \begin{macrocode}
+\int_new:N \l_@@_min_thread_int
+\int_new:N \l_@@_max_thread_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_state_active_intarray, \g_@@_thread_info_intarray}
+% \cs{g_@@_state_active_intarray} stores the last \meta{step} in which
+% each \meta{state} was active. \cs{g_@@_thread_info_intarray} stores
+% threads to be considered in the next step, more precisely the
+% states in which these threads are.
+% \begin{macrocode}
+\intarray_new:Nn \g_@@_state_active_intarray { 65536 }
+\intarray_new:Nn \g_@@_thread_info_intarray { 65536 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_matched_analysis_tl, \l_@@_curr_analysis_tl}
+% The list \cs{l_@@_curr_analysis_tl} consists of a brace group
+% containing three brace groups corresponding to the current token,
+% with the same syntax as \cs{tl_analysis_map_inline:nn}. The list
+% \cs{l_@@_matched_analysis_tl} (constructed under the
+% \texttt{tl\_build} machinery) has one item for each token that has
+% already been treated so far in a given match attempt: each item
+% consists of three brace groups with the same syntax as
+% \cs{tl_analysis_map_inline:nn}.
+% \begin{macrocode}
+\tl_new:N \l_@@_matched_analysis_tl
+\tl_new:N \l_@@_curr_analysis_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_every_match_tl}
+% Every time a match is found, this token list is used. For single
+% matching, the token list is empty. For multiple matching, the token
+% list is set to repeat the matching, after performing some operation
+% which depends on the user function. See \cs{@@_single_match:} and
+% \cs{@@_multi_match:n}.
+% \begin{macrocode}
+\tl_new:N \l_@@_every_match_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_fresh_thread_bool, \l_@@_empty_success_bool}
+% \begin{macro}{\@@_if_two_empty_matches:F}
+% When doing multiple matches, we need to avoid infinite loops where
+% each iteration matches the same empty token list. When an empty
+% token list is matched, the next successful match of the same empty
+% token list is suppressed. We detect empty matches by setting
+% \cs{l_@@_fresh_thread_bool} to \texttt{true} for threads which
+% directly come from the start of the regex or from the |\K| command,
+% and testing that boolean whenever a thread succeeds. The function
+% \cs{@@_if_two_empty_matches:F} is redefined at every match
+% attempt, depending on whether the previous match was empty or not:
+% if it was, then the function must cancel a purported success if it
+% is empty and at the same spot as the previous match; otherwise, we
+% definitely don't have two identical empty matches, so the function
+% is \cs{use:n}.
+% \begin{macrocode}
+\bool_new:N \l_@@_fresh_thread_bool
+\bool_new:N \l_@@_empty_success_bool
+\cs_new_eq:NN \@@_if_two_empty_matches:F \use:n
+% \end{macrocode}
+% \end{macro}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \g_@@_success_bool,
+% \l_@@_saved_success_bool,
+% \l_@@_match_success_bool
+% }
+% The boolean \cs{l_@@_match_success_bool} is true if the current
+% match attempt was successful, and \cs{g_@@_success_bool} is true
+% if there was at least one successful match. This is the only global
+% variable in this whole module, but we would need it to be local when
+% matching a control sequence with |\c{...}|. This is done by saving
+% the global variable into \cs{l_@@_saved_success_bool}, which is
+% local, hence not affected by the changes due to inner regex
+% functions.
+% \begin{macrocode}
+\bool_new:N \g_@@_success_bool
+\bool_new:N \l_@@_saved_success_bool
+\bool_new:N \l_@@_match_success_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Matching: framework}
+%
+% \begin{macro}{\@@_match:n, \@@_match_cs:n}
+% \begin{macro}{\@@_match_init:}
+% Initialize the variables that should
+% be set once for each user function (even for multiple
+% matches). Namely, the overall matching is not yet successful; none of
+% the states should be marked as visited (\cs{g_@@_state_active_intarray}), and
+% we start at step $0$; we pretend that there was a previous match
+% ending at the start of the query, which was not empty (to avoid
+% smothering an empty match at the start). Once all this is set up, we
+% are ready for the ride. Find the first match.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_match:n #1
+ {
+ \@@_match_init:
+ \@@_match_once_init:
+ \tl_analysis_map_inline:nn {#1}
+ { \@@_match_one_token:nnN {##1} {##2} ##3 }
+ \@@_match_one_token:nnN { } { -2 } F
+ \prg_break_point:Nn \@@_maplike_break: { }
+ }
+\cs_new_protected:Npn \@@_match_cs:n #1
+ {
+ \int_set_eq:NN \l_@@_min_thread_int \l_@@_max_thread_int
+ \@@_match_init:
+ \@@_match_once_init:
+ \str_map_inline:nn {#1}
+ {
+ \tl_if_blank:nTF {##1}
+ { \@@_match_one_token:nnN {##1} {`##1} A }
+ { \@@_match_one_token:nnN {##1} {`##1} C }
+ }
+ \@@_match_one_token:nnN { } { -2 } F
+ \prg_break_point:Nn \@@_maplike_break: { }
+ }
+\cs_new_protected:Npn \@@_match_init:
+ {
+ \bool_gset_false:N \g_@@_success_bool
+ \int_step_inline:nnn
+ \l_@@_min_state_int { \l_@@_max_state_int - \c_one_int }
+ {
+ \__kernel_intarray_gset:Nnn
+ \g_@@_state_active_intarray {##1} \c_one_int
+ }
+ \int_zero:N \l_@@_step_int
+ \int_set:Nn \l_@@_min_pos_int { 2 }
+ \int_set_eq:NN \l_@@_success_pos_int \l_@@_min_pos_int
+ \int_set:Nn \l_@@_last_char_success_int { -2 }
+ \tl_build_begin:N \l_@@_matched_analysis_tl
+ \tl_clear:N \l_@@_curr_analysis_tl
+ \int_set_eq:NN \l_@@_min_submatch_int \c_one_int
+ \int_set_eq:NN \l_@@_submatch_int \l_@@_min_submatch_int
+ \bool_set_false:N \l_@@_empty_success_bool
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_match_once_init:}
+% This function resets various variables used when finding one match.
+% It is called before the loop through characters, and every time we
+% find a match, before searching for another match (this is controlled
+% by the \texttt{every_match} token list).
+%
+% First initialize some variables: set the
+% conditional which detects identical empty matches; this match
+% attempt starts at the previous \texttt{success_pos}, is not yet
+% successful, and has no submatches yet; clear the array of active
+% threads, and put the starting state $0$ in it. We are then almost
+% ready to read our first token in the query, but we actually start
+% one position earlier than the start because
+% \cs{@@_match_one_token:nnN} increments \cs{l_@@_curr_pos_int} and
+% saves \cs{l_@@_curr_char_int} as the \texttt{last_char} so that word
+% boundaries can be correctly identified.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_match_once_init:
+ {
+ \if_meaning:w \c_true_bool \l_@@_empty_success_bool
+ \cs_set:Npn \@@_if_two_empty_matches:F
+ {
+ \int_compare:nNnF
+ \l_@@_start_pos_int = \l_@@_curr_pos_int
+ }
+ \else:
+ \cs_set_eq:NN \@@_if_two_empty_matches:F \use:n
+ \fi:
+ \int_set_eq:NN \l_@@_start_pos_int \l_@@_success_pos_int
+ \bool_set_false:N \l_@@_match_success_bool
+ \tl_set:Ne \l_@@_curr_submatches_tl
+ { \prg_replicate:nn { 2 * \l_@@_capturing_group_int } { 0 , } }
+ \int_set_eq:NN \l_@@_max_thread_int \l_@@_min_thread_int
+ \@@_store_state:n { \l_@@_min_state_int }
+ \int_set:Nn \l_@@_curr_pos_int { \l_@@_start_pos_int - \c_one_int }
+ \int_set_eq:NN \l_@@_curr_char_int \l_@@_last_char_success_int
+ \tl_build_get_intermediate:NN \l_@@_matched_analysis_tl \l_@@_internal_a_tl
+ \exp_args:NNf \@@_match_once_init_aux:
+ \tl_map_inline:nn
+ { \exp_after:wN \l_@@_internal_a_tl \l_@@_curr_analysis_tl }
+ { \@@_match_one_token:nnN ##1 }
+ \prg_break_point:Nn \@@_maplike_break: { }
+ }
+\cs_new_protected:Npn \@@_match_once_init_aux:
+ {
+ \tl_build_begin:N \l_@@_matched_analysis_tl
+ \tl_clear:N \l_@@_curr_analysis_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_single_match:, \@@_multi_match:n}
+% For a single match, the overall success is determined by whether the
+% only match attempt is a success. When doing multiple matches, the
+% overall matching is successful as soon as any match
+% succeeds. Perform the action |#1|, then find the next match.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_single_match:
+ {
+ \tl_set:Nn \l_@@_every_match_tl
+ {
+ \bool_gset_eq:NN
+ \g_@@_success_bool
+ \l_@@_match_success_bool
+ \@@_maplike_break:
+ }
+ }
+\cs_new_protected:Npn \@@_multi_match:n #1
+ {
+ \tl_set:Nn \l_@@_every_match_tl
+ {
+ \if_meaning:w \c_false_bool \l_@@_match_success_bool
+ \exp_after:wN \@@_maplike_break:
+ \fi:
+ \bool_gset_true:N \g_@@_success_bool
+ #1
+ \@@_match_once_init:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_match_one_token:nnN}
+% \begin{macro}[rEXP]{\@@_match_one_active:n}
+% At each new position, set some variables and get the new character
+% and category from the query. Then unpack the array of active
+% threads, and clear it by resetting its length
+% (\texttt{max_thread}). This results in a sequence of
+% \cs{@@_use_state_and_submatches:w} \meta{state}|,|\meta{submatch-clist}|;| and
+% we consider those states one by one in order. As soon as a thread
+% succeeds, exit the step, and, if there are threads to consider at the
+% next position, and we have not reached the end of the string,
+% repeat the loop. Otherwise, the last thread that succeeded is the
+% match. We explain the \texttt{fresh_thread} business when
+% describing \cs{@@_action_wildcard:}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_match_one_token:nnN #1#2#3
+ {
+ \int_add:Nn \l_@@_step_int { 2 }
+ \int_incr:N \l_@@_curr_pos_int
+ \int_set_eq:NN \l_@@_last_char_int \l_@@_curr_char_int
+ \cs_set_eq:NN \@@_maybe_compute_ccc: \@@_compute_case_changed_char:
+ \tl_set:Nn \l_@@_curr_token_tl {#1}
+ \int_set:Nn \l_@@_curr_char_int {#2}
+ \int_set:Nn \l_@@_curr_catcode_int { "#3 }
+ \tl_build_put_right:Ne \l_@@_matched_analysis_tl
+ { \exp_not:o \l_@@_curr_analysis_tl }
+ \tl_set:Nn \l_@@_curr_analysis_tl { { {#1} {#2} #3 } }
+ \use:e
+ {
+ \int_set_eq:NN \l_@@_max_thread_int \l_@@_min_thread_int
+ \int_step_function:nnN
+ \l_@@_min_thread_int
+ { \l_@@_max_thread_int - \c_one_int }
+ \@@_match_one_active:n
+ }
+ \prg_break_point:
+ \bool_set_false:N \l_@@_fresh_thread_bool
+ \if_int_compare:w \l_@@_max_thread_int > \l_@@_min_thread_int
+ \if_int_compare:w -2 < \l_@@_curr_char_int
+ \exp_after:wN \use_i:nn
+ \fi:
+ \fi:
+ \l_@@_every_match_tl
+ }
+\cs_new:Npn \@@_match_one_active:n #1
+ {
+ \@@_use_state_and_submatches:w
+ \__kernel_intarray_range_to_clist:Nnn
+ \g_@@_thread_info_intarray
+ { \c_one_int + #1 * (\l_@@_capturing_group_int * 2 + \c_one_int) }
+ { (\c_one_int + #1) * (\l_@@_capturing_group_int * 2 + \c_one_int) }
+ ;
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Using states of the \textsc{nfa}}
+%
+% \begin{macro}{\@@_use_state:}
+% Use the current \textsc{nfa} instruction. The state is initially
+% marked as belonging to the current \texttt{step}: this allows normal
+% free transition to repeat, but group-repeating transitions
+% won't. Once we are done exploring all the branches it spawned, the
+% state is marked as $\texttt{step}+1$: any thread hitting it at that
+% point will be terminated.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_use_state:
+ {
+ \__kernel_intarray_gset:Nnn \g_@@_state_active_intarray
+ \l_@@_curr_state_int \l_@@_step_int
+ \@@_toks_use:w \l_@@_curr_state_int
+ \__kernel_intarray_gset:Nnn \g_@@_state_active_intarray
+ \l_@@_curr_state_int
+ { \@@_int_eval:w \l_@@_step_int + \c_one_int \scan_stop: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_use_state_and_submatches:w}
+% This function is called as one item in the array of active threads
+% after that array has been unpacked for a new step. Update the
+% \texttt{curr_state} and \texttt{curr_submatches} and use the
+% state if it has not yet been encountered at this step.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_use_state_and_submatches:w #1 , #2 ;
+ {
+ \int_set:Nn \l_@@_curr_state_int {#1}
+ \if_int_compare:w
+ \__kernel_intarray_item:Nn \g_@@_state_active_intarray
+ \l_@@_curr_state_int
+ < \l_@@_step_int
+ \tl_set:Nn \l_@@_curr_submatches_tl { #2 , }
+ \exp_after:wN \@@_use_state:
+ \fi:
+ \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Actions when matching}
+%
+% \begin{macro}{\@@_action_start_wildcard:N}
+% For an unanchored match, state $0$ has a free transition to the next
+% and a costly one to itself, to repeat at the next position. To catch
+% repeated identical empty matches, we need to know if a successful
+% thread corresponds to an empty match. The instruction resetting
+% \cs{l_@@_fresh_thread_bool} may be skipped by a successful
+% thread, hence we had to add it to \cs{@@_match_one_token:nnN} too.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_action_start_wildcard:N #1
+ {
+ \bool_set_true:N \l_@@_fresh_thread_bool
+ \@@_action_free:n {1}
+ \bool_set_false:N \l_@@_fresh_thread_bool
+ \bool_if:NT #1 { \@@_action_cost:n {0} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_action_free:n, \@@_action_free_group:n}
+% \begin{macro}{\@@_action_free_aux:nn}
+% These functions copy a thread after checking that the \textsc{nfa}
+% state has not already been used at this position. If not, store
+% submatches in the new state, and insert the instructions for that
+% state in the input stream. Then restore the old value of
+% \cs{l_@@_curr_state_int} and of the current submatches. The
+% two types of free transitions differ by how they test that the state
+% has not been encountered yet: the \texttt{group} version is
+% stricter, and will not use a state if it was used earlier in the
+% current thread, hence forcefully breaking the loop, while the
+% \enquote{normal} version will revisit a state even within the thread
+% itself.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_action_free:n
+ { \@@_action_free_aux:nn { > \l_@@_step_int \else: } }
+\cs_new_protected:Npn \@@_action_free_group:n
+ { \@@_action_free_aux:nn { < \l_@@_step_int } }
+\cs_new_protected:Npn \@@_action_free_aux:nn #1#2
+ {
+ \use:e
+ {
+ \int_add:Nn \l_@@_curr_state_int {#2}
+ \exp_not:n
+ {
+ \if_int_compare:w
+ \__kernel_intarray_item:Nn \g_@@_state_active_intarray
+ \l_@@_curr_state_int
+ #1
+ \exp_after:wN \@@_use_state:
+ \fi:
+ }
+ \int_set:Nn \l_@@_curr_state_int
+ { \int_use:N \l_@@_curr_state_int }
+ \tl_set:Nn \exp_not:N \l_@@_curr_submatches_tl
+ { \exp_not:o \l_@@_curr_submatches_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_action_cost:n}
+% A transition which consumes the current character and shifts the
+% state by |#1|. The resulting state is stored in the appropriate array
+% for use at the next position, and we also store the current
+% submatches.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_action_cost:n #1
+ {
+ \exp_args:No \@@_store_state:n
+ { \tex_the:D \@@_int_eval:w \l_@@_curr_state_int + #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_store_state:n}
+% \begin{macro}{\@@_store_submatches:}
+% Put the given state and current submatch information in
+% \cs{g_@@_thread_info_intarray}, and increment the length of the
+% array.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_store_state:n #1
+ {
+ \exp_args:No \@@_store_submatches:nn
+ \l_@@_curr_submatches_tl {#1}
+ \int_incr:N \l_@@_max_thread_int
+ }
+\cs_new_protected:Npn \@@_store_submatches:nn #1#2
+ {
+ \__kernel_intarray_gset_range_from_clist:Nnn
+ \g_@@_thread_info_intarray
+ {
+ \@@_int_eval:w
+ \c_one_int + \l_@@_max_thread_int *
+ (\l_@@_capturing_group_int * 2 + \c_one_int)
+ }
+ { #2 , #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_disable_submatches:}
+% Some user functions don't require tracking submatches.
+% We get a performance improvement by simply defining the
+% relevant functions to remove their argument and do nothing
+% with it.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_disable_submatches:
+ {
+ \cs_set_protected:Npn \@@_store_submatches:n ##1 { }
+ \cs_set_protected:Npn \@@_action_submatch:nN ##1##2 { }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_action_submatch:nN, \@@_action_submatch_aux:w, \@@_action_submatch_auxii:w, \@@_action_submatch_auxiii:w, \@@_action_submatch_auxiv:w}
+% Update the current submatches with the information from the current
+% position. Maybe a bottleneck.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_action_submatch:nN #1#2
+ {
+ \exp_after:wN \@@_action_submatch_aux:w
+ \l_@@_curr_submatches_tl ; {#1} #2
+ }
+\cs_new_protected:Npn \@@_action_submatch_aux:w #1 ; #2#3
+ {
+ \tl_set:Ne \l_@@_curr_submatches_tl
+ {
+ \prg_replicate:nn
+ { #2 \if_meaning:w > #3 + \l_@@_capturing_group_int \fi: }
+ { \@@_action_submatch_auxii:w }
+ \@@_action_submatch_auxiii:w
+ #1
+ }
+ }
+\cs_new:Npn \@@_action_submatch_auxii:w
+ #1 \@@_action_submatch_auxiii:w #2 ,
+ { #2 , #1 \@@_action_submatch_auxiii:w }
+\cs_new:Npn \@@_action_submatch_auxiii:w #1 ,
+ { \int_use:N \l_@@_curr_pos_int , }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_action_success:}
+% There is a successful match when an execution path reaches the last
+% state in the \textsc{nfa}, unless this marks a second identical
+% empty match. Then mark that there was a successful match; it is
+% empty if it is \enquote{fresh}; and we store the current position
+% and submatches. The current step is then interrupted with
+% \cs{prg_break:}, and only paths with higher precedence are
+% pursued further. The values stored here may be overwritten by a
+% later success of a path with higher precedence.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_action_success:
+ {
+ \@@_if_two_empty_matches:F
+ {
+ \bool_set_true:N \l_@@_match_success_bool
+ \bool_set_eq:NN \l_@@_empty_success_bool
+ \l_@@_fresh_thread_bool
+ \int_set_eq:NN \l_@@_success_pos_int \l_@@_curr_pos_int
+ \int_set_eq:NN \l_@@_last_char_success_int \l_@@_last_char_int
+ \tl_build_begin:N \l_@@_matched_analysis_tl
+ \tl_set_eq:NN \l_@@_success_submatches_tl
+ \l_@@_curr_submatches_tl
+ \prg_break:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Replacement}
+%
+% \subsubsection{Variables and helpers used in replacement}
+%
+% \begin{variable}{\l_@@_replacement_csnames_int}
+% The behaviour of closing braces inside a replacement text depends on
+% whether a sequences |\c{| or |\u{| has been encountered. The number
+% of \enquote{open} such sequences that should be closed by |}| is
+% stored in \cs{l_@@_replacement_csnames_int}, and decreased by
+% $1$ by each |}|.
+% \begin{macrocode}
+\int_new:N \l_@@_replacement_csnames_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_replacement_category_tl, \l_@@_replacement_category_seq}
+% This sequence of letters is used to correctly restore categories in
+% nested constructions such as |\cL(abc\cD(_)d)|.
+% \begin{macrocode}
+\tl_new:N \l_@@_replacement_category_tl
+\seq_new:N \l_@@_replacement_category_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_balance_tl}
+% This token list holds the replacement text for
+% \cs{@@_replacement_balance_one_match:n} while it is being built
+% incrementally.
+% \begin{macrocode}
+\tl_new:N \g_@@_balance_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[rEXP]{\@@_replacement_balance_one_match:n}
+% This expects as an argument the first index of a set of entries in
+% \cs{g_@@_submatch_begin_intarray} (and related arrays) which hold the
+% submatch information for a given match. It
+% can be used within an integer expression to obtain the brace balance
+% incurred by performing the replacement on that match. This combines
+% the braces lost by removing the match, braces added by all the
+% submatches appearing in the replacement, and braces appearing
+% explicitly in the replacement. Even though it is always redefined
+% before use, we initialize it as for an empty replacement. An
+% important property is that concatenating several calls to that
+% function must result in a valid integer expression (hence a leading
+% |+| in the actual definition).
+% \begin{macrocode}
+\cs_new:Npn \@@_replacement_balance_one_match:n #1
+ { - \@@_submatch_balance:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_replacement_do_one_match:n}
+% The input is the same as \cs{@@_replacement_balance_one_match:n}.
+% This function is redefined to expand to the part of the token list
+% from the end of the previous match to a given match, followed by the
+% replacement text. Hence concatenating the result of this function
+% with all possible arguments (one call for each match), as well as
+% the range from the end of the last match to the end of the string,
+% produces the fully replaced token list. The initialization does
+% not matter, but (as an example) we set it as for an empty replacement.
+% \begin{macrocode}
+\cs_new:Npn \@@_replacement_do_one_match:n #1
+ {
+ \@@_query_range:nn
+ { \__kernel_intarray_item:Nn \g_@@_submatch_prev_intarray {#1} }
+ { \__kernel_intarray_item:Nn \g_@@_submatch_begin_intarray {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_exp_not:N}
+% This function lets us navigate around the fact that the primitive
+% \cs{exp_not:n} requires a braced argument. As far as I can tell, it
+% is only needed if the user tries to include in the replacement text
+% a control sequence set equal to a macro parameter character, such as
+% \cs{c_parameter_token}. Indeed, within an \texttt{e}/\texttt{x}-expanding
+% assignment, \cs{exp_not:N}~|#| behaves as a single |#|, whereas
+% \cs{exp_not:n}~|{#}| behaves as a doubled |##|.
+% \begin{macrocode}
+\cs_new:Npn \@@_replacement_exp_not:N #1 { \exp_not:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_exp_not:V}
+% This is used for the implementation of~|\u|, and it gets redefined
+% for \cs{peek_regex_replace_once:nnTF}.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_replacement_exp_not:V \exp_not:V
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Query and brace balance}
+%
+% \begin{macro}[rEXP]{\@@_query_range:nn}
+% \begin{macro}[rEXP]{\@@_query_range_loop:ww}
+% When it is time to extract submatches from the token list, the
+% various tokens are stored in \tn{toks} registers numbered from
+% \cs{l_@@_min_pos_int} inclusive to \cs{l_@@_max_pos_int}
+% exclusive. The function \cs{@@_query_range:nn} \Arg{min}
+% \Arg{max} unpacks registers from the position \meta{min} to the
+% position $\meta{max}-1$ included. Once this is expanded, a second
+% \texttt{e}-expansion results in the actual tokens from the
+% query. That second expansion is only done by user functions at the
+% very end of their operation, after checking (and correcting) the
+% brace balance first.
+% \begin{macrocode}
+\cs_new:Npn \@@_query_range:nn #1#2
+ {
+ \exp_after:wN \@@_query_range_loop:ww
+ \int_value:w \@@_int_eval:w #1 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w #2 ;
+ \prg_break_point:
+ }
+\cs_new:Npn \@@_query_range_loop:ww #1 ; #2 ;
+ {
+ \if_int_compare:w #1 < #2 \exp_stop_f:
+ \else:
+ \prg_break:n
+ \fi:
+ \@@_toks_use:w #1 \exp_stop_f:
+ \exp_after:wN \@@_query_range_loop:ww
+ \int_value:w \@@_int_eval:w #1 + \c_one_int ; #2 ;
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_query_submatch:n}
+% Find the start and end positions for a given submatch (of a given match).
+% \begin{macrocode}
+\cs_new:Npn \@@_query_submatch:n #1
+ {
+ \@@_query_range:nn
+ { \__kernel_intarray_item:Nn \g_@@_submatch_begin_intarray {#1} }
+ { \__kernel_intarray_item:Nn \g_@@_submatch_end_intarray {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_submatch_balance:n}
+% Every user function must result in a balanced token list (unbalanced
+% token lists cannot be stored by TeX). When we unpacked the query, we
+% kept track of the brace balance, hence the contribution from a given
+% range is the difference between the brace balances at the
+% \meta{max~pos} and \meta{min~pos}. These two positions are found in
+% the corresponding \enquote{submatch} arrays.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_submatch_balance:n #1
+ {
+ \tex_the:D \@@_int_eval:w
+ \@@_intarray_item:NnF \g_@@_balance_intarray
+ {
+ \__kernel_intarray_item:Nn
+ \g_@@_submatch_end_intarray {#1}
+ }
+ \c_zero_int
+ -
+ \@@_intarray_item:NnF \g_@@_balance_intarray
+ {
+ \__kernel_intarray_item:Nn
+ \g_@@_submatch_begin_intarray {#1}
+ }
+ \c_zero_int
+ \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Framework}
+%
+% \begin{macro}{\@@_replacement:n, \@@_replacement:e}
+% \begin{macro}{\@@_replacement_apply:Nn, \@@_replacement_set:n}
+% The replacement text is built incrementally. We keep track in
+% \cs{l_@@_balance_int} of the balance of explicit begin- and
+% end-group tokens and we store in \cs{g_@@_balance_tl} some
+% code to compute the brace balance from submatches (see its
+% description). Detect unescaped right braces, and escaped characters,
+% with trailing \cs{prg_do_nothing:} because some of the later
+% function look-ahead. Once the whole replacement text has been
+% parsed, make sure that there is no open csname. Finally, define the
+% \texttt{balance_one_match} and \texttt{do_one_match} functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replacement:n
+ { \@@_replacement_apply:Nn \@@_replacement_set:n }
+\cs_new_protected:Npn \@@_replacement_apply:Nn #1#2
+ {
+ \group_begin:
+ \tl_build_begin:N \l_@@_build_tl
+ \int_zero:N \l_@@_balance_int
+ \tl_gclear:N \g_@@_balance_tl
+ \@@_escape_use:nnnn
+ {
+ \if_charcode:w \c_right_brace_str ##1
+ \@@_replacement_rbrace:N
+ \else:
+ \if_charcode:w \c_left_brace_str ##1
+ \@@_replacement_lbrace:N
+ \else:
+ \@@_replacement_normal:n
+ \fi:
+ \fi:
+ ##1
+ }
+ { \@@_replacement_escaped:N ##1 }
+ { \@@_replacement_normal:n ##1 }
+ {#2}
+ \prg_do_nothing: \prg_do_nothing:
+ \if_int_compare:w \l_@@_replacement_csnames_int > \c_zero_int
+ \msg_error:nne { regex } { replacement-missing-rbrace }
+ { \int_use:N \l_@@_replacement_csnames_int }
+ \tl_build_put_right:Ne \l_@@_build_tl
+ { \prg_replicate:nn \l_@@_replacement_csnames_int \cs_end: }
+ \fi:
+ \seq_if_empty:NF \l_@@_replacement_category_seq
+ {
+ \msg_error:nne { regex } { replacement-missing-rparen }
+ { \seq_count:N \l_@@_replacement_category_seq }
+ \seq_clear:N \l_@@_replacement_category_seq
+ }
+ \tl_gput_right:Ne \g_@@_balance_tl
+ { + \int_use:N \l_@@_balance_int }
+ \tl_build_end:N \l_@@_build_tl
+ \exp_args:NNo
+ \group_end:
+ #1 \l_@@_build_tl
+ }
+\cs_generate_variant:Nn \@@_replacement:n { e }
+\cs_new_protected:Npn \@@_replacement_set:n #1
+ {
+ \cs_set:Npn \@@_replacement_do_one_match:n ##1
+ {
+ \@@_query_range:nn
+ {
+ \__kernel_intarray_item:Nn
+ \g_@@_submatch_prev_intarray {##1}
+ }
+ {
+ \__kernel_intarray_item:Nn
+ \g_@@_submatch_begin_intarray {##1}
+ }
+ #1
+ }
+ \exp_args:Nno \use:n
+ { \cs_gset:Npn \@@_replacement_balance_one_match:n ##1 }
+ {
+ \g_@@_balance_tl
+ - \@@_submatch_balance:n {##1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_case_replacement:n, \@@_case_replacement:e}
+% \begin{macrocode}
+\tl_new:N \g_@@_case_replacement_tl
+\tl_new:N \g_@@_case_balance_tl
+\cs_new_protected:Npn \@@_case_replacement:n #1
+ {
+ \tl_gset:Nn \g_@@_case_balance_tl
+ {
+ \if_case:w
+ \__kernel_intarray_item:Nn
+ \g_@@_submatch_case_intarray {##1}
+ }
+ \tl_gset_eq:NN \g_@@_case_replacement_tl \g_@@_case_balance_tl
+ \tl_map_tokens:nn {#1}
+ { \@@_replacement_apply:Nn \@@_case_replacement_aux:n }
+ \tl_gset:No \g_@@_balance_tl
+ { \g_@@_case_balance_tl \fi: }
+ \exp_args:No \@@_replacement_set:n
+ { \g_@@_case_replacement_tl \fi: }
+ }
+\cs_generate_variant:Nn \@@_case_replacement:n { e }
+\cs_new_protected:Npn \@@_case_replacement_aux:n #1
+ {
+ \tl_gput_right:Nn \g_@@_case_replacement_tl { \or: #1 }
+ \tl_gput_right:No \g_@@_case_balance_tl
+ { \exp_after:wN \or: \g_@@_balance_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_put:n}
+% This gets redefined for \cs{peek_regex_replace_once:nnTF}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replacement_put:n
+ { \tl_build_put_right:Nn \l_@@_build_tl }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_normal:n, \@@_replacement_normal_aux:N}
+% Most characters are simply sent to the output by
+% \cs{tl_build_put_right:Nn}, unless a particular category code has been
+% requested: then \cs{@@_replacement_c_A:w} or a similar auxiliary is
+% called. One exception is right parentheses, which restore the
+% category code in place before the group started. Note that the
+% sequence is non-empty there: it contains an empty entry
+% corresponding to the initial value of
+% \cs{l_@@_replacement_category_tl}.
+% The argument |#1| is a single character (including the case of a catcode-other space).
+% In case no specific catcode is requested, we taked into account the
+% current catcode regime (at the time the replacement is performed)
+% as much as reasonable, with all impossible catcodes (escape,
+% newline, etc.) being mapped to \enquote{other}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replacement_normal:n #1
+ {
+ \int_compare:nNnTF \l_@@_replacement_csnames_int > \c_zero_int
+ { \exp_args:No \@@_replacement_put:n { \token_to_str:N #1 } }
+ {
+ \tl_if_empty:NTF \l_@@_replacement_category_tl
+ { \@@_replacement_normal_aux:N #1 }
+ { % (
+ \token_if_eq_charcode:NNTF #1 )
+ {
+ \seq_pop:NN \l_@@_replacement_category_seq
+ \l_@@_replacement_category_tl
+ }
+ {
+ \use:c { @@_replacement_c_ \l_@@_replacement_category_tl :w }
+ ? #1
+ }
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_replacement_normal_aux:N #1
+ {
+ \token_if_eq_charcode:NNTF #1 \c_space_token
+ { \@@_replacement_c_S:w }
+ {
+ \exp_after:wN \exp_after:wN
+ \if_case:w \tex_catcode:D `#1 \exp_stop_f:
+ \@@_replacement_c_O:w
+ \or: \@@_replacement_c_B:w
+ \or: \@@_replacement_c_E:w
+ \or: \@@_replacement_c_M:w
+ \or: \@@_replacement_c_T:w
+ \or: \@@_replacement_c_O:w
+ \or: \@@_replacement_c_P:w
+ \or: \@@_replacement_c_U:w
+ \or: \@@_replacement_c_D:w
+ \or: \@@_replacement_c_O:w
+ \or: \@@_replacement_c_S:w
+ \or: \@@_replacement_c_L:w
+ \or: \@@_replacement_c_O:w
+ \or: \@@_replacement_c_A:w
+ \else: \@@_replacement_c_O:w
+ \fi:
+ }
+ ? #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_escaped:N}
+% As in parsing a regular expression, we use an auxiliary built from
+% |#1| if defined. Otherwise, check for escaped digits (standing from
+% submatches from $0$ to $9$): anything else is a raw character.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replacement_escaped:N #1
+ {
+ \cs_if_exist_use:cF { @@_replacement_#1:w }
+ {
+ \if_int_compare:w \c_one_int < 1#1 \exp_stop_f:
+ \@@_replacement_put_submatch:n {#1}
+ \else:
+ \@@_replacement_normal:n {#1}
+ \fi:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Submatches}
+%
+% \begin{macro}{\@@_replacement_put_submatch:n, \@@_replacement_put_submatch_aux:n}
+% Insert a submatch in the replacement text. This is dropped if the
+% submatch number is larger than the number of capturing groups.
+% Unless the submatch appears inside a |\c{...}| or |\u{...}|
+% construction, it must be taken into account in the brace balance.
+% Later on, |##1| will be replaced by a pointer to the $0$-th submatch for a
+% given match.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replacement_put_submatch:n #1
+ {
+ \if_int_compare:w #1 < \l_@@_capturing_group_int
+ \@@_replacement_put_submatch_aux:n {#1}
+ \else:
+ \msg_expandable_error:nnff { regex } { submatch-too-big }
+ {#1} { \int_eval:n { \l_@@_capturing_group_int - \c_one_int } }
+ \fi:
+ }
+\cs_new_protected:Npn \@@_replacement_put_submatch_aux:n #1
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \@@_query_submatch:n { \@@_int_eval:w #1 + ##1 \scan_stop: } }
+ \if_int_compare:w \l_@@_replacement_csnames_int = \c_zero_int
+ \tl_gput_right:Nn \g_@@_balance_tl
+ { + \@@_submatch_balance:n { \@@_int_eval:w #1 + ##1 \scan_stop: } }
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_g:w}
+% \begin{macro}[rEXP]{\@@_replacement_g_digits:NN}
+% Grab digits for the |\g| escape sequence in a primitive assignment
+% to the integer \cs{l_@@_internal_a_int}. At the end of the run of
+% digits, check that it ends with a right brace.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replacement_g:w #1#2
+ {
+ \token_if_eq_meaning:NNTF #1 \@@_replacement_lbrace:N
+ { \l_@@_internal_a_int = \@@_replacement_g_digits:NN }
+ { \@@_replacement_error:NNN g #1 #2 }
+ }
+\cs_new:Npn \@@_replacement_g_digits:NN #1#2
+ {
+ \token_if_eq_meaning:NNTF #1 \@@_replacement_normal:n
+ {
+ \if_int_compare:w \c_one_int < 1#2 \exp_stop_f:
+ #2
+ \exp_after:wN \use_i:nnn
+ \exp_after:wN \@@_replacement_g_digits:NN
+ \else:
+ \exp_stop_f:
+ \exp_after:wN \@@_replacement_error:NNN
+ \exp_after:wN g
+ \fi:
+ }
+ {
+ \exp_stop_f:
+ \if_meaning:w \@@_replacement_rbrace:N #1
+ \exp_args:No \@@_replacement_put_submatch:n
+ { \int_use:N \l_@@_internal_a_int }
+ \exp_after:wN \use_none:nn
+ \else:
+ \exp_after:wN \@@_replacement_error:NNN
+ \exp_after:wN g
+ \fi:
+ }
+ #1 #2
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Csnames in replacement}
+%
+% \begin{macro}{\@@_replacement_c:w}
+% |\c| may only be followed by an unescaped character. If followed by
+% a left brace, start a control sequence by calling an auxiliary
+% common with |\u|. Otherwise test whether the category is known; if
+% it is not, complain.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replacement_c:w #1#2
+ {
+ \token_if_eq_meaning:NNTF #1 \@@_replacement_normal:n
+ {
+ \cs_if_exist:cTF { @@_replacement_c_#2:w }
+ { \@@_replacement_cat:NNN #2 }
+ { \@@_replacement_error:NNN c #1#2 }
+ }
+ {
+ \token_if_eq_meaning:NNTF #1 \@@_replacement_lbrace:N
+ { \@@_replacement_cu_aux:Nw \@@_replacement_exp_not:N }
+ { \@@_replacement_error:NNN c #1#2 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_cu_aux:Nw}
+% Start a control sequence with \cs{cs:w}, protected
+% from expansion by |#1| (either \cs{@@_replacement_exp_not:N} or
+% \cs{exp_not:V}), or turned to a string by \cs{tl_to_str:V} if inside
+% another csname construction |\c| or |\u|. We use \cs{tl_to_str:V}
+% rather than \cs{tl_to_str:N} to deal with integers and other
+% registers.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replacement_cu_aux:Nw #1
+ {
+ \if_case:w \l_@@_replacement_csnames_int
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \exp_not:n { \exp_after:wN #1 \cs:w } }
+ \else:
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \exp_not:n { \exp_after:wN \tl_to_str:V \cs:w } }
+ \fi:
+ \int_incr:N \l_@@_replacement_csnames_int
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_u:w}
+% Check that |\u| is followed by a left brace. If so, start a control
+% sequence with \cs{cs:w}, which is then unpacked either with
+% \cs{exp_not:V} or \cs{tl_to_str:V} depending on the current context.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replacement_u:w #1#2
+ {
+ \token_if_eq_meaning:NNTF #1 \@@_replacement_lbrace:N
+ { \@@_replacement_cu_aux:Nw \@@_replacement_exp_not:V }
+ { \@@_replacement_error:NNN u #1#2 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_rbrace:N}
+% Within a |\c{...}| or |\u{...}| construction, end the control
+% sequence, and decrease the brace count. Otherwise, this is a raw
+% right brace.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replacement_rbrace:N #1
+ {
+ \if_int_compare:w \l_@@_replacement_csnames_int > \c_zero_int
+ \tl_build_put_right:Nn \l_@@_build_tl { \cs_end: }
+ \int_decr:N \l_@@_replacement_csnames_int
+ \else:
+ \@@_replacement_normal:n {#1}
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_lbrace:N}
+% Within a |\c{...}| or |\u{...}| construction, this is
+% forbidden. Otherwise, this is a raw left brace.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replacement_lbrace:N #1
+ {
+ \if_int_compare:w \l_@@_replacement_csnames_int > \c_zero_int
+ \msg_error:nnn { regex } { cu-lbrace } { u }
+ \else:
+ \@@_replacement_normal:n {#1}
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Characters in replacement}
+%
+% \begin{macro}{\@@_replacement_cat:NNN}
+% Here, |#1| is a letter among |BEMTPUDSLOA| and |#2#3| denote the
+% next character. Complain if we reach the end of the replacement or
+% if the construction appears inside |\c{|\ldots{}|}| or
+% |\u{|\ldots{}|}|, and detect the case of a parenthesis. In that
+% case, store the current category in a sequence and switch to a new
+% one.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replacement_cat:NNN #1#2#3
+ {
+ \token_if_eq_meaning:NNTF \prg_do_nothing: #3
+ { \msg_error:nn { regex } { replacement-catcode-end } }
+ {
+ \int_compare:nNnTF \l_@@_replacement_csnames_int > \c_zero_int
+ {
+ \msg_error:nnnn
+ { regex } { replacement-catcode-in-cs } {#1} {#3}
+ #2 #3
+ }
+ {
+ \@@_two_if_eq:NNNNTF #2 #3 \@@_replacement_normal:n (
+ {
+ \seq_push:NV \l_@@_replacement_category_seq
+ \l_@@_replacement_category_tl
+ \tl_set:Nn \l_@@_replacement_category_tl {#1}
+ }
+ {
+ \token_if_eq_meaning:NNT #2 \@@_replacement_escaped:N
+ {
+ \@@_char_if_alphanumeric:NTF #3
+ {
+ \msg_error:nnnn
+ { regex } { replacement-catcode-escaped }
+ {#1} {#3}
+ }
+ { }
+ }
+ \use:c { @@_replacement_c_#1:w } #2 #3
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% We now need to change the category code of the null character many
+% times, hence work in a group. The catcode-specific macros below are
+% defined in alphabetical order; if you are trying to understand the
+% code, start from the end of the alphabet as those categories are
+% simpler than active or begin-group.
+% \begin{macrocode}
+\group_begin:
+% \end{macrocode}
+%
+% \begin{macro}{\@@_replacement_char:nNN}
+% The only way to produce an arbitrary character--catcode pair is to
+% use the \tn{lowercase} or \tn{uppercase} primitives. This is a
+% wrapper for our purposes. The first argument is the null character
+% with various catcodes. The second and third arguments are grabbed
+% from the input stream: |#3| is the character whose character code to
+% reproduce. We could use \cs{char_generate:nn} but only for some
+% catcodes (active characters and spaces are not supported).
+% \begin{macrocode}
+ \cs_new_protected:Npn \@@_replacement_char:nNN #1#2#3
+ {
+ \tex_lccode:D \c_zero_int = `#3 \scan_stop:
+ \tex_lowercase:D { \@@_replacement_put:n {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_c_A:w}
+% For an active character, expansion must be avoided, twice because we
+% later do two \texttt{e}-expansions, to unpack \tn{toks} for the
+% query, and to expand their contents to tokens of the query.
+% \begin{macrocode}
+ \char_set_catcode_active:N \^^@
+ \cs_new_protected:Npn \@@_replacement_c_A:w
+ { \@@_replacement_char:nNN { \exp_not:n { \exp_not:N ^^@ } } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_c_B:w}
+% An explicit begin-group token increases the balance, unless within a
+% |\c{...}| or |\u{...}| construction. Add the desired begin-group
+% character, using the standard \cs{if_false:} trick. We eventually
+% \texttt{e}-expand twice. The first time must yield a balanced token
+% list, and the second one gives the bare begin-group token. The
+% \cs{exp_after:wN} is not strictly needed, but is more consistent
+% with \pkg{l3tl-analysis}.
+% \begin{macrocode}
+ \char_set_catcode_group_begin:N \^^@
+ \cs_new_protected:Npn \@@_replacement_c_B:w
+ {
+ \if_int_compare:w \l_@@_replacement_csnames_int = \c_zero_int
+ \int_incr:N \l_@@_balance_int
+ \fi:
+ \@@_replacement_char:nNN
+ { \exp_not:n { \exp_after:wN ^^@ \if_false: } \fi: } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_c_C:w}
+% This is not quite catcode-related: when the user requests a
+% character with category \enquote{control sequence}, the
+% one-character control symbol is returned. As for the active
+% character, we prepare for two \texttt{e}-expansions.
+% \begin{macrocode}
+ \cs_new_protected:Npn \@@_replacement_c_C:w #1#2
+ {
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \exp_not:N \@@_replacement_exp_not:N \exp_not:c {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_c_D:w}
+% Subscripts fit the mould: \tn{lowercase} the null byte with the
+% correct category.
+% \begin{macrocode}
+ \char_set_catcode_math_subscript:N \^^@
+ \cs_new_protected:Npn \@@_replacement_c_D:w
+ { \@@_replacement_char:nNN { ^^@ } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_c_E:w}
+% Similar to the begin-group case, the second \texttt{e}-expansion
+% produces the bare end-group token.
+% \begin{macrocode}
+ \char_set_catcode_group_end:N \^^@
+ \cs_new_protected:Npn \@@_replacement_c_E:w
+ {
+ \if_int_compare:w \l_@@_replacement_csnames_int = \c_zero_int
+ \int_decr:N \l_@@_balance_int
+ \fi:
+ \@@_replacement_char:nNN
+ { \exp_not:n { \if_false: { \fi: ^^@ } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_c_L:w}
+% Simply \tn{lowercase} a letter null byte to produce an arbitrary letter.
+% \begin{macrocode}
+ \char_set_catcode_letter:N \^^@
+ \cs_new_protected:Npn \@@_replacement_c_L:w
+ { \@@_replacement_char:nNN { ^^@ } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_c_M:w}
+% No surprise here, we lowercase the null math toggle.
+% \begin{macrocode}
+ \char_set_catcode_math_toggle:N \^^@
+ \cs_new_protected:Npn \@@_replacement_c_M:w
+ { \@@_replacement_char:nNN { ^^@ } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_c_O:w}
+% Lowercase an other null byte.
+% \begin{macrocode}
+ \char_set_catcode_other:N \^^@
+ \cs_new_protected:Npn \@@_replacement_c_O:w
+ { \@@_replacement_char:nNN { ^^@ } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_c_P:w}
+% For macro parameters, expansion is a tricky issue. We need to
+% prepare for two \texttt{e}-expansions and passing through various
+% macro definitions. Note that we cannot replace one \cs{exp_not:n} by
+% doubling the macro parameter characters because this would misbehave
+% if a mischievous user asks for |\c{\cP\#}|, since that macro
+% parameter character would be doubled.
+% \begin{macrocode}
+ \char_set_catcode_parameter:N \^^@
+ \cs_new_protected:Npn \@@_replacement_c_P:w
+ {
+ \@@_replacement_char:nNN
+ { \exp_not:n { \exp_not:n { ^^@^^@^^@^^@ } } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_c_S:w}
+% Spaces are normalized on input by \TeX{} to have character code
+% $32$. It is in fact impossible to get a token with character code
+% $0$ and category code $10$. Hence we use $32$ instead of $0$ as our
+% base character.
+% \begin{macrocode}
+ \cs_new_protected:Npn \@@_replacement_c_S:w #1#2
+ {
+ \if_int_compare:w `#2 = \c_zero_int
+ \msg_error:nn { regex } { replacement-null-space }
+ \fi:
+ \tex_lccode:D `\ = `#2 \scan_stop:
+ \tex_lowercase:D { \@@_replacement_put:n {~} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_c_T:w}
+% No surprise for alignment tabs here. Those are surrounded by the
+% appropriate braces whenever necessary, hence they don't cause
+% trouble in alignment settings.
+% \begin{macrocode}
+ \char_set_catcode_alignment:N \^^@
+ \cs_new_protected:Npn \@@_replacement_c_T:w
+ { \@@_replacement_char:nNN { ^^@ } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replacement_c_U:w}
+% Simple call to \cs{@@_replacement_char:nNN} which lowercases the
+% math superscript |^^@|.
+% \begin{macrocode}
+ \char_set_catcode_math_superscript:N \^^@
+ \cs_new_protected:Npn \@@_replacement_c_U:w
+ { \@@_replacement_char:nNN { ^^@ } }
+% \end{macrocode}
+% \end{macro}
+%
+% Restore the catcode of the null byte.
+% \begin{macrocode}
+\group_end:
+% \end{macrocode}
+%
+% \subsubsection{An error}
+%
+% \begin{macro}{\@@_replacement_error:NNN}
+% Simple error reporting by calling one of the messages
+% \texttt{replacement-c}, \texttt{replacement-g}, or
+% \texttt{replacement-u}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replacement_error:NNN #1#2#3
+ {
+ \msg_error:nne { regex } { replacement-#1 } {#3}
+ #2 #3
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{User functions}
+%
+% \begin{macro}{\regex_new:N}
+% Before being assigned a sensible value, a regex variable matches
+% nothing.
+% \begin{macrocode}
+\cs_new_protected:Npn \regex_new:N #1
+ { \cs_new_eq:NN #1 \c_@@_no_match_regex }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_tmpa_regex, \l_tmpb_regex, \g_tmpa_regex, \g_tmpb_regex}
+% The usual scratch space.
+% \begin{macrocode}
+\regex_new:N \l_tmpa_regex
+\regex_new:N \l_tmpb_regex
+\regex_new:N \g_tmpa_regex
+\regex_new:N \g_tmpb_regex
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\regex_set:Nn, \regex_gset:Nn, \regex_const:Nn}
+% Compile, then store the result in the user variable with the
+% appropriate assignment function.
+% \begin{macrocode}
+\cs_new_protected:Npn \regex_set:Nn #1#2
+ {
+ \@@_compile:n {#2}
+ \tl_set_eq:NN #1 \l_@@_internal_regex
+ }
+\cs_new_protected:Npn \regex_gset:Nn #1#2
+ {
+ \@@_compile:n {#2}
+ \tl_gset_eq:NN #1 \l_@@_internal_regex
+ }
+\cs_new_protected:Npn \regex_const:Nn #1#2
+ {
+ \@@_compile:n {#2}
+ \tl_const:Ne #1 { \exp_not:o \l_@@_internal_regex }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \regex_show:n, \regex_log:n, \@@_show:Nn,
+% \regex_show:N, \regex_log:N, \@@_show:NN
+% }
+% User functions: the \texttt{n} variant requires compilation first.
+% Then show the variable with some appropriate text. The auxiliary
+% \cs{@@_show:N} is defined in a different section.
+% \begin{macrocode}
+\cs_new_protected:Npn \regex_show:n { \@@_show:Nn \msg_show:nneeee }
+\cs_new_protected:Npn \regex_log:n { \@@_show:Nn \msg_log:nneeee }
+\cs_new_protected:Npn \@@_show:Nn #1#2
+ {
+ \@@_compile:n {#2}
+ \@@_show:N \l_@@_internal_regex
+ #1 { regex } { show }
+ { \tl_to_str:n {#2} } { }
+ { \l_@@_internal_a_tl } { }
+ }
+\cs_new_protected:Npn \regex_show:N { \@@_show:NN \msg_show:nneeee }
+\cs_new_protected:Npn \regex_log:N { \@@_show:NN \msg_log:nneeee }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_chk_tl_type:NnnT #2 { regex }
+ { \exp_args:No \@@_clean_regex:n {#2} }
+ {
+ \@@_show:N #2
+ #1 { regex } { show }
+ { } { \token_to_str:N #2 }
+ { \l_@@_internal_a_tl } { }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]
+% {
+% \regex_match:nn, \regex_match:nV,
+% \regex_match:Nn, \regex_match:NV
+% }
+% Those conditionals are based on a common auxiliary defined
+% later. Its first argument builds the \textsc{nfa} corresponding to
+% the regex, and the second argument is the query token list. Once we
+% have performed the match, convert the resulting boolean to
+% \cs{prg_return_true:} or \texttt{false}.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \regex_match:nn #1#2 { T , F , TF }
+ {
+ \@@_if_match:nn { \@@_build:n {#1} } {#2}
+ \@@_return:
+ }
+\prg_generate_conditional_variant:Nnn \regex_match:nn { nV } { T , F , TF }
+\prg_new_protected_conditional:Npnn \regex_match:Nn #1#2 { T , F , TF }
+ {
+ \@@_if_match:nn { \@@_build:N #1 } {#2}
+ \@@_return:
+ }
+\prg_generate_conditional_variant:Nnn \regex_match:Nn { NV } { T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\regex_count:nnN, \regex_count:nVN, \regex_count:NnN, \regex_count:NVN}
+% Again, use an auxiliary whose first argument builds the \textsc{nfa}.
+% \begin{macrocode}
+\cs_new_protected:Npn \regex_count:nnN #1
+ { \@@_count:nnN { \@@_build:n {#1} } }
+\cs_new_protected:Npn \regex_count:NnN #1
+ { \@@_count:nnN { \@@_build:N #1 } }
+\cs_generate_variant:Nn \regex_count:nnN { nV }
+\cs_generate_variant:Nn \regex_count:NnN { NV }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[noTF]{\regex_match_case:nn}
+% The auxiliary errors if |#1| has an odd number of items, and
+% otherwise it sets \cs{g_@@_case_int} according to which case was
+% found (zero if not found). The \texttt{true} branch leaves the
+% corresponding code in the input stream.
+% \begin{macrocode}
+\cs_new_protected:Npn \regex_match_case:nnTF #1#2#3
+ {
+ \@@_match_case:nnTF {#1} {#2}
+ {
+ \tl_item:nn {#1} { 2 * \g_@@_case_int }
+ #3
+ }
+ }
+\cs_new_protected:Npn \regex_match_case:nn #1#2
+ { \regex_match_case:nnTF {#1} {#2} { } { } }
+\cs_new_protected:Npn \regex_match_case:nnT #1#2#3
+ { \regex_match_case:nnTF {#1} {#2} {#3} { } }
+\cs_new_protected:Npn \regex_match_case:nnF #1#2
+ { \regex_match_case:nnTF {#1} {#2} { } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[noTF]
+% {
+% \regex_extract_once:nnN, \regex_extract_once:nVN,
+% \regex_extract_once:NnN, \regex_extract_once:NVN,
+% \regex_extract_all:nnN, \regex_extract_all:nVN,
+% \regex_extract_all:NnN, \regex_extract_all:NVN,
+% \regex_replace_once:nnN, \regex_replace_once:nVN,
+% \regex_replace_once:NnN, \regex_replace_once:NVN,
+% \regex_replace_all:nnN, \regex_replace_all:nVN,
+% \regex_replace_all:NnN, \regex_replace_all:NVN,
+% \regex_split:NnN, \regex_split:NVN,
+% \regex_split:nnN, \regex_split:nVN
+% }
+% We define here $40$ user functions, following a common pattern in
+% terms of \texttt{:nnN} auxiliaries, defined in the coming
+% subsections. The auxiliary is handed \cs{@@_build:n} or
+% \cs{@@_build:N} with the appropriate regex argument, then all
+% other necessary arguments (replacement text, token list, \emph{etc.}
+% The conditionals call \cs{@@_return:} to return either
+% \texttt{true} or \texttt{false} once matching has been performed.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1#2#3
+ {
+ \cs_new_protected:Npn #2 ##1 { #1 { \@@_build:n {##1} } }
+ \cs_new_protected:Npn #3 ##1 { #1 { \@@_build:N ##1 } }
+ \prg_new_protected_conditional:Npnn #2 ##1##2##3 { T , F , TF }
+ { #1 { \@@_build:n {##1} } {##2} ##3 \@@_return: }
+ \prg_new_protected_conditional:Npnn #3 ##1##2##3 { T , F , TF }
+ { #1 { \@@_build:N ##1 } {##2} ##3 \@@_return: }
+ \cs_generate_variant:Nn #2 { nV }
+ \prg_generate_conditional_variant:Nnn #2 { nV } { T , F , TF }
+ \cs_generate_variant:Nn #3 { NV }
+ \prg_generate_conditional_variant:Nnn #3 { NV } { T , F , TF }
+ }
+\@@_tmp:w \@@_extract_once:nnN
+ \regex_extract_once:nnN \regex_extract_once:NnN
+\@@_tmp:w \@@_extract_all:nnN
+ \regex_extract_all:nnN \regex_extract_all:NnN
+\@@_tmp:w \@@_replace_once:nnN
+ \regex_replace_once:nnN \regex_replace_once:NnN
+\@@_tmp:w \@@_replace_all:nnN
+ \regex_replace_all:nnN \regex_replace_all:NnN
+\@@_tmp:w \@@_split:nnN \regex_split:nnN \regex_split:NnN
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[noTF]{\regex_replace_case_once:nN}
+% If the input is bad (odd number of items) then take the false
+% branch. Otherwise, use the same auxiliary as
+% \cs{regex_replace_once:nnN}, but with more complicated code to build
+% the automaton, and to find what replacement text to use. The
+% \cs{tl_item:nn} is only expanded once we know the value of
+% \cs{g_@@_case_int}, namely which case matched.
+% \begin{macrocode}
+\cs_new_protected:Npn \regex_replace_case_once:nNTF #1#2
+ {
+ \int_if_odd:nTF { \tl_count:n {#1} }
+ {
+ \msg_error:nneeee { regex } { case-odd }
+ { \token_to_str:N \regex_replace_case_once:nN(TF) } { code }
+ { \tl_count:n {#1} } { \tl_to_str:n {#1} }
+ \use_ii:nn
+ }
+ {
+ \@@_replace_once_aux:nnN
+ { \@@_case_build:e { \@@_tl_odd_items:n {#1} } }
+ { \@@_replacement:e { \tl_item:nn {#1} { 2 * \g_@@_case_int } } }
+ #2
+ \bool_if:NTF \g_@@_success_bool
+ }
+ }
+\cs_new_protected:Npn \regex_replace_case_once:nN #1#2
+ { \regex_replace_case_once:nNTF {#1} {#2} { } { } }
+\cs_new_protected:Npn \regex_replace_case_once:nNT #1#2#3
+ { \regex_replace_case_once:nNTF {#1} {#2} {#3} { } }
+\cs_new_protected:Npn \regex_replace_case_once:nNF #1#2
+ { \regex_replace_case_once:nNTF {#1} {#2} { } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[noTF]{\regex_replace_case_all:nN}
+% If the input is bad (odd number of items) then take the false
+% branch. Otherwise, use the same auxiliary as
+% \cs{regex_replace_all:nnN}, but with more complicated code to build
+% the automaton, and to find what replacement text to use.
+% \begin{macrocode}
+\cs_new_protected:Npn \regex_replace_case_all:nNTF #1#2
+ {
+ \int_if_odd:nTF { \tl_count:n {#1} }
+ {
+ \msg_error:nneeee { regex } { case-odd }
+ { \token_to_str:N \regex_replace_case_all:nN(TF) } { code }
+ { \tl_count:n {#1} } { \tl_to_str:n {#1} }
+ \use_ii:nn
+ }
+ {
+ \@@_replace_all_aux:nnN
+ { \@@_case_build:e { \@@_tl_odd_items:n {#1} } }
+ { \@@_case_replacement:e { \@@_tl_even_items:n {#1} } }
+ #2
+ \bool_if:NTF \g_@@_success_bool
+ }
+ }
+\cs_new_protected:Npn \regex_replace_case_all:nN #1#2
+ { \regex_replace_case_all:nNTF {#1} {#2} { } { } }
+\cs_new_protected:Npn \regex_replace_case_all:nNT #1#2#3
+ { \regex_replace_case_all:nNTF {#1} {#2} {#3} { } }
+\cs_new_protected:Npn \regex_replace_case_all:nNF #1#2
+ { \regex_replace_case_all:nNTF {#1} {#2} { } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Variables and helpers for user functions}
+%
+% \begin{variable}{\l_@@_match_count_int}
+% The number of matches found so far is stored
+% in \cs{l_@@_match_count_int}. This is only used
+% in the \cs{regex_count:nnN} functions.
+% \begin{macrocode}
+\int_new:N \l_@@_match_count_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_begin_flag, \l_@@_end_flag}
+% Those flags are raised to indicate begin-group or end-group tokens
+% that had to be added when extracting submatches.
+% \begin{macrocode}
+\flag_new:N \l_@@_begin_flag
+\flag_new:N \l_@@_end_flag
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_min_submatch_int, \l_@@_submatch_int, \l_@@_zeroth_submatch_int}
+% The end-points of each submatch are stored in two arrays whose index \meta{submatch} ranges
+% from \cs{l_@@_min_submatch_int} (inclusive) to
+% \cs{l_@@_submatch_int} (exclusive). Each successful match comes
+% with a $0$-th submatch (the full match), and one match for each
+% capturing group: submatches corresponding to the last successful
+% match are labelled starting at \texttt{zeroth_submatch}. The entry
+% \cs{l_@@_zeroth_submatch_int} in \cs{g_@@_submatch_prev_intarray} holds
+% the position at which that match attempt started: this is used for
+% splitting and replacements.
+% \begin{macrocode}
+\int_new:N \l_@@_min_submatch_int
+\int_new:N \l_@@_submatch_int
+\int_new:N \l_@@_zeroth_submatch_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_submatch_prev_intarray, \g_@@_submatch_begin_intarray, \g_@@_submatch_end_intarray, \g_@@_submatch_case_intarray}
+% Hold the place where the match attempt begun, the end-points of each
+% submatch, and which regex case the match corresponds to, respectively.
+% \begin{macrocode}
+\intarray_new:Nn \g_@@_submatch_prev_intarray { 65536 }
+\intarray_new:Nn \g_@@_submatch_begin_intarray { 65536 }
+\intarray_new:Nn \g_@@_submatch_end_intarray { 65536 }
+\intarray_new:Nn \g_@@_submatch_case_intarray { 65536 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_balance_intarray}
+% The first thing we do when matching is to store the balance of
+% begin-group/end-group characters into \cs{g_@@_balance_intarray}.
+% \begin{macrocode}
+\intarray_new:Nn \g_@@_balance_intarray { 65536 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_added_begin_int, \l_@@_added_end_int}
+% Keep track of the number of left/right braces to add when performing
+% a regex operation such as a replacement.
+% \begin{macrocode}
+\int_new:N \l_@@_added_begin_int
+\int_new:N \l_@@_added_end_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_return:}
+% This function triggers either \cs{prg_return_false:} or
+% \cs{prg_return_true:} as appropriate to whether a match was found or
+% not. It is used by all user conditionals.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_return:
+ {
+ \if_meaning:w \c_true_bool \g_@@_success_bool
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_query_set:n, \@@_query_set_aux:nN}
+% To easily extract subsets of the input once we found the positions
+% at which to cut, store the input tokens one by one into successive
+% \tn{toks} registers. Also store the brace balance (used to check
+% for overall brace balance) in an array.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_query_set:n #1
+ {
+ \int_zero:N \l_@@_balance_int
+ \int_zero:N \l_@@_curr_pos_int
+ \@@_query_set_aux:nN { } F
+ \tl_analysis_map_inline:nn {#1}
+ { \@@_query_set_aux:nN {##1} ##3 }
+ \@@_query_set_aux:nN { } F
+ \int_set_eq:NN \l_@@_max_pos_int \l_@@_curr_pos_int
+ }
+\cs_new_protected:Npn \@@_query_set_aux:nN #1#2
+ {
+ \int_incr:N \l_@@_curr_pos_int
+ \@@_toks_set:Nn \l_@@_curr_pos_int {#1}
+ \__kernel_intarray_gset:Nnn \g_@@_balance_intarray
+ \l_@@_curr_pos_int \l_@@_balance_int
+ \if_case:w "#2 \exp_stop_f:
+ \or: \int_incr:N \l_@@_balance_int
+ \or: \int_decr:N \l_@@_balance_int
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Matching}
+%
+% \begin{macro}{\@@_if_match:nn}
+% We don't track submatches, and stop after a single match. Build the
+% \textsc{nfa} with |#1|, and perform the match on the query |#2|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_if_match:nn #1#2
+ {
+ \group_begin:
+ \@@_disable_submatches:
+ \@@_single_match:
+ #1
+ \@@_match:n {#2}
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_match_case:nnTF}
+% \begin{macro}[EXP]{\@@_match_case_aux:nn}
+% The code would get badly messed up if the number of items in |#1|
+% were not even, so we catch this case, then follow the same code as
+% \cs{regex_match:nnTF} but using \cs{@@_case_build:n} and without
+% returning a result.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_match_case:nnTF #1#2
+ {
+ \int_if_odd:nTF { \tl_count:n {#1} }
+ {
+ \msg_error:nneeee { regex } { case-odd }
+ { \token_to_str:N \regex_match_case:nn(TF) } { code }
+ { \tl_count:n {#1} } { \tl_to_str:n {#1} }
+ \use_ii:nn
+ }
+ {
+ \@@_if_match:nn
+ { \@@_case_build:e { \@@_tl_odd_items:n {#1} } }
+ {#2}
+ \bool_if:NTF \g_@@_success_bool
+ }
+ }
+\cs_new:Npn \@@_match_case_aux:nn #1#2 { \exp_not:n { {#1} } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_count:nnN}
+% Again, we don't care about submatches. Instead of aborting after the
+% first \enquote{longest match} is found, we search for multiple
+% matches, incrementing \cs{l_@@_match_count_int} every time to
+% record the number of matches. Build the \textsc{nfa} and match. At
+% the end, store the result in the user's variable.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_count:nnN #1#2#3
+ {
+ \group_begin:
+ \@@_disable_submatches:
+ \int_zero:N \l_@@_match_count_int
+ \@@_multi_match:n { \int_incr:N \l_@@_match_count_int }
+ #1
+ \@@_match:n {#2}
+ \exp_args:NNNo
+ \group_end:
+ \int_set:Nn #3 { \int_use:N \l_@@_match_count_int }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Extracting submatches}
+%
+% \begin{macro}{\@@_extract_once:nnN, \@@_extract_all:nnN}
+% Match once or multiple times. After each match (or after the only
+% match), extract the submatches using \cs{@@_extract:}. At the
+% end, store the sequence containing all the submatches into the user
+% variable |#3| after closing the group.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_extract_once:nnN #1#2#3
+ {
+ \group_begin:
+ \@@_single_match:
+ #1
+ \@@_match:n {#2}
+ \@@_extract:
+ \@@_query_set:n {#2}
+ \@@_group_end_extract_seq:N #3
+ }
+\cs_new_protected:Npn \@@_extract_all:nnN #1#2#3
+ {
+ \group_begin:
+ \@@_multi_match:n { \@@_extract: }
+ #1
+ \@@_match:n {#2}
+ \@@_query_set:n {#2}
+ \@@_group_end_extract_seq:N #3
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_split:nnN}
+% Splitting at submatches is a bit more tricky. For each match,
+% extract all submatches, and replace the zeroth submatch by the part
+% of the query between the start of the match attempt and the start of
+% the zeroth submatch. This is inhibited if the delimiter matched an
+% empty token list at the start of this match attempt. After the last
+% match, store the last part of the token list, which ranges from the
+% start of the match attempt to the end of the query. This step is
+% inhibited if the last match was empty and at the very end: decrement
+% \cs{l_@@_submatch_int}, which controls which matches will be used.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_split:nnN #1#2#3
+ {
+ \group_begin:
+ \@@_multi_match:n
+ {
+ \if_int_compare:w
+ \l_@@_start_pos_int < \l_@@_success_pos_int
+ \@@_extract:
+ \__kernel_intarray_gset:Nnn \g_@@_submatch_prev_intarray
+ \l_@@_zeroth_submatch_int \c_zero_int
+ \__kernel_intarray_gset:Nnn \g_@@_submatch_end_intarray
+ \l_@@_zeroth_submatch_int
+ {
+ \__kernel_intarray_item:Nn \g_@@_submatch_begin_intarray
+ \l_@@_zeroth_submatch_int
+ }
+ \__kernel_intarray_gset:Nnn \g_@@_submatch_begin_intarray
+ \l_@@_zeroth_submatch_int
+ \l_@@_start_pos_int
+ \fi:
+ }
+ #1
+ \@@_match:n {#2}
+ \@@_query_set:n {#2}
+ \__kernel_intarray_gset:Nnn \g_@@_submatch_prev_intarray
+ \l_@@_submatch_int \c_zero_int
+ \__kernel_intarray_gset:Nnn \g_@@_submatch_end_intarray
+ \l_@@_submatch_int
+ \l_@@_max_pos_int
+ \__kernel_intarray_gset:Nnn \g_@@_submatch_begin_intarray
+ \l_@@_submatch_int
+ \l_@@_start_pos_int
+ \int_incr:N \l_@@_submatch_int
+ \if_meaning:w \c_true_bool \l_@@_empty_success_bool
+ \if_int_compare:w \l_@@_start_pos_int = \l_@@_max_pos_int
+ \int_decr:N \l_@@_submatch_int
+ \fi:
+ \fi:
+ \@@_group_end_extract_seq:N #3
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_group_end_extract_seq:N}
+% \begin{macro}{\@@_extract_seq:N}
+% \begin{macro}{\@@_extract_seq:NNn}
+% \begin{macro}{\@@_extract_seq_loop:Nw}
+% The end-points of submatches are stored as entries of two arrays
+% from \cs{l_@@_min_submatch_int} to \cs{l_@@_submatch_int}
+% (exclusive). Extract the relevant ranges into \cs{g_@@_internal_tl},
+% separated by \cs{@@_tmp:w} |{}|. We keep track in the two flags
+% \texttt{__regex_begin} and \texttt{__regex_end} of the number of
+% begin-group or end-group tokens added to make each of these items
+% overall balanced. At this step, |}{| is counted as being balanced
+% (same number of begin-group and end-group tokens). This problem is
+% caught by \cs{@@_extract_check:w}, explained later. After
+% complaining about any begin-group or end-group tokens we had to add,
+% we are ready to construct the user's sequence outside the group.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_group_end_extract_seq:N #1
+ {
+ \flag_clear:N \l_@@_begin_flag
+ \flag_clear:N \l_@@_end_flag
+ \cs_set_eq:NN \@@_tmp:w \scan_stop:
+ \__kernel_tl_gset:Nx \g_@@_internal_tl
+ {
+ \int_step_function:nnN \l_@@_min_submatch_int
+ { \l_@@_submatch_int - \c_one_int } \@@_extract_seq_aux:n
+ \@@_tmp:w
+ }
+ \int_set:Nn \l_@@_added_begin_int
+ { \flag_height:N \l_@@_begin_flag }
+ \int_set:Nn \l_@@_added_end_int
+ { \flag_height:N \l_@@_end_flag }
+ \tex_afterassignment:D \@@_extract_check:w
+ \__kernel_tl_gset:Nx \g_@@_internal_tl
+ { \g_@@_internal_tl \if_false: { \fi: } }
+ \int_compare:nNnT
+ { \l_@@_added_begin_int + \l_@@_added_end_int } > \c_zero_int
+ {
+ \msg_error:nneee { regex } { result-unbalanced }
+ { splitting~or~extracting~submatches }
+ { \int_use:N \l_@@_added_begin_int }
+ { \int_use:N \l_@@_added_end_int }
+ }
+ \group_end:
+ \@@_extract_seq:N #1
+ }
+\cs_gset_protected:Npn \@@_extract_seq:N #1
+ {
+ \seq_clear:N #1
+ \cs_set_eq:NN \@@_tmp:w \@@_extract_seq_loop:Nw
+ \exp_after:wN \@@_extract_seq:NNn
+ \exp_after:wN #1
+ \g_@@_internal_tl \use_none:nnn
+ }
+\cs_new_protected:Npn \@@_extract_seq:NNn #1#2#3
+ { #3 #2 #1 \prg_do_nothing: }
+\cs_new_protected:Npn \@@_extract_seq_loop:Nw #1#2 \@@_tmp:w #3
+ {
+ \seq_put_right:No #1 {#2}
+ #3 \@@_extract_seq_loop:Nw #1 \prg_do_nothing:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_extract_seq_aux:n, \@@_extract_seq_aux:ww}
+% The \texttt{:n} auxiliary builds one item of the sequence of
+% submatches. First compute the brace balance of the submatch, then
+% extract the submatch from the query, adding the appropriate braces
+% and raising a flag if the submatch is not balanced.
+% \begin{macrocode}
+\cs_new:Npn \@@_extract_seq_aux:n #1
+ {
+ \@@_tmp:w { }
+ \exp_after:wN \@@_extract_seq_aux:ww
+ \int_value:w \@@_submatch_balance:n {#1} ; #1;
+ }
+\cs_new:Npn \@@_extract_seq_aux:ww #1; #2;
+ {
+ \if_int_compare:w #1 < \c_zero_int
+ \prg_replicate:nn {-#1}
+ {
+ \flag_raise:N \l_@@_begin_flag
+ \exp_not:n { { \if_false: } \fi: }
+ }
+ \fi:
+ \@@_query_submatch:n {#2}
+ \if_int_compare:w #1 > \c_zero_int
+ \prg_replicate:nn {#1}
+ {
+ \flag_raise:N \l_@@_end_flag
+ \exp_not:n { \if_false: { \fi: } }
+ }
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_extract_check:w, \@@_extract_check:n,
+% \@@_extract_check_loop:w, \@@_extract_check_end:w
+% }
+% In \cs{@@_group_end_extract_seq:N} we had to expand
+% \cs{g_@@_internal_tl} to turn \cs{if_false:} constructions into
+% actual begin-group and end-group tokens. This is done with a
+% \cs{__kernel_tl_gset:Nx} assignment, and \cs{@@_extract_check:w} is
+% run immediately after this assignment ends, thanks to the
+% \tn{afterassignment} primitive. If all of the items were properly
+% balanced (enough begin-group tokens before end-group tokens, so |}{|
+% is not) then \cs{@@_extract_check:w} is called just before the
+% closing brace of the \cs{__kernel_tl_gset:Nx} (thanks to our sneaky
+% \cs{if_false:} |{| \cs{fi:} |}| construction), and finds that there
+% is nothing left to expand. If any of the items is unbalanced, the
+% assignment gets ended early by an extra end-group token, and our
+% check finds more tokens needing to be expanded in a new
+% \cs{__kernel_tl_gset:Nx} assignment. We need to add a begin-group
+% and an end-group tokens to the unbalanced item, namely to the last
+% item found so far, which we reach through a loop.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_extract_check:w
+ {
+ \exp_after:wN \@@_extract_check:n
+ \exp_after:wN { \if_false: } \fi:
+ }
+\cs_new_protected:Npn \@@_extract_check:n #1
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \int_incr:N \l_@@_added_begin_int
+ \int_incr:N \l_@@_added_end_int
+ \tex_afterassignment:D \@@_extract_check:w
+ \__kernel_tl_gset:Nx \g_@@_internal_tl
+ {
+ \exp_after:wN \@@_extract_check_loop:w
+ \g_@@_internal_tl
+ \@@_tmp:w \@@_extract_check_end:w
+ #1
+ }
+ }
+ }
+\cs_new:Npn \@@_extract_check_loop:w #1 \@@_tmp:w #2
+ {
+ #2
+ \exp_not:o {#1}
+ \@@_tmp:w { }
+ \@@_extract_check_loop:w \prg_do_nothing:
+ }
+% \end{macrocode}
+% Arguments of \cs{@@_extract_check_end:w} are: |#1| is the part of
+% the item before the extra end-group token; |#2| is junk; |#3| is
+% \cs{prg_do_nothing:} followed by the not-yet-expanded part of the
+% item after the extra end-group token. In the replacement text, the
+% first brace and the \cs{if_false:} |{| \cs{fi:} |}| construction are
+% the added begin-group and end-group tokens (the latter being not-yet
+% expanded, just like~|#3|), while the closing brace after
+% \cs{exp_not:o} |{#1}| replaces the extra end-group token that had
+% ended the assignment early. In particular this means that the
+% character code of that end-group token is lost.
+% \begin{macrocode}
+\cs_new:Npn \@@_extract_check_end:w
+ \exp_not:o #1#2 \@@_extract_check_loop:w #3 \@@_tmp:w
+ {
+ { \exp_not:o {#1} }
+ #3
+ \if_false: { \fi: }
+ \@@_tmp:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_extract:, \@@_extract_aux:w}
+% Our task here is to store the list of end-points of submatches, and
+% store them in appropriate array entries, from
+% \cs{l_@@_zeroth_submatch_int} upwards. First, we store in
+% \cs{g_@@_submatch_prev_intarray} the position at which the match
+% attempt started. We extract the rest from the comma list
+% \cs{l_@@_success_submatches_tl}, which starts with entries to be
+% stored in \cs{g_@@_submatch_begin_intarray} and continues with
+% entries for \cs{g_@@_submatch_end_intarray}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_extract:
+ {
+ \if_meaning:w \c_true_bool \g_@@_success_bool
+ \int_set_eq:NN \l_@@_zeroth_submatch_int \l_@@_submatch_int
+ \prg_replicate:nn \l_@@_capturing_group_int
+ {
+ \__kernel_intarray_gset:Nnn \g_@@_submatch_prev_intarray
+ \l_@@_submatch_int \c_zero_int
+ \__kernel_intarray_gset:Nnn \g_@@_submatch_case_intarray
+ \l_@@_submatch_int \c_zero_int
+ \int_incr:N \l_@@_submatch_int
+ }
+ \__kernel_intarray_gset:Nnn \g_@@_submatch_prev_intarray
+ \l_@@_zeroth_submatch_int \l_@@_start_pos_int
+ \__kernel_intarray_gset:Nnn \g_@@_submatch_case_intarray
+ \l_@@_zeroth_submatch_int \g_@@_case_int
+ \int_zero:N \l_@@_internal_a_int
+ \exp_after:wN \@@_extract_aux:w \l_@@_success_submatches_tl
+ \prg_break_point: \@@_use_none_delimit_by_q_recursion_stop:w ,
+ \q_@@_recursion_stop
+ \fi:
+ }
+\cs_new_protected:Npn \@@_extract_aux:w #1 ,
+ {
+ \prg_break: #1 \prg_break_point:
+ \if_int_compare:w \l_@@_internal_a_int < \l_@@_capturing_group_int
+ \__kernel_intarray_gset:Nnn \g_@@_submatch_begin_intarray
+ { \@@_int_eval:w \l_@@_zeroth_submatch_int + \l_@@_internal_a_int } {#1}
+ \else:
+ \__kernel_intarray_gset:Nnn \g_@@_submatch_end_intarray
+ {
+ \@@_int_eval:w
+ \l_@@_zeroth_submatch_int + \l_@@_internal_a_int
+ - \l_@@_capturing_group_int
+ }
+ {#1}
+ \fi:
+ \int_incr:N \l_@@_internal_a_int
+ \@@_extract_aux:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Replacement}
+%
+% \begin{macro}{\@@_replace_once:nnN, \@@_replace_once_aux:nnN}
+% Build the \textsc{nfa} and the replacement functions, then find a
+% single match. If the match failed, simply exit the
+% group. Otherwise, we do the replacement. Extract submatches. Compute
+% the brace balance corresponding to replacing this match by the
+% replacement (this depends on submatches). Prepare the replaced token
+% list: the replacement function produces the tokens from the start of
+% the query to the start of the match and the replacement text for
+% this match; we need to add the tokens from the end of the match to
+% the end of the query. Finally, store the result in the user's
+% variable after closing the group: this step involves an additional
+% \texttt{e}-expansion, and checks that braces are balanced in the
+% final result.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replace_once:nnN #1#2
+ { \@@_replace_once_aux:nnN {#1} { \@@_replacement:n {#2} } }
+\cs_new_protected:Npn \@@_replace_once_aux:nnN #1#2#3
+ {
+ \group_begin:
+ \@@_single_match:
+ #1
+ \exp_args:No \@@_match:n {#3}
+ \bool_if:NTF \g_@@_success_bool
+ {
+ \@@_extract:
+ \exp_args:No \@@_query_set:n {#3}
+ #2
+ \int_set:Nn \l_@@_balance_int
+ { \@@_replacement_balance_one_match:n \l_@@_zeroth_submatch_int }
+ \__kernel_tl_set:Nx \l_@@_internal_a_tl
+ {
+ \@@_replacement_do_one_match:n \l_@@_zeroth_submatch_int
+ \@@_query_range:nn
+ {
+ \__kernel_intarray_item:Nn \g_@@_submatch_end_intarray
+ \l_@@_zeroth_submatch_int
+ }
+ \l_@@_max_pos_int
+ }
+ \@@_group_end_replace:N #3
+ }
+ { \group_end: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_replace_all:nnN}
+% Match multiple times, and for every match, extract submatches and
+% additionally store the position at which the match attempt started.
+% The entries from \cs{l_@@_min_submatch_int} to
+% \cs{l_@@_submatch_int} hold information about submatches of every
+% match in order; each match corresponds to
+% \cs{l_@@_capturing_group_int} consecutive entries.
+% Compute the brace balance corresponding to doing all the
+% replacements: this is the sum of brace balances for replacing each
+% match. Join together the replacement texts for each match (including
+% the part of the query before the match), and the end of the query.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replace_all:nnN #1#2
+ { \@@_replace_all_aux:nnN {#1} { \@@_replacement:n {#2} } }
+\cs_new_protected:Npn \@@_replace_all_aux:nnN #1#2#3
+ {
+ \group_begin:
+ \@@_multi_match:n { \@@_extract: }
+ #1
+ \exp_args:No \@@_match:n {#3}
+ \exp_args:No \@@_query_set:n {#3}
+ #2
+ \int_set:Nn \l_@@_balance_int
+ {
+ \c_zero_int
+ \int_step_function:nnnN
+ \l_@@_min_submatch_int
+ \l_@@_capturing_group_int
+ { \l_@@_submatch_int - \c_one_int }
+ \@@_replacement_balance_one_match:n
+ }
+ \__kernel_tl_set:Nx \l_@@_internal_a_tl
+ {
+ \int_step_function:nnnN
+ \l_@@_min_submatch_int
+ \l_@@_capturing_group_int
+ { \l_@@_submatch_int - \c_one_int }
+ \@@_replacement_do_one_match:n
+ \@@_query_range:nn
+ \l_@@_start_pos_int \l_@@_max_pos_int
+ }
+ \@@_group_end_replace:N #3
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_group_end_replace:N, \@@_group_end_replace_try:,
+% \@@_group_end_replace_check:w, \@@_group_end_replace_check:n
+% }
+% At this stage \cs{l_@@_internal_a_tl} (|e|-expands to the desired
+% result). Guess from \cs{l_@@_balance_int} the number of braces to
+% add before or after the result then try expanding. The simplest
+% case is when \cs{l_@@_internal_a_tl} together with the braces we
+% insert via \cs{prg_replicate:nn} give a balanced result, and the
+% assignment ends at the \cs{if_false:} |{| \cs{fi:} |}| construction:
+% then \cs{@@_group_end_replace_check:w} sees that there is no
+% material left and we successfully found the result. The harder case
+% is that expanding \cs{l_@@_internal_a_tl} may produce extra closing
+% braces and end the assignment early. Then we grab the remaining code
+% using; importantly, what follows has not yet been expanded so that
+% \cs{@@_group_end_replace_check:n} grabs everything until the last
+% brace in \cs{@@_group_end_replace_try:}, letting us try again with
+% an extra surrounding pair of braces.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_group_end_replace:N #1
+ {
+ \int_set:Nn \l_@@_added_begin_int
+ { \int_max:nn { - \l_@@_balance_int } \c_zero_int }
+ \int_set:Nn \l_@@_added_end_int
+ { \int_max:nn \l_@@_balance_int \c_zero_int }
+ \@@_group_end_replace_try:
+ \int_compare:nNnT { \l_@@_added_begin_int + \l_@@_added_end_int }
+ > \c_zero_int
+ {
+ \msg_error:nneee { regex } { result-unbalanced }
+ { replacing } { \int_use:N \l_@@_added_begin_int }
+ { \int_use:N \l_@@_added_end_int }
+ }
+ \group_end:
+ \tl_set_eq:NN #1 \g_@@_internal_tl
+ }
+\cs_new_protected:Npn \@@_group_end_replace_try:
+ {
+ \tex_afterassignment:D \@@_group_end_replace_check:w
+ \__kernel_tl_gset:Nx \g_@@_internal_tl
+ {
+ \prg_replicate:nn \l_@@_added_begin_int { { \if_false: } \fi: }
+ \l_@@_internal_a_tl
+ \prg_replicate:nn \l_@@_added_end_int { \if_false: { \fi: } }
+ \if_false: { \fi: }
+ }
+ }
+\cs_new_protected:Npn \@@_group_end_replace_check:w
+ {
+ \exp_after:wN \@@_group_end_replace_check:n
+ \exp_after:wN { \if_false: } \fi:
+ }
+\cs_new_protected:Npn \@@_group_end_replace_check:n #1
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \int_incr:N \l_@@_added_begin_int
+ \int_incr:N \l_@@_added_end_int
+ \@@_group_end_replace_try:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Peeking ahead}
+%
+% \begin{variable}{\l_@@_peek_true_tl, \l_@@_peek_false_tl}
+% True/false code arguments of \cs{peek_regex:nTF} or similar.
+% \begin{macrocode}
+\tl_new:N \l_@@_peek_true_tl
+\tl_new:N \l_@@_peek_false_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_replacement_tl}
+% When peeking in \cs{peek_regex_replace_once:nnTF} we need to store
+% the replacement text.
+% \begin{macrocode}
+\tl_new:N \l_@@_replacement_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_input_tl}
+% \begin{macro}{\@@_input_item:n}
+% Stores each token found as \cs{@@_input_item:n} \Arg{tokens}, where
+% the \meta{tokens} \texttt{o}-expand to the token found, as for
+% \cs{tl_analysis_map_inline:nn}.
+% \begin{macrocode}
+\tl_new:N \l_@@_input_tl
+\cs_new_eq:NN \@@_input_item:n ?
+% \end{macrocode}
+% \end{macro}
+% \end{variable}
+%
+% \begin{macro}[TF]
+% {\peek_regex:n, \peek_regex:N, \peek_regex_remove_once:n, \peek_regex_remove_once:N}
+% The |T| and |F| functions just call the corresponding |TF| function.
+% The four |TF| functions differ along two axes: whether to remove the
+% token or not, distinguished by using \cs{@@_peek_end:} or
+% \cs{@@_peek_remove_end:n} (the latter case needs an argument, as we
+% will see), and whether the regex has to be compiled or is already in
+% an |N|-type variable, distinguished by calling \cs{@@_build_aux:Nn}
+% or \cs{@@_build_aux:NN}. The first argument of these functions is
+% \cs{c_false_bool} to indicate that there should be no implicit
+% insertion of a wildcard at the start of the pattern: otherwise the
+% code would keep looking further into the input stream until matching
+% the regex.
+% \begin{macrocode}
+\cs_new_protected:Npn \peek_regex:nTF #1
+ {
+ \@@_peek:nnTF
+ { \@@_build_aux:Nn \c_false_bool {#1} }
+ { \@@_peek_end: }
+ }
+\cs_new_protected:Npn \peek_regex:nT #1#2
+ { \peek_regex:nTF {#1} {#2} { } }
+\cs_new_protected:Npn \peek_regex:nF #1 { \peek_regex:nTF {#1} { } }
+\cs_new_protected:Npn \peek_regex:NTF #1
+ {
+ \@@_peek:nnTF
+ { \@@_build_aux:NN \c_false_bool #1 }
+ { \@@_peek_end: }
+ }
+\cs_new_protected:Npn \peek_regex:NT #1#2
+ { \peek_regex:NTF #1 {#2} { } }
+\cs_new_protected:Npn \peek_regex:NF #1 { \peek_regex:NTF {#1} { } }
+\cs_new_protected:Npn \peek_regex_remove_once:nTF #1
+ {
+ \@@_peek:nnTF
+ { \@@_build_aux:Nn \c_false_bool {#1} }
+ { \@@_peek_remove_end:n {##1} }
+ }
+\cs_new_protected:Npn \peek_regex_remove_once:nT #1#2
+ { \peek_regex_remove_once:nTF {#1} {#2} { } }
+\cs_new_protected:Npn \peek_regex_remove_once:nF #1
+ { \peek_regex_remove_once:nTF {#1} { } }
+\cs_new_protected:Npn \peek_regex_remove_once:NTF #1
+ {
+ \@@_peek:nnTF
+ { \@@_build_aux:NN \c_false_bool #1 }
+ { \@@_peek_remove_end:n {##1} }
+ }
+\cs_new_protected:Npn \peek_regex_remove_once:NT #1#2
+ { \peek_regex_remove_once:NTF #1 {#2} { } }
+\cs_new_protected:Npn \peek_regex_remove_once:NF #1
+ { \peek_regex_remove_once:NTF #1 { } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_peek:nnTF, \@@_peek_aux:nnTF}
+% Store the user's true/false codes (plus \cs{group_end:}) into two
+% token lists. Then build the automaton with |#1|, without submatch
+% tracking, and aiming for a single match. Then start matching by
+% setting up a few variables like for any regex matching like
+% \cs{regex_match:nnTF}, with the addition of \cs{l_@@_input_tl}
+% that keeps track of the tokens seen, to reinsert them at the
+% end. Instead of \cs{tl_analysis_map_inline:nn} on the input, we
+% call \cs{peek_analysis_map_inline:n} to go through tokens in the
+% input stream. Since \cs{@@_match_one_token:nnN} calls
+% \cs{@@_maplike_break:} we need to catch that and break the
+% \cs{peek_analysis_map_inline:n} loop instead.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek:nnTF #1
+ {
+ \@@_peek_aux:nnTF
+ {
+ \@@_disable_submatches:
+ #1
+ }
+ }
+\cs_new_protected:Npn \@@_peek_aux:nnTF #1#2#3#4
+ {
+ \group_begin:
+ \tl_set:Nn \l_@@_peek_true_tl { \group_end: #3 }
+ \tl_set:Nn \l_@@_peek_false_tl { \group_end: #4 }
+ \@@_single_match:
+ #1
+ \@@_match_init:
+ \tl_build_begin:N \l_@@_input_tl
+ \@@_match_once_init:
+ \peek_analysis_map_inline:n
+ {
+ \tl_build_put_right:Nn \l_@@_input_tl
+ { \@@_input_item:n {##1} }
+ \@@_match_one_token:nnN {##1} {##2} ##3
+ \use_none:nnn
+ \prg_break_point:Nn \@@_maplike_break:
+ { \peek_analysis_map_break:n {#2} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_peek_end:, \@@_peek_remove_end:n}
+% Once the regex matches (or permanently fails to match) we call
+% \cs{@@_peek_end:}, or \cs{@@_peek_remove_end:n} with argument the
+% last token seen. For \cs{peek_regex:nTF} we reinsert tokens seen by
+% calling \cs{@@_peek_reinsert:N} regardless of the result of the
+% match. For \cs{peek_regex_remove_once:nTF} we reinsert the tokens
+% seen only if the match failed; otherwise we just reinsert the
+% tokens~|#1|, with one expansion. To be more precise, |#1| consists
+% of tokens that \texttt{o}-expand and \texttt{e}-expand to the last
+% token seen, for example it is \cs{exp_not:N} \meta{cs} for a control
+% sequence. This means that just doing \cs{exp_after:wN}
+% \cs{l_@@_peek_true_tl} |#1| would be unsafe because the expansion of
+% \meta{cs} would be suppressed.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_end:
+ {
+ \bool_if:NTF \g_@@_success_bool
+ { \@@_peek_reinsert:N \l_@@_peek_true_tl }
+ { \@@_peek_reinsert:N \l_@@_peek_false_tl }
+ }
+\cs_new_protected:Npn \@@_peek_remove_end:n #1
+ {
+ \bool_if:NTF \g_@@_success_bool
+ { \exp_args:NNo \use:nn \l_@@_peek_true_tl {#1} }
+ { \@@_peek_reinsert:N \l_@@_peek_false_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_peek_reinsert:N, \@@_reinsert_item:n}
+% Insert the true/false code |#1|, followed by the tokens found, which
+% were stored in \cs{l_@@_input_tl}. For this, loop through that
+% token list using \cs{@@_reinsert_item:n}, which expands |#1| once to
+% get a single token, and jumps over it to expand what follows, with
+% suitable \cs{exp:w} and \cs{exp_end:}. We cannot just use
+% \cs{use:e} on the whole token list because the result may be
+% unbalanced, which would stop the primitive prematurely, or let it
+% continue beyond where we would like.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_reinsert:N #1
+ {
+ \tl_build_end:N \l_@@_input_tl
+ \cs_set_eq:NN \@@_input_item:n \@@_reinsert_item:n
+ \exp_after:wN #1 \exp:w \l_@@_input_tl \exp_end:
+ }
+\cs_new_protected:Npn \@@_reinsert_item:n #1
+ {
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_end:
+ \exp_after:wN \exp_after:wN
+ #1
+ \exp:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[noTF]
+% {\peek_regex_replace_once:nn, \peek_regex_replace_once:Nn}
+% Similar to \cs{peek_regex:nTF} above.
+% \begin{macrocode}
+\cs_new_protected:Npn \peek_regex_replace_once:nnTF #1
+ { \@@_peek_replace:nnTF { \@@_build_aux:Nn \c_false_bool {#1} } }
+\cs_new_protected:Npn \peek_regex_replace_once:nnT #1#2#3
+ { \peek_regex_replace_once:nnTF {#1} {#2} {#3} { } }
+\cs_new_protected:Npn \peek_regex_replace_once:nnF #1#2
+ { \peek_regex_replace_once:nnTF {#1} {#2} { } }
+\cs_new_protected:Npn \peek_regex_replace_once:nn #1#2
+ { \peek_regex_replace_once:nnTF {#1} {#2} { } { } }
+\cs_new_protected:Npn \peek_regex_replace_once:NnTF #1
+ { \@@_peek_replace:nnTF { \@@_build_aux:NN \c_false_bool #1 } }
+\cs_new_protected:Npn \peek_regex_replace_once:NnT #1#2#3
+ { \peek_regex_replace_once:NnTF #1 {#2} {#3} { } }
+\cs_new_protected:Npn \peek_regex_replace_once:NnF #1#2
+ { \peek_regex_replace_once:NnTF #1 {#2} { } }
+\cs_new_protected:Npn \peek_regex_replace_once:Nn #1#2
+ { \peek_regex_replace_once:NnTF #1 {#2} { } { } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_peek_replace:nnTF}
+% Same as \cs{@@_peek:nnTF} (used for \cs{peek_regex:nTF} above), but
+% without disabling submatches, and with a different end. The
+% replacement text |#2| is stored, to be analyzed later.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_replace:nnTF #1#2
+ {
+ \tl_set:Nn \l_@@_replacement_tl {#2}
+ \@@_peek_aux:nnTF {#1} { \@@_peek_replace_end: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_peek_replace_end:}
+% If the match failed \cs{@@_peek_reinsert:N} reinserts the tokens
+% found. Otherwise, finish storing the submatch information using
+% \cs{@@_extract:}, and store the input into \tn{toks}. Redefine a
+% few auxiliaries to change slightly their expansion behaviour as
+% explained below. Analyse the replacement text with
+% \cs{@@_replacement:n}, which as usual defines
+% \cs{@@_replacement_do_one_match:n} to insert the tokens from the
+% start of the match attempt to the beginning of the match, followed
+% by the replacement text. The \cs{use:e} expands for instance the
+% trailing \cs{@@_query_range:nn} down to a sequence of
+% \cs{@@_reinsert_item:n} \Arg{tokens} where \meta{tokens}
+% \texttt{o}-expand to a single token that we want to insert. After
+% \texttt{e}-expansion, \cs{use:e} does \cs{use:n}, so we have
+% \cs{exp_after:wN} \cs{l_@@_peek_true_tl} \cs{exp:w} \ldots{}
+% \cs{exp_end:}. This is set up such as to obtain
+% \cs{l_@@_peek_true_tl} followed by the replaced tokens (possibly
+% unbalanced) in the input stream.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_replace_end:
+ {
+ \bool_if:NTF \g_@@_success_bool
+ {
+ \@@_extract:
+ \@@_query_set_from_input_tl:
+ \cs_set_eq:NN \@@_replacement_put:n \@@_peek_replacement_put:n
+ \cs_set_eq:NN \@@_replacement_put_submatch_aux:n
+ \@@_peek_replacement_put_submatch_aux:n
+ \cs_set_eq:NN \@@_input_item:n \@@_reinsert_item:n
+ \cs_set_eq:NN \@@_replacement_exp_not:N \@@_peek_replacement_token:n
+ \cs_set_eq:NN \@@_replacement_exp_not:V \@@_peek_replacement_var:N
+ \exp_args:No \@@_replacement:n { \l_@@_replacement_tl }
+ \use:e
+ {
+ \exp_not:n { \exp_after:wN \l_@@_peek_true_tl \exp:w }
+ \@@_replacement_do_one_match:n \l_@@_zeroth_submatch_int
+ \@@_query_range:nn
+ {
+ \__kernel_intarray_item:Nn \g_@@_submatch_end_intarray
+ \l_@@_zeroth_submatch_int
+ }
+ \l_@@_max_pos_int
+ \exp_end:
+ }
+ }
+ { \@@_peek_reinsert:N \l_@@_peek_false_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_query_set_from_input_tl:, \@@_query_set_item:n}
+% The input was stored into \cs{l_@@_input_tl} as successive items
+% \cs{@@_input_item:n} \Arg{tokens}. Store that in successive
+% \tn{toks}. It's not clear whether the empty entries before and
+% after are both useful.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_query_set_from_input_tl:
+ {
+ \tl_build_end:N \l_@@_input_tl
+ \int_zero:N \l_@@_curr_pos_int
+ \cs_set_eq:NN \@@_input_item:n \@@_query_set_item:n
+ \@@_query_set_item:n { }
+ \l_@@_input_tl
+ \@@_query_set_item:n { }
+ \int_set_eq:NN \l_@@_max_pos_int \l_@@_curr_pos_int
+ }
+\cs_new_protected:Npn \@@_query_set_item:n #1
+ {
+ \int_incr:N \l_@@_curr_pos_int
+ \@@_toks_set:Nn \l_@@_curr_pos_int { \@@_input_item:n {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_peek_replacement_put:n}
+% While building the replacement function
+% \cs{@@_replacement_do_one_match:n}, we often want to put simple
+% material, given as |#1|, whose \texttt{e}-expansion
+% \texttt{o}-expands to a single token. Normally we can just add the
+% token to \cs{l_@@_build_tl}, but for
+% \cs{peek_regex_replace_once:nnTF} we eventually want to do some
+% strange expansion that is basically using \cs{exp_after:wN} to jump
+% through numerous tokens (we cannot use \texttt{e}-expansion like for
+% \cs{regex_replace_once:nnNTF} because it is ok for the result to be
+% unbalanced since we insert it in the input stream rather than
+% storing it. When within a csname we don't do any such shenanigan
+% because \cs{cs:w} \ldots{} \cs{cs_end:} does all the expansion we
+% need.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_replacement_put:n #1
+ {
+ \if_case:w \l_@@_replacement_csnames_int
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \exp_not:N \@@_reinsert_item:n {#1} }
+ \else:
+ \tl_build_put_right:Nn \l_@@_build_tl {#1}
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_peek_replacement_token:n}
+% When hit with \cs{exp:w}, \cs{@@_peek_replacement_token:n}
+% \Arg{token} stops \cs{exp_end:} and does \cs{exp_after:wN}
+% \meta{token} \cs{exp:w} to continue expansion after it.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_replacement_token:n #1
+ { \exp_after:wN \exp_end: \exp_after:wN #1 \exp:w }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_peek_replacement_put_submatch_aux:n}
+% While analyzing the replacement we also have to insert submatches
+% found in the query. Since query items \cs{@@_input_item:n}
+% \Arg{tokens} expand correctly only when surrounded by \cs{exp:w}
+% \ldots{} \cs{exp_end:}, and since these expansion controls are not
+% there within csnames (because \cs{cs:w} \ldots{} \cs{cs_end:} make
+% them unnecessary in most cases), we have to put \cs{exp:w} and
+% \cs{exp_end:} by hand here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_replacement_put_submatch_aux:n #1
+ {
+ \if_case:w \l_@@_replacement_csnames_int
+ \tl_build_put_right:Nn \l_@@_build_tl
+ { \@@_query_submatch:n { \@@_int_eval:w #1 + ##1 \scan_stop: } }
+ \else:
+ \tl_build_put_right:Nn \l_@@_build_tl
+ {
+ \exp:w
+ \@@_query_submatch:n { \@@_int_eval:w #1 + ##1 \scan_stop: }
+ \exp_end:
+ }
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_peek_replacement_var:N}
+% This is used for |\u| outside csnames. It makes sure to continue
+% expansion with \cs{exp:w} before expanding the variable~|#1| and
+% stopping the \cs{exp:w} that precedes.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_replacement_var:N #1
+ {
+ \exp_after:wN \exp_last_unbraced:NV
+ \exp_after:wN \exp_end:
+ \exp_after:wN #1
+ \exp:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% Messages for the preparsing phase.
+% \begin{macrocode}
+\use:e
+ {
+ \msg_new:nnn { regex } { trailing-backslash }
+ { Trailing~'\iow_char:N\\'~in~regex~or~replacement. }
+ \msg_new:nnn { regex } { x-missing-rbrace }
+ {
+ Missing~brace~'\iow_char:N\}'~in~regex~
+ '...\iow_char:N\\x\iow_char:N\{...##1'.
+ }
+ \msg_new:nnn { regex } { x-overflow }
+ {
+ Character~code~##1~too~large~in~
+ \iow_char:N\\x\iow_char:N\{##2\iow_char:N\}~regex.
+ }
+ }
+% \end{macrocode}
+%
+% Invalid quantifier.
+% \begin{macrocode}
+\msg_new:nnnn { regex } { invalid-quantifier }
+ { Braced~quantifier~'#1'~may~not~be~followed~by~'#2'. }
+ {
+ The~character~'#2'~is~invalid~in~the~braced~quantifier~'#1'.~
+ The~only~valid~quantifiers~are~'*',~'?',~'+',~'{<int>}',~
+ '{<min>,}'~and~'{<min>,<max>}',~optionally~followed~by~'?'.
+ }
+% \end{macrocode}
+%
+% Messages for missing or extra closing brackets and parentheses, with
+% some fancy singular/plural handling for the case of parentheses.
+% \begin{macrocode}
+\msg_new:nnnn { regex } { missing-rbrack }
+ { Missing~right~bracket~inserted~in~regular~expression. }
+ {
+ LaTeX~was~given~a~regular~expression~where~a~character~class~
+ was~started~with~'[',~but~the~matching~']'~is~missing.
+ }
+\msg_new:nnnn { regex } { missing-rparen }
+ {
+ Missing~right~
+ \int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } ~
+ inserted~in~regular~expression.
+ }
+ {
+ LaTeX~was~given~a~regular~expression~with~\int_eval:n {#1} ~
+ more~left~parentheses~than~right~parentheses.
+ }
+\msg_new:nnnn { regex } { extra-rparen }
+ { Extra~right~parenthesis~ignored~in~regular~expression. }
+ {
+ LaTeX~came~across~a~closing~parenthesis~when~no~submatch~group~
+ was~open.~The~parenthesis~will~be~ignored.
+ }
+% \end{macrocode}
+%
+% Some escaped alphanumerics are not allowed everywhere.
+% \begin{macrocode}
+\msg_new:nnnn { regex } { bad-escape }
+ {
+ Invalid~escape~'\iow_char:N\\#1'~
+ \@@_if_in_cs:TF { within~a~control~sequence. }
+ {
+ \@@_if_in_class:TF
+ { in~a~character~class. }
+ { following~a~category~test. }
+ }
+ }
+ {
+ The~escape~sequence~'\iow_char:N\\#1'~may~not~appear~
+ \@@_if_in_cs:TF
+ {
+ within~a~control~sequence~test~introduced~by~
+ '\iow_char:N\\c\iow_char:N\{'.
+ }
+ {
+ \@@_if_in_class:TF
+ { within~a~character~class~ }
+ { following~a~category~test~such~as~'\iow_char:N\\cL'~ }
+ because~it~does~not~match~exactly~one~character.
+ }
+ }
+% \end{macrocode}
+%
+% Range errors.
+% \begin{macrocode}
+\msg_new:nnnn { regex } { range-missing-end }
+ { Invalid~end-point~for~range~'#1-#2'~in~character~class. }
+ {
+ The~end-point~'#2'~of~the~range~'#1-#2'~may~not~serve~as~an~
+ end-point~for~a~range:~alphanumeric~characters~should~not~be~
+ escaped,~and~non-alphanumeric~characters~should~be~escaped.
+ }
+\msg_new:nnnn { regex } { range-backwards }
+ { Range~'[#1-#2]'~out~of~order~in~character~class. }
+ {
+ In~ranges~of~characters~'[x-y]'~appearing~in~character~classes,~
+ the~first~character~code~must~not~be~larger~than~the~second.~
+ Here,~'#1'~has~character~code~\int_eval:n {`#1},~while~
+ '#2'~has~character~code~\int_eval:n {`#2}.
+ }
+% \end{macrocode}
+%
+% Errors related to |\c| and |\u|.
+% \begin{macrocode}
+\msg_new:nnnn { regex } { c-bad-mode }
+ { Invalid~nested~'\iow_char:N\\c'~escape~in~regular~expression. }
+ {
+ The~'\iow_char:N\\c'~escape~cannot~be~used~within~
+ a~control~sequence~test~'\iow_char:N\\c{...}'~
+ nor~another~category~test.~
+ To~combine~several~category~tests,~use~'\iow_char:N\\c[...]'.
+ }
+\msg_new:nnnn { regex } { c-C-invalid }
+ { '\iow_char:N\\cC'~should~be~followed~by~'.'~or~'(',~not~'#1'. }
+ {
+ The~'\iow_char:N\\cC'~construction~restricts~the~next~item~to~be~a~
+ control~sequence~or~the~next~group~to~be~made~of~control~sequences.~
+ It~only~makes~sense~to~follow~it~by~'.'~or~by~a~group.
+ }
+\msg_new:nnnn { regex } { cu-lbrace }
+ { Left~braces~must~be~escaped~in~'\iow_char:N\\#1{...}'. }
+ {
+ Constructions~such~as~'\iow_char:N\\#1{...\iow_char:N\{...}'~are~
+ not~allowed~and~should~be~replaced~by~
+ '\iow_char:N\\#1{...\token_to_str:N\{...}'.
+ }
+\msg_new:nnnn { regex } { c-lparen-in-class }
+ { Catcode~test~cannot~apply~to~group~in~character~class }
+ {
+ Construction~such~as~'\iow_char:N\\cL(abc)'~are~not~allowed~inside~a~
+ class~'[...]'~because~classes~do~not~match~multiple~characters~at~once.
+ }
+\msg_new:nnnn { regex } { c-missing-rbrace }
+ { Missing~right~brace~inserted~for~'\iow_char:N\\c'~escape. }
+ {
+ LaTeX~was~given~a~regular~expression~where~a~
+ '\iow_char:N\\c\iow_char:N\{...'~construction~was~not~ended~
+ with~a~closing~brace~'\iow_char:N\}'.
+ }
+\msg_new:nnnn { regex } { c-missing-rbrack }
+ { Missing~right~bracket~inserted~for~'\iow_char:N\\c'~escape. }
+ {
+ A~construction~'\iow_char:N\\c[...'~appears~in~a~
+ regular~expression,~but~the~closing~']'~is~not~present.
+ }
+\msg_new:nnnn { regex } { c-missing-category }
+ { Invalid~character~'#1'~following~'\iow_char:N\\c'~escape. }
+ {
+ In~regular~expressions,~the~'\iow_char:N\\c'~escape~sequence~
+ may~only~be~followed~by~a~left~brace,~a~left~bracket,~or~a~
+ capital~letter~representing~a~character~category,~namely~
+ one~of~'ABCDELMOPSTU'.
+ }
+\msg_new:nnnn { regex } { c-trailing }
+ { Trailing~category~code~escape~'\iow_char:N\\c'... }
+ {
+ A~regular~expression~ends~with~'\iow_char:N\\c'~followed~
+ by~a~letter.~It~will~be~ignored.
+ }
+\msg_new:nnnn { regex } { u-missing-lbrace }
+ { Missing~left~brace~following~'\iow_char:N\\u'~escape. }
+ {
+ The~'\iow_char:N\\u'~escape~sequence~must~be~followed~by~
+ a~brace~group~with~the~name~of~the~variable~to~use.
+ }
+\msg_new:nnnn { regex } { u-missing-rbrace }
+ { Missing~right~brace~inserted~for~'\iow_char:N\\u'~escape. }
+ {
+ LaTeX~
+ \str_if_eq:eeTF { } {#2}
+ { reached~the~end~of~the~string~ }
+ { encountered~an~escaped~alphanumeric~character '\iow_char:N\\#2'~ }
+ when~parsing~the~argument~of~an~
+ '\iow_char:N\\u\iow_char:N\{...\}'~escape.
+ }
+% \end{macrocode}
+%
+% Errors when encountering the \textsc{posix} syntax |[:...:]|.
+% \begin{macrocode}
+\msg_new:nnnn { regex } { posix-unsupported }
+ { POSIX~collating~element~'[#1 ~ #1]'~not~supported. }
+ {
+ The~'[.foo.]'~and~'[=bar=]'~syntaxes~have~a~special~meaning~
+ in~POSIX~regular~expressions.~This~is~not~supported~by~LaTeX.~
+ Maybe~you~forgot~to~escape~a~left~bracket~in~a~character~class?
+ }
+\msg_new:nnnn { regex } { posix-unknown }
+ { POSIX~class~'[:#1:]'~unknown. }
+ {
+ '[:#1:]'~is~not~among~the~known~POSIX~classes~
+ '[:alnum:]',~'[:alpha:]',~'[:ascii:]',~'[:blank:]',~
+ '[:cntrl:]',~'[:digit:]',~'[:graph:]',~'[:lower:]',~
+ '[:print:]',~'[:punct:]',~'[:space:]',~'[:upper:]',~
+ '[:word:]',~and~'[:xdigit:]'.
+ }
+\msg_new:nnnn { regex } { posix-missing-close }
+ { Missing~closing~':]'~for~POSIX~class. }
+ { The~POSIX~syntax~'#1'~must~be~followed~by~':]',~not~'#2'. }
+% \end{macrocode}
+%
+% In various cases, the result of a \pkg{l3regex} operation can leave us
+% with an unbalanced token list, which we must re-balance by adding
+% begin-group or end-group character tokens.
+% \begin{macrocode}
+\msg_new:nnnn { regex } { result-unbalanced }
+ { Missing~brace~inserted~when~#1. }
+ {
+ LaTeX~was~asked~to~do~some~regular~expression~operation,~
+ and~the~resulting~token~list~would~not~have~the~same~number~
+ of~begin-group~and~end-group~tokens.~Braces~were~inserted:~
+ #2~left,~#3~right.
+ }
+% \end{macrocode}
+%
+% Error message for unknown options.
+% \begin{macrocode}
+\msg_new:nnnn { regex } { unknown-option }
+ { Unknown~option~'#1'~for~regular~expressions. }
+ {
+ The~only~available~option~is~'case-insensitive',~toggled~by~
+ '(?i)'~and~'(?-i)'.
+ }
+\msg_new:nnnn { regex } { special-group-unknown }
+ { Unknown~special~group~'#1~...'~in~a~regular~expression. }
+ {
+ The~only~valid~constructions~starting~with~'(?'~are~
+ '(?:~...~)',~'(?|~...~)',~'(?i)',~and~'(?-i)'.
+ }
+% \end{macrocode}
+%
+% Errors in the replacement text.
+% \begin{macrocode}
+\msg_new:nnnn { regex } { replacement-c }
+ { Misused~'\iow_char:N\\c'~command~in~a~replacement~text. }
+ {
+ In~a~replacement~text,~the~'\iow_char:N\\c'~escape~sequence~
+ can~be~followed~by~one~of~the~letters~'ABCDELMOPSTU'~
+ or~a~brace~group,~not~by~'#1'.
+ }
+\msg_new:nnnn { regex } { replacement-u }
+ { Misused~'\iow_char:N\\u'~command~in~a~replacement~text. }
+ {
+ In~a~replacement~text,~the~'\iow_char:N\\u'~escape~sequence~
+ must~be~~followed~by~a~brace~group~holding~the~name~of~the~
+ variable~to~use.
+ }
+\msg_new:nnnn { regex } { replacement-g }
+ {
+ Missing~brace~for~the~'\iow_char:N\\g'~construction~
+ in~a~replacement~text.
+ }
+ {
+ In~the~replacement~text~for~a~regular~expression~search,~
+ submatches~are~represented~either~as~'\iow_char:N \\g{dd..d}',~
+ or~'\\d',~where~'d'~are~single~digits.~Here,~a~brace~is~missing.
+ }
+\msg_new:nnnn { regex } { replacement-catcode-end }
+ {
+ Missing~character~for~the~'\iow_char:N\\c<category><character>'~
+ construction~in~a~replacement~text.
+ }
+ {
+ In~a~replacement~text,~the~'\iow_char:N\\c'~escape~sequence~
+ can~be~followed~by~one~of~the~letters~'ABCDELMOPSTU'~representing~
+ the~character~category.~Then,~a~character~must~follow.~LaTeX~
+ reached~the~end~of~the~replacement~when~looking~for~that.
+ }
+\msg_new:nnnn { regex } { replacement-catcode-escaped }
+ {
+ Escaped~letter~or~digit~after~category~code~in~replacement~text.
+ }
+ {
+ In~a~replacement~text,~the~'\iow_char:N\\c'~escape~sequence~
+ can~be~followed~by~one~of~the~letters~'ABCDELMOPSTU'~representing~
+ the~character~category.~Then,~a~character~must~follow,~not~
+ '\iow_char:N\\#2'.
+ }
+\msg_new:nnnn { regex } { replacement-catcode-in-cs }
+ {
+ Category~code~'\iow_char:N\\c#1#3'~ignored~inside~
+ '\iow_char:N\\c\{...\}'~in~a~replacement~text.
+ }
+ {
+ In~a~replacement~text,~the~category~codes~of~the~argument~of~
+ '\iow_char:N\\c\{...\}'~are~ignored~when~building~the~control~
+ sequence~name.
+ }
+\msg_new:nnnn { regex } { replacement-null-space }
+ { TeX~cannot~build~a~space~token~with~character~code~0. }
+ {
+ You~asked~for~a~character~token~with~category~space,~
+ and~character~code~0,~for~instance~through~
+ '\iow_char:N\\cS\iow_char:N\\x00'.~
+ This~specific~case~is~impossible~and~will~be~replaced~
+ by~a~normal~space.
+ }
+\msg_new:nnnn { regex } { replacement-missing-rbrace }
+ { Missing~right~brace~inserted~in~replacement~text. }
+ {
+ There~ \int_compare:nTF { #1 = 1 } { was } { were } ~ #1~
+ missing~right~\int_compare:nTF { #1 = 1 } { brace } { braces } .
+ }
+\msg_new:nnnn { regex } { replacement-missing-rparen }
+ { Missing~right~parenthesis~inserted~in~replacement~text. }
+ {
+ There~ \int_compare:nTF { #1 = 1 } { was } { were } ~ #1~
+ missing~right~
+ \int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } .
+ }
+\msg_new:nnn { regex } { submatch-too-big }
+ { Submatch~#1~used~but~regex~only~has~#2~group(s) }
+% \end{macrocode}
+%
+% Some escaped alphanumerics are not allowed everywhere.
+% \begin{macrocode}
+\msg_new:nnnn { regex } { backwards-quantifier }
+ { Quantifer~"{#1,#2}"~is~backwards. }
+ { The~values~given~in~a~quantifier~must~be~in~order. }
+% \end{macrocode}
+%
+% Used in user commands, and when showing a regex.
+% \begin{macrocode}
+\msg_new:nnnn { regex } { case-odd }
+ { #1~with~odd~number~of~items }
+ {
+ There~must~be~a~#2~part~for~each~regex:~
+ found~odd~number~of~items~(#3)~in\\
+ \iow_indent:n {#4}
+ }
+\msg_new:nnn { regex } { show }
+ {
+ >~Compiled~regex~
+ \tl_if_empty:nTF {#1} { variable~ #2 } { {#1} } :
+ #3
+ }
+\prop_gput:Nnn \g_msg_module_name_prop { regex } { LaTeX }
+\prop_gput:Nnn \g_msg_module_type_prop { regex } { }
+% \end{macrocode}
+%
+% \begin{macro}{\@@_msg_repeated:nnN}
+% This is not technically a message, but seems related enough to go
+% there. The arguments are: |#1| is the minimum number of repetitions;
+% |#2| is the number of allowed extra repetitions ($-1$ for infinite
+% number), and |#3| tells us about lazyness.
+% \begin{macrocode}
+\cs_new:Npn \@@_msg_repeated:nnN #1#2#3
+ {
+ \str_if_eq:eeF { #1 #2 } { 1 0 }
+ {
+ , ~ repeated ~
+ \int_case:nnF {#2}
+ {
+ { -1 } { #1~or~more~times,~\bool_if:NTF #3 { lazy } { greedy } }
+ { 0 } { #1~times }
+ }
+ {
+ between~#1~and~\int_eval:n {#1+#2}~times,~
+ \bool_if:NTF #3 { lazy } { greedy }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Code for tracing}
+%
+% There is a more extensive implementation of tracing in the l3trial
+% package \pkg{l3trace}. Function names are a bit different but could
+% be merged.
+%
+% \begin{macro}
+% {\@@_trace_push:nnN, \@@_trace_pop:nnN, \@@_trace:nne}
+% Here |#1| is the module name (\texttt{regex}) and |#2| is
+% typically~1. If the module's current tracing level is less than
+% |#2| show nothing, otherwise write |#3| to the terminal.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_trace_push:nnN #1#2#3
+ { \@@_trace:nne {#1} {#2} { entering~ \token_to_str:N #3 } }
+\cs_new_protected:Npn \@@_trace_pop:nnN #1#2#3
+ { \@@_trace:nne {#1} {#2} { leaving~ \token_to_str:N #3 } }
+\cs_new_protected:Npn \@@_trace:nne #1#2#3
+ {
+ \int_compare:nNnF
+ { \int_use:c { g_@@_trace_#1_int } } < {#2}
+ { \iow_term:e { Trace:~#3 } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_trace_regex_int}
+% No tracing when that is zero.
+% \begin{macrocode}
+\int_new:N \g_@@_trace_regex_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_trace_states:n}
+% This function lists the contents of all states of the \textsc{nfa},
+% stored in \tn{toks} from $0$ to \cs{l_@@_max_state_int}
+% (excluded).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_trace_states:n #1
+ {
+ \int_step_inline:nnn
+ \l_@@_min_state_int
+ { \l_@@_max_state_int - \c_one_int }
+ {
+ \@@_trace:nne { regex } {#1}
+ { \iow_char:N \\toks ##1 = { \@@_toks_use:w ##1 } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
+% \endinput
+%^^A NOT IMPLEMENTED
+%^^A \p{xx} a character with the xx property
+%^^A \P{xx} a character without the xx property
+%^^A (?=...) positive look ahead
+%^^A (?!...) negative look ahead
+%^^A (?<=...) positive look behind
+%^^A (?<!...) negative look behind
+%^^A (?<name>...) or (?'name'...) or (?P<name>...)
+%^^A named capturing group
+%^^A \R a newline sequence
+%^^A \X an extended Unicode sequence
+%^^A (?C) or (?Cn) callout with data n
+%^^A (?R) recurse whole pattern
+%^^A (?[+-]n) or \g<[+-]n> or (?&name) or (?P>name) or \g<name>
+%^^A call subpattern
+%^^A (?([+-]n)... or (?(<name>)...
+%^^A reference condition
+%^^A (?(R)... or (?(Rn)... or (?(R&name)...
+%^^A recursion condition
+%^^A (?(DEFINE)... define subpattern for reference
+%^^A (?(assert)... assertion condition
+%^^A (?(?=..)..|..) positive/negative look ahead/behind condition
+%^^A (*ACCEPT) force successful match
+%^^A (*FAIL) force backtrack; synonym (*F)
+%^^A (*COMMIT) overall failure, no advance of starting point
+%^^A (*PRUNE) advance to next starting character
+%^^A (*SKIP) advance start to current matching position
+%^^A (*THEN) local failure, backtrack to next alternation
+%^^A (*CR) or (*LF) or (*CRLF) or (*ANYCRLF) or (*ANY)
+%^^A newline convention
+%^^A (*BSR_ANYCRLF) or (*BSR_UNICODE)
+%^^A change what \R matches.
+%^^A
+%^^A \cx "control-x", where x is any ASCII character
+%^^A \C one byte, even in UTF-8 mode (best avoided)
+%^^A + possessive quantifiers
+%^^A (?>...) atomic, non-capturing group
+%^^A (?#....) comment (not nestable)
+%^^A (?Jms-UxX) options (duplicate names; multiline; single line;
+%^^A unset what follows; ungreedy; extended;
+%^^A error on bad escapes)
+%^^A (?i:...|...) convenient shorthand for (?:(?i)...|...)
+%^^A (*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE)
+%^^A (*UTF8) set UTF-8 mode (PCRE_UTF8)
+%^^A (*UCP) set PCRE_UCP (use Unicode properties for \d etc)
+%^^A \n or \gn or \g{[-]n} or \g{name} or (?P=name)
+%^^A or \k<name> or \k'name' or \k{name}
+%^^A back-references
diff --git a/macros/latex-dev/required/l3kernel/l3seq.dtx b/macros/latex-dev/required/l3kernel/l3seq.dtx
new file mode 100644
index 0000000000..6be32f7a83
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3seq.dtx
@@ -0,0 +1,2681 @@
+% \iffalse meta-comment
+%
+%% File: l3seq.dtx
+%
+% Copyright (C) 1990-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3seq} module\\ Sequences and stacks^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \LaTeX3 implements a \enquote{sequence} data type, which contain
+% an ordered list of entries which may contain any \meta{balanced text}.
+% It is possible to map functions to sequences such that the function
+% is applied to every item in the sequence.
+%
+% Sequences are also used to implement stack functions in \LaTeX3. This
+% is achieved using a number of dedicated stack functions.
+%
+% \section{Creating and initialising sequences}
+%
+% \begin{function}{\seq_new:N, \seq_new:c}
+% \begin{syntax}
+% \cs{seq_new:N} \meta{seq~var}
+% \end{syntax}
+% Creates a new \meta{seq~var} or raises an error if the name is
+% already taken. The declaration is global. The \meta{seq~var}
+% initially contains no items.
+% \end{function}
+%
+% \begin{function}{\seq_clear:N, \seq_clear:c, \seq_gclear:N, \seq_gclear:c}
+% \begin{syntax}
+% \cs{seq_clear:N} \meta{seq~var}
+% \end{syntax}
+% Clears all items from the \meta{seq~var}.
+% \end{function}
+%
+% \begin{function}
+% {\seq_clear_new:N, \seq_clear_new:c, \seq_gclear_new:N, \seq_gclear_new:c}
+% \begin{syntax}
+% \cs{seq_clear_new:N} \meta{seq~var}
+% \end{syntax}
+% Ensures that the \meta{seq~var} exists globally by applying
+% \cs{seq_new:N} if necessary, then applies
+% \cs[index=seq_clear:N]{seq_(g)clear:N} to leave
+% the \meta{seq~var} empty.
+% \end{function}
+%
+% \begin{function}
+% {
+% \seq_set_eq:NN, \seq_set_eq:cN, \seq_set_eq:Nc, \seq_set_eq:cc,
+% \seq_gset_eq:NN, \seq_gset_eq:cN, \seq_gset_eq:Nc, \seq_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{seq_set_eq:NN} \meta{seq~var_1} \meta{seq~var_2}
+% \end{syntax}
+% Sets the content of \meta{seq~var_1} equal to that of
+% \meta{seq~var_2}.
+% \end{function}
+%
+% \begin{function}[added = 2014-07-17]
+% {
+% \seq_set_from_clist:NN, \seq_set_from_clist:cN,
+% \seq_set_from_clist:Nc, \seq_set_from_clist:cc,
+% \seq_set_from_clist:Nn, \seq_set_from_clist:cn,
+% \seq_gset_from_clist:NN, \seq_gset_from_clist:cN,
+% \seq_gset_from_clist:Nc, \seq_gset_from_clist:cc,
+% \seq_gset_from_clist:Nn, \seq_gset_from_clist:cn
+% }
+% \begin{syntax}
+% \cs{seq_set_from_clist:NN} \meta{seq~var} \meta{comma-list}
+% \end{syntax}
+% Converts the data in the \meta{comma list} into a \meta{seq~var}:
+% the original \meta{comma list} is unchanged.
+% \end{function}
+%
+% \begin{function}[added = 2017-11-28]
+% {\seq_const_from_clist:Nn, \seq_const_from_clist:cn}
+% \begin{syntax}
+% \cs{seq_const_from_clist:Nn} \meta{seq~var} \Arg{comma-list}
+% \end{syntax}
+% Creates a new constant \meta{seq~var} or raises an error if the name
+% is already taken. The \meta{seq~var} is set globally to contain the
+% items in the \meta{comma list}.
+% \end{function}
+%
+% \begin{function}[added = 2011-08-15, updated = 2012-07-02]
+% {
+% \seq_set_split:Nnn ,
+% \seq_set_split:NVn , \seq_set_split:NnV , \seq_set_split:NVV ,
+% \seq_set_split:Nne , \seq_set_split:Nee ,
+% \seq_gset_split:Nnn,
+% \seq_gset_split:NVn , \seq_gset_split:NnV, \seq_gset_split:NVV,
+% \seq_gset_split:Nne , \seq_gset_split:Nee
+% }
+% \begin{syntax}
+% \cs{seq_set_split:Nnn} \meta{seq~var} \Arg{delimiter} \Arg{token list}
+% \end{syntax}
+% Splits the \meta{token list} into \meta{items} separated
+% by \meta{delimiter}, and assigns the result to the \meta{seq~var}.
+% Spaces on both sides of each \meta{item} are ignored,
+% then one set of outer braces is removed (if any);
+% this space trimming behaviour is identical to that of
+% \pkg{l3clist} functions. Empty \meta{items} are preserved by
+% \cs{seq_set_split:Nnn}, and can be removed afterwards using
+% \cs{seq_remove_all:Nn} \meta{seq~var} |{}|.
+% The \meta{delimiter} may not contain |{|, |}| or |#|
+% (assuming \TeX{}'s normal category code r\'egime).
+% If the \meta{delimiter} is empty, the \meta{token list} is split
+% into \meta{items} as a \meta{token list}.
+% See also \cs{seq_set_split_keep_spaces:Nnn}, which omits space stripping.
+% \end{function}
+%
+% \begin{function}[added = 2021-03-24]
+% {
+% \seq_set_split_keep_spaces:Nnn , \seq_set_split_keep_spaces:NnV ,
+% \seq_gset_split_keep_spaces:Nnn, \seq_gset_split_keep_spaces:NnV
+% }
+% \begin{syntax}
+% \cs{seq_set_split_keep_spaces:Nnn} \meta{seq~var} \Arg{delimiter} \Arg{token list}
+% \end{syntax}
+% Splits the \meta{token list} into \meta{items} separated
+% by \meta{delimiter}, and assigns the result to the \meta{seq~var}.
+% One set of outer braces is removed (if any) but any surrounding spaces
+% are retained: any braces \emph{inside} one or more spaces are
+% therefore kept. Empty \meta{items} are preserved by
+% \cs{seq_set_split_keep_spaces:Nnn}, and can be removed afterwards using
+% \cs{seq_remove_all:Nn} \meta{seq~var} |{}|.
+% The \meta{delimiter} may not contain |{|, |}| or |#|
+% (assuming \TeX{}'s normal category code r\'egime).
+% If the \meta{delimiter} is empty, the \meta{token list} is split
+% into \meta{items} as a \meta{token list}.
+% See also \cs{seq_set_split:Nnn}, which removes spaces around the delimiters.
+% \end{function}
+%
+% \begin{function}[added = 2012-06-15]
+% {\seq_set_filter:NNn, \seq_gset_filter:NNn}
+% \begin{syntax}
+% \cs{seq_set_filter:NNn} \meta{seq~var_1} \meta{seq~var_2} \Arg{inline boolexpr}
+% \end{syntax}
+% Evaluates the \meta{inline boolexpr} for every \meta{item} stored
+% within the \meta{seq~var_2}. The \meta{inline boolexpr}
+% receives the \meta{item} as |#1|. The sequence of all \meta{items}
+% for which the \meta{inline boolexpr} evaluated to \texttt{true}
+% is assigned to \meta{seq~var_1}.
+% \begin{texnote}
+% Contrarily to other mapping functions, \cs{seq_map_break:} cannot
+% be used in this function, and would lead to low-level \TeX{} errors.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}
+% {\seq_concat:NNN, \seq_concat:ccc, \seq_gconcat:NNN, \seq_gconcat:ccc}
+% \begin{syntax}
+% \cs{seq_concat:NNN} \meta{seq~var_1} \meta{seq~var_2} \meta{seq~var_3}
+% \end{syntax}
+% Concatenates the content of \meta{seq~var_2} and \meta{seq~var_3}
+% together and saves the result in \meta{seq~var_1}. The items in
+% \meta{seq~var_2} are placed at the left side of the new sequence.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added=2012-03-03]
+% {\seq_if_exist:N, \seq_if_exist:c}
+% \begin{syntax}
+% \cs{seq_if_exist_p:N} \meta{seq~var}
+% \cs{seq_if_exist:NTF} \meta{seq~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{seq~var} is currently defined. This does not
+% check that the \meta{seq~var} really is a sequence variable.
+% \end{function}
+%
+% \section{Appending data to sequences}
+%
+% \begin{function}{
+% \seq_put_left:Nn, \seq_put_left:NV, \seq_put_left:Nv, \seq_put_left:Ne,
+% \seq_put_left:No,
+% \seq_put_left:cn, \seq_put_left:cV, \seq_put_left:cv, \seq_put_left:ce,
+% \seq_put_left:co,
+% \seq_gput_left:Nn, \seq_gput_left:NV, \seq_gput_left:Nv, \seq_gput_left:Ne,
+% \seq_gput_left:No,
+% \seq_gput_left:cn, \seq_gput_left:cV, \seq_gput_left:cv, \seq_gput_left:ce,
+% \seq_gput_left:co
+% }
+% \begin{syntax}
+% \cs{seq_put_left:Nn} \meta{seq~var} \Arg{item}
+% \end{syntax}
+% Appends the \meta{item} to the left of the \meta{seq~var}.
+% \end{function}
+%
+% \begin{function}{
+% \seq_put_right:Nn, \seq_put_right:NV, \seq_put_right:Nv, \seq_put_right:Ne,
+% \seq_put_right:No,
+% \seq_put_right:cn, \seq_put_right:cV, \seq_put_right:cv, \seq_put_right:ce,
+% \seq_put_right:co,
+% \seq_gput_right:Nn, \seq_gput_right:NV, \seq_gput_right:Nv, \seq_gput_right:Ne,
+% \seq_gput_right:No,
+% \seq_gput_right:cn, \seq_gput_right:cV, \seq_gput_right:cv, \seq_gput_right:ce,
+% \seq_gput_right:co,
+% }
+% \begin{syntax}
+% \cs{seq_put_right:Nn} \meta{seq~var} \Arg{item}
+% \end{syntax}
+% Appends the \meta{item} to the right of the \meta{seq~var}.
+% \end{function}
+%
+% \section{Recovering items from sequences}
+%
+% Items can be recovered from either the left or the right of sequences.
+% For implementation reasons, the actions at the left of the sequence are
+% faster than those acting on the right. These functions all assign the
+% recovered material locally, \emph{i.e.}~setting the
+% \meta{token list variable} used with \cs{tl_set:Nn} and \emph{never}
+% \cs{tl_gset:Nn}.
+%
+% \begin{function}[updated = 2012-05-14]{\seq_get_left:NN, \seq_get_left:cN}
+% \begin{syntax}
+% \cs{seq_get_left:NN} \meta{seq~var} \meta{token list variable}
+% \end{syntax}
+% Stores the left-most item from a \meta{seq~var} in the
+% \meta{token list variable} without removing it from the
+% \meta{seq~var}. The \meta{token list variable} is assigned locally.
+% If \meta{seq~var} is empty the \meta{token list variable}
+% is set to the special marker \cs{q_no_value}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-19]{\seq_get_right:NN, \seq_get_right:cN}
+% \begin{syntax}
+% \cs{seq_get_right:NN} \meta{seq~var} \meta{token list variable}
+% \end{syntax}
+% Stores the right-most item from a \meta{seq~var} in the
+% \meta{token list variable} without removing it from the
+% \meta{seq~var}. The \meta{token list variable} is assigned locally.
+% If \meta{seq~var} is empty the \meta{token list variable}
+% is set to the special marker \cs{q_no_value}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-14]{\seq_pop_left:NN, \seq_pop_left:cN}
+% \begin{syntax}
+% \cs{seq_pop_left:NN} \meta{seq~var} \meta{token list variable}
+% \end{syntax}
+% Pops the left-most item from a \meta{seq~var} into the
+% \meta{token list variable}, \emph{i.e.}~removes the item from the
+% sequence and stores it in the \meta{token list variable}.
+% Both of the variables are assigned locally. If \meta{seq~var} is
+% empty the \meta{token list variable} is set to
+% the special marker \cs{q_no_value}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-14]{\seq_gpop_left:NN, \seq_gpop_left:cN}
+% \begin{syntax}
+% \cs{seq_gpop_left:NN} \meta{seq~var} \meta{token list variable}
+% \end{syntax}
+% Pops the left-most item from a \meta{seq~var} into the
+% \meta{token list variable}, \emph{i.e.}~removes the item from the
+% sequence and stores it in the \meta{token list variable}.
+% The \meta{seq~var} is modified globally, while the assignment of
+% the \meta{token list variable} is local.
+% If \meta{seq~var} is empty the \meta{token list variable} is set to
+% the special marker \cs{q_no_value}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-19]{\seq_pop_right:NN, \seq_pop_right:cN}
+% \begin{syntax}
+% \cs{seq_pop_right:NN} \meta{seq~var} \meta{token list variable}
+% \end{syntax}
+% Pops the right-most item from a \meta{seq~var} into the
+% \meta{token list variable}, \emph{i.e.}~removes the item from the
+% sequence and stores it in the \meta{token list variable}.
+% Both of the variables are assigned locally. If \meta{seq~var} is
+% empty the \meta{token list variable} is set to
+% the special marker \cs{q_no_value}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-19]{\seq_gpop_right:NN, \seq_gpop_right:cN}
+% \begin{syntax}
+% \cs{seq_gpop_right:NN} \meta{seq~var} \meta{token list variable}
+% \end{syntax}
+% Pops the right-most item from a \meta{seq~var} into the
+% \meta{token list variable}, \emph{i.e.}~removes the item from the
+% sequence and stores it in the \meta{token list variable}.
+% The \meta{seq~var} is modified globally, while the assignment of
+% the \meta{token list variable} is local.
+% If \meta{seq~var} is empty the \meta{token list variable} is set to
+% the special marker \cs{q_no_value}.
+% \end{function}
+%
+% \begin{function}[added = 2014-07-17, EXP]
+% {
+% \seq_item:Nn, \seq_item:NV, \seq_item:Ne,
+% \seq_item:cn, \seq_item:cV, \seq_item:ce
+% }
+% \begin{syntax}
+% \cs{seq_item:Nn} \meta{seq~var} \Arg{integer expression}
+% \end{syntax}
+% Indexing items in the \meta{seq~var} from~$1$ at the top (left), this
+% function evaluates the \meta{integer expression} and leaves the
+% appropriate item from the sequence in the input stream. If the
+% \meta{integer expression} is negative, indexing occurs from the
+% bottom (right) of the sequence. If the \meta{integer expression}
+% is larger than the number of items in the \meta{seq~var} (as
+% calculated by \cs{seq_count:N}) then the function expands to
+% nothing.
+% \begin{texnote}
+% The result is returned within the \tn{unexpanded}
+% primitive (\cs{exp_not:n}), which means that the \meta{item}
+% does not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2016-12-06]{\seq_rand_item:N, \seq_rand_item:c}
+% \begin{syntax}
+% \cs{seq_rand_item:N} \meta{seq~var}
+% \end{syntax}
+% Selects a pseudo-random item of the \meta{seq~var}. If the
+% \meta{seq~var} is empty the result is empty.
+% This is not available in older versions of \XeTeX{}.
+% \begin{texnote}
+% The result is returned within the \tn{unexpanded}
+% primitive (\cs{exp_not:n}), which means that the \meta{item}
+% does not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \section{Recovering values from sequences with branching}
+%
+% The functions in this section combine tests for non-empty sequences
+% with recovery of an item from the sequence. They offer increased readability
+% and performance over separate testing and recovery phases.
+%
+% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]
+% {\seq_get_left:NN, \seq_get_left:cN}
+% \begin{syntax}
+% \cs{seq_get_left:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
+% input stream. The value of the \meta{token list variable} is
+% not defined in this case and should not be relied upon. If the
+% \meta{seq~var} is non-empty, stores the left-most item from the
+% \meta{seq~var}
+% in the \meta{token list variable} without removing it from the
+% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
+% The \meta{token list variable} is assigned locally.
+% \end{function}
+%
+% \begin{function}[TF, added = 2012-05-19]
+% {\seq_get_right:NN, \seq_get_right:cN}
+% \begin{syntax}
+% \cs{seq_get_right:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
+% input stream. The value of the \meta{token list variable} is
+% not defined in this case and should not be relied upon. If the
+% \meta{seq~var} is non-empty, stores the right-most item from the
+% \meta{seq~var}
+% in the \meta{token list variable} without removing it from the
+% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
+% The \meta{token list variable} is assigned locally.
+% \end{function}
+%
+% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]
+% {\seq_pop_left:NN, \seq_pop_left:cN}
+% \begin{syntax}
+% \cs{seq_pop_left:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
+% input stream. The value of the \meta{token list variable} is
+% not defined in this case and should not be relied upon. If the
+% \meta{seq~var} is non-empty, pops the left-most item from the
+% \meta{seq~var}
+% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
+% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
+% Both the \meta{seq~var} and the \meta{token list variable} are assigned
+% locally.
+% \end{function}
+%
+% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]
+% {\seq_gpop_left:NN, \seq_gpop_left:cN}
+% \begin{syntax}
+% \cs{seq_gpop_left:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
+% input stream. The value of the \meta{token list variable} is
+% not defined in this case and should not be relied upon. If the
+% \meta{seq~var} is non-empty, pops the left-most item from the \meta{seq~var}
+% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
+% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
+% The \meta{seq~var} is modified globally, while the \meta{token list variable}
+% is assigned locally.
+% \end{function}
+%
+% \begin{function}[TF, added = 2012-05-19]
+% {\seq_pop_right:NN, \seq_pop_right:cN}
+% \begin{syntax}
+% \cs{seq_pop_right:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
+% input stream. The value of the \meta{token list variable} is
+% not defined in this case and should not be relied upon. If the
+% \meta{seq~var} is non-empty, pops the right-most item from the \meta{seq~var}
+% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
+% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
+% Both the \meta{seq~var} and the \meta{token list variable} are assigned
+% locally.
+% \end{function}
+%
+% \begin{function}[TF, added = 2012-05-19]
+% {\seq_gpop_right:NN, \seq_gpop_right:cN}
+% \begin{syntax}
+% \cs{seq_gpop_right:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
+% input stream. The value of the \meta{token list variable} is
+% not defined in this case and should not be relied upon. If the
+% \meta{seq~var} is non-empty, pops the right-most item from the \meta{seq~var}
+% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
+% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
+% The \meta{seq~var} is modified globally, while the
+% \meta{token list variable} is assigned locally.
+% \end{function}
+%
+% \section{Modifying sequences}
+%
+% While sequences are normally used as ordered lists, it may be
+% necessary to modify the content. The functions here may be used
+% to update sequences, while retaining the order of the unaffected
+% entries.
+%
+% \begin{function}
+% {
+% \seq_remove_duplicates:N, \seq_remove_duplicates:c,
+% \seq_gremove_duplicates:N, \seq_gremove_duplicates:c
+% }
+% \begin{syntax}
+% \cs{seq_remove_duplicates:N} \meta{seq~var}
+% \end{syntax}
+% Removes duplicate items from the \meta{seq~var}, leaving the
+% left most copy of each item in the \meta{seq~var}. The \meta{item}
+% comparison takes place on a token basis, as for \cs{tl_if_eq:nnTF}.
+% \begin{texnote}
+% This function iterates through every item in the \meta{seq~var} and
+% does a comparison with the \meta{items} already checked. It is therefore
+% relatively slow with large sequences.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}
+% {
+% \seq_remove_all:Nn, \seq_remove_all:NV, \seq_remove_all:Ne,
+% \seq_remove_all:cn, \seq_remove_all:cV, \seq_remove_all:ce,
+% \seq_gremove_all:Nn, \seq_gremove_all:NV, \seq_gremove_all:Ne,
+% \seq_gremove_all:cn, \seq_gremove_all:cV, \seq_gremove_all:ce
+% }
+% \begin{syntax}
+% \cs{seq_remove_all:Nn} \meta{seq~var} \Arg{item}
+% \end{syntax}
+% Removes every occurrence of \meta{item} from the \meta{seq~var}.
+% The \meta{item} comparison takes place on a token basis, as for
+% \cs{tl_if_eq:nnTF}.
+% \end{function}
+%
+% \begin{function}[added = 2021-04-29, noTF]
+% {\seq_set_item:Nnn, \seq_set_item:cnn, \seq_gset_item:Nnn, \seq_gset_item:cnn}
+% \begin{syntax}
+% \cs{seq_set_item:Nnn} \meta{seq~var} \Arg{int expr} \Arg{item}
+% \cs{seq_set_item:NnnTF} \meta{seq~var} \Arg{int expr} \Arg{item} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Removes the item of \meta{seq~var} at the position given by
+% evaluating the \meta{int expr} and replaces it by
+% \meta{item}. Items are indexed from $1$ on the left/top of the
+% \meta{seq~var}, or from $-1$ on the right/bottom. If the
+% \meta{int expr} is zero or is larger (in absolute value)
+% than the number of items in the sequence, the \meta{seq~var} is not
+% modified. In these cases, \cs{seq_set_item:Nnn} raises an error
+% while \cs{seq_set_item:NnnTF} runs the \meta{false code}. In cases
+% where the assignment was successful, \meta{true code} is run
+% afterwards.
+% \end{function}
+%
+% \begin{function}[added = 2014-07-18]
+% {
+% \seq_reverse:N, \seq_reverse:c,
+% \seq_greverse:N, \seq_greverse:c
+% }
+% \begin{syntax}
+% \cs{seq_reverse:N} \meta{seq~var}
+% \end{syntax}
+% Reverses the order of the items stored in the \meta{seq~var}.
+% \end{function}
+%
+% \begin{function}[added = 2017-02-06]
+% {\seq_sort:Nn, \seq_sort:cn, \seq_gsort:Nn, \seq_gsort:cn}
+% \begin{syntax}
+% \cs{seq_sort:Nn} \meta{seq~var} \Arg{comparison code}
+% \end{syntax}
+% Sorts the items in the \meta{seq~var} according to the
+% \meta{comparison code}, and assigns the result to
+% \meta{seq~var}. The details of sorting comparison are
+% described in Section~\ref{sec:l3sort:mech}.
+% \end{function}
+%
+% \begin{function}[added = 2018-04-29]
+% {\seq_shuffle:N, \seq_shuffle:c, \seq_gshuffle:N, \seq_gshuffle:c}
+% \begin{syntax}
+% \cs{seq_shuffle:N} \meta{seq~var}
+% \end{syntax}
+% Sets the \meta{seq~var} to the result of placing the items of the
+% \meta{seq~var} in a random order. Each item is (roughly) as likely
+% to end up in any given position.
+% \begin{texnote}
+% For sequences with more than $13$ items or so, only a small
+% proportion of all possible permutations can be reached, because
+% the random seed \cs{sys_rand_seed:} only has $28$-bits. The use
+% of \tn{toks} internally means that sequences with more than
+% $32767$ or $65535$ items (depending on the engine) cannot be
+% shuffled.
+% \end{texnote}
+% \end{function}
+%
+% \section{Sequence conditionals}
+%
+% \begin{function}[EXP,pTF]{\seq_if_empty:N, \seq_if_empty:c}
+% \begin{syntax}
+% \cs{seq_if_empty_p:N} \meta{seq~var}
+% \cs{seq_if_empty:NTF} \meta{seq~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{seq~var} is empty (containing no items).
+% \end{function}
+%
+% \begin{function}[TF]
+% {
+% \seq_if_in:Nn, \seq_if_in:NV, \seq_if_in:Nv, \seq_if_in:Ne,
+% \seq_if_in:No,
+% \seq_if_in:cn, \seq_if_in:cV, \seq_if_in:cv, \seq_if_in:ce,
+% \seq_if_in:co,
+% }
+% \begin{syntax}
+% \cs{seq_if_in:NnTF} \meta{seq~var} \Arg{item} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{item} is present in the \meta{seq~var}.
+% \end{function}
+%
+% \section{Mapping over sequences}
+%
+% All mappings are done at the current group level, \emph{i.e.}~any
+% local assignments made by the \meta{function} or \meta{code} discussed
+% below remain in effect after the loop.
+%
+% \begin{function}[rEXP, updated = 2012-06-29]
+% {\seq_map_function:NN, \seq_map_function:cN}
+% \begin{syntax}
+% \cs{seq_map_function:NN} \meta{seq~var} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every \meta{item} stored in the
+% \meta{seq~var}. The \meta{function} will receive one argument for
+% each iteration. The \meta{items} are returned from left to right.
+% To pass further arguments to the \meta{function}, see
+% \cs{seq_map_tokens:Nn}.
+% The function \cs{seq_map_inline:Nn} is faster than
+% \cs{seq_map_function:NN} for sequences with more than about~$10$
+% items.
+% \end{function}
+%
+% \begin{function}[updated = 2012-06-29]
+% {\seq_map_inline:Nn, \seq_map_inline:cn}
+% \begin{syntax}
+% \cs{seq_map_inline:Nn} \meta{seq~var} \Arg{inline function}
+% \end{syntax}
+% Applies \meta{inline function} to every \meta{item} stored
+% within the \meta{seq~var}. The \meta{inline function} should
+% consist of code which will receive the \meta{item} as |#1|.
+% The \meta{items} are returned from left to right.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2019-08-30]
+% {\seq_map_tokens:Nn, \seq_map_tokens:cn}
+% \begin{syntax}
+% \cs{seq_map_tokens:Nn} \meta{seq~var} \Arg{code}
+% \end{syntax}
+% Analogue of \cs{seq_map_function:NN} which maps several tokens
+% instead of a single function. The \meta{code} receives each item in
+% the \meta{seq~var} as a trailing brace group. For instance,
+% \begin{verbatim}
+% \seq_map_tokens:Nn \l_my_seq { \prg_replicate:nn { 2 } }
+% \end{verbatim}
+% expands to twice each item in the \meta{seq~var}: for each item in
+% |\l_my_seq| the function \cs{prg_replicate:nn} receives |2| and
+% \meta{item} as its two arguments. The function
+% \cs{seq_map_inline:Nn} is typically faster but it is not expandable.
+% \end{function}
+%
+% \begin{function}[updated = 2012-06-29]
+% {
+% \seq_map_variable:NNn, \seq_map_variable:Ncn,
+% \seq_map_variable:cNn, \seq_map_variable:ccn
+% }
+% \begin{syntax}
+% \cs{seq_map_variable:NNn} \meta{seq~var} \meta{variable} \Arg{code}
+% \end{syntax}
+% Stores each \meta{item} of the \meta{seq~var} in turn in the (token
+% list) \meta{variable} and applies the \meta{code}. The \meta{code}
+% will usually make use of the \meta{variable}, but this is not
+% enforced. The assignments to the \meta{variable} are local. Its
+% value after the loop is the last \meta{item} in the \meta{seq~var},
+% or its original value if the \meta{seq~var} is empty. The
+% \meta{items} are returned from left to right.
+% \end{function}
+%
+% \begin{function}[rEXP,added = 2018-05-03]{\seq_map_indexed_function:NN}
+% \begin{syntax}
+% \cs{seq_map_indexed_function:NN} \meta{seq~var} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every entry in the \meta{seq~var}.
+% The \meta{function} should have signature |:nn|. It
+% receives two arguments for each iteration: the \meta{index} (namely
+% |1| for the first entry, then |2| and so on) and the \meta{item}.
+% \end{function}
+%
+% \begin{function}[added = 2018-05-03]{\seq_map_indexed_inline:Nn}
+% \begin{syntax}
+% \cs{seq_map_indexed_inline:Nn} \meta{seq~var} \Arg{inline function}
+% \end{syntax}
+% Applies \meta{inline function} to every entry in the \meta{seq~var}.
+% The \meta{inline function} should consist of code which
+% receives the \meta{index} (namely |1| for the first entry, then |2|
+% and so on) as~|#1| and the \meta{item} as~|#2|.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2023-05-10]
+% {
+% \seq_map_pairwise_function:NNN, \seq_map_pairwise_function:NcN,
+% \seq_map_pairwise_function:cNN, \seq_map_pairwise_function:ccN
+% }
+% \begin{syntax}
+% \cs{seq_map_pairwise_function:NNN} \meta{seq_1} \meta{seq_2} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every pair of items
+% \meta{seq_1-item}--\meta{seq_2-item} from the two sequences, returning
+% items from both sequences from left to right. The \meta{function}
+% receives two \texttt{n}-type arguments for each iteration. The mapping
+% terminates when
+% the end of either sequence is reached (\emph{i.e.}~whichever sequence has
+% fewer items determines how many iterations
+% occur).
+% \end{function}
+%
+% \begin{function}[rEXP, updated = 2012-06-29]{\seq_map_break:}
+% \begin{syntax}
+% \cs{seq_map_break:}
+% \end{syntax}
+% Used to terminate a \cs[no-index]{seq_map_\ldots} function before all
+% entries in the \meta{seq~var} have been processed. This
+% normally takes place within a conditional statement, for example
+% \begin{verbatim}
+% \seq_map_inline:Nn \l_my_seq
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \seq_map_break: }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs[no-index]{seq_map_\ldots} scenario leads to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted
+% before further items are taken
+% from the input stream. This depends on the design of the mapping
+% function.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[rEXP, updated = 2012-06-29]{\seq_map_break:n}
+% \begin{syntax}
+% \cs{seq_map_break:n} \Arg{code}
+% \end{syntax}
+% Used to terminate a \cs[no-index]{seq_map_\ldots} function before all
+% entries in the \meta{seq~var} have been processed, inserting
+% the \meta{code} after the mapping has ended. This
+% normally takes place within a conditional statement, for example
+% \begin{verbatim}
+% \seq_map_inline:Nn \l_my_seq
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \seq_map_break:n { <code> } }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs[no-index]{seq_map_\ldots} scenario leads to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted
+% before the \meta{code} is
+% inserted into the input stream.
+% This depends on the design of the mapping function.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2011-12-22, updated = 2020-07-16]
+% {\seq_set_map:NNn, \seq_gset_map:NNn}
+% \begin{syntax}
+% \cs{seq_set_map:NNn} \meta{seq~var_1} \meta{seq~var_2} \Arg{inline function}
+% \end{syntax}
+% Applies \meta{inline function} to every \meta{item} stored
+% within the \meta{seq~var_2}. The \meta{inline function} should
+% consist of code which will receive the \meta{item} as |#1|.
+% The sequence resulting applying \meta{inline function} to each
+% \meta{item} is assigned to \meta{seq~var_1}.
+% \begin{texnote}
+% Contrarily to other mapping functions, \cs{seq_map_break:} cannot
+% be used in this function, and would lead to low-level \TeX{} errors.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2020-07-16, updated = 2023-10-26]
+% {\seq_set_map_e:NNn, \seq_gset_map_e:NNn}
+% \begin{syntax}
+% \cs{seq_set_map_e:NNn} \meta{seq~var_1} \meta{seq~var_2} \Arg{inline function}
+% \end{syntax}
+% Applies \meta{inline function} to every \meta{item} stored
+% within the \meta{seq~var_2}. The \meta{inline function} should
+% consist of code which will receive the \meta{item} as |#1|.
+% The sequence resulting from \texttt{e}-expanding
+% \meta{inline function} applied to each \meta{item}
+% is assigned to \meta{seq~var_1}. As such, the code
+% in \meta{inline function} should be expandable.
+% \begin{texnote}
+% Contrarily to other mapping functions, \cs{seq_map_break:} cannot
+% be used in this function, and would lead to low-level \TeX{} errors.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2012-07-13]{\seq_count:N, \seq_count:c}
+% \begin{syntax}
+% \cs{seq_count:N} \meta{seq~var}
+% \end{syntax}
+% Leaves the number of items in the \meta{seq~var} in the input
+% stream as an \meta{integer denotation}. The total number of items
+% in a \meta{seq~var} includes those which are empty and duplicates,
+% \emph{i.e.}~every item in a \meta{seq~var} is unique.
+% \end{function}
+%
+% \section{Using the content of sequences directly}
+%
+% \begin{function}[EXP, added = 2013-05-26]{\seq_use:Nnnn, \seq_use:cnnn}
+% \begin{syntax}
+% \cs{seq_use:Nnnn} \meta{seq~var} \Arg{separator~between~two} \Arg{separator~between~more~than~two} \Arg{separator~between~final~two}
+% \end{syntax}
+% Places the contents of the \meta{seq~var} in the input stream, with
+% the appropriate \meta{separator} between the items. Namely, if the
+% sequence has more than two items, the \meta{separator between more
+% than two} is placed between each pair of items except the last,
+% for which the \meta{separator between final two} is used. If the
+% sequence has exactly two items, then they are placed in the input stream
+% separated by the \meta{separator between two}. If the sequence has
+% a single item, it is placed in the input stream, and an empty sequence
+% produces no output. An error is raised if the variable does
+% not exist or if it is invalid.
+%
+% For example,
+% \begin{verbatim}
+% \seq_set_split:Nnn \l_tmpa_seq { | } { a | b | c | {de} | f }
+% \seq_use:Nnnn \l_tmpa_seq { ~and~ } { ,~ } { ,~and~ }
+% \end{verbatim}
+% inserts \enquote{\texttt{a, b, c, de, and f}} in the input
+% stream. The first separator argument is not used in this case
+% because the sequence has more than $2$ items.
+% \begin{texnote}
+% The result is returned within the \tn{unexpanded}
+% primitive (\cs{exp_not:n}), which means that the \meta{items}
+% do not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2013-05-26]{\seq_use:Nn, \seq_use:cn}
+% \begin{syntax}
+% \cs{seq_use:Nn} \meta{seq~var} \Arg{separator}
+% \end{syntax}
+% Places the contents of the \meta{seq~var} in the input stream, with
+% the \meta{separator} between the items. If the sequence has
+% a single item, it is placed in the input stream with no \meta{separator},
+% and an empty sequence produces no output. An error is raised if
+% the variable does not exist or if it is invalid.
+%
+% For example,
+% \begin{verbatim}
+% \seq_set_split:Nnn \l_tmpa_seq { | } { a | b | c | {de} | f }
+% \seq_use:Nn \l_tmpa_seq { ~and~ }
+% \end{verbatim}
+% inserts \enquote{\texttt{a and b and c and de and f}} in the input
+% stream.
+% \begin{texnote}
+% The result is returned within the \tn{unexpanded}
+% primitive (\cs{exp_not:n}), which means that the \meta{items}
+% do not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \section{Sequences as stacks}
+%
+% Sequences can be used as stacks, where data is pushed to and popped
+% from the top of the sequence. (The left of a sequence is the top, for
+% performance reasons.) The stack functions for sequences are not
+% intended to be mixed with the general ordered data functions detailed
+% in the previous section: a sequence should either be used as an
+% ordered data type or as a stack, but not in both ways.
+%
+% \begin{function}[updated = 2012-05-14]{\seq_get:NN, \seq_get:cN}
+% \begin{syntax}
+% \cs{seq_get:NN} \meta{seq~var} \meta{token list variable}
+% \end{syntax}
+% Reads the top item from a \meta{seq~var} into the
+% \meta{token list variable} without removing it from the
+% \meta{seq~var}. The \meta{token list variable} is assigned locally.
+% If \meta{seq~var} is empty the \meta{token list variable} is set to
+% the special marker \cs{q_no_value}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-14]{\seq_pop:NN, \seq_pop:cN}
+% \begin{syntax}
+% \cs{seq_pop:NN} \meta{seq~var} \meta{token list variable}
+% \end{syntax}
+% Pops the top item from a \meta{seq~var} into the
+% \meta{token list variable}. Both of the variables are assigned
+% locally. If \meta{seq~var} is empty the \meta{token list variable}
+% is set to the special marker \cs{q_no_value}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-14]{\seq_gpop:NN, \seq_gpop:cN}
+% \begin{syntax}
+% \cs{seq_gpop:NN} \meta{seq~var} \meta{token list variable}
+% \end{syntax}
+% Pops the top item from a \meta{seq~var} into the
+% \meta{token list variable}. The \meta{seq~var} is modified globally,
+% while the \meta{token list variable} is assigned locally. If
+% \meta{seq~var} is empty the \meta{token list variable} is set to
+% the special marker \cs{q_no_value}.
+% \end{function}
+%
+% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]{\seq_get:NN, \seq_get:cN}
+% \begin{syntax}
+% \cs{seq_get:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
+% input stream. The value of the \meta{token list variable} is
+% not defined in this case and should not be relied upon. If the
+% \meta{seq~var} is non-empty, stores the top item from a
+% \meta{seq~var} in the \meta{token list variable} without removing it from
+% the \meta{seq~var}. The \meta{token list variable} is assigned locally.
+% \end{function}
+%
+% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]{\seq_pop:NN, \seq_pop:cN}
+% \begin{syntax}
+% \cs{seq_pop:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
+% input stream. The value of the \meta{token list variable} is
+% not defined in this case and should not be relied upon. If the
+% \meta{seq~var} is non-empty, pops the top item from the
+% \meta{seq~var} in the \meta{token list variable}, \emph{i.e.}~removes the
+% item from the \meta{seq~var}. Both the \meta{seq~var} and the
+% \meta{token list variable} are assigned locally.
+% \end{function}
+%
+% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]{\seq_gpop:NN, \seq_gpop:cN}
+% \begin{syntax}
+% \cs{seq_gpop:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
+% input stream. The value of the \meta{token list variable} is
+% not defined in this case and should not be relied upon. If the
+% \meta{seq~var} is non-empty, pops the top item from the \meta{seq~var}
+% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
+% \meta{seq~var}. The \meta{seq~var} is modified globally, while the
+% \meta{token list variable} is assigned locally.
+% \end{function}
+%
+% \begin{function}
+% {
+% \seq_push:Nn, \seq_push:NV, \seq_push:Nv, \seq_push:Ne,
+% \seq_push:No,
+% \seq_push:cn, \seq_push:cV, \seq_push:cv, \seq_push:ce,
+% \seq_push:co,
+% \seq_gpush:Nn, \seq_gpush:NV, \seq_gpush:Nv, \seq_gpush:Ne,
+% \seq_gpush:No,
+% \seq_gpush:cn, \seq_gpush:cV, \seq_gpush:cv, \seq_gpush:ce,
+% \seq_gpush:co
+% }
+% \begin{syntax}
+% \cs{seq_push:Nn} \meta{seq~var} \Arg{item}
+% \end{syntax}
+% Adds the \Arg{item} to the top of the \meta{seq~var}.
+% \end{function}
+%
+% \section{Sequences as sets}
+%
+% Sequences can also be used as sets, such that all of their items are
+% distinct. Usage of sequences as sets is not currently widespread,
+% hence no specific set function is provided. Instead, it is explained
+% here how common set operations can be performed by combining several
+% functions described in earlier sections. When using sequences to
+% implement sets, one should be careful not to rely on the order of
+% items in the sequence representing the set.
+%
+% Sets should not contain several occurrences of a given item. To make
+% sure that a \meta{seq~var} only has distinct items, use
+% \cs{seq_remove_duplicates:N} \meta{seq~var}. This function
+% is relatively slow, and to avoid performance issues one should only
+% use it when necessary.
+%
+% Some operations on a set \meta{seq~var} are straightforward. For
+% instance, \cs{seq_count:N} \meta{seq~var} expands to the number of
+% items, while \cs{seq_if_in:NnTF} \meta{seq~var} \Arg{item} tests if
+% the \meta{item} is in the set.
+%
+% Adding an \meta{item} to a set \meta{seq~var} can be done by appending
+% it to the \meta{seq~var} if it is not already in the \meta{seq~var}:
+% \begin{quote}\ttfamily\parskip=0pt\obeylines
+% \cs{seq_if_in:NnF} \meta{seq~var} \Arg{item}
+% | |\{ \cs{seq_put_right:Nn} \meta{seq~var} \Arg{item} \}
+% \end{quote}
+% Removing an \meta{item} from a set \meta{seq~var} can be done using
+% \cs{seq_remove_all:Nn},
+% \begin{quote}\ttfamily
+% \cs{seq_remove_all:Nn} \meta{seq~var} \Arg{item}
+% \end{quote}
+%
+% The intersection of two sets \meta{seq~var_1} and \meta{seq~var_2} can
+% be stored into \meta{seq~var_3} by collecting items of
+% \meta{seq~var_1} which are in \meta{seq~var_2}.
+% \begin{quote}\ttfamily\parskip=0pt\obeylines
+% \cs{seq_clear:N} \meta{seq~var_3}
+% \cs{seq_map_inline:Nn} \meta{seq~var_1}
+% | |\{
+% | |\cs{seq_if_in:NnT} \meta{seq~var_2} \{\#1\}
+% | |\{ \cs{seq_put_right:Nn} \meta{seq~var_3} \{\#1\} \}
+% | |\}
+% \end{quote}
+% The code as written here only works if \meta{seq~var_3} is different
+% from the other two sequence variables. To cover all cases, items
+% should first be collected in a sequence
+% |\l__|\meta{pkg}|_internal_seq|, then \meta{seq~var_3} should be set
+% equal to this internal sequence. The same remark applies to other set
+% functions.
+%
+% The union of two sets \meta{seq~var_1} and \meta{seq~var_2} can be
+% stored into \meta{seq~var_3} through
+% \begin{quote}\ttfamily
+% \cs{seq_concat:NNN} \meta{seq~var_3} \meta{seq~var_1} \meta{seq~var_2} \\
+% \cs{seq_remove_duplicates:N} \meta{seq~var_3}
+% \end{quote}
+% or by adding items to (a copy of) \meta{seq~var_1} one by one
+% \begin{quote}\ttfamily\parskip=0pt\obeylines
+% \cs{seq_set_eq:NN} \meta{seq~var_3} \meta{seq~var_1}
+% \cs{seq_map_inline:Nn} \meta{seq~var_2}
+% | |\{
+% | |\cs{seq_if_in:NnF} \meta{seq~var_3} \{\#1\}
+% | |\{ \cs{seq_put_right:Nn} \meta{seq~var_3} \{\#1\} \}
+% | |\}
+% \end{quote}
+% The second approach is faster than the first when the \meta{seq~var_2}
+% is short compared to \meta{seq~var_1}.
+%
+% The difference of two sets \meta{seq~var_1} and \meta{seq~var_2} can
+% be stored into \meta{seq~var_3} by removing items of the
+% \meta{seq~var_2} from (a copy of) the \meta{seq~var_1} one by one.
+% \begin{quote}\ttfamily\parskip=0pt\obeylines
+% \cs{seq_set_eq:NN} \meta{seq~var_3} \meta{seq~var_1}
+% \cs{seq_map_inline:Nn} \meta{seq~var_2}
+% | |\{ \cs{seq_remove_all:Nn} \meta{seq~var_3} \{\#1\} \}
+% \end{quote}
+%
+% The symmetric difference of two sets \meta{seq~var_1} and
+% \meta{seq~var_2} can be stored into \meta{seq~var_3} by computing the
+% difference between \meta{seq~var_1} and \meta{seq~var_2} and storing
+% the result as |\l__|\meta{pkg}|_internal_seq|, then the difference
+% between \meta{seq~var_2} and \meta{seq~var_1}, and finally
+% concatenating the two differences to get the symmetric differences.
+% \begin{quote}\ttfamily\parskip=0pt\obeylines
+% \cs{seq_set_eq:NN} |\l__|\meta{pkg}|_internal_seq| \meta{seq~var_1}
+% \cs{seq_map_inline:Nn} \meta{seq~var_2}
+% | |\{ \cs{seq_remove_all:Nn} |\l__|\meta{pkg}|_internal_seq| \{\#1\} \}
+% \cs{seq_set_eq:NN} \meta{seq~var_3} \meta{seq~var_2}
+% \cs{seq_map_inline:Nn} \meta{seq~var_1}
+% | |\{ \cs{seq_remove_all:Nn} \meta{seq~var_3} \{\#1\} \}
+% \cs{seq_concat:NNN} \meta{seq~var_3} \meta{seq~var_3} |\l__|\meta{pkg}|_internal_seq|
+% \end{quote}
+%
+% \section{Constant and scratch sequences}
+%
+% \begin{variable}[added = 2012-07-02]{\c_empty_seq}
+% Constant that is always empty.
+% \end{variable}
+%
+% \begin{variable}[added = 2012-04-26]{\l_tmpa_seq, \l_tmpb_seq}
+% Scratch sequences for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}[added = 2012-04-26]{\g_tmpa_seq, \g_tmpb_seq}
+% Scratch sequences for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Viewing sequences}
+%
+% \begin{function}[updated = 2021-04-29]{\seq_show:N, \seq_show:c}
+% \begin{syntax}
+% \cs{seq_show:N} \meta{seq~var}
+% \end{syntax}
+% Displays the entries in the \meta{seq~var} in the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-12, updated = 2021-04-29]{\seq_log:N, \seq_log:c}
+% \begin{syntax}
+% \cs{seq_log:N} \meta{seq~var}
+% \end{syntax}
+% Writes the entries in the \meta{seq~var} in the log file.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3seq} implementation}
+%
+% \TestFiles{m3seq002,m3seq003}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=seq>
+% \end{macrocode}
+%
+% A sequence is a control sequence whose top-level expansion is of the
+% form \enquote{\cs{s_@@} \cs{@@_item:n} \marg{item_1} \ldots
+% \cs{@@_item:n} \marg{item_n}}, with a leading scan
+% mark followed by $n$~items of the same form. An
+% earlier implementation used the structure \enquote{\cs{seq_elt:w}
+% \meta{item_1} \cs{seq_elt_end:} \ldots \cs{seq_elt:w} \meta{item_n}
+% \cs{seq_elt_end:}}. This allowed rapid searching using a delimited
+% function, but was not suitable for items containing |{|, |}| and |#|
+% tokens, and also lead to the loss of surrounding braces around items
+%
+% \begin{function}[EXP]{\@@_item:n}
+% \begin{syntax}
+% \cs{@@_item:n} \Arg{item}
+% \end{syntax}
+% The internal token used to begin each sequence entry. If expanded
+% outside of a mapping or manipulation function, an error is
+% raised. The definition should always be set globally.
+% \end{function}
+%
+% \begin{function}{\@@_push_item_def:n, \@@_push_item_def:e}
+% \begin{syntax}
+% \cs{@@_push_item_def:n} \Arg{code}
+% \end{syntax}
+% Saves the definition of \cs{@@_item:n} and redefines it to
+% accept one parameter and expand to \meta{code}. This function
+% should always be balanced by use of \cs{@@_pop_item_def:}.
+% \end{function}
+%
+% \begin{function}{\@@_pop_item_def:}
+% \begin{syntax}
+% \cs{@@_pop_item_def:}
+% \end{syntax}
+% Restores the definition of \cs{@@_item:n} most recently saved by
+% \cs{@@_push_item_def:n}. This function should always be used in
+% a balanced pair with \cs{@@_push_item_def:n}.
+% \end{function}
+%
+% \begin{variable}{\s_@@}
+% This private scan mark.
+% \begin{macrocode}
+\scan_new:N \s_@@
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\s_@@_mark,\s_@@_stop}
+% Private scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_item:n}
+% The delimiter is always defined, but when used incorrectly simply
+% removes its argument and hits an undefined control sequence to
+% raise an error.
+% \begin{macrocode}
+\cs_new:Npn \@@_item:n
+ {
+ \msg_expandable_error:nn { seq } { misused }
+ \use_none:n
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_internal_a_tl, \l_@@_internal_b_tl}
+% Scratch space for various internal uses.
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_a_tl
+\tl_new:N \l_@@_internal_b_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_tmp:w}
+% Scratch function for internal use.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_tmp:w ?
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\c_empty_seq}
+% A sequence with no item, following the structure mentioned above.
+% \begin{macrocode}
+\tl_const:Nn \c_empty_seq { \s_@@ }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Allocation and initialisation}
+%
+% \begin{macro}{\seq_new:N, \seq_new:c}
+% \UnitTested
+% Sequences are initialized to \cs{c_empty_seq}.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_new:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \cs_gset_eq:NN #1 \c_empty_seq
+ }
+\cs_generate_variant:Nn \seq_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\seq_clear:N, \seq_clear:c}
+% \UnitTested
+% \begin{macro}{\seq_gclear:N, \seq_gclear:c}
+% \UnitTested
+% Clearing a sequence is similar to setting it equal to the empty one.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_clear:N #1
+ { \seq_set_eq:NN #1 \c_empty_seq }
+\cs_generate_variant:Nn \seq_clear:N { c }
+\cs_new_protected:Npn \seq_gclear:N #1
+ { \seq_gset_eq:NN #1 \c_empty_seq }
+\cs_generate_variant:Nn \seq_gclear:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_clear_new:N, \seq_clear_new:c}
+% \UnitTested
+% \begin{macro}{\seq_gclear_new:N, \seq_gclear_new:c}
+% \UnitTested
+% Once again we copy code from the token list functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_clear_new:N #1
+ { \seq_if_exist:NTF #1 { \seq_clear:N #1 } { \seq_new:N #1 } }
+\cs_generate_variant:Nn \seq_clear_new:N { c }
+\cs_new_protected:Npn \seq_gclear_new:N #1
+ { \seq_if_exist:NTF #1 { \seq_gclear:N #1 } { \seq_new:N #1 } }
+\cs_generate_variant:Nn \seq_gclear_new:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_set_eq:NN, \seq_set_eq:cN, \seq_set_eq:Nc, \seq_set_eq:cc}
+% \UnitTested
+% \begin{macro}
+% {\seq_gset_eq:NN, \seq_gset_eq:cN, \seq_gset_eq:Nc, \seq_gset_eq:cc}
+% \UnitTested
+% Copying a sequence is the same as copying the underlying token list.
+% \begin{macrocode}
+\cs_new_eq:NN \seq_set_eq:NN \tl_set_eq:NN
+\cs_new_eq:NN \seq_set_eq:Nc \tl_set_eq:Nc
+\cs_new_eq:NN \seq_set_eq:cN \tl_set_eq:cN
+\cs_new_eq:NN \seq_set_eq:cc \tl_set_eq:cc
+\cs_new_eq:NN \seq_gset_eq:NN \tl_gset_eq:NN
+\cs_new_eq:NN \seq_gset_eq:Nc \tl_gset_eq:Nc
+\cs_new_eq:NN \seq_gset_eq:cN \tl_gset_eq:cN
+\cs_new_eq:NN \seq_gset_eq:cc \tl_gset_eq:cc
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \seq_set_from_clist:NN, \seq_set_from_clist:cN,
+% \seq_set_from_clist:Nc, \seq_set_from_clist:cc,
+% \seq_set_from_clist:Nn, \seq_set_from_clist:cn
+% }
+% \begin{macro}
+% {
+% \seq_gset_from_clist:NN, \seq_gset_from_clist:cN,
+% \seq_gset_from_clist:Nc, \seq_gset_from_clist:cc,
+% \seq_gset_from_clist:Nn, \seq_gset_from_clist:cn
+% }
+% Setting a sequence from a comma-separated list is done using a simple
+% mapping.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_set_from_clist:NN #1#2
+ {
+ \__kernel_tl_set:Nx #1
+ { \s_@@ \clist_map_function:NN #2 \@@_wrap_item:n }
+ }
+\cs_new_protected:Npn \seq_set_from_clist:Nn #1#2
+ {
+ \__kernel_tl_set:Nx #1
+ { \s_@@ \clist_map_function:nN {#2} \@@_wrap_item:n }
+ }
+\cs_new_protected:Npn \seq_gset_from_clist:NN #1#2
+ {
+ \__kernel_tl_gset:Nx #1
+ { \s_@@ \clist_map_function:NN #2 \@@_wrap_item:n }
+ }
+\cs_new_protected:Npn \seq_gset_from_clist:Nn #1#2
+ {
+ \__kernel_tl_gset:Nx #1
+ { \s_@@ \clist_map_function:nN {#2} \@@_wrap_item:n }
+ }
+\cs_generate_variant:Nn \seq_set_from_clist:NN { Nc }
+\cs_generate_variant:Nn \seq_set_from_clist:NN { c , cc }
+\cs_generate_variant:Nn \seq_set_from_clist:Nn { c }
+\cs_generate_variant:Nn \seq_gset_from_clist:NN { Nc }
+\cs_generate_variant:Nn \seq_gset_from_clist:NN { c , cc }
+\cs_generate_variant:Nn \seq_gset_from_clist:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_const_from_clist:Nn, \seq_const_from_clist:cn}
+% Almost identical to \cs{seq_set_from_clist:Nn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_const_from_clist:Nn #1#2
+ {
+ \tl_const:Ne #1
+ { \s_@@ \clist_map_function:nN {#2} \@@_wrap_item:n }
+ }
+\cs_generate_variant:Nn \seq_const_from_clist:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \seq_set_split:Nnn ,
+% \seq_set_split:NVn , \seq_set_split:NnV , \seq_set_split:NVV ,
+% \seq_set_split:Nne , \seq_set_split:Nee ,
+% \seq_set_split:Nnx , \seq_set_split:Nxx ,
+% \seq_gset_split:Nnn,
+% \seq_gset_split:NVn, \seq_gset_split:NnV, \seq_gset_split:NVV,
+% \seq_gset_split:Nne, \seq_gset_split:Nee,
+% \seq_gset_split:Nnx, \seq_gset_split:Nxx
+% }
+% \begin{macro}
+% {
+% \seq_set_split_keep_spaces:Nnn , \seq_set_split_keep_spaces:NnV ,
+% \seq_gset_split_keep_spaces:Nnn, \seq_gset_split_keep_spaces:NnV
+% }
+% \begin{macro}{\@@_set_split:NNnn}
+% \begin{macro}
+% {
+% \@@_set_split:Nw, \@@_set_split:w,
+% \@@_set_split_end:
+% }
+% When the separator is empty, everything is very simple, just map
+% \cs{@@_wrap_item:n} through the items of the last argument.
+% For non-trivial separators, the goal is to split a given token list
+% at the marker, strip spaces from each item, and remove one set of
+% outer braces if after removing leading and trailing
+% spaces the item is enclosed within braces. After
+% \cs{tl_replace_all:Nnn}, the token list \cs{l_@@_internal_a_tl}
+% is a repetition of the pattern
+% \cs{@@_set_split:Nw} \cs{prg_do_nothing:}
+% \meta{item with spaces} \cs{@@_set_split_end:}.
+% Then, \texttt{e}-expansion causes \cs{@@_set_split:Nw}
+% to trim spaces, and leaves its result as
+% \cs{@@_set_split:w} \meta{trimmed item}
+% \cs{@@_set_split_end:}. This is then converted
+% to the \pkg{l3seq} internal structure by another
+% \texttt{e}-expansion. In the first step, we insert
+% \cs{prg_do_nothing:} to avoid losing braces too early:
+% that would cause space trimming to act within those
+% lost braces. The second step is solely there to strip
+% braces which are outermost after space trimming.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_set_split:Nnn
+ { \@@_set_split:NNNnn \__kernel_tl_set:Nx \tl_trim_spaces:n }
+\cs_new_protected:Npn \seq_gset_split:Nnn
+ { \@@_set_split:NNNnn \__kernel_tl_gset:Nx \tl_trim_spaces:n }
+\cs_new_protected:Npn \seq_set_split_keep_spaces:Nnn
+ { \@@_set_split:NNNnn \__kernel_tl_set:Nx \exp_not:n }
+\cs_new_protected:Npn \seq_gset_split_keep_spaces:Nnn
+ { \@@_set_split:NNNnn \__kernel_tl_gset:Nx \exp_not:n }
+\cs_new_protected:Npn \@@_set_split:NNNnn #1#2#3#4#5
+ {
+ \tl_if_empty:nTF {#4}
+ {
+ \tl_set:Nn \l_@@_internal_a_tl
+ { \tl_map_function:nN {#5} \@@_wrap_item:n }
+ }
+ {
+ \tl_set:Nn \l_@@_internal_a_tl
+ {
+ \@@_set_split:Nw #2 \prg_do_nothing:
+ #5
+ \@@_set_split_end:
+ }
+ \tl_replace_all:Nnn \l_@@_internal_a_tl {#4}
+ {
+ \@@_set_split_end:
+ \@@_set_split:Nw #2 \prg_do_nothing:
+ }
+ \__kernel_tl_set:Nx \l_@@_internal_a_tl { \l_@@_internal_a_tl }
+ }
+ #1 #3 { \s_@@ \l_@@_internal_a_tl }
+ }
+\cs_new:Npn \@@_set_split:Nw #1#2 \@@_set_split_end:
+ {
+ \exp_not:N \@@_set_split:w
+ \exp_args:No #1 {#2}
+ \exp_not:N \@@_set_split_end:
+ }
+\cs_new:Npn \@@_set_split:w #1 \@@_set_split_end:
+ { \@@_wrap_item:n {#1} }
+\cs_generate_variant:Nn \seq_set_split:Nnn { NV , NnV , NVV , Nne , Nee }
+\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx , Nxx }
+\cs_generate_variant:Nn \seq_gset_split:Nnn { NV , NnV , NVV , Nne , Nee }
+\cs_generate_variant:Nn \seq_gset_split:Nnn { Nnx , Nxx }
+\cs_generate_variant:Nn \seq_set_split_keep_spaces:Nnn { NnV }
+\cs_generate_variant:Nn \seq_gset_split_keep_spaces:Nnn { NnV }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_set_filter:NNn, \seq_gset_filter:NNn}
+% \begin{macro}{\@@_set_filter:NNNn}
+% Similar to \cs{seq_map_inline:Nn}, without a
+% \cs{prg_break_point:} because the user's code
+% is performed within the evaluation of a boolean expression,
+% and skipping out of that would break horribly.
+% The \cs{@@_wrap_item:n} function inserts the relevant
+% \cs{@@_item:n} without expansion in the input stream,
+% hence in the \texttt{e}-expanding assignment.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_set_filter:NNn
+ { \@@_set_filter:NNNn \__kernel_tl_set:Nx }
+\cs_new_protected:Npn \seq_gset_filter:NNn
+ { \@@_set_filter:NNNn \__kernel_tl_gset:Nx }
+\cs_new_protected:Npn \@@_set_filter:NNNn #1#2#3#4
+ {
+ \@@_push_item_def:n { \bool_if:nT {#4} { \@@_wrap_item:n {##1} } }
+ #1 #2 { #3 }
+ \@@_pop_item_def:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_concat:NNN, \seq_concat:ccc}
+% \UnitTested
+% \begin{macro}{\seq_gconcat:NNN, \seq_gconcat:ccc}
+% \UnitTested
+% When concatenating sequences, one must remove the leading \cs{s_@@}
+% of the second sequence. The result starts with \cs{s_@@} (of the
+% first sequence), which stops \texttt{f}-expansion.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_concat:NNN #1#2#3
+ { \tl_set:Nf #1 { \exp_after:wN \use_i:nn \exp_after:wN #2 #3 } }
+\cs_new_protected:Npn \seq_gconcat:NNN #1#2#3
+ { \tl_gset:Nf #1 { \exp_after:wN \use_i:nn \exp_after:wN #2 #3 } }
+\cs_generate_variant:Nn \seq_concat:NNN { ccc }
+\cs_generate_variant:Nn \seq_gconcat:NNN { ccc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\seq_if_exist:N, \seq_if_exist:c}
+% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \seq_if_exist:N \cs_if_exist:N
+ { TF , T , F , p }
+\prg_new_eq_conditional:NNn \seq_if_exist:c \cs_if_exist:c
+ { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Appending data to either end}
+%
+% \begin{macro}{
+% \seq_put_left:Nn, \seq_put_left:NV, \seq_put_left:Nv, \seq_put_left:Ne,
+% \seq_put_left:No, \seq_put_left:Nx,
+% \seq_put_left:cn, \seq_put_left:cV, \seq_put_left:cv,\seq_put_left:ce,
+% \seq_put_left:co, \seq_put_left:cx
+% }
+% \UnitTested
+% \begin{macro}{
+% \seq_gput_left:Nn, \seq_gput_left:NV, \seq_gput_left:Nv, \seq_gput_left:Ne,
+% \seq_gput_left:No, \seq_gput_left:Nx,
+% \seq_gput_left:cn, \seq_gput_left:cV, \seq_gput_left:cv, \seq_gput_left:ce,
+% \seq_gput_left:co, \seq_gput_left:cx
+% }
+% \begin{macro}[EXP]{\@@_put_left_aux:w}
+% When adding to the left of a sequence, remove \cs{s_@@}. This is
+% done by \cs{@@_put_left_aux:w}, which also stops
+% \texttt{f}-expansion.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_put_left:Nn #1#2
+ {
+ \__kernel_tl_set:Nx #1
+ {
+ \exp_not:n { \s_@@ \@@_item:n {#2} }
+ \exp_not:f { \exp_after:wN \@@_put_left_aux:w #1 }
+ }
+ }
+\cs_new_protected:Npn \seq_gput_left:Nn #1#2
+ {
+ \__kernel_tl_gset:Nx #1
+ {
+ \exp_not:n { \s_@@ \@@_item:n {#2} }
+ \exp_not:f { \exp_after:wN \@@_put_left_aux:w #1 }
+ }
+ }
+\cs_new:Npn \@@_put_left_aux:w \s_@@ { \exp_stop_f: }
+\cs_generate_variant:Nn \seq_put_left:Nn { NV , Nv , Ne , No , Nx }
+\cs_generate_variant:Nn \seq_put_left:Nn { c , cV , cv , ce , co ,cx }
+\cs_generate_variant:Nn \seq_gput_left:Nn { NV , Nv , Ne , No , Nx }
+\cs_generate_variant:Nn \seq_gput_left:Nn { c , cV , cv , ce , co , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \seq_put_right:Nn, \seq_put_right:NV, \seq_put_right:Nv, \seq_put_right:Ne,
+% \seq_put_right:No, \seq_put_right:Nx,
+% \seq_put_right:cn, \seq_put_right:cV, \seq_put_right:cv, \seq_put_right:cx,
+% \seq_put_right:co, \seq_put_right:cx
+% }
+% \UnitTested
+% \begin{macro}
+% {
+% \seq_gput_right:Nn, \seq_gput_right:NV, \seq_gput_right:Nv, \seq_gput_right:Ne,
+% \seq_gput_right:No, \seq_gput_right:Nx,
+% \seq_gput_right:cn, \seq_gput_right:cV, \seq_gput_right:cv, \seq_gput_right:ce,
+% \seq_gput_right:co, \seq_gput_right:cx
+% }
+% Since there is no trailing marker, adding an item to the right of a
+% sequence simply means wrapping it in \cs{@@_item:n}.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_put_right:Nn #1#2
+ { \tl_put_right:Nn #1 { \@@_item:n {#2} } }
+\cs_new_protected:Npn \seq_gput_right:Nn #1#2
+ { \tl_gput_right:Nn #1 { \@@_item:n {#2} } }
+\cs_generate_variant:Nn \seq_put_right:Nn { NV , Nv , Ne , No , Nx }
+\cs_generate_variant:Nn \seq_put_right:Nn { c , cV , cv , ce , co , cx }
+\cs_generate_variant:Nn \seq_gput_right:Nn { NV , Nv , Ne , No , Nx }
+\cs_generate_variant:Nn \seq_gput_right:Nn { c , cV , cv , ce , co , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Modifying sequences}
+%
+% \begin{macro}{\@@_wrap_item:n}
+% This function converts its argument to a proper sequence item
+% in an \texttt{e}-expansion context.
+% \begin{macrocode}
+\cs_new:Npn \@@_wrap_item:n #1 { \exp_not:n { \@@_item:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_remove_seq}
+% An internal sequence for the removal routines.
+% \begin{macrocode}
+\seq_new:N \l_@@_remove_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\seq_remove_duplicates:N, \seq_remove_duplicates:c}
+% \UnitTested
+% \begin{macro}{\seq_gremove_duplicates:N, \seq_gremove_duplicates:c}
+% \UnitTested
+% \begin{macro}{\@@_remove_duplicates:NN}
+% Removing duplicates means making a new list then copying it.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_remove_duplicates:N
+ { \@@_remove_duplicates:NN \seq_set_eq:NN }
+\cs_new_protected:Npn \seq_gremove_duplicates:N
+ { \@@_remove_duplicates:NN \seq_gset_eq:NN }
+\cs_new_protected:Npn \@@_remove_duplicates:NN #1#2
+ {
+ \seq_clear:N \l_@@_remove_seq
+ \seq_map_inline:Nn #2
+ {
+ \seq_if_in:NnF \l_@@_remove_seq {##1}
+ { \seq_put_right:Nn \l_@@_remove_seq {##1} }
+ }
+ #1 #2 \l_@@_remove_seq
+ }
+\cs_generate_variant:Nn \seq_remove_duplicates:N { c }
+\cs_generate_variant:Nn \seq_gremove_duplicates:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \seq_remove_all:Nn, \seq_remove_all:NV, \seq_remove_all:Ne,
+% \seq_remove_all:Nx,
+% \seq_remove_all:cn, \seq_remove_all:cV, \seq_remove_all:ce,
+% \seq_remove_all:cx,
+% }
+% \UnitTested
+% \begin{macro}
+% {
+% \seq_gremove_all:Nn, \seq_gremove_all:NV, \seq_gremove_all:Ne,
+% \seq_gremove_all:Nx,
+% \seq_gremove_all:cn, \seq_gremove_all:cV, \seq_gremove_all:ce,
+% \seq_gremove_all:Nx
+% }
+% \UnitTested
+% \begin{macro}{\@@_remove_all_aux:NNn}
+% The idea of the code here is to avoid a relatively expensive addition of
+% items one at a time to an intermediate sequence.
+% The approach taken is therefore similar to
+% that in \cs{@@_pop_right:NNN}, using a \enquote{flexible}
+% \texttt{e}-type expansion to do most of the work. As \cs{tl_if_eq:nnT}
+% is not expandable, a two-part strategy is needed. First, the
+% \texttt{e}-type expansion uses \cs{str_if_eq:nnT} to find potential
+% matches. If one is found, the expansion is halted and the necessary
+% set up takes place to use the \cs{tl_if_eq:NNT} test. The \texttt{e}-type
+% is started again, including all of the items copied already. This
+% happens repeatedly until the entire sequence has been scanned. The code
+% is set up to avoid needing an intermediate scratch list: the lead-off
+% \texttt{e}-type expansion (|#1 #2 {#2}|) ensures that nothing is lost.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_remove_all:Nn
+ { \@@_remove_all_aux:NNn \__kernel_tl_set:Nx }
+\cs_new_protected:Npn \seq_gremove_all:Nn
+ { \@@_remove_all_aux:NNn \__kernel_tl_gset:Nx }
+\cs_new_protected:Npn \@@_remove_all_aux:NNn #1#2#3
+ {
+ \@@_push_item_def:n
+ {
+ \str_if_eq:nnT {##1} {#3}
+ {
+ \if_false: { \fi: }
+ \tl_set:Nn \l_@@_internal_b_tl {##1}
+ #1 #2
+ { \if_false: } \fi:
+ \exp_not:o {#2}
+ \tl_if_eq:NNT \l_@@_internal_a_tl \l_@@_internal_b_tl
+ { \use_none:nn }
+ }
+ \@@_wrap_item:n {##1}
+ }
+ \tl_set:Nn \l_@@_internal_a_tl {#3}
+ #1 #2 {#2}
+ \@@_pop_item_def:
+ }
+\cs_generate_variant:Nn \seq_remove_all:Nn { NV , Ne , c , cV , ce }
+\cs_generate_variant:Nn \seq_remove_all:Nn { Nx , cx }
+\cs_generate_variant:Nn \seq_gremove_all:Nn { NV , Ne , c , cV , ce }
+\cs_generate_variant:Nn \seq_gremove_all:Nn { Nx , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_int_eval:w}
+% Useful to more quickly go through items.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_int_eval:w \tex_numexpr:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[noTF]{\seq_set_item:Nnn, \seq_set_item:cnn, \seq_gset_item:Nnn, \seq_gset_item:cnn}
+% \begin{macro}{\@@_set_item:NnnNN, \@@_set_item:nnNNNN, \@@_set_item_false:nnNNNN, \@@_set_item:nNnnNNNN}
+% \begin{macro}[rEXP]{\@@_set_item:wn, \@@_set_item_end:w}
+% The conditionals are distinguished from the |Nnn| versions by the
+% last argument \cs{use_ii:nn} vs \cs{use_i:nn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_set_item:Nnn #1#2#3
+ { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_set:Nx \use_i:nn }
+\cs_new_protected:Npn \seq_gset_item:Nnn #1#2#3
+ { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_gset:Nx \use_i:nn }
+\cs_generate_variant:Nn \seq_set_item:Nnn { c }
+\cs_generate_variant:Nn \seq_gset_item:Nnn { c }
+\prg_new_protected_conditional:Npnn \seq_set_item:Nnn #1#2#3 { TF , T , F }
+ { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_set:Nx \use_ii:nn }
+\prg_new_protected_conditional:Npnn \seq_gset_item:Nnn #1#2#3 { TF , T , F }
+ { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_gset:Nx \use_ii:nn }
+\prg_generate_conditional_variant:Nnn \seq_set_item:Nnn { c } { TF , T , F }
+\prg_generate_conditional_variant:Nnn \seq_gset_item:Nnn { c } { TF , T , F }
+% \end{macrocode}
+% Save the item to be stored and evaluate the position and the sequence
+% length only once. Then depending on the sign of the position, check
+% that it is not bigger than the length (in absolute value) nor zero.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_item:NnnNN #1#2#3
+ {
+ \tl_set:Nn \l_@@_internal_a_tl { \@@_item:n {#3} }
+ \exp_args:Nff \@@_set_item:nnNNNN
+ { \int_eval:n {#2} } { \seq_count:N #1 } #1 \use_none:nn
+ }
+\cs_new_protected:Npn \@@_set_item:nnNNNN #1#2
+ {
+ \int_compare:nNnTF {#1} > 0
+ { \int_compare:nNnF {#1} > {#2} { \@@_set_item:nNnnNNNN { #1 - 1 } } }
+ {
+ \int_compare:nNnF {#1} < {-#2}
+ {
+ \int_compare:nNnF {#1} = 0
+ { \@@_set_item:nNnnNNNN { #2 + #1 } }
+ }
+ }
+ \@@_set_item_false:nnNNNN {#1} {#2}
+ }
+% \end{macrocode}
+% If the position is not ok, \cs{@@_set_item_false:nnNNNN} calls an
+% error or returns \texttt{false} (depending on the \cs{use_i:nn} vs
+% \cs{use_ii:nn} argument mentioned above).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_item_false:nnNNNN #1#2#3#4#5#6
+ {
+ #6
+ {
+ \msg_error:nneee { seq } { item-too-large }
+ { \token_to_str:N #3 } {#2} {#1}
+ }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+% If the position is ok, \cs{@@_set_item:nNnnNNNN} makes the assignment
+% and returns \texttt{true} (in the case of conditionnals). Here |#1|
+% is an integer expression (position minus one), it needs to be
+% evaluated. The sequence |#5| starts with \cs{s_@@} (even if empty),
+% which stops the integer expression and is absorbed by it. The
+% \cs{if_meaning:w} test is slightly faster than an integer test (but
+% only works when testing against zero, hence the offset we chose in
+% the position). When we are done skipping items, insert the saved
+% item \cs{l_@@_internal_a_tl}. For |put| functions the last argument
+% of \cs{@@_set_item_end:w} is \cs{use_none:nn} and it absorbs the
+% item |#2| that we are removing: this is only useful for the |pop|
+% functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_item:nNnnNNNN #1#2#3#4#5#6#7#8
+ {
+ #7 #5
+ {
+ \s_@@
+ \exp_after:wN \@@_set_item:wn
+ \int_value:w \@@_int_eval:w #1
+ #5 \s_@@_stop #6
+ }
+ #8 { } { \prg_return_true: }
+ }
+\cs_new:Npn \@@_set_item:wn #1 \@@_item:n #2
+ {
+ \if_meaning:w 0 #1 \@@_set_item_end:w \fi:
+ \exp_not:n { \@@_item:n {#2} }
+ \exp_after:wN \@@_set_item:wn
+ \int_value:w \@@_int_eval:w #1 - 1 \s_@@
+ }
+\cs_new:Npn \@@_set_item_end:w #1 \exp_not:n #2 #3 \s_@@ #4 \s_@@_stop #5
+ {
+ #1
+ \exp_not:o \l_@@_internal_a_tl
+ \exp_not:n {#4}
+ #5 #2
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\seq_reverse:N, \seq_reverse:c, \seq_greverse:N, \seq_greverse:c}
+% \begin{macro}{\@@_reverse:NN}
+% \begin{macro}[EXP]{\@@_reverse_item:nwn}
+% Previously, \cs{seq_reverse:N} was coded by collecting the items
+% in reverse order after an \cs{exp_stop_f:} marker.
+% \begin{verbatim}
+% \cs_new_protected:Npn \seq_reverse:N #1
+% {
+% \cs_set_eq:NN \@@_item:n \@@_reverse_item:nw
+% \tl_set:Nf #2 { #2 \exp_stop_f: }
+% }
+% \cs_new:Npn \@@_reverse_item:nw #1 #2 \exp_stop_f:
+% {
+% #2 \exp_stop_f:
+% \@@_item:n {#1}
+% }
+% \end{verbatim}
+% At first, this seems optimal, since we can forget about each item
+% as soon as it is placed after \cs{exp_stop_f:}. Unfortunately,
+% \TeX{}'s usual tail recursion does not take place in this case:
+% since the following \cs{@@_reverse_item:nw} only reads
+% tokens until \cs{exp_stop_f:}, and never reads the
+% |\@@_item:n {#1}| left by the previous call, \TeX{} cannot
+% remove that previous call from the stack, and in particular
+% must retain the various macro parameters in memory, until the
+% end of the replacement text is reached. The stack is thus
+% only flushed after all the \cs{@@_reverse_item:nw} are
+% expanded. Keeping track of the arguments of all those calls
+% uses up a memory quadratic in the length of the sequence.
+% \TeX{} can then not cope with more than a few thousand items.
+%
+% Instead, we collect the items in the argument
+% of \cs{exp_not:n}. The previous calls are cleanly removed
+% from the stack, and the memory consumption becomes linear.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_reverse:N
+ { \@@_reverse:NN \__kernel_tl_set:Nx }
+\cs_new_protected:Npn \seq_greverse:N
+ { \@@_reverse:NN \__kernel_tl_gset:Nx }
+\cs_new_protected:Npn \@@_reverse:NN #1 #2
+ {
+ \cs_set_eq:NN \@@_tmp:w \@@_item:n
+ \cs_set_eq:NN \@@_item:n \@@_reverse_item:nwn
+ #1 #2 { #2 \exp_not:n { } }
+ \cs_set_eq:NN \@@_item:n \@@_tmp:w
+ }
+\cs_new:Npn \@@_reverse_item:nwn #1 #2 \exp_not:n #3
+ {
+ #2
+ \exp_not:n { \@@_item:n {#1} #3 }
+ }
+\cs_generate_variant:Nn \seq_reverse:N { c }
+\cs_generate_variant:Nn \seq_greverse:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_sort:Nn, \seq_sort:cn, \seq_gsort:Nn, \seq_gsort:cn}
+% Implemented in \pkg{l3sort}.
+% \end{macro}
+%
+% \subsection{Sequence conditionals}
+%
+% \begin{macro}[pTF]{\seq_if_empty:N, \seq_if_empty:c}
+% \UnitTested
+% Similar to token lists, we compare with the empty sequence.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \seq_if_empty:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \c_empty_seq
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_generate_conditional_variant:Nnn \seq_if_empty:N
+ { c } { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\seq_shuffle:N, \seq_shuffle:c, \seq_gshuffle:N, \seq_gshuffle:c}
+% \begin{macro}{\@@_shuffle:NN}
+% \begin{macro}{\@@_shuffle_item:n}
+% \begin{variable}{\g_@@_internal_seq}
+% We apply the Fisher--Yates shuffle, storing items in \tn{toks}
+% registers. We use the primitive \cs{tex_uniformdeviate:D} for
+% speed reasons. Its non-uniformity is of order its argument divided
+% by $2^{28}$, not too bad for small lists. For sequences with more
+% than $13$ elements there are more possible permutations than
+% possible seeds ($13!>2^{28}$) so the question of uniformity is
+% somewhat moot. The integer variables are declared in \pkg{l3int}:
+% load-order issues.
+% \begin{macrocode}
+\seq_new:N \g_@@_internal_seq
+\cs_new_protected:Npn \seq_shuffle:N { \@@_shuffle:NN \seq_set_eq:NN }
+\cs_new_protected:Npn \seq_gshuffle:N { \@@_shuffle:NN \seq_gset_eq:NN }
+\cs_new_protected:Npn \@@_shuffle:NN #1#2
+ {
+ \int_compare:nNnTF { \seq_count:N #2 } > \c_max_register_int
+ {
+ \msg_error:nne { seq } { shuffle-too-large }
+ { \token_to_str:N #2 }
+ }
+ {
+ \group_begin:
+ \int_zero:N \l_@@_internal_a_int
+ \@@_push_item_def:
+ \cs_gset_eq:NN \@@_item:n \@@_shuffle_item:n
+ #2
+ \@@_pop_item_def:
+ \seq_gclear:N \g_@@_internal_seq
+ \int_step_inline:nn \l_@@_internal_a_int
+ {
+ \seq_gput_right:Ne \g_@@_internal_seq
+ { \tex_the:D \tex_toks:D ##1 }
+ }
+ \group_end:
+ #1 #2 \g_@@_internal_seq
+ \seq_gclear:N \g_@@_internal_seq
+ }
+ }
+\cs_new_protected:Npn \@@_shuffle_item:n
+ {
+ \int_incr:N \l_@@_internal_a_int
+ \int_set:Nn \l_@@_internal_b_int
+ { 1 + \tex_uniformdeviate:D \l_@@_internal_a_int }
+ \tex_toks:D \l_@@_internal_a_int
+ = \tex_toks:D \l_@@_internal_b_int
+ \tex_toks:D \l_@@_internal_b_int
+ }
+\cs_generate_variant:Nn \seq_shuffle:N { c }
+\cs_generate_variant:Nn \seq_gshuffle:N { c }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]
+% {
+% \seq_if_in:Nn, \seq_if_in:NV, \seq_if_in:Nv, \seq_if_in:Ne,
+% \seq_if_in:No, \seq_if_in:Nx,
+% \seq_if_in:cn, \seq_if_in:cV, \seq_if_in:cv,\seq_if_in:ce,
+% \seq_if_in:co, \seq_if_in:cx
+% }
+% \UnitTested
+% \begin{macro}{\@@_if_in:}
+% The approach here is to define \cs{@@_item:n} to compare its
+% argument with the test sequence. If the two items are equal, the
+% mapping is terminated and \cs{group_end:} \cs{prg_return_true:}
+% is inserted after skipping over the rest of the recursion. On the
+% other hand, if there is no match then the loop breaks, returning
+% \cs{prg_return_false:}.
+% Everything is inside a group so that \cs{@@_item:n} is preserved
+% in nested situations.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \seq_if_in:Nn #1#2
+ { T , F , TF }
+ {
+ \group_begin:
+ \tl_set:Nn \l_@@_internal_a_tl {#2}
+ \cs_set_protected:Npn \@@_item:n ##1
+ {
+ \tl_set:Nn \l_@@_internal_b_tl {##1}
+ \if_meaning:w \l_@@_internal_a_tl \l_@@_internal_b_tl
+ \exp_after:wN \@@_if_in:
+ \fi:
+ }
+ #1
+ \group_end:
+ \prg_return_false:
+ \prg_break_point:
+ }
+\cs_new:Npn \@@_if_in:
+ { \prg_break:n { \group_end: \prg_return_true: } }
+\prg_generate_conditional_variant:Nnn \seq_if_in:Nn
+ { NV , Nv , Ne , No , Nx , c , cV , cv , ce , co , cx } { T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Recovering data from sequences}
+%
+% \begin{macro}{\@@_pop:NNNN, \@@_pop_TF:NNNN}
+% The two \texttt{pop} functions share their emptiness tests. We also
+% use a common emptiness test for all branching \texttt{get} and
+% \texttt{pop} functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_pop:NNNN #1#2#3#4
+ {
+ \if_meaning:w #3 \c_empty_seq
+ \tl_set:Nn #4 { \q_no_value }
+ \else:
+ #1#2#3#4
+ \fi:
+ }
+\cs_new_protected:Npn \@@_pop_TF:NNNN #1#2#3#4
+ {
+ \if_meaning:w #3 \c_empty_seq
+ % \tl_set:Nn #4 { \q_no_value }
+ \prg_return_false:
+ \else:
+ #1#2#3#4
+ \prg_return_true:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\seq_get_left:NN, \seq_get_left:cN}
+% \UnitTested
+% \begin{macro}{\@@_get_left:wnw}
+% Getting an item from the left of a sequence is pretty easy: just
+% trim off the first item after \cs{@@_item:n} at the start. We
+% append a \cs{q_no_value} item to cover the case of an empty sequence
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_get_left:NN #1#2
+ {
+ \__kernel_tl_set:Nx #2
+ {
+ \exp_after:wN \@@_get_left:wnw
+ #1 \@@_item:n { \q_no_value } \s_@@_stop
+ }
+ }
+\cs_new:Npn \@@_get_left:wnw #1 \@@_item:n #2#3 \s_@@_stop
+ { \exp_not:n {#2} }
+\cs_generate_variant:Nn \seq_get_left:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_pop_left:NN, \seq_pop_left:cN}
+% \UnitTested
+% \begin{macro}{\seq_gpop_left:NN, \seq_gpop_left:cN}
+% \UnitTested
+% \begin{macro}{\@@_pop_left:NNN, \@@_pop_left:wnwNNN}
+% The approach to popping an item is pretty similar to that to get
+% an item, with the only difference being that the sequence itself has
+% to be redefined. This makes it more sensible to use an auxiliary
+% function for the local and global cases.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_pop_left:NN
+ { \@@_pop:NNNN \@@_pop_left:NNN \tl_set:Nn }
+\cs_new_protected:Npn \seq_gpop_left:NN
+ { \@@_pop:NNNN \@@_pop_left:NNN \tl_gset:Nn }
+\cs_new_protected:Npn \@@_pop_left:NNN #1#2#3
+ { \exp_after:wN \@@_pop_left:wnwNNN #2 \s_@@_stop #1#2#3 }
+\cs_new_protected:Npn \@@_pop_left:wnwNNN
+ #1 \@@_item:n #2#3 \s_@@_stop #4#5#6
+ {
+ #4 #5 { #1 #3 }
+ \tl_set:Nn #6 {#2}
+ }
+\cs_generate_variant:Nn \seq_pop_left:NN { c }
+\cs_generate_variant:Nn \seq_gpop_left:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_get_right:NN, \seq_get_right:cN}
+% \UnitTested
+% \begin{macro}[EXP]{\@@_get_right_loop:nw, \@@_get_right_end:NnN}
+% First remove \cs{s_@@} and prepend \cs{q_no_value}. The first
+% argument of \cs{@@_get_right_loop:nw} is the last item found, and
+% the second argument is empty until the end of the loop, where it is
+% code that applies \cs{exp_not:n} to the last item and ends the loop.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_get_right:NN #1#2
+ {
+ \__kernel_tl_set:Nx #2
+ {
+ \exp_after:wN \use_i_ii:nnn
+ \exp_after:wN \@@_get_right_loop:nw
+ \exp_after:wN \q_no_value
+ #1
+ \@@_get_right_end:NnN \@@_item:n
+ }
+ }
+\cs_new:Npn \@@_get_right_loop:nw #1#2 \@@_item:n
+ {
+ #2 \use_none:n {#1}
+ \@@_get_right_loop:nw
+ }
+\cs_new:Npn \@@_get_right_end:NnN #1#2#3 { \exp_not:n {#2} }
+\cs_generate_variant:Nn \seq_get_right:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_pop_right:NN, \seq_pop_right:cN}
+% \UnitTested
+% \begin{macro}{\seq_gpop_right:NN, \seq_gpop_right:cN}
+% \UnitTested
+% \begin{macro}{\@@_pop_right:NNN, \@@_pop_right_loop:nn}
+% The approach to popping from the right is a bit more involved, but does
+% use some of the same ideas as getting from the right. What is needed is a
+% \enquote{flexible length} way to set a token list variable. This is
+% supplied by the |{ \if_false: } \fi:| \ldots
+% |\if_false: { \fi: }| construct. Using an \texttt{e}-type
+% expansion and a \enquote{non-expanding} definition for \cs{@@_item:n},
+% the left-most $n - 1$ entries in a sequence of $n$ items are stored
+% back in the sequence. That needs a loop of unknown length, hence using the
+% strange \cs{if_false:} way of including braces. When the last item
+% of the sequence is reached, the closing brace for the assignment is
+% inserted, and |\tl_set:Nn #3| is inserted in front of the final
+% entry. This therefore does the pop assignment. One more iteration
+% is performed, with an empty argument and \cs{use_none:nn}, which
+% finally stops the loop.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_pop_right:NN
+ { \@@_pop:NNNN \@@_pop_right:NNN \__kernel_tl_set:Nx }
+\cs_new_protected:Npn \seq_gpop_right:NN
+ { \@@_pop:NNNN \@@_pop_right:NNN \__kernel_tl_gset:Nx }
+\cs_new_protected:Npn \@@_pop_right:NNN #1#2#3
+ {
+ \cs_set_eq:NN \@@_tmp:w \@@_item:n
+ \cs_set_eq:NN \@@_item:n \scan_stop:
+ #1 #2
+ { \if_false: } \fi: \s_@@
+ \exp_after:wN \use_i:nnn
+ \exp_after:wN \@@_pop_right_loop:nn
+ #2
+ {
+ \if_false: { \fi: }
+ \__kernel_tl_set:Nx #3
+ }
+ { } \use_none:nn
+ \cs_set_eq:NN \@@_item:n \@@_tmp:w
+ }
+\cs_new:Npn \@@_pop_right_loop:nn #1#2
+ {
+ #2 { \exp_not:n {#1} }
+ \@@_pop_right_loop:nn
+ }
+\cs_generate_variant:Nn \seq_pop_right:NN { c }
+\cs_generate_variant:Nn \seq_gpop_right:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]{\seq_get_left:NN, \seq_get_left:cN}
+% \begin{macro}[TF]{\seq_get_right:NN, \seq_get_right:cN}
+% Getting from the left or right with a check on the results. The
+% first argument to \cs{@@_pop_TF:NNNN} is left unused.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \seq_get_left:NN #1#2 { T , F , TF }
+ { \@@_pop_TF:NNNN \prg_do_nothing: \seq_get_left:NN #1#2 }
+\prg_new_protected_conditional:Npnn \seq_get_right:NN #1#2 { T , F , TF }
+ { \@@_pop_TF:NNNN \prg_do_nothing: \seq_get_right:NN #1#2 }
+\prg_generate_conditional_variant:Nnn \seq_get_left:NN
+ { c } { T , F , TF }
+\prg_generate_conditional_variant:Nnn \seq_get_right:NN
+ { c } { T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]{\seq_pop_left:NN, \seq_pop_left:cN}
+% \begin{macro}[TF]{\seq_gpop_left:NN, \seq_gpop_left:cN}
+% \begin{macro}[TF]{\seq_pop_right:NN, \seq_pop_right:cN}
+% \begin{macro}[TF]{\seq_gpop_right:NN, \seq_gpop_right:cN}
+% More or less the same for popping.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \seq_pop_left:NN #1#2
+ { T , F , TF }
+ { \@@_pop_TF:NNNN \@@_pop_left:NNN \tl_set:Nn #1 #2 }
+\prg_new_protected_conditional:Npnn \seq_gpop_left:NN #1#2
+ { T , F , TF }
+ { \@@_pop_TF:NNNN \@@_pop_left:NNN \tl_gset:Nn #1 #2 }
+\prg_new_protected_conditional:Npnn \seq_pop_right:NN #1#2
+ { T , F , TF }
+ { \@@_pop_TF:NNNN \@@_pop_right:NNN \__kernel_tl_set:Nx #1 #2 }
+\prg_new_protected_conditional:Npnn \seq_gpop_right:NN #1#2
+ { T , F , TF }
+ { \@@_pop_TF:NNNN \@@_pop_right:NNN \__kernel_tl_gset:Nx #1 #2 }
+\prg_generate_conditional_variant:Nnn \seq_pop_left:NN { c }
+ { T , F , TF }
+\prg_generate_conditional_variant:Nnn \seq_gpop_left:NN { c }
+ { T , F , TF }
+\prg_generate_conditional_variant:Nnn \seq_pop_right:NN { c }
+ { T , F , TF }
+\prg_generate_conditional_variant:Nnn \seq_gpop_right:NN { c }
+ { T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\seq_item:Nn, \seq_item:NV, \seq_item:Ne, \seq_item:cn, \seq_item:cV, \seq_item:ce}
+% \begin{macro}{\@@_item:wNn, \@@_item:nN, \@@_item:nwn}
+% The idea here is to find the offset of the item from the left, then use
+% a loop to grab the correct item. If the resulting offset is too large,
+% then the argument delimited by \cs{@@_item:n} is \cs{prg_break:} instead
+% of being empty, terminating the loop and returning nothing at all.
+% \begin{macrocode}
+\cs_new:Npn \seq_item:Nn #1
+ { \exp_after:wN \@@_item:wNn #1 \s_@@_stop #1 }
+\cs_new:Npn \@@_item:wNn \s_@@ #1 \s_@@_stop #2#3
+ {
+ \exp_args:Nf \@@_item:nwn
+ { \exp_args:Nf \@@_item:nN { \int_eval:n {#3} } #2 }
+ #1
+ \prg_break: \@@_item:n { }
+ \prg_break_point:
+ }
+\cs_new:Npn \@@_item:nN #1#2
+ {
+ \int_compare:nNnTF {#1} < 0
+ { \int_eval:n { \seq_count:N #2 + 1 + #1 } }
+ {#1}
+ }
+\cs_new:Npn \@@_item:nwn #1#2 \@@_item:n #3
+ {
+ #2
+ \int_compare:nNnTF {#1} = 1
+ { \prg_break:n { \exp_not:n {#3} } }
+ { \exp_args:Nf \@@_item:nwn { \int_eval:n { #1 - 1 } } }
+ }
+\cs_generate_variant:Nn \seq_item:Nn { NV , Ne , c , cV , ce }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_rand_item:N, \seq_rand_item:c}
+% Importantly, \cs{seq_item:Nn} only evaluates its argument once.
+% \begin{macrocode}
+\cs_new:Npn \seq_rand_item:N #1
+ {
+ \seq_if_empty:NF #1
+ { \seq_item:Nn #1 { \int_rand:nn { 1 } { \seq_count:N #1 } } }
+ }
+\cs_generate_variant:Nn \seq_rand_item:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Mapping over sequences}
+%
+% \begin{macro}{\seq_map_break:}
+% \UnitTested
+% \begin{macro}{\seq_map_break:n}
+% \UnitTested
+% To break a function, the special token \cs{prg_break_point:Nn} is
+% used to find the end of the code. Any ending code is then inserted
+% before the return value of \cs{seq_map_break:n} is inserted.
+% \begin{macrocode}
+\cs_new:Npn \seq_map_break:
+ { \prg_map_break:Nn \seq_map_break: { } }
+\cs_new:Npn \seq_map_break:n
+ { \prg_map_break:Nn \seq_map_break: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_map_function:NN, \seq_map_function:cN}
+% \UnitTested
+% \begin{macro}[rEXP]{\@@_map_function:Nw}
+% The idea here is to apply the code of |#2| to each item in the
+% sequence without altering the definition of \cs{@@_item:n}. The
+% even-numbered arguments of \cs{@@_map_function:Nw} delimited by
+% \cs{@@_item:n} are almost always empty, except
+% at the end of the loop where it is \cs{prg_break:}. This allows to
+% break the loop without needing to do a (relatively-expensive) quark
+% test.
+% \begin{macrocode}
+\cs_new:Npn \seq_map_function:NN #1#2
+ {
+ \exp_after:wN \use_i_ii:nnn
+ \exp_after:wN \@@_map_function:Nw
+ \exp_after:wN #2
+ #1
+ \prg_break:
+ \@@_item:n { } \@@_item:n { } \@@_item:n { } \@@_item:n { }
+ \prg_break_point:
+ \prg_break_point:Nn \seq_map_break: { }
+ }
+\cs_new:Npn \@@_map_function:Nw #1
+ #2 \@@_item:n #3
+ #4 \@@_item:n #5
+ #6 \@@_item:n #7
+ #8 \@@_item:n #9
+ {
+ #2 #1 {#3}
+ #4 #1 {#5}
+ #6 #1 {#7}
+ #8 #1 {#9}
+ \@@_map_function:Nw #1
+ }
+\cs_generate_variant:Nn \seq_map_function:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_push_item_def:n, \@@_push_item_def:e}
+% \begin{macro}{\@@_push_item_def:}
+% \begin{macro}{\@@_pop_item_def:}
+% The definition of \cs{@@_item:n} needs to be saved and restored at
+% various points within the mapping and manipulation code. That is handled
+% here: as always, this approach uses global assignments.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_push_item_def:n
+ {
+ \@@_push_item_def:
+ \cs_gset:Npn \@@_item:n ##1
+ }
+\cs_new_protected:Npn \@@_push_item_def:e
+ {
+ \@@_push_item_def:
+ \cs_gset:Npe \@@_item:n ##1
+ }
+\cs_new_protected:Npn \@@_push_item_def:
+ {
+ \int_gincr:N \g__kernel_prg_map_int
+ \cs_gset_eq:cN { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
+ \@@_item:n
+ }
+\cs_new_protected:Npn \@@_pop_item_def:
+ {
+ \cs_gset_eq:Nc \@@_item:n
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
+ \int_gdecr:N \g__kernel_prg_map_int
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_map_inline:Nn, \seq_map_inline:cn}
+% \UnitTested
+% The idea here is that \cs{@@_item:n} is already \enquote{applied} to
+% each item in a sequence, and so an in-line mapping is just a case of
+% redefining \cs{@@_item:n}.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_map_inline:Nn #1#2
+ {
+ \@@_push_item_def:n {#2}
+ #1
+ \prg_break_point:Nn \seq_map_break: { \@@_pop_item_def: }
+ }
+\cs_generate_variant:Nn \seq_map_inline:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\seq_map_tokens:Nn, \seq_map_tokens:cn}
+% \begin{macro}{\@@_map_tokens:nw}
+% This is based on the function mapping but using the same tricks as
+% described for \cs{prop_map_tokens:Nn}. The idea is to remove the leading
+% \cs{s_@@} and apply the tokens such that they are safe with the
+% break points, hence the \cs{use:n}.
+% \begin{macrocode}
+\cs_new:Npn \seq_map_tokens:Nn #1#2
+ {
+ \exp_last_unbraced:Nno
+ \use_i:nn { \@@_map_tokens:nw {#2} } #1
+ \prg_break:
+ \@@_item:n { } \@@_item:n { } \@@_item:n { } \@@_item:n { }
+ \prg_break_point:
+ \prg_break_point:Nn \seq_map_break: { }
+ }
+\cs_generate_variant:Nn \seq_map_tokens:Nn { c }
+\cs_new:Npn \@@_map_tokens:nw #1
+ #2 \@@_item:n #3
+ #4 \@@_item:n #5
+ #6 \@@_item:n #7
+ #8 \@@_item:n #9
+ {
+ #2 \use:n {#1} {#3}
+ #4 \use:n {#1} {#5}
+ #6 \use:n {#1} {#7}
+ #8 \use:n {#1} {#9}
+ \@@_map_tokens:nw {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \seq_map_variable:NNn, \seq_map_variable:Ncn,
+% \seq_map_variable:cNn, \seq_map_variable:ccn
+% }
+% \UnitTested
+% This is just a specialised version of the in-line mapping function,
+% using an \texttt{e}-type expansion for the code set up so that the
+% number of |#| tokens required is as expected.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_map_variable:NNn #1#2#3
+ {
+ \@@_push_item_def:e
+ {
+ \tl_set:Nn \exp_not:N #2 {##1}
+ \exp_not:n {#3}
+ }
+ #1
+ \prg_break_point:Nn \seq_map_break: { \@@_pop_item_def: }
+ }
+\cs_generate_variant:Nn \seq_map_variable:NNn { Nc }
+\cs_generate_variant:Nn \seq_map_variable:NNn { c , cc }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \seq_map_indexed_function:NN, \seq_map_indexed_inline:Nn,
+% \@@_map_indexed:nNN, \@@_map_indexed:Nw
+% }
+% Similar to \cs{seq_map_function:NN} but we keep track of the item
+% index as a |;|-delimited argument of \cs{@@_map_indexed:Nw}.
+% \begin{macrocode}
+\cs_new:Npn \seq_map_indexed_function:NN #1#2
+ {
+ \@@_map_indexed:NN #1#2
+ \prg_break_point:Nn \seq_map_break: { }
+ }
+\cs_new_protected:Npn \seq_map_indexed_inline:Nn #1#2
+ {
+ \int_gincr:N \g__kernel_prg_map_int
+ \cs_gset_protected:cpn
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w } ##1##2 {#2}
+ \exp_args:NNc \@@_map_indexed:NN #1
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
+ \prg_break_point:Nn \seq_map_break:
+ { \int_gdecr:N \g__kernel_prg_map_int }
+ }
+\cs_new:Npn \@@_map_indexed:NN #1#2
+ {
+ \exp_after:wN \@@_map_indexed:Nw
+ \exp_after:wN #2
+ \int_value:w 1
+ \exp_after:wN \use_i:nn
+ \exp_after:wN ;
+ #1
+ \prg_break: \@@_item:n { } \prg_break_point:
+ }
+\cs_new:Npn \@@_map_indexed:Nw #1#2 ; #3 \@@_item:n #4
+ {
+ #3
+ #1 {#2} {#4}
+ \exp_after:wN \@@_map_indexed:Nw
+ \exp_after:wN #1
+ \int_value:w \int_eval:w 1 + #2 ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \seq_map_pairwise_function:NNN, \seq_map_pairwise_function:NcN,
+% \seq_map_pairwise_function:cNN, \seq_map_pairwise_function:ccN
+% }
+% \begin{macro}
+% {
+% \@@_map_pairwise_function:wNN, \@@_map_pairwise_function:wNw,
+% \@@_map_pairwise_function:Nnnwnn
+% }
+% The idea is to first expand both sequences, adding the
+% usual |{ ? \prg_break: } { }| to the end of each one. This is
+% most conveniently done in two steps using an auxiliary function.
+% The mapping then throws away the first tokens of |#2| and |#5|,
+% which for items in both sequences are \cs{s_@@}
+% \cs{@@_item:n}. The function to be mapped are then be applied to
+% the two entries. When the code hits the end of one of the
+% sequences, the break material stops the entire loop and tidy up.
+% This avoids needing to find the count of the two sequences, or
+% worrying about which is longer.
+% \begin{macrocode}
+\cs_new:Npn \seq_map_pairwise_function:NNN #1#2#3
+ { \exp_after:wN \@@_map_pairwise_function:wNN #2 \s_@@_stop #1 #3 }
+\cs_new:Npn \@@_map_pairwise_function:wNN \s_@@ #1 \s_@@_stop #2#3
+ {
+ \exp_after:wN \@@_map_pairwise_function:wNw #2 \s_@@_stop #3
+ #1 { ? \prg_break: } { }
+ \prg_break_point:
+ }
+\cs_new:Npn \@@_map_pairwise_function:wNw \s_@@ #1 \s_@@_stop #2
+ {
+ \@@_map_pairwise_function:Nnnwnn #2
+ #1 { ? \prg_break: } { }
+ \s_@@_stop
+ }
+\cs_new:Npn \@@_map_pairwise_function:Nnnwnn #1#2#3#4 \s_@@_stop #5#6
+ {
+ \use_none:n #2
+ \use_none:n #5
+ #1 {#3} {#6}
+ \@@_map_pairwise_function:Nnnwnn #1 #4 \s_@@_stop
+ }
+\cs_generate_variant:Nn \seq_map_pairwise_function:NNN { Nc , c , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_set_map_e:NNn, \seq_gset_map_e:NNn}
+% \begin{macro}{\@@_set_map_e:NNNn}
+% Very similar to \cs{seq_set_filter:NNn}. We could actually
+% merge the two within a single function, but it would have weird
+% semantics.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_set_map_e:NNn
+ { \@@_set_map_e:NNNn \__kernel_tl_set:Nx }
+\cs_new_protected:Npn \seq_gset_map_e:NNn
+ { \@@_set_map_e:NNNn \__kernel_tl_gset:Nx }
+\cs_new_protected:Npn \@@_set_map_e:NNNn #1#2#3#4
+ {
+ \@@_push_item_def:n { \exp_not:N \@@_item:n {#4} }
+ #1 #2 { #3 }
+ \@@_pop_item_def:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_set_map:NNn, \seq_gset_map:NNn}
+% \begin{macro}{\@@_set_map:NNNn}
+% Similar to \cs{seq_set_map_e:NNn}, but prevents expansion of the
+% <inline function>.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_set_map:NNn
+ { \@@_set_map:NNNn \__kernel_tl_set:Nx }
+\cs_new_protected:Npn \seq_gset_map:NNn
+ { \@@_set_map:NNNn \__kernel_tl_gset:Nx }
+\cs_new_protected:Npn \@@_set_map:NNNn #1#2#3#4
+ {
+ \@@_push_item_def:n { \exp_not:n { \@@_item:n {#4} } }
+ #1 #2 { #3 }
+ \@@_pop_item_def:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_count:N, \seq_count:c}
+% \begin{macro}{\@@_count:w, \@@_count_end:w}
+% Since counting the items in a sequence is quite common, we optimize
+% it by grabbing $8$~items at a time and correspondingly adding $8$ to
+% an integer expression. At the end of the loop, |#9| is
+% \cs{@@_count_end:w} instead of being empty. It removes |8+| and
+% instead places the number of \cs{@@_item:n} that \cs{@@_count:w}
+% grabbed before reaching the end of the sequence.
+% \begin{macrocode}
+\cs_new:Npn \seq_count:N #1
+ {
+ \int_eval:n
+ {
+ \exp_after:wN \use_i:nn
+ \exp_after:wN \@@_count:w
+ #1
+ \@@_count_end:w \@@_item:n 7
+ \@@_count_end:w \@@_item:n 6
+ \@@_count_end:w \@@_item:n 5
+ \@@_count_end:w \@@_item:n 4
+ \@@_count_end:w \@@_item:n 3
+ \@@_count_end:w \@@_item:n 2
+ \@@_count_end:w \@@_item:n 1
+ \@@_count_end:w \@@_item:n 0
+ \prg_break_point:
+ }
+ }
+\cs_new:Npn \@@_count:w
+ #1 \@@_item:n #2 \@@_item:n #3 \@@_item:n #4 \@@_item:n
+ #5 \@@_item:n #6 \@@_item:n #7 \@@_item:n #8 #9 \@@_item:n
+ { #9 8 + \@@_count:w }
+\cs_new:Npn \@@_count_end:w 8 + \@@_count:w #1#2 \prg_break_point: {#1}
+\cs_generate_variant:Nn \seq_count:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using sequences}
+%
+% \begin{macro}[EXP]{\seq_use:Nnnn, \seq_use:cnnn}
+% \begin{macro}[EXP]
+% {\@@_use:NNnNnn, \@@_use_setup:w, \@@_use:nwwwwnwn, \@@_use:nwwn}
+% \begin{macro}[EXP]{\seq_use:Nn, \seq_use:cn}
+% See \cs{clist_use:Nnnn} for a general explanation. The main
+% difference is that we use \cs{@@_item:n} as a delimiter rather than
+% commas. We also need to add \cs{@@_item:n} at various places, and
+% \cs{s_@@}.
+% \begin{macrocode}
+\cs_new:Npn \seq_use:Nnnn #1#2#3#4
+ {
+ \seq_if_exist:NTF #1
+ {
+ \int_case:nnF { \seq_count:N #1 }
+ {
+ { 0 } { }
+ { 1 } { \exp_after:wN \@@_use:NNnNnn #1 ? { } { } }
+ { 2 } { \exp_after:wN \@@_use:NNnNnn #1 {#2} }
+ }
+ {
+ \exp_after:wN \@@_use_setup:w #1 \@@_item:n
+ \s_@@_mark { \@@_use:nwwwwnwn {#3} }
+ \s_@@_mark { \@@_use:nwwn {#4} }
+ \s_@@_stop { }
+ }
+ }
+ {
+ \msg_expandable_error:nnn
+ { kernel } { bad-variable } {#1}
+ }
+ }
+\cs_generate_variant:Nn \seq_use:Nnnn { c }
+\cs_new:Npn \@@_use:NNnNnn #1#2#3#4#5#6 { \exp_not:n { #3 #6 #5 } }
+\cs_new:Npn \@@_use_setup:w \s_@@ { \@@_use:nwwwwnwn { } }
+\cs_new:Npn \@@_use:nwwwwnwn
+ #1 \@@_item:n #2 \@@_item:n #3 \@@_item:n #4#5
+ \s_@@_mark #6#7 \s_@@_stop #8
+ {
+ #6 \@@_item:n {#3} \@@_item:n {#4} #5
+ \s_@@_mark {#6} #7 \s_@@_stop { #8 #1 #2 }
+ }
+\cs_new:Npn \@@_use:nwwn #1 \@@_item:n #2 #3 \s_@@_stop #4
+ { \exp_not:n { #4 #1 #2 } }
+\cs_new:Npn \seq_use:Nn #1#2
+ { \seq_use:Nnnn #1 {#2} {#2} {#2} }
+\cs_generate_variant:Nn \seq_use:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Sequence stacks}
+%
+% The same functions as for sequences, but with the correct naming.
+%
+% \begin{macro}{
+% \seq_push:Nn, \seq_push:NV, \seq_push:Nv, \seq_push:Ne,
+% \seq_push:No, \seq_push:Nx,
+% \seq_push:cn, \seq_push:cV, \seq_push:cv, \seq_push:ce,
+% \seq_push:co, \seq_push:cx
+% }
+% \UnitTested
+% \begin{macro}{
+% \seq_gpush:Nn, \seq_gpush:NV, \seq_gpush:Nv, \seq_gpush:Ne,
+% \seq_gpush:No, \seq_gpush:Nx,
+% \seq_gpush:cn, \seq_gpush:cV, \seq_gpush:cv, \seq_gpush:ce,
+% \seq_gpush:co, \seq_gpush:cx
+% }
+% \UnitTested
+% Pushing to a sequence is the same as adding on the left.
+% \begin{macrocode}
+\cs_new_eq:NN \seq_push:Nn \seq_put_left:Nn
+\cs_generate_variant:Nn \seq_push:Nn { NV , Nv , Ne , c , cV , cv , ce }
+\cs_generate_variant:Nn \seq_push:Nn { No , Nx , co , cx }
+\cs_new_eq:NN \seq_gpush:Nn \seq_gput_left:Nn
+\cs_generate_variant:Nn \seq_gpush:Nn { NV , Nv , Ne , c , cV , cv , ce }
+\cs_generate_variant:Nn \seq_gpush:Nn { No , Nx , co , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_get:NN, \seq_get:cN}
+% \UnitTested
+% \begin{macro}{\seq_pop:NN, \seq_pop:cN}
+% \UnitTested
+% \begin{macro}{\seq_gpop:NN, \seq_gpop:cN}
+% \UnitTested
+% In most cases, getting items from the stack does not need to specify
+% that this is from the left. So alias are provided.
+% \begin{macrocode}
+\cs_new_eq:NN \seq_get:NN \seq_get_left:NN
+\cs_new_eq:NN \seq_get:cN \seq_get_left:cN
+\cs_new_eq:NN \seq_pop:NN \seq_pop_left:NN
+\cs_new_eq:NN \seq_pop:cN \seq_pop_left:cN
+\cs_new_eq:NN \seq_gpop:NN \seq_gpop_left:NN
+\cs_new_eq:NN \seq_gpop:cN \seq_gpop_left:cN
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]{\seq_get:NN, \seq_get:cN}
+% \begin{macro}[TF]{\seq_pop:NN, \seq_pop:cN}
+% \begin{macro}[TF]{\seq_gpop:NN, \seq_gpop:cN}
+% More copies.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \seq_get:NN \seq_get_left:NN { T , F , TF }
+\prg_new_eq_conditional:NNn \seq_get:cN \seq_get_left:cN { T , F , TF }
+\prg_new_eq_conditional:NNn \seq_pop:NN \seq_pop_left:NN { T , F , TF }
+\prg_new_eq_conditional:NNn \seq_pop:cN \seq_pop_left:cN { T , F , TF }
+\prg_new_eq_conditional:NNn \seq_gpop:NN \seq_gpop_left:NN { T , F , TF }
+\prg_new_eq_conditional:NNn \seq_gpop:cN \seq_gpop_left:cN { T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Viewing sequences}
+%
+% \begin{macro}{\seq_show:N, \seq_show:c, \seq_log:N, \seq_log:c, \@@_show:NN}
+% \begin{macro}[rEXP]{\@@_show_validate:nn}
+% \UnitTested
+% Apply the general \cs{__kernel_chk_tl_type:NnnT}.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_show:N { \@@_show:NN \msg_show:nneeee }
+\cs_generate_variant:Nn \seq_show:N { c }
+\cs_new_protected:Npn \seq_log:N { \@@_show:NN \msg_log:nneeee }
+\cs_generate_variant:Nn \seq_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_chk_tl_type:NnnT #2 { seq }
+ {
+ \s_@@
+ \exp_after:wN \use_i:nn \exp_after:wN \@@_show_validate:nn #2
+ \q_recursion_tail \q_recursion_tail \q_recursion_stop
+ }
+ {
+ #1 { seq } { show }
+ { \token_to_str:N #2 }
+ { \seq_map_function:NN #2 \msg_show_item:n }
+ { } { }
+ }
+ }
+\cs_new:Npn \@@_show_validate:nn #1#2
+ {
+ \quark_if_recursion_tail_stop:n {#2}
+ \@@_wrap_item:n {#2}
+ \@@_show_validate:nn
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Scratch sequences}
+%
+% \begin{variable}{\l_tmpa_seq, \l_tmpb_seq, \g_tmpa_seq, \g_tmpb_seq}
+% Temporary comma list variables.
+% \begin{macrocode}
+\seq_new:N \l_tmpa_seq
+\seq_new:N \l_tmpb_seq
+\seq_new:N \g_tmpa_seq
+\seq_new:N \g_tmpb_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3skip.dtx b/macros/latex-dev/required/l3kernel/l3skip.dtx
new file mode 100644
index 0000000000..a3d9256223
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3skip.dtx
@@ -0,0 +1,2600 @@
+% \iffalse meta-comment
+%
+%% File: l3skip.dtx
+%
+% Copyright (C) 2004-2011 Frank Mittelbach, The LaTeX Project
+% (C) 2012-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3skip} module\\ Dimensions and skips^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \LaTeX3 provides two general length variables: \texttt{dim} and
+% \texttt{skip}. Lengths stored as \texttt{dim} variables have a fixed
+% length, whereas \texttt{skip} lengths have a rubber (stretch/shrink)
+% component. In addition, the \texttt{muskip} type is available for
+% use in math mode: this is a special form of \texttt{skip} where the
+% lengths involved are determined by the current math font (in
+% \texttt{mu)}. There are common features in the creation and setting of
+% length variables, but for clarity the functions are grouped by variable
+% type.
+%
+% Many functions take
+% \emph{dimension expressions} (\enquote{\meta{dim expr}}) or
+% \emph{skip expressions} (\enquote{\meta{skip expr}}) as arguments.
+%
+%
+% \section{Creating and initialising \texttt{dim} variables}
+%
+% \begin{function}{\dim_new:N, \dim_new:c}
+% \begin{syntax}
+% \cs{dim_new:N} \meta{dimension}
+% \end{syntax}
+% Creates a new \meta{dimension} or raises an error if the name is
+% already taken. The declaration is global. The \meta{dimension}
+% is initially equal to $0$\,pt.
+% \end{function}
+%
+% \begin{function}[added = 2012-03-05]{\dim_const:Nn, \dim_const:cn}
+% \begin{syntax}
+% \cs{dim_const:Nn} \meta{dimension} \Arg{dim expr}
+% \end{syntax}
+% Creates a new constant \meta{dimension} or raises an error if the
+% name is already taken. The value of the \meta{dimension} is set
+% globally to the \meta{dim expr}.
+% \end{function}
+%
+% \begin{function}{\dim_zero:N, \dim_zero:c, \dim_gzero:N, \dim_gzero:c}
+% \begin{syntax}
+% \cs{dim_zero:N} \meta{dimension}
+% \end{syntax}
+% Sets \meta{dimension} to $0$\,pt.
+% \end{function}
+%
+% \begin{function}[added = 2012-01-07]
+% {\dim_zero_new:N, \dim_zero_new:c, \dim_gzero_new:N, \dim_gzero_new:c}
+% \begin{syntax}
+% \cs{dim_zero_new:N} \meta{dimension}
+% \end{syntax}
+% Ensures that the \meta{dimension} exists globally by applying
+% \cs{dim_new:N} if necessary, then applies
+% \cs[index=dim_zero:N]{dim_(g)zero:N} to leave
+% the \meta{dimension} set to zero.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added=2012-03-03]{\dim_if_exist:N, \dim_if_exist:c}
+% \begin{syntax}
+% \cs{dim_if_exist_p:N} \meta{dimension}
+% \cs{dim_if_exist:NTF} \meta{dimension} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{dimension} is currently defined. This does
+% not check that the \meta{dimension} really is a dimension variable.
+% \end{function}
+%
+% \section{Setting \texttt{dim} variables}
+%
+% \begin{function}[updated = 2011-10-22]
+% {\dim_add:Nn, \dim_add:cn, \dim_gadd:Nn, \dim_gadd:cn}
+% \begin{syntax}
+% \cs{dim_add:Nn} \meta{dimension} \Arg{dim expr}
+% \end{syntax}
+% Adds the result of the \meta{dim expr} to the current
+% content of the \meta{dimension}.
+% \end{function}
+%
+% \begin{function}[updated = 2011-10-22]
+% {\dim_set:Nn, \dim_set:cn, \dim_gset:Nn, \dim_gset:cn}
+% \begin{syntax}
+% \cs{dim_set:Nn} \meta{dimension} \Arg{dim expr}
+% \end{syntax}
+% Sets \meta{dimension} to the value of \meta{dim expr}, which
+% must evaluate to a length with units.
+% \end{function}
+%
+% \begin{function}
+% {
+% \dim_set_eq:NN, \dim_set_eq:cN, \dim_set_eq:Nc, \dim_set_eq:cc,
+% \dim_gset_eq:NN, \dim_gset_eq:cN, \dim_gset_eq:Nc, \dim_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{dim_set_eq:NN} \meta{dimension_1} \meta{dimension_2}
+% \end{syntax}
+% Sets the content of \meta{dimension_1} equal to that of
+% \meta{dimension_2}.
+% \end{function}
+%
+% \begin{function}[updated = 2011-10-22]
+% {\dim_sub:Nn, \dim_sub:cn, \dim_gsub:Nn, \dim_gsub:cn}
+% \begin{syntax}
+% \cs{dim_sub:Nn} \meta{dimension} \Arg{dim expr}
+% \end{syntax}
+% Subtracts the result of the \meta{dim expr} from the
+% current content of the \meta{dimension}.
+% \end{function}
+%
+% \section{Utilities for dimension calculations}
+%
+% \begin{function}[updated = 2012-09-26, EXP]{\dim_abs:n}
+% \begin{syntax}
+% \cs{dim_abs:n} \Arg{dim expr}
+% \end{syntax}
+% Converts the \meta{dim expr} to its absolute value, leaving the result
+% in the input stream as a \meta{dimension denotation}.
+% \end{function}
+%
+% \begin{function}[added = 2012-09-09, updated = 2012-09-26, EXP]
+% {\dim_max:nn, \dim_min:nn}
+% \begin{syntax}
+% \cs{dim_max:nn} \Arg{dim expr_1} \Arg{dim expr_2}
+% \cs{dim_min:nn} \Arg{dim expr_1} \Arg{dim expr_2}
+% \end{syntax}
+% Evaluates the two \meta{dim exprs} and leaves either the
+% maximum or minimum value in the input stream as appropriate, as a
+% \meta{dimension denotation}.
+% \end{function}
+%
+% \begin{function}[updated = 2011-10-22, rEXP]{\dim_ratio:nn}
+% \begin{syntax}
+% \cs{dim_ratio:nn} \Arg{dim expr_1} \Arg{dim expr_2}
+% \end{syntax}
+% Parses the two \meta{dim exprs} and converts the ratio of
+% the two to a form suitable for use inside a \meta{dim expr}.
+% This ratio is then left in the input stream, allowing syntax such as
+% \begin{verbatim}
+% \dim_set:Nn \l_my_dim
+% { 10 pt * \dim_ratio:nn { 5 pt } { 10 pt } }
+% \end{verbatim}
+% The output of \cs{dim_ratio:nn} on full expansion is a ratio expression
+% between two integers, with all distances converted to scaled points.
+% Thus
+% \begin{verbatim}
+% \tl_set:Ne \l_my_tl { \dim_ratio:nn { 5 pt } { 10 pt } }
+% \tl_show:N \l_my_tl
+% \end{verbatim}
+% displays |327680/655360| on the terminal.
+% \end{function}
+%
+% \section{Dimension expression conditionals}
+%
+% \begin{function}[EXP,pTF]{\dim_compare:nNn}
+% \begin{syntax}
+% \cs{dim_compare_p:nNn} \Arg{dim expr_1} \meta{relation} \Arg{dim expr_2} \\
+% \cs{dim_compare:nNnTF}
+% ~~\Arg{dim expr_1} \meta{relation} \Arg{dim expr_2}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function first evaluates each of the \meta{dim exprs}
+% as described for \cs{dim_eval:n}. The two results are then
+% compared using the \meta{relation}:
+% \begin{center}
+% \begin{tabular}{ll}
+% Equal & |=| \\
+% Greater than & |>| \\
+% Less than & |<| \\
+% \end{tabular}
+% \end{center}
+% This function is less flexible than \cs{dim_compare:nTF} but around
+% $5$~times faster.
+% \end{function}
+%
+% \begin{function}[updated = 2013-01-13, EXP, pTF]{\dim_compare:n}
+% \begin{syntax}
+% \cs{dim_compare_p:n} \\
+% ~~\{ \\
+% ~~~~\meta{dim expr_1} \meta{relation_1} \\
+% ~~~~\ldots{} \\
+% ~~~~\meta{dim expr_N} \meta{relation_N} \\
+% ~~~~\meta{dim expr_{N+1}} \\
+% ~~\} \\
+% \cs{dim_compare:nTF}
+% ~~\{ \\
+% ~~~~\meta{dim expr_1} \meta{relation_1} \\
+% ~~~~\ldots{} \\
+% ~~~~\meta{dim expr_N} \meta{relation_N} \\
+% ~~~~\meta{dim expr_{N+1}} \\
+% ~~\} \\
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function evaluates the \meta{dim exprs} as
+% described for \cs{dim_eval:n} and compares consecutive result using
+% the corresponding \meta{relation}, namely it compares
+% \meta{dim expr_1} and \meta{dim expr_2} using the \meta{relation_1},
+% then \meta{dim expr_2} and \meta{dim expr_3} using the
+% \meta{relation_2}, until finally comparing \meta{dim expr_N} and
+% \meta{dim expr_{N+1}} using the \meta{relation_N}. The test yields
+% \texttt{true} if all comparisons are \texttt{true}. Each
+% \meta{dim expr} is evaluated only once, and the
+% evaluation is lazy, in the sense that if one comparison is
+% \texttt{false}, then no other \meta{dim expr} is
+% evaluated and no other comparison is performed. The
+% \meta{relations} can be any of the following:
+% \begin{center}
+% \begin{tabular}{ll}
+% Equal & |=| or |==| \\
+% Greater than or equal to & |>=| \\
+% Greater than & |>| \\
+% Less than or equal to & |<=| \\
+% Less than & |<| \\
+% Not equal & |!=| \\
+% \end{tabular}
+% \end{center}
+% This function is more flexible than \cs{dim_compare:nNnTF} but
+% around $5$~times slower.
+% \end{function}
+%
+% \begin{function}[added = 2013-07-24, EXP, noTF]{\dim_case:nn}
+% \begin{syntax}
+% \cs{dim_case:nnTF} \Arg{test dim expr} \\
+% ~~|{| \\
+% ~~~~\Arg{dim expr case_1} \Arg{code case_1} \\
+% ~~~~\Arg{dim expr case_2} \Arg{code case_2} \\
+% ~~~~\ldots \\
+% ~~~~\Arg{dim expr case_n} \Arg{code case_n} \\
+% ~~|}| \\
+% ~~\Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% This function evaluates the \meta{test dim expr} and
+% compares this in turn to each of the
+% \meta{dim expr cases}. If the two are equal then the
+% associated \meta{code} is left in the input stream
+% and other cases are discarded. If any of the
+% cases are matched, the \meta{true code} is also inserted into the
+% input stream (after the code for the appropriate case), while if none
+% match then the \meta{false code} is inserted. The function
+% \cs{dim_case:nn}, which does nothing if there is no match, is also
+% available. For example
+% \begin{verbatim}
+% \dim_set:Nn \l_tmpa_dim { 5 pt }
+% \dim_case:nnF
+% { 2 \l_tmpa_dim }
+% {
+% { 5 pt } { Small }
+% { 4 pt + 6 pt } { Medium }
+% { - 10 pt } { Negative }
+% }
+% { No idea! }
+% \end{verbatim}
+% leaves \enquote{\texttt{Medium}} in the input stream.
+% \end{function}
+%
+% \section{Dimension expression loops}
+%
+% \begin{function}[rEXP]{\dim_do_until:nNnn}
+% \begin{syntax}
+% \cs{dim_do_until:nNnn} \Arg{dim expr_1} \meta{relation} \Arg{dim expr_2} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the relationship between the two
+% \meta{dim exprs} as described for \cs{dim_compare:nNnTF}.
+% If the test is \texttt{false} then the \meta{code} is inserted
+% into the input stream again and a loop occurs until the
+% \meta{relation} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP]{\dim_do_while:nNnn}
+% \begin{syntax}
+% \cs{dim_do_while:nNnn} \Arg{dim expr_1} \meta{relation} \Arg{dim expr_2} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the relationship between the two
+% \meta{dim exprs} as described for \cs{dim_compare:nNnTF}.
+% If the test is \texttt{true} then the \meta{code} is inserted
+% into the input stream again and a loop occurs until the
+% \meta{relation} is \texttt{false}.
+% \end{function}
+%
+% \begin{function}[rEXP]{\dim_until_do:nNnn}
+% \begin{syntax}
+% \cs{dim_until_do:nNnn} \Arg{dim expr_1} \meta{relation} \Arg{dim expr_2} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{dim exprs}
+% as described for \cs{dim_compare:nNnTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{false}. After the \meta{code} has been processed by \TeX{} the
+% test is repeated, and a loop occurs until the test is
+% \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP]{\dim_while_do:nNnn}
+% \begin{syntax}
+% \cs{dim_while_do:nNnn} \Arg{dim expr_1} \meta{relation} \Arg{dim expr_2} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{dim exprs}
+% as described for \cs{dim_compare:nNnTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{true}. After the \meta{code} has been processed by \TeX{} the
+% test is repeated, and a loop occurs until the test is
+% \texttt{false}.
+% \end{function}
+%
+% \begin{function}[updated = 2013-01-13, rEXP]{\dim_do_until:nn}
+% \begin{syntax}
+% \cs{dim_do_until:nn} \Arg{dimension relation} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the \meta{dimension relation}
+% as described for \cs{dim_compare:nTF}.
+% If the test is \texttt{false} then the \meta{code} is inserted
+% into the input stream again and a loop occurs until the
+% \meta{relation} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[updated = 2013-01-13, rEXP]{\dim_do_while:nn}
+% \begin{syntax}
+% \cs{dim_do_while:nn} \Arg{dimension relation} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the \meta{dimension relation}
+% as described for \cs{dim_compare:nTF}.
+% If the test is \texttt{true} then the \meta{code} is inserted
+% into the input stream again and a loop occurs until the
+% \meta{relation} is \texttt{false}.
+% \end{function}
+%
+% \begin{function}[updated = 2013-01-13, rEXP]{\dim_until_do:nn}
+% \begin{syntax}
+% \cs{dim_until_do:nn} \Arg{dimension relation} \Arg{code}
+% \end{syntax}
+% Evaluates the \meta{dimension relation}
+% as described for \cs{dim_compare:nTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{false}. After the \meta{code} has been processed by \TeX{} the
+% test is repeated, and a loop occurs until the test is
+% \texttt{true}.
+% \end{function}
+%
+% \begin{function}[updated = 2013-01-13, rEXP]{\dim_while_do:nn}
+% \begin{syntax}
+% \cs{dim_while_do:nn} \Arg{dimension relation} \Arg{code}
+% \end{syntax}
+% Evaluates the \meta{dimension relation}
+% as described for \cs{dim_compare:nTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{true}. After the \meta{code} has been processed by \TeX{} the
+% test is repeated, and a loop occurs until the test is
+% \texttt{false}.
+% \end{function}
+%
+% \section{Dimension step functions}
+%
+% \begin{function}[added = 2018-02-18, rEXP]
+% {\dim_step_function:nnnN}
+% \begin{syntax}
+% \cs{dim_step_function:nnnN} \Arg{initial value} \Arg{step} \Arg{final value} \meta{function}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, all of which should be dimension expressions.
+% The \meta{function} is then placed in front of each \meta{value}
+% from the \meta{initial value} to the \meta{final value} in turn
+% (using \meta{step} between each \meta{value}). The \meta{step} must
+% be non-zero. If the \meta{step} is positive, the loop stops when
+% the \meta{value} becomes larger than the \meta{final value}. If the
+% \meta{step} is negative, the loop stops when the \meta{value}
+% becomes smaller than the \meta{final value}. The \meta{function}
+% should absorb one argument.
+% \end{function}
+%
+% \begin{function}[added = 2018-02-18]
+% {\dim_step_inline:nnnn}
+% \begin{syntax}
+% \cs{dim_step_inline:nnnn} \Arg{initial value} \Arg{step} \Arg{final value} \Arg{code}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, all of which should be dimension expressions.
+% Then for each \meta{value} from the \meta{initial value} to the
+% \meta{final value} in turn (using \meta{step} between each
+% \meta{value}), the \meta{code} is inserted into the input stream
+% with |#1| replaced by the current \meta{value}. Thus the
+% \meta{code} should define a function of one argument~(|#1|).
+% \end{function}
+%
+% \begin{function}[added = 2018-02-18]
+% {\dim_step_variable:nnnNn}
+% \begin{syntax}
+% \cs{dim_step_variable:nnnNn} \\
+% ~~\Arg{initial value} \Arg{step} \Arg{final value} \meta{tl~var} \Arg{code}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, all of which should be dimension expressions.
+% Then for each \meta{value} from the \meta{initial value} to the
+% \meta{final value} in turn (using \meta{step} between each
+% \meta{value}), the \meta{code} is inserted into the input stream,
+% with the \meta{tl~var} defined as the current \meta{value}. Thus
+% the \meta{code} should make use of the \meta{tl~var}.
+% \end{function}
+%
+% \section{Using \texttt{dim} expressions and variables}
+%
+% \begin{function}[updated = 2011-10-22, EXP]{\dim_eval:n}
+% \begin{syntax}
+% \cs{dim_eval:n} \Arg{dim expr}
+% \end{syntax}
+% Evaluates the \meta{dim expr}, expanding any
+% dimensions and token list variables within the \meta{expression}
+% to their content (without requiring \cs{dim_use:N}/\cs{tl_use:N})
+% and applying the standard mathematical rules. The result of the
+% calculation is left in the input stream as a
+% \meta{dimension denotation} after two expansions. This is
+% expressed in points (\texttt{pt}), and requires suitable
+% termination if used in a \TeX{}-style assignment as it is \emph{not}
+% an \meta{internal dimension}.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2018-11-03]{\dim_sign:n}
+% \begin{syntax}
+% \cs{dim_sign:n} \Arg{dim expr}
+% \end{syntax}
+% Evaluates the \meta{dim expr} then leaves $1$ or $0$ or $-1$ in the
+% input stream according to the sign of the result.
+% \end{function}
+%
+% \begin{function}[EXP]{\dim_use:N, \dim_use:c}
+% \begin{syntax}
+% \cs{dim_use:N} \meta{dimension}
+% \end{syntax}
+% Recovers the content of a \meta{dimension} and places it directly
+% in the input stream. An error is raised if the variable does
+% not exist or if it is invalid. Can be omitted in places where a
+% \meta{dimension} is required (such as in the argument of
+% \cs{dim_eval:n}).
+% \begin{texnote}
+% \cs{dim_use:N} is the \TeX{} primitive \tn{the}: this is one of
+% several \LaTeX3 names for this primitive.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2014-07-15, EXP]{\dim_to_decimal:n}
+% \begin{syntax}
+% \cs{dim_to_decimal:n} \Arg{dim expr}
+% \end{syntax}
+% Evaluates the \meta{dim expr}, and leaves the result,
+% expressed in points (\texttt{pt}) in the input stream, with \emph{no
+% units}. The result is rounded by \TeX{} to at most five decimal
+% places. If the decimal part of the result is zero, it is omitted,
+% together with the decimal marker.
+%
+% For example
+% \begin{verbatim}
+% \dim_to_decimal:n { 1bp }
+% \end{verbatim}
+% leaves |1.00374| in the input stream, \emph{i.e.}~the magnitude of
+% one \enquote{big point} when converted to (\TeX{}) points.
+% \end{function}
+%
+% \begin{function}[added = 2014-07-15, updated = 2023-05-20, EXP]
+% {\dim_to_decimal_in_bp:n}
+% \begin{syntax}
+% \cs{dim_to_decimal_in_bp:n} \Arg{dim expr}
+% \end{syntax}
+% Evaluates the \meta{dim expr}, and leaves the result,
+% expressed in big points (\texttt{bp}) in the input stream, with \emph{no
+% units}. The result is rounded by \TeX{} to at most five decimal
+% places. If the decimal part of the result is zero, it is omitted,
+% together with the decimal marker.
+%
+% For example
+% \begin{verbatim}
+% \dim_to_decimal_in_bp:n { 1pt }
+% \end{verbatim}
+% leaves |0.99628| in the input stream, \emph{i.e.}~the magnitude of
+% one (\TeX{}) point when converted to big points.
+% \begin{texnote}
+% The implementation of this function is re-entrant: the result of
+% \begin{verbatim}
+% \dim_compare:nNnTF
+% { <x>bp } =
+% { \dim_to_decimal_in_bp:n { <x>bp } bp }
+% \end{verbatim}
+% will be logically \texttt{true}. The decimal representations may
+% differ provided they produce the same \TeX{} dimension.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2023-05-20, EXP]
+% {
+% \dim_to_decimal_in_cc:n ,
+% \dim_to_decimal_in_cm:n ,
+% \dim_to_decimal_in_dd:n ,
+% \dim_to_decimal_in_in:n ,
+% \dim_to_decimal_in_mm:n ,
+% \dim_to_decimal_in_pc:n
+% }
+% \begin{syntax}
+% \cs{dim_to_decimal_in_cm:n} \Arg{dim expr}
+% \end{syntax}
+% Evaluates the \meta{dim expr}, and leaves the result,
+% expressed with the appropriate scaling in the input stream, with
+% \emph{no units}. If the decimal part of the result is zero, it is omitted,
+% together with the decimal marker. The precisions of the result is limited
+% to a maximum of five decimal places with trailing zeros omitted.
+%
+% The maximum \TeX{} allowable dimension value (available as
+% \tn{maxdimen} in plain \TeX{} and \LaTeX{} and \cs{c_max_dim} in
+% \pkg{expl3}) can only be expressed exactly in the units
+% \texttt{pt}, \texttt{bp} and \texttt{sp}. The maximum allowable
+% input values to five decimal places are\\
+% \begin{center}
+% \begin{tabular}{@{}>{$}r<{$}@{\,}l@{}}
+% 1276.00215 & cc \\
+% 575.83174 & cm \\
+% 15312.02584 & dd \\
+% 226.70540 & in \\
+% 5758.31742 & mm \\
+% 1365.33333 & pc \\
+% \end{tabular}
+% \end{center}
+% (Note that these are not all equal, but rather any larger value will overflow
+% due to the way \TeX{} converts to \texttt{sp}.)
+% Values given to five decimal places larger that these will result in \TeX{}
+% errors; the behavior if additional decimal places are given depends on the
+% \TeX{} internals and thus larger values are \emph{not} supported by
+% \pkg{expl3}.
+% \begin{texnote}
+% The implementation of these functions is re-entrant: the result of
+% \begin{verbatim}
+% \dim_compare:nNnTF
+% { <x><unit> } =
+% { \dim_to_decimal_in_<unit>:n { <x><unit> } <unit> }
+% \end{verbatim}
+% will be logically \texttt{true}. The decimal representations may
+% differ provided they produce the same \TeX{} dimension.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2015-05-18, EXP]{\dim_to_decimal_in_sp:n}
+% \begin{syntax}
+% \cs{dim_to_decimal_in_sp:n} \Arg{dim expr}
+% \end{syntax}
+% Evaluates the \meta{dim expr}, and leaves the result,
+% expressed in scaled points (\texttt{sp}) in the input stream, with \emph{no
+% units}. The result is necessarily an integer.
+% \end{function}
+%
+% \begin{function}[added = 2014-07-15, updated = 2023-05-20, EXP]
+% {\dim_to_decimal_in_unit:nn}
+% \begin{syntax}
+% \cs{dim_to_decimal_in_unit:nn} \Arg{dim expr_1} \Arg{dim expr_2}
+% \end{syntax}
+% Evaluates the \meta{dim exprs}, and leaves the value of
+% \meta{dim expr_1}, expressed in a unit given by \meta{dim expr_2}, in
+% the input stream. If the decimal part of the result
+% is zero, it is omitted, together with the decimal marker.
+% The precisions of the result is limited
+% to a maximum of five decimal places with trailing zeros omitted.
+%
+% For example
+% \begin{verbatim}
+% \dim_to_decimal_in_unit:nn { 1bp } { 1mm }
+% \end{verbatim}
+% leaves |0.35278| in the input stream, \emph{i.e.}~the magnitude of
+% one big point when expressed in millimetres. The conversions do
+% \emph{not} guarantee that \TeX{} would yield identical results
+% for the direct input in an equality test, thus for instance
+% \begin{verbatim}
+% \dim_compare:nNnTF
+% { 1bp } =
+% { \dim_to_decimal_in_unit:nn { 1bp } { 1mm } mm }
+% \end{verbatim}
+% will take the \texttt{false} branch.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2012-05-08, tested = m3fp-convert002]
+% {\dim_to_fp:n}
+% \begin{syntax}
+% \cs{dim_to_fp:n} \Arg{dim expr}
+% \end{syntax}
+% Expands to an internal floating point number equal to the value of
+% the \meta{dim expr} in \texttt{pt}. Since dimension expressions are
+% evaluated much faster than their floating point equivalent,
+% \cs{dim_to_fp:n} can be used to speed up parts of a computation
+% where a low precision and a smaller range are acceptable.
+% \end{function}
+%
+% \section{Viewing \texttt{dim} variables}
+%
+% \begin{function}{\dim_show:N, \dim_show:c}
+% \begin{syntax}
+% \cs{dim_show:N} \meta{dimension}
+% \end{syntax}
+% Displays the value of the \meta{dimension} on the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2011-11-22, updated = 2015-08-07]{\dim_show:n}
+% \begin{syntax}
+% \cs{dim_show:n} \Arg{dim expr}
+% \end{syntax}
+% Displays the result of evaluating the \meta{dim expr}
+% on the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2015-08-03]{\dim_log:N, \dim_log:c}
+% \begin{syntax}
+% \cs{dim_log:N} \meta{dimension}
+% \end{syntax}
+% Writes the value of the \meta{dimension} in the log file.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2015-08-07]{\dim_log:n}
+% \begin{syntax}
+% \cs{dim_log:n} \Arg{dim expr}
+% \end{syntax}
+% Writes the result of evaluating the \meta{dim expr}
+% in the log file.
+% \end{function}
+%
+% \section{Constant dimensions}
+%
+% \begin{variable}{\c_max_dim}
+% The maximum value that can be stored as a dimension. This can also
+% be used as a component of a skip.
+% \end{variable}
+%
+% \begin{variable}{\c_zero_dim}
+% A zero length as a dimension. This can also be used as a component
+% of a skip.
+% \end{variable}
+%
+% \section{Scratch dimensions}
+%
+% \begin{variable}{\l_tmpa_dim, \l_tmpb_dim}
+% Scratch dimension for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_dim, \g_tmpb_dim}
+% Scratch dimension for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Creating and initialising \texttt{skip} variables}
+%
+% \begin{function}{\skip_new:N, \skip_new:c}
+% \begin{syntax}
+% \cs{skip_new:N} \meta{skip}
+% \end{syntax}
+% Creates a new \meta{skip} or raises an error if the name is
+% already taken. The declaration is global. The \meta{skip}
+% is initially equal to $0$\,pt.
+% \end{function}
+%
+% \begin{function}[added = 2012-03-05]{\skip_const:Nn, \skip_const:cn}
+% \begin{syntax}
+% \cs{skip_const:Nn} \meta{skip} \Arg{skip expr}
+% \end{syntax}
+% Creates a new constant \meta{skip} or raises an error if the
+% name is already taken. The value of the \meta{skip} is set
+% globally to the \meta{skip expr}.
+% \end{function}
+%
+% \begin{function}{\skip_zero:N, \skip_zero:c, \skip_gzero:N, \skip_gzero:c}
+% \begin{syntax}
+% \cs{skip_zero:N} \meta{skip}
+% \end{syntax}
+% Sets \meta{skip} to $0$\,pt.
+% \end{function}
+%
+% \begin{function}[added = 2012-01-07]
+% {\skip_zero_new:N, \skip_zero_new:c, \skip_gzero_new:N, \skip_gzero_new:c}
+% \begin{syntax}
+% \cs{skip_zero_new:N} \meta{skip}
+% \end{syntax}
+% Ensures that the \meta{skip} exists globally by applying
+% \cs{skip_new:N} if necessary, then applies
+% \cs[index=skip_zero:N]{skip_(g)zero:N} to leave
+% the \meta{skip} set to zero.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added=2012-03-03]
+% {\skip_if_exist:N, \skip_if_exist:c}
+% \begin{syntax}
+% \cs{skip_if_exist_p:N} \meta{skip}
+% \cs{skip_if_exist:NTF} \meta{skip} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{skip} is currently defined. This does not
+% check that the \meta{skip} really is a skip variable.
+% \end{function}
+%
+% \section{Setting \texttt{skip} variables}
+%
+% \begin{function}[updated = 2011-10-22]
+% {\skip_add:Nn, \skip_add:cn, \skip_gadd:Nn, \skip_gadd:cn}
+% \begin{syntax}
+% \cs{skip_add:Nn} \meta{skip} \Arg{skip expr}
+% \end{syntax}
+% Adds the result of the \meta{skip expr} to the current
+% content of the \meta{skip}.
+% \end{function}
+%
+% \begin{function}[updated = 2011-10-22]
+% {\skip_set:Nn, \skip_set:cn, \skip_gset:Nn, \skip_gset:cn}
+% \begin{syntax}
+% \cs{skip_set:Nn} \meta{skip} \Arg{skip expr}
+% \end{syntax}
+% Sets \meta{skip} to the value of \meta{skip expr}, which
+% must evaluate to a length with units and may include a rubber
+% component (for example |1 cm plus 0.5 cm|.
+% \end{function}
+%
+% \begin{function}
+% {
+% \skip_set_eq:NN, \skip_set_eq:cN, \skip_set_eq:Nc, \skip_set_eq:cc,
+% \skip_gset_eq:NN, \skip_gset_eq:cN, \skip_gset_eq:Nc, \skip_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{skip_set_eq:NN} \meta{skip_1} \meta{skip_2}
+% \end{syntax}
+% Sets the content of \meta{skip_1} equal to that of \meta{skip_2}.
+% \end{function}
+%
+% \begin{function}[updated = 2011-10-22]
+% {\skip_sub:Nn, \skip_sub:cn, \skip_gsub:Nn, \skip_gsub:cn}
+% \begin{syntax}
+% \cs{skip_sub:Nn} \meta{skip} \Arg{skip expr}
+% \end{syntax}
+% Subtracts the result of the \meta{skip expr} from the
+% current content of the \meta{skip}.
+% \end{function}
+%
+% \section{Skip expression conditionals}
+%
+% \begin{function}[EXP,pTF]{\skip_if_eq:nn}
+% \begin{syntax}
+% \cs{skip_if_eq_p:nn} \Arg{skip expr_1} \Arg{skip expr_2}
+% \cs{skip_if_eq:nnTF}
+% ~~\Arg{skip expr_1} \Arg{skip expr_2}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function first evaluates each of the
+% \meta{skip exprs} as described for \cs{skip_eval:n}.
+% The two results are then compared for exact equality,
+% \emph{i.e.}~both the fixed and rubber components must be the same
+% for the test to be true.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added = 2012-03-05]{\skip_if_finite:n}
+% \begin{syntax}
+% \cs{skip_if_finite_p:n} \Arg{skip expr}
+% \cs{skip_if_finite:nTF} \Arg{skip expr} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Evaluates the \meta{skip expr} as described for \cs{skip_eval:n},
+% and then tests if all of its components are finite.
+% \end{function}
+%
+% \section{Using \texttt{skip} expressions and variables}
+%
+% \begin{function}[updated = 2011-10-22, EXP]{\skip_eval:n}
+% \begin{syntax}
+% \cs{skip_eval:n} \Arg{skip expr}
+% \end{syntax}
+% Evaluates the \meta{skip expr}, expanding any skips
+% and token list variables within the \meta{expression}
+% to their content (without requiring \cs{skip_use:N}/\cs{tl_use:N})
+% and applying the standard mathematical rules. The result of the
+% calculation is left in the input stream as a \meta{glue denotation}
+% after two expansions. This is expressed in points (\texttt{pt}),
+% and requires suitable termination if used in a \TeX{}-style
+% assignment as it is \emph{not} an \meta{internal glue}.
+% \end{function}
+%
+% \begin{function}[EXP]{\skip_use:N, \skip_use:c}
+% \begin{syntax}
+% \cs{skip_use:N} \meta{skip}
+% \end{syntax}
+% Recovers the content of a \meta{skip} and places it directly
+% in the input stream. An error is raised if the variable does
+% not exist or if it is invalid. Can be omitted in places where a
+% \meta{dimension} or \meta{skip} is required (such as in the argument of
+% \cs{skip_eval:n}).
+% \begin{texnote}
+% \cs{skip_use:N} is the \TeX{} primitive \tn{the}: this is one of
+% several \LaTeX3 names for this primitive.
+% \end{texnote}
+% \end{function}
+%
+% \section{Viewing \texttt{skip} variables}
+%
+% \begin{function}[updated = 2015-08-03]{\skip_show:N, \skip_show:c}
+% \begin{syntax}
+% \cs{skip_show:N} \meta{skip}
+% \end{syntax}
+% Displays the value of the \meta{skip} on the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2011-11-22, updated = 2015-08-07]{\skip_show:n}
+% \begin{syntax}
+% \cs{skip_show:n} \Arg{skip expr}
+% \end{syntax}
+% Displays the result of evaluating the \meta{skip expr}
+% on the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2015-08-03]{\skip_log:N, \skip_log:c}
+% \begin{syntax}
+% \cs{skip_log:N} \meta{skip}
+% \end{syntax}
+% Writes the value of the \meta{skip} in the log file.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2015-08-07]{\skip_log:n}
+% \begin{syntax}
+% \cs{skip_log:n} \Arg{skip expr}
+% \end{syntax}
+% Writes the result of evaluating the \meta{skip expr}
+% in the log file.
+% \end{function}
+%
+% \section{Constant skips}
+%
+% \begin{variable}[updated = 2012-11-02]{\c_max_skip}
+% The maximum value that can be stored as a skip (equal to
+% \cs{c_max_dim} in length), with no stretch nor shrink component.
+% \end{variable}
+%
+% \begin{variable}[updated = 2012-11-01]{\c_zero_skip}
+% A zero length as a skip, with no stretch nor shrink component.
+% \end{variable}
+%
+% \section{Scratch skips}
+%
+% \begin{variable}{\l_tmpa_skip, \l_tmpb_skip}
+% Scratch skip for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_skip, \g_tmpb_skip}
+% Scratch skip for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Inserting skips into the output}
+%
+% \begin{function}[updated = 2011-10-22]
+% {\skip_horizontal:N, \skip_horizontal:c, \skip_horizontal:n}
+% \begin{syntax}
+% \cs{skip_horizontal:N} \meta{skip}
+% \cs{skip_horizontal:n} \Arg{skip expr}
+% \end{syntax}
+% Inserts a horizontal \meta{skip} into the current list.
+% The argument can also be a \meta{dim}.
+% \begin{texnote}
+% \cs{skip_horizontal:N} is the \TeX{} primitive \tn{hskip}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[updated = 2011-10-22]
+% {\skip_vertical:N, \skip_vertical:c, \skip_vertical:n}
+% \begin{syntax}
+% \cs{skip_vertical:N} \meta{skip}
+% \cs{skip_vertical:n} \Arg{skip expr}
+% \end{syntax}
+% Inserts a vertical \meta{skip} into the current list.
+% The argument can also be a \meta{dim}.
+% \begin{texnote}
+% \cs{skip_vertical:N} is the \TeX{} primitive \tn{vskip}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Creating and initialising \texttt{muskip} variables}
+%
+% \begin{function}{\muskip_new:N, \muskip_new:c}
+% \begin{syntax}
+% \cs{muskip_new:N} \meta{muskip}
+% \end{syntax}
+% Creates a new \meta{muskip} or raises an error if the name is
+% already taken. The declaration is global. The \meta{muskip}
+% is initially equal to $0$\,mu.
+% \end{function}
+%
+% \begin{function}[added = 2012-03-05]{\muskip_const:Nn, \muskip_const:cn}
+% \begin{syntax}
+% \cs{muskip_const:Nn} \meta{muskip} \Arg{muskip expr}
+% \end{syntax}
+% Creates a new constant \meta{muskip} or raises an error if the
+% name is already taken. The value of the \meta{muskip} is set
+% globally to the \meta{muskip expr}.
+% \end{function}
+%
+% \begin{function}
+% {\muskip_zero:N, \muskip_zero:c, \muskip_gzero:N, \muskip_gzero:c}
+% \begin{syntax}
+% \cs{skip_zero:N} \meta{muskip}
+% \end{syntax}
+% Sets \meta{muskip} to $0$\,mu.
+% \end{function}
+%
+% \begin{function}[added = 2012-01-07]
+% {
+% \muskip_zero_new:N, \muskip_zero_new:c,
+% \muskip_gzero_new:N, \muskip_gzero_new:c
+% }
+% \begin{syntax}
+% \cs{muskip_zero_new:N} \meta{muskip}
+% \end{syntax}
+% Ensures that the \meta{muskip} exists globally by applying
+% \cs{muskip_new:N} if necessary, then applies
+% \cs[index=muskip_zero:N]{muskip_(g)zero:N}
+% to leave the \meta{muskip} set to zero.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added=2012-03-03]
+% {\muskip_if_exist:N, \muskip_if_exist:c}
+% \begin{syntax}
+% \cs{muskip_if_exist_p:N} \meta{muskip}
+% \cs{muskip_if_exist:NTF} \meta{muskip} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{muskip} is currently defined. This does not
+% check that the \meta{muskip} really is a muskip variable.
+% \end{function}
+%
+% \section{Setting \texttt{muskip} variables}
+%
+% \begin{function}[updated = 2011-10-22]
+% {\muskip_add:Nn, \muskip_add:cn, \muskip_gadd:Nn, \muskip_gadd:cn}
+% \begin{syntax}
+% \cs{muskip_add:Nn} \meta{muskip} \Arg{muskip expr}
+% \end{syntax}
+% Adds the result of the \meta{muskip expr} to the current
+% content of the \meta{muskip}.
+% \end{function}
+%
+% \begin{function}[updated = 2011-10-22]
+% {\muskip_set:Nn, \muskip_set:cn, \muskip_gset:Nn, \muskip_gset:cn}
+% \begin{syntax}
+% \cs{muskip_set:Nn} \meta{muskip} \Arg{muskip expr}
+% \end{syntax}
+% Sets \meta{muskip} to the value of \meta{muskip expr}, which
+% must evaluate to a math length with units and may include a rubber
+% component (for example |1 mu plus 0.5 mu|.
+% \end{function}
+%
+% \begin{function}
+% {
+% \muskip_set_eq:NN, \muskip_set_eq:cN,
+% \muskip_set_eq:Nc, \muskip_set_eq:cc,
+% \muskip_gset_eq:NN, \muskip_gset_eq:cN,
+% \muskip_gset_eq:Nc, \muskip_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{muskip_set_eq:NN} \meta{muskip_1} \meta{muskip_2}
+% \end{syntax}
+% Sets the content of \meta{muskip_1} equal to that of
+% \meta{muskip_2}.
+% \end{function}
+%
+% \begin{function}[updated = 2011-10-22]
+% {\muskip_sub:Nn, \muskip_sub:cn, \muskip_gsub:Nn, \muskip_gsub:cn}
+% \begin{syntax}
+% \cs{muskip_sub:Nn} \meta{muskip} \Arg{muskip expr}
+% \end{syntax}
+% Subtracts the result of the \meta{muskip expr} from the
+% current content of the \meta{muskip}.
+% \end{function}
+%
+% \section{Using \texttt{muskip} expressions and variables}
+%
+% \begin{function}[updated = 2011-10-22, EXP]{\muskip_eval:n}
+% \begin{syntax}
+% \cs{muskip_eval:n} \Arg{muskip expr}
+% \end{syntax}
+% Evaluates the \meta{muskip expr}, expanding any skips
+% and token list variables within the \meta{expression}
+% to their content (without requiring \cs{muskip_use:N}/\cs{tl_use:N})
+% and applying the standard mathematical rules. The result of the
+% calculation is left in the input stream as a \meta{muglue denotation}
+% after two expansions. This is expressed in \texttt{mu},
+% and requires suitable termination if used in a \TeX{}-style
+% assignment as it is \emph{not} an \meta{internal muglue}.
+% \end{function}
+%
+% \begin{function}[EXP]{\muskip_use:N, \muskip_use:c}
+% \begin{syntax}
+% \cs{muskip_use:N} \meta{muskip}
+% \end{syntax}
+% Recovers the content of a \meta{skip} and places it directly
+% in the input stream. An error is raised if the variable does
+% not exist or if it is invalid. Can be omitted in places where a
+% \meta{dimension} is required (such as in the argument of
+% \cs{muskip_eval:n}).
+% \begin{texnote}
+% \cs{muskip_use:N} is the \TeX{} primitive \tn{the}: this is one of
+% several \LaTeX3 names for this primitive.
+% \end{texnote}
+% \end{function}
+%
+% \section{Viewing \texttt{muskip} variables}
+%
+% \begin{function}[updated = 2015-08-03]{\muskip_show:N, \muskip_show:c}
+% \begin{syntax}
+% \cs{muskip_show:N} \meta{muskip}
+% \end{syntax}
+% Displays the value of the \meta{muskip} on the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2011-11-22, updated = 2015-08-07]{\muskip_show:n}
+% \begin{syntax}
+% \cs{muskip_show:n} \Arg{muskip expr}
+% \end{syntax}
+% Displays the result of evaluating the \meta{muskip expr}
+% on the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2015-08-03]{\muskip_log:N, \muskip_log:c}
+% \begin{syntax}
+% \cs{muskip_log:N} \meta{muskip}
+% \end{syntax}
+% Writes the value of the \meta{muskip} in the log file.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2015-08-07]{\muskip_log:n}
+% \begin{syntax}
+% \cs{muskip_log:n} \Arg{muskip expr}
+% \end{syntax}
+% Writes the result of evaluating the \meta{muskip expr}
+% in the log file.
+% \end{function}
+%
+% \section{Constant muskips}
+%
+% \begin{variable}{\c_max_muskip}
+% The maximum value that can be stored as a muskip, with no stretch
+% nor shrink component.
+% \end{variable}
+%
+% \begin{variable}{\c_zero_muskip}
+% A zero length as a muskip, with no stretch nor shrink component.
+% \end{variable}
+%
+% \section{Scratch muskips}
+%
+% \begin{variable}{\l_tmpa_muskip, \l_tmpb_muskip}
+% Scratch muskip for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_muskip, \g_tmpb_muskip}
+% Scratch muskip for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Primitive conditional}
+%
+% \begin{function}[EXP]{\if_dim:w}
+% \begin{syntax}
+% \cs{if_dim:w} \meta{dimen_1} \meta{relation} \meta{dimen_2}
+% ~~\meta{true code}
+% \cs{else:}
+% ~~\meta{false}
+% \cs{fi:}
+% \end{syntax}
+% Compare two dimensions. The \meta{relation} is one of
+% |<|, |=| or |>| with category code $12$.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifdim}.
+% \end{texnote}
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3skip} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=dim>
+% \end{macrocode}
+%
+% \subsection{Length primitives renamed}
+%
+% \begin{macro}{\if_dim:w}
+% \begin{macro}{\@@_eval:w}
+% \begin{macro}{\@@_eval_end:}
+% Primitives renamed.
+% \begin{macrocode}
+\cs_new_eq:NN \if_dim:w \tex_ifdim:D
+\cs_new_eq:NN \@@_eval:w \tex_dimexpr:D
+\cs_new_eq:NN \@@_eval_end: \tex_relax:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Internal auxiliaries}
+%
+% \begin{variable}{\s_@@_mark,\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_use_none_delimit_by_s_stop:w}
+% Functions to gobble up to a scan mark.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_none_delimit_by_s_stop:w #1 \s_@@_stop { }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Creating and initialising \texttt{dim} variables}
+%
+% \begin{macro}{\dim_new:N, \dim_new:c}
+% Allocating \meta{dim} registers \ldots
+% \begin{macrocode}
+\cs_new_protected:Npn \dim_new:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \cs:w newdimen \cs_end: #1
+ }
+\cs_generate_variant:Nn \dim_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\dim_const:Nn, \dim_const:cn}
+% Contrarily to integer constants, we cannot avoid using a register,
+% even for constants. We cannot use \cs{dim_gset:Nn} because
+% debugging code would complain that the constant is not a global
+% variable. Since \cs{dim_const:Nn} does not need to be fast, use
+% \cs{dim_eval:n} to avoid needing a debugging patch that wraps the
+% expression in checking code.
+% \begin{macrocode}
+\cs_new_protected:Npn \dim_const:Nn #1#2
+ {
+ \dim_new:N #1
+ \tex_global:D #1 = \dim_eval:n {#2} \scan_stop:
+ }
+\cs_generate_variant:Nn \dim_const:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\dim_zero:N, \dim_zero:c}
+% \begin{macro}{\dim_gzero:N, \dim_gzero:c}
+% Reset the register to zero. Using \cs{c_zero_skip} deals with the
+% case where the variable passed is incorrectly a skip (for example a
+% \LaTeXe{} length). Besides, these functions are then simply copied
+% for \cs{skip_zero:N} and related functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \dim_zero:N #1 { #1 = \c_zero_skip }
+\cs_new_protected:Npn \dim_gzero:N #1
+ { \tex_global:D #1 = \c_zero_skip }
+\cs_generate_variant:Nn \dim_zero:N { c }
+\cs_generate_variant:Nn \dim_gzero:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\dim_zero_new:N, \dim_zero_new:c, \dim_gzero_new:N, \dim_gzero_new:c}
+% Create a register if needed, otherwise clear it.
+% \begin{macrocode}
+\cs_new_protected:Npn \dim_zero_new:N #1
+ { \dim_if_exist:NTF #1 { \dim_zero:N #1 } { \dim_new:N #1 } }
+\cs_new_protected:Npn \dim_gzero_new:N #1
+ { \dim_if_exist:NTF #1 { \dim_gzero:N #1 } { \dim_new:N #1 } }
+\cs_generate_variant:Nn \dim_zero_new:N { c }
+\cs_generate_variant:Nn \dim_gzero_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\dim_if_exist:N, \dim_if_exist:c}
+% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \dim_if_exist:N \cs_if_exist:N
+ { TF , T , F , p }
+\prg_new_eq_conditional:NNn \dim_if_exist:c \cs_if_exist:c
+ { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Setting \texttt{dim} variables}
+%
+% \begin{macro}{\dim_set:Nn, \dim_set:cn}
+% \begin{macro}{\dim_gset:Nn, \dim_gset:cn}
+% Setting dimensions is easy enough but when debugging we want both to
+% check that the variable is correctly local/global and to wrap the
+% expression in some code. The \cs{scan_stop:} deals with the case
+% where the variable passed is a skip (for example a \LaTeXe{}
+% length).
+% \begin{macrocode}
+\cs_new_protected:Npn \dim_set:Nn #1#2
+ { #1 = \@@_eval:w #2 \@@_eval_end: \scan_stop: }
+\cs_new_protected:Npn \dim_gset:Nn #1#2
+ { \tex_global:D #1 = \@@_eval:w #2 \@@_eval_end: \scan_stop: }
+\cs_generate_variant:Nn \dim_set:Nn { c }
+\cs_generate_variant:Nn \dim_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_set_eq:NN, \dim_set_eq:cN, \dim_set_eq:Nc, \dim_set_eq:cc}
+% \begin{macro}
+% {\dim_gset_eq:NN, \dim_gset_eq:cN, \dim_gset_eq:Nc, \dim_gset_eq:cc}
+% All straightforward, with a \cs{scan_stop:} to deal with the case
+% where |#1| is (incorrectly) a skip.
+% \begin{macrocode}
+\cs_new_protected:Npn \dim_set_eq:NN #1#2
+ { #1 = #2 \scan_stop: }
+\cs_generate_variant:Nn \dim_set_eq:NN { c , Nc , cc }
+\cs_new_protected:Npn \dim_gset_eq:NN #1#2
+ { \tex_global:D #1 = #2 \scan_stop: }
+\cs_generate_variant:Nn \dim_gset_eq:NN { c , Nc , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_add:Nn, \dim_add:cn}
+% \begin{macro}{\dim_gadd:Nn, \dim_gadd:cn}
+% \begin{macro}{\dim_sub:Nn, \dim_sub:cn}
+% \begin{macro}{\dim_gsub:Nn, \dim_gsub:cn}
+% Using |by| here would slow things down just to detect nonsensical
+% cases such as passing |\dimen 123| as the first argument.
+% Using \cs{scan_stop:} deals with skip variables. Since
+% debugging checks that the variable is correctly local/global, the
+% global versions cannot be defined as \cs{tex_global:D} followed by
+% the local versions.
+% \begin{macrocode}
+\cs_new_protected:Npn \dim_add:Nn #1#2
+ { \tex_advance:D #1 \@@_eval:w #2 \@@_eval_end: \scan_stop: }
+\cs_new_protected:Npn \dim_gadd:Nn #1#2
+ {
+ \tex_global:D \tex_advance:D #1
+ \@@_eval:w #2 \@@_eval_end: \scan_stop:
+ }
+\cs_generate_variant:Nn \dim_add:Nn { c }
+\cs_generate_variant:Nn \dim_gadd:Nn { c }
+\cs_new_protected:Npn \dim_sub:Nn #1#2
+ { \tex_advance:D #1 - \@@_eval:w #2 \@@_eval_end: \scan_stop: }
+\cs_new_protected:Npn \dim_gsub:Nn #1#2
+ {
+ \tex_global:D \tex_advance:D #1
+ -\@@_eval:w #2 \@@_eval_end: \scan_stop:
+ }
+\cs_generate_variant:Nn \dim_sub:Nn { c }
+\cs_generate_variant:Nn \dim_gsub:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Utilities for dimension calculations}
+%
+% \begin{macro}[EXP]{\dim_abs:n}
+% \begin{macro}[EXP]{\@@_abs:N}
+% \UnitTested
+% \begin{macro}[EXP]{\dim_max:nn}
+% \begin{macro}[EXP]{\dim_min:nn}
+% \begin{macro}[EXP]{\@@_maxmin:wwN}
+% \UnitTested
+% \UnitTested
+% Functions for $\min$, $\max$, and absolute value with only one evaluation.
+% The absolute value is evaluated by removing a leading~|-| if present.
+% \begin{macrocode}
+\cs_new:Npn \dim_abs:n #1
+ {
+ \exp_after:wN \@@_abs:N
+ \dim_use:N \@@_eval:w #1 \@@_eval_end:
+ }
+\cs_new:Npn \@@_abs:N #1
+ { \if_meaning:w - #1 \else: \exp_after:wN #1 \fi: }
+\cs_new:Npn \dim_max:nn #1#2
+ {
+ \dim_use:N \@@_eval:w \exp_after:wN \@@_maxmin:wwN
+ \dim_use:N \@@_eval:w #1 \exp_after:wN ;
+ \dim_use:N \@@_eval:w #2 ;
+ >
+ \@@_eval_end:
+ }
+\cs_new:Npn \dim_min:nn #1#2
+ {
+ \dim_use:N \@@_eval:w \exp_after:wN \@@_maxmin:wwN
+ \dim_use:N \@@_eval:w #1 \exp_after:wN ;
+ \dim_use:N \@@_eval:w #2 ;
+ <
+ \@@_eval_end:
+ }
+\cs_new:Npn \@@_maxmin:wwN #1 ; #2 ; #3
+ {
+ \if_dim:w #1 #3 #2 ~
+ #1
+ \else:
+ #2
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_ratio:nn}
+% \begin{macro}{\@@_ratio:n}
+% With dimension expressions, something like |10 pt * ( 5 pt / 10 pt )| does
+% not work. Instead, the ratio part needs to be converted to an integer
+% expression. Using \cs{int_value:w} forces everything into |sp|, avoiding
+% any decimal parts.
+% \begin{macrocode}
+\cs_new:Npn \dim_ratio:nn #1#2
+ { \@@_ratio:n {#1} / \@@_ratio:n {#2} }
+\cs_new:Npn \@@_ratio:n #1
+ { \int_value:w \@@_eval:w (#1) \@@_eval_end: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Dimension expression conditionals}
+%
+% \begin{macro}[pTF, EXP]{\dim_compare:nNn}
+% Simple comparison.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \dim_compare:nNn #1#2#3 { p , T , F , TF }
+ {
+ \if_dim:w \@@_eval:w #1 #2 \@@_eval:w #3 \@@_eval_end:
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF, EXP]{\dim_compare:n}
+% \begin{macro}[EXP]{\@@_compare:w, \@@_compare:wNN}
+% \begin{macro}[EXP]
+% {
+% \@@_compare_=:w,
+% \@@_compare_!:w,
+% \@@_compare_<:w,
+% \@@_compare_>:w
+% }
+% \begin{macro}{\@@_compare_error:}
+% This code is adapted from the \cs{int_compare:nTF} function. First
+% make sure that there is at least one relation operator, by
+% evaluating a dimension expression with a trailing
+% \cs{@@_compare_error:}. Just like for integers, the looping
+% auxiliary \cs{@@_compare:wNN} closes a primitive conditional and
+% opens a new one. It is actually easier to grab a dimension operand
+% than an integer one, because once evaluated, dimensions all end with
+% \texttt{pt} (with category other). Thus we do not need specific
+% auxiliaries for the three \enquote{simple} relations |<|, |=|,
+% and~|>|.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \dim_compare:n #1 { p , T , F , TF }
+ {
+ \exp_after:wN \@@_compare:w
+ \dim_use:N \@@_eval:w #1 \@@_compare_error:
+ }
+\cs_new:Npn \@@_compare:w #1 \@@_compare_error:
+ {
+ \exp_after:wN \if_false: \exp:w \exp_end_continue_f:w
+ \@@_compare:wNN #1 ? { = \@@_compare_end:w \else: } \s_@@_stop
+ }
+\exp_args:Nno \use:nn
+ { \cs_new:Npn \@@_compare:wNN #1 } { \tl_to_str:n {pt} #2#3 }
+ {
+ \if_meaning:w = #3
+ \use:c { @@_compare_#2:w }
+ \fi:
+ #1 pt \exp_stop_f:
+ \prg_return_false:
+ \exp_after:wN \@@_use_none_delimit_by_s_stop:w
+ \fi:
+ \reverse_if:N \if_dim:w #1 pt #2
+ \exp_after:wN \@@_compare:wNN
+ \dim_use:N \@@_eval:w #3
+ }
+\cs_new:cpn { @@_compare_ ! :w }
+ #1 \reverse_if:N #2 ! #3 = { #1 #2 = #3 }
+\cs_new:cpn { @@_compare_ = :w }
+ #1 \@@_eval:w = { #1 \@@_eval:w }
+\cs_new:cpn { @@_compare_ < :w }
+ #1 \reverse_if:N #2 < #3 = { #1 #2 > #3 }
+\cs_new:cpn { @@_compare_ > :w }
+ #1 \reverse_if:N #2 > #3 = { #1 #2 < #3 }
+\cs_new:Npn \@@_compare_end:w #1 \prg_return_false: #2 \s_@@_stop
+ { #1 \prg_return_false: \else: \prg_return_true: \fi: }
+\cs_new_protected:Npn \@@_compare_error:
+ {
+ \if_int_compare:w \c_zero_int \c_zero_int \fi:
+ =
+ \@@_compare_error:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP, noTF]{\dim_case:nn}
+% \begin{macro}{\@@_case:nnTF}
+% \begin{macro}{\@@_case:nw, \@@_case_end:nw}
+% For dimension cases, the first task to fully expand the check
+% condition. The over all idea is then much the same as for
+% \cs{str_case:nnTF} as described in \pkg{l3basics}.
+% \begin{macrocode}
+\cs_new:Npn \dim_case:nnTF #1
+ {
+ \exp:w
+ \exp_args:Nf \@@_case:nnTF { \dim_eval:n {#1} }
+ }
+\cs_new:Npn \dim_case:nnT #1#2#3
+ {
+ \exp:w
+ \exp_args:Nf \@@_case:nnTF { \dim_eval:n {#1} } {#2} {#3} { }
+ }
+\cs_new:Npn \dim_case:nnF #1#2
+ {
+ \exp:w
+ \exp_args:Nf \@@_case:nnTF { \dim_eval:n {#1} } {#2} { }
+ }
+\cs_new:Npn \dim_case:nn #1#2
+ {
+ \exp:w
+ \exp_args:Nf \@@_case:nnTF { \dim_eval:n {#1} } {#2} { } { }
+ }
+\cs_new:Npn \@@_case:nnTF #1#2#3#4
+ { \@@_case:nw {#1} #2 {#1} { } \s_@@_mark {#3} \s_@@_mark {#4} \s_@@_stop }
+\cs_new:Npn \@@_case:nw #1#2#3
+ {
+ \dim_compare:nNnTF {#1} = {#2}
+ { \@@_case_end:nw {#3} }
+ { \@@_case:nw {#1} }
+ }
+\cs_new:Npn \@@_case_end:nw #1#2#3 \s_@@_mark #4#5 \s_@@_stop
+ { \exp_end: #1 #4 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Dimension expression loops}
+%
+% \begin{macro}{\dim_while_do:nn}
+% \begin{macro}{\dim_until_do:nn}
+% \begin{macro}{\dim_do_while:nn}
+% \begin{macro}{\dim_do_until:nn}
+% |while_do| and |do_while| functions for dimensions. Same as for the
+% |int| type only the names have changed.
+% \begin{macrocode}
+\cs_new:Npn \dim_while_do:nn #1#2
+ {
+ \dim_compare:nT {#1}
+ {
+ #2
+ \dim_while_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \dim_until_do:nn #1#2
+ {
+ \dim_compare:nF {#1}
+ {
+ #2
+ \dim_until_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \dim_do_while:nn #1#2
+ {
+ #2
+ \dim_compare:nT {#1}
+ { \dim_do_while:nn {#1} {#2} }
+ }
+\cs_new:Npn \dim_do_until:nn #1#2
+ {
+ #2
+ \dim_compare:nF {#1}
+ { \dim_do_until:nn {#1} {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_while_do:nNnn}
+% \begin{macro}{\dim_until_do:nNnn}
+% \begin{macro}{\dim_do_while:nNnn}
+% \begin{macro}{\dim_do_until:nNnn}
+% |while_do| and |do_while| functions for dimensions. Same as for the
+% |int| type only the names have changed.
+% \begin{macrocode}
+\cs_new:Npn \dim_while_do:nNnn #1#2#3#4
+ {
+ \dim_compare:nNnT {#1} #2 {#3}
+ {
+ #4
+ \dim_while_do:nNnn {#1} #2 {#3} {#4}
+ }
+ }
+\cs_new:Npn \dim_until_do:nNnn #1#2#3#4
+ {
+ \dim_compare:nNnF {#1} #2 {#3}
+ {
+ #4
+ \dim_until_do:nNnn {#1} #2 {#3} {#4}
+ }
+ }
+\cs_new:Npn \dim_do_while:nNnn #1#2#3#4
+ {
+ #4
+ \dim_compare:nNnT {#1} #2 {#3}
+ { \dim_do_while:nNnn {#1} #2 {#3} {#4} }
+ }
+\cs_new:Npn \dim_do_until:nNnn #1#2#3#4
+ {
+ #4
+ \dim_compare:nNnF {#1} #2 {#3}
+ { \dim_do_until:nNnn {#1} #2 {#3} {#4} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Dimension step functions}
+%
+% \begin{macro}{\dim_step_function:nnnN}
+% \begin{macro}{\@@_step:wwwN, \@@_step:NnnnN}
+% Before all else, evaluate the initial value, step, and final value.
+% Repeating a function by steps first needs a check on the direction
+% of the steps. After that, do the function for the start value then
+% step and loop around. It would be more symmetrical to test for a
+% step size of zero before checking the sign, but we optimize for the
+% most frequent case (positive step).
+% \begin{macrocode}
+\cs_new:Npn \dim_step_function:nnnN #1#2#3
+ {
+ \exp_after:wN \@@_step:wwwN
+ \tex_the:D \@@_eval:w #1 \exp_after:wN ;
+ \tex_the:D \@@_eval:w #2 \exp_after:wN ;
+ \tex_the:D \@@_eval:w #3 ;
+ }
+\cs_new:Npn \@@_step:wwwN #1; #2; #3; #4
+ {
+ \dim_compare:nNnTF {#2} > \c_zero_dim
+ { \@@_step:NnnnN > }
+ {
+ \dim_compare:nNnTF {#2} = \c_zero_dim
+ {
+ \msg_expandable_error:nnn { kernel } { zero-step } {#4}
+ \use_none:nnnn
+ }
+ { \@@_step:NnnnN < }
+ }
+ {#1} {#2} {#3} #4
+ }
+\cs_new:Npn \@@_step:NnnnN #1#2#3#4#5
+ {
+ \dim_compare:nNnF {#2} #1 {#4}
+ {
+ #5 {#2}
+ \exp_args:NNf \@@_step:NnnnN
+ #1 { \dim_eval:n { #2 + #3 } } {#3} {#4} #5
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_step_inline:nnnn}
+% \begin{macro}{\dim_step_variable:nnnNn}
+% \begin{macro}{\@@_step:NNnnnn}
+% The approach here is to build a function, with a global integer
+% required to make the nesting safe (as seen in other in line
+% functions), and map that function using \cs{dim_step_function:nnnN}.
+% We put a \cs{prg_break_point:Nn} so that \texttt{map_break}
+% functions from other modules correctly decrement \cs{g__kernel_prg_map_int}
+% before looking for their own break point. The first argument is
+% \cs{scan_stop:}, so that no breaking function recognizes this break
+% point as its own.
+% \begin{macrocode}
+\cs_new_protected:Npn \dim_step_inline:nnnn
+ {
+ \int_gincr:N \g__kernel_prg_map_int
+ \exp_args:NNc \@@_step:NNnnnn
+ \cs_gset_protected:Npn
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
+ }
+\cs_new_protected:Npn \dim_step_variable:nnnNn #1#2#3#4#5
+ {
+ \int_gincr:N \g__kernel_prg_map_int
+ \exp_args:NNc \@@_step:NNnnnn
+ \cs_gset_protected:Npe
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
+ {#1}{#2}{#3}
+ {
+ \tl_set:Nn \exp_not:N #4 {##1}
+ \exp_not:n {#5}
+ }
+ }
+\cs_new_protected:Npn \@@_step:NNnnnn #1#2#3#4#5#6
+ {
+ #1 #2 ##1 {#6}
+ \dim_step_function:nnnN {#3} {#4} {#5} #2
+ \prg_break_point:Nn \scan_stop: { \int_gdecr:N \g__kernel_prg_map_int }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using \texttt{dim} expressions and variables}
+%
+% \begin{macro}{\dim_eval:n}
+% Evaluating a dimension expression expandably.
+% \begin{macrocode}
+\cs_new:Npn \dim_eval:n #1
+ { \dim_use:N \@@_eval:w #1 \@@_eval_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\dim_sign:n, \@@_sign:Nw}
+% See \cs{dim_abs:n}. Contrarily to \cs{int_sign:n} the case of a
+% zero dimension cannot be distinguished from a positive dimension by
+% looking only at the first character, since |0.2pt| and |0pt| start
+% the same way. We need explicit comparisons. We start by
+% distinguishing the most common case of a positive dimension.
+% \begin{macrocode}
+\cs_new:Npn \dim_sign:n #1
+ {
+ \int_value:w \exp_after:wN \@@_sign:Nw
+ \dim_use:N \@@_eval:w #1 \@@_eval_end: ;
+ \exp_stop_f:
+ }
+\cs_new:Npn \@@_sign:Nw #1#2 ;
+ {
+ \if_dim:w #1#2 > \c_zero_dim
+ 1
+ \else:
+ \if_meaning:w - #1
+ -1
+ \else:
+ 0
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\dim_use:N, \dim_use:c}
+% Accessing a \meta{dim}. We hand-code the |c| variant for some speed gain.
+% \begin{macrocode}
+\cs_new_eq:NN \dim_use:N \tex_the:D
+\cs_new:Npn \dim_use:c #1 { \tex_the:D \cs:w #1 \cs_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\dim_to_decimal:n}
+% \begin{macro}[EXP]{\@@_to_decimal:w}
+% A function which comes up often enough to deserve a place in the
+% kernel. Evaluate the dimension expression~|#1| then remove the
+% trailing \texttt{pt}. When debugging is enabled, the argument is
+% put in parentheses as this prevents the dimension expression from
+% terminating early and leaving extra tokens lying around. This is
+% used a lot by low-level manipulations.
+% \begin{macrocode}
+\cs_new:Npn \dim_to_decimal:n #1
+ {
+ \exp_after:wN
+ \@@_to_decimal:w \dim_use:N \@@_eval:w #1 \@@_eval_end:
+ }
+\use:e
+ {
+ \cs_new:Npn \exp_not:N \@@_to_decimal:w
+ #1 . #2 \tl_to_str:n { pt }
+ }
+ {
+ \int_compare:nNnTF {#2} > \c_zero_int
+ { #1 . #2 }
+ { #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\dim_to_fp:n}
+% Defined in \pkg{l3fp-convert}, documented here.
+% \end{macro}
+%
+% \subsection{Conversion of \texttt{dim} to other units}
+%
+% The conversion from \texttt{pt} or \texttt{sp} to other units is complicated
+% by the fact that \TeX{}'s conversion to \texttt{sp} involves rounding and
+% hard-coded ratios. In order to give re-entrant outcomes, we therefore need
+% to do quite a bit of work: see
+% \url{https://github.com/latex3/latex3/issues/954} for detailed discussion.
+% After dealing with the trivial case, we therefore have some work to do.
+% The code to do this is contributed by Ruixi Zhang.
+%
+% \begin{macro}[EXP]{\dim_to_decimal_in_sp:n}
+% The one easy case: the only requirement here is that we avoid an
+% overflow.
+% \begin{macrocode}
+\cs_new:Npn \dim_to_decimal_in_sp:n #1
+ { \int_value:w \@@_eval:w #1 \@@_eval_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \dim_to_decimal_in_bp:n ,
+% \dim_to_decimal_in_cc:n ,
+% \dim_to_decimal_in_cm:n ,
+% \dim_to_decimal_in_dd:n ,
+% \dim_to_decimal_in_in:n ,
+% \dim_to_decimal_in_mm:n ,
+% \dim_to_decimal_in_pc:n
+% }
+% \begin{macro}[EXP]{\@@_to_decimal_aux:w}
+% We first set up a helper macro \cs[no-index]{@@_tmp:w} which takes two
+% arguments. The first argument is one of the following engine-defined
+% units: |in|,~|pc|, |cm|, |mm|, |bp|, |dd|, |cc|, |nd|, and~|nc|.
+% The second argument is $\frac{1}{2}\delta^{-1}$ in reduced fraction,
+% where $\delta>1$~is the engine-defined conversion factor for each unit.
+% Note that $\delta$~must be strictly larger than~$1$ for the following
+% algorithm to work.
+%
+% Here is how the algorithm works: Suppose that a user inputs a
+% non-negative dimension in a unit that has conversion factor~$\delta>1$.
+% Then this dimension is internally represented as $X$\,sp, where
+% $X=\lfloor N\delta\rfloor$ for some integer $N\ge0$. We then seek a
+% formula to express this $N$ using~$X$.
+% The \cs[no-index]{dim_to_decimal_in_<unit>:n} functions shall return
+% the number $N/2^{16}$ in decimal. This way, we guarantee the returned
+% decimal followed by the original unit will parse to exactly~$X$\,sp.
+%
+% So how do we get $N$ from~$X$? Well, since $X=\lfloor N\delta\rfloor$,
+% we have $X\le N\delta<X+1$ and $X\delta^{-1}\le N<(X+1)\delta^{-1}$.
+% Let's focus on the midpoint of this bounding interval for~$N$. The
+% midpoint is $(X+\frac{1}{2})\delta^{-1}$. The fact $\delta>1$ implies
+% that the bounding interval is shorter than~$1$ in length. Thus,
+% (1)~$\hbox{midpoint}+\frac{1}{2}>N$ and
+% (2)~$\hbox{midpoint}+\frac{1}{2}<N+1$. In other words,
+% $N=\lfloor\hbox{midpoint}+\frac{1}{2}\rfloor$. As long as we can
+% rewrite the midpoint as the result of a \enquote{scaling operation} of \eTeX,
+% the $\lfloor\ldots+\frac{1}{2}\rfloor$ part will follow naturally.
+% Indeed we can: $\hbox{midpoint}=(2X+1)\times(\frac{1}{2}\delta^{-1})$.
+%
+% Addendum: If $\delta\ge2$, then the bounding interval for~$N$ is at
+% most~$\frac{1}{2}$ wide in length. In this case, the leftpoint
+% $X\delta^{-1}$ suffices as $N=\lfloor X\delta^{-1}+\frac{1}{2}\rfloor$.
+% Six out of the nine units listed above can be handled in this way,
+% which is much simpler than using midpoint. But three remaining units
+% have $1<\delta<2$; they are |bp|~($\delta=7227/7200$),
+% |nd|~($\delta=685/642$), and |dd|~($\delta=1238/1157$),
+% and these three must be handled using midpoint.
+% For consistency, we shall use the midpoint approach for all nine units.
+% \begin{macrocode}
+\group_begin:
+ \cs_set_protected:Npn \@@_tmp:w #1#2
+ {
+ \cs_new:cpn { dim_to_decimal_in_ #1 :n } ##1
+ {
+ \exp_after:wN \@@_to_decimal_aux:w
+ \int_value:w \@@_eval:w ##1 \@@_eval_end: ; #2 ;
+ }
+ }
+% \end{macrocode}
+% Conversions to other units are now coded.
+% Consult the pdf\/\TeX{} source for each conversion factor~$\delta$.
+% Each factor $\frac{1}{2}\delta^{-1}$ is hand-coded
+% for accuracy (and speed). As the units \texttt{nc} and \texttt{nd}
+% are not supported by \XeTeX{} or (u)p\TeX{}, they are not included
+% here.
+% \begin{macrocode}
+ \@@_tmp:w { in } { 50 / 7227 } % delta = 7227/100
+ \@@_tmp:w { pc } { 1 / 24 } % delta = 12/1
+ \@@_tmp:w { cm } { 127 / 7227 } % delta = 7227/254
+ \@@_tmp:w { mm } { 1270 / 7227 } % delta = 7227/2540
+ \@@_tmp:w { bp } { 400 / 803 } % delta = 7227/7200
+ \@@_tmp:w { dd } { 1157 / 2476 } % delta = 1238/1157
+ \@@_tmp:w { cc } { 1157 / 29712 } % delta = 14856/1157
+\group_end:
+% \end{macrocode}
+% The tokens after \cs{@@_to_decimal_aux:w} shall have the following form:
+% |<number>;<half of delta inverse>;|, where |<number>| represents the
+% input dimension in |sp| unit.
+% If |<number>| is positive, then |#1| is its leading digit and |#2|
+% (possibly empty) is all the remaining digits;
+% If |<number>| is zero, then |#1| is~|0|$_{12}$ and |#2| is empty;
+% If |<number>| is negative, then |#1| is its sign~|-|$_{12}$ and |#2|
+% is all its digits.
+% In all three cases, |#1#2| is the original |<number>|. We can use |#1|
+% to decide whether to use the |-1| formula or the |+1| formula.
+% \begin{macrocode}
+\cs_new:Npn \@@_to_decimal_aux:w #1#2 ; #3 ;
+ {
+ \dim_to_decimal:n
+ {
+% \end{macrocode}
+% We need different formulae depending on whether the user input dimension
+% is negative or not.
+% For negative dimension (internally represented as $X$\,sp), the formula
+% is $(2X-1)\times(\frac{1}{2}\delta^{-1})$.
+% For non-negative dimension, the formula
+% is $(2X+1)\times(\frac{1}{2}\delta^{-1})$.
+% The intermediate step doubles the dimension~$X$.
+% To avoid overflow, we must invoke \cs[no-index]{int_eval:n}.
+% \begin{macrocode}
+ \int_eval:n
+ { ( 2 * #1#2 \if:w #1 - - \else: + \fi: 1 ) * #3 }
+% \end{macrocode}
+% Now we append~|sp| to finish the dimension specification.
+% \begin{macrocode}
+ sp
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\dim_to_decimal_in_unit:nn}
+% \begin{macrocode}
+\cs_new:Npn \dim_to_decimal_in_unit:nn #1#2
+ {
+ \exp_after:wN \@@_chk_unit:w
+ \int_value:w \@@_eval:w #2 \@@_eval_end: ; {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_chk_unit:w}
+% The tokens after \cs{@@_chk_unit:w} shall have the following form:
+% |<number2>;{<dimexpr1>}|, where |<number2>| represents |<dimexpr2>| in
+% |sp| unit.
+% If |#1| is~|0|$_{12}$, the \enquote{unit} |<dimexpr2>| must also be zero.
+% So we throw out a \enquote{division by zero} error message at this point.
+% Otherwise, if |#1| is~|-|$_{12}$, we shall negate both |<dimexpr1>| and
+% |<dimexpr2>| for later procedures.
+% \begin{macrocode}
+\cs_new:Npn \@@_chk_unit:w #1#2;#3
+ {
+ \token_if_eq_charcode:NNTF #1 0
+ { \msg_expandable_error:nn { dim } { zero-unit } }
+ {
+ \exp_after:wN \@@_branch_unit:w
+ \int_value:w \if:w #1 - - \fi: \@@_eval:w #3 \exp_after:wN ;
+ \int_value:w \if:w #1 - - \fi: #1#2 ;
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_branch_unit:w}
+% The tokens after \cs{@@_branch_unit:w} shall have the following form:
+% |<number1>;<number2>;|, where |<number1>| represents |<dimexpr1>| in
+% |sp| unit (whose sign is taken care of) and |<number2>| represents the
+% absolute value of |<dimexpr2>| in |sp| unit (which is strictly positive).
+%
+% As explained, the formulae $(2X\pm1)\times(\frac{1}{2}\delta^{-1})$ work
+% if and only if $\delta=|<number2>|/65536>1$. This corresponds to
+% |<dimexpr2>| strictly larger than 1\,pt in absolute value.
+% In this case, we simply call \cs{@@_to_decimal_aux:w} and supply
+% $\frac{1}{2}\delta^{-1}=32768/|<number2>|$ as |<half of delta inverse>|.
+%
+% Otherwise if $|<number2>|=65536$, then |<dimexpr2>| is 1\,pt in absolute
+% value and we call \cs{dim_to_decimal:n} directly.
+%
+% Otherwise $0<|<number2>|<65536$ and we shall proceed differently.
+%
+% For unit less than 1\,pt, write $n=|<number2>|$, then $\delta=n/65536<1$.
+% The midpoint formulae are not optimal. Let's go back to the inequalities
+% $X\delta^{-1}\le N<(X+1)\delta^{-1}$. Since now $\delta<1$, the bounding
+% interval is wider than~$1$ in length. Consider the ceiling integer
+% $M=\lceil X\delta^{-1}\rceil$, then $X\delta^{-1}\le M<(X+1)\delta^{-1}$,
+% or equivalently $X\le M\delta<X+1$, and thus $\lfloor M\delta\rfloor=X$.
+% The key point here is that we \emph{don't} need to solve for~$N$;
+% in fact, any integer that can reproduce~$X$ (such as~$M$) is good enough.
+% So the algorithm goes like this: (1)~Compute rounding of $X\delta^{-1}$,
+% i.e., $M'=\lfloor X\delta^{-1}+\frac{1}{2}\rfloor$; this $M'$ could be
+% either $M$ or $M-1$. (2)~Check if $\lfloor M'\delta\rfloor=X$, i.e.,
+% whether our candidate $M'$ can reproduce~$X$. If so, then this $M'$ is
+% good enough; if not, then we add one to~$M'$.
+%
+% But when $0<n<65536$, we cannot delay the problem of overflow any more.
+% For $X\delta^{-1}=X\times65536/n$, where $X$ can go up to $2^{30}-1$ and
+% $n$ can be as small as~$1$, the result is well over $2^{31}-1$ (largest
+% integer allowed within |\numexpr|).
+% For example, |\dim_to_decimal_in_unit:nn { \maxdimen } { 1sp }|.
+% Here, all inputs are legal, so we should be able to output |1073741823|
+% \emph{without} causing arithmetic overflow.
+%
+% As a workaround, let's write $X=qn+r$ with some $q\ge0$ and $0\le r<n$.
+% Then $X\delta^{-1}=65536q+65536r/n$, and so
+% $M'=65536q+\lfloor65536r/n+\frac{1}{2}\rfloor=65536q+R'$.
+% Computing $R'$ will never overflow. If this $R'$ can reproduce~$r$, then
+% it is good enough; otherwise we add one to~$R'$. In the end, we shall
+% output $q+R'/65536$ in decimal.
+%
+% Note: $q=\lfloor X/n\rfloor=\lfloor\frac{2X-n}{2n}+\frac{1}{2}\rfloor$
+% represents the \enquote{integer} part, while $0\le R'\le65536$ represents the
+% \enquote{fractional} part. (Can $R'=65536$ really happen? Didn't investigate.)
+% \begin{macrocode}
+\cs_new:Npn \@@_branch_unit:w #1;#2;
+ {
+ \int_compare:nNnTF {#2} > { 65536 }
+ { \@@_to_decimal_aux:w #1 ; 32768 / #2 ; }
+ {
+ \int_compare:nNnTF {#2} = { 65536 }
+ { \dim_to_decimal:n { #1sp } }
+ { \@@_get_quotient:w #1 ; #2 ; }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_get_quotient:w}
+% We wish to get the quotient $q$ via rounding of $\frac{2X-n}{2n}$.
+% When $0\le X<n/2$, we have $\frac{2X-n}{2n}<0$. So, strictly speaking,
+% |\numexpr| performs its rounding as
+% $\lceil\frac{2X-n}{2n}-\frac{1}{2}\rceil$, not exactly what we want.
+% However, lucky for us, only $X=0$ makes
+% $\lceil\frac{2X-n}{2n}-\frac{1}{2}\rceil=-1\neq0$ (we want~$0$);
+% all other $0<X<n/2$ make $\lceil\frac{2X-n}{2n}-\frac{1}{2}\rceil=0=q$.
+% Thus, let's filter out $X=0$ early.
+% If $X\neq0$, we extract its sign and leave the sign to the back.
+% The sign does not participate in any calculations (also the code works
+% with positive integers only). The sign is used at the last stages when
+% we parse the decimal output.
+%
+% After \cs{@@_get_quotient:w} has done its job, either we have the
+% decimal~|0|, or we have \cs{@@_get_remainder:w} followed by
+% $q$|;|$\lvert X\rvert$|;|$n$|;<sign of X>;|.
+% \begin{macrocode}
+\cs_new:Npn \@@_get_quotient:w #1#2;#3;
+ {
+ \token_if_eq_charcode:NNTF #1 0
+ { 0 }
+ {
+ \token_if_eq_charcode:NNTF #1 -
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_get_remainder:w
+ \int_eval:n { ( 2 * #2 - #3 ) / ( 2 * #3 ) } ;
+ #2 ; #3 ; - ;
+ }
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_get_remainder:w
+ \int_eval:n { ( 2 * #1#2 - #3 ) / ( 2 * #3 ) } ;
+ #1#2 ; #3 ; ;
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_get_remainder:w}
+% \cs{@@_get_remainder:w} does not need to read the sign.
+% After finding the remainder~$r$, the number~$\lvert X\rvert$ is no longer
+% needed. We should then have \cs{@@_convert_remainder:w} followed by
+% $r$|;|$n$|;|$q$|;<sign of X>;|.
+% \begin{macrocode}
+\cs_new:Npn \@@_get_remainder:w #1;#2;#3;
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_convert_remainder:w
+ \int_eval:n { #2 - #1 * #3 } ;
+ #3 ; #1 ;
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_convert_remainder:w}
+% This is trivial. We compute $R'=\lfloor65536r/n+\frac{1}{2}\rfloor$,
+% then leave \cs{@@_test_candidate:w} followed by
+% $R'$|;|$r$|;|$n$|;|$q$|;<sign of X>;|.
+% \begin{macrocode}
+\cs_new:Npn \@@_convert_remainder:w #1;#2;
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_test_candidate:w
+ \int_eval:n { #1 * 65536 / #2 } ;
+ #1 ; #2 ;
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_test_candidate:w}
+% Now the fun part: We take $R'$, $r$ and~$n$ to test whether
+% $r=\lfloor R'\delta\rfloor$. This is done as a dimension comparison.
+% The left-hand side, $r$, is simply |r sp|. The right-hand side,
+% $\lfloor R'\delta\rfloor$, is exactly |<R' as decimal><dimen = n sp>|.
+% If the result is true, then we've found~$R'$;
+% otherwise we add one to~$R'$.
+% After this step, $r$ and~$n$ are no longer needed. We should then have
+% \cs{@@_parse_decimal:w} followed by $R'$|;|$q$|;<sign of X>;|.
+% \begin{macrocode}
+\cs_new:Npn \@@_test_candidate:w #1;#2;#3;
+ {
+ \dim_compare:nNnTF { #2sp } =
+ { \dim_to_decimal:n { #1sp } \@@_eval:w #3sp \@@_eval_end: }
+ { \@@_parse_decimal:w #1 ; }
+ {
+ \@@_parse_decimal:w \int_eval:n { #1 + 1 } ;
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_parse_decimal:w, \@@_parse_decimal_aux:w}
+% The Grand Finale: We sum $q$ and $R'/65536$ together, and negate the
+% result if necessary. These are all done expandably.
+% If $0<R'/65536<1$, the integer summation is naturally terminated at the
+% decimal point. If $R'/65536=0$ (or~$1$?), the summation is terminated
+% at the semicolon. The auxiliary function \cs{@@_parse_decimal_aux:w}
+% takes care of both cases.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_decimal:w #1;#2;#3;
+ {
+ \exp_after:wN \@@_parse_decimal_aux:w
+ \int_value:w #3 \int_eval:w #2 + \dim_to_decimal:n { #1sp } ;
+ }
+\cs_new:Npn \@@_parse_decimal_aux:w #1 ; {#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Viewing \texttt{dim} variables}
+%
+% \begin{macro}{\dim_show:N, \dim_show:c}
+% Diagnostics.
+% \begin{macrocode}
+\cs_new_eq:NN \dim_show:N \__kernel_register_show:N
+\cs_generate_variant:Nn \dim_show:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\dim_show:n}
+% Diagnostics. We don't use the \TeX{} primitive \tn{showthe} to show
+% dimension expressions: this gives a more unified output.
+% \begin{macrocode}
+\cs_new_protected:Npn \dim_show:n
+ { \__kernel_msg_show_eval:Nn \dim_eval:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\dim_log:N, \dim_log:c, \dim_log:n}
+% Diagnostics. Redirect output of \cs{dim_show:n} to the log.
+% \begin{macrocode}
+\cs_new_eq:NN \dim_log:N \__kernel_register_log:N
+\cs_new_eq:NN \dim_log:c \__kernel_register_log:c
+\cs_new_protected:Npn \dim_log:n
+ { \__kernel_msg_log_eval:Nn \dim_eval:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Constant dimensions}
+%
+% \begin{variable}{\c_zero_dim, \c_max_dim}
+% Constant dimensions.
+% \begin{macrocode}
+\dim_const:Nn \c_zero_dim { 0 pt }
+\dim_const:Nn \c_max_dim { 16383.99999 pt }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Scratch dimensions}
+%
+% \begin{variable}{\l_tmpa_dim, \l_tmpb_dim}
+% \begin{variable}{\g_tmpa_dim, \g_tmpb_dim}
+% We provide two local and two global scratch registers, maybe we
+% need more or less.
+% \begin{macrocode}
+\dim_new:N \l_tmpa_dim
+\dim_new:N \l_tmpb_dim
+\dim_new:N \g_tmpa_dim
+\dim_new:N \g_tmpb_dim
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \subsection{Creating and initialising \texttt{skip} variables}
+%
+% \begin{macrocode}
+%<@@=skip>
+% \end{macrocode}
+%
+% \begin{variable}{\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\skip_new:N, \skip_new:c}
+% Allocation of a new internal registers.
+% \begin{macrocode}
+\cs_new_protected:Npn \skip_new:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \cs:w newskip \cs_end: #1
+ }
+\cs_generate_variant:Nn \skip_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\skip_const:Nn, \skip_const:cn}
+% Contrarily to integer constants, we cannot avoid using a register,
+% even for constants. See \cs{dim_const:Nn} for why we cannot use
+% \cs{skip_gset:Nn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \skip_const:Nn #1#2
+ {
+ \skip_new:N #1
+ \tex_global:D #1 = \skip_eval:n {#2} \scan_stop:
+ }
+\cs_generate_variant:Nn \skip_const:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\skip_zero:N, \skip_zero:c}
+% \begin{macro}{\skip_gzero:N, \skip_gzero:c}
+% Reset the register to zero.
+% \begin{macrocode}
+\cs_new_eq:NN \skip_zero:N \dim_zero:N
+\cs_new_eq:NN \skip_gzero:N \dim_gzero:N
+\cs_generate_variant:Nn \skip_zero:N { c }
+\cs_generate_variant:Nn \skip_gzero:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\skip_zero_new:N, \skip_zero_new:c, \skip_gzero_new:N, \skip_gzero_new:c}
+% Create a register if needed, otherwise clear it.
+% \begin{macrocode}
+\cs_new_protected:Npn \skip_zero_new:N #1
+ { \skip_if_exist:NTF #1 { \skip_zero:N #1 } { \skip_new:N #1 } }
+\cs_new_protected:Npn \skip_gzero_new:N #1
+ { \skip_if_exist:NTF #1 { \skip_gzero:N #1 } { \skip_new:N #1 } }
+\cs_generate_variant:Nn \skip_zero_new:N { c }
+\cs_generate_variant:Nn \skip_gzero_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\skip_if_exist:N, \skip_if_exist:c}
+% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \skip_if_exist:N \cs_if_exist:N
+ { TF , T , F , p }
+\prg_new_eq_conditional:NNn \skip_if_exist:c \cs_if_exist:c
+ { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Setting \texttt{skip} variables}
+%
+% \begin{macro}{\skip_set:Nn, \skip_set:cn}
+% \begin{macro}{\skip_gset:Nn, \skip_gset:cn}
+% Much the same as for dimensions.
+% \begin{macrocode}
+\cs_new_protected:Npn \skip_set:Nn #1#2
+ { #1 = \tex_glueexpr:D #2 \scan_stop: }
+\cs_new_protected:Npn \skip_gset:Nn #1#2
+ { \tex_global:D #1 = \tex_glueexpr:D #2 \scan_stop: }
+\cs_generate_variant:Nn \skip_set:Nn { c }
+\cs_generate_variant:Nn \skip_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\skip_set_eq:NN, \skip_set_eq:cN, \skip_set_eq:Nc, \skip_set_eq:cc}
+% \begin{macro}
+% {\skip_gset_eq:NN, \skip_gset_eq:cN, \skip_gset_eq:Nc, \skip_gset_eq:cc}
+% All straightforward.
+% \begin{macrocode}
+\cs_new_protected:Npn \skip_set_eq:NN #1#2 { #1 = #2 }
+\cs_generate_variant:Nn \skip_set_eq:NN { c , Nc , cc }
+\cs_new_protected:Npn \skip_gset_eq:NN #1#2 { \tex_global:D #1 = #2 }
+\cs_generate_variant:Nn \skip_gset_eq:NN { c , Nc , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\skip_add:Nn, \skip_add:cn}
+% \begin{macro}{\skip_gadd:Nn, \skip_gadd:cn}
+% \begin{macro}{\skip_sub:Nn, \skip_sub:cn}
+% \begin{macro}{\skip_gsub:Nn, \skip_gsub:cn}
+% Using |by| here deals with the (incorrect) case |\skip123|.
+% \begin{macrocode}
+\cs_new_protected:Npn \skip_add:Nn #1#2
+ { \tex_advance:D #1 \tex_glueexpr:D #2 \scan_stop: }
+\cs_new_protected:Npn \skip_gadd:Nn #1#2
+ { \tex_global:D \tex_advance:D #1 \tex_glueexpr:D #2 \scan_stop: }
+\cs_generate_variant:Nn \skip_add:Nn { c }
+\cs_generate_variant:Nn \skip_gadd:Nn { c }
+\cs_new_protected:Npn \skip_sub:Nn #1#2
+ { \tex_advance:D #1 - \tex_glueexpr:D #2 \scan_stop: }
+\cs_new_protected:Npn \skip_gsub:Nn #1#2
+ { \tex_global:D \tex_advance:D #1 - \tex_glueexpr:D #2 \scan_stop: }
+\cs_generate_variant:Nn \skip_sub:Nn { c }
+\cs_generate_variant:Nn \skip_gsub:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Skip expression conditionals}
+%
+% \begin{macro}[pTF]{\skip_if_eq:nn}
+% Comparing skips means doing two expansions to make strings, and then
+% testing them. As a result, only equality is tested.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \skip_if_eq:nn #1#2 { p , T , F , TF }
+ {
+ \str_if_eq:eeTF { \skip_eval:n {#1} } { \skip_eval:n {#2} }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\skip_if_finite:n}
+% \begin{macro}[EXP]{\@@_if_finite:wwNw}
+% With \eTeX{}, we have an easy access to the order of infinities of
+% the stretch and shrink components of a skip. However, to access
+% both, we either need to evaluate the expression twice, or evaluate
+% it, then call an auxiliary to extract both pieces of information
+% from the result. Since we are going to need an auxiliary anyways,
+% it is quicker to make it search for the string \texttt{fil} which
+% characterizes infinite glue.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \prg_new_conditional:Npnn \skip_if_finite:n ##1 { p , T , F , TF }
+ {
+ \exp_after:wN \@@_if_finite:wwNw
+ \skip_use:N \tex_glueexpr:D ##1 ; \prg_return_false:
+ #1 ; \prg_return_true: \s_@@_stop
+ }
+ \cs_new:Npn \@@_if_finite:wwNw ##1 #1 ##2 ; ##3 ##4 \s_@@_stop {##3}
+ }
+\exp_args:No \@@_tmp:w { \tl_to_str:n { fil } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using \texttt{skip} expressions and variables}
+%
+% \begin{macro}{\skip_eval:n}
+% Evaluating a skip expression expandably.
+% \begin{macrocode}
+\cs_new:Npn \skip_eval:n #1
+ { \skip_use:N \tex_glueexpr:D #1 \scan_stop: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\skip_use:N, \skip_use:c}
+% Accessing a \meta{skip}.
+% \begin{macrocode}
+\cs_new_eq:NN \skip_use:N \dim_use:N
+\cs_new_eq:NN \skip_use:c \dim_use:c
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Inserting skips into the output}
+%
+% \begin{macro}{\skip_horizontal:N, \skip_horizontal:c, \skip_horizontal:n}
+% \begin{macro}{\skip_vertical:N, \skip_vertical:c, \skip_vertical:n}
+% Inserting skips.
+% \begin{macrocode}
+\cs_new_eq:NN \skip_horizontal:N \tex_hskip:D
+\cs_new:Npn \skip_horizontal:n #1
+ { \skip_horizontal:N \tex_glueexpr:D #1 \scan_stop: }
+\cs_new_eq:NN \skip_vertical:N \tex_vskip:D
+\cs_new:Npn \skip_vertical:n #1
+ { \skip_vertical:N \tex_glueexpr:D #1 \scan_stop: }
+\cs_generate_variant:Nn \skip_horizontal:N { c }
+\cs_generate_variant:Nn \skip_vertical:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Viewing \texttt{skip} variables}
+%
+% \begin{macro}{\skip_show:N, \skip_show:c}
+% Diagnostics.
+% \begin{macrocode}
+\cs_new_eq:NN \skip_show:N \__kernel_register_show:N
+\cs_generate_variant:Nn \skip_show:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\skip_show:n}
+% Diagnostics. We don't use the \TeX{} primitive \tn{showthe} to show
+% skip expressions: this gives a more unified output.
+% \begin{macrocode}
+\cs_new_protected:Npn \skip_show:n
+ { \__kernel_msg_show_eval:Nn \skip_eval:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\skip_log:N, \skip_log:c, \skip_log:n}
+% Diagnostics. Redirect output of \cs{skip_show:n} to the log.
+% \begin{macrocode}
+\cs_new_eq:NN \skip_log:N \__kernel_register_log:N
+\cs_new_eq:NN \skip_log:c \__kernel_register_log:c
+\cs_new_protected:Npn \skip_log:n
+ { \__kernel_msg_log_eval:Nn \skip_eval:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Constant skips}
+%
+% \begin{macro}{\c_zero_skip, \c_max_skip}
+% Skips with no rubber component are just dimensions but need to terminate
+% correctly.
+% \begin{macrocode}
+\skip_const:Nn \c_zero_skip { \c_zero_dim }
+\skip_const:Nn \c_max_skip { \c_max_dim }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Scratch skips}
+%
+% \begin{variable}{\l_tmpa_skip, \l_tmpb_skip}
+% \begin{variable}{\g_tmpa_skip, \g_tmpb_skip}
+% We provide two local and two global scratch registers, maybe we
+% need more or less.
+% \begin{macrocode}
+\skip_new:N \l_tmpa_skip
+\skip_new:N \l_tmpb_skip
+\skip_new:N \g_tmpa_skip
+\skip_new:N \g_tmpb_skip
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \subsection{Creating and initialising \texttt{muskip} variables}
+%
+% \begin{macro}{\muskip_new:N, \muskip_new:c}
+% And then we add muskips.
+% \begin{macrocode}
+\cs_new_protected:Npn \muskip_new:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \cs:w newmuskip \cs_end: #1
+ }
+\cs_generate_variant:Nn \muskip_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\muskip_const:Nn, \muskip_const:cn}
+% See \cs{skip_const:Nn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \muskip_const:Nn #1#2
+ {
+ \muskip_new:N #1
+ \tex_global:D #1 = \muskip_eval:n {#2} \scan_stop:
+ }
+\cs_generate_variant:Nn \muskip_const:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\muskip_zero:N, \muskip_zero:c}
+% \begin{macro}{\muskip_gzero:N, \muskip_gzero:c}
+% Reset the register to zero.
+% \begin{macrocode}
+\cs_new_protected:Npn \muskip_zero:N #1
+ { #1 = \c_zero_muskip }
+\cs_new_protected:Npn \muskip_gzero:N #1
+ { \tex_global:D #1 = \c_zero_muskip }
+\cs_generate_variant:Nn \muskip_zero:N { c }
+\cs_generate_variant:Nn \muskip_gzero:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \muskip_zero_new:N, \muskip_zero_new:c,
+% \muskip_gzero_new:N, \muskip_gzero_new:c
+% }
+% Create a register if needed, otherwise clear it.
+% \begin{macrocode}
+\cs_new_protected:Npn \muskip_zero_new:N #1
+ { \muskip_if_exist:NTF #1 { \muskip_zero:N #1 } { \muskip_new:N #1 } }
+\cs_new_protected:Npn \muskip_gzero_new:N #1
+ { \muskip_if_exist:NTF #1 { \muskip_gzero:N #1 } { \muskip_new:N #1 } }
+\cs_generate_variant:Nn \muskip_zero_new:N { c }
+\cs_generate_variant:Nn \muskip_gzero_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\muskip_if_exist:N, \muskip_if_exist:c}
+% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \muskip_if_exist:N \cs_if_exist:N
+ { TF , T , F , p }
+\prg_new_eq_conditional:NNn \muskip_if_exist:c \cs_if_exist:c
+ { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Setting \texttt{muskip} variables}
+%
+% \begin{macro}{\muskip_set:Nn, \muskip_set:cn}
+% \begin{macro}{\muskip_gset:Nn, \muskip_gset:cn}
+% This should be pretty familiar.
+% \begin{macrocode}
+\cs_new_protected:Npn \muskip_set:Nn #1#2
+ { #1 = \tex_muexpr:D #2 \scan_stop: }
+\cs_new_protected:Npn \muskip_gset:Nn #1#2
+ { \tex_global:D #1 = \tex_muexpr:D #2 \scan_stop: }
+\cs_generate_variant:Nn \muskip_set:Nn { c }
+\cs_generate_variant:Nn \muskip_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \muskip_set_eq:NN, \muskip_set_eq:cN,
+% \muskip_set_eq:Nc, \muskip_set_eq:cc
+% }
+% \begin{macro}
+% {
+% \muskip_gset_eq:NN, \muskip_gset_eq:cN,
+% \muskip_gset_eq:Nc, \muskip_gset_eq:cc
+% }
+% All straightforward.
+% \begin{macrocode}
+\cs_new_protected:Npn \muskip_set_eq:NN #1#2 { #1 = #2 }
+\cs_generate_variant:Nn \muskip_set_eq:NN { c , Nc , cc }
+\cs_new_protected:Npn \muskip_gset_eq:NN #1#2 { \tex_global:D #1 = #2 }
+\cs_generate_variant:Nn \muskip_gset_eq:NN { c , Nc , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\muskip_add:Nn, \muskip_add:cn}
+% \begin{macro}{\muskip_gadd:Nn, \muskip_gadd:cn}
+% \begin{macro}{\muskip_sub:Nn, \muskip_sub:cn}
+% \begin{macro}{\muskip_gsub:Nn, \muskip_gsub:cn}
+% Using |by| here deals with the (incorrect) case |\muskip123|.
+% \begin{macrocode}
+\cs_new_protected:Npn \muskip_add:Nn #1#2
+ { \tex_advance:D #1 \tex_muexpr:D #2 \scan_stop: }
+\cs_new_protected:Npn \muskip_gadd:Nn #1#2
+ { \tex_global:D \tex_advance:D #1 \tex_muexpr:D #2 \scan_stop: }
+\cs_generate_variant:Nn \muskip_add:Nn { c }
+\cs_generate_variant:Nn \muskip_gadd:Nn { c }
+\cs_new_protected:Npn \muskip_sub:Nn #1#2
+ { \tex_advance:D #1 - \tex_muexpr:D #2 \scan_stop: }
+\cs_new_protected:Npn \muskip_gsub:Nn #1#2
+ { \tex_global:D \tex_advance:D #1 - \tex_muexpr:D #2 \scan_stop: }
+\cs_generate_variant:Nn \muskip_sub:Nn { c }
+\cs_generate_variant:Nn \muskip_gsub:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using \texttt{muskip} expressions and variables}
+%
+% \begin{macro}{\muskip_eval:n}
+% Evaluating a muskip expression expandably.
+% \begin{macrocode}
+\cs_new:Npn \muskip_eval:n #1
+ { \muskip_use:N \tex_muexpr:D #1 \scan_stop: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\muskip_use:N, \muskip_use:c}
+% Accessing a \meta{muskip}.
+% \begin{macrocode}
+\cs_new_eq:NN \muskip_use:N \dim_use:N
+\cs_new_eq:NN \muskip_use:c \dim_use:c
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Viewing \texttt{muskip} variables}
+%
+% \begin{macro}{\muskip_show:N, \muskip_show:c}
+% Diagnostics.
+% \begin{macrocode}
+\cs_new_eq:NN \muskip_show:N \__kernel_register_show:N
+\cs_generate_variant:Nn \muskip_show:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\muskip_show:n}
+% Diagnostics. We don't use the \TeX{} primitive \tn{showthe} to show
+% muskip expressions: this gives a more unified output.
+% \begin{macrocode}
+\cs_new_protected:Npn \muskip_show:n
+ { \__kernel_msg_show_eval:Nn \muskip_eval:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\muskip_log:N, \muskip_log:c, \muskip_log:n}
+% Diagnostics. Redirect output of \cs{muskip_show:n} to the log.
+% \begin{macrocode}
+\cs_new_eq:NN \muskip_log:N \__kernel_register_log:N
+\cs_new_eq:NN \muskip_log:c \__kernel_register_log:c
+\cs_new_protected:Npn \muskip_log:n
+ { \__kernel_msg_log_eval:Nn \muskip_eval:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Constant muskips}
+%
+% \begin{macro}{\c_zero_muskip}
+% \begin{macro}{\c_max_muskip}
+% Constant muskips given by their value.
+% \begin{macrocode}
+\muskip_const:Nn \c_zero_muskip { 0 mu }
+\muskip_const:Nn \c_max_muskip { 16383.99999 mu }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Scratch muskips}
+%
+% \begin{variable}{\l_tmpa_muskip, \l_tmpb_muskip}
+% \begin{variable}{\g_tmpa_muskip, \g_tmpb_muskip}
+% We provide two local and two global scratch registers, maybe we
+% need more or less.
+% \begin{macrocode}
+\muskip_new:N \l_tmpa_muskip
+\muskip_new:N \l_tmpb_muskip
+\muskip_new:N \g_tmpa_muskip
+\muskip_new:N \g_tmpb_muskip
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3sort.dtx b/macros/latex-dev/required/l3kernel/l3sort.dtx
new file mode 100644
index 0000000000..81a025b474
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3sort.dtx
@@ -0,0 +1,1097 @@
+% \iffalse
+%
+%% File l3sort.dtx
+%
+% Copyright (C) 2012-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3sort} module\\ Sorting functions^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{Controlling sorting}
+%
+% \label{sec:l3sort:mech}
+%
+% \LaTeX3 comes with a facility to sort list variables (sequences,
+% token lists, or comma-lists) according to some user-defined
+% comparison. For instance,
+% \begin{verbatim}
+% \clist_set:Nn \l_foo_clist { 3 , 01 , -2 , 5 , +1 }
+% \clist_sort:Nn \l_foo_clist
+% {
+% \int_compare:nNnTF { #1 } > { #2 }
+% { \sort_return_swapped: }
+% { \sort_return_same: }
+% }
+% \end{verbatim}
+% results in \cs[no-index]{l_foo_clist} holding the values
+% |{ -2 , 01 , +1 , 3 , 5 }| sorted in non-decreasing order.
+%
+% The code defining the comparison should call
+% \cs{sort_return_swapped:} if the two items given as |#1|
+% and |#2| are not in the correct order, and otherwise it
+% should call \cs{sort_return_same:} to indicate that
+% the order of this pair of items should not be changed.
+%
+% For instance, a \meta{comparison code} consisting only
+% of \cs{sort_return_same:} with no test yields a trivial
+% sort: the final order is identical to the original order.
+% Conversely, using a \meta{comparison code} consisting only
+% of \cs{sort_return_swapped:} reverses the list (in a fairly
+% inefficient way).
+%
+% \begin{texnote}
+% The current implementation is limited to sorting approximately
+% $20000$ items ($40000$ in \LuaTeX{}), depending on what other
+% packages are loaded.
+%
+% Internally, the code from \pkg{l3sort} stores items in \tn{toks}
+% registers allocated locally. Thus, the \meta{comparison code}
+% should not call \tn{newtoks} or other commands that allocate new
+% \tn{toks} registers. On the other hand, altering the value of a
+% previously allocated \tn{toks} register is not a problem.
+% \end{texnote}
+%
+% \begin{function}[added = 2017-02-06]{\sort_return_same:, \sort_return_swapped:}
+% \begin{syntax}
+% \cs{seq_sort:Nn} \meta{seq~var}
+% ~~|{| \ldots{} \cs{sort_return_same:} or \cs{sort_return_swapped:} \ldots{} |}|
+% \end{syntax}
+% Indicates whether to keep the order or swap the order of two items
+% that are compared in the sorting code. Only one of the
+% \cs[no-index]{sort_return_\ldots{}} functions should be used by the
+% code, according to the results of some tests on the items |#1| and
+% |#2| to be compared.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3sort} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=sort>
+% \end{macrocode}
+%
+% \subsection{Variables}
+%
+% \begin{variable}{\g_@@_internal_seq, \g_@@_internal_tl}
+% Sorting happens in a group; the result is stored in those global
+% variables before being copied outside the group to the proper
+% places. For seq and tl this is more efficient than using \cs{use:e}
+% (or some \cs{exp_args:NNNe}) to smuggle the definition outside the
+% group since \TeX{} does not need to re-read tokens. For clist we
+% don't gain anything since the result is converted from seq to clist
+% anyways.
+% \begin{macrocode}
+\seq_new:N \g_@@_internal_seq
+\tl_new:N \g_@@_internal_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \l_@@_length_int, \l_@@_min_int, \l_@@_top_int, \l_@@_max_int,
+% \l_@@_true_max_int
+% }
+% The sequence has \cs{l_@@_length_int} items and is stored from
+% \cs{l_@@_min_int} to $\cs{l_@@_top_int}-1$. While reading the
+% sequence in memory, we check that \cs{l_@@_top_int} remains at most
+% \cs{l_@@_max_int}, precomputed by \cs{@@_compute_range:}. That
+% bound is such that the merge sort only uses \tn{toks} registers
+% less than \cs{l_@@_true_max_int}, namely those that have not been
+% allocated for use in other code: the user's comparison code could
+% alter these.
+% \begin{macrocode}
+\int_new:N \l_@@_length_int
+\int_new:N \l_@@_min_int
+\int_new:N \l_@@_top_int
+\int_new:N \l_@@_max_int
+\int_new:N \l_@@_true_max_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_block_int}
+% Merge sort is done in several passes. In each pass, blocks of size
+% \cs{l_@@_block_int} are merged in pairs. The block size starts
+% at $1$, and, for a length in the range $[2^k+1,2^{k+1}]$, reaches
+% $2^{k}$ in the last pass.
+% \begin{macrocode}
+\int_new:N \l_@@_block_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_begin_int}
+% \begin{variable}{\l_@@_end_int}
+% When merging two blocks, \cs{l_@@_begin_int} marks the lowest
+% index in the two blocks, and \cs{l_@@_end_int} marks the
+% highest index, plus $1$.
+% \begin{macrocode}
+\int_new:N \l_@@_begin_int
+\int_new:N \l_@@_end_int
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_A_int}
+% \begin{variable}{\l_@@_B_int}
+% \begin{variable}{\l_@@_C_int}
+% When merging two blocks (whose end-points are \texttt{beg}
+% and \texttt{end}), $A$ starts from the high end of the low
+% block, and decreases until reaching \texttt{beg}. The index
+% $B$ starts from the top of the range and marks the register
+% in which a sorted item should be put. Finally, $C$ points
+% to the copy of the high block in the interval of registers
+% starting at \cs{l_@@_length_int}, upwards. $C$ starts
+% from the upper limit of that range.
+% \begin{macrocode}
+\int_new:N \l_@@_A_int
+\int_new:N \l_@@_B_int
+\int_new:N \l_@@_C_int
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\s_@@_mark,\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Finding available \tn{toks} registers}
+%
+% \begin{macro}{\@@_shrink_range:}
+% \begin{macro}{\@@_shrink_range_loop:}
+% After \cs{@@_compute_range:} (defined below) determines that
+% \tn{toks} registers between \cs{l_@@_min_int} (included) and
+% \cs{l_@@_true_max_int} (excluded) have not yet been assigned,
+% \cs{@@_shrink_range:} computes \cs{l_@@_max_int} to reflect the need
+% for a buffer when merging blocks in the merge sort. Given
+% $2^{n}\leq A\leq 2^{n}+2^{n-1}$ registers we can sort $\lfloor
+% A/2\rfloor+2^{n-2}$ items while if we have $2^{n}+2^{n-1}\leq A\leq
+% 2^{n+1}$ registers we can sort $A-2^{n-1}$ items. We first find out
+% a power $2^{n}$ such that $2^{n}\leq A\leq 2^{n+1}$ by repeatedly
+% halving \cs{l_@@_block_int}, starting at $2^{15}$ or $2^{14}$ namely
+% half the total number of registers, then we use the formulas and set
+% \cs{l_@@_max_int}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_shrink_range:
+ {
+ \int_set:Nn \l_@@_A_int
+ { \l_@@_true_max_int - \l_@@_min_int + 1 }
+ \int_set:Nn \l_@@_block_int { \c_max_register_int / 2 }
+ \@@_shrink_range_loop:
+ \int_set:Nn \l_@@_max_int
+ {
+ \int_compare:nNnTF
+ { \l_@@_block_int * 3 / 2 } > \l_@@_A_int
+ {
+ \l_@@_min_int
+ + ( \l_@@_A_int - 1 ) / 2
+ + \l_@@_block_int / 4
+ - 1
+ }
+ { \l_@@_true_max_int - \l_@@_block_int / 2 }
+ }
+ }
+\cs_new_protected:Npn \@@_shrink_range_loop:
+ {
+ \if_int_compare:w \l_@@_A_int < \l_@@_block_int
+ \tex_divide:D \l_@@_block_int 2 \exp_stop_f:
+ \exp_after:wN \@@_shrink_range_loop:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_compute_range:, \@@_redefine_compute_range:}
+% \begin{variable}{\c_@@_max_length_int}
+% First find out what \tn{toks} have not yet been assigned. There are
+% many cases. In \LaTeXe{} with no package, available \tn{toks} range
+% from $\tn{count}15+1$ to \cs{c_max_register_int} included (this was
+% not altered despite the 2015 changes). When \tn{loctoks} is
+% defined, namely in plain (e)\TeX{}, or when the package \pkg{etex}
+% is loaded in \LaTeXe{}, redefine \cs{@@_compute_range:} to use the
+% range $\tn{count}265$ to $\tn{count}275-1$. The \pkg{elocalloc}
+% package also defines \tn{loctoks} but uses yet another number for
+% the upper bound, namely \cs{e@alloc@top} (minus one). We must check
+% for \tn{loctoks} every time a sorting function is called, as
+% \pkg{etex} or \pkg{elocalloc} could be loaded.
+%
+% In \ConTeXt{} MkIV the range is from
+% $|\c_syst_last_allocated_toks|+1$ to \cs{c_max_register_int}, and in
+% MkII it is from $|\lastallocatedtoks|+1$ to \cs{c_max_register_int}.
+% In all these cases, call \cs{@@_shrink_range:}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compute_range:
+ {
+ \int_set:Nn \l_@@_min_int { \tex_count:D 15 + 1 }
+ \int_set:Nn \l_@@_true_max_int { \c_max_register_int + 1 }
+ \@@_shrink_range:
+ \if_meaning:w \loctoks \tex_undefined:D \else:
+ \if_meaning:w \loctoks \scan_stop: \else:
+ \@@_redefine_compute_range:
+ \@@_compute_range:
+ \fi:
+ \fi:
+ }
+\cs_new_protected:Npn \@@_redefine_compute_range:
+ {
+ \cs_if_exist:cTF { ver@elocalloc.sty }
+ {
+ \cs_gset_protected:Npn \@@_compute_range:
+ {
+ \int_set:Nn \l_@@_min_int { \tex_count:D 265 }
+ \int_set_eq:NN \l_@@_true_max_int \e@alloc@top
+ \@@_shrink_range:
+ }
+ }
+ {
+ \cs_gset_protected:Npn \@@_compute_range:
+ {
+ \int_set:Nn \l_@@_min_int { \tex_count:D 265 }
+ \int_set:Nn \l_@@_true_max_int { \tex_count:D 275 }
+ \@@_shrink_range:
+ }
+ }
+ }
+\cs_if_exist:NT \loctoks { \@@_redefine_compute_range: }
+\tl_map_inline:nn { \lastallocatedtoks \c_syst_last_allocated_toks }
+ {
+ \cs_if_exist:NT #1
+ {
+ \cs_gset_protected:Npn \@@_compute_range:
+ {
+ \int_set:Nn \l_@@_min_int { #1 + 1 }
+ \int_set:Nn \l_@@_true_max_int { \c_max_register_int + 1 }
+ \@@_shrink_range:
+ }
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \subsection{Protected user commands}
+%
+% \begin{macro}{\@@_main:NNNn}
+% Sorting happens in three steps. First store items in \tn{toks}
+% registers ranging from \cs{l_@@_min_int} to $\cs{l_@@_top_int}-1$,
+% while checking that the list is not too long. If we reach the
+% maximum length, that's an error; exit the group. Secondly, sort the
+% array of \tn{toks} registers, using the user-defined sorting
+% function: \cs{@@_level:} calls \cs{@@_compare:nn} as needed.
+% Finally, unpack the \tn{toks} registers (now sorted) into the target
+% tl, or into \cs{g_@@_internal_seq} for seq and clist. This is done
+% by \cs{@@_seq:NNNNn} and \cs{@@_tl:NNn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_main:NNNn #1#2#3#4
+ {
+ \@@_disable_toksdef:
+ \@@_compute_range:
+ \int_set_eq:NN \l_@@_top_int \l_@@_min_int
+ #1 #3
+ {
+ \if_int_compare:w \l_@@_top_int = \l_@@_max_int
+ \@@_too_long_error:NNw #2 #3
+ \fi:
+ \tex_toks:D \l_@@_top_int {##1}
+ \int_incr:N \l_@@_top_int
+ }
+ \int_set:Nn \l_@@_length_int
+ { \l_@@_top_int - \l_@@_min_int }
+ \cs_set:Npn \@@_compare:nn ##1 ##2 {#4}
+ \int_set:Nn \l_@@_block_int { 1 }
+ \@@_level:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_sort:Nn, \tl_sort:cn, \tl_gsort:Nn, \tl_gsort:cn}
+% \begin{macro}{\@@_tl:NNn}
+% \begin{macro}[EXP]{\@@_tl_toks:w}
+% Call the main sorting function then unpack \tn{toks} registers
+% outside the group into the target token list. The unpacking is done
+% by \cs{@@_tl_toks:w}; registers are numbered from \cs{l_@@_min_int}
+% to $\cs{l_@@_top_int}-1$. For expansion behaviour we need a couple
+% of primitives. The \cs{tl_gclear:N} reduces memory usage. The
+% \cs{prg_break_point:} is used by \cs{@@_main:NNNn} when the list is
+% too long.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_sort:Nn { \@@_tl:NNn \tl_set_eq:NN }
+\cs_generate_variant:Nn \tl_sort:Nn { c }
+\cs_new_protected:Npn \tl_gsort:Nn { \@@_tl:NNn \tl_gset_eq:NN }
+\cs_generate_variant:Nn \tl_gsort:Nn { c }
+\cs_new_protected:Npn \@@_tl:NNn #1#2#3
+ {
+ \group_begin:
+ \@@_main:NNNn \tl_map_inline:Nn \tl_map_break:n #2 {#3}
+ \__kernel_tl_gset:Nx \g_@@_internal_tl
+ { \@@_tl_toks:w \l_@@_min_int ; }
+ \group_end:
+ #1 #2 \g_@@_internal_tl
+ \tl_gclear:N \g_@@_internal_tl
+ \prg_break_point:
+ }
+\cs_new:Npn \@@_tl_toks:w #1 ;
+ {
+ \if_int_compare:w #1 < \l_@@_top_int
+ { \tex_the:D \tex_toks:D #1 }
+ \exp_after:wN \@@_tl_toks:w
+ \int_value:w \int_eval:n { #1 + 1 } \exp_after:wN ;
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_sort:Nn, \seq_sort:cn, \seq_gsort:Nn, \seq_gsort:cn}
+% \begin{macro}{\clist_sort:Nn, \clist_sort:cn, \clist_gsort:Nn, \clist_gsort:cn}
+% \begin{macro}{\@@_seq:NNNNn}
+% Use the same general framework for seq and clist. Apply the general
+% sorting code, then unpack \tn{toks} into \cs{g_@@_internal_seq}.
+% Outside the group copy or convert (for clist) the data to the target
+% variable. The \cs{seq_gclear:N} reduces memory usage. The
+% \cs{prg_break_point:} is used by \cs{@@_main:NNNn} when the list is
+% too long.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_sort:Nn
+ { \@@_seq:NNNNn \seq_map_inline:Nn \seq_map_break:n \seq_set_eq:NN }
+\cs_generate_variant:Nn \seq_sort:Nn { c }
+\cs_new_protected:Npn \seq_gsort:Nn
+ { \@@_seq:NNNNn \seq_map_inline:Nn \seq_map_break:n \seq_gset_eq:NN }
+\cs_generate_variant:Nn \seq_gsort:Nn { c }
+\cs_new_protected:Npn \clist_sort:Nn
+ {
+ \@@_seq:NNNNn \clist_map_inline:Nn \clist_map_break:n
+ \clist_set_from_seq:NN
+ }
+\cs_generate_variant:Nn \clist_sort:Nn { c }
+\cs_new_protected:Npn \clist_gsort:Nn
+ {
+ \@@_seq:NNNNn \clist_map_inline:Nn \clist_map_break:n
+ \clist_gset_from_seq:NN
+ }
+\cs_generate_variant:Nn \clist_gsort:Nn { c }
+\cs_new_protected:Npn \@@_seq:NNNNn #1#2#3#4#5
+ {
+ \group_begin:
+ \@@_main:NNNn #1 #2 #4 {#5}
+ \seq_gclear:N \g_@@_internal_seq
+ \int_step_inline:nnn
+ \l_@@_min_int { \l_@@_top_int - 1 }
+ {
+ \seq_gput_right:Ne \g_@@_internal_seq
+ { \tex_the:D \tex_toks:D ##1 }
+ }
+ \group_end:
+ #3 #4 \g_@@_internal_seq
+ \seq_gclear:N \g_@@_internal_seq
+ \prg_break_point:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Merge sort}
+%
+% \begin{macro}{\@@_level:}
+% This function is called once blocks of size \cs{l_@@_block_int}
+% (initially $1$) are each sorted. If the whole list fits in one
+% block, then we are done (this also takes care of the case of an
+% empty list or a list with one item). Otherwise, go through pairs
+% of blocks starting from $0$, then double the block size, and repeat.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_level:
+ {
+ \if_int_compare:w \l_@@_block_int < \l_@@_length_int
+ \l_@@_end_int \l_@@_min_int
+ \@@_merge_blocks:
+ \tex_advance:D \l_@@_block_int \l_@@_block_int
+ \exp_after:wN \@@_level:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_merge_blocks:}
+% This function is called to merge a pair of blocks, starting at
+% the last value of \cs{l_@@_end_int} (end-point of the previous
+% pair of blocks). If shifting by one block to the right we reach
+% the end of the list, then this pass has ended: the end of the
+% list is sorted already. Otherwise, store the result of that shift in $A$,
+% which indexes the first block starting from the top end.
+% Then locate the end-point (maximum) of the second block: shift
+% \texttt{end} upwards by one more block, but keeping it
+% $\leq\texttt{top}$. Copy this upper block of \tn{toks}
+% registers in registers above \texttt{length}, indexed by $C$:
+% this is covered by \cs{@@_copy_block:}. Once this is done we
+% are ready to do the actual merger using \cs{@@_merge_blocks_aux:},
+% after shifting $A$, $B$ and $C$ so that they point to the largest
+% index in their respective ranges rather than pointing just beyond
+% those ranges. Of course, once that pair of blocks is merged,
+% move on to the next pair.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_merge_blocks:
+ {
+ \l_@@_begin_int \l_@@_end_int
+ \tex_advance:D \l_@@_end_int \l_@@_block_int
+ \if_int_compare:w \l_@@_end_int < \l_@@_top_int
+ \l_@@_A_int \l_@@_end_int
+ \tex_advance:D \l_@@_end_int \l_@@_block_int
+ \if_int_compare:w \l_@@_end_int > \l_@@_top_int
+ \l_@@_end_int \l_@@_top_int
+ \fi:
+ \l_@@_B_int \l_@@_A_int
+ \l_@@_C_int \l_@@_top_int
+ \@@_copy_block:
+ \int_decr:N \l_@@_A_int
+ \int_decr:N \l_@@_B_int
+ \int_decr:N \l_@@_C_int
+ \exp_after:wN \@@_merge_blocks_aux:
+ \exp_after:wN \@@_merge_blocks:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_copy_block:}
+% We wish to store a copy of the \enquote{upper} block of
+% \tn{toks} registers, ranging between the initial value of
+% \cs{l_@@_B_int} (included) and \cs{l_@@_end_int}
+% (excluded) into a new range starting at the initial value
+% of \cs{l_@@_C_int}, namely \cs{l_@@_top_int}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_copy_block:
+ {
+ \tex_toks:D \l_@@_C_int \tex_toks:D \l_@@_B_int
+ \int_incr:N \l_@@_C_int
+ \int_incr:N \l_@@_B_int
+ \if_int_compare:w \l_@@_B_int = \l_@@_end_int
+ \use_i:nn
+ \fi:
+ \@@_copy_block:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_merge_blocks_aux:}
+% At this stage, the first block starts at \cs{l_@@_begin_int},
+% and ends at \cs{l_@@_A_int}, and the second block starts at
+% \cs{l_@@_top_int} and ends at \cs{l_@@_C_int}. The result
+% of the merger is stored at positions indexed by \cs{l_@@_B_int},
+% which starts at $\cs{l_@@_end_int}-1$ and decreases down to
+% \cs{l_@@_begin_int}, covering the full range of the two blocks.
+% In other words, we are building the merger starting with the
+% largest values.
+% The comparison function is defined to return either
+% \texttt{swapped} or \texttt{same}. Of course, this
+% means the arguments need to be given in the order they
+% appear originally in the list.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_merge_blocks_aux:
+ {
+ \exp_after:wN \@@_compare:nn \exp_after:wN
+ { \tex_the:D \tex_toks:D \exp_after:wN \l_@@_A_int \exp_after:wN }
+ \exp_after:wN { \tex_the:D \tex_toks:D \l_@@_C_int }
+ \prg_do_nothing:
+ \@@_return_mark:w
+ \@@_return_mark:w
+ \s_@@_mark
+ \@@_return_none_error:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\sort_return_same:, \sort_return_swapped:}
+% \begin{macro}{\@@_return_mark:w}
+% \begin{macro}{\@@_return_none_error:, \@@_return_two_error:}
+% Each comparison should call \cs{sort_return_same:} or
+% \cs{sort_return_swapped:} exactly once. If neither is called,
+% \cs{@@_return_none_error:} is called, since the \texttt{return_mark}
+% removes tokens until \cs{s_@@_mark}. If one is called, the
+% \texttt{return_mark} auxiliary removes everything except
+% \cs{@@_return_same:w} (or its \texttt{swapped} analogue) followed by
+% \cs{@@_return_none_error:}. Finally if two or more are called,
+% \cs{@@_return_two_error:} ends up before any \cs{@@_return_mark:w},
+% so that it produces an error.
+% \begin{macrocode}
+\cs_new_protected:Npn \sort_return_same:
+ #1 \@@_return_mark:w #2 \s_@@_mark
+ {
+ #1
+ #2
+ \@@_return_two_error:
+ \@@_return_mark:w
+ \s_@@_mark
+ \@@_return_same:w
+ }
+\cs_new_protected:Npn \sort_return_swapped:
+ #1 \@@_return_mark:w #2 \s_@@_mark
+ {
+ #1
+ #2
+ \@@_return_two_error:
+ \@@_return_mark:w
+ \s_@@_mark
+ \@@_return_swapped:w
+ }
+\cs_new_protected:Npn \@@_return_mark:w #1 \s_@@_mark { }
+\cs_new_protected:Npn \@@_return_none_error:
+ {
+ \msg_error:nnee { sort } { return-none }
+ { \tex_the:D \tex_toks:D \l_@@_A_int }
+ { \tex_the:D \tex_toks:D \l_@@_C_int }
+ \@@_return_same:w \@@_return_none_error:
+ }
+\cs_new_protected:Npn \@@_return_two_error:
+ {
+ \msg_error:nnee { sort } { return-two }
+ { \tex_the:D \tex_toks:D \l_@@_A_int }
+ { \tex_the:D \tex_toks:D \l_@@_C_int }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_return_same:w}
+% If the comparison function returns \texttt{same},
+% then the second argument fed to \cs{@@_compare:nn}
+% should remain to the right of the other one. Since
+% we build the merger starting from the right, we copy
+% that \tn{toks} register into the allotted range, then
+% shift the pointers $B$ and $C$, and go on to do one
+% more step in the merger, unless the second block has
+% been exhausted: then the remainder of the first block
+% is already in the correct registers and we are done
+% with merging those two blocks.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_return_same:w #1 \@@_return_none_error:
+ {
+ \tex_toks:D \l_@@_B_int \tex_toks:D \l_@@_C_int
+ \int_decr:N \l_@@_B_int
+ \int_decr:N \l_@@_C_int
+ \if_int_compare:w \l_@@_C_int < \l_@@_top_int
+ \use_i:nn
+ \fi:
+ \@@_merge_blocks_aux:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_return_swapped:w}
+% If the comparison function returns \texttt{swapped},
+% then the next item to add to the merger is the first
+% argument, contents of the \tn{toks} register $A$.
+% Then shift the pointers $A$ and $B$ to the left, and
+% go for one more step for the merger, unless the left
+% block was exhausted ($A$ goes below the threshold).
+% In that case, all remaining \tn{toks} registers in
+% the second block, indexed by $C$, are copied
+% to the merger by \cs{@@_merge_blocks_end:}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_return_swapped:w #1 \@@_return_none_error:
+ {
+ \tex_toks:D \l_@@_B_int \tex_toks:D \l_@@_A_int
+ \int_decr:N \l_@@_B_int
+ \int_decr:N \l_@@_A_int
+ \if_int_compare:w \l_@@_A_int < \l_@@_begin_int
+ \@@_merge_blocks_end: \use_i:nn
+ \fi:
+ \@@_merge_blocks_aux:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_merge_blocks_end:}
+% This function's task is to copy the \tn{toks} registers
+% in the block indexed by $C$ to the merger indexed by $B$.
+% The end can equally be detected by checking when $B$ reaches
+% the threshold \texttt{begin}, or when $C$ reaches
+% \texttt{top}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_merge_blocks_end:
+ {
+ \tex_toks:D \l_@@_B_int \tex_toks:D \l_@@_C_int
+ \int_decr:N \l_@@_B_int
+ \int_decr:N \l_@@_C_int
+ \if_int_compare:w \l_@@_B_int < \l_@@_begin_int
+ \use_i:nn
+ \fi:
+ \@@_merge_blocks_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Expandable sorting}
+%
+% Sorting expandably is very different from sorting and assigning to a
+% variable. Since tokens cannot be stored, they must remain in the
+% input stream, and be read through at every step. It is thus
+% necessarily much slower (at best $O(n^2\ln n)$) than non-expandable
+% sorting functions ($O(n\ln n)$).
+%
+% A prototypical version of expandable quicksort is as follows. If the
+% argument has no item, return nothing, otherwise partition, using the
+% first item as a pivot (argument |#4| of \cs{@@:nnNnn}). The
+% arguments of \cs{@@:nnNnn} are 1.~items less than |#4|, 2.~items
+% greater or equal to |#4|, 3.~comparison, 4.~pivot, 5.~next item to
+% test. If |#5| is the tail of the list, call \cs{tl_sort:nN} on |#1|
+% and on |#2|, placing |#4| in between; |\use:ff| expands the parts to
+% make \cs{tl_sort:nN} \texttt{f}-expandable. Otherwise, compare |#4|
+% and |#5| using |#3|. If they are ordered, place |#5| amongst the
+% \enquote{greater} items, otherwise amongst the \enquote{lesser} items,
+% and continue partitioning.
+% \begin{verbatim}
+% \cs_new:Npn \tl_sort:nN #1#2
+% {
+% \tl_if_blank:nF {#1}
+% {
+% \__sort:nnNnn { } { } #2
+% #1 \q__sort_recursion_tail \q__sort_recursion_stop
+% }
+% }
+% \cs_new:Npn \__sort:nnNnn #1#2#3#4#5
+% {
+% \quark_if_recursion_tail_stop_do:nn {#5}
+% { \use:ff { \tl_sort:nN {#1} #3 {#4} } { \tl_sort:nN {#2} #3 } }
+% #3 {#4} {#5}
+% { \__sort:nnNnn {#1} { #2 {#5} } #3 {#4} }
+% { \__sort:nnNnn { #1 {#5} } {#2} #3 {#4} }
+% }
+% \cs_generate_variant:Nn \use:nn { ff }
+% \end{verbatim}
+% There are quite a few optimizations available here: the code below is
+% less legible, but more than twice as fast.
+%
+% In the simple version of the code, \cs{@@:nnNnn} is called
+% \(O(n\ln n)\) times on average (the number of comparisons required by
+% the quicksort algorithm). Hence most of our focus is on
+% optimizing that function.
+%
+% The first speed up is to avoid testing for the end of the list at
+% every call to \cs{@@:nnNnn}. For this, the list is prepared by
+% changing each \meta{item} of the original token list into
+% \meta{command} \Arg{item}, just like sequences are stored. We arrange
+% things such that the \meta{command} is the \meta{conditional} provided
+% by the user: the loop over the \meta{prepared tokens} then looks like
+% \begin{quote}
+% \ttfamily
+% \cs{cs_new:Npn}~\cs{@@_loop:wNn}~\ldots{}~|#6#7|\\
+% ~~|{|\\
+% ~~~~|#6|~\Arg{pivot}~|{#7}|~\meta{loop big}~\meta{loop small}\\
+% ~~~~~~\meta{extra arguments}\\
+% ~~|}|\\
+% \cs{@@_loop:wNn}~\ldots{}~\meta{prepared tokens}\\
+% ~~\meta{end-loop}~|{}|~\cs{s_@@_stop}
+% \end{quote}
+% In this example, which matches the structure of
+% \cs{@@_quick_split_i:NnnnnNn} and a few other functions below, the
+% \cs{@@_loop:wNn} auxiliary normally receives the user's
+% \meta{conditional} as~|#6| and an \meta{item} as~|#7|. This is
+% compared to the \meta{pivot} (the argument~|#5|, not shown here), and
+% the \meta{conditional} leaves the \meta{loop big} or \meta{loop small}
+% auxiliary, which both have the same form as \cs{@@_loop:wNn},
+% receiving the next pair \meta{conditional} \Arg{item} as |#6|
+% and~|#7|. At the end, |#6| is the \meta{end-loop} function, which
+% terminates the loop.
+%
+% The second speed up is to minimize the duplicated tokens between the
+% \texttt{true} and \texttt{false} branches of the conditional. For
+% this, we introduce two versions of \cs{@@:nnNnn}, which receive
+% the new item as~|#1| and place it either into the list~|#2| of items
+% less than the pivot~|#4| or into the list~|#3| of items greater or
+% equal to the pivot.
+% \begin{verbatim}
+% \cs_new:Npn \__sort_i:nnnnNn #1#2#3#4#5#6
+% {
+% #5 {#4} {#6} \__sort_ii:nnnnNn \__sort_i:nnnnNn
+% {#6} { #2 {#1} } {#3} {#4}
+% }
+% \cs_new:Npn \__sort_ii:nnnnNn #1#2#3#4#5#6
+% {
+% #5 {#4} {#6} \__sort_ii:nnnnNn \__sort_i:nnnnNn
+% {#6} {#2} { #3 {#1} } {#4}
+% }
+% \end{verbatim}
+% Note that the two functions have the form of \cs{@@_loop:wNn} above,
+% receiving as~|#5| the conditional or a function to end the loop. In
+% fact, the lists~|#2| and~|#3| must be made of pairs \meta{conditional}
+% \Arg{item}, so we have to replace~|{#6}| above by |{|~|#5|~|{#6}|~|}|,
+% and |{#1}|~by~|#1|. The actual functions have one more argument, so
+% all argument numbers are shifted compared to this code.
+%
+% The third speed up is to avoid |\use:ff| using a continuation-passing
+% style: \cs{@@_quick_split:NnNn} expects a list followed by
+% \cs{s_@@_mark} \Arg{code}, and expands to \meta{code} \meta{sorted list}.
+% Sorting the two parts of the list around the pivot is done with
+% \begin{quote}
+% \ttfamily
+% \cs{@@_quick_split:NnNn} |#2| \ldots{} \cs{s_@@_mark}\\
+% ~~|{|\\
+% ~~~~\cs{@@_quick_split:NnNn} |#1| \ldots{} \cs{s_@@_mark} \Arg{code}\\
+% ~~~~\Arg{pivot}\\
+% ~~|}|
+% \end{quote}
+% Items which are larger than the \meta{pivot} are sorted, then placed
+% after code that sorts the smaller items, and after the (braced)
+% \meta{pivot}.
+%
+% The fourth speed up is avoid the recursive call to \cs{tl_sort:nN}
+% with an empty first argument. For this, we introduce functions
+% similar to the \cs{@@_i:nnnnNn} of the last example, but aware of
+% whether the list of \meta{conditional} \Arg{item} read so far that are
+% less than the pivot, and the list of those greater or equal, are empty
+% or not: see \cs{@@_quick_split:NnNn} and functions defined below.
+% Knowing whether the lists are empty or not is useless if we do not use
+% distinct ending codes as appropriate. The splitting auxiliaries
+% communicate to the \meta{end-loop} function (that is initially placed
+% after the ``prepared'' list) by placing a specific ending function,
+% ignored when looping, but useful at the end. In fact, the
+% \meta{end-loop} function does nothing but place the appropriate ending
+% function in front of all its arguments. The ending functions take
+% care of sorting non-empty sublists, placing the pivot in between, and
+% the continuation before.
+%
+% The final change in fact slows down the code a little, but is required
+% to avoid memory issues: schematically, when \TeX{} encounters
+% \begin{verbatim}
+% \use:n { \use:n { \use:n { ... } ... } ... }
+% \end{verbatim}
+% the argument of the first \cs{use:n} is not completely read by the
+% second \cs{use:n}, hence must remain in memory; then the argument of
+% the second \cs{use:n} is not completely read when grabbing the
+% argument of the third \cs{use:n}, hence must remain in memory, and so
+% on. The memory consumption grows quadratically with the number of
+% nested \cs{use:n}. In practice, this means that we must read
+% everything until a trailing \cs{s_@@_stop} once in a while, otherwise
+% sorting lists of more than a few thousand items would exhaust a
+% typical \TeX{}'s memory.
+%
+% \begin{macro}[EXP]{\tl_sort:nN}
+% \begin{macro}[EXP]
+% {
+% \@@_quick_prepare:Nnnn,
+% \@@_quick_prepare_end:NNNnw,
+% \@@_quick_cleanup:w
+% }
+% The code within the \cs{exp_not:f} sorts the list, leaving in most
+% cases a leading \cs{exp_not:f}, which stops the expansion, letting
+% the result be return within \cs{exp_not:n}. We filter out the case
+% of a list with no item, which would otherwise cause problems. Then
+% prepare the token list~|#1| by inserting the conditional~|#2| before
+% each item. The \texttt{prepare} auxiliary receives the conditional
+% as~|#1|, the prepared token list so far as~|#2|, the next prepared
+% item as~|#3|, and the item after that as~|#4|. The loop ends
+% when~|#4| contains \cs{prg_break_point:}, then the
+% \texttt{prepare_end} auxiliary finds the prepared token list
+% as~|#4|. The scene is then set up for \cs{@@_quick_split:NnNn},
+% which sorts the prepared list and perform the post action placed
+% after \cs{s_@@_mark}, namely removing the trailing \cs{s_@@_stop} and
+% \cs{s_@@_stop} and leaving \cs{exp_stop_f:} to stop
+% \texttt{f}-expansion.
+% \begin{macrocode}
+\cs_new:Npn \tl_sort:nN #1#2
+ {
+ \exp_not:f
+ {
+ \tl_if_blank:nF {#1}
+ {
+ \@@_quick_prepare:Nnnn #2 { } { }
+ #1
+ { \prg_break_point: \@@_quick_prepare_end:NNNnw }
+ \s_@@_stop
+ }
+ }
+ }
+\cs_new:Npn \@@_quick_prepare:Nnnn #1#2#3#4
+ {
+ \prg_break: #4 \prg_break_point:
+ \@@_quick_prepare:Nnnn #1 { #2 #3 } { #1 {#4} }
+ }
+\cs_new:Npn \@@_quick_prepare_end:NNNnw #1#2#3#4#5 \s_@@_stop
+ {
+ \@@_quick_split:NnNn #4 \@@_quick_end:nnTFNn { }
+ \s_@@_mark { \@@_quick_cleanup:w \exp_stop_f: }
+ \s_@@_mark \s_@@_stop
+ }
+\cs_new:Npn \@@_quick_cleanup:w #1 \s_@@_mark \s_@@_stop {#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_quick_split:NnNn,
+% \@@_quick_only_i:NnnnnNn,
+% \@@_quick_only_ii:NnnnnNn,
+% \@@_quick_split_i:NnnnnNn,
+% \@@_quick_split_ii:NnnnnNn
+% }
+% The \texttt{only_i}, \texttt{only_ii}, \texttt{split_i} and
+% \texttt{split_ii} auxiliaries receive a useless first argument, the
+% new item~|#2| (that they append to either one of the next two
+% arguments), the list~|#3| of items less than the pivot, bigger
+% items~|#4|, the pivot~|#5|, a \meta{function}~|#6|, and an
+% item~|#7|. The \meta{function} is the user's \meta{conditional}
+% except at the end of the list where it is
+% \cs{@@_quick_end:nnTFNn}. The comparison is applied to the
+% \meta{pivot} and the \meta{item}, and calls the \texttt{only_i} or
+% \texttt{split_i} auxiliaries if the \meta{item} is smaller, and the
+% \texttt{only_ii} or \texttt{split_ii} auxiliaries otherwise. In
+% both cases, the next auxiliary goes to work right away, with no
+% intermediate expansion that would slow down operations. Note that
+% the argument~|#2| left for the next call has the form
+% \meta{conditional} \Arg{item}, so that the lists~|#3| and~|#4| keep
+% the right form to be fed to the next sorting function.
+% The \texttt{split} auxiliary differs from these in that it is
+% missing three of the arguments, which would be empty, and its first
+% argument is always the user's \meta{conditional} rather than an
+% ending function.
+% \begin{macrocode}
+\cs_new:Npn \@@_quick_split:NnNn #1#2#3#4
+ {
+ #3 {#2} {#4} \@@_quick_only_ii:NnnnnNn
+ \@@_quick_only_i:NnnnnNn
+ \@@_quick_single_end:nnnwnw
+ { #3 {#4} } { } { } {#2}
+ }
+\cs_new:Npn \@@_quick_only_i:NnnnnNn #1#2#3#4#5#6#7
+ {
+ #6 {#5} {#7} \@@_quick_split_ii:NnnnnNn
+ \@@_quick_only_i:NnnnnNn
+ \@@_quick_only_i_end:nnnwnw
+ { #6 {#7} } { #3 #2 } { } {#5}
+ }
+\cs_new:Npn \@@_quick_only_ii:NnnnnNn #1#2#3#4#5#6#7
+ {
+ #6 {#5} {#7} \@@_quick_only_ii:NnnnnNn
+ \@@_quick_split_i:NnnnnNn
+ \@@_quick_only_ii_end:nnnwnw
+ { #6 {#7} } { } { #4 #2 } {#5}
+ }
+\cs_new:Npn \@@_quick_split_i:NnnnnNn #1#2#3#4#5#6#7
+ {
+ #6 {#5} {#7} \@@_quick_split_ii:NnnnnNn
+ \@@_quick_split_i:NnnnnNn
+ \@@_quick_split_end:nnnwnw
+ { #6 {#7} } { #3 #2 } {#4} {#5}
+ }
+\cs_new:Npn \@@_quick_split_ii:NnnnnNn #1#2#3#4#5#6#7
+ {
+ #6 {#5} {#7} \@@_quick_split_ii:NnnnnNn
+ \@@_quick_split_i:NnnnnNn
+ \@@_quick_split_end:nnnwnw
+ { #6 {#7} } {#3} { #4 #2 } {#5}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_quick_end:nnTFNn,
+% \@@_quick_single_end:nnnwnw,
+% \@@_quick_only_i_end:nnnwnw,
+% \@@_quick_only_ii_end:nnnwnw,
+% \@@_quick_split_end:nnnwnw,
+% }
+% The \cs{@@_quick_end:nnTFNn} appears instead of the user's
+% conditional, and receives as its arguments the pivot~|#1|, a fake
+% item~|#2|, a \texttt{true} and a \texttt{false} branches |#3|
+% and~|#4|, followed by an ending function~|#5| (one of the four
+% auxiliaries here) and another copy~|#6| of the fake item. All those
+% are discarded except the function~|#5|. This function receives
+% lists~|#1| and~|#2| of items less than or greater than the
+% pivot~|#3|, then a continuation code~|#5| just after \cs{s_@@_mark}.
+% To avoid a memory problem described earlier, all of the ending
+% functions read~|#6| until \cs{s_@@_stop} and place~|#6| back into the
+% input stream. When the lists |#1| and~|#2| are empty, the
+% \texttt{single} auxiliary simply places the continuation~|#5| before
+% the pivot~|{#3}|. When |#2|~is empty, |#1|~is sorted and placed
+% before the pivot~|{#3}|, taking care to feed the continuation~|#5|
+% as a continuation for the function sorting~|#1|. When |#1|~is
+% empty, |#2|~is sorted, and the continuation argument is used to
+% place the continuation~|#5| and the pivot~|{#3}| before the sorted
+% result. Finally, when both lists are non-empty, items larger than
+% the pivot are sorted, then items less than the pivot, and the
+% continuations are done in such a way to place the pivot in between.
+% \begin{macrocode}
+\cs_new:Npn \@@_quick_end:nnTFNn #1#2#3#4#5#6 {#5}
+\cs_new:Npn \@@_quick_single_end:nnnwnw #1#2#3#4 \s_@@_mark #5#6 \s_@@_stop
+ { #5 {#3} #6 \s_@@_stop }
+\cs_new:Npn \@@_quick_only_i_end:nnnwnw #1#2#3#4 \s_@@_mark #5#6 \s_@@_stop
+ {
+ \@@_quick_split:NnNn #1
+ \@@_quick_end:nnTFNn { } \s_@@_mark {#5}
+ {#3}
+ #6 \s_@@_stop
+ }
+\cs_new:Npn \@@_quick_only_ii_end:nnnwnw #1#2#3#4 \s_@@_mark #5#6 \s_@@_stop
+ {
+ \@@_quick_split:NnNn #2
+ \@@_quick_end:nnTFNn { } \s_@@_mark { #5 {#3} }
+ #6 \s_@@_stop
+ }
+\cs_new:Npn \@@_quick_split_end:nnnwnw #1#2#3#4 \s_@@_mark #5#6 \s_@@_stop
+ {
+ \@@_quick_split:NnNn #2 \@@_quick_end:nnTFNn { } \s_@@_mark
+ {
+ \@@_quick_split:NnNn #1
+ \@@_quick_end:nnTFNn { } \s_@@_mark {#5}
+ {#3}
+ }
+ #6 \s_@@_stop
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% \begin{macro}{\@@_error:}
+% Bailing out of the sorting code is a bit tricky. It may not be safe
+% to use a delimited argument, so instead we redefine many
+% \pkg{l3sort} commands to be trivial, with \cs{@@_level:} jumping to
+% the break point. This error recovery won't work in a group.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_error:
+ {
+ \cs_set_eq:NN \@@_merge_blocks_aux: \prg_do_nothing:
+ \cs_set_eq:NN \@@_merge_blocks: \prg_do_nothing:
+ \cs_set_protected:Npn \@@_level: { \group_end: \prg_break: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_disable_toksdef:, \@@_disabled_toksdef:n}
+% While sorting, \tn{toksdef} is locally disabled to prevent users
+% from using \tn{newtoks} or similar commands in their comparison
+% code: the \tn{toks} registers that would be assigned are in use by
+% \pkg{l3sort}. In format mode, none of this is needed since there is
+% no \tn{toks} allocator.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_disable_toksdef:
+ { \cs_set_eq:NN \toksdef \@@_disabled_toksdef:n }
+\cs_new_protected:Npn \@@_disabled_toksdef:n #1
+ {
+ \msg_error:nne { sort } { toksdef }
+ { \token_to_str:N #1 }
+ \@@_error:
+ \tex_toksdef:D #1
+ }
+\msg_new:nnnn { sort } { toksdef }
+ { Allocation~of~\iow_char:N\\toks~registers~impossible~while~sorting. }
+ {
+ The~comparison~code~used~for~sorting~a~list~has~attempted~to~
+ define~#1~as~a~new~\iow_char:N\\toks~register~using~
+ \iow_char:N\\newtoks~
+ or~a~similar~command.~The~list~will~not~be~sorted.
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_too_long_error:NNw}
+% When there are too many items in a sequence, this is an error, and
+% we clean up properly the mapping over items in the list: break using
+% the type-specific breaking function |#1|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_too_long_error:NNw #1#2 \fi:
+ {
+ \fi:
+ \msg_error:nneee { sort } { too-large }
+ { \token_to_str:N #2 }
+ { \int_eval:n { \l_@@_true_max_int - \l_@@_min_int } }
+ { \int_eval:n { \l_@@_top_int - \l_@@_min_int } }
+ #1 \@@_error:
+ }
+\msg_new:nnnn { sort } { too-large }
+ { The~list~#1~is~too~long~to~be~sorted~by~TeX. }
+ {
+ TeX~has~#2~toks~registers~still~available:~
+ this~only~allows~to~sort~with~up~to~#3~
+ items.~The~list~will~not~be~sorted.
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\msg_new:nnnn { sort } { return-none }
+ { The~comparison~code~did~not~return. }
+ {
+ When~sorting~a~list,~the~code~to~compare~items~#1~and~#2~
+ did~not~call~
+ \iow_char:N\\sort_return_same: ~nor~
+ \iow_char:N\\sort_return_swapped: .~
+ Exactly~one~of~these~should~be~called.
+ }
+\msg_new:nnnn { sort } { return-two }
+ { The~comparison~code~returned~multiple~times. }
+ {
+ When~sorting~a~list,~the~code~to~compare~items~#1~and~#2~called~
+ \iow_char:N\\sort_return_same: ~or~
+ \iow_char:N\\sort_return_swapped: ~multiple~times.~
+ Exactly~one~of~these~should~be~called.
+ }
+\prop_gput:Nnn \g_msg_module_name_prop { sort } { LaTeX }
+\prop_gput:Nnn \g_msg_module_type_prop { sort } { }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3str-convert.dtx b/macros/latex-dev/required/l3kernel/l3str-convert.dtx
new file mode 100644
index 0000000000..75dbdd095b
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3str-convert.dtx
@@ -0,0 +1,3566 @@
+% \iffalse meta-comment
+%
+%% File: l3str-convert.dtx
+%
+% Copyright (C) 2013-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+%
+% \title{^^A
+% The \pkg{l3str-convert} module\\ String encoding conversions^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{Encoding and escaping schemes}
+%
+% Traditionally, string encodings only specify how strings of characters
+% should be stored as bytes. However, the resulting lists of bytes are
+% often to be used in contexts where only a restricted subset of bytes
+% are permitted (\emph{e.g.}, \textsc{pdf} string objects,
+% \textsc{url}s). Hence, storing a string of characters is done in two
+% steps.
+% \begin{itemize}
+% \item The code points (\enquote{character codes}) are expressed as
+% bytes following a given \enquote{encoding}. This can be
+% \textsc{utf-16}, \textsc{iso 8859-1}, \emph{etc.} See
+% Table~\ref{tab:encodings} for a list of supported
+% encodings.\footnote{Encodings and escapings will be added as they
+% are requested.}
+% \item Bytes are translated to \TeX{} tokens through a given
+% \enquote{escaping}. Those are defined for the most part by the
+% \texttt{pdf} file format. See Table~\ref{tab:escapings} for a
+% list of escaping methods supported.\footnotemark[\csname c@footnote\endcsname]
+% \end{itemize}
+%
+% \begin{table}\centering
+% \caption{\label{tab:encodings}Supported encodings.
+% Non-alphanumeric characters are ignored,
+% and capital letters are lower-cased
+% before searching for the encoding in this list.}
+% \begin{tabular}{cc}
+% \toprule
+% \meta{Encoding} & description \\
+% \midrule
+% \texttt{utf8} & \textsc{utf-8} \\
+% \texttt{utf16} & \textsc{utf-16}, with byte-order mark \\
+% \texttt{utf16be} & \textsc{utf-16}, big-endian \\
+% \texttt{utf16le} & \textsc{utf-16}, little-endian \\
+% \texttt{utf32} & \textsc{utf-32}, with byte-order mark \\
+% \texttt{utf32be} & \textsc{utf-32}, big-endian \\
+% \texttt{utf32le} & \textsc{utf-32}, little-endian \\
+% \midrule
+% \texttt{iso88591}, \texttt{latin1} & \textsc{iso 8859-1} \\
+% \texttt{iso88592}, \texttt{latin2} & \textsc{iso 8859-2} \\
+% \texttt{iso88593}, \texttt{latin3} & \textsc{iso 8859-3} \\
+% \texttt{iso88594}, \texttt{latin4} & \textsc{iso 8859-4} \\
+% \texttt{iso88595} & \textsc{iso 8859-5} \\
+% \texttt{iso88596} & \textsc{iso 8859-6} \\
+% \texttt{iso88597} & \textsc{iso 8859-7} \\
+% \texttt{iso88598} & \textsc{iso 8859-8} \\
+% \texttt{iso88599}, \texttt{latin5} & \textsc{iso 8859-9} \\
+% \texttt{iso885910}, \texttt{latin6} & \textsc{iso 8859-10} \\
+% \texttt{iso885911} & \textsc{iso 8859-11} \\
+% \texttt{iso885913}, \texttt{latin7} & \textsc{iso 8859-13} \\
+% \texttt{iso885914}, \texttt{latin8} & \textsc{iso 8859-14} \\
+% \texttt{iso885915}, \texttt{latin9} & \textsc{iso 8859-15} \\
+% \texttt{iso885916}, \texttt{latin10} & \textsc{iso 8859-16} \\
+% \midrule
+% \texttt{clist} & comma-list of integers \\
+% \meta{empty} & native (Unicode) string \\
+% \texttt{default} & like \texttt{utf8} with 8-bit engines,
+% and like native with unicode-engines \\
+% \bottomrule
+% \end{tabular}
+% \end{table}
+%
+% \begin{table}\centering
+% \caption{\label{tab:escapings}Supported escapings.
+% Non-alphanumeric characters are ignored,
+% and capital letters are lower-cased
+% before searching for the escaping in this list.}
+% \begin{tabular}{cc}
+% \toprule
+% \meta{Escaping} & description \\
+% \midrule
+% \texttt{bytes}, or empty
+% & arbitrary bytes \\
+% \texttt{hex}, \texttt{hexadecimal}
+% & byte $=$ two hexadecimal digits \\
+% \texttt{name}
+% & see \tn{pdfescapename} \\
+% \texttt{string}
+% & see \tn{pdfescapestring} \\
+% \texttt{url}
+% & encoding used in \textsc{url}s \\
+% \bottomrule
+% \end{tabular}
+% \end{table}
+%
+% \section{Conversion functions}
+%
+% \begin{function}{\str_set_convert:Nnnn, \str_gset_convert:Nnnn}
+% \begin{syntax}
+% \cs{str_set_convert:Nnnn} \meta{str~var} \Arg{string} \Arg{name~1} \Arg{name~2}
+% \end{syntax}
+% This function converts the \meta{string} from the encoding given by
+% \meta{name~1} to the encoding given by \meta{name~2}, and stores the
+% result in the \meta{str~var}. Each \meta{name} can have the form
+% \meta{encoding} or \meta{encoding}\texttt{/}\meta{escaping}, where
+% the possible values of \meta{encoding} and \meta{escaping} are given
+% in Tables~\ref{tab:encodings} and~\ref{tab:escapings}, respectively.
+% The default escaping is to input and output bytes directly. The
+% special case of an empty \meta{name} indicates the use of
+% \enquote{native} strings, 8-bit for \pdfTeX{}, and Unicode strings
+% for the other two engines.
+%
+% For example,
+% \begin{verbatim}
+% \str_set_convert:Nnnn \l_foo_str { Hello! } { } { utf16/hex }
+% \end{verbatim}
+% results in the variable \cs[no-index]{l_foo_str} holding the string
+% \texttt{FEFF00480065006C006C006F0021}. This is obtained by
+% converting each character in the (native) string \texttt{Hello!} to
+% the \textsc{utf-16} encoding, and expressing each byte as a pair of
+% hexadecimal digits. Note the presence of a (big-endian) byte order
+% mark \hexnum{FEFF}, which can be avoided by specifying the encoding
+% \texttt{utf16be/hex}.
+%
+% An error is raised if the \meta{string} is not valid according to
+% the \meta{escaping~1} and \meta{encoding~1}, or if it cannot be
+% reencoded in the \meta{encoding~2} and \meta{escaping~2} (for
+% instance, if a character does not exist in the \meta{encoding~2}).
+% Erroneous input is replaced by the Unicode replacement character
+% \hexnum{FFFD}, and characters which cannot be reencoded are replaced
+% by either the replacement character \hexnum{FFFD} if it exists in
+% the \meta{encoding~2}, or an encoding-specific replacement
+% character, or the question mark character.
+% \end{function}
+%
+% \begin{function}[TF]{\str_set_convert:Nnnn, \str_gset_convert:Nnnn}
+% \begin{syntax}
+% \cs{str_set_convert:NnnnTF} \meta{str~var} \Arg{string} \Arg{name~1} \Arg{name~2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% As \cs{str_set_convert:Nnnn}, converts the \meta{string} from the
+% encoding given by \meta{name~1} to the encoding given by
+% \meta{name~2}, and assigns the result to \meta{str~var}. Contrarily
+% to \cs{str_set_convert:Nnnn}, the conditional variant does not raise
+% errors in case the \meta{string} is not valid according to the
+% \meta{name~1} encoding, or cannot be expressed in the \meta{name~2}
+% encoding. Instead, the \meta{false code} is performed.
+% \end{function}
+%
+% \section{Conversion by expansion (for PDF contexts)}
+%
+% A small number of expandable functions are provided for use in PDF string/name
+% contexts. These \emph{assume UTF-8} and \emph{no escaping} in the input.
+%
+% \begin{function}[EXP]{\str_convert_pdfname:n}
+% \begin{syntax}
+% \cs{str_convert_pdfname:n} \meta{string}
+% \end{syntax}
+% As \cs{str_set_convert:Nnnn}, converts the \meta{string} on a byte-by-byte
+% basis with non-ASCII codepoints escaped using hashes.
+% \end{function}
+%
+% \section{Possibilities, and things to do}
+%
+% Encoding/escaping-related tasks.
+% \begin{itemize}
+% \item In \XeTeX{}/\LuaTeX{}, would it be better to use the
+% |^^^^....| approach to build a string from a given list of
+% character codes? Namely, within a group, assign |0-9a-f| and all
+% characters we want to category ``other'', then assign~|^| the
+% category superscript, and use \tn{scantokens}.
+% \item Change \cs{str_set_convert:Nnnn} to expand its last two
+% arguments.
+% \item Describe the internal format in the code comments. Refuse code
+% points in $[\hexnum{D800}, \hexnum{DFFF}]$ in the internal
+% representation?
+% \item Add documentation about each encoding and escaping method, and
+% add examples.
+% \item The \texttt{hex} unescaping should raise an error for
+% odd-token count strings.
+% \item Decide what bytes should be escaped in the \texttt{url}
+% escaping. Perhaps the characters |!'()*-./0123456789_| are safe,
+% and all other characters should be escaped?
+% \item Automate generation of 8-bit mapping files.
+% \item Change the framework for 8-bit encodings: for decoding from
+% 8-bit to Unicode, use $256$ integer registers; for encoding, use a
+% tree-box.
+% \item More encodings (see Heiko's \pkg{stringenc}). CESU?
+% \item More escapings: \textsc{ascii85}, shell escapes, lua escapes,
+% \emph{etc.}?
+% \end{itemize}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3str-convert} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=str>
+% \end{macrocode}
+%
+% \subsection{Helpers}
+%
+% \subsubsection{Variables and constants}
+%
+% \begin{macro}{\@@_tmp:w}
+% \begin{variable}{\l_@@_internal_tl}
+% Internal scratch space for some functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_tmp:w { }
+\tl_new:N \l_@@_internal_tl
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_result_tl}
+% The \cs{g_@@_result_tl} variable is used to hold the result of
+% various internal string operations (mostly conversions) which are
+% typically performed in a group. The variable is global so that it
+% remains defined outside the group, to be assigned to a user-provided
+% variable.
+% \begin{macrocode}
+\tl_new:N \g_@@_result_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_replacement_char_int}
+% When converting, invalid bytes are replaced by the Unicode
+% replacement character \hexnum{FFFD}.
+% \begin{macrocode}
+\int_const:Nn \c_@@_replacement_char_int { "FFFD }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_max_byte_int}
+% The maximal byte number.
+% \begin{macrocode}
+\int_const:Nn \c_@@_max_byte_int { 255 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\s_@@}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\q_@@_nil}
+% Internal quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_nil
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_alias_prop}
+% To avoid needing one file per encoding/escaping alias, we keep track
+% of those in a property list.
+% \begin{macrocode}
+\prop_new:N \g_@@_alias_prop
+\prop_gput:Nnn \g_@@_alias_prop { latin1 } { iso88591 }
+\prop_gput:Nnn \g_@@_alias_prop { latin2 } { iso88592 }
+\prop_gput:Nnn \g_@@_alias_prop { latin3 } { iso88593 }
+\prop_gput:Nnn \g_@@_alias_prop { latin4 } { iso88594 }
+\prop_gput:Nnn \g_@@_alias_prop { latin5 } { iso88599 }
+\prop_gput:Nnn \g_@@_alias_prop { latin6 } { iso885910 }
+\prop_gput:Nnn \g_@@_alias_prop { latin7 } { iso885913 }
+\prop_gput:Nnn \g_@@_alias_prop { latin8 } { iso885914 }
+\prop_gput:Nnn \g_@@_alias_prop { latin9 } { iso885915 }
+\prop_gput:Nnn \g_@@_alias_prop { latin10 } { iso885916 }
+\prop_gput:Nnn \g_@@_alias_prop { utf16le } { utf16 }
+\prop_gput:Nnn \g_@@_alias_prop { utf16be } { utf16 }
+\prop_gput:Nnn \g_@@_alias_prop { utf32le } { utf32 }
+\prop_gput:Nnn \g_@@_alias_prop { utf32be } { utf32 }
+\prop_gput:Nnn \g_@@_alias_prop { hexadecimal } { hex }
+\bool_lazy_any:nTF
+ {
+ \sys_if_engine_luatex_p:
+ \sys_if_engine_xetex_p:
+ }
+ {
+ \prop_gput:Nnn \g_@@_alias_prop { default } { }
+ }
+ {
+ \prop_gput:Nnn \g_@@_alias_prop { default } { utf8 }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_error_bool}
+% In conversion functions with a built-in conditional, errors are not
+% reported directly to the user, but the information is collected in
+% this boolean, used at the end to decide on which branch of the
+% conditional to take.
+% \begin{macrocode}
+\bool_new:N \g_@@_error_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_byte_flag, \l_@@_error_flag}
+% Conversions from one \meta{encoding}/\meta{escaping} pair to another
+% are done within \texttt{e}-expanding assignments. Errors are
+% signalled by raising the relevant flag.
+% \begin{macrocode}
+\flag_new:N \l_@@_byte_flag
+\flag_new:N \l_@@_error_flag
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{String conditionals}
+%
+% \begin{macro}[EXP]{\@@_if_contains_char:NnT, \@@_if_contains_char:NnTF}
+% \begin{macro}[EXP]{\@@_if_contains_char:nnTF}
+% \begin{macro}[EXP]{\@@_if_contains_char_aux:nn,\@@_if_contains_char_auxi:nN}
+% \begin{macro}[EXP]{\@@_if_contains_char_true:}
+% \begin{syntax}
+% \cs{@@_if_contains_char:nnTF} \Arg{token list} \meta{char}
+% \end{syntax}
+% Expects the \meta{token list} to be an \meta{other string}: the
+% caller is responsible for ensuring that no (too-)special catcodes
+% remain.
+% Loop over the characters of the string, comparing character codes.
+% The loop is broken if character codes match. Otherwise we return
+% \enquote{false}.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_if_contains_char:Nn #1#2 { T , TF }
+ {
+ \exp_after:wN \@@_if_contains_char_aux:nn \exp_after:wN {#1} {#2}
+ { \prg_break:n { ? \fi: } }
+ \prg_break_point:
+ \prg_return_false:
+ }
+\cs_new:Npn \@@_if_contains_char_aux:nn #1#2
+ { \@@_if_contains_char_auxi:nN {#2} #1 }
+\prg_new_conditional:Npnn \@@_if_contains_char:nn #1#2 { TF }
+ {
+ \@@_if_contains_char_auxi:nN {#2} #1 { \prg_break:n { ? \fi: } }
+ \prg_break_point:
+ \prg_return_false:
+ }
+\cs_new:Npn \@@_if_contains_char_auxi:nN #1#2
+ {
+ \if_charcode:w #1 #2
+ \exp_after:wN \@@_if_contains_char_true:
+ \fi:
+ \@@_if_contains_char_auxi:nN {#1}
+ }
+\cs_new:Npn \@@_if_contains_char_true:
+ { \prg_break:n { \prg_return_true: \use_none:n } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_octal_use:NTF}
+% \begin{syntax}
+% \cs{@@_octal_use:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{token} is an octal digit, it is left in the input
+% stream, \emph{followed} by the \meta{true code}. Otherwise, the
+% \meta{false code} is left in the input stream.
+% \begin{texnote}
+% This function will fail if the escape character is an octal
+% digit. We are thus careful to set the escape character to a known
+% value before using it.
+% \end{texnote}
+% \TeX{} dutifully detects octal digits for us: if |#1| is an octal
+% digit, then the right-hand side of the comparison is |'1#1|, greater
+% than $1$. Otherwise, the right-hand side stops as |'1|, and the
+% conditional takes the \texttt{false} branch.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_octal_use:N #1 { TF }
+ {
+ \if_int_compare:w 1 < '1 \token_to_str:N #1 \exp_stop_f:
+ #1 \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_hexadecimal_use:NTF}
+% \TeX{} detects uppercase hexadecimal digits for us (see
+% \cs{@@_octal_use:NTF}), but not the lowercase letters, which we
+% need to detect and replace by their uppercase counterpart.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_hexadecimal_use:N #1 { TF }
+ {
+ \if_int_compare:w 1 < "1 \token_to_str:N #1 \exp_stop_f:
+ #1 \prg_return_true:
+ \else:
+ \if_case:w \int_eval:n { \exp_after:wN ` \token_to_str:N #1 - `a }
+ A
+ \or: B
+ \or: C
+ \or: D
+ \or: E
+ \or: F
+ \else:
+ \prg_return_false:
+ \exp_after:wN \use_none:n
+ \fi:
+ \prg_return_true:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Conversions}
+%
+% \subsubsection{Producing one byte or character}
+%
+% \begin{variable}{\c_@@_byte_0_tl, \c_@@_byte_1_tl, \c_@@_byte_255_tl}
+% \begin{variable}{\c_@@_byte_-1_tl}
+% For each integer $N$ in the range $[0,255]$, we create a constant
+% token list which holds three character tokens with category code
+% other: the character with character code $N$, followed by the
+% representation of $N$ as two hexadecimal digits. The value $-1$ is
+% given a default token list which ensures that later functions give
+% an empty result for the input $-1$.
+% \begin{macrocode}
+\group_begin:
+ \__kernel_tl_set:Nx \l_@@_internal_tl { \tl_to_str:n { 0123456789ABCDEF } }
+ \tl_map_inline:Nn \l_@@_internal_tl
+ {
+ \tl_map_inline:Nn \l_@@_internal_tl
+ {
+ \tl_const:ce { c_@@_byte_ \int_eval:n {"#1##1} _tl }
+ { \char_generate:nn { "#1##1 } { 12 } #1 ##1 }
+ }
+ }
+\group_end:
+\tl_const:cn { c_@@_byte_-1_tl } { { } \use_none:n { } }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_output_byte:n}
+% \begin{macro}[EXP]{\@@_output_byte:w}
+% \begin{macro}[EXP]{\@@_output_hexadecimal:n}
+% \begin{macro}[EXP]{\@@_output_end:}
+% Those functions must be used carefully: feeding them a value outside
+% the range $[-1,255]$ will attempt to use the undefined token list
+% variable \cs{c_@@_byte_\meta{number}_tl}. Assuming that the
+% argument is in the right range, we expand the corresponding token
+% list, and pick either the byte (first token) or the hexadecimal
+% representations (second and third tokens). The value $-1$ produces
+% an empty result in both cases.
+% \begin{macrocode}
+\cs_new:Npn \@@_output_byte:n #1
+ { \@@_output_byte:w #1 \@@_output_end: }
+\cs_new:Npn \@@_output_byte:w
+ {
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \use_i:nnn
+ \cs:w c_@@_byte_ \int_eval:w
+ }
+\cs_new:Npn \@@_output_hexadecimal:n #1
+ {
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \use_none:n
+ \cs:w c_@@_byte_ \int_eval:n {#1} _tl \cs_end:
+ }
+\cs_new:Npn \@@_output_end:
+ { \scan_stop: _tl \cs_end: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_output_byte_pair_be:n}
+% \begin{macro}[rEXP]{\@@_output_byte_pair_le:n}
+% \begin{macro}[rEXP]{\@@_output_byte_pair:nnN}
+% Convert a number in the range $[0,65535]$ to a pair of bytes, either
+% big-endian or little-endian.
+% \begin{macrocode}
+\cs_new:Npn \@@_output_byte_pair_be:n #1
+ {
+ \exp_args:Nf \@@_output_byte_pair:nnN
+ { \int_div_truncate:nn { #1 } { "100 } } {#1} \use:nn
+ }
+\cs_new:Npn \@@_output_byte_pair_le:n #1
+ {
+ \exp_args:Nf \@@_output_byte_pair:nnN
+ { \int_div_truncate:nn { #1 } { "100 } } {#1} \use_ii_i:nn
+ }
+\cs_new:Npn \@@_output_byte_pair:nnN #1#2#3
+ {
+ #3
+ { \@@_output_byte:n { #1 } }
+ { \@@_output_byte:n { #2 - #1 * "100 } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Mapping functions for conversions}
+%
+% \begin{macro}{\@@_convert_gmap:N}
+% \begin{macro}[rEXP]{\@@_convert_gmap_loop:NN}
+% This maps the function |#1| over all characters in
+% \cs{g_@@_result_tl}, which should be a byte string in most cases,
+% sometimes a native string.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_convert_gmap:N #1
+ {
+ \__kernel_tl_gset:Nx \g_@@_result_tl
+ {
+ \exp_after:wN \@@_convert_gmap_loop:NN
+ \exp_after:wN #1
+ \g_@@_result_tl { ? \prg_break: }
+ \prg_break_point:
+ }
+ }
+\cs_new:Npn \@@_convert_gmap_loop:NN #1#2
+ {
+ \use_none:n #2
+ #1#2
+ \@@_convert_gmap_loop:NN #1
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert_gmap_internal:N}
+% \begin{macro}[rEXP]{\@@_convert_gmap_internal_loop:Nw}
+% This maps the function |#1| over all character codes in
+% \cs{g_@@_result_tl}, which must be in the internal representation.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_convert_gmap_internal:N #1
+ {
+ \__kernel_tl_gset:Nx \g_@@_result_tl
+ {
+ \exp_after:wN \@@_convert_gmap_internal_loop:Nww
+ \exp_after:wN #1
+ \g_@@_result_tl \s_@@ \s_@@_stop \prg_break: \s_@@
+ \prg_break_point:
+ }
+ }
+\cs_new:Npn \@@_convert_gmap_internal_loop:Nww #1 #2 \s_@@ #3 \s_@@
+ {
+ \@@_use_none_delimit_by_s_stop:w #3 \s_@@_stop
+ #1 {#3}
+ \@@_convert_gmap_internal_loop:Nww #1
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Error-reporting during conversion}
+%
+% \begin{macro}{\@@_if_flag_error:Nne}
+% \begin{macro}{\@@_if_flag_no_error:Nne}
+% When converting using the function \cs{str_set_convert:Nnnn}, errors
+% should be reported to the user after each step in the
+% conversion. Errors are signalled by raising some flag (typically
+% \texttt{@@_error}), so here we test that flag: if it is raised,
+% give the user an error, otherwise remove the arguments. On the other
+% hand, in the conditional functions \cs{str_set_convert:NnnnTF},
+% errors should be suppressed. This is done by changing
+% \cs{@@_if_flag_error:Nne} into \cs{@@_if_flag_no_error:Nne}
+% locally.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_if_flag_error:Nne #1
+ {
+ \flag_if_raised:NTF #1
+ { \msg_error:nne { str } }
+ { \use_none:nn }
+ }
+\cs_new_protected:Npn \@@_if_flag_no_error:Nne #1#2#3
+ { \flag_if_raised:NT #1 { \bool_gset_true:N \g_@@_error_bool } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_if_flag_times:NT}
+% At the end of each conversion step, we raise all relevant errors as
+% one error message, built on the fly. The height of each flag
+% indicates how many times a given error was encountered. This
+% function prints |#2| followed by the number of occurrences of an
+% error if it occurred, nothing otherwise.
+% \begin{macrocode}
+\cs_new:Npn \@@_if_flag_times:NT #1#2
+ { \flag_if_raised:NT #1 { #2~(x \flag_height:N #1 ) } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Framework for conversions}
+%
+% Most functions in this module expect to be working with
+% \enquote{native} strings. Strings can also be stored as bytes, in one
+% of many encodings, for instance \textsc{utf8}. The bytes themselves
+% can be expressed in various ways in terms of \TeX{} tokens, for
+% instance as pairs of hexadecimal digits. The questions of going from
+% arbitrary Unicode code points to bytes, and from bytes to tokens are
+% mostly independent.
+%
+% Conversions are done in four steps:
+% \begin{itemize}
+% \item \enquote{unescape} produces a string of bytes;
+% \item \enquote{decode} takes in a string of bytes, and converts it
+% to a list of Unicode characters in an internal representation,
+% with items of the form
+% \begin{quote}
+% \meta{bytes} \cs{s_@@} \meta{Unicode code point} \cs{s_@@}
+% \end{quote}
+% where we have collected the \meta{bytes} which combined to form
+% this particular Unicode character, and the \meta{Unicode code
+% point} is in the range $[0,\hexnum{10FFFF}]$.
+% \item \enquote{encode} encodes the internal list of code points as a
+% byte string in the new encoding;
+% \item \enquote{escape} escapes bytes as requested.
+% \end{itemize}
+% The process is modified in case one of the encoding is empty (or the
+% conversion function has been set equal to the empty encoding because
+% it was not found): then the unescape or escape step is ignored, and
+% the decode or encode steps work on tokens instead of bytes. Otherwise,
+% each step must ensure that it passes a correct byte string or internal
+% string to the next step.
+%
+% \begin{macro}{\str_set_convert:Nnnn, \str_gset_convert:Nnnn}
+% \begin{macro}[TF]{\str_set_convert:Nnnn, \str_gset_convert:Nnnn}
+% \begin{macro}{\@@_convert:nNNnnn}
+% The input string is stored in \cs{g_@@_result_tl}, then we:
+% unescape and decode; encode and escape; exit the group and store the
+% result in the user's variable. The various conversion functions all
+% act on \cs{g_@@_result_tl}. Errors are silenced for the conditional
+% functions by redefining \cs{@@_if_flag_error:Nne} locally.
+% \begin{macrocode}
+\cs_new_protected:Npn \str_set_convert:Nnnn
+ { \@@_convert:nNNnnn { } \tl_set_eq:NN }
+\cs_new_protected:Npn \str_gset_convert:Nnnn
+ { \@@_convert:nNNnnn { } \tl_gset_eq:NN }
+\prg_new_protected_conditional:Npnn
+ \str_set_convert:Nnnn #1#2#3#4 { T , F , TF }
+ {
+ \bool_gset_false:N \g_@@_error_bool
+ \@@_convert:nNNnnn
+ { \cs_set_eq:NN \@@_if_flag_error:Nne \@@_if_flag_no_error:Nne }
+ \tl_set_eq:NN #1 {#2} {#3} {#4}
+ \bool_if:NTF \g_@@_error_bool \prg_return_false: \prg_return_true:
+ }
+\prg_new_protected_conditional:Npnn
+ \str_gset_convert:Nnnn #1#2#3#4 { T , F , TF }
+ {
+ \bool_gset_false:N \g_@@_error_bool
+ \@@_convert:nNNnnn
+ { \cs_set_eq:NN \@@_if_flag_error:Nne \@@_if_flag_no_error:Nne }
+ \tl_gset_eq:NN #1 {#2} {#3} {#4}
+ \bool_if:NTF \g_@@_error_bool \prg_return_false: \prg_return_true:
+ }
+\cs_new_protected:Npn \@@_convert:nNNnnn #1#2#3#4#5#6
+ {
+ \group_begin:
+ #1
+ \__kernel_tl_gset:Nx \g_@@_result_tl { \__kernel_str_to_other_fast:n {#4} }
+ \exp_after:wN \@@_convert:wwwnn
+ \tl_to_str:n {#5} /// \s_@@_stop
+ { decode } { unescape }
+ \prg_do_nothing:
+ \@@_convert_decode_:
+ \exp_after:wN \@@_convert:wwwnn
+ \tl_to_str:n {#6} /// \s_@@_stop
+ { encode } { escape }
+ \use_ii_i:nn
+ \@@_convert_encode_:
+ \__kernel_tl_gset:Nx \g_@@_result_tl
+ { \tl_to_str:V \g_@@_result_tl }
+ \group_end:
+ #2 #3 \g_@@_result_tl
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert:wwwnn}
+% \begin{macro}{\@@_convert:NNnNN}
+% The task of \cs{@@_convert:wwwnn} is to split
+% \meta{encoding}/\meta{escaping} pairs into their components, |#1|
+% and |#2|. Calls to \cs{@@_convert:nnn} ensure that the
+% corresponding conversion functions are defined. The third auxiliary
+% does the main work.
+% \begin{itemize}
+% \item |#1| is the encoding conversion function;
+% \item |#2| is the escaping function;
+% \item |#3| is the escaping name for use in an error message;
+% \item |#4| is \cs{prg_do_nothing:} for unescaping/decoding, and
+% \cs{use_ii_i:nn} for encoding/escaping;
+% \item |#5| is the default encoding function (either
+% \enquote{decode} or \enquote{encode}), for which there should be
+% no escaping.
+% \end{itemize}
+% Let us ignore the native encoding for a second. In the
+% unescaping/decoding phase, we want to do |#2#1| in this order, and
+% in the encoding/escaping phase, the order should be reversed:
+% |#4#2#1| does exactly that. If one of the encodings is the default
+% (native), then the escaping should be ignored, with an error if any
+% was given, and only the encoding, |#1|, should be performed.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_convert:wwwnn
+ #1 / #2 // #3 \s_@@_stop #4#5
+ {
+ \@@_convert:nnn {enc} {#4} {#1}
+ \@@_convert:nnn {esc} {#5} {#2}
+ \exp_args:Ncc \@@_convert:NNnNN
+ { @@_convert_#4_#1: } { @@_convert_#5_#2: } {#2}
+ }
+\cs_new_protected:Npn \@@_convert:NNnNN #1#2#3#4#5
+ {
+ \if_meaning:w #1 #5
+ \tl_if_empty:nF {#3}
+ { \msg_error:nne { str } { native-escaping } {#3} }
+ #1
+ \else:
+ #4 #2 #1
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert:nnn}
+% \begin{macro}{\@@_convert:nnnn}
+% The arguments of \cs{@@_convert:nnn} are: \texttt{enc} or
+% \texttt{esc}, used to build filenames, the type of the conversion
+% (unescape, decode, encode, escape), and the encoding or escaping
+% name. If the function is already defined, no need to do anything.
+% Otherwise, filter out all non-alphanumerics in the name, and
+% lowercase it. Feed that, and the same three arguments, to
+% \cs{@@_convert:nnnn}. The task is then to make sure that the
+% conversion function |#3_#1| corresponding to the type |#3| and
+% filtered name |#1| is defined, then set our initial conversion
+% function |#3_#4| equal to that.
+%
+% How do we get the |#3_#1| conversion to be defined if it isn't?
+% Two main cases.
+%
+% First, if |#1| is a key in \cs{g_@@_alias_prop}, then the value
+% \cs{l_@@_internal_tl} tells us what file to load. Loading is
+% skipped if the file was already read, \emph{i.e.}, if the conversion
+% command based on \cs{l_@@_internal_tl} already exists. Otherwise,
+% try to load the file; if that fails, there is an error, use the
+% default empty name instead.
+%
+% Second, |#1| may be absent from the property list. The
+% \cs{cs_if_exist:cF} test is automatically false, and we search for a
+% file defining the encoding or escaping |#1| (this should allow
+% third-party \texttt{.def} files). If the file is not found, there is
+% an error, use the default empty name instead.
+%
+% In all cases, the conversion based on \cs{l_@@_internal_tl} is
+% defined, so we can set the |#3_#1| function equal to that. In some
+% cases (\emph{e.g.}, \texttt{utf16be}), the |#3_#1| function is
+% actually defined within the file we just loaded, and it is different
+% from the \cs{l_@@_internal_tl}-based function: we mustn't clobber
+% that different definition.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_convert:nnn #1#2#3
+ {
+ \cs_if_exist:cF { @@_convert_#2_#3: }
+ {
+ \exp_args:Ne \@@_convert:nnnn
+ { \@@_convert_lowercase_alphanum:n {#3} }
+ {#1} {#2} {#3}
+ }
+ }
+\cs_new_protected:Npn \@@_convert:nnnn #1#2#3#4
+ {
+ \cs_if_exist:cF { @@_convert_#3_#1: }
+ {
+ \prop_get:NnNF \g_@@_alias_prop {#1} \l_@@_internal_tl
+ { \tl_set:Nn \l_@@_internal_tl {#1} }
+ \cs_if_exist:cF { @@_convert_#3_ \l_@@_internal_tl : }
+ {
+ \file_if_exist:nTF { l3str-#2- \l_@@_internal_tl .def }
+ {
+ \group_begin:
+ \cctab_select:N \c_code_cctab
+ \file_input:n { l3str-#2- \l_@@_internal_tl .def }
+ \group_end:
+ }
+ {
+ \tl_clear:N \l_@@_internal_tl
+ \msg_error:nnee { str } { unknown-#2 } {#4} {#1}
+ }
+ }
+ \cs_if_exist:cF { @@_convert_#3_#1: }
+ {
+ \cs_gset_eq:cc { @@_convert_#3_#1: }
+ { @@_convert_#3_ \l_@@_internal_tl : }
+ }
+ }
+ \cs_gset_eq:cc { @@_convert_#3_#4: } { @@_convert_#3_#1: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_convert_lowercase_alphanum:n}
+% \begin{macro}[rEXP]{\@@_convert_lowercase_alphanum_loop:N}
+% This function keeps only letters and digits, with upper case letters
+% converted to lower case.
+% \begin{macrocode}
+\cs_new:Npn \@@_convert_lowercase_alphanum:n #1
+ {
+ \exp_after:wN \@@_convert_lowercase_alphanum_loop:N
+ \tl_to_str:n {#1} { ? \prg_break: }
+ \prg_break_point:
+ }
+\cs_new:Npn \@@_convert_lowercase_alphanum_loop:N #1
+ {
+ \use_none:n #1
+ \if_int_compare:w `#1 > `Z \exp_stop_f:
+ \if_int_compare:w `#1 > `z \exp_stop_f: \else:
+ \if_int_compare:w `#1 < `a \exp_stop_f: \else:
+ #1
+ \fi:
+ \fi:
+ \else:
+ \if_int_compare:w `#1 < `A \exp_stop_f:
+ \if_int_compare:w 1 < 1#1 \exp_stop_f:
+ #1
+ \fi:
+ \else:
+ \@@_output_byte:n { `#1 + `a - `A }
+ \fi:
+ \fi:
+ \@@_convert_lowercase_alphanum_loop:N
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Byte unescape and escape}
+%
+% Strings of bytes may need to be stored in auxiliary files in safe
+% \enquote{escaping} formats. Each such escaping is only loaded as
+% needed. By default, on input any non-byte is filtered out, while the
+% output simply consists in letting bytes through.
+%
+% \begin{macro}[rEXP]{\@@_filter_bytes:n}
+% \begin{macro}[rEXP]{\@@_filter_bytes_aux:N}
+% In the case of 8-bit engines, every character is a byte. For
+% Unicode-aware engines, test the character code; non-bytes cause us
+% to raise the flag \cs{l_@@_byte_flag}. Spaces have already been given
+% the correct category code when this function is called.
+% \begin{macrocode}
+\bool_lazy_any:nTF
+ {
+ \sys_if_engine_luatex_p:
+ \sys_if_engine_xetex_p:
+ }
+ {
+ \cs_new:Npn \@@_filter_bytes:n #1
+ {
+ \@@_filter_bytes_aux:N #1
+ { ? \prg_break: }
+ \prg_break_point:
+ }
+ \cs_new:Npn \@@_filter_bytes_aux:N #1
+ {
+ \use_none:n #1
+ \if_int_compare:w `#1 < 256 \exp_stop_f:
+ #1
+ \else:
+ \flag_raise:N \l_@@_byte_flag
+ \fi:
+ \@@_filter_bytes_aux:N
+ }
+ }
+ { \cs_new_eq:NN \@@_filter_bytes:n \use:n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert_unescape_:}
+% \begin{macro}{\@@_convert_unescape_bytes:}
+% The simplest unescaping method removes non-bytes from
+% \cs{g_@@_result_tl}.
+% \begin{macrocode}
+\bool_lazy_any:nTF
+ {
+ \sys_if_engine_luatex_p:
+ \sys_if_engine_xetex_p:
+ }
+ {
+ \cs_new_protected:Npn \@@_convert_unescape_:
+ {
+ \flag_clear:N \l_@@_byte_flag
+ \__kernel_tl_gset:Nx \g_@@_result_tl
+ { \exp_args:No \@@_filter_bytes:n \g_@@_result_tl }
+ \@@_if_flag_error:Nne \l_@@_byte_flag { non-byte } { bytes }
+ }
+ }
+ { \cs_new_protected:Npn \@@_convert_unescape_: { } }
+\cs_new_eq:NN \@@_convert_unescape_bytes: \@@_convert_unescape_:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert_escape_:}
+% \begin{macro}{\@@_convert_escape_bytes:}
+% The simplest form of escape leaves the bytes from the previous step
+% of the conversion unchanged.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_convert_escape_: { }
+\cs_new_eq:NN \@@_convert_escape_bytes: \@@_convert_escape_:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Native strings}
+%
+% \begin{macro}{\@@_convert_decode_:}
+% \begin{macro}[rEXP]{\@@_decode_native_char:N}
+% Convert each character to its character code, one at a time.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_convert_decode_:
+ { \@@_convert_gmap:N \@@_decode_native_char:N }
+\cs_new:Npn \@@_decode_native_char:N #1
+ { #1 \s_@@ \int_value:w `#1 \s_@@ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert_encode_:}
+% \begin{macro}[EXP]{\@@_encode_native_char:n}
+% The conversion from an internal string to native character tokens
+% basically maps \cs{char_generate:nn} through the code-points, but in
+% non-Unicode-aware engines we use a fall-back character |?| rather
+% than nothing when given a character code outside $[0,255]$. We
+% detect the presence of bad characters using a flag and only produce
+% a single error after the \texttt{e}-expanding assignment.
+% \begin{macrocode}
+\bool_lazy_any:nTF
+ {
+ \sys_if_engine_luatex_p:
+ \sys_if_engine_xetex_p:
+ }
+ {
+ \cs_new_protected:Npn \@@_convert_encode_:
+ { \@@_convert_gmap_internal:N \@@_encode_native_char:n }
+ \cs_new:Npn \@@_encode_native_char:n #1
+ { \char_generate:nn {#1} {12} }
+ }
+ {
+ \cs_new_protected:Npn \@@_convert_encode_:
+ {
+ \flag_clear:N \l_@@_error_flag
+ \@@_convert_gmap_internal:N \@@_encode_native_char:n
+ \@@_if_flag_error:Nne \l_@@_error_flag
+ { native-overflow } { }
+ }
+ \cs_new:Npn \@@_encode_native_char:n #1
+ {
+ \if_int_compare:w #1 > \c_@@_max_byte_int
+ \flag_raise:N \l_@@_error_flag
+ ?
+ \else:
+ \char_generate:nn {#1} {12}
+ \fi:
+ }
+ \msg_new:nnnn { str } { native-overflow }
+ { Character~code~too~large~for~this~engine. }
+ {
+ This~engine~only~support~8-bit~characters:~
+ valid~character~codes~are~in~the~range~[0,255].~
+ To~manipulate~arbitrary~Unicode,~use~LuaTeX~or~XeTeX.
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{\texttt{clist}}
+%
+% \begin{macro}{\@@_convert_decode_clist:}
+% \begin{macro}[rEXP]{\@@_decode_clist_char:n}
+% Convert each integer to the internal form. We first turn
+% \cs{g_@@_result_tl} into a clist variable, as this avoids problems
+% with leading or trailing commas.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_convert_decode_clist:
+ {
+ \clist_gset:No \g_@@_result_tl \g_@@_result_tl
+ \__kernel_tl_gset:Nx \g_@@_result_tl
+ {
+ \exp_args:No \clist_map_function:nN
+ \g_@@_result_tl \@@_decode_clist_char:n
+ }
+ }
+\cs_new:Npn \@@_decode_clist_char:n #1
+ { #1 \s_@@ \int_eval:n {#1} \s_@@ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert_encode_clist:}
+% \begin{macro}[rEXP]{\@@_encode_clist_char:n}
+% Convert the internal list of character codes to a comma-list of
+% character codes. The first line produces a comma-list with a
+% leading comma, removed in the next step (this also works in the
+% empty case, since \cs{tl_tail:N} does not trigger an error in this
+% case).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_convert_encode_clist:
+ {
+ \@@_convert_gmap_internal:N \@@_encode_clist_char:n
+ \__kernel_tl_gset:Nx \g_@@_result_tl { \tl_tail:N \g_@@_result_tl }
+ }
+\cs_new:Npn \@@_encode_clist_char:n #1 { , #1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{8-bit encodings}
+%
+% It is not clear in what situations 8-bit encodings are used, hence it
+% is not clear what should be optimized. The current approach is
+% reasonably efficient to convert long strings, and it scales well when
+% using many different encodings.
+%
+% The data needed to support a given 8-bit encoding is stored in a file
+% that consists of a single function call
+% \begin{quote}\ttfamily
+% \cs{@@_declare_eight_bit_encoding:nnnn} \Arg{name} \Arg{modulo}
+% \Arg{mapping} \Arg{missing}
+% \end{quote}
+% This declares the encoding \meta{name} to map bytes to Unicode
+% characters according to the \meta{mapping}, and map those bytes which
+% are not mentioned in the \meta{mapping} either to the replacement
+% character (if they appear in \meta{missing}), or to themselves. The
+% \meta{mapping} argument is a token list of pairs \Arg{byte}
+% \Arg{Unicode} expressed in uppercase hexadecimal notation. The
+% \meta{missing} argument is a token list of \Arg{byte}. Every
+% \meta{byte} which does not appear in the \meta{mapping} nor the
+% \meta{missing} lists maps to itself in Unicode, so for instance the
+% \texttt{latin1} encoding has empty \meta{mapping} and \meta{missing}
+% lists. The \meta{modulo} is a (decimal) integer between $256$ and
+% $558$ inclusive, modulo which all Unicode code points supported by the
+% encodings must be different.
+%
+% We use two integer arrays per encoding. When decoding we only use the
+% \texttt{decode} integer array, with entry $n+1$ (offset needed because
+% integer array indices start at~$1$) equal to the Unicode code point
+% that corresponds to the $n$-th byte in the encoding under
+% consideration, or $-1$ if the given byte is invalid in this encoding.
+% When encoding we use both arrays: upon seeing a code point~$n$, we
+% look up the entry ($1$~plus) $n$ modulo some number $M$ in the
+% \texttt{encode} array, which tells us the byte that might encode the
+% given Unicode code point, then we check in the \texttt{decode} array
+% that indeed this byte encodes the Unicode code point we want. Here,
+% $M$ is an encoding-dependent integer between $256$ and $558$ (it turns
+% out), chosen so that among the Unicode code points that can be validly
+% represented in the given encoding, no pair of code points have the
+% same value modulo~$M$.
+%
+% \begin{macro}
+% {
+% \@@_declare_eight_bit_encoding:nnnn,
+% \@@_declare_eight_bit_aux:NNnnn,
+% \@@_declare_eight_bit_loop:Nnn,
+% \@@_declare_eight_bit_loop:Nn
+% }
+% Loop through both lists of bytes to fill in the \texttt{decode}
+% integer array, then fill the \texttt{encode} array accordingly.
+% For bytes that are invalid in the given encoding, store $-1$ in the
+% \texttt{decode} array.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_declare_eight_bit_encoding:nnnn #1
+ {
+ \tl_set:Nn \l_@@_internal_tl {#1}
+ \cs_new_protected:cpn { @@_convert_decode_#1: }
+ { \@@_convert_decode_eight_bit:n {#1} }
+ \cs_new_protected:cpn { @@_convert_encode_#1: }
+ { \@@_convert_encode_eight_bit:n {#1} }
+ \exp_args:Ncc \@@_declare_eight_bit_aux:NNnnn
+ { g_@@_decode_#1_intarray } { g_@@_encode_#1_intarray }
+ }
+\cs_new_protected:Npn \@@_declare_eight_bit_aux:NNnnn #1#2#3#4#5
+ {
+ \intarray_new:Nn #1 { 256 }
+ \int_step_inline:nnn { 0 } { 255 }
+ { \intarray_gset:Nnn #1 { 1 + ##1 } {##1} }
+ \@@_declare_eight_bit_loop:Nnn #1
+ #4 { \s_@@_stop \prg_break: } { }
+ \prg_break_point:
+ \@@_declare_eight_bit_loop:Nn #1
+ #5 { \s_@@_stop \prg_break: }
+ \prg_break_point:
+ \intarray_new:Nn #2 {#3}
+ \int_step_inline:nnn { 0 } { 255 }
+ {
+ \int_compare:nNnF { \intarray_item:Nn #1 { 1 + ##1 } } = { -1 }
+ {
+ \intarray_gset:Nnn #2
+ {
+ 1 +
+ \int_mod:nn { \intarray_item:Nn #1 { 1 + ##1 } }
+ { \intarray_count:N #2 }
+ }
+ {##1}
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_declare_eight_bit_loop:Nnn #1#2#3
+ {
+ \@@_use_none_delimit_by_s_stop:w #2 \s_@@_stop
+ \intarray_gset:Nnn #1 { 1 + "#2 } { "#3 }
+ \@@_declare_eight_bit_loop:Nnn #1
+ }
+\cs_new_protected:Npn \@@_declare_eight_bit_loop:Nn #1#2
+ {
+ \@@_use_none_delimit_by_s_stop:w #2 \s_@@_stop
+ \intarray_gset:Nnn #1 { 1 + "#2 } { -1 }
+ \@@_declare_eight_bit_loop:Nn #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert_decode_eight_bit:n}
+% \begin{macro}[rEXP]{\@@_decode_eight_bit_aux:n, \@@_decode_eight_bit_aux:Nn}
+% The map from bytes to Unicode code points is in the \texttt{decode}
+% array corresponding to the given encoding. Define \cs{@@_tmp:w} and
+% pass it successively all bytes in the string. It produces an
+% internal representation with suitable \cs{s_@@} inserted, and the
+% corresponding code point is obtained by looking it up in the integer
+% array. If the entry is $-1$ then issue a replacement character and
+% raise the flag indicating that there was an error.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_convert_decode_eight_bit:n #1
+ {
+ \cs_set:Npe \@@_tmp:w
+ {
+ \exp_not:N \@@_decode_eight_bit_aux:Nn
+ \exp_not:c { g_@@_decode_#1_intarray }
+ }
+ \flag_clear:N \l_@@_error_flag
+ \@@_convert_gmap:N \@@_tmp:w
+ \@@_if_flag_error:Nne \l_@@_error_flag { decode-8-bit } {#1}
+ }
+\cs_new:Npn \@@_decode_eight_bit_aux:Nn #1#2
+ {
+ #2 \s_@@
+ \exp_args:Nf \@@_decode_eight_bit_aux:n
+ { \intarray_item:Nn #1 { 1 + `#2 } }
+ \s_@@
+ }
+\cs_new:Npn \@@_decode_eight_bit_aux:n #1
+ {
+ \if_int_compare:w #1 < \c_zero_int
+ \flag_raise:N \l_@@_error_flag
+ \int_value:w \c_@@_replacement_char_int
+ \else:
+ #1
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert_encode_eight_bit:n}
+% \begin{macro}[rEXP]{\@@_encode_eight_bit_aux:nnN, \@@_encode_eight_bit_aux:NNn}
+% It is not practical to make an integer array with indices in the
+% full Unicode range, so we work modulo some number, which is simply
+% the size of the \texttt{encode} integer array for the given
+% encoding. This gives us a candidate byte for representing a given
+% Unicode code point. Of course taking the modulo leads to collisions
+% so we check in the \texttt{decode} array that the byte we got is
+% indeed correct. Otherwise the Unicode code point we started from is
+% simply not representable in the given encoding.
+% \begin{macrocode}
+\int_new:N \l_@@_modulo_int
+\cs_new_protected:Npn \@@_convert_encode_eight_bit:n #1
+ {
+ \cs_set:Npe \@@_tmp:w
+ {
+ \exp_not:N \@@_encode_eight_bit_aux:NNn
+ \exp_not:c { g_@@_encode_#1_intarray }
+ \exp_not:c { g_@@_decode_#1_intarray }
+ }
+ \flag_clear:N \l_@@_error_flag
+ \@@_convert_gmap_internal:N \@@_tmp:w
+ \@@_if_flag_error:Nne \l_@@_error_flag { encode-8-bit } {#1}
+ }
+\cs_new:Npn \@@_encode_eight_bit_aux:NNn #1#2#3
+ {
+ \exp_args:Nf \@@_encode_eight_bit_aux:nnN
+ {
+ \intarray_item:Nn #1
+ { 1 + \int_mod:nn {#3} { \intarray_count:N #1 } }
+ }
+ {#3}
+ #2
+ }
+\cs_new:Npn \@@_encode_eight_bit_aux:nnN #1#2#3
+ {
+ \int_compare:nNnTF { \intarray_item:Nn #3 { 1 + #1 } } = {#2}
+ { \@@_output_byte:n {#1} }
+ { \flag_raise:N \l_@@_error_flag }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% General messages, and messages for the encodings and escapings loaded
+% by default (\enquote{native}, and \enquote{bytes}).
+% \begin{macrocode}
+\msg_new:nnn { str } { unknown-esc }
+ { Escaping~scheme~'#1'~(filtered:~'#2')~unknown. }
+\msg_new:nnn { str } { unknown-enc }
+ { Encoding~scheme~'#1'~(filtered:~'#2')~unknown. }
+\msg_new:nnnn { str } { native-escaping }
+ { The~'native'~encoding~scheme~does~not~support~any~escaping. }
+ {
+ Since~native~strings~do~not~consist~in~bytes,~
+ none~of~the~escaping~methods~make~sense.~
+ The~specified~escaping,~'#1',~will~be~ignored.
+ }
+\msg_new:nnn { str } { file-not-found }
+ { File~'l3str-#1.def'~not~found. }
+% \end{macrocode}
+%
+% Message used when the \enquote{bytes} unescaping fails because the
+% string given to \cs{str_set_convert:Nnnn} contains a non-byte. This
+% cannot happen for the -8-bit engines.
+% Messages used for other escapings and
+% encodings are defined in each definition file.
+% \begin{macrocode}
+\bool_lazy_any:nT
+ {
+ \sys_if_engine_luatex_p:
+ \sys_if_engine_xetex_p:
+ }
+ {
+ \msg_new:nnnn { str } { non-byte }
+ { String~invalid~in~escaping~'#1':~it~may~only~contain~bytes. }
+ {
+ Some~characters~in~the~string~you~asked~to~convert~are~not~
+ 8-bit~characters.~Perhaps~the~string~is~a~'native'~Unicode~string?~
+ If~it~is,~try~using\\
+ \\
+ \iow_indent:n
+ {
+ \iow_char:N\\str_set_convert:Nnnn \\
+ \ \ <str~var>~\{~<string>~\}~\{~native~\}~\{~<target~encoding>~\}
+ }
+ }
+ }
+% \end{macrocode}
+%
+% Those messages are used when converting to and from 8-bit encodings.
+% \begin{macrocode}
+\msg_new:nnnn { str } { decode-8-bit }
+ { Invalid~string~in~encoding~'#1'. }
+ {
+ LaTeX~came~across~a~byte~which~is~not~defined~to~represent~
+ any~character~in~the~encoding~'#1'.
+ }
+\msg_new:nnnn { str } { encode-8-bit }
+ { Unicode~string~cannot~be~converted~to~encoding~'#1'. }
+ {
+ The~encoding~'#1'~only~contains~a~subset~of~all~Unicode~characters.~
+ LaTeX~was~asked~to~convert~a~string~to~that~encoding,~but~that~
+ string~contains~a~character~that~'#1'~does~not~support.
+ }
+% \end{macrocode}
+%
+% \subsection{Escaping definitions}
+%
+% Several of those encodings are defined by the pdf file format. The
+% following byte storage methods are defined:
+% \begin{itemize}
+% \item \texttt{bytes} (default), non-bytes are filtered out, and
+% bytes are left untouched (this is defined by default);
+% \item \texttt{hex} or \texttt{hexadecimal}, as per the \pdfTeX{}
+% primitive \tn{pdfescapehex}
+% \item \texttt{name}, as per the \pdfTeX{} primitive
+% \tn{pdfescapename}
+% \item \texttt{string}, as per the \pdfTeX{} primitive
+% \tn{pdfescapestring}
+% \item \texttt{url}, as per the percent encoding of urls.
+% \end{itemize}
+%
+% \subsubsection{Unescape methods}
+%
+% \begin{macro}{\@@_convert_unescape_hex:}
+% \begin{macro}[rEXP]{\@@_unescape_hex_auxi:N}
+% \begin{macro}[rEXP]{\@@_unescape_hex_auxii:N}
+% Take chars two by two, and interpret each pair as the hexadecimal
+% code for a byte. Anything else than hexadecimal digits is ignored,
+% raising the flag. A string which contains an odd number of
+% hexadecimal digits gets |0| appended to it: this is equivalent to
+% appending a |0| in all cases, and dropping it if it is alone.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_convert_unescape_hex:
+ {
+ \group_begin:
+ \flag_clear:N \l_@@_error_flag
+ \int_set:Nn \tex_escapechar:D { 92 }
+ \__kernel_tl_gset:Nx \g_@@_result_tl
+ {
+ \@@_output_byte:w "
+ \exp_last_unbraced:Nf \@@_unescape_hex_auxi:N
+ { \tl_to_str:N \g_@@_result_tl }
+ 0 { ? 0 - 1 \prg_break: }
+ \prg_break_point:
+ \@@_output_end:
+ }
+ \@@_if_flag_error:Nne \l_@@_error_flag { unescape-hex } { }
+ \group_end:
+ }
+\cs_new:Npn \@@_unescape_hex_auxi:N #1
+ {
+ \use_none:n #1
+ \@@_hexadecimal_use:NTF #1
+ { \@@_unescape_hex_auxii:N }
+ {
+ \flag_raise:N \l_@@_error_flag
+ \@@_unescape_hex_auxi:N
+ }
+ }
+\cs_new:Npn \@@_unescape_hex_auxii:N #1
+ {
+ \use_none:n #1
+ \@@_hexadecimal_use:NTF #1
+ {
+ \@@_output_end:
+ \@@_output_byte:w " \@@_unescape_hex_auxi:N
+ }
+ {
+ \flag_raise:N \l_@@_error_flag
+ \@@_unescape_hex_auxii:N
+ }
+ }
+\msg_new:nnnn { str } { unescape-hex }
+ { String~invalid~in~escaping~'hex':~only~hexadecimal~digits~allowed. }
+ {
+ Some~characters~in~the~string~you~asked~to~convert~are~not~
+ hexadecimal~digits~(0-9,~A-F,~a-f)~nor~spaces.
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert_unescape_name:}
+% \begin{macro}[rEXP]{\@@_unescape_name_loop:wNN}
+% \begin{macro}{\@@_convert_unescape_url:}
+% \begin{macro}[rEXP]{\@@_unescape_url_loop:wNN}
+% The \cs{@@_convert_unescape_name:} function replaces each
+% occurrence of |#| followed by two hexadecimal digits in
+% \cs{g_@@_result_tl} by the corresponding byte. The \texttt{url}
+% function is identical, with escape character |%| instead of |#|.
+% Thus we define the two together. The arguments of \cs{@@_tmp:w} are
+% the character code of |#| or |%| in hexadecimal, the name of the
+% main function to define, and the name of the auxiliary which
+% performs the loop.
+%
+% The looping auxiliary |#3| finds the next escape character, reads
+% the following two characters, and tests them. The test
+% \cs{@@_hexadecimal_use:NTF} leaves the upper-case digit in the
+% input stream, hence we surround the test with
+% \cs{@@_output_byte:w}~|"| and \cs{@@_output_end:}. If both
+% characters are hexadecimal digits, they should be removed before
+% looping: this is done by \cs{use_i:nnn}. If one of the characters
+% is not a hexadecimal digit, then feed |"#1| to
+% \cs{@@_output_byte:w} to produce the escape character, raise the
+% flag, and call the looping function followed by the two characters
+% (remove \cs{use_i:nnn}).
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1#2#3
+ {
+ \cs_new_protected:cpn { @@_convert_unescape_#2: }
+ {
+ \group_begin:
+ \flag_clear:N \l_@@_byte_flag
+ \flag_clear:N \l_@@_error_flag
+ \int_set:Nn \tex_escapechar:D { 92 }
+ \__kernel_tl_gset:Nx \g_@@_result_tl
+ {
+ \exp_after:wN #3 \g_@@_result_tl
+ #1 ? { ? \prg_break: }
+ \prg_break_point:
+ }
+ \@@_if_flag_error:Nne \l_@@_byte_flag { non-byte } { #2 }
+ \@@_if_flag_error:Nne \l_@@_error_flag { unescape-#2 } { }
+ \group_end:
+ }
+ \cs_new:Npn #3 ##1#1##2##3
+ {
+ \@@_filter_bytes:n {##1}
+ \use_none:n ##3
+ \@@_output_byte:w "
+ \@@_hexadecimal_use:NTF ##2
+ {
+ \@@_hexadecimal_use:NTF ##3
+ { }
+ {
+ \flag_raise:N \l_@@_error_flag
+ * 0 + `#1 \use_i:nn
+ }
+ }
+ {
+ \flag_raise:N \l_@@_error_flag
+ 0 + `#1 \use_i:nn
+ }
+ \@@_output_end:
+ \use_i:nnn #3 ##2##3
+ }
+ \msg_new:nnnn { str } { unescape-#2 }
+ { String~invalid~in~escaping~'#2'. }
+ {
+ LaTeX~came~across~the~escape~character~'#1'~not~followed~by~
+ two~hexadecimal~digits.~This~is~invalid~in~the~escaping~'#2'.
+ }
+ }
+\exp_after:wN \@@_tmp:w \c_hash_str { name }
+ \@@_unescape_name_loop:wNN
+\exp_after:wN \@@_tmp:w \c_percent_str { url }
+ \@@_unescape_url_loop:wNN
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert_unescape_string:}
+% \begin{macro}[rEXP]{\@@_unescape_string_newlines:wN}
+% \begin{macro}[rEXP]{\@@_unescape_string_loop:wNNN}
+% \begin{macro}[rEXP]{\@@_unescape_string_repeat:NNNNNN}
+% The \texttt{string} escaping is somewhat similar to the
+% \texttt{name} and \texttt{url} escapings, with escape character |\|.
+% The first step is to convert all three line endings, |^^J|, |^^M|,
+% and |^^M^^J| to the common |^^J|, as per the \textsc{pdf}
+% specification. This step cannot raise the flag.
+%
+% Then the following escape sequences are decoded.
+% \begin{itemize}\def\makelabel#1{\hss\llap{\ttfamily\string#1}}
+% \item[\n] Line feed ($10$)
+% \item[\r] Carriage return ($13$)
+% \item[\t] Horizontal tab ($9$)
+% \item[\b] Backspace ($8$)
+% \item[\f] Form feed ($12$)
+% \item[\(] Left parenthesis
+% \item[\)] Right parenthesis
+% \item[\\] Backslash
+% \item[\ddd] (backslash followed by $1$ to $3$ octal digits) Byte
+% \texttt{ddd} (octal), subtracting $256$ in case of overflow.
+% \end{itemize}
+% If followed by an end-of-line character, the backslash and the
+% end-of-line are ignored. If followed by anything else, the backslash
+% is ignored, raising the error flag.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_other:N \^^J
+ \char_set_catcode_other:N \^^M
+ \cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \cs_new_protected:Npn \@@_convert_unescape_string:
+ {
+ \group_begin:
+ \flag_clear:N \l_@@_byte_flag
+ \flag_clear:N \l_@@_error_flag
+ \int_set:Nn \tex_escapechar:D { 92 }
+ \__kernel_tl_gset:Nx \g_@@_result_tl
+ {
+ \exp_after:wN \@@_unescape_string_newlines:wN
+ \g_@@_result_tl \prg_break: ^^M ?
+ \prg_break_point:
+ }
+ \__kernel_tl_gset:Nx \g_@@_result_tl
+ {
+ \exp_after:wN \@@_unescape_string_loop:wNNN
+ \g_@@_result_tl #1 ?? { ? \prg_break: }
+ \prg_break_point:
+ }
+ \@@_if_flag_error:Nne \l_@@_byte_flag { non-byte } { string }
+ \@@_if_flag_error:Nne \l_@@_error_flag { unescape-string } { }
+ \group_end:
+ }
+ }
+ \exp_args:No \@@_tmp:w { \c_backslash_str }
+ \exp_last_unbraced:NNNNo
+ \cs_new:Npn \@@_unescape_string_loop:wNNN #1 \c_backslash_str #2#3#4
+ {
+ \@@_filter_bytes:n {#1}
+ \use_none:n #4
+ \@@_output_byte:w '
+ \@@_octal_use:NTF #2
+ {
+ \@@_octal_use:NTF #3
+ {
+ \@@_octal_use:NTF #4
+ {
+ \if_int_compare:w #2 > 3 \exp_stop_f:
+ - 256
+ \fi:
+ \@@_unescape_string_repeat:NNNNNN
+ }
+ { \@@_unescape_string_repeat:NNNNNN ? }
+ }
+ { \@@_unescape_string_repeat:NNNNNN ?? }
+ }
+ {
+ \str_case_e:nnF {#2}
+ {
+ { \c_backslash_str } { 134 }
+ { ( } { 50 }
+ { ) } { 51 }
+ { r } { 15 }
+ { f } { 14 }
+ { n } { 12 }
+ { t } { 11 }
+ { b } { 10 }
+ { ^^J } { 0 - 1 }
+ }
+ {
+ \flag_raise:N \l_@@_error_flag
+ 0 - 1 \use_i:nn
+ }
+ }
+ \@@_output_end:
+ \use_i:nn \@@_unescape_string_loop:wNNN #2#3#4
+ }
+ \cs_new:Npn \@@_unescape_string_repeat:NNNNNN #1#2#3#4#5#6
+ { \@@_output_end: \@@_unescape_string_loop:wNNN }
+ \cs_new:Npn \@@_unescape_string_newlines:wN #1 ^^M #2
+ {
+ #1
+ \if_charcode:w ^^J #2 \else: ^^J \fi:
+ \@@_unescape_string_newlines:wN #2
+ }
+ \msg_new:nnnn { str } { unescape-string }
+ { String~invalid~in~escaping~'string'. }
+ {
+ LaTeX~came~across~an~escape~character~'\c_backslash_str'~
+ not~followed~by~any~of:~'n',~'r',~'t',~'b',~'f',~'(',~')',~
+ '\c_backslash_str',~one~to~three~octal~digits,~or~the~end~
+ of~a~line.
+ }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Escape methods}
+%
+% Currently, none of the escape methods can lead to errors, assuming
+% that their input is made out of bytes.
+%
+% \begin{macro}{\@@_convert_escape_hex:}
+% \begin{macro}[rEXP]{\@@_escape_hex_char:N}
+% Loop and convert each byte to hexadecimal.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_convert_escape_hex:
+ { \@@_convert_gmap:N \@@_escape_hex_char:N }
+\cs_new:Npn \@@_escape_hex_char:N #1
+ { \@@_output_hexadecimal:n { `#1 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert_escape_name:}
+% \begin{macro}[rEXP]{\@@_escape_name_char:n}
+% \begin{macro}[rEXP]{\@@_if_escape_name:nTF}
+% \begin{variable}{\c_@@_escape_name_str}
+% \begin{variable}{\c_@@_escape_name_not_str}
+% For each byte, test whether it should be output as is, or be
+% \enquote{hash-encoded}. Roughly, bytes outside the range
+% $[\hexnum{2A},\hexnum{7E}]$ are hash-encoded. We keep two lists of
+% exceptions: characters in \cs{c_@@_escape_name_not_str} are not
+% hash-encoded, and characters in the \cs{c_@@_escape_name_str} are
+% encoded.
+% \begin{macrocode}
+\str_const:Nn \c_@@_escape_name_not_str { ! " $ & ' } %$
+\str_const:Nn \c_@@_escape_name_str { {}/<>[] }
+\cs_new_protected:Npn \@@_convert_escape_name:
+ { \@@_convert_gmap:N \@@_escape_name_char:n }
+\cs_new:Npn \@@_escape_name_char:n #1
+ {
+ \@@_if_escape_name:nTF {#1} {#1}
+ { \c_hash_str \@@_output_hexadecimal:n {`#1} }
+ }
+\prg_new_conditional:Npnn \@@_if_escape_name:n #1 { TF }
+ {
+ \if_int_compare:w `#1 < "2A \exp_stop_f:
+ \@@_if_contains_char:NnTF \c_@@_escape_name_not_str {#1}
+ \prg_return_true: \prg_return_false:
+ \else:
+ \if_int_compare:w `#1 > "7E \exp_stop_f:
+ \prg_return_false:
+ \else:
+ \@@_if_contains_char:NnTF \c_@@_escape_name_str {#1}
+ \prg_return_false: \prg_return_true:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert_escape_string:}
+% \begin{macro}[rEXP]{\@@_escape_string_char:N}
+% \begin{macro}[rEXP]{\@@_if_escape_string:NTF}
+% \begin{variable}{\c_@@_escape_string_str}
+% Any character below (and including) space, and any character above
+% (and including) \texttt{del}, are converted to octal. One backslash
+% is added before each parenthesis and backslash.
+% \begin{macrocode}
+\str_const:Ne \c_@@_escape_string_str
+ { \c_backslash_str ( ) }
+\cs_new_protected:Npn \@@_convert_escape_string:
+ { \@@_convert_gmap:N \@@_escape_string_char:N }
+\cs_new:Npn \@@_escape_string_char:N #1
+ {
+ \@@_if_escape_string:NTF #1
+ {
+ \@@_if_contains_char:NnT
+ \c_@@_escape_string_str {#1}
+ { \c_backslash_str }
+ #1
+ }
+ {
+ \c_backslash_str
+ \int_div_truncate:nn {`#1} {64}
+ \int_mod:nn { \int_div_truncate:nn {`#1} { 8 } } { 8 }
+ \int_mod:nn {`#1} { 8 }
+ }
+ }
+\prg_new_conditional:Npnn \@@_if_escape_string:N #1 { TF }
+ {
+ \if_int_compare:w `#1 < "27 \exp_stop_f:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w `#1 > "7A \exp_stop_f:
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert_escape_url:}
+% \begin{macro}[rEXP]{\@@_escape_url_char:n}
+% \begin{macro}[rEXP]{\@@_if_escape_url:nTF}
+% This function is similar to \cs{@@_convert_escape_name:}, escaping
+% different characters.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_convert_escape_url:
+ { \@@_convert_gmap:N \@@_escape_url_char:n }
+\cs_new:Npn \@@_escape_url_char:n #1
+ {
+ \@@_if_escape_url:nTF {#1} {#1}
+ { \c_percent_str \@@_output_hexadecimal:n { `#1 } }
+ }
+\prg_new_conditional:Npnn \@@_if_escape_url:n #1 { TF }
+ {
+ \if_int_compare:w `#1 < "30 \exp_stop_f:
+ \@@_if_contains_char:nnTF { "-. } {#1}
+ \prg_return_true: \prg_return_false:
+ \else:
+ \if_int_compare:w `#1 > "7E \exp_stop_f:
+ \prg_return_false:
+ \else:
+ \@@_if_contains_char:nnTF { : ; = ? @ [ ] } {#1}
+ \prg_return_false: \prg_return_true:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Encoding definitions}
+%
+% The \texttt{native} encoding is automatically defined. Other encodings
+% are loaded as needed. The following encodings are supported:
+% \begin{itemize}
+% \item \textsc{utf-8};
+% \item \textsc{utf-16}, big-, little-endian, or with byte order mark;
+% \item \textsc{utf-32}, big-, little-endian, or with byte order mark;
+% \item the \textsc{iso 8859} code pages, numbered from $1$ to $16$,
+% skipping the inexistent \textsc{iso 8859-12}.
+% \end{itemize}
+%
+% \subsubsection{\textsc{utf-8} support}
+%
+% \begin{macro}{\@@_convert_encode_utf8:}
+% \begin{macro}[rEXP]{\@@_encode_utf_viii_char:n}
+% \begin{macro}[rEXP]{\@@_encode_utf_viii_loop:wwnnw}
+% Loop through the internal string, and convert each character to its
+% \textsc{utf-8} representation. The representation is built from the
+% right-most (least significant) byte to the left-most (most
+% significant) byte. Continuation bytes are in the range $[128,191]$,
+% taking $64$ different values, hence we roughly want to express the
+% character code in base $64$, shifting the first digit in the
+% representation by some number depending on how many continuation
+% bytes there are. In the range $[0,127]$, output the corresponding
+% byte directly. In the range $[128,2047]$, output the remainder
+% modulo $64$, plus $128$ as a continuation byte, then output the
+% quotient (which is in the range $[0,31]$), shifted by $192$. In the
+% next range, $[2048,65535]$, split the character code into residue
+% and quotient modulo $64$, output the residue as a first continuation
+% byte, then repeat; this leaves us with a quotient in the range
+% $[0,15]$, which we output shifted by $224$. The last range,
+% $[65536,1114111]$, follows the same pattern: once we realize that
+% dividing twice by $64$ leaves us with a number larger than $15$, we
+% repeat, producing a last continuation byte, and offset the quotient
+% by $240$ for the leading byte.
+%
+% How is that implemented? \cs{@@_encode_utf_vii_loop:wwnnw} takes
+% successive quotients as its first argument, the quotient from the
+% previous step as its second argument (except in step~$1$), the bound
+% for quotients that trigger one more step or not, and finally the
+% offset used if this step should produce the leading byte. Leading
+% bytes can be in the ranges $[0,127]$, $[192,223]$, $[224,239]$, and
+% $[240,247]$ (really, that last limit should be $244$ because Unicode
+% stops at the code point $1114111$). At each step, if the quotient
+% |#1| is less than the limit |#3| for that range, output the leading
+% byte (|#1| shifted by |#4|) and stop. Otherwise, we need one more
+% step: use the quotient of |#1| by $64$, and |#1| as arguments for
+% the looping auxiliary, and output the continuation byte
+% corresponding to the remainder $|#2|-64|#1|+128$. The bizarre
+% construction |- 1 + 0 *| removes the spurious initial
+% continuation byte (better methods welcome).
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_convert_encode_utf8: }
+ { \@@_convert_gmap_internal:N \@@_encode_utf_viii_char:n }
+\cs_new:Npn \@@_encode_utf_viii_char:n #1
+ {
+ \@@_encode_utf_viii_loop:wwnnw #1 ; - 1 + 0 * ;
+ { 128 } { 0 }
+ { 32 } { 192 }
+ { 16 } { 224 }
+ { 8 } { 240 }
+ \s_@@_stop
+ }
+\cs_new:Npn \@@_encode_utf_viii_loop:wwnnw #1; #2; #3#4 #5 \s_@@_stop
+ {
+ \if_int_compare:w #1 < #3 \exp_stop_f:
+ \@@_output_byte:n { #1 + #4 }
+ \exp_after:wN \@@_use_none_delimit_by_s_stop:w
+ \fi:
+ \exp_after:wN \@@_encode_utf_viii_loop:wwnnw
+ \int_value:w \int_div_truncate:nn {#1} {64} ; #1 ;
+ #5 \s_@@_stop
+ \@@_output_byte:n { #2 - 64 * ( #1 - 2 ) }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}
+% {
+% @@_missing ,
+% @@_extra ,
+% @@_overlong ,
+% @@_overflow ,
+% }
+% When decoding a string that is purportedly in the \textsc{utf-8}
+% encoding, four different errors can occur, signalled by a specific
+% flag for each (we define those flags using \cs{flag_clear_new:N}
+% rather than \cs{flag_new:N}, because they are shared with other
+% encoding definition files).
+% \begin{itemize}
+% \item \enquote{Missing continuation byte}: a leading byte is not
+% followed by the right number of continuation bytes.
+% \item \enquote{Extra continuation byte}: a continuation byte
+% appears where it was not expected, \emph{i.e.}, not after an
+% appropriate leading byte.
+% \item \enquote{Overlong}: a Unicode character is expressed using
+% more bytes than necessary, for instance, \hexnum{C0}\hexnum{80}
+% for the code point $0$, instead of a single null byte.
+% \item \enquote{Overflow}: this occurs when decoding produces
+% Unicode code points greater than $1114111$.
+% \end{itemize}
+% We only raise one \LaTeX3 error message, combining all the errors
+% which occurred. In the short message, the leading comma must be
+% removed to get a grammatically correct sentence. In the long text,
+% first remind the user what a correct \textsc{utf-8} string should
+% look like, then add error-specific information.
+% \begin{macrocode}
+\flag_clear_new:N \l_@@_missing_flag
+\flag_clear_new:N \l_@@_extra_flag
+\flag_clear_new:N \l_@@_overlong_flag
+\flag_clear_new:N \l_@@_overflow_flag
+\msg_new:nnnn { str } { utf8-decode }
+ {
+ Invalid~UTF-8~string:
+ \exp_last_unbraced:Nf \use_none:n
+ {
+ \@@_if_flag_times:NT \l_@@_missing_flag { ,~missing~continuation~byte }
+ \@@_if_flag_times:NT \l_@@_extra_flag { ,~extra~continuation~byte }
+ \@@_if_flag_times:NT \l_@@_overlong_flag { ,~overlong~form }
+ \@@_if_flag_times:NT \l_@@_overflow_flag { ,~code~point~too~large }
+ }
+ .
+ }
+ {
+ In~the~UTF-8~encoding,~each~Unicode~character~consists~in~
+ 1~to~4~bytes,~with~the~following~bit~pattern: \\
+ \iow_indent:n
+ {
+ Code~point~\ \ \ \ <~128:~0xxxxxxx \\
+ Code~point~\ \ \ <~2048:~110xxxxx~10xxxxxx \\
+ Code~point~\ \ <~65536:~1110xxxx~10xxxxxx~10xxxxxx \\
+ Code~point~ <~1114112:~11110xxx~10xxxxxx~10xxxxxx~10xxxxxx \\
+ }
+ Bytes~of~the~form~10xxxxxx~are~called~continuation~bytes.
+ \flag_if_raised:NT \l_@@_missing_flag
+ {
+ \\\\
+ A~leading~byte~(in~the~range~[192,255])~was~not~followed~by~
+ the~appropriate~number~of~continuation~bytes.
+ }
+ \flag_if_raised:NT \l_@@_extra_flag
+ {
+ \\\\
+ LaTeX~came~across~a~continuation~byte~when~it~was~not~expected.
+ }
+ \flag_if_raised:NT \l_@@_overlong_flag
+ {
+ \\\\
+ Every~Unicode~code~point~must~be~expressed~in~the~shortest~
+ possible~form.~For~instance,~'0xC0'~'0x83'~is~not~a~valid~
+ representation~for~the~code~point~3.
+ }
+ \flag_if_raised:NT \l_@@_overflow_flag
+ {
+ \\\\
+ Unicode~limits~code~points~to~the~range~[0,1114111].
+ }
+ }
+\prop_gput:Nnn \g_msg_module_name_prop { str } { LaTeX }
+\prop_gput:Nnn \g_msg_module_type_prop { str } { }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_convert_decode_utf8:}
+% \begin{macro}[rEXP]
+% {
+% \@@_decode_utf_viii_start:N,
+% \@@_decode_utf_viii_continuation:wwN,
+% \@@_decode_utf_viii_aux:wNnnwN
+% }
+% \begin{macro}[rEXP]
+% {\@@_decode_utf_viii_overflow:w, \@@_decode_utf_viii_end:}
+% Decoding is significantly harder than encoding. As before, lower
+% some flags, which are tested at the end (in bulk, to trigger at most
+% one \LaTeX3 error, as explained above). We expect successive
+% multi-byte sequences of the form \meta{start byte}
+% \meta{continuation bytes}. The \texttt{_start} auxiliary tests the
+% first byte:
+% \begin{itemize}
+% \item $[0,\hexnum{7F}]$: the byte stands alone, and is converted
+% to its own character code;
+% \item $[\hexnum{80}, \hexnum{BF}]$: unexpected continuation byte,
+% raise the appropriate flag, and convert that byte to the
+% replacement character \hexnum{FFFD};
+% \item $[\hexnum{C0}, \hexnum{FF}]$: this byte should be followed
+% by some continuation byte(s).
+% \end{itemize}
+% In the first two cases, \cs{use_none_delimit_by_q_stop:w} removes
+% data that only the third case requires, namely the limits of ranges
+% of Unicode characters which can be expressed with $1$, $2$, $3$, or
+% $4$ bytes.
+%
+% We can now concentrate on the multi-byte case and the
+% \texttt{_continuation} auxiliary. We expect |#3| to be in the range
+% $[\hexnum{80}, \hexnum{BF}]$. The test for this goes as follows: if
+% the character code is less than \hexnum{80}, we compare it to
+% $-\hexnum{C0}$, yielding \texttt{false}; otherwise to \hexnum{C0},
+% yielding \texttt{true} in the range $[\hexnum{80}, \hexnum{BF}]$ and
+% \texttt{false} otherwise. If we find that the byte is not a
+% continuation range, stop the current slew of bytes, output the
+% replacement character, and continue parsing with the \texttt{_start}
+% auxiliary, starting at the byte we just tested. Once we know that
+% the byte is a continuation byte, leave it behind us in the input
+% stream, compute what code point the bytes read so far would produce,
+% and feed that number to the \texttt{_aux} function.
+%
+% The \texttt{_aux} function tests whether we should look for more
+% continuation bytes or not. If the number it receives as |#1| is less
+% than the maximum |#4| for the current range, then we are done: check
+% for an overlong representation by comparing |#1| with the maximum
+% |#3| for the previous range. Otherwise, we call the
+% \texttt{_continuation} auxiliary again, after shifting the
+% \enquote{current code point} by |#4| (maximum from the range we just
+% checked).
+%
+% Two additional tests are needed: if we reach the end of the list of
+% range maxima and we are still not done, then we are faced with an
+% overflow. Clean up, and again insert the code point \hexnum{FFFD}
+% for the replacement character. Also, every time we read a byte, we
+% need to check whether we reached the end of the string. In a correct
+% \textsc{utf-8} string, this happens automatically when the
+% \texttt{_start} auxiliary leaves its first argument in the input
+% stream: the end-marker begins with \cs{prg_break:}, which ends
+% the loop. On the other hand, if the end is reached when looking for
+% a continuation byte, the \cs{use_none:n} |#3| construction removes
+% the first token from the end-marker, and leaves the \texttt{_end}
+% auxiliary, which raises the appropriate error flag before ending the
+% mapping.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_convert_decode_utf8: }
+ {
+ \flag_clear:N \l_@@_error_flag
+ \flag_clear:N \l_@@_missing_flag
+ \flag_clear:N \l_@@_extra_flag
+ \flag_clear:N \l_@@_overlong_flag
+ \flag_clear:N \l_@@_overflow_flag
+ \__kernel_tl_gset:Nx \g_@@_result_tl
+ {
+ \exp_after:wN \@@_decode_utf_viii_start:N \g_@@_result_tl
+ { \prg_break: \@@_decode_utf_viii_end: }
+ \prg_break_point:
+ }
+ \@@_if_flag_error:Nne \l_@@_error_flag { utf8-decode } { }
+ }
+\cs_new:Npn \@@_decode_utf_viii_start:N #1
+ {
+ #1
+ \if_int_compare:w `#1 < "C0 \exp_stop_f:
+ \s_@@
+ \if_int_compare:w `#1 < "80 \exp_stop_f:
+ \int_value:w `#1
+ \else:
+ \flag_raise:N \l_@@_extra_flag
+ \flag_raise:N \l_@@_error_flag
+ \int_use:N \c_@@_replacement_char_int
+ \fi:
+ \else:
+ \exp_after:wN \@@_decode_utf_viii_continuation:wwN
+ \int_value:w \int_eval:n { `#1 - "C0 } \exp_after:wN
+ \fi:
+ \s_@@
+ \@@_use_none_delimit_by_s_stop:w {"80} {"800} {"10000} {"110000} \s_@@_stop
+ \@@_decode_utf_viii_start:N
+ }
+\cs_new:Npn \@@_decode_utf_viii_continuation:wwN
+ #1 \s_@@ #2 \@@_decode_utf_viii_start:N #3
+ {
+ \use_none:n #3
+ \if_int_compare:w `#3 <
+ \if_int_compare:w `#3 < "80 \exp_stop_f: - \fi:
+ "C0 \exp_stop_f:
+ #3
+ \exp_after:wN \@@_decode_utf_viii_aux:wNnnwN
+ \int_value:w \int_eval:n { #1 * "40 + `#3 - "80 } \exp_after:wN
+ \else:
+ \s_@@
+ \flag_raise:N \l_@@_missing_flag
+ \flag_raise:N \l_@@_error_flag
+ \int_use:N \c_@@_replacement_char_int
+ \fi:
+ \s_@@
+ #2
+ \@@_decode_utf_viii_start:N #3
+ }
+\cs_new:Npn \@@_decode_utf_viii_aux:wNnnwN
+ #1 \s_@@ #2#3#4 #5 \@@_decode_utf_viii_start:N #6
+ {
+ \if_int_compare:w #1 < #4 \exp_stop_f:
+ \s_@@
+ \if_int_compare:w #1 < #3 \exp_stop_f:
+ \flag_raise:N \l_@@_overlong_flag
+ \flag_raise:N \l_@@_error_flag
+ \int_use:N \c_@@_replacement_char_int
+ \else:
+ #1
+ \fi:
+ \else:
+ \if_meaning:w \s_@@_stop #5
+ \@@_decode_utf_viii_overflow:w #1
+ \fi:
+ \exp_after:wN \@@_decode_utf_viii_continuation:wwN
+ \int_value:w \int_eval:n { #1 - #4 } \exp_after:wN
+ \fi:
+ \s_@@
+ #2 {#4} #5
+ \@@_decode_utf_viii_start:N
+ }
+\cs_new:Npn \@@_decode_utf_viii_overflow:w #1 \fi: #2 \fi:
+ {
+ \fi: \fi:
+ \flag_raise:N \l_@@_overflow_flag
+ \flag_raise:N \l_@@_error_flag
+ \int_use:N \c_@@_replacement_char_int
+ }
+\cs_new:Npn \@@_decode_utf_viii_end:
+ {
+ \s_@@
+ \flag_raise:N \l_@@_missing_flag
+ \flag_raise:N \l_@@_error_flag
+ \int_use:N \c_@@_replacement_char_int \s_@@
+ \prg_break:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{\textsc{utf-16} support}
+%
+% The definitions are done in a category code regime where the bytes
+% $254$ and $255$ used by the byte order mark have catcode~$12$.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_other:N \^^fe
+ \char_set_catcode_other:N \^^ff
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_convert_encode_utf16: ,
+% \@@_convert_encode_utf16be: ,
+% \@@_convert_encode_utf16le: ,
+% }
+% \begin{macro}[rEXP]
+% {
+% \@@_encode_utf_xvi_aux:N ,
+% \@@_encode_utf_xvi_char:n ,
+% }
+% When the endianness is not specified, it is big-endian by default,
+% and we add a byte-order mark. Convert characters one by one in a
+% loop, with different behaviours depending on the character code.
+% \begin{itemize}
+% \item $[0, \hexnum{D7FF}]$: converted to two bytes;
+% \item $[\hexnum{D800}, \hexnum{DFFF}]$ are used as surrogates:
+% they cannot be converted and are replaced by the replacement
+% character;
+% \item $[\hexnum{E000}, \hexnum{FFFF}]$: converted to two bytes;
+% \item $[\hexnum{10000}, \hexnum{10FFFF}]$: converted to a pair of
+% surrogates, each two bytes. The magic \hexnum{D7C0} is
+% $\hexnum{D800}-\hexnum{10000}/\hexnum{400}$.
+% \end{itemize}
+% For the duration of this operation, \cs{@@_tmp:w} is defined as a
+% function to convert a number in the range $[0, \hexnum{FFFF}]$ to a
+% pair of bytes (either big endian or little endian), by feeding the
+% quotient of the division of |#1| by \hexnum{100}, followed by |#1|
+% to \cs{@@_encode_utf_xvi_be:nn} or its \texttt{le} analog: those
+% compute the remainder, and output two bytes for the quotient and
+% remainder.
+% \begin{macrocode}
+ \cs_new_protected:cpn { @@_convert_encode_utf16: }
+ {
+ \@@_encode_utf_xvi_aux:N \@@_output_byte_pair_be:n
+ \tl_gput_left:Ne \g_@@_result_tl { ^^fe ^^ff }
+ }
+ \cs_new_protected:cpn { @@_convert_encode_utf16be: }
+ { \@@_encode_utf_xvi_aux:N \@@_output_byte_pair_be:n }
+ \cs_new_protected:cpn { @@_convert_encode_utf16le: }
+ { \@@_encode_utf_xvi_aux:N \@@_output_byte_pair_le:n }
+ \cs_new_protected:Npn \@@_encode_utf_xvi_aux:N #1
+ {
+ \flag_clear:N \l_@@_error_flag
+ \cs_set_eq:NN \@@_tmp:w #1
+ \@@_convert_gmap_internal:N \@@_encode_utf_xvi_char:n
+ \@@_if_flag_error:Nne \l_@@_error_flag { utf16-encode } { }
+ }
+ \cs_new:Npn \@@_encode_utf_xvi_char:n #1
+ {
+ \if_int_compare:w #1 < "D800 \exp_stop_f:
+ \@@_tmp:w {#1}
+ \else:
+ \if_int_compare:w #1 < "10000 \exp_stop_f:
+ \if_int_compare:w #1 < "E000 \exp_stop_f:
+ \flag_raise:N \l_@@_error_flag
+ \@@_tmp:w { \c_@@_replacement_char_int }
+ \else:
+ \@@_tmp:w {#1}
+ \fi:
+ \else:
+ \exp_args:Nf \@@_tmp:w { \int_div_truncate:nn {#1} {"400} + "D7C0 }
+ \exp_args:Nf \@@_tmp:w { \int_mod:nn {#1} {"400} + "DC00 }
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}
+% {
+% @@_missing ,
+% @@_extra ,
+% @@_end ,
+% }
+% When encoding a Unicode string to \textsc{utf-16}, only one error
+% can occur: code points in the range $[\hexnum{D800},
+% \hexnum{DFFF}]$, corresponding to surrogates, cannot be encoded. We
+% use the all-purpose flag \texttt{@@_error} to signal that error.
+%
+% When decoding a Unicode string which is purportedly in
+% \textsc{utf-16}, three errors can occur: a missing trail surrogate,
+% an unexpected trail surrogate, and a string containing an odd number
+% of bytes.
+% \begin{macrocode}
+ \flag_clear_new:N \l_@@_missing_flag
+ \flag_clear_new:N \l_@@_extra_flag
+ \flag_clear_new:N \l_@@_end_flag
+ \msg_new:nnnn { str } { utf16-encode }
+ { Unicode~string~cannot~be~expressed~in~UTF-16:~surrogate. }
+ {
+ Surrogate~code~points~(in~the~range~[U+D800,~U+DFFF])~
+ can~be~expressed~in~the~UTF-8~and~UTF-32~encodings,~
+ but~not~in~the~UTF-16~encoding.
+ }
+ \msg_new:nnnn { str } { utf16-decode }
+ {
+ Invalid~UTF-16~string:
+ \exp_last_unbraced:Nf \use_none:n
+ {
+ \@@_if_flag_times:NT \l_@@_missing_flag { ,~missing~trail~surrogate }
+ \@@_if_flag_times:NT \l_@@_extra_flag { ,~extra~trail~surrogate }
+ \@@_if_flag_times:NT \l_@@_end_flag { ,~odd~number~of~bytes }
+ }
+ .
+ }
+ {
+ In~the~UTF-16~encoding,~each~Unicode~character~is~encoded~as~
+ 2~or~4~bytes: \\
+ \iow_indent:n
+ {
+ Code~point~in~[U+0000,~U+D7FF]:~two~bytes \\
+ Code~point~in~[U+D800,~U+DFFF]:~illegal \\
+ Code~point~in~[U+E000,~U+FFFF]:~two~bytes \\
+ Code~point~in~[U+10000,~U+10FFFF]:~
+ a~lead~surrogate~and~a~trail~surrogate \\
+ }
+ Lead~surrogates~are~pairs~of~bytes~in~the~range~[0xD800,~0xDBFF],~
+ and~trail~surrogates~are~in~the~range~[0xDC00,~0xDFFF].
+ \flag_if_raised:NT \l_@@_missing_flag
+ {
+ \\\\
+ A~lead~surrogate~was~not~followed~by~a~trail~surrogate.
+ }
+ \flag_if_raised:NT \l_@@_extra_flag
+ {
+ \\\\
+ LaTeX~came~across~a~trail~surrogate~when~it~was~not~expected.
+ }
+ \flag_if_raised:NT \l_@@_end_flag
+ {
+ \\\\
+ The~string~contained~an~odd~number~of~bytes.~This~is~invalid:~
+ the~basic~code~unit~for~UTF-16~is~16~bits~(2~bytes).
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \@@_convert_decode_utf16: ,
+% \@@_convert_decode_utf16be: ,
+% \@@_convert_decode_utf16le: ,
+% }
+% \begin{macro}{\@@_decode_utf_xvi_bom:NN, \@@_decode_utf_xvi:Nw}
+% As for \textsc{utf-8}, decoding \textsc{utf-16} is harder than
+% encoding it. If the endianness is unknown, check the first two
+% bytes: if those are \hexnum{FE} and \hexnum{FF} in either order,
+% remove them and use the corresponding endianness, otherwise assume
+% big-endianness. The three endianness cases are based on a common
+% auxiliary whose first argument is $1$ for big-endian and $2$ for
+% little-endian, and whose second argument, delimited by the scan mark
+% \cs{s_@@_stop}, is expanded once (the string may be long; passing
+% \cs{g_@@_result_tl} as an argument before expansion is cheaper).
+%
+% The \cs{@@_decode_utf_xvi:Nw} function defines \cs{@@_tmp:w} to
+% take two arguments and return the character code of the first one if
+% the string is big-endian, and the second one if the string is
+% little-endian, then loops over the string using
+% \cs{@@_decode_utf_xvi_pair:NN} described below.
+% \begin{macrocode}
+ \cs_new_protected:cpn { @@_convert_decode_utf16be: }
+ { \@@_decode_utf_xvi:Nw 1 \g_@@_result_tl \s_@@_stop }
+ \cs_new_protected:cpn { @@_convert_decode_utf16le: }
+ { \@@_decode_utf_xvi:Nw 2 \g_@@_result_tl \s_@@_stop }
+ \cs_new_protected:cpn { @@_convert_decode_utf16: }
+ {
+ \exp_after:wN \@@_decode_utf_xvi_bom:NN
+ \g_@@_result_tl \s_@@_stop \s_@@_stop \s_@@_stop
+ }
+ \cs_new_protected:Npn \@@_decode_utf_xvi_bom:NN #1#2
+ {
+ \str_if_eq:nnTF { #1#2 } { ^^ff ^^fe }
+ { \@@_decode_utf_xvi:Nw 2 }
+ {
+ \str_if_eq:nnTF { #1#2 } { ^^fe ^^ff }
+ { \@@_decode_utf_xvi:Nw 1 }
+ { \@@_decode_utf_xvi:Nw 1 #1#2 }
+ }
+ }
+ \cs_new_protected:Npn \@@_decode_utf_xvi:Nw #1#2 \s_@@_stop
+ {
+ \flag_clear:N \l_@@_error_flag
+ \flag_clear:N \l_@@_missing_flag
+ \flag_clear:N \l_@@_extra_flag
+ \flag_clear:N \l_@@_end_flag
+ \cs_set:Npn \@@_tmp:w ##1 ##2 { ` ## #1 }
+ \__kernel_tl_gset:Nx \g_@@_result_tl
+ {
+ \exp_after:wN \@@_decode_utf_xvi_pair:NN
+ #2 \q_@@_nil \q_@@_nil
+ \prg_break_point:
+ }
+ \@@_if_flag_error:Nne \l_@@_error_flag { utf16-decode } { }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]
+% {
+% \@@_decode_utf_xvi_pair:NN ,
+% \@@_decode_utf_xvi_quad:NNwNN ,
+% \@@_decode_utf_xvi_pair_end:Nw ,
+% }
+% \begin{macro}[rEXP]
+% {
+% \@@_decode_utf_xvi_error:nNN ,
+% \@@_decode_utf_xvi_extra:NNw ,
+% }
+% Bytes are read two at a time. At this stage, |\@@_tmp:w #1#2|
+% expands to the character code of the most significant byte, and we
+% distinguish cases depending on which range it lies in:
+% \begin{itemize}
+% \item $[\hexnum{D8}, \hexnum{DB}]$ signals a lead surrogate, and
+% the integer expression yields $1$ (\eTeX{} rounds ties away from
+% zero);
+% \item $[\hexnum{DC}, \hexnum{DF}]$ signals a trail surrogate,
+% unexpected here, and the integer expression yields $2$;
+% \item any other value signals a code point in the Basic
+% Multilingual Plane, which stands for itself, and the
+% \cs{if_case:w} construction expands to nothing (cases other than
+% $1$ or $2$), leaving the relevant material in the input stream,
+% followed by another call to the \texttt{_pair} auxiliary.
+% \end{itemize}
+% The case of a lead surrogate is treated by the \texttt{_quad}
+% auxiliary, whose arguments |#1|, |#2|, |#4| and |#5| are the four
+% bytes. We expect the most significant byte of |#4#5| to be in the
+% range $[\hexnum{DC}, \hexnum{DF}]$ (trail surrogate). The test is
+% similar to the test used for continuation bytes in the
+% \textsc{utf-8} decoding functions. In the case where |#4#5| is
+% indeed a trail surrogate, leave |#1#2#4#5| \cs{s_@@}
+% \meta{code~point} \cs{s_@@}, and remove the pair |#4#5| before
+% looping with \cs{@@_decode_utf_xvi_pair:NN}. Otherwise, of course,
+% complain about the missing surrogate.
+%
+% The magic number \hexnum{D7F7} is such that
+% $\hexnum{D7F7}*\hexnum{400} = \hexnum{D800}*\hexnum{400} +
+% \hexnum{DC00} - \hexnum{10000}$.
+%
+% Every time we read a pair of bytes, we test for the end-marker
+% \cs{q_@@_nil}. When reaching the end, we additionally check that the
+% string had an even length. Also, if the end is reached when
+% expecting a trail surrogate, we treat that as a missing surrogate.
+% \begin{macrocode}
+ \cs_new:Npn \@@_decode_utf_xvi_pair:NN #1#2
+ {
+ \if_meaning:w \q_@@_nil #2
+ \@@_decode_utf_xvi_pair_end:Nw #1
+ \fi:
+ \if_case:w
+ \int_eval:n { ( \@@_tmp:w #1#2 - "D6 ) / 4 } \scan_stop:
+ \or: \exp_after:wN \@@_decode_utf_xvi_quad:NNwNN
+ \or: \exp_after:wN \@@_decode_utf_xvi_extra:NNw
+ \fi:
+ #1#2 \s_@@
+ \int_eval:n { "100 * \@@_tmp:w #1#2 + \@@_tmp:w #2#1 } \s_@@
+ \@@_decode_utf_xvi_pair:NN
+ }
+ \cs_new:Npn \@@_decode_utf_xvi_quad:NNwNN
+ #1#2 #3 \@@_decode_utf_xvi_pair:NN #4#5
+ {
+ \if_meaning:w \q_@@_nil #5
+ \@@_decode_utf_xvi_error:nNN { missing } #1#2
+ \@@_decode_utf_xvi_pair_end:Nw #4
+ \fi:
+ \if_int_compare:w
+ \if_int_compare:w \@@_tmp:w #4#5 < "DC \exp_stop_f:
+ 0 = 1
+ \else:
+ \@@_tmp:w #4#5 < "E0
+ \fi:
+ \exp_stop_f:
+ #1 #2 #4 #5 \s_@@
+ \int_eval:n
+ {
+ ( "100 * \@@_tmp:w #1#2 + \@@_tmp:w #2#1 - "D7F7 ) * "400
+ + "100 * \@@_tmp:w #4#5 + \@@_tmp:w #5#4
+ }
+ \s_@@
+ \exp_after:wN \use_i:nnn
+ \else:
+ \@@_decode_utf_xvi_error:nNN { missing } #1#2
+ \fi:
+ \@@_decode_utf_xvi_pair:NN #4#5
+ }
+ \cs_new:Npn \@@_decode_utf_xvi_pair_end:Nw #1 \fi:
+ {
+ \fi:
+ \if_meaning:w \q_@@_nil #1
+ \else:
+ \@@_decode_utf_xvi_error:nNN { end } #1 \prg_do_nothing:
+ \fi:
+ \prg_break:
+ }
+ \cs_new:Npn \@@_decode_utf_xvi_extra:NNw #1#2 \s_@@ #3 \s_@@
+ { \@@_decode_utf_xvi_error:nNN { extra } #1#2 }
+ \cs_new:Npn \@@_decode_utf_xvi_error:nNN #1#2#3
+ {
+ \flag_raise:N \l_@@_error_flag
+ \flag_raise:c { l_@@_#1_flag }
+ #2 #3 \s_@@
+ \int_use:N \c_@@_replacement_char_int \s_@@
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Restore the original catcodes of bytes $254$ and $255$.
+% \begin{macrocode}
+\group_end:
+% \end{macrocode}
+%
+% \subsubsection{\textsc{utf-32} support}
+%
+% The definitions are done in a category code regime where the bytes
+% $0$, $254$ and $255$ used by the byte order mark have catcode
+% \enquote{other}.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_other:N \^^00
+ \char_set_catcode_other:N \^^fe
+ \char_set_catcode_other:N \^^ff
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_convert_encode_utf32: ,
+% \@@_convert_encode_utf32be: ,
+% \@@_convert_encode_utf32le: ,
+% }
+% \begin{macro}[rEXP]
+% {
+% \@@_encode_utf_xxxii_be:n ,
+% \@@_encode_utf_xxxii_be_aux:nn ,
+% \@@_encode_utf_xxxii_le:n ,
+% \@@_encode_utf_xxxii_le_aux:nn ,
+% }
+% Convert each integer in the comma-list \cs{g_@@_result_tl} to a
+% sequence of four bytes. The functions for big-endian and
+% little-endian encodings are very similar, but the
+% \cs{@@_output_byte:n} instructions are reversed.
+% \begin{macrocode}
+ \cs_new_protected:cpn { @@_convert_encode_utf32: }
+ {
+ \@@_convert_gmap_internal:N \@@_encode_utf_xxxii_be:n
+ \tl_gput_left:Ne \g_@@_result_tl { ^^00 ^^00 ^^fe ^^ff }
+ }
+ \cs_new_protected:cpn { @@_convert_encode_utf32be: }
+ { \@@_convert_gmap_internal:N \@@_encode_utf_xxxii_be:n }
+ \cs_new_protected:cpn { @@_convert_encode_utf32le: }
+ { \@@_convert_gmap_internal:N \@@_encode_utf_xxxii_le:n }
+ \cs_new:Npn \@@_encode_utf_xxxii_be:n #1
+ {
+ \exp_args:Nf \@@_encode_utf_xxxii_be_aux:nn
+ { \int_div_truncate:nn {#1} { "100 } } {#1}
+ }
+ \cs_new:Npn \@@_encode_utf_xxxii_be_aux:nn #1#2
+ {
+ ^^00
+ \@@_output_byte_pair_be:n {#1}
+ \@@_output_byte:n { #2 - #1 * "100 }
+ }
+ \cs_new:Npn \@@_encode_utf_xxxii_le:n #1
+ {
+ \exp_args:Nf \@@_encode_utf_xxxii_le_aux:nn
+ { \int_div_truncate:nn {#1} { "100 } } {#1}
+ }
+ \cs_new:Npn \@@_encode_utf_xxxii_le_aux:nn #1#2
+ {
+ \@@_output_byte:n { #2 - #1 * "100 }
+ \@@_output_byte_pair_le:n {#1}
+ ^^00
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{@@_overflow, @@_end}
+% There can be no error when encoding in \textsc{utf-32}. When
+% decoding, the string may not have length $4n$, or it may contain
+% code points larger than \hexnum{10FFFF}. The latter case often
+% happens if the encoding was in fact not \textsc{utf-32}, because
+% most arbitrary strings are not valid in \textsc{utf-32}.
+% \begin{macrocode}
+ \flag_clear_new:N \l_@@_overflow_flag
+ \flag_clear_new:N \l_@@_end_flag
+ \msg_new:nnnn { str } { utf32-decode }
+ {
+ Invalid~UTF-32~string:
+ \exp_last_unbraced:Nf \use_none:n
+ {
+ \@@_if_flag_times:NT \l_@@_overflow_flag { ,~code~point~too~large }
+ \@@_if_flag_times:NT \l_@@_end_flag { ,~truncated~string }
+ }
+ .
+ }
+ {
+ In~the~UTF-32~encoding,~every~Unicode~character~
+ (in~the~range~[U+0000,~U+10FFFF])~is~encoded~as~4~bytes.
+ \flag_if_raised:NT \l_@@_overflow_flag
+ {
+ \\\\
+ LaTeX~came~across~a~code~point~larger~than~1114111,~
+ the~maximum~code~point~defined~by~Unicode.~
+ Perhaps~the~string~was~not~encoded~in~the~UTF-32~encoding?
+ }
+ \flag_if_raised:NT \l_@@_end_flag
+ {
+ \\\\
+ The~length~of~the~string~is~not~a~multiple~of~4.~
+ Perhaps~the~string~was~truncated?
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \@@_convert_decode_utf32: ,
+% \@@_convert_decode_utf32be: ,
+% \@@_convert_decode_utf32le: ,
+% }
+% \begin{macro}
+% {\@@_decode_utf_xxxii_bom:NNNN, \@@_decode_utf_xxxii:Nw}
+% \begin{macro}[rEXP]
+% {\@@_decode_utf_xxxii_loop:NNNN, \@@_decode_utf_xxxii_end:w}
+%
+% The structure is similar to \textsc{utf-16} decoding functions. If
+% the endianness is not given, test the first $4$ bytes of the string
+% (possibly \cs{s_@@_stop} if the string is too short) for the presence
+% of a byte-order mark. If there is a byte-order mark, use that
+% endianness, and remove the $4$ bytes, otherwise default to
+% big-endian, and leave the $4$ bytes in place. The
+% \cs{@@_decode_utf_xxxii:Nw} auxiliary receives $1$ or $2$ as its
+% first argument indicating endianness, and the string to convert as
+% its second argument (expanded or not). It sets \cs{@@_tmp:w} to
+% expand to the character code of either of its two arguments
+% depending on endianness, then triggers the \texttt{_loop} auxiliary
+% inside an \texttt{e}-expanding assignment to \cs{g_@@_result_tl}.
+%
+% The \texttt{_loop} auxiliary first checks for the end-of-string
+% marker \cs{s_@@_stop}, calling the \texttt{_end} auxiliary if
+% appropriate. Otherwise, leave the \meta{4~bytes} \cs{s_@@} behind,
+% then check that the code point is not overflowing: the leading byte
+% must be $0$, and the following byte at most $16$.
+%
+% In the ending code, we check that there remains no byte: there
+% should be nothing left until the first \cs{s_@@_stop}. Break the map.
+% \begin{macrocode}
+ \cs_new_protected:cpn { @@_convert_decode_utf32be: }
+ { \@@_decode_utf_xxxii:Nw 1 \g_@@_result_tl \s_@@_stop }
+ \cs_new_protected:cpn { @@_convert_decode_utf32le: }
+ { \@@_decode_utf_xxxii:Nw 2 \g_@@_result_tl \s_@@_stop }
+ \cs_new_protected:cpn { @@_convert_decode_utf32: }
+ {
+ \exp_after:wN \@@_decode_utf_xxxii_bom:NNNN \g_@@_result_tl
+ \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop
+ }
+ \cs_new_protected:Npn \@@_decode_utf_xxxii_bom:NNNN #1#2#3#4
+ {
+ \str_if_eq:nnTF { #1#2#3#4 } { ^^ff ^^fe ^^00 ^^00 }
+ { \@@_decode_utf_xxxii:Nw 2 }
+ {
+ \str_if_eq:nnTF { #1#2#3#4 } { ^^00 ^^00 ^^fe ^^ff }
+ { \@@_decode_utf_xxxii:Nw 1 }
+ { \@@_decode_utf_xxxii:Nw 1 #1#2#3#4 }
+ }
+ }
+ \cs_new_protected:Npn \@@_decode_utf_xxxii:Nw #1#2 \s_@@_stop
+ {
+ \flag_clear:N \l_@@_overflow_flag
+ \flag_clear:N \l_@@_end_flag
+ \flag_clear:N \l_@@_error_flag
+ \cs_set:Npn \@@_tmp:w ##1 ##2 { ` ## #1 }
+ \__kernel_tl_gset:Nx \g_@@_result_tl
+ {
+ \exp_after:wN \@@_decode_utf_xxxii_loop:NNNN
+ #2 \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop
+ \prg_break_point:
+ }
+ \@@_if_flag_error:Nne \l_@@_error_flag { utf32-decode } { }
+ }
+ \cs_new:Npn \@@_decode_utf_xxxii_loop:NNNN #1#2#3#4
+ {
+ \if_meaning:w \s_@@_stop #4
+ \exp_after:wN \@@_decode_utf_xxxii_end:w
+ \fi:
+ #1#2#3#4 \s_@@
+ \if_int_compare:w \@@_tmp:w #1#4 > \c_zero_int
+ \flag_raise:N \l_@@_overflow_flag
+ \flag_raise:N \l_@@_error_flag
+ \int_use:N \c_@@_replacement_char_int
+ \else:
+ \if_int_compare:w \@@_tmp:w #2#3 > 16 \exp_stop_f:
+ \flag_raise:N \l_@@_overflow_flag
+ \flag_raise:N \l_@@_error_flag
+ \int_use:N \c_@@_replacement_char_int
+ \else:
+ \int_eval:n
+ { \@@_tmp:w #2#3*"10000 + \@@_tmp:w #3#2*"100 + \@@_tmp:w #4#1 }
+ \fi:
+ \fi:
+ \s_@@
+ \@@_decode_utf_xxxii_loop:NNNN
+ }
+ \cs_new:Npn \@@_decode_utf_xxxii_end:w #1 \s_@@_stop
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \flag_raise:N \l_@@_end_flag
+ \flag_raise:N \l_@@_error_flag
+ #1 \s_@@
+ \int_use:N \c_@@_replacement_char_int \s_@@
+ }
+ \prg_break:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% Restore the original catcodes of bytes $0$, $254$ and $255$.
+% \begin{macrocode}
+\group_end:
+% \end{macrocode}
+%
+% \subsection{PDF names and strings by expansion}
+%
+% \begin{macro}[EXP]{\str_convert_pdfname:n}
+% \begin{macro}[EXP]{\@@_convert_pdfname:n}
+% \begin{macro}[EXP]
+% {\@@_convert_pdfname_bytes:n, \@@_convert_pdfname_bytes_aux:n}
+% \begin{macro}[EXP]{\@@_convert_pdfname_bytes_aux:nnn}
+% To convert to PDF names by expansion, we work purely on UTF-8 input. The
+% first step is to make a string with \enquote{other} spaces,
+% after which we use a simple token-by-token approach. In Unicode
+% engines, we break down everything before one-byte codepoints, but for
+% $8$-bit engines there is no need to worry. Actual escaping is covered
+% by the same code as used in the non-expandable route.
+% \begin{macrocode}
+\cs_new:Npn \str_convert_pdfname:n #1
+ {
+ \exp_args:Ne \tl_to_str:n
+ { \str_map_function:nN {#1} \@@_convert_pdfname:n }
+ }
+\bool_lazy_or:nnTF
+ { \sys_if_engine_luatex_p: }
+ { \sys_if_engine_xetex_p: }
+ {
+ \cs_new:Npn \@@_convert_pdfname:n #1
+ {
+ \int_compare:nNnTF { `#1 } > { "7F }
+ { \@@_convert_pdfname_bytes:n {#1} }
+ { \@@_escape_name_char:n {#1} }
+ }
+ \cs_new:Npn \@@_convert_pdfname_bytes:n #1
+ {
+ \exp_args:Ne \@@_convert_pdfname_bytes_aux:n
+ { \__kernel_codepoint_to_bytes:n {`#1} }
+ }
+ \cs_new:Npn \@@_convert_pdfname_bytes_aux:n #1
+ { \@@_convert_pdfname_bytes_aux:nnnn #1 }
+ \cs_new:Npe \@@_convert_pdfname_bytes_aux:nnnn #1#2#3#4
+ {
+ \c_hash_str \exp_not:N \@@_output_hexadecimal:n {#1}
+ \c_hash_str \exp_not:N \@@_output_hexadecimal:n {#2}
+ \exp_not:N \tl_if_blank:nF {#3}
+ {
+ \c_hash_str \exp_not:N \@@_output_hexadecimal:n {#3}
+ \exp_not:N \tl_if_blank:nF {#4}
+ {
+ \c_hash_str \exp_not:N \@@_output_hexadecimal:n {#4}
+ }
+ }
+ }
+ }
+ { \cs_new_eq:NN \@@_convert_pdfname:n \@@_escape_name_char:n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \subsubsection{\textsc{iso 8859} support}
+%
+% The \textsc{iso-8859-1} encoding exactly matches with the $256$ first
+% Unicode characters. For other 8-bit encodings of the \textsc{iso-8859}
+% family, we keep track only of differences, and of unassigned bytes.
+% \begin{macrocode}
+%<*iso88591>
+\@@_declare_eight_bit_encoding:nnnn { iso88591 } { 256 }
+ {
+ }
+ {
+ }
+%</iso88591>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*iso88592>
+\@@_declare_eight_bit_encoding:nnnn { iso88592 } { 399 }
+ {
+ { A1 } { 0104 }
+ { A2 } { 02D8 }
+ { A3 } { 0141 }
+ { A5 } { 013D }
+ { A6 } { 015A }
+ { A9 } { 0160 }
+ { AA } { 015E }
+ { AB } { 0164 }
+ { AC } { 0179 }
+ { AE } { 017D }
+ { AF } { 017B }
+ { B1 } { 0105 }
+ { B2 } { 02DB }
+ { B3 } { 0142 }
+ { B5 } { 013E }
+ { B6 } { 015B }
+ { B7 } { 02C7 }
+ { B9 } { 0161 }
+ { BA } { 015F }
+ { BB } { 0165 }
+ { BC } { 017A }
+ { BD } { 02DD }
+ { BE } { 017E }
+ { BF } { 017C }
+ { C0 } { 0154 }
+ { C3 } { 0102 }
+ { C5 } { 0139 }
+ { C6 } { 0106 }
+ { C8 } { 010C }
+ { CA } { 0118 }
+ { CC } { 011A }
+ { CF } { 010E }
+ { D0 } { 0110 }
+ { D1 } { 0143 }
+ { D2 } { 0147 }
+ { D5 } { 0150 }
+ { D8 } { 0158 }
+ { D9 } { 016E }
+ { DB } { 0170 }
+ { DE } { 0162 }
+ { E0 } { 0155 }
+ { E3 } { 0103 }
+ { E5 } { 013A }
+ { E6 } { 0107 }
+ { E8 } { 010D }
+ { EA } { 0119 }
+ { EC } { 011B }
+ { EF } { 010F }
+ { F0 } { 0111 }
+ { F1 } { 0144 }
+ { F2 } { 0148 }
+ { F5 } { 0151 }
+ { F8 } { 0159 }
+ { F9 } { 016F }
+ { FB } { 0171 }
+ { FE } { 0163 }
+ { FF } { 02D9 }
+ }
+ {
+ }
+%</iso88592>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*iso88593>
+\@@_declare_eight_bit_encoding:nnnn { iso88593 } { 384 }
+ {
+ { A1 } { 0126 }
+ { A2 } { 02D8 }
+ { A6 } { 0124 }
+ { A9 } { 0130 }
+ { AA } { 015E }
+ { AB } { 011E }
+ { AC } { 0134 }
+ { AF } { 017B }
+ { B1 } { 0127 }
+ { B6 } { 0125 }
+ { B9 } { 0131 }
+ { BA } { 015F }
+ { BB } { 011F }
+ { BC } { 0135 }
+ { BF } { 017C }
+ { C5 } { 010A }
+ { C6 } { 0108 }
+ { D5 } { 0120 }
+ { D8 } { 011C }
+ { DD } { 016C }
+ { DE } { 015C }
+ { E5 } { 010B }
+ { E6 } { 0109 }
+ { F5 } { 0121 }
+ { F8 } { 011D }
+ { FD } { 016D }
+ { FE } { 015D }
+ { FF } { 02D9 }
+ }
+ {
+ { A5 }
+ { AE }
+ { BE }
+ { C3 }
+ { D0 }
+ { E3 }
+ { F0 }
+ }
+%</iso88593>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*iso88594>
+\@@_declare_eight_bit_encoding:nnnn { iso88594 } { 383 }
+ {
+ { A1 } { 0104 }
+ { A2 } { 0138 }
+ { A3 } { 0156 }
+ { A5 } { 0128 }
+ { A6 } { 013B }
+ { A9 } { 0160 }
+ { AA } { 0112 }
+ { AB } { 0122 }
+ { AC } { 0166 }
+ { AE } { 017D }
+ { B1 } { 0105 }
+ { B2 } { 02DB }
+ { B3 } { 0157 }
+ { B5 } { 0129 }
+ { B6 } { 013C }
+ { B7 } { 02C7 }
+ { B9 } { 0161 }
+ { BA } { 0113 }
+ { BB } { 0123 }
+ { BC } { 0167 }
+ { BD } { 014A }
+ { BE } { 017E }
+ { BF } { 014B }
+ { C0 } { 0100 }
+ { C7 } { 012E }
+ { C8 } { 010C }
+ { CA } { 0118 }
+ { CC } { 0116 }
+ { CF } { 012A }
+ { D0 } { 0110 }
+ { D1 } { 0145 }
+ { D2 } { 014C }
+ { D3 } { 0136 }
+ { D9 } { 0172 }
+ { DD } { 0168 }
+ { DE } { 016A }
+ { E0 } { 0101 }
+ { E7 } { 012F }
+ { E8 } { 010D }
+ { EA } { 0119 }
+ { EC } { 0117 }
+ { EF } { 012B }
+ { F0 } { 0111 }
+ { F1 } { 0146 }
+ { F2 } { 014D }
+ { F3 } { 0137 }
+ { F9 } { 0173 }
+ { FD } { 0169 }
+ { FE } { 016B }
+ { FF } { 02D9 }
+ }
+ {
+ }
+%</iso88594>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*iso88595>
+\@@_declare_eight_bit_encoding:nnnn { iso88595 } { 374 }
+ {
+ { A1 } { 0401 }
+ { A2 } { 0402 }
+ { A3 } { 0403 }
+ { A4 } { 0404 }
+ { A5 } { 0405 }
+ { A6 } { 0406 }
+ { A7 } { 0407 }
+ { A8 } { 0408 }
+ { A9 } { 0409 }
+ { AA } { 040A }
+ { AB } { 040B }
+ { AC } { 040C }
+ { AE } { 040E }
+ { AF } { 040F }
+ { B0 } { 0410 }
+ { B1 } { 0411 }
+ { B2 } { 0412 }
+ { B3 } { 0413 }
+ { B4 } { 0414 }
+ { B5 } { 0415 }
+ { B6 } { 0416 }
+ { B7 } { 0417 }
+ { B8 } { 0418 }
+ { B9 } { 0419 }
+ { BA } { 041A }
+ { BB } { 041B }
+ { BC } { 041C }
+ { BD } { 041D }
+ { BE } { 041E }
+ { BF } { 041F }
+ { C0 } { 0420 }
+ { C1 } { 0421 }
+ { C2 } { 0422 }
+ { C3 } { 0423 }
+ { C4 } { 0424 }
+ { C5 } { 0425 }
+ { C6 } { 0426 }
+ { C7 } { 0427 }
+ { C8 } { 0428 }
+ { C9 } { 0429 }
+ { CA } { 042A }
+ { CB } { 042B }
+ { CC } { 042C }
+ { CD } { 042D }
+ { CE } { 042E }
+ { CF } { 042F }
+ { D0 } { 0430 }
+ { D1 } { 0431 }
+ { D2 } { 0432 }
+ { D3 } { 0433 }
+ { D4 } { 0434 }
+ { D5 } { 0435 }
+ { D6 } { 0436 }
+ { D7 } { 0437 }
+ { D8 } { 0438 }
+ { D9 } { 0439 }
+ { DA } { 043A }
+ { DB } { 043B }
+ { DC } { 043C }
+ { DD } { 043D }
+ { DE } { 043E }
+ { DF } { 043F }
+ { E0 } { 0440 }
+ { E1 } { 0441 }
+ { E2 } { 0442 }
+ { E3 } { 0443 }
+ { E4 } { 0444 }
+ { E5 } { 0445 }
+ { E6 } { 0446 }
+ { E7 } { 0447 }
+ { E8 } { 0448 }
+ { E9 } { 0449 }
+ { EA } { 044A }
+ { EB } { 044B }
+ { EC } { 044C }
+ { ED } { 044D }
+ { EE } { 044E }
+ { EF } { 044F }
+ { F0 } { 2116 }
+ { F1 } { 0451 }
+ { F2 } { 0452 }
+ { F3 } { 0453 }
+ { F4 } { 0454 }
+ { F5 } { 0455 }
+ { F6 } { 0456 }
+ { F7 } { 0457 }
+ { F8 } { 0458 }
+ { F9 } { 0459 }
+ { FA } { 045A }
+ { FB } { 045B }
+ { FC } { 045C }
+ { FD } { 00A7 }
+ { FE } { 045E }
+ { FF } { 045F }
+ }
+ {
+ }
+%</iso88595>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*iso88596>
+\@@_declare_eight_bit_encoding:nnnn { iso88596 } { 344 }
+ {
+ { AC } { 060C }
+ { BB } { 061B }
+ { BF } { 061F }
+ { C1 } { 0621 }
+ { C2 } { 0622 }
+ { C3 } { 0623 }
+ { C4 } { 0624 }
+ { C5 } { 0625 }
+ { C6 } { 0626 }
+ { C7 } { 0627 }
+ { C8 } { 0628 }
+ { C9 } { 0629 }
+ { CA } { 062A }
+ { CB } { 062B }
+ { CC } { 062C }
+ { CD } { 062D }
+ { CE } { 062E }
+ { CF } { 062F }
+ { D0 } { 0630 }
+ { D1 } { 0631 }
+ { D2 } { 0632 }
+ { D3 } { 0633 }
+ { D4 } { 0634 }
+ { D5 } { 0635 }
+ { D6 } { 0636 }
+ { D7 } { 0637 }
+ { D8 } { 0638 }
+ { D9 } { 0639 }
+ { DA } { 063A }
+ { E0 } { 0640 }
+ { E1 } { 0641 }
+ { E2 } { 0642 }
+ { E3 } { 0643 }
+ { E4 } { 0644 }
+ { E5 } { 0645 }
+ { E6 } { 0646 }
+ { E7 } { 0647 }
+ { E8 } { 0648 }
+ { E9 } { 0649 }
+ { EA } { 064A }
+ { EB } { 064B }
+ { EC } { 064C }
+ { ED } { 064D }
+ { EE } { 064E }
+ { EF } { 064F }
+ { F0 } { 0650 }
+ { F1 } { 0651 }
+ { F2 } { 0652 }
+ }
+ {
+ { A1 }
+ { A2 }
+ { A3 }
+ { A5 }
+ { A6 }
+ { A7 }
+ { A8 }
+ { A9 }
+ { AA }
+ { AB }
+ { AE }
+ { AF }
+ { B0 }
+ { B1 }
+ { B2 }
+ { B3 }
+ { B4 }
+ { B5 }
+ { B6 }
+ { B7 }
+ { B8 }
+ { B9 }
+ { BA }
+ { BC }
+ { BD }
+ { BE }
+ { C0 }
+ { DB }
+ { DC }
+ { DD }
+ { DE }
+ { DF }
+ }
+%</iso88596>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*iso88597>
+\@@_declare_eight_bit_encoding:nnnn { iso88597 } { 498 }
+ {
+ { A1 } { 2018 }
+ { A2 } { 2019 }
+ { A4 } { 20AC }
+ { A5 } { 20AF }
+ { AA } { 037A }
+ { AF } { 2015 }
+ { B4 } { 0384 }
+ { B5 } { 0385 }
+ { B6 } { 0386 }
+ { B8 } { 0388 }
+ { B9 } { 0389 }
+ { BA } { 038A }
+ { BC } { 038C }
+ { BE } { 038E }
+ { BF } { 038F }
+ { C0 } { 0390 }
+ { C1 } { 0391 }
+ { C2 } { 0392 }
+ { C3 } { 0393 }
+ { C4 } { 0394 }
+ { C5 } { 0395 }
+ { C6 } { 0396 }
+ { C7 } { 0397 }
+ { C8 } { 0398 }
+ { C9 } { 0399 }
+ { CA } { 039A }
+ { CB } { 039B }
+ { CC } { 039C }
+ { CD } { 039D }
+ { CE } { 039E }
+ { CF } { 039F }
+ { D0 } { 03A0 }
+ { D1 } { 03A1 }
+ { D3 } { 03A3 }
+ { D4 } { 03A4 }
+ { D5 } { 03A5 }
+ { D6 } { 03A6 }
+ { D7 } { 03A7 }
+ { D8 } { 03A8 }
+ { D9 } { 03A9 }
+ { DA } { 03AA }
+ { DB } { 03AB }
+ { DC } { 03AC }
+ { DD } { 03AD }
+ { DE } { 03AE }
+ { DF } { 03AF }
+ { E0 } { 03B0 }
+ { E1 } { 03B1 }
+ { E2 } { 03B2 }
+ { E3 } { 03B3 }
+ { E4 } { 03B4 }
+ { E5 } { 03B5 }
+ { E6 } { 03B6 }
+ { E7 } { 03B7 }
+ { E8 } { 03B8 }
+ { E9 } { 03B9 }
+ { EA } { 03BA }
+ { EB } { 03BB }
+ { EC } { 03BC }
+ { ED } { 03BD }
+ { EE } { 03BE }
+ { EF } { 03BF }
+ { F0 } { 03C0 }
+ { F1 } { 03C1 }
+ { F2 } { 03C2 }
+ { F3 } { 03C3 }
+ { F4 } { 03C4 }
+ { F5 } { 03C5 }
+ { F6 } { 03C6 }
+ { F7 } { 03C7 }
+ { F8 } { 03C8 }
+ { F9 } { 03C9 }
+ { FA } { 03CA }
+ { FB } { 03CB }
+ { FC } { 03CC }
+ { FD } { 03CD }
+ { FE } { 03CE }
+ }
+ {
+ { AE }
+ { D2 }
+ }
+%</iso88597>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*iso88598>
+\@@_declare_eight_bit_encoding:nnnn { iso88598 } { 308 }
+ {
+ { AA } { 00D7 }
+ { BA } { 00F7 }
+ { DF } { 2017 }
+ { E0 } { 05D0 }
+ { E1 } { 05D1 }
+ { E2 } { 05D2 }
+ { E3 } { 05D3 }
+ { E4 } { 05D4 }
+ { E5 } { 05D5 }
+ { E6 } { 05D6 }
+ { E7 } { 05D7 }
+ { E8 } { 05D8 }
+ { E9 } { 05D9 }
+ { EA } { 05DA }
+ { EB } { 05DB }
+ { EC } { 05DC }
+ { ED } { 05DD }
+ { EE } { 05DE }
+ { EF } { 05DF }
+ { F0 } { 05E0 }
+ { F1 } { 05E1 }
+ { F2 } { 05E2 }
+ { F3 } { 05E3 }
+ { F4 } { 05E4 }
+ { F5 } { 05E5 }
+ { F6 } { 05E6 }
+ { F7 } { 05E7 }
+ { F8 } { 05E8 }
+ { F9 } { 05E9 }
+ { FA } { 05EA }
+ { FD } { 200E }
+ { FE } { 200F }
+ }
+ {
+ { A1 }
+ { BF }
+ { C0 }
+ { C1 }
+ { C2 }
+ { C3 }
+ { C4 }
+ { C5 }
+ { C6 }
+ { C7 }
+ { C8 }
+ { C9 }
+ { CA }
+ { CB }
+ { CC }
+ { CD }
+ { CE }
+ { CF }
+ { D0 }
+ { D1 }
+ { D2 }
+ { D3 }
+ { D4 }
+ { D5 }
+ { D6 }
+ { D7 }
+ { D8 }
+ { D9 }
+ { DA }
+ { DB }
+ { DC }
+ { DD }
+ { DE }
+ { FB }
+ { FC }
+ }
+%</iso88598>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*iso88599>
+\@@_declare_eight_bit_encoding:nnnn { iso88599 } { 352 }
+ {
+ { D0 } { 011E }
+ { DD } { 0130 }
+ { DE } { 015E }
+ { F0 } { 011F }
+ { FD } { 0131 }
+ { FE } { 015F }
+ }
+ {
+ }
+%</iso88599>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*iso885910>
+\@@_declare_eight_bit_encoding:nnnn { iso885910 } { 383 }
+ {
+ { A1 } { 0104 }
+ { A2 } { 0112 }
+ { A3 } { 0122 }
+ { A4 } { 012A }
+ { A5 } { 0128 }
+ { A6 } { 0136 }
+ { A8 } { 013B }
+ { A9 } { 0110 }
+ { AA } { 0160 }
+ { AB } { 0166 }
+ { AC } { 017D }
+ { AE } { 016A }
+ { AF } { 014A }
+ { B1 } { 0105 }
+ { B2 } { 0113 }
+ { B3 } { 0123 }
+ { B4 } { 012B }
+ { B5 } { 0129 }
+ { B6 } { 0137 }
+ { B8 } { 013C }
+ { B9 } { 0111 }
+ { BA } { 0161 }
+ { BB } { 0167 }
+ { BC } { 017E }
+ { BD } { 2015 }
+ { BE } { 016B }
+ { BF } { 014B }
+ { C0 } { 0100 }
+ { C7 } { 012E }
+ { C8 } { 010C }
+ { CA } { 0118 }
+ { CC } { 0116 }
+ { D1 } { 0145 }
+ { D2 } { 014C }
+ { D7 } { 0168 }
+ { D9 } { 0172 }
+ { E0 } { 0101 }
+ { E7 } { 012F }
+ { E8 } { 010D }
+ { EA } { 0119 }
+ { EC } { 0117 }
+ { F1 } { 0146 }
+ { F2 } { 014D }
+ { F7 } { 0169 }
+ { F9 } { 0173 }
+ { FF } { 0138 }
+ }
+ {
+ }
+%</iso885910>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*iso885911>
+\@@_declare_eight_bit_encoding:nnnn { iso885911 } { 369 }
+ {
+ { A1 } { 0E01 }
+ { A2 } { 0E02 }
+ { A3 } { 0E03 }
+ { A4 } { 0E04 }
+ { A5 } { 0E05 }
+ { A6 } { 0E06 }
+ { A7 } { 0E07 }
+ { A8 } { 0E08 }
+ { A9 } { 0E09 }
+ { AA } { 0E0A }
+ { AB } { 0E0B }
+ { AC } { 0E0C }
+ { AD } { 0E0D }
+ { AE } { 0E0E }
+ { AF } { 0E0F }
+ { B0 } { 0E10 }
+ { B1 } { 0E11 }
+ { B2 } { 0E12 }
+ { B3 } { 0E13 }
+ { B4 } { 0E14 }
+ { B5 } { 0E15 }
+ { B6 } { 0E16 }
+ { B7 } { 0E17 }
+ { B8 } { 0E18 }
+ { B9 } { 0E19 }
+ { BA } { 0E1A }
+ { BB } { 0E1B }
+ { BC } { 0E1C }
+ { BD } { 0E1D }
+ { BE } { 0E1E }
+ { BF } { 0E1F }
+ { C0 } { 0E20 }
+ { C1 } { 0E21 }
+ { C2 } { 0E22 }
+ { C3 } { 0E23 }
+ { C4 } { 0E24 }
+ { C5 } { 0E25 }
+ { C6 } { 0E26 }
+ { C7 } { 0E27 }
+ { C8 } { 0E28 }
+ { C9 } { 0E29 }
+ { CA } { 0E2A }
+ { CB } { 0E2B }
+ { CC } { 0E2C }
+ { CD } { 0E2D }
+ { CE } { 0E2E }
+ { CF } { 0E2F }
+ { D0 } { 0E30 }
+ { D1 } { 0E31 }
+ { D2 } { 0E32 }
+ { D3 } { 0E33 }
+ { D4 } { 0E34 }
+ { D5 } { 0E35 }
+ { D6 } { 0E36 }
+ { D7 } { 0E37 }
+ { D8 } { 0E38 }
+ { D9 } { 0E39 }
+ { DA } { 0E3A }
+ { DF } { 0E3F }
+ { E0 } { 0E40 }
+ { E1 } { 0E41 }
+ { E2 } { 0E42 }
+ { E3 } { 0E43 }
+ { E4 } { 0E44 }
+ { E5 } { 0E45 }
+ { E6 } { 0E46 }
+ { E7 } { 0E47 }
+ { E8 } { 0E48 }
+ { E9 } { 0E49 }
+ { EA } { 0E4A }
+ { EB } { 0E4B }
+ { EC } { 0E4C }
+ { ED } { 0E4D }
+ { EE } { 0E4E }
+ { EF } { 0E4F }
+ { F0 } { 0E50 }
+ { F1 } { 0E51 }
+ { F2 } { 0E52 }
+ { F3 } { 0E53 }
+ { F4 } { 0E54 }
+ { F5 } { 0E55 }
+ { F6 } { 0E56 }
+ { F7 } { 0E57 }
+ { F8 } { 0E58 }
+ { F9 } { 0E59 }
+ { FA } { 0E5A }
+ { FB } { 0E5B }
+ }
+ {
+ { DB }
+ { DC }
+ { DD }
+ { DE }
+ }
+%</iso885911>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*iso885913>
+\@@_declare_eight_bit_encoding:nnnn { iso885913 } { 399 }
+ {
+ { A1 } { 201D }
+ { A5 } { 201E }
+ { A8 } { 00D8 }
+ { AA } { 0156 }
+ { AF } { 00C6 }
+ { B4 } { 201C }
+ { B8 } { 00F8 }
+ { BA } { 0157 }
+ { BF } { 00E6 }
+ { C0 } { 0104 }
+ { C1 } { 012E }
+ { C2 } { 0100 }
+ { C3 } { 0106 }
+ { C6 } { 0118 }
+ { C7 } { 0112 }
+ { C8 } { 010C }
+ { CA } { 0179 }
+ { CB } { 0116 }
+ { CC } { 0122 }
+ { CD } { 0136 }
+ { CE } { 012A }
+ { CF } { 013B }
+ { D0 } { 0160 }
+ { D1 } { 0143 }
+ { D2 } { 0145 }
+ { D4 } { 014C }
+ { D8 } { 0172 }
+ { D9 } { 0141 }
+ { DA } { 015A }
+ { DB } { 016A }
+ { DD } { 017B }
+ { DE } { 017D }
+ { E0 } { 0105 }
+ { E1 } { 012F }
+ { E2 } { 0101 }
+ { E3 } { 0107 }
+ { E6 } { 0119 }
+ { E7 } { 0113 }
+ { E8 } { 010D }
+ { EA } { 017A }
+ { EB } { 0117 }
+ { EC } { 0123 }
+ { ED } { 0137 }
+ { EE } { 012B }
+ { EF } { 013C }
+ { F0 } { 0161 }
+ { F1 } { 0144 }
+ { F2 } { 0146 }
+ { F4 } { 014D }
+ { F8 } { 0173 }
+ { F9 } { 0142 }
+ { FA } { 015B }
+ { FB } { 016B }
+ { FD } { 017C }
+ { FE } { 017E }
+ { FF } { 2019 }
+ }
+ {
+ }
+%</iso885913>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*iso885914>
+\@@_declare_eight_bit_encoding:nnnn { iso885914 } { 529 }
+ {
+ { A1 } { 1E02 }
+ { A2 } { 1E03 }
+ { A4 } { 010A }
+ { A5 } { 010B }
+ { A6 } { 1E0A }
+ { A8 } { 1E80 }
+ { AA } { 1E82 }
+ { AB } { 1E0B }
+ { AC } { 1EF2 }
+ { AF } { 0178 }
+ { B0 } { 1E1E }
+ { B1 } { 1E1F }
+ { B2 } { 0120 }
+ { B3 } { 0121 }
+ { B4 } { 1E40 }
+ { B5 } { 1E41 }
+ { B7 } { 1E56 }
+ { B8 } { 1E81 }
+ { B9 } { 1E57 }
+ { BA } { 1E83 }
+ { BB } { 1E60 }
+ { BC } { 1EF3 }
+ { BD } { 1E84 }
+ { BE } { 1E85 }
+ { BF } { 1E61 }
+ { D0 } { 0174 }
+ { D7 } { 1E6A }
+ { DE } { 0176 }
+ { F0 } { 0175 }
+ { F7 } { 1E6B }
+ { FE } { 0177 }
+ }
+ {
+ }
+%</iso885914>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*iso885915>
+\@@_declare_eight_bit_encoding:nnnn { iso885915 } { 383 }
+ {
+ { A4 } { 20AC }
+ { A6 } { 0160 }
+ { A8 } { 0161 }
+ { B4 } { 017D }
+ { B8 } { 017E }
+ { BC } { 0152 }
+ { BD } { 0153 }
+ { BE } { 0178 }
+ }
+ {
+ }
+%</iso885915>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*iso885916>
+\@@_declare_eight_bit_encoding:nnnn { iso885916 } { 558 }
+ {
+ { A1 } { 0104 }
+ { A2 } { 0105 }
+ { A3 } { 0141 }
+ { A4 } { 20AC }
+ { A5 } { 201E }
+ { A6 } { 0160 }
+ { A8 } { 0161 }
+ { AA } { 0218 }
+ { AC } { 0179 }
+ { AE } { 017A }
+ { AF } { 017B }
+ { B2 } { 010C }
+ { B3 } { 0142 }
+ { B4 } { 017D }
+ { B5 } { 201D }
+ { B8 } { 017E }
+ { B9 } { 010D }
+ { BA } { 0219 }
+ { BC } { 0152 }
+ { BD } { 0153 }
+ { BE } { 0178 }
+ { BF } { 017C }
+ { C3 } { 0102 }
+ { C5 } { 0106 }
+ { D0 } { 0110 }
+ { D1 } { 0143 }
+ { D5 } { 0150 }
+ { D7 } { 015A }
+ { D8 } { 0170 }
+ { DD } { 0118 }
+ { DE } { 021A }
+ { E3 } { 0103 }
+ { E5 } { 0107 }
+ { F0 } { 0111 }
+ { F1 } { 0144 }
+ { F5 } { 0151 }
+ { F7 } { 015B }
+ { F8 } { 0171 }
+ { FD } { 0119 }
+ { FE } { 021B }
+ }
+ {
+ }
+%</iso885916>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3str.dtx b/macros/latex-dev/required/l3kernel/l3str.dtx
new file mode 100644
index 0000000000..efc24fe8ea
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3str.dtx
@@ -0,0 +1,2226 @@
+% \iffalse meta-comment
+%
+%% File: l3str.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3str} module\\ Strings^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \TeX{} associates each character with a category code: as such, there is no
+% concept of a \enquote{string} as commonly understood in many other
+% programming languages. However, there are places where we wish to manipulate
+% token lists while in some sense \enquote{ignoring} category codes: this is
+% done by treating token lists as strings in a \TeX{} sense.
+%
+% A \TeX{} string (and thus an \pkg{expl3} string) is a series of characters
+% which have category code $12$ (\enquote{other}) with the exception of
+% space characters which have category code $10$ (\enquote{space}). Thus
+% at a technical level, a \TeX{} string is a token list with the appropriate
+% category codes. In this documentation, these are simply referred to as
+% strings.
+%
+% String variables are simply specialised token lists, but by convention
+% should be named with the suffix \texttt{\ldots{}str}. Such variables
+% should contain characters with category code $12$ (other), except
+% spaces, which have category code $10$ (blank space). All the
+% functions in this module which accept a token list argument first
+% convert it to a string using \cs{tl_to_str:n} for internal processing,
+% and do not treat a token list or the corresponding string
+% representation differently.
+%
+% As a string is a subset of the more general token list, it is sometimes unclear
+% when one should be used over the other.
+% Use a string variable for data that isn't primarily intended for typesetting
+% and for which a level of protection from unwanted expansion is suitable.
+% This data type simplifies comparison of variables since there are no concerns
+% about expansion of their contents.
+%
+% The functions \cs{cs_to_str:N}, \cs{tl_to_str:n}, \cs{tl_to_str:N} and
+% \cs{token_to_str:N} (and variants) generate strings from the appropriate
+% input: these are documented in \pkg{l3basics}, \pkg{l3tl} and \pkg{l3token},
+% respectively.
+%
+% Most expandable functions in this module come in three flavours:
+% \begin{itemize}
+% \item \cs[no-index]{str_\ldots{}:N}, which expect a token list or string
+% variable as their argument;
+% \item \cs[no-index]{str_\ldots{}:n}, taking any token list (or string) as an
+% argument;
+% \item \cs[no-index]{str_\ldots{}_ignore_spaces:n}, which ignores any space
+% encountered during the operation: these functions are typically
+% faster than those which take care of escaping spaces
+% appropriately.
+% \end{itemize}
+%
+% \section{Creating and initialising string variables}
+%
+% \begin{function}[added = 2015-09-18]{\str_new:N, \str_new:c}
+% \begin{syntax}
+% \cs{str_new:N} \meta{str~var}
+% \end{syntax}
+% Creates a new \meta{str~var} or raises an error if the name is
+% already taken. The declaration is global. The \meta{str~var} is
+% initially empty.
+% \end{function}
+%
+% \begin{function}[added = 2015-09-18, updated = 2018-07-28]
+% {
+% \str_const:Nn, \str_const:NV, \str_const:Ne,
+% \str_const:cn, \str_const:cV, \str_const:ce
+% }
+% \begin{syntax}
+% \cs{str_const:Nn} \meta{str~var} \Arg{token list}
+% \end{syntax}
+% Creates a new constant \meta{str~var} or raises an error if the name
+% is already taken. The value of the \meta{str~var} is set
+% globally to the \meta{token list}, converted to a string.
+% \end{function}
+%
+% \begin{function}[added = 2015-09-18]
+% {\str_clear:N, \str_clear:c, \str_gclear:N, \str_gclear:c}
+% \begin{syntax}
+% \cs{str_clear:N} \meta{str~var}
+% \end{syntax}
+% Clears the content of the \meta{str~var}.
+% \end{function}
+%
+% \begin{function}[added = 2015-09-18]
+% {
+% \str_clear_new:N, \str_clear_new:c,
+% \str_gclear_new:N, \str_gclear_new:c
+% }
+% \begin{syntax}
+% \cs{str_clear_new:N} \meta{str~var}
+% \end{syntax}
+% Ensures that the \meta{str~var} exists globally by applying
+% \cs{str_new:N} if necessary, then applies
+% \cs[index=str_clear:N]{str_(g)clear:N} to leave
+% the \meta{str~var} empty.
+% \end{function}
+%
+% \begin{function}[added = 2015-09-18]
+% {
+% \str_set_eq:NN, \str_set_eq:cN, \str_set_eq:Nc, \str_set_eq:cc,
+% \str_gset_eq:NN, \str_gset_eq:cN, \str_gset_eq:Nc, \str_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{str_set_eq:NN} \meta{str~var_1} \meta{str~var_2}
+% \end{syntax}
+% Sets the content of \meta{str~var_1} equal to that of
+% \meta{str~var_2}.
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08]
+% {
+% \str_concat:NNN, \str_concat:ccc,
+% \str_gconcat:NNN, \str_gconcat:ccc
+% }
+% \begin{syntax}
+% \cs{str_concat:NNN} \meta{str~var_1} \meta{str~var_2} \meta{str~var_3}
+% \end{syntax}
+% Concatenates the content of \meta{str~var_2} and \meta{str~var_3}
+% together and saves the result in \meta{str~var_1}. The \meta{str~var_2}
+% is placed at the left side of the new string variable.
+% The \meta{str~var_2} and \meta{str~var_3} must indeed be strings, as
+% this function does not convert their contents to a string.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added = 2015-09-18]
+% {\str_if_exist:N, \str_if_exist:c}
+% \begin{syntax}
+% \cs{str_if_exist_p:N} \meta{str~var}
+% \cs{str_if_exist:NTF} \meta{str~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{str~var} is currently defined. This does not
+% check that the \meta{str~var} really is a string.
+% \end{function}
+%
+% \section{Adding data to string variables}
+%
+% \begin{function}[added = 2015-09-18, updated = 2018-07-28]
+% {
+% \str_set:Nn, \str_set:NV, \str_set:Ne,
+% \str_set:cn, \str_set:cV, \str_set:ce,
+% \str_gset:Nn, \str_gset:NV, \str_gset:Ne,
+% \str_gset:cn, \str_gset:cV, \str_gset:ce
+% }
+% \begin{syntax}
+% \cs{str_set:Nn} \meta{str var} \Arg{token list}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string}, and stores the
+% result in \meta{str var}.
+% \end{function}
+%
+% \begin{function}[added = 2015-09-18, updated = 2018-07-28]
+% {
+% \str_put_left:Nn, \str_put_left:NV, \str_put_left:Ne,
+% \str_put_left:cn, \str_put_left:cV, \str_put_left:ce,
+% \str_gput_left:Nn, \str_gput_left:NV, \str_gput_left:Ne,
+% \str_gput_left:cn, \str_gput_left:cV, \str_gput_left:ce
+% }
+% \begin{syntax}
+% \cs{str_put_left:Nn} \meta{str var} \Arg{token list}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string}, and prepends the
+% result to \meta{str var}. The current contents of the \meta{str
+% var} are not automatically converted to a string.
+% \end{function}
+%
+% \begin{function}[added = 2015-09-18, updated = 2018-07-28]
+% {
+% \str_put_right:Nn, \str_put_right:NV, \str_put_right:Ne,
+% \str_put_right:cn, \str_put_right:cV, \str_put_right:Ne,
+% \str_gput_right:Nn, \str_gput_right:NV, \str_gput_right:Ne,
+% \str_gput_right:cn, \str_gput_right:cV, \str_gput_right:ce
+% }
+% \begin{syntax}
+% \cs{str_put_right:Nn} \meta{str var} \Arg{token list}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string}, and appends the
+% result to \meta{str var}. The current contents of the \meta{str
+% var} are not automatically converted to a string.
+% \end{function}
+%
+% \section{String conditionals}
+%
+% \begin{function}[EXP,pTF, added = 2015-09-18, updated = 2022-03-21]
+% {\str_if_empty:N, \str_if_empty:c, \str_if_empty:n}
+% \begin{syntax}
+% \cs{str_if_empty_p:N} \meta{str~var}
+% \cs{str_if_empty:NTF} \meta{str~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{string variable} is entirely empty
+% (\emph{i.e.}~contains no characters at all).
+% \end{function}
+%
+% \begin{function}[EXP,pTF, added = 2015-09-18]
+% {\str_if_eq:NN, \str_if_eq:Nc, \str_if_eq:cN, \str_if_eq:cc}
+% \begin{syntax}
+% \cs{str_if_eq_p:NN} \meta{str~var_1} \meta{str~var_2}
+% \cs{str_if_eq:NNTF} \meta{str~var_1} \meta{str~var_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Compares the content of two \meta{str variables} and
+% is logically \texttt{true} if the two contain the same characters
+% in the same order. See \cs{tl_if_eq:NNTF} to compare tokens
+% (including their category codes) rather than characters.
+% \end{function}
+%
+% \begin{function}[EXP,pTF, updated = 2018-06-18]
+% {
+% \str_if_eq:nn, \str_if_eq:Vn, \str_if_eq:on, \str_if_eq:no,
+% \str_if_eq:nV, \str_if_eq:VV, \str_if_eq:vn, \str_if_eq:nv,
+% \str_if_eq:ee
+% }
+% \begin{syntax}
+% \cs{str_if_eq_p:nn} \Arg{tl_1} \Arg{tl_2}
+% \cs{str_if_eq:nnTF} \Arg{tl_1} \Arg{tl_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Compares the two \meta{token lists} on a character by character
+% basis (namely after converting them to strings),
+% and is \texttt{true} if the two \meta{strings} contain the same
+% characters in the same order. Thus for example
+% \begin{verbatim}
+% \str_if_eq_p:no { abc } { \tl_to_str:n { abc } }
+% \end{verbatim}
+% is logically \texttt{true}. See \cs{tl_if_eq:nnTF} to compare
+% tokens (including their category codes) rather than characters.
+% \end{function}
+%
+% \begin{function}[TF, added = 2017-10-08]{\str_if_in:Nn, \str_if_in:cn}
+% \begin{syntax}
+% \cs{str_if_in:NnTF} \meta{str~var} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string} and
+% tests if that \meta{string} is found in the content of the
+% \meta{str~var}.
+% \end{function}
+%
+% \begin{function}[TF, added = 2017-10-08]{\str_if_in:nn}
+% \begin{syntax}
+% \cs{str_if_in:nnTF} \Arg{tl_1} \Arg{tl_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Converts both \meta{token lists} to \meta{strings} and
+% tests whether \meta{string_2} is found inside \meta{string_1}.
+% \end{function}
+%
+% \begin{function}[added = 2013-07-24, updated = 2022-03-21, EXP, noTF]
+% {
+% \str_case:nn, \str_case:Vn, \str_case:Nn, \str_case:on, \str_case:en,
+% \str_case:nV, \str_case:nv
+% }
+% \begin{syntax}
+% \cs{str_case:nnTF} \Arg{test string} \\
+% ~~|{| \\
+% ~~~~\Arg{string case_1} \Arg{code case_1} \\
+% ~~~~\Arg{string case_2} \Arg{code case_2} \\
+% ~~~~\ldots \\
+% ~~~~\Arg{string case_n} \Arg{code case_n} \\
+% ~~|}| \\
+% ~~\Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Compares the \meta{test string} in turn with each
+% of the \meta{string case}s (all token lists are converted to strings).
+% If the two are equal (as described for
+% \cs{str_if_eq:nnTF}) then the associated \meta{code} is left in the
+% input stream and other cases are discarded. If any of the
+% cases are matched, the \meta{true code} is also inserted into the
+% input stream (after the code for the appropriate case), while if none
+% match then the \meta{false code} is inserted. The function
+% \cs{str_case:nn}, which does nothing if there is no match, is also
+% available.
+%
+% This set of functions performs no expansion on each
+% \meta{string~case} argument, so any variable in there will be
+% compared as a string. If expansion is needed in the
+% \meta{string~case}s, then \cs[no-index]{str_case_e:nn(TF)} should
+% be used instead.
+% \end{function}
+%
+% \begin{function}[added = 2018-06-19, EXP, noTF]
+% {\str_case_e:nn, \str_case_e:en}
+% \begin{syntax}
+% \cs{str_case_e:nnTF} \Arg{test string} \\
+% ~~|{| \\
+% ~~~~\Arg{string case_1} \Arg{code case_1} \\
+% ~~~~\Arg{string case_2} \Arg{code case_2} \\
+% ~~~~\ldots \\
+% ~~~~\Arg{string case_n} \Arg{code case_n} \\
+% ~~|}| \\
+% ~~\Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Compares the full expansion of the \meta{test string}
+% in turn with the full expansion of the \meta{string case}s
+% (all token lists are converted to strings). If the two
+% full expansions are equal (as described for \cs{str_if_eq:eeTF}) then the
+% associated \meta{code} is left in the input stream
+% and other cases are discarded. If any of the
+% cases are matched, the \meta{true code} is also inserted into the
+% input stream (after the code for the appropriate case), while if none
+% match then the \meta{false code} is inserted. The function
+% \cs{str_case_e:nn}, which does nothing if there is no match, is also
+% available.
+% In \cs[index=str_case_e:nnTF]{str_case_e:nn(TF)}, the \meta{test string}
+% is expanded in each comparison, and must always yield the same result:
+% for example, random numbers must not be used within this string.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added = 2021-05-17]{\str_compare:nNn, \str_compare:eNe}
+% \begin{syntax}
+% \cs{str_compare_p:nNn} \Arg{tl_1} \meta{relation} \Arg{tl_2}
+% \cs{str_compare:nNnTF} \Arg{tl_1} \meta{relation} \Arg{tl_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Compares the two \meta{token lists} on a character by character
+% basis (namely after converting them to strings) in a lexicographic
+% order according to the character codes of the characters. The
+% \meta{relation} can be |<|, |=|, or~|>| and the test is
+% \texttt{true} under the following conditions:
+% \begin{itemize}
+% \item for |<|, if the first string is earlier than the second in lexicographic order;
+% \item for |=|, if the two strings have exactly the same characters;
+% \item for |>|, if the first string is later than the second in lexicographic order.
+% \end{itemize}
+% Thus for example the following is logically \texttt{true}:
+% \begin{verbatim}
+% \str_compare_p:nNn { ab } < { abc }
+% \end{verbatim}
+% \begin{texnote}
+% This is a wrapper around the \TeX{} primitive
+% \cs[index=pdfstrcmp]{(pdf)strcmp}. It is meant for programming
+% and not for sorting textual contents, as it simply considers
+% character codes and not more elaborate considerations of grapheme
+% clusters, locale, etc.
+% \end{texnote}
+% \end{function}
+%
+% \section{Mapping over strings}
+%
+% All mappings are done at the current group level, \emph{i.e.}~any
+% local assignments made by the \meta{function} or \meta{code} discussed
+% below remain in effect after the loop.
+%
+% \begin{function}[added = 2017-11-14, rEXP]
+% {\str_map_function:nN, \str_map_function:NN, \str_map_function:cN}
+% \begin{syntax}
+% \cs{str_map_function:nN} \Arg{token list} \meta{function}
+% \cs{str_map_function:NN} \meta{str~var} \meta{function}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string} then
+% applies \meta{function} to every \meta{character} in the
+% \meta{string} including spaces.
+% \end{function}
+%
+% \begin{function}[added = 2017-11-14]
+% {\str_map_inline:nn, \str_map_inline:Nn, \str_map_inline:cn}
+% \begin{syntax}
+% \cs{str_map_inline:nn} \Arg{token list} \Arg{inline function}
+% \cs{str_map_inline:Nn} \meta{str~var} \Arg{inline function}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string} then
+% applies the \meta{inline function} to every \meta{character} in the
+% \meta{str~var} including spaces.
+% The \meta{inline function} should consist of code which
+% receives the \meta{character} as |#1|.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2021-05-05]
+% {\str_map_tokens:nn, \str_map_tokens:Nn, \str_map_tokens:cn}
+% \begin{syntax}
+% \cs{str_map_tokens:nn} \Arg{token list} \Arg{code}
+% \cs{str_map_tokens:Nn} \meta{str~var} \Arg{code}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string} then applies
+% \meta{code} to every \meta{character} in the \meta{string} including
+% spaces. The \meta{code} receives each character as a trailing brace
+% group. This is equivalent to \cs{str_map_function:nN} if the
+% \meta{code} consists of a single function.
+% \end{function}
+%
+% \begin{function}[added = 2017-11-14]
+% {\str_map_variable:nNn, \str_map_variable:NNn, \str_map_variable:cNn}
+% \begin{syntax}
+% \cs{str_map_variable:nNn} \Arg{token list} \meta{variable} \Arg{code}
+% \cs{str_map_variable:NNn} \meta{str~var} \meta{variable} \Arg{code}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string} then stores each
+% \meta{character} in the \meta{string} (including spaces) in turn in
+% the (string or token list) \meta{variable} and applies the
+% \meta{code}. The \meta{code} will usually make use of the
+% \meta{variable}, but this is not enforced. The assignments to the
+% \meta{variable} are local. Its value after the loop is the last
+% \meta{character} in the \meta{string}, or its original value if the
+% \meta{string} is empty. See also \cs{str_map_inline:Nn}.
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08, rEXP]{\str_map_break:}
+% \begin{syntax}
+% \cs{str_map_break:}
+% \end{syntax}
+% Used to terminate a \cs[no-index]{str_map_\ldots} function before all
+% characters in the \meta{string} have been processed. This
+% normally takes place within a conditional statement, for example
+% \begin{verbatim}
+% \str_map_inline:Nn \l_my_str
+% {
+% \str_if_eq:nnT { #1 } { bingo } { \str_map_break: }
+% % Do something useful
+% }
+% \end{verbatim}
+% See also \cs{str_map_break:n}.
+% Use outside of a \cs[no-index]{str_map_\ldots} scenario leads to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted
+% before continuing with the
+% code that follows the loop.
+% This depends on the design of the mapping function.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08, rEXP]{\str_map_break:n}
+% \begin{syntax}
+% \cs{str_map_break:n} \Arg{code}
+% \end{syntax}
+% Used to terminate a \cs[no-index]{str_map_\ldots} function before all
+% characters in the \meta{string} have been processed, inserting
+% the \meta{code} after the mapping has ended. This
+% normally takes place within a conditional statement, for example
+% \begin{verbatim}
+% \str_map_inline:Nn \l_my_str
+% {
+% \str_if_eq:nnT { #1 } { bingo }
+% { \str_map_break:n { <code> } }
+% % Do something useful
+% }
+% \end{verbatim}
+% Use outside of a \cs[no-index]{str_map_\ldots} scenario leads to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted
+% before the \meta{code} is
+% inserted into the input stream.
+% This depends on the design of the mapping function.
+% \end{texnote}
+% \end{function}
+%
+% \section{Working with the content of strings}
+%
+% \begin{function}[EXP, added = 2015-09-18]{\str_use:N, \str_use:c}
+% \begin{syntax}
+% \cs{str_use:N} \meta{str~var}
+% \end{syntax}
+% Recovers the content of a \meta{str~var} and places it
+% directly in the input stream. An error is raised if the variable
+% does not exist or if it is invalid. Note that it is possible to use
+% a \meta{str} directly without an accessor function.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2015-09-18]
+% {\str_count:N, \str_count:c, \str_count:n, \str_count_ignore_spaces:n}
+% \begin{syntax}
+% \cs{str_count:n} \Arg{token list}
+% \end{syntax}
+% Leaves in the input stream the number of characters in the string
+% representation of \meta{token list}, as an integer denotation. The
+% functions differ in their treatment of spaces. In the case of
+% \cs{str_count:N} and \cs{str_count:n}, all characters including
+% spaces are counted. The \cs{str_count_ignore_spaces:n} function
+% leaves the number of non-space characters in the input stream.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2015-09-18]
+% {\str_count_spaces:N, \str_count_spaces:c, \str_count_spaces:n}
+% \begin{syntax}
+% \cs{str_count_spaces:n} \Arg{token list}
+% \end{syntax}
+% Leaves in the input stream the number of space characters in the
+% string representation of \meta{token list}, as an integer
+% denotation. Of course, this function has no \texttt{_ignore_spaces}
+% variant.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2015-09-18]
+% {\str_head:N, \str_head:c, \str_head:n, \str_head_ignore_spaces:n}
+% \begin{syntax}
+% \cs{str_head:n} \Arg{token list}
+% \end{syntax}
+% Converts the \meta{token list} into a \meta{string}. The first
+% character in the \meta{string} is then left in the input stream,
+% with category code \enquote{other}. The functions differ if the
+% first character is a space: \cs{str_head:N} and \cs{str_head:n}
+% return a space token with category code~$10$ (blank space), while
+% the \cs{str_head_ignore_spaces:n} function ignores this space
+% character and leaves the first non-space character in the input
+% stream. If the \meta{string} is empty (or only contains spaces in
+% the case of the \texttt{_ignore_spaces} function), then nothing is
+% left on the input stream.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2015-09-18]
+% {\str_tail:N, \str_tail:c, \str_tail:n, \str_tail_ignore_spaces:n}
+% \begin{syntax}
+% \cs{str_tail:n} \Arg{token list}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string}, removes the first
+% character, and leaves the remaining characters (if any) in the input
+% stream, with category codes $12$ and $10$ (for spaces). The
+% functions differ in the case where the first character is a space:
+% \cs{str_tail:N} and \cs{str_tail:n} only trim that space, while
+% \cs{str_tail_ignore_spaces:n} removes the first non-space character
+% and any space before it. If the \meta{token list} is empty (or
+% blank in the case of the \texttt{_ignore_spaces} variant), then
+% nothing is left on the input stream.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2015-09-18]
+% {\str_item:Nn, \str_item:nn, \str_item_ignore_spaces:nn}
+% \begin{syntax}
+% \cs{str_item:nn} \Arg{token list} \Arg{integer expression}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string}, and leaves in the
+% input stream the character in position \meta{integer expression} of
+% the \meta{string}, starting at $1$ for the first (left-most)
+% character. In the case of \cs{str_item:Nn} and \cs{str_item:nn},
+% all characters including spaces are taken into account. The
+% \cs{str_item_ignore_spaces:nn} function skips spaces when counting
+% characters. If the \meta{integer expression} is negative,
+% characters are counted from the end of the \meta{string}. Hence,
+% $-1$ is the right-most character, \emph{etc.}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2015-09-18]
+% {
+% \str_range:Nnn, \str_range:cnn, \str_range:nnn,
+% \str_range_ignore_spaces:nnn
+% }
+% \begin{syntax}
+% \cs{str_range:nnn} \Arg{token list} \Arg{start index} \Arg{end index}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string}, and leaves in the
+% input stream the characters from the \meta{start index} to the
+% \meta{end index} inclusive. Spaces are preserved and counted as items
+% (contrast this with \cs{tl_range:nnn} where spaces are not counted as
+% items and are possibly discarded from the output).
+%
+% Here \meta{start index} and \meta{end index} should be integer denotations.
+% For describing in detail the functions' behavior, let $m$ and $n$ be the start
+% and end index respectively. If either is $0$, the result is empty. A positive
+% index means `start counting from the left end', a negative index means
+% `start counting from the right end'. Let $l$ be the count of the token list.
+%
+% The \emph{actual start point} is determined as $M=m$ if~$m>0$ and as $M=l+m+1$
+% if~$m<0$. Similarly the \emph{actual end point} is $N=n$ if~$n>0$ and $N=l+n+1$
+% if~$n<0$. If $M>N$, the result is empty. Otherwise it consists of all items from
+% position $M$ to position $N$ inclusive; for the purpose of this rule, we can
+% imagine that the token list extends at infinity on either side, with void items
+% at positions $s$ for $s\le0$ or $s>l$.
+% For instance,
+% \begin{verbatim}
+% \iow_term:e { \str_range:nnn { abcdef } { 2 } { 5 } }
+% \iow_term:e { \str_range:nnn { abcdef } { -4 } { -1 } }
+% \iow_term:e { \str_range:nnn { abcdef } { -2 } { -1 } }
+% \iow_term:e { \str_range:nnn { abcdef } { 0 } { -1 } }
+% \end{verbatim}
+% prints \texttt{bcde}, \texttt{cdef}, \texttt{ef}, and an empty
+% line to the terminal. The \meta{start index} must always be smaller than
+% or equal to the \meta{end index}: if this is not the case then no output
+% is generated. Thus
+% \begin{verbatim}
+% \iow_term:e { \str_range:nnn { abcdef } { 5 } { 2 } }
+% \iow_term:e { \str_range:nnn { abcdef } { -1 } { -4 } }
+% \end{verbatim}
+% both yield empty strings.
+% \end{function}
+%
+% ^^A If this stays in the same {function} environment, we get a really
+% ^^A awful page break. Perhaps we should add a way to allow a page break
+% ^^A in a function environment...
+% The behavior of \cs{str_range_ignore_spaces:nnn} is similar, but spaces
+% are removed before starting the job. The input
+% \begin{verbatim}
+% \iow_term:e { \str_range:nnn { abcdefg } { 2 } { 5 } }
+% \iow_term:e { \str_range:nnn { abcdefg } { 2 } { -3 } }
+% \iow_term:e { \str_range:nnn { abcdefg } { -6 } { 5 } }
+% \iow_term:e { \str_range:nnn { abcdefg } { -6 } { -3 } }
+%
+% \iow_term:e { \str_range:nnn { abc~efg } { 2 } { 5 } }
+% \iow_term:e { \str_range:nnn { abc~efg } { 2 } { -3 } }
+% \iow_term:e { \str_range:nnn { abc~efg } { -6 } { 5 } }
+% \iow_term:e { \str_range:nnn { abc~efg } { -6 } { -3 } }
+%
+% \iow_term:e { \str_range_ignore_spaces:nnn { abcdefg } { 2 } { 5 } }
+% \iow_term:e { \str_range_ignore_spaces:nnn { abcdefg } { 2 } { -3 } }
+% \iow_term:e { \str_range_ignore_spaces:nnn { abcdefg } { -6 } { 5 } }
+% \iow_term:e { \str_range_ignore_spaces:nnn { abcdefg } { -6 } { -3 } }
+%
+% \iow_term:e { \str_range_ignore_spaces:nnn { abcd~efg } { 2 } { 5 } }
+% \iow_term:e { \str_range_ignore_spaces:nnn { abcd~efg } { 2 } { -3 } }
+% \iow_term:e { \str_range_ignore_spaces:nnn { abcd~efg } { -6 } { 5 } }
+% \iow_term:e { \str_range_ignore_spaces:nnn { abcd~efg } { -6 } { -3 } }
+% \end{verbatim}
+% will print four instances of |bcde|, four instances of |bc e| and eight
+% instances of |bcde|.
+% ^^A\end{function}
+%
+% \section{Modifying string variables}
+%
+% \begin{function}[added = 2017-10-08]
+% {
+% \str_replace_once:Nnn, \str_replace_once:cnn,
+% \str_greplace_once:Nnn, \str_greplace_once:cnn
+% }
+% \begin{syntax}
+% \cs{str_replace_once:Nnn} \meta{str~var} \Arg{old} \Arg{new}
+% \end{syntax}
+% Converts the \meta{old} and \meta{new} token lists to strings, then
+% replaces the first (leftmost) occurrence of \meta{old string} in the
+% \meta{str~var} with \meta{new string}.
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08]
+% {
+% \str_replace_all:Nnn, \str_replace_all:cnn,
+% \str_greplace_all:Nnn, \str_greplace_all:cnn
+% }
+% \begin{syntax}
+% \cs{str_replace_all:Nnn} \meta{str~var} \Arg{old} \Arg{new}
+% \end{syntax}
+% Converts the \meta{old} and \meta{new} token lists to strings, then
+% replaces all occurrences of \meta{old string} in the
+% \meta{str~var} with \meta{new string}.
+% As this function
+% operates from left to right, the pattern \meta{old string}
+% may remain after the replacement (see \cs{str_remove_all:Nn}
+% for an example).
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08]
+% {
+% \str_remove_once:Nn, \str_remove_once:cn,
+% \str_gremove_once:Nn, \str_gremove_once:cn
+% }
+% \begin{syntax}
+% \cs{str_remove_once:Nn} \meta{str~var} \Arg{token list}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string} then
+% removes the first (leftmost) occurrence of \meta{string} from the
+% \meta{str~var}.
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08]
+% {
+% \str_remove_all:Nn, \str_remove_all:cn,
+% \str_gremove_all:Nn, \str_gremove_all:cn
+% }
+% \begin{syntax}
+% \cs{str_remove_all:Nn} \meta{str~var} \Arg{token list}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string} then
+% removes all occurrences of \meta{string} from the
+% \meta{str~var}.
+% As this function
+% operates from left to right, the pattern \meta{string}
+% may remain after the removal, for instance,
+% \begin{quote}
+% \cs{str_set:Nn} \cs{l_tmpa_str} |{abbccd}|
+% \cs{str_remove_all:Nn} \cs{l_tmpa_str} |{bc}|
+% \end{quote}
+% results in \cs{l_tmpa_str} containing \texttt{abcd}.
+% \end{function}
+%
+% \section{String manipulation}
+%
+% \begin{function}[EXP, added = 2019-11-26]
+% {
+% \str_lowercase:n, \str_lowercase:f,
+% \str_uppercase:n, \str_uppercase:f
+% }
+% \begin{syntax}
+% \cs{str_lowercase:n} \Arg{tokens}
+% \cs{str_uppercase:n} \Arg{tokens}
+% \end{syntax}
+% Converts the input \meta{tokens} to their string representation, as
+% described for \cs{tl_to_str:n}, and then to the lower or upper
+% case representation using a one-to-one mapping as described by the
+% Unicode Consortium file |UnicodeData.txt|.
+%
+% These functions are intended for case changing programmatic data in
+% places where upper/lower case distinctions are meaningful. One example
+% would be automatically generating a function name from user input where
+% some case changing is needed. In this situation the input is programmatic,
+% not textual, case does have meaning and a language-independent one-to-one
+% mapping is appropriate. For example
+% \begin{verbatim}
+% \cs_new_protected:Npn \myfunc:nn #1#2
+% {
+% \cs_set_protected:cpn
+% {
+% user
+% \str_uppercase:f { \tl_head:n {#1} }
+% \str_lowercase:f { \tl_tail:n {#1} }
+% }
+% { #2 }
+% }
+% \end{verbatim}
+% would be used to generate a function with an auto-generated name consisting
+% of the upper case equivalent of the supplied name followed by the lower
+% case equivalent of the rest of the input.
+%
+% These functions should \emph{not} be used for
+% \begin{itemize}
+% \item Caseless comparisons: use \cs{str_casefold:n} for this
+% situation (case folding is distinct from lower casing).
+% \item Case changing text for typesetting: see the
+% \cs[index=text_lowercase:n]{text_lowercase:n(n)},
+% \cs[index=text_uppercase:n]{text_uppercase:n(n)} and
+% \cs[index=text_titlecase_all:n]{text_titlecase_(all|once):n(n)} functions which
+% correctly deal with context-dependence and other factors appropriate
+% to text case changing.
+% \end{itemize}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2022-10-16]
+% {\str_casefold:n, \str_casefold:V}
+% \begin{syntax}
+% \cs{str_casefold:n} \Arg{tokens}
+% \end{syntax}
+% Converts the input \meta{tokens} to their string representation, as
+% described for \cs{tl_to_str:n}, and then folds the case of the resulting
+% \meta{string} to remove case information. The result of this process is
+% left in the input stream.
+%
+% String folding is a process used for material such as identifiers rather
+% than for \enquote{text}. The folding provided by \cs{str_casefold:n}
+% follows the mappings provided by the \href{http://www.unicode.org}^^A
+% {Unicode Consortium}, who
+% \href{http://www.unicode.org/faq/casemap_charprop.html#2}{state}:
+% \begin{quote}
+% Case folding is primarily used for caseless comparison of text, such
+% as identifiers in a computer program, rather than actual text
+% transformation. Case folding in Unicode is based on the lowercase
+% mapping, but includes additional changes to the source text to help make
+% it language-insensitive and consistent. As a result, case-folded text
+% should be used solely for internal processing and generally should not be
+% stored or displayed to the end user.
+% \end{quote}
+% The folding approach implemented by \cs{str_casefold:n} follows the
+% \enquote{full} scheme defined by the Unicode Consortium
+% (\emph{e.g.}~\SS folds to \texttt{SS}). As case-folding is
+% a language-insensitive process, there is no special treatment of
+% Turkic input (\emph{i.e.}~\texttt{I} always folds to \texttt{i} and
+% not to \texttt{\i}).
+% \end{function}
+%
+% \begin{function}[added = 2023-05-19, EXP]{\str_mdfive_hash:n, \str_mdfive_hash:e}
+% \begin{syntax}
+% \cs{str_mdfive_hash:n} \Arg{tl}
+% \end{syntax}
+% Expands to the MD5 sum generated from the \meta{tl}, which is converted
+% to a \meta{string} as described for \cs{tl_to_str:n}.
+% \end{function}
+%
+% \section{Viewing strings}
+%
+% \begin{function}[added = 2015-09-18, updated = 2021-04-29]
+% {\str_show:N, \str_show:c, \str_show:n}
+% \begin{syntax}
+% \cs{str_show:N} \meta{str~var}
+% \end{syntax}
+% Displays the content of the \meta{str~var} on the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2019-02-15, updated = 2021-04-29]
+% {\str_log:N, \str_log:c, \str_log:n}
+% \begin{syntax}
+% \cs{str_log:N} \meta{str~var}
+% \end{syntax}
+% Writes the content of the \meta{str~var} in the log file.
+% \end{function}
+%
+% \section{Constant strings}
+%
+% \begin{variable}[added = 2015-09-19, updated = 2020-12-22, module = str]
+% {
+% \c_ampersand_str,
+% \c_atsign_str,
+% \c_backslash_str,
+% \c_left_brace_str,
+% \c_right_brace_str,
+% \c_circumflex_str,
+% \c_colon_str,
+% \c_dollar_str,
+% \c_hash_str,
+% \c_percent_str,
+% \c_tilde_str,
+% \c_underscore_str,
+% \c_zero_str
+% }
+% Constant strings, containing a single character token, with category
+% code $12$.
+% \end{variable}
+%
+% \begin{variable}[added = 2023-12-07]{\c_empty_str}
+% Constant that is always empty.
+% \end{variable}
+%
+% \section{Scratch strings}
+%
+% \begin{variable}{\l_tmpa_str, \l_tmpb_str}
+% Scratch strings for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_str, \g_tmpb_str}
+% Scratch strings for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3str} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=str>
+% \end{macrocode}
+%
+% \subsection{Internal auxiliaries}
+%
+% \begin{variable}{\s_@@_mark,\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{
+% \@@_use_none_delimit_by_s_stop:w,
+% \@@_use_i_delimit_by_s_stop:nw
+% }
+% Functions to gobble up to a scan mark.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_none_delimit_by_s_stop:w #1 \s_@@_stop { }
+\cs_new:Npn \@@_use_i_delimit_by_s_stop:nw #1 #2 \s_@@_stop {#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\q_@@_recursion_tail,\q_@@_recursion_stop}
+% Internal recursion quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_recursion_tail
+\quark_new:N \q_@@_recursion_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{
+% \@@_if_recursion_tail_break:NN,
+% \@@_if_recursion_tail_stop_do:Nn
+% }
+% Functions to query recursion quarks.
+% \begin{macrocode}
+\__kernel_quark_new_test:N \@@_if_recursion_tail_break:NN
+\__kernel_quark_new_test:N \@@_if_recursion_tail_stop_do:Nn
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Creating and setting string variables}
+%
+% \begin{macro}
+% {
+% \str_new:N, \str_new:c,
+% \str_use:N, \str_use:c,
+% \str_clear:N, \str_clear:c,
+% \str_gclear:N,\str_gclear:c,
+% \str_clear_new:N, \str_clear_new:c,
+% \str_gclear_new:N, \str_gclear_new:c
+% }
+% \begin{macro}
+% {
+% \str_set_eq:NN, \str_set_eq:cN, \str_set_eq:Nc, \str_set_eq:cc,
+% \str_gset_eq:NN, \str_gset_eq:cN, \str_gset_eq:Nc, \str_gset_eq:cc
+% }
+% \begin{macro}
+% {\str_concat:NNN, \str_concat:ccc, \str_gconcat:NNN, \str_gconcat:ccc}
+% A string is simply a token list. The full mapping system isn't set up
+% yet so do things by hand.
+% \begin{macrocode}
+\group_begin:
+ \cs_set_protected:Npn \@@_tmp:n #1
+ {
+ \tl_if_blank:nF {#1}
+ {
+ \cs_new_eq:cc { str_ #1 :N } { tl_ #1 :N }
+ \exp_args:Nc \cs_generate_variant:Nn { str_ #1 :N } { c }
+ \@@_tmp:n
+ }
+ }
+ \@@_tmp:n
+ { new }
+ { use }
+ { clear }
+ { gclear }
+ { clear_new }
+ { gclear_new }
+ { }
+\group_end:
+\cs_new_eq:NN \str_set_eq:NN \tl_set_eq:NN
+\cs_new_eq:NN \str_gset_eq:NN \tl_gset_eq:NN
+\cs_generate_variant:Nn \str_set_eq:NN { c , Nc , cc }
+\cs_generate_variant:Nn \str_gset_eq:NN { c , Nc , cc }
+\cs_new_eq:NN \str_concat:NNN \tl_concat:NNN
+\cs_new_eq:NN \str_gconcat:NNN \tl_gconcat:NNN
+\cs_generate_variant:Nn \str_concat:NNN { ccc }
+\cs_generate_variant:Nn \str_gconcat:NNN { ccc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \str_set:Nn, \str_set:NV, \str_set:Ne, \str_set:Nx,
+% \str_set:cn, \str_set:cV, \str_set:ce, \str_set:cx,
+% \str_gset:Nn, \str_gset:NV, \str_gset:Ne, \str_gset:Nx,
+% \str_gset:cn, \str_gset:cV, \str_gset:ce, \str_gset:cx,
+% \str_const:Nn, \str_const:NV, \str_const:Ne, \str_const:Nx,
+% \str_const:cn, \str_const:cV, \str_const:ce, \str_const:cx,
+% \str_put_left:Nn, \str_put_left:NV, \str_put_left:Ne, \str_put_left:Nx,
+% \str_put_left:cn, \str_put_left:cV, \str_put_left:ce, \str_put_left:cx,
+% \str_gput_left:Nn, \str_gput_left:NV, \str_gput_left:Ne, \str_gput_left:Nx,
+% \str_gput_left:cn, \str_gput_left:cV, \str_gput_left:ce, \str_gput_left:cx,
+% \str_put_right:Nn, \str_put_right:NV, \str_put_right:Ne, \str_put_right:Nx,
+% \str_put_right:cn, \str_put_right:cV, \str_put_right:ce, \str_put_right:cx,
+% \str_gput_right:Nn, \str_gput_right:NV, \str_gput_right:Ne, \str_gput_right:Nx,
+% \str_gput_right:cn, \str_gput_right:cV, \str_gput_right:ce, \str_gput_right:cx
+% }
+% Similar to corresponding \pkg{l3tl} base functions, except that
+% \cs{__kernel_exp_not:w} is replaced with \cs{__kernel_tl_to_str:w}.
+% Just like token list, string constants use \cs{cs_gset_nopar:Npe}
+% instead of \cs{__kernel_tl_gset:Nx} so that the scope checking for
+% |c| is applied when \pkg{l3debug} is used.
+% To maintain backward compatibility, in
+% \cs[index=str_put_left:Nn]{str_(g)put_left:Nn} and
+% \cs[index=str_put_right:Nn]{str_(g)put_right:Nn},
+% contents of string variables are wrapped in \cs{__kernel_exp_not:w}
+% to prevent further expansion.
+% \begin{macrocode}
+\cs_new_protected:Npn \str_set:Nn #1#2
+ { \__kernel_tl_set:Nx #1 { \__kernel_tl_to_str:w {#2} } }
+\cs_gset_protected:Npn \str_gset:Nn #1#2
+ { \__kernel_tl_gset:Nx #1 { \__kernel_tl_to_str:w {#2} } }
+\cs_new_protected:Npn \str_const:Nn #1#2
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \cs_gset_nopar:Npe #1 { \__kernel_tl_to_str:w {#2} }
+ }
+\cs_new_protected:Npn \str_put_left:Nn #1#2
+ {
+ \__kernel_tl_set:Nx #1
+ { \__kernel_tl_to_str:w {#2} \__kernel_exp_not:w \exp_after:wN {#1} }
+ }
+\cs_new_protected:Npn \str_gput_left:Nn #1#2
+ {
+ \__kernel_tl_gset:Nx #1
+ { \__kernel_tl_to_str:w {#2} \__kernel_exp_not:w \exp_after:wN {#1} }
+ }
+\cs_new_protected:Npn \str_put_right:Nn #1#2
+ {
+ \__kernel_tl_set:Nx #1
+ { \__kernel_exp_not:w \exp_after:wN {#1} \__kernel_tl_to_str:w {#2} }
+ }
+\cs_new_protected:Npn \str_gput_right:Nn #1#2
+ {
+ \__kernel_tl_gset:Nx #1
+ { \__kernel_exp_not:w \exp_after:wN {#1} \__kernel_tl_to_str:w {#2} }
+ }
+\cs_generate_variant:Nn \str_set:Nn { NV , Ne , Nx , c , cV , ce , cx }
+\cs_generate_variant:Nn \str_gset:Nn { NV , Ne , Nx , c , cV , ce , cx }
+\cs_generate_variant:Nn \str_const:Nn { NV , Ne , Nx , c , cV , ce , cx }
+\cs_generate_variant:Nn \str_put_left:Nn { NV , Ne , Nx , c , cV , ce , cx }
+\cs_generate_variant:Nn \str_gput_left:Nn { NV , Ne , Nx , c , cV , ce , cx }
+\cs_generate_variant:Nn \str_put_right:Nn { NV , Ne , Nx , c , cV , ce , cx }
+\cs_generate_variant:Nn \str_gput_right:Nn { NV , Ne , Nx , c , cV , ce , cx }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Modifying string variables}
+%
+% \begin{macro}
+% {
+% \str_replace_all:Nnn, \str_replace_all:cnn,
+% \str_greplace_all:Nnn, \str_greplace_all:cnn,
+% \str_replace_once:Nnn, \str_replace_once:cnn,
+% \str_greplace_once:Nnn, \str_greplace_once:cnn
+% }
+% \begin{macro}{\@@_replace:NNNnn}
+% \begin{macro}{\@@_replace_aux:NNNnnn}
+% \begin{macro}{\@@_replace_next:w}
+% Start by applying \cs{tl_to_str:n} to convert the old and new token
+% lists to strings, and also apply \cs{tl_to_str:N} to avoid any
+% issues if we are fed a token list variable. Then the code is a much
+% simplified version of the token list code because neither the
+% delimiter nor the replacement can contain macro parameters or
+% braces. The delimiter \cs{s_@@_mark} cannot appear in the string to
+% edit so it is used in all cases. Some |e|-expansion is unnecessary.
+% There is no need to avoid losing braces nor to protect against
+% expansion. The ending code is much simplified and does not need to
+% hide in braces.
+% \begin{macrocode}
+\cs_new_protected:Npn \str_replace_once:Nnn
+ { \@@_replace:NNNnn \prg_do_nothing: \__kernel_tl_set:Nx }
+\cs_new_protected:Npn \str_greplace_once:Nnn
+ { \@@_replace:NNNnn \prg_do_nothing: \__kernel_tl_gset:Nx }
+\cs_new_protected:Npn \str_replace_all:Nnn
+ { \@@_replace:NNNnn \@@_replace_next:w \__kernel_tl_set:Nx }
+\cs_new_protected:Npn \str_greplace_all:Nnn
+ { \@@_replace:NNNnn \@@_replace_next:w \__kernel_tl_gset:Nx }
+\cs_generate_variant:Nn \str_replace_once:Nnn { c }
+\cs_generate_variant:Nn \str_greplace_once:Nnn { c }
+\cs_generate_variant:Nn \str_replace_all:Nnn { c }
+\cs_generate_variant:Nn \str_greplace_all:Nnn { c }
+\cs_new_protected:Npn \@@_replace:NNNnn #1#2#3#4#5
+ {
+ \tl_if_empty:nTF {#4}
+ {
+ \msg_error:nne { kernel } { empty-search-pattern } {#5}
+ }
+ {
+ \use:e
+ {
+ \exp_not:n { \@@_replace_aux:NNNnnn #1 #2 #3 }
+ { \tl_to_str:N #3 }
+ { \tl_to_str:n {#4} } { \tl_to_str:n {#5} }
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_replace_aux:NNNnnn #1#2#3#4#5#6
+ {
+ \cs_set:Npn \@@_replace_next:w ##1 #5 { ##1 #6 #1 }
+ #2 #3
+ {
+ \@@_replace_next:w
+ #4
+ \@@_use_none_delimit_by_s_stop:w
+ #5
+ \s_@@_stop
+ }
+ }
+\cs_new_eq:NN \@@_replace_next:w ?
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\str_remove_once:Nn, \str_remove_once:cn}
+% \begin{macro}{\str_gremove_once:Nn, \str_gremove_once:cn}
+% Removal is just a special case of replacement.
+% \begin{macrocode}
+\cs_new_protected:Npn \str_remove_once:Nn #1#2
+ { \str_replace_once:Nnn #1 {#2} { } }
+\cs_new_protected:Npn \str_gremove_once:Nn #1#2
+ { \str_greplace_once:Nnn #1 {#2} { } }
+\cs_generate_variant:Nn \str_remove_once:Nn { c }
+\cs_generate_variant:Nn \str_gremove_once:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\str_remove_all:Nn, \str_remove_all:cn}
+% \begin{macro}{\str_gremove_all:Nn, \str_gremove_all:cn}
+% Removal is just a special case of replacement.
+% \begin{macrocode}
+\cs_new_protected:Npn \str_remove_all:Nn #1#2
+ { \str_replace_all:Nnn #1 {#2} { } }
+\cs_new_protected:Npn \str_gremove_all:Nn #1#2
+ { \str_greplace_all:Nnn #1 {#2} { } }
+\cs_generate_variant:Nn \str_remove_all:Nn { c }
+\cs_generate_variant:Nn \str_gremove_all:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{String comparisons}
+%
+% \begin{macro}[pTF, EXP]
+% {
+% \str_if_empty:N, \str_if_empty:c, \str_if_empty:n,
+% \str_if_exist:N, \str_if_exist:c
+% }
+% More copy-paste!
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \str_if_exist:N \tl_if_exist:N
+ { p , T , F , TF }
+\prg_new_eq_conditional:NNn \str_if_exist:c \tl_if_exist:c
+ { p , T , F , TF }
+\prg_new_eq_conditional:NNn \str_if_empty:N \tl_if_empty:N
+ { p , T , F , TF }
+\prg_new_eq_conditional:NNn \str_if_empty:c \tl_if_empty:c
+ { p , T , F , TF }
+\prg_new_eq_conditional:NNn \str_if_empty:n \tl_if_empty:n
+ { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_if_eq:nn}
+% String comparisons rely on the primitive \tn[index=pdfstrcmp]{(pdf)strcmp},
+% so we define a new name for it.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_if_eq:nn \tex_strcmp:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF, EXP]{\str_compare:nNn, \str_compare:eNe}
+% Simply rely on \cs{@@_if_eq:nn}, which expands to |-1|, |0|
+% or~|1|. The |ee| version is created directly because it is more efficient.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \str_compare:nNn #1#2#3 { p , T , F , TF }
+ {
+ \if_int_compare:w
+ \@@_if_eq:nn { \exp_not:n {#1} } { \exp_not:n {#3} }
+ #2 \c_zero_int
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \str_compare:eNe #1#2#3 { p , T , F , TF }
+ {
+ \if_int_compare:w \@@_if_eq:nn {#1} {#3} #2 \c_zero_int
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF, EXP]
+% {
+% \str_if_eq:nn, \str_if_eq:Vn, \str_if_eq:on, \str_if_eq:nV,
+% \str_if_eq:no, \str_if_eq:VV,
+% \str_if_eq:ee
+% }
+% Modern engines provide a direct way of comparing two token lists,
+% but returning a number. This set of conditionals therefore makes life
+% a bit clearer. The \texttt{nn} and \texttt{ee} versions are created
+% directly as this is most efficient. Since \cs{@@_if_eq:nn} will expand to
+% |0| as an explicit character with category 12 if the two lists match (and
+% either |-1| or |1| if they don't) we can use \cs{if:w} here which is faster
+% than using \cs{if_int_compare:w}.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \str_if_eq:nn #1#2 { p , T , F , TF }
+ {
+ \if:w 0 \@@_if_eq:nn { \exp_not:n {#1} } { \exp_not:n {#2} }
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_generate_conditional_variant:Nnn \str_if_eq:nn
+ { V , v , o , nV , no , VV , nv } { p , T , F , TF }
+\prg_new_conditional:Npnn \str_if_eq:ee #1#2 { p , T , F , TF }
+ {
+ \if:w 0 \@@_if_eq:nn {#1} {#2}
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, pTF]
+% {\str_if_eq:NN, \str_if_eq:Nc, \str_if_eq:cN, \str_if_eq:cc}
+% Note that \cs{str_if_eq:NNTF} is different from
+% \cs{tl_if_eq:NNTF} because it needs to ignore category codes.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \str_if_eq:NN #1#2 { p , TF , T , F }
+ {
+ \if:w 0 \@@_if_eq:nn { \tl_to_str:N #1 } { \tl_to_str:N #2 }
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_generate_conditional_variant:Nnn \str_if_eq:NN
+ { c , Nc , cc } { T , F , TF , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\str_if_in:Nn, \str_if_in:cn, \str_if_in:nn}
+% Everything here needs to be detokenized but beyond that it is a
+% simple token list test. It would be faster to fine-tune the |T|,
+% |F|, |TF| variants by calling the appropriate variant of
+% \cs{tl_if_in:nnTF} directly but that takes more code.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \str_if_in:Nn #1#2 { T , F , TF }
+ {
+ \use:e
+ { \tl_if_in:nnTF { \tl_to_str:N #1 } { \tl_to_str:n {#2} } }
+ { \prg_return_true: } { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn \str_if_in:Nn
+ { c } { T , F , TF }
+\prg_new_protected_conditional:Npnn \str_if_in:nn #1#2 { T , F , TF }
+ {
+ \use:e
+ { \tl_if_in:nnTF { \tl_to_str:n {#1} } { \tl_to_str:n {#2} } }
+ { \prg_return_true: } { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, noTF]
+% {
+% \str_case:nn, \str_case:Vn, \str_case:Nn, \str_case:on, \str_case:en, \str_case:nV, \str_case:nv,
+% \str_case_e:nn, \str_case_e:en
+% }
+% \begin{macro}[EXP]{\@@_case:nnTF, \@@_case_e:nnTF}
+% \begin{macro}[EXP]
+% {\@@_case:nw, \@@_case_e:nw, \@@_case_end:nw}
+% The aim here is to allow the case statement to be evaluated
+% using a known number of expansion steps (two), and without
+% needing to use an explicit \enquote{end of recursion} marker.
+% That is achieved by using the test input as the final case,
+% as this is always true. The trick is then to tidy up
+% the output such that the appropriate case code plus either
+% the \texttt{true} or \texttt{false} branch code is inserted.
+% \begin{macrocode}
+\cs_new:Npn \str_case:nn #1#2
+ {
+ \exp:w
+ \@@_case:nnTF {#1} {#2} { } { }
+ }
+\cs_new:Npn \str_case:nnT #1#2#3
+ {
+ \exp:w
+ \@@_case:nnTF {#1} {#2} {#3} { }
+ }
+\cs_new:Npn \str_case:nnF #1#2
+ {
+ \exp:w
+ \@@_case:nnTF {#1} {#2} { }
+ }
+\cs_new:Npn \str_case:nnTF #1#2
+ {
+ \exp:w
+ \@@_case:nnTF {#1} {#2}
+ }
+\cs_new:Npn \@@_case:nnTF #1#2#3#4
+ { \@@_case:nw {#1} #2 {#1} { } \s_@@_mark {#3} \s_@@_mark {#4} \s_@@_stop }
+\cs_generate_variant:Nn \str_case:nn { V , o , e , nV , nv }
+\prg_generate_conditional_variant:Nnn \str_case:nn
+ { V , o , e , nV , nv } { T , F , TF }
+\cs_new_eq:NN \str_case:Nn \str_case:Vn
+\cs_new_eq:NN \str_case:NnT \str_case:VnT
+\cs_new_eq:NN \str_case:NnF \str_case:VnF
+\cs_new_eq:NN \str_case:NnTF \str_case:VnTF
+\cs_new:Npn \@@_case:nw #1#2#3
+ {
+ \str_if_eq:nnTF {#1} {#2}
+ { \@@_case_end:nw {#3} }
+ { \@@_case:nw {#1} }
+ }
+\cs_new:Npn \str_case_e:nn #1#2
+ {
+ \exp:w
+ \@@_case_e:nnTF {#1} {#2} { } { }
+ }
+\cs_new:Npn \str_case_e:nnT #1#2#3
+ {
+ \exp:w
+ \@@_case_e:nnTF {#1} {#2} {#3} { }
+ }
+\cs_new:Npn \str_case_e:nnF #1#2
+ {
+ \exp:w
+ \@@_case_e:nnTF {#1} {#2} { }
+ }
+\cs_new:Npn \str_case_e:nnTF #1#2
+ {
+ \exp:w
+ \@@_case_e:nnTF {#1} {#2}
+ }
+\cs_new:Npn \@@_case_e:nnTF #1#2#3#4
+ { \@@_case_e:nw {#1} #2 {#1} { } \s_@@_mark {#3} \s_@@_mark {#4} \s_@@_stop }
+\cs_generate_variant:Nn \str_case_e:nn { e }
+\prg_generate_conditional_variant:Nnn \str_case_e:nn { e } { T , F , TF }
+\cs_new:Npn \@@_case_e:nw #1#2#3
+ {
+ \str_if_eq:eeTF {#1} {#2}
+ { \@@_case_end:nw {#3} }
+ { \@@_case_e:nw {#1} }
+ }
+% \end{macrocode}
+% To tidy up the recursion, there are two outcomes. If there was a hit to
+% one of the cases searched for, then |#1| is the code to insert,
+% |#2| is the \emph{next} case to check on and |#3| is all of
+% the rest of the cases code. That means that |#4| is the \texttt{true}
+% branch code, and |#5| tidies up the spare \cs{s_@@_mark} and the
+% \texttt{false} branch. On the other hand, if none of the cases matched
+% then we arrive here using the \enquote{termination} case of comparing
+% the search with itself. That means that |#1| is empty, |#2| is
+% the first \cs{s_@@_mark} and so |#4| is the \texttt{false} code (the
+% \texttt{true} code is mopped up by |#3|).
+% \begin{macrocode}
+\cs_new:Npn \@@_case_end:nw #1#2#3 \s_@@_mark #4#5 \s_@@_stop
+ { \exp_end: #1 #4 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Mapping over strings}
+%
+% \begin{macro}[rEXP]{\str_map_function:NN, \str_map_function:cN}
+% \begin{macro}[rEXP]{\str_map_function:nN}
+% \begin{macro}{\str_map_inline:Nn, \str_map_inline:cn}
+% \begin{macro}{\str_map_inline:nn}
+% \begin{macro}{\str_map_variable:NNn, \str_map_variable:cNn}
+% \begin{macro}{\str_map_variable:nNn}
+% \begin{macro}{\str_map_break:}
+% \begin{macro}{\str_map_break:n}
+% \begin{macro}[rEXP]{\@@_map_function:w, \@@_map_function:nn}
+% \begin{macro}{\@@_map_inline:NN, \@@_map_variable:NnN}
+% The inline and variable mappings are similar to the usual token list
+% mappings but start out by turning the argument to an ``other
+% string''. Doing the same for the expandable function mapping would
+% require \cs{__kernel_str_to_other:n}, quadratic in the string length. To deal
+% with spaces in that case, \cs{@@_map_function:w} replaces the
+% following space by a braced space and a further call to itself.
+% These are received by \cs{@@_map_function:nn}, which passes
+% the space to |#1| and calls \cs{@@_map_function:w} to deal with the
+% next space. The space before the braced space allows to optimize
+% the \cs{q_@@_recursion_tail} test. Of course we need to include a
+% trailing space (the question mark is needed to avoid losing the
+% space when \TeX{} tokenizes the line).
+% At the cost of about three more auxiliaries this code could get a $9$
+% times speed up by testing only every $9$-th character for whether it
+% is \cs{q_@@_recursion_tail} (also by converting $9$ spaces at a time in
+% the \cs{str_map_function:nN} case).
+%
+% For the \texttt{map_variable} functions we use a string assignment
+% to store each character because spaces are made catcode~$12$ before
+% the loop.
+% \begin{macrocode}
+\cs_new:Npn \str_map_function:nN #1#2
+ {
+ \exp_after:wN \@@_map_function:w
+ \exp_after:wN \@@_map_function:nn \exp_after:wN #2
+ \__kernel_tl_to_str:w {#1}
+ \q_@@_recursion_tail ? ~
+ \prg_break_point:Nn \str_map_break: { }
+ }
+\cs_new:Npn \str_map_function:NN
+ { \exp_args:No \str_map_function:nN }
+\cs_new:Npn \@@_map_function:w #1 ~
+ { #1 { ~ { ~ } \@@_map_function:w } }
+\cs_new:Npn \@@_map_function:nn #1#2
+ {
+ \if_meaning:w \q_@@_recursion_tail #2
+ \exp_after:wN \str_map_break:
+ \fi:
+ #1 #2 \@@_map_function:nn {#1}
+ }
+\cs_generate_variant:Nn \str_map_function:NN { c }
+\cs_new_protected:Npn \str_map_inline:nn #1#2
+ {
+ \int_gincr:N \g__kernel_prg_map_int
+ \cs_gset_protected:cpn
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w } ##1 {#2}
+ \use:e
+ {
+ \exp_not:N \@@_map_inline:NN
+ \exp_not:c { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
+ \__kernel_str_to_other_fast:n {#1}
+ }
+ \q_@@_recursion_tail
+ \prg_break_point:Nn \str_map_break:
+ { \int_gdecr:N \g__kernel_prg_map_int }
+ }
+\cs_new_protected:Npn \str_map_inline:Nn
+ { \exp_args:No \str_map_inline:nn }
+\cs_generate_variant:Nn \str_map_inline:Nn { c }
+\cs_new:Npn \@@_map_inline:NN #1#2
+ {
+ \@@_if_recursion_tail_break:NN #2 \str_map_break:
+ \exp_args:No #1 { \token_to_str:N #2 }
+ \@@_map_inline:NN #1
+ }
+\cs_new_protected:Npn \str_map_variable:nNn #1#2#3
+ {
+ \use:e
+ {
+ \exp_not:n { \@@_map_variable:NnN #2 {#3} }
+ \__kernel_str_to_other_fast:n {#1}
+ }
+ \q_@@_recursion_tail
+ \prg_break_point:Nn \str_map_break: { }
+ }
+\cs_new_protected:Npn \str_map_variable:NNn
+ { \exp_args:No \str_map_variable:nNn }
+\cs_new_protected:Npn \@@_map_variable:NnN #1#2#3
+ {
+ \@@_if_recursion_tail_break:NN #3 \str_map_break:
+ \str_set:Nn #1 {#3}
+ \use:n {#2}
+ \@@_map_variable:NnN #1 {#2}
+ }
+\cs_generate_variant:Nn \str_map_variable:NNn { c }
+\cs_new:Npn \str_map_break:
+ { \prg_map_break:Nn \str_map_break: { } }
+\cs_new:Npn \str_map_break:n
+ { \prg_map_break:Nn \str_map_break: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\str_map_tokens:Nn, \str_map_tokens:cn}
+% \begin{macro}[rEXP]{\str_map_tokens:nn}
+% Uses an auxiliary of \cs{str_map_function:NN}.
+% \begin{macrocode}
+\cs_new:Npn \str_map_tokens:nn #1#2
+ {
+ \exp_args:Nno \use:nn
+ { \@@_map_function:w \@@_map_function:nn {#2} }
+ { \__kernel_tl_to_str:w {#1} }
+ \q_@@_recursion_tail ? ~
+ \prg_break_point:Nn \str_map_break: { }
+ }
+\cs_new:Npn \str_map_tokens:Nn { \exp_args:No \str_map_tokens:nn }
+\cs_generate_variant:Nn \str_map_tokens:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Accessing specific characters in a string}
+%
+% \begin{macro}[EXP]{\__kernel_str_to_other:n}
+% \begin{macro}[EXP]{\@@_to_other_loop:w, \@@_to_other_end:w}
+% First apply \cs{tl_to_str:n}, then replace all spaces by
+% \enquote{other} spaces, $8$ at a time, storing the converted part of
+% the string between the \cs{s_@@_mark} and \cs{s_@@_stop} markers. The end
+% is detected when \cs{@@_to_other_loop:w} finds one of the trailing
+% |A|, distinguished from any contents of the initial token list by
+% their category. Then \cs{@@_to_other_end:w} is called, and finds
+% the result between \cs{s_@@_mark} and the first |A| (well, there is
+% also the need to remove a space).
+% \begin{macrocode}
+\cs_new:Npn \__kernel_str_to_other:n #1
+ {
+ \exp_after:wN \@@_to_other_loop:w
+ \tl_to_str:n {#1} ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ \s_@@_mark \s_@@_stop
+ }
+\group_begin:
+\tex_lccode:D `\* = `\ %
+\tex_lccode:D `\A = `\A %
+\tex_lowercase:D
+ {
+ \group_end:
+ \cs_new:Npn \@@_to_other_loop:w
+ #1 ~ #2 ~ #3 ~ #4 ~ #5 ~ #6 ~ #7 ~ #8 ~ #9 \s_@@_stop
+ {
+ \if_meaning:w A #8
+ \@@_to_other_end:w
+ \fi:
+ \@@_to_other_loop:w
+ #9 #1 * #2 * #3 * #4 * #5 * #6 * #7 * #8 * \s_@@_stop
+ }
+ \cs_new:Npn \@@_to_other_end:w \fi: #1 \s_@@_mark #2 * A #3 \s_@@_stop
+ { \fi: #2 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\__kernel_str_to_other_fast:n}
+% \begin{macro}[rEXP]{\__kernel_str_to_other_fast_loop:w, \@@_to_other_fast_end:w}
+% The difference with \cs{__kernel_str_to_other:n} is that the converted part is
+% left in the input stream, making these commands only
+% restricted-expandable.
+% \begin{macrocode}
+\cs_new:Npn \__kernel_str_to_other_fast:n #1
+ {
+ \exp_after:wN \@@_to_other_fast_loop:w \tl_to_str:n {#1} ~
+ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ \s_@@_stop
+ }
+\group_begin:
+\tex_lccode:D `\* = `\ %
+\tex_lccode:D `\A = `\A %
+\tex_lowercase:D
+ {
+ \group_end:
+ \cs_new:Npn \@@_to_other_fast_loop:w
+ #1 ~ #2 ~ #3 ~ #4 ~ #5 ~ #6 ~ #7 ~ #8 ~ #9 ~
+ {
+ \if_meaning:w A #9
+ \@@_to_other_fast_end:w
+ \fi:
+ #1 * #2 * #3 * #4 * #5 * #6 * #7 * #8 * #9
+ \@@_to_other_fast_loop:w *
+ }
+ \cs_new:Npn \@@_to_other_fast_end:w #1 * A #2 \s_@@_stop {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\str_item:Nn, \str_item:cn, \str_item:nn, \str_item_ignore_spaces:nn}
+% \begin{macro}[EXP]{\@@_item:nn, \@@_item:w}
+% The \cs{str_item:nn} hands its argument with spaces escaped to
+% \cs{@@_item:nn}, and makes sure to turn the result back into
+% a proper string (with category code~$10$ spaces) eventually. The
+% \cs{str_item_ignore_spaces:nn} function does not escape spaces,
+% which are thus ignored by \cs{@@_item:nn} since
+% everything else is done with undelimited arguments.
+% Evaluate the \meta{index} argument~|#2| and count characters in
+% the string, passing those two numbers to \cs{@@_item:w} for
+% further analysis. If the \meta{index} is negative, shift it by
+% the \meta{count} to know the how many character to discard, and if
+% that is still negative give an empty result. If the \meta{index}
+% is larger than the \meta{count}, give an empty result, and
+% otherwise discard $\meta{index}-1$ characters before returning the
+% following one. The shift by $-1$ is obtained by inserting an empty
+% brace group before the string in that case: that brace group also
+% covers the case where the \meta{index} is zero.
+% \begin{macrocode}
+\cs_new:Npn \str_item:Nn { \exp_args:No \str_item:nn }
+\cs_generate_variant:Nn \str_item:Nn { c }
+\cs_new:Npn \str_item:nn #1#2
+ {
+ \exp_args:Nf \tl_to_str:n
+ {
+ \exp_args:Nf \@@_item:nn
+ { \__kernel_str_to_other:n {#1} } {#2}
+ }
+ }
+\cs_new:Npn \str_item_ignore_spaces:nn #1
+ { \exp_args:No \@@_item:nn { \tl_to_str:n {#1} } }
+\cs_new:Npn \@@_item:nn #1#2
+ {
+ \exp_after:wN \@@_item:w
+ \int_value:w \int_eval:n {#2} \exp_after:wN ;
+ \int_value:w \@@_count:n {#1} ;
+ #1 \s_@@_stop
+ }
+\cs_new:Npn \@@_item:w #1; #2;
+ {
+ \int_compare:nNnTF {#1} < 0
+ {
+ \int_compare:nNnTF {#1} < {-#2}
+ { \@@_use_none_delimit_by_s_stop:w }
+ {
+ \exp_after:wN \@@_use_i_delimit_by_s_stop:nw
+ \exp:w \exp_after:wN \@@_skip_exp_end:w
+ \int_value:w \int_eval:n { #1 + #2 } ;
+ }
+ }
+ {
+ \int_compare:nNnTF {#1} > {#2}
+ { \@@_use_none_delimit_by_s_stop:w }
+ {
+ \exp_after:wN \@@_use_i_delimit_by_s_stop:nw
+ \exp:w \@@_skip_exp_end:w #1 ; { }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_skip_exp_end:w}
+% \begin{macro}[EXP]
+% {\@@_skip_loop:wNNNNNNNN, \@@_skip_end:w, \@@_skip_end:NNNNNNNN}
+% Removes |max(#1,0)| characters from the input stream, and then
+% leaves \cs{exp_end:}. This should be expanded using
+% \cs{exp:w}. We remove characters $8$ at a time until
+% there are at most $8$ to remove. Then we do a dirty trick: the
+% \cs{if_case:w} construction leaves between $0$ and $8$ times the
+% \cs{or:} control sequence, and those \cs{or:} become arguments of
+% \cs{@@_skip_end:NNNNNNNN}. If the number of characters to remove
+% is $6$, say, then there are two \cs{or:} left, and the $8$ arguments
+% of \cs{@@_skip_end:NNNNNNNN} are the two \cs{or:}, and $6$
+% characters from the input stream, exactly what we wanted to
+% remove. Then close the \cs{if_case:w} conditional with \cs{fi:}, and
+% stop the initial expansion with \cs{exp_end:} (see places where
+% \cs{@@_skip_exp_end:w} is called).
+% \begin{macrocode}
+\cs_new:Npn \@@_skip_exp_end:w #1;
+ {
+ \if_int_compare:w #1 > 8 \exp_stop_f:
+ \exp_after:wN \@@_skip_loop:wNNNNNNNN
+ \else:
+ \exp_after:wN \@@_skip_end:w
+ \int_value:w \int_eval:w
+ \fi:
+ #1 ;
+ }
+\cs_new:Npn \@@_skip_loop:wNNNNNNNN #1; #2#3#4#5#6#7#8#9
+ {
+ \exp_after:wN \@@_skip_exp_end:w
+ \int_value:w \int_eval:n { #1 - 8 } ;
+ }
+\cs_new:Npn \@@_skip_end:w #1 ;
+ {
+ \exp_after:wN \@@_skip_end:NNNNNNNN
+ \if_case:w #1 \exp_stop_f: \or: \or: \or: \or: \or: \or: \or: \or:
+ }
+\cs_new:Npn \@@_skip_end:NNNNNNNN #1#2#3#4#5#6#7#8 { \fi: \exp_end: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\str_range:Nnn, \str_range:nnn, \str_range_ignore_spaces:nnn}
+% \begin{macro}[EXP]{\@@_range:nnn}
+% \begin{macro}[EXP]{\@@_range:w, \@@_range:nnw}
+% Sanitize the string. Then evaluate the arguments. At this stage we
+% also decrement the \meta{start index}, since our goal is to know how
+% many characters should be removed. Then limit the range to be
+% non-negative and at most the length of the string (this avoids
+% needing to check for the end of the string when grabbing
+% characters), shifting negative numbers by the appropriate amount.
+% Afterwards, skip characters, then keep some more, and finally drop
+% the end of the string.
+% \begin{macrocode}
+\cs_new:Npn \str_range:Nnn { \exp_args:No \str_range:nnn }
+\cs_generate_variant:Nn \str_range:Nnn { c }
+\cs_new:Npn \str_range:nnn #1#2#3
+ {
+ \exp_args:Nf \tl_to_str:n
+ {
+ \exp_args:Nf \@@_range:nnn
+ { \__kernel_str_to_other:n {#1} } {#2} {#3}
+ }
+ }
+\cs_new:Npn \str_range_ignore_spaces:nnn #1
+ { \exp_args:No \@@_range:nnn { \tl_to_str:n {#1} } }
+\cs_new:Npn \@@_range:nnn #1#2#3
+ {
+ \exp_after:wN \@@_range:w
+ \int_value:w \@@_count:n {#1} \exp_after:wN ;
+ \int_value:w \int_eval:n { (#2) - 1 } \exp_after:wN ;
+ \int_value:w \int_eval:n {#3} ;
+ #1 \s_@@_stop
+ }
+\cs_new:Npn \@@_range:w #1; #2; #3;
+ {
+ \exp_args:Nf \@@_range:nnw
+ { \@@_range_normalize:nn {#2} {#1} }
+ { \@@_range_normalize:nn {#3} {#1} }
+ }
+\cs_new:Npn \@@_range:nnw #1#2
+ {
+ \exp_after:wN \@@_collect_delimit_by_q_stop:w
+ \int_value:w \int_eval:n { #2 - #1 } \exp_after:wN ;
+ \exp:w \@@_skip_exp_end:w #1 ;
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_range_normalize:nn}
+% This function converts an \meta{index} argument into an explicit
+% position in the string (a result of $0$ denoting \enquote{out of
+% bounds}). Expects two explicit integer arguments: the
+% \meta{index} |#1| and the string count~|#2|. If |#1| is negative,
+% replace it by $|#1| + |#2| + 1$, then limit to the range $[0,
+% |#2|]$.
+% \begin{macrocode}
+\cs_new:Npn \@@_range_normalize:nn #1#2
+ {
+ \int_eval:n
+ {
+ \if_int_compare:w #1 < \c_zero_int
+ \if_int_compare:w #1 < -#2 \exp_stop_f:
+ 0
+ \else:
+ #1 + #2 + 1
+ \fi:
+ \else:
+ \if_int_compare:w #1 < #2 \exp_stop_f:
+ #1
+ \else:
+ #2
+ \fi:
+ \fi:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_collect_delimit_by_q_stop:w}
+% \begin{macro}[EXP]
+% {
+% \@@_collect_loop:wn, \@@_collect_loop:wnNNNNNNN,
+% \@@_collect_end:wn, \@@_collect_end:nnnnnnnnw
+% }
+% Collects |max(#1,0)| characters, and removes everything else until
+% \cs{s_@@_stop}. This is somewhat similar to \cs{@@_skip_exp_end:w}, but
+% accepts integer expression arguments. This time we can only grab
+% $7$ characters at a time. At the end, we use an \cs{if_case:w}
+% trick again, so that the $8$ first arguments of
+% \cs{@@_collect_end:nnnnnnnnw} are some \cs{or:}, followed by an
+% \cs{fi:}, followed by |#1| characters from the input stream. Simply
+% leaving this in the input stream closes the conditional properly
+% and the \cs{or:} disappear.
+% \begin{macrocode}
+\cs_new:Npn \@@_collect_delimit_by_q_stop:w #1;
+ { \@@_collect_loop:wn #1 ; { } }
+\cs_new:Npn \@@_collect_loop:wn #1 ;
+ {
+ \if_int_compare:w #1 > 7 \exp_stop_f:
+ \exp_after:wN \@@_collect_loop:wnNNNNNNN
+ \else:
+ \exp_after:wN \@@_collect_end:wn
+ \fi:
+ #1 ;
+ }
+\cs_new:Npn \@@_collect_loop:wnNNNNNNN #1; #2 #3#4#5#6#7#8#9
+ {
+ \exp_after:wN \@@_collect_loop:wn
+ \int_value:w \int_eval:n { #1 - 7 } ;
+ { #2 #3#4#5#6#7#8#9 }
+ }
+\cs_new:Npn \@@_collect_end:wn #1 ;
+ {
+ \exp_after:wN \@@_collect_end:nnnnnnnnw
+ \if_case:w \if_int_compare:w #1 > \c_zero_int
+ #1 \else: 0 \fi: \exp_stop_f:
+ \or: \or: \or: \or: \or: \or: \fi:
+ }
+\cs_new:Npn \@@_collect_end:nnnnnnnnw #1#2#3#4#5#6#7#8 #9 \s_@@_stop
+ { #1#2#3#4#5#6#7#8 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Counting characters}
+%
+% \begin{macro}[EXP]
+% {\str_count_spaces:N, \str_count_spaces:c, \str_count_spaces:n}
+% \begin{macro}[EXP]{\@@_count_spaces_loop:w}
+% To speed up this function, we grab and discard $9$ space-delimited
+% arguments in each iteration of the loop. The loop stops when the
+% last argument is one of the trailing |X|\meta{number}, and that
+% \meta{number} is added to the sum of $9$ that precedes, to adjust
+% the result.
+% \begin{macrocode}
+\cs_new:Npn \str_count_spaces:N
+ { \exp_args:No \str_count_spaces:n }
+\cs_generate_variant:Nn \str_count_spaces:N { c }
+\cs_new:Npn \str_count_spaces:n #1
+ {
+ \int_eval:n
+ {
+ \exp_after:wN \@@_count_spaces_loop:w
+ \tl_to_str:n {#1} ~
+ X 7 ~ X 6 ~ X 5 ~ X 4 ~ X 3 ~ X 2 ~ X 1 ~ X 0 ~ X -1 ~
+ \s_@@_stop
+ }
+ }
+\cs_new:Npn \@@_count_spaces_loop:w #1~#2~#3~#4~#5~#6~#7~#8~#9~
+ {
+ \if_meaning:w X #9
+ \@@_use_i_delimit_by_s_stop:nw
+ \fi:
+ 9 + \@@_count_spaces_loop:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\str_count:N, \str_count:c, \str_count:n, \str_count_ignore_spaces:n}
+% \begin{macro}[EXP]{\@@_count:n}
+% \begin{macro}[EXP]{\@@_count_aux:n, \@@_count_loop:NNNNNNNNN}
+% To count characters in a string we could first escape all spaces
+% using \cs{__kernel_str_to_other:n}, then pass the result to \cs{tl_count:n}.
+% However, the escaping step would be quadratic in the number of
+% characters in the string, and we can do better. Namely, sum the
+% number of spaces (\cs{str_count_spaces:n}) and the result of
+% \cs{tl_count:n}, which ignores spaces. Since strings tend to be
+% longer than token lists, we use specialized functions to count
+% characters ignoring spaces. Namely, loop, grabbing $9$ non-space
+% characters at each step, and end as soon as we reach one of the $9$
+% trailing items. The internal function \cs{@@_count:n}, used in
+% \cs{str_item:nn} and \cs{str_range:nnn}, is similar to
+% \cs{str_count_ignore_spaces:n} but expects its argument to already
+% be a string or a string with spaces escaped.
+% \begin{macrocode}
+\cs_new:Npn \str_count:N { \exp_args:No \str_count:n }
+\cs_generate_variant:Nn \str_count:N { c }
+\cs_new:Npn \str_count:n #1
+ {
+ \@@_count_aux:n
+ {
+ \str_count_spaces:n {#1}
+ + \exp_after:wN \@@_count_loop:NNNNNNNNN \tl_to_str:n {#1}
+ }
+ }
+\cs_new:Npn \@@_count:n #1
+ {
+ \@@_count_aux:n
+ { \@@_count_loop:NNNNNNNNN #1 }
+ }
+\cs_new:Npn \str_count_ignore_spaces:n #1
+ {
+ \@@_count_aux:n
+ { \exp_after:wN \@@_count_loop:NNNNNNNNN \tl_to_str:n {#1} }
+ }
+\cs_new:Npn \@@_count_aux:n #1
+ {
+ \int_eval:n
+ {
+ #1
+ { X 8 } { X 7 } { X 6 }
+ { X 5 } { X 4 } { X 3 }
+ { X 2 } { X 1 } { X 0 }
+ \s_@@_stop
+ }
+ }
+\cs_new:Npn \@@_count_loop:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \if_meaning:w X #9
+ \exp_after:wN \@@_use_none_delimit_by_s_stop:w
+ \fi:
+ 9 + \@@_count_loop:NNNNNNNNN
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{The first character in a string}
+%
+% \begin{macro}[EXP]
+% {\str_head:N, \str_head:c, \str_head:n, \str_head_ignore_spaces:n}
+% \begin{macro}[EXP]{\@@_head:w}
+% The \texttt{_ignore_spaces} variant applies \cs{tl_to_str:n} then
+% grabs the first item, thus skipping spaces.
+% As usual, \cs{str_head:N} expands its argument and
+% hands it to \cs{str_head:n}. To circumvent the fact that \TeX{}
+% skips spaces when grabbing undelimited macro parameters,
+% \cs{@@_head:w} takes an argument delimited by a space. If |#1|
+% starts with a non-space character, \cs{@@_use_i_delimit_by_s_stop:nw}
+% leaves that in the input stream. On the other hand, if |#1| starts
+% with a space, the \cs{@@_head:w} takes an empty argument, and the
+% single (initially braced) space in the definition of \cs{@@_head:w}
+% makes its way to the output. Finally, for an empty argument, the
+% (braced) empty brace group in the definition of \cs{str_head:n}
+% gives an empty result after passing through
+% \cs{@@_use_i_delimit_by_s_stop:nw}.
+% \begin{macrocode}
+\cs_new:Npn \str_head:N { \exp_args:No \str_head:n }
+\cs_generate_variant:Nn \str_head:N { c }
+\cs_new:Npn \str_head:n #1
+ {
+ \exp_after:wN \@@_head:w
+ \tl_to_str:n {#1}
+ { { } } ~ \s_@@_stop
+ }
+\cs_new:Npn \@@_head:w #1 ~ %
+ { \@@_use_i_delimit_by_s_stop:nw #1 { ~ } }
+\cs_new:Npn \str_head_ignore_spaces:n #1
+ {
+ \exp_after:wN \@@_use_i_delimit_by_s_stop:nw
+ \tl_to_str:n {#1} { } \s_@@_stop
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\str_tail:N, \str_tail:c, \str_tail:n, \str_tail_ignore_spaces:n}
+% \begin{macro}[EXP]{\@@_tail_auxi:w, \@@_tail_auxii:w}
+% Getting the tail is a little bit more convoluted than the head of a
+% string. We hit the front of the string with \cs{reverse_if:N}
+% \cs{if_charcode:w} \cs{scan_stop:}. This removes the first
+% character, and necessarily makes the test true, since the character
+% cannot match \cs{scan_stop:}. The auxiliary function then inserts
+% the required \cs{fi:} to close the conditional, and leaves the tail
+% of the string in the input stream. The details are such that an
+% empty string has an empty tail (this requires in particular that the
+% end-marker |X| be unexpandable and not a control sequence). The
+% \texttt{_ignore_spaces} is rather simpler: after converting the
+% input to a string, \cs{@@_tail_auxii:w} removes one undelimited
+% argument and leaves everything else until an end-marker \cs{s_@@_mark}.
+% One can check that an empty (or blank) string yields an empty
+% tail.
+% \begin{macrocode}
+\cs_new:Npn \str_tail:N { \exp_args:No \str_tail:n }
+\cs_generate_variant:Nn \str_tail:N { c }
+\cs_new:Npn \str_tail:n #1
+ {
+ \exp_after:wN \@@_tail_auxi:w
+ \reverse_if:N \if_charcode:w
+ \scan_stop: \tl_to_str:n {#1} X X \s_@@_stop
+ }
+\cs_new:Npn \@@_tail_auxi:w #1 X #2 \s_@@_stop { \fi: #1 }
+\cs_new:Npn \str_tail_ignore_spaces:n #1
+ {
+ \exp_after:wN \@@_tail_auxii:w
+ \tl_to_str:n {#1} \s_@@_mark \s_@@_mark \s_@@_stop
+ }
+\cs_new:Npn \@@_tail_auxii:w #1 #2 \s_@@_mark #3 \s_@@_stop { #2 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{String manipulation}
+%
+% \begin{macro}[EXP]
+% {
+% \str_casefold:n, \str_casefold:V,
+% \str_lowercase:n, \str_lowercase:f,
+% \str_uppercase:n, \str_uppercase:f
+% }
+% \begin{macro}[EXP]{\@@_change_case:nn}
+% \begin{macro}[EXP]{\@@_change_case_aux:nn}
+% \begin{macro}[EXP]{\@@_change_case_result:n}
+% \begin{macro}[EXP]{\@@_change_case_output:nw, \@@_change_case_output:fw}
+% \begin{macro}[EXP]{\@@_change_case_end:nw}
+% \begin{macro}[EXP]{\@@_change_case_loop:nw}
+% \begin{macro}[EXP]{\@@_change_case_space:n}
+% \begin{macro}[EXP]
+% {\@@_change_case_char:nN, \@@_change_case_char_auxi:nN, \@@_change_case_char_auxii:nN}
+% \begin{macro}[EXP]{\@@_change_case_codepoint:nN}
+% \begin{macro}[EXP]{\@@_change_case_codepoint:nNN}
+% \begin{macro}[EXP]{\@@_change_case_codepoint:nNNN}
+% \begin{macro}[EXP]{\@@_change_case_codepoint:nNNNN}
+% \begin{macro}[EXP]{\@@_change_case_char:nnn, \@@_change_case_char_aux:nnn}
+% \begin{macro}[EXP]{\@@_change_case_char:nnnnn}
+% Case changing for programmatic reasons is done by first detokenizing
+% input then doing a simple loop that only has to worry about spaces
+% and everything else. The output is detokenized to allow data sharing
+% with text-based case changing. Similarly, for $8$-bit engines the
+% multi-byte information is shared.
+% \begin{macrocode}
+\cs_new:Npn \str_casefold:n #1 { \@@_change_case:nn {#1} { casefold } }
+\cs_new:Npn \str_lowercase:n #1 { \@@_change_case:nn {#1} { lowercase } }
+\cs_new:Npn \str_uppercase:n #1 { \@@_change_case:nn {#1} { uppercase } }
+\cs_generate_variant:Nn \str_casefold:n { V }
+\cs_generate_variant:Nn \str_lowercase:n { f }
+\cs_generate_variant:Nn \str_uppercase:n { f }
+\cs_new:Npn \@@_change_case:nn #1
+ {
+ \exp_after:wN \@@_change_case_aux:nn \exp_after:wN
+ { \tl_to_str:n {#1} }
+ }
+\cs_new:Npn \@@_change_case_aux:nn #1#2
+ {
+ \@@_change_case_loop:nw {#2} #1 \q_@@_recursion_tail \q_@@_recursion_stop
+ \@@_change_case_result:n { }
+ }
+\cs_new:Npn \@@_change_case_output:nw #1#2 \@@_change_case_result:n #3
+ { #2 \@@_change_case_result:n { #3 #1 } }
+\cs_generate_variant:Nn \@@_change_case_output:nw { f }
+\cs_new:Npn \@@_change_case_end:wn #1 \@@_change_case_result:n #2
+ { \tl_to_str:n {#2} }
+\cs_new:Npn \@@_change_case_loop:nw #1#2 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_space:nTF {#2}
+ { \@@_change_case_space:n }
+ { \@@_change_case_char:nN }
+ {#1} #2 \q_@@_recursion_stop
+ }
+\exp_last_unbraced:NNNNo
+ \cs_new:Npn \@@_change_case_space:n #1 \c_space_tl
+ {
+ \@@_change_case_output:nw { ~ }
+ \@@_change_case_loop:nw {#1}
+ }
+\cs_new:Npn \@@_change_case_char:nN #1#2
+ {
+ \@@_if_recursion_tail_stop_do:Nn #2
+ { \@@_change_case_end:wn }
+ \@@_change_case_codepoint:nN {#1} #2
+ }
+\if_int_compare:w 0
+ \cs_if_exist:NT \tex_XeTeXversion:D { 1 }
+ \cs_if_exist:NT \tex_luatexversion:D { 1 }
+ > 0 \exp_stop_f:
+ \cs_new:Npn \@@_change_case_codepoint:nN #1#2
+ { \@@_change_case_char:fnn { \int_eval:n {`#2} } {#1} {#2} }
+\else:
+ \cs_new:Npe \@@_change_case_codepoint:nN #1#2
+ {
+ \exp_not:N \int_compare:nNnTF {`#2} > { "80 }
+ {
+ \cs_if_exist:NTF \tex_pdftexversion:D
+ { \exp_not:N \@@_change_case_char_auxi:nN }
+ {
+ \exp_not:N \int_compare:nNnTF {`#2} > { "FF }
+ { \exp_not:N \@@_change_case_char_auxii:nN }
+ { \exp_not:N \@@_change_case_char_auxi:nN }
+ }
+ }
+ { \exp_not:N \@@_change_case_char_auxii:nN }
+ {#1} #2
+ }
+ \cs_new:Npn \@@_change_case_char_auxi:nN #1#2
+ {
+ \int_compare:nNnTF {`#2} < { "E0 }
+ { \@@_change_case_codepoint:nNN }
+ {
+ \int_compare:nNnTF {`#2} < { "F0 }
+ { \@@_change_case_codepoint:nNNN }
+ { \@@_change_case_codepoint:nNNNNN }
+ }
+ {#1} #2
+ }
+ \cs_new:Npn \@@_change_case_char_auxii:nN #1#2
+ { \@@_change_case_char:fnn { \int_eval:n {`#2} } {#1} {#2} }
+ \cs_new:Npn \@@_change_case_codepoint:nNN #1#2#3
+ {
+ \@@_change_case_char:fnn
+ { \int_eval:n { (`#2 - "C0) * "40 + `#3 - "80 } }
+ {#1} {#2#3}
+ }
+ \cs_new:Npn \@@_change_case_codepoint:nNNN #1#2#3#4
+ {
+ \@@_change_case_char:fnn
+ {
+ \int_eval:n
+ { (`#2 - "E0) * "1000 + (`#3 - "80) * "40 + `#4 - "80 }
+ }
+ {#1} {#2#3#4}
+ }
+ \cs_new:Npn \@@_change_case_codepoint:nNNNN #1#2#3#4#5
+ {
+ \@@_change_case_char:fnn
+ {
+ \int_eval:n
+ {
+ (`#2 - "F0) * "40000
+ + (`#3 - "80) * "1000
+ + (`#4 - "80) * "40
+ + `#5 - "80
+ }
+ }
+ {#1} {#2#3#4#5}
+ }
+\fi:
+\cs_new:Npn \@@_change_case_char:nnn #1#2#3
+ {
+ \@@_change_case_output:fw
+ {
+ \exp_args:Ne \@@_change_case_char_aux:nnn
+ { \__kernel_codepoint_case:nn {#2} {#1} } {#1} {#3}
+ }
+ \@@_change_case_loop:nw {#2}
+ }
+\cs_generate_variant:Nn \@@_change_case_char:nnn { f }
+\cs_new:Npn \@@_change_case_char_aux:nnn #1#2#3
+ {
+ \use:e { \@@_change_case_char:nnnnn #1 {#2} {#3} }
+ }
+\cs_new:Npn \@@_change_case_char:nnnnn #1#2#3#4#5
+ {
+ \int_compare:nNnTF {#1} = {#4}
+ { \tl_to_str:n {#5} }
+ {
+ \codepoint_str_generate:n {#1}
+ \tl_if_blank:nF {#2}
+ {
+ \codepoint_str_generate:n {#2}
+ \tl_if_blank:nF {#3}
+ { \codepoint_str_generate:n {#3} }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\str_mdfive_hash:n, \str_mdfive_hash:e}
+% \begin{macrocode}
+\cs_new:Npn \str_mdfive_hash:n #1 { \tex_mdfivesum:D { \tl_to_str:n {#1} } }
+\cs_new:Npn \str_mdfive_hash:e #1 { \tex_mdfivesum:D {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}
+% {
+% \c_ampersand_str,
+% \c_atsign_str,
+% \c_backslash_str,
+% \c_left_brace_str,
+% \c_right_brace_str,
+% \c_circumflex_str,
+% \c_colon_str,
+% \c_dollar_str,
+% \c_hash_str,
+% \c_percent_str,
+% \c_tilde_str,
+% \c_underscore_str,
+% \c_zero_str
+% }
+% For all of those strings, use \cs{cs_to_str:N} to get characters with
+% the correct category code without worries
+% \begin{macrocode}
+\str_const:Ne \c_ampersand_str { \cs_to_str:N \& }
+\str_const:Ne \c_atsign_str { \cs_to_str:N \@ }
+\str_const:Ne \c_backslash_str { \cs_to_str:N \\ }
+\str_const:Ne \c_left_brace_str { \cs_to_str:N \{ }
+\str_const:Ne \c_right_brace_str { \cs_to_str:N \} }
+\str_const:Ne \c_circumflex_str { \cs_to_str:N \^ }
+\str_const:Ne \c_colon_str { \cs_to_str:N \: }
+\str_const:Ne \c_dollar_str { \cs_to_str:N \$ }
+\str_const:Ne \c_hash_str { \cs_to_str:N \# }
+\str_const:Ne \c_percent_str { \cs_to_str:N \% }
+\str_const:Ne \c_tilde_str { \cs_to_str:N \~ }
+\str_const:Ne \c_underscore_str { \cs_to_str:N \_ }
+\str_const:Ne \c_zero_str { 0 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_empty_str}
+% An empty string is simply an empty token list.
+% \begin{macrocode}
+\cs_new_eq:NN \c_empty_str \c_empty_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_tmpa_str, \l_tmpb_str, \g_tmpa_str, \g_tmpb_str}
+% Scratch strings.
+% \begin{macrocode}
+\str_new:N \l_tmpa_str
+\str_new:N \l_tmpb_str
+\str_new:N \g_tmpa_str
+\str_new:N \g_tmpb_str
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Viewing strings}
+%
+% \begin{macro}{\str_show:n, \str_show:N, \str_show:c}
+% \begin{macro}{\str_log:n, \str_log:N, \str_log:c}
+% Displays a string on the terminal.
+% \begin{macrocode}
+\cs_new_eq:NN \str_show:n \tl_show:n
+\cs_new_protected:Npn \str_show:N #1
+ {
+ \__kernel_chk_tl_type:NnnT #1 { str } { \tl_to_str:N #1 }
+ { \tl_show:N #1 }
+ }
+\cs_generate_variant:Nn \str_show:N { c }
+\cs_new_eq:NN \str_log:n \tl_log:n
+\cs_new_protected:Npn \str_log:N #1
+ {
+ \__kernel_chk_tl_type:NnnT #1 { str } { \tl_to_str:N #1 }
+ { \tl_log:N #1 }
+ }
+\cs_generate_variant:Nn \str_log:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3styleguide.pdf b/macros/latex-dev/required/l3kernel/l3styleguide.pdf
new file mode 100644
index 0000000000..89d4efff14
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3styleguide.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3styleguide.tex b/macros/latex-dev/required/l3kernel/l3styleguide.tex
new file mode 100644
index 0000000000..da169cd8b1
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3styleguide.tex
@@ -0,0 +1,303 @@
+\iffalse meta-comment
+
+File: l3styleguide.tex
+
+Copyright (C) 2011,2012,2014-2024 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this
+license or (at your option) any later version. The latest version
+of this license is in the file
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3kernel bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+The released version of this bundle is available from CTAN.
+
+\fi
+
+\documentclass{l3doc}
+
+
+\title{%
+ The \LaTeX3 kernel: style guide for code authors%
+}
+\author{%
+ The \LaTeX{} Project\thanks
+ {%
+ E-mail:
+ \href{mailto:latex-team@latex-project.org}%
+ {latex-team@latex-project.org}%
+ }%
+}
+\date{Released 2024-04-11}
+
+\begin{document}
+
+\maketitle
+
+\tableofcontents
+
+\section{Introduction}
+
+This document is intended as a style guide for authors of code and
+documentation for the \LaTeX3 kernel. It covers both aspects of coding
+style and the formatting of the sources. The aim of providing these
+guidelines is help ensure consistency of the code and sources from
+different authors. Experience suggests that in the long-term this helps
+with maintenance. There will of course be places where there are
+exceptions to these guidelines: common sense should always be
+applied!
+
+\section{Documentation style}
+
+\LaTeX3 source and documentation should be written using the document
+class \cls{l3doc} in \file{dtx} format. This class provides a number
+of logical mark up elements, which should be used where possible.
+In the main, this is standard \LaTeX{} practice, but there are a
+few points to highlight:
+\begin{itemize}
+ \item
+ Where possible, use \cs{cs} to mark up control sequences
+ rather than using a verbatim environment.
+ \item
+ Arguments which are given in braces should be marked using
+ \cs{Arg} when code-level functions are discussed, but using
+ \cs{marg} for document functions.
+ \item
+ The names \TeX{}, \LaTeX{}, \emph{etc}.\ use the normal logical mark
+ up followed by an empty group (|{}|), with the exception of |\LaTeX3|,
+ where the number should follow directly.
+ \item
+ Where in line verbatim text is used, it should be marked up
+ using the \verb=|...|= construct (\emph{i.e.}~vertical bars delimit
+ the verbatim text).
+ \item In line quotes should be marked up using the \cs{enquote}
+ function.
+ \item
+ Where numbers in the source have a mathematical meaning,
+ they should be included in math mode. Such in-line math mode
+ material should be marked up using |$...$| and \emph{not}
+ |\(...\)|.
+\end{itemize}
+
+Line length in the source files should be under $80$
+characters where possible, as this helps keep everything on the screen
+when editing files. In the \file{dtx} format, documentation lines start
+with a \texttt{\%}, which is usually followed by a space to leave a
+\enquote{comment margin} at the start of each line.
+
+As with code indenting (see later), nested environments and arguments
+should be indented by (at least) two spaces to make the nature of the nesting
+clear. Thus for example a typical arrangement for the \env{function}
+environment might be
+\begin{verbatim*}
+\begin{function}{\seq_gclear:N, \seq_gclear:c}
+ \begin{syntax}
+ \cs{seq_gclear:N} \meta{sequence}
+ \end{syntax}
+ Clears all entries from the \meta{sequence} globally.
+\end{function}
+\end{verbatim*}
+The \enquote{outer} \verb*|% \begin{function}| should have the customary
+space after the |%| character at the start of the line.
+
+In general, a single \env{function} or \env{macro} environment should be
+used for a group of closely-related functions, for example argument
+specification variants. In such cases, a comma-separated list should be
+used, as shown in the preceding example.
+
+\section{Format of the code itself}
+
+The requirement for fewer than $80$ characters per line applies to the code
+itself as well as the surrounding documentation. A number of the general
+style principles for \LaTeX3 code apply: these are described in the following
+paragraph and an example is then given.
+
+With the exception of simple runs of parameter (|{#1}|, |#1#2|,
+\emph{etc.}), everything should be divided up using spaces to make the code
+more readable. In general, these will be single spaces, but in some
+places it makes more sense to align parts of the code to emphasise
+similarity. (Tabs should not be used for introducing white space.)
+
+Each conceptually-separate step in a function should be on a separate
+line, to make the meaning clearer. Hence the \texttt{false} branch
+in the example uses two lines for the two auxiliary function uses.
+
+Within the definition, a two-space indent should be used to show each
+\enquote{level} of code. Thus in the example \cs{tl_if_empty:nTF} is
+indented by two spaces, but the two branches are indented by four
+spaces. Within the \texttt{false} branch, the need for multiple lines
+means that an additional two-space indent should be used to show that
+these lines are all part of the brace group.
+
+The result of these lay-out conventions is code which in general
+looks like the example:
+\begin{verbatim*}
+\cs_new:Npn \module_foo:nn #1#2
+ {
+ \tl_if_empty:nTF {#1}
+ { \module_foo_aux:n { X #2 } }
+ {
+ \module_foo_aux:nn {#1} {#2}
+ \module_foo_aux:n { #1 #2 }
+ }
+ }
+\end{verbatim*}
+
+\section{Code conventions}
+
+All code-level functions should be \enquote{long} if they accept any
+arguments, even if it seems \enquote{very unlikely} that a \cs{par} token
+will be passed. Thus \cs{cs_new_nopar:Npn} and so forth should only be used
+to create interfaces at the document level (where trapping \cs{par} tokens
+may be appropriate) or where comparison to other code known not to be
+\enquote{long} is required (\emph{e.g.}~when working with mixed
+\LaTeXe{}/\pkg{expl3} situations).
+
+The expandability of each function should be well-defined. Functions which
+cannot be fully expanded must be \texttt{protected}. This means that expandable
+functions must themselves only contain expandable material. Functions which
+use any non-expandable material must be defined using \cs{cs_new_protected:Npn}
+or similar.
+
+When using \cs{cs_generate_variant:Nn}, group related variants together
+to make the pattern clearer. A common example is variants of a function
+which has an \texttt{N}-type first argument:
+\begin{verbatim}
+ \cs_generate_variant:Nn \foo:Nn { NV , No }
+ \cs_generate_variant:Nn \foo:Nn { c , cV , co }
+\end{verbatim}
+
+There may be cases where omitting braces from \texttt{o}-type arguments
+is desirable for performance reasons. This should only be done if the
+argument is a single token, thus for example
+\begin{verbatim}
+ \tl_set:No \l_some_tl \l_some_other_tl
+\end{verbatim}
+remains clear and can be used where appropriate.
+
+\section{Private and internal functions}
+
+Private functions (those starting \cs{__}) should not be used between modules.
+The only exception is where a \enquote{family} of modules share some
+\enquote{internal} methods: this happens most obviously in the kernel itself.
+Any internal functions or variables \emph{must} be documented in the same way
+as public ones.
+
+The \pkg{DocStrip} method should be used for internal functions in a module.
+This requires a line
+\begin{quote}
+ \ttfamily
+ \%<@@=\meta{module}>
+\end{quote}
+at the start of the source (\texttt{.dtx}) file, with internal functions
+then written in the form
+\begin{verbatim}
+ \cs_new_protected:Npn \@@_function:nn #1#2
+ ...
+\end{verbatim}
+
+\subsection{Access from other modules}
+
+There may be cases where it is useful to use an internal function from
+a third-party module (this includes cases where you are the author of both
+but they are not part of the same \enquote{family}). In these cases, you should
+\emph{copy} the definition of the internal function to your code: this avoids
+relying on non-documented interfaces. At the same time, it is strongly
+encouraged that you discuss your requirements with the author of the
+code you need to access. The best long-term solution to these cases is for
+new documented interfaces to be added to the parent module.
+
+\subsection{Access to primitives}
+
+As \pkg{expl3} is still a developing system, there are places where direct
+access to engine primitives is required. These are all marked as
+\enquote{do not use} in the code and so require special handling. Where a
+programmer is sure that they need to use a primitive (for example where the
+team have not yet covered access to an area) then a local copy of the
+primitive should be made, for example
+\begin{verbatim}
+ \cs_new_eq:NN \__module_message:w \tex_message:D
+ % ...
+ \cs_new_protected:Npn \__module_fancy_msg:n #1
+ { \__module_message:w { *** #1 *** } }
+\end{verbatim}
+This approach makes it possible for the team and others to find such
+usage (by searching for the \texttt{:D} argument type) but avoids
+multiple uses in general code.
+
+At the same time, the team ask that these use cases are raised on the
+\texttt{LaTeX-L} mailing list. The team are keen to collect use cases for
+areas that have not yet been addressed and to provide new code where the
+required interfaces become clear.
+
+Programmers using primitives should be ready to make updates to their
+code as the team develop additional interfaces.
+
+\section{Auxiliary functions}
+
+In general, the team encourages the use of descriptive names in \LaTeX3 code.
+Thus many helper functions would have names which describe briefly what they do,
+rather than simply indicating that they are auxiliary to some higher-level
+function. However, there are places where one or more \texttt{aux} functions
+are required. Where possible, these should be differentiated by signature
+\begin{verbatim}
+ \cs_new_protected:Npn \@@_function:nn #1#2
+ {
+ ...
+ }
+ \cs_new_protected:Npn \@@_function_aux:nn #1#2
+ {
+ ...
+ }
+ \cs_new_protected:Npn \@@_function_aux:w #1#2 \q_stop
+ {
+ ...
+ }
+\end{verbatim}
+Where more than one auxiliary shares the same signature, the recommended naming
+scheme is \texttt{auxi}, \texttt{auxii} and so on.
+\begin{verbatim}
+ \cs_new_protected:Npn \@@_function_auxi:nn #1#2
+ {
+ ...
+ }
+ \cs_new_protected:Npn \@@_function_auxii:nn #1#2
+ {
+ ...
+ }
+\end{verbatim}
+The use of \texttt{aux_i}, \texttt{aux_ii}, \emph{etc.}\ is discouraged as this
+conflicts with the convention used by \cs{use_i:nn} and related functions.
+
+\section{Functions with `weird' arguments}
+
+When defining commands that do not follow the usual convention of accepting
+arguments as single-tokens or braced-text, the \verb|w| argument specifier
+is used to denote that the function signature cannot fully describe the syntax.
+Two examples from the \LaTeX3 kernel are:
+\begin{quote}
+\verb|\use_none_delimit_by_q_stop:w| $\langle$\,\emph{text}\,$\rangle$ \verb|\q_stop|\\
+\verb|\use_i_delimit_by_q_stop:nw| \char`\{ $\langle$\,\emph{arg}\,$\rangle$\char`}\,$\langle$\,\emph{text}\,$\rangle$ \verb|\q_stop|
+\end{quote}
+More complex definitions are possible if commands are to parse tokens,
+such as the internal kernel command
+\begin{verbatim}
+ \cs_new_protected:Npn \__clist_get:wN #1 , #2 \q_stop #3
+ { \tl_set:Nn #3 {#1} }
+\end{verbatim}
+When the \verb|w| specifier is being used, it is encouraged not to try
+and complicate the rest of the signature too much---for example, it
+would be considered poor style to have a function with a signature like
+\verb|\foo_bar:wnw| unless there were very clear reasons of code clarity.
+A signature such as \verb|:ww| would certainly be discouraged.
+
+Examining the examples above, it can be seen that there are scenarios in
+which it may make logical sense for having a signature such as \verb|:wN| or
+\verb|:nw|, but when in doubt the recommended approach is to simply use
+\verb|:w| as a catch-all.
+
+\end{document}
diff --git a/macros/latex-dev/required/l3kernel/l3syntax-changes.pdf b/macros/latex-dev/required/l3kernel/l3syntax-changes.pdf
new file mode 100644
index 0000000000..7823600916
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3syntax-changes.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3syntax-changes.tex b/macros/latex-dev/required/l3kernel/l3syntax-changes.tex
new file mode 100644
index 0000000000..85f83bf0e3
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3syntax-changes.tex
@@ -0,0 +1,190 @@
+\iffalse meta-comment
+
+File: l3syntax-changes.tex
+
+Copyright (C) 2011,2012,2017-2024 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this
+license or (at your option) any later version. The latest version
+of this license is in the file
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3kernel bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+The released version of this bundle is available from CTAN.
+
+\fi
+
+\documentclass{l3doc}
+
+
+\title{%
+ Syntax changes in \LaTeX3 functions%
+}
+\author{%
+ The \LaTeX{} Project\thanks
+ {%
+ E-mail:
+ \href{mailto:latex-team@latex-project.org}%
+ {latex-team@latex-project.org}%
+ }%
+}
+\date{Released 2024-04-11}
+
+\newcommand{\TF}{\textit{(TF)}}
+
+\begin{document}
+
+\maketitle
+
+This file describes functions that were expected to be completely
+stable, but whose syntax has changed in ways that may potentially
+require code relying on them to be changed. This file does not include
+bug-fixes, nor backward-compatible extensions of the syntax,
+nor functions that were completely
+deprecated: the latter are listed in \texttt{l3obsolete.txt}. Only
+changes after August 2011 are listed, with an approximate date.
+
+\section{August 2011}
+
+\begin{itemize}
+ \item \cs{tl_if_single:n\TF} recognized any non-zero number of
+ explicit spaces as \meta{true}, and did not ignore trailing spaces.
+ Now it is \meta{true} for
+ \[
+ \meta{optional spaces}
+ \meta{normal token or brace group}
+ \meta{optional spaces}.
+ \]
+ \item \cs{tl_reverse:n} stripped outer braces and lost unprotected spaces.
+ Now it keeps spaces, leaves unbraced single tokens unbraced, and
+ braced groups braced.
+ \item \cs{tl_trim_spaces:n} only removed one leading and trailing space.
+ Now removes recursively. Also, on the left it used to strip implicit
+ and explicit spaces with any character code. Now it strips only explicit
+ space characters $(32,10)$.
+\end{itemize}
+
+\section{September 2011}
+
+\begin{itemize}
+\item clist functions which receive an \texttt{n}-type comma list argument
+ now trim spaces from each item in the argument.
+\end{itemize}
+
+\section{May 2012}
+
+\begin{itemize}
+ \item The \pkg{l3fp} code has been completely rewritten with a new
+ expandable interface.
+ \item Getting/popping from a comma list or sequence or property list
+ that is empty (or missing the given key) now gives the quark
+ \cs{q_no_value}.
+\end{itemize}
+
+\section{June 2012}
+
+\begin{itemize}
+ \item Access to list functions now indexes from~$1$, not from~$0$.
+ This applies to multiple choices in the \pkg{l3keys} module and
+ the \cs{clist_item:Nn}, \cs{seq_item:Nn} and \cs{tl_item:Nn}
+ functions.
+ \item \cs{tl_trim_spaces:n} now requires a variable number of
+ expansions to fully expand, rather than exactly two. Of course,
+ \texttt{x}-type or \texttt{e}-type expansion still correctly evaluates this function.
+\end{itemize}
+
+\section{July 2012}
+
+\begin{itemize}
+ \item The \cs{tl_if_head_eq_meaning:nN}, \cs{tl_if_head_eq_catcode:nN}
+ and \cs{tl_if_head_eq_charcode:nN} conditionals now never match when
+ their first argument is empty.
+\end{itemize}
+
+\section{August 2012}
+
+\begin{itemize}
+ \item \cs{lua_now:x} is now a standard \texttt{x}-type expansion of
+ \cs{lua_now:n}, which does no expansion. Engine-level expansion is moved
+ to \cs{lua_now:e}, reflecting the fact that this is non-standard in the
+ same way as for example \cs{str_if_eq_x:nn(TF)}.
+\end{itemize}
+
+\section{December 2013}
+
+\begin{itemize}
+ \item In \pkg{l3fp} expressions, the badly named functions |round0|,
+ |round-|, |round+| are now named |trunc|, |floor|, |ceil|.
+\end{itemize}
+
+\section{May 2014}
+
+\begin{itemize}
+ \item Now \cs{int_step_function:nnnN} evaluates its first three
+ arguments (start, step, stop) up front, rather than evaluating them
+ at each step in the loop. The same holds for the related mappings
+ \cs{int_step_inline:nnnn}, \cs{int_step_variable:nnnNn}, and their
+ analogues for \texttt{dim} and \texttt{fp} datatypes.
+\end{itemize}
+
+\section{July 2014}
+
+\begin{itemize}
+ \item In \pkg{l3fp} expressions, juxtaposition is interpreted as
+ multiplication. Now the precedence of juxtaposition is set to be
+ the same as if there was an explicit multiplication
+ sign~\texttt{*}. Previously, juxtaposition would bound more tightly
+ than any other operation.
+\end{itemize}
+
+\section{August 2015}
+
+\begin{itemize}
+ \item The \cs{hbox:n} and related \pkg{l3box} commands now take an
+ \texttt{n}-type argument and provide it braced to the underlying
+ \TeX{} primitive. The functions \cs{hbox:w} and \cs{hbox_end:} in
+ contrast do not read the contents of the box as a macro argument.
+\end{itemize}
+
+\section{2016}
+
+No change.
+
+\section{July 2017}
+
+\begin{itemize}
+ \item Boolean expressions are now evaluated eagerly, namely both
+ operands of logical \texttt{and} (|&&|) and \texttt{or} (\verb"||")
+ are evaluated even when the result of the logical operation is fixed
+ after determining the first operand. For lazy evaluation,
+ \cs{bool_lazy_and_p:nn} and related functions are provided.
+\end{itemize}
+
+\section{November 2017}
+
+\begin{itemize}
+ \item Spaces are now preserved inside keys in \pkg{l3keys}, and
+ trimmed at both ends.
+ \item \cs{cs_generate_variant:Nn} is now stricter: it only allows to
+ change \texttt{N}-type arguments to \texttt{c}, and \texttt{n} to
+ \texttt{o}, \texttt{V}, \texttt{v}, \texttt{f}, \texttt{x}. On the
+ one hand the latter argument types typically give rise to more than
+ one token, not suitable for use by an \texttt{N}-type base function.
+ On the other hand, \texttt{c} variants of \texttt{n} arguments
+ should often be \texttt{v} variants (when the argument is eventually
+ evaluated) or mistakes where the programmer thought the base
+ function was \texttt{N}-type.
+\end{itemize}
+
+\section{February 2020}
+
+\begin{itemize}
+ \item \cs{keyval_parse:NNn} now works by expansion, returning
+ the parsed list inside \cs{exp_not:n}.
+\end{itemize}
+
+\end{document}
diff --git a/macros/latex-dev/required/l3kernel/l3sys.dtx b/macros/latex-dev/required/l3kernel/l3sys.dtx
new file mode 100644
index 0000000000..085b5f2c97
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3sys.dtx
@@ -0,0 +1,1383 @@
+% \iffalse meta-comment
+%
+%% File: l3sys.dtx
+%
+% Copyright (C) 2015-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3sys} module\\ System/runtime functions^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{The name of the job}
+%
+% \begin{variable}[added = 2015-09-19, updated = 2019-10-27]{\c_sys_jobname_str}
+% Constant that gets the \enquote{job name} assigned when \TeX{} starts.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{jobname}. For technical
+% reasons, the string here is not of the same internal form as other,
+% but may be manipulated using normal string functions.
+% \end{texnote}
+% \end{variable}
+%
+% \section{Date and time}
+%
+% \begin{variable}[added = 2015-09-22]
+% {
+% \c_sys_minute_int,
+% \c_sys_hour_int,
+% \c_sys_day_int,
+% \c_sys_month_int,
+% \c_sys_year_int,
+% }
+% The date and time at which the current job was started: these are
+% all reported as integers.
+% \begin{texnote}
+% Whilst the underlying \TeX{} primitives \tn{time}, \tn{day}, \tn{month},
+% and~\tn{year} can be altered by the user, this
+% interface to the time and date is intended to be the \enquote{real}
+% values.
+% \end{texnote}
+% \end{variable}
+%
+% \begin{variable}[added = 2023-08-27]{\c_sys_timestamp_str}
+% The timestamp for the current job: the format is as described for
+% \cs{file_timestamp:n}.
+% \end{variable}
+%
+% \section{Engine}
+%
+% \begin{function}[added = 2015-09-07, EXP, pTF]
+% {
+% \sys_if_engine_luatex:,
+% \sys_if_engine_pdftex:,
+% \sys_if_engine_ptex: ,
+% \sys_if_engine_uptex: ,
+% \sys_if_engine_xetex:
+% }
+% \begin{syntax}
+% \cs{sys_if_engine_pdftex_p:}
+% \cs{sys_if_engine_pdftex:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Conditionals which allow engine-specific code to be used. The names
+% follow naturally from those of the engine binaries: note that the
+% |(u)ptex| tests are for \epTeX{} and \eupTeX{} as \pkg{expl3} requires
+% the \eTeX{} extensions. Each conditional is true for
+% \emph{exactly one} supported engine. In particular,
+% |\sys_if_engine_ptex_p:| is true for \epTeX{} but false for \eupTeX{}.
+% \end{function}
+%
+% \begin{variable}[added = 2015-09-19]{\c_sys_engine_str}
+% The current engine given as a lower case string: one of
+% |luatex|, |pdftex|, |ptex|, |uptex| or |xetex|.
+% \end{variable}
+%
+% \begin{variable}[added = 2020-08-20]{\c_sys_engine_exec_str}
+% The name of the standard executable for the current \TeX{} engine given
+% as a lower case string: one of |luatex|,
+% |luahbtex|, |pdftex|, |eptex|, |euptex| or |xetex|.
+% \end{variable}
+%
+% \begin{variable}[added = 2020-08-20]{\c_sys_engine_format_str}
+% The name of the preloaded format for the current \TeX{} run given
+% as a lower case string: one of
+% |lualatex| (or |dvilualatex|),
+% |pdflatex| (or |latex|), |platex|, |uplatex| or |xelatex| for \LaTeX{},
+% similar names for plain \TeX{} (except \pdfTeX{} in DVI mode yields
+% |etex|), and |cont-en| for Con\TeX{}t (i.e.~the
+% \tn{fmtname}).
+% \end{variable}
+%
+% \begin{variable}[added = 2018-05-02]{\c_sys_engine_version_str}
+% The version string of the current engine, in the same form as
+% given in the banner issued when running a job. For \pdfTeX{}
+% and \LuaTeX{} this is of the form
+% \begin{quote}
+% \meta{major}.\meta{minor}.\meta{revision}
+% \end{quote}
+% For \XeTeX{}, the form is
+% \begin{quote}
+% \meta{major}.\meta{minor}
+% \end{quote}
+% For \pTeX{} and \upTeX{}, only releases since \TeX{} Live 2018
+% make the data available, and the form is more complex, as it comprises
+% the \pTeX{} version, the \upTeX{} version and the e-\pTeX{} version.
+% \begin{quote}
+% p\meta{major}.\meta{minor}.\meta{revision}-u\meta{major}.\meta{minor}^^A
+% -\meta{epTeX}
+% \end{quote}
+% where the |u| part is only present for \upTeX{}.
+% \end{variable}
+%
+% \begin{function}[added = 2021-05-12, EXP]{\sys_timer:}
+% \begin{syntax}
+% \cs{sys_timer:}
+% \end{syntax}
+% Expands to the current value of the engine's timer clock, a
+% non-negative integer. This function is only defined for engines with
+% timer support. This command measures not just CPU time but
+% real time (including time waiting for user input). The unit are
+% scaled seconds ($2^{-16}$ seconds).
+% \end{function}
+%
+% \begin{function}[added = 2021-05-12, EXP, pTF]{\sys_if_timer_exist:}
+% \begin{syntax}
+% \cs{sys_if_timer_exist_p:}
+% \cs{sys_if_timer_exist:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether current engine has timer support.
+% \end{function}
+%
+% \section{Output format}
+%
+% \begin{function}[added = 2015-09-19, EXP, pTF]
+% {
+% \sys_if_output_dvi:,
+% \sys_if_output_pdf:
+% }
+% \begin{syntax}
+% \cs{sys_if_output_dvi_p:}
+% \cs{sys_if_output_dvi:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Conditionals which give the current output mode the \TeX{} run is
+% operating in. This is always one of two outcomes, DVI mode or
+% PDF mode. The two sets of conditionals are thus complementary and
+% are both provided to allow the programmer to emphasise the most
+% appropriate case.
+% \end{function}
+%
+% \begin{variable}[added = 2015-09-19]{\c_sys_output_str}
+% The current output mode given as a lower case string: one of
+% |dvi| or |pdf|.
+% \end{variable}
+%
+% \section{Platform}
+%
+% \begin{function}[added = 2018-07-27, EXP, pTF]
+% {
+% \sys_if_platform_unix:,
+% \sys_if_platform_windows:
+% }
+% \begin{syntax}
+% \cs{sys_if_platform_unix_p:}
+% \cs{sys_if_platform_unix:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Conditionals which allow platform-specific code to be used. The names
+% follow the \Lua{} |os.type()| function, \emph{i.e.}~all Unix-like systems
+% are |unix| (including Linux and MacOS).
+% \end{function}
+%
+% \begin{variable}[added = 2018-07-27]{\c_sys_platform_str}
+% The current platform given as a lower case string: one of
+% |unix|, |windows| or |unknown|.
+% \end{variable}
+%
+% \section{Random numbers}
+%
+% \begin{function}[added = 2017-05-27, EXP]{\sys_rand_seed:}
+% \begin{syntax}
+% \cs{sys_rand_seed:}
+% \end{syntax}
+% Expands to the current value of the engine's random seed, a
+% non-negative integer. In engines without random number support this
+% expands to $0$.
+% \end{function}
+%
+% \begin{function}[added = 2017-05-27]{\sys_gset_rand_seed:n}
+% \begin{syntax}
+% \cs{sys_gset_rand_seed:n} \Arg{int expr}
+% \end{syntax}
+% Globally sets the seed for the engine's pseudo-random number
+% generator to the \meta{integer expression}. This random seed
+% affects all \cs[no-index]{\ldots{}_rand} functions (such as
+% \cs{int_rand:nn} or \cs{clist_rand_item:n}) as well as other
+% packages relying on the engine's random number generator. In
+% engines without random number support this produces an error.
+% \begin{texnote}
+% While a $32$-bit (signed) integer can be given as a seed, only the
+% absolute value is used and any number beyond $2^{28}$ is divided
+% by an appropriate power of~$2$. We recommend using an integer in
+% $[0,2^{28}-1]$.
+% \end{texnote}
+% \end{function}
+%
+% \section{Access to the shell}
+%
+% \begin{function}[noTF, added = 2019-09-20]
+% {\sys_get_shell:nnN}
+% \begin{syntax}
+% \cs{sys_get_shell:nnN} \Arg{shell~command} \Arg{setup} \meta{tl~var}
+% \cs{sys_get_shell:nnNTF} \Arg{shell~command} \Arg{setup} \meta{tl~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Defines \meta{tl~var} to the text returned by the \meta{shell command}.
+% The \meta{shell command} is converted to a string using
+% \cs{tl_to_str:n}. Category codes may need to be set appropriately
+% via the \meta{setup} argument, which is run just before running the
+% \meta{shell command} (in a group).
+% If shell escape is disabled, the \meta{tl~var} will be set to
+% \cs{q_no_value} in the non-branching version.
+% Note that quote characters (|"|) \emph{cannot} be used inside the
+% \meta{shell command}. The \cs{sys_get_shell:nnNTF} conditional
+% inserts the \meta{true code} if the shell is available and no quote is
+% detected, and the \meta{false code} otherwise.
+%
+% \emph{Note}: It is not possible to tell from \TeX{} if a command is allowed
+% in restricted shell escape. If restricted escape is enabled, the
+% \texttt{true} branch is taken: if the command is forbidden at this stage, a
+% low-level \TeX{} error will arise.
+% \end{function}
+%
+% \begin{variable}[added = 2017-05-27]{\c_sys_shell_escape_int}
+% This variable exposes the internal triple of the shell escape
+% status. The possible values are
+% \begin{description}
+% \item[0] Shell escape is disabled
+% \item[1] Unrestricted shell escape is enabled
+% \item[2] Restricted shell escape is enabled
+% \end{description}
+% \end{variable}
+%
+% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell:}
+% \begin{syntax}
+% \cs{sys_if_shell_p:}
+% \cs{sys_if_shell:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Performs a check for whether shell escape is enabled. This
+% returns true if either of restricted or unrestricted shell escape
+% is enabled.
+% \end{function}
+%
+% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell_unrestricted:}
+% \begin{syntax}
+% \cs{sys_if_shell_unrestricted_p:}
+% \cs{sys_if_shell_unrestricted:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Performs a check for whether \emph{unrestricted} shell escape is
+% enabled.
+% \end{function}
+%
+% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell_restricted:}
+% \begin{syntax}
+% \cs{sys_if_shell_restricted_p:}
+% \cs{sys_if_shell_restricted:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Performs a check for whether \emph{restricted} shell escape is
+% enabled. This returns false if unrestricted shell escape is
+% enabled. Unrestricted shell escape is not considered a superset
+% of restricted shell escape in this case. To find whether any
+% shell escape is enabled use \cs{sys_if_shell:TF}.
+% \end{function}
+%
+% \begin{function}[added = 2017-05-27]
+% {\sys_shell_now:n, \sys_shell_now:e}
+% \begin{syntax}
+% \cs{sys_shell_now:n} \Arg{tokens}
+% \end{syntax}
+% Execute \meta{tokens} through shell escape immediately.
+% \end{function}
+%
+% \begin{function}[added = 2017-05-27]
+% {\sys_shell_shipout:n, \sys_shell_shipout:e}
+% \begin{syntax}
+% \cs{sys_shell_shipout:n} \Arg{tokens}
+% \end{syntax}
+% Execute \meta{tokens} through shell escape at shipout.
+% \end{function}
+%
+% \section{System queries}
+%
+% Some queries can be made about the file system, etc., without needing to
+% use unrestricted shell escape. This is carried out using the script
+% \texttt{l3sys-query}, which is documented separately. The wrappers here
+% use this script, if available, to obtain system information that is
+% not directly available within the \TeX{} run. Note that if restricted
+% shell escape is disabled, no results can be obtained.
+%
+% \begin{function}[added = 2024-03-08, updated = 2024-04-08]
+% {\sys_get_query:nN, \sys_get_query:nnN, \sys_get_query:nnnN}
+% \begin{syntax}
+% \cs{sys_get_query:nN} \Arg{cmd} \Arg{tl var}
+% \cs{sys_get_query:nnN} \Arg{cmd} \Arg{spec} \Arg{tl var}
+% \cs{sys_get_query:nnnN} \Arg{cmd} \Arg{options} \Arg{spec} \Arg{tl var}
+% \end{syntax}
+% Sets the \meta{tl var} to the information returned by the
+% \texttt{l3sys-query} \meta{cmd}, potentially supplying the \meta{options}
+% and \meta{spec} to the query call. The valid \meta{cmd} names are at present
+% \begin{itemize}
+% \item \texttt{pwd} Returns the present working directory
+% \item \texttt{ls} Returns a directory listing, using the \meta{spec} to
+% select files and applying the \meta{options} if given
+% \end{itemize}
+% The \meta{spec} is likely to contain the wildcards |*| or |?|,
+% and will automatically be passed to
+% the script without shell expansion. In a glob is needed within the
+% \meta{options}, this will need to be protected from shell expansion
+% using |'| tokens.
+%
+% The \meta{spec} and \meta{options}, if given, are expanded fully
+% before passing to the underlying script.
+%
+% Spaces in the output are stored as active tokens, allowing them to be
+% replaced by for example a visible space easily. Other non-letter
+% characters in the ASCII range are set to category code~12. The category
+% codes for characters out of the ASCII range are left unchanged: typically
+% this will mean that with an 8-bit engine, accented values can be typeset
+% directly whilst in Unicode engines, standard category code setup will
+% apply.
+%
+% If more than one line of text is returned by the \meta{cmd}, these will be
+% separated by character~13 (|^^M|) tokens of category code~12. In most
+% cases, \cs{sys_split_query:nnnN} should be preferred when multi-line
+% output is expected.
+% \end{function}
+%
+% \begin{function}[added = 2024-03-08]
+% {\sys_split_query:nN, \sys_split_query:nnN, \sys_split_query:nnnN}
+% \begin{syntax}
+% \cs{sys_split_query:nN} \Arg{cmd} \Arg{seq}
+% \cs{sys_split_query:nnN} \Arg{cmd} \Arg{spec} \Arg{seq}
+% \cs{sys_split_query:nnnN} \Arg{cmd} \Arg{options} \Arg{spec} \Arg{seq}
+% \end{syntax}
+% Works as described for \cs{sys_split_query:nnnN}, but sets the \meta{seq}
+% to contain one entry for each line returned by \texttt{l3sys-query}.
+% This function should therefore be preferred where multi-line return is
+% expected, e.g.~for the \texttt{ls} command.
+% \end{function}
+%
+% \section{Loading configuration data}
+%
+% \begin{function}[added = 2019-09-12]{\sys_load_backend:n}
+% \begin{syntax}
+% \cs{sys_load_backend:n} \Arg{backend}
+% \end{syntax}
+% Loads the additional configuration file needed for backend support.
+% If the \meta{backend} is empty, the standard backend for the engine in
+% use will be loaded. This command may only be used once.
+% \end{function}
+%
+% \begin{function}[added = 2022-07-29]{\sys_ensure_backend:}
+% \begin{syntax}
+% \cs{sys_ensure_backend:}
+% \end{syntax}
+% Ensures that a backend has been loaded by calling \cs{sys_load_backend:n}
+% if required.
+% \end{function}
+%
+% \begin{variable}{\c_sys_backend_str}
+% Set to the name of the backend in use by \cs{sys_load_backend:n} when
+% issued. Possible values are
+% \begin{itemize}
+% \item \texttt{pdftex}
+% \item \texttt{luatex}
+% \item \texttt{xetex}
+% \item \texttt{dvips}
+% \item \texttt{dvipdfmx}
+% \item \texttt{dvisvgm}
+% \end{itemize}
+% \end{variable}
+%
+% \begin{function}[added = 2019-09-12]{\sys_load_debug:}
+% \begin{syntax}
+% \cs{sys_load_debug:}
+% \end{syntax}
+% Load the additional configuration file for debugging support.
+% \end{function}
+%
+% \subsection{Final settings}
+%
+% \begin{function}[added = 2019-10-06]{\sys_finalise:}
+% \begin{syntax}
+% \cs{sys_finalise:}
+% \end{syntax}
+% Finalises all system-dependent functionality: required before loading
+% a backend.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3sys} implementation}
+%
+% \begin{macrocode}
+%<@@=sys>
+% \end{macrocode}
+%
+% \subsection{Kernel code}
+%
+% \begin{macrocode}
+%<*package>
+%<*tex>
+% \end{macrocode}
+%
+% \begin{macro}{\l_@@_tmp_tl}
+% \begin{macrocode}
+\tl_new:N \l_@@_tmp_tl
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Detecting the engine}
+%
+% \begin{macro}{\@@_const:nn}
+% Set the |T|, |F|, |TF|, |p| forms of |#1| to be constants equal to
+% the result of evaluating the boolean expression~|#2|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_const:nn #1#2
+ {
+ \bool_if:nTF {#2}
+ {
+ \cs_new_eq:cN { #1 :T } \use:n
+ \cs_new_eq:cN { #1 :F } \use_none:n
+ \cs_new_eq:cN { #1 :TF } \use_i:nn
+ \cs_new_eq:cN { #1 _p: } \c_true_bool
+ }
+ {
+ \cs_new_eq:cN { #1 :T } \use_none:n
+ \cs_new_eq:cN { #1 :F } \use:n
+ \cs_new_eq:cN { #1 :TF } \use_ii:nn
+ \cs_new_eq:cN { #1 _p: } \c_false_bool
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF, EXP]
+% {
+% \sys_if_engine_luatex:,
+% \sys_if_engine_pdftex:,
+% \sys_if_engine_ptex:,
+% \sys_if_engine_uptex:,
+% \sys_if_engine_xetex:
+% }
+% \begin{variable}{\c_sys_engine_str}
+% Set up the engine tests on the basis exactly one test should be true.
+% Mainly a case of looking for the appropriate marker primitive.
+% \begin{macrocode}
+\str_const:Ne \c_sys_engine_str
+ {
+ \cs_if_exist:NT \tex_luatexversion:D { luatex }
+ \cs_if_exist:NT \tex_pdftexversion:D { pdftex }
+ \cs_if_exist:NT \tex_kanjiskip:D
+ {
+ \cs_if_exist:NTF \tex_enablecjktoken:D
+ { uptex }
+ { ptex }
+ }
+ \cs_if_exist:NT \tex_XeTeXversion:D { xetex }
+ }
+\tl_map_inline:nn { { luatex } { pdftex } { ptex } { uptex } { xetex } }
+ {
+ \@@_const:nn { sys_if_engine_ #1 }
+ { \str_if_eq_p:Vn \c_sys_engine_str {#1} }
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{variable}{\c_sys_engine_exec_str,\c_sys_engine_format_str}
+% Take the functions defined above, and set up the engine and format
+% names. \cs{c_sys_engine_exec_str} differs from \cs{c_sys_engine_str}
+% as it is the \emph{actual} engine name, not a \enquote{filtered}
+% version. It differs for |ptex| and |uptex|, which have a leading
+% |e|, and for |luatex|, because \LaTeX{} uses the \Lua HB\TeX{}
+% engine.
+%
+% \cs{c_sys_engine_format_str} is quite similar to
+% \cs{c_sys_engine_str}, except that it differentiates |pdflatex| from
+% |latex| (which is \pdfTeX{} in DVI mode). This differentiation,
+% however, is reliable only if the user doesn't change
+% \cs{tex_pdfoutput:D} before loading this code.
+% \begin{macrocode}
+\group_begin:
+ \cs_set_eq:NN \lua_now:e \tex_directlua:D
+ \str_const:Ne \c_sys_engine_exec_str
+ {
+ \sys_if_engine_pdftex:T { pdf }
+ \sys_if_engine_xetex:T { xe }
+ \sys_if_engine_ptex:T { ep }
+ \sys_if_engine_uptex:T { eup }
+ \sys_if_engine_luatex:T
+ {
+ lua \lua_now:e
+ {
+ if (pcall(require, 'luaharfbuzz')) then ~
+ tex.print("hb") ~
+ end
+ }
+ }
+ tex
+ }
+\group_end:
+\str_const:Ne \c_sys_engine_format_str
+ {
+ \cs_if_exist:NTF \fmtname
+ {
+ \bool_lazy_or:nnTF
+ { \str_if_eq_p:Vn \fmtname { plain } }
+ { \str_if_eq_p:Vn \fmtname { LaTeX2e } }
+ {
+ \sys_if_engine_pdftex:T
+ { \int_compare:nNnT { \tex_pdfoutput:D } = { 1 } { pdf } }
+ \sys_if_engine_xetex:T { xe }
+ \sys_if_engine_ptex:T { p }
+ \sys_if_engine_uptex:T { up }
+ \sys_if_engine_luatex:T
+ {
+ \int_compare:nNnT { \tex_pdfoutput:D } = { 0 } { dvi }
+ lua
+ }
+ \str_if_eq:VnTF \fmtname { LaTeX2e }
+ { latex }
+ {
+ \bool_lazy_and:nnT
+ { \sys_if_engine_pdftex_p: }
+ { \int_compare_p:nNn { \tex_pdfoutput:D } = { 0 } }
+ { e }
+ tex
+ }
+ }
+ { \fmtname }
+ }
+ { unknown }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_sys_engine_version_str}
+% Various different engines, various different ways to extract the
+% data!
+% \begin{macrocode}
+\str_const:Ne \c_sys_engine_version_str
+ {
+ \str_case:on \c_sys_engine_str
+ {
+ { pdftex }
+ {
+ \int_div_truncate:nn { \tex_pdftexversion:D } { 100 }
+ .
+ \int_mod:nn { \tex_pdftexversion:D } { 100 }
+ .
+ \tex_pdftexrevision:D
+ }
+ { ptex }
+ {
+ \cs_if_exist:NT \tex_ptexversion:D
+ {
+ p
+ \int_use:N \tex_ptexversion:D
+ .
+ \int_use:N \tex_ptexminorversion:D
+ \tex_ptexrevision:D
+ -
+ \int_use:N \tex_epTeXversion:D
+ }
+ }
+ { luatex }
+ {
+ \int_div_truncate:nn { \tex_luatexversion:D } { 100 }
+ .
+ \int_mod:nn { \tex_luatexversion:D } { 100 }
+ .
+ \tex_luatexrevision:D
+ }
+ { uptex }
+ {
+ \cs_if_exist:NT \tex_ptexversion:D
+ {
+ p
+ \int_use:N \tex_ptexversion:D
+ .
+ \int_use:N \tex_ptexminorversion:D
+ \tex_ptexrevision:D
+ -
+ u
+ \int_use:N \tex_uptexversion:D
+ \tex_uptexrevision:D
+ -
+ \int_use:N \tex_epTeXversion:D
+ }
+ }
+ { xetex }
+ {
+ \int_use:N \tex_XeTeXversion:D
+ \tex_XeTeXrevision:D
+ }
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Platform}
+%
+% \begin{macro}[pTF]{\sys_if_platform_unix:, \sys_if_platform_windows:}
+% \begin{variable}{\c_sys_platform_str}
+% Setting these up requires the file module (file lookup), so is actually
+% implemented there.
+% \end{variable}
+% \end{macro}
+%
+% \subsubsection{Configurations}
+%
+% \begin{macro}{\sys_load_backend:n}
+% \begin{macro}{\@@_load_backend_check:N}
+% \begin{variable}{\c_sys_backend_str}
+% Loading the backend code is pretty simply: check that the backend is valid,
+% then load it up.
+% \begin{macrocode}
+\cs_new_protected:Npn \sys_load_backend:n #1
+ {
+ \sys_finalise:
+ \str_if_exist:NTF \c_sys_backend_str
+ {
+ \str_if_eq:VnF \c_sys_backend_str {#1}
+ { \msg_error:nn { sys } { backend-set } }
+ }
+ {
+ \tl_if_blank:nF {#1}
+ { \tl_gset:Nn \g_@@_backend_tl {#1} }
+ \@@_load_backend_check:N \g_@@_backend_tl
+ \str_const:Ne \c_sys_backend_str { \g_@@_backend_tl }
+ \__kernel_sys_configuration_load:n
+ { l3backend- \c_sys_backend_str }
+ }
+ }
+\cs_new_protected:Npn \@@_load_backend_check:N #1
+ {
+ \sys_if_engine_xetex:TF
+ {
+ \str_case:VnF #1
+ {
+ { dvisvgm } { }
+ { xdvipdfmx } { \tl_gset:Nn #1 { xetex } }
+ { xetex } { }
+ }
+ {
+ \msg_error:nnee { sys } { wrong-backend }
+ #1 { xetex }
+ \tl_gset:Nn #1 { xetex }
+ }
+ }
+ {
+ \sys_if_output_pdf:TF
+ {
+ \str_if_eq:VnTF #1 { pdfmode }
+ {
+ \sys_if_engine_luatex:TF
+ { \tl_gset:Nn #1 { luatex } }
+ { \tl_gset:Nn #1 { pdftex } }
+ }
+ {
+ \bool_lazy_or:nnF
+ { \str_if_eq_p:Vn #1 { luatex } }
+ { \str_if_eq_p:Vn #1 { pdftex } }
+ {
+ \msg_error:nnee { sys } { wrong-backend }
+ #1 { \sys_if_engine_luatex:TF { luatex } { pdftex } }
+ \sys_if_engine_luatex:TF
+ { \tl_gset:Nn #1 { luatex } }
+ { \tl_gset:Nn #1 { pdftex } }
+ }
+ }
+ }
+ {
+ \str_case:VnF #1
+ {
+ { dvipdfmx } { }
+ { dvips } { }
+ { dvisvgm } { }
+ }
+ {
+ \msg_error:nnee { sys } { wrong-backend }
+ #1 { dvips }
+ \tl_gset:Nn #1 { dvips }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\sys_ensure_backend:}
+% A simple wrapper.
+% \begin{macrocode}
+\cs_new_protected:Npn \sys_ensure_backend:
+ {
+ \str_if_exist:NF \c_sys_backend_str
+ { \sys_load_backend:n { } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_debug_bool}
+% \begin{macrocode}
+\bool_new:N \g_@@_debug_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\sys_load_debug:}
+% The most complicated thing here is that we can only use
+% \cs{__kernel_sys_configuration_load:n} in the preamble in \LaTeX{}.
+% \begin{macrocode}
+\cs_new_protected:Npn \sys_load_debug:
+ {
+ \bool_if:NF \g_@@_debug_bool
+ { \__kernel_sys_configuration_load:n { l3debug } }
+ \bool_gset_true:N \g_@@_debug_bool
+ }
+\cs_if_exist:NT \@expl@finalise@setup@@@@
+ {
+ \tl_gput_right:Nn \@expl@finalise@setup@@@@
+ {
+ \tl_gput_right:Nn \@kernel@after@begindocument
+ {
+ \cs_gset_protected:Npn \sys_load_debug:
+ { \msg_error:nn { sys } { load-debug-in-preamble } }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Access to the shell}
+%
+% \begin{variable}{\l_@@_internal_tl}
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_marker_tl}
+% The same idea as the marker for rescanning token lists.
+% \begin{macrocode}
+\tl_const:Ne \c_@@_marker_tl { : \token_to_str:N : }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[TF]{\sys_get_shell:nnN}
+% \begin{macro}{\sys_get_shell:nnN,\@@_get:nnN,\@@_get_do:Nw}
+% Setting using a shell is at this level just a slightly specialised file
+% operation, with an additional check for quotes, as these are not supported.
+% \begin{macrocode}
+\cs_new_protected:Npn \sys_get_shell:nnN #1#2#3
+ {
+ \sys_get_shell:nnNF {#1} {#2} #3
+ { \tl_set:Nn #3 { \q_no_value } }
+ }
+\prg_new_protected_conditional:Npnn \sys_get_shell:nnN #1#2#3 { T , F , TF }
+ {
+ \sys_if_shell:TF
+ { \exp_args:No \@@_get:nnN { \tl_to_str:n {#1} } {#2} #3 }
+ { \prg_return_false: }
+ }
+\cs_new_protected:Npn \@@_get:nnN #1#2#3
+ {
+ \tl_if_in:nnTF {#1} { " }
+ {
+ \msg_error:nne
+ { kernel } { quote-in-shell } {#1}
+ \prg_return_false:
+ }
+ {
+ \group_begin:
+ \if_false: { \fi:
+ \int_set_eq:NN \tex_tracingnesting:D \c_zero_int
+ \exp_args:No \tex_everyeof:D { \c_@@_marker_tl }
+ #2 \scan_stop:
+ \exp_after:wN \@@_get_do:Nw
+ \exp_after:wN #3
+ \exp_after:wN \prg_do_nothing:
+ \tex_input:D | "#1" \scan_stop:
+ \if_false: } \fi:
+ \prg_return_true:
+ }
+ }
+\exp_args:Nno \use:nn
+ { \cs_new_protected:Npn \@@_get_do:Nw #1#2 }
+ { \c_@@_marker_tl }
+ {
+ \group_end:
+ \tl_set:No #1 {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\c_@@_shell_stream_int}
+% This is not needed for \LuaTeX{}: shell escape there isn't done using
+% a \TeX{} interface.
+% \begin{macrocode}
+\sys_if_engine_luatex:F
+ { \int_const:Nn \c_@@_shell_stream_int { 18 } }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\sys_shell_now:n, \sys_shell_now:e, \sys_shell_now:x}
+% \begin{macro}{\@@_shell_now:e}
+% Execute commands through shell escape immediately.
+%
+% For \LuaTeX{}, we use a pseudo-primitive to do the actual work.
+% \begin{macrocode}
+%</tex>
+%<*lua>
+do
+ local os_exec = os.execute
+
+ local function shellescape(cmd)
+ local status,msg = os_exec(cmd)
+ if status == nil then
+ write_nl("log","runsystem(" .. cmd .. ")...(" .. msg .. ")\n")
+ elseif status == 0 then
+ write_nl("log","runsystem(" .. cmd .. ")...executed\n")
+ else
+ write_nl("log","runsystem(" .. cmd .. ")...failed " .. (msg or "") .. "\n")
+ end
+ end
+ luacmd("@@_shell_now:e", function()
+ shellescape(scan_string())
+ end, "global", "protected")
+%</lua>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*tex>
+\sys_if_engine_luatex:TF
+ {
+ \cs_new_protected:Npn \sys_shell_now:n #1
+ { \@@_shell_now:e { \exp_not:n {#1} } }
+ }
+ {
+ \cs_new_protected:Npn \sys_shell_now:n #1
+ { \iow_now:Nn \c_@@_shell_stream_int {#1} }
+ }
+\cs_generate_variant:Nn \sys_shell_now:n { e, x }
+%</tex>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\sys_shell_shipout:n, \sys_shell_shipout:e, \sys_shell_shipout:x}
+% \begin{macro}{\@@_shell_shipout:e}
+% Execute commands through shell escape at shipout.
+%
+% For \LuaTeX, we use the same helper as above but delayed using a |late_lua| whatsit.
+% Creating a |late_lua| whatsit works a bit different if we are running under Con\TeX{}t.
+% \begin{macrocode}
+%<*lua>
+ local new_latelua = nodes and nodes.nuts and nodes.nuts.pool and nodes.nuts.pool.latelua or (function()
+ local whatsit_id = node.id'whatsit'
+ local latelua_sub = node.subtype'late_lua'
+ local node_new = node.direct.new
+ local setfield = node.direct.setwhatsitfield or node.direct.setfield
+ return function(f)
+ local n = node_new(whatsit_id, latelua_sub)
+ setfield(n, 'data', f)
+ return n
+ end
+ end)()
+ local node_write = node.direct.write
+
+ luacmd("@@_shell_shipout:e", function()
+ local cmd = scan_string()
+ node_write(new_latelua(function() shellescape(cmd) end))
+ end, "global", "protected")
+end
+%</lua>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*tex>
+\sys_if_engine_luatex:TF
+ {
+ \cs_new_protected:Npn \sys_shell_shipout:n #1
+ { \@@_shell_shipout:e { \exp_not:n {#1} } }
+ }
+ {
+ \cs_new_protected:Npn \sys_shell_shipout:n #1
+ { \iow_shipout:Nn \c_@@_shell_stream_int {#1} }
+ }
+\cs_generate_variant:Nn \sys_shell_shipout:n { e , x }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Dynamic (every job) code}
+%
+% \begin{macro}{\__kernel_sys_everyjob:}
+% \begin{macro}{\@@_everyjob:n}
+% \begin{variable}{\g_@@_everyjob_tl}
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_sys_everyjob:
+ {
+ \tl_use:N \g_@@_everyjob_tl
+ \tl_gclear:N \g_@@_everyjob_tl
+ }
+\cs_new_protected:Npn \@@_everyjob:n #1
+ { \tl_gput_right:Nn \g_@@_everyjob_tl {#1} }
+\tl_new:N \g_@@_everyjob_tl
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{The name of the job}
+%
+% \begin{variable}{\c_sys_jobname_str}
+% Inherited from the \LaTeX3 name for the primitive. This \emph{has} to be
+% the primitive as it's set in \tn{everyjob}. If the user does
+% \begin{verbatim}
+% pdflatex \input some-file-name
+% \end{verbatim}
+% then \tn{everyjob} is inserted \emph{before} \tn{jobname} is changed form
+% |texput|, and thus we would have the wrong result.
+% \begin{macrocode}
+\@@_everyjob:n
+ { \cs_new_eq:NN \c_sys_jobname_str \tex_jobname:D }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Time and date}
+%
+% \begin{variable}
+% {
+% \c_sys_minute_int,
+% \c_sys_hour_int,
+% \c_sys_day_int,
+% \c_sys_month_int,
+% \c_sys_year_int,
+% }
+% Copies of the information provided by \TeX{}. There is a lot of defensive
+% code in package mode: someone may have moved the primitives, and they can
+% only be recovered if we have \tn{primitive} and it is working correctly.
+% For Ini\TeX{} of course that is all redundant but does no harm.
+% \begin{macrocode}
+\@@_everyjob:n
+ {
+ \group_begin:
+ \cs_set:Npn \@@_tmp:w #1
+ {
+ \str_if_eq:eeTF { \cs_meaning:N #1 } { \token_to_str:N #1 }
+ { #1 }
+ {
+ \cs_if_exist:NTF \tex_primitive:D
+ {
+ \bool_lazy_and:nnTF
+ { \sys_if_engine_xetex_p: }
+ {
+ \int_compare_p:nNn
+ { \exp_after:wN \use_none:n \tex_XeTeXrevision:D }
+ < { 99999 }
+ }
+ { 0 }
+ { \tex_primitive:D #1 }
+ }
+ { 0 }
+ }
+ }
+ \int_const:Nn \c_sys_minute_int
+ { \int_mod:nn { \@@_tmp:w \time } { 60 } }
+ \int_const:Nn \c_sys_hour_int
+ { \int_div_truncate:nn { \@@_tmp:w \time } { 60 } }
+ \int_const:Nn \c_sys_day_int { \@@_tmp:w \day }
+ \int_const:Nn \c_sys_month_int { \@@_tmp:w \month }
+ \int_const:Nn \c_sys_year_int { \@@_tmp:w \year }
+ \group_end:
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_sys_timestamp_str}
+% A simple expansion: Lua\TeX{} chokes if we use \tn{pdffeedback} here,
+% hence the direct use of Lua. Notice that the function there is in the
+% \texttt{pdf} library but isn actually tied to PDF.
+% \begin{macrocode}
+\@@_everyjob:n
+ {
+ \str_const:Ne \c_sys_timestamp_str
+ {
+ \cs_if_exist:NTF \tex_directlua:D
+ { \tex_directlua:D { tex.print(pdf.getcreationdate()) } }
+ { \tex_creationdate:D }
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsubsection{Random numbers}
+%
+% \begin{macro}[EXP]{\sys_rand_seed:}
+% Unpack the primitive.
+% \begin{macrocode}
+\@@_everyjob:n
+ {
+ \cs_new:Npn \sys_rand_seed: { \tex_the:D \tex_randomseed:D }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\sys_gset_rand_seed:n}
+% The primitive always assigns the seed globally.
+% \begin{macrocode}
+\@@_everyjob:n
+ {
+ \cs_new_protected:Npn \sys_gset_rand_seed:n #1
+ { \tex_setrandomseed:D \int_eval:n {#1} \exp_stop_f: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\sys_timer:, \@@_elapsedtime:}
+% \begin{macro}[EXP, pTF]{\sys_if_timer_exist:}
+% In \LuaTeX{}, create a pseudo-primitve, otherwise try to
+% locate the real primitive. The elapsed time will be
+% available if this succeeds.
+% \begin{macrocode}
+%</tex>
+%<*lua>
+ local gettimeofday = os.gettimeofday
+ local epoch = gettimeofday() - os.clock()
+ local write = tex.write
+ local tointeger = math.tointeger
+ luacmd('@@_elapsedtime:', function()
+ write(tointeger((gettimeofday() - epoch)*65536 // 1))
+ end, 'global')
+%</lua>
+%<*tex>
+\sys_if_engine_luatex:TF
+ {
+ \cs_new:Npn \sys_timer:
+ { \@@_elapsedtime: }
+ }
+ {
+ \cs_if_exist:NTF \tex_elapsedtime:D
+ {
+ \cs_new:Npn \sys_timer:
+ { \int_value:w \tex_elapsedtime:D }
+ }
+ {
+ \cs_new:Npn \sys_timer:
+ {
+ \int_value:w
+ \msg_expandable_error:nnn { kernel } { no-elapsed-time }
+ { \sys_timer: }
+ \c_zero_int
+ }
+ }
+ }
+\@@_const:nn { sys_if_timer_exist }
+ { \cs_if_exist_p:N \tex_elapsedtime:D || \cs_if_exist_p:N \@@_elapsedtime: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Access to the shell}
+%
+% \begin{variable}{\c_sys_shell_escape_int}
+% Expose the engine's shell escape status to the user.
+% \begin{macrocode}
+\@@_everyjob:n
+ {
+ \int_const:Nn \c_sys_shell_escape_int
+ {
+ \sys_if_engine_luatex:TF
+ {
+ \tex_directlua:D
+ { tex.sprint(status.shell_escape~or~os.execute()) }
+ }
+ { \tex_shellescape:D }
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP, pTF]{\sys_if_shell:, \sys_if_shell_unrestricted:, \sys_if_shell_restricted:}
+% Performs a check for whether shell escape is enabled. The first set
+% of functions returns true if either of restricted or unrestricted
+% shell escape is enabled, while the other two sets of functions
+% return true in only one of these two cases.
+% \begin{macrocode}
+\@@_everyjob:n
+ {
+ \@@_const:nn { sys_if_shell }
+ { \int_compare_p:nNn \c_sys_shell_escape_int > 0 }
+ \@@_const:nn { sys_if_shell_unrestricted }
+ { \int_compare_p:nNn \c_sys_shell_escape_int = 1 }
+ \@@_const:nn { sys_if_shell_restricted }
+ { \int_compare_p:nNn \c_sys_shell_escape_int = 2 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{System queries}
+%
+% \begin{macro}{\sys_get_query:nN}
+% \begin{macro}{\sys_get_query:nnN}
+% \begin{macro}
+% {
+% \sys_get_query:nnnN,
+% \@@_get_query_auxi:nnnN, \@@_get_query_auxi:neeN,
+% \@@_get_query_auxii:nnnN, \@@_get_query_auxii:neeN
+% }
+% Calling the query system is quite straight-forward: most of the effort is
+% in making the read-back catcode-safe. We also want to trim off the trailing
+% |^^M| from the last line.
+% \begin{macrocode}
+\cs_new_protected:Npn \sys_get_query:nN #1#2
+ { \sys_get_query:nnnN {#1} { } { } #2 }
+\cs_new_protected:Npn \sys_get_query:nnN #1#2#3
+ { \sys_get_query:nnnN {#1} { } {#2} #3 }
+\cs_new_protected:Npn \sys_get_query:nnnN #1#2#3#4
+ {
+ \tl_clear:N #4
+ \@@_get_query_auxi:neeN {#1} {#2} {#3} #4
+ }
+\cs_new:Npn \@@_get_query_auxi:nnnN #1#2#3#4
+ {
+ \@@_get_query_auxii:neeN {#1}
+ { \tl_if_blank:nF {#2} { \tl_to_str:n { ~ #2 } } }
+ {
+ \tl_if_blank:nF {#3}
+ {
+ \c_space_tl
+ \sys_if_shell_restricted:F '
+ \tl_to_str:n {#3}
+ \sys_if_shell_restricted:F '
+ }
+ }
+ #4
+ }
+\cs_generate_variant:Nn \@@_get_query_auxi:nnnN { nee }
+\cs_new_protected:Npn \@@_get_query_auxii:nnnN #1#2#3#4
+ {
+ \sys_if_shell:T
+ {
+ \sys_get_shell:nnN
+ { l3sys-query~#1 #2 #3 }
+ {
+ \int_step_inline:nnn { 0 } { `A - 1 }
+ { \char_set_catcode_other:n {##1} }
+ \int_step_inline:nnn { `Z + 1 } { `a - 1 }
+ { \char_set_catcode_other:n {##1} }
+ \int_step_inline:nnn { `z + 1 } { 127 }
+ { \char_set_catcode_other:n {##1} }
+ \char_set_catcode_active:n { `\ }
+ \tex_endlinechar:D 13 \scan_stop:
+ }
+ \l_@@_tmp_tl
+ \tl_if_empty:NF \l_@@_tmp_tl
+ {
+ \exp_after:wN \@@_get_query:Nw \exp_after:wN #4
+ \l_@@_tmp_tl \q_stop
+ }
+ }
+ }
+\cs_generate_variant:Nn \@@_get_query_auxii:nnnN { nee }
+\group_begin:
+ \tex_lccode:D `\* = 13 \scan_stop:
+ \tex_lowercase:D
+ {
+ \group_end:
+ \cs_new_protected:Npn \@@_get_query:Nw #1#2 * \q_stop
+ }
+ { \tl_set:Nn #1 {#2} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\sys_split_query:nN}
+% \begin{macro}{\sys_split_query:nnN}
+% \begin{macro}{\sys_split_query:nnnN}
+% A wrapper for convenience.
+% \begin{macrocode}
+\cs_new_protected:Npn \sys_split_query:nN #1#2
+ { \sys_split_query:nnnN {#1} { } { } #2 }
+\cs_new_protected:Npn \sys_split_query:nnN #1#2#3
+ { \sys_split_query:nnnN {#1} { } {#2} #3 }
+\group_begin:
+ \tex_lccode:D `\* = 13 \scan_stop:
+ \tex_lowercase:D
+ {
+ \group_end:
+ \cs_new_protected:Npn \sys_split_query:nnnN #1#2#3#4
+ {
+ \seq_clear:N #4
+ \sys_get_query:nnnN {#1} {#2} {#3} \l_@@_tmp_tl
+ \tl_if_empty:NF \l_@@_tmp_tl
+ { \seq_set_split:NnV #4 * \l_@@_tmp_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Held over from \pkg{l3file}}
+%
+% \begin{variable}{\g_file_curr_name_str}
+% See comments about \cs{c_sys_jobname_str}: here, as soon as there is
+% file input/output, things get \enquote{tided up}.
+% \begin{macrocode}
+\@@_everyjob:n
+ { \cs_gset_eq:NN \g_file_curr_name_str \tex_jobname:D }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Last-minute code}
+%
+% \begin{macro}{\sys_finalise:}
+% \begin{macro}{\@@_finalise:n}
+% \begin{variable}{\g_@@_finalise_tl}
+% A simple hook to finalise the system-dependent layer. This is forced by
+% the backend loader, which is forced by the main loader, so we do not need
+% to include that here.
+% \begin{macrocode}
+\cs_new_protected:Npn \sys_finalise:
+ {
+ \__kernel_sys_everyjob:
+ \tl_use:N \g_@@_finalise_tl
+ \tl_gclear:N \g_@@_finalise_tl
+ }
+\cs_new_protected:Npn \@@_finalise:n #1
+ { \tl_gput_right:Nn \g_@@_finalise_tl {#1} }
+\tl_new:N \g_@@_finalise_tl
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Detecting the output}
+%
+% \begin{macro}[pTF, EXP]
+% {
+% \sys_if_output_dvi:,
+% \sys_if_output_pdf:
+% }
+% \begin{variable}{\c_sys_output_str}
+% This is a simple enough concept: the two views here are complementary.
+% \begin{macrocode}
+\@@_finalise:n
+ {
+ \str_const:Ne \c_sys_output_str
+ {
+ \int_compare:nNnTF
+ { \cs_if_exist_use:NF \tex_pdfoutput:D { 0 } } > { 0 }
+ { pdf }
+ { dvi }
+ }
+ \@@_const:nn { sys_if_output_dvi }
+ { \str_if_eq_p:Vn \c_sys_output_str { dvi } }
+ \@@_const:nn { sys_if_output_pdf }
+ { \str_if_eq_p:Vn \c_sys_output_str { pdf } }
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \subsubsection{Configurations}
+%
+% \begin{variable}{\g_@@_backend_tl}
+% As the backend has to be checked and possibly adjusted, the approach here
+% is to create a variable and use that in a one-shot to set a constant.
+% \begin{macrocode}
+\tl_new:N \g_@@_backend_tl
+\@@_finalise:n
+ {
+ \__kernel_tl_gset:Nx \g_@@_backend_tl
+ {
+ \sys_if_engine_xetex:TF
+ { xetex }
+ {
+ \sys_if_output_pdf:TF
+ {
+ \sys_if_engine_pdftex:TF
+ { pdftex }
+ { luatex }
+ }
+ { dvips }
+ }
+ }
+ }
+% \end{macrocode}
+% If there is a class option set, and recognised, we pick it up: these
+% will over-ride anything set automatically but will themselves be
+% over-written if there is a package option.
+% \begin{macrocode}
+\@@_finalise:n
+ {
+ \cs_if_exist:NT \@classoptionslist
+ {
+ \cs_if_eq:NNF \@classoptionslist \scan_stop:
+ {
+ \clist_map_inline:Nn \@classoptionslist
+ {
+ \str_case:nnT {#1}
+ {
+ { dvipdfmx }
+ { \tl_gset:Nn \g_@@_backend_tl { dvipdfmx } }
+ { dvips }
+ { \tl_gset:Nn \g_@@_backend_tl { dvips } }
+ { dvisvgm }
+ { \tl_gset:Nn \g_@@_backend_tl { dvisvgm } }
+ { pdftex }
+ { \tl_gset:Nn \g_@@_backend_tl { pdfmode } }
+ { xetex }
+ { \tl_gset:Nn \g_@@_backend_tl { xdvipdfmx } }
+ }
+ { \clist_remove_all:Nn \@unusedoptionlist {#1} }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macrocode}
+%</tex>
+%</package>
+% \end{macrocode}
+%
+%\end{implementation}
+%
+%\PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3term-glossary.pdf b/macros/latex-dev/required/l3kernel/l3term-glossary.pdf
new file mode 100644
index 0000000000..7d03a9143b
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3term-glossary.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3term-glossary.tex b/macros/latex-dev/required/l3kernel/l3term-glossary.tex
new file mode 100644
index 0000000000..d1b4b0082c
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3term-glossary.tex
@@ -0,0 +1,180 @@
+\iffalse meta-comment
+
+File: l3term-glossary.tex
+
+Copyright (C) 2018-2024 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this
+license or (at your option) any later version. The latest version
+of this license is in the file
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3kernel bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+The released version of this bundle is available from CTAN.
+
+\fi
+
+\documentclass{l3doc}
+
+
+\title{%
+ Glossary of \TeX{} terms used to describe \LaTeX3 functions%
+}
+\author{%
+ The \LaTeX{} Project\thanks
+ {%
+ E-mail:
+ \href{mailto:latex-team@latex-project.org}%
+ {latex-team@latex-project.org}%
+ }%
+}
+\date{Released 2024-04-11}
+
+\newcommand{\TF}{\textit{(TF)}}
+
+\begin{document}
+
+\maketitle
+
+This file describes aspects of \TeX{} programming that are relevant in a
+\pkg{expl3} context.
+
+\section{Reading a file}
+
+Tokenization.
+
+Treatment of spaces, such as the trap that \verb|\~~a| is equivalent to
+\verb|\~a| in \pkg{expl3} syntax, or that \verb|~| fails to give a space at the
+beginning of a line.
+
+\section{Structure of tokens}
+
+We refer to the documentation of \texttt{l3token} for a complete
+description of all \TeX{} tokens. We distinguish the meaning of the
+token, which controls the expansion of the token and its effect on
+\TeX{}'s state, and its shape, which is used when comparing token lists
+such as for delimited arguments. At any given time two tokens of the
+same shape automatically have the same meaning, but the converse does
+not hold, and the meaning associated with a given shape change when
+doing assignments.
+
+Apart from a few exceptions, a token has one of the following shapes.
+\begin{itemize}
+ \item A control sequence, characterized by the sequence of characters
+ that constitute its name: for instance, \cs{use:n} is a five-letter
+ control sequence.
+ \item An active character token, characterized by its character code
+ (between $0$ and $1114111$ for \LuaTeX{} and \XeTeX{} and less for
+ other engines) and category code~$13$.
+ \item A character token such as |A| or |#|, characterized by its
+ character code and category code (one of $1$, $2$, $3$, $4$, $6$,
+ $7$, $8$, $10$, $11$ or~$12$ whose meaning is described below).
+\end{itemize}
+
+The meaning of a (non-active) character token is fixed by its category
+code (and character code) and cannot be changed. We call these tokens
+\emph{explicit} character tokens. Category codes that a character token
+can have are listed below by giving a sample output of the \TeX{}
+primitive \tn{meaning}, together with their \pkg{expl3} names and most
+common example:
+\begin{itemize}
+ \item[1] begin-group character (|group_begin|, often |{|),
+ \item[2] end-group character (|group_end|, often |}|),
+ \item[3] math shift character (|math_toggle|, often |$|), % $
+ \item[4] alignment tab character (|alignment|, often |&|),
+ \item[6] macro parameter character (|parameter|, often |#|),
+ \item[7] superscript character (|math_superscript|, often |^|),
+ \item[8] subscript character (|math_subscript|, often |_|),
+ \item[10] blank space (|space|, often character code~$32$),
+ \item[11] the letter (|letter|, such as |A|),
+ \item[12] the character (|other|, such as |0|).
+\end{itemize}
+Category code~$13$ (|active|) is discussed below. Input characters can
+also have several other category codes which do not lead to character
+tokens for later processing: $0$~(|escape|), $5$~(|end_line|),
+$9$~(|ignore|), $14$~(|comment|), and $15$~(|invalid|).
+
+The meaning of a control sequence or active character can be identical
+to that of any character token listed above (with any character code),
+and we call such tokens \emph{implicit} character tokens. The meaning
+is otherwise in the following list:
+\begin{itemize}
+ \item a macro, used in \pkg{expl3} for most functions and some variables
+ (|tl|, |fp|, |seq|, \ldots{}),
+ \item a primitive such as \tn{def} or \tn{topmark}, used in \pkg{expl3}
+ for some functions,
+ \item a register such as \tn{count}|123|, used in \pkg{expl3} for the
+ implementation of some variables (|int|, |dim|, \ldots{}),
+ \item a constant integer such as \tn{char}|"56| or
+ \tn{mathchar}|"121|, used when defining a constant using
+ \cs{int_const:Nn},
+ \item a font selection command,
+ \item undefined.
+\end{itemize}
+Macros can be \tn{protected} or not, \tn{long} or not (the opposite of
+what \pkg{expl3} calls |nopar|), and \tn{outer} or not (unused in \pkg{expl3}).
+Their \tn{meaning} takes the form
+\begin{quote}
+ \meta{prefix} |macro:|\meta{argument}|->|\meta{replacement}
+\end{quote}
+where \meta{prefix} is among \tn{protected}\tn{long}\tn{outer},
+\meta{argument} describes parameters that the macro expects, such as
+|#1#2#3|, and \meta{replacement} describes how the parameters are
+manipulated, such as~|\int_eval:n{#2+#1*#3}|. This information can be
+accessed by \cs{cs_prefix_spec:N}, \cs{cs_parameter_spec:N},
+\cs{cs_replacement_spec:N}.
+
+When a macro takes an undelimited argument, explicit space characters
+(with character code $32$ and category code $10$) are ignored. If the
+following token is an explicit character token with category code $1$
+(begin-group) and an arbitrary character code, then \TeX{} scans ahead
+to obtain an equal number of explicit character tokens with category
+code $1$ (begin-group) and $2$ (end-group), and the resulting list of
+tokens (with outer braces removed) becomes the argument. Otherwise, a
+single token is taken as the argument for the macro: we call such single
+tokens \enquote{N-type}, as they are suitable to be used as an argument
+for a function with the signature~\texttt{:N}.
+
+When a macro takes a delimited argument \TeX{} scans ahead until finding
+the delimiter (outside any pairs of begin-group/end-group explicit
+characters), and the resulting list of tokens (with outer braces
+removed) becomes the argument. Note that explicit space characters at
+the start of the argument are \emph{not} ignored in this case (and they
+prevent brace-stripping).
+
+\section{Handling of hash tokens}
+
+\TeX{} uses the hash (octothorpe) character |#| to denote parameters for
+macros: these must be numbered sequentially. To allow handling of nested
+macros, \TeX{} requires that for each nesting level, hash tokens are doubled.
+For example
+\begin{verbatim}
+\cs_new:Npn \mypkg_outer:N #1
+ {
+ \cs_new:Npn \mypkg_inner:N ##1
+ {
+ #1
+ ##1
+ }
+ }
+\end{verbatim}
+would define both |\mypkg_outer:N| and |\mypkg_inner:N| as taking
+exactly one argument. If we then do
+\begin{verbatim}
+\mypkg_outer:N \foo
+\cs_show:N \mypkg_inner:N
+\end{verbatim}
+\TeX{} will report
+\begin{verbatim}
+> \mypkg_inner:N=\long macro:#1->\foo #1.
+\end{verbatim}
+i.e.~the hash is not doubled, but is now the parameter of this macro.
+
+Exactly the same concept applies to anywhere that inline code is nested in
+\pkg{expl3}, for example inline mapping code, key definitions, etc.
+
+\end{document}
diff --git a/macros/latex-dev/required/l3kernel/l3text-case.dtx b/macros/latex-dev/required/l3kernel/l3text-case.dtx
new file mode 100644
index 0000000000..5010114fb4
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3text-case.dtx
@@ -0,0 +1,2336 @@
+% \iffalse meta-comment
+%
+%% File: l3text-case.dtx
+%
+% Copyright (C) 2020-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3text-case} module\\ Text processing (case changing)^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3text-case} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=text>
+% \end{macrocode}
+%
+% \subsection{Case changing}
+%
+% \begin{variable}{\l_text_titlecase_check_letter_bool}
+% Needed to determine the route used in titlecasing.
+% \begin{macrocode}
+\bool_new:N \l_text_titlecase_check_letter_bool
+\bool_set_true:N \l_text_titlecase_check_letter_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]
+% {
+% \text_lowercase:n,
+% \text_uppercase:n,
+% \text_titlecase_all:n,
+% \text_titlecase_first:n
+% }
+% \begin{macro}[EXP]
+% {
+% \text_lowercase:nn,
+% \text_uppercase:nn,
+% \text_titlecase_all:nn,
+% \text_titlecase_first:nn
+% }
+% \begin{macro}[EXP]{\@@_change_case:nnn}
+% The user level functions here are all wrappers around the internal
+% functions for case changing.
+% \begin{macrocode}
+\cs_new:Npn \text_lowercase:n #1
+ { \@@_change_case:nnn { lower } { } {#1} }
+\cs_new:Npn \text_uppercase:n #1
+ { \@@_change_case:nnn { upper } { } {#1} }
+\cs_new:Npn \text_titlecase_all:n #1
+ { \@@_change_case:nnn { title } { } {#1} }
+\cs_new:Npn \text_titlecase_first:n #1
+ { \@@_change_case:nnnn { title } { break } { } {#1} }
+\cs_new:Npn \text_lowercase:nn #1#2
+ { \@@_change_case:nnn { lower } {#1} {#2} }
+\cs_new:Npn \text_uppercase:nn #1#2
+ { \@@_change_case:nnn { upper } {#1} {#2} }
+\cs_new:Npn \text_titlecase_all:nn #1#2
+ { \@@_change_case:nnn { title } {#1} {#2} }
+\cs_new:Npn \text_titlecase_first:nn #1#2
+ { \@@_change_case:nnnn { title } { break } {#1} {#2} }
+\cs_new:Npn \@@_change_case:nnn #1#2#3
+ { \@@_change_case:nnnn {#1} {#1} {#2} {#3} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_change_case:nnnn ,
+% \@@_change_case_auxi:nnnn ,
+% \@@_change_case_auxii:nnnn
+% }
+% \begin{macro}[EXP]{\@@_change_case_BCP:nnnn}
+% \begin{macro}[EXP]{\@@_change_case_BCP:nnnw}
+% \begin{macro}[EXP]{\@@_change_case_BCP:nnnnnw}
+% \begin{macro}[EXP]
+% {
+% \@@_change_case_store:n, \@@_change_case_store:o,
+% \@@_change_case_store:V, \@@_change_case_store:v,
+% \@@_change_case_store:e
+% }
+% \begin{macro}[EXP]{\@@_change_case_store:nw}
+% \begin{macro}[EXP]{\@@_change_case_result:n}
+% \begin{macro}[EXP]{\@@_change_case_end:w}
+% \begin{macro}[EXP]{\@@_change_case_loop:nnnw}
+% \begin{macro}[EXP]{\@@_change_case_break:w, \@@_change_case_break_aux:w}
+% \begin{macro}[EXP]
+% {
+% \@@_change_case_group_lower:nnnn ,
+% \@@_change_case_group_upper:nnnn ,
+% \@@_change_case_group_title:nnnn
+% }
+% \begin{macro}[EXP]
+% {\@@_change_case_space:nnnw, \@@_change_case_space_break:nnnw}
+% \begin{macro}[EXP]
+% {\@@_change_case_N_type:nnnN, \@@_change_case_N_type_aux:nnnN}
+% \begin{macro}[EXP]{\@@_change_case_N_type:nnnnN}
+% \begin{macro}[EXP]{\@@_change_case_math_search:nnnNNN}
+% \begin{macro}[EXP]{\@@_change_case_math_loop:nnnNw}
+% \begin{macro}[EXP]{\@@_change_case_math_N_type:nnnNN}
+% \begin{macro}[EXP]{\@@_change_case_math_group:nnnNn}
+% \begin{macro}[EXP]{\@@_change_case_math_space:nnnNw}
+% \begin{macro}[EXP]{\@@_change_case_cs_check:nnnN}
+% \begin{macro}[EXP]{\@@_change_case_exclude:nnnN}
+% \begin{macro}[EXP]{\@@_change_case_exclude:nnnnN}
+% \begin{macro}[EXP]{\@@_change_case_exclude:nnnNN}
+% \begin{macro}[EXP]{\@@_change_case_exclude:nnnNw}
+% \begin{macro}[EXP]{\@@_change_case_exclude:nnnNnn}
+% \begin{macro}[EXP]{\@@_change_case_replace:nnnN}
+% \begin{macro}[EXP]{\@@_change_case_replace:nnnn, \@@_change_case_replace:vnnn}
+% \begin{macro}[EXP]{\@@_change_case_switch:nnnN}
+% \begin{macro}[EXP]
+% {
+% \@@_change_case_switch_lower:nnnNnnnn ,
+% \@@_change_case_switch_upper:nnnNnnnn ,
+% \@@_change_case_switch_title:nnnNnnnn
+% }
+% \begin{macro}[EXP]{\@@_change_case_skip:nnw}
+% \begin{macro}[EXP]{\@@_change_case_skip_N_type:nnN}
+% \begin{macro}[EXP]{\@@_change_case_skip_group:nnn}
+% \begin{macro}[EXP]{\@@_change_case_skip_space:nnw}
+% \begin{macro}[EXP]
+% {
+% \@@_change_case_letterlike_lower:nnnN ,
+% \@@_change_case_letterlike_upper:nnnN ,
+% \@@_change_case_letterlike_title:nnnN
+% }
+% \begin{macro}[EXP]{\@@_change_case_letterlike:nnnnnN}
+% \begin{macro}[EXP]
+% {
+% \@@_change_case_custom_lower:nnnn ,
+% \@@_change_case_custom_title:nnnn ,
+% \@@_change_case_custom_upper:nnnn
+% }
+% \begin{macro}[EXP]{\@@_change_case_custom:nnnnn}
+% \begin{macro}[EXP]
+% {
+% \@@_change_case_codepoint_lower:nnnn ,
+% \@@_change_case_codepoint_upper:nnnn ,
+% \@@_change_case_codepoint_title:nnnn
+% }
+% \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnnnn}
+% \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnnnw}
+% \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnnnN}
+% \begin{macro}[EXP]
+% {
+% \@@_change_case_codepoint_title_auxi:nnnn ,
+% \@@_change_case_codepoint_title_auxii:nnnn
+% }
+% \begin{macro}[EXP]{\@@_change_case_codepoint_title:nnn}
+% \begin{macro}[EXP]{\@@_change_case_codepoint:nnnnn}
+% \begin{macro}[EXP]{\@@_change_case_codepoint:nn}
+% \begin{macro}[EXP]
+% {
+% \@@_change_case_codepoint:nnn ,
+% \@@_change_case_codepoint:fnn ,
+% \@@_change_case_codepoint_aux:nnn
+% }
+% \begin{macro}[EXP]{\@@_change_case_codepoint_aux:nnn}
+% \begin{macro}[EXP]{\@@_change_case_codepoint_aux:nn}
+% \begin{macro}[EXP]{\@@_change_case_catcode:nn}
+% \begin{macro}[EXP]
+% {
+% \@@_change_case_next_lower:nnn ,
+% \@@_change_case_next_upper:nnn ,
+% \@@_change_case_next_title:nnn ,
+% \@@_change_case_next_end:nnn
+% }
+% As for the expansion code, the business end of case changing is the
+% handling of \texttt{N}-type tokens. First, we expand the input fully
+% (so the loops here don't need to worry about awkward look-aheads and the
+% like). Then we split into the different paths.
+%
+% The code here needs to be \texttt{f}-type expandable to deal with the
+% situation where case changing is applied in running text. There, we
+% might have case changing as a document command and the text containing
+% other non-expandable document commands.
+% \begin{verbatim}
+% \cs_set_eq:NN \MakeLowercase \text_lowercase
+% ...
+% \MakeLowercase{\enquote*{A} text}
+% \end{verbatim}
+% If we use an \texttt{e}-type expansion and wrap each token in
+% \cs{exp_not:n}, that would explode: the document command grabs
+% \cs{exp_not:n} as an argument, and things go badly wrong. So we have to
+% wrap the entire result in exactly one \cs{exp_not:n}, or rather in the
+% kernel version.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case:nnnn #1#2#3#4
+ {
+ \__kernel_exp_not:w \exp_after:wN
+ {
+ \exp:w
+ \exp_args:Ne \@@_change_case_auxi:nnnn
+ { \text_expand:n {#4} }
+ {#1} {#2} {#3}
+ }
+ }
+\cs_new:Npn \@@_change_case_auxi:nnnn #1#2#3#4
+ {
+ \exp_args:No \@@_change_case_BCP:nnnn
+ { \tl_to_str:n {#4} } {#1} {#2} {#3}
+ }
+\cs_new:Npe \@@_change_case_BCP:nnnn #1#2#3#4
+ {
+ \exp_not:N \@@_change_case_BCP:nnnw
+ {#2} {#3} {#4} #1 \tl_to_str:n { -x- -x- } \exp_not:N \q_@@_stop
+ }
+\use:e
+ {
+ \cs_new:Npn \exp_not:N \@@_change_case_BCP:nnnw
+ #1#2#3#4 \tl_to_str:n { -x- } #5 \tl_to_str:n { -x- } #6
+ \exp_not:N \q_@@_stop
+ }
+ { \@@_change_case_BCP:nnnnnw {#1} {#2} {#3} {#5} {#4} #4 - \q_@@_stop }
+\cs_new:Npn \@@_change_case_BCP:nnnnnw #1#2#3#4#5#6 - #7 \q_@@_stop
+ {
+ \bool_lazy_or:nnTF
+ { \cs_if_exist_p:c { @@_change_case_ #2 _ #6 -x- #4 :nnnnn } }
+ { \tl_if_exist_p:c { l_@@_ #2 case_special_ #6 -x- #4 _tl } }
+ { \@@_change_case_auxii:nnnn {#1} {#2} {#3} { #6 -x- #4 } }
+ {
+ \cs_if_exist:cTF { @@_change_case_ #2 _ #6 :nnnnn }
+ { \@@_change_case_auxii:nnnn {#1} {#2} {#3} {#6} }
+ { \@@_change_case_auxii:nnnn {#1} {#2} {#3} {#5} }
+ }
+ }
+\cs_new:Npn \@@_change_case_auxii:nnnn #1#2#3#4
+ {
+ \group_align_safe_begin:
+ \cs_if_exist_use:c { @@_change_case_boundary_ #2 _ #4 :Nnnnw }
+ \@@_change_case_loop:nnnw {#2} {#3} {#4} #1
+ \q_@@_recursion_tail \q_@@_recursion_stop
+ \@@_change_case_result:n { }
+ }
+% \end{macrocode}
+% As for expansion, collect up the tokens for future use.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_store:n #1
+ { \@@_change_case_store:nw {#1} }
+\cs_generate_variant:Nn \@@_change_case_store:n { o , e , V , v }
+\cs_new:Npn \@@_change_case_store:nw #1#2 \@@_change_case_result:n #3
+ { #2 \@@_change_case_result:n { #3 #1 } }
+\cs_new:Npn \@@_change_case_end:w #1 \@@_change_case_result:n #2
+ {
+ \group_align_safe_end:
+ \exp_end:
+ #2
+ }
+% \end{macrocode}
+% The main loop is the standard \texttt{tl action} type.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_loop:nnnw #1#2#3#4 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#4}
+ { \@@_change_case_N_type:nnnN }
+ {
+ \tl_if_head_is_group:nTF {#4}
+ { \use:c { @@_change_case_group_ #1 :nnnn } }
+ { \@@_change_case_space:nnnw }
+ }
+ {#1} {#2} {#3} #4 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_change_case_break:w
+ { \@@_change_case_break_aux:w \prg_do_nothing: }
+\cs_new:Npn \@@_change_case_break_aux:w
+ #1 \q_@@_recursion_tail \q_@@_recursion_stop
+ {
+ \@@_change_case_store:o {#1}
+ \@@_change_case_end:w
+ }
+% \end{macrocode}
+% For a group, we \emph{could} worry about whether this contains a character
+% or not. However, that would make life very complex for little gain: exactly
+% what a first character is is rather weakly-defined anyway. So if there is
+% a group, we simply assume that a character has been seen, and for title
+% case we switch to the \enquote{rest of the tokens} situation. To avoid
+% having too much testing, we use a two-step process here to allow the
+% titlecase functions to be separate.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_group_lower:nnnn #1#2#3#4
+ {
+ \@@_change_case_store:o
+ {
+ \exp_after:wN
+ {
+ \exp:w
+ \@@_change_case_auxii:nnnn {#4} {#1} {#2} {#3}
+ }
+ }
+ \@@_change_case_loop:nnnw {#1} {#2} {#3}
+ }
+\cs_new_eq:NN \@@_change_case_group_upper:nnnn
+ \@@_change_case_group_lower:nnnn
+\cs_new:Npn \@@_change_case_group_title:nnnn #1#2#3#4
+ {
+ \@@_change_case_store:o
+ {
+ \exp_after:wN
+ {
+ \exp:w
+ \@@_change_case_auxii:nnnn {#4} {#1} {#2} {#3}
+ }
+ }
+ \@@_change_case_skip:nnw {#2} {#3}
+ }
+\use:e
+ {
+ \cs_new:Npn \exp_not:N \@@_change_case_space:nnnw #1#2#3 \c_space_tl
+ }
+ {
+ \@@_change_case_store:n { ~ }
+ \cs_if_exist_use:cF { @@_change_case_space_ #2 :nnn }
+ {
+ \cs_if_exist_use:c { @@_change_case_boundary_ #1 _ #3 :Nnnnw }
+ \@@_change_case_loop:nnnw
+ }
+ {#2} {#2} {#3}
+ }
+\cs_new:Npn \@@_change_case_space_break:nnn #1#2#3
+ { \@@_change_case_break:w }
+% \end{macrocode}
+% The first step of handling \texttt{N}-type tokens is to filter out the
+% end-of-loop. That has to be done separately from the first real step
+% as otherwise we pick up the wrong delimiter. The loop here is the same
+% as the \texttt{expand} one, just passing the additional data long. If no
+% close-math token is found then the final clean-up is forced
+% (i.e.~there is no assumption of \enquote{well-behaved} input in terms of
+% math mode).
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_N_type:nnnN #1#2#3#4
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #4
+ { \@@_change_case_end:w }
+ \@@_change_case_N_type_aux:nnnN {#1} {#2} {#3} #4
+ }
+\cs_new:Npn \@@_change_case_N_type_aux:nnnN #1#2#3#4
+ {
+ \exp_args:NV \@@_change_case_N_type:nnnnN
+ \l_text_math_delims_tl {#1} {#2} {#3} #4
+ }
+\cs_new:Npn \@@_change_case_N_type:nnnnN #1#2#3#4#5
+ {
+ \@@_change_case_math_search:nnnNNN {#2} {#3} {#4} #5 #1
+ \q_@@_recursion_tail \q_@@_recursion_tail
+ \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_change_case_math_search:nnnNNN #1#2#3#4#5#6
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #5
+ { \@@_change_case_cs_check:nnnN {#1} {#2} {#3} #4 }
+ \token_if_eq_meaning:NNTF #4 #5
+ {
+ \@@_use_i_delimit_by_q_recursion_stop:nw
+ {
+ \@@_change_case_store:n {#4}
+ \@@_change_case_math_loop:nnnNw {#1} {#2} {#3} #6
+ }
+ }
+ { \@@_change_case_math_search:nnnNNN {#1} {#2} {#3} #4 }
+ }
+\cs_new:Npn \@@_change_case_math_loop:nnnNw #1#2#3#4#5 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#5}
+ { \@@_change_case_math_N_type:nnnNN }
+ {
+ \tl_if_head_is_group:nTF {#5}
+ { \@@_change_case_math_group:nnnNn }
+ { \@@_change_case_math_space:nnnNw }
+ }
+ {#1} {#2} {#3} #4 #5 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_change_case_math_N_type:nnnNN #1#2#3#4#5
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #5
+ { \@@_change_case_end:w }
+ \@@_change_case_store:n {#5}
+ \token_if_eq_meaning:NNTF #5 #4
+ { \@@_change_case_loop:nnnw {#1} {#2} {#3} }
+ { \@@_change_case_math_loop:nnnNw {#1} {#2} {#3} #4 }
+ }
+\cs_new:Npn \@@_change_case_math_group:nnnNn #1#2#3#4#5
+ {
+ \@@_change_case_store:n { {#5} }
+ \@@_change_case_math_loop:nnnNw {#1} {#2} {#3} #4
+ }
+\use:e
+ {
+ \cs_new:Npn \exp_not:N \@@_change_case_math_space:nnnNw #1#2#3#4
+ \c_space_tl
+ }
+ {
+ \@@_change_case_store:n { ~ }
+ \@@_change_case_math_loop:nnnNw {#1} {#2} {#3} #4
+ }
+% \end{macrocode}
+% Once potential math-mode cases are filtered out the next stage is to
+% test if the token grabbed is a control sequence: the two routes the code
+% may take are then very different.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_cs_check:nnnN #1#2#3#4
+ {
+ \token_if_cs:NTF #4
+ { \@@_change_case_exclude:nnnN {#1} {#2} {#3} }
+ {
+ \@@_codepoint_process:nN
+ { \use:c { @@_change_case_custom_ #1 :nnnn } {#1} {#2} {#3} }
+ }
+ #4
+ }
+% \end{macrocode}
+% To deal with a control sequence there is first a need to test if it is
+% on the list which indicate that case changing should be skipped. That's
+% done using a loop as for the other special cases. If a hit is found then
+% the argument is grabbed and passed through as-is.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_exclude:nnnN #1#2#3#4
+ {
+ \exp_args:Ne \@@_change_case_exclude:nnnnN
+ {
+ \exp_not:V \l_text_math_arg_tl
+ \exp_not:V \l_text_case_exclude_arg_tl
+ }
+ {#1} {#2} {#3} #4
+ }
+\cs_new:Npn \@@_change_case_exclude:nnnnN #1#2#3#4#5
+ {
+ \@@_change_case_exclude:nnnNN {#2} {#3} {#4} #5 #1
+ \q_@@_recursion_tail \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_change_case_exclude:nnnNN #1#2#3#4#5
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #5
+ { \@@_change_case_replace:nnnN {#1} {#2} {#3} #4 }
+ \str_if_eq:nnTF {#4} {#5}
+ {
+ \@@_use_i_delimit_by_q_recursion_stop:nw
+ { \@@_change_case_exclude:nnnNw {#1} {#2} {#3} #4 }
+ }
+ { \@@_change_case_exclude:nnnNN {#1} {#2} {#3} #4 }
+ }
+\cs_new:Npn \@@_change_case_exclude:nnnNw #1#2#3#4#5#
+ { \@@_change_case_exclude:nnnNnn {#1} {#2} {#3} {#4} {#5} }
+\cs_new:Npn \@@_change_case_exclude:nnnNnn #1#2#3#4#5#6
+ {
+ \tl_if_blank:nTF {#5}
+ { \@@_change_case_store:n { #4 {#6} } }
+ {
+ \@@_change_case_store:o
+ {
+ \exp_after:wN #4
+ \exp:w \@@_change_case_auxii:nnnn {#5} {#1} {#2} {#3}
+ {#6}
+ }
+ }
+ \@@_change_case_loop:nnnw {#1} {#2} {#3}
+ }
+% \end{macrocode}
+% Deal with any specialist replacement for case changing.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_replace:nnnN #1#2#3#4
+ {
+ \cs_if_exist:cTF { l_@@_case_ \token_to_str:N #4 _tl }
+ {
+ \@@_change_case_replace:vnnn
+ { l_@@_case_ \token_to_str:N #4 _tl } {#1} {#2} {#3}
+ }
+ { \@@_change_case_switch:nnnN {#1} {#2} {#3} #4 }
+ }
+\cs_new:Npn \@@_change_case_replace:nnnn #1#2#3#4
+ { \@@_change_case_loop:nnnw {#2} {#3} {#4} #1 }
+\cs_generate_variant:Nn \@@_change_case_replace:nnnn { v }
+% \end{macrocode}
+% Allow for manually-controlled case switching.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_switch:nnnN #1#2#3#4
+ {
+ \cs_if_eq:NNTF #4 \text_case_switch:nnnn
+ { \use:c { @@_change_case_switch_ #1 :nnnNnnnn } }
+ { \use:c { @@_change_case_letterlike_ #1 :nnnN } }
+ {#1} {#2} {#3} #4
+ }
+\cs_new:Npn \@@_change_case_switch_lower:nnnNnnnn #1#2#3#4#5#6#7#8
+ {
+ \@@_change_case_store:n {#7}
+ \@@_change_case_loop:nnnw {#1} {#2} {#3}
+ }
+\cs_new:Npn \@@_change_case_switch_upper:nnnNnnnn #1#2#3#4#5#6#7#8
+ {
+ \@@_change_case_store:n {#6}
+ \@@_change_case_loop:nnnw {#1} {#2} {#3}
+ }
+\cs_new:Npn \@@_change_case_switch_title:nnnNnnnn #1#2#3#4#5#6#7#8
+ {
+ \@@_change_case_store:n {#8}
+ \@@_change_case_skip:nnw {#2} {#3}
+ }
+% \end{macrocode}
+% Skip over material quickly after titlecase-first-only initials
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_skip:nnw #1#2#3 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#3}
+ { \@@_change_case_skip_N_type:nnN }
+ {
+ \tl_if_head_is_group:nTF {#3}
+ { \@@_change_case_skip_group:nnn }
+ { \@@_change_case_skip_space:nnw }
+ }
+ {#1} {#2} #3 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_change_case_skip_N_type:nnN #1#2#3
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #3
+ { \@@_change_case_end:w }
+ \@@_change_case_store:n {#3}
+ \@@_change_case_skip:nnw {#1} {#2}
+ }
+\cs_new:Npn \@@_change_case_skip_group:nnn #1#2#3
+ {
+ \@@_change_case_store:n { {#3} }
+ \@@_change_case_skip:nnw {#1} {#2}
+ }
+\cs_new:Npn \@@_change_case_skip_space:nnw #1#2
+ { \@@_change_case_space:nnnw {#1} {#1} {#2} }
+% \end{macrocode}
+% Letter-like commands may still be present: they are set up using a simple
+% lookup approach, so can easily be handled with no loop. If there is no
+% hit, we are at the end of the process: we loop around. Letter-like chars
+% are all available only in upper- and lowercase, so titlecasing maps to the
+% uppercase version.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_letterlike_lower:nnnN #1#2#3#4
+ { \@@_change_case_letterlike:nnnnnN {#1} {#1} {#1} {#2} {#3} #4 }
+\cs_new_eq:NN \@@_change_case_letterlike_upper:nnnN
+ \@@_change_case_letterlike_lower:nnnN
+\cs_new:Npn \@@_change_case_letterlike_title:nnnN #1#2#3#4
+ { \@@_change_case_letterlike:nnnnnN { upper } { end } {#1} {#2} {#3} #4 }
+\cs_new:Npn \@@_change_case_letterlike:nnnnnN #1#2#3#4#5#6
+ {
+ \cs_if_exist:cTF { c_@@_ #1 case_ \token_to_str:N #6 _tl }
+ {
+ \@@_change_case_store:v
+ { c_@@_ #1 case_ \token_to_str:N #6 _tl }
+ \use:c { @@_change_case_next_ #2 :nnn } {#2} {#4} {#5}
+ }
+ {
+ \@@_change_case_store:n {#6}
+ \cs_if_exist:cTF
+ {
+ c_@@_
+ \str_if_eq:nnTF {#1} { lower } { upper } { lower }
+ case_ \token_to_str:N #6 _tl
+ }
+ { \use:c { @@_change_case_next_ #2 :nnn } {#2} {#4} {#5} }
+ { \@@_change_case_loop:nnnw {#3} {#4} {#5} }
+ }
+ }
+% \end{macrocode}
+% Check for a customised codepoint result.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_custom_lower:nnnn #1#2#3#4
+ {
+ \@@_change_case_custom:nnnnnn {#1} {#1} {#2} {#3} {#4}
+ { \use:c { @@_change_case_codepoint_ #1 :nnnn } {#1} {#2} {#3} {#4} }
+ }
+\cs_new_eq:NN \@@_change_case_custom_upper:nnnn
+ \@@_change_case_custom_lower:nnnn
+\cs_new:Npn \@@_change_case_custom_title:nnnn #1#2#3#4
+ {
+ \@@_change_case_custom:nnnnnn { title } {#1} {#2} {#3} {#4}
+ {
+ \@@_change_case_custom:nnnnnn { upper } {#1} {#2} {#3} {#4}
+ { \use:c { @@_change_case_codepoint_ #1 :nnnn } {#1} {#2} {#3} {#4} }
+ }
+ }
+\cs_new:Npn \@@_change_case_custom:nnnnnn #1#2#3#4#5#6
+ {
+ \tl_if_exist:cTF { l_@@_ #1 case _ \tl_to_str:n {#5} _ #4 _tl }
+ {
+ \@@_change_case_replace:vnnn
+ { l_@@_ #1 case _ \tl_to_str:n {#5} _ #4 _tl } {#2} {#3} {#4}
+ }
+ {
+ \tl_if_exist:cTF { l_@@_ #1 case _ \tl_to_str:n {#5} _tl }
+ {
+ \@@_change_case_replace:vnnn
+ { l_@@_ #1 case _ \tl_to_str:n {#5} _tl } {#2} {#3} {#4}
+ }
+ {#6}
+ }
+ }
+% \end{macrocode}
+% For upper- and lowercase changes, once we get to this stage there are only
+% a couple of questions remaining: is there a language-specific mapping and
+% is there the special case of a terminal sigma. If not, then we pass to
+% a simple codepoint mapping.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_codepoint_lower:nnnn #1#2#3#4
+ {
+ \cs_if_exist_use:cF { @@_change_case_lower_ #3 :nnnnn }
+ { \@@_change_case_lower_sigma:nnnnn }
+ {#1} {#1} {#2} {#3} {#4}
+ }
+\cs_new:Npn \@@_change_case_codepoint_upper:nnnn #1#2#3#4
+ {
+ \cs_if_exist_use:cF { @@_change_case_upper_ #3 :nnnnn }
+ { \@@_change_case_codepoint:nnnnn }
+ {#1} {#1} {#2} {#3} {#4}
+ }
+% \end{macrocode}
+% If the current character is an uppercase sigma, the a check is made on the
+% next item in the input. If it is \texttt{N}-type and not a control sequence
+% then there is a look-ahead phase: the logic here is simply based on letters
+% or actives (to cover $8$-bit engines).
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_lower_sigma:nnnnn #1#2#3#4#5
+ {
+ \@@_codepoint_compare:nNnTF {#5} = { "03A3 }
+ { \@@_change_case_lower_sigma:nnnnw {#2} }
+ { \@@_change_case_codepoint:nnnnn {#1} {#2} }
+ {#3} {#4} {#5}
+ }
+\cs_new:Npn \@@_change_case_lower_sigma:nnnnw #1#2#3#4#5 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#5}
+ { \@@_change_case_lower_sigma:nnnnN {#4} }
+ {
+ \@@_change_case_store:e
+ { \codepoint_generate:nn { "03C2 } { \@@_char_catcode:N #4 } }
+ \@@_change_case_loop:nnnw
+ }
+ {#1} {#2} {#3} #5 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_change_case_lower_sigma:nnnnN #1#2#3#4#5
+ {
+ \@@_change_case_store:e
+ {
+ \bool_lazy_or:nnTF
+ { \token_if_letter_p:N #5 }
+ {
+ \bool_lazy_and_p:nn
+ { \token_if_active_p:N #5 }
+ { \int_compare_p:nNn {`#5} > { "80 } }
+ }
+ { \codepoint_generate:nn { "03C3 } { \@@_char_catcode:N #1 } }
+ { \codepoint_generate:nn { "03C2 } { \@@_char_catcode:N #1 } }
+ }
+ \@@_change_case_loop:nnnw {#2} {#3} {#4} #5
+ }
+% \end{macrocode}
+% For titlecasing, we need to obtain the general category of the current
+% codepoint.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_codepoint_title:nnnn #1#2#3#4
+ {
+ \bool_if:NTF \l_text_titlecase_check_letter_bool
+ {
+ \exp_args:Ne \@@_change_case_codepoint_title_auxi:nnnn
+ {
+ \codepoint_to_category:n
+ { \@@_codepoint_from_chars:Nw #4 }
+ }
+ }
+ { \@@_change_case_codepoint_title:nnn }
+ {#2} {#3} {#4}
+ }
+\cs_new:Npn \@@_change_case_codepoint_title_auxi:nnnn #1#2#3#4
+ {
+ \tl_if_head_eq_charcode:nNTF {#1} { L }
+ { \@@_change_case_codepoint_title:nnn }
+ { \@@_change_case_codepoint_title_auxii:nnnn { title } }
+ {#2} {#3} {#4}
+ }
+\cs_new:Npn \@@_change_case_codepoint_title:nnn #1#2#3
+ { \@@_change_case_codepoint_title_auxii:nnnn { end } {#1} {#2} {#3} }
+\cs_new:Npn \@@_change_case_codepoint_title_auxii:nnnn #1#2#3#4
+ {
+ \cs_if_exist_use:cF { @@_change_case_title_ #3 :nnnnn }
+ {
+ \cs_if_exist_use:cF { @@_change_case_upper_ #3 :nnnnn }
+ { \@@_change_case_codepoint:nnnnn }
+ }
+ { title } {#1} {#2} {#3} {#4}
+ }
+\cs_new:Npn \@@_change_case_codepoint:nnnnn #1#2#3#4#5
+ {
+ \bool_lazy_and:nnTF
+ { \tl_if_single_p:n {#5} }
+ { \token_if_active_p:N #5 }
+ { \@@_change_case_store:n {#5} }
+ {
+ \@@_change_case_store:e
+ { \@@_change_case_codepoint:nn {#1} {#5} }
+ }
+ \use:c { @@_change_case_next_ #2 :nnn } {#2} {#3} {#4}
+ }
+\cs_new:Npn \@@_change_case_codepoint:nn #1#2
+ {
+ \@@_change_case_codepoint:fnn
+ { \int_eval:n { \@@_codepoint_from_chars:Nw #2 } } {#1} {#2}
+ }
+\cs_new:Npn \@@_change_case_codepoint:nnn #1#2#3
+ {
+ \exp_args:Ne \@@_change_case_codepoint_aux:nn
+ { \__kernel_codepoint_case:nn { #2 case } {#1} } {#3}
+ }
+\cs_generate_variant:Nn \@@_change_case_codepoint:nnn { f }
+% \end{macrocode}
+% Avoid high chars with p\TeX{}.
+% \begin{macrocode}
+\sys_if_engine_ptex:T
+ {
+ \cs_new_eq:NN \@@_change_case_codepoint_aux:nnn
+ \@@_change_case_codepoint:nnn
+ \cs_gset:Npn \@@_change_case_codepoint:nnn #1#2#3
+ {
+ \int_compare:nNnTF {#1} = { -1 }
+ { \exp_not:n {#3} }
+ { \@@_change_case_codepoint_aux:nnn {#1} {#2} {#3} }
+ }
+ }
+\cs_new:Npn \@@_change_case_codepoint_aux:nn #1#2
+ {
+ \use:e { \@@_change_case_codepoint_aux:nnnn #1 {#2} }
+ }
+\cs_new:Npn \@@_change_case_codepoint_aux:nnnn #1#2#3#4
+ {
+ \@@_codepoint_compare:nNnTF {#4} = {#1}
+ { \exp_not:n {#4} }
+ {
+ \codepoint_generate:nn {#1}
+ { \@@_change_case_catcode:nn {#4} {#1} }
+ \tl_if_blank:nF {#2}
+ {
+ \codepoint_generate:nn {#2}
+ { \char_value_catcode:n {#2} }
+ \tl_if_blank:nF {#3}
+ {
+ \codepoint_generate:nn {#3}
+ { \char_value_catcode:n {#3} }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% We need to ensure that only valid catcode-extraction is attempted. That's
+% fine with Unicode engines but needs a bit of work with 8-bit ones. The
+% logic is that if the original codepoint was in the ASCII range, we keep
+% the catcode. Otherwise, if the target is in the ASCII range, we use
+% the standard catcode. If neither are true, we set as 13 on the grounds that
+% this will be what is used anyway!
+% \begin{macrocode}
+\bool_lazy_or:nnTF
+ { \sys_if_engine_luatex_p: }
+ { \sys_if_engine_xetex_p: }
+ {
+ \cs_new:Npn \@@_change_case_catcode:nn #1#2
+ { \@@_char_catcode:N #1 }
+ }
+ {
+ \cs_new:Npn \@@_change_case_catcode:nn #1#2
+ {
+ \@@_codepoint_compare:nNnTF {#1} < { "80 }
+ { \@@_char_catcode:N #1 }
+ {
+ \int_compare:nNnTF {#2} < { "80 }
+ { \char_value_catcode:n {#2} }
+ { 13 }
+ }
+ }
+ }
+\cs_new:Npn \@@_change_case_next_lower:nnn #1#2#3
+ { \@@_change_case_loop:nnnw {#1} {#2} {#3} }
+\cs_new_eq:NN \@@_change_case_next_upper:nnn
+ \@@_change_case_next_lower:nnn
+\cs_new_eq:NN \@@_change_case_next_title:nnn
+ \@@_change_case_next_lower:nnn
+\cs_new:Npn \@@_change_case_next_end:nnn #1#2#3
+ { \@@_change_case_skip:nnw {#2} {#3} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\text_declare_case_equivalent:Nn}
+% Create equivalents to allow replacement.
+% \begin{macrocode}
+\cs_new_protected:Npn \text_declare_case_equivalent:Nn #1#2
+ {
+ \tl_clear_new:c { l_@@_case_ \token_to_str:N #1 _tl }
+ \tl_set:cn { l_@@_case_ \token_to_str:N #1 _tl } {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \text_declare_lowercase_mapping:nn ,
+% \text_declare_titlecase_mapping:nn ,
+% \text_declare_uppercase_mapping:nn
+% }
+% \begin{macro}
+% {\@@_declare_case_mapping:nnn, \@@_declare_case_mapping_aux:nnn}
+% \begin{macro}
+% {
+% \text_declare_lowercase_mapping:nnn ,
+% \text_declare_titlecase_mapping:nnn ,
+% \text_declare_uppercase_mapping:nnn
+% }
+% \begin{macro}
+% {\@@_declare_case_mapping:nnnn, \@@_declare_case_mapping_aux:nnnn}
+% Codepoint customisation.
+% \begin{macrocode}
+\cs_new_protected:Npn \text_declare_lowercase_mapping:nn #1#2
+ { \@@_declare_case_mapping:nnn { lower } {#1} {#2} }
+\cs_new_protected:Npn \text_declare_titlecase_mapping:nn #1#2
+ { \@@_declare_case_mapping:nnn { title } {#1} {#2} }
+\cs_new_protected:Npn \text_declare_uppercase_mapping:nn #1#2
+ { \@@_declare_case_mapping:nnn { upper } {#1} {#2} }
+\cs_new_protected:Npn \@@_declare_case_mapping:nnn #1#2#3
+ {
+ \exp_args:Ne \@@_declare_case_mapping_aux:nnn
+ { \codepoint_str_generate:n {#2} } {#1} {#3}
+ }
+\cs_new_protected:Npn \@@_declare_case_mapping_aux:nnn #1#2#3
+ {
+ \tl_clear_new:c { l_@@_ #2 case _ #1 _tl }
+ \tl_set:cn { l_@@_ #2 case _ #1 _ tl } {#3}
+ }
+\cs_new_protected:Npn \text_declare_lowercase_mapping:nnn #1#2#3
+ { \@@_declare_case_mapping:nnnn { lower } {#1} {#2} {#3} }
+\cs_new_protected:Npn \text_declare_titlecase_mapping:nnn #1#2#3
+ { \@@_declare_case_mapping:nnnn { title } {#1} {#2} {#3} }
+\cs_new_protected:Npn \text_declare_uppercase_mapping:nnn #1#2#3
+ { \@@_declare_case_mapping:nnnn { upper } {#1} {#2} {#3} }
+\cs_new_protected:Npn \@@_declare_case_mapping:nnnn #1#2#3#4
+ {
+ \exp_args:Ne \@@_declare_case_mapping_aux:nnnn
+ { \codepoint_str_generate:n {#3} } {#1} {#2} {#4}
+ }
+\cs_new_protected:Npn \@@_declare_case_mapping_aux:nnnn #1#2#3#4
+ {
+ \tl_clear_new:c { l_@@_ #2 case _ #1 _ #3 _tl }
+ \tl_set:cn { l_@@_ #2 case _ #1 _ #3 _ tl } {#4}
+ \tl_clear_new:c { l_@@_ #2 case_special_ #3 _tl }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\text_case_switch:nnnn}
+% \begin{macro}{\@@_case_switch_marker:}
+% Set up the mechanism for manual case switching.
+% \begin{macrocode}
+\cs_new:Npn \text_case_switch:nnnn #1#2#3#4
+ {
+ \@@_case_switch_marker:
+ #1
+ }
+\cs_new:Npn \@@_case_switch_marker: { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_change_case_generate:n}
+% A utility.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_generate:n #1
+ { \codepoint_generate:nn {#1} { \char_value_catcode:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_change_case_upper_de-x-eszett:nnnnn,
+% \@@_change_case_upper_de-alt:nnnnn
+% }
+% A simple alternative version for German.
+% \begin{macrocode}
+\cs_new:cpn { @@_change_case_upper_de-x-eszett:nnnnn } #1#2#3#4#5
+ {
+ \@@_codepoint_compare:nNnTF {#5} = { "00DF }
+ {
+ \@@_change_case_store:e
+ {
+ \codepoint_generate:nn { "1E9E }
+ { \@@_change_case_catcode:nn {#5} { "1E9E } }
+ }
+ \use:c { @@_change_case_next_ #2 :nnn }
+ {#2} {#3} {#4}
+ }
+ { \@@_change_case_codepoint:nnnnn {#1} {#2} {#3} {#4} {#5} }
+ }
+\cs_new_eq:cc { @@_change_case_upper_de-alt:nnnnn }
+ { @@_change_case_upper_de-x-eszett:nnnnn }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_change_case_upper_el:nnnnn ,
+% \@@_change_case_upper_el-x-iota:nnnnn ,
+% \@@_change_case_upper_el_aux:nnnnn
+% }
+% \begin{macro}[EXP]{\@@_change_case_upper_el:nnnn}
+% \begin{macro}[EXP]{\@@_change_case_upper_el:nnnnw}
+% \begin{macro}[EXP]
+% {\@@_change_case_upper_el:nnnnN, \@@_change_case_upper_el_aux:nnnnN}
+% \begin{macro}[EXP]{\@@_change_case_upper_el_ypogegrammeni:nnnnnnw}
+% \begin{macro}[EXP]{\@@_change_case_upper_el_ypogegrammeni:nnnnnnN}
+% \begin{macro}[EXP]{\@@_change_case_upper_el_ypogegrammeni:nnnnnnn}
+% \begin{macro}[EXP]{\@@_change_case_upper_el_dialytika:nnnn}
+% \begin{macro}[EXP]{\@@_change_case_upper_el_dialytika:n}
+% \begin{macro}[EXP]{\@@_change_case_upper_el_hiatus:nnnnw}
+% \begin{macro}[EXP]{\@@_change_case_upper_el_hiatus:nnnnN}
+% \begin{macro}[EXP]{\@@_change_case_upper_el_hiatus:nnnnn}
+% \begin{macro}[EXP]
+% {
+% \@@_change_case_upper_el_ypogegrammeni:n ,
+% \@@_change_case_upper_el-x-iota_ypogegrammeni:n
+% }
+% \begin{macro}[EXP]{\@@_change_case_upper_el_stress:nn}
+% \begin{macro}[EXP]{\@@_change_case_upper_el_gobble:nnnw}
+% \begin{macro}[EXP]{\@@_change_case_upper_el_gobble:nnnN}
+% \begin{macro}[EXP]{\@@_change_case_upper_el_gobble:nnnn}
+% \begin{macro}[EXP,noTF]
+% {
+% \@@_change_case_if_greek:n ,
+% \@@_change_case_if_greek_spacing_diacritic:n ,
+% \@@_change_case_if_greek_accent:n ,
+% \@@_change_case_if_greek_breathing:n ,
+% \@@_change_case_if_greek_stress:n ,
+% \@@_change_case_if_takes_dialytika:n ,
+% \@@_change_case_if_takes_ypogegrammeni:n
+% }
+% For Greek uppercasing, we need to know if characters \emph{in the Greek
+% range} have accents. That means doing a \textsc{nfd} conversion first, then
+% starting a search. As described by the Unicode \textsc{cldr}, Greek accents
+% need to be found \emph{after} any U+0308 (diaeresis) and are done in two
+% groups to allow for the canonical ordering. The implementation here follows
+% the data and examples from \textsc{icu}
+% (\url{https://icu.unicode.org/design/case/greek-upper}),
+% although necessarily the implementation is somewhat different. The
+% \emph{ypogegrammeni} is filtered out here as it is not actually in the
+% Greek range, so gets lost if we leave until later. The one Greek codepoint
+% we skip is the numeral sign and question mark: the first has an awkward NFD
+% for \pdfTeX{} so is best left unchanged, and the latter has issues concerning
+% how \texttt{LGR} outputs the input and output (differently!).
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_upper_el:nnnnn #1#2#3#4#5
+ {
+ \bool_lazy_and:nnTF
+ { \@@_change_case_if_greek_p:n {#5} }
+ {
+ ! \bool_lazy_or_p:nn
+ { \@@_codepoint_compare_p:nNn {#5} = { "0374 } }
+ { \@@_codepoint_compare_p:nNn {#5} = { "037E } }
+ }
+ {
+ \@@_change_case_if_greek_spacing_diacritic:nTF {#5}
+ {
+ \@@_change_case_store:n {#5}
+ \@@_change_case_loop:nnnw
+ }
+ {
+ \exp_args:Ne \@@_change_case_upper_el:nnnn
+ {
+ \codepoint_to_nfd:n
+ { \@@_codepoint_from_chars:Nw #5 }
+ }
+ }
+ {#2} {#3} {#4}
+ }
+ {
+ \@@_codepoint_compare:nNnTF {#5} = { "0345 }
+ {
+ \@@_change_case_store:e
+ {
+ \codepoint_generate:nn { "0399 }
+ { \char_value_catcode:n { "0399 } }
+ }
+ \@@_change_case_loop:nnnw {#2} {#3} {#4}
+ }
+ { \@@_change_case_codepoint:nnnnn {#1} {#2} {#3} {#4} {#5} }
+ }
+ }
+\cs_new_eq:cN { @@_change_case_upper_el-x-iota:nnnnn }
+ \@@_change_case_upper_el:nnnnn
+\cs_new:Npn \@@_change_case_upper_el:nnnn #1#2#3#4
+ {
+ \@@_codepoint_process:nN
+ { \@@_change_case_upper_el:nnnnw {#2} {#3} {#4} } #1
+ }
+% \end{macrocode}
+% At this stage we have the first NFD codepoint as |#3|. What we need to know
+% is whether after that we have another character, either from the NFD or
+% directly in the input. If not, we store the changed character at this stage.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_upper_el:nnnnw #1#2#3#4#5 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#5}
+ { \@@_change_case_upper_el:nnnnN {#4} }
+ {
+ \@@_change_case_store:e
+ { \@@_change_case_codepoint:nn { upper } {#4} }
+ \@@_change_case_loop:nnnw
+ }
+ {#1} {#2} {#3} #5 \q_@@_recursion_stop
+ }
+% \end{macrocode}
+% Now, we check the detail of the next codepoint: again we filter out the
+% not-a-char cases, before checking if it's an dialytika, accent or diacritic.
+% (The latter do not have the same hiatus behavior as accents.) There is
+% additional work if the codepoint can take a ypogegrammeni: there, we need
+% to move any ypogegrammeni to after accents (in case the input is not
+% normalised). The ypogegrammeni itself is handled separately.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_upper_el:nnnnN #1#2#3#4#5
+ {
+ \token_if_cs:NTF #5
+ {
+ \@@_change_case_store:e
+ { \@@_change_case_codepoint:nn { upper } {#1} }
+ \@@_change_case_loop:nnnw {#2} {#3} {#4} #5
+ }
+ {
+ \@@_change_case_if_takes_ypogegrammeni:nTF {#1}
+ {
+ \@@_change_case_upper_el_ypogegrammeni:nnnnnnw
+ {#1} {#2} {#3} {#4} { } { } #5
+ }
+ { \@@_change_case_upper_el_aux:nnnnN {#1} {#2} {#3} {#4} #5 }
+ }
+ }
+\cs_new:Npn \@@_change_case_upper_el_ypogegrammeni:nnnnnnw
+ #1#2#3#4#5#6#7 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#7}
+ {
+ \@@_change_case_upper_el_ypogegrammeni:nnnnnnN
+ {#1} {#2} {#3} {#4} {#5} {#6}
+ }
+ { \@@_change_case_upper_el_aux:nnnnN {#1} {#2} {#3} {#4} #5#6 }
+ #7 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_change_case_upper_el_ypogegrammeni:nnnnnnN #1#2#3#4#5#6#7
+ {
+ \token_if_cs:NTF #7
+ { \@@_change_case_upper_el_aux:nnnnN {#1} {#2} {#3} {#4} #5#6 }
+ {
+ \@@_codepoint_process:nN
+ {
+ \@@_change_case_upper_el_ypogegrammeni:nnnnnnn
+ {#1} {#2} {#3} {#4} {#5} {#6}
+ }
+ }
+ #7
+ }
+\cs_new:Npn \@@_change_case_upper_el_ypogegrammeni:nnnnnnn #1#2#3#4#5#6#7
+ {
+ \@@_codepoint_compare:nNnTF {#7} = { "0345 }
+ {
+ \@@_change_case_upper_el_ypogegrammeni:nnnnnnw
+ {#1} {#2} {#3} {#4} {#5} {#7}
+ }
+ {
+ \bool_lazy_or:nnTF
+ { \@@_change_case_if_greek_accent_p:n {#7} }
+ { \@@_change_case_if_greek_breathing_p:n {#7} }
+ {
+ \@@_change_case_upper_el_ypogegrammeni:nnnnnnw
+ {#1} {#2} {#3} {#4} {#5#7} {#6}
+ }
+ { \@@_change_case_upper_el_aux:nnnnN {#1} {#2} {#3} {#4} #5#6 #7 }
+ }
+ }
+\cs_new:Npn \@@_change_case_upper_el_aux:nnnnN #1#2#3#4#5
+ {
+ \@@_codepoint_process:nN
+ { \@@_change_case_upper_el_aux:nnnnn {#1} {#2} {#3} {#4} } #5
+ }
+\cs_new:Npn \@@_change_case_upper_el_aux:nnnnn #1#2#3#4#5
+ {
+ \@@_codepoint_compare:nNnTF {#5} = { "0308 }
+ { \@@_change_case_upper_el_dialytika:nnnn {#2} {#3} {#4} {#1} }
+ {
+ \@@_change_case_if_greek_accent:nTF {#5}
+ { \@@_change_case_upper_el_hiatus:nnnnw {#2} {#3} {#4} {#1} }
+ {
+ \@@_change_case_if_greek_breathing:nTF {#5}
+ { \@@_change_case_upper_el:nnnn {#1} {#2} {#3} {#4} }
+ {
+ \@@_codepoint_compare:nNnTF {#5} = { "0345 }
+ {
+ \@@_change_case_store:e
+ { \use:c { @@_change_case_upper_ #4 _ypogegrammeni:n } {#1} }
+ \@@_change_case_loop:nnnw {#2} {#3} {#4}
+ }
+ {
+ \@@_change_case_if_greek_stress:nTF {#5}
+ {
+ \@@_change_case_store:e
+ { \@@_change_case_upper_el_stress:nn {#1} {#5} }
+ \@@_change_case_loop:nnnw {#2} {#3} {#4}
+
+ }
+ {
+ \@@_change_case_store:e
+ { \@@_change_case_codepoint:nn { upper } {#1} }
+ \@@_change_case_loop:nnnw {#2} {#3} {#4} #5
+ }
+ }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% We handle \emph{dialytika} in parts as it's also needed for the hiatus.
+% We know only two letters take it, so we can shortcut here on the second
+% part of the tests.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_upper_el_dialytika:nnnn #1#2#3#4
+ {
+ \@@_change_case_if_takes_dialytika:nTF {#4}
+ { \@@_change_case_upper_el_dialytika:n {#4} }
+ {
+ \@@_change_case_store:e
+ { \@@_change_case_codepoint:nn { upper } {#4} }
+ }
+ \@@_change_case_upper_el_gobble:nnnw {#1} {#2} {#3}
+ }
+\cs_new:Npn \@@_change_case_upper_el_dialytika:n #1
+ {
+ \@@_change_case_store:e
+ {
+ \bool_lazy_or:nnTF
+ { \@@_codepoint_compare_p:nNn {#1} = { "0399 } }
+ { \@@_codepoint_compare_p:nNn {#1} = { "03B9 } }
+ {
+ \codepoint_generate:nn { "03AA }
+ { \@@_change_case_catcode:nn {#1} { "03AA } }
+ }
+ {
+ \codepoint_generate:nn { "03AB }
+ { \@@_change_case_catcode:nn {#1} { "03AB } }
+ }
+ }
+ }
+% \end{macrocode}
+% Adding a hiatus needs some of the same ideas, but if there is not one we
+% skip this code point, hence needing a separate function.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_upper_el_hiatus:nnnnw
+ #1#2#3#4#5 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#5}
+ { \@@_change_case_upper_el_hiatus:nnnnN {#4} }
+ {
+ \@@_change_case_store:e
+ { \@@_change_case_codepoint:nn { upper } {#4} }
+ \@@_change_case_loop:nnnw
+ }
+ {#1} {#2} {#3} #5 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_change_case_upper_el_hiatus:nnnnN #1#2#3#4#5
+ {
+ \token_if_cs:NTF #5
+ {
+ \@@_change_case_store:e
+ { \@@_change_case_codepoint:nn { upper } {#1} }
+ \@@_change_case_loop:nnnw {#2} {#3} {#4} #5
+ }
+ {
+ \@@_codepoint_process:nN
+ { \@@_change_case_upper_el_hiatus:nnnnn {#1} {#2} {#3} {#4} } #5
+ }
+ }
+\cs_new:Npn \@@_change_case_upper_el_hiatus:nnnnn #1#2#3#4#5
+ {
+ \@@_change_case_if_takes_dialytika:nTF {#5}
+ {
+ \@@_change_case_store:e
+ { \@@_change_case_codepoint:nn { upper } {#1} }
+ \@@_change_case_upper_el_dialytika:n {#5}
+ \@@_change_case_upper_el_gobble:nnnw {#2} {#3} {#4}
+ }
+ { \@@_change_case_upper_el:nnnn {#1} {#2} {#3} {#4} #5 }
+ }
+% \end{macrocode}
+% Handling the \emph{ypogegrammeni} output depends on the selected approach
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_upper_el_ypogegrammeni:n #1
+ {
+ \exp_args:Ne \@@_change_case_generate:n
+ {
+ \int_case:nn
+ { \@@_codepoint_from_chars:Nw #1 }
+ {
+ { "0391 } { "1FBC }
+ { "03B1 } { "1FBC }
+ { "0397 } { "1FCC }
+ { "03B7 } { "1FCC }
+ { "03A9 } { "1FFC }
+ { "03C9 } { "1FFC }
+ }
+ }
+ }
+\cs_new:cpn { @@_change_case_upper_el-x-iota_ypogegrammeni:n } #1
+ {
+ \@@_change_case_codepoint:nn { upper } {#1}
+ \codepoint_generate:nn { "0399 }
+ { \char_value_catcode:n { "0399 } }
+ }
+% \end{macrocode}
+% We choose to retain stress diacritics, but we also need to recombine
+% them for pdf\TeX{}. That is handled here.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_upper_el_stress:nn #1#2
+ {
+ \exp_args:Ne \@@_change_case_generate:n
+ {
+ \int_case:nn
+ { \@@_codepoint_from_chars:Nw #2 }
+ {
+ { "0304 }
+ {
+ \int_case:nn { \@@_codepoint_from_chars:Nw #1 }
+ {
+ { "0391 } { "1FB9 }
+ { "03B1 } { "1FB9 }
+ { "0399 } { "1FD9 }
+ { "03B9 } { "1FD9 }
+ { "03A5 } { "1FE9 }
+ { "03C5 } { "1FE9 }
+ }
+ }
+ { "0306 }
+ {
+ \int_case:nn { \@@_codepoint_from_chars:Nw #1 }
+ {
+ { "0391 } { "1FB8 }
+ { "03B1 } { "1FB8 }
+ { "0399 } { "1FD8 }
+ { "03B9 } { "1FD8 }
+ { "03A5 } { "1FE8 }
+ { "03C5 } { "1FE8 }
+ }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% For clearing out trailing combining marks after we have dealt with
+% the first one.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_upper_el_gobble:nnnw
+ #1#2#3#4 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#4}
+ { \@@_change_case_upper_el_gobble:nnnN }
+ { \@@_change_case_loop:nnnw }
+ {#1} {#2} {#3} #4 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_change_case_upper_el_gobble:nnnN #1#2#3#4
+ {
+ \token_if_cs:NTF #4
+ { \@@_change_case_loop:nnnw {#1} {#2} {#3} }
+ {
+ \@@_codepoint_process:nN
+ { \@@_change_case_upper_el_gobble:nnnn {#1} {#2} {#3} }
+ }
+ #4
+ }
+\cs_new:Npn \@@_change_case_upper_el_gobble:nnnn #1#2#3#4
+ {
+ \bool_lazy_or:nnTF
+ { \@@_change_case_if_greek_accent_p:n {#4} }
+ { \@@_change_case_if_greek_breathing_p:n {#4} }
+ { \@@_change_case_upper_el_gobble:nnnw {#1} {#2} {#3} }
+ { \@@_change_case_loop:nnnw {#1} {#2} {#3} #4 }
+ }
+% \end{macrocode}
+% Luckily the Greek range is limited and clear.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_change_case_if_greek:n #1 { p , TF }
+ {
+ \exp_args:Nf \@@_change_case_if_greek:n
+ { \int_eval:n { \@@_codepoint_from_chars:Nw #1 } }
+ }
+\cs_new:Npn \@@_change_case_if_greek:n #1
+ {
+ \if_int_compare:w #1 < "0370 \exp_stop_f:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w #1 > "03FF \exp_stop_f:
+ \if_int_compare:w #1 < "1F00 \exp_stop_f:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w #1 > "1FFF \exp_stop_f:
+ \if_int_compare:w #1 = "2126 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ \else:
+ \prg_return_true:
+ \fi:
+ \fi:
+ \else:
+ \prg_return_true:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% We follow ICU in adding a few extras to the accent list here.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_change_case_if_greek_accent:n #1 { TF , p }
+ {
+ \exp_args:Nf \@@_change_case_if_greek_accent:n
+ { \int_eval:n { \@@_codepoint_from_chars:Nw #1 } }
+ }
+\cs_new:Npn \@@_change_case_if_greek_accent:n #1
+ {
+ \if_int_compare:w #1 = "0300 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "0301 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "0342 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "0302 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "0303 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "0311 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ }
+\prg_new_conditional:Npnn \@@_change_case_if_greek_spacing_diacritic:n
+ #1 { TF }
+ {
+ \exp_args:Nf \@@_change_case_if_greek_spacing_diacritic:n
+ { \int_eval:n { \@@_codepoint_from_chars:Nw #1 } }
+ }
+\cs_new:Npn \@@_change_case_if_greek_spacing_diacritic:n #1
+ {
+ \if_int_compare:w #1 < "1FBD \exp_stop_f:
+ \if_int_compare:w #1 = "037A \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ \else:
+ \if_int_compare:w #1 = "1FBD \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "1FBF \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "1FC0 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "1FC1 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "1FCD \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "1FCE \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "1FCF \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "1FDD \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "1FDE \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "1FDF \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "1FED \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "1FEE \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "1FEF \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "1FFD \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "1FFE \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ }
+\prg_new_conditional:Npnn \@@_change_case_if_greek_breathing:n
+ #1 { TF , p }
+ {
+ \exp_args:Nf \@@_change_case_if_greek_breathing:n
+ { \int_eval:n { \@@_codepoint_from_chars:Nw #1 } }
+ }
+\cs_new:Npn \@@_change_case_if_greek_breathing:n #1
+ {
+ \if_int_compare:w #1 = "0313 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "0314 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ \fi:
+ }
+\prg_new_conditional:Npnn \@@_change_case_if_greek_stress:n
+ #1 { TF , p }
+ {
+ \exp_args:Nf \@@_change_case_if_greek_stress:n
+ { \int_eval:n { \@@_codepoint_from_chars:Nw #1 } }
+ }
+\cs_new:Npn \@@_change_case_if_greek_stress:n #1
+ {
+ \if_int_compare:w #1 = "0304 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "0306 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ \fi:
+ }
+\prg_new_conditional:Npnn \@@_change_case_if_takes_dialytika:n #1 { TF }
+ {
+ \exp_args:Nf \@@_change_case_if_takes_dialytika:n
+ { \int_eval:n { \@@_codepoint_from_chars:Nw #1 } }
+ }
+\cs_new:Npn \@@_change_case_if_takes_dialytika:n #1
+ {
+ \if_int_compare:w #1 = "0399 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "03B9 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "03A5 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "03C5 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ }
+\prg_new_conditional:Npnn \@@_change_case_if_takes_ypogegrammeni:n #1 { TF }
+ {
+ \exp_args:Nf \@@_change_case_if_takes_ypogegrammeni:n
+ { \int_eval:n { \@@_codepoint_from_chars:Nw #1 } }
+ }
+\cs_new:Npn \@@_change_case_if_takes_ypogegrammeni:n #1
+ {
+ \if_int_compare:w #1 = "03B1 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "03B7 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w #1 = "03C9 \exp_stop_f:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}[EXP]
+% {
+% \@@_change_case_boundary_upper_el:Nnnnw,
+% \@@_change_case_boundary_upper_el-x-iota:Nnnnw
+% }
+% \begin{macro}[EXP]{\@@_change_case_boundary_upper_el:nnnN}
+% \begin{macro}[EXP]{\@@_change_case_boundary_upper_el:nnnn}
+% \begin{macro}[EXP]{\@@_change_case_boundary_upper_el:nnnnw}
+% There is one things that need special treatment at the start of
+% words in Greek. For an isolated accent \emph{eta},
+% which is handled by seeing if we have exactly one of the affected
+% codepoints followed by a space or brace group.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_boundary_upper_el:Nnnnw
+ #1#2#3#4#5 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#5}
+ { \@@_change_case_boundary_upper_el:nnnN }
+ { \@@_change_case_loop:nnnw }
+ {#2} {#3} {#4} #5 \q_@@_recursion_stop
+ }
+\cs_new_eq:cN { @@_change_case_boundary_upper_el-x-iota:Nnnnw }
+ \@@_change_case_boundary_upper_el:Nnnnw
+\cs_new:Npn \@@_change_case_boundary_upper_el:nnnN #1#2#3#4
+ {
+ \token_if_cs:NTF #4
+ { \@@_change_case_loop:nnnw {#1} {#2} {#3} }
+ {
+ \@@_codepoint_process:nN
+ { \@@_change_case_boundary_upper_el:nnnn {#1} {#2} {#3} }
+ }
+ #4
+ }
+\cs_new:Npn \@@_change_case_boundary_upper_el:nnnn #1#2#3#4
+ {
+ \bool_lazy_any:nTF
+ {
+ { \@@_codepoint_compare_p:nNn {#4} = { "0389 } }
+ { \@@_codepoint_compare_p:nNn {#4} = { "03AE } }
+ { \@@_codepoint_compare_p:nNn {#4} = { "1F22 } }
+ { \@@_codepoint_compare_p:nNn {#4} = { "1F2A } }
+ }
+ { \@@_change_case_boundary_upper_el:nnnnw {#1} {#2} {#3} {#4} }
+ { \@@_change_case_breathing:nnnn {#1} {#2} {#3} {#4} }
+ }
+\cs_new:Npn \@@_change_case_boundary_upper_el:nnnnw
+ #1#2#3#4#5 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#5}
+ { \@@_change_case_loop:nnnw {#1} {#2} {#3} #4 }
+ {
+ \@@_change_case_store:e
+ {
+ \codepoint_generate:nn { "0389 }
+ { \@@_change_case_catcode:nn {#4} { "0389 } }
+ }
+ \@@_change_case_loop:nnnw {#1} {#2} {#3}
+ }
+ #5 \q_@@_recursion_stop
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_change_case_breathing:nnnn}
+% \begin{macro}[EXP]{\@@_change_case_breathing:nnnnn}
+% \begin{macro}[EXP]{\@@_change_case_breathing:nnnnnw}
+% \begin{macro}[EXP]{\@@_change_case_breathing:nnnnnnw}
+% \begin{macro}[EXP]{\@@_change_case_breathing_aux:nnnnnn}
+% \begin{macro}[EXP]{\@@_change_case_breathing_aux:nnnnw}
+% \begin{macro}[EXP]{\@@_change_case_breathing_aux:nnnN}
+% \begin{macro}[EXP]{\@@_change_case_breathing_dialytika:nnnn}
+% In Greek, breathing diacritics are normally dropped when uppercasing:
+% see the code for the general case. However, for the first character
+% of a word, if there is a breather \emph{and} the next character takes
+% a \emph{dialytika}, it needs to be added. We start by checking if
+% the current codepoint is in the Greek range, then decomposing.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_breathing:nnnn #1#2#3#4
+ {
+ \@@_change_case_if_greek:nTF {#4}
+ {
+ \exp_args:Ne \@@_change_case_breathing:nnnnn
+ {
+ \codepoint_to_nfd:n
+ { \@@_codepoint_from_chars:Nw #4 }
+ }
+ {#1} {#2} {#3} {#4}
+ }
+ { \@@_change_case_loop:nnnw {#1} {#2} {#3} #4 }
+ }
+\cs_new:Npn \@@_change_case_breathing:nnnnn #1#2#3#4#5
+ {
+ \@@_codepoint_process:nN
+ { \@@_change_case_breathing:nnnnnw {#2} {#3} {#4} {#5} }
+ #1 \q_mark
+ }
+% \end{macrocode}
+% Normal form decomposition will always give between one and three
+% codepoints. Luckily, the two breathing marks (\emph{psili} and
+% \emph{dasia}) will be in a predictable position: last. So we can
+% quickly establish first that there was a change on decomposition,
+% and second if the final resulting codepoint is one of the two we
+% care about.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_breathing:nnnnnw #1#2#3#4#5#6 \q_mark
+ {
+ \tl_if_blank:nTF {#6}
+ { \@@_change_case_loop:nnnw {#1} {#2} {#3} #4 }
+ {
+ \@@_codepoint_process:nN
+ { \@@_change_case_breathing:nnnnnnw {#1} {#2} {#3} {#4} {#5} }
+ #6 \q_mark
+ }
+ }
+\cs_new:Npn \@@_change_case_breathing:nnnnnnw #1#2#3#4#5#6#7 \q_mark
+ {
+ \tl_if_blank:nTF {#7}
+ {
+ \@@_change_case_breathing_aux:nnnnnn
+ {#1} {#2} {#3} {#4} {#5} {#6}
+ }
+ {
+ \@@_codepoint_process:nN
+ { \@@_change_case_breathing:nnnnnnw {#1} {#2} {#3} {#4} {#5} }
+ #7 \q_mark
+ }
+ }
+\cs_new:Npn \@@_change_case_breathing_aux:nnnnnn #1#2#3#4#5#6
+ {
+ \bool_lazy_or:nnTF
+ { \@@_codepoint_compare_p:nNn {#6} = { "0313 } }
+ { \@@_codepoint_compare_p:nNn {#6} = { "0314 } }
+ { \@@_change_case_breathing_aux:nnnnw {#1} {#2} {#3} {#5} }
+ { \@@_change_case_loop:nnnw {#1} {#2} {#3} #4 }
+ }
+% \end{macrocode}
+% Now the lookahead can be fired: check the next codepoint and assess
+% whether it takes a \emph{dialytika}. Drop the
+% breathing mark or generate the \emph{dialytika}: the
+% latter is code shared with the general mechanism.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_breathing_aux:nnnnw #1#2#3#4#5
+ \q_@@_recursion_stop
+ {
+ \@@_change_case_store:e
+ { \@@_change_case_codepoint:nn { upper } {#4} }
+ \tl_if_head_is_N_type:nTF {#5}
+ { \@@_change_case_breathing_aux:nnnN }
+ { \@@_change_case_loop:nnnw }
+ {#1} {#2} {#3} #5 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_change_case_breathing_aux:nnnN #1#2#3#4
+ {
+ \@@_codepoint_process:nN
+ { \@@_change_case_breathing_dialytika:nnnn {#1} {#2} {#3} } #4
+ }
+\cs_new:Npn \@@_change_case_breathing_dialytika:nnnn #1#2#3#4
+ {
+ \@@_change_case_if_takes_dialytika:nTF {#4}
+ {
+ \@@_change_case_upper_el_dialytika:n {#4}
+ \@@_change_case_loop:nnnw {#1} {#2} {#3}
+ }
+ { \@@_change_case_loop:nnnw {#1} {#2} {#3} #4 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_change_case_title_el:nnnnn}
+% Titlecasing retains accents, but to prevent the uppercasing code
+% from kicking in, there has to be an explicit function here.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_title_el:nnnnn #1#2#3#4#5
+ { \@@_change_case_codepoint:nnnnn {#1} {#2} {#3} {#4} {#5} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_change_case_upper_hy:nnnnn ,
+% \@@_change_case_title_hy:nnnnn ,
+% \@@_change_case_upper_hy-x-yiwn:nnnnn ,
+% \@@_change_case_title_hy-x-yiwn:nnnnn
+% }
+% See \url{https://www.unicode.org/L2/L2020/20143-armenian-ech-yiwn.pdf}.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_upper_hy:nnnnn #1#2#3#4#5
+ {
+ \@@_codepoint_compare:nNnTF {#5} = { "0587 }
+ {
+ \@@_change_case_store:e
+ {
+ \codepoint_generate:nn { "0535 }
+ { \@@_change_case_catcode:nn {#5} { "0535 } }
+ \codepoint_generate:nn { "054E }
+ { \@@_change_case_catcode:nn {#5} { "054E } }
+ }
+ \use:c { @@_change_case_next_ #2 :nnn }
+ {#2} {#3} {#4}
+ }
+ { \@@_change_case_codepoint:nnnnn {#1} {#2} {#3} {#4} {#5} }
+ }
+\cs_new:Npn \@@_change_case_title_hy:nnnnn #1#2#3#4#5
+ {
+ \@@_codepoint_compare:nNnTF {#5} = { "0587 }
+ {
+ \@@_change_case_store:e
+ {
+ \codepoint_generate:nn { "0535 }
+ { \@@_change_case_catcode:nn {#5} { "0535 } }
+ \codepoint_generate:nn { "057E }
+ { \@@_change_case_catcode:nn {#5} { "057E } }
+ }
+ \use:c { @@_change_case_next_ #2 :nnn }
+ {#2} {#3} {#4}
+ }
+ { \@@_change_case_codepoint:nnnnn {#1} {#2} {#3} {#4} {#5} }
+ }
+\cs_new:cpn { @@_change_case_upper_hy-x-yiwn:nnnnn } #1#2#3#4#5
+ { \@@_change_case_codepoint:nnnnn {#1} {#2} {#3} {#4} {#5} }
+\cs_new_eq:cc { @@_change_case_title_hy-x-yiwn:nnnnn }
+ { @@_change_case_upper_hy-x-yiwn:nnnnn }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_change_case_lower_la-x-medieval:nnnnn}
+% \begin{macro}[EXP]{\@@_change_case_upper_la-x-medieval:nnnnn}
+% Simply swaps of characters.
+% \begin{macrocode}
+\cs_new:cpn { @@_change_case_lower_la-x-medieval:nnnnn } #1#2#3#4#5
+ {
+ \@@_codepoint_compare:nNnTF {#5} = { "0056 }
+ {
+ \@@_change_case_store:e
+ { \char_generate:nn { "0075 } { \@@_char_catcode:N #5 } }
+ \use:c { @@_change_case_next_ #2 :nnn }
+ {#2} {#3} {#4}
+ }
+ { \@@_change_case_codepoint:nnnnn {#1} {#2} {#3} {#4} {#5} }
+ }
+\cs_new:cpn { @@_change_case_upper_la-x-medieval:nnnnn } #1#2#3#4#5
+ {
+ \@@_codepoint_compare:nNnTF {#5} = { "0075 }
+ {
+ \@@_change_case_store:e
+ { \char_generate:nn { "0056 } { \@@_char_catcode:N #5 } }
+ \use:c { @@_change_case_next_ #2 :nnn }
+ {#2} {#3} {#4}
+ }
+ { \@@_change_case_codepoint:nnnnn {#1} {#2} {#3} {#4} {#5} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_change_cases_lower_lt:nnnnn ,
+% \@@_change_cases_lower_lt_auxi:nnnnn ,
+% \@@_change_cases_lower_lt_auxii:nnnnn
+% }
+% \begin{macro}[rEXP]{\@@_change_case_lower_lt:nnnw}
+% \begin{macro}[rEXP]{\@@_change_case_lower_lt:nnnN}
+% \begin{macro}[rEXP]{\@@_change_case_lower_lt:nnnn}
+% For Lithuanian, the issue to be dealt with is dots over lower case
+% letters: these should be present if there is another accent. The first step
+% is a simple match attempt: look for the three uppercase accented letters
+% which should gain a dot-above char in their lowercase form.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_lower_lt:nnnnn #1#2#3#4#5
+ {
+ \exp_args:Ne \@@_change_case_lower_lt_auxi:nnnnn
+ {
+ \int_case:nn { \@@_codepoint_from_chars:Nw #5 }
+ {
+ { "00CC } { "0300 }
+ { "00CD } { "0301 }
+ { "0128 } { "0303 }
+ }
+ }
+ {#2} {#3} {#4} {#5}
+ }
+% \end{macrocode}
+% If there was a hit, output the result with the dot-above and move on.
+% Otherwise, look for one of the three letters that can take a combining
+% accent: I, J nd I-ogonek.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_lower_lt_auxi:nnnnn #1#2#3#4#5
+ {
+ \tl_if_blank:nTF {#1}
+ {
+ \exp_args:Ne \@@_change_case_lower_lt_auxii:nnnnn
+ {
+ \int_case:nn { \@@_codepoint_from_chars:Nw #5 }
+ {
+ { "0049 } { "0069 }
+ { "004A } { "006A }
+ { "012E } { "012F }
+ }
+ }
+ {#2} {#3} {#4} {#5}
+ }
+ {
+ \@@_change_case_store:e
+ {
+ \codepoint_generate:nn { "0069 }
+ { \@@_change_case_catcode:nn {#5} { "0069 } }
+ \codepoint_generate:nn { "0307 }
+ { \@@_change_case_catcode:nn {#5} { "0307 } }
+ \codepoint_generate:nn {#1}
+ { \@@_change_case_catcode:nn {#5} {#1} }
+ }
+ \@@_change_case_loop:nnnw {#2} {#3} {#4}
+ }
+ }
+% \end{macrocode}
+% Again, branch depending on a hit. If there is one, we output the character
+% then need to look for a combining accent: as usual, we need to be aware of
+% the loop situation.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_lower_lt_auxii:nnnnn #1#2#3#4#5
+ {
+ \tl_if_blank:nTF {#1}
+ { \@@_change_case_codepoint:nnnnn {#2} {#2} {#3} {#4} {#5} }
+ {
+ \@@_change_case_store:e
+ {
+ \codepoint_generate:nn {#1}
+ { \@@_change_case_catcode:nn {#5} {#1} }
+ }
+ \@@_change_case_lower_lt:nnnw {#2} {#3} {#4}
+ }
+ }
+\cs_new:Npn \@@_change_case_lower_lt:nnnw #1#2#3#4 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#4}
+ { \@@_change_case_lower_lt:nnnN }
+ { \@@_change_case_loop:nnnw }
+ {#1} {#2} {#3} #4 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_change_case_lower_lt:nnnN #1#2#3#4
+ {
+ \@@_codepoint_process:nN
+ { \@@_change_case_lower_lt:nnnn {#1} {#2} {#3} } #4
+ }
+\cs_new:Npn \@@_change_case_lower_lt:nnnn #1#2#3#4
+ {
+ \bool_lazy_and:nnT
+ {
+ \bool_lazy_or_p:nn
+ { ! \tl_if_single_p:n {#4} }
+ { ! \token_if_cs_p:N #4 }
+ }
+ {
+ \bool_lazy_any_p:n
+ {
+ { \@@_codepoint_compare_p:nNn {#4} = { "0300 } }
+ { \@@_codepoint_compare_p:nNn {#4} = { "0301 } }
+ { \@@_codepoint_compare_p:nNn {#4} = { "0303 } }
+ }
+ }
+ {
+ \@@_change_case_store:e
+ {
+ \codepoint_generate:nn { "0307 }
+ { \@@_change_case_catcode:nn {#4} { "0307 } }
+ }
+ }
+ \@@_change_case_loop:nnnw {#1} {#2} {#3} #4
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}[EXP]
+% {
+% \@@_change_cases_upper_lt:nnnnn ,
+% \@@_change_cases_upper_lt_aux:nnnnn
+% }
+% \begin{macro}[rEXP]{\@@_change_case_upper_lt:nnnw}
+% \begin{macro}[rEXP]{\@@_change_case_upper_lt:nnnN}
+% \begin{macro}[rEXP]{\@@_change_case_upper_lt:nnnn}
+% The uppercasing version: first find i/j/i-ogonek, then look for the
+% combining char: drop it if present.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_upper_lt:nnnnn #1#2#3#4#5
+ {
+ \exp_args:Ne \@@_change_case_upper_lt_aux:nnnnn
+ {
+ \int_case:nn { \@@_codepoint_from_chars:Nw #5 }
+ {
+ { "0069 } { "0049 }
+ { "006A } { "004A }
+ { "012F } { "012E }
+ }
+ }
+ {#2} {#3} {#4} {#5}
+ }
+\cs_new:Npn \@@_change_case_upper_lt_aux:nnnnn #1#2#3#4#5
+ {
+ \tl_if_blank:nTF {#1}
+ { \@@_change_case_codepoint:nnnnn { upper } {#2} {#3} {#4} {#5} }
+ {
+ \@@_change_case_store:e
+ {
+ \codepoint_generate:nn {#1}
+ { \@@_change_case_catcode:nn {#5} {#1} }
+ }
+ \@@_change_case_upper_lt:nnnw {#2} {#3} {#4}
+ }
+ }
+\cs_new:Npn \@@_change_case_upper_lt:nnnw #1#2#3#4 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#4}
+ { \@@_change_case_upper_lt:nnnN }
+ { \use:c { @@_change_case_next_ #1 :nnn } }
+ {#1} {#2} {#3} #4 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_change_case_upper_lt:nnnN #1#2#3#4
+ {
+ \@@_codepoint_process:nN
+ { \@@_change_case_upper_lt:nnnn {#1} {#2} {#3} } #4
+ }
+\cs_new:Npn \@@_change_case_upper_lt:nnnn #1#2#3#4
+ {
+ \bool_lazy_and:nnTF
+ {
+ \bool_lazy_or_p:nn
+ { ! \tl_if_single_p:n {#4} }
+ { ! \token_if_cs_p:N #4 }
+ }
+ { \@@_codepoint_compare_p:nNn {#4} = { "0307 } }
+ { \use:c { @@_change_case_next_ #1 :nnn } {#1} {#2} {#3} }
+ { \use:c { @@_change_case_next_ #1 :nnn } {#1} {#2} {#3} #4 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_change_case_title_nl:nnnnn, \@@_change_case_title_nl_aux:nnnnn}
+% \begin{macro}[EXP]{\@@_change_case_title_nl:nnnw}
+% \begin{macro}[EXP]{\@@_change_case_title_nl:nnnN}
+% For Dutch, there is a single look-ahead test for \texttt{ij} when
+% title casing. If the appropriate letters are found, produce \texttt{IJ}
+% and gobble the \texttt{j}/\texttt{J}.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_title_nl:nnnnn #1#2#3#4#5
+ {
+ \tl_if_single:nTF {#5}
+ { \@@_change_case_title_nl_aux:nnnnn }
+ { \@@_change_case_codepoint:nnnnn }
+ {#1} {#2} {#3} {#4} {#5}
+ }
+\cs_new:Npn \@@_change_case_title_nl_aux:nnnnn #1#2#3#4#5
+ {
+ \bool_lazy_or:nnTF
+ { \int_compare_p:nNn {`#5} = { "0049 } }
+ { \int_compare_p:nNn {`#5} = { "0069 } }
+ {
+ \@@_change_case_store:e
+ { \char_generate:nn { "0049 } { \@@_char_catcode:N #5 } }
+ \@@_change_case_title_nl:nnnw {#2} {#3} {#4}
+ }
+ { \@@_change_case_codepoint:nnnnn {#1} {#2} {#3} {#4} {#5} }
+ }
+\cs_new:Npn \@@_change_case_title_nl:nnnw #1#2#3#4 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#4}
+ { \@@_change_case_title_nl:nnnN }
+ { \use:c { @@_change_case_next_ #1 :nnn } }
+ {#1} {#2} {#3} #4 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_change_case_title_nl:nnnN #1#2#3#4
+ {
+ \bool_lazy_and:nnTF
+ { ! \token_if_cs_p:N #4 }
+ {
+ \bool_lazy_or_p:nn
+ { \int_compare_p:nNn {`#4} = { "004A } }
+ { \int_compare_p:nNn {`#4} = { "006A } }
+ }
+ {
+ \@@_change_case_store:e
+ { \char_generate:nn { "004A } { \@@_char_catcode:N #4 } }
+ \use:c { @@_change_case_next_ #1 :nnn } {#1} {#2} {#3}
+ }
+ { \use:c { @@_change_case_next_ #1 :nnn } {#1} {#2} {#3} #4 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_change_case_lower_tr:nnnnn}
+% \begin{macro}[EXP]{\@@_change_case_lower_tr:nnnNw}
+% \begin{macro}[EXP]{\@@_change_case_lower_tr:NnnnN}
+% \begin{macro}[EXP]{\@@_change_case_lower_tr:Nnnnn}
+% The Turkic languages need special treatment for dotted-i and dotless-i.
+% The lower casing rule can be expressed in terms of searching first for
+% either a dotless-I or a dotted-I. In the latter case the mapping is
+% easy, but in the former there is a second stage search.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_lower_tr:nnnnn #1#2#3#4#5
+ {
+ \@@_codepoint_compare:nNnTF {#5} = { "0049 }
+ { \@@_change_case_lower_tr:nnnNw {#1} {#3} {#4} #5 }
+ {
+ \@@_codepoint_compare:nNnTF {#5} = { "0130 }
+ {
+ \@@_change_case_store:e
+ {
+ \codepoint_generate:nn { "0069 }
+ { \@@_change_case_catcode:nn {#5} { "0069 } }
+ }
+ \@@_change_case_loop:nnnw {#1} {#3} {#4}
+ }
+ { \@@_change_case_codepoint:nnnnn {#1} {#2} {#3} {#4} {#5} }
+ }
+ }
+% \end{macrocode}
+% After a dotless-I there may be a dot-above character. If there is then
+% a dotted-i should be produced, otherwise output a dotless-i. When the
+% combination is found both the dotless-I and the dot-above char have to
+% be removed from the input.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_lower_tr:nnnNw #1#2#3#4#5 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#5}
+ { \@@_change_case_lower_tr:NnnnN #4 {#1} {#2} {#3} }
+ {
+ \@@_change_case_store:e
+ {
+ \codepoint_generate:nn { "0131 }
+ { \@@_change_case_catcode:nn {#4} { "0131 } }
+ }
+ \@@_change_case_loop:nnnw {#1} {#2} {#3}
+ }
+ #5 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_change_case_lower_tr:NnnnN #1#2#3#4#5
+ {
+ \@@_codepoint_process:nN
+ { \@@_change_case_lower_tr:Nnnnn #1 {#2} {#3} {#4} } #5
+ }
+\cs_new:Npn \@@_change_case_lower_tr:Nnnnn #1#2#3#4#5
+ {
+ \bool_lazy_or:nnTF
+ {
+ \bool_lazy_and_p:nn
+ { \tl_if_single_p:n {#5} }
+ { \token_if_cs_p:N #5 }
+ }
+ { ! \@@_codepoint_compare_p:nNn {#5} = { "0307 } }
+ {
+ \@@_change_case_store:e
+ {
+ \codepoint_generate:nn { "0131 }
+ { \@@_change_case_catcode:nn {#1} { "0131 } }
+ }
+ \@@_change_case_loop:nnnw {#2} {#3} {#4} #5
+ }
+ {
+ \@@_change_case_store:e
+ {
+ \codepoint_generate:nn { "0069 }
+ { \@@_change_case_catcode:nn {#1} { "0069 } }
+ }
+ \@@_change_case_loop:nnnw {#2} {#3} {#4}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_change_case_upper_tr:nnnnn}
+% Uppercasing is easier: just one exception with no context.
+% \begin{macrocode}
+\cs_new:Npn \@@_change_case_upper_tr:nnnnn #1#2#3#4#5
+ {
+ \@@_codepoint_compare:nNnTF {#5} = { "0069 }
+ {
+ \@@_change_case_store:e
+ {
+ \codepoint_generate:nn { "0130 }
+ { \@@_change_case_catcode:nn {#5} { "0130 } }
+ }
+ \use:c { @@_change_case_next_ #2 :nnn } {#2} {#3} {#4}
+ }
+ { \@@_change_case_codepoint:nnnnn {#1} {#2} {#3} {#4} {#5} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\@@_change_case_lower_az:nnnnn, \@@_change_case_upper_az:nnnnn}
+% Straight copies.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_change_case_lower_az:nnnnn
+ \@@_change_case_lower_tr:nnnnn
+\cs_new_eq:NN \@@_change_case_upper_az:nnnnn
+ \@@_change_case_upper_tr:nnnnn
+% \end{macrocode}
+% \end{macro}
+%
+% The (fixed) look-up mappings for letter-like control sequences.
+% \begin{macrocode}
+\group_begin:
+ \cs_set_protected:Npn \@@_change_case_setup:NN #1#2
+ {
+ \quark_if_recursion_tail_stop:N #1
+ \tl_const:cn { c_@@_lowercase_ \token_to_str:N #1 _tl }
+ { #2 }
+ \tl_const:cn { c_@@_uppercase_ \token_to_str:N #2 _tl }
+ { #1 }
+ \@@_change_case_setup:NN
+ }
+ \@@_change_case_setup:NN
+ \AA \aa
+ \AE \ae
+ \DH \dh
+ \DJ \dj
+ \IJ \ij
+ \L \l
+ \NG \ng
+ \O \o
+ \OE \oe
+ \SS \ss
+ \TH \th
+ \q_recursion_tail ?
+ \q_recursion_stop
+ \tl_const:cn { c_@@_uppercase_ \token_to_str:N \i _tl } { I }
+ \tl_const:cn { c_@@_uppercase_ \token_to_str:N \j _tl } { J }
+\group_end:
+% \end{macrocode}
+%
+% To deal with possible encoding-specific extensions to \tn{@uclclist},
+% we check at the end of the preamble. This will therefore only apply
+% to \LaTeXe{} package mode.
+% \begin{macrocode}
+\tl_if_exist:NT \@expl@finalise@setup@@@@
+ {
+ \tl_gput_right:Nn \@expl@finalise@setup@@@@
+ {
+ \tl_gput_right:Nn \@kernel@after@begindocument
+ {
+ \group_begin:
+ \cs_set_protected:Npn \@@_change_case_setup:Nn #1#2
+ {
+ \quark_if_recursion_tail_stop:N #1
+ \tl_if_single_token:nT {#2}
+ {
+ \cs_if_exist:cF
+ { c_@@_uppercase_ \token_to_str:N #1 _tl }
+ {
+ \tl_const:cn
+ { c_@@_uppercase_ \token_to_str:N #1 _tl }
+ { #2 }
+ }
+ \cs_if_exist:cF
+ { c_@@_lowercase_ \token_to_str:N #2 _tl }
+ {
+ \tl_const:cn
+ { c_@@_lowercase_ \token_to_str:N #2 _tl }
+ { #1 }
+ }
+ }
+ \@@_change_case_setup:Nn
+ }
+ \exp_after:wN \@@_change_case_setup:Nn \@uclclist
+ \q_recursion_tail ?
+ \q_recursion_stop
+ \group_end:
+ }
+ }
+ }
+% \end{macrocode}
+%
+% A few adjustments to case mapping for combining chars: these are not needed
+% for the Unicode engines
+% \begin{macrocode}
+\bool_lazy_or:nnF
+ { \sys_if_engine_luatex_p: }
+ { \sys_if_engine_xetex_p: }
+ {
+ \text_declare_uppercase_mapping:nn { "01F0 } { \v { J } }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3text-map.dtx b/macros/latex-dev/required/l3kernel/l3text-map.dtx
new file mode 100644
index 0000000000..213d8281a9
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3text-map.dtx
@@ -0,0 +1,586 @@
+% \iffalse meta-comment
+%
+%% File: l3text-map.dtx
+%
+% Copyright (C) 2022-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3text-map} module\\ Text processing (mapping)^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3text-map} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=text>
+% \end{macrocode}
+%
+% \subsection{Mapping to text}
+%
+% \begin{macro}[EXP]{\text_map_function:nN}
+% \begin{macro}[EXP]{\@@_map_function:nN}
+% \begin{macro}[EXP]{\@@_map_loop:Nnw}
+% \begin{macro}[EXP]{\@@_map_group:Nnn}
+% \begin{macro}[EXP]{\@@_map_space:Nnw}
+% \begin{macro}[EXP]{\@@_map_N_type:NnN}
+% \begin{macro}[EXP]{\@@_map_codepoint:Nnn}
+% \begin{macro}[EXP]{\@@_map_CR:Nnw}
+% \begin{macro}[EXP]{\@@_map_CR:NnN}
+% \begin{macro}[EXP]{\@@_map_class:Nnnn}
+% \begin{macro}[EXP]{\@@_map_class:nNnnn}
+% \begin{macro}[EXP]{\@@_map_class_loop:Nnnnw}
+% \begin{macro}[EXP]{\@@_map_class_end:nw}
+% \begin{macro}[EXP]
+% {
+% \@@_map_Control:Nnn ,
+% \@@_map_Extend:Nnn ,
+% \@@_map_SpacingMark:Nnn ,
+% \@@_map_Prepend:Nnn ,
+% \@@_map_Prepend_aux:Nnn
+% }
+% \begin{macro}[EXP]{\@@_map_Prepend:nNnn}
+% \begin{macro}[EXP]{\@@_map_Prepend_loop:Nnnw}
+% \begin{macro}[EXP]
+% {
+% \@@_map_not_Control:Nnn ,
+% \@@_map_not_Extend:Nnn ,
+% \@@_map_not_SpacingMark:Nnn ,
+% \@@_map_not_Prepend:Nnn ,
+% \@@_map_not_L:Nnn ,
+% \@@_map_not_LV:Nnn ,
+% \@@_map_not_V:Nnn ,
+% \@@_map_not_LVT:Nnn ,
+% \@@_map_not_T:Nnn
+% }
+% \begin{macro}[EXP]
+% {
+% \@@_map_L:Nnn ,
+% \@@_map_LV:Nnn ,
+% \@@_map_V:Nnn ,
+% \@@_map_LVT:Nnn ,
+% \@@_map_T:Nnn
+% }
+% \begin{macro}[EXP]{\@@_map_hangul:Nnnw}
+% \begin{macro}[EXP]{\@@_map_hangul:NnnN}
+% \begin{macro}[EXP]{\@@_map_hangul:Nnnn}
+% \begin{macro}[EXP]{\@@_map_hangul_aux:Nnnnw}
+% \begin{macro}[EXP]{\@@_map_hangul:nNnnnw}
+% \begin{macro}[EXP]{\@@_map_hangul_loop:Nnnnnw}
+% \begin{macro}[EXP]{\@@_map_hangul_next:Nnnn}
+% \begin{macro}[EXP]{\@@_map_hangul_end:nw}
+% \begin{macro}[EXP]
+% {
+% \@@_map_hangul_L:Nnn ,
+% \@@_map_hangul_LV:Nnn ,
+% \@@_map_hangul_V:Nnn ,
+% \@@_map_hangul_LVT:Nnn ,
+% \@@_map_hangul_T:Nnn
+% }
+% \begin{macro}[EXP]
+% {\@@_map_Regional_Indicator:Nnn, \@@_map_Regional_Indicator_aux:Nnn}
+% \begin{macro}[EXP]{\@@_map_lookahead:NnNw}
+% \begin{macro}[EXP]{\@@_map_lookahead:NnNN}
+% \begin{macro}[EXP]{\@@_map_output:Nn}
+% \begin{macro}[EXP]{\text_map_break:}
+% \begin{macro}[EXP]{\text_map_break:n}
+% The standard lead-off for an action loop.
+% \begin{macrocode}
+\cs_new:Npn \text_map_function:nN #1#2
+ { \exp_args:Ne \@@_map_function:nN { \text_expand:n {#1} } #2 }
+\cs_new:Npn \@@_map_function:nN #1#2
+ {
+ \@@_map_loop:Nnw #2 { } #1
+ \q_@@_recursion_tail \q_@@_recursion_stop
+ \prg_break_point:Nn \text_map_break: { }
+ }
+% \end{macrocode}
+% The standard set up for an \enquote{action} loop. Groups are handled by
+% recursion, spaces are treated similarly: both count as grapheme boundaries.
+% For \texttt{N}-type tokens, we filter out control sequences (again
+% a boundary), then move on to further analysis.
+% \begin{macrocode}
+\cs_new:Npn \@@_map_loop:Nnw #1#2#3 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#3}
+ { \@@_map_N_type:NnN }
+ {
+ \tl_if_head_is_group:nTF {#3}
+ { \@@_map_group:Nnn }
+ { \@@_map_space:Nnw }
+ }
+ #1 {#2} #3 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_map_group:Nnn #1#2#3
+ {
+ \@@_map_output:Nn #1 {#2}
+ {
+ \@@_map_loop:Nnw #1 { } #2
+ \q_@@_recursion_tail \q_@@_recursion_stop
+ \prg_break_point:Nn \text_map_break: { }
+ }
+ \@@_map_loop:Nnw #1 { }
+ }
+\use:e
+ { \cs_new:Npn \exp_not:N \@@_map_space:Nnw #1#2 \c_space_tl }
+ {
+ \@@_map_output:Nn #1 {#2}
+ #1 { ~ }
+ \@@_map_loop:Nnw #1 { }
+ }
+\cs_new:Npn \@@_map_N_type:NnN #1#2#3
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #3
+ {
+ \@@_map_output:Nn #1 {#2}
+ \text_map_break:
+ }
+ \token_if_cs:NTF #3
+ {
+ \@@_map_output:Nn #1 {#2}
+ #1 {#3}
+ \@@_map_loop:Nnw #1 { }
+ }
+ {
+ \@@_codepoint_process:nN
+ { \@@_map_codepoint:Nnn #1 {#2} } #3
+ }
+ }
+% \end{macrocode}
+% We pull out a few special cases here. Carriage returns case needs a bit of
+% context handling so has an auxiliary. Codepoint U+200D is the zero-width
+% joiner, which has no context to concern us: just don't break.
+% \begin{macrocode}
+\cs_new:Npn \@@_map_codepoint:Nnn #1#2#3
+ {
+ \@@_codepoint_compare:nNnTF {#3} = { "0D }
+ {
+ \@@_map_output:Nn #1 {#2}
+ \@@_map_CR:Nnw #1 {#3}
+ }
+ {
+ \@@_codepoint_compare:nNnTF {#3} = { "200D }
+ { \@@_map_loop:Nnw #1 {#2#3} }
+ { \@@_map_class:Nnnn #1 {#2} {#3} { Control } }
+ }
+ }
+% \end{macrocode}
+% A carriage return is a boundary unless it is immediately followed by
+% a line feed, in which case that pair is a boundary.
+% \begin{macrocode}
+\cs_new:Npn \@@_map_CR:Nnw #1#2#3 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#3}
+ { \@@_map_CR:NnN #1 {#2} }
+ {
+ #1 {#2}
+ \@@_map_loop:Nnw #1 { }
+ }
+ #3 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_map_CR:NnN #1#2#3
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #3
+ {
+ #1 {#2}
+ \text_map_break:
+ }
+ \bool_lazy_and:nnTF
+ { ! \token_if_cs_p:N #3 }
+ { \int_compare_p:nNn { `#3 } = { "0A } }
+ {
+ \@@_map_output:Nn #1 {#2#3}
+ \@@_map_loop:Nnw #1 { }
+ }
+ { \@@_map_loop:Nnw #1 { } #3 }
+ }
+% \end{macrocode}
+% There are various classes of character, and we deal with them all in
+% the same general way. We need to example the relevant list of codepoints:
+% if we get a hit, then we do whatever the relevant action is. Otherwise
+% we loop, but only if the current codepoint could still match: the
+% loop stops early otherwise and we move forward.
+% \begin{macrocode}
+\cs_new:Npn \@@_map_class:Nnnn #1#2#3#4
+ {
+ \exp_args:Nv \@@_map_class:nNnnn { c_@@_grapheme_ #4 _clist }
+ #1 {#2} {#3} {#4}
+ }
+\cs_new:Npn \@@_map_class:nNnnn #1#2#3#4#5
+ {
+ \@@_map_class_loop:Nnnnw #2 {#3} {#4} {#5}
+ #1 , \q_@@_recursion_tail .. , \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_map_class_loop:Nnnnw #1#2#3#4 #5 .. #6 ,
+ {
+ \@@_if_q_recursion_tail_stop_do:nn {#5}
+ { \use:c { @@_map_not_ #4 :Nnn } #1 {#2} {#3} }
+ \@@_codepoint_compare:nNnTF {#3} < { "#5 }
+ {
+ \@@_map_class_end:nw
+ { \use:c { @@_map_not_ #4 :Nnn } #1 {#2} {#3} }
+ }
+ {
+ \@@_codepoint_compare:nNnTF {#3} > { "#6 }
+ { \@@_map_class_loop:Nnnnw #1 {#2} {#3} {#4} }
+ {
+ \@@_map_class_end:nw
+ { \use:c { @@_map_ #4 :Nnn } #1 {#2} {#3} }
+ }
+ }
+ }
+\cs_new:Npn \@@_map_class_end:nw #1#2 \q_@@_recursion_stop {#1}
+% \end{macrocode}
+% Break before \emph{and} after.
+% \begin{macrocode}
+\cs_new:Npn \@@_map_Control:Nnn #1#2#3
+ {
+ \@@_map_output:Nn #1 {#2}
+ \@@_map_output:Nn #1 {#3}
+ \@@_map_loop:Nnw #1 { }
+ }
+% \end{macrocode}
+% Keep collecting.
+% \begin{macrocode}
+\cs_new:Npn \@@_map_Extend:Nnn #1#2#3
+ { \@@_map_loop:Nnw #1 {#2#3} }
+\cs_new_eq:NN \@@_map_SpacingMark:Nnn \@@_map_Extend:Nnn
+% \end{macrocode}
+% Outputting anything earlier, the combine with what follows. The only
+% exclusions are control characters.
+% \begin{macrocode}
+\cs_new:Npn \@@_map_Prepend:Nnn #1#2#3
+ {
+ \@@_map_output:Nn #1 {#2}
+ \@@_map_lookahead:NnNw #1 {#3} \@@_map_Prepend_aux:Nnn
+ }
+\cs_new:Npn \@@_map_Prepend_aux:Nnn #1#2#3
+ {
+ \bool_lazy_or:nnTF
+ { \@@_codepoint_compare_p:nNn {#3} = { "0A } }
+ { \@@_codepoint_compare_p:nNn {#3} = { "0D } }
+ {
+ #1 {#2}
+ \@@_map_loop:Nnw #1 {#3}
+ }
+ {
+ \exp_args:NV \@@_map_Prepend:nNnn
+ \c_@@_grapheme_Control_clist
+ #1 {#2} {#3}
+ }
+ }
+\cs_new:Npn \@@_map_Prepend:nNnn #1#2#3#4
+ {
+ \@@_map_Prepend_loop:Nnnw #2 {#3} {#4}
+ #1 , \q_@@_recursion_tail .. , \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_map_Prepend_loop:Nnnw #1#2#3 #4 .. #5 ,
+ {
+ \@@_if_q_recursion_tail_stop_do:nn {#4}
+ { \@@_map_loop:Nnw #1 {#2#3} }
+ \@@_codepoint_compare:nNnTF {#3} < { "#4 }
+ {
+ \@@_map_class_end:nw
+ { \@@_map_loop:Nnw #1 {#2#3} }
+ }
+ {
+ \@@_codepoint_compare:nNnTF {#3} > { "#5 }
+ { \@@_map_Prepend_loop:Nnnw #1 {#2} {#3} }
+ {
+ \@@_map_class_end:nw
+ { \@@_map_loop:Nnw #1 {#2} #3 }
+ }
+ }
+ }
+% \end{macrocode}
+% Dealing with end-of-class is done such that we can be flexible.
+% \begin{macrocode}
+\cs_new:Npn \@@_map_not_Control:Nnn #1#2#3
+ { \@@_map_class:Nnnn #1 {#2} {#3} { Extend } }
+\cs_new:Npn \@@_map_not_Extend:Nnn #1#2#3
+ { \@@_map_class:Nnnn #1 {#2} {#3} { SpacingMark } }
+\cs_new:Npn \@@_map_not_SpacingMark:Nnn #1#2#3
+ { \@@_map_class:Nnnn #1 {#2} {#3} { Prepend } }
+\cs_new:Npn \@@_map_not_Prepend:Nnn #1#2#3
+ { \@@_map_class:Nnnn #1 {#2} {#3} { L } }
+\cs_new:Npn \@@_map_not_L:Nnn #1#2#3
+ { \@@_map_class:Nnnn #1 {#2} {#3} { LV } }
+\cs_new:Npn \@@_map_not_LV:Nnn #1#2#3
+ { \@@_map_class:Nnnn #1 {#2} {#3} { V } }
+\cs_new:Npn \@@_map_not_V:Nnn #1#2#3
+ { \@@_map_class:Nnnn #1 {#2} {#3} { LVT } }
+\cs_new:Npn \@@_map_not_LVT:Nnn #1#2#3
+ { \@@_map_class:Nnnn #1 {#2} {#3} { T } }
+\cs_new:Npn \@@_map_not_T:Nnn #1#2#3
+ { \@@_map_class:Nnnn #1 {#2} {#3} { Regional_Indicator } }
+\cs_new:Npn \@@_map_not_Regional_Indicator:Nnn #1#2#3
+ {
+ \@@_map_output:Nn #1 {#2}
+ \@@_map_loop:Nnw #1 {#3}
+ }
+% \end{macrocode}
+% Hangul needs additional treatment. First we have to deal with
+% the start-of-Hangul position: output what we had up to now, then
+% move the specialist handler. The idea here is to pick off the
+% different codepoint types one at a time, tracking what else can be
+% considered at each stage until we hit the end of the viable types.
+% Other than that, we just keep building up the Hangul codepoints
+% using a dedicated version of the loop from above.
+% \begin{macrocode}
+\cs_new:Npn \@@_map_L:Nnn #1#2#3
+ {
+ \@@_map_output:Nn #1 {#2}
+ \@@_map_hangul:Nnnw
+ #1 {#3} { L ; V ; LV ; LVT }
+ }
+\cs_new:Npn \@@_map_LV:Nnn #1#2#3
+ {
+ \@@_map_output:Nn #1 {#2}
+ \@@_map_hangul:Nnnw
+ #1 {#3} { V ; T }
+ }
+\cs_new_eq:NN \@@_map_V:Nnn \@@_map_LV:Nnn
+\cs_new:Npn \@@_map_LVT:Nnn #1#2#3
+ {
+ \@@_map_output:Nn #1 {#2}
+ \@@_map_hangul:Nnnw
+ #1 {#3} { T }
+ }
+\cs_new_eq:NN \@@_map_T:Nnn \@@_map_LVT:Nnn
+\cs_new:Npn \@@_map_hangul:Nnnw #1#2#3#4 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#4}
+ { \@@_map_hangul:NnnN #1 {#2} {#3} }
+ {
+ #1 {#2}
+ \@@_map_loop:Nnw #1 { }
+ }
+ #4 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_map_hangul:NnnN #1#2#3#4
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #4
+ {
+ #1 {#2}
+ \text_map_break:
+ }
+ \token_if_cs:NTF #4
+ {
+ #1 {#2}
+ \@@_map_loop:Nnw #1 { }
+ }
+ {
+ \@@_codepoint_process:nN
+ { \@@_map_hangul:Nnnn #1 {#2} {#3} } #4
+ }
+ }
+\cs_new:Npn \@@_map_hangul:Nnnn #1#2#3#4
+ {
+ \@@_map_hangul_aux:Nnnw #1 {#2} {#4}
+ #3 ; \q_recursion_tail ; \q_recursion_stop
+ }
+\cs_new:Npn \@@_map_hangul_aux:Nnnw #1#2#3#4 ;
+ {
+ \quark_if_recursion_tail_stop_do:nn {#4}
+ { \@@_map_loop:Nnw #1 {#2} #3 }
+ \exp_args:Nv \@@_map_hangul:nNnnnw { c_@@_grapheme_ #4 _clist }
+ #1 {#2} {#3} {#4}
+ }
+\cs_new:Npn \@@_map_hangul:nNnnnw #1#2#3#4#5#6 \q_recursion_stop
+ {
+ \@@_map_hangul_loop:Nnnnnw #2 {#3} {#4} {#5} {#6}
+ #1 , \q_@@_recursion_tail .. , \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_map_hangul_loop:Nnnnnw #1#2#3#4#5 #6 .. #7 ,
+ {
+ \@@_if_q_recursion_tail_stop_do:nn {#6}
+ { \@@_map_hangul_next:Nnnn #1 {#2} {#3} {#5} }
+ \@@_codepoint_compare:nNnTF {#3} < { "#6 }
+ {
+ \@@_map_hangul_end:nw
+ { \@@_map_hangul_next:Nnnn #1 {#2} {#3} {#5} }
+ }
+ {
+ \@@_codepoint_compare:nNnTF {#3} > { "#7 }
+ { \@@_map_hangul_loop:Nnnnnw #1 {#2} {#3} {#4} {#5} }
+ {
+ \@@_map_hangul_end:nw
+ { \use:c { @@_map_hangul_ #4 :Nnn } #1 {#2} {#3} }
+ }
+ }
+ }
+\cs_new:Npn \@@_map_hangul_next:Nnnn #1#2#3#4
+ { \@@_map_hangul_aux:Nnnw #1 {#2} {#3} #4 \q_recursion_stop }
+\cs_new:Npn \@@_map_hangul_end:nw #1#2 \q_@@_recursion_stop {#1}
+\cs_new:Npn \@@_map_hangul_L:Nnn #1#2#3
+ {
+ \@@_map_hangul:Nnnw
+ #1 {#2#3} { L V { LV } { LVT } }
+ }
+\cs_new:Npn \@@_map_hangul_LV:Nnn #1#2#3
+ {
+ \@@_map_hangul:Nnnw
+ #1 {#2#3} { VT }
+ }
+\cs_new_eq:NN \@@_map_hangul_V:Nnn \@@_map_hangul_LV:Nnn
+\cs_new:Npn \@@_map_hangul_LVT:Nnn #1#2#3
+ {
+ \@@_map_hangul:Nnnw
+ #1 {#2#3} { T }
+ }
+\cs_new_eq:NN \@@_map_hangul_T:Nnn \@@_map_hangul_LVT:Nnn
+% \end{macrocode}
+% The Regional Indicator rule means looking ahead and dealing with the
+% case where there are two in a row. So we use a look ahead to pick them
+% off. As there is only one range the values are hard-coded.
+% \begin{macrocode}
+\cs_new:Npn \@@_map_Regional_Indicator:Nnn #1#2#3
+ {
+ \@@_map_output:Nn #1 {#2}
+ \@@_map_lookahead:NnNw #1 {#3} \@@_map_Regional_Indicator_aux:Nnn
+ }
+\cs_new:Npn \@@_map_Regional_Indicator_aux:Nnn #1#2#3
+ {
+ \bool_lazy_or:nnTF
+ { \@@_codepoint_compare_p:nNn {#3} < { "1F1E6 } }
+ { \@@_codepoint_compare_p:nNn {#3} > { "1F1FF } }
+ {
+ \@@_map_loop:Nnw #1 {#2} #3
+ }
+ { \@@_map_loop:Nnw #1 {#2#3} }
+ }
+% \end{macrocode}
+% A generic loop-ahead setup.
+% \begin{macrocode}
+\cs_new:Npn \@@_map_lookahead:NnNw #1#2#3#4 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#4}
+ { \@@_map_lookahead:NnNN #1 {#2} #3 }
+ { \@@_map_loop:Nnw #1 {#2} }
+ #4 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_map_lookahead:NnNN #1#2#3#4
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #4 { #1 {#2} }
+ \token_if_cs:NTF #4
+ {
+ #1 {#2}
+ \@@_map_loop:Nnw #1 { }
+ }
+ { \@@_codepoint_process:nN { #3 #1 {#2} } }
+ #4
+ }
+% \end{macrocode}
+% For the end of the process.
+% \begin{macrocode}
+\cs_new:Npn \@@_map_output:Nn #1#2
+ { \tl_if_blank:nF {#2} { #1 {#2} } }
+\cs_new:Npn \text_map_break:
+ { \prg_map_break:Nn \text_map_break: { } }
+\cs_new:Npn \text_map_break:n
+ { \prg_map_break:Nn \text_map_break: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\text_map_inline:nn}
+% The standard non-expandable inline version.
+% \begin{macrocode}
+\cs_new_protected:Npn \text_map_inline:nn #1#2
+ {
+ \int_gincr:N \g__kernel_prg_map_int
+ \cs_gset_protected:cpn
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w } ##1 {#2}
+ \exp_args:Nnc \text_map_function:nN {#1}
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
+ \prg_break_point:Nn \text_map_break:
+ { \int_gdecr:N \g__kernel_prg_map_int }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3text-purify.dtx b/macros/latex-dev/required/l3kernel/l3text-purify.dtx
new file mode 100644
index 0000000000..a713cd6e40
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3text-purify.dtx
@@ -0,0 +1,797 @@
+% \iffalse meta-comment
+%
+%% File: l3text-purify.dtx
+%
+% Copyright (C) 2020-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3text-purify} module\\ Text processing (purification)^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3text-purify} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=text>
+% \end{macrocode}
+%
+% \subsection{Purifying text}
+%
+% \begin{macro}[EXP]{\@@_if_recursion_tail_stop:N}
+% Functions to query recursion quarks.
+% \begin{macrocode}
+\__kernel_quark_new_test:N \@@_if_recursion_tail_stop:N
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\text_purify:n, \@@_purify:n}
+% \begin{macro}[EXP]{\@@_purify_store:n}
+% \begin{macro}[EXP]{\@@_purify_store:nw}
+% \begin{macro}[EXP]{\@@_purify_end:w}
+% \begin{macro}[EXP]{\@@_purify_loop:w}
+% \begin{macro}[EXP]{\@@_purify_group:n}
+% \begin{macro}[EXP]{\@@_purify_space:w}
+% \begin{macro}[EXP]{\@@_purify_N_type:N, \@@_purify_N_type_aux:N}
+% \begin{macro}[EXP]{\@@_purify_math_search:NNN}
+% \begin{macro}[EXP]{\@@_purify_math_start:NNw}
+% \begin{macro}[EXP]{\@@_purify_math_store:n}
+% \begin{macro}[EXP]{\@@_purify_math_store:nw}
+% \begin{macro}[EXP]{\@@_purify_math_end:w}
+% \begin{macro}[EXP]{\@@_purify_math_loop:NNw}
+% \begin{macro}[EXP]{\@@_purify_math_N_type:NNN}
+% \begin{macro}[EXP]{\@@_purify_math_group:NNn}
+% \begin{macro}[EXP]{\@@_purify_math_space:NNw}
+% \begin{macro}[EXP]{\@@_purify_math_cmd:N}
+% \begin{macro}[EXP]{\@@_purify_math_cmd:NN}
+% \begin{macro}[EXP]{\@@_purify_math_cmd:Nn}
+% \begin{macro}[EXP]{\@@_purify_replace:N}
+% \begin{macro}[EXP]{\@@_purify_replace_auxi:n, \@@_purify_replace_auxii:n}
+% \begin{macro}[EXP]{\@@_purify_expand:N, \@@_purify_protect:N, \@@_purify_encoding:N}
+% \begin{macro}[EXP]{\@@_purify_encoding_escape:NN}
+% As in the other parts of the module, we start off with a standard
+% \enquote{action} loop, with expansion applied up-front.
+% \begin{macrocode}
+\cs_new:Npn \text_purify:n #1
+ {
+ \__kernel_exp_not:w \exp_after:wN
+ {
+ \exp:w
+ \exp_args:Ne \@@_purify:n
+ { \text_expand:n {#1} }
+ }
+ }
+\cs_new:Npn \@@_purify:n #1
+ {
+ \group_align_safe_begin:
+ \@@_purify_loop:w #1
+ \q_@@_recursion_tail \q_@@_recursion_stop
+ \@@_purify_result:n { }
+ }
+% \end{macrocode}
+% As for expansion, collect up the tokens for future use.
+% \begin{macrocode}
+\cs_new:Npn \@@_purify_store:n #1
+ { \@@_purify_store:nw {#1} }
+\cs_new:Npn \@@_purify_store:nw #1#2 \@@_purify_result:n #3
+ { #2 \@@_purify_result:n { #3 #1 } }
+\cs_new:Npn \@@_purify_end:w #1 \@@_purify_result:n #2
+ {
+ \group_align_safe_end:
+ \exp_end:
+ #2
+ }
+% \end{macrocode}
+% The main loop is a standard \enquote{tl action}. Unlike the expansion
+% or case changing, here any groups have to be run inline. Most of the
+% business end is as before in the \texttt{N}-type token processing.
+% \begin{macrocode}
+\cs_new:Npn \@@_purify_loop:w #1 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#1}
+ { \@@_purify_N_type:N }
+ {
+ \tl_if_head_is_group:nTF {#1}
+ { \@@_purify_group:n }
+ { \@@_purify_space:w }
+ }
+ #1 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_purify_group:n #1 { \@@_purify_loop:w #1 }
+\exp_last_unbraced:NNo \cs_new:Npn \@@_purify_space:w \c_space_tl
+ {
+ \@@_purify_store:n { ~ }
+ \@@_purify_loop:w
+ }
+% \end{macrocode}
+% The first part of handling math mode is exactly the same as in the
+% other functions: look for a start-of-math mode token and if found start
+% a new loop tracking the closing token.
+% \begin{macrocode}
+\cs_new:Npn \@@_purify_N_type:N #1
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #1 { \@@_purify_end:w }
+ \@@_purify_N_type_aux:N #1
+ }
+\cs_new:Npn \@@_purify_N_type_aux:N #1
+ {
+ \exp_after:wN \@@_purify_math_search:NNN
+ \exp_after:wN #1 \l_text_math_delims_tl
+ \q_@@_recursion_tail ?
+ \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_purify_math_search:NNN #1#2#3
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #2
+ { \@@_purify_math_cmd:N #1 }
+ \token_if_eq_meaning:NNTF #1 #2
+ {
+ \@@_use_i_delimit_by_q_recursion_stop:nw
+ { \@@_purify_math_start:NNw #2 #3 }
+ }
+ { \@@_purify_math_search:NNN #1 }
+ }
+\cs_new:Npn \@@_purify_math_start:NNw #1#2#3 \q_@@_recursion_stop
+ {
+ \@@_purify_math_loop:NNw #1#2#3 \q_@@_recursion_stop
+ \@@_purify_math_result:n { }
+ }
+\cs_new:Npn \@@_purify_math_store:n #1
+ { \@@_purify_math_store:nw {#1} }
+\cs_new:Npn \@@_purify_math_store:nw #1#2 \@@_purify_math_result:n #3
+ { #2 \@@_purify_math_result:n { #3 #1 } }
+\cs_new:Npn \@@_purify_math_end:w #1 \@@_purify_math_result:n #2
+ {
+ \@@_purify_store:n { $ #2 $ }
+ \@@_purify_loop:w #1
+ }
+\cs_new:Npn \@@_purify_math_stop:Nw #1 \@@_purify_math_result:n #2
+ {
+ \@@_purify_store:n {#1#2}
+ \@@_purify_end:w
+ }
+\cs_new:Npn \@@_purify_math_loop:NNw #1#2#3 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#3}
+ { \@@_purify_math_N_type:NNN }
+ {
+ \tl_if_head_is_group:nTF {#3}
+ { \@@_purify_math_group:NNn }
+ { \@@_purify_math_space:NNw }
+ }
+ #1#2#3 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_purify_math_N_type:NNN #1#2#3
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #3
+ { \@@_purify_math_stop:Nw #1 }
+ \token_if_eq_meaning:NNTF #3 #2
+ { \@@_purify_math_end:w }
+ {
+ \@@_purify_math_store:n {#3}
+ \@@_purify_math_loop:NNw #1#2
+ }
+ }
+\cs_new:Npn \@@_purify_math_group:NNn #1#2#3
+ {
+ \@@_purify_math_store:n { {#3} }
+ \@@_purify_math_loop:NNw #1#2
+ }
+\exp_after:wN \cs_new:Npn \exp_after:wN \@@_purify_math_space:NNw
+ \exp_after:wN # \exp_after:wN 1
+ \exp_after:wN # \exp_after:wN 2 \c_space_tl
+ {
+ \@@_purify_math_store:n { ~ }
+ \@@_purify_math_loop:NNw #1#2
+ }
+% \end{macrocode}
+% Then handle math mode as an argument: same outcomes, different input
+% syntax.
+% \begin{macrocode}
+\cs_new:Npn \@@_purify_math_cmd:N #1
+ {
+ \exp_after:wN \@@_purify_math_cmd:NN \exp_after:wN #1
+ \l_text_math_arg_tl \q_@@_recursion_tail \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_purify_math_cmd:NN #1#2
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #2
+ { \@@_purify_replace:N #1 }
+ \cs_if_eq:NNTF #2 #1
+ {
+ \@@_use_i_delimit_by_q_recursion_stop:nw
+ { \@@_purify_math_cmd:n }
+ }
+ { \@@_purify_math_cmd:NN #1 }
+ }
+\cs_new:Npn \@@_purify_math_cmd:n #1
+ { \@@_purify_math_end:w \@@_purify_math_result:n {#1} }
+% \end{macrocode}
+% For \texttt{N}-type tokens, we first look for a string-context replacement
+% before anything else: this can therefore cover anything. Assuming we don't
+% find one, check to see if we can expand control sequences: if not, they have
+% to be dropped. We also allow for \LaTeXe{} \tn{protect}: there's an
+% assumption that we don't have |\protect { \oops }| or similar, but that's
+% also in the expansion code and seems like a reasonable balance.
+% \begin{macrocode}
+\cs_new:Npn \@@_purify_replace:N #1
+ {
+ \bool_lazy_and:nnTF
+ { \cs_if_exist_p:c { l_@@_purify_ \token_to_str:N #1 _tl } }
+ {
+ \bool_lazy_or_p:nn
+ { \token_if_cs_p:N #1 }
+ { \token_if_active_p:N #1 }
+ }
+ {
+ \exp_args:Nv \@@_purify_replace_auxi:n
+ { l_@@_purify_ \token_to_str:N #1 _tl }
+ }
+ {
+ \exp_args:Ne \@@_purify_replace_auxii:n
+ { \@@_token_to_explicit:N #1 }
+ }
+ }
+\cs_new:Npn \@@_purify_replace_auxi:n #1 { \@@_purify_loop:w #1 }
+\cs_new:Npn \@@_purify_replace_auxii:n #1
+ {
+ \token_if_cs:NTF #1
+ { \@@_purify_expand:N #1 }
+ {
+ \@@_purify_store:n {#1}
+ \@@_purify_loop:w
+ }
+ }
+\cs_new:Npn \@@_purify_expand:N #1
+ {
+ \str_if_eq:nnTF {#1} { \protect }
+ { \@@_purify_protect:N }
+ { \@@_purify_encoding:N #1 }
+ }
+\cs_new:Npn \@@_purify_protect:N #1
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #1 { \@@_purify_end:w }
+ \@@_purify_loop:w
+ }
+% \end{macrocode}
+% Handle encoding commands, as detailed for expansion.
+% \begin{macrocode}
+\cs_new:Npn \@@_purify_encoding:N #1
+ {
+ \bool_lazy_or:nnTF
+ { \cs_if_eq_p:NN #1 \@current@cmd }
+ { \cs_if_eq_p:NN #1 \@changed@cmd }
+ { \@@_purify_encoding_escape:NN }
+ {
+ \@@_if_expandable:NTF #1
+ { \exp_after:wN \@@_purify_loop:w #1 }
+ { \@@_purify_loop:w }
+ }
+ }
+\cs_new:Npn \@@_purify_encoding_escape:NN #1#2
+ {
+ \@@_purify_store:n {#1}
+ \@@_purify_loop:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \text_declare_purify_equivalent:Nn,
+% \text_declare_purify_equivalent:Ne
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \text_declare_purify_equivalent:Nn #1#2
+ {
+ \tl_clear_new:c { l_@@_purify_ \token_to_str:N #1 _tl }
+ \tl_set:cn { l_@@_purify_ \token_to_str:N #1 _tl } {#2}
+ }
+\cs_generate_variant:Nn \text_declare_purify_equivalent:Nn { Ne }
+% \end{macrocode}
+% \end{macro}
+%
+% Now pre-define a range of standard commands that need dedicated definitions
+% in purified text. First handle font-related stuff: all of this needs to be
+% disabled.
+% \begin{macrocode}
+\tl_map_inline:nn
+ {
+ \fontencoding
+ \fontfamily
+ \fontseries
+ \fontshape
+ }
+ { \text_declare_purify_equivalent:Nn #1 { \use_none:n } }
+\text_declare_purify_equivalent:Nn \fontsize { \use_none:nn }
+\text_declare_purify_equivalent:Nn \selectfont { }
+\text_declare_purify_equivalent:Nn \usefont { \use_none:nnnn }
+\tl_map_inline:nn
+ {
+ \emph
+ \text
+ \textnormal
+ \textrm
+ \textsf
+ \texttt
+ \textbf
+ \textmd
+ \textit
+ \textsl
+ \textup
+ \textsc
+ \textulc
+ }
+ { \text_declare_purify_equivalent:Nn #1 { \use:n } }
+\tl_map_inline:nn
+ {
+ \normalfont
+ \rmfamily
+ \sffamily
+ \ttfamily
+ \bfseries
+ \mdseries
+ \itshape
+ \scshape
+ \slshape
+ \upshape
+ \em
+ \Huge
+ \LARGE
+ \Large
+ \footnotesize
+ \huge
+ \large
+ \normalsize
+ \scriptsize
+ \small
+ \tiny
+ }
+ { \text_declare_purify_equivalent:Nn #1 { } }
+\exp_args:Nc \text_declare_purify_equivalent:Nn
+ { @protected@testopt } { \use_none:nnn }
+% \end{macrocode}
+% Environments have to be handled by pure expansion.
+%
+% \begin{macro}{\@@_end_env:n}
+% \begin{macrocode}
+\text_declare_purify_equivalent:Nn \begin { \use:c }
+\text_declare_purify_equivalent:Nn \end { \@@_end_env:n }
+\cs_new:Npn \@@_end_env:n #1 { \cs:w end #1 \cs_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% Some common symbols and similar ideas.
+% \begin{macrocode}
+\text_declare_purify_equivalent:Nn \\ { }
+\tl_map_inline:nn
+ { \{ \} \# \$ \% \_ }
+ { \text_declare_purify_equivalent:Ne #1 { \cs_to_str:N #1 } }
+% \end{macrocode}
+% Cross-referencing.
+% \begin{macrocode}
+\text_declare_purify_equivalent:Nn \label { \use_none:n }
+% \end{macrocode}
+% Spaces.
+% \begin{macrocode}
+\group_begin:
+\char_set_catcode_active:N \~
+\use:n
+ {
+ \group_end:
+ \text_declare_purify_equivalent:Ne ~ { \c_space_tl }
+ }
+\text_declare_purify_equivalent:Nn \nobreakspace { ~ }
+\text_declare_purify_equivalent:Nn \ { ~ }
+\text_declare_purify_equivalent:Nn \, { ~ }
+% \end{macrocode}
+%
+% \subsection{Accent and letter-like data for purifying text}
+%
+% In contrast to case changing, both $8$-bit and Unicode engines need
+% information for text purification to handle accents and letter-like
+% functions: these all need to be removed. However, the results are
+% of course engine-dependent.
+%
+% For the letter-like commands, life is relatively easy: they are all
+% simply added as standard exceptions. The only oddity is \tn{SS}, which
+% gets converted to two letters. (At some stage an alternative version
+% can presumably be added to \pkg{babel} or similar.)
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_loop:Nn #1#2
+ {
+ \quark_if_recursion_tail_stop:N #1
+ \text_declare_purify_equivalent:Ne #1
+ {
+ \codepoint_generate:nn {"#2}
+ { \char_value_catcode:n {"#2} }
+ }
+ \@@_loop:Nn
+ }
+\@@_loop:Nn
+ \AA { 00C5 }
+ \AE { 00C6 }
+ \DH { 00D0 }
+ \DJ { 0110 }
+ \IJ { 0132 }
+ \L { 0141 }
+ \NG { 014A }
+ \O { 00D8 }
+ \OE { 0152 }
+ \TH { 00DE }
+ \aa { 00E5 }
+ \ae { 00E6 }
+ \dh { 00F0 }
+ \dj { 0111 }
+ \i { 0131 }
+ \j { 0237 }
+ \ij { 0132 }
+ \l { 0142 }
+ \ng { 014B }
+ \o { 00F8 }
+ \oe { 0153 }
+ \ss { 00DF }
+ \th { 00FE }
+ \q_recursion_tail ?
+ \q_recursion_stop
+\text_declare_purify_equivalent:Nn \SS { SS }
+% \end{macrocode}
+%
+% \begin{macro}[rEXP]{\@@_purify_accent:NN}
+% Accent \textsc{licr} handling is a little more complex. Accents may exist
+% as pre-composed codepoints or as independent glyphs. The former are all
+% saved as single token lists, whilst for the latter the combining accent
+% needs to be re-ordered compared to the character it applies to.
+% \begin{macrocode}
+\cs_new:Npn \@@_purify_accent:NN #1#2
+ {
+ \cs_if_exist:cTF
+ { c_@@_purify_ \token_to_str:N #1 _ \token_to_str:N #2 _tl }
+ {
+ \exp_not:v
+ { c_@@_purify_ \token_to_str:N #1 _ \token_to_str:N #2 _tl }
+ }
+ {
+ \exp_not:n {#2}
+ \exp_not:v { c_@@_purify_ \token_to_str:N #1 _tl }
+ }
+ }
+\tl_map_inline:nn { \` \' \^ \~ \= \u \. \" \r \H \v \d \c \k \b \t }
+ { \text_declare_purify_equivalent:Nn #1 { \@@_purify_accent:NN #1 } }
+% \end{macrocode}
+% First set up the combining accents.
+% \begin{macrocode}
+\group_begin:
+ \cs_set_protected:Npn \@@_loop:Nn #1#2
+ {
+ \quark_if_recursion_tail_stop:N #1
+ \tl_const:ce { c_@@_purify_ \token_to_str:N #1 _tl }
+ { \codepoint_generate:nn {"#2} { \char_value_catcode:n { "#2 } } }
+ \@@_loop:Nn
+ }
+ \@@_loop:Nn
+ \` { 0300 }
+ \' { 0301 }
+ \^ { 0302 }
+ \~ { 0303 }
+ \= { 0304 }
+ \u { 0306 }
+ \. { 0307 }
+ \" { 0308 }
+ \r { 030A }
+ \H { 030B }
+ \v { 030C }
+ \d { 0323 }
+ \c { 0327 }
+ \k { 0328 }
+ \b { 0331 }
+ \t { 0361 }
+ \q_recursion_tail { }
+ \q_recursion_stop
+% \end{macrocode}
+% Now we handle the pre-composed accents: the list here is taken from
+% \texttt{puenc.def}. All of the precomposed cases take a single letter
+% as their second argument. We do not try to cover the case where an accent
+% is added to a \enquote{real} dotless-i or -j, or a \ae/\AE. Rather, we
+% assume that if the \textsc{utf}-8 character is used, it will have the
+% real accent character too.
+% \begin{macrocode}
+ \cs_set_protected:Npn \@@_loop:NNn #1#2#3
+ {
+ \quark_if_recursion_tail_stop:N #1
+ \tl_const:ce
+ { c_@@_purify_ \token_to_str:N #1 _ \token_to_str:N #2 _tl }
+ { \codepoint_generate:nn {"#3} { \char_value_catcode:n { "#3 } } }
+ \@@_loop:NNn
+ }
+ \@@_loop:NNn
+ \` A { 00C0 }
+ \' A { 00C1 }
+ \^ A { 00C2 }
+ \~ A { 00C3 }
+ \" A { 00C4 }
+ \r A { 00C5 }
+ \c C { 00C7 }
+ \` E { 00C8 }
+ \' E { 00C9 }
+ \^ E { 00CA }
+ \" E { 00CB }
+ \` I { 00CC }
+ \' I { 00CD }
+ \^ I { 00CE }
+ \" I { 00CF }
+ \~ N { 00D1 }
+ \` O { 00D2 }
+ \' O { 00D3 }
+ \^ O { 00D4 }
+ \~ O { 00D5 }
+ \" O { 00D6 }
+ \` U { 00D9 }
+ \' U { 00DA }
+ \^ U { 00DB }
+ \" U { 00DC }
+ \' Y { 00DD }
+ \` a { 00E0 }
+ \' a { 00E1 }
+ \^ a { 00E2 }
+ \~ a { 00E3 }
+ \" a { 00E4 }
+ \r a { 00E5 }
+ \c c { 00E7 }
+ \` e { 00E8 }
+ \' e { 00E9 }
+ \^ e { 00EA }
+ \" e { 00EB }
+ \` i { 00EC }
+ \` \i { 00EC }
+ \' i { 00ED }
+ \' \i { 00ED }
+ \^ i { 00EE }
+ \^ \i { 00EE }
+ \" i { 00EF }
+ \" \i { 00EF }
+ \~ n { 00F1 }
+ \` o { 00F2 }
+ \' o { 00F3 }
+ \^ o { 00F4 }
+ \~ o { 00F5 }
+ \" o { 00F6 }
+ \` u { 00F9 }
+ \' u { 00FA }
+ \^ u { 00FB }
+ \" u { 00FC }
+ \' y { 00FD }
+ \" y { 00FF }
+ \= A { 0100 }
+ \= a { 0101 }
+ \u A { 0102 }
+ \u a { 0103 }
+ \k A { 0104 }
+ \k a { 0105 }
+ \' C { 0106 }
+ \' c { 0107 }
+ \^ C { 0108 }
+ \^ c { 0109 }
+ \. C { 010A }
+ \. c { 010B }
+ \v C { 010C }
+ \v c { 010D }
+ \v D { 010E }
+ \v d { 010F }
+ \= E { 0112 }
+ \= e { 0113 }
+ \u E { 0114 }
+ \u e { 0115 }
+ \. E { 0116 }
+ \. e { 0117 }
+ \k E { 0118 }
+ \k e { 0119 }
+ \v E { 011A }
+ \v e { 011B }
+ \^ G { 011C }
+ \^ g { 011D }
+ \u G { 011E }
+ \u g { 011F }
+ \. G { 0120 }
+ \. g { 0121 }
+ \c G { 0122 }
+ \c g { 0123 }
+ \^ H { 0124 }
+ \^ h { 0125 }
+ \~ I { 0128 }
+ \~ i { 0129 }
+ \~ \i { 0129 }
+ \= I { 012A }
+ \= i { 012B }
+ \= \i { 012B }
+ \u I { 012C }
+ \u i { 012D }
+ \u \i { 012D }
+ \k I { 012E }
+ \k i { 012F }
+ \k \i { 012F }
+ \. I { 0130 }
+ \^ J { 0134 }
+ \^ j { 0135 }
+ \^ \j { 0135 }
+ \c K { 0136 }
+ \c k { 0137 }
+ \' L { 0139 }
+ \' l { 013A }
+ \c L { 013B }
+ \c l { 013C }
+ \v L { 013D }
+ \v l { 013E }
+ \. L { 013F }
+ \. l { 0140 }
+ \' N { 0143 }
+ \' n { 0144 }
+ \c N { 0145 }
+ \c n { 0146 }
+ \v N { 0147 }
+ \v n { 0148 }
+ \= O { 014C }
+ \= o { 014D }
+ \u O { 014E }
+ \u o { 014F }
+ \H O { 0150 }
+ \H o { 0151 }
+ \' R { 0154 }
+ \' r { 0155 }
+ \c R { 0156 }
+ \c r { 0157 }
+ \v R { 0158 }
+ \v r { 0159 }
+ \' S { 015A }
+ \' s { 015B }
+ \^ S { 015C }
+ \^ s { 015D }
+ \c S { 015E }
+ \c s { 015F }
+ \v S { 0160 }
+ \v s { 0161 }
+ \c T { 0162 }
+ \c t { 0163 }
+ \v T { 0164 }
+ \v t { 0165 }
+ \~ U { 0168 }
+ \~ u { 0169 }
+ \= U { 016A }
+ \= u { 016B }
+ \u U { 016C }
+ \u u { 016D }
+ \r U { 016E }
+ \r u { 016F }
+ \H U { 0170 }
+ \H u { 0171 }
+ \k U { 0172 }
+ \k u { 0173 }
+ \^ W { 0174 }
+ \^ w { 0175 }
+ \^ Y { 0176 }
+ \^ y { 0177 }
+ \" Y { 0178 }
+ \' Z { 0179 }
+ \' z { 017A }
+ \. Z { 017B }
+ \. z { 017C }
+ \v Z { 017D }
+ \v z { 017E }
+ \v A { 01CD }
+ \v a { 01CE }
+ \v I { 01CF }
+ \v \i { 01D0 }
+ \v i { 01D0 }
+ \v O { 01D1 }
+ \v o { 01D2 }
+ \v U { 01D3 }
+ \v u { 01D4 }
+ \v G { 01E6 }
+ \v g { 01E7 }
+ \v K { 01E8 }
+ \v k { 01E9 }
+ \k O { 01EA }
+ \k o { 01EB }
+ \v \j { 01F0 }
+ \v j { 01F0 }
+ \' G { 01F4 }
+ \' g { 01F5 }
+ \` N { 01F8 }
+ \` n { 01F9 }
+ \' \AE { 01FC }
+ \' \ae { 01FD }
+ \' \O { 01FE }
+ \' \o { 01FF }
+ \v H { 021E }
+ \v h { 021F }
+ \. A { 0226 }
+ \. a { 0227 }
+ \c E { 0228 }
+ \c e { 0229 }
+ \. O { 022E }
+ \. o { 022F }
+ \= Y { 0232 }
+ \= y { 0233 }
+ \q_recursion_tail ? { }
+ \q_recursion_stop
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3text.dtx b/macros/latex-dev/required/l3kernel/l3text.dtx
new file mode 100644
index 0000000000..56c9a5533c
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3text.dtx
@@ -0,0 +1,1453 @@
+% \iffalse meta-comment
+%
+%% File: l3text.dtx
+%
+% Copyright (C) 2020-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3text} module\\ Text processing^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% This module deals with manipulation of (formatted) text; such material is
+% comprised of a restricted set of token list content. The functions provided
+% here concern conversion of textual content for example in case changing,
+% generation of bookmarks and extraction to tags. All of the major functions
+% operate by expansion. Begin-group and end-group tokens in the \meta{text}
+% are normalized and become |{| and |}|, respectively.
+%
+% \section{Expanding text}
+%
+% \begin{function}[EXP, added = 2020-01-02, updated = 2023-06-09]
+% {\text_expand:n}
+% \begin{syntax}
+% \cs{text_expand:n} \Arg{text}
+% \end{syntax}
+% Takes user input \meta{text} and expands the content.
+% Protected commands (typically
+% formatting) are left in place, and no processing takes place of
+% math mode material (as delimited by pairs given in
+% \cs{l_text_math_delims_tl} or as the argument to commands listed
+% in \cs{l_text_math_arg_tl}). Commands which are neither engine-
+% nor \LaTeX{} protected are expanded exhaustively.
+% Any commands listed in \cs{l_text_expand_exclude_tl} are excluded from
+% expansion, as are those in \cs{l_text_case_exclude_arg_tl} and
+% \cs{l_text_math_arg_tl}.
+% \end{function}
+%
+% \begin{function}[added = 2020-01-22]
+% {
+% \text_declare_expand_equivalent:Nn ,
+% \text_declare_expand_equivalent:cn
+% }
+% \begin{syntax}
+% \cs{text_declare_expand_equivalent:Nn} \meta{cmd} \Arg{replacement}
+% \end{syntax}
+% Declares that the \meta{replacement} tokens should be used whenever the
+% \meta{cmd} (a single token) is encountered. The \meta{replacement} tokens
+% should be expandable. A token can be \enquote{replaced} by itself if
+% the defined replacement wraps it in \cs{exp_not:n}, for example
+% \begin{verbatim}
+% \text_declare_expand_equivalent:Nn \' { \exp_not:n { \' } }
+% \end{verbatim}
+% \end{function}
+%
+% \section{Case changing}
+%
+% \begin{function}[EXP, added = 2019-11-20, updated = 2023-07-08]
+% {
+% \text_lowercase:n, \text_uppercase:n, \text_titlecase_all:n,
+% \text_titlecase_first:n,
+% \text_lowercase:nn, \text_uppercase:nn, \text_titlecase_all:nn,
+% \text_titlecase_first:nn
+% }
+% \begin{syntax}
+% \cs{text_uppercase:n} \Arg{tokens}
+% \cs{text_uppercase:nn} \Arg{BCP-47} \Arg{tokens}
+% \end{syntax}
+% Takes user input \meta{text} first applies \cs{text_expand:n}, then
+% transforms the case of character tokens as specified by the
+% function name. The category code of letters are not changed by this
+% process when Unicode engines are used; in $8$-bit engines, case changed
+% charters in the ASCII range will have the current prevailing category code,
+% while those outside of it will be represented by active characters.
+% \end{function}
+%
+% Upper- and lowercase have the obvious meanings. Titlecasing may be regarded
+% informally as converting the first character of the \meta{tokens} to
+% uppercase. However, the process is more complex
+% than this as there are some situations where a single lowercase character
+% maps to a special form, for example \texttt{ij} in Dutch which becomes
+% \texttt{IJ}. There are two functions available for titlecasing: one which
+% applies the change to each \enquote{word} and a second which only applies
+% at the start of the input. (Here, \enquote{word} boundaries are spaces:
+% at present, full Unicode word breaking is not attempted.)
+%
+% Importantly, notice that these functions are intended for working with
+% user \emph{text for typesetting}. For case changing programmatic data see
+% the \pkg{l3str} module and discussion there of \cs{str_lowercase:n},
+% \cs{str_uppercase:n} and \cs{str_casefold:n}.
+%
+% Case changing does not take place within math mode material so for example
+% \begin{verbatim}
+% \text_uppercase:n { Some~text~$y = mx + c$~with~{Braces} }
+% \end{verbatim}
+% becomes
+% \begin{verbatim}
+% SOME TEXT $y = mx + c$ WITH {BRACES}
+% \end{verbatim}
+%
+% The first mandatory argument of commands listed in
+% \cs{l_text_case_exclude_arg_tl}
+% is excluded from case changing; the latter are entirely non-textual
+% content (such as labels).
+%
+% The standard mappings
+% here follow those defined by the \href{http://www.unicode.org}^^A
+% {Unicode Consortium} in \texttt{UnicodeData.txt} and
+% \texttt{SpecialCasing.txt}. For \pTeX{}, only the ASCII range is
+% covered as the engine treats input outside of this range as east Asian.
+%
+% Locale-sensitive conversions are enabled using the \meta{BCP-47}
+% argument, and follow Unicode Consortium guidelines. Currently, the
+% locale strings recognized for special handling are as follows.
+% \begin{itemize}
+% \item Armenian (\texttt{hy} and \texttt{hy-x-yiwn})
+% The setting \texttt{hy} maps the codepoint U+0587, the ligature of
+% letters ech and yiwn, to the codepoints for capital ech and vew
+% when uppercasing: this follows the spelling reform which is used
+% in Armenia. The alternative \texttt{hy-x-yiwn} maps U+0587 to
+% capital ech and yiwn on uppercasing (also the output if Armenian
+% is not selected at all).
+% \item Azeri and Turkish (\texttt{az} and \texttt{tr}).
+% The case pairs I/i-dotless and I-dot/i are activated for these
+% languages. The combining dot mark is removed when lowercasing
+% I-dot and introduced when upper casing i-dotless.
+% \item German (\texttt{de-x-eszett}).
+% An alternative mapping for German in which the lowercase
+% \emph{Eszett} maps to a \emph{gro\ss{}es Eszett}.
+% \item Greek (\texttt{el}).
+% Removes accents from Greek letters when uppercasing; titlecasing
+% leaves accents in place. A variant \texttt{el-x-iota} is available
+% which converts the \textit{ypogegrammeni} (subscript muted iota)
+% to capital iota when uppercasing: the standard version retains the
+% subscript versions.
+% \item Lithuanian (\texttt{lt}).
+% The lowercase letters i and j should retain a dot above when the
+% accents grave, acute or tilde are present. This is implemented for
+% lowercasing of the relevant uppercase letters both when input as
+% single Unicode codepoints and when using combining accents. The
+% combining dot is removed when uppercasing in these cases. Note that
+% \emph{only} the accents used in Lithuanian are covered: the behaviour
+% of other accents are not modified.
+% \item Medieval Latin (\texttt{la-x-medieval}).
+% The characters |u| and |V| are interchanged on case changing.
+% \item Dutch (\texttt{nl}).
+% Capitalisation of \texttt{ij} at the beginning of titlecased
+% input produces \texttt{IJ} rather than \texttt{Ij}.
+% \end{itemize}
+%
+% Determining whether non-letter characters at the start of text should count
+% as the uppercase element is controllable. When
+% \cs{l_text_titlecase_check_letter_bool} is \texttt{true}, codepoints which are
+% not letters (Unicode general category \texttt{L}) are not changed, and only
+% the first \emph{letter} is uppercased.
+% When \cs{l_text_titlecase_check_letter_bool} is \texttt{false}, the first
+% codepoint is uppercased, irrespective of the general code of the character.
+%
+% \begin{function}[added = 2022-07-04]
+% {\text_declare_case_equivalent:Nn}
+% \begin{syntax}
+% \cs{text_declare_case_equivalent:Nn} \meta{cmd} \Arg{replacement}
+% \end{syntax}
+% Declares that the \meta{replacement} tokens should be used whenever the
+% \meta{cmd} (a single token) is encountered during case changing.
+% \end{function}
+%
+% \begin{function}[added = 2023-04-11, updated = 2023-04-20]
+% {
+% \text_declare_lowercase_mapping:nn ,
+% \text_declare_lowercase_mapping:nnn ,
+% \text_declare_titlecase_mapping:nn ,
+% \text_declare_titlecase_mapping:nnn ,
+% \text_declare_uppercase_mapping:nn ,
+% \text_declare_uppercase_mapping:nnn
+% }
+% \begin{syntax}
+% \cs{text_declare_lowercase_mapping:nn} \Arg{codeppoint} \Arg{replacement}
+% \cs{text_declare_lowercase_mapping:nnn} \Arg{BCP-47} \Arg{codeppoint} \Arg{replacement}
+% \end{syntax}
+% Declares that the \meta{replacement} tokens should be used when case mapping
+% the \meta{codepoint}, rather than the standard mapping given in the
+% Unicode data files. The \texttt{nnn} version takes a BCP-47 tag, which
+% can be used to specify that the customisation only applies to that
+% locale.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2022-07-04]{\text_case_switch:nnnn}
+% \begin{syntax}
+% \cs{text_case_switch:nnnn} \Arg{normal} \Arg{upper} \Arg{lower} \Arg{title}
+% \end{syntax}
+% Context-sensitive function which will expand to one of the \meta{normal},
+% \meta{upper}, \meta{lower} or \meta{title} tokens depending on the current
+% case changing operation. Outside of case changing, the \meta{normal} tokens
+% are produced. Within case changing, the appropriate mapping tokens are
+% inserted.
+% \end{function}
+%
+% \section{Removing formatting from text}
+%
+% \begin{function}[EXP, added = 2020-03-05, updated = 2020-05-14]{\text_purify:n}
+% \begin{syntax}
+% \cs{text_purify:n} \Arg{text}
+% \end{syntax}
+% Takes user input \meta{text} and expands as described for
+% \cs{text_expand:n}, then removes all functions from the resulting
+% text. Math mode material (as delimited by pairs given in
+% \cs{l_text_math_delims_tl} or as the argument to commands listed in
+% \cs{l_text_math_arg_tl}) is left contained in a pair of |$| delimiters.
+% Non-expandable functions present in the \meta{text} must either have a
+% defined equivalent (see \cs{text_declare_purify_equivalent:Nn}) or will
+% be removed from the result. Implicit tokens are converted to their
+% explicit equivalent.
+% \end{function}
+%
+% \begin{function}[added = 2020-03-05]
+% {
+% \text_declare_purify_equivalent:Nn ,
+% \text_declare_purify_equivalent:Ne
+% }
+% \begin{syntax}
+% \cs{text_declare_purify_equivalent:Nn} \meta{cmd} \Arg{replacement}
+% \end{syntax}
+% Declares that the \meta{replacement} tokens should be used whenever the
+% \meta{cmd} (a single token) is encountered. The \meta{replacement} tokens
+% should be expandable.
+% \end{function}
+%
+% \section{Control variables}
+%
+% \begin{variable}{\l_text_math_arg_tl}
+% Lists commands present in the \meta{text} where the argument of the
+% command should be treated as math mode material. The treatment here is
+% similar to \cs{l_text_math_delims_tl} but for a command rather than
+% paired delimiters.
+% \end{variable}
+%
+% \begin{variable}{\l_text_math_delims_tl}
+% Lists pairs of tokens which delimit (in-line) math mode content; such
+% content \emph{may} be excluded from processing.
+% \end{variable}
+%
+% \begin{variable}{\l_text_case_exclude_arg_tl}
+% Lists commands where the first mandatory argument is excluded from
+% case changing.
+% \end{variable}
+%
+% \begin{variable}{\l_text_expand_exclude_tl}
+% Lists commands which are excluded from expansion. This protection
+% includes everything up to and including their first braced argument.
+% \end{variable}
+%
+% \begin{variable}{\l_text_titlecase_check_letter_bool}
+% Controls how the start of titlecasing is handled: when \texttt{true}, the
+% first \emph{letter} in text is considered. The standard setting is
+% \texttt{true}.
+% \end{variable}
+%
+% \section{Mapping to graphemes}
+%
+% Grapheme splitting is implemented using the algorithm described in Unicode
+% Standard Annex \#29. This includes support for extended grapheme clusters.
+% Text starting with a line feed or carriage return character will drop this
+% due to standard \TeX{} processing. At present extended pictograms are
+% not supported: these may be added in a future release.
+%
+% \begin{function}[rEXP, added = 2022-08-04]{\text_map_function:nN}
+% \begin{syntax}
+% \cs{text_map_function:nN} \meta{text} \Arg{function}
+% \end{syntax}
+% Takes user input \meta{text} and expands as described for
+% \cs{text_expand:n}, then maps over the \emph{graphemes} within the
+% result, passing each grapheme to the \meta{function}.
+% Broadly a grapheme is a \enquote{user perceived character}:
+% the Unicode Consortium describe the decomposition of input to
+% graphemes in depth, and the approach used here implements that
+% algorithm. The \meta{function} should accept one argument as \meta{balanced
+% text}: this may be comprise codepoints or may be a control sequence.
+% With $8$-bit engines, the codepoint(s) themselves may of course be
+% made up of multiple bytes: the mapping will pass the correct codepoints
+% independent of the engine in use.
+% See also \cs{text_map_inline:nn}.
+% \end{function}
+%
+% \begin{function}[added = 2022-08-04]{\text_map_inline:nn}
+% \begin{syntax}
+% \cs{text_map_inline:nn} \meta{text} \Arg{inline function}
+% \end{syntax}
+% Takes user input \meta{text} and expands as described for
+% \cs{text_expand:n}, then maps over the \emph{graphemes} within the
+% result, passing each grapheme to the \meta{inline function}.
+% Broadly a grapheme is a \enquote{user perceived character}:
+% the Unicode Consortium describe the decomposition of input to
+% graphemes in depth, and the approach used here implements that
+% algorithm. The \meta{inline function} should consist of code which
+% receives the grapheme as \meta{balanced
+% text}: this may be comprise codepoints or may be a control sequence.
+% With $8$-bit engines, the codepoint(s) themselves may of course be
+% made up of multiple bytes: the mapping will pass the correct codepoints
+% independent of the engine in use.
+% See also \cs{text_map_function:nN}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2022-08-04]
+% {\text_map_break:, \text_map_break:n}
+% \begin{syntax}
+% \cs{text_map_break:}
+% \cs{text_map_break:n} \Arg{code}
+% \end{syntax}
+% Used to terminate a \cs[no-index]{text_map_\ldots} function before all
+% entries in the \meta{text} have been processed. This
+% normally takes place within a conditional statement.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3text} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=text>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \tl_if_head_eq_meaning_p:nN { o }
+% \end{macrocode}
+%
+% \subsection{Internal auxiliaries}
+%
+% \begin{variable}{\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\q_@@_nil}
+% Internal quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_nil
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[pTF]{\@@_quark_if_nil:n}
+% Branching quark conditional.
+% \begin{macrocode}
+\__kernel_quark_new_conditional:Nn \@@_quark_if_nil:n { TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\q_@@_recursion_tail,\q_@@_recursion_stop}
+% Internal recursion quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_recursion_tail
+\quark_new:N \q_@@_recursion_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_use_i_delimit_by_q_recursion_stop:nw}
+% Functions to gobble up to a quark.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_i_delimit_by_q_recursion_stop:nw
+ #1 #2 \q_@@_recursion_stop {#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_if_q_recursion_tail_stop_do:Nn}
+% \begin{macro}[EXP]{\@@_if_q_recursion_tail_stop_do:nn}
+% Functions to query recursion quarks.
+% \begin{macrocode}
+\__kernel_quark_new_test:N \@@_if_q_recursion_tail_stop_do:Nn
+\__kernel_quark_new_test:N \@@_if_q_recursion_tail_stop_do:nn
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\s_@@_recursion_tail,\s_@@_recursion_stop}
+% Internal scan marks quarks.
+% \begin{macrocode}
+\scan_new:N \s_@@_recursion_tail
+\scan_new:N \s_@@_recursion_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_use_i_delimit_by_s_recursion_stop:nw}
+% Functions to gobble up to a scan mark.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_i_delimit_by_s_recursion_stop:nw
+ #1 #2 \s_@@_recursion_stop {#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_if_s_recursion_tail_stop_do:Nn}
+% Functions to query recursion scan marks. Slower than a quark
+% test but needed to avoid issues in the outer expansion loop
+% with unterminated \tn{romannumeral} primitives.
+% \begin{macrocode}
+\cs_new:Npn \@@_if_s_recursion_tail_stop_do:Nn #1
+ {
+ \bool_lazy_and:nnTF
+ { \cs_if_eq_p:NN \s_@@_recursion_tail #1 }
+ { \str_if_eq_p:nn { \s_@@_recursion_tail } {#1} }
+ { \@@_use_i_delimit_by_s_recursion_stop:nw }
+ { \use_none:n }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Utilities}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_token_to_explicit:N ,
+% \@@_token_to_explicit_char:N ,
+% \@@_token_to_explicit_cs:N ,
+% \@@_token_to_explicit_cs_aux:N
+% }
+% \begin{macro}[EXP]{\@@_token_to_explicit:n}
+% \begin{macro}[EXP]
+% {
+% \@@_token_to_explicit_auxi:w ,
+% \@@_token_to_explicit_auxii:w ,
+% \@@_token_to_explicit_auxiii:w
+% }
+% The idea here is to take a token and ensure that if it's an implicit
+% char, we output the explicit version. Otherwise, the token needs to be
+% unchanged. First, we have to split between control sequences and everything
+% else.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_active:n { 0 }
+ \cs_new:Npn \@@_token_to_explicit:N #1
+ {
+ \if_catcode:w \exp_not:N #1
+ \if_catcode:w \scan_stop: \exp_not:N #1
+ \scan_stop:
+ \else:
+ \exp_not:N ^^@
+ \fi:
+ \exp_after:wN \@@_token_to_explicit_cs:N
+ \else:
+ \exp_after:wN \@@_token_to_explicit_char:N
+ \fi:
+ #1
+ }
+\group_end:
+% \end{macrocode}
+% For control sequences, we can check for macros versus other cases using
+% \cs{if_meaning:w}, then explicitly check for \tn{chardef} and
+% \tn{mathchardef}.
+% \begin{macrocode}
+\cs_new:Npn \@@_token_to_explicit_cs:N #1
+ {
+ \exp_after:wN \if_meaning:w \exp_not:N #1 #1
+ \exp_after:wN \use:nn \exp_after:wN
+ \@@_token_to_explicit_cs_aux:N
+ \else:
+ \exp_after:wN \exp_not:n
+ \fi:
+ {#1}
+ }
+\cs_new:Npn \@@_token_to_explicit_cs_aux:N #1
+ {
+ \bool_lazy_or:nnTF
+ { \token_if_chardef_p:N #1 }
+ { \token_if_mathchardef_p:N #1 }
+ {
+ \char_generate:nn {#1}
+ {
+ \if_int_compare:w \char_value_catcode:n {#1} = 10 \exp_stop_f:
+ 10
+ \else:
+ 12
+ \fi:
+ }
+ }
+ {#1}
+ }
+% \end{macrocode}
+% For character tokens, we need to filter out the implicit characters from
+% those that are explicit. That's done here, then if necessary we work out
+% the category code and generate the char. To avoid issues with alignment
+% tabs, that one is done by elimination rather than looking up the code
+% explicitly. The trick with finding the charcode is that the \TeX{}
+% messages are either \texttt{the \meta{something} character \meta{char}}
+% or \texttt{the \meta{type} \meta{char}}.
+% \begin{macrocode}
+\cs_new:Npn \@@_token_to_explicit_char:N #1
+ {
+ \if:w
+ \if_catcode:w ^ \exp_args:No \str_tail:n { \token_to_str:N #1 } ^
+ \token_to_str:N #1 #1
+ \else:
+ AB
+ \fi:
+ \exp_after:wN \exp_not:n
+ \else:
+ \exp_after:wN \@@_token_to_explicit:n
+ \fi:
+ {#1}
+ }
+\cs_new:Npn \@@_token_to_explicit:n #1
+ {
+ \exp_after:wN \@@_token_to_explicit_auxi:w
+ \int_value:w
+ \if_catcode:w \c_group_begin_token #1 1 \else:
+ \if_catcode:w \c_group_end_token #1 2 \else:
+ \if_catcode:w \c_math_toggle_token #1 3 \else:
+ \if_catcode:w ## #1 6 \else:
+ \if_catcode:w ^ #1 7 \else:
+ \if_catcode:w \c_math_subscript_token #1 8 \else:
+ \if_catcode:w \c_space_token #1 10 \else:
+ \if_catcode:w A #1 11 \else:
+ \if_catcode:w + #1 12 \else:
+ 4 \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi:
+ \exp_after:wN ;
+ \token_to_meaning:N #1 \s_@@_stop
+ }
+\cs_new:Npn \@@_token_to_explicit_auxi:w #1 ; #2 \s_@@_stop
+ {
+ \char_generate:nn
+ {
+ \if_int_compare:w #1 < 9 \exp_stop_f:
+ \exp_after:wN \@@_token_to_explicit_auxii:w
+ \else:
+ \exp_after:wN \@@_token_to_explicit_auxiii:w
+ \fi:
+ #2
+ }
+ {#1}
+ }
+\exp_last_unbraced:NNNNo \cs_new:Npn \@@_token_to_explicit_auxii:w
+ #1 { \tl_to_str:n { character ~ } } { ` }
+\cs_new:Npn \@@_token_to_explicit_auxiii:w #1 ~ #2 ~ { ` }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_char_catcode:N}
+% An idea from \pkg{l3char}: we need to get the category code of
+% a specific token, not the general case.
+% \begin{macrocode}
+\cs_new:Npn \@@_char_catcode:N #1
+ {
+ \if_catcode:w \exp_not:N #1 \c_math_toggle_token
+ 3
+ \else:
+ \if_catcode:w \exp_not:N #1 \c_alignment_token
+ 4
+ \else:
+ \if_catcode:w \exp_not:N #1 \c_math_superscript_token
+ 7
+ \else:
+ \if_catcode:w \exp_not:N #1 \c_math_subscript_token
+ 8
+ \else:
+ \if_catcode:w \exp_not:N #1 \c_space_token
+ 10
+ \else:
+ \if_catcode:w \exp_not:N #1 \c_catcode_letter_token
+ 11
+ \else:
+ \if_catcode:w \exp_not:N #1 \c_catcode_other_token
+ 12
+ \else:
+ 13
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, TF]{\@@_if_expandable:N}
+% Test for tokens that make sense to expand here: that is more
+% restrictive than the engine view.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_if_expandable:N #1 { T , F , TF }
+ {
+ \token_if_expandable:NTF #1
+ {
+ \bool_lazy_any:nTF
+ {
+ { \token_if_protected_macro_p:N #1 }
+ { \token_if_protected_long_macro_p:N #1 }
+ { \token_if_eq_meaning_p:NN \q_@@_recursion_tail #1 }
+ }
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Codepoint utilities}
+%
+% For working with codepoints in an engine-neutral way.
+%
+% \begin{macro}[EXP]{\@@_codepoint_process:nN, \@@_codepoint_process_aux:nN}
+% \begin{macro}[EXP]{\@@_codepoint_process:nNN}
+% \begin{macro}[EXP]{\@@_codepoint_process:nNNN}
+% \begin{macro}[EXP]{\@@_codepoint_process:nNNNN}
+% Grab a codepoint and apply some code to it: here |#1| should expect one
+% following \emph{balanced text}.
+% \begin{macrocode}
+\bool_lazy_or:nnTF
+ { \sys_if_engine_luatex_p: }
+ { \sys_if_engine_xetex_p: }
+ {
+ \cs_new:Npn \@@_codepoint_process:nN #1#2 { #1 {#2} }
+ }
+ {
+ \cs_new:Npe \@@_codepoint_process:nN #1#2
+ {
+ \exp_not:N \int_compare:nNnTF {`#2} > { "80 }
+ {
+ \sys_if_engine_pdftex:TF
+ { \exp_not:N \@@_codepoint_process_aux:nN }
+ {
+ \exp_not:N \int_compare:nNnTF {`#2} > { "FF }
+ { \exp_not:N \use:n }
+ { \exp_not:N \@@_codepoint_process_aux:nN }
+ }
+ }
+ { \exp_not:N \use:n }
+ {#1} #2
+ }
+ \cs_new:Npn \@@_codepoint_process_aux:nN #1#2
+ {
+ \int_compare:nNnTF { `#2 } < { "E0 }
+ { \@@_codepoint_process:nNN }
+ {
+ \int_compare:nNnTF { `#2 } < { "F0 }
+ { \@@_codepoint_process:nNNN }
+ { \@@_codepoint_process:nNNNN }
+ }
+ {#1} #2
+ }
+ \cs_new:Npn \@@_codepoint_process:nNN #1#2#3
+ { #1 {#2#3} }
+ \cs_new:Npn \@@_codepoint_process:nNNN #1#2#3#4
+ { #1 {#2#3#4} }
+ \cs_new:Npn \@@_codepoint_process:nNNNN #1#2#3#4#5
+ { #1 {#2#3#4#5} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP, pTF]{\@@_codepoint_compare:nNn}
+% \begin{macro}[EXP]
+% {\@@_codepoint_from_chars:Nw, \@@_codepoint_from_chars_aux:Nw}
+% \begin{macro}[EXP]{\@@_codepoint_from_chars:N}
+% \begin{macro}[EXP]{\@@_codepoint_from_chars:NN}
+% \begin{macro}[EXP]{\@@_codepoint_from_chars:NNN}
+% \begin{macro}[EXP]{\@@_codepoint_from_chars:NNNN}
+% Allows comparison for all engines using a first \enquote{character} followed
+% by a codepoint.
+% \begin{macrocode}
+\bool_lazy_or:nnTF
+ { \sys_if_engine_luatex_p: }
+ { \sys_if_engine_xetex_p: }
+ {
+ \prg_new_conditional:Npnn
+ \@@_codepoint_compare:nNn #1#2#3 { TF , p }
+ {
+ \int_compare:nNnTF {`#1} #2 {#3}
+ \prg_return_true: \prg_return_false:
+ }
+ \cs_new:Npn \@@_codepoint_from_chars:Nw #1 {`#1}
+ }
+ {
+ \prg_new_conditional:Npnn
+ \@@_codepoint_compare:nNn #1#2#3 { TF , p }
+ {
+ \int_compare:nNnTF { \@@_codepoint_from_chars:Nw #1 }
+ #2 {#3}
+ \prg_return_true: \prg_return_false:
+ }
+ \cs_new:Npe \@@_codepoint_from_chars:Nw #1
+ {
+ \exp_not:N \if_int_compare:w `#1 > "80 \exp_not:N \exp_stop_f:
+ \sys_if_engine_pdftex:TF
+ {
+ \exp_not:N \exp_after:wN
+ \exp_not:N \@@_codepoint_from_chars_aux:Nw
+ }
+ {
+ \exp_not:N \if_int_compare:w `#1 > "FF \exp_not:N \exp_stop_f:
+ \exp_not:N \exp_after:wN \exp_not:N \exp_after:wN
+ \exp_not:N \exp_after:wN
+ \exp_not:N \@@_codepoint_from_chars:N
+ \exp_not:N \else:
+ \exp_not:N \exp_after:wN \exp_not:N \exp_after:wN
+ \exp_not:N \exp_after:wN
+ \exp_not:N \@@_codepoint_from_chars_aux:Nw
+ \exp_not:N \fi:
+ }
+ \exp_not:N \else:
+ \exp_not:N \exp_after:wN \exp_not:N \@@_codepoint_from_chars:N
+ \exp_not:N \fi:
+ #1
+ }
+ \cs_new:Npn \@@_codepoint_from_chars_aux:Nw #1
+ {
+ \if_int_compare:w `#1 < "E0 \exp_stop_f:
+ \exp_after:wN \@@_codepoint_from_chars:NN
+ \else:
+ \if_int_compare:w `#1 < "F0 \exp_stop_f:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \@@_codepoint_from_chars:NNN
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \@@_codepoint_from_chars:NNNN
+ \fi:
+ \fi:
+ #1
+ }
+ \cs_new:Npn \@@_codepoint_from_chars:N #1 {`#1}
+ \cs_new:Npn \@@_codepoint_from_chars:NN #1#2
+ { (`#1 - "C0) * "40 + `#2 - "80 }
+ \cs_new:Npn \@@_codepoint_from_chars:NNN #1#2#3
+ { (`#1 - "E0) * "1000 + (`#2 - "80) * "40 + `#3 - "80 }
+ \cs_new:Npn \@@_codepoint_from_chars:NNNN #1#2#3#4
+ {
+ (`#1 - "F0) * "40000
+ + (`#2 - "80) * "1000
+ + (`#3 - "80) * "40
+ + `#4 - "80
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Configuration variables}
+%
+% \begin{variable}[deprecated]{\l_text_accents_tl, \l_text_letterlike_tl}
+% Used to be used for excluding these ideas from expansion: now deprecated.
+% \begin{macrocode}
+\tl_new:N \l_text_accents_tl
+\tl_new:N \l_text_letterlike_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_text_case_exclude_arg_tl}
+% Non-text arguments, including covering the case of \tn{protected@edef}
+% applied to \cs{cite}.
+% \begin{macrocode}
+\tl_new:N \l_text_case_exclude_arg_tl
+\tl_set:Ne \l_text_case_exclude_arg_tl
+ {
+ \exp_not:n { \begin \cite \end \label \ref }
+ \exp_not:c { cite ~ }
+ \exp_not:n { \babelshorthand }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_text_math_arg_tl}
+% Math mode as arguments.
+% \begin{macrocode}
+\tl_new:N \l_text_math_arg_tl
+\tl_set:Nn \l_text_math_arg_tl { \ensuremath }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_text_math_delims_tl}
+% Paired math mode delimiters.
+% \begin{macrocode}
+\tl_new:N \l_text_math_delims_tl
+\tl_set:Nn \l_text_math_delims_tl { $ $ \( \) }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_text_expand_exclude_tl}
+% Commands which need not to expand. We start with a somewhat historical
+% list, and tidy up if possible.
+% \begin{macrocode}
+\tl_new:N \l_text_expand_exclude_tl
+\tl_set:Nn \l_text_expand_exclude_tl
+ { \begin \cite \end \label \ref }
+\bool_lazy_and:nnT
+ { \str_if_eq_p:Vn \fmtname { LaTeX2e } }
+ { \tl_if_exist_p:N \@expl@finalise@setup@@@@ }
+ {
+ \tl_gput_right:Nn \@expl@finalise@setup@@@@
+ {
+ \tl_gput_right:Nn \@kernel@after@begindocument
+ {
+ \group_begin:
+ \cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \tl_clear:N \l_text_expand_exclude_tl
+ \tl_map_inline:nn {#1}
+ {
+ \bool_lazy_any:nF
+ {
+ { \token_if_protected_macro_p:N ##1 }
+ { \token_if_protected_long_macro_p:N ##1 }
+ {
+ \str_if_eq_p:ee
+ { \cs_replacement_spec:N ##1 }
+ { \exp_not:n { \protect ##1 } \c_space_tl }
+ }
+ }
+ { \tl_put_right:Nn \l_text_expand_exclude_tl {##1} }
+ }
+ }
+ \exp_args:NV \@@_tmp:w \l_text_expand_exclude_tl
+ \exp_args:NNNV \group_end:
+ \tl_set:Nn \l_text_expand_exclude_tl \l_text_expand_exclude_tl
+ }
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\l_@@_math_mode_tl}
+% Used to control math mode output: internal as there is a dedicated
+% setter.
+% \begin{macrocode}
+\tl_new:N \l_@@_math_mode_tl
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Expansion to formatted text}
+%
+% \begin{variable}{\c_@@_chardef_space_token, \c_@@_mathchardef_space_token}
+% \begin{variable}
+% {\c_@@_chardef_group_begin_token, \c_@@_mathchardef_group_begin_token}
+% \begin{variable}
+% {\c_@@_chardef_group_end_token, \c_@@_mathchardef_group_end_token}
+% Markers for implict char handling.
+% \begin{macrocode}
+\tex_global:D \tex_chardef:D \c_@@_chardef_space_token = `\ %
+\tex_global:D \tex_mathchardef:D \c_@@_mathchardef_space_token = `\ %
+\tex_global:D \tex_chardef:D \c_@@_chardef_group_begin_token = `\{ % `\}
+\tex_global:D \tex_mathchardef:D \c_@@_mathchardef_group_begin_token = `\{ % `\} `\{
+\tex_global:D \tex_chardef:D \c_@@_chardef_group_end_token = `\} % `\{
+\tex_global:D \tex_mathchardef:D \c_@@_mathchardef_group_end_token = `\} %
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\text_expand:n, \@@_expand:n}
+% \begin{macro}[EXP]{\@@_expand_result:n}
+% \begin{macro}[EXP]{\@@_expand_store:n, \@@_expand_store:o}
+% \begin{macro}[EXP]{\@@_expand_store:nw}
+% \begin{macro}[EXP]{\@@_expand_end:w}
+% \begin{macro}[EXP]{\@@_expand_loop:w}
+% \begin{macro}[EXP]{\@@_expand_group:n}
+% \begin{macro}[EXP]{\@@_expand_space:w}
+% \begin{macro}[EXP]{\@@_expand_N_type:N}
+% \begin{macro}[EXP]{\@@_expand_math_search:NNN}
+% \begin{macro}[EXP]{\@@_expand_math_loop:Nw}
+% \begin{macro}[EXP]{\@@_expand_math_N_type:NN}
+% \begin{macro}[EXP]{\@@_expand_math_group:Nn}
+% \begin{macro}[EXP]{\@@_expand_math_space:Nw}
+% \begin{macro}[EXP]
+% {
+% \@@_expand_explicit:N ,
+% \@@_expand_exclude:N
+% }
+% \begin{macro}[EXP]{\@@_expand_exclude_switch:Nnnnn}
+% \begin{macro}[EXP]{\@@_expand_exclude:nN}
+% \begin{macro}[EXP]{\@@_expand_exclude:NN}
+% \begin{macro}[EXP]{\@@_expand_exclude:Nw}
+% \begin{macro}[EXP]{\@@_expand_exclude:Nnn}
+% \begin{macro}[EXP]{\@@_expand_accent:N}
+% \begin{macro}[EXP]{\@@_expand_accent:NN}
+% \begin{macro}[EXP]{\@@_expand_letterlike:N}
+% \begin{macro}[EXP]{\@@_expand_letterlike:NN}
+% \begin{macro}[EXP]{\@@_expand_cs:N}
+% \begin{macro}[EXP]{\@@_expand_protect:w}
+% \begin{macro}[EXP]{\@@_expand_protect:N}
+% \begin{macro}[EXP]{\@@_expand_protect:nN}
+% \begin{macro}[EXP]{\@@_expand_protect:Nw}
+% \begin{macro}[EXP]{\@@_expand_testopt:N}
+% \begin{macro}[EXP]{\@@_expand_testopt:NNn}
+% \begin{macro}[EXP]{\@@_expand_encoding:N, \@@_expand_encoding_escape:N}
+% \begin{macro}[EXP]{\@@_expand_replace:N}
+% \begin{macro}[EXP]{\@@_expand_replace:n}
+% \begin{macro}[EXP]{\@@_expand_cs_expand:N}
+% \begin{macro}[EXP]{\@@_expand_unexpanded:w}
+% \begin{macro}[EXP]{\@@_expand_unexpanded_test:w}
+% \begin{macro}[EXP]{\@@_expand_unexpanded:N}
+% \begin{macro}[EXP]{\@@_expand_unexpanded:n}
+% After precautions against |&| tokens, start a simple loop: that of
+% course means that \enquote{text} cannot contain the two recursion
+% quarks. The loop here must be \texttt{f}-type expandable; we have
+% arbitrary user commands which might be protected \emph{and} take
+% arguments, and if the expansion code is used in a typesetting
+% context, that will otherwise explode. (The same issue applies more
+% clearly to case changing: see the example there.) The outer
+% loop has to use scan marks as delimiters to protect against
+% unterminated \tn{romannumeral} usage in the input.
+% \begin{macrocode}
+\cs_new:Npn \text_expand:n #1
+ {
+ \__kernel_exp_not:w \exp_after:wN
+ {
+ \exp:w
+ \@@_expand:n {#1}
+ }
+ }
+\cs_new:Npn \@@_expand:n #1
+ {
+ \group_align_safe_begin:
+ \@@_expand_loop:w #1
+ \s_@@_recursion_tail \s_@@_recursion_stop
+ \@@_expand_result:n { }
+ }
+% \end{macrocode}
+% The approach to making the code \texttt{f}-type expandable is to usee
+% a marker result token and to shuffle the collected tokens
+% \begin{macrocode}
+\cs_new:Npn \@@_expand_store:n #1
+ { \@@_expand_store:nw {#1} }
+\cs_generate_variant:Nn \@@_expand_store:n { o }
+\cs_new:Npn \@@_expand_store:nw #1#2 \@@_expand_result:n #3
+ { #2 \@@_expand_result:n { #3 #1 } }
+\cs_new:Npn \@@_expand_end:w #1 \@@_expand_result:n #2
+ {
+ \group_align_safe_end:
+ \exp_end:
+ #2
+ }
+% \end{macrocode}
+% The main loop is a standard \enquote{tl action}; groups are handled
+% recursively, while spaces are just passed through. Thus all of the
+% action is in handling \texttt{N}-type tokens.
+% \begin{macrocode}
+\cs_new:Npn \@@_expand_loop:w #1 \s_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#1}
+ { \@@_expand_N_type:N }
+ {
+ \tl_if_head_is_group:nTF {#1}
+ { \@@_expand_group:n }
+ { \@@_expand_space:w }
+ }
+ #1 \s_@@_recursion_stop
+ }
+\cs_new:Npn \@@_expand_group:n #1
+ {
+ \@@_expand_store:o
+ {
+ \exp_after:wN
+ {
+ \exp:w
+ \@@_expand:n {#1}
+ }
+ }
+ \@@_expand_loop:w
+ }
+\exp_last_unbraced:NNo \cs_new:Npn \@@_expand_space:w \c_space_tl
+ {
+ \@@_expand_store:n { ~ }
+ \@@_expand_loop:w
+ }
+% \end{macrocode}
+% The first step in dealing with \texttt{N}-type tokens is to look for
+% math mode material: that needs to be left alone. The starting function
+% has to be split into two as we need \cs{quark_if_recursion_tail_stop:N}
+% first before we can trigger the search. We then look for matching
+% pairs of delimiters, allowing for the case where math mode starts
+% but does not end. Within math mode, we simply pass all the tokens
+% through unchanged, just checking the \texttt{N}-type ones against the
+% end marker.
+% \begin{macrocode}
+\cs_new:Npn \@@_expand_N_type:N #1
+ {
+ \@@_if_s_recursion_tail_stop_do:Nn #1
+ { \@@_expand_end:w }
+ \exp_after:wN \@@_expand_math_search:NNN
+ \exp_after:wN #1 \l_text_math_delims_tl
+ \q_@@_recursion_tail \q_@@_recursion_tail
+ \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_expand_math_search:NNN #1#2#3
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #2
+ { \@@_expand_explicit:N #1 }
+ \token_if_eq_meaning:NNTF #1 #2
+ {
+ \@@_use_i_delimit_by_q_recursion_stop:nw
+ {
+ \@@_expand_store:n {#1}
+ \@@_expand_math_loop:Nw #3
+ }
+ }
+ { \@@_expand_math_search:NNN #1 }
+ }
+\cs_new:Npn \@@_expand_math_loop:Nw #1#2 \s_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#2}
+ { \@@_expand_math_N_type:NN }
+ {
+ \tl_if_head_is_group:nTF {#2}
+ { \@@_expand_math_group:Nn }
+ { \@@_expand_math_space:Nw }
+ }
+ #1#2 \s_@@_recursion_stop
+ }
+\cs_new:Npn \@@_expand_math_N_type:NN #1#2
+ {
+ \@@_if_s_recursion_tail_stop_do:Nn #2
+ { \@@_expand_end:w }
+ \token_if_eq_meaning:NNF #2 \exp_not:N
+ { \@@_expand_store:n {#2} }
+ \token_if_eq_meaning:NNTF #2 #1
+ { \@@_expand_loop:w }
+ { \@@_expand_math_loop:Nw #1 }
+ }
+\cs_new:Npn \@@_expand_math_group:Nn #1#2
+ {
+ \@@_expand_store:n { {#2} }
+ \@@_expand_math_loop:Nw #1
+ }
+\exp_after:wN \cs_new:Npn \exp_after:wN \@@_expand_math_space:Nw
+ \exp_after:wN # \exp_after:wN 1 \c_space_tl
+ {
+ \@@_expand_store:n { ~ }
+ \@@_expand_math_loop:Nw #1
+ }
+% \end{macrocode}
+% At this stage, either we have a control sequence or a simple character:
+% split and handle. The need to check for non-protected actives arises
+% from handling of legacy input encodings: they need to end up in a
+% representation we can deal with in further processing. The tests for
+% explicit parts of the \LaTeXe{} UTF-8 mechanism cover the case of
+% bookmarks, where definitions change and are no longer protected. The
+% same is true for \pkg{babel} shorthands.
+% \begin{macrocode}
+\cs_new:Npn \@@_expand_explicit:N #1
+ {
+ \token_if_cs:NTF #1
+ { \@@_expand_exclude:N #1 }
+ {
+ \bool_lazy_and:nnTF
+ { \token_if_active_p:N #1 }
+ {
+ ! \bool_lazy_any_p:n
+ {
+ { \token_if_protected_macro_p:N #1 }
+ { \token_if_protected_long_macro_p:N #1 }
+ { \tl_if_head_eq_meaning_p:oN {#1} \UTFviii@two@octets }
+ { \tl_if_head_eq_meaning_p:oN {#1} \UTFviii@three@octets }
+ { \tl_if_head_eq_meaning_p:oN {#1} \UTFviii@four@octets }
+ { \tl_if_head_eq_meaning_p:oN {#1} \active@prefix }
+ }
+ }
+ { \exp_after:wN \@@_expand_loop:w #1 }
+ {
+ \@@_expand_store:n {#1}
+ \@@_expand_loop:w
+ }
+ }
+ }
+% \end{macrocode}
+% Next we exclude math commands: this is mainly as there \emph{might} be an
+% \cs{ensuremath}. The switching command for case needs special handling
+% as it has to work by meaning.
+% \begin{macrocode}
+\cs_new:Npn \@@_expand_exclude:N #1
+ {
+ \cs_if_eq:NNTF #1 \text_case_switch:nnnn
+ { \@@_expand_exclude_switch:Nnnnn #1 }
+ {
+ \exp_args:Ne \@@_expand_exclude:nN
+ {
+ \exp_not:V \l_text_math_arg_tl
+ \exp_not:V \l_text_expand_exclude_tl
+ \exp_not:V \l_text_case_exclude_arg_tl
+ }
+ #1
+ }
+ }
+\cs_new:Npn \@@_expand_exclude_switch:Nnnnn #1#2#3#4#5
+ {
+ \@@_expand_store:n { #1 {#2} {#3} {#4} {#5} }
+ \@@_expand_loop:w
+ }
+\cs_new:Npn \@@_expand_exclude:nN #1#2
+ {
+ \@@_expand_exclude:NN #2 #1
+ \q_@@_recursion_tail \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_expand_exclude:NN #1#2
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #2
+ { \@@_expand_accent:N #1 }
+ \str_if_eq:nnTF {#1} {#2}
+ {
+ \@@_use_i_delimit_by_q_recursion_stop:nw
+ { \@@_expand_exclude:Nw #1 }
+ }
+ { \@@_expand_exclude:NN #1 }
+ }
+\cs_new:Npn \@@_expand_exclude:Nw #1#2#
+ { \@@_expand_exclude:Nnn #1 {#2} }
+\cs_new:Npn \@@_expand_exclude:Nnn #1#2#3
+ {
+ \@@_expand_store:n { #1#2 {#3} }
+ \@@_expand_loop:w
+ }
+% \end{macrocode}
+% Accents.
+% \begin{macrocode}
+\cs_new:Npn \@@_expand_accent:N #1
+ {
+ \exp_after:wN \@@_expand_accent:NN \exp_after:wN
+ #1 \l_text_accents_tl
+ \q_@@_recursion_tail \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_expand_accent:NN #1#2
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #2
+ { \@@_expand_letterlike:N #1 }
+ \cs_if_eq:NNTF #2 #1
+ {
+ \@@_use_i_delimit_by_q_recursion_stop:nw
+ {
+ \@@_expand_store:n {#1}
+ \@@_expand_loop:w
+ }
+ }
+ { \@@_expand_accent:NN #1 }
+ }
+% \end{macrocode}
+% Another list of exceptions: these ones take no arguments so are
+% easier to handle.
+% \begin{macrocode}
+\cs_new:Npn \@@_expand_letterlike:N #1
+ {
+ \exp_after:wN \@@_expand_letterlike:NN \exp_after:wN
+ #1 \l_text_letterlike_tl
+ \q_@@_recursion_tail \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_expand_letterlike:NN #1#2
+ {
+ \@@_if_q_recursion_tail_stop_do:Nn #2
+ { \@@_expand_cs:N #1 }
+ \cs_if_eq:NNTF #2 #1
+ {
+ \@@_use_i_delimit_by_q_recursion_stop:nw
+ {
+ \@@_expand_store:n {#1}
+ \@@_expand_loop:w
+ }
+ }
+ { \@@_expand_letterlike:NN #1 }
+ }
+% \end{macrocode}
+% \LaTeXe{}'s \cs{protect} makes life interesting. Where possible, we
+% simply remove it and replace with the \enquote{parent} command; of course,
+% the \cs{protect} might be explicit, in which case we need to leave it alone.
+% That includes the case where it's not even followed by an \texttt{N}-type
+% token. There is also the case of a straight \tn{@protected@testopt} to
+% cover.
+% \begin{macrocode}
+\cs_new:Npe \@@_expand_cs:N #1
+ {
+ \exp_not:N \str_if_eq:nnTF {#1} { \exp_not:N \protect }
+ { \exp_not:N \@@_expand_protect:w }
+ {
+ \bool_lazy_and:nnTF
+ { \cs_if_exist_p:N \fmtname }
+ { \str_if_eq_p:Vn \fmtname { LaTeX2e } }
+ { \exp_not:N \@@_expand_testopt:N #1 }
+ { \exp_not:N \@@_expand_replace:N #1 }
+ }
+ }
+\cs_new:Npn \@@_expand_protect:w #1 \s_@@_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#1}
+ { \@@_expand_protect:N }
+ {
+ \@@_expand_store:n { \protect }
+ \@@_expand_loop:w
+ }
+ #1 \s_@@_recursion_stop
+ }
+\cs_new:Npn \@@_expand_protect:N #1
+ {
+ \@@_if_s_recursion_tail_stop_do:Nn #1
+ {
+ \@@_expand_store:n { \protect }
+ \@@_expand_end:w
+ }
+ \exp_args:Ne \@@_expand_protect:nN
+ { \cs_to_str:N #1 } #1
+ }
+\cs_new:Npn \@@_expand_protect:nN #1#2
+ { \@@_expand_protect:Nw #2 #1 \q_@@_nil #1 ~ \q_@@_nil \q_@@_nil \s_@@_stop }
+\cs_new:Npn \@@_expand_protect:Nw #1 #2 ~ \q_@@_nil #3 \q_@@_nil #4 \s_@@_stop
+ {
+ \@@_quark_if_nil:nTF {#4}
+ {
+ \cs_if_exist:cTF {#2}
+ { \exp_args:Ne \@@_expand_store:n { \exp_not:c {#2} } }
+ { \@@_expand_store:n { \protect #1 } }
+ }
+ { \@@_expand_store:n { \protect #1 } }
+ \@@_expand_loop:w
+ }
+\cs_new:Npn \@@_expand_testopt:N #1
+ {
+ \token_if_eq_meaning:NNTF #1 \@protected@testopt
+ { \@@_expand_testopt:NNn }
+ { \@@_expand_encoding:N #1 }
+ }
+\cs_new:Npn \@@_expand_testopt:NNn #1#2#3
+ {
+ \@@_expand_store:n {#1}
+ \@@_expand_loop:w
+ }
+% \end{macrocode}
+% Deal with encoding-specific commands
+% \begin{macrocode}
+\cs_new:Npn \@@_expand_encoding:N #1
+ {
+ \bool_lazy_or:nnTF
+ { \cs_if_eq_p:NN #1 \@current@cmd }
+ { \cs_if_eq_p:NN #1 \@changed@cmd }
+ { \exp_after:wN \@@_expand_loop:w \@@_expand_encoding_escape:NN }
+ { \@@_expand_replace:N #1 }
+ }
+\cs_new:Npn \@@_expand_encoding_escape:NN #1#2 { \exp_not:n {#1} }
+% \end{macrocode}
+% See if there is a dedicated replacement, and if there is, insert it.
+% \begin{macrocode}
+\cs_new:Npn \@@_expand_replace:N #1
+ {
+ \bool_lazy_and:nnTF
+ { \cs_if_exist_p:c { l_@@_expand_ \token_to_str:N #1 _tl } }
+ {
+ \bool_lazy_or_p:nn
+ { \token_if_cs_p:N #1 }
+ { \token_if_active_p:N #1 }
+ }
+ {
+ \exp_args:Nv \@@_expand_replace:n
+ { l_@@_expand_ \token_to_str:N #1 _tl }
+ }
+ { \@@_expand_cs_expand:N #1 }
+ }
+\cs_new:Npn \@@_expand_replace:n #1 { \@@_expand_loop:w #1 }
+% \end{macrocode}
+% Finally, expand any macros which can be: this then loops back around to
+% deal with what they produce. The only issue is if the token is
+% \cs{exp_not:n}, as that must apply to the following balanced text.
+% \begin{macrocode}
+\cs_new:Npn \@@_expand_cs_expand:N #1
+ {
+ \@@_if_expandable:NTF #1
+ {
+ \token_if_eq_meaning:NNTF #1 \exp_not:n
+ { \@@_expand_unexpanded:w }
+ { \exp_after:wN \@@_expand_loop:w #1 }
+ }
+ {
+ \@@_expand_store:n {#1}
+ \@@_expand_loop:w
+ }
+ }
+% \end{macrocode}
+% Since \cs{exp_not:n} is actually a primitive, it allows a strange syntax
+% and it particular the primitive expands what follows and discards spaces
+% and \cs{scan_stop:} until finding a braced argument (the opening brace
+% can be implicit but we will not support this here). Here, we repeatedly
+% |f|-expand after such an \cs{exp_not:n}, and test what follows. If
+% it is a brace group, then we found the intended argument of
+% \cs{exp_not:n}. If it is a space, then the next |f|-expansion will
+% eliminate it. If it is an |N|-type token then
+% \cs{@@_expand_unexpanded:N} leaves the token to be expanded if it is
+% expandable, and otherwise removes it, assuming that it is
+% \cs{scan_stop:}. This silently hides errors when \cs{exp_not:n} is
+% incorrectly followed by some non-expandable token other than
+% \cs{scan_stop:}, but this should be pretty rare, and there is no good
+% error recovery anyways.
+% \begin{macrocode}
+\cs_new:Npn \@@_expand_unexpanded:w
+ {
+ \exp_after:wN \@@_expand_unexpanded_test:w
+ \exp:w \exp_end_continue_f:w
+ }
+\cs_new:Npn \@@_expand_unexpanded_test:w #1 \s_@@_recursion_stop
+ {
+ \tl_if_head_is_group:nTF {#1}
+ { \@@_expand_unexpanded:n }
+ {
+ \@@_expand_unexpanded:w
+ \tl_if_head_is_N_type:nT {#1} { \@@_expand_unexpanded:N }
+ }
+ #1 \s_@@_recursion_stop
+ }
+\cs_new:Npn \@@_expand_unexpanded:N #1
+ {
+ \exp_after:wN \if_meaning:w \exp_not:N #1 #1
+ \else:
+ \exp_after:wN #1
+ \fi:
+ }
+\cs_new:Npn \@@_expand_unexpanded:n #1
+ {
+ \@@_expand_store:n {#1}
+ \@@_expand_loop:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \text_declare_expand_equivalent:Nn ,
+% \text_declare_expand_equivalent:cn
+% }
+% Create equivalents to allow replacement.
+% \begin{macrocode}
+\cs_new_protected:Npn \text_declare_expand_equivalent:Nn #1#2
+ {
+ \tl_clear_new:c { l_@@_expand_ \token_to_str:N #1 _tl }
+ \tl_set:cn { l_@@_expand_ \token_to_str:N #1 _tl } {#2}
+ }
+\cs_generate_variant:Nn \text_declare_expand_equivalent:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% Prevent expansion of various standard values.
+% \begin{macrocode}
+\tl_map_inline:nn
+ { \` \' \^ \~ \= \u \. \" \r \H \v \d \c \k \b \t }
+ { \text_declare_expand_equivalent:Nn #1 { \exp_not:n {#1} } }
+\tl_map_inline:nn
+ {
+ \AA \aa
+ \AE \ae
+ \DH \dh
+ \DJ \dj
+ \IJ \ij
+ \L \l
+ \NG \ng
+ \O \o
+ \OE \oe
+ \SS \ss
+ \TH \th
+ }
+ { \text_declare_expand_equivalent:Nn #1 { \exp_not:n {#1} } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3tl-analysis.dtx b/macros/latex-dev/required/l3kernel/l3tl-analysis.dtx
new file mode 100644
index 0000000000..a4141dcfe4
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3tl-analysis.dtx
@@ -0,0 +1,1660 @@
+% \iffalse meta-comment
+%
+%% File: l3tl-analysis.dtx
+%
+% Copyright (C) 2011-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+%
+% \title{^^A
+% The \pkg{l3tl-analysis} module\\ Analysing token lists^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% This module provides functions that are particularly useful in the
+% \pkg{l3regex} module for mapping through a token list one \meta{token}
+% at a time (including begin-group/end-group tokens). For
+% \cs{tl_analysis_map_inline:Nn} or \cs{tl_analysis_map_inline:nn}, the
+% token list is given as an argument; the analogous function
+% \cs{peek_analysis_map_inline:n} documented in \pkg{l3token} finds
+% tokens in the input stream instead. In both cases the user provides
+% \meta{inline code} that receives three arguments for each
+% \meta{token}:
+% \begin{itemize}
+% \item \meta{tokens}, which both \texttt{o}-expand and
+% \texttt{e}/\texttt{x}-expand to the \meta{token}. The detailed form of
+% \meta{tokens} may change in later releases.
+% \item \meta{char code}, a decimal representation of the character
+% code of the \meta{token}, $-1$ if it is a control sequence.
+% \item \meta{catcode}, a capital hexadecimal digit which denotes the
+% category code of the \meta{token} (0:~control sequence,
+% 1:~begin-group, 2:~end-group, 3:~math shift, 4:~alignment tab,
+% 6:~parameter, 7:~superscript, 8:~subscript, A:~space, B:~letter,
+% C:~other, D:~active). This can be converted to an integer by
+% writing |"|\meta{catcode}.
+% \end{itemize}
+% In addition, there is a debugging function \cs{tl_analysis_show:n},
+% very similar to the \cs[no-index]{ShowTokens} macro from the \pkg{ted} package.
+%
+% \begin{function}[added = 2021-05-11]
+% {
+% \tl_analysis_show:N, \tl_analysis_show:n,
+% \tl_analysis_log:N, \tl_analysis_log:n
+% }
+% \begin{syntax}
+% \cs{tl_analysis_show:n} \Arg{token list}
+% \cs{tl_analysis_log:n} \Arg{token list}
+% \end{syntax}
+% Displays to the terminal (or log) the detailed decomposition of the
+% \meta{token list} into tokens, showing the category code of each
+% character token, the meaning of control sequences and active
+% characters, and the value of registers.
+% \end{function}
+%
+% \begin{function}[added = 2018-04-09, updated = 2022-03-26]
+% {\tl_analysis_map_inline:nn, \tl_analysis_map_inline:Nn}
+% \begin{syntax}
+% \cs{tl_analysis_map_inline:nn} \Arg{token list} \Arg{inline function}
+% \end{syntax}
+% Applies the \meta{inline function} to each individual \meta{token}
+% in the \meta{token list}. The \meta{inline function} receives three
+% arguments as explained above. As all other mappings the mapping is
+% done at the current group level, \emph{i.e.}~any local assignments
+% made by the \meta{inline function} remain in effect after the loop.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3tl-analysis} implementation}
+%
+% \begin{macrocode}
+%<@@=tl>
+% \end{macrocode}
+%
+% \subsection{Internal functions}
+%
+% \begin{variable}{\s_@@}
+% The format used to store token lists internally uses the scan mark
+% \cs{s_@@} as a delimiter.
+% \end{variable}
+%
+% \subsection{Internal format}
+%
+% The task of the \pkg{l3tl-analysis} module is to convert token lists
+% to an internal format which allows us to extract all the relevant
+% information about individual tokens (category code, character code),
+% as well as reconstruct the token list quickly. This internal format is
+% used in \pkg{l3regex} where we need to support arbitrary tokens, and
+% it is used in conversion functions in \pkg{l3str-convert}, where we wish to
+% support clusters of characters instead of single tokens.
+%
+% We thus need a way to encode any \meta{token} (even begin-group and
+% end-group character tokens) in a way amenable to manipulating tokens
+% individually. The best we can do is to find \meta{tokens} which both
+% \texttt{o}-expand and \texttt{e}/\texttt{x}-expand to the given
+% \meta{token}. Collecting more information about the category code and
+% character code is also useful for regular expressions, since most
+% regexes are catcode-agnostic. The internal format thus takes the form
+% of a succession of items of the form
+% \begin{quote}
+% \meta{tokens} \cs{s_@@} \meta{catcode} \meta{char code} \cs{s_@@}
+% \end{quote}
+% The \meta{tokens} \texttt{o}- \emph{and} \texttt{e}/\texttt{x}-expand to the
+% original token in the token list or to the cluster of tokens
+% corresponding to one Unicode character in the given encoding (for
+% \pkg{l3str-convert}). The \meta{catcode} is given as a single hexadecimal
+% digit, $0$ for control sequences. The \meta{char code} is given as a
+% decimal number, $-1$ for control sequences.
+%
+% Using delimited arguments lets us build the \meta{tokens}
+% progressively when doing an encoding conversion in \pkg{l3str-convert}. On the
+% other hand, the delimiter \cs{s_@@} may not appear unbraced in
+% \meta{tokens}. This is not a problem because we are careful to wrap
+% control sequences in braces (as an argument to \cs{exp_not:n}) when
+% converting from a general token list to the internal format.
+%
+% The current rule for converting a \meta{token} to a balanced set of
+% \meta{tokens} which both \texttt{o}-expands and \texttt{e}/\texttt{x}-expands to
+% it is the following.
+% \begin{itemize}
+% \item A control sequence |\cs| becomes |\exp_not:n { \cs }|
+% \cs{s_@@} $0$ $-1$ \cs{s_@@}.
+% \item A begin-group character |{| becomes \cs{exp_after:wN} |{|
+% \cs{if_false:} |}| \cs{fi:} \cs{s_@@} $1$ \meta{char code}
+% \cs{s_@@}.
+% \item An end-group character |}| becomes \cs{if_false:} |{| \cs{fi:}
+% |}| \cs{s_@@} $2$ \meta{char code} \cs{s_@@}.
+% \item A character with any other category code becomes
+% \cs{exp_not:n} \Arg{character} \cs{s_@@} \meta{hex catcode}
+% \meta{char code} \cs{s_@@}.
+% \end{itemize}
+% In contrast, for \cs{peek_analysis_map_inline:n} we must allow for an
+% input stream containing \tn{outer} macros, so that wrapping all
+% control sequences in \cs{exp_not:n} is unsafe. Instead, we write the
+% more elaborate \cs{__kernel_exp_not:w} \cs{exp_after:wN} |{|
+% \cs{exp_not:N} |\cs| |}|. (On the other hand we make a better effort
+% by avoiding \cs{exp_not:n} for characters other than active and macro
+% parameters.)
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \subsection{Variables and helper functions}
+%
+% \begin{variable}{\s_@@}
+% The scan mark \cs{s_@@} is used as a delimiter in the internal
+% format. This is more practical than using a quark, because we would
+% then need to control expansion much more carefully: compare
+% \cs{int_value:w} |`#1| \cs{s_@@} with \cs{int_value:w} |`#1|
+% \cs{exp_stop_f:} \cs{exp_not:N} \cs{q_mark} to extract a character
+% code followed by the delimiter in an \texttt{e}-expansion.
+% \begin{macrocode}
+\scan_new:N \s_@@
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {\l_@@_analysis_token, \l_@@_analysis_char_token}
+% The tokens in the token list are probed with the \TeX{} primitive
+% \tn{futurelet}. We use \cs{l_@@_analysis_token} in that
+% construction. In some cases, we convert the following token to a
+% string before probing it: then the token variable used is
+% \cs{l_@@_analysis_char_token}.
+% \begin{macrocode}
+\cs_new_eq:NN \l_@@_analysis_token ?
+\cs_new_eq:NN \l_@@_analysis_char_token ?
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_peek_code_tl}
+% Holds some code to be run once the next token has been fully
+% analysed in \cs{peek_analysis_map_inline:n}.
+% \begin{macrocode}
+\tl_new:N \l_@@_peek_code_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_peek_catcodes_tl}
+% A token list containing the character number~$32$ (space) with all
+% possible category codes except $1$ and $2$ (begin-group and
+% end-group). Why $32$? Because some \LuaTeX{} versions only allow
+% creation of catcode~$10$ (space) tokens with this character code, so
+% that we decided to make \cs{char_generate:nn} refuse to create such
+% weird spaces as well. We do not include the macro parameter case
+% (catcode~$6$) because it cannot be used as a macro delimiter.
+% \begin{macrocode}
+\group_begin:
+\char_set_active_eq:NN \ \scan_stop:
+\tl_const:Ne \c_@@_peek_catcodes_tl
+ {
+ \char_generate:nn { 32 } { 3 } 3
+ \char_generate:nn { 32 } { 4 } 4
+ \char_generate:nn { 32 } { 7 } 7
+ \char_generate:nn { 32 } { 8 } 8
+ \c_space_tl \token_to_str:N A
+ \char_generate:nn { 32 } { 11 } \token_to_str:N B
+ \char_generate:nn { 32 } { 12 } \token_to_str:N C
+ \char_generate:nn { 32 } { 13 } \token_to_str:N D
+ }
+\group_end:
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_analysis_normal_int}
+% The number of normal (\texttt{N}-type argument) tokens since the
+% last special token.
+% \begin{macrocode}
+\int_new:N \l_@@_analysis_normal_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_analysis_index_int}
+% During the first pass, this is the index in the array being built.
+% During the second pass, it is equal to the maximum index in the
+% array from the first pass.
+% \begin{macrocode}
+\int_new:N \l_@@_analysis_index_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_analysis_nesting_int}
+% Nesting depth of explicit begin-group and end-group characters
+% during the first pass. This lets us detect the end of the token list
+% without a reserved end-marker.
+% \begin{macrocode}
+\int_new:N \l_@@_analysis_nesting_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_analysis_type_int}
+% When encountering special characters, we record their \enquote{type}
+% in this integer.
+% \begin{macrocode}
+\int_new:N \l_@@_analysis_type_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_analysis_result_tl}
+% The result of the conversion is stored in this token list, with a
+% succession of items of the form
+% \begin{quote}
+% \meta{tokens} \cs{s_@@} \meta{catcode} \meta{char code} \cs{s_@@}
+% \end{quote}
+% \begin{macrocode}
+\tl_new:N \g_@@_analysis_result_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_analysis_extract_charcode:}
+% \begin{macro}[EXP]{\@@_analysis_extract_charcode_aux:w}
+% Extracting the character code from the meaning of
+% \cs{l_@@_analysis_token}. This has no error checking, and should
+% only be assumed to work for begin-group and end-group character
+% tokens. It produces a number in the form |`|\meta{char}.
+% \begin{macrocode}
+\cs_new:Npn \@@_analysis_extract_charcode:
+ {
+ \exp_after:wN \@@_analysis_extract_charcode_aux:w
+ \token_to_meaning:N \l_@@_analysis_token
+ }
+\cs_new:Npn \@@_analysis_extract_charcode_aux:w #1 ~ #2 ~ { ` }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_analysis_cs_space_count:NN}
+% \begin{macro}[EXP]{\@@_analysis_cs_space_count:w}
+% \begin{macro}[EXP]{\@@_analysis_cs_space_count_end:w}
+% Counts the number of spaces in the string representation of its
+% second argument, as well as the number of characters following the
+% last space in that representation, and feeds the two numbers as
+% semicolon-delimited arguments to the first argument. When this
+% function is used, the escape character is printable and non-space.
+% \begin{macrocode}
+\cs_new:Npn \@@_analysis_cs_space_count:NN #1 #2
+ {
+ \exp_after:wN #1
+ \int_value:w \int_eval:w 0
+ \exp_after:wN \@@_analysis_cs_space_count:w
+ \token_to_str:N #2
+ \fi: \@@_analysis_cs_space_count_end:w ; ~ !
+ }
+\cs_new:Npn \@@_analysis_cs_space_count:w #1 ~
+ {
+ \if_false: #1 #1 \fi:
+ + 1
+ \@@_analysis_cs_space_count:w
+ }
+\cs_new:Npn \@@_analysis_cs_space_count_end:w ; #1 \fi: #2 !
+ { \exp_after:wN ; \int_value:w \str_count_ignore_spaces:n {#1} ; }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Plan of attack}
+%
+% Our goal is to produce a token list of the form roughly
+% \begin{quote}
+% \meta{token 1} \cs{s_@@} \meta{catcode 1} \meta{char code 1} \cs{s_@@} \\
+% \meta{token 2} \cs{s_@@} \meta{catcode 2} \meta{char code 2} \cs{s_@@} \\
+% \ldots{}
+% \meta{token N} \cs{s_@@} \meta{catcode N} \meta{char code N} \cs{s_@@}
+% \end{quote}
+% Most but not all tokens can be grabbed as an undelimited
+% (\texttt{N}-type) argument by \TeX{}. The plan is to have a two pass
+% system. In the first pass, locate special tokens, and store them in
+% various \tn{toks} registers. In the second pass, which is done within
+% an \texttt{e}-expanding assignment, normal tokens are taken in as
+% \texttt{N}-type arguments, and special tokens are retrieved from the
+% \tn{toks} registers, and removed from the input stream by some means.
+% The whole process takes linear time, because we avoid building the
+% result one item at a time.
+%
+% We make the escape character printable (backslash, but this later
+% oscillates between slash and backslash): this allows us to
+% distinguish characters from control sequences.
+%
+% A token has two characteristics: its \tn{meaning}, and what it looks
+% like for \TeX{} when it is in scanning mode (\emph{e.g.}, when
+% capturing parameters for a macro). For our purposes, we distinguish
+% the following meanings:
+% \begin{itemize}
+% \item begin-group token (category code $1$), either space (character
+% code $32$), or non-space;
+% \item end-group token (category code $2$), either space (character
+% code $32$), or non-space;
+% \item space token (category code $10$, character code $32$);
+% \item anything else (then the token is always an \texttt{N}-type
+% argument).
+% \end{itemize}
+% The token itself can \enquote{look like} one of the following
+% \begin{itemize}
+% \item a non-active character, in which case its meaning is
+% automatically that associated to its character code and category
+% code, we call it \enquote{true} character;
+% \item an active character;
+% \item a control sequence.
+% \end{itemize}
+% The only tokens which are not valid \texttt{N}-type arguments are true
+% begin-group characters, true end-group characters, and true spaces.
+% We detect those characters by scanning ahead with \tn{futurelet},
+% then distinguishing true characters from control sequences set equal
+% to them using the \tn{string} representation.
+%
+% The second pass is a simple exercise in expandable loops.
+%
+% \begin{macro}{\@@_analysis:n}
+% Everything is done within a group, and all definitions are
+% local. We use \cs{group_align_safe_begin/end:} to avoid problems in
+% case \cs{@@_analysis:n} is used within an alignment and its argument
+% contains alignment tab tokens.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_analysis:n #1
+ {
+ \group_begin:
+ \group_align_safe_begin:
+ \@@_analysis_a:n {#1}
+ \@@_analysis_b:n {#1}
+ \group_align_safe_end:
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Disabling active characters}
+%
+% \begin{macro}{\@@_analysis_disable:n}
+% Active characters can cause problems later on in the processing, so
+% we provide a way to disable them, by setting them to
+% \texttt{undefined}. Since Unicode contains too many characters to
+% loop over all of them, we instead do this whenever we encounter a
+% character. For \pTeX{} and \upTeX{} we skip characters beyond
+% $[0,255]$ because \tn{lccode} only allows those values.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_active:N \^^@
+ \cs_new_protected:Npn \@@_analysis_disable:n #1
+ {
+ \tex_lccode:D 0 = #1 \exp_stop_f:
+ \tex_lowercase:D { \tex_let:D ^^@ } \tex_undefined:D
+ }
+ \bool_lazy_or:nnT
+ { \sys_if_engine_ptex_p: }
+ { \sys_if_engine_uptex_p: }
+ {
+ \cs_gset_protected:Npn \@@_analysis_disable:n #1
+ {
+ \if_int_compare:w 256 > #1 \exp_stop_f:
+ \tex_lccode:D 0 = #1 \exp_stop_f:
+ \tex_lowercase:D { \tex_let:D ^^@ } \tex_undefined:D
+ \fi:
+ }
+ }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_analysis_disable_char:N}
+% Similar to \cs{@@_analysis_disable:n}, but it receives a normal
+% character token, tests if that token is active (by turning it into
+% a space: the active space has been undefined at this point), and
+% if so, disables it. Even if the character is active and set equal
+% to a primitive conditional, nothing blows up.
+% Again, in \pTeX{} and \upTeX{} we skip characters beyond $[0,255]$,
+% which cannot be active anyways.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_active:N \^^@
+ \cs_new_protected:Npn \@@_analysis_disable_char:N #1
+ {
+ \tex_lccode:D `#1 = 32 \exp_stop_f:
+ \tex_lowercase:D { \if_meaning:w #1 } \tex_undefined:D
+ \tex_let:D #1 \tex_undefined:D
+ \fi:
+ }
+ \bool_lazy_or:nnT
+ { \sys_if_engine_ptex_p: }
+ { \sys_if_engine_uptex_p: }
+ {
+ \cs_gset_protected:Npn \@@_analysis_disable_char:N #1
+ {
+ \if_int_compare:w 256 > `#1 \exp_stop_f:
+ \tex_lccode:D `#1 = 32 \exp_stop_f:
+ \tex_lowercase:D { \if_meaning:w #1 } \tex_undefined:D
+ \tex_let:D #1 \tex_undefined:D
+ \fi:
+ \fi:
+ }
+ }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{First pass}
+%
+% The goal of this pass is to detect special (non-\texttt{N}-type) tokens,
+% and count how many \texttt{N}-type tokens lie between special tokens.
+% Also, we wish to store some representation of each special token
+% in a \tn{toks} register.
+%
+% We have $11$ types of tokens:
+% \begin{itemize}
+% \item[1.] a true non-space begin-group character;
+% \item[2.] a true space begin-group character;
+% \item[3.] a true non-space end-group character;
+% \item[4.] a true space end-group character;
+% \item[5.] a true space blank space character;
+% \item[6.] an active character;
+% \item[7.] any other true character;
+% \item[8.] a control sequence equal to a begin-group token (category code $1$);
+% \item[9.] a control sequence equal to an end-group token (category code $2$);
+% \item[10.] a control sequence equal to a space token
+% (character code $32$, category code $10$);
+% \item[11.] any other control sequence.
+% \end{itemize}
+% Our first tool is \tn{futurelet}. This cannot distinguish
+% case $8$ from $1$ or $2$, nor case $9$ from $3$ or $4$,
+% nor case $10$ from case $5$. Those cases are later distinguished
+% by applying the \tn{string} primitive to the following token,
+% after possibly changing the escape character to ensure that
+% a control sequence's string representation cannot be mistaken
+% for the true character.
+%
+% In cases $6$, $7$, and $11$, the following token is a valid
+% \texttt{N}-type argument, so we grab it and distinguish the case
+% of a character from a control sequence: in the latter case,
+% \cs{str_tail:n} \Arg{token} is non-empty, because the
+% escape character is printable.
+%
+% \begin{macro}{\@@_analysis_a:n}
+% We read tokens one by one using \tn{futurelet}.
+% While performing the loop, we keep track of the number of
+% true begin-group characters minus the number of
+% true end-group characters in \cs{l_@@_analysis_nesting_int}.
+% This reaches $-1$ when we read the closing brace.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_analysis_a:n #1
+ {
+ \@@_analysis_disable:n { 32 }
+ \int_set:Nn \tex_escapechar:D { 92 }
+ \int_zero:N \l_@@_analysis_normal_int
+ \int_zero:N \l_@@_analysis_index_int
+ \int_zero:N \l_@@_analysis_nesting_int
+ \if_false: { \fi: \@@_analysis_a_loop:w #1 }
+ \int_decr:N \l_@@_analysis_index_int
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_analysis_a_loop:w}
+% Read one character and check its type.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_analysis_a_loop:w
+ { \tex_futurelet:D \l_@@_analysis_token \@@_analysis_a_type:w }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_analysis_a_type:w}
+% At this point, \cs{l_@@_analysis_token} holds the meaning
+% of the following token. We store in \cs{l_@@_analysis_type_int}
+% information about the meaning of the token ahead:
+% \begin{itemize}
+% \item 0 space token;
+% \item 1 begin-group token;
+% \item -1 end-group token;
+% \item 2 other.
+% \end{itemize}
+% The values $0$, $1$, $-1$ correspond to how much a true such
+% character changes the nesting level ($2$ is used only here,
+% and is irrelevant later). Then call the auxiliary for each case.
+% Note that nesting conditionals here is safe because we only skip
+% over \cs{l_@@_analysis_token} if it matches with one of the
+% character tokens (hence is not a primitive conditional).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_analysis_a_type:w
+ {
+ \l_@@_analysis_type_int =
+ \if_meaning:w \l_@@_analysis_token \c_space_token
+ 0
+ \else:
+ \if_catcode:w \exp_not:N \l_@@_analysis_token \c_group_begin_token
+ 1
+ \else:
+ \if_catcode:w \exp_not:N \l_@@_analysis_token \c_group_end_token
+ - 1
+ \else:
+ 2
+ \fi:
+ \fi:
+ \fi:
+ \exp_stop_f:
+ \if_case:w \l_@@_analysis_type_int
+ \exp_after:wN \@@_analysis_a_space:w
+ \or: \exp_after:wN \@@_analysis_a_bgroup:w
+ \or: \exp_after:wN \@@_analysis_a_safe:N
+ \else: \exp_after:wN \@@_analysis_a_egroup:w
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_analysis_a_space:w}
+% \begin{macro}{\@@_analysis_a_space_test:w}
+% In this branch, the following token's meaning is a blank space.
+% Apply \tn{string} to that token: a true blank space gives a space, a
+% control sequence gives a result starting with the escape character,
+% an active character gives something else than a space since we
+% disabled the space. We grab as \cs{l_@@_analysis_char_token} the first
+% character of the string representation then test it in
+% \cs{@@_analysis_a_space_test:w}.
+% Also, since \cs{@@_analysis_a_store:} expects the special token to be
+% stored in the relevant \tn{toks} register, we do that. The extra
+% \cs{exp_not:n} is unnecessary of course, but it makes the treatment
+% of all tokens more homogeneous.
+% If we discover that the next token was actually a control sequence
+% or an active character
+% instead of a true space, then we step the counter of normal tokens.
+% We now have in front of us the whole string representation of
+% the control sequence, including potential spaces; those will appear
+% to be true spaces later in this pass. Hence, all other branches of
+% the code in this first pass need to consider the string representation,
+% so that the second pass does not need to test the meaning of tokens,
+% only strings.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_analysis_a_space:w
+ {
+ \tex_afterassignment:D \@@_analysis_a_space_test:w
+ \exp_after:wN \cs_set_eq:NN
+ \exp_after:wN \l_@@_analysis_char_token
+ \token_to_str:N
+ }
+\cs_new_protected:Npn \@@_analysis_a_space_test:w
+ {
+ \if_meaning:w \l_@@_analysis_char_token \c_space_token
+ \tex_toks:D \l_@@_analysis_index_int { \exp_not:n { ~ } }
+ \@@_analysis_a_store:
+ \else:
+ \int_incr:N \l_@@_analysis_normal_int
+ \fi:
+ \@@_analysis_a_loop:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_analysis_a_bgroup:w, \@@_analysis_a_egroup:w}
+% \begin{macro}
+% {\@@_analysis_a_group:nw, \@@_analysis_a_group_aux:w, \@@_analysis_a_group_auxii:w, \@@_analysis_a_group_test:w}
+% The token is most likely a true character token with catcode $1$ or
+% $2$, but it might be a control sequence, or an active character.
+% Optimizing for the first case, we store in a toks register some code
+% that expands to that token. Since we will turn what follows into
+% a string, we make sure the escape character is different from the
+% current character code (by switching between solidus and backslash).
+% To detect the special case of an active character let to the catcode
+% $1$ or~$2$ character with the same character code, we disable the
+% active character with that character code and re-test: if the
+% following token has become undefined we can in fact safely grab it.
+% We are finally ready to turn what follows to a string and test it.
+% This is one place where we need \cs{l_@@_analysis_char_token} to be a
+% separate control sequence from \cs{l_@@_analysis_token}, to compare them.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_group_begin:N \^^@ % {
+ \cs_new_protected:Npn \@@_analysis_a_bgroup:w
+ { \@@_analysis_a_group:nw { \exp_after:wN ^^@ \if_false: } \fi: } }
+ \char_set_catcode_group_end:N \^^@
+ \cs_new_protected:Npn \@@_analysis_a_egroup:w
+ { \@@_analysis_a_group:nw { \if_false: { \fi: ^^@ } } % }
+\group_end:
+\cs_new_protected:Npn \@@_analysis_a_group:nw #1
+ {
+ \tex_lccode:D 0 = \@@_analysis_extract_charcode: \scan_stop:
+ \tex_lowercase:D { \tex_toks:D \l_@@_analysis_index_int {#1} }
+ \if_int_compare:w \tex_lccode:D 0 = \tex_escapechar:D
+ \int_set:Nn \tex_escapechar:D { 139 - \tex_escapechar:D }
+ \fi:
+ \@@_analysis_disable:n { \tex_lccode:D 0 }
+ \tex_futurelet:D \l_@@_analysis_token \@@_analysis_a_group_aux:w
+ }
+\cs_new_protected:Npn \@@_analysis_a_group_aux:w
+ {
+ \if_meaning:w \l_@@_analysis_token \tex_undefined:D
+ \exp_after:wN \@@_analysis_a_safe:N
+ \else:
+ \exp_after:wN \@@_analysis_a_group_auxii:w
+ \fi:
+ }
+\cs_new_protected:Npn \@@_analysis_a_group_auxii:w
+ {
+ \tex_afterassignment:D \@@_analysis_a_group_test:w
+ \exp_after:wN \cs_set_eq:NN
+ \exp_after:wN \l_@@_analysis_char_token
+ \token_to_str:N
+ }
+\cs_new_protected:Npn \@@_analysis_a_group_test:w
+ {
+ \if_charcode:w \l_@@_analysis_token \l_@@_analysis_char_token
+ \@@_analysis_a_store:
+ \else:
+ \int_incr:N \l_@@_analysis_normal_int
+ \fi:
+ \@@_analysis_a_loop:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_analysis_a_store:}
+% This function is called each time we meet a special token;
+% at this point, the \tn{toks} register \cs{l_@@_analysis_index_int}
+% holds a token list which expands to the given special token.
+% Also, the value of \cs{l_@@_analysis_type_int} indicates which case
+% we are in:
+% \begin{itemize}
+% \item -1 end-group character;
+% \item 0 space character;
+% \item 1 begin-group character.
+% \end{itemize}
+% We need to distinguish further the case of a space character
+% (code $32$) from other character codes, because those
+% behave differently in the second pass. Namely, after testing
+% the \tn{lccode} of $0$ (which holds the present character code)
+% we change the cases above to
+% \begin{itemize}
+% \item -2 space end-group character;
+% \item -1 non-space end-group character;
+% \item 0 space blank space character;
+% \item 1 non-space begin-group character;
+% \item 2 space begin-group character.
+% \end{itemize}
+% This has the property that non-space characters correspond to odd
+% values of \cs{l_@@_analysis_type_int}. The number of normal tokens until
+% here and the type of special token are packed into a \tn{skip}
+% register. Finally, we check whether we reached the last closing
+% brace, in which case we stop by disabling the looping function
+% (locally).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_analysis_a_store:
+ {
+ \tex_advance:D \l_@@_analysis_nesting_int \l_@@_analysis_type_int
+ \if_int_compare:w \tex_lccode:D 0 = `\ \exp_stop_f:
+ \tex_advance:D \l_@@_analysis_type_int \l_@@_analysis_type_int
+ \fi:
+ \tex_skip:D \l_@@_analysis_index_int
+ = \l_@@_analysis_normal_int sp
+ plus \l_@@_analysis_type_int sp \scan_stop:
+ \int_incr:N \l_@@_analysis_index_int
+ \int_zero:N \l_@@_analysis_normal_int
+ \if_int_compare:w \l_@@_analysis_nesting_int = - \c_one_int
+ \cs_set_eq:NN \@@_analysis_a_loop:w \scan_stop:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_analysis_a_safe:N}
+% \begin{macro}{\@@_analysis_a_cs:ww}
+% This should be the simplest case: since the upcoming token is safe,
+% we can simply grab it in a second pass. If the token is a single
+% character (including space), the \cs{if_charcode:w} test yields
+% true; we disable a potentially active character (that could
+% otherwise masquerade as the true character in the next pass) and we
+% count one \enquote{normal} token. On the other
+% hand, if the token is a control sequence, we should replace it by
+% its string representation for compatibility with other code
+% branches. Instead of slowly looping through the characters with
+% the main code, we use the knowledge of how the second pass works:
+% if the control sequence name contains no space, count that token
+% as a number of normal tokens equal to its string length. If the
+% control sequence contains spaces, they should be registered as
+% special characters by increasing \cs{l_@@_analysis_index_int}
+% (no need to carefully count character between each space), and
+% all characters after the last space should be counted in the
+% following sequence of \enquote{normal} tokens.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_analysis_a_safe:N #1
+ {
+ \if_charcode:w
+ \scan_stop:
+ \exp_after:wN \use_none:n \token_to_str:N #1 \prg_do_nothing:
+ \scan_stop:
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ \@@_analysis_disable_char:N #1
+ \int_incr:N \l_@@_analysis_normal_int
+ }
+ { \@@_analysis_cs_space_count:NN \@@_analysis_a_cs:ww #1 }
+ \@@_analysis_a_loop:w
+ }
+\cs_new_protected:Npn \@@_analysis_a_cs:ww #1; #2;
+ {
+ \if_int_compare:w #1 > \c_zero_int
+ \tex_skip:D \l_@@_analysis_index_int
+ = \int_eval:n { \l_@@_analysis_normal_int + 1 } sp \exp_stop_f:
+ \tex_advance:D \l_@@_analysis_index_int #1 \exp_stop_f:
+ \else:
+ \tex_advance:D
+ \fi:
+ \l_@@_analysis_normal_int #2 \exp_stop_f:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Second pass}
+%
+% The second pass is an exercise in expandable loops.
+% All the necessary information is stored in \tn{skip}
+% and \tn{toks} registers.
+%
+% \begin{macro}{\@@_analysis_b:n}
+% \begin{macro}[EXP]{\@@_analysis_b_loop:w}
+% Start the loop with the index $0$. No need for an end-marker:
+% the loop stops by itself when the last index is read.
+% We repeatedly oscillate between reading long stretches
+% of normal tokens, and reading special tokens.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_analysis_b:n #1
+ {
+ \__kernel_tl_gset:Nx \g_@@_analysis_result_tl
+ {
+ \@@_analysis_b_loop:w 0; #1
+ \prg_break_point:
+ }
+ }
+\cs_new:Npn \@@_analysis_b_loop:w #1;
+ {
+ \exp_after:wN \@@_analysis_b_normals:ww
+ \int_value:w \tex_skip:D #1 ; #1 ;
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_analysis_b_normals:ww}
+% \begin{macro}[EXP]{\@@_analysis_b_normal:wwN}
+% The first argument is the number of normal tokens which remain
+% to be read, and the second argument is the index in the array
+% produced in the first step.
+% A character's string representation is always one character long,
+% while a control sequence is always longer (we have set the escape
+% character to a printable value). In both cases, we leave
+% \cs{exp_not:n} \Arg{token} \cs{s_@@} in the input stream
+% (after \texttt{e}-expansion). Here, \cs{exp_not:n} is used
+% rather than \cs{exp_not:N} because |#3| could be
+% a macro parameter character or could be \cs{s_@@}
+% (which must be hidden behind braces in the result).
+% \begin{macrocode}
+\cs_new:Npn \@@_analysis_b_normals:ww #1;
+ {
+ \if_int_compare:w #1 = \c_zero_int
+ \@@_analysis_b_special:w
+ \fi:
+ \@@_analysis_b_normal:wwN #1;
+ }
+\cs_new:Npn \@@_analysis_b_normal:wwN #1; #2; #3
+ {
+ \exp_not:n { \exp_not:n { #3 } } \s_@@
+ \if_charcode:w
+ \scan_stop:
+ \exp_after:wN \use_none:n \token_to_str:N #3 \prg_do_nothing:
+ \scan_stop:
+ \exp_after:wN \@@_analysis_b_char:Nn
+ \exp_after:wN \@@_analysis_b_char_aux:nww
+ \else:
+ \exp_after:wN \@@_analysis_b_cs:Nww
+ \fi:
+ #3 #1; #2;
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_analysis_b_char:Nn, \@@_analysis_b_char_aux:nww}
+% This function is called here with arguments
+% \cs{@@_analysis_b_char_aux:nww} and a normal character, while in the
+% peek analysis code it is called with \cs{use_none:n} and possibly a
+% space character, which is why the function has signature |Nn|.
+% If the normal token we grab is a character, leave
+% \meta{catcode} \meta{charcode} followed by \cs{s_@@}
+% in the input stream, and call \cs{@@_analysis_b_normals:ww}
+% with its first argument decremented.
+% \begin{macrocode}
+\cs_new:Npe \@@_analysis_b_char:Nn #1#2
+ {
+ \exp_not:N \if_meaning:w #2 \exp_not:N \tex_undefined:D
+ \token_to_str:N D \exp_not:N \else:
+ \exp_not:N \if_catcode:w #2 \c_catcode_other_token
+ \token_to_str:N C \exp_not:N \else:
+ \exp_not:N \if_catcode:w #2 \c_catcode_letter_token
+ \token_to_str:N B \exp_not:N \else:
+ \exp_not:N \if_catcode:w #2 \c_math_toggle_token 3
+ \exp_not:N \else:
+ \exp_not:N \if_catcode:w #2 \c_alignment_token 4
+ \exp_not:N \else:
+ \exp_not:N \if_catcode:w #2 \c_math_superscript_token 7
+ \exp_not:N \else:
+ \exp_not:N \if_catcode:w #2 \c_math_subscript_token 8
+ \exp_not:N \else:
+ \exp_not:N \if_catcode:w #2 \c_space_token
+ \token_to_str:N A \exp_not:N \else:
+ 6
+ \exp_not:n { \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: }
+ #1 {#2}
+ }
+\cs_new:Npn \@@_analysis_b_char_aux:nww #1
+ {
+ \int_value:w `#1 \s_@@
+ \exp_after:wN \@@_analysis_b_normals:ww
+ \int_value:w \int_eval:w - 1 +
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_analysis_b_cs:Nww}
+% \begin{macro}[EXP]{\@@_analysis_b_cs_test:ww}
+% If the token we grab is a control sequence, leave
+% |0 -1| (as category code and character code) in the input stream,
+% followed by \cs{s_@@},
+% and call \cs{@@_analysis_b_normals:ww} with updated arguments.
+% \begin{macrocode}
+\cs_new:Npn \@@_analysis_b_cs:Nww #1
+ {
+ 0 -1 \s_@@
+ \@@_analysis_cs_space_count:NN \@@_analysis_b_cs_test:ww #1
+ }
+\cs_new:Npn \@@_analysis_b_cs_test:ww #1 ; #2 ; #3 ; #4 ;
+ {
+ \exp_after:wN \@@_analysis_b_normals:ww
+ \int_value:w \int_eval:w
+ \if_int_compare:w #1 = \c_zero_int
+ #3
+ \else:
+ \tex_skip:D \int_eval:n { #4 + #1 } \exp_stop_f:
+ \fi:
+ - #2
+ \exp_after:wN ;
+ \int_value:w \int_eval:n { #4 + #1 } ;
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_analysis_b_special:w}
+% \begin{macro}[EXP]{\@@_analysis_b_special_char:wN}
+% \begin{macro}[EXP]{\@@_analysis_b_special_space:w}
+% Here, |#1| is the current index in the array built in the first pass.
+% Check now whether we reached the end (we shouldn't keep the trailing
+% end-group character that marked the end of the token list in the
+% first pass).
+% Unpack the \tn{toks} register: when \texttt{e}/\texttt{x}-expanding again,
+% we will get the special token.
+% Then leave the category code in the input stream, followed by
+% the character code, and call \cs{@@_analysis_b_loop:w} with the next index.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_other:N A
+ \cs_new:Npn \@@_analysis_b_special:w
+ \fi: \@@_analysis_b_normal:wwN 0 ; #1 ;
+ {
+ \fi:
+ \if_int_compare:w #1 = \l_@@_analysis_index_int
+ \exp_after:wN \prg_break:
+ \fi:
+ \tex_the:D \tex_toks:D #1 \s_@@
+ \if_case:w \tex_gluestretch:D \tex_skip:D #1 \exp_stop_f:
+ \token_to_str:N A
+ \or: 1
+ \or: 1
+ \else: 2
+ \fi:
+ \if_int_odd:w \tex_gluestretch:D \tex_skip:D #1 \exp_stop_f:
+ \exp_after:wN \@@_analysis_b_special_char:wN \int_value:w
+ \else:
+ \exp_after:wN \@@_analysis_b_special_space:w \int_value:w
+ \fi:
+ \int_eval:n { 1 + #1 } \exp_after:wN ;
+ \token_to_str:N
+ }
+\group_end:
+\cs_new:Npn \@@_analysis_b_special_char:wN #1 ; #2
+ {
+ \int_value:w `#2 \s_@@
+ \@@_analysis_b_loop:w #1 ;
+ }
+\cs_new:Npn \@@_analysis_b_special_space:w #1 ; ~
+ {
+ 32 \s_@@
+ \@@_analysis_b_loop:w #1 ;
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Mapping through the analysis}
+%
+% \begin{macro}{\tl_analysis_map_inline:Nn, \tl_analysis_map_inline:nn}
+% \begin{macro}{\@@_analysis_map:Nn}
+% \begin{macro}{\@@_analysis_map:NwNw}
+% First obtain the analysis of the token list into
+% \cs{g_@@_analysis_result_tl}. To allow nested mappings, increase the
+% nesting depth \cs{g__kernel_prg_map_int} (shared between all
+% modules), then define the payload macro, which runs the user code
+% and has a name specific to that nesting depth. The looping macro
+% grabs the \meta{tokens}, \meta{catcode} and \meta{char code}; it
+% checks for the end of the loop with \cs{use_none:n} |##2|, normally
+% empty, but which becomes \cs{tl_map_break:} at the end; it then
+% calls the payload macro with the arguments in the correct order
+% (this is the reason why we cannot directly use the same macro for
+% looping and payload), and loops by calling itself. When the loop
+% ends, remember to decrease the nesting depth.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_analysis_map_inline:Nn #1
+ { \exp_args:No \tl_analysis_map_inline:nn #1 }
+\cs_new_protected:Npn \tl_analysis_map_inline:nn #1
+ {
+ \@@_analysis:n {#1}
+ \int_gincr:N \g__kernel_prg_map_int
+ \exp_args:Nc \@@_analysis_map:Nn
+ { @@_analysis_map_inline_ \int_use:N \g__kernel_prg_map_int :wNw }
+ }
+\cs_new_protected:Npn \@@_analysis_map:Nn #1#2
+ {
+ \cs_gset_protected:Npn #1 ##1##2##3 {#2}
+ \exp_after:wN \@@_analysis_map:NwNw \exp_after:wN #1
+ \g_@@_analysis_result_tl
+ \s_@@ { ? \tl_map_break: } \s_@@
+ \prg_break_point:Nn \tl_map_break:
+ { \int_gdecr:N \g__kernel_prg_map_int }
+ }
+\cs_new_protected:Npn \@@_analysis_map:NwNw #1 #2 \s_@@ #3 #4 \s_@@
+ {
+ \use_none:n #3
+ #1 {#2} {#4} {#3}
+ \@@_analysis_map:NwNw #1
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Showing the results}
+%
+% \begin{macro}{\tl_analysis_show:N, \tl_analysis_log:N, \@@_analysis_show:NNN}
+% Add to \cs{@@_analysis:n} a third pass to display tokens to the terminal.
+% If the token list variable is not defined, throw the same error
+% as \cs{tl_show:N} by simply calling that function.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_analysis_show:N
+ { \@@_analysis_show:NNN \msg_show:nneeee \tl_show:N }
+\cs_new_protected:Npn \tl_analysis_log:N
+ { \@@_analysis_show:NNN \msg_log:nneeee \tl_log:N }
+\cs_new_protected:Npn \@@_analysis_show:NNN #1#2#3
+ {
+ \tl_if_exist:NTF #3
+ {
+ \exp_args:No \@@_analysis:n {#3}
+ #1 { tl } { show-analysis }
+ { \token_to_str:N #3 } { \@@_analysis_show: } { } { }
+ }
+ { #2 #3 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_analysis_show:n, \tl_analysis_log:n, \@@_analysis_show:Nn}
+% No existence test needed here.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_analysis_show:n
+ { \@@_analysis_show:Nn \msg_show:nneeee }
+\cs_new_protected:Npn \tl_analysis_log:n
+ { \@@_analysis_show:Nn \msg_log:nneeee }
+\cs_new_protected:Npn \@@_analysis_show:Nn #1#2
+ {
+ \@@_analysis:n {#2}
+ #1 { tl } { show-analysis } { } { \@@_analysis_show: } { } { }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_analysis_show:, \@@_analysis_show_loop:wNw}
+% Here, |#1| \texttt{o}- and \texttt{e}/\texttt{x}-expands to the token;
+% |#2| is the category code (one uppercase hexadecimal digit),
+% $0$ for control sequences;
+% |#3| is the character code, which we ignore.
+% In the cases of control sequences and active characters,
+% the meaning may overflow one line, and we want to truncate
+% it. Those cases are thus separated out.
+% \begin{macrocode}
+\cs_new:Npn \@@_analysis_show:
+ {
+ \exp_after:wN \@@_analysis_show_loop:wNw \g_@@_analysis_result_tl
+ \s_@@ { ? \prg_break: } \s_@@
+ \prg_break_point:
+ }
+\cs_new:Npn \@@_analysis_show_loop:wNw #1 \s_@@ #2 #3 \s_@@
+ {
+ \use_none:n #2
+ \iow_newline: > \use:nn { ~ } { ~ }
+ \if_int_compare:w "#2 = \c_zero_int
+ \exp_after:wN \@@_analysis_show_cs:n
+ \else:
+ \if_int_compare:w "#2 = 13 \exp_stop_f:
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_analysis_show_active:n
+ \else:
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_analysis_show_normal:n
+ \fi:
+ \fi:
+ {#1}
+ \@@_analysis_show_loop:wNw
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_analysis_show_normal:n}
+% Non-active characters are a simple matter of printing
+% the character, and its meaning. Our test suite checks that
+% begin-group and end-group characters do not mess up
+% \TeX{}'s alignment status.
+% \begin{macrocode}
+\cs_new:Npn \@@_analysis_show_normal:n #1
+ {
+ \exp_after:wN \token_to_str:N #1 ~
+ ( \exp_after:wN \token_to_meaning:N #1 )
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_analysis_show_value:N}
+% This expands to the value of |#1| if it has any.
+% \begin{macrocode}
+\cs_new:Npn \@@_analysis_show_value:N #1
+ {
+ \token_if_expandable:NF #1
+ {
+ \token_if_chardef:NTF #1 \prg_break: { }
+ \token_if_mathchardef:NTF #1 \prg_break: { }
+ \token_if_dim_register:NTF #1 \prg_break: { }
+ \token_if_int_register:NTF #1 \prg_break: { }
+ \token_if_skip_register:NTF #1 \prg_break: { }
+ \token_if_toks_register:NTF #1 \prg_break: { }
+ \use_none:nnn
+ \prg_break_point:
+ \use:n { \exp_after:wN = \tex_the:D #1 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\@@_analysis_show_cs:n}
+% \begin{macro}[rEXP]{\@@_analysis_show_active:n}
+% \begin{macro}[rEXP]{\@@_analysis_show_long:nn}
+% \begin{macro}[rEXP]{\@@_analysis_show_long_aux:nnnn}
+% Control sequences and active characters are printed in the same way,
+% making sure not to go beyond the \cs{l_iow_line_count_int}. In case
+% of an overflow, we replace the last characters by
+% \cs{c_@@_analysis_show_etc_str}.
+% \begin{macrocode}
+\cs_new:Npn \@@_analysis_show_cs:n #1
+ { \exp_args:No \@@_analysis_show_long:nn {#1} { control~sequence= } }
+\cs_new:Npn \@@_analysis_show_active:n #1
+ { \exp_args:No \@@_analysis_show_long:nn {#1} { active~character= } }
+\cs_new:Npn \@@_analysis_show_long:nn #1
+ {
+ \@@_analysis_show_long_aux:oofn
+ { \token_to_str:N #1 }
+ { \token_to_meaning:N #1 }
+ { \@@_analysis_show_value:N #1 }
+ }
+\cs_new:Npn \@@_analysis_show_long_aux:nnnn #1#2#3#4
+ {
+ \int_compare:nNnTF
+ { \str_count:n { #1 ~ ( #4 #2 #3 ) } }
+ > { \l_iow_line_count_int - 3 }
+ {
+ \str_range:nnn { #1 ~ ( #4 #2 #3 ) } { 1 }
+ {
+ \l_iow_line_count_int - 3
+ - \str_count:N \c_@@_analysis_show_etc_str
+ }
+ \c_@@_analysis_show_etc_str
+ }
+ { #1 ~ ( #4 #2 #3 ) }
+ }
+\cs_generate_variant:Nn \@@_analysis_show_long_aux:nnnn { oof }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Peeking ahead}
+%
+% \begin{macro}[EXP]{\peek_analysis_map_break:, \peek_analysis_map_break:n}
+% The break statements use the general \cs{prg_map_break:Nn}.
+% \begin{macrocode}
+\cs_new:Npn \peek_analysis_map_break:
+ { \prg_map_break:Nn \peek_analysis_map_break: { } }
+\cs_new:Npn \peek_analysis_map_break:n
+ { \prg_map_break:Nn \peek_analysis_map_break: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_peek_charcode_int}
+% \begin{macrocode}
+\int_new:N \l_@@_peek_charcode_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_analysis_char_arg:Nw, \@@_analysis_char_arg_aux:Nw}
+% After a call to \tn{futurelet} \cs{l_@@_analysis_token} followed by
+% a stringified character token (either explicit space or catcode
+% other character), grab the argument and pass it to |#1|. We only
+% need to do anything in the case of a space.
+% \begin{macrocode}
+\cs_new:Npn \@@_analysis_char_arg:Nw
+ {
+ \if_meaning:w \l_@@_analysis_token \c_space_token
+ \exp_after:wN \@@_analysis_char_arg_aux:Nw
+ \fi:
+ }
+\cs_new:Npn \@@_analysis_char_arg_aux:Nw #1 ~ { #1 { ~ } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \peek_analysis_map_inline:n,
+% \@@_peek_analysis_loop:NNn, \@@_peek_analysis_test:,
+% \@@_peek_analysis_exp:N, \@@_peek_analysis_exp_aux:N,
+% \@@_peek_analysis_nonexp:N, \@@_peek_analysis_cs:N,
+% \@@_peek_analysis_char:N, \@@_peek_analysis_char:w,
+% \@@_peek_analysis_special:, \@@_peek_analysis_retest:,
+% \@@_peek_analysis_str:,
+% \@@_peek_analysis_str:w, \@@_peek_analysis_str:n,
+% \@@_peek_analysis_active_str:n, \@@_peek_analysis_explicit:n,
+% \@@_peek_analysis_escape:, \@@_peek_analysis_collect:w,
+% \@@_peek_analysis_collect:n, \@@_peek_analysis_collect_loop:,
+% \@@_peek_analysis_collect_test:, \@@_peek_analysis_collect_end:NNNN
+% }
+% Save the user's code in a control sequence that is suitable for
+% nested maps. We may wish to pass to this function an \tn{outer}
+% control sequence or active character; for this we will undefine
+% any expandable token (testing if it is \tn{outer} is much slower)
+% within a group, closed immediately after the function reads its
+% arguments to avoid affecting the user's code or even our peek code
+% (there is no risk of undefining \cs{group_end:} itself since that is
+% not expandable). This user's code function also
+% calls the loop auxiliary, and includes the trailing
+% \cs{prg_break_point:Nn} for when the user wants to stop the loop.
+% The loop auxiliary must remove that break point because it must look
+% at the input stream.
+% \begin{macrocode}
+\cs_new_protected:Npn \peek_analysis_map_inline:n #1
+ {
+ \group_align_safe_begin:
+ \int_gincr:N \g__kernel_prg_map_int
+ \cs_set_protected:cpn
+ { @@_analysis_map_ \int_use:N \g__kernel_prg_map_int :nnN }
+ ##1##2##3
+ {
+ \group_end:
+ #1
+ \@@_peek_analysis_loop:NNn
+ \prg_break_point:Nn \peek_analysis_map_break:
+ {
+ \int_gdecr:N \g__kernel_prg_map_int
+ \group_align_safe_end:
+ }
+ }
+ \@@_peek_analysis_loop:NNn ? ? ?
+ }
+% \end{macrocode}
+% The loop starts a group (closed by the user-code function defined
+% above) with a normalized escape character, and checks if the next
+% token is special or \texttt{N}-type (distinguishing expandable from
+% non-expandable tokens). The test for nonexpandable tokens in
+% \cs{@@_peek_analysis_test:} must be done after the tests for
+% begin-group, end-group, and space tokens, in case \cs{l_peek_token}
+% is either \tn{outer} or is a primitive \TeX{} conditional, as such
+% tokens cannot be skipped over correctly by conditional code.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_analysis_loop:NNn #1#2#3
+ {
+ \group_begin:
+ \tl_set:Ne \l_@@_peek_code_tl
+ {
+ \exp_not:c
+ { @@_analysis_map_ \int_use:N \g__kernel_prg_map_int :nnN }
+ }
+ \int_set:Nn \tex_escapechar:D { `\\ }
+ \peek_after:Nw \@@_peek_analysis_test:
+ }
+\cs_new_protected:Npn \@@_peek_analysis_test:
+ {
+ \if_case:w
+ \if_catcode:w \exp_not:N \l_peek_token { \c_max_int \fi:
+ \if_catcode:w \exp_not:N \l_peek_token } \c_max_int \fi:
+ \if_meaning:w \l_peek_token \c_space_token \c_max_int \fi:
+ \exp_after:wN \if_meaning:w \exp_not:N \l_peek_token \l_peek_token
+ \c_one_int
+ \fi:
+ \c_zero_int
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_peek_analysis_exp:N
+ \exp_after:wN \exp_not:N
+ \or:
+ \exp_after:wN \@@_peek_analysis_nonexp:N
+ \else:
+ \exp_after:wN \@@_peek_analysis_special:
+ \fi:
+ }
+% \end{macrocode}
+% Expandable tokens (which are automatically |N|-type) can be
+% \tn{outer} macros, hence the need for \cs{exp_after:wN} and
+% \cs{exp_not:N} in the code above, which allows the next function to
+% safely grab the token as an argument. We run some code that is
+% expanded using the primitive \cs{cs_set_nopar:Npe} rather than
+% \cs{tl_set:Ne} to avoid grabbing it as an argument as |#1| may be
+% \tn{outer}. To allow~|#1| as an argument of the user's function
+% (stored in \cs{l_@@_peek_code_tl}), we set it equal to
+% \cs{scan_stop:}, but we do it at the last minute because |#1|
+% may be some pretty important function such as \cs{exp_after:wN}.
+% Then we put the user's function and the elaborate first argument
+% \cs{__kernel_exp_not:w} \cs{exp_after:wN} |{| \cs{exp_not:N} |#1| |}|:
+% indeed we cannot use \cs{exp_not:n} |{#1}| as this breaks for an
+% \tn{outer} macro and we cannot use \cs{exp_not:N} |#1|, as
+% \texttt{o}-expanding this yields a \enquote{notexpanded} token equal
+% to (a weird) \tn{relax}, which would have the wrong value for
+% primitive \TeX{} conditionals such as \cs{if_meaning:w}.
+%
+% Then we must add |{-1}0| if the token is a
+% control sequence and \Arg{charcode}|D| otherwise. Distinguishing
+% the two cases is easy: since we have made the escape character
+% printable, \cs{token_to_str:N} gives at least two characters for a
+% control sequence versus a single one for an active character
+% (possibly being a space). Importantly, once we apply
+% \cs{token_to_str:N} we no longer need to worry about \tn{outer}
+% tokens.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_analysis_exp:N #1
+ {
+ \cs_set_nopar:Npe \l_@@_peek_code_tl
+ {
+ \tex_let:D \exp_not:N #1 \scan_stop:
+ \exp_not:o \l_@@_peek_code_tl
+ {
+ \exp_not:n { \__kernel_exp_not:w \exp_after:wN }
+ { \exp_not:N \exp_not:N \exp_not:N #1 }
+ }
+ \exp_after:wN \@@_peek_analysis_exp_aux:Nw
+ \token_to_str:N #1 \prg_do_nothing: \s_@@
+ }
+ \l_@@_peek_code_tl
+ }
+\cs_new:Npe \@@_peek_analysis_exp_aux:Nw #1#2 \s_@@
+ {
+ \exp_not:N \if:w \scan_stop: #2 \scan_stop:
+ { \exp_not:N \int_value:w `#1 } \token_to_str:N D
+ \exp_not:N \else:
+ { -1 } 0
+ \exp_not:N \fi:
+ }
+% \end{macrocode}
+% For normal non-expandable tokens we must distinguish characters
+% (including active ones and macro parameter characters) from control
+% sequences (whose string representation is more than one character
+% because we made the escape character printable). For a control
+% sequence call the user code with suitable arguments, wrapping |#1|
+% within \cs{exp_not:n} just in case it happens to be equal to a macro
+% parameter character. We do not skip \cs{exp_not:n} when
+% unnecessary, because this auxiliary is also called in
+% \cs{@@_peek_analysis_retest:} where we have changed some control
+% sequences or active characters to \cs{scan_stop:} temporarily.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_analysis_nonexp:N #1
+ {
+ \if_charcode:w
+ \scan_stop:
+ \exp_after:wN \use_none:n \token_to_str:N #1 \prg_do_nothing:
+ \scan_stop:
+ \exp_after:wN \@@_peek_analysis_char:N
+ \else:
+ \exp_after:wN \@@_peek_analysis_cs:N
+ \fi:
+ #1
+ }
+\cs_new_protected:Npn \@@_peek_analysis_cs:N #1
+ { \l_@@_peek_code_tl { \exp_not:n {#1} } { -1 } 0 }
+% \end{macrocode}
+% For normal characters we must determine their catcode. The main
+% difficulty is that the character may be an active character
+% masquerading as (i.e., set equal to) itself with a different
+% catcode. Two approaches based on \tn{lowercase} can detect this.
+% One could make an active character with the same catcode as~|#1| and
+% change its definition before testing the catcode of~|#1|, but in
+% some Unicode engine this fills up the hash table uselessly.
+% Instead, we lowercase~|#1| itself, changing its character code
+% to~$32$, namely space (because \LuaTeX{} cannot turn catcode~$10$
+% characters to anything else than character code~$32$), then we apply
+% \cs{@@_analysis_b_char:Nn}, which detects active characters by
+% comparing them to \cs{tex_undefined:D}, and we must have undefined
+% the active space (locally) for this test to work.
+% To define \cs{@@_peek_analysis_char:N} itself we use an
+% |e|-expanding assignment to get the active space in the right place
+% after making it (just for this definition) unexpandable.
+% Finally \cs{@@_peek_analysis_char:w} receives the \meta{charcode},
+% \meta{user function}, \meta{catcode}, and \meta{token}, and places
+% the arguments in the correct order. It keeps \cs{exp_not:n} for
+% macro parameter characters and active characters (the latter could
+% be macro parameter characters, and it seems more uniform to always
+% put \cs{exp_not:n}), and otherwise eliminates it by expanding once
+% with \cs{exp_args:NNNo}.
+% \begin{macrocode}
+\group_begin:
+\char_set_active_eq:NN \ \scan_stop:
+\cs_new_protected:Npe \@@_peek_analysis_char:N #1
+ {
+ \cs_set_eq:NN
+ \char_generate:nn { 32 } { 13 }
+ \exp_not:N \tex_undefined:D
+ \tex_lccode:D `#1 = 32 \exp_stop_f:
+ \tex_lowercase:D
+ {
+ \tl_put_right:Ne \exp_not:N \l_@@_peek_code_tl
+ { \exp_not:n { \@@_analysis_b_char:Nn \use_none:n } {#1} }
+ }
+ \exp_not:n
+ {
+ \exp_after:wN \@@_peek_analysis_char:w
+ \int_value:w
+ }
+ `#1
+ \exp_not:n { \exp_after:wN \s_@@ \l_@@_peek_code_tl }
+ #1
+ }
+\group_end:
+\cs_new_protected:Npn \@@_peek_analysis_char:w #1 \s_@@ #2#3#4
+ {
+ \if_charcode:w 6 #3
+ \else:
+ \if_charcode:w D #3
+ \else:
+ \exp_args:NNNo
+ \fi:
+ \fi:
+ #2 { \exp_not:n {#4} } {#1} #3
+ }
+% \end{macrocode}
+% For special characters the idea is to eventually act with
+% \cs{token_to_str:N}, then pick up one by one the characters of this
+% string representation until hitting the token that follows. First
+% determine the character code of (the meaning of) the \meta{token}
+% (which we know is a special token), make sure the escape character
+% is different from it, normalize the meanings of two active
+% characters and the empty control sequence, and filter out these
+% cases in \cs{@@_peek_analysis_retest:}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_analysis_special:
+ {
+ \tex_let:D \l_@@_analysis_token = ~ \l_peek_token
+ \int_set:Nn \l_@@_peek_charcode_int
+ { \@@_analysis_extract_charcode: }
+ \if_int_compare:w \l_@@_peek_charcode_int = \tex_escapechar:D
+ \int_set:Nn \tex_escapechar:D { `\/ }
+ \fi:
+ \char_set_active_eq:nN { \l_@@_peek_charcode_int } \scan_stop:
+ \char_set_active_eq:nN { \tex_escapechar:D } \scan_stop:
+ \cs_set_eq:cN { } \scan_stop:
+ \tex_futurelet:D \l_@@_analysis_token
+ \@@_peek_analysis_retest:
+ }
+\cs_new_protected:Npn \@@_peek_analysis_retest:
+ {
+ \if_meaning:w \l_@@_analysis_token \scan_stop:
+ \exp_after:wN \@@_peek_analysis_nonexp:N
+ \else:
+ \exp_after:wN \@@_peek_analysis_str:
+ \fi:
+ }
+% \end{macrocode}
+% At this point we know the meaning of the \meta{token} in the input
+% stream is \cs{l_peek_token}, either a space (32, 10) or a
+% begin-group or end-group token (catcode $1$ or~$2$), and we excluded
+% a few cases that would be difficult later (empty control sequence,
+% active character with the same character code as its meaning or as
+% the escape character). The idea is to apply \cs{token_to_str:N} to
+% the \meta{token} then grab characters (of category code~$12$ except
+% for spaces that have category code~$10$) to reconstruct it. In
+% earlier versions of the code we would peek at the \meta{next token}
+% that lies after \meta{token} in the input stream, which would help
+% us be more accurate in reconstructing the \meta{token} case in edge
+% cases (mentioned below), but this had the side-effect of tokenizing
+% the input stream (turning characters into tokens) farther ahead than
+% needed.
+%
+% We hit the \meta{token} with \cs{token_to_str:N} and start grabbing
+% characters. More
+% precisely, by looking at the first character in the string
+% representation of the \meta{token} we distinguish three cases:
+% a stringified control sequence starts with the escape character; for
+% an explicit character we find that same character; for an active
+% character we find anything else (we made sure to exclude the case of
+% an active character whose string representation coincides with the
+% other two cases).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_analysis_str:
+ {
+ \exp_after:wN \tex_futurelet:D
+ \exp_after:wN \l_@@_analysis_token
+ \exp_after:wN \@@_peek_analysis_str:w
+ \token_to_str:N
+ }
+\cs_new_protected:Npn \@@_peek_analysis_str:w
+ { \@@_analysis_char_arg:Nw \@@_peek_analysis_str:n }
+\cs_new_protected:Npn \@@_peek_analysis_str:n #1
+ {
+ \int_case:nnF { `#1 }
+ {
+ { \l_@@_peek_charcode_int }
+ { \@@_peek_analysis_explicit:n {#1} }
+ { \tex_escapechar:D } { \@@_peek_analysis_escape: }
+ }
+ { \@@_peek_analysis_active_str:n {#1} }
+ }
+% \end{macrocode}
+% When |#1| is a stringified active character we pass appropriate
+% arguments to the user's code; thankfully \cs{char_generate:nn}
+% can make active characters.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_analysis_active_str:n #1
+ {
+ \tl_put_right:Ne \l_@@_peek_code_tl
+ {
+ { \char_generate:nn { `#1 } { 13 } }
+ { \int_value:w `#1 }
+ \token_to_str:N D
+ }
+ \l_@@_peek_code_tl
+ }
+% \end{macrocode}
+% When |#1| matches the character we had extracted from the meaning of
+% \cs{l_peek_token}, the token was an explicit character, which can be
+% a standard space, or a begin-group or end-group character with some
+% character code. In the latter two cases we call
+% \cs{char_generate:nn} with suitable arguments and put suitable
+% \cs{if_false:} \cs{fi:} constructions to make the result balanced
+% and such that \texttt{o}-expanding or \texttt{e}/\texttt{x}-expanding gives
+% back a single (unbalanced) begin-group or end-group character.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_analysis_explicit:n #1
+ {
+ \tl_put_right:Ne \l_@@_peek_code_tl
+ {
+ \if_meaning:w \l_peek_token \c_space_token
+ { ~ } { 32 } \token_to_str:N A
+ \else:
+ \if_catcode:w \l_peek_token \c_group_begin_token
+ {
+ \exp_not:N \exp_after:wN
+ \char_generate:nn { `#1 } { 1 }
+ \exp_not:N \if_false:
+ \if_false: { \fi: }
+ \exp_not:N \fi:
+ }
+ { \int_value:w `#1 }
+ 1
+ \else:
+ {
+ \exp_not:N \if_false:
+ { \if_false: } \fi:
+ \exp_not:N \fi:
+ \char_generate:nn { `#1 } { 2 }
+ }
+ { \int_value:w `#1 }
+ 2
+ \fi:
+ \fi:
+ }
+ \l_@@_peek_code_tl
+ }
+% \end{macrocode}
+% Finally there is the case of a special token whose string
+% representation starts with an escape character, namely the token was
+% a control sequence. In that case we could have grabbed the token
+% directly as an \texttt{N}-type argument, but of course we couldn't
+% know that until we had run all the various tests including
+% stringifying the token. We are thus left with the hard work of
+% picking up one by one the characters in the csname (being careful
+% about spaces), until the constructed csname has the expected
+% meaning. This fails if someone defines a token like
+% \cs[no-index]{bgroup@my} whose string representation starts the same
+% as another token with the same meaning being an implicit character
+% token of category code $1$, $2$, or $10$.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_analysis_escape:
+ {
+ \tl_clear:N \l_@@_internal_a_tl
+ \tex_futurelet:D \l_@@_analysis_token
+ \@@_peek_analysis_collect:w
+ }
+\cs_new_protected:Npn \@@_peek_analysis_collect:w
+ { \@@_analysis_char_arg:Nw \@@_peek_analysis_collect:n }
+\cs_new_protected:Npn \@@_peek_analysis_collect:n #1
+ {
+ \tl_put_right:Nn \l_@@_internal_a_tl {#1}
+ \@@_peek_analysis_collect_loop:
+ }
+\cs_new_protected:Npn \@@_peek_analysis_collect_loop:
+ {
+ \exp_after:wN \if_meaning:w
+ \cs:w
+ \if_cs_exist:w \l_@@_internal_a_tl \cs_end:
+ \l_@@_internal_a_tl
+ \else:
+ c_one % anything short
+ \fi:
+ \cs_end:
+ \l_peek_token
+ \@@_peek_analysis_collect_end:NNNN
+ \fi:
+ \tex_futurelet:D \l_@@_analysis_token
+ \@@_peek_analysis_collect:w
+ }
+% \end{macrocode}
+% As in all other cases, end by calling the user code with suitable
+% arguments (here |#1| is \cs{fi:}).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_analysis_collect_end:NNNN #1#2#3#4
+ {
+ #1
+ \tl_put_right:Ne \l_@@_peek_code_tl
+ {
+ { \exp_not:N \exp_not:n { \exp_not:c { \l_@@_internal_a_tl } } }
+ { -1 }
+ 0
+ }
+ \l_@@_peek_code_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% \begin{variable}{\c_@@_analysis_show_etc_str}
+% When a control sequence (or active character)
+% and its meaning are too long to fit in one line
+% of the terminal, the end is replaced by this token list.
+% \begin{macrocode}
+\tl_const:Ne \c_@@_analysis_show_etc_str % (
+ { \token_to_str:N \ETC.) }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macrocode}
+\msg_new:nnn { tl } { show-analysis }
+ {
+ The~token~list~ \tl_if_empty:nF {#1} { #1 ~ }
+ \tl_if_empty:nTF {#2}
+ { is~empty }
+ { contains~the~tokens: #2 }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3tl-build.dtx b/macros/latex-dev/required/l3kernel/l3tl-build.dtx
new file mode 100644
index 0000000000..859dd5025c
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3tl-build.dtx
@@ -0,0 +1,356 @@
+% \iffalse meta-comment
+%
+%% File: l3tl-build.dtx
+%
+% Copyright (C) 2018-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3tl-build} module\\ Piecewise \texttt{tl} constructions^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{Constructing \meta{tl~var} by accumulation}
+%
+% When creating a \meta{tl~var} by accumulation of many tokens, the performance
+% available using a combination of \cs{tl_set:Nn} and \cs{tl_put_right:Nn} or
+% similar begins to become an issue. To address this, a set of functions are
+% available to \enquote{build} a \meta{tl~var}. The performance of this approach
+% is much more efficient than the standard \cs{tl_put_right:Nn}, but the
+% constructed token list cannot be accessed during construction other than
+% by methods provided in this section.
+%
+% Whilst the exact performance difference is dependent on the size of each
+% added block of tokens and the total number of blocks, in general, the
+% \cs[no-index]{tl_build_(g)put...} functions will out-perform the basic
+% \cs[no-index]{tl_(g)put...} equivalent if more than 100 non-empty addition
+% operations occur. See
+% \url{https://github.com/latex3/latex3/issues/1393#issuecomment-1880164756}
+% for a more detailed analysis.
+%
+% \begin{function}[added = 2018-04-01]{\tl_build_begin:N, \tl_build_gbegin:N}
+% \begin{syntax}
+% \cs{tl_build_begin:N} \meta{tl~var}
+% \end{syntax}
+% Clears the \meta{tl~var} and sets it up to support other
+% \cs[no-index]{tl_build_\ldots{}} functions. Until \cs{tl_build_end:N}
+% \meta{tl~var} or \cs{tl_build_gend:N} \meta{tl~var} is called,
+% applying any function from \pkg{l3tl} other
+% than \cs[no-index]{tl_build_\ldots{}} will lead to incorrect
+% results. The |begin| and |gbegin| functions must be used for local
+% and global \meta{tl~var} respectively.
+% \end{function}
+%
+% \begin{function}[added = 2018-04-01]
+% {
+% \tl_build_put_left:Nn, \tl_build_put_left:Ne,
+% \tl_build_gput_left:Nn, \tl_build_gput_left:Ne,
+% \tl_build_put_right:Nn, \tl_build_put_right:Ne,
+% \tl_build_gput_right:Nn, \tl_build_gput_right:Ne
+% }
+% \begin{syntax}
+% \cs{tl_build_put_left:Nn} \meta{tl~var} \Arg{tokens}
+% \cs{tl_build_put_right:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Adds \meta{tokens} to the left or right side of the current contents
+% of \meta{tl~var}. The \meta{tl~var} must have been set up with
+% \cs{tl_build_begin:N} or \cs{tl_build_gbegin:N}. The |put| and
+% |gput| functions must be used for local and global \meta{tl~var}
+% respectively. The |right| functions are about twice faster than the
+% |left| functions.
+% \end{function}
+%
+% \begin{function}[added = 2018-04-01]{\tl_build_end:N, \tl_build_gend:N}
+% \begin{syntax}
+% \cs{tl_build_end:N} \meta{tl~var}
+% \end{syntax}
+% Gets the contents of \meta{tl~var} and stores that into the
+% \meta{tl~var} using \cs{tl_set:Nn} or \cs{tl_gset:Nn}.
+% The \meta{tl~var} must have
+% been set up with \cs{tl_build_begin:N} or \cs{tl_build_gbegin:N}.
+% The |end| and |gend| functions must be used for local and global
+% \meta{tl~var} respectively. These functions completely remove the
+% setup code that enabled \meta{tl~var} to be used for other
+% \cs[no-index]{tl_build_\ldots{}} functions. After the action of
+% |end|/|gend|, the \meta{tl~var} may be manipulated using standard
+% \texttt{tl} functions.
+% \end{function}
+%
+% \begin{function}[added = 2023-12-14]{\tl_build_get_intermediate:NN}
+% \begin{syntax}
+% \cs{tl_build_get_intermediate:NN} \meta{tl~var_1} \meta{tl~var_2}
+% \end{syntax}
+% Stores the contents of the \meta{tl~var_1} in the \meta{tl~var_2}.
+% The \meta{tl~var_1} must have been set up with \cs{tl_build_begin:N}
+% or \cs{tl_build_gbegin:N}. The \meta{tl~var_2} is a
+% \enquote{normal} token list variable, assigned locally using
+% \cs{tl_set:Nn}.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3tl-build} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=tl>
+% \end{macrocode}
+%
+% Between \cs{tl_build_begin:N} \meta{tl~var} and \cs{tl_build_end:N}
+% \meta{tl~var}, the \meta{tl~var} has the structure
+% \begin{quote}
+% \cs{exp_end:} \ldots{} \cs{exp_end:} \cs{@@_build_last:NNn}
+% \meta{assignment} \meta{next~tl} \Arg{left} \meta{right}
+% \end{quote}
+% where \meta{right} is not braced. The \enquote{data} it represents is
+% \meta{left} followed by the \enquote{data} of \meta{next~tl} followed
+% by \meta{right}. The \meta{next~tl} is a token list variable whose
+% name is that of \meta{tl~var} followed by~|'|. There are between $0$
+% and $4$ \cs{exp_end:} to keep track of when \meta{left} and
+% \meta{right} should be put into the \meta{next~tl}. The
+% \meta{assignment} is \cs{cs_set_nopar:Npe} if the variable is local,
+% and \cs{cs_gset_nopar:Npe} if it is global.
+%
+% \begin{macro}{\tl_build_begin:N, \tl_build_gbegin:N}
+% \begin{macro}{\@@_build_begin:NN, \@@_build_begin:NNN}
+% First construct the \meta{next~tl}: using a prime here conflicts
+% with the usual \pkg{expl3} convention but we need a name that can be
+% derived from |#1| without any external data such as a counter.
+% Empty that \meta{next~tl} and setup the structure. The local and
+% global versions only differ by a single function
+% \cs[no-index]{cs_(g)set_nopar:Npe} used for all assignments: this is
+% important because only that function is stored in the \meta{tl~var}
+% and \meta{next~tl} for subsequent assignments. In principle
+% \cs{@@_build_begin:NNN} could use \cs[no-index]{tl_(g)clear_new:N}
+% to empty |#1| and make sure it is defined, but logging the
+% definition does not seem useful so we just do |#3| |#1| |{}| to
+% clear it locally or globally as appropriate.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_build_begin:N #1
+ { \@@_build_begin:NN \cs_set_nopar:Npe #1 }
+\cs_new_protected:Npn \tl_build_gbegin:N #1
+ { \@@_build_begin:NN \cs_gset_nopar:Npe #1 }
+\cs_new_protected:Npn \@@_build_begin:NN #1#2
+ { \exp_args:Nc \@@_build_begin:NNN { \cs_to_str:N #2 ' } #2 #1 }
+\cs_new_protected:Npn \@@_build_begin:NNN #1#2#3
+ {
+ #3 #1 { }
+ #3 #2
+ {
+ \exp_not:n { \exp_end: \exp_end: \exp_end: \exp_end: }
+ \exp_not:n { \@@_build_last:NNn #3 #1 { } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \tl_build_put_right:Nn, \tl_build_put_right:Ne, \tl_build_put_right:Nx,
+% \tl_build_gput_right:Nn, \tl_build_gput_right:Ne, \tl_build_gput_right:Nx
+% }
+% \begin{macro}{\@@_build_last:NNn}
+% \begin{macro}{\@@_build_put:nn}
+% \begin{macro}{\@@_build_put:nw}
+% Similar to \cs{tl_put_right:Nn}, but apply \cs{exp:w} to |#1|. Most
+% of the time this just removes one \cs{exp_end:}. When there are
+% none left, \cs{@@_build_last:NNn} is expanded instead. It resets
+% the definition of the \meta{tl~var} by ending the \cs{exp_not:n} and
+% the definition early. Then it makes sure the \meta{next~tl} (its
+% argument |#1|) is set-up and starts a new definition. Then
+% \cs{@@_build_put:nn} and \cs{@@_build_put:nw} place the \meta{left}
+% part of the original \meta{tl~var} as appropriate for the definition
+% of the \meta{next~tl} (the \meta{right} part is left in the right
+% place without ever becoming a macro argument). We use
+% \cs{exp_after:wN} rather than some \cs{exp_args:No} to avoid reading
+% arguments that are likely very long token lists. We use
+% \cs[no-index]{cs_(g)set_nopar:Npe} rather than
+% \cs[no-index]{tl_(g)set:Ne} partly for the same reason and partly
+% because the assignments are interrupted by brace tricks, which
+% implies that the assignment does not simply set the token list to an
+% |e|-expansion of the second argument.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_build_put_right:Nn #1#2
+ {
+ \cs_set_nopar:Npe #1
+ { \__kernel_exp_not:w \exp_after:wN { \exp:w #1 #2 } }
+ }
+\cs_generate_variant:Nn \tl_build_put_right:Nn { Ne , Nx }
+\cs_new_protected:Npn \tl_build_gput_right:Nn #1#2
+ {
+ \cs_gset_nopar:Npe #1
+ { \__kernel_exp_not:w \exp_after:wN { \exp:w #1 #2 } }
+ }
+\cs_generate_variant:Nn \tl_build_gput_right:Nn { Ne , Nx }
+\cs_new_protected:Npn \@@_build_last:NNn #1#2
+ {
+ \if_false: { { \fi:
+ \exp_end: \exp_end: \exp_end: \exp_end: \exp_end:
+ \@@_build_last:NNn #1 #2 { }
+ }
+ }
+ \if_meaning:w \c_empty_tl #2
+ \@@_build_begin:NN #1 #2
+ \fi:
+ #1 #2
+ {
+ \__kernel_exp_not:w \exp_after:wN
+ {
+ \exp:w \if_false: } } \fi:
+ \exp_after:wN \@@_build_put:nn \exp_after:wN {#2}
+ }
+\cs_new_protected:Npn \@@_build_put:nn #1#2 { \@@_build_put:nw {#2} #1 }
+\cs_new_protected:Npn \@@_build_put:nw #1#2 \@@_build_last:NNn #3#4#5
+ { #2 \@@_build_last:NNn #3 #4 { #1 #5 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \tl_build_put_left:Nn, \tl_build_put_left:Ne, \tl_build_put_left:Nx,
+% \tl_build_gput_left:Nn, \tl_build_gput_left:Ne, \tl_build_gput_left:Nx
+% }
+% \begin{macro}{\@@_build_put_left:NNn}
+% See \cs{tl_build_put_right:Nn} for all the machinery. We could
+% easily provide \cs[no-index]{tl_build_put_left_right:Nnn}, by just
+% adding the \meta{right} material after the \Arg{left} in the
+% |e|-expanding assignment.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_build_put_left:Nn #1
+ { \@@_build_put_left:NNn \cs_set_nopar:Npe #1 }
+\cs_generate_variant:Nn \tl_build_put_left:Nn { Ne , Nx }
+\cs_new_protected:Npn \tl_build_gput_left:Nn #1
+ { \@@_build_put_left:NNn \cs_gset_nopar:Npe #1 }
+\cs_generate_variant:Nn \tl_build_gput_left:Nn { Ne , Nx }
+\cs_new_protected:Npn \@@_build_put_left:NNn #1#2#3
+ {
+ #1 #2
+ {
+ \__kernel_exp_not:w \exp_after:wN
+ {
+ \exp:w \exp_after:wN \@@_build_put:nn
+ \exp_after:wN {#2} {#3}
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_build_end:N, \tl_build_gend:N}
+% \begin{macro}{\@@_build_end_loop:NN}
+% Get the data then clear the \meta{next~tl} recursively until finding
+% an empty one. It is perhaps wasteful to repeatedly use
+% \cs{cs_to_str:N}. The local/global scope is checked by
+% \cs{tl_set:Ne} or \cs{tl_gset:Ne}.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_build_end:N #1
+ {
+ \@@_build_get:NNN \__kernel_tl_set:Nx #1 #1
+ \exp_args:Nc \@@_build_end_loop:NN { \cs_to_str:N #1 ' } \tl_clear:N
+ }
+\cs_new_protected:Npn \tl_build_gend:N #1
+ {
+ \@@_build_get:NNN \__kernel_tl_gset:Nx #1 #1
+ \exp_args:Nc \@@_build_end_loop:NN { \cs_to_str:N #1 ' } \tl_gclear:N
+ }
+\cs_new_protected:Npn \@@_build_end_loop:NN #1#2
+ {
+ \if_meaning:w \c_empty_tl #1
+ \exp_after:wN \use_none:nnnnnn
+ \fi:
+ #2 #1
+ \exp_args:Nc \@@_build_end_loop:NN { \cs_to_str:N #1 ' } #2
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_build_get_intermediate:NN}
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_build_get_intermediate:NN
+ { \@@_build_get:NNN \__kernel_tl_set:Nx }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_build_get:NNN}
+% \begin{macro}{\@@_build_get:w, \@@_build_get_end:w}
+% The idea is to expand the \meta{tl~var} then the \meta{next~tl} and
+% so on, all within an |e|-expanding assignment, and wrap as
+% appropriate in \cs{exp_not:n}. The various \meta{left} parts are
+% left in the assignment as we go, which enables us to expand the
+% \meta{next~tl} at the right place. The various \meta{right} parts
+% are eventually picked up in one last \cs{exp_not:n}, with a brace
+% trick to wrap all the \meta{right} parts together.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_build_get:NNN #1#2#3
+ { #1 #3 { \if_false: { \fi: \exp_after:wN \@@_build_get:w #2 } } }
+\cs_new:Npn \@@_build_get:w #1 \@@_build_last:NNn #2#3#4
+ {
+ \exp_not:n {#4}
+ \if_meaning:w \c_empty_tl #3
+ \exp_after:wN \@@_build_get_end:w
+ \fi:
+ \exp_after:wN \@@_build_get:w #3
+ }
+\cs_new:Npn \@@_build_get_end:w #1#2#3
+ { \__kernel_exp_not:w \exp_after:wN { \if_false: } \fi: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3tl.dtx b/macros/latex-dev/required/l3kernel/l3tl.dtx
new file mode 100644
index 0000000000..30e16636e5
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3tl.dtx
@@ -0,0 +1,3843 @@
+% \iffalse meta-comment
+%
+%% File: l3tl.dtx
+%
+% Copyright (C) 1990-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3tl} module\\ Token lists^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \TeX{} works with tokens, and \LaTeX3 therefore provides a number of
+% functions to deal with lists of tokens. Token lists may be present
+% directly in the argument to a function:
+% \begin{verbatim}
+% \foo:n { a collection of \tokens }
+% \end{verbatim}
+% or may be stored in a so-called \enquote{token list variable}, which
+% have the suffix \texttt{tl}: a token list variable can also be used as
+% the argument to a function, for example
+% \begin{verbatim}
+% \foo:N \l_some_tl
+% \end{verbatim}
+% In both cases, functions are available to test and manipulate the lists
+% of tokens, and these have the module prefix \texttt{tl}.
+% In many cases, functions which can be applied to token list variables
+% are paired with similar functions for application to explicit lists
+% of tokens: the two \enquote{views} of a token list are therefore collected
+% together here.
+%
+% A token list (explicit, or stored in a variable) can be seen either
+% as a list of \enquote{items},
+% or a list of \enquote{tokens}. An item is whatever \cs{use:n} would
+% grab as its argument: a single non-space token or a brace group,
+% with optional leading explicit space characters (each item is thus
+% itself a token list). A token is either a normal \texttt{N} argument,
+% or \verb*| |, |{|, or |}| (assuming normal \TeX{} category codes).
+% Thus for example
+% \begin{verbatim}
+% { Hello } ~ world
+% \end{verbatim}
+% contains six items (\texttt{Hello}, \texttt{w}, \texttt{o}, \texttt{r},
+% \texttt{l} and \texttt{d}), but thirteen tokens (|{|, \texttt{H}, \texttt{e},
+% \texttt{l}, \texttt{l}, \texttt{o}, |}|, \verb*| |, \texttt{w}, \texttt{o},
+% \texttt{r}, \texttt{l} and \texttt{d}).
+% Functions which act on items are often faster than their analogue acting
+% directly on tokens.
+%
+% \section{Creating and initialising token list variables}
+%
+% \begin{function}{\tl_new:N, \tl_new:c}
+% \begin{syntax}
+% \cs{tl_new:N} \meta{tl~var}
+% \end{syntax}
+% Creates a new \meta{tl~var} or raises an error if the
+% name is already taken. The declaration is global. The
+% \meta{tl~var} is initially empty.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_const:Nn, \tl_const:Ne,
+% \tl_const:cn, \tl_const:ce
+% }
+% \begin{syntax}
+% \cs{tl_const:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Creates a new constant \meta{tl~var} or raises an error
+% if the name is already taken. The value of the
+% \meta{tl~var} is set globally to the \meta{tokens}.
+% \end{function}
+%
+% \begin{function}{\tl_clear:N, \tl_clear:c, \tl_gclear:N, \tl_gclear:c}
+% \begin{syntax}
+% \cs{tl_clear:N} \meta{tl~var}
+% \end{syntax}
+% Clears all entries from the \meta{tl~var}.
+% \end{function}
+%
+% \begin{function}
+% {\tl_clear_new:N, \tl_clear_new:c, \tl_gclear_new:N, \tl_gclear_new:c}
+% \begin{syntax}
+% \cs{tl_clear_new:N} \meta{tl~var}
+% \end{syntax}
+% Ensures that the \meta{tl~var} exists globally by applying
+% \cs{tl_new:N} if necessary, then applies \cs[index=tl_clear:N]{tl_(g)clear:N} to leave
+% the \meta{tl~var} empty.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_set_eq:NN, \tl_set_eq:cN, \tl_set_eq:Nc, \tl_set_eq:cc,
+% \tl_gset_eq:NN, \tl_gset_eq:cN, \tl_gset_eq:Nc, \tl_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{tl_set_eq:NN} \meta{tl~var_1} \meta{tl~var_2}
+% \end{syntax}
+% Sets the content of \meta{tl~var_1} equal to that of
+% \meta{tl~var_2}.
+% \end{function}
+%
+% \begin{function}[added = 2012-05-18]
+% {
+% \tl_concat:NNN, \tl_concat:ccc,
+% \tl_gconcat:NNN, \tl_gconcat:ccc
+% }
+% \begin{syntax}
+% \cs{tl_concat:NNN} \meta{tl~var_1} \meta{tl~var_2} \meta{tl~var_3}
+% \end{syntax}
+% Concatenates the content of \meta{tl~var_2} and \meta{tl~var_3}
+% together and saves the result in \meta{tl~var_1}. The \meta{tl~var_2}
+% is placed at the left side of the new token list.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, added=2012-03-03]{\tl_if_exist:N, \tl_if_exist:c}
+% \begin{syntax}
+% \cs{tl_if_exist_p:N} \meta{tl~var}
+% \cs{tl_if_exist:NTF} \meta{tl~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{tl~var} is currently defined. This does not
+% check that the \meta{tl~var} really is a token list variable.
+% \end{function}
+%
+% \section{Adding data to token list variables}
+%
+% \begin{function}
+% {
+% \tl_set:Nn, \tl_set:NV, \tl_set:Nv, \tl_set:No, \tl_set:Ne, \tl_set:Nf,
+% \tl_set:cn, \tl_set:cV, \tl_set:cv, \tl_set:co, \tl_set:ce, \tl_set:cf,
+% \tl_gset:Nn, \tl_gset:NV, \tl_gset:Nv,
+% \tl_gset:No, \tl_gset:Ne, \tl_gset:Nf,
+% \tl_gset:cn, \tl_gset:cV, \tl_gset:cv,
+% \tl_gset:co, \tl_gset:ce, \tl_gset:cf
+% }
+% \begin{syntax}
+% \cs{tl_set:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Sets \meta{tl~var} to contain \meta{tokens},
+% removing any previous content from the variable.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_put_left:Nn, \tl_put_left:NV, \tl_put_left:Nv, \tl_put_left:Ne,
+% \tl_put_left:No,
+% \tl_put_left:cn, \tl_put_left:cV, \tl_put_left:cv, \tl_put_left:ce,
+% \tl_put_left:co,
+% \tl_gput_left:Nn, \tl_gput_left:NV, \tl_gput_left:Nv, \tl_gput_left:Ne,
+% \tl_gput_left:No,
+% \tl_gput_left:cn, \tl_gput_left:cV, \tl_gput_left:cv, \tl_gput_left:ce,
+% \tl_gput_left:co
+% }
+% \begin{syntax}
+% \cs{tl_put_left:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Appends \meta{tokens} to the left side of the current content of
+% \meta{tl~var}.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_put_right:Nn, \tl_put_right:NV, \tl_put_right:Nv, \tl_put_right:Ne,
+% \tl_put_right:No,
+% \tl_put_right:cn, \tl_put_right:cV, \tl_put_right:cv, \tl_put_right:ce,
+% \tl_put_right:co,
+% \tl_gput_right:Nn, \tl_gput_right:NV, \tl_gput_right:Nv, \tl_gput_right:Ne,
+% \tl_gput_right:No,
+% \tl_gput_right:cn, \tl_gput_right:cV, \tl_gput_right:cv, \tl_gput_right:ce,
+% \tl_gput_right:co
+% }
+% \begin{syntax}
+% \cs{tl_put_right:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Appends \meta{tokens} to the right side of the current content of
+% \meta{tl~var}.
+% \end{function}
+%
+% \section{Token list conditionals}
+%
+% \begin{function}[EXP,pTF, updated = 2019-09-04]
+% {\tl_if_blank:n, \tl_if_blank:e, \tl_if_blank:V, \tl_if_blank:o}
+% \begin{syntax}
+% \cs{tl_if_blank_p:n} \Arg{token list}
+% \cs{tl_if_blank:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} consists only of blank spaces
+% (\emph{i.e.}~contains no item). The test is \texttt{true} if
+% \meta{token list} is zero or more explicit space characters
+% (explicit tokens with character code~$32$ and category code~$10$),
+% and is \texttt{false} otherwise.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_empty:N, \tl_if_empty:c}
+% \begin{syntax}
+% \cs{tl_if_empty_p:N} \meta{tl~var}
+% \cs{tl_if_empty:NTF} \meta{tl~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{tl~var} is entirely empty
+% (\emph{i.e.}~contains no tokens at all).
+% \end{function}
+%
+% \begin{function}[added = 2012-05-24, updated = 2012-06-05, EXP,pTF]
+% {\tl_if_empty:n, \tl_if_empty:V, \tl_if_empty:o, \tl_if_empty:e}
+% \begin{syntax}
+% \cs{tl_if_empty_p:n} \Arg{token list}
+% \cs{tl_if_empty:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} is entirely empty
+% (\emph{i.e.}~contains no tokens at all).
+% \end{function}
+%
+% \begin{function}[EXP,pTF]
+% {\tl_if_eq:NN, \tl_if_eq:Nc, \tl_if_eq:cN, \tl_if_eq:cc}
+% \begin{syntax}
+% \cs{tl_if_eq_p:NN} \meta{tl~var_1} \meta{tl~var_2}
+% \cs{tl_if_eq:NNTF} \meta{tl~var_1} \meta{tl~var_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Compares the content of \meta{tl~var_1} and \meta{tl~var_2} and
+% is logically \texttt{true} if the two contain the same list of
+% tokens (\emph{i.e.}~identical in both the list of characters they
+% contain and the category codes of those characters). Thus for example
+% \begin{verbatim}
+% \tl_set:Nn \l_tmpa_tl { abc }
+% \tl_set:Ne \l_tmpb_tl { \tl_to_str:n { abc } }
+% \tl_if_eq:NNTF \l_tmpa_tl \l_tmpb_tl { true } { false }
+% \end{verbatim}
+% yields \texttt{false}.
+% See also \cs{str_if_eq:nnTF} for a comparison that ignores category codes.
+% \end{function}
+%
+% \begin{function}[TF, added = 2020-07-14]{\tl_if_eq:Nn, \tl_if_eq:cn}
+% \begin{syntax}
+% \cs{tl_if_eq:NnTF} \meta{tl~var_1} \Arg{token list_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{tl~var_1} and the \meta{token
+% list_2} contain the same list of tokens, both in respect of
+% character codes and category codes. This conditional is not
+% expandable: see \cs{tl_if_eq:NNTF} for an expandable version when
+% both token lists are stored in variables, or \cs{str_if_eq:nnTF} if
+% category codes are not important.
+% \end{function}
+%
+% \begin{function}[TF]
+% {
+% \tl_if_eq:nn, \tl_if_eq:nV, \tl_if_eq:ne, \tl_if_eq:Vn, \tl_if_eq:en,
+% \tl_if_eq:ee
+% }
+% \begin{syntax}
+% \cs{tl_if_eq:nnTF} \Arg{token list_1} \Arg{token list_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{token list_1} and \meta{token list_2} contain the
+% same list of tokens, both in respect of character codes and category
+% codes. This conditional is not expandable: see \cs{tl_if_eq:NNTF}
+% for an expandable version when token lists are stored in variables,
+% or \cs{str_if_eq:nnTF} if category codes are not important.
+% \end{function}
+%
+% \begin{function}[TF]
+% {
+% \tl_if_in:Nn, \tl_if_in:NV, \tl_if_in:No,
+% \tl_if_in:cn, \tl_if_in:cV, \tl_if_in:co
+% }
+% \begin{syntax}
+% \cs{tl_if_in:NnTF} \meta{tl~var} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} is found in the content of the
+% \meta{tl~var}. The \meta{token list} cannot contain
+% the tokens |{|, |}| or |#|
+% (more precisely, explicit character tokens with category code $1$
+% (begin-group) or $2$ (end-group), and tokens with category code $6$).
+% \end{function}
+%
+% \begin{function}[TF]
+% {
+% \tl_if_in:nn, \tl_if_in:Vn, \tl_if_in:VV, \tl_if_in:on, \tl_if_in:oo,
+% \tl_if_in:nV, \tl_if_in:no
+% }
+% \begin{syntax}
+% \cs{tl_if_in:nnTF} \Arg{token list_1} \Arg{token list_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{token list_2} is found inside \meta{token list_1}.
+% The \meta{token list_2} cannot contain the tokens |{|, |}| or |#|
+% (more precisely, explicit character tokens with category code $1$
+% (begin-group) or $2$ (end-group), and tokens with category code $6$).
+% The search does \emph{not} enter brace (category code $1$/$2$) groups.
+% \end{function}
+%
+% \begin{function}[added = 2017-11-14, EXP,pTF]{\tl_if_novalue:n}
+% \begin{syntax}
+% \cs{tl_if_novalue_p:n} \Arg{token list}
+% \cs{tl_if_novalue:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} and the special \cs{c_novalue_tl} marker
+% contain the same list of tokens, both in respect of character codes and
+% category codes. This means that
+% \cs{exp_args:No} \cs{tl_if_novalue:nTF} \{ \cs{c_novalue_tl} \} is
+% logically \texttt{true} but \cs{tl_if_novalue:nTF} \{ \cs{c_novalue_tl} \}
+% is logically \texttt{false}.
+% This function is intended to allow construction
+% of flexible document interface structures in which missing optional
+% arguments are detected.
+% \end{function}
+%
+% \begin{function}[updated = 2011-08-13, EXP,pTF]
+% {\tl_if_single:N, \tl_if_single:c}
+% \begin{syntax}
+% \cs{tl_if_single_p:N} \meta{tl~var}
+% \cs{tl_if_single:NTF} \meta{tl~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the content of the \meta{tl~var} consists of a single \meta{item},
+% \emph{i.e.}~is a single normal token (neither an explicit space
+% character nor a begin-group character) or a single brace group,
+% surrounded by optional spaces on both sides. In other words, such a
+% token list has token count $1$ according to \cs{tl_count:N}.
+% \end{function}
+%
+% \begin{function}[updated = 2011-08-13, EXP,pTF]{\tl_if_single:n}
+% \begin{syntax}
+% \cs{tl_if_single_p:n} \Arg{token list}
+% \cs{tl_if_single:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} has exactly one \meta{item}, \emph{i.e.}~is
+% a single normal token (neither an explicit space character nor a
+% begin-group character) or a single brace group, surrounded by
+% optional spaces on both sides. In other words, such a token list has
+% token count $1$ according to \cs{tl_count:n}.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_single_token:n}
+% \begin{syntax}
+% \cs{tl_if_single_token_p:n} \Arg{token list}
+% \cs{tl_if_single_token:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the token list consists of exactly one token, \emph{i.e.}~is
+% either a single space character or a single normal token.
+% Token groups (|{|\ldots|}|) are not single tokens.
+% \end{function}
+%
+% \subsection{Testing the first token}
+%
+% \begin{function}[updated = 2012-07-09, EXP, pTF]
+% {
+% \tl_if_head_eq_catcode:nN, \tl_if_head_eq_catcode:VN,
+% \tl_if_head_eq_catcode:eN, \tl_if_head_eq_catcode:oN
+% }
+% \begin{syntax}
+% \cs{tl_if_head_eq_catcode_p:nN} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_catcode:nNTF} \Arg{token list} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the first \meta{token} in the \meta{token list} has the
+% same category code as the \meta{test token}. In the case where the
+% \meta{token list} is empty, the test is always \texttt{false}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-07-09, EXP, pTF]
+% {
+% \tl_if_head_eq_charcode:nN, \tl_if_head_eq_charcode:VN,
+% \tl_if_head_eq_charcode:eN, \tl_if_head_eq_charcode:fN
+% }
+% \begin{syntax}
+% \cs{tl_if_head_eq_charcode_p:nN} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_charcode:nNTF} \Arg{token list} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the first \meta{token} in the \meta{token list} has the
+% same character code as the \meta{test token}. In the case where the
+% \meta{token list} is empty, the test is always \texttt{false}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-07-09, EXP, pTF]
+% {
+% \tl_if_head_eq_meaning:nN, \tl_if_head_eq_meaning:VN,
+% \tl_if_head_eq_meaning:eN
+% }
+% \begin{syntax}
+% \cs{tl_if_head_eq_meaning_p:nN} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_meaning:nNTF} \Arg{token list} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the first \meta{token} in the \meta{token list} has the
+% same meaning as the \meta{test token}. In the case where
+% \meta{token list} is empty, the test is always \texttt{false}.
+% \end{function}
+%
+% \begin{function}[added = 2012-07-08, EXP, pTF]{\tl_if_head_is_group:n}
+% \begin{syntax}
+% \cs{tl_if_head_is_group_p:n} \Arg{token list}
+% \cs{tl_if_head_is_group:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the first \meta{token} in the \meta{token list}
+% is an explicit begin-group character (with category code~$1$
+% and any character code), in other words, if the \meta{token list}
+% starts with a brace group. In particular, the test is \texttt{false}
+% if the \meta{token list} starts with an implicit token such as
+% \cs{c_group_begin_token}, or if it is empty.
+% This function is useful to implement actions on token lists on
+% a token by token basis.
+% \end{function}
+%
+% \begin{function}[added = 2012-07-08, EXP, pTF]{\tl_if_head_is_N_type:n}
+% \begin{syntax}
+% \cs{tl_if_head_is_N_type_p:n} \Arg{token list}
+% \cs{tl_if_head_is_N_type:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the first \meta{token} in the \meta{token list}
+% is a normal \texttt{N}-type argument. In other words,
+% it is neither an explicit space character
+% (explicit token with character code~$32$ and category code~$10$)
+% nor an explicit begin-group character
+% (with category code~1 and any character code). An empty
+% argument yields \texttt{false}, as it does not have a normal
+% first token.
+% This function is useful to implement actions on token lists on
+% a token by token basis.
+% \end{function}
+%
+% \begin{function}[updated = 2012-07-08, EXP, pTF]{\tl_if_head_is_space:n}
+% \begin{syntax}
+% \cs{tl_if_head_is_space_p:n} \Arg{token list}
+% \cs{tl_if_head_is_space:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the first \meta{token} in the \meta{token list}
+% is an explicit space character
+% (explicit token with character code~$32$ and category code~$10$).
+% In particular, the test is \texttt{false} if the \meta{token list}
+% starts with an implicit token such as \cs{c_space_token}, or if it
+% is empty.
+% This function is useful to implement actions on token lists on
+% a token by token basis.
+% \end{function}
+%
+% \section{Working with token lists as a whole}
+%
+% \subsection{Using token lists}
+%
+% \begin{function}[EXP]
+% {\tl_to_str:n, \tl_to_str:o, \tl_to_str:V, \tl_to_str:v, \tl_to_str:e}
+% \begin{syntax}
+% \cs{tl_to_str:n} \Arg{token list}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string}, leaving the
+% resulting character tokens in the input stream. A \meta{string}
+% is a series of tokens with category code $12$ (other) with the exception
+% of spaces, which retain category code $10$ (space).
+% The base function requires only a single expansion.
+% Its argument \emph{must} be braced.
+% \begin{texnote}
+% This is the \eTeX{} primitive \tn{detokenize}.
+% Converting a \meta{token list} to a \meta{string} yields a
+% concatenation of the string representations of every token in the
+% \meta{token list}.
+% The string representation of a control sequence is
+% \begin{itemize}
+% \item an escape character, whose character code is given by the
+% internal parameter \tn{escapechar}, absent if the
+% \tn{escapechar} is negative or greater than the largest
+% character code;
+% \item the control sequence name, as defined by \cs{cs_to_str:N};
+% \item a space, unless the control sequence name is a single
+% character whose category at the time of expansion of
+% \cs{tl_to_str:n} is not \enquote{letter}.
+% \end{itemize}
+% The string representation of an explicit character token is that
+% character, doubled in the case of (explicit) macro parameter
+% characters (normally |#|).
+% In particular, the string representation of a token list may
+% depend on the category codes in effect when it is evaluated, and
+% the value of the \tn{escapechar}: for instance |\tl_to_str:n {\a}|
+% normally produces the three character \enquote{backslash},
+% \enquote{lower-case a}, \enquote{space}, but it may also produce a
+% single \enquote{lower-case a} if the escape character is negative
+% and \texttt{a} is currently not a letter.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_to_str:N, \tl_to_str:c}
+% \begin{syntax}
+% \cs{tl_to_str:N} \meta{tl~var}
+% \end{syntax}
+% Converts the content of the \meta{tl~var} into a series of characters
+% with category code $12$ (other) with the exception of spaces, which
+% retain category code $10$ (space). This \meta{string} is then left
+% in the input stream. For low-level details, see the notes given for
+% \cs{tl_to_str:n}.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_use:N, \tl_use:c}
+% \begin{syntax}
+% \cs{tl_use:N} \meta{tl~var}
+% \end{syntax}
+% Recovers the content of a \meta{tl~var} and places it
+% directly in the input stream. An error is raised if the variable
+% does not exist or if it is invalid. Note that it is possible to use
+% a \meta{tl~var} directly without an accessor function.
+% \end{function}
+%
+% \subsection{Counting and reversing token lists}
+%
+% \begin{function}[added = 2012-05-13, EXP]
+% {\tl_count:n, \tl_count:V, \tl_count:v, \tl_count:e, \tl_count:o}
+% \begin{syntax}
+% \cs{tl_count:n} \Arg{token list}
+% \end{syntax}
+% Counts the number of \meta{items} in the \meta{token list} and leaves this
+% information in the input stream. Unbraced tokens count as one
+% element as do each token group (|{|\ldots|}|). This process
+% ignores any unprotected spaces within the \meta{token list}. See also
+% \cs{tl_count:N}. This function requires three expansions,
+% giving an \meta{integer denotation}.
+% \end{function}
+%
+% \begin{function}[added = 2012-05-13, EXP]{\tl_count:N, \tl_count:c}
+% \begin{syntax}
+% \cs{tl_count:N} \meta{tl~var}
+% \end{syntax}
+% Counts the number of \meta{items} in the \meta{tl~var}
+% and leaves this information in the input stream. Unbraced tokens
+% count as one element as do each token group (|{|\ldots|}|). This
+% process ignores any unprotected spaces within the \meta{tl~var}.
+% See also \cs{tl_count:n}. This function requires three expansions,
+% giving an \meta{integer denotation}.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2019-02-25]{\tl_count_tokens:n}
+% \begin{syntax}
+% \cs{tl_count_tokens:n} \Arg{token list}
+% \end{syntax}
+% Counts the number of \TeX{} tokens in the \meta{token list} and leaves
+% this information in the input stream. Every token, including spaces and
+% braces, contributes one to the total; thus for instance, the token count of
+% |a~{bc}| is $6$.
+% \end{function}
+%
+% \begin{function}[updated = 2012-01-08, EXP]
+% {\tl_reverse:n, \tl_reverse:V, \tl_reverse:o, \tl_reverse:f, \tl_reverse:e}
+% \begin{syntax}
+% \cs{tl_reverse:n} \Arg{token list}
+% \end{syntax}
+% Reverses the order of the \meta{items} in the \meta{token list},
+% so that \meta{item_1}\meta{item_2}\meta{item_3} \ldots \meta{item_n}
+% becomes \meta{item_n}\ldots \meta{item_3}\meta{item_2}\meta{item_1}.
+% This process preserves unprotected space within the
+% \meta{token list}. Tokens are not reversed within braced token
+% groups, which keep their outer set of braces.
+% In situations where performance is important,
+% consider \cs{tl_reverse_items:n}.
+% See also \cs{tl_reverse:N}.
+% \begin{texnote}
+% The result is returned within \tn{unexpanded}, which means that the token
+% list does not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[updated = 2012-01-08]
+% {\tl_reverse:N, \tl_reverse:c, \tl_greverse:N, \tl_greverse:c}
+% \begin{syntax}
+% \cs{tl_reverse:N} \meta{tl~var}
+% \end{syntax}
+% Sets the \meta{tl~var} to contain the result of reversing
+% the order of its \meta{items}, so
+% that \meta{item_1}\meta{item_2}\meta{item_3} \ldots \meta{item_n}
+% becomes \meta{item_n}\ldots \meta{item_3}\meta{item_2}\meta{item_1}.
+% This process preserves unprotected spaces within the
+% \meta{tl~var}. Braced token groups are copied without
+% reversing the order of tokens, but keep the outer set of braces.
+% This is equivalent to a combination of an assignment and
+% \cs{tl_reverse:V}. See also \cs{tl_reverse_items:n} for improved
+% performance.
+% \end{function}
+%
+% \begin{function}[added = 2012-01-08, EXP]{\tl_reverse_items:n}
+% \begin{syntax}
+% \cs{tl_reverse_items:n} \Arg{token list}
+% \end{syntax}
+% Reverses the order of the \meta{items} in the \meta{token list},
+% so that \meta{item_1}\meta{item_2}\meta{item_3} \ldots \meta{item_n}
+% becomes \Arg{item_n} \ldots{} \Arg{item_3}\Arg{item_2}\Arg{item_1}.
+% This process removes any unprotected space within the
+% \meta{token list}. Braced token groups are copied without
+% reversing the order of tokens, and keep the outer set of braces.
+% Items which are initially not braced are copied with braces in
+% the result. In cases where preserving spaces is important,
+% consider the slower function \cs{tl_reverse:n}.
+% \begin{texnote}
+% The result is returned within \tn{unexpanded}, which means that the token
+% list does not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2011-07-09, updated = 2012-06-25, EXP]
+% {
+% \tl_trim_spaces:n, \tl_trim_spaces:V, \tl_trim_spaces:v,
+% \tl_trim_spaces:e,
+% \tl_trim_spaces:o
+% }
+% \begin{syntax}
+% \cs{tl_trim_spaces:n} \Arg{token list}
+% \end{syntax}
+% Removes any leading and trailing explicit space characters
+% (explicit tokens with character code~$32$ and category code~$10$)
+% from the \meta{token list} and leaves the result in the input
+% stream.
+% \begin{texnote}
+% The result is returned within \tn{unexpanded}, which means that the token
+% list does not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2018-04-12, EXP]
+% {\tl_trim_spaces_apply:nN, \tl_trim_spaces_apply:oN}
+% \begin{syntax}
+% \cs{tl_trim_spaces_apply:nN} \Arg{token list} \meta{function}
+% \end{syntax}
+% Removes any leading and trailing explicit space characters (explicit
+% tokens with character code~$32$ and category code~$10$) from the
+% \meta{token list} and passes the result to the \meta{function} as an
+% \texttt{n}-type argument.
+% \end{function}
+%
+% \begin{function}[added = 2011-07-09]
+% {
+% \tl_trim_spaces:N, \tl_trim_spaces:c,
+% \tl_gtrim_spaces:N, \tl_gtrim_spaces:c
+% }
+% \begin{syntax}
+% \cs{tl_trim_spaces:N} \meta{tl~var}
+% \end{syntax}
+% Sets the \meta{tl~var} to contain the result of removing any leading
+% and trailing explicit space characters (explicit tokens with
+% character code~$32$ and category code~$10$) from its contents.
+% \end{function}
+%
+% \subsection{Viewing token lists}
+%
+% \begin{function}[updated = 2021-04-29]{\tl_show:N, \tl_show:c}
+% \begin{syntax}
+% \cs{tl_show:N} \meta{tl~var}
+% \end{syntax}
+% Displays the content of the \meta{tl~var} on the terminal.
+% \begin{texnote}
+% This is similar to the \TeX{} primitive \tn{show}, wrapped to a
+% fixed number of characters per line.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[updated = 2015-08-07]{\tl_show:n, \tl_show:e}
+% \begin{syntax}
+% \cs{tl_show:n} \Arg{token list}
+% \end{syntax}
+% Displays the \meta{token list} on the terminal.
+% \begin{texnote}
+% This is similar to the \eTeX{} primitive \tn{showtokens}, wrapped
+% to a fixed number of characters per line.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2021-04-29]{\tl_log:N, \tl_log:c}
+% \begin{syntax}
+% \cs{tl_log:N} \meta{tl~var}
+% \end{syntax}
+% Writes the content of the \meta{tl~var} in the log file. See also
+% \cs{tl_show:N} which displays the result in the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2015-08-07]
+% {\tl_log:n, \tl_log:e, \tl_log:x}
+% \begin{syntax}
+% \cs{tl_log:n} \Arg{token list}
+% \end{syntax}
+% Writes the \meta{token list} in the log file. See also
+% \cs{tl_show:n} which displays the result in the terminal.
+% \end{function}
+%
+% \section{Manipulating items in token lists}
+%
+% \subsection{Mapping over token lists}
+%
+% All mappings are done at the current group level, \emph{i.e.}~any
+% local assignments made by the \meta{function} or \meta{code} discussed
+% below remain in effect after the loop.
+%
+% \begin{function}[updated = 2012-06-29, rEXP]
+% {\tl_map_function:NN, \tl_map_function:cN}
+% \begin{syntax}
+% \cs{tl_map_function:NN} \meta{tl~var} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every \meta{item} in the \meta{tl~var}.
+% The \meta{function} receives one argument for each iteration.
+% This may be a number of tokens if the \meta{item} was stored within
+% braces. Hence the \meta{function} should anticipate receiving
+% \texttt{n}-type arguments. See also \cs{tl_map_function:nN}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-06-29, rEXP]{\tl_map_function:nN}
+% \begin{syntax}
+% \cs{tl_map_function:nN} \Arg{token list} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every \meta{item} in the \meta{token list},
+% The \meta{function} receives one argument for each iteration.
+% This may be a number of tokens if the \meta{item} was stored within
+% braces. Hence the \meta{function} should anticipate receiving
+% \texttt{n}-type arguments. See also \cs{tl_map_function:NN}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-06-29]
+% {\tl_map_inline:Nn, \tl_map_inline:cn}
+% \begin{syntax}
+% \cs{tl_map_inline:Nn} \meta{tl~var} \Arg{inline function}
+% \end{syntax}
+% Applies the \meta{inline function} to every \meta{item} stored within the
+% \meta{tl~var}. The \meta{inline function} should consist of code which
+% receives the \meta{item} as |#1|. See also \cs{tl_map_function:NN}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-06-29]{\tl_map_inline:nn}
+% \begin{syntax}
+% \cs{tl_map_inline:nn} \Arg{token list} \Arg{inline function}
+% \end{syntax}
+% Applies the \meta{inline function} to every \meta{item} stored within the
+% \meta{token list}. The \meta{inline function} should consist of code which
+% receives the \meta{item} as |#1|. See also \cs{tl_map_function:nN}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2019-09-02]
+% {\tl_map_tokens:Nn, \tl_map_tokens:cn, \tl_map_tokens:nn}
+% \begin{syntax}
+% \cs{tl_map_tokens:Nn} \meta{tl~var} \Arg{code}
+% \cs{tl_map_tokens:nn} \Arg{token list} \Arg{code}
+% \end{syntax}
+% Analogue of \cs{tl_map_function:NN} which maps several tokens
+% instead of a single function. The \meta{code} receives each \meta{item} in
+% the \meta{tl~var} or in the \meta{token list} as a trailing brace group. For
+% instance,
+% \begin{verbatim}
+% \tl_map_tokens:Nn \l_my_tl { \prg_replicate:nn { 2 } }
+% \end{verbatim}
+% expands to twice each \meta{item} in the \meta{tl~var}: for each \meta{item} in
+% \cs[no-index]{l_my_tl} the function \cs{prg_replicate:nn} receives |2| and
+% \meta{item} as its two arguments. The function
+% \cs{tl_map_inline:Nn} is typically faster but is not expandable.
+% \end{function}
+%
+% \begin{function}[updated = 2012-06-29]
+% {\tl_map_variable:NNn, \tl_map_variable:cNn}
+% \begin{syntax}
+% \cs{tl_map_variable:NNn} \meta{tl~var} \meta{variable} \Arg{code}
+% \end{syntax}
+% Stores each \meta{item} of the \meta{tl~var} in turn in the (token
+% list) \meta{variable} and applies the \meta{code}. The \meta{code}
+% will usually make use of the \meta{variable}, but this is not
+% enforced. The assignments to the \meta{variable} are local. Its
+% value after the loop is the last \meta{item} in the \meta{tl~var},
+% or its original value if the \meta{tl~var} is blank. See also
+% \cs{tl_map_inline:Nn}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-06-29]{\tl_map_variable:nNn}
+% \begin{syntax}
+% \cs{tl_map_variable:nNn} \Arg{token list} \meta{variable} \Arg{code}
+% \end{syntax}
+% Stores each \meta{item} of the \meta{token list} in turn in the
+% (token list) \meta{variable} and applies the \meta{code}. The
+% \meta{code} will usually make use of the \meta{variable}, but this
+% is not enforced. The assignments to the \meta{variable} are local.
+% Its value after the loop is the last \meta{item} in the
+% \meta{tl~var}, or its original value if the \meta{tl~var} is blank.
+% See also \cs{tl_map_inline:nn}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-06-29, rEXP]{\tl_map_break:}
+% \begin{syntax}
+% \cs{tl_map_break:}
+% \end{syntax}
+% Used to terminate a \cs[no-index]{tl_map_\ldots} function before all
+% entries in the \meta{token list} have been processed. This
+% normally takes place within a conditional statement, for example
+% \begin{verbatim}
+% \tl_map_inline:Nn \l_my_tl
+% {
+% \str_if_eq:nnT { #1 } { bingo } { \tl_map_break: }
+% % Do something useful
+% }
+% \end{verbatim}
+% See also \cs{tl_map_break:n}.
+% Use outside of a \cs[no-index]{tl_map_\ldots} scenario leads to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted
+% before further items are taken
+% from the input stream. This depends on the design of the mapping
+% function.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[updated = 2012-06-29, rEXP]{\tl_map_break:n}
+% \begin{syntax}
+% \cs{tl_map_break:n} \Arg{code}
+% \end{syntax}
+% Used to terminate a \cs[no-index]{tl_map_\ldots} function before all
+% entries in the \meta{token list} have been processed, inserting
+% the \meta{code} after the mapping has ended. This
+% normally takes place within a conditional statement, for example
+% \begin{verbatim}
+% \tl_map_inline:Nn \l_my_tl
+% {
+% \str_if_eq:nnT { #1 } { bingo }
+% { \tl_map_break:n { <code> } }
+% % Do something useful
+% }
+% \end{verbatim}
+% Use outside of a \cs[no-index]{tl_map_\ldots} scenario leads to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted
+% before the \meta{code} is
+% inserted into the input stream.
+% This depends on the design of the mapping function.
+% \end{texnote}
+% \end{function}
+%
+% \subsection{Head and tail of token lists}
+%
+% Functions which deal with either only the very first item (balanced
+% text or single normal token) in a token list, or the remaining tokens.
+%
+% \begin{function}[updated = 2012-09-09, EXP]
+% {\tl_head:N, \tl_head:n, \tl_head:V, \tl_head:v, \tl_head:f}
+% \begin{syntax}
+% \cs{tl_head:n} \Arg{token list}
+% \end{syntax}
+% Leaves in the input stream the first \meta{item} in the
+% \meta{token list}, discarding the rest of the \meta{token list}.
+% All leading explicit space characters
+% (explicit tokens with character code~$32$ and category code~$10$)
+% are discarded; for example
+% \begin{verbatim}
+% \tl_head:n { abc }
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% \tl_head:n { ~ abc }
+% \end{verbatim}
+% both leave |a| in the input stream. If the \enquote{head} is a
+% brace group, rather than a single token, the braces are removed, and
+% so
+% \begin{verbatim}
+% \tl_head:n { ~ { ~ ab } c }
+% \end{verbatim}
+% yields \verb*| ab|.
+% A blank \meta{token list} (see \cs{tl_if_blank:nTF}) results in
+% \cs{tl_head:n} leaving nothing in the input stream.
+% \begin{texnote}
+% The result is returned within \cs{exp_not:n}, which means that the token
+% list does not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_head:w}
+% \begin{syntax}
+% \cs{tl_head:w} \meta{token list} | { } | \cs{q_stop}
+% \end{syntax}
+% Leaves in the input stream the first \meta{item} in the
+% \meta{token list}, discarding the rest of the \meta{token list}.
+% All leading explicit space characters
+% (explicit tokens with character code~$32$ and category code~$10$)
+% are discarded.
+% A blank \meta{token list} (which consists only of space characters)
+% results in a low-level \TeX{} error, which may be avoided by the
+% inclusion of an empty group in the input (as shown), without the need
+% for an explicit test. Alternatively, \cs{tl_if_blank:nF} may be used to
+% avoid using the function with a \enquote{blank} argument.
+% This function requires only a single expansion, and thus is suitable for
+% use within an \texttt{o}-type expansion. In general, \cs{tl_head:n} should
+% be preferred if the number of expansions is not critical.
+% \end{function}
+%
+% \begin{function}[updated = 2012-09-01, EXP]
+% {\tl_tail:N, \tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f}
+% \begin{syntax}
+% \cs{tl_tail:n} \Arg{token list}
+% \end{syntax}
+% Discards all leading explicit space characters
+% (explicit tokens with character code~$32$ and category code~$10$)
+% and the first \meta{item} in the \meta{token list}, and leaves the
+% remaining tokens in the input stream. Thus for example
+% \begin{verbatim}
+% \tl_tail:n { a ~ {bc} d }
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% \tl_tail:n { ~ a ~ {bc} d }
+% \end{verbatim}
+% both leave \verb*| {bc}d| in the input stream. A blank
+% \meta{token list} (see \cs{tl_if_blank:nTF}) results
+% in \cs{tl_tail:n} leaving nothing in the input stream.
+% \begin{texnote}
+% The result is returned within \cs{exp_not:n}, which means that the
+% token list does not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% If you wish to handle token lists where the first token may be a space, and
+% this needs to be treated as the head/tail, this can be accomplished using
+% \cs{tl_if_head_is_space:nTF}, for example
+% \begin{verbatim}
+% \exp_last_unbraced:NNo
+% \cs_new:Npn \__mypkg_gobble_space:w \c_space_tl { }
+% \cs_new:Npn \mypkg_tl_head_keep_space:n #1
+% {
+% \tl_if_head_is_space:nTF {#1}
+% { ~ }
+% { \tl_head:n {#1} }
+% }
+% \cs_new:Npn \mypkg_tl_tail_keep_space:n #1
+% {
+% \tl_if_head_is_space:nTF {#1}
+% { \exp_not:o { \__mypkg_gobble_space:w #1 } }
+% { \tl_tail:n {#1} }
+% }
+% \end{verbatim}
+%
+% \subsection{Items and ranges in token lists}
+%
+% \begin{function}[added = 2014-07-17, EXP]
+% {\tl_item:nn, \tl_item:Nn, \tl_item:cn}
+% \begin{syntax}
+% \cs{tl_item:nn} \Arg{token list} \Arg{integer expression}
+% \end{syntax}
+% Indexing items in the \meta{token list} from~$1$ on the left, this
+% function evaluates the \meta{integer expression} and leaves the
+% appropriate item from the \meta{token list} in the input stream.
+% If the \meta{integer expression} is negative, indexing occurs from
+% the right of the token list, starting at $-1$ for the right-most item.
+% If the index is out of bounds, then the function expands to nothing.
+% \begin{texnote}
+% The result is returned within the \tn{unexpanded}
+% primitive (\cs{exp_not:n}), which means that the \meta{item}
+% does not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2016-12-06]
+% {\tl_rand_item:N, \tl_rand_item:c, \tl_rand_item:n}
+% \begin{syntax}
+% \cs{tl_rand_item:N} \meta{tl~var}
+% \cs{tl_rand_item:n} \Arg{token list}
+% \end{syntax}
+% Selects a pseudo-random item of the \meta{token list}. If the
+% \meta{token list} is blank, the result is empty.
+% This is not available in older versions of \XeTeX{}.
+% \begin{texnote}
+% The result is returned within the \tn{unexpanded}
+% primitive (\cs{exp_not:n}), which means that the \meta{item}
+% does not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2017-02-17, updated = 2017-07-15]
+% {\tl_range:Nnn, \tl_range:nnn}
+% \begin{syntax}
+% \cs{tl_range:Nnn} \meta{tl~var} \Arg{start index} \Arg{end index}
+% \cs{tl_range:nnn} \Arg{token list} \Arg{start index} \Arg{end index}
+% \end{syntax}
+% Leaves in the input stream the items from the \meta{start index} to the
+% \meta{end index} inclusive. Spaces and braces are preserved between
+% the items returned (but never at either end of the list).
+% Here \meta{start index} and \meta{end index} should be \meta{integer expressions}.
+% For describing in detail the functions' behavior, let $m$ and $n$ be the start
+% and end index respectively. If either is $0$, the result is empty. A positive
+% index means `start counting from the left end', and a negative index means
+% `from the right end'. Let $l$ be the count of the token list.
+%
+% The \emph{actual start point} is determined as $M=m$ if~$m>0$ and as $M=l+m+1$
+% if~$m<0$. Similarly the \emph{actual end point} is $N=n$ if~$n>0$ and $N=l+n+1$
+% if~$n<0$. If $M>N$, the result is empty. Otherwise it consists of all items from
+% position $M$ to position $N$ inclusive; for the purpose of this rule, we can
+% imagine that the token list extends at infinity on either side, with void items
+% at positions $s$ for $s\le0$ or $s>l$.
+%
+% Spaces in between items in the actual range are preserved. Spaces at either end
+% of the token list will be removed anyway (think to the token list being passed to
+% |\tl_trim_spaces:n| to begin with.
+%
+% Thus, with $l=7$ as in the examples below, all of the following are equivalent
+% and result in the whole token list
+% \begin{verbatim}
+% \tl_range:nnn { abcd~{e{}}fg } { 1 } { 7 }
+% \tl_range:nnn { abcd~{e{}}fg } { 1 } { 12 }
+% \tl_range:nnn { abcd~{e{}}fg } { -7 } { 7 }
+% \tl_range:nnn { abcd~{e{}}fg } { -12 } { 7 }
+% \end{verbatim}
+% Here are some more interesting examples. The calls
+% \begin{verbatim}
+% \iow_term:e { \tl_range:nnn { abcd{e{}}fg } { 2 } { 5 } }
+% \iow_term:e { \tl_range:nnn { abcd{e{}}fg } { 2 } { -3 } }
+% \iow_term:e { \tl_range:nnn { abcd{e{}}fg } { -6 } { 5 } }
+% \iow_term:e { \tl_range:nnn { abcd{e{}}fg } { -6 } { -3 } }
+% \end{verbatim}
+% are all equivalent and will print |bcd{e{}}| on the terminal; similarly
+% \begin{verbatim}
+% \iow_term:e { \tl_range:nnn { abcd~{e{}}fg } { 2 } { 5 } }
+% \iow_term:e { \tl_range:nnn { abcd~{e{}}fg } { 2 } { -3 } }
+% \iow_term:e { \tl_range:nnn { abcd~{e{}}fg } { -6 } { 5 } }
+% \iow_term:e { \tl_range:nnn { abcd~{e{}}fg } { -6 } { -3 } }
+% \end{verbatim}
+% are all equivalent and will print |bcd {e{}}| on the
+% terminal (note the space in the middle). To the contrary,
+% \begin{verbatim}
+% \tl_range:nnn { abcd~{e{}}f } { 2 } { 4 }
+% \end{verbatim}
+% will discard the space after `d'.
+%
+% If we want to get the items from, say, the third to the last in a token
+% list |<tl>|, the call
+% is |\tl_range:nnn { <tl> } { 3 } { -1 }|. Similarly, for discarding
+% the last item, we can do |\tl_range:nnn { <tl> } { 1 } { -2 }|.
+%
+%^^A The behavior of \cs{tl_range:Nnn} is exactly the same, acting on the
+%^^A contents of the tl variable.
+%
+% \begin{texnote}
+% The result is returned within the \tn{unexpanded}
+% primitive (\cs{exp_not:n}), which means that the \meta{item}
+% does not expand further when appearing in an \texttt{e}-type
+% or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \subsection{Sorting token lists}
+%
+% \begin{function}[added = 2017-02-06]
+% {\tl_sort:Nn, \tl_sort:cn, \tl_gsort:Nn, \tl_gsort:cn}
+% \begin{syntax}
+% \cs{tl_sort:Nn} \meta{tl var} \Arg{comparison code}
+% \end{syntax}
+% Sorts the items in the \meta{tl var} according to the
+% \meta{comparison code}, and assigns the result to
+% \meta{tl var}. The details of sorting comparison are
+% described in Section~\ref{sec:l3sort:mech}.
+% \end{function}
+%
+% \begin{function}[added = 2017-02-06, EXP]{\tl_sort:nN}
+% \begin{syntax}
+% \cs{tl_sort:nN} \Arg{token list} \meta{conditional}
+% \end{syntax}
+% Sorts the items in the \meta{token list}, using the
+% \meta{conditional} to compare items, and leaves the result in the
+% input stream. The \meta{conditional} should have signature |:nnTF|,
+% and return \texttt{true} if the two items being compared should be
+% left in the same order, and \texttt{false} if the items should be
+% swapped. The details of sorting comparison are
+% described in Section~\ref{sec:l3sort:mech}.
+% \begin{texnote}
+% The result is returned within \cs{exp_not:n}, which means that the
+% token list does not expand further when appearing in an
+% \texttt{e}-type or \texttt{x}-type argument expansion.
+% \end{texnote}
+% \end{function}
+%
+% \section{Manipulating tokens in token lists}
+%
+% \subsection{Replacing tokens}
+%
+% Within token lists, replacement takes place at the top level: there is
+% no recursion into brace groups (more precisely, within a group defined by
+% a categroy code $1$/$2$ pair).
+%
+% \begin{function}[updated = 2011-08-11]
+% {
+% \tl_replace_once:Nnn, \tl_replace_once:NVn, \tl_replace_once:NnV,
+% \tl_replace_once:Nen, \tl_replace_once:Nne, \tl_replace_once:Nee,
+% \tl_replace_once:cnn, \tl_replace_once:cVn, \tl_replace_once:cnV,
+% \tl_replace_once:cen, \tl_replace_once:cne, \tl_replace_once:cee,
+% \tl_greplace_once:Nnn, \tl_greplace_once:NVn, \tl_greplace_once:NnV,
+% \tl_greplace_once:Nen, \tl_greplace_once:Nne, \tl_greplace_once:Nee,
+% \tl_greplace_once:cnn, \tl_greplace_once:cVn, \tl_greplace_once:cnV,
+% \tl_greplace_once:cen, \tl_greplace_once:cne, \tl_greplace_once:cee
+% }
+% \begin{syntax}
+% \cs{tl_replace_once:Nnn} \meta{tl~var} \Arg{old tokens} \Arg{new tokens}
+% \end{syntax}
+% Replaces the first (leftmost) occurrence of \meta{old tokens} in the
+% \meta{tl~var} with \meta{new tokens}. \meta{Old tokens}
+% cannot contain |{|, |}| or |#|
+% (more precisely, explicit character tokens with category code $1$
+% (begin-group) or $2$ (end-group), and tokens with category code $6$).
+% \end{function}
+%
+% \begin{function}[updated = 2011-08-11]
+% {
+% \tl_replace_all:Nnn, \tl_replace_all:NVn, \tl_replace_all:NnV,
+% \tl_replace_all:Nen, \tl_replace_all:Nne, \tl_replace_all:Nee,
+% \tl_replace_all:cnn, \tl_replace_all:cVn, \tl_replace_all:cnV,
+% \tl_replace_all:cen, \tl_replace_all:cne, \tl_replace_all:cee,
+% \tl_greplace_all:Nnn, \tl_greplace_all:NVn, \tl_greplace_all:NnV,
+% \tl_greplace_all:Nen, \tl_greplace_all:Nne, \tl_greplace_all:Nee,
+% \tl_greplace_all:cnn, \tl_greplace_all:cVn, \tl_greplace_all:cnV,
+% \tl_greplace_all:cen, \tl_greplace_all:cne, \tl_greplace_all:cee
+% }
+% \begin{syntax}
+% \cs{tl_replace_all:Nnn} \meta{tl~var} \Arg{old tokens} \Arg{new tokens}
+% \end{syntax}
+% Replaces all occurrences of \meta{old tokens} in the
+% \meta{tl~var} with \meta{new tokens}. \meta{Old tokens}
+% cannot contain |{|, |}| or |#|
+% (more precisely, explicit character tokens with category code $1$
+% (begin-group) or $2$ (end-group), and tokens with category code $6$).
+% As this function
+% operates from left to right, the pattern \meta{old tokens}
+% may remain after the replacement (see \cs{tl_remove_all:Nn}
+% for an example).
+% \end{function}
+%
+% \begin{function}[updated = 2011-08-11]
+% {
+% \tl_remove_once:Nn, \tl_remove_once:NV, \tl_remove_once:Ne,
+% \tl_remove_once:cn, \tl_remove_once:cV, \tl_remove_once:ce,
+% \tl_gremove_once:Nn, \tl_gremove_once:NV, \tl_gremove_once:Ne,
+% \tl_gremove_once:cn, \tl_gremove_once:cV, \tl_gremove_once:ce
+% }
+% \begin{syntax}
+% \cs{tl_remove_once:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Removes the first (leftmost) occurrence of \meta{tokens} from the
+% \meta{tl~var}. The \meta{tokens} cannot contain |{|, |}| or |#|
+% (more precisely, explicit character tokens with category code $1$
+% (begin-group) or $2$ (end-group), and tokens with category code $6$).
+% \end{function}
+%
+% \begin{function}[updated = 2011-08-11]
+% {
+% \tl_remove_all:Nn, \tl_remove_all:NV, \tl_remove_all:Ne,
+% \tl_remove_all:cn, \tl_remove_all:cV, \tl_remove_all:ce,
+% \tl_gremove_all:Nn, \tl_gremove_all:NV, \tl_gremove_all:Ne,
+% \tl_gremove_all:cn, \tl_gremove_all:cV, \tl_gremove_all:ce,
+% }
+% \begin{syntax}
+% \cs{tl_remove_all:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Removes all occurrences of \meta{tokens} from the
+% \meta{tl~var}. The \meta{tokens} cannot contain |{|, |}| or |#|
+% (more precisely, explicit character tokens with category code $1$
+% (begin-group) or $2$ (end-group), and tokens with category code $6$).
+% As this function
+% operates from left to right, the pattern \meta{tokens}
+% may remain after the removal, for instance,
+% \begin{quote}
+% \cs{tl_set:Nn} \cs{l_tmpa_tl} |{abbccd}|
+% \cs{tl_remove_all:Nn} \cs{l_tmpa_tl} |{bc}|
+% \end{quote}
+% results in \cs{l_tmpa_tl} containing \texttt{abcd}.
+% \end{function}
+%
+% \subsection{Reassigning category codes}
+%
+% These functions allow the rescanning of tokens: re-apply \TeX{}'s
+% tokenization process to apply category codes different from those
+% in force when the tokens were absorbed. Whilst this functionality is
+% supported, it is often preferable to find alternative approaches
+% to achieving outcomes rather than rescanning tokens (for example
+% construction of token lists token-by-token with intervening category
+% code changes or using \cs{char_generate:nn}).
+%
+% \begin{function}[updated = 2015-08-11]
+% {
+% \tl_set_rescan:Nnn, \tl_set_rescan:NnV, \tl_set_rescan:Nne,
+% \tl_set_rescan:Nno,
+% \tl_set_rescan:cnn, \tl_set_rescan:cnV, \tl_set_rescan:cne,
+% \tl_set_rescan:cno,
+% \tl_gset_rescan:Nnn, \tl_gset_rescan:NnV, \tl_gset_rescan:Nne,
+% \tl_gset_rescan:Nno,
+% \tl_gset_rescan:cnn, \tl_gset_rescan:cnV, \tl_gset_rescan:cne,
+% \tl_gset_rescan:cno,
+% }
+% \begin{syntax}
+% \cs{tl_set_rescan:Nnn} \meta{tl~var} \Arg{setup} \Arg{tokens}
+% \end{syntax}
+% Sets \meta{tl~var} to contain \meta{tokens}, applying the category
+% code r\'{e}gime specified in the \meta{setup} before carrying out
+% the assignment. (Category codes applied to tokens not explicitly covered
+% by the \meta{setup} are those in force at the point of use of
+% \cs{tl_set_rescan:Nnn}.)
+% This allows the \meta{tl~var} to contain material
+% with category codes other than those that apply when \meta{tokens}
+% are absorbed. The \meta{setup} is run within a group and may
+% contain any valid input, although only changes in category codes,
+% such as uses of \cs{cctab_select:N},
+% are relevant. See also \cs{tl_rescan:nn}.
+% \begin{texnote}
+% The \meta{tokens} are first turned into a string (using
+% \cs{tl_to_str:n}). If the string contains one or more characters
+% with character code \tn{newlinechar} (set equal to
+% \tn{endlinechar} unless that is equal to $32$, before the user
+% \meta{setup}), then it is split into lines at these characters,
+% then read as if reading multiple lines from a file, ignoring
+% spaces (catcode $10$) at the beginning and spaces and tabs
+% (character code $32$ or $9$) at the end of every line.
+% Otherwise, spaces (and tabs) are retained at both ends of the
+% single-line string, as if it appeared in the middle of a line
+% read from a file.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[updated = 2015-08-11]{\tl_rescan:nn, \tl_rescan:nV}
+% \begin{syntax}
+% \cs{tl_rescan:nn} \Arg{setup} \Arg{tokens}
+% \end{syntax}
+% Rescans \meta{tokens} applying the category code r\'{e}gime
+% specified in the \meta{setup}, and leaves the resulting tokens in
+% the input stream. (Category codes applied to tokens not explicitly covered
+% by the \meta{setup} are those in force at the point of use of
+% \cs{tl_rescan:nn}.)
+% The \meta{setup} is run within a group and may
+% contain any valid input, although only changes in category codes,
+% such as uses of \cs{cctab_select:N},
+% are relevant. See also \cs{tl_set_rescan:Nnn}, which is more
+% robust than using \cs{tl_set:Nn} in the \meta{tokens} argument of
+% \cs{tl_rescan:nn}.
+% \begin{texnote}
+% The \meta{tokens} are first turned into a string (using
+% \cs{tl_to_str:n}). If the string contains one or more characters
+% with character code \tn{newlinechar} (set equal to
+% \tn{endlinechar} unless that is equal to $32$, before the user
+% \meta{setup}), then it is split into lines at these characters,
+% then read as if reading multiple lines from a file, ignoring
+% spaces (catcode $10$) at the beginning and spaces and tabs
+% (character code $32$ or $9$) at the end of every line.
+% Otherwise, spaces (and tabs) are retained at both ends of the
+% single-line string, as if it appeared in the middle of a line
+% read from a file.
+%
+% Contrarily to the \tn{scantokens} \eTeX{} primitive, \cs{tl_rescan:nn}
+% tokenizes the whole string in the same category code regime rather
+% than one token at a time, so that directives such as \tn{verb}
+% that rely on changing category codes will not function properly.
+% \end{texnote}
+% \end{function}
+%
+% \section{Constant token lists}
+%
+% \begin{variable}{\c_empty_tl}
+% Constant that is always empty.
+% \end{variable}
+%
+% \begin{variable}[added = 2017-11-14]{\c_novalue_tl}
+% A marker for the absence of an argument. This constant |tl| can safely
+% be typeset (\emph{cf.}~\cs{q_nil}), with the result being |-NoValue-|.
+% It is important to note that \cs{c_novalue_tl} is constructed such that it
+% will \emph{not} match the simple text input |-NoValue-|, \emph{i.e.}
+% that
+% \begin{verbatim}
+% \tl_if_eq:NnTF \c_novalue_tl { -NoValue- }
+% \end{verbatim}
+% is logically \texttt{false}. The \cs{c_novalue_tl} marker is intended for
+% use in creating document-level interfaces, where it serves as an indicator
+% that an (optional) argument was omitted. In particular, it is distinct
+% from a simple empty |tl|.
+% \end{variable}
+%
+% \begin{variable}{\c_space_tl}
+% An explicit space character contained in a token list (compare this with
+% \cs{c_space_token}). For use where an explicit space is required.
+% \end{variable}
+%
+% \section{Scratch token lists}
+%
+% \begin{variable}{\l_tmpa_tl, \l_tmpb_tl}
+% Scratch token lists for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_tl, \g_tmpb_tl}
+% Scratch token lists for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3tl} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=tl>
+% \end{macrocode}
+%
+% A token list variable is a \TeX{} macro that holds tokens. By using the
+% \eTeX{} primitive \tn{unexpanded} inside a \TeX{} \tn{edef} it is
+% possible to store any tokens, including |#|, in this way.
+%
+% \subsection{Functions}
+%
+% \begin{macro}{\__kernel_tl_set:Nx,\__kernel_tl_gset:Nx}
+% These two are supplied to get better performance for macros which would
+% otherwise use \cs{tl_set:Ne} or \cs{tl_gset:Ne} internally.
+% \begin{macrocode}
+\cs_new_eq:NN \__kernel_tl_set:Nx \cs_set_nopar:Npe
+\cs_new_eq:NN \__kernel_tl_gset:Nx \cs_gset_nopar:Npe
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_new:N, \tl_new:c}
+% Creating new token list variables is a case of checking for an
+% existing definition and doing the definition.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_new:N #1
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \cs_gset_eq:NN #1 \c_empty_tl
+ }
+\cs_generate_variant:Nn \tl_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \tl_const:Nn, \tl_const:Ne, \tl_const:Nx,
+% \tl_const:cn, \tl_const:ce, \tl_const:cx
+% }
+% Constants are also easy to generate. They use \cs{cs_gset_nopar:Npe} instead
+% of \cs{__kernel_tl_gset:Nx} so that the correct scope checking for |c|,
+% instead of for |g|, is applied when
+% \cs{debug_on:n} |{ check-declarations }| is used.
+% Constant assignment functions are patched specially in \pkg{l3debug} to
+% apply such checks.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_const:Nn #1#2
+ {
+ \__kernel_chk_if_free_cs:N #1
+ \cs_gset_nopar:Npe #1 { \__kernel_exp_not:w {#2} }
+ }
+\cs_generate_variant:Nn \tl_const:Nn { Ne , c , ce }
+\cs_generate_variant:Nn \tl_const:Nn { Nx , cx }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_clear:N, \tl_clear:c}
+% \begin{macro}{\tl_gclear:N, \tl_gclear:c}
+% Clearing a token list variable means setting it to an empty value.
+% Error checking is sorted out by the parent function.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_clear:N #1
+ { \tex_let:D #1 = ~ \c_empty_tl }
+\cs_new_protected:Npn \tl_gclear:N #1
+ { \tex_global:D \tex_let:D #1 ~ \c_empty_tl }
+\cs_generate_variant:Nn \tl_clear:N { c }
+\cs_generate_variant:Nn \tl_gclear:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_clear_new:N, \tl_clear_new:c}
+% \begin{macro}{\tl_gclear_new:N, \tl_gclear_new:c}
+% Clearing a token list variable means setting it to an empty value.
+% Error checking is sorted out by the parent function.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_clear_new:N #1
+ { \tl_if_exist:NTF #1 { \tl_clear:N #1 } { \tl_new:N #1 } }
+\cs_new_protected:Npn \tl_gclear_new:N #1
+ { \tl_if_exist:NTF #1 { \tl_gclear:N #1 } { \tl_new:N #1 } }
+\cs_generate_variant:Nn \tl_clear_new:N { c }
+\cs_generate_variant:Nn \tl_gclear_new:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_set_eq:NN, \tl_set_eq:Nc, \tl_set_eq:cN, \tl_set_eq:cc}
+% \begin{macro}{\tl_gset_eq:NN, \tl_gset_eq:Nc, \tl_gset_eq:cN, \tl_gset_eq:cc}
+% For setting token list variables equal to each other. To allow for
+% patching, the arguments have to be explicit. In addition this
+% ensures that a braced second argument will not cause problems.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_set_eq:NN #1#2
+ { \tex_let:D #1 = ~ #2 }
+\cs_new_protected:Npn \tl_gset_eq:NN #1#2
+ { \tex_global:D \tex_let:D #1 = ~ #2 }
+\cs_generate_variant:Nn \tl_set_eq:NN { cN, Nc, cc }
+\cs_generate_variant:Nn \tl_gset_eq:NN { cN, Nc, cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_concat:NNN, \tl_concat:ccc}
+% \begin{macro}{\tl_gconcat:NNN, \tl_gconcat:ccc}
+% Concatenating token lists is easy. When checking is turned on, all
+% three arguments must be checked: a token list |#2| or |#3| equal to
+% \cs{scan_stop:} would lead to problems later on.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_concat:NNN #1#2#3
+ {
+ \__kernel_tl_set:Nx #1
+ {
+ \__kernel_exp_not:w \exp_after:wN {#2}
+ \__kernel_exp_not:w \exp_after:wN {#3}
+ }
+ }
+\cs_new_protected:Npn \tl_gconcat:NNN #1#2#3
+ {
+ \__kernel_tl_gset:Nx #1
+ {
+ \__kernel_exp_not:w \exp_after:wN {#2}
+ \__kernel_exp_not:w \exp_after:wN {#3}
+ }
+ }
+\cs_generate_variant:Nn \tl_concat:NNN { ccc }
+\cs_generate_variant:Nn \tl_gconcat:NNN { ccc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_exist:N, \tl_if_exist:c}
+% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \tl_if_exist:N \cs_if_exist:N { TF , T , F , p }
+\prg_new_eq_conditional:NNn \tl_if_exist:c \cs_if_exist:c { TF , T , F , p }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Constant token lists}
+%
+% \begin{variable}{\c_empty_tl}
+% Never full. We need to define that constant before using \cs{tl_new:N}.
+% \begin{macrocode}
+\tl_const:Nn \c_empty_tl { }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_novalue_tl}
+% A special marker: as we don't have |\char_generate:nn| yet, has to be
+% created the old-fashioned way.
+% \begin{macrocode}
+\group_begin:
+\tex_catcode:D `- = 11 ~
+\tl_const:Ne \c_novalue_tl { - NoValue \token_to_str:N - }
+\group_end:
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_space_tl}
+% A space as a token list (as opposed to as a character).
+% \begin{macrocode}
+\tl_const:Nn \c_space_tl { ~ }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Adding to token list variables}
+%
+% \begin{macro}
+% {
+% \tl_set:Nn, \tl_set:NV, \tl_set:Nv, \tl_set:No, \tl_set:Ne, \tl_set:Nf, \tl_set:Nx,
+% \tl_set:cn, \tl_set:cV, \tl_set:cv, \tl_set:co, \tl_set:ce, \tl_set:cf, \tl_set:cx
+% }
+% \begin{macro}
+% {
+% \tl_gset:Nn, \tl_gset:NV, \tl_gset:Nv,
+% \tl_gset:No, \tl_gset:Ne, \tl_gset:Nf, \tl_gset:Nx,
+% \tl_gset:cn, \tl_gset:cV, \tl_gset:cv,
+% \tl_gset:co, \tl_gset:ce, \tl_gset:cf, \tl_gset:cx
+% }
+% By using \cs{exp_not:n} token list variables can contain |#| tokens,
+% which makes the token list registers provided by \TeX{}
+% more or less redundant. The \cs{tl_set:No} version is done
+% by hand as it is used quite a lot.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_set:Nn #1#2
+ { \__kernel_tl_set:Nx #1 { \__kernel_exp_not:w {#2} } }
+\cs_new_protected:Npn \tl_set:No #1#2
+ { \__kernel_tl_set:Nx #1 { \__kernel_exp_not:w \exp_after:wN {#2} } }
+\cs_new_protected:Npn \tl_gset:Nn #1#2
+ { \__kernel_tl_gset:Nx #1 { \__kernel_exp_not:w {#2} } }
+\cs_new_protected:Npn \tl_gset:No #1#2
+ { \__kernel_tl_gset:Nx #1 { \__kernel_exp_not:w \exp_after:wN {#2} } }
+\cs_generate_variant:Nn \tl_set:Nn { NV , Nv , Ne , Nf }
+\cs_generate_variant:Nn \tl_set:Nn { c, cV , cv , ce , cf }
+\cs_generate_variant:Nn \tl_set:No { c }
+\cs_generate_variant:Nn \tl_set:Nn { Nx , cx }
+\cs_generate_variant:Nn \tl_gset:Nn { NV , Nv , Ne , Nf }
+\cs_generate_variant:Nn \tl_gset:Nn { c, cV , cv , ce , cf }
+\cs_generate_variant:Nn \tl_gset:No { c }
+\cs_generate_variant:Nn \tl_gset:Nn { Nx , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \tl_put_left:Nn, \tl_put_left:NV, \tl_put_left:Nv, \tl_put_left:Ne,
+% \tl_put_left:No, \tl_put_left:Nx,
+% \tl_put_left:cn, \tl_put_left:cV, \tl_put_left:cv, \tl_put_left:ce,
+% \tl_put_left:co, \tl_put_left:cx
+% }
+% \begin{macro}
+% {
+% \tl_gput_left:Nn, \tl_gput_left:NV, \tl_gput_left:Nv, \tl_gput_left:Ne,
+% \tl_gput_left:No, \tl_gput_left:Nx,
+% \tl_gput_left:cn, \tl_gput_left:cV, \tl_gput_left:cv, \tl_gput_left:ce,
+% \tl_gput_left:co, \tl_gput_left:cx
+% }
+% Adding to the left is done directly to gain a little performance.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_put_left:Nn #1#2
+ {
+ \__kernel_tl_set:Nx #1
+ { \__kernel_exp_not:w {#2} \__kernel_exp_not:w \exp_after:wN {#1} }
+ }
+\cs_new_protected:Npn \tl_put_left:NV #1#2
+ {
+ \__kernel_tl_set:Nx #1
+ { \exp_not:V #2 \__kernel_exp_not:w \exp_after:wN {#1} }
+ }
+\cs_new_protected:Npn \tl_put_left:Nv #1#2
+ {
+ \__kernel_tl_set:Nx #1
+ { \exp_not:v {#2} \__kernel_exp_not:w \exp_after:wN {#1} }
+ }
+\cs_new_protected:Npn \tl_put_left:Ne #1#2
+ {
+ \__kernel_tl_set:Nx #1
+ {
+ \__kernel_exp_not:w \tex_expanded:D { {#2} }
+ \__kernel_exp_not:w \exp_after:wN {#1}
+ }
+ }
+\cs_new_protected:Npn \tl_put_left:No #1#2
+ {
+ \__kernel_tl_set:Nx #1
+ {
+ \__kernel_exp_not:w \exp_after:wN {#2}
+ \__kernel_exp_not:w \exp_after:wN {#1}
+ }
+ }
+\cs_new_protected:Npn \tl_gput_left:Nn #1#2
+ {
+ \__kernel_tl_gset:Nx #1
+ { \__kernel_exp_not:w {#2} \__kernel_exp_not:w \exp_after:wN {#1} }
+ }
+\cs_new_protected:Npn \tl_gput_left:NV #1#2
+ {
+ \__kernel_tl_gset:Nx #1
+ { \exp_not:V #2 \__kernel_exp_not:w \exp_after:wN {#1} }
+ }
+\cs_new_protected:Npn \tl_gput_left:Nv #1#2
+ {
+ \__kernel_tl_gset:Nx #1
+ { \exp_not:v {#2} \__kernel_exp_not:w \exp_after:wN {#1} }
+ }
+\cs_new_protected:Npn \tl_gput_left:Ne #1#2
+ {
+ \__kernel_tl_gset:Nx #1
+ {
+ \__kernel_exp_not:w \tex_expanded:D { {#2} }
+ \__kernel_exp_not:w \exp_after:wN {#1}
+ }
+ }
+\cs_new_protected:Npn \tl_gput_left:No #1#2
+ {
+ \__kernel_tl_gset:Nx #1
+ {
+ \__kernel_exp_not:w \exp_after:wN {#2}
+ \__kernel_exp_not:w \exp_after:wN {#1}
+ }
+ }
+\cs_generate_variant:Nn \tl_put_left:Nn { c }
+\cs_generate_variant:Nn \tl_put_left:NV { c }
+\cs_generate_variant:Nn \tl_put_left:Nv { c }
+\cs_generate_variant:Nn \tl_put_left:Ne { c }
+\cs_generate_variant:Nn \tl_put_left:No { c }
+\cs_generate_variant:Nn \tl_put_left:Nn { Nx, cx }
+\cs_generate_variant:Nn \tl_gput_left:Nn { c }
+\cs_generate_variant:Nn \tl_gput_left:NV { c }
+\cs_generate_variant:Nn \tl_gput_left:Nv { c }
+\cs_generate_variant:Nn \tl_gput_left:Ne { c }
+\cs_generate_variant:Nn \tl_gput_left:No { c }
+\cs_generate_variant:Nn \tl_gput_left:Nn { Nx , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \tl_put_right:Nn, \tl_put_right:NV, \tl_put_right:Nv, \tl_put_right:Ne,
+% \tl_put_right:No, \tl_put_right:Nx,
+% \tl_put_right:cn, \tl_put_right:cV, \tl_put_right:cv, \tl_put_right:ce,
+% \tl_put_right:co, \tl_put_right:cx
+% }
+% \begin{macro}
+% {
+% \tl_gput_right:Nn, \tl_gput_right:NV, \tl_gput_right:Nv, \tl_gput_right:Ne,
+% \tl_gput_right:No, \tl_gput_right:Nx,
+% \tl_gput_right:cn, \tl_gput_right:cV, \tl_gput_right:cv, \tl_gput_right:ce,
+% \tl_gput_right:co, \tl_gput_right:cx
+% }
+% The same on the right.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_put_right:Nn #1#2
+ { \__kernel_tl_set:Nx #1 { \__kernel_exp_not:w \exp_after:wN { #1 #2 } } }
+\cs_new_protected:Npn \tl_put_right:NV #1#2
+ {
+ \__kernel_tl_set:Nx #1
+ { \__kernel_exp_not:w \exp_after:wN {#1} \exp_not:V #2 }
+ }
+\cs_new_protected:Npn \tl_put_right:Nv #1#2
+ {
+ \__kernel_tl_set:Nx #1
+ { \__kernel_exp_not:w \exp_after:wN {#1} \exp_not:v {#2} }
+ }
+\cs_new_protected:Npn \tl_put_right:Ne #1#2
+ {
+ \__kernel_tl_set:Nx #1
+ {
+ \__kernel_exp_not:w \exp_after:wN {#1}
+ \__kernel_exp_not:w \tex_expanded:D { {#2} }
+ }
+ }
+\cs_new_protected:Npn \tl_put_right:No #1#2
+ {
+ \__kernel_tl_set:Nx #1
+ {
+ \__kernel_exp_not:w \exp_after:wN {#1}
+ \__kernel_exp_not:w \exp_after:wN {#2}
+ }
+ }
+\cs_new_protected:Npn \tl_gput_right:Nn #1#2
+ { \__kernel_tl_gset:Nx #1 { \__kernel_exp_not:w \exp_after:wN { #1 #2 } } }
+\cs_new_protected:Npn \tl_gput_right:NV #1#2
+ {
+ \__kernel_tl_gset:Nx #1
+ { \__kernel_exp_not:w \exp_after:wN {#1} \exp_not:V #2 }
+ }
+\cs_new_protected:Npn \tl_gput_right:Nv #1#2
+ {
+ \__kernel_tl_gset:Nx #1
+ { \__kernel_exp_not:w \exp_after:wN {#1} \exp_not:v {#2} }
+ }
+\cs_new_protected:Npn \tl_gput_right:Ne #1#2
+ {
+ \__kernel_tl_gset:Nx #1
+ {
+ \__kernel_exp_not:w \exp_after:wN {#1}
+ \__kernel_exp_not:w \tex_expanded:D { {#2} }
+ }
+ }
+\cs_new_protected:Npn \tl_gput_right:No #1#2
+ {
+ \__kernel_tl_gset:Nx #1
+ {
+ \__kernel_exp_not:w \exp_after:wN {#1}
+ \__kernel_exp_not:w \exp_after:wN {#2}
+ }
+ }
+\cs_generate_variant:Nn \tl_put_right:Nn { c }
+\cs_generate_variant:Nn \tl_put_right:NV { c }
+\cs_generate_variant:Nn \tl_put_right:Nv { c }
+\cs_generate_variant:Nn \tl_put_right:Ne { c }
+\cs_generate_variant:Nn \tl_put_right:No { c }
+\cs_generate_variant:Nn \tl_put_right:Nn { Nx , cx }
+\cs_generate_variant:Nn \tl_gput_right:Nn { c }
+\cs_generate_variant:Nn \tl_gput_right:NV { c }
+\cs_generate_variant:Nn \tl_gput_right:Nv { c }
+\cs_generate_variant:Nn \tl_gput_right:Ne { c }
+\cs_generate_variant:Nn \tl_gput_right:No { c }
+\cs_generate_variant:Nn \tl_gput_right:Nn { Nx, cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Internal quarks and quark-query functions}
+%
+% \begin{variable}{\q_@@_nil,\q_@@_mark,\q_@@_stop}
+% Internal quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_nil
+\quark_new:N \q_@@_mark
+\quark_new:N \q_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\q_@@_recursion_tail,\q_@@_recursion_stop}
+% Internal recursion quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_recursion_tail
+\quark_new:N \q_@@_recursion_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_if_recursion_tail_break:nN}
+% \begin{macro}[pTF]{\@@_if_recursion_tail_stop:n}
+% Functions to query recursion quarks.
+% \begin{macrocode}
+\__kernel_quark_new_test:N \@@_if_recursion_tail_break:nN
+\__kernel_quark_new_conditional:Nn \@@_quark_if_nil:n { TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Reassigning token list category codes}
+%
+% \begin{variable}{\c_@@_rescan_marker_tl}
+% The rescanning code needs a special token list containing the same
+% character (chosen here to be a colon) with two different category
+% codes: it cannot appear in the tokens being rescanned since all
+% colons have the same category code.
+% \begin{macrocode}
+\tl_const:Ne \c_@@_rescan_marker_tl { : \token_to_str:N : }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \tl_set_rescan:Nnn, \tl_set_rescan:NnV, \tl_set_rescan:Nne,
+% \tl_set_rescan:Nno, \tl_set_rescan:Nnx,
+% \tl_set_rescan:cnn, \tl_set_rescan:cnV, \tl_set_rescan:cne,
+% \tl_set_rescan:cno, \tl_set_rescan:cnx,
+% }
+% \begin{macro}
+% {
+% \tl_gset_rescan:Nnn, \tl_gset_rescan:NnV, \tl_gset_rescan:Nne,
+% \tl_gset_rescan:Nno, \tl_gset_rescan:Nnx,
+% \tl_gset_rescan:cnn, \tl_gset_rescan:cnV, \tl_gset_rescan:cne,
+% \tl_gset_rescan:cno, \tl_gset_rescan:cnx
+% }
+% \begin{macro}{\tl_rescan:nn, \tl_rescan:nV}
+% \begin{macro}{\@@_rescan_aux:}
+% \begin{macro}{\@@_set_rescan:NNnn, \@@_set_rescan_multi:nNN}
+% \begin{macro}[EXP]{\@@_rescan:NNw}
+% In a group, after some initial setup explained below and the user
+% setup~|#3| (followed by \cs{scan_stop:} to be safe), there is a call
+% to \cs{@@_set_rescan:nNN}. This shared auxiliary defined later
+% distinguishes single-line and multi-line ``files''. In the simplest
+% case of multi-line files, it calls (with the same arguments)
+% \cs{@@_set_rescan_multi:nNN}, whose code is included here to help
+% understand the approach. This function rescans its argument |#1|,
+% closes the group, and performs the assignment.
+%
+% One difficulty when rescanning is that \tn{scantokens} treats the
+% argument as a file, and without the correct settings a \TeX{} error
+% occurs:
+% \begin{verbatim}
+% ! File ended while scanning definition of ...
+% \end{verbatim}
+% A related minor issue is a warning due to opening a group before the
+% \tn{scantokens} and closing it inside that temporary file; we avoid
+% that by setting \tn{tracingnesting}. The standard solution to the
+% ``File ended'' error is to grab the rescanned tokens as a delimited
+% argument of an auxiliary, here \cs{@@_rescan:NNw}, that performs the
+% assignment, then let \TeX{} ``execute'' the end of file marker. As
+% usual in delimited arguments we use \cs{prg_do_nothing:} to avoid
+% stripping an outer set braces: this is removed by using
+% \texttt{o}-expanding assignments. The delimiter cannot appear
+% within the rescanned token list because it contains twice the same
+% character, with different catcodes.
+%
+% For \cs{tl_rescan:nn} we cannot simply call \cs{@@_set_rescan:NNnn}
+% \cs{prg_do_nothing:} \cs{use:n} because that would leave the
+% end-of-file marker \emph{after} the result of rescanning. If that
+% rescanned result is code that looks further in the input stream for
+% arguments, it would break.
+%
+% For multi-line files the only subtlety is that \tn{newlinechar}
+% should be equal to \tn{endlinechar} because \tn{newlinechar}
+% characters become new lines and then become \tn{endlinechar}
+% characters when writing to an abstract file and reading back. This
+% equality is ensured by setting \tn{newlinechar} equal to
+% \tn{endlinechar}. Prior to this, \tn{endlinechar} is set to $-1$ if
+% it was $32$ (in particular true after \cs{ExplSyntaxOn}) to avoid
+% unreasonable line-breaks at every space for instance in error
+% messages triggered by the user setup. Another side effect of
+% reading back from the file is that spaces (catcode $10$) are ignored
+% at the beginning of lines, and spaces and tabs (character code $32$
+% and $9$) are ignored at the end of lines.
+%
+% The two \cs{if_false:} \ldots{} \cs{fi:} are there to prevent
+% alignment tabs to cause a change of tabular cell while rescanning.
+% We put the \enquote{opening} one after \cs{group_begin:} so that if
+% one accidentally \texttt{f}-expands \cs{tl_set_rescan:Nnn} braces
+% remain balanced. This is essential in \texttt{e}-type arguments
+% when \tn{expanded} is not available.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_rescan:nn #1#2
+ {
+ \tl_set_rescan:Nnn \l_@@_internal_a_tl {#1} {#2}
+ \exp_after:wN \@@_rescan_aux:
+ \l_@@_internal_a_tl
+ }
+\cs_generate_variant:Nn \tl_rescan:nn { nV }
+\exp_args:NNo \cs_new_protected:Npn \@@_rescan_aux:
+ { \tl_clear:N \l_@@_internal_a_tl }
+\cs_new_protected:Npn \tl_set_rescan:Nnn
+ { \@@_set_rescan:NNnn \tl_set:No }
+\cs_new_protected:Npn \tl_gset_rescan:Nnn
+ { \@@_set_rescan:NNnn \tl_gset:No }
+\cs_new_protected:Npn \@@_set_rescan:NNnn #1#2#3#4
+ {
+ \group_begin:
+ \if_false: { \fi:
+ \int_set_eq:NN \tex_tracingnesting:D \c_zero_int
+ \int_compare:nNnT \tex_endlinechar:D = { 32 }
+ { \int_set:Nn \tex_endlinechar:D { -1 } }
+ \int_set_eq:NN \tex_newlinechar:D \tex_endlinechar:D
+ #3 \scan_stop:
+ \exp_args:No \@@_set_rescan:nNN { \tl_to_str:n {#4} } #1 #2
+ \if_false: } \fi:
+ }
+\cs_new_protected:Npn \@@_set_rescan_multi:nNN #1#2#3
+ {
+ \tex_everyeof:D \exp_after:wN { \c_@@_rescan_marker_tl }
+ \exp_after:wN \@@_rescan:NNw
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \exp_after:wN \prg_do_nothing:
+ \tex_scantokens:D {#1}
+ }
+\exp_args:Nno \use:nn
+ { \cs_new:Npn \@@_rescan:NNw #1#2#3 } \c_@@_rescan_marker_tl
+ {
+ \group_end:
+ #1 #2 {#3}
+ }
+\cs_generate_variant:Nn \tl_set_rescan:Nnn { NnV , Nne , c , cnV , cne }
+\cs_generate_variant:Nn \tl_set_rescan:Nnn { Nno , Nnx , cno , cnx }
+\cs_generate_variant:Nn \tl_gset_rescan:Nnn { NnV , Nne , c , cnV , cne }
+\cs_generate_variant:Nn \tl_gset_rescan:Nnn { Nno , Nnx , cno , cnx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_set_rescan:nNN}
+% \begin{macro}{\@@_set_rescan_single:nnNN, \@@_set_rescan_single_aux:nnnNN}
+% \begin{macro}[rEXP]{\@@_set_rescan_single_aux:w}
+% The function \cs{@@_set_rescan:nNN} calls \cs{@@_set_rescan_multi:nNN} or
+% \cs{@@_set_rescan_single:nnNN} |{ ' }| depending on whether its argument
+% is a single-line fragment of code/data or is made of multiple lines
+% by testing for the presence of a \tn{newlinechar} character. If
+% \tn{newlinechar} is out of range, the argument is assumed to be a
+% single line.
+%
+% For a single line, no \tn{endlinechar} should be added, so it is
+% set to $-1$, and spaces should not be removed.
+% Trailing spaces and tabs are a difficult matter, as \TeX{} removes
+% these at a very low level. The only way to preserve them is to
+% rescan not the argument but the argument followed by a character
+% with a reasonable category code. Here, $11$ (letter) and $12$ (other)
+% are accepted, as these are convenient, suitable for
+% delimiting an argument, and it is very unlikely that none of the
+% ASCII characters are in one of these categories. To avoid
+% selecting one particular character to put at the end, whose
+% category code may have been modified, there is a loop through
+% characters from |'| (ASCII $39$) to |~| (ASCII $127$). The choice
+% of starting point was made because this is the start of a very long
+% range of characters whose standard category is letter or other,
+% thus minimizing the number of steps needed by the loop (most often
+% just a single one). If no valid character is found (very rare),
+% fall-back on \cs{@@_set_rescan_multi:nNN}.
+%
+% Otherwise, once a valid character is found (let us use |'| in this
+% explanation) run some code very similar to \cs{@@_set_rescan_multi:nNN}
+% but with |'| added at both ends of the input. Of course, we need to
+% define the auxiliary \cs{@@_set_rescan_single:NNww} on the fly to remove
+% the additional~|'| that is just before |::| (by which we mean
+% \cs{c_@@_rescan_marker_tl}). Note that the argument must be
+% delimited by |'| with the current catcode; this is done thanks to
+% \cs{char_generate:nn}. Yet another issue is that the rescanned
+% token list may contain a comment character, in which case the |'| we
+% expected is not there. We fix this as follows: rather than just
+% |::| we set \tn{everyeof} to |::|\Arg{code1} |'::|\Arg{code2}
+% \cs{s_@@_stop}. The auxiliary \cs{@@_set_rescan_single:NNww} runs the
+% \texttt{o}-expanding assignment, expanding either \meta{code1} or
+% \meta{code2} before its the main argument~|#3|. In the typical case
+% without comment character, \meta{code1} is expanded, removing the
+% leading~|'|. In the rarer case with comment character, \meta{code2}
+% is expanded, calling \cs{@@_set_rescan_single_aux:w}, which removes the
+% trailing |::|\Arg{code1} and the leading~|'|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_rescan:nNN #1
+ {
+ \int_compare:nNnTF \tex_newlinechar:D < 0
+ { \use_ii:nn }
+ {
+ \exp_args:Nnf \tl_if_in:nnTF {#1}
+ { \char_generate:nn { \tex_newlinechar:D } { 12 } }
+ }
+ { \@@_set_rescan_multi:nNN }
+ {
+ \int_set:Nn \tex_endlinechar:D { -1 }
+ \@@_set_rescan_single:nnNN { `' }
+ }
+ {#1}
+ }
+\cs_new_protected:Npn \@@_set_rescan_single:nnNN #1
+ {
+ \int_compare:nNnTF
+ { \char_value_catcode:n {#1} / 2 } = 6
+ {
+ \exp_args:Nof \@@_set_rescan_single_aux:nnnNN
+ \c_@@_rescan_marker_tl
+ { \char_generate:nn {#1} { \char_value_catcode:n {#1} } }
+ }
+ {
+ \int_compare:nNnTF {#1} < { `\~ }
+ {
+ \exp_args:Nf \@@_set_rescan_single:nnNN
+ { \int_eval:n { #1 + 1 } }
+ }
+ { \@@_set_rescan_multi:nNN }
+ }
+ }
+\cs_new_protected:Npn \@@_set_rescan_single_aux:nnnNN #1#2#3#4#5
+ {
+ \tex_everyeof:D
+ {
+ #1 \use_none:n
+ #2 #1 { \exp:w \@@_set_rescan_single_aux:w }
+ \s_@@_stop
+ }
+ \cs_set:Npn \@@_rescan:NNw ##1##2##3 #2 #1 ##4 ##5 \s_@@_stop
+ {
+ \group_end:
+ ##1 ##2 { ##4 ##3 }
+ }
+ \exp_after:wN \@@_rescan:NNw
+ \exp_after:wN #4
+ \exp_after:wN #5
+ \tex_scantokens:D { #2 #3 #2 }
+ }
+\exp_args:Nno \use:nn
+ { \cs_new:Npn \@@_set_rescan_single_aux:w #1 }
+ \c_@@_rescan_marker_tl #2
+ { \use_i:nn \exp_end: #1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Modifying token list variables}
+%
+% \begin{macro}
+% {
+% \tl_replace_once:Nnn, \tl_replace_once:NVn, \tl_replace_once:NnV,
+% \tl_replace_once:Nen, \tl_replace_once:Nne, \tl_replace_once:Nee,
+% \tl_replace_once:Nxn, \tl_replace_once:Nnx, \tl_replace_once:Nxx,
+% \tl_replace_once:cnn, \tl_replace_once:cVn, \tl_replace_once:cnV,
+% \tl_replace_once:cen, \tl_replace_once:cne, \tl_replace_once:cee,
+% \tl_replace_once:cxn, \tl_replace_once:cnx, \tl_replace_once:cxx
+% }
+% \begin{macro}
+% {
+% \tl_greplace_once:Nnn, \tl_greplace_once:NVn, \tl_greplace_once:NnV,
+% \tl_greplace_once:Nen, \tl_greplace_once:Nne, \tl_greplace_once:Nee,
+% \tl_greplace_once:Nxn, \tl_greplace_once:Nnx, \tl_greplace_once:Nxx,
+% \tl_greplace_once:cnn, \tl_greplace_once:cVn, \tl_greplace_once:cnV,
+% \tl_greplace_once:cen, \tl_greplace_once:cne, \tl_greplace_once:cee,
+% \tl_greplace_once:cxn, \tl_greplace_once:cnx, \tl_greplace_once:cxx
+% }
+% \begin{macro}
+% {
+% \tl_replace_all:Nnn, \tl_replace_all:NVn, \tl_replace_all:NnV,
+% \tl_replace_all:Nen, \tl_replace_all:Nne, \tl_replace_all:Nee,
+% \tl_replace_all:Nxn, \tl_replace_all:Nnx, \tl_replace_all:Nxx,
+% \tl_replace_all:cnn, \tl_replace_all:cVn, \tl_replace_all:cnV,
+% \tl_replace_all:cen, \tl_replace_all:cne, \tl_replace_all:cee,
+% \tl_replace_all:cxn, \tl_replace_all:cnx, \tl_replace_all:cxx
+% }
+% \begin{macro}
+% {
+% \tl_greplace_all:Nnn, \tl_greplace_all:NVn, \tl_greplace_all:NnV,
+% \tl_greplace_all:Nen, \tl_greplace_all:Nne, \tl_greplace_all:Nee,
+% \tl_greplace_all:Nxn, \tl_greplace_all:Nnx, \tl_greplace_all:Nxx,
+% \tl_greplace_all:cnn, \tl_greplace_all:cVn, \tl_greplace_all:cnV,
+% \tl_greplace_all:cen, \tl_greplace_all:cne, \tl_greplace_all:cee,
+% \tl_greplace_all:cxn, \tl_greplace_all:cnx, \tl_greplace_all:cxx
+% }
+% All of the \texttt{replace} functions call \cs{@@_replace:NnNNNnn}
+% with appropriate arguments. The first two arguments are explained
+% later. The next controls whether the replacement function calls
+% itself (\cs{@@_replace_next:w}) or stops (\cs{@@_replace_wrap:w})
+% after the first replacement. Next comes an \texttt{e}-type
+% assignment function \cs{tl_set:Ne} or \cs{tl_gset:Ne} for local or
+% global replacements. Finally, the three arguments \meta{tl~var}
+% \Arg{pattern} \Arg{replacement} provided by the user. When
+% describing the auxiliary functions below, we denote the contents of
+% the \meta{tl~var} by \meta{token list}.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_replace_once:Nnn
+ { \@@_replace:NnNNNnn \q_@@_mark ? \@@_replace_wrap:w \__kernel_tl_set:Nx }
+\cs_new_protected:Npn \tl_greplace_once:Nnn
+ { \@@_replace:NnNNNnn \q_@@_mark ? \@@_replace_wrap:w \__kernel_tl_gset:Nx }
+\cs_new_protected:Npn \tl_replace_all:Nnn
+ { \@@_replace:NnNNNnn \q_@@_mark ? \@@_replace_next:w \__kernel_tl_set:Nx }
+\cs_new_protected:Npn \tl_greplace_all:Nnn
+ { \@@_replace:NnNNNnn \q_@@_mark ? \@@_replace_next:w \__kernel_tl_gset:Nx }
+\cs_generate_variant:Nn \tl_replace_once:Nnn
+ { NnV , Nne , NV , Ne , Nee , c , cnV , cne , cV , ce , cee }
+\cs_generate_variant:Nn \tl_replace_once:Nnn
+ { Nx , Nnx , Nxx , cxn , cnx , cxx }
+\cs_generate_variant:Nn \tl_greplace_once:Nnn
+ { NnV , Nne , NV , Ne , Nee , c , cnV , cne , cV , ce , cee }
+\cs_generate_variant:Nn \tl_greplace_once:Nnn
+ { Nx , Nnx , Nxx , cxn , cnx , cxx }
+\cs_generate_variant:Nn \tl_replace_all:Nnn
+ { NnV , Nne , NV , Ne , Nee , c , cnV , cne , cV , ce , cee }
+\cs_generate_variant:Nn \tl_replace_all:Nnn
+ { Nx , Nnx , Nxx , cxn , cnx , cxx }
+\cs_generate_variant:Nn \tl_greplace_all:Nnn
+ { NnV , Nne , NV , Ne , Nee , c , cnV , cne , cV , ce , cee }
+\cs_generate_variant:Nn \tl_greplace_all:Nnn
+ { Nx , Nnx , Nxx , cxn , cnx , cxx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_replace:NnNNNnn,
+% \@@_replace_auxi:NnnNNNnn,
+% \@@_replace_auxii:nNNNnn,
+% \@@_replace_next:w,
+% \@@_replace_next_aux:w,
+% \@@_replace_wrap:w,
+% }
+% To implement the actual replacement auxiliary
+% \cs{@@_replace_auxii:nNNNnn} we need a \meta{delimiter} with
+% the following properties:
+% \begin{itemize}
+% \item all occurrences of the \meta{pattern}~|#6| in
+% \enquote{\meta{token list} \meta{delimiter}} belong to the
+% \meta{token list} and have no overlap with the \meta{delimiter},
+% \item the first occurrence of the \meta{delimiter} in
+% \enquote{\meta{token list} \meta{delimiter}} is the trailing
+% \meta{delimiter}.
+% \end{itemize}
+% We first find the building blocks for the \meta{delimiter}, namely
+% two tokens \meta{A} and~\meta{B} such that \meta{A} does not appear
+% in~|#6| and |#6| is not~\meta{B} (this condition is trivial if |#6|
+% has more than one token). Then we consider the delimiters
+% \enquote{\meta{A}} and \enquote{\meta{A} \meta{A}$^n$ \meta{B}
+% \meta{A}$^n$ \meta{B}}, for $n\geq 1$, where $\meta{A}^n$ denotes
+% $n$~copies of \meta{A}, and we choose as our \meta{delimiter} the
+% first one which is not in the \meta{token list}.
+%
+% Every delimiter in the set obeys the first condition: |#6|~does not
+% contain~\meta{A} hence cannot be overlapping with the \meta{token
+% list} and the \meta{delimiter}, and it cannot be within the
+% \meta{delimiter} since it would have to be in one of the two
+% \meta{B} hence be equal to this single token (or empty, but this is
+% an error case filtered separately). Given the particular form of
+% these delimiters, for which no prefix is also a suffix, the second
+% condition is actually a consequence of the weaker condition that the
+% \meta{delimiter} we choose does not appear in the \meta{token list}.
+% Additionally, the set of delimiters is such that a \meta{token list}
+% of $n$~tokens can contain at most $O(n^{1/2})$ of them, hence we
+% find a \meta{delimiter} with at most $O(n^{1/2})$ tokens in a time
+% at most $O(n^{3/2})$. Bear in mind that these upper bounds are
+% reached only in very contrived scenarios: we include the case
+% \enquote{\meta{A}} in the list of delimiters to try, so that the
+% \meta{delimiter} is simply \cs{q_@@_mark} in the most common
+% situation where neither the \meta{token list} nor the \meta{pattern}
+% contains \cs{q_@@_mark}.
+%
+% Let us now ahead, optimizing for this most common case. First, two
+% special cases: an empty \meta{pattern}~|#6| is an error, and if
+% |#1|~is absent from both the \meta{token list}~|#5| and the
+% \meta{pattern}~|#6| then we can use it as the \meta{delimiter}
+% through \cs{@@_replace_auxii:nNNNnn} |{#1}|. Otherwise, we end up
+% calling \cs{@@_replace:NnNNNnn} repeatedly with the first two
+% arguments \cs{q_@@_mark} |{?}|, |\?| |{??}|, |\??| |{???}|, and so on,
+% until |#6|~does not contain the control sequence~|#1|, which we take
+% as our~\meta{A}. The argument~|#2| only serves to collect~|?|
+% characters for~|#1|. Note that the order of the tests means that
+% the first two are done every time, which is wasteful (for instance,
+% we repeatedly test for the emptyness of~|#6|). However, this is
+% rare enough not to matter. Finally, choose~\meta{B} to be
+% \cs{q_@@_nil} or~\cs{q_@@_stop} such that it is not equal to~|#6|.
+%
+% The \cs{@@_replace_auxi:NnnNNNnn} auxiliary receives \Arg{A} and
+% |{|\meta{A}$^n$\meta{B}|}| as its arguments, initially with $n=1$.
+% If \enquote{\meta{A} \meta{A}$^n$\meta{B} \meta{A}$^n$\meta{B}} is
+% in the \meta{token list} then increase~$n$ and try again. Once it
+% is not anymore in the \meta{token list} we take it as our
+% \meta{delimiter} and pass this to the \texttt{auxii} auxiliary.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replace:NnNNNnn #1#2#3#4#5#6#7
+ {
+ \tl_if_empty:nTF {#6}
+ {
+ \msg_error:nne { kernel } { empty-search-pattern }
+ { \tl_to_str:n {#7} }
+ }
+ {
+ \tl_if_in:onTF { #5 #6 } {#1}
+ {
+ \tl_if_in:nnTF {#6} {#1}
+ { \exp_args:Nc \@@_replace:NnNNNnn {#2} {#2?} }
+ {
+ \@@_quark_if_nil:nTF {#6}
+ { \@@_replace_auxi:NnnNNNnn #5 {#1} { #1 \q_@@_stop } }
+ { \@@_replace_auxi:NnnNNNnn #5 {#1} { #1 \q_@@_nil } }
+ }
+ }
+ { \@@_replace_auxii:nNNNnn {#1} }
+ #3#4#5 {#6} {#7}
+ }
+ }
+\cs_new_protected:Npn \@@_replace_auxi:NnnNNNnn #1#2#3
+ {
+ \tl_if_in:NnTF #1 { #2 #3 #3 }
+ { \@@_replace_auxi:NnnNNNnn #1 { #2 #3 } {#2} }
+ { \@@_replace_auxii:nNNNnn { #2 #3 #3 } }
+ }
+% \end{macrocode}
+% The auxiliary \cs{@@_replace_auxii:nNNNnn} receives the following
+% arguments:
+% \begin{quote}
+% \Arg{delimiter} \meta{function} \meta{assignment} \\
+% \meta{tl~var} \Arg{pattern} \Arg{replacement}
+% \end{quote}
+% All of its work is done between
+% \cs{group_align_safe_begin:} and \cs{group_align_safe_end:} to avoid
+% issues in alignments. It does the actual replacement within
+% |#3|~|#4|~|{...}|, an \texttt{e}-expanding \meta{assignment}~|#3| to
+% the \meta{tl~var}~|#4|. The auxiliary \cs{@@_replace_next:w} is
+% called, followed by the \meta{token list}, some tokens including the
+% \meta{delimiter}~|#1|, followed by the \meta{pattern}~|#5|.
+% This auxiliary finds an argument delimited by~|#5| (the presence of
+% a trailing~|#5| avoids runaway arguments) and calls
+% \cs{@@_replace_wrap:w} to test whether this |#5| is found within the
+% \meta{token list} or is the trailing one.
+%
+% If on the one hand it is found within the \meta{token list}, then
+% |##1| cannot contain the \meta{delimiter}~|#1| that we worked so
+% hard to obtain, thus \cs{@@_replace_wrap:w} gets~|##1| as its own
+% argument~|##1|, and protects it against
+% the \texttt{e}-expanding assignment. It also finds \cs{exp_not:n}
+% as~|##2| and does nothing to it, thus letting through \cs{exp_not:n}
+% \Arg{replacement} into the assignment. Note that
+% \cs{@@_replace_next:w} and \cs{@@_replace_wrap:w} are always called
+% followed by two empty brace groups. These are safe because no
+% delimiter can match them. They prevent losing braces when grabbing
+% delimited arguments, but require the use of \cs{exp_not:o} and
+% \cs{use_none:nn}, rather than simply \cs{exp_not:n}.
+% Afterwards, \cs{@@_replace_next:w} is called
+% to repeat the replacement, or \cs{@@_replace_wrap:w} if we only want
+% a single replacement. In this second case, |##1| is the
+% \meta{remaining tokens} in the \meta{token list} and |##2| is some
+% \meta{ending code} which ends the assignment and removes the
+% trailing tokens |#5| using some \cs{if_false:} |{| \cs{fi:} |}|
+% trickery because~|#5| may contain any delimiter.
+%
+% If on the other hand the argument~|##1| of \cs{@@_replace_next:w} is
+% delimited by the trailing \meta{pattern}~|#5|, then |##1| is
+% \enquote{\{ \} \{ \} \meta{token list} \meta{delimiter}
+% \Arg{ending code}}, hence \cs{@@_replace_wrap:w} finds
+% \enquote{\{ \} \{ \} \meta{token list}} as |##1| and the
+% \meta{ending code} as~|##2|. It leaves the \meta{token list} into
+% the assignment and unbraces the \meta{ending code} which removes
+% what remains (essentially the \meta{delimiter} and
+% \meta{replacement}).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_replace_auxii:nNNNnn #1#2#3#4#5#6
+ {
+ \group_align_safe_begin:
+ \cs_set:Npn \@@_replace_wrap:w ##1 #1 ##2
+ { \__kernel_exp_not:w \exp_after:wN { \use_none:nn ##1 } ##2 }
+ \cs_set:Npe \@@_replace_next:w ##1 #5
+ {
+ \exp_not:N \@@_replace_wrap:w ##1
+ \exp_not:n { #1 }
+ \exp_not:n { \exp_not:n {#6} }
+ \exp_not:n { #2 { } { } }
+ }
+ #3 #4
+ {
+ \exp_after:wN \@@_replace_next_aux:w
+ #4
+ #1
+ {
+ \if_false: { \fi: }
+ \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi:
+ }
+ #5
+ }
+ \group_align_safe_end:
+ }
+\cs_new:Npn \@@_replace_next_aux:w { \@@_replace_next:w { } { } }
+\cs_new_eq:NN \@@_replace_wrap:w ?
+\cs_new_eq:NN \@@_replace_next:w ?
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \tl_remove_once:Nn, \tl_remove_once:NV, \tl_remove_once:Ne,
+% \tl_remove_once:cn, \tl_remove_once:cV, \tl_remove_once:ce
+% }
+% \begin{macro}
+% {
+% \tl_gremove_once:Nn, \tl_gremove_once:NV,
+% \tl_gremove_once:cn, \tl_gremove_once:cV,
+% }
+% Removal is just a special case of replacement.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_remove_once:Nn #1#2
+ { \tl_replace_once:Nnn #1 {#2} { } }
+\cs_new_protected:Npn \tl_gremove_once:Nn #1#2
+ { \tl_greplace_once:Nnn #1 {#2} { } }
+\cs_generate_variant:Nn \tl_remove_once:Nn { NV , Ne , c , cV , ce }
+\cs_generate_variant:Nn \tl_gremove_once:Nn { NV , Ne , c , cV , ce }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \tl_remove_all:Nn, \tl_remove_all:NV, \tl_remove_all:Ne,
+% \tl_remove_all:Nx,
+% \tl_remove_all:cn, \tl_remove_all:cV, \tl_remove_all:ce,
+% \tl_remove_all:cx,
+% }
+% \begin{macro}
+% {
+% \tl_gremove_all:Nn, \tl_gremove_all:NV, \tl_gremove_all:Ne,
+% \tl_gremove_all:Nx,
+% \tl_gremove_all:cn, \tl_gremove_all:cV, \tl_gremove_all:ce,
+% \tl_gremove_all:cx,
+% }
+% Removal is just a special case of replacement.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_remove_all:Nn #1#2
+ { \tl_replace_all:Nnn #1 {#2} { } }
+\cs_new_protected:Npn \tl_gremove_all:Nn #1#2
+ { \tl_greplace_all:Nnn #1 {#2} { } }
+\cs_generate_variant:Nn \tl_remove_all:Nn { NV , Ne , c , cV , ce }
+\cs_generate_variant:Nn \tl_remove_all:Nn { Nx , cx }
+\cs_generate_variant:Nn \tl_gremove_all:Nn { NV , Ne , c , cV , ce }
+\cs_generate_variant:Nn \tl_gremove_all:Nn { Nx , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Token list conditionals}
+%
+% \begin{macro}[pTF]{\tl_if_empty:N, \tl_if_empty:c}
+% These functions check whether the token list in the argument is
+% empty and execute the proper code from their argument(s).
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_empty:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \c_empty_tl
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_generate_conditional_variant:Nnn \tl_if_empty:N
+ { c } { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_empty:n, \tl_if_empty:V, \tl_if_empty:e}
+% The \cs{if:w} triggers the expansion of \cs{tl_to_str:n} which converts the
+% argument to a string: this is empty if and only if the argument is. Then
+% |\if:w \scan_stop: ... \scan_stop:| is \texttt{true} if and only if the
+% string |...| is empty.
+% It could be tempting to use |\if:w \scan_stop: #1 \scan_stop:| directly.
+% But this fails on a token list expanding to anything starting with
+% \cs{scan_stop:} leaving everything that follows in the input stream.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_empty:n #1 { p , TF , T , F }
+ {
+ \if:w \scan_stop: \tl_to_str:n {#1} \scan_stop:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_generate_conditional_variant:Nnn \tl_if_empty:n
+ { V , e } { p , TF , T , F }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF,documented-as=\tl_if_empty:nTF]{\tl_if_empty:o}
+% \begin{macro}[EXP]{\@@_if_empty_if:o}
+% The auxiliary function \cs{@@_if_empty_if:o} is for use
+% in various token list conditionals which reduce to testing
+% if a given token list is empty after applying a simple function
+% to it.
+% The test for emptiness is based on \cs{tl_if_empty:nTF}, but
+% the expansion is hard-coded for efficiency, as this auxiliary
+% function is used in several places.
+% We don't put \cs{prg_return_true:} and so on in the definition of
+% the auxiliary, because that would prevent an optimization applied to
+% conditionals that end with this code.
+% Also the |\@@_if_empty_if:o| is expanded once in |\tl_if_empty:oTF| for
+% efficiency as well (and to reduce code doubling).
+% \begin{macrocode}
+\cs_new:Npn \@@_if_empty_if:o #1
+ {
+ \if:w \scan_stop: \__kernel_tl_to_str:w \exp_after:wN {#1} \scan_stop:
+ }
+\exp_args:Nno \use:n
+ { \prg_new_conditional:Npnn \tl_if_empty:o #1 { p , TF , T , F } }
+ {
+ \@@_if_empty_if:o {#1}
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_blank:n, \tl_if_blank:V, \tl_if_blank:o}
+% \begin{macro}{\@@_if_blank_p:NNw}
+% \TeX{} skips spaces when reading a non-delimited arguments. Thus,
+% a \meta{token list} is blank if and only if \cs{use_none:n}
+% \meta{token list} |?| is empty after one expansion. The auxiliary
+% \cs{@@_if_empty_if:o} is a fast emptyness test, converting its
+% argument to a string (after one expansion) and using the test
+% \cs{if:w} \cs{scan_stop:} |...| \cs{scan_stop:}.
+% \begin{macrocode}
+\exp_args:Nno \use:n
+ { \prg_new_conditional:Npnn \tl_if_blank:n #1 { p , T , F , TF } }
+ {
+ \@@_if_empty_if:o { \use_none:n #1 ? }
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_generate_conditional_variant:Nnn \tl_if_blank:n
+ { e , V , o } { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_eq:NN, \tl_if_eq:Nc, \tl_if_eq:cN, \tl_if_eq:cc}
+% Returns \cs{c_true_bool} if and only if the two token list variables are
+% equal.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \tl_if_eq:NN \cs_if_eq:NN { p , T , F , TF }
+\prg_generate_conditional_variant:Nnn \tl_if_eq:NN
+ { Nc , c , cc } { p , TF , T , F }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_internal_a_tl, \l_@@_internal_b_tl}
+% Temporary storage.
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_a_tl
+\tl_new:N \l_@@_internal_b_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[TF]{\tl_if_eq:Nn}
+% A simple store and compare routine.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \tl_if_eq:Nn #1#2 { T , F , TF }
+ {
+ \group_begin:
+ \tl_set:Nn \l_@@_internal_b_tl {#2}
+ \exp_after:wN
+ \group_end:
+ \if_meaning:w #1 \l_@@_internal_b_tl
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_generate_conditional_variant:Nnn \tl_if_eq:Nn { c } { TF , T , F }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]
+% {
+% \tl_if_eq:nn, \tl_if_eq:nV, \tl_if_eq:ne, \tl_if_eq:Vn, \tl_if_eq:en,
+% \tl_if_eq:ee,
+% \tl_if_eq:xn, \tl_if_eq:nx, \tl_if_eq:xx,
+% }
+% A simple store and compare routine.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \tl_if_eq:nn #1#2 { T , F , TF }
+ {
+ \group_begin:
+ \tl_set:Nn \l_@@_internal_a_tl {#1}
+ \tl_set:Nn \l_@@_internal_b_tl {#2}
+ \exp_after:wN
+ \group_end:
+ \if_meaning:w \l_@@_internal_a_tl \l_@@_internal_b_tl
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_generate_conditional_variant:Nnn \tl_if_eq:nn
+ { nV , ne , nx , V, e , ee , x , xx }
+ { TF , T , F }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]
+% {
+% \tl_if_in:Nn, \tl_if_in:NV, \tl_if_in:No,
+% \tl_if_in:cn, \tl_if_in:cV, \tl_if_in:co
+% }
+% See \cs{tl_if_in:nnTF} for further comments. Here we simply
+% expand the token list variable and pass it to \cs{tl_if_in:nnTF}.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_if_in:NnT { \exp_args:No \tl_if_in:nnT }
+\cs_new_protected:Npn \tl_if_in:NnF { \exp_args:No \tl_if_in:nnF }
+\cs_new_protected:Npn \tl_if_in:NnTF { \exp_args:No \tl_if_in:nnTF }
+\prg_generate_conditional_variant:Nnn \tl_if_in:Nn
+ { NV , No , c , cV , co } { T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]
+% {
+% \tl_if_in:nn, \tl_if_in:Vn, \tl_if_in:VV, \tl_if_in:on, \tl_if_in:oo,
+% \tl_if_in:nV, \tl_if_in:no
+% }
+% Once more, the test relies on the emptiness test for robustness.
+% The function \cs{@@_tmp:w} removes tokens until the first occurrence
+% of |#2|. If this does not appear in |#1|, then the final |#2| is removed,
+% leaving an empty token list. Otherwise some tokens remain, and the
+% test is \texttt{false}. See \cs{tl_if_empty:nTF} for details on
+% the emptiness test.
+%
+% Treating correctly cases like
+% |\tl_if_in:nnTF {a state}{states}|, where |#1#2| contains |#2| before
+% the end, requires special care.
+% To cater for this case, we insert |{}{}| between the two token
+% lists. This marker may not appear in |#2| because of \TeX{} limitations
+% on what can delimit a parameter, hence we are safe. Using two brace
+% groups makes the test work also for empty arguments.
+% The \cs{if_false:} constructions are a faster way to do
+% \cs{group_align_safe_begin:} and \cs{group_align_safe_end:}.
+% The \cs{scan_stop:} ensures that \texttt{f}-expanding
+% \cs{tl_if_in:nnTF} does not lead to unbalanced braces.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \tl_if_in:nn #1#2 { T , F , TF }
+ {
+ \scan_stop:
+ \if_false: { \fi:
+ \cs_set:Npn \@@_tmp:w ##1 #2 { }
+ \tl_if_empty:oTF { \@@_tmp:w #1 {} {} #2 }
+ { \prg_return_false: } { \prg_return_true: }
+ \if_false: } \fi:
+ }
+\prg_generate_conditional_variant:Nnn \tl_if_in:nn
+ { V , VV , o , oo , nV , no } { T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF, EXP]{\tl_if_novalue:n}
+% \begin{macro}[EXP]{\@@_if_novalue:w}
+% Tests whether |##1| matches |-NoValue-| exactly (with suitable
+% catcodes): this is similar to \cs{quark_if_nil:nTF}. The first
+% argument of \cs{@@_if_novalue:w} is empty if and only if |##1|
+% starts with |-NoValue-|, while the second argument is empty if |##1|
+% is exactly |-NoValue-| or if it has a question mark just following
+% |-NoValue-|. In this second case, however, the material after the
+% first |?!| remains and makes the emptyness test return
+% \texttt{false}.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \prg_new_conditional:Npnn \tl_if_novalue:n ##1
+ { p , T , F , TF }
+ {
+ \@@_if_empty_if:o { \@@_if_novalue:w {} ##1 {} ? ! #1 ? ? ! }
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ \cs_new:Npn \@@_if_novalue:w ##1 #1 ##2 ? ##3 ? ! { ##1 ##2 }
+ }
+\exp_args:No \@@_tmp:w { \c_novalue_tl }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\tl_if_single:N, \tl_if_single:c}
+% Expand the token list and feed it to \cs{tl_if_single:nTF}.
+% \begin{macrocode}
+\cs_new:Npn \tl_if_single_p:N { \exp_args:No \tl_if_single_p:n }
+\cs_new:Npn \tl_if_single:NT { \exp_args:No \tl_if_single:nT }
+\cs_new:Npn \tl_if_single:NF { \exp_args:No \tl_if_single:nF }
+\cs_new:Npn \tl_if_single:NTF { \exp_args:No \tl_if_single:nTF }
+\prg_generate_conditional_variant:Nnn \tl_if_single:N {c} { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\tl_if_single:n}
+% \begin{macro}[EXP]{\@@_if_single:nnw}
+% This test is similar to \cs{tl_if_empty:nTF}. Expanding
+% \cs{use_none:nn} |#1| |??| once yields an empty result if |#1| is
+% blank, a single~|?| if |#1| has a single item, and otherwise yields
+% some tokens ending with |??|. Then, \cs{__kernel_tl_to_str:w} makes sure
+% there are no odd category codes. An earlier version would compare
+% the result to a single~|?| using string comparison, but the Lua call
+% is slow in \LuaTeX{}. Instead, \cs{@@_if_single:nnw} picks the
+% second token in front of it. If |#1| is empty, this token is
+% the trailing~|?| and the |\if:w| test yields \texttt{false}. If
+% |#1| has a single item, the token is~|\scan_stop:| and the |\if:w| test
+% yields \texttt{true}. Otherwise, it is one of the characters
+% resulting from \cs{tl_to_str:n}, and the |\if:w| test yields
+% \texttt{false}. Note that \cs{if:w} and
+% \cs{__kernel_tl_to_str:w} are primitives that take care of
+% expansion.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_single:n #1 { p , T , F , TF }
+ {
+ \if:w \scan_stop: \exp_after:wN \@@_if_single:nnw
+ \__kernel_tl_to_str:w
+ \exp_after:wN { \use_none:nn #1 ?? } \scan_stop: ? \s_@@_stop
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:Npn \@@_if_single:nnw #1#2#3 \s_@@_stop {#2}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\tl_if_single_token:n}
+% There are four cases: empty token list, token list starting with a
+% normal token, with a brace group, or with a space token. If the
+% token list starts with a normal token, remove it and check for
+% emptiness. For the next case, an empty token list is not a single
+% token. Finally, we have a non-empty token list starting with a
+% space or a brace group. Applying \texttt{f}-expansion yields an
+% empty result if and only if the token list is a single space.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_single_token:n #1 { p , T , F , TF }
+ {
+ \tl_if_head_is_N_type:nTF {#1}
+ { \@@_if_empty_if:o { \use_none:n #1 } }
+ {
+ \tl_if_empty:nTF {#1}
+ { \if_false: }
+ { \@@_if_empty_if:o { \exp:w \exp_end_continue_f:w #1 } }
+ }
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Mapping over token lists}
+%
+% \begin{macro}
+% {
+% \tl_map_function:nN, \tl_map_function:NN, \tl_map_function:cN,
+% \@@_map_function:Nnnnnnnnn, \@@_map_function_end:w,
+% \@@_use_none_delimit_by_s_stop:w
+% }
+% Expandable loop macro for token lists. We use the internal scan
+% mark \cs{s_@@_stop} (defined later), which is not allowed to show up
+% in the token list |#1| since it is internal to \pkg{l3tl}. This
+% allows us a very fast test of whether some \meta{item} is the
+% end-marker \cs{s_@@_stop}, namely call
+% \cs{@@_use_none_delimit_by_s_stop:w} \meta{item} \meta{function}
+% \cs{s_@@_stop}, which calls \meta{function} if the \meta{item} is
+% the end-marker. To speed up the loop even more, only test one out
+% of eight items, and once we hit one of the eight end-markers,
+% go more slowly through the last few items of the list using
+% \cs{@@_map_function_end:w}.
+% \begin{macrocode}
+\cs_new:Npn \tl_map_function:nN #1#2
+ {
+ \@@_map_function:Nnnnnnnnn #2 #1
+ \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop
+ \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop
+ \prg_break_point:Nn \tl_map_break: { }
+ }
+\cs_new:Npn \tl_map_function:NN
+ { \exp_args:No \tl_map_function:nN }
+\cs_generate_variant:Nn \tl_map_function:NN { c }
+\cs_new:Npn \@@_map_function:Nnnnnnnnn #1#2#3#4#5#6#7#8#9
+ {
+ \@@_use_none_delimit_by_s_stop:w
+ #9 \@@_map_function_end:w \s_@@_stop
+ #1 {#2} #1 {#3} #1 {#4} #1 {#5} #1 {#6} #1 {#7} #1 {#8} #1 {#9}
+ \@@_map_function:Nnnnnnnnn #1
+ }
+\cs_new:Npn \@@_map_function_end:w \s_@@_stop #1#2
+ {
+ \@@_use_none_delimit_by_s_stop:w #2 \tl_map_break: \s_@@_stop
+ #1 {#2}
+ \@@_map_function_end:w \s_@@_stop
+ }
+\cs_new:Npn \@@_use_none_delimit_by_s_stop:w #1 \s_@@_stop { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_map_inline:nn}
+% \begin{macro}{\tl_map_inline:Nn, \tl_map_inline:cn}
+% The inline functions are straight forward by now. We use a little
+% trick with the counter \cs{g__kernel_prg_map_int} to make
+% them nestable. We can also make use of \cs{@@_map_function:Nnnnnnnnn}
+% from before.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_map_inline:nn #1#2
+ {
+ \int_gincr:N \g__kernel_prg_map_int
+ \cs_gset_protected:cpn
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w } ##1 {#2}
+ \exp_args:Nc \@@_map_function:Nnnnnnnnn
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
+ #1
+ \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop
+ \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop
+ \prg_break_point:Nn \tl_map_break:
+ { \int_gdecr:N \g__kernel_prg_map_int }
+ }
+\cs_new_protected:Npn \tl_map_inline:Nn
+ { \exp_args:No \tl_map_inline:nn }
+\cs_generate_variant:Nn \tl_map_inline:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \tl_map_tokens:nn, \tl_map_tokens:Nn, \tl_map_tokens:cn,
+% \@@_map_tokens:nnnnnnnnn, \@@_map_tokens_end:w
+% }
+% Much like the function mapping.
+% \begin{macrocode}
+\cs_new:Npn \tl_map_tokens:nn #1#2
+ {
+ \@@_map_tokens:nnnnnnnnn {#2} #1
+ \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop
+ \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop
+ \prg_break_point:Nn \tl_map_break: { }
+ }
+\cs_new:Npn \tl_map_tokens:Nn
+ { \exp_args:No \tl_map_tokens:nn }
+\cs_generate_variant:Nn \tl_map_tokens:Nn { c }
+\cs_new:Npn \@@_map_tokens:nnnnnnnnn #1#2#3#4#5#6#7#8#9
+ {
+ \@@_use_none_delimit_by_s_stop:w
+ #9 \@@_map_tokens_end:w \s_@@_stop
+ \use:n {#1} {#2} \use:n {#1} {#3} \use:n {#1} {#4} \use:n {#1} {#5}
+ \use:n {#1} {#6} \use:n {#1} {#7} \use:n {#1} {#8} \use:n {#1} {#9}
+ \@@_map_tokens:nnnnnnnnn {#1}
+ }
+\cs_new:Npn \@@_map_tokens_end:w \s_@@_stop \use:n #1#2
+ {
+ \@@_use_none_delimit_by_s_stop:w #2 \tl_map_break: \s_@@_stop
+ #1 {#2}
+ \@@_map_tokens_end:w \s_@@_stop
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_map_variable:nNn}
+% \begin{macro}{\tl_map_variable:NNn, \tl_map_variable:cNn}
+% \begin{macro}{\@@_map_variable:Nnn}
+% \cs{tl_map_variable:nNn} \Arg{token list} \meta{tl~var}
+% \Arg{action} assigns \meta{tl~var} to each element and executes
+% \meta{action}. The assignment to \meta{tl~var} is done after the
+% quark test so that this variable does not get set to a quark.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_map_variable:nNn #1#2#3
+ { \tl_map_tokens:nn {#1} { \@@_map_variable:Nnn #2 {#3} } }
+\cs_new_protected:Npn \@@_map_variable:Nnn #1#2#3
+ { \tl_set:Nn #1 {#3} #2 }
+\cs_new_protected:Npn \tl_map_variable:NNn
+ { \exp_args:No \tl_map_variable:nNn }
+\cs_generate_variant:Nn \tl_map_variable:NNn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_map_break:}
+% \begin{macro}{\tl_map_break:n}
+% The break statements use the general \cs{prg_map_break:Nn}.
+% \begin{macrocode}
+\cs_new:Npn \tl_map_break:
+ { \prg_map_break:Nn \tl_map_break: { } }
+\cs_new:Npn \tl_map_break:n
+ { \prg_map_break:Nn \tl_map_break: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using token lists}
+%
+% \begin{macro}{\tl_to_str:n, \tl_to_str:o, \tl_to_str:V, \tl_to_str:v, \tl_to_str:e}
+% Another name for a primitive: defined in \pkg{l3basics}.
+% \begin{macrocode}
+\cs_generate_variant:Nn \tl_to_str:n { o , V , v , e }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_to_str:N, \tl_to_str:c}
+% These functions return the replacement text of a token list as a
+% string.
+% \begin{macrocode}
+\cs_new:Npn \tl_to_str:N #1 { \__kernel_tl_to_str:w \exp_after:wN {#1} }
+\cs_generate_variant:Nn \tl_to_str:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_use:N, \tl_use:c}
+% Token lists which are simply not defined give a clear \TeX{}
+% error here. No such luck for ones equal to \cs{scan_stop:} so
+% instead a test is made and if there is an issue an error is forced.
+% \begin{macrocode}
+\cs_new:Npn \tl_use:N #1
+ {
+ \tl_if_exist:NTF #1 {#1}
+ {
+ \msg_expandable_error:nnn
+ { kernel } { bad-variable } {#1}
+ }
+ }
+\cs_generate_variant:Nn \tl_use:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Working with the contents of token lists}
+%
+% \begin{macro}{\tl_count:n, \tl_count:V, \tl_count:v, \tl_count:e, \tl_count:o}
+% \begin{macro}{\tl_count:N, \tl_count:c}
+% \begin{macro}{\@@_count:n}
+% Count number of elements within a token list or token list
+% variable. Brace groups within the list are read as a single
+% element. Spaces are ignored.
+% \cs{@@_count:n} grabs the element and replaces it by |+1|.
+% The |0| ensures that it works on an empty list.
+% \begin{macrocode}
+\cs_new:Npn \tl_count:n #1
+ {
+ \int_eval:n
+ { 0 \tl_map_function:nN {#1} \@@_count:n }
+ }
+\cs_new:Npn \tl_count:N #1
+ {
+ \int_eval:n
+ { 0 \tl_map_function:NN #1 \@@_count:n }
+ }
+\cs_new:Npn \@@_count:n #1 { + 1 }
+\cs_generate_variant:Nn \tl_count:n { V , v , e , o }
+\cs_generate_variant:Nn \tl_count:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}[EXP]{\tl_count_tokens:n}
+% \begin{macro}[EXP]{\@@_act_count_normal:nN,
+% \@@_act_count_group:nn, \@@_act_count_space:n}
+% The token count is computed through an \cs{int_eval:n} construction.
+% Each \texttt{1+} is output to the \emph{left}, into the integer
+% expression, and the sum is ended by the \cs{exp_end:} inserted by
+% \cs{@@_act_end:wn} (which is technically implemented as \cs{c_zero_int}).
+% Somewhat a hack!
+% \begin{macrocode}
+\cs_new:Npn \tl_count_tokens:n #1
+ {
+ \int_eval:n
+ {
+ \@@_act:NNNn
+ \@@_act_count_normal:N
+ \@@_act_count_group:n
+ \@@_act_count_space:
+ {#1}
+ }
+ }
+\cs_new:Npn \@@_act_count_normal:N #1 { 1 + }
+\cs_new:Npn \@@_act_count_space: { 1 + }
+\cs_new:Npn \@@_act_count_group:n #1 { 2 + \tl_count_tokens:n {#1} + }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_reverse_items:n}
+% \begin{macro}{\@@_reverse_items:nwNwn}
+% \begin{macro}{\@@_reverse_items:wn}
+% Reversal of a token list is done by taking one item at a time
+% and putting it after \cs{s_@@_stop}.
+% \begin{macrocode}
+\cs_new:Npn \tl_reverse_items:n #1
+ {
+ \@@_reverse_items:nwNwn #1 ?
+ \s_@@_mark \@@_reverse_items:nwNwn
+ \s_@@_mark \@@_reverse_items:wn
+ \s_@@_stop { }
+ }
+\cs_new:Npn \@@_reverse_items:nwNwn #1 #2 \s_@@_mark #3 #4 \s_@@_stop #5
+ {
+ #3 #2
+ \s_@@_mark \@@_reverse_items:nwNwn
+ \s_@@_mark \@@_reverse_items:wn
+ \s_@@_stop { {#1} #5 }
+ }
+\cs_new:Npn \@@_reverse_items:wn #1 \s_@@_stop #2
+ { \__kernel_exp_not:w \exp_after:wN { \use_none:nn #2 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \tl_trim_spaces:n, \tl_trim_spaces:V, \tl_trim_spaces:v,
+% \tl_trim_spaces:e,
+% \tl_trim_spaces:o,
+% }
+% \begin{macro}{\tl_trim_spaces_apply:nN, \tl_trim_spaces_apply:oN}
+% \begin{macro}
+% {
+% \tl_trim_spaces:N, \tl_trim_spaces:c,
+% \tl_gtrim_spaces:N, \tl_gtrim_spaces:c
+% }
+% Trimming spaces from around the input is deferred to an internal
+% function whose first argument is the token list to trim, augmented
+% by an initial \cs{@@_trim_mark:}, and whose second argument is a
+% \meta{continuation}, which receives as a braced argument
+% \cs{@@_trim_mark:} \meta{trimmed token list}. The control sequence
+% \cs{@@_trim_mark:} expands to nothing in a single expansion. In the case
+% at hand, we take \cs{__kernel_exp_not:w} \cs{exp_after:wN} as our
+% continuation, so that space trimming behaves correctly within an
+% \texttt{e}-type or \texttt{x}-type expansion.
+% \begin{macrocode}
+\cs_new:Npn \tl_trim_spaces:n #1
+ {
+ \@@_trim_spaces:nn
+ { \@@_trim_mark: #1 }
+ { \__kernel_exp_not:w \exp_after:wN }
+ }
+\cs_generate_variant:Nn \tl_trim_spaces:n { V , v , e , o }
+\cs_new:Npn \tl_trim_spaces_apply:nN #1#2
+ { \@@_trim_spaces:nn { \@@_trim_mark: #1 } { \exp_args:No #2 } }
+\cs_generate_variant:Nn \tl_trim_spaces_apply:nN { o }
+\cs_new_protected:Npn \tl_trim_spaces:N #1
+ { \__kernel_tl_set:Nx #1 { \exp_args:No \tl_trim_spaces:n {#1} } }
+\cs_new_protected:Npn \tl_gtrim_spaces:N #1
+ { \__kernel_tl_gset:Nx #1 { \exp_args:No \tl_trim_spaces:n {#1} } }
+\cs_generate_variant:Nn \tl_trim_spaces:N { c }
+\cs_generate_variant:Nn \tl_gtrim_spaces:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_trim_spaces:nn}
+% \begin{macro}
+% {
+% \@@_trim_spaces_auxi:w, \@@_trim_spaces_auxii:w,
+% \@@_trim_spaces_auxiii:w, \@@_trim_spaces_auxiv:w
+% }
+% \begin{macro}{\@@_trim_mark:}
+% Trimming spaces from around the input is done using delimited
+% arguments and quarks, and to get spaces at odd places in the
+% definitions, we nest those in \cs{@@_tmp:w}, which then receives
+% a single space as its argument: |#1| is \verb*+ +.
+% Removing leading spaces is done with \cs{@@_trim_spaces_auxi:w},
+% which loops until \cs{@@_trim_mark:}\verb*+ + matches the end of the token
+% list: then |##1| is the token list and |##3| is
+% \cs{@@_trim_spaces_auxii:w}. This hands the relevant tokens to the
+% loop \cs{@@_trim_spaces_auxiii:w}, responsible for trimming
+% trailing spaces. The end is reached when \verb*+ + \cs{s_@@_nil}
+% matches the one present in the definition of \cs{tl_trim_spaces:n}.
+% Then \cs{@@_trim_spaces_auxiv:w} puts the token list into a group,
+% with a lingering \cs{@@_trim_mark:} at the start (which will expand to
+% nothing in one step of expansion), and feeds this to the
+% \meta{continuation}.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \cs_new:Npn \@@_trim_spaces:nn ##1
+ {
+ \@@_trim_spaces_auxi:w
+ ##1
+ \s_@@_nil
+ \@@_trim_mark: #1 { }
+ \@@_trim_mark: \@@_trim_spaces_auxii:w
+ \@@_trim_spaces_auxiii:w
+ #1 \s_@@_nil
+ \@@_trim_spaces_auxiv:w
+ \s_@@_stop
+ }
+ \cs_new:Npn
+ \@@_trim_spaces_auxi:w ##1 \@@_trim_mark: #1 ##2 \@@_trim_mark: ##3
+ {
+ ##3
+ \@@_trim_spaces_auxi:w
+ \@@_trim_mark:
+ ##2
+ \@@_trim_mark: #1 {##1}
+ }
+ \cs_new:Npn \@@_trim_spaces_auxii:w
+ \@@_trim_spaces_auxi:w \@@_trim_mark: \@@_trim_mark: ##1
+ {
+ \@@_trim_spaces_auxiii:w
+ ##1
+ }
+ \cs_new:Npn \@@_trim_spaces_auxiii:w ##1 #1 \s_@@_nil ##2
+ {
+ ##2
+ ##1 \s_@@_nil
+ \@@_trim_spaces_auxiii:w
+ }
+ \cs_new:Npn \@@_trim_spaces_auxiv:w ##1 \s_@@_nil ##2 \s_@@_stop ##3
+ { ##3 { ##1 } }
+ \cs_new:Npn \@@_trim_mark: {}
+ }
+\@@_tmp:w { ~ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\tl_sort:Nn, \tl_sort:cn, \tl_gsort:Nn, \tl_gsort:cn, \tl_sort:nN}
+% Implemented in \pkg{l3sort}.
+% \end{macro}
+%
+% \subsection{The first token from a token list}
+%
+% \begin{macro}{\tl_head:N, \tl_head:n, \tl_head:V, \tl_head:v, \tl_head:f}
+% \begin{macro}{\@@_head_auxi:nw, \@@_head_auxii:n}
+% \begin{macro}{\tl_head:w,\@@_tl_head:w}
+% \begin{macro}{\tl_tail:N, \tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f}
+% Finding the head of a token list expandably always strips braces, which
+% is fine as this is consistent with for example mapping over a list. The
+% empty brace groups in \cs{tl_head:n} ensure that a blank argument gives an
+% empty result. The result is returned within the \tn{unexpanded} primitive.
+% The approach here is to use \cs{if_false:} to allow us to use |}| as
+% the closing delimiter: this is the only safe choice, as any other token
+% would not be able to parse it's own code. More detail in
+% \url{http://tex.stackexchange.com/a/70168}.
+% \begin{macrocode}
+\cs_new:Npn \tl_head:n #1
+ {
+ \__kernel_exp_not:w \tex_expanded:D
+ { { \if_false: { \fi: \@@_head_aux:n #1 { } } } }
+ }
+\cs_new:Npn \@@_head_aux:n #1
+ {
+ \__kernel_exp_not:w {#1}
+ \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi:
+ }
+\cs_generate_variant:Nn \tl_head:n { V , v , f }
+\cs_new:Npn \tl_head:w #1#2 \q_stop {#1}
+\cs_new:Npn \@@_tl_head:w #1#2 \s_@@_stop {#1}
+\cs_new:Npn \tl_head:N { \exp_args:No \tl_head:n }
+% \end{macrocode}
+% To correctly leave the tail of a token list, it's important \emph{not} to
+% absorb any of the tail part as an argument. For example, the simple
+% definition
+% \begin{verbatim}
+% \cs_new:Npn \tl_tail:n #1 { \tl_tail:w #1 \q_stop }
+% \cs_new:Npn \tl_tail:w #1#2 \q_stop
+% \end{verbatim}
+% would give the wrong result for |\tl_tail:n { a { bc } }| (the braces would
+% be stripped). Thus the only safe way to proceed is to first check that
+% there is an item to grab (\emph{i.e.}~that the argument is not blank) and
+% assuming there is to dispose of the first item. As with \cs{tl_head:n},
+% the result is protected from further expansion by \tn{unexpanded}.
+% While we could optimise the test here, this would leave some tokens
+% \enquote{banned} in the input, which we do not have with this definition.
+% \begin{macrocode}
+\exp_args:Nno \use:n { \cs_new:Npn \tl_tail:n #1 }
+ {
+ \exp_after:wN \__kernel_exp_not:w
+ \tl_if_blank:nTF {#1}
+ { { } }
+ { \exp_after:wN { \use_none:n #1 } }
+ }
+\cs_generate_variant:Nn \tl_tail:n { V , v , f }
+\cs_new:Npn \tl_tail:N { \exp_args:No \tl_tail:n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]
+% {
+% \tl_if_head_eq_meaning:nN, \tl_if_head_eq_meaning:VN,
+% \tl_if_head_eq_meaning:eN
+% }
+% \begin{macro}[pTF]
+% {
+% \tl_if_head_eq_charcode:nN, \tl_if_head_eq_charcode:VN,
+% \tl_if_head_eq_charcode:eN, \tl_if_head_eq_charcode:fN
+% }
+% \begin{macro}[pTF]
+% {
+% \tl_if_head_eq_catcode:nN, \tl_if_head_eq_catcode:VN,
+% \tl_if_head_eq_catcode:eN, \tl_if_head_eq_catcode:oN
+% }
+% \begin{macro}[EXP]{\@@_head_exp_not:w}
+% \begin{macro}[EXP]{\@@_if_head_eq_empty_arg:w}
+% Accessing the first token of a token list is tricky in three cases:
+% when it has category code $1$ (begin-group token), when it is an
+% explicit space, with category code $10$ and character code $32$, or
+% when the token list is empty (obviously).
+%
+% Forgetting temporarily about this issue we would use the following
+% test in \cs{tl_if_head_eq_charcode:nN}. Here, \cs{tl_head:w} yields
+% the first token of the token list, then passed to \cs{exp_not:N}.
+% \begin{verbatim}
+% \if_charcode:w
+% \exp_after:wN \exp_not:N \tl_head:w #1 \q_nil \q_stop
+% \exp_not:N #2
+% \end{verbatim}
+% The two first special cases are detected by testing if the token
+% list starts with an \texttt{N}-type token (the extra |?| sends empty
+% token lists to the \texttt{true} branch of this test). In those
+% cases, the first token is a character, and since we only care about
+% its character code, we can use \cs{str_head:n} to access it (this
+% works even if it is a space character). An empty argument
+% results in \cs{tl_head:w} leaving two token: |^| and
+% \cs{@@_if_head_eq_empty_arg:w} which will result in the \cs{if_charcode:w}
+% test being false and remove \cs{exp_not:N} and |#2|.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_eq_charcode:nN #1#2 { p , T , F , TF }
+ {
+ \if_charcode:w
+ \tl_if_head_is_N_type:nTF { #1 ? }
+ { \@@_head_exp_not:w #1 { ^ \@@_if_head_eq_empty_arg:w } \s_@@_stop }
+ { \str_head:n {#1} }
+ \exp_not:N #2
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_generate_conditional_variant:Nnn \tl_if_head_eq_charcode:nN
+ { V , e , f } { p , TF , T , F }
+% \end{macrocode}
+% For \cs{tl_if_head_eq_catcode:nN}, again we detect special cases
+% with a \cs{tl_if_head_is_N_type:n}. Then we need to test if the
+% first token is a begin-group token or an explicit space token, and
+% produce the relevant token, either \cs{c_group_begin_token} or
+% \cs{c_space_token}. Again, for an empty argument, a hack is used,
+% removing the token given by the user and leaving two tokens in the input
+% stream which will make the \cs{if_catcode:w} test return \texttt{false}.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_eq_catcode:nN #1 #2 { p , T , F , TF }
+ {
+ \if_catcode:w
+ \tl_if_head_is_N_type:nTF { #1 ? }
+ { \@@_head_exp_not:w #1 { ^ \@@_if_head_eq_empty_arg:w } \s_@@_stop }
+ {
+ \tl_if_head_is_group:nTF {#1}
+ \c_group_begin_token
+ \c_space_token
+ }
+ \exp_not:N #2
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_generate_conditional_variant:Nnn \tl_if_head_eq_catcode:nN
+ { V , e , o } { p , TF , T , F }
+% \end{macrocode}
+% For \cs{tl_if_head_eq_meaning:nN}, again, detect special cases. In
+% the normal case, use \cs{tl_head:w}, with no \cs{exp_not:N} this
+% time, since \cs{if_meaning:w} causes no expansion. With an empty
+% argument, the test is \texttt{true}, and \cs{use_none:nnn} removes
+% |#2| and \cs{prg_return_true:} and \cs{else:} (it is safe this way here as
+% in this case \cs{prg_new_conditional:Npnn} didn't optimize these two away).
+% In the special cases, we know that the first token is a character,
+% hence \cs{if_charcode:w} and \cs{if_catcode:w} together are enough.
+% We combine them in some order, hopefully faster than the reverse.
+% Tests are not nested because the arguments may contain unmatched
+% primitive conditionals.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_eq_meaning:nN #1#2 { p , T , F , TF }
+ {
+ \tl_if_head_is_N_type:nTF { #1 ? }
+ \@@_if_head_eq_meaning_normal:nN
+ \@@_if_head_eq_meaning_special:nN
+ {#1} #2
+ }
+\prg_generate_conditional_variant:Nnn \tl_if_head_eq_meaning:nN
+ { V , e } { p , TF , T , F }
+\cs_new:Npn \@@_if_head_eq_meaning_normal:nN #1 #2
+ {
+ \exp_after:wN \if_meaning:w
+ \@@_tl_head:w #1 { ?? \use_none:nnn } \s_@@_stop #2
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:Npn \@@_if_head_eq_meaning_special:nN #1 #2
+ {
+ \if_charcode:w \str_head:n {#1} \exp_not:N #2
+ \exp_after:wN \use_ii:nn
+ \else:
+ \prg_return_false:
+ \fi:
+ \use_none:n
+ {
+ \if_catcode:w \exp_not:N #2
+ \tl_if_head_is_group:nTF {#1}
+ { \c_group_begin_token }
+ { \c_space_token }
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ }
+% \end{macrocode}
+%
+% Both \cs{tl_if_head_eq_charcode:nN} and \cs{tl_if_head_eq_catcode:nN} will
+% need to get the first token of their argument and apply \cs{exp_not:N} to
+% it. \cs{@@_head_exp_not:w} does exactly that.
+% \begin{macrocode}
+\cs_new:Npn \@@_head_exp_not:w #1 #2 \s_@@_stop
+ { \exp_not:N #1 }
+% \end{macrocode}
+%
+% If the argument of \cs{tl_if_head_eq_charcode:nN} and
+% \cs{tl_if_head_eq_catcode:nN} was empty \cs{@@_if_head_eq_empty_arg:w} will
+% be left in the input stream. This macro has to remove \cs{exp_not:N} and
+% the following token from the input stream to make sure no unbalanced
+% if-construct is created and leave tokens there which make the two tests
+% return \texttt{false}.
+% \begin{macrocode}
+\cs_new:Npn \@@_if_head_eq_empty_arg:w \exp_not:N #1
+ { ? }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_head_is_N_type:n}
+% \begin{macro}[EXP]
+% {
+% \@@_if_head_is_N_type_auxi:w ,
+% \@@_if_head_is_N_type_auxii:n ,
+% }
+% A token list can be empty, can start with an explicit space
+% character (catcode 10 and charcode 32), can start with a begin-group
+% token (catcode 1), or start with an \texttt{N}-type argument. In
+% the first two cases, and when |#1~| starts with |{}~|,
+% \cs{@@_if_head_is_N_type_auxi:w} receives an empty argument hence
+% produces |f| and removes everything before the first
+% \cs{scan_stop:}. In the third case (except when |#1~| starts with
+% |{}~|), the second auxiliary removes the first copy of~|#1| that was
+% used for the space test, then expands \cs{token_to_str:N} which hits
+% the leading begin-group token, leaving a single closing brace to be
+% compared with \cs{scan_stop:}. In the last case,
+% \cs{token_to_str:N} does not change the brace balance so that only
+% \cs{scan_stop:} \cs{scan_stop:} remain, making the character code
+% test true. One cannot optimize by
+% moving one of the \cs{scan_stop:} to the beginning: if |#1| contains
+% primitive conditionals, all of its occurrences must be dealt with before
+% the \cs{if:w} tries to skip the \texttt{true} branch of the
+% conditional.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_is_N_type:n #1 { p , T , F , TF }
+ {
+ \if:w
+ \if_false: { \fi: \@@_if_head_is_N_type_auxi:w #1 ~ }
+ { \exp_after:wN { \token_to_str:N #1 } }
+ \scan_stop: \scan_stop:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\exp_args:Nno \use:n { \cs_new:Npn \@@_if_head_is_N_type_auxi:w #1 ~ }
+ {
+ \tl_if_empty:nTF {#1}
+ { f \exp_after:wN \use_none:nn }
+ { \exp_after:wN \@@_if_head_is_N_type_auxii:n }
+ \exp_after:wN { \if_false: } \fi:
+ }
+\cs_new:Npn \@@_if_head_is_N_type_auxii:n #1
+ { \exp_after:wN \use_none:n \exp_after:wN }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\tl_if_head_is_group:n}
+% \begin{macro}[EXP]{\@@_if_head_is_group_fi_false:w}
+% Pass the first token of |#1| through \cs{token_to_str:N}, then check
+% for the brace balance. The extra \texttt{?} caters for an empty
+% argument. This could be made faster, but we need all brace tricks
+% to happen in one step of expansion, keeping the token list brace
+% balanced at all times.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_is_group:n #1 { p , T , F , TF }
+ {
+ \if:w
+ \exp_after:wN \use_none:n
+ \exp_after:wN { \exp_after:wN { \token_to_str:N #1 ? } }
+ \scan_stop: \scan_stop:
+ \@@_if_head_is_group_fi_false:w
+ \fi:
+ \if_true:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:Npn \@@_if_head_is_group_fi_false:w \fi: \if_true: { \fi: \if_false: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\tl_if_head_is_space:n}
+% \begin{macro}[EXP]{\@@_if_head_is_space:w}
+% The auxiliary's argument is all that is before the first explicit
+% space in |\prg_do_nothing:#1?~|. If that is a single~|\prg_do_nothing:| the
+% test yields \texttt{true}. Otherwise, that is more than one token, and the
+% test yields \texttt{false}. The work is done within braces (with an
+% |\if_false: { \fi: ... }| construction) both to hide potential
+% alignment tab characters from \TeX{} in a table, and to allow for
+% removing what remains of the token list after its first space. The use of
+% \cs{if:w} ensures that the result of a single step of expansion directly
+% yields a balanced token list (no trailing closing brace).
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_is_space:n #1 { p , T , F , TF }
+ {
+ \if:w
+ \if_false: { \fi: \@@_if_head_is_space:w \prg_do_nothing: #1 ? ~ }
+ \scan_stop: \scan_stop:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\exp_args:Nno \use:n { \cs_new:Npn \@@_if_head_is_space:w #1 ~ }
+ {
+ \@@_if_empty_if:o {#1} \else: f \fi:
+ \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Token by token changes}
+%
+% \begin{variable}{\s_@@_act_stop}
+% The \cs[no-index]{@@_act_\ldots{}} functions may be applied to any token list.
+% Hence, we use a private quark, to allow any token, even quarks,
+% in the token list.
+% Only \cs{s_@@_act_stop} may not appear in the token lists manipulated by
+% \cs{@@_act:NNNn} functions.
+% \begin{macrocode}
+\scan_new:N \s_@@_act_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_act:NNNn}
+% \begin{macro}[EXP]{\@@_act_output:n, \@@_act_reverse_output:n}
+% \begin{macro}[EXP]{\@@_act_loop:w}
+% \begin{macro}[EXP]{\@@_act_normal:NwNNN}
+% \begin{macro}[EXP]{\@@_act_group:nwNNN}
+% \begin{macro}[EXP]{\@@_act_space:wwNNN}
+% \begin{macro}[EXP]{\@@_act_end:wn}
+% \begin{macro}[EXP]
+% {
+% \@@_act_if_head_is_space:nTF,
+% \@@_act_if_head_is_space:w,
+% \@@_act_if_head_is_space_true:w
+% }
+% \begin{macro}[EXP]{\@@_use_none_delimit_by_q_act_stop:w}
+% To help control the expansion, \cs{@@_act:NNNn} should always
+% be preceeded by \cs{exp:w} and ends by producing \cs{exp_end:}
+% once the result has been obtained. This way no internal token of it can be
+% accidentally end up in the input stream.
+% Because \cs{s_@@_act_stop} can't appear without braces around it in the
+% argument~|#1| of \cs{@@_act_loop:w}, we can use this marker to set up a fast
+% test for leading spaces.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \cs_new:Npn \@@_act_if_head_is_space:nTF ##1
+ {
+ \@@_act_if_head_is_space:w
+ \s_@@_act_stop ##1 \s_@@_act_stop \@@_act_if_head_is_space_true:w
+ \s_@@_act_stop #1 \s_@@_act_stop \use_ii:nn
+ }
+ \cs_new:Npn \@@_act_if_head_is_space:w
+ ##1 \s_@@_act_stop #1 ##2 \s_@@_act_stop
+ {}
+ \cs_new:Npn \@@_act_if_head_is_space_true:w
+ \s_@@_act_stop #1 \s_@@_act_stop \use_ii:nn ##1 ##2
+ {##1}
+ }
+\@@_tmp:w { ~ }
+% \end{macrocode}
+% (We expand the definition \cs{@@_act_if_head_is_space:nTF} when
+% setting up \cs{@@_act_loop:w}, so we can then undefine the auxiliary.)
+% In the loop, we check how the token list begins and act
+% accordingly. In the \enquote{group} case, we may have
+% reached \cs{s_@@_act_stop}, the end of the list. Then
+% leave \cs{exp_end:} and the result in the input stream,
+% to terminate the expansion of \cs{exp:w}.
+% Otherwise, apply the relevant function to the
+% \enquote{arguments}, |#3|
+% and to the head of the token list. Then repeat the loop.
+% The scheme is the same if the token list starts with an |N|-type
+% or with a space, making sure that
+% \cs{@@_act_space:wwNNN} gobbles the space.
+% \begin{macrocode}
+\exp_args:Nne \use:n { \cs_new:Npn \@@_act_loop:w #1 \s_@@_act_stop }
+ {
+ \exp_not:o { \@@_act_if_head_is_space:nTF {#1} }
+ \exp_not:N \@@_act_space:wwNNN
+ {
+ \exp_not:o { \tl_if_head_is_group:nTF {#1} }
+ \exp_not:N \@@_act_group:nwNNN
+ \exp_not:N \@@_act_normal:NwNNN
+ }
+ \exp_not:n {#1} \s_@@_act_stop
+ }
+\cs_undefine:N \@@_act_if_head_is_space:nTF
+\cs_new:Npn \@@_act_normal:NwNNN #1 #2 \s_@@_act_stop #3
+ {
+ #3 #1
+ \@@_act_loop:w #2 \s_@@_act_stop
+ #3
+ }
+\cs_new:Npn \@@_use_none_delimit_by_s_act_stop:w #1 \s_@@_act_stop { }
+\cs_new:Npn \@@_act_end:wn #1 \@@_act_result:n #2
+ { \group_align_safe_end: \exp_end: #2 }
+\cs_new:Npn \@@_act_group:nwNNN #1 #2 \s_@@_act_stop #3#4#5
+ {
+ \@@_use_none_delimit_by_s_act_stop:w #1 \@@_act_end:wn \s_@@_act_stop
+ #5 {#1}
+ \@@_act_loop:w #2 \s_@@_act_stop
+ #3 #4 #5
+ }
+\exp_last_unbraced:NNo
+ \cs_new:Npn \@@_act_space:wwNNN \c_space_tl #1 \s_@@_act_stop #2#3
+ {
+ #3
+ \@@_act_loop:w #1 \s_@@_act_stop
+ #2 #3
+ }
+% \end{macrocode}
+% \cs{@@_act:NNNn} loops over tokens, groups, and spaces in |#4|.
+% |{\s_@@_act_stop}| serves as the end of token list marker, the |?| after it
+% avoids losing outer braces. The result is stored as an argument for the
+% dummy function \cs{@@_act_result:n}.
+% \begin{macrocode}
+\cs_new:Npn \@@_act:NNNn #1#2#3#4
+ {
+ \group_align_safe_begin:
+ \@@_act_loop:w #4 { \s_@@_act_stop } ? \s_@@_act_stop
+ #1 #3 #2
+ \@@_act_result:n { }
+ }
+% \end{macrocode}
+% Typically, the output is done to the right of what was already output,
+% using \cs{@@_act_output:n}, but for the \cs{@@_act_reverse} functions,
+% it should be done to the left.
+% \begin{macrocode}
+\cs_new:Npn \@@_act_output:n #1 #2 \@@_act_result:n #3
+ { #2 \@@_act_result:n { #3 #1 } }
+\cs_new:Npn \@@_act_reverse_output:n #1 #2 \@@_act_result:n #3
+ { #2 \@@_act_result:n { #1 #3 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {\tl_reverse:n, \tl_reverse:o, \tl_reverse:V, \tl_reverse:f, \tl_reverse:e}
+% \begin{macro}[EXP]{\@@_reverse_normal:nN}
+% \begin{macro}[EXP]{\@@_reverse_group_preserve:nn}
+% \begin{macro}[EXP]{\@@_reverse_space:n}
+% The goal here is to reverse without losing spaces nor braces.
+% This is done using the general internal function \cs{@@_act:NNNn}.
+% Spaces and \enquote{normal} tokens are output on the left of the current
+% output. Grouped tokens are output to the left but without any reversal
+% within the group.
+% \begin{macrocode}
+\cs_new:Npn \tl_reverse:n #1
+ {
+ \__kernel_exp_not:w \exp_after:wN
+ {
+ \exp:w
+ \@@_act:NNNn
+ \@@_reverse_normal:N
+ \@@_reverse_group_preserve:n
+ \@@_reverse_space:
+ {#1}
+ }
+ }
+\cs_generate_variant:Nn \tl_reverse:n { o , V , f , e }
+\cs_new:Npn \@@_reverse_normal:N
+ { \@@_act_reverse_output:n }
+\cs_new:Npn \@@_reverse_group_preserve:n #1
+ { \@@_act_reverse_output:n { {#1} } }
+\cs_new:Npn \@@_reverse_space:
+ { \@@_act_reverse_output:n { ~ } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_reverse:N, \tl_reverse:c, \tl_greverse:N, \tl_greverse:c}
+% This reverses the list, leaving \cs{exp_stop_f:} in front,
+% which stops the \texttt{f}-expansion.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_reverse:N #1
+ { \__kernel_tl_set:Nx #1 { \exp_args:No \tl_reverse:n { #1 } } }
+\cs_new_protected:Npn \tl_greverse:N #1
+ { \__kernel_tl_gset:Nx #1 { \exp_args:No \tl_reverse:n { #1 } } }
+\cs_generate_variant:Nn \tl_reverse:N { c }
+\cs_generate_variant:Nn \tl_greverse:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Using a single item}
+%
+% \begin{macro}{\tl_item:nn, \tl_item:Nn, \tl_item:cn}
+% \begin{macro}{\@@_item_aux:nn, \@@_item:nn}
+% The idea here is to find the offset of the item from the left, then use
+% a loop to grab the correct item. If the resulting offset is too large,
+% then \cs{@@_if_recursion_tail_break:nN} terminates the loop, and returns
+% nothing at all.
+% \begin{macrocode}
+\cs_new:Npn \tl_item:nn #1#2
+ {
+ \exp_args:Nf \@@_item:nn
+ { \exp_args:Nf \@@_item_aux:nn { \int_eval:n {#2} } {#1} }
+ #1
+ \q_@@_recursion_tail
+ \prg_break_point:
+ }
+\cs_new:Npn \@@_item_aux:nn #1#2
+ {
+ \int_compare:nNnTF {#1} < 0
+ { \int_eval:n { \tl_count:n {#2} + 1 + #1 } }
+ {#1}
+ }
+\cs_new:Npn \@@_item:nn #1#2
+ {
+ \@@_if_recursion_tail_break:nN {#2} \prg_break:
+ \int_compare:nNnTF {#1} = 1
+ { \prg_break:n { \exp_not:n {#2} } }
+ { \exp_args:Nf \@@_item:nn { \int_eval:n { #1 - 1 } } }
+ }
+\cs_new:Npn \tl_item:Nn { \exp_args:No \tl_item:nn }
+\cs_generate_variant:Nn \tl_item:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_rand_item:n, \tl_rand_item:N, \tl_rand_item:c}
+% Importantly \cs{tl_item:nn} only evaluates its argument once.
+% \begin{macrocode}
+\cs_new:Npn \tl_rand_item:n #1
+ {
+ \tl_if_blank:nF {#1}
+ { \tl_item:nn {#1} { \int_rand:nn { 1 } { \tl_count:n {#1} } } }
+ }
+\cs_new:Npn \tl_rand_item:N { \exp_args:No \tl_rand_item:n }
+\cs_generate_variant:Nn \tl_rand_item:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_range:Nnn, \tl_range:cnn, \tl_range:nnn}
+% \begin{macro}
+% {
+% \@@_range:Nnnn, \@@_range:nnnNn, \@@_range:nnNn, \@@_range_skip:w,
+% \@@_range:w, \@@_range_skip_spaces:n, \@@_range_collect:nn,
+% \@@_range_collect:ff, \@@_range_collect_space:nw,
+% \@@_range_collect_N:nN, \@@_range_collect_group:nN,
+% }
+% To avoid checking for the end of the token list at every step, start
+% by counting the number $l$ of items and \enquote{normalizing} the
+% bounds, namely clamping them to the interval $[0,l]$ and dealing
+% with negative indices. More precisely, \cs{@@_range_items:nnNn}
+% receives the number of items to skip at the beginning of the token
+% list, the index of the last item to keep, a function which is either
+% \cs{@@_range:w} or the token list itself. If nothing should be kept,
+% leave |{}|: this stops the \texttt{f}-expansion of \cs{tl_head:f} and that
+% function produces an empty result. Otherwise, repeatedly call
+% \cs{@@_range_skip:w} to delete |#1| items from the input stream (the
+% extra brace group avoids an off-by-one shift). For the braced
+% version \cs{@@_range_braced:w} sets up
+% \cs{@@_range_collect_braced:w} which stores items one by one in an
+% argument after the semicolon. Depending on the first token of the tail,
+% either just move it (if it is a space) or also decrement the number of
+% items left to find. Eventually, the result is a brace group followed by
+% the rest of the token list, and \cs{tl_head:f} cleans up and gives the
+% result in \cs{exp_not:n}.
+% \begin{macrocode}
+\cs_new:Npn \tl_range:Nnn { \exp_args:No \tl_range:nnn }
+\cs_generate_variant:Nn \tl_range:Nnn { c }
+\cs_new:Npn \tl_range:nnn { \@@_range:Nnnn \@@_range:w }
+\cs_new:Npn \@@_range:Nnnn #1#2#3#4
+ {
+ \tl_head:f
+ {
+ \exp_args:Nf \@@_range:nnnNn
+ { \tl_count:n {#2} } {#3} {#4} #1 {#2}
+ }
+ }
+\cs_new:Npn \@@_range:nnnNn #1#2#3
+ {
+ \exp_args:Nff \@@_range:nnNn
+ {
+ \exp_args:Nf \@@_range_normalize:nn
+ { \int_eval:n { #2 - 1 } } {#1}
+ }
+ {
+ \exp_args:Nf \@@_range_normalize:nn
+ { \int_eval:n {#3} } {#1}
+ }
+ }
+\cs_new:Npn \@@_range:nnNn #1#2#3#4
+ {
+ \if_int_compare:w #2 > #1 \exp_stop_f: \else:
+ \exp_after:wN { \exp_after:wN }
+ \fi:
+ \exp_after:wN #3
+ \int_value:w \int_eval:n { #2 - #1 } \exp_after:wN ;
+ \exp_after:wN { \exp:w \@@_range_skip:w #1 ; { } #4 }
+ }
+\cs_new:Npn \@@_range_skip:w #1 ; #2
+ {
+ \if_int_compare:w #1 > \c_zero_int
+ \exp_after:wN \@@_range_skip:w
+ \int_value:w \int_eval:n { #1 - 1 } \exp_after:wN ;
+ \else:
+ \exp_after:wN \exp_end:
+ \fi:
+ }
+\cs_new:Npn \@@_range:w #1 ; #2
+ {
+ \exp_args:Nf \@@_range_collect:nn
+ { \@@_range_skip_spaces:n {#2} } {#1}
+ }
+\cs_new:Npn \@@_range_skip_spaces:n #1
+ {
+ \tl_if_head_is_space:nTF {#1}
+ { \exp_args:Nf \@@_range_skip_spaces:n {#1} }
+ { { } #1 }
+ }
+\cs_new:Npn \@@_range_collect:nn #1#2
+ {
+ \int_compare:nNnTF {#2} = 0
+ {#1}
+ {
+ \exp_args:No \tl_if_head_is_space:nTF { \use_none:n #1 }
+ {
+ \exp_args:Nf \@@_range_collect:nn
+ { \@@_range_collect_space:nw #1 }
+ {#2}
+ }
+ {
+ \@@_range_collect:ff
+ {
+ \exp_args:No \tl_if_head_is_N_type:nTF { \use_none:n #1 }
+ { \@@_range_collect_N:nN }
+ { \@@_range_collect_group:nn }
+ #1
+ }
+ { \int_eval:n { #2 - 1 } }
+ }
+ }
+ }
+\cs_new:Npn \@@_range_collect_space:nw #1 ~ { { #1 ~ } }
+\cs_new:Npn \@@_range_collect_N:nN #1#2 { { #1 #2 } }
+\cs_new:Npn \@@_range_collect_group:nn #1#2 { { #1 {#2} } }
+\cs_generate_variant:Nn \@@_range_collect:nn { ff }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_range_normalize:nn}
+% This function converts an \meta{index} argument into an explicit
+% position in the token list (a result of $0$ denoting \enquote{out of
+% bounds}). Expects two explicit integer arguments: the \meta{index}
+% |#1| and the string count~|#2|. If |#1| is negative, replace it by
+% $|#1| + |#2| + 1$, then limit to the range $[0, |#2|]$.
+% \begin{macrocode}
+\cs_new:Npn \@@_range_normalize:nn #1#2
+ {
+ \int_eval:n
+ {
+ \if_int_compare:w #1 < \c_zero_int
+ \if_int_compare:w #1 < -#2 \exp_stop_f:
+ 0
+ \else:
+ #1 + #2 + 1
+ \fi:
+ \else:
+ \if_int_compare:w #1 < #2 \exp_stop_f:
+ #1
+ \else:
+ #2
+ \fi:
+ \fi:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Viewing token lists}
+%
+% \begin{macro}{\tl_show:N, \tl_show:c, \tl_log:N, \tl_log:c, \@@_show:NN}
+% Showing token list variables is done after checking that the
+% variable is defined (see \cs{__kernel_register_show:N}).
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_show:N { \@@_show:NN \tl_show:n }
+\cs_generate_variant:Nn \tl_show:N { c }
+\cs_new_protected:Npn \tl_log:N { \@@_show:NN \tl_log:n }
+\cs_generate_variant:Nn \tl_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_chk_defined:NT #2
+ {
+ \exp_args:Nf \tl_if_empty:nTF
+ { \cs_prefix_spec:N #2 \cs_parameter_spec:N #2 }
+ {
+ \exp_args:Ne #1
+ { \token_to_str:N #2 = \__kernel_exp_not:w \exp_after:wN {#2} }
+ }
+ {
+ \msg_error:nneee { kernel } { bad-type }
+ { \token_to_str:N #2 } { \token_to_meaning:N #2 } { tl }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_show:n, \tl_show:e, \tl_show:x, \@@_show:n}
+% \begin{macro}[EXP]{\@@_show:w}
+% Many |show| functions are based on \cs{tl_show:n}.
+% The argument of \cs{tl_show:n} is line-wrapped using
+% \cs{iow_wrap:nnnN} but with a leading |>~| and trailing period, both
+% removed before passing the wrapped text to the \tn{showtokens}
+% primitive. This primitive shows the result with a leading |>~| and
+% trailing period.
+%
+% The token list \cs{l_@@_internal_a_tl} containing the result
+% of all these manipulations is displayed to the terminal using
+% \cs{tex_showtokens:D} and an odd \cs{exp_after:wN} which expand the
+% closing brace to improve the output slightly. The calls to
+% \cs{__kernel_iow_with:Nnn} ensure that the \tn{newlinechar} is set to~$10$
+% so that the \cs{iow_newline:} inserted by the line-wrapping code
+% are correctly recognized by \TeX{}, and that \tn{errorcontextlines}
+% is $-1$ to avoid printing irrelevant context.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_show:n #1
+ { \iow_wrap:nnnN { >~ \tl_to_str:n {#1} . } { } { } \@@_show:n }
+\cs_generate_variant:Nn \tl_show:n { e , x }
+\cs_new_protected:Npn \@@_show:n #1
+ {
+ \tl_set:Nf \l_@@_internal_a_tl { \@@_show:w #1 \s_@@_stop }
+ \__kernel_iow_with:Nnn \tex_newlinechar:D { 10 }
+ {
+ \__kernel_iow_with:Nnn \tex_errorcontextlines:D { -1 }
+ {
+ \tex_showtokens:D \exp_after:wN \exp_after:wN \exp_after:wN
+ { \exp_after:wN \l_@@_internal_a_tl }
+ }
+ }
+ }
+\cs_new:Npn \@@_show:w #1 > #2 . \s_@@_stop {#2}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_log:n, \tl_log:e, \tl_log:x}
+% Logging is much easier, simply line-wrap. The |>~| and trailing
+% period is there to match the output of \cs{tl_show:n}.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_log:n #1
+ { \iow_wrap:nnnN { > ~ \tl_to_str:n {#1} . } { } { } \iow_log:n }
+\cs_generate_variant:Nn \tl_log:n { e , x }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_chk_tl_type:NnnT}
+% Helper for checking that |#1| has the correct internal structure to
+% be of a certain type. Make sure that it is defined and that it is a
+% token list, namely a macro with no \tn{long} nor \tn{protected}
+% prefix. Then compare |#1| to an attempt at reconstructing a valid
+% structure of the given type using |#2| (see implementation of
+% \cs{seq_show:N} for instance). If that is successful run the
+% requested code~|#4|.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_chk_tl_type:NnnT #1#2#3#4
+ {
+ \__kernel_chk_defined:NT #1
+ {
+ \exp_args:Nf \tl_if_empty:nTF
+ { \cs_prefix_spec:N #1 \cs_parameter_spec:N #1 }
+ {
+ \tl_set:Ne \l_@@_internal_a_tl {#3}
+ \tl_if_eq:NNTF #1 \l_@@_internal_a_tl
+ {#4}
+ {
+ \msg_error:nneeee { kernel } { bad-type }
+ { \token_to_str:N #1 } { \tl_to_str:N #1 }
+ {#2} { \tl_to_str:N \l_@@_internal_a_tl }
+ }
+ }
+ {
+ \msg_error:nneee { kernel } { bad-type }
+ { \token_to_str:N #1 } { \token_to_meaning:N #1 } {#2}
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Internal scan marks}
+%
+% \begin{variable}{\s_@@_nil,\s_@@_mark,\s_@@_stop}
+% Internal scan marks. These are defined here at the end because the
+% code for \cs{scan_new:N} depends on some \pkg{l3tl} functions.
+% \begin{macrocode}
+\scan_new:N \s_@@_nil
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Scratch token lists}
+%
+% \begin{variable}{\g_tmpa_tl, \g_tmpb_tl}
+% Global temporary token list variables.
+% They are supposed to be set and used immediately,
+% with no delay between the definition and the use because you
+% can't count on other macros not to redefine them from under you.
+% \begin{macrocode}
+\tl_new:N \g_tmpa_tl
+\tl_new:N \g_tmpb_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_tmpa_tl, \l_tmpb_tl}
+% These are local temporary token list variables. Be sure not to assume
+% that the value you put into them will survive for
+% long---see discussion above.
+% \begin{macrocode}
+\tl_new:N \l_tmpa_tl
+\tl_new:N \l_tmpb_tl
+% \end{macrocode}
+% \end{variable}
+%
+% We finally clean up a temporary control sequence that we have used at
+% various points to set up some definitions.
+% \begin{macrocode}
+\cs_undefine:N \@@_tmp:w
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3token.dtx b/macros/latex-dev/required/l3kernel/l3token.dtx
new file mode 100644
index 0000000000..a38860b548
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3token.dtx
@@ -0,0 +1,2936 @@
+% \iffalse meta-comment
+%
+%% File: l3token.dtx
+%
+% Copyright (C) 2005-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3token} module\\ Token manipulation^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% This module deals with tokens. Now this is perhaps not the most
+% precise description so let's try with a better description: When
+% programming in \TeX{}, it is often desirable to know just what a
+% certain token is: is it a control sequence or something
+% else. Similarly one often needs to know if a control sequence is
+% expandable or not, a macro or a primitive, how many arguments it
+% takes etc. Another thing of great importance (especially when it
+% comes to document commands) is looking ahead in the token stream to
+% see if a certain character is present and maybe even remove it or
+% disregard other tokens while scanning. This module provides
+% functions for both and as such has two primary function
+% categories: |\token_| for anything that deals with tokens and
+% |\peek_| for looking ahead in the token stream.
+%
+% Most functions we describe here can be used on control sequences,
+% as those are tokens as well.
+%
+% It is important to distinguish two aspects of a token: its
+% \enquote{shape} (for lack of a better word), which affects the
+% matching of delimited arguments and the comparison of token lists
+% containing this token, and its \enquote{meaning}, which affects
+% whether the token expands or what operation it performs. One can have
+% tokens of different shapes with the same meaning, but not the
+% converse.
+%
+% For instance, \cs{if:w}, \cs{if_charcode:w}, and \cs[no-index]{tex_if:D} are
+% three names for the same internal operation of \TeX{}, namely the
+% primitive testing the next two characters for equality of their
+% character code. They have the same meaning hence behave identically
+% in many situations. However, \TeX{} distinguishes them when searching
+% for a delimited argument. Namely, the example function
+% |\show_until_if:w| defined below takes everything until \cs{if:w}
+% as an argument, despite the presence of other copies of \cs{if:w}
+% under different names.
+% \begin{verbatim}
+% \cs_new:Npn \show_until_if:w #1 \if:w { \tl_show:n {#1} }
+% \show_until_if:w \tex_if:D \if_charcode:w \if:w
+% \end{verbatim}
+% A list of all possible shapes and a list of all possible meanings are
+% given in section~\ref{sec:l3token:all-tokens}.
+%
+% \section{Creating character tokens}
+%
+% \begin{function}[updated = 2015-11-12]
+% {
+% \char_set_active_eq:NN, \char_set_active_eq:Nc,
+% \char_gset_active_eq:NN, \char_gset_active_eq:Nc
+% }
+% \begin{syntax}
+% \cs{char_set_active_eq:NN} \meta{char} \meta{function}
+% \end{syntax}
+% Sets the behaviour of the \meta{char} in situations where it is
+% active (category code $13$) to be equivalent to that of the
+% definition of the \meta{function} at the time \cs{char_set_active_eq:NN}
+% is used. The category code of the \meta{char} is
+% \emph{unchanged} by this process. The \meta{function} may itself
+% be an active character.
+% \end{function}
+%
+% \begin{function}[added = 2015-11-12]
+% {
+% \char_set_active_eq:nN, \char_set_active_eq:nc,
+% \char_gset_active_eq:nN, \char_gset_active_eq:nc
+% }
+% \begin{syntax}
+% \cs{char_set_active_eq:nN} \Arg{integer expression} \meta{function}
+% \end{syntax}
+% Sets the behaviour of the \meta{char} which has character
+% code as given by the \meta{integer expression} in situations
+% where it is active (category code $13$) to be equivalent to that of the
+% \meta{function} at the time \cs{char_set_active_eq:nN}
+% is used. The category code of the \meta{char} is
+% \emph{unchanged} by this process. The \meta{function} may itself
+% be an active character.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2015-09-09, updated = 2019-01-16]
+% {\char_generate:nn}
+% \begin{syntax}
+% \cs{char_generate:nn} \Arg{charcode} \Arg{catcode}
+% \end{syntax}
+% Generates a character token of the given \meta{charcode} and \meta{catcode}
+% (both of which may be integer expressions). The \meta{catcode} may be
+% one of
+% \begin{itemize}
+% \item $1$ (begin group)
+% \item $2$ (end group)
+% \item $3$ (math toggle)
+% \item $4$ (alignment)
+% \item $6$ (parameter)
+% \item $7$ (math superscript)
+% \item $8$ (math subscript)
+% \item $10$ (space)
+% \item $11$ (letter)
+% \item $12$ (other)
+% \item $13$ (active)
+% \end{itemize}
+% and other values raise an error. The \meta{charcode} may be any one valid
+% for the engine in use, except that for \meta{catcode} $10$, \meta{charcode}
+% $0$ is not allowed.
+% Active characters cannot be generated in older versions of \XeTeX{}.
+% Another way to build token lists with unusual category codes is
+% \cs{regex_replace:nnN} |{.*}| \Arg{replacement} \meta{tl~var}.
+% \begin{texnote}
+% Exactly two expansions are needed to produce the character.
+% \end{texnote}
+% \end{function}
+%
+% \begin{variable}[added = 2017-08-07]{\c_catcode_active_space_tl}
+% Token list containing one character with category code $13$,
+% (\enquote{active}), and character code $32$ (space).
+% \end{variable}
+%
+% \begin{variable}[added = 2011-09-05]{\c_catcode_other_space_tl}
+% Token list containing one character with category code $12$,
+% (\enquote{other}), and character code $32$ (space).
+% \end{variable}
+%
+% \section{Manipulating and interrogating character tokens}
+%
+% \begin{function}[updated = 2015-11-11]
+% {
+% \char_set_catcode_escape:N ,
+% \char_set_catcode_group_begin:N ,
+% \char_set_catcode_group_end:N ,
+% \char_set_catcode_math_toggle:N ,
+% \char_set_catcode_alignment:N ,
+% \char_set_catcode_end_line:N ,
+% \char_set_catcode_parameter:N ,
+% \char_set_catcode_math_superscript:N ,
+% \char_set_catcode_math_subscript:N ,
+% \char_set_catcode_ignore:N ,
+% \char_set_catcode_space:N ,
+% \char_set_catcode_letter:N ,
+% \char_set_catcode_other:N ,
+% \char_set_catcode_active:N ,
+% \char_set_catcode_comment:N ,
+% \char_set_catcode_invalid:N
+% }
+% \begin{syntax}
+% \cs{char_set_catcode_letter:N} \meta{character}
+% \end{syntax}
+% Sets the category code of the \meta{character} to that indicated in
+% the function name. Depending on the current category code of the
+% \meta{token} the escape token may also be needed:
+% \begin{verbatim}
+% \char_set_catcode_other:N \%
+% \end{verbatim}
+% The assignment is local.
+% \end{function}
+%
+% \begin{function}[updated = 2015-11-11]
+% {
+% \char_set_catcode_escape:n ,
+% \char_set_catcode_group_begin:n ,
+% \char_set_catcode_group_end:n ,
+% \char_set_catcode_math_toggle:n ,
+% \char_set_catcode_alignment:n ,
+% \char_set_catcode_end_line:n ,
+% \char_set_catcode_parameter:n ,
+% \char_set_catcode_math_superscript:n ,
+% \char_set_catcode_math_subscript:n ,
+% \char_set_catcode_ignore:n ,
+% \char_set_catcode_space:n ,
+% \char_set_catcode_letter:n ,
+% \char_set_catcode_other:n ,
+% \char_set_catcode_active:n ,
+% \char_set_catcode_comment:n ,
+% \char_set_catcode_invalid:n
+% }
+% \begin{syntax}
+% \cs{char_set_catcode_letter:n} \Arg{integer expression}
+% \end{syntax}
+% Sets the category code of the \meta{character} which has character
+% code as given by the \meta{integer expression}. This version can be
+% used to set up characters which cannot otherwise be given
+% (\emph{cf.}~the \texttt{N}-type variants). The assignment is local.
+% \end{function}
+%
+% \begin{function}[updated = 2015-11-11]{\char_set_catcode:nn}
+% \begin{syntax}
+% \cs{char_set_catcode:nn} \Arg{int expr_1} \Arg{int expr_2}
+% \end{syntax}
+% These functions set the category code of the \meta{character} which
+% has character code as given by the \meta{integer expression}.
+% The first \meta{integer expression}
+% is the character code and the second is the category code to apply.
+% The setting applies within the current \TeX{} group. In general, the
+% symbolic functions \cs[no-index]{char_set_catcode_\meta{type}} should be preferred,
+% but there are cases where these lower-level functions may be useful.
+% \end{function}
+%
+% \begin{function}[EXP]{\char_value_catcode:n}
+% \begin{syntax}
+% \cs{char_value_catcode:n} \Arg{integer expression}
+% \end{syntax}
+% Expands to the current category code of the \meta{character} with
+% character code given by the
+% \meta{integer expression}.
+% \end{function}
+%
+% \begin{function}{\char_show_value_catcode:n}
+% \begin{syntax}
+% \cs{char_show_value_catcode:n} \Arg{integer expression}
+% \end{syntax}
+% Displays the current category code of the \meta{character} with
+% character code given by the \meta{integer expression} on the
+% terminal.
+% \end{function}
+%
+% \begin{function}[updated = 2015-08-06]{\char_set_lccode:nn}
+% \begin{syntax}
+% \cs{char_set_lccode:nn} \Arg{int expr_1} \Arg{int expr_2}
+% \end{syntax}
+% Sets up the behaviour of the \meta{character} when
+% found inside \cs{text_lowercase:n}, such that \meta{character_1}
+% will be converted into \meta{character_2}. The two \meta{characters}
+% may be specified using an \meta{integer expression} for the character code
+% concerned. This may include the \TeX{} |`|\meta{character}
+% method for converting a single character into its character
+% code:
+% \begin{verbatim}
+% \char_set_lccode:nn { `\A } { `\a } % Standard behaviour
+% \char_set_lccode:nn { `\A } { `\A + 32 }
+% \char_set_lccode:nn { 50 } { 60 }
+% \end{verbatim}
+% The setting applies within the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}[EXP]{\char_value_lccode:n}
+% \begin{syntax}
+% \cs{char_value_lccode:n} \Arg{integer expression}
+% \end{syntax}
+% Expands to the current lower case code of the \meta{character} with
+% character code given by the
+% \meta{integer expression}.
+% \end{function}
+%
+% \begin{function}{\char_show_value_lccode:n}
+% \begin{syntax}
+% \cs{char_show_value_lccode:n} \Arg{integer expression}
+% \end{syntax}
+% Displays the current lower case code of the \meta{character} with
+% character code given by the \meta{integer expression} on the
+% terminal.
+% \end{function}
+%
+% \begin{function}[updated = 2015-08-06]{\char_set_uccode:nn}
+% \begin{syntax}
+% \cs{char_set_uccode:nn} \Arg{int expr_1} \Arg{int expr_2}
+% \end{syntax}
+% Sets up the behaviour of the \meta{character} when
+% found inside \cs{text_uppercase:n}, such that \meta{character_1}
+% will be converted into \meta{character_2}. The two \meta{characters}
+% may be specified using an \meta{integer expression} for the character code
+% concerned. This may include the \TeX{} |`|\meta{character}
+% method for converting a single character into its character
+% code:
+% \begin{verbatim}
+% \char_set_uccode:nn { `\a } { `\A } % Standard behaviour
+% \char_set_uccode:nn { `\A } { `\A - 32 }
+% \char_set_uccode:nn { 60 } { 50 }
+% \end{verbatim}
+% The setting applies within the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}[EXP]{\char_value_uccode:n}
+% \begin{syntax}
+% \cs{char_value_uccode:n} \Arg{integer expression}
+% \end{syntax}
+% Expands to the current upper case code of the \meta{character} with
+% character code given by the
+% \meta{integer expression}.
+% \end{function}
+%
+% \begin{function}{\char_show_value_uccode:n}
+% \begin{syntax}
+% \cs{char_show_value_uccode:n} \Arg{integer expression}
+% \end{syntax}
+% Displays the current upper case code of the \meta{character} with
+% character code given by the \meta{integer expression} on the
+% terminal.
+% \end{function}
+%
+% \begin{function}[updated = 2015-08-06]{\char_set_mathcode:nn}
+% \begin{syntax}
+% \cs{char_set_mathcode:nn} \Arg{int expr_1} \Arg{int expr_2}
+% \end{syntax}
+% This function sets up the math code of \meta{character}.
+% The \meta{character} is specified as
+% an \meta{integer expression} which will be used as the character
+% code of the relevant character. The setting applies within the
+% current \TeX{} group.
+% \end{function}
+%
+% \begin{function}[EXP]{\char_value_mathcode:n}
+% \begin{syntax}
+% \cs{char_value_mathcode:n} \Arg{integer expression}
+% \end{syntax}
+% Expands to the current math code of the \meta{character} with
+% character code given by the
+% \meta{integer expression}.
+% \end{function}
+%
+% \begin{function}{\char_show_value_mathcode:n}
+% \begin{syntax}
+% \cs{char_show_value_mathcode:n} \Arg{integer expression}
+% \end{syntax}
+% Displays the current math code of the \meta{character} with
+% character code given by the \meta{integer expression} on the
+% terminal.
+% \end{function}
+%
+% \begin{function}[updated = 2015-08-06]{\char_set_sfcode:nn}
+% \begin{syntax}
+% \cs{char_set_sfcode:nn} \Arg{int expr_1} \Arg{int expr_2}
+% \end{syntax}
+% This function sets up the space factor for the \meta{character}.
+% The \meta{character} is specified as
+% an \meta{integer expression} which will be used as the character
+% code of the relevant character. The setting applies within the
+% current \TeX{} group.
+% \end{function}
+%
+% \begin{function}[EXP]{\char_value_sfcode:n}
+% \begin{syntax}
+% \cs{char_value_sfcode:n} \Arg{integer expression}
+% \end{syntax}
+% Expands to the current space factor for the \meta{character} with
+% character code given by the
+% \meta{integer expression}.
+% \end{function}
+%
+% \begin{function}{\char_show_value_sfcode:n}
+% \begin{syntax}
+% \cs{char_show_value_sfcode:n} \Arg{integer expression}
+% \end{syntax}
+% Displays the current space factor for the \meta{character} with
+% character code given by the \meta{integer expression} on the
+% terminal.
+% \end{function}
+%
+% \begin{variable}[added = 2012-01-23, updated = 2015-11-11]{\l_char_active_seq}
+% Used to track which tokens may require special handling at the document
+% level as they are (or have been at some point)
+% of category \meta{active} (catcode~$13$). Each entry in
+% the sequence consists of a single escaped token, for example |\~|.
+% Active tokens should be added to the sequence when they are defined for
+% general document use.
+% \end{variable}
+%
+% \begin{variable}[added = 2012-01-23, updated = 2015-11-11]{\l_char_special_seq}
+% Used to track which tokens will require special handling when working with
+% verbatim-like material at the document level as they are not of categories
+% \meta{letter} (catcode~$11$) or \meta{other} (catcode~$12$). Each entry in
+% the sequence consists of a single escaped token, for example |\\| for the
+% backslash or |\{| for an opening brace. ^^A \}
+% Escaped tokens should be added to the sequence when they are defined for
+% general document use.
+% \end{variable}
+%
+% \section{Generic tokens}
+%
+% \begin{variable}[module = token]
+% {
+% \c_group_begin_token,
+% \c_group_end_token,
+% \c_math_toggle_token,
+% \c_alignment_token,
+% \c_parameter_token,
+% \c_math_superscript_token,
+% \c_math_subscript_token,
+% \c_space_token
+% }
+% These are implicit tokens which have the category code described
+% by their name. They are used internally for test purposes but
+% are also available to the programmer for other uses.
+% \begin{texnote}
+% The tokens \cs{c_group_begin_token}, \cs{c_group_end_token}, and
+% \cs{c_space_token} are \pkg{expl3} counterparts of \LaTeXe{}'s
+% \tn{bgroup}, \tn{egroup}, and \cs{@sptoken}.
+% \end{texnote}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \c_catcode_letter_token,
+% \c_catcode_other_token
+% }
+% These are implicit tokens which have the category code described
+% by their name. They are used internally for test purposes and should
+% not be used other than for category code tests.
+% \end{variable}
+%
+% \begin{variable}{\c_catcode_active_tl}
+% A token list containing an active token. This is used internally
+% for test purposes and should not be used other than in
+% appropriately-constructed category code tests.
+% \end{variable}
+%
+% \section{Converting tokens}
+%
+% \begin{function}[EXP]{\token_to_meaning:N, \token_to_meaning:c}
+% \begin{syntax}
+% \cs{token_to_meaning:N} \meta{token}
+% \end{syntax}
+% Inserts the current meaning of the \meta{token} into the input
+% stream as a series of characters of category code $12$ (other).
+% This is the primitive \TeX{} description of the \meta{token},
+% thus for example both functions defined by \cs{cs_set_nopar:Npn}
+% and token list variables defined using \cs{tl_new:N} are described
+% as |macro|s.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{meaning}.
+% The \meta{token} can thus be an explicit space token or an
+% explicit begin-group or end-group character token (|{|~or~|}| when
+% normal \TeX{} category codes apply) even though these are not
+% valid \texttt{N}-type arguments.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\token_to_str:N, \token_to_str:c}
+% \begin{syntax}
+% \cs{token_to_str:N} \meta{token}
+% \end{syntax}
+% Converts the given \meta{token} into a series of characters with
+% category code $12$ (other). If the \meta{token} is a control
+% sequence, this will start with the current escape character with
+% category code $12$ (the escape character is part of the
+% \meta{token}). This function requires only a single expansion.
+% \begin{texnote}
+% \cs{token_to_str:N} is the \TeX{} primitive \tn{string}.
+% The \meta{token} can thus be an explicit space tokens or an
+% explicit begin-group or end-group character token (|{|~or~|}| when
+% normal \TeX{} category codes apply) even though these are not
+% valid \texttt{N}-type arguments.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP,added = 2023-10-15]{\token_to_catcode:N}
+% \begin{syntax}
+% \cs{token_to_catcode:N} \meta{token}
+% \end{syntax}
+% Converts the given \meta{token} into a number describing its category code.
+% If \meta{token} is a control sequence this expands to $16$. This can't
+% detect the categories $0$ (escape character), $5$ (end of line), $9$
+% (ignored character), $14$ (comment character), or $15$ (invalid character).
+% Control sequences or active characters let to a token of one of the
+% detectable category codes will yield that category.
+% \end{function}
+%
+% \section{Token conditionals}
+%
+% \begin{function}[EXP,pTF]{\token_if_group_begin:N}
+% \begin{syntax}
+% \cs{token_if_group_begin_p:N} \meta{token} \\
+% \cs{token_if_group_begin:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of a begin group token
+% (|{| when normal \TeX{} category codes are in ^^A }
+% force).
+% Note that an explicit begin group token cannot be tested in this way,
+% as it is not a valid \texttt{N}-type argument.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_group_end:N}
+% \begin{syntax}
+% \cs{token_if_group_end_p:N} \meta{token} \\
+% \cs{token_if_group_end:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of an end group token
+% (^^A {
+% |}| when normal \TeX{} category codes are in force).
+% Note that an explicit end group token cannot be tested in this way,
+% as it is not a valid \texttt{N}-type argument.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_math_toggle:N}
+% \begin{syntax}
+% \cs{token_if_math_toggle_p:N} \meta{token} \\
+% \cs{token_if_math_toggle:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of a math shift token
+% (|$| when normal \TeX{} category codes are in force).
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_alignment:N}
+% \begin{syntax}
+% \cs{token_if_alignment_p:N} \meta{token} \\
+% \cs{token_if_alignment:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of an alignment token
+% (|&| when normal \TeX{} category codes are in force).
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_parameter:N}
+% \begin{syntax}
+% \cs{token_if_parameter_p:N} \meta{token} \\
+% \cs{token_if_parameter:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of a macro parameter token
+% (|#| when normal \TeX{} category codes are in force).
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_math_superscript:N}
+% \begin{syntax}
+% \cs{token_if_math_superscript_p:N} \meta{token} \\
+% \cs{token_if_math_superscript:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of a superscript token
+% (|^| when normal \TeX{} category codes are in force).
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_math_subscript:N}
+% \begin{syntax}
+% \cs{token_if_math_subscript_p:N} \meta{token} \\
+% \cs{token_if_math_subscript:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of a subscript token
+% (|_| when normal \TeX{} category codes are in force).
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_space:N}
+% \begin{syntax}
+% \cs{token_if_space_p:N} \meta{token} \\
+% \cs{token_if_space:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of a space token.
+% Note that an explicit space token with character code $32$ cannot
+% be tested in this way, as it is not a valid \texttt{N}-type argument.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_letter:N}
+% \begin{syntax}
+% \cs{token_if_letter_p:N} \meta{token} \\
+% \cs{token_if_letter:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of a letter token.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_other:N}
+% \begin{syntax}
+% \cs{token_if_other_p:N} \meta{token} \\
+% \cs{token_if_other:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of an \enquote{other}
+% token.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_active:N}
+% \begin{syntax}
+% \cs{token_if_active_p:N} \meta{token} \\
+% \cs{token_if_active:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of an active character.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_eq_catcode:NN}
+% \begin{syntax}
+% \cs{token_if_eq_catcode_p:NN} \meta{token_1} \meta{token_2} \\
+% \cs{token_if_eq_catcode:NNTF} \meta{token_1} \meta{token_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the two \meta{tokens} have the same category code.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_eq_charcode:NN}
+% \begin{syntax}
+% \cs{token_if_eq_charcode_p:NN} \meta{token_1} \meta{token_2} \\
+% \cs{token_if_eq_charcode:NNTF} \meta{token_1} \meta{token_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the two \meta{tokens} have the same character code.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_eq_meaning:NN}
+% \begin{syntax}
+% \cs{token_if_eq_meaning_p:NN} \meta{token_1} \meta{token_2} \\
+% \cs{token_if_eq_meaning:NNTF} \meta{token_1} \meta{token_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the two \meta{tokens} have the same meaning when expanded.
+% \end{function}
+%
+% \begin{function}[updated = 2011-05-23, EXP,pTF]{\token_if_macro:N}
+% \begin{syntax}
+% \cs{token_if_macro_p:N} \meta{token} \\
+% \cs{token_if_macro:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is a \TeX{} macro.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_cs:N}
+% \begin{syntax}
+% \cs{token_if_cs_p:N} \meta{token} \\
+% \cs{token_if_cs:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is a control sequence.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_expandable:N}
+% \begin{syntax}
+% \cs{token_if_expandable_p:N} \meta{token} \\
+% \cs{token_if_expandable:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is expandable. This test returns \meta{false}
+% for an undefined token.
+% \end{function}
+%
+% \begin{function}[EXP,pTF, updated=2012-01-20]{\token_if_long_macro:N}
+% \begin{syntax}
+% \cs{token_if_long_macro_p:N} \meta{token} \\
+% \cs{token_if_long_macro:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is a long macro.
+% \end{function}
+%
+% \begin{function}[EXP,pTF, updated=2012-01-20]{\token_if_protected_macro:N}
+% \begin{syntax}
+% \cs{token_if_protected_macro_p:N} \meta{token} \\
+% \cs{token_if_protected_macro:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is a protected macro: for a macro which
+% is both protected and long this returns \texttt{false}.
+% \end{function}
+%
+% \begin{function}[EXP,pTF, updated=2012-01-20]{\token_if_protected_long_macro:N}
+% \begin{syntax}
+% \cs{token_if_protected_long_macro_p:N} \meta{token} \\
+% \cs{token_if_protected_long_macro:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is a protected long macro.
+% \end{function}
+%
+% \begin{function}[EXP,pTF, updated=2012-01-20]{\token_if_chardef:N}
+% \begin{syntax}
+% \cs{token_if_chardef_p:N} \meta{token} \\
+% \cs{token_if_chardef:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is defined to be a chardef.
+% \begin{texnote}
+% Booleans, boxes and small integer constants are implemented as
+% \tn{chardef}s.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP,pTF, updated=2012-01-20]{\token_if_mathchardef:N}
+% \begin{syntax}
+% \cs{token_if_mathchardef_p:N} \meta{token} \\
+% \cs{token_if_mathchardef:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is defined to be a mathchardef.
+% \end{function}
+%
+% \begin{function}[EXP,pTF, added=2020-10-27]{\token_if_font_selection:N}
+% \begin{syntax}
+% \cs{token_if_font_selection_p:N} \meta{token} \\
+% \cs{token_if_font_selection:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is defined to be a font selection command.
+% \end{function}
+%
+% \begin{function}[EXP,pTF, updated=2012-01-20]{\token_if_dim_register:N}
+% \begin{syntax}
+% \cs{token_if_dim_register_p:N} \meta{token} \\
+% \cs{token_if_dim_register:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is defined to be a dimension register.
+% \end{function}
+%
+% \begin{function}[EXP,pTF, updated=2012-01-20]{\token_if_int_register:N}
+% \begin{syntax}
+% \cs{token_if_int_register_p:N} \meta{token} \\
+% \cs{token_if_int_register:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is defined to be a integer register.
+% \begin{texnote}
+% Constant integers may be implemented as integer registers,
+% \tn{chardef}s, or \tn{mathchardef}s depending on their value.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP,pTF, added=2012-02-15]{\token_if_muskip_register:N}
+% \begin{syntax}
+% \cs{token_if_muskip_register_p:N} \meta{token} \\
+% \cs{token_if_muskip_register:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is defined to be a muskip register.
+% \end{function}
+%
+% \begin{function}[EXP,pTF, updated=2012-01-20]{\token_if_skip_register:N}
+% \begin{syntax}
+% \cs{token_if_skip_register_p:N} \meta{token} \\
+% \cs{token_if_skip_register:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is defined to be a skip register.
+% \end{function}
+%
+% \begin{function}[EXP,pTF, updated=2012-01-20]{\token_if_toks_register:N}
+% \begin{syntax}
+% \cs{token_if_toks_register_p:N} \meta{token} \\
+% \cs{token_if_toks_register:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is defined to be a toks register
+% (not used by \LaTeX3).
+% \end{function}
+%
+% \begin{function}[updated = 2020-09-11, EXP,pTF]{\token_if_primitive:N}
+% \begin{syntax}
+% \cs{token_if_primitive_p:N} \meta{token} \\
+% \cs{token_if_primitive:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is an engine primitive. In \LuaTeX{}
+% this includes primitive-like commands defined using |token.set_lua|.
+% \end{function}
+%
+% \begin{function}[added = 2020-12-03, EXP, noTF]
+% {\token_case_catcode:Nn, \token_case_charcode:Nn, \token_case_meaning:Nn}
+% \begin{syntax}
+% \cs{token_case_meaning:NnTF} \meta{test token} \\
+% ~~"{" \\
+% ~~~~\meta{token case_1} \Arg{code case_1} \\
+% ~~~~\meta{token case_2} \Arg{code case_2} \\
+% ~~~~\ldots \\
+% ~~~~\meta{token case_n} \Arg{code case_n} \\
+% ~~"}" \\
+% ~~\Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% This function compares the \meta{test token} in turn with each of
+% the \meta{token cases}. If the two are equal (as described for
+% \cs{token_if_eq_catcode:NNTF}, \cs{token_if_eq_charcode:NNTF} and
+% \cs{token_if_eq_meaning:NNTF}, respectively) then the associated
+% \meta{code} is left in the input stream and other cases are
+% discarded. If any of the cases are matched, the \meta{true code} is
+% also inserted into the input stream (after the code for the
+% appropriate case), while if none match then the \meta{false code} is
+% inserted. The functions \cs{token_case_catcode:Nn},
+% \cs{token_case_charcode:Nn}, and \cs{token_case_meaning:Nn}, which
+% do nothing if there is no match, are also available.
+% \end{function}
+%
+% \section{Peeking ahead at the next token}
+%
+% There is often a need to look ahead at the next token in the input
+% stream while leaving it in place. This is handled using the
+% \enquote{peek} functions. The generic \cs{peek_after:Nw} is provided
+% along with a family of predefined tests for common cases. Peeking
+% ahead does \emph{not} skip spaces: rather, \cs{peek_remove_spaces:n}.
+% should be used. In addition, using \cs{peek_analysis_map_inline:n},
+% one can map through the following tokens in the input stream and
+% repeatedly perform some tests.
+%
+% \begin{function}{\peek_after:Nw}
+% \begin{syntax}
+% \cs{peek_after:Nw} \meta{function} \meta{token}
+% \end{syntax}
+% Locally sets the test variable \cs{l_peek_token} equal to \meta{token}
+% (as an implicit token, \emph{not} as a token list), and then
+% expands the \meta{function}. The \meta{token} remains in
+% the input stream as the next item after the \meta{function}.
+% The \meta{token} here may be \verb*| |, |{| or |}| (assuming
+% normal \TeX{} category codes), \emph{i.e.}~it is not necessarily the
+% next argument which would be grabbed by a normal function.
+% \end{function}
+%
+% \begin{function}{\peek_gafter:Nw}
+% \begin{syntax}
+% \cs{peek_gafter:Nw} \meta{function} \meta{token}
+% \end{syntax}
+% Globally sets the test variable \cs{g_peek_token} equal to \meta{token}
+% (as an implicit token, \emph{not} as a token list), and then
+% expands the \meta{function}. The \meta{token} remains in
+% the input stream as the next item after the \meta{function}.
+% The \meta{token} here may be \verb*| |, |{| or |}| (assuming
+% normal \TeX{} category codes), \emph{i.e.}~it is not necessarily the
+% next argument which would be grabbed by a normal function.
+% \end{function}
+%
+% \begin{variable}{\l_peek_token}
+% Token set by \cs{peek_after:Nw} and available for testing
+% as described above.
+% \end{variable}
+%
+% \begin{variable}{\g_peek_token}
+% Token set by \cs{peek_gafter:Nw} and available for testing
+% as described above.
+% \end{variable}
+%
+% \begin{function}[updated = 2012-12-20, TF]{\peek_catcode:N}
+% \begin{syntax}
+% \cs{peek_catcode:NTF} \meta{test token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% category code as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_catcode:NNTF}). Spaces are respected by the test
+% and the \meta{token} is left in the input stream after
+% the \meta{true code} or \meta{false code} (as appropriate to the
+% result of the test).
+% \end{function}
+%
+% \begin{function}[updated = 2012-12-20, TF]{\peek_catcode_remove:N}
+% \begin{syntax}
+% \cs{peek_catcode_remove:NTF} \meta{test token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% category code as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_catcode:NNTF}). Spaces are respected by the test
+% and the \meta{token} is removed from the input stream if the
+% test is true. The function then places either the
+% \meta{true code} or \meta{false code} in the input stream (as
+% appropriate to the result of the test).
+% \end{function}
+%
+% \begin{function}[updated = 2012-12-20, TF]{\peek_charcode:N}
+% \begin{syntax}
+% \cs{peek_charcode:NTF} \meta{test token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% character code as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_charcode:NNTF}). Spaces are respected by the test
+% and the \meta{token} is left in the input stream after
+% the \meta{true code} or \meta{false code} (as appropriate to the
+% result of the test).
+% \end{function}
+%
+% \begin{function}[updated = 2012-12-20, TF]{\peek_charcode_remove:N}
+% \begin{syntax}
+% \cs{peek_charcode_remove:NTF} \meta{test token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% character code as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_charcode:NNTF}). Spaces are respected by the test
+% and the \meta{token} is removed from the input stream if the
+% test is true. The function then places either the
+% \meta{true code} or \meta{false code} in the input stream (as
+% appropriate to the result of the test).
+% \end{function}
+%
+% \begin{function}[updated = 2011-07-02, TF]{\peek_meaning:N}
+% \begin{syntax}
+% \cs{peek_meaning:NTF} \meta{test token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% meaning as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_meaning:NNTF}). Spaces are respected by the test
+% and the \meta{token} is left in the input stream after
+% the \meta{true code} or \meta{false code} (as appropriate to the
+% result of the test).
+% \end{function}
+%
+% \begin{function}[updated = 2011-07-02, TF]{\peek_meaning_remove:N}
+% \begin{syntax}
+% \cs{peek_meaning_remove:NTF} \meta{test token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% meaning as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_meaning:NNTF}). Spaces are respected by the test
+% and the \meta{token} is removed from the input stream if the
+% test is true. The function then places either the
+% \meta{true code} or \meta{false code} in the input stream (as
+% appropriate to the result of the test).
+% \end{function}
+%
+% \begin{function}[added = 2018-10-01]{\peek_remove_spaces:n}
+% \begin{syntax}
+% \cs{peek_remove_spaces:n} \Arg{code}
+% \end{syntax}
+% Peeks ahead and detect if the following token is a space (category code
+% $10$ and character code $32$). If so, removes the token and checks the
+% next token. Once a non-space token is found, the \meta{code} will be
+% inserted into the input stream. Typically this will contain a \texttt{peek}
+% operation, but this is not required.
+% \end{function}
+%
+% \begin{function}[added = 2022-01-10]{\peek_remove_filler:n}
+% \begin{syntax}
+% \cs{peek_remove_filler:n} \Arg{code}
+% \end{syntax}
+% Peeks ahead and detect if the following token is a space (category code
+% $10$) or has meaning equal to \cs{scan_stop:}. If so,
+% removes the token and checks the next token. If neither of these cases
+% apply, expands the next token using \texttt{f}-type expansion, then checks
+% the resulting leading token in the same way. If after expansion the next
+% token is neither of the two test cases, the \meta{code} will be inserted
+% into the input stream. Typically this will contain a \texttt{peek}
+% operation, but this is not required.
+% \begin{texnote}
+% This is essentially a macro-based implementation of how \TeX{} handles
+% the search for a left brace after for example \tn{everypar}, except that
+% any non-expandable token cleanly ends the \meta{filler} (i.e.~it does not
+% lead to a \TeX{} error).
+%
+% In contrast to \TeX{}'s filler removal, a construct
+% \verb|\exp_not:N \foo| will be treated in the same way as \verb|\foo|.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[TF, updated = 2012-12-20]{\peek_N_type:}
+% \begin{syntax}
+% \cs{peek_N_type:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream can be safely
+% grabbed as an \texttt{N}-type argument. The test is \meta{false}
+% if the next \meta{token} is either an explicit or implicit
+% begin-group or end-group token (with any character code), or
+% an explicit or implicit space character (with character code $32$
+% and category code $10$), or an outer token (never used in \LaTeX3)
+% and \meta{true} in all other cases.
+% Note that a \meta{true} result ensures that the next \meta{token} is
+% a valid \texttt{N}-type argument. However, if the next \meta{token}
+% is for instance \cs{c_space_token}, the test takes the
+% \meta{false} branch, even though the next \meta{token} is in fact
+% a valid \texttt{N}-type argument. The \meta{token} is left
+% in the input stream after the \meta{true code} or \meta{false code}
+% (as appropriate to the result of the test).
+% \end{function}
+%
+% \begin{function}[added = 2020-12-03, updated = 2024-02-07]
+% {\peek_analysis_map_inline:n}
+% \begin{syntax}
+% \cs{peek_analysis_map_inline:n} \Arg{inline function}
+% \end{syntax}
+% Repeatedly removes one \meta{token} from the input stream and
+% applies the \meta{inline function} to it, until
+% \cs{peek_analysis_map_break:} is called. The \meta{inline function}
+% receives three arguments for each \meta{token} in the input stream:
+% \begin{itemize}
+% \item \meta{tokens}, which both \texttt{o}-expand and
+% \texttt{e}/\texttt{x}-expand to the \meta{token}. The detailed form of
+% \meta{tokens} may change in later releases.
+% \item \meta{char code}, a decimal representation of the character
+% code of the \meta{token}, $-1$ if it is a control sequence.
+% \item \meta{catcode}, a capital hexadecimal digit which denotes the
+% category code of the \meta{token} (0:~control sequence,
+% 1:~begin-group, 2:~end-group, 3:~math shift, 4:~alignment tab,
+% 6:~parameter, 7:~superscript, 8:~subscript, A:~space, B:~letter,
+% C:~other, D:~active). This can be converted to an integer by
+% writing |"|\meta{catcode}.
+% \end{itemize}
+% These arguments are the same as for \cs{tl_analysis_map_inline:nn}
+% defined in \pkg{l3tl-analysis}. The \meta{char code} and
+% \meta{catcode} do not take the meaning of a control sequence or
+% active character into account: for instance, upon encountering the
+% token \cs{c_group_begin_token} in the input stream,
+% \cs{peek_analysis_map_inline:n} calls the \meta{inline function}
+% with |#1| being \cs{exp_not:n} |{| \cs{c_group_begin_token} |}|
+% (with the current implementation),
+% |#2|~being~$-1$, and
+% |#3|~being~$0$, as for any other control sequence. In contrast,
+% upon encountering an explicit begin-group token~|{|, % ^^A |}|
+% the \meta{inline function} is called with arguments
+% \cs{exp_after:wN} |{| \cs{if_false:} |}| \cs{fi:}, $123$ and~$1$.
+%
+% The mapping is done at the current group level, \emph{i.e.}~any
+% local assignments made by the \meta{inline function} remain in
+% effect after the loop. Within the code, \cs{l_peek_token} is set
+% equal (as a token, not a token list) to the token under
+% consideration.
+%
+% Peek functions cannot be used within this mapping function (nor
+% other mapping functions) since the input stream contains trailing
+% material necessary for the functioning of the loop.
+% \begin{texnote}
+% In case the input stream has not yet been tokenized (converted
+% from characters to tokens), characters are tokenized one by one as
+% needed by \cs{peek_analysis_map_inline:n} using the current
+% category code regime.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2020-12-03]
+% {\peek_analysis_map_break:, \peek_analysis_map_break:n}
+% \begin{syntax}
+% \cs{peek_analysis_map_inline:n}
+% |{| \dots{} \cs{peek_analysis_map_break:n} \Arg{code} |}|
+% \end{syntax}
+% Stops the \cs{peek_analysis_map_inline:n} loop from seeking more
+% tokens, and inserts \meta{code} in the input stream (empty for
+% \cs{peek_analysis_map_break:}).
+% \end{function}
+%
+% \begin{function}[added = 2020-12-03, TF]{\peek_regex:n, \peek_regex:N}
+% \begin{syntax}
+% \cs{peek_regex:nTF} \Arg{regex} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{tokens} that follow in the input stream match the
+% \meta{regular expression}. Any \meta{tokens} that have been read
+% are left in the input stream after the \meta{true code} or
+% \meta{false code} (as appropriate to the result of the test). See
+% \pkg{l3regex} for documentation of the syntax of regular
+% expressions. The \meta{regular expression} is implicitly anchored
+% at the start, so for instance \cs{peek_regex:nTF}~|{|~|a|~|}| is
+% essentially equivalent to \cs{peek_charcode:NTF}~|a|.
+% \begin{texnote}
+% Implicit character tokens are correctly considered by
+% \cs{peek_regex:nTF} as control sequences, while functions that
+% inspect individual tokens (for instance \cs{peek_charcode:NTF})
+% only take into account their meaning.
+%
+% The \cs{peek_regex:nTF} function only inspects as few tokens as
+% necessary to determine whether the regular expression matches.
+% For instance \cs{peek_regex:nTF} \verb"{ abc | [a-z] }" |{ } { }|
+% |abc| will only inspect the first token~|a| even though the first
+% branch |abc| of the alternative is preferred in functions such as
+% \cs{peek_regex_remove_once:nTF}. This may have an effect on
+% tokenization if the input stream has not yet been tokenized and
+% category codes are changed.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2020-12-03, TF]
+% {\peek_regex_remove_once:n, \peek_regex_remove_once:N}
+% \begin{syntax}
+% \cs{peek_regex_remove_once:nTF} \Arg{regex} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{tokens} that follow in the input stream match the
+% \meta{regex}. If the test is true, the \meta{tokens} are removed
+% from the input stream and the \meta{true code} is inserted, while if
+% the test is false, the \meta{false code} is inserted followed by the
+% \meta{tokens} that were originally in the input stream.
+% See \pkg{l3regex} for documentation of the syntax of
+% regular expressions. The \meta{regular expression} is implicitly
+% anchored at the start, so for instance
+% \cs{peek_regex_remove_once:nTF}~|{|~|a|~|}| is essentially equivalent to
+% \cs{peek_charcode_remove:NTF}~|a|.
+% \begin{texnote}
+% Implicit character tokens are correctly considered by
+% \cs{peek_regex_remove_once:nTF} as control sequences, while functions
+% that inspect individual tokens (for instance
+% \cs{peek_charcode:NTF}) only take into account their meaning.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2020-12-03, noTF]
+% {\peek_regex_replace_once:nn, \peek_regex_replace_once:Nn}
+% \begin{syntax}
+% \cs{peek_regex_replace_once:nnTF} \Arg{regex} \Arg{replacement} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{tokens} that follow in the input stream match the
+% \meta{regex}, replaces them according to the \meta{replacement} as
+% for \cs{regex_replace_once:nnN}, and leaves the result in the input
+% stream, after the \meta{true code}. Otherwise, leaves \meta{false
+% code} followed by the \meta{tokens} that were originally in the
+% input stream, with no modifications. See \pkg{l3regex} for
+% documentation of the syntax of regular expressions and of the
+% \meta{replacement}: for instance |\0| in the \meta{replacement} is
+% replaced by the tokens that were matched in the input stream. The
+% \meta{regular expression} is implicitly anchored at the start. In
+% contrast to \cs{regex_replace_once:nnN}, no error arises if the
+% \meta{replacement} leads to an unbalanced token list: the tokens are
+% inserted into the input stream without issue.
+% \begin{texnote}
+% Implicit character tokens are correctly considered by
+% \cs{peek_regex_replace_once:nnTF} as control sequences, while
+% functions that inspect individual tokens (for instance
+% \cs{peek_charcode:NTF}) only take into account their meaning.
+% \end{texnote}
+% \end{function}
+%
+% \section{Description of all possible tokens}
+% \label{sec:l3token:all-tokens}
+%
+% Let us end by reviewing every case that a given token can fall into.
+% This section is quite technical and some details are only meant for
+% completeness. We distinguish the meaning of the token, which controls
+% the expansion of the token and its effect on \TeX{}'s state, and its
+% shape, which is used when comparing token lists such as for delimited
+% arguments. Two tokens of the same shape must have the same meaning,
+% but the converse does not hold.
+%
+% A token has one of the following shapes.
+% \begin{itemize}
+% \item A control sequence, characterized by the sequence of
+% characters that constitute its name: for instance, \cs{use:n} is a
+% five-letter control sequence.
+% \item An active character token, characterized by its character code
+% (between $0$ and $1114111$ for \LuaTeX{} and \XeTeX{} and less for
+% other engines) and category code~$13$.
+% \item A character token, characterized by its character code and
+% category code (one of $1$, $2$, $3$, $4$, $6$, $7$, $8$, $10$,
+% $11$ or~$12$ whose meaning is described below).
+% \end{itemize}
+% There are also a few internal tokens. The following list may be
+% incomplete in some engines.
+% \begin{itemize}
+% \item Expanding \tn{the}\tn{font} results in a token that looks
+% identical to the command that was used to select the current font
+% (such as \tn{tenrm}) but it differs from it in shape.
+% \item A \enquote{frozen} |\relax|, which differs from the primitive in
+% shape (but has the same meaning), is inserted when the closing \tn{fi} of a
+% conditional is encountered before the conditional is evaluated.
+% \item Expanding \tn{noexpand} \meta{token} (when the \meta{token} is
+% expandable) results in an internal token, displayed (temporarily)
+% as \cs[module = {}]{notexpanded: \meta{token}}, whose shape coincides with the
+% \meta{token} and whose meaning differs from \tn{relax}.
+% \item An |\outer endtemplate:| can be encountered when peeking ahead
+% at the next token; this expands to another internal token,
+% |end of alignment template|.
+% \item Tricky programming might access a frozen |\endwrite|.
+% \item Some frozen tokens can only be accessed in interactive
+% sessions: |\cr|, |\right|, |\endgroup|, |\fi|, |\inaccessible|.
+% \item In \LuaTeX{}, there is also the strange case of \enquote{bytes}
+% |^^^^^^1100|$xy$ where $x,y$ are any two lowercase hexadecimal
+% digits, so that the hexadecimal number ranges from
+% |"|$11\,0000=1\,114\,112$ to~|"|$110\,0\mathrm{ff}=1\,114\,367$. These are
+% used to output individual bytes to files, rather than UTF-8. For
+% the purposes of token comparisons they behave like non-expandable
+% primitive control sequences (\emph{not characters}) whose
+% \tn{meaning} is \verb*|the character | followed by the given byte.
+% If this byte is in the range |80|--|ff| this gives an ``invalid
+% utf-8 sequence'' error: applying \cs{token_to_str:N} or
+% \cs{token_to_meaning:N} to these tokens is unsafe. Unfortunately,
+% they don't seem to be detectable safely by any means except perhaps
+% Lua code.
+% \end{itemize}
+%
+% The meaning of a (non-active) character token is fixed by its category
+% code (and character code) and cannot be changed. We call these
+% tokens \emph{explicit} character tokens. Category codes that a
+% character token can have are listed below by giving a sample output of
+% the \TeX{} primitive \tn{meaning}, together with their \LaTeX3 names
+% and most common example:
+% \begin{itemize}
+% \item[1] begin-group character (|group_begin|, often |{|),
+% \item[2] end-group character (|group_end|, often |}|),
+% \item[3] math shift character (|math_toggle|, often |$|), %^^A $
+% \item[4] alignment tab character (|alignment|, often |&|),
+% \item[6] macro parameter character (|parameter|, often |#|),
+% \item[7] superscript character (|math_superscript|, often |^|),
+% \item[8] subscript character (|math_subscript|, often |_|),
+% \item[10] blank space (|space|, often character code~$32$),
+% \item[11] the letter (|letter|, such as |A|),
+% \item[12] the character (|other|, such as |0|).
+% \end{itemize}
+% Category code~$13$ (|active|) is discussed below. Input characters
+% can also have several other category codes which do not lead to
+% character tokens for later processing: $0$~(|escape|),
+% $5$~(|end_line|), $9$~(|ignore|), $14$~(|comment|), and
+% $15$~(|invalid|).
+%
+% The meaning of a control sequence or active character can be identical
+% to that of any character token listed above (with any character code),
+% and we call such tokens \emph{implicit} character tokens. The
+% meaning is otherwise in the following list:
+% \begin{itemize}
+% \item a macro, used in \LaTeX3 for most functions and some variables
+% (|tl|, |fp|, |seq|, \ldots{}),
+% \item a primitive such as \tn{def} or \tn{topmark}, used in \LaTeX3
+% for some functions,
+% \item a register such as \tn{count}|123|, used in \LaTeX3{} for the
+% implementation of some variables (|int|, |dim|, \ldots{}),
+% \item a constant integer such as \tn{char}|"56| or \tn{mathchar}|"121|,
+% \item a font selection command,
+% \item undefined.
+% \end{itemize}
+% Macros can be \tn{protected} or not, \tn{long} or not (the opposite of
+% what \LaTeX3 calls |nopar|), and \tn{outer} or not (unused in
+% \LaTeX3). Their \tn{meaning} takes the form
+% \begin{quote}
+% \meta{prefix} |macro:|\meta{argument}|->|\meta{replacement}
+% \end{quote}
+% where \meta{prefix} is among \tn{protected}\tn{long}\tn{outer},
+% \meta{argument} describes parameters that the macro expects, such as
+% |#1#2#3|, and \meta{replacement} describes how the parameters are
+% manipulated, such as~|\int_eval:n{#2+#1*#3}|.
+%
+% Now is perhaps a good time to mention some subtleties relating to
+% tokens with category code $10$ (space). Any input character with this
+% category code (normally, space and tab characters) becomes a normal
+% space, with character code~$32$ and category code~$10$.
+%
+% When a macro takes an undelimited argument, explicit space characters
+% (with character code $32$ and category code $10$) are ignored. If the
+% following token is an explicit character token with category code $1$
+% (begin-group) and an arbitrary character code, then \TeX{} scans ahead
+% to obtain an equal number of explicit character tokens with category
+% code $1$ (begin-group) and $2$ (end-group), and the resulting list of
+% tokens (with outer braces removed) becomes the argument. Otherwise, a
+% single token is taken as the argument for the macro: we call such
+% single tokens \enquote{N-type}, as they are suitable to be used as an
+% argument for a function with the signature~\texttt{:N}.
+%
+% When a macro takes a delimited argument \TeX{} scans ahead until
+% finding the delimiter (outside any pairs of begin-group/end-group
+% explicit characters), and the resulting list of tokens (with outer
+% braces removed) becomes the argument. Note that explicit space
+% characters at the start of the argument are \emph{not} ignored in this
+% case (and they prevent brace-stripping).
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3token} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*tex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=char>
+% \end{macrocode}
+%
+% \subsection{Internal auxiliaries}
+%
+% \begin{variable}{\s_@@_stop}
+% Internal scan mark.
+% \begin{macrocode}
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\q_@@_no_value}
+% Internal recursion quarks.
+% \begin{macrocode}
+\quark_new:N \q_@@_no_value
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[pTF]{\@@_quark_if_no_value:N}
+% Functions to query recursion quarks.
+% \begin{macrocode}
+\__kernel_quark_new_conditional:Nn \@@_quark_if_no_value:N { TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Manipulating and interrogating character tokens}
+%
+% \begin{macro}{\char_set_catcode:nn}
+% \begin{macro}{\char_value_catcode:n}
+% \begin{macro}{\char_show_value_catcode:n}
+% Simple wrappers around the primitives.
+% \begin{macrocode}
+\cs_new_protected:Npn \char_set_catcode:nn #1#2
+ { \tex_catcode:D \int_eval:n {#1} = \int_eval:n {#2} \exp_stop_f: }
+\cs_new:Npn \char_value_catcode:n #1
+ { \tex_the:D \tex_catcode:D \int_eval:n {#1} \exp_stop_f: }
+\cs_new_protected:Npn \char_show_value_catcode:n #1
+ { \exp_args:Nf \tl_show:n { \char_value_catcode:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \char_set_catcode_escape:N ,
+% \char_set_catcode_group_begin:N ,
+% \char_set_catcode_group_end:N ,
+% \char_set_catcode_math_toggle:N ,
+% \char_set_catcode_alignment:N ,
+% \char_set_catcode_end_line:N ,
+% \char_set_catcode_parameter:N ,
+% \char_set_catcode_math_superscript:N ,
+% \char_set_catcode_math_subscript:N ,
+% \char_set_catcode_ignore:N ,
+% \char_set_catcode_space:N ,
+% \char_set_catcode_letter:N ,
+% \char_set_catcode_other:N ,
+% \char_set_catcode_active:N ,
+% \char_set_catcode_comment:N ,
+% \char_set_catcode_invalid:N
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \char_set_catcode_escape:N #1
+ { \char_set_catcode:nn { `#1 } { 0 } }
+\cs_new_protected:Npn \char_set_catcode_group_begin:N #1
+ { \char_set_catcode:nn { `#1 } { 1 } }
+\cs_new_protected:Npn \char_set_catcode_group_end:N #1
+ { \char_set_catcode:nn { `#1 } { 2 } }
+\cs_new_protected:Npn \char_set_catcode_math_toggle:N #1
+ { \char_set_catcode:nn { `#1 } { 3 } }
+\cs_new_protected:Npn \char_set_catcode_alignment:N #1
+ { \char_set_catcode:nn { `#1 } { 4 } }
+\cs_new_protected:Npn \char_set_catcode_end_line:N #1
+ { \char_set_catcode:nn { `#1 } { 5 } }
+\cs_new_protected:Npn \char_set_catcode_parameter:N #1
+ { \char_set_catcode:nn { `#1 } { 6 } }
+\cs_new_protected:Npn \char_set_catcode_math_superscript:N #1
+ { \char_set_catcode:nn { `#1 } { 7 } }
+\cs_new_protected:Npn \char_set_catcode_math_subscript:N #1
+ { \char_set_catcode:nn { `#1 } { 8 } }
+\cs_new_protected:Npn \char_set_catcode_ignore:N #1
+ { \char_set_catcode:nn { `#1 } { 9 } }
+\cs_new_protected:Npn \char_set_catcode_space:N #1
+ { \char_set_catcode:nn { `#1 } { 10 } }
+\cs_new_protected:Npn \char_set_catcode_letter:N #1
+ { \char_set_catcode:nn { `#1 } { 11 } }
+\cs_new_protected:Npn \char_set_catcode_other:N #1
+ { \char_set_catcode:nn { `#1 } { 12 } }
+\cs_new_protected:Npn \char_set_catcode_active:N #1
+ { \char_set_catcode:nn { `#1 } { 13 } }
+\cs_new_protected:Npn \char_set_catcode_comment:N #1
+ { \char_set_catcode:nn { `#1 } { 14 } }
+\cs_new_protected:Npn \char_set_catcode_invalid:N #1
+ { \char_set_catcode:nn { `#1 } { 15 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \char_set_catcode_escape:n ,
+% \char_set_catcode_group_begin:n ,
+% \char_set_catcode_group_end:n ,
+% \char_set_catcode_math_toggle:n ,
+% \char_set_catcode_alignment:n ,
+% \char_set_catcode_end_line:n ,
+% \char_set_catcode_parameter:n ,
+% \char_set_catcode_math_superscript:n ,
+% \char_set_catcode_math_subscript:n ,
+% \char_set_catcode_ignore:n ,
+% \char_set_catcode_space:n ,
+% \char_set_catcode_letter:n ,
+% \char_set_catcode_other:n ,
+% \char_set_catcode_active:n ,
+% \char_set_catcode_comment:n ,
+% \char_set_catcode_invalid:n
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \char_set_catcode_escape:n #1
+ { \char_set_catcode:nn {#1} { 0 } }
+\cs_new_protected:Npn \char_set_catcode_group_begin:n #1
+ { \char_set_catcode:nn {#1} { 1 } }
+\cs_new_protected:Npn \char_set_catcode_group_end:n #1
+ { \char_set_catcode:nn {#1} { 2 } }
+\cs_new_protected:Npn \char_set_catcode_math_toggle:n #1
+ { \char_set_catcode:nn {#1} { 3 } }
+\cs_new_protected:Npn \char_set_catcode_alignment:n #1
+ { \char_set_catcode:nn {#1} { 4 } }
+\cs_new_protected:Npn \char_set_catcode_end_line:n #1
+ { \char_set_catcode:nn {#1} { 5 } }
+\cs_new_protected:Npn \char_set_catcode_parameter:n #1
+ { \char_set_catcode:nn {#1} { 6 } }
+\cs_new_protected:Npn \char_set_catcode_math_superscript:n #1
+ { \char_set_catcode:nn {#1} { 7 } }
+\cs_new_protected:Npn \char_set_catcode_math_subscript:n #1
+ { \char_set_catcode:nn {#1} { 8 } }
+\cs_new_protected:Npn \char_set_catcode_ignore:n #1
+ { \char_set_catcode:nn {#1} { 9 } }
+\cs_new_protected:Npn \char_set_catcode_space:n #1
+ { \char_set_catcode:nn {#1} { 10 } }
+\cs_new_protected:Npn \char_set_catcode_letter:n #1
+ { \char_set_catcode:nn {#1} { 11 } }
+\cs_new_protected:Npn \char_set_catcode_other:n #1
+ { \char_set_catcode:nn {#1} { 12 } }
+\cs_new_protected:Npn \char_set_catcode_active:n #1
+ { \char_set_catcode:nn {#1} { 13 } }
+\cs_new_protected:Npn \char_set_catcode_comment:n #1
+ { \char_set_catcode:nn {#1} { 14 } }
+\cs_new_protected:Npn \char_set_catcode_invalid:n #1
+ { \char_set_catcode:nn {#1} { 15 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\char_set_mathcode:nn}
+% \begin{macro}{\char_value_mathcode:n}
+% \begin{macro}{\char_show_value_mathcode:n}
+% \begin{macro}{\char_set_lccode:nn}
+% \begin{macro}{\char_value_lccode:n}
+% \begin{macro}{\char_show_value_lccode:n}
+% \begin{macro}{\char_set_uccode:nn}
+% \begin{macro}{\char_value_uccode:n}
+% \begin{macro}{\char_show_value_uccode:n}
+% \begin{macro}{\char_set_sfcode:nn}
+% \begin{macro}{\char_value_sfcode:n}
+% \begin{macro}{\char_show_value_sfcode:n}
+% Pretty repetitive, but necessary!
+% \begin{macrocode}
+\cs_new_protected:Npn \char_set_mathcode:nn #1#2
+ { \tex_mathcode:D \int_eval:n {#1} = \int_eval:n {#2} \exp_stop_f: }
+\cs_new:Npn \char_value_mathcode:n #1
+ { \tex_the:D \tex_mathcode:D \int_eval:n {#1} \exp_stop_f: }
+\cs_new_protected:Npn \char_show_value_mathcode:n #1
+ { \exp_args:Nf \tl_show:n { \char_value_mathcode:n {#1} } }
+\cs_new_protected:Npn \char_set_lccode:nn #1#2
+ { \tex_lccode:D \int_eval:n {#1} = \int_eval:n {#2} \exp_stop_f: }
+\cs_new:Npn \char_value_lccode:n #1
+ { \tex_the:D \tex_lccode:D \int_eval:n {#1} \exp_stop_f: }
+\cs_new_protected:Npn \char_show_value_lccode:n #1
+ { \exp_args:Nf \tl_show:n { \char_value_lccode:n {#1} } }
+\cs_new_protected:Npn \char_set_uccode:nn #1#2
+ { \tex_uccode:D \int_eval:n {#1} = \int_eval:n {#2} \exp_stop_f: }
+\cs_new:Npn \char_value_uccode:n #1
+ { \tex_the:D \tex_uccode:D \int_eval:n {#1} \exp_stop_f: }
+\cs_new_protected:Npn \char_show_value_uccode:n #1
+ { \exp_args:Nf \tl_show:n { \char_value_uccode:n {#1} } }
+\cs_new_protected:Npn \char_set_sfcode:nn #1#2
+ { \tex_sfcode:D \int_eval:n {#1} = \int_eval:n {#2} \exp_stop_f: }
+\cs_new:Npn \char_value_sfcode:n #1
+ { \tex_the:D \tex_sfcode:D \int_eval:n {#1} \exp_stop_f: }
+\cs_new_protected:Npn \char_show_value_sfcode:n #1
+ { \exp_args:Nf \tl_show:n { \char_value_sfcode:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\l_char_active_seq, \l_char_special_seq}
+% Two sequences for dealing with special characters. The first is characters
+% which may be active, the second longer list is for \enquote{special}
+% characters more generally. Both lists are escaped so that for example
+% bulk code assignments can be carried out. In both cases, the order is
+% by \textsc{ascii} character code (as is done in for example
+% \cs{ExplSyntaxOn}).
+% \begin{macrocode}
+\seq_new:N \l_char_special_seq
+\seq_set_split:Nnn \l_char_special_seq { }
+ { \ \" \# \$ \% \& \\ \^ \_ \{ \} \~ }
+\seq_new:N \l_char_active_seq
+\seq_set_split:Nnn \l_char_active_seq { }
+ { \" \$ \& \^ \_ \~ }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Creating character tokens}
+%
+% \begin{macro}
+% {
+% \char_set_active_eq:NN, \char_gset_active_eq:NN,
+% \char_set_active_eq:Nc, \char_gset_active_eq:Nc,
+% \char_set_active_eq:nN, \char_gset_active_eq:nN,
+% \char_set_active_eq:nc, \char_gset_active_eq:nc
+% }
+% Four simple functions with very similar definitions, so set up using
+% an auxiliary.
+% These are similar to \LuaTeX{}'s \tn{letcharcode} primitive.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_active:N \^^@
+ \cs_set_protected:Npn \@@_tmp:nN #1#2
+ {
+ \cs_new_protected:cpn { #1 :nN } ##1
+ {
+ \group_begin:
+ \char_set_lccode:nn { `\^^@ } { ##1 }
+ \tex_lowercase:D { \group_end: #2 ^^@ }
+ }
+ \cs_new_protected:cpe { #1 :NN } ##1
+ { \exp_not:c { #1 : nN } { `##1 } }
+ }
+ \@@_tmp:nN { char_set_active_eq } \cs_set_eq:NN
+ \@@_tmp:nN { char_gset_active_eq } \cs_gset_eq:NN
+\group_end:
+\cs_generate_variant:Nn \char_set_active_eq:NN { Nc }
+\cs_generate_variant:Nn \char_gset_active_eq:NN { Nc }
+\cs_generate_variant:Nn \char_set_active_eq:nN { nc }
+\cs_generate_variant:Nn \char_gset_active_eq:nN { nc }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_int_to_roman:w}
+% For efficiency in 8-bit engines, we use the faster primitive approach
+% to making roman numerals.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_int_to_roman:w \tex_romannumeral:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\char_generate:nn}
+% \begin{macro}[EXP]{\@@_generate_aux:nn}
+% \begin{macro}[EXP]{\@@_generate_aux:nnw, \@@_generate_auxii:nnw}
+% \begin{variable}{\l_@@_tmp_tl}
+% \begin{macro}[EXP]{\@@_generate_invalid_catcode:}
+% The aim here is to generate characters of (broadly) arbitrary category
+% code. Where possible, that is done using engine support (\XeTeX{},
+% \LuaTeX{}). There are though various issues which are covered below. At
+% the interface layer, turn the two arguments into integers up-front so
+% this is only done once.
+% \begin{macrocode}
+\cs_new:Npn \char_generate:nn #1#2
+ {
+ \exp:w \exp_after:wN \@@_generate_aux:w
+ \int_value:w \int_eval:n {#1} \exp_after:wN ;
+ \int_value:w \int_eval:n {#2} ;
+ }
+% \end{macrocode}
+% Before doing any actual conversion, first some special case filtering.
+% Spaces are out here as \LuaTeX{} emulation only makes normal (charcode
+% $32$ spaces). However, |^^@| is filtered out separately as that can't be
+% done with macro emulation either, so is treated separately. That
+% done, hand off to the engine-dependent part.
+% \begin{macrocode}
+\cs_new:Npn \@@_generate_aux:w #1 ; #2 ;
+ {
+ \if_int_odd:w 0
+ \if_int_compare:w #2 < 1 \exp_stop_f: 1 \fi:
+ \if_int_compare:w #2 = 5 \exp_stop_f: 1 \fi:
+ \if_int_compare:w #2 = 9 \exp_stop_f: 1 \fi:
+ \if_int_compare:w #2 > 13 \exp_stop_f: 1 \fi: \exp_stop_f:
+ \msg_expandable_error:nn { char }
+ { invalid-catcode }
+ \else:
+ \if_int_odd:w 0
+ \if_int_compare:w #1 < \c_zero_int 1 \fi:
+ \if_int_compare:w #1 > \c_max_char_int 1 \fi: \exp_stop_f:
+ \msg_expandable_error:nn { char }
+ { out-of-range }
+ \else:
+ \if_int_compare:w #2#1 = 100 \exp_stop_f:
+ \msg_expandable_error:nn { char } { null-space }
+ \else:
+ \@@_generate_aux:nnw {#1} {#2}
+ \fi:
+ \fi:
+ \fi:
+ \exp_end:
+ }
+\tl_new:N \l_@@_tmp_tl
+% \end{macrocode}
+% Engine-dependent definitions are now needed for the implementation. Recent
+% (u)p\TeX{} and the Unicode engines \LuaTeX{} and \XeTeX{} have engine-level
+% support for expandable character creation. \pdfTeX{} and older (u)p\TeX{}
+% releases do not. The branching here if low-level to avoid fixing
+% the category code of the null character used in the false branch.
+% The final level is the basic definition at the engine level: the arguments
+% here are integers so there is no need to worry about them too much.
+% Older versions of \XeTeX{} cannot generate active characters so we filter
+% that:
+% at some future stage that may change: the slightly odd ordering of
+% auxiliaries reflects that.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_active:N \^^L
+ \cs_set:Npn ^^L { }
+ \if_cs_exist:N \tex_Ucharcat:D
+ \cs_new:Npn \@@_generate_aux:nnw #1#2#3 \exp_end:
+ {
+ #3
+ \exp_after:wN \exp_end:
+ \tex_Ucharcat:D #1 \exp_stop_f: #2 \exp_stop_f:
+ }
+ \else:
+% \end{macrocode}
+% For engines where \tn{Ucharcat} isn't available or emulated, we have
+% to work in macros, and cover only the $8$-bit range. The first stage is
+% to build up a |tl| containing |^^@| with each category code that can
+% be accessed in this way, with an error set up for the other cases. This
+% is all done such that it can be quickly accessed using a |\if_case:w|
+% low-level conditional. The list is done in reverse as this puts the case
+% of an active token \emph{first}: that's needed to cover the possibility
+% that it is \tn{outer}. Getting the braces into the list is done using
+% some standard \cs{if_false:} manipulation, while all of the \cs{exp_not:N}
+% are required as there is an expansion in the setup.
+% \begin{macrocode}
+ \char_set_catcode_active:n { 0 }
+ \tl_set:Nn \l_@@_tmp_tl { \exp_not:N ^^@ \exp_not:N \or: }
+ \char_set_catcode_other:n { 0 }
+ \tl_put_right:Nn \l_@@_tmp_tl { ^^@ \exp_not:N \or: }
+ \char_set_catcode_letter:n { 0 }
+ \tl_put_right:Nn \l_@@_tmp_tl { ^^@ \exp_not:N \or: }
+% \end{macrocode}
+% For making spaces, there needs to be an |o|-type expansion of a |\use:n|
+% (or some other tokenization) to avoid dropping the space.
+% \begin{macrocode}
+ \tl_put_right:Nn \l_@@_tmp_tl { \use:n { ~ } \exp_not:N \or: }
+ \tl_put_right:Nn \l_@@_tmp_tl { \exp_not:N \or: }
+ \char_set_catcode_math_subscript:n { 0 }
+ \tl_put_right:Nn \l_@@_tmp_tl { ^^@ \exp_not:N \or: }
+ \char_set_catcode_math_superscript:n { 0 }
+ \tl_put_right:Nn \l_@@_tmp_tl { ^^@ \exp_not:N \or: }
+ \char_set_catcode_parameter:n { 0 }
+ \tl_put_right:Nn \l_@@_tmp_tl { ^^@ \exp_not:N \or: }
+ \tl_put_right:Nn \l_@@_tmp_tl { { \if_false: } \fi: \exp_not:N \or: }
+ \char_set_catcode_alignment:n { 0 }
+ \tl_put_right:Nn \l_@@_tmp_tl { ^^@ \exp_not:N \or: }
+ \char_set_catcode_math_toggle:n { 0 }
+ \tl_put_right:Nn \l_@@_tmp_tl { ^^@ \exp_not:N \or: }
+ \char_set_catcode_group_end:n { 0 }
+ \tl_put_right:Nn \l_@@_tmp_tl { \if_false: { \fi: ^^@ \exp_not:N \or: } % }
+ \char_set_catcode_group_begin:n { 0 } % {
+ \tl_put_right:Nn \l_@@_tmp_tl { ^^@ \exp_not:N \or: } }
+% \end{macrocode}
+% Convert the above temporary list into a series of constant token
+% lists, one for each character code, using \cs{tex_lowercase:D} to
+% convert |^^@| in each case. The \texttt{e}-type expansion ensures
+% that \cs{tex_lowercase:D} receives the contents of the token list.
+% \begin{macrocode}
+ \cs_set_protected:Npn \@@_tmp:n #1
+ {
+ \char_set_lccode:nn { 0 } {#1}
+ \char_set_lccode:nn { 32 } {#1}
+ \exp_args:Ne \tex_lowercase:D
+ {
+ \tl_const:Ne
+ \exp_not:c { c_@@_ \@@_int_to_roman:w #1 _tl }
+ { \exp_not:o \l_@@_tmp_tl }
+ }
+ }
+ \int_step_function:nnN { 0 } { 255 } \@@_tmp:n
+% \end{macrocode}
+% As \TeX{} is very unhappy if it finds an alignment character inside
+% a primitive \tn{halign} even when skipping false branches, some
+% precautions are required. \TeX{} is happy if the token is hidden
+% between braces within \cs{if_false:} \dots{} \cs{fi:}. The
+% rather low-level approach here expands in one step to the
+% \meta{target token} (\cs{or:} \dots{}), then \cs{exp_after:wN}
+% \meta{target token} (\cs{or:} \dots{}) expands in one step to
+% \meta{target token}. This means that \cs{exp_not:N} is applied to
+% a potentially-problematic active token.
+% \begin{macrocode}
+ \cs_new:Npn \@@_generate_aux:nnw #1#2#3 \exp_end:
+ {
+ #3
+ \if_false: { \fi:
+ \exp_after:wN \exp_after:wN \exp_after:wN \exp_end:
+ \exp_after:wN \exp_after:wN
+ \if_case:w \tex_numexpr:D 13 - #2
+ \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN \scan_stop:
+ \exp_after:wN \exp_after:wN \exp_after:wN \exp_not:N
+ \cs:w c_@@_ \@@_int_to_roman:w #1 _tl \cs_end:
+ }
+ \fi:
+ }
+ \fi:
+\group_end:
+% \end{macrocode}
+% \end{macro}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\c_catcode_active_space_tl}
+% While \cs{char_generate:nn} can produce active characters in some
+% engines it cannot in general. It would be possible to simply change
+% the catcode of space but then the code would need to avoid all
+% spaces, making it quite unreadable. Instead we use the primitive
+% \cs{tex_lowercase:D} trick.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_active:N *
+ \char_set_lccode:nn { `* } { `\ }
+ \tex_lowercase:D { \tl_const:Nn \c_catcode_active_space_tl { * } }
+\group_end:
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\c_catcode_other_space_tl}
+% Create a space with category code $12$: an \enquote{other} space.
+% \begin{macrocode}
+\tl_const:Ne \c_catcode_other_space_tl { \char_generate:nn { `\ } { 12 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Generic tokens}
+%
+% \begin{macrocode}
+%<@@=token>
+% \end{macrocode}
+%
+% \begin{variable}{\s_@@_mark, \s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\token_to_meaning:N, \token_to_meaning:c}
+% \begin{macro}{\token_to_str:N, \token_to_str:c}
+% These are all defined in \pkg{l3basics}, as they are needed
+% \enquote{early}. This is just a reminder!
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_to_catcode:N}
+% \begin{macro}{\@@_to_catcode:N}
+% The macro works by comparing the input token with \cs{if_catcode:w} with all
+% valid category codes. Since the most common tokens in an average argument
+% list are of category $11$ or $12$ those are tested first. And since a space
+% and braces are no ordinary |N|-type arguments, and only control sequences
+% let to those categories can match them they are tested last.
+% \begin{macrocode}
+\cs_new:Npn \token_to_catcode:N
+ { \int_value:w \group_align_safe_begin: \@@_to_catcode:N }
+\cs_new:Npn \@@_to_catcode:N #1
+ {
+ \if_catcode:w \exp_not:N #1 \c_catcode_letter_token
+ 11
+ \else:
+ \if_catcode:w \exp_not:N #1 \c_catcode_other_token
+ 12
+ \else:
+ \if_catcode:w \exp_not:N #1 \c_math_toggle_token
+ 3
+ \else:
+ \if_catcode:w \exp_not:N #1 \c_alignment_token
+ 4
+ \else:
+ \if_catcode:w \exp_not:N #1 ##
+ 6
+ \else:
+ \if_catcode:w \exp_not:N #1 \c_math_superscript_token
+ 7
+ \else:
+ \if_catcode:w \exp_not:N #1 \c_math_subscript_token
+ 8
+ \else:
+ \if_catcode:w \exp_not:N #1 \c_group_begin_token
+ 1
+ \else:
+ \if_catcode:w \exp_not:N #1 \c_group_end_token
+ 2
+ \else:
+ \if_catcode:w \exp_not:N #1 \c_space_token
+ 10
+ \else:
+ \token_if_cs:NTF #1 { 16 } { 13 }
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \group_align_safe_end:
+ \exp_stop_f:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \c_group_begin_token,
+% \c_group_end_token,
+% \c_math_toggle_token,
+% \c_alignment_token,
+% \c_parameter_token,
+% \c_math_superscript_token,
+% \c_math_subscript_token,
+% \c_space_token,
+% \c_catcode_letter_token,
+% \c_catcode_other_token
+% }
+% We define these useful tokens. For the brace and space tokens things have
+% to be done by hand: the formal argument spec.~for \cs{cs_new_eq:NN} does
+% not cover them so we do things by hand. (As currently coded it would
+% \emph{work} with \cs{cs_new_eq:NN} but that's not really a great idea to
+% show off: we want people to stick to the defined interfaces and that
+% includes us.) So that these few odd names go into the log when appropriate
+% there is a need to hand-apply the \cs{__kernel_chk_if_free_cs:N} check.
+% \begin{macrocode}
+\group_begin:
+ \__kernel_chk_if_free_cs:N \c_group_begin_token
+ \tex_global:D \tex_let:D \c_group_begin_token {
+ \__kernel_chk_if_free_cs:N \c_group_end_token
+ \tex_global:D \tex_let:D \c_group_end_token }
+ \char_set_catcode_math_toggle:N \*
+ \cs_new_eq:NN \c_math_toggle_token *
+ \char_set_catcode_alignment:N \*
+ \cs_new_eq:NN \c_alignment_token *
+ \cs_new_eq:NN \c_parameter_token #
+ \cs_new_eq:NN \c_math_superscript_token ^
+ \char_set_catcode_math_subscript:N \*
+ \cs_new_eq:NN \c_math_subscript_token *
+ \__kernel_chk_if_free_cs:N \c_space_token
+ \use:n { \tex_global:D \tex_let:D \c_space_token = ~ } ~
+ \cs_new_eq:NN \c_catcode_letter_token a
+ \cs_new_eq:NN \c_catcode_other_token 1
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\c_catcode_active_tl}
+% Not an implicit token!
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_active:N \*
+ \tl_const:Nn \c_catcode_active_tl { \exp_not:N * }
+\group_end:
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Token conditionals}
+%
+% \begin{macro}[pTF]{\token_if_group_begin:N}
+% Check if token is a begin group token. We use the constant
+% \cs{c_group_begin_token} for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_group_begin:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_group_begin_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_group_end:N}
+% Check if token is a end group token. We use the constant
+% \cs{c_group_end_token} for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_group_end:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_group_end_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_math_toggle:N}
+% Check if token is a math shift token. We use the constant
+% \cs{c_math_toggle_token} for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_math_toggle:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_math_toggle_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_alignment:N}
+% Check if token is an alignment tab token. We use the constant
+% \cs{c_alignment_token} for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_alignment:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_alignment_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_parameter:N}
+% Check if token is a parameter token. We use the constant
+% \cs{c_parameter_token} for this. We have to trick \TeX{} a bit to
+% avoid an error message: within a group we prevent
+% \cs{c_parameter_token} from behaving like a macro parameter character.
+% The definitions of \cs{prg_new_conditional:Npnn} are global, so they
+% remain after the group.
+% \begin{macrocode}
+\group_begin:
+\cs_set_eq:NN \c_parameter_token \scan_stop:
+\prg_new_conditional:Npnn \token_if_parameter:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_parameter_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_math_superscript:N}
+% Check if token is a math superscript token. We use the constant
+% \cs{c_math_superscript_token} for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_math_superscript:N #1
+ { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_math_superscript_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_math_subscript:N}
+% Check if token is a math subscript token. We use the constant
+% \cs{c_math_subscript_token} for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_math_subscript:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_math_subscript_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_space:N}
+% Check if token is a space token. We use the constant
+% \cs{c_space_token} for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_space:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_space_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_letter:N}
+% Check if token is a letter token. We use the constant
+% \cs{c_catcode_letter_token} for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_letter:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_catcode_letter_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_other:N}
+% Check if token is an other char token. We use the constant
+% \cs{c_catcode_other_token} for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_other:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_catcode_other_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_active:N}
+% Check if token is an active char token. We use the constant
+% \cs{c_catcode_active_tl} for this. A technical point is that
+% \cs{c_catcode_active_tl} is in fact a macro expanding to
+% |\exp_not:N *|, where |*| is active.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_active:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_catcode_active_tl
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_eq_meaning:NN}
+% Check if the tokens |#1| and |#2| have same meaning.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \token_if_eq_meaning:NN \cs_if_eq:NN
+ { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_eq_catcode:NN}
+% Check if the tokens |#1| and |#2| have same category code.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_eq_catcode:NN #1#2 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \exp_not:N #2
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_eq_charcode:NN}
+% Check if the tokens |#1| and |#2| have same character code.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_eq_charcode:NN #1#2 { p , T , F , TF }
+ {
+ \if_charcode:w \exp_not:N #1 \exp_not:N #2
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_macro:N}
+% \begin{macro}{\@@_if_macro_p:w}
+% When a token is a macro, \cs{token_to_meaning:N} always outputs
+% something like |\long macro:#1->#1| so we could naively check to
+% see if the meaning contains |->|. However, this can fail the five
+% \tn[no-index]{...mark} primitives, whose meaning has the form
+% |...mark:|\meta{user material}. The problem is that the
+% \meta{user material} can contain |->|.
+%
+% However, only characters, macros, and marks can contain the colon
+% character. The idea is thus to grab until the first |:|, and analyse
+% what is left. However, macros can have any combination of |\long|,
+% |\protected| or |\outer| (not used in \LaTeX3) before the string
+% |macro:|. We thus only select the part of the meaning between
+% the first |ma| and the first following |:|. If this string is
+% |cro|, then we have a macro. If the string is |rk|, then we have
+% a mark. The string can also be |cro parameter character | for a
+% colon with a weird category code (namely the usual category code
+% of |#|). Otherwise, it is empty.
+%
+% This relies on the fact that |\long|, |\protected|, |\outer|
+% cannot contain |ma|, regardless of the escape character, even if
+% the escape character is |m|\ldots{}
+%
+% Both |ma| and |:| must be of category code $12$ (other), so are
+% detokenized.
+%
+% \begin{macrocode}
+\use:e
+ {
+ \prg_new_conditional:Npnn \exp_not:N \token_if_macro:N #1
+ { p , T , F , TF }
+ {
+ \exp_not:N \exp_after:wN \exp_not:N \@@_if_macro_p:w
+ \exp_not:N \token_to_meaning:N #1 \tl_to_str:n { ma : }
+ \s_@@_stop
+ }
+ \cs_new:Npn \exp_not:N \@@_if_macro_p:w
+ #1 \tl_to_str:n { ma } #2 \c_colon_str #3 \s_@@_stop
+ }
+ {
+ \str_if_eq:nnTF { #2 } { cro }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_cs:N}
+% Check if token has same catcode as a control sequence. This
+% follows the same pattern as for \cs{token_if_letter:N} \emph{etc.}
+% We use \cs{scan_stop:} for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_cs:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \scan_stop:
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_expandable:N}
+% Check if token is expandable. We use the fact that \TeX{}
+% temporarily converts \cs{exp_not:N} \meta{token} into \cs{scan_stop:}
+% if \meta{token} is expandable. An \texttt{undefined} token is not
+% considered as expandable. No problem nesting the conditionals,
+% since the third |#1| is only skipped if it is non-expandable (hence
+% not part of \TeX{}'s conditional apparatus).
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_expandable:N #1 { p , T , F , TF }
+ {
+ \exp_after:wN \if_meaning:w \exp_not:N #1 #1
+ \prg_return_false:
+ \else:
+ \if_cs_exist:N #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_delimit_by_char":w,
+% \@@_delimit_by_count:w,
+% \@@_delimit_by_dimen:w,
+% \@@_delimit_by_ font:w,
+% \@@_delimit_by_macro:w,
+% \@@_delimit_by_muskip:w,
+% \@@_delimit_by_skip:w,
+% \@@_delimit_by_toks:w,
+% }
+% These auxiliary functions are used below to define some
+% conditionals which detect whether the \tn{meaning} of their
+% argument begins with a particular string. Each auxiliary takes an
+% argument delimited by a string, a second one delimited by
+% \cs{s_@@_stop}, and returns the first one and its delimiter.
+% This result is eventually compared to another string.
+% Note that the ``font'' auxiliary is delimited by a space followed by
+% ``\texttt{font}''. This avoids an unnecessary check for the
+% \tn{font} primitive below.
+% \begin{macrocode}
+\group_begin:
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \use:e
+ {
+ \cs_new:Npn \exp_not:c { @@_delimit_by_ #1 :w }
+ ##1 \tl_to_str:n {#1} ##2 \s_@@_stop
+ { ##1 \tl_to_str:n {#1} }
+ }
+ }
+\@@_tmp:w { char" }
+\@@_tmp:w { count }
+\@@_tmp:w { dimen }
+\@@_tmp:w { ~ font }
+\@@_tmp:w { macro }
+\@@_tmp:w { muskip }
+\@@_tmp:w { skip }
+\@@_tmp:w { toks }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]
+% {
+% \token_if_chardef:N, \token_if_mathchardef:N,
+% \token_if_long_macro:N,
+% \token_if_protected_macro:N, \token_if_protected_long_macro:N,
+% \token_if_font_selection:N,
+% \token_if_dim_register:N, \token_if_int_register:N,
+% \token_if_muskip_register:N,
+% \token_if_skip_register:N, \token_if_toks_register:N,
+% }
+% Each of these conditionals tests whether its argument's
+% \tn{meaning} starts with a given string. This is essentially done
+% by having an auxiliary grab an argument delimited by the string and
+% testing whether the argument was empty. Of course, a copy of this
+% string must first be added to the end of the \tn{meaning} to avoid
+% a runaway argument in case it does not contain the string. Two
+% complications arise. First, the escape character is not fixed, and
+% cannot be included in the delimiter of the auxiliary function (this
+% function cannot be defined on the fly because tests must remain
+% expandable): instead the first argument of the auxiliary (plus the
+% delimiter to avoid complications with trailing spaces) is compared
+% using \cs{str_if_eq:eeTF} to the result of applying
+% \cs{token_to_str:N} to a control sequence. Second, the
+% \tn{meaning} of primitives such as \tn{dimen} or \tn{dimendef}
+% starts in the same way as registers such as
+% \tn{dimen}\texttt{123}, so they must be tested for.
+%
+% Characters used as delimiters must have catcode~$12$
+% and are obtained through \cs{tl_to_str:n}. This requires doing all
+% definitions within \texttt{e}-expansion. The temporary function
+% \cs{@@_tmp:w} used to define each conditional receives three
+% arguments: the name of the conditional, the auxiliary's delimiter
+% (also used to name the auxiliary), and the string to which one
+% compares the auxiliary's result. Note that the \tn{meaning} of a
+% protected long macro starts with |\protected\long macro|, with no
+% space after |\protected| but a space after |\long|, hence the
+% mixture of \cs{token_to_str:N} and \cs{tl_to_str:n}.
+%
+% For the first six conditionals, \cs{cs_if_exist:cT} turns out to
+% be \texttt{false} (thanks to the leading space for \texttt{font}),
+% and the code boils down to a string comparison
+% between the result of the auxiliary on the \tn{meaning} of the
+% conditional's argument~|####1|, and~|#3|. Both are evaluated at
+% run-time, as this is important to get the correct escape character.
+%
+% The other five conditionals have additional code that compares the
+% argument~|####1| to two \TeX{} primitives which would wrongly be
+% recognized as registers otherwise. Despite using \TeX{}'s
+% primitive conditional construction, this does not break
+% when~|####1| is itself a conditional, because branches of the
+% conditionals are only skipped if |####1|~is one of the two
+% primitives that are tested for (which are not \TeX{} conditionals).
+% \begin{macrocode}
+\group_begin:
+\cs_set_protected:Npn \@@_tmp:w #1#2#3
+ {
+ \use:e
+ {
+ \prg_new_conditional:Npnn \exp_not:c { token_if_ #1 :N } ##1
+ { p , T , F , TF }
+ {
+ \cs_if_exist:cT { tex_ #2 :D }
+ {
+ \exp_not:N \if_meaning:w ##1 \exp_not:c { tex_ #2 :D }
+ \exp_not:N \prg_return_false:
+ \exp_not:N \else:
+ \exp_not:N \if_meaning:w ##1 \exp_not:c { tex_ #2 def:D }
+ \exp_not:N \prg_return_false:
+ \exp_not:N \else:
+ }
+ \exp_not:N \str_if_eq:eeTF
+ {
+ \exp_not:N \exp_after:wN
+ \exp_not:c { @@_delimit_by_ #2 :w }
+ \exp_not:N \token_to_meaning:N ##1
+ ? \tl_to_str:n {#2} \s_@@_stop
+ }
+ { \exp_not:n {#3} }
+ { \exp_not:N \prg_return_true: }
+ { \exp_not:N \prg_return_false: }
+ \cs_if_exist:cT { tex_ #2 :D }
+ {
+ \exp_not:N \fi:
+ \exp_not:N \fi:
+ }
+ }
+ }
+ }
+\@@_tmp:w { chardef } { char" } { \token_to_str:N \char" }
+\@@_tmp:w { mathchardef } { char" } { \token_to_str:N \mathchar" }
+\@@_tmp:w { long_macro } { macro } { \tl_to_str:n { \long } macro }
+\@@_tmp:w { protected_macro } { macro }
+ { \tl_to_str:n { \protected } macro }
+\@@_tmp:w { protected_long_macro } { macro }
+ { \token_to_str:N \protected \tl_to_str:n { \long } macro }
+\@@_tmp:w { font_selection } { ~ font } { select ~ font }
+\@@_tmp:w { dim_register } { dimen } { \token_to_str:N \dimen }
+\@@_tmp:w { int_register } { count } { \token_to_str:N \count }
+\@@_tmp:w { muskip_register } { muskip } { \token_to_str:N \muskip }
+\@@_tmp:w { skip_register } { skip } { \token_to_str:N \skip }
+\@@_tmp:w { toks_register } { toks } { \token_to_str:N \toks }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_primitive:N}
+% \begin{macro}{\@@_if_primitive:NNw,
+% \@@_if_primitive_space:w,
+% \@@_if_primitive_nullfont:N,
+% \@@_if_primitive_loop:N,
+% \@@_if_primitive:Nw,
+% \@@_if_primitive_undefined:N,
+% \@@_if_primitive_lua:N}
+%^^A See http://groups.google.com/group/comp.text.tex/browse_thread/thread/0a72666873f8753d#
+%
+% We filter out macros first, because they cause endless trouble later
+% otherwise.
+%
+% Primitives are almost distinguished by the fact that the result
+% of \cs{token_to_meaning:N} is formed from letters only. Every other
+% token has either a space (e.g., |the letter A|), a digit
+% (e.g., |\count123|) or a double quote (e.g., |\char"A|).
+%
+% Ten exceptions: on the one hand, \cs{tex_undefined:D} is not a
+% primitive, but its meaning is |undefined|, only letters;
+% on the other hand, \tn{space}, \tn{italiccorr},
+% \tn{hyphen}, \tn{firstmark}, \tn{topmark},
+% \tn{botmark}, \tn{splitfirstmark}, \tn{splitbotmark},
+% and \tn{nullfont} are primitives, but have non-letters
+% in their meaning.
+%
+% We start by removing the two first (non-space) characters from
+% the meaning. This removes the escape character (which may be
+% nonexistent depending on \tn{endlinechar}), and takes care
+% of three of the exceptions: \tn{space}, \tn{italiccorr}
+% and \tn{hyphen}, whose meaning is at most two characters.
+% This leaves a string terminated by some |:|, and \cs{s_@@_stop}.
+%
+% The meaning of each one of the five \tn[no-index]{...mark} primitives
+% has the form \meta{letters}|:|\meta{user material}. In other words,
+% the first non-letter is a colon. We remove everything after the first
+% colon.
+%
+% We are now left with a string, which we must analyze. For primitives,
+% it contains only letters. For non-primitives, it contains either
+% |"|, or a space, or a digit. Two exceptions remain: \cs{tex_undefined:D},
+% which is not a primitive, and \tn{nullfont}, which is a primitive.
+%
+% Spaces cannot be grabbed in an undelimited way, so we check them
+% separately. If there is a space, we test for \tn{nullfont}.
+% Otherwise, we go through characters one by one, and stop at the
+% first character less than |`A| (this is not quite a test for
+% \enquote{only letters}, but is close enough to work in this context).
+% If this first character is |:| then we have a primitive, or
+% \cs{tex_undefined:D}, and if it is |"| or a digit, then the token
+% is not a primitive.
+%
+% For \LuaTeX{} we use a different implementation which just looks at the
+% command code for the token and compares it to a list of non-primitives.
+% Again, \tn{nullfont} is a special case because it is the only primitive
+% with the normally non-primitive |set_font| command code.
+%
+% In LuaMeta\TeX{} some of the command names are different, so we check for
+% both versions. The first one is always the \LuaTeX{} version.
+%
+% \begin{macrocode}
+\sys_if_engine_luatex:TF
+ {
+%</tex>
+%<*lua>
+do
+ local get_next = token.get_next
+ local get_command = token.get_command
+ local get_index = token.get_index
+ local get_mode = token.get_mode or token.get_index
+ local cmd = command_id
+ local set_font = cmd'get_font'
+ local biggest_char = token.biggest_char and token.biggest_char()
+ or status.getconstants().max_character_code
+
+ local mode_below_biggest_char = {}
+ local index_not_nil = {}
+ local mode_not_null = {}
+ local non_primitive = {
+ [cmd'left_brace'] = true,
+ [cmd'right_brace'] = true,
+ [cmd'math_shift'] = true,
+ [cmd'mac_param' or cmd'parameter'] = mode_below_biggest_char,
+ [cmd'sup_mark' or cmd'superscript'] = true,
+ [cmd'sub_mark' or cmd'subscript'] = true,
+ [cmd'endv' or cmd'ignore'] = true,
+ [cmd'spacer'] = true,
+ [cmd'letter'] = true,
+ [cmd'other_char'] = true,
+ [cmd'tab_mark' or cmd'alignment_tab'] = mode_below_biggest_char,
+ [cmd'char_given'] = true,
+ [cmd'math_given' or 'math_char_given'] = true,
+ [cmd'xmath_given' or 'math_char_xgiven'] = true,
+ [cmd'set_font'] = mode_not_null,
+ [cmd'undefined_cs'] = true,
+ [cmd'call'] = true,
+ [cmd'long_call' or cmd'protected_call'] = true,
+ [cmd'outer_call' or cmd'tolerant_call'] = true,
+ [cmd'long_outer_call' or cmd'tolerant_protected_call'] = true,
+ [cmd'assign_glue' or cmd'register_glue'] = index_not_nil,
+ [cmd'assign_mu_glue' or cmd'register_mu_glue' or cmd'register_muglue'] = index_not_nil,
+ [cmd'assign_toks' or cmd'register_toks'] = index_not_nil,
+ [cmd'assign_int' or cmd'register_int' or cmd'register_integer'] = index_not_nil,
+ [cmd'assign_attr' or cmd'register_attribute'] = true,
+ [cmd'assign_dimen' or cmd'register_dimen' or cmd'register_dimension'] = index_not_nil,
+ }
+
+ luacmd("@@_if_primitive_lua:N", function()
+ local tok = get_next()
+ local is_non_primitive = non_primitive[get_command(tok)]
+ return put_next(
+ is_non_primitive == true
+ and false_tok
+ or is_non_primitive == nil
+ and true_tok
+ or is_non_primitive == mode_not_null
+ and (get_mode(tok) == 0 and true_tok or false_tok)
+ or is_non_primitive == index_not_nil
+ and (get_index(tok) and false_tok or true_tok)
+ or is_non_primitive == mode_below_biggest_char
+ and (get_mode(tok) > biggest_char and true_tok or false_tok))
+ end, "global")
+end
+%</lua>
+%<*tex>
+ \prg_new_conditional:Npnn \token_if_primitive:N #1 { p , T , F , TF }
+ {
+ \@@_if_primitive_lua:N #1
+ }
+ }
+ {
+ \tex_global:D \tex_chardef:D \c_@@_A_int = `A ~ %
+ \use:e
+ {
+ \prg_new_conditional:Npnn \exp_not:N \token_if_primitive:N #1
+ { p , T , F , TF }
+ {
+ \exp_not:N \token_if_macro:NTF #1
+ \exp_not:N \prg_return_false:
+ {
+ \exp_not:N \exp_after:wN \exp_not:N \@@_if_primitive:NNw
+ \exp_not:N \token_to_meaning:N #1
+ \tl_to_str:n { : : : } \s_@@_stop #1
+ }
+ }
+ \cs_new:Npn \exp_not:N \@@_if_primitive:NNw
+ #1#2 #3 \c_colon_str #4 \s_@@_stop
+ {
+ \exp_not:N \tl_if_empty:oTF
+ { \exp_not:N \@@_if_primitive_space:w #3 ~ }
+ {
+ \exp_not:N \@@_if_primitive_loop:N #3
+ \c_colon_str \s_@@_stop
+ }
+ { \exp_not:N \@@_if_primitive_nullfont:N }
+ }
+ }
+ \cs_new:Npn \@@_if_primitive_space:w #1 ~ { }
+ \cs_new:Npn \@@_if_primitive_nullfont:N #1
+ {
+ \if_meaning:w \tex_nullfont:D #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ \cs_new:Npn \@@_if_primitive_loop:N #1
+ {
+ \if_int_compare:w `#1 < \c_@@_A_int %
+ \exp_after:wN \@@_if_primitive:Nw
+ \exp_after:wN #1
+ \else:
+ \exp_after:wN \@@_if_primitive_loop:N
+ \fi:
+ }
+ \cs_new:Npn \@@_if_primitive:Nw #1 #2 \s_@@_stop
+ {
+ \if:w : #1
+ \exp_after:wN \@@_if_primitive_undefined:N
+ \else:
+ \prg_return_false:
+ \exp_after:wN \use_none:n
+ \fi:
+ }
+ \cs_new:Npn \@@_if_primitive_undefined:N #1
+ {
+ \if_cs_exist:N #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP, noTF]
+% {\token_case_catcode:Nn, \token_case_charcode:Nn, \token_case_meaning:Nn}
+% \begin{macro}[EXP]{\@@_case:NNnTF, \@@_case:NNw, \@@_case_end:nw}
+% The aim here is to allow the case statement to be evaluated
+% using a known number of expansion steps (two), and without
+% needing to use an explicit \enquote{end of recursion} marker.
+% That is achieved by using the test input as the final case,
+% as this is always true. The trick is then to tidy up
+% the output such that the appropriate case code plus either
+% the \texttt{true} or \texttt{false} branch code is inserted.
+% \begin{macrocode}
+\cs_new:Npn \token_case_catcode:Nn #1#2
+ { \exp:w \@@_case:NNnTF \token_if_eq_catcode:NNTF #1 {#2} { } { } }
+\cs_new:Npn \token_case_catcode:NnT #1#2#3
+ { \exp:w \@@_case:NNnTF \token_if_eq_catcode:NNTF #1 {#2} {#3} { } }
+\cs_new:Npn \token_case_catcode:NnF #1#2
+ { \exp:w \@@_case:NNnTF \token_if_eq_catcode:NNTF #1 {#2} { } }
+\cs_new:Npn \token_case_catcode:NnTF
+ { \exp:w \@@_case:NNnTF \token_if_eq_catcode:NNTF }
+\cs_new:Npn \token_case_charcode:Nn #1#2
+ { \exp:w \@@_case:NNnTF \token_if_eq_charcode:NNTF #1 {#2} { } { } }
+\cs_new:Npn \token_case_charcode:NnT #1#2#3
+ { \exp:w \@@_case:NNnTF \token_if_eq_charcode:NNTF #1 {#2} {#3} { } }
+\cs_new:Npn \token_case_charcode:NnF #1#2
+ { \exp:w \@@_case:NNnTF \token_if_eq_charcode:NNTF #1 {#2} { } }
+\cs_new:Npn \token_case_charcode:NnTF
+ { \exp:w \@@_case:NNnTF \token_if_eq_charcode:NNTF }
+\cs_new:Npn \token_case_meaning:Nn #1#2
+ { \exp:w \@@_case:NNnTF \token_if_eq_meaning:NNTF #1 {#2} { } { } }
+\cs_new:Npn \token_case_meaning:NnT #1#2#3
+ { \exp:w \@@_case:NNnTF \token_if_eq_meaning:NNTF #1 {#2} {#3} { } }
+\cs_new:Npn \token_case_meaning:NnF #1#2
+ { \exp:w \@@_case:NNnTF \token_if_eq_meaning:NNTF #1 {#2} { } }
+\cs_new:Npn \token_case_meaning:NnTF
+ { \exp:w \@@_case:NNnTF \token_if_eq_meaning:NNTF }
+\cs_new:Npn \@@_case:NNnTF #1#2#3#4#5
+ {
+ \@@_case:NNw #1 #2 #3 #2 { }
+ \s_@@_mark {#4}
+ \s_@@_mark {#5}
+ \s_@@_stop
+ }
+\cs_new:Npn \@@_case:NNw #1#2#3#4
+ {
+ #1 #2 #3
+ { \@@_case_end:nw {#4} }
+ { \@@_case:NNw #1 #2 }
+ }
+% \end{macrocode}
+% To tidy up the recursion, there are two outcomes. If there was a hit to
+% one of the cases searched for, then |#1| is the code to insert,
+% |#2| is the \emph{next} case to check on and |#3| is all of
+% the rest of the cases code. That means that |#4| is the \texttt{true}
+% branch code, and |#5| tidies up the spare \cs{s_@@_mark} and the
+% \texttt{false} branch. On the other hand, if none of the cases matched
+% then we arrive here using the \enquote{termination} case of comparing
+% the search with itself. That means that |#1| is empty, |#2| is
+% the first \cs{s_@@_mark} and so |#4| is the \texttt{false} code (the
+% \texttt{true} code is mopped up by |#3|).
+% \begin{macrocode}
+\cs_new:Npn \@@_case_end:nw #1#2#3 \s_@@_mark #4#5 \s_@@_stop
+ { \exp_end: #1 #4 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Peeking ahead at the next token}
+%
+% \begin{macrocode}
+%<@@=peek>
+% \end{macrocode}
+%
+% Peeking ahead is implemented using a two part mechanism. The
+% outer level provides a defined interface to the lower level material.
+% This allows a large amount of code to be shared. There are four
+% cases:
+% \begin{enumerate}
+% \item peek at the next token;
+% \item peek at the next non-space token;
+% \item peek at the next token and remove it;
+% \item peek at the next non-space token and remove it.
+% \end{enumerate}
+%
+% \begin{variable}{\l_peek_token}
+% \begin{variable}{\g_peek_token}
+% Storage tokens which are publicly documented: the token peeked.
+% \begin{macrocode}
+\cs_new_eq:NN \l_peek_token ?
+\cs_new_eq:NN \g_peek_token ?
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_search_token}
+% The token to search for as an implicit token:
+% \emph{cf.}~\cs{l_@@_search_tl}.
+% \begin{macrocode}
+\cs_new_eq:NN \l_@@_search_token ?
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_search_tl}
+% The token to search for as an explicit token:
+% \emph{cf.}~\cs{l_@@_search_token}.
+% \begin{macrocode}
+\tl_new:N \l_@@_search_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {\@@_true:w, \@@_true_aux:w, \@@_false:w, \@@_tmp:w}
+% Functions used by the branching and space-stripping code.
+% \begin{macrocode}
+\cs_new:Npn \@@_true:w { }
+\cs_new:Npn \@@_true_aux:w { }
+\cs_new:Npn \@@_false:w { }
+\cs_new:Npn \@@_tmp:w { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\s_@@_mark,\s_@@_stop}
+% Internal scan marks.
+% \begin{macrocode}
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_use_none_delimit_by_s_stop:w}
+% Functions to gobble up to a scan mark.
+% \begin{macrocode}
+\cs_new:Npn \@@_use_none_delimit_by_s_stop:w #1 \s_@@_stop { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\peek_after:Nw}
+% \begin{macro}{\peek_gafter:Nw}
+% Simple wrappers for \tn{futurelet}: no arguments absorbed
+% here.
+% \begin{macrocode}
+\cs_new_protected:Npn \peek_after:Nw
+ { \tex_futurelet:D \l_peek_token }
+\cs_new_protected:Npn \peek_gafter:Nw
+ { \tex_global:D \tex_futurelet:D \g_peek_token }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_true_remove:w}
+% A function to remove the next token and then regain control.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_true_remove:w
+ {
+ \tex_afterassignment:D \@@_true_aux:w
+ \cs_set_eq:NN \@@_tmp:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\peek_remove_spaces:n, \@@_remove_spaces:}
+% Repeatedly use \cs{@@_true_remove:w} to remove a space and call
+% \cs{@@_true_aux:w}.
+% \begin{macrocode}
+\cs_new_protected:Npn \peek_remove_spaces:n #1
+ {
+ \cs_set:Npe \@@_false:w { \exp_not:n {#1} }
+ \group_align_safe_begin:
+ \cs_set:Npn \@@_true_aux:w { \peek_after:Nw \@@_remove_spaces: }
+ \@@_true_aux:w
+ }
+\cs_new_protected:Npn \@@_remove_spaces:
+ {
+ \if_meaning:w \l_peek_token \c_space_token
+ \exp_after:wN \@@_true_remove:w
+ \else:
+ \group_align_safe_end:
+ \exp_after:wN \@@_false:w
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\peek_remove_filler:n}
+% \begin{macro}{\@@_remove_filler:w}
+% \begin{macro}{\@@_remove_filler:}
+% \begin{macro}{\@@_remove_filler_expand:w}
+% Here we expand the input, removing spaces and \cs{scan_stop:} tokens until
+% we reach a non-expandable token. At that stage we re-insert the payload.
+% To deal with the problem of |&| tokens, we have to put the align-safe
+% group in the correct place.
+% \begin{macrocode}
+\cs_new_protected:Npn \peek_remove_filler:n #1
+ {
+ \cs_set:Npn \@@_true_aux:w { \@@_remove_filler:w }
+ \cs_set:Npe \@@_false:w
+ {
+ \exp_not:N \group_align_safe_end:
+ \exp_not:n {#1}
+ }
+ \group_align_safe_begin:
+ \@@_remove_filler:w
+ }
+\cs_new_protected:Npn \@@_remove_filler:w
+ {
+ \exp_after:wN \peek_after:Nw \exp_after:wN \@@_remove_filler:
+ \exp:w \exp_end_continue_f:w
+ }
+% \end{macrocode}
+% Here we can nest conditionals as \cs{l_peek_token} is only skipped over in
+% the nested one if it's a space: no problems with conditionals or outer
+% tokens.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_remove_filler:
+ {
+ \if_catcode:w \exp_not:N \l_peek_token \c_space_token
+ \exp_after:wN \@@_true_remove:w
+ \else:
+ \if_meaning:w \l_peek_token \scan_stop:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \@@_true_remove:w
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \@@_remove_filler_expand:w
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% To deal with undefined control sequences in the same way \TeX{} does,
+% we need to check for expansion manually.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_remove_filler_expand:w
+ {
+ \exp_after:wN \if_meaning:w \exp_not:N \l_peek_token \l_peek_token
+ \exp_after:wN \@@_false:w
+ \else:
+ \exp_after:wN \@@_remove_filler:w
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_token_generic_aux:NNNTF}
+% The generic functions store the test token in both implicit and
+% explicit modes, and the \texttt{true} and \texttt{false} code as
+% token lists, more or less. The two branches have to be absorbed here
+% as the input stream needs to be cleared for the peek function itself.
+% Here, |#1| is \cs{@@_true_remove:w} when removing the token and
+% \cs{@@_true_aux:w} otherwise.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_token_generic_aux:NNNTF #1#2#3#4#5
+ {
+ \group_align_safe_begin:
+ \cs_set_eq:NN \l_@@_search_token #3
+ \tl_set:Nn \l_@@_search_tl {#3}
+ \cs_set:Npe \@@_true_aux:w
+ {
+ \exp_not:N \group_align_safe_end:
+ \exp_not:n {#4}
+ }
+ \cs_set_eq:NN \@@_true:w #1
+ \cs_set:Npe \@@_false:w
+ {
+ \exp_not:N \group_align_safe_end:
+ \exp_not:n {#5}
+ }
+ \peek_after:Nw #2
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\@@_token_generic:NN, \@@_token_remove_generic:NN}
+% For token removal there needs to be a call to the auxiliary
+% function which does the work.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_token_generic:NNTF
+ { \@@_token_generic_aux:NNNTF \@@_true_aux:w }
+\cs_new_protected:Npn \@@_token_generic:NNT #1#2#3
+ { \@@_token_generic:NNTF #1 #2 {#3} { } }
+\cs_new_protected:Npn \@@_token_generic:NNF #1#2#3
+ { \@@_token_generic:NNTF #1 #2 { } {#3} }
+\cs_new_protected:Npn \@@_token_remove_generic:NNTF
+ { \@@_token_generic_aux:NNNTF \@@_true_remove:w }
+\cs_new_protected:Npn \@@_token_remove_generic:NNT #1#2#3
+ { \@@_token_remove_generic:NNTF #1 #2 {#3} { } }
+\cs_new_protected:Npn \@@_token_remove_generic:NNF #1#2#3
+ { \@@_token_remove_generic:NNTF #1 #2 { } {#3} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_execute_branches_meaning:}
+% The meaning test is straight forward.
+% \begin{macrocode}
+\cs_new:Npn \@@_execute_branches_meaning:
+ {
+ \if_meaning:w \l_peek_token \l_@@_search_token
+ \exp_after:wN \@@_true:w
+ \else:
+ \exp_after:wN \@@_false:w
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_execute_branches_catcode:, \@@_execute_branches_charcode:}
+% \begin{macro}
+% {
+% \@@_execute_branches_catcode_aux: ,
+% \@@_execute_branches_catcode_auxii:N ,
+% \@@_execute_branches_catcode_auxiii:
+% }
+% The catcode and charcode tests are very similar, and in order to use
+% the same auxiliaries we do something a little bit odd, firing
+% \cs{if_catcode:w} and \cs{if_charcode:w} before finding the operands
+% for those tests, which are only given in the |auxii:N| and
+% |auxiii:| auxiliaries. For our purposes, three kinds of tokens may
+% follow the peeking function:
+% \begin{itemize}
+% \item control sequences which are not equal to a non-active
+% character token (\emph{e.g.}, macro, primitive);
+% \item active characters which are not equal to a non-active
+% character token (\emph{e.g.}, macro, primitive);
+% \item explicit non-active character tokens, or control sequences
+% or active characters set equal to a non-active character token.
+% \end{itemize}
+% The first two cases are not distinguishable simply using \TeX{}'s
+% \tn{futurelet}, because we can only access the \tn{meaning} of
+% tokens in that way. In those cases, detected thanks to a
+% comparison with \cs{scan_stop:}, we grab the following token, and
+% compare it explicitly with the explicit search token stored in
+% \cs{l_@@_search_tl}. The \cs{exp_not:N} prevents outer macros
+% (coming from non-\LaTeX3 code) from blowing up. In the third case,
+% \cs{l_peek_token} is good enough for the test, and we compare it
+% again with the explicit search token. Just like the peek token, the
+% search token may be of any of the three types above, hence the need
+% to use the explicit token that was given to the peek function.
+% \begin{macrocode}
+\cs_new:Npn \@@_execute_branches_catcode:
+ { \if_catcode:w \@@_execute_branches_catcode_aux: }
+\cs_new:Npn \@@_execute_branches_charcode:
+ { \if_charcode:w \@@_execute_branches_catcode_aux: }
+\cs_new:Npn \@@_execute_branches_catcode_aux:
+ {
+ \if_catcode:w \exp_not:N \l_peek_token \scan_stop:
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_execute_branches_catcode_auxii:N
+ \exp_after:wN \exp_not:N
+ \else:
+ \exp_after:wN \@@_execute_branches_catcode_auxiii:
+ \fi:
+ }
+\cs_new:Npn \@@_execute_branches_catcode_auxii:N #1
+ {
+ \exp_not:N #1
+ \exp_after:wN \exp_not:N \l_@@_search_tl
+ \exp_after:wN \@@_true:w
+ \else:
+ \exp_after:wN \@@_false:w
+ \fi:
+ #1
+ }
+\cs_new:Npn \@@_execute_branches_catcode_auxiii:
+ {
+ \exp_not:N \l_peek_token
+ \exp_after:wN \exp_not:N \l_@@_search_tl
+ \exp_after:wN \@@_true:w
+ \else:
+ \exp_after:wN \@@_false:w
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]
+% {
+% \peek_catcode:N,
+% \peek_catcode_remove:N,
+% \peek_charcode:N,
+% \peek_charcode_remove:N,
+% \peek_meaning:N,
+% \peek_meaning_remove:N,
+% }
+% The public functions themselves cannot be defined using
+% \cs{prg_new_conditional:Npnn}. Instead, the |TF|, |T|, |F| variants
+% are defined in terms of corresponding variants of
+% \cs{@@_token_generic:NNTF} or \cs{@@_token_remove_generic:NNTF},
+% with first argument one of \cs{@@_execute_branches_catcode:},
+% \cs{@@_execute_branches_charcode:}, or
+% \cs{@@_execute_branches_meaning:}.
+% \begin{macrocode}
+\tl_map_inline:nn { { catcode } { charcode } { meaning } }
+ {
+ \tl_map_inline:nn { { } { _remove } }
+ {
+ \tl_map_inline:nn { { TF } { T } { F } }
+ {
+ \cs_new_protected:cpe { peek_ #1 ##1 :N ####1 }
+ {
+ \exp_not:c { @@_token ##1 _generic:NN ####1 }
+ \exp_not:c { @@_execute_branches_ #1 : }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\peek_N_type:}
+% \begin{macro}
+% {\@@_execute_branches_N_type:, \@@_N_type:w, \@@_N_type_aux:nnw}
+% All tokens are \texttt{N}-type tokens, except in four cases:
+% begin-group tokens, end-group tokens, space tokens with character
+% code~$32$, and outer tokens. Since \cs{l_peek_token} might be
+% outer, we cannot use the convenient \cs{bool_if:nTF} function, and
+% must resort to the old trick of using \tn{ifodd} to expand a set of
+% tests. The \texttt{false} branch of this test is taken if the token
+% is one of the first three kinds of non-\texttt{N}-type tokens
+% (explicit or implicit), thus we call \cs{@@_false:w}. In the
+% \texttt{true} branch, we must detect outer tokens, without impacting
+% performance too much for non-outer tokens. The first filter is to
+% search for \texttt{outer} in the \tn{meaning} of \cs{l_peek_token}.
+% If that is absent, \cs{@@_use_none_delimit_by_s_stop:w} cleans up, and
+% we call \cs{@@_true:w}. Otherwise, the token can be a non-outer
+% macro or a primitive mark whose parameter or replacement text
+% contains \texttt{outer}, it can be the primitive \tn{outer}, or it
+% can be an outer token. Macros and marks would have \texttt{ma} in
+% the part before the first occurrence of \texttt{outer}; the meaning
+% of \tn{outer} has nothing after \texttt{outer}, contrarily to outer
+% macros; and that covers all cases, calling \cs{@@_true:w} or
+% \cs{@@_false:w} as appropriate. Here, there is no \meta{search
+% token}, so we feed a dummy \cs{scan_stop:} to the
+% \cs{@@_token_generic:NNTF} function.
+% \begin{macrocode}
+\group_begin:
+ \cs_set_protected:Npn \@@_tmp:w #1 \s_@@_stop
+ {
+ \cs_new_protected:Npn \@@_execute_branches_N_type:
+ {
+ \if_int_odd:w
+ \if_catcode:w \exp_not:N \l_peek_token { \c_zero_int \fi:
+ \if_catcode:w \exp_not:N \l_peek_token } \c_zero_int \fi:
+ \if_meaning:w \l_peek_token \c_space_token \c_zero_int \fi:
+ \c_one_int
+ \exp_after:wN \@@_N_type:w
+ \token_to_meaning:N \l_peek_token
+ \s_@@_mark \@@_N_type_aux:nnw
+ #1 \s_@@_mark \@@_use_none_delimit_by_s_stop:w
+ \s_@@_stop
+ \exp_after:wN \@@_true:w
+ \else:
+ \exp_after:wN \@@_false:w
+ \fi:
+ }
+ \cs_new_protected:Npn \@@_N_type:w ##1 #1 ##2 \s_@@_mark ##3
+ { ##3 {##1} {##2} }
+ }
+ \exp_after:wN \@@_tmp:w \tl_to_str:n { outer } \s_@@_stop
+\group_end:
+\cs_new_protected:Npn \@@_N_type_aux:nnw #1 #2 #3 \fi:
+ {
+ \fi:
+ \tl_if_in:noTF {#1} { \tl_to_str:n {ma} }
+ { \@@_true:w }
+ { \tl_if_empty:nTF {#2} { \@@_true:w } { \@@_false:w } }
+ }
+\cs_new_protected:Npn \peek_N_type:TF
+ {
+ \@@_token_generic:NNTF
+ \@@_execute_branches_N_type: \scan_stop:
+ }
+\cs_new_protected:Npn \peek_N_type:T
+ { \@@_token_generic:NNT \@@_execute_branches_N_type: \scan_stop: }
+\cs_new_protected:Npn \peek_N_type:F
+ { \@@_token_generic:NNF \@@_execute_branches_N_type: \scan_stop: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</tex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/l3unicode.dtx b/macros/latex-dev/required/l3kernel/l3unicode.dtx
new file mode 100644
index 0000000000..0ee6858f5b
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/l3unicode.dtx
@@ -0,0 +1,1031 @@
+% \iffalse meta-comment
+%
+%% File: l3unicode.dtx
+%
+% Copyright (C) 2018-2024 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3unicode} module\\ Unicode support functions^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2024-04-11}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% This module provides Unicode-specific functions along with loading data
+% from a range of Unicode Consortium files. Most of the code here is
+% internal, but there are a small set of public functions. These work with
+% Unicode \meta{codepoints} and are designed to give useable results with
+% both Unicode-aware and $8$-bit engines.
+%
+% \begin{function}[EXP, added = 2022-10-09, updated = 2022-11-09]
+% {\codepoint_generate:nn}
+% \begin{syntax}
+% \cs{codepoint_generate:nn} \Arg{codepoint} \Arg{catcode}
+% \end{syntax}
+% Generates one or more character tokens representing the \meta{codepoint}.
+% With Unicode engines, exactly one character token will be generated, and
+% this will have the \meta{catcode} specified as the second argument:
+% \begin{itemize}
+% \item $1$ (begin group)
+% \item $2$ (end group)
+% \item $3$ (math toggle)
+% \item $4$ (alignment)
+% \item $6$ (parameter)
+% \item $7$ (math superscript)
+% \item $8$ (math subscript)
+% \item $10$ (space)
+% \item $11$ (letter)
+% \item $12$ (other)
+% \item $13$ (active)
+% \end{itemize}
+% For $8$-bit engines, between one and four character tokens will be
+% produced: these will be the bytes of the UTF-8 representation of the
+% \meta{codepoint}. For all codepoints outside of the classical ASCII
+% range, the generated character tokens will be active (category code
+% $13$); for codepoints in the ASCII range, the given \meta{catcode}
+% will be used. To allow the result of this function to be used
+% inside an expansion context, the result is protected by \cs{exp_not:n}.
+%
+% \begin{texnote}
+% Users of (u)p\TeX{} note that these engines are treated as $8$-bit in
+% this context. In particular, for up\TeX{}, irrespective of the
+% \tn{kcatcode} of the \meta{codepoint}, any value outside the ASCII range
+% will result in a series of active bytes being generated.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2022-10-09]
+% {\codepoint_str_generate:n}
+% \begin{syntax}
+% \cs{codepoint_str_generate:n} \Arg{codepoint}
+% \end{syntax}
+% Generates one or more character tokens representing the \meta{codepoint}.
+% With Unicode engines, exactly one character token will be generated.
+% For $8$-bit engines, between one and four character tokens will be
+% produced: these will be the bytes of the UTF-8 representation of the
+% \meta{codepoint}. All of the generated character tokens will be of
+% category code $12$, except any spaces (codepoint $32$), which will be
+% category code $10$.
+% \end{function}
+%
+% \begin{function}[added = 2023-06-19, EXP]{\codepoint_to_category:n}
+% \begin{syntax}
+% \cs{codepoint_to_category:n} \Arg{codepoint}
+% \end{syntax}
+% Expands to the Unicode general category identifier of the \meta{codepoint}.
+% The general category identifier is a string made up of two letter
+% characters, the first uppercase and the second lowercase. The uppercase
+% letters divide codepoints into broader groups, which are then refined
+% by the lowercase letter. For example, codepoints representing letters
+% all have identifiers starting \texttt{L}, for example \texttt{Lu}
+% (uppercase letter), \texttt{Lt} (titlecase letter), \emph{etc.}
+% Full details are available in the documentation provided by the Unicode
+% Consortium: see
+% \url{https://www.unicode.org/reports/tr44/#General_Category_Values}
+% \end{function}
+%
+% \begin{function}[added = 2022-10-09, EXP]{\codepoint_to_nfd:n}
+% \begin{syntax}
+% \cs{codepoint_to_nfd:n} \Arg{codepoint}
+% \end{syntax}
+% Converts the \meta{codepoint} to the Unicode Normalization
+% Form Canonical Decomposition. The generated character(s) will have
+% the current category code as they would if typed in directly for Unicode
+% engines; for $8$-bit engines, active characters are used for all codepoints
+% outside of the ASCII range.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3unicode} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=codepoint>
+% \end{macrocode}
+%
+% \subsection{User functions}
+%
+% \begin{macro}[EXP]{\codepoint_str_generate:n}
+% \begin{macro}[EXP]{\@@_str_generate:nnnn}
+% \begin{macro}[EXP]{\codepoint_generate:nn}
+% \begin{macro}[EXP]{\@@_generate:nnnn}
+% \begin{macro}[EXP]{\@@_generate:n}
+% Conversion of a codepoint to a character (Unicode engines) or to one
+% or more bytes ($8$-bit engines) is required. For loading the data,
+% all that is needed is the form which creates strings: these are outside
+% the group as they will also be used when looking up data in the hash
+% table storage at point-of-use. Later, we will also need functions that
+% can generate character tokens for document use: those are defined below,
+% in the data recovery setup.
+% \begin{macrocode}
+\bool_lazy_or:nnTF
+ { \sys_if_engine_luatex_p: }
+ { \sys_if_engine_xetex_p: }
+ {
+ \cs_new:Npn \codepoint_str_generate:n #1
+ {
+ \int_compare:nNnTF {#1} = { `\ }
+ { ~ }
+ { \char_generate:nn {#1} { 12 } }
+ }
+ \cs_new:Npn \codepoint_generate:nn #1#2
+ {
+ \int_compare:nNnTF {#1} = { `\ }
+ { ~ }
+ {
+ \__kernel_exp_not:w \exp_after:wN \exp_after:wN \exp_after:wN
+ { \char_generate:nn {#1} {#2} }
+ }
+ }
+ }
+ {
+ \cs_new:Npn \codepoint_str_generate:n #1
+ {
+ \int_compare:nNnTF {#1} = { `\ }
+ { ~ }
+ {
+ \use:e
+ {
+ \exp_not:N \@@_str_generate:nnnn
+ \__kernel_codepoint_to_bytes:n {#1}
+ }
+ }
+ }
+ \cs_new:Npn \@@_str_generate:nnnn #1#2#3#4
+ {
+ \char_generate:nn {#1} { 12 }
+ \tl_if_blank:nF {#2}
+ {
+ \char_generate:nn {#2} { 12 }
+ \tl_if_blank:nF {#3}
+ {
+ \char_generate:nn {#3} { 12 }
+ \tl_if_blank:nF {#4}
+ { \char_generate:nn {#4} { 12 } }
+ }
+ }
+ }
+ \cs_new:Npn \codepoint_generate:nn #1#2
+ {
+ \int_compare:nNnTF {#1} = { `\ }
+ { ~ }
+ {
+ \int_compare:nNnTF {#1} < { "80 }
+ {
+ \__kernel_exp_not:w \exp_after:wN \exp_after:wN \exp_after:wN
+ { \char_generate:nn {#1} {#2} }
+ }
+ {
+ \use:e
+ {
+ \exp_not:N \@@_generate:nnnn
+ \__kernel_codepoint_to_bytes:n {#1}
+ }
+ }
+ }
+ }
+ \cs_new:Npn \@@_generate:nnnn #1#2#3#4
+ {
+ \__kernel_exp_not:w \exp_after:wN
+ {
+ \tex_expanded:D
+ {
+ \@@_generate:n {#1}
+ \@@_generate:n {#2}
+ \tl_if_blank:nF {#3}
+ {
+ \@@_generate:n {#3}
+ \tl_if_blank:nF {#4}
+ { \@@_generate:n {#4} }
+ }
+ }
+ }
+ }
+ \cs_new:Npn \@@_generate:n #1
+ {
+ \__kernel_exp_not:w \exp_after:wN \exp_after:wN \exp_after:wN
+ { \char_generate:nn {#1} { 13 } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\__kernel_codepoint_to_bytes:n}
+% \begin{macro}[EXP]{\@@_to_bytes_auxi:n}
+% \begin{macro}[EXP]{\@@_to_bytes_auxii:Nnn}
+% \begin{macro}[EXP]{\@@_to_bytes_auxiii:n}
+% \begin{macro}[EXP]
+% {
+% \@@_to_bytes_outputi:nw ,
+% \@@_to_bytes_outputii:nw ,
+% \@@_to_bytes_outputiii:nw ,
+% \@@_to_bytes_outputiv:nw
+% }
+% \begin{macro}[EXP]
+% {\@@_to_bytes_output:nnn, \@@_to_bytes_output:fnn}
+% \begin{macro}[EXP]{\@@_to_bytes_end:}
+% This code converts a codepoint into the correct UTF-8 representation.
+% In terms of the algorithm itself, see
+% \url{https://en.wikipedia.org/wiki/UTF-8} for the octet pattern.
+% \begin{macrocode}
+\cs_new:Npn \__kernel_codepoint_to_bytes:n #1
+ {
+ \exp_args:Nf \@@_to_bytes_auxi:n
+ { \int_eval:n {#1} }
+ }
+\cs_new:Npn \@@_to_bytes_auxi:n #1
+ {
+ \if_int_compare:w #1 > "80 \exp_stop_f:
+ \if_int_compare:w #1 < "800 \exp_stop_f:
+ \@@_to_bytes_outputi:nw
+ { \@@_to_bytes_auxii:Nnn C {#1} { 64 } }
+ \@@_to_bytes_outputii:nw
+ { \@@_to_bytes_auxiii:n {#1} }
+ \else:
+ \if_int_compare:w #1 < "10000 \exp_stop_f:
+ \@@_to_bytes_outputi:nw
+ { \@@_to_bytes_auxii:Nnn E {#1} { 64 * 64 } }
+ \@@_to_bytes_outputii:nw
+ {
+ \@@_to_bytes_auxiii:n
+ { \int_div_truncate:nn {#1} { 64 } }
+ }
+ \@@_to_bytes_outputiii:nw
+ { \@@_to_bytes_auxiii:n {#1} }
+ \else:
+ \@@_to_bytes_outputi:nw
+ {
+ \@@_to_bytes_auxii:Nnn F
+ {#1} { 64 * 64 * 64 }
+ }
+ \@@_to_bytes_outputii:nw
+ {
+ \@@_to_bytes_auxiii:n
+ { \int_div_truncate:nn {#1} { 64 * 64 } }
+ }
+ \@@_to_bytes_outputiii:nw
+ {
+ \@@_to_bytes_auxiii:n
+ { \int_div_truncate:nn {#1} { 64 } }
+ }
+ \@@_to_bytes_outputiv:nw
+ { \@@_to_bytes_auxiii:n {#1} }
+ \fi:
+ \fi:
+ \else:
+ \@@_to_bytes_outputi:nw {#1}
+ \fi:
+ \@@_to_bytes_end: { } { } { } { }
+ }
+\cs_new:Npn \@@_to_bytes_auxii:Nnn #1#2#3
+ { "#10 + \int_div_truncate:nn {#2} {#3} }
+\cs_new:Npn \@@_to_bytes_auxiii:n #1
+ { \int_mod:nn {#1} { 64 } + 128 }
+\cs_new:Npn \@@_to_bytes_outputi:nw
+ #1 #2 \@@_to_bytes_end: #3
+ { \@@_to_bytes_output:fnn { \int_eval:n {#1} } { } {#2} }
+\cs_new:Npn \@@_to_bytes_outputii:nw
+ #1 #2 \@@_to_bytes_end: #3#4
+ { \@@_to_bytes_output:fnn { \int_eval:n {#1} } { {#3} } {#2} }
+\cs_new:Npn \@@_to_bytes_outputiii:nw
+ #1 #2 \@@_to_bytes_end: #3#4#5
+ {
+ \@@_to_bytes_output:fnn
+ { \int_eval:n {#1} } { {#3} {#4} } {#2}
+ }
+\cs_new:Npn \@@_to_bytes_outputiv:nw
+ #1 #2 \@@_to_bytes_end: #3#4#5#6
+ {
+ \@@_to_bytes_output:fnn
+ { \int_eval:n {#1} } { {#3} {#4} {#5} } {#2}
+ }
+\cs_new:Npn \@@_to_bytes_output:nnn #1#2#3
+ {
+ #3
+ \@@_to_bytes_end: #2 {#1}
+ }
+\cs_generate_variant:Nn \@@_to_bytes_output:nnn { f }
+\cs_new:Npn \@@_to_bytes_end: { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\codepoint_to_category:n}
+% Get the value and convert back to the string.
+% \begin{macrocode}
+\cs_new:Npn \codepoint_to_category:n #1
+ {
+ \cs:w
+ c_@@_category_
+ \tex_romannumeral:D
+ \__kernel_codepoint_data:nn { category } {#1}
+ _str
+ \cs_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\codepoint_to_nfd:n, \@@_to_nfd:n}
+% \begin{macro}[EXP]{\@@_to_nfd:nn}
+% \begin{macro}[EXP]{\@@_to_nfd:nnn}
+% \begin{macro}[EXP]{\@@_to_nfd:nnnn}
+% Converted to NFD is a potentially-recursive process: the key is to
+% check if we get the input codepoint back again. As far as possible,
+% we use the same path for all engines.
+% \begin{macrocode}
+\cs_new:Npn \codepoint_to_nfd:n #1
+ { \exp_args:Ne \@@_to_nfd:n { \int_eval:n {#1} } }
+\cs_new:Npn \@@_to_nfd:n #1
+ { \@@_to_nfd:nn {#1} { \char_value_catcode:n {#1} } }
+\bool_lazy_or:nnF
+ { \sys_if_engine_luatex_p: }
+ { \sys_if_engine_xetex_p: }
+ {
+ \cs_gset:Npn \@@_to_nfd:n #1
+ {
+ \int_compare:nNnTF {#1} > { "80 }
+ { \@@_to_nfd:nn {#1} { 12 } }
+ { \@@_to_nfd:nn {#1} { \char_value_catcode:n {#1} } }
+ }
+ }
+\cs_new:Npn \@@_to_nfd:nn #1#2
+ {
+ \exp_args:Ne \@@_to_nfd:nnn
+ { \@@_nfd:n {#1} } {#1} {#2}
+ }
+\cs_new:Npn \@@_to_nfd:nnn #1#2#3 { \@@_to_nfd:nnnn #1 {#2} {#3} }
+\cs_new:Npn \@@_to_nfd:nnnn #1#2#3#4
+ {
+ \int_compare:nNnTF {#1} = {#3}
+ { \codepoint_generate:nn {#1} {#4} }
+ {
+ \@@_to_nfd:nn {#1} {#4}
+ \tl_if_blank:nF {#2}
+ { \@@_to_nfd:nn {#2} {#4} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Data loader}
+%
+% Text operations requires data from the Unicode Consortium. Data read into
+% Unicode engine formats is at best a small part of what we need, so there
+% is a loader here to set up the appropriate data structures.
+%
+% Where we need data for most or all of the Unicode range, we use the two-stage
+% table approach recommended by the Unicode Consortium and demonstrated in a
+% model implementation in Python in
+% \url{https://www.strchr.com/multi-stage_tables}. This approach uses the
+% \texttt{intarray} (\texttt{fontdimen}-based) data type as it is fast for
+% random access and avoids significant hash table usage. In contrast, where
+% only a small subset of codepoints are required, storage as macros is
+% preferable. There is also some consideration of the effort needed to load
+% data: see for example the grapheme breaking information, which would be
+% problematic to convert into a two-stage table but which can be used with
+% reasonable performance in a small number of comma lists (at the cost that
+% breaking at higher codepoint Hangul characters will be slightly slow).
+%
+% \begin{variable}{\c_@@_block_size_int}
+% Choosing the block size for the blocks in the two-stage approach is
+% non-trivial: depending on the data stored, the optimal size for
+% memory usage will vary. At the same time, for us there is also the
+% question of load-time: larger blocks require longer comma lists
+% as intermediates, so are slower. As this is going to be needed
+% to use the data, we set it up outside of the group for clarity.
+% \begin{macrocode}
+\int_const:Nn \c_@@_block_size_int { 64 }
+% \end{macrocode}
+% \end{variable}
+%
+% Parsing the data files can be the same way for all engines, but where they
+% are stored as character tokens, the construction method depends on whether
+% they are Unicode or $8$-bit internally. Parsing is therefore done by common
+% functions, with some data storage using engine-specific auxiliaries.
+%
+% As only the data needs to remain at the end of this process, everything
+% is set up inside a group. The only thing that is outside is creating a
+% stream: they are global anyway and it is best to force a stream for
+% all engines.
+%
+% \begin{variable}{\g_@@_data_ior}
+% \begin{macrocode}
+\ior_new:N \g_@@_data_ior
+% \end{macrocode}
+% \end{variable}
+%
+% We need some setup for the two-part table approach. The number of blocks we
+% need will be variable, but the resulting size of the stage one table
+% is predictable. For performance reasons, we therefore create the stage one
+% tables now so they can be used immediately, and will later rename them as a
+% constant tables. For each two-stage table construction, we need a comma
+% list to hold the partial block and a couple of integers to track where
+% we are up to. To avoid burning registers, the latter are stored in macros
+% and are \enquote{fake} integers. We also avoid any \texttt{new} functions,
+% keeping as much as possible local.
+%
+% As we need both positive and negative values, case data requires one
+% two-stage table for each transformation. In contrasts, general Unicode
+% properties could be stored in one table with appropriate combination rules:
+% that is not done at present but is likely to be added over time. Here, all
+% that is needed is additional entries into the comma-list to create the
+% structures.
+%
+% Notice that in the standard \pkg{expl3} way we are indexes position not
+% offset: that does mean a little work later.
+% \begin{macrocode}
+\group_begin:
+ \clist_map_inline:nn
+ { category , uppercase , lowercase }
+ {
+ \cs_set_nopar:cpn { l_@@_ #1 _block_clist } { }
+ \cs_set_nopar:cpn { l_@@_ #1 _block_tl } { 1 }
+ \cs_set_nopar:cpn { l_@@_ #1 _pos_tl } { 0 }
+ \intarray_new:cn { g_@@_ #1 _index_intarray }
+ { \int_div_truncate:nn { "110000 } \c_@@_block_size_int }
+ }
+% \end{macrocode}
+% We need an integer value when matching the current block to those we have
+% already seen, and a way to track codepoints for handling ranges. Again,
+% we avoid using up registers or creating global names.
+% \begin{macrocode}
+ \cs_set_nopar:Npn \l_@@_next_codepoint_fint_tl { 0 }
+ \cs_set_nopar:Npn \l_@@_matched_block_tl { 0 }
+% \end{macrocode}
+% For Unicode general category, there needs to be numerical representation of
+% each possible value. As we need to go from string to number here, but the
+% other way elsewhere, we set up fast mappings both ways, but one set local
+% and the other as constants.
+% \begin{macrocode}
+ \cs_set_protected:Npn \@@_data_auxi:w #1#2
+ {
+ \quark_if_recursion_tail_stop:n {#2}
+ \cs_set_nopar:cpn { l_@@_category_ #2 _tl } {#1}
+ \str_const:cn { c_@@_category_ \tex_romannumeral:D #1 _str } {#2}
+ \exp_args:Ne \@@_data_auxi:w { \int_eval:n { #1 + 1 } }
+ }
+ \@@_data_auxi:w { 1 }
+ { Lu } { Ll } { Lt } { Lm } { Lo }
+ { Mn } { Me } { Mc }
+ { Nd } { Nl } { No }
+ { Zs } { Zl } { Zp }
+ { Cc } { Cf } { Co } { Cs } { Cn }
+ { Pd } { Ps } { Pe } { Pc } { Po } { Pi } { Pf }
+ { Sm } { Sc } { Sk } { So }
+ \q_recursion_tail
+ \q_recursion_stop
+% \end{macrocode}
+% Parse the main Unicode data file and pull out the NFD and case changing
+% data. The NFD data is stored on using the hash table approach and can yield
+% a predictable number of codepoints: one or two. We also need the case data,
+% which will be modified further below. To allow for finding ranges, the
+% description of the codepoint needs to be carried forward.
+% \begin{macrocode}
+ \cs_set_protected:Npn \@@_data_auxi:w
+ #1 ; #2 ; #3 ; #4 ; #5 ; #6 ; #7 ; #8 ; #9 ;
+ {
+ \tl_if_blank:nF {#6}
+ {
+ \tl_if_head_eq_charcode:nNF {#6} < % >
+ { \@@_data_auxii:w #1 ; #6 ~ \q_stop }
+ }
+ \@@_data_auxiii:w #1 ; #2 ; #3 ;
+ }
+ \cs_set_protected:Npn \@@_data_auxii:w #1 ; #2 ~ #3 \q_stop
+ {
+ \tl_const:ce
+ { c_@@_nfd_ \codepoint_str_generate:n {"#1} _tl }
+ {
+ {"#2}
+ { \tl_if_blank:nF {#3} {"#3} }
+ }
+ }
+% \end{macrocode}
+% The category data needs to be converted from a string to the numerical
+% equivalent: a simple operation.
+% The case data is going to be stored as an offset from the parent character,
+% rather than an absolute value. We therefore deal with that plus the situation
+% where a codepoint has no mapping data in one shot.
+% \begin{macrocode}
+ \cs_set_protected:Npn \@@_data_auxiii:w
+ #1 ; #2 ; #3 ; #4 ; #5 ; #6 ; #7 ; #8 ; #9 ~ \q_stop
+ {
+ \use:e
+ {
+ \@@_data_auxiv:w
+ #1 ; #2 ;
+ \@@_data_category:n {#3} ;
+ \@@_data_offset:nn {#1} {#7} ;
+ \@@_data_offset:nn {#1} {#8} ;
+ #9;
+ }
+ }
+ \cs_set:Npn \@@_data_category:n #1
+ { \use:c { l_@@_category_ #1 _tl } }
+ \cs_set:Npn \@@_data_offset:nn #1#2
+ {
+ \tl_if_blank:nTF {#2}
+ { 0 }
+ { \int_eval:n { "#2 - "#1 } }
+ }
+% \end{macrocode}
+% To deal with ranges, we track the position of the next codepoint expected.
+% If there is a gap, we deal with that separately: it could be a range or
+% an unused part of the Unicode space. As such, we deal with the current
+% codepoint here whether or not there is range to fill in. Upper- and
+% lowercase data go into the two-stage table, any titlecase exception is
+% just stored in a macro. The data for the codepoint is added to the current
+% block, and if that is now complete we move on to save the block. The
+% case exceptions are all stored as codepoints, with a fixed number of
+% balanced text as we know that there are never more than three.
+% \begin{macrocode}
+ \cs_set_protected:Npn \@@_data_auxiv:w #1 ; #2 ; #3 ; #4 ; #5 ; #6 ;
+ {
+ \int_compare:nNnT {"#1} > \l_@@_next_codepoint_fint_tl
+ {
+ \@@_data_auxv:nnnnw {#1} {#3} {#4} {#5}
+ #2 Last> \q_stop
+ }
+ \@@_add:nn { category } {#3}
+ \@@_add:nn { uppercase } {#4}
+ \@@_add:nn { lowercase } {#5}
+ \int_compare:nNnF {#4} = { \@@_data_offset:nn {#1} {#6} }
+ {
+ \tl_const:ce
+ { c_@@_titlecase_ \codepoint_str_generate:n {"#1} _tl }
+ { {"#6} { } { } }
+ }
+ \tl_set:Ne \l_@@_next_codepoint_fint_tl
+ { \int_eval:n { "#1 + 1 } }
+ }
+ \cs_set_protected:Npn \@@_add:nn #1#2
+ {
+ \clist_put_right:cn { l_@@_ #1 _block_clist } {#2}
+ \int_compare:nNnT { \clist_count:c { l_@@_ #1 _block_clist } }
+ = \c_@@_block_size_int
+ { \@@_save_blocks:nn {#1} { 1 } }
+ }
+% \end{macrocode}
+% Distinguish between a range and a gap, and pass on the appropriate value(s).
+% The general category for unassigned characters is \texttt{Cn}, so we
+% find the correct value once and then use that.
+% \begin{macrocode}
+ \cs_set_protected:Npe \@@_data_auxv:nnnnw #1#2#3#4#5 Last> #6 \q_stop
+ {
+ \exp_not:N \tl_if_blank:nTF {#6}
+ {
+ \exp_not:N \@@_range:nnn {#1} { category }
+ { \exp_not:V \l_@@_category_Cn_tl }
+ \exp_not:N \@@_range:nnn {#1} { uppercase } { 0 }
+ \exp_not:N \@@_range:nnn {#1} { lowercase } { 0 }
+ }
+ {
+ \exp_not:N \@@_range:nnn {#1} { category } {#2}
+ \exp_not:N \@@_range:nnn {#1} { uppercase } {#3}
+ \exp_not:N \@@_range:nnn {#1} { lowercase } {#4}
+ }
+ }
+% \end{macrocode}
+% Calculated the length of the range and the space remaining in the current
+% block.
+% \begin{macrocode}
+ \cs_set_protected:Npn \@@_range:nnn #1
+ {
+ \exp_args:Nf \@@_range_aux:nnn
+ { \int_eval:n { "#1 - \l_@@_next_codepoint_fint_tl } }
+ }
+ \cs_set_protected:Npn \@@_range_aux:nnn #1#2
+ {
+ \exp_args:Nf \@@_range:nnnn
+ {
+ \int_min:nn
+ {#1}
+ {
+ \c_@@_block_size_int
+ - \clist_count:c { l_@@_ #2 _block_clist }
+ }
+ }
+ {#1} {#2}
+ }
+% \end{macrocode}
+% Here we want to do three things: add to and possibly complete the current
+% block, add complete blocks quickly, then finish up the range in a final
+% open block. We need to avoid as far as possible avoid dealing with every
+% single codepoint, so the middle step is optimised.
+% \begin{macrocode}
+ \cs_set_protected:Npn \@@_range:nnnn #1#2#3#4
+ {
+ \prg_replicate:nn {#1}
+ { \clist_put_right:cn { l_@@_ #3 _block_clist } {#4} }
+ \int_compare:nNnT { \clist_count:c { l_@@_ #3 _block_clist } }
+ = \c_@@_block_size_int
+ { \@@_save_blocks:nn {#3} { 1 } }
+ \int_compare:nNnF
+ { \int_div_truncate:nn { #2 - #1 } \c_@@_block_size_int } = 0
+ {
+ \tl_set:ce { l_@@_ #3 _block_clist }
+ {
+ \exp_args:NNe \use:nn \use_none:n
+ { \prg_replicate:nn { \c_@@_block_size_int } { , #4 } }
+ }
+ \@@_save_blocks:nn {#3}
+ { \int_div_truncate:nn { (#2 - #1) } \c_@@_block_size_int }
+ }
+ \prg_replicate:nn
+ { \int_mod:nn { #2 - #1 } \c_@@_block_size_int }
+ { \clist_put_right:ce { l_@@_ #3 _block_clist } {#4} }
+ }
+% \end{macrocode}
+% To allow rapid comparison, each completed block is stored locally as a
+% comma list: once all of the blocks have been created, they are converted
+% into an \texttt{intarray} in one step. The aim here is to check the current
+% block against those we've already used, and either match to an existing
+% block or save a new block.
+% \begin{macrocode}
+ \cs_set_protected:Npn \@@_save_blocks:nn #1#2
+ {
+ \tl_set_eq:Nc \l_@@_matched_block_tl { l_@@_ #1 _block_tl }
+ \int_step_inline:nn { \tl_use:c { l_@@_ #1 _block_tl } - 1 }
+ {
+ \tl_if_eq:ccT { l_@@_ #1 _block_clist }
+ { l_@@_ #1 _block_ ##1 _clist }
+ { \tl_set:Nn \l_@@_matched_block_tl {##1} }
+ }
+ \int_compare:nNnT
+ { \tl_use:c { l_@@_ #1 _block_tl } } = \l_@@_matched_block_tl
+ {
+ \clist_set_eq:cc
+ {
+ l_@@_ #1 _block_
+ \tl_use:c { l_@@_ #1 _block_tl } _clist
+ }
+ { l_@@_ #1 _block_clist }
+ \tl_set:ce { l_@@_ #1 _block_tl }
+ { \int_eval:n { \tl_use:c { l_@@_ #1 _block_tl } + 1 } }
+ }
+ \prg_replicate:nn {#2}
+ {
+ \tl_set:ce { l_@@_ #1 _pos_tl }
+ { \int_eval:n { \tl_use:c { l_@@_ #1 _pos_tl } + 1 } }
+ \exp_args:Nc \__kernel_intarray_gset:Nnn
+ { g_@@_ #1 _index_intarray }
+ { \tl_use:c { l_@@_ #1 _pos_tl } }
+ \l_@@_matched_block_tl
+ }
+ \clist_clear:c { l_@@_ #1 _block_clist }
+ }
+% \end{macrocode}
+% Close out the final block, rename the first stage table, then combine all
+% of the block comma-lists into one large second-stage table with offsets.
+% As we use an index not an offset, there is a little back-and-forward to do.
+% \begin{macrocode}
+ \cs_set_protected:Npn \@@_finalise_blocks:
+ {
+ \clist_map_inline:nn { category , uppercase , lowercase }
+ {
+ \@@_range:nnn { 110000 } {##1} { 0 }
+ \@@_finalise_blocks:n {##1}
+ }
+ }
+ \cs_set_protected:Npn \@@_finalise_blocks:n #1
+ {
+ \cs_gset_eq:cc { c_@@_ #1 _index_intarray } { g_@@_ #1 _index_intarray }
+ \cs_undefine:c { g_@@_ #1 _index_intarray }
+ \intarray_new:cn { g_@@_ #1 _blocks_intarray }
+ { ( \tl_use:c { l_@@_ #1 _block_tl } - 1 ) * \c_@@_block_size_int }
+ \int_step_inline:nn { \tl_use:c { l_@@_ #1 _block_tl } - 1 }
+ {
+ \exp_args:Nv \@@_finalise_blocks:nnn
+ { l_@@_ #1 _block_ ##1 _clist }
+ {##1} {#1}
+ }
+ \cs_gset_eq:cc { c_@@_ #1 _blocks_intarray }
+ { g_@@_ #1 _blocks_intarray }
+ \cs_undefine:c { g_@@_ #1 _blocks_intarray }
+ }
+ \cs_set_protected:Npn \@@_finalise_blocks:nnn #1#2#3
+ {
+ \exp_args:Nnf \@@_finalise_blocks:nnnw { 1 }
+ { \int_eval:n { ( #2 - 1 ) * \c_@@_block_size_int } }
+ {#3}
+ #1 , \q_recursion_tail , \q_recursion_stop
+ }
+ \cs_set_protected:Npn \@@_finalise_blocks:nnnw #1#2#3#4 ,
+ {
+ \quark_if_recursion_tail_stop:n {#4}
+ \intarray_gset:cnn { g_@@_ #3 _blocks_intarray }
+ { #1 + #2 }
+ {#4}
+ \exp_args:Nf \@@_finalise_blocks:nnnw
+ { \int_eval:n { #1 + 1 } } {#2} {#3}
+ }
+% \end{macrocode}
+% With the setup done, read the main data file: it's easiest to do that as
+% a token list with spaces retained.
+% \begin{macrocode}
+ \ior_open:Nn \g_@@_data_ior { UnicodeData.txt }
+ \group_begin:
+ \char_set_catcode_space:n { `\ }%
+ \ior_map_variable:NNn \g_@@_data_ior \l_@@_tmpa_tl
+ {%
+ \if_meaning:w \l_@@_tmpa_tl \c_space_tl
+ \exp_after:wN \ior_map_break:
+ \fi:
+ \exp_after:wN \@@_data_auxi:w \l_@@_tmpa_tl \q_stop
+ }%
+ \@@_finalise_blocks:
+ \group_end:
+\group_end:
+% \end{macrocode}
+%
+% \begin{macro}[EXP]{\__kernel_codepoint_data:nn}
+% \begin{macro}[EXP]{\@@_data:nnn}
+% Recover data from a two-stage table: entirely generic as this applies to
+% all tables (as we use the same block size for all of them). Notice that
+% as we use indices not offsets we have to shuffle out-by-one issues. This
+% function is needed \emph{before} loading the special casing data, as there
+% we need to be able to check the standard case mappings.
+% \begin{macrocode}
+\cs_new:Npn \__kernel_codepoint_data:nn #1#2
+ {
+ \exp_args:Nf \@@_data:nnn
+ {
+ \int_eval:n
+ {
+ \c_@@_block_size_int *
+ (
+ \intarray_item:cn { c_@@_ #1 _index_intarray }
+ {
+ \int_div_truncate:nn {#2}
+ \c_@@_block_size_int
+ + 1
+ }
+ - 1
+ )
+ }
+ }
+ {#2} {#1}
+ }
+\cs_new:Npn \@@_data:nnn #1#2#3
+ {
+ \intarray_item:cn { c_@@_ #3 _blocks_intarray }
+ { #1 + \int_mod:nn {#2} \c_@@_block_size_int + 1 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% The other data files all use C-style comments so we have to worry about
+% |#| tokens (and reading as strings). The set up for case folding is in two
+% parts. For the basic (core) mappings, folding is the same as lower casing in
+% most positions so only store the differences. For the more complex foldings,
+% always store the result, splitting up the two or three code points in the input
+% as required.
+% \begin{macrocode}
+\group_begin:
+ \ior_open:Nn \g_@@_data_ior { CaseFolding.txt }
+ \cs_set_protected:Npn \@@_data_auxi:w #1 ;~ #2 ;~ #3 ; #4 \q_stop
+ {
+ \if:w \tl_head:n { #2 ? } C
+ \reverse_if:N \if_int_compare:w
+ \int_eval:n { \__kernel_codepoint_data:nn { lowercase } {"#1} + "#1 }
+ = "#3 ~
+ \tl_const:ce
+ { c_@@_casefold_ \codepoint_str_generate:n {"#1} _tl }
+ { {"#3} { } { } }
+ \fi:
+ \else:
+ \if:w \tl_head:n { #2 ? } F
+ \@@_data_auxii:w #1 ~ #3 ~ \q_stop
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% Here, |#4| can have a trailing space, so we tidy up a bit at the cost of
+% speed for these small number of cases it applies to.
+% \begin{macrocode}
+ \cs_set_protected:Npn \@@_data_auxii:w #1 ~ #2 ~ #3 ~ #4 \q_stop
+ {
+ \tl_const:ce { c_@@_casefold_ \codepoint_str_generate:n {"#1} _tl }
+ {
+ {"#2}
+ {"#3}
+ { \tl_if_blank:nF {#4} { " \int_to_Hex:n {"#4} } }
+ }
+ }
+ \ior_str_map_inline:Nn \g_@@_data_ior
+ {
+ \reverse_if:N \if:w \c_hash_str \tl_head:w #1 \c_hash_str \q_stop
+ \@@_data_auxi:w #1 \q_stop
+ \fi:
+ }
+ \ior_close:N \g_@@_data_ior
+% \end{macrocode}
+% For upper- and lowercasing special situations, there is a bit more to
+% do as we also have titlecasing to consider, plus we need to stop part-way
+% through the file.
+% \begin{macrocode}
+ \ior_open:Nn \g_@@_data_ior { SpecialCasing.txt }
+ \cs_set_protected:Npn \@@_data_auxi:w
+ #1 ;~ #2 ;~ #3 ;~ #4 ; #5 \q_stop
+ {
+ \use:n { \@@_data_auxii:w #1 ~ lower ~ #2 ~ } ~ \q_stop
+ \use:n { \@@_data_auxii:w #1 ~ upper ~ #4 ~ } ~ \q_stop
+ \str_if_eq:nnF {#3} {#4}
+ { \use:n { \@@_data_auxii:w #1 ~ title ~ #3 ~ } ~ \q_stop }
+ }
+ \cs_set_protected:Npn \@@_data_auxii:w
+ #1 ~ #2 ~ #3 ~ #4 ~ #5 \q_stop
+ {
+ \tl_if_empty:nF {#4}
+ {
+ \tl_const:ce { c_@@_ #2 case_ \codepoint_str_generate:n {"#1} _tl }
+ {
+ {"#3}
+ {"#4}
+ { \tl_if_blank:nF {#5} {"#5} }
+ }
+ }
+ }
+ \ior_str_map_inline:Nn \g_@@_data_ior
+ {
+ \str_if_eq:eeTF { \tl_head:w #1 \c_hash_str \q_stop } { \c_hash_str }
+ {
+ \str_if_eq:eeT
+ {#1}
+ { \c_hash_str \c_space_tl Conditional~Mappings }
+ { \ior_map_break: }
+ }
+ { \@@_data_auxi:w #1 \q_stop }
+ }
+ \ior_close:N \g_@@_data_ior
+\group_end:
+% \end{macrocode}
+%
+% \begin{macro}[EXP]{\__kernel_codepoint_case:nn}
+% \begin{macro}[EXP]{\@@_case:nnn}
+% \begin{macro}[EXP]
+% {\@@_uppercase:n, \@@_lowercase:n, \@@_titlecase:n, \@@_casefold:n}
+% \begin{macro}[EXP]{\@@_case:nn}
+% With the core data files loaded, there is now a need to provide access to
+% this information for other modules. That is done here such that case
+% folding can also be covered. At this level, all that needs to be returned
+% is the
+% \begin{macrocode}
+\cs_new:Npn \__kernel_codepoint_case:nn #1#2
+ {
+ \exp_args:Ne \@@_case:nnn
+ { \codepoint_str_generate:n {#2} } {#1} {#2}
+ }
+\cs_new:Npn \@@_case:nnn #1#2#3
+ {
+ \cs_if_exist:cTF { c_@@_ #2 _ #1 _tl }
+ {
+ \tl_use:c
+ { c_@@_ #2 _ #1 _tl }
+ }
+ { \use:c { @@_ #2 :n } {#3} }
+ }
+\cs_new:Npn \@@_uppercase:n { \@@_case:nn { uppercase } }
+\cs_new:Npn \@@_lowercase:n { \@@_case:nn { lowercase } }
+\cs_new:Npn \@@_titlecase:n { \@@_case:nn { uppercase } }
+\cs_new:Npn \@@_casefold:n { \@@_case:nn { lowercase } }
+\cs_new:Npn \@@_case:nn #1#2
+ {
+ { \int_eval:n { \__kernel_codepoint_data:nn {#1} {#2} + #2 } }
+ { }
+ { }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_nfd:n}
+% \begin{macro}[EXP]{\@@_nfd:nn}
+% A simple interface.
+% \begin{macrocode}
+\cs_new:Npn \@@_nfd:n #1
+ { \exp_args:Ne \@@_nfd:nn { \codepoint_str_generate:n {#1} } {#1} }
+\cs_new:Npn \@@_nfd:nn #1#2
+ {
+ \tl_if_exist:cTF { c_@@_nfd_ #1 _tl }
+ { \tl_use:c { c_@@_nfd_ #1 _tl } }
+ { {#2} { } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%<@@=text>
+% \end{macrocode}
+%
+% Read the Unicode grapheme data. This is quite easy to handle and we only need
+% codepoints, not characters, so there is no need to worry about the engine in use.
+% As reading as a string is most convenient, we have to do some work to remove
+% spaces: the hardest part of the entire process!
+% \begin{macrocode}
+\ior_new:N \g_@@_data_ior
+\group_begin:
+ \ior_open:Nn \g_@@_data_ior { GraphemeBreakProperty.txt }
+ \cs_set_nopar:Npn \l_@@_tmpa_str { }
+ \cs_set_nopar:Npn \l_@@_tmpb_str { }
+ \cs_set_protected:Npn \@@_data_auxi:w #1 ;~ #2 ~ #3 \q_stop
+ {
+ \str_if_eq:VnF \l_@@_tmpb_str {#2}
+ {
+ \str_if_empty:NF \l_@@_tmpb_str
+ {
+ \clist_const:ce { c_@@_grapheme_ \l_@@_tmpb_str _clist }
+ { \exp_after:wN \use_none:n \l_@@_tmpa_str }
+ \cs_set_nopar:Npn \l_@@_tmpa_str { }
+ }
+ \cs_set_nopar:Npn \l_@@_tmpb_str {#2}
+ }
+ \@@_data_auxii:w #1 .. #1 .. #1 \q_stop
+ }
+ \cs_set_protected:Npn \@@_data_auxii:w #1 .. #2 .. #3 \q_stop
+ {
+ \cs_set_nopar:Npe \l_@@_tmpa_str
+ {
+ \l_@@_tmpa_str ,
+ \tl_trim_spaces:n {#1} .. \tl_trim_spaces:n {#2}
+ }
+ }
+ \ior_str_map_inline:Nn \g_@@_data_ior
+ {
+ \str_if_eq:eeF { \tl_head:w #1 \c_hash_str \q_stop } { \c_hash_str }
+ {
+ \tl_if_blank:nF {#1}
+ { \@@_data_auxi:w #1 \q_stop }
+ }
+ }
+ \ior_close:N \g_@@_data_ior
+\group_end:
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/macros/latex-dev/required/l3kernel/source3.pdf b/macros/latex-dev/required/l3kernel/source3.pdf
new file mode 100644
index 0000000000..a88cd68030
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/source3.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/source3.tex b/macros/latex-dev/required/l3kernel/source3.tex
new file mode 100644
index 0000000000..f0aaeb20c8
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/source3.tex
@@ -0,0 +1,106 @@
+\iffalse meta-comment
+
+File: source3.tex
+
+Copyright (C) 1990-2012,2017-2024 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this
+license or (at your option) any later version. The latest version
+of this license is in the file
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3kernel bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+The released version of this bundle is available from CTAN.
+
+-----------------------------------------------------------------------
+
+The development version of the bundle can be found at
+
+ https://github.com/latex3/latex3
+
+for those people who are interested.
+
+\fi
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% This document typesets the LaTeX3 sources as a single document.
+% This produces quite a large file (more than 1670 pages as of Dec 2023).
+%
+% There is also a shorter version (interface3.tex) that only typesets the
+% command % interface descriptions.
+%
+% Do not forget to generate the index (as explained on the terminal output
+% near the end of the run)!
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\documentclass[kernel]{l3doc}
+
+\newif\ifinterface
+\interfacefalse
+
+\listfiles
+
+\begin{document}
+
+\title{The \LaTeX3 Sources}
+\author{%
+ The \LaTeX{} Project\thanks
+ {%
+ E-mail:
+ \href{mailto:latex-team@latex-project.org}
+ {latex-team@latex-project.org}%
+ }%
+}
+\date{Released 2024-04-11}
+
+\pagenumbering{roman}
+\maketitle
+
+%
+% First load all modules and typeset the documentation parts
+%
+
+\input{source3body} % all the individual modules
+
+%
+% Now reload all modules and typeset the implementation parts
+%
+
+\part{Implementation}
+
+\def\maketitle{}
+\let\subsubsection\subsection
+\let\subsection\section
+\let\section\chapter
+
+\EnableImplementation
+\DisableDocumentation
+\DocInputAgain
+
+\clearpage
+\pagestyle{headings}
+
+% Make TeX shut up.
+\hbadness=10000
+\newcount\hbadness
+\hfuzz=\maxdimen
+
+\PrintChanges
+\clearpage
+
+\begingroup
+ \def\endash{--}
+ \catcode`\-\active
+ \def-{\futurelet\temp\indexdash}
+ \def\indexdash{\ifx\temp-\endash\fi}
+
+ \DelayPrintIndex
+\endgroup
+
+\end{document}
diff --git a/macros/latex-dev/required/l3kernel/source3body.tex b/macros/latex-dev/required/l3kernel/source3body.tex
new file mode 100644
index 0000000000..8471296227
--- /dev/null
+++ b/macros/latex-dev/required/l3kernel/source3body.tex
@@ -0,0 +1,620 @@
+\iffalse meta-comment
+
+File: source3body.tex
+
+Copyright (C) 1990-2012,2014-2023 The LaTeX Project
+
+It may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this
+license or (at your option) any later version. The latest version
+of this license is in the file
+
+ https://www.latex-project.org/lppl.txt
+
+This file is part of the "l3kernel bundle" (The Work in LPPL)
+and all files in that bundle must be distributed together.
+
+The released version of this bundle is available from CTAN.
+
+-----------------------------------------------------------------------
+
+The development version of the bundle can be found at
+
+ https://github.com/latex3/latex3
+
+for those people who are interested.
+
+\fi
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% This file is used by
+%
+% source3.tex % documentation including implementation
+%
+% interface3.tex % only interface documentation
+%
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\begin{abstract}
+
+\setlength\parindent{0pt}
+\setlength\parskip{\baselineskip}
+
+\noindent
+\ifinterface
+This is the reference documentation for the \pkg{expl3}
+programming environment; see the matching \pkg{source3} PDF
+for the typeset sources.
+\else
+This is the typset sources for the \pkg{expl3}
+programming environment; see the matching \pkg{interface3} PDF
+for the API reference manual.
+\fi
+The \pkg{expl3} modules set up a
+naming scheme for \LaTeX{} commands, which allow the \LaTeX{} programmer
+to systematically name functions and variables, and specify the argument
+types of functions.
+
+The \TeX{} and \eTeX{} primitives are all given a new name according to
+these conventions. However, in the main direct use of the primitives is
+not required or encouraged: the \pkg{expl3} modules define an
+independent low-level \LaTeX3 programming language.
+
+The \pkg{expl3} modules are designed to be loaded on top of
+\LaTeXe{}. With an up-to-date \LaTeXe{} kernel, this material is loaded
+as part of the format. The fundamental programming code can also be loaded
+with other \TeX{} formats, subject to restrictions on the full range of
+functionality.
+
+\end{abstract}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Each of the following \DocInput lines includes a file with extension
+% .dtx. Each of these files may be typeset separately. For instance
+% pdflatex l3box.dtx
+% will typeset the source of the LaTeX3 box commands. If you use the
+% Makefile, the index will be generated automatically; e.g.,
+% make doc F=l3box
+%
+% If this file is processed, each of these separate dtx files will be
+% contained as a part of a single document.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\makeatletter
+% l3doc is based on article, but for these very large documents we need
+% chapters; the code is based on the standard classes but somewhat simplified
+\renewcommand\part{%
+ \clearpage
+ \thispagestyle{plain}%
+ \@tempswafalse
+ \null\vfil
+ \secdef\@part\@spart}
+\newcounter {chapter}
+\numberwithin{section}{chapter}
+\renewcommand \thechapter {\@arabic\c@chapter}
+\renewcommand \thesection {\thechapter.\@arabic\c@section}
+\newcommand*\chaptermark[1]{}
+\setcounter{secnumdepth}{2}
+\newcommand\@chapapp{\chaptername}
+\newcommand\chaptername{Chapter}
+ \def\ps@headings{%
+ \let\@oddfoot\@empty
+ \def\@oddhead{{\slshape\rightmark}\hfil\thepage}%
+ \let\@mkboth\markboth
+ \def\chaptermark##1{%
+ \markright {\MakeUppercase{%
+ \ifnum \c@secnumdepth >\m@ne
+ \@chapapp\ \thechapter. \ %
+ \fi
+ ##1}}}}
+\newcommand\chapter{\clearpage
+ \thispagestyle{plain}%
+ \global\@topnum\z@
+ \@afterindentfalse
+ \secdef\@chapter\@schapter}
+\def\@chapter[#1]#2{\refstepcounter{chapter}%
+ \typeout{\@chapapp\space\thechapter.}%
+ \addcontentsline{toc}{chapter}%
+ {\protect\numberline{\thechapter}#1}%
+ \chaptermark{#1}%
+ \addtocontents{lof}{\protect\addvspace{10\p@}}%
+ \addtocontents{lot}{\protect\addvspace{10\p@}}%
+ \@makechapterhead{#2}%
+ \@afterheading}
+\def\@makechapterhead#1{%
+ \vspace*{50\p@}%
+ {\parindent \z@ \raggedright \normalfont
+ \huge\bfseries \@chapapp\space \thechapter
+ \par\nobreak
+ \vskip 20\p@
+ \interlinepenalty\@M
+ \Huge \bfseries #1\par\nobreak
+ \vskip 40\p@
+ }}
+\newcommand*\l@chapter[2]{%
+ \ifnum \c@tocdepth >\m@ne
+ \addpenalty{-\@highpenalty}%
+ \vskip 1.0em \@plus\p@
+ \setlength\@tempdima{1.5em}%
+ \begingroup
+ \parindent \z@ \rightskip \@pnumwidth
+ \parfillskip -\@pnumwidth
+ \leavevmode \bfseries
+ \advance\leftskip\@tempdima
+ \hskip -\leftskip
+ #1\nobreak\hfil
+ \nobreak\hb@xt@\@pnumwidth{\hss #2%
+ \kern-\p@\kern\p@}\par
+ \penalty\@highpenalty
+ \endgroup
+ \fi}
+\renewcommand*\l@section{\@dottedtocline{1}{1.5em}{2.8em}}
+\renewcommand*\l@subsection{\@dottedtocline{2}{3.8em}{3.2em}}
+\renewcommand*\l@subsubsection{\@dottedtocline{3}{7.0em}{4.1em}}
+\def\partname{Part}
+\def\toclevel@part{-1}
+\def\maketitle{\chapter{\@title}}
+\let\thanks\@gobble
+\let\DelayPrintIndex\PrintIndex
+\let\PrintIndex\@empty
+\providecommand*{\hexnum}[1]{\text{\texttt{\char`\"}#1}}
+\makeatother
+
+\clearpage
+
+{%
+ \def\\{:}% fix "newlines" in the ToC
+ \tableofcontents
+}
+
+\clearpage
+\pagenumbering{arabic}
+
+\part{Introduction}
+
+\chapter{Introduction to \pkg{expl3} and this document}
+
+This document is intended to act as a comprehensive reference manual
+for the \pkg{expl3} language. A general guide to the \LaTeX3
+programming language is found in \href{expl3.pdf}{expl3.pdf}.
+
+\section{Naming functions and variables}
+
+\LaTeX3 does not use \texttt{@} as a \enquote{letter} for defining
+internal macros. Instead, the symbols |_| and \texttt{:}
+are used in internal macro names to provide structure. The name of
+each \emph{function} is divided into logical units using \texttt{_},
+while \texttt{:} separates the \emph{name} of the function from the
+\emph{argument specifier} (\enquote{arg-spec}). This describes the arguments
+expected by the function. In most cases, each argument is represented
+by a single letter. The complete list of arg-spec letters for a function
+is referred to as the \emph{signature} of the function.
+
+Each function name starts with the \emph{module} to which it belongs.
+Thus apart from a small number of very basic functions, all \pkg{expl3}
+function names contain at least one underscore to divide the module
+name from the descriptive name of the function. For example, all
+functions concerned with comma lists are in module \texttt{clist} and
+begin |\clist_|.
+
+Every function must include an argument specifier. For functions which
+take no arguments, this will be blank and the function name will end
+\texttt{:}. Most functions take one or more arguments, and use the
+following argument specifiers:
+\begin{description}
+ \item[\texttt{N} and \texttt{n}] These mean \emph{no manipulation},
+ of a single token for \texttt{N} and of a set of tokens given in
+ braces for \texttt{n}. Both pass the argument through exactly as
+ given. Usually, if you use a single token for an \texttt{n} argument,
+ all will be well.
+ \item[\texttt{c}] This means \emph{csname}, and indicates that the
+ argument will be turned into a csname before being used. So
+ |\foo:c| |{ArgumentOne}| will act in the same way as |\foo:N|
+ |\ArgumentOne|. All macros that appear in the argument are expanded.
+ An internal error will occur if the result of expansion inside
+ a \texttt{c}-type argument is not a series of character tokens.
+ \item[\texttt{V} and \texttt{v}] These mean \emph{value
+ of variable}. The \texttt{V} and \texttt{v} specifiers are used to
+ get the content of a variable without needing to worry about the
+ underlying \TeX{} structure containing the data. A \texttt{V}
+ argument will be a single token (similar to \texttt{N}), for example
+ |\foo:V| |\MyVariable|; on the other hand, using \texttt{v} a
+ csname is constructed first, and then the value is recovered, for
+ example |\foo:v| |{MyVariable}|.
+ \item[\texttt{o}] This means \emph{expansion once}. In general, the
+ \texttt{V} and \texttt{v} specifiers are favoured over \texttt{o}
+ for recovering stored information. However, \texttt{o} is useful
+ for correctly processing information with delimited arguments.
+ \item[\texttt{x}] The \texttt{x} specifier stands for \emph{exhaustive
+ expansion}: every token in the argument is fully expanded until only
+ unexpandable ones remain. The \TeX{} \tn{edef} primitive carries out
+ this type of expansion. Functions which feature an \texttt{x}-type
+ argument are \emph{not} expandable.
+ \item[\texttt{e}] The \texttt{e} specifier is in many respects
+ identical to \texttt{x}, but uses \tn{expanded} primitive.
+ Parameter character (usually~|#|) in the argument need not be doubled.
+ Functions which feature an \texttt{e}-type argument may be
+ expandable.
+ \item[\texttt{f}] The \texttt{f} specifier stands for \emph{full
+ expansion}, and in contrast to \texttt{x} stops at the first
+ non-expandable token (reading the argument from left to right) without
+ trying to expand it. If this token is a \meta{space token}, it is gobbled,
+ and thus won't be part of the resulting argument. For example, when
+ setting a token list variable (a macro used for storage), the sequence
+ \begin{verbatim}
+ \tl_set:Nn \l_mya_tl { A }
+ \tl_set:Nn \l_myb_tl { B }
+ \tl_set:Nf \l_mya_tl { \l_mya_tl \l_myb_tl }
+ \end{verbatim}
+ will leave |\l_mya_tl| with the content |A\l_myb_tl|, as |A| cannot
+ be expanded and so terminates expansion before |\l_myb_tl| is considered.
+ \item[\texttt{T} and \texttt{F}] For logic tests, there are the branch
+ specifiers \texttt{T} (\emph{true}) and \texttt{F} (\emph{false}).
+ Both specifiers treat the input in the same way as \texttt{n} (no
+ change), but make the logic much easier to see.
+ \item[\texttt{p}] The letter \texttt{p} indicates \TeX{}
+ \emph{parameters}. Normally this will be used for delimited
+ functions as \pkg{expl3} provides better methods for creating simple
+ sequential arguments.
+ \item[\texttt{w}] Finally, there is the \texttt{w} specifier for
+ \emph{weird} arguments. This covers everything else, but mainly
+ applies to delimited values (where the argument must be terminated
+ by some specified string).
+ \item[\texttt{D}] The \texttt{D} stands for \textbf{Do not use}.
+ All of the \TeX{} primitives are initially \cs[no-index]{let} to a \texttt{D}
+ name, and some are then given a second name.
+ These functions have no standardized syntax, they are engine
+ dependent and their name can change without warning, thus their
+ use is \emph{strongly discouraged} in package code: programmers
+ should instead use the interfaces documented in
+ \ifinterface
+ this documentation.
+ \else
+ \href{interface3.pdf}{interface3.pdf}.
+ \fi
+\end{description}
+Notice that the argument specifier describes how the argument is
+processed prior to being passed to the underlying function. For example,
+|\foo:c| will take its argument, convert it to a control sequence and
+pass it to |\foo:N|.
+
+Variables are named in a similar manner to functions, but begin with
+a single letter to define the type of variable:
+\begin{description}
+ \item[\texttt{c}] Constant: global parameters whose value should not
+ be changed.
+ \item[\texttt{g}] Parameters whose value should only be set globally.
+ \item[\texttt{l}] Parameters whose value should only be set locally.
+\end{description}
+Each variable name is then build up in a similar way to that of a
+function, typically starting with the module\footnote{The module names are
+ not used in case of generic scratch registers defined in the data
+ type modules, e.g., the
+ \texttt{int} module contains some scratch variables called \cs{l_tmpa_int},
+ \cs{l_tmpb_int}, and so on. In such a case adding the module name up front
+ to denote the module
+ and in the back to indicate the type, as in
+ \texttt{\string\l_int_tmpa_int} would be very unreadable.} name
+and then a descriptive part.
+Variables end with a short identifier to show the variable type:
+\begin{description}%
+ \item[\texttt{bitset}] a set of bits (a string made up of a series of \texttt{0}
+ and \texttt{1} tokens that are accessed by position).
+ \item[\texttt{clist}] Comma separated list.
+ \item[\texttt{dim}] \enquote{Rigid} lengths.
+ \item[\texttt{fp}] Floating-point values;
+ \item[\texttt{int}] Integer-valued count register.
+ \item[\texttt{muskip}] \enquote{Rubber} lengths for use in
+ mathematics.
+ \item[\texttt{skip}] \enquote{Rubber} lengths.
+ \item[\texttt{str}] String variables: contain character data.
+ \item[\texttt{tl}] Token list variables: placeholder for a token list.
+\end{description}
+Applying \texttt{V}-type or \texttt{v}-type expansion to variables of
+one of the above types is supported, while it is not supported for the
+following variable types:
+\begin{description}
+ \item[\texttt{bool}] Either true or false.
+ \item[\texttt{box}] Box register.
+ \item[\texttt{coffin}] A \enquote{box with handles} --- a higher-level
+ data type for carrying out \texttt{box} alignment operations.
+ \item[\texttt{flag}] Non-negative integer that can be incremented expandably.
+ \item[\texttt{fparray}] Fixed-size array of floating point values.
+ \item[\texttt{intarray}] Fixed-size array of integers.
+ \item[\texttt{ior}/\texttt{iow}] An input or output stream, for
+ reading from or writing to, respectively.
+ \item[\texttt{prop}] Property list: analogue of dictionary or
+ associative arrays in other languages.
+ \item[\texttt{regex}] Regular expression.
+ \item[\texttt{seq}] \enquote{Sequence}: a data type used to implement
+ lists (with access at both ends) and stacks.
+\end{description}
+
+\subsection{Scratch variables}
+
+Modules focussed on variable usage typically provide four scratch variables,
+two local and two global, with names of the form
+\cs[no-index]{\meta{scope}_tmpa_\meta{type}}/\cs[no-index]{\meta{scope}_tmpb_\meta{type}}. These
+are never used by the core code. The nature of \TeX{} grouping means that as
+with any other scratch variable, these should only be set and used with no
+intervening third-party code.
+
+\subsection{Terminological inexactitude}
+
+A word of warning. In this document, and others referring to the \pkg{expl3}
+programming modules, we often refer to \enquote{variables} and
+\enquote{functions} as if they
+were actual constructs from a real programming language. In truth, \TeX{}
+is a macro processor, and functions are simply macros that may or may not take
+arguments and expand to their replacement text. Many of the common variables
+are \emph{also} macros, and if placed into the input stream will simply expand
+to their definition as well~--- a \enquote{function} with no arguments and a
+\enquote{token list variable} are almost the same.\footnote{\TeX{}nically,
+functions with no arguments are \tn{long} while token list variables are not.}
+On the other
+hand, some \enquote{variables} are actually registers that must be
+initialised and their values set and retrieved with specific functions.
+
+The conventions of the \pkg{expl3} code are designed to clearly separate the
+ideas of \enquote{macros that contain data} and
+\enquote{macros that contain code}, and a
+consistent wrapper is applied to all forms of \enquote{data} whether they be
+macros or
+actually registers. This means that sometimes we will use phrases like
+\enquote{the function returns a value}, when actually we just mean
+\enquote{the macro expands to something}. Similarly, the term
+\enquote{execute} might be used in place of \enquote{expand}
+or it might refer to the more specific case of
+\enquote{processing in \TeX's stomach}
+(if you are familiar with the \TeX{}book parlance).
+
+If in doubt, please ask; chances are we've been hasty in writing certain
+definitions and need to be told to tighten up our terminology.
+
+\section{Documentation conventions}
+
+This document is typeset with the experimental \pkg{l3doc} class;
+several conventions are used to help describe the features of the code.
+A number of conventions are used here to make the documentation clearer.
+
+Each group of related functions is given in a box. For a function with
+a \enquote{user} name, this might read:
+\begin{function}[label = ]{\ExplSyntaxOn, \ExplSyntaxOff}
+ \begin{syntax}
+ |\ExplSyntaxOn| \dots{} |\ExplSyntaxOff|
+ \end{syntax}
+ The textual description of how the function works would appear here. The
+ syntax of the function is shown in mono-spaced text to the right of
+ the box. In this example, the function takes no arguments and so the
+ name of the function is simply reprinted.
+\end{function}
+
+For programming functions, which use \texttt{_} and \texttt{:} in their name
+there are a few additional conventions: If two related functions are given
+with identical names but different argument specifiers, these are termed
+\emph{variants} of each other, and the latter functions are printed in grey to
+show this more clearly. They will carry out the same function but will take
+different types of argument:
+\begin{function}[label = ]{\seq_new:N, \seq_new:c}
+ \begin{syntax}
+ |\seq_new:N| \meta{sequence}
+ \end{syntax}
+ When a number of variants are described, the arguments are usually
+ illustrated only for the base function. Here, \meta{sequence} indicates
+ that |\seq_new:N| expects the name of a sequence. From the argument
+ specifier, |\seq_new:c| also expects a sequence name, but as a
+ name rather than as a control sequence. Each argument given in the
+ illustration should be described in the following text.
+\end{function}
+
+\paragraph{Fully expandable functions}
+\hypertarget{expstar}{Some functions are fully expandable},
+which allows them to be used within
+an \texttt{x}-type or \texttt{e}-type argument (in plain \TeX{} terms, inside an \tn{edef} or \tn{expanded}),
+as well as within an \texttt{f}-type argument.
+These fully expandable functions are indicated in the documentation by
+a star:
+\begin{function}[EXP, label = ]{\cs_to_str:N}
+ \begin{syntax}
+ |\cs_to_str:N| \meta{cs}
+ \end{syntax}
+ As with other functions, some text should follow which explains how
+ the function works. Usually, only the star will indicate that the
+ function is expandable. In this case, the function expects a \meta{cs},
+ shorthand for a \meta{control sequence}.
+\end{function}
+
+\paragraph{Restricted expandable functions}
+\hypertarget{rexpstar}{A few functions are fully expandable} but cannot be fully expanded within
+an \texttt{f}-type argument. In this case a hollow star is used to indicate
+this:
+\begin{function}[rEXP, label = ]{\seq_map_function:NN}
+ \begin{syntax}
+ |\seq_map_function:NN| \meta{seq} \meta{function}
+ \end{syntax}
+\end{function}
+
+\paragraph{Conditional functions}
+\hypertarget{explTF}{Conditional (\texttt{if}) functions}
+are normally defined in three variants, with
+\texttt{T}, \texttt{F} and \texttt{TF} argument specifiers. This allows
+them to be used for different \enquote{true}/\enquote{false} branches,
+depending on
+which outcome the conditional is being used to test. To indicate this
+without repetition, this information is given in a shortened form:
+\begin{function}[EXP,TF, label = ]{\sys_if_engine_xetex:}
+ \begin{syntax}
+ |\sys_if_engine_xetex:TF| \Arg{true code} \Arg{false code}
+ \end{syntax}
+ The underlining and italic of \texttt{TF} indicates that three functions
+ are available:
+ \begin{itemize}
+ \item |\sys_if_engine_xetex:T|
+ \item |\sys_if_engine_xetex:F|
+ \item |\sys_if_engine_xetex:TF|
+ \end{itemize}
+ Usually, the illustration
+ will use the \texttt{TF} variant, and so both \meta{true code}
+ and \meta{false code} will be shown. The two variant forms \texttt{T} and
+ \texttt{F} take only \meta{true code} and \meta{false code}, respectively.
+ Here, the star also shows that this function is expandable.
+ With some minor exceptions, \emph{all} conditional functions in the
+ \pkg{expl3} modules should be defined in this way.
+\end{function}
+
+Variables, constants and so on are described in a similar manner:
+\begin{variable}[label = ]{\l_tmpa_tl}
+ A short piece of text will describe the variable: there is no
+ syntax illustration in this case.
+\end{variable}
+
+In some cases, the function is similar to one in \LaTeXe{} or plain \TeX{}.
+In these cases, the text will include an extra \enquote{\textbf{\TeX{}hackers
+note}} section:
+\begin{function}[EXP, label = ]{\token_to_str:N}
+ \begin{syntax}
+ |\token_to_str:N| \meta{token}
+ \end{syntax}
+ The normal description text.
+ \begin{texnote}
+ Detail for the experienced \TeX{} or \LaTeXe\ programmer. In this
+ case, it would point out that this function is the \TeX{} primitive
+ |\string|.
+ \end{texnote}
+\end{function}
+
+\paragraph{Changes to behaviour}
+When new functions are added to \pkg{expl3}, the date of first inclusion is
+given in the documentation. Where the documented behaviour of a function
+changes after it is first introduced, the date of the update will also be
+given. This means that the programmer can be sure that any release of
+\pkg{expl3} after the date given will contain the function of interest with
+expected behaviour as described. Note that changes to code internals, including
+bug fixes, are not recorded in this way \emph{unless} they impact on the
+expected behaviour.
+
+\section{Formal language conventions which apply generally}
+
+As this is a formal reference guide for \LaTeX3 programming, the descriptions
+of functions are intended to be reasonably \enquote{complete}. However, there
+is also a need to avoid repetition. Formal ideas which apply to general
+classes of function are therefore summarised here.
+
+For tests which have a \texttt{TF} argument specification, the test if
+evaluated to give a logically \texttt{TRUE} or \texttt{FALSE} result.
+Depending on this result, either the \meta{true code} or the \meta{false code}
+will be left in the input stream. In the case where the test is expandable,
+and a predicate (|_p|) variant is available, the logical value determined by
+the test is left in the input stream: this will typically be part of a larger
+logical construct.
+
+\section{\TeX{} concepts not supported by \LaTeX3{}}
+
+The \TeX{} concept of an \enquote{\tn{outer}} macro is \emph{not supported}
+at all by \LaTeX3{}. As such, the functions provided here may break when
+used on top of \LaTeXe{} if \tn{outer} tokens are used in the arguments.
+
+\DisableImplementation
+
+\part{Bootstrapping}
+
+\DocInput{l3bootstrap.dtx}
+\DocInput{l3names.dtx}
+\ExplSyntaxOn
+\clist_gput_right:Nn \g_docinput_clist { l3kernel-functions.dtx }
+\ExplSyntaxOff
+
+\part{Programming Flow}
+
+\DocInput{l3basics.dtx}
+\DocInput{l3expan.dtx}
+\DocInput{l3sort.dtx}
+\DocInput{l3tl-analysis.dtx}
+\DocInput{l3regex.dtx}
+\DocInput{l3prg.dtx}
+\DocInput{l3sys.dtx}
+\DocInput{l3msg.dtx}
+\DocInput{l3file.dtx}
+
+\DocInput{l3luatex.dtx}
+
+\DocInput{l3legacy.dtx}
+
+
+\part{Data types}
+
+\DocInput{l3tl.dtx}
+\DocInput{l3tl-build.dtx}
+\DocInput{l3str.dtx}
+\DocInput{l3str-convert.dtx}
+\DocInput{l3quark.dtx}
+\DocInput{l3seq.dtx}
+\DocInput{l3int.dtx}
+\DocInput{l3flag.dtx}
+\DocInput{l3clist.dtx}
+\DocInput{l3token.dtx}
+\DocInput{l3prop.dtx}
+\DocInput{l3skip.dtx}
+\DocInput{l3keys.dtx}
+\DocInput{l3intarray.dtx}
+\DocInput{l3fp.dtx}
+% To get the various submodules of l3fp to appear in the implementation
+% part only, they have to be added to the documentation list after typesetting
+% the 'user' part just for the main module.
+\ExplSyntaxOn
+\clist_gput_right:Nn \g_docinput_clist
+ {
+ l3fp-aux.dtx ,
+ l3fp-traps.dtx ,
+ l3fp-round.dtx ,
+ l3fp-parse.dtx ,
+ l3fp-assign.dtx ,
+ l3fp-logic.dtx ,
+ l3fp-basics.dtx ,
+ l3fp-extended.dtx ,
+ l3fp-expo.dtx ,
+ l3fp-trig.dtx ,
+ l3fp-convert.dtx ,
+ l3fp-random.dtx ,
+ l3fp-types.dtx ,
+ l3fp-symbolic.dtx ,
+ l3fp-functions.dtx
+ }
+\ExplSyntaxOff
+
+\DocInput{l3fparray.dtx}
+\DocInput{l3bitset.dtx}
+\DocInput{l3cctab.dtx}
+
+\part{Text manipulation}
+
+\DocInput{l3unicode.dtx}
+\DocInput{l3text.dtx}
+\ExplSyntaxOn
+\clist_gput_right:Nn \g_docinput_clist
+ {
+ l3text-case.dtx ,
+ l3text-map.dtx ,
+ l3text-purify.dtx
+ }
+\ExplSyntaxOff
+
+\part{Typesetting}
+
+\DocInput{l3box.dtx}
+\DocInput{l3coffins.dtx}
+\DocInput{l3color.dtx}
+\DocInput{l3pdf.dtx}
+
+% implementation part only
+\ExplSyntaxOn
+\clist_gput_right:Nn \g_docinput_clist { l3deprecation.dtx }
+\clist_gput_right:Nn \g_docinput_clist { l3debug.dtx }
+\ExplSyntaxOff
+
+\endinput
diff --git a/macros/latex/contrib/acmart/README b/macros/latex/contrib/acmart/README
index f72ea3b2bf..9ed398e5aa 100644
--- a/macros/latex/contrib/acmart/README
+++ b/macros/latex/contrib/acmart/README
@@ -12,13 +12,17 @@ The production version is the one on CTAN and ACM sites.
Changes
-Version 2.05. Changed title for TELO.
+Version 2.06. Added eISSN for a number of journals.
+ ACM no longer collects or prints authors'
+ postal addresses
-Version 2.04. Compatibility with the new latex-dev format
+Version 2.05 Changed title for TELO.
+
+Version 2.04 Compatibility with the new latex-dev format
eSSN is always printed, even if pSSN is present
Wording change in copyright statement
-Version 2.03. Cleaned generation of samples.
+Version 2.03 Cleaned generation of samples.
New options for printing conference proceedings
in ACM journals
diff --git a/macros/latex/contrib/acmart/acmart.dtx b/macros/latex/contrib/acmart/acmart.dtx
index c9d253b955..8516651ee4 100644
--- a/macros/latex/contrib/acmart/acmart.dtx
+++ b/macros/latex/contrib/acmart/acmart.dtx
@@ -635,15 +635,12 @@
% \author{Ben Trovato}
% \additionalaffiliation{%
% \institution{The Th{\o}rv{\"a}ld Group}
-% \streetaddress{1 Th{\o}rv{\"a}ld Circle}
% \city{Hekla}
% \country{Iceland}}
% \affiliation{%
% \institution{Institute for Clarity in Documentation}
-% \streetaddress{P.O. Box 1212}
% \city{Dublin}
-% \state{Ohio}
-% \postcode{43017-6221}}
+% \state{Ohio}}
% \end{verbatim}
% Here Trovato and Tobin share their affiliation with the Institute
% for Clarity in Documentation, but only Ben Trovato is affiliated
@@ -653,16 +650,14 @@
% \DescribeMacro{\position}%
% \DescribeMacro{\institution}%
% \DescribeMacro{\department}%
-% \DescribeMacro{\streetaddress}%
% \DescribeMacro{\city}%
% \DescribeMacro{\state}%
-% \DescribeMacro{\postcode}%
% \DescribeMacro{\country}%
% The \cs{affiliation} and \cs{additionalaffiliation} commands are
% further structured to interact with the metadata extraction tools.
% Inside these commands you should use the \cs{position},
-% \cs{institution}, \cs{department}, \cs{city}, \cs{streetaddress},
-% \cs{state}, \cs{postcode} and \cs{country} macros to indicate the
+% \cs{institution}, \cs{department}, \cs{city},
+% \cs{state}, and \cs{country} macros to indicate the
% corresponding parts of the affiliation. Note that in some cases
% (for example, journals) these parts are not printed in the resulting
% copy, but they \emph{are} necessary since they are used by the XML
@@ -675,6 +670,11 @@
% issued. Currently the absence of \cs{country} produces an error;
% ACM may change this in the future.
%
+% Starting 2024, ACM no longer collects or print postal addresses of
+% the authors. Thus the commands \cs{streetaddress} and
+% \cs{postcode}, present in the previous versions of the class, now
+% produce a warining.
+%
%
% An example of the author block:
% \begin{verbatim}
@@ -683,10 +683,8 @@
% \affiliation{%
% \institution{University of New South Wales}
% \department{School of Biomedical Engineering}
-% \streetaddress{Samuels Building (F25), Kensington Campus}
% \city{Sidney}
% \state{NSW}
-% \postcode{2052}
% \country{Australia}}
% \email{author@nsw.au.edu}
% \author{A. N. Other}
@@ -737,51 +735,6 @@
% \end{verbatim}
%
%
-% The command \cs{affiliation} formats its output according to
-% American conventions. This might be wrong for some cases.
-% Consider, for example, a German address. In Germany, the postcode is
-% put before the city and is not separated by a comma. We can handle this
-% order using
-% \begin{verbatim}
-% \affiliation{%
-% \institution{Fluginstitut}
-% \streetaddress{Sonnenallee 17}
-% \postcode{123456}
-% \city{Helm}
-% \country{Germany}}
-% \end{verbatim}
-% However, the comma after the postcode is unfortunate: the address will
-% be typeset (in some formats) as
-% \begin{verbatim}
-% Fluginstitut
-% Sonenallee 17
-% 123456, Helm, Germany
-% \end{verbatim}
-%
-%
-% To overcome this problem, the command \cs{affiliation} has an
-% optional parameter |obeypunctuation|, which can be |false| (the
-% default) or |true|. If this parameter is |true|, \cs{afffiliation}
-% obeys the author's command. Thus
-% \begin{verbatim}
-% \affiliation[obeypunctuation=true]{%
-% \institution{Fluginstitut}\\
-% \streetaddress{Sonnenallee 17}\\
-% \postcode{123456}
-% \city{Helm},
-% \country{Germany}}
-% \end{verbatim}
-% will be typeset as
-% \begin{verbatim}
-% Fluginstitut
-% Sonenallee 17
-% 123456 Helm, Germany
-% \end{verbatim}
-%
-% Note that you should \emph{not} use this option for journals.
-%
-% It is expected that these commands are inserted by the author of the
-% manuscript.
%
% \DescribeMacro{\thanks}%
% Like |amsart| (and unlike standard \LaTeX{}), we allow
@@ -2309,7 +2262,7 @@
\ProvidesFile{acmart.dtx}
%</gobble>
%<class>\ProvidesClass{acmart}
-[2024/04/03 v2.05 Typesetting articles for the Association for Computing Machinery]
+[2024/04/13 v2.06 Typesetting articles for the Association for Computing Machinery]
% \end{macrocode}
%
% \changes{v1.00}{2016/04/14}{First released version}
@@ -4392,6 +4345,7 @@
% \changes{1.89}{2023/03/25}{Added TOPML}
% \changes{1.90}{2023/03/30}{Added TOPML eISSN}
% \changes{2.05}{2024/04/04}{New data for TELO}
+% \changes{2.06}{2024/04/13}{Added eISSN for a number of journals}
%
% We use the |xkeyval| interface to define journal titles and the relevant
% information
@@ -4456,9 +4410,9 @@
TOMPECS,%
TOMS,%
TOPC,%
- TOPS,%
TOPLAS,%
TOPML,%
+ TOPS,%
TORS,%
TOS,%
TOSEM,%
@@ -4476,6 +4430,7 @@
\def\@journalName{ACM Journal on Computing and Sustainable Societies}%
\def\@journalNameShort{ACM J. Comput. Sustain. Soc.}%
\def\@permissionCodeOne{2834-5533}%
+ \def\@permissionCodeTwo{2834-5533}%
\or % CIE
\def\@journalName{ACM Computers in Entertainment}%
\def\@journalNameShort{ACM Comput. Entertain.}%
@@ -4484,18 +4439,22 @@
\def\@journalName{ACM Computing Surveys}%
\def\@journalNameShort{ACM Comput. Surv.}%
\def\@permissionCodeOne{0360-0300}%
+ \def\@permissionCodeTwo{1557-7341}%
\or % DGOV
\def\@journalName{Digital Government: Research and Practice}%
\def\@journalNameShort{Digit. Gov. Res. Pract.}%
\def\@permissionCodeOne{2639-0175}%
+ \def\@permissionCodeTwo{2639-0175}%
\or % DLT
\def\@journalName{Distributed Ledger Technologies: Research and Practice}%
\def\@journalNameShort{Distrib. Ledger Technol.}%
\def\@permissionCodeOne{2769-6472}%
+ \def\@permissionCodeTwo{2769-6480}%
\or % DTRAP
\def\@journalName{Digital Threats: Research and Practice}%
\def\@journalNameShort{Digit. Threat. Res. Pract.}%
\def\@permissionCodeOne{2576-5337}%
+ \def\@permissionCodeTwo{2576-5337}%
\or % FAC
\def\@journalName{Formal Aspects of Computing}%
\def\@journalNameShort{Form. Asp. Comput.}%
@@ -4505,29 +4464,35 @@
\def\@journalName{ACM Games: Research and Practice}%
\def\@journalNameShort{ACM Games}%
\def\@permissionCodeOne{2832-5516}%
+ \def\@permissionCodeTwo{2832-5516}%
\or % HEALTH
\def\@journalName{ACM Transactions on Computing for Healthcare}%
\def\@journalNameShort{ACM Trans. Comput. Healthcare}%
\def\@permissionCodeOne{2637-8051}%
+ \def\@permissionCodeTwo{2637-8051}%
\or % IMWUT
\def\@journalName{Proceedings of the ACM on Interactive, Mobile,
Wearable and Ubiquitous Technologies}%
\def\@journalNameShort{Proc. ACM Interact. Mob. Wearable Ubiquitous Technol.}%
\def\@permissionCodeOne{2474-9567}%
+ \def\@permissionCodeTwo{2474-9567}%
\@ACM@screentrue
\PackageInfo{\@classname}{Using screen mode due to \@journalCode}%
\or % JACM
\def\@journalName{Journal of the ACM}%
\def\@journalNameShort{J. ACM}%
\def\@permissionCodeOne{0004-5411}%
+ \def\@permissionCodeTwo{1557-735X}%
\or % JATS
\def\@journalName{Journal on Autonomous Transportation Systems}%
\def\@journalNameShort{ACM J. Auton. Transport. Syst.}%
\def\@permissionCodeOne{2833-0528}%
+ \def\@permissionCodeTwo{2833-0528}%
\or % JDIQ
\def\@journalName{ACM Journal of Data and Information Quality}%
\def\@journalNameShort{ACM J. Data Inform. Quality}%
\def\@permissionCodeOne{1936-1955}%
+ \def\@permissionCodeTwo{1936-1963}%
\or % JDS
\def\@journalName{ACM/IMS Journal of Data Science}%
\def\@journalNameShort{ACM/IMS J. Data Sci.}%
@@ -4537,6 +4502,7 @@
\def\@journalName{ACM Journal of Experimental Algorithmics}%
\def\@journalNameShort{ACM J. Exp. Algor.}%
\def\@permissionCodeOne{1084-6654}%
+ \def\@permissionCodeTwo{1084-6654}%
\or % JERIC
\def\@journalName{ACM Journal of Educational Resources in Computing}%
\def\@journalNameShort{ACM J. Edu. Resources in Comput.}%
@@ -4545,6 +4511,7 @@
\def\@journalName{ACM Journal on Emerging Technologies in Computing Systems}%
\def\@journalNameShort{ACM J. Emerg. Technol. Comput. Syst.}%
\def\@permissionCodeOne{1550-4832}%
+ \def\@permissionCodeTwo{1550-4840}%
\or % JOCCH
\def\@journalName{ACM Journal on Computing and Cultural Heritage}%
\def\@journalNameShort{ACM J. Comput. Cult. Herit.}%
@@ -4554,52 +4521,62 @@
\def\@journalName{ACM Journal on Responsible Computing}%
\def\@journalNameShort{ACM J. Responsib. Comput.}%
\def\@permissionCodeOne{2832-0565}%
+ \def\@permissionCodeTwo{2832-0565}%
\or % PACMCGIT
\def\@journalName{Proceedings of the ACM on Computer Graphics and Interactive Techniques}%
\def\@journalNameShort{Proc. ACM Comput. Graph. Interact. Tech.}%
\def\@permissionCodeOne{2577-6193}%
+ \def\@permissionCodeTwo{2577-6193}%
\@ACM@screentrue
\PackageInfo{\@classname}{Using screen mode due to \@journalCode}%
\or % PACMHCI
\def\@journalName{Proceedings of the ACM on Human-Computer Interaction}%
\def\@journalNameShort{Proc. ACM Hum.-Comput. Interact.}%
\def\@permissionCodeOne{2573-0142}%
+ \def\@permissionCodeTwo{2573-0142}%
\@ACM@screentrue
\PackageInfo{\@classname}{Using screen mode due to \@journalCode}%
\or % PACMMOD
\def\@journalName{Proceedings of the ACM on Management of Data}%
\def\@journalNameShort{Proc. ACM Manag. Data}%
\def\@permissionCodeOne{2836-6573}%
+ \def\@permissionCodeTwo{2836-6573}%
\or % PACMNET
\def\@journalName{Proceedings of the ACM on Networkng}%
\def\@journalNameShort{Proc. ACM Netw.}%
\def\@permissionCodeOne{2834-5509}%
+ \def\@permissionCodeTwo{2834-5509}%
\or % PACMPL
\def\@journalName{Proceedings of the ACM on Programming Languages}%
\def\@journalNameShort{Proc. ACM Program. Lang.}%
\def\@permissionCodeOne{2475-1421}%
+ \def\@permissionCodeTwo{2475-1421}%
\@ACM@screentrue
\PackageInfo{\@classname}{Using screen mode due to \@journalCode}%
\or % PACMSE
\def\@journalName{Proceedings of the ACM on Software Engineering}%
\def\@journalNameShort{Proc. ACM Softw. Eng.}%
\def\@permissionCodeOne{2994-970X}%
+ \def\@permissionCodeTwo{2994-970X}%
\@ACM@screentrue
\PackageInfo{\@classname}{Using screen mode due to \@journalCode}%
\or % POMACS
\def\@journalName{Proceedings of the ACM on Measurement and Analysis of Computing Systems}%
\def\@journalNameShort{Proc. ACM Meas. Anal. Comput. Syst.}%
\def\@permissionCodeOne{2476-1249}%
+ \def\@permissionCodeTwo{2476-1249}%
\@ACM@screentrue
\PackageInfo{\@classname}{Using screen mode due to \@journalCode}%
\or % TAAS
\def\@journalName{ACM Transactions on Autonomous and Adaptive Systems}%
\def\@journalNameShort{ACM Trans. Autonom. Adapt. Syst.}%
\def\@permissionCodeOne{1556-4665}%
+ \def\@permissionCodeTwo{1556-4703}%
\or % TACCESS
\def\@journalName{ACM Transactions on Accessible Computing}%
\def\@journalNameShort{ACM Trans. Access. Comput.}%
\def\@permissionCodeOne{1936-7228}%
+ \def\@permissionCodeTwo{1936-7236}%
\or % TACO
\def\@journalName{ACM Transactions on Architecture and Code Optimization}%
\def\@journalNameShort{ACM Trans. Arch. Code Optim.}%
@@ -4609,18 +4586,22 @@
\def\@journalName{ACM Transactions on Algorithms}%
\def\@journalNameShort{ACM Trans. Algor.}%
\def\@permissionCodeOne{1549-6325}%
+ \def\@permissionCodeTwo{1549-6333}%
\or % TALLIP
\def\@journalName{ACM Transactions on Asian and Low-Resource Language Information Processing}%
\def\@journalNameShort{ACM Trans. Asian Low-Resour. Lang. Inf. Process.}%
\def\@permissionCodeOne{2375-4699}%
+ \def\@permissionCodeTwo{2375-4702}%
\or % TAP
\def\@journalName{ACM Transactions on Applied Perception}%
\def\@journalNameShort{ACM Trans. Appl. Percept.}%
\def\@permissionCodeOne{1544-3558}%
+ \def\@permissionCodeTwo{1544-3965}%
\or % TCPS
\def\@journalName{ACM Transactions on Cyber-Physical Systems}%
\def\@journalNameShort{ACM Trans. Cyber-Phys. Syst.}%
\def\@permissionCodeOne{2378-962X}%
+ \def\@permissionCodeTwo{2378-9638}%
\or % TDS
\def\@journalName{ACM/IMS Transactions on Data Science}%
\def\@journalNameShort{ACM/IMS Trans. Data Sci.}%
@@ -4629,26 +4610,32 @@
\def\@journalName{ACM Transactions on Economics and Computation}%
\def\@journalNameShort{ACM Trans. Econ. Comput.}%
\def\@permissionCodeOne{2167-8375}%
+ \def\@permissionCodeTwo{2167-8383}%
\or % TECS
\def\@journalName{ACM Transactions on Embedded Computing Systems}%
\def\@journalNameShort{ACM Trans. Embedd. Comput. Syst.}%
\def\@permissionCodeOne{1539-9087}%
+ \def\@permissionCodeTwo{1558-3465}%
\or % TELO
\def\@journalName{ACM Transactions on Evolutionary Learning and Optimization}%
\def\@journalNameShort{ACM Trans. Evol. Learn. Optim.}%
\def\@permissionCodeOne{2688-3007}%
+ \def\@permissionCodeTwo{2345-6789}%
\or % THRI
\def\@journalName{ACM Transactions on Human-Robot Interaction}%
\def\@journalNameShort{ACM Trans. Hum.-Robot Interact.}%
\def\@permissionCodeOne{2573-9522}%
+ \def\@permissionCodeTwo{2573-9522}%
\or % TIIS
\def\@journalName{ACM Transactions on Interactive Intelligent Systems}%
\def\@journalNameShort{ACM Trans. Interact. Intell. Syst.}%
\def\@permissionCodeOne{2160-6455}%
+ \def\@permissionCodeTwo{2160-6463}%
\or % TIOT
\def\@journalName{ACM Transactions on Internet of Things}%
\def\@journalNameShort{ACM Trans. Internet Things}%
\def\@permissionCodeOne{2577-6207}%
+ \def\@permissionCodeTwo{2577-6207}%
\or % TISSEC
\def\@journalName{ACM Transactions on Information and System Security}%
\def\@journalNameShort{ACM Trans. Info. Syst. Sec.}%
@@ -4657,54 +4644,67 @@
\def\@journalName{ACM Transactions on Intelligent Systems and Technology}%
\def\@journalNameShort{ACM Trans. Intell. Syst. Technol.}%
\def\@permissionCodeOne{2157-6904}%
+ \def\@permissionCodeTwo{2157-6912}%
\or % TKDD
\def\@journalName{ACM Transactions on Knowledge Discovery from Data}%
\def\@journalNameShort{ACM Trans. Knowl. Discov. Data.}%
\def\@permissionCodeOne{1556-4681}%
+ \def\@permissionCodeTwo{1556-472X}%
\or % TMIS
\def\@journalName{ACM Transactions on Management Information Systems}%
\def\@journalNameShort{ACM Trans. Manag. Inform. Syst.}%
\def\@permissionCodeOne{2158-656X}%
+ \def\@permissionCodeTwo{2158-6578}%
\or % TOCE
\def\@journalName{ACM Transactions on Computing Education}%
\def\@journalNameShort{ACM Trans. Comput. Educ.}%
\def\@permissionCodeOne{1946-6226}%
+ \def\@permissionCodeTwo{1946-6226}%
\or % TOCHI
\def\@journalName{ACM Transactions on Computer-Human Interaction}%
\def\@journalNameShort{ACM Trans. Comput.-Hum. Interact.}%
\def\@permissionCodeOne{1073-0516}%
+ \def\@permissionCodeTwo{1557-7325}%
\or % TOCL
\def\@journalName{ACM Transactions on Computational Logic}%
\def\@journalNameShort{ACM Trans. Comput. Logic}%
\def\@permissionCodeOne{1529-3785}%
+ \def\@permissionCodeTwo{1557-945X}%
\or % TOCS
\def\@journalName{ACM Transactions on Computer Systems}%
\def\@journalNameShort{ACM Trans. Comput. Syst.}%
\def\@permissionCodeOne{0734-2071}%
+ \def\@permissionCodeTwo{1557-7333}%
\or % TOCT
\def\@journalName{ACM Transactions on Computation Theory}%
\def\@journalNameShort{ACM Trans. Comput. Theory}%
\def\@permissionCodeOne{1942-3454}%
+ \def\@permissionCodeTwo{1942-3462}%
\or % TODAES
\def\@journalName{ACM Transactions on Design Automation of Electronic Systems}%
\def\@journalNameShort{ACM Trans. Des. Autom. Electron. Syst.}%
\def\@permissionCodeOne{1084-4309}%
+ \def\@permissionCodeTwo{1557-7309}%
\or % TODS
\def\@journalName{ACM Transactions on Database Systems}%
\def\@journalNameShort{ACM Trans. Datab. Syst.}%
\def\@permissionCodeOne{0362-5915}%
+ \def\@permissionCodeTwo{1557-4644}%
\or % TOG
\def\@journalName{ACM Transactions on Graphics}%
\def\@journalNameShort{ACM Trans. Graph.}%
- \def\@permissionCodeOne{0730-0301}
+ \def\@permissionCodeOne{0730-0301}%
+ \def\@permissionCodeTwo{1557-7368}%
\or % TOIS
\def\@journalName{ACM Transactions on Information Systems}%
\def\@journalNameShort{ACM Trans. Inf. Syst.}%
\def\@permissionCodeOne{1046-8188}%
+ \def\@permissionCodeTwo{1558-2868}%
\or % TOIT
\def\@journalName{ACM Transactions on Internet Technology}%
\def\@journalNameShort{ACM Trans. Internet Technol.}%
\def\@permissionCodeOne{1533-5399}%
+ \def\@permissionCodeTwo{1557-6051}%
\or % TOMACS
\def\@journalName{ACM Transactions on Modeling and Computer Simulation}%
\def\@journalNameShort{ACM Trans. Model. Comput. Simul.}%
@@ -4719,67 +4719,82 @@
\def\@journalName{ACM Transactions on Modeling and Performance Evaluation of Computing Systems}%
\def\@journalNameShort{ACM Trans. Model. Perform. Eval. Comput. Syst.}%
\def\@permissionCodeOne{2376-3639}%
+ \def\@permissionCodeTwo{2376-3647}%
\or % TOMS
\def\@journalName{ACM Transactions on Mathematical Software}%
\def\@journalNameShort{ACM Trans. Math. Softw.}%
\def\@permissionCodeOne{0098-3500}%
+ \def\@permissionCodeTwo{1557-7295}%
\or % TOPC
\def\@journalName{ACM Transactions on Parallel Computing}%
\def\@journalNameShort{ACM Trans. Parallel Comput.}%
\def\@permissionCodeOne{2329-4949}%
\def\@permissionCodeTwo{2329-4957}%
-\or % TOPS
- \def\@journalName{ACM Transactions on Privacy and Security}%
- \def\@journalNameShort{ACM Trans. Priv. Sec.}%
- \def\@permissionCodeOne{2471-2566}%
\or % TOPLAS
\def\@journalName{ACM Transactions on Programming Languages and Systems}%
\def\@journalNameShort{ACM Trans. Program. Lang. Syst.}%
\def\@permissionCodeOne{0164-0925}%
+ \def\@permissionCodeTwo{1558-4593}%
\or % TOPML
\def\@journalName{ACM Transactions on Probabilistic Machine Learning}%
\def\@journalNameShort{ACM Trans. Probab. Mach. Learn.}%
\def\@permissionCodeOne{2836-8924}%
+ \def\@permissionCodeTwo{2836-8924}%
+\or % TOPS
+ \def\@journalName{ACM Transactions on Privacy and Security}%
+ \def\@journalNameShort{ACM Trans. Priv. Sec.}%
+ \def\@permissionCodeOne{2471-2566}%
+ \def\@permissionCodeTwo{2471-2574}%
\or % TORS
\def\@journalName{ACM Transactions on Recommender Systems}%
\def\@journalNameShort{ACM Trans. Recomm. Syst.}%
\def\@permissionCodeOne{2770-6699}%
+ \def\@permissionCodeTwo{2770-6699}%
\or % TOS
\def\@journalName{ACM Transactions on Storage}%
\def\@journalNameShort{ACM Trans. Storage}%
\def\@permissionCodeOne{1553-3077}%
+ \def\@permissionCodeTwo{1553-3093}%
\or % TOSEM
\def\@journalName{ACM Transactions on Software Engineering and Methodology}%
\def\@journalNameShort{ACM Trans. Softw. Eng. Methodol.}%
\def\@permissionCodeOne{1049-331X}%
+ \def\@permissionCodeTwo{1557-7392}%
\or % TOSN
\def\@journalName{ACM Transactions on Sensor Networks}%
\def\@journalNameShort{ACM Trans. Sensor Netw.}%
\def\@permissionCodeOne{1550-4859}%
+ \def\@permissionCodeTwo{1550-4867}%
\or % TQC
\def\@journalName{ACM Transactions on Quantum Computing}%
\def\@journalNameShort{ACM Trans. Quantum Comput.}%
\def\@permissionCodeOne{2643-6817}%
+ \def\@permissionCodeTwo{2643-6817}%
\or % TRETS
\def\@journalName{ACM Transactions on Reconfigurable Technology and Systems}%
\def\@journalNameShort{ACM Trans. Reconfig. Technol. Syst.}%
\def\@permissionCodeOne{1936-7406}%
+ \def\@permissionCodeTwo{1936-7414}%
\or % TSAS
\def\@journalName{ACM Transactions on Spatial Algorithms and Systems}%
\def\@journalNameShort{ACM Trans. Spatial Algorithms Syst.}%
\def\@permissionCodeOne{2374-0353}%
+ \def\@permissionCodeTwo{2374-0361}%
\or % TSC
\def\@journalName{ACM Transactions on Social Computing}%
\def\@journalNameShort{ACM Trans. Soc. Comput.}%
\def\@permissionCodeOne{2469-7818}%
+ \def\@permissionCodeTwo{2469-7826}%
\or % TSLP
\def\@journalName{ACM Transactions on Speech and Language Processing}%
\def\@journalNameShort{ACM Trans. Speech Lang. Process.}%
\def\@permissionCodeOne{1550-4875}%
+ \def\@permissionCodeTwo{2329-9304}%
\or % TWEB
\def\@journalName{ACM Transactions on the Web}%
\def\@journalNameShort{ACM Trans. Web}%
\def\@permissionCodeOne{1559-1131}%
+ \def\@permissionCodeTwo{1559-114X}%
\else % FACMP, a dummy journal
\def\@journalName{ACM Just Accepted}%
\def\@journalNameShort{ACM Accepted}%
@@ -5050,10 +5065,8 @@
\def\institution##1{##1\ignorespaces}%
\def\department{\@ifnextchar[{\@department}{\@department[]}}%
\def\@department[##1]##2{\unskip, ##2\ignorespaces}%
- \let\streetaddress\position
\let\city\position
\let\state\position
- \let\postcode\position
\let\country\position
Also with #1\unskip.\egroup}
% \end{macrocode}
@@ -6850,6 +6863,8 @@
% \changes{v1.15}{2016/07/03}{Added macro}
% \changes{v1.33}{2017/03/28}{Added obeypunctuation code}
% \changes{v1.40}{2017/06/15}{We now do not print this even in SIG}
+% \changes{v2.06}{2024/04/13}{We now do not collect postal information
+% anymore}
% \begin{macro}{\city}
% \changes{v1.15}{2016/07/03}{Added macro}
% \changes{v1.33}{2017/03/28}{Added obeypunctuation code}
@@ -6863,6 +6878,8 @@
% \changes{v1.15}{2016/07/03}{Added macro}
% \changes{v1.33}{2017/03/28}{Added obeypunctuation code}
% \changes{v1.40}{2017/06/15}{We now do not print this even in SIG}
+% \changes{v2.06}{2024/04/13}{We now do not collect postal information
+% anymore}
% \begin{macro}{\country}
% \changes{v1.15}{2016/07/03}{Added macro}
% \changes{v1.33}{2017/03/28}{Added obeypunctuation code}
@@ -6876,8 +6893,12 @@
% strange error if an author uses them outside \cs{affiliation}. Of
% course we can make them produce an error message, but\ldots
% \begin{macrocode}
-\def\streetaddress#1{\unskip\ignorespaces}
-\def\postcode#1{\unskip\ignorespaces}
+\def\streetaddress#1{\ClassWarning{\@classname}{ACM no longer collects
+ authors' postal addresses. I am ignoring your street
+ address}\unskip\ignorespaces}
+\def\postcode#1{\ClassWarning{\@classname}{ACM no longer collects
+ authors' postal addresses. I am ignoring your postal
+ code}\unskip\ignorespaces}
\if@ACM@journal
\def\position#1{\unskip\ignorespaces}
\def\institution#1{\global\@ACM@instpresenttrue
@@ -6895,10 +6916,8 @@
\if@ACM@affiliation@obeypunctuation#1\else#1\par\fi}%
\newcommand\department[2][0]{\if@ACM@affiliation@obeypunctuation
#2\else#2\par\fi}%
-% \def\streetaddress#1{\if@ACM@affiliation@obeypunctuation#1\else#1\par\fi}%
\def\city#1{\global\@ACM@citypresenttrue\@ACM@addtoaddress{#1}}%
\let\state\@ACM@addtoaddress
-% \def\postcode#1{\if@ACM@affiliation@obeypunctuation#1\else\unskip\space#1\fi}%
\def\country#1{\global\@ACM@countrypresenttrue\@ACM@addtoaddress{#1}}%
\fi
% \end{macrocode}
@@ -7342,16 +7361,21 @@
% \changes{v1.46}{2017/08/27}{Introduced macro}
% \changes{v1.65}{2019/10/13}{Deleted cs{@addpunct}}
% \changes{v1.77}{2021/04/16}{New separator of institutions}
+% \changes{v2.06}{2024/04/13}{\cs{streetaddress} and \cs{postcode} now
+% produce warnings}
% Typesetting authors' addresses in the footnote style
% \begin{macrocode}
\def\@mkauthorsaddresses{%
\ifnum\num@authors>1\relax
Authors' \else Author's \fi
- \ifnum\num@authorgroups>1\relax
- addresses: \else address: \fi
+ Contact Information:
\bgroup
- \def\streetaddress##1{\unskip, ##1}%
- \def\postcode##1{\unskip, ##1}%
+ \def\streetaddress##1{\ClassWarning{\@classname}{ACM no longer collects
+ authors' postal addresses. I am ignoring your street
+ address}\unskip\ignorespaces}%
+ \def\postcode##1{\ClassWarning{\@classname}{ACM no longer collects
+ authors' postal addresses. I am ignoring your postal
+ code}\unskip\ignorespaces}%
\def\position##1{\unskip\ignorespaces}%
\gdef\@ACM@institution@separator{, }%
\def\institution##1{\unskip\@ACM@institution@separator ##1\gdef\@ACM@institution@separator{ and }}%
diff --git a/macros/latex/contrib/acmart/acmart.pdf b/macros/latex/contrib/acmart/acmart.pdf
index 344d409f1b..6968505073 100644
--- a/macros/latex/contrib/acmart/acmart.pdf
+++ b/macros/latex/contrib/acmart/acmart.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/acmguide.pdf b/macros/latex/contrib/acmart/acmguide.pdf
index 20738de1c0..79d2c75930 100644
--- a/macros/latex/contrib/acmart/acmguide.pdf
+++ b/macros/latex/contrib/acmart/acmguide.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-acmcp.pdf b/macros/latex/contrib/acmart/samples/sample-acmcp.pdf
index aa0af4ed03..248ec92fda 100644
--- a/macros/latex/contrib/acmart/samples/sample-acmcp.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-acmcp.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-acmengage.pdf b/macros/latex/contrib/acmart/samples/sample-acmengage.pdf
index ecef3f264c..4f27c502b3 100644
--- a/macros/latex/contrib/acmart/samples/sample-acmengage.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-acmengage.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-acmlarge.pdf b/macros/latex/contrib/acmart/samples/sample-acmlarge.pdf
index 1dadd006b9..d40c026b0b 100644
--- a/macros/latex/contrib/acmart/samples/sample-acmlarge.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-acmlarge.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-acmsmall-biblatex.pdf b/macros/latex/contrib/acmart/samples/sample-acmsmall-biblatex.pdf
index 60c0827ba8..68416d9b6d 100644
--- a/macros/latex/contrib/acmart/samples/sample-acmsmall-biblatex.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-acmsmall-biblatex.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-acmsmall-conf.pdf b/macros/latex/contrib/acmart/samples/sample-acmsmall-conf.pdf
index b2cba4a4f3..a41acf251c 100644
--- a/macros/latex/contrib/acmart/samples/sample-acmsmall-conf.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-acmsmall-conf.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-acmsmall-submission.pdf b/macros/latex/contrib/acmart/samples/sample-acmsmall-submission.pdf
index 23dc335812..2ae43840f3 100644
--- a/macros/latex/contrib/acmart/samples/sample-acmsmall-submission.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-acmsmall-submission.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-acmsmall.pdf b/macros/latex/contrib/acmart/samples/sample-acmsmall.pdf
index c7a9e5f575..25671b661e 100644
--- a/macros/latex/contrib/acmart/samples/sample-acmsmall.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-acmsmall.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-acmtog-conf.pdf b/macros/latex/contrib/acmart/samples/sample-acmtog-conf.pdf
index b1df26ca61..750a6f6221 100644
--- a/macros/latex/contrib/acmart/samples/sample-acmtog-conf.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-acmtog-conf.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-acmtog.pdf b/macros/latex/contrib/acmart/samples/sample-acmtog.pdf
index 1434d59099..dfe07e0656 100644
--- a/macros/latex/contrib/acmart/samples/sample-acmtog.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-acmtog.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-manuscript.pdf b/macros/latex/contrib/acmart/samples/sample-manuscript.pdf
index be3cac8e04..a0be04191c 100644
--- a/macros/latex/contrib/acmart/samples/sample-manuscript.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-manuscript.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-sigconf-authordraft.pdf b/macros/latex/contrib/acmart/samples/sample-sigconf-authordraft.pdf
index c95d95127d..d27c922559 100644
--- a/macros/latex/contrib/acmart/samples/sample-sigconf-authordraft.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-sigconf-authordraft.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-sigconf-biblatex.pdf b/macros/latex/contrib/acmart/samples/sample-sigconf-biblatex.pdf
index 6aa27ae8fb..e763de031c 100644
--- a/macros/latex/contrib/acmart/samples/sample-sigconf-biblatex.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-sigconf-biblatex.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-sigconf-i13n.pdf b/macros/latex/contrib/acmart/samples/sample-sigconf-i13n.pdf
index 7a84d7c4e7..76c620139f 100644
--- a/macros/latex/contrib/acmart/samples/sample-sigconf-i13n.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-sigconf-i13n.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-sigconf.pdf b/macros/latex/contrib/acmart/samples/sample-sigconf.pdf
index e1239820b7..1f2896d691 100644
--- a/macros/latex/contrib/acmart/samples/sample-sigconf.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-sigconf.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/sample-sigplan.pdf b/macros/latex/contrib/acmart/samples/sample-sigplan.pdf
index cb491065d0..4d19efa089 100644
--- a/macros/latex/contrib/acmart/samples/sample-sigplan.pdf
+++ b/macros/latex/contrib/acmart/samples/sample-sigplan.pdf
Binary files differ
diff --git a/macros/latex/contrib/acmart/samples/samples.dtx b/macros/latex/contrib/acmart/samples/samples.dtx
index f6642f1dba..37e7a0abfd 100644
--- a/macros/latex/contrib/acmart/samples/samples.dtx
+++ b/macros/latex/contrib/acmart/samples/samples.dtx
@@ -178,17 +178,14 @@
\email{webmaster@marysville-ohio.com}
\affiliation{%
\institution{Institute for Clarity in Documentation}
- \streetaddress{P.O. Box 1212}
\city{Dublin}
\state{Ohio}
\country{USA}
- \postcode{43017-6221}
}
\author{Lars Th{\o}rv{\"a}ld}
\affiliation{%
\institution{The Th{\o}rv{\"a}ld Group}
- \streetaddress{1 Th{\o}rv{\"a}ld Circle}
\city{Hekla}
\country{Iceland}}
\email{larst@affiliation.org}
@@ -203,7 +200,6 @@
\author{Aparna Patel}
\affiliation{%
\institution{Rajiv Gandhi University}
- \streetaddress{Rono-Hills}
\city{Doimukh}
\state{Arunachal Pradesh}
\country{India}}
@@ -211,7 +207,6 @@
\author{Huifen Chan}
\affiliation{%
\institution{Tsinghua University}
- \streetaddress{30 Shuangqing Rd}
\city{Haidian Qu}
\state{Beijing Shi}
\country{China}}
@@ -219,17 +214,14 @@
\author{Charles Palmer}
\affiliation{%
\institution{Palmer Research Laboratories}
- \streetaddress{8600 Datapoint Drive}
\city{San Antonio}
\state{Texas}
- \country{USA}
- \postcode{78229}}
+ \country{USA}}
\email{cpalmer@prl.com}
\author{John Smith}
\affiliation{%
\institution{The Th{\o}rv{\"a}ld Group}
- \streetaddress{1 Th{\o}rv{\"a}ld Circle}
\city{Hekla}
\country{Iceland}}
\email{jsmith@affiliation.org}
diff --git a/macros/latex/contrib/thesis-ekf/thesis-ekf.dtx b/macros/latex/contrib/thesis-ekf/thesis-ekf.dtx
index ab3b2d7f52..5c97dbe0ea 100644
--- a/macros/latex/contrib/thesis-ekf/thesis-ekf.dtx
+++ b/macros/latex/contrib/thesis-ekf/thesis-ekf.dtx
@@ -20,24 +20,25 @@
\ProvidesFile{thesis-ekf.dtx}
%</driver>
%<class>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
-%<class>\ProvidesClass{thesis-ekf}[2024/04/13 v4.3 Thesis class for Eszterhazy Karoly Catholic University (Eger, Hungary)]
+%<class>\ProvidesClass{thesis-ekf}[2024/04/14 v4.4 Thesis class for Eszterhazy Karoly Catholic University (Eger, Hungary)]
%<class>
%<*driver>
-\documentclass{ltxdoc}
+\documentclass[nohyperref]{ltxdoc}
\OnlyDescription
\usepackage[T1]{fontenc}
-\AddToHook{begindocument/before}[doc/hyperref]{\hypersetup{pdfstartview=FitH,bookmarksnumbered=false,allcolors=black}}
-\PassOptionsToPackage{active=onlycs}{magyar.ldf}
+\PassOptionsToPackage{defaults=hu-min}{magyar.ldf}
\usepackage[english,magyar]{babel}
-\usepackage[numbered=false]{bookmark}
\usepackage[a4paper,left=2in,top=1.5in,bottom=1.5in]{geometry}
-\frenchspacing
-\usepackage{lmodern,paralist,textcomp,fancyvrb}
-\setlength{\MacroTopsep}{0pt}
-\fvset{gobble=1,fontsize=\footnotesize,commandchars=+<>}
-\newcommand{\param}[1]{\hspace*{-4.5pt}{\small#1}}
-\renewcommand{\bfdefault}{b}
-\providecommand\narg[1]{\ttfamily\char`\{#1\char`\}}
+\usepackage[pdfstartview=FitH,bookmarksnumbered,allcolors=black,bookmarksopen,colorlinks]{hyperref}
+\usepackage{bookmark,lmodern,fancyvrb,upquote}
+\fvset{gobble=1,commandchars=+()}
+\let\oldmeta\meta
+\def\meta#1{{\rmfamily\oldmeta{#1}}}
+\def\param#1{\hspace*{-.5em}{\ttfamily#1}}
+\setlength{\parindent}{0pt}
+\def\descriptionlabel#1{\hspace{\labelsep}\texttt{#1} --}
+\def\MacroFont{\ttfamily}
+\setlength{\overfullrule}{5pt}
\begin{document}
\DocInput{./thesis-ekf.dtx}
\end{document}
@@ -61,64 +62,61 @@
% Right brace \} Tilde \~}
%
% \GetFileInfo{thesis-ekf.cls}
-% \title{Thesis class for\\ Eszterházy Károly Catholic University\\\textsf{thesis-ekf.cls}\\[2mm]{\normalsize Version 4.3 (2024/04/13)}}
+% \title{Thesis class for\\ Eszterházy Károly Catholic University\\\textsf{thesis-ekf.cls}\\[2mm]{\normalsize v4.4 (2024/04/14)}}
% \author{Tibor Tómács\\{\normalsize\href{mailto:tomacs.tibor@gmail.com}{\texttt{tomacs.tibor@gmail.com}}}}
% \date{}
% \maketitle
-% \def\abstractname{}
-%\begin{abstract}
-% \selectlanguage{english}\noindent This is a class file for theses and dissertations at Eszterházy Károly Catholic University, Eger, Hungary (website: \texttt{https://uni-eszterhazy.hu/en}). The documentation is in Hungarian.
-%\end{abstract}
+%
+% {\selectlanguage{english}
+% This is a class file for theses and dissertations at the \emph{Eszterházy Károly Catholic University}, Eger, Hungary (\url{https://uni-eszterhazy.hu/en}).
+% The documentation is in Hungarian language.}
%
% \section{Bevezető}
%
-% A |thesis-ekf| dokumentumosztály segítségével az Eszterházy Károly Katolikus Egyetem szabályzatának megfelelő szakdolgozatokat lehet készíteni. Ez a dokumentumosztály 2014-től létezik, amikor az intézmény neve még Eszterházy Károly Főiskola volt. Ennek rövidítése a dokumentumosztály nevében szereplő |ekf|. A formai követelmények a következők:
+% A |thesis-ekf| dokumentumosztály segítségével az \emph{Eszterházy Károly Katolikus Egyetem} szabályzatának megfelelő szakdolgozatokat lehet készíteni. Az első verzió 2014-ben készült, amikor az intézmény neve Eszterházy Károly Főiskola volt. Ennek rövidítése a dokumentumosztály nevében szereplő |ekf|. A formai követelmények a következők:
%
-% \medskip
-% \begin{compactitem}
+% \begin{itemize}
% \item A4-es lap- és 12\,pt betűméret,
% \item a margó a kötés oldalon 30\,mm, a többi 25\,mm,
% \item oldalszámozás a láblécben arab számozással,
% \item a fejezetcímek középre, a további szintek címei balra igazítva,
% \item a főszöveg antikva betűcsaláddal kiszedve,
% \item sorkizárt igazítás, másfeles sortávolság.
-% \end{compactitem}
+% \end{itemize}
%
-% \medskip\noindent
% A |thesis-ekf| ezeket a paramétereket automatikusan beállítja, továbbá a megfelelő címoldal elkészítését is elvégzi.
%
% \section{A dokumentumosztály által betöltött csomagok}
%
-% A |thesis-ekf| dokumentumosztály a |report| osztályt használja alapként, továbbá rendre a következő csomagokat tölti be:
-%
-% \medskip
-% \begin{compactdesc}
-% \item[|kvoptions|] (opciók definiálásához)
-% \item[|iftex|] (pdf/dvi kimenet detektálásához)
-% \item[|hyperref|] (elektronikus verzióhoz; opciók: |pdfstartview=FitH|, |allcolors=blue|, |linktocpage|, |bookmarksnumbered|, |pdfborder={0 0 0}|)
-% \item[|geometry|] (oldalméretek beállításához; opciók: |a4paper|, |top=25mm|, |bottom=25mm|, |inner=30mm|, |outer=25mm|)
-% \item[|lmodern|] (Latin Modern fontkészlethez; |times| opció esetén nem töltődik be)
-% \item[|fixcmex|] (Latin Modern fontkészlet esetén a nagy operátor jeleket méretezhetővé teszi; |times| opció esetén nem töltődik be)
-% \item[|cmupint|] (Latin Modern fontkészlet esetén az integráljelek álló alakúak; csak az |upint| és |times=false| opciók esetén töltődik be)
-% \item[|etoolbox|] (dokumentumkapcsokhoz)
-% \item[|setspace|] (sortávolság beállításához)
-% \item[|graphicx|] (képek betöltéséhez)
-% \item[|newtxtext|] (Times fontkészlethez; |times| opció esetén töltődik be)
-% \item[|newtxmath|] (Times matematikai fontkészlethez; |times| opció esetén töltődik be)
-% \item[|fontsize|] (|fontsize=|\meta{méret} opcióhoz; csak akkor töltődik be, ha a \meta{méret} különbözik a |10pt|, |11pt| és |12pt| értékektől.)
-% \item[|upquote|] (verbatimban \textquotesingle\ és \textasciigrave\ jelekért)
-% \end{compactdesc}
+% A |thesis-ekf| dokumentumosztály a |report| osztályt használja alapként, továbbá a következő csomagokat tölti be:
+%
+% \begin{description}
+% \item[kvoptions] Opciók definiálásához.
+% \item[iftex] PDF/DVI kimenet detektálásához.
+% \item[hyperref] Elektronikus verzióhoz. Opciók: |pdfstartview=FitH|, |linktocpage|, |allcolors=blue|, |bookmarksnumbered|, |pdfborder={0 0 0}|.
+% \item[geometry] Oldalméretek beállításához. Opciók: |a4paper|, |inner=30mm|, |top=25mm|, |outer=25mm|, |bottom=25mm|.
+% \item[lmodern] Latin Modern fontkészlethez. |times| opció esetén nem töltődik be.
+% \item[fixcmex] Latin Modern fontkészlet esetén a nagy operátor jeleket méretezhetővé teszi. |times| opció esetén nem töltődik be.
+% \item[cmupint] Latin Modern fontkészlet esetén az integráljelek álló alakúak. Csak az |upint| és |times=false| opciók esetén töltődik be.
+% \item[etoolbox] Dokumentumkapcsokhoz.
+% \item[setspace] Sortávolság beállításához.
+% \item[graphicx] Képek betöltéséhez.
+% \item[newtxtext] Times fontkészlethez. |times| opció esetén töltődik be.
+% \item[newtxmath] Times matematikai fontkészlethez. |times| opció esetén töltődik be.
+% \item[fontsize] A |fontsize=|\meta{méret} opcióhoz. Csak akkor töltődik be, ha a \meta{méret} különbözik a |10pt|, |11pt| és |12pt| értékektől.
+% \item[upquote] Verbatimban |'| és |`| jelekért.
+% \end{description}
%
% \section{A dokumentumosztály betöltése és legfontosabb opciói}
%
-% \begin{macro}{\documentclass}\param{\oarg{opciók}\narg{thesis-ekf}}
-% A dokumentumosztályt a preambulum elején ezzel a paranccsal lehet betölteni.
-% \end{macro}
+%\begin{Verbatim}
+%\documentclass+oarg(opciók){thesis-ekf}
+%\end{Verbatim}
%
-% \medskip\noindent
-% Opciók nélkül akkor használja, ha a szakdolgozatot egyoldalasan szeretné kinyomtatni, vagy ha olyan elektronikus verziót akar, amelyben a linkek nem színes karakterrel jelennek meg. A fontosabb \meta{opciók} a következők:
+% A dokumentumosztályt a preambulum elején ezzel lehet betölteni.
+% Opciók nélkül akkor használja, ha a szakdolgozatot egyoldalasan szeretné kinyomtatni, vagy ha olyan elektronikus verziót akar, amelyben a linkek nem színes karakterrel jelennek meg.
+% A fontosabb \meta{opciók} a következők:
%
-% \medskip
% \begin{macro}{twoside}
% Ha a szakdolgozatot kétoldalasan szeretné kinyomtatni, akkor ezt az opciót alkalmazza! Ne használja egyoldalas nyomtatáshoz illetve elektronikus verzióhoz!
% \end{macro}
@@ -136,7 +134,7 @@
% \end{macro}
%
% \begin{macro}{times}
-% Alapbeállítás esetén a Latin Modern fontkészletet használja a dokumentumosztály. Ezzel az opcióval áttérhet a Times fontkészletre, amely nagyon hasonló a közismert Times New Roman-hoz. Ne használja \texttt{xelatex} és \texttt{lualatex} fordítók esetén!
+% Alapbeállítás esetén a Latin Modern fontkészletet használja a dokumentumosztály. Ezzel az opcióval áttérhet a Times fontkészletre, amely nagyon hasonló a közismert Times New Roman-hoz. Ne használja |xelatex| és |lualatex| fordítók esetén!
% \end{macro}
%
% \begin{macro}{upint}
@@ -146,18 +144,18 @@
% \section{Címoldal létrehozása}
%
% \begin{macro}{\institute}\param{\marg{intézmény neve}}
-% Ezzel kell megadni annak az intézménynek a nevét, ahol a szakdolgozat készült. Az Eszterházy Károly Egyetem esetében az egyetem nevét nem kell kiírni, mert azt tartalmazza a logója. Ekkor elég csak az intézet nevét feltüntetni.
+% Ezzel kell megadni annak az intézménynek a nevét, ahol a szakdolgozat készült. Az Eszterházy Károly Katolikus Egyetem esetében az egyetem nevét nem kell kiírni, mert azt tartalmazza a logója. Ekkor elég csak az intézet nevét feltüntetni.
% \end{macro}
%
% \begin{macro}{\title}\param{\marg{szakdolgozat címe}}
% Ezzel kell megadni a szakdolgozat címét.
% \end{macro}
%
-% \begin{macro}{\author}\param{\texttt{\{}\meta{szerző neve}\texttt{\textbackslash\textbackslash}\meta{szak}\texttt{\}}}
+% \begin{macro}{\author}\param{\{\meta{szerző neve}\textbackslash\textbackslash\meta{szak}\}}
% Ezzel kell megadni a szakdolgozat szerzőjének a nevét és a szakot.
% \end{macro}
%
-% \begin{macro}{\supervisor}\param{\texttt{\{}\meta{témavezető neve}\texttt{\textbackslash\textbackslash}\meta{beosztás}\texttt{\}}}
+% \begin{macro}{\supervisor}\param{\{\meta{témavezető neve}\textbackslash\textbackslash\meta{beosztás}\}}
% Ezzel kell megadni a szakdolgozat témavezetőjének a nevét és beosztását.
% \end{macro}
%
@@ -217,18 +215,18 @@
%
% \section{A dokumentumosztály testreszabása}
%
-% A \texttt{thesis-ekf} dokumentumosztály könnyen testreszabható opciókkal és parancsokkal, így más egyetemek is használhatják.
+% A |thesis-ekf| dokumentumosztály testreszabható opciókkal és parancsokkal, így más egyetemek is használhatják.
%
% \subsection{A dokumentumosztály opciói}
%
% A |twoside|, |colorlinks|, |tocnopagenum|, |reverseorder|, |times| és |upint| opciókról már volt szó. További opciók:
%
% \medskip
-% \begin{macro}{centeredchapter}\param{\texttt{=false}}
+% \begin{macro}{centeredchapter}\param{=false}
% Ezzel a fejezetcímek nem középre, hanem balra zártan lesznek kiszedve.
% \end{macro}
%
-% \begin{macro}{warning}\param{\texttt{=false}}
+% \begin{macro}{warning}\param{=false}
% A dokumentumosztály figyelmeztetéseinek kikapcsolása.
% \end{macro}
%
@@ -244,7 +242,7 @@
% Az alapbetűméret 12\,pt (alapopció).
% \end{macro}
%
-% \begin{macro}{fontsize}\param{\texttt{=}\meta{betűméret}}
+% \begin{macro}{fontsize}\param{=\meta{betűméret}}
% A \meta{betűméret} adja meg az alapbetűméretet, amely bármilyen méret lehet. Ha a \meta{betűméret} különbözik a |10pt|, |11pt| és |12pt| értékektől, akkor ez az opció a beállításhoz betölti a |fontsize| csomagot. Ennek az opciónak a használata felülbírálja a |10pt|, |11pt| és |12pt| opciókat.
% \end{macro}
%
@@ -252,112 +250,112 @@
% Alapbeállítás esetén a logó az intézmény neve felett van. Ezzel a logó az intézmény neve alá kerül.
% \end{macro}
%
-% \begin{macro}{logofont}\param{\texttt{=}\meta{betűtípus}}
+% \begin{macro}{logofont}\param{=\meta{betűtípus}}
% Ha a logó helyén szöveg van (lásd a |\logo| parancsot), akkor annak a betűtípusa (alapérték |\large\scshape|).
% \end{macro}
%
-% \begin{macro}{logosep}\param{\texttt{=}\meta{méret}}
-% A logó alatti térköz a normál sortávolságon felül, ha a \texttt{logodown} opció nincs bekapcsolva (alapérték |0mm|).
+% \begin{macro}{logosep}\param{=\meta{méret}}
+% A logó alatti térköz a normál sortávolságon felül, ha a |logodown| opció nincs bekapcsolva (alapérték |0mm|).
% \end{macro}
%
-% \begin{macro}{institutefont}\param{\texttt{=}\meta{betűtípus}}
+% \begin{macro}{institutefont}\param{=\meta{betűtípus}}
% Az intézménynév betűtípusa (alapérték |\large\scshape|).
% \end{macro}
%
-% \begin{macro}{institutesep}\param{\texttt{=}\meta{méret}}
-% Az intézmény neve alatti térköz a normál sortávolságon felül, ha a \texttt{logodown} opció be van kapcsolva (alapérték |10mm|).
+% \begin{macro}{institutesep}\param{=\meta{méret}}
+% Az intézmény neve alatti térköz a normál sortávolságon felül, ha a |logodown| opció be van kapcsolva (alapérték |10mm|).
% \end{macro}
%
-% \begin{macro}{titlefont}\param{\texttt{=}\meta{betűtípus}}
+% \begin{macro}{titlefont}\param{=\meta{betűtípus}}
% A dolgozat címének betűtípusa (alapérték |\Huge\bfseries|).
% \end{macro}
%
-% \begin{macro}{titlesep}\param{\texttt{=}\meta{méret}}
+% \begin{macro}{titlesep}\param{=\meta{méret}}
% A cím feletti térköz mérete |\stretch{1}|. Ezzel a cím alatti térközt lehet beállítani a normál sortávolságon felül (alapérték |\stretch{1.4}|).
% \end{macro}
%
-% \begin{macro}{captionfont}\param{\texttt{=}\meta{betűtípus}}
+% \begin{macro}{captionfont}\param{=\meta{betűtípus}}
% A szerző és témavezető nevei feletti feliratok betűtípusa (alapérték |\large\bfseries|).
% \end{macro}
%
-% \begin{macro}{captionsep}\param{\texttt{=}\meta{méret}}
+% \begin{macro}{captionsep}\param{=\meta{méret}}
% Az előbbi feliratok alatti térköz a normál sortávolságon felül, amennyiben nem használja a |\collaborator| parancsot több szerző vagy témavezető megadásához (alapérték |0mm|).
% \end{macro}
%
-% \begin{macro}{collcaptionsep}\param{\texttt{=}\meta{méret}}
+% \begin{macro}{collcaptionsep}\param{=\meta{méret}}
% Az előbbi feliratok alatti térköz a normál sortávolságon felül, amennyiben használja az |\collaborator| parancsot több szerző vagy témavezető megadásához (alapérték |2mm|). Ahol az |collcaptionsep| értékét fel kell használni, ott még nem lehet tudni, hogy lesz-e |\collaborator| kifejtve. Ezért ennek érzékeléséhez kereszthivatkozást alkalmaz a kód, így csak a második fordításnál alakulnak ki a helyes térközök. Mivel például a tartalomjegyzék miatt úgyis többször kell fordítani, ezért ez nem okoz gondot. Ha |latexmk|-val vagy valamilyen hasonló programmal fordít, akkor természetesen azt csak egyszer kell futtatni.
% \end{macro}
%
-% \begin{macro}{authorfont}\param{\texttt{=}\meta{betűtípus}}
+% \begin{macro}{authorfont}\param{=\meta{betűtípus}}
% A szerző nevének és szakjának, illetve a témavezető nevének és beosztásának betűtípusa (alapérték |\large|).
% \end{macro}
%
-% \begin{macro}{authoralign}\param{\texttt{=}\meta{igazítás}}
+% \begin{macro}{authoralign}\param{=\meta{igazítás}}
% A szerző adatait tartalmazó doboz tartalmának igazítása. Az \meta{igazítás} lehetséges értékei |left| (balra igazítás, ez az alapérték), |center| (középre igazítás) |right| (jobbra igazítás).
% \end{macro}
%
-% \begin{macro}{supervisoralign}\param{\texttt{=}\meta{igazítás}}
-% A témavezető adatait tartalmazó doboz tartalmának igazítása. Az \meta{igazítás} lehetséges értékei |left| (balra igazítás, ez az alapérték), |center| (középre igazítás) |right| (jobbra igazítás).
+% \begin{macro}{supervisoralign}\param{=\meta{igazítás}}
+% A témavezető adatait tartalmazó doboz tartalmának igazítása. Az \meta{igazí\-tás} lehetséges értékei |left| (balra igazítás, ez az alapérték), |center| (középre igazítás) |right| (jobbra igazítás).
% \end{macro}
%
-% \begin{macro}{authorxmargin}\param{\texttt{=}\meta{méret}}
+% \begin{macro}{authorxmargin}\param{=\meta{méret}}
% Ezzel a szerző és témavezető dobozának sorában a normál margóméret ennyivel nő meg (alapérték |10mm|).
% \end{macro}
%
-% \begin{macro}{authorsep}\param{\texttt{=}\meta{méret}}
+% \begin{macro}{authorsep}\param{=\meta{méret}}
% A szerző és témavezető dobozait tartalmazó sor alatti térköz a normál sortávolságon felül (alapérték |15mm|).
% \end{macro}
%
-% \begin{macro}{hminsep}\param{\texttt{=}\meta{méret}}
+% \begin{macro}{hminsep}\param{=\meta{méret}}
% A szerző és témavezető dobozai közötti minimális vízszintes térköz (alapérték |5mm|).
% \end{macro}
%
-% \begin{macro}{cityfont}\param{\texttt{=}\meta{betűtípus}}
+% \begin{macro}{cityfont}\param{=\meta{betűtípus}}
% A város nevének betűtípusa (alapérték |\large\scshape|).
% \end{macro}
%
-% \begin{macro}{datefont}\param{\texttt{=}\meta{betűtípus}}
+% \begin{macro}{datefont}\param{=\meta{betűtípus}}
% Az évszám betűtípusa (alapérték |\large\scshape|).
% \end{macro}
%
-% \begin{macro}{datesep}\param{\texttt{=}\meta{elválasztás}}
+% \begin{macro}{datesep}\param{=\meta{elválasztás}}
% A város és az évszám közötti elválasztás (alapérték |{,~}|). Például |datesep=\\| esetén a városnév alá kerül az évszám.
% \end{macro}
%
% \subsection{Parancsok}
%
-% \begin{macro}{\setkeys}\param{\texttt{\{thesis-ekf\}}\marg{opciók}}
-% A \texttt{thesis-ekf} opciói az alapbetűméretet beállító (|10pt|, |11pt|, |12pt|, |fontsize=|\meta{méret}) opciók kivételével ezzel is beállíthatók. Ha a |\setkeys| parancsot a konfigurációs fájlba írja (lásd később), akkor abba az alapbetűméretet beállító opciók is beírhatók. Azok az opciók, melyekben parancs van, mint például a betűtípusra vonatkozók, csak a |\setkeys| parancsba írhatók! Például |\setkeys{thesis-ekf}{logodown,tocnopagenum}|.
+% \begin{macro}{\setkeys}\param{\{thesis-ekf\}\marg{opciók}}
+% A |thesis-ekf| opciói az alapbetűméretet beállító (|10pt|, |11pt|, |12pt|, |fontsize=|\meta{méret}) opciók kivételével ezzel is beállíthatók. Ha a |\setkeys| parancsot a konfigurációs fájlba írja (lásd később), akkor abba az alapbetűméretet beállító opciók is beírhatók. Azok az opciók, melyekben parancs van, mint például a betűtípusra vonatkozók, csak a |\setkeys| parancsba írhatók! Például |\setkeys{thesis-ekf}{logodown,tocnopagenum}|.
% \end{macro}
%
% \begin{macro}{\hypersetup}\param{\marg{hyperref opciók}}
-% A \texttt{hyperref} csomag opciói ezzel állíthatók be. Például, ha a linkek színét pirosra akarja állítani: |\hypersetup{allcolors=red}|.
+% A |hyperref| csomag opciói ezzel állíthatók be. Például, ha a linkek színét pirosra akarja állítani: |\hypersetup{allcolors=red}|.
% \end{macro}
%
% \begin{macro}{\geometry}\param{\marg{geometry opciók}}
-% A \texttt{geometry} csomag opciói ezzel állíthatók be. Például, ha B5 lapméretet szeretne, 20\,mm margókkal, kivéve a belső margót, amely 25\,mm:\\ |\geometry{b5paper,top=20mm,bottom=20mm,inner=25mm,outer=20mm}|.
+% A |geometry| csomag opciói ezzel állíthatók be. Például, ha B5 lapméretet szeretne, 20\,mm margókkal, kivéve a belső margót, amely 25\,mm:\\ |\geometry{b5paper,top=20mm,bottom=20mm,inner=25mm,outer=20mm}|.
% \end{macro}
%
% \begin{macro}{\singlespacing}
-% Alapbeállítás esetén a sortávolság másfeles. A \texttt{setspace} csomag |\singlespacing| parancsával visszaállítható a normál méretű sortávolság.
+% Alapbeállítás esetén a sortávolság másfeles. A |setspace| csomag |\singlespacing| parancsával visszaállítható a normál méretű sortávolság.
% \end{macro}
%
% \begin{macro}{\logo}\param{\marg{kép vagy szöveg}}
-% Ezt a parancsot a |\maketitle| előtt vagy a konfigurációs fájlban (lásd később) kell használni. Ezzel kell megadni az intézmény logóját. Például |\logo{\includegraphics[width=9cm]{logo}}|. Ha nem adja meg, akkor az Eszterházy Károly Egyetem angol, német vagy magyar logója fog megjelenni aszerint, hogy a \texttt{babel} csomaggal melyik nyelvet töltötte be. Ha nem akar logót, akkor írja be a |\logo{}| parancsot.
+% Ezt a parancsot a |\maketitle| előtt vagy a konfigurációs fájlban (lásd később) kell használni. Ezzel kell megadni az intézmény logóját. Például |\logo{\includegraphics[width=9cm]{logo}}|. Ha nem adja meg, akkor az Eszterházy Károly Katolikus Egyetem angol, német vagy magyar logója fog megjelenni aszerint, hogy a |babel| csomaggal melyik nyelvet töltötte be. Ha nem akar logót, akkor írja be a |\logo{}| parancsot.
% \end{macro}
%
% \begin{macro}{\authorcaption}\param{\marg{szerző neve feletti felirat}}
-% Ezt a parancsot a |\maketitle| előtt vagy a konfigurációs fájlban (lásd később) kell használni. Ezzel adhatja meg a szakdolgozat szerzőjének neve feletti feliratot. Alapértéke \texttt{Author}, magyar nyelv esetén \texttt{Készítette}, német nyelv esetén \texttt{Autor}.
+% Ezt a parancsot a |\maketitle| előtt vagy a konfigurációs fájlban (lásd később) kell használni. Ezzel adhatja meg a szakdolgozat szerzőjének neve feletti feliratot. Alapértéke |Author|, magyar nyelv esetén |Készítette|, német nyelv esetén |Autor|.
% \end{macro}
%
% \begin{macro}{\supervisorcaption}\param{\marg{témavezető neve feletti felirat}}
-% Ezt a parancsot a |\maketitle| előtt vagy a konfigurációs fájlban (lásd később) kell használni. Ezzel adhatja meg a szakdolgozat témavezetőjének neve feletti feliratot. Alapértéke \texttt{Supervisor}, magyar nyelv esetén \texttt{Témavezető}, német nyelv esetén \texttt{Betreuer}.
+% Ezt a parancsot a |\maketitle| előtt vagy a konfigurációs fájlban (lásd később) kell használni. Ezzel adhatja meg a szakdolgozat témavezetőjének neve feletti feliratot. Alapértéke |Supervisor|, magyar nyelv esetén |Témavezető|, német nyelv esetén |Betreuer|.
% \end{macro}
%
% \subsection{Konfigurációs fájl}
%
% \begin{macro}{thesis-ekf.cfg}
-% Az átparaméterező opciókat és parancsokat célszerű egy \texttt{thesis-ekf.cfg} fájlba írni, amit a \texttt{tex} forrásfájl mellé kell tenni. A dokumentumosztály betöltésekor ez a fájl automatikusan betöltődik. A konfigurációs fájlban az ékezetes betűket repülő ékezettel érdemes beírni, hogy minden kódolású \texttt{tex} fájl esetén működjön.
+% Az átparaméterező opciókat és parancsokat célszerű egy |thesis-ekf.cfg| fájlba írni, amit a tex forrásfájl mellé kell tenni. A dokumentumosztály betöltésekor ez a fájl automatikusan betöltődik. A konfigurációs fájlban az ékezetes betűket repülő ékezettel érdemes beírni, hogy minden kódolású tex fájl esetén működjön.
% \end{macro}
%
% \begin{macro}{\AtEndOfClass}\param{\marg{parancsok}}
@@ -366,20 +364,20 @@
%
% \subsection{Egy példa az átparaméterezésre}
%
-% A következőket írja be a \texttt{thesis-ekf.cfg} fájlba, majd tegye a \texttt{tex} forrásfájl mellé.
+% A következőket írja be a |thesis-ekf.cfg| fájlba, majd tegye a tex forrásfájl mellé.
%
%\begin{Verbatim}
%\setkeys{thesis-ekf}{
-% 11pt,
-% centeredchapter=false,
-% titlefont=\Huge\sffamily
-%}
+% 11pt,
+% centeredchapter=false,
+% titlefont=\Huge\sffamily,
+% }
%\AtEndOfClass{
-% \hypersetup{allcolors=red}
-% \geometry{b5paper,top=20mm,bottom=20mm,inner=25mm,outer=20mm}
-% \singlespacing
-% \authorcaption{\+textquotesingle{I}rta}
-%}
+% \hypersetup{allcolors=red}
+% \geometry{b5paper,top=20mm,bottom=20mm,inner=25mm,outer=20mm}
+% \singlespacing
+% \authorcaption{Ãrta}
+% }
%\end{Verbatim}
%
% \StopEventually{}
diff --git a/macros/latex/contrib/thesis-ekf/thesis-ekf.pdf b/macros/latex/contrib/thesis-ekf/thesis-ekf.pdf
index 3577d171b8..1e4539c51b 100644
--- a/macros/latex/contrib/thesis-ekf/thesis-ekf.pdf
+++ b/macros/latex/contrib/thesis-ekf/thesis-ekf.pdf
Binary files differ
diff --git a/macros/luatex/latex/piton/piton-french.pdf b/macros/luatex/latex/piton/piton-french.pdf
index 8095e34c2a..ffb413000b 100644
--- a/macros/luatex/latex/piton/piton-french.pdf
+++ b/macros/luatex/latex/piton/piton-french.pdf
@@ -354,21 +354,18 @@ endobj
<< /S /GoTo /D [ 205 0 R /Fit ] >>
endobj
208 0 obj
-<< /Filter /FlateDecode /Length 3340 >>
-stream
-xÚ½¹Ž¹5Ÿ¯¨P‚!Š|'0 KíZ`3{•­7òbXØŸïÇûªªéõ(Lwùî“õÈ—.|ù鉧ÿëקϛ0‹0 „’rùúÇ“ '| Á8ˆÅGíòõÛòë3çÒp±iÎ87’síâgy¥Ïþ?ý)á¿¿|Bq_è©}1ö9íÄ—ß¾þì‘Û]ä(5shFäJFiB’À¸…ÈuJ3-+(µPLj•Á¬kØV8Õ†¡ Ae:¯BâRYâ´G/`ž#'„6|ödxrp­¿H’°K f´qÑF34…34‘»~íÁrRý‡ºÆÿ‡-J"üÙGós©€FfŒZ´B&ªTô…À»Ì¯\“Ö¸×kþU¯~Mü.¡Q|±Ìi¶ÃbCÄEs’.©2«ÞÖh+úñlk–™Ûƒ$ÈB éE‘~¬so°ÄD§Ø…®-ÓFŽÐMí€F‡ Ì/À ùò ÜsüâéC’*©æ9*ÑS®Ë/aMcÒvO;P× ñ jMä®»»¥Ö¸9mšË$Ü`«"rVÌ$ªÖHQ¿3ªÅƒàJÑžƒÂ¶,^ÂxíÜRpr^C2%Cr²ˆ”Â%9Á%>Öh鉾øO*¡Ô.Ó^o3y¥øò>þØõëaÍOƒe^£Ž"„"X[™ïÏ1/âƒÈ¢
-6E
-¿ÚÈQL~6"JûÝK„}"ÌL­_AüdJ1®ÿm¥.‰[5â—)Jëk ÇÿâU…´/)æ'çI¾¯8ò,gE‰/oôO0 Ê
-ÔX³ a ´<¹’·ÄQ“¡hln°Ð”ÔB^¥Aˤ FHÞgålÀÈ|FèÇ)}—B¡4³v¢ñÈ_‚2B^.>R¾eÉžöð”vÃ>;úEÜ{­!6f¯Oç5Y"”l™3hUW
-#&õšÂS!y+ž*‚’lkâaáI(Ï+Žâu„vé"G²?cwµb ÑÇÇH~)‘Þº–ôðlJ‡v'Æ¥>!˜”l›ؘ&°M2)<ãÚÐ&sšR€ð/½‰Ux˜ ¼cóÔüÊ~}gÔã¶ÿ¼\ÐD® Dëfšvª5ºZ7Ê:¨šxÛT<JK®%Ü%Éúx¬ÉèT_wœŠVPŒ#¥¡ìÊr°5œÆPxê¦ Ål1BTªlä¯ç–hV*ò¸)>Ö¨›å—<å‰mG Qo-†€/Ù”·íúT¦Ö £M»"[S„Ö;aµÒƒä4ØŽ’LXÓ$£b8X£„ ¯¦´‘ ŸsvÏÏuƵpf¾5&î³á¨¢Ÿ(p}Å"Eh]‡]^~Aºæ IõÒ#Ä^OiÑ@©Æ;} C¸Ÿç®Iª*µÛQg(ú8uG–J‘³x÷g †µÆîø¤íÉ|¬.鿉µ[[ðlk[Ô ›¨M¨Œ¥ÆŽ-K`€%Üá™7±BB(ð’gf‹/´ñLMnój´È¿6QåTóTl+ì)—<þ™o}¼ÖÒºC%Kf8,k82I•ù€)Z„(ž_¸ºKv¹ÕEOü¹D·ÐéNª™æP"n­Ìƒõ\«ÅõÑ&—ݵ}/ÔæF/a£Û&)RPÚS¥Ÿk*}€¹×eQŸ%ÚÊ.WˆÿéÓ¾n†”)¥sùöj錸Ó@B¡6÷\yOéµ°k…#Ÿ—Ò% ’㚊*¹-f„Û=|Y`–ú [Ï»¹JC©‡â·Ý
-8Šk·î7ÔŸÛš—µ‡]í‰SïyÍ+«ÔǼßVFé àÌÇQ#S\ò™ë›3úÝœú±ô~Œ´é$l_ñõ’’ºynöpÜÑJÊp@9‰¦FK˜¤?½üÇ•ç/ûÉ‹{g´À¤Òm©[T´&Èñìý°è RŒ´)tYZ•¨ò‰¦ºW1ÓÞöŽšÁ–Š²4“Rž`½OTú†SÕ‘’Æárã”ÌóU¹™R‘0S˜ÿ}z#‹R²œ…çÃO47Ñæ£Æt’…GZâIeéc§²¤î~oŽå¹¾O»ªË¢î!øNÃÇ8¸Öþ@žL~ü(ÛÔRª€)§G<(slö²ö°òÇn¯a¦½
-Â+‡]®¨ö;+æKâ’ne¤¾~m±Šlb‚‘ϱõfëp;Ѫ öÁt¤&¹´öXÿªx
-‹ „/Ñ&Õi è@«ký+G*¶©qs×ö&押¶ë×Ì(ëWÎôMófÀÙiµ>¥or $I
-ÒÌ´º©›ÿPœ9éîð&©èe
-a‰.Ò}^rðÎ"{IÑWõýW=<:“ßÚs¬ö”oÿô±LI;áÏŠÝl¤DŒP õþÎÿwÁþY·R d¿éOñhZŠ8á?À‡?}<} b(`[9Šø ì"%tŸýGnÅçS~QP æ†$» óáÏçøÈÚÑLt¢8GIÙF
-Ýïú §¢EÒ‹vz²Þ‰S‚Ãôè$ ÀêË)Ñþp0@þñüÜ”"¼˜iÖ§#$R`ìj”dJÅöWj'´Ì9ù>µS»Ô~psÏ["Qi¿~
-Þá+þâ¦Tð&5@¾ ßÇF)þP·Ê”â*õ>6j©G°úm6êY¡oµQŠ[DóöYO8Á(¾ÿŠfÄõýçD{ÔG™üåëÓ¿GV55¥°üãÛÓ¯¿ÑÏ¿ÓßÏ^QÎ.ÿ ¿Q¶¢öOømÿZ~yúk¼ÔGjTäiFu· (›(­Ãe]oÕ­y6a1´‰°öå6µÂo¢PÈëxÈ%5éJ–!3ãï¹yÙÌ¡¸|aEµc1á¼·™óZ
-“^ï‘é ’NŠOàOÿê5¯µO1å¼"‹…¿¯À­}ï˜\eDþÜn§\RV•{ÏJ×\½ÃžžÖˆ½­y\¼s’Y½5—°–^¯D÷-œ\»3àÚiVr߀ ÈI1ŠÒ¿šÅk3—£¡}Å„ô#—¡×ík9ª[þ/q{
+<< /Filter /FlateDecode /Length 3343 >>
+stream
+xÚ½¹Ž¹5Ÿ¯¨P‚!Š|¼ö
+ìÄþ|?gUM÷¨GÁ`º»ÈwŸ¬G¾üsáËOO<ÿ_¿>}Þ„]„e ´RË×?ž>á‹X@ÆA,Vx|薯ߖ_/œ+ËÅf8—À¹UœŸ>«+~ÿñO‹ðýù“ävpñŸºgë.y§|þíëϹÛE.•a^Ú¹V A@š‘d0~Ar½ÖÈL Æ)Z/4SF˜uÛ
+§Æ2éÅ‚P™C«$r©r& –Ï`/‰D?29r­¿Y“IR°KHÃpãb¬aÒΤMÜ%ð#è
+YdŠXá%;ÚD!æ¨~ ŸtÆi<}3A/Áhhe°síü9òÖÃJO£i^“’„"YW¹ï8§Ø—ðAâ1D—#FXmÕ(§°C62ÊûåGS„…L¢6¬@~ˆR™ÖÇÿ®R—å-„ñ«­Íµ…~ º’¸W¾ä˜HO:×S|_sèZV+ÒÜ[4N'Fh÷:¨vlH Ñ((Wfi‰\dYÉ$âÂrr®j
+ª¬JNSö‘vÉЙ’ £P3órŠaþƒ–ìCQ€»‰¡ˆÑòìKÁ)¤f+’¢±¹ÁBsŠÐ‹G)aJ˜Ñ)ç™ýö@«ö` Íg„~œÚw)Ú0ç&ü%*#æ³â#åùyrÜ“3^ÚçF¿H{¯5ƦôÕá鼆$¢¬k¬tº«RP­N‰EaòPªÑî™
+µ*)á°œáXû`a>`J!ŠÏ®î’õž¦è‰_JX‹}é¤J4ÇÊpke­çZ-®3Tm׶½P˜QÂ[•¦7J”®T›K­Kã Œ¤#ÖC}zh+:ªþ¤øϿئÞõ3$ú¥TÌåÛ«³”;}#j©Õ¢=¥Å’]œø|)ÍÑ 9n0µVÉm)PTðUY
+7ÙzöØÄUJ!”¾íV¾I\»•o¿ñ ðÜVZÖžAtE§œZÎ+­¬R~[åó3—F2Íõ(O0‰¹¾'Ãßí©«àÇr‚6€í ¢1¾³RaÏíŽ;:HÏ%' ÉÔp Søg–ÿ„“rúò·Ÿ‚åqË,0
++æü´:ÅëN«¦›&U.Gñ€£üÅDÁVóD,ûšC#“Ëãs(‡Q{‡_g«µŠùN1§‡-›s§[cÙûLåãbE„ÚëyD)º%ö„ƒD3íÕ°‰<³_½{ `DüA±gÀõ€Ø3Sß6'ߧÝ\8Ì-úÊ•ð¸wÝ×—u̪]<‚ '™·n„}Is-¾#×W¢é¹<
+ƒÑQl¥v’ñ}ŸÚ©‡]j?¸¹ç-‘¨‡´_?`ÿåêˆÔy|¤.ý!µWîäzüùtlîûr¥6R{Sí•ë¶~ïAß—¥"°Þ×æÇTU=®:%z›®I23Ūv&‡4PÖïN'~¯¼åÏ=Ûˆ÷žóFªÐ¼V'r>éiG”ôãîoc]stþPb·[ü»y
+Þd¢ÐÔûØ(ÆúV™bü‘Z¿:ìœy›z‰5Š¹ÕF1n!Í6Úg=á±ïR?¦¢q}ÿ9ÑõI&ùúôï‘U£˜÷rùÇ·§_ÃßÇ¿Ÿƒ¦¼[þW~Ãt…ýŸûþµüòô×t±õ¨ÑÕ¬în@`:ÑÆÄ‹áÒ[%7Ábq•eó†{ 6i¦ë¥µð2véZ•I³pëïÒ¼’l†Q<]VÑílŒáítijÑ"ˆ2q²†GŸÊL’VÃÝöü¸œSD„á®Z¼"'[ŠË\šr{ŒŠÉ 
endstream
endobj
205 0 obj
@@ -378,7 +375,7 @@ endobj
[ 206 0 R ]
endobj
206 0 obj
-<< /Type /Annot /Border[0 0 1]/H/I/C[0 1 1] /Rect [ 222.163 133.041 393.939 144.498 ]
+<< /Type /Annot /Border[0 0 1]/H/I/C[0 1 1] /Rect [ 222.163 132.814 393.939 144.271 ]
/Subtype/Link/A<</Type/Action/S/URI/URI(http://www.inf.puc-rio.br/~roberto/lpeg/)>>
>>
endobj
@@ -389,30 +386,34 @@ endobj
<< /D [ 205 0 R /XYZ 79.37 771.024 null ] >>
endobj
5 0 obj
-<< /D [ 205 0 R /XYZ 79.37 539.331 null ] >>
+<< /D [ 205 0 R /XYZ 79.37 539.104 null ] >>
endobj
207 0 obj
<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F17 211 0 R /F18 212 0 R /F19 213 0 R /F42 214 0 R /F50 215 0 R /F49 216 0 R /F51 217 0 R /F53 218 0 R /F15 219 0 R /F54 220 0 R /F55 221 0 R /F62 222 0 R /F63 223 0 R /F65 224 0 R /F31 225 0 R /F22 226 0 R /F33 227 0 R /F32 228 0 R /F48 229 0 R /F60 230 0 R /F61 231 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
241 0 obj
-<< /Filter /FlateDecode /Length 3547 >>
-stream
-xÚµ\K#¹ ¾Ï¯ðE¢ÞÀ`€v{½@n æäìæ´‡ìÿ?„zP¢U¶{{=¶«TEQäÇG¼ü÷"/¿~¹þøò·»Õe„6.?~ÿ¢ð†¼¨‹Bû‹·A¯.?þ¸üë›”îúý«’RâWƒŸæ†—
-ð
-\+½ôiðjº˜.¤a÷kz$ iè}ý…ãni¹tÕßÉïàÓd÷Âr%Å6é{ewpÃ<+‚ E€Ÿ¡o¨w§"ÑÚ
-j+’xÊ6Vø§ÙIú”„¢ÞÏÙ‰V(½î³-tÖ±Hij^Ñàð=@]’קK2.ˆ á“E\ÏN†h&ÞCå=s‰ª ¯I¹¾ÕÞÔYËSžDú¦ÈÛU¹µ¤ÙÆ•ïº(ò鉉RX¥fê^~·î[ÞMäÖâ··@|»~¢ë=’[æGÒU¾{\´‹…ízyæd×OUedœWñWuÕ;au\¨ºD…8NZXìK[÷d"Æ•…ÑŸÍœBÞƒ2:[Óò=Y°,7%UYW–jÙãI% Þ.‹467Ò™Nµš© +ÙKÜèjÞõ[Ùñ2†(5ÛÙ–û*k•
-¨lÐÑp#ènÌ6﫯O • m„Qö'=­ÕLýe£‡Š;*”»ã¡ÓAuýuªÐˆjöÚÎ7æT®ÕÔQ•‹¤A„Íu2=užþ¤%YøÐ)­Ò¾÷°n4ÖÊ¢™Ÿká ÚJŽ· #x.‰ì ÊLo|ô¡ßGÄ×°Y¡8õöÎ!¼‘™ðTä 4ŒËâ~j$i„BCC4ÓÆÇóMñÙÌKh‡.‰¦ýÚ©B¹Óü
-tÿÓ i†â(¢g‡ÿÆÇŸ6qíJ‘? Î[â|ˆ³áœFHC”¾Ÿ‡Æ.f±ŽR:™ùLâFaŒ‰)Ól#¼waU=6 ÿJFÌǃÈâ­·ªo©.‚¯ÉšáÞC6 à6ZÝç·cõ G§m˵‰ ¬‡ÆµäÊ0Ê·á|LzE ¶<I[î+‹9Oúó|³ªR&(-†SM y!3ù„c„´3ÁºÔS­Fo©õò )[¶ä|d=ÿ¾Ëö4ÿ@8³Îòþö3Þ ÇPÛËœá3î¡l¿Úl´µ¡oÙ|û'œ9F_Â3±!‹ä”gÑA±ƒÇó+iTz¶Ù*ÏU]Ö݈O¹Àµ#3¶14²ùCºÒNuùu#`ÎÙs7>úð ”ñ×1ÍTF³t[Ã`òs®me=Ù"Œ#G§¢ù’ÂV³¿åò?P—Û¥^!n¦3çžøwÉJá!®9Ýž|˜c<æ+oýÎLš ñ%@¯¿nc„t%bpnæMü²Ïà¦ëç碌鉖óSJ(if.ö&^§’Hƒ—ðË´ÎsÛê©É­¯B·qÍ¢;ŠK˯ÐòÀM±*‰kOÛúoÌÛ9÷%?2^\àÙ2blœ>zº¶$‚dò3ƒiÈãÙRNs6kæÆrxU %!ÍÄUS dLv*Èe@ëßÂ8ØaN[
-Z–Ô›s ”–Ôaþ³áœN%—^|¢pŽÕl)œ›«&L´jÕ€ŸœëÂ=²ƒ±O ûA‚š©¿ö9cœ©” üÜ“ÂMòîîà ]Z;o„—aæõù:^A;‹øÀãëTõ´v‘õÎÂik…ìXÇÕ„B63*R0kvNQ Ü´QÍ ƒd¤Eb”ö&Y÷^ÖÞƒä¿öB;5¯(QlÙ¼ŒZêÞÊE
-5°q•%Iç,k;çA+gªîÉÈg»?$Âò•'w`Ò £…RþqœÜOÜ!/9Ôsq¤I~£I©> tCZ‘꯯†´×'WÜWòI® Nªyþj¸6R¨¸Èä–Ncl±“Ë‹–n]G­¨ž[;ãb´e(•Ó7WB¾L–­|¶BÝQe]kDŒ¸·twÈ*5ð6`gŠ•f€Ä²WŸãgÑ­3 ϯjºqÀÌTÆ5=ö³ƒm¤¬Fƒ{sm§'eÎ×ÿ,î‚èEˆ°à®^cÜôrLuÚçÖãÑFRµÿ"”æe×'„÷ˆŽÓ| c➣½2§T¿bÝk´­ÏD_p$Á"xtº&þ„t õÔ ª™JËÆ×øß´` %ýœÞ†±ï¡µïÄ!}ÂäÉî®]-të´±%càЊ=H"mp< éò¢rª6.aÜÂÍÖŸ·ª Æ£8 ÌË[Fí*3¥îHMGò’Mõ¿?y ëŸ7-–Y3B×/#tô»ÙWMÔôŒ^s¶Ç{t‰8#œt ï9Jê ¦¬PÖ'×üAŽ7ùaŒ#æÙ¦è#àjTƒg4´Ê‚BÈl›i.‹WÏ-^Š˜š§ñß_¿üòãËÿº¬1²>M•|¸üç/éF*Cz›Ü‡Ráòço—ß¿üo°þëEpQX'Î?¢ì ”‚Y)±ºnQµ¶ÿU¹œU¼Ë(8´C‹`íVCA–úFì w¹{«2ìSY}d'­M\¾•džŸŽ»™ˆR3ßh³ÕSÒ40ç]®Dw¹7ÿÈë8Ü`¥ïéž¾·Ê~«!íªWäõ’v`µ´¢Ç6ë±E5<ÔAZ€p6œë`1Rdʵo¥ƒk_Y³\ A—9¤z§‘-1¹×¤»¶ËúYÌr) þ¹ËŸé<Ñæé}aHá!5ËŠ:×…n9ž‡Hêqn¦âêÓ"äQ‰§ú9âÁ•‰Ë³«”Nz×}@Øæ§GyvN^–F¾P?Ø—§$º3X%Õ²¦2Ùg´Ðóg–Þþ“¦‘.—ÒfiÊ­ô Záà—Ѧê)AÄÀûT˜ÛLv,"Þúœö³œÅ¡çî;+@ÆŽ—nx‰eÈq–rŸtëlÕ£L‰I*εî$è³÷뼪½fÁR4¦ìОœ´ŠZØÖ¤9:éÏÀ\Ç®‘^ @€é¡¹n<k2©„×æÏdÖ“q9…p)ÐNu¦6yoðnã½QmO½w}nï¹ËÃOyîB…¯üáÁÅ·©_¾2ñ8*ÏÑ"’“4·¡NB”߶}•ó‘V!e1¸ n]KN~¡Ä‹
-÷ÕØxÔ)–ió×]ŒSßÆäƾ.GTÛ‹Ó¼µÕ©ÖÀ:Aœ2py‹A c¦63– ‹ê4²7NiÛ‚B·zb&_Y4´<ÑÐí¶!6va8 <Qf(üì) GR¥˜!³Êßkß=)jiJį˜ü˜™%X.ÔÚ š71À¼Ì‘…õ½™³*é¶Í½n{¶=†©Waš®%‰öXYF”'6é …Þ>¶T;ÞrcÙ¹Kmó :¬F[ÛÇ?~¦«Ø3^Úã­Þ=ÁK£]‰'ÎÛˆJí$¥ú #ÛÈYä­-õagþp, ÏV±<?д!½
-n¡ÐsûŽñ/ÚzÐVDµLöÉ´Ò‹js³P&d°¯+VMõ®ö ůþÆ«$ù-Åvf5 í—8Â×fïBȤNu821kƬ²ÛGÃÞümÁ”ÜÚ Hÿe‚ñˆDôýi:’ÿ 7ï¤
+<< /Filter /FlateDecode /Length 3696 >>
+stream
+xڵˎ#¹í>_áE¢ÞÀ`€v{½@rJ0· § ›C°‡ìÿB=(Q*ÛžCí*‰¢(¾I¼üû"/¿~¹þøò§»Õe„6.?~û¢ð…¼¨‹Bû‹·A¯.?~¿üý›”îúý«’RâWƒŸæ†
+ð \+¼ôiðiz˜¤a÷kš’†Æ4ô¾þÂq·´]zêo äwði±{A9’ b[ô½"'¸A‚Á„Ç$ÀÏÐÔ»S’hmHµ%I<ÅG+üÓè$~JDQïçèD+”^ÏÙº똤49¯ppø nÉëÓ-DÐðÉ$®r ÒÌ„{¨¸g,‘ô51×÷¯Ú›ºjysŠ³‚(ÀÀßz»J‚–8Û¸ò]F>•˜(…Uj†îåwë¾åÓDl-~{ „·ë]ßÝ2>’žòÓã S,ÐèÔËœ“S?eU¤‘qvÞÅÿË«Þ «ãÕ%(„qâ¢_Ú¾'1î,¨ˆ>7c
+ù Êè¬MË÷¤Á2Ý”Te_™ªåŒ'~”€|8-Òؤ܈g:Ôª¦‚®8d+q£§ùÔoåÄË‚ÔtgÛJ쨨U
+ tºW +5hN¢Ÿg¨A^¸Jf¢Œö•B²[1 sð:|q<h¾Ù\—%NUWp"&9+™ÛdzMÞÀ)K[¥Qýº…9†´€¨™¡/‚ª“bHk5&FÏoø vmέ—Èg®Wˆœe$9;Ž—A-ì
+T›"ø8ïäE§œ&,P‹¡bb
+×FÆmOeU謚~ƒ®,>:bg’4ç“ûb®´JbvóV©fç¹E
+ÜνE¥„“qž•všéà_ÇÃ:á—Í0pˆŠ—ˆJ˜g&Ñð2 =BQ .é(=yåÉc'Tt¡^4µæ¾ŒÙ©¾õo²G}®cn]vž5wVHPîÕö:Q‰h­ò>JQ­í&ÿ­x±šr„·âT6×Ñp%ènL 6뫯O  m„Qö'(=­Õ ýe¥‡Š;(ƒ+wG¡Óêúë8T¡Uíµ“o
+Ì)]‹WSGU,‘7h®“ê©ëô™–dÁC§p´RûÞøÑX+ ?d|®7h;u8Þ&ÁsJdcPVzã£í>*& ¸†Ã
+MàÔÛ;Cx#5á/ÈÈAi5–ÅóÔÒ…Š†`¦ƒç‡ã³—Є.‘¦ýÚ±ByÓì
+tûÓiŠâ(¢gÂããO„F\;SäOrŽÇ-a>ÄY pN#¤!JßÏCc3YG*¬|Fq#ƒ0ÆŒÀ”iºÞ;±*ŸÐ%%æãAäaQ×[ÕTÂ×d ­pï!w à6jÝçcµ GÒ¶ÅÚDÖCÃZrfåÛ _‚-OÒ¶ûÊfŽÃ“>ŸVeªÓ¥Åp
+¡i£3.¤&Ÿ0,ƒvX·zÊÕh-µ^&šrdKÎGVùü»¬`Oó?„3ë*ïOø~Æ{á˜×ö2f8Ç=¤íW›•¶6ô-«oÿ„1ÇèK¸`f²xANy<ž_I£Òܦ«<guY7t#<å×î™±ƒ¡‘ÍÒ“&Õå×sŽž»ñч‚RÆ_Ç4SÍÒm™ ƒnÈó\;Ê*ÙäDGNMND³%­¦Ë²?P·Û©^]Ü gÎ=ñ-î’•ÂC\sº=ù0ÇxÌVÞú›Ñ1i:Ä—
+çX͖¹¹jÂ@«V øɹ.<S!»3öiaz fè/‡}NÄg(%Áo‡îÃMôîæàÌ»:ÕvÞ/ÃŒëóu¼âì4⋯SÕÓÚ…Ö; §­²û:®&²šQ‘ê€ù[ÓsŠJà¦jF$3÷%$-£´7Ѻ¯ð2÷$ÿµÚ©yG bËæe¯¥ž­|P@(h&h¦gB+öMñ=¹_IÑ5ꤨñ@«P½V#®´$êœemç<hÅLÕ3ñlï‡DX~òä Ld´PÊ?®ƒ“ù‰;ÏÆKîê¹89ÄI~ÃI©> xCZ‘ꮯ†´×'wÜwòI® Oªyýr¸6R¨¸ÐäšNcl±£Ë‹šnÝG­¨žk;ãúhË>Š£T¤o®„ |™4[ùl…º£ÊºÖè1:àÖfàÝ!«Ôœ·Áw¦XivXöêsì, wëÌ‚ó«œnœ
+—?þuùíË_ñë¿>`…uqÂü#ÌžœR0+$V×-Ì Öö¿J—³Šw‡zh!ì±Òj(HÀR߈}ã®!woU†}*«ì Õ¡ŠË¯²Ì듸› (5ó:{`=%@ƒî¼Ë•èN÷fy§;7ä°Ò÷ôNß[e¿ÕvÕ+²ˆzI;°ZZác›ùØ"ò í
+Ê(ëÕ›nb¦œðªåƶåMOêŒðNMoÛz©n¡VY‚ÝñÙÔ®N%m\†úÏñØgˆO$<P o¥ÜÂÐt,s¬mñßÿ\ú÷¿LÂI§$•ˆ¨ªpºtÏ \0ÒÔn+›Ê]êT÷JjJ©ùû`5 V15úå¨ïZ¶¨õSqpR`Î-a°SÏwü*m„–nÕ"ßËÐjÐ[ÏÔÐ/ÿg^[§V®0/öÉMÁ©u@Û…$“?gXŒRIÞ6 ßzé®]¢PÜߘL4§»J`Ý}Ø:©›2èùØÃxëô67Љ§çÅ †ñ.k£èºwÝÃx-j§½G‰Rs.‹«‹±g÷ë¾Ûÿ±ªyë¥vv »¶C:_¼ïÊü=å·õ–òëÝ„Ò¸Ó…¬2?¤Î¹šóNCËSÖ| wÜô¶y±cþKãÑ£Ñö_ФA¨Kÿ„fw»
endstream
endobj
240 0 obj
-<< /Type /Page /Contents 241 0 R /Resources 239 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 232 0 R /Annots 244 0 R >>
+<< /Type /Page /Contents 241 0 R /Resources 239 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 232 0 R /Annots 246 0 R >>
endobj
-244 0 obj
+246 0 obj
[ 234 0 R 235 0 R 236 0 R 237 0 R 238 0 R ]
endobj
234 0 obj
@@ -449,44 +450,46 @@ endobj
<< /D [ 240 0 R /XYZ 79.37 309.787 null ] >>
endobj
239 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F15 219 0 R /F54 220 0 R /F62 222 0 R /F67 243 0 R /F63 223 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F15 219 0 R /F54 220 0 R /F62 222 0 R /F67 243 0 R /F63 223 0 R /F16 244 0 R /F68 245 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-247 0 obj
-<< /Filter /FlateDecode /Length 3740 >>
-stream
-xÚÅÉ’c·í>_¡†÷ª©®jµF®rNqææòÉ©øø\òûwä[¤nši=‘
-VyÍû¼V1 sǧÆRC†ö^÷ïò³{aaÙ•Ö»º =gfº.uŸ›dTÊì®~(å I"Ð5BJ“$¦• 2a-ÊÑ()³<uzIdCfx³ÅV9~Bm¤õ½ Ä9#„wXà’Rt…Ê6KQ”E¹KM’ ')\DJ•5‹»9)iqϽÊçÞ“¶í;Î’p¿–Q›ÚQ2ᶪ§aYY‘aœcѧ(».x¤€³Àé1…ç:ï«ÎˆXµNr›p¬d„+f4ÚE­VÉ,J$ Þö} ÀQ8›ú¢‰¾è}¢³ˆ˜@צ_!‚Lš‘Ö›yUíŒf=ªòš)é2%©ýrE2ìkGߊmઔD·Ü¤[Ùº¹!åÅXÍ´óy£B\ã 4ä¿¿å±?ýBµf‡b`-ƒQPYФèûgà€B{Ðò±m2¹¬ã5¹Ìä×DÖfVÐïJêFÒ“3Ê ˆrCeaÙAø…©v:A:v9ɨ',ÅtB¤'M§4–9E‰õD¬¦PsµÒR ®ÒB©_oL¨VÞÅ–^ª ¨¸ÜÞ&5ýV‘t9«î)þdùK Ìxrq ¾™íf6B@3*ó¦RËІ™¬ïa¢Œ1Úh/¨…(ðúNÖeŠ3¶BýÎS[íK]©‰™hq1R`to:“òYÇì'Ê‹Ëñ)´(#~ç²²Òžv0Ž(4)
-QÕ ÚΤ~V–˜F‹ôK·ë²Î‚ù>aï<>q$MÈó“ÑWí0FebóeWû­$i…®ÛOÑÍŽÆÏ
-m)šQLù…ž9Uœ*M<*ÄùZõŽ/þ/´]…ƒ{ž( iæ fѲå_³:V§¼^WŠ²ÒÓ`ŠŠôKŸVd'œÕzku©Îw[elL: ö 2`
-‚)I'&ÿ¿˜+³Dy ¥Ú0©–V‹Ío½E?Öãm·ð .ϲ^K4.&Mi…‘R
- ý–¢³Ä×}\Ð846â²ÐYæ
-fÙj²ä`„ÄÌ^I
-º˜áCÃ*Q¾Œ¡Ó;B-÷c-Ã=ÑYZšz ÿL*¹ŽR0lÓ(
-½‹5÷Ï–BtWFœŽ6C GŒûré+­jŽ2c#Æ×\&þ:D-¯éL³‹F%#cŒr,qãÚ·×÷Añh F¼ñhå÷8:ð6oOĤ%¦a4ÊnØ)¦@O¼maÍã”)§+]cSœ a&l·GbïâÌûLÒ±Æ\‚g÷i ³0É‘ôkl%œ Øö«â%{”yÂ-휖±Ïû=ÓÆ!å…ÿD7NìˆÔ’BÂUÆ ºÏÞS}QÐ~ÚøäT—£ÜíV¬pŽËñb»(*–Eq¢ZÆîªÒ’Ü
- bª¶ŸÛðÜdQ„¥§ôé‘*â{êüµÔ±Yë—žqëp†¡JÙ¤ÜH(1ìUŽžo$á¼·‘@{°Kôl#¡TáøMí6Ö>Ø”¿½ÇxÍ@9Šù;
-§ÒO R/ºú)Ø_–÷(´Ž@ ^t)æ"œq´–•C+—Vž¼.1ùnt¹Íþ“¶¨[Kú”jã
-lu(#ì?¹ ¡ýϨCa{û3*°úm_êƵ·
-,Á{P%£ŸªÀ'+°”·V`éÊ÷+°Û3ØÅ>OT`ŸÞg®ÀR~îW`)¶R ïâPLªpq¾¹¸:¡Û+8´L/Û¨7i`¼ãŠ.‡Y˜èãg+ÃKBê’_Çì£à^]üU
-º$V©1{iøº]ÚŸÆž-—¤Ñ‡¯ŠP«ÚhšÛg>퉂öº‡ÒÎ%¯ý¨R.U–ûå.cZ.TÂÔ‹D!ëïP—{B›ÖÕF¥1Á”O¦õVcÞ<1ûVך¯@eRCKte½Ï¿¸!/ÂýXïû®iµH8W 2(Ù (5Ô÷D)ýª®©wc‹t“²¼³£ö‡YÐ_߸5±[ïïÂXsÂMé(d‹ä"ÞL tÜì.«;Ci;PºÔâ2õ€î»©yGãGïOÉ<\¿ e!;h+¹R½ìì¼we·Â ¡ÑVQˆ ºê\©ò]UíþE•p~…ã(Tò~ù²Õ8Nn§åbgždg^ᶾùWÖ;¿Ga¾cvò†án¯-î54þ¯( -]¤º×—¬ÌþŒ&–«(†¾Æ¹aÁÇ6x2sÄ]®ŽvõIØ/«pY ÌÄæTeûúíÓ¨ÜBÈ=äå×ß?ýü >ÿ~~ !!&†ÿ‹#G;«˜aÞ¿/ÿô·ôB. ‹rŠþ­Çï­Œ¹-ãÝU›×$eé"MpÊå¶HtµÞ+].¼-®àhÛƒ¥'géÖ#‹{»7 êKP×6xCoéË©F¨uöC×$P†ÅŠ Òhæ'‚Ö‹!k.Hd˜’΢·éÒæbÄqmñ5¼#)Ö„?÷TÆõuà ðÓÁ*œÜ¢’¨î•Wä.s"í«ËóÞßs¬¯UºƒC^y¥ú=øÂÈp80 ¥×,Ëýb³ÐcÄÛ«SBf×d¾ö!wúld)ã'‹±Ïˆl÷hd-#ánÆR@ÁÖÔ¦zÆ=Ü-®»›5Wåóˆ¹/@ø3§­N-Äôº‡ø¤˜ízl%†×Y‰rCµÞunú½ì­8±è#œí“‡
-ém—aJéð—‘ÌæÃj÷(’Sð[µ{혖”åçSWÌO%3WóÖÕÝj§ÍêÀ‚ä·[©…ŒŠOP¹ýƒS¯™@ÕP!~r$—G×÷µùÃ[
+249 0 obj
+<< /Filter /FlateDecode /Length 4158 >>
+stream
+xÚÅÉ’d§ñ>_Q? $kÄÄDtuu+B>Iž›C'ÛÒÁÖÁºø÷ìð–ª.Õ]õ$I’; üòë…_¾ÿtýúé/ïB_<óFuùúË'/øE\WLZ{±F0nÄåëo—¿æ\Y.Þ ç 9·ŠsãÓwuÃïá?~´¿¿üüõ„®ÕºvÌsO¡k• ¨” ÆÞK(ˆb„ Õ—ï¤ûœ~A~ùNyOÄ+>Éh'ÔÉoä{š”iO®¡kú„¾aÊ]Ë€(g>Pÿ~ÿéíë§ÿVLA3îbµeNÃå¿}
+Ï}cýE&„»üþ¯Ë/Ÿ~ÄÝÚ¹š7H… ·Äyk ÄOþérËkfR;åòÜ.¥÷ ´›F¼íO[ ˸ôÏš·ÁégÎÌî¼5·ÌðI
+"ÅüþÜ«
+qM±alòû¯¹íOßoçC²ã<ÂÁˆ³ 4‰ù¾OÀ™t’B»S– ô(CdЉQGÑ/‰¬M© ÑjC$œµ!$nY—°F»·$ÐÔŽ@'HÇö&N5 ŠSVFzPq‚ ‘4%Ö~šBÉÕ’Hų’°2êmú¸à˲Šú´Ga0²×I]dI—ý¯jœR˜Öe’õÈ(ø¦¶›ÚÞÌ(Ìc^€h†ÖÌÈÕÆ!u‰‹×­+{ÉÁI»L®c­P¿³Eד¸÷u¤&®«ÄˆI;´´¦W)ßé÷D~q-wY£Ú[N™ÈÊ~î'í+é”íhR¢Š™l3oú^% Pi‘Þt³.x–‘ߧÑ; ‡O‰2Äüd´•G3Œ.Y„جEËòæÑ'h5:–Þâåƒdk&1ÃØ\Û “5h}q}^¢åŠ?äk
+øåß—òí¯óÚ² ²ÐwæpL™´Á>âì Î@{2¨TûÎÐL;Ò Û|7-=±#qËrÃZÂS³©3ï8˜w¤ˆ^dÏEÍTL?$ö8q@|äµÁT¶|\HSÂX ºR¬œ'¨ÎäÖ6^Fò-2=‹ =9¡0%Ôºé®"݉œ«dܦ¼oyÚæÏõ~Â2¥-é4Z·àM±G•Ëge)oçE8óhæ¾±ì£F‡aŸD½¾"=Ÿ,w½DâŽÌ’$hŸ°S}Îÿ^îL¡-)CÆñÎ.ÄÌQâTFâ>'!öת7yñ¿Ðvå< †qx¢$ 0>ëwL²4Vs¼Æ+ùWéiÐEFzW¥óŠOË
+º„ ô±¬¬çq°Íº-3¨nµ¤£™‘æ #!˜ÚñÄ~DæÊ,‡<Sm˜“©–¾UóÊÉ~õ‘ o[…;…yæýóR¢d[Å$)-%RR-Ôo›éĨj!™1l-ïÊ£+&õy?Áu]ìQ2©Ð2©y;c2TDàô¨5Sè)¯˜o®ÀËa‚,löŽ“Øá~
+ÙïNføP”¼Ë ¾\)žè¸æ}J¢t¦ »p¨$¨Þ¯ó`·ægt‹²IÊG!í6ÁÔmbù>áSú@^{›µãíjT!VxŠ^Ô³Bñ–ö|‚ñ¥ÞÚÈ<]¸–·9‹H‚­•4‚ ÝÛ i·L (“Zw»_³6)Ä_Û·SéÖºÑiÍ–h wdK”c
+?&oíäq{ÇÀ:TÍœAfÙf2¼[[1L@úË»Mùk·X`QÑIAûŽ„[3µŽœz$nXÜM…*Qø‰6ë ™”F
+ˆÒ©Aø˜˜…ZP˜à笅H“°Êס¯‰I}ŠÛõxYŒaý;1òÜ\(ÆšøËúóBT¿;¥Še1üÔ`ôÂæ“HÚ{•ØÕËYC´ vLrôÛE%H=Žt5Aù Ù#ý袆+ C»w„ZÎÝpaïØ«KS·¢ã×$’k/Ý6í$…FBÔV%ý>¿&>33Ùyð2nµ?È\™ÔÞ·oÊyt>Oä<ú^Î#ÝOré9¥~áBïb„Àý³¹Ð!Ùíio3oD¿/§¾V³—K0ÞršømðZ^ÒnfçmÑG9æ¸÷müžä׌»áÖõ[‡µÍÉÛ>iöi ŒFÙÝ:Å”ÔÓÚ6·æÀpB
+Ä)æ/ëÑT(z3Óh·{|ïìâ,晸c=rv>ž§5ÌʉÀ¯GËîm?+^¢GÐ) OË¥!Öv¤\Ú8¤œ ð¨Ã‰•(¤­£1 ó¡ŒÄÙ2ZØ­S¬pŽÓñb;)*–Iq¢
+@.oˆ)Û.ÎEY¥@YÆ»B„÷û³ˆÉó÷GÖ¹~@V@V;“á€Û( [Œ”Ká>YOJ<^B8Âùh !vg}èÙB›6ÝÎU a­Ð‰åxñ×Gô€×ä8:ò#z@â¢{˜æ°ªÀ£ÕSùÉ©2HeöJã[ZÕÚ¨t&yž)|ºV9—I*ÓWØú;æ´qjɉ¹²ÁS«ßæ¾[®18f¤ZÁŒúWÊV—¨y_–ß‚öØb,K<¨ƒRÌxMG…Œq&ò-Æy¥`ø%¦4¹žól_ìêè¥÷Ã:”½¿ñ¨¶¹PKXøÏ
+(!Q"€Rà‘šWe˜‰;êWæŒÙ®í±‡
+»à§R_tµSr-ì)Qߨ]²¹KASQÒ‡v÷€äáA‰iËw£Äm¶Ÿ´Ä@ÝZЇT›
+‚þ#óÿ«Ü?è'åþé Êý wåþIß;rÿ´ç³sÿtVÏýOtzrîŸRäžÜ?Å홹ûîÜ?éGî_‚b^ª`í¿aî_û}=MP~b–€¾7KºŸÌÀ’^cöÁ,lµ)#ì?9 +¥ŒìzÄl¯FV¿îs݈û7ËÂ’q²°¤õCYXãd–®í½YXŠù~–ŽöHv1ÏY؇癳°t=÷³°t4ÛÝÁ¡¨plÞX!¬cÚën„rõ††tÉF=J#dz˜Ñ¯è★Š>¾0#Üla¡R¾ŒH{uìW)Ù²JLKjÄ›”ìBÿÔölÊ$µ>¼%B­ò£©oþ´'J¶›JI\ûV펳îHe9ÝXN2¶¦å0A%Ì3.qSƒ<A×éÞÐÞj¦æžU\ó)¨LjÙ‚]¨§ùçãjkM_9­Qç*H–
+:†J yÇ=VJoÕµ³@"ÕÏ…[ˆìçûÕþÔ«¿a®8¼ã5=üz ÆzU$J­
+¾ó-
+óA³“‡ wëmÑÖ†âÿ%e ©ìõi+ãn¬21eEGèóœzPúXÍKzŽc“+ìrÚv!"3-sÊ´ w &¾ ÙHîüûÏøôŸøù!8„þ/¶û -ºbF„^ÿ¹üíÓé¾AÔº¹”‡›XÚèž3îdØœ²ÍH·p•“4Á"—ã"ÑÎzCTt9ñ¶8S€­-¹¨/=9³K·nYLØkw- /AÄm0…ÞÒK©F¨µ÷]ç$ÅŠž`4ó”žõ`Èz
endstream
endobj
-246 0 obj
-<< /Type /Page /Contents 247 0 R /Resources 245 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 232 0 R >>
-endobj
248 0 obj
-<< /D [ 246 0 R /XYZ 78.37 808.885 null ] >>
+<< /Type /Page /Contents 249 0 R /Resources 247 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 232 0 R >>
+endobj
+250 0 obj
+<< /D [ 248 0 R /XYZ 78.37 808.885 null ] >>
endobj
29 0 obj
-<< /D [ 246 0 R /XYZ 79.37 771.024 null ] >>
+<< /D [ 248 0 R /XYZ 79.37 716.02 null ] >>
endobj
33 0 obj
-<< /D [ 246 0 R /XYZ 79.37 219.367 null ] >>
+<< /D [ 248 0 R /XYZ 79.37 192.144 null ] >>
endobj
-245 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F15 219 0 R /F62 222 0 R /F54 220 0 R /F55 221 0 R /F63 223 0 R /F65 224 0 R /F68 249 0 R /F32 228 0 R /F61 231 0 R >> /ProcSet [ /PDF /Text ] >>
+247 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F54 220 0 R /F62 222 0 R /F53 218 0 R /F55 221 0 R /F63 223 0 R /F65 224 0 R /F68 245 0 R /F32 228 0 R /F61 231 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-256 0 obj
+257 0 obj
<< /Filter /FlateDecode /Length 5216 >>
stream
xڽɮ·ñ®¯˜cr0Ã}h4~| ¢[àSçH.ùý—"‹K³gZ’²<Ýìb±ªX;)~ûçß~úpÿòáOïFÝ„`Áán_~ý à ¿‰› L¹›³‚q+n_~»ýõs87þÈ?Î9<ÒKÎ-<RÎÀy‡§0èýÞ=}ãðW|/>Ó/ ÀÓ÷üG|†¿ã7RÃ(oâl¡|£ bt~ßás˜û—/?Ã
@@ -515,34 +518,34 @@ B2!<ÙõH¤¡W+´_G÷¢d–× Sägvz½E4残üføG*`çð•Ô‚Ï’:"z*È„ÜÇúzÐ<”w[Bʼn›è†n¾
ËPÅ'¡©[öÚÈ…R—·ßÃÁ…]¦ÐñÌP¼e'º²ÿCO‰w
endstream
endobj
-255 0 obj
-<< /Type /Page /Contents 256 0 R /Resources 254 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 232 0 R /Annots 259 0 R >>
+256 0 obj
+<< /Type /Page /Contents 257 0 R /Resources 255 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 232 0 R /Annots 260 0 R >>
endobj
-259 0 obj
-[ 252 0 R 253 0 R 250 0 R 251 0 R ]
+260 0 obj
+[ 253 0 R 254 0 R 251 0 R 252 0 R ]
endobj
-252 0 obj
+253 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 437.011 267.484 451.736 279.44 ]/A << /S /GoTo /D (subsection.5.2) >> >>
endobj
-253 0 obj
+254 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 468.149 267.484 480.104 279.44 ]/A << /S /GoTo /D (subsection.5.2) >> >>
endobj
-250 0 obj
+251 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 475.636 99.554 481.861 111.011 ]/A << /S /GoTo /D (section.6) >> >>
endobj
-251 0 obj
+252 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 494.916 99.554 505.373 111.011 ]/A << /S /GoTo /D (section.6) >> >>
endobj
-257 0 obj
-<< /D [ 255 0 R /XYZ 78.37 808.885 null ] >>
+258 0 obj
+<< /D [ 256 0 R /XYZ 78.37 808.885 null ] >>
endobj
37 0 obj
-<< /D [ 255 0 R /XYZ 79.37 771.024 null ] >>
+<< /D [ 256 0 R /XYZ 79.37 771.024 null ] >>
endobj
-254 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F15 219 0 R /F62 222 0 R /F69 258 0 R /F55 221 0 R /F22 226 0 R /F54 220 0 R /F68 249 0 R /F32 228 0 R /F61 231 0 R /F60 230 0 R >> /ProcSet [ /PDF /Text ] >>
+255 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F15 219 0 R /F62 222 0 R /F69 259 0 R /F55 221 0 R /F22 226 0 R /F54 220 0 R /F68 245 0 R /F32 228 0 R /F61 231 0 R /F60 230 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-272 0 obj
+273 0 obj
<< /Filter /FlateDecode /Length 4559 >>
stream
xÚÅÉŽd·í>_Q?0²j LMOpNIæfø”Ä>$>Ä—ü~¨…µ¼WU³$ôt×{EQÜI•öòÛEâÿ?¾»~~÷ÃÍéKÑi—Ï¿¾S‰ÿÔEIÚû‹wJH§.Ÿ¿üü"¥)­‘´”.âß
@@ -567,49 +570,49 @@ ZwÑãEîá(3ˆÊ'^–‰¬,SÇ”eâAYÆê¸QHT÷Ž“ûaª=qâÀ§cªVe؆ÙXŸWö X ïR)o¸^ö{¯ 㵈
”Ó  mñMc›2 CÍÿÜI#|
endstream
endobj
-271 0 obj
-<< /Type /Page /Contents 272 0 R /Resources 270 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 232 0 R /Annots 276 0 R >>
+272 0 obj
+<< /Type /Page /Contents 273 0 R /Resources 271 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 232 0 R /Annots 277 0 R >>
endobj
-276 0 obj
-[ 260 0 R 261 0 R 262 0 R 263 0 R 264 0 R 265 0 R 266 0 R 267 0 R 268 0 R 269 0 R ]
+277 0 obj
+[ 261 0 R 262 0 R 263 0 R 264 0 R 265 0 R 266 0 R 267 0 R 268 0 R 269 0 R 270 0 R ]
endobj
-260 0 obj
+261 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 262.513 581.622 277.238 592.501 ]/A << /S /GoTo /D (subsection.7.1) >> >>
endobj
-261 0 obj
+262 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 290.19 581.622 302.145 592.501 ]/A << /S /GoTo /D (subsection.7.1) >> >>
endobj
-262 0 obj
+263 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 474.51 448.218 489.234 460.174 ]/A << /S /GoTo /D (subsection.8.2) >> >>
endobj
-263 0 obj
+264 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 502.177 448.218 514.132 460.174 ]/A << /S /GoTo /D (subsection.8.2) >> >>
endobj
-264 0 obj
+265 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 401.781 408.918 424.257 420.873 ]/A << /S /GoTo /D (subsubsection.5.1.2) >> >>
endobj
-265 0 obj
+266 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 439.978 408.918 446.952 420.873 ]/A << /S /GoTo /D (subsubsection.5.1.2) >> >>
endobj
-266 0 obj
+267 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 362.08 358.22 376.805 369.059 ]/A << /S /GoTo /D (subsection.7.2) >> >>
endobj
-267 0 obj
+268 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 466.03 358.22 477.985 369.059 ]/A << /S /GoTo /D (subsection.7.2) >> >>
endobj
-268 0 obj
+269 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 111.179 73.186 130.57 84.643 ]/A << /S /GoTo /D (subsubsection.5.1.2) >> >>
endobj
-269 0 obj
+270 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 141.274 73.186 147.499 84.643 ]/A << /S /GoTo /D (subsubsection.5.1.2) >> >>
endobj
-273 0 obj
-<< /D [ 271 0 R /XYZ 78.37 808.885 null ] >>
+274 0 obj
+<< /D [ 272 0 R /XYZ 78.37 808.885 null ] >>
endobj
-270 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F62 222 0 R /F15 219 0 R /F68 249 0 R /F54 220 0 R /F70 274 0 R /F55 221 0 R /F71 275 0 R /F32 228 0 R /F61 231 0 R /F60 230 0 R /F48 229 0 R >> /ProcSet [ /PDF /Text ] >>
+271 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F62 222 0 R /F15 219 0 R /F68 245 0 R /F54 220 0 R /F70 275 0 R /F55 221 0 R /F71 276 0 R /F32 228 0 R /F61 231 0 R /F60 230 0 R /F48 229 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-280 0 obj
+281 0 obj
<< /Filter /FlateDecode /Length 3262 >>
stream
xÚ½\ÉŽ$·½÷WÔˆ"\FSª©tÓxn‚N¶å‹ç`]üû.Á=³*»s,!§»2É`¬/"ȬæL_þuáøï——ë·—ŸïV\óÆ€»|ûóE\8þ/.4sÚ]¬Œqùöýòû+çFrnñ¿p®Uº
@@ -625,26 +628,26 @@ J¤õ"•@1Œ"Ôõ 3Ö3·–‹p‡Þï
:Âÿ
endstream
endobj
-279 0 obj
-<< /Type /Page /Contents 280 0 R /Resources 278 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 232 0 R /Annots 283 0 R >>
+280 0 obj
+<< /Type /Page /Contents 281 0 R /Resources 279 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 232 0 R /Annots 283 0 R >>
endobj
283 0 obj
-[ 277 0 R ]
+[ 278 0 R ]
endobj
-277 0 obj
+278 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 239.659 387.611 246.633 399.566 ]/A << /S /GoTo /D (subsection.5.1) >> >>
endobj
-281 0 obj
-<< /D [ 279 0 R /XYZ 78.37 808.885 null ] >>
+282 0 obj
+<< /D [ 280 0 R /XYZ 78.37 808.885 null ] >>
endobj
41 0 obj
-<< /D [ 279 0 R /XYZ 79.37 369.285 null ] >>
+<< /D [ 280 0 R /XYZ 79.37 369.285 null ] >>
endobj
45 0 obj
-<< /D [ 279 0 R /XYZ 79.37 345.056 null ] >>
+<< /D [ 280 0 R /XYZ 79.37 345.056 null ] >>
endobj
-278 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F71 275 0 R /F61 231 0 R /F62 222 0 R /F63 223 0 R /F15 219 0 R /F53 218 0 R /F16 282 0 R /F54 220 0 R /F55 221 0 R /F69 258 0 R /F68 249 0 R /F32 228 0 R >> /ProcSet [ /PDF /Text ] >>
+279 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F71 276 0 R /F61 231 0 R /F62 222 0 R /F63 223 0 R /F15 219 0 R /F53 218 0 R /F16 244 0 R /F54 220 0 R /F55 221 0 R /F69 259 0 R /F68 245 0 R /F32 228 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
288 0 obj
<< /Filter /FlateDecode /Length 3886 >>
@@ -687,7 +690,7 @@ endobj
<< /D [ 287 0 R /XYZ 79.37 286.301 null ] >>
endobj
286 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F62 222 0 R /F72 290 0 R /F63 223 0 R /F16 282 0 R /F55 221 0 R /F54 220 0 R /F32 228 0 R /F48 229 0 R /F61 231 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F62 222 0 R /F72 290 0 R /F63 223 0 R /F16 244 0 R /F55 221 0 R /F54 220 0 R /F32 228 0 R /F48 229 0 R /F61 231 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
295 0 obj
<< /Filter /FlateDecode /Length 3624 >>
@@ -734,39 +737,31 @@ endobj
<< /D [ 294 0 R /XYZ 79.37 489.074 null ] >>
endobj
293 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F62 222 0 R /F63 223 0 R /F49 216 0 R /F51 217 0 R /F71 275 0 R /F33 227 0 R /F53 218 0 R /F15 219 0 R /F54 220 0 R /F55 221 0 R /F65 224 0 R /F32 228 0 R /F48 229 0 R /F61 231 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F62 222 0 R /F63 223 0 R /F49 216 0 R /F51 217 0 R /F71 276 0 R /F33 227 0 R /F53 218 0 R /F15 219 0 R /F54 220 0 R /F55 221 0 R /F65 224 0 R /F32 228 0 R /F48 229 0 R /F61 231 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
302 0 obj
-<< /Filter /FlateDecode /Length 4203 >>
-stream
-xÚ½\K¯[¹ ÞçWxÙ.¢ŠÔ.ãÚUÑì³j;]´S Ýôï—zSsl'™,’{í£C‘õñ!êÊË?.òòã»ëçw¸u-”¶xùüË; ò„rg¼Ð.Ÿ½üôAJåßÞƒ”2þjß‚¦Ÿ†>ë›”x•Òúûwñü@?}þ>>¿Çqøö^9ó!>}S@?|³êC]¨Å‘
-ÓèŸ?ÿ±0
-"nÃ)*á­ëœñ6ŽñcæÌ}£óO+㕼·Ë7q\äI]ç'éS8~³Êߌ ’€½,Z½D‚pj•ã5y¼š¹Jßlä)™cŽ¬WB)]Y2ê }Y++‰²Â2WZ1WžÜŠ~”*Úhœ¤ñÍ&°ÛMÒSµUù2x{Ÿ&ÓDÒÕœ:Á*Zf©L
-w›'Ö·7tÉÐÊ»r4Ó4æÚÇƹˆý¬Úå(鄜Ճ6ª¨sØ6ˆ;UµÒNàªìffÇ2ÆMTáZæ»æm;%C8•F+'´Y„Ñ{atùÙì.DD(«èÙd§vå€~„:—mÈÑÔ_…,¶GDÃ"*nYqƒ¤Y§YL›Dú‡L£ªFW•±9ðöö^£aêÕh¿N½œ ˜¹9Ò¯‘E·¢>دhƒ@b`š¥ï¢ø{ÙI :0ÃE¶nÒ.pü¶€öénÐ(¸š¦NË¢G ùÞ“}ïUÍß×wVøÜ
-¯ iÕÌAÙA§¶o•°Ÿá=þMïC§½­mèËÁ—àÆ·sGÎòTv”L‚´‘Åæʧ´ÿÊÞ±V1»]=ÅvßxbZ‘•ÊVßpMƒâ) ýÿÏKÿýOï>}~÷ŸníR t$8¨Ñ’üõ×ôž¥`B’G/ÿýûå—w¦,Ù;F‘Œ8J[¹ŠEDBÀ(RVbuyöš=§Õ§+ÕX+¬÷mW
-çþ(Þ¡ýG<Ç8?u¯Rø] ”~:ÕÄa·[ýLd•GÕo[½âÓš×¹æ5¨8ýbŸc?ë¼ùéf-Ê“êÓ{h3l)
-°=†¬ïUÓ··™ƒ„Da
-éjüÝÁºjÜú_6z|¿jò(:XOP8×çåu©(ßCÅ3ùáÙð<òß¹m~dÒŸßé/Ó/;7ÒI+{-ë_ö­Ó{Oµ8¿:M ˜‹€¢¼6zÁõ™§²jœóqÄÈ ^gî­xñmíÈ¿ƒ4 +>ff{\Ht1ð07näø-
-¯–Y¾'ð;)9²‰ƒÁš’D)$b6_÷^Íár¤5i»8½—B*™tSÒ³7ck Zp©¸…Z™)êú~­#⻥¦Pæ*–Kk+?ôÌTœ§dòV?-¨¢ªŸé9B[Åøê2m.Vb
-Ñv&In«&㧓häcŠ÷Ý®=azÁÖMõâDCšW6or·ÒÖm˜~³­¾W¿Yñ·>±·~Û7{Á´F¥‰%œº+Ûh âTQŒaØêØ._ÀÎÃuÙ ½Á:õÁ-géO1žJuÒæpó·µuÍó£"ugFöë NXÀ1;|)2KL4Üâѵš<G”cMÛØ£Š†”–kÍ*ïM*¥WàÁà_Ï”R›‰ê÷ÍË¥°¸p0ÆÊEsE4Õ£ô¨åü-±Œêž‘E4 aÄÀ<Ž×HSè~í+4:ïø†caC¢Û
-ò9_›’X‡”zÕä]ïSp'”³«&æÒê9ä9Vú•ÓòiÑNöø»½¡=ýô­
-” 7ß Ì N ³R>ðú´Û)ìYÖ„Þ±
-ý+Û2†P¤ži–o %‚Î.üÖœø®U1c5æ^€=ËÃrž¶[c&¾“ý,*ãëþ»õ¾Â}¯ùp_ÂwZ8Ѓ|¿û÷ïOO­<-¼…eI *‹­äДåwPã=KËò§± Ä
- Lüªò‚¢>0Aã…e•ä[Ç÷hpVg šl|Ìó£QŠmبeT«Ÿ69E(~¾ÄlÑÊÌ<XíZhTCi¹¬ãkÙÓjþþ¬ÿ¶V¦Rب•9ÇÍÔv9nѳ§g79Õ¼¢{/¼·MÛZvÛýö~¿Áéy¦!^³þ!päÐ&aÑÓ,Õ”LpÙ\ùÅma-щ ’ªÇƒ×yÙ}|a( iLETóTˤ{ð;SIõÝG¬§Ÿ•F1Äb ñ:„úÛeV„n¸>ìž@üÀ’ćÊNCf@*š|_` }ñlwõwÛƒw,ÕÉã21€7:
-/fÍÔp§?1œsbvFS4tP-ÅסÆo*¨–†B=ýŠ #¬ZLàÞ³ª’ L‚棙b
-e€½C
-FÍ(
-®U˜ñxºRnz+S9"»@ÕX3îòЬƒéa)ö+ð3÷ß ,U)XÔ²8—tÊƪ4»˜²W4«Ò\.§œ¶~8/‚‚/m1dó¨Í;φÍ?¨AêñœÏ?>Ý™œ
-N€õ;•ª.›§D^É8î]bu’']o.}T×›?V;È­Ç-–vf=\9jrZvh/µqø㘘ZHߊCæþf*z¶ÃM™¿[’•³ÎeÉ°õÇŒSúÊÛ:-bj®:3…Kᙵ{¶VP7Õ ]­õ¹[ö ƒœ=‘NÑÃÑ÷~–·–ŒÙbÂ’q_h%[×fžç¨bŒäf§[ê掱üÍX°ãOFE;þörZåô‡MÝ¥&,s`fÎvÔš ÆH
-Å‘Ç:sJ5öX±&Ûû3ñ²O>meôÌÇ÷,z2%M@«Ôa°À=Ãû«.ÌÄžç…§¶&Hþ¼Ç'ºJ%PÂyÇ{|ô§'z³êÔ_yÐœm¯_Õœ}Þ2~†‚{k´ýaƒvÙ0jq•*”¡öîb¢<Ò=ߨ=ž¹–tQkï$̽VÒçq2¨™J|åwóÃÖ¡&k÷aûã4û@Eåƒ;Jc\ ±ýpöL&¥,yA¡ö
-ëÕ¢Žßæ>¨‰µ\Êÿç%Ûã"€ðëÅ–[EX^zaB‹ÏA º/¹­•¯çŒ\¾
-^õõkýRÈ´¡Ÿ^€µ=d„´ ¯ÇŒHä`¢é®ÃGçë:$=ÚþüKªâ4»¡GÓì)d¬:ê's·Îx0ÃiÑi '}Ù}_‰m±š¹m‹<¿55ˆ­òùÅÓ4ÍÛ>¼µ4 ƒÐý.ìѽ˜ƒúe¤8ØZÙÚÏÐM´´Ÿ~¦ïÿFÿþH¦©‚¿ü/ü5°Xˆïýëò²¼dq
-/N{hÙš{#<­8~AÂxß7WQ{XÑÐÃœÞu5zr¶­¨wï™™]ž­Ú“íu0£Ç#ÝQK.¦QÛþ-€ô”·ein|Ʊä/,§Ï»I¹±B ËguÉÐòÒP$còᘆ/Mµr”šïøU\sC*ìܶQvVZ
-Ü<ùK§\{{¯‚Ÿ)'ŒqŽ7½:~øžOïꢜɇñ`ÂÂÅ£ôn/z'\üÃL#µ–œ;íh«uï˪Í)ð¤)ÿuš"
-öÃTÑÒ~'©64`»óÑz¡-ó•™²ò—NŸ*3ö²†°LsåÓÎY¯Pˆ3Àò×R°;˵–
-’µ–”ñµ*
-ðÂN²RhifF6ÁÓ ›ãŸÇÚ ÷`ù9øé½Íâe5”ÅËw‚Ë—ÉãÅ?Ó1ÎÀ7BVÞ3=¾éB¤ÑFfC/Ÿ¦¼jøsmi*ø÷ã6SC÷ò„ý)lóÔÎôÂqY­Ø0æ‡?ÒV@÷>¿_·ç@íKl´jïÓM“ç>€JOï}Ë]£'ç4Ë”øò|†±ž= W[3´ÑH~ò5x×ç´aœIW;~;Å)€tWxRܦg-3Í1úQÐQS]>Âc)ÔÖ{uüp€›ÚG_®ÝN^
-†’³Ø{Kûß*ùT#õÿ}èÊP
+<< /Filter /FlateDecode /Length 4211 >>
+stream
+xÚ½\9d¹ ÎçWTh#‹Ô ˜Úš^ÀŽ O¶ØÈö:°×€ø©ã½ªšî zOIQQ%/ÿ¸ÈË®_?üáÕ¨ h¡´ÅË×_>
+pÚ(¢NaÛ îTÔJ;«°›šó7Q]„k™ïšÚvJŠpÊVNh³0£÷Ìèò·é]ˆˆPVѳÉNõÊý u.Û£‰¿2Yt#¶ˆ:†…5T\³âI³N³˜ 46ŽôyŒ*]EÆæÀÛËG†‰W£}›x!8A*0Ss$_#‹l'D½³_ÑDÀ4KßEñÿ²“t`†‹Îlݤáø´€öénÐ(¨š¦NË¢G ùÞ“}ïU†ÍÏkŸ>·ÌkBZ5SPvЩî[%¬ÄGh?£ê=¢è´·µ }9øÜøvîÈYÞÊŽ’‰‘Ö²è\ù”ö_Ù{#Ö*¦·«¥ØîOD+’£’BÙjû®©Ql"…¡ßÿ¼ôÿÿôáË×ÿéÚ.µ@GŒ#-É_Mý,9’Œ8Š€xùïß/¿|ø3½`¾ÈÞ0‚ŒÃ؉¢´•+[ä@$Œ,e!V“g¯ÙrZ}ºRd°Âzßæp
+ç:à<½.廫Ø|&?¼ÞGú;µÍŽLòó;ùåñËÎ㤕½–õ/ûÖé½¥ZŒ_¦:aÌÄ @QºV°A}¦©¬§|l1Ò‚×Y†{-^,d[;²ï MÊϙØîÒ¾vŽû‘ίfäø-?ùÇÓ,ßø!šö3\›2É%b:_÷^á“Gx¯»8÷K.•L²)áÙ‹±5P48·Œ£¸Ïe´2S”5É°Œû–œë£ÛÌ52Õò¤Ñ7ÞfT3öx
+F¦ð,R&gôÉïmYz»ÃÏ<Rµ“xåúœøJô^0ÅZeóLu¼ÈrtÑ&–‘)­+æZ&ÍËZ¿dsJ_Ìv¨ÆY‹¶Ý*7ÍÒJõi´$i½¯ä¼š®kê`Ú
+6𑓯Ìñ«yÃÏùÙ¯Qºz‹$Ÿ‚BrC”àªé°„
+Oû‘HŒRŒ43z'5ä˜Å9šµsø H”žg<S ÂP\0yÞ
+Ü°¹Ùæ©¡Xf8¹Ùî­ë8Í
+kªûðQÊù)‘Œê5C-ŠeAŠ¹Ï &ÇþÚWh´á±‡cÞC5
+¶¥ë-rº6 ³Ž1Ùͪ¡½ÞèN(gWỈ×s t ¬ô»QN“«E:ÙØmíé¯Üóx(ÉA ]„ìY&Cƒ…oI3¡(jÞ!
+N ³Ž|àÐn#0±g1zS¡*¦"Fâ™fy.¬pv¡Ðf_­PËË°\ÍköÌ‹ˆÚnqúŽ÷3稴¯ûïÖ=ù
+÷=›PøÃ}‚ßiá@üýîß¿?=Óò´ð–%5ÜC¨$¶„D–ßAçA[þ4¦‹X‚±ß}Wžn<°gÚxaYžùÖðá#œÅ½(ß
+}\ÆæðFGîÂ,™êîTå'‚sÌNpŠ„r©xã2Ôø®ŒjiÈÕÓÏ0ª0ªE^{TU”‰Ñ|pS@eÂ[uF"ºªíœ+)ÑSG¥*&¢páYGå£I'úJ·ÿ ’Âã<Ù‰Vw;¬Jr€6†k²`Õµ§ÕuhÏÇÞ’ñ‚#÷QØë§`”<…à€ìKÁµ
+3þWêÁN/t*h·±N¨*kÆ]îšu0}À-EÂ~~¦þÜR%‘âE,‹qIgp,m³ó){Š³
+­äWN CœAÁ7²¶(²¹W‚ŒgÃfÔÀõx
+èîTN'ÀúûuLU–ÍR"ÏdW6±<Ƀ¦7§>ªéÍŸ ËÒ Ã­‡ƒÍ—vf=z9*ZvhOµrøãú˜ZHßòGæõÅTôlGŸ2?[‚•³ºeI°eõçŒSúÊ‹>-"jJ–ROæ,™hV Ú
+Eݘ”,…¥&g9£uhä챋tŠŽö¸÷3¿5‡œ0È–Œúz|+Ùº6õ<GcD 3;ÍØ<P7דå'cÂŽ¿e6&íxïùÐ*¯Ò’w©Ë\!˜‰³µ&…1’\qä¾ÎRX,‡É6ÆþļlÇS£OA=Óñ=“†Ó™ó, h©ûC% V
+!ÏBîûL±rV' J’cçõÔít't¦£þt[›_=RË'kG屌³‚ÄB–ÙõÏ7 ŸtŒäœeòYȃÑ,–1O¼¶ÝŸ'6ó¸YpŸ.Ý´³Y;×g5³ÓVcíCÎÎÍꃌ„åt±dDÁ¸©ð0]•MaÒ
+cÍz HÿÀÆSÔRò/)Ÿ9Ä!GÊ…@³*ráÜ[K…¥ÑÌÄCRšªÐI´‡¾AyŽÝ¯xQQ¨ÄÏHÁ‹©×=Tœ[Õsx)Îí—Ê&ß*›äð«“äî¤ÿ`‘¿õ>H‰ÑhÑóÒ¨w/wŠ|ÿ¹S­–Œ£VÓà À®<ÁB`çp[u+ç[o:uÊm¾{ äÉI|”{3qoîÞ¤²Ê΃ß*·ë9sÖôϾ„B¯ýŠ˜j¼žÇYµH&Žšüof ¢tr*°ö™K7ZÉO`þ1L©˜ž}¥º=ȵ î)”BáPÓ¤öi|3J‘#oÃ(õFaâf භ™î!a5ò;ˆÊíöÖÚ>QÝÇ6i¥þ·¼õØ€+]í1o¼õéêÄ2ZÊU•’Ÿ1‹5VR¶•
+Kyçq¤ÞûeFu÷p_GL™¸.°ÇQk¨9¼ëÑð¨æKÙƒ’~T®þ.—hÕ.ú:º,*…õjÇos[ÔÄ\.Åÿó’íq@xwRÅõ\ n,ãrqá¥&4ÿŒÄ û–»\ùòÎHåàw¾›9]æÑ×DÉZÜ–JŸ]bKìf¯}sõc
+ðF}¬ ïô÷uwÄpr­È…0ý´œV·¡žÓ¼X¼ÇNƒiا@aªíšFÒ Žn¸]GiWznéb^0ÿ[ÄWߌ7Æ«6í(ÌNæ¥ÿîÎ)˜ƒ:ûxxþ™WµÖÕ¼TØ[ïmñbàå»À<`Ny?6ïbN'¡MFs*è(jãh›¡äu ADA
endstream
endobj
301 0 obj
@@ -788,7 +783,7 @@ endobj
<< /D [ 301 0 R /XYZ 79.37 333.945 null ] >>
endobj
300 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F16 282 0 R /F15 219 0 R /F62 222 0 R /F55 221 0 R /F54 220 0 R /F22 226 0 R /F68 249 0 R /F32 228 0 R /F61 231 0 R /F48 229 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F16 244 0 R /F15 219 0 R /F62 222 0 R /F55 221 0 R /F54 220 0 R /F22 226 0 R /F68 245 0 R /F32 228 0 R /F61 231 0 R /F48 229 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
306 0 obj
<< /Filter /FlateDecode /Length 3872 >>
@@ -823,27 +818,18 @@ endobj
<< /D [ 305 0 R /XYZ 79.37 198.115 null ] >>
endobj
304 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F62 222 0 R /F63 223 0 R /F65 224 0 R /F32 228 0 R /F22 226 0 R /F25 308 0 R /F53 218 0 R /F16 282 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F62 222 0 R /F63 223 0 R /F65 224 0 R /F32 228 0 R /F22 226 0 R /F25 308 0 R /F53 218 0 R /F16 244 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
311 0 obj
<< /Filter /FlateDecode /Length 2735 >>
stream
-xÚÍËŽ¹ñ>_Ñ?°4Y|Û– 9Ř[SÍ!ØCöÿ)>ŠoµÔ3òÚ»¥îf½¬*öp¦·ÿlÿýËËþöòéjÅæ˜7Fºíí·±qü_lÖ3i7kãFlo¿oÿxå\]9ǹœ[…ßÀ¹áxoÇg¾%|þEƒÆÕ:Üñte®u½´^#u¡áŽñœ_MZ%¾¤ëpßòˆùŸo9Ôœ Ä!d*ÒVi3o2ÑÓ:ÐÄo$_:ŒÞ1جôL(YDî@©ÒÇúˆ€ÄãY<¼k.麊fý‚8&œ"BX¹¤›ð{àMËP››Åo
-¿Êf
-ˆQzîì9ä‚ÁöìZP¥©+S…+‘¯®{
-°¸ÖÏëøÍuâ•ô¶†²—¤ÇtejÒ
-þCQÀ
-4Ô¬þëÀ‘»lÀw¤¼´:dò¸\è΄­QJP¥Ú½ëÚ
-N“öXîÕ™â¨p9ԃƀ )>«³+:Éœ2p*ÉÕ¯ÇYK*æ¹1—àÕg*Ûöê=(·š‚ˆÖ›ì·©èþ¬õ+A¤Ð!oL«c‘çèŽÎ6$¹bêÚ#LKéHWàÖ“¶Ž5–ŤçךÈ5‡EÝÓ'išj‰,)4Õ\…ì´ª‘¢5Y×Yt‡êšpWp‘#½Ó7y_Ð{ô{¾ SÉ5Ú¯Âtï¼è7 J™µ€'iéIÊpÝŽÜïdy;ÜCojdÔ]s „PNMçM“z'¬° ç¾%lÓç7üæI>ÊLt?èL&i5Rôû·îòo•u˜ìÒN+q­
- ³ØŠöÄjg’TjÒðÝ7Üp9!—ä
-«+{B®!I­ø—è!Nˆ»ü‡Š•ø—¥g{¢»A£3p®øÁ¯cœ‡ˆ¯m¤Š×6wAêÒb&¨±[´x;°Ä{ ÿ÷!P(pÈ=E™÷Ù”oDÞ‰K… T>Z•#70Ã8&iƒreä»Y]rQ-Iš¦ 8UoY݆D“˜¨žëòÀìu$sóØÞ‹¥ÜZ%Gl0ß•ü²×­-–/±ùŒØâÏžä8ôœ*ÖtÕTämÉOc©\
-`BÚ–ÙA€X¹û{¡RLëIŒ§t<à sFL*2¤Nª!«‹,0‘‹%©oƒ(_íV+Ìj4X
-JÞJuêaN(7{7øå¾[ƒ/”eÒè‘NÞé~‘±«Ë-t¾º=¶8v.™Åà,Ñ=W­™ÇáO¬§P
-ª£;×ÀÞ´D¼ÙAö¦ØÒ­wdýdK“WIŠã©€ |‚_µYéÉÝ<¤)¨ñiñ¶’fu͋주b
-Jh¨P2¶…t(ùY)Ù®”_êDÛ)7vÓõʸÏNRº‘—¥µ_»ž}Oi_v¶Í{èt–c/£¨OèmB×)¸1/›|ÊInŽš|îF­M½=H?ì™éέqFzºJv4üI4ÑDÑqLžc&8|Øið‘òoï+¼å$j÷ä~iMLŒ® ÕÂ[KùvG^$Ét†-x.î|,î<Öa_ß^þWÍäC…‡f2Ž pÛ¿~ ÂɆR›à˜üÄöÇ¿·ß^þ^
-¹xètcîŠÝŸ0Zt>^8žYàžæG,9XŽ§ªŠ7Þh*5ª*Yšªè;lj..Íä¾g; …{Œ“þã܆½ïL+d$Ã3Ò_k:R9UÂ,;#lÃpÇ›d÷¥ûtµë”e,3xk€¬urô•ª¾ô»œ îÓ”òøA û»‰Ç¾­ÁµLáÇl„tñ-Z]XÓÜ,Î=û¦iÍ›×ñXw@b20sqQ`(ÿüVUJbàa„íY;&
-$B€#äÁl•{¬ƒEå²ýdJg•X¤èq«ÇU(Dˆ Xq§¨ó–á¿müŽz]?ú¶ÐV?>“–‚ ýlá¥`ƪ>O¶‘†y>­†/Ñq.~G ­OJÒ¹u̪…G<¢'™Çòö1}$Ï“Þ2íÍwñ¼wüÿ˜6²‡ ˜–1$fF݈¡Åç9l˜Â2` }Ê{ØckY‰»·yTÆ|&ÿ${Úçdìa5Éh³ò1ßë äV©æe‡|3ç“™ßX—XÚ9×hˆÝçWNŽ§q©$©fCC_%ãÖËÖ(XÉ‚›½®@§,ºÜê{à´Á=ÁÙ€+æüˆ^ñ| p·šlzÃÓ@hÌÛãÚ[»³TžY«Î,cBc E"9MÏOŽÄÉRyŽ¿âþ)¹Ü¨Ç¯o쾘´˜V/ß’2pþ^uÇ ÷©êîع§í‰÷µˆ ™3ïw)þl{~î 9soWÓi‰ýŸN*ïI} 
-HͲûaó•þó³¼R°œ°ä9É(ý幞‡f6ÒbƒÃaÒÄóg6JcÂä“Î3“$ùgJÂG©/¼¾h칓¦”ZIKq+¸ù}S]߇þ£Ó'gE>6}œš> °'¦OäÝéS¨é¥¶ße0à~ÇôiÁÝS§OþÓÓ§þÎôiXý”éÓ¨¡OŸ&Ÿ˜>=¦ìy˜âßgî9àþÀôiÀ´Ž!‹¬)óC¦OísÞÛÃ[Kc%çÅ™> ´ÏÉØÃNŸ„2LKó§ô,­wΟŸ@ Ð'&PÝwŒ FçfPôÓ‡P£nNL¡FÖÇPãâ›û´TL;ñÓÌ¡~î VÜ?s5à¿3‡V/‡4€¡÷ÿ4ƒ¨Ÿ{úž¹_K‰kìO3‰êÙ¹'ãÄûr屪úOÉé©Ï¡fÞi_}G‹æ ³æÜ_ÒÕíÁ¿Å ß`ÂK<–ƒ%–,øõíåÿ[îƒ^
+xÚÍËŽ#·ñ>_¡0—,¾ÁîÕ*@rÊbnANAœCàƒýÿÅ·Zjfwmh¥îf½¬*öp¦Oÿ;qü÷o/ÛÛ˧‹'Ǽ1ÒÞ~{'Žÿ‹“õLÚ“5‚q#No¿ŸþõʹºpŽs)8·
+¿sÃñÞ†Ï }Køü‹«u¸ãéÊ\êzi½F<êL+Âã9¿˜´J|I×á¾åó¿ßþ>r¨9ˆCÈT¤%¬ÒfÞd¢§u ‰ßH¾t½cp²Ò3¡d¹C
+²p%òÕeK×úy¿ºN¼’ÞÖPöœô˜®LM`_[¨:½<°¥5òåÚfM«‚æ>] ¬4&•Æ›~ÒÙ#é/ÑY[F¡/9-G:Y{*ÉWbÅáC>t•CLU\š‘ŽvEï6hwåÝÜ2«Kê ÖpKk &)_¹—]‰…À¤i݈÷^Iw¥˜> HÙáŠgÞJRN‰Žî†hÑ!b®HÂå~ÙÁ²k’pnÅ
+Hyt5-ɼ·h·pB;ÊZÜV&ZIšDG3Æ,•UaÏ•%%USb„L“€ïÉœ-,ÁÁÖìžž¨&Ï‘e‡¶Ú’Å´Zf1.˜“0)AÕR+çÒ=‡’ ÷rÄg’‚Š¸Ìù¹š=˜)R¢G5aÑig«ás#C+ÌG¹¸j-¡LSpš´ïÄÒp«Î?@…Ë®4ÕHñŽ\]ÑI改‡SI®~ÙÏZR1Ï݈¹'¨68SÙ¶UïA¹…ÐD´Þd¿ME÷g­_ "…ycZ‹<Gwt¶!ÉS×aZJ{º ´ž´µ¯ ´,&=¿ÖD® €<,úë–>IÓTKdI¡©æ*d§U­ÉÚ¸ÔÈ: ;Tׄ»‚‹é¾Éû‚Þ£ßóðM˜J¨Ñ>x¦{çE¿aPʬ<IKOR†ëvä~'Ë;Øî†zCP#  nšK „rz„l²8ošÔa…e8÷-ñ`›>¿á7OòQf¢ûA¿`2I«‘¢Øÿê.ÿQY×X±È>!í´תÀ0‹­hO¬v&IÕ©& ß}à çrI®°º²ä’ÔŠ‰ℸɨX‰Yz&°º4:çŠü:Æyˆ(ñÚFªxms¤.-f‚»E‹×ƒ
+ÌÝÞ •bZOb<¥ão˜3bR‘!ÕpR Y]d‰\,I}Dùj·nµZaV£ÄBPèPòVªSs@¹ÙC¸Á/÷a ¾P–I£G:y§ûEÆ®.·ÐùêúØbßY¸d"ƒ³D·\! ´f„?±žB)¨Žît^[ÓñfÙšbK·Þ‘õ“-M^%)Ž§.@ð ~Õf¥'7ó¦ Æ§ÅÛJšÕ5#,²òŠ)(¡ BÉØÒA¢äg¥d»P~©[EPl§ÜØM×+ã>;IéF6^–Ö~ízö-¤}YØÙ6ì®ÓYŽ½Œ¢>¡· ]§àfļlòU('¹ÙkòAº+µ6õö ý°g¦;×Æéé*ÙÑð'ÑDEÇ1yŽ™àhða§ÁGÊ¿ ¿®ð–“¨Ý’û¥511º&T o-åëy‘$oжt⹸ó±¸óX‡}}{ù£šÉ‡
+ÍdàNÿùý%<'JÇä'Nþ÷ôÛË?K!®Ì]±ûsF‹ÎÇ û3K
+âVÜ)ê¼eøï4~G½®}[h«ÇŸNŸIKAЀ~¶ðR0cÕŸŠ'ÛHÃ<ŸV×÷è8¿£†Ö'¥wéÜ:fÕÂ#îч“Ìcy{Ÿ>’çIo™öæC<oÀÝÿߧì!¦e I§™QWbhñyŽ¦° hòÞvßZVâîmî•1ŸÉ?IÆžö1{X {2Á¬¼OÄG”ܪ#Õ¼ r—oæ|2óëK;çš Ñ¡{àüÊÉþ4.•$#ÕlhÈâ«dÜzÙ+Yp“¢×è”EC·‚[}œ6¸'8pÅœÑ+~‡¯îV“M¯xy{\{mw–Ê3kõÝ™eŒBh ô®H$§éùÉ‘8Y*ÏñWÜ?%÷‘õøõ•Ý3€Óêå[CRÎUwÜpŸªîŽ[Úžx_‹š9ó¸KñgËØósKÈ™{»šNKìÿ¼ø>©¼'õŽŒ42ñnùn³›D/§¸úò" >UÓÝ3sB0áB'ç˜Æb0Ï7¨ŒøÌ9 ËʉµÖêMê¿ÂÛŽ4d™^6»2`€A?pP06Göejžæ’õì#ßé^©(w6ǧå8¼9§]è øšÂ=/¿Ä•åå=˜ç¶ {mu¨Eò«çX홳}¥0ž©7#ì£#ûe÷ÃF,ýpÎå%JFéÏÏòÜ5¶‘{“&ž?¶A_eÀ'/Æ6&ÏHòÏ”‡÷²_xƒÑØc‡M)»’–ânpõEú¦À¾ýý{PŽ‹¼o
endstream
endobj
310 0 obj
@@ -853,30 +839,30 @@ endobj
<< /D [ 310 0 R /XYZ 78.37 808.885 null ] >>
endobj
309 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F71 275 0 R /F15 219 0 R /F62 222 0 R /F68 249 0 R /F54 220 0 R /F72 290 0 R /F63 223 0 R /F65 224 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F71 276 0 R /F15 219 0 R /F62 222 0 R /F68 245 0 R /F54 220 0 R /F72 290 0 R /F63 223 0 R /F65 224 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
318 0 obj
-<< /Filter /FlateDecode /Length 3176 >>
+<< /Filter /FlateDecode /Length 3130 >>
stream
-xÚÅËr7è0C‚ï*•ªÔËUÉ)^ÝR9ínrH|Ø\ö÷— ¾»gdM¼®’¥îFƒxÑ|û}ãÛç‡ýõᇡ7ϼ£¶×ßDxÀ7±YϤݬŒ±½~Ý~yä\‰ðãž>HáJçV…;á·Á÷ð©ÈOÕ¥ÀZÎÅÇ ëé.Þ1—ü6Â=Q.a0åìéîËïþúúãg ÿ~øôúðŸB<΄3›Õ–Y'·~}ÀÚ3 v eàé¯o¿=ü4²0°’ÐÁ( ‰F¹'¾Tà$ˆƒžy½¤g2Q{$i°’1ÉZ&Ióé4s F>•ˆÌ7ðé skJxù&þ¤tÌúIzZ=}
-ÁÁ>’‘¦k\=a(+ïÙ(½§§Á Îä,¸!†ˆµWÌ‘F_Å…¸Ô>Pžk·Â/-º
-L&øD_žwFŒ{• ^áü‘°Ó£3agˆÆÓ„B%ø„' š q=´™þÝ–`\ ²÷À>­òL=»Â®ëØJŠ=f’Œ•@AÈL* f Ý.U-'›>ŒŒ–÷²¥TLIdteÞìO¾4ÖÊWZ̈́׭UÅÕ(pJùXÃmäð’yò•ë— ‰ ’…„
-M6Ó[ãÓa R¤¡MÁó1‡"C‘‘ä(Œd>¸d*M
-–
+xÚÅËŽ¹í>_Q?`­D½Á
+M6Ó[ãËa R¤¡MÁó1‡"C‘‘ä(Œd>¸d`] –
-¸J‘$«òo´[2%i²Y’»¼¶Õ1
-â2lÝåOeua$ tOë߬?hÐÈ¿*‰3“%(óœL3¿s=h~ã:ÒMš Þ•PL„(<òd
-&i»Ô™Å´¤5#’•˜O‰›¨¥O)¥êf«>²åë'mâ*g©^´ÜBÚõZ‡„4—±œ²%C9 ¡)bj9Rþ\ “X”XÝ%ñ
-£Í‘€•ºTy'¨ðD¼˜êIŠÇl~+Æf?å¢ÄÚŠ¦[þþ©Oè™;Dc¥sg™ i@»ët.ÌJÒ˜Ô>`3L‹’¦P0Zæà±Æµ‘þ6ÆI#ΞD,ýi²Ï HJY–´)÷Ií5ß’§”Rbm;"Æx?âÇØb•LÇq¦Õ1qIVÜYîA¡)½W/i‡Ü–Bj ×™µ"€jÑiúKœE)$]!™ÆU£(üMád½V¥«"P³t^«7íR–\7íƒÒÅÃl-”Ÿ«nÊ&á[ÈP17ð6¦–<˜s`ÉåªâdÎÍ«ª«BC±Î{)+‹¼úPàD•AÞ %-ž°YÕbÃ<„ªU9‘X T~Í¢uA´R†]Œg–»,\!Bª×)äÙ¨®³þôAÅðu {RW¶<*IIþXË*Œ-àûŠ§hRM‘*è««¶ŽÊn¼j¦5~ã’IX\¦_©¥§«øÇI•;ÖE‘uIð´e­o“$jHª¯óW!ÚM‡Ànu‰#gê’Ž6܆ìÌ‘•£E˜Õz¯ÛL§hÎSö“{•ªÜG¨~ÓÞ>A£Éû³x N1çüÈéwŠ×Ò9ÆW²*n‚|ÐŽi´‹W&=à!ËÑ7»"YÞ­åYƒÕa›ìZkèµRâA¨ôf˜·Òé.;JX<S57aֶ盢ŠáLÙuTI[§ÇP¼wªÈgÑÇf1»xS8$Ü­¤;¦D+¼c+¶¶#•`)©¤«®´maVÅ^qªŠ½Ìí§««”VB#˲™´w»åcÛê^›
-WR„
-{H}¢LÅ픥âBa÷@*C(w£B¾·(4ánšî´
-MwV
-MOZeQ cµ+[‰Z•£›qO%ºZÙ˦ÐyCùUh
-kÚw.¸(]ú½” xõXŸ¢5]eYJˆ&ERq´ê£É)5}ƒºÂ AN’øû¥qøUv*5OÜQe öõfæ˜!m4Zªš|Þ¸í9_*Œ‰}ˆ&ú…ÑáÎ#lt‚4Kå,_Ó>­vþ¦=ÎY|agì¸1cŨ’ý‹êE±!ô¤•n¾óŽ°¢ÀL» t\žË¬±Â‹àô´º=)Ä]讽ÕÐ#$Þ±Ï}C)Æ;W˜µûԌʥ âS_Ÿè  p$È>zÏ;î¥Ê®·¸³7 —ê,Hx;ºÃÂÀ Uo \ñ]Ç…D‚/ ¼s$U“Û¹y>¬Ôõj8t-]öRÃwÝH5áÛSö¡"¥áɵkœåÿSºð5ÛI—Ê/¾sù(¬cVM«ë[š‘Wø±œéRkÝ‘ló%éh/ÙÐvmz†k•mŽ«¾ŽÏJ{ø%ÃÛÃFcæC;f +ëWmVĽâ)ãp*ÃŒ±½ß"Ÿ¥Íêkû>n÷\J¹A]Ó+ZƒMIŬ(mF}©?Æ&ÂÝVdy5høÙ{ùÏͲÿš€`(…;ÕqFQ.â)œ•§¾mGýƒ`Jÿ`*!aŽKC¡9P—ºæ’NésMµD”l!ë•%žú²2¶üÆ7b‡›lK¯±Xż¬ýÊhÍ3&pô—­ ô’½æg
-z¾IŽ‘–®ê¤y¿@ _‚ëØô8`Á
-¼Ž§áC1×E $(ÿùåóì¥Ã»Etå-¡ƒQÊñ­“šØó ¢RØþTj„wˆÞx‘¸Î­™ƒ÷::§µÚ}t\û}‘ùšz2ïN0£Íïo6žÂ{[Ýn:B`¹3uYÉPIõòËl #%­m>¬ßjm¨P!ñß6þŽ­µÔi`Ú›‰º”—”åcßµLD®N¶«ÇÀMÚÖ~d%ÃCÉzí;{õ¾s/{Êáz\k®o²/’þL½Zö
-›°·©+‡™»˜;¹U·ü‘¥KÃ<W ZSEp‹Á“‚;¹Q<­äæ`j†,>)™“ú æžÞOT4’Úzœ¹< N#wÑPzûHE
-˜P y`탿±ßúíÎAk ¦ÖŽ79†“̇mè‚ʆºC¼5?階ÚÑ8%g³bßdÀ
-¾`Ïÿ
+â2ÿںǿ”Õ…‘,Ð=­°þ A#ÿªü%ÎL– Ìk2Í<çvÐüÎu¤›4A¼+¡˜Qxä=ÈLÒv©3Ši;I-jF$+1Ÿ7QKŸRJ/ÔÍV}dÊ»°‚Ÿh´‰«œ¥~ºj¹…´ëµ i2.c9 ²*ÊaM#PË‘ò×Z˜Ä¢Äê¶(‰O lŽ¨Ô¥Ê;A…q5#Ô‹Ï5Ø<+Æf?墳ô˜
+¹Dá@–»MQ«÷aµ× E¶U’ïZÚB…âÂû?z£Td{f+â•ôÞéú ´Q†I¯ÆÕK &C§ T\f­ '4³Þ‰rQ¡(è¦'$“ŸjTƒ¿É×kUºJꆚ×òZ½1”D~Û’½‘Á¡èçµê¦”Õ÷ØB†ŠÑ”·Q¨dŽœ5JN)s¨î‘9›­ê”
+ Å:#쥬,òêCIUyû´PxÂfU‹ #7ªVåèMb-PÁ2‹ÖÑJ¹…êš)!³p…ÉQ§ a“kßfý僊{RW¶<*IIþ\ -²;´5BÑ>¤,œ*è둶òÈn|j¦5~%!“IX\¦_©¥§«‘ÇIµ.V‘uIð´É«³É
+5¤ÕWF‚«+‚“pÍ”®aÿD]ÒÑÕ9²r´(³z0{§yÝö3ÎKUU®\+ɪßæ¶#h4¹r?‹×àsÎœþ x-c܉qõ «â&Èí1F»(qeÒVÕYŽ¾©Ï‹tfy·–{` ÚK¦9´ÖÐk¥ÄƒPMèÍ0o¥Ó]v”°„]–(uˆÁšÀŸJ)Gm]˜˨’Š§ÇP¼wªÈgÑÇf1»xS8$Ü­¤7¦D+|cž+¶ö 'ÁRRIO]1جʣâTw”G™;ÚVW)›ïF–eûiïö—ƶ[»½nÃÏS„6À,œ(Sq;e©¸P¨·IeåîThÂ÷…&Ü­BÓ›V¡éÍJ¡i¤UmúWûÈq3Ÿ¨U9º÷R¢«•½l
+w”_…¦°v¡}ç‚‹"Ñ¥ßë°õ35:ùm¬é*ËRB4)’Š£ÕÉ“œâP³Ó®+Ìäàt¶_‡_e§RóÄ=HÖ`_afŽÒF£¥ªÉç­ÎžóU¡¡Â˜¸so¢ŸqÇ;-ÃA{’f°|M;›zV6|œÅGö’Žû3VŒ*Ù¿¨^€FZéæ7ï+
+Ì´Û@Çå¹Ì+¼N£Õýh¤w¡·ö^CøƾöG01޹¬اã›\
+*>„ŽÙGïy¢A0Ëë‘ÜÙ›†Ku$¼Ýaaà…ªˆ·®8×Àq!‘àK(sŽ¤jòh^§+u½]K—½Ôð]7RMøö”}¨Hixrígù?Áß•.|Ív§dÖ%÷Ì*ÿƒËG*"«¦Õõ=Çwçü(g™“âñüàÁXÒ˜Žö’í
+¦G×wÞl¾/´­k®É†õ÷e®ŠâhÝPÎUÖÅã¾ñ@±€Ã â.±HL¸âkÉ’gLàè/[›KæšÇô\':’#- \ÕH3¿@ _‚ëxàqÀ‚ B”ªeÁìÿä¥]½ªçˆ “εï2£¥OBk¾ÚW¾ó©…ŸÇVx0xi³R&¡;no)n:™™
+?fû_Ð×x$C¸`ªÞf6qª?÷_§¯ãÝñ€ÄP¼u Ê~ù<ùè8·ˆ®# Ìšy'ÇY'4³)‚D|½¶íO¥–A˜CôƇ$Àu^%zÜëÐœÖj÷Ðqí÷…å[êI¼ƒwL+qÆû›‡xp«ûMG,5`¦.k2*é£>~™­a¤¢d µ IÁŒUã¬Ö†
+ÿmãïHÑz¨¥NÓÁ.FêR\R–/I×2I¸:ýÙ®†ÎMÚÖ~d%Ã+¼zé;Ø¢^ÛÏ£ì)‡ëq­u¸¾Ë¾Hú3õjuÓV1#ÿ'éP÷uÈ}¼t:DkeÆ}§²ryˆ±“Sõëº4Ìsµ¢6U÷<)¸Ç‘O‰§uتÀ=T Y†x’o°÷4=‘9IšëPærð48 4<DEYèê# ©PÀJ½>øZ¿ß5(Zõ´Ôºñ.·pa‹e݂Ɔ¶C
+¼gÆøQ3Ðœ£µr6iôM– ú{Á ‚PàT+¿CØ`•\°gþ†àPÀå¹ðßg°`9?¬Z;8ཬ 6Ÿl¼KÇVH£ëð=μ{:õø‘ŠGº|û–ÏÏòx¬ÓÔ|§×ÏT¾ÅíýÜï÷ó²owüÇ-Ïï¡çú³Þêû§*xóÆr94_†!õÒ|)¬Ý°¿úÇ”·ýR¨ngÚ»³‡[Ñ* ÷hÎÊçƒæÝ0áq[&òÎýAÄç*Xˆ_È žÍ<ÊÉï¢+]pð^Ý`¥ª¤Zèæ ‘tsGŸ#p¦Êæ¶Q‘oÝèŽbó².M ôôž6È°ßu Æåyp£ÍBJR&
+.ĵ”ç§ñÒ2Ý›|‡”j®°}Û ©©åFê®AÏÜh ËRS;XÑNi@4Ímãtß꺻É9F¢ß{éÆ”}v︸†?¹w¬—뉾uèH?©‚¾Xª-Š·ohÛ‹z²´hË®m°'‰ª®õà°­ªk í·÷Ÿs“B×~¦Õº BfS£´ýâÔÖ6‹Ëûï±°«_½ti>öxDq^Ãó‡×zC¼—Ú0ÞTN¦ùðÚÏÊGB—îmó‰Pó ­7ŽåÖ±ŒRó$Ý]Ãt¹@A°·£:G ãç
+6·öAwi2ÓÞÞ´òåD9pÓ-%‰Há· „> 1Ù›Úv›xKû1¯‘9Gÿj#ú±U‘¯=¸1
+lïz +xØr(ÕÆ­â·å2«¢òÚ]TíU3©ó¼è¹ß¬tßÿ¥¥b^
+‰Óþ½ýõé—ô`ÈF6lp8j¥én ;½YÍ”·}SdêTImq:_g…`ñ\?nIÍ¡á-ŸÂ=¶ý¢P )¸(·¢OÄY;Px¡ÖLæÕˆ¤ÒÓuy¥7Cóc¥{€;L¯Ô;®{:ª4MíÈŠ2©!ɹi”©°²éû‹UrÅk,n
+·D!Tl¥Çì ìñÀŒ6›âq+]ö¡¥¶ öü?cvN&
endstream
endobj
317 0 obj
@@ -886,35 +872,35 @@ endobj
[ 314 0 R 315 0 R ]
endobj
314 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 324.092 529.716 338.817 541.672 ]/A << /S /GoTo /D (subsection.4.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 324.092 547.28 338.817 559.235 ]/A << /S /GoTo /D (subsection.4.2) >> >>
endobj
315 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 354.538 529.716 361.512 541.672 ]/A << /S /GoTo /D (subsection.4.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 354.538 547.28 361.512 559.235 ]/A << /S /GoTo /D (subsection.4.2) >> >>
endobj
319 0 obj
<< /D [ 317 0 R /XYZ 78.37 808.885 null ] >>
endobj
89 0 obj
-<< /D [ 317 0 R /XYZ 79.37 681.914 null ] >>
+<< /D [ 317 0 R /XYZ 79.37 681.674 null ] >>
endobj
316 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F62 222 0 R /F72 290 0 R /F53 218 0 R /F16 282 0 R /F55 221 0 R /F68 249 0 R /F63 223 0 R /F65 224 0 R /F54 220 0 R /F32 228 0 R /F48 229 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F62 222 0 R /F72 290 0 R /F53 218 0 R /F55 221 0 R /F68 245 0 R /F63 223 0 R /F65 224 0 R /F54 220 0 R /F32 228 0 R /F48 229 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
327 0 obj
-<< /Filter /FlateDecode /Length 3564 >>
-stream
-xÚÍÉŽc·ñÞ_¡šKq„F£‘ß’ÌÍð)ArÉ’K~?Ž¸==õL€Øhwë‰,Ö¾±ž9Ó—\8þ÷×·Û··_F^<óF¸|ûû›¸püW\¬gÊ^¬Œqùöýòû•se97œs-8‡Ûû'-õ5üŹø‚ßx\ñ¨OeúFCZö_¾•üýo¿§g‚›rš¼åIë)@5Ê„ïÌ
-†²Lèã€[€ð+˜8á9¸[¹<©™ðšâ¤d¦.ïžñÁÏæóŽPLE+n ¥Šþ(¿Ã“®¡;þýÀ¤UfS&7~g#,$rGˆ ðÇ\þ”þ5¨ƒÚ«ƒq’)í7ê@OØ©®dÒË’)øqæpUÆ*ü‰8µ½ši9íÔbQwJÃ
- ˜ø’õ³BëXoÌÈzcO³>.¥¬·KÖ㚀¿Ñ™ýEM…‘ Ò';¡Ø#¡DbB>oMÉoIN/+æÓÇÃÓÇæ´}ú&žŸ]Å:W,‰@ÂàŠ:@ׯ‚ìwSŠjaqܘ7$#è4Fp`ÒâyÊ1ß*¯¾Zh*Ï¢Ó½%ÏÕ™#ùô¢ÎJŒyF鬞tVŸ×YMñ#Ÿ]¥:TÅqÄUŸÝaX‘˜îAW‡þ«aELÐ#”ßÇ­@Iþnø†UÔBèªYÇÃ. ÉeªÅšÁÚŒ^XèĹº’Ê_Ò OýFÂu­›B²Ö]©f|§þ=HÎJ¹òèkÅu_m…üoã¼%Š’ñU2÷>^ôÖ{*$®xãqíèÉ{𢕨jÔ#ñEȵ•Ñ1£Pyß–kiKqQ¥nõ¼Ûd•2CpŠ9¬oŠy|#ókiS²ÆX-¸è\=‘O1Âj$®…‘.)ëC^åH…ÉùkM
-yrE£ ßæ]&S‡ths-§5}/*»æ¥Á jñ³ †é¯}Sp ZuÕò>Õ­u÷.Æšƒr„1q)>­Ö“ÖLêä—|’ïK«0߇‘ÎW3:D„ÒG¡Èµ;Ñp¢õ‘Gò9µè µéIó*5ÕXÓ
-X?a)Iûã±ÕËç wzwÌp
-»PVº .Ûr-ou:œª«÷A‰›}ÍX‹VOw þð·\w1Bäá2Eq³¯jÛbY=ÄÜ„6+4¦? à'Ú 08ñªhòëèþMͳê§ ï‹Ì¥”‰ÇæJåP<þ\à;š~˜Ì!iÜËõUØ”ÉÉPpîà:;™Žùh=Ï,á$…ƒ»jîv
-5io5ìã
-͢ǯÉA â‰›ÂÜñw&åtNUÓò+×Äs0\š½1Ò !?КžJ’Öä'– [ ëŠ³# ô®qarhN;Tw@s·˜ð…L3a\KZos"Hqª°º•%\†TH‚Ш.•IÚ£Ÿ×Ôè^ý(BæÞ¯òìŒÝZ÷gi*Ô ×®¤$Qð{‹ü±-òØädÊZæUUˆ¾
-¦ðr®²¦˜¾‰¶ëqta‘úkw诧èUÕBj¤½Ýª)sÔ‹š¹”Zµzªý»»®Ü8íô bÎ[—¦xuëV<í#Q}è|¨?Óé¢:R°IÆ›àO¼ê‚>+“jƒ× W’ûùª,eg7&¶ Ó¹#××Â9]6òßy¾OÕ¿ZšÙ.Jò8Úö.:zTžLd¸ŸwÓùäÞwC7½LX[áI(“ÖO>Vü:ö"Ò3ƒ‡ 6Ö*fNÕî“Ù/ZO+pÇ«nÒ~NYWû,q]g[ã FZ_2­ûPÂÇocC÷læ²+ ûɉ‡R<Þb§Ü êu`«F{>*¬õí$á,¯ê·zÝE($º“JX¬ô]×F<¡ÀBJÆå¸ùIÄÒÆ ©ñÈeÄ[ÛW?<°÷Úµç6ÑÇÛ6ò°U”i©-²¬ñ¤¶˜iɃ›8˜nâàüMtñÔ‰O¼Ž7ëÔ!¹ïb+tQ ÔGZopÄφY‰Þð‰÷VÐáQµà:Qš§Èj¢?³>]ÞšúíáìU1"ÐLØçw;crÌi=B ·€;'zÇ/F
-á ž2¡º 
-í»ÕSZúLZæø>|Ëf܈EHcBÈR…µ‹”ÆäËÍ&ÀœÊ¼ÎÌ)• çÇ´i0’xŽ%8ø´¶†k{".ª)xÄÏ>M‰ÀÜO¹Yt±&WÇ×R–œqÓÍÆü¬ê¹+ÿðÈXó}ù¶k£Â<Ì+Û9ךëÄOô®¨zÚI{Hs¸NØ2dÒMÈþþ¼?-ÏÙn3š` !Ùèñ[%ñʘqWŒ­5VZÈmo}¼½7e;¾'*§ƒ~Óøôr<°ËZË’.d¢Üò¥ihÇ”såñzfXšiãny_kJßä¸o³*áy]:Ærµ»«ÞøÀ`é\~rP\1…_§ôÍ„îbúÒvym„c¨h9y/íYu+,&’äE±ÿƒ¸°óõêÖUáìèë!•z¯Æ“Ô«lM¯ÀÃŒÞ2:.¬…ö ÚàY‰îó½I›…m5Åzlx—ì®û_¾‘é4»;ûŸ9½íl]ª³óëI§j"ß¹íg àëæ6MÄQZ7E6ž[Ì5B­nVhÙ[…Í]¹}ãö`€4F†¸¶œ²Š]½ÀÍ(¡´Ÿönmf0¿FÖí#gשߤ˜Jã G^–3ê Ï&xomyòÁad˜ocÊ6œ5)IªÜÌp7üüÌ:ï&(ãÆùBh¥DXÁ+§¦eûÎÖöš'0ûçÕÀ&‘nZÔ+qžl“‹âæ'M8¬Ê½9!¡õ‡Š¸Á=é æfHšBº‘‘¹ƒær?fúš#;9ŸŽÅ¬¾`¶cUx‘˜(¬Gì%*¬ÔÌ{׽̖8ùõÛÛ¿5òžIqùë÷·ßÿÀ§ßßÂKv¸ý?qÝw ÖÀŒ»þyùËÛŸÒKçJ^,b€ÙÅ ´×thšØöÆu:>ùÆÔ4©Ó±¾¥ ýµšóŒ×"®ø|Ó¬øxÅŸÀÐÆ×)Jë¯6c‘³æ£ÞÈæìÙÞûé]CºžLE%X£’d¼Hpm¸''òvžø1ÌBQ(b'Å –'ošï$ŒT1
-M¯dÓôYuUITïëRÇ6-VcR€ëXÆ1Jô›Ú‰Y(6° æ +гˆ±°cŒXÈrÇ’ø`%•&ež ¤Vï¹FK¢û°jÆê& ×¦u2¿1^߈ÞMíKf´¹
+<< /Filter /FlateDecode /Length 3530 >>
+stream
+xÚÍÉŽc·ñÞ_¡šKq„F£‘ß’ÌÍð)ArÉ’K~?Ž¸==õ ‚Øhwë‰,Ö¾±ž9Ó—\8þ÷×·Û··_F^<óF¸|ûû›¸püW\¬gÊ^¬Œqùöýòû•syã\ ÎÄ߀sÀ¿ÁŸðyÿãÛo# ðLpS`(˹ø’`Ÿáñ'<—`+·ƒ§,ºÃIÉ´¿ìE´>øÙ|ÞÁ‘š ¯)^q¿h8U<ðGù¡˜„Šdtîø÷ŽV™M™Üø xJ2ÀsùwxP>üù× µñ’YÛ17"N¹u'ì+™ôr„d
+~œ9\•±
+"Nm¯fZN{á–DèU‹ºS
+¢$#dåÈ´[ÉÄV<ÉlÏœèwŽ+qÆŶrÏazæDfÞtÈ¡
+P€vØtNk(¢…ÁqcÞ, SÁI‹Çc\èu…ÐøSžE{Kn«³EòéE…UŠaô;ÒX=i¬>¯±šâG>5ºJE¨Š×ˆ«>»Ã˜"1σ ®ýWcŠÄ2^)=B™ñ}ÜZô“äï†oXE탮š5<ì’V¦ú«YÜ©Åè…}Nœ«+©ü%ñÄÑk$\׺‰E„¨¦PøN{<(œ•råÎ7ŠÇ Öz⤀$-Q”œˆ¯š¹÷Á¢·ÞSñøsÅkGOÞƒå¨DU£‰/B®í‹Ž…ÂÈû³\ËYŠÛˆ*u«çmœö «”‚G3ñ­Šþ<†å×r¦.`ZpÑ9z"Ÿb„ÕH\ "]Fּʑ ““ךòä>ŠF¾Í»L¦éÐæZNkú^TvÍKk˜U%7ãŸm0LíS˜‚ÕŠ¨«–çà©n­+¸w1~Ь’#Œ‰Kñiµž´¦`RŸ ¿ä“d_Z…É>Œt¾ê˜½cˆþ¥B‘kw¢áDë#äsjÑjÓ“æUj¢±¦°&4~ÂR*’óÇc«—?NA@2îôî˜á€„þQ~Cš3ÓÑÛÐWøŸy¸ÐsÌ:Õá“ë¯ÞÊΗ Ëׂ„_ –·°\|\ ®«Xe6I•”Kq¶2låÛº5UÛ¶ÞÇȞˤ¼.”•Ö‚˶\k[]c†§êê}Pâf_ðƒò˜øÀܺH¿µ\·0Bäêq³¯jÏbY;ÄÜ„v*4¦? à'z˜YYûòëèþMͳê§ ï‹Ì¥‰ÇæJåP<þ\Ý;š~˜Ì!iÜËÕUØ”ÉÉPpîà:;™Žùh5Ï,á$…ƒ»jîv
+5io5ìãú̢ǯÉA â‰›ÂÜñw&åtNUÓò+×ijVö­Ý÷O FúA˜!äZÓSIÒšüäÑd t]qv¤sÞu-LÍi‡êÎhN"ã¾i&Œ‹cIëmN)NV·²„ËJ
+VYÖÙõŠ9!1r]·tUTçG oá¡„«’ꤒ¡òG;l»2M4V~Ð JÛ)î©2m¥¥¡jI5.æ¦õD[Isø¬:å „¢gô„æÎJ:eŸ^V2õÊg„Ò@—òø^Ø¢¯­Rš=Iä}© žÐ b:åK-V÷ÎŽ;µIþ4S§Te›'Øô´”6L·A„rgØuGB(ÕþZ/Ôò§rÓ@‹×”lòk)ró“¸^Ö>â!—$ Ñ1[[I– 'å€/˜=é&y<e:¤ˆÁ¸u½¤™5ó®GcZ’WâÆ^‡3„9½"„•ÕSEäìu„˜®VÞuª9%ÿ-É@¿£vQI³4_fYDµ×ìÔB1¡Ì†Ÿ“Ò0ݦVú4féckï7)?¹Î©é¼\¥õ³ï}ñÇÆAT·[­ÒT‰¿c«ãd¾¥0ÉÇ„zd<ÙWöŒ5´„)¼œË¬éþ¥ï¢íš]X¤þÚúë)zUµP¡‡ÙÊP• e®‘‚ÑB3—R¬VOU¢wÓ•;§TÌykÓ/¢nÝŠ§$ªõgZ]TG
+6ÉxüÉ€WmÐguRíðšáBr?T•Å",³Ä¦a= ¦sO®¯†sÂl>äÀ?i ÍúWK4ÛUIBÛ^E*ð·’~êÿ„‹Î'×¾ºéuÂÚ OºŒÐ“ÖO>Vü:v#Ò3ƒ‡ 6æ*=gž·d^dÇh=­Á¯ÊI;:e]í´Äuqwi}IµîC¿-ýܳ©‡‘LÁHØOÎ<”âñk<å^P¯³Z5ÜóQa­ÿhß gy¡P¿Õë>Bñx$ÓTÂ:浤Ä
+,¤d\Ž›Ÿ„<!-“ZLG.CÞÚ¾úÙ½Ûî¬=7Š>Þ¸‘‡Í¢ÜJK‘e‘ïA ÜÅÁtçïâ K
+ý &ú3ëÓõ­©ßŽ^#,MøóÛ19æ´¡„{À Ýã#…œé] PaÖnó:Ðgò:0Ç7â[†¸0}àF,BB–*¬]¤4&_o6æTæufN©L8?¦Mƒ‘Äs,ÁÁ§µÕ0\ÛqQMÁ#~öiJ˜@©¹Yt±&WÇ×R–ÀpŽùY)ÔsWþቱæûò}×F…g¦)zËu€æ:ñ½-ªÞƒ¶GÒÒ®ó
+<ÌØáÝ¢ãÂZ`>
+stŸ/NÚ,l«)ÖSû<`wáÿò•L7¢ÙÝÚÿÌèÝpgkS@XÏ:Uü‚Èm?e
endstream
endobj
326 0 obj
@@ -924,28 +910,28 @@ endobj
[ 321 0 R 322 0 R 323 0 R 324 0 R ]
endobj
321 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 409.333 454.662 424.058 465.502 ]/A << /S /GoTo /D (subsection.5.5) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 409.333 461.854 424.058 472.694 ]/A << /S /GoTo /D (subsection.5.5) >> >>
endobj
322 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 439.779 454.662 451.734 465.502 ]/A << /S /GoTo /D (subsection.5.5) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 439.779 461.854 451.734 472.694 ]/A << /S /GoTo /D (subsection.5.5) >> >>
endobj
323 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 470.992 156.532 485.716 167.371 ]/A << /S /GoTo /D (subsection.7.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 470.992 158.558 485.716 169.397 ]/A << /S /GoTo /D (subsection.7.2) >> >>
endobj
324 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 498.668 156.532 510.623 167.371 ]/A << /S /GoTo /D (subsection.7.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 498.668 158.558 510.623 169.397 ]/A << /S /GoTo /D (subsection.7.2) >> >>
endobj
328 0 obj
<< /D [ 326 0 R /XYZ 78.37 808.885 null ] >>
endobj
93 0 obj
-<< /D [ 326 0 R /XYZ 79.37 610.899 null ] >>
+<< /D [ 326 0 R /XYZ 79.37 621.051 null ] >>
endobj
97 0 obj
-<< /D [ 326 0 R /XYZ 79.37 442.219 null ] >>
+<< /D [ 326 0 R /XYZ 79.37 449.146 null ] >>
endobj
325 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F62 222 0 R /F63 223 0 R /F53 218 0 R /F15 219 0 R /F54 220 0 R /F16 282 0 R /F68 249 0 R /F70 274 0 R /F55 221 0 R /F32 228 0 R /F61 231 0 R /F48 229 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F62 222 0 R /F63 223 0 R /F53 218 0 R /F15 219 0 R /F54 220 0 R /F16 244 0 R /F68 245 0 R /F70 275 0 R /F55 221 0 R /F32 228 0 R /F61 231 0 R /F48 229 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
332 0 obj
<< /Filter /FlateDecode /Length 3281 >>
@@ -977,7 +963,7 @@ endobj
<< /D [ 331 0 R /XYZ 79.37 157.041 null ] >>
endobj
330 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F16 282 0 R /F15 219 0 R /F62 222 0 R /F68 249 0 R /F63 223 0 R /F65 224 0 R /F22 226 0 R /F59 334 0 R /F54 220 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F16 244 0 R /F15 219 0 R /F62 222 0 R /F68 245 0 R /F63 223 0 R /F65 224 0 R /F22 226 0 R /F59 334 0 R /F54 220 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
337 0 obj
<< /Filter /FlateDecode /Length 3290 >>
@@ -1005,7 +991,7 @@ endobj
<< /D [ 336 0 R /XYZ 79.37 419.325 null ] >>
endobj
335 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F62 222 0 R /F54 220 0 R /F63 223 0 R /F68 249 0 R /F16 282 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F62 222 0 R /F54 220 0 R /F63 223 0 R /F68 245 0 R /F16 244 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
341 0 obj
<< /Filter /FlateDecode /Length 3995 >>
@@ -1047,7 +1033,7 @@ endobj
<< /D [ 340 0 R /XYZ 79.37 288.408 null ] >>
endobj
339 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F62 222 0 R /F61 231 0 R /F63 223 0 R /F22 226 0 R /F31 225 0 R /F25 308 0 R /F15 219 0 R /F59 334 0 R /F57 343 0 R /F44 344 0 R /F56 345 0 R /F53 218 0 R /F68 249 0 R /F55 221 0 R /F54 220 0 R /F16 282 0 R /F32 228 0 R /F48 229 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F62 222 0 R /F61 231 0 R /F63 223 0 R /F22 226 0 R /F31 225 0 R /F25 308 0 R /F15 219 0 R /F59 334 0 R /F57 343 0 R /F44 344 0 R /F56 345 0 R /F53 218 0 R /F68 245 0 R /F55 221 0 R /F54 220 0 R /F16 244 0 R /F32 228 0 R /F48 229 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
348 0 obj
<< /Filter /FlateDecode /Length 2692 >>
@@ -1079,7 +1065,7 @@ endobj
<< /D [ 347 0 R /XYZ 79.37 475.905 null ] >>
endobj
346 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F55 221 0 R /F62 222 0 R /F71 275 0 R /F16 282 0 R /F54 220 0 R /F68 249 0 R /F32 228 0 R /F61 231 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F55 221 0 R /F62 222 0 R /F71 276 0 R /F16 244 0 R /F54 220 0 R /F68 245 0 R /F32 228 0 R /F61 231 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
352 0 obj
<< /Filter /FlateDecode /Length 3938 >>
@@ -1121,7 +1107,7 @@ endobj
<< /D [ 351 0 R /XYZ 79.37 165.179 null ] >>
endobj
350 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F62 222 0 R /F54 220 0 R /F53 218 0 R /F22 226 0 R /F16 282 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F62 222 0 R /F54 220 0 R /F53 218 0 R /F22 226 0 R /F16 244 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
361 0 obj
<< /Filter /FlateDecode /Length 3563 >>
@@ -1183,7 +1169,7 @@ endobj
<< /D [ 360 0 R /XYZ 79.37 189.497 null ] >>
endobj
359 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F62 222 0 R /F54 220 0 R /F53 218 0 R /F71 275 0 R /F61 231 0 R /F63 223 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F62 222 0 R /F54 220 0 R /F53 218 0 R /F71 276 0 R /F61 231 0 R /F63 223 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
368 0 obj
<< /Filter /FlateDecode /Length 3335 >>
@@ -1219,7 +1205,7 @@ endobj
<< /D [ 367 0 R /XYZ 79.37 218.498 null ] >>
endobj
366 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F71 275 0 R /F63 223 0 R /F62 222 0 R /F15 219 0 R /F68 249 0 R /F53 218 0 R /F54 220 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F71 276 0 R /F63 223 0 R /F62 222 0 R /F15 219 0 R /F68 245 0 R /F53 218 0 R /F54 220 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
376 0 obj
<< /Filter /FlateDecode /Length 3219 >>
@@ -1268,7 +1254,7 @@ endobj
<< /D [ 375 0 R /XYZ 79.37 249.858 null ] >>
endobj
374 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F71 275 0 R /F63 223 0 R /F62 222 0 R /F55 221 0 R /F15 219 0 R /F77 378 0 R /F60 230 0 R /F32 228 0 R /F53 218 0 R /F68 249 0 R /F54 220 0 R /F61 231 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F71 276 0 R /F63 223 0 R /F62 222 0 R /F55 221 0 R /F15 219 0 R /F77 378 0 R /F60 230 0 R /F32 228 0 R /F53 218 0 R /F68 245 0 R /F54 220 0 R /F61 231 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
385 0 obj
<< /Filter /FlateDecode /Length 2671 >>
@@ -1301,7 +1287,7 @@ endobj
<< /D [ 384 0 R /XYZ 79.37 238.622 null ] >>
endobj
383 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F62 222 0 R /F15 219 0 R /F54 220 0 R /F68 249 0 R /F89 387 0 R /F88 388 0 R /F90 389 0 R /F31 225 0 R /F22 226 0 R /F53 218 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F62 222 0 R /F15 219 0 R /F54 220 0 R /F68 245 0 R /F89 387 0 R /F88 388 0 R /F90 389 0 R /F31 225 0 R /F22 226 0 R /F53 218 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
392 0 obj
<< /Filter /FlateDecode /Length 2992 >>
@@ -1339,7 +1325,7 @@ endobj
<< /D [ 391 0 R /XYZ 79.37 539.277 null ] >>
endobj
390 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F62 222 0 R /F54 220 0 R /F63 223 0 R /F65 224 0 R /F53 218 0 R /F70 274 0 R /F68 249 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 219 0 R /F62 222 0 R /F54 220 0 R /F63 223 0 R /F65 224 0 R /F53 218 0 R /F70 275 0 R /F68 245 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
397 0 obj
<< /Filter /FlateDecode /Length 2119 >>
@@ -1423,7 +1409,7 @@ endobj
<< /D [ 405 0 R /XYZ 79.37 734.627 null ] >>
endobj
404 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F15 219 0 R /F54 220 0 R /F62 222 0 R /F55 221 0 R /F68 249 0 R /F32 228 0 R /F61 231 0 R /F48 229 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F15 219 0 R /F54 220 0 R /F62 222 0 R /F55 221 0 R /F68 245 0 R /F32 228 0 R /F61 231 0 R /F48 229 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
411 0 obj
<< /Filter /FlateDecode /Length 3013 >>
@@ -1453,7 +1439,7 @@ endobj
<< /D [ 410 0 R /XYZ 79.37 771.024 null ] >>
endobj
409 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F15 219 0 R /F62 222 0 R /F68 249 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F15 219 0 R /F62 222 0 R /F68 245 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
415 0 obj
<< /Filter /FlateDecode /Length 3132 >>
@@ -1479,7 +1465,7 @@ endobj
<< /D [ 414 0 R /XYZ 79.37 771.024 null ] >>
endobj
413 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F67 243 0 R /F15 219 0 R /F62 222 0 R /F68 249 0 R /F54 220 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F67 243 0 R /F15 219 0 R /F62 222 0 R /F68 245 0 R /F54 220 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
419 0 obj
<< /Filter /FlateDecode /Length 3056 >>
@@ -1508,7 +1494,7 @@ endobj
<< /D [ 418 0 R /XYZ 79.37 771.024 null ] >>
endobj
417 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F15 219 0 R /F62 222 0 R /F68 249 0 R /F54 220 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F15 219 0 R /F62 222 0 R /F68 245 0 R /F54 220 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
425 0 obj
<< /Filter /FlateDecode /Length 1379 >>
@@ -1544,20 +1530,20 @@ endobj
<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F15 219 0 R /F62 222 0 R /F54 220 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
495 0 obj
-<< /Filter /FlateDecode /Length 1912 >>
+<< /Filter /FlateDecode /Length 1911 >>
stream
xÚ½ZÉn$7 ½û+êF‘HŠ’€À€ÛmÈÙ· ×ä”ÿ¿†R•–R©–næ`ŒÇíâÎÇG–õô蠟?^n_/¿}Zœ )$†éëŸ#èÉL.(t“C­,O_ÿMý®5ùºk ŸZ#híèõï¯?E„á)¨ÀÀÔŠ0ä”õVÎRbnù!;zhÖËž” ¡<ó®5‹bZÛh„nó÷€óùÙ(¸¿þ@Dy
éyŽÂÄŒJ»â$Àû¬QLygáö
>ŠgûäŸdc´=.Ú‹íÑæô¹^Ùí $hû`P†«gï£t›¿g}艑¬ƒ½$kgû¢m)î0E‰–[;müÄ&mà˜&:¯?RX¢ˆ‚9)‹ø¨2ª³ÔüòZ×’ÏN—±
j‰>¯+þ-Ä:ÃÏ~?Ò¯Q¡¾ækLsJÐ}þl뢅
-Œ´§m‹u“n^Œ÷U[ñ´H§•ä;Ù¨!<#9ý¼ñÍâüÿÒ¢÷ ÚÙ)BûSÔÓõ‡H y²d•3Xìy»€QÐÍ—grgßjÒ}F…h[ö§TY‚ÑMW½Ê
-â#F7Ø•)rÄ]…'QÓF°õ‘¨ÍiMPÙæþŒè“(öê~r4e“PÀø 3K› z<Ôû#B†ØÂ5ëŠW¨X+Ð[èéÃM¼°\ T50ßZe{ÉhIíOAžýø¥¥j@¸Z°POh„P…PFìÇyí‡ Î¼¡±F8Ô˜‘»â‡ ¬®ûõ˜È<p×
-—oƒ22µzR—¸fuȯ×ÛåæxÐI ZÉm “ä†ÕnXke4U+/Ë¥þVÁ•Ö3BK\òÆí¶2’M|´ußOo—¶
-ÓsgÛå°ÝÿøÄR`³Òiy¸×À(2§qåFÓ½óBY+#øÔK¯Oc„‘„ê‹ž]©J‰“þůã²}ñzlë‹ ÙgËn›¹Ûúè%aìˆ~#õ©¥=ŽÎ‹ˆF^v^â¾ÒìEÆò’÷å>˜°ÆŸc.{åÄ“NCöhµ¸ö$è¾w~íïQžÈÊ„B»Ñÿ½<‘§uÞHÝÆÿítzË ˆQq=y±¹–5ØvjìÊŒô{hXñŠ1éô
-—îJ¤¬÷¼Ñ¾>j_¬;™È®§®xð(î8«<Ù¦š%;ħ\½ß0ä.XêêŸÌzà6:Pt›y‘oÄ.ퟕ߿-“\‰÷‰-B½}=òpÓÝ9úý‹«Ü—3þ6½ôèél£|=íÙPþ$ê}ü¢lOŸ,Æ}ÎKÂø€¶'—
-~åÇ*>›µ)_ŒZÖ”=|éУ²32SÒó!¤—ƒž9B5á2ÍXVºrbi'‰ÜØÔw«,è:óœ¾í/»ÂÜ„}„‘ÌÄ
-ü¸Š<;§#BŒžÖ
-¨Ìo~¿ä9x¯À×Õ÷½Ö{šº<¿F,<f—_ÇšÚ«¼.“ÇË…²Ÿ8æ ˜…S´ræš?–„ë uKæÒáí†9Æ&ˆïxëZ\Ú&³ "C¸£ªà*Ô¾•#ÙÇ×Ëÿîþe
+Œ´§m‹u“n^Œ÷U[ñ´H§•ä;Ù¨!<#9ý¼ñÍâüÿÒ¢÷ ÚÙ)BûSÔÓõ‡H y²d•3Xìy»€QÐÍ—grgßjÒ}F…h[ö§TY‚ÑMW½Ê
+tfi“C‡zLÈ ›@øf]Dñ
+½k~ E}¸‰¦ „ªæ[ël/ ©ý)ȳ¿ ´T _ ê9àB
+ôƒºn3ðYsÓì8~sgXJ“¡]žÀ„Óëi2
+½]|k3gs€^…ºi¬ám†är¡îÙ­ÇcßÐÜGªc`¨3çeT 9í]XŸVvÊÖ(£ib!ÐRfåI¼2m•• ÒÞ6±Óì6¡&Ü{>6¢[J›Ú;Âv ·—õâe(À;ÈãÑŽ($JFL/­ŸÑ§Öð,§iöíAòÄRª¤°®Yb¥ùkãßÇÄúºÚ& ÿèŽýËÏò
+Ìt<ÈLIÏÇ^
+zæÕ„wÊ4cYéÊ Šý¥$rcSßA®² ëÌs~øÖk¼ì
+söF2+ðã*bxðôœŽ1zZ+ 2¿ùý’çà½_Wß÷Zïiêòü:±ð˜]~kj¯òºLÿMÊ~â˜'`NYÐÊ™kþX®W0Ô-™Ko†·æ› ¾ë­pqi›Ì2 ˆ áŽBª‚«PûVŽd_/ÿ#™ÿë
endstream
endobj
494 0 obj
@@ -1621,7 +1607,7 @@ endobj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 157.288 403.697 169.243 414.537 ]/A << /S /GoTo /D (page.15) >> >>
endobj
446 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 162.817 391.752 169.791 402.691 ]/A << /S /GoTo /D (page.9) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 162.817 391.752 174.772 402.691 ]/A << /S /GoTo /D (page.10) >> >>
endobj
447 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 127.111 379.668 139.066 390.626 ]/A << /S /GoTo /D (page.11) >> >>
@@ -1672,7 +1658,7 @@ endobj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 135.44 91.29 147.395 103.245 ]/A << /S /GoTo /D (page.10) >> >>
endobj
463 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 169.761 79.334 181.716 91.29 ]/A << /S /GoTo /D (page.11) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 173.686 79.334 185.642 91.29 ]/A << /S /GoTo /D (page.11) >> >>
endobj
464 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[1 0 0] /Rect [ 153.96 67.947 165.916 78.776 ]/A << /S /GoTo /D (page.14) >> >>
@@ -1768,7 +1754,7 @@ endobj
<< /D [ 494 0 R /XYZ 79.37 706.717 null ] >>
endobj
493 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F16 282 0 R /F15 219 0 R /F54 220 0 R /F68 249 0 R /F62 222 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F16 244 0 R /F15 219 0 R /F54 220 0 R /F68 245 0 R /F62 222 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
538 0 obj
<< /Filter /FlateDecode /Length 2265 >>
@@ -1898,7 +1884,7 @@ endobj
<< /D [ 537 0 R /XYZ 78.37 808.885 null ] >>
endobj
536 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F15 219 0 R /F62 222 0 R /F54 220 0 R /F70 274 0 R /F71 275 0 R /F16 282 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F53 218 0 R /F15 219 0 R /F62 222 0 R /F54 220 0 R /F70 275 0 R /F71 276 0 R /F16 244 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
556 0 obj
<< /Filter /FlateDecode /Length 808 >>
@@ -1963,7 +1949,7 @@ endobj
<< /D [ 555 0 R /XYZ 78.37 808.885 null ] >>
endobj
554 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F16 282 0 R /F15 219 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F16 244 0 R /F15 219 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
1 0 obj
<< /pgf@ca1.0 << /ca 1.0 >>>>
@@ -2307,79 +2293,15 @@ endobj
<< /Type /Font /Subtype /CIDFontType0 /BaseFont /HKOFRT+LMMonoSlant10-Regular /FontDescriptor 589 0 R /W 588 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
594 0 obj
-[ 27 [ 869 559 ] 34 [ 818 639 575 ] 38 [ 575 575 ] 42 [ 831 511 ] 46 [ 882 639 ] 49 [ 756 527 575 ] 54 [ 724 351 575 575 904 575 ] 63 [ 639 383 436 319 ] 71 [ 692 319 ] 74 [ 1092 958 900 639 575 ] 81 [ 575 575 786 639 ] 88 [ 319 ] 91 [ 607 ] 95 [ 863 474 639 454 ] 100 [ 575 575 ] 104 [ 800 447 575 575 885 639 ] 112 [ 607 1189 831 869 607 ] 118 [ 607 ] 122 [ 671 ] 125 [ 639 ] 168 [ 559 ] 251 [ 527 ] 319 [ 639 639 ] 499 [ 571 571 ] 502 [ 319 ] ]
-endobj
-596 0 obj
-<< /Filter /FlateDecode /Length 39 >>
-stream
-xÚc``°6.þøp_ÅÄ7~©0€@ @iF„2
-endstream
-endobj
-597 0 obj
-<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 6521 >>
-stream
-xÚµz T׶vµÐ]­2(E;taU;jb4€QŒqFD™gš¡¡»OÓÌ“€ ‚"(È J‰ó£ñjbý5c¼Ic®Ù…‡÷¿ÿ4¨IîÍ{ÿºë­Ç‚j¨sêœ}¾³÷·¿}
- enNI$’AK\¹­Z<~ÉÒU!;|‚ß™ìè²Ý×Ôâ*ªÄáÈ‚í(q˜Däúˆ¼™hkŽí-Ì.Y˜wÇããv2W;óÒa%AÖäÚÇv ˆ,FßT£-F™nXXŒ¦è>”„D±ÔcJ$ÃÊ$V9唉“'O›¸5 R5eòä©L×™*—‰ªÅ>[‚Bb"‚U>Á¾ªÅUK'ª–…Ä»ª1!ÁªÍ~>ÛýU!þªÕ~ª¨¿ðÕÖð¨Ðˆ±U«#T1!áA*òî·ÝÏ'ÂÏWì뮊 ðS¹®q[­Z©Z¸Å/8ÂOåè¨REøù©"#CgMšµubHøÖIþ¤OĤí½"&™žs\¸|ÙjÇ%Î_°ÌmÁÄÈØH•H¸Ê×/Ò'p{ÄÄ?¯ðí_ξ!›ý>ôõ Ž ŒŒ£ÈKÙQ#¨‘Ô(Êžr ÆQ㩉Ô$êj
-5•z—šA½GͤfQïSó('Ê™r¡\©EÔbê#j µ”ZF­¤VQnÔjʃÚ@m¢¼)j3åKùQT µ
-¢¶S;¨P*Œ
-§"¨H*šŠ§vQu–Ì“8I~•üCò›Ù òåL9›¶Êœ
-¡@²]òmŸ¡}™9™5Ÿ`žnŽ¥¥×en²&º?½~)Ïí›Ð÷NßçýÆ÷‹é×ÞïQÿL …ÅEËá––¿Y½oUb=ÖúCëƒÖ h¸n ØØ
-æàøI‰á[SJN9«®‹dÉÇš L€ †30¬KËO¦_Ãýó9 ö\½tKùý´;x:׽Шîï0å)úÊ`Öý‡Ïxìws7,ÇáÉP‹eÏËg{ñûðE¶x‡—À1p—UÈûй©•V]Œ¦I´m‚•gm^‚ -
-
-êø#í².8&‚ƒ/H•zÒ—s‘/ßýT K÷”•—î‘3WSó:×|ÇÂØ€ç±í O´:Ì—Ûì¥bøžÙÌCݸïxÝY¬¶\À[‰Ÿw¥ÄHÄ\¢ÈÑÒ‹¹nËWã¥eiéÅÑì®êAŸÈ‹–ÿw¼4!''¡’-)-¬0=†Mâ*Ó·ÀÌö1 '(ŠÓ³’ ÜŒlÿƤ&¹¶
-ŠÂ#ÞY7WÏáÍôR½-˜‹ŒصY'ߥOEñÊÄìŒ"=÷(½icþVyf*Òù+±?ma–úZU>*çþÒ&0¾¶é#ãÚÚø³rmÊl1™
-P%Œ»w榃ÍôUTv¨ž+,<XuúÍ¢¬º>W â+ArEm§YW.Ä(*Ò ñ‰)(ž,T™†-—Ù³sfìýx-ïy>éËGÊsF >ù”ûôê·…§X ÏÃLk4èªÙZCf-O¼ÊKÑéÒR¹WHO,]TîÊâLìˆÇbìä2a9HÁh²QyšVѺզl ,ïÀ@æ1ú*Jv¡ä8½.1[¶!ÖƒÅ<‡Žs¢±L«-æ™Õq;uÑ)Ê7Qö
-Åã@×sÝ.oÃd¾ ÖÁ8bß6;X’ä´‘sÝ0uç2Û‹ß½ìÓ{± :ùF<׉½‘±CÍHlžgMKlB ‹ÅgƒzijáÅÐLû¢¯¥[Ö­ÍÙF†1ÇC¾Ÿ
-^Êâ ÐxVö¤ÀÛ™à§Ì9Å{·
-`‚Œiƒéµ.ز”dÛA#ý‰ ‚{‚.ÓÇJÜ«i…%aV“¤l÷>‹Çfb
-Ù™òX”¯Kß©á6D¯
-ZÌâázz’‡³²ª´¯^ssÝ ¾Éß½|!‹§M…båÏã`:LiYÆO
-˜v÷!ôáTpS±>,pS0‡ÇÝ—îÌ);¤¼ñ(·õþ‰Í®\ewÅ Ç«Æ®:yûöéöÆ
-†Í“ ?½lf
-݃
-ËeKPñn¼hÉ{5Á„'<‰xÖæO6=ÙÚ´µÍò"0Cm©P†z.ž‡+ªã½<µ›8¦6´(ΧҙţVÏY°¹bsC$ Ù­LÈZßÄ%j]¢—(=Î:',¸}ñÆÔO☡ûÝ–£ñl˜2¤ó›rÕÍåÊ‚¬Ý9ycÑqRWè³·oáJù¥•™…¹.]—¢Q2ýBÃËâjkËöìåpÐÅF´h*Ç\Š®;†®=|ˆmäAÚm©Øê»Âë;:.}‚J8è+«)ZJˆA¿s˜’7!½›"$,„"úkZÆ{¬ô‹âôðƒŒyúGMp¢×¿ÁF+%}ýh<èüäPeô<W¿v}+‘—§’b¸`Ÿ‹â)¾0Ž »è-‡0 XFèXFv~óXäÅzEÆÍdçe„ÇeÄ…Úž¡¶ãÒ¶‘Ø39ásbëÿÉ6_ÃdlSÄ—Š4s»˜ì»ØÃΗMFX¥ÌëâsE{@£·w@€·wc@{{cc;Ñ_0.vÜC¹ SãñìÊŽ"6±‚L» KÐzv“=2úño“Ë ºÇò¸ 691â0tȺXš¹þ/ Y$^ÝBÂ&A|@ˆ~Ìé§Åz’!Û^5‘ÅSd"JÀat”…«yœÖ]‹ÓÄZiZ¢Xnšô’ŒqŠÒëC´£ÖFèPîIn›Ï£–Ñ9eBG§¸xCflÔª”¢` ¡¦û™”©‰É/J/d+òvçgñÐ b©¡g!¦1š~@m,£nûÑDSV¯V½F¸×|zlí˜ÎWï÷úÄ ¶Q“×®ó
-ã~ˆ™dôc§­Ú¸$ˆŠfîb§ß“ãåqo;/ªŠ™ûÖ=þ›&‚×¼î‘ I1x@.Ì€®ç] ! F¥õ[Eh‚±ñYÛã.543²¼L¯+çë´}”²{,Ý=B 2Ej½!šÅq½8þ×(¦ýŽâ’?¡XA‹éÝ÷¤LURA_ÊîCùÕ¼ø%]e0ì7rÌ
-£º?…‘û*0ÎÓ­ÿ¦¿ˆ"’*a`g¼l‘Ü‚Dx 3¥Ô¯×ád<bÌ,¬ÄÜON`Ý(äÞhæ¢h—” œo¼÷Æ…lÜÖÌŠ|‘ñpÉ1å¡Èý¾¾a~®'Waï܇|ûI±$lôŒ èËŸŸ¡;¿]¬vOÎ⊶¡•J2;wLz€\°%ÄÁ
-PNzŽgà÷&ÆCñ€‡ð>Ìþö9XsضP1 a
-3˜A@}{ ,;ÄÞs¤²“=rdg@_ˆVoPöäQ#\!é$ úIBBA%Þ$²½ L­Ci)ܪ¹£P4ãY!+=kØs‘ï.Á<უ/Q'ÛùÒ”¯­ºöÐóÚ ³WB38šuù‰I
-è3æ<‹ëžþ&dI¢FRQ;á‘f’ç)ȃ4ð ÿúòØqÐh.OÄ2t+ƒqhÞ|9bw†7Á¢É‚Z_WLXJ¶×šTMrêuÙ4ùG<ÊÉ}{\$×I3ùÔÛø÷ã» ÚÞe4ã¢h?šÜƸ_^×Oxø‚µ‹wy¢39u12ìQB
-æñðçÓ€ï<VÒÚA¤ìk_ó€Š8¤MˆæVlñPï`—.¿
-S¯ë³wÝX]ï]*ù“W?U>Ç}îã\÷
-ÊË? =_6¯Îæ †ô×vÞé13C‡b}¹â°€œ-ì<áÁ[*B+âùÖ€fÍ­]ò&Í—‰+”N“PÔð°›íI\Iz:ÚõÚ6Im¹™hw%ÇhkˤA§P[؛ʄ‚hq l °š‰g»†(°·,;dgí⣳ôùº¹§,
- n¤ÒûOÜbl^€ÌS€~óT´ŠÓž´kPDÈJt¥šƒ:°°=¸yÒz‡õcÆhå[I|÷ÉTßF}öÕ±ó7{ëpœ×ãZ>‡aÍ-6w€w~ C0Œáœd‹gƒgç®WÞ<ÿ@ykÞeR÷ŸóÑûÞõ¡ÍÇj_XS˜aàö7Í«gï?Ú–¨ÇƒGjøÍ:>]/OÖë’‰„ Ž+@åÓL•‘"l¬‡'=2lmÖ üÁüšš6%s†:T¿É' Ôã§ËAÁ1*
-\oþüw“!’ ÏÃðfTJ\pF¥Ž)#ÅR8ÑrÚ˜”v¥É5j'´“Å2¡åTû±ƒræÈî_+ù1ÚÒqé;+Ž'ìmh­:qʧ4!‹Û[×\ØÄ>èpuZèçºà{aibÒÅ(ãh&Mt6UÖ¯úªñi¯@!xÕ¤OT]zõ‰Ók}2æw}r÷OúÄ’Æc°d=©“æë`ð9Ž™,N#:°çɱțeڼǾќh<(,-°êRtZsâ@ÒñµQ½U šÓðü¬äþ03É×G?úçÜè™î.sµ5g8øñO-»hÕݨŸj?G·;¸9DªÿZ-Ž$µâI3ñ)wZ¬g'É#{ê´©éÒ“y,ÇFÌ@­ôŒ ôXFš¯Ð0¿ÛB^TŒŠÙ²ce³@”–ädå^a­ìÌk‹£»XA²×Î<ÒÌÎÜЃ›>4@·‘õ[ŠŒ[I®¯9ŽÔu<vêvà ÄÒ'DŽû9l|g#c
-só¢ »ûIãs_ÛV–Ë3ú—Pôýé&Œ‚—Rƹ8;+ï"ÛspþF'ê:ÂÔu}5HKãx³!¬°Ä`h45©Ôâ#u‚Œ(gŸõ&ÿà;·åò¤näõºtN‹‡àùCðHX'½×Óuó´‘eVl™Öƒé3Âñ%¼—§$étAÚ¡ŒV­aƒ{tô‘N¢°uË­žìIÇù¢Â
-—Þ“âf=G*’*ñ’™øõ áφ ÄÑIKŠsrï±=I;ÊSI‘.­ˆÏÐ ]FÆ Ç!c–¶-µ¸iþŒ&%á<;Hcã·¢ ¬'ý½ñ‘^t\lvB$KòOA}𠩯§ ,LâúWìÙ$^ “M*sú­ŸGìxãçH@IÊô$Lc=qòêròåÝÃ#7H7D¹~ÀîÒŒ©|~VuI£ò`ÄÞÀàX_aó¥[.ŸßÇAè%-É5šÜ¿kêÛS¤Ã`½¨5`mkו(v)ÚýÎ X™¾Ã“kôq3•€Vx¤îÇ;¼=U²6‚u |þuÎÔWÀÖÏi ïg•çeéõ9ÿ|΄o´)´ºÐe|nty7oFßÿ´ùïõUšŒB®·–y!|Ìž& ÑOà”™é t¡8žÆhôRìðLvÿoÍß×U¦'VsñšÐø-Jߺ°¦Ãu5m§6]Á}ð
-endstream
-endobj
-595 0 obj
-<< /Type /FontDescriptor /FontName /LGHSRJ+LMRoman10-Bold /Flags 4 /FontBBox [ -486 -295 1607 1133 ] /Ascent 1133 /CapHeight 686 /Descent -295 /ItalicAngle 0 /StemV 106 /XHeight 444 /FontFile3 597 0 R /CIDSet 596 0 R >>
-endobj
-598 0 obj
-<< /Filter /FlateDecode /Length 637 >>
-stream
-xÚ}”KÚ0…÷ùî‰Ydp^ö0BH<[ªy PÕ-ĆF'J‚_Ûç¤
- Ä—{ís|ì¸÷íkNT¹×aòÌÙZ7å¥Îu8{ßUA¯7/óËY›öCk¥UWm^ÙW]æݲþl5_™¢}²Í+“Ÿ.Jw]›¦úX˜{‹Óaý­þ¾}ÿ±Yÿ ßÞ×åyg"NË“
-¹³-Ú“íý_³5ö°Æü¿tÝ¥yeÑ3çÜ>X5+ÏnmM0 lÐ9>FÕd’íå Š™*ò–Èÿæg’¼¹6­>¯Ì¡ F#6XÛbÓÖWïø)|ÖJ×…9²þC‡¶cs©ª“vnÆc¦ôÁNl³ùØ5¸…¯”­íõq÷Ûk¥Yì9‚Ù¼Tº©v¹®w樃‘ €Ùhi?ã@õOcÔþ
-uADz4 é!ùtš£F„”(dPKÔìX†\2ÂI"x‰1guIã°Ú {+°ZI½ ;& '‰  3»9 Û :âñãˆDB³ÀKBzH"ÃŽ $!A’œAA’3¨KrFDI`ÿ$%AD§yÊ —Û™‘óûôL°–’\ÂïÂ×":)ö#:)SÐÒ¹ˆÝkå)ÍA4ã õo¤{™Ýt»9òK]ÛkÃ_\þvp÷Baôín«ÊÊò_)vW³£Ïeð$u‡X
-endstream
-endobj
-282 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /LGHSRJ+LMRoman10-Bold /DescendantFonts [ 599 0 R ] /ToUnicode 598 0 R >>
-endobj
-599 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /LGHSRJ+LMRoman10-Bold /FontDescriptor 595 0 R /W 594 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
-endobj
-600 0 obj
[ 28 [ 525 ] 32 [ 525 ] 35 [ 525 525 ] 38 [ 525 525 525 525 525 525 525 525 525 525 ] 49 [ 525 525 ] 52 [ 525 525 525 525 525 525 ] 59 [ 525 ] 61 [ 525 ] 63 [ 525 525 ] 66 [ 525 ] 68 [ 525 ] 70 [ 525 525 525 525 525 525 525 525 ] 79 [ 525 525 525 525 525 525 525 525 ] 88 [ 525 525 ] 91 [ 525 ] 93 [ 525 525 ] 96 [ 525 525 525 525 ] 102 [ 525 ] 104 [ 525 525 525 525 525 525 525 525 525 ] 114 [ 525 525 525 ] 118 [ 525 ] 121 [ 525 ] 246 [ 525 ] 272 [ 525 ] 338 [ 525 ] ]
endobj
-602 0 obj
+596 0 obj
<< /Filter /FlateDecode /Length 34 >>
stream
xÚc``à˜ý?ÿêê¿ÿ®}ú¿Ë0q”­
endstream
endobj
-603 0 obj
+597 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 6014 >>
stream
xÚ½YpW·^!ïÊ`Ç‹¥hÉ] ?¡‡@á½›Þ»‹ÜmÉ*–‹Ü$÷+¹÷Þ;`Ó[
@@ -2411,10 +2333,10 @@ J$¼f‘Ö—£yïFêóRù—›ø Goã_HcZf,”@õ ](Ðx‡Æ+Ór*†ìJSæG2òÈ…wËŽ—;?û¾‰Eïr+ɲFhÊbsMÅ9Õ’
K°^öæ¹5ùI˜S@㑸ïÇ{ ~ȼøãÕ«Ç`Wðz{5 ÖºtMcÅ÷þODZâ!‘è[º<¦B˜’–j
endstream
endobj
-601 0 obj
-<< /Type /FontDescriptor /FontName /WZILKB+LMMono9-Regular /Flags 4 /FontBBox [ -451 -318 734 1016 ] /Ascent 1016 /CapHeight 611 /Descent -318 /ItalicAngle 0 /StemV 175 /XHeight 431 /FontFile3 603 0 R /CIDSet 602 0 R >>
+595 0 obj
+<< /Type /FontDescriptor /FontName /WZILKB+LMMono9-Regular /Flags 4 /FontBBox [ -451 -318 734 1016 ] /Ascent 1016 /CapHeight 611 /Descent -318 /ItalicAngle 0 /StemV 175 /XHeight 431 /FontFile3 597 0 R /CIDSet 596 0 R >>
endobj
-604 0 obj
+598 0 obj
<< /Filter /FlateDecode /Length 672 >>
stream
xÚ}”_oÚ0Åßó)¼‡Jô!%‰c»T‰?AB+mUÐ6í-$†E'JÂß~¶Ï¥•*6¤¢þ¸¶ï9'νûö¶ §e½Ó!ˆØ»îês[èp¾Î›àînQç“6ý‹Ö¥.¯Õµu±Ñ=ÌW‹•©ú{»xeŠã¹Ô×U·Íô¡2ŸK\6Øê_áÏß«çï³ðy½®M=
@@ -2426,22 +2348,22 @@ xÚ}”_oÚ0Åßó)¼‡Jô!%‰c»T‰?AB+mUÐ6í-$†E'JÂß~¶Ï¥•*6¤¢þ¸¶ï9'νûö¶ §e½Ó!ˆØ»îês[èp
xHÐ]ÀC·ªu çŽ['ðÜd-¡S¡&¡SÀƒ„NE$i#I÷OSB‹"BžœN2Ný§ÀЩˆ SP¤+p—©&"p¤(Od¦(O"zÇ ¢çŽ¬—¨e¾Çèù}1=±,›àÝ÷ïºnÞ} ¥âܶv"ù¡è玛8•Ñs³©·Ëÿù{üŽ^—Á_Vïœí
endstream
endobj
-275 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /WZILKB+LMMono9-Regular /DescendantFonts [ 605 0 R ] /ToUnicode 604 0 R >>
+276 0 obj
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /WZILKB+LMMono9-Regular /DescendantFonts [ 599 0 R ] /ToUnicode 598 0 R >>
endobj
-605 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /WZILKB+LMMono9-Regular /FontDescriptor 601 0 R /W 600 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+599 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /WZILKB+LMMono9-Regular /FontDescriptor 595 0 R /W 594 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-606 0 obj
+600 0 obj
[ 35 [ 580 ] 47 [ 624 ] 50 [ 558 ] 55 [ 536 ] 72 [ 513 ] 77 [ 613 ] 81 [ 636 ] 84 [ 558 ] 96 [ 602 ] 98 [ 458 ] 112 [ 613 ] 116 [ 613 ] ]
endobj
-608 0 obj
+602 0 obj
<< /Filter /FlateDecode /Length 23 >>
stream
xÚc````Td`hñ`XÀÐ
endstream
endobj
-609 0 obj
+603 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 1806 >>
stream
xÚ}U}Pçßå¸Û$¬g“;Ø]‰ebŽ’˜ÔÖ/D b4aR‰‡·|Èqw섯Óûð¸½;îdîäøO‰L¬ÅViꘙª¥ÔÖi›f’tš¦ZÿHÞ%/ýØãh;I3ywçÙwžçýý~ÏǼ(‹ (šºÿµ’¢²W3ŠöÔשuyjƒñ;ٙ骭š‰8äóëø4VFð)ŸŠòD OŠx*¦ËD²Ø%¼š"þà‹yq*‚ c«#vú)'Kþ°¿ÈÖG6nɾHcIEÒ'¨ÅÑgPMÿ&蜬ììóô†f¦¦ªÚDådg¿°1b7S;³¨½êcµúFcm ¥Öi¨½YÔ¾,ªXß(ìÖPÏéuT]­ÖVRúJª”~j0ÒŒ‘ªbô ã†,ª´ºÆH5ê™ZJø2´–Vi Õ ÓÐ eª¦©=‡JJ©|½ÎDÕ£uFšÊ̤(#MSÕ&“á{*•©¡*KÏT©*£Ju2ª"q™ùû‹K3‹
@@ -2456,33 +2378,33 @@ $Áçà“›`<Hž2ˆMA9,ƒ1wí‚1·@™Ðl’ë3÷€¸ î'¢@Ÿ­:)¤‰[“Âwñqò¹í÷!FÀ _í7 ^€
Èdœð\Ðëõvuy½²„>cŠ-
endstream
endobj
-607 0 obj
-<< /Type /FontDescriptor /FontName /OWSLYP+LMRomanCaps10-Regular /Flags 4 /FontBBox [ -496 -290 1501 1100 ] /Ascent 1100 /CapHeight 683 /Descent -290 /ItalicAngle 0 /StemV 106 /XHeight 514 /FontFile3 609 0 R /CIDSet 608 0 R >>
+601 0 obj
+<< /Type /FontDescriptor /FontName /OWSLYP+LMRomanCaps10-Regular /Flags 4 /FontBBox [ -496 -290 1501 1100 ] /Ascent 1100 /CapHeight 683 /Descent -290 /ItalicAngle 0 /StemV 106 /XHeight 514 /FontFile3 603 0 R /CIDSet 602 0 R >>
endobj
-610 0 obj
+604 0 obj
<< /Filter /FlateDecode /Length 422 >>
stream
xÚ’Ëjƒ@†÷ó§‹@º°Ž&¥¡5 mbèeifNÒ8#£.òö‹¦PJ¨ øyþsûÑÕº¸Úa0¹¡°ÁFuša½”5ŠuÊö‘#¢Í=¬µb¶0ÎòE.E{mĹdÇŽã ú[ôˆ!$¶Œ·ø¬Þ‹çÏuðü²QU)³²n"lðÐKP›ºíѤüC F—$à
¾¡n„’÷ÝPJ͇'É3UÙ…öCC8¬±’ë~rØÙ=H¬íÉ=Yeœ³ÉÅ©i±Êå^‘ùBÓY4­>¹ù¯I¸Òµ_Ô‹®®h‡JÒ8îM}ãÛkY!„Öœ›¨hOmùIÜžj„ØqäGgŠcS— u)HæÆšÂ|i®” ä¿âÔgíö`x5†ô!öUj[(ž˜B”ÎâÔÑÒÓÔÑ$ötë)ñ4s4½ó”yZxzrtyZzš:J¨£õäûÍ|‡dâ(éc¾CÒçÝ¥~7±]ÖþÁ³Á¬ÓÚ¸ë~³sÏú&$žOB­j›ånw„†Ómiµ$ß±I
endstream
endobj
-274 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /OWSLYP+LMRomanCaps10-Regular /DescendantFonts [ 611 0 R ] /ToUnicode 610 0 R >>
+275 0 obj
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /OWSLYP+LMRomanCaps10-Regular /DescendantFonts [ 605 0 R ] /ToUnicode 604 0 R >>
endobj
-611 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /OWSLYP+LMRomanCaps10-Regular /FontDescriptor 607 0 R /W 606 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+605 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /OWSLYP+LMRomanCaps10-Regular /FontDescriptor 601 0 R /W 600 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-612 0 obj
+606 0 obj
[ 28 [ 500 ] 43 [ 444 ] 50 [ 444 ] 52 [ 778 ] 72 [ 278 ] 96 [ 392 ] 109 [ 556 ] 112 [ 528 ] 251 [ 444 ] ]
endobj
-614 0 obj
+608 0 obj
<< /Filter /FlateDecode /Length 24 >>
stream
xÚc``à`Ð``h

endstream
endobj
-615 0 obj
+609 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 1371 >>
stream
xÚµTmLSg¾-ÜZµvÒ»ñEÞ«C"J ¢ÄÈ¢AP"ÔÍáG¡¨ôúÁ‡+RÊ•Û–
@@ -2494,10 +2416,10 @@ xÚµTmLSg¾-ÜZµvÒ»ñEÞ«C"J ¢ÄÈ¢AP"ÔÍáG¡¨ôúÁ‡+RÊ•Û–
…õ»á1)çD(.øcà𲞚F(]èG‘“H9){¸ ømÅ‚‚¸·0€~‘¸k˜:°ø\TWÃTÓ°šîgz
endstream
endobj
-613 0 obj
-<< /Type /FontDescriptor /FontName /UHLNIO+LMRomanSlant10-Regular /Flags 4 /FontBBox [ -457 -290 1446 1127 ] /Ascent 1127 /CapHeight 683 /Descent -290 /ItalicAngle -10 /StemV 93 /XHeight 431 /FontFile3 615 0 R /CIDSet 614 0 R >>
+607 0 obj
+<< /Type /FontDescriptor /FontName /UHLNIO+LMRomanSlant10-Regular /Flags 4 /FontBBox [ -457 -290 1446 1127 ] /Ascent 1127 /CapHeight 683 /Descent -290 /ItalicAngle -10 /StemV 93 /XHeight 431 /FontFile3 609 0 R /CIDSet 608 0 R >>
endobj
-616 0 obj
+610 0 obj
<< /Filter /FlateDecode /Length 412 >>
stream
xÚ’]KÃ0†ïó+ŽƒyQ›v:?ít“uŠ·]r6mRÒôbÿÞ|¬
@@ -2505,22 +2427,22 @@ xÚ’]KÃ0†ïó+ŽƒyQ›v:?ít“uŠ·]r6mRÒôbÿÞ|¬
\0s$ÿe5Ï%—‡Î`SÈ"³Ķ²èŒ>ø ÎI¼Òµ{ŸìÔ*˾mkt]%Yw¶€õnY5±3¤à6*Ìá´3?™›C‹zNBóLqìÚŠ¡®äÉÌB3˜-ì“”üWœ†¬í.  ËÛ!Â>+íöIr»¥Ó$s”>šxš¤®]zšÌ=]Þ„XîiJ=]§æBÞõ16õ´o³Ð–ïÃMàæÛ6Ökm=ó§ç-qf‰ßܪÖeù×ߌáÞ:Z-ÈÄgÿî
endstream
endobj
-258 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /UHLNIO+LMRomanSlant10-Regular /DescendantFonts [ 617 0 R ] /ToUnicode 616 0 R >>
+259 0 obj
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /UHLNIO+LMRomanSlant10-Regular /DescendantFonts [ 611 0 R ] /ToUnicode 610 0 R >>
endobj
-617 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /UHLNIO+LMRomanSlant10-Regular /FontDescriptor 613 0 R /W 612 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+611 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /UHLNIO+LMRomanSlant10-Regular /FontDescriptor 607 0 R /W 606 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-618 0 obj
+612 0 obj
[ 27 [ 743 511 ] 35 [ 460 ] 43 [ 460 ] 46 [ 755 511 ] 49 [ 678 460 ] 55 [ 307 ] 59 [ 460 ] 63 [ 511 358 ] 66 [ 307 ] 68 [ 307 ] 72 [ 256 ] 74 [ 897 818 ] 77 [ 562 511 ] 81 [ 511 511 678 511 ] 91 [ 460 ] 95 [ 729 422 562 409 ] 105 [ 332 ] 107 [ 511 ] 109 [ 537 ] 111 [ 743 460 ] 116 [ 464 ] 118 [ 486 ] 121 [ 511 ] 125 [ 562 ] 168 [ 511 ] 251 [ 460 ] 257 [ 460 ] 277 [ 460 ] 502 [ 307 ] ]
endobj
-620 0 obj
+614 0 obj
<< /Filter /FlateDecode /Length 38 >>
stream
xÚc``N\±­BðAh— 40À€€ nÀ
endstream
endobj
-621 0 obj
+615 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 4997 >>
stream
xÚÅY XSgº>1žˆJ±ÓÊ9ã9q©b­h­£Uë´.TÅ*U´¸]d $aÉFöüÙCvˆìÙ\P[k][µíغt¦½¶NgÚéü‡9ܹ÷
@@ -2543,21 +2465,81 @@ wnm«Ù¹{ÿþLâŠ&¶:Þsà?äq­ %O•æf’²$ÅV€ÍâwW«ªð T5ÿeújÒ™õFLå.ªñUºª]D\z
?‡ˆÚ‘±(x"žìŸtz²ßƘ+槻Òî îªdž»¬eG5Uüåž6ô÷
endstream
endobj
-619 0 obj
-<< /Type /FontDescriptor /FontName /BZJCMG+LMRoman10-Italic /Flags 4 /FontBBox [ -458 -290 1386 1125 ] /Ascent 1125 /CapHeight 683 /Descent -290 /ItalicAngle -15 /StemV 102 /XHeight 431 /FontFile3 621 0 R /CIDSet 620 0 R >>
+613 0 obj
+<< /Type /FontDescriptor /FontName /BZJCMG+LMRoman10-Italic /Flags 4 /FontBBox [ -458 -290 1386 1125 ] /Ascent 1125 /CapHeight 683 /Descent -290 /ItalicAngle -15 /StemV 102 /XHeight 431 /FontFile3 615 0 R /CIDSet 614 0 R >>
endobj
-622 0 obj
+616 0 obj
<< /Filter /FlateDecode /Length 552 >>
stream
xÚ}”]š@…ïùÓ ÷‚uÖ!Q„†¦înÔ4Mï-‰ ðÂß™9ƒ›4µ&Þ¯3'ó2ùò±wW¼9
צd'úæÚ•ÂM¶EëL&›¦¼ÖBoBpÁÇhÿJ>º¦Ü‹L“|“ËjxRɹ,/W.Ƭ'­Å¹’Ÿ)z™ÄOwýë[²ýê~ßŒºùP\ªÒ¥ºêP •ýÿD¢¢äA”˜6?D×W|%ì™Rª¤’'M­OØ;3«’ÌFݧJòÎJ%G-ÜaáU9X2¿e­¬ÒÅû[?ˆ:—§ÆY.Él§‚ýÐÝŒê'göÞqÑUòL¦4ªœýµm/Bë!Ô‰cÂÅIµV½µ 3}üœ«h5ÜùðYs¸µ‚x†— }[”¢+äY8KeÉ2SŸØ’ÿ§¨:ž€*aü;÷ÆPù»èt#¶V(³ØPb(y>È!3ôA)êæ  1Ï @b–"P²=#íòbhN yí²
endstream
endobj
-249 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /BZJCMG+LMRoman10-Italic /DescendantFonts [ 623 0 R ] /ToUnicode 622 0 R >>
+245 0 obj
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /BZJCMG+LMRoman10-Italic /DescendantFonts [ 617 0 R ] /ToUnicode 616 0 R >>
+endobj
+617 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /BZJCMG+LMRoman10-Italic /FontDescriptor 613 0 R /W 612 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+endobj
+618 0 obj
+[ 27 [ 869 559 ] 34 [ 818 639 575 ] 38 [ 575 575 ] 42 [ 831 511 ] 46 [ 882 639 ] 49 [ 756 527 575 ] 54 [ 724 351 575 575 904 575 ] 63 [ 639 383 436 319 ] 71 [ 692 319 ] 74 [ 1092 958 900 639 575 ] 81 [ 575 575 786 639 ] 88 [ 319 ] 91 [ 607 ] 95 [ 863 474 639 454 ] 100 [ 575 575 ] 104 [ 800 447 575 575 885 639 ] 112 [ 607 1189 831 869 607 ] 118 [ 607 ] 122 [ 671 ] 168 [ 559 ] 251 [ 527 ] 319 [ 639 639 ] 499 [ 571 571 ] 502 [ 319 ] ]
+endobj
+620 0 obj
+<< /Filter /FlateDecode /Length 39 >>
+stream
+xÚc``°6.þøp_ÅÄ7~)0€@ @iF„2
+endstream
+endobj
+621 0 obj
+<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 6436 >>
+stream
+xÚµy XG·v0Ó£²(Í Nc÷¸B\b4£ãŽ"*( (Š²ï" ËÀÌÔ0움,‚"(È"J‹Æݘ¯&&Ñ«Ñã—Ä%1æ3§±¸÷ÿk@Mü¾Ü{Ÿï¹Ïz «ºêÔ[ç¼ç=ÕÊÜœ’H$vK-_6×}Ââ%+Cwø…¼åâäº=ÀÔâ.ªÄÈ‚í)q¸Däú‰¼™hkŽ,Ì.Z˜÷$àãö2w{óÒá%AÖäÚÏf°ˆ,F’¿øf‹Ñ¦,ÆPt?JBÙQ,õÉ°2‰Õ_N9y’‹ËÔy¡añ[·E©&»¸L™hºÎP¹MR-òÛ¼Uå Z4Iµd’jih,¹»U564Dåä·}³*t³jU —*:20"Rµ%"4:,rÜ$Õª ­‘ªØЈ`ùŽÜè Š ŒPEªÜW{¬R- ‰R-Þº)0$2Påä¤REª‚¢¢Âf:;GEo™±Åy3éé¼½¯S¤³é9§Ë–®rZüÁ¼ùK=æOŠŠ‹RmPFùmÝ9é;þon@¨à!Q[£â)òa){j$5ŠM9PŽÔxj5‰r¦Þ¢&SS¨·©éÔ;Ô j&õ.5‡r¥æRn”;µZD}H-¦–PK©ÔJʃZEyQë©”/åGùST Dm¥¶QÁÔvjF…ST$EÅP T=…%s$®’ß$—ünF¶‡|\)WÓF™S¡H¶K¾ë7¬ß!3W³3æÍ3̱tƒôªÌCÖL¤÷ÑÏåyýûßêÿtÀ„±:<˜e¡°¸`9²Òòw«w­J­ÇY`}pÐêA­ƒ×› `2ù¶3l)*Ê¿Ûå ™=´ßФ¡Ï‡å)g+¿d·°/ì·ÙÿûðapЪ» à ˆb%Ýÿf'Œ§qA·TZ§NF lhfZ|: =?K5Ú´9lŒ· ú¥­g‘ö0/Ðh2*QfŸ
+à{ tÙžòŠ²=rærZ~×êïY÷ìð<¶µóF«Â8ÿu0;?àôî²é¦}ÇëÏ°`…°å|ÞJü¢;5V"æáPE®ÞQÂõX¾˜ -OÏ(‰awíTÇj úœ$^´üÏ ÒÄÜÜÄ*¶´¬¨Òô66‹+M?H3ÛoÅtœ¨(ÉÈN6pÓs67%7˵…(¿\ )´þHðÉi5r؈®SÂfºÕ·ÖsEyõ奆|T®¬HEÑxä[kßÓsØŸ^‚b¶…pQ1A»üuò]ú4” LÊÉ,Ös2š7l‘g¥!Ýf%ÞLc[˜©¾R]€*¸¿´ Œ/múи¦.áŒ\›²ZM&€5žX6#&Å÷ |;³}[q€Ü˜‚Ò”8…6ø5¬ý.RŽ#wÓLQ(|s—’¾=vµö¥Iñ…¨
+Æß9}ÝÀ?}•jàŠŠVŸzµ(«î/Ô‚øB|
+N¢¶Ë¬;b•é†„¤T”@ªLÇ–KØÙÓ÷~¼†÷>—üÕåY#PŸ|Æ}vù»¢X ÎÁL5g4èjØ:CVO¼*ˆOÕéÒÓ¸–KO,YXáÎâ,ì„Ça?ìä²`HÁh²Qùš6Ѻͦl .…ÁoÁ`æG1ú+Jw¡”x½.)ƒ[¾>΋Å<Çγì@ÑT®Õ–ð̪øº˜Tå«(»‡å¹+8¦
+»ÏÅ4–ãa?M„IðöçñV/dH¿ï{q8šuŸ‡
+ÃãA×q=n¯Ãdž ÖÂxbß6;X’ì¼s_?eçR;ˆßƒƒì³;qó»ø&¯|÷I}‘±CÍHlÞgLKB ‹Ä'v½$µòâßi¦ãOQ×Эk×än#Ãœ‚Gà¡?L„±ß[ÛÀ¯£W˜3ûâ“üWÍa±ËkÇÑéºVþH½PØÀžk ©æ­ºµ„š(lÈŠFÂ4…Dyѽö)¼e˜‹Œ—°x"4‘=*ôË pÈ[67Õw<·
+
+a¢Œi‡iunزŒdÛA#ý‰ ‚;‚nÓÏJÜ«iƒÅaf³¤l÷>‹‡fb*Ù™Š8”‘ ËØ©áÖǬ ^Äâzv’‡3²êB´¯As}í ¾y³gÅO:ÆÊ_ÆÃ4˜Üñ¼œŸJN“eµŽT”·Õµ׳Ð?  2˜ÂVÝέ¢²UrüÞå{à|ÏL¬e
+ ¦ ëösךŽžWþêr Ë0?Ö„‹onä¦oÞ¸r®[å
+˜zû>ôãTp]±.|ëÆ¿+ÝYZ~HyíA^ÛÝþî\UÏ@Åt§+Ç­<yóæ©Ž¦J†Ï‘8³žlfÁµF€ê^O Î ̺§‹*Lõüú
+#’'ž¢£lHö(/`jNÐ
+^ãœFp^ Õ ’Á´š÷pÿݼüFÆ~&@!€þ@}Öfâb·âÈ–c³ÇaÊK9Wï¯ð³Þ4Ø¥-Ÿ"m3/L…g@ Øò) ý¾.¨ÍÉAº<.Q§ômŠ«;ÐXÕÎõB÷1ØÃèæ0¨1Öæ(@ù=ŒdŽ‹¥à£
+òõm
+êèhjê úëOfÀEÂCz)wAZžŒÝÙÑÄ&Vi7b ZÇnt@Æ@þur¹F÷šB7Á&'F†NY7K3Wÿ $k‚Ä‹HØ(ˆ÷Ñ=uà”Ø@2dû‹f²xŠLD 8œŽV£5Ó{êpºX'­U«Q4‹#L“^”1®Ñz}¨–cÔÚH
+e#¼É-cË9ÔÊ2Ú#™Ð"hÆ+>Áχõ†j¥(h¨íy"ejc Š3ŠØÊüÝÙ<4ŠXjè]ˆiŒæQ;˨Û2єՋ•/îó¿¾_[{¦ëÅ»}>ñÌ«}´Ëšµ>áܱÎÆ@vêÊ ‹ƒy hæ6vý#9^ú'÷ø®ëÒ¡êØ÷^»ÇÓDðÚ‹×r!©‘ ÷È…Ôý´›!$Á¨´+ M06~kzÝ¥–fFU”ëu|½Ö VöŒ£{FŠARÆ«X­7Ä°8¾ÇÿÅô?P\üŠ•´˜ÑsGÊT'ôeì>TPË_ÑÕÃ~#Ç 2îÍBûÙÞHúp¦0ª#Œ<Wz…s&˜nü÷0ýE‘¬Pƒ»šáy«ä &Âk¸)¥~£¸‚ §à‘cgb%æ~vë&!ïZ M»¥.OÜÊ$ønXÀÆoɪÜÁ—SŠÚè~r%˜öÖ](àððŸ‹ÃÇLŸˆ¾úå ºõû…Ï”l®xZ±UIf'âŽéU¶„ø!DJç§x:~Çe †Ýw„waÖwOÁšÃ¶EŠ©S˜Á ê»cèdù!îðž#U]ì‘#;ƒªùª­hÕzeo>5§$$Ã@"IH(¨ÄëD¶†«u(=•[ùÞhÃÆzWÊÊÎö\à{J1OøàèsÔÅv=7åk«î}ôüvèêS„ÐNfÝb²úýÏäz¦½
+Y’èŸTÔAx¤…äy
+òa> <È¿€þ<v²{½‡'± ]ÀÊ`<š3ÏDŽØS€Íph²à¶—–’íµ&U“œzY6¹ü„G»znâºh¦€zÿ|áí]J3nê Ž£)í,Œÿõeý„GÌ_³h—7:½S— Ã%ÑÌõƒ¡´”koû(·š½rv)¶ée?p‘Ü3H¹ùŒ&þÖg¯8¨MòR¿š‰O°§BX þäO{Î’vyXFôêèɘÇ#žN¾ëXi['‘²/}Í î)â‘61†[¾ÉK½ƒ]²ì< ƒ‘_
+¿>>k-Ä$~š¡¡W°Ú#°ÿ•ˆìá'l¿e~ìþù¡¢šÈý}J’žóΉÞÁ.KýüH¯+J»ªÏÙumUƒo™äN^þLù÷»‹—s=ƒHþþz“šŸ #ì‘'½Š‰lRô§K¢­ |cŠsS~€Ö]ÛÊE½”ÙÎþ^ò ŒÇ‚8NáÞÁ38,'Ý–5{)¡!¯Âñ9P¬v‚3V\*š+N­®_3ÓÚÅQHiæ:žùOÁø‡d›G_««_8—¢ôoŒ­¯o¬j#©ƒ!âÅ·C¤;$Ÿ>†«ÍÄω¶³™·]öpxLƒtSÇ¡•û/ýrëéVl_ÃEf#]»åÔðða¯.IÓëSÔ܆Ò΋
+Ö…?oÂÈE}ª¢ù®u‡ÒAy?®\[#ßXî£\¾`Ô<±Æ¥qz”ÍF"Mu”ZQ••—ÏuvJ×}ö£†øÖŒK }J0X§i nÙF›–Ï!ùs&Nœ*EGlSÐ~. >8wv‰|sÞ¢"AyéG´ç«–U9\¢ÁñÒÎ[½ffêP\
+P9\Ç–³0ÚÍñã÷Ð «êÈÛÍ {O7Ì2'+i£jø-ña;”[kB[[÷Öµ\òûd¶Ç3¦áœYï¶/àæ_G^cô (ylŸ¥p@sÖ„µ–¥q;Ñõ
+% >-œyˆ\‰µ¼)HŽNHQ :q"ÆTÃM“Å` Y5H
+oÃhöFÏMìDÂã4QŸØ äª=MÄI¼ù5 £
+ßŲB¨©ôþŸ
+ã[¿€á-­6·€w~# G0œá\ d gBîgç®V]?wOycÎ%RœýỾ a-ÇjŸ_]”iàö7Ío`ï?Ü–¤ÇCFixNŸ¡—§èu)DÂRÇ¢
+Ži¡ŽÊH6Î˾&ûÀzþ`Amm»’9M nØèæõÖãe àî×ù›ÉƒI†ç`D‹@*%.8#ŒVÇ”“b)‚h9mlꇻÒåµ+ÚÉbG™ÐúQDZƒræÈî~*<T=êKb´¥Ó’·–OÜÛØV}â#¿²Älno}KQ3{¯ÓÝuA ûü÷yìƒý¤IÉH«Œ§™tq®©²~Ñ_-ˆû
+ÙÀË&}¢ê¾×§O\_ꓱè“ÛoèKÅ’u¤Nš§ƒ!g9ÆEœJt`ï“ã/Ë´ûŽ{¥9'ÒxPX›`å·¤è´æÄÁ¤ãK¢z­@4§àéÉ+ýaf’/.(øÏyÐ3¼<ÝÞÓÖžæà§7ZvѪÛÑ?×}nvr³‰Tÿ­<F#HêÄ“fâ Rî´."DÁºÉ#{êµié2Rx,ÇFÌ@ô´ ôXFš?¥a^…4¢¸•°å…ƪBf‚(-ÍÍÎû”µ²7¯+‰éfÉ^{ó(3{sC/nú° Ý6p 2n!¹¾ö8R×óصÇÏ7H9èD° ˜…ŒA¼÷=ºÝ~ÿ/!ý?$Ò¹Ù)µlmvaY.n¢'¸õx¾ys§øSn¹!«Á8,«²
+•¿è]´M-$â¹0׶€m¶„¹ÌüîÎ>¢vè#Ù &
+ºôj­V£×ò#q–ÁAéY‚L+õóË2ìä½/ÐUk‘)3M}¸Yx•”Y8Š¤Œ¯©ŸµKL£0×/ÈÀ©g€4!ï¥måy<£ÅÏqñ7a4<—2sKr²ó/°½ç¯tò¡î#L}÷×vÂ8çÂ3˜áE¥C“q˜I¥æ©dD9û­3ù× €÷úP®hEê&^¯ËÐè´x(ž7‚µÒ;½]ý'¢ ,³|ÓÔ^LŸÐ/â ¸"5Y§ Öc´ºØ},Ò«£t…Ũ[oôfO:>
+¿û½º¹M ‚„ÏMœ#Wçjò¹|YnNvNßxçÔWW.ÈYYÙÙJìi÷¿ÃJü7x .à+¹ ®·À•Ô5âLE[X‹WtlZâN’Ñͯ©.—g³yÊBuaÚ.,y«ö8ßÙ@Jȱûz“ùDI x’"ê›—ó剟)®n>»Âg{ï¦}'«+ów—ql>Ut‚<S›©MW¦¥ä—‚ä[P™æûz“‚íÕ|·M“åþk“Y™^ÈY ‡áE½mzÃ~ÖF]$./€ U…E2nѪíÎý‘Å@a
+endstream
+endobj
+619 0 obj
+<< /Type /FontDescriptor /FontName /MJPOAG+LMRoman10-Bold /Flags 4 /FontBBox [ -486 -295 1607 1133 ] /Ascent 1133 /CapHeight 686 /Descent -295 /ItalicAngle 0 /StemV 106 /XHeight 444 /FontFile3 621 0 R /CIDSet 620 0 R >>
+endobj
+622 0 obj
+<< /Filter /FlateDecode /Length 632 >>
+stream
+xÚ}”KÚ0…÷ùî‰Ydp^ö0BH<+ª2 @U·›i$p¢$,ø÷µ}n©B‰÷ÚçøøÑû¶Ý‡Užt˜¼r¶ÓMy«sÎÖÇ*èõæe~»jÓ~h­´êªÍ;ÛÖe¾×-ëÏVó•)ÚÛ¼2ùå¦t×õ¼iª? óÕâtXÿ ‡ëÛÍä{øs½+¯GñpZ^TÈݘCÑ^lïÿÚ˜­±§5æ§ø¥ë¦(Í;‹^9çö‡…Q³òêÖÖòÇãsaTM&ÙÉY¢˜©"o‰üÿüjCrƒ÷÷¦Õו9—ÁhÄ;[lÚúM­t]˜OÖêÐvìoUuÑÎ ãÁxÌ”>Û‰m6Ç«f·ð•²Õ¢½?OàkÄá^i{Ž`6/•nªc®ë£ùÔÁÈÀÇl´´ã@õOcÔé ´ ÝW‘t¥üϱvES;çi4ö4ó$@qŒZ JP#J=e3ð$§ šƒ&˜%AO-PKAKÔ@I„Z‚A/Éê©
+uADz4 é!ùtš£F„”(dPKÔìX†\2ÂI"x‰1guIã°Ú {+°ZI½ ;& '‰  3»9 Û :âñãˆDB³ÀKBzH"ÃŽ $!A’œAA’3¨KrFDI`ÿ$%AD§yÊ —Ç™™Àù¹-áná»#:Ò#:SÐÒiÆîyJAs
+£/YUVn”ÿø'°{ˆm–Á_‚uƒ‡
+endstream
+endobj
+244 0 obj
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /MJPOAG+LMRoman10-Bold /DescendantFonts [ 623 0 R ] /ToUnicode 622 0 R >>
endobj
623 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /BZJCMG+LMRoman10-Italic /FontDescriptor 619 0 R /W 618 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /MJPOAG+LMRoman10-Bold /FontDescriptor 619 0 R /W 618 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
624 0 obj
[ 89 [ 1161 ] ]
@@ -3337,51 +3319,42 @@ endobj
<< /Type /Font /Subtype /CIDFontType0 /BaseFont /CKBVSC+LMMono12-Regular /FontDescriptor 723 0 R /W 722 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
728 0 obj
-[ 28 [ 490 ] 54 [ 639 ] 57 [ 490 ] 59 [ 490 ] 66 [ 272 ] 75 [ 816 ] 77 [ 544 ] 83 [ 666 ] 88 [ 272 ] 96 [ 381 ] 98 [ 386 ] 105 [ 381 490 490 ] 118 [ 517 ] 121 [ 490 ] 187 [ 489 ] ]
+[ 28 [ 490 ] 54 [ 639 ] 57 [ 490 ] 59 [ 490 ] 66 [ 272 ] 72 [ 272 ] 77 [ 544 ] 82 [ 490 666 ] 88 [ 272 ] 96 [ 381 ] 105 [ 381 ] 107 [ 490 ] 112 [ 517 ] 118 [ 517 ] 121 [ 490 ] 187 [ 489 ] ]
endobj
730 0 obj
<< /Filter /FlateDecode /Length 27 >>
stream
xÚc``à```
-PhXPÀäÀ
+Ph1hhhr`€
endstream
endobj
731 0 obj
-<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 2455 >>
-stream
-xÚ­V}TWŸ’I+¦6cÚ:CgÆëV-jÕZ»¢ R©"¶­È$5!HÈGI !!‡PĶZ±ŠŠm-UÛZq±zÜj©ì¡®§u÷M;œÝê9îžÝí_»ï¼ófÎ{ßýͽ÷wÏå!ÁÁÇ›•—¸vAüÆDUNªrᢰD™\—ªžú¸Ž™Í<BH&ažå1dCñ:˜ á<ù
-Û*PÿÂ
-žE^ãSçù'á¦ç¸·ÇûCæL >
-y!<dB"? 㡼é< ÿ-·‹Â##_ŠQåª3å
--½(2rñ‹Sçr::œŽKÝ¥Òk²2éTe:No §TzNšI¿ RÒi2Ejv­Ê “dÛhF¦ÖÐrµJ—«™N')25´^¥Î¢¹§Z–-KÕÈÒi2]¦¦µ
-»uK½N¥ÔÒñ™»eJŒ £iLF+´ÚÜW""´:y¸J-Èàt4Ù•4Svaë^OH
-‹_³6aËÚpm–ÎP©ét™653[þ?ùH Rç¤f¯NW¥É֧˔ÚLm!­Pd)²YD#Èd’‚¤!™È$ ÉG
-‘|. Ü’ ’©Ð#•ËÛääoã_Ž V#(\ ï¡VO4Äþ]\x'p·Þ¸®—þ¦ x±fFyGzV·MÔ˜ 2pÚIÂtôï:Bv)v:vËã·Æ)݆_S“ï¨SﵜpõÇÏËR»Qöíò¨e+qlÕ«ß«?ùüXÿ 7‰µï¨ê”¿Ox†×)vÙ)é¼è=)Éi½'à3på¡^)¶€
-Ü…”©®ÄíÁ›jšêdö‡ý žøîâ¥k~s_VÕäCPMTUk…-Ye²”™Œ¸¡n_£ÝUí%Ù•l´¤å’Ê‚S>±Üoq£M~*àî¨óØãm0WKAdòq馨 ¢ÎÙmGúÚH‡÷ ø‚¸ à%J<‰‚
-(û!:!¹=uk…ûŸ
- q–ê#ŒbçØP£@‰~vp2Ŷ¢; ŽT¢¶ö @Ôëa
-{f s_Ú¡qkTùºÜ<¯®­Ãíó‘b¸šKPwàw¹"Ãp÷Ôž)Ænþ|˜sð–tTP0½ Úµ]ä厚LâåÔ×Ó÷R× [½ñÄ|ÙËz3Uñ£»÷Â%{)Á÷BÛ —ÊÀ °¶QtÃ>pŒ‚ èƒËg?ýÔ±-d÷ýOŠâþ<v…qýîbøÿa·pÞóÁaŽNÏŽ¿ —Ýå3)“NÌ¿Í$ûÝ#:µÿ npy鸬¾Gõ ËàïQøØ_GïSáO¥VÈ.#Y
-¶>$Ô¸.¬ å×R˜à};Á‡ñR¿Ö£VêµêœÖ‚¿×ÓNŠY'‡æb¿k* ?]°Œvb3á_LÚ‘Ûž²TQ°Ÿ¬€|!`ñÿ€ö3Íý_þÊ;+Õ ±¸hk=Çõ…èDÿØ5» TT‘fËÞý¹¸²ÅØØÜÜàç|ÖÕçÃE.ètñºÁÂc|ø
-ôTõྂ†Bså›”²w3NŸ=:p¡‚«™•‚‹þ+Ý„äÿ­çö>—¤+Ò›eßÈGÈ›i1ÞdbóåË”*Þ´‘EðùµÑ½kȨ#—5§ˆoOž
-P½Wm? áQ‡¤¯(#ׂ
-â DVœ ò
-(ãÇ`ä üøºñ<y±é£Î÷‰¾!í7Õ^ÅÅlø¹|&Z/ª“r/6ƒYI›õU{’o´iëu}– õÙ½Ž–zQ‡ó|“?dvî5 f#©ÈËTÉ5",eÐ1t¯·4å– $6#ɱy+.÷e¶+ÚDv£Áa öš‹÷é›-%Ôé¼£×à3ϲ¢³Î 5ŠrŠ7åâûìŇÃ^Oö´nïå²íÙjØœ„«Š<®Z‡ƒ»öŒahïÕVõä‰Ìõƒƒh´;Q⩉tC„ÌåæJdÅÔŒù±$ßÃÄ8¡ªÎî’qIÙ!iLJ§¹+mkª*mýίßa«©>`³UÕT…LgÞ™ùóÓÒ
+<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 2282 >>
+stream
+xÚuV TWž’ÁŠ©fŒ[3:3v­ÇGyø® Ö"UÄúX_ ! a‚yPRƒ@¸D!’ Š â£*VQq[¤J­V[Û®ìÒžn·»wt8»;Ñ=nÏÙî=sî̹óßï»÷ÿ¿ïœ_€„†"`üÚ¸ÄÕ+g$¬IRg§Ð3gE$)”zUŠ&øs9;‰}„ì„(`‰–²T(.<:¼k Ò<çDDPÿzp¾1® “ÿQ>9¸ðqø[HX"@Æ#ò=òO*%
+äÿvVdtôœ8uN¾&S™¡£fEGÏ~;8/ b#©ø”]Yjƒ6+“J¡Ó¨øHjM$•¨6ð«™ÔT5M¥*2RTé”:JVl¢ôZ…FK)5j}ŽvZ$•œ‘©¥ jMÅ¿5
+•"E«H£ôtšBCé2ÔŠ ë“©åjZG%dîRÐZAQZ…‚ÊÐérFEéôÊHµF•ÎÇh£T/ƒ´QÁ}ËßOLŽHX÷^âú÷"uy:*]­¡Òº”L•6ò.ùj!Q­ÉNQ½›¦NU¬JSкL]> È<d²‰EV"k$d=² Ù‰d"YH’‹ä#…|Bù!E¤ÁÔ†"å'XR2 Ü&ô„Ž
+õ†þU´KÔ'Î?AÜ¿$Å̇¹ð ³ùáƒôø˜ÚÛïÆšXúÙ5ýz4Ik1*À•:Æ¡] cÇ)âXÆvÇ|A†xÚiôx¼§• €<ã¹ØØŸ¿¡˜IîB¹m¥1ó—ȱ¥‹ÿ¤ùä³:.: ,°µâ¨ò,îêv< ¹ù—eÓbwïÜ’Ú~¾—Ô¶ÛI `à¥à#€¾‚Én8Ù=ö1;Èn—íZÑ°ŸnqÐœNûÐôRsa Å6ï7 o{¬ Éd£s¬µí$´=A«wÏ'Ý°^/žoÞĂÕâV[Õ9ŽÃÉÌÜ$)áÙ†ÕðâgB6.’1SØߣNPi´”‚B Áu +E4¬FÓ­æØtžÀ€ÕC24®´úùºŠ‘q%bXÂŽI¸Üpõ.hsIý}0®tš;•ØØ¥¬š.k426¦e OvÆ>såŠ%IméÕûIìϦ‚|:M¾®Mc/&¶}¸M¹Q¾|0 ¾Gþpå^sÑ÷¾M›Á\<±8óIsõ~§KÞp¨¡ÚA¨.t€üÛ[·ïû-'³Ž‘§.€J¼¢X+HlîRsI±Ù$7VÖÛ+Ý·„ ‘åƒÔ½9—mÎÅgƒ=àtƒŸdœ-Õ.ë1=St$D†_“­Ù5#¶óºÝvê¤p¸ƒÏñGPæ’a0lCw@tHúd(¦k†Æ1h|Iå)’ E±ëÜ“ˆFo>°…äšÑí&OШ-p0xM7°'±7Ö³?ÊZ´N­:WŸ³Ç­÷µ8½^âô3-…‚ì,çaW‚ÈgŠõqdö¶½h 9ìú/l'¯†–KÀ %Sùú¶2=/
+‹áïP8â?’‘ãR
+ÂR²ï@Žœö˜ê›šŽøƒœf7+g`‚AúS¯Þ '¸±Ÿá
endstream
endobj
729 0 obj
-<< /Type /FontDescriptor /FontName /ZCBJRE+LMRoman12-Regular /Flags 4 /FontBBox [ -422 -280 1394 1127 ] /Ascent 1127 /CapHeight 683 /Descent -280 /ItalicAngle 0 /StemV 91 /XHeight 431 /FontFile3 731 0 R /CIDSet 730 0 R >>
+<< /Type /FontDescriptor /FontName /PCNKHN+LMRoman12-Regular /Flags 4 /FontBBox [ -422 -280 1394 1127 ] /Ascent 1127 /CapHeight 683 /Descent -280 /ItalicAngle 0 /StemV 91 /XHeight 431 /FontFile3 731 0 R /CIDSet 730 0 R >>
endobj
732 0 obj
-<< /Filter /FlateDecode /Length 451 >>
+<< /Filter /FlateDecode /Length 449 >>
stream
-xÚ…“Okã0ÅïúÚC =¸–íÔÚ–`hœ¼lÿ„RöæH“¬ –ŒlòíWÒØ-,6_Þ›™ç‘2ûö¶‹¥9@”Ý2º…Î V@T>×-™ÍÖF èþ@‚œÔî¾Y#vÐÓyY­+­úg®´8&׿M+8)ýeñsè|ѯrõc»‰~>oMSë$¶pε˜/Û«þììÿqR'Ók2 ÞÁvÊèšÜ2ÆÜ-KÓø‡ìH<¥ñý¨´´cZzðÙI’R©D?RøÛ–/Þ]ºšJ Y.iì&«®·—û†Ä¯V‚UúDç×B:ÓnhÛ3ø@”‘¢ Ž®·ÛÓKÝ
+xÚ…“Án£0†ï<…{ˆ”(¼­"¤ iµ¨m%QÕ+±'YKÁFyûµ=ÐJU£Eñ1ÿÌü›ÉÍfþú
+•Ýåê(¾’ö—Hâ9FË\ h›Šƒ©Ô ‚…ÍÉâÉ^y
+Å…-DiçŽÒÌÓ,Cº÷”Ζ¨džf Ò=Ò/¤i…ôèiŽÊ;ÌSOsŠ„y *3ê‰%HØa÷ »§cƒ}2tÍÐ \c‡¥ËK’˜å8¿n72·ÿŸ[Ä{cìþøCâ÷ÀM_*ø<Gn\–¿ýÿGoOÁ?ž‰ ‡
endstream
endobj
213 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /ZCBJRE+LMRoman12-Regular /DescendantFonts [ 733 0 R ] /ToUnicode 732 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /PCNKHN+LMRoman12-Regular /DescendantFonts [ 733 0 R ] /ToUnicode 732 0 R >>
endobj
733 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /ZCBJRE+LMRoman12-Regular /FontDescriptor 729 0 R /W 728 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /PCNKHN+LMRoman12-Regular /FontDescriptor 729 0 R /W 728 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
734 0 obj
[ 66 [ 223 ] 77 [ 484 ] 81 [ 470 ] 84 [ 484 ] 105 [ 340 ] ]
@@ -3722,7 +3695,7 @@ endobj
<< /Type /Font /Subtype /Type1 /BaseFont /PXBGHL+CMSY7 /FontDescriptor 758 0 R /FirstChar 0 /LastChar 0 /Widths 585 0 R >>
endobj
232 0 obj
-<< /Type /Pages /Parent 760 0 R /Count 10 /Kids [ 205 0 R 240 0 R 246 0 R 255 0 R 271 0 R 279 0 R 287 0 R 294 0 R 301 0 R 305 0 R ] >>
+<< /Type /Pages /Parent 760 0 R /Count 10 /Kids [ 205 0 R 240 0 R 248 0 R 256 0 R 272 0 R 280 0 R 287 0 R 294 0 R 301 0 R 305 0 R ] >>
endobj
313 0 obj
<< /Type /Pages /Parent 760 0 R /Count 10 /Kids [ 310 0 R 317 0 R 326 0 R 331 0 R 336 0 R 340 0 R 347 0 R 351 0 R 360 0 R 367 0 R ] >>
@@ -3890,7 +3863,7 @@ endobj
<< /Title 7 0 R /A 4 0 R /Parent 761 0 R /Next 10 0 R >>
endobj
762 0 obj
-<< /Names [ (Doc-Start) 210 0 R (page.1) 209 0 R (page.10) 307 0 R (page.11) 312 0 R (page.12) 319 0 R (page.13) 328 0 R (page.14) 333 0 R (page.15) 338 0 R (page.16) 342 0 R (page.17) 349 0 R (page.18) 353 0 R (page.19) 362 0 R (page.2) 242 0 R (page.20) 369 0 R (page.21) 377 0 R (page.22) 386 0 R (page.23) 393 0 R (page.24) 398 0 R (page.25) 402 0 R (page.26) 407 0 R (page.27) 412 0 R (page.28) 416 0 R (page.29) 420 0 R (page.3) 248 0 R (page.30) 426 0 R (page.31) 496 0 R (page.32) 539 0 R (page.33) 557 0 R (page.4) 257 0 R (page.5) 273 0 R (page.6) 281 0 R (page.7) 289 0 R ] /Limits [ (Doc-Start) (page.7) ] >>
+<< /Names [ (Doc-Start) 210 0 R (page.1) 209 0 R (page.10) 307 0 R (page.11) 312 0 R (page.12) 319 0 R (page.13) 328 0 R (page.14) 333 0 R (page.15) 338 0 R (page.16) 342 0 R (page.17) 349 0 R (page.18) 353 0 R (page.19) 362 0 R (page.2) 242 0 R (page.20) 369 0 R (page.21) 377 0 R (page.22) 386 0 R (page.23) 393 0 R (page.24) 398 0 R (page.25) 402 0 R (page.26) 407 0 R (page.27) 412 0 R (page.28) 416 0 R (page.29) 420 0 R (page.3) 250 0 R (page.30) 426 0 R (page.31) 496 0 R (page.32) 539 0 R (page.33) 557 0 R (page.4) 258 0 R (page.5) 274 0 R (page.6) 282 0 R (page.7) 289 0 R ] /Limits [ (Doc-Start) (page.7) ] >>
endobj
763 0 obj
<< /Names [ (page.8) 296 0 R (page.9) 303 0 R (piton:passe) 298 0 R (piton:transpose) 297 0 R (section*.1) 201 0 R (section.1) 5 0 R (section.2) 9 0 R (section.3) 13 0 R (section.4) 33 0 R (section.5) 61 0 R (section.6) 141 0 R (section.7) 145 0 R (section.8) 165 0 R (section.9) 177 0 R (subsection.3.1) 17 0 R (subsection.3.2) 21 0 R (subsection.3.3) 25 0 R (subsection.3.4) 29 0 R (subsection.4.1) 37 0 R (subsection.4.2) 41 0 R (subsection.4.3) 57 0 R (subsection.5.1) 65 0 R (subsection.5.2) 77 0 R (subsection.5.3) 89 0 R (subsection.5.4) 93 0 R (subsection.5.5) 117 0 R (subsection.5.6) 133 0 R (subsection.5.7) 137 0 R (subsection.7.1) 149 0 R (subsection.7.2) 153 0 R (subsection.7.3) 157 0 R (subsection.7.4) 161 0 R ] /Limits [ (page.8) (subsection.7.4) ] >>
@@ -3908,781 +3881,781 @@ endobj
<< /Type /Catalog /Pages 760 0 R /Outlines 761 0 R /Names 766 0 R /PageMode/UseOutlines /OpenAction 204 0 R >>
endobj
768 0 obj
-<< /Author(\376\377\000F\000.\000\040\000P\000a\000n\000t\000i\000g\000n\000y)/Title(\376\377\000L\040\031\000e\000x\000t\000e\000n\000s\000i\000o\000n\000\040\000p\000i\000t\000o\000n)/Subject(\376\377\000U\000n\000e\000\040\000e\000x\000t\000e\000n\000s\000i\000o\000n\000\040\000L\000a\000T\000e\000X)/Creator(LaTeX with hyperref)/Keywords() /Producer (LuaTeX-1.18.0) /CreationDate (D:20240330195443+01'00') /ModDate (D:20240330195443+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.18.0 (MiKTeX 24.3)) >>
+<< /Author(\376\377\000F\000.\000\040\000P\000a\000n\000t\000i\000g\000n\000y)/Title(\376\377\000L\040\031\000e\000x\000t\000e\000n\000s\000i\000o\000n\000\040\000p\000i\000t\000o\000n)/Subject(\376\377\000U\000n\000e\000\040\000e\000x\000t\000e\000n\000s\000i\000o\000n\000\040\000L\000a\000T\000e\000X)/Creator(LaTeX with hyperref)/Keywords() /Producer (LuaTeX-1.18.1) /CreationDate (D:20240414151949+02'00') /ModDate (D:20240414151949+02'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.18.1 (MiKTeX 24.3.31)) >>
endobj
xref
0 769
0000000000 65535 f
-0000161657 00000 n
-0000161702 00000 n
-0000161722 00000 n
+0000162165 00000 n
+0000162210 00000 n
+0000162230 00000 n
0000000020 00000 n
-0000015522 00000 n
-0000395896 00000 n
+0000015525 00000 n
+0000396136 00000 n
0000000065 00000 n
0000000155 00000 n
-0000020648 00000 n
-0000395810 00000 n
+0000020800 00000 n
+0000396050 00000 n
0000000200 00000 n
0000000288 00000 n
-0000020708 00000 n
-0000395685 00000 n
+0000020860 00000 n
+0000395925 00000 n
0000000334 00000 n
0000000498 00000 n
-0000020769 00000 n
-0000395611 00000 n
+0000020921 00000 n
+0000395851 00000 n
0000000549 00000 n
0000000663 00000 n
-0000020830 00000 n
-0000395524 00000 n
+0000020982 00000 n
+0000395764 00000 n
0000000714 00000 n
0000000873 00000 n
-0000020891 00000 n
-0000395437 00000 n
+0000021043 00000 n
+0000395677 00000 n
0000000924 00000 n
0000001304 00000 n
-0000025146 00000 n
-0000395363 00000 n
+0000025742 00000 n
+0000395603 00000 n
0000001355 00000 n
0000001561 00000 n
-0000025207 00000 n
-0000395238 00000 n
+0000025802 00000 n
+0000395478 00000 n
0000001607 00000 n
0000001715 00000 n
-0000031681 00000 n
-0000395164 00000 n
+0000032276 00000 n
+0000395404 00000 n
0000001766 00000 n
0000002000 00000 n
-0000042521 00000 n
-0000395040 00000 n
+0000043116 00000 n
+0000395280 00000 n
0000002051 00000 n
0000002132 00000 n
-0000042582 00000 n
-0000394966 00000 n
+0000043177 00000 n
+0000395206 00000 n
0000002188 00000 n
0000002297 00000 n
-0000047422 00000 n
-0000394879 00000 n
+0000048017 00000 n
+0000395119 00000 n
0000002353 00000 n
0000002510 00000 n
-0000047483 00000 n
-0000394805 00000 n
+0000048078 00000 n
+0000395045 00000 n
0000002566 00000 n
0000002705 00000 n
-0000052007 00000 n
-0000394731 00000 n
+0000052602 00000 n
+0000394971 00000 n
0000002756 00000 n
0000002981 00000 n
-0000056829 00000 n
-0000394604 00000 n
+0000057432 00000 n
+0000394844 00000 n
0000003027 00000 n
0000003184 00000 n
-0000056890 00000 n
-0000394493 00000 n
+0000057493 00000 n
+0000394733 00000 n
0000003235 00000 n
0000003433 00000 n
-0000056951 00000 n
-0000394419 00000 n
+0000057554 00000 n
+0000394659 00000 n
0000003489 00000 n
0000003608 00000 n
-0000057012 00000 n
-0000394345 00000 n
+0000057615 00000 n
+0000394585 00000 n
0000003664 00000 n
0000003788 00000 n
-0000061464 00000 n
-0000394221 00000 n
+0000062067 00000 n
+0000394461 00000 n
0000003839 00000 n
0000004054 00000 n
-0000061525 00000 n
-0000394147 00000 n
+0000062128 00000 n
+0000394387 00000 n
0000004110 00000 n
0000004326 00000 n
-0000061586 00000 n
-0000394073 00000 n
+0000062189 00000 n
+0000394313 00000 n
0000004382 00000 n
0000004554 00000 n
-0000068902 00000 n
-0000393986 00000 n
+0000069457 00000 n
+0000394226 00000 n
0000004605 00000 n
0000004815 00000 n
-0000073764 00000 n
-0000393860 00000 n
+0000074272 00000 n
+0000394100 00000 n
0000004866 00000 n
0000005041 00000 n
-0000073825 00000 n
-0000393785 00000 n
+0000074333 00000 n
+0000394025 00000 n
0000005097 00000 n
0000005257 00000 n
-0000077699 00000 n
-0000393694 00000 n
+0000078207 00000 n
+0000393934 00000 n
0000005314 00000 n
0000005468 00000 n
-0000077761 00000 n
-0000393602 00000 n
+0000078269 00000 n
+0000393842 00000 n
0000005525 00000 n
0000005699 00000 n
-0000077823 00000 n
-0000393510 00000 n
+0000078331 00000 n
+0000393750 00000 n
0000005756 00000 n
0000005905 00000 n
-0000081668 00000 n
-0000393432 00000 n
+0000082176 00000 n
+0000393672 00000 n
0000005962 00000 n
0000006136 00000 n
-0000086179 00000 n
-0000393302 00000 n
+0000086687 00000 n
+0000393542 00000 n
0000006188 00000 n
0000006399 00000 n
-0000086241 00000 n
-0000393223 00000 n
+0000086749 00000 n
+0000393463 00000 n
0000006456 00000 n
0000006751 00000 n
-0000086303 00000 n
-0000393130 00000 n
+0000086811 00000 n
+0000393370 00000 n
0000006808 00000 n
0000007172 00000 n
-0000089667 00000 n
-0000393051 00000 n
+0000090175 00000 n
+0000393291 00000 n
0000007229 00000 n
0000007613 00000 n
-0000094160 00000 n
-0000392959 00000 n
+0000094668 00000 n
+0000393199 00000 n
0000007665 00000 n
0000007991 00000 n
-0000094222 00000 n
-0000392881 00000 n
+0000094730 00000 n
+0000393121 00000 n
0000008043 00000 n
0000008127 00000 n
-0000094284 00000 n
-0000392789 00000 n
+0000094792 00000 n
+0000393029 00000 n
0000008174 00000 n
0000008340 00000 n
-0000099237 00000 n
-0000392657 00000 n
+0000099745 00000 n
+0000392897 00000 n
0000008387 00000 n
0000008456 00000 n
-0000099299 00000 n
-0000392578 00000 n
+0000099807 00000 n
+0000392818 00000 n
0000008508 00000 n
0000008661 00000 n
-0000099361 00000 n
-0000392485 00000 n
+0000099869 00000 n
+0000392725 00000 n
0000008713 00000 n
0000008911 00000 n
-0000103594 00000 n
-0000392392 00000 n
+0000104102 00000 n
+0000392632 00000 n
0000008963 00000 n
0000009116 00000 n
-0000107899 00000 n
-0000392313 00000 n
+0000108407 00000 n
+0000392553 00000 n
0000009168 00000 n
0000009375 00000 n
-0000111164 00000 n
-0000392181 00000 n
+0000111672 00000 n
+0000392421 00000 n
0000009422 00000 n
0000009582 00000 n
-0000111226 00000 n
-0000392102 00000 n
+0000111734 00000 n
+0000392342 00000 n
0000009634 00000 n
0000009832 00000 n
-0000115145 00000 n
-0000392023 00000 n
+0000115653 00000 n
+0000392263 00000 n
0000009884 00000 n
0000010209 00000 n
-0000123221 00000 n
-0000391891 00000 n
+0000123729 00000 n
+0000392131 00000 n
0000010256 00000 n
0000010571 00000 n
-0000123283 00000 n
-0000391812 00000 n
+0000123791 00000 n
+0000392052 00000 n
0000010623 00000 n
0000010743 00000 n
-0000126851 00000 n
-0000391719 00000 n
+0000127359 00000 n
+0000391959 00000 n
0000010795 00000 n
0000010910 00000 n
-0000130473 00000 n
-0000391626 00000 n
+0000130981 00000 n
+0000391866 00000 n
0000010962 00000 n
0000011114 00000 n
-0000134045 00000 n
-0000391533 00000 n
+0000134553 00000 n
+0000391773 00000 n
0000011166 00000 n
0000011271 00000 n
-0000136298 00000 n
-0000391454 00000 n
+0000136806 00000 n
+0000391694 00000 n
0000011323 00000 n
0000011464 00000 n
-0000149069 00000 n
-0000391375 00000 n
+0000149577 00000 n
+0000391615 00000 n
0000011512 00000 n
0000011566 00000 n
-0000015040 00000 n
-0000015206 00000 n
-0000015582 00000 n
+0000015043 00000 n
+0000015209 00000 n
+0000015585 00000 n
0000011618 00000 n
-0000015398 00000 n
-0000015460 00000 n
-0000334929 00000 n
-0000331638 00000 n
-0000329534 00000 n
-0000325536 00000 n
-0000322202 00000 n
-0000319771 00000 n
-0000313167 00000 n
-0000311066 00000 n
-0000302786 00000 n
-0000291768 00000 n
-0000288301 00000 n
-0000285210 00000 n
-0000274923 00000 n
-0000271356 00000 n
-0000390094 00000 n
-0000389662 00000 n
-0000265112 00000 n
-0000262927 00000 n
-0000253557 00000 n
-0000250329 00000 n
-0000246308 00000 n
-0000390659 00000 n
-0000015177 00000 n
-0000019793 00000 n
-0000019951 00000 n
-0000020110 00000 n
-0000020268 00000 n
-0000020427 00000 n
-0000020952 00000 n
-0000019595 00000 n
-0000015966 00000 n
-0000020586 00000 n
-0000238711 00000 n
-0000019732 00000 n
-0000025268 00000 n
-0000024963 00000 n
-0000021141 00000 n
-0000025084 00000 n
-0000236930 00000 n
-0000031313 00000 n
-0000031466 00000 n
-0000030997 00000 n
-0000031155 00000 n
-0000031742 00000 n
-0000030807 00000 n
-0000025509 00000 n
-0000031619 00000 n
-0000230057 00000 n
-0000030944 00000 n
-0000036875 00000 n
-0000037034 00000 n
-0000037192 00000 n
-0000037350 00000 n
-0000037509 00000 n
-0000037673 00000 n
-0000037837 00000 n
-0000037994 00000 n
-0000038151 00000 n
-0000038312 00000 n
-0000038536 00000 n
-0000036637 00000 n
-0000031996 00000 n
-0000038474 00000 n
-0000227243 00000 n
-0000223967 00000 n
-0000036774 00000 n
-0000042300 00000 n
-0000042643 00000 n
-0000042134 00000 n
-0000038790 00000 n
-0000042459 00000 n
-0000215898 00000 n
-0000042271 00000 n
-0000047052 00000 n
-0000047206 00000 n
-0000047544 00000 n
-0000046878 00000 n
-0000042910 00000 n
-0000047360 00000 n
-0000207361 00000 n
-0000047015 00000 n
-0000051657 00000 n
-0000052068 00000 n
-0000051491 00000 n
-0000047785 00000 n
-0000051817 00000 n
-0000051879 00000 n
-0000051943 00000 n
-0000051628 00000 n
-0000057073 00000 n
-0000056646 00000 n
-0000052361 00000 n
-0000056767 00000 n
-0000061647 00000 n
-0000061281 00000 n
-0000057327 00000 n
-0000061402 00000 n
-0000390377 00000 n
-0000064875 00000 n
-0000064692 00000 n
-0000061875 00000 n
-0000064813 00000 n
-0000390811 00000 n
-0000068522 00000 n
-0000068681 00000 n
-0000068963 00000 n
-0000068348 00000 n
-0000065090 00000 n
-0000068840 00000 n
-0000068485 00000 n
-0000073066 00000 n
-0000073225 00000 n
+0000015401 00000 n
+0000015463 00000 n
+0000335169 00000 n
+0000331878 00000 n
+0000329774 00000 n
+0000325942 00000 n
+0000322608 00000 n
+0000320177 00000 n
+0000313573 00000 n
+0000311472 00000 n
+0000303192 00000 n
+0000292174 00000 n
+0000288707 00000 n
+0000285616 00000 n
+0000275329 00000 n
+0000271762 00000 n
+0000390334 00000 n
+0000389902 00000 n
+0000265518 00000 n
+0000263333 00000 n
+0000253963 00000 n
+0000250735 00000 n
+0000246714 00000 n
+0000390899 00000 n
+0000015180 00000 n
+0000019945 00000 n
+0000020103 00000 n
+0000020262 00000 n
+0000020420 00000 n
+0000020579 00000 n
+0000021104 00000 n
+0000019747 00000 n
+0000015969 00000 n
+0000020738 00000 n
+0000239117 00000 n
+0000237340 00000 n
+0000228915 00000 n
+0000019884 00000 n
+0000025863 00000 n
+0000025559 00000 n
+0000021319 00000 n
+0000025680 00000 n
+0000031908 00000 n
+0000032061 00000 n
+0000031592 00000 n
+0000031750 00000 n
+0000032337 00000 n
+0000031402 00000 n
+0000026104 00000 n
+0000032214 00000 n
+0000222042 00000 n
+0000031539 00000 n
+0000037470 00000 n
+0000037629 00000 n
+0000037787 00000 n
+0000037945 00000 n
+0000038104 00000 n
+0000038268 00000 n
+0000038432 00000 n
+0000038589 00000 n
+0000038746 00000 n
+0000038907 00000 n
+0000039131 00000 n
+0000037232 00000 n
+0000032591 00000 n
+0000039069 00000 n
+0000219228 00000 n
+0000215952 00000 n
+0000037369 00000 n
+0000042895 00000 n
+0000043238 00000 n
+0000042729 00000 n
+0000039385 00000 n
+0000043054 00000 n
+0000042866 00000 n
+0000047647 00000 n
+0000047801 00000 n
+0000048139 00000 n
+0000047473 00000 n
+0000043505 00000 n
+0000047955 00000 n
+0000207869 00000 n
+0000047610 00000 n
+0000052252 00000 n
+0000052663 00000 n
+0000052086 00000 n
+0000048380 00000 n
+0000052412 00000 n
+0000052474 00000 n
+0000052538 00000 n
+0000052223 00000 n
+0000057676 00000 n
+0000057249 00000 n
+0000052956 00000 n
+0000057370 00000 n
+0000062250 00000 n
+0000061884 00000 n
+0000057930 00000 n
+0000062005 00000 n
+0000390617 00000 n
+0000065478 00000 n
+0000065295 00000 n
+0000062478 00000 n
+0000065416 00000 n
+0000391051 00000 n
+0000069079 00000 n
+0000069237 00000 n
+0000069518 00000 n
+0000068905 00000 n
+0000065693 00000 n
+0000069395 00000 n
+0000069042 00000 n
+0000073574 00000 n
+0000073733 00000 n
+0000073892 00000 n
+0000074051 00000 n
+0000074394 00000 n
0000073384 00000 n
-0000073543 00000 n
-0000073886 00000 n
-0000072876 00000 n
-0000069230 00000 n
-0000073702 00000 n
-0000073013 00000 n
-0000077885 00000 n
-0000077516 00000 n
-0000074153 00000 n
-0000077637 00000 n
-0000390236 00000 n
-0000081730 00000 n
-0000081485 00000 n
-0000078113 00000 n
-0000081606 00000 n
-0000086365 00000 n
-0000085996 00000 n
-0000081919 00000 n
-0000086117 00000 n
-0000390519 00000 n
-0000389806 00000 n
-0000389950 00000 n
-0000089729 00000 n
-0000089484 00000 n
-0000086710 00000 n
-0000089605 00000 n
-0000094346 00000 n
-0000093977 00000 n
-0000089957 00000 n
-0000094098 00000 n
-0000098378 00000 n
-0000098537 00000 n
-0000098700 00000 n
-0000098863 00000 n
-0000099021 00000 n
-0000099423 00000 n
-0000098180 00000 n
-0000094535 00000 n
-0000099175 00000 n
-0000098317 00000 n
-0000103216 00000 n
-0000103374 00000 n
-0000103656 00000 n
-0000103042 00000 n
-0000099625 00000 n
-0000103532 00000 n
-0000103179 00000 n
-0000107341 00000 n
-0000107500 00000 n
-0000107659 00000 n
-0000107961 00000 n
-0000107159 00000 n
-0000103858 00000 n
-0000107837 00000 n
-0000203509 00000 n
-0000390963 00000 n
-0000107296 00000 n
-0000114777 00000 n
-0000114930 00000 n
-0000111288 00000 n
-0000110981 00000 n
-0000108228 00000 n
-0000111102 00000 n
-0000201443 00000 n
-0000189282 00000 n
-0000174555 00000 n
-0000115207 00000 n
-0000114603 00000 n
-0000111529 00000 n
-0000115083 00000 n
-0000114740 00000 n
-0000117806 00000 n
-0000117623 00000 n
-0000115422 00000 n
-0000117744 00000 n
-0000118944 00000 n
-0000118761 00000 n
-0000118008 00000 n
-0000118882 00000 n
-0000122981 00000 n
-0000123345 00000 n
-0000122815 00000 n
-0000119094 00000 n
-0000123159 00000 n
-0000122952 00000 n
-0000126913 00000 n
-0000126668 00000 n
-0000123573 00000 n
-0000126789 00000 n
-0000130535 00000 n
-0000130290 00000 n
-0000127076 00000 n
-0000130411 00000 n
-0000134107 00000 n
-0000133862 00000 n
-0000130724 00000 n
-0000133983 00000 n
-0000135918 00000 n
-0000136077 00000 n
-0000136360 00000 n
-0000135744 00000 n
-0000134283 00000 n
-0000136236 00000 n
-0000135881 00000 n
-0000139195 00000 n
-0000139344 00000 n
-0000139495 00000 n
-0000139647 00000 n
-0000139799 00000 n
-0000139951 00000 n
-0000140103 00000 n
-0000140254 00000 n
-0000140405 00000 n
-0000140556 00000 n
-0000140707 00000 n
-0000140858 00000 n
-0000141010 00000 n
-0000141161 00000 n
-0000141312 00000 n
-0000141464 00000 n
-0000141616 00000 n
-0000141768 00000 n
-0000141920 00000 n
-0000142071 00000 n
-0000142223 00000 n
-0000142374 00000 n
-0000142526 00000 n
-0000142678 00000 n
-0000142830 00000 n
-0000142982 00000 n
-0000143134 00000 n
-0000143285 00000 n
-0000143435 00000 n
-0000143586 00000 n
-0000143735 00000 n
-0000143886 00000 n
-0000144037 00000 n
-0000144186 00000 n
-0000144336 00000 n
-0000144485 00000 n
-0000144634 00000 n
-0000144783 00000 n
-0000144934 00000 n
-0000145085 00000 n
-0000145237 00000 n
-0000145389 00000 n
-0000145540 00000 n
-0000145690 00000 n
-0000145841 00000 n
-0000145992 00000 n
-0000146143 00000 n
-0000146295 00000 n
-0000146446 00000 n
-0000146597 00000 n
-0000146747 00000 n
-0000146898 00000 n
-0000147050 00000 n
-0000147202 00000 n
-0000147352 00000 n
-0000147503 00000 n
-0000147654 00000 n
-0000147805 00000 n
-0000147956 00000 n
-0000148107 00000 n
-0000148256 00000 n
-0000148407 00000 n
-0000148558 00000 n
-0000148707 00000 n
-0000148856 00000 n
-0000149131 00000 n
-0000138517 00000 n
-0000136523 00000 n
-0000149007 00000 n
-0000391115 00000 n
-0000138654 00000 n
-0000152105 00000 n
-0000152257 00000 n
-0000152410 00000 n
-0000152560 00000 n
-0000152718 00000 n
-0000152874 00000 n
-0000153032 00000 n
-0000153190 00000 n
-0000153343 00000 n
-0000153500 00000 n
-0000153658 00000 n
-0000153822 00000 n
-0000153986 00000 n
-0000154150 00000 n
-0000154308 00000 n
-0000154461 00000 n
-0000154619 00000 n
-0000154783 00000 n
-0000154947 00000 n
-0000155105 00000 n
-0000155269 00000 n
-0000155432 00000 n
-0000155590 00000 n
-0000155747 00000 n
-0000155911 00000 n
-0000156074 00000 n
-0000156238 00000 n
-0000156402 00000 n
-0000156566 00000 n
-0000156721 00000 n
-0000156885 00000 n
-0000157049 00000 n
-0000157213 00000 n
-0000157370 00000 n
-0000157528 00000 n
-0000159112 00000 n
-0000159265 00000 n
-0000157742 00000 n
-0000151667 00000 n
-0000149320 00000 n
-0000157680 00000 n
-0000151804 00000 n
-0000159423 00000 n
-0000159581 00000 n
-0000159739 00000 n
-0000159896 00000 n
-0000160049 00000 n
-0000160207 00000 n
-0000160364 00000 n
-0000160517 00000 n
-0000160675 00000 n
-0000160833 00000 n
-0000160990 00000 n
-0000161148 00000 n
-0000161305 00000 n
-0000161520 00000 n
-0000158834 00000 n
-0000157944 00000 n
-0000161458 00000 n
-0000158971 00000 n
-0000161775 00000 n
-0000173757 00000 n
-0000162002 00000 n
-0000162104 00000 n
-0000173996 00000 n
-0000174717 00000 n
-0000174948 00000 n
-0000188457 00000 n
-0000175270 00000 n
-0000175376 00000 n
-0000188688 00000 n
-0000189436 00000 n
-0000189659 00000 n
-0000200690 00000 n
-0000189805 00000 n
-0000189902 00000 n
-0000200927 00000 n
-0000201602 00000 n
-0000201830 00000 n
-0000202822 00000 n
-0000201873 00000 n
-0000201968 00000 n
-0000203062 00000 n
-0000203664 00000 n
-0000203865 00000 n
-0000203891 00000 n
-0000203917 00000 n
-0000203943 00000 n
-0000204003 00000 n
-0000204098 00000 n
-0000206585 00000 n
-0000204303 00000 n
-0000204406 00000 n
-0000206830 00000 n
-0000207522 00000 n
-0000207729 00000 n
-0000214942 00000 n
-0000208194 00000 n
-0000208315 00000 n
-0000215179 00000 n
-0000216052 00000 n
-0000216252 00000 n
-0000222976 00000 n
-0000216740 00000 n
-0000216856 00000 n
-0000223213 00000 n
-0000224122 00000 n
-0000224323 00000 n
-0000226495 00000 n
-0000224478 00000 n
-0000224583 00000 n
-0000226739 00000 n
-0000227404 00000 n
-0000227611 00000 n
-0000229317 00000 n
-0000227734 00000 n
-0000227840 00000 n
-0000229563 00000 n
-0000230219 00000 n
-0000230427 00000 n
-0000236055 00000 n
-0000230832 00000 n
-0000230952 00000 n
-0000236296 00000 n
-0000237086 00000 n
-0000237288 00000 n
-0000238035 00000 n
-0000237321 00000 n
-0000237415 00000 n
-0000238271 00000 n
-0000238864 00000 n
-0000239063 00000 n
-0000245346 00000 n
-0000239515 00000 n
-0000239625 00000 n
-0000245583 00000 n
-0000246463 00000 n
-0000246664 00000 n
-0000249558 00000 n
-0000246890 00000 n
-0000246995 00000 n
-0000249798 00000 n
-0000250484 00000 n
-0000250685 00000 n
-0000252790 00000 n
-0000250919 00000 n
-0000251024 00000 n
-0000253027 00000 n
-0000253712 00000 n
-0000253913 00000 n
-0000261909 00000 n
-0000254457 00000 n
-0000254588 00000 n
-0000262147 00000 n
-0000263083 00000 n
-0000263285 00000 n
-0000264416 00000 n
-0000263341 00000 n
-0000263441 00000 n
-0000264655 00000 n
-0000265268 00000 n
-0000265470 00000 n
-0000265708 00000 n
-0000265796 00000 n
-0000270497 00000 n
-0000266161 00000 n
-0000266270 00000 n
-0000270736 00000 n
-0000271511 00000 n
-0000271712 00000 n
-0000274163 00000 n
-0000271922 00000 n
-0000272026 00000 n
-0000274400 00000 n
-0000275078 00000 n
-0000275279 00000 n
-0000284144 00000 n
-0000275756 00000 n
-0000275876 00000 n
-0000284382 00000 n
-0000285366 00000 n
-0000285568 00000 n
-0000287575 00000 n
-0000285681 00000 n
-0000285784 00000 n
-0000287814 00000 n
-0000288457 00000 n
-0000288659 00000 n
-0000290988 00000 n
-0000288887 00000 n
-0000288992 00000 n
-0000291226 00000 n
-0000291924 00000 n
-0000292126 00000 n
-0000301682 00000 n
-0000292773 00000 n
-0000292914 00000 n
-0000301921 00000 n
-0000302943 00000 n
-0000303146 00000 n
-0000310112 00000 n
-0000303624 00000 n
-0000303748 00000 n
-0000310349 00000 n
-0000311220 00000 n
-0000311420 00000 n
-0000312466 00000 n
-0000311497 00000 n
-0000311596 00000 n
-0000312703 00000 n
-0000313322 00000 n
-0000313523 00000 n
-0000318881 00000 n
-0000313931 00000 n
-0000314054 00000 n
-0000319119 00000 n
-0000319927 00000 n
-0000320129 00000 n
-0000321503 00000 n
-0000320207 00000 n
-0000320309 00000 n
-0000321739 00000 n
-0000322355 00000 n
-0000322554 00000 n
-0000324788 00000 n
-0000322732 00000 n
-0000322837 00000 n
-0000325026 00000 n
-0000325692 00000 n
-0000325894 00000 n
-0000328762 00000 n
-0000326092 00000 n
-0000326201 00000 n
-0000329001 00000 n
-0000329691 00000 n
-0000329894 00000 n
-0000330935 00000 n
-0000329971 00000 n
-0000330070 00000 n
-0000331173 00000 n
-0000331794 00000 n
-0000331996 00000 n
-0000334183 00000 n
-0000332138 00000 n
-0000332247 00000 n
-0000334422 00000 n
-0000335086 00000 n
-0000343485 00000 n
-0000335289 00000 n
-0000350938 00000 n
-0000343749 00000 n
-0000358334 00000 n
-0000351160 00000 n
-0000367025 00000 n
-0000358556 00000 n
-0000374831 00000 n
-0000367302 00000 n
-0000382220 00000 n
-0000375087 00000 n
-0000389435 00000 n
+0000069772 00000 n
+0000074210 00000 n
+0000073521 00000 n
+0000078393 00000 n
+0000078024 00000 n
+0000074661 00000 n
+0000078145 00000 n
+0000390476 00000 n
+0000082238 00000 n
+0000081993 00000 n
+0000078621 00000 n
+0000082114 00000 n
+0000086873 00000 n
+0000086504 00000 n
+0000082427 00000 n
+0000086625 00000 n
+0000390759 00000 n
+0000390046 00000 n
+0000390190 00000 n
+0000090237 00000 n
+0000089992 00000 n
+0000087218 00000 n
+0000090113 00000 n
+0000094854 00000 n
+0000094485 00000 n
+0000090465 00000 n
+0000094606 00000 n
+0000098886 00000 n
+0000099045 00000 n
+0000099208 00000 n
+0000099371 00000 n
+0000099529 00000 n
+0000099931 00000 n
+0000098688 00000 n
+0000095043 00000 n
+0000099683 00000 n
+0000098825 00000 n
+0000103724 00000 n
+0000103882 00000 n
+0000104164 00000 n
+0000103550 00000 n
+0000100133 00000 n
+0000104040 00000 n
+0000103687 00000 n
+0000107849 00000 n
+0000108008 00000 n
+0000108167 00000 n
+0000108469 00000 n
+0000107667 00000 n
+0000104366 00000 n
+0000108345 00000 n
+0000204017 00000 n
+0000391203 00000 n
+0000107804 00000 n
+0000115285 00000 n
+0000115438 00000 n
+0000111796 00000 n
+0000111489 00000 n
+0000108736 00000 n
+0000111610 00000 n
+0000201951 00000 n
+0000189790 00000 n
+0000175063 00000 n
+0000115715 00000 n
+0000115111 00000 n
+0000112037 00000 n
+0000115591 00000 n
+0000115248 00000 n
+0000118314 00000 n
+0000118131 00000 n
+0000115930 00000 n
+0000118252 00000 n
+0000119452 00000 n
+0000119269 00000 n
+0000118516 00000 n
+0000119390 00000 n
+0000123489 00000 n
+0000123853 00000 n
+0000123323 00000 n
+0000119602 00000 n
+0000123667 00000 n
+0000123460 00000 n
+0000127421 00000 n
+0000127176 00000 n
+0000124081 00000 n
+0000127297 00000 n
+0000131043 00000 n
+0000130798 00000 n
+0000127584 00000 n
+0000130919 00000 n
+0000134615 00000 n
+0000134370 00000 n
+0000131232 00000 n
+0000134491 00000 n
+0000136426 00000 n
+0000136585 00000 n
+0000136868 00000 n
+0000136252 00000 n
+0000134791 00000 n
+0000136744 00000 n
+0000136389 00000 n
+0000139702 00000 n
+0000139851 00000 n
+0000140002 00000 n
+0000140154 00000 n
+0000140306 00000 n
+0000140458 00000 n
+0000140610 00000 n
+0000140761 00000 n
+0000140912 00000 n
+0000141063 00000 n
+0000141214 00000 n
+0000141365 00000 n
+0000141517 00000 n
+0000141668 00000 n
+0000141819 00000 n
+0000141971 00000 n
+0000142123 00000 n
+0000142275 00000 n
+0000142427 00000 n
+0000142579 00000 n
+0000142731 00000 n
+0000142882 00000 n
+0000143034 00000 n
+0000143186 00000 n
+0000143338 00000 n
+0000143490 00000 n
+0000143642 00000 n
+0000143793 00000 n
+0000143943 00000 n
+0000144094 00000 n
+0000144243 00000 n
+0000144394 00000 n
+0000144545 00000 n
+0000144694 00000 n
+0000144844 00000 n
+0000144993 00000 n
+0000145142 00000 n
+0000145291 00000 n
+0000145442 00000 n
+0000145593 00000 n
+0000145745 00000 n
+0000145897 00000 n
+0000146048 00000 n
+0000146198 00000 n
+0000146349 00000 n
+0000146500 00000 n
+0000146651 00000 n
+0000146803 00000 n
+0000146954 00000 n
+0000147105 00000 n
+0000147255 00000 n
+0000147406 00000 n
+0000147558 00000 n
+0000147710 00000 n
+0000147860 00000 n
+0000148011 00000 n
+0000148162 00000 n
+0000148313 00000 n
+0000148464 00000 n
+0000148615 00000 n
+0000148764 00000 n
+0000148915 00000 n
+0000149066 00000 n
+0000149215 00000 n
+0000149364 00000 n
+0000149639 00000 n
+0000139024 00000 n
+0000137031 00000 n
+0000149515 00000 n
+0000391355 00000 n
+0000139161 00000 n
+0000152613 00000 n
+0000152765 00000 n
+0000152918 00000 n
+0000153068 00000 n
+0000153226 00000 n
+0000153382 00000 n
+0000153540 00000 n
+0000153698 00000 n
+0000153851 00000 n
+0000154008 00000 n
+0000154166 00000 n
+0000154330 00000 n
+0000154494 00000 n
+0000154658 00000 n
+0000154816 00000 n
+0000154969 00000 n
+0000155127 00000 n
+0000155291 00000 n
+0000155455 00000 n
+0000155613 00000 n
+0000155777 00000 n
+0000155940 00000 n
+0000156098 00000 n
+0000156255 00000 n
+0000156419 00000 n
+0000156582 00000 n
+0000156746 00000 n
+0000156910 00000 n
+0000157074 00000 n
+0000157229 00000 n
+0000157393 00000 n
+0000157557 00000 n
+0000157721 00000 n
+0000157878 00000 n
+0000158036 00000 n
+0000159620 00000 n
+0000159773 00000 n
+0000158250 00000 n
+0000152175 00000 n
+0000149828 00000 n
+0000158188 00000 n
+0000152312 00000 n
+0000159931 00000 n
+0000160089 00000 n
+0000160247 00000 n
+0000160404 00000 n
+0000160557 00000 n
+0000160715 00000 n
+0000160872 00000 n
+0000161025 00000 n
+0000161183 00000 n
+0000161341 00000 n
+0000161498 00000 n
+0000161656 00000 n
+0000161813 00000 n
+0000162028 00000 n
+0000159342 00000 n
+0000158452 00000 n
+0000161966 00000 n
+0000159479 00000 n
+0000162283 00000 n
+0000174265 00000 n
+0000162510 00000 n
+0000162612 00000 n
+0000174504 00000 n
+0000175225 00000 n
+0000175456 00000 n
+0000188965 00000 n
+0000175778 00000 n
+0000175884 00000 n
+0000189196 00000 n
+0000189944 00000 n
+0000190167 00000 n
+0000201198 00000 n
+0000190313 00000 n
+0000190410 00000 n
+0000201435 00000 n
+0000202110 00000 n
+0000202338 00000 n
+0000203330 00000 n
+0000202381 00000 n
+0000202476 00000 n
+0000203570 00000 n
+0000204172 00000 n
+0000204373 00000 n
+0000204399 00000 n
+0000204425 00000 n
+0000204451 00000 n
+0000204511 00000 n
+0000204606 00000 n
+0000207093 00000 n
+0000204811 00000 n
+0000204914 00000 n
+0000207338 00000 n
+0000208030 00000 n
+0000208237 00000 n
+0000214961 00000 n
+0000208725 00000 n
+0000208841 00000 n
+0000215198 00000 n
+0000216107 00000 n
+0000216308 00000 n
+0000218480 00000 n
+0000216463 00000 n
+0000216568 00000 n
+0000218724 00000 n
+0000219389 00000 n
+0000219596 00000 n
+0000221302 00000 n
+0000219719 00000 n
+0000219825 00000 n
+0000221548 00000 n
+0000222204 00000 n
+0000222412 00000 n
+0000228040 00000 n
+0000222817 00000 n
+0000222937 00000 n
+0000228281 00000 n
+0000229071 00000 n
+0000229273 00000 n
+0000236389 00000 n
+0000229726 00000 n
+0000229847 00000 n
+0000236626 00000 n
+0000237494 00000 n
+0000237694 00000 n
+0000238441 00000 n
+0000237727 00000 n
+0000237821 00000 n
+0000238677 00000 n
+0000239270 00000 n
+0000239469 00000 n
+0000245752 00000 n
+0000239921 00000 n
+0000240031 00000 n
+0000245989 00000 n
+0000246869 00000 n
+0000247070 00000 n
+0000249964 00000 n
+0000247296 00000 n
+0000247401 00000 n
+0000250204 00000 n
+0000250890 00000 n
+0000251091 00000 n
+0000253196 00000 n
+0000251325 00000 n
+0000251430 00000 n
+0000253433 00000 n
+0000254118 00000 n
+0000254319 00000 n
+0000262315 00000 n
+0000254863 00000 n
+0000254994 00000 n
+0000262553 00000 n
+0000263489 00000 n
+0000263691 00000 n
+0000264822 00000 n
+0000263747 00000 n
+0000263847 00000 n
+0000265061 00000 n
+0000265674 00000 n
+0000265876 00000 n
+0000266114 00000 n
+0000266202 00000 n
+0000270903 00000 n
+0000266567 00000 n
+0000266676 00000 n
+0000271142 00000 n
+0000271917 00000 n
+0000272118 00000 n
+0000274569 00000 n
+0000272328 00000 n
+0000272432 00000 n
+0000274806 00000 n
+0000275484 00000 n
+0000275685 00000 n
+0000284550 00000 n
+0000276162 00000 n
+0000276282 00000 n
+0000284788 00000 n
+0000285772 00000 n
+0000285974 00000 n
+0000287981 00000 n
+0000286087 00000 n
+0000286190 00000 n
+0000288220 00000 n
+0000288863 00000 n
+0000289065 00000 n
+0000291394 00000 n
+0000289293 00000 n
+0000289398 00000 n
+0000291632 00000 n
+0000292330 00000 n
+0000292532 00000 n
+0000302088 00000 n
+0000293179 00000 n
+0000293320 00000 n
+0000302327 00000 n
+0000303349 00000 n
+0000303552 00000 n
+0000310518 00000 n
+0000304030 00000 n
+0000304154 00000 n
+0000310755 00000 n
+0000311626 00000 n
+0000311826 00000 n
+0000312872 00000 n
+0000311903 00000 n
+0000312002 00000 n
+0000313109 00000 n
+0000313728 00000 n
+0000313929 00000 n
+0000319287 00000 n
+0000314337 00000 n
+0000314460 00000 n
+0000319525 00000 n
+0000320333 00000 n
+0000320535 00000 n
+0000321909 00000 n
+0000320613 00000 n
+0000320715 00000 n
+0000322145 00000 n
+0000322761 00000 n
+0000322960 00000 n
+0000325194 00000 n
+0000323138 00000 n
+0000323243 00000 n
+0000325432 00000 n
+0000326098 00000 n
+0000326300 00000 n
+0000329004 00000 n
+0000326507 00000 n
+0000326616 00000 n
+0000329243 00000 n
+0000329931 00000 n
+0000330134 00000 n
+0000331175 00000 n
+0000330211 00000 n
+0000330310 00000 n
+0000331413 00000 n
+0000332034 00000 n
+0000332236 00000 n
+0000334423 00000 n
+0000332378 00000 n
+0000332487 00000 n
+0000334662 00000 n
+0000335326 00000 n
+0000343725 00000 n
+0000335529 00000 n
+0000351178 00000 n
+0000343989 00000 n
+0000358574 00000 n
+0000351400 00000 n
+0000367265 00000 n
+0000358796 00000 n
+0000375071 00000 n
+0000367542 00000 n
0000382460 00000 n
-0000391210 00000 n
-0000391299 00000 n
-0000395968 00000 n
-0000396606 00000 n
-0000397393 00000 n
-0000398095 00000 n
-0000398198 00000 n
-0000398236 00000 n
-0000398364 00000 n
+0000375327 00000 n
+0000389675 00000 n
+0000382700 00000 n
+0000391450 00000 n
+0000391539 00000 n
+0000396208 00000 n
+0000396846 00000 n
+0000397633 00000 n
+0000398335 00000 n
+0000398438 00000 n
+0000398476 00000 n
+0000398604 00000 n
trailer
-<< /Size 769 /Root 767 0 R /Info 768 0 R /ID [ <FE5FA4FCCFAC49FF593A803DB9EC9696> <FE5FA4FCCFAC49FF593A803DB9EC9696> ] >>
+<< /Size 769 /Root 767 0 R /Info 768 0 R /ID [ <F8F6D5173C0989FB25C367E1C4534D02> <F8F6D5173C0989FB25C367E1C4534D02> ] >>
startxref
-398912
+399155
%%EOF
diff --git a/macros/luatex/latex/piton/piton-french.tex b/macros/luatex/latex/piton/piton-french.tex
index 940903dc77..5a2bcd4523 100644
--- a/macros/luatex/latex/piton/piton-french.tex
+++ b/macros/luatex/latex/piton/piton-french.tex
@@ -223,7 +223,18 @@ composer un fichier externe.
Il est possible de n'insérer qu'une partie de ce fichier : cf. partie~\ref{part-of-a-file},
p.~\pageref{part-of-a-file}.
-La clé |path| de la commande |\PitonOptions| permet de spécifier un chemin pour le fichier à inclure.
+
+\colorbox{yellow!50}{\textbf{Nouveau 2.8}}\par\nobreak
+
+La clé |path| de la commande |\PitonOptions| permet de spécifier une \emph{liste} de chemins où sera recherché le
+fichier à inclure (dans cette liste, les chemins sont séparés par des virgules).
+
+L'extension \pkg{piton} propose aussi des commandes \colorbox{gray!20}{\ttfamily\textbackslash PitonInputFileT},
+\colorbox{gray!20}{\ttfamily \textbackslash PitonInputFileF} et
+\colorbox{gray!20}{\ttfamily \textbackslash PitonInputFileTF} avec des arguments correspondant aux lettres |T| et
+|F|, arguments qui seront executés dans le
+cas où le fichier a été trouvé (lettre |T|) ou pas (lettre |F|).
+
\end{itemize}
@@ -760,12 +771,12 @@ La clé \Definition{split-on-empty-lines} autorise les coupures sur les lignes v
lignes vides séparent le plus souvent les définitions des fonctions informatiques et il est donc souvent judicieux
de pouvoir couper au niveau de ces lignes.
-Quand la clé |split-on-empty-lines| est activée, le travail effectué va en fait un plus loin : les lignes vides
+Quand la clé |split-on-empty-lines| est activée, le travail effectué va en fait un peu plus loin : les lignes vides
successives sont supprimées et remplacées par le contenu du paramètre correspondant à la clé
\Definition{split-separation}.
La valeur initiale de ce paramètre est |\vspace{\baselineskip}\vspace{-1.25pt}|, ce qui, au final, correspond à une
-ligne vide dans le PDF final (cet espace vertical est supprimé s'il tombe au niveau d'un saut de page).
+ligne vide dans le PDF produit (cet espace vertical est supprimé s'il tombe au niveau d'un saut de page).
\medskip
\item La clé |split-on-empty-lines| peut bien sûr être insuffisante et c'est pourquoi \pkg{piton} propose la clé
@@ -948,8 +959,8 @@ def fibo(n):
\end{Piton}
\vspace{1cm}
-\index{marker/include-line}
-La clé \Definition{marker/include-line} demande que les lignes contenant les marqueurs soient également insérées.
+\index{marker/include-lines}
+La clé \Definition{marker/include-lines} demande que les lignes contenant les marqueurs soient également insérées.
\begin{Verbatim}
\PitonInputFile[~emphase#marker/include-lines@,range = Exercice 1]{~textsl#nom_du_fichier@}
@@ -992,9 +1003,6 @@ structuré correctement!):
\indexcommand{SetPitonIdentifier}
\label{SetPitonIdentifier}
-\colorbox{yellow!50}{\bfseries Modification 2.4}\par\nobreak
-
-\smallskip
La commande |\SetPitonIdentifier| permet de changer le formatage de certains identificateurs.
\smallskip
diff --git a/macros/luatex/latex/piton/piton.dtx b/macros/luatex/latex/piton/piton.dtx
index c8f13eabb5..c40a3c8631 100644
--- a/macros/luatex/latex/piton/piton.dtx
+++ b/macros/luatex/latex/piton/piton.dtx
@@ -72,12 +72,12 @@
% \iffalse
%<*STY>
% \fi
-\def\PitonFileVersion{2.7a}
-\def\PitonFileDate{2024/03/30}
+\def\PitonFileVersion{2.8}
+\def\PitonFileDate{2024/04/14}
% \iffalse
%</STY>
%<*LUA>
-piton_version = "2.7a" -- 2024/03/30
+piton_version = "2.8" -- 2024/04/14
%</LUA>
%\fi
%
@@ -211,8 +211,21 @@ piton_version = "2.7a" -- 2024/03/30
% It's possible to insert only a part of the file: cf.
% part~\ref{part-of-a-file}, p.~\pageref{part-of-a-file}.
%
-% The key |path| of the command |\PitonOptions| specifies a path where the files
-% included by |\PitonInputFile| will be searched.
+%
+% \colorbox{yellow!50}{\bfseries New 2.8}\par\nobreak
+%
+%
+% The key |path| of the command |\PitonOptions| specifies a \emph{list} of
+% pathes where the files included by |\PitonInputFile| will be searched. That
+% list is comma separated.
+%
+% The extension \pkg{piton} also provides the commands
+% \colorbox{gray!20}{\ttfamily \textbackslash PitonInputFileT},
+% \colorbox{gray!20}{\ttfamily \textbackslash PitonInputFileF} and
+% \colorbox{gray!20}{\ttfamily \textbackslash PitonInputFileTF} with
+% supplementary arguments corresponding to the letters~|T| and~|F|. Those
+% arguments will be exectued if the file to include has been found (letter~|T|)
+% or not found (letter~|F|).
% \end{itemize}
%
% \subsection{The syntax of the command \textbackslash piton}
@@ -1002,8 +1015,8 @@ piton_version = "2.7a" -- 2024/03/30
% \end{Piton}
%
% \vspace{1cm}
-% \index{marker/include-line}
-% The key \Definition{marker/include-line} requires the insertion of the lines
+% \index{marker/include-lines}
+% The key \Definition{marker/include-lines} requires the insertion of the lines
% containing the markers.
%
% \begin{Verbatim}
@@ -1046,9 +1059,6 @@ piton_version = "2.7a" -- 2024/03/30
%
% \label{SetPitonIdentifier}
%
-% \colorbox{yellow!50}{\bfseries Modification 2.4}\par\nobreak
-%
-% \smallskip
% The command |\SetPitonIdentifier| allows to change the formatting of some
% identifiers.
%
@@ -2757,9 +2767,10 @@ piton_version = "2.7a" -- 2024/03/30
%
% \medskip
% The following parameter corresponds to the key |path| (which is the path used
-% to include files by |\PitonInputFile|).
+% to include files by |\PitonInputFile|). Each component of that sequence will
+% be a string (type |str|).
% \begin{macrocode}
-\str_new:N \l_@@_path_str
+\seq_new:N \l_@@_path_seq
% \end{macrocode}
%
% \medskip
@@ -3546,8 +3557,19 @@ piton_version = "2.7a" -- 2024/03/30
language .code:n =
\str_set:Nx \l_piton_language_str { \str_lowercase:n { #1 } } ,
language .value_required:n = true ,
- path .str_set:N = \l_@@_path_str ,
+ path .code:n =
+ \seq_clear:N \l_@@_path_seq
+ \clist_map_inline:nn { #1 }
+ {
+ \str_set:Nn \l_tmpa_str { ##1 }
+ \seq_put_right:No \l_@@_path_seq \l_tmpa_str
+ } ,
path .value_required:n = true ,
+% \end{macrocode}
+% The initial value of the key |path| is not empty: it's |.|, that is to say a
+% comma separated list with only one component which is |.|, the current directory.
+% \begin{macrocode}
+ path .initial:n = . ,
path-write .str_set:N = \l_@@_path_write_str ,
path-write .value_required:n = true ,
gobble .int_set:N = \l_@@_gobble_int ,
@@ -3682,6 +3704,7 @@ piton_version = "2.7a" -- 2024/03/30
{ \@@_error:n { Invalid~key } }
}
% \end{macrocode}
+%
%
%
% \bigskip
@@ -3694,6 +3717,8 @@ piton_version = "2.7a" -- 2024/03/30
}
% \end{macrocode}
%
+%
+%
% \bigskip
% When using |\NewPitonEnvironment| a user may use |\PitonOptions| inside.
% However, the set of keys available should be different that in standard
@@ -4243,22 +4268,44 @@ piton_version = "2.7a" -- 2024/03/30
% the environment |{Piton}|. In fact, it's simpler because there isn't the
% problem of catching the content of the environment in a verbatim mode.
% \begin{macrocode}
-\NewDocumentCommand { \PitonInputFile } { d < > O { } m }
+\NewDocumentCommand { \PitonInputFileTF } { d < > O { } m m m }
{
\group_begin:
- \tl_if_empty:NTF \l_@@_path_str
- { \str_set:Nn \l_@@_file_name_str { #3 } }
- {
- \str_set_eq:NN \l_@@_file_name_str \l_@@_path_str
- \str_put_right:Nn \l_@@_file_name_str { / #3 }
+% \end{macrocode}
+% The boolean |\l_tmap_bool| will be raised if the file is found somewhere in
+% the path (specified by the key |path|).
+% \begin{macrocode}
+ \bool_set_false:N \l_tmpa_bool
+ \seq_map_inline:Nn \l_@@_path_seq
+ {
+ \str_set:Nn \l_@@_file_name_str { ##1 / #3 }
+ \file_if_exist:nT { \l_@@_file_name_str }
+ {
+ \@@_input_file:nn { #1 } { #2 }
+ \bool_set_true:N \l_tmpa_bool
+ \seq_map_break:
+ }
}
- \file_if_exist:nTF { \l_@@_file_name_str }
- { \@@_input_file:nn { #1 } { #2 } }
- { \msg_error:nnn { piton } { Unknown~file } { #3 } }
+ \bool_if:NTF \l_tmpa_bool { #4 } { #5 }
\group_end:
}
% \end{macrocode}
%
+% \medskip
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_unknown_file:n #1
+ { \msg_error:nnn { piton } { Unknown~file } { #1 } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\NewDocumentCommand { \PitonInputFile } { d < > O { } m }
+ { \PitonInputFileTF < #1 > [ #2 ] { #3 } { } { \@@_unknown_file:n { #3 } } }
+\NewDocumentCommand { \PitonInputFileT } { d < > O { } m m }
+ { \PitonInputFileTF < #1 > [ #2 ] { #3 } { #4 } { \@@_unknown_file:n { #3 } } }
+\NewDocumentCommand { \PitonInputFileF } { d < > O { } m m }
+ { \PitonInputFileTF < #1 > [ #2 ] { #3 } { } { #4 } }
+% \end{macrocode}
+%
% The following command uses as implicit argument the name of the file in
% |\l_@@_file_name_str|.
% \begin{macrocode}
@@ -7839,6 +7886,13 @@ end
%
% \verb|https://github.com/fpantigny/piton|
%
+% \subsection*{Changes between versions 2.7 and 2.8}
+%
+% The key |path| now accepts a \emph{list} of pathes where the files to include
+% will be searched.
+%
+% New commands |\PitonInputFileT|, |\PitonInputFileF| and |\PitonInputFileTF|.
+%
% \subsection*{Changes between versions 2.6 and 2.7}
%
% New keys |split-on-empty-lines| and |split-separation|
diff --git a/macros/luatex/latex/piton/piton.pdf b/macros/luatex/latex/piton/piton.pdf
index b0f5aca15d..e304fb1611 100644
--- a/macros/luatex/latex/piton/piton.pdf
+++ b/macros/luatex/latex/piton/piton.pdf
@@ -536,28 +536,22 @@ endobj
<< /S /GoTo /D [ 309 0 R /FitBH 771.02165 ] >>
endobj
314 0 obj
-<< /Filter /FlateDecode /Length 3602 >>
+<< /Filter /FlateDecode /Length 3603 >>
stream
-xڽˎ·ñ®¯èã
-²øÖ h4Î)¶n¶†ƒø8@Œ
-J$nä%óoð­E¢à\žœâú+}BiÄæ˜7†À6-JXÙÍpË„ÈN‰
- @+²¨**3–V)ä`•nÏ* ,qXŽG»6¹C¨—LÁ
-±«Å x²¡B žD’ˆx^>„a¡Ë¯Uó:Ž\’µh…“è&ÂK}žHBàN‰šdtaÏ
-™¥LÎ’u,Yé#õI„Õì’Ny4q1\»ö¾B¨’É3A&Ýš‚ù±Ïc³¬‚á†'ÊÆñâSy’0—áÕW+|šCÒ—(%ù1E¯øF$ÝGl<êYŸ"Ž #ÞXÞ@A¼øÜ‹3ɦ¬ ’õc`ÇuB¡+5Öê¨e˜ÕÕö’Ó©TÄñ/ªEŠF-Y¸³ ½yt60jóë`ÕìnHX"#§wŠÝ°¦R‰á×tž/-´vvžtvaõ5»(sª]4žóû¯[¼øî"×l†y+îb·“Lj«cZšF‹'g{Ì‚Lk50V;‘M§"|r‘8â(¬8}VÂÛV"¤‚Y÷!%‹ëZÐ óšàÔ†¢dƒ—֔ܗ#hP®Ó:1BOý"šÅ§m4sÑ,B¾ÍìóÌ2E%²¨òˆÞ’¨PimIô¶œ(ml9Íjl9Î$ÕH;¿ï#4ˆçö4XˆÜDeG/¯dÝÕª•+«0aƒQ¥aδ¹ª]ê–0Åã%ÊÖL ÈqAKÕý"J¬áq1™qµd¼¾ HOj)þј ùJ+³(&’Ì>ŠPŒÒÈí;%‡úf_õ@à|ˆYr»?
-\¥lËÞO…æL`þÜâÁ.5Æ1ㆹV%ÙÞGˆBÎÀ2Õ&û¬jVþ¨À¸]èP~E´kÑZRuãVÿDkMëND¹ETÎ3´â9íMÑ”çhQÕè1å3f\Ø1uUƒäšl!ÏX±Á·lÇÁûÙѱ;ÜØ)?²¬xüA^ªšÃ¯I}ˆ)b@«Óžýá.‰…‹:×JŒ9Oàò~‘©"¥rxÚB“[„72ÇeèdÓJ±0Üöîä‚0ä”Ky-I#
-Õáš4¡B¡¼Üå¼|ÓaN%W¹vH4›#¯ë¾$¶ •õ>–<z–g|Iš¾®òo(í8N§é.»kNˆ‚æ]'Ñ´Þ&JN›@'Ûv–£|ri\ˆ™6fäòÎdŒg&(½6º=àŽÆ“†"å¼z}Y˜Oý˜r@±æ­dÜú‰.­¦çŸÛ+Þ3ãÅ$+—rpÎþ åóõ&äôö Q@qÄ·Iyáø4d÷k.q$.@0B2¶ÐåpT¢Š.‘¦:W3 Ó\uj–ÀKGE™N ÕÖû¤!¤`ÆNð‚—&¯ÉÉTÒúU¹à×á™Âl߯ÓJNšjSiU‘ö&Ú¼ÆtVŒ@²ðPK<©,]v*KêîçÖCúýHn;©.‹º‡@y.*8×™LÒ¿mü([¿j)ÕÀ´7#©r˜%Y§ío¸ìæÚR)˜ú5W†T'ÅP"–²â^’…jÍ"þªDúêM4 { Ò¬>×_XcöNûìîÛÑ óN´ÏrÆvB6FÍr®°â¯×¦R @››l8‰c¿æòábìÁ†ÓxÛœ¬ÄuN©b:ÑÎËôÈ~—7Ÿ*¼œÈ¬`‡1ç›Cr Ú°Vîá¢éÁV »‡4…qß/´öšžÓ
-˜z½]R2#ÝZ{Ò&BN¸xsVvΛÏÛ´›–ƒ‰ú‡,5q¹`+¾³TÄÌ`½A¡Çì—¥Û(®ÂqÉ0:FçN«¦æv&&
-{ဣüÅDÁ%YJÒ,œªfóþÎò
-ÛG¹{bZ”qoszØeGìÉö>Sù¸Ø“#Â@íù8"ŒÝ{”Å$hš;|/˜<³½Ž=¸ ²`ÿ˜Ø3àz@왩o÷¯ÓnJ@Gæ}áN•
-ƹ§µ¾¬cV-tñ.œdÞºö^$u¸·ân%×+ÑôX€ë.&m#\ý=Qñ8ØÑÓ‰•@ÍL£›<¹÷ð–Ù¦âº0eÜÆ´„-ºHwÿÝþW½ì%ÆÅÃK:*'+—ð…'¬ŒoÛoE0ÏÄýF.Z¯-Ü2®DGËÓÏ¿ÿòŸŸÿõþƒ}ú‘kžÊ$_ΗŽáâØMÿßûCŒŠ*¢T?ñˆ÷
-‰|[é—TXûôUšlìê£.\qOaî/•R2’ùõçwÿ^ ÅõÎÈí—ßÞýð¾ùþ¾%#÷nûoûÛ¦pñxõÏíûwUeÆìá×x¥Œ¦ýïO½¥ß~›k>%I˜¾ÙX4îAÍAT/ÇrÆí U=Þ'~LªUÁaG÷0w~z—l ‡ %éÜNh>N}Àiæ„}“Ôg€SŸôÍèžÔg€´\þ*gn oyoýÔ)nÄüé,iÞ¶ÅDk¢ö¦Ô)¦]ÃÜm[’ŠˆïIŠ\ƒë]Õu–ÌL±ª‹]R5ÌNŸRŽŽâó–k›l’T´‡z»H°F¼&MùÐdå…ê~6-—!-Ù;'…ìèÛ-þÍ< ˾§Gû}/È2Ÿ9xÌ–6%­ü”*^Kxc
-;r³£»””Ž£ÍCޘ°Rפ7måG¾AMÞø:ÛINg±Ü”a :&ŸðœÁC:h˜$ºæpÕñ6ÒLÛˆÉgnÚ‚ÄmÂmš· oa¡@¥›JÞ*O-(‰G§*–WR¢-úŠ¼ÃW¨¬ßPRý%&j}A½bü o•i(¿Ôoc£Î1íÌ—Ù¨ÇE˜[mãÒ¼c£Ãª'-óÞü1Í€ëõÇ<+êá†"iÚÆŠæ¨íTŠ¤UªÈå¨õô ¤&ÛR¯+¤¼¾BZQëKã J¤µð#”Rë¨,5MM7NMS˜NœhknÂ\*g±Ïõ´"´P„qöœkdn,kÄ%ÄØëüÆöœ¬ÃR³³
-»n„zk‰!mƒ€o¤©V²Ó„›Yåg¨z¨¦ ò]WëÎ2>®¼Å¤ÛIx°l“`‰µu¨+·TÛ1nUÑ´·™Õhûf„ ª?åªÞµãY;>áP«z¢<×7•Ú9c'~2})¥» “uƒé ãv¢æµ6ž‘á@M.n Ê€¶By&;—-öR
-û*"0;*X
-±~ÒÜ[Z•WÌ(=²xçÒšìó0åìn£\*&-Çñ£]–òÚ¶O&½†¢Ùó¢°Xæö;s®™-¾¶”•ÚQƒ¤ôˆ¿-ï\S¦lþx<~n(æ\p”f™G*®ìΓðBÇñI¸°¨,!ú³pe7$«»Q‡@qÛ-„gN‰©iYË 3JË©o¶)È‘ÌböM}°¦®ìb}ÁÔsõ»äÏõ{[Ï­›†Ë&¯
-!®©P§ø@”¢ÕK‹¥Ø¸ž×ÂÒ…o£' Ö›SZÌU²?­j™rˆ_ P7ôyÈ®w¬ÅNìÕ%Ø›Î-©QTk.áÒvp ôçY]ã4°¤ûñ:·Z—æJ+vì†ê§©r šª?x¹Ånp·¡š6œ¾Aðƒâmiy¼#m(Þõêù¹Dñ¾P¼Ü7g¹\_…ÿ3à¨Ì>bm— ˆ½m
-#½ÄÖ´£¢û4¯Üå¢{(ïnbÈ©_×ÙŒ…•HÑpé?HDŠÞ¢õó~¿‚’¶©Ð1/qeÊ!up4ãTG–FÇS‹çPÿ¸÷Œû³žÚ´Ëáé›Ô?¶|õb{’Yù
-ÐYÌ þWr­
+xڽˎ$·í¾_QÇY«HõÆlo» 8§Ø{³}0ćÄbH>?Ô«$±TÕÝ;=^ 1õø&Eª¨•Ë¯‹\¾y'ËßÓçw¾€^”  âòùïq‹Z@£Ð~q*Ð;¿|þmùáYJë¥ÔúÁË-ž”R}’N/`ém¾×§4ê§ÏßF8Å¡Á
+Ä ’ºVt}.`4,J‰`Œr+…vq`Z“À<ýHèßçi¨¦ÓÀ:¡ƒZ J*v‚&'ö;F¿€{Î,é:Òé‹,ÖgÎÍœFÐVÐÄÅ:+´[YÕ®IÏtK’%8hc’´/Y4éç3+_®ð«5,Ö€°!TÔ)“@˜jl¼GBˆ 8×'–ƺÿêPÐYµx¬%ké±9’.ºÅJ+¼S=6Сè7bÍæï+D9ƒ¨È„éɾPë©I*ÍLÒ…)'é!G±k;„-¦P"»F½@ˆ&S‰ø(’Ê@Æóò! K}}Ýë:8sMÅ MŠ7^ùêÄ(䮪¼X\%+Àˆ ¡©(Å9‹¯‘Ÿ®"×™€íR¥TMGÆÄ-|,V|ÊXÒ[™„nµr¸¬ F§™è’ÔW)Kdd‹qA Ã*åè)UW:ÂÀ2}Ñ]Ca3»¢‡S9¨^˜®}ß 4ÉÔ™ ‹níŠùœ±oÇVY%ÃMOÐåñêÓú¤`N.S\%þmðãœ(}MRÒKèÊoTÑ}Æ&³žÍ)ãH2’å1
+òuÂç_¼-6åtÂP¬Ÿ¢:-H®ÔY?©C“VÐ
+£`µ}Â@äÈb* qþKjѪSKîàlÊ,œ ,NÐ
+ëÕ4&8d1ÁíÆ„)¥½€à9ŽÝ 0§SY-À‡ ¥çÎQWjÓHOÓpæši¬sšitÎóû¯K¾øî›H¯]¬N{3Äo¯…6Q²‘{×)2©Ä·”09·i¹S%Ø z‰”oÜ$8
+-Þ…–ô6…– iÅlÆ°Råu-ð¥y]€êÃQ±CiªÚ½›3h@?¨=2Ÿ†IDËOûˆæ"Z†|-¢¹ç-Ë1’ ª¢ªo ;L¡ËúRègÆ\(팹ÌêŒ9ÏŒªÑnû~ŒBÐE¡¨à<w¤ÁAæ&+;;z“0“evXZ<&&Lk
+elÀUš–âJ›oá*Ñ…·„*)…k Q5ç+º.`2U3®„€†ñFoÔÅVÎqÊy{Ã-Èlô²:HgƒÑYòXÝÙÅj#ÅŽáÓ¡䨭æ|ß);Ò8­'†Có!n- Ua#s,Y—»Ÿ#…¢€Æ ² °Kõùd‡EÀ÷‘‚Ä„`­®‹]՘ˆ!ÕW‘z£z{jÞÜ[A$¶åŒ­"A? ‡è½ðÊn3àTe Ú\­áÙŸµ|)Lcx‹Lt]âPgÌØÎà{¶óàýDéØÌ=x8Ë(ó/ òÒôœ~]™Š ì0í™ UËD.éÜ âÙOâò~‘á*¥xd-Ué)ÇHot Ï0È6 ÆÄ8¨övt!_êO½Iµ¾–-¤+Ýéº|¡A‰Iº¯Iú¦ÃìJÏï”q¤7Z5ø°f¹•í>®I5“UêÁ¬ÉÓ×M¡Ãe›¢ÜU­‰QR½ZÖÝBÈ©óäq[•ÉÅ{”VÓ‚,ŒµŒÉ;³j°Axà@FU ÕàŽº‹z2ݲ9ýº:ŸÆ1ëVÅNœwZH8Y6[ÌÈ=wWâ|6(.(_q)~6&õí&%öî A®ú¼|e÷Ä2ü9‹4’V`€¬[©ò4¨Ð/‰¢6Õ|*žºÕï2аNLû…¸ó>I(­„u\òÍâ,5•*ê¾*ªñhýÝÐWÍúu#©©u3©niweÁP.«Œ*8Ò,Ê*—ƒ²Šž‡©5Öj£Ä©Òª”
+ —Ãäzn°ò’’¯çfÒ´oìMÖ[ÄH±>½x°G°iÞu3qKjX6³ëªÌÙòäSƒWÓ–ì4æ|s.¢! Ö2<\4#Øfa÷†Fh3ÑÚkw‰I 6Þ•¢šÉÀŒºTà¸GD¤²Zq*Ãa˜ÜPtK
+.ÅRŠfáÔ4[«9'[(ìWô÷IJ(Dý61g„½ÖówÄžjï[*{jD`Ôž#§è–؃´FØÍ\ö`ã™ãèy졺½ÿcbÃõ€Ø³¥¾/^§Ý’rö}QiøÜÓ\_Î ‡]<‚ ¯EpžÃÞ‹¤žÒ4égr½Må´îRÒÆášGè)6}€‡=m"1ªôÉ”îòäÑ? 8a´¾Ã?Z¿ÐX²‹ ÷ßíÍ«^Â0¦,^ÊVк•rIvÊV
+Û"‚͆L®7jÓÐ|m‘Žjk5Ðòôóï¿üçç½ÿàž~”F–¶-§óµ´8Óÿ÷þ#ÆN(§õþ
+Ú–
+$g†Ó¡>¤oâJ…´ÙË+½8š$ Xߣ)¦¥FQ¢àOåVëK¦^»Ýµ|nßØûÖlÝq¸îòª⺎ôÿˆµMõÒcYmÜl¬¥'Q¡žÀ¬#!·§r~Y×y¥#¹#Ì„“04ŠKc×3æ"Q(ÉÖL=‰šÅ4ç.ýq F5˜Ž»+ù¾^×#Öë™J§vl&¶J+Iî +¾®ÙŒtBYèמîPà”}y¾‹‘
+HGª>e£NFí7=Û@å… l_¿Ø€oM«)i&{°ðÜ”^ÿÓƒjJŸº´ö¡%³&m¶dÉå¬U’í¸Õyýëø¡s)¼×lëèŠozOYõq4ïsE߯|F?ÏŽ• ÝÒú]½.½ê¦tkGw`¦Nh§ÚÞ€èâ™ÊÙ žÝ‰¤ƒµ©!.n9•¦Ö–
+5Š3v›éswPâÚ‰eª:1öt§ýÿ1ÄRVðÇQ(
endstream
endobj
309 0 obj
@@ -567,18 +561,18 @@ endobj
[ 310 0 R 312 0 R 311 0 R 343 0 R ]
endobj
310 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 282.361 521.872 288.82 534.163 ]/A << /S /GoTo /D (Hfootnote.1) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 282.361 521.633 288.82 533.924 ]/A << /S /GoTo /D (Hfootnote.1) >> >>
endobj
312 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 377.606 293.189 384.065 307.137 ]/A << /S /GoTo /D (Hfootnote.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 377.606 292.95 384.065 306.898 ]/A << /S /GoTo /D (Hfootnote.2) >> >>
endobj
311 0 obj
-<< /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [ 468.356 104.635 516.902 115.185 ]
+<< /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [ 468.356 104.396 516.902 114.946 ]
/Subtype/Link/A<</Type/Action/S/URI/URI(http://www.inf.puc-rio.br/~roberto/lpeg/)>>
>>
endobj
343 0 obj
-<< /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [ 79.37 95.097 202.6 103.468 ]
+<< /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [ 79.37 94.858 202.6 103.229 ]
/Subtype/Link/A<</Type/Action/S/URI/URI(http://www.inf.puc-rio.br/~roberto/lpeg/)>>
>>
endobj
@@ -589,71 +583,63 @@ endobj
<< /D [ 309 0 R /XYZ 79.37 771.024 null ] >>
endobj
5 0 obj
-<< /D [ 309 0 R /XYZ 79.37 562.837 null ] >>
+<< /D [ 309 0 R /XYZ 79.37 562.598 null ] >>
endobj
9 0 obj
-<< /D [ 309 0 R /XYZ 79.37 218.136 null ] >>
+<< /D [ 309 0 R /XYZ 79.37 217.897 null ] >>
endobj
340 0 obj
-<< /D [ 309 0 R /XYZ 93.716 116.866 null ] >>
+<< /D [ 309 0 R /XYZ 93.716 116.627 null ] >>
endobj
344 0 obj
-<< /D [ 309 0 R /XYZ 93.716 97.774 null ] >>
+<< /D [ 309 0 R /XYZ 93.716 97.535 null ] >>
endobj
313 0 obj
<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F23 317 0 R /F24 318 0 R /F32 319 0 R /F41 320 0 R /F52 321 0 R /F61 322 0 R /F60 323 0 R /F62 324 0 R /F64 325 0 R /F15 326 0 R /F65 327 0 R /F16 328 0 R /F74 329 0 R /F75 330 0 R /F77 331 0 R /F27 332 0 R /F30 333 0 R /F67 334 0 R /F66 335 0 R /F47 336 0 R /F53 337 0 R /F59 338 0 R /F71 339 0 R /F72 341 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
354 0 obj
-<< /Filter /FlateDecode /Length 3879 >>
+<< /Filter /FlateDecode /Length 4167 >>
stream
-xÚµËn$¹íî¯èE¢Þ€a`lHN æäd÷ì!ûÿ‡PJÔ£ªº=³xÜ]%QIñ-ËÛo7yûåéõûÓ_>œ¹)#´qpûþë“Âò¦n>
-íoÞIƒº}ÿýöÏg)Ý×—/JJ™>¾áH©áå‹öŸX|£=}s¿} ï”
-gÁë‹Vøݸò]¿æQÿúþWDFÙ[Ñ"µ"££À÷„Kè XÇÀ-ච(ƒûŒjZ"4Pö’vgÞO±TÎ qb›ð}/s‘ðýò%¿Ê[P’ Òø4ÐCÇCÐXãËø´Åô9ývá%Às™ïušè›I„Á‘¡¯’`zYˆ•Æ¤wÈq o/_|Ì$„ÂÓ‚G^é½Ð¢ó?KŽÓ9i~bˆ¡ÏmïÖVêz³£® EÑÌÔ uÁHÛ<e‘UZ(í& ð~ºr•>ðBÅA6 íß?Œ„%@éâ
-G/sW‰s`à´ˆ; ¤RÉ:<³ZWþ; o£tfŒëõFŸ´ï˜dy íM–”ò“%HÒ’ï´‹>~8Yˆˆ tºQ—)­U~å ‹Q@„®ÌÒDü¦Ô’ø&Ô²ù`Búú'ª5Td"D·Óke×\¯…õšöÂx˜×xX±vA
-¢™—ï…{Igr/ àÔ%%×&äñU°N :˜3Šh§ÛL3|ævTÀçþ”ÚJá´^èYäo⫳(‰MÜŒ*‡#ˆö™ŽI"“Ÿ$ ‚cê2ѨŒ![Þ¯3ÒŽÒI3ó9©–t¡~Þy[œïÌ‚ît˜wMf'Ó7ó¿ZCyJg<¦Â.À²™hmÃÝÑ&wDAÚÝ‘üUÚÙ"ƒ>Ëà1ý{Y–”[å“»¤Ø*LÅ¿­ÐO êFž,*íèù>Ö
-I‰3“r À‰f`ùí`‚é4ŽPfj» MåphŠ&(Ÿ• Âo MŽ”v0ëtGfÏ4­š­÷‚IúžÞ”9ÐSQg¯rÂâQ=µÒ `t¥«¢Ë¾ûÌ]ÛwL¨Ð¡ûLƒÂýF£¬Qºü–§#=»)(0u“pÒì;©6h[L;â BÖb•‹4£–ýbŒùé6Ò;°bòØ)À‘"$#9BÉÞ‰b*ÉÑR®’ic»W5¶ºñ¾ï!ÂÝnFƒJÇÙMr¯ÍM‚¯Ý‰DðúHØDùµ²ú½û­y/yy´/P¤s·[e£Þhn~“)ÐNUòº²ÌDébˆÓ¨´Oå‘0
-eö]XTˆúASªpvÙÁ£i Fq†’UÚ{f
-¦î%ë: Ó­=;Ñ’“î”}E—œ²¯ ‘ÂL+3±tñû¸ le»âÕTg3¿M©KZãkòß KZÓªslЇÐÎè×v€,éþ9œ)š¿ùª_+郼™¤d5Œ^· ®c…•=dLŒ‹¶Tcˆ2#8*?£8* ?ÃŽŸ]„2%kö)tËÏ ÓUPãô1Ž»8™D¢×¾`s=I³©}j8µQB©…†å òï¶Æ¹!ô^x­&hêÃ,TÍ:Ìs:gŠrÇþßnåÃ?~éY …ª
-3¦.Ñ¥Äà²æÚÚ °è.©…Ç»Â:t­Œi‚
-Ü Û"îƒ%¦÷È|ÐLðoÎDíòGÇv¿—ä†pmŒ³ŠL®µ+á —_è
-·Ç/i¨gÞIùFJ–|ÚZ¿Ä:uι ((]«ÀšýÊ2w¿&éÎ&¼]K«‚z$aò"æ6iÊåΦô[Àk0üˆеJÙ“qÝHVï0…çj·i?`è)›7ÒåíŽdžEý<-‹g~%’ìiCŸ’»ðÚñŒ ‹1ÄáþH¸` ÝKÐ,êDbV
-ð•G
-³xç-Ï*_,¥Ҏȶ3õzšvh•ƒž1H‡'Ûoû”Zz~é~ãÁöùA%"AÍXìeJ€£¬3—Ëò”œ^ò[:Gû9
-­¨þûØŸ¥Aõ#ŽV·"¹‹c¡i˜«àá¾XÖx*®±,«c†9>m‰õÜEÁ ùþRÂ(ù~OTãíÐA <å ¯CZƒv.H½­HýƒPíDða^ãáJª»…RiV’Í\ÛÑc½["‹V˜Y$‡ÔUýFi6mDûØè·=}é­iÞ[]µ±;EgKýywÏ€Ãø!"˜‡Ùa,F>F-ò–ö8sûIl¢Š]Ž»v©iƒÎJ0žÇi§Ø³s»"°ÆÍPr‰F?\¢QÆãhÜ•=ŠŒ>É/Hü
-qÁÿÀ©4ä\òä‰ë–ãÂéEYÄUì¼Údÿ¢B’â …ßßr%Ñz÷„&lŒcñÿ_ž¾}úËžJ ­T|Ñÿþ”^
-"A×cTmÎbQ=9B±Wv˜3AþPr䎶6¾ÔѲ9Í{JTÞ抌¬¿}MóHaðÇ¥4Qÿò¼«ƒ§ËƒyWsž>:Ì (&ºŠ«³EÈ£Nõ#K^i<³Ö¹[Jm“YÚDt°ã a¤iÇæa¡£$À©Ã=wî¡—‘N8£Wzµ¦)túw›gî_ A1 WåA2Ä2úª}‡ÎƒwBFsÜ9â è£nˆ GþPbâf‘ëÊ{PÝÚŒd?u¤®XZÔÔÏ5³ZiáÌ»þ„[¤M:IÕ‰Éú”bmÍL°Ifñ/R{8²ËÚ:¡\¼0Ìö.‡lïlì€
-ÃD!7}’ÁÖA8™¨åQ °×A#43o蓾
-²5ÍÑ„S}b+ –åÚâšYžg-‹À”-ã›Ó™Ý[j˃æÄeGÄ#KMA”Õw(Ïç-å%(ßPŠ3 Â6nÊ ÛnY
-_Íì*¹çµ[­0’vË^tlI­˫ѨªeÖ]Õb;4ÿzYQ8×^`¼±¬´÷($ò᣸‡õ§¡¾ÒÈ
-V©ð` ¯Rì1âý'%M %Àâ²ÚY{;?:½[‚GÖ­<½éäeîe„—1÷Ð×°¹·ÕŒ-§µšóÞÑI&H7@0ÂèpTu'‡ÿUþ0-çoZè›ãŒ{c¾é«æ ýâXj+œ3¹thoûã‰QDTó¬ÞzqŸJpèê¢ã=A±Iâ~ݵ ?Ï8„‰a#û`ý^ŒÆ®#ÌFëbrÎ3uð‡@eºYj¼åÉgó²È ð0¯ö“'’vNË™ÐGÍTž
-e{éL”O%ëS*TÒë„YIÅÏG_ÇtŒ×«*™{úUº>Ki–uºþ9š[—îžL‹ÝcX%TöÖXýñèí!
-èÇ-¢àÍTôU[ãõÆ.óóõ¦utm…ËÁ,/Ö)”.ªÚÂY ¢õ¶™ºæòhvP5¾ÑŽ¨ã‰«zàÛ1صŪˆú’µÅžÈžÉVÓÛ9Z:
-‚ŽCc¼VWç²4F}OP^Fé·–Õa 8t ¨ †È7)HäÎ
-Ù¿éPsÇõTí¬ðÁ,D<©QØÐ.‚=ZhgèvÄý“…Ò*•À³Œé¸ié X]ò6R‚
-9å¼IÎNsP»(4(rþò§ãc’F\FïaÈ+„%z¿c ŵï„Ï&ªuãü‰RI¼ä ³s¿Â¡™ÅÀn†’Ü˨w}uAñfG£¹?/ÈC^­Ô¸ãDn¤Å›!¼ûèYrÎ]Štv×A—Pªí1iY.ˆJcÜÄ]
-¤SÞt Q”z»ø+.ÿí‡aÒÐvýwNrâÆÿµÇwã9H•©ØBâÕ¿*7¶–ÎɵG±â?5“pp¥9GN—­Ë“%!5<eð4ÛX;E`ùéz÷o¹hu0n¾¶²·D£\W®E.˜¥Þ£õôwx.Ž_
+xÚµ\Éne¹ Ýû+ÞX‘¨0 ”írÉ*ÚY5Ò½z‘þÿEHIÔ|着jû½«¤(òp¸–—?.òòËÓÛ·§¿}:sQFhãàòí÷'…äE]|Ú_¼“"uùöçå_/Rº/¯ÏJJI¿¾ã?RÃë³ö¿±øD{þä"~úž)΂·W­ð³qù³~K£þýíïHŒ²—(¢$j%FGÏ™–Ð6°2Ž€?ÚÀm7PùŒjÚ‚4y!îÌÇ)•Êy¡!N‹¤&½Y`.2½ _ŸÓ£Ä‚’Ý ÿà“zhtèOk|O,ÒïôÓ…×
+áEw‡­ñÎ¥X0B¢ج|u0Aºã*³´ÝKåp芦UÕ ÂoV›€”v0ÛtÇnÏT¼VÜÖG¦„>ÓóA2v*ê„*'*îµS« 2E×lUt »Ï§kÇl²ª³O2ȧ_e”,JÓßüí(Ïæ
+òšºj8[öVxö•:U¬Ø å¬ÍheŸ1?ÜGz'
+3­LÂÒ÷õvd°•Yí2ª)`3=¥ÀÔ‘ÕøBø©ä½ñ2­6ÇÝg5àK½@–mÿÎdË_±ê—"ú /†–Ò0¢n%<ÜÇ¢Ok–—.^ñ¥Z ©žŸQ=)Ëy†Ýy6sò”dÙ§Ð-}o:[%Nã¸+7“EôÖ6¬Ð“-›úÔ§ŽS%”Zä`º¼AúY÷8w„Þ ¯Õ´šú4Y³T“ 󽜓D{`ÿ×—ü˯¿´¬„ÂÛ¥ÂL©#¹ä\–\[á’ZÎxBX…’¡**ô~€!l¸K F‡Þ"óÁ2Ýq~s&j—8º¶{^†€¶½=ÆyÙ¸v9€é5šÉm õ>ÉŸØÌ2ªaæòø%Ú)sÎ@&隸òZ3²Ìs÷{²õ¬êÛìÔá…°
+e¨g!’¤C˜£X²–;åΧŒóÁÍ»t4²L Ù–Ì—qÍUœw˜Èó
+mÜÂËw8|ÎêÍÒy¿!­g¯Ax\ ¢_S ¤‚ÚðoäÊ®Àw¼ìÂbð0¸¿Zà…‘5¡ÝkÐ]ô‰Xb66tdN3¯ð Ç?Ùéš—fÕû[œ^‚Û_†tØ°%«×oý·U1s ÑY‹í³¾·r•Ö^9YÄLW2ý%LÍfáµ!É’`ßX@Wç+u\n=±¦§jÀ—>Hk1›¥×|«|µœ~ ŽØÇwFö4íÐ;=S@w'ùŸ¯ûÔ}~íƒîóûfD‚š©Ø_ άs,
+gÛm:;à
+äc•RiÙøï`dû6 ®#õdµq+‘»xª…¹DÜÓÃÓvõÌ0Ç©5¢^š*¸!ïŸK9ïïYj}f{\è žr‡×C[c©^ ÛŠÔßY ÕNæ=î® ‰°ÛUŠÌrRc’™«°<漆"zÕ
+óÉ!…U>±Gš]Ë>Vùmo=5Õ]ëqS$q>`©}œÐ«ÁÜ}ÆbdÔ²RbiOsï?ù˜¸r—â¯]ŠÚ VÑÁõñ¯“ýÙ¹_‘FXãæUR©Fß]ªQÆã—Õz0{!=x^@çâBÿ¦4Œ-û$Škžã
+èE]ÁØy·ÉÿE…"ÅA&Ô¬ä{*é/fï–EŠH-þÿ—§¯ßžþ×¥Qi ÜJy¢½üöç=
+Mÿ]æŸI†ûGCnУDÌrªò /ˆv\/£¯uòð}@çôq‰ƒlŽš+ΊËŦÞ1ö&f׆#Ù.[«.AÈVêÇ:Z­´p&¦ÀEÚ¡šê}JµÖ¦&Ø$µÇx©/V{8òË™6þŠ_¶7²=Ø:ö×­… H‚]eñ×:'IXuñw4®ff†Än
+49' ]j
+¢,À!?Gh”—à|C.ÒÔ¶qSZ2tìæ  ™ƒZ+/OúsÎ+ÏçœÎÝ •ƒ0‡<ÌÓ$±·MM Ím}X‘eÏÚ_ó¸ckWÊN°VL-̧¿?M×Pû¾›"Ù_3½ûËXJj>Œ§6T`nÖR½n-ØäíëµËÄpòù£õç%ùù:ó~ÓÇ$Ê—FQ­V×Å;Ž” nêÁý¯@b*€L‡õhœËGJ˜
+ŒãÒ÷Ýw¤”)sËn?¸ïCË(œr‹¤úÁ|ãdö·Zµo_±Â[5oÀ1Sy- „–ú\ìã1Î4r—MT>¿=®Þ¼¸:®Óø=º®Ü·µ¼Ôܺ/ÛK.çjªBÂ6óìŸãUŒ"„0ïvû[YÐU™ek?ÖŸÃZSïvm©Mi*lÛÍÖ;4S0'±Ùqvïˆ-N€;xûJmœpŸLRLõT4­žìŸϽõÔ¨†aó*kG§šª¬þ¨Êª—PG«EƯÏc/mµ$‡ØP«Ü± …´ ¢cõñ~tˆä¦êÄ÷ã!Å槥RÔ ܲãÇ9߆
+\Nÿ(¾ ΄D~ßÚóMFÀ¸­†Ýðu"VÑNþ#•ð_¡½‹ Ô9÷«2P­ç]—ÞÎœ&¯Û>kÖ¨Ù¤ÔcnË5Çcdw+ûæ¶Á;×\ÁôÒ* ™0óëNùy×É7Äî¼ÌX2Jv×µ FR iÊ0ëÖž1Îœ'_Óí`ðΓÈ%ù„.¯ ‡É5z©L[·” 6GØg¡ÆáÖ¶˜óWìopqa«5a…îÅ|X^?Éß4
+KØuê·¾+<ÚJ¡ƒQÏ’"Uð²/êžgg"$D‚ó*”z÷îGP}x¿“ÑüI‡gµJã†¹Ñ 6¡ý}6·µ²ÿÖí}ð§K–t¹Úc²¼®Ü!En®sû}*¥Ol°¯ëz÷
+k®dîÓ…½òçT²§6ódìdì¹n`@ Ì«whfª`Å ZÛà{m+­kܸv˜o)`}X…z,òõ®Ö©Ë×#ð0®s§…l hçnDÔêÊá¦j©³ä
+‚™½N°·z6·Î㿾5¼öU÷Y<T8òPÁy¨´ÍÞCxsU§Ìy°Q^’
endstream
endobj
353 0 obj
-<< /Type /Page /Contents 354 0 R /Resources 352 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 345 0 R /Annots 358 0 R >>
+<< /Type /Page /Contents 354 0 R /Resources 352 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 345 0 R /Annots 359 0 R >>
endobj
-358 0 obj
+359 0 obj
[ 347 0 R 348 0 R 349 0 R 350 0 R 351 0 R ]
endobj
347 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 414.922 580.301 426.877 592.256 ]/A << /S /GoTo /D (subsection.0.8.5) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 414.922 580.494 426.877 592.449 ]/A << /S /GoTo /D (subsection.0.8.5) >> >>
endobj
348 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 313.871 317.374 328.596 328.323 ]/A << /S /GoTo /D (subsection.0.4.3) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 313.871 318.553 328.596 329.502 ]/A << /S /GoTo /D (subsection.0.4.3) >> >>
endobj
349 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 341.547 317.374 348.521 328.323 ]/A << /S /GoTo /D (subsection.0.4.3) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 341.547 318.553 348.521 329.502 ]/A << /S /GoTo /D (subsection.0.4.3) >> >>
endobj
350 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 334.663 281.399 349.388 292.458 ]/A << /S /GoTo /D (subsection.0.5.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 334.663 282.791 349.388 293.849 ]/A << /S /GoTo /D (subsection.0.5.2) >> >>
endobj
351 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 365.109 281.399 377.064 292.458 ]/A << /S /GoTo /D (subsection.0.5.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 365.109 282.791 377.064 293.849 ]/A << /S /GoTo /D (subsection.0.5.2) >> >>
endobj
355 0 obj
<< /D [ 353 0 R /XYZ 78.37 808.885 null ] >>
@@ -662,255 +648,258 @@ endobj
<< /D [ 353 0 R /XYZ 79.37 771.024 null ] >>
endobj
17 0 obj
-<< /D [ 353 0 R /XYZ 79.37 710.749 null ] >>
+<< /D [ 353 0 R /XYZ 79.37 710.81 null ] >>
endobj
21 0 obj
-<< /D [ 353 0 R /XYZ 79.37 625.596 null ] >>
+<< /D [ 353 0 R /XYZ 79.37 625.789 null ] >>
endobj
25 0 obj
-<< /D [ 353 0 R /XYZ 79.37 484.094 null ] >>
+<< /D [ 353 0 R /XYZ 79.37 484.633 null ] >>
endobj
29 0 obj
-<< /D [ 353 0 R /XYZ 79.37 240.376 null ] >>
+<< /D [ 353 0 R /XYZ 79.37 185.972 null ] >>
endobj
352 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F15 326 0 R /F65 327 0 R /F74 329 0 R /F80 356 0 R /F75 330 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F15 326 0 R /F65 327 0 R /F74 329 0 R /F80 356 0 R /F75 330 0 R /F22 357 0 R /F81 358 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-364 0 obj
-<< /Filter /FlateDecode /Length 4206 >>
+365 0 obj
+<< /Filter /FlateDecode /Length 4089 >>
stream
-xÚÅ\I¯·¾ëWÌ19ˆæ¾
-Æ­¸|þíòÓ âãëÏŸ€^Â,{IËD ½¸–œÛÀÅ›…åë{¥>½qnþRžýú^ú—üX¦v–
-þõœ«Ú†ƒVõÛ-µ…ßyN¯È“Ò1-&òŒÛ]”TªÕ¢ô­£ñÒ§†'â#<åðäšèÕWüÇxkÆò)I3óË¿.寿Ì,ÖŽ ¡
-5È¡È…°M¼&ÎâÌøAŠpòmŸkÜ1h4ͨ9'9sžvŒÚ ›Ì[@˜‘ Ž÷ìŒÄ-EÞ³ÛámñUO×K‚Œ‹‰²¼žÍckYJ&õÔÛª<çE)Á„Sg-jèµ®J<@¡Ê¬Z­]³’eŽ5NI•mnÔTK5G+©o×+IËörŒ
-Ud1©]|ʳT¯i hÔm ”§’…Â*ÿ»MB8&¥yŽIÄìš…à,H7Í
-|öÀ,4s|¢÷^sÔšq/—ó˜£q̃[Ì›äÒ+
-!RB·~;p¨œ>õʪº9—±ÌK{‰OûsAöé¥=;´¢PyÌåZŸË&•˜ÖuÛŸËk¦­8;W
-¶ †'Ž-‹Ì‚êõŒKð<;Ëão¤AJuùË|*î7G£O5š\ŸÜ]ßHÍþŒð=îþ»Ðÿõ²õÓÝÜÁÇ[éu6Ä8¤©u¥ÄÃ2eíË}Ïœšú^%> 3÷Òœ¤YVð÷¯¤ ÊUAå$Qe†FÿÚ¨H¹U)'"ûoY·òk=V©ð ¦‘:}\˜D „3 YS¿ÄÄË­íº(Ÿȶ1Ûp)Ö2OÇè¥mŠ¬àÏ^/æ}‚t¹¶Væ È€tÙÛh8Í-°…Ê~CN÷°HcŒE—CxÔø"ûÒê(:|DZqNÄãŸCWˤõ”²ë3¨r‚é@‡Nú{e²MCõÊ…û-ü<—wù]™ Ë`}€ÌJcž²§l‰)Âöß°¤ˆŸ ˆ'¤iҥǑc&ä>C
-²4­èÐÅïzRze-íÞ1i¹¹µ´WgŒ6;„üg2D·t-^2ã% g·®å<åïûäÑÑ2+ÑQ07A2ïQ¥Êš ÷þúfG×òD#CŸÕ8ÒýN#½P+ÚçíËi ÷Ô>Ï™úL*)?e àšRgšBb[L"^úiÈK>Ä
-¦O5m£BÓµc}©_Sø¬”*|•
-™s#å,ùi’Í0è=igJ[É·ëd7§T²-}9ˆ’20kÌDù‡õlJ3ï§Öòv&½Ö†)mWëLú±ž9§(¯3'Tža=›³ÌI¿”ç>¼\ŠC:+]‹8âknOßèBcCñŒ X»ŠPÃ0?”ªÃ/Û"´„†ùGŸ‡jÿôY[Ð6áÀq±¡Z[\
-‚ v¬BeÒÇoj´)±ÆîëÝ8–åè#õ­Å“0ï*Ð`¶7‘Ñ6ã…A¶µ4w-½Ò žO›:‹ EE‘ÁE‘Á(Š{IÑ*õ-J’ú#Ù/0¨}\P”þLEq0:%éHe“8¯¢Ûzry=ªÛ³6¤æòµ>£¬[ ŸI¿ôÃ7¶¶p[v¬d0´vwÖ)1P¼÷
-•ç,ÕÍð *Öúƒ3]ú9„_ºá½ú)OEhý”éëF­D— ¨k+idû5c–í[)‚Ò“R¥ö€V|Qd¥öxÞÚ¥óÖ™]›':5×tgÑK£cÌ%£”Â.QTƳuMñthwz{(#r%®YœÁLý‹“,'Lµ’KÞÕÓ¡Ýyò¾xÌÔ\;·›1ærJµœ)nüå‘p§Üx|±/"³¶hÇ$·=¯éɪ„®Ú±d
-X.F<!=¡EÌ4É(¥Ì®ÎñöZgÉi³†=—þúÖΈ“q¦r¿hC_Œ÷öòe˜õþ=p9­aäç²—ÿNŸ}lE@0³¼}çÀ0WÅ6³KA4™w,#Ʋz²áˆ¬‹Vb_“nf,ÊÖ_*0¿ <wfŸ_¥&(j‘ ð ¶ÒÔHÞã79¸iîV‡~eðËQhÈý! ã?y R¯žVÑa§W®+ªØiڒ÷CÞç½›ÔgÉ!Þl³x—‚/÷g?3Eƒ.ãfÉÈîòN&Óª²þ~ݨ…~à¯Æö÷Dn‡H.8ƒœˆ >_Êðnrý{nWzÆ&ûCþ…yݽ¥5”¸öRµ²ŸbWõCoà#·ïBQLùЋõwö5÷"_î·ô¡q%¼Ž¼Îî÷a
-Qê"^¶¥|þ®M¯,8ôÊaá%è¾.Õ¼þ6[´Âõõ­¥ÝûmÍ\ö®–Šÿ‘«L½ˆJË"½F¿wCšäœab¬®ð`ÇÂÚÐÑF›öÑüÆ>Z³sm ï÷¹J^ÔùÓG°PŸ÷ˆ¥1Œ»Ðí¿7SØ”J¿Œ›\®TŠ!Vò”óÓçwÿ6{ qçßsyùûoqßY+敽@¥¢ ýýýŸ—_Þýµjw¼4½¨ 7Q[ÕW‡r[¤„ÉœÉh:`Êe;¹ró¥Ká7œl»2m“¥.)†Ì[Ÿèa+sLá{wHA¦ÒÝÖÜ[é‹7mÄ)39y.Ýmp'®ù|Q¢§£8xcUSªWöˆ (2!Û¹Ûz~e{ǵ}Õ?õbegfÍ'É×Q NPjÑ+DçÙ]9*ÿ´…P­èH‡·š$ƒ'tzžjô²¡¦ýÁÅ#Ï\g§ö¡L>ÜÂóMgg
-xÃpR Ü<3°ŠÙw· "¬Hï{«DÀý$–‚vÄ`"»ÌbŸÓÊ!
-&%¸…û¢·ý &ÖŽŒç1¶sYw[m­o]ã$®°eÜûÉx¡è‚·êF]êÇ>fgŸO$îêäÚ[:[9‘œüNVZ"UGº{°åô†s·×wX«p:9·ªÃÙ¡-
-¬dñæÆ3‘µ*'
-˜#vg?÷“"5tœ­:=¯»b—}ž¾¡×2 ¯¥U©ÍA´«#«ë\¢tÔäàX‹sn•¨øRqÁÖ%*n·Ä?ýçÏ»þ\㦅¢\Á !kì„£†l¥è®eÇAÁÇKß'ÂSvAЉÛÝ°xOx©¼lw/Á‰‹W†´<N€¹(á7«œñäbÕšò-êIw1un¯¨ÈtÇŽrHJ5à­«;ã÷îxám<í£šÆšIJÙv!ç­¤´…”þ}™Ùª±R¤©
-aãÈkÞ!@¿Œ¸ÖÊ\Ü,2RQ‘=Xæë9¢
-Á
-*P3a½Br®#é[ï0ê–þ8åœç/ㆭI‡¤Ön¸x(üDáÙóÖÀD%5e ;Ú°]~äáu/Üh7B„ƃpc¸cÞÙ‰9 ÷žì\»áxa¿´tV¹ï[{IC EûãÉSî{x™ûöA_iCóÅݦ×1‡HÕ3 Åñï>û÷Lªi^'ª2/£VÑ—3ñ6¿¦"’GãÂjá#ÃóáO<£,!© ²{0.TMP¦?[6ãò[€ñA5‹^/ ã?’ñ‚ó¶óHôDûÞîÃ~m>ì­R:¨\½h80J„s°â$dçÀ4DŠ´7 Dz›ŠŸ~†çÿ€Ïx–(øËÿbËß
-hàöû÷åo8RÀ
-°Ò
-7oø=6›OÚ B©ÙópÍ'„í—?•¥õoÏ‹ý§ý•yq¢$ìõý~ÙÕ…—¾E¡à®Ì)ö@¯5­¯²² % VÝõ’ÜL‘ ŠŸDè÷zb;#Óùº>Ю`˜uôVår_ÄWåW_6icL©)õÖ]„˜e½zYª=tfÂîíÊZßÄå§oýíÊ©þIOŽwñ—K—Ö3 ¾{\ûî%—5„uÜ‘jjiŒZßÕ>=;¹GRöœÜ½R—ÿqw™
-óì uQÏ8D ä0PNªA[7) ÀyOi9s‘ÂHÒ;žÄk(éd›\_!G·D‰§â½¦ÌºÏî¼eàÂÈôÝyŤÒí`_²»NÙyK…Ú>/5…ˆªõ‡˜|¿oúàpœ
-¥ƒ€¡ô¬XÇ`õMÙûC!ýÅòÊÆŠ,ÌcƒÖíÃÛû)†AZJܧ‡^!Ôÿè\n-
+xÚÅÉ®·ñ®¯˜crÍ}„hÞèpNqt3|Jbˆ/ùý—"‹KwOF²±Þô°ÈÚ7’Í/¿^øåûw×Ïï¾{“òX°ÒêËç_Þ ø_ÄEô7gãV\>ÿvùéâõåçÏ?
+çï(MOªÂ\ó‡p1+©Ó+%•Ü14­¨wU[
+ɤ¡`P¥/óFg΃¤’¦9žGÈ7¢S•®$ÏÌe—iŠ°UO6èGn£±D4”^6½$ÁˆqÎY+#xñH»æž£GŽYU8vàBD`Rø³.¤ƒÊÜ \¼YÊåH}âVh|/¦ËüIŒWYE{†6ÆÛÊÈ}å‘Ži1¡gܾò
+·—ú8ZU4Š¤Úaœ+ë-Ê’²T†I•P“Â¥§œä„Üê
+”D «ìïµë S^>Ç»!8 ûqUàƒ´¡(Îy¯!jÍ8@­Ö=°D㘇Œn±n– U€.M9i¥-
+ÆÞßbÏ ,Û­ŸúG°iÞ)e­‚”Ⱦ;1òÚZ0}*s|ÁE×ÿÿ~“Õ²+ åªñÖe9in‰°°×c\‚çűXÞÿ{#MÄTã_æºß>Õ jr}F@\ #6û+Â÷2$îðßeü÷÷_/[?ýHÖ8®Æµ•Þ(ó8¤itÅÄÃ2çíË}›À© y•ùÔ­L¥9IÏi&”»Gz˜3ÄG‘Tɱi•œü­4¥^qV‰ÿ·"ƒþšfO5*ü3I?.L²Ì™†M¼©_RîåÖ†Z1PÙ(és° §b-óÓ$T`0ÅRÕp1ù#lϸµBH!á {7,N³F‹
+ÿ{ZÑÚ‚¶q":¿¡Z[\
+‚m@ã3¦2éµÆ›m0ÖØ]½æ‰zô‘úÖâIî5ï*Ð`¶7 ³mÆ ÙÖ>ÒÜEzÅ9mQWq¢5G£¢È`E‘Á(Šû£U†E%ÉpýLö LÊÔˆÿ¦¢8˜È0î*È>”Û؇*ô(² lÈÃe;À4²¶ýLþ…NßØÚÂ-n_É`î>½“=WL § §:˦›Ö1HÙi›fÓCDòe GÌÆb.Ô±í[݃ªay*@1 À »éŒz1xö y¦¯‘êÔvL*÷bxmœôÀ-3'ÀW½×™fOw°Ó6 Uáy6¾MJùC$O%º&t#rmž îA£ŠÞ\ÀHéF¥ƒf
+\ö8SÃ%‡ã SŽ9Þ¹#méY¿Íô—‡»­PG÷×ÛIw9B´
+T¦›°ÅÓõÕ¡ÜáF.çÁ
+õ8aNe‰€^!\憓m'¦mQÆ_G—”Bæ­{Õ
+ß'ήâUÃI%â–™ù‹˜}w "’ÜŽÐ÷3
+²`?‰›)˜H’YìsZ¹Øÿ›pIÉ—ÖË»{t4¡>Ømä…}v³¿ÿ­˜~‚
+ÇÝoç傺El^0ebË*%9Š-2m?
+Ðiîjl,;@
+&HÜÂ}ÿ±%Ö¶ÿûsÛ¹¬»­¶Ó·îs®°eÜûÉx¡F‚·êFõ# „¶½†è¨Â\B{;®6½Èh++ÅHU{#äB,Þ†ÞP`+âÎήþjNçFàU5(pQ@8(ú«$ñæý"GdUIb†HÎ}î§D2îuÓlé…êÚ·¤Ezþ]–Y¸,­°0¹®N«® ÔÙ1l“w8}÷¦øRkÁÐeÔÚFáŸþóç]_ßþÔÀ“¸d:¨¡ÖÛµâØ@'x¦ l»xîÂÎ蜸ßMÅ)ÚXrYr/·¯ i œ
+oýÙmÔ4׌RN³7ÌeúNŽ‚ŽleÖy©þ5`•æô‡¾¡õ„ú6n©F‘=XßÆCÉ"rƒ¬ó|¡#‡‡7ûçßT0§ýó‹0ð58½N5X=·ì—/ЫäuÎ<·^DÜ`3.ºòŸ~†çÿ€Ïq§6øËÿÒÈß ]ÑÌŠ÷ïËßÀµg—¼dÁ¹ø
+±Æ^˜±±L¾‘[ǘwCÌp
endstream
endobj
-363 0 obj
-<< /Type /Page /Contents 364 0 R /Resources 362 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 345 0 R /Annots 371 0 R >>
+364 0 obj
+<< /Type /Page /Contents 365 0 R /Resources 363 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 345 0 R /Annots 371 0 R >>
endobj
371 0 obj
-[ 359 0 R 360 0 R 361 0 R ]
-endobj
-359 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 221.129 698.246 227.587 710.527 ]/A << /S /GoTo /D (Hfootnote.3) >> >>
+[ 360 0 R 361 0 R 362 0 R ]
endobj
360 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 459.405 548.067 465.864 560.587 ]/A << /S /GoTo /D (Hfootnote.4) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 221.129 656.403 227.587 668.684 ]/A << /S /GoTo /D (Hfootnote.3) >> >>
endobj
361 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 386.12 285.904 392.579 298.194 ]/A << /S /GoTo /D (Hfootnote.5) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 459.405 506.224 465.864 518.744 ]/A << /S /GoTo /D (Hfootnote.4) >> >>
endobj
-365 0 obj
-<< /D [ 363 0 R /XYZ 78.37 808.885 null ] >>
+362 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 386.12 244.061 392.579 256.351 ]/A << /S /GoTo /D (Hfootnote.5) >> >>
+endobj
+366 0 obj
+<< /D [ 364 0 R /XYZ 78.37 808.885 null ] >>
endobj
33 0 obj
-<< /D [ 363 0 R /XYZ 79.37 392.002 null ] >>
+<< /D [ 364 0 R /XYZ 79.37 350.159 null ] >>
endobj
37 0 obj
-<< /D [ 363 0 R /XYZ 79.37 331.199 null ] >>
+<< /D [ 364 0 R /XYZ 79.37 289.356 null ] >>
endobj
368 0 obj
-<< /D [ 363 0 R /XYZ 93.716 112.012 null ] >>
+<< /D [ 364 0 R /XYZ 93.716 114.244 null ] >>
endobj
369 0 obj
-<< /D [ 363 0 R /XYZ 93.716 102.325 null ] >>
+<< /D [ 364 0 R /XYZ 93.716 104.557 null ] >>
endobj
370 0 obj
-<< /D [ 363 0 R /XYZ 93.716 92.698 null ] >>
+<< /D [ 364 0 R /XYZ 93.716 94.93 null ] >>
endobj
-362 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F15 326 0 R /F74 329 0 R /F16 328 0 R /F75 330 0 R /F77 331 0 R /F65 327 0 R /F81 366 0 R /F64 325 0 R /F82 367 0 R /F30 333 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
+363 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F15 326 0 R /F74 329 0 R /F16 328 0 R /F75 330 0 R /F77 331 0 R /F65 327 0 R /F81 358 0 R /F64 325 0 R /F82 367 0 R /F30 333 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-383 0 obj
-<< /Filter /FlateDecode /Length 4489 >>
+381 0 obj
+<< /Filter /FlateDecode /Length 4505 >>
stream
-xÚÍ\Ko$¹ ¾ûWô19L­D½Ã@z¼`oIæ¶ØS’ÝK&@ö’¿êMQªê®¶'ÈÁ3v•E‘)²Äå·‹¸|yº~}úáMšKØ‚«/_}’øB\ä%ÈÍhsqVnÂÊË×o—ŸŸ…øì^>!ð7'…PoøBè×—OJ*|jC}ZŸhûî9·söå—¯?=‰-Äùñß/O?~}úw›SZ·y//θÍyuùÛ·§øÂè ‚½H±)¤ä÷\~}ú3¾ KpzµiýæãkÈ#5ÿÇuÂàj@åíý‘Ò=æ
-yDýzLkp›ÏG‘Ÿ3Òÿ>î þøLW_Ãb?}îcô©.|ím#uÊíUd'ÉGÚ ÈüɫŸkoãÓe¥ëýÖÎn_)àFqžáswÈ7#Õ&Õ´ÇeÏšŒ Î(c:lRØÚª®5q*rI;*Ú?WZÚ_[çuâ9)=ž¥v§S;¹]|×râÞê[¸6I:jÚ÷2Ž…C¾‚ŇÎó5‚îg Þæ³R¨ œå£Wù„¾Š¢mOŠ¤D éÜ Ü­i=êï‚ò±Gýýœ¤B¹Mš~r«\û¼ÇÚÕg:ŽW5C\G~[õF¢Ë'‰É粬$=ò['©òÖÖ'D‚÷X)Ô®SüA{ ÷X¨‰þå“w!r½hŠ¼æ¸¶l3ê*Ò‰úÄíZxÈöR§Q#g+¥öµ¾ÍÏåÇ:X£t²ŒS~NkcÑ^ø‰»Uª®yÄHc“nàkS;2†¶HÓlPÕ•IæßQ*>5aÁIUbi4µDµ7Œú‡ýñhqÒà憉¦üƒ8òü¶°°¶å3=fz:¨‰ö$Δ¶¨ô)³
-(³R;–i4dŒTW·¢äèÔÙg"²UèÌ$œvéðæ§ÕÆqÿÞUÔº][·*¿V,';Š½ ÖcèD)Εq¯vb3àW<n¸! ÚÞBWž§EµoBà"a‰o“ÙHõ}µÍ©UQ cëfF×t×vîZÉÈö›6–¯!ú+þꊹhœÉvÕp+¨g1D5ÎÆôBã+z'Öt¾JŠ<"WèÙ€×}ΰ`À¡ß…Î=x=ÍýÇ\GÕcù Eõý,(
-{uþ„+ܮط!å§+†Ãƒ]D/9•QÈu
-+ÍLg&üZÌ_úUwluñ“7ðŽk‹Ò’]M ‡ºŠ ‚cçüÙxD·8uN± ½r££ÖA°ZQå½ë›”WU$N“ªìÉñuãåkmP5ny…Yf=knÓ`qkRàÙLx ¢®¨qøØÂ~UX/{¸øÀˆž“@e£&}쇸‘X „q›E"éô‘áÖ!î*XË/#Æ­<7¸!h™:U«ÖíߥcOŽ¤Jïû9 g Å×ö•†…xéÂ&e,¨ò_
- Ga)\ÚlÞzÊ‹Df£9¥ðz¸3Y„ÖÁ~ó08ûÇP,à4'Œ,%‡ÐÂbÏ ùQ 7ST$áF:„vóè0±1+üJ<‚;n³Ô&D˜(³ üÝV‹7cÁ»‰ªï‡K³°Ú Àƒ.@
-ìsU£¯M|wê Ò¨9­*F¬âù¾¦æøa¬W‚žÉ)€ëÆÜΦ»N6Š‰âÖóFË S‡v¦[ÙĦ1¥<ži†÷š`R~µ‹$ìD¾²¸t½°Œïp«ÙDXÃƾóZSÆ£Óhş®­¦_²´¡âgqX±“H³Wæ!зieÑ€~.2ëU*ÉShwÓgàzó/w^„iÜ%íYô<ôψ8_À¦S­µ¡¦¨89àT*<
-A²S½Ô¶ãjmÃ*…êݺ¬VWG.ú´lõ%iœªq;"éÛ\hÊÑjU+1¥«T XXÕ•¯ÇNn~¯;\Q,§Q„èI*ι<ZŤ‘0ÍÐʵ)Õ-sKŒ©|õêÙ*7£ƒ¥$Ø\/Y¨{U÷‡XßõâAuÎT¸ÚòUÃœÜp¸]ëpž¾œüË|/:Uo¤€|6«&™U“îK]ÑÅ ѷ
-[ŠOL5
-#Ýú„²­×±w¸ÅÝ+‚C_$½…ÄÄt)•'Õú9Ê“Wêþׄ‘2ýü׺LŸ/5çÁÂÝ[îU}zåéXŽß©•EìÜ©õOtbi¹Ö„-ר5*MtX†ËéÁZ§ØÄTÛl§k{òÚDz•«ÖÆù?Ìšˆ ä4CÍ>·@§¯!ÙhI¾<}ªŒÉ ζï1è~‡†š-è“4ÊgÜgEW¾íS/CÉÜùÉŠ¥¨àÑW=ÛÁÈUÙôH`ç$Ž:è&RLb¾‰‹ªéç_ðùßñç'Te/ÿI-¿¥*&+c¿^þŠª*«(y1[pÎxºñéê̦˜€òÀjÔx‹ß²ÁN£:ÅQÆNñ»sVÊ…[hia{™¿|³Z./Á‘ÊŒ¡²|ô*÷¡p­ Pùû1å—(¢½G‡Òëþ5œn‡\”¨ò›3*U ²í}$¿º ´E°d¼26}Dq~®SÏNTMJ¡ùg÷ò³ª›hZ¶êÞöÇa!9¬ˆ(±'¢ÈØÿäÆÑÃUN€Pèxï|©‡ÓÓF˜©jÆäoTdúpC”x£“»EÛ©§.bmýKúŒRRUßÒ„Ñf8â²Óè…SPÓ i½/à•v–• ¬×x&OA©ü½&Æ[ö­
-š‚¯aÚ x¥sßÌOÀ¦›vÓœ1?¥<Ò
-—ï@YKbž‡j.Ø À°’ZÿÓ$sþ´Ïg%÷nGÂêQk™|å[)ê:ì‘*•šDvË÷ävGæIà¡&™Ýˆ´ÒŸvÆ­¶<¾ë(–S³Ñ¼6¯ [?@žéá!zó”ßTÏïÃBÕ±¦ÄÅø߸äVûWAB©¯gÄÂÛÍÇòmoˆE„däÓIüC¶{bAøÒAßr©}úâÀ8ÍFlP„¨G
-2Ö ~³ÏÐBµ›/ã4åOë7ª¦.û¾ÓµºÝкöQóS½ÕŽšøék,û_¨4 ›i‘¬t•§P±Ü“u3û
+xÚÍ\Ko$¹ ¾ûWô19ŒV¢¨`H×ì-ÉÜ{J²{ÉÈ^ò÷C=K¢TÕ]mOƒgìzHE‘_%/¿]äåËÓõëÓoÊ\‚,^¾þú¤è†¼¨KP ¹8«„´êòõÛåçg)?»—OFJúÍ))õý€”øúòI»@Wm¨Wë´/àžósξüòõ§')BœŸþýòôãק·9• ¼8ã„óúò·oOñ† €»()4Qòû?.¿>ý™ntKp¸Z‚r’†ãKPŸ‰Ì×Lª¡E $â®ùwÐù}ZB$v? µPÆñÑ‘–i·ÅÌÑ.ÏbiF¸f–@¼$g—•eXâØyÔDùk¡Ð.)Ôhø‰Bƒ…ÊÀFY¯“ˆ…cxÍ#VŽêaý q¸V®”ÿ¯yGÐ×'œ|1æ¹^Í#·½ÐrE#/”
+ø×–e¤ÞÙ‰9Qª]š¬I‘DŽØˆA(ië“ÃÒ¤NŒL’ Æë Äk _>5ñ·²>Z¦)5^–ýMrqÝxùD\)ãÄ·Ò49ùT¥É6bÒľL¬{¦¿n¿ëk|<”§ò@™nýÖH5ùÙ"*媆nëC&Í‘\[É‹[×æõÂGV:"}„"¨rc^Çghî¼Ëk €.šïDJ5?tÝ…& ÚÑÑJz;òLër%r&µÂ‡²=GÔ*cEˆb<Žÿ€rR¤½í<’ƒmͺQ[w!)ÆP¯ÆchçcXîvçdïP‚<4Ü8”à<]DN¶ñì–I9`î°LJsYKWÎY&R^ѤZôÍ2‘@û€e²ž´ãk¨J>Iþƒf L"‰ÜÌR^ùÀ™³tdZÀiø,'M ',x>J=OUò¢^q¾Sp{ûé‹ C‘ãvuÐCJ÷zhg¬ªcÜGé!KFó•>¨‡ ¡ÒÓ—=›´•$‰pÜlµÃŽ®¬jÙ¨öW2 E%ÛúÆÀ²ôÜÄèô\T9ñ9„l\\5.éîfùŠé eÛÚ9d+^ γ%n' Þæ²Ö¤"B”}^CQ5 ýÈåè·•í· ßß¡‰»þ~þq‘°A ­Lz’Pû¼Ãèü¾Èw«ÒHtù$/ù°ÀKƒ‘Gè\F#"Ô+üî0¡lm§øƒ¶m±Ô?‹úŒV‹šÈkŽk«,¯"푬W|§Z Ù^bFŶ¯õnëo*`$áb§üœFüÄÝØ~\›Þ‘1¯hçšý©z’cc¿aã#0¡P‘Êë½%”¡­ œŒ¦ö³Çµ‡ ÓÝxï¬Êtu:•éê #Ú•
+
+,ŸqÀùpõ¼Be‹@>&`œ@…|~øL‡,3óeu‘ êœÔP9Rù\ž[SSîbãXue5Ô±<3噉ƒE$ðÚÉrY’6Õof‹HÛrËi«BYI¸³PqÙÜý~ÔõtFø,¦9¤1 ]\ÒøVÔá•ç£sä×Â
+ɬ¨©iÐk—»¥›ÓÙb"²ZÝ€—§Î‡ö<LKn¨œ=ÌAó
+Eµ-Ïæ1mΕ5Sï*å£fiqVÎjá»yæÆÝ<áÃØ{°Âé‰Ù'á9ù÷!ðAàµçÝÈI ýŽÄ•×€HöÇv5ù¸jÝÐtáMg-Ðð@J;;jFšÎFM7R[!|Ýþ9;©ýè)RÅ|àìtN
+#åz·>q%ë°0Q·Cr·_öü…V2qßfà+ê´Iy¯ÇLürìÅîíƬT ³œ)'9K€ ¹Å(XÍ¿¯kì<ÂÛËÞ“eãpGŽeÙœ—e-Àzå¨*ËÉC{$7‰tè£vt(³,'U”h…”Y©Ë´Š9
+k@L˜Ÿé…ÆWòO<l|U=òˆ\éϼîs†=/rðÁã4÷s”ɶ²ŠÚö³ €˜Iö !$ÜžŠT$—}Xg±‡¾P°\¯2 µr#|¨'B‘y<t>hUào¥D^êx
+ ÈgÅ a„Ìï½p©—ëOñF¢èízW•ëbíë3¶–hï= 9è÷ŸBEf—¸ÏGƒÕ3ŒèýCÜ®KüŸ^mQ˜¨wÆŸ0¼d¡½ÍG8oÚ¼ ã8F¸ÐäBës¦ ­ 0qÖ´ oÍ®<NngºrÊ´‘ï­•§© U WÓF6Íkõˆ/¯h<ä¤?bÚÞá
+=§"ùêv¨0CX³ðF¼0¿§»’!WºÚ½<ÞH>Sf’¿¯Õ¯3ƒ–Z-&Ùý²kƒ.ßorããC%‰ŸŠR¼Û3šÞ2‘ñ ffŠˆ€äÖÑfK} yf>ð—ØÇÛÞè5®$ìãÝ„}jqÑ/°ÃóšÊ—?rÓ– ´Þ=þÉjù¡úÁOùÿteH[7Ó„ÐY´fqüÖ×Y®#tÌWÇLYºd»î¡ã-1CSÄ¡‹e51â{ùå±.<ÎöÕýÚ’Ïé{Œ]ØcUÆÜ;b‰“x®;?ñ]Õ§tۈЃÓö¯Èo˜û\†Åèk¿yõF@´Q#­:†¬âù¾¦½/ó „oåÞC|n€ëÆÜΦ\'ÅDq ëyÉõr0½ÐΔ•Ml:ÓÚ“á™fx¯ ö!h±Q7‘„ÐW—M/¬ã;d5«ëà‚zoŸ›¥Ñ`múÔµÕLV6$·¾ÂVìÒìµxHòm`ZY4 Ÿ‹ŒÀz•Zñ*ÚÝ
+Úã8(
+§àÎD˜Žåþ,zßψ<ß»†©ÅUG7Q¶®ê@Séð
+éqÍ©üN•:¤²86YK¦Û¡œÕå¬m=c»dWó [i°Ñ¸ò¯,v´æwk;¦ÝÑ–Z
+ëÌàh}_/ÛªîêV¥õÒÑlŸ¨€ªB­³u=tEœ¨÷Ñ
+…Ó§ ÂðÖsRRýÌ1±²OÇ"yÓ4T¡î!”c…ËI|åè\J||ÐQX;ÏØÎÁÔvëÞ¶œB*èô;å5Qr±ÃÛ l¸þÚ;Jt˜»{[ñ±µKÂîŽÑäÇ7]½F+ϙΠ¬31„ê\èk@¶€@ßšÌ:ÍŽ ùbxÂó±?²O¡ž³LkÈîý¯©w[Í}Ÿ}ÉÈfèož‡[Öy-ÞÌ°£L]+tRµç>~ß&½ÎààÑg€Jã5îëíØÔí»>¨PB#8¨Âën™h¬¶‰þ^ ­Td\-nX±õÊ·®«µÖu™>T­Á$SÕî†I¶}®g4émŒºõ™ö%«½°°j+_3Ý|7¼ÃX‘qL‘êeœûÀ³:–„i†Ö°ÝSÝj·äXÌWsÏV»#,%!Il= u¯êþt&xA<hÏ™zW[å¡Þ‚Æ0T'7R k%Îë—“ƒ™£SûFŠÈgËj’e5))xÜí
+±¡\…[¨ÑÈ-Ü·Øñ£›Lž¿
+0ÆR¢Pme´ï¬ÁÛª¿ÍÅPåÏqrb\‡Úòw–Õ¼Ÿ$ëÈ ÷Üœ‡6ÛtÐúåù¶(±ÝVÃã–â[t´sì©
+ö°H,‹ñ
+ŽJæo$VŽ^"t<|gQ §âK€*oNHu «æ”vëpUo¶jBË<õ¬kYòÐþS>÷’ß­@-ŠÕù
+å—¨A·76+²~¿ºá¶Ë¡e-ÎÕDº:™û£G|àWq±ž¶bµ–Œ×ñkkÎsÎÏ=š?Ô„yrŒ~ä_›Ê×**hÈ´J­½íýqRq"X}bOþB‡ÌÞÉëM9¤ï@áú‹ [()m„™JÆMnÏÎôцhù<ºç» ‹éM,bmý‹¯ÿsºÞí‹¥ê7ê8ƒwmpak©MßëÖYŸJ;ËÈ¡ƒõÏäètòDoYŸv_Š0í¼ösßÌÍÅ!ºiΘ›cå>}ywˆñö†í|þC5ÈAÖÈêeoh9úÏl)”­C­w$¬µVÅR> ¯ÃéÒ¥ÔÉnù’Òîȼ
endstream
endobj
-382 0 obj
-<< /Type /Page /Contents 383 0 R /Resources 381 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 345 0 R /Annots 388 0 R >>
+380 0 obj
+<< /Type /Page /Contents 381 0 R /Resources 379 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 345 0 R /Annots 386 0 R >>
endobj
-388 0 obj
+386 0 obj
[ 372 0 R 375 0 R 376 0 R 377 0 R 378 0 R 373 0 R 374 0 R ]
endobj
372 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 510.443 677.086 516.902 690.602 ]/A << /S /GoTo /D (Hfootnote.6) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 510.443 633.25 516.902 646.766 ]/A << /S /GoTo /D (Hfootnote.6) >> >>
endobj
375 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 338.658 542.381 345.117 555.194 ]/A << /S /GoTo /D (Hfootnote.7) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 338.658 498.545 345.117 511.358 ]/A << /S /GoTo /D (Hfootnote.7) >> >>
endobj
376 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 387.236 502.75 393.694 515.26 ]/A << /S /GoTo /D (Hfootnote.8) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 387.236 458.914 393.694 471.424 ]/A << /S /GoTo /D (Hfootnote.8) >> >>
endobj
377 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 244.218 450.725 258.942 462.68 ]/A << /S /GoTo /D (subsection.0.5.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 244.218 406.889 258.942 418.844 ]/A << /S /GoTo /D (subsection.0.5.2) >> >>
endobj
378 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 275.761 450.725 287.716 462.68 ]/A << /S /GoTo /D (subsection.0.5.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 275.761 406.889 287.716 418.844 ]/A << /S /GoTo /D (subsection.0.5.2) >> >>
endobj
373 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 334.199 99.269 340.423 110.079 ]/A << /S /GoTo /D (section.0.6) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 334.199 99.379 340.423 110.188 ]/A << /S /GoTo /D (section.0.6) >> >>
endobj
374 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 353.478 99.269 363.935 110.079 ]/A << /S /GoTo /D (section.0.6) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 353.478 99.379 363.935 110.188 ]/A << /S /GoTo /D (section.0.6) >> >>
endobj
-384 0 obj
-<< /D [ 382 0 R /XYZ 78.37 808.885 null ] >>
+382 0 obj
+<< /D [ 380 0 R /XYZ 78.37 808.885 null ] >>
endobj
-385 0 obj
-<< /D [ 382 0 R /XYZ 93.716 122.034 null ] >>
+383 0 obj
+<< /D [ 380 0 R /XYZ 93.716 122.143 null ] >>
endobj
-386 0 obj
-<< /D [ 382 0 R /XYZ 93.716 102.876 null ] >>
+384 0 obj
+<< /D [ 380 0 R /XYZ 93.716 102.986 null ] >>
endobj
-387 0 obj
-<< /D [ 382 0 R /XYZ 93.716 93.249 null ] >>
+385 0 obj
+<< /D [ 380 0 R /XYZ 93.716 93.359 null ] >>
endobj
-381 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F65 327 0 R /F30 333 0 R /F81 366 0 R /F16 328 0 R /F22 357 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
+379 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F65 327 0 R /F30 333 0 R /F81 358 0 R /F16 328 0 R /F22 357 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
401 0 obj
-<< /Filter /FlateDecode /Length 4404 >>
+<< /Filter /FlateDecode /Length 4609 >>
stream
-xÚÅËŽ$·í¾_Ñ?0²D½Á
-ô=K ‚°ÁÌÐ}¡5c~L‡—oÖ½æU #¢ߞѣq%çÚ·ÊÊ3”u@”•š!Øðöâ¡éÕòi¥Ø`PÈ7áéIL®ÂXàŸeÕ?…’®eU†’Dy˸HIáè9‰ÕÁ)o”—Â;·¬
-ºì! üht6–Ýum d)#PX”÷VaG,¿ó(Þ‹™TËÂnïXxæ- /³ú-ášf‰ž—á„0éB™<ÉC-$ù,×^([uÕ©²y ²Ö¬7þ+é’)O¯d‹šÉÉ#¬iÒ@Ûš¿ýrÉÿøË ‹è„ÁÕg, á‹?Y§d1 Õ4(Ügr™•„v›ñÐ׺ññ
-ÕY&ÕÑÒÚÃãl 2„u‡îÒy#t¨áË`¿­|2èBó-‰’æ7µ·R€Ó !Óö•[vF8‘W£Q`ÅV:Õ1ûȵA((µ¡u0#8Z¡óÜâ&Ž ‰mÉ­¨1Ò‹‰þ•-
-ÓÇj_£Õ
-%SÞŦ‰òqk«ŽÅ4‡bo:gEmöjç@Ýâ#9*¬¢µ×';Z—½!9~‰b³öõÍb
-}$—"ýº–wekËù­‡LŽgz‚n1Ù‘ÆUŒEcå±V‡‘î©y ʓ‘¡ÁçsS`•ˆ2,³ü•Å×ÌÏ“ñs¿Û„¼X -Ö†ÿ ‚K2À= u ­Ï:X÷'>þnÈR9O…»µ©O'²dS1úA~c“ª—qA^Œ·: ËUš’R§Ä}“šÐù4k©\Ú¶Ajʳ”
-“O€þW} ûtFX'ZfÑ’‹ŠßrWc´™®XºƒŠ¥JÆ{¥`´ßçòVÙ0ÁHT¾—¹J‹LH–äNgó˜g’‚¦)Kó7:²Ô–ÚZ]LÝ
-q姅»moƒKnó Ê«ÕbßT<TòV½ësc´ÎÍkëÿœ;¯ÑàϘ«wSq³Söh0}]#«ÂãŠ_M³K%á6Ö!«Í'x÷hÔ
-Rä‘Æd B(#nf…Þt¡‘r¤†É
-¤S´ú–A‡ÁàUÆyÅ·œžÆzJ@Ü<ûÿ@iŒ
-E‡+÷\1KYsAÉ5ýñ¸áx3¨‡ÎëöŠƒ‰Z3`T4áâveGË}PTfÚ–롬QʵpîgÎ¥bùur‹ïyâÆ
-­T3 uWa !UœgŸ9œæ°Pk˹Â[©æ-•þk«j9krÚÃ[Rùì0}Kléß FÈ%ÉdõGšÝʼnèu°£‹¡qÌâQ?spÁ„™cÞx+0]«Îk.¥~¬of 1ºV½áýi@¶JÁŒßºõ¨–ù°6™=AmN—Ï¿4HõŒìº2î8km„E‰L«s‡ÐQ `0Ì'8?(8›÷Ñå¤+H{ò‹ö)³¡£JöåÚ!^˜™
-úér-¦ÌÎá¢(M]«µ˜åS§âªµÁÁLƒƒV¡ñ¥aÐAkÆê>MW¦àq©2&—6“óRmƨ“zT ð:Ö£ÊqkuÈÍë³åöž^¡Fb°l€,½cêÊœj
-§a¦5Ð挎¢`:–Os'£B³jë8ÄLe:™5‚yÐ2snX¨çr6Áçxw‡[æÚr…®cÑ ­ÄвÐ!üÔ]Y‚ÁØ:·ïؤÝ]é—Oç-ÚRi.*¬ëôç×­œÝcÑÅG]£/™ŒC/r©¨JòøƒÞzØ€S¿ëÝ ¨¬À„úŽVÐ{]€Qáò)§ûrbÆ|q?šþ»Ì¿ûårôªï•è5)
-›è2]ÀÂÇytÅ$àeÒþèWÃyN.ó-QùÞ ,RöûRUUùåžžqiŽ¸â»æoûå)9êHqƒõ´V.'q꧵´#5õUêÈþŸš˜Áì°-ÂŒùãîÿÜ¥ê!,ÐÉÐAЯ}>óbäŽ<q×yüà¬2„{ÎÊËÙYåuŽ f‚:ÉÝøŒU. .YKwõ͵ee•šö–ž“ì#¶¶Yôÿ¹MMóàúì›iBÇùtÎØõ=o;Ò¨£X/fñIVXÙ”·­?WJ Ô^¸iÜ3·”Pãµ53ÝOVFŸ0ïV‹h§Q*é{ó>%+‡±£$Bͳ*8´»*Sc‰B©3î8êKºï7ÍsIj>¾6G;J»jË-óö}Ä"Œ<çRDu‡\o/DqÇTWÖZn}µ'ßÔ2X_Í7þ,’Ï}Lv^y]GCw®ŸgqôÞuwùMõʺžžÚª™žpѪž^Ç©çk=»Úw¢ ÑΨ™ëO¶¢D”°@I=dnÛ©Ç•j®Ÿ”‡¶ZB=E†Œ"ž´ž>Øpò»qÖ®ÚÞ[DZ÷;mëM©¥£·F–Rx›\:ñê_—áÏ?Qâb.('çtè…ç#G\^x}?)ßÙëùu|å$÷º±k´wëïVåjÕWáöìÁ<g9Ê“-Þ¢ñÍÑäñt?ß®·• vê×+I±°)²²]©U]ˈéj½e¹"øÒ0XöÃLŒSc£=_:áÖ<»W’Ôz³]Îo×ñ)¼p­ywÜkTòˆ~1Mï]F(¬¾õ„@ïá —
-ÚžÀ)ÁqßXÀÉÓLïDh¾³? Î0÷|2°Š–Z,q•e„¸•Zg`™ÃºôsÈKmE°áÎb*7TÁöâ·…j1°ñi.˜»\0;.ÔÉ ·Úš#—Ì#\²T’GzÌ mdŠ³Žd¨ØéÛÑ^h´ØØã§Q&tÿP5´U_¹¸Çq•CÇ4F˜ëcšPx´²RB>^ùâŠÍ=+À+J)”3ÙE£v£B [·ßîåÑwo”óB8Ö@2úg¶ªÓ¦MîP(àØ~H¾³/¦›!Ê;J½ÿö>ÿþüHeLËÿ›FþŠ¤ áŠæýûòWLÅs
-®.h^¼·ƒƒGÖXç<Lš‡/çß½£Gò8I"°nRÔÐ$#lŒÛÊß;ÏUþ°Ìõå2å9gV¾»/:–•øíØbæùö¼ì® m×:; Ì•~»¹bP5þÆp[¿©[ïÏ¢|¶¬ÖèÃ"†ç¯9Ô©õá½ t¡‚Ÿgû[WÒS~¾ß›ñ“-ð‹•åvxWù7æyEÅŽ½Z_ÎòHY…‡î^¾iÙ}ì êŸ¾¦Àý¬¹Ù¤¾®÷í
-zéµ4Éœ‰$†4ÑÍäô¨óyn:Cu§¢Ä [h£ghéhbå,!r–žÐA
-òy½‡¬HÄPÂæ´îŽ¡/ܨíåVâk_ˆÌŠOÁäôÝ\!nù‡ê&NKVùöh¦¸XÎ@êíïë(íŒsï·\¥d0‘oÈ×ãjÙªcñ•[Àç¸y•þ—W¥Í¼ŸùWǼp,5ïr‘.èd{ø†SìNÐYݲÃÎ^§¥WT+É ãÒjQÎ_i›»îø€afûþPïAkÐ>\Ø+ÝöÑ3,3~Šg–S#¯û*Ã’y%ì‚lsþKA6ß
+xÚÅËŽ#·ñ>_¡Xš,_À`
+AHgœp^_þþëK¼a‚0à.J
+uùퟗŸ_þL7:dîU¨ Ü‚-úŒv„o ¿%}®RªÏô7ýÖôé>Þ¶G¬
+]<z)”I*æEyä[CUfÆ‘ó§róZŸìWíDÛ ~«*Ú eꢬ*¢õLkº²Y'[¨ %bñ$þJõn3#ÝeF;êCžˆ‡ò¢GôÃêéï3¢yÌZKÓ `Aú²~„ñ8CŸWߤ ƲžøL»†Sz4ÙYæ Ú·ÊÊ3”µ'”•š!D›è|ROu†<[ÊF€Y !“–¡3Ýâ-ÂXàž4@¬2Ð7|¤œÎÚe¶)N÷KÜákV vtÑh3õÚcñ`yÜ‘ËwYa-ž¯¾%_Ý-Æ
+Š^mchíÌŽVè<7F@XHl HnÝ@‘>a®Hp,‘ècµ¯Ñj…’)ïbÓDù¸´UÇâø ÅÞtÄÄ5«Í^í
+€€Ô>ª|VÀº88ëqwãf» Rxe·õé4¶Ôc'˜ßØ¢*Bfš‘gã¥Îò²•ª¤ÔèbRôOs·–Ê¥e!(ýÞ¥<K _q_’¼ʺ>aŽgyqÔÝizÇæ+qCXôxYª!Zj)‹:P,æ[±ÛAsåY¹Î
+£ÃLDË-šJrYñ[.lÊ¢½Æࢥ=(Z*Dü††ÑŒŸË\âÄ $úÞmë$‰¥wdGò˜g2ƒ¦)™KÏoôd)0µ¹ºÀºUãʧÅÛµNÈ51¨©ZŒœ
+‡Rîªw}wëÅ[;Ï­oü9wb!cfÌÕ;VÜÌ”‚+ß h6ži\Û¬*e¿šk—rÂm,FVÃáÝ£QS\Q—G“•ò]|t ´ Utª31Qjø—4ð½Å ¼29(¨vú¢jåGŠGRÖÙÖòÆ0möYh ¡îY¥Q›„—¢B}žh#¤ }äÍÏù}‘5C0æ<%{oƒ]ç}Kyñ£f\lÙ’±–]qZ¶5QKÓ©LÀ;¶´´S¹DnûÔ*'†
+{èƒÈx)ëîÔ:•Ú×Nwî!DðŠÒÿÀÞ|*z} Ö©“—š°}¶áÈj¥n9$jkõG©EÁÕQõ'ÝiKcÿäY‘.oÈÛ͆üÙ¬¼ÃZ÷MË m9©¾ºu€×iê™G<ì™j5uY ’$© ¯eÔHT—b– š''„ž(EZ%@›y¢o{ E±2Ì3v~ät[ÖIòIv~úÿGé@ÑaŒWîÙb—²4æÊz5ìò¸aŸÓ«‡6Cqš
+ãíýsÜsƲä“Ìü7mœÐd:'HÚ·ì)~Ûëv÷M;—|ëŒÇ°ûw‡ãl3C9Øñ#ˆÂ¨…ö“b1:C4ê¹´Q °ÄMG”–zÓ•ÇF}ËÒ«ÕBÏ%M_MOÖce­®¥§Æ-ç1fKqZ §u¯,c¹lx§Ù wp‡˜Ó}6Päý,|¬…œ§ðøLOg¿Š›Üz$° Ûœ7ulˆRlíü~÷Åyomw1ˆ¶KÛC¾t|Âmj^H£R3Oõ<ýˆíz17[];j{Šr³­vKìÞ¶®OfŠºHÍ¥ýT½‚ïG—Ñ×P“!3rKÚ=Ý
+Ð(P•æMIJKʺf@ꮢ@Bª0?}æpšÃ"­- o¥¬·”ü¯]Wß%¨=¼%ÏÓµä6þN0|®M&“¨Œ8Ñl/V§½]í#Ç(aÑþÀ¨Ÿ98~æØ‘§¤CMŠ–šêÇhÆ£ëÙîŸ
+E `kÂo]z±¨ù°6˜=AmN·væÂq€T7Ë®'m–[g­Q§çÙ¹Uè(P@
+3ä Î
+Öäu4B9iÒŽ$à ìSf¤ôÑJ·/Ûñ",´ Ÿ.ÛRÊl)ŒQ´N &ÒŠòüØdþ²m x0a¡•i\i´ÐÚ²úMPì
+<.•ÇäÒpr^²õQ͘ÔM[€×±(U6^«Gnn¯hà–Ý{:x†ŠÁ²²øŽ©+ÏT
+ÖpÏoÚ’A˜ÜùŸ;t -„x´ràõkßÏœy#O|u?xª ឧrröTyž#k™ ÎÛ€En7Þe•KzËcÖÂ]½sm¹E™¥&½¥õ$;ˆ½a¦ÀØ3÷΃íso¶¤ ëÒNc×þ¼éïH£Ž½´g˜Å'Y]eSÝ6ÿ\'-P{á¦qÏV
+Vhƒ3ÝOÖEŸ°íF ïã:£_õ¦}ÊTã35#Ì.¨0``ÐîÀL#Rì |ìrÃP7á[è’Ð\˜Î6aWe¹eÖÁ¾›XS6ô²™Úà‰ú­·Ç¢¸oª«i-g¿ÚŽmj ¬/å£;‹âs7“™g^çÑÐmì£ë#÷®ÇËmJWÆöôÔ†Ít…+Vuû:L_ëÆÕ¾)¥³¨f®?ÙŒ‚Ú‹ a’:Éì¶cËÔ\ >© mµ4i>ÙD8i@}°ãäwïଽµ½³8Žaï÷ÛÖóRK_o*¥p&ùóÈ«]†?ÿ“¼Än!+^Mx.P`D©‹êËȱ±”Oîõü:>x’;ÞXŒ5Ò»õ'¬r))WáöìÉÁü̲'[¬Ç7?“ÇÿÑ]}»&×h°S×^Iˆ…Ia•é¢ÏÖã¦+¶vsÇ¥ò"øÒ6XÖÃLŒUc»==áÆüt¯$©1d»œï®ãSta[ï¸Öb¹B:ƆÃqðkoÝÐ{0èÓ‰¼c8%.î›
+8o:‚©]ê/äØßÍ’Û³ a•l쳤Y–80+õÍÀ82uésÈJ2ŒÞxŠVm:°ÜÅÀ{ŠñÛB¹I;Îõ0ð.pÇ…úKn¸Õ湄pÉ °Å—ZX»¼€ Ñ2«y„C};Zz<á«ØÀ£(ï Z¸®x9hýÊÉ=Ž« ºáÐÏå±
+ñ#Íì”p>Ï|qÅæž%à-¥Øú#‹ (U™köeŠ¬‚S©lý·Ÿèú?èóc,!PNûß4òWÂ%žý‰ÏýûòWÊcsþª.À8gé)ï%mŒ»lÁà´YôÝ»ÑGIÖ¿£†”…¢~•šÏÔöä‚r÷6C•;ì¾²}©I¹G6i•ëN]Ž%¾;ög9>ƒ.»Ã7Û¹Îv÷r•Ülõ«ºÜnkØ´ë)T’Ï–ÕÚQnEáíÄkjmu/(@(ïæ§Ý­+‡)7Ÿ’ÍøɸŒ…¾r»ßùj¯èQQqå…un~ßÏ#òHQ¹ƒî ?%ØZv¯ ¨úg†wp7hîÔ¨·ë©µ¤-&g¢W;“ӣΛ¡iÒžŠ’‚V¡)˜ ¥²þ,ÃQvà(;]‰EôXoÓ b8÷OYAb„e2ùý7ÑϾ!ÂÔ—U ,u×Ö@PÖ‰–\Š6å ùJ~„.u§O8yh;݈OoÏwýß&’®)$Æ+á-lv‰î™I;ÒŽjšs#I¾ržl𨣦ðj}±Jö8®‰<Yª[Kë°:Þ£Î×2/</Rnó¥ÖÅš†J‰ìq:ÛÄõ•ö'8U°dUùÏ–(R¦­Œ›Ddν’¯tny¨o=˜-¾ï Ì
+anç³!©øù¡RÕ²Þt‡u §dëñÁrP4½4õª«õ':üo)Ëd"dÿŠ¬²‚»WdU ÒkV³íM¸õŽ°cŽ
+ñôa˜p涞<u>3”âßswƒýÈ“
endstream
endobj
400 0 obj
<< /Type /Page /Contents 401 0 R /Resources 399 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 345 0 R /Annots 409 0 R >>
endobj
409 0 obj
-[ 379 0 R 380 0 R 389 0 R 390 0 R 391 0 R 392 0 R 393 0 R 394 0 R 395 0 R 396 0 R 397 0 R 398 0 R ]
+[ 387 0 R 388 0 R 389 0 R 390 0 R 391 0 R 392 0 R 393 0 R 394 0 R 395 0 R 396 0 R 397 0 R 398 0 R ]
endobj
-379 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 195.455 734.102 210.18 745.17 ]/A << /S /GoTo /D (subsection.0.7.1) >> >>
+387 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 195.455 694.268 210.18 705.337 ]/A << /S /GoTo /D (subsection.0.7.1) >> >>
endobj
-380 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 248.586 734.102 260.541 745.17 ]/A << /S /GoTo /D (subsection.0.7.1) >> >>
+388 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 248.586 694.268 260.541 705.337 ]/A << /S /GoTo /D (subsection.0.7.1) >> >>
endobj
389 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 356.342 527.437 378.817 539.392 ]/A << /S /GoTo /D (subsubsection.0.5.1.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 356.342 487.77 378.817 499.725 ]/A << /S /GoTo /D (subsubsection.0.5.1.2) >> >>
endobj
390 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 394.538 527.437 401.512 539.392 ]/A << /S /GoTo /D (subsubsection.0.5.1.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 394.538 487.77 401.512 499.725 ]/A << /S /GoTo /D (subsubsection.0.5.1.2) >> >>
endobj
391 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 331.385 488.144 337.844 500.316 ]/A << /S /GoTo /D (Hfootnote.9) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 331.385 448.494 337.844 460.665 ]/A << /S /GoTo /D (Hfootnote.9) >> >>
endobj
392 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 333.577 472.204 348.302 483.153 ]/A << /S /GoTo /D (subsection.0.7.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 333.577 432.57 348.302 443.519 ]/A << /S /GoTo /D (subsection.0.7.2) >> >>
endobj
393 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 364.023 472.204 375.978 483.153 ]/A << /S /GoTo /D (subsection.0.7.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 364.023 432.57 375.978 443.519 ]/A << /S /GoTo /D (subsection.0.7.2) >> >>
endobj
394 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 506.475 450.934 516.902 464.45 ]/A << /S /GoTo /D (Hfootnote.10) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 506.475 411.333 516.902 424.849 ]/A << /S /GoTo /D (Hfootnote.10) >> >>
endobj
395 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 317.437 428.368 327.864 440.54 ]/A << /S /GoTo /D (Hfootnote.11) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 317.437 388.768 327.864 400.939 ]/A << /S /GoTo /D (Hfootnote.11) >> >>
endobj
396 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 352.892 383.975 363.319 396.704 ]/A << /S /GoTo /D (Hfootnote.12) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 352.892 344.408 363.319 357.137 ]/A << /S /GoTo /D (Hfootnote.12) >> >>
endobj
397 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 105.185 73.488 124.577 85.108 ]/A << /S /GoTo /D (subsubsection.0.5.1.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 105.185 67.03 124.577 78.65 ]/A << /S /GoTo /D (subsubsection.0.5.1.2) >> >>
endobj
398 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 135.281 73.488 141.505 85.108 ]/A << /S /GoTo /D (subsubsection.0.5.1.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 135.281 67.03 141.505 78.65 ]/A << /S /GoTo /D (subsubsection.0.5.1.2) >> >>
endobj
402 0 obj
<< /D [ 400 0 R /XYZ 78.37 808.885 null ] >>
endobj
405 0 obj
-<< /D [ 400 0 R /XYZ 93.716 144.063 null ] >>
+<< /D [ 400 0 R /XYZ 93.716 137.606 null ] >>
endobj
406 0 obj
-<< /D [ 400 0 R /XYZ 93.716 124.972 null ] >>
+<< /D [ 400 0 R /XYZ 93.716 118.514 null ] >>
endobj
407 0 obj
-<< /D [ 400 0 R /XYZ 93.716 105.88 null ] >>
+<< /D [ 400 0 R /XYZ 93.716 99.422 null ] >>
endobj
408 0 obj
-<< /D [ 400 0 R /XYZ 93.716 86.788 null ] >>
+<< /D [ 400 0 R /XYZ 93.716 80.331 null ] >>
endobj
399 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F81 366 0 R /F65 327 0 R /F83 403 0 R /F16 328 0 R /F84 404 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R /F72 341 0 R /F59 338 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F81 358 0 R /F65 327 0 R /F83 403 0 R /F16 328 0 R /F84 404 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R /F72 341 0 R /F59 338 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
416 0 obj
-<< /Filter /FlateDecode /Length 3922 >>
+<< /Filter /FlateDecode /Length 3829 >>
stream
-xڽˎ#·ñ>_¡X.Å°`µòð-ÎÞŒœ’8—ø_òû)¾Éj²Õ=ÓÚ‘º›Åz¿Xgúö¯Ç~¹ùüæàæ˜7F¹Û÷ß_Äãÿâ&„e\ú›5‚q#nßÿ¸ýö…si_ÿöý—ú”wLÞ¬æLp¹xÄz¦ìÍ*Ϩú p®$çðÀ÷oø2œk…Ÿñšñø^ä{ g^&¬Ãߟ_~úþòºLyuûû/á2(ôÒ7 ÀÜþüçí÷—¿¼pJ»U7˼åBô´Ç„i™Äý2ÎZ&\\Ï‘rÎ ¾þ @ÛÇ_ áæ‘­u 0¥my&Yv ÛTypÍd@w\i
-ƒ\|*"’ÞþÚ­H2߬•ÈpóHà \Š ”
-cŽ‘Ìq»a‘ÎØ챦ÁpŒ£ÒÕbµ³S̽¤|à\|Ë8ãK"-I>:Á
-a2måI¬$&šaVi“ÞKsX9â…̹R£UÔî!Ïôu\kûב%À=“¸D>mñ·ÉSD/rG£G1ê({s Ü¥ÞÂxÅ”h¢ÿz†¿tñGLàäð \ie²­ÀbwpÚ'Øm‘¿òRm6N0e
-ªÊŸâö°vÆìÌ[Y]?$¿®g+ãG´lñ¤‡Ð«rØàwα*Á
-‚¦F
-Ó ¬ã7+ÎGk@gä¥N4j TNÁ)§MÛ3¯÷:ñ’Þ{ÕVö˜G1hkgØk½m¾Ç0×NΈǭÕc‘>{Œ4S6ϼÈ×dï1îù, ¥±lm0nlÖ®,»xœñé ˜wØ‘tÌbýv¥)ô
-ªÅJuÊŽÆÅçìhò¢Ý¤k꾪 °ª·t-­ëxæ* ³úZ'(Ó®ù’ŸN o\üQáý_ÜψòBˆÕýl üñîgÜó™û¡žq?d§'îg|ú¤æ"÷­¿Èí(æZÊÈÈ.-ÚdÏÏ´wð#´÷Ò¶¡w¿ïDi;¢Eé)cç•ÔøôuöZª‹þÊ`gŽË©Lß}À ½dä•J«½eÆB¯´„¿O”–
-“Z?"ÇÄ‘M Ï;Ë·vµa‹±*K¬ÐWðnü}b R =ÓÀ˜(pWõ³†{³€ª5<E ž«Æ >ê¤+:™Ö¹×èõb
- ÊUu/!ÁØ 7hyæÊBåô˜¦½ ¦BÆÛÝjvϯ¢‹gÂNý*(øH"h™Gáÿ
-<v$zgŸ#[XO¯ýdZ
-tj1¸l^T4È:r“Ã}©`{CvûÉCv ñ©V¨ô‰·á|.*@v®Ã9ê
-ÒjÙvT}ªÕ;®Š[q0ÅMÕÐêÄT-óÄ„7EÖ%©Š^¢ÙiQÝÙ¾>JÉ´Ø0—µ˜Í¢€ÅÅ›éÉ­¾T.²n%S¾M[CöѲ²ãJMŽš|’¶Käñ“/e×#ëÈc—ŸÓ`èÖ%•Þomþ¥ÿFb¹ÒRs>]AC|‚<®:éÛv#ïc¯Ð%cßËçô%qk
-ÐÄëÜ…„…Ng[e*1 íº÷C—@lòÂpu0ÇøÌvÕ>*婥衘«©)óêéN¨ªër°ZÝBk¶gO'${-hm‰yg™†š¿°=r8~ᚪ–?çÙùuJ£™Åäd<”3ófË„ódaÉ¿k]õxļ”ÍQ ô¦Å0Ñ7"¬¦Å΢µX
-ˆÜÐÅcuí*Rx´
-Õ5€FF&h0 0bh:dåÝ*›"˜ÍZ™ñ‰EÈ™ø) ý¡ÐªåÕ·j;b''k-˜·<&9™ë3Ú„©µÒ½*\¹ûhy_ÿàþ1ûiO‚ì[ª0дɑ”êNP“÷ëú0¬ rò?ß0 .E±™æ¹’ætmÈY1ÐLâJu U2Å×ÒC€Æw+_›M |-'ÓY“"ür¸E×Èoïj s(NJg±áƒƒAák]šK
-¥›óÓñ•'ýÒ‡_ÉèG˜¶
-ÅÂ3m-|ÿ^Ê›àxS×ÙŒPšû˜SVÁ”ÝÛ¬(ùä€Ïbü
-!ä6Á¦ë—5¾}`¨(TC7œãîäx’…R¸­ð[Y$¬/™UÈÛ‰ÒÌ¿3§0Ì(ø±ø ¤¸:Œ•L9ÇèÀ!¹p’yÓÃœZ <;N…XجSsÎ8ÒFR™” ¸Þy´¶3€ÿvóY“T‚Rwòx^Zä©sJ=ÚÔUg8&¾´—zœúØαÀnI ­¤ô…G%F¦Á¾ÆÛÉpÌ^|/ÊjaуµVIÆ’_[¢já ÜéÂwøÕ§¯!(.OTÄ›ÚÏ.Q á[§‹Ú¾|´–é–¥ŠaYA ‰·ìæÛs›ÃsT³<j]¹u?ˆµ3E¤’—%LXM0.(‘$ç*Y`?‡5.‘l`IAWk®)
+xڽˎä¶ñ>_¡.ß`0ÀööŽß²Ù›á“ç’=Ä—ü~Šo²Hª¥mlôNK"‹UÅz³Ô”¨í_…yº}úôfåf‰ÓZØíûŸOl£ð?Û˜’D[»ÍÕlûþcûí…Rn^ÿþk%±
+F)JåF G˜y”ä”
+óú¬¸‚+¥à
+>îø°/pOÆ€kþßuÍŒ¤ñ‰)áB‹~Ufån3ÜDÎqs–ðÍÀPÎÕbˆqD˜ÍPM¸ÖeLBKÞ#jP"¥|géY„E‰ã‘ïþï/O_¿?ý- ábûãÇ“¿-…&J¨I"¥ÞþúçöçÓßž(Þ=#6Cœ¡Œµ»§d-á$Jº¸x0Ÿå”ÈðùË­—ß~ñ åæ@08
+b@.>DI8Ç-‰ßÁ
+™(ÃObÅ%ñ3¬ü,¥ãw®‹³6Ä{©8Nª)Ò·ŽGòÚÏ5íçÌ–g!îÀ=Úq|ñ7ÑR+r‹†.™°#ìU`SùµÖBS` ~ŸOñMþ0ƒ{xG9<ÁbÇŸœ`·Äjs)»¥%Ú¹Œ«p§ØÝOž±;qWf—‹hÙÕ ta=BÌdczÁ²#†çŒ«`DÂv 8A˜ž­<sEáÿÛð߀ÍüÑ·‰ë@|’ G“œÆ(Çžt¿rþÚ®dåa®YÐn,‘n\I\M¿s°3ÃÆ,ü
+…8RM÷ã~.œ)ØïA$=À]’*FBP”4¸Õw¯ &;a„‘'ìU ‚‰AÛÞá®AÝã—8€ad ¼…=eàúɽ›|ö¬ü5JŸÔµPú¬¸˜ŠCJŸÔ¸ŸkD“h¥ãžÁ&¨k=—Äت"êÔƣɻÿ^OÇ5aNáµÎz:ÐVkõ ãsžNq°CÃyäé²@Ž«Ky•ÐgáB|Z½µ InÄèˆÐ; ;‚§®d>9 ´Ž¸˜úâо¸}ÿ0ÙûUeÿ€0¢‹”Nƒ!SŒ®Š8ÄB̪£AN(™z—„pŸ<ÉaîÊ[C¬Ñk¹‚v' UôvÇ[ † ±fœ÷Ö”Ÿ^ë­Dµ¢:yÊh£ÉæÌç½F<‡úýÚ©ªxÈ€+*kfØûj$®ÆxÃâ+2×(NŠ‹û¥Å}D;ð4S6ϼÈÖ$ëѯù(ÅÑl¥Áo sWš-N?ÚoÌy=RN*¯ ~(ËS}¥8¥Gýäsz4ùàòÒ5é_tÕˆN¹ëªGº–Úu8rUÀ4ê.5‚ʇ0¼Ú’¯g6Mþèæý?ÌBy±‰ÙüLüéæ­ùÀü ž0?x¥}óƒFŸ”\ˆe˜Ð×H® Np
+Sy¢¸9°x7yÅ+i ç×Z4%UE;wä‡
+¨åæZÍ€LŸÑN3ÎÇ!
+}­Ê2`¿ëTöÜ‘ð…lKRu)qþl@·öèTYHÄ|zcSa‰tH Gsšï»{Þ¼¬¼>sË<”[ê:ºÅO {é@Zî%áÀß·tÍZ¸M¡’‹Ïò}ÍwiðÞ›R‹W B·Ô+·©sJ& ½K…ºx
+¬/[J”m¨Q`úr3ç˜#_¥i:aû±Þà§U>½t3™2˜©‰ªJïj!Á« Û3ÈEÚ+ŒJ² ’,‚<é¦{/ëç;¶.ÂŽ Æ¿çæ…å—ª
+·ªE*Šk
+<wT•´—I›e2γ¯Áêç/ò]qË!ÂØu5 yzÓ6
+«ú
+‹QMÝ-v‹8qTñ³ÖØå¢ü\é§îá+·&%Õ,¾÷ΣšØë9…ˆs2e±|}Ö1Tj0ç æéé)\ʬ”ÑT‡‘Ÿt9ŒæîsÞ‹ËBqïS-]Ï­™p–å0K½5+šo+ á]%[?’q©4áN Ðï»8I­ à=ÅI¤DרIrüÏqQL„“³s¸$£¶õEÁÖ§¸FóêÕcÅk?–†äƒ31@ô›fõ{¸1‹¦.§®­"ÛýØ!™„0ªæ)m\%³Ù°.å’7¦ÃZl
+âl^Wm¤Õ®‚[60ÙLÏjÙT %Ê ¼É{c™<X–KP;ÅŠ9Û—GΉbówÙXrÙ´2:qö¦[r‹-å‹ ›;¯
+Mò”lEЬd¸bu£ÄÏÜ4q<\¹œuÝ“ŒÜwùɤ…ÜEã¥süÉâlúÒ¾›˜ïÔÈœNg`!÷³NڶݸÈAÌk–òPðr)z‰ÜZ9€ÈÙ½Ø;ί±Vo¯ãÓ
+Wv0¬Zf¬e<ÎV㜜—„•3Naµ·*añºrÊï¹p¦-×…ù#N¹*aî‘ÉguÙÙK•d)Ý_埑שü(2tí©‹×¼ÒU Øú»>†1ã¬}\ò¨åÞˬ¯º@ÄÜ+ç:>«Ö¶ ÂJv+k™=™:Þ!ÙŠA]h$æiˆzxû±8¼|…Ëôשm~Ô(b <A»„f^Ž“Úfž™cð’ZÝ;2' l³j(3L„οðSß÷xP^ÌYD*¨l¶š’Ê>ª\f (irîçSÑò°\Sé‚î»͈”#oj»=ôÚ}ÃÕß*x_a ´¢¦_,ðeè6;ô·Ðû*g
+Y~õàqðÜŒ|¬!±5+K@Ðlÿ+ Þùùg®@3'J6ÜŸôÉúnt6WLÌÊgL캸‡¡}ø
+Øk´êEôïJ›ŠoÌaz“6´™e¤²Ë,Ó­[Ÿ(w•wÚxW&š:PÏÊMÎü ëŠ Fþ¶Šªf³Šf±ð<£©b`æ¸Õ*_mi¡”%vb³ZZ‘óÒÇ$6³mÄQŠ1%gº‘ËOï53oó X?DAu¤ämeUv4 ±’ÍjÜÇýü^*J9yŸ¯hE„›i¼ËŒ"Í;Œ¬#y–bÊÆdk‹*Û ­*Õ±5ŸL'A
+ðóžÃ¿¼³©Å÷¡XÆ™Yƒöù·ºåHÓå§Â'õùÅ‹o¨ñ÷Kûa_ðÒï_Ň+Fá™* Øô1'«@ëȺÕ_[üÁŸ!Ú lÀ6^›Ë{_>ÐOäóGp ˜k´‘št
+àë(-ówå¸!*6°ITEÇ –æS|œ3ß ß´#¶ç8%7yt’*CN³>IM8mQ ]¢¤$¾åɽ–œ¥äý¹ßn TqÏÁžº“'óÜhb­ÅPÊÐRá{©­-å$õ>¶¯ÈÝlRÖlÒee¿»ÛB­‡Â¬Wüyâ½H©™pÄ4dž¾hý¹7ž êü“Æeûß~úìáò4…½‰ý˜6Ä¿jŠ°(¥Ë{-—(Wrn²¼{K†°b>žÙnžšÅNë„­ùY¬æ!‘ìkÏô>[µl’P†‰DqVŽüÚö«þ` …
+šsM\¬pò-Bè ºžUºèΑøM#¦âyo¢ýXo¢·Ó=øUkâÙ³h*Á¯;Œû" tÔ.Äæ0ª½zpÍ-nIpQ²Â»cŽ¦\Ž,fÅHn Òð<³ë¾z`’qÓeN)ÈGømÜÐdÔµ¯rM‰?‰Uóck$2þõï¦T5)(ÉYר»´¢?GÞ?Ñ=}F«§ÕËè|v†TeÒ”l!º‚À"Óß~‡Ûÿ€Ï¯>*qvûoøì.äòÌOû÷öwˆTc„Ê6Eœñu²¶«î1¹A´q“î’OojÚÎì+nLo††´’–¼Z—%qhM~°³JÎX¢r·EüÖnŒm7F‰—ª ®é¶Ëý6²W"As¿ŽªYe²ªªí‰WÇÚ[Ûùç®ë^ õ¹Ž"LúŽHà¾E¿rñ?¨†&b
endstream
endobj
415 0 obj
@@ -920,225 +909,213 @@ endobj
[ 410 0 R 411 0 R 412 0 R 413 0 R ]
endobj
410 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 303.231 497.2 310.205 509.156 ]/A << /S /GoTo /D (subsection.0.5.1) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 303.231 464.713 310.205 476.668 ]/A << /S /GoTo /D (subsection.0.5.1) >> >>
endobj
411 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 225.413 409.033 235.839 421.324 ]/A << /S /GoTo /D (Hfootnote.13) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 225.413 376.583 235.839 388.874 ]/A << /S /GoTo /D (Hfootnote.13) >> >>
endobj
412 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 338.04 167.499 345.014 179.454 ]/A << /S /GoTo /D (section.0.8) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 338.04 136.261 345.014 148.216 ]/A << /S /GoTo /D (section.0.8) >> >>
endobj
413 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 438.852 167.499 450.807 179.454 ]/A << /S /GoTo /D (section.0.8) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 438.852 136.261 450.807 148.216 ]/A << /S /GoTo /D (section.0.8) >> >>
endobj
417 0 obj
<< /D [ 415 0 R /XYZ 78.37 808.885 null ] >>
endobj
41 0 obj
-<< /D [ 415 0 R /XYZ 79.37 484.241 null ] >>
+<< /D [ 415 0 R /XYZ 79.37 451.791 null ] >>
endobj
45 0 obj
-<< /D [ 415 0 R /XYZ 79.37 463.953 null ] >>
+<< /D [ 415 0 R /XYZ 79.37 431.502 null ] >>
endobj
418 0 obj
-<< /D [ 415 0 R /XYZ 93.716 84.945 null ] >>
+<< /D [ 415 0 R /XYZ 93.716 80.331 null ] >>
endobj
414 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F84 404 0 R /F73 342 0 R /F74 329 0 R /F75 330 0 R /F15 326 0 R /F64 325 0 R /F22 357 0 R /F65 327 0 R /F16 328 0 R /F82 367 0 R /F81 366 0 R /F71 339 0 R /F53 337 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F84 404 0 R /F73 342 0 R /F74 329 0 R /F75 330 0 R /F15 326 0 R /F64 325 0 R /F22 357 0 R /F65 327 0 R /F16 328 0 R /F82 367 0 R /F81 358 0 R /F71 339 0 R /F53 337 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-426 0 obj
-<< /Filter /FlateDecode /Length 3139 >>
+425 0 obj
+<< /Filter /FlateDecode /Length 3099 >>
stream
-xÚÕËn¹ñ®¯˜0—¬âðXš6§l|[ì)Aöø\òûañYd³{Z² ÆÒt“Åz?)yùã"/??ݾ>ýtWæD°`õåëߟT|!/êâ‚@wqV iÕåë·ËoÏRZ/%Þ㮟´2ô¤tVJýrG߃”êK|¦¯¿ý%Bwz]!
-´a†h) Fˆ¡EÐãï*O§@ëË)~IHOÑ*`†tˆ+€Ö™ ®.ãk|ÿ¤g®@[ó¬q†–¨m\Õ·ÌE¢îù÷Ê‹xdÄœVÚ²/ò¾ì«ïážùce]—w×u€×OàŸ« iØRÅ۶њ
-6¡æ7ÀL‘Þë]ŽýiþÖø>iœBIËeEGG­‘:¼e4é<B¹¢ƒ€„έèÌmËGâ0‚~æOë†Õ› Í4vø¶àj_ò~̲J¼¢Õ¶D0èl‚·lI6mÈOIò;b»{®Ó¡F—C1®fWT&ÉÖLÊî%“[‰£ŸÙÛyñº•Ñ eºÁñ3› fVlÌpmÌJá•ßÀÞ3æµù)m…ˆñeÀ¾/´!ˆ¸•=²ÍÛ[ýyýù!éÕçõŒv„çÑ™%uH+åLO24â{ÑËÓ ˜QèòRx*]ê6 ÉB*o7Z‰8{–òhҧ三2$Zsþd°K#C½Ô«}“=tñ(0nÃ
-
-Ev°†¢Saéåè¼ðæ“ ySmYˆÍ.Ÿ3»yÞ—¢+úz]ÃI˜¹—ùZaÒòô)ÜÞZ²á* æ–œô°Aan%’½ ù‰žªdªW¦r­ÒX]'}dz‘ᤑOö¥z¾ë–þ§9‚‰Úˆ¨ Íðí5]¦¦BL® ö·ÎÕ¤í/uÕVñ=z,…¡ .þÿó®NÜ!âü÷itIÌ>8a‘,qÕ
-æäM¤mÞVª»-š$-“Ÿ…â3ÓӪآp<ùÎK›³•vFéKµ{[–D4õÝÄڤ˽SRÂ’†“æøçfGŒ§4'¯ž4gКL22 I$Ô 7’‘ßÈõÎu¿®ì%á¯_º6ôsvóXcœ@s;ÅæGÐbe^tb¢eÈ«YZ×÷ ž| nÐÕ„ÕB aèæ¡çqÝISE’LÝ^üÁò ÖSƒKÍ4DIÄ
-«õÒX¤gyMMcxö4œ²c0:Øéœ7L̼ŒZA©*?uªšt¥oݵPsà9GÓlàÞ—­»|nÑØ+µË¡é/” †o„únbrù¸a½Ð¬€”úÅ
-A8Ä¥T]í}ºÃâ¯dRèø±”Tô/)±p;Q;&d{#UÚx®'£¢]n 4ù¸êhÀ…‡š×V-åYßõ_JŠõIƒwÙ Ûô´õLÒŠX^˜aˆòÂ¥QSâ¼vN=ÊÓßQä œÒzÃ(·ä›%¥Ð­Ãïÿô§ƒNË*µ®Åb:§bàp~­s{Þ©HfIßyÊy9[WÛ»ªì{¯ ®¬¥ç÷âÞš,{|ë^µ°Ýè1\WÃsŸ†Õ\Ø•\¸kVê¹¾®›X¼e’Îzi|TWíáÄP®ŠûŒf»¬5ÖÙË~Ý2ñ€û·¢ö”~¨¬Þu¯¡÷µÆ9TiîL9x¿ÈÇfÃ'áШa÷¦ŽÂnyùÆA@x óIËîx'zN «ŸL¥ì`éÉ*Jùm”ª«Db°Uûëe@0UQ-›ïa³ö“ìîØNÎhcÎkä‰ô/£Ë¢²â{ÒFô1ÙRÓ!gUŸXΛ?0©% 1ÒΔqænó‘ûý]6ßZôæv~ ·cçn
-Ùï´ÖÈ[tŸÖØ^/$´ë3vÝd"âž{d‘÷LFÓ•žÏ}BJD£eÄñ3܆Ð"ÐBAø_èmfÒ± FË{ïG>­x$¥
-Ôöaݹö~ÅL@lÙ,|ZD•_e.ˆ)6{C¿xTûy©É£†ItE¬÷òœ@kfhinœ
-€Pè§Îe|Y2Z »ÖàÆO*[*uHÿ.óÏDíú§^‘FÂ|ê5u*†t+ì\qŸ‰º°¢HƒÐhw)öu`…Öz>{:TÂ:½Â´a§÷¨Ã¨é^=¤NÿêƳQ·Å´ü‘ÜëקMd%»ÂË_¿=ýö{|ü·øù…P‰®ê?iá·‹rZXEÛþyùËÓŸóßò9u‰šâœñÜJ}|¦ô…†e÷Ñ~º¼¸¸OFxܺQ8ei»îW œºúP¯a½{ £…Fï]Å0šêÌæ:ŒžæaaofÂ
-{P$;3¡¿ÛÝ_³
-óÒ:kÂæ:Ë oõÒðpùf‡·4ö|Àm]Åïãfvm~Òã*„c¬Î``æc>ºµòù˜ÇG#3¾«×±f:RùãËÄõAoø8“º ¹xEYú¶­j¬&§qTS™i~ôz1Ž_tÌÓX_´9Éÿ@{]>
+xÚÕ»Ž¹1߯˜¬âX, Ñî8G¶•.²á l¾Ä¿o’ÅG‘ÍîéÙÕp0Ú™n²Xï'%/¿]äåëÓõÛÓO7e.A V_¾ýãIÅò¢..tg•V]¾}¿üò,%Úñ¯QRZùò 1ýBÒi)Õ)õ5¾ßµ§çðšVé¸JÇ_6Hu³ñ/Ô§F¿|_A}ÒRÀ
+¤7ÇUu£Kke›ÖýúíçHŽÓ+r"8á㣉 ˆ ¢k°CJ˜è×ø]Ñog9é»)$[‚˜ßÝâÇÑŒí+Á+ÁÑÐaçu®`¼€–J˜ˆé„qfr‚p«|qðî™sÊ&¬µ¯Ã[Úý’¹í$ý¹›V tÜN_Æ7b'tüØËïI‰ê¿|”
+˜![8aÙàZ,Ãøþ9a`½Ðˆ3´Lmãj•2ÙE—x•—³i¥-û"ïË>.Ori´®úZXœ ÒÕá.ªˆ·mKk*ØŒšß
+0ÍÅ®› ×=›áÚ˜•
+Â+¿½gÌ;.V[¡pR|ß±¿·úî•Ù¼½Ö¿/Ÿ"?dzõyGA=£áytfY<ÎÊ™Ÿ´Ä÷¢—§A1£ÐeP„ÐÂñu–‘eTCʬ”ˆ³c)&uê+Çð¥-Ó‡À.m õR­ö-öÐã4¸™)¥ ƒ5
+J‡ Gç…—0d’+Õ–ÅWò÷œÕÍí¾òd³r ¯ï‰éÌ»ž;UK¶Î.ÌØj 7cÊW›’0·ò W³ŸÁWWûNcõ›é7^™ '|²¯ÕíÝY·t>;U^(Ð-p©Åø-–¤<2þûuW£ w"îUè’•}qÂ"ÙÄU) @]¿¥s že%¶ÈU–ÑÓ½ì¸ÐMœª‡ª…-²ö€æüÃbÃne+´pj›Š¯y¸ü´‡[ÿÌéçñÜmÖ¡+¿‡›µ]éYÖ<,¿¨v—õUÖ*«h2Ãö„Å6 ö-v‹y¥×Öºµ:c­@Õ=¤!mMS¡µÊ³ÙWÒÑþËHzRm2áÚßV€½Ý±} –¾ÙÌ“7‘vÕ–ÉÏBñ™ùé¹æ€ä ;ýÚÑôÆÕ"vìÅkiXÑÔwi3.÷NI=
+KÞkí¢±Ò>¢9´zÒœAkˆdd’I¨ém$ƒÞ”n ܸî×Õƒ½düõk׆~ÎnNhƒs;Åæ{°¨ËÓ‰™–©‡Òrº¾ç°‚hðÌà£Xpƒ.¨&¬ C—ª†žÅu'Ê?µÈi&£Ù¶²ðG&f¢$‚ŸEñdfF‚°€óIƒKøý· }É­!e/V‡±Zà˜ˆq‚£E<¿ÁI„9i…Ñø™vhoEL›~€´¤p&2ø^†Ÿê5a‚Ýœë ®IÕXJ3†Ž!&No1¿ÓM&}:ùIT½QŠ¯Ft† ô±†>ú>11âP±4¡mâcMûJ]Þ-oY²_wÖЖG’0ó °ªï#M'Ž¶¯.¾‰~ Ð|J_ºÛŽÃÔ§®šÓ9z:¤såÑ™tn…kåb¶<èíÏ~Z+ÅYÃ6q &hÂó6!Ë'dÚ³„Ý–7éi/æX ·¾F»$%çeŽ]ÖcGõXDGm´pèxÿ’…—m%è
+<OŽ,€C8R%³*ÊÙ÷¦øÖ±l{J£kÌeÖ•w‡¦ÜAáR¡§Ø=8WnnZv¥í­ºžV¥æ¹ÖnŽªÓ,\oá\4° 1(GP`IŸ2éZ3}£ÍÒ¯‡Êù¼÷nj”WYÆ€ŽtN: }–trë@­ŽrÞüvè£5
+:u›”ŽžÂlë®é„œû4ªyvEàTs•ï™øBâÊ ï`77µp¢Ÿ’…nìïžzìŸçÚ±km£À*6Ó ˆ\ÐeÞôÉäŽå¦ëe;[ÜÉoKÖN¿Ô ïa¼ÓóQ7Ý(悵ƒ`7«h[Ÿn’+‹K~îP³lLü‚j]æF'%|{4âiÝZùÀ¥ON^wá÷¤Ò*¬ó/¯Öó¯˜Àa˜é¤¾È‹QÏ=}<Ió^€Ùp숶…=“Ô#ÄXQV1kDrzÿ@Ö„…ìc]>L-ìÓsÍ5xLb†]Ï5Ð ÂtÏK˜ÊíNG,if š•|XÒ©®“\O¦ÚxÓ³e%"°Ù½Ý»Y—OÌh½ O_f5mhtÜ®G%PmøÑËÞÕlcÌîuÈ÷zÑÊ •…gæW¨PZíί>·ùÕ ™¦ööËX•Äj5Øç»×!îX ØX“™¥µHÏ›šÇðôi8eÇb4
+„;žó°Å¸X”ª”ÚªòS«ª‰WúÖ^ 5 ž“4ÍÆí}ÙºÍç½R¼ÚNšØ°aøF¨ï(fŸ&¥¹šUp‡R¿˜`ñR¸ìo-ÔMÿ<¿û|çnOUŒ>¬ _|¾OŠŠÓyX_Õ£Õ@Ðû²woŠJ°x¯l0Ós¢-fìù*î5–$ 5eöAGýy SñZçt´w% ÂWR´–ÃïP4˘«î÷
+wè/¤*AxÔK©ºÚüt‡ÕßÝ›dn'lG}J¶7bP¥çš2Ê 
+~"ý1bu¯
endstream
endobj
-425 0 obj
-<< /Type /Page /Contents 426 0 R /Resources 424 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 345 0 R /Annots 432 0 R >>
+424 0 obj
+<< /Type /Page /Contents 425 0 R /Resources 423 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 345 0 R /Annots 430 0 R >>
endobj
-432 0 obj
+430 0 obj
[ 420 0 R 421 0 R ]
endobj
420 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 504.396 553.865 514.823 566.664 ]/A << /S /GoTo /D (Hfootnote.14) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 504.396 526.966 514.823 539.765 ]/A << /S /GoTo /D (Hfootnote.14) >> >>
endobj
421 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 323.794 430.329 334.22 443.058 ]/A << /S /GoTo /D (Hfootnote.15) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 323.794 403.43 334.22 416.159 ]/A << /S /GoTo /D (Hfootnote.15) >> >>
endobj
-427 0 obj
-<< /D [ 425 0 R /XYZ 78.37 808.885 null ] >>
+426 0 obj
+<< /D [ 424 0 R /XYZ 78.37 808.885 null ] >>
endobj
49 0 obj
-<< /D [ 425 0 R /XYZ 79.37 708.969 null ] >>
+<< /D [ 424 0 R /XYZ 79.37 682.07 null ] >>
endobj
53 0 obj
-<< /D [ 425 0 R /XYZ 79.37 381.504 null ] >>
-endobj
-429 0 obj
-<< /D [ 425 0 R /XYZ 100.292 166.346 null ] >>
+<< /D [ 424 0 R /XYZ 79.37 354.605 null ] >>
endobj
-430 0 obj
-<< /D [ 425 0 R /XYZ 93.716 94.891 null ] >>
+428 0 obj
+<< /D [ 424 0 R /XYZ 93.716 149.755 null ] >>
endobj
-431 0 obj
-<< /D [ 425 0 R /XYZ 93.716 85.263 null ] >>
+429 0 obj
+<< /D [ 424 0 R /XYZ 93.716 140.128 null ] >>
endobj
-424 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F85 428 0 R /F22 357 0 R /F16 328 0 R /F81 366 0 R /F65 327 0 R /F75 330 0 R /F71 339 0 R /F53 337 0 R /F59 338 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
+423 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F22 357 0 R /F85 427 0 R /F16 328 0 R /F81 358 0 R /F65 327 0 R /F75 330 0 R /F71 339 0 R /F53 337 0 R /F59 338 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-437 0 obj
-<< /Filter /FlateDecode /Length 3760 >>
+435 0 obj
+<< /Filter /FlateDecode /Length 3466 >>
stream
-xÚÅËŽ$·í>_Q?0Z‰¢^@c϶ǀsr²7Ç`;@vƒ89ä÷C=¨W©ª{ÆcxÞéRKÅ7)–Ü~Ùäö݃ܤ@úØí?q€þòÝÃó§‡/ÎlA ·O??¨8cS› B»ÍY%¤UÛ§¯Û)áEJ ôqO?}úž
-DÜ­6R:I-åcZ9ƒPÒ6LûOÙ鈖G„¬'ak‚iè7+ï"¥RF¯÷¦Õ‡{ƒ v«(‡W^¹ÞO+aé§Wß²:¡­9Ø(XHY^Úc/3„ vCf™Á+QýùXfœw2` ËIÜ0îÎ_û½Áùy­ ë| w³áúš³¨ÃŽÒ>+h¡ö¼3()öâÐÔ¢  ã¿mþ›YÿÔ!`„µCLÞAF ¡#¥Øá·f°ß)Ö±rk'”Qkå~/eg…÷ÂûmfU¼=¶‘Gà34rü~)«‰ævÞO¯HYO4wçؽV¬"ã>&Ü£Œ¬ÓÚµAX»›é»–"’oÌ}R´”ª /ã>aŽ@êiv{„шEÇar'Ni8Bcm‡k‘¤ë;ñ @’ùU»ýîáYµÓÚ#Í/vbšm‹‹±ró¤YVûED#ÉTc¨kdÒÌGmeäús¡ê5S<S7™fš…úåéQ]ÝË:,Z™Â’À£RƒWòª¸>ò2ñô9ïba½Òhâ˜mâ¯xe(1ˆøFhÿ8+â’g P1Ÿ*î%€gÙ"SñÎVZÐN/Ï؉/÷_´Oà/yNÚ%ÒÀ„æúiPÎŽLyÙã0ÒËIÍ\ ý“7eg§újƒ!`/ý'9ª>ò·DÄ]A—}<ÿê Ÿ‘æC<aéí¥È†qÝé^×UJ–£êdxþRN]W$n¾0EŸÓ–zú‘–&–3óŒî gp&{ÉÖ 2€…"±²K5D *­¡%(Xöf¤š²bÂJ1Qá)JŸY……xa†²ToÔ ,ÅÙ (ùL…mEð™†5MØ D¡Œ6¼$þ óRHzcìÇdI,düŬ„%Íß’4—Ñ#ãRé¡^lÁÜïø›WœŸàËÇ £a%ó™
-%)H°¢ßoðÙY0¼HÈÏ"79Bxá_[Øøf)ÜÅRaˆ^%©âMIM3+ÃÓÓŒðßëÏëÜ6åªþ³ðTE}ÈCÇŠŸÌâ:Á dSmF猫.ŠRg²÷èRu©†Ýt<3¥«”¦*ò¬Æ(·ª­²ÂS^ÈÙc¤cÔ¼o(R&Þ\²¯àà³gS féÙœž8ìtÀ#E`µê<9G,8êCš“…²xuRè4Á
-oªW]–kF¨g¶S–Ùpw'ÖÑÓJ˜§„\é#°>Øž€Ò°;_uMù¢èç3A§LQô]ý<«ºóHÔdvTùå1šö Cîü•=³Þrö&hf/ƒ6Ë]ÆX9ÿ’âù.whl)ÅUFÙ³®3ÚlœÛ““å …œ°¨âóB·ÂhÛ‡}8œªQñàj駂-bž°Ö.˜KG’SLo²Â÷]Ù€–¨¬F_<sЭ„F/£÷É1Â~ó
-fä—äƒ)Ö“–0&Çvql0ï¯[hLªÓNL{£na (°ƒ6Å ‘q((zD¦ZÕe ýMBÓʬêÔåtvïÈθTD™°‰±~“–ÏS¿£ü²”ãI˜w‹êË6?Ÿˆ¥¶? #ð³úôj›ƒÔò2Ü­Q@;PÚ%>6
-À·¥$°‹¹
-ïÔ»PÈ>¦ÎBŠ,å»P‹_=EtGûMÍß0Œ¶zmNì‹Í«V
-4Öh¨¨b­´\Q¶†f˜Ï¯é¡Œõ§óþ ÏøF'ú®dx-€Z8;i–Ž•Ýx'‰Ðè‰I;2FåWjǯ;N[(SÕËvþ®Ò]u†ÆƉͺnóž÷JÚnyz!Ó^8eÆIWéÓúÎì: K1KœZ‹1opš`§}L”G”G /Ùö£±@Û#g9Žw÷‹_°|µ—>·Ö¦ŠÏHÂ?È"9RKiȈÌIV£ìfÉ¡koF0d× ù2CQú¬§¬æ4'F8é«_Wc~Oüš½wá¤4§r]Ì]âú̳΢µ±IJ¿8‚Îë»8½zÿ˜I+Zî¨Á1Óþbâfܤ­⥙¾S
-œÏW3‹FàÛAn«5e’Ì¥™ëÔ^½÷–ùSå9¶£f¶Ë¤Éœ÷^8áÚmö¶(UQL44CûX®üLÔúÿøJºÝ+á‚ÿ}üà-y*¿Ëü7=—±£Útœ»ª§EÇuø’-Â
-0fÿ܆Ç?ßP›™:3T‚Ž$ó¡zUöH6Â.Zª ˜Ãk¸Ò¸…ËGî1ÖÚ
-­~tmŸxÿÂùoŠ‹8uƒºogsÏ0á_Ù¦ç§NäoÉH¡dê%a­Ø¬q'wåýе[¯‹Ÿˆ®7ï‘TRV»|Îó‰þ
-(ûx<„[¼-àÛOh@+HÓ·Ï_~ÝhÚw[šûꥨÿÛÒ°€(þýËÏúü7%hÊã°ÜȉE!ö×ühb§šÓ¸})Ï–e¬ß”R“ü/T4ÖÏÛCì‡ïCüQXí _K2Cá}ƒß 1
- òv_úAFªm‘ŽÄXć¤,´œÅÇøéŸy*­úÇöðóöðC¡_XÑO T.ÚüFCêéXÇŒ0
-ÈUSðêS™Ñ
-çA6
-‰lLÍû¾ÁÃ4š`¯=Ô]òǰǶz´ßÔ>oœp°ƒò ©Ÿ<¢±óì‚Içå&Ý#Eý¡Y†Çb›mø!Ù“môì*;_™´=¶— Ðha–rB«ZºÒ¾v•¨çÜ瑺 ä“Õ—®²ÿÜ·œ™’Òöý'̵R‹)9äYŸ‹
-Z  “Üçb bdôS-h¾%H»sc€µYÍ\¦ûˆÜýâ»Dû”Œ;Àql«œ¡Ð\ïQ_æ#x}kó³lH‘‹´¡å£Pî~Ð Æ»°æZúö¸£Ã\@³ëë«…°hÆÃV°³| --‰Ž[qב€ö÷¨®“ÏWjG ·Õz5…ŠìÊm-4Kb¾ñ’µ¸Ûð¨(‹\œíýˆme}—,Q®éúÃÕNÅš?×~}$·©Î¢[gÐòfQÅÒQ××öm_k-,c; ¿`w­÷ðvB+o‚š1z}ùû<'>R.6mrÏ¥»6jyÜþ’ÙÙ›wšbà
-øÐm(S_+‹³f»ý:ðÓÌ
+xÚÅÙŽ¹ñ}¾¢`hÅ ñxV6ONü¶Ø‡…ƒÝ
+ÀÛþEüð§ÏŸ޽ݢˆN;Ø>ÿú hƦ6…ñ›wJH§¶Ï߶ŸNRê³”FãÇ?ýüùGœ7@°‚mZ<qe±iáT¾"F¼TI)tÔ»µ?RJõAJxÁü¨üÝè±
+ ¼0ÎÎЬ•Ò#4@—¿ ·Ð¤‰…’®Q2~<tÔú·ÍµëW=õJ
+oõ¼Ÿ5uÊŠÌ
+»D](ÔÅEÆ eÕ!EÃú{Q§
+ÓŠQ§­PÑ^¥¾uãÞרÛcêyÅ‘õ^1]©„öwšîäu¦;®%3%³%3½dªÌ¾iu1ÕCÓtÿ˜µ¤ßÈG&dm|q7ò&F²qÎø¥Å‡;k$^Í‹Èá…®w+êôºÝŒQÂv+nu¹ò®0²¢´Ç^Y¬6ºDçâÍó±®ø <̲·–Õƒ¶£½ùk¿o0"ú0-õq½NÒrž¬_^Cg&Î<Ù( Ÿç}5†4K¸ƒ³Òèv‚V3ZòjT54„»µ¤4ª˜³)³GÅò‡~û>ÖÍ66î·ûÈjl{l¿OÜt9îæýÌZy” Èr»{`ÅÆ1îcã-VÈV1­=0÷…s»ÙÄßµ9+@ߦDK¥Êà2êâ Ñ2í¼Å³Sæà
+¶ììÍÊR5þq½æW”, T}ào”  hSmÊ6ßzIÄùšC$ƒ;Õ°¾#.¡y]e”eõ±ª>é /œ
+ÑuEæ™úô˜¶4Ó $"-MgÙYÓóÍÂÌõ<2r­c
+Þ¬XHNAÎ4iÈhŽ¿Ÿ©Ãχæ3“§qW}Ó%¡
+¦ÆÒ%6ï4Âõh®âºŒGw5ë3Ï})WÛ
+ï`¢Þ×v Ô4–ÓÏl™œ²VÔ­W O9ÔÞêtÔÑâ·GÇ€R6Ž®o(´\Õ\N¥{öÐÓaüÅ|ÏH-œ43?rß yBÎÙrYÝmNõÚq.$EÐ󩨶vQTÜo)¡¡vˆ2ûew­x6žõ¼³£-j…‚6wp³Jƒ°FÍwꃤdÆÂ"Œõ Ö¤vùU_äÙØòxý
+ÿâŠJ€òèó;òPÏÇ:f…U:¢çš†H¼Z6
+õ*N¾B+ÛÅåvcw¾r[oR¼Œ·{…¸BA9äÀŒÃáQÚš…,pr¥a²¿<^HçÑk—‰o¾eáÖûXåJnw ­^ÍUÝSc}¾|Ì»{ù”<¦%]ÓMåj\!\Óm„‚v* äݱ®«Xô¥š3õ´ÜîR€ínÊÔ|SÆ¿´k˜ú3õk—VãP..)Ò:`Æf’´¹Èú9–Œj^EQn¾
+
+Æ=8·¸~ëõ#Ø1Ç•†JéX–/íú‘8²fnÏkwÊä‰Û±v¸AdkWÕMgò¡»cn’ ßf°Ý5ɹÝÚŸP(e0É«ž®]ù]+`wc𰸘—¦ª2Ýœa6þ m
endstream
endobj
-436 0 obj
-<< /Type /Page /Contents 437 0 R /Resources 435 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 345 0 R /Annots 442 0 R >>
+434 0 obj
+<< /Type /Page /Contents 435 0 R /Resources 433 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 345 0 R /Annots 441 0 R >>
endobj
-442 0 obj
-[ 422 0 R 423 0 R 433 0 R ]
+441 0 obj
+[ 422 0 R 431 0 R 432 0 R ]
endobj
422 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 141.139 720.613 190.205 734.56 ]/A << /S /GoTo /D (piton:transpose) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 141.139 660.837 190.205 674.784 ]/A << /S /GoTo /D (piton:transpose) >> >>
endobj
-423 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 140.107 641.438 149.903 652.954 ]/A << /S /GoTo /D (Hfootnote.16) >> >>
-endobj
-433 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 488.456 523.721 498.883 536.086 ]/A << /S /GoTo /D (Hfootnote.17) >> >>
+431 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 140.107 578.803 149.903 590.319 ]/A << /S /GoTo /D (Hfootnote.16) >> >>
endobj
-438 0 obj
-<< /D [ 436 0 R /XYZ 78.37 808.885 null ] >>
+432 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 488.456 460.471 498.883 472.835 ]/A << /S /GoTo /D (Hfootnote.17) >> >>
endobj
-439 0 obj
-<< /D [ 436 0 R /XYZ 100.292 761.061 null ] >>
+436 0 obj
+<< /D [ 434 0 R /XYZ 78.37 808.885 null ] >>
endobj
-57 0 obj
-<< /D [ 436 0 R /XYZ 79.37 629.095 null ] >>
+437 0 obj
+<< /D [ 434 0 R /XYZ 100.292 761.061 null ] >>
endobj
-61 0 obj
-<< /D [ 436 0 R /XYZ 79.37 231.659 null ] >>
+438 0 obj
+<< /D [ 434 0 R /XYZ 100.292 701.285 null ] >>
endobj
-65 0 obj
-<< /D [ 436 0 R /XYZ 79.37 207.265 null ] >>
+57 0 obj
+<< /D [ 434 0 R /XYZ 79.37 565.844 null ] >>
endobj
-69 0 obj
-<< /D [ 436 0 R /XYZ 79.37 184.645 null ] >>
+439 0 obj
+<< /D [ 434 0 R /XYZ 93.716 142.304 null ] >>
endobj
440 0 obj
-<< /D [ 436 0 R /XYZ 93.716 99.488 null ] >>
+<< /D [ 434 0 R /XYZ 93.716 132.611 null ] >>
endobj
-441 0 obj
-<< /D [ 436 0 R /XYZ 93.716 89.795 null ] >>
-endobj
-435 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F75 330 0 R /F74 329 0 R /F60 323 0 R /F62 324 0 R /F84 404 0 R /F71 339 0 R /F64 325 0 R /F15 326 0 R /F65 327 0 R /F16 328 0 R /F77 331 0 R /F22 357 0 R /F53 337 0 R /F59 338 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
+433 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F75 330 0 R /F74 329 0 R /F60 323 0 R /F62 324 0 R /F84 404 0 R /F71 339 0 R /F64 325 0 R /F15 326 0 R /F65 327 0 R /F16 328 0 R /F77 331 0 R /F53 337 0 R /F59 338 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
446 0 obj
-<< /Filter /FlateDecode /Length 4341 >>
+<< /Filter /FlateDecode /Length 3979 >>
stream
-xÚÅ»’$·-߯˜Ð–"ÁwÕÔss£*9²}™J‘l)°ÏUVâß7ø
-+<p])¯ñÈ"”žNäéN01b|§“§„(­ù¿µ ÓÛ-ù¥·íæ¾L.Ï2
-Oÿµl›ß«ŠyÄæÖã8,¤=#òzEђܲµlR·ŽR°È/R:ÇÜ]ŒuLiA^¤CáF¯å´)Aârz$ò–~ª¸']¯›wõ‘âŽi7«Žlo/;Óf‹M¢’F (Dg„D×Üi¾Ûd›v×Ϭ•¶'E
-~íÖÜtÜ1FQÎŒ{€
-XTÊwÂcÒû X"P…³è¤lT^ìñºÑê@ŽŠÂsW-Ø}Ëbп”bÄ„¬hö€’ê…N‰R´‚|ÊV[¶Ò¿ôy+xi=û€q¨…G=Jú*;]Ù[WlåÖÐr;‰q³«†G
-q\Y]ë‰Eiþ¶ôêà6®:vç0V_mGË×ñÑ nÜÍ)v2PÅLWOT´D‰&?{¨½áÜv,µ™¼¼œ~0ÒaÐMúáIçæžá
-pÕ¡‘³C#Ä9O æõÆÐ|Ë8<ø6VŒ¤`¤áݤ î™žpmüuDŽ‡Í窪×É’&ó1"bpƺÈ$ŽOº¡8& -³¶Z'=Ù£‰
-$ÚÇÖÆzæ”X­bxÜð,JEÚ Q`0¦7å'!ŒãžÍIÏУÆE%ãàÉ’kÜÊ¿+!Äq91Á¸`ÄðUƒ,Îön6 ÌÎ+oÄ^!×%dµb©Ä¤…:)qÆ¢Ë"‡¾ž
-#XÅŒ«–§ñ÷""äK€6H”àÆ#èf.Ŷª¶@ ð{Ô×ߣøPnä
-´JP‰°ª‰Í" vZ»X:ÔI­Úò±@Û…§’žŽ\Y"#_F,S)éha*^¥9g☒0âðÜ7ŠÀÁ$õ+“EHFªfÍ•]Û)“¨MÍ#ìá%‘+5ïÃkâN½«ÒÀ„kŽe.˜Ïj·²·æ7©Q ùÓB0ZJw«?d)Ý®¥¤´ÈVµ«îB2"m“´iß”$É–¯$”oµ‚G ¨þ˜–Ù 0%’ˆ£.ÊA`´Û¥kÆ~iñ‹¶ŒŸ
-ÙÛ 9x4¼
-k­º6!îM׊©$(•¸²CëäL.y¶ÂåP )PñØÃ!y~ öCÄrãŽál¢ýQ|‰SŸs"ò{MŇâÖª@TO;à÷vô X‰g”7Lé¾&(º,h+&•áŸJ;l§ <³Ú,7ÿV}#í7ŒTÖýb%G}êÏÚÃÑ+ÕãÊ}VµÏ/£÷Ž®'Ñ+æœñªïCâ^}ÚRÖ-R™å,g–Û¢¦\Jü×ÀÛ+‚C';$¹ÝNédycªÐ¥3 ëŸT^ËŸ*óQ?¸Z—~ŠŠâ¼6uMé”6k$U€j¾ü¯Z[-!µÔã^zPŽ¤#b'Ó“€^ƒtuªJ¶Î7À5FÖú£p4"ß)üø$›]<ÔÒ¯soiP´]uì„
-p¬TÄCt~l÷ ¥ê5»P•
-ý]R½.ÈÍM[ñáf[Qã[ÝÕ×›ÄN|³iâªm…&ÂÏí*ÃEY®ÖÍK ¬–ï"£´MW[±6×£yâSÊ)=YÿJ—€u}¨ôäjô¶h?n—³CÅ+žY U¹|æ€æ‹V{·©¶m»H¤¸g ä\$²¢÷Ã`lEÈONuxÁœNÚÚKý¥žy:eG–ÌÃ7ŠÁ ­¢5?©Lê1!‘ Rkr µQ€½Ž1˜ºO`§§u°Ê~ón߶s¿ŸjÐYpÆ\­h˜
-éÚÕŸƒÂ9ÅUÒcĪ]›|”¢xÜÚ!pIí gë¦v÷~œAh¦õÕ&ÎzÀYX:ɸÓêÎ2PÂ2cOÑ{Á55Ò¸¬ÚŒmšñÕè!½Ã‡æ9zìGëR2!&ÊÖsÌy—®¬4{PŒ~+4¹ ŽŒÜUÒZôùÄ*ÐOüäýi¨˜@G5¤CÈ/VWƒ…/Rò¤ƒ†sħ‡`iÁû•
-ô{1&x?ª@ïžU]ï&LݪéIëSÛ´¡ÝmJ{íªF´ÎàåD³¢íóªOÚ*ӪšÒ›Xæà<æV0û–˜¶Å¥éÛÚWˆÀЊL°Éƒ*2rÌ„ÐQwPé êêRr³é{w­ý ß”6Û ‰äв¹_ !‘Q
-sÁ*ÿ€Ü3"¦ÖBq…ÊÔq1ÎZ*Äó³l› ßÑ¡ vwKüë”Ï4Ø÷´pHfÁÐ>¯îö3Þl±ãê}î¢Ö-jŸ-þ¨F —%GÙVÐ6ør¼ Pï/¦(¤®mî]^eŠú6’±=[»½»3öÚF/5ÉÚ´£íÅýBZ&¦-N:!PÐ~¹ÊAWRF g€ÝmåinoÎÛUk»¤­KØIv#®6›‚,—VÃ-”®}¶Uè¢Ëv
-·\rê¸L
-/då„c§ON\zrÎé 7%:K¨øt÷Š@±wx}†)TP
-jÕ€üJS÷I°úþ=jwwFŽ»§Ê‚]Ój‚¬JÌ¢;guêR•V©øi7¡§– ÈJ·Š<誷Z6-#µ‘H]›6‘­ilâµá¾Ñ£egKf¹lïkçm4öknÕÈ) ̳էͳD‹wåW%ñhþd¼*¡àœuVLc<8
-¿z}ͤtà¯:3»ÞúxÏk·ç%AÁôð7Y>6.jð`YŸr-²)zÐ%’iK—7†¬¾ ¨4ÛlTºÛ]à¹Ê ùEÏßñ÷ƒÆÓ7æópyô_lW‚—®ümëè¶á]+ïÒ=¨$#‰ÐY4ö…Ø0Ð[›?-ÉŠ%æ§4lzr$ÃiØ– §·%ÿkÛ`©%8s`-¤m‹ðªR‡ Û½>­Fwà÷–V Ìøqsí³ÐɃÎy“çÙz+‡ñž´­vLˆq‹'€+˜sn‹®¥q„7§!F4ЀêZÚ—Þ²ÌÖÍ·6î,í%5…s ¼Ý×8*öoœÓ8¨õ\ºÕ:žHã„[$ð®K:zE¸_OåÌ][nòÉkš<ãÞmAþ´¾R¥'è+¥¦o¿Pâ}•†mÞ,ŽoI_¥-mû+­"¬aRÁXzßÒe©vK—Á½íNݾvÙM¼{¢Ÿ\“ç¥ì{¢ ~ÿÂ6Ô)W®ºwWv¶ö}¾G,Üp\ŽÄþ:Ý.ëXÀ«7šCC:»NÜ®¯PÏ´ú#ÝJ±a~
-.†6ˆf9Iî£êÕäžú¢yxÛ.Éôß{¨“f>AÔ¹Ì Üçè©W3ôOŸŸUnØ@5åur<È[5¸¦z’úïcêÎQÊ>G)’?øê÷ã$…¾ ð©ªZåD<ÈibíßÚÝU{ ãG~Vi¤¯;Y(Ùý
-yúšÏ›œ}­®É/G«kp'Ô1™Ê{ó-o[fܤ™O˜)áëCaÀé˜hû’¢ÆìrXô!6Ži1Røk²&"À¼wЉG¯™ˆ}¤±|Hlù‘¼ÊÿÎ,‚«
+xÚÅ\9³¹ Îõ+&´qI¼ª¦^0=U­#Ûʶ6²½Ør•7ñß7xßÝ3OZ9½Qw“@àÃAôð˯~ùôîöùݯ/™D —Ï¿¼tƒ_ÄÅ8&ÍÅhÎœ—Ï_.?]9—öå½àœÓWq{‘‚þÂ+熿hé¯}àïtíF‚¿÷ò^åšxÅ?¡}è)Íã5 /?þ1"˜SJ˜%Ò0¡l¥„så?P(R2Räׂ¼:ȺZ Q‡UÓÝBu¡ib„xõt–H;ÀÅ1§x˜I–/Ý‘ô% 0²`åÙâB,Î9“ZçÅÆM³¢J›çgôÛ¶æ™÷[wÿ”»ÆÿÉ×D ¶ÒïaÝ’`ÃS
+#ÍJ¼¼›–Ó£~ ì½€¹fÒpZÔ?#Ã"é9žÓÇÅñVŸ±a†$ƒ+ñH¡˜böÛfwuv0‡Â–ŠfÓjœ­Ó­ ”Y˜^a•[ü4cŽèG2œ\“éoØ“{"C§³œs]ÒÖ2-oQ%‰é•4, ‚äÓ••Úú¿þz\ÖÛ@XzXÊhâN›ùÔ(ì«ø×%ä)ßý:Ai•å¬àírV11R´´âIÈÉ,òõc¥™ƒq‘Æ‚"ëIí³Ý[SbÉ.êh*AL-ZlÌA*"@x ÷T‹÷lµF—6× 4³íWó×{="2Ç‘‚GÍAK¦9<B¿ÿôJøˆîkduVQ-*y ÐÆO£¤énÀÈ
+blœ"¯n'¯H˜@hÍO#ªìئ
+Oxmú’»9FJ4 Ë>´ÑÛ¹Ì&ה妬§f³‘Î^kr‘çôªŒB% Ê´Äç§t#\Yàþ¨KÚA9RôZ’?¥Ï$“lzA&ØqÜêtÉŠ”fyøÝ5×ƼÁº ¡[“nkƒÄ‡"Î!J1PCLNÏ;eá™ø|5šÇZ! 2+KV’S³¬Åe`¡ý&©FÅ@ÿ¤Hñp›Çñ»8
+ˆcžÈ8æÓ3ÀÚ<{Ôê6èôÁnt^yëÃ|+ä­çÔ)ñðZ%#!ƒk„žFJ÷öJæ9+v6²:.áC„„"ï?¦40[k>%m*6c×@xü_«¶é>VÎ7·žW¯añɼfÐA^w¢
+GW£wøTp/º›Ó*n)JŸ¶Uµ×Cœä³ÇΦŸ SPª1]}ÏãíV¶~W)’Ï&í=S)øµ›sºkAI×ðù»áUòñèxßK ªqöÁÓ`Îç ^'Uþ|~ªÉãœÕ˜(Å•RŒœd/š" šd =eJÁ[~Ѳµþe¼È[Ësùi)¨uåG3^¥ k,Ç–PlÖä+9ìÌŠ›B5ÚRøèk_劚T4Ï0—j˜9Î:ov0ÖXí
+ÑÇëù¡x˜´¯}µ;æcF"ÄŒu™Ix>bC LÒ9ËÚO(q²g+µ«q{ã˜E±šå¤¹„ nwmÕ­·q¯7öÑ‚/~ÑŠ2+Š#W´’{SEˆÓtb$ñëË‚ÔËLo/$ÛEÊF ù”˜ Qà“æ¦ Å+rXè° ¾.'lj \FÊï |¼fêsjùÊW\fë¹÷ H©ˆòá¼`ˆd"é’¯Ïz,C2¢†ô?üûÇžÛ0EÑ3ë=ÏÞyý¾UtöBÎ(‚í÷ηkè¹6‹I«tP“ŠÀ”^뙺pjiáÀëY¢$±~LVÉèE•åˆ°
+ƒдe#œ}Âý= ù‰Ö'cò8úæødwH©+ozWy‹T«©øqx¶!”$þý|^ÙsRdÀÉZ%ï2±©i(ïfgYfè•Z¶ÕëÀ“îâÑ4(E™iª^®õx’¯€CN'gá¹6LÈÆkÜ7$^ÃÑ &ï¹Æ·®Ãç;¥ÖasL)öÑÞ8¨ ]g‚NLq2‰f[O¬(E `«çi‚½ €@ùÒ
+7}$l ¯ÆZO
+dêÿ„+™3v¤` uBæÀœ‡{«·ÚñépÏ¿Ó(iQd] ÷DØóñž¦
+ÿÃÆß[¼Àùë’“Ó„ÍÀÐæHYŠÿKÿ¡HFâUÎ}V.×W•\÷UˆWLãûŠšŒ0\Y¿#‰‹æz—+—JÐíEÌsÅydÓe_߯ġ¶×t„$t<”7·LªÅÉÄ™¸}X"MÛÌТºé5`—ƒ7-èíDŽ+=u´fÁûpnqœÙ#†³¤;£„;ÏÆ$¯ÅÞ#þ<n!ÎTœedkž(idÎÇ'ýlÝ bü%(‰öX ÉHÓ<»N©(/Žñ[)ýz‡Î3?/ë<2!t’“[É)b—ÓŒ7ØçÆÃì—Ò¿çnÂòEƒÇº%(>ÄaÐœÍ÷µ‚68} Ó\{ìÿ÷éÄ‘H¤bZŠ'åñð)Ñt,_™A;,€M½ 7/eß¼ª˜Ø&ÁŽEÖþõÒ¾‚òœ¤Ìc’B+Ñ­ßO“Pj|%ª
+,°ˆÞÃOkAúpUÊ‚…øQЈoo-@cÎö¬¦üߎ¸IáµY
+ÐÐ儬(«åÇ_þqiõ±
endstream
endobj
445 0 obj
<< /Type /Page /Contents 446 0 R /Resources 444 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 345 0 R /Annots 450 0 R >>
endobj
450 0 obj
-[ 434 0 R 443 0 R ]
+[ 442 0 R 443 0 R ]
endobj
-434 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 404.583 741.031 415.01 754.547 ]/A << /S /GoTo /D (Hfootnote.18) >> >>
+442 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 404.583 622.368 415.01 635.884 ]/A << /S /GoTo /D (Hfootnote.18) >> >>
endobj
443 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 404.84 493.191 415.267 505.701 ]/A << /S /GoTo /D (Hfootnote.19) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 404.84 372.316 415.267 384.826 ]/A << /S /GoTo /D (Hfootnote.19) >> >>
endobj
447 0 obj
<< /D [ 445 0 R /XYZ 78.37 808.885 null ] >>
endobj
+61 0 obj
+<< /D [ 445 0 R /XYZ 79.37 771.024 null ] >>
+endobj
+65 0 obj
+<< /D [ 445 0 R /XYZ 79.37 750.933 null ] >>
+endobj
+69 0 obj
+<< /D [ 445 0 R /XYZ 79.37 728.314 null ] >>
+endobj
73 0 obj
-<< /D [ 445 0 R /XYZ 79.37 480.391 null ] >>
+<< /D [ 445 0 R /XYZ 79.37 359.357 null ] >>
endobj
448 0 obj
-<< /D [ 445 0 R /XYZ 93.716 108.887 null ] >>
+<< /D [ 445 0 R /XYZ 93.716 124.629 null ] >>
endobj
449 0 obj
-<< /D [ 445 0 R /XYZ 93.716 99.26 null ] >>
+<< /D [ 445 0 R /XYZ 93.716 115.001 null ] >>
endobj
444 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F22 357 0 R /F74 329 0 R /F16 328 0 R /F65 327 0 R /F30 333 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R /F59 338 0 R /F72 341 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F22 357 0 R /F15 326 0 R /F74 329 0 R /F16 328 0 R /F65 327 0 R /F30 333 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R /F59 338 0 R /F72 341 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
453 0 obj
-<< /Filter /FlateDecode /Length 3273 >>
+<< /Filter /FlateDecode /Length 3729 >>
stream
-xÚÅÉn#¹õî¯Pn Í&wÀ00²Úä–Fß‚œ‚LNsHþÿÇåq¯R•-wfà–Ä"ß¾‘Å™¾üûÂñßßž®?ž¾¾YuñÌ0êòã÷'qáø¿¸XϤ½X#7âòãËߟ9Ź–œ+àÜxü.ðû ?9þ©4žÑ¸Áï`8·Æá-Í‘ø)¬
-4Ú^„bJ™Ëÿuùýéoø¡ œÁþáƒ0@?¾“˜õJÌBÓ
-7òL(Yäœy) W'¸ù+BÝÒ¡%SV0£\“|Ì·Ä3iÓw’‡‰º•öÍ”d†Ø²ÖYÈix=Á]<âwÁÄÑ‘»pø¸îÚ]VàŽÂ¹‚ð­þÁ¯Õ\lVû :‘EðòEƒ~ŠDß6åÑÄHúŸ5¦ÔÂ!¦µ!ÑðlÂKs^ïÔ=àT=¬ æ]ç&#Ëb©¾‡x¤´a•sਸâë›–˼åh-g:T¡Ȫ
->¯’|Wͪ?ÿå—¼ÖKÓÆ÷KþôK1‹¥Jlꃱ ¼±®Ò¤å~]NärÑ ÎP©½ñ.ºCNe'BfrÉÀVåÎ~2*Þ·‘¤¬2üw?#×¾7^€£I=î+Õ†Ï@fx3ÎQéŒ'6½‚ÿLGœ¹i¼` Pe)²tÔmÊÄbÀpr„Ò;êo%ýöäx²ù¬q‰&ªÜ½ø^ 9éWxñØÉ ¢ÿD1CþclK"Ã{"ðœq>@  uL Èw ï@}mMA;ÜkÜÊnDO#ÙDø£[YÉ0<º—uhuÓì,ë;;9…QƵæ×õNÎ3¥a¦ëžÆ£|Åij˜á©—ý@0$ºzÃÕ¤Ù3OB¦þ¶¤N*Á¬6Óê&Ó‰J-HÇMÉÍ–Hj‹¦2iŒzkƒu ì%Ïÿ¶NFúDã¡È`öé>‰¼f’£ÉaxU¢z—4Ce!áú
-^ü„þHÇÐ_ÿ„ÄGI¦yµkHÞ)ˆ|èÝ(+aéTž‡š„5Òã°VöóC¿Ï½À0`õi¡ßç^`ègŸ ýz ûaØí¡aàï©ÀЯ½Fž½'5£ToÀú©ÙÜ“yGz†gµÿYAKx¦½xoÐVŸZÃú­óÿo
-žkFÿ1¥!54z|¶<~*½û¹·Y©rc\fÚÈ÷otgÛÆ9dÄNƒ©bÚ̶RÊ^ÒÎu¢#˜+P”Ùí0)‰¸ÙyÕº…¼¹·2L51üXKY£?2Nm)gÅlWÝk)[z‰ÝŠÜQ¾—Za
-0bø m%´i§'N¬C9hƒ’žf?$”ƒ1ÖŒ å`г[s”
-‹IŸ¤ÓŸuž¶X'xõÅÚIf¡(7y‘(ðì‹ÉìEæ{}ÌaŸU;¿h-BÈF­…Ï’µ”ÌèêO‰]p×—/èVxkslÜžƒÕS—/Ò¶a4ý
-YOWõœ$èýÙöF†’M\èí£pÎl*»]ùRËçæ,8Ÿe7Gm{q¡Pß@ à·Ú‰CÑÿçƒni²ƒ¼O -õnجdX0?&ÚBH¡3ü”íГ*Õ$²®1åÙm¦4píöö¹úªðÛ=g!jh…×E!jÕ 1èæN\Uj±¤3ý˜Ä'®¦ÑâÍtôª—/qûƒéƒìø<h—1‘%‰rCRn2™žùƤ1˽ÐRaÆ»%†¸„¼Ïìé„°èÐfì »e+8J|ÓèÈz¥T4ŸÂKæaáe`×ô„ ª[ `aN„” ²ŒPY€P# ËëÕ’û­çøHAÚ§…¯ò®Úu2õ¡ Ó…îO–cÃ׺_Õ*º÷ƒŠƒSm£ù4‹eö¯©â‹Ñ,"J#£Çë瑼Òhˆ}¦Õ¦IR¨&—žö(nipš 2AJ¸š%®ÅÈcÉ“vÃu_2Rõ²B&-«àéó ž²RWñO«[! ,x
-æI9&6'ß«B×#,…4rÿ\’Žî:1N
-'5˜y«2QM‡zP ᙾ ˽ª·JV‚ïF¶†‰¼æn„9r#Þ/\öv²õšœH2ôlô”ÒÝKã°æTeÙ0¾¾l§±Òc:ÏÝœ…§O¬Ž(í¯N³bTïI-£· U»â÷ ]ñK£]÷ÓlÌÌ™lNäš<[9õ‘<Kg5Áÿ¬D;¸#,eGj 9ñï\z“r'2»pçtVS[Ô´°³·T”Ž%ih±{,I¥Æë¥Ï›K¸ûg:pR˜PÙ$…8¢ZÕö«ëµ»Ì
-¹› ‚ݦ+v8t*ÏÐÎÒœ¢Ó#VŒØz(P¼ƒF…è¸IûJŽâT£åJ&'Ñ—DÌé&ìÖ.Hk?¡ÕXÏÇЬ›Ë 3¬<oHêêØÃŽ¿š":”p›úÙ…Cu²¹ÀÛÜ–L<nËk`îL¦ÜÃ.•&-_Ýìå :o¿R"@ ˆ½ú#B¢mãM¾J›81„â
-¼'¯7ä]¯•eRH‰6¤¶‡‹BÇÐ/Ž;
-ei
-÷±²ÌlÖ½«®ôк,¢m¨[ôÓôÁ¹;É„ÓËPÐô^L)°ðËSD´rH«Ê«i×ZÞ‘vŦ¸X¥ RÝÑ¿#ÿk˜Ä#</·lÑCëÏçÅ`-‚“#/{¡7á’×ð³#½]—kT<v<\„{äXô×úçd]€Œ Çœ'èo´j¿6ñ
-ùšê kÒ~P{Ö`1lÔ÷òÞYOC¸4Â:ý~è~îáY5n²hµfº´DÑ–Ö†²¥¡`wkJ‚jû§ö`ÇÓ†öðˆN?ûðJ‘‹nš„•ÍÙÈ[‰¥ )Ò¶"šD, œ}@•¾­˜ŸN'20õý@åY]}¨]EóWGtåÜ„8
-ð¼neïV<-ïÊ%…k=*ÍE­WŽPêYPÿÊm«ÊÓù1Ô󶑗²àGŠì-œ6ÙÆÚï5H$kŒkË®IË"<·¸ÌâÔÅ¡˜pÜ4e.0ý¬ºý–îI±Ç¹r‘,Ýz¢Kg¢¿ÒrÉòv]÷>*t|œ)á¼üâbºgë‘E€inÝË,åèÄ1¸‡ŒßÀj.Î¥×pÂ}Ö¸ž.ã­ïAE~± ]T±¾ñ<¡n !3±.rÌèÚÙ»2ëÙÊ2ãËñ„åôþûz¶4ÌJ½¸yU./×6Ä“ÿ–×æ:X~ç]Ã’Ý]‘Ó}ºfÖšZíÑ©²C˜)è‚P̉Ú}ºÍ¶Vr? ‡+×Ü áêùÚù¯
-h'XM°,åÏX–¼ ·`6Zˆg¸þ¢0UiÞ–…¢3˜¼üÃ2Of
+xÚÅËŽ#¹íÞ_áܲ@F+Qo a`=ž^ · æäd÷´‡äÿ¡Ô»ÊUÝžÙz\®’(’â[,óËï~ùõåöíåç7¡/žyF]¾ýö"𿈋L+}±F0nÄåÛ—¾rþÙ^?iÎñÊ8ÎåþÁõ“´ï(s÷îpnÍõ_ßþþ™+áÿ¿¾|ùöòß](É´½Xm™uòòï?^Â}o˜þ"8S .ÿûÏå·—àƒW«V¸
+¥˜6fD6 ¢îœ¢©8çZà=›®A" ùž2ulx¦4•¿#y-.Ò¡f6Á-A+„¿
+¼È·:Ÿ®z&”Òì0B½ŽœÄ‘.r³ìW ,ŠòLpCÜëDKÊ×
+#|ŒÃg #ÒGX~Õæ•îâ¨û8?0>çÝÜ#/™0rÄTÂ'íàÀ× Kȶ.àí2ð9Ø47ò8l]¾|#Aö\Ú¯p-ßveN¢´» s=–oI¹}õ/_û|¬¾‚y ]3Ï‹þ
+.˜´A¥9§¿À¼ò²¤DaãiÓãõ„8Ý£1Au«†$6gÅØWaÃ@o¬}XIÁ«A·òG
+Ϡm)pzJ
+œ¾I qÙú¾2af›i ¥‘·%¢Î'ÎÆ‘÷(NŸ”½¨,•WXÈÀ̹¥ª˜ñãâÚg“»[.P9ŒŸgëÁJÙŠá-ýE´“}ÜC´cBŒK@¬`ι-¾FyW}öÑh˜ã•U×ò>Fr ZG¢œ¤'@ìwkeô´Ù27Æ[&÷­Rü´µAƒçWŒkc=s`Þcn4s(¹²Ï³65Ø(Eˆ{%N÷p÷ ?š(îÝïÖ*ñŸ,•Rb°TùÎ#K•†mYªô”,UZ²µTöµ¸¹Ñž§™Tº¥oÏŠÉkËŠAE6”ñ­š§ç-¿¢Á´9yr‰‡ ìëj»¯eäbË ªn„ÆE­ÈO,Ð
+Û$صNm©€hdÐqÌÞÔ'FÌš{h+›µƒ1V2Ì
+:‹=³Uúë„R§þÌ`¤ax§Ç^òN¼‰™$ÙQªßQá•éA ’ÿpö-®Í1šéL6šO ÖŒôL »{‹“#‰V#ꉅfÏo½·Ìª= 7
+qË`™Jh¤{òº“j–„&íV£¬²Üù9BÈ’¤¤§e×9ÓÑYit5[Œ~\{ßF
+É"á 𚸿îÚ]V8É,Ôl÷^ÿà—ª.–Ïᱪ[¤«Mù.yõô->kT©…Së#émµ¡­ÉÆ|­Îëõ‚¸'¯ŸæÉ·vlvz£á)Þ\¦Q8ÊNBË‹eÞrt»-gÑ0y‡¢€ ‡µU|ž%ùî~4³þú·ŸòXO å9ßOùËOE-–"±)Ó"ïG¬ëîŽJÒrŸ\jär‘ NQŽ‰=Rä:fTö2b¦ÆTFTá5Š zÝ“”Å@†—ñ3²qýèkc8
+ÔãºRmØ d†7ãèà•NYb%1}sßÓ;•e®RUbÄŽºíÊ‚bÒÉHo3ª¹-I‡'»CAá:¹—– åFàÐä~[å`NúV§ÌµŒ[ù=·€¸'Ce° ïÉ>â?:lŒY<Ô±M@¶”`7àH ËV´ÃµÆ¥ì†ë4LcÁ]
+CqkÄѵ¬C•›Fç½~°’ü `œk~Y¯ä<Sfºžaf<xÃ;uÝ·ÿ%•¨p5‰C6‹ÁL©¿,©“
+½„6Óì&̉B-HÆM Ì–ÞGj‹ª2IŒzk=uõê%Èÿ²ŽDú(ã~Hx&„û¸ÂhP"9$ó•ªì1Õ­dõ”(kvXfËë ­òHÛ€ÓÓM€Wð̖Z’@wƒÛ
+äMíµ}å©DÚ˜=«ü÷
+´qÉì@ 4ý=oîDdç뜞ºâ /7ß6 5v9)€cºöÊhtwÞœ7U
+R»¢øj+Öþt#=&c±âÝ6u›JT"Æ•Ê3T±ó¯ÔHTZ1 Ó¾Ôø
+bãFÁ+Á‰S”LNÛ^"0§Ûž¾2s×ñ´µ>Y7'xw ­ò¸Áû×Ù±€¿5t¾ÓuÂã4°MÐvÇo-{ê5 ¶Û=M_ur‡Ä­¶?S@ˆ½ú#B¢mMn5náƒ+𞼯¶ä=å–ªxÚÃÙ «Z Ó«;
+ú74•¦JJˆæJ®Çƒ‘:®ZŠp×,üI{(XJC›Út9/ýîE†JÊ’¢‰/ |祡y÷ 8»/09ÏìÄîyŸêNÎ|¬ýL9À(Á89®Bª&)g__)‡6¾õ®-ùV±/G#°ßVê4sÁà÷Ø>Ã=)Á”›¸}0èÀñÒÓ^}СÁ@›ý½9»/´vñŠ'Cý(”Š7âɦ»Ž'wóA·Èχ”B f¬sCðnÃ÷‚÷Ýkð¾O1šçm%Á B×èÝ«(Çt‡›!ÝIóF똡m$Aéé€á£T¿G»‚Yqi<9ýÕl¿H×Ç|2³Y÷–ºÐCë_¦kJ/ýl4|PÄaß%ZWËÄO¸ñGBDáHá—3¦ªˆh÷!Í*ï¡ÝjRGÒkáb3THuEÿŽÀ?æ„‘xrHŒ2¨Àé¬Epräe¿é·äÕýììÞ®É5*Å+N B߸ð#ý5ñ9™ ãÂç ú©ÚÏ Dl> ÇŸo¸×l±þúA®×“ž…6€eÖÌ¿Kr2…Ëìôë ~Ù˜UÓ*‹k&cê#«µ%!woc•òó¦©* ?>Aç í±}ö–œµ™Ð È­R¥ñ×f(¶é¸$½
+Ô®•¢ñ«³¹r`B x]—°Æ×+ž ‡–u¥AáV‚JQd÷cª;êß°meyþyù:~빦6Þ®¶óÛÕó¦âÿ^¹Ö< ïgx½@
+º }hÈl•s(šhÚþy›È
endstream
endobj
452 0 obj
@@ -1148,135 +1125,148 @@ endobj
<< /D [ 452 0 R /XYZ 78.37 808.885 null ] >>
endobj
77 0 obj
-<< /D [ 452 0 R /XYZ 79.37 543.021 null ] >>
+<< /D [ 452 0 R /XYZ 79.37 399.559 null ] >>
endobj
81 0 obj
-<< /D [ 452 0 R /XYZ 79.37 403.621 null ] >>
+<< /D [ 452 0 R /XYZ 79.37 260.159 null ] >>
endobj
85 0 obj
-<< /D [ 452 0 R /XYZ 79.37 323.559 null ] >>
+<< /D [ 452 0 R /XYZ 79.37 180.097 null ] >>
endobj
451 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F74 329 0 R /F75 330 0 R /F77 331 0 R /F53 337 0 R /F30 333 0 R /F32 319 0 R /F64 325 0 R /F15 326 0 R /F81 366 0 R /F22 357 0 R /F84 404 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F75 330 0 R /F77 331 0 R /F53 337 0 R /F30 333 0 R /F32 319 0 R /F64 325 0 R /F81 358 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-458 0 obj
-<< /Filter /FlateDecode /Length 2819 >>
+457 0 obj
+<< /Filter /FlateDecode /Length 2663 >>
stream
-xÚÍ[Kã6¾÷¯ðh†,_€Ñ@<ŽdO;èÛbOÁf‹6ÿÿâS|I²Üî™ÀÓ¶D֛ŪO?ý÷ÄO¿¾\Þ_~º urÌiÐxzÿãEÐ ~'ã˜4'£ãZœÞÿ<ýë̹¶œË}àíUJAWð¹øBw8}×o`Ïþnü­Ë(%èªÉ¿´ë©€|{-S%‘Dú‹×ôIßå%÷ ý¸­“”ÐÉbÆ1|:KC¼Ô)|ƒ*ÿ~ÿŒepf,)9a{s!Ño2RßàbHznž·åD¿À%>s§ GBô|*{lI‰ ™ÒS)Ñ‘R^·¥t‚øÈž²o¯ˆ² #O§ 9tLp]Bnêò—pg.nrSc!€Ò=Í{5ÝÔRhdiqÃ$7¶þCW·‘^.¥%F©BÔB£Q+fÒ
-Šk[ Æy3)¬’`¶Ÿ4¤.“ vI™ö– ôyØôy8Ž
-J&÷ë¹ûIp²WËû!‹]QY "e™RØSo£ÃêÈ2zÙôl½D¯U ESÕÞcj}ÞOÖJ3% [ VÖÓ>^v·¦Í„ˆ’YÛ3¼7kkÉ4‡#âV{ß–X)~A1áT¦›ÝÍìÌ°¿
-8ÇÀ ²ÅrpBqcÉÓ¢Z]u6×iµùßþ¾Ê+'Ð÷©bäê?¸ú¶hò[¢“ÖØ–=Á(æÍÙªÛ¦+™Tƒ±–¬87’+¨u‰Ÿè˜¨B0ä¹ ¥ ¼L‘œ(¶¦Ád] š©´y-®,_bÄU»L5zƽ§‹!`<éðÜ’ÃVRV÷²½}#å"Ð+À]w eânØʸ¤pΔ/éÿ_W¹G553 fî½ÓæBúË“ š`ŽfxE,] ÿ¿Sóóè–tîø>!;Õ:/eƒfeÏMb.‚¢±cëÿ¦"5ß½ÐLúâÕ˜#šu‰l¦¤"ÓRI¼«/q³TÀæ»&RN ÑvªÔÚ1äeõ‹Ø¼R†>/—á
-Ö…Ý5É‹0¬ˆëvì+dÎÙžç'îR@»ùhൖ‹>XU}yõËTñihSzœ›³a·]
-ŸlB_-Õ{Hd–+¦åWN¶‘|1M¹Ó^C¨kí¢‚‰‰ç»Ñ˜÷4-PDWï—ò–©/e™Ò9ƒæ=ªdá&F㪕NñJU¿/µ¡>’÷›¤¼-Q ·+ŠézžÒµŒûLÒÒV:ËŠÝÞç]¹©U»½GÕÆÂPצK"­2Íá¼wIE°Ý5sŠT ~à7GI5|Ç'mr¯†CØ`lÝæýôfØêçÌ4Ú
-ÐLP0t3%½ˆžÀЃÆ+þ^˜î釵|myä5.¡&›K¯5²7JÇBn›RÌ?ùêv¾)ÛBKRR˲›sbÕ¢Z9ñæLR§ç:¦¹©…òºå.Õ0˜Gä5“ÆÛ7+óJ‘1òÒ8±t½x‹¿"ι^ï'ô<$s\ö”§½æŽiX¸‰]ŽMÍl(»MÊ0A3•«*ˆ½åC Ïué\R¯Äß–j=Ì)¨@Û4¿|h~ضùMe’ e’£‚æ—÷—ÿWùŸ.úžkêfÄé÷?_ü °´Hñ$8åqúë?§?^þY*¢
-{ ùQ™Ùo~ömë÷¾#M–Œv²žÿ$¶Ò~¹”û‡Š™iKD P†èuw¥‘ûéfWb™ºNºÔÍô9¯¶„þ%j«ŠjB
-dÖ¾hË>úô—¿| Þhi”ÒÔnšB5elÙ·EsÙœ
-
-ºk,€àË$+$Cš%˜LýIœŽ±hÑÒÆûM(„_0“sw-ý¿Sÿ7Øu~ëëÄZ-}‰aÑ$+yE=½üµžOI^“èÝ|ã澑:ì0Ýhøò§B··P.ÝRèe‹íÙÜXfp÷ØÃRaìöH‘êω¼–¶L‰&¥»»¬‘#¤¥4_C@ɺzlv>ω`M%ö¼Eo;wÛ[´Ås®ïÕÑðgêØò>¦c;WÁ†Žè m°wúñÑMqÕñêZ€ÝèLe"qØÖK‘¸5ºŸÝ<[á›Joò6$`ôðò³öŒ¶ ìhíy‰<äR‡ ©EéfÇ}î 1Ü}äwÄЮ5ºv%ä@(JàÃàµ}-Uîîõ7¬G¨¼ô¡5™c§•'­ÉÁ[ ·ŸIÿ”,˜c©¥¯VöajŽ”F>³·o¤P<jï°÷>ÕÞ­<{ö¥Ÿk©V=UüÙZ¶òìi9JofåùmÒzËêÕX¶È »áw<¿Fn(
+xÚÍËŽã¸ñÞ_áhY|>x<^ 9eз § ›C°‡ìÿ¶ø(‰,Q’e»gf[ëý`UQ-…=ý÷$ñßß^Î/_®Áœ‚ˆÎépúøýE$þ¯N>
+íOÞ)!:}üqúç›”æ*%)µ’Òü)Ä{g|–~Cº÷þjÁâj‹WéÊ Œ‹3ŒúZ®œ—-\¹*«Æ´Â"´¹¼ÿëãoœC+…’@µÀjOØ´/@,Ö&Løèák‡1'¯£PFO"wÈ 6åãcFPŸ8bïºK¹F†I¤8 A(T~%”€M .xSÊ ÔæÉã7€%(w!fÆ«¥à­Îš5É2ÃÕ.Z¡¥Ÿ8òEcNNâÃü«ì™Õs.ü“ž‘\ö„¾•¶"ØprÁmâÄåDE›‰B²XLŒ1x-tœ•²D°è@­f W”e•0~r¼ûËë:ƒQ¨t\& .]B¦xÆhþrUö1”Á™e(;„³ã¤0¾ŒZ«Dÿ\ƒ2qîÞ!¼µaH«’C¤x(W9 ;, ß_'P}&O© ¡åä5p]G©¯!6Ë9„rd ÙÒÍ¢$¥}¹z3R–Ö ¢
+\]we¾Bgl#
+¬°Ž¡¼UÎM•3‚cVWSÃð¯ì†ôÁ» {7ŸnÕø) k¿ÒÓÆA 3A˜… \΄.¡FªvŠˆ°)xLlÀðLÁ›%ëb&3™ðn鳬J™ö…z‡ð‚âµfŽYo…òRd»Æ*â`ò«Ìx(™˜J‚ô6!®j£A½ÏTÊWíü ;cÊ‚»Ð2”×%5YÓä?Ò_ÚI½›€ 2v®IöJx
+ö<—U0ÕB_®nl}UBÔ\¬dÄvƒeŇ,F½5 $ÅxW¶ÆÊcâÍ¢¥H|i|¨¨ªµv^ÓÊëÝ~ž¶NX½°×`£=W*À]i3-BàoMØN ‡eêv›mo‹­ê¿„×s5Û9{—Zì¬
+Rºr¶ÁdÅ)E«&¸ÚDîj°Q%o)p2þ”)–T“ßgK_gásv;·¦:Á[‘´ÙIm¶kDËU5§Ä±ŠSY¨sù«²€`gLYt]ݸbìcª
+ܤNÂÒ'µ²¸Ñûä ±Ù`òª¥Ía¹í0§ñRxoÚìpÛ¦SkmRê/ÝuY”ÍÛ¤~ÅqZ`ví¥¬Ï[!çrNá²ie×èWIMÀrß·Ô“ú\ˆß²j¡óæ¢yp•¦·H2fôÿ;u—ïxIêžî²S+ó\48á±eeÔæ¦h»T°é»ïÌár@2êVïHÆÙHí”X ïJª[’@Oíø'âÜ,ªÒ¼b†~›-®óÓ–uZCq˜câ²íýÖˆ§ù‰»à.…6ZP„VÊYÓT}ÿºV|löRa)!f~›ÕSáC*LÕR»‰bT1ÍW”o úI5Ó“þž¶ÒžDð%—šñv4H}
+ 3_RòÔWÂ>—eÖQmGx
+,ʵÅ=™Ê¦|ŸkÃÄ|AŸvI}½@oW> -î_‘‹ð”^B2e’·uÄ«aÛ_2嬤^ìþØÞåp«ºiµB”Ü;[ï\‹à°«æê'RçiÏgÒö¨±†gtê&÷ê%°Y)­Û¸—Þt…­¼‚‘D{N©D™È!%7³N `у–;éYOøs,_zãZ´T}­¡FFã²–ÛÆTòÝÝÎ7Ó¶ÐûR¦È¾HåœRbõ-J¼”IÚôÜfÃ
+[[¨$u©i…7´‚b¦®ïAS¤èâyuš»^s^–;E:z\Œ\î'ô<´ˆRsÌÃÎÞ8/”›©-mN¨ÈÍl®¼}Í0Y²tWÚƉ“æs /ÝÔºÔfI¾Ï{†™¦ym×üÊEó›×ôÍo-“b.“"4ß>^þß伉;|j)¶’ÿþã%=H§ Æœ”Ä|¢NþçôûË?¦Š(ô¬m'
+i0--úÛÂXæ0,5’¶}D åVZ+Ð ê¦ê5iÒÍ#‡>µMÝ·^HÛÙkÜnÑS´:­[Ùr›”ý`ê› “rNx#¬¶í‹Ç,üc…ÝÑüSf§ë6í}Gš tPÜÉ8ýo-Î\3Ö0H‚ɧFîË5¬ø2¶x‹AÒ1"iÂ}+PU±SMh,¨B\Ú¢o\p­0øq§?Ó ºøž-¼ÑÒÄ®çcÚæ´o‹Æ¼E›ÏxWEÈ‹Cõç÷YÍh&8læÚ11A‚ 4‡Ü8­¢JFÎÎäÛO¥tT‰“=ns»
+•J1
+áÀ\D¡Ù
+l> ýUfDŒŸ=}/¹K©´
endstream
endobj
-457 0 obj
-<< /Type /Page /Contents 458 0 R /Resources 456 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 460 0 R >>
+456 0 obj
+<< /Type /Page /Contents 457 0 R /Resources 455 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 459 0 R >>
endobj
-459 0 obj
-<< /D [ 457 0 R /XYZ 78.37 808.885 null ] >>
+458 0 obj
+<< /D [ 456 0 R /XYZ 78.37 808.885 null ] >>
endobj
-456 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F81 366 0 R /F65 327 0 R /F85 428 0 R /F75 330 0 R /F77 331 0 R >> /ProcSet [ /PDF /Text ] >>
+455 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F84 404 0 R /F15 326 0 R /F74 329 0 R /F81 358 0 R /F65 327 0 R /F85 427 0 R /F75 330 0 R /F77 331 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
465 0 obj
-<< /Filter /FlateDecode /Length 2804 >>
+<< /Filter /FlateDecode /Length 3107 >>
stream
-xÚÅËŽ7ò>_Ñ?`š,¾a
-¨“K
-3öD{È,óÔ^¸Ít4Þó’ó­_zéÐüQ^D%qBæd:=íÌ5ͦ™ÚWh³ñ¦ÑÉxEkã%½'¹L:FWįIÅ™°;ÔܱšF]Ê ¸ÌÚ,"KCÏLÂ*³Ý™Y#FàãÀHT»¹…±À¬|DÉÙ0»U²HÖšÙGò'ÛÍT7Hò§"¤ Óf{a‹Õ—Žñ4#é À©p1Î#ô„l‹ â,Ì[7À3ÏïêÒÓ øÊð`Š ]5·“L†õRg‡ÑÈé·.¢@³zg´;eçL«Ôi‚ƒCÊA—JÞoÎ{abµË½% Û‘ù è)}‰›È#IÍ’å1+y<ÓÌ8É(ÃN"/fÑܳÇG®ÇÆ£Û¨Îð½»!(ᢚyýFaóˆÞÎØÙ„s(dIÖH’ô¡'ÈYᕃbþ«Ñ^†Mªp¿å-­ÂYtõêâ׬²EŸF³,ÜRÊ"\°3üÄí ù«UÞ öPú°û÷[þñÓ'‚ã6‡Jиh€…µáD¡l‹ÍÈ™¥ÉUÃ%1Ï:åoDÄ$$
-œ'Zàƒ}S«ÌàÞÐÝ'×…ü«IF6§%e0¦#½š„¸y³hðGfòö¼ÊÂ~¼‘ŽŒ‡Sc±Š äVãïUBžyO²ÊY ¼®âšD˜GY4eŽ/˜Âs€’y¼¦§}^qœ²d¦…x›Óm£`ÄÐÇŒ2½ÚÚ<Ž³%úSÿ8 WßD#Ü^Y¯u|OXÛ{í
-uÑU¹štYÀ%©‹©¶×%)/›\$‡Üýì>¥±Ž^Au ¿„À}êëâÂÄîÊìe=u•Ã4¢w«R²·0z ”(Êi­³kL·ZÆí0¹Šéý%¨ãÝŒEÇ *Ö4û¡XÈy·Wºªke„Ñq ]($ײ²¤è¢3küdÒyäþSW¤@À¶Ä£XlpX‡ú8òÒ@™s3Žº˜+q¡¼(¨Ýsq®47m%©îS2Ø)¤­PY‘éæ EœgÎÜiÜPÉ+ÕÇçVœ$YÉZcïw6¿‚ÓÕŽ}+掂‘µpÊ´úS}¢.®ˆÂÂNÞ–ÿÐbxsÂ\_:ɺ—­ §A™+7†ÖX/AHò“1yõØsmÖmr*èdtsxÍ#söo€oåô ŸÃ÷ü¯<'(zt¸_—á—ÇÊáÍ{‰4R`å,EL“ÿ܆?¸ÅVe1>žœSŒ%Û+!ˆªFðù᪪3º–P’ÍÒ|_µ†ñÿO3Ú©mϹ¨.'q\ìOàW. :M–“e=µ‚"ù­-L¸Ý
-È%}û# Я·G…ƒöׇãBÏõ`|K%…_ë„¿Æí«Í¥rÛC6÷›ŠRTMÀLY‘=L–~ûó§…î
-j¾YÛ‹VÂ!AÚÞZ*šþmów¢fý¨§Ì‚°ÑM”å\·¤
-7—ˆ}) •Y/Ëô³Ç„¶aÒ¯=ð¯õ"‡¹kï0‹Âïx”ý”€<ãZä»,Š¥¾§Þ¬ZBZƒðñŸqŠôXiÜÇ Kg
-aL‡Åm¶v³§º ÈPÂ+ìýø°§jn
-¾«!i¢á!**B@iÈ€P(§½,¨´¡ooÞâ©FZZex—[¤fNXÐØÑvHAŒÂ¹8kº³°ƒí¯ôéÝ– `ÑÕâÀ
- ¦ÚBÎÝkð8÷]nçU˪Où
-îÃ…(3lœf¨T„r‰i GReßØTZ¼ûõ†6@ï~üü ÿ?ßS!…Qó¿iâ´.“z3rûkû×Óù¯6‹›:Ooztï€àæ` »Ö¯.„¾¿X½y\G¯–ô}'¹ÛmˆÈ»*,¯žCää`MW|ó»#üDÊKvŸ}ú'5çól¾·IwÚSÙàú‹ºL}\QOûL»ð‘üÃ,³
+xÚÅ[K·¾ï¯è? Š,¾ÅÆ€s²£›á“ûè_ò÷S|ßÝÓ»;VŒf§»Y¬çWÅ"›ol|ûáéòõéãMèÍ3oÀ¨íëïOoðMlÖ3i7kãFl_¿m¿<s®~®/¤æøKZÎÅgÎá¹ñøïèçôKÞðø7ßáŽxNW¬B*áNøx¢()—®jAÏWJôœ2/`‰’ Ï¿üúõÇ'Î|
+ÿÿáéËקÿA
+€bÚ›Q/ ?ò’$SWüð${”ëšîÉÄëžÎÁf„©¸K*¹aŠQV员y½¬’[&Ì䈛7É(µc&ƒ“Õ£óÁȇ’§DŸÈW-÷\ŸHTh\Ò•p§õÔb~"ø­NïF_ƒôÛåß&øòÙ
+ÈCmˆT°à¦•¤x¬”™ßÈÛ¥»ê³œ—4«v+Úm «îÍ‹ c׆ÎLS4‡V)’¢´Wâ?é4ü²…B²bÒQ+–ˆ¿v-Qž-²Fº)zs$_«”IϤO“9vŸIE³Â¥¢F¼V(™OkÞ¥#L
+Ö¶@>îëx%Ëç²ßÄQ6Ïçò-GZ§«{\ÇÑWÒ}‘ã–}£Í„×Y.ÕV I o[ïŠžÊ“Æ £öóÔ
+"åhãœ÷ïÛ¹‘5^5MuÒq³p§—‚Óå9ª\‚¢R•Ð×&ÑI/˜VzÃ;!–DùŒªÓ1È:Ç<«6Âö¨ @„Ä(Ä–RùThêš\IÄ"x|"!Ó)tf
+0OPœË>êÌÂkÓÑC.êË;_ŒÓÛñÉèY—ò´ë½<ü-k ÷AI“WJÑcE»ŠQ…“¥BygKÁâ-ú%wX‡CYƒMž€b{’#PÏ9 º®D3sÒÇh¼”÷ÀûAG‰6UÑ5 J_ç ±GÎ#ëU™è[sˆƒà3^Œ²~'”N"þéqö±>LšV š¤*%˲*¦_E[V­ÂyÏ[y®BðâG^YÑ'ãhÒ…YêBhKc=Ò×jÔü¡F…5¸©´¸ûç[úãçP=³…$$qPGêZ!ÏË”Ìú¡þXs’Ë"†Nv£’ìµ&Š
+ü=ØW‘Ù‚œ…î6˜ò“ ¯A«U…ø(KÛDÙ -–EíKÀ…›¼?±’ò±¾Ú+_YhÖöumžÄRö¬Ò“g’Uš‘Œ@ãÊ\ƒ
+ÓURM~&wÀŒ{q@kVîŠaí¼Z¡ëâÕ -fä+C7ž#œÍ‰–º:à0ð•WÌÌÆzmà<)ŧx7Y™ÊIÓ,G
+œúùú½Ž¿CëâC¡ügS%S”Žc‹ê–Õ²šy¬O‡Q¨™Ä_µç`ÛOe–A*éë¤?»^%zÒoGãÌÎ1ß3H–ÖY&>÷ÕîRÄíi«óÎ"D((`æ.
+ò*3þÙÎfÃq“T;‘c% ÛyÃÓëhÁ¬k÷y”;e|¦ZÃó)ï"ÝO¼«ÕQXà+­þšéi÷…Ç9aH;=¥µ±´`ÊûsÖÊÀóg§ êçßsti˜çjÅmªÎ8<™¸§1tëÓ–9˜ž†Õ¹ži¥^áñûíŸb»žf.áiäâ!VÊzïiïYIR¯ôêðÎC¼=B²nj½x*:â[qÙp·Ëækƒþhhšd;;[˜Àfþʅ4:¥iì8 c bƧS¡ü3€2¸"•+œÌå€Á\Þ1Áû\,0ç'×Uëp똀¥ë&ÈËn¼ °L;ÿØðïiªý^s ÿ‘‹G†Oû^øÏúxløܼ1üg._þƒ}·ÿ<íëÿ§q/üû§þ³
+^þ‡&xPøÎrÝu_@Çzé¾ëðÇE…‘êûÔ»Ã\(xÜwý‡{€•[£zÅy´¾G<nE!:Ðß~®ÐOüJµGó(Ÿ¤ˆ<Ç™ àÝLáø……ö¶/)vF 8)<
+Þœ …¼I+â>mݶçú„Îb™wœ£tÀ<.‰G>¾Ó9Jœ]¢ÆÆÙãq7:{tÓöôe—*æ1¨J
+»åyQT<p)h0¶ùn…”_º)
+=Þ+ÌãÏìæ™tóú0ë¹g¸ €¡ ´TiûÕÖƒ‘Íù¾ý]Ò¬Ôt„42ºLÞ1PJ-6nó¹žñ¸:kÓîaæK·J|ÞÇlÒöóѱ
+°˜õ¼ðÊc¶ÞôLåý[pB¦ù_³çÒøø–V6IéDûÝ-5LN†ºR±fkÐ4ïB@{F¿Eèºò;®ímöÇ*wé|
+¶;û•‚;fœ~ç(¥¤îµ¶4Ó˜ã;m¿üŠ—ÿŸC¶ÅÐúo|ð‡bF„aÿÞþþôS~·Ml+6¥ªï#5/ԆѤ…[œ*üxÓr³8Ž#½vïB2+ÂÛ„ÌÖ˜±âÅyB­žû7uÚÓôém¤¢Ú;˜»ç*m:üFÇÜbÚӞĽ_q#—j=û»P´V€C­Dà€ãåAÃ$ 4Üyödvzz8K‡Ëå4owä<^!K•Cd|~÷M5uL9žÄ“š7øö1˜ÁEñ¸-˸R¡×ÿ®)¡
endstream
endobj
464 0 obj
-<< /Type /Page /Contents 465 0 R /Resources 463 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 460 0 R /Annots 468 0 R >>
+<< /Type /Page /Contents 465 0 R /Resources 463 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 459 0 R /Annots 468 0 R >>
endobj
468 0 obj
-[ 455 0 R 461 0 R 462 0 R ]
+[ 460 0 R 461 0 R 462 0 R ]
endobj
-455 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 178.558 662.494 188.985 674.784 ]/A << /S /GoTo /D (Hfootnote.20) >> >>
+460 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 178.558 593.158 188.985 605.449 ]/A << /S /GoTo /D (Hfootnote.20) >> >>
endobj
461 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 246.892 610.249 261.617 622.205 ]/A << /S /GoTo /D (subsection.0.4.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 246.892 540.914 261.617 552.869 ]/A << /S /GoTo /D (subsection.0.4.2) >> >>
endobj
462 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 274.568 610.249 281.542 622.205 ]/A << /S /GoTo /D (subsection.0.4.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 274.568 540.914 281.542 552.869 ]/A << /S /GoTo /D (subsection.0.4.2) >> >>
endobj
466 0 obj
<< /D [ 464 0 R /XYZ 78.37 808.885 null ] >>
endobj
89 0 obj
-<< /D [ 464 0 R /XYZ 79.37 771.024 null ] >>
+<< /D [ 464 0 R /XYZ 79.37 687.041 null ] >>
endobj
467 0 obj
-<< /D [ 464 0 R /XYZ 93.716 84.229 null ] >>
+<< /D [ 464 0 R /XYZ 93.716 85.17 null ] >>
endobj
463 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F22 357 0 R /F15 326 0 R /F74 329 0 R /F65 327 0 R /F16 328 0 R /F81 366 0 R /F75 330 0 R /F77 331 0 R /F71 339 0 R /F53 337 0 R /F59 338 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F85 427 0 R /F64 325 0 R /F65 327 0 R /F16 328 0 R /F81 358 0 R /F75 330 0 R /F77 331 0 R /F71 339 0 R /F53 337 0 R /F59 338 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
476 0 obj
-<< /Filter /FlateDecode /Length 3410 >>
+<< /Filter /FlateDecode /Length 3489 >>
stream
-xÚÍ[ÉŽ$¹ ½×Wä”Z¢¨ HÐÕ55ÀÜl÷m0'öÅ}°/þ}S µGdTwð
-yûÇMÞ~}’7)þÙÛ¿ãþòç_Ÿ^¿>}zwæD°`ñöõïO*Ž¸©› B»›³JH«n_¿Ý~¿K©”VJi””øúòÇ×ßhñ¼ ­ƒ»uh¤€
-e hš[¦fƒÙ£6BU«YZžZ
-«ù4vœÁ‰ŒœÉÇ*-—m›B¯¡ºµBΈ±›xùv¶ˆ£Â(‰¹?…ää}ÚÓ1GâØ•ìuÍD
-IšØ˜ar3{gE$À®Þ?æ¬4%*Nêydô—i#L¦ßAÛI¿óÕ-J–¥lÏ/‚¦ÆÎ A=©é++Ü)ƒh4ÅbX–;.96Öý p‘R\·>pbE.“fS"ÿG(qæ:ƒ!,Áf£©§çîÜ#jZ V2ª_-‰ƒ=B³“÷íÝÌ[Q¦ÛrR oq¥]¥vZ’ÒgÊV¹.á&g’óâ1+Ö†â 3ÿ5[Ý×4hi¡å2+îè)cÖv™y0ûÝ( ùà—¾œ,Àqæj¤Ú®|…ü×@ÍƇ¤6õ®Ç”ÙöÆŸ¤6êÒ*x!ÁFO€ÚÖbr´€FõY lÀ{ä^‹ÛßhQrÜÊ–Áq} "£†³ÊÓ™q=ãê¢OŒÓè9#(Ä_Èò\6XÒîDÿ{¥£wš1z6ØÐ ÉùÑ9 Ce…!µœO"’ýÀ Æd(,gHêI ÒÍšÕ‰o(ª/0ò¥ ×£R&X):BãJõh¼ÎÇ»÷Rla¿¯ÞV´U±¶XB䜛'1n>aãï-à'h|ïÃŒßÎ`P”M¿wåµ4ïξ>º’>æ¡9XWjJÔè½9˦Í9DE®û´ðÙ¨0hA‡!ó²02åó´äæ°SÏÅÌ©Wå7ñã² ž>ÿŠd¸‘/:t±¦s”U *¡´¿’ãõŒØ Ù™Ùh9Ãk]—ó7S´ ‚öÞY)Ï!sžûB{Å9&Ž©¬ÆÊÂ}ðì½Q›¦&gNLû Œ‡YÈWœm‰zžilVaë£
-k›c4G9²Y`Ñ2ydŠ•±¾2S,cW…AByX|àÌ+}úHŽ±x¯æ•÷Ê]Ô@vXŸkMø \¢…œw‰¥Á _ŒeÈmõ!ANœU¨È¥ÐÌoÍÂÂ’„®Þ
-ÜôbÅyr ’´£»I¼-š5R¯”S;Ìz}Ah¼Ú2®óóù>`ë:+gñ t/´÷¦QǼÛÏ·XîÄïß«@Ê’ƒ]f]ê†G¯f.s#ß¿lwË å´P¨—X(çΆ–fÊŸ“f¤q5‚µq¥`f¸ºÛÝÀMÑ;Í;u<·žÓ[_lëoªr¡5-‰îpÃFš…|üXÉBKHÕY@SsË *.aGÒÑxz£È¡d˜wˆ­’Üj—-ÿiI¡¼ÜÍjBHØ$Ÿ¨l¢v†ë¸„Rêi¸Ýi¸û
-gÊ
-~}jôÍŒ k«Êc×öä©­¦»,»Ó¨ŠÒR÷3Ÿ§½.ç,QæEU*t“<i½Çê/ÝÎí7žKÒ¯a%ŽL£ë-›’|ÀÙ/ø—*ñÐä­ÎÁùï7Œ-V¿á÷B|»,èy¥Ä[ÿž× ßmáŒ{{&ìö)*_Xli“KiI1ÉçÔ¾g<¥?¾= æ•ëUá=5q4Râ=ÍêÕ>¥7ï­%^_C9 CÇHl>JR¬ZåÒn¾³îPÄ·€ºw«ìy¨R^ =ÂBس6xo9+”·dë› G}<–Â7JÚËW]óëµµÿ Mü:
+xÚÍ[K$· ¾ï¯è?°²D½Æ
+íoÞ)!º}ûãöÛ]Jí¥tRJ«¤4¯/Ÿ-Ø{ú$¥úŠ¿DñÞžBùÅš2>Ís‘~ùòû·_çÕLJ:Z ^ëL¤dm¡”¨:$åÒonGC{¡ìÀqâ-ÑJü'‰NznB¡­Ã=°BEËyÒPwWçYùÁïîË¥ÎVž®:K üÓñˆŒTBgÇTvÞðó;þ!!««˜êvóo>Ó’éäñÜ‘¢0øçnÿNèËŸIê`ÕÁ-¬×êÀW8R+) ÂLÉRU¹J‘§>×
+ ËÜIý8m&8aŒ9Yõ9i(­„ó ½•¿$§žø‡B§nóÿ¿?q¹¹€:³œ^5Á¦êÖM¡Û¿2ZU<î_…ÕP·Ò6ûiR·è±E%…·0¯áš ¥$Zôq˜kE z™ûz Jh€j]õ)!Ú(œÓ×=Õ¹jÔ¬½²sR㉓ƒ•´Q®+}`çÆ /ÃÞ§î×&·1ά»üNÝ!·2Ò6ò’îT½çöhp~fÓn> Imóú‡aå@šuÇãìk:C;žVnë|ÇÓŠeÇ?½£3TJDk•ßD„Ž~³ÔgÜ£Lgõ¥h¼¾h•†¼W›y«¡°:ftPŸµOø£X}Óu ÔPb þ’ L0ÕX]x‰¦ðºnFDP¥À©MQBa6¯£õ½¸Äâ^ ¤•\ù®³‘¸¢’ÆüFƒM œò©`$Ú)¡¾°å«g‚w’m É1‹C–‘ùWÙ|Xe^Û‰•Qg'–g$Ý®:MO–S«>ä-‰«ñCWÖít;8¤ñu
+=µŽœBç˜,è
+(ø|c«B·öº_è3ºöVßx™tŽÜtâ1»_TÓœÚàÈÛ±èe‡\·+®èq^Ýš\S'Lª¥iYõ^j¤î%Q?ßÍydŒmUÏ«îõÕD#‚„«¡ƒŽ«Ðw
+ƒdìT|9óòc”ŒræÒ°ÊL'»‹úÞ%ÚýE Bûàƒ.žö­ËLR’jR4+tŒ@*_bþrt pãVÖñÜIÂ,udXi…äµWÜ-‚€yŽœ< Ì*\çpSHŸ“‘ p½ÒÈ{*Ô˜9
+Yš¦+0§ÉÅìJ‘¶Zöþœ£Ò€x]Ꙋ!ÄWx£JáßC_I¿ï3©[’,IÙƒ\s7s4ò¬¦¯¤p§4V‹¨`!w.\tlÂ8ÿÂ5Á
+³.}àĪ\&ÍvN@p|8sëc\&>¨zDÔ`e£ùÕš,¸#;y_îfÞª2-x–RVy|{„†Ó(í°Ó’œ|Æ•
+~r&%“am1Ù8ï¿e¨ûb’Z.³rÕðáŠÓdí–¹iv¿¤€sžêÉg«˜ûÕ“À¡:>CËÀ‡D6õ®Ç4Ùñ@NÒ í
+~¶*ZÀ0d! +S$×ÃÖ1Íœzµý ~\ª!ÀÃó¯Ä†_ù¢Cë8GYErÿ2À•LØ\Ï„íÙ–¼Öô˜¿Ùª ´sO4f¥4w†Ìe~jíýå˜ftH•) 5PÀ“÷6Úv59sb:DaQ¸“¯81ÛÒèy¦uE…]H*¬]‰TÄåHj\eaª–É#SlãÕ˜j»Ê‹vQ(ð+‚”yåOÏ$á&UìÕLy¯ÜU $ÃúT_2J%Zx0ó*©XÀà‹u¡Sä¼³©üYöÛ²°¸d'‘Õ½;`,òé:È-¥‡ˆÃsÄâ}¬áðHÖ®w%âdµy»@Í5b’±µUë…òÐr,ÎÇ:òl³ýf¿½¿A¥ÆYpÇûÉÊÃcØ:mÌÌ·y?W)“úàˬÎã1‰'1¯‡î9Ápà{„9Á¡jb÷ÕSm@Hvý•@ºvE¼ééMNJ­òÒS¢u;½÷]á©Ùû´ãK¬²ƒka…k›¢V“²©c¯Œ´~ΡïR(Qo:¡Ooøuš]le•È´JyîC>¯ÞƒÒíS‡G¬+õ ý&½P˜ây;ƒWVg»Pð»ÒVzh<xÖ–ÄBÍ›IÑw̓Þ
+&¥gJFÑ ïO“aÀR®*Ož
+^Ø™þA¨°î¢F ØèÊÓ¹@w´cÍn55x\¬Øò6Ë? ãž!ïÖP'ß2þR×+ssŒ!iÄYλU`D
+·«O.è”±¹º
endstream
endobj
475 0 obj
-<< /Type /Page /Contents 476 0 R /Resources 474 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 460 0 R /Annots 479 0 R >>
+<< /Type /Page /Contents 476 0 R /Resources 474 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 459 0 R /Annots 479 0 R >>
endobj
479 0 obj
[ 469 0 R 470 0 R 471 0 R 472 0 R 473 0 R ]
endobj
469 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 353.263 528.233 367.988 539.292 ]/A << /S /GoTo /D (subsection.0.5.5) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 353.263 463.247 367.988 474.306 ]/A << /S /GoTo /D (subsection.0.5.5) >> >>
endobj
470 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 380.939 528.233 392.894 539.292 ]/A << /S /GoTo /D (subsection.0.5.5) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 380.939 463.247 392.894 474.306 ]/A << /S /GoTo /D (subsection.0.5.5) >> >>
endobj
471 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 430.922 204.087 445.647 215.035 ]/A << /S /GoTo /D (subsection.0.7.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 430.922 156.649 445.647 167.598 ]/A << /S /GoTo /D (subsection.0.7.2) >> >>
endobj
472 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 458.598 204.087 470.553 215.035 ]/A << /S /GoTo /D (subsection.0.7.2) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 458.598 156.649 470.553 167.598 ]/A << /S /GoTo /D (subsection.0.7.2) >> >>
endobj
473 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 346.259 159.364 356.686 170.43 ]/A << /S /GoTo /D (Hfootnote.21) >> >>
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 346.259 119.497 356.686 130.563 ]/A << /S /GoTo /D (Hfootnote.21) >> >>
endobj
477 0 obj
<< /D [ 475 0 R /XYZ 78.37 808.885 null ] >>
endobj
93 0 obj
-<< /D [ 475 0 R /XYZ 79.37 694.453 null ] >>
+<< /D [ 475 0 R /XYZ 79.37 617.69 null ] >>
endobj
97 0 obj
-<< /D [ 475 0 R /XYZ 79.37 515.275 null ] >>
+<< /D [ 475 0 R /XYZ 79.37 451.013 null ] >>
endobj
478 0 obj
-<< /D [ 475 0 R /XYZ 93.716 139.127 null ] >>
+<< /D [ 475 0 R /XYZ 93.716 99.26 null ] >>
endobj
474 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F75 330 0 R /F74 329 0 R /F64 325 0 R /F15 326 0 R /F65 327 0 R /F22 357 0 R /F83 403 0 R /F16 328 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R /F59 338 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F74 329 0 R /F75 330 0 R /F64 325 0 R /F15 326 0 R /F65 327 0 R /F22 357 0 R /F83 403 0 R /F16 328 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R /F59 338 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
482 0 obj
<< /Filter /FlateDecode /Length 3177 >>
@@ -1303,7 +1293,7 @@ gÿÛº-8
endstream
endobj
481 0 obj
-<< /Type /Page /Contents 482 0 R /Resources 480 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 460 0 R >>
+<< /Type /Page /Contents 482 0 R /Resources 480 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 459 0 R >>
endobj
483 0 obj
<< /D [ 481 0 R /XYZ 78.37 808.885 null ] >>
@@ -1318,7 +1308,7 @@ endobj
<< /D [ 481 0 R /XYZ 79.37 186.744 null ] >>
endobj
480 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F15 326 0 R /F74 329 0 R /F81 366 0 R /F75 330 0 R /F77 331 0 R /F30 333 0 R /F66 335 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F15 326 0 R /F74 329 0 R /F81 358 0 R /F75 330 0 R /F77 331 0 R /F30 333 0 R /F66 335 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
486 0 obj
<< /Filter /FlateDecode /Length 3041 >>
@@ -1341,7 +1331,7 @@ V ’¹z®d¨Ý™#©ß£ÆX‘r¢ô‰û
endstream
endobj
485 0 obj
-<< /Type /Page /Contents 486 0 R /Resources 484 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 460 0 R >>
+<< /Type /Page /Contents 486 0 R /Resources 484 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 459 0 R >>
endobj
487 0 obj
<< /D [ 485 0 R /XYZ 78.37 808.885 null ] >>
@@ -1350,7 +1340,7 @@ endobj
<< /D [ 485 0 R /XYZ 79.37 456.212 null ] >>
endobj
484 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F75 330 0 R /F81 366 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F75 330 0 R /F81 358 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
494 0 obj
<< /Filter /FlateDecode /Length 4268 >>
@@ -1379,7 +1369,7 @@ O,ɦo&g÷‹øîW³çè5ªY=b‰å+ SH§"‡ÀÍü{âf!Øâo®?Z}‡ð^zľÄž-©Ê¹útKÀr s€…NJ1Z»^
endstream
endobj
493 0 obj
-<< /Type /Page /Contents 494 0 R /Resources 492 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 460 0 R /Annots 502 0 R >>
+<< /Type /Page /Contents 494 0 R /Resources 492 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 459 0 R /Annots 502 0 R >>
endobj
502 0 obj
[ 488 0 R 489 0 R 490 0 R 491 0 R ]
@@ -1421,7 +1411,7 @@ endobj
<< /D [ 493 0 R /XYZ 93.716 89.795 null ] >>
endobj
492 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F73 342 0 R /F75 330 0 R /F74 329 0 R /F30 333 0 R /F27 332 0 R /F32 319 0 R /F66 335 0 R /F68 496 0 R /F55 497 0 R /F67 334 0 R /F64 325 0 R /F81 366 0 R /F15 326 0 R /F16 328 0 R /F65 327 0 R /F22 357 0 R /F71 339 0 R /F53 337 0 R /F59 338 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F73 342 0 R /F75 330 0 R /F74 329 0 R /F30 333 0 R /F27 332 0 R /F32 319 0 R /F66 335 0 R /F68 496 0 R /F55 497 0 R /F67 334 0 R /F64 325 0 R /F81 358 0 R /F15 326 0 R /F16 328 0 R /F65 327 0 R /F22 357 0 R /F71 339 0 R /F53 337 0 R /F59 338 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
505 0 obj
<< /Filter /FlateDecode /Length 2595 >>
@@ -1440,7 +1430,7 @@ T–i,£Œ,íç+G~gÑ4 Y«¬ÏH=e±EÐ8+tëËGðÓˆ¯A¨“Y¢²Xý?›%ÕCú•æÖôŒÕ-Û#³géêìÙBæNdvO
endstream
endobj
504 0 obj
-<< /Type /Page /Contents 505 0 R /Resources 503 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 460 0 R >>
+<< /Type /Page /Contents 505 0 R /Resources 503 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 459 0 R >>
endobj
506 0 obj
<< /D [ 504 0 R /XYZ 78.37 808.885 null ] >>
@@ -1449,7 +1439,7 @@ endobj
<< /D [ 504 0 R /XYZ 79.37 559.897 null ] >>
endobj
503 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F84 404 0 R /F15 326 0 R /F74 329 0 R /F22 357 0 R /F65 327 0 R /F81 366 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F84 404 0 R /F15 326 0 R /F74 329 0 R /F22 357 0 R /F65 327 0 R /F81 358 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
516 0 obj
<< /Filter /FlateDecode /Length 4194 >>
@@ -1481,7 +1471,7 @@ tPr—F8¼ÅÞ<ê¬9Þr;ÎsGM\æ·… Œ’@ZÞï;ªhp’öOPß1Xn›5¤®½7å>팺Z/´Í23ê£tY3ZßͲ‘EïÒçô
endstream
endobj
515 0 obj
-<< /Type /Page /Contents 516 0 R /Resources 514 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 460 0 R /Annots 518 0 R >>
+<< /Type /Page /Contents 516 0 R /Resources 514 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 459 0 R /Annots 518 0 R >>
endobj
518 0 obj
[ 507 0 R 508 0 R 509 0 R 510 0 R 511 0 R 512 0 R 513 0 R ]
@@ -1543,7 +1533,7 @@ lPqF².Ê©NhÛÁl=«#ù»Ål™+¶—¼ö·™–O2ÄK´‚ô¶Tž‚›îîr#<9¼‡ÐUá6 ©Úq
endstream
endobj
520 0 obj
-<< /Type /Page /Contents 521 0 R /Resources 519 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 460 0 R >>
+<< /Type /Page /Contents 521 0 R /Resources 519 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 459 0 R >>
endobj
522 0 obj
<< /D [ 520 0 R /XYZ 78.37 808.885 null ] >>
@@ -1585,7 +1575,7 @@ I¨‚M®$¦¢^ñ‘¹6¸ñOOVºŒôô”§ÛžþüÌ•Ä”C»j–KÔا¢¹Rø):š+…wòÓJfT3zLÍr®@>`-¹6ø.Í•ÂOÑÑ
endstream
endobj
528 0 obj
-<< /Type /Page /Contents 529 0 R /Resources 527 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 460 0 R /Annots 533 0 R >>
+<< /Type /Page /Contents 529 0 R /Resources 527 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 459 0 R /Annots 533 0 R >>
endobj
533 0 obj
[ 523 0 R 524 0 R 525 0 R 526 0 R ]
@@ -1615,7 +1605,7 @@ endobj
<< /D [ 528 0 R /XYZ 93.716 110.956 null ] >>
endobj
527 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F84 404 0 R /F75 330 0 R /F74 329 0 R /F81 366 0 R /F64 325 0 R /F15 326 0 R /F65 327 0 R /F16 328 0 R /F71 339 0 R /F53 337 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F84 404 0 R /F75 330 0 R /F74 329 0 R /F81 358 0 R /F64 325 0 R /F15 326 0 R /F65 327 0 R /F16 328 0 R /F71 339 0 R /F53 337 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
542 0 obj
<< /Filter /FlateDecode /Length 3204 >>
@@ -1678,7 +1668,7 @@ endobj
<< /D [ 541 0 R /XYZ 93.716 80.936 null ] >>
endobj
540 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F84 404 0 R /F75 330 0 R /F91 544 0 R /F53 337 0 R /F64 325 0 R /F81 366 0 R /F16 328 0 R /F65 327 0 R /F71 339 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F84 404 0 R /F75 330 0 R /F91 544 0 R /F53 337 0 R /F64 325 0 R /F81 358 0 R /F16 328 0 R /F65 327 0 R /F71 339 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
554 0 obj
<< /Filter /FlateDecode /Length 2303 >>
@@ -1719,7 +1709,7 @@ endobj
<< /D [ 553 0 R /XYZ 79.37 515.126 null ] >>
endobj
552 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F65 327 0 R /F81 366 0 R /F104 556 0 R /F103 557 0 R /F105 558 0 R /F27 332 0 R /F30 333 0 R /F64 325 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F65 327 0 R /F81 358 0 R /F104 556 0 R /F103 557 0 R /F105 558 0 R /F27 332 0 R /F30 333 0 R /F64 325 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
564 0 obj
<< /Filter /FlateDecode /Length 3557 >>
@@ -1770,7 +1760,7 @@ endobj
<< /D [ 563 0 R /XYZ 93.716 99.261 null ] >>
endobj
562 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F15 326 0 R /F65 327 0 R /F74 329 0 R /F16 328 0 R /F81 366 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R /F59 338 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F15 326 0 R /F65 327 0 R /F74 329 0 R /F16 328 0 R /F81 358 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R /F59 338 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
570 0 obj
<< /Filter /FlateDecode /Length 2900 >>
@@ -1798,7 +1788,7 @@ endobj
<< /D [ 569 0 R /XYZ 79.37 771.024 null ] >>
endobj
568 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F15 326 0 R /F74 329 0 R /F81 366 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F15 326 0 R /F74 329 0 R /F81 358 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
574 0 obj
<< /Filter /FlateDecode /Length 3100 >>
@@ -1828,7 +1818,7 @@ endobj
<< /D [ 573 0 R /XYZ 79.37 771.024 null ] >>
endobj
572 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F80 356 0 R /F15 326 0 R /F74 329 0 R /F81 366 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F80 356 0 R /F15 326 0 R /F74 329 0 R /F81 358 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
578 0 obj
<< /Filter /FlateDecode /Length 2872 >>
@@ -1856,7 +1846,7 @@ endobj
<< /D [ 577 0 R /XYZ 79.37 771.024 null ] >>
endobj
576 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F15 326 0 R /F74 329 0 R /F81 366 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F15 326 0 R /F74 329 0 R /F81 358 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
584 0 obj
<< /Filter /FlateDecode /Length 1295 >>
@@ -1943,7 +1933,7 @@ endobj
<< /D [ 592 0 R /XYZ 93.716 108.297 null ] >>
endobj
591 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F15 326 0 R /F65 327 0 R /F74 329 0 R /F81 366 0 R /F83 403 0 R /F16 328 0 R /F75 330 0 R /F91 544 0 R /F53 337 0 R /F73 342 0 R /F59 338 0 R /F85 428 0 R /F71 339 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F15 326 0 R /F65 327 0 R /F74 329 0 R /F81 358 0 R /F83 403 0 R /F16 328 0 R /F75 330 0 R /F91 544 0 R /F53 337 0 R /F73 342 0 R /F59 338 0 R /F85 427 0 R /F71 339 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
602 0 obj
<< /Filter /FlateDecode /Length 3061 >>
@@ -2424,20 +2414,19 @@ endobj
<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
752 0 obj
-<< /Filter /FlateDecode /Length 2645 >>
+<< /Filter /FlateDecode /Length 2727 >>
stream
xÚÅ[K#¹ ¾÷¯ð1{DQ/Àh Ýî^`Ï} rMNÉÿ?F/êUªrÉÓ“,àµ[%±¨OäGŠÒðË¿.üòç g*üòÿÿóåöõòóS¹ 2g…„Ë×?_„ïÄ/âb«.F Ƶ¸|ýûò÷+ç
8×oœKûú¯¿^x–ùóÓâÅ2§µ´­!SVR
uq~hlGǤ¹h'˜„Â&‘?“éJÖÆ|AgigÒ„°Ì7Êûæ•Ý› €`èÞ™©Ì$rÖ;µROõ5?¹·-¡Ox7ÜC‹ XÀ+Øk‡Næ¿`û^Ç<2j|O­FSkäÇ÷Wˆ’ø()Ì\‰ònÂ!úÐ!òÈ‘Yÿèÿƒ¼ò¶§œ™!ïãL9Ø[øÒ¦X:Å¥ÏJwRÊðW Õ¤iÂÍ@yVÒÐ_ý
Éu»A}òHo)ìÅ#úù©È±3ËM3Ìr³Uñfío}Ÿ«(¹·`½ÁtÒ&¼;¼EÂdÅ࡯Kå|Hƒ úË|©•f¨äHT
-N•3Ì…Ä4ΦØæ,æh ä,«šú(ŽGMõm‰R)>Ž¯ª!‘)©6j¼SChf”ÙHÁšu‘½)›],¬áÕ}ËÏoéS9.ñbNI~…U Ä#pG©$=UªMb¢,K¾Rú¬’)³ }Ò­4HÙÈfkR“µEšÿl'RAQá³<-L »™–]›Ö eaZÔúÄ8pŸ%¦¿<MO[Ú÷Í[­yY/¥™'»‰‹2ÀL¥2üHPè}¿þðñk´` ™¿Kp«ùiaú¬s+›x ·$+D•Èò (yõ¦hfîµWŒµP×MÉìL)ô_bšn¶˜­ ÄGÓæ%qõ©w±>{ºÉeb+¹Gˆc&#AYTŒ†Pò•N3¼·H‡V“ã}ŒÖ“Q¦‰À4¯¨iÆ—„¢ñ#O2ë m¾ÑäQ¦RGzµ+YÖ<¡Ç_•º6¼xïЀfÅç@^q†¢#²°$òJYŽÜsl$égâ½ò;ܲóÉtŽ÷ƒ¸}n,‘â}ô˜éÞv–3þ{ÌuyZÞ¸ŒðÛ_a6T.—0è…Ì0h÷Ì ƒ®Vóý8lŠ;ÖÖ—Ž X¼äv’Ên·œy{?CÀkõ"â‡ÚJž‡é­·½æx?êd,â úC©pD)šRi'è¡+Êc¶£˜ö¦2¼-³]©ç#­·”›‘›>Îï…dèwBûߌí½Ý÷¦}-¢9@ýõG\4øl—ˆ(<u,…¿÷´UJ}hãcÎoŽüH9 BY™UÉë0ØœåLcñ-ÝàÖñ{³Çk÷µÞ!w"ªEÔÔûF½Ò®¹Ä„$}oŸáaÔ>!èd•*3P'"ò«ŒrÌ¿TGxÄ;ûiu­>¨'äõÛ.cì,ïA” y"\kv?û#¹¤5ÕÍi­0 M›¶Pi•7$†©|‘Ô‹ëCâç¨2ƒ(ú˜ ÀïíÃט\`ÎYTed”-[ œNbÐúÝûjZ… ÒÖUàVs#èd›;ñl«ƒwû´ªúDæ„R2 ¿›é…2þ-z|ÛsÙ
-Ǭé‹ötÙ—üºò|vÕV ûµžfPÇ,×XátçbÌ
-Ï}Òƒ“ÜeNÃJ!ÐŒ1µ,y02 n„`„Ôÿ'KÁ!Ÿ.—ñ| ³v#ùÀµ³öT7z:»Ñµ3
-ƒk§Vz“¤@ZZÛ™4K¸ ØÒjæ\ÙïÎ_qÉJÀæÒ”¸Ú°ªá¸»œ
-,—x[Î$N1«ìˆÇjòÜ'z”ÈÓ^é
-”µl,ãy¢\¡µÆOp–àl¸éhO_ Êêd¬3Öì^Üfv«Ì#¬cFNkÖRñæQüÚä³Má)‘ø´/ƒ„V1ó;ÅÏœà«MF¥…œ´§ןìôá9=Uüä1~s"¿°X{”1©bO˨†&v¯I†KÌ ÇeŠy- ×%2#`M—ªÖ½k'G׎­»7$…1ÌØÁ&nm;Nöd3ÈŸ+§-™•›jõÚ]€AÈsçP­ßÖ\<c̉i†ª”ZðW¥ðD¦d.W§Ó0²±úWUU¯V§¨6ÓÏÿŽ¡‹«D¹G#¡öä,Œ’»:èNíPû¤m«ÓÞÎ~éã؇Ã%JܨçyRøÿ®ôo‰æ(«ƒ+>éé‰yfÓœ¹æ¶ÛN
-}nE–•UÕàɽåt€‹lCª¹< ‡j…é ’O­+^T•ÝþöŸ?ïN g!7°‚ç¶[ˆLûQÍ|<«ÖGoj;ìeq*º<¹5÷¹cKÝ’ÝÒ'eÎôxü‡N%xd
-I§þwJ¯šU™c†
+N•3Ì…Ä4ΦØæ,æh ä,«šú(ŽGMõm‰R)>Ž¯ª!‘)©6j¼SChf”ÙHÁšu‘½)›],¬áÕ}ËÏoéS9.ñbNI~…U Ä#pG©$=UªMb¢,K¾Rú¬’)³ }Ò­4HÙÈfkR“µEšÿl'RAQá³<-L »™–]›Ö eaZÔúÄ8pŸ%¦¿<MO[Ú÷Í[­yY/¥™'»‰‹2ÀL¥2üHPè}¿þðñk´` ™¿Kp«ùiaú¬s+›x ·$+D•Èò (yõ¦hfîµWŒµP×MÉìL)ô_bšn¶˜­ ÄGÓæ%qõ©w±>{ºÉeb+¹Gˆc&#AYTŒ†Pò•N3¼·H‡V“ã}ŒÖ“Q¦‰À4¯¨iÆ—„¢ñ#O2ë m¾ÑäQ¦RGzµ+YÖ<¡Ç_•º6¼xïЀfÅç@^q†¢#²°$òJYŽÜsl$égâ½ò;ܲóÉtŽ÷ƒ¸}n,‘â}ô˜éÞv–3þ{ÌuyZÞ¸ŒðÛ_a6T.—0è…Ì0h÷Ì ƒ®Vóý8lŠ;ÖÖ—Ž X¼äv’Ên·œy{?CÀkõ"â‡ÚJž‡é­·½æx?êd,â úC©pD)šRi'è¡+Êc¶£˜ö¦2¼-³]©ç#­·”›‘›>Îï…dèwBûߌí½Ý÷¦}-¢9@ýõG\4øl—ˆ(<u,…¿÷´UJ}hãcÎoŽüH9 BY™UÉë0ØœåLcñ-ÝàÖñ{³Çk÷µÞ!w"ªEÔÔûF½Ò®¹Ä„$}oŸáaÔ>!èd•*3P'"ò«ŒrÌ¿TGxÄ;ûiu­>¨'äõÛ.cì,ïA” y"\kv?û#¹¤5ÕÍi­0 M›¶Pi•7$†©|‘Ô‹ëCâç¨2ƒ(ú˜ ÀïíÃט\`ÎYTed”-[ œNbÐúÝûjZ… ÒÖUàVs#èd›;ñl«ƒwû´ªúDæ„R2 ¿›é…2þ-z|[ήòìgQ/1BÍ6652bRR掰ˆo+ÑÄ“ˆ[-±à•Ú¶ÅJ9pk©t3XQ-æÊ™u3#yœê¢@ÆAR´½%@p~ç··«Ä*³¦¯ÏØÓ•w¢Ö^%weEN'¸m¡¶w·>ET·$*×XátóhÌJ¨3ú$‰&¹Ë$š†•Z¬s’Ô²D¢È4¸‚Rÿgœ,Yw>à=®¤ú\ÃÚävÍÚÓY„ÑÓÙìšQØ5µÒ›$å2¥µI³„ÛœIZÍœ+%—‘k.TÒ¶âõÑ\š*c›Ùh8®¥/gcËUöV‡3ù·SÌ*;ⱚ÷ù·¥„ø•¸±Ìð^+¦Gô^Ÿ«·ç¬^:òÓ×vÍÂ}Ï„ØXÈsô*߆)1ÒëÚyÁ äùúÁ#zÝ"5­< ]L@Á EkágÏ»ŽO­j|n‚wVÑ‚Û^q^÷ŠbãËFåŽÌ2óûºyÈp£
+ãoBx½ÎDcñ•Ò”¦þO¤~T")ùGtPsNÒ ‰ùÓ`ÛDRØï×½6=—óª];ñ¡’“öÇnZ:)êAÞoÄ‘%lï¨tr{¾MKBâ&±–Š)“¼÷üE`®3XÎ|î6z•\Ê÷!€?¸§=êž¼
+*½1 ^çNx
+hÅp'ÿ/›»îˆ¦+€²?­ÅhéÛÐÑç7t®)‚î3Kº1[šúÄ©¬i×'šØùij ”`Š›=Ù%{ê…ü{º÷»ö Õ·ÙÔLi9µ»È§-­p€¹YÎëwµDÛ㎪PX̾bŸ9íLéîwÇî}R?Ù!ÎÝú†ù1r(:i!s¢Y•Üà1˜)³ÍÑeíß(8áj¿Qм°àÌv ¿.µëè=ßÔ NFÇÈ_ËnØ¡«`)ñ©Û§“ª×Æ2&yyT ¬åXª{Š(Whm†ñœ%8.›ÚÓw6ˆ²:ëŒ5»š¸™Ý*ó똑Óc©ø
+ó(~mòÙ¦ðƒH|Ú—AB«˜ùâg.Q¨MF¥…œ´§×®õwrzªøÉ›Í]”üÂbíQƤr@ŠQ<-£šØ-û†{ä ÇeŠy- ×%2#`M÷5ªÖ½k'G׎­»—T…1ÌØÁ&nm;Nöd3ÈŸ+§-™•›jõÚuŒAÈsG­ßÖ\<æ̉i†ª”ZðW¥ðD¦d.W§Ó0²±úWUU¯V§¨6ÓÏÿ”¤‹«D¹§S¡öä,Œ’»:èNíPû¤m«ÓÞ)Ú~éã؇Ã=VܨçyRøÿ®ôϹæ(«ƒ[Véé‰yfÓœ¹æÂáN
+}nE–•UÕàɽåt€‹k”Wnp¨V˜Þ ùÔºâ]aÙ½áoÿùãðú
+zörK xn»…È´ÕÌò³j}ô¦Ö¸É^§¢Ë“[s¥>¶Ô-Ù-}RæLÇkV‚gA¦tê§ôªY•9fèV0CtLØÍ:Îv\´)ýŠCm³ ‹p§Ïèj­ÏÕl7â—v×Ç'@O6®˜‰›môÒ»AÈ÷l£@¸¥åõôFçšK.o¥ðýñõò_ÉPZ
endstream
endobj
751 0 obj
@@ -2691,7 +2680,7 @@ endobj
<< /D [ 804 0 R /XYZ 79.822 148.157 null ] >>
endobj
803 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F81 366 0 R /F59 338 0 R /F84 404 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F81 358 0 R /F59 338 0 R /F84 404 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
826 0 obj
<< /Filter /FlateDecode /Length 2254 >>
@@ -2830,7 +2819,7 @@ endobj
<< /D [ 825 0 R /XYZ 79.822 130.224 null ] >>
endobj
824 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F81 366 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F81 358 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
868 0 obj
<< /Filter /FlateDecode /Length 2973 >>
@@ -2963,7 +2952,7 @@ endobj
<< /D [ 867 0 R /XYZ 79.822 136.087 null ] >>
endobj
866 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F81 366 0 R /F65 327 0 R /F59 338 0 R /F84 404 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F81 358 0 R /F65 327 0 R /F59 338 0 R /F84 404 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
904 0 obj
<< /Filter /FlateDecode /Length 2176 >>
@@ -3667,18 +3656,20 @@ endobj
<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F59 338 0 R /F84 404 0 R /F15 326 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
1120 0 obj
-<< /Filter /FlateDecode /Length 2048 >>
+<< /Filter /FlateDecode /Length 2056 >>
stream
-xÚÕ[Ër#)¼û+ôÃ@UQ@„Ã#Ûšˆ=û¶±×ÝÓþÿuyvóhÉ,Íh²õê„JŠ¬„FòðÏA~>I¡Ã3ÿ÷çÓñãéûI» gÂáãï'å¿$ê`µ
-ÇŒ¶Q¨…¶Ü£
-×¥ÏÊû|›PÑ E؇Êz.Ôø囃®ƒã#Ó#t8ü‡×ÐrÅrmkã¿£^y
-³V‚ ô”tŽì‚
-ûo ­p
-˜ê«Œhš­7:K¤„DPÏiˆBÚ—”ôÄÐÃrN¿|#’äðêT_é}]µž±hÊw¢»n®*äGÒmxþæ9X„ãrý¢Vå?´Füöy^^{wL¸\œDD‘
-øëé¹Ø¡&àSÎÏ<¾å4ÄVm ±–J8iûA.3ÝžÑ,p͆!ÄÈP&ú”=ÓªzÚ˜iòæÛ5¾q·…wF8°=H,\\§ÃZˆJj×3Šrl¨ÊœUý‚* yg={Ý{Q…ұcÐýb’yõƼ–6.á­$€—.%Ö- òÎælŒŸˆSgùþ™d/)7f¡zM ù¢ùy­Öñ?¬s°êdÙ·²iŸ"w4ש¶s]hyÞ'‰Kí®øWe¼_5›!á÷.ErnA‘r9¡ÕóS*e‹¸Ó£Lßð9ßu•N~}môñÎ¥JaëQsšËO1¦¥êŸs aL‡ùœs§, (ëÃ’þ?.Qç?ó‚ Cû!‰!=×|‹UùÕ¸qƒ*ìÝôÍÉÒ¡Ü6[Õ.“_¬[ĺ¹ÅU‡r[êŠ) ßXªèZF-ju®¡é²à“ö›ÅÁë²d® ñ'’=håù¨s mõ¼k‘Šú>mÍî²QPŒj`¤bìRÜ`@ ‘§9^"¨ o['b!£Ôb=še3¹ªÞëQe“k~yÑ”A ^®a|¾´–ü@¸È!y÷c€÷pØ+䂼Í9+$ 3]òˆ<Ž2C˜[½w(e=fNqs$ÏåÉ] á‡ðhjçµCÙ9|» Ü]ç§Õ†
-É;vk*ìn¹B+ìksΫC™+y'ý¸¸áà}ïèƼÑÄnyÎu(¿×åö6)|X•ó¹ÓnúÄÌ3h-ÈmóîaåOj¡Gæ&M[‡r[êAÁ‘ÐnµPaDÝŒ“‹‚‘z€I'×£ì*3¿ZÃþ݇:iî:”ßcîþR¬„Q<Ð?gøz”›dÚ£Š hƒî(›ô€=ÊM({ñC'Œ³=»}!€¶:WRrÎv(ýpá;Þ'•ë=º²cnèÚ3"×Üù¹Ô»rÎn»w­®,wyn£ Ê; ää!çäkÃð°Š Y8PCÊÏÊåkT=‚(§Ã¾}OKç/(òÿýu5@Èn3§´J«žÛ÷Åšù×îÏoœ¥ üî=´ˆÇC‹]âç{tñ$íü8’tOó¤ÛìP¾Hsu&¢ä›_ ½>•Ôò.ÓY1
-i¹çcòD‡ò5>~ÓíX…,Ö Ó‡Ãp6ß'\Þ`Õùr"- õùƒ7×ܬS ³Ffέv(Ëñœ|`¬o̧ÉÜmñ£ #¡ç~$Ò¡™)ÇCâtØ<S]Œú4õÖ¨¶ Û,­­¤V7,ÎF¯ÒéÊ|Ó9§ÍrÖ¶(®~ú­ÎmÖ¥$
-CC½™<—Ñ¡L¤×WýÍÝÑ0–†i7çÈ[r`¡,bØ®b÷iò.¬}þ‹€¶³y:M‰UÂÂP3'Íq r’‡Í #…å¡TN:ߤ±P)MŽ‹`ý=$²ùe3¶ÿI&=îãgk>Î4÷>²Ýzÿxú¼°$
+xÚÕ[Ër#)¼û+ôÃ@ápÄȶ&bϾmìu÷´ÿ]žÝP´äF–v4Ù­GgSI‘•Ð´<üs‡ŸOR˜xþþ|:~<}?ÐÂ;…pøøûI…Ƀ:8#À™ƒ%%$©ÃÇ¿‡?Ÿ¥D/%™øÿå¯?ždÁü~rúà„'Bׂ(4Â8â( ¥Ô. ½‡c•_ñXCx½åcƒù=…+•?×å¿ çÓ[þ©œð
+&æsÒy.·´‰ú³J²› ¹G¹6äpá®ÏßÕÏé6¡¢J#•Ì\¨=
+ÐË7¦Ý›úGæWlpü¯1 åŒåÜÚ×6üF½fò"p
+ïÃKSƳëÕìÆÑÛ4%à„
+ñrJô>J k,G‰Äž¢Úƒ®I`¨5®7þ¢¦4Ú†2\©ˆ/,9ÔS‰ºÅ«$ÚßÚ«]A²À ;jZ@ I
+ÇÌ]åjài’òF ´]!ÓíNMÊGIc¥̹ãcXXD!½ï:³óÚŽ¸-™Ù&éBN Ôž“a`ŽŒå1ëãHÈAGñÿ,ð_«¯dQàÀ §äµaêz·Œ©z«JÄ”ì‰W^ô|›¬¨1j`ðÇ”b0”Ïã‘U˜ŒÚ§„9² *~-ŒÂÀÍqÚ£Ô¤3ºSÞSI¢ã˜š}®<MÈO’omA9w¹ö¸/ŒÑCú™9ªz”mªÎ¥\MVs,áÃúYJ½{§›rÂx3P w§›´‚†tÃ9{”ÄÄ[vIÆC’Xh™ØUøoàSéõ\K¸OÍï[ Iß3 M¹ê¦Nö£ñ$Ȧe¯÷
+ô£ŽRšñý¤ÌÁ‡³€t{–õíÁ FgÉ €œê9wQLûšÒ‘žzœÎ™—oZËHr|wjÏKô¾®Ú
+ªQŒ4Œ]Š,„!ò<Æk­áíëD*d:_±íͺ˜ÜÔ‚àõtc“3kazÑ•A›
+^©at¾´Öü@¸È¡îÇíá+䂼͛öNHfºäip”*ÀÜì¡ÔùX9ÕÍiy.OîZàЊ
+¬Eå—ÊØ{i:Iýû¸öNKŠ†1”[kXËÓï«]hU»B³P=w+…£Ì§Ð£Š’¨‰ó39éá(;ùy,¹B»³n·\¡Üks΋¡Ì•€²’~\Üpô¾wtcÁè M~yÎ1”_ëÆÊõ6)|X• ¹Ó/ú¤Ì3h=ÈmóîaåOaFæ&MC¹-u àµ0~µP±GýŒ“‡‚Ps€I'ÇQv•™ÿ[ãúYÃC4w åט»ßQ
+”°Šúç G¹I¦=ª‚‘)hFÙ¤ä(7¡ì!Ľ°Þ ôìö…
+«‡z3¹/ƒ¡L¤×WýÍÝу°NÃnΑ÷ uÃÂýWœ†ê6¹æÚƒÔd^:¥TìºÛ¢îUÙ÷MO{Pá8ý
endstream
endobj
1119 0 obj
@@ -3853,14 +3844,20 @@ endobj
<< /D [ 1119 0 R /XYZ 79.822 78.635 null ] >>
endobj
1118 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F81 366 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F81 358 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
1180 0 obj
-<< /Filter /FlateDecode /Length 1792 >>
+<< /Filter /FlateDecode /Length 2074 >>
stream
-xÚÕ[Moã8 ½÷W䔕(ê XhÚf€=÷¶Øëîiÿÿu%[Ž-*IEÛ™É: ûY|"ÅGJ£ÿÔáÇ“›¿¥<¿ž^N6bÐ_ÿ<ét“:èC°€Á¼Ó œ>|ýwøë¥LPÊ¢Rôùú÷ןOª`¾œDçLX‚híÀ[ÏQ,)¥ß•r1!žšRÊ'T—> Ëu|}6ÎÛ|{z©Wã#”¾»üsúüÉßíq¼N8_Ãù™×g­¬Êã§×g‹4¿#ß8‚MWñc´kÁÑwYZá’ —Æ⣌ †’¬NÃ1ã_¶z¤?’ ¥bG& )±ýþúL~0j6©0˜@=þåï—ß7þ6¿hI&‚&ÃI²(#‰¡|OÒãz ÐÉZFˆ;Ê©Q†*.‘‰Éau$£Ë2I8Ýr*ã]º½õžoÝn|xWsÓ·l‘i÷&@{@´Í¼É& FY9×¼ÔøñÑìpã“w–‰Ê,aÅ÷U9@ç8OF¸¼1”2øløMŽæõÿ7sÒÈ;8©‹Œò ùAD>G‘“ÿÈê¡Ø²•qT£äÁeƒ³QÙyHÉ‚{4æwôÛ·]üÖ0í”lJ*ýfä¡Ù!ÑMÀ›Š¹% °’êã
-Šn†šf
-’lª)5G¹Ö;\®†Ó5Gß©º¶,¶ÞZ&üX÷·¶õªŒ1à\ë¦FFL2s*Ã,«·se2„Ù&ft±ÁˆàU£T„Í9†²".´Ou/ÛŠY eE\(>x>Œ^ý1MÒS0üŽ" œœ^aPÈa(—bcÝÙŽØø¾½!¥Ä.6”¼‰Ü–¡lé² ó5P'Ô ·eÂÖhDÛRz5&‡›¹•Žb(—Žj/j&f¶œçhß4cŽïØÀmrÜ”jd (†r›šG•öˆÊÛÆͺ¡6á
+xÚÕ[Érã6½û+ôÓƒnìUS®²FVªrö-•krÊÿ_€
+™éí…$Ÿ‰¡  ¥æ,„õûÄP„@ŽB* eŒ>ïÓÿe¾F?ƒ¢ñsyý¦Iç7”ËO†'TA‡kø³¾=¡Ío˜ò›ºNMó=;Lƒô€Jrä -J¡!ª­Ï“"Q)sÉʼOô¨øL¸/¯-=×è!œ>-QäóÛïËo<@î(mä
+HÝ[a…¿I ^'&¢ä¦Ó,>£Cþ_ZÇ¢M¹®äßè<ñ5ŸzgŽ…y±Xdªó÷»"Ã’OKÕšäui'ÉÎÜl­¥†ÇA’™ËÏ'K’’I¬ƒokK¾“®%QÒ+Q”H[‡ÎÓÝ$Rº›éÛ4IgC*5pÛˉ>,£ïTJË™¾¹q“Y¹”D ½>teQã\–}ºˆu²Ê7#M\cyŒ”~(F2”y;ìÔ8¨lz¼ÆÁ Öá$`Œ%\§ S°Eá©V‰ÉæJŸ\&¬ž±EñÏK ÅGR}ÿý7«¥qµ¥|—Iõ‰-Êm†!HP;‚ÔA %>’Ó'j„´–»Ó\AÞcUëß7Ý«_tI±Ä“]{!åI ås’ž×jH¶]£±·í+„´(É¥.5?D·ºE’ĤY$©dYºf²ò&<Þ[ϧfw«Ÿ»ÃÞj'Xw|P‚Á¶eyÛßð–hQ.À-+•¶æùôj±Îk©êbiæé3ÔPŸ­9O{;âÂCÉÂGÅ79ªñÿf¤æü#ÕÁxÃÉßÛWgò9Ê8ùÏl A>°Òvµú %
+ŽJEãQb̹5ý_íöí!vk<Xëøš ¶ åqkòÔæ¬8ôumÓ²ä
+kQS\㣨t@;3Õcš¶(µöNJ›²gV…î²Ã¥é
+ùð`ÿõõ:? s˜c´`YeU åq?íÆn<×eîœr¬rc()eŠåY¨:y§›JÝw¯ß;‘"¯Á‰.· NÿʯYƒg­ÀÉ)pªÝeÓ]½‘íÉJpÎq€Á}d†RÎÒµž8ûº*› 'ÏUØ[üå*›¡¬‘W9™–n5.úÊtª±…nÓçOµÇñ~4‚ïLaïÀ.·ë-Èø,Bˆ\
+9ö åÖØp K€ª^Å·©n…ÅÞZórŸÛáÖ}ƒªð6#èˆqcÄ´(‰˜|Uåèm]mK’›ÝEBEV=/;{›Ì1”^! TcS,†2îèm3º[~9´ü e¯_”@¹zï™|Â.tí-
+9-Êšo;¸±Ã7>ŸmŒRbÃOÝæeµ2–Í–¡Ü3bA£€¼ç 
+ e»PxÚfµRTWpl]¨¤Ã`ìlCY;¨½h"vvß{šã+ϵ£DPDœšÁùCÙ¦æYk{$ÊÈŽŠÝGŽPxТ·Ó±y C)Ó²Tç>k¹ƒ!•ìŽÃÌG‹~ï@+Ý©¦†jþäž’÷h{~¢="w<Q8›"=79”'Z¦lÀP—¬ów ò¸Ò–[l©_z‹]-yoþ£g§ÍI‰Ð0UÝëQ÷—G@¯Ó
endstream
endobj
1179 0 obj
@@ -3885,559 +3882,557 @@ endobj
<< /D [ 1179 0 R /XYZ 79.822 724.994 null ] >>
endobj
1187 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 714.035 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 687.136 null ] >>
endobj
1188 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 703.076 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 676.177 null ] >>
endobj
1189 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 692.117 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 665.218 null ] >>
endobj
1190 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 681.158 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 654.259 null ] >>
endobj
1191 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 670.199 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 643.3 null ] >>
endobj
1192 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 659.24 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 632.341 null ] >>
endobj
1193 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 648.281 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 621.382 null ] >>
endobj
1194 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 637.322 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 610.423 null ] >>
endobj
1195 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 626.364 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 599.464 null ] >>
endobj
1196 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 615.405 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 588.506 null ] >>
endobj
1197 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 604.446 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 577.547 null ] >>
endobj
1198 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 593.487 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 566.588 null ] >>
endobj
1199 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 582.528 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 555.629 null ] >>
endobj
1200 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 571.569 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 544.67 null ] >>
endobj
1201 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 560.61 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 533.711 null ] >>
endobj
1202 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 549.651 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 522.752 null ] >>
endobj
1203 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 538.692 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 511.793 null ] >>
endobj
1204 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 527.733 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 500.834 null ] >>
endobj
1205 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 516.775 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 489.875 null ] >>
endobj
1206 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 505.816 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 478.917 null ] >>
endobj
1207 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 494.857 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 467.958 null ] >>
endobj
1208 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 483.898 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 456.999 null ] >>
endobj
1209 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 472.939 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 446.04 null ] >>
endobj
1210 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 461.98 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 435.081 null ] >>
endobj
1211 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 451.021 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 424.122 null ] >>
endobj
1212 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 440.062 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 413.163 null ] >>
endobj
1213 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 429.103 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 402.204 null ] >>
endobj
1214 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 418.144 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 391.245 null ] >>
endobj
1215 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 407.186 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 380.286 null ] >>
endobj
1216 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 396.227 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 369.327 null ] >>
endobj
1217 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 385.268 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 358.369 null ] >>
endobj
1218 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 374.309 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 347.41 null ] >>
endobj
1219 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 363.35 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 336.451 null ] >>
endobj
1220 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 352.391 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 325.492 null ] >>
endobj
1221 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 341.432 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 314.533 null ] >>
endobj
1222 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 330.473 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 303.574 null ] >>
endobj
1223 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 319.514 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 292.615 null ] >>
endobj
1224 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 308.555 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 281.656 null ] >>
endobj
1225 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 297.596 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 270.697 null ] >>
endobj
1226 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 286.638 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 259.738 null ] >>
endobj
1227 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 275.679 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 248.78 null ] >>
endobj
1228 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 264.72 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 237.821 null ] >>
endobj
1229 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 253.761 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 226.862 null ] >>
endobj
1230 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 242.802 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 215.903 null ] >>
endobj
1231 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 231.843 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 204.944 null ] >>
endobj
1232 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 220.884 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 193.985 null ] >>
endobj
1233 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 209.925 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 183.026 null ] >>
endobj
1234 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 198.966 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 172.067 null ] >>
endobj
1235 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 188.007 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 161.108 null ] >>
endobj
1236 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 177.049 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 150.149 null ] >>
endobj
1237 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 166.09 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 139.19 null ] >>
endobj
1238 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 155.131 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 128.232 null ] >>
endobj
1239 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 144.172 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 117.273 null ] >>
endobj
1240 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 133.213 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 106.314 null ] >>
endobj
1241 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 122.254 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 95.355 null ] >>
endobj
1242 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 111.295 null ] >>
-endobj
-1243 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 100.336 null ] >>
-endobj
-1244 0 obj
-<< /D [ 1179 0 R /XYZ 79.822 89.377 null ] >>
+<< /D [ 1179 0 R /XYZ 79.822 84.396 null ] >>
endobj
1178 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-1247 0 obj
-<< /Filter /FlateDecode /Length 1841 >>
+1245 0 obj
+<< /Filter /FlateDecode /Length 1834 >>
stream
-xÚÝ[Ërë6 Ýç+ü—Á×L'3ñuÒ™®³ëtÛ®úÿÛ’i‰ ‚mÝ:w¡ØV¤#âàA€„ÔîŸÚýþ¢Àæoéïï/ûÏ—ï6îbÐwŸ¿èt‘Úé]°€Áî¼Ó œÞ}þ»ûó7¥LH‡QÊí_ÿúüãEUÌïv¢s&,A´và­ç(.*¥(… ‰Túé3>£ãë7òhÓe6ýôjº”ÒwwÈÿNŸïéPÓw»ŸÎçÛÛ9üHG¾çðúM+«ò¸éõ›- ùÙù ¬ÅÃ$Ï‚›kÄXZá@Ì›Œ˜%aÒè­N’ãLŽ¥Jؾ2nt‘,“”Oç[²à…€*¼Kš„—
-g"h2\8× G
-0GAš4žGš¢Ò÷*4Vͼs Ui~5Eó¨§ãˆ² ®©«÷v#„t’ždõ(… …HM­t˜üÀT_ÕܨýÎÔà;ÌZ{@´ƒY[™Y÷(7šõ9ß7~‚Ê\”Ò|¾š櫹ÀÄÃsO$ã©GYÏÓô?ªÂ¶ëšpí¼ÙOœÚc8=)*ë3OÙ›=q'rÉï%§´ÔãÝ®~Cûv<çºiϹ„g³°³~¶È»^‡.Z0ÊNlD:d(Ûëð™ÝÂC‘SJï2J{”ßjü+‚»J]XÐt†R[‰ÈN±´s‡+ÓQ›z²=îqÊàO 5Ÿ?5Ôr¾žËßÇ¡žœ©n×7`:ÕPB÷Q¦šdCÍT£ÍF‘KŽZIW£ÛÊŠÍ©²(£ªG¹‹+ú:VL[±Õê®aAÂP6ÔÍÿjÇ)Ï´Ú \Éj†²ž«%´Ÿí±Lƒg&¢c.°‘Nælb›ØÕå-Ruak‰«Ë#tr›º‘c 9åÃÌZ°Ñ<O=Jãb)IISÕÌaQµ›ÿÇÕ¡™‡€s¡ùÜ0—a›óRè~XXVœqC¨‘Õ e#¬ɛٮœ÷O²º‘£,x¢ÊI–NÆÓq±Ì†kµ_"Èùu»[ÉêØÄ;–ròÓ§×a²‚£<žü{=·ªî¬'ðƒ ‹»d¹ÆUÔÛLàP³žk×´2Ù»)§hñk6‹‡Z¯txíãðdÁÎ@PóBºÍœ¸ˆc(ÛèàiØ"BN¡°¸c(£p"Ç@qfq%.`q½¸ö„GÅaÒ‚á*Öp åùTð´`D¤þ¾,\r
-™Ÿ2=õ'y¸V`¼ãD
-sF†r›>«§›úI¤PÖzº ȆÁXe™Cáë[¿š‡ïbH#‘‡3”-<œ¯¤>‹gçÀÓ‹0]ìAd6÷´þl-Ø 93,)¼äÏDà°›ús§“0+â(¿šÿÎ'iíz^óß%yŒtˆà•åÃX›e™l*Ž£|‘ô@J•ÖàÉ T½É¨êQž<ÎJ)R
-|𜢵ÙR3êåž !BÀ0 H¶çÎQ¾dXG ¸8˜¯]ÖÑyˆz¸_¶Ì@Ôb[ÿÐÚmniÀá«¥h>̨-Êܵ§ßÀ°uíÀK).1LbD Ü©ä(‡:•¹:•µßÃ#&Ð#§jÑaÓÇ+·l>=’¤Ûy«9omäßË®üûÔmkÛÔ°£‰È1í¤¿N!oC&sI£H ¼å
+xÚÝ[Á’ã&½ÏWøÒ 4P•Úªñx¼U9Ï-•krÊÿ_,ÑØcµmm<{ÐŒ-KOðúuÓ HíþÙ©Ý.J¼ì?^¾]ÜYˆAÜ}üý¢ÓEj§wÁ·ó¤A‘Þ}ü»ûów¥LH‡QÊÇï}üñ¢*æ·c°»
+zq3Lm oíeÍèQÄÍÀ
+?ógë F
+A;Ï)Z›-5Q÷(÷y5èxƒ„kîåK†u ‰¯kú¦8P)\f j±¬hÛmnÙ€ÃgJÑ|˜Q[ 9M”ѵ§ßÀ° `P …Õ [†p0‘l¡’£êPFu(k;|@OœªÅ› ¯÷ÐÛ¥–$Ûç¥æ¼´‘¿/wíäïçhW·M ë™yH«Ì`Õ/rit`­$![µc(ó†òf­Â@‹%ûygŠ-â^k 6 pæ…¡´ØÖ©d+’ª´»Ê€ÃnÐ2Q<WÂP¶|˜ûü,ÚÝýæPDp8G½Ùþýݲ²fëÅEZš´Ÿƒ†§Ÿ³Ó,h 9ÂD¤yœKýôw3¾uÒTê(æ¹Ù¹£˜$BŽvVAôó\μ%ïýãå?Hu^5
endstream
endobj
+1244 0 obj
+<< /Type /Page /Contents 1245 0 R /Resources 1243 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1177 0 R >>
+endobj
1246 0 obj
-<< /Type /Page /Contents 1247 0 R /Resources 1245 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1177 0 R >>
+<< /D [ 1244 0 R /XYZ 78.37 808.885 null ] >>
+endobj
+1247 0 obj
+<< /D [ 1244 0 R /XYZ 79.822 768.829 null ] >>
endobj
1248 0 obj
-<< /D [ 1246 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 757.87 null ] >>
endobj
1249 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 768.829 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 746.912 null ] >>
endobj
1250 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 757.87 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 735.953 null ] >>
endobj
1251 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 746.912 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 724.994 null ] >>
endobj
1252 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 735.953 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 714.035 null ] >>
endobj
1253 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 724.994 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 703.076 null ] >>
endobj
1254 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 714.035 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 692.117 null ] >>
endobj
1255 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 703.076 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 681.158 null ] >>
endobj
1256 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 692.117 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 670.199 null ] >>
endobj
1257 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 681.158 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 659.24 null ] >>
endobj
1258 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 670.199 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 648.281 null ] >>
endobj
1259 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 659.24 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 637.322 null ] >>
endobj
1260 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 648.281 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 626.364 null ] >>
endobj
1261 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 637.322 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 615.405 null ] >>
endobj
1262 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 626.364 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 604.446 null ] >>
endobj
1263 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 615.405 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 593.487 null ] >>
endobj
1264 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 604.446 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 582.528 null ] >>
endobj
1265 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 593.487 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 571.569 null ] >>
endobj
1266 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 582.528 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 560.61 null ] >>
endobj
1267 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 571.569 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 549.651 null ] >>
endobj
1268 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 560.61 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 538.692 null ] >>
endobj
1269 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 549.651 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 527.733 null ] >>
endobj
1270 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 538.692 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 516.775 null ] >>
endobj
1271 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 527.733 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 505.816 null ] >>
endobj
1272 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 516.775 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 494.857 null ] >>
endobj
1273 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 505.816 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 483.898 null ] >>
endobj
1274 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 494.857 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 472.939 null ] >>
endobj
1275 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 483.898 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 461.98 null ] >>
endobj
1276 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 472.939 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 451.021 null ] >>
endobj
1277 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 461.98 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 440.062 null ] >>
endobj
1278 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 451.021 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 429.103 null ] >>
endobj
1279 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 440.062 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 418.144 null ] >>
endobj
1280 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 429.103 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 407.186 null ] >>
endobj
1281 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 418.144 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 396.227 null ] >>
endobj
1282 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 407.186 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 385.268 null ] >>
endobj
1283 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 396.227 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 374.309 null ] >>
endobj
1284 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 385.268 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 363.35 null ] >>
endobj
1285 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 374.309 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 352.391 null ] >>
endobj
1286 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 363.35 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 341.432 null ] >>
endobj
1287 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 352.391 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 330.473 null ] >>
endobj
1288 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 341.432 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 319.514 null ] >>
endobj
1289 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 330.473 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 308.555 null ] >>
endobj
1290 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 319.514 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 297.596 null ] >>
endobj
1291 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 308.555 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 286.638 null ] >>
endobj
1292 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 297.596 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 275.679 null ] >>
endobj
1293 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 286.638 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 264.72 null ] >>
endobj
1294 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 275.679 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 253.761 null ] >>
endobj
1295 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 264.72 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 242.802 null ] >>
endobj
1296 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 253.761 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 231.843 null ] >>
endobj
1297 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 242.802 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 220.884 null ] >>
endobj
1298 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 231.843 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 209.925 null ] >>
endobj
1299 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 220.884 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 198.966 null ] >>
endobj
1300 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 209.925 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 188.007 null ] >>
endobj
1301 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 198.966 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 177.049 null ] >>
endobj
1302 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 188.007 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 166.09 null ] >>
endobj
1303 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 177.049 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 155.131 null ] >>
endobj
1304 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 166.09 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 144.172 null ] >>
endobj
1305 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 155.131 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 133.213 null ] >>
endobj
1306 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 144.172 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 122.254 null ] >>
endobj
1307 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 133.213 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 111.295 null ] >>
endobj
1308 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 107.31 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 100.336 null ] >>
endobj
1309 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 96.351 null ] >>
-endobj
-1310 0 obj
-<< /D [ 1246 0 R /XYZ 79.822 85.392 null ] >>
+<< /D [ 1244 0 R /XYZ 79.822 89.377 null ] >>
endobj
-1245 0 obj
+1243 0 obj
<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-1313 0 obj
-<< /Filter /FlateDecode /Length 2245 >>
+1312 0 obj
+<< /Filter /FlateDecode /Length 2119 >>
stream
-xÚÕ[Énä6½û+ú†CVqÜn÷
-„Vû€à†¡Jå
-è¼qžB¼)ºV´¦<Ǽuà¢|ßž1Âü¦3Âö…‡)ÿ¾dPÑЃqjœ‘rŸ5'êÍu”1…XÚØ2®:Ñqë2v²¯Dó±štßz\)CR"å$ó³¬Kø2Q[¤³TX|DÀí’Ѻ•_Šß‰nøaKc"ÇËù„²ÈPÀ”O¼¬T`„ÈÏ©À†Âºdo9^ÏÅætv=U*¤Øímvä\ŒP» ÿj¦_ü)Àòù“‚ZÎÉ°1MÑ›¹Ÿ‚wÁ$ú½Éõá\t"݇ oš‰—áÕyYšsdr#IŽtGV«
-¨”Mɳug§:ån]d¹wé3PúH‘N1_¯OŽÒ®B$zÇ.ˆÄÒüÚ©˜ÇË\Ì×ÀšÃpm ¼m,z_ü»e B‡«)Ъ% F"1,^Zdèå!Qv½g7¦“˜k¿„SÛE¹Ýôˆ_óuìàu¯Ðב“Îìl —àJ¨¬7=¥2>‰3“êâR“ŠP¹×¤
-ˆ…xSÖõGͨ˜
-¹ã´¸Ô‘ÊúZù8ÇŒ \,Ì‘È®–“O@vZ¤åä}éý–Su“­ÆÖWŠ}|2ÐÔ#y¡¾;wºQÑðÃþ¤¬´®µ¾Š´äÌ¡ž ^jÒ"¿.w›1ì\ã5å#ëù€Wc(&‹ÍWBe= ƒpŒ‹ÉaíÍ+rÂF¨@éÐ’ºð^u·]/n”óªÖk>à–q59 ½YLv@„Ê:öÂk¶à³’KÁ‚P)=fÇm”ç‚õ¬ïÕŸä Ü{€i³A¦ aT ("­f~âï|˜mÙO ëñ–0©(®Á4RÙ S'üÇ0­
-f©`{s–œÐ*ÔPK0äôˆûsŸK¡)êð2oüw¼µñ“á?ê¦ { »º(eïÎð{]’6cv0Ç•W!­(¸{sÌ¢ TT²ˆècvÜ•‘]íÛU”ò¬Ç—Àk*øÞôª(÷Hå
+xÚÕ[Én#7½û+ôæU\ÀeYrö-È59åÿ¯)®M[š¦Æ3Au·ØÅÇÚ©‘§¿OòôÛ“&^Ñ¿¿=?Ÿ¾]M8i¼B8}þõ¤h<©“7¼99«„´êôùÏé)­‘}¾½þùùû“ÜÁä
+%`
+倣€e*T©X7IrñìyM¼ì-jγZ¤ä6Ñ-­ìOïJu±X£…-–n»å?NFç¦'"ÞÖÌjDy@ Ea ã`
+S]ä’ ä}s‹ð‘ɇóÙ°K õoEÙÏù/‘I¹M·­{&ed1§¿«Ï-ìlïùñÍ2!`>ÐÏ™Êf1”u'h¼ Ý¤3kùC¹åûd,ÝOÐuŠ·wð+œ¡qdÞO„é5ÂF”´Ôæ æ ³e¯—}?ó "»•þAgl¬aRk\£gD9ªO1À¶ŒþG:eŒÀÉÓ¡¤ìÜ·«2§@/ÕýK.ıèUÕœ¬#áñZé볶ê¥ä°Q„ç‚ìô²¢ðATqlîÀ÷HÆ.ZÖ¢¢e:ƒƒ¿»6ÐV€1\õÎW”#y}šÃÄ+ø—ùØ»«F„1joÕ‹¶yoeHuƒÂÀgiÊ [v‘
+4ÿúìÓz0…˲6ÈŸi'ävò˜¸ëK±–u¡1ÑŒ­>‰RcÖ3¦WŠTÑ4óÕ¶›ÑfD_ç=÷’ä0ö¥oÉ]ãu4«œÇÖ7’×’y]ò·1¨SÖùÆ×ç2U{TŠr÷¶-³(xš:.§@—%ç^H}_cئã¶|¢Œ—­orSE$
+}$ç«UÄ)š…O5Á€~)uG[$%¡u?Òb]b·ì‰­‹Žã^ú]¨æ.µZív´bÉúV×lh ÙÓ"HË–xvÚu‹Ò ¢â/~1£Ê"¹Ïgq°Í€Qƒ.24ºK¢kUkúŽÛ(E}»3Ì˓η7ˆ¦òý’A%CÆé¸q&ä>gÎè›ë¨c* ©°ñu\-s’ã¶uìd_ó¾štï¯÷”!+‘&ÐúgY—2’¬ ù,ÍG Vy;¶®õ›êw’¾äò˜$ñr6Aì =d`ñÏ-•_#ÆÏ©¾†¢ºfnvkZühu¶ž¼jKQ§îh££$b eì$ü§Y~õ¦
+c§ý=z⪠=â(Õ k ɇÌs9ˆÅSÆMv?Põ‚‘ÂIÃq40×EŒ(IK݇R}z}Gmõ8ÿÈ‚
+ E@Å)Yl¼2”õp®”¦6íÌѬ¢¤k jw–Õ„·*»ýZq/œôœ×@µ^ï)‰qZôÛ’ûa(ëÜ P£¹G“)FÌSfÜYF½¯LÏÚÞ|I À½õOÇ :ÿr!î‚©ÁDå½ìCOú^³-ûh¯(š‰$¿DÒr”$§HZým·¤Ðe' 4K™ÜRðf7”4Å{ÒR×2‹îZ||>ý fò)ê
endstream
endobj
-1312 0 obj
-<< /Type /Page /Contents 1313 0 R /Resources 1311 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1177 0 R >>
+1311 0 obj
+<< /Type /Page /Contents 1312 0 R /Resources 1310 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1177 0 R >>
+endobj
+1313 0 obj
+<< /D [ 1311 0 R /XYZ 78.37 808.885 null ] >>
endobj
1314 0 obj
-<< /D [ 1312 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 768.829 null ] >>
endobj
1315 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 768.829 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 757.87 null ] >>
endobj
1316 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 757.87 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 746.912 null ] >>
endobj
1317 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 746.912 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 735.953 null ] >>
endobj
1318 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 720.304 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 724.994 null ] >>
endobj
1319 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 709.345 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 699.787 null ] >>
endobj
1320 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 698.386 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 688.828 null ] >>
endobj
1321 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 687.427 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 677.87 null ] >>
endobj
1322 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 676.468 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 666.911 null ] >>
endobj
1323 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 665.509 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 655.952 null ] >>
endobj
1324 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 591.08 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 644.993 null ] >>
endobj
1325 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 580.121 null ] >>
-endobj
-221 0 obj
-<< /D [ 1312 0 R /XYZ 79.37 556.447 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 617.933 null ] >>
endobj
1326 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 502.884 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 606.974 null ] >>
endobj
1327 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 487.373 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 596.016 null ] >>
endobj
1328 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 476.415 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 585.057 null ] >>
endobj
1329 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 465.456 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 574.098 null ] >>
endobj
1330 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 454.497 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 563.139 null ] >>
endobj
1331 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 443.538 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 488.259 null ] >>
endobj
1332 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 428.027 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 477.3 null ] >>
+endobj
+221 0 obj
+<< /D [ 1311 0 R /XYZ 79.37 453.248 null ] >>
endobj
1333 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 417.068 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 399.385 null ] >>
endobj
1334 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 406.109 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 383.724 null ] >>
endobj
1335 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 395.15 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 372.765 null ] >>
endobj
1336 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 384.191 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 361.806 null ] >>
endobj
1337 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 373.232 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 350.847 null ] >>
endobj
1338 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 362.273 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 339.888 null ] >>
endobj
1339 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 351.314 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 324.227 null ] >>
endobj
1340 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 340.355 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 313.268 null ] >>
endobj
1341 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 329.397 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 302.309 null ] >>
endobj
1342 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 318.438 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 291.35 null ] >>
endobj
1343 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 307.479 null ] >>
-endobj
-225 0 obj
-<< /D [ 1312 0 R /XYZ 79.37 269.547 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 280.391 null ] >>
endobj
1344 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 248.705 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 269.432 null ] >>
endobj
1345 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 237.746 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 258.473 null ] >>
endobj
1346 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 226.787 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 247.514 null ] >>
endobj
1347 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 215.828 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 236.555 null ] >>
endobj
1348 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 204.869 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 225.596 null ] >>
endobj
1349 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 193.91 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 214.638 null ] >>
endobj
1350 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 182.951 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 203.679 null ] >>
+endobj
+225 0 obj
+<< /D [ 1311 0 R /XYZ 79.37 165.23 null ] >>
endobj
1351 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 171.992 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 144.388 null ] >>
endobj
1352 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 161.033 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 133.429 null ] >>
endobj
1353 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 150.074 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 122.47 null ] >>
endobj
1354 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 139.116 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 111.511 null ] >>
endobj
1355 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 128.157 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 100.552 null ] >>
endobj
1356 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 117.198 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 89.593 null ] >>
endobj
1357 0 obj
-<< /D [ 1312 0 R /XYZ 79.822 106.239 null ] >>
+<< /D [ 1311 0 R /XYZ 79.822 78.635 null ] >>
endobj
-1311 0 obj
+1310 0 obj
<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
1360 0 obj
-<< /Filter /FlateDecode /Length 2181 >>
+<< /Filter /FlateDecode /Length 2338 >>
stream
-xÚå[Ënë6Ýç+ü——œáÄv|®³+ºmWýÿmù‘ɱh'EÐ.reËÒÑðp‡C]yøë ¿ž¤0éSü÷×ÓñýéçÅ„ƒÁ+„ÃûŸO*^$êà
-%󃸋%@ ì´„ÒÈÍÐoûÌPV8ã8Jb31¥}a
-unÎå|fR†ÓoXY¦¹qºŸ—tEº£ŸŸž{ší§^¨8²nð:M~Ø7x°B9à(wÌrÀp3 ì30Þr”ìї±® ¦¸IqÐs=Æ
-!ºîÓ$Q6Ò­ˆzrZ†r‡^Ç ¸¦òC©fü¼
-Âsq¤„Jõ']™°úkrî[ðÐÕZ"é 9M³× RqÑåºsËrzæb¾’a•nÐÏTf’sÇ©Ucx+cËÕw`¢fŸ×kŒo‡_m°2:¦]ÃÀúÌô=WØ»½åž³œÆä«p½Ì\4Œ(Œ߆Eâ' ?Ó}†¹Ü—E£*ÅN û:}ñž8“h¾¤²T>ù7lËŽYÅ—ªb 2l²°`¥˜WpŒýŒìh|°ªèsªsÄøj×^ÏÑGîz#ÎÇ£Z…ûœÐd(ë!`ÍGÚV—ª´ÐðqlÚ#çç±Dcu@RñÉ1ô5•¾åÞ¤sÒ¹>g×”Ã4ìDK™kfOöe¤°QÒg'ÆB¤v51;¥7ùêòÕÎú‰ì˜‹ï`Ó(¾­§tÒñûµ<¹ùˆ2¯å#)Br3öjùºžb(‹
--³¬¡MfÆÐw¶ª=e®«=£@˜èèdY/é°—Qy™âÓçðÏM—¤CWg{Î<%ѯ }K¢b©jþe‘|—+HF.w'_¤Y÷ÔhWý¦NÕBYŽÙz¨Â©é«äËgÒ4[Ù¥T{Åf¾Xƒþºfë 5 —j•­ ýÒ¥ŠTó§—×F*alX9ÕëœS(É©hõ¿džã˜•¡ö¶†¢«Ö‡K/™p©1©û‡©ƒ]£«ŽrïB¨Žrá®~áNúÊt…TŸ†$=ÌcK‰¤ô=ihº/ã_Æô=¿°Ð1b­Y3áç˜Q£Â¸-*H¯ä`eñA
-¬6¬ªÐÞu
-Ù˜[ma8}ÆjU+>xNÖ¤~f(ÿYTIàò¥$I'iR­3¾i³µY0nÌ,Wv}pê
-ººÃPvvðfMuRĉZ™ê§6MÊíö¡Á®T7ºÜ²Ô.|äZ·àVëq,7·×þ¶E]nÿwmGÞ‘ *OÏÊvZÖzœ„’¸òY37#J×É×ÌÓ^(­Wæé¹Qî0PÞ¬uNõ0j&7 ¥’]ªêÚëmÆ­mNZQDÒ¹±ø·"2>yšÈ,ÀJìÕA4/#Ê(õ©]@‘´ì•×óF·èëµmk>´†}þ;m÷3î1 šë½=0¯ÛújGYÝ×Vu6UäPžõXËÅÇm%T*Înµ•tél´•ÜF[)ê²eñåGî À
-©ñ¥ÇÆW$jU†]KÒÚJ¹?V/á¸ÊÒjº[8D-—­cú½‰D:³ôð4lôðL m“uúµt]íÓe³™½£¦`yH§r©›¼´dYmiæ;G’-6ÁÔÈ$Wh¼f–uÕËnx¶¹Ü/‰Ú\Ó·f×»x€qvûÆ¥¶íéKK9®7b_)-ŒôskjµÜj¦ÖóÔK”›Ûwe
-±õÑé×îÅ€¼~Ÿ®Kଈ«§¾.Õð©K e^ƒƒ5BÍ͘|%Š¡ì× ·´Â–Ãl¾*í $F¯ áÇô-t°œ°ÉקÊ7Ö·¯œÕ³„kÝŠð¹µ*C¹Ã aœçfLî>0”¯YÜ(aUX™:·=ÀP>Úí›1ó[¢1Ö…]ÔÜ=#ÈüôªG­`eÅÔû, ä;¼#°ûŠÕœ¼?fãÚ1úЪ¸M¾
-ÃPæ‹›rZ¸°*n“=p†òõï(‹Âã°†·¯Ó}l†²ó3 ï7s²ƒÌP¾ß®³ÒJåù0'{À 忺« PŠ`Š¬¹7ÊmWAäMʈá;ì&(„Ôj5(?%ÑÊ|º^ÈñÅ´ì{fj)3‚|ÍnB\’ªñÕµl¨žZBŒ ÷í%üŸöâJY/ÞeŹÿö2€ÜØ=¸Úš ¬±³\[ `{ƒçíýéƒEgN
+xÚÍ[Ën#»Ýû+ôÃ!«Š –l] kï‚l“Uþ¾Å–Ü”ÆÁ]xd·ºO‹ÅÃCŽ<ýç$O½H¡Ãoþß¿^Î_/¿¯z;‘ØœB8}ýûEù›äIœàôÉ%¤Q§¯ÿžþù*¥ÑR"úOzû××?^dÆü}utrb3]¢4 R†£
+œ@bû¿iè>Os““š*{9‡sþ†jáä›6¯åjz)Â]È’nŠý\úûnÃÉmÂÚ©åz}Hh-l|Hà±j½Y±ã ±ôfõQ
+uL‰üwœ2e›. ­õ÷k+è± OE½”…9]ZyÐ;¥.Ëü 7U tkc
+œ8]“ÿ …QàZ³öÖ¨]3ësšfªÂá²)`ߦÏ?㫱4_ÃO¿ÃGþ܉-&f–^*K­jé„gLÂ
+clÂÑæOTGrþ;âý°¦9GŒŸNí¹î¥ëŒX ßM”¬éL†27s="“SêÜãq„BK¯¢=b}§hÌ X4üGZ#íkô½ô.:§*¥ŽWSຊ*;æÊâ‹HÛΔ¾Ú1Ú eôT3ôR®Ž ?¬ý»µø6É
+“,:ªåKš(ëZžÐ IÕòy=ÅPª
+ÝldWR͘ùb Fÿí¶…×•ÉýÚ•
+xÄ
+e­×^2acÊf¡™Î­oæÑ•PiæˆÂ®~é^–î¦ÒÑç†qÊ<·RQ¬Ý8MCS~:‹«¼gyiV ½mœŠE»Ÿ¡<G…¶{TŇ+›Ÿ¤À041ð¾ÆÀ
+q
+cMõ0”b†4(J¥ ºö¶Í¸·ÍYV@ý9°yòo“ÈøæeB
endstream
endobj
1359 0 obj
@@ -4468,2611 +4463,2607 @@ endobj
<< /D [ 1359 0 R /XYZ 79.822 703.076 null ] >>
endobj
1369 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 692.117 null ] >>
-endobj
-229 0 obj
-<< /D [ 1359 0 R /XYZ 79.37 668.66 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 663.598 null ] >>
endobj
1370 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 635.863 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 652.639 null ] >>
endobj
1371 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 624.904 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 641.68 null ] >>
endobj
1372 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 597.009 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 630.721 null ] >>
endobj
1373 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 586.05 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 619.762 null ] >>
endobj
1374 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 570.11 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 608.803 null ] >>
endobj
1375 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 559.151 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 597.844 null ] >>
endobj
1376 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 548.192 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 586.885 null ] >>
+endobj
+229 0 obj
+<< /D [ 1359 0 R /XYZ 79.37 563.739 null ] >>
endobj
1377 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 537.233 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 531.19 null ] >>
endobj
1378 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 509.337 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 520.231 null ] >>
endobj
1379 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 498.379 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 492.708 null ] >>
endobj
1380 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 487.42 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 481.749 null ] >>
endobj
1381 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 476.461 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 465.933 null ] >>
endobj
1382 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 465.502 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 454.974 null ] >>
endobj
1383 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 454.543 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 444.015 null ] >>
endobj
1384 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 443.584 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 433.056 null ] >>
endobj
1385 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 432.625 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 405.285 null ] >>
endobj
1386 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 421.666 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 394.326 null ] >>
endobj
1387 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 410.707 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 383.367 null ] >>
endobj
1388 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 399.748 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 372.408 null ] >>
endobj
1389 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 388.789 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 361.449 null ] >>
endobj
1390 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 377.831 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 350.491 null ] >>
endobj
1391 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 366.872 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 339.532 null ] >>
endobj
1392 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 355.913 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 328.573 null ] >>
endobj
1393 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 344.954 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 317.614 null ] >>
endobj
1394 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 333.995 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 306.655 null ] >>
endobj
1395 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 284.182 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 295.696 null ] >>
endobj
1396 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 273.223 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 284.737 null ] >>
endobj
1397 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 262.264 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 273.778 null ] >>
endobj
1398 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 251.305 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 262.819 null ] >>
endobj
1399 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 240.346 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 251.86 null ] >>
endobj
1400 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 229.387 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 240.901 null ] >>
endobj
1401 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 218.428 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 229.943 null ] >>
endobj
1402 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 204.481 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 180.191 null ] >>
endobj
1403 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 193.522 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 169.233 null ] >>
endobj
1404 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 182.563 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 158.274 null ] >>
endobj
1405 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 171.604 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 147.315 null ] >>
endobj
1406 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 160.645 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 136.356 null ] >>
endobj
1407 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 149.686 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 125.397 null ] >>
endobj
1408 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 138.727 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 114.438 null ] >>
endobj
1409 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 127.768 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 100.552 null ] >>
endobj
1410 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 116.809 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 89.593 null ] >>
endobj
1411 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 105.851 null ] >>
-endobj
-1412 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 94.892 null ] >>
-endobj
-1413 0 obj
-<< /D [ 1359 0 R /XYZ 79.822 83.933 null ] >>
+<< /D [ 1359 0 R /XYZ 79.822 78.635 null ] >>
endobj
1358 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-1416 0 obj
-<< /Filter /FlateDecode /Length 1939 >>
+1414 0 obj
+<< /Filter /FlateDecode /Length 1936 >>
stream
-xÚíZÉn#7½û+ôC“U¬" ,K gß‚\“Sþÿ®Ý\dMSÍ–9´Õ ùX{Y–»vr÷ùI
-
-wþïç§ãÛÓó…ÜN gÂîíï'åÉÚY`igX Éj÷öïîϽ”¬ýõ"¥>þzûãIfÌç‹Õ;+3ÚD e G“fW”|‰ ’BI¨É@'¥qÛÈP, ™<
- ”¤Ò¥­G>û_ðèÆ{õ÷þb{øD@yF*]ážÃŒKB1°¾#?^y8úïÞŹͪÓÂ@'”Æ^s:iQ€k&Y&‚1ntf*¿§,ˆ†¹szïÃÅwÊ×ë‚Þ¬qQ‘å­F½\ùZ©‚=÷ú¸Š{ygÇy´Ü±I.­ù—_¦•V(/éN|œ³Ìe#s³¤*#
-P"šåÉSb8ÑW¢}ä=~MJÈâƒ,š }rq!>XÈQs6ZRŽ­‘¡ãW£°´3Å>‚æ,]©5_:×7Å8`úM!{—âýȃ\ðyŒøAB{•eýx"…A†‰Éì‹F_óE­pªWœVï±àŸ/=áQ™^+AÒ•5ˆ:æ’—eïø”Wr‹±_^íÛ‹
-ÖÎkl‡˳ãZ4é,ÍR`‘®²ŽË>s¬î/k ýêT×uù¿6f[ª—2C_ÖújB&Ê rjH¸4•Á:_Í’!­`ŠgÖSy¿C¹•÷Cy[ªÇræó?y«`3TVˆSdw(½Q-ÉÔ}m£º&„hƶ*
-f,§7Hd=»jð¿­û´"¬åÛ «®($CžÍ¶¢´Ó»Èå– o:æ®ά²dÙ°œ¯m~®bœ×íY*F“ƒ†g¬¶k\”é %I6‹®Ú-µ ßڧݣÖÂ8ÓkdëV¶h¤Eùù&Âò• h…5¹ÕìPÞ=Éæcl®%Î¥vmwöqw4’Hƒ°Æ ¬¼Lat(ïÎ@µƒˆÁ׃ÌRhTÑú=ïúØ ¡òOÏýÖmá¾yóøæAz¦ÔÀ½ã¾E™¯Š<ñBÊA [‹3$á³eÏÎ\uxÓ…ž ž<ÚdL;'dw<h·—{š<CªG™—¯¶VHKƒš7–o¤…VÜ£,;­R*ç%’ŒqºN×ÆoW=©[‹'Uõ()Òë%§ø »o]‰lr±²é[ŒÅ–ž´¥ó#2~Æ=U8¼b¶î´e˜¿ue:ÃÆñùM³wmnŠ¦íåYQC‹²ª!ïáüßGù_i{ò¶Ö*ůZ”;ÈÐZ€v=[«€>;”;È@0R1—À[;b €@T=[iŽáÊÕh``ÌÎÙZ‹r‡|¥ôQ-Ó\ oQÃÑ:¡I¤ê©àÑ¡ÜÃÿOqÚñ`¬8'úåëÅmd#‡´²5»g_êPî ƒXiÓ‡ÞžÝrÄìPî ÃóÃÊõdLî¸;”Ÿµ“Ž¨EÛaŒ×\*mA~÷Ñïë£# 0R º˜kNw(IΨ@ =©8wŒØ¡<®ŽR cq ×Nu!:”M}t0ZØê#êF:È™Fz}³‘ªn¤Ç'.(ǵašòô2¢tš—§–>ª\ØȵM–zâe^É帼‰‡.§ÜLØ2Ó ¥F(_bÛ.Þ-EWue“œònp1Ys[€+ÿ®¦íVCÑì …t—/+Åú´4R; 3·Vðk ²Ô…êÒ¦Mpi€Êª¡pÊ#O÷´”hÏ‘SžŸi?¶ß·ýXÅ1Ïë£×µ%A+!ÕjõT@èPæ7ÞI„§~ˆKsý½åñmIPNH7„ÓÉN[‡ò«¶%AZ¡°íáâtÇ­CùÕÚ’ÊÇe¨ÒdIÞ¡ünK~D#–(Ókd²ÓÖ¡üªmIotÈš«Ü;”oçãu^¿âß³Â`-À¹^“­½¥Ýëé,–è=çkec½gÜbK7í!'Su©ÿ35=×»Ô²a/ÿ&: ÎÛ¡SÇÖmK1«äû4»•V Bs6Ñ¢ü<Ín…Jh€}=Ç~‹òó´»H¡;Æ9ö[”ùj[I'Hî´µlÍ­’åGh•8+H7Å“>o¯0óén 2/]k¢x:"¶Vp¹OÒ‚<¦MbX0؞Э…M>ªoA~7ºo…Áº`­÷ÕÿŸßžþùLŸ
+xÚí[É’Û6½ÏWèº[•JU£‘䪜ç–Ê59åÿ¯ÁÖ$LÈ–íŒ} I‘àcï z,wÿìäîó“:^…??ßž>]´ß‘ðN!ìÞþ~Ra‘Ü©ÓœÞY£„4j÷öïîϽ”†Âñχ¿Þþx’óÓÅÑÎ o ºD)#¬¶=
+DŸ´RªW)釓ҚŒ^Qú%2µJBO&â™-J$3’fN™T­2™éžÏäBø—HrxNù#§¼6¾éÞáYƒ¨H|¥ašMôBölÒyŽÍ%²Ù0lsÎçÈBÒÐ9³¸K¬$¶—ëÀD ¾æµtb²ÊGDÌo ëú”ïGóï„øº ˜åÊN œPA•°0lýœ°Z”ï',¶¢øÆ…¤¬
+©EaÿŽ$÷Bbæ-ÕŒ/+}qv=¾ç¦“F€1=cæ¸10BYèQ`:0¯J;ñ² ÔB;Ó£,;­RŠfÎB–1NãH ùžTÜè/¤E ¦GYm3Y;T‘4˜ÐX˜«¡hŽsk×Þg¿H ä” %^cå¥ÉCeÁ­#ºY}-ÒcŠÇ2fÿþâƒÇBgŒü_áÆ¢ÀQênNê È*tº$_¾Ÿ8‚P 櫧¼¨C¹ƒ ­YȘ«B:”p1A2„bhQÁ±*áHeܵHU‡êd¶—ÕÿøG1`S„5®_…e
+‹Á9´(U)Œu<[*L•ûšV¿ƒÊϒϸ|@ñŸt\ËUTp)'¯&Ú¯ýrå鶤1¼§—+3°ÏßÇræ°<¡ ðBë¡È˜¬È:”ÇdD£œÐ¾MõnºêP"©)êrÍs*5PWÁ„je–\i…AÓ“»µ2 o#ARBϧ‹Ò;ÞCõ[Ö ´;m«n ÉŽËúÃ3"îstàˆ­`÷Ù÷×ôÀ«á¸¶T%¸Ä´/imAçLn<?W¯|•Z®¦ä—¿SÚá™ÈDÜs¡ÕeGÉwÏàö5³õ'W’-Ô½¯µ±¾}ý3ñÍÀTš<T_„=gæ²V]p;]nVZ«JéÓ)U“p¸ºØ±|õ’φ#•)ªp5"¢]~aîóR-á*„Ÿf%ñAM”¾öéCæà @&͹dI%¸rÌ5 ;B{Ëö5çô5‘ºQséÓ¹Þaãä:*žsÌ^ÀåA›ýÉÍ©~¿•Çˆ%ÔÖhŒ›+¨,ë(ÃÌdqFKל‘È
+¯zÅ‘z…ðûÒž”¹Áã „³‹ÇDz®a.{YÑ)ïX$“qìSø®ðjß^˜]køÂ\ÈÒqq±l¦þ}´%ð–¡.Ñ‹Í[S‚ª(7Én'õF%<ôÑzc»åƒ¦Áu}«Í/WX߮վÖZäò¥«£ge2𪡼L¥°e¾ ,…&aÐ Î%þåV⿶Ï3_
+¥? dÌíÌw(?Ãä#
+‹'ƒ¡AU=JŽô´ä”a÷Û¦Æñϯ5 Ac…F;¨æÔТ¬jXg!æ>ò´ÚºÁ qʯ:”;È@F ÉckPÂg‡rH¢¯Æc2· wÄ@a¥ê©ØšHK ïP~†Ž
+„%èÛš#ÙÖZ”;ä+•°2^æbx‹ò˜^
+Ô“º5ë•àÑ¡ÜÃ¥¸ Ö gô z7'úåÛÅm0á«rU[³{ñ¥å2´žÜ@MEÌå2È„g~PÖ\ÇÝ¡ü_Gé€FÈ!¼M¦Òä÷ ý¾A:@ð3Ûî•ãôtºCyLrEB)èIü›¹åqƒt(”ƞܭµD™Bt(›éÊU XÒAÎ ÒÓꛃtPõ =ý2ŒRýiqÎÓË
+ž4/¿ZútåÂV®c²<ç÷8—ãr'mºœÊh0cËB/pÀOÒØ.]-ƒE_Me³œJ7¸‡¬9N#À•_Óvk h÷La#ÝåÉJ1–Aj§aCü’Ö$×L5is \ ²(œÊÊÓ=ãÇ`ši°ñ—™ñc‹ñcÇuQœòܱÞzýº±¤"è†P»µT.¡C™o.*A0„ÑÉù^‡òø±¤)ÈŒátnÒÖ¡|Ô±¤’^h9úåÜÄ­CùhcIï„&=øÁ\EÞ‚üJ~…>œMÛB>&Çl-ÈGI†Ï@ÓÓÒyþ¿Ø4 ßÏ»ëŒ~ųoÕ·àAmv$…_7s«??¿=ýý:D5
endstream
endobj
+1413 0 obj
+<< /Type /Page /Contents 1414 0 R /Resources 1412 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1177 0 R >>
+endobj
1415 0 obj
-<< /Type /Page /Contents 1416 0 R /Resources 1414 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1177 0 R >>
+<< /D [ 1413 0 R /XYZ 78.37 808.885 null ] >>
+endobj
+1416 0 obj
+<< /D [ 1413 0 R /XYZ 79.822 768.829 null ] >>
endobj
1417 0 obj
-<< /D [ 1415 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 757.87 null ] >>
endobj
1418 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 768.829 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 746.912 null ] >>
endobj
1419 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 757.87 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 735.953 null ] >>
endobj
1420 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 746.912 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 724.994 null ] >>
endobj
1421 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 735.953 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 714.035 null ] >>
endobj
1422 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 724.994 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 703.076 null ] >>
endobj
1423 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 714.035 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 692.117 null ] >>
endobj
1424 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 638.319 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 681.158 null ] >>
endobj
1425 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 627.36 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 670.199 null ] >>
endobj
1426 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 616.401 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 659.24 null ] >>
endobj
1427 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 605.442 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 648.281 null ] >>
endobj
1428 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 594.483 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 637.322 null ] >>
endobj
1429 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 583.524 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 626.364 null ] >>
endobj
1430 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 572.565 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 615.405 null ] >>
endobj
1431 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 561.606 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 539.689 null ] >>
endobj
1432 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 550.648 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 528.73 null ] >>
endobj
1433 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 539.689 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 517.771 null ] >>
endobj
1434 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 528.73 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 506.812 null ] >>
endobj
1435 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 517.771 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 495.853 null ] >>
endobj
1436 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 506.812 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 484.894 null ] >>
endobj
1437 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 495.853 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 473.935 null ] >>
endobj
1438 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 484.894 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 462.976 null ] >>
endobj
1439 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 473.935 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 452.017 null ] >>
endobj
1440 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 462.976 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 441.058 null ] >>
endobj
1441 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 452.017 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 430.1 null ] >>
endobj
1442 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 441.058 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 419.141 null ] >>
endobj
1443 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 430.1 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 408.182 null ] >>
endobj
1444 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 419.141 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 397.223 null ] >>
endobj
1445 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 408.182 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 386.264 null ] >>
endobj
1446 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 397.223 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 375.305 null ] >>
endobj
1447 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 386.264 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 364.346 null ] >>
endobj
1448 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 375.305 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 353.387 null ] >>
endobj
1449 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 364.346 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 342.428 null ] >>
endobj
1450 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 353.387 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 331.469 null ] >>
endobj
1451 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 342.428 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 320.511 null ] >>
endobj
1452 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 331.469 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 309.552 null ] >>
endobj
1453 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 320.511 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 298.593 null ] >>
endobj
1454 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 309.552 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 287.634 null ] >>
endobj
1455 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 259.738 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 276.675 null ] >>
endobj
1456 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 248.78 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 265.716 null ] >>
endobj
1457 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 237.821 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 254.757 null ] >>
endobj
1458 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 226.862 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 243.798 null ] >>
endobj
1459 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 215.903 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 232.839 null ] >>
endobj
1460 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 204.944 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 221.88 null ] >>
endobj
1461 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 193.985 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 210.921 null ] >>
endobj
1462 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 183.026 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 161.108 null ] >>
endobj
1463 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 172.067 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 150.149 null ] >>
endobj
1464 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 161.108 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 139.19 null ] >>
endobj
1465 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 150.149 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 128.232 null ] >>
endobj
1466 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 139.19 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 117.273 null ] >>
endobj
1467 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 128.232 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 106.314 null ] >>
endobj
1468 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 117.273 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 95.355 null ] >>
endobj
1469 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 106.314 null ] >>
-endobj
-1470 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 95.355 null ] >>
+<< /D [ 1413 0 R /XYZ 79.822 84.396 null ] >>
endobj
-1471 0 obj
-<< /D [ 1415 0 R /XYZ 79.822 84.396 null ] >>
-endobj
-1414 0 obj
+1412 0 obj
<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-1474 0 obj
-<< /Filter /FlateDecode /Length 2726 >>
+1472 0 obj
+<< /Filter /FlateDecode /Length 2763 >>
stream
-xÚÍ[Mo$-¾çWô H­Hééä•ö<·Õ^wOûÿ¯/_.ÀTWŠžÌj=“T(c<¶iyùÏE^þz‘¦Ÿâ¿½Ü~½üø´ábDðJÃå׿_T\$/êâ­
-)§ò:eôĆ?Ç P8•'Ø
-D*"%ÿOÔ êÊ3øŸÇ3É’l]½­LoÝ¢Ågêg÷Ì/ &Q
-9•Mc÷¦%¶*ꊎ5,³êÐ&Ð&ZGb!}–£ÒÂG:RǺ–#MÌf¦£ VWAd3kãçc4Bc|? ïËûéw}kŠI?gëF˜ÞK{dº÷Ž–uÄOZ ·F“¿o í•ùÄôÙ z9 ÓBOš·°¦ùÈ÷ÅmDF+ÎÞ–<‰Qy‚ «„q0±ñ¾0•'Ø0q™Òœ³YL¡pÖq*ÉÆA[ÌöXí=Ù™v-h¢ß š Êg µŸ-Ð3
-¨@Qÿ6 ÂZ3)c-—2*€½ÉÝÃäÊÎT¡êskšûCçîÙu}ù@uãüù¹QöÉto9Ü57æ+Á¾ïüõ\þšÞ³ÛOWÚPö×õ²ë…ÃP^Ø`'±k–9Rù3É¥¨qbÕ¬±:RI¬æà/‹9§$`«µPp‡Ïd «ìÚ€›Ìü$–ˆljœJ =?>•½„ø éßrAhw±„s~{ç£yoŸ c²L¦DO0?IßÔ\hªsÀ½îëÌÞ¾Êb<œv6cœ±kö
-ŽÁŠüH2
-6á˜Ãv1•´6þ+øz¤èãB¾ àŒ“Ü¡„ö¦‰¢ô7p×¢ø̦ìؼµ5þÚFÂ9¤ýn…BTXbš uƒîyD8TePÑ~ p_“_xŠõ ȉ »q¬AáqÊT'qxp"€çD²OÜZ.͈O;{é½O‹^´"c¬Æ‚€…ó
-yt.áÉ4r‘ó¹=í
-p¼i-*¢;9q`n º?€ˆ„CÅßÎ-¹ÈfWRãÆÌÙT|¤»Â<9IW,½­wõ±¡l_,°PØ4´Õ!H'òMc°èµå#¯­l¨þ·“^›TˆÊpUžôZãR³z:ÆÞm›¼£Ê;Þ˜Q`7˜l gÛzÕšdÖîØÒb†6Vqº²ó'3Åqõk¢`8IÆCÎdtåI
-9þ\ȉ¹XXp{;-„­b¦•ÄU-+g]¥>‰Á#R~Ê"ÒC‘¿Œ;•Ü¾mÚ»‹qG.ÛÉÀ“PžÓüåwV1“V‚ŸðõZïŽQ™êÓÚM&„䨃Ô!§á¨rKu§]: ï­‰ù1 $VÄpº¿U¼L;N-ÖUõƒZÏåÍZ?’Q9ÛÔ×øeS_vMû®¯³ÓÀßímïU”óŸ;”­Ëmȶɵ,çC{âpdL“kœm¾ÒÙ Döjˆç•Ò÷Å2Ä‚
-tðÂÀTR"W0*ßk_œþªÀÞ ƒÃ°¯g–©ìú×Âöå¹éÆúyá
-+5n±Aƨ<'ÜtjP†á¦äÜUÁ0"c¸`‹-1F…g±õZ?Wͺž˜Ô‹WR+fY 
-¥ßËì¯L.kÕœuX¤ÊæE=—l™XÛÌ]÷¢‘,%5­›™jsbzc¤ü3¸^%ùX|1݉{¤.:¶l@²BMšGÅñ°ÛqùoJàyÞÍ:M:”ÆÉLüž)I-œk—÷|W[µE—Å’´ÙNW¶+`½î©ûSÞ§S-¿ 5g¦D­ºA5½#”Ë_ô~Ö̽›ÐðV«±}—Îàîžã ~æôÁ[ŽøynzJäå)Šþ©ÚšvýÆôå½a7.%|ƒ¡û?™÷6'ÞG‡LV{%C‚œ‡°[
-­å±ö1n­Q<ÓÜéÈÐ¥ü•o´eyq{­wÀKág¤|rbUÛŒÈÑ`»[÷-N²4 tËæÌ
-ežçÎD$nídZvÍ´F*»cŸ.‡“Ú©ÉFWöž49í…8‰`–<§&fþa×èå^ôÓ»&™îjüŽù‹'Œv“)Ÿè…•'ØH£{7åÛ³iŸ‚òH剨,#Hsƒ^ø–¹ÎHåë:Á‹\€³
+xÚå[Ko#9¾çWøD-‰Ô Äãx€9ç¶ØëîiÿÿuôbI¢Ê•’»`n;ÕUŸHŠoªäå¿yùóE
+“~Åÿ|¹~½ü¸›pA¼}ùúÏ‹Š7É‹ºx#´7g•V]¾þwù×›”¥ÄO)~ÿ÷×_/²bþ¸{¼x¬߃(m…rš£hûþj´I¿Þ5âj)!}GlpRª?âïP¾ÑÇûÒ÷-}¶'7 “0t¹ß¨á7ß­Ó*2"ß bz"¯to«¥OºîUñ£ï;ˆ®H “æw¢4R(©¹(íõœ(•Î8Ž’¨¡›™÷Eˆé;±ãâ·³åZfUöÂŒÇÿ»Ì
+¡&V>Ö´bDɺPÉת|òo(d§È;d‹ißéÿ’åëõZfyÒ†ÙD¶Ì¾öBEÞûÖØQ~ ûð[ØWNhm&öýû#Š^WBi…¶vRBsŽ 0ÂxËQÒ.$iÑNØêÒµl7ɦpp_tg(®,©\v_tmY¾6ÒMŒá9ÆЈHGY—¯õ(
++gƒ{µ$†òF Cø0ú|t«“¡<A*á=p2ÎF±ZD2”‡E¤.Õ89Më÷œf_¬dë¹7W@×È¡êëX¬ü\!íV\‹±”¡ŒÍ ª¼È”V¦êuƒÍüugî}+¡¯·ñ–VÜkÖ§ÇÍ m>vþ÷\üšž3Û/ï4¡¬õ›…ÍP!ÊØL›ñ±¦™#Êï ÎF†è,'õlÖA¤Ž(‰T¨Í¥Üi¹RsK«:l}OÚ°J./$º‰Ü“¹DÌ! º†R]Ï»2—$rm±Êî‚N …-š~6ëíca ö¯Ú&U¢+6_Ik,ÄjúV×u¸·®26¦rvZG?c:Óììä&àGœi­ã¶¾BòV9®úb.… ñ—#Ci_m×,W·©Ÿ÷^&xÌ5ȸq;òÆýRî‚•œ´žmô×äë‘¢GMà‹Q²¡9áÄw(®½I¢ý]»·"xÔMû3™×vë#å9¤õ®!
+,ÍСô4Z}(Ê ¢þ PÛ}I~cJ{¡åD†Yö8ˆæHu..(ÏA²M\»Æ_mR
+ž"v¶Ò[*­h…GpB»9
+äˆÐ>¸RvDuko»¦žï½ Ì$îÜ[±5wÒ™†#  0Ñl8O³â -ˆ€ÀQòæ5žX†Ü6z+ör=0©›ÛŽtÜ¢ÒoTvl yõÖ4õé6È©è»1o­··oµE—÷{¤
+9c‹M1†Â£Øz­Ÿ«f¨;æucç;©³,†˜
+$[!Ô¸yT«—ÿFX©ùFž7ÅCµ6
+„;©‰ßS%™Ú‡íl¹ïjB4UZt\,I
+£g›3þÓçèe¬äGyBKÀ v"Ã/çg(ºž¥ möcý£¥lhËLj'Üd
+fé@2CyBÖi’àüD.íg(YÖ®ib–Ümô´¶†hçŸ9æ¯bfeT˜Tdí­2†rþ
endstream
endobj
+1471 0 obj
+<< /Type /Page /Contents 1472 0 R /Resources 1470 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1177 0 R >>
+endobj
1473 0 obj
-<< /Type /Page /Contents 1474 0 R /Resources 1472 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1177 0 R >>
+<< /D [ 1471 0 R /XYZ 78.37 808.885 null ] >>
+endobj
+1474 0 obj
+<< /D [ 1471 0 R /XYZ 79.822 768.829 null ] >>
endobj
1475 0 obj
-<< /D [ 1473 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 757.87 null ] >>
endobj
1476 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 768.829 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 746.912 null ] >>
endobj
1477 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 757.87 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 735.953 null ] >>
endobj
1478 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 746.912 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 724.994 null ] >>
endobj
1479 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 735.953 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 714.035 null ] >>
endobj
1480 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 724.994 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 703.076 null ] >>
endobj
1481 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 714.035 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 692.117 null ] >>
endobj
1482 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 703.076 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 681.158 null ] >>
endobj
1483 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 692.117 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 670.199 null ] >>
endobj
1484 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 681.158 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 659.24 null ] >>
endobj
1485 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 670.199 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 648.281 null ] >>
endobj
1486 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 659.24 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 637.322 null ] >>
endobj
1487 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 648.281 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 626.364 null ] >>
endobj
1488 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 637.322 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 615.405 null ] >>
endobj
1489 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 626.364 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 604.446 null ] >>
endobj
1490 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 615.405 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 593.487 null ] >>
endobj
1491 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 604.446 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 582.528 null ] >>
endobj
1492 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 554.633 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 571.569 null ] >>
endobj
1493 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 543.674 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 560.61 null ] >>
endobj
1494 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 532.715 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 549.651 null ] >>
endobj
1495 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 521.756 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 538.692 null ] >>
endobj
1496 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 510.797 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 527.733 null ] >>
endobj
1497 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 499.838 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 516.775 null ] >>
endobj
1498 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 488.879 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 505.816 null ] >>
endobj
1499 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 439.066 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 456.002 null ] >>
endobj
1500 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 428.107 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 445.044 null ] >>
endobj
1501 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 417.148 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 434.085 null ] >>
endobj
1502 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 406.189 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 423.126 null ] >>
endobj
1503 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 395.23 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 412.167 null ] >>
endobj
1504 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 384.271 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 401.208 null ] >>
endobj
1505 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 373.313 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 390.249 null ] >>
endobj
1506 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 362.354 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 340.436 null ] >>
endobj
1507 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 288.63 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 329.477 null ] >>
endobj
1508 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 277.671 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 318.518 null ] >>
endobj
1509 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 266.712 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 307.559 null ] >>
endobj
1510 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 255.753 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 296.6 null ] >>
endobj
1511 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 244.794 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 285.641 null ] >>
endobj
1512 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 233.836 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 274.682 null ] >>
endobj
1513 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 222.877 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 263.723 null ] >>
endobj
1514 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 211.918 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 190 null ] >>
endobj
1515 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 200.959 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 179.041 null ] >>
endobj
1516 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 190 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 168.082 null ] >>
endobj
1517 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 179.041 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 157.123 null ] >>
endobj
1518 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 168.082 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 146.164 null ] >>
endobj
1519 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 157.123 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 135.205 null ] >>
endobj
1520 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 146.164 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 124.247 null ] >>
endobj
1521 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 135.205 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 113.288 null ] >>
endobj
1522 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 124.247 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 102.329 null ] >>
endobj
1523 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 113.288 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 91.37 null ] >>
endobj
1524 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 102.329 null ] >>
-endobj
-1525 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 91.37 null ] >>
+<< /D [ 1471 0 R /XYZ 79.822 80.411 null ] >>
endobj
-1526 0 obj
-<< /D [ 1473 0 R /XYZ 79.822 80.411 null ] >>
-endobj
-1472 0 obj
+1470 0 obj
<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-1530 0 obj
-<< /Filter /FlateDecode /Length 3125 >>
+1528 0 obj
+<< /Filter /FlateDecode /Length 2723 >>
stream
-xÚí\K#¹ ¾÷¯ð­D½£q»½ÀÞ’Ìm±§ ²—ì!¹äï‡zKT•]ò<2äP3¶\¢¨O$ŇÔüôljŸ~~áL‡OøïÏ/—O/?Ý´?)æpúô/ñ“89ÍÀé“5‚q#NŸþ<ýzæ\J||x^ûôË Ï4º9urÌ#]OD(ÎÀ+J>7Îàsáܼミ%>©Ã¶‡çúúAƒÎ=”Ko‚HOøÚB/iSÏ؆ö6Û/y”kî[GMüwX<Bs&8L@¸ƒ@xf¹£TÀô¤©qbV%f-$†[P„)‡éj•§üÞS)=´c€çšh…þq!xZ”~q´š`œÆ°È“Æ14”9¼ vzé™P’Boô1è%gÎzJå 6À1cP6Ô16¸eR¥òÂ2
-mª—Ò÷­ù,¡¨p£öQœ±pÛ(†QˆDY‡ÿÕM°á+&špÞ˜]ýeì™4éõCTœBǤhåqØ@N«L*¾ìÇuŽûMÑuWºìn¸•‘ Å‘߸Že'É HdÆžû ia¬@¶˜%¸m ç´å…÷à’XP&M¤ˆsdéšÐÕnkiaJ4}/ÛeƲØÒ*…MÜ¥´ç¢1áÕÑÔß¼ C|7j¯I '& ½Ð[¼Í|Í”_ý /ö¶¾«©€²ìALÿvš*a]KÂAÜ/ŠºÜƒœ©™Â#Ûü¬eñÀ$ŽBF+Z‘ÖÆÂk÷-!ÓŠ©ÎÏ«ì¦U–Ã*ËlÚ·QÂdæ"¬þ¨ü½õ€*ù ®ŠQ’éÙgVï+®
-!B]•"R6BÌGóß/ŸoÍ= ï>ï¢l ¼-c$iâܺàE/y•„
-ú?«l £¢‰s›œøCl추ÊVœGQ­tŽ\q%ƒhŽÄ€O—œ¨aý3—Öµ=G‹Ï ZC\ö0‘Ë1pÁ0aRY_c."šŸ‰ã(kk(•G±¼){ᥠ޾îš~¦ _Ô9Œë-…ôhz¤@:R)‚X@0”ªÄDï%®ÎÆÉo A|Lub¬OÓ•]©µœˆž´•ÌšjTvÖèþST¿üRüìüí:ìa“æ8iÉC’yGwÆŸ¸è?ž Q£D¬y-¹Ë{;ç§ÖÖx} Õ˜ã“]>œvÒ 9¡THÚiC{ k™¸/¯±Ÿ‘ß[ öµ²Ì™Ï“Vôž°¤“É’oC‘È-%ß–¿ÙÞËÜ‘âMHGÙï]2@1ktkÑþÒ. ó\L;”^“ö‘Ê%hægŸìh¦/øéèá*ߪš© ’s'Sû@uÐ+ñÞ—YŠK ·¥QcLƒ-‡ä:öK9†ôvÜŒ¦Òßä1¶L69µîÛä:ÆÂUïãHtÍkMFXs?“%óBQt¨9S|W÷îƾ¸»r;aŸ"Âl“"Ç1R²(u‚íÚ%êbiM³FŽhÞ C¢¦F-U¡¶²$
-=GÞƒVmú…¾&°Áš.0Nß(O©µ_¢ÜB³.p3V™­ç¡ïf<âŠ:: ulÅ
-B$ùªýúAœ0æé*´B‰1$3>ž¨+xŽT¾S@¿v4¶»’ ´¤°MLæ€Py‚ ñ$ ac1…G¨r°•°Lj›Þóœg;Œý¾aeFxƒÁ´$ Ω]ñ*e
-C+”IÈD¦²é@äíPØy;.Ô/­ˆ_Š•é—÷¡ÿ6ÏfÛÕê<žˆ®v%˜Þ!QõÝš•L{ ØFN®ñÈϽ…AyeŠ+ÒÙ^›bçò@®™ôz¨…G ü„ߢ6(‘B´ž¾SÙ2$æ„«ò$¨e9pP+Úuø˜¶¼šc<Pઑ U}|3Ç{îh¼gУS«sû^¶F§Fo"Þø¤›ðÒÆœRË£
-f_ƹ{ÒXÔàkfrçŽÖ3
-¤#•¢`¶’òÌðÙÙ\Kƒ*÷‹>É7G<3~ÌBJnjҼj Þ‘ÊÖ%ä™Ta-B¨üOÖvµ¢°R8Y–‚t4‹Q@©ü?KÔŒ—5n
-'ºô_÷¥CϽv.•ØI?¦+D½zèÇ5‡°§ ,ÌpÞ?aÐ-zƒíûwOpÕ0õºoÎ
-QO ÜçÚ‡­™
-“¸©.“Ã1 „*˜Æ"TõªD½ÝͽÊ×.ò›j0Ž¶ûZØ0N1€j6æLe‘`›ÏY£ÒR¤÷¸µðSÏOÖ›—=J÷΂֊Éf"·¤Šz…,¹ÕõÌ©°’™ýeµtƒPEÊoµÖ´Âš&¹™üF¹äD*ëi¡ÑÂ*KÙ8šQÈHB…ÞJ¢ Ý'n%­NKq&ÝLJçhŸ%Bekáa#ÆžÒ¤]j´Ö/Žêßú¿…
-ž÷‘ ±•tþ‹çF"Áþ)ĘŽ©Ñq·¾*}2¨5OçÌ tVZß\ó! 2ÆLÝ­P?ž×íÎêJØ£MV¶£;ž_¢{ÿôò/²xö@Ÿ~ÿóå×ß°ùïøü‚‹#½;ý'¾ø'š3ÅŒÝþyúÛË_ÒŸ=A<5ó68¢ãº…s»Î1­ÄÆAB\oyÂÖr¤×‡µèÒ¢#ˆÝ-¸ù"Áìƒù\`öSy“¾=wKX=O¼Í¼pœyIh•}YncKN+ûr³(-ÝVQZúMJQºŸŠÒ2ßrÕn·(½93),³¸kØŽÁ‚šÊ”ñ¤stª•ØœH;ÅN½»;üç_G/{“!ÅÑÍ—T†?ó%Ž
+xÚí[ÉŽ#¹½×WèŠM2‚ h•ª˜›íº æ4†çâ>Øÿ¾¹&“A¦”Ì^\ øP%)•ù|ŒÆBñÓŸ'~úå‰3Þùÿ¿<]ߟ>½)wBæ¬
+h¯éU‰ô^¼øWž^%¤{åÕÿ½„g¦§
+%wJÁ™tHQÂË·¼XY™ÂÆ…tYñ“ò?R ›žSM+ “
+ªº¨ÄëzÔi"”`h$%bï–_–£Eií*èvð ³MÉ$p¢cDE˜rÙ0â”_×(s–¬6`…çãBðjUeqv4vc˜àÙ’Šä+ÐÜy@½)õ;ãàÌGQˆ!S
+©{cn¼;å€Âo¹NubìÛ°aNZ
+µïZ×;˜ ¬½kÞ‚¾nx5³  ÑãßîðZãÂh1ô)áέEŸ1l™G^VcéåšD?½ urž"©qM‘q ÌI9Á´[öpãe…·Êäk™± Ž°„ôön%EÛ²Ã`ñ˜`mಶ¤.ˆíèHiO¾<£¶çŠ ñŠ;×Ã(éÛòMX0åSÿdÒ‹4çÕîÏk@‹×zO[Þî²Þ;Z€½lâŠ~>S,¢ÏÉ„Û,ö\Ø1‹a¢QþÅಠV~E‡)Ï£§|Ó>™,éòI– U§pæà(ÝÑàf¨x³k×9î7ÅÖmydsÃ] VñøöÀËQw’ÎHð˜ózCêIØ&+À·$ßÆCËsÚòbð}M" ÎA.¯œ%Œ°µ–VflUØײ]f.‹/]´0ˆéwD
+PŒ:Ñv[–ÅRŠV
+ѽ%šBMuŒ¥m™‹C}ëgë cq³>iUz½Ð·D¶4z•§OT¦tu½Dù
+­ºÈk[±Êp~hÕ}·âWÔÒIྒྷÞhîèÓJ?¬‰J0Lôã~§†Ø¦ÆÅþU·„kKÌ5IïÖ‡‚ž·)ÕŽ•HcÿûÏSzó×àq½[ÕÌðNz][Ñ{Zäȸ\ºúó ߨΠeÜuó[‹"Vo&j ‰ªeê˜ ¬e¨ì}CHž 1˜ˆê K±ƒv#îF+i´²e†uﯱÐV¬qd¯c:×m²vj“%(?®âðuQé¨:€ÖLõ™Ã܉š$Ÿ}yçŸ,¢9Ü…’õ>6Å9>[”Jè÷ÎÆfhGdZBç&`*% (Ä
+v&HèãØM=$H1 Nínq±r«=*2Ëk$¸ÝØnËË©*·Ë[£#2£à¸r}üeß™ZBÌO-ê­ù”cYÅ_¶·±;îzÄ+ó“×ÚLmÏ3¬+ìå\î|n ­–š~™Æýª¼Ù¶ óU@i$³NR)&{;åû´Ë¾Mhw0˜¡T æ
+äg½°?Í' Ê1À0¤BìŒàò‘Î"ªÛKík„ÃÓÁ±E‡×$Iù7Ÿ««.êWz4Ôú)¶‚šù,YJ~½Ÿ ‘_ö¿3¹î{w€o¯?ˆöí ˲·(9^y}úI£G¦Œ>ýñåé·ßýõ¿û¿_½¤àìé?ñÎ/Q•µÏýóô·§¿¤ÌqR>â4Ê’I„>¸_x+Ä 1ç''¯†‡¯WšÌø­ÛçôÎÙþ`NPÞå‚ë
+6C|‚icè
endstream
endobj
-1529 0 obj
-<< /Type /Page /Contents 1530 0 R /Resources 1528 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1177 0 R /Annots 1572 0 R >>
+1527 0 obj
+<< /Type /Page /Contents 1528 0 R /Resources 1526 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1177 0 R /Annots 1573 0 R >>
endobj
-1572 0 obj
-[ 1527 0 R ]
+1573 0 obj
+[ 1525 0 R ]
endobj
-1527 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 435.916 495.557 446.343 508.286 ]/A << /S /GoTo /D (Hfootnote.36) >> >>
+1525 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 435.916 396.926 446.343 409.656 ]/A << /S /GoTo /D (Hfootnote.36) >> >>
+endobj
+1529 0 obj
+<< /D [ 1527 0 R /XYZ 78.37 808.885 null ] >>
+endobj
+1530 0 obj
+<< /D [ 1527 0 R /XYZ 79.822 768.829 null ] >>
endobj
1531 0 obj
-<< /D [ 1529 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 757.87 null ] >>
endobj
1532 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 768.829 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 746.912 null ] >>
endobj
1533 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 757.87 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 735.953 null ] >>
endobj
1534 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 746.912 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 724.994 null ] >>
endobj
1535 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 735.953 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 714.035 null ] >>
endobj
1536 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 724.994 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 703.076 null ] >>
endobj
1537 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 651.27 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 692.117 null ] >>
endobj
1538 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 640.311 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 681.158 null ] >>
endobj
1539 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 629.352 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 670.199 null ] >>
endobj
1540 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 618.393 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 659.24 null ] >>
endobj
1541 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 607.435 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 648.281 null ] >>
endobj
1542 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 596.476 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 637.322 null ] >>
endobj
1543 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 570.573 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 626.364 null ] >>
endobj
1544 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 544.67 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 552.64 null ] >>
endobj
1545 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 533.711 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 541.681 null ] >>
endobj
1546 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 483.898 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 530.722 null ] >>
endobj
1547 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 472.939 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 519.763 null ] >>
endobj
1548 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 461.98 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 508.804 null ] >>
endobj
1549 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 451.021 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 497.846 null ] >>
endobj
1550 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 440.062 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 471.943 null ] >>
endobj
1551 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 390.249 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 446.04 null ] >>
endobj
1552 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 379.29 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 435.081 null ] >>
endobj
1553 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 368.331 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 385.268 null ] >>
endobj
1554 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 357.372 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 374.309 null ] >>
endobj
1555 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 346.413 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 363.35 null ] >>
endobj
1556 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 335.454 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 352.391 null ] >>
endobj
1557 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 324.496 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 341.432 null ] >>
endobj
1558 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 313.537 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 291.619 null ] >>
endobj
1559 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 302.578 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 280.66 null ] >>
endobj
1560 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 291.619 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 269.701 null ] >>
endobj
1561 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 280.66 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 258.742 null ] >>
endobj
1562 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 269.701 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 247.783 null ] >>
endobj
1563 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 243.798 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 236.824 null ] >>
endobj
1564 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 232.839 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 225.865 null ] >>
endobj
1565 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 181.034 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 214.907 null ] >>
endobj
1566 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 170.075 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 203.948 null ] >>
endobj
1567 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 159.116 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 192.989 null ] >>
endobj
1568 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 148.157 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 182.03 null ] >>
endobj
1569 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 137.198 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 171.071 null ] >>
endobj
1570 0 obj
-<< /D [ 1529 0 R /XYZ 79.822 126.239 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 145.168 null ] >>
endobj
1571 0 obj
-<< /D [ 1529 0 R /XYZ 93.716 95.193 null ] >>
+<< /D [ 1527 0 R /XYZ 79.822 134.209 null ] >>
endobj
-1528 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F16 328 0 R /F85 428 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
+1572 0 obj
+<< /D [ 1527 0 R /XYZ 93.716 104.463 null ] >>
endobj
-1575 0 obj
-<< /Filter /FlateDecode /Length 2643 >>
+1526 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F16 328 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
+endobj
+1576 0 obj
+<< /Filter /FlateDecode /Length 2845 >>
stream
-xÚÕ[Ënc¹Ýû+ôÍ&‹Å`ðµ¬fí]m²Êÿo‡ï·®H¹{’,dYÔåa±Þ,–èåßzùã…áþ³ÿx9¾^~Þ„¹ 1šq¸|ýë…Ù‡è…]´  ÅEIF¨d—¯ÿ\þñJ)çá%ßßþùõç ˜?o/š)¹®AHÂô( Â슒GdJ…ž nÖÈ@JÀ`r› nC>¡×ÈHÉÐ"–§”RÁìûÕ¾Û1ùiÇR´Ÿáf_Ûä‚&ÌÒÒ Oì‘Û¢8rñ¤:²‰ŽT´ï\…ÿí[·ïÒ„ïÀÎaöí¶bÇí;—o?ˆ3Tþw33êÒ
- ò5<­ |‹Æ<'~Þ˜¸ËXs@ÂÕE1N¸ViÿŠ½iþêçþ@ãþƒ£¯o ^Mî[xkB ’ßÜ(ÚQTáyö‘PÂ÷5nÆr¸Çh·ûáÃæÓ£ny®2x³EûŒÏKº™Ž}Ž¥^¯A$AÓ¶,†~ûaÀ=íEØ,“X Î׉¼b…§O§5ý–tÃQùå¹!á–ùÍ1J&·Üô,Dé*<‘.e94Ú­ƒŽ /¯‡ÎyÑÉ–½Åܘ4§ZÅ'‚ +;¶
-¿›ÄV/ Ë<îõ-¯¨
-_ðHO…ïݸÝuœÑ³›kèÙt¬s›HlŽ£^
-¼×ñ Z§}†¿RÙžî•iU#Õx /ÕS£ å%Q½Uc€èPÔ5)JôZ(—JšŸÕÊjÔÊ#%¿7:“Z©Ò|®
-ÿéŸÂÃ
-ãš5z§…Ò;³jX¤¦FÊ~ß^Ü#¶^<³Ú©¤ÀbÉÙ£ç,Ûœ°;á
-F””µlm:G‡£¨:dr&d„ÌK«=‰›—>Z{{ø,Áj1'(=Ó'Núµ_¨uf³Èþ„“²Ç MÕpJà{NªEqNªNH²$Ž ®•¿®g¯z&Ž­¬ÒV!:™™“›:³¢¼¦Á¸¤læìžrH;,C4šžåø¹Çòe—åÉR}¨ŽJ¹h“LÝì¶ÙÛIQ6ž(U\Zr+jû ,©"†³žJ{T¶(žß·’‚xžê’‚ødÇ‘ÞœíR
-™b‹¤Þ·âBT³Ù$a<ŸmƒbÇÌIòzâdä[ö'‘÷ÒLÆÝ ïWSPR¢ Gç £”„Ù¯:”}ÿ$læÉ”è…'-áu(^Ǫ<¯/ ¤ì´öA˜ÓRÀä–E‘L®ea/”l3G1LÌY,xÙ,I[îP‚³Ã¼¹·ìõ<ßä°žoNô(Îà˜ç^ï3ö1Ýü‰ ßvÓ6;% TÏÜÕ2^bn‹²_Æh=±XƳçwÀeå-|‡T® ÇA+xÖDmV×bü~}zÒP#²|è¶õu—ç ×Cp[=d&-mQž ƒI‚
-£[íP’Â:5Ǩ°ÍÆIî6ST~ì)jXíïWuT@„–= WS³àï;Mö·iy9g–‹œyððÕŠ_’T dD‚xö¾Å³ä åÔâ螊ÕÔÆ
-[Œ'ÄÉQ"ö’¤e©Í3UóÔ™=UÔ›2$b¹HÙ?MsmMvð>›YZ â !<•JÞuÜÛKÈ|³ª '›HŽá^ÚwvÕÙR·Í2i˜±žg› ]‡ÒWëøQ¤Z_‘²¤«%ñâcw·(œy5æ!`;%ëPv¶ø ·‚ÎFy¿•Õ´.m¥E)éw(ÿ†ô{óNŠs Æ”l)Õò%ôÖ/ûknàGó ä™ýu¸äS<WTk@°‡ÎŠÇŠñé® B5¿‡’¯yïí?TEË5Äp¸£O)ú&Duã/ëF™ùö8GÊ 9ºFŒù¶8ÚÁ7Þ+Ú"Ÿ‰l^9Äçµ^fgäûXˆØSàµÂe>ç•dDM(›W×d÷%r‡ÕñùåÌRÀö°ôÎüÎ…Ÿ—ëðš#z
-ÜM´[­¾lÊáÃôí •ö¯¶Lœf3ÃMÔxh -Qß_ª¤j´DÍñŽ3^¾ïGCF­U¡b³ß¡¬§+éëLC°º@œ¤ê
-Zîöú¬í.ߟÇ«–“rÚ›„9éÐcïÀé2b,Ÿ»µü±¡nÒ”é2óa s¶cãFˆƒ>ã5_Óuûi/ÌÇ+{7ê¸ ñå\ýŸQö{6‡ñ‚Ñj–NØê©Ì4Þì½a¼oF‡Ò
-l~ý›hPœð¶àˆæ{÷·ÊÌŠfGʉåì.`{B÷¤/žÐÑ&'”õ(K‰pI
-L9QÈ {ÌkQ’»ÌÅi:ÏD úL~>éÕ?çù±Ûþã1@”Æa—¸¥ñ-`Wk•ŠÁÑõ.G@]®<’AÙw)ðG8è=+e͈1XßÊv['~M‰–CV´š ¥ßb7 퀛Åû°’”B^S¢&/—xŸ_/䈷í
+xÚÕ[ÉŽ#9½×WøJ-‰Ô$(§íúœ·Æ\gNóÿ×Ö¾GXre5ºÎ%¢(.O$EÑËÿ.ôòû·ëç·ßL\ 1’K¼|þ÷³_Ð »(C@]”d„JvùüÿåÏ7J{×`ÿ í_üJ©`”âRÉíÇصŸ[øNšô&ûHIý®¹§b)‚{*ìxuïÄQÔQMï+û<ìÜ}ûΕûHãÜ·îÔîSóå¨9~Æ1þ^8 3Â5ðí8q¼á-Œ kHãÚy}Ç[‘ˆ{â%"ã¬<I'QñsdÚ‰û÷ÿ|þaµ¡p¦ d’¦{}p,ô¹å‚ËHEOuŠÈ‰”êû…ÅeË{!ªè9[Z W*š[ J £’“DùÍSéì aTfÖƒ–¬\U¥‹ ÷SƳ’¢§·)Ošh&®^(ÓŒ
+Áô£¼š¼²OçJíœrS-@ A„~”“®ˆP
+6J„Û¯íÏß­Ö„¹ 1š¯µf˜;ÕsI˜áÙÔ ~Ò¸í[<˶ª— [T´ép¤¥âPQÆýݳöá¹Í³¿ÖôkŽ%Å{*ÑëwØ H¸õŸŽ )ÖØ
+Ö¡ûeáÚ²Pk~=•™âm0õ]pdÿrKä,|üßÉÆuøÔË•÷4
+…óLÍUùOm @sBæ{h©8ëew—-e7t£z¶ð¾ÇVK%›Û= L
+›Q]eŽs2Éœ'—@'K½¢›ôæñÏ”¹œ§ù€Ñît[ÑuãÞ¹`Ûó¶N{Wô’Ú-_×¢GKP™-À騼`˜vEez6’)=µ
+ˆ`ÃÌN¬Â¯&‰5GÐÞªU‘ VÑnM뙸Á—‹q‡›àä‘Ÿ¦4Ê+5ÿ4(€§oCyŠG
+城Ãð†ßÆ2?iKŽŸ6ä "è“&O©¬!QYH¸ƒ ­‰¢ªN…Bå©à¯Ðz†˜[Pù±¿<7#Ùx¹ŸÝš°×Ž¢á·ç$ƶ%5ª#aŸE˜ÄkýV=m‚6¦zÙ°¯Õ¸²ü<Ý+ÔjgŒïTÍlÆ×W3¡Q8#«‰YÜÑ:*Ùçc%!ù»[¨Šñºóª>^÷)F…TÉPøz?ˆÞ©FÌâ+-ÐóµYÅÿ×UÞf ç» 
+Ǫ˜¬
+¤%XQÛi° ŠP†ƒÃ›-/ñG A¼Tu A|°ãË{un—BÈ´÷¸Ôc+.ìj6} %ö
+–ã/žN~0F¾g8Qòü4
+ÜCè&S¼DÁŽÎÃE) ³_µDöÁ 5³t_Y­¤EÍuT¼ÕÇÖ]= …¦5L¤Bí¤0É¿²–M©ÅüÙZ—….ÂJe&Ô¹Ök]ˆ¶
+¢&°gcµ„g“wŽ••¶«ÞŠp%VëwÚÎ÷D~½E½èªéä)l[ì®Ô¹$Àd/uØ–Ê l0A@¨½0²£òëú€2EF^ öôÑRÙå
+À’ 9W¹°‚ß”Ñ ·ÔQÙV°xcã‚Á`a X;*É`s·Gg°Mã4÷˜*\÷ 5Ìö÷›:(FâÕà,
+u]N\õ\l†I•¥R4׆h®_ÊÚ¯uÃ\~Šå$e?£æJ-Í ˆ½@­£âk!ØJUïzïÛ Ê|³* ç†*VNf¡ßÙigËݶФ"† &¼ÓµDú‚\‹Vë3²StÅ$((»»@!‰ã
+÷‚²ŽÊοp)(ˆ1|0pØ[JK¥à¡ðÍC)ŒÐr‡©˜/yïý²?çöG
+s¼ž¼+îÚÞÀ;f¾þšV+åÔà€×åK}6ì#ûEûÍä£t] KRÀÒeÎ3a?m¤„á vWð
+ŸmO`îµÞ~lÝýjhôÂà1õæ|‚yŽ`Ó7äõuŒ3Nß.ÃÞ}–È~½Uk"ô€³«5—xý¬%òìöY*2¦È©kC™¸ ¥œRü±éˆêzU:žs"¿Gy÷"Ÿ"’¨¿y¯%òÈîr˜ÈN¤¤6ñ+í¼å¬ãþùí/÷To
endstream
endobj
-1574 0 obj
-<< /Type /Page /Contents 1575 0 R /Resources 1573 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1177 0 R >>
-endobj
-1576 0 obj
-<< /D [ 1574 0 R /XYZ 78.37 808.885 null ] >>
+1575 0 obj
+<< /Type /Page /Contents 1576 0 R /Resources 1574 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1177 0 R >>
endobj
1577 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 768.829 null ] >>
+<< /D [ 1575 0 R /XYZ 78.37 808.885 null ] >>
endobj
1578 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 757.87 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 733.96 null ] >>
endobj
1579 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 746.912 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 723.001 null ] >>
endobj
1580 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 735.953 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 712.042 null ] >>
endobj
1581 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 686.287 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 701.083 null ] >>
endobj
1582 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 648.576 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 690.124 null ] >>
endobj
1583 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 637.617 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 679.166 null ] >>
endobj
1584 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 626.658 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 668.207 null ] >>
endobj
1585 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 615.699 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 657.248 null ] >>
endobj
1586 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 589.944 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 646.289 null ] >>
endobj
1587 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 578.985 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 635.33 null ] >>
endobj
1588 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 568.026 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 585.517 null ] >>
endobj
1589 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 557.067 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 547.659 null ] >>
endobj
1590 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 546.108 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 536.7 null ] >>
endobj
1591 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 535.149 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 525.741 null ] >>
endobj
1592 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 524.19 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 514.782 null ] >>
endobj
1593 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 513.231 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 488.879 null ] >>
endobj
1594 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 502.272 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 477.92 null ] >>
endobj
1595 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 491.313 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 466.961 null ] >>
endobj
1596 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 480.355 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 456.002 null ] >>
endobj
1597 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 469.396 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 445.044 null ] >>
endobj
1598 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 458.437 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 434.085 null ] >>
endobj
1599 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 447.478 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 423.126 null ] >>
endobj
1600 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 436.519 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 412.167 null ] >>
endobj
1601 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 425.56 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 401.208 null ] >>
endobj
1602 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 388.438 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 390.249 null ] >>
endobj
1603 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 377.479 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 379.29 null ] >>
endobj
1604 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 366.52 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 368.331 null ] >>
endobj
1605 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 355.561 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 357.372 null ] >>
endobj
1606 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 317.851 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 346.413 null ] >>
endobj
1607 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 292.095 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 335.454 null ] >>
endobj
1608 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 281.136 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 324.496 null ] >>
endobj
1609 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 270.177 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 286.638 null ] >>
endobj
1610 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 221.1 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 275.679 null ] >>
endobj
1611 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 210.141 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 264.72 null ] >>
endobj
1612 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 199.183 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 253.761 null ] >>
endobj
1613 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 188.224 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 215.903 null ] >>
endobj
1614 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 177.265 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 190 null ] >>
endobj
1615 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 166.306 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 179.041 null ] >>
endobj
1616 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 155.347 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 168.082 null ] >>
endobj
1617 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 144.388 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 118.269 null ] >>
endobj
1618 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 133.429 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 107.31 null ] >>
endobj
1619 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 122.47 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 96.351 null ] >>
endobj
1620 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 111.511 null ] >>
+<< /D [ 1575 0 R /XYZ 79.822 85.392 null ] >>
endobj
-1621 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 100.552 null ] >>
-endobj
-1622 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 89.593 null ] >>
+1574 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F85 427 0 R /F59 338 0 R /F84 404 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
1623 0 obj
-<< /D [ 1574 0 R /XYZ 79.822 78.635 null ] >>
-endobj
-1573 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-1626 0 obj
-<< /Filter /FlateDecode /Length 2412 >>
+<< /Filter /FlateDecode /Length 2633 >>
stream
-xÚÕZÉn#7½ÏWèÂ!«¸†Ë’ÈÙ· ×ä”ÿ¿†ûRìn75Kœƒf¬ùX«ê±É/_øåÛ—ëû—¯oB]s´¼¼ÿõEøøE\Œch.F Ƶ¸¼ÿsùã‰sm9Ç7ÿçßÐrÿ çJp.mú(ñ Æ?7࿇Ï͹–Ñp#~¾T ñ”ëú­Àj^žhFˆç8;ˆÀ%$Xñ( ižF‡§²ˆ·ü·¥lÀ0âÙÂS–¸(v?¢ÝÒJÚUT—ÄOIL–$ªöƉ2ZIÃ/;ƃ¸hžÿ|ÿÝûÇÈ-ÿHp̤÷ô‘/yö¶w¥t Ôä_À,N°]óA/Ú¨A³@çì°0 #¿œàº†Qo!²½ã:]¯^“ Á&ψÑ!:óøo°‰å€èÍü¤Çòj¥hã-.úõªÏãÌXW¯²Vôä<?öÖb²DCˆ6‰AæµÊèÍþo¸÷@Ò«híïú1³<u«Ù¼¢URTóži”MÀ47ê-vƒ<£«þžFĪUw5b´\ù«XªîÚø4H%sifñÎ8êãX #á©ø¡GãcN‰OŠŠˆ¬TgˆU¬“öƱžk4ûµˆ¨«æœ–b©<õÛ8é¤ Î°G¦™Í"£ÅrÜð2(&œê½\²kX©dC(ÙPÛ~×jK%Òö!oä}aL‰­„ 9Šni~‰¤¤1dmrºÞæq\¯[‰üZ‹Þz 螊ÈyoEOD¼!ÅÖdZ(Btæ9¬(˜•@r¶
-(Á€Ã–;›R™ê]ó\åf˜V&7ÂF Y«Àäÿ]ÇŒ¦r¦B—âÿýæPî"™³¡WÀ*V] ÿK:^sýâ%u (7;_߬¼Xo¶B3jáˆA´kvò[ê}bßs¢
-6ñnU Âèúæ€ñvÊOtýMzóó&±$\ÛÌ¿˜y… Y4Ø[K%úÞ…¨Kßçf£}oÅ¥Oê¶îk¿RKM¦Ei'P)8ç nú '(`ƒ;…œ6ÚÿgiKòêðmΕť-ÃÖ\¶3c«#«Úi¤²ý®éSsëÛab
-˜Ôv‹eH” ,C&w™\Vs ¢†O˜´mJO»ô©Û¦—Ó@{ÿ¥'>Eä~-V#Ÿ!× œžÌ‘ód´ÄQïÞz·Ò=ž—9¥#Öp\„߯H(Û#+Ô5!ùÉ`‚ž6Ô´îík¤ÍMp›I|°ÒçE¼¶òÚÚV6üd£ÄèúkiÕöflèÚ,9öøax¿“÷à6|Ñ RòKzR„Ž©ö•ÄmR,®q¶T3í§=)Ï
-ÖglÒÊšI|16 >Ë”j)éÚZµð ¡kncõêÉÀz{ …aÊ9Z}ôõTõq†9°¤Ô`ki£œ¹¶vÍ`;º ­ãkJÆqs߆ê.Ò' mÇ|[e “Œz[¶‘Ï=ZN&zY+ÐèU!”SLÏ}®õqrêÔ™†o›šl¯Üe¯ˆj}};´çDÍ„Šò€Å 2£qò›:'*¦¬¦(1IS BÔ½lG¢Â)Y­ª¡Y>‡Ÿ<§†TÌK@Q”ZC6¥&§â91”dRhŠ¢î] Þ·­cҎLj%^ñÚö{!Ø1³ÜkÆXÞí^f­¡ŠÊûš¢#
-ÈŽ-g
-2ôNµ(&9›îúw¨.æóNutç¹bQ}D©¾Ô­=;F÷‡ÓÙÏûÕ·WÌoùk=)ˆ ¹£*že[e7(ˆÁ-ã‚Jq²êÖ 9€¬3OéË7W³k… œbžÒp&l¾:Q°òꤎ>"5iÔt¬’š4p:8¬Ó{R“¦¤4Ž[ 5à¼]gküBNã}È R~5Ž¡ FqìÌ‘ÁwxÊÜ Ke™pfëňòÁàÀ`äæì#³ ·Í`$9ß½À„gè·"1ÏYwO!|6 Ř ĦX±K`u:éÍ'ŽpÿÁU-¦·m{/BÓà]ŸnDÔ dMKã†I§´é
-É ªIŒµjGPN‘Z°†Ùnå×®™‚ÜÿYC¯)µñJ4ýbhGhôcs9(ÿk*=èí X´ðÅMhîí%s»"WìP[ÒÝëKÞÂIyôªR\ïÌ[›´òpmȨI:óÔsÑ´NH-¡g»é£2žÙýJ}hz?‚i¤•)(Þ¿K/oÎk×^’v%)^Q°õfØ|3ê0¨„ï9@ "Ì/|ÁÎ/¬ìlÅlâa=u˜Ë‡Zá$²ì.ÊØVî¿.œ"r»ábK¬!¤€–ë1q[\»«GwºÊ²î
-½J8é.—2)AYï‚A¢OPs]Á%Þ@P~p(N×f¼ÃKKoõTÅÂ:Cñæñ G€À¸œ*äÙÞ;j‚ò€_A0n’¥ÕùÞ;³‚ýªË9Zãöýõ/x-ç|gü–2çÖÍ[ G> ×Ù|—ù¸—g 5ÏÙ–½˜gD¢I9mæíüJßúƒ‡)%íÜÝ[WV8Ç„¶TÙ³]zna
-¹¸°Žëß!S´Ýôêâ÷ìAa-î&…×zv‚òënijô<Þ¾Ã$ÆøžZd‘>Œ ¡Ã531I±vu Œ~é/Lþ‡¨C„)
-¹‚b2!˜tcI—ç;žb²eðæª@ž2*´T Å«çå£L{KÎ\»úܺÞß¿ü ÷¸›
+xÚÕ[ÉŽ½¾ÏSèL“Åf~ gß‚\“SÞÿnÅ¥Hõ4å߆s[j5‹µ³¾"É/ÿ¹ðË_/œéø)üû×ËíÇË÷Oí/Šy'$\~üûE„—øE\œfàôÅÁ¸—ÿ½üóʹúàÜÜŸzý×¼ðBóû§SǼ1ÒõD„ÔL;C©€
+"ÿ™@Q‡ï†s.!ÿ«;ç6<ƒ÷<SÇõW,kÎʲ”{,T"˪°e|fUDP·,‚xobÀ{~W•ÿ{ý¦A#%W(tJHoÝ35E¼üæÚìéyQTúß·™‘³Æ)Î*ïýü‘óøžum-¦±»Š—ž %©âÕÇ9Å+Í‚$”
+˜AqÄò–• ‹"’Ú“ÊûQò6«;ú–BUÞ³
+Ñ,“º—*%œýv“*ŽŸ4TNl÷i×|à˜¶éÍ÷å÷âf¤RÕv/áþÑTGñžwa€¦ll±=R‰lGÍW¸e‹ ëÒËÞK0ù,BJ÷>ü·Åá†1TsÛ ¢‘JïªC¿ ݹR´!￉!¼ÔçðÛGÿÍ ßô@SqùO‰ç]ØxÍ$·“òÞ¶”G¨`”Ÿ]T~Œy—ƒô»oK|¶ ’Üßg:˜ r¾ÚÓ)&•§bʽH%T’µîM¬ÈÜædG“\]]þKco¨–š¬>‡4h[ø ;[Éä,¿;'?&,"O0a€))&gÓ{\ŒTšž£Æ¤':úþ)ôÅj`TOÍz&íÅ(Áœ­Žk:Ûë7éø5§­ÞVZ¼‚½F[t‹Ñ ßΖ}ýW\9ñ’5Ÿ$?OŽðšFG6R>„'ÊáDX4¥èé²hú 'iXñêàZ¸°>±ÙyÅO3Åõ±Põ™ýÌQäÄ^[gQ{å´ØlchDOʈ#»ícÕÊ>
+<³VR Õœ÷vh]¥<=Ùda'-¢Õ=k£M±ãÄijjé;èEˆkWèÞZ}“kö<C
+ýôv§žð –Ô°²õIO«Öi¼ùE?_µy‰!ëì­(Çw0'Û{óIô†èmJF
+
+Wòòvòæðî‘Ž)1åB)0÷wf~j¨¹I+Ù+Qâ3MƒªÉ‹&L³ê†z?£ž«ü K‡ªÇ›¶^bTK™4‡ŸPS5jÓÓÈVsí3¾õµ¯Ä7áŠv詧åˆã“§¼"QÖºÓN¢…Úɱq,çžMÍ#ê¬ýòú‰OCg™ ÒbdÙ42j¬dÁ…•C1ÈôVÆìŠHëØ4£q}ÔG92î)k”¸°}+S†âE÷<=)KLßï=Ÿ¾×yz¯—­¢-O¢7q@c*Q.±•,‘è )¶&Ó:2Ñ©çp!+ 9»
+hÁ€ÃÊœMµ»ÓdB•GضLÎn£½b¡b¯ËÀd‚ðݤ”¹Y8i'÷n*œNö”„a6°E¨$q+VþÌÅOòáRy'¥˜¹œm½¦ZàšuÑÚžÏÀu¿ m¸üBü°‚QoÏ—×Ú‹úúdÛ€+€R9UÁjÆ
+G+X’X‡os²D“¶[“Ùƒ«’`\ÖNSêz‚Ø4(¼e±fPùº~Çò(P–7L´R´féã$\ûyô/½hˆ0P‚›IJæ¼[Á %ÕÌPÙ\‡½¤Ië¦ü´ËÏñ‘^,²m8N#ÚÛ/? )¢li8²™Œ=o&u”<‰ ¾$NoÞŠ7,Ÿ¬ÉÏç¦àñŠ B¼JÊ
+S‚¨àêÉ°ùdÔ¡[ /XX)7¿qƒ=VŠN»…>v3Š²aŸ3ÊÛö DBÝI×–¼ˆ±W$|g¾º[ƒçcRhÜÆ{/ã,Û²Kà PÑå^{p$²_‹¢ ¹§ÏÂ9*³'N§fz‡g–êÕ µ¸B¦ùbÄOÜ<B1Ë'³nž¤'Tž°+—Ì’ûkzû®#¡’ìj°6Þón­Ý›Ø-gÎÕÉ[G6§ÙÌíy+y`–\ÓÛ×*G"Ó5«’nØÌ»Ëy÷ñv%IGîí‹êsäJ™Þ¾È8!çŸ lmºíTD;ÍMO-þÔÍ?ιr¦¶ ö‘Èï·%¨Ñêò~òî Ÿ4Ú\œômEì¶>~¼ü0{w
endstream
endobj
+1622 0 obj
+<< /Type /Page /Contents 1623 0 R /Resources 1621 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1177 0 R >>
+endobj
+1624 0 obj
+<< /D [ 1622 0 R /XYZ 78.37 808.885 null ] >>
+endobj
1625 0 obj
-<< /Type /Page /Contents 1626 0 R /Resources 1624 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1177 0 R >>
+<< /D [ 1622 0 R /XYZ 79.822 768.829 null ] >>
+endobj
+1626 0 obj
+<< /D [ 1622 0 R /XYZ 79.822 757.87 null ] >>
endobj
1627 0 obj
-<< /D [ 1625 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 746.912 null ] >>
endobj
1628 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 710.05 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 735.953 null ] >>
endobj
1629 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 699.091 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 724.994 null ] >>
endobj
1630 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 625.367 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 714.035 null ] >>
endobj
1631 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 614.408 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 703.076 null ] >>
endobj
1632 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 603.45 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 692.117 null ] >>
endobj
1633 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 592.491 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 681.158 null ] >>
endobj
1634 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 581.532 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 670.199 null ] >>
endobj
1635 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 570.573 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 590.866 null ] >>
endobj
1636 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 559.614 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 579.907 null ] >>
endobj
1637 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 548.655 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 506.797 null ] >>
endobj
1638 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 537.696 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 495.838 null ] >>
endobj
1639 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 526.737 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 484.879 null ] >>
endobj
1640 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 515.778 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 473.921 null ] >>
endobj
1641 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 504.819 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 462.962 null ] >>
endobj
1642 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 443.051 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 452.003 null ] >>
endobj
1643 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 432.092 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 441.044 null ] >>
endobj
1644 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 421.133 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 430.085 null ] >>
endobj
1645 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 410.174 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 419.126 null ] >>
endobj
1646 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 399.215 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 408.167 null ] >>
endobj
1647 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 388.256 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 397.208 null ] >>
endobj
1648 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 377.298 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 386.249 null ] >>
endobj
1649 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 366.339 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 325.095 null ] >>
endobj
1650 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 355.38 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 314.136 null ] >>
endobj
1651 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 344.421 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 303.177 null ] >>
endobj
1652 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 333.462 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 292.218 null ] >>
endobj
1653 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 322.503 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 281.259 null ] >>
endobj
1654 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 272.69 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 270.3 null ] >>
endobj
1655 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 261.731 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 259.341 null ] >>
endobj
1656 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 250.772 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 248.382 null ] >>
endobj
1657 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 239.813 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 237.423 null ] >>
endobj
1658 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 228.854 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 226.464 null ] >>
endobj
1659 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 217.895 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 215.505 null ] >>
endobj
1660 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 206.936 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 204.547 null ] >>
endobj
1661 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 195.978 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 155.347 null ] >>
endobj
1662 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 185.019 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 144.388 null ] >>
endobj
1663 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 174.06 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 133.429 null ] >>
endobj
1664 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 163.101 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 122.47 null ] >>
endobj
1665 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 152.142 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 111.511 null ] >>
endobj
1666 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 141.183 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 100.552 null ] >>
endobj
1667 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 130.224 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 89.593 null ] >>
endobj
1668 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 119.265 null ] >>
-endobj
-1669 0 obj
-<< /D [ 1625 0 R /XYZ 79.822 108.306 null ] >>
+<< /D [ 1622 0 R /XYZ 79.822 78.635 null ] >>
endobj
-1624 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
+1621 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-1672 0 obj
-<< /Filter /FlateDecode /Length 2447 >>
+1671 0 obj
+<< /Filter /FlateDecode /Length 2476 >>
stream
-xÚÝ[Én#7½ÏWè†CÉ" Ü– gß‚\“Sþÿî[SR—Æ9ÈjõòX|µ°ªØ槿OüôÛ·íóÛ‹Ð'ǪÓç_ß„¿ÀOâd“ædP0ŽâôùÏéÎÑr./þ¯ßX6εxýž~ÔKî%œö¿Lù…®ÔÕG9W[úˆwÿ}(¯~þî3j%pÁÂ,(&=¤±"²GSù[ûëxÎr`ºOÙ(OmMXÅ„›‹ƒTÚD¤?6¦&„®
- ˆ*Çe|N,Ǫ–ï•œŸÇÜ#Ý5U<™‡4Lèæ3Ûbt)_Ê\Ê/ñ^Ž ­z £¾
-ªp–öž-(Å™ÑÎÿýÍÛ v'åÍMHèmÐjVŸ  wv¨ø±‚¾¶”ƒæ‹U'ë ¥íAœaì â’zo>²ò·dd–¬ä·«Qñ»ý¬=ó
-‚Y Ö‘”+Gò\Ž4_<QQ‚Jê9*û>€”;öß±/¸aRÁŒâ…¤ŠÁö&1¤;&†@f´™Q‚¦äÖœ‹v>’Y [skx§ŠN2é#ì,¶%‰=¡±£·Ù$j/àp,» î1ÄNÆó„ÁL ˆô ÇáÉâÏ!Þ„s˜M9™
-Ø“ùÊcbHÍ´ÅåžÎŠë­Óßûõ÷kÁ'Rʸ™JõA£rDYQÙ//Q䜄@§ñËݯ;•Di™2éôq4¯@ Ó¸“B-¦(q)Zq=Åv£Zf[5yÞÅv|¢^é„ù)#—3a¸ª¶eœb?µ²ZÏŽ0O¹P×9Á`¨úf>Myû’XÏ5C¥vô¼ÑèQ& ØrˆÝš%ÅxQÞÓ±¦D«9¥½E4ÌÊ)ÑŽ6v™•q—è/YTµS ­ž‰&æÊ­²T¡ö¡çŽÚJæË–¸–”yO(wÊþT#j´ÌºU{)vAyÑlúø"/Öx¦8Þ}££”ïhe}îä’³ÿ5w Tn $“žáY#ç[åíPN§†ðWÎÖ"üÊSæÜŒx(œouj }ð‰þÂX}KÇÚî~œ^—kíKk)vqKSêò $Æò¬Ê4K^“›âi®5‡êñ¥%7ÑRÎ_¿JŒkC^¨Ü)dÎìrˆ£ù}ñí%ç÷w|[²Æ#^mté`¾64öR­õ¸’“׫®ï¢æFŸ+ý¶è(VÄP»b׸Þ5ëHµÃŸ€
-Ô<ZéVÇ™ˆ‹LaÔ,:l©'Cl—w¿!}7v=–ê9¯¡v¥¿Ò–Ý÷ 5p&luÌÔ=/2ìÃa§ÛÇPÞz‰×ÒŸPÐxNÖFåC«ØŸˆ‘P„逻–LC§ŽvÂQØ)Åõ“Óú¶±i„œ Uî¶Ñh·6¦§Ž¸ñ&Büø´<ß1TéW¥ÝSZ¸c
--Ãû•ªs¢±ë°†:²”e%*%Xø®¯mî+ªI¥•_ÖíŽ`ZÙ>¡< †’L¡›Å µÊó7F”O†´ØImiä  š@%›7¶™ŽûšH½åhÈ]—ºÔ¡±¯+ò^=…Lï9!n•L(Ï#¥¦MÏ#DøÛÆßÔ6§2¢¬ùù݇Èèi^,K cÔÏR'c8îڦĄDÝ„r-˜é«»}öuŸÂ2ÙG«°¯È$B±†f—F³¹ %N³ƒaënìv*¯µ^th¾.¢Öµ>L0_,Hc˜iÑ:ÌÇ•¡éx¢yÄw^wn%dY¾j,ÿÈužì^³‰ý¤Y%Þ0-³ ÞŽæ¨9AŸö9ê=ç,ojÅë@qÐø2Uv¸¡Ã=½n°ÔšŇíPkfœ]ñIÜUšÙaÛn#J­³Ò-¥~£YÁˆdI¤dvIßѼ1צÊÀˆ¥ SÁ? œ‘V«|ß,¬{û¼yx8W£0isœ˜î«».X&gä‰_!B›giqšÆïˆ:|~žÎöã9–zZ¶•X*mgz`YÑÜiB¢ú58ÎxÛüI’$™DhÏV I}ëý«{¯£ Ú¿»ê¬ÊÍòZKßɽ² FàÎ8Æí2·!¾¤3!‘W7@ËDÛ²-’¤oš$#y
-r0Q @8-‹æK÷JÿO¥kB(føRGSŽLô¢¡÷ýã4<sC*QÀ%3J.)°4“‘Ⱦါ–&IkëŒ@d9¬`vŸÃG9)ùÈrÎ,âR1´¯hÎ'ÊۧŒÚ;5o¸úëžiÔxRœ¹¶,H[–Ïoÿ¡
+xÚÝ[Énc»Ýû+ôÍ&‹3`°,éY{d›¬òÿÛpŠÔ5)è¼…º¥;‹§fV™žþs¢§¿ž(‘þ›û÷¯§óûÓï›´'A¬aNïÿ~bî!zb'# yÒŠªØéý¿§>S*®”*A©„—½ÿã‰&š¿oFœ ±JqÓa Ó€©€Žo7œ|Ƥ„QÀl¨ó=P/¿$HÿÍÑâàè^Ü÷[¹Zî«Kºwv[g”jŸW´¾§iyO7ßv7Ê-a‚}]Û(Õ„ ÀT` an Ä·{lôTž»l0M
+8÷ñš¿—¯+8NÜ‚úÈ”•„S=@&¶ CT:iî2d„³;¨=ß²>D%±ñûÆäɺ·@‰ö-m ×'%5õeܪ7/Ù—_Ìsö€/¿ârË>G±qyaòî~vžÞ~ü‡½‡ÓbÆPF„ÌšWÄ™2‰¬T"ºíÀ‡ŠÏ ø9‚hÌâÅÂ"u#Ù‰ø­ú y‡
+0«µOÊ>•Pjœ«9©,¹kTx/-~®o a[:Ž53³°Í™j}^±š =I;¢ÖF
+êW.C¶ÕÕ‚d«ˆŠ×î^ƒÇbÇÿÎ9J¸ŸUÏÿ~ëÊ&d'ª¹ìl^2b„6ÿº·ùžŠg9oFž#›Ø¼³“
+Æ™3”²ù®l
+Dåžgœ#*V÷´vjÐÜ~dòÜ|Âä9#` k5ëÈ`õTŽêÄÚªzHÓÎíÀ®Ùª®•Psu±`ƒ¿XŒòéô v®]‰œj¨ÙfÔÖRª|¿U- ‡‡].Õ£\zg‚K¥êå((¡0´‰7–9¸¨ÕXŸ‡¨ l&ÇÏUÓB@É Ñ6¾Þiñˆþ—z»$»a ¦!Ä]E*Ù
+
+Êqêÿ,Æâ›å¸1D8-G«•®¹ß »ñèNõdº'ÎÃ%Wë×¥ÍoˆÿWt-Ñb^\îL~y$llwƒ¯xíp¿eF·Øȶ8ÃÞ¥×9¦p9™bÚ¶ïÒ»15w¹†Cy­c¦!ÜŒf‚uH–Ôïî¢F
+y¬lÒ9Æ1 Â+´áï
+®Ê9OÞæ—•»è4¼µ;fœ
+¢t¿¾Ÿ…«kÿ]Cuñ!ÈBõÊ÷ê}ŒdöÜ>(úð\‡ä°”»Aþ·¿?×¼/85`F¨Í•ãÍ¿ÿB”ö9ÑŠ€3N6'¼¥§178W’€•SÎ_÷0ì)¨\åD_›ªE’åÆýq€Y}tº.ÀC^mÉ‘þ~`)çj†Ëæ´¢ô}¸”ŒêÛ0Üå¨zŠ‰Ùä§4Ãd˜aLeŒì;ðh=+šæÐâ³èq ‚™©¥íýñ¢ôõÃ7³¢=D’Gì>›c0`DH;Ån/×C”þ¬?TÙ2柚Y&ß祳ž®Øâ`w—ZbæXV|ú5Õ¼`7†}…VYK¤˜¦h«‰kÊÛ{BcÞúµóÙ]OR?Ðô͹ê`Ðë™ àp@iWqX ɘ:¯'¼I{BK:x)UÐÏZ5©zžWȤ=¡ŽÁºÅ¥: J¬.nœ›²êõýéF©?K
endstream
endobj
-1671 0 obj
-<< /Type /Page /Contents 1672 0 R /Resources 1670 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1731 0 R >>
+1670 0 obj
+<< /Type /Page /Contents 1671 0 R /Resources 1669 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1724 0 R >>
+endobj
+1672 0 obj
+<< /D [ 1670 0 R /XYZ 78.37 808.885 null ] >>
endobj
1673 0 obj
-<< /D [ 1671 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 768.829 null ] >>
endobj
1674 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 733.96 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 757.87 null ] >>
endobj
1675 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 723.001 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 746.912 null ] >>
endobj
1676 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 712.042 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 735.953 null ] >>
endobj
1677 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 701.083 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 724.994 null ] >>
endobj
1678 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 690.124 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 714.035 null ] >>
endobj
1679 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 679.166 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 703.076 null ] >>
endobj
1680 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 668.207 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 692.117 null ] >>
endobj
1681 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 657.248 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 630.349 null ] >>
endobj
1682 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 646.289 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 619.39 null ] >>
endobj
1683 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 635.33 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 608.431 null ] >>
endobj
1684 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 624.371 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 570.573 null ] >>
endobj
1685 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 613.412 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 559.614 null ] >>
endobj
1686 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 602.453 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 548.655 null ] >>
endobj
1687 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 591.494 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 537.696 null ] >>
endobj
1688 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 565.7 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 526.737 null ] >>
endobj
1689 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 554.741 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 515.778 null ] >>
endobj
1690 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 516.991 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 504.819 null ] >>
endobj
1691 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 506.032 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 493.86 null ] >>
endobj
1692 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 495.073 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 482.902 null ] >>
endobj
1693 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 484.114 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 471.943 null ] >>
endobj
1694 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 473.155 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 460.984 null ] >>
endobj
1695 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 462.196 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 450.025 null ] >>
endobj
1696 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 451.237 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 439.066 null ] >>
endobj
1697 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 440.278 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 428.107 null ] >>
endobj
1698 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 429.32 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 408.182 null ] >>
endobj
1699 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 418.361 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 397.223 null ] >>
endobj
1700 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 407.402 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 381.283 null ] >>
endobj
1701 0 obj
-<< /D [ 1671 0 R /XYZ 79.822 396.443 null ] >>
+<< /D [ 1670 0 R /XYZ 79.822 370.324 null ] >>
endobj
1702 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 385.484 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 359.365 null ] >>
endobj
1703 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 374.525 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 348.406 null ] >>
endobj
1704 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 363.566 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 337.447 null ] >>
endobj
1705 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 352.607 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 326.488 null ] >>
endobj
1706 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 341.648 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 298.593 null ] >>
endobj
1707 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 330.689 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 287.634 null ] >>
endobj
1708 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 319.73 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 249.776 null ] >>
endobj
1709 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 308.772 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 238.817 null ] >>
endobj
1710 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 297.813 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 227.858 null ] >>
endobj
1711 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 286.854 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 216.899 null ] >>
endobj
1712 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 275.895 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 205.94 null ] >>
endobj
1713 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 264.936 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 194.981 null ] >>
endobj
1714 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 253.977 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 184.022 null ] >>
endobj
1715 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 243.018 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 173.063 null ] >>
endobj
1716 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 232.059 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 162.105 null ] >>
endobj
1717 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 221.1 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 151.146 null ] >>
endobj
1718 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 210.141 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 140.187 null ] >>
endobj
1719 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 199.183 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 129.228 null ] >>
endobj
1720 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 188.224 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 118.269 null ] >>
endobj
1721 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 177.265 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 107.31 null ] >>
endobj
1722 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 166.306 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 96.351 null ] >>
endobj
1723 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 155.347 null ] >>
+<< /D [ 1670 0 R /XYZ 81.145 85.392 null ] >>
endobj
-1724 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 144.388 null ] >>
+1669 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-1725 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 133.429 null ] >>
+1727 0 obj
+<< /Filter /FlateDecode /Length 2574 >>
+stream
+xÚÍ[Ënk+ç+üá@Q¼$ËRÇWºãÌZ=íõÿO/¯bÛà·ŽŽrïÇ¢XU‹‚p¦ÿ=pÿÿ_oçï·_WåÈœßÿyîÿ‰ƒ¦ñ`´`\‹Ã÷ÿÿ:r®€sã8×çðsú÷÷ßo<€y¨_W‹ËœÖÒÖ8ã\ìTz»2æ%Š3ÁahÉÇœ%
+
+Ý#rŽ /) ~ùkU -|úûâÓ_çœKH÷Ã5øLï`ü<½+P„f3ŠH?áwiR+EÃÖRx–Z'ôÍB• ~°.<gl~‡'k»wù•Ž ”#~¥[ã·E~~^Îv¸Q–™F7b:Xð þ.Ë`™ðôX¶kó©CÒ«–Ã
+S
+G–ÈʼnÕ"=“ãȳ¤þcò›–)§†üØ%-Ø!­7LK=ô™I•¢%³~ÎwH}Vé5¨Î1¡p9à>{£œfÚ˜aop©7RìL=ˆ½°m,
+ѽ詜'‹¢=µ«=±Ša‡2©;|JT=Òͨz®2º®T@c6¶iìB/‘¶¾°Í§±U 23tÌY¹C4@›YSÎêÜ«å+æGÊ€Æ二¸šWT˜|§¤›—I4-Òr´R
+˜EY2«Tæë&AËtþ3›BÁ¬•#f%G¦¡ÑPÏýyžÐh‹HÎà‚5Ÿl‘Ög‡p\,Y¬ëtHë–pç5“Zb—ô_‡´l :Ë8šáèLª
+ÐLx-Ü!õª"*‰ª’EQÑð'ÔZøµC«qÍêé¦zÈ9†ò‰W ój7‡.)#‡ Nù¦„Ÿ¯¼æ–y]-¶ ^«¯ßÊÔh|¯Á ýn­FÒ!¾WÕ Y®^M–¬ÜT/åyÏbð$rÉyÓ.­$õkëÑX²µÏk[Þ~6ƒ£VÞ/G4«¥È± ÕZs[cžò÷[¾}GuÛÔrŸÉþ¯Uô±Ä^±ØyíDs£EZÖNˆ>ß)9²d±ÊÓ!ý1ss‘ Žø˜Q9owHcÃk½úFìXd“R ÙY«%uHÙ’_W¡Aî€o¬zË8&͹fÒ•u‚32ÊñÓ;
+wLÑ•rYøQâæ˜êÒ[-:<mUÕjŒ²Ú…ÊWËÝ€$¯¤(èjÌ™%)ÞÞ!6”n¥u4 zØ:òy]?ÊëwY–>ÏJ¯û{+°é91×
+E$%ú†©ˆ5©iÏšòRi°Ê©xcg;½Ñ“®6dç”wÙÄL•])éM+N66@w“A¥‰ëì¼—Ó•<×öDžù6íÃÖ‚~* ƒdfP„¶ËÅ™©xIåä!“Ó®„ýÂ_á
+Ò`…^ù'>ê
+¬b‡%–ÙBhŽQÒêf:Å…è}n¿Á[oGÒ²"¾+nŽbÙçæRì[ÌǺª ùcqnuÄ 2k‡E ÅÊh‡´:b4×ãvnvëå Ð’¹Á‘S5_l¤Þ´HÇ7Zf6þilÌj1„ÆG–Î#ÉÒiçSý‚Ãð~q²j;ãƒ#¡j¾pH¶·H“JdÑZ)˜GZ»VÈë– Ð
+êc‹4<úZ¯Í^yšäi6Œf08¶©æõ ±Ñ"ý ¿qðw™ ­¸a&>lŸ™h‘æÌX¥£òıRGŒ[ö1yho¿îé·r׸ýÝå? krp(—7M;¤å«@éWIfdÉ¢Né~îHÈH9’Þ¯ÞWœC+¼| $Ì^ƒOhT‘áà`+Ϋ'¡c=¢C*åz¾­YîKf‹ï×<„0 ŽÊÄ UU­ËÔÕ|·YÏÇøóŠêaÕ 2­ðO¹þ®45[ ghᜪZÚy+›o-Ô‹âüNµö U`^ÆßÝ©t‚Y¹:.ÏA[õêI{Õ«›vÝwKÒ»‡Ó}kT§‰=WYUø©ZÕSvÈUI¶PËwHŸÕvš¸bÍ9•5çÝø‰«®¬È[Ã¥l½/ªî£(
+•Ze
+€ãv:ú)Ðy,+ñ\ߢçE>:‘¾ÕU´²Å«‘ØaW¢ vVƒn+WqRmÔ4Gíî×Áø¸çeWõèæDîï5d;êt7Æ4¬J<”Ðb•ªÐ—ØU@ö¢º6Òþi[Ýb¬Ý‚»9ßž¨)9dj˜ gWo9Z68´žï³N³âäÕÖæ¥Ý‚®”Iù ¯¿uàÄJ¦÷åýÐÑÅ]ö¨Ý^ϸ£ `:ŒÑÇàõXg£ýý¹7<ø,ó!ðîÏÔGæí’‹µ@#eQŽÛT•¯š¸GœoÁ{1ræLIüÕ‰­¯ï·
+endstream
endobj
1726 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 122.47 null ] >>
-endobj
-1727 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 111.511 null ] >>
+<< /Type /Page /Contents 1727 0 R /Resources 1725 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1724 0 R >>
endobj
1728 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 100.552 null ] >>
+<< /D [ 1726 0 R /XYZ 78.37 808.885 null ] >>
endobj
1729 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 89.593 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 768.829 null ] >>
endobj
1730 0 obj
-<< /D [ 1671 0 R /XYZ 81.145 78.635 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 757.87 null ] >>
endobj
-1670 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R >> /ProcSet [ /PDF /Text ] >>
+1731 0 obj
+<< /D [ 1726 0 R /XYZ 81.145 746.912 null ] >>
endobj
-1734 0 obj
-<< /Filter /FlateDecode /Length 2899 >>
-stream
-xÚí\ÉŽëºÝ÷Wøš—,΀a ÝnȺwA¶É*ÿ¿ §â,Yìá!‹àÁ¯mI,²ÖpXº”ÈË¿/Ôýÿo/÷Ï—?›´A¬a.ŸÿzaêþcD‰‹VŒPÅ.Ÿÿ¹üãJ©Jµ¥TÝ)·~þý…zbŽÔŸÍˆ‹!V)nj: azJ ܇;Š,~„qT?Ü_7×îÞ»ûî>ÊÜ^%È4Ÿ?a„‰£ÄÄtÍ}Wî#îq–pºOºÏÞãuÿ;ÏîÇØB£]]äµÝ¹IJ…Anoþï9¹qI¤Q=%P<ß~Ý~Íüy
-<Ø"Eñ¨G…§:):‘jAB(¡¬“™„óÌ™²z¦)¯WQk®Ð¿IÈ3éêÛ¢†¸%Lð™†ý%Ën)Íô÷dGþ¯ˆÒõRðÜ=PO§,~Ϻg²LòDyãÌYöƒœyc+lE›2dÃØEÙƒ!Ì u"{u_Û-%gƒ‹+aš
-"˜ê)=÷¿kÕ;ÞcM:ÊJ©žJÇ,ÙmG)­äÏÆäźQà&«FiK¸¾(ãÖ˜ªü†Ü¼8n¯‚Ùkt¯ÌüG²hw]C%¼»Ú\ãÆbƒš
--
-ïzJqÎh´ñjšÍJ¢»»½B˜(ÞŠüi1㌠ö:ôI\WÏâú¡Œ¹V„Þ/¢á_4|£¼ý<Ǽ‘“€"™ðT2Ç=™…û.ü(®‹fÂò;“P†(šŽ¸WT· þb¶Û+çüï°w´…xW®&7Jj÷gê$”\
-¥Ÿ ¿“æûëáÑI„(3u3J¬¹™–Òóä±ç#†¨¿ y\vÅŽCü§®˜¯Ù`K)H&ÙlíšýŽG~³ë±ñúSÏ/¼'ÿÜÊ{F5ÉÛÌTOÍÐPN² ~§‘÷™°Ô Ù×ìfø5¹!˯e¿ûˆ!%82 ƒ«óW…ß$ ©4/\É´‚?Î
-¸ úŠ¼ã£ÙFâC20>7N)ªèl8…‘Ë[Á¾Z}„µè=yeçÁÆ-ÞÍq6Ä_œ3°d‰bÖ‚Á]t’7Oa[¡Œ[iŠˆŽbjR.µ„vYéNîâæA®Õ¹³=£bšɆ™½X…¨Å”a10å« šÃYÚ
-šõÁc•W Ds>5¾ÆkGé×2Ûu#ZO#öÙªyl)Í0§¦6°¦Ÿ?D\—†¤Ä°1šóù J£¥ô3Ò@Ûÿ+$Á-1RÍ$q6/@I´”η ˆÚD"!K­’~”Jí1B:ÞåhGÐG×
-0Ö½³ü-ßÕv¼+—cb¬žIñÈ´£´Œ¼
-¦‰åfº’µ<¥£ôs-!³Ìóý¼öõ*ÎQË^j(ñ»W‹/䨂ª
-­z6yrI“–º#”ÑzZ*–`ñ¸‘§´Þcă[ Àa—6Z£Ô^¦énSÍïó
-Q_sõý-á¿þJƒÙ>ƒes¤ P!i÷‚š—ê’8©*¬SxLi™Û9²—…—³Ï¬úÜD`æU×6mÕw| éŒÃª~6Di'lãöCoUM±!a’* æßÿV§ilµÌÔˆ2ïôÇ6U­" gØz„Tœ-ÐÙçàì¤
-ûúV>Á¹"B°é9Y¥RM¸€žÒ©³ÎÜOÏF`éì"<}«ÝúúG|ªõJÉsJu÷³Ê+M~í0VÇ´°=×?\½æ V`ЯàdN#<Þæìú¿Po>·°†HUZÚ.³£Õ3*CÓVGá—22f4a®nífËçf§Í}›DuXq—iæÞ™|³ÓÑ…ö³=Áñ è4¢œDwœ¹Yg0¡Ü UTØ’‚à].Dl)ò÷­„šP¾?öʱgdz·e
-Z5¶Ëó¨Oò -¡?ÙŠK§¥V9lûGNÿ h~ŽlßúÙ0Le˜µ´9ÈcÉ aŽáŽ¯î€j7U–œªúÑþÀþ[§¨[ý [9¼{æå
-£E9)hÚÙ ~iÍýÞjWŠ; ]¤Å}î¥?8&RùŽGsúÙ:~‘Ó´k
-ßÉÈH*Tg6£Ë>Ÿ6¬i‰YßF8 µ‹Ç:¥ÿké0YXÔ’‰o¦¥54¹£ô+KLùŽ:5ÝùkxpGi¹w‰Iß §§+Y{G©§ô¤‡|VöË­OÐV¹: `3+àKX=¥ÝÞõc_Óuðœ 1î„s4~´‡~Qê|Ú5襾øþBGi¹,b0ëTbîi år
-endstream
+1732 0 obj
+<< /D [ 1726 0 R /XYZ 81.145 735.953 null ] >>
endobj
1733 0 obj
-<< /Type /Page /Contents 1734 0 R /Resources 1732 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1731 0 R >>
+<< /D [ 1726 0 R /XYZ 81.145 724.994 null ] >>
+endobj
+1734 0 obj
+<< /D [ 1726 0 R /XYZ 81.145 714.035 null ] >>
endobj
1735 0 obj
-<< /D [ 1733 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 703.076 null ] >>
endobj
1736 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 692.117 null ] >>
endobj
1737 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 681.158 null ] >>
endobj
1738 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 670.199 null ] >>
endobj
1739 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 659.24 null ] >>
endobj
1740 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 648.281 null ] >>
endobj
1741 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 637.322 null ] >>
endobj
1742 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 626.364 null ] >>
endobj
1743 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 665.414 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 615.405 null ] >>
endobj
1744 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 654.455 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 604.446 null ] >>
endobj
1745 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 643.496 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 593.487 null ] >>
endobj
1746 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 605.834 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 582.528 null ] >>
endobj
1747 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 568.173 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 571.569 null ] >>
endobj
1748 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 557.214 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 560.61 null ] >>
endobj
1749 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 546.255 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 549.651 null ] >>
endobj
1750 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 535.296 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 538.692 null ] >>
endobj
1751 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 524.337 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 527.733 null ] >>
endobj
1752 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 513.378 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 516.775 null ] >>
endobj
1753 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 502.419 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 505.816 null ] >>
endobj
1754 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 491.46 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 494.857 null ] >>
endobj
1755 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 480.501 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 483.898 null ] >>
endobj
1756 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 469.542 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 472.939 null ] >>
endobj
1757 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 458.584 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 461.98 null ] >>
endobj
1758 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 447.625 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 451.021 null ] >>
endobj
1759 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 436.666 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 440.062 null ] >>
endobj
1760 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 425.707 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 429.103 null ] >>
endobj
1761 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 414.748 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 391.245 null ] >>
endobj
1762 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 377.086 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 380.286 null ] >>
endobj
1763 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 366.127 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 369.327 null ] >>
endobj
1764 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 355.168 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 331.469 null ] >>
endobj
1765 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 344.209 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 293.611 null ] >>
endobj
1766 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 295.377 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 282.653 null ] >>
endobj
1767 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 284.418 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 271.694 null ] >>
endobj
1768 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 258.712 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 260.735 null ] >>
endobj
1769 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 247.753 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 249.776 null ] >>
endobj
1770 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 210.091 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 238.817 null ] >>
endobj
1771 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 199.132 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 227.858 null ] >>
endobj
1772 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 188.173 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 216.899 null ] >>
endobj
1773 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 177.214 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 205.94 null ] >>
endobj
1774 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 166.255 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 194.981 null ] >>
endobj
1775 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 155.297 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 184.022 null ] >>
endobj
1776 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 144.338 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 173.063 null ] >>
endobj
1777 0 obj
-<< /D [ 1733 0 R /XYZ 81.145 133.379 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 162.105 null ] >>
endobj
-233 0 obj
-<< /D [ 1733 0 R /XYZ 79.37 110.903 null ] >>
+1778 0 obj
+<< /D [ 1726 0 R /XYZ 81.145 151.146 null ] >>
endobj
-1732 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
+1779 0 obj
+<< /D [ 1726 0 R /XYZ 81.145 140.187 null ] >>
endobj
1780 0 obj
-<< /Filter /FlateDecode /Length 1868 >>
-stream
-xÚÍZÉŽã6½÷Wø†C²Š‹€Aí¶ ç¾¹&§üÿ5\%±TVwÉžd0ð´lJO¯ÖBR+wúû¤Óÿ¿½œ?^¾ßÜtB5Eöôñ׋9éôÏœ¢UOÁ¥½9}üsúã‡ÖÎj&­=æë×??~Ñ,A}¿E<E5yq35ÙHlÀw­!¦½&@“þžø%ë¦kŸ^hßêxþ=Ì{³·×oκŒèç«LÒ¸­Ï–ç2Ž©ßƒOßcÆŸŸ[<¯F‹ +½}¢4§•Ñ–Sš?IiFh)Rb'd“2,“·¯11^(RÖq±UÖñµêB½.6Ŧÿfƒü{¶kþžÇí{}üVó%¶ó×µÝóX~‹q­ãÝw ùZþÍß
-ÏÎY¿~3Úéá%x+žØ5lT&iš1L_3ˆõÊK‘F÷ߪúyjÞhà°.LPÖ:VQ6MF$1?YŸ&NåÐÏŽrÙ\ÐMøpÄsšyKxB<ôÑ(4¬Ó{š ‰ã¡Z¡ã]Dñ kÌq£Æ‘låªõjÉþ{‰=Ý#²…ß¹fMý”ˆ$¶s‹‚¦Nó<–ŸYGÂU”êÐM
-'Ïé¯2ŽHœ{+³ã½Î¦€ÿ³¾ø¹H˜gÜü|èèêÅV¡/Líñ¬ë1*Ú
- ÿ•ÙjDb%&5€;W g-Æ_În- ô‹Ü'ÕÂq«@P.DÎ*_,ª{@ö=r=—¨ðWˆC?±Ž;j©¤go&ÎR_­äûü‘ŠŒ¾å¿ÔÑ›xwá#ÄV/s¡6ßÃZc¿ç¹¹kË8å=«¬7Yš€Ä<\Œ*Z–È‹ìVΠMÓ³JäÝYódsMñ%ÄŸW×·e²^Ö.¿žh½ø+OÞ×°«¢p6½_®MRi©D¨ÀTôlÚVæi P™qÑ•^•»±&‘y²O4¤Qôv“ן¬-Ô{r¸Àv¯õ[½¯Êß1%ãòŽbÕÝgHàΕôÎÎ)QgB€º+guÓ>}¿>-Ñ–æËEš±
-^Þ"Uj• ̪
-;)c;/A6/G$q#åLTƱ!VØ$Ú/%Ù¬ù‹”k’ÙL›h†WqLîsM¿g;‡š8,Cj“”…ÈÉðÕ’±É@ìuñǹ=ÑÃ’ƒ˜ktʲT…5Ó¦ÆyÛ4½-(3¨À–²l™” ßf¸c¦%ï”(kÄp84b9<(ð–“džNÐÔ<74H­ÝùÁ=ÎÛY…XÞQÆ{DÂVEôRíReøÛêú²)Å2 QˆÈú“É0"¡kRabóùØ"Yê?´ÝVÇe­ÒäceA™,#º¥å v™D3)·-ö‹ïÈ–ôÒ}®Uçsô¿,Y©KË££ržÍVÂÌJöäY5}R¾ª+¯‡pß9 ³+AÚåûvœoL8N_a&%H{|á¸?@H½0KW˜MG ]¶ñ8[*€eéÊ2)AÚõwœ¯ÆŸ¹–zËóE«â¸•2ó•eJ‚´ëÇëV
-³.AºÇû kÖ:°œe™— eÎý°M_÷$"j­
-÷û͸Sj½MWï
-)y„SDõPŠ:ójã¶ÛœÀ
-ž¥€©D»ñ² ?líËä´Sè¢ô<ºVÑó!MVØ@eEÊ.~³žAAj0;%rΟP¯—5 Î ïúñò/ò†
-endstream
-endobj
-1779 0 obj
-<< /Type /Page /Contents 1780 0 R /Resources 1778 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1731 0 R >>
+<< /D [ 1726 0 R /XYZ 81.145 102.329 null ] >>
endobj
1781 0 obj
-<< /D [ 1779 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 91.37 null ] >>
endobj
1782 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 768.829 null ] >>
-endobj
-1783 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 1726 0 R /XYZ 81.145 80.411 null ] >>
endobj
-1784 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 746.912 null ] >>
+1725 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
1785 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 735.953 null ] >>
+<< /Filter /FlateDecode /Length 2267 >>
+stream
+xÚí[Énä6½û+ú†C‹00à¶[rö-È59åÿ¯á*.*É¢ìä zº[-=ÖÆWÅ"Í™ºý}ãþÿßžîïOßånÈœnï=‰÷ÿÄÍÓx3Z0®ÅíýŸÛ?8WÀ¹qœkô/õüçûïO<€y¨ï‹Å›eNki[Á “#˜øô÷E¨›óO¬yÊ8&ÍÍHdBCyF[Îåâ_ðüM‚öW¤ñ2 ÎѦ—Ï`üuãåÄðzó÷ÜËÝpÏwßÓK¼¦;` w˜átô¿jFôïPîŠWV9âxüY…"¢MÏÕgÂ/U R:ƒõJ£µ̘ÿY¤Wøt:jÆIR…ëÑEwÈ×òwí­.a `” ±Ó‘ü(4S`ÏÊ®ä/’=G
+zUÜC›€’Ìr=>­4-{± ,EÏÖ6>Ùäoá÷ú-ȬZf:0zߪT³TKÏ󄪰R(äØÄûJuÁSf£ÉéeZÉÑ6‘¾—C«¢O\Bàƪ³„¢ z
+ÖÔLÁǹ™âSQfD
+:´‘çv&Öp­°…Á–)JÒ
+w†ˆÑÿèâ­<¡÷X¦Ÿ5ÍŒ $Ó÷0Š¯ã«™Qº7J²ŽË¤=ÛÑÀÌúKK†`FIÞçüÕ#}¿‚U¾Ò_J)tÖ/í—üñ¿£eèË‚ßÁèC¾Xïh)_ɶV÷ZÊFîkY{XJ9ΫQ¶L\2-ìF«\ÆaÌô9ï,EÚä¯\øëp5ZOúO¶3E)’
+•*M¦Ê —SÀžqZó–*®Rëƒ11…µ5³4k²¨m¢Íc”I_ª_dj’GtjʼnÁƾ·ã§D–0£›—šºrí>L{I¢]R»šþ½áSúú å­Ké4/ÕõÀ™tb”ÿ'ïáŠÉ—#Æl,yrÅ$•/f”úŒ!M’8(¦´£H\Á‰÷H€uEçÌ£j!sy_ˆ<ú|i©´Ì°B‘+}î•?e„RHÁkã××âÇ•˜*í¶¿ß³—ºZ•Ë.eŸ/&½$mÛ0ÁIú>ç¤è–
+“>
+ÉKÑNz™sR´JüV#)öDJÁ†¹ßp^Zåü›JZy²xÍ„)/K'$±‚)IIì9I¤g_îH¸íÛ¨s/ûË~µŒåÙ¬6†ûŒ€dœì˜¢b^ˆ ’*¬3Lî_cÿí Æv&œÃ º“©Vc6Ú–,{Û1Ôt )ǬФÕq.š{¤éE‘ò¥«Uä¢h²Ý3 ­Ë€ýå€ÁœZ+ |¤ˆ×÷ôî%øæÄÇfº­½™g ±xk\'Ö!茟‚H¶ê/t9[õk§FÓåÒ‡Yí†ÔÔ>Õ bÁqcs5IÙ”´u-qÔ›=Sû¢)LÞ+›‡(ût÷į—˜/$©À;Ù=ÉíØ(Îð×Ú‚…Gr äÅa5s^œ¿ì»ŽÊîTw]çÖn C"ó¯(x¿ÜÂ@ãßÌf¶†ys¶…‘gë€4QûÜ%,%Éd> mÚé§Ë£Vmý>LÝ¥zÓ[ËSvßwúAÕ`$F³?´¶ˆsöØkš®x7.Ñt—CCùô«)œ-¹sFéúàßú댼Ñÿ²%¤O‰\¦x™›$=Ò¼$~õbR’œ,Z Çõ@?›ã‚»Jóòó|§¨&¦ù
+6ôë'i^;çèiš ¥_S¸Ù§¦Øp@¢ZËÁË¥Ø)«ßqã1­‚?jöÎû9s È+‘±ö™õ¨ôo\¹ílM\lØ#}®=ÿ íEÏÅAòTŒæ&sî¬Á½é$À¦Õ¯¿œb¥Œ+2ûŸ]5_õH¤ÆC r¯sµ¢ýÏù-ópÔ€÷\Œü£ZáºW4gdÚ;»™+€ç8Ûy4úÿ ô+¸«^BÇv~*¾šÜ†¢Ž¹ß¬¥a‡ëÞhvØÚe-ÒÖ{Ho¯v–X^¶V8@a²ÖÙuFÎñÒ¼$áØ•”$'+ì\Ì @¿îüк1ãú†34%áê|ÝÐÖ&¥äD2i@Ι$ 8W—H=E•VsÜ~º×ÊÚÑI‡óRmÐNÛÚc§ñOlÒÞÚ½)~û„ŒÃÙ᳟Hß`ÂùEybn]2
+·Ç 9Æ §Tmb …ݲbZ«¼’Òcr7@
+‡Òa–GP7ãÊÖ«rdÆ!)÷Ü÷€TÓ—b¡ùSŠ…þ³Š«:hɬT”r.î$}­+L¬{^‘iD­ÿŠ¯®ë¢€YcH]ìœ.=ªºè1Оƒ¾.+
+æ„%cg®¡7 íË:lö¿Õ¬_ëÒëúHÎœr¤>s™u@:Ò§YöMË œŒ“¹ÌÚ Êùr]NîG2/M¦ÐéH^y=œe|»šûí“i´:”Ö^–6üÕHJÚÉÚÆ‚º,­ÑLh¤¤L“=С´8H»{R9zRúæËbgV2’vM…÷§Í1¬µ
+endstream
+endobj
+1784 0 obj
+<< /Type /Page /Contents 1785 0 R /Resources 1783 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1724 0 R >>
endobj
1786 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 1784 0 R /XYZ 78.37 808.885 null ] >>
endobj
1787 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 700.141 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 768.829 null ] >>
endobj
1788 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 689.182 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 719.016 null ] >>
endobj
1789 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 678.223 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 708.057 null ] >>
endobj
1790 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 667.264 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 682.154 null ] >>
endobj
1791 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 656.306 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 671.195 null ] >>
endobj
1792 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 645.347 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 633.337 null ] >>
endobj
1793 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 634.388 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 622.379 null ] >>
endobj
1794 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 623.429 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 611.42 null ] >>
endobj
1795 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 596.595 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 600.461 null ] >>
endobj
1796 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 585.636 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 589.502 null ] >>
endobj
1797 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 558.801 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 578.543 null ] >>
endobj
1798 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 547.843 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 567.584 null ] >>
endobj
1799 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 536.884 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 556.625 null ] >>
+endobj
+233 0 obj
+<< /D [ 1784 0 R /XYZ 79.37 533.168 null ] >>
endobj
1800 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 525.925 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 491.405 null ] >>
endobj
1801 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 514.966 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 480.446 null ] >>
endobj
1802 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 504.007 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 469.487 null ] >>
endobj
1803 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 493.048 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 458.528 null ] >>
endobj
1804 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 482.089 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 447.569 null ] >>
endobj
1805 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 471.13 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 422.662 null ] >>
endobj
1806 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 460.171 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 411.704 null ] >>
endobj
1807 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 449.212 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 400.745 null ] >>
endobj
1808 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 438.253 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 389.786 null ] >>
endobj
1809 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 427.295 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 378.827 null ] >>
endobj
1810 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 416.336 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 367.868 null ] >>
endobj
1811 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 405.377 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 356.909 null ] >>
endobj
1812 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 394.418 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 345.95 null ] >>
endobj
1813 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 383.459 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 319.051 null ] >>
endobj
1814 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 372.5 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 308.092 null ] >>
endobj
1815 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 361.541 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 281.193 null ] >>
endobj
1816 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 350.582 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 270.234 null ] >>
endobj
1817 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 339.623 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 259.275 null ] >>
endobj
1818 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 328.664 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 248.316 null ] >>
endobj
1819 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 317.706 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 237.357 null ] >>
endobj
1820 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 306.747 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 226.398 null ] >>
endobj
1821 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 295.788 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 215.44 null ] >>
endobj
1822 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 284.829 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 204.481 null ] >>
endobj
1823 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 273.87 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 193.522 null ] >>
endobj
1824 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 262.911 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 182.563 null ] >>
endobj
1825 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 251.952 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 171.604 null ] >>
endobj
1826 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 240.993 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 160.645 null ] >>
endobj
1827 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 230.034 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 149.686 null ] >>
endobj
1828 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 219.075 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 138.727 null ] >>
endobj
1829 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 208.116 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 127.768 null ] >>
endobj
1830 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 197.158 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 116.809 null ] >>
endobj
1831 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 186.199 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 105.851 null ] >>
endobj
1832 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 175.24 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 94.892 null ] >>
endobj
1833 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 164.281 null ] >>
-endobj
-1834 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 153.322 null ] >>
+<< /D [ 1784 0 R /XYZ 81.145 83.933 null ] >>
endobj
-1835 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 142.363 null ] >>
+1783 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
1836 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 131.404 null ] >>
+<< /Filter /FlateDecode /Length 1947 >>
+stream
+xÚÕZÉŽ#7 ½÷Wøš#‘Ô4 ´Ûí
+oñ:_ šx^Ë3”ÿ¯Q ŽøRñ]#=âËŸÇùR
+Wµ¨Ñgôoe1^‰è­Uqç×üUÛܤ‡ºk ómÑ
+€m…SÙŠ–;ÈÍ)´þ&7¢éž¶‰mΖ„MŸéÒ£eñkÂh /³»µ;’Ü |«*q<R )µÕ)¹(&·7ª 5ĶtÓ2¾Ïø¡!(” M÷ÔŽ÷]]ÙÚt‰†ÏZOw¤';nw$Žä*;äÀÎãÖ|å€ËfH•ð±TF¤{Dã…‹Š}
+Ø[Ì5¬€¶ò·kóÑ\2Þ1â›1ñ+À°AB®ÉÅϱªUXûb,Õ2ÅŽýlgjä
+endstream
+endobj
+1835 0 obj
+<< /Type /Page /Contents 1836 0 R /Resources 1834 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1724 0 R >>
endobj
1837 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 120.445 null ] >>
+<< /D [ 1835 0 R /XYZ 78.37 808.885 null ] >>
endobj
1838 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 109.486 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 768.829 null ] >>
endobj
1839 0 obj
-<< /D [ 1779 0 R /XYZ 81.145 78.635 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 757.87 null ] >>
endobj
-1778 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-1842 0 obj
-<< /Filter /FlateDecode /Length 2027 >>
-stream
-xÚÕ[KÛ6¾ï¯ðCÎð , Øk»@Ï{+zmOýÿ×røHŠÞÕx4E Ä’¥OÃoÞG
-søû ãß¿½œß_¾ßL8h¼B8¼ÿõ¢2þQÂꃳJH«ïÿþx•Ò@>ìYJ}=þùþû‹$°õýæõÁ‹`-úGI'PÈ.?Ýó‰$F
-%a#ÉIJÖp?¡4Îî7°KòàD
-T>èsEw6£`}ãu&—RðBŵO(²gžr{$°\I”
-g܈D¼j›y#înùº‰f.flýDZÕEFµ÷Øå«fúZ°ØF/­
-/ÕT=i,Œá5LDNc1
-5ô Í­q¼¼¨CbÁefÊ/·Œ›²xø×=\3"»f¦Š½y´ª¢G‚Saæ¼rž²](Ì2ÿtŽ·ã7Ê®EE—¬[2ØåZ%‹)¢’ÉŠøË "ÊŒã½ù¸r< aP®D©s¶¤ÔŸA¶mTægs»W´ÍV/¢óM)åmGŒH|JÑnX{'¤÷3ŠdG¤]º”>™\íÖvп–!~$-Ÿyë/Sæ=ùé)ÌÿªöjM¬Z§mx¤u@i%—\¸UN\qâØòÿ  m´
-D˜FÃIkÐ
-:†ð¢àTxÍsœ‰„TPB«ylBVîï
-¿YL~ÙL t“¡|Óì¹×ìA´Ls ZÂRñ’r|:Ðæ£ÙÅoöºRiv[ãÞvX¨ÐfZPí
-endstream
+1840 0 obj
+<< /D [ 1835 0 R /XYZ 81.145 746.912 null ] >>
endobj
1841 0 obj
-<< /Type /Page /Contents 1842 0 R /Resources 1840 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1731 0 R >>
+<< /D [ 1835 0 R /XYZ 81.145 735.953 null ] >>
+endobj
+1842 0 obj
+<< /D [ 1835 0 R /XYZ 81.145 724.994 null ] >>
endobj
1843 0 obj
-<< /D [ 1841 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 714.035 null ] >>
endobj
1844 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 703.076 null ] >>
endobj
1845 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 692.117 null ] >>
endobj
1846 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 681.158 null ] >>
endobj
1847 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 670.199 null ] >>
endobj
1848 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 659.24 null ] >>
endobj
1849 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 648.281 null ] >>
endobj
1850 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 637.322 null ] >>
endobj
1851 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 626.364 null ] >>
endobj
1852 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 615.405 null ] >>
endobj
1853 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 670.199 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 604.446 null ] >>
endobj
1854 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 659.24 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 593.487 null ] >>
endobj
1855 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 648.281 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 582.528 null ] >>
endobj
1856 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 637.322 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 571.569 null ] >>
endobj
1857 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 626.364 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 560.61 null ] >>
endobj
1858 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 615.405 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 549.651 null ] >>
endobj
1859 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 604.446 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 538.692 null ] >>
endobj
1860 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 593.487 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 527.733 null ] >>
endobj
1861 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 582.528 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 496.849 null ] >>
endobj
1862 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 571.569 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 485.89 null ] >>
endobj
1863 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 560.61 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 474.931 null ] >>
endobj
1864 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 549.651 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 463.973 null ] >>
endobj
1865 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 538.692 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 453.014 null ] >>
endobj
1866 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 527.733 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 442.055 null ] >>
endobj
1867 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 516.775 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 431.096 null ] >>
endobj
1868 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 505.816 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 420.137 null ] >>
endobj
1869 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 494.857 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 409.178 null ] >>
endobj
1870 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 483.898 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 398.219 null ] >>
endobj
1871 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 472.939 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 387.26 null ] >>
endobj
1872 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 461.98 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 376.301 null ] >>
endobj
1873 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 451.021 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 365.342 null ] >>
endobj
1874 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 397.305 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 354.384 null ] >>
endobj
1875 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 355.544 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 343.425 null ] >>
endobj
1876 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 344.585 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 332.466 null ] >>
endobj
1877 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 333.626 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 321.507 null ] >>
endobj
1878 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 322.667 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 310.548 null ] >>
endobj
1879 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 311.708 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 299.589 null ] >>
endobj
1880 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 300.749 null ] >>
-endobj
-237 0 obj
-<< /D [ 1841 0 R /XYZ 79.37 264.241 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 288.63 null ] >>
endobj
1881 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 221.1 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 277.671 null ] >>
endobj
1882 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 210.141 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 266.712 null ] >>
endobj
1883 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 199.183 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 255.753 null ] >>
endobj
1884 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 188.224 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 244.794 null ] >>
endobj
1885 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 177.265 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 233.836 null ] >>
endobj
1886 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 166.306 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 222.877 null ] >>
endobj
1887 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 155.347 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 211.918 null ] >>
endobj
1888 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 144.388 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 200.959 null ] >>
endobj
1889 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 133.429 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 190 null ] >>
endobj
1890 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 122.47 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 179.041 null ] >>
endobj
1891 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 111.511 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 168.082 null ] >>
endobj
1892 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 100.552 null ] >>
-endobj
-1893 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 89.593 null ] >>
+<< /D [ 1835 0 R /XYZ 81.145 113.288 null ] >>
endobj
-1894 0 obj
-<< /D [ 1841 0 R /XYZ 81.145 78.635 null ] >>
-endobj
-1840 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
+1834 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-1897 0 obj
-<< /Filter /FlateDecode /Length 2434 >>
+1895 0 obj
+<< /Filter /FlateDecode /Length 2450 >>
stream
-xÚÕ[ËŽã:Ý×WäJ-‘Ô $•d€Y×îângVóÿÛÑ[²¬¸¬$=÷n'ŽM“‡ä!E»8“‡¸ûÿ—ï_wiĬ‡ï}ˆwÿÄÁ
-UßD’õ=°ú=¦²˜!õª ÕÌ ×t̤ȽÔcþœW ÖÈpˆ4âÒ A:!­™ÄßÒ…M.·W QÀ‡í!Ýæ0YJÊé˜éÅïsà¨{óùZËÖ¸Ö‰¸©[D3 Ì‘^Ðõy
-Ոɾ½“äu'¨ñãC#Û ù+ÛŽšEZÅ”ÖCPæzøN’úZ.¼Ârüšø´(r¬ã%Õ/s§M1’ia†>×O÷’°ò§ÔÀv´.›VYÓÈœlj;AMÈ>ðqƒ¹-M‰Škj[C|TT(!‹sÿ{K~=c¥Bf¸ç\+ÚKÚÐêú Ý‚”À [­É^³“‰jU¢¨ €ŸŸ Kœº6)Üx˜R3š 43fÑ ©²TÜgžc_tfu’ ú«Ý…<Xw¸›5WiËÐAN1Rm…©›$‹ÇÚ"*ˆ9N–Žåècl¸È”v<ÞSÓèž®Õb©¿ë é¹e! 1ÁU· ñܼ¥+Hɸ‘Ï麩
-Ó‰ûÔâθFL}(F?€[fƒ9f×x'”j¹Z
-4¥÷žÏŽNLâÄ‹ªÁ‰írÃË‹ë¬|óîwÊgHÙ^ Û.ÐœÑÖŠê„S°Fó“TǺÁ£
-¾&“?‡IÕ¹&ÞÒ ÒÝ‘j`TM¦óî5.ñ’¯£ÆÈ8ôÍ×51œ%…ÈIŠ„rsmç7ÙË“‚]Ʀüò8µ÷xbày.¯ÍáÊGˆ+å£>ªtH‹Œvþ¥ÆšÛŸ®ïîœìH
-—7ýMJD@6¥ ÂâódS‹­˜x4T²;uÜ!÷’Ö¹#Íû
-.ÅØó\È/ÍëáÖeRÂHœÌ½¥¤ùÜsr¤Å¡&f.÷–’òkù ¿G5@ÓÞ¼ªÒtÝÝòðL·Ïæ/õ¹ ®ûÒÇÜútÄ ÉÒ0ää¾KIC‹›ÊÞ¹D ˪Á¼ëKÃäÙWÉy^䙆Jó«<ßxINLi9D’æXq)i;ŠÚ˜íq uáëL›+>¯ÞDó¡äYt…E¦…ò
-úá•/?.RRˆ3«KEŠú.¼}ü?›;©
+xÚÕ[Ko+©ÞçWø„U<%+RÇWºëì®f;³šÿ¿½o0¶§s4££>ŽÛÝõQ(8S‡¿ÜÿÿŸ—Ó×˯‹rÉœ‡¯?_Äûâ`iy0Z0®ÅáëïÃÿŽœ+ˆ—–œ#¾ýñõßN¼¨_+–9­Ñ¶rœaì(¼
+™¤g7¿ä§
+¿§lf#Í, ô’¤Š`§™&×Q8ÛÕŽ´ŠW¶§ÞŽ€1ÉŽRT•P#ò³°ÎO‰ÎV:šaë%݆-&ÇâžçJs4'ʨ9´Êgbyź¨ýE~=H"žÜòÁ
+0Ì¢)¾ÈºIyÕ.÷“R;žvr‰ÌròLm—ðjXã¦@¬qçAÒˆ:S 9è´SÐÜ
+ß Òý´ëáÊ÷Õ&Ôª"à4C3Méô( k4Èõi¡JàjV¶Üe«˜vyÕŽ’š<G!ì¬dbš-$×D\¾ÜJªdðâÌ€S=ß F2)pjk\t”´   ¡ëØhdRÉ©Òk\sŸµ0N€›¥
+úÜ8q3ÂòÜVf®ª§€I§§FK•Eƒ¤R“w¯ð P1¥Ü¬ðMºP¢Öîp:º+›r3s«ØÎÈY›žj1ƒrlõîyOC@É×ck¹l.wû
+J^þT_ïö 0Ÿ®°O'ÄŒs³ÓâRàk¨¿‹CCƒP²åÕT ¯"ŒOÇALâbE`ªê3Ç~ºAòrmclüÆp‡úÁø„RMÀ‹ée04@¦k½‹øHµŠüMécÝd+
+ ¾ç¡nÃúYÒ ÞÆ¡gåï(+Kº—3j­e74±Id†;UÁØ5†0=w©v‰§üžl”Œ‹¾ù½Æ†³¤`9©#!ÝœûÚÍ8Ê“‚]ƦürÛµ·ŒÄdä…ðq®˜ùÕÅúÕnŒJªŠÀáe¬€­¶æ??ʘ^·.2S+{eªs4ƒ†±ÕyàBkwƒx½üÜsláTWèI¶ä}9ÿ¸ªö >Y8Áœ)Y•Æ˘'ZlÉ`âÝlPIïĸƒï¥^—¢¨\HO•Ìð‘!ßÂzniw1«•€#W-ßÛ1¹‹7íÊque7&çcO)2\ŠnóÐ=±F+˜iV[ûÈa‚:Jw¬OJ›œ#Ü­±Â•X‘¾mü±7w¿ÀÐ#øjUÐÄQÓÆÑ5ÝUµÓ8ê¶D?[¢Ÿ=6¥~  üWØ;÷1šÎðrúïælÒ>Š…B;fy%{2u94#Ž–]i{€4ŽßL³›G´(Æ:É0k‡ ¢ÛX1çZ†Y©GcXyS"ö$|f 3æX ÷.Ó–é+èʦ£Eßm–3¸'Î1O ­š®m\½LçA4Ãi)
endstream
endobj
+1894 0 obj
+<< /Type /Page /Contents 1895 0 R /Resources 1893 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1724 0 R >>
+endobj
1896 0 obj
-<< /Type /Page /Contents 1897 0 R /Resources 1895 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1731 0 R >>
+<< /D [ 1894 0 R /XYZ 78.37 808.885 null ] >>
+endobj
+1897 0 obj
+<< /D [ 1894 0 R /XYZ 81.145 768.829 null ] >>
endobj
1898 0 obj
-<< /D [ 1896 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 757.87 null ] >>
endobj
1899 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 746.912 null ] >>
endobj
1900 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 735.953 null ] >>
endobj
1901 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 724.994 null ] >>
endobj
1902 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 714.035 null ] >>
+endobj
+237 0 obj
+<< /D [ 1894 0 R /XYZ 79.37 676.623 null ] >>
endobj
1903 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 632.867 null ] >>
endobj
1904 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 621.908 null ] >>
endobj
1905 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 610.949 null ] >>
endobj
1906 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 599.99 null ] >>
endobj
1907 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 589.031 null ] >>
endobj
1908 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 670.199 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 578.072 null ] >>
endobj
1909 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 659.24 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 567.113 null ] >>
endobj
1910 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 648.281 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 556.154 null ] >>
endobj
1911 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 637.322 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 545.195 null ] >>
endobj
1912 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 626.364 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 534.237 null ] >>
endobj
1913 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 615.405 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 523.278 null ] >>
endobj
1914 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 604.446 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 512.319 null ] >>
endobj
1915 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 593.487 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 501.36 null ] >>
endobj
1916 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 582.528 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 490.401 null ] >>
endobj
1917 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 571.569 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 479.442 null ] >>
endobj
1918 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 560.61 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 468.483 null ] >>
endobj
1919 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 549.651 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 457.524 null ] >>
endobj
1920 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 453.014 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 446.565 null ] >>
endobj
1921 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 442.055 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 435.606 null ] >>
endobj
1922 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 431.096 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 424.648 null ] >>
endobj
1923 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 420.137 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 413.689 null ] >>
endobj
1924 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 409.178 null ] >>
-endobj
-241 0 obj
-<< /D [ 1896 0 R /XYZ 79.37 359.811 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 402.73 null ] >>
endobj
1925 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 332.991 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 391.771 null ] >>
endobj
1926 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 322.032 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 380.812 null ] >>
endobj
1927 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 311.073 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 369.853 null ] >>
endobj
1928 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 300.115 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 358.894 null ] >>
endobj
1929 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 289.156 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 347.935 null ] >>
endobj
1930 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 278.197 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 336.976 null ] >>
endobj
1931 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 267.238 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 326.017 null ] >>
endobj
1932 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 256.279 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 315.058 null ] >>
endobj
1933 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 245.32 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 304.1 null ] >>
endobj
1934 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 234.361 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 293.141 null ] >>
endobj
1935 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 223.402 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 282.182 null ] >>
endobj
1936 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 212.443 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 271.223 null ] >>
endobj
1937 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 201.484 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 260.264 null ] >>
endobj
1938 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 190.525 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 163.626 null ] >>
endobj
1939 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 179.567 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 152.667 null ] >>
endobj
1940 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 168.608 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 141.709 null ] >>
endobj
1941 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 152.667 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 130.75 null ] >>
endobj
1942 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 141.709 null ] >>
+<< /D [ 1894 0 R /XYZ 81.145 119.791 null ] >>
endobj
-1943 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 130.75 null ] >>
-endobj
-1944 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 119.791 null ] >>
+1893 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F15 326 0 R /F74 329 0 R /F81 358 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
1945 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 108.832 null ] >>
+<< /Filter /FlateDecode /Length 2692 >>
+stream
+xÚå[ËŽ»Ýû+ô¦É*>Á
+<‚ìõ´xŸ[ù®U.k,ãNÍä{^ù¶”¦W™%p§®‰CòSm?EÖÁÅUyçõ<Ñ%ô†yløŽÐ>+Ia˜@=•¤] ‹-¥c+ªm¶—kÌ ï¿ ÓjFŒ·]\%+Þ—æ.åeéòOÌ4¨5;m)ýEs°rŠ°SyÈ%kë(ý÷eáu»ým\YÉ@¹i Xì¥õdÓ¬y±æZ®¡³¾ å© !Ýi¤˜k÷–No˜ä†¶PÂc0¼`ÑE¯Õçûæ²Ê"ý#‡l²}šÎ·(*©™äb&«³àTÖRZ†\ÊJ)a¶“³à/š¥Ao0rR–ßZ0æϊͯ
+8Ÿ›öÚÀô űɤũŽÞÖMKi?ü?§­¯/Ð>+ÌKb&ϳ0˜l¾¥ôiíÅ)­¦;\kÏu”òN~Ü…Úo.KŸ´)\I‘㈥dÌ7Í•6ªÝ~ƒ0C‡î³W0/nG¡-ÞÓSÃ_Á–_å yZ=ö wiô½ëD'Ø¢óÁÖÑ/ÛŒª“w²ÓÉÎtbw'¾3g÷zï© ™¯m#Gj:o´·ëì;FoT£‡è·ÌA
+ÒÏ¢H"DÈîç½kßý¤cF— €Km.*v`xHcHŽ„‚˜‹éÙÃ0 “nØI– *xÙj%%+§Ì†F¤ ¾ÕŠ.âhLï Á|Ì
+2¯r`@%¦Z¨©ø•’¬¡^\qG/y ¥¢áÆ_“мƒÕ¡¦98;ý$š8)fyqÒú¬ “#ÅÀTöƒt4GÖ]‚1¯:"®Œ¬l3=yàG6
+>õI¥û]Ÿ9Ó¢Þ0·B°Ži+ú•|R V²–P¥@Vº)„R+ÅIG質“ÃòZž列¾&p øë©
+H
+Åì\r à´„rýó
+z#Xb
+õÎOPk)õدãé§àïÿ¯n3
+Ã`<Ʊç/üäfsKès Çbˆ}Lp`(ô˜ÀL`ÊÚ²*¾„*Š!`ƒpŠ6p@ y\1iÜ#t€%ÏËyß
+c”9hû¨åP}x[k+×aðÆ=¯s/t”Á‚rí _JÓ÷|žw}]h[”4÷HY›©¤íZ¢o)'úYz!ÏŠºpµþRò6½‡s}Ãí4½«¥S·ŽÒúNŒ`–O½ïäù_>í}Á‹ž_¨GD£ÆW>×Å«9³rîr¸¦è–ÒòýR!³vjr‹Ý¿ŽÒôEÆãTêgN‰ú¾\l^¨á(B=ÀyÎvÑfŠc”|”nã¼&Ý*y&ÝÆyGé–Ú1±¦\ßSÓ6FâúÞžœ7]¤I Ý­$¯ô¤¹ÛÁÍ#KØöT­8¶Œp朮/?Åw¬2"%¨s"],C!8óëýÕrk¶£ÔݮҽºÒD¹Z–gk®àyOÇ3ç7vÆøâ»’-¡u¾g/ãý‹_í³–‰ñ%Hèl3%ü–ÐÃs"¿x¸ Þ@-b­ðÄÇÏovk¡P
+endstream
+endobj
+1944 0 obj
+<< /Type /Page /Contents 1945 0 R /Resources 1943 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1724 0 R >>
endobj
1946 0 obj
-<< /D [ 1896 0 R /XYZ 81.145 97.873 null ] >>
+<< /D [ 1944 0 R /XYZ 78.37 808.885 null ] >>
endobj
-1895 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F81 366 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
+241 0 obj
+<< /D [ 1944 0 R /XYZ 79.37 771.024 null ] >>
endobj
-1949 0 obj
-<< /Filter /FlateDecode /Length 2751 >>
-stream
-xÚÝ[ÉŽ9½û+ô¦Éà
-(•¤æ\·Æ\§Oýÿ×áÜ•™”¥6܇²¥L2ŒåÅBŠžþ:ÑÓßÎ_ß~ܘ<Yb(qúúß7æ^Ð;iK¸>iÅUìôõ÷éÏ7Js—÷ï’I÷M
-JÙ'¥Šº?ëÞ
-’ÒSΠp3wÇõ‚k…‚4 xîo¸æ©Ý¢Ÿã·§,Š"ŠÐ½õJúqÓbÃý¸&L÷ûlÍEz:jkq Ê1p–ÄœMÏ$>æ0À¬&VØ“$.!™º7ÿ—2BáW–Ì«%\Äâ˜Þ¼!Hêßhön —lª…šŠ[)ÊêõÇïè%­!e0Üð6:
-L!UÏ5x
-ÁX¢ ëWrAÅ[‰ŸI‰ô1Íýû‡£"íIk‡šŠâÈj&ð „ÒsvŽœGZ):þ¸q2ŽÅMMÇ»˜žßv 'x-à ÓwÄUÉŠ#¢À3ˆ|ÆgÁ‘<¾ƒÇwPø)<ße­®øéEÀü鼎7BXUå´™)D\)„QM¸€ž¨M£Š.§Œqÿe“òR9ÒÇ{hçÚôî£ì[
-<&ý.ÙCÌEü(SÃe˜4Ìâx)Þ¿®qSÓœ˜àÄqyep\N_; ŒO¡Ï+Lh®G+.Ñza®›Ý¦Âx¼‘ý*}fRwÓŠ¾8!¦œiÞ­’¼2%b­´ãê<ªT
-è# xÇ,gÍK”’D”L<{ɇ[Ñó×ZêžRA`Áz@¦T= GE-âÈ8BñhéäéDY¡W7º€÷f0¦«F@«dúÙ# C6£c `6Zw¦Ÿ´ >ÅÔH)³bàÈ3îd±‘Â^›¨&?ˆß|†œž«>gêgÕE‘žEY|S¹ î„ÌÐ ×®4øž«½8ÐoS/²H&;æĹ!ŠŠ€Ñ{hx2Ú¸#ƒ>¦,#/ê³õ÷Ÿ€=à@€²~Ÿ U *î£K@Z•°KõV
-&¬NÓÞ9yùë6SAÔGg  Ô|Mî¥çÇ
-Ví¨tÔʽ“DÙY ìñh kõ©7?WÎgŸ˜~O¤çSä‚Å9<˜ (Ù§äjeämº×ÒD‹Í¬h{þ;Çvѵ$©³5†0º¨-ê²:>M9Ôù˜ºœÍ0 =¥ç¤‹ûX2!]åi`3™àC2ÁcÔUõ=d± è3Þd|šmð!KHãšÇíe<Çy1/sÂû’—6ožqnâ@&{E¿€v‡r#ÙÒa8,˜‹079hi´TØûRkbtŽ£{NVÝÀ4
-º°µ~+ù?á…‘¨Î"<_:xë(­s"]Å1o <Lg²¡ ìÏ*É»¦Žä
-é%ÔïLÊõÙê°ÕBQÿ¹ºª~Q=ø¤Âœtí¢ŽfÖ(•–Ò–T0
-endstream
+1947 0 obj
+<< /D [ 1944 0 R /XYZ 81.145 745.452 null ] >>
endobj
1948 0 obj
-<< /Type /Page /Contents 1949 0 R /Resources 1947 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1731 0 R >>
+<< /D [ 1944 0 R /XYZ 81.145 734.493 null ] >>
+endobj
+1949 0 obj
+<< /D [ 1944 0 R /XYZ 81.145 723.534 null ] >>
endobj
1950 0 obj
-<< /D [ 1948 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 712.575 null ] >>
endobj
1951 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 722.005 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 701.616 null ] >>
endobj
1952 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 711.046 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 690.657 null ] >>
endobj
1953 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 673.23 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 679.699 null ] >>
endobj
1954 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 623.458 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 668.74 null ] >>
endobj
1955 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 612.5 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 657.781 null ] >>
endobj
1956 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 574.683 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 646.822 null ] >>
endobj
1957 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 563.724 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 635.863 null ] >>
endobj
1958 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 552.765 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 624.904 null ] >>
endobj
1959 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 514.949 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 613.945 null ] >>
endobj
1960 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 503.99 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 602.986 null ] >>
endobj
1961 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 493.031 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 592.027 null ] >>
endobj
1962 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 467.338 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 581.068 null ] >>
endobj
1963 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 456.379 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 565.128 null ] >>
endobj
1964 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 445.42 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 554.169 null ] >>
endobj
1965 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 405.653 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 543.21 null ] >>
endobj
1966 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 394.694 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 532.252 null ] >>
endobj
1967 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 383.735 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 521.293 null ] >>
endobj
1968 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 358.041 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 510.334 null ] >>
endobj
1969 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 347.082 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 434.618 null ] >>
endobj
1970 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 336.123 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 423.659 null ] >>
endobj
1971 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 325.165 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 385.801 null ] >>
endobj
1972 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 314.206 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 335.987 null ] >>
endobj
1973 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 303.247 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 325.029 null ] >>
endobj
1974 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 292.288 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 287.171 null ] >>
endobj
1975 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 264.643 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 276.212 null ] >>
endobj
1976 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 253.684 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 265.253 null ] >>
endobj
1977 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 213.917 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 227.395 null ] >>
endobj
1978 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 202.959 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 216.436 null ] >>
endobj
1979 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 192 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 205.477 null ] >>
endobj
1980 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 181.041 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 179.574 null ] >>
endobj
1981 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 170.082 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 168.615 null ] >>
endobj
1982 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 159.123 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 157.656 null ] >>
endobj
1983 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 148.164 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 117.806 null ] >>
endobj
1984 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 137.205 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 106.847 null ] >>
endobj
1985 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 126.246 null ] >>
+<< /D [ 1944 0 R /XYZ 81.145 95.888 null ] >>
endobj
-1986 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 100.552 null ] >>
-endobj
-1987 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 89.593 null ] >>
+1943 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
1988 0 obj
-<< /D [ 1948 0 R /XYZ 81.145 78.635 null ] >>
-endobj
-1947 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-1991 0 obj
<< /Filter /FlateDecode /Length 2018 >>
stream
-xÚÕ[Moä6 ½çW̨V¢¾E€u¦@Ϲ½¶§þÿkEY²d'1¤M±ðŽ?Ÿ¥'Š|¤­ü寋.ÿÿút}}úvóùâTNÆÂåõÏ'sÑ培$PÁ]b0Jsyýûòûw­=h®eó¸=ÿñúÛ“F°õí–Ü%©‚M3Ž1AE)¸‚PÐlÙ<"¾”}üÕë9Wö½Ñ:¶c¼n~–óiÝ
-
-œ6”ð,S?dL푸d‚Úê¶ø×ewªs
-V«‹Ë°é,Ï÷ØBàzleÉ+A¢¶NÃ[ %0ªëØÃÙV8šKsRêýX&ÜÒý´†¼î¨·¿-ŽÐ¦EÎjgaõ>âdVQG–E™%H}¥°ÚL³âe¿d;Öæï|çƒÕG<Ï«Cã÷žø¾¼òVá–÷îx ïDHµUt‰É^æ}÷Hò8`¬Jšo‰…Ô=ÐG…TgFg[ž4øpSçC¡•\f§‡• ÆI
-!•Ø† { hö•/{AªOQšÎîÿ´û†¤U¶{-üµš¸öHÞÊüË”‘Ò¬„¹’´FyžÁUŽÀ1(¬1¤
-L‚´}5çö=ì˦uŽd~¿{®Qp=ë‘<.¸×;¡ø#H_Nü‡ à–ë©Pü$±j1”×|KDâ
-é´Êãc›6Û|y}úÈÜHì
+xÚÕ[ÉŽã6½÷WøÂ!‹;` ÐjÛrî[krÊÿ_ÃU\Tîfy<˜4ÙõH¾*V½¢ÔœéÓ?'þÿýe{ùvÓþ¤˜wBÂéýïqâáŸ89`F¬Œqzÿ÷ôç™s œ›-|tø¼~ÿëýÁÔ·›S'Ǽ1Òõ8Þ2n>(^9WÎeønËo®Ž"}¾–Ú×ï·ðy ÷½å¶êòý7 º"‹ü‰Hñ.åò]â-£¦Ã9e>Ÿ“6/y4µ·Ø&Ž"ž‹mS¯{oêIÉDt¼~BªæLpÀH•~‰TÁ-“
+f$0Ô‘HÏ„’èHÜÚH„aVÛ©Úc9~—åwµáh¿xWjùß²…“í®ê~§™¬RÏ[*+à˜ÓÅœ^ÓX‘>b%ÎSo^ñŹ·'0·¸fVÖGšK['Dæ…e
+^$£Cé[-ÒjÈ€è -[žR.×h5£MHô‘pÉ8xl$‹EN*Ð×*O'Ê;Öý‘¿E¡W-9‘“˜r‚ ºÔªH*ÒdBúùÕùÓ¶¸”åLhÀ8 ʳ éëmlý‹Ú3á%Ê¢£¹ôˆ´TÕ+É™ä«ês}†Uõ©ê[5w¯ªo-°ª>_mV¬gúŠ¹œ!TìmŸ¥Åq¶­>]Ñ΃mq}í ¶¾&þÌçÈ°>ù
+Çâ: ƒ$Ú' hM±•yËÉ7mW_ó1y²A*¿’nl«ˆ[u­æêúØd©Ø·¶]û x 0 Žr¤†¨Ç'¤qßA• T}?®ýš\k~øèYî}VºÝ&èÞr+që¹.¼ÛµØÆ‹Ø~©'2ËÜ3ÀI~vússð!ËÝØ^’IN@˜%z=Ð,ð¿¶{pÁ?- dÒäù„DV`CuÚ;,Rý­ÄŠ,ÖÝïôýòLk„6ºdzEeÁh¦´BY ½O2!­°Psì#,€Á÷>ÁŽØéñZùî»[RÅëTö´bÊÔ›iêrBJš¦ÎÊt³¿v
+¯ãƒí£¶Á<%xH—·LÇh+Ä~†ßR™U’i‰*$¢Zœ’ß(Üo¢ú·æ»ýÌ++{uÆì`y”\z‚¦í(^£.$kà iI—Ì8ó‘6 Jd׆ýþ†“gŒ¦zEõâfA][Õ÷ ò¯ao _/¯ë…ú?©Ï¸8ºçû4ªE($ÀŒjš€æšk-Ë#¯®È2ÙÃö :žñúú,eQ|ðN–еîOõÌÃ9\„šC‚Åh#ªÔ ‰œÃ…QLt­·'$€‘ùÇJ\«z¿F
+‚ÊÁ ¦½>!}æE=óì©Ö¨ªÁšÒ®ä=« Ë—¦•¶µìßmV ·ÃI±ïÖÎ¥úò½%Bů< ë¦Ù'¤êƒi߀O‰ªc|Ïî]æOŸÑÉÙ^„:]K‰Îˆ¶S:!Ñ£:WL{t$‹Z¶&ÃèYÉÐÔk¦… Í «LŽÎWE/Ôê>VZ Há`D[y!=œ }ÐPRaLߦÈé1þoõ<Žx´´d0ÍÉ 'sêÿ䢷оܟ›
+š=Qô ñrß b{(iZÁ¬0O«¯JïSÑaeÄì¥ûs¿’$k8틯´±xiÞ\å4ß{O&Á‡IjsRœùV H·G˜ëûË«—,ø
endstream
endobj
+1987 0 obj
+<< /Type /Page /Contents 1988 0 R /Resources 1986 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1724 0 R >>
+endobj
+1989 0 obj
+<< /D [ 1987 0 R /XYZ 78.37 808.885 null ] >>
+endobj
1990 0 obj
-<< /Type /Page /Contents 1991 0 R /Resources 1989 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1731 0 R >>
+<< /D [ 1987 0 R /XYZ 81.145 768.829 null ] >>
+endobj
+1991 0 obj
+<< /D [ 1987 0 R /XYZ 81.145 757.87 null ] >>
endobj
1992 0 obj
-<< /D [ 1990 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 746.912 null ] >>
endobj
1993 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 735.953 null ] >>
endobj
1994 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 724.994 null ] >>
endobj
1995 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 718.02 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 714.035 null ] >>
endobj
1996 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 707.061 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 703.076 null ] >>
endobj
1997 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 696.102 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 675.181 null ] >>
endobj
1998 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 685.143 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 664.222 null ] >>
endobj
1999 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 674.184 null ] >>
-endobj
-245 0 obj
-<< /D [ 1990 0 R /XYZ 79.37 650.728 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 624.371 null ] >>
endobj
2000 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 629.885 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 613.412 null ] >>
endobj
2001 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 618.926 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 602.453 null ] >>
endobj
2002 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 607.968 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 591.494 null ] >>
endobj
2003 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 597.009 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 580.535 null ] >>
endobj
2004 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 586.05 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 569.577 null ] >>
endobj
2005 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 575.091 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 558.618 null ] >>
endobj
2006 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 564.132 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 547.659 null ] >>
endobj
2007 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 553.173 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 536.7 null ] >>
endobj
2008 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 542.214 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 510.797 null ] >>
endobj
2009 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 531.255 null ] >>
-endobj
-249 0 obj
-<< /D [ 1990 0 R /XYZ 79.37 505.806 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 499.838 null ] >>
endobj
2010 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 484.964 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 488.879 null ] >>
endobj
2011 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 474.005 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 477.92 null ] >>
endobj
2012 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 463.046 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 466.961 null ] >>
endobj
2013 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 452.087 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 427.111 null ] >>
endobj
2014 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 441.128 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 416.152 null ] >>
endobj
2015 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 430.169 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 405.193 null ] >>
endobj
2016 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 419.21 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 394.234 null ] >>
endobj
2017 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 403.27 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 383.275 null ] >>
+endobj
+245 0 obj
+<< /D [ 1987 0 R /XYZ 79.37 359.819 null ] >>
endobj
2018 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 392.311 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 338.976 null ] >>
endobj
2019 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 381.352 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 328.017 null ] >>
endobj
2020 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 370.393 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 317.058 null ] >>
endobj
2021 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 359.435 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 306.1 null ] >>
endobj
2022 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 348.476 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 295.141 null ] >>
endobj
2023 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 337.517 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 284.182 null ] >>
endobj
2024 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 321.577 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 273.223 null ] >>
endobj
2025 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 310.618 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 262.264 null ] >>
endobj
2026 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 299.659 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 251.305 null ] >>
endobj
2027 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 288.7 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 240.346 null ] >>
+endobj
+249 0 obj
+<< /D [ 1987 0 R /XYZ 79.37 214.897 null ] >>
endobj
2028 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 277.741 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 194.055 null ] >>
endobj
2029 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 266.782 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 183.096 null ] >>
endobj
2030 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 250.842 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 172.137 null ] >>
endobj
2031 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 239.883 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 161.178 null ] >>
endobj
2032 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 228.924 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 150.219 null ] >>
endobj
2033 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 217.965 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 139.26 null ] >>
endobj
2034 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 207.006 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 128.301 null ] >>
endobj
2035 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 196.047 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 112.361 null ] >>
endobj
2036 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 185.088 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 101.402 null ] >>
endobj
2037 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 174.129 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 90.443 null ] >>
endobj
2038 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 163.171 null ] >>
+<< /D [ 1987 0 R /XYZ 81.145 79.484 null ] >>
endobj
-2039 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 152.212 null ] >>
-endobj
-2040 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 136.271 null ] >>
+1986 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
2041 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 125.313 null ] >>
+<< /Filter /FlateDecode /Length 1935 >>
+stream
+xÚÕ[Moã6½çWøt–~E8v
+ôœ[Ñk{êÿ¿–¤H‰’îf±ðÚ+ÉO䛯7#¯wúç¤òß¿?ßž¾½ºt²¢6xzûûIŸTþ£OÁÛSð”ק·Oþª”C¥üs{?ÿö×ÛOª€e¨o¯Ñž"$ïMq´ö\ H>*e^ó+#éü®_”
+jy·ù˜Ëg4Ëç~/wNùZ¿÷F>¼^ë\úlçËwœ]îÝñMÃ,×â¹}W/XØÖX>»ü¾”óËÎ"ßaÑ)Ð
+YŸe,ÎHh——]YÜØñ×üº,ÿ.«/«¶/ Ëë·_º†`ÎË7P/¯úí<×ëvw\Ñ|ÿ´ò}Y8ÌœõkÂþj¼¼wÅ=¼Ìd”ZÄ$ÐÖp1é1‹¨
+0R êƒAí¹¹C3v!²5t÷˜Ýb%ÞêåÜœÍð‹ògßpü`>!­eÃÃÉŒ1#å]W¢4`tìJ¬,Pg¤ÐÒ‰klš–fÆ íiÇÊlqðfQ+ÜQŽa0èY÷2¢¤œ‰–$Ù’kMœÍÜuIÜËñ1ñ»¬ \—?«~:œï h:6$«ÊðuÁ1Câ.ïÇ Œƒö*cpFê%°–­Ä³Q¢³—ÃZ_·’U¯o]Y×ÛnKtŠ“¢÷¬Št§>ãYR$HâŒà‚õìJJ’"ú¬¤èû9¿Q¥AÍXBº›§ž›2)×åeÕÏ%XÊšVU¢Êú'Vo58•8UoÝ 3’8±z“¯rìBdh’Ø!‡Ã yäi@'pIs[xT1ô-ÌHT s ñ˜¿x?îø£ ÕJÛ_nó~<ѪÞ Ëp”1<#í5(S´@ÓRV¿,é¸Ç­¸1¿¯²ìrfôÁ²¡èD,¤Ö]¹˜×£ùä"m©ï ÚB·º4»cïZ»Ç¡ãºl™~d¢ú@³e±yakí³ÔÞGü€Õ} Fgó™ñ^åxH\pÝGÊ~p™;ÏF­L`¤ÎdYù¸Ã*•ZDtÙ4w†[îò—Š?ç-„¸Ý ÅAúrâÏ9Ñì%׳Xü$±jq&@LìJdâ
+}÷e*vO¥qä^ºOcÁjÍF­ìÿY$qÕÓ:‚ üJ¬D ïõŸÙ]ÿB§ÓÈzžL­$qñOœ3ÜB„ó¶HÆㇾ¸}—ì­xž6=šÜìërÓïö#›`ÁÇíW¨Øf {ãè¯ÞÛ¾×qá`dóÌèÛ«v§”Iâª7ÒÊ4Ï;²
+RX•ËÐb]ßžþÄW
+endstream
+endobj
+2040 0 obj
+<< /Type /Page /Contents 2041 0 R /Resources 2039 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1724 0 R >>
endobj
2042 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 114.354 null ] >>
+<< /D [ 2040 0 R /XYZ 78.37 808.885 null ] >>
endobj
2043 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 103.395 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 768.829 null ] >>
endobj
2044 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 92.436 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 757.87 null ] >>
endobj
2045 0 obj
-<< /D [ 1990 0 R /XYZ 81.145 81.477 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 746.912 null ] >>
endobj
-1989 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-2048 0 obj
-<< /Filter /FlateDecode /Length 1932 >>
-stream
-xÚÕ[Mo#7 ½çWø”+QÔP,Çqžs+zmOýÿ׎4£‰C'æØÅv±ðú#“gê‘|¤8Šúûd¦ÿ{9¼|»ú|"ÈÉ:<}üõbOfúgO !Ð) &ØÓÇ?§?~5Æ£1áu~¦÷ï~üþb
-Øõíšè” ‡àRcm€è#G
-Éw5ƾM¯óô<½¦0}6!Ç0¿å[Ê#ÍòºùšzýôìÎÓóe²ÈN8fþN?ói¶®[ì+õ¬A¾Ò0áÇ|ßJMGÈ‘0j-q6ˆ–x¼Ë’!câ@HÓÃÎð>Ñ6†…Âúþ²Ð_(|›ßÓåû/}ùí°¾r³Û
-ÍÅ …v»\_°š{
-¶§Å%çÅ]q~.ï›ëËûâ¾î»Ô”¡4N¢,œuΑ¦U+-±H$ZòªK˜‰ìÌpa®²užÙíY,ž)‰²&H—PÕi‰Ò®ÊXÀä¥U¹¬[Õˆ4åÊœº—%½Ï[,ù÷MnÅR“Šr]‘“5önÄdù®ò{•´ÈË÷7¬r]“˜Æz¹¾Ø‰Ý÷ÆW.3ÆŠyÞ®©k\l´W%ûÓ/‚à ²ŸTì3$jYh¶X)¯Á–é5–höDc¯ycñËÌDÁnb]½qû‡ã3Ä .D1뼎¡©Ï¶Š¢nYMŸmMÛúÏJ ãÂVÑØ^ùõMƒ+ëçí³°°[¾¿àÝ[oÅí¡òB2Id˜T
-ËÔZ<Ñç4å‘=«<†Epk"äÙ%iZÕ3­c9\òYð&K4ÜÛ™5‡ŒHê’ÜtÕ¾6¼Þß8µÜ€¤Ôků—à^Tx¨©Ñ•°¤×P.cŠVqí T?¾µKÕË–ŠMP×N5)6ƒÏV"úξp%zD’"¶0½¶­(/bÓ
-^óF‹èVœ+s‡¥Ü$¥UÞÛʵUŽHd·"qómßfôZâ FܘiòÙK¬w~ÂÁ"ñA. jùõ“f…H"+¯ªlgHjÝñÉBtN²äÎVp‘_ôÌ݉kÃÎE·z}ZÎîjÒ3÷?‡eÚGQvܽ½[s܈¤–iï3$ÄÒõH ‰^aö©ð” ù(®ˆt+‘ÚpâËÝÄ'݇µDX·º¼&A…±¸HQßÅñÝÊ(CZ6]„”“©NÇæˆÔïXé¼ßU×b»ÄÏÊÖò9g¨*ÀÛš•4K./ÛmÏ\ylF)ž¢nAYÇQ(ÇîêÑNUnųž} ]–ØWÚåŸi÷°k™ó»o=ìCÛeõloÒWcÀd‡n²7â<«t¶À^;œS2)e0ÉJ,)‡y I]2)&°ˆ¢%ºaCúa%“Bœ´"å !q™ù,vú¹ÏvsGÊp¯+¿Zf}
-N-¹³\ºô´ÁfûYØ’#²dØöpùw9
-endstream
+2046 0 obj
+<< /D [ 2040 0 R /XYZ 81.145 730.971 null ] >>
endobj
2047 0 obj
-<< /Type /Page /Contents 2048 0 R /Resources 2046 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1731 0 R >>
+<< /D [ 2040 0 R /XYZ 81.145 720.012 null ] >>
+endobj
+2048 0 obj
+<< /D [ 2040 0 R /XYZ 81.145 709.053 null ] >>
endobj
2049 0 obj
-<< /D [ 2047 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 698.095 null ] >>
endobj
2050 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 687.136 null ] >>
endobj
2051 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 676.177 null ] >>
endobj
2052 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 741.93 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 660.237 null ] >>
endobj
2053 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 730.971 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 649.278 null ] >>
endobj
2054 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 720.012 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 638.319 null ] >>
endobj
2055 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 709.053 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 627.36 null ] >>
endobj
2056 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 698.095 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 616.401 null ] >>
endobj
2057 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 687.136 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 605.442 null ] >>
endobj
2058 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 676.177 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 594.483 null ] >>
endobj
2059 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 660.237 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 583.524 null ] >>
endobj
2060 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 649.278 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 572.565 null ] >>
endobj
2061 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 638.319 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 561.606 null ] >>
endobj
2062 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 627.36 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 545.666 null ] >>
endobj
2063 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 616.401 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 534.707 null ] >>
endobj
2064 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 605.442 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 523.748 null ] >>
endobj
2065 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 589.502 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 512.789 null ] >>
endobj
2066 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 578.543 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 501.831 null ] >>
endobj
2067 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 567.584 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 490.872 null ] >>
endobj
2068 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 556.625 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 479.913 null ] >>
endobj
2069 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 545.666 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 468.954 null ] >>
endobj
2070 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 534.707 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 453.014 null ] >>
endobj
2071 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 523.748 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 442.055 null ] >>
endobj
2072 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 507.808 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 431.096 null ] >>
endobj
2073 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 496.849 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 420.137 null ] >>
endobj
2074 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 485.89 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 409.178 null ] >>
endobj
2075 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 474.931 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 398.219 null ] >>
endobj
2076 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 463.973 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 387.26 null ] >>
endobj
2077 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 453.014 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 371.32 null ] >>
endobj
2078 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 442.055 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 360.361 null ] >>
endobj
2079 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 431.096 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 349.402 null ] >>
endobj
2080 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 415.156 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 338.443 null ] >>
endobj
2081 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 404.197 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 327.484 null ] >>
endobj
2082 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 393.238 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 316.525 null ] >>
endobj
2083 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 382.279 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 300.585 null ] >>
endobj
2084 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 371.32 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 289.626 null ] >>
endobj
2085 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 360.361 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 278.667 null ] >>
endobj
2086 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 344.421 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 267.709 null ] >>
endobj
2087 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 333.462 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 256.75 null ] >>
endobj
2088 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 322.503 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 245.791 null ] >>
endobj
2089 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 311.544 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 234.832 null ] >>
endobj
2090 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 300.585 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 218.892 null ] >>
endobj
2091 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 289.626 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 207.933 null ] >>
endobj
2092 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 278.667 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 196.974 null ] >>
endobj
2093 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 267.709 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 186.015 null ] >>
endobj
2094 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 256.75 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 175.056 null ] >>
endobj
2095 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 245.791 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 164.097 null ] >>
endobj
2096 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 234.832 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 153.138 null ] >>
endobj
2097 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 223.873 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 142.179 null ] >>
endobj
2098 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 212.914 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 126.239 null ] >>
endobj
2099 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 201.955 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 115.28 null ] >>
endobj
2100 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 190.996 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 104.321 null ] >>
endobj
2101 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 180.037 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 93.362 null ] >>
endobj
2102 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 169.078 null ] >>
+<< /D [ 2040 0 R /XYZ 81.145 82.403 null ] >>
endobj
-2103 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 158.119 null ] >>
-endobj
-2104 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 147.161 null ] >>
+2039 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
2105 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 136.202 null ] >>
+<< /Filter /FlateDecode /Length 1875 >>
+stream
+xÚÅZËn+7 Ýç+üÕ•¨7P\ ãG®³+ºmWýÿm%Íp$ÑtbN\ãñØ>æ㈤(jåOŸtùÿÛÛòñöãæóÉ©œŒ…ÓÇ_oæ¤ËŸ9%PÁb0JsúøçôǯZ{Ð:¼—‡+å矿¿é
+V ~Ü’;%•C°iÄ1:*ë€"A\¿=ó…$Î+(8œ$ïOI’£Ê(
+ø~XŸ½Y¿W¯Ím½ß°ÂúÚÆõ3åe{ímùLU,¯÷FyÏ»õ^}ïØ_lJë$Ë™Òf™Sg¤b ¡$`•ÇJ’ž“Ä}¤HOø´[²rÁIu0 lð,1½L‡)¤"ãm•“c¿®»´1ux¿2øîÞu»ŸWÆÕï7\Xï×ëpùÜn”±à¶n¿ÕØyí÷éï¶Utm.ã}õXýu©Ÿ´QNÖONæ§É™UÊjf+X}âÒf#;øp‹,hÛjúÜV­1°ü¸r.²«ÈŠ4#H6ÌÞ6çM‹ÔYƒš×ÏUv4噹õ{Q¯Ïhz]-S¯9†Wl¸t¼¶R]ÿ¬EöænÅÆ°ËúºÅíK[ÝBkƬ\Jœ5ÝU ’8N‡”¿ Ó¶-ÊÂô $ŽÒÁGå£áñ ã׌D#ÜQžàw‘~øô÷+FãЭã"oêgaé\n‘j“­EË°F.qÜ .¨`€³Þ³%ZoFj_†¨©×ØR¯«f£ÕÖ•$•Üzx>Yrí’ÏHU²fÿeóå²ÙØô Tm_5‚M£æ;ôË!mÀ©§Í³Uj3#Umvæ·Ü©{”Ä
+2öƒ±*ZÏJ.«’’Dòv»ç¶ÜLsö1í4¨Ë2YýD¾¥}‘v>•Ldµ“Ui_—¿Úõe‹ ¤nªZ…-fÖ=Nµ®«cš%­’O,+eUAz¥fNÏŸC,Œìøî1«„¬RÎœUž­Ð*3Òž‹òÑ—ášÆÊe}˜s×öpôñ¾é»>_† F3’…9ÒcÙ4±=#Œû
+nýÓÊÅòpZ k‚Dµ
+ºû¡æ¹ãÛ¨Š]8‰…uAB‰kåõòÂCP%Ò±RËj‚ôZ)WF{NJam@Å)ǯ^í”qÕLV;$¬Í‘׿Åq—­2)²l‘Õ ÙQã Ú#dØ8¿ûêäå ±’Ëò<A¢LpºgCÌv¸GiûñpTƒh„Ì2E–Ï Òhgäy“ö°¤A+Ë&$aŠv9·î—QÇ5|xM:—•õSÑÅ•"¹YƒcÒÙ¤l¶œtÂÌH‘ܽ}ãÆ7V6‡¤†¨œuœÔÂìH‘Ü¥—¡'©ÿ§}¬+rºèYMe• í]4èÑå¸?´WÞNJaF%Hílæ6t¦·¸‡ì‚å›Óf§¼¬ä²ŒI$’ÓýèØ?ß³Áò-“U>'–E²LKP£½GœûëÛušåÉfVjY–%HœÔtïØbÿâ«û<6X—ð ôH·ÆǸSyÉ>Øz­"Na’&H#—p¥üçPk³Šá.c×gaÆ&HÓÊØ|Rm¿%-$•´ã¤fp‚„§[0œñì½õ-×á)Íêâsk¢JÎsZG’ør--+‰hô€
+¬e­++I j„1‹üjµ=ñßxåpéc¬Qpß»lkMV<$œ$K˜}]éyŠq,ö¯Î}Þò¤´T1P·uÕÊÉ2âŒ$ÎÍTLŽ%••T*3Ϋ
+•V€èî ã˜.iûפlà<\È$£°\ÎyÎ@ò!x­R¸gÏ»¸·4Ý›ö„ñL‘±àúÔöÁ¨ø¸#ÙÇÇ?-šò?nÆŸrQêÙW
+Gƒ'§UŽ{ iÓî½ëÇÛ¿"UÊ
+endstream
+endobj
+2104 0 obj
+<< /Type /Page /Contents 2105 0 R /Resources 2103 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1724 0 R >>
endobj
2106 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 125.243 null ] >>
+<< /D [ 2104 0 R /XYZ 78.37 808.885 null ] >>
endobj
2107 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 114.284 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 768.829 null ] >>
endobj
2108 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 103.325 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 753.01 null ] >>
endobj
2109 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 92.366 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 742.051 null ] >>
endobj
2110 0 obj
-<< /D [ 2047 0 R /XYZ 81.145 81.407 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 731.093 null ] >>
endobj
-2046 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-2113 0 obj
-<< /Filter /FlateDecode /Length 1868 >>
-stream
-xÚ­ZËnä6¼û+ôK“Í7°0`Y3rö-È59åÿ¯!)¶HQ=cµl,ìÕÈ£r?««9–ÂNÿN2}ÿãeþ|y½Û8ƒÒ0}þó¢&™þ©)€pfòN éÔôùßô×o)-HéÞ¥ÔZJßþþüóEf°õzf
-":§C£”ÞúÉÌRª„&Óuú¦a½vé,ég÷½3ö K­Je©ž¥{¤ÍÒ˜Ðîéu²Ò=«ÖŸå¯l½YÖ÷8¸êŽBMyàfž’Ù{pÍ:B¥_KY÷γn@2ÇøúZ êýË1U^
-Â÷Îéî—j»ì¥×B“NjÍsr„þä*ÇžÎ_Å?½Þ¿^S„ÑäŒ27žÑ{$Êjƒ=_3P˜¿ëïj–B—‘oÕUÂøÃ\37öyW걫¿\[ÈÏù}èý5oLz—Ò”7Ì)= õÕ„R¬®S¹X-×îÈ×ù}߯<ˆÂZCyÃœØÒ®7jNrìý·¬UAØhIky|@òÕº<ÓpŠ«ûêκüššê6p½^8í(/ÎNô„  ŒHà™–Ø Eôd<ONÜèE„0AÊ8¨õËÝVz)M9×וRr8¡†Ø,o¿,Øü´Ã«\ÚXD…¦BKÖ‚šŠ®Êý¥ }Ä)2¶ßÇ›—B*2g%@Mà€”<gZb£Ö“–ðFú€”6ˆMìå(ÂÜšÁÞj{ß+9UºU]óàëqÍ
-LGn®[Cní~¹îdB©˜-{†®0ÜXš d d3ð”À„Va ¿ŠÆ!âü:Ç{¬î2 VöúLÁ:¡Ä36rË6áXô ­v0;‚Ú uÔ^9‚L3 ™dµöµ÷ݾ2qªû8Ø;~øh^U‘È-%â¡E1ÿž-‚5Rù6ý[piy샤³êŠçՒLjÍb&¦­"eÈI!SÉ
-4é9ï4e@Â[¼èúGPñzîÆÑíydãÝ`2¯¯DàW„1ƒ!û‹w~3 azÜú=ûPÇû
-ÊýW6YèäPíK‹¢wèßþÔ¥ôJè*mn®Ûm0'½tëO]Ž=É®ÖÂ;KF—'H$ôY%~ŽÚ6öïGo8Y¹,| €’Lé8 ¹p0[_É‘Qꕺúh[x™“\¡b”ÁJ嬜ѸGbÏflR:‡øæÿOj¦*U Ÿ’*E‚È–$r™#‘aËnš”¤ÎËRF{#
-í'ˆJøvNjª¼sse˜µ›%'e&9õ]Q–o¿tп۾[6‡;Þ%•c fIÜ3HÉÖÐA2œy;
->¬”_“B‹Úåøe”žŠSiHlKTá ™É“J³RÖ
-endstream
+2111 0 obj
+<< /D [ 2104 0 R /XYZ 81.145 720.134 null ] >>
endobj
2112 0 obj
-<< /Type /Page /Contents 2113 0 R /Resources 2111 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1731 0 R >>
+<< /D [ 2104 0 R /XYZ 81.145 709.175 null ] >>
+endobj
+2113 0 obj
+<< /D [ 2104 0 R /XYZ 81.145 698.216 null ] >>
endobj
2114 0 obj
-<< /D [ 2112 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 687.257 null ] >>
endobj
2115 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 676.298 null ] >>
endobj
2116 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 665.339 null ] >>
endobj
2117 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 654.38 null ] >>
endobj
2118 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 643.421 null ] >>
endobj
2119 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 632.462 null ] >>
endobj
2120 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 621.504 null ] >>
endobj
2121 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 610.545 null ] >>
endobj
2122 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 599.586 null ] >>
endobj
2123 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 588.627 null ] >>
endobj
2124 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 670.199 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 577.668 null ] >>
endobj
2125 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 659.24 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 566.709 null ] >>
endobj
2126 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 648.281 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 555.75 null ] >>
endobj
2127 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 637.322 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 544.791 null ] >>
endobj
2128 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 626.364 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 533.832 null ] >>
endobj
2129 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 615.405 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 522.873 null ] >>
endobj
2130 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 588.743 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 511.914 null ] >>
endobj
2131 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 577.784 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 500.956 null ] >>
endobj
2132 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 566.825 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 489.997 null ] >>
endobj
2133 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 555.867 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 479.038 null ] >>
endobj
2134 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 544.908 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 468.079 null ] >>
endobj
2135 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 533.949 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 457.12 null ] >>
endobj
2136 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 507.287 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 446.161 null ] >>
endobj
2137 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 496.328 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 435.202 null ] >>
endobj
2138 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 485.369 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 424.243 null ] >>
endobj
2139 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 474.411 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 413.284 null ] >>
endobj
2140 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 463.452 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 402.325 null ] >>
endobj
2141 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 452.493 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 391.367 null ] >>
endobj
2142 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 441.534 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 380.408 null ] >>
endobj
2143 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 430.575 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 369.449 null ] >>
endobj
2144 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 419.616 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 358.49 null ] >>
endobj
2145 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 392.955 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 347.531 null ] >>
endobj
2146 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 381.996 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 336.572 null ] >>
endobj
2147 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 371.037 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 325.613 null ] >>
endobj
2148 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 360.078 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 298.081 null ] >>
endobj
2149 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 349.119 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 287.123 null ] >>
endobj
2150 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 338.16 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 276.164 null ] >>
endobj
2151 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 327.201 null ] >>
-endobj
-253 0 obj
-<< /D [ 2112 0 R /XYZ 79.37 302.986 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 265.205 null ] >>
endobj
2152 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 271.011 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 254.246 null ] >>
endobj
2153 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 260.052 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 243.287 null ] >>
endobj
2154 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 249.093 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 215.755 null ] >>
endobj
2155 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 238.134 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 204.796 null ] >>
endobj
2156 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 227.175 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 193.837 null ] >>
endobj
2157 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 200.514 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 182.879 null ] >>
endobj
2158 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 189.555 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 171.92 null ] >>
endobj
2159 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 178.596 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 160.961 null ] >>
endobj
2160 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 167.637 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 150.002 null ] >>
endobj
2161 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 156.678 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 139.043 null ] >>
endobj
2162 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 145.719 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 128.084 null ] >>
endobj
2163 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 134.761 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 100.552 null ] >>
endobj
2164 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 123.802 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 89.593 null ] >>
endobj
2165 0 obj
-<< /D [ 2112 0 R /XYZ 81.145 112.843 null ] >>
-endobj
-257 0 obj
-<< /D [ 2112 0 R /XYZ 79.37 88.628 null ] >>
+<< /D [ 2104 0 R /XYZ 81.145 78.635 null ] >>
endobj
-2111 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F15 326 0 R >> /ProcSet [ /PDF /Text ] >>
+2103 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
2168 0 obj
-<< /Filter /FlateDecode /Length 2758 >>
+<< /Filter /FlateDecode /Length 2340 >>
stream
-xڽˎ#¹í>_áãæ°ZIÔ˜4з¹eö$¹&›CþÿQK¢Ë%÷N°ëiW•Äâ›IKa/ÿ¾Èô\¿ùånãňèË÷}Q™þS— …3ï”N]¾ÿ÷ò÷¯RZ-%D)Ý;~ûç÷?‘,úåÌ%ˆè„Nô"ê0Ò&RRúôצ (^»ôý–¾§—¨oõ¹Lk=~Ê ;üŸ o¥PRsÈ»ëò# D^C†
-k ‹ðÉ4ÊDáe˜!bœ˜í‚?ÝCÜ@ƒÜ¯ÇUúƯ:‚Õ‚ÚÜŽû§ÎíƒÇë<UAØh9žžM舧#$pœ{”ps¼}œ¸4Vñ,KÇ”õø¾’:‡ë"·¥Ëí“i!Xaƒ›!-IltÂyÏÚÒZB4A:—öäób åIKL)2¾®©ëô{]{-Ÿ¬ ·²¶ÚÍYºâÉa&@-ù¸}*ù°Á
-¯Ë7³ä4gH8²ÆÆý®p[úñ< éoýZ„—߃¶tß[ö”™7ÂóFkª>
-=GòZ/i„ÒC•>N¸)¶P‚M™Z6œÎƒÅš·úžêþ7Ríí¨ºÑ™#ÖgðŠC‰ãådØè(V(ïKB™
-£ö£áÓèñz«j.ˆXâ@À>É0«yÖ ÈÏV¾³xÝ{~
-
+xÚµ[K#¹ ¾÷¯ðqsDê thÛí
+þB»F
+%Ó®=¯iwDÒU›IB Õ$íË÷´ã‹£.¥Æ ”FVê÷5©G¤d9t¼Þñ\~§ïdi¨÷²…É6a²Ó¹`ÐÊõµqм"}²¶°³-”ù›«Ý!ÉàWµ^¨¨FkŽiM:f$pyö÷À)ÄYÖÍrA ;Ù„uMÓÅþö\þ&i¢í¾ÅEÊxÛ©·`_Óbß¾¡Ç×¢ž¬þKZ>]M[lÞ~¦*3$ëâ(Çnô‡”œàg ìççM>Š É’®þαB¶Laû~£èS}í£¨ò¡Ø•wÅ­xÍɶëlõ¹Í‡/=š¾µ¸z\i&ÚVñûÑ,yÖ„vUí…5¬[½&¤œ-ºLm%Z¤ïI»æ\´ikTFûU¦˜³BšÉÛiC²“¥èº[Õ:aƒei
+¬PÑÃ'$°÷<s[™lÑlô¾n.ÒV¯‘òSD¦È} (4­=­¿¸zã£?ý±æó#Ò²$&FV€]ÈJVBÖ”̇UµD’²Ï#µI× &G¨\ÌJÞ¼HÉ­&E¨Ï6a2&ÛÐb*|ÖŒÆ{9套ՌÒrè2.âHÍI²HÅ&¤dÇæú-ý$]»ÍV«ÒZWmXiß—ÂÇ„´®7czËIr”Ö &"LHD¶ ù#еÍïÌöíz'ìl¾o–×¥µÐqWrëòk둈 8])4ú¡wû­­qð¡ƒB5-™ÖŸÛ¸96dò{)ó¶ÄGóÞÌóûy¨ê:²oQ`Ù›…¶õæƒ&Ľça‡t¥ç$i`Ïò}ä¼ð1úŒ£¤‘$ºû1F±ZÕk1b
+Çð7¿ÜášrɬÛ*ˆÉÊ^S©1ÌøÕý®„c\É/S˜ i/õ“° úõ­ËhêÊìÇÀûþ%B²lKôÝÅ\[íºiPÂKÃêi<MH¨ûd=ÛžÓ7îˆþ¸yœN¹qGôÌÎSÇ-ÛCIáµåìq”B’ߎH÷ý6÷ jD1~Ÿ’©Î¥‘¡]?«»cyç½cWyPj#¢P3ÒýUÚͲÍ3›6j™+÷êu…F>Í90–a¡Íþ8•£UŽHIÆÒµØV÷±÷G×v }µÎçuGÃ’U3ë,›YW+•sYüH£íš {9p+¯W5ËÈÀbœ¾‘&G$*¬2ñ½Ö£‹Â«rZ'$ËŽ’;s
+iXŽv†j4™îï³Ä]mÏŒ±ó–ÅU$¥„}#ܦV”£f$ì8]±‘Øb+6–k8D-"'ðQ¥ƒpÒÏH¨˜ fºäßõ
+%œ\;„íj~óI¿è$J‡e‹Q¡µö†êµ5ã¦p\Uhî÷6SÛÛoÔ®_ìQ®7‹¿ü+ùZº¥_çÓ0Û¬ƒ;Ôá,HkŽ–»®¾ÇhϬ§@¾ßœæ–’¬“š(ãböÇ=WÂk?WÅç5‘¬ôJ\ï=˘›£:4hVÇ4ÖÆ#…—ß)º`Øá~hov²û¸N«÷­Œd%²ô¹€ëž'/òZx»‘Ö\¢£Ÿ½:_™À[Aðkg¤s=XU·ÍÞÉ‹
+èì€åêà€þÁÓ7‹©YøòìMÂûªæ6i˜:Ï⌺HcðÜÕ†8 ó˜rõËO½ˆþôaј\Ññq% •c¬ÚªúÉîbXÜ’2ÄÝðë@¶íÎÆÆÊÞƸ·1-³W2vò+Çår½Ô›ðã«ÊÇ(x¡c6šô±ãfƒ ‚Æ©dõ” ŠÉM–úï»2xôËïÿŽ0ÇRò0ïoÿxÿ2%[´ã¤’’–¬ã“Â¥Wß"M@å|ØWT{~—ן%ú<¾ro4~èø_ɱ·"uÛBGŠ«‘ch[ ͧIp*e• œQ¶sÈ(ÐO^~>–·ðnþÉg fq?Yë9nV‚5´õöZ°rh/<S½ÖFFðµ? Þ_i“Ž‚[ „Râryz ¢E
+ÛÓ’M±v^Òìü¾¸Æñ6v;¿Ýi‡Ð¢|c@Ñ[À7ƒ4š t˜ÕZ+Ý Ê±‹¥ÿ<«c8éc¡çg>fÒÚÍ2–ÏcûDký›'C9Ü ô1ºÈrf‰b9æø¹>ÜK¬zÄù±ŽR>Û¨Çü±÷’Öx¢¿j
endstream
endobj
2167 0 obj
-<< /Type /Page /Contents 2168 0 R /Resources 2166 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1731 0 R >>
+<< /Type /Page /Contents 2168 0 R /Resources 2166 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 1724 0 R >>
endobj
2169 0 obj
<< /D [ 2167 0 R /XYZ 78.37 808.885 null ] >>
@@ -7089,6070 +7080,6146 @@ endobj
2173 0 obj
<< /D [ 2167 0 R /XYZ 81.145 735.953 null ] >>
endobj
+253 0 obj
+<< /D [ 2167 0 R /XYZ 79.37 710.884 null ] >>
+endobj
2174 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 678.341 null ] >>
endobj
2175 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 667.382 null ] >>
endobj
2176 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 656.423 null ] >>
endobj
2177 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 645.464 null ] >>
endobj
2178 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 634.505 null ] >>
endobj
2179 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 670.199 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 606.991 null ] >>
endobj
2180 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 659.24 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 596.032 null ] >>
endobj
2181 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 648.281 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 585.073 null ] >>
endobj
2182 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 637.322 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 574.114 null ] >>
endobj
2183 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 626.364 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 563.155 null ] >>
endobj
2184 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 615.405 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 552.196 null ] >>
endobj
2185 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 604.446 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 541.237 null ] >>
endobj
2186 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 593.487 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 530.278 null ] >>
endobj
2187 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 582.528 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 519.319 null ] >>
+endobj
+257 0 obj
+<< /D [ 2167 0 R /XYZ 79.37 494.251 null ] >>
endobj
2188 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 571.569 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 473.409 null ] >>
endobj
2189 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 560.61 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 462.45 null ] >>
endobj
-261 0 obj
-<< /D [ 2167 0 R /XYZ 79.37 533.664 null ] >>
+2190 0 obj
+<< /D [ 2167 0 R /XYZ 81.145 451.491 null ] >>
endobj
2191 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 459.524 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 440.532 null ] >>
endobj
2192 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 448.565 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 429.573 null ] >>
endobj
2193 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 437.606 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 418.614 null ] >>
endobj
2194 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 394.767 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 407.655 null ] >>
endobj
2195 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 383.808 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 396.696 null ] >>
endobj
2196 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 372.849 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 385.738 null ] >>
endobj
2197 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 361.89 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 374.779 null ] >>
endobj
2198 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 350.931 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 363.82 null ] >>
endobj
2199 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 339.973 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 352.861 null ] >>
endobj
2200 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 324.032 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 341.902 null ] >>
endobj
2201 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 313.073 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 330.943 null ] >>
endobj
2202 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 302.115 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 319.984 null ] >>
endobj
2203 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 291.156 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 309.025 null ] >>
endobj
2204 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 280.197 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 298.066 null ] >>
endobj
2205 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 269.238 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 287.107 null ] >>
endobj
2206 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 258.279 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 276.148 null ] >>
endobj
2207 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 247.32 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 265.19 null ] >>
endobj
-2208 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 236.361 null ] >>
+261 0 obj
+<< /D [ 2167 0 R /XYZ 79.37 238.624 null ] >>
endobj
2209 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 225.402 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 164.865 null ] >>
endobj
2210 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 214.443 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 153.906 null ] >>
endobj
2211 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 203.484 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 142.947 null ] >>
endobj
2212 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 192.525 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 100.552 null ] >>
endobj
2213 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 181.567 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 89.593 null ] >>
endobj
2214 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 170.608 null ] >>
-endobj
-2215 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 103.858 null ] >>
-endobj
-2216 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 92.899 null ] >>
-endobj
-2217 0 obj
-<< /D [ 2167 0 R /XYZ 81.145 81.94 null ] >>
+<< /D [ 2167 0 R /XYZ 81.145 78.635 null ] >>
endobj
2166 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F88 606 0 R /F87 2190 0 R /F109 607 0 R /F64 325 0 R /F15 326 0 R /F74 329 0 R /F83 403 0 R /F81 366 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F88 606 0 R /F87 2208 0 R /F109 607 0 R /F64 325 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-2220 0 obj
-<< /Filter /FlateDecode /Length 3268 >>
+2217 0 obj
+<< /Filter /FlateDecode /Length 3354 >>
stream
-xÚÍ[ÉŽä8½×WÄ”F"© H$ÑQÙÀœë6˜ëÌiþÿÚÚZvØ‘=…:d•Ã–)n")YÞþ{“·?¿Ý~ûǧÒ7/¼C·Ÿÿù¦ÂyS7ëÚ›5JH£n?ÿwû×›”ÆI‰ŸáÞ¿ƒöáÚp÷!%…?¸‡k®AJ­â½÷ÿüg˜ÁÒj…Vò|²å­5_Š´€ga^õGxÛ¼ƒ‹|Lã2r¸ùF¾åqéYÿ%Ã÷"É=¿ƃM”+õG}GSyÏç¿4›äs$|Ö·ÓPÞyÔñ3'Er‡+É »‘œ\æ'ÒÆ{¥ –
-1
-²U£–¢ 1òl#Ïð-ù®å¨Qëª.\¼÷w­ŠÄ‘._¾|åÈž¤Qx½á)úÚ¦;?øÝ „g.ÍÈ<™¼PÒpOÎ4â<æ-K¿•£ú»)ºJÞäâ_{£6ÞÆVn¤‹0A©eÙ„{wPÔl±Ž­ÓeŒ´›Ã?²™ªg‡³Œ2N”GQ#x8rÅæ}õ˜²Æ£=‚EË4ñ¤ÉBe‚,8ÌÅÿk”¨‹Â@ð&’zI‹¶Óÿ›µ™ø\X;Ä¥›7íÛ5+ -l›ïN¶Í·ºB2KÜ3I=„šü^rNö^ŸhÏ
-k%oÿ®1Þ%•XPŸfœ49Ë£»Q²VnEª¬–HcÔ'1‰É,ÜÚV
-ÕÑ5*oæ[Ø´P^W{VºQj+‹l²fyn7ûÉn6"²‘æ3…h#5víÕàI–r ¶ÄƤ@
-™’IÑ9w/ïŽY3Kfá}ºÿ$£Ô‚¼ÛHŽ5§TK…?Ùýn\SOb<ZèŽÔqÈŸ¡ÍŽäµð"_D$œUœr\QÆ™E–(&zŽy˜÷*@=ÝfóWÊË5GÄM¸I·è^¼ø‘£jzúYŸ¦X5ð´ì'…Ž /üûg_û ïÂ(pÒ ã½p¾gÞH+:ZÔfZ.\A7ôhÐt¼'”€‰ê‰‘Nƒ~®À2*
-e¶ºdÏ)x)ÖôXÆÔL•§Ãš‰BVßðBÉD&©Îp
-—#Ùr)?)l2§ÆQJ]0õw´TFÊ×K.dQQ¦yþ¹ Ò ¹g¦ 7`™š,ËÝ¥És’%/ùb'wå‘O}µöùÝ)Ó’? ìÉk!ýŠ±Ä|ŒLm z—7Ãô•?   qãck¥6\§[3hwK™Y~Á‘—cv±½’¬æëo7Ã¥;Gú›Öû‰ùêøÑÌ2úK$š\Ù¦ÙêÏ‚Œåû ;9i
-nd„¾^6äuÁAôöx6k§Ø·+ñÍýRÙÀ(=/VÒA+
-%”BNakf®6MvçF•d”ë°‘ï%o4·Yñ³XÉOv{ônîlTœ`†•¦2¼%šÏy¡‰ëN—{5„F,ߣ0fÐP¥«¡1'•Þ’ï ¥”ÔL±c)ØË®qZY!VÂÚ†§°V#ïxÊ{00== )^€_1W¼­:'‘ܸ€B ;}CT= ;fèqUŒ¥»»îáñÐ=:š2Y¢±dK³ÛGßÍéóêøɽÊ{õŠlÍfM²½‚ÿš)=Œ¦ô_ÍìdAšZ'Õ·˜jŽrˆR¤~ð*‰Â“ãTŠòË:¶xy{7ò!ebÛÈ™ÆïÕåîmì`7Sb3eº:êb–«è³ Ù¬„Ëèƒ'C¨½0è¹/d6tZh œÂõÀß;ü=‹Ë€ˆžqz‰ÂñR÷–*-¤ ŒD¨à—xÝ%FfB_.ô~)0®aÿ; du
-”ÿVÛ¬FqK•-ÙnW¶ÀŸXv—æ¶Z—-»Â°ôy¼¦²‰ÈÆÑÇ/Ù#Bt·äìXd¦Ô%a^Põo“þ/r‹ BäÜÒ«;VŒÐ¥"”VÛUØw‰Ï
-˜xšlÕ# cïöø|€ îÔÇudš=îCoÙ,fŒ¢TÔ”ŒX@qËnس[qˆÏŽÄH.Š’Z¸3"¥ñ˜ÕªÚ!§*Ê‚íqrÃáÈÃEP2Iâ@i2¥¼<4Ð Z×á¸S Ï©N[§k~
-Øòô>T{åŒR7/’óݼúÇ_Ϫ¨<7­½jZr>x:®TÍÍù·t"B†jH8² écx×üÅäW÷Þ—i‹·1“óx\ÜغFåœ8ª¥Â"WvKÁk){vÉ $w¶~ˆÆ­Ÿ<®>o+›–&Ïcq(PçG{ýKé§Èœ±l,ï}ìí€êl÷°ÜegɺP~P;¿9ª%–ÁU ùÌgãôC(¾ŒóÊp
-ï*DÜùúÕqížDPçdì¨÷ã;Õì½0Ùfþãf¬0á—Û>u_°N(ÐüÍåh42ü§—˜Eû·} U/`˜¥~µÍí‚v½çY5Ï[Ûë‘—S­ÍƒÌµ©²Ü{“9GØ8blõ_]Kð5¹Qc@œ°á𸽄ÃÍ[i…•ÖB—ml:DÙÒšN|ϸDÃjñk`‡3a*ɤm V[¢)Ï3×#'&¤½ÛHj皯•ˆ:XU\Ûœé|µÿpÂ¥—þçF ^ÜÒd”þ–þª°tô²ê;¹õ§P
-`£´“W¬Zöî`:Ëß·eå³ Úß²ÛñŒû¹JÙ¯d(³=­,w²GY» ŒÒÐ'Ù_ ×x¯ ^òê.ñÊ(Í:>çoñNC¼uÛþu;€“¬Y® }%B2B—ú& @ã—'}¥?A·­ã·Zó¹.4÷•‰ß9Na>/QKçᰧܞ—’GûnJ>ÙwëTù–y­íòÓV#Â|~®ýÚÛdÍ:ß|;1|Zbºší"Mâö£UׄšÏ8JT¶P(`G…£MÆ#³ã‘§é((Ng˜>ÈB<ø€®oãð£ºÇÛÍ­¨¼¸l1~¹ Ÿ'óuÙ΄P-?˜©è†ZœÁm¬BÛ„æÈôzT ñ:â^úü„Z‹×ƒj+Ì¿^dé…¢e >Ùn¯"Ï„R§ÍŽ9‘#Œtèkña—ù±ûU¡¦>GÑ£®Û‹¢+ÊU7£ôx.Ñ_íÝ3B=æ¾ôàWL,*ðe”ž.±‹|ZòîŠÍ³ø\™ÔÈf„p½Éô÷9Ï墌ÈJ‘*êÇ5QgJã†ÔBê~Õx'yöô4~xJ?›+õcËËu=j¨a¥Ç³Ð»êq¦¿F+Ïñ¤")¤\~9F²/‹ø+®Eüxrø2”Æpš2É!¦ô(lÀ-Œ:‡@™ë¹W#qÕ«‘ãGÔùµ©Y%q+~¹»J‚ù Çx3Ýö!ìíÖn“°Ëuk±Å_éÃr¸sŽò§â}üîÇá
-œóÇþ›ó˜íãZvL¨"DÊ/M_”·£a;‡¥NM<qxê øP)V®×¸»–½fJ/!¨‹¼Ë°&—q^_‹OŒÒï—Ó<ëh)*]u&4Dâß5{]ÓSÜÈ
+xÚå\ÉŽ9½û+ê,k¡6 Q€sÊÙ@Ÿ}Ìuæ4ÿí¢Rd(Ëm40h¸33BAq“øH1Š3ýöŸ7þÿÇ—ûÏ/ßÚ¿óN(ùöóß_Äÿ‰7'™7kãF¼ýüïÛ?oœkɹòœŸîý_?ÿüÂ#±@êÛÃÁ›cÞå0o™—ŽR6ùàÂ?yßQĵˆ×Þ¿j©ãt¯Æ»ùNøtù pùš‰,Å1?Âu>9çâyŒ’’ÿLfÉÿDxÍ™àr&¼Ñ—„B2®)¡(NdÙB'ŠE¬Gq£˜IäÈtTÍŸû(Ϩ©
+Œ½ªù“s43ÕMÛ•äø
+Øšp°Š´0Ò‹ŸÖ`U¥0còŽîžàAq÷tÍbÞâœPrO98¹*Ë¡ÈÑiv÷#Çá³¾¸ów¹]ž±†QýÏSùéòج£M ż€éÒØÂY”¥«>îmÅK¼{@ >i_jê»Ffx6{ŽÑYR$
+i¯îVñŠ²Ôå²1ž;Y2ä¦)¸d^OãÀE¼WMAp òZÝ»Ú#¹þ½§CQ†Š’1rÛÞyµÌûÄ»˜‹ZÃø(\ïþ%¿Ó_ ¬Ž÷[hR€Ž÷ˆ[ÇYg#FN¦#ÏFŒ¯FŒR,éÜwMéB^®ìÌ”{h•Z›2 #9@¼Þ1Ãxîx}cªkÆÌó^Q⌋ÕØgK©]Yθu3íÁoBèd­=.®Žœ}{ýæô2p‹¦ h?¸ƒɸknQ£_ Rûç zžÁÂl¡,áéúû)_4“ÎJú
+æ]º[J™ËåÖz«køÅKÆðÑZ/í-»G¦qL~&ê²"€št§D}˜£äŸåéšÉ¥g>êø‘“"¹S3É•r ìAòѶ•‚˜R0Š™p‹P˜¡(i} Z¼kŽ5j]Õ…Káëþ®E‘8,š|ùzA?+{‚Exª¾èaËghAžx²âLtp>â¸÷¯
+ì­¯¦QŽ<¯7AÃùjÜÄŠÛÕKõ`7Ê“ärh!g†›ïNÞ*äŒwÍ$÷*´‘:
+‡ÊNaHâaâ¡
+8k’|╆oùJƒ|n>}Ö[²iUq±uÒ<¬º5ÁÄÃdÏꊫXýX”šð9±µpLX;Ô‚
+šÇ«»Ê’æV
+y]þ5È™ï« #ëZ†Ìw+ð4²ïƒ9•ÆsК׆™® ©‚8šŠs,«Ÿ.0}
+ #•ƒ#æ²ZV†æÔèû:Ôr´ÓrTp¬’ß›Öô(uÔ ª“´$zîÞq؉{ÇÊä è_sþä§Ñ{«fE}¶à­'Eí³˜ôbq¼b gÒ_¬ n™
+FBóH8bþ£|#òÿ½ð8÷ò9w|Nsê„ÈUÞ%{Ñš/Û5|ÀñX0v«ôF‘¢û9´m˜ò/…–d°— %åìÿZR}íCKBáo- O¿Z„Í]Û´”Ú<–yÈå9 -ó¥´”Z£8šÇ­ eK¡e§Ý¾œOU7Îg e5P6Ï£u]=†ÀÍ|ÃͶP™`nr=¥³†¶ɵUØóz7ÀÚ®YaÊÀ m¥«cÚ.u…ôâvÄLR£­&?—œ“<×'Z&™¹JÙ[¥,E¨ž|
+Õ‰H•õàÅ1 ¹­™T·v£ps[•4Æ(´+æ›ØSr0& %9°¼×Ák-z‘@œF#!i:S¬ïjul‘‘O¢Tˆ¹Gb8(€ (\s÷ò,rÌûÓ0+߇ëOâ°âšwÉ'ÕnàÝïðšz²Ç++™rgê8åÏK¦ÍÂòZx‘¯œ”r\QÆ™I”(&zŽyˆ÷ò¹=Š·Ù>Å—òzm)Û¸ßäœõ^Üø#o«éî£ebè0úñB¥<0ãaš@m­BŸM Àþ–J9ŬÒSña+ƒ"”^M¡~s¢W§µÓ“¦½ƒLBh+ÑP`˜‘Ó¶’곉† °WÑ9b(“÷óm\‡Ëhú$®•tcÞ›¿ÕsíÎ9ª‚­À¹ä†qq˜«Âë~Ì:b¿VZ– ØÄôÝ%s‡'‹`¾’‡è4¶¡ §L%& e¶ºøØÄÒ)ÖøXÆŸ$M•§Ó¤ BX?p#g²Tg(…cÍ×.ò¥|§°Iœ^…ýÒÊ SUÊHþzÎ%40eçó@frÉ÷ÌCɹ—ëÝÒä9Ê‚çt±ƒ»‚ÆšúÙ_?ðW‘}«¸w6jkgê€Õ»¼§ÏüA†Å*ÖÕ_!\§K#hWk½6ÿ’ÃŽ<³÷‚Ó3†öt3\ºr¦¿a½_˜¯5Ô"2'Í'™fW¶i‡·´@ãV¯w»$™³%¨¾ñ[wCQ—iθ{ýp¦Õ²)LÌ-x؛ǖõ¦Íºtb‘»>N¡ËB-£ëÒU÷òÝáßÂh;©ýI¤ðSÞZþÚt’
+mP ŸªãJ!çôÅk ÕÇ抆I¤bÊÒS~v¢(Ü…Ö&ùQ#YÕš0 ö6{Д¿õñÚ^U)›æ·(Èk¸ÍG¶€£Iï˜ã¦'m‡ä¡’¨nIÅÖ·_”<HŒÇ§§/{½W„Ð瓇ùIÄ
+¼ž¥…øö –>ê×_îÒª¹ÃHèyê0“Mš¿× gšîý¡û:7ŠqÒ”\”¾×OEm%,Ræa~2âüç–0ˆÎúÉɈa"Ü"OÕ®ÄÚ?ÞòÇÆé"sâ ñC/’Ò(¡(…ÞÌ\*íΟ,Œ* –ë´šï9­6·Y[Ó€Ãw–…z·€|˜Š *Tµ£ûfãB)×ãÏWy„”q­ôänÕ
+
+¦»—a¥”¯
+E²UÁΔ^bSúƒ¯fvŠ àŽ¯Žªo{ª9‹!\0þrÏà*즎R)ÊoBíœG)ZbY4òà7›º¦êÝóF­V²–¸u(.·T2çH+š¤‰î>êBqHiÏŒòTƒ‘MЪ­¤Æ]Á}O›¥fu‹m@$œe’t@@´×¿Lm¿#¬aä%­ÊÇV'ÖHçÓ©€^§x…P
+Šyÿ¿ú¼ÞÓÙH©·žý¦FB{&L%=IFJ]âÕéo/ìræÒäðê«[§V„ÐV(¸aVM“À~T|¸æÑ´}÷÷˜F³VÜò¯ZË\å >Ö8íý/*oà™æ†Ê±Û¼l9/ÚX
+nlµš%;àDYòØQ
+DÿHTëó<ó€ì8aé9cpÞ.4\ïôòÕ´pîÁûƒö#¸ŒÞûvªÑé{õ8ÜŸo]Æ2“þÆÎ µ}êºÒ:&¤&’Þg•6!ˆ1ßßK5ºUÊüüò?ÿx¦[
endstream
endobj
+2216 0 obj
+<< /Type /Page /Contents 2217 0 R /Resources 2215 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2253 0 R >>
+endobj
+2218 0 obj
+<< /D [ 2216 0 R /XYZ 78.37 808.885 null ] >>
+endobj
2219 0 obj
-<< /Type /Page /Contents 2220 0 R /Resources 2218 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2254 0 R >>
+<< /D [ 2216 0 R /XYZ 81.145 768.829 null ] >>
+endobj
+2220 0 obj
+<< /D [ 2216 0 R /XYZ 81.145 757.87 null ] >>
endobj
2221 0 obj
-<< /D [ 2219 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 746.912 null ] >>
endobj
2222 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 707.659 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 731.271 null ] >>
endobj
2223 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 696.7 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 720.312 null ] >>
endobj
2224 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 685.742 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 709.354 null ] >>
endobj
2225 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 600.664 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 698.395 null ] >>
endobj
2226 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 589.705 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 687.436 null ] >>
endobj
2227 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 578.747 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 676.477 null ] >>
endobj
2228 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 505.625 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 665.518 null ] >>
endobj
2229 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 494.666 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 654.559 null ] >>
endobj
2230 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 483.707 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 643.6 null ] >>
endobj
2231 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 472.748 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 632.641 null ] >>
endobj
2232 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 461.789 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 621.682 null ] >>
endobj
2233 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 450.83 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 610.723 null ] >>
endobj
2234 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 439.871 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 599.765 null ] >>
endobj
2235 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 342.839 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 588.806 null ] >>
endobj
2236 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 331.88 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 577.847 null ] >>
endobj
2237 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 320.921 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 512.147 null ] >>
endobj
2238 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 309.962 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 501.188 null ] >>
endobj
2239 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 299.003 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 490.23 null ] >>
endobj
2240 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 288.044 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 402.462 null ] >>
endobj
2241 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 238.833 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 391.503 null ] >>
endobj
2242 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 227.874 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 380.545 null ] >>
endobj
2243 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 216.915 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 292.777 null ] >>
endobj
2244 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 205.956 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 281.818 null ] >>
endobj
2245 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 194.997 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 270.859 null ] >>
endobj
2246 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 184.038 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 195.047 null ] >>
endobj
2247 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 173.079 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 184.089 null ] >>
endobj
2248 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 162.12 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 173.13 null ] >>
endobj
2249 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 122.47 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 162.171 null ] >>
endobj
2250 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 111.511 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 151.212 null ] >>
endobj
2251 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 100.552 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 140.253 null ] >>
endobj
2252 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 89.593 null ] >>
+<< /D [ 2216 0 R /XYZ 81.145 129.294 null ] >>
endobj
-2253 0 obj
-<< /D [ 2219 0 R /XYZ 81.145 78.635 null ] >>
-endobj
-2218 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F83 403 0 R /F81 366 0 R /F59 338 0 R /F84 404 0 R /F65 327 0 R /F85 428 0 R >> /ProcSet [ /PDF /Text ] >>
+2215 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F83 403 0 R /F81 358 0 R /F65 327 0 R /F85 427 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-2257 0 obj
-<< /Filter /FlateDecode /Length 2780 >>
+2256 0 obj
+<< /Filter /FlateDecode /Length 2297 >>
stream
-xÚÕ[Kã8¾×¯ÈµDJ”
-H*•æ\·Å^wNóÿ¯«÷˲c¥»1X4ª“Ø͗Ȕ̙ºüuáîÿ½Ý¾ß~<”½Hf@¸|ÿ÷M\¸û'.É‹&Á8‰Ë÷ß—¿s®€s4ñSÛÿ|ÿùÆ=1GêÇÃÈ‹a–MKÇjfÁŒ„PpNŽÜ8ŸŽ t×Üoy¿Éºß?(?Zæo
-Ë7Uîê8GšH¡Œ¡Èb#ñqg‚ÃL\Kâö„¤'¤ [2^ñB*§ywŸî1€Q x‹÷ýuúŠ×fÊò÷äm¦0ñh•æézfUh™8SÝ–ÔÑŠÌ&‹ßW™Ä{ÚŒ©ë)¦× %Œ”–}r‘o¡€šñç–’Ä´ÒJ“5ñû]l}mqb@4•ß¬ÉßS^]{
-‡N6ñ³¬^&ÿÉÓµN67–ü¼EÉÈ*†\O=R-I6Pj%›Ø¸~+Oò)ýˆ}OÈǪÛW/È!çkËͲ‘neÚ©&åš&{J»>¢:oÑÁú/s¯‘á”yÄ5æ;BÀ²ß¯·ïëò0‰S° ¿VÒÅ@¨Šˆüxu±n2¸g6“µeètç‚£!SRÉ©æãDLp!(ÊÄ?%>À¸ëjHÄ[Få«…FPxý•Ô—ÕUéŸâ¦ãÇ©ÕüK\20£>é¶
-¾z:AhYó€*Š¨Þ!“ù²OÉ
-ñ3 pô×F]F° ¸ÍQÀëQ4‘ÇLœ1!È0£ÌÈFo¹C1„Lj)DNxÀË•ÏZ'x…º¨…ƒn˜[w ßy¿6£*RpŒêHˆ«ÎÌwâêO‚h9Ñá!»䊇â£ó"9ÿðY’g™cU£_øB¯>K9×vœõy=~!n÷ÍŠ ºµ"%¾W;U+Æ„VféÖ†Å!-?³¦Åœöüïʾ¨M4Ì·Š%’D-ëLH&´§Â¸”TÝêŠi™Ï‚ˆ8ˈºþrˆ {iDUÒ|…(ÃåÈB\c Ùg M»¥JIxpOËÞæ+O›‡ñ!z'\?«_@NµŽQ1Ð×¥ÝÚÐÙ‚Ù$Ç(½Ÿ´”m±¹Ç©Mïî™Ûþ½+îßû¼îß{Ðî=áÞŸ÷¹?ï?O¨ƒç…þÓjU*sXŽ3“Ÿí7X`\« ¥Ž·«Úåðèž=°ç]®p`Ïšu`—ÇÁ¼ÛÁ<ûŠ]\Ì°RNíbÖì2Pê}æ@^¿b÷î]åÍŽî™WtA.ª5 KªËi¼Ë›h:^®„±Ð
-^O¤{
-§j]Rº÷|”2;B¡ÇØëˆ03ßÍO,
-Ì6ÂÆ›r¸÷|?&¬Ýä!Ý®¢(ɉ¡™§T\
-?=¡unÑ,†¡ÚQ<ÞjoWŸ Shˆ)YÁ&oM=q Ñï·Ž­ºGßXƒ•Ã`f$ãÂŒ-3Wo1«6ÄÏÇ2ß Ó°Q–ªÑº”Pˆ9ħiáæqÅTÇ×-Ñ¥°%Á1î9òµ+Ë='©TL‹Pk¹ÒuàÛÅ%Þ+_•~¼^ 5׆DWVL´±ºBQƒ3×t…®µ B+T¼¸Bgû8_géù±“æÞR´(}Üõ,53ªö %·âˆ)ÇR•”Êy ã9Õ5œ Û
-L1QÃÉekI¿ÌiCa\:c²ÉÕwæ.ÛôÙ7ž´òPŠ€o-.´òÐ#dÁz
-ÇIz¾ÈgÒµ#J‡ÅL@‚j3~ Њl ÈŒ‘>Ü×÷œÆ¨
-W;û†+¥³T~¥P’®xí‡ uïw’/Æs4Ì å‘ê8XK—Gh3Ë÷Ø’ f€‹AOøÌZ½>\mº[[E…½°|5£Ð8íV—Zۣ¡ÃJ0NPÚ¨ç¼ÃJ%ªÃì:lPÔ¾KÎ\Q «/ênòt<w 뎒9$EW•ÚöËÙÍüFª>téd›DáÑ ^[ïswâç‘íWÛeëš=Îyß,2Ëa£ƒÍ&ðqPñˆ_n4™–ei»–M@ç”Æ—(ïd]ñ¦úÈ!9p“æ†ä$ôFÇã.DÔºOú½ÀϺ͢ßÛ" é¯ÏÕ$­th@ý¤š’»ñ¸™ÒÐù7oó>ï§â6]ðF±ºSl·ëj¼©‘R»?[Tü8Žx ÑFù™Õ\O=ƒ¬
-W…8ï -‡~Db¾KÔYˆÞ“rì8ëX]½Bž™Õí¼j™‚t¸Ò<Üú(ãÓæɆûm¤c™ÝúBèc´ç,oûû·j˜ ¤Âš°ydÖX1è/^ù™ôèœEI9–˜v‡YÞ3"Ç6FþZب`#X;ÄÞH½I'ÐoZeJúK.…gò¨ª½§¿Rç³ ·<fÿسGëa•¿Íµ‰iÍÁ9è×oöƒåäG‡ûdDaŸlàa1
-ˈ…‘Ê^¾é»<>8 Û±ø¶Ù6²ÉÔ+Ó4¯¡WK——zF@.cëm‹ûºzˆg tP‘Î#û«çVCÔ4àä™|Þv ´[Où*ÞE$¸Ì¥g2œ< "\ˆ6”ÔóC;³“‘Ó3}éä^ÝaiN->ΞúܧVÏjVºg¸Ö«Ç
-É_R³ ‡¢h|ÀI¯Æ-9Ü°×ZÿE¶
+xÚÍ[Ko#7 ¾çWø¬V"E=€À€Ç ôœ[Ñk{êÿ¿VÏÑc4㑳 zÈÚž‘(’¢ÈO$—Ÿþ9ñÓ¯—ëÇËÏ» “eV’§¿_„{ÁOâ¤-C}ÒJ0®ÄéãßÓŸ¯œ+Ã9ÞÝœHî jÎIp.Mü#qížkp¿ýß͹֣Õ->…«ûnã¨@ávþëãÇ–#~„‘LZÛs¤E¤à)yΔˆßµŠü8N#Õ±”€Šq=Õ@q‘QeY®éÓÑoî9÷#à5®è$¯~-ÁçäFB&8¬8¤]¹P3¸šùP¶–Íóê9 :Ùàžù<ÿ
+MMÇjfÁô„âIˆ{í-Ešózl iÔ«N#‰ò7[c`¡K2Y®M´ý^¯LjV… ™pç²S¡ÿÔö
+× %ô”<_˜d
+FÇ—³2Á@rÄÁ1æ3£mG.ñ õ{àŸÃuyî¸&µŽÉÜiÑ4ðYTÏ'6ÈøGX¬"ÚËÈ2✲™p0ZI;.¬­W´ÔCîó<ÝÍ›Ü7 ŒmœºÛ8L®)¾wίÊ
+†
+N\$WQ…÷ô¶ÒÖ: oûuƒëáQÐ5H˜F=khFjè’ÐLÛ–Š~Óë‚rñ3¸öU¨³²²gzÞ+ ÅÇ¡Ç¥)ñZBcñŠSõߣ1¿ÈœÜÇÐ+9%rKÈ›ê:&öÃãoˆ.°8Tõ>rµâ^+(œäpn'E'+™244fœ½#T|îAŸ 2 jÄÔÁ›C†½¥‡Gl’O L+Ýó©®Çá¹;#šôŠÒÀÞ¯ùLŸr—]ÃÍHÖ£h?ËÚR*@LêÔåÛ»ä{~aKOÔÏê›x_ó2¯GrwiGz<
+¾³[Jð=ZyŒ(É]×-§aZ‹CŠãùÓˆ—ýÄJõ4'bÉ.ª´Î;ì©÷ (rݦk8ŽÒ5áizqZ“¯â¸?=…Áø¦Gy-ÝŒòöh/7›\/Y6ÿKÜ1*·åÈ=—õø$× ³Ô"¤=È@<‚6ŒhT«ü$CD'Å·¼Íw¦‘5¬OJ¢¬ÀÇ|]Ï?”ôz :˜mxÄ/sá«¥ô„šã]Z˸Äï8ÒzJÿ¿&a|}‚¬fNÖ–RåŠÿ¯ákRSÚ]¿×€,X4Íiª¥ôAkBZ¥\к¹ë@G¨ËËL0ä"=À¡9ÞÚò'òR|§Oi|óuL¢e †Ps®pÐúŠëX|W›¢°ßtE“`ò5b¼¾edu´„>uE“ÂE(ñtô6B\KhÚ"'¹æŠ¡#¶'ÁwOéË¢ÛžMŸ,´Ä$ÂPþË”ü¥ú·Êš§
+Kv!9wk‘^‘m©ŠLJæ+ØG’Mâ–ŽÒ箧½.Ž,à /¨¨‘‘CMΡ¢ŽÒ¦P_ßúDMÅ×扆Ži©t”¾©üÞ3N‚‘UC L¡—ŽÐTU ½{8¬*5Wµºªd­-)óßô4,O¡©\ëkrQe¾º+f¨L_çÀC5Tèúêµå¯h/ëÞ†Te¤ÁøœŒØÞð›(†=Fh0u­Ä"ÌRÊJoü“Pɾ1güȺ˜RF’:*F_ úœ9Ä×ÚnÉÊ
+ Ö²nè€TÝ˺‰+T7ØÄ#´GóëMª|ÅeåüÐÎ"ŎжCŽD»xP¯ºUß;‚©Ò_E÷.W“
+¾Ub.öH!¬Ë Q÷ˆ¢í§Ú­Z+à ™ž™ªµJt"'|•Â
+OÞÊMa#oÖVsK©¹>›¹ØÜcTäRhUª[J°»}rHí®¹à~ŸœäLˆ¿»–t¶gT?Ëì«Ú++ôìZäì]Û~ÖÛåAÿ2àv{[sgUØ@Ÿ@–Ø·`Ógézƒ¨JÙ%0æÀº
+®ƒl­°–éÒ ècº®3´•eADˈrþ–ŽŒ%ÉœT©Æ'„Ü•eÏB<cÙGM»£ªV’t
+áþ¹¾u—
+Ì{„•5å+àÖú~L8»É&ž*¯ËÄÐù̵'6dvðÓ±3é‚J6ñ˜k+™]½ï¢|ŽI‘:¹«—Õ‹5)ZÀÆûÇËŠ·&*
endstream
endobj
-2256 0 obj
-<< /Type /Page /Contents 2257 0 R /Resources 2255 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2254 0 R >>
+2255 0 obj
+<< /Type /Page /Contents 2256 0 R /Resources 2254 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2253 0 R >>
+endobj
+2257 0 obj
+<< /D [ 2255 0 R /XYZ 78.37 808.885 null ] >>
endobj
2258 0 obj
-<< /D [ 2256 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 742.926 null ] >>
endobj
2259 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 731.968 null ] >>
endobj
2260 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 721.009 null ] >>
endobj
2261 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 710.05 null ] >>
endobj
2262 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 699.091 null ] >>
endobj
2263 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 688.132 null ] >>
endobj
2264 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 635.33 null ] >>
endobj
2265 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 624.371 null ] >>
endobj
2266 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 613.412 null ] >>
endobj
2267 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 602.453 null ] >>
endobj
2268 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 670.199 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 591.494 null ] >>
endobj
2269 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 612.048 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 580.535 null ] >>
endobj
2270 0 obj
-<< /D [ 2256 0 R /XYZ 79.37 577.49 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 569.577 null ] >>
endobj
2271 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 559.716 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 558.618 null ] >>
endobj
2272 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 548.757 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 517.771 null ] >>
endobj
2273 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 508.63 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 506.812 null ] >>
endobj
2274 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 497.671 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 495.853 null ] >>
endobj
2275 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 486.712 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 484.894 null ] >>
endobj
2276 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 475.753 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 473.935 null ] >>
endobj
2277 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 464.794 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 457.995 null ] >>
endobj
2278 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 414.152 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 447.036 null ] >>
endobj
2279 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 380.722 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 436.077 null ] >>
endobj
2280 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 271.743 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 425.118 null ] >>
endobj
2281 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 260.784 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 414.159 null ] >>
endobj
2282 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 249.825 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 403.2 null ] >>
endobj
2283 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 238.866 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 392.242 null ] >>
endobj
2284 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 227.907 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 381.283 null ] >>
endobj
2285 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 216.948 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 370.324 null ] >>
endobj
2286 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 205.99 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 359.365 null ] >>
endobj
2287 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 195.031 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 300.134 null ] >>
endobj
2288 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 144.388 null ] >>
+<< /D [ 2255 0 R /XYZ 79.37 263.467 null ] >>
endobj
2289 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 133.429 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 245.332 null ] >>
endobj
2290 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 122.47 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 234.373 null ] >>
endobj
2291 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 111.511 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 193.526 null ] >>
endobj
2292 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 100.552 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 182.568 null ] >>
endobj
2293 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 89.593 null ] >>
+<< /D [ 2255 0 R /XYZ 81.145 171.609 null ] >>
endobj
2294 0 obj
-<< /D [ 2256 0 R /XYZ 81.145 78.635 null ] >>
-endobj
-2255 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F22 357 0 R /F83 403 0 R /F74 329 0 R /F65 327 0 R /F81 366 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /D [ 2255 0 R /XYZ 81.145 160.65 null ] >>
endobj
-2297 0 obj
-<< /Filter /FlateDecode /Length 2277 >>
-stream
-xÚµZÉnä8 ½ç+êZ‘H­@¡TWj€9ç6˜ëÌiþÿ:Ô¾XvYIêزL‘ÔõH™3uù÷Âéÿ?^n/¯å.’9+.ÿ¼ˆ §âbiy1Z0®Ååã¿Ë_WÎpŽ–~Îÿýù÷ÇŸ/Ü #Q¯+/–9­Ñ¶rœaì(H’%8‡çâ—¿ÿùC¢'šZ•Œ­þ)B~‚2_©·ruß^‰÷ÒQÅÆâ'æ*·™¹ZYCtLHœö—Kîé»GjúAtÓwºË¸Uwe‚ìš¡gYù¾ä®^о»’‹îÔrOµ;tªn®Ž¢É/dk’ˆªs¥^u× ´Þ¸Á–)èûk§r3ëŸ~Îmƒ ”Ù„(œ¸Ë;Â#ϵN
-æ¼äã}™MÏ,Ã@Ô+ÅqñÐ 2Qû±é•7oUœä3ÍŒ*¨ÌHv¶Ÿx)¹òÞF¦ ü¼^ûQ
-ëÓö+²}¡  ´Tœ÷±B—D²'óñ-‡f_ª¼ «%¶š˜¨¢ûmeÒiF¦([ªÐ ‚öQÖ«rÖ š@—+³jUŒ[;ÍÔ’A½ ó)ø^ƒŒd¦q`­H4:o¾}¯A™˜#—ìéä,˜ó{I@&^yGxjêqÖ&Q30¥
-9¾]Ø•®HIÚAÏÁÂvWòhoMÞÁbù3÷̽º½)H<öƈ„QªiÙZ¸;àØYjÞ/¹™êôl-” ^ÍQ„˜Ž¦C²å¶fÆf¥
-fóĉ.GÓ]U1õ/k6ÜÙß w¼¢OÞ&+?õ<¯a·V„™Úy¸Vâ89vL<õ<v)*k[üÑ°Š&î÷ó‹Ö2©D§·YdÙµx²¥{º[pÓŸÈ5‘¨¡â8ãdk'kƒ }RödgÂõ¹•¹)Ï÷åìš_nØèsf›·-—Æç%Î,8˜¸ª’›“ ­ê±é áË+f# ·4ÕgÖžì6ç2Ëú*`ʪ™¾'Ï …ä ÜFŠ†`/ê$£8;ÓéäPŽ2 ÜHR«š /È›©&çÎ¥„?D ¦QÒ=ÍNÔôã`~yWU1Ÿ8kCá˜ávfÓÉrS±i´úY
-ß°@®Õ%ÍmŒ–åÈÎEGCqܺ¿°m –&ôCž§Ù5½¤Ö7›#ÄÏ]¡ƒ Áç9&&'’–}¦,à ™çÉ£
-±£ fŠÕ¹¥®kþ¨Î³æ¸ó!c÷Ø,~87^ ,køUÞíŽ â^rF£†Ølž­O¤P4g_gÙvšº^ÐîêüÒQ3tzŠt\R²Ô/És¡×·äí3|%ÜI‘hf¦­­A'Ù/8Ò‚¨äÌ™BšÀûÇËÿÎè
-endstream
+2295 0 obj
+<< /D [ 2255 0 R /XYZ 81.145 149.691 null ] >>
endobj
2296 0 obj
-<< /Type /Page /Contents 2297 0 R /Resources 2295 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2254 0 R >>
+<< /D [ 2255 0 R /XYZ 81.145 96.889 null ] >>
endobj
-2298 0 obj
-<< /D [ 2296 0 R /XYZ 78.37 808.885 null ] >>
+2254 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F83 403 0 R /F22 357 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
2299 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 768.829 null ] >>
+<< /Filter /FlateDecode /Length 2413 >>
+stream
+xÚÕ[Ín,+ÞŸ§è8 ó'EJ'é#Í:»Ñlç®îûoÇ€)( ª‹ä^f‘tM¹Ìgã?ÜòöÇMÞ~ÿ¸þøÇC™[Á‚ÅÛç~(úBÞÔÍ¡ÝÍY%¤U·Ï?oÿú%¥‘RâûËO­5ÝÙ ¥~Д£ÚQº–å›8¢ÞâÓR]Ìʿ?ÿIüx=ãGyRùž#ôôVÌoÓw¦àpF$ š€Ê E‘¹ÈFbŽ?ó22á9T`0°-™J^dY²z+WpÏ°Ä%”y ¦¸,[çç â 8ÉÜÑ3ö=ߧ@ó†TÍøÖ!ëBÏ7Ü_ŒúUùªôóø&¨9¨¥ð4|zJ
+uþÿ&
+&ÜP¯4´<"éÐ ¥ôö|”a #7˜i±Óúð扫}K'8À÷„´ªBþå§s]x¶Æí9S®L½ú¸J/Î-OÅ]Á4a…R•3‘ð^)@á&f¢àl«ˆÚÝàéÞÉü™ßŸ¯ y^»‡”Ùu$ÏhG„Yeß³×y‘N’Â×4Pè·NkÑ)óâg‘é³ ¶Y&ÇvKžÚŠ4Õô(NíÏ\
+Ú’>F ¶§×í_’øq|œoòÙêÚÉmÓíõÀ+´ÜÞ¯?ª&&¹ØÀÈ&YXß[úô½ã7ÙÄ[ÝÉ7DdµkïØ”ðHD?Ž$}º÷:vnϵ^‡~=´O5’±ÃSÆokðÕ[å•ùç|Tz­O£ _~ÖíÑ·ù6ؾçÇîu«Ù¢2?›Y8UXO µ<×
+m…9TØÔ±JÎT‘œºÆ° AG“TÕ­€K<g¿.¿+›#Ú¬ªèÂ~;Ósê„ßL5š.Dza
+Iøy´šÁ2?únæçQäWh¥ÙäšÑµsE Z ¡Úm‚£¢h$y[fSn³Ôu6?½·qEöÅo!›,kŠsV“œ¸ág“sRnÀXv"£†+RbÔÓFp¿ª½±™ìL¢óM˜XÝtK#ù_U|ÞÞï&¥’¡]ÉX·¶Ì;T5ÙÚÔL©Æ Äs‹JX;¬ß
+Ìâk!«ÑBšÒë°1‚ui{G]QÌ;ƒú§ÎáÚòLð¨âhŸ«ÂA6Òi¤y?»MÈê•ùÀö¥ç~b©¬Ã˺¿4ìmtä‚,üE›w¯‚)TÚ¡Ì,øAP~yä;Šî9æÁ
+G»§¢fdŽKؘùkÃF·6BíÍÔÛ
+•šò[âPÎÛ.æYm
+]¢´”ö·%JäâXM£f©Z)í¥?MÕŒŠªºy´5tv ̵…ü8ßS™iÊ/Á¬,ÅP¶ÁE­Pž¶œØk¥ÿE¶@!ɘw”—£d#0w/f%JîGÉNUÕbø®³ëKՔݥc¦ŽP>¬ÙŒóM'¿â*›#V\  )kJÎ;^J:J†c2ó: |OCà‰¹Ãä¿Ùçtìì‚L…8“ÉÕÄÌG£âzJx^ç€ù¸îž³tº—sdm†B­YXõ`­Ê9·5—Ó½²=÷„Jˆ‹M‹L)
+ƒsõ^
+L:BÇpÝ6\³@ýˆÎ7RˆiCt¦«\-ÂFI‰ñaª5zÒÇt^ô¤µó¬OzV1¡á èRÝ¿› |æ£ Pù/^—Ö•TEç{Ìe¯EHe ´}ÄW}jGhÅNåî¨Hµ]Nå½í®:®k+)U¼F¸ú6FŽ£FÏÄx`2Ö„Î
+ïÜL(c
+JGèX(ðÑŸ…}e»? .•ƒ
+endstream
+endobj
+2298 0 obj
+<< /Type /Page /Contents 2299 0 R /Resources 2297 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2253 0 R >>
endobj
2300 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 2298 0 R /XYZ 78.37 808.885 null ] >>
endobj
2301 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 754.882 null ] >>
endobj
2302 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 642.304 null ] >>
endobj
2303 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 631.345 null ] >>
endobj
2304 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 620.386 null ] >>
endobj
2305 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 609.427 null ] >>
endobj
2306 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 670.199 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 598.468 null ] >>
endobj
2307 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 637.322 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 587.509 null ] >>
endobj
2308 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 558.618 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 576.55 null ] >>
endobj
2309 0 obj
-<< /D [ 2296 0 R /XYZ 79.37 521.95 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 565.591 null ] >>
endobj
2310 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 503.816 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 512.789 null ] >>
endobj
2311 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 492.857 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 501.831 null ] >>
endobj
2312 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 481.898 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 490.872 null ] >>
endobj
2313 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 470.939 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 479.913 null ] >>
endobj
2314 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 382.271 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 468.954 null ] >>
endobj
2315 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 371.313 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 457.995 null ] >>
endobj
2316 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 360.354 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 447.036 null ] >>
endobj
2317 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 349.395 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 416.152 null ] >>
endobj
2318 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 338.436 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 405.193 null ] >>
endobj
2319 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 327.477 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 394.234 null ] >>
endobj
2320 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 316.518 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 383.275 null ] >>
endobj
2321 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 305.559 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 372.316 null ] >>
endobj
2322 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 294.6 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 361.357 null ] >>
endobj
2323 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 283.641 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 350.398 null ] >>
endobj
2324 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 272.682 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 317.522 null ] >>
endobj
2325 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 261.723 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 284.645 null ] >>
endobj
2326 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 220.877 null ] >>
+<< /D [ 2298 0 R /XYZ 81.145 205.94 null ] >>
endobj
-2327 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 209.918 null ] >>
-endobj
-2328 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 198.959 null ] >>
+2297 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F83 403 0 R /F74 329 0 R /F81 358 0 R /F59 338 0 R /F84 404 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
2329 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 188 null ] >>
+<< /Filter /FlateDecode /Length 2185 >>
+stream
+xÚÕZI“c' ¾÷¯ð ’ت\]ÕÛS•sßR¹&§üÿkØáñðkðôd9ôÌ3‹„–O
+’öDÌÐ*È
+„Š I#Ð. ´%4/„¯$V2Km Í ¤._+ ¨†&'—ÚZèGù>„Ñ×&„}½ ù8è(£ºÿ_¨ÞŠw{ê ì¹® —7Ðþ÷Ý÷˜$Gáèc†ÿí¿ý,pž¢†70ç!"U ):˜(lͲ…Ù~ÍÏžfî—WQÊÖ°ècL›Cb¢w©ã÷ü‡
+æü¡Ÿí5$SÕRw1‡DsÂãê\¥É9Ìó_GæQ›ì(k£·„žjÃUúÕfÎØ“<¢RÍ“ë!OŸùR°ôòà-è ðSý*@…òíùðÞ‡B WóüjµÕ«_MÓÈ–2‚%ZT¡wŽ-Gú#6¿>‘ž¼<÷¤ òQåœ7¦vlŒÄ‡TÝ:U
+â®Ú…½C;GŽÊT¾U&µêl„©¥
+O¦àƒSBgÆs êl”C0ÝDÓÈMH ÓdzåÃ{š}I†zmáí¡i9$YÎ4ô EÅDv}ä41r¬Ãù3ihçµq…nQæŽm?Âô6ZŽb}ù
+'ô&Š´v—ÇŸ ¿mÈ3Ã/^­.ÏO#ç9ÜøŠÐC9}%®“cÇ@SŸÇŽBEfn‹>TÑÄýnÑ2)t§Ëꈉÿ’µx’eÓ;–ÎÍPÁQ×@™ràP*;e´Ê:BAÙ'^œ×sž™fKY  ‰ó ºÄ¹c%–¹ô•´eÓú¼Ä™;°Z Ñ ŠÇ)ý
+¡˜–º'„{*¯êʪÅen92‚FìÒmŽ]â 쎊^¯ñ$­ûÏBÏb¨!§x’– À%¹Ê‰q` qĉ„9N”aÒ5õ”¼/¨ÍΕrDÝö—·} CߢLÚå+M#™\ý·$SGÉ®râvÉ5ää}“-¥…°È1f¤q<yæP8î(-ë53Ö 91kœt”J$­ÇTmSlìO¬±tQPÌ¢Ú€\óõŽR‰’â–¿ô²–…dc%OæJá˜Ým -Ÿ¤H.1Üm\IÚ¡ZLœv6Nѵâ4É@(2Z‹Øµ­²¶i´èà~â¨ÝÉGh=BÈqD‹¼bK M5”âÁ£š,2CØ+n5„…Kó}ß"›r°›ê®Oj ·É ¨_ðAm‘¥‚|âm§³/ÄîVØÐãòG:V#7=e“¼ôaƒŒUŽrž´¤È¹Ø0ŸM"˜ä¡ŸhÌl†À·V1 Ì_Ç
+î:•1ÜŒÀé$ÈÁh@iYgܥѡÊf±£
+1‰©avž=¸JcKè‘•ÿ º¦åEM
+zJã³¼½“Ö¯t‘éƒUÞ$£ÛçzPœkUNé²7™¡Ñ-½kêíNãŽ<G&Hí.¶§Þ!ƨA¤»;V¢p/ U_
+8:rSh츢òÎÑîÞ9Ús‘å6½c>Royi_+Ô §'.6Ï7¨9 WÚíÝ´ÎxÕOè¿Ä1ùÖ8®–ï¾s|EË»óÇQ²«¦›èý-±°‚UøPðp%\®ÚaÓrmI“6Z<ÿÂ…˜™ß~Œ¡ò¨rñ8¼Âtä³»†GÜ
+ÿzWãóNWÚ:
+:ö€ëøÐ];"«çŠBk4N{KUGGè1È´íý+ÅQ
+endstream
+endobj
+2328 0 obj
+<< /Type /Page /Contents 2329 0 R /Resources 2327 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2253 0 R >>
endobj
2330 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 177.041 null ] >>
+<< /D [ 2328 0 R /XYZ 78.37 808.885 null ] >>
endobj
2331 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 166.082 null ] >>
+<< /D [ 2328 0 R /XYZ 79.37 773.016 null ] >>
endobj
2332 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 155.123 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 754.882 null ] >>
endobj
2333 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 144.164 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 743.923 null ] >>
endobj
2334 0 obj
-<< /D [ 2296 0 R /XYZ 81.145 133.205 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 732.964 null ] >>
endobj
-2295 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R /F22 357 0 R /F81 366 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-2337 0 obj
-<< /Filter /FlateDecode /Length 1954 >>
-stream
-xÚåZK#'¾Ï¯ðXªxJ«‘ìñ8RÎs‹rMNùÿ× 44]¶ÁóÐFÑjÖ6 _õ®)Ìáÿ{:½?=_L8h¼B8¼ÿõ¤’þ©ƒaõÁY%¤U‡÷ü”Ò€”èé¥táåÏ÷ߟd#¨ç‹×/‚µè[œàD
-%‚!!(éjè‘"mØï¾ù¦÷#ýIôé—ñü¬•‡>UÞÁ¥å TNÇg6~ÎòƒP9^ØÓ/´D`-PÒÈëbž$¼PD GòqŒd‹Â£ê‘ì¢fz˜6Ÿ*à ¥-¦1eZôÌ÷æDc«ÒÁ늛ÕfQ§Èë˵ñ=IÕöÏèÛ¤¬”
-ö@×Ö{ª%OGž‰ñYaŽkÍpr“TRi¢‘ÛäqªPíÀ¶Ùs[߼;Ù¨T0ç}áׯ*±Ä‡±5«JAŽ3M²uuý$÷¨ºÓ6pÜ­=”θÒ¹ú”‡öÑð¡8ÞUsÂø:.;»²ÖÍòNJA•)Ë;?e^[ y¤_»1ø¿ô‰QP{JE<o¶f†yP›oggú¶×·n³ä^õW̆–Mm¾U÷1?W‹ªDŒšeŸóBk·£¥`özÒwªØ׿«vÜl\ÑÖ Å÷TºÅéŠÐ rÐ §Y{™Ë–; oÉ '·
-N¸j[sãáü¸„¤¨éèU+‡SëƸöÈYúéõ~›à— Œ¶ÎÁ’Î@¤g#”–Fx%£ëÜ0ê‘Ì$%è‘B–’ãT³GÂMSç?ÜkonýïŽ¾Þ }B=Š`4Ç¿Éq‡ÌAÔ’»ž[\KSK&iˆþâÜbÜn2nyt¥–՚ƹè@„`X.ú){è‘fÓ´ $ZÖÌ”è:]ÓYG§õÍ(!céÓSN¸Gâµ`’: ÃËq*8w@_ZïOnQ)a+€Áx¿
- Cú®0H.X8ôýâçh/*¾E¢0xëÌ¥ 5ÛúåÜÿ£uP¹ãöÙQüœL.:¤Or@å„Ž¼ÑŒ#«mtÝm\kS§Ö?PÛÖ÷ÍõR0–æ=•bË‘„ƒ¶Ñ¾¶âóQ·zm×ß:üN³V4Ÿêù|<@Z»¼¬’³=iiψ°²ìtí"
-s†Xä‘íäeuÖöLZØ K•œfÈ»»z„θÐ[¡ƒï‘Úz>3ŠËJ‚Âî¥]ÃÕ´§*íý
-heèm$ÕåÖ|àý€š½¿öþ|¿2ò¥ó<<kù{9X‡„þô¦XÇh“;VÒíÓˆ†w»þÓx"QÒ¤Ö;ß©ŽÎéÒGk(ÖP÷WæêÑT$ê»Vš•¨Ÿ’h‡tWnìs3[E(/…ÞWés*•ê®]qŒãpÚœ
-ɺ}~ ÝR6PÔ´ìë4£‰÷¶GjäãÍËš¬½Ü:-kt2°¶Ö”Ý›ÏÝ[sëDj^Æ ƒŽµƒ±jTªáÙ!±´œªðŒ;û@a¢´ƱåÞhÁlô¿jP)´Âîª'{/™378p-¶<rZQÍ`­âh-@eøÚì¦5Niá$Ë­ÑZ³ø¾-RëûzýP÷VIN#Kéqê&j4Ë3r4ÎkŽÑ$ åR›l8ó»]Ô«¤Ûãåï½GðŸº+î•ð`Xùù)ùm>å¦øÒJàTÜLQ¶ÚÚâXVUnŽÅeëw
-Q±%O¼D¨Q(î%[ÈÛûÓ¿Þ|À^
-endstream
+2335 0 obj
+<< /D [ 2328 0 R /XYZ 81.145 722.005 null ] >>
endobj
2336 0 obj
-<< /Type /Page /Contents 2337 0 R /Resources 2335 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2254 0 R >>
+<< /D [ 2328 0 R /XYZ 81.145 633.337 null ] >>
+endobj
+2337 0 obj
+<< /D [ 2328 0 R /XYZ 81.145 622.379 null ] >>
endobj
2338 0 obj
-<< /D [ 2336 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 611.42 null ] >>
endobj
2339 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 600.461 null ] >>
endobj
2340 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 589.502 null ] >>
endobj
2341 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 578.543 null ] >>
endobj
2342 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 567.584 null ] >>
endobj
2343 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 556.625 null ] >>
endobj
2344 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 545.666 null ] >>
endobj
2345 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 534.707 null ] >>
endobj
2346 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 523.748 null ] >>
endobj
2347 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 512.789 null ] >>
endobj
2348 0 obj
-<< /D [ 2336 0 R /XYZ 79.37 636.592 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 471.943 null ] >>
endobj
2349 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 607.059 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 460.984 null ] >>
endobj
2350 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 596.1 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 450.025 null ] >>
endobj
2351 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 585.141 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 439.066 null ] >>
endobj
2352 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 558.155 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 428.107 null ] >>
endobj
2353 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 547.196 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 417.148 null ] >>
endobj
2354 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 536.237 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 406.189 null ] >>
endobj
2355 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 507.815 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 395.23 null ] >>
endobj
2356 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 496.856 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 384.271 null ] >>
endobj
2357 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 485.898 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 353.387 null ] >>
endobj
2358 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 474.939 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 342.428 null ] >>
endobj
2359 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 446.517 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 331.469 null ] >>
endobj
2360 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 435.558 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 320.511 null ] >>
endobj
2361 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 424.599 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 309.552 null ] >>
endobj
2362 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 413.64 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 298.593 null ] >>
endobj
2363 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 402.681 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 287.634 null ] >>
endobj
2364 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 391.722 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 276.675 null ] >>
endobj
2365 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 380.763 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 265.716 null ] >>
endobj
2366 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 369.805 null ] >>
+<< /D [ 2328 0 R /XYZ 79.37 215.101 null ] >>
endobj
2367 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 358.846 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 185.011 null ] >>
endobj
2368 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 330.424 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 174.052 null ] >>
endobj
2369 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 319.465 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 163.093 null ] >>
endobj
2370 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 308.506 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 132.209 null ] >>
endobj
2371 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 297.547 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 121.25 null ] >>
endobj
2372 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 286.588 null ] >>
-endobj
-2373 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 247.647 null ] >>
+<< /D [ 2328 0 R /XYZ 81.145 110.291 null ] >>
endobj
-2374 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 210.141 null ] >>
+2327 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F59 338 0 R /F84 404 0 R /F15 326 0 R /F81 358 0 R /F74 329 0 R /F83 403 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
2375 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 199.183 null ] >>
+<< /Filter /FlateDecode /Length 1816 >>
+stream
+xÚíZMo$'½ûWÌ EQ€YšÙ±#åì[”krÊÿ¿.4ÐMCµÆ»£µ6Zy=î×E}ñ^õHaNÿždøÿ§ËÛÓ—WãO(¼SNoÿ<©“ ÿÔÉ <YRB’:½ýwúëw) HI&ÿ>?ÿýöç“Œ`ê˫ÓžH»Ç[áÁµ@舒.Rª¯ñïçß ˜p´†|ô’>“ Ÿ¿6Çâu¯RÚx>_gò±r]üL>^_ž ±|2zýdÖ³¶X”Ÿ±Þg(-¸òß ç)”ÎyÚO9oMŒË$YL£—Õ}×òÉ®ËÄÅ õ_ó"³Ó6çlŽˆÀìèÅ/]óÁ‰çŠ³­¬V¬zϺO{¡P³îsCîSÒ
+Ð"=2Å~ü³Œ¯">éapB×qÕm¦tT …×IƒÈ¡¥e ƒ £(”ãúRªäŸ\ªÃ›žÍn=–ÝŠ„5¶CZ+˜ªJ‡KÝÊÔÚ/ìš= gW`µÐìðel@BYh€ÐÎÚA Pw{]–Õ ¢0Ž:$3k‰Q-p–³áé¶*–æÝg/P¼¦ŠéÃúÐö¬ÅF»Ø1é? W)Íù.sþÛ#U¶™ÚJô¼·ª«Öõ¡dhCì×cÛójlêN”[æŒ{¼0Y/žçê¡Aš%@¤œ0Þp–  µEì‘š\Ãœ£Óùøibíss=¸Aâ³`Î:cQXÖ¸¹ÍysÔJÑGªö -ÐN²{p·/îo‘µÂ!ÛðG7ñœà RØûVÄn×úéšÿ½ºÉ αÛÀ$³h¾SÛ0Z†Âêìyœp”¼mŽÛÆ—WeN> A0 B²^è€#AH½fé¦_S¶k­+ɸˆºE{?ƒ‹èPßK¹ÃÕt¹Qß,™vIÑ_„¤JÒ2]µ¢¹¤èÓQy»<l3'BQNÊ ÊQ¿Vn»døK*aÊIW¡øu™ÉE!ÒŒ‹4áˆZ'-nÀ 2‚E!°1ë}‹À—Õ»áÒŽz×"ÕŠ>;JÓJÒ«—Öp­÷¤§Ç«KX` ¥Ëö]OLaMŸã3Œ›L~tNHg¸ää¸y[j€Ž'B·r/w óQºäÑ,vì±9¬«DÒ]¾í(;1NÕŠ¤‚Z^WnÕ³Ó»ò8¨£›‘=沈"˘ÀÖ¿å• é[„ÁZé1x>h*èàù©
+6G>7‡wíB€ÊœëškêzOu Ó½¯ŽQ“gV Òqy4¾ë&PãT¢¥º;ßPGñn÷q þ^ uûά¡î%#¨I€õlDÏsÝ#ÝŒ{Þ̪ »ŸÎüI ¶Ší–|ëx.u„ŒÜÖ×;è*º±,aP¥¨¨Eªò™ÉÚÕRoI±2­Üˆu•‘ž­´B¨CŒ-ݾ¾¼Xçíþö=+Ï/n\c>R ”l ŠQå㱦CbmGhD¿†›>ë釄‰kÀþÄâ…AÁ¨ú¥ÆSÚ)ŽUO£š9;qG{ Ý‘ïsŠ
+ºOxTÊõØÞ4^Qi±èìuUüT+þ¥í1ô:K“Ï+úRŽK±ås”Š&ßavS±e½y·Ah¨hg8¥’·íûPÂAªLòÙ T 6£öQÜRfL¶dƬ&‹ÂõþR1sßãh¤ €´ð=Xš‘™÷6HãÊ|«‹Bø“‘ŦÏÒ‡X7ˆ.eý?Ⱥ!0Åi³9Õ÷’öÐTe[U—T…åûSiN”«<ˆŒßwz¹sx8á šªÿºÌRYzÎ3{¤Ê3·sÔ~<ÂZ‰ßÜ:†_øäuì‘>„A
+Ùó 7Nþ‹cv@³ñäÊk¡ü¥xx+Àèæþuà’§ùeþ]6¦<}—0`ü"CkØÿ|á§ä *$ôS–˜ô£:2ó…éA|A‘Àð7®>óȵAbkõÖ”òÝ¢áwû_„W(²„áun\d–8í‘>ý®£„f—›~iÐ =˜WÄï±!Ãܸò(ëØ#}þ
+d—×4Å3{¤GGXiŽ%HÃÚ ¯côù#,AvüfÚè‡1GðÁlC'”ÂÛ5’ÍË/oOß
+endstream
+endobj
+2374 0 obj
+<< /Type /Page /Contents 2375 0 R /Resources 2373 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2253 0 R >>
endobj
2376 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 188.224 null ] >>
+<< /D [ 2374 0 R /XYZ 78.37 808.885 null ] >>
endobj
2377 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 177.265 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 768.829 null ] >>
endobj
2378 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 166.306 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 757.87 null ] >>
endobj
2379 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 155.347 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 746.912 null ] >>
endobj
2380 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 144.388 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 735.953 null ] >>
endobj
2381 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 133.429 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 703.076 null ] >>
endobj
2382 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 122.47 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 692.117 null ] >>
endobj
2383 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 111.511 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 681.158 null ] >>
endobj
2384 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 100.552 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 670.199 null ] >>
endobj
2385 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 89.593 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 659.24 null ] >>
endobj
2386 0 obj
-<< /D [ 2336 0 R /XYZ 81.145 78.635 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 648.281 null ] >>
endobj
-2335 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F15 326 0 R /F65 327 0 R /F83 403 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-2389 0 obj
-<< /Filter /FlateDecode /Length 2615 >>
-stream
-xÚí[ÉŽ#¹½÷WèšCFp
-J¥Ò
-6P2[ëvý®@…¹Êòm~_¹UýQ3q3ýÏé/43ÊŒ’¤©:©ú ë·û,/Âõòpú¬Ü»×dCµ Ÿ‡w*#DJú&ÞË7ãæ£÷oö÷@RíŠè™ýåû9ûƒ`r+©i)ÕÄZïÁ:%ËRî„H·”…Ñ'òEÙü×ç
-¼ú¿ð~µF³K—£9/áó–’6˼F?-Y¦—D,ó<FÍ{˜#Cngóð1»4^Ò/ïaíÀW>7³Œ¾-Yf´êáwQ…ÖŠiŽ;¨â!8Ã@á( ¸úBZ¬Bi/‹S*Ç A:¦ÔFµÿƒ†ÿJР•`Úêià¿.†AÒ-930-Íx¶4{°``”4M×'ðá8kæKþÿ¸Ðà ‰ž.=h×üÔKúõ—a™åó¥G­Y¦—ôÅàBû:0Aï¯çÙG™F'è—÷¯ršYÓÈÇ%à ’¾Ø¿*4gó8Mò<zI¿¾‡¿e6ÄÝ=È–é%ýÍàQIëiZ­¤òÀ%8Flÿdh•Ñ
-/à,­€ô™„oæ  ŠGßÚ{QÖ*–Q(
-1óÃYz“±Ì MkÔ%ûêIT™†m2:l¿”l‘š¢xëÏ€êËözO‘:³M¸‡9ê Ÿ ŠGôå¢ýÀ“:3û%AÅ~½¤/‚JxêåpªÿI,‹Š)aI¡–h·õX¸7š…Š·™È„¦çÀ=Äi-9‹g•cp”Ôj ¼’™¬içá)“FMµ;‰â<=æ^Â( 'õ ë’xkÕ~XÏl¬›\ì¯ïVÊøâ©„žF™Z³A/iŠö*'ø60{SòVYÏÛOÛؘÙï$P ‚ôFв#•aÊÙi0ãRª ’hªubÚ¥T„’½Ò—›ŸÓR3nfŠ³ØNI&},’–5ñxKÑž‡R¹„÷‚º¬YÔ$3
-vÍ
-½¤~!:‡`ÕˆÇEãÚ?27íéç¶?cM-qŠAɃçL%2aÅs¦krO>ÎþNa¤|®Œx§.ìñeÏÑ”~!Ì÷înÝY¨üúA¶'øx—
- l#j{Ï‘ù­2gÇ¢á&^Z;:0HzR?{Þ·¨³° ù¼vœƒoÎø€²£ ¥À_v”ªpG[âx@Ò:¶¤ÕL»BdåE€Í‚RdÔ­ ú+†Hbàºå4î’’ÑR`–«]˜&Ù:i$}¸Öú%`cº¬Ù"Œg˜Š…sSèÈʨ´ÆQBù•2€_)RaKÖ¨VÖ.³"»yuê÷VÝà±5-’\M‚äÜ`v»û~cí*~"ÁÿgŠ8O¢ñÙƒ RÖk9³tØó|¥%Í›ÅIiO ì¶}¬Î#û\bFI=Ñås²¼×Z>šyl'¿öñ<k'Ãw-FýâV!F®ƒ¬Âðf»…ÓI×ÀrÀSýB&$­
-PèeIs¼×údžŠoweÛ•2ŸÞ”Aîfɯ£­0åè@,ñn—±ñJ7ü‹CK¡Lw%éc—Õµô®«ø '
-Áå¼76Z†¡hÃWÝ¢LþÐå~~þµcá$-¯x´NxóYò¬_vˆÔ`¹ô«H+ÞѹââñAXЊ¡Âa²èˤf]²ÃJ˜FÅŽÃA1ãFáÙéE=53àÆe;R@b­=)È¡6F0±QFçÕC!1âj¡sîÐÌ®GLŠ öR­wPÒ¸º{šP“hŽ{àØJˆkð\BÛ¦‹Ä ÝXdt\ýïm‹0–
-Ó¼ÍW9]¤ËÕ!ôZÀ@22—z ]}FùÏÂÇyÈçÃÿ]Áãq±”j¬N&S%ñÈ{?çÁ,j<2EÕ›oõ›6‚˜BåsÍ}ôD‚ýþÿƒàxˆp/jí_ÃéB“hf8ýd»;“AÐ>ùP8Ç\ø>VPÿöûóbþI‚"¤`ÒØÙÄw¿GIm‡ÿñì’¡®Ûc¶äsx¢0àhÒÝ{'û©$©ö0/¼Qºódÿï¸Mη¨V¥ ÁÊÇmcÐýÝÀË#lKT~§ë²qÚ|à}+ãÉQ耘 W£–ò¸B0v|«Cž¥N0…b3Þ¶¶;¶´>·F‡Ç¨±6‘ÜÌ¢›_ʹ•BDêñé{ygÛrq¤ÜÃa­ãÊѬ;U*,¾e­öa‘Šr û²Eïº>šÕgOSÛc£«¹Ñ{™Ò(j\Xûœ‡õh[˜]7±¡ŠÂ'ÇG!%<rü÷
-,D”°>”<#éÄÆ8ˆ Z’¶]WâšPr¸kfá
-[-,¬¦Ì6š^lƒFÄOR˶È×€Ž.§bS¢„’Ÿ€†B¢tµB‹ì¼
-y2–kf‘B–*+Jèisˆîf/¢þ6”¬d¦5¹Jò”ŒîAÁ
-endstream
+2387 0 obj
+<< /D [ 2374 0 R /XYZ 81.145 637.322 null ] >>
endobj
2388 0 obj
-<< /Type /Page /Contents 2389 0 R /Resources 2387 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2254 0 R >>
+<< /D [ 2374 0 R /XYZ 81.145 626.364 null ] >>
+endobj
+2389 0 obj
+<< /D [ 2374 0 R /XYZ 81.145 615.405 null ] >>
endobj
2390 0 obj
-<< /D [ 2388 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 582.528 null ] >>
endobj
2391 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 754.912 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 571.569 null ] >>
endobj
2392 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 743.953 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 560.61 null ] >>
endobj
2393 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 732.994 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 549.651 null ] >>
endobj
2394 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 722.036 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 538.692 null ] >>
endobj
2395 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 711.077 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 495.853 null ] >>
endobj
2396 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 700.118 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 455.006 null ] >>
endobj
2397 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 659.455 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 444.047 null ] >>
endobj
2398 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 648.496 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 433.088 null ] >>
endobj
2399 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 637.537 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 422.129 null ] >>
endobj
2400 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 626.578 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 411.171 null ] >>
endobj
2401 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 615.619 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 400.212 null ] >>
endobj
2402 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 604.66 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 389.253 null ] >>
endobj
2403 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 593.701 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 378.294 null ] >>
endobj
2404 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 582.742 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 367.335 null ] >>
endobj
2405 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 542.079 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 356.376 null ] >>
endobj
2406 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 531.12 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 345.417 null ] >>
endobj
2407 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 520.161 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 334.458 null ] >>
endobj
2408 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 509.202 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 323.499 null ] >>
endobj
2409 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 498.243 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 282.653 null ] >>
endobj
2410 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 487.284 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 271.694 null ] >>
endobj
2411 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 476.326 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 260.735 null ] >>
endobj
2412 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 465.367 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 249.776 null ] >>
endobj
2413 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 454.408 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 238.817 null ] >>
endobj
2414 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 443.449 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 227.858 null ] >>
endobj
2415 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 432.49 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 187.011 null ] >>
endobj
2416 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 421.531 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 176.052 null ] >>
endobj
2417 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 410.572 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 165.093 null ] >>
endobj
2418 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 399.613 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 154.134 null ] >>
endobj
2419 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 388.654 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 143.176 null ] >>
endobj
2420 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 377.695 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 132.217 null ] >>
endobj
2421 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 337.032 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 121.258 null ] >>
endobj
2422 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 326.073 null ] >>
+<< /D [ 2374 0 R /XYZ 81.145 110.299 null ] >>
endobj
-2423 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 285.41 null ] >>
+2373 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-2424 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 274.451 null ] >>
+2426 0 obj
+<< /Filter /FlateDecode /Length 2866 >>
+stream
+xÚÅ[Ër,· Ýë+æLó¾ªTªÒ\i\å]’»sy•T¼É]Ø›ü~À7øèVSñM#M³›h
+¨Í¼eÝܦŠXLPtÖž'˜¬R XK<ö–® ² Z ‘)àÙ×$t ÏDÄö–"–löK{OÏÊ;õ¸ÆQ[íϯ‚ÐÌp³Z…«8 4Cö'JÛœpÀvÅÉU´S콧$ÿ¿Ö³§í3Î/µðº¥…RŠ®!Ø0ñ¸H™HÐÏ#þ³j%šÚK)zBÄ
+‘ó<WkÍœºçZ“F£ìuTÞ‹5×|øÀ+e˘¡i󜩸4‡Ü•é­$»~„gKv=Þ üDvO¹FäÀ'ŽbÞ·›7k̹õ"¹½Eê)}à=û¬o“gÅ™_De¸ ß¼En$´·±ÐépÙ‚# /)€+Fõ"mÞv% ¯’r
+'…F* Ы¸Õ$—€3†¸4§¼-mÌ2ÚmÓDÛ$îEk²üVòKç0
+7¤Ï„›ü¡ñEzIÊùùê@ʼnšÖiÑJ!¼-ZZZŒ;„jP]º*ÔÊò˜ìrÕã<NRªQÚô!ñYãS^²²Q#gç ¤fÖOÔ³>ÒL³ž© ³ÒO3!ƒ>Ó€bõ?2&!§üXÁÄÌŽÉ!SobÅ‹“ݡͼü>Úk^†#{ë)±\—|iU«-ÉÑŸx׶dÃèߥdν”=‰à­ôW²0úë*Åùq{Þiô¯(!)Þ‰å6“–¨ªÈ¯{[-ÔøÝü‚©³µFc”×ã;C°ÈªfRE‡†Æ!Úê¢j%îÌÚ”ÃýÓBÆT[¤mjÑb~/ °èëd,–œi
+‘ÂA
+’Ÿˆ†b¢4Z¡E^¼Šy2˜kjB¦
+$ôÉsØÞM_„ýy+Ii¢oi룷é âÑN“Iâ“Gí À§óy‡uO ‰ÿÜÜç qõbÇ1ã‰Ð. X=;¨ ’*€ÿ“NiÏߦÐüqð&•Æã¸ÔšypËjŸ:jz¸MO=™ßµteëx.ŒÅâF
+W+›èžd­õ»NÎè2NÏÉR«ëϾŽ9˧:r>»,ëb½XV#rlUD}Ÿ…ØR Æa ±¯6»3Ä)©±½Ÿ«ì›üIθ[*t³c=P’|—žÎ—­8ÙkËŽ”v@ ÌË…åš]<+'0¡A”ÈQ—4eÎ|¯Tœ|ܦdÎ2ÉõR2Ø“l ä/¸Ra%“í
+œI?Йϒ5¸ð‰@,$0˜¼_¯Å.{JÛXÅ`†“Ëç%3'=¥å*¾}ú}pOØÛß¿=ýò+ÿ??#ç¡éñïøà7 %€Ï„iÿºýíé/éÇ_VÜ¿Z«;fŽ d⮌•¡nh@í»s8ŠY´7Ô "¡ªŒG+Ú¥ÿ/©Ò¼$&
+̆G>éMŽ¤”J¢éÃðKÒ¾~âÝô‚qR§¶¯W””=M´£†V}ªD¬Ÿ4ƾôÌÀƒ]qJ¦Rzyf,•úi¹
+6HW¥/X«xœ.`l%ÉíT‚îá‚?K”L·êSa°œ¯"¿,ÌõJ”]ͬôtZKÃó|­5±ÎwCÏýÀÖwŠ³¡«ktèi"#-Çn?JAïðÉÕÏ=
+endstream
endobj
2425 0 obj
-<< /D [ 2388 0 R /XYZ 79.37 226.13 null ] >>
+<< /Type /Page /Contents 2426 0 R /Resources 2424 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2253 0 R /Annots 2463 0 R >>
endobj
-2426 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 160.206 null ] >>
+2463 0 obj
+[ 2423 0 R ]
+endobj
+2423 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 256.954 157.029 267.381 169.548 ]/A << /S /GoTo /D (Hfootnote.37) >> >>
endobj
2427 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 149.247 null ] >>
+<< /D [ 2425 0 R /XYZ 78.37 808.885 null ] >>
endobj
2428 0 obj
-<< /D [ 2388 0 R /XYZ 81.145 78.635 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 754.882 null ] >>
endobj
-2387 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F22 357 0 R /F65 327 0 R /F81 366 0 R /F83 403 0 R >> /ProcSet [ /PDF /Text ] >>
+2429 0 obj
+<< /D [ 2425 0 R /XYZ 81.145 743.923 null ] >>
endobj
-2432 0 obj
-<< /Filter /FlateDecode /Length 2740 >>
-stream
-xÚµ[ÉŽ#9½çWøJ¥…Ú€„t9]@ßf&o>ucê2uè¾Ìï(‰¡%‹œÓWÙÅE"I%¿ü¸ðË÷—ÛÇËׇÐϼ‘.ÿ~Ὲ‹õLÙ‹5‚q#.?/¿¾rnçê>òúE)ž(˹œƒK-®Ò…çV†ßø¹‡1·ëo¿„•œ­$@0/L¿V¤¸VEÁ‚±Ìë)¨À—æ’ͳǒ
-g˜Ó+Y‘{³’ÓpzbüJY^ù '8CYúuD:‰ÔÃyãL£I¿ßŸÚ_€y'”¬ùt’Æ-X&„".5ÒÑé£|¢•ô ä5ÊÕt¼e^ºžP2^`þƹø†¿¯_´Ô­é Ì2­ †L»SL n™¹¢¤ˆ'Š4~ŸåOj&¼ñgô-%Ég9À¤2CN`Ž“Ž’žå„+&­ÚLãDfñ`u”4Ù,
-"¬ŽW¥ÎÇo Hé)Íæ(A¤¥Ãˆ“³;PpÖ¯(Ms"/é'gcrÎH{JÓœð
-&»»”[‘W•œ´ˆÄ
-†smEg`bí˜ð¶.eDùí*9-O -Žçõ­iƒWe«4Wåî‚Ù©ÂÛ|î›ànË©H©Z TòmßQhŬZÍÒ K±MåŠPÅ{ /Š6{£µ¬y÷­œìX!»–fF[)œ+w«™‹ ää@¦Sã¨ä¸È[:'i«6¿2¬LÐ|ÐaÙ“
-´a
-Î^Gõ¨oÄñ $¦qµÍ"HXVZ$”ø+oäzh^ÓÜZpâ½jÆEbM“¯y’ƒ}ËHVû¤¥…nÅû´(3 «T»Â;•È‘Q(8²Ö_ÕyÔæµ4ÚÈú öŠÌ.h-Î7²±Û+nb™ŸîœØed%Ô'Úû>ÂL å¤Y S^å¿ZÑ,­C-_j·Àƒô4wi÷~:¤zúKÒB¼ÊwÖk ]š¼O€(‰uXÕxðdÛ)ÕÚQèŒ9âþ¡ýDiý“ Iº¼œ r¶€—jG F!ïýH³ÀÆÙ
-éF²œ-JÃDå=¥&,+ :Єe_¿t#÷í÷8÷h>~6çß÷éÇõá`þÎ{,Ÿï½7&}6çóô™ðRûè9Fö{›³_GÉJ”) Œ–>I¹¶Iz²¢ ˜§Rw`lR>ÌÛÅH¼œxuÕeZËáx7åcZBÏú¼T¾ËÇó>'XI{5´ó\2ÓQzÚç¸^¶Î á9ÅûÍsXR“áûº8¶5fápk ã?·3…fFÁÐ"0Úš˜±z¸5ÕÔÖl moMКTÖù?lCá³bÃ'ó‰ŽÒÖ6Ü–áSaO„ÿð.N-G¼És¾˜ÝfOIõÛõh;YêÊ3ï„1©
-Ž¶Þ )·B_ÉýqK½åàø-u›{Á„ñûý`\~V¶3i5+˜õndµ³À‹¬ÖQª;nTý÷•,ƒqGº§Ôª2T8?O9Üæ8[lSw£¬ÙŸsä:cžWøOØÒpæ”Ùrxö”r½øEUt°vöì ²Ü<XrÛ;-ˆ[ZŸz9G!©t—×^}'àÁ¹Ó»¤ÐUJ½
-Æ“V¼¶:4âúìÝKñdoÏÖÍ
-* ì-]·q9é¦3,§Æ.‘uû¤Ì ,x)FJ>{/bnG©T瞉¾®ªZß×ýËx>!ïâi:ˆ X
-¡späUá[Ý`üœîeÀ\F uï OËÂÂág@^Gh§Q”ëNtJXî@ÞûÇËŸ]Ëkf­»üþóå×ßÂã?Âç— ããÀŸ!P°)pÚ.ÿzùGú³2+.šykuù ÏDÉ3.`pQ;hZ]‚t–zµÄ :Ãdu×îÑݸ]ÏE*EUÏx5ÃØÑU
-ãÚâdî;H` çàÉ›í[RJ%™B“7‹àíßÝ>
-”Y²G‹À ‘}`ðþc/?k~©£¯oØD‘S‰ê:½†¾à­ap›¦ä¨û»Îa'ÞwlýMñ%S£Íx`d ³ÕÁïð?Qà­
-endstream
+2430 0 obj
+<< /D [ 2425 0 R /XYZ 81.145 732.964 null ] >>
endobj
2431 0 obj
-<< /Type /Page /Contents 2432 0 R /Resources 2430 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2254 0 R /Annots 2478 0 R >>
-endobj
-2478 0 obj
-[ 2429 0 R ]
+<< /D [ 2425 0 R /XYZ 81.145 722.005 null ] >>
endobj
-2429 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 256.954 662.142 267.381 674.662 ]/A << /S /GoTo /D (Hfootnote.37) >> >>
+2432 0 obj
+<< /D [ 2425 0 R /XYZ 81.145 711.046 null ] >>
endobj
2433 0 obj
-<< /D [ 2431 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 700.087 null ] >>
endobj
2434 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 754.882 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 689.128 null ] >>
endobj
2435 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 743.923 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 678.169 null ] >>
endobj
2436 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 732.964 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 667.21 null ] >>
endobj
2437 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 722.005 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 656.252 null ] >>
endobj
2438 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 711.046 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 645.293 null ] >>
endobj
2439 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 700.087 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 634.334 null ] >>
endobj
2440 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 659.24 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 623.375 null ] >>
endobj
2441 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 648.281 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 612.416 null ] >>
endobj
2442 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 637.322 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 601.457 null ] >>
endobj
2443 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 626.364 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 590.498 null ] >>
endobj
2444 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 615.405 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 549.651 null ] >>
endobj
2445 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 604.446 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 538.692 null ] >>
endobj
2446 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 593.487 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 497.846 null ] >>
endobj
2447 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 582.528 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 486.887 null ] >>
endobj
2448 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 571.569 null ] >>
+<< /D [ 2425 0 R /XYZ 79.37 438.264 null ] >>
endobj
2449 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 560.61 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 372.309 null ] >>
endobj
2450 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 549.651 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 361.35 null ] >>
endobj
2451 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 538.692 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 290.615 null ] >>
endobj
2452 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 527.733 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 249.768 null ] >>
endobj
2453 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 516.775 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 238.809 null ] >>
endobj
2454 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 452.017 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 227.851 null ] >>
endobj
2455 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 441.058 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 216.892 null ] >>
endobj
2456 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 430.1 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 205.933 null ] >>
endobj
2457 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 419.141 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 194.974 null ] >>
endobj
2458 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 408.182 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 154.127 null ] >>
endobj
2459 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 397.223 null ] >>
-endobj
-265 0 obj
-<< /D [ 2431 0 R /XYZ 79.37 359.811 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 143.168 null ] >>
endobj
2460 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 300.115 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 132.209 null ] >>
endobj
2461 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 289.156 null ] >>
+<< /D [ 2425 0 R /XYZ 81.145 121.25 null ] >>
endobj
2462 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 278.197 null ] >>
+<< /D [ 2425 0 R /XYZ 93.716 91.504 null ] >>
endobj
-2463 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 267.238 null ] >>
+2424 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F59 338 0 R /F84 404 0 R /F74 329 0 R /F22 357 0 R /F65 327 0 R /F81 358 0 R /F83 403 0 R /F16 328 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-2464 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 256.279 null ] >>
+2466 0 obj
+<< /Filter /FlateDecode /Length 2793 >>
+stream
+xÚµ[ÉŽã8½çWøŠEw @ª”`ÎykÌuúÔÿmnÁM%¦»QpÙi‘AÆþ"HS">¨ûÿ?oÛ×Ûϧ´A¬a_ÿcêþ±‡¢ÄC+F¨b¯¿ü¢T¥JR*>Ýûöþ¿¯ÿ¾QOÌ‘úù4âaˆUŠ›šSœÎzJBS
+Ûû ÂÓÝß0÷"½X|)·wkŠÝýýŒ ã^é;ÿ ~‡ùa/k|IJ…!_k|µ”€"O
+Þ9öLô@ #¯ô³å‰O?ÚÅ?çÛTPj(±&Ÿ–ÒXÜ«²’pª‡öÊïíU
+"˜:PR«;1‚paG;Ÿ÷vÂ)1Ú(-ïDsÂÛ8ÑjïN7CÕnÐZÞ‡"8mDÂÚFZJÑŽ¼oH‰Ÿ‹ä£`¬³DC„i#H¢Â>ñ“ú_^M<ë:Nð)-{ÉO÷Ú‹C¤Îß8y>•õÍRúùdòatÀ µ’Ž¶„ë‡â’Hžó§r€?cFÔG®—&¾${ý+EŒ[ZÉðÑJ.o¹¥ _+P‰-†4%Î#{
+ðQü¿Ï]>†M™%ùTÀ1â°BÈYøØ¿ñRðòŠ6߶³¼=…Ìœ$"ë³ë-(þ²Ôž·@'÷`9Õ$ë¨8\VD²Ù“×y7ð+ %ÍñT¢DÊ!¥²§xgÜz‹‹¹¼³$àDê­½G¡}DzÿÁµê¶ÇµN[AÉŒïç¢|â·Ùƒ„‘*ð$±²ªÂ“q 6,ÀŸE%‘œpOü</å%ðÉ€¤‚£Ê^½ÖÑñ·DþjÚq0´Ùî”rËrmG‰o¿8äÆ„$©ÀHÅŒ%$‹$#Ï2ç½jÃ7¸<B´0žÖ#¤DGà‘çò¨­Îé{— Þ°ŸB»³ ÂIUÏ|Ì…äDóÃ,™÷ˆÿb¿ë½‡ôÂÑØ yMÖw²cn\Ê'Rè#7qÄ• ®Ôff0È ˆ^àYó« ðÛr_@eæµÞR(q%¤"B¤Ý¦nq*,'ÔaŽƒîrH»O¤ÕDi1‚'7KsGÀ‚é Å[gŒÖ²]šÅÅ*cFÍä±%ÜÕSâÑÔ½â0Ö¡Ónçüau‚‘,ð(¾*¥–DK5⎯ÁÛŽR…órõ&±zS¥óRè¹÷¹ëÕŒÔ\ã^bG­»9º]O`·£Ã•°ß#ÞðÝj½'• Úê¡DÍšD[JµDÈyŠ¡%oä?AÏ#̾nUÒW¬fè3rM-¥©UéøZט€P)Žv+ÖvÛRUV¾ß$i£CÛU)­Ô>ÎëIÐÒ3ñõ±÷õß=5· íJnø¯@b6ÖÿÍ·z”wP5$1+¥„fu %%CÇuÔ­ ¢ufO™QaCƒkŸa1ŽC€©m8 aaY)‡HQr0l|p^…h+¬¸#®Eb,ì¾I ?fOVڨŅ¶Ú”6 «r»Â<•0”a(X²–ŸC\±@¥ïRá¡h¿Á_a³±…ù
+½Q°Ö¥µì¢¹@ÎB¨qNÐ÷>ÂM ¥Â™ Ë^nˆPö°¢ÂÖí»dˆ1¥É!~ñýÔn™‘Ž!ÞÓÏ… ¢ðªæÉ[¯Á¶u¶¡e %„Ë£zØç¹ÙƒK@ª#t¤|8Bôèíí Kûo'Á1 FŒÜmᥰÚQ£¤÷yŇ“¡ãjŠ®˜7’÷¼ø÷»]@P„i8Pj3—^ÎMb¶õsá`?îç^Í÷¯Óùûœ~X_\ÌŸ<÷ ôÙs¥âët>¯å/˜KÌVŒôw·yŠúë(ÙQ›2¦ræ³¥…]ëÈ=j‘!Ð÷^);8¶ÈeÄr9â/U_íxn)±Z Ǭ™ŽÐwƒŒs#V>ÃóÛA‡W¼3=bl±žé(};蘞·. :&üSG,ÕÉðyÝ!;“wx¶Ž±/™&W–8) 5bF¦) aCÔK†Y“97K!2T±¯óO˜ Ð„‰1 kåDGéÌÏyx)çqî"ž¡âøRÌì)ñÞT¯LYAi,À<ÉaÀ
+ºžå“­Ðç0—Û-®—Û6{„áó~±Fê?sÝYÔH0D*wQj­£Tý™ ¨Žß¼ Æ]Éë6lÊ`çüj<p§ãtÑM}¥Õ|ÎUØ xZÄ¿ K&H(QZ]ªmuö”Rõœã"/2˜¥œ™>”‹¹°è)w¶¸>æ\¥£r¼|Œê“d'îyo®Ÿ«zúˆµH9áTŽ´¸ˆ={J{é̬¶>¯ÀþÉll9x›ŒK57z1,͹õÜWVaXp9S¤|÷j`ʺ=¥ÒžûNþ5UÛz?a¹„ƒ¾wüé"‡øNzÂU\¿ë3Æ×doáFeÿ1€x )`Fão‚ôò:B“³¢ÔvB(‰ùÛ0¤ ͨk}þŽÒ©™ýno4Ó:åë%莂ÙPŸr)bu„Z£þLçX'‰ŸÏ€a
+Ö,‹Â¶/K§2ª®^ÑcðÆhòËümÄlþeß¹j°$,jѽi©GZ¼[¦¡;J‡ÞvÀl¢ý•Ë¬~g vúg2jÊ¿I;"Äi˜©¯EL÷&Jì¯O#ðÕ+~§ÑÖ 5ö±¦±ŽÒ^ð€¨rÐUkFŠy¾ÀqšVr
+endstream
endobj
2465 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 245.32 null ] >>
-endobj
-2466 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 234.361 null ] >>
+<< /Type /Page /Contents 2466 0 R /Resources 2464 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2253 0 R >>
endobj
2467 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 223.402 null ] >>
+<< /D [ 2465 0 R /XYZ 78.37 808.885 null ] >>
endobj
2468 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 212.443 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 768.829 null ] >>
endobj
2469 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 201.484 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 757.87 null ] >>
endobj
2470 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 190.525 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 746.912 null ] >>
endobj
2471 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 179.567 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 735.953 null ] >>
endobj
2472 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 168.608 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 724.994 null ] >>
endobj
2473 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 157.649 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 714.035 null ] >>
endobj
2474 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 146.69 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 703.076 null ] >>
endobj
2475 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 135.731 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 692.117 null ] >>
endobj
2476 0 obj
-<< /D [ 2431 0 R /XYZ 81.145 124.772 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 681.158 null ] >>
endobj
2477 0 obj
-<< /D [ 2431 0 R /XYZ 93.716 95.665 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 670.199 null ] >>
endobj
-2430 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F83 403 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F16 328 0 R /F22 357 0 R /F81 366 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
+2478 0 obj
+<< /D [ 2465 0 R /XYZ 81.145 605.442 null ] >>
endobj
-2481 0 obj
-<< /Filter /FlateDecode /Length 3264 >>
-stream
-xÚ½\Ioe«Þ÷¯¸ i(fɲd÷õ”eÔ»(Ûdõ6ùÿ‹0ÎÀµ÷ä¶} EM|5À¹œéÛn<üû·ï~üzhSÌ;!áöçß?ćÿÅÍ3êf`܈۟¿nÿ|á\çFqn}üþú¯?ÿÁ#±@ê×é›cÞé(Á-“
-FJJ¿þÔ #ÍöÓGxþ›s¾Ô;ç2¬¦çW½‡gá»
-¿_~¾Ç98î™"Þ‰lš3Áa&›”×dÄ… %Y%
-šü•8Ré°†áÏ’àßõ½Îòt~ÔÈ0ŽÇDÍįÃ1á»5ûcâ:U³c"ÿñëh½8.®eŒ–Œë'™yþyÃÇ¢õ¤gBÉ™õÔÇšõJÞtÑSY®£1QWI…zxZã‘õ cIçŇp7HX˜SÆ[u0ç‘ÇT~}ù⟳8&‚!{ÅïÖ¯Ùk TxŽúˆòF^d‹ãmUÆX^ôvbYöKB(´)oº;²,ëàþÝg{ô“'2¤ñ.óŽ||ÆvÂ2
-¯ˆ‡QS~Ù’ìaŽuDÿÐöÓî\²ç}{˜ƒºŒ¸€¶:„¸Ÿq¯_^‡Ì‘ÏÙ‹ÆÌìeÞ×ì5P*|žaHڋ㿧£ò¾9²Ž=“0•øÚX!FÃù|S2hçfÎßÛ—k¶3^3ÉíÔvoK¶)ÝþÅ÷”G@ÓáѸ´'Þ¯í ÜÛZ±'c$4lŽúŽ±:áuÁ
-o‹–2’9.¦¦ZË‘GJE>C’šà>áÕò­ÙhlÇ¡Ðê¬ÌEZ°³óVÿWÛCs
-¦ˆ·–øŽ”dxÆJ´bƒîÊ,ë™Ðö\š¯Ë<óõ¶Q‚9'§¶YKjGJßxƒ6IíkA0
-Œ”&2Ñ.AüÛ˜¹=Ó ;êø<cïTAÙ/­Þ]6Yéð,ÚCp&í´B]ì Œ”†.Í—ÉG+WÙl—ŽÌ'ãÖQ<yºs·fé=SÛTMúå®ÁH©Ta´Â¯Ý¿^EÒ*Ï7±Ò…÷ÏUþê­eÅæþ…{zÑÎ1¥ÝÌ‹‘Áð´îí
-Å‚ï®^ŸÖ2åýLžR/ãaÛÛiøÛl¸ÖL;1/—nO „öoOh¬`åì˜Ü¨(?í¾.CN, —òèMœ#ÇË`#wõp>ÇŸŒh¹râ÷×o”g;纼mŽ~ëPO?Ñ{‘J1rjì±6ú̦:Ö‡q“"îŒZ™¨Â±ò%ãq=‡´}i„y‰š)cÅC’Î 9N&ÅC!õlü­RÚ\2ëÏ^ÁÆ1>Ž†—ÒÙ/¼e+#Þ
-
-_æö߈ìøË?"ÄÛ)KbÝ KMœ§;¢cd eleÍ„ÿlŒ]Á?$²Ø?<bU1b 5‘®Æ<ɲ—Aþ‘gTçõXÔèÍ´6»Ø÷ÃXÛ:µ;Àüì5mšñyÑ$—ni÷„¾¬¤¹Ÿ¾«·SÈœ.KyÈÛ„ƒ ·øf$½þ£ ½áÛg×’ ÎA ”5ÀŒñ.= ñ ¥M¯ÇI@¼Þì9¬²³·ö8†ØP©NâLá[eŸì§A¯µnI!'k¹Õ*åIŠÑ™v§w,‘ʹ&š
-·:£q²‰éi!ó£÷ýú¤±šÕV—2e\uû,1ÑTD3‹¨ólPiÉø®gƒ*xx¹¡°»]/¸®pŽn]Yݧxµf«)IÞ*-Çxò|’O±R¢ÙGJËo-Ðj“ê$ßÉ‹voÄâÓšå1¦yäÜ„ö»0*¡ý¤$PÊUI BBdƵVJÂyp£‘ÂÎeáÜv=) , IàH°
--QÉÝ™ xw\—†`bäÈHÁÔÃ0Ìã•gv¾PüNÛe@‡UI“^öŠÆ’Nt ±7ë=)-Ó. õ3 º¶T>m­Âæú5Ô”Jì»<ë¥ë{f§Õ^í1vÕžX¨öŠ[…Jˆ“·®Öj=Á£eÝHå‰ZO€e}¤§4KúÆg6Iå!ô…HªŒÙH> jYø¿Ô}ýRÐu^ûåê¬'hlÿy9‘pj¡Ûgù.õZ¿ Aƒ3>!øŽ‘j‡O­®$2B„ôª)í¼h¤ÝË[–P³Me »)Ý!]F©ôJ}>!¶¦¥Þð¼£@ZæÄFú&UÙÀâa
-%‰úˆANÄÓGY8*jÍØÒĽ
-endstream
+2479 0 obj
+<< /D [ 2465 0 R /XYZ 81.145 594.483 null ] >>
endobj
2480 0 obj
-<< /Type /Page /Contents 2481 0 R /Resources 2479 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2254 0 R >>
+<< /D [ 2465 0 R /XYZ 81.145 583.524 null ] >>
+endobj
+2481 0 obj
+<< /D [ 2465 0 R /XYZ 81.145 572.565 null ] >>
endobj
2482 0 obj
-<< /D [ 2480 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 561.606 null ] >>
endobj
2483 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 550.648 null ] >>
+endobj
+265 0 obj
+<< /D [ 2465 0 R /XYZ 79.37 513.236 null ] >>
endobj
2484 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 453.539 null ] >>
endobj
2485 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 442.58 null ] >>
endobj
2486 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 431.621 null ] >>
endobj
2487 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 420.662 null ] >>
endobj
2488 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 409.704 null ] >>
endobj
2489 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 398.745 null ] >>
endobj
2490 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 387.786 null ] >>
endobj
2491 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 376.827 null ] >>
endobj
2492 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 670.199 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 365.868 null ] >>
endobj
2493 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 659.24 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 354.909 null ] >>
endobj
2494 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 648.281 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 343.95 null ] >>
endobj
2495 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 637.322 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 332.991 null ] >>
endobj
2496 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 626.364 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 322.032 null ] >>
endobj
2497 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 615.405 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 311.073 null ] >>
endobj
2498 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 604.446 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 300.115 null ] >>
endobj
2499 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 593.487 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 289.156 null ] >>
endobj
2500 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 582.528 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 278.197 null ] >>
endobj
2501 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 571.569 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 267.238 null ] >>
endobj
2502 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 560.61 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 256.279 null ] >>
endobj
2503 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 549.651 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 245.32 null ] >>
endobj
2504 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 538.692 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 234.361 null ] >>
endobj
2505 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 527.733 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 223.402 null ] >>
endobj
2506 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 516.775 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 212.443 null ] >>
endobj
2507 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 505.816 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 201.484 null ] >>
endobj
2508 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 494.857 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 190.525 null ] >>
endobj
2509 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 483.898 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 179.567 null ] >>
endobj
2510 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 472.939 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 168.608 null ] >>
endobj
2511 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 461.98 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 157.649 null ] >>
endobj
2512 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 451.021 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 146.69 null ] >>
endobj
2513 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 440.062 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 135.731 null ] >>
endobj
2514 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 429.103 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 124.772 null ] >>
endobj
2515 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 418.144 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 113.813 null ] >>
endobj
2516 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 407.186 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 102.854 null ] >>
endobj
2517 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 396.227 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 91.895 null ] >>
endobj
2518 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 385.268 null ] >>
+<< /D [ 2465 0 R /XYZ 81.145 80.936 null ] >>
endobj
-2519 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 374.309 null ] >>
-endobj
-2520 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 363.35 null ] >>
+2464 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R /F22 357 0 R /F81 358 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
2521 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 352.391 null ] >>
+<< /Filter /FlateDecode /Length 3228 >>
+stream
+xÚÕ\Én#»Ýû+ôÍ&/g@0`ÙÖ² ¼ ²MVÙäÿóp‹U"ËòCÒnI%òðN¼iS"/ÿ¾P÷ÿ/·¯—ßwi/‚XÃ8\¾þõÂ.ÔýeD‰‹VŒPÅ._ÿ¹üãJ©J• ”[÷úöúϯ¿½Pæ ~߸b•â¦Åa Ó°Aúp(Ê¡¸WeÓ+uÏÜ
+šQÊÞãgáž ˆ¯üæç½þ’ =‚-ïüwoqnqnÀpØ’%l÷ªEÄ Ïw°„'Óx?ÏÿËGs„§OÔ±~‡A†JèCRÂ(ŒôÁíš>Ògô°Ü+Ü«^<VÖ‰Çi̲œ\¯Ï¥ù2ÍSÏ× ·„ >ÔYÓ BBtôfxYd¹›ƒÊ—ßW^Ÿ‡ö®#^Їªs–äš÷ß­Ž’q‹ñyòëÙúC˜üÈ—É5ý ¤D{ ÑöûH˜*—vø÷Á†äã}’bës4­6Áu¤ÉÏÓ? c¦ €ÊX¬É!y^x•a°ùÆÁgü.ØzâncsÆŸÉäo¼üŠ,3-³ö:ÀS‰®ÿ2Ö4‹ú¡Š€RCÅ×ôƒOžlãö2’ÍÎÝ)Vó€°'Yï'G6r„åýZϦbКž”•„S=Ò“ø\ÒF:àá¬l=–‚*Ó «}aÌäkÊDº}\\Z×ÄuC¬Û·ÑEÍA¸°ÍùµÖ24ŒÔÓþž|¯þ£øÅϳÿ 1hE.ïUÿâyη²ŸÅÏŸ…ÏYõ©Kø‹ZÒœð¡’$¬)©šàîRò–›=WØŵœ=Ù3×ú¡H¤ÁÙH궦„”øñ2Éþ”g»×Ý£>NÈô³âÕŒí ­~Žh2£œÝ©Ø9’¡a¨·µŽ
+Ú±~4\Sg?ѵœqÀY˜k2Ë[-T;$À鸕ßµ‰ŠƒKw\Ù„,Í ˜såT„'ezcÿá5xÏÜdkó|ûoõ5ŽæEVp­ú¨¼æÌ7{l‰ÝÜçhóÛ{«:¶Y£u5Éj('J/ˆ§Øì=Eô‘/ mÝéùŒ~MZ]šÅ=!Œ%Ô æd˜ Úw€¸E¸5øg‡Ž¥™ÁŸq„ÀZÇWÝPë¡Ü(©Bþ–\m~1*iyÇ>E( Ì”ø᳞b­’ïØ‹ÞÚK\É9¹ÁJL
+î8¼ËŽBWÌÛF,CŽh-‰bÙãõò¬hÝ—ãrPÒéŽ*¾KUøf£
+“OØ‹ï\ºL£Þ¤j+!ì³*áò"…×Z© ´‹FÞŒÂÎáØ}}PhârA ˜Cdgÿ½@¼»¡k]“UW.„C»ÛéOÛ3Ðl;D»ôÁÚ;[ùÊEPA¤+´’³_ÚSg¯®™YsÍEB¢“Ö­‘„˜Œ?ñ³S,m9°Tá4Æj/!oÙ´ÕÛf…g>§*±I3áïŽËSLÇ„$Ÿz†œz¬`xfg Å´]3h‡NPnáÊŽuNcoÖ-*),ÓŸ1d*òmŸ¾;ÏEkÇ°š~ 5iû>Ös×·Î}¥ÕØ}l¡èKfå2n%ÕÉ’Q¯YƒQN”| 4o#=Ò(éÃÏl’ÊC×G]Mæ¶6æ|€Íà/)ÿÐZÎëq k4„¨tJ~?*rh¦ë³”§ª ­Óx„G”‚³ÅÅ¥RÌd3T­ÊQZ>*ÌÇÊ¥õKkªPRN¡½!çi:Ž\Hì)„ø¾ª\'74¯*àš¶á¾r•v1»«äˆG}ØhNÇýíœâñ«%m ÷¢%k ãrc8œÀçj™6ç]¢Þ°kûíÁ©Eã¼/ž]xøtà°3·"e¶%wÅÝîv—g;™ÖžÆÃäòØ£1C”ËÜêL¼äàòs¶¡§ë!veßvk’^Іeÿ¯†Öz‚WCˆÁW4QÒk>ö¼ÝbÆ‘@, p&/Ĥ~Úï'=ÈéÏö“À¢V Oggo‘¤~Bzf?ilߺá
+ˆR:põÇ~.”Ø&§«Ðϯ—?ù;4j
+endstream
+endobj
+2520 0 obj
+<< /Type /Page /Contents 2521 0 R /Resources 2519 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2253 0 R >>
endobj
2522 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 300.463 null ] >>
+<< /D [ 2520 0 R /XYZ 78.37 808.885 null ] >>
endobj
2523 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 233.737 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 768.829 null ] >>
endobj
2524 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 222.778 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 757.87 null ] >>
endobj
2525 0 obj
-<< /D [ 2480 0 R /XYZ 81.145 78.635 null ] >>
-endobj
-2479 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F83 403 0 R /F65 327 0 R /F75 330 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /D [ 2520 0 R /XYZ 81.145 746.912 null ] >>
endobj
-2530 0 obj
-<< /Filter /FlateDecode /Length 3431 >>
-stream
-xÚÕ\Ko$·¾ëWÌ—,¾A€F£ à[œ½>9ˆ/ñ!¾äï§ø(¾»§[»‹$khwÔCëÅbÕÇjs¦/¿_8þý—§ëק/wí/Šy'$\¾þãI\8þ'.˜QkãF\¾þqùå…s œŹtœ[ÿúëןžx †¤¾Üº8æ‘®¥#¸eRÁHIé×g :ЬŸ>Âs¤Ž«Xƒ?ø¯¸"çîá{ ·2ç†spœºâgUǾ+£LâµýÜš3Áa%·†cr `\„€KF$†Å;>½¡Ï²(=J®X4×S,ö„*‹›6zOl«k²•vó3£xkûÛÛ†ïÕ-Ù-<“6ÿhŽ*o G·ÄAµv#Á)êè%ù“(œ¢—Ú‡À1š_èí”zBN²$,Ð+–äÁí,9sÖO”ôŽ_ÏfùŽ›?¬í6›ñ{î6n³Ôœ;¦9¥20Rú_ÞnU“§ßxÍ$·Kçק<m¤äÏrâ@~ɉ:ÇÉ@©óye’ƒŽìýÖz1ÜÖì
-A0µ ”öØ—»Ð³
-î%ÑÔâšÙ¸d¢ãÓkˆB˜-m–Ѫ•Œ ñ¤eÌ;~K/KÑ,nœ“­]e.ܨª'â9ž7·Vñ[Õ6ù‡fD=¥3`°H¦]‰ôÆ’<N®äñžáá:N& LD³^w•(@3 j¤ M¡Q¬²æ]U ‡9<L¬‘×
-áYI8¯^:!³p½zÄ{Q_ ¸ÅqÒµÚ#,»ïJ1‰Æ|–Âú+A¢jåºB0SCSk,ÅçL æp«!XqÕ˜?šØÅ°’,½ýÒèÅj&¯Éa
-.5AÜ+Š3åÅ(Õ KƒÑL… ÓSèa
-z™ãFåô¨îd+²[7»CIjIŠ §Z«fí”f+GVÃ6'š)jí
-¬„cÆøɺȞŒYøY+_)<6gÍ}*8p@jŒŸÆ–½éÝò^“|:
-ø ï”à¿Ý…·XÌ™‘Ï5†±ï“R0§ÝDiá“IÎÎ'{Ñ÷|2}rRæ®Ojƒ…¬Y=铘b1Ã'*ŸñI.™3³ê6ëÏý½¢$³</XÆö–ɉ€X’u–YÜ‚#“·Ìؾwh®q«qvësØ×aÉ
-V5Ù«(qLRÉ|Úö‰ÞäëDG(Lܸ=“èX`Z‰‘€X£âSŠÝ%°ÀÃœ½'¸Ìí4®m­+G‰Hy"…¯èÙ.«ê=Wxá¹üÊúåçP'X½•È \c\k>¶jű¡)Tµé[ør8&s>"Oe¦LÊqj*ä½c¡5hØYô¤2lHï'z;qó‘R€; zæÓÉÂPk *z׌>Œ•ãÑàÁ„Ò‘T·cÈSíz0¥§Ñê¬@xr;oVÁ3ø?Púžø_¿¾ ô×x ziWòFÔ ³ÚŽ”vqÈãèèA9©IàÌ×-Õiòíœ&{JßI“?ò’éË`;=UÖ1¡ôx–J–l&gd%ùÌÕpÄo2Ž’Çk™ä C÷@%<æöÞ¼HóêäK­ÓÁ»!]ïp˜Fö’(¬9Lú•Ül R‰RE³ˆZÉXoÄ¥R J^ OH£Iƒ‰bÙ®Z¹dº™£f®sᆿȔÁ³·Aì®u|(œ]S8—BCO˜•V#fuKGAJâœgÑTz+þÀ¯âÜ.asÃXñNÅPx
-»ö{ Á:Úµƒ?âÜRR¹Œf¤uZÌ(x…n½hKê6Æ>[vˆ¦ý’½e/Uxêz,P{-óÑ:ÀÌGÍdñ(ƒÛ·ßÂo´b U ÁD4VØì³
-ª-:;Üêw±RîDR®³˜ð «ŸÐ‚pŠi1Q ]–2˜Áß…]U˜ßiwÓÓ£û=Q.þ(îøo´UDØÒ½b¡0à¿#ìUJ¢8ºxî¨ùüýaÀAýxÊÉŠæS\̵ÉÇקÕ¼L‰er
-«uÅt5ÂÂ@ãK”ËŠ=ÆÙ¾:3óé=iäpÛV²™NÉnWÉ„õx™$¤Ü„)ÛkKuëŒç:­Uùó÷Kú1a.ë éto ™3…E÷·å@7o‹2fQÒ–Üku xÙJªO©´bNÌáö†$nýåçmP$[W)¦x‡8Ååz‘:Ôº³ð`ð%¥·¿v8“ÅÃÊŒ+ƒYƒKF2Ì5ÇÑ„#7ü%døsÿܬ¿j9sž®1¬¥K®°«ìNñc;×ã駹ðÀ:u¾·0£VÞSõo®åFý˜–ÃA ½˜èÙƒü„+Ôð0_€‰ÇÔ‘ ‘ý+ðÁ×Uð·;½¾?~q<Bٻ׉
-VÜ&J²k¶%;>Á›•Ì8¹äMã­§´Ùʬ׀”(Ç*ü^Ó¥X^ç¾6½ê9¤ÍvÛëˆ ¹¢>{ù˜µôUyNO=¥•žŒèÙà­÷®UÛ?’ñt×hÁ¬Y^îîúËòõ”Vòº# ¹g_í»NRþcì«0!às¼UÇ_!ù{Jg[ú¬–¾Ÿ¾À3§ìJ_GïÎH_=¥Çû!Ô–Y²?Æ„cι•dGoÉH²žR{·ÓÊcè®Ê¦ϘËåûv+›Ì&û|« nmÿTÜç!=ðK)ÏÝ`”ŽtùÆFKµÂT”0 ür«ô„ò/‚ê•ÐMVgoÔy¾±'à`‡‰Œ @ƒA
-œ´a«®ŸÝφ9L .¤-5²mm¹®êìª! JÍ™mîÊßjmw8Ž %W/áÅ76NÕ‰¡íBq}#²ºuØ*¸>]0âÃÕë}éõ”Sã@ÉŠþ›ønïlA¹ÒÇTDv×Ùë8î3ÝaÈö†Èb(ÄpE„á}ÍêN`<ß¼@Íq”×ë‹—tË‘`ë’Yt_ïcWÚd5`KÜHI¿Ñ«5šžÿÔ‘;÷üg6üŠ aÂÛ„nàc3̬eÎ2¨&Å…ÔýÛE; ÆX1™co‡¾„ñq†ÌØY OP_»–¶ø)ï0¹|ŠïF9¿œC±Ö/cíxPùî šº²˜š BhU/uTû†ˆY4NÌÁØsÆë5\¿†VËŠMk55Q̳
-âåjªX_#hRÅøðQªÊŽbÊÌøÒÈ1ãKO§ÒhyAaê¢Õ çÉÈ^^ô~ÔÕ:äìû5 ­ÔzˆÙ¶¸.´]¡ûÞ¤ðœÀä`<^n›[WÍ´/´eSð×Ø"Uún4¿­ízQ„ÈO7u¢  éþ_ëPa’-5 bê Dú1+§û¸†NAÚòxŸLY”ƒ#ÅêÒxG-mä…ýè¸hŽûÖÝ•È´»«ö ÒÓî=ÏrhС ;*’åÒÕ§Ò9Õ‡íõ^“Ý;(¶Óßɽ&Aaô›ˆ¸}üÂcf­ Vbmrkc†ú]̉Ã
-endstream
+2526 0 obj
+<< /D [ 2520 0 R /XYZ 81.145 735.953 null ] >>
endobj
-2529 0 obj
-<< /Type /Page /Contents 2530 0 R /Resources 2528 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2254 0 R /Annots 2561 0 R >>
+2527 0 obj
+<< /D [ 2520 0 R /XYZ 81.145 724.994 null ] >>
endobj
-2561 0 obj
-[ 2526 0 R 2527 0 R ]
+2528 0 obj
+<< /D [ 2520 0 R /XYZ 81.145 714.035 null ] >>
endobj
-2526 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 244.87 353.434 255.296 365.605 ]/A << /S /GoTo /D (Hfootnote.38) >> >>
+2529 0 obj
+<< /D [ 2520 0 R /XYZ 81.145 703.076 null ] >>
endobj
-2527 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 106.14 154.081 116.567 166.441 ]/A << /S /GoTo /D (Hfootnote.39) >> >>
+2530 0 obj
+<< /D [ 2520 0 R /XYZ 81.145 692.117 null ] >>
endobj
2531 0 obj
-<< /D [ 2529 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 681.158 null ] >>
endobj
2532 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 670.199 null ] >>
endobj
2533 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 659.24 null ] >>
endobj
2534 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 648.281 null ] >>
endobj
2535 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 637.322 null ] >>
endobj
2536 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 626.364 null ] >>
endobj
2537 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 615.405 null ] >>
endobj
2538 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 604.446 null ] >>
endobj
2539 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 593.487 null ] >>
endobj
2540 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 582.528 null ] >>
endobj
2541 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 670.199 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 571.569 null ] >>
endobj
2542 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 561.624 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 560.61 null ] >>
endobj
2543 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 550.665 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 549.651 null ] >>
endobj
2544 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 539.706 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 496.849 null ] >>
endobj
2545 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 528.747 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 429.103 null ] >>
endobj
2546 0 obj
-<< /D [ 2529 0 R /XYZ 79.37 490.1 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 418.144 null ] >>
endobj
2547 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 314.328 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 272.69 null ] >>
endobj
2548 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 303.369 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 261.731 null ] >>
endobj
2549 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 292.41 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 250.772 null ] >>
endobj
2550 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 281.451 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 239.813 null ] >>
endobj
2551 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 270.492 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 228.854 null ] >>
endobj
2552 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 259.533 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 217.895 null ] >>
endobj
2553 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 248.575 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 206.936 null ] >>
endobj
2554 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 237.616 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 195.978 null ] >>
endobj
2555 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 226.657 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 185.019 null ] >>
endobj
2556 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 215.698 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 174.06 null ] >>
endobj
2557 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 150.952 null ] >>
+<< /D [ 2520 0 R /XYZ 81.145 163.101 null ] >>
endobj
-2558 0 obj
-<< /D [ 2529 0 R /XYZ 81.145 139.993 null ] >>
+2519 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F83 403 0 R /F65 327 0 R /F75 330 0 R /F81 358 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-2559 0 obj
-<< /D [ 2529 0 R /XYZ 93.716 108.947 null ] >>
+2562 0 obj
+<< /Filter /FlateDecode /Length 3157 >>
+stream
+xÚµ[Ko$7¾ûWôE¢Þ€aÀívÈm³s rÊbsÙ9l.ùû¡Ô»ª«ì™jÜ­’(>DŠü¤æ—?/üòóÓõëÓOw¡/žyF]¾þ÷Ià ~ë™´kãF\¾~»üö̹œ[Źxã\]9×øY9lÎáíå÷¯¿<áh¦ð1—¿Âôåןq&»œI€fºi.˹á8‡seÚ‰m¤¤–””ab¤cláËaŸÌUøˆ<•‘Z0)Ç¡AÄ ªñÈνc¡ ´À@ÃΤ'•a-Sn¢§ *<($(ÆøCJî˜3zæ0›¦ü?PÒþ¢˜wBBKÉCÒV‹/œ•)Žœº8äÈH×Òñ–yp#¡°Ž‚h•®ÜË :¬Ó®|ÄRÔ[H
+\r%z?$à–I#%¥‰']?½‡öä1·Pe€{xO=áVÆÜFomå­9+/pBòJ‰Üøcò
+ì¶#%àÄ“É:ÁŽÁžŠT¥Ï¦vÞj| ZÒnn30Ò_k.¸MÐjx¯nÉ‘C[Ðfühñk’{t~½Ò¤†sšì)}'M~`­Íb½ýtØÞ7Œ1LqW‚MØ#î‰{©äs²` è«ly í¡‡zN³KKýµLr¤Pœýà–9Yï`Â;f¼y‘æÅÉg’îå x÷\éÁû¦©•(¬9Lú•Üts$ªu®¸É”—w¿ÈḠý Ý ñCV*ë¹P% &ŠÅ\µ²‚J+ZºŽÕiÍ”÷†Ÿ%‹kÅ”.±®µ?êHÇU“¨-ÍK-¯HÈÃ-e$YS´ÃiLôhþ`]ű1Ž»Üilè+Þ^À>™C+ìÚ?ø@ˆKèÑ®V¼¸0B–±¤¹¨kWæ¹¥Ñ1[
+«B·«hKaÞ>öQßâ!šü%¯–äN®¼mļ£½âî«hUíú•²†ie&‹Gܾýë³
+­z½„ñq—“Ù¶®ÆEôµ`‹÷¯Oÿ¯y-&’£0éâN\þøöôÛïøæ?øü‚Û·õöòwìû Í­˜±øñ—?ý+•=Ù²ÁlÙ¢{Ï4”ŶáV‰©èAÖ‘Ù`§÷êÿüz›gNh'–Ã:ú
+uB u½-ò[i¦˜ÞRh»›Ý .¦QE”q(…
+2Èûø¶ÛHŠþªT“Ë¡5+2ÃôÑ¥3s÷ª:¸vSÜRë¨Rl͘¿má
+a2×3`ë@hl ì“Š(ÆèLÔÏu­Ò2ý0
+†aN=Q’-„§mIOðfókPXºs¼õ”*LÙØà–"Bk/Ê”c~¯ùR, ¯¥W±‚^
+ìCo)¨i À}™´ÁŒh)ÂjÍ••l–J–J<†¹AÍénIE+Ö† 餩d¡s½Ú@U
+¤´a«öH£ö«†9R KHi&µè¹ZÕ'‘·P·i~­¶…ÞäÙÌMbå­¸ZÅòs¥â@h»T\Š¬N¶J®—Œ8 SJ/…=W2”¬èϼ‰ïvñ-)Wú˜ÊÈ1Œk¦y½—7ÓàÝPÜkhHÏx´û a@N'Ж~x¶.»é]$¤å´~î¹å¤½‘)nœ,W0ý ¸% z#&e£^÷Á-i5Sf”÷÷Ýéœe&,ÛÑŒûÓy¬òý4ê4ˆ^D$oá,GqÅø™ÒëÂäxm-žîÝÖõ‰4Óû³—°À´w÷Ž"$]O©«@Nò„iŠ‘ëðt%Ћ9RúáˆV[;šÏÙE;LÙÌR‘#cN0PJvQEf¾øöHâV+Ð_\jCÏu¶Ú¨ã ¯øxzñ›ù"x:?­\e™v¹èå9åö”ªr“s›çîE\‡Ôé¼Q×w.ñA†âÕ¯´x¼ -ö”/Ñâ°ös šuÀWº|ï ÕÑ9›Æ‚PÌ)±âã($A|ô”L{—ìÖ\ɘoØžä˜ãp°âø`â]8(ÕÀ„Áƒ\ròzŠ“‘Òj£ßŠ
+*={Û~ØZ†íÅOQÁn¼SŠo˜Œ÷#Kžžõá*Q­4~8µòÌr7Qú`¾°‚!©%wçR£Rë_;0ûý ¤0œqe–«ö`²$9sÖO”ü|G,•SB:æ`¾3(Û xV1#ÄpO\4–ñVwó;O¼Pºx_c¾@ƒ
+¬®-G‚mÅ-qï5ž’óE¦þ‰ E9ðNßnùú˜¡ûÊ|’¼Á¶twD¢!|,‡À¸‘‘M g-À*°”ÅI¨Kä«Çp`¼Ê="1SŸÙêî7%¼'…#d¾hF€Òן…lñC—Û ¡ã}x{ù¢œ_Ž!$Ë/‘¬±ö 8]'O\Èbl$3UoWèoq3}†º„ÀxÔÃt“¤kìÓõM k5]SŸGÓ ƒ¢ÕkÝ[ºþl@í`péºZ¡ƒé:}¹B¯Ú˜…¦x#9¨¢_®õP+z©Fuƒv½IJÅ´ã =Ú°©0ññú oÃÅÝ]¾¼`J¹‰/Š0û!R`^Q÷‘è|"†v«»T \Åã£íF<>6>Â㱉£ÜAX=õñ´Ô:A­C0(üV£ 'C0\ËOÚZÇžýõÃ>Púxe½¿¦0 R 'áãEb³c煮f§#sð—øs”’èßh|{ŠÖ‰bEn݈ى‚ª?iÙÒ¢2S5ŒrÅY¤Ç¼¯ŒœŠâÆΛóxvI
+endstream
endobj
-2560 0 obj
-<< /D [ 2529 0 R /XYZ 93.716 89.795 null ] >>
+2561 0 obj
+<< /Type /Page /Contents 2562 0 R /Resources 2560 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2253 0 R /Annots 2596 0 R >>
endobj
-2528 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F83 403 0 R /F65 327 0 R /F81 366 0 R /F75 330 0 R /F22 357 0 R /F16 328 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
+2596 0 obj
+[ 2558 0 R 2559 0 R ]
endobj
-2564 0 obj
-<< /Filter /FlateDecode /Length 1686 >>
-stream
-xÚÕZÉ’ã6 ½÷WèCàV•ê*{lOUÎ}Kåšœòÿ×!%j£`‰tÛäÐmY"ŸÀ­º¿;Õý|;¼}¿iÓ-w½éø@uºsÈuÎjPVwÿtü¦Y¥•ŠʦϠ^Þ¿Q|êð}…ã¼¥oJéqžŸÇe”8›nãÝáÛr6¹8nñ¦ôÖ4/ñÙ9ÝGFOß(¾ÃΈéiš³”tx’Ð𜥞$IÒ¦wÍ’ïĹÉñpÓ¤ÅÙ÷??~¬:–X%k!hÜðêò,Yä °-'¥eYµÿ:ïÀÆ[5î¿. ø°™e|?KIÖÿÿŒ&t ÁkÂ%‚GHoåøv?ÏOjäüg¬l‡ßož;%±ä—8š`Ø"Þ¿4éÊLW4]]Ó1×t=Ý «çvóܶ®Ž,8Dquܶº5ªÅêeBÎ’$QL&€F*‘ØŒGþ¬–·¦ññ:o»~f§‘6R¿}š?"áe©´ŸÓ‹fðŠ%øZÇ%ð¤K¤A/<±a7l®xÉJv‚£‹Ù˜Ñq¼âÉ:¬^±–-ìå+=Ỹ´2ê!rU¤†MI.QÛDîi&wØÜvgs¯—¸Ú.Mtõ8׺î?Mñ)¾­E›¬·‹#V%‹Ò±‰¾dúOmØèØ! “Ø°ç&§U"…VIœŠà^”äÔ&ÉÉæ\£Ïd.c>4h#1œ¾ã¹Ï8%¶
-”
-’ÄÚ$.š¹ã
-/Eˆ Ïàî<?ð+Óþ°³CÞ÷.3bû¾!* h­µéU
-tð¢ÛŽâJ¤J棼ã+{¢b~ó̲›l
-¤SÍþÙÛ7}óâ`LjÉ=!§'4ÀŠDNm,¬‘žÕ–Ûå¡ÖGðŒùòöé¸Ë™%FÏÎJ¤×·çH°·¢ìm9B‰ôõ : hÙmYF‰ôÌz ÆŠŽ»ú<khЕHψ*1°‚UA´jòRE\yøÇ$Õf$sŽÓÅpö`·-{®¹IW
-õìrZ•œÅ)/rÆ<äc½¥¼¤tjŠŽkœ6‘ã3ÄsÚm¡‘º¯Ò½üëž”‡Zc»˜R7ÿÐL‰ÍõãíÚ—ù
-endstream
+2558 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 244.87 541.675 255.296 553.846 ]/A << /S /GoTo /D (Hfootnote.38) >> >>
+endobj
+2559 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 106.14 342.303 116.567 354.663 ]/A << /S /GoTo /D (Hfootnote.39) >> >>
endobj
2563 0 obj
-<< /Type /Page /Contents 2564 0 R /Resources 2562 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2254 0 R >>
+<< /D [ 2561 0 R /XYZ 78.37 808.885 null ] >>
+endobj
+2564 0 obj
+<< /D [ 2561 0 R /XYZ 81.145 749.9 null ] >>
endobj
2565 0 obj
-<< /D [ 2563 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 738.941 null ] >>
endobj
2566 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 755.449 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 727.983 null ] >>
endobj
2567 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 744.49 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 717.024 null ] >>
endobj
2568 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 733.531 null ] >>
+<< /D [ 2561 0 R /XYZ 79.37 678.364 null ] >>
endobj
2569 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 722.572 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 502.559 null ] >>
endobj
2570 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 711.613 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 491.601 null ] >>
endobj
2571 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 700.655 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 480.642 null ] >>
endobj
2572 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 689.696 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 469.683 null ] >>
endobj
2573 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 678.737 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 458.724 null ] >>
endobj
2574 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 667.778 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 447.765 null ] >>
endobj
2575 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 656.819 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 436.806 null ] >>
endobj
2576 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 645.86 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 425.847 null ] >>
endobj
2577 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 634.901 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 414.888 null ] >>
endobj
2578 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 623.942 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 403.929 null ] >>
endobj
2579 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 596.186 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 339.172 null ] >>
endobj
2580 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 585.227 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 328.213 null ] >>
endobj
2581 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 574.268 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 299.322 null ] >>
endobj
2582 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 563.309 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 288.363 null ] >>
endobj
2583 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 552.35 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 277.404 null ] >>
endobj
2584 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 541.391 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 266.445 null ] >>
endobj
2585 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 530.432 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 255.486 null ] >>
endobj
2586 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 519.473 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 244.527 null ] >>
endobj
2587 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 508.514 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 233.568 null ] >>
endobj
2588 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 497.555 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 222.609 null ] >>
endobj
2589 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 486.596 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 211.65 null ] >>
endobj
2590 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 475.638 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 200.691 null ] >>
endobj
2591 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 464.679 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 189.733 null ] >>
endobj
2592 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 453.72 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 178.774 null ] >>
endobj
2593 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 442.761 null ] >>
+<< /D [ 2561 0 R /XYZ 81.145 167.815 null ] >>
endobj
2594 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 431.802 null ] >>
+<< /D [ 2561 0 R /XYZ 93.716 138.708 null ] >>
endobj
2595 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 420.843 null ] >>
+<< /D [ 2561 0 R /XYZ 93.716 119.556 null ] >>
endobj
-2596 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 409.884 null ] >>
+2560 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F75 330 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F22 357 0 R /F83 403 0 R /F16 328 0 R /F65 327 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-2597 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 398.925 null ] >>
+2599 0 obj
+<< /Filter /FlateDecode /Length 1612 >>
+stream
+xÚÕZÉŽä6 ½÷WøF-‘Ô TuU sß‚\“Sþÿ:’wË´-Ö2“9t—ù™;)Òºù·ÑÍ÷·ó×ÛûÍØ&ªèÀQóõÏ›I7tcúÆ;£´3Í×Í_hMŸZ[ó!{Ð.ß±=ë®" Wà–Ï´6é
+Óºt–þ\LwoÃÕîlþ´ë×´O_:´|ìt>.Wå«5¯Äs¾>¬°&]ñã&
+Üô¾|·Eù€´Â]òŠáJG÷®ÄûÅæ†æsÏ1•é)ú03iáãï¯?ß´²Y7éÿ÷¤R1„¹j¨¤+O^øA56cf/¿ˆ:¬^Ëï·@MH*væ8†´‚¸F:}|³`ó‘p<JÄÛkþ¯Äù½ÌäÞ}{[ÝwRÎÑ)pãQÆù 4Ã9' ¹
+ÊFÏ*ÓÖ)S{…%’7óêc¢;×Lˆ¿nñ—“6/;2ˆÝ ½j™ax—¥õé0­£ïÓ×e;}£c׈Íœr>²æ,KáÒ"… i2Vy6¾ sሬܦöÓKa_óÄ=¦MÊ»U"rçúœê’¿¥KÒ¤•-ir<—J¿‡v¬4lmÑ•žšÙ=|•[>Þ-_Q œ|k}/߉+\ªÝmHMž3ºªµó9:zÙÑéIÚõšK?Ó\mñ3hn‰tì/Ñ—(NXoTHlrÒ8‰Be‰$-û¬Ó©ªq%(ÛH/Û¶XÊÍÏRdHbÙaTZV‹VFItÇ–ù¨îÈ™­Ènq%ücÛîö~£¾yæ¶ÛBPš"+ùÊÏ’"ãVHÏØJYã•f‰–fK ­ÔLÚB:µSÙj¥¶`C­BªK$©Ä(ZeÖ¥£;Õ×M½ÈJ¤SÿìùMÛ¼8X“[rO¨é)ƒœj«›A
+K¤gµåvåP#hÂ|y{Ž<*°ÄI´¶êè#t‰ôúö9Hº´,í²¡Dúù :²F!:Ža•Q"=³AGÉ{Ð–Ê jЕHÏÈ*1e¬ÈÚƒ•E‡%RE^ùf´Õw9  ŠX½÷yºX®½²Ú°@I“®
+ þê8/œ¢—ƒµšàÔG­sÁÜ<ª]p¦œx‡Z¥î‚Ê®Ê ŒÕeÐ ÃN&,p{¢hjáãÛ¼d­``~×æ'FÑÂÞ3ìâ,·óùynÍmÕT;†å!ñÁ­Æ{4¤4yϵÇíùÉïó =´cñó$:/ÇòNZ@HQ5FÎN* ÅÞN
+ }V–jd˜«ý)ï{¡yPH¡tJ4¾¯ªr¬8õ\ÎRÃÀÁ]!0íY½çÔ^YÍj_ɈN÷‘¨Óš(7¡ðþê71m´Âè@.Ì>jiý~H_Cbè®î|v#3 ´"kY“8IL¢
+¤¦›rlmVÝr춰K ßhºiÀ*·žn¢à³±~†S ýÓÍÏYÇê²~b×öÙIÛ½;jcHyÍÚamÓvPÂé`ÔˆÛãʹSý:>y`i4*¿Xbò ¤_;°¼×ì"(¿Xfi¿°+€¤]°`T
+endstream
endobj
2598 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 387.966 null ] >>
-endobj
-2599 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 377.007 null ] >>
+<< /Type /Page /Contents 2599 0 R /Resources 2597 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2253 0 R >>
endobj
2600 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 366.049 null ] >>
+<< /D [ 2598 0 R /XYZ 78.37 808.885 null ] >>
endobj
2601 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 355.09 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 754.995 null ] >>
endobj
2602 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 344.131 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 744.036 null ] >>
endobj
2603 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 333.172 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 733.078 null ] >>
endobj
2604 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 322.213 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 722.119 null ] >>
endobj
2605 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 311.254 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 711.16 null ] >>
endobj
2606 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 300.295 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 700.201 null ] >>
endobj
2607 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 289.336 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 689.242 null ] >>
endobj
2608 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 278.377 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 678.283 null ] >>
endobj
2609 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 267.418 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 667.324 null ] >>
endobj
2610 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 256.46 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 656.365 null ] >>
endobj
2611 0 obj
-<< /D [ 2563 0 R /XYZ 79.37 223.118 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 645.406 null ] >>
endobj
2612 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 205.551 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 634.447 null ] >>
endobj
2613 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 194.593 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 623.489 null ] >>
endobj
2614 0 obj
-<< /D [ 2563 0 R /XYZ 79.37 161.252 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 612.53 null ] >>
endobj
2615 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 143.685 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 601.571 null ] >>
endobj
2616 0 obj
-<< /D [ 2563 0 R /XYZ 79.37 110.344 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 590.612 null ] >>
endobj
2617 0 obj
-<< /D [ 2563 0 R /XYZ 81.145 92.777 null ] >>
-endobj
-2562 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /D [ 2598 0 R /XYZ 81.145 579.653 null ] >>
endobj
-2620 0 obj
-<< /Filter /FlateDecode /Length 1724 >>
-stream
-xÚÕ[Érã6½û+ôîzÁR5å*{Æžªœ}Kåšœòÿ×4HPÁ– H²“lÉôØýzE‹v‡¿îðëáåýáÛâ!Cøðþçƒ×wð‡˜â!.øÃû߇߿;’sô¦?øôH‰ô
-ëñúúS¯¾,WêOÖ§+¸¬–ëO¼ÿöà@Š
-JÝoE.;©üO÷íU\PˆG¥
-µH£9Ë‹
-'Ïp_ ù¢ê˜µeæt½ê¤Q/¡å.ÖáY*ÞZÕ¡ªÊª¨“6š&mËÕY5ƒµKª°›£·C•È&€žÝ]j}­¸öôá:º.Ú'säYÖjµK<qv-šŠfÓœñ¥zíÛæÛ¡ÙýSœZûE¤:’œsÁôÌý#ð>S¶\ݸÝqßÑÝÒéŠÔæøˆ_ÅZ£ú¸ÓR–¿4Äê»BÔ’ê®E‡Xw.Rïw–aࢬկj:[ºÑsÄ\tõ#¯6²9§xÙÌ>ëY˜šK˜Âsôÿ ìÏçóÛCÿ±Á¹üoVnYr;¶ßùã
-endstream
+2618 0 obj
+<< /D [ 2598 0 R /XYZ 81.145 568.694 null ] >>
endobj
2619 0 obj
-<< /Type /Page /Contents 2620 0 R /Resources 2618 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2254 0 R >>
+<< /D [ 2598 0 R /XYZ 81.145 557.735 null ] >>
+endobj
+2620 0 obj
+<< /D [ 2598 0 R /XYZ 81.145 546.776 null ] >>
endobj
2621 0 obj
-<< /D [ 2619 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 535.817 null ] >>
endobj
2622 0 obj
-<< /D [ 2619 0 R /XYZ 79.37 773.016 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 524.858 null ] >>
endobj
2623 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 754.882 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 513.899 null ] >>
endobj
2624 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 743.923 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 502.941 null ] >>
endobj
2625 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 732.964 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 491.982 null ] >>
endobj
2626 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 722.005 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 481.023 null ] >>
endobj
2627 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 711.046 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 470.064 null ] >>
endobj
2628 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 700.087 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 459.105 null ] >>
endobj
2629 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 689.128 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 448.146 null ] >>
endobj
2630 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 678.169 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 437.187 null ] >>
endobj
2631 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 667.21 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 426.228 null ] >>
endobj
2632 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 656.252 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 415.269 null ] >>
endobj
2633 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 645.293 null ] >>
+<< /D [ 2598 0 R /XYZ 79.37 379.268 null ] >>
endobj
2634 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 634.334 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 361.248 null ] >>
endobj
2635 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 623.375 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 350.289 null ] >>
endobj
2636 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 612.416 null ] >>
+<< /D [ 2598 0 R /XYZ 79.37 314.288 null ] >>
endobj
2637 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 601.457 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 296.267 null ] >>
endobj
2638 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 590.498 null ] >>
+<< /D [ 2598 0 R /XYZ 79.37 260.266 null ] >>
endobj
2639 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 579.539 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 242.245 null ] >>
endobj
2640 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 568.58 null ] >>
+<< /D [ 2598 0 R /XYZ 79.37 206.244 null ] >>
endobj
2641 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 557.621 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 188.224 null ] >>
endobj
2642 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 546.662 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 177.265 null ] >>
endobj
2643 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 535.704 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 166.306 null ] >>
endobj
2644 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 524.745 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 155.347 null ] >>
endobj
2645 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 513.786 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 144.388 null ] >>
endobj
2646 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 502.827 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 133.429 null ] >>
endobj
2647 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 491.868 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 122.47 null ] >>
endobj
2648 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 480.909 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 111.511 null ] >>
endobj
2649 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 469.95 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 100.552 null ] >>
endobj
2650 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 458.991 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 89.593 null ] >>
endobj
2651 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 448.032 null ] >>
-endobj
-2652 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 437.073 null ] >>
+<< /D [ 2598 0 R /XYZ 81.145 78.635 null ] >>
endobj
-2653 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 426.115 null ] >>
+2597 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F59 338 0 R /F84 404 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
2654 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 415.156 null ] >>
+<< /Filter /FlateDecode /Length 1809 >>
+stream
+xÚÍZMo#7 ½çWø¬"‘¢>€ €³è9·¢×öÔÿ-5’fFz<²¢XxãÌ(o)’¢­þ>iþÿ·—¯—× Å“U1„Ó×_/æ¤ùŸ9PΞ¼3J;súúçôÇ›ÖZ#ò+ð+¾ÿùõû‹N` õz öTtÃÇPT°GBÃhZkë3ÊŠÔ F¤•Ñ 2
+ÇÙ¨¼$÷þƒ€øù¬ï|e‡l­E‰£cìP«àãi˜ eø{P'­ n‘ÎU¢í;gæk¿ø7ö0]Òûùª ²M«àý‡áˆà_A¯!èsõZà Êa¼ 1lpLŽiÅ–F9i§À9‰“ýÛ\Ò®‹’ÔUøùÞÖ|YÝ:lq´¿åèåÉÃþs‘jßkåhÙ¤µê‘F7– V¡¶oˆI‡”|YKøÈïmÚD‘šå}]C¬;¥ëaÔ
+EÜǘ-а’”E#9éÚhÎq9ÈŒ²$nƒ…¯GV‰ó™„1&-ÒÝ%ØATDVô •àé%Ø™ (’Èî`᧠{¬GÎYÚ+‡NôŽ1i‘V5ç¼—·KA&NÑ)çÅd[
+S·>ò&lÖÛÙ}Ýzo•wÒòƒ4z!t86ä|˜r§ù9åÅ¢ |æ;.U+Ì+§ìêKåëø‘êZΰ)»Z¨×+
+ÚQª dçÑDË~G =’7™ßT . oïªmBÕÿ¼fß [-hÞ0š;‰@ ¢Ýó:pÎF;,²F…€“£YIQp¤ó­ÖYOt뎨íkS×$ý| Çå‚·…­ cÖ¶Hô¸d"?†ÄX8X+È*k\déŽßí¢òßïÆKîÁLª£âçˆæ,FiëskÓ!e—ØY·⦱kA ‹—¼¶Ùü‡Ý‘€ƒ~®ŽÂ!âð&Z‚{·ˆAqª·ù£CZü‘SCç_Y1ÐÿLÑkçóA¥ƒW:ˆ=ÁÑÃmUºEºù¥
+¸2nÃiÜV¯fãÝöŒ±Úr¸à!c¼P+6—"|úë2ÃNœ“ô“Kbf[<·'•œ¦E¥’qÓ¼ñ£ï¥ù”¨l®Š:ÌÇä:›ÌI!‰Èr!®´Ï²Õ«MðÍëæ  ë;Tºä¿ðZ¶÷¼Ò$Yêo¼ÕÊ»$ÕŽLeUµÁ—••õveš
+^Qªb-±UòZmL¯ ³ K&•Ytôûž6\û¿&7mÓÁ¢秦ÁË=üá>¾–èza¹6/¬‰îÿÐ0ãI2æhOoœòä{¤{>þXì¹2çÄÍÀ`gXð}¨e‚SÐÎ
+ª‚GÏ"exÓ!5³‚jÛw¨JÏ>åËãÑksýeb½qÙÝ Dí°dvÊyè Ñ!-ÜRQOÛð G㬂vHQù~Ü#=ã`d•œðÇ“-Тå÷„õ÷Œ°Æ‚û¡$ôz¸Þ…ʆù\›Ì©º4¨SÑþȯ<zÇÚÁ¹yåÜÝM¿5IØ튧»SK K3Ü6»uxwQ´½-͉µÐ˜ä;µ'OOôçeÄU,ÿv³áæöQù=ƒ‘†›Ó¶×úvp}bË6mÛBsÝkÅ–Ú=5^C¡'ïbEó>ÇõÄPtçÔ”í»óŽ†‰õ¡ö;.s.¦‘~©ÅÙù6ÕYRpŠ„{Û$Sb<:)SèÞïI]·Pø^ÔÕ½Ù4rÜY«èç·ú’Ûç×Ë¿š¼
+endstream
+endobj
+2653 0 obj
+<< /Type /Page /Contents 2654 0 R /Resources 2652 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2711 0 R >>
endobj
2655 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 404.197 null ] >>
+<< /D [ 2653 0 R /XYZ 78.37 808.885 null ] >>
endobj
2656 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 393.238 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 768.829 null ] >>
endobj
2657 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 382.279 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 757.87 null ] >>
endobj
2658 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 371.32 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 746.912 null ] >>
endobj
2659 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 360.361 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 735.953 null ] >>
endobj
2660 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 349.402 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 724.994 null ] >>
endobj
2661 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 338.443 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 714.035 null ] >>
endobj
2662 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 327.484 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 703.076 null ] >>
endobj
2663 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 316.525 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 692.117 null ] >>
endobj
2664 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 305.567 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 681.158 null ] >>
endobj
2665 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 294.608 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 670.199 null ] >>
endobj
2666 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 283.649 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 659.24 null ] >>
endobj
2667 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 272.69 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 648.281 null ] >>
endobj
2668 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 261.731 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 637.322 null ] >>
endobj
2669 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 250.772 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 626.364 null ] >>
endobj
2670 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 239.813 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 615.405 null ] >>
endobj
2671 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 228.854 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 604.446 null ] >>
endobj
2672 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 217.895 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 593.487 null ] >>
endobj
2673 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 206.936 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 582.528 null ] >>
endobj
2674 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 195.978 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 571.569 null ] >>
endobj
2675 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 185.019 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 560.61 null ] >>
endobj
2676 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 174.06 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 549.651 null ] >>
endobj
2677 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 163.101 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 538.692 null ] >>
endobj
2678 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 152.142 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 527.733 null ] >>
endobj
2679 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 136.202 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 516.775 null ] >>
endobj
2680 0 obj
-<< /D [ 2619 0 R /XYZ 81.145 81.407 null ] >>
-endobj
-2618 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /D [ 2653 0 R /XYZ 81.145 505.816 null ] >>
endobj
-2683 0 obj
-<< /Filter /FlateDecode /Length 2994 >>
-stream
-xÚÝ[Én#9½û+ôÅ"#¸†Û²èãÀ·Á\gN}™ÿ?Lp_’™JÊeTcº¡’œIFÆÁG&gêòŸ §ÿxzû|úySî"™³áòùï'qáô¿¸X`Z^ŒŒkqùüëòÏgÎpŽ?úõå_Ÿ>qOŒHý¼Yy±Ìi¶¥#„fF™‘’T/?(O³þú ª‚>Ž>œÆÐÓä•žöF÷,ç@÷Ýÿ÷Gž×2˯k¤ Ê=QÆKÊlÞÎ9ÿ®t”ŽR7J¼£AÅ™à0Ó ºsÍ„‘RÃyÑà·hUµú’|®íûš“M÷"ÍnleÜËÁïnWÁ‘ØV^$³jtLHœÅž3ŠTŒ8)UÞ4©V¼ÓœŠµÈ/X&ˆ‘Yªsü¢bÊê %ý+¸†¨)wrÍÅ{JU›ßãØå×otï/¥¡Ÿ7€‹#}™¡Ñ§q ÍEû/i³6½Gâ>$-ZSA3¤!ù?4ø‚â9iµŒŒºÍù{•’Ú"it½¨^ó]i# qDk)zF”D¨™$`Èoe1âÅâsâ
-÷}:ÕZ…hŠù_ÜtTXœ›ž8·õŠ¬r£ýH™”IþœæUƒæ+I–=%ƒFjÖGá‚f“–³uå[ÑþaDe{‡ì)6ÎW+ø–۬͘íóÕâl®w°¨o¯…Ì\ŽfïùQG"Ä;Þòó_/²è|pËD57gÁ™yå=5™ƒ(ÇÀº’®åÜІƻøœÝ„˜m›àÒN¾5Cb±iWI×Ê¥Õo½+]ÕÉ Û<x=»<¨Wªv¼®gRÕTÒØÈ–'ÙÊsp¹kü‹×ÏÌ~Ñó&»±¥?¼&¹Ëø>Ú¼žÈA9í¥•¤6å˜ZkÜ–ç"ÂÞ–XI#Î¥úf5Wa ³€#WÙÉòÊ9§ŸPÙçšåe
-9}§¬Hͤ’ãs2—1¼|ñ`} ™Ý¶Ö¾‘Ño+ëƒÐþúàd}t­ €:|TS^—Ö
-#¥[€îúUÑuÓ«=¿‚¹y'yÅDάq#%·}ø5®dŽ×[¨&
-
-ƒL+1r³
-ç˜6v¤à¡¤K»·“†’Iƒ#¥Í2yG;Ð,“ýœ
-ä»Ý²?\é÷‰²ÎÊr_.¡‚q®Úã¸,è%6Wâ,À` ¸Ð~1EKÍ4Eä ·_€**á·?6¦ÕHµfÜÔ}-h·ã:Ň+£ÃJØ`äid1&wÎ×7
-s‰"—0¨Ö&å2I}ù¯OBùøld惵$õÆ›¸h†”¶ƒésË ˆ‘ŠÎXlåYJ?‰¡v?Á)çú.o)_Ôîì‰dî*’K½‘R#ÅŒ ú^0~›Œp ÿï2~Žç·Z œa>ÇÏK艈Vð´òÏf.R°z3×—•¡#,3|)·±XÖÑ{’’õe”¢þÙ>ÅèFõuÓxÊ€”agdÙWä÷jôeOô'ä–›S¹“óá÷Ü`ƪ­[ÞÝLJ鉚m°j¬)5³N«£ÓL'¯G
-»rv)Dm¦ãð‘výrÙ-¼ÖnÁwvrë}xnÆ[…×8*MðõÌ,ÿñÜ8¤09ô{BîE«Q¤æÀËY.’(uz_äI)¦·pɤÛÙå‰<ÈŸ„(í¤•b»RÈõ­ùÝìQOÕ^SY™ÄêÚžÚòI{ vKoAÿ}@Ó–)º4RÚóã÷œô@dîÚå½_ûƒÍ:o¥¦.if‡°¥{>¾—uÈ´53]/Ây#¥ý¬¼È!õ†ì”õ7WJ§à'A½­­Çì»óeâ/RPõuã³Vúgm­HG
-ýi»‡OÚj7º˜·ÁÍé !2!°£ÐÑë Ä9ùŒµÛG2"wa0rѯÛw[\°´B–ãìîԌ؜ÅpÞÂ4š'à±Æy¦Q°Œâ3wm±bõb£LK£¡znò| ;A¢„¥×Gäªk1£VJ©äs=›TNp…ólY¦ræÉæñÞ â­å³Blçäþ>΋Gt2·=ìÒE׎÷j$¿ÅõÀ–Ø„tråz0Ù¯Û2â(&‡âØ3`]™Üá()H®˜â¾ÞV¹ÙPx««ÐŒçF©*¼ö–´}µ%1­*’¯¾ˆ 0W‘Ns-gÜ¢Ü)fì87 Š—ᙬÞ`ô1& YûU k—b%Ĥ«õ4Þé²A¸r
-‘ #KÌGJc¬fÁ²jµíœöŒ]9p¹óJ -7}Í$[y¥…ª¶Û(<žö´Íhù± IZ¼‹‘æÁ‹‡^Ì5£j×C¤ 4)xðÇÝ“t ¾6xÌ—Q ¹^åË
-jEpãŠë@—È®>?…¦îŽí½{Wß»;/ÐLJ9Rõ?‹ Ÿ´d6Ó†ïä~cB‘Bïï“E–ÈTLÃT&»„,õ„vWªí³ÚkµW;©/½'-€Ö©ZLûõ5m Ô¯Ë¾„!i?5ÇYä,óØSzlxìsqL^×÷gàkŸ÷ÖŽ‚#3§NkZì)}#Fäh håŒåÅWûzB Bô:;¤“Þ}o†×»ä9±C%ÇÂÒoç¨$rOèd8³ZÏ8>‹ÿ$Ž{B÷ÁiPàõÿ º‘¿`FæPšz0j1j» ËÄϧÿ¥wÿ±
-endstream
+2681 0 obj
+<< /D [ 2653 0 R /XYZ 81.145 494.857 null ] >>
endobj
2682 0 obj
-<< /Type /Page /Contents 2683 0 R /Resources 2681 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2726 0 R >>
+<< /D [ 2653 0 R /XYZ 81.145 483.898 null ] >>
+endobj
+2683 0 obj
+<< /D [ 2653 0 R /XYZ 81.145 472.939 null ] >>
endobj
2684 0 obj
-<< /D [ 2682 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 461.98 null ] >>
endobj
2685 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 451.021 null ] >>
endobj
2686 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 440.062 null ] >>
endobj
2687 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 429.103 null ] >>
endobj
2688 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 418.144 null ] >>
endobj
2689 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 407.186 null ] >>
endobj
2690 0 obj
-<< /D [ 2682 0 R /XYZ 79.37 691.303 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 396.227 null ] >>
endobj
2691 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 661.722 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 385.268 null ] >>
endobj
2692 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 650.763 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 374.309 null ] >>
endobj
2693 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 639.804 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 363.35 null ] >>
endobj
2694 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 628.845 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 352.391 null ] >>
endobj
2695 0 obj
-<< /D [ 2682 0 R /XYZ 79.37 595.155 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 341.432 null ] >>
endobj
2696 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 541.663 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 330.473 null ] >>
endobj
2697 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 530.704 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 319.514 null ] >>
endobj
2698 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 519.745 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 308.555 null ] >>
endobj
2699 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 508.786 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 297.596 null ] >>
endobj
2700 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 497.827 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 286.638 null ] >>
endobj
2701 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 486.868 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 270.697 null ] >>
endobj
2702 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 475.909 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 215.903 null ] >>
endobj
2703 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 464.95 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 204.944 null ] >>
endobj
2704 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 453.992 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 193.985 null ] >>
endobj
2705 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 443.033 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 183.026 null ] >>
endobj
2706 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 432.074 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 172.067 null ] >>
endobj
2707 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 421.115 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 161.108 null ] >>
endobj
2708 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 410.156 null ] >>
+<< /D [ 2653 0 R /XYZ 79.37 124.441 null ] >>
endobj
2709 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 318.168 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 94.351 null ] >>
endobj
2710 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 307.209 null ] >>
+<< /D [ 2653 0 R /XYZ 81.145 83.392 null ] >>
endobj
-2711 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 296.25 null ] >>
+2652 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-2712 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 285.291 null ] >>
+2714 0 obj
+<< /Filter /FlateDecode /Length 3282 >>
+stream
+xÚÝ\ÉŽ#¹½÷WèšCFp
+T•ª øhôÍðÕ>ùâÿ?8¸¯™Jª»1†g –”"ƒ±2##‹3uû×Ó¿ùöþãÛ_ÊÝ$sV Ü~üó›¸qú_Ü,0-oF Ƶ¸ýø÷íï/œ+à\~rn爯ÿøñ×oÜ#R|Yy³Ìi¶¥#@0¹ ôöú]òŸîDóË¿ç+ÀËoª\{£o‚F¾ÇzNh¦&N$ý&>âgü*s]ùô6Ók>Aþ$˺Z´Ü!§õ%]å-—JçOâs¦U]3nþ•h8@µÛë¥g‚ÃÊRò󚥤c†Û‘ÒÊH–Pž_3kÛËÑéÁ¯ýÇÀÍÑš@¬6kÇÐÜŒ
+~¦‘‘Š÷Aÿ]§×E=€SL 7R.Ò©³.
+{[b%¸¶á1ÎÂUXÃ,àÈUv² f¨[ŽßPÙ—ºÓËrúÁÍEj&•×É\Æðò©@ØÊöÒ­Ù)ÿôïÆ]Êjœaì@'ÞáëÛ’Ù\»×æÑrW%˜UKy\ËÒhËD %,™²îrWÑeÖ÷]~%gÖÁŠ_ý~_$
+Æ”P4:œsr¿ß|>ª ªÌ~¼ÏÐý«Ÿ×Tó|?óZž_ó÷†¯Êó¦Žb
+q©ã·k:VŽ è%7ê'ðø„Nç¹;zͳN· ›ú¤2J¸úE·§ßR¯_½Ö­þêâñ`T `ž‘Ž[J¡ÔR:»'Ý@©“Îg ?'ÒOH§hû¦™ËØP[Ò”zÛÙŸ¶{F:«wf)Ü“n äžÁ9¼TÑZ^+^®·p_Çîƒ(ÞÖŠQTmÙ¥GãÖ=g „z}Ï4îÏ bE¬XJ|»É~ÐúŸa…m©“…Óï—S¸"Ü@é"„%PÎ +é®&tYºÒï a¹J®†ò¦NP0ä¸ÒÉÕ¤Qhf”)9­Cb ¦¸fV—9F¼ZÌUœ„è%3ˆâK\Fä±¹¬6÷Rõ¥ñ*Y‚ £}äf Î1mìHÁCI#žVêÀƒú %“GJS™| hÊd?§$ù×®ìW2 kͬ³RîË-d0ÎUG—‚^bq%Î –€ ½à÷W´‚q©G½ý\Q `|2HÂÊ{w–΃›eK/x â¨øpetX ^žFc`rç|ý
+ô8yçŽÀ¤O<z
+OÜ)ãgBÙ‘Òtï‹I#®ŽÃ°»õ”ý§½eÚ—žwî:&¼ç –úüÌÐY¦Å$ÊÉ>ärì´!19õáaÌJœÔ¿ éJ¤À’Ë”ù"Þ•0ÝÐ1¨{à!Ï‚¸,ãv™ß^”ˆ;Rú= ®äí —üÚ­‚z tâ^¬¼Ô¢Mã>‚ ×깫­õ×¾Ya_³”À ­–®¬ö4ÛSZAZ¤Ã8HÇ¢æÐñè÷L»þè¸Þkžà: 9ã>mžñVá5’Jî{¿2Ë¿<÷N)è…Å˽g5tŠ×K«É­V™R§÷Mž¬d í2F/‚^†vE…#%¹jyúŒþ0q×ô1Ö|nŽ¦Õg)mÊu¬î¦¥ògCgTcƒu+]…Í´eŠ.”Žüøã`Oz"2íòÑWÃÊÆv¥p‚šò¤•ÂIîõøÞÖµ6ŸQé·mo t¼'oò§e¦bÅàU.aN¥K˜‚b—Ýeâu— )˜$í—ÚÉžµ¡½Êú^»§ûì
+ÝkY¤ÒádóxïqŒÒrgPÛ99±óbCN†ÜæÖ–.®<W“œj×ÃXF`ÌÉkë`²±/Ø2¾(­Fqìh.ŽLÞp¶H®˜âßËýà ·ýFŒ…÷Z~fô6JUÁ´÷¤í{¼¥$¦UÅíâ•ü‹ rÔRyß3 xá”n;L "äê;£ÕŒ>‡$0ëã¾'ê±bíR „xtõév‚påøF–x” XÝÿJ­jÛ9m;]é­\{ˆï­ÔvTô†ƒsÐÝv˜ÛÁ†C
+zJoÖ×6ú”«'ç XÃQŵÓéû±ÿ@Ív6/P³¹¹Ù«vóiµžÐQ"›Î×6yÅôü'*<“W»3“=¥URøëSZ!™áK_@3Ú’GJ»¶aÛ˜ÿèO]ä[ZòÛzM”óöõ¹ÆÌx‹¨sTS·ÑX ª˜+,´³iCŽÌH\Ùð*º‘mØSjJ ›·è_Пï€+—ìÚ-v{B¿±ð³‚YPË Q[÷„zŽÀ'ûjïÏ=Fß–ùFnj— ¶¿ý|Å×|vÐ%yþWÅ/ׇ_3ÞøS2œY­—Ú–[Gé¡çJM /ÓJß$g®Þœµ,ÛûçoÿŽ"à½
+endstream
endobj
2713 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 274.332 null ] >>
-endobj
-2714 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 263.373 null ] >>
+<< /Type /Page /Contents 2714 0 R /Resources 2712 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2711 0 R >>
endobj
2715 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 252.414 null ] >>
+<< /D [ 2713 0 R /XYZ 78.37 808.885 null ] >>
endobj
2716 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 241.455 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 768.829 null ] >>
endobj
2717 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 230.496 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 757.87 null ] >>
endobj
2718 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 155.347 null ] >>
+<< /D [ 2713 0 R /XYZ 79.37 724.086 null ] >>
endobj
2719 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 144.388 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 670.578 null ] >>
endobj
2720 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 133.429 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 659.619 null ] >>
endobj
2721 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 122.47 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 648.66 null ] >>
endobj
2722 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 111.511 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 637.701 null ] >>
endobj
2723 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 100.552 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 626.743 null ] >>
endobj
2724 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 89.593 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 615.784 null ] >>
endobj
2725 0 obj
-<< /D [ 2682 0 R /XYZ 81.145 78.635 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 604.825 null ] >>
endobj
-2681 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R /F81 366 0 R /F75 330 0 R >> /ProcSet [ /PDF /Text ] >>
+2726 0 obj
+<< /D [ 2713 0 R /XYZ 81.145 593.866 null ] >>
endobj
-2730 0 obj
-<< /Filter /FlateDecode /Length 2872 >>
-stream
-xÚÝ[ÉŽ$·½÷WäˆCw`Ð@Ww—
-òù§ô`¾#ø1¤šVI”§ÌK @Œ•"}ÌûL9xïõ¡
-²¢‘e" Ï
-Ç* /PB â©Ü¢·'ô<YrÄÐÉcT]ºªL5ß^vÒ¶o“§Øø^+·äçåù·¤¢+o JZ÷­jHñŒ.Ç»`~ônÔ“›™êAèj̱”2¯“¾]š‘Î-}’ÍÐ 3bOWB„-Nž¨Ü“„]#áz7š2O Ç«ð7h(H¥Ò¨}´1ð,ò"z$…ÑÄTT†l<¥ ¹Ï.K‚ãL‡,„ÿþŒ©ý¦˜wBBkZ¨ÅH\¡ÚwLâ-ÑÊùìËÝ©Í¡a麄À-“
-FJ€<hˆŠ×ôM×oïW}੼àß{xŸ(…4¹£e킈r7ÇP %V
-†¾‰Bßúæî¢lÆx¥¦²}Y“mO©ÊV¿Œ\é·U”\0pz†Rú5”=¥¥®Z¨(:‘¨A=‡í5ôè2L‚™¢w×ЃaÂÂHi†^´!\Ùr¯XG´LQCŽÌÖ|ZÙléÙ›­\yo!|V˦¤–-÷µæÑL™`ö1­×ŒI¢¾CÁ:<Ñú£n­·‰tuâ»±S?Ñk:ì)Uɧ =õðE¼Æ1ÅݯZÃÛSjðþp?Ñ–)å§~"×0÷”zÌmá
-|â=ÇîÛYtímºÖ—5}æç²5Ûâ !'ÊÎ&áž>TžE)RéQK zÿNø¨Ùó`–å­ S^Ìä­Þ¯É[,;íŽÒ$GÙi8-?S e¤`ZUOË®%R*óä$2ä†4•‚9âÈAWt…Ê£ëx•¿¡Î¢‰1¹‚{ézO{F‰÷02²|Ó
-NL3Îq3®¨R•kü©¨‘;faGZ ­šª¯¦ Ç‚Û¯$4þ°“–ÈÖ×¥ò yÔØ4º5¬[•âÎ)K*ª
-NE[¯nB“zŠØÕðI­o„gº=¥ rf2ª¦ü¥Ê¼ë
-:ÓÌÕ÷Yx(•{‘ý„Ò™õ€ÐLŽèQãZ|í‹Ý¶S’štn9OzƒÒ5½QP¦7nõÉ}·S‚Ö¡*…FïÐjâPÎßrÌLX¤>å|Iƒ9Dî—4¥sÌ€+ ¦Õ I¹°S.¨¦#·ÁööÌm„äÌW¡P$íù ykÍcqÙ4½±ÕŒÉ´R\ׂæIÈ~DW ©¹µÔð“kg§"'ykºÉæ]¢¯†ÊH£¸8W”håÊÕnxr7<Õ£¾Nh¡‹€šòN;d ³Å‰šó{½¸æ~+Ó£ö˜»1»*ÝÄ°L‰£ßcó;RÐ-ê‰a™–f wÔâøî­òÁ”Ò\¨Œ òU8‰dg(bÄ9–kfΑÓÅS~®ÁS× ecßcY-ý˜Òÿ`’Õå  ÄHª¸8Sø1ÛŸ¡ô¢ÿü=Ô`vž
-•dSù ˆ!BÔJî ¡jǬp;uÖ¨÷åpb–5­«FõÒø#¥õMÈÃe_q­Õ®Zsr?·x©½ÒƒÚÕ[æÁ„R¸«1 –à¡u 6IìШ¸+ÜiºûÒ´¦Pƒim¤ºN·4h»èļŸ©èk³%-»)Ìú\©1í¥؇¨ÊR+¹Æ=âPP Óï|Õ¦\XJ¾ÐÕ.^¸»9JCËu1MÙëSvpFzÿÊŒÜ;Þ ÉÜSéTz‘£h0²[&©¥ÛÐ"Å›<‡}]t…8¹„™ƒä6좃 „Ž$ø|ËS1ôEàÎ2l€fÀ¯N{CÍdýHÉÀn>±³øê9Íl¸v® \X¬"Å4>]«‚`jB©øä~ªúíOF3¡ÍŒ§«SXâi äÛùÌwÍ”VLx;ÅèÖ0”üdN·ˆ 35H7µ ½†m ä[ÝRÎ¥f¾Úţ窧ˆµÊŸÖOùSkü ”>;Á^Ä«Ï#æåñc†ßªè¡©o¥ ]D)8“FÌ`^ÚÌRÅù^÷ûd¶’òý¾×BíÙ>QÉIï™â;±K¹’#~FJunkk9‹éxwh)9Ã}1ÁÜ¥+û-‹X­eÊ©Ö«9•°”ü.ù®—Ÿòµ–eGJ;_('j–íDk¦÷;GãbÖ)Õêœ×NÇ
-èÈÇr| #7³ß9Šx×2èHé"ÞpĤœŒL¿W;¯šÕòQ
-:vÓìVžiyš3vVsøÙ]x¬ññŸÚñZe0Rê*+jqL>Úòcâ „‰ÁúZÒéo!¶jVŠ©E¯%ö‘Rµ SÛÄh-êàªJ|7çÌÚif\Ìô#¥*Û{íÙÊÈîñ@bpžán9ÔvþFQ½|vë˜Ój†}1Ë”¦ØCf¤ÑEÚTYÅk,s^Ïð.fú‘RuÇã¿~¤m˜—f*ßµŠc¤´ã°«üÞŒJ3oí ób2Rê:›¨¹¬ò¹~xùWµ ©~*ßµŠi¤TŠv­Ê7Ä Ÿì$ãsS^+:BõkÖÝNÀ|¥Lp1…¹V`Œ”
-ΡÞ||FExÇ„¶§?‹88´«ò¡þæ Ýi÷aëÞö0ÄÁÆž ÇAüˆj2©=lóttyäM/êK8ŀϽA® žBý^@" .ÓU³9~º~¿ç2UïŽÛ=0mY­ñx™5­dŒn¼ÆñöÄc¾;œiLWi:T·Ã5ü¢£®A ô4ëýƒ ¼k槛ZRáV&³ûMÝ7ÕÓÕnS=„q÷ž8+‡Ó›CüéNa¾¶ó=’t:¥º[²9sÓX¨Â ÷ž7UƒÓ‘£e½cÄVüèç0èdó{p½W`ÙÑ9Ü_7‚ ¥†ÕDùýÔA(0ž)0JhvÇØÕ?ÿØÒ—¸ -̆u‹•á uÿûeƒþ\bÇtê~}°³;àË¿c=ŸÖ:{&Š>=¡1ú„C’ËÑg‘à¨Ëýv¾Þ6åCï¥Ðd4eT
-ðïOÿ vrûýÛÓ¯¿áåâçD.½Ûþü¶ «˜áµoÿxú[úA¡[,uÆá5F+°ƒó AaÈ eoÑÈ;}HfÑè°óãMÑœ
-MŸ%ý.~¡³ÊØY°5nvîÆN‹M¿|Ò¥Ž¸ L-v‹„bÁÅ‚Š¿k%vÚÃy´:Üê)¨$ŠNBå¤Ó[×#±þ¥]”Ï ìpÔ&ôƒéA:*•žNòF{u•¬ÿW+³ö9×æ‡ÄÙ}ìZ6ÜÃ_z¦•hOÂÆ~«%lÎ ’çô%µjþh5nõkµ;SÚp;µ:,ê8V?=¬ÿS²pêG›Ma!ië) U†þITH
-endstream
+2727 0 obj
+<< /D [ 2713 0 R /XYZ 81.145 582.907 null ] >>
endobj
-2729 0 obj
-<< /Type /Page /Contents 2730 0 R /Resources 2728 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2726 0 R /Annots 2774 0 R >>
+2728 0 obj
+<< /D [ 2713 0 R /XYZ 81.145 571.948 null ] >>
endobj
-2774 0 obj
-[ 2727 0 R ]
+2729 0 obj
+<< /D [ 2713 0 R /XYZ 81.145 560.989 null ] >>
endobj
-2727 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 236.441 142.077 246.868 154.597 ]/A << /S /GoTo /D (Hfootnote.40) >> >>
+2730 0 obj
+<< /D [ 2713 0 R /XYZ 81.145 550.03 null ] >>
endobj
2731 0 obj
-<< /D [ 2729 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 539.071 null ] >>
endobj
2732 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 730.971 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 446.81 null ] >>
endobj
2733 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 720.012 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 435.852 null ] >>
endobj
2734 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 709.053 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 424.893 null ] >>
endobj
2735 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 698.095 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 413.934 null ] >>
endobj
2736 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 687.136 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 402.975 null ] >>
endobj
2737 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 676.177 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 392.016 null ] >>
endobj
2738 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 665.218 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 381.057 null ] >>
endobj
2739 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 654.259 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 370.098 null ] >>
endobj
2740 0 obj
-<< /D [ 2729 0 R /XYZ 79.37 578.737 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 359.139 null ] >>
endobj
2741 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 560.603 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 283.877 null ] >>
endobj
2742 0 obj
-<< /D [ 2729 0 R /XYZ 79.37 523.935 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 272.919 null ] >>
endobj
2743 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 505.801 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 261.96 null ] >>
endobj
2744 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 494.842 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 251.001 null ] >>
endobj
2745 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 483.883 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 240.042 null ] >>
endobj
2746 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 472.924 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 229.083 null ] >>
endobj
2747 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 461.965 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 218.124 null ] >>
endobj
2748 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 451.006 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 207.165 null ] >>
endobj
2749 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 440.047 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 155.347 null ] >>
endobj
2750 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 429.088 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 144.388 null ] >>
endobj
2751 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 418.129 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 133.429 null ] >>
endobj
2752 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 407.171 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 122.47 null ] >>
endobj
2753 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 396.212 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 111.511 null ] >>
endobj
2754 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 385.253 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 100.552 null ] >>
endobj
2755 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 374.294 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 89.593 null ] >>
endobj
2756 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 363.335 null ] >>
+<< /D [ 2713 0 R /XYZ 81.145 78.635 null ] >>
endobj
-2757 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 352.376 null ] >>
+2712 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R /F81 358 0 R /F75 330 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-2758 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 341.417 null ] >>
+2760 0 obj
+<< /Filter /FlateDecode /Length 2474 >>
+stream
+xÚÝ[¹Ž$7õû+ò†"#xºú oWí ²$HÎŽ±rôûŠà‘<’U¬‘5S•Çã 2n²åöû&·ï.ß½+³,X½}üö è†ÜÔæ‚@·9«„´jûøºýô(¥y—AJ}‘R½Hi%}·O_ ݵî¾ç;ô^ùŽ£;šßyŸC(WŒNXŒídzÞ(ºöJŸý)¸ðÕ§/àùG¦Bƒüüñ‰áôL @-B€QxN° ü‰B½&jÚe|&„y¯f# ”4‚G`ÔDŸQ3Â|ªI:áà€ÀxbŒÎ"3™4ëûŒ`s ]ž´8‘7g½Ú˜ó³r“¿&þ4[´—§/ZËnÁwvY
+£°®ñ'!TõŒ*Ÿªs?Aº¥= ŒÀ‘=­¸QÕÄX‡t^ ¼Ð¦¬¹ÓÅxÒq†¡¾±³Lo\ê“Œ]Ö¹Žs[OµŽµf`kŠ„8Ë ;1+íåöÖ
+…Ç!‰­ñ35 sWv#,‹ ‡ÅÍj
+ÂÓM“+4}ìöçKåÇ¿çe‡BBr(ïbð2§_WªñÂ)XÎêõ¾{¸®–6Xa÷–ú¹±ÇÖ³7)Ž}ÆY
+Ã<é_fjÂF™”Wíx°ôê°ódü7ÂäyÇAb¯7O¼-ú'8À@ÉÝUÀZdbn€*éd'ÆÀ.2'ç×s½f¡:SV‡Œ¦Ïã–'t—Œ˜Óó\.R(<~Û‡¡Ä¥\ÃýÌÙ¯ÙÁ-ßÔ[ùæÂñ.È–¸á$ÇÑ­„zO–|ckR°çíé*»Lcás¹Ú9 °·ôf«i91æßxiŸbl¶Æò~žð[Ž‚'M£Dh³ÆË’€ßvUywõËN†É°ÇI·(·]4pÂh73ý¶d"=Ðua«oeÚU}‘¸²Âx î£Fž!³&F$ 5›€KkŽUç«íTM×2^_”‚­…0“¢`}&†Mv«<#Oµá«–{^&´°n&’½,‰4
+Ø/×^×Æ_µ9Ó>çÛ
+1Iö>¶[1& Þ+;Sû©óKíbåe.`Ñèöô¯Ñãi?£XÒr¿©u^RrZÿP¹ \Œ±9†àªqÖ.&9‡¿
+endstream
endobj
2759 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 330.458 null ] >>
+<< /Type /Page /Contents 2760 0 R /Resources 2758 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2711 0 R /Annots 2806 0 R >>
endobj
-2760 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 319.499 null ] >>
+2806 0 obj
+[ 2757 0 R ]
+endobj
+2757 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 236.441 271.591 246.868 284.111 ]/A << /S /GoTo /D (Hfootnote.40) >> >>
endobj
2761 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 308.54 null ] >>
+<< /D [ 2759 0 R /XYZ 78.37 808.885 null ] >>
endobj
2762 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 297.582 null ] >>
+<< /D [ 2759 0 R /XYZ 79.37 708.251 null ] >>
endobj
2763 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 286.623 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 690.117 null ] >>
endobj
2764 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 275.664 null ] >>
+<< /D [ 2759 0 R /XYZ 79.37 653.449 null ] >>
endobj
2765 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 264.705 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 635.315 null ] >>
endobj
2766 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 253.746 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 624.356 null ] >>
endobj
2767 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 242.787 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 613.397 null ] >>
endobj
2768 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 231.828 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 602.438 null ] >>
endobj
2769 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 220.869 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 591.479 null ] >>
endobj
2770 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 191.978 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 580.521 null ] >>
endobj
2771 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 139.176 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 569.562 null ] >>
endobj
2772 0 obj
-<< /D [ 2729 0 R /XYZ 81.145 128.217 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 558.603 null ] >>
endobj
2773 0 obj
-<< /D [ 2729 0 R /XYZ 93.716 98.47 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 547.644 null ] >>
endobj
-2728 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F65 327 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F81 366 0 R /F83 403 0 R /F75 330 0 R /F22 357 0 R /F16 328 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
+2774 0 obj
+<< /D [ 2759 0 R /XYZ 81.145 536.685 null ] >>
endobj
-2777 0 obj
-<< /Filter /FlateDecode /Length 2173 >>
-stream
-xÚå[Én#7½û+ô¡¹7À0 YR€œ} rMNùÿkXÜšdWKÍ{0@0ð¨Ýj¾®WÅZX¤9Ó§N<üÿûËåóåõ®ý ˜wBÉÓçß/âÄÃ?qr’8Y#7âôùïéÏ7εänœ×ï}þñÂ,@½ÞœóÆ(×âÅ™³~…¤ßÓR‡+05p.>8—Ε,߈[¹²¾\I^®ô5üÆŽ×õ®Y¾HÛÂ\s&¸¤˜›Ëóia %²MÌá’®‘M¹¯Â=À÷¦J¤OËÓ½È:ß+cñÚxÔè,Wå™
-ÚY˜x˼t#ŠÞR…s5[[ûÖ™¡ Î‘s½ÒKÌì*–0Zê®bñÝ÷=”þÞˆI#’Y0“ÊÔÎ1© ¥ÌµNVæ
-E²8ÍÑüþ’÷c¢D% –Z3ïºÔ— £ÖÏÃdÑá–ê
-³® áL©ø¾bRäܨEO”˜ˆb§;­Ø¦‰¦ñN,²DŒæš4•À£v'}‚¹íëç)_ïÎcsvî­ï‹€jmëóM™ª7Æ)¬Û¾OзÂ02Š%ñ$²„Æ–(G-S§‹L­ ¤vG™r粦˜²z`Êó^/Z›4aœý
-+ŒýU‘îú5Sn>JÅÀzÒnÊ=ж! +h\ Bm#å˜z¬oTô“,yÈ<cä§Ýƒ<F`úRÙ71OÇh]ãòfî[·¹¯„÷*N4ZÎò}I5Ì×2Av4ÜÒõ(eLŸ(R2©iãÚ¯lÙ%çáïªKDý1«æô”kÝòMQZyCo€E*¯Og)«^Mtl`w {Ô
-
-»é[œ¸ÿÛ”3OêDh&WŒ?{‹FJ{m igåà‚)!)Aæ¶} ;•|ÙÊÇ©6.ʶpYVÄYrëHÉôò"Xš) á½õ]Öüˆ¤Ÿ¶5t^h™ÔhקT+Cç£h¦9XƒžJcóq· ì@Öo\Ö‰­c_vÄOâBÚkR·ç©¥Û€Ô!™è·S³ëKZFGt=©Iã(2>ì­#‹&{¤&œŸ» ø±‘¾œ™¶ ÖçL"37ǬG:6GöìÉ|_sdzcL‚aZ8ÒÃôœöz¤ï´¸ÒLkOÊ ].?/Ñ3ª÷ÕÁMGÇÓŒPáCP4öÖ<%ÍôHÿ—
-endstream
+2775 0 obj
+<< /D [ 2759 0 R /XYZ 81.145 525.726 null ] >>
endobj
2776 0 obj
-<< /Type /Page /Contents 2777 0 R /Resources 2775 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2726 0 R >>
+<< /D [ 2759 0 R /XYZ 81.145 514.767 null ] >>
+endobj
+2777 0 obj
+<< /D [ 2759 0 R /XYZ 81.145 503.808 null ] >>
endobj
2778 0 obj
-<< /D [ 2776 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 492.849 null ] >>
endobj
2779 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 481.89 null ] >>
endobj
2780 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 470.931 null ] >>
endobj
2781 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 459.973 null ] >>
endobj
2782 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 449.014 null ] >>
endobj
2783 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 438.055 null ] >>
endobj
2784 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 427.096 null ] >>
endobj
2785 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 416.137 null ] >>
endobj
2786 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 405.178 null ] >>
endobj
2787 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 394.219 null ] >>
endobj
2788 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 670.199 null ] >>
-endobj
-269 0 obj
-<< /D [ 2776 0 R /XYZ 79.37 632.787 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 383.26 null ] >>
endobj
2789 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 611.945 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 372.301 null ] >>
endobj
2790 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 596.005 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 361.342 null ] >>
endobj
2791 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 556.154 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 350.384 null ] >>
endobj
2792 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 542.207 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 321.492 null ] >>
endobj
2793 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 531.248 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 268.69 null ] >>
endobj
2794 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 503.352 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 257.731 null ] >>
endobj
2795 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 492.393 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 246.772 null ] >>
endobj
2796 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 454.535 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 235.813 null ] >>
endobj
2797 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 443.577 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 224.854 null ] >>
endobj
2798 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 432.618 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 213.895 null ] >>
endobj
2799 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 421.659 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 202.936 null ] >>
endobj
2800 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 410.7 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 191.978 null ] >>
endobj
2801 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 399.741 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 181.019 null ] >>
endobj
2802 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 388.782 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 170.06 null ] >>
endobj
2803 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 377.823 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 159.101 null ] >>
endobj
2804 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 366.864 null ] >>
+<< /D [ 2759 0 R /XYZ 81.145 148.142 null ] >>
endobj
2805 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 355.905 null ] >>
+<< /D [ 2759 0 R /XYZ 93.716 103.452 null ] >>
endobj
-2806 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 344.946 null ] >>
+2758 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F81 358 0 R /F83 403 0 R /F75 330 0 R /F22 357 0 R /F59 338 0 R /F84 404 0 R /F16 328 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-2807 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 333.988 null ] >>
+2809 0 obj
+<< /Filter /FlateDecode /Length 2224 >>
+stream
+xÚå[Énä8½û+òŠEFp
+2™ ôÙ·Æ\gNóÿ×æ.’
+©DÙnèCZ²D>ÆÆXHŠ_þwá—?^nï/?Ÿ
+n©fx\ÀW°þj
+•FRT
+L7ÒYÆPÒó©\(D“¯‘Ê]y€¶ ¥]äM7 –I™ éI+sâ-ÜéPåU/EÀ’¢ÅˆŽàÚ:‚ VÿÖˆ_]<ur4‚À$ŒB ìcó¬æñ]­BEJd1eÊ£«Œ8^Yo2ÚYfÁÕ™"¸ީ!ÆñŠZÏèé©IñŒìô¤%»À4>5>‘‘ì T§Ž-àQºs3^[ì¡&¼‚™ ßãì8Ïs6»ö Ïvþ jL;ï¸ïã©0vÃÿ}ËŽÔƒn¸”ÍôY<÷QùN<Ê]q·ÇiÐ+)Mú0=£ÉhG•×£sh­>©õr߀²ŒããŒJÝýsLn:†j ^¶’TÄuJ=ж"dÐÊ!Øâ‚’ùˆz¬/ô~¤ÖR3†ŠÔÙC‘ÚîDêÔ#/Ìs3Dêè««WÞŒ|Kç6òç^ɉJËÑ
+•¯B,5£p*+€vfÔÙ¨t&Ö”¸q_ǃ_Éw¤ªí”ª{ U‹sªÞtž‡ðhú“;&´®rxkýQµÊÞ))a&«’_†‹¼PsÊã)7¦ªé Ï>¤ñ;1@Õk­nðÞ¸ÂØlMXy’_öñåmJ
+¹cV½ûÙòÞǾ…Üšâoô,Ñ%.O²g¤¨ôŒB9‘eçº.G”7û¥ÜNËZ«QFf˃Û%J>UË‘[cigê e5E® h53 í ÑÌY_H×ÙPkêøhk¬åÿÂn«·:Ù'™7Š£spyˆyÁ¯¿a…T—Ž@·žEWóÜgéÕ’!’©*â1z‘û²ÏH(èØ(<_eÉFÓåšî‚n´Š)˜M²¬ÐÏE±|p¹P(ïQ}}4"u]©r§ôî$0)ª·×!ä»ò›ã®GÖ&í‡uçÎp‡‚Ie(î.VTîz¤;™5°¿˜€cŸòëû6ØÕ±H¾±Œ)—kÌî¿I®hÙ.4LÊ8“ÎRò=¸„PåÛ# sãqN¶[)éïåz~L¦yìIyúÜK¡#åy“gÔð®&¬KgŸYö
+lš‡E2añœ’Îoä4+oL‘Fv°˜+1§Bý]CŽ´†é%9ë8¶Sf0 }‹#fZiäjŽ»é[„©3Iîäw=Ò×LáêúSSyR&J2#iϳF¡™ñáw@3K‰äÌ82!˜Ûû€v¶+yÞІdlcñPö†KaÚ–jy)FN³¸rž!‹=šßÑ÷H‹n®k¨\jé´Ð¨ÔZF0C™+ÍRa.+›ûË]:È)Ë7v"]#Ê­]ΦLZò%#<.[acX!d{4»ÌÅÛ€´p5³àNYק¬‘õ¤$y˜U” ¦‘EPãίS|Û ŸÍ:íi$c×)ƤsrdKæëG¦÷ÅÐjæA(éMüŠôz¤¯Ô¸QŒK$i¶Ý2\n¯%ãV‘2µú5
+g=µðîk’[à ä*)H×cÜ‚fÂÀ
+IÜšñ,•46gàˆ$¨JÉåÔ‹·}¥I'îº1^“ÖbeõüKÙª 'K©ÿVqº]•´£r„º2CÏ4F¸c@*äh–VS4M8˼S„Lf9ÒÎ]°~D$ÍW"œ¯È¥@ªýÜÆû
+yÈÁxèÆ8ê4Ôi ËÇÃ1±]°ÁÏÝ’8v <”¾4b=E; _a,•Zjúluï›
+ä¾®âj%’ìËÁe—%Ëú%S"mOܨÓèFô¸Ã’«› 2í@ ‹Ç2¡xnÎ0Å~û¢­­ÊY¦¨Žáçú<‘@ÍV×väÛòüS=®Ú~1öÜ=÷ô­¾– ˜3†šÏs ñ
+endstream
endobj
2808 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 323.029 null ] >>
-endobj
-2809 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 309.081 null ] >>
+<< /Type /Page /Contents 2809 0 R /Resources 2807 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2711 0 R >>
endobj
2810 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 298.122 null ] >>
+<< /D [ 2808 0 R /XYZ 78.37 808.885 null ] >>
+endobj
+269 0 obj
+<< /D [ 2808 0 R /XYZ 79.37 771.024 null ] >>
endobj
2811 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 287.163 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 751.43 null ] >>
endobj
2812 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 276.204 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 735.489 null ] >>
endobj
2813 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 265.245 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 695.639 null ] >>
endobj
2814 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 254.286 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 681.691 null ] >>
endobj
2815 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 243.327 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 670.732 null ] >>
endobj
2816 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 232.369 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 642.837 null ] >>
endobj
2817 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 221.41 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 631.878 null ] >>
endobj
2818 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 210.451 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 594.02 null ] >>
endobj
2819 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 199.492 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 583.061 null ] >>
endobj
2820 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 188.533 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 572.102 null ] >>
endobj
2821 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 177.574 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 561.143 null ] >>
endobj
2822 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 166.615 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 550.184 null ] >>
endobj
2823 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 155.656 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 539.225 null ] >>
endobj
2824 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 144.697 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 528.266 null ] >>
endobj
2825 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 133.738 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 517.308 null ] >>
endobj
2826 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 122.78 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 506.349 null ] >>
endobj
2827 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 111.821 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 495.39 null ] >>
endobj
2828 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 100.862 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 484.431 null ] >>
endobj
2829 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 89.903 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 473.472 null ] >>
endobj
2830 0 obj
-<< /D [ 2776 0 R /XYZ 81.145 78.944 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 462.513 null ] >>
endobj
-2775 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-2833 0 obj
-<< /Filter /FlateDecode /Length 2293 >>
-stream
-xÚÝ[Ë®ã(ÞŸ§È 4 U\¥Ö‘’v2Ò¬Ïn4ÛùWÿûo0˜KÊØ$=ÒhÔrÇ'†Ïu¯¢ œ©Ëÿ.ÜÿÿÛÇíëãûC¹‹dÎ
-„Ë×_âÂý?q±À´¼-×âòõÿË?8×7Îã\¿¿~þùõû`êûÃÊ‹eNk´5Žšez$¥×Ù1”(Ίtç(ᆡ„ ø,%è˜HRbç(i‘Ôõó›îO— ŸïûC¨‹ó8à__áÇÐKVpj“¬üéç‰O°þÞxš`ùü†â_Ÿ`ü'‚ÿƸÀû#üŹðs¤õßZ‘fÉ aÏ>·üGþ+ÍŽãäÞ´> á3Ì ß…gò\QÉÏo‘Ì8! YVð2Y©•Hô‚†ŸI FRA^µêI$&½>‘ l`wE „äDÚHܨÓèzt¥¢WÕá]‘ùvîi¾&ßÖ·®
-Á‰ž êÛª®"š±h·QåÔ¡—1p+'­¡hg8éF“ÞÁ=b¯âøY’”ìj,z{f¢ÙŸé…²RrËoé¢L–Hkúæ E2â%É€KQf`_ÙIÖÖ{£ãÔ)v†9°=P *p$luo¸í®îº¯éuÊY¦Œö*·$Sr*HuHJÍR¢“tÜÆs„€fÂ@$Õ,ËÝ}•gö6„äëפ‰Î\Ô}ÓÈ&é¬-%ýØûª‹&cPKúÁS¢Ùñ‚Ù´¦•d’N°ò~N<¨˜==šš´ä‘ÒÊ•™zN¾ëç•-REå¦E)¦$î6Í]ëÔ“²Ï6E~AÏíd¤¢ŒF=5J7£¦í©çb#|*˜sŸI¹YJ@x JŠ}›£¤E:©ïIj}ŽÖ Hj¯sÛ"ýR¿RÎWZSTâœ_uH…Ê™8‰ºH<g|*FþÃ1QYË 7¤Tæ
-ìižc˜‘–´"5GI‹DÅ=Òž²ìÿ]ú|ºª™+J#³\2–3åW´_~…¢<¤÷•­RvµÉaºäR
-˜•d’<[édci‘öT>æ£Sõ$/R0kÉ´s¶,IÁ¾CRX9†¥ÜI£¡P åÿ²ÿ<Ì=š®ÝùË?¾_Ì<‡ŸÏÕzí=éjžOj¹÷Žç´}=_ºeM¶H>­×k—?¾^{Ï5®×H~áÚÕëO¹>>Ï=‡ƒç‘÷—¿ýEie²¬ë
-}ZôœŠÇ*‘@uä̬֙½,Xˆ'‹œNšÜ1ÿŠ·T(¶ã¥³ŒKCŽ¿Î$€èÕà_/êžÅË AZøµc“-Ëéå„`{ÞÞJÒxGòg§Œ¸Cj“Dé åÏ´æ›`g°²ÝaéTUÆyëVº»ìcÖ-¥V^Ö¤—)Ê+•d €?U–u@û^)SŸ×èµaü+<P"…¤…ΕdÒn¾ËÃ{žæ×îàÈ$>YŽuHÏž¦¡t‘c÷Ľî¬gî¦X,Ý}™Ö»coÅ‹3£±T7(Ò\­svç?Ê|„R¼ÁŸR<ºó…W¶½‰¦ÓÔ<‰c¾vKZ(Ñ á`Üî£'ÈUK>oÍ;
-_‘í–!£Çå ìVŠ¼èdñX„²¥vTrÔeI³i2¯—²‘ûáœìèð–³¢µL*Kªö:§Ú)—^‘Y64G:Y7FÇÏs‘>rÊ,“Ó˜ª˜ɳNpG¼Ù Ý“öíñ` ¹Õò†>aÒ9JŸ“ §I-õ–òXþG‰4ó<òá0&>—c]dýæàzvìhŒ¬
-8}"qܕˤþ´fJ’ê›ëß·@5•Ž£K{êä­Åª°Í"È3·Ð!Š_ZRXzÛ3æц‰†[ö×Þ;,ùLe¥ÏÑeZ¦R2 HÊT+RDdZÓf…3+ÒhpN#ÏÉÆ–k’7Îe
-x9
-k$ÃÏÜZªCÚ+³ûænJ>òJáð,wöíª^Ò+q$KQï…m]Çé2ºEÛ9JEÍr½ö*ʨ÷¿@É$ßä
-PýJäöâLœIE— Sû‰P]¯æ
-GCeœýéà[ª€–ÊOïG8•b“Ôrh „ ´‡2žqÆfÐ*–œ=©î˜td%0·¤î€Ö …,YµþsÁiËÖ_gWYTMŸn’1ÒZŠ¯ÉUv ´ã óÆ6ÄéuÔ±8mÀìE¨ÿŒaúÀ®ÌóÉ5»âkqÊžåìOþDüáAÎÉ5["§Å{µ#méÊ—ÚŠòN϶Ty%Äý’÷½fáuܤçµàC¾ôëÃê7Mr«…ï_ˆ›Ô
-endstream
+2831 0 obj
+<< /D [ 2808 0 R /XYZ 81.145 448.565 null ] >>
endobj
2832 0 obj
-<< /Type /Page /Contents 2833 0 R /Resources 2831 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2726 0 R >>
+<< /D [ 2808 0 R /XYZ 81.145 437.606 null ] >>
+endobj
+2833 0 obj
+<< /D [ 2808 0 R /XYZ 81.145 426.648 null ] >>
endobj
2834 0 obj
-<< /D [ 2832 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 415.689 null ] >>
endobj
2835 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 404.73 null ] >>
endobj
2836 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 393.771 null ] >>
endobj
2837 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 382.812 null ] >>
endobj
2838 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 695.106 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 371.853 null ] >>
endobj
2839 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 684.147 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 360.894 null ] >>
endobj
2840 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 673.188 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 349.935 null ] >>
endobj
2841 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 662.229 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 338.976 null ] >>
endobj
2842 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 651.27 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 328.017 null ] >>
endobj
2843 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 640.311 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 317.058 null ] >>
endobj
2844 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 629.352 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 306.1 null ] >>
endobj
2845 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 618.393 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 295.141 null ] >>
endobj
2846 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 607.435 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 284.182 null ] >>
endobj
2847 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 596.476 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 273.223 null ] >>
endobj
2848 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 585.517 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 262.264 null ] >>
endobj
2849 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 571.569 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 251.305 null ] >>
endobj
2850 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 560.61 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 240.346 null ] >>
endobj
2851 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 549.651 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 229.387 null ] >>
endobj
2852 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 538.692 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 218.428 null ] >>
endobj
2853 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 527.733 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 207.469 null ] >>
endobj
2854 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 516.775 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 196.511 null ] >>
endobj
2855 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 505.816 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 185.552 null ] >>
endobj
2856 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 494.857 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 133.746 null ] >>
endobj
2857 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 483.898 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 122.787 null ] >>
endobj
2858 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 472.939 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 111.828 null ] >>
endobj
2859 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 461.98 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 100.869 null ] >>
endobj
2860 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 451.021 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 89.91 null ] >>
endobj
2861 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 440.062 null ] >>
+<< /D [ 2808 0 R /XYZ 81.145 78.951 null ] >>
endobj
-2862 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 429.103 null ] >>
-endobj
-2863 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 418.144 null ] >>
+2807 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
2864 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 407.186 null ] >>
+<< /Filter /FlateDecode /Length 1930 >>
+stream
+xÚÝZÉŽã6½÷Wø†Cw Ñ€5¶äÜ· ×ä”ÿ¿)²ÄÅ\D÷ ‚Fj‹|ª¯(Q"/_¨ûÿ··íóíûCÚ‹ Ö0—Ï¿ÞØ…ºìb€(qÑŠªØåóŸËRm)åÖŸ?þüüýz0õýaÄÅ«79E˜†I0JááÀ]ß²Cîšëxv‡¢á ™Ài%%ŒBKZ ç¤å’H£j$ ß$Hw%¯Ç•“Z^•’[ÂoI©¶5)K¤$¥‡”éêî~ÿA)s‡Ø‚…½ü\%‹ ¼"ï8 n&œò>M­Z aNÝ–U®ç¬B5áj¤uI˜&
+wÒ-oñVZJˉ2¶9~‰•U@ý´2„®všjø%)(ÝI7KÑ"!+º¼«Á—MjF´fM5ÖÈX…ôœh{A*!ÊŽ“îlbvWXžÅ·ÐhˆÁjî#“åõÖß›z`IY“ÓÿHó9¼°ÂKE‰aÐL¾z%R[NëÄæzu-¤âÆa2nâû=DðÅŽ%Rc‰¶Íõã1ÆÜ èú†µYp½',1²Y8Îò3ô^‰„2ª[´ß¶`“ƼÙâ’Ïé.@±ÑÝYþ©[Ú,˜ÍáÌ0Î9œƒãüýí¯µIXëùÈ 1ö‰e*y~ó=Z"µuð:2GȺ,Ä+£Õ˜=ð™Á¶Äñö${ŒÇ"ÌGÎJT&Ïh¼ŠÈËä ût&:|-YÁ .[®=»Ó‹®-‘yíºD^}$Þ€©’i/¾"Ðî8‘’Fg\~dÏ|›p?õéŽX&cpqU·Ž}ýɱZµü¹Ø7UHò–âfÿÙBŠ:rØÙ/пX\ÏŽS'NŸƒ]»,ú*B™núom÷¾BÊå0¯/ÒbRÕÆÕîIXI\ÿÜÒiñ=@…”$~©©ð{ú×gª‹Ô|âÆ~Iüóü’>Åés}Y¶©„ZÛ´©it¤BsÂkÆ•\éH+ ~G
+?dÅWø—;R¡€0M%ÄZ •H+¯…úz ögñS䑳q;Ð!ÕîIBX~0y±ÎšàœYS[ÂõEpN E¢ÁZøñsþžÚŠŠîáòæ=U˜ÉlÇè:°÷•O[šþJëÛñKU¼yð™~k%¢D’í¹Î±w¸¯o8"0›ã/*†–OšxLJr ÿ¬Yîæ«)@8oæýÉVó¾êç=g3¼žÿŒ¹€kæÿbgY!•ùϤÆ0WæK›SöÔ*+q¾±â”mk¤²èÀ=qaä·E>ÜC„ùUÒ_ÍâhÃ¥¬ðó¿ûk|{>ã~ܱ±9òënŒÏÍù¾…÷Ï>ªBì«°|77®Ö<Æ%BŠ–ÇN<V!íz]Ÿ{ÒÝ–úýH bìßæ›O’¦~´öëaË-{ç3âñ,ëk}­S SÓgû×&mÈ}ÅGÚaUËG§¿ Š>*‘PŸ=O åM^ ½~<‹E̳‘}r¼có˜Î7¨T¶*ñì‹Ü@ò~ckÀáƒû©} $
+²ÈÌ"w'
+[¤?·,Iï3œÌ¯Ñþò6…F”_d<㌣ ôksö¢S„³³nÒ€µvº
+¯±D¶ñlÓ¤U\¡©Š]ºUŸ!”ɦbk-v…ÔÉ…õpâTßtä¥8¾€é•¨ÿOh‚&nV³^,u|Pzk¹*ëµk
+t²kCJ ¸goe džÁä‘„o{Žnå•B÷Kž÷Z„NŠìjŒ0Çk?ŸÂO÷Ñ%ðM!¿F³m‰H¢Ià™Áýf×Ý´&ÿà–ÞîXç —_‚º 펧uýþùöþzKª
+endstream
+endobj
+2863 0 obj
+<< /Type /Page /Contents 2864 0 R /Resources 2862 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2711 0 R >>
endobj
2865 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 396.227 null ] >>
+<< /D [ 2863 0 R /XYZ 78.37 808.885 null ] >>
endobj
2866 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 385.268 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 768.829 null ] >>
endobj
2867 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 374.309 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 757.87 null ] >>
endobj
2868 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 363.35 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 746.912 null ] >>
endobj
2869 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 352.391 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 735.953 null ] >>
endobj
2870 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 341.432 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 724.994 null ] >>
endobj
2871 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 330.473 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 711.046 null ] >>
endobj
2872 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 290.623 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 700.087 null ] >>
endobj
2873 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 279.664 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 689.128 null ] >>
endobj
2874 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 268.705 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 678.169 null ] >>
endobj
2875 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 257.746 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 667.21 null ] >>
endobj
2876 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 246.787 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 656.252 null ] >>
endobj
2877 0 obj
-<< /D [ 2832 0 R /XYZ 79.37 224.075 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 645.293 null ] >>
endobj
2878 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 205.94 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 634.334 null ] >>
endobj
2879 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 194.981 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 623.375 null ] >>
endobj
2880 0 obj
-<< /D [ 2832 0 R /XYZ 79.37 146.359 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 612.416 null ] >>
endobj
2881 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 128.224 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 601.457 null ] >>
endobj
2882 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 117.265 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 590.498 null ] >>
endobj
2883 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 106.306 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 579.539 null ] >>
endobj
2884 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 95.347 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 568.58 null ] >>
endobj
2885 0 obj
-<< /D [ 2832 0 R /XYZ 81.145 79.407 null ] >>
-endobj
-2831 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /D [ 2863 0 R /XYZ 81.145 557.621 null ] >>
endobj
-2888 0 obj
-<< /Filter /FlateDecode /Length 2595 >>
-stream
-xÚ½[Én$7 ½û+ú¬‘(jÜcw€œ} rMNùÿk´oŪ.µ'Á`ÆeU‰¢HŠ|$5œ©Ëßîÿýíåöõòã®Ü™³BÂåë¯qáþ¸X`/F Ƶ¸|ýsùãʹ¾qnœÿ©ÂóÛŸ_¿¿ð@Ì“úq·x±Ìi-mOÇæÀ΄Ðp®$çRø¿ïžØ'çà‰£õ¿çâ§þHÏšûw~\ùo”HßÅ÷ùû0îíUò”%–'xO߇ïz:žžv™æç*…ªRõi—ŸÊÁG}’iá»ð}¤ •’Ž¢üq¸8/Bð’ïDh“æb„e eUEàò(½½¢5aÒþÂ:™÷[Z'}!ãhùMñ$£Æ{æB(Š à’™`#F¼YyÍ|@x*2 á^FÅÏð„פ‹°fäÕ5{ÎÒúÉõ`
-ļ>¥ IZ‡;”Ê2ÅÕf‡(D^ïiÅdKeoeýhe.¿åMËù+ùö
-6«¡L‰ŸB_OZªL*‹‡myåo:RqG“¥pÍ$7ÕRêIRJbW˜m#½-£­4.§ oÕ–"qÏõËð•4õ·•ù±di¼óDÇnH;`RÒ ½¯¸¡‰Pd¦7 [äšY5糸1+rKmLºS’3kÜLI½×xÓOõ±ÊŸá Ñ‘üÙsüçkK z‡ºÈ“rŒfI«s,!gà6„ò!ˆþ(öàŸEsYÉu¯ò‹Þ­H:†âÃ#%åV9‘†)¤6å'#¥ÎÚñTV­kÑì³IlÖÎW{ãd~Ÿ[ª9|.È4ÓBRrÀÏ59Œ”Ö5"Ó
-7œ`ø¹ÆÉH)€šàzѬrÄ‘i§)Ž¬y¤‘¥C³*/å<‘†âî$-þh¢Ôù£_ã9•1Ì
-Arº²&Bû!+8ªÃÐT„.ÆÈ_æ]°/uiú!šg,-º1?R+6¦1[B<
-ƒüšŒ ›œû¸FÜ=2W·äò•hˆ´!¥}\ígãYÔSßg›¥²Š4V4ؾ'ëâ{Þ=œóþA7ŠsPÉ!èÞâ*ÇûïÌ1>6Ö[âFÚJWD7iÅ O¸º$2…²s°ê:¡ê „ó›}¹G‚‹Ö o`®ý¼2§Qˆk´UÓ¬0Û^û7çö¨ùÖ²Ç@Ùð~M¼¶\±€†p–44@¡"tˆ]çQ^vhèJ£ðqL±—^â]ç=J˜²ª['=˜¥>J­è¡xDõ “šô ŠùùEße+êæ·õMÙÿÛþþó¹Ùœ¤mæ¢0'KýñîS„æJsrÄ),Ø;„ö,µmï³ÔEç<ò(ýÚ; ôÁ’ñ.†Û^ÙÑì?f´§L.J,'¶ÅicnÔCªŸ¾Å[Kõá–MÀÙ¼I>%“eîQ*‘#]‰éœhqžý~Êjíh÷»®ùtŸÛçífU$"e)U ªÈ>‰w¾þF/™|V©ÔÈêëì¨pB\0Íß–úI^³_?¼ëèxh!(O.d
-+&ý^Š±¸Ç»aCá})Îiÿ¸7ņñâF“£Mß`¦Uø ¤ä3&Î*\-€ 5 (,y²J±ä@fI6L°E&¼÷@9P0vHÚ\ÿ> ½ã„n9@£ ±O'ŠXFBÇU¡¢yü „ó‘ÀW—Óò¾ÝÁZµ/ì26k.½Aë&Ä.{ùH°n9_ñî€%mìdY¥s$´/ÌRkï‘)Pµ'Ð3ÂÜ’yFHÊ; ¤pIH#¡!•èûtÍQú¤¬9œ­qÃ$ÂL)Xx~ðÕce'$Db*ù<u
-–Õ)!W”$ÎÖ¤bÊG¤‰’ÌsÔ¡Àv‡­ÔÎ>cYm[K[IÔæC‡  "qh˜Éþ »†£±²ÅŒHj®sÌ¢œ'“A–†ÂçÆŠ‰‚z§²úý:4¨{Ü3L©y±9éÌM“œt¡ú’`V˜x?—="¤÷>j{ò¥<]mÌîk"t0Ÿ×Á³îÍD¦¹¦6y¶€™ÝÛD鯛-îÛ(ÿÃPû>]ÕL˜)-7h|H`ÚZ’“÷%·:Sún+F*É 8Š³Óí¶ÌÙHi¹ðïíËû,’»ÆÈ@è×5bþÓŒôù'Q¢Ö¶?RZ×pfœà'#¥§0’ûxè$irí”vr®Wáù<áÁúõyùCJsï3Hi3ÚˆO±Ôþ%*U \r·¹” !u­€Ú5žOÍPc³›h\Š?æ–±êP4CùÚ*ÂýM“‰nk?…Dë5Ÿ=x„Ü2éu2‰~¡’3?q"Ì’Kª©uÅdÞ3œÐŒ°ÍÃølnü¨§o·ÖKëõ›¬(›òªY³=×Gû5k-ríXƒ5YÒãŸÌ52öšý*ìõ4ÞLÈM´ÇÏó-lÌ#鉕ÞÓõàçBÝã\ú‹þ8í’°Õ¨(¼ßv”$‘ëD©«<˜žM.¿ø¡¦§cû Òs¤¯G7,!vSɶ r·NŠîœw×KEÁ'“(Qýáôm×zrkuuÛ}Z:ï‹«Tjç>^ìÁi˜]¡ê{Š…¯ÒOì{Œº~=ôãâAñÌMBUz ¹µt”ÿ£UÌJ7ï;Àb#c¬=èyf×Â;Z7YðaþJY¿¨óÄØÝ2z0¼ÖY“ˆ£@òH9ÌÁ\b"Ú µ?n}x¸éSFZ䥅ºnÁTáb…ɨ*”;mü4÷”º+ˆ(p¾ãš‡êml}ËVtÙk´.VœŸzÜ™}]–ío¤‘éóУªÎ^jcw¯ÈwZµÂg¸Š‹ù¬‚›{åõn„;'Ô|ª¹˜ïH8(27d£ Kÿ4XCZb¸"Ùéݱ¼?bÅtúM‹ÆÙ_‚žoa™?hJÝœ?ï“ì$p»›{Ü$çY'ϺԎqcV×4obO³B¤J"íag“Eùæ„®ê]UÈ9Š+Wî›!•°]Ó“®(óô˜L¡îëÚ®[ôÁ—BÛØwhGL¯Ò/
-æ­ýŸš‘ÎAé’ÓÔÞ]Ü(¦·ÿ/(îá} ªN”ž-²îïñ[EU!NêêlÁ0ß7(©ÚkÕ4A„ÿˆƒ’äÉ.Ýž(Å6þm(®ÊË3I³X»›?Ä5Öñžn{O´t­`ÉñÉúŸrL€œQ9©/LÜžàÖpfµ&U²6h¼ïPr"Ô]ÕøV¹•Ž%îNofM:#ß'(½T†®tzZ‚´'L{0ç-Ï™VÇh·H>¿^þÚk¯H
-endstream
+2886 0 obj
+<< /D [ 2863 0 R /XYZ 81.145 546.662 null ] >>
endobj
2887 0 obj
-<< /Type /Page /Contents 2888 0 R /Resources 2886 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2726 0 R >>
+<< /D [ 2863 0 R /XYZ 81.145 535.704 null ] >>
+endobj
+2888 0 obj
+<< /D [ 2863 0 R /XYZ 81.145 524.745 null ] >>
endobj
2889 0 obj
-<< /D [ 2887 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 513.786 null ] >>
endobj
2890 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 502.827 null ] >>
endobj
2891 0 obj
-<< /D [ 2887 0 R /XYZ 79.37 730.218 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 491.868 null ] >>
endobj
2892 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 700.135 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 480.909 null ] >>
endobj
2893 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 689.176 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 469.95 null ] >>
endobj
2894 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 678.217 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 430.1 null ] >>
endobj
2895 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 667.258 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 419.141 null ] >>
endobj
2896 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 656.3 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 408.182 null ] >>
endobj
2897 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 645.341 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 397.223 null ] >>
endobj
2898 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 634.382 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 386.264 null ] >>
endobj
2899 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 623.423 null ] >>
+<< /D [ 2863 0 R /XYZ 79.37 363.552 null ] >>
endobj
2900 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 612.464 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 345.417 null ] >>
endobj
2901 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 601.505 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 334.458 null ] >>
endobj
2902 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 585.579 null ] >>
+<< /D [ 2863 0 R /XYZ 79.37 285.835 null ] >>
endobj
2903 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 494.968 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 267.701 null ] >>
endobj
2904 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 484.009 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 256.742 null ] >>
endobj
2905 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 473.051 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 245.783 null ] >>
endobj
2906 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 462.092 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 234.824 null ] >>
endobj
2907 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 451.133 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 218.884 null ] >>
endobj
2908 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 440.174 null ] >>
-endobj
-2909 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 405.333 null ] >>
+<< /D [ 2863 0 R /XYZ 81.145 186.007 null ] >>
endobj
-2910 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 394.374 null ] >>
+2862 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
2911 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 383.415 null ] >>
+<< /Filter /FlateDecode /Length 2628 >>
+stream
+xÚ½[K#¹ ¾Ï¯ðX­DR/ 1@{Ý^ ç¹¹&§üÿëê]’ŠU.¹79xÆV•(Š¤¨–·ÿÜäíÏ÷_?~ܼð Ý~ýû‡
+äMݬhoÖ(!ºýúïíŸR'%>Ã~þFÎÆ>RJ
+ßéžÞãx}Óhý¥Ã{ð)¥ú#Œ†÷Èýüׯ.”æ¸
+
+*ït¤ÒŽ&K!/”4ÍRÚYˆÈ슊mä§u4²•G"ÃqçIÆ÷fK‰‹´çöf| mûµ³²0–-M
+?üûgЉö7Þ)„^'D´9Ô‚fêŽ9Ä@+K@–côûÓÑÍÝt=o…7JÌô$¬A¯›U™…´º1 d¸™û¥)”ÂY?SÒŸm'C ü¿~¬ò§P€³,Ÿ×ø%hO dãO¯ò$A`Ð%Ãúk<‘à÷”Ê1H:~T‹ßÕæ´àÞÝuŽMp]È
+ÝÃ#!íWùpRR¬6õ##¥ÎÚ4ó ê7jZ7j³Ïú­Ziü?ž¯í‰6õ›úÚS Oå`¼ ¬hM#¥u„+‡<²¦kœŒ”Pe×Kv•#²B#qÑ×’Gš(q:´ËòB#´Ý]ôµÑºè&J?ú{<gp"‚ç8]»²&BÇWVtS§WSºoþ:ÏšL9Â_Gôãmͬ ƒ:ÖT ï]©åpa¶Œx´Ûd±˜ÊØ$â8Æ5ê1Ä=;|­6Dº!¥c\fÓUÔÓžèø^YKÖѸ¢¥íýxÝ]œaâÀ»À€T§ýƒÙ(FÎAg‡`Êå–V2Þ¿gÏñ±u©´µiˆnÒJ¸$”iG MŽêÎÁé U \žË=i|²fø ö£Ÿ7Cæ<
+imÕ<+Îvý“†s{Ô|¯ˆ?S¶²_“>ŠD;ÈÏ’ NèÝb7eTÖF¦Ñ¨|œS쥗y7eSTu盧ÔG©U=T/©žDR“¾›YÔ D¦¸Xž¶'uûý¯ãí—c³;HûÀES‰•úÓÝG.›'-±‘ä€`ïF8س´mû˜¥îr.#¯¢¯£³ÀŸ;mhÍe
+ Eþö1ÛŸ»dqIb%®­>³ÚòF=Fúù]ºo‘>ÜË™‰ [n’ϱd{Iç3äYOb;Z}g¿ŸºÚv²û]·pºíËv‹*2‘º”®U—$;Wç—Ì.«&j°¹:7*œQ'‘h¸®%OÊŠýêñYG%à
+Źq…é‘n¼À‹©«§)­]8굜GO’M§I$šiixû Á-ºi^ôXõ“0HeÃæßIIlSÉâä¦ø°œ‚ðzn
+ãÕ{fÿšß¡B3©îE&)Äi6 ÃQu«Y€4zB^L9:†ØÃÆ >{„)X7Dk¾!Þy$·h¢.båò¹$—Îy2¨jžŒhsu¡l '"
+ìЬ>u‡”¿6k®H}CÔ›» å‘ÑÜr˜¢ep²¼˜L©²  îÛÓ
+øXê#^æ¡ìB¢°G È
+É­i"´"¤zë¾j$^ßš‹ÉiÌ”¢…ÇK¯¾~­ìñ„Ę‹9/‚euZ-Œd“WÓ?¨…÷ÑD Ë%JåÖ!À~‡ögŸ˜±ˆ¨æ±NbM­æÐ!'b¨ õ‡m£Ô@ùs)ú&M‡7 An®÷ÂΓÙK–
+´°LLô'̧/`ƒ¸çå¯ptõ¼Øk–ZI‰5ÏÐ|+<|^ }ÞÀD2xöä_L2V÷5:¹0ß×ÁÛî ¢ÒØC}5oYÝÛHéÿž.[ÜwÀ0R$ yï—3¢F( 3¥åº $Âqr1ãÙÜêDé»õ ö+ç8»\eËœM”–óý!ˆ
+YF>×ý}õ—ÿiÝÃu©¬â¶µrW·?RZ׃!bQ–·ÆÉHéíº j yÓÐKçx¢tqý¦ŸWoxDd‘ëù@´c¢+h#}KöWÈ(S9Éþ”L»+ô”ikmPuÉõ>µCnÍínãšô±÷‚U‡\ òÆ["¸o€°…è>çSIl¥&×s¢Ä “Iô I
+Q¿Ç™@4N.9—ÖåeÏpF3vÀ6/WŒÐjsãß@=}•å4OÚºnŠ¢\ŽK¸Í~öœí×l9ÈÅc-0ʲǚV°×DèïÂ^oã-ð!ôÑìmµr­@„Øi"Ä…÷|þeh!9¹ê^ÇÒ/\$È×ál„­ÞŠàHÏ¢“Eä:Qêò#o¦WƒËï#~háéX6ˆ‡ô‡'áëYc% À6VJÜú†ªk} îºs©¤ää`2%®,œŸëJN~-§°PìÅ™öAÕUj}І—jofW¨ûRbå«–ûÒ¢iou¸4ÂP¼Ò@¨ké³””ÎârZ8ôó¾#<'öôfL¹3ÏìJwgë« ת2]?ÛK(墨扩ªeÍ`x[E ‰F”‘z˜£¹¤@´jÜúëiWŸL´Ø^…¶nÅT±ŸÂ–ŒGRáAõ>Ͻ¤îF#!
+š[[ËP½| Œ¾e/ºâ5¶
+VšŸKÛ…}S—íòÈÔ¸¼4Ái¬ßU¸[A÷¨(J´Ðh3ŸUðs¼µDøkB-§Zª¹5ÂCõ¥›]ë¦ÑòCg@b§wÇø|ÅŠíô›M²ï}ž›/ªÌ_‘TÀ³~–ÊMÝRÈ
+gv{®£^ãÌÄ‹ÎM„N¾ÁòŒŽe@á»ëŽš£ûúõã/û
+endstream
+endobj
+2910 0 obj
+<< /Type /Page /Contents 2911 0 R /Resources 2909 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2711 0 R >>
endobj
2912 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 372.456 null ] >>
+<< /D [ 2910 0 R /XYZ 78.37 808.885 null ] >>
endobj
2913 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 361.497 null ] >>
+<< /D [ 2910 0 R /XYZ 79.37 773.016 null ] >>
endobj
2914 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 350.538 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 742.974 null ] >>
endobj
2915 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 339.579 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 732.015 null ] >>
endobj
2916 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 328.621 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 721.056 null ] >>
endobj
2917 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 317.662 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 710.097 null ] >>
endobj
2918 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 270.865 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 699.138 null ] >>
endobj
2919 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 259.907 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 688.179 null ] >>
endobj
2920 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 248.948 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 677.22 null ] >>
endobj
2921 0 obj
-<< /D [ 2887 0 R /XYZ 79.37 212.322 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 666.261 null ] >>
endobj
2922 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 144.388 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 655.302 null ] >>
endobj
2923 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 133.429 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 644.344 null ] >>
endobj
2924 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 122.47 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 628.498 null ] >>
endobj
2925 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 111.511 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 538.168 null ] >>
endobj
2926 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 100.552 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 527.209 null ] >>
endobj
2927 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 89.593 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 516.25 null ] >>
endobj
2928 0 obj
-<< /D [ 2887 0 R /XYZ 81.145 78.635 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 505.291 null ] >>
endobj
-2886 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F15 326 0 R /F74 329 0 R /F81 366 0 R /F83 403 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-2931 0 obj
-<< /Filter /FlateDecode /Length 1831 >>
-stream
-xÚå[Mo3'¾çWød30€Y²ã¸RϹU½¶§þÿkaÝ…Å6؉ßJUåÚÁ뇙a>^z÷÷Nøÿÿörüzy;k·Sà¬$Ü}ýõ"wÂÿ'wÕΰÁr÷õÏîw!ø(„qB¨ÏðÚÿùõû‹`êílÕ΂c&»Æ‘Æ€ÓT#i·Õ¨Ã')z\ùá1ý»²~Ïè_~.~ÌV'!èç\©pC~-@
-\˯1ê`ܘü%ÒJþ —ïyEþ¤ôüÔòÉ놇¨÷¤¯QÒ/諽þêíþ¦søÍŒ}j â<ß<3ËZ>TÑ–‹œšó'ù¹ÅZ¾]ôÙêªÄzV£ëC¤¢ÖúxI†Ö§DZÖ‡¼uҌʆ¤Ÿ´!ûdc ÚUH-»goì—N@ÔMé}Òio1¤iµÚ‡õºcXwžÖ~PRÁ€Ì-I©3I€5®FB³•Ú$g @ogÄó
-IÓ¬ÉH‰÷´ýJ‡mÂ<…¿Ú)›ÏWð‹D˜‚!¸þt<ÍÍ·R±™q4u1"hÓ^5äl%Ðeg“ÇäDÇ3EU»ß¡¤–ÍL4æP%ҥʬd ŽuEV)'Lh£"+ìùíjÉm!°nfü^.–mQ"­\÷Ð"!ÿqÊ…*þIL0ƒšië€Ý¦BDíú4“ F›é6{êz?Á’Æ‚ñ¥®aÉ^>•-Y"]dÏò6`ŒmiÖËƲf%R‡|,»“°¦¡ö`8ê45üãñüŸÑ Vº¦ec–-‘.ùÌŠE¾¥¾LØ´çôÖÎÕ'ó3Nš«´CœÑû2ÂËÈ©\»°:ñ›¼·ŠVOÒøÉÒH+ÁsùZž©¦õO;Ó·³Q-ô™W
-yI£È8o²ÍKÖBŽ{ =i—}p±Ê2ðó¨Á•MÏWõ!Òž¸–E¦*v÷ÙF7´ +ÀÏVA¡Â2MÉö¸Gû> —DŽðû×8¼ŠŸ´ú6ê7}½–ø2¼˜cþÁqýƒsZ›ã~4²Pƒ#ÝŠ¬ÎO¢aÐÎßïP÷R2-ýW¦Y¬;72™†THÓ¯Ž:…tk’ü!]â¥ÆÈé¶#VÜ{ÐBÍ"ۻˑB×@eŽ(§+G~‚vµT#"V@÷K•Ú]›€jÍäÓSiûüqR­ü›lúòØö¢ÀÑ£Íe|QM9©}…ôm1E×£+Ó—°zÍ=qñ«ËÏÌ4éüP„z~Ònš-±}=Di*¤ï Qå
-é¾½^-RË%óÆh&Xö—lŠY˜xÄÖŠƒÛ‚
-é;W}l
-Ý”qŒ`WH+‚­Geòˆ¤¸%SwSÖS@Ë5RIõIݽ=ì>L¹‡ï»êí䡬iZÖŽY¶D®*ä(´M¿ÓC’TH7š}ƒRZÅ®)e'UQÐmŠèxÀïúZ›ßr¨CA˦ëИ)
- ò±­›•´—™¤c¦é»Û¤ýSn[Oý5?KZ"Ýh} Jéw·Lª%eoÕÏR–H?×ƺ~Ð\2Ã2ß_?Õά„Øè–ízk½gJFØ©%g8ØÖÃ>( ÉM ;+=2Hƒ5R×ù&ËÍN¥°êÄ=Ùþ•pÓé¸Ú¥ gÚN_›‹¬zsLÕÔÎm4«&SºÎ‘žVáiŠçmt£zý¬=Ž8Š4÷{òÏù{Y±³šŒÓä¿–~ß ”h©ID ÷¾ÖD€ç9™ûZ£ˆ—)( çòȦõõ¿$jXŠj•Ù»ŸàºÉwS‰¹_F&7;es=vÛyfÌ{-ßg=¯»
-ST#͆¼Ýqã{ºnèÓ·Ó®„c]·
-¨¯ëÖîuÜÝmC%šŠŒuÚV(ßÚe;^èëœn`<Téˆm·dʲc· *$½¾„Ò‚hôm¶¸³«†yÚtÀ€MöÓM5øE©‘¾Ó_–ò?‘Î×Rnr­^îšö?Ò>·û)­Üv&hàzdâ+Òð^U¸íGÐÀEÀ¼V%Ò¶Oýó»¡þ¢µ-›öòålÓi8OJ@èš’†²S…4œ'¥’°½Awµå‰y ô‹.΄‹‘Jʦ: Á¯¬%Y#E™Õ?ü¿Œé@m{4p›1[·DZ¬ý†Ÿ}™F
- jÛ+¡þû³f%Ò}~ó”ÊøóVõÛ½míÐÀ]ÅdÔh8ÛZmšE½ûßløt¯t4œkÞ6CÈö“‹€ÃNÕ„;=2oÔ8?³-xp«KgjŽüϯ—¨Wtˆ
-endstream
+2929 0 obj
+<< /D [ 2910 0 R /XYZ 81.145 494.332 null ] >>
endobj
2930 0 obj
-<< /Type /Page /Contents 2931 0 R /Resources 2929 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2726 0 R >>
+<< /D [ 2910 0 R /XYZ 81.145 483.373 null ] >>
+endobj
+2931 0 obj
+<< /D [ 2910 0 R /XYZ 81.145 448.693 null ] >>
endobj
2932 0 obj
-<< /D [ 2930 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 437.734 null ] >>
endobj
2933 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 426.775 null ] >>
endobj
2934 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 415.816 null ] >>
endobj
2935 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 404.857 null ] >>
endobj
2936 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 393.898 null ] >>
endobj
2937 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 382.939 null ] >>
endobj
2938 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 371.98 null ] >>
endobj
2939 0 obj
-<< /D [ 2930 0 R /XYZ 79.37 675.375 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 361.021 null ] >>
endobj
2940 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 657.24 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 314.386 null ] >>
endobj
2941 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 646.281 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 303.427 null ] >>
endobj
2942 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 630.341 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 292.468 null ] >>
endobj
2943 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 619.382 null ] >>
+<< /D [ 2910 0 R /XYZ 79.37 256.077 null ] >>
endobj
2944 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 608.423 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 188.224 null ] >>
endobj
2945 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 597.464 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 177.265 null ] >>
endobj
2946 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 586.506 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 166.306 null ] >>
endobj
2947 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 575.547 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 155.347 null ] >>
endobj
2948 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 564.588 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 144.388 null ] >>
endobj
2949 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 533.704 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 133.429 null ] >>
endobj
2950 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 522.745 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 122.47 null ] >>
endobj
2951 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 511.786 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 111.511 null ] >>
endobj
2952 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 500.827 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 100.552 null ] >>
endobj
2953 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 489.868 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 89.593 null ] >>
endobj
2954 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 478.909 null ] >>
+<< /D [ 2910 0 R /XYZ 81.145 78.635 null ] >>
endobj
-2955 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 467.95 null ] >>
-endobj
-2956 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 456.991 null ] >>
+2909 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F15 326 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F81 358 0 R /F83 403 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
2957 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 446.032 null ] >>
+<< /Filter /FlateDecode /Length 1748 >>
+stream
+xÚåZÍnë(Þ÷)ò¥Àù¤*RÒ6#ͺ»ÑlgVóþÛ¶Á$4Mïht•ÛŸÏÿù8Ž´û{'ýÿ¿=?Ÿ^Näv(œU wŸ=©ôÿÔÎjÁ¸3¬„dµûüg÷Ç«”|”’tþÞÿùùû“ `êådqg…c»ÆQä„ÒP#i¹&MþˆóÑ{X÷ߎ#úJØ+’’Jê–¤|쓤°ÆÕHÚ쟙I@ž€^NZïœÐþ¹+
+Toáïì5 y%}'5‚ŠÚ+Î^]ÂxÎ;vZװ΀£Jú/@×R\Ÿ¯½“
+(w{@ lÓX@•HH°ð *&Ç"{ÌùP¦oõ¤mСî¹wåòA[
+tÍ’Ï8f‹iº‡® õS-Äøw.$±ÀŒj š- O3Å©‘™ ?À’Z 2в$~ŒY²D:K Þ#J V¸Ñì0Ê!ÍJ¤ŽyKÕ.Õ4²‘=Ž:Mkøøz~LÌH)xÅ‹V–í¥’Ù²%Ò¹˜YÑÈ—“¢óŒ,£æî“ù'̓BÎM àuYáeå½ô]ðN<3Ý9go’ÆBKe•Plky¦n˜üÇ„`°… }åURÓ(2Ϋlóœµ4ûnM°AOÚå\¬²¬ü¼jôʦ§‹ú
+ÿ´
+2Ü4Ûã^Û×I¸$r„ß?ÇåUþ$ïÛ¨ßtz!-ñcx1Ç|Ãq}Ã)yÄæ¼Ì,b'ŒQ­ÌêÜú$V]àüýu+%#²Â*ÝTê0DC*¤³å—¢N¡Üš$(—Á=­²Kï×±âÞƒ@#,A˽»¥…¤¨¬ñ_ªé,¬kvËÎ @±º­Yâ!ÅkP­¦™bzjmßNªýmÂA³ù n0*$r£’(ÊpS’1z_!Ý-¯àr†e
+<ØÜw¿f¦J§¯e©D!•i¦Àئ¢Bºcš¢Ÿd¶%ã ]¯nËÓË#å²Zò0oŽf’edcŒþkÓdÁ o
+œ{zÙxúˆM  v…´"Ø4*K¡¬nÉÔ=•õÐrTR}À›·‡›{îÉBä]ŒôÛë¢ZCÓ²‡1Ë–HÃÁŠ‰co%éå)Y’éÊ°oPJí»–¤¦”T¥ÐnƒTdÇâ®o´yf‚;h Ÿç€ÜŒ³E‰ô•J!I€5M™pèMStïA8¨m3’`HÒ
+éÊðkPJ¿¿Ev-){{~–²Dú¾AÖ
+¥ñn£ä…eÅ¿ü^c¸¶‚Ñ‚¶Ôö·z_R´PKJ”Kwî—• Ò-{;½f¡Œ®‘º^pz÷ v¦õ‚QWÓ¸'Û?ƒÞL:.Ni{©éÒ³Àâk|ÆÔMí<†Ñf5d
+ÕŽùj WC|߇°JëkmœqÄU ó¼'ßÎïq–'«ùÂø˜ü×2ï›%5‰äÙךðüŒ°fƾ4(âå„sye3z‹úŸ5¸¢ò²´Â ®‡|W•˜çe`ò°S5ì{½Û>'`Æ:±'õ:ëy9T@8„i6äõ‰ß2uóíO˜íì#$áØÔ­꛺µg7OÛ´¯ñ¸©ÌØ´­Bºë´íxf¾ó~íEÆ—ú½öEÜÓ²Í௠*$/ã $¾Z;e›’Ø¡^…4ÌÖ4I_ž]3^z$ ï”éžñ²Ô’ÇÄ Ê¦=ph´BùÆW†~jí„Ä&¡êẻ¯THÃ{U­¬¶ÉœzYqöS‰ôËΩ¿ÿÅîôÒq;‰`ê§ËÙ¦%Òp}TÎGÉv$éåÅ©*UHÃõQYz;m’ôνÈï ×H?ôÓePèíÄ`Ò§“pàªFŠ2ãœAüÌ `mm˺½ #[·DZ¬ã†ýsEZ€vMÍì˜f%ÒmqóÞø
+[´V2Ò˜Q  ñz Ò×(Õ¤“õ¯H5Òx½UNàv"2ÅY'Ã@\Uƒ¸÷G¥ßÊ¢k¶Ô^šâ´†j¤ÿÀ‹õï·®ßwlYöó•dÜèÇ»hY¡–^½ì'éUýÂÛï·©!ÁŠ[6íåq©Â•@^ãœýõwïÐï—ÍÂp®µŸOÿŽˆ‘1
+endstream
+endobj
+2956 0 obj
+<< /Type /Page /Contents 2957 0 R /Resources 2955 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2711 0 R >>
endobj
2958 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 435.073 null ] >>
+<< /D [ 2956 0 R /XYZ 78.37 808.885 null ] >>
endobj
2959 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 424.115 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 768.829 null ] >>
endobj
2960 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 413.156 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 757.87 null ] >>
endobj
2961 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 402.197 null ] >>
+<< /D [ 2956 0 R /XYZ 79.37 719.21 null ] >>
endobj
2962 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 391.238 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 701.076 null ] >>
endobj
2963 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 380.279 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 690.117 null ] >>
endobj
2964 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 369.32 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 674.177 null ] >>
endobj
2965 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 358.361 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 663.218 null ] >>
endobj
2966 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 347.402 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 652.259 null ] >>
endobj
2967 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 336.443 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 641.3 null ] >>
endobj
2968 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 325.484 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 630.341 null ] >>
endobj
2969 0 obj
-<< /D [ 2930 0 R /XYZ 79.37 288.817 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 619.382 null ] >>
endobj
2970 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 258.727 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 608.423 null ] >>
endobj
2971 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 247.768 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 577.539 null ] >>
endobj
2972 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 236.809 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 566.58 null ] >>
endobj
2973 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 225.851 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 555.621 null ] >>
endobj
2974 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 214.892 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 544.662 null ] >>
endobj
2975 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 203.933 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 533.704 null ] >>
endobj
2976 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 192.974 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 522.745 null ] >>
endobj
2977 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 182.015 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 511.786 null ] >>
endobj
2978 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 171.056 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 500.827 null ] >>
endobj
2979 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 160.097 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 489.868 null ] >>
endobj
2980 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 149.138 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 478.909 null ] >>
endobj
2981 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 138.179 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 467.95 null ] >>
endobj
2982 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 127.22 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 456.991 null ] >>
endobj
2983 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 116.261 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 446.032 null ] >>
endobj
2984 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 105.303 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 435.073 null ] >>
endobj
2985 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 94.344 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 424.115 null ] >>
endobj
2986 0 obj
-<< /D [ 2930 0 R /XYZ 81.145 83.385 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 413.156 null ] >>
endobj
-2929 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R /F81 366 0 R >> /ProcSet [ /PDF /Text ] >>
+2987 0 obj
+<< /D [ 2956 0 R /XYZ 81.145 402.197 null ] >>
endobj
-2990 0 obj
-<< /Filter /FlateDecode /Length 1648 >>
-stream
-xÚíZÉnä6½û+ú¦L²ª¸
-øôçIÅÿyº|<=ß8œ‚×hN<é“ŠÿôÉ°trVƒ²úôñ×é·¥ìE)6J¡OÇ×ß?~}R ,B=ß<<kÑqt0 ·HF½~aÃñŒ8Ÿq9{×ß”ÒñCñßÉñtŽGŸ¾E.×øÝo?{ÏOšë~vYŸgŠ÷&<³>—î§ø¬ ë5tÛ1~ìΊ펳_³ñÍd×»T½Ó[ÌÂrõÈÁÁŸx—heFÞµ™wk¤Â™ÏûY´Ù$\¿‡e@-;Ë,«‘‹?ή6ýÈñb<èè®W1ÌyÕ!â©°×»g\²ÓŒá!;?ÇÎ"xÔ-ÒêQÚ£ÙnÑÌv‰f!KeÁX;ŒLžcI ÑQ-Òȇq±÷:9ÍÐTnÈæ"{Û"E?
-™x¤0\QùªAb–2‰q‹C"ô>G„ HÛ¨®ŽHß©:Zk€°ëª–KÖÍšS#ý]U+Vÿ²{Y93rï¬hÉî­‘îµUæ
-‘¥x—ÆËÙæŸYÖHÿK«ä]€™†Þ=‹šQƒ$/¢Ú1™mÚ™I$/¢ÊE;dâEò¡AjDæõlà`Á:7\/qkÄëÅžÁi?dB2&5ÒOœìÜ8ðP”5ÐÊvÉe‘­œ Õ° µEƒt·[<"[™ xê{ÍK†MŠ5Hÿ˜leÒà=ŽÎv]mÁ±k‘"C!T ˜ÌvÖXß0ú¨AbqléÁyÈä,cR#Ý­%¼æwÚì:³ÖxºÔƒQí`<F&m#åxª8©òäJR„qôÂ1šuÙVÓµºO¼n*ĵ#oÍvÊì­©®lM%ëªß¶N'<ߌ9¥P0ÑaË]
-ÖõšÍ>ŸÖvÕ\øÁø
-›ø
-;lƒtà‹Ûnôšë’”#1„~KïâÛ º“Ýö=9N·còsžZÈy#ƒÒaÄ[Ø}¤º«:ÊÊeÛÍo;÷ÅédÏ‚~è‘( j ÔgXÚN-^¯"ã[˜Çí‘î'§ uY“mÆÜdz)ge@÷sÔÄYØI¤CöÝŠ"(ó7!O4è~šºð”uË©ð¼?+ì÷e~p‚ö·õ§ï¡}Ý*ØmÓýlÛ±=:kÔ^égÄKìʺpƒ4Û5¢ÏõÏæsÀôÓðÅç25Ñ Õ{›'Ù¾Ô7ºþ þe8n%B%Ô ÕfÕœæáù<ÇöýDSšÜ‡P5HU|-ó»EezáCŠN£ôÕž?}\«¥ézêwBÞ†¡ÂeÚB±TX¿m9sI“”GYjrzDS(¤Â³©ÄB~
-µò[UP}0À<ôú¤
-endstream
+2988 0 obj
+<< /D [ 2956 0 R /XYZ 81.145 391.238 null ] >>
endobj
2989 0 obj
-<< /Type /Page /Contents 2990 0 R /Resources 2988 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2726 0 R >>
+<< /D [ 2956 0 R /XYZ 81.145 380.279 null ] >>
+endobj
+2990 0 obj
+<< /D [ 2956 0 R /XYZ 81.145 369.32 null ] >>
endobj
2991 0 obj
-<< /D [ 2989 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 2956 0 R /XYZ 79.37 332.652 null ] >>
endobj
2992 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 302.563 null ] >>
endobj
2993 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 291.604 null ] >>
endobj
2994 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 280.645 null ] >>
endobj
2995 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 269.686 null ] >>
endobj
2996 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 258.727 null ] >>
endobj
2997 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 247.768 null ] >>
endobj
2998 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 236.809 null ] >>
endobj
2999 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 225.851 null ] >>
endobj
3000 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 214.892 null ] >>
endobj
3001 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 670.199 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 203.933 null ] >>
endobj
3002 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 659.24 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 192.974 null ] >>
endobj
3003 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 648.281 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 182.015 null ] >>
endobj
3004 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 637.322 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 171.056 null ] >>
endobj
3005 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 626.364 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 160.097 null ] >>
endobj
3006 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 615.405 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 149.138 null ] >>
endobj
3007 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 604.446 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 138.179 null ] >>
endobj
3008 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 593.487 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 127.22 null ] >>
endobj
3009 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 582.528 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 116.261 null ] >>
endobj
3010 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 571.569 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 105.303 null ] >>
endobj
3011 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 560.61 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 94.344 null ] >>
endobj
3012 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 549.651 null ] >>
+<< /D [ 2956 0 R /XYZ 81.145 83.385 null ] >>
endobj
-3013 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 538.692 null ] >>
+2955 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R /F81 358 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-3014 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 527.733 null ] >>
+3016 0 obj
+<< /Filter /FlateDecode /Length 1720 >>
+stream
+xÚåZMã6 ½Ï¯ÈX®$R_À @2™èynE¯í©ÿÿº¢%Y–¬ì˜Ù.ÐbQLí8Îó#Å'zØÓß'•þÿÛËõãåëÝÆA Íéã¯}Ré?}
+¼Ó œ>}üsúãU)wUÊšt¤ôw9ÿùñû‹b°õõè :‡a‹£B@="uþb ¥3{á3Çg·ôçø˜‘7D?aihef,1cI”Ò#’uÌͦ3ý^ÏhB—2ÄšpÊ0cˆlp#Rò£‰  Ó#f+je¾ê‘¬•2ÑŒ±S&tŒ‰% íF¤Q¶DÒQåJŽ;>s:­eŠ6JÏ´”?óQ¿¥»¯±r`œ›®1Êìé‘g²«eíì=]˼iá®…t~IÇd“¹'ÉÊwk$›æ•kþýâ‡÷ìþßOé·.ækèË‘íZYq–heÕÏu¯‹Pù™{é]äÞ©qîÇÚ'J‘ Hqd‰¨”2–=Òÿ!~zŠ9€SçÖŠ|°õ@â"êœB=#â®2"=’¸ˆ:«¼™29Ø “+ Ù©Ïs{&(Ý¥qÆíh[®Üz$ùz™ÖÒ”I1é‘~å\Ôl´Óȳ²è‘2{ZEKÃZ;³Sº);™¸v‹g„«œ÷Ó¸D‘þ5ájƒ¯ÃŒáÑ®«xëG¤ÄPÈÄøÝ‚ÒûñÆšÉ @VY–£Vé‘£M¨é‘Ö›óÛ§ó&×tºÔƒYí°¸K*ƒsœ+WžZIš,N^ØÆr© µÚl5È̼u´SVoõH}e*Ù®úýgë4{àëݘSL–›ä°å>¦¼Ñ:9·ÕfsÏVbÀ×f;ÇÄÖ~v~^úkwkfS?-÷th.žÑ¼æh³”®ò‡FZ:(P4]ùcÊ$zˆ& 8¼ËêÏSXã TÖe½ð3¿Ô_"}'rì¹yËx³ i¶¦<ãΟ'q|Ÿð3­ÂÏk@ÿÄÖÅYŸ¶ùöqüQ]‰%æ׫>{ 9Þ.õ*çA®_#}°àñæýšs?㵋z®€—æ}
+Åmg¶îÉŠÁ,Š(çHfë…¸ã†S[ט<1áµÏú•y“f %¡‰a–6EsM›èqÞÐ¥·iÍ !q4`|œ?:âRˆdÕ÷¦mì¬æ?£wÈhÀy»:(j
+ÐMõÊQ%\Mê‘66ýè^cRS·ÕÁ…〴áXªŠA)·€ö£[ævTWn=RãÆkËq±U-.>»¯ep®WRû¼êÂüçãqa]íë‘oS”O×)¥{xtl?.®<êîʳGÚð|ï»8ûy=¿ç~Ã5té7×Ö¥¥(ŽykÁ:?³ç¨2®öôH}Ì ‘Ð"p*Lm¸Èlè‘úÚÂü˜sÝËàu²o¹d¥`u¿fGÏk›U×3~@L‡8ó
+s¨Gêùmc¯í0¤\M:Ì©ÕhŸE¬8_¥ ÓŽÇ÷ÓÕ5ªdMx@ÚD‹jYQ³£¤hS!_¥À÷3Ø•¯¬ÃH¾Xö¢·Z•„MˆúYìºì²; mº“+ûž¥åÈ~®3 9o Øiwvߩ爵ªr){ù²o_l‘NõŒóâ®S±jvÔiŸc¼ŸZüÞÅÆp·b?7­Ü…]v@šsŸÏZ¤œÉBô~ÆYØI¤MþÝ›"hó7)O´ tœò”uË©ñ|<+Üï(Úáñí»hßC÷•ªaË>f÷]Ù±=;k4†@MCWØ„{ £]#y\ÿj×Zé©Ëebb@ê÷®Î±C«ntûü« h2ÓŠ!SBRoaÕÌ< ¯ç5¶Ÿî$:jЧÜeªh@šhâ[›Þ-*cÓ ŸRt:(HE`×2µ4 m"CzS äí"7UBµ4 mx¿•¬¹ò,åYž6
+endstream
endobj
3015 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 516.775 null ] >>
-endobj
-3016 0 obj
-<< /D [ 2989 0 R /XYZ 79.37 480.107 null ] >>
+<< /Type /Page /Contents 3016 0 R /Resources 3014 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2711 0 R >>
endobj
3017 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 461.973 null ] >>
+<< /D [ 3015 0 R /XYZ 78.37 808.885 null ] >>
endobj
3018 0 obj
-<< /D [ 2989 0 R /XYZ 79.37 425.305 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 768.829 null ] >>
endobj
3019 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 407.171 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 757.87 null ] >>
endobj
3020 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 396.212 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 746.912 null ] >>
endobj
3021 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 385.253 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 735.953 null ] >>
endobj
3022 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 374.294 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 724.994 null ] >>
endobj
3023 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 363.335 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 714.035 null ] >>
endobj
3024 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 352.376 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 703.076 null ] >>
endobj
3025 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 341.417 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 692.117 null ] >>
endobj
3026 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 330.458 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 681.158 null ] >>
endobj
3027 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 319.499 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 670.199 null ] >>
endobj
3028 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 308.54 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 659.24 null ] >>
endobj
3029 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 297.582 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 648.281 null ] >>
endobj
3030 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 286.623 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 637.322 null ] >>
endobj
3031 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 275.664 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 626.364 null ] >>
endobj
3032 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 264.705 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 615.405 null ] >>
endobj
3033 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 253.746 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 604.446 null ] >>
endobj
3034 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 242.787 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 593.487 null ] >>
endobj
3035 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 231.828 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 582.528 null ] >>
endobj
3036 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 220.869 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 571.569 null ] >>
endobj
3037 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 209.91 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 560.61 null ] >>
endobj
3038 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 198.951 null ] >>
+<< /D [ 3015 0 R /XYZ 79.37 523.943 null ] >>
endobj
3039 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 187.992 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 505.808 null ] >>
endobj
3040 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 177.034 null ] >>
+<< /D [ 3015 0 R /XYZ 79.37 469.141 null ] >>
endobj
3041 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 166.075 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 451.006 null ] >>
endobj
3042 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 155.116 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 440.047 null ] >>
endobj
3043 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 144.157 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 429.088 null ] >>
endobj
3044 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 133.198 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 418.129 null ] >>
endobj
3045 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 122.239 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 407.171 null ] >>
endobj
3046 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 111.28 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 396.212 null ] >>
endobj
3047 0 obj
-<< /D [ 2989 0 R /XYZ 81.145 100.321 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 385.253 null ] >>
endobj
-2988 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F15 326 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-3050 0 obj
-<< /Filter /FlateDecode /Length 2712 >>
-stream
-xÚµ¹Žì¸1Ÿ¯Ð<š,ÞÀ Öôô›Ùžl±ÑÞÄ/°ÿ¾y•xˆ¢Ä8èéi‘,Ö}‘¢ËŸ ]~y[¿Þþòdr±Ä*Pbùúçsta‹¶„ëE+F¨bË×Ïå·wJ5»î¾9Ü~(®ÝŠú_”ÂJ)û Tÿñ£ÆZ7úŒ#Êâ?ß?õá÷GÂj7*¸‡‡Ÿl;&˜yÜï-Ùí„ÕŸì‡âR)*iå< i›
-}à hA/Dü>±Áà5UB•g$„NH˜›Ä Í3”mË
-D°®^ñ9Â+@€ìáÅšÍÏK‡âµÐ;¥LŽ+j¡†kƒãñr™¥TYF„ì’*>§Hm eZ½592úL.êeWêaÌRi(Z*%횢²†”©T¬Õd‡3Ë®·”RŒô‘®(É®ÖOÒèÂä¢G#êÿUkHµ$K¿èa_ð‹“tHC¤–=:Ô:GG © ãŸ „&Š©.^÷9¼jH³–rÐ_±®ˆ’ºG¿h!àìÉùä˜Ä
-Ô‰{Í7ÏSEE•lRzÞ{ûsÝDÉIV(N„îk¾œbE è˜ÞÉx95_Ë$fŠh Ê»,ÙaÁ¸¬“.)äY)ƒƒgr^)š˜xia„kÄn{k¸Æùžf^γ±´KÐV\…XÞ)”@"THÁÒó'®«J#d¬g%–r˜/–ô{ïI4¥XJ°Ò6õdÚh¤…21Õ·1›KÈ"øeΔ|)Üc8 hn 2'"bšÞ¤zÏõÚ½O"WY,…ãz•Ür­³ÉœVRŽræz Ê€ÕqÀ†s”÷#°&•åq$PI¯ ëVlÜ8iw;ª­"•‰bG‰I ¼+ŠÃÓT³ëHã4Vó>–ÖϪ^ϨÚsÇêM‡¦‹2É\Ê+ºyÈŪ½E èØ[KhR¬ [:}GÞî<Úb°mçå°Œ-oyب û<J'ýÔMR:M7åIõF=_XºùbÒžXÜ
-  £u#Á"÷LîÊ<ë[rä–cU׋ð)96O/‡œCF¼éÒEÂq4Ë«{Ã<÷p¼ÀÛ’RŒu õ)–ÙöF²
-k¹Ãêô;23”XÞM¯¶¦Qf5$YÔ™Øn.mj$—²Ô-ë~,ŸxªEN×õîHWpŸ²e ëü|ß(,}"Ò¹ÓƒI)W†êÝÑ•oÜ]MàQF5¤’–€ç#óxD;žQ_‰ØÔ(ãUÙT­sœkpü ã¹~žVã9¥ŸE?¼³óIYIK(³=YM( $ùÈݺ|¤1 /ɪì—Í-½ÐfÎä¡ñ€ÌÔv€õþá:ˆrlæNrY˜ò2HÉå«uSDKÝBš.8ׄQèbrŸÊœH™k/åÐûZu6³uUl“go=á^nÂuÎM1GÅ]Ô³ÜCx˜ñHFœÄWÜ{Dhãg> “MËØ[¤à=§¯™Ï$aFtçOj4€§©aŠF•ЗKBN]Åž»/Ñ@:Tçú¤>¨ð!]ß*ÁrJui›+8Hçeb<¨¨zu{-ËûJ‰†=‚¯Êró¹!=E7½Ç}Ö”À}qª»¦Ñk‚fN‡º©Ï\¶tlJþì3ç/›(J¸ÙåÜN7]H3æSÓò=“–ì] 'g2­©5ñ†§:ŒsÌ9ñüîò¼p˜sϳ>@¹N¥ëi§ëRM^ÖhÃÚ[gMÜšäƒt‹Ü¯ç§àOÇ4ôy5sBAÖZ9?çWEÓEÙ”k®Ê¥Z#µgkLΞøI-ÈŸÅ1­=w¨ Š:vRŠ ‰d]s¼šu¢kHûBŒñ×gó ck{¹Læ/ºˆwºùPI¤•ÝùSùZèüŠw
-Õ¹ëÓ.„IJö`¦“·
-N­£"]H ü·u–[bö—©=ÆWó3ĸ†THýÙoH¹°ñU/’Ð|¢|ƒ‡ƒ-ÞàÅídWhç ž´¦¼3æa´Há ¬ÓWQ€:[¥²ÅÒQ=¢ #à,¼Y•®£¥kJ¼»€HÎvû™œ®óu¼·0>“n
-2¹ öT¨æ½sn÷ÜDcŒ§|ȯò*žVÛý­íæYV¦ò×v‚óƒÏ¯·7Û'1j–?~¾ýö»{ü÷ùÕ™2·fùo˜øÓ…X™_ö¯åïoïÀ9Ì$±ZËÊ:{ÆœÝòª•{1Î;ðÅ%!š:xebÂ]
-çyå ‰‰²g{/º$£#ðæ>ærl»W»–¶ÐJ.Æß½å½Ýð«r=áÉfÙkÑ‹aa¨uN(µ Zÿ§ Áº,Õ"huJ'¶tÑy‡ÿ?)
-endstream
+3048 0 obj
+<< /D [ 3015 0 R /XYZ 81.145 374.294 null ] >>
endobj
3049 0 obj
-<< /Type /Page /Contents 3050 0 R /Resources 3048 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2726 0 R /Annots 3100 0 R >>
-endobj
-3100 0 obj
-[ 2987 0 R ]
+<< /D [ 3015 0 R /XYZ 81.145 363.335 null ] >>
endobj
-2987 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 236.441 745.828 246.868 758.348 ]/A << /S /GoTo /D (Hfootnote.41) >> >>
+3050 0 obj
+<< /D [ 3015 0 R /XYZ 81.145 352.376 null ] >>
endobj
3051 0 obj
-<< /D [ 3049 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 341.417 null ] >>
endobj
3052 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 743.055 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 330.458 null ] >>
endobj
3053 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 732.097 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 319.499 null ] >>
endobj
3054 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 721.138 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 308.54 null ] >>
endobj
3055 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 710.179 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 297.582 null ] >>
endobj
3056 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 699.22 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 286.623 null ] >>
endobj
3057 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 688.261 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 275.664 null ] >>
endobj
3058 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 677.302 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 264.705 null ] >>
endobj
3059 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 666.343 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 253.746 null ] >>
endobj
3060 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 655.384 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 242.787 null ] >>
endobj
3061 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 644.425 null ] >>
-endobj
-273 0 obj
-<< /D [ 3049 0 R /XYZ 79.37 607.769 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 231.828 null ] >>
endobj
3062 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 586.927 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 220.869 null ] >>
endobj
3063 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 571.245 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 209.91 null ] >>
endobj
3064 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 520.213 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 198.951 null ] >>
endobj
3065 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 509.254 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 187.992 null ] >>
endobj
3066 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 498.295 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 177.034 null ] >>
endobj
3067 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 487.336 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 166.075 null ] >>
endobj
3068 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 476.377 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 155.116 null ] >>
endobj
3069 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 465.418 null ] >>
+<< /D [ 3015 0 R /XYZ 81.145 144.157 null ] >>
endobj
-3070 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 454.459 null ] >>
+3014 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F15 326 0 R >> /ProcSet [ /PDF /Text ] >>
+endobj
+3072 0 obj
+<< /Filter /FlateDecode /Length 2574 >>
+stream
+xڵɎë¸ñÞ_áx YÅhh?·˜[’wÌ)Aæ’wH.ùýp+q1E‰îä ¶-Kµ/d5¿üqá—_Þn?Þþô0òâ˜Ó ååÇ?Þ„À/âbCs1Z0®ÅåÇÏËoô—H—þôŸÈ9‚¿nœKÿ)ïé¾´åwx߯¿ÿøÕ¿K¨Ñ»„‹²{›´jL¡ÐŽI G4b¦SÚÖÿqI_þòK V_4s­ªß h˜Œ²‘LMïÕþRÏâÝã¤bÖ<Q®lZÍTXïÿ Ê]$sV Ô,0ÒHÄÀ‚[u}t”Xy±ž¶Æã s`{DÒxb‚j½ñ#!/6åŧ‚hýoñÝÃÝ’8Ã}p×o
+”_r• ÔL(9bÝ)67 ƒ)´˜ оѥÔ*] ˜pjH—=Gr¯h×cò”dš´7@%“4ƒTè‰ø¤ofã
+²‰*›oq§ÉŠ:û¤
+²þç/ÓeÉEQŸÃìP'ëE‹h_!È=F3¿ÕEÌ’(îÉtYj ‚½ú4¥òU*:³±-r¨&»Ò<01íòÊ o1 {ñžÖ !øÀ3Öp.Øó†íF«b‚àõ›Â*#SŠ!œ*ƒ|Ò:Àë7°œD©¡Ffà
+æ}t'¹Ò5âˆh•{'2 >¾è–X D&B©šË¨*õÉÔr9ÙS2Œdn¨Š$a†_•&¡ø}(’T‰Øô6Z¯¡Ñ[éu6=#ÖáÍ–’³25ˆ¤ïh•éiÔ]|¹€lWV ;6ô¡Q»§7j*ë®*sì9±¹€W"ÝM%ļ´Þb öøK¦³²št¸•ŠÄ‹z³¡å¦Lìe’“]E‹Ñ~´ˆžÐXѶLþL²}Š ä‹Qî‡+i9½-y^pÊ61BÝþ…›‚)Ã\£‹ÍðÜcÕj/—DÜ"šdžÙÏݹlŠ
+.u¾&©ž“C¬R§|ĺ‰Ô_åÅXÿaF¼œ-¿ÁwïzL
+ë¤Ê&™¹æ¹œ?—.]»ëó5[?}ÿ}þTºöž‹|©eùk_C>W)èúÅ”Õ=¦B_[^„.B<Âsÿ$TZÁ~Lâ>J‰8±¹~W;eÈJ3ƒ# â„ôŒ1b²¨Ïq¢C4 Å**:TůàñzŒ@ɬ€!k1¢Å´#öyøZ|
+s/Ñr׿±q‘=½•w#œ€sygå1‡¥ÒPÀïE­ `ÖÉ¡ÖìšÖZLD+•ÉÔHÌøêaë– Û Ý_ëªÝµûÜ¥2 kƒWP­›Ùu¹GzG¨ ­¯é‘ æP £ˆZÓc‹‰è z(Ed¢{—/SU{0Ô_øº»Ï+úhWRɹ­‘=¥^ øÞLWqͽ´cÔž~Ag^9Ì=Ô™\ÒY‡IU&í6×>5ÓKÝëÖ?õO˜›‘ÃõUÃ;³zO½c ·uø°SXÇDâóÉud9ã ã#®é¨ÅTóé¼Ïx[¹\A»u¾ªwUÛçž°ÆÀ6À=‡©ã,Åá'?_Ô•vÌW£#]-v(&u/ÛuåDcÂ_ÖU½a¶[Ÿy‘ÏéÃÐù˜mý€þÝuôØÁ.JYYö\rÛó]ˆð5¾2-žåNɶÒqö´"Wͦ"±—êgK›Zm%³m©¸®ÆÞ6„GuIðªK©>™å\²›£ºCœßÓyŒ<È­ônÚ "ÿ>òÿAíµ¬ãpÚoa¤ãÜÞuð 
+Ÿ¥&xÙ} œ‰ƒšØÚŽk‡iÅ}Z^¾ä2ÎÒµñ³XÓt˜ºŒƒ¹ óʃ*N:¾; ŠJ•çÑ.@½Nçé´Ãu¹#¯;´içmŠ-n{ä“tËݯW§ -SÏcê|áDŠlõ"K«áè¤fê5gµÒ¬Q¹³=ZcKõ„} >ª3ZwP)T=ì¢Ñ0¥`¤Ä³U')±ÅôÜ?È9Ýó¾àžö¬—å$ãySGÒÖk Ó(‡ðKõZ‡èx%¸8•ng0Fãjë ˆ‡©a5bj±~ë1µ r*ᡇTÙ%ª:L³ñÀUýGh Gæ Öhl1UcµMÒhØGj…Ì8;¤^®QßbªÆçJ¹u'Ym™×ÛºÛöàQ]›EX!BsfÑ ít­|ë0µv*óDJ¬â¿l·Ò1;TüÙ
+HnUzŒ· ”ÚRØ|ÒK '¾ ¼q3ƒq@âøSÞ ”Õh2ÄÉ^ G¥Bi[SLE8ê¡¢iÀŠö0û?àÞ[}/×Q鹞qB0¶_•§Ñò”W0…âé}¶ìx›¿;Œ€b ™ÃjzÍÜ«™¯Fv›D9½]¶<yú ÓX[éÒCžKëº(þ^œvÛÃoöóËB:-/HŠÌC<4}œÚÝ'ƒh ÞûÉ«žÄ3zßÚÏŠ1Õó[ÛùEJ[Ÿ?ÞþÕ½Æy/ò†ñ·Ÿo¿ýîoÿÝ_¿zGFRÿúëS«ËþyùëÛŸóÿI‰‹bÎÕ8§õ÷„·[d¼:Ü.“K>6àÅ—!†{|ui’ÒdŽ­6ÅÏÒç5)Çë yq—oR›™Hm[3Én5$ ¥‘ž‚ÿ{jK@ðí½ì^âÙJf¾í€ÚuË(±s4÷™DÑHh4÷™µ‹zçH0 æ½F”œ!æ‰Ç ÓG7÷¤.ÚùK¿êmág«yÅÌÙ£‹®Ù(¼µvË™)'ÛXí­öÅHV1aôRÖc»ñWzâͳoÕæXJ S« §\ÜudýŸþ¯0ìji¥/2œ~– ,·Ìë£Ã´-©Õ
+endstream
endobj
3071 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 443.5 null ] >>
+<< /Type /Page /Contents 3072 0 R /Resources 3070 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2711 0 R /Annots 3122 0 R >>
endobj
-3072 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 432.541 null ] >>
+3122 0 obj
+[ 3013 0 R ]
+endobj
+3013 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 236.441 757.783 246.868 770.303 ]/A << /S /GoTo /D (Hfootnote.41) >> >>
endobj
3073 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 421.582 null ] >>
+<< /D [ 3071 0 R /XYZ 78.37 808.885 null ] >>
endobj
3074 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 410.624 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 754.882 null ] >>
endobj
3075 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 399.665 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 743.923 null ] >>
endobj
3076 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 388.706 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 732.964 null ] >>
endobj
3077 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 377.747 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 722.005 null ] >>
endobj
3078 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 366.788 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 711.046 null ] >>
endobj
3079 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 355.829 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 700.087 null ] >>
endobj
3080 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 344.87 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 689.128 null ] >>
endobj
3081 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 333.911 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 678.169 null ] >>
endobj
3082 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 322.952 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 667.21 null ] >>
endobj
3083 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 311.993 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 656.252 null ] >>
+endobj
+273 0 obj
+<< /D [ 3071 0 R /XYZ 79.37 618.84 null ] >>
endobj
3084 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 301.034 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 597.997 null ] >>
endobj
3085 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 290.076 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 582.057 null ] >>
endobj
3086 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 279.117 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 530.252 null ] >>
endobj
3087 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 268.158 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 519.293 null ] >>
endobj
3088 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 257.199 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 508.334 null ] >>
endobj
3089 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 246.24 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 497.375 null ] >>
endobj
3090 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 235.281 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 486.416 null ] >>
endobj
3091 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 224.322 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 475.457 null ] >>
endobj
3092 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 213.363 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 464.498 null ] >>
endobj
3093 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 202.404 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 453.539 null ] >>
endobj
3094 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 191.445 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 442.58 null ] >>
endobj
3095 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 180.487 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 431.621 null ] >>
endobj
3096 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 169.528 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 420.662 null ] >>
endobj
3097 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 158.569 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 409.704 null ] >>
endobj
3098 0 obj
-<< /D [ 3049 0 R /XYZ 81.145 147.61 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 398.745 null ] >>
endobj
3099 0 obj
-<< /D [ 3049 0 R /XYZ 93.716 89.795 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 387.786 null ] >>
endobj
-3048 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F16 328 0 R /F59 338 0 R /F84 404 0 R /F22 357 0 R /F81 366 0 R /F83 403 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
+3100 0 obj
+<< /D [ 3071 0 R /XYZ 81.145 376.827 null ] >>
endobj
-3103 0 obj
-<< /Filter /FlateDecode /Length 1910 >>
-stream
-xÚÍZÉŽã6½÷WøÂ!YÅ h°Ûö
-"Xmñôù盢ò¤N.p'g•V>ÿ>ýþ.¥õRƒ.}þ Ð8)’}¾Œ:kGãNÓïxÝhÎõüÇ篴“n'…Z
-IB¾èâ#­§Õ鲧¢wª?~û¹eiRÚåü¸c>?;½U/b”
-¤©|ÚJ¹²Qé§5ºd¡}GÙ1ŽÐ)¡P±ù#IÔ
-Õ¡Êkö@˜CJ™ÕꤵhU–°vUEZ­ˆMÐzkÍuoâÌ3}åOLfReml”Jð€z)ƒ`ÏÌÎÔ±ªgTûbóϵ,Ÿ ¯v¶ñVk·„ý%û}‘Rª@{’w[pHs Tÿ@nZÃ¥ˆéÚÖUS+Æ÷lÓ=Wñ=‚Ø·£PÔA³Qè×,8îÓ›Qj[É3è÷¶/WøÏZù=6´úœú"ú½g£$Üê…°­ŒdSŽeD±Ÿh½ém€ã)õß³Vs­c¬7œññJ@\æºi¯§QI#WúØmÃhè&–n™2£dÝ'
-’JWͨѪXLïÇJèUŒÏN3q
-jz0Ì‚t©ïæ=·E‡kó›ŸA¡ä‚n§ÎÉøãnÈ~öÍo°;rîÒ\Ѽk¼ÙhÔ",`;­+Ÿ©‚RG„JpíoôݳÌÒøɵ°Ã+hj€Ûĸî”×õ
-*"»0$Ayªôggt]uSûó€3‘H9ý—àî¹ú’ÎÆ÷³ '®Üû}±I©ÇÃÞâº4)¤W›”ë<þPûHÓ̓æøÜ[k%p‰4/0­Í׶ãÝâ/íM<(‹ÖÂv«âir¯[7Lê¼]µ·Ñ›7
-àh”Ö\½V[;äkQÙéK¢Ò>¨
-9>`þg2e>’Ï5¬G9V”@ë.eìûÿ Dg°¬2Í13Gú¿¹ª((»eùÜùaÁzahh@Zº-_èaiå„tž5.8Fßé¿wqCÖ*G'ü“œaØp!_ÑÕÒ
-¥§±½ß<ªÆæH«ýÑ&¹c”ª`„b>ªÁþ¯ÅaHOBÊjª¿ñ{Bò¿É7ÁÝ?ßþ&åÌ
-endstream
+3101 0 obj
+<< /D [ 3071 0 R /XYZ 81.145 365.868 null ] >>
endobj
3102 0 obj
-<< /Type /Page /Contents 3103 0 R /Resources 3101 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2726 0 R >>
+<< /D [ 3071 0 R /XYZ 81.145 354.909 null ] >>
+endobj
+3103 0 obj
+<< /D [ 3071 0 R /XYZ 81.145 343.95 null ] >>
endobj
3104 0 obj
-<< /D [ 3102 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 332.991 null ] >>
endobj
3105 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 730.971 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 322.032 null ] >>
endobj
3106 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 720.012 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 311.073 null ] >>
endobj
3107 0 obj
-<< /D [ 3102 0 R /XYZ 79.37 673.39 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 300.115 null ] >>
endobj
3108 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 655.255 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 289.156 null ] >>
endobj
3109 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 644.296 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 278.197 null ] >>
endobj
3110 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 633.337 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 267.238 null ] >>
endobj
3111 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 622.379 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 256.279 null ] >>
endobj
3112 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 611.42 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 245.32 null ] >>
endobj
3113 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 600.461 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 234.361 null ] >>
endobj
3114 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 589.502 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 223.402 null ] >>
endobj
3115 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 578.543 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 212.443 null ] >>
endobj
3116 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 567.584 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 201.484 null ] >>
endobj
3117 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 556.625 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 190.525 null ] >>
endobj
3118 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 545.666 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 179.567 null ] >>
endobj
3119 0 obj
-<< /D [ 3102 0 R /XYZ 79.37 497.043 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 168.608 null ] >>
endobj
3120 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 478.909 null ] >>
+<< /D [ 3071 0 R /XYZ 81.145 157.649 null ] >>
endobj
3121 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 467.95 null ] >>
+<< /D [ 3071 0 R /XYZ 93.716 99.705 null ] >>
endobj
-3122 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 452.01 null ] >>
+3070 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F74 329 0 R /F15 326 0 R /F16 328 0 R /F59 338 0 R /F84 404 0 R /F22 357 0 R /F81 358 0 R /F83 403 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-3123 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 436.07 null ] >>
+3125 0 obj
+<< /Filter /FlateDecode /Length 1907 >>
+stream
+xÚÍYÉŽã6½÷WøÂ!YÅ h°Ûö
+Ò{&ñ<¯JÝݪijŽÚŠFÉ"D¦ÑyˆÌC]XÔ×¼<FR³Ð¦­l™7|f¯SË¢åB*Ÿ¢: âߟ "Y™0¬_=¤{ Örf
+yfžßEÕÇç–äÒŒóœÔ‘t(où>)fYbyj €ÁEž“ì&oê«•ö`Sj–çØf¼úŠ'hQýÛCë ÑP~Œ€l}àaÊaJ6ÕŤüŒÂô¤/ý½E'Ð;ÎßÛë‘À5)Žð—Ã’Šþ´ GæåPXœêÓ×Fw—0²Aç/¬Î¬Žõá ß”¢8¾a_^¡´¥ GHæ2 ¨˜ÍaúŠ®¾íÉóÇÈ›µ Ü¤nÝ­u”gCûA$kX&¬ÙÇAŒH&<K-6­Hµ”¡­Èg “?`U&ÐOÐ,ǸcGi*ùô)Ùë“1V“jf{–¥^g>c¹ã 8×Û,Á ýú(‹”,n¼G½þ>žú­õðX¬·Gåí•pÀV
+Y‹Vei
+´ y·e©`”êÈMk¸1][úŠ`jÅøžmú ÇÕplÏŸ öí¨uÐlú5 Žûôf”ÚVò ú½íËþ³Ö_~ ­Þ§¾ˆ~ïÙ( ·z!ìE+#Ù”cgQìg
+šà61®;åu½‚ŠÈ.ÌIPž*ýÙ]WÝÔþ<àL$RNϦpÈ—Ìp6¾Ÿ]8qåÞï‹MJ@¸ÀÆÓ½ÅuiRH¯6)×yü¡ö‘¦‹Ìïû a­.‘榵ùÚv¼[<â¥}¢‰eÑZØnU<­q@îuë†I·ë¡ö6zóFÒš‚«wÀikoc€|-*;"}IT:À•aA!ÇGi ó‘|®1ìüCEù
+endstream
endobj
3124 0 obj
-<< /D [ 3102 0 R /XYZ 79.37 397.41 null ] >>
-endobj
-3125 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 379.275 null ] >>
+<< /Type /Page /Contents 3125 0 R /Resources 3123 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2711 0 R >>
endobj
3126 0 obj
-<< /D [ 3102 0 R /XYZ 79.37 342.608 null ] >>
+<< /D [ 3124 0 R /XYZ 78.37 808.885 null ] >>
endobj
3127 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 312.518 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 730.971 null ] >>
endobj
3128 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 301.559 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 720.012 null ] >>
endobj
3129 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 290.6 null ] >>
+<< /D [ 3124 0 R /XYZ 79.37 673.39 null ] >>
endobj
3130 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 279.641 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 655.255 null ] >>
endobj
3131 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 268.682 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 644.296 null ] >>
endobj
3132 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 257.724 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 633.337 null ] >>
endobj
3133 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 246.765 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 622.379 null ] >>
endobj
3134 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 235.806 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 611.42 null ] >>
endobj
3135 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 224.847 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 600.461 null ] >>
endobj
3136 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 213.888 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 589.502 null ] >>
endobj
3137 0 obj
-<< /D [ 3102 0 R /XYZ 81.145 202.929 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 578.543 null ] >>
endobj
-3101 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F83 403 0 R /F74 329 0 R /F65 327 0 R /F75 330 0 R /F59 338 0 R /F84 404 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
+3138 0 obj
+<< /D [ 3124 0 R /XYZ 81.145 567.584 null ] >>
endobj
-3141 0 obj
-<< /Filter /FlateDecode /Length 2229 >>
-stream
-xÚÝ[ÉŽ7½ÏWô˜&‹;0 Mk ø–dn†O âK|H.ùý°¸4—¦4]2rñA–†jU¿"‹¯^Û|ù¶ðåÓÓåíéã+Àâ™7`Ôòöç“_ðE,Ö3ikãF,oß—/Ïœǹ| /8}N†uá\¼„w¯uµœk®áu.£GÈáeÄø=—í­a4Ø6kú?׫à|úúö9`z†ŒgÖ™½4 gxãÒÝ1Ë9õM„Zœ>€{NîhU¾‚—‹3óþý j¿(æÐBtÀf«,BnÓ{I/¦NC²•Wêã«S‹ ®éZ;Þ2n4”0@Åwú Aã7çÞ§4*¸4Lh5n.‡€ É™³~g pBFÈkž0Škù¤·1à›_¼NÙq/@3áõÔ‹ó1/@0µ·¤}ÁuÄë÷þàÎÑwÕ'¡H3óIzšO½¥Æ'±ó‰ˆ‘KÖM1:ÆÞRƒ1óH"6ãIá§1¡IØK®-ÆEÙ8—5.Þ»®îáÄXTÿœ`óð0Šæ^g¨¢†sâdOuɈׄóBDîÒ¸%¯ŽåLq1Iƒß[jðCÂY2㋈S{¦Ìpª+ go©ÁyÍØ|zÇ(Ù>¿îסdUüÎPw¬QŽ)·KTêÙ‹äOo©úƒz3³ÌŒ‰ŸS£b•–iP3¬“ꆵ·t$Æ÷»XeÕSÍßýôÑ3?æàâgoic¨'¢b ¯…ÐÌp3ÅHË°ƒ¥&nxeFŒ™ÂŒYiñrÞì /1{–úì‰ø«‚DœÚKfœŸâ¤eÐÁÒ°×Ì—âS‡7;¥ b"í í£ë
-Ôö=Ú4»içQ‘[Á¬Sè´$9XšcGF(uO¬K¨ì¬MÐÒ¦Ñ@ËŠƒ¥^OY3j•ªWµÞ>·O¸¸;×½æÍz}Ç–m¹»f™»k&Ì5ÕWYcïY»Çg¨+¢<szüÄü?XjꬡªX(|‡ùýÞêü,ó+s¾ÏñgÔ"d=2Xêu`œ…ìea”Z5ÿÌó –y©góKÔPƒ¥¡HZ´«2#*xPwka˜·f†›¨‰K î—¼z¨åä£8¹a\Ø)Nš.,UœVtœp¯_–z}Ê Ækž•×ª©bM±uÀ,œbó«í”¥œ—ÔYÛ¾Y3Šm$jûªw?¾Z5Ã$gÞûÕ¤³u·È-Zì|ÓÄõR6Øi\Ô…¹Q7ꥸ¹‚kèâ5¹ß}Ó¦»ÛÆëZJ\s°…Ž§Ô¦EÚ0æ¹Yúm²s+1}›¦Ip—ÑR:‡² ìslP„oôsCek{̓ÎfýÎÛ§KÓx…÷Ë_…KŸ·^‡y²ðyud6Ú„BLÉ‹ênùâþF™9ˆÚê89xÞÚy.š[Fãñ&u_m7Ï—‹—Ñ7UYçÖÊ‹òT
-á÷ ÒË\+ƒaeZÇûÅÚZÛ·JÁ„RÃÝ„x¹¿ÇMêm¼ƒ±dˆØ¹¸-YýçÛ’>üŠ{Q˜i\:ݱB¨ëÎ̹ÊÂ牾¿Á+J3gwȵ£ò
-(&aªcÖq…WzC#¯ á»¼B„-$“f*ŽÖv˜%.}o K¡F‘išS|žþéXb°Ô¼úZveQip­D»U$Ñæ@†T§ÔTZ-ó –ª/óioÉDæÖ—åõð­´ÃÆö0¹ð•A$(çf¾-³Š¯½¥æ`ÉF®/«tÍôô0¢ ª—&5øÑKÔ
-G‹âeo©z¹/[’@/´Û®Ri°5í•[úƒà£vLÛ™‹Gëâbg¨_ÇJ‹ˆZYf„˜Á&ƒ–~ð`SJÃŒ†)®3 Wo‰º/ÞOÝìÐÌì‹ôŽØ¤,å2ùþ#àsrÛCñXÁe."øœçó§%=Ý7ãù³_0¨k¦DASƒ¡Û`±~§íÚÄJqõý¶U͵jmsÌÃÍ Ð&pû|—jÒ´ †x=‹- ×ŒJRÃ|«”,×£¡~"ÓÅ—I{™PA=(‰Üž&peT> Åëo¯XxÙlÓ?Àž ÓFNÃU’\ï 5¢ë¼ªØm¿üÌÌð)•&d©04X‚ ^‡úd; äHø¶õø~Tf¯zKÇH¢•ØÛ,ìÇbU<x}cO6â}ö– |M¨ž%î‘Íî(Uט™RVMƒÔ5á‚gfkrTiÏÈÑ™D…çÌ‚!!JÁIÈÃÖ¸)’3…6C7µÍšyÎÆz6l Çý ,­q8"ê~£OÈð•ØU¢}žqòÜcÇ8¹³›÷¬]k¹gÞé
-ݶüdÛmKCéA­’uZ`ØOË?»ÔÊ£ôÞ°·Ø;¡EmùÕße¢Ù)“׿;°¯ƒz7Ç®g2s¹‰•rº»5íc¤ñþf›¶{­²P‡3Ù°”›ÝѱŸÑ¹·EsÍÀÊ}jCK@a=w’ Ýy¢•”É­.!æLCks5VŠ´ŠyÈø`šu²ÿª†^ôtŸ Æ x·¹”súõíéï.|(pœ_~ÿþôåkþ#¼>‡¹’Þ-ÿÆ ¿êT±\åË_ËoO¿¤Ém#æ­Õݸ0&Âä¸@¹nÒj Ó/—°æ–cùÛÄdVü9T)¡ËB—Åå$y&•ø¡Ì¦2v²Y•q=ãå-7 ðÙ ?"x°9}ËKÀ$ÆNw<OóÃyšÚÎ*²£Å¨Í³p)w‡KÑ÷e*ºÚÈt­t™Œõ?<]3`°Ï­¡TÉ¥ +•kÊCˆQ|™ä`¿\å,(ýÕÖõ:×ðköìu<*oݘ,øð_4³µ¦+
-endstream
+3139 0 obj
+<< /D [ 3124 0 R /XYZ 81.145 556.625 null ] >>
endobj
3140 0 obj
-<< /Type /Page /Contents 3141 0 R /Resources 3139 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 2726 0 R /Annots 3191 0 R >>
+<< /D [ 3124 0 R /XYZ 81.145 545.666 null ] >>
endobj
-3191 0 obj
-[ 3138 0 R ]
-endobj
-3138 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 236.441 434.994 246.868 447.597 ]/A << /S /GoTo /D (Hfootnote.42) >> >>
+3141 0 obj
+<< /D [ 3124 0 R /XYZ 79.37 497.043 null ] >>
endobj
3142 0 obj
-<< /D [ 3140 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 478.909 null ] >>
endobj
3143 0 obj
-<< /D [ 3140 0 R /XYZ 79.37 773.016 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 467.95 null ] >>
endobj
3144 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 754.882 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 452.01 null ] >>
endobj
3145 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 743.923 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 436.07 null ] >>
endobj
3146 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 732.964 null ] >>
+<< /D [ 3124 0 R /XYZ 79.37 397.41 null ] >>
endobj
3147 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 722.005 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 379.275 null ] >>
endobj
3148 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 711.046 null ] >>
+<< /D [ 3124 0 R /XYZ 79.37 342.608 null ] >>
endobj
3149 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 700.087 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 312.518 null ] >>
endobj
3150 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 689.128 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 301.559 null ] >>
endobj
3151 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 678.169 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 290.6 null ] >>
endobj
3152 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 667.21 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 279.641 null ] >>
endobj
3153 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 656.252 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 268.682 null ] >>
endobj
3154 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 645.293 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 257.724 null ] >>
endobj
3155 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 634.334 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 246.765 null ] >>
endobj
3156 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 623.375 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 235.806 null ] >>
endobj
3157 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 612.416 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 224.847 null ] >>
endobj
3158 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 601.457 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 213.888 null ] >>
endobj
3159 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 590.498 null ] >>
+<< /D [ 3124 0 R /XYZ 81.145 202.929 null ] >>
endobj
-3160 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 579.539 null ] >>
+3123 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F83 403 0 R /F74 329 0 R /F65 327 0 R /F75 330 0 R /F59 338 0 R /F84 404 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-3161 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 568.58 null ] >>
+3163 0 obj
+<< /Filter /FlateDecode /Length 2230 >>
+stream
+xÚÝ[ÉŽÜ6½ÏWèL“Å Ð==cÀ·$s3|J_âCrÉï‡ÅE\»GÕF.>ÈÒPêÒ+²øøª(óíÛÆ·Oç·‡¯
+ßáú~kt~–þ•Ž9¯–3”¦GK½Œ½½,ŒR³æŸ¹Á2/—Ú‚¨¡K B‘´h—dFTp§îÖÂ0o'½g¢&,5¸Ÿóè¡–“÷âä†qaW8‰ºh°TqZÑq­zYªõ)/¯ë¬|©š*æ{ÌÂS,~µ•²Ô‚ý’*kûKF±·Dm_õîÇW«V˜„ãÌ{?¢ZT¶nV¹eB‹É7M/eƒXÆÕA]˜ uƒ¡¾Pš& ‹/ÉÅxöM™îf¯+)pÍÀ:V<¥2-Ò†1ÍÐïK‰én.˜&Á]ZKêÒ6°±@îèdžÊ.í;v:›õ>œö«sSx…÷Ë_…K·>‡ëdáóêÈl´1…˜’Õ?œòÅ?ü2kµÔñäàq/wä¾h^Ç—Ôyµ¿<?.žGßTek3(rXß *P¿‘óR 3Ó28ØÞÖ^Ú¾PÂ&”Þ&Äóí9nRmãŒe…ˆ•‹ëØ’Õ¾méâWœ‹ÂlHãÒéŽB^¯°o”`ÎU>-ÔÙ^Qš9;!׎Ê+ ˜œkéLâ•ÞÐÈ+hð&¯a Éä\zÀóÑÜ.³Ä¡ï-a*ÔÈ!2Ms`Š/iúhâ–·%KÀ»³ ¯e—•×¥‘h×’$ZÈ°Ô)µ”G“Á܃¥ê˺DZÛ[2‘¹ôeyÝ|+å°±<LN|e ʹ¥¯Šæko©ÙX²‘ëË(½dzº›FÑÕË@“ü2ª%ÍËÞRõrN[’@/´ÛŽR)°5å•kúƒà£vL/ƒöh¾Q\ì õãx@iQ+ËŒ˜
+E©ÜLƒÝ[úÁM) 3V¸Ž¦Wo‰:/Þ_ºï™ ™™“ÿ0¤äi°”ÓäÛŸD€SÌÉ}á^½v¹o]\ÿ>çùúk‰C_7ÄÉxºcï ê¿ì’š ]ÿœ
+Ï™…I¡Iú_ƒ%:’°[ãVHŽŠ›Dƒ¡«Úæ’yÎÆ|6L Çý
+,­p8"êv¡OÈpKìŽ*Ñ~ϸøî±cœ\ÙÍsÖ^jºgÞ©
+Õ¶ü‘d[mKMéC­²ê´À°ž–v®™G©½am±wB‹Zò«¿ËD³;R:¯Ù~/v`΃z7Ǫgí2s¹‰™rz»5íg¤ñýfï¶[¥²‡3Ù0”›ÝÖ±_ѹ×EsÍÀÊÉ>µ % „°^Ç;I‚†n|ÑJZÉ¥.!–LC,s5VŠ´ŠëñÁrÕÉþ«zÑÓËz_0ŻťÌÚ/otáC‚ãüöû÷‡/_CóáøúJz·ýü¨SÅt•om¿=ü’>$·!Œ˜·Vw]àB›ãåºE©5t¿Ü˜[Žéo’YaðçP¥„.]jç'É3©Ä‹Ò›ÊØÅdUÆõŒ—§Ü€Ào7üˆàÎâô5/A“;ÝKp?Íûijß«ÈŽw¢6ÏÂ¥¼ÎEß—®èzh'ÓK¥Ëd¬ÿÑÈà陃}l ¥L.=˜X©<S>BŒâË$ûá*{Aé¯6ϨϹ†_³g¯ãVyëÆbÀ‡ÿâ ™­9]X²óZ¢L)_« OÚòW·ŠÆ–}ᙾ¿¼uŽ3ÖùÖÿ´m>pœ6›âÈ>9¥Ü•T`‡ÿ
+endstream
endobj
3162 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 557.621 null ] >>
+<< /Type /Page /Contents 3163 0 R /Resources 3161 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3213 0 R /Annots 3214 0 R >>
endobj
-3163 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 546.662 null ] >>
+3214 0 obj
+[ 3160 0 R ]
+endobj
+3160 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 236.441 434.994 246.868 447.597 ]/A << /S /GoTo /D (Hfootnote.42) >> >>
endobj
3164 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 535.704 null ] >>
+<< /D [ 3162 0 R /XYZ 78.37 808.885 null ] >>
endobj
3165 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 524.745 null ] >>
+<< /D [ 3162 0 R /XYZ 79.37 773.016 null ] >>
endobj
3166 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 513.786 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 754.882 null ] >>
endobj
3167 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 484.894 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 743.923 null ] >>
endobj
3168 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 432.092 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 732.964 null ] >>
endobj
3169 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 421.133 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 722.005 null ] >>
endobj
3170 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 410.174 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 711.046 null ] >>
endobj
3171 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 399.215 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 700.087 null ] >>
endobj
3172 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 388.256 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 689.128 null ] >>
endobj
3173 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 377.298 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 678.169 null ] >>
endobj
3174 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 366.339 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 667.21 null ] >>
endobj
3175 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 355.38 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 656.252 null ] >>
endobj
3176 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 344.421 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 645.293 null ] >>
endobj
3177 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 333.462 null ] >>
-endobj
-277 0 obj
-<< /D [ 3140 0 R /XYZ 79.37 296.05 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 634.334 null ] >>
endobj
3178 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 275.208 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 623.375 null ] >>
endobj
3179 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 264.249 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 612.416 null ] >>
endobj
3180 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 253.29 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 601.457 null ] >>
endobj
3181 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 242.331 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 590.498 null ] >>
endobj
3182 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 231.372 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 579.539 null ] >>
endobj
3183 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 220.413 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 568.58 null ] >>
endobj
3184 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 209.455 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 557.621 null ] >>
endobj
3185 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 198.496 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 546.662 null ] >>
endobj
3186 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 187.537 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 535.704 null ] >>
endobj
3187 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 176.578 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 524.745 null ] >>
endobj
3188 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 136.727 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 513.786 null ] >>
endobj
3189 0 obj
-<< /D [ 3140 0 R /XYZ 81.145 125.768 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 484.894 null ] >>
endobj
3190 0 obj
-<< /D [ 3140 0 R /XYZ 93.716 94.71 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 432.092 null ] >>
endobj
-3139 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F15 326 0 R /F59 338 0 R /F84 404 0 R /F74 329 0 R /F16 328 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
+3191 0 obj
+<< /D [ 3162 0 R /XYZ 81.145 421.133 null ] >>
endobj
-3194 0 obj
-<< /Filter /FlateDecode /Length 2519 >>
-stream
-xÚÝ[Énä¼¾û)ú†CVq ÝîV€œ} rMNyÿk¸o¢(Ñcà~ zì‹‹µ—HS"nÿ½Qûÿ?Þ_o¿7anœÍn_ÿyc7jÿ±›"ùMIF¨d·¯ÿÝþõN©|ØÏ=þäÿþúçu`ê÷¦ùM#%ê‡QEC$ÌÇ/Âýö²Ÿ§û™ž
-gö ºD$KÉ6Y¯®Þæ)鞊÷Àq@Jt!ìí£›Q;’ö® Ož/ÝïÌI?‚ 'ê¼ã¸OóL»ànMö¡¡YSÅÝ{ ½“q¿Ç]lMü š¶Af·­µlE‹@+nN B˜tVÈú{§.È)“¸YÞê€7ÈqÔ8};:ÏIeŽ1ű)—¸wH6ÐTX¹<ÁøÄsþës‡.à±hŸì®¶ÁÈÑs¤c¥íR'@±>¿W£Wöê©wVgŒ“¹ ¯Å%£¡!†e`Ë‹C 0~N(
-2T
-8Q–z1—K!j”Ëåc¥(逎‹’¹'”ü–ľ/ rÄmÇåêÖ9'ÜèáÖïKeL‡t¼÷”Ë
-׶øJ¥K©eÕêN‰@3Ú šµ´HNWm±(_u‘Uv–ܺ|Kµ>¯âûeM&IlÁ{éÙfÃ@’>Ó`e¥ËÈyc[•.
-_œÐ\Æû<çÏçç“q¸Ó
-ð£í9ßMt|"¬ôy‚ KnE\8Á>Sm÷8'1!ÑJVhwjÑë(« Ý.Ž,ªí5Cuß—ÔÝyö.zIòŽ²gtK̽(ÓÝ£ˆf˜÷¢’³xã÷@Oð>c,:I)^.ŸóñI-ª1Ò,®%á§f.…«™í{mè¢_bL3!'?J†3 {ú)ŽµÜ-¾Îó­_o‹ÃóaâYT®Õ1l¨]½¤ÝȳÙuê8³Óváu-§:SÈåÔgÉvGô¾´¹ êš.åømŠ Ê´EáÛ:™" ƒ¦X«´[¤å^F¨Â!'£vȶ-„1>4›¥v¨ºÞ¹wLé5ª›U¿býÑvˆKC˜6!‹íP‡´Üq¡ 3ûšY¯¶CPn¶y)“êää׳0X×à>t½J8Ì5ùë#Å:äÍè}ٮǑzNò÷´7ù:ÁYTWPÔ·Öòt@©"®Ùt¬ûê7fX~E|c×Ùu%‘ÃTìBµªJæJeÔ¬|òkãœæ´¬L¦
-ËÓ2Lý¡ZQPf¤ÖµF§JÅLêb¹˜=µgÎ^ä¦á‚Z|_øŠ™Ô#Š‹Oš;ÅOÍž›“¥ãŽt‹ŠAÉV/¼Xq¼Š¹v~žmf”$¢ó1K˜«q4×î–pÃûÙù~‹K‰ˆ ø”Íëz‡ÀêÓÏ’<Ý›õp’7ÝS6@º?’ÓÇÁvTíΛôêÁ¬ÑÍ –"¦YþÅüVŸ}¥¢œ²¥ëCáˆrŒi–+Ust|Œ8¬gò…ƒÁÙ›"¼z~r”ë¹A¬åå¿Õ—)ÜqoxÊšN³ÑdÙÐ4´&TbÏ?Lf¹ú:2, Âz¯èg÷6¤“ …Ô² ÜN;G{ßͬN;+š9ÓD­—ÃøƒK­: ã’yæ岧÷•u}"öG"~CkGPÜgr°²—rV'W‹l”‚·iB¬íªEb•Á‰ÐbÈÉÅÛ•L%Ttí¬[ˆhèËäH$È¡]\ë ZÉiÙ#}ï|,œÍ¦»8’¶÷q„qYµ¾ÒWdPŸéú°LësÝDâø¥“ºú¾Y¬w¾}߬Yú Õõy•‚ ‰Ô9²ˆäoÂìÂnÌÏ~Óešð-ß:êiš[p!<§K7^dP¶Z¢o½¼ÏÐáÛøØz–©@¶Ût´¢9¨–+ƒ©Ñf/4Ø#*‹ ëÚâù'Y„)¢`t¯¾HÎÕ!5Ù²ùL¯”Ë!¾tNÂÃÇôÉDsÂÂwç)“º9þ5ü»€
-4US ¾Ý©!µáPî¶Åõ÷'ÆvjJôHEI¿É)ü¾x°ßÚµ]Ài«š˜Ä«{]ãª#ÕQE[%íAuQãäFMåH^W_XDyuHݨðit¼È©æDs5âôj½¢CJ}Cº»WBìq"š¿™ü‘D´(…Dk=”ÎÅÎWÛðá鯋Ÿm…ïý Žåþ£q$ØBÜŒäy±’&ˆd¬Gú»ÆÁˆ:çÅ>!‹«úù(¡Œ ýD¬ùI‹4Ž"•Ÿ¸÷©eJïD~Ö?›!†räk
-o‘þ®þÁ ¡‡‚kòj‘~ÞC¨& ùˆÓ«ÕgòéÛ÷8™Q„©}Mǯ×t1ówHßçHKßW 8º|ÌÚöéû)A`pW˜_¯Žâ+)ÿ)ÀqSɸ&(ÌàÕ÷/Ôø~\ ÉL‘ßÚiÜ·´ r@Nø ¾óËuP|×M­ÙhkûÃé£?1Ïቫþý³×ÁyO{4úëÙÑß¼â1Æü¯_«F3§¯m» …¼qjÓ|¶2Äì9¯¯·ÿyfÜ
-endstream
+3192 0 obj
+<< /D [ 3162 0 R /XYZ 81.145 410.174 null ] >>
endobj
3193 0 obj
-<< /Type /Page /Contents 3194 0 R /Resources 3192 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3244 0 R >>
+<< /D [ 3162 0 R /XYZ 81.145 399.215 null ] >>
+endobj
+3194 0 obj
+<< /D [ 3162 0 R /XYZ 81.145 388.256 null ] >>
endobj
3195 0 obj
-<< /D [ 3193 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 377.298 null ] >>
endobj
3196 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 366.339 null ] >>
endobj
3197 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 355.38 null ] >>
endobj
3198 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 344.421 null ] >>
endobj
3199 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 333.462 null ] >>
+endobj
+277 0 obj
+<< /D [ 3162 0 R /XYZ 79.37 296.05 null ] >>
endobj
3200 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 275.208 null ] >>
endobj
3201 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 663.225 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 264.249 null ] >>
endobj
3202 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 652.266 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 253.29 null ] >>
endobj
3203 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 641.308 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 242.331 null ] >>
endobj
3204 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 630.349 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 231.372 null ] >>
endobj
3205 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 619.39 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 220.413 null ] >>
endobj
3206 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 608.431 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 209.455 null ] >>
endobj
3207 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 597.472 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 198.496 null ] >>
endobj
3208 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 586.513 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 187.537 null ] >>
endobj
3209 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 575.554 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 176.578 null ] >>
endobj
3210 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 564.595 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 136.727 null ] >>
endobj
3211 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 553.636 null ] >>
+<< /D [ 3162 0 R /XYZ 81.145 125.768 null ] >>
endobj
3212 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 542.677 null ] >>
-endobj
-3213 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 531.719 null ] >>
+<< /D [ 3162 0 R /XYZ 93.716 94.71 null ] >>
endobj
-3214 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 520.76 null ] >>
+3161 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F15 326 0 R /F59 338 0 R /F84 404 0 R /F74 329 0 R /F16 328 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-3215 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 509.801 null ] >>
+3217 0 obj
+<< /Filter /FlateDecode /Length 2523 >>
+stream
+xÚÝ[Énä¼¾û)ú†CwÀ0ÐínÈÙ· ×ä”÷¿†û¦%z üÀAÝbñc±öiJäí¿7êþÿÇÛãëí÷&íMk‡Û×Þغìf€(qÓŠªØíë·½Sªîs§”[÷1ÿþúçõ`ê÷fÄÍ«7-£šp#’´¿$HÿÛË}žþg~´ŒÉýoì“RaÜáxØÒw7_¹xú‚¯ Òz:püsÈ#‚ó UY¯>ƒý(`A.˜Od,)a0+°zn ¥=Âœr0òK:´šX0#PP‹BJ)¢ I=NôŠÆQe#µ*ãbUPL
+qfÔa\¡èïYº"çLâg«Ñ!§Ñ0âõíé'ex
+þHÙ(M¹üýC¶‰ˆ¦ãÊõ OOç\ïBxlîKö ÙîZL=1kã~Ô:ªõ…½Z³²×@½³:k½Ì]x­.¡†—­,)À„9±((PÄ“äDɼ<%wŽC~GxhV/!#“U!Ö-EÅQeóhÌ,e‘´ƒ jÈÊ+ü·†Y}&ÜGšWF¼x¹>žYƒ-¦X¥ˆ`ó†BŠç€“dis¹’’©w¹Üaj»R” @ÇEÉÜj~Ëbß—%âöãjuëBa ¶uWa®”1ÒñÞs.«\»â+—.µ–Õ«;áœHn±¨ÇÚNz$¯«¾XT¯¶Èª;Ën]¿åZ_4ñý²&³$¶èŠ£ô܈‰³‘dÈÄ4ZYí2JÞØV¥ @$j&ê¾&܈ÖÝ„ E;û¯–²È-cDÃØåkÝ}_|”¥
+4`»MgAkZ‚Šd¥2˜
+‘»ìÅ-µCPmmñü“,Â4Ñ€]±æ\Rw‘­˜Ïô:@½úGï$"~|AŸM´T ,~÷n‘3©Ÿ^ø èHÓ4úÛ§.*< ^|b]§¦åˆTåõ›"ìKDûm]Ûœ¾ªII¼¹×…W¹ŽªÚªiš‹? /°’Šò«/,’¼¤Ántüt:^äÔbÄþ4™_ïÁ“W H¹oÈw÷jˆ=NDó7“?’ˆ¥£91Æ`Ò¹ÚùJë>¾CúëbÆg_á‚c¹ÿh®·˜</VòÀ$QŒH×8"±¨s^슸: Ÿ"‚ÊÆèÕÒ?ûI„G‘¿ÊOü{áÜ2åw"?ëœYP9š5…÷HWÿ`–PËQ‘kòê‘~ÞC¨!Œ ”S±æ!=Ò·ïq2« Óµ5¾”ù¤ïsdTè+Ž.óĶ}@ú>GZØ߯ëÕQz¥1 •?å8n*™0„K‹¼úþÅ ?®…T¡(oí ß·´ rà‚ˆ}|÷r¸X¥7pÐäКa[ÛNý‰!>?†'¡køÏ^ç=ýYö׳Øß¼òcŒù_¿6+`3§¯]» ¤º êÒ|±²¦®z}½ýÎÅf
+endstream
endobj
3216 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 498.842 null ] >>
-endobj
-3217 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 487.883 null ] >>
+<< /Type /Page /Contents 3217 0 R /Resources 3215 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3213 0 R >>
endobj
3218 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 476.924 null ] >>
+<< /D [ 3216 0 R /XYZ 78.37 808.885 null ] >>
endobj
3219 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 465.965 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 768.829 null ] >>
endobj
3220 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 455.006 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 757.87 null ] >>
endobj
3221 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 444.047 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 746.912 null ] >>
endobj
3222 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 433.088 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 735.953 null ] >>
endobj
3223 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 395.23 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 724.994 null ] >>
endobj
3224 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 384.271 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 663.225 null ] >>
endobj
3225 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 373.313 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 652.266 null ] >>
endobj
3226 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 362.354 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 641.308 null ] >>
endobj
3227 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 351.395 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 630.349 null ] >>
endobj
3228 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 325.492 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 619.39 null ] >>
endobj
3229 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 314.533 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 608.431 null ] >>
endobj
3230 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 303.574 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 597.472 null ] >>
endobj
3231 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 292.615 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 586.513 null ] >>
endobj
3232 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 281.656 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 575.554 null ] >>
endobj
3233 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 270.697 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 564.595 null ] >>
endobj
3234 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 259.738 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 553.636 null ] >>
endobj
3235 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 248.78 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 542.677 null ] >>
endobj
3236 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 237.821 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 531.719 null ] >>
endobj
3237 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 226.862 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 520.76 null ] >>
endobj
3238 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 215.903 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 509.801 null ] >>
endobj
3239 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 204.944 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 498.842 null ] >>
endobj
3240 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 193.985 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 487.883 null ] >>
endobj
3241 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 183.026 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 476.924 null ] >>
endobj
3242 0 obj
-<< /D [ 3193 0 R /XYZ 79.37 160.314 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 465.965 null ] >>
endobj
3243 0 obj
-<< /D [ 3193 0 R /XYZ 81.145 142.179 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 455.006 null ] >>
endobj
-3192 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R /F81 366 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
+3244 0 obj
+<< /D [ 3216 0 R /XYZ 81.145 444.047 null ] >>
endobj
-3247 0 obj
-<< /Filter /FlateDecode /Length 1756 >>
-stream
-xÚÕZÉn9½û+ôaXU,.€a@Ž¬
-‡àÁX‡÷ÿ?[‹h-å|³Ö½ÖßÞ¾üóþד5\@óßï“ÓÁ™p‹Ñä‡
--Xvµ¨ç\GÝiQ$ÞºG¡ð›8«Âù­"ç9.–ÿ—'¬œnÏ/ìšÁð¬5Zƒ šÉ³ÊL=¾5²M1…üòûÜ+±|&eêµ»¼ü!Ï{°q”¦°Î`MáT¦è\ÈdÊzÈâÓ±©«‰µøéiöÓ|-Jâçñ¤7‹îÙ¿Ð ·ó‚ÏyÁaXTçøðò… >WÜ­û´ÈAТ‰_fºSRi–‘ŒÂÇ¢™y¤È5Å°æ¾kðp+{`‰=r0œÜÈ?ÀK¤çúT ṺyáN³¾·WÊÃqõ€&†I‚Æ ’Ä€ˆœlå*RN"·d ï û fÆ“‡Ä>%Uæ×ØOçEÙRM–j) ~c©zßÖRbo©Â𗌠¸•÷º KNROlåôIš`0
-bÉ°·4bgø郌r»rÁ@û ©£XZç¹Ë©£]—7R‹”¥¯«#]7TðµöåzÝÎ*ñýZvÞ¸l©K½Téa
-ÐéÚb/²«zni ¦(²<êXöH+Kí.}ñ÷ؼ!J’VZÝ6Ì·lHT¢n3¹Ç¹¾Œ§Ützøò¥”c6‚è ¬ªì$f-“HÙ©Pd²³¶É& F$±)‹‡·ƒT}\§°ÿ¨êX;«Í¤;•Ú
-hØ’è¤ÓVÄÚ
-‡<vbFÛ[7” ¡èG¤O˜
-`ÒÃr 0B}‹„Ü y1·ììê[n€®ç–r8½·9Zš\ô,›ytþÊÊ·ù§|+ß–ôÁ£®|n™öxOAkœ‹’,{siÍ®žûà\M)’MÆÅ$‰¤K‰ÐF¤]uÍ5¸ÖlL¯î)qû»Óõ–H¼KŽ‡l¦r*)šä¨j:œÍ²¶H‰Áp
-vÔì
-իǤ¥Í™Ê–ج6êo<ˆî°·riÚï~J¶Xe*/¿—»7r]}y5eaØJ;´VΛ7–ÞÞŸ~
-endstream
+3245 0 obj
+<< /D [ 3216 0 R /XYZ 81.145 433.088 null ] >>
endobj
3246 0 obj
-<< /Type /Page /Contents 3247 0 R /Resources 3245 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3244 0 R >>
+<< /D [ 3216 0 R /XYZ 81.145 395.23 null ] >>
+endobj
+3247 0 obj
+<< /D [ 3216 0 R /XYZ 81.145 384.271 null ] >>
endobj
3248 0 obj
-<< /D [ 3246 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 373.313 null ] >>
endobj
3249 0 obj
-<< /D [ 3246 0 R /XYZ 79.37 773.016 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 362.354 null ] >>
endobj
3250 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 754.882 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 351.395 null ] >>
endobj
3251 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 743.923 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 325.492 null ] >>
endobj
3252 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 727.983 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 314.533 null ] >>
endobj
3253 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 712.042 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 303.574 null ] >>
endobj
3254 0 obj
-<< /D [ 3246 0 R /XYZ 79.37 673.382 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 292.615 null ] >>
endobj
3255 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 643.293 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 281.656 null ] >>
endobj
3256 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 632.334 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 270.697 null ] >>
endobj
3257 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 621.375 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 259.738 null ] >>
endobj
3258 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 610.416 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 248.78 null ] >>
endobj
3259 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 599.457 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 237.821 null ] >>
endobj
3260 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 588.498 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 226.862 null ] >>
endobj
3261 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 577.539 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 215.903 null ] >>
endobj
3262 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 566.58 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 204.944 null ] >>
endobj
3263 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 555.621 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 193.985 null ] >>
endobj
3264 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 544.662 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 183.026 null ] >>
endobj
3265 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 533.704 null ] >>
+<< /D [ 3216 0 R /XYZ 79.37 160.314 null ] >>
endobj
3266 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 522.745 null ] >>
-endobj
-3267 0 obj
-<< /D [ 3246 0 R /XYZ 79.37 486.077 null ] >>
+<< /D [ 3216 0 R /XYZ 81.145 142.179 null ] >>
endobj
-3268 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 467.943 null ] >>
+3215 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R /F81 358 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
3269 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 456.984 null ] >>
+<< /Filter /FlateDecode /Length 1758 >>
+stream
+xÚÕZÉn9½û+ôaXU,.€a@Ž¬
+ó˪
+³†y¤È5Å°æ¾kðp+{`‰=r0œÜÈ?ÀK¤çúV ṺyáN³¾·wÊÃqõ€&†I‚Æ ’Ä€ˆœlå*½Þ”¼7ì/d˜Oû”T™\c?ydK5Yª¥0ø¥ês[Kaˆ½¥
+ÿÁc\2.àVÞë6,9I <±a”Ó'k‚Á
+^dº³4bgø郌r»rÁ@û ©£XZç¹Ë©£]—7R‹”¥¯«#]7TŸŒ›ðµöåozÝÎ*ñýZvÞò
+&Mz€®§ß*MéÜä’oÛVXÇð|wjp¹í@|oÑEÖÄF$Çrèwßú¬²¹&É(5æ×6n eXcÖǦé×–
+Ž¢A¾XBŒûKžV€H×{‘]½ÐsKk0E‰e«hv³ì‘V–Û]úâï±xC”$­´ºm˜oÙ¨DÝfrs}O¹éôðåK)ÇlIÒUé³–I¤ìT(2ÙYÛd#’X‹”ÅÃÛŠAª€>®SØTu¬Õæ Ò“Jm4lIô?Öi«Gbm…C ;'2ÙY7” ¡èG¤O˜
+œ¾Û-M.z–Í<ºƒ¿?ÿ
+endstream
+endobj
+3268 0 obj
+<< /Type /Page /Contents 3269 0 R /Resources 3267 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3213 0 R >>
endobj
3270 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 446.025 null ] >>
+<< /D [ 3268 0 R /XYZ 78.37 808.885 null ] >>
endobj
3271 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 435.066 null ] >>
+<< /D [ 3268 0 R /XYZ 79.37 773.016 null ] >>
endobj
3272 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 424.107 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 754.882 null ] >>
endobj
3273 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 413.148 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 743.923 null ] >>
endobj
3274 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 402.189 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 727.983 null ] >>
endobj
3275 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 391.23 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 712.042 null ] >>
endobj
3276 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 380.271 null ] >>
+<< /D [ 3268 0 R /XYZ 79.37 673.382 null ] >>
endobj
3277 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 369.313 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 643.293 null ] >>
endobj
3278 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 358.354 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 632.334 null ] >>
endobj
3279 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 347.395 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 621.375 null ] >>
endobj
3280 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 336.436 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 610.416 null ] >>
endobj
3281 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 325.477 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 599.457 null ] >>
endobj
3282 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 314.518 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 588.498 null ] >>
endobj
3283 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 303.559 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 577.539 null ] >>
endobj
3284 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 292.6 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 566.58 null ] >>
endobj
3285 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 281.641 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 555.621 null ] >>
endobj
3286 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 270.682 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 544.662 null ] >>
endobj
3287 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 259.724 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 533.704 null ] >>
endobj
3288 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 248.765 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 522.745 null ] >>
endobj
3289 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 237.806 null ] >>
+<< /D [ 3268 0 R /XYZ 79.37 486.077 null ] >>
endobj
3290 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 226.847 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 467.943 null ] >>
endobj
3291 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 215.888 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 456.984 null ] >>
endobj
3292 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 204.929 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 446.025 null ] >>
endobj
3293 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 193.97 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 435.066 null ] >>
endobj
3294 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 183.011 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 424.107 null ] >>
endobj
3295 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 172.052 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 413.148 null ] >>
endobj
3296 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 161.093 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 402.189 null ] >>
endobj
3297 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 150.134 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 391.23 null ] >>
endobj
3298 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 139.176 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 380.271 null ] >>
endobj
3299 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 128.217 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 369.313 null ] >>
endobj
3300 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 117.258 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 358.354 null ] >>
endobj
3301 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 106.299 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 347.395 null ] >>
endobj
3302 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 95.34 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 336.436 null ] >>
endobj
3303 0 obj
-<< /D [ 3246 0 R /XYZ 81.145 84.381 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 325.477 null ] >>
endobj
-3245 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R >> /ProcSet [ /PDF /Text ] >>
+3304 0 obj
+<< /D [ 3268 0 R /XYZ 81.145 314.518 null ] >>
endobj
-3307 0 obj
-<< /Filter /FlateDecode /Length 2171 >>
-stream
-xÚµZÉn#7½û+úL“,®€!À²¤
-ù»a®Ý¤UQ˜Ãhpg“¬JÔ[ÞeU&é+ɤŠ{4Ï@*Ð"QXhêÀj’&ý0˜,vHUxõ`ÉMŸ¢‚“qÒ§m(Wž~¨Øˆû‚Á¶
-Ö~ Ë¿\E%sB¹ñ%.ƒÿ<e1×^Ãsq™uæ ÐÕÙñ„MÅ"Ðõ6áõrBÉoôÛ¨´ÑxSú#;DûY'=Swœ
-Ž¾oÛž ;ª`3—}Ûî ñ;ã4uÐõ©»_Çžæ¤u =½?tHÁ\‡Du%KJ—ë¨Ö¬=öÍÃ{£Ã£W÷"O³rŠþýHνqƒæ@ôHQUURK…é®dzü´aʉ¿½.>ók‘¢™Vë<›{]´¶¸­¶fu$‹³o\à{Cá¦xcœmªˆå½0[£üNK9\ƒ!: êËvHÓ¦H:#&“õÌiT3þë²R3\ åp#“*èGW`ªÞÖ]7©WÚ;›S.˜Ù6Q‚
-Y\{Gc ’r•)¤ÇðÔ5 ¹®Œ´Ÿ”qm)õ †„ÌúžÁƒ-ˆkRJ H‡š—PÏÔw=SeL+h'ôTÔ”üvyÌ‘@žŠf†rˆ“ñ XûPß‹c:öµŠŸ/Äáë˜\‚Úh¢€írå>_<+ êz\ÝÔK’]úÏ
-j1 Þ}¢-л­.:ÌÕ•’ùDE ½j­=°ù¬ùv;\‰MÉÑ×o·µÎqƹïhýOÍ9éÑÞi³(ŽDÊWê°Zh4ÿ¡Úâ6
-endstream
+3305 0 obj
+<< /D [ 3268 0 R /XYZ 81.145 303.559 null ] >>
endobj
3306 0 obj
-<< /Type /Page /Contents 3307 0 R /Resources 3305 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3244 0 R /Annots 3360 0 R >>
-endobj
-3360 0 obj
-[ 3304 0 R ]
+<< /D [ 3268 0 R /XYZ 81.145 292.6 null ] >>
endobj
-3304 0 obj
-<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 236.441 463.885 246.868 476.405 ]/A << /S /GoTo /D (Hfootnote.43) >> >>
+3307 0 obj
+<< /D [ 3268 0 R /XYZ 81.145 281.641 null ] >>
endobj
3308 0 obj
-<< /D [ 3306 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 270.682 null ] >>
endobj
3309 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 259.724 null ] >>
endobj
3310 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 248.765 null ] >>
endobj
3311 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 728.979 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 237.806 null ] >>
endobj
3312 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 718.02 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 226.847 null ] >>
endobj
3313 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 707.061 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 215.888 null ] >>
endobj
3314 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 696.102 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 204.929 null ] >>
endobj
3315 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 685.143 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 193.97 null ] >>
endobj
3316 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 674.184 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 183.011 null ] >>
endobj
3317 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 663.225 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 172.052 null ] >>
endobj
3318 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 652.266 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 161.093 null ] >>
endobj
3319 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 641.308 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 150.134 null ] >>
endobj
3320 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 630.349 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 139.176 null ] >>
endobj
3321 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 619.39 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 128.217 null ] >>
endobj
3322 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 608.431 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 117.258 null ] >>
endobj
3323 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 597.472 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 106.299 null ] >>
endobj
3324 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 586.513 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 95.34 null ] >>
endobj
3325 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 575.554 null ] >>
+<< /D [ 3268 0 R /XYZ 81.145 84.381 null ] >>
endobj
-3326 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 564.595 null ] >>
+3267 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-3327 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 553.636 null ] >>
+3329 0 obj
+<< /Filter /FlateDecode /Length 2168 >>
+stream
+xÚµZÉŽã6½û+ôÍæRÜ€†»m˜[’¾ æ” sÉ’K~?,.â*[t'ôX õôŠ,Ö*Jäò}¡îÿŸçÃëMÚˆ5Lðåã[¨ûÇÉ‚E+F¨bËÇåë¥êL©°éïøíãË"˜ƒz½X ±J Sâ0¦ˆ–ºE’*<]yÀDRÂ(21sLj$N/’Kä$Ó‘bî (eïî>¾‰¯cl:8†R
+z½§ÒQ‰#.ˆàPMDîšñ¨ÈûõÆäb_îÄ,øjK„c+$aÒ$¶B¹gËá*üuòóËñEñÎÄ-ð WàÞ‰ÏÀ:ß.Ùñ…¤è…M·øûìÂpFøPC”ܵ.VËMƒ†Ù÷üMšQ8ÕÅÕ€YÚŒ.ǼaŸ> JŒ¶ßÒv]µ‚÷šâÁësR(k ·b¸+Ä>)Ü´C”õ|<ÚöòûcR&cˆ0’ ®s2ÕH…Lýþžä¨µÛœ²ãhü\Lq¬‘
+Ž«µ˜å¦¦FÜ’~íåV#Õ¶õ"íNœË-ÙË{8Ø«Yù¤$àìø@>už“¯Fʼù)X´žpŽœ//èÈÝ„ëzz}
+n¹S ~KwVÓpIï@”$A|cQ& ÷ñÝkA„W·‚ÍJ&«—ê/yœæñ5}—½½¬êßž õ%pÏRá†/¥U2Î$r
+r4ümMCV”õ•œ›jW­/ÃÙ{âšdƒls¶öO\Zç™Z£îžç,ü©k¶_ߦ%Áëõ­%§-5bŠм±÷û;\YÀqLÞÐgÛÜêßß—pð îD—+bµ0²² BðjO‰ÖÙWœ±â†UAß ;æÒLZ‚p&‡VÅÌX•¨µ*¼ËªLÒN¸Š{gžª@„a¡*«I^‚nÇAÀ\á°A*«'Knò“¼ô¡\~ú©b£ÛDˆaX±7 J’×HY‚qá"_/M‰ˆé³¦¹$žRê¶h3Òun¸È{3©$jT”{µ·óIn Ú×÷' iB°~ïÍÉ,¬!ЗìO͢РR–ºOBb’Lp¹f)a@ únF 2gžûÒʸ7UK2ÖHõÊND]“üµ"²/E ÿ½)Hâ_#}²!”$`Èë4Ç«FznÇìpëŸÚ)ˆ4r$ídi´AŠ)éëóí°KpCTnÀƒƒbÈPÍ|qÓ@c­`íšÔùKUT4'˜+á¹8£ØM„à?MYȵ×ðœÝf¹`ÎÕéñ„MÅ" Ðv›p»œóy•6*oŠh‡p?˨gÐx×É© Î÷õí¿Sdl¦ñܸEïÛ~<ÌL]´=uëØÓÁ׆ˆAÐûC‡Ì5HX‡
+¢ÝÚÌs”ªL) =]úà ô ýÊÔ ¤Øƒ`šm[O¶ ¶¤ä‚:T½{¦¶é™‚Rµ Iß?‚ )éíüœ"4Õ ¥'ág°ú¡¶+Æ4ô[ >_ý+Ö1©áµQëåJ}¾p–Ô帲©%»µŸ”b ¼ùD›9ﶺèD0UWræÍ÷ª%DzB§³êÛm%4%G_¿Ý×:C ¥¶¡õ?5ç¸uöNª¨#’¿RÏ‘´3ÿ+vá}
+endstream
endobj
3328 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 542.677 null ] >>
+<< /Type /Page /Contents 3329 0 R /Resources 3327 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3213 0 R /Annots 3382 0 R >>
endobj
-3329 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 513.786 null ] >>
+3382 0 obj
+[ 3326 0 R ]
+endobj
+3326 0 obj
+<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 236.441 463.885 246.868 476.405 ]/A << /S /GoTo /D (Hfootnote.43) >> >>
endobj
3330 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 460.984 null ] >>
+<< /D [ 3328 0 R /XYZ 78.37 808.885 null ] >>
endobj
3331 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 450.025 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 768.829 null ] >>
endobj
3332 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 439.066 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 757.87 null ] >>
endobj
3333 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 428.107 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 728.979 null ] >>
endobj
3334 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 417.148 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 718.02 null ] >>
endobj
3335 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 406.189 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 707.061 null ] >>
endobj
3336 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 395.23 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 696.102 null ] >>
endobj
3337 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 384.271 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 685.143 null ] >>
endobj
3338 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 373.313 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 674.184 null ] >>
endobj
3339 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 362.354 null ] >>
-endobj
-281 0 obj
-<< /D [ 3306 0 R /XYZ 79.37 339.886 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 663.225 null ] >>
endobj
3340 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 319.044 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 652.266 null ] >>
endobj
3341 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 308.085 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 641.308 null ] >>
endobj
3342 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 297.126 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 630.349 null ] >>
endobj
3343 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 286.167 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 619.39 null ] >>
endobj
3344 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 275.208 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 608.431 null ] >>
endobj
3345 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 264.249 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 597.472 null ] >>
endobj
3346 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 253.29 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 586.513 null ] >>
endobj
3347 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 242.331 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 575.554 null ] >>
endobj
3348 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 231.372 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 564.595 null ] >>
endobj
3349 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 220.413 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 553.636 null ] >>
endobj
3350 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 209.455 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 542.677 null ] >>
endobj
3351 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 198.496 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 513.786 null ] >>
endobj
3352 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 187.537 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 460.984 null ] >>
endobj
3353 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 176.578 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 450.025 null ] >>
endobj
3354 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 165.619 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 439.066 null ] >>
endobj
3355 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 154.66 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 428.107 null ] >>
endobj
3356 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 143.701 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 417.148 null ] >>
endobj
3357 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 132.742 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 406.189 null ] >>
endobj
3358 0 obj
-<< /D [ 3306 0 R /XYZ 81.145 121.783 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 395.23 null ] >>
endobj
3359 0 obj
-<< /D [ 3306 0 R /XYZ 93.716 90.737 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 384.271 null ] >>
endobj
-3305 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F16 328 0 R /F22 357 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
+3360 0 obj
+<< /D [ 3328 0 R /XYZ 81.145 373.313 null ] >>
endobj
-3363 0 obj
-<< /Filter /FlateDecode /Length 2058 >>
-stream
-xÚÍ[ÉŽ#7½×Wè&š 2¸
-d1ùßÿCHé_dË— I§ë{úJ¡I«Ò}ýšîÝʵSí©¼Ú<Ê]{ow?{ÆØ}ݵ¾ëVÞïî1¯û
-‡h¿z+¿[,toß·ú\È¿ïoì4šŒUÖ`ÃÆÑíÔVL|QšûBm¤@+dÕf7¬e½‰ ­áÖ#Ró „o•¹*ØÌì~ý˜•° í^~ë(í§¼ï+W¨J  “ÌÕØ7N•Ú"­ëM¢ÊG‘*g ëñÙ“ø̵ŠûVÄ°ûɽùIú-œ_Zåj–Ñòÿ©Vå
-(a»~X›òú]iû:ܯvaÛƛҲ²ím_µ«¢Yïi»`ÁØÈŠìʉØ0ìr#rœçë'LXô)<ÞºeÊ[»sÖhV¶Si°YՉʎèce´Ì‘W”pp<]‚wz¿—󈫲rpKŸ¬îϋΦUÚ°¢àR¹ÃD–µ(•/@ŸØñµÞ™ê0c¥Œê
-»¦÷“Y!Õø&U RÎ[.ͦŒ.#XÞ½„Ô‚4´½Oö [“lëâ~œx÷§Ÿê¾L`é·³ãœÍ-ó©sÀ×rý¾ìÍÔ½ _óåÆu½·Ö±âúÉx6FŽ×³9ªñ:# °ÏÚÝ9Ï;2}`’„º|¶ù«9ò¿Íjà À^w„¸yŸkç€,ÇôÙטž€:ÏÇN´äêVçŽ:k=Sæ¯èõ'UC4ËâUÆâŒ4ëõ‰EȵàÐpü¡OÎHßœÔcÀ9Ö”Îö}®é9ÿé{}¿ÆoÁ+b­JÖ=.Hâ¦Ñ¼u,%Ü@3Ù)øàY=‰š ùI¦–Ý·’ܬ«n--
-0DȦ “É·’»
-ogû€ÎÝù4°µn“5Ïž×D–ŸëÄÛûT®w]e ¥“ñe¶·›É\¼cÔ/TZPžX%‰†/ Ð’o«]yÛü¨)‡ŒýC-Я¼©£ ¯vÎ4ôGÎ^ó±o4…Žû÷íMÝg›'”wÓ8†Ã¼iCúGÓ”ÏQj]JOT„¨ híØà(Úí_€º
-sÐh–º…ƒÎÔpZå^=ñ~”“àÛÖÙøÌ0
-DÂô‹: aËaY§°
-®Y™÷|Žõé[(/e€Ð³þB2™‘žþÿ›æÎ]©Í@Ÿœ±¬Ú&×Xì½5{Çž{8IïžHâAƒS‘5OÙ¶æ ôINR½¤Êvô$‡?š.ùx æa|'“”¹‹U}/*úÁî·÷—ÿÏ8
-endstream
+3361 0 obj
+<< /D [ 3328 0 R /XYZ 81.145 362.354 null ] >>
+endobj
+281 0 obj
+<< /D [ 3328 0 R /XYZ 79.37 339.886 null ] >>
endobj
3362 0 obj
-<< /Type /Page /Contents 3363 0 R /Resources 3361 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3244 0 R >>
+<< /D [ 3328 0 R /XYZ 81.145 319.044 null ] >>
+endobj
+3363 0 obj
+<< /D [ 3328 0 R /XYZ 81.145 308.085 null ] >>
endobj
3364 0 obj
-<< /D [ 3362 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 297.126 null ] >>
endobj
3365 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 286.167 null ] >>
endobj
3366 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 275.208 null ] >>
endobj
3367 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 264.249 null ] >>
endobj
3368 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 253.29 null ] >>
endobj
3369 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 242.331 null ] >>
endobj
3370 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 231.372 null ] >>
endobj
3371 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 220.413 null ] >>
endobj
3372 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 209.455 null ] >>
endobj
3373 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 198.496 null ] >>
endobj
3374 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 670.199 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 187.537 null ] >>
endobj
3375 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 659.24 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 176.578 null ] >>
endobj
3376 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 648.281 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 165.619 null ] >>
endobj
3377 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 637.322 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 154.66 null ] >>
endobj
3378 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 626.364 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 143.701 null ] >>
endobj
3379 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 615.405 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 132.742 null ] >>
endobj
3380 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 604.446 null ] >>
+<< /D [ 3328 0 R /XYZ 81.145 121.783 null ] >>
endobj
3381 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 593.487 null ] >>
+<< /D [ 3328 0 R /XYZ 93.716 90.737 null ] >>
endobj
-3382 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 582.528 null ] >>
+3327 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F16 328 0 R /F22 357 0 R /F71 339 0 R /F53 337 0 R /F73 342 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-3383 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 571.569 null ] >>
+3385 0 obj
+<< /Filter /FlateDecode /Length 2058 >>
+stream
+xÚÍ[Ín+·Þç)ü—G¢$JŠv¸ëìŠnÛÕ}ÿm¥‘4ú&:ç
+YÚ†µ¬7´5Üzr"šg |«ÊUÃfe÷÷™„Ýh÷ò]7ˆ€´Ÿò¼_L®J  “Í9j,G¥ö€èXêˆÊÈú$|ÞÉ|æZÍ}+fØ÷ɽí“ô]8c¾´.Êi–ÉòÿI«"@"Ž&ûÆÐJÑQ~ZŸ$õ1ÿIh]€6uuQ©¨ßT²uÏ´ ” (a»¾~X yýNÚ¾÷w»±m ã´L¶½í«v*šš§MLÁ‚±‘3™CÎÄÞ€a—ÓMdá çë' ì>ðèSx¼wËÈ{;‚5šµí•£Âi°¹õ²²cú˜Œ–9òŠŽ†w×£áIïŸå<B5ð¹l¤ÜÒ_V÷çMgÓ*mXSp©œ0‚s–5µ(•/@Ÿøñµ~2ÕaÆJÕ\t¬àö”àÚ(>°™¹ÁÅá1@Yµ
+Êbé:—~5&—="¹=OžÑÇÇ£>9[&¿LÙS¨“‹äÙÜSsÕY¤A'}ÐI(cpàuXetx:?î2ÎHƒŒ¡Êg¤²y ž8Ñš{mê’ef ûÞÜRj¯M¾X×wp騤ڑ 4§Þɼ¹«7#u¹×²}ÊR¾Ê^Ë/fÇ!‹¬üW™ü3Ò ?ßK
+å´B0œœFèá3Ò ç÷Ú'¡>)ZG´¬>A¦ÏŒtÆo¤²ê˜ïXq2Yg¤£í‡D(£ŠÄae´2g¤9Joe½ê½“‘Êic€´kYÞerAêræÞpk#î͇¥2*°ÙD˜ñ¤.ãÉê_(·'Ðxèaò«0 .HƒÜ¯­Eëó9¹œä@{NLaFœº”^—¿M"¤Í: ¨‘¯f´e½5€Î°ë¯’’{ZÇÙý¾3Vá õotØÖ `´œâ5%-ëkÆ8v}j:̃nOJ¨¾V`Ž…ÝÆûɬj|“*†)ç-ŠC³)“ËÄ–ß^ÂNjAÚÞ'{­I¶uq?N¼û¯Ÿê¾L`]`ÌÈ4Ÿ‘º|-×?7ƒ¿™z–ák¾Ü´®Ÿ­u¬¸~2Þƒl¬?›£š®3ÒÐûÌî®y>‘é“Dêò·Í_ÍQÿmV{ä
+t8†•ú!i¿°±cι¤¯±Ç$žŸß›©TÍ4mWO¨|“7we;Á™ŽíÄ´bDŽÄ“I½‘89¿ª;ÑMßTꟴµ[À;Ô£Ó!m¹2TþS®Âñ„¼|$Æé1#.ÓÚ Ì8nŸ’ìõvmÌcÔÏŽ·TÉ c'ž q"GšìDxê¤eOocŠ¶Ú¹ù0`ûÒx»úØttçÓÀÖºMÞ<ï¼f²ü»~@¼=Ouãzê”1’NΗ lO7“»xbè’„”w,I¢áË´äÛêWÞ¶}TŒ”CÆ~‰¡–èWÞèhÆ«³zŠ£ç]óñÞh„Žç÷íI}϶PžQ\ãó¡uéMS>G©u©{¢"Dm@kâ(”ö/@Â4š§ná ‡35ÜV¹×x?ÊÉðíèlüÍ0
+endstream
endobj
3384 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 560.61 null ] >>
-endobj
-3385 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 549.651 null ] >>
+<< /Type /Page /Contents 3385 0 R /Resources 3383 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3213 0 R >>
endobj
3386 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 538.692 null ] >>
+<< /D [ 3384 0 R /XYZ 78.37 808.885 null ] >>
endobj
3387 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 527.733 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 768.829 null ] >>
endobj
3388 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 516.775 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 757.87 null ] >>
endobj
3389 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 505.816 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 746.912 null ] >>
endobj
3390 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 494.857 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 735.953 null ] >>
endobj
3391 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 483.898 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 724.994 null ] >>
endobj
3392 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 472.939 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 714.035 null ] >>
endobj
3393 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 461.98 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 703.076 null ] >>
endobj
3394 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 451.021 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 692.117 null ] >>
endobj
3395 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 440.062 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 681.158 null ] >>
endobj
3396 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 429.103 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 670.199 null ] >>
endobj
3397 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 418.144 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 659.24 null ] >>
endobj
3398 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 407.186 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 648.281 null ] >>
endobj
3399 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 396.227 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 637.322 null ] >>
endobj
3400 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 385.268 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 626.364 null ] >>
endobj
3401 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 374.309 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 615.405 null ] >>
endobj
3402 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 363.35 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 604.446 null ] >>
endobj
3403 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 352.391 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 593.487 null ] >>
endobj
3404 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 341.432 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 582.528 null ] >>
endobj
3405 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 330.473 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 571.569 null ] >>
endobj
3406 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 319.514 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 560.61 null ] >>
endobj
3407 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 308.555 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 549.651 null ] >>
endobj
3408 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 297.596 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 538.692 null ] >>
endobj
3409 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 286.638 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 527.733 null ] >>
endobj
3410 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 275.679 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 516.775 null ] >>
endobj
3411 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 264.72 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 505.816 null ] >>
endobj
3412 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 253.761 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 494.857 null ] >>
endobj
3413 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 242.802 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 483.898 null ] >>
endobj
3414 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 231.843 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 472.939 null ] >>
endobj
3415 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 220.884 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 461.98 null ] >>
endobj
3416 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 209.925 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 451.021 null ] >>
endobj
3417 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 198.966 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 440.062 null ] >>
endobj
3418 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 188.007 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 429.103 null ] >>
endobj
3419 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 177.049 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 418.144 null ] >>
endobj
3420 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 166.09 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 407.186 null ] >>
endobj
3421 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 155.131 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 396.227 null ] >>
endobj
3422 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 144.172 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 385.268 null ] >>
endobj
3423 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 133.213 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 374.309 null ] >>
endobj
3424 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 122.254 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 363.35 null ] >>
endobj
3425 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 111.295 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 352.391 null ] >>
endobj
3426 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 100.336 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 341.432 null ] >>
endobj
3427 0 obj
-<< /D [ 3362 0 R /XYZ 81.145 89.377 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 330.473 null ] >>
endobj
-3361 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-3430 0 obj
-<< /Filter /FlateDecode /Length 2475 >>
-stream
-xÚ½[Koã6¾çWø,—¾ @¼Ž ôœ[Ñk{êÿ¿–#’9;¤ì,ÞXùi^΃–žþ=Éôÿ/çÏ—ŸWOFÄ 4œ>ÿyQ'™þ©S
-ïšK{e”êW/ÓVD»¾/®÷Üúæ+¾3óÕˆé Y)”*#èôqLFÊ o=EB굓E¢=½Ó¦ï°ò¥ ~Öù87aØ$ƒÒ¿l’HO®é2˽ŽBÍqoaŒ{pBy Hc²iö È"çs–Ê¥ëŠtq>¤gÆ=ËZ •ÁÈËÇ䥭°ÁíŠ-øĵ ™”@åm§±y»—`âl’å€eyyŸÓ}¤ ½p¥H:Îqé8GQô{¬qd#Oð,ßå¢ZzV^aÊ)µÆøíÖè‚I;Md­ÑNéž ¶FçµÐ<AfŽ è÷Ø¢ ™s|Û·{Eç@­X;ÔsvH~¿WtV ãÙx`4fªjï‘ŽÛ¡I£Ô~Ó
-AZ(*RÕy·ÿyUö¤7>
-æƒnÓŽþ(¾N.óh­‹…ºõj±ÓK½ªº\îž³.³¥Ö¸20jâfÓø1ßýöBÇ@ Æò)ßõ:ÜCt-L{Ã1 Iþ)ž#\c$†QÒ^uj/w¥§•FêR¸ûú"s¥„óëÞ
-®:öQ8ÚœA9íEIu®ˆ
-=JßËM«.L,6÷þfß÷^ƒálÎÆ(¶EdT6ÕXØk}E}²lXª^Õç‹9…z—XB33‡ÓõN˘ƒöÝh¨ù
-xµ5ÈK
-E1¿é ükÅ„×üõ+ßõò­Øo}J¨?gü…[h)»EkÅݶˆšà¢«cBI£ò;­½kŒ:Ê¢ŽÛz¾«Y£pT³Ðj¶rVÉÆï>ò–GáS—#1¥à…w¶Û\ªô¼ì]t¹³jÙ«×͆à\ô‰ã\Üé¿ÎÎî«â©×ê*3®5ãZX_&e“l!ò•bIö~?{¸j¿êjÙÉiý0°è(T;^ÔÕ]-H¸º’|²%º*§n%,ãÐý¬VïÄ2 ².+!KÙçñiåTº&Ï3n]Œ x+ÂêÑv³SØ îo
-XQɬ{ ÁpëÞ¢P)ôpcBw©
-J(ëÈä‰ôøe ƒp‘`±y±iq›ç‹)íb"8ÊiõåY‘¸$l¿8ð‹!ÑwÔ;QÛÄE5okêBõŠ¶.·šõ=¡P)£*~Îæ<²•:-‚µ“¦ƒðf7ùI¦¥li èT»Ho (uæ;­:· “SghÔYÌFáku¦íFè´Ÿâǃ¡û†ž‚õ°MYwã郵p—>L–øÒó œ·ÃÙ‡ŠœÖ(µç$0Y´£HCééÃ%¢InµÑ–Û÷9n R]Öº‰ºšè ïâ¥$-IŒ¶ž#3BªÈÉl´ðXeF”Ù|{RnïÉMF!Y×2Z¬®¥b
-ã4™´a)©Xû·Sº$HÏ÷wðN3»§ù<“re€•Â`õ2EpÉÀvHGKrÖœeg®“sŽ[±ñÉ[`-_VYõHcoãwx|cS«w­ùÞl|`œeÛ@a¼àY¹'H¿MãÏ‚5\ëÉÙñ"kõ=Òc¾Ìh®ÁƒTÆnU7é`ƒg¬¥?¿5mÇçd„FÝ1UÓ!²Í5G ÒqŠ”ûN=¤çº
-Òá[i'°Í…Ž=ÐqzÀ
-·Ï‘ É( §Há%+¢ÉFA:N‘ÔÂ3¿zÔÓQAÚ{¾†AýÅSü–ñ™Ÿ&êñ¦(¾ºU‘Ò牢 ûã-NQ®ÙÂâÃÕ*ïýjjÚ³%Ó×ÓU¢è¡ö¯ÏG]šF‰úÓäèÆ1µ¥¨ºFØ’‡Íƒ—CªKEž>ªÅ§g¨¹ÜÊif,zļVå~¯5œ¥Ž‹=©­¼ŒïÞÔ"º’kÕƒ”»ÙÐŽör³[k(/ uåÇîÒˆËñ‚»]ˆ´Jœu'Ó‘kœÚÇçËÿÂjù‹
-endstream
+3428 0 obj
+<< /D [ 3384 0 R /XYZ 81.145 319.514 null ] >>
endobj
3429 0 obj
-<< /Type /Page /Contents 3430 0 R /Resources 3428 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3244 0 R >>
+<< /D [ 3384 0 R /XYZ 81.145 308.555 null ] >>
+endobj
+3430 0 obj
+<< /D [ 3384 0 R /XYZ 81.145 297.596 null ] >>
endobj
3431 0 obj
-<< /D [ 3429 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 286.638 null ] >>
endobj
3432 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 275.679 null ] >>
endobj
3433 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 264.72 null ] >>
endobj
3434 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 253.761 null ] >>
endobj
3435 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 242.802 null ] >>
endobj
3436 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 231.843 null ] >>
endobj
3437 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 220.884 null ] >>
endobj
3438 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 209.925 null ] >>
endobj
3439 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 198.966 null ] >>
endobj
3440 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 188.007 null ] >>
endobj
3441 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 670.199 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 177.049 null ] >>
endobj
3442 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 659.24 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 166.09 null ] >>
endobj
3443 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 648.281 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 155.131 null ] >>
endobj
3444 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 560.664 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 144.172 null ] >>
endobj
3445 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 549.705 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 133.213 null ] >>
endobj
3446 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 538.746 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 122.254 null ] >>
endobj
3447 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 527.788 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 111.295 null ] >>
endobj
3448 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 516.829 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 100.336 null ] >>
endobj
3449 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 505.87 null ] >>
-endobj
-3450 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 494.911 null ] >>
+<< /D [ 3384 0 R /XYZ 81.145 89.377 null ] >>
endobj
-3451 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 483.952 null ] >>
+3383 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
3452 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 472.993 null ] >>
+<< /Filter /FlateDecode /Length 2469 >>
+stream
+xÚ½[ËŽ#+Ý×Wøš† xI¥’ìëò•f]»ÑlgVóÿÛK$ ‘ØiW«å.g&œŒA<°æô¿“Œÿÿývùzû}3á„"x¥áôõß7u’ñŸ:yOÎ*!­:}ýÿôïw)íEJíÓÇâǾþõ& ,Bý¾y<y¬Õ¾ÆQÒ À‘´“Ò¨ˆ"?~0„ýY¾Áµ|£x£žÇïô7¤k¼”Qt¯õ•A)Õ_y¼ŒXÍú¾°Þ³ë›oôÎÄW%¦odd¤Pz2ÒzLFÊ
+gG"굓E¤=¾ÏÄï°ò¥‘>ë|š1L”’ô¯›$â“[FºÎr¯ƒP¨{Üãç÷`…rÀ‘Æ,dÓìA+YΗ$’I×féÒ|ˆÏоÊZÀ Áäe£Z\“—6Âx»Cʶà"×Æ'H…C²ÊæÍ^‚‘³I^”
+à ؜ Al‹U2ðÅXØ[yEy²lXª\•ç‹9ùr—YB53…ÓåN͘…úÝd¨éŠŒxµ5HKŠD!½éÜ{Á„÷ôõWºëäG¶ßò”QIø ·PSvÖ‚»m%4¡EWÆøœF¥wóÐu ”õL÷õüP³¨QX®Y¨5[8+Îdã®ï>Ò–FÑS›BfJÞ gM³¹é9Ùºè|gÕ²Sï› Á%ë“ÆÙ°Ó™ÜWÁSïÅU&\ƒ•ãZX_&%“¬!Ò•ê’<ìýzüìáŠý:(c¸eG§õ aÑ‘/v¼ ©›ÍºZhuEù$K´ENÍJXÆ‘ûY­:Ý y$]VB’²KããÊ)4!Mš‡v]pFøÕ“í&§°<Þ¨"¢¢Y·@ƒáÖ£E¡bèÆ3àÊ„Rå•PƲÉéñ#Ê@{aÃþfó4qqãëÅw1á-ç´øò¤HZ¦]ôYôµNÔTqQÉÛj§ºP½¢­‹Ã®fýH(*Æa\ůٜG¶R«…7fÒ´‚w“_dZÊ÷ŽÎÕ¹‹ôÖ€²RgºS«s :{êô•:s€Y©Ó¯Î¸Ý÷Füx0ôØÐc°î÷¢Éën<}0"N·¨2YâcH¯/pÞgŸ*rT"è}™§‹vi(=}ºD4É­–"8ßãv´¬W¸eHeYë*ꪢƒ´‹ç’Dx¶$1ÚFxÌ@
+©BOf£…Ç"3†ô¤Ìæ Ü“r;?'7„´]±ç\KÔ)LŒÓ„qÃRRõˆÒs«!½ÞßÁ™gv/óys…ЕÂ`õ2FpÑÀvHGKrÖœd‡·É9Ç­]4B¯»flædÕ"y¼ßáñ•M­Þµä{³ñZÓmáxÁ³pÏþ˜Æ_!ƒÝÖŽY‹×h‘žóe¨» ÝŠnÒÁÏXK~jw1‹ÖÓC:\t§TMûУh²9ÊŽS¤¤ètêõxˆ’»
+z îüÁ‰
+9*ÏÁõMžnÙ*Ž¥J'bH—qTûËãÕóÂýGªŠ“GÒôÔ½o93ESx®WÄŒ\D}sv(+'AµVÄóßÅûå|mBxäW1ìUæ|ØUI‹tŒ€™áÂY\êÖ[¢”$—RUe^vËܵÈOêêÈrÇ]·\ÁâíYY™d54AéÝòùN81¾õ­· žÐ–#D
+Ð||·àR D‘–ƒkØ ðºµÖzÏ×î÷ûÅÕ9ÿ²-‚Ò;\je¢>ºqŠ™‹S ’¸o=¤ýé“*Ýÿ¤Ï,å2>²ýkîü.CºO;vh/!ø0Ý0&ý@LOÑÍög§úvÔ93¥rámר﬛î:xòŒ5 d?~MårüÎzÛî™mÝÌ&Ÿ´ÏÊýYWüOÊ
+Å-R[H«è¿Ö<Ìy›§Šeƒ·˜®õ8Lö8RG7•Åù(nr
+n>ûc:!É—t>ݺ—“$C:œ°¤ïRtž£¨E³°ñ}‰kÙè6ÔÞŠðÇ%^Àþ,Id´x]<g‹4•Ã‚ÒBëÕë:õ‘ßðs|%à*e9Ú¥ïµaò¯Îý³~kòEë^&ÏÍÙ¿ml)U•`‘·t§ƒ>×]¹û9¹·H­%ÞR“59[ÊiδV-žÎîÄÚ °¬¥WxI”@ÕÝF©¼ZÒÏÊÈ^¾“qB0ü|œ¼hLWNs'ˆÒËé<bK9ö|‰œlº»îdÉ!ý¬œt‘SŽ^"'ã…ÑÝ}{² À‘ºÑÉ}i•´œŠCC’ò\P2¯5) t´‡Òo¯¦ éðŽ­´zM†Ž-ÐqzÀÛ挅 É(!§H¡p²+¢ÉFC:N‘Ôµ¹X¡h2ÊbH{ÏÓ¯apñ?Aeü6][™òSŠoîU¤ô9×t{¼Å*Îu·°øtµÊ…G¿ššö,^ ßvÁW#«µ@Oµ]:êÚ£ ç~šÜÝ9¦¶U×(€Zò°yð|Hu©£¨ÌÓg±øøŒ4—Z9ÕŒE”תô¡ï¥†³ÔqB¶'µµ‘—ñÍ›jD›s­rr7êÑNnvkó²P—a¯Íˆ°/xØ…ˆ«Ä{ÂæŒ\UUüüzû÷ú
+endstream
+endobj
+3451 0 obj
+<< /Type /Page /Contents 3452 0 R /Resources 3450 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3213 0 R >>
endobj
3453 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 462.034 null ] >>
+<< /D [ 3451 0 R /XYZ 78.37 808.885 null ] >>
endobj
3454 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 451.075 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 768.829 null ] >>
endobj
3455 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 440.116 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 757.87 null ] >>
endobj
3456 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 429.157 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 746.912 null ] >>
endobj
3457 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 418.198 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 735.953 null ] >>
endobj
3458 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 407.24 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 724.994 null ] >>
endobj
3459 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 396.281 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 714.035 null ] >>
endobj
3460 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 334.647 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 703.076 null ] >>
endobj
3461 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 323.688 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 692.117 null ] >>
endobj
3462 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 312.73 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 681.158 null ] >>
endobj
3463 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 301.771 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 670.199 null ] >>
endobj
3464 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 290.812 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 659.24 null ] >>
endobj
3465 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 279.853 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 648.281 null ] >>
endobj
3466 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 268.894 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 560.664 null ] >>
endobj
3467 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 257.935 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 549.705 null ] >>
endobj
3468 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 246.976 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 538.746 null ] >>
endobj
3469 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 236.017 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 527.788 null ] >>
endobj
3470 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 210.141 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 516.829 null ] >>
endobj
3471 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 199.183 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 505.87 null ] >>
endobj
3472 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 188.224 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 494.911 null ] >>
endobj
3473 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 177.265 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 483.952 null ] >>
endobj
3474 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 166.306 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 472.993 null ] >>
endobj
3475 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 155.347 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 462.034 null ] >>
endobj
3476 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 144.388 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 451.075 null ] >>
endobj
3477 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 133.429 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 440.116 null ] >>
endobj
3478 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 122.47 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 429.157 null ] >>
endobj
3479 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 111.511 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 418.198 null ] >>
endobj
3480 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 100.552 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 407.24 null ] >>
endobj
3481 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 89.593 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 396.281 null ] >>
endobj
3482 0 obj
-<< /D [ 3429 0 R /XYZ 81.145 78.635 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 334.647 null ] >>
endobj
-3428 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-3485 0 obj
-<< /Filter /FlateDecode /Length 2421 >>
-stream
-xÚÝZÉn$7¾û)úF#‘Z£Ûí³oA®Nyÿk¨})uuÉÓp⃚.WI7‘©âLþ:qúÿ·§×§ŸWåN’9+Nÿ{'NÿÄÉÓòd´`\‹ÓÇߧ?ž9ׯœ£å\¾snÜùÏߟ¸'F¤~^­<Yæ´FÛÒB3£ÌHII¢DÑѽ û ýe…œ‹7zÎé¢÷ç
-”Ÿ¡ò´qŒŸƒÄ‘¾Ä¿ý}—|§+ ynTpG~Å™à0“_Ášü%ˆ:ðrz=xY¼.¤¡ß—U.Ñ1!qÆ¥~=Æ%h& Œ”À¦‹85¼ríµ AÛô«ãŠÞz~Õ I&Îóc‚•x´´·–ãßÆgÁh®~Ú@?×[Ø{BZ?Р÷ âåïý¸<?hïRïýºaü°FæÉ…k”ÉËãåËÏ;çd¹½àås«VË©f¥—cV↡„‘R•f•#a€šq„Çv·3Ì ý¼œMZ³™lCs"=3熭å]á%ýÒ¶'kpÏŸ=;M¿Î~7‹ó´èŸð³–ÏÕ>r„ˆ#½-}ˆ£½uÑä¿‚¯1rÄ'Þ«¼—^“gAŽS…
-FÚc´JAoxÍOãN¯<µ{#ÐIÏ ÌÈ1›xäö$òÔé
-nXIzjGïF0Wc†m´ ÄsÝ[~Ïø‹VÓH£¯Í+aôk¼r|’(hçzyÀó°ÏíÂ^õQ™yz—×eœYngj^fÞf-jÉÈ™–P
-FmÐSŽ}îÚU7dB ti@º ¸>[xÎÆ…‹^q_”˜ïP¥ýTã­)%òó¨ð GapEâ˜.uµàƒ¸Ù?áIˆª)ÊkCä<{x·—°Û‘7(z£íeŽ¼¯)‰vmIVcœÛQ yÝ5HÅ
-9Š7S§’¹
-ÊÑñNN±Ÿ ­Gê™·²šZþg-*
-5“8ÅÞò}à „_¨h[«ü‡*w¼£0ZÌ3’Õm8IP¤¶ K Ü” `õ
-ŠÚW¼é yœJ«©i¥@iN‰«œ t‚©Ú6í˃¾áV÷@Á·œ›ö …:Þ/Œ±8E2’¸$ :¬%Ó§ñtצ‚f"l¹†ß¤ƒÀ}î¡hñyþ@!Ï©Òv"Ì ¨ ª=d6âœR›_†ã©Ò¶ã™X‰Fq± 6¨Ì–ùc}QÜry:¹@]ZÏåܨý̉ï(EùDö8·k|~-úCW]{SmvZû"a t,ŠÔÌi_fû5â‹0Œi
-Ô} (¥k3…á]w¿…áv†;¡Çµa¸•vC¡/; åüa@,¯êqN\õ|æ\¼xs¾ŽÓ/)o}#ÖìÏÜvß~q–p÷*. ¶xÂûÓ.í41m#|9NT[Âtÿ…©iÿô„–¡©°œ!Ó¬–È@iíBpÆɤ(MB¦û"˜,”eh§àa”–a²†Éy"\‡¥# à¨Ö¿ ~ºM_þ÷0¨KÚè)ýBwÿ`Y€bŠ›™^áè@é!`YÉ”´3ÁÌ]Oé³`ù¿·/82eÝTCarL
-endstream
+3483 0 obj
+<< /D [ 3451 0 R /XYZ 81.145 323.688 null ] >>
endobj
3484 0 obj
-<< /Type /Page /Contents 3485 0 R /Resources 3483 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3244 0 R >>
+<< /D [ 3451 0 R /XYZ 81.145 312.73 null ] >>
+endobj
+3485 0 obj
+<< /D [ 3451 0 R /XYZ 81.145 301.771 null ] >>
endobj
3486 0 obj
-<< /D [ 3484 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 290.812 null ] >>
endobj
3487 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 279.853 null ] >>
endobj
3488 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 268.894 null ] >>
endobj
3489 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 257.935 null ] >>
endobj
3490 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 246.976 null ] >>
endobj
3491 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 724.994 null ] >>
-endobj
-285 0 obj
-<< /D [ 3484 0 R /XYZ 79.37 702.177 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 236.017 null ] >>
endobj
3492 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 653.796 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 210.141 null ] >>
endobj
3493 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 642.837 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 199.183 null ] >>
endobj
3494 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 631.878 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 188.224 null ] >>
endobj
3495 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 620.919 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 177.265 null ] >>
endobj
3496 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 544.207 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 166.306 null ] >>
endobj
3497 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 503.36 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 155.347 null ] >>
endobj
3498 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 492.401 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 144.388 null ] >>
endobj
3499 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 481.442 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 133.429 null ] >>
endobj
3500 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 470.483 null ] >>
-endobj
-289 0 obj
-<< /D [ 3484 0 R /XYZ 79.37 433.711 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 122.47 null ] >>
endobj
3501 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 349.464 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 111.511 null ] >>
endobj
3502 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 338.506 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 100.552 null ] >>
endobj
3503 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 327.547 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 89.593 null ] >>
endobj
3504 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 316.588 null ] >>
-endobj
-3505 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 305.629 null ] >>
+<< /D [ 3451 0 R /XYZ 81.145 78.635 null ] >>
endobj
-3506 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 294.67 null ] >>
+3450 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
3507 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 283.711 null ] >>
+<< /Filter /FlateDecode /Length 2422 >>
+stream
+xÚÝZËn$·Ýû+úF#‘zFö´;@ÖÞÙÞ¬òÿÛP¢^¥Rw—<†“¹Ôt¹J¢øyH•æô×IÒÿ¿=½¾?}¿špÒ"x…pzÿß“:Iú§N„Õ'g•VÞÿ>ýñ,¥}¥ËHé‚”ˆç?ß’‘‘ú~õúäE°}OG)+œq#%£¥Ô@Ôˆ’Qt¡_OJ©~ÐsI½G83`â Sî´ç1qFŽ.üw¼oãáRîl£a™çNä7R( 3ùõÛšü%`D9£¢,QÚÑïË*—„Ò8ri rzŒK°B9)Ïqêdã:j’¶é×òŠÑzè³T$ 8žÇ$+I¶t´Vßò³ä4×¾±60ÎŽž×O4è=(¾â}Wæ'í]Ú}\7Ö(<űpe™¢<Q¾ò|CxN‘;ÊQ¾°j%ðB‘ú'V2pÌJÒ Ô0RjÒ¬r¤œ
+.͘™k$³TõZ™¼£‰Š§sï ‘’ß…@áû´Ðà Õõ£!ô¶RE-øñ;jKÔGêz+OÃKLËÎiMÊŒ´Ñlv; ¹UßÍ cðþ´¼’©B¿C ¸Ýå'Ý]XãqDªÈuÁŽ…B¡]vñvVòeŒ˜Vg ´]³l=~Z«ì†t·í¸_QW¿…øm‰ByEÙ¸¬Av:g« £;d[ÊÁ^ÄZÚúûn©Ù†Ý26G
+«‰ªÍÍlŠŽã¦ŸGÅPu﫳íb`‚÷7Ã;—³Ì¯jç¬}C 8Ë27ª mÏu»‰£Ò£x3uÆ(Yª èû…²v¤^y/{U¡kå1Ðr¡bÐ
+Sìmõ
+†}~¡b}«ò?µPyàÍ …Ñjî’‘¼íÃIv€*µg€®AepSƒ€·w
+ÍÓK–Lm²dzò@¡w±
+ù§A3*a²]î" ª{h[ïT™K€\N2ƪJÙ´8ªJ±k’´–†œ7´¡®xÓÊ:%)ÔVS×JÚœRW=A”0­mº-¶ ·š¸
+±½´_¨Ìñ~![ÄãÉhâ’0谖Ο
+ðè]›*š‰°çv~³÷¥#„ªÇçå…2§I» iNBmÐì¡;°Ásjm~Ž§jÛNb5ñblИ­ò ƶEqÏåeèä&mi;—s_ ngN|ÇÊ'z‹s7Ï Åxèj[oªÏNk_$ „nƒE•›€%MãËl¿2þ±Ó˜`.
+ˆR8tS_–>Õ(™ôDê\³Ê”
+Â9?cêè™›&
+Ò”º“±Ëþn†Z¡ôÆÝ)C]V%’^x¦ù5‰¶”ÌêW?@éçm–ÙJUL˜U7«ouB«@J¶ß
+;J7¸_äÎÆWÓÚëh%Y¸ÛRšÙèWÜT'Ëýx±:Z›ZÕH‰õ£«ì/±'focÿ¼T¦ÇõªQífz=ú­%¥WO…Ä@iæ}/¯ì 8¨û@QJ·n
+Ã7Ýý†ûu”×Z„á^û…mÙ (—¸¼jÇ9pµó™s;ò’Ýù:N¿¤¼õX·?KÛ}ÿÅYÆÝ«¸$˜à‰—U\:ºÓÄô8ðå8UQm Óýs¦æý³%´ M•—¥š1ršr(­sbCjÎ8Yƒ”¥IÈ _“•ñ=Nͼ†NJË0Yi'ô<.‚ÃÒPpTë_ T<?§¯Ã .kcKé'Òxø?
+Œ0ÒÍôºGJŸ–•ÒÂè]Žá8,Üm)},ÿ÷ö…Da|˜iè(¬3A(À‘Ò¯º/> 0úgz=oJºßÐùd° ‘¸±'ròÐzLˆ5E¼½?ý¾ÍœÛ
+endstream
+endobj
+3506 0 obj
+<< /Type /Page /Contents 3507 0 R /Resources 3505 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3213 0 R >>
endobj
3508 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 272.752 null ] >>
+<< /D [ 3506 0 R /XYZ 78.37 808.885 null ] >>
endobj
3509 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 261.793 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 768.829 null ] >>
endobj
3510 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 250.834 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 757.87 null ] >>
endobj
3511 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 209.988 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 746.912 null ] >>
endobj
3512 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 199.029 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 735.953 null ] >>
endobj
3513 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 188.07 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 724.994 null ] >>
+endobj
+285 0 obj
+<< /D [ 3506 0 R /XYZ 79.37 702.177 null ] >>
endobj
3514 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 177.111 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 653.796 null ] >>
endobj
3515 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 166.152 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 642.837 null ] >>
endobj
3516 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 155.193 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 631.878 null ] >>
endobj
3517 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 144.234 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 620.919 null ] >>
endobj
3518 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 133.275 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 544.207 null ] >>
endobj
3519 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 122.316 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 503.36 null ] >>
endobj
3520 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 111.357 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 492.401 null ] >>
endobj
3521 0 obj
-<< /D [ 3484 0 R /XYZ 81.145 100.398 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 481.442 null ] >>
endobj
-3483 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F15 326 0 R /F74 329 0 R /F65 327 0 R /F83 403 0 R >> /ProcSet [ /PDF /Text ] >>
+3522 0 obj
+<< /D [ 3506 0 R /XYZ 81.145 470.483 null ] >>
endobj
-3524 0 obj
-<< /Filter /FlateDecode /Length 2414 >>
-stream
-xÚí[9+9Î߯p¸<­DQÐhÀ~n0qgƒMw£ÿu%—KnϱÀÕ]®’>Q$E‘‹Ÿþs⧟¿]>¿ýó&ÔÉ1§Aãéóßß½à'q2ŽIs2Z0®Åéó¿§_ß8×–sy£ Þ¿Kîè‰4œ+Á9Úx)ñ†ž ßþºR›Ëû¿>¡‘¬œ$P0DÇ
-hèÇjæ´
-m˜vC-½µ£ë{zt¡^ühÁ%>ñ£¶}êlýÓ2Á=•×w°o±-^â=È÷ïá& ÎsgÏ&i
-Äü€~àж'Ìí k3ñm» „ÌtúWß„»1}_Á#‹I˜Ú·ÙL-Ëþ.¢Ì îè:&¸Îƒ$o? h%¡.išgöõ9³°AW*2 ¢½N&É6^ÓÛ¤ÉaÒßÊè⦻ÂÓÜ6R´VT±÷52q£!¦ÕдhH„º§!¡í¾$nh‘IÃs»²:Â0 ¬0ø6Y¾sA"æÄL’ óê­`OJ4i‹¤u®ÊúîXog˜´”ÝoÄ(7+O<sßo•T„J.eɽ DÑú5cóš)xAAÂ/lÔ;ªz2 ®oQ~™D¹}·2ÍÕ•g¤ LãLy{N&*wBæ¬Ð2Ð#Ž ¸,’x¦Uü/VÚÈXãÉ’ 4ÙÕÇ‘°ÁŽ@ÑòW!x¶(PžÜÄ0ãµíœZÉxù^&ê„o+Ï¥'®NN
-ŽÏ5YÀì]$Ç©îU ‹ì4ȤÕ3vâÇ’ò H÷ù‰—b÷ãzK3k6¿ÀoÛ*-™ží‚?¼¸áÇýÑÿ:ÞkÉ\¢‘÷çjDŽò¾GBˆ>ËWø]÷àg©†ÚÎf¦`ÉìHÓð¡Ð<•O4:y– _%o¸~ÃëúBA™ânÆU}YÓ—)ÈØm‘*I­Ô”¨óš¨{ ]I/JlqFÂ1åÄlJrq]öH5ŒZ¥ˆ[¦ý‹ EK>â
-Z¾›LØJ5'.dcä¼T Oár&˜ž(ÕFá× ×)I³Ëq´šqr#8ŽŽD®¶Êsk"?ž¸Å=(¶6Ì4>P|ç0a .uʦ…Húšxrm‚Þ!<ÕðDp¨”dVN7ÒƒñSZøÐW½Ý; s»³^·»eNxÀ­ë³º*fÍ|7<6qC
-»cw 5ÎoÃÜé!v,í˜KÓ§zj»V¼¥N  Ôñêmæ¡/B˜kßËyùtx¼VZ¦'®]N@Hj)iAê‰Ób—3Ö#ÒdJQOI^ÌH÷@7ëá¦Ñ žYne”kÌlÊ•%‰¶Uhþ)¾ e!,ûnUš „©X©J#Óŵ6¥Xi.5Ã)¾·/¥ùäÕ×É;¤‰šcŠ:[¯ F7…+)ÏX“rMÕSìñ°ºt±yí0rÌiær]¨É >9¬°Âiv7Ïý@fWq_)ÔóþAfW Ʉ܈kÙp3̸©á:Ã¥%?"Í—ü"uV3+çi-ŠÚB¡
-ÔLêé
-]«º€Ž±û˜a¬ÈÕ³w±> › Kr8°9Ž·õk‹i!Ûw\ï7äs㢖ŒË€tOýç8õ~ïhÿoPÖ
-endstream
+289 0 obj
+<< /D [ 3506 0 R /XYZ 79.37 433.711 null ] >>
endobj
3523 0 obj
-<< /Type /Page /Contents 3524 0 R /Resources 3522 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3244 0 R >>
+<< /D [ 3506 0 R /XYZ 81.145 349.464 null ] >>
+endobj
+3524 0 obj
+<< /D [ 3506 0 R /XYZ 81.145 338.506 null ] >>
endobj
3525 0 obj
-<< /D [ 3523 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 327.547 null ] >>
endobj
3526 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 730.971 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 316.588 null ] >>
endobj
3527 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 720.012 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 305.629 null ] >>
endobj
3528 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 709.053 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 294.67 null ] >>
endobj
3529 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 693.113 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 283.711 null ] >>
endobj
3530 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 682.154 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 272.752 null ] >>
endobj
3531 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 671.195 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 261.793 null ] >>
endobj
3532 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 660.237 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 250.834 null ] >>
endobj
3533 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 649.278 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 209.988 null ] >>
endobj
3534 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 638.319 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 199.029 null ] >>
endobj
3535 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 627.36 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 188.07 null ] >>
endobj
3536 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 616.401 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 177.111 null ] >>
endobj
3537 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 561.606 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 166.152 null ] >>
endobj
3538 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 550.648 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 155.193 null ] >>
endobj
3539 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 539.689 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 144.234 null ] >>
endobj
3540 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 528.73 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 133.275 null ] >>
endobj
3541 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 517.771 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 122.316 null ] >>
endobj
3542 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 506.812 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 111.357 null ] >>
endobj
3543 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 495.853 null ] >>
+<< /D [ 3506 0 R /XYZ 81.145 100.398 null ] >>
endobj
-3544 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 484.894 null ] >>
-endobj
-3545 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 473.935 null ] >>
+3505 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F22 357 0 R /F15 326 0 R /F74 329 0 R /F65 327 0 R /F83 403 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
3546 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 462.976 null ] >>
+<< /Filter /FlateDecode /Length 2411 >>
+stream
+xÚí[Kä¸ ¾Ï¯¨cö0ŠDR/`Ð@×T÷{î[krJþÿ1Ô[–Un«ºv7r¨·-¢øIÑòòÏ‹¼üúíúñí¯ïJ_¼ð ]>þñMñyQëÚ‹5JH£.ÿºü퇔ÆI‰ïüƒ—ï(=ßA+¥VR’K?­^Àò} üwøÝxÌõåï¿ñLg3)R‚ƹ"…¹:„9­ÊX¡Ðí¨•émãùwKzL¥^ýìÿ‚kºfíßi« wëú• TÞ^ÀýHcéš®_¾Ç‹8¹,/6¡­P&
+†‰ãØ-aþ`ZWˆïÇE!¦óÿp ã©CØâÒfÎ0†Å—gÈêg¦ cvK+²¿Ë£$3KúE^(iŠÄ Ë;,
+Ø9¹ U+_rº\æ;Z÷Yø­%ÈmIh9NÎÉaÄÇɳÈõ^yÞ»ÌOfî'qŠm¬°] Ô'ß%%“K“«i1“¾ežÜº¤wHO <j¡›þÉü)þ
+^áŒ?gð"é-Ò×ôÏ0ÏQu6†.RÛ"×?s}ŽþiÍ¥›®ä\ì­P ÍñÅ€4Ó¿ÇK³Žî ?ãÍbyw@úšî!
+˜åÖ¶Zм×çhgˆjªy'·tÒ¼£¨i¦yƵbm<güô„Jq8S~Ñšà·Hçí¬ ‚NU×ìc‹ô0Eè¼ M3Šã‚i©”€–D;3´ª£qž¨M—ºÙmêÆOS~YÆ%÷Шœ"秾+¿ùãúƒÓ‚ÜHØéØ÷°H¥ ?='í–ðÞ:8;.ç5ýÎU‚8¾P<¾]Ÿ›öV8 M ­=
+õé!³ÐqNéqXQ]@9A–ÕoHsÌ
+¿—„~•mÍ}®UÎä¯ì¾Q`Ÿý£ %žnŽÝ ´<¿Os§‡Ø©µcr\Œv[êiãzñÖ>ŠÐÄc©Sõ•‡mÂüXû^Í+”ÃÓoÕyf
+Ñrz@úC“Ldƒ4“ …–+Ö#Òï—d"Ïh¦$/V¤·@“0ëÇÍ£%3óܘdTzÌ\®•e‰ö]há.ýÚB {öî4£(5R±Ò•Æ®K3"ìZ±òZZ…3Q|o_Êë)Ö·‘w,uÇmµA¬éWr±庮§ôƧÝ5`ªÏë§Á±¦YÚ]L¥¦øp°°Êiu·¬ýDeWËÐ)´åý'•]­P(܉kÙq·Âú©ã:›Ãe“‘æ&¿H3ÂáÔº³¨©oô@)´Z¸)ûÎfTÚ 8
+±¡[KJ:°;Žwík‹i#Ûïw\6’Sçr6ÈÍÎe@ºÇ§íç8íþèhÿ¿ ­A ¢©Ë[lkVø´Õ“ö^ç|ôjqÅ’V9wòk #R®“õÍ€ÑÖlD!P©í/å™À¡âÅ‹ë v a•éÓîȣёن’:ÝÛuß.ÒfêMî7*Í%»·¡F¹jש“ùýÛfDsV2vjz_>‹â¢%qmîéç3üÚ×}IJs&®§LZl
+Ùâkôâw'Z˜ýéb qñ$h ”ì©ÓËÉ'sá‹3“³Ñµ¯;Á¶ï ÷Z»bÏ´Ëý7Ÿ[gz§¬;M4[»{TäY0Ú\H
+o[°Ú”æíãÛ
+endstream
+endobj
+3545 0 obj
+<< /Type /Page /Contents 3546 0 R /Resources 3544 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3213 0 R >>
endobj
3547 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 452.017 null ] >>
+<< /D [ 3545 0 R /XYZ 78.37 808.885 null ] >>
endobj
3548 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 441.058 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 730.971 null ] >>
endobj
3549 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 430.1 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 720.012 null ] >>
endobj
3550 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 419.141 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 709.053 null ] >>
endobj
3551 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 408.182 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 693.113 null ] >>
endobj
3552 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 397.223 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 682.154 null ] >>
endobj
3553 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 356.376 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 671.195 null ] >>
endobj
3554 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 345.417 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 660.237 null ] >>
endobj
3555 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 334.458 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 649.278 null ] >>
endobj
3556 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 305.567 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 638.319 null ] >>
endobj
3557 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 294.608 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 627.36 null ] >>
endobj
3558 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 283.649 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 616.401 null ] >>
endobj
3559 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 272.69 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 561.606 null ] >>
endobj
3560 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 261.731 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 550.648 null ] >>
endobj
3561 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 250.772 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 539.689 null ] >>
endobj
3562 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 239.813 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 528.73 null ] >>
endobj
3563 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 228.854 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 517.771 null ] >>
endobj
3564 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 217.895 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 506.812 null ] >>
endobj
3565 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 206.936 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 495.853 null ] >>
endobj
3566 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 154.134 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 484.894 null ] >>
endobj
3567 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 143.176 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 473.935 null ] >>
endobj
3568 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 132.217 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 462.976 null ] >>
endobj
3569 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 116.276 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 452.017 null ] >>
endobj
3570 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 105.318 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 441.058 null ] >>
endobj
3571 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 94.359 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 430.1 null ] >>
endobj
3572 0 obj
-<< /D [ 3523 0 R /XYZ 81.145 83.4 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 419.141 null ] >>
endobj
-3522 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F83 403 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F30 333 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-3575 0 obj
-<< /Filter /FlateDecode /Length 2455 >>
-stream
-xÚÕ[9c7ÎçW(ô¦Éâ ¤VËÀÆN½ÑþÿtyŸõÔd[=ðoFz"‹uó«"›žþs¢§ßÜ>~üö`òd‰U Äéã¯Ìý@Oì¤-áú¤#T±ÓÇOœ)o”Jvã>k î—_¹õß„ûƵûf„û¦¬ûöpø7Ò¾»1îaŽ‚0ù­ro”ŸéEó[?ÓS€ƒGy;­"Ôô9ŽÓêòçÇ¿|Z`òÄP;J¨'Qž@\K`ÑVTüL§§¤ „æ¡p‹3ƒŠ¡ûI²¬b|ªZÜ£t^ŽÆy^õâVǘ@!3Gd:ÁD÷–ª™ñ$H5¤WÎà2ÂFUQ¨_ÙĹ2Ž§Dzÿsÿþî+íIk‡V±ˆÓ´æ’0iŠZJºÇós‹´’'ÿö0âdœ7-F5áFJÙ]%ÍŠjœ¬-ipÃÅQGÑ¿LÃ[O”ùïþÉߪuƒ-6µ‚0kQ­]×´ÆÑR”¼½lÞIs G~¹ŽFK—·¢Õ—àìÑÿ’ì2ò4ü
-2­äµšt0Ý×8Ü÷çºÿßcìÉ-=©šO›6bœ€ÀLÄ힉:B½¿oÏôñ¹.yÊþ}Ѓil™Þ®ù
--Q `ª&³§¦ž¦'/Göð觨,{(Ë@cQne°RŒŠ692”p…ºžKYM,˜‘ÐÀÐs\¡$'¢aÂ4›ãÉ@ÁM6JÚØ îîÓ†4Z%„áÍè]3§’°•1ÑÎ5 ƒ„•€§Ý6..0¸úéMNNo»}8ÌÞ!V:5Ìꀑ¦F¥hwrš¸¸Åqþw­âû<'((dܧæ”» ?q Á¯ £è$Φñ9negÿUð
-ŠõXºŽÉäy[ý–yïèê|µ:¾×g4¦ÿÕ&V:c(A¹_Q»!-Ô gG$£áHbÎ0;Ô¯j‡[EL;‹Ý¯Ô¬m–re‰{œÂ°ÓRƒ–Öÿ^•Û×BçöVKýééj©lŒè¢p’FN‡ôù
-9ȇ@ô2lÓq•’K?b7q)‰œo_·lÜú›¯¹z±©
-!ˆŽ©bµ}—ŽFJ´‘枯‘•PÖTøƒ:²lp ‘L æXo˜žz0RÛ·YǵA»—ªvxxÑáŽ
-¢æëÁBfËY{BSB8NH`!\žÌç{[]“ëº]ÍIJC®ºXuη!y kBd\8”«ˆSü›ˆ[Ò˜PIÄϳ‡õâhO ?Þ„XW5¸´+8 yAî¨z ô÷ò\[ýÕfñx7`ôÕùHC„F3Äj33eˆÒñåÂÞcÚVqvz·a ®´’ #¾'GO©vöê¥Æöz£ø¬Ô ä³ÓRú¬Â#Æߺ6ÇH;è/_E®ˆ”³ÁæAõHiéP¥‰ùxe8ô(Wm>숖dTÒ''2"Á,ôôãøDᧇ¡Ÿ¸ý8³t{»x?èÁÛ×hÂÝr–3aOèëžC-Qeh±hÉ õ„¾!5¿5}_†ÜÙûy©›YC”Õ˜Ò6oÓ”~rêfF=ôײ×=9zJO¹ÝäQ»šX[ŒÇU ,ÜÈ(5^qÅïÐÿîŒ0%‰†J¿xZ®81œ”âö#Š”ê›;9ÍiÖMmù?ER€úóâÙµ£ ˜)¡÷ˆ^§­M)'–rTJ±'eO©JîHï¢|÷’X!P_å[ÝúRs#Iµ×Óßÿœ‹ýí¿÷ñ™Âç»I‚U•sMO©[eñ«ö+ƈÃB£\Ö;Ã9Ï”þ‘ððÞ_ÄÁ.øÿŸÃH·
-¡JcÝCm¡/ÃH áà
-endstream
+3573 0 obj
+<< /D [ 3545 0 R /XYZ 81.145 408.182 null ] >>
endobj
3574 0 obj
-<< /Type /Page /Contents 3575 0 R /Resources 3573 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3244 0 R >>
+<< /D [ 3545 0 R /XYZ 81.145 397.223 null ] >>
+endobj
+3575 0 obj
+<< /D [ 3545 0 R /XYZ 81.145 356.376 null ] >>
endobj
3576 0 obj
-<< /D [ 3574 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 345.417 null ] >>
endobj
3577 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 742.926 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 334.458 null ] >>
endobj
3578 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 731.968 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 305.567 null ] >>
endobj
3579 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 721.009 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 294.608 null ] >>
endobj
3580 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 710.05 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 283.649 null ] >>
endobj
3581 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 699.091 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 272.69 null ] >>
endobj
3582 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 688.132 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 261.731 null ] >>
endobj
3583 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 623.375 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 250.772 null ] >>
endobj
3584 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 612.416 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 239.813 null ] >>
endobj
3585 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 601.457 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 228.854 null ] >>
endobj
3586 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 590.498 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 217.895 null ] >>
endobj
3587 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 579.539 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 206.936 null ] >>
endobj
3588 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 568.58 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 154.134 null ] >>
endobj
3589 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 557.621 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 143.176 null ] >>
endobj
3590 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 546.662 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 132.217 null ] >>
endobj
3591 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 535.704 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 116.276 null ] >>
endobj
3592 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 524.745 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 105.318 null ] >>
endobj
3593 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 495.853 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 94.359 null ] >>
endobj
3594 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 455.006 null ] >>
-endobj
-3595 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 426.115 null ] >>
+<< /D [ 3545 0 R /XYZ 81.145 83.4 null ] >>
endobj
-3596 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 415.156 null ] >>
+3544 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F83 403 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F30 333 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
3597 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 404.197 null ] >>
+<< /Filter /FlateDecode /Length 2447 >>
+stream
+xÚÕ[;ok7îï¯P™-ÂÃ7 ,+ÀÖî‚´Ùjÿ»|?çȤ#_d YÒ9œ7¿ÒôôŸ=ýþãöñã·“'K¬%Ný`îzb'm ×'­¡Š>þ{úãL©x£T² ÷Y¥p¿üÊ­ÿ&Ü7®Ý7#Ü7eÝ·‡{"ýè»ã^ÌQ&?Uî‰ò3ÝKÑüÔÏôã`ãàQžN«u}Žã´ºüùño'Ÿ˜| 1ÔŽêÀI”'ЇD×A´U#?Óé)i¡y(ÜâÌ bè~’,«Ÿê…÷¨
+2­äµšt0Ý×8Ü÷çº÷÷;AòGKOªæÓ¦' 0©Ûž‰:B½¿oÏôñ¹.yÊþyЃil™ž®ù
+-Q `ª¦ëžšzJ˜ž¼Ù㟢²ìI ,#
+¦Â½iTÁbsô”$/œVLçåó:jåÙãWZN”AëÎ×øE˜†‘gs%R-¤ *Ȱɹ{Óc\¼¯1îŠeMÍ@(‚<yåvþÄJå¨KUÕPñ!R7`[F͈Ö=~õ\"Ý£‘’š¥\Œá2^‹¹ÊÈ›v®yÂnccúvUCÖŽñ¯òÍ_¡Î†Ÿ•žÊ°Í溨ݜá­P¶þU䃩o°ÝnO"†fÕê^Z€”ª«7eŠëÜ9‡6’cÜ­¶™»Ò«½eS.nˆ±•k±Õn×ròŒ”¾è­ÙóZ¯Åê†üœCE~­Löžžõ+5\ù_hSû8aÇò±ðÖÎò£Fþ&ûÞR"fÓ>à´Ë%fŸÕ:;Û§§ôŠˆeŠX­PÞÌâ6!‰3ÙH ‹X,ÿ£;]¿[?/×%B9 åzÄÚ÷¾:íºÅ·jå¦k|T‡ø÷²ökrõ”O¦´SµgeDr8Í…“„„Š3Ór©0ÎÞ>Ç„ç&ý7%»€[C¨Accpg|5PâjÆWpýi]?C.R-ø¤Ðœ0ÁPŸ´âÜtpn­™ó¯9†<5œŽè|:bE5éSŸµ¾fFžB©7Žj ¤®x~øÄ 0>®ZZv:Š[•ü™¬\*¢í$+¿a2=åŸ;ob¡
+ëÚ<#í  ¿| ¸"RJÔ{Õ#¥¥C•&6æã•áУ\\µù°#Z’QIŸœÈˆ³ÐÓã…Ÿ†~âBXôãüÍbÐííâý l¬BƒžoežÐ×=‡Z¢$ÊÐbÑ’ê }Cj~kú¾ ¹³÷óR7³†(;Uzþ}ó6ý@é'§nf4ÑsÍ¿¯ž€g9zJO¹ÝäQ»šX[ŒÇU ,ÜÈ(5^qÅïÐÿîŒ0%‰†J¿xZ®81œ”âö#Š”ê›;9ÍiÖMmùER€ikõìÚQL”Ð{D¯ÓÖ¦”‚K9*¥Ù“²§T¥ w¤wQ¾{H¬¨¯Ê­ný@©¹‘¤ÚÿëéïÎÅþöÿûøLaçóÝø¾—kzJ „Ü*‹_µ_1FB=†ïåùÒ?Þû‹8ØÿÿséV!T¡
+endstream
+endobj
+3596 0 obj
+<< /Type /Page /Contents 3597 0 R /Resources 3595 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3213 0 R >>
endobj
3598 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 363.35 null ] >>
+<< /D [ 3596 0 R /XYZ 78.37 808.885 null ] >>
endobj
3599 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 352.391 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 742.926 null ] >>
endobj
3600 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 341.432 null ] >>
-endobj
-293 0 obj
-<< /D [ 3574 0 R /XYZ 79.37 304.66 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 731.968 null ] >>
endobj
3601 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 277.2 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 721.009 null ] >>
endobj
3602 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 266.242 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 710.05 null ] >>
endobj
3603 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 255.283 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 699.091 null ] >>
endobj
3604 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 244.324 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 688.132 null ] >>
endobj
3605 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 233.365 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 623.375 null ] >>
endobj
3606 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 217.425 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 612.416 null ] >>
endobj
3607 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 206.466 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 601.457 null ] >>
endobj
3608 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 195.507 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 590.498 null ] >>
endobj
3609 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 184.548 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 579.539 null ] >>
endobj
3610 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 173.589 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 568.58 null ] >>
endobj
3611 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 162.63 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 557.621 null ] >>
endobj
3612 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 151.671 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 546.662 null ] >>
endobj
3613 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 140.712 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 535.704 null ] >>
endobj
3614 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 129.753 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 524.745 null ] >>
endobj
3615 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 118.794 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 495.853 null ] >>
endobj
3616 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 107.836 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 455.006 null ] >>
endobj
3617 0 obj
-<< /D [ 3574 0 R /XYZ 81.145 79.94 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 426.115 null ] >>
endobj
-3573 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F27 332 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-3620 0 obj
-<< /Filter /FlateDecode /Length 2161 >>
-stream
-xÚí[ÉŽã6½÷WøÂ!«¸ƒºÇv€œûäšœòÿ×).*¹YêY`౬å©X km)Ì埋ŒÿÿþôúöôénÂE‹àÂåíï'u‘ñŸºxV_œUBZuyû÷òçg)íküh) Äï—ç¿Þþx’ ,B}º{}ñ"X‹¾ÅQÒ Ô0"iQ””Õ—ôûù7æóz&]±×x6~l(WP—#Öw7KygF
-%ZÞ:z$t™ZYhK+Ó°ÒŽ°]δ¿ÒSÆ÷G¤íc¶û¯™K¯-¦±Ïî ÃÁã{L=ÚÞ„™>¸sùŽA($ß=ïRâ N|¯Ü³!~»E3wŸ>Û/Ý?eo+âÂÿø¯¿´[žðë ÖO:^¸‚ùx'É|FC•\z[åx²Š Kèï3‰¦¤‡·F3˜r/T
-ð$H³ê’½~&þ.:“­±JÛdýHW×++Ïáe”Ȫ'åT«.š¯9»jä¨hó9ßÙóûöÎc¢õA m|È2¾è;ïÝÖyŽôAúÆ[Fôƒ÷n&¬Zí<Xúv<6 õ¾#­]Kû¡°_Ws„ÛÑu¤nä‹žTŽËÖÏ4íËvGÖ²e_N<¼<&åVÑêQBÁ{Ù˜¸20Vhƒ” â¦d€RxF¤¯è±™+ÒFè ©Ù×¹ztzã·¨…ACRÄ‹8¤ó
-ã,E3v‘~ÆæZ½Yú½pmðh¿x¬cUüRž”§ç„Р`ŸîÊ\B|â;›‡]t¥îb<
-U|Ù–žCðsÒ¾8Ügpi…†ñ¯íÝ„®„4IéŠËZ¯êº%~º;MÑ #Õj¤þH±0‡>é]åݤòôŠóˆ{q¹ÂJ3R°8Ø–÷4ý¨£äô4ýéÜâz¾í:¦Ž&n‘£ìÃ(û(…EÖ‹D_Ÿ—sìr7†Á%qFŸ^=(™S¹.ç£D¬ùWGÐrÆ]·Xõ{•¶ÂZ?¾·¨ÁŠP÷™&*zÄ6Í-ú¸uÛ1d«Ìi§ŠŒòŸë6–œÎb¶E¦°çhÉ›Ìeûô´‡qOp;lALB³oëÖ›~'ôò¦åSi~¨U2ëÕøÆI‹Ð(æ>¢wrŸÓ^ ´8"ÏÜ®!øòRÓèëd‚›oÌ^81ÇÜ+ûñ5Ÿ3U‚xÏuV0ë½ïÛÝ ïitžŽ'ó HÇYeͪj4ÜDE/tÞEæ'‰÷õS#kÇëMtATÃj6Aå6TÖÁÌf>¶Yœ‹ záé\€Y.H6ü/Yb[=-Aˆ;;1+%Ò±çB¼½”sÞÏ\Ÿ²"™Ø »2 }犖‘VHå¨uÌÖÊ:z¤ãuP¡ìVÿºŽšW×–îY‘JvÉ\«&žZël…!¯u@ú>Õ»‰Øõ¬µj¯… ä ¯Ò1 =ªèqíõÃ6«
-¥µÊÙêI®0H}%\íQo²6ÛëšXÍÕáº÷õ\ò.–ð$=-›„ò@òo²ƒ¦£ÝHµC"ùwv?'öIæ:
-!.6Ú˜Ž™«LÃÍXooOÿËPb
-endstream
+3618 0 obj
+<< /D [ 3596 0 R /XYZ 81.145 415.156 null ] >>
endobj
3619 0 obj
-<< /Type /Page /Contents 3620 0 R /Resources 3618 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3244 0 R >>
+<< /D [ 3596 0 R /XYZ 81.145 404.197 null ] >>
+endobj
+3620 0 obj
+<< /D [ 3596 0 R /XYZ 81.145 363.35 null ] >>
endobj
3621 0 obj
-<< /D [ 3619 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 352.391 null ] >>
endobj
3622 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 341.432 null ] >>
+endobj
+293 0 obj
+<< /D [ 3596 0 R /XYZ 79.37 304.66 null ] >>
endobj
3623 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 277.2 null ] >>
endobj
3624 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 266.242 null ] >>
endobj
3625 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 255.283 null ] >>
endobj
3626 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 708.057 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 244.324 null ] >>
endobj
3627 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 697.098 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 233.365 null ] >>
endobj
3628 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 686.139 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 217.425 null ] >>
endobj
3629 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 675.181 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 206.466 null ] >>
endobj
3630 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 664.222 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 195.507 null ] >>
endobj
3631 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 653.263 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 184.548 null ] >>
endobj
3632 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 642.304 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 173.589 null ] >>
endobj
3633 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 631.345 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 162.63 null ] >>
endobj
3634 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 620.386 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 151.671 null ] >>
endobj
3635 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 568.58 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 140.712 null ] >>
endobj
3636 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 557.621 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 129.753 null ] >>
endobj
3637 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 546.662 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 118.794 null ] >>
endobj
3638 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 535.704 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 107.836 null ] >>
endobj
3639 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 524.745 null ] >>
+<< /D [ 3596 0 R /XYZ 81.145 79.94 null ] >>
endobj
-3640 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 513.786 null ] >>
-endobj
-3641 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 502.827 null ] >>
+3595 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F15 326 0 R /F74 329 0 R /F59 338 0 R /F84 404 0 R /F27 332 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
3642 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 491.868 null ] >>
+<< /Filter /FlateDecode /Length 2161 >>
+stream
+xÚí[Ioë6¾çWø”!g¸A€8¶ ôœ[Ñk{êÿ¿–”HqÑÈÖ(yP<øYÖò‰³pöHaNÿœdüÿ÷§óÇÓóÍ„“Á+„ÓÇßOê$ã?uò ¬>9«„´êôñïéÏ)í9~tü¼Iiàõ¯?žd‹PÏ7¯O^kÑ·8J:F$í#‚’"¢zO¿_3`^æ3銽ijñcC¹‚º¹0¿»!åF
+%¢ÃžytôHèòjeY[¢Lüv„åìt¦ý•ž2~¼?"-ϳÜÉ\:·˜Æ.<»%<·ï1õhyæõÁËw Bi$ùþÆãû€”8˜dåž ñÛMÈ+‚OŸå—×qâü ‰×ï­Ä¦'ü|'¨ù“Ž'®`>^I2Ÿ‡‘ÇP%—ÞV9žvÅŽÐßgÒš’^Í`Ê ¼PQ
+ñaˆïlvÑ•º“ñ(TUðÅ,½þ†àç¤}q¸¯à’…†ñçöî{a BÈ
+WBš¤tÅeÍWu5‰Ï7§©µȸj5®~K±0‡>é]åݤòôŠs{‘\a¥W09Ø–÷ôúQGÉéÝëOç&×ó5k×1u4ÑDŽ²£ì£&YO=¿Nç :Ùé$. -‚KâŒ>;½zP2§„s]Î=F+ˆXò¯nAÓwYbÕ{ìUÚ
+kýøÞ¢3Bµ3MTtm*n·èãFÔÅbÈV™“¥ŠŒò/ÕŒ¥
+=Ò6T(»Ô¿.£æUÚÒ=3RÉ.™´ê`b€±Î¶üþ
+C¦u@ú>Õ»±ëÑݪ½2Š3ÌJÇ€t¯¢ÇݯŸÞ³Ú¡PZQTî­žä
+ÓˆÔWòHj·‚x“µÙ^æÄj_=.kQÏ%ïb OÒóвùgA($ÿvvÐtÜ7R­Hþµç„dÒi”
+Â)KZÓOtÜVK/œqäŠxÕ£éðŠ 8á‚'u˜Wï‘övÞ™ëõVx$ã‰ÝŽÊÁˆô­:ÿ´¬Î>Ï7ÝþuLdÏuNw0eäŒðk•ÒŒ/‹¨¦¾Õ¤¿!ý¦0­Å¬XP”8v¬¹¹7
+åx5q9|éšf¥¾ÈM/óQÓ>oÒ¼rvÄ,öÂYz²*IzHy0™g¤
+endstream
+endobj
+3641 0 obj
+<< /Type /Page /Contents 3642 0 R /Resources 3640 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3213 0 R >>
endobj
3643 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 480.909 null ] >>
+<< /D [ 3641 0 R /XYZ 78.37 808.885 null ] >>
endobj
3644 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 469.95 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 768.829 null ] >>
endobj
3645 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 458.991 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 757.87 null ] >>
endobj
3646 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 448.032 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 746.912 null ] >>
endobj
3647 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 437.073 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 735.953 null ] >>
endobj
3648 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 426.115 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 708.057 null ] >>
endobj
3649 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 415.156 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 697.098 null ] >>
endobj
3650 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 404.197 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 686.139 null ] >>
endobj
3651 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 393.238 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 675.181 null ] >>
endobj
3652 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 382.279 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 664.222 null ] >>
endobj
3653 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 371.32 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 653.263 null ] >>
endobj
3654 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 360.361 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 642.304 null ] >>
endobj
3655 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 349.402 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 631.345 null ] >>
endobj
3656 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 338.443 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 620.386 null ] >>
endobj
3657 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 327.484 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 568.58 null ] >>
endobj
3658 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 316.525 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 557.621 null ] >>
endobj
3659 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 305.567 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 546.662 null ] >>
endobj
3660 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 294.608 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 535.704 null ] >>
endobj
3661 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 283.649 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 524.745 null ] >>
endobj
3662 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 272.69 null ] >>
-endobj
-297 0 obj
-<< /D [ 3619 0 R /XYZ 79.37 249.873 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 513.786 null ] >>
endobj
3663 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 228.391 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 502.827 null ] >>
endobj
3664 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 217.432 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 491.868 null ] >>
endobj
3665 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 189.537 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 480.909 null ] >>
endobj
3666 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 178.578 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 469.95 null ] >>
endobj
3667 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 138.727 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 458.991 null ] >>
endobj
3668 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 112.824 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 448.032 null ] >>
endobj
3669 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 101.865 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 437.073 null ] >>
endobj
3670 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 90.907 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 426.115 null ] >>
endobj
3671 0 obj
-<< /D [ 3619 0 R /XYZ 81.145 79.948 null ] >>
-endobj
-3618 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F22 357 0 R /F83 403 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /D [ 3641 0 R /XYZ 81.145 415.156 null ] >>
endobj
-3674 0 obj
-<< /Filter /FlateDecode /Length 2554 >>
-stream
-xÚÝ[Ën$+Ýû+êš"xIVI®[öH³ön4Û™Õüÿv‚WòH2 lׇZîªÊ$Á! É™ºüóÂéÿ¿¼Ü>_~(wAæ¬
-S{è3õAæÑ×é¥{Ýgr<1tc©wUo)¬ÑÀy¥éDWPÃÓ4Ê:( ž¬×ØOȽ]¡eñ‰ÒŽìKñJæ:þšä:—>e4—òžžß®È4%föþ–îÀUÏN4è! (%ºgÁâìΉØ3.áŽJ¥3ƒaüÜkëöìaò m¯V¦iÏÀÀµóÓd3ÂñÞŽ }/þUFT*‹»¶šuÉÝ.MìR˜.E´4ößìºQžÛr27þ4ÙǸ·Ø<£Â0Ô«¹Ö ÍŒ2‚-¶êÍÉ>QGuy_µV#C3V&8g.(¦¬î‘@앃RµåR7–ó­³>šö”
-¦Ñ6nPÌß°à‹#YÒaéý7ñž¿·¹Ç:á
-˜cYk„·H ÿG_'{‘a/¦ŽÆ÷I±­™0²G’fB0jAaÐmÏà~Nº†h’4„0×ú øû•Œô3;˜\.ÏOyÎ=‹YíD̬^â¯}9Þùº=:Ê’œ@z¤aJËsÄMbl‡g)Ä×<G…
-G«hIëv5ÛÅq¯­XìnØc™B&eE t¬*ä-«°¤$æú¯ÌÒ‹í³‚Y)F TrIYtHO’Êpf5ŒìÕ·¥H×!¤…|kj1¶©^¬ÆÉ#™Ðß]gQÑá8dñmÅi¤Y”q&(ù¬µ…1ù¶ÇÊ+«Øøð¿÷XEETÌñEkyF¢ÕˆçÙt“& ¡C:ò2À/ûA®¿²î™ÑdÈ»>Zä ÝÒC®í’Bë’B[°DFO G—Z -ÒIÔ¨¢„ïß¡ >Uú»—ߊ4raµV }þ±÷™5l¥'41­Rw%rÙ*sçô¤
-%·l\øÕä
-[T‡Œ¦ ~pû$7v?àÆnœs÷kõrÌ¢X•õs¡j½;%0Ä]* `9•Ö!wgºSN±Îr‡ãzø[h3)FÜïJú6/f×:¤nÂüï÷´EÞ¸`
-F´M'ù8³Æu@OÎö€£RûmÏ`öÛ’ÙRe÷×&¨Åv"ÓûÝDߎ٬UnG‹ôlþµezì6³ lw‹tÌÿ×9V¦ÞÑk|E­ÙÚ"=›c¤ùÔÐn\³»Ee4N˜,Dµ¯Æ7ðíÃÑ¿(ò:¤Ÿo9VÏ)W°×@8fÕp†˜•f)®uH£SÃ(ÖÆ)^Ç©6£¬oƒ¾ý®gü9»À-³n7Ÿáû¼bJí©ØýWHÒÑR[»QgR5ÒšóôÃB{郋Qsg•M8-Ðÿ¹”F0âHÛš²êž<‚¥æŒ;9²{QIuH²"”蘀áL´¨¬:¤gó–æ?úÍšÊêŒ)x™Ú{ýæ~¨”’I5lúZ°úÞ¼šw^Ö=P&Ýp˜UWyâl‘†ç¿¦.[Ä9Î ³*ûf‹ôä1%¬Ï×7c*æpæUI²»C:<9cž¯ùÑÈuš)û‰³¤þýjÄà¬æÉ ¶HÏîym*=²{1-Ó!=a}-”fèÌÐÖ5ÅÐ!=›cTLÙ½¨:¤iŽÏO]øY´Ê64ûÛœ'V¶ØÎEˆþL-ç³g„óÛáˆß ‰‰·rŠJØ6½ýäwŽ†¶-ž:
-ÛN$o­ñÞ±Üvß••M8gpÀ®Â´¯*pû½o”õ·Û¡žØûëCºyÏ>L¯]Ãð‡ÄùE/"ö¨±ÃÍöª[ÕA)-vaE:²²%
-Ó¡žþîF±€×âþq7qᜋz(Äù™Ž³„[jhµT¬zç½¢>ÛŸß8 Ôí-äÒÛè eÃìk½â¿w(«þY´Gï$ŽN«„“Ó¸z¤f;a!Sß
-endstream
+3672 0 obj
+<< /D [ 3641 0 R /XYZ 81.145 404.197 null ] >>
endobj
3673 0 obj
-<< /Type /Page /Contents 3674 0 R /Resources 3672 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3244 0 R >>
+<< /D [ 3641 0 R /XYZ 81.145 393.238 null ] >>
+endobj
+3674 0 obj
+<< /D [ 3641 0 R /XYZ 81.145 382.279 null ] >>
endobj
3675 0 obj
-<< /D [ 3673 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 371.32 null ] >>
endobj
3676 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 360.361 null ] >>
endobj
3677 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 349.402 null ] >>
endobj
3678 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 694.158 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 338.443 null ] >>
endobj
3679 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 683.199 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 327.484 null ] >>
endobj
3680 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 672.24 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 316.525 null ] >>
endobj
3681 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 661.281 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 305.567 null ] >>
endobj
3682 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 650.322 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 294.608 null ] >>
endobj
3683 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 600.549 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 283.649 null ] >>
endobj
3684 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 589.59 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 272.69 null ] >>
+endobj
+297 0 obj
+<< /D [ 3641 0 R /XYZ 79.37 249.928 null ] >>
endobj
3685 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 578.631 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 228.391 null ] >>
endobj
3686 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 567.672 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 217.432 null ] >>
endobj
3687 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 556.713 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 189.537 null ] >>
endobj
3688 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 545.754 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 178.578 null ] >>
endobj
3689 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 534.795 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 138.727 null ] >>
endobj
3690 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 467.073 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 112.824 null ] >>
endobj
3691 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 456.115 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 101.865 null ] >>
endobj
3692 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 445.156 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 90.907 null ] >>
endobj
3693 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 431.216 null ] >>
-endobj
-3694 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 420.257 null ] >>
+<< /D [ 3641 0 R /XYZ 81.145 79.948 null ] >>
endobj
-3695 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 409.298 null ] >>
+3640 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R /F22 357 0 R /F83 403 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
3696 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 398.339 null ] >>
+<< /Filter /FlateDecode /Length 2554 >>
+stream
+xÚÝ[Ën,)Ýû+ê.ˆà%Y%¹ºì‘fíÝh¶3«ùÿí¯ä‘dØ®ž‡Z·Ë™I‚C@’3uùç…Óÿÿòrû|ùý¡Ü™³äåó/âÂé?q±’i¼-×âòù¯Ëß^9×7ú‡œp®äõïŸ}ጠ~X¼Xæ´[ã)î‘PŠ¹þRRÑ•¼å¿ÄÝÇ|¥îû¿´£¾!àvW~$Ì[üÕ.?)hÇe”Û[ñý[±m8Sœ .GœéÛgÜ0@Ù#uýþêâèmI•VoÇÀ\ ñ.•Íï*ù–6¶’Ð4=Ñ2¢KâS:lXNuYÕ%P2å°¯ -ácÄ„[B08DЖqÕHOÖ{ú%ÅÑh¨åió¥ÌÀÞ¤øf"
+‡ ã¤ØÖLÙ#I3!µ 0è¶wð?']C4IB˜kýüóJFú™L.—ç§<çžÅÀ¬v"fV/ñj_gŽw¾nŽr„$'i˜Òòq“…ÛáY
+ñ5ÏÑE!€m®¸Ùsˆ÷2ÿ§r•âð2Y,k¦:©Þõ*RÃ[¤ -à¥xÛR¡§7©t Ö%0§ GÍ-ö½›£ð ?Î|P¹Š*íSßÚä8sRîÞÜ ¯DS/ËèÓ>Š>Ð[§ÂÑ*ZÒº]ÍvqÜ+G+;Œd°$+Z cU!oY…%%1×e–^lŸÌÊa¨Æ÷%eÑ!=IZ(ÙÕ;%„ïeNŸŒtÒHZÈ·&¡c›ê%Ájœ<’ ýÓu Ž#gSG™Åi¤Y”q&(ù¬µ…1ù¶ÇÊ+«Øøð×{¬¢"*æø¢5‹<#Q‡jÄólºÉ
+­CJ
+mÁi½5²dvµ–ƒF‹t5ª(áûÁ÷Gèˆo•þ®Æå·"ÜFX­CŸì}f [é ML«Æ]‰\¶ÊÜ9=©BcÉ-®š`¸3¥Bù¬î”Nuº3ÞÙ×ÛëÎd_§;›6œe‘
+;n¾yêÀçu
+Ü~ïe}@Åív¨'ö~ÇúnÞ³ÏÓk×0ü!q~Ñ‹ˆ=jìp³}êVuPJ‹„]X‘Ž¬lg @„â¡Ât¨§ºQ,൸ÜÇM\øç¢
+±D~§ã,áV‡Z-«Þy¯¨Ïöç/Îu»C ¹ô6ºhÙ0ûZ¯ø¯ÅʪíÑ7‰£Ó*áä4®©ÙNXÈÔ7
+8#ŠUç– -óI&„<?A&¶°þ€úÀ(+ȨÞ'ºeÅaÅÎ0}ÍËÇ+ÂAw5 ÑkŸ¶@ç_>˜‡›úù+KXÍÊ…£ñC¡·x€µ:naö¢+Ýn­XιçÖñâÿ~„Þ9ý:„<@“þDÎ\õQF9þþþùòo1Œc©
+endstream
+endobj
+3695 0 obj
+<< /Type /Page /Contents 3696 0 R /Resources 3694 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3742 0 R >>
endobj
3697 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 387.38 null ] >>
+<< /D [ 3695 0 R /XYZ 78.37 808.885 null ] >>
endobj
3698 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 376.421 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 768.829 null ] >>
endobj
3699 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 365.463 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 757.87 null ] >>
endobj
3700 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 354.504 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 694.158 null ] >>
endobj
3701 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 338.579 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 683.199 null ] >>
endobj
3702 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 327.621 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 672.24 null ] >>
endobj
3703 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 316.662 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 661.281 null ] >>
endobj
3704 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 300.737 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 650.322 null ] >>
endobj
3705 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 289.778 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 600.549 null ] >>
endobj
3706 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 278.82 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 589.59 null ] >>
endobj
3707 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 267.861 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 578.631 null ] >>
endobj
3708 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 256.902 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 567.672 null ] >>
endobj
3709 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 245.943 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 556.713 null ] >>
endobj
3710 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 230.019 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 545.754 null ] >>
endobj
3711 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 219.06 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 534.795 null ] >>
endobj
3712 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 208.101 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 467.073 null ] >>
endobj
3713 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 197.142 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 456.115 null ] >>
endobj
3714 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 186.183 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 445.156 null ] >>
endobj
3715 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 175.224 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 431.216 null ] >>
endobj
3716 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 164.265 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 420.257 null ] >>
endobj
3717 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 153.306 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 409.298 null ] >>
endobj
3718 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 89.593 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 398.339 null ] >>
endobj
3719 0 obj
-<< /D [ 3673 0 R /XYZ 81.145 78.635 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 387.38 null ] >>
endobj
-3672 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R /F81 366 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-3722 0 obj
-<< /Filter /FlateDecode /Length 2411 >>
-stream
-xÚÍ[ËŽäº Ý÷WÔ\Dê \4Ð5Õ ëÞÙ&«üÿ6’,Y/Ú%yz’‹AM»Êö1IQÔ9’Ì™ºýûÆýÿ{»½ýx*w“ÌYpûú×›¸qÿOÜ,0-oF Ƶ¸}ýçö?9×wÎ97ÎË÷~ýý0õãiåÍ2§5ÚGpÃPB„†s%<
-ÿC
-ØŸùùÈÈ|$Áõ7%9?·cÍýòY¥v¤§lOÓŸþã¶{Àû m8·ß£ë{”Ø|«Bõ"NŠ3ÁŠâ\œ„fF™IFëK<¼}Þnå—E>»'‹Ío™ŽcŒÜöׇ"žS{4Ã|æ;V=GÇ„DÊsù9ç9h& ôH´çÿÈóàm̻Ǣɰ’
-›h¹”A>2UVüÜŸrßr(ÜÁÛçˆO[[Ð~-â`™ð¡ì"r¸¹ˆ£bÊêéeÖ”¸×ž”Ø­z" P”'
-Ör§EŠ^ØìѪU\3К²Jß×âÛ"µ}”¡VźfK‹TéŽïúŸçmþõBÞŒ^îg<ÛM;ŲÝ>–²©Cºn‘•~ìs”Eè–F…éºEÒÙ5ƒ k£TÝþ¡R‡‘7"ÝKŽR§[²>`üPŸ
-2“ÕZ3µHßÓNsJµß¥cþ×m+ÚÞïl/%˜4@¶—\k¯é"ûK,7Äó›Xž–þ*dáÀµÚÚ"嶉 ݵ,ïc;‡<Ëý.xs|O‰Iõx•_Ÿµþ8|æ÷Œœ‹qÇ”"¹Ý,›Î™Ô"]Ïma™rG gÙfR€RgѧP7çïÿÐênãzo82ß7ö¬ù5ØyØò›,O¨)TÂ;<ÀÚMVÆ„¼Ÿš%¤aΧq‡PËÚÁ ô‹ï|ÑðPæä};å.à®fC­{ÿCJòˆou`9ò(×b…<"%*E¨s\Œ¤ÜBÌyõÙ¹EŒvgÁAßh¢G ¡ÕI}šÔw?c7º÷2ô¾xç£Tï¨Ñíb&+çÿ8 2yVm¤LîbÚˆÍâm¬Ü+ÇÏÜÌÛœC;ò \õÀ
-f)f•Iª’TÄhûyd8WUæE gÆHÒ‡%uÕ!µ³>47»Ýj×ÀOøÅ~N5¿`HN«²­Re|ÅÖ\gçc¬³BS1žÕR1oBTÔç¤ÝK1žl·ÅXHˬ2d,ìZ,Z¤µX(¸Ì fý`EõµÖcZ$ fÆ´hf‚W‚n­öJô~£Šïñw¸ÜÞCïã陨EpŒ§\‹g‹´œ‹v Åè4X¤à-Ðz>zŽÀ‘Gg9jG[¤ãq4+ÐHΞéûc§Pã¡øÎÚi-Ò ÆÍ8",³ãé„S@Y×2Ó¨§‚cLŤôʹXÿÂèäÁ™’ŠÙ"ëNb&.ÆìˆMáu<éRû¥Þy®Ž¤
-¡]æœRžu.ž®ï‰ì3ꔇn;î×¼΋ßñ ´ó,2­*wHmNÌú;
-Õßá³/{0¾ûƒvùM‰éšÏתÆ¿µe0¾ý^ÛÃÔ!}ßy$Þ¿ê£ò}q|7'ø8ËxA0I ýÊ>d!5ÃñÝœh•]‹|‹tÂ)N{Í7ñŠ… xÞjÉÜ[Û Ô!/Å„V hLjâuÈSØï
-Y¨¯µÝ>Ò÷ŒC 5êå;X¿·f,ÚêWužá*ª·ãZÛ58§±\ñ?Û"ˆÒÑ:r8WVÏkw-Í_ ªsLI’©Ì2ØÕ褄>èG÷n‘ÎÓts-Ok½Ýã"™Z~s¶jKü¦« Ó )[gùdZŽiŽlÅǸ~ñÿ*5¯e|[^â†â‰áª½n\‰›|%%LLj¥½¤d®Ò¬Ÿ{Ë|~½ýÓåQ×
-endstream
+3720 0 obj
+<< /D [ 3695 0 R /XYZ 81.145 376.421 null ] >>
endobj
3721 0 obj
-<< /Type /Page /Contents 3722 0 R /Resources 3720 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3779 0 R >>
+<< /D [ 3695 0 R /XYZ 81.145 365.463 null ] >>
+endobj
+3722 0 obj
+<< /D [ 3695 0 R /XYZ 81.145 354.504 null ] >>
endobj
3723 0 obj
-<< /D [ 3721 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 338.579 null ] >>
endobj
3724 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 327.621 null ] >>
endobj
3725 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 316.662 null ] >>
endobj
3726 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 300.737 null ] >>
endobj
3727 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 289.778 null ] >>
endobj
3728 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 278.82 null ] >>
endobj
3729 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 267.861 null ] >>
endobj
3730 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 256.902 null ] >>
endobj
3731 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 245.943 null ] >>
endobj
3732 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 230.019 null ] >>
endobj
3733 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 670.199 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 219.06 null ] >>
endobj
3734 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 659.24 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 208.101 null ] >>
endobj
3735 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 648.281 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 197.142 null ] >>
endobj
3736 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 637.322 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 186.183 null ] >>
endobj
3737 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 626.364 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 175.224 null ] >>
endobj
3738 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 600.461 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 164.265 null ] >>
endobj
3739 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 589.502 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 153.306 null ] >>
endobj
3740 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 578.543 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 89.593 null ] >>
endobj
3741 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 567.584 null ] >>
+<< /D [ 3695 0 R /XYZ 81.145 78.635 null ] >>
endobj
-3742 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 556.625 null ] >>
+3694 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R /F81 358 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-3743 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 545.666 null ] >>
+3745 0 obj
+<< /Filter /FlateDecode /Length 2395 >>
+stream
+xÚÍ[ÉŽã6½÷Wø†Cw`Ð@»Ýsß‚\“Sþÿ’"ÅE%™¥ö$ƒ§m-Oµ±X¯Hq¦/_xøÿ·—ëçË÷»öż.Ÿ½ˆ ÿÄÅ3êb`܈Ëç?—?~pn®œK™ÿº×??á,@}¿;uqÌ#]‹#¸eRÁˆ$-çZ$þúMƒŽØåÜÊ7«Ê7áskiŹx_¾>PÎj½"ÝÓ`yšù¿ÜAåâ¹õÓޣŢ[cªvÒœ ˜Œž³“0Ìj;"©$}µG/È­ÃQðå¨Tñ³jr‹¶XôVù{²‘_þS¤szµf<#ïåªæÒ3¡$ª¹šÓ F$\󈻧yÔ6ʼn[mÑEX -;kùA·Ñ2MT¼¯O¹.1í}‹K[ѾfqpLSbcRÎY\j¦Ù =Œšj÷V“j;ª&Â2
+sŸÇ$2WÒ¬0 —ÈJ&qÞhu@çf©Öÿ1SÇ™7!]k íÎR‡[£>bEü˜Ÿ@"c/×®}N­>R¥p_>¥zH3Ê&ëv´œ÷’¦¤ÀÜ$=ÍM=Òsü´TN9÷ûüÿº¾Âå}¦¿´`Êê/GóWt²úËUn´ç“ª<£ÂUB¢‰CÓrkT|“*tßWéòºõsŒ³2î¢6û÷T›¤Y7ñõÑòÝg>gæ$Ú<ÓZ¡vV´Hê‘ÎǶpL{ƶ$1Àièû]è‹wCxhs·õLm¸dal¬Qóž8¸hyXâCJÙEyFuC ‚ÂX·ÐÊ×C±„²Ì‡0ZZ»( ƒ/ Óœº.ßcºK_äÊfc®{ý¦”ŠqÄ—<°
+Óa¶JÏìj@ê»>xm&V¹õÊ7€Ôë9…äüŠ¡8ÎÊz´†•qŠ¬Å·ó6Öž9a0Ïò¥YaDªìsRn’'ýF´…rÌi‹Úâf‹‰f §k--sa²B4´~Ä€Hg̈®«µ¸·ú+uäû¨º§ãpÚߛѳA&Ú3T¢~K‚“=Íž=9"ˆr Íð0 –à==CÀ% ‚(Ú<Ú#íÏ£…¦âìžßÖjSñ?`|G~¢ÙByÁ¸Egdbu< ÔP×5Ô­vÚbé©
+B\©ÄÈoµ[Q¯Ò:c稭\h‹ˆ¬êri‚µ6V›X+<ä<N29bê•ÍLCóºr@kª·JŸ"õ¶`e>C HÏÀÔéÁ5èB5D]–‘ò
+6Gˆ‚âxu’%^-—Ù_¾Œ¼6ÚPÕ•f ”%{Åtò½pñQI©c ¢Iû{¡kÆdƒÝ‹€QÓ‘øœD»`­ b¹ªke“eÉH‰L'ÃôLÝVÏ•žçryòW冷ÂÅØŠGRœ]¬6
+R®^¯V+rüeö¿ˆ—ÔUY¼d_Àê ê¬À1É·%“›'ž%e÷Hû)Ûä%þ®P}ñÊõXWZ‘é´A&)5ËD3›î*ÓÓbh]¥å†I/0q§Igà7HRl'¾¾é;„B…ÁãTø1]||ç) ½f
+)cÝ<1 äX„d? Áà `iD×Æ)¦BÔÍ“Ä¢MÔе·n™«RÆ{åæa¬D ÜvHåÖqÌiŒ´’i¤ uó4°X¬Gšð¿ðÿÖ6ͦ'¸¶Kæè¢æi€i¦ÃY~™óË€$ ²m„¦Kƒ[ÛþDb³Ýt!ú…´úœã–Ù‹Dß…²S{ƒúŽ¶ k@;A?bAm4 ¥gWü¶¥§ÃJÏõj“iF´N3Ö{]®ãäPa«poWHYÊT-^®î*»¼È³–¸ÍzFº®ÔˆüÑΙ*¹`“ ™ñxr£õ%¤ý‚í‘Ûò`5­M{"ëöÍrÜvà—2þ:ìä$ÚJ(fñ:Ø‘x“˜rµN^y—\2k·»Ñ4yÍg@ÒH*S¼ºÓ<M^ðÀœ°˜¼³Uµ‘ÌI1"-©_­òš3½”³“#8Áœv˜V³ÅwѪG:5K$õhrÏrÌ7{òð(k¦›²G³¦Ú¥¯¯Žã«Œ±Ô±Ò#~¿¿ä ^?NŸ²ã&TPÌyúc¶xe®0#9{@(·‰6
+2[wç™·¢Ë¡\<…
+BÛ©? ÷‘tŒ >Ò4‰z¤ƒ>¯Þ›]Š‹ì0Ûß•:Õ‡Œ[w¦[ÊÁ2Š‹ýžˆ2ò¢ŽK¬½¿/…žQÓd¿ÏXöÎ>çA/6DwË]«Te¿GyÏCBŸ)Ëû æ¸?«âì'Õø$re›’Bà™‡¶ú5 ý‚oÄ-ÃÏ@´šs@*]çª)}OäQ‡uè²ãž¦½ðür4ÛÍV‘yUy@êcbVß-Qý:‡´È»?Šü¦Ä€tNçsYãŒÞÆ1@ÞÀQä=LÒsô.Mtÿõ¬Ž:ŒEäÝ5_ñ‚`
+AúÊ>d¡ “È»9j¾î+–ï‘jŠÃQ󤺂` ¡nu˜ˆ»¤ã¥˜èµh~Ž¨ZÇ8…õPËêáúGf3FŒHK3|¿nK-¨‚êÓ8 Ú+F¡ö¨½h»}¤çÌC„õð¬Ÿë£I7¾ú*Ï"^…vMó]‡sh+Á5ÿÑ'ÑX(í­#Çsuõøç¼v7”…[ñiFõži¨Uɪ=ÐA
+½á/Ž®6ÜÝ"]Ú¸»ÈÉÓ¹ 7Z¯ßœíúT žôbµeÐc¶žÌË1=О¬ò¶]¿ø¿RÍcߧ—´¡xbºê¯Û®ÄM¾’“F›@)™o8ëÇZ}|¾ü FQµ
+endstream
endobj
3744 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 534.707 null ] >>
-endobj
-3745 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 523.748 null ] >>
+<< /Type /Page /Contents 3745 0 R /Resources 3743 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3742 0 R >>
endobj
3746 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 509.801 null ] >>
+<< /D [ 3744 0 R /XYZ 78.37 808.885 null ] >>
endobj
3747 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 498.842 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 768.829 null ] >>
endobj
3748 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 487.883 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 757.87 null ] >>
endobj
3749 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 436.077 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 746.912 null ] >>
endobj
3750 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 425.118 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 735.953 null ] >>
endobj
3751 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 414.159 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 724.994 null ] >>
endobj
3752 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 403.2 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 714.035 null ] >>
endobj
3753 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 392.242 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 703.076 null ] >>
endobj
3754 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 381.283 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 692.117 null ] >>
endobj
3755 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 370.324 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 681.158 null ] >>
endobj
3756 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 359.365 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 670.199 null ] >>
endobj
3757 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 333.462 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 659.24 null ] >>
endobj
3758 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 322.503 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 648.281 null ] >>
endobj
3759 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 311.544 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 637.322 null ] >>
endobj
3760 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 300.585 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 626.364 null ] >>
endobj
3761 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 289.626 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 600.461 null ] >>
endobj
3762 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 278.667 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 589.502 null ] >>
endobj
3763 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 267.709 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 578.543 null ] >>
endobj
3764 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 256.75 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 567.584 null ] >>
endobj
3765 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 245.791 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 556.625 null ] >>
endobj
3766 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 219.888 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 545.666 null ] >>
endobj
3767 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 208.929 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 534.707 null ] >>
endobj
3768 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 197.97 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 523.748 null ] >>
endobj
3769 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 187.011 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 509.801 null ] >>
endobj
3770 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 176.052 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 498.842 null ] >>
endobj
3771 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 165.093 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 487.883 null ] >>
endobj
3772 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 154.134 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 436.077 null ] >>
endobj
3773 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 140.187 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 425.118 null ] >>
endobj
3774 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 129.228 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 414.159 null ] >>
endobj
3775 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 118.269 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 403.2 null ] >>
endobj
3776 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 107.31 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 392.242 null ] >>
endobj
3777 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 96.351 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 381.283 null ] >>
endobj
3778 0 obj
-<< /D [ 3721 0 R /XYZ 81.145 85.392 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 370.324 null ] >>
endobj
-3720 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R /F81 366 0 R >> /ProcSet [ /PDF /Text ] >>
+3779 0 obj
+<< /D [ 3744 0 R /XYZ 81.145 359.365 null ] >>
endobj
-3782 0 obj
-<< /Filter /FlateDecode /Length 2642 >>
-stream
-xÚÍ\ÉŽ#7½×WèšÍ%¸…J-i
-%†iCµ#9Y· h9d:äk1œ=V9§AÉ#³!|&Ö<;!nzéÝR(RÈÞ^"f`NQ_0ÖE†ü ¨(¦h÷‰T ©B8;”#¥áMÀñ3áH{òpÍûæ)•©lh‘yögÄ?÷W^ëúñ(âc!ØÔ
-Ɉa¹æ@îÙbýO×J»Ê—Ds…ñ5]ÁZ¢©‘@ûMtëu¾N媭Cû:,gžÇ¸QàëœZËÓµøÒ¬ï©öÏÐñ%W+dé’>­4*ÙÉ
-™3[¤ó6¬1Ô 6,×(ê‘Nv+uÓ§«>U€ÔÉxQÃ¥¨Ä€E¥1Yã
-‡àR)ì;,¦!Õ¯6‹r„¤éi )‚¬ûh±`)ªŒ‘OÅGØ}‹‚yÐ1^EÑHwíE½ºE½
-K ªÖÙL/«µzyœ.k½Þ0üõmW¶Ñ“œ³7LÛÑ^SÞô¨¥jl™<Ñú¢ž¸“½`˜¢fÍz¤óñ‘ibõ&3ó¯ÙÌŒj"€HEÇý,°®äѵú;ÖÐ&e¬G âMÔ¹íüQ›
-ÇlyÅÑ#ˆCâ`¸(6[y#‰×Ê@¬Feð±&ƒi_üÚ´ë›~Xàæ^üÂ5ÛôyoÇrù M¸0˜tÄZ(&HákÇ¢áë5˜àÃç¶/^“EŠ+ùµÔ#Ò‹0w‚è‹J
-endstream
+3780 0 obj
+<< /D [ 3744 0 R /XYZ 81.145 333.462 null ] >>
endobj
3781 0 obj
-<< /Type /Page /Contents 3782 0 R /Resources 3780 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3779 0 R >>
+<< /D [ 3744 0 R /XYZ 81.145 322.503 null ] >>
+endobj
+3782 0 obj
+<< /D [ 3744 0 R /XYZ 81.145 311.544 null ] >>
endobj
3783 0 obj
-<< /D [ 3781 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 300.585 null ] >>
endobj
3784 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 289.626 null ] >>
endobj
3785 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 752.889 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 278.667 null ] >>
endobj
3786 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 741.93 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 267.709 null ] >>
endobj
3787 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 730.971 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 256.75 null ] >>
endobj
3788 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 720.012 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 245.791 null ] >>
endobj
3789 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 709.053 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 219.888 null ] >>
endobj
3790 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 657.248 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 208.929 null ] >>
endobj
3791 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 646.289 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 197.97 null ] >>
endobj
3792 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 635.33 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 187.011 null ] >>
endobj
3793 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 624.371 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 176.052 null ] >>
endobj
3794 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 613.412 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 165.093 null ] >>
endobj
3795 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 602.453 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 154.134 null ] >>
endobj
3796 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 591.494 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 140.187 null ] >>
endobj
3797 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 580.535 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 129.228 null ] >>
endobj
3798 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 569.577 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 118.269 null ] >>
endobj
3799 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 558.618 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 107.31 null ] >>
endobj
3800 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 547.659 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 96.351 null ] >>
endobj
3801 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 536.7 null ] >>
+<< /D [ 3744 0 R /XYZ 81.145 85.392 null ] >>
endobj
-3802 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 525.741 null ] >>
-endobj
-3803 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 487.883 null ] >>
+3743 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R /F81 358 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
3804 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 476.924 null ] >>
+<< /Filter /FlateDecode /Length 2643 >>
+stream
+xÚÍ\ÉŽ#7½×WèšÍ%¸…*[Ò
+ÙÛKÄ ÌÉ!ê ƺȿÅí>‘ª#Ug‡r¤4<  8Þa&éH. 9cß=¥2• -2Ï~ãŒøçþ
+Âk]?ÞE|¬ [€`½˜5ä5• &ª9¶„¸°)^1™8$e¦¨L¼jµäÃŽJ ¨(åa-lÉ ®u»J'Zý}•¢ùf÷÷øÐS¥•¸Ï Й…ðpZßv
++-°áݨ#ÇûO„Ðï%ˆ°»Jú‹0´šþ^ÞýClŠ)”øP0hp#Â&‚é[Q>ö!)=¿R&DÚx\ê¸É¨›pµõ—àà×z_bþÆã˸ço:¾Â7ƒ.ßä"¼6Q1Ê%y¡ahTRŠh½ã·ÄN¹“­Ì
+ zÓÍp?wŽE¨{øø³¸¡)°´EÓ¹´¡HƒïM¥SI̘0|êÛ3Ç7‘xJ k’ꀆ|äIA®¿¥øÃâû'rˆx,à¿(ãS\‰× B¬ ¸GzºžTL¹ÔÍåᶔƒHÏSD¥{ÙeÅp[®¹¤§)’ˆÚgÄž¢Åš{@yd[ˆõ?\+í*_FÍÆ×tk‰¦fDí7ѽ×ù:•«¶íë°œExãF¯Cpj-O×âK³¾§Ú?CÇ?¹Z!K—ôi¥QÉNVÈœØ#=oÊC FÑl­™)ê‘žìVœê¦OW}ª
+x\YöGJˆ»£y±]< 5Myv22Ý
+yâ0OöÓT²<z"h(s?ÍÔØ2½”áëÃì{;3Ö®îåY궭™
+2ÝÍE¹–YD»=»c-“ï—µMˆbã„e¼16"b/_[Uk›fG„­Pf»’’XYRGÝLŠ{ˆ*ï¦Ü-£T[e\!Ú‰²pô‘šî´6ÆÃ|šãgS¡Ü¿r1’FÞ»ñÁô§$ÆGÂ%+$8ã6·ÛèÔ1´´b ßðr÷7.]$Ôåë_ãFC"*,VØ).ô+F‹,]||<M¸CZ¾›Í-ŽóSÆ £»»ÛÁÀlÏÀëéG1“É“€²•,Fwp—,ZÌŽ9º÷H/M'î]ZÕ5Nfðºvw†çxÃd¶X¸Hß’¤ÿü„ Bõ®Bô¯‹c\ÒÓG¼Ü;5³E‹c\Òs]°dÜ‹<¸=…íû¡j›¯l3:Ë:=´ò½':ÌRÂ÷ýKµÍ—ĉë Låº2NÉù\§ªä†Ÿ!-¿­t£ný5_™tÝ©EɺŒŠïû§j[®ë¤¥B) ÜÖN…jOÈšúà`ô!$s´ùy‚}8:À$%
+endstream
+endobj
+3803 0 obj
+<< /Type /Page /Contents 3804 0 R /Resources 3802 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3742 0 R >>
endobj
3805 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 465.965 null ] >>
+<< /D [ 3803 0 R /XYZ 78.37 808.885 null ] >>
endobj
3806 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 455.006 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 768.829 null ] >>
endobj
3807 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 444.047 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 752.889 null ] >>
endobj
3808 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 433.088 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 741.93 null ] >>
endobj
3809 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 422.129 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 730.971 null ] >>
endobj
3810 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 411.171 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 720.012 null ] >>
endobj
3811 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 400.212 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 709.053 null ] >>
endobj
3812 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 389.253 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 657.248 null ] >>
endobj
3813 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 378.294 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 646.289 null ] >>
endobj
3814 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 367.335 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 635.33 null ] >>
endobj
3815 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 356.376 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 624.371 null ] >>
endobj
3816 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 345.417 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 613.412 null ] >>
endobj
3817 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 334.458 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 602.453 null ] >>
endobj
3818 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 323.499 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 591.494 null ] >>
endobj
3819 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 312.54 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 580.535 null ] >>
endobj
3820 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 301.582 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 569.577 null ] >>
endobj
3821 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 290.623 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 558.618 null ] >>
endobj
3822 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 252.765 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 547.659 null ] >>
endobj
3823 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 241.806 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 536.7 null ] >>
endobj
3824 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 230.847 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 525.741 null ] >>
endobj
3825 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 219.888 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 487.883 null ] >>
endobj
3826 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 208.929 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 476.924 null ] >>
endobj
3827 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 197.97 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 465.965 null ] >>
endobj
3828 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 187.011 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 455.006 null ] >>
endobj
3829 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 161.108 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 444.047 null ] >>
endobj
3830 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 150.149 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 433.088 null ] >>
endobj
3831 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 139.19 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 422.129 null ] >>
endobj
3832 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 128.232 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 411.171 null ] >>
endobj
3833 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 117.273 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 400.212 null ] >>
endobj
3834 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 106.314 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 389.253 null ] >>
endobj
3835 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 95.355 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 378.294 null ] >>
endobj
3836 0 obj
-<< /D [ 3781 0 R /XYZ 81.145 84.396 null ] >>
-endobj
-3780 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F65 327 0 R /F74 329 0 R /F81 366 0 R /F83 403 0 R >> /ProcSet [ /PDF /Text ] >>
+<< /D [ 3803 0 R /XYZ 81.145 367.335 null ] >>
endobj
-3839 0 obj
-<< /Filter /FlateDecode /Length 2111 >>
-stream
-xÚå[Én#7½û+ôáUÅ FR€œ} rMNùÿk¸4›MvI&%9™I`Ø’zy]{½"e)ôáσ y;½¿}¹j áB8¼ÿñ¦2ü¨ƒaè`Ò¨Ãû_‡ß~–Òœ¤¤‹”¤D÷õ÷÷_ßd P_®ŽNxcÐmqI~‡òëOtxG.à©ðz˜ß|ð¿2‡r.?o#þ²k)”Nv£çdo‘ªìpŒr–OZoÃi=~ÎGŠ¦Q;„x|½ÂÌê†^(BV7ÓMaµí‘p±6\g%'Tx)8&‘´ z¤Ç%RV
-í²ÖQÓdÓ¢õš›É>×?«%áÞ=¿‹S-}Ÿ®i, ç±)’=šÆQ°°ç|dNL‹ùËs.m€à²è¶Ø0꺾¿¶ö¦SµY<÷PF¼äy/ôã¤× BŹ=ç5­Y`¯wsnk‘Èécž[áq±í)Ûcÿs‰ÿpÎõ¶
-Çü¼ÿæžûIþúrUúàƒ­ ˜xc+ëÚƒÚ®“¾E¾‚ ï-äg!bú”"”#pÝháêuµÎáµ­ul½ûÔÆîRáÒ3Ru_¯¬Q}­ÔH·ô„Sf(ÚÍƬBa±¥CÏÅ`‹t§9Kd-K¨zí£Pã>rЖ§¦öxËð¢5kb²X{%ŒgÈ$‡ê¢N‰yÖîxÙç„]íBMÏŒŸbŽ&«,yÎÕÈIñi‰Åû%¿°äí¾¯Å{BÖÌÙ54a‘å ³e¿RË;,åz㶆5t^j˜Êv)½æVTVÎßñ“I /¬u; ǹ*¡BïnçZü”4Ììn=Û󆩸Zµ:§(ºt÷1¾=Ÿï©ñ¼t‹a¬r}[£{Ñ4ÕŒS®¼}d—H0M7›®Z;á”ç¼6Ê—‹×Z$Þö7lxj<RgÙȨke¥Ü{Þ]&kj/óA%^3
-|²ßǽU
-g×ÊI*ç%:Û÷0ç~®’¤îçWVŸc‰{ŽB6ô˜þIpW:¯–{ùöåK|FNQûs–½\UjlÖ Õ)ž·çRiË]®÷ä¹íÿ-¾ÖK5>¥h¿g‹0y‰0(÷JM'Õ†Þ-Í“`qºÉA¤ˆv S(…Ç=“S
-v~Šu…¤bæ¼[ö„:E%’M^b•ð•J§æ÷õ§Ä®JÄ®µŸáeY†- £%^JíM|úZg–iFW°§âêÍ2û ×›©í“7:ÃH…=/ìâ|jÿ¨¾=Y».·m¿«]ÏÎãA!÷«’É'Ç9Ÿ´H/õ‰{S!ï…ܯTF}q© Ú™iŒ©›îY¿n4ƒÜßo­£¥†§¬8•M÷ØÜl¡¬V&n+^]—ü]Ó܃œÒiÖƒ+>pf=Ò“šcóZZ+B~°Ù¥ç¢­Eº]ÛÛפ\èÚ×:ÇEî9cÕÜÜÔ¡MÄì}RºVñOé„vÚÂ&TcY Óœ…[¤ggùÇî×~V­HvòÑ5 R¦GßKÒ2sÌ¢¡ž®ÉDR±sÈèü²Ãkì‘Ú±ÔºÙ 3ÍÞ—KÌæþ¤Ò\Ã`˜}ådöàlþ}bß0ÑáÐÝÅp P”Z¿F‘˜V—…yáî•£ô£ãg‘¾Eɇí­t¤c-D›&QƒŸk§L­eΨ­£Qæ²mÆIm¹7ZëÖÜ–W”³>P*ÌÀù`”’—òÑ"}›ÒÁ4A2du;ÎéÖ"qñ7b!$»ŸišÓ¤‰Óç×:¤Ò‚–eåI©¬´_NR¹©ÆÛ!Íi~É·«
-D@a垃¹qYŒß"e¹ieOæ3$*–€“~”Aé[¤ôzV&©„uÈÉ4ʨ"é&ìœÀà¥p@¬ÀÇ; gø3·XÅw÷š)ŸÃ¾Ÿä×`½pFsÆån‹q[ jÜ ñœÍ„§IÊ6HàlÜ
-Ñ=ÒeR:F;rlTê©ÔîÆ >¾³
-dÂ)ÏJOsÒ·HUúÚÞÌ?;V!Ùú6ÊVvÖ=¼ƒÈe[Ø((µH/ÝÁ8¿Œ.‚"¡Ô~ÇF·ì….vH?]‰BiäômúËXß!=µâù!ŒÊƒPž8ë/y¡
-endstream
+3837 0 obj
+<< /D [ 3803 0 R /XYZ 81.145 356.376 null ] >>
endobj
3838 0 obj
-<< /Type /Page /Contents 3839 0 R /Resources 3837 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3779 0 R >>
+<< /D [ 3803 0 R /XYZ 81.145 345.417 null ] >>
+endobj
+3839 0 obj
+<< /D [ 3803 0 R /XYZ 81.145 334.458 null ] >>
endobj
3840 0 obj
-<< /D [ 3838 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 323.499 null ] >>
endobj
3841 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 312.54 null ] >>
endobj
3842 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 301.582 null ] >>
endobj
3843 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 290.623 null ] >>
endobj
3844 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 252.765 null ] >>
endobj
3845 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 241.806 null ] >>
endobj
3846 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 230.847 null ] >>
endobj
3847 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 219.888 null ] >>
endobj
3848 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 208.929 null ] >>
endobj
3849 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 197.97 null ] >>
endobj
3850 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 670.199 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 187.011 null ] >>
endobj
3851 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 659.24 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 161.108 null ] >>
endobj
3852 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 621.382 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 150.149 null ] >>
endobj
3853 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 610.423 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 139.19 null ] >>
endobj
3854 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 599.464 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 128.232 null ] >>
endobj
3855 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 588.506 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 117.273 null ] >>
endobj
3856 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 577.547 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 106.314 null ] >>
endobj
3857 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 566.588 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 95.355 null ] >>
endobj
3858 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 528.73 null ] >>
-endobj
-3859 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 517.771 null ] >>
+<< /D [ 3803 0 R /XYZ 81.145 84.396 null ] >>
endobj
-3860 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 506.812 null ] >>
+3802 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F65 327 0 R /F74 329 0 R /F81 358 0 R /F83 403 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
3861 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 495.853 null ] >>
+<< /Filter /FlateDecode /Length 2116 >>
+stream
+xÚå[Én#7½û+ôáUÅ °FR€œ} rMNùÿk¸4›MvI&%y2“` ÛêåuíõŠì‘Bþ:Èðó×—ãûË—‹öÞ)„ÃûŸ/ê Ã?up ¬QBuxÿûðûW)ÍQJ:‡ßoñóúÇûo/2‚¨/G'¼1è¶8Š¤
+×¥å,Fç)‹uHQ6´«\”DÉK¥Ð.k5M6-Z¯¹™ìs)ñ³ZnÝ3añ›8ÕâÑ÷éšÆÒp‹€à‘"Ù½Y` ûÞGt±žÉcQ {¹†9—6@p^t[lu]ÿ¾´ö¦cµY<wWF<åyOôã¤× BŹÁ9¯i%È{ýÛœÛZ$²Aú˜gÁVø¶Øö˜í±Æÿ©Ä8çz[…c~ÞsÏý$}¹(}ðÁVL¼±•õíÁ
+5î#myJaj÷g± ¿´f-â˜,Ö^ ã ›ÅsªCŠ:%æY»ãyŸvµ 5=3~‹9š¬²ä9W#K$ŧ%ï—üÂ’·û¾ï Y3g×Ðü…EËÚ‰¦Øo‡ÔòK¹žihkXA§¥†©l—Òk®Eeåü?™´€ñÂZÇFÖ W#T¨óÒõ\‹ß’†ÇDvѳ=o˜Š«U«sŠ¢swÓéÛóùžÏK·öÀ*×·5ºMSÍ8æÊÛGv‰Ót³éz µN±äj”/¯µH¼í¯ØðØx¤Î²‘Q×ÊJ¹ÿö¼»LÖÔ^ æƒJ¼fød¿{«&ή•“TÎKt¶ïaÎ}­’¤îçWVŸc‰{ŽB6ô˜þIpS:¯–{ùöåK|FNQûs–½\UjlÖ Õ)ž·§RiË]®÷ä©íÿ-¾ÖK5>¦h¿e‹0y‰0(÷JM'Õ†Þ-Í“`qºÉA¤ˆv S(…Ç-“S
+v~Šu…¤bæ¼kö„:E%’M^b•ð•J§æ÷úKbW% b×ÚÎÏ÷ð²,Ö…Ñ/¥ö&>}©3Ë4# +Øs?E¸uö®7-RÛ'¯t†‘
+{ZØÅéöÔþQ}{°v¯Û~W»ǃ0BîW%ÑØÅ'-ÒS}âžÆTÈ{!÷+•èÖIöC}Q íL4ÆTÂô»gýºÑ r¿¶Ž–Vž²âT6ñ¶Çæf Í0`µ2q[ñêê¸äïšæäœN³~\!ð3;è‘æ˜Ô œ×ÒZòƒÓrt-ÑÖ"]Ï®m„íkR®FtéëÇ@ã"÷”±jnnêÐ&bHö>)]«ø§tB;maª±¬…Ýœ…[¤Ggùûî×~V­HÇæÑàŒ®I2=Òø^’–™c õtM&
+”ʳ: ÎÏ!;¼Æ©ÝÛH­›½0Óì}¹ÄlnO*Í5 †ÙWNfÎæÏûn„Œ²†»‹á (µ
+~"1­„/ óÂD–ŽŽŸEú $¶×Ò‘Þj!Ú4‰ü\;ešh-sFm2—Ýh3.Hj˽ÒZo´æ¶¼¢œõRaÆØoJëqJ^ÊG‹ôlJÓÉÓm”ÚÝZ$.¾âÆ@,„d÷ñ³#Msz ó‚4qzŒRÖ…¢wH¥-ËÊ“RY'h¿8œ¤z›j¼Ò,‘æ—üp»
+0©™±Bï—s£fÃ/jè0
+©é:Ñß“ùcf³Ü‡€1ªþñ36mêG"ͨÐûÅädÿ9J×!=s$5ð´‘C´˜ý2lÊ$=o-ÒOBaI¾ ²?ƒÂ…ößÕ¾CkôšQû}û¯HV*6×pÎø-R–›Vöd>ƒA¢a‰e/£ ²Hß"m¤×³2I%¬Û³gTÈô@vN`ðR8 NàQš”î€áÏÜbßÝk¦|û~_ƒõÂÍw”»-Æmªq7ÄsR4ž& +Ú ³q+D÷HW–IétíÈqÒ’°%µ;¤ñ„÷﬙pʳһ9é[¤*}moæûŽU€FH¶¾²•…µ@wï`
+­`KÊ YZ#d‹³Yý¬ÿÒ×U‰ÛzNò)Ê®´ÝŽ0Õ)[éþÀ
+=Æ— ý-×#mÞàÒð|›!Ä×αñæ½Íï¶ñ’í|…% È4ÎY¸EÚ”ègG…G¡ ›ƒƒ¤ªDr ô„95þ”»¶?ƒ„” ãiô”)ÕªðÓp² RŠÒ‹[ Ÿß&[͵×ÁÇwÿãVVê¥+œ×¾r~ùØl)¨
+endstream
+endobj
+3860 0 obj
+<< /Type /Page /Contents 3861 0 R /Resources 3859 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3742 0 R >>
endobj
3862 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 484.894 null ] >>
+<< /D [ 3860 0 R /XYZ 78.37 808.885 null ] >>
endobj
3863 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 473.935 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 768.829 null ] >>
endobj
3864 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 462.976 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 757.87 null ] >>
endobj
3865 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 452.017 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 746.912 null ] >>
endobj
3866 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 441.058 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 735.953 null ] >>
endobj
3867 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 430.1 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 724.994 null ] >>
endobj
3868 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 419.141 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 714.035 null ] >>
endobj
3869 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 408.182 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 703.076 null ] >>
endobj
3870 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 397.223 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 692.117 null ] >>
endobj
3871 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 386.264 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 681.158 null ] >>
endobj
3872 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 375.305 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 670.199 null ] >>
endobj
3873 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 364.346 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 659.24 null ] >>
endobj
3874 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 353.387 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 621.382 null ] >>
endobj
3875 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 342.428 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 610.423 null ] >>
endobj
3876 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 331.469 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 599.464 null ] >>
endobj
3877 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 320.511 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 588.506 null ] >>
endobj
3878 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 309.552 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 577.547 null ] >>
endobj
3879 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 298.593 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 566.588 null ] >>
endobj
3880 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 287.634 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 528.73 null ] >>
endobj
3881 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 276.675 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 517.771 null ] >>
endobj
3882 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 265.716 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 506.812 null ] >>
endobj
3883 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 254.757 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 495.853 null ] >>
endobj
3884 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 243.798 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 484.894 null ] >>
endobj
3885 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 232.839 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 473.935 null ] >>
endobj
3886 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 221.88 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 462.976 null ] >>
endobj
3887 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 210.921 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 452.017 null ] >>
endobj
3888 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 199.963 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 441.058 null ] >>
endobj
3889 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 189.004 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 430.1 null ] >>
endobj
3890 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 178.045 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 419.141 null ] >>
endobj
3891 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 167.086 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 408.182 null ] >>
endobj
3892 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 156.127 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 397.223 null ] >>
endobj
3893 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 145.168 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 386.264 null ] >>
endobj
3894 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 134.209 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 375.305 null ] >>
endobj
3895 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 123.25 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 364.346 null ] >>
endobj
3896 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 112.291 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 353.387 null ] >>
endobj
3897 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 101.332 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 342.428 null ] >>
endobj
3898 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 90.374 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 331.469 null ] >>
endobj
3899 0 obj
-<< /D [ 3838 0 R /XYZ 81.145 79.415 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 320.511 null ] >>
endobj
-3837 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-3902 0 obj
-<< /Filter /FlateDecode /Length 1958 >>
-stream
-xÚí[Ín#7 ¾ç)ü«•DR?À"€½Ž ôœ[Ñk{êû_+FÖHC;¢ã
-âjÏ•¤·•d½’…0?ËU¯Ç»YL2õ7ó³JÓ¸¹’'v¡|’íDå'a’`î\,ê(ïÊ‹qÀrµ2=—qyéµg_¿-ÃêªD[^œ¿óµEËWeÍ®/^¨†A°{B2ÊD·›L}WHQyÄqÔj=wßçŠöïûøiù Þ©‚pý¹hXÖÿâ›hý HY;à«ïô ÏfÏšíûê‹!¯rÜzà×ÂÖ#oÍ/™‘Pò ¸/Hl£ÈH5‚ØS³ÀÂw»0È^ãЙ»ïNÜ?Þ¿ñƒûbKq1YqóEVͤf|y•g|ß,"ÿ>c!®ÍíÏú®ÚÈ6“5—}FP­4ËÖ¬T÷…踙r'™eõH·- %[]î¹­±«G©èÏÊq”ÉÑ#õ¾_{ß½â&³£ÇùœIlàfh6®k¢GšÑg^å^±ˆ>&rÖ½±è*ýºŠòX·†ß6iBI>‚6ã5O6§2û‹]®¹…–*äÜš.yüÞ/qÌÎ(M3ê"«“ ³ÚéqFÕ¾ØZ–Éu@w¼A(l ‰ÅoÞÈ*RhPŽx1dµÃ€tÛlbàŒ?¯öÿœµM1}EËÚˆÖö€4©½ÿ†ýjä#¾8bQ0Êp²Îf«n¤*SñRV^+ïwZþx™wÖÀñë4jˆ`'ëlvU5Ð#=쵃
-ä9FÂ,f@zêzÏ[ïàUˆ•÷(³¶i‰|¦HÒJáU¢·­î±ñ¥ò'mEˆœü³¹Ìº7 Íï¿QÎÌ°IØ4ÛïæmFQ—ݹ.C K=|·vêŸa0܇ ò_>ŸØ+$CŠ7>á6hÔXIN@š”¶†]3$£Ý#5ÞM÷sbâòÔk€š‰ YkX,‚Ó¶yÛã´»Üs^ºÞ0¢Jq‘;ÍÝ€ô ì|c
-
-mP #+ïdF…)*h³Cš×¼Š
-{ ã°KS¸Ô}ª†BíDÃ’
-2 HŸÑÁñËt
-endstream
+3900 0 obj
+<< /D [ 3860 0 R /XYZ 81.145 309.552 null ] >>
endobj
3901 0 obj
-<< /Type /Page /Contents 3902 0 R /Resources 3900 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3779 0 R >>
+<< /D [ 3860 0 R /XYZ 81.145 298.593 null ] >>
+endobj
+3902 0 obj
+<< /D [ 3860 0 R /XYZ 81.145 287.634 null ] >>
endobj
3903 0 obj
-<< /D [ 3901 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 276.675 null ] >>
endobj
3904 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 265.716 null ] >>
endobj
3905 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 254.757 null ] >>
endobj
3906 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 243.798 null ] >>
endobj
3907 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 232.839 null ] >>
endobj
3908 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 221.88 null ] >>
endobj
3909 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 699.091 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 210.921 null ] >>
endobj
3910 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 688.132 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 199.963 null ] >>
endobj
3911 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 677.173 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 189.004 null ] >>
endobj
3912 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 666.214 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 178.045 null ] >>
endobj
3913 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 655.255 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 167.086 null ] >>
endobj
3914 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 644.296 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 156.127 null ] >>
endobj
3915 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 633.337 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 145.168 null ] >>
endobj
3916 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 622.379 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 134.209 null ] >>
endobj
3917 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 611.42 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 123.25 null ] >>
endobj
3918 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 600.461 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 112.291 null ] >>
endobj
3919 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 589.502 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 101.332 null ] >>
endobj
3920 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 578.543 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 90.374 null ] >>
endobj
3921 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 567.584 null ] >>
-endobj
-3922 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 556.625 null ] >>
+<< /D [ 3860 0 R /XYZ 81.145 79.415 null ] >>
endobj
-3923 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 545.666 null ] >>
+3859 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
3924 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 534.707 null ] >>
+<< /Filter /FlateDecode /Length 1949 >>
+stream
+xÚí[ÉŽ#7 ½÷WøF#‰¤`Ѐ=nȹoA®É)ÿT*YKÑî¢Û L€`à©vUééQ¤¸H²Vtøû Óÿ¿½œÞ_¾_(PÅ`ÀÞÿz1þ™C°ÊáÁ;£´3‡÷üÐÚ´Æ·òq§×?ßÑ,A}¿<ƒÐãïU$˜‘¬/­;20!­Œ¶,“ã>&„
+›‘¬~ýF–ò_Ç„ë7¢þ¾=]ïŸË éo“ZX­Áæû×7œT6ˆÊ p²AÜ'¢àf¤Ì 3ß‹”‘ ʤ®8Fa#ë”ñvFzœ‘ñÊZbõOû§<ùibôýbèSk›:íZû¨ µÕVÙpµbp¯~¬vì s1=¹däzÝ« k_Þe›YûòÈõeÀ)0›ÞðT{*Hö²²O–ˆùzº+   Πö\Iz[IÖ;Yó³Üõz~šÅ$S¿™Ÿ…PÆîNØ…òuHúÊo,Â$ÁܹXÔQúÊ“qÀr·2=—vyêµw_¿-Íê¬D[:Î×|oÑòd™³kÇ Õ0 vOCHF™è6ƒ©ïj
+Âùç¢Q`yÿ‹¢ù7!e퀯¾Óc’({ÖlßW_ ˜?½þx.ô¹7¿dFBɃVàx_"_8!ÕbOÍ ß~b½Æ¡3÷Ü>x~¼ÿâÏÅ–âb²8ÖSã›(šMHÍùò,ϺðÍ"ò÷=âÚØþ¬áªl3Y3pÙfÕJ³lÍJÅqßQPˆî:R)«ð±~d–5"ݶ,<–nu¹ç6Ç®r¥r W<'Y™#ÒèøY±õ Ù+vÙØ›å#Îç|HŠèd7B{óè:'F¤=úÌ3£<+1ÆDκ;‹®Ò¯³(·ukømm‘¶(”æ Añš'›SýÅ.×Ü‹BKrnM—Ü~ë—8fg”Φu‘ÕÉQfµ#Ò㌠ª®ØêÐ @w¼A(l ‰ÅoÞÈ*RhPŽx1dµÃ„tÛt1p?¯öÿœ¹M1]¢eíˆDs{BÚ©­ÿ†ílä#¾8bQ0Ê°²¢H·R•©x )+¯•÷ÈZÈ40"=¬ã×i ÕÁ°9ÃÞìªj`DzØkhýs/Ìb&¤§Î÷ð¼ù^…8y÷f;ÕÚF¤%ò™"I+…W‰Þ>¶ºÇÚS”ÊŸ´!ròïÍeÖ•¸ iÿúåÌ ›„M³ãj^׊†ìÎ bXêỵÓøƒá>dÛøòùÄZ!R¼ñ —AG ÆúKrÒ¤´5í½©M¥="5ÞM÷sbâòÔk€š‰ YkX,‚Ó¶yÛâ´§Ü{^:ß0¢Jq‘» » éXùÆ
+µS Kê(ÓÁ„ô¿LI!XN^ážë„ô°Ç†"™–Q1‘þ#uxPdµ@Y.0!ý_Wì}gï”P6ú#ÒW@FQtì¬ïéË+‹=Ú¶õ窑x'~F¥¨•ÏéboVu1"5]|YÎ6*ç·9ÈqÎU¹H¿@•&(o9Ñ„Ûs#Ðã‘N{å·ùº7ZÏLH3²Ñ© Ù!Ú›ý$&€vFzœQ 8Fk~2½ïQ…€ìûA&Áˆt»þÙ“;pœ3s¼[N|P¶ì¼ŸþéXf¨h‰Õ&ÉÆbDº=y§sÜc}d,ò>´Í9"$D âïó'ï§.×óçÆÓ#&^÷Çù:6#Òý3m··!s@¥™èrÜéST±q‹dKÖ·a;•#n·ãi—Ï諽jЦ2ÍèæïÂ|>pË œMéŽÉÅÛ§ ;S™Rçß<ÚÞ;Ó—îßÍ‘u9Ig›nó5âæ«ø4™M5¢AÖßî^­Ñ*¤(;!µgV}ÜjµËd2™Tš°ñØ 8ͳÊ4!u2™LBŽ©2´9Ž»÷®VŽ#RÇ1¬ü@Ê-UmÖÇm÷²ÈÊmDóÞÞŽK­ÇçÇÛ÷š'+3J*_ª‹@;V¾£L¾©ñ¾W©£_¹¯U˜ë'ÕG€žãBû‘:þõŒÐÏÆ=+à™¼<„Àò 2ž#RÇó­†ÛNUU8ë¡…ÎÏœxΦzY·²ûxÉ*Î
+endstream
+endobj
+3923 0 obj
+<< /Type /Page /Contents 3924 0 R /Resources 3922 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3742 0 R >>
endobj
3925 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 523.748 null ] >>
+<< /D [ 3923 0 R /XYZ 78.37 808.885 null ] >>
endobj
3926 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 512.789 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 768.829 null ] >>
endobj
3927 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 501.831 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 757.87 null ] >>
endobj
3928 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 490.872 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 746.912 null ] >>
endobj
3929 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 479.913 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 735.953 null ] >>
endobj
3930 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 468.954 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 724.994 null ] >>
endobj
3931 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 457.995 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 699.091 null ] >>
endobj
3932 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 447.036 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 688.132 null ] >>
endobj
3933 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 436.077 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 677.173 null ] >>
endobj
3934 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 425.118 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 666.214 null ] >>
endobj
3935 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 414.159 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 655.255 null ] >>
endobj
3936 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 403.2 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 644.296 null ] >>
endobj
3937 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 392.242 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 633.337 null ] >>
endobj
3938 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 381.283 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 622.379 null ] >>
endobj
3939 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 370.324 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 611.42 null ] >>
endobj
3940 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 359.365 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 600.461 null ] >>
endobj
3941 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 348.406 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 589.502 null ] >>
endobj
3942 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 337.447 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 578.543 null ] >>
endobj
3943 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 326.488 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 567.584 null ] >>
endobj
3944 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 315.529 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 556.625 null ] >>
endobj
3945 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 304.57 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 545.666 null ] >>
endobj
3946 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 293.611 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 534.707 null ] >>
endobj
3947 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 282.653 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 523.748 null ] >>
endobj
3948 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 271.694 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 512.789 null ] >>
endobj
3949 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 252.765 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 501.831 null ] >>
endobj
3950 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 241.806 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 490.872 null ] >>
endobj
3951 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 213.91 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 479.913 null ] >>
endobj
3952 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 202.951 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 468.954 null ] >>
endobj
3953 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 191.992 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 457.995 null ] >>
endobj
3954 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 181.034 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 447.036 null ] >>
endobj
3955 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 170.075 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 436.077 null ] >>
endobj
3956 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 159.116 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 425.118 null ] >>
endobj
3957 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 148.157 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 414.159 null ] >>
endobj
3958 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 137.198 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 403.2 null ] >>
endobj
3959 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 126.239 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 392.242 null ] >>
endobj
3960 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 115.28 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 381.283 null ] >>
endobj
3961 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 104.321 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 370.324 null ] >>
endobj
3962 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 93.362 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 359.365 null ] >>
endobj
3963 0 obj
-<< /D [ 3901 0 R /XYZ 81.145 82.403 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 348.406 null ] >>
endobj
-3900 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-3966 0 obj
-<< /Filter /FlateDecode /Length 1952 >>
-stream
-xÚåZMã6 ½Ï¯È¨V"E}
-ƒ›æåÝ€´xį™t5ËY“¨Xâ8žÁO5e–ôH™ÍAv–W3 T…£
-Ç‹E*LÊ{·CŠŸ»|P…rvè]`Ž*Ü
-ARáüé-õ-ß^š³s[VÓs­E—RoE¯%üÝ– u%6kV©aU
-ö.wã”'?"Á9/_æE$åeH9íf¼Žñ²ZAÜ!1“ZQ §Pò$\²ÎNT¼¼½Ú‚ë»”ù6#­=@ªÎ#ŽÕ÷qhË/~æw‘ù Gj¶@IÊÚzÖÔªÇStÙšv&¿ú¢i‹Õå˜Ý¤gi=e¶RäQ‡™­g‘­R³5e¬z’òÂú‰LþKúS§¿­ýéøÒøoÊüXâZ*Vó‹Ç™ÑGGÚjtÔlvfŒñÜeÖÆ|»f¹àfûjñFW+°Ð351ÈLì‘úuŒ“îŽçpÓ˜$÷iÃý#u,·4 ›£}YåÕ#},WZôïä¢FŠöS$rR&<SE;Õ$¡ÎH_Þ“Aþj¯,A¬úÒÒ–š\kj{Vø†Ñ‚6KÓyÓ'ˆ¼°QeÓûÄé{j._{Šcwæ±£ýˆG<à H èî;h5cÒ‰´®æý‰sקÌ:–OøÊFPz\GÛ–„ãF·7v ŽÒç×ýª½|µó½Ý›\wÿG]‹¯o‰K²ä~ ÞÊ]›bŠøÞŽ1Ú •³¥.F0Ê3]³(p¤Màž?†B‹¼V†`fʊ׀Ôoéåmv ­¬,%¦6¸¡ÛÀ°§¨LÄ)ûƒ Ye‘Z9=2Ø´ròÉfÄòÜh§ñE2{z¤v»ã£ƒZÊYJqè¥6ñž¦6Y™M=ÒƦ]c.åÈã67#”qì‘6KŒJ¹ñÈ4U€£RåÖ#5nim´F#ï…­ÑýÎy-×snKíãqcØmøÐñö©Ú×#5Þiûd{7e;¨%MZ¸—ÉK×yD¶gü63…ÿ€´á?ÝXòäVÏ£DåÙ#mx¾Ü»ëµ_‡þ®–Ôa `jÏYfOt,nª­ë€&Õ.ä1–Îø£,î¤ýz|œ#´NÛ)G™¾H›Ç|ÛøZî¿–Ñ£ö<ù¸”7§ÎÒ46d:: mxS½uÈÐ=B°§èŽRíªlêû>|Îde§Õº(öî»Ò|´kDðÊMnf‘XÓ¤»^rL}éä6‰5}@ÚÆÀd´|É›‚ㆠ-ã·…¶1LkÇ×qT_r Žãw‹©z;uÑà[«¥ùù…‡Ž ¨Iy7Uha2 =øa!ˆV½Wb+î$¤» øTfôŽ6
-eÔêäSõ[^žÒ>¿• Tˆ0sÆÑn¤:£GzÏ¢ÏšàŒŠˆSƲ~c@úI³&^™Ø#ì?¤Ÿ8k‚ÕJ›iŠ û•é³&@T\ƒ§q$ëM¤Ìš`‚ÒÑO¹Ét}@úÌš ½2¦ñ!ë ¤/š5MtÊø©Â •x@zð¬i©ýh†(âè'MšÆ[û‡¥“9 @ú¢IÓ8T¨§Ë!œü¤}Å«ª!P¸uá&SÕéS°±Fá¾qK…J9 =pÚI·e-¸)G™ò Hÿ»iǘ¨¬óÓˆ”éó€ô )Âè H‡)?+ꜤÇ=À}·ëþüì½"§¡Ž"ô@_ð€`pŠ¦Äª7$Õ†ç“zRwâf_ŽkµÊsõ@?ýÑÀ7Zl6¥»<´´àY åËëÓ?®Þþ
-endstream
+3964 0 obj
+<< /D [ 3923 0 R /XYZ 81.145 337.447 null ] >>
endobj
3965 0 obj
-<< /Type /Page /Contents 3966 0 R /Resources 3964 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3779 0 R >>
+<< /D [ 3923 0 R /XYZ 81.145 326.488 null ] >>
+endobj
+3966 0 obj
+<< /D [ 3923 0 R /XYZ 81.145 315.529 null ] >>
endobj
3967 0 obj
-<< /D [ 3965 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 304.57 null ] >>
endobj
3968 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 293.611 null ] >>
endobj
3969 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 282.653 null ] >>
endobj
3970 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 720.012 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 271.694 null ] >>
endobj
3971 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 682.154 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 252.765 null ] >>
endobj
3972 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 671.195 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 241.806 null ] >>
endobj
3973 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 645.293 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 213.91 null ] >>
endobj
3974 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 634.334 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 202.951 null ] >>
endobj
3975 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 623.375 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 191.992 null ] >>
endobj
3976 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 612.416 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 181.034 null ] >>
endobj
3977 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 601.457 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 170.075 null ] >>
endobj
3978 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 590.498 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 159.116 null ] >>
endobj
3979 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 579.539 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 148.157 null ] >>
endobj
3980 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 568.58 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 137.198 null ] >>
endobj
3981 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 557.621 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 126.239 null ] >>
endobj
3982 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 546.662 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 115.28 null ] >>
endobj
3983 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 532.715 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 104.321 null ] >>
endobj
3984 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 521.756 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 93.362 null ] >>
endobj
3985 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 510.797 null ] >>
-endobj
-3986 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 499.838 null ] >>
+<< /D [ 3923 0 R /XYZ 81.145 82.403 null ] >>
endobj
-3987 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 488.879 null ] >>
+3922 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
3988 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 477.92 null ] >>
+<< /Filter /FlateDecode /Length 1964 >>
+stream
+xÚåZMoã6½çWø,—œá'°¯ã=çVôÚžúÿ¯;IQ¤&Ž&q“Å"k[–žß çãD­Üéÿ{8¿<|¿ºt²*EƒpzùëÁœ4ý3§ÊÛSðFioN/ÿœþø¡µÒ:$­1ÒûóãŸ/¿?è FP߯ў¢JÞcÜâÔ*†4#¹ôøÍ£wö'a]èõ¬5 a}Ö{Cõ žN+£åù$ã9"užÁÐ'“¹Ïë‚ùýjÜ)… VH
+Ã) SÆÅ•qÁk¶¯^‘»6Ebš/¶t±³Å9x®
+.ÌHðT–¯ðrNÊË8å5[{ìó1^V+H;$bÒ*
+”Êž„sé³L¯ï@¯¶àú.g¾-ÁèV «óŒcó õ¶ô²«ZÞ­êâ°F¤n Ô¤lÒ³¥V;ž£Ë¶´3å5Ôž¶X]ÙMzVé)³Õ%hØ`lm~;hë„ÔmÍÙk?ÉyqýD ¦üåþÓ¦¿­ýùø"ü7e~®i-•«é% gôÑ‘¶=
+n±¯©ˆWT­ÀÂ`¨ùÖÄ'™‰#Ò¸®‚qRÀÝÓn€ãŽ²ü›6ÜßSœ%IàØ°9ªË¯é}¹Ò5п“#UL– 'ºŸ2!9/eB3U²že"ëóÒ§ëag¾b;‹°ëOH‹,5¥Ö4yVùÆÙ‚>K»§NyaÓ•Íè¯ousùÚkT»œÇŽê‘€
+h†›6¸›ï × F‰tUóöĹÓ)œbù€¯l¥÷ÁeË–Œãg¿7v ŽªóÛýª}ûêç»7¹Ýý[u©¼¼Ö\²%·%x/w}Š©Í÷zŒÑf¨ä–J¸Ñ(c ·G…U Ü i¸O C¡EA+〳è¨jªÅkBoé•ÛìzYYJL¸q¸#`ï’2 Yö‘³Ê?#õrzd°éåäƒbÄÒÜh9{ŽŠ¤fψÔw¼wPË9ër©M4†Cp¬MQfÓˆ´±i'Ì¥iÜFãÙ8r2Ž#Ò†cq@)7¹Ñ±à¨PjÜF¤Î-¯­‡.4ʽ°5ºß8¯çzÉm©}4NcŠl| Ì¾©óηO¶OS¶ƒZîI ÷*‘‚t}Fd‹‰ãTÌTþÒ†?{cAÊ“^¨ëìnáq%ÑxŽHžÏ·žzí×a|ª%µ‡FXÀÙs´7{F¤cqÓl]4iïBcGŽÿÑÎÛøHûõx?Gi½¶,GY6ÛB¿ñµ<­£GÓ<帔7 §Þ:Ž·°NHÞ®=:¤?¶ìÇ)w£SíªlVÈ£ߟì,[­kÇÞ}WÕÉ{U#BPžy˜…âž>!Ýô‚cÖ¥Ìc*÷ô iÌhù\n
+Î7m¿-ôÃnU\p™Gõ%Ò<~÷˜jS—|íµ´ì_¸ëŠÚ©à#ëI™™î¼Y’UQ'6*eJbBº¹YHÀ/¢ŠlQ:*ê¨5ɧê×6^žÒ>~+¨˜vÝÛ>W#Í#Ò[½{ÖoTBä õÆ„ôE³&8½laìê é gM°ZiãX›dzeBºã¬ Õ`Ž£P›LHw˜5ÁD¥S`¹Éúú„ô™5Ae0²ñ!ÓÒ'Íš&yeBbùË:ñ„tçYÓD§€-îÂF<}Ѥi‚U°ß,ÍNøÒ'MšÆ£Âqu~¬›mNþҾ∻ªq pÜŽÚ¸ »ê„tÇ)ØX£pn£°SNHwœvòcY žå(ë|ÒÿnÚ1&)ëçIažî4E•Ó‘åEÊyBºßûã³C
+ÊÙĆº9`ú„ ‚Ñ+Ç?ؽ!wmq>¸908åÑ°át°WÛ¤…Ñôå[_Ý´žÈl—ŸÐÐÒƒ¿KÀç—‡_Çêß
+endstream
+endobj
+3987 0 obj
+<< /Type /Page /Contents 3988 0 R /Resources 3986 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3742 0 R >>
endobj
3989 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 466.961 null ] >>
+<< /D [ 3987 0 R /XYZ 78.37 808.885 null ] >>
endobj
3990 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 456.002 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 768.829 null ] >>
endobj
3991 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 445.044 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 757.87 null ] >>
endobj
3992 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 434.085 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 720.012 null ] >>
endobj
3993 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 423.126 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 682.154 null ] >>
endobj
3994 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 412.167 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 671.195 null ] >>
endobj
3995 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 401.208 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 645.293 null ] >>
endobj
3996 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 390.249 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 634.334 null ] >>
endobj
3997 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 379.29 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 623.375 null ] >>
endobj
3998 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 368.331 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 612.416 null ] >>
endobj
3999 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 357.372 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 601.457 null ] >>
endobj
4000 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 346.413 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 590.498 null ] >>
endobj
4001 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 335.454 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 579.539 null ] >>
endobj
4002 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 324.496 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 568.58 null ] >>
endobj
4003 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 313.537 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 557.621 null ] >>
endobj
4004 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 302.578 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 546.662 null ] >>
endobj
4005 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 291.619 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 532.715 null ] >>
endobj
4006 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 280.66 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 521.756 null ] >>
endobj
4007 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 269.701 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 510.797 null ] >>
endobj
4008 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 258.742 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 499.838 null ] >>
endobj
4009 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 247.783 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 488.879 null ] >>
endobj
4010 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 236.824 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 477.92 null ] >>
endobj
4011 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 225.865 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 466.961 null ] >>
endobj
4012 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 214.907 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 456.002 null ] >>
endobj
4013 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 203.948 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 445.044 null ] >>
endobj
4014 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 192.989 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 434.085 null ] >>
endobj
4015 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 182.03 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 423.126 null ] >>
endobj
4016 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 171.071 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 412.167 null ] >>
endobj
4017 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 160.112 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 401.208 null ] >>
endobj
4018 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 149.153 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 390.249 null ] >>
endobj
4019 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 138.194 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 379.29 null ] >>
endobj
4020 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 127.235 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 368.331 null ] >>
endobj
4021 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 116.276 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 357.372 null ] >>
endobj
4022 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 105.318 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 346.413 null ] >>
endobj
4023 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 94.359 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 335.454 null ] >>
endobj
4024 0 obj
-<< /D [ 3965 0 R /XYZ 81.145 83.4 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 324.496 null ] >>
endobj
-3964 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
-endobj
-4027 0 obj
-<< /Filter /FlateDecode /Length 1873 >>
-stream
-xÚÍZKã6 ¾Ï¯È±=Œ*‘zi€d’)Pô8=½öqèÿ¿–’¨‡eÅq³À`áµG–(>?’r¤0‡¿’þÿååòñòÓ» -‚W‡¿^ÔAÒ?uð ¬>8«„´êðñßᣔö,¥ Rê›”N~üú"#1"õÓ»×/‚µè{:Já¤)<½0ñ ¤DºÔѽäg+Û8Ò˜¦»¾Ò³Êw'óXœgx¬¬Ï–x´Ì_'îYJÂLV{yNÖ%¥&«&ÆáR%÷ñªiºT¾,í ¸–?ŽkßéƒîðV)„x=+5¡4N¥>?'õ’R“Ú’DFg C±[ Þ—V‹sâ=J˜-[¨¨[yrOË^(b~"#†çd\RZZÖ`öP<ÇèÈöÖJž}Í–|Þ>Ê
-Cø .•hZÛ–+œ]G€³}ý_¬§ËW_§ã¥½Ì S[šKk:ó [1¾UïÈg%hè´ïé½®mË{É—•2v,VØÂr€u;IlƒVZuPŸ öKš5™‡¦Ìüï;ßãÂWza£.wÝ—ÆÁ£0Þ¥ôqÙQžw¤ Ì¨|ªešßÙ²,‡A¸qnÒ –b8Ü” ÑÇq`ðÝSÂ΀Ë×RÞ>@2jÀЇ‘‹åéHI7þØÛ1¥™k“W³%¦ñZQòüd¯XÒ¼[ÈÝ)´A©‘ÊÎøUÔ*¹¯tDa`Gü^vø½
-ñ#~ª¥šË2ü•P„àG
-åä­z÷ýã±:uKÃêO.Ùâw  ?J9‹EÀ/ÁohwWrO?8óôé>N éšU’J½ç#¥WãݤŒ4Þ''Åùúo”¼ŽEy…\=H¾¶ƒÔü&ƒQ©[=Ò±’OóÆcéKM&´ØP½FÊáeÿ ,ý"IôH§™š1íä–=³³`?ÏUsO)…Zá¯û`q]ž¤;>IoôøKÌö¡nôhjªž©w­êøüc\4 L°ãNÆ®< PsmZŠàšK·ß2Ü>^þ÷ý›½
-endstream
+4025 0 obj
+<< /D [ 3987 0 R /XYZ 81.145 313.537 null ] >>
endobj
4026 0 obj
-<< /Type /Page /Contents 4027 0 R /Resources 4025 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3779 0 R >>
+<< /D [ 3987 0 R /XYZ 81.145 302.578 null ] >>
+endobj
+4027 0 obj
+<< /D [ 3987 0 R /XYZ 81.145 291.619 null ] >>
endobj
4028 0 obj
-<< /D [ 4026 0 R /XYZ 78.37 808.885 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 280.66 null ] >>
endobj
4029 0 obj
-<< /D [ 4026 0 R /XYZ 81.145 768.829 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 269.701 null ] >>
endobj
4030 0 obj
-<< /D [ 4026 0 R /XYZ 81.145 757.87 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 258.742 null ] >>
endobj
4031 0 obj
-<< /D [ 4026 0 R /XYZ 81.145 746.912 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 247.783 null ] >>
endobj
4032 0 obj
-<< /D [ 4026 0 R /XYZ 81.145 735.953 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 236.824 null ] >>
endobj
4033 0 obj
-<< /D [ 4026 0 R /XYZ 81.145 724.994 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 225.865 null ] >>
endobj
4034 0 obj
-<< /D [ 4026 0 R /XYZ 81.145 714.035 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 214.907 null ] >>
endobj
4035 0 obj
-<< /D [ 4026 0 R /XYZ 81.145 703.076 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 203.948 null ] >>
endobj
4036 0 obj
-<< /D [ 4026 0 R /XYZ 81.145 692.117 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 192.989 null ] >>
endobj
4037 0 obj
-<< /D [ 4026 0 R /XYZ 81.145 681.158 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 182.03 null ] >>
endobj
4038 0 obj
-<< /D [ 4026 0 R /XYZ 81.145 670.199 null ] >>
-endobj
-301 0 obj
-<< /D [ 4026 0 R /XYZ 79.37 626.861 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 171.071 null ] >>
endobj
4039 0 obj
-<< /D [ 4026 0 R /XYZ 79.37 518.597 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 160.112 null ] >>
endobj
4040 0 obj
-<< /D [ 4026 0 R /XYZ 79.37 472.298 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 149.153 null ] >>
endobj
4041 0 obj
-<< /D [ 4026 0 R /XYZ 79.37 425.999 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 138.194 null ] >>
endobj
4042 0 obj
-<< /D [ 4026 0 R /XYZ 79.37 379.7 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 127.235 null ] >>
endobj
4043 0 obj
-<< /D [ 4026 0 R /XYZ 79.37 297.536 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 116.276 null ] >>
endobj
4044 0 obj
-<< /D [ 4026 0 R /XYZ 79.37 227.327 null ] >>
+<< /D [ 3987 0 R /XYZ 81.145 105.318 null ] >>
endobj
-4025 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F88 606 0 R /F87 2190 0 R /F109 607 0 R /F64 325 0 R /F15 326 0 R /F74 329 0 R /F83 403 0 R /F65 327 0 R >> /ProcSet [ /PDF /Text ] >>
+4045 0 obj
+<< /D [ 3987 0 R /XYZ 81.145 94.359 null ] >>
+endobj
+4046 0 obj
+<< /D [ 3987 0 R /XYZ 81.145 83.4 null ] >>
+endobj
+3986 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F15 326 0 R /F83 403 0 R /F74 329 0 R >> /ProcSet [ /PDF /Text ] >>
+endobj
+4049 0 obj
+<< /Filter /FlateDecode /Length 2082 >>
+stream
+xÚÍZ;#¹ÎçW(<Ã#«ødÒJcÀp8.=Ûÿê"Y|4›Ýj-æ€ÁB+M‹,Öó«%…9ýû$éÿ¼Ý>ß~ý0á¤Eð
+áôùç›:Iú§N„Õ'g•V>ÿwúý,¥½Ji@J¤ÔËŸÿ|“‘‘úõÃë“ÁZô=¥ƒpÒ”@^Þ ˜ø‰è!½Ô¢yËŸ­lÏ‘žiz×wú¬ò»“ùY\gøYÙ?[âÏBæ¯÷‰¬F
+%a”5Ëûš¬KJMVMŒÃ­Jîã«þ¥é¥òË>è×òÇçÚwú wøQ)„øzUj BiœImà5©—”šÔ–$2:[Š•Øjð±´Z\ߣ„Ù²…Šz”OîeÁ EÌOd´·×d\RZZÖ`öPdúѾÑZɳïÙ’¯ÛG9`¦¼__ã}I©ã]6[çKZÖÎø£eIé碥øPô§¿ Jl0¥›JëJ+„%c_åÄk:LýÁãD:¢
+ýÙ:Rºg(@`IœžIà„\‰s–îT6¾©é‰zÀÞZ3£šë– øs«eJ&$‡gq
+ý¹WzÊ£rù„©É‹±¼"!$g¨Xo°ª:åÆü»R.{(ΤÖ&έ¼XÐû®Ê4¹”òÓÝÅš¨ñïÁ"íÁ;ÉØ¥~R î*0¥
+pŠVL7`%õ’jÎÀöMdèÝò+äˆ@ô `ñïô}UO[ŸXÔ-“9ÉBz2ÓLµ/Ÿ£¯lyh4Òº‘f Ã(z̵))~,`܈û|`rßJµ~Í,d¶ž¿J¬s­…é’p4ˆçB½55«Ûè¾EÈßÛPvVÁŽ`õÝäÍ(´(SƒçP€”üQ¬µ²(F ¯`¤’íÖë h¸ñ_CyK>Çk|уteÔ­®¾6¾cîH莕:;ªÑ—÷D$y;,EÍé¥ ¶90³á„1p4ÚJÇTÄÌìe‡‹ ( Ê‘—×­F/½G¢qÏ<ÎøÒ’®Á˜˜]WŒKM%IÅ1¸f†ú†
+)ß,Öp™´ŒÚSÕnp;µmAXÃ{neE‰;Ò,vÉvÜåIiTÿŽÌTW.œ•>´#F׉A]QR€š"•nÖ§ùD÷C@ªÁG‰0´”¿s•ôm ÍúTöš_‡w+ƒz
+Ù—«½JÁ}kPK*Ð*í+à ‡yÇ@7ÒI£œ»B-q¢£M²µvšŠ_úƒÝ§¡[¾ñÕœ¸|6Ì(!½ψdlÜÇìTÉ9Ð6$Uú}#£ή¤‚û~-J¢7æ+ùÄýìŠTýzãÇ;€Øã5•¹Ô’|©^Ÿò¬‘º'J éÆe­-ušæ;Á²yËÜM?e²ea;‚–°ü<jbÃI…ð@×2lVÈ <F*Væ Æh×xZ|>Žf*[Q¤„¥zàà w‚‘"xw”ÿ‚\zåt$yÄǤ2Øoäcèø˜9àc蕨էºqœ«§Åœ’(P-·o5µÁ( É£?ô]èF=à ½X=è2T´i;ðá,uk&çq„çü,9Ó~ê@ªˆ¬rkþ—™þù,á($¢Aá‚ûNîTªþˆ»¢Zª£ø¤R ™0Ò+µ%Ž%­²ƒtB‡oÕ1\Ø!°ø ¦ƒUlwÔ>é Ùûþ¢›ã1O“z=ˆa£WÔkuž¸]TÙv‹Ó')ŠJ¿ÒÏVedK©ƒåö‹<#üú”:<Èà~É•~)=--h“å¶
+g÷àl?)ÖÓåνvrã]eöeÐé[°2,{²büV} kœ• ¡Ó¾§ïu"}”l9é$;Øj-ûÇ4± Z¡<è¾ìš5•‡¦Ìüõ©> ½°Ñ—§Kã@QŽ¨¿Sú¸¨:¯GÒ‡´" ÿZË.iþÅ–Ír¨¯.wgýM) † š]Ù0öã8ž ¾G
+Ø9
+„WÍŠ*I¥>ò$éÝx7)#·çÉ}Pq¾þæÙxßM¦3¹z­wo×Zùž´sݸœq3+ù2+<–.±ÔdB‹ÕÂH¹Jê‘~’–$z¦ÓL͘6:gÏìÄ,ØÏkÕÜSJ¡Vøë®ïË{MÇ÷šß‹ï_±Ñ:á-¾RïZÕÍõüs\4 L°ãIÆ®< kìIK\ƒöG>>ßþä6¾
+endstream
+endobj
+4048 0 obj
+<< /Type /Page /Contents 4049 0 R /Resources 4047 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3742 0 R >>
+endobj
+4050 0 obj
+<< /D [ 4048 0 R /XYZ 78.37 808.885 null ] >>
+endobj
+4051 0 obj
+<< /D [ 4048 0 R /XYZ 81.145 768.829 null ] >>
+endobj
+4052 0 obj
+<< /D [ 4048 0 R /XYZ 81.145 757.87 null ] >>
endobj
4053 0 obj
+<< /D [ 4048 0 R /XYZ 81.145 746.912 null ] >>
+endobj
+4054 0 obj
+<< /D [ 4048 0 R /XYZ 81.145 735.953 null ] >>
+endobj
+4055 0 obj
+<< /D [ 4048 0 R /XYZ 81.145 724.994 null ] >>
+endobj
+4056 0 obj
+<< /D [ 4048 0 R /XYZ 81.145 714.035 null ] >>
+endobj
+4057 0 obj
+<< /D [ 4048 0 R /XYZ 81.145 703.076 null ] >>
+endobj
+4058 0 obj
+<< /D [ 4048 0 R /XYZ 81.145 692.117 null ] >>
+endobj
+4059 0 obj
+<< /D [ 4048 0 R /XYZ 81.145 681.158 null ] >>
+endobj
+4060 0 obj
+<< /D [ 4048 0 R /XYZ 81.145 670.199 null ] >>
+endobj
+301 0 obj
+<< /D [ 4048 0 R /XYZ 79.37 626.861 null ] >>
+endobj
+4061 0 obj
+<< /D [ 4048 0 R /XYZ 79.37 518.597 null ] >>
+endobj
+4062 0 obj
+<< /D [ 4048 0 R /XYZ 79.37 460.343 null ] >>
+endobj
+4063 0 obj
+<< /D [ 4048 0 R /XYZ 79.37 414.044 null ] >>
+endobj
+4064 0 obj
+<< /D [ 4048 0 R /XYZ 79.37 367.745 null ] >>
+endobj
+4065 0 obj
+<< /D [ 4048 0 R /XYZ 79.37 321.446 null ] >>
+endobj
+4066 0 obj
+<< /D [ 4048 0 R /XYZ 79.37 239.282 null ] >>
+endobj
+4067 0 obj
+<< /D [ 4048 0 R /XYZ 79.37 169.073 null ] >>
+endobj
+4047 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F59 338 0 R /F84 404 0 R /F88 606 0 R /F87 2208 0 R /F109 607 0 R /F64 325 0 R /F15 326 0 R /F74 329 0 R /F83 403 0 R /F65 327 0 R /F81 358 0 R >> /ProcSet [ /PDF /Text ] >>
+endobj
+4076 0 obj
<< /Filter /FlateDecode /Length 2643 >>
stream
xÚÍ[Én45¾ÿO1/€±ËåMŠ"ý!HQnˆ+œ¸ðþÊ»Ûvo“rM¦—Ú\ËWe‡ßþ¼ñÛÏß–o?¾k¼ ÁœRÂÜ>þø&迉›qLš›Ñ‚q-nÝ~{á¾s.ß9oœãþ^èœkxýAåŸô—xI—ÝkøÛÀk¹æ?xÏ^ïhî Ñ]ú(TšX)Ko¸|% ïý3
@@ -13168,59 +13235,59 @@ Y’ú¼(
fÑÌd) 14J×ärŽ8èžÃÉŒžBD“óÊÕÔ .I¹‹@À’â asb—ìÔÿj
~¿ç—ÌŽDkº(ffØ.“ûÞOk@Yº#xÄKdR‰‰4.Ð"c/L™LÁ°ÿQâýÚtêŽø¬òà€
¹cÀ{3Ðí'mhw19¢!뻋µäæFåEb² z6ôÎYjáêpåj@žƒÆ
-•™1š‹Û‰G&ÒuÛÜïk&ñPÔ’_O&6nrA´5“x˜öǨw¯”ð'bç›?}|û¹í(+
+•™1š‹Û‰G&ÒuÛÜïk&ñPÔ’_O&6nrA´5“x˜öǨw¯”ð'² /þôñí¹Æ('
endstream
endobj
-4052 0 obj
-<< /Type /Page /Contents 4053 0 R /Resources 4051 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3779 0 R /Annots 4064 0 R >>
+4075 0 obj
+<< /Type /Page /Contents 4076 0 R /Resources 4074 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3742 0 R /Annots 4087 0 R >>
endobj
-4064 0 obj
-[ 4045 0 R 4046 0 R ]
+4087 0 obj
+[ 4068 0 R 4069 0 R ]
endobj
-4045 0 obj
+4068 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 78.374 135.489 168.645 144.376 ]/A << /S /GoTo /D (section.0.1) >> >>
endobj
-4046 0 obj
+4069 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 78.374 113.572 162.18 122.538 ]/A << /S /GoTo /D (section.0.2) >> >>
endobj
-4054 0 obj
-<< /D [ 4052 0 R /XYZ 78.37 808.885 null ] >>
+4077 0 obj
+<< /D [ 4075 0 R /XYZ 78.37 808.885 null ] >>
endobj
-4055 0 obj
-<< /D [ 4052 0 R /XYZ 79.37 775.009 null ] >>
+4078 0 obj
+<< /D [ 4075 0 R /XYZ 79.37 775.009 null ] >>
endobj
-4056 0 obj
-<< /D [ 4052 0 R /XYZ 79.37 668.934 null ] >>
+4079 0 obj
+<< /D [ 4075 0 R /XYZ 79.37 668.934 null ] >>
endobj
-4057 0 obj
-<< /D [ 4052 0 R /XYZ 79.37 622.635 null ] >>
+4080 0 obj
+<< /D [ 4075 0 R /XYZ 79.37 622.635 null ] >>
endobj
-4058 0 obj
-<< /D [ 4052 0 R /XYZ 79.37 552.426 null ] >>
+4081 0 obj
+<< /D [ 4075 0 R /XYZ 79.37 552.426 null ] >>
endobj
-4059 0 obj
-<< /D [ 4052 0 R /XYZ 79.37 506.127 null ] >>
+4082 0 obj
+<< /D [ 4075 0 R /XYZ 79.37 506.127 null ] >>
endobj
-4060 0 obj
-<< /D [ 4052 0 R /XYZ 79.37 435.918 null ] >>
+4083 0 obj
+<< /D [ 4075 0 R /XYZ 79.37 435.918 null ] >>
endobj
-4061 0 obj
-<< /D [ 4052 0 R /XYZ 79.37 329.843 null ] >>
+4084 0 obj
+<< /D [ 4075 0 R /XYZ 79.37 329.843 null ] >>
endobj
-4062 0 obj
-<< /D [ 4052 0 R /XYZ 79.37 247.679 null ] >>
+4085 0 obj
+<< /D [ 4075 0 R /XYZ 79.37 247.679 null ] >>
endobj
305 0 obj
-<< /D [ 4052 0 R /XYZ 79.37 191.315 null ] >>
+<< /D [ 4075 0 R /XYZ 79.37 191.315 null ] >>
endobj
-4063 0 obj
-<< /D [ 4052 0 R /XYZ 79.37 176.396 null ] >>
+4086 0 obj
+<< /D [ 4075 0 R /XYZ 79.37 176.396 null ] >>
endobj
-4051 0 obj
-<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F15 326 0 R /F74 329 0 R /F65 327 0 R /F81 366 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
+4074 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F64 325 0 R /F15 326 0 R /F74 329 0 R /F65 327 0 R /F81 358 0 R /F22 357 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-4117 0 obj
-<< /Filter /FlateDecode /Length 6179 >>
+4140 0 obj
+<< /Filter /FlateDecode /Length 6178 >>
stream
xÚåÝÍŽãÖzFṯ¢oàèˆÿ4ÐÕv ÃÀ³ ÓœQ&¹ÿAHîwm‰ÔW•ƒLðÛ~ºŠª–¾µIQdóí<ÿõßÿüÖ¬ÿòoÿøíãÏßþþ«m¿]O×±ûoþçoåÿ5ߦ멛¾Mcs:Í·?ÿëÛ¿ÿËù<þøþ·æÚË¿þœÿnÏç®ýþ·îÒÍÿehæ_Müj¼Î¿úµùÿýùÜÌ¿«ýøÞµó¯û±üºûXÕüù¯¿¿ýsþæÿ¨1ÉS3=nÆǪ›‡Çó÷_ÍðìÁ4çþÔ._§¿žšóx{8óV]æ¿çmlÎíºQSy ë†Î›ßϱÿ}ÙÈùat¬Û=°öâXÛ6ówØoÐpy¡gÕŽVwãéòø`_é¾?íÅê¡·ûjõ8ÿñµ^O§‹Þi8]cõ¥;u—ÖêksjºNë˼ÙVwçqÞîÞꦟ·Û>Mº¶·{Ôú:o·}štÝ4o·ýÓéúaÞn­‡nÞnû4éæ'ÕÅãËiìíÓ¤›ÆSwµO“îÒŸš^ëùIu¹ê§Éõ:o·}šôçiÞnû4é›aÞnû4éç'Õåªuwž·{Òú2o·}šôý8o·ý“ïç'•¶s^Æ¡ÑúzêÏZOÓ©쳤ŸŸS׳}–ô×vÞnû,Ybzmô˘>ij[I³çüû‰gû£¤q èÎöc“IÖ/2ºèõw~”¤Ž¿GÍ_i<£úK‰k‰rQG±¥ÛpÔ
§i…Ôi…ÒµNÓ
@@ -13239,10 +13306,16 @@ Ng¥ qV
N³Rpš•‚Ó¬¤ÎJAéºRpš•‚Ó¬œf¥ uV
N³Rpº¬œe¥ uV
N³Rpš•‚Ó¬”®+…­‡£•B3Ú¥Ãpê‡éq¥p·WÖôý²ö³ìívŸï‡=]K¼ævCŽ¢é4Ñtšh:M4&šR—h:L4&šNM©M¥k4&šNM©M§‰¦ÓDÓi¢ét¢)q¢é4Ñtšh:M4¥N4•®Ñtšh:M4&šR'šNM§K4%šR'šNM§‰¦ÓDSéÍ­öÑì»Ópn_EsÝÍ.Ñì~”ø-yl»~¼ˆ]îˆÇÕå«å4öã_òm¶è(R'J×8Mœ&R'N“§ÉÓäÀéä@âäÀirà49pšH(]sà49pš8M¤Nœ&N—8K¤Nœ&N“§ÉÒ5[=ö6]sú—ûPëY{%ö¨ký¿?ïOµ›ÿ9~¿p
-Þš…õ^ÝûØnèÁÞ‡Ãì}8Mnœ&7R'7J×Ü8Mnœ&7R'7N“§ÉÓäÆéäFâäÆirã4¹qšÜHÜ(]sã4¹qšÜ8Mn¤Nnœ&7N—Ü8Kn¤Nnœ&7N“§ÉÒ57[}œÞÜk®§áÚ<äæÇæƒDk.Ú§gy<=d·~ h9½¢Æ§kogûq¶x9ƒ¼èþck–ïòj7#IÙnùQRœ&)N“©“¥kRœ&)N“©“§IŠÓ$Åi’ât’"q’â4Iqš¤8MR¤NR”®Iqš¤8MRœ&)R')N“§KRœ%)R')N“§IŠÓ$Eéš”]º/R8\ç0Õ»K=¥°Éµ'– MçïcˆêãîƒDë^J7m´žŒx~{<Š“ ÷›Ð}ñdÃá2œ¦ær{(']©×݇`91°ÛV´ÌÕë]}•wo)í6úà-%«×KœKK[]
-ì4–:–:¶ºXêXêXêXêR`‹K¥N¥N¥N­.všKKK[]
+Þš…õ^ÝûØnèÁÞ‡Ãì}8Mnœ&7R'7J×Ü8Mnœ&7R'7N“§ÉÓäÆéäFâäÆirã4¹qšÜHÜ(]sã4¹qšÜ8Mn¤Nnœ&7N—Ü8Kn¤Nnœ&7N“§ÉÒ57[}œÞÜk®§áÚ<äæÇæƒDk.Ú§gy<=d·~ h9½¢Æ§kogûq¶x9ƒ¼èþck–ïòj7#IÙnùQRœ&)N“©“¥kRœ&)N“©“§IŠÓ$Åi’ât’"q’â4Iqš¤8MR¤NR”®Iqš¤8MRœ&)R')N“§KRœ%)R')N“§IŠÓ$Eéš”]º/R8\ç0Õ»K=¥°Éµ'– MçïcˆêãîƒDë^J7m´žŒx~{<Š“ w›ÐÿñÅ“ ‡ËpššËí¡<œl8t¥^w‚åÄÀn[Ñ~<>2W¯wqôUÞ½¥´Û胷”¬^ ,q
+,u
+,u
+lu)°ÓXêXêØêR`©S`©S`©S`©K-.–:–:–:¶ºØi
,u
-,õZ`iS`«K¥N¥N¥N¦Àûàtòâ0u§iìCõpƧƒõî4ÈÝ·=8 RêœÑau9£CêœÑ!uÎèšü:M~¥.ùu˜ü:M~&¿R'¿J×ü:M~&¿R'¿N“_§É¯Óä×éäWâä×iòë4ùušüJü*]óë4ùušü:M~¥N~&¿N—ü:K~¥N~&¿N“_§É¯Ò5¿»ŒêüÎ?¥Ëùò*¿wgt,W8ük{y¤wû-Òë4é•:éušô:Mz&½N“^©Kz&½N“^§I¯ÔI¯Ò5½N“^§I¯ÔI¯Ó¤×iÒë4éu:é•8éušô:Mz&½R'½J×ô:Mz&½N“^©“^§I¯Ó%½Î’^©“^§I¯Ó¤×iÒ«tMïV÷È·3‡~ÃÞïÝgûúÉëÛ™0æ-ÍæçþÃåwéé÷÷ŸX VÛ ?Š•Ô%V+§‰•ÓÄJêÄJé+§‰•ÓÄJêÄÊibå4±ršX9XIœX9M¬œ&VN+©+¥k¬œ&VN+§‰•Ô‰•ÓÄÊé+g‰•Ô‰•ÓÄÊibå4±Rz˜w¾®ýã×^N|¹Ú}Åy \®—Ç`=ªšÛeEºƒ÷ ëY4ë™5åßÛ.çù×êµïwͶ[v´kæ4µsšÚI]jç0µsšÚ9Mí¤Ní”®µsšÚ9Mí¤N휦vNS;§©Ó©Ä©ÓÔÎijç4µ“:µSºÖÎijç4µsšÚIÚ9Míœ.µs–ÚIÚ9M휦vNS;¥kívúSµkË×xQ»»#£ÏkÇ%è§þvÐö#k\–k Üý…¾Þ(m7î(JR—(9L”œ&JN%©%¥k”œ&JN%©%§‰’ÓDÉi¢ät¢$q¢ä4Qrš(9M”¤N””®Qrš(9M”œ&JR'JN%§K”œ%JR'JN%§‰’ÓDIé¥VQâ˜a3ÿT/ÓC”nèþ(1ZÏùuÛé*¿¾}`áÉ ÊÚÛ#ïvÏî.•ÿ‡õbš¿‹m7ü A“ §IÓ$Hê$Héš §IÓ$Hê$Èiä4 rš9Iœ9M‚œ&AN“ ©“ ¥k‚œ&AN“ §IÔIÓ$Èé’ gIÔIÓ$Èiä4 Rº&h§ÛO\B8·§yêïtw ýþG>‘£yK†øÔÀºŸÔ–ÈŒíó;¯t1\äcèëÑÀç¿a95eÝ‘º”O‰¯»]ÝûhlÅQ4œ&R'J×h8M4œ&R'N §‰†ÓDÃéDCâDÃi¢á4ÑpšhHh(]£á4Ñpšh8M4¤N4œ&N—h8K4¤N4œ&N §‰†Ò5;Ýšë2ç`Z=ŸÎÓô‡·Ž®Òüê^Nø׺üpöüUú·û'» |¿"qR#uR#uRcuIÓ¤Fê¤Fê¤Æê’©“©“©“©Kj,.©‘:©‘:©‘:©±º¤ÆiR#uR#uR#uRcuIÔIÔkj¤Mj¬.©‘:©‘:©‘:©qšÔìõ§R3-—Åo_¥æî}›£Û­lôqû8÷zXíüײC¶{Ô§iƒÔiƒÒµ NÓ§iƒÔiƒÓ´ÁiÚà4mp:m8mpš68Mœ¦ R§ J×68Mœ¦ NÓ©Ó§iƒÓ¥ ÎÒ©Ó§iƒÓ´ÁiÚ tmÃN·ë±'Ù†qþ3_½`áë6ðöïøsqÂ.o<kÅí*ï;Á,ßnøÑ,WºÎr§™åN3Ë¥Î,wšYî4³Üif¹Ó™åg–;Í,wšYî4³\êÌr¥ë,wšYî4³Üif¹Ô™åN3Ë.³ÜYf¹Ô™åN3Ëf–;Í,WºÎòþÔ,úSÛ¼\ç¯ïG¼œåæŠûÿæ=‰7Ç–ÊÑ¢í†-rš=§©ˆÔ©ˆÒµ"NS§©ˆÔ©ˆÓTÄi*â4q:‘8qšŠ8MEœ¦"R§"J׊8MEœ¦"NS©S§©ˆÓ¥"ÎR©S§©ˆÓTÄi*¢t­ÈNª"}{j‡ñeE.ÿgYwv‡™w ¶[4Е®ÝiºÓ t©3Ðf ;Í@wšîtºÄèN3Ðf ;Í@—:]é:Ðf ;Í@wš.uºÓ t§Ë@w–.uºÓ t§èN3Е®}§Ûu»Ó“–?ßîÜ< ôËí"áù4}×ÛË|¯÷ù[¯ÖzþëísöÏï³ÞsSùÍ-Œø>k>8SöížÂvÛöœfOÁiÂ"u¢t ‹Ó„ÅiÂ"uÂâ4aqš°8MXœNX$NXœ&,N§ ‹Ô ‹Ò5,N§ ‹Ó„Eê„ÅiÂât ‹³„Eê„ÅiÂâ4aqš°(]òÓí'î}×7óŸXÿ¸§py8…©—‹•Þ>È}#Úis†k½KÛ?÷\þe¹ˆË¥%>c’´¹]Ÿ"Üž454ÄmûÙÂ’«»[/ï~ÝÞ.²šëº½Ú am.GÓÈi¦‘ÓL#§™FRg)]§‘ÓL#§™FN3¤Î4ršiät™FÎ2¤Î4ršiä4ÓÈi¦‘Òuíô§¦Ñyy…4¯¦ÑÝY.Ë=q^¿óøü’P/–®÷w
+,u
+,u
+lu)°Ô)°Ôk¥M­.–:–:–:všïôËpí!SwšÆî1Tça|:XïNƒÜ}ÛƒÓ ¥ÎV—3:¤ÎR猩ɯÓäWê’_‡É¯Óä×iò+uò«tͯÓä×iò+uòë4ùušü:M~N~%N~&¿N“_§É¯ÔɯÒ5¿N“_§É¯ÓäWêä×iòëtɯ³äWêä×iòë4ùušü*]ó»Õ>¿óOér¾¼ÊïÝËÿÚ^éÝ~Ë£ô:Mz¥Nz&½N“^§I¯Ó¤Wê’^‡I¯Ó¤×iÒ+uÒ«tM¯Ó¤×iÒ+uÒë4éušô:MzNz%Nz&½N“^§I¯ÔI¯Ò5½N“^§I¯Ó¤Wê¤×iÒëtI¯³¤Wê¤×iÒë4éušô*]Ó»ÕÇéåm?ŒáaÏ÷}ýäõíLó–fós‰áò;ôôûûO,«í†ÅJê+‡‰•ÓÄÊib%ub¥t•ÓÄÊib%ubå4±ršX9M¬œN¬$N¬œ&VN+§‰•Ô‰•Ò5VN+§‰•ÓÄJêÄÊibåt‰•³ÄJêÄÊibå4±ršX)=Ì;_×þñk/'¾\í¾â<.×Ëc°ÕNÍí²"ÝÁû„õ,šõÌšòïm—óükõÚ÷»fÛ-;Ú5sšÚ9Mí¤.µs˜Ú9M휦vR§vJ×Ú9M휦vR§vNS;§©ÓÔÎéÔNâÔÎijç4µsšÚIÚ)]kç4µsšÚ9Mí¤N휦vN—Ú9Kí¤N휦vNS;§©Òµv;ý©Úµåk¼¨ÝÝ‘ÑçµãôS; hû‘5.˵îþB_ï‚G”¶w%©K”&JN%§‰’Ô‰’Ò5JN%§‰’Ô‰’ÓDÉi¢ä4Qr:Q’8Qrš(9M”œ&JR'JJ×(9M”œ&JN%©%§‰’Ó%JÎ%©%§‰’ÓDÉi¢¤tÒN«(qÌ°™ª—é!J·@t”­gÈüºít•_ß>°ðäeí튑w»gw—Ê¿ÿÀÃz1Í߃E‚¶~ ‡IÓ$Èi$u¤tMÓ$Èi$uä4 rš9M‚œN‚$N‚œ&AN“ §IÔIÒ5AN“ §IÓ$Hê$ÈiätI³$Hê$Èiä4 rš)]´Óí'.¡?œÛÓ<õ÷ º»†~ÿ#ˆÈѼ%C|j`ÝOjKdÆöùWº.ò1ôõhàóß°œš²îH]ʧÄ×Ý®î}4¶â(N © ¥k4œ&N © §‰†ÓDÃi¢át¢!q¢á4Ñpšh8M4¤N4”®Ñpšh8M4œ&R'N §K4œ%R'N §‰†ÓDCénÍu™s0­¿žOçizŒÆÃ[GW
+i~u/'ü‹kÝ?~8{þ*ýÛý“ݾß?‘8©‘:©‘:©±º¤ÆiR#uR#uRcuIÔIÔIÔIÔ%5—ÔHÔHÔHÔX]Rã4©‘:©‘:©‘:©±º¤Fê¤Fê55Ò&5V—ÔHÔHÔHÔ8MjöúS©™–Ëâ·¯Rs÷¾ÍÑíV6ú¸}œ{=¬vþkÙ¡ Û=jƒÓ´Aê´AéÚ§iƒÓ´Aê´ÁiÚà4mpš686Hœ68Mœ¦ NÓ©Ó¥kœ¦ NÓ§iƒÔiƒÓ´ÁéÒgiƒÔiƒÓ´ÁiÚà4mPº¶a§ÛõØ“lÃ8ÿŒ/wCÞ^°ðux{„wü¹8a—·Nžµâv÷`–o7üh–+]g¹ÓÌr§™åRg–;Í,wšYî4³ÜéÌr‰3Ëf–;Í,wšY.uf¹Òu–;Í,wšYî4³\êÌr§™åN—Yî,³\êÌr§™åN3Ëf–+]gùNj–ý©m^®ó×÷#^ÎòóÅýŒóžÄ›cKåhÑvCŽ9ÍÓTDêTDéZ§©ˆÓTDêTÄi*â4qšŠ8ŠHœŠ8MEœ¦"NS©S¥kEœ¦"NS§©ˆÔ©ˆÓTÄéRg©ˆÔ©ˆÓTÄi*â4QºVd§?U‘¾=µÃø²"—ÿ³Š¬» »ÃL‡»Û­?èJ×î4ÝiºÔèN3Ðf ;Í@w:]â t§èN3Ðf K®tèN3Ðf ;Í@—:ÝiºÓe ;Ë@—:ÝiºÓ t§èJ×¾Óí:ˆÝéIËŸownúåv‘ð|š¾Œëíe¾×ûü­Wk½?ÿõö9ûç÷Y﹩üæF|Ÿ5 œ)ûvOa»íG{
+N³§à4a‘:aQº†ÅiÂâ4a‘:aqš°8MXœ&,N',',N§ ‹Ó„Eê„Eé§ ‹Ó„ÅiÂ"uÂâ4aqº„ÅYÂ"uÂâ4aqš°8MX”®aÙéö÷¾ë›ùO¬ÜS¸<œÂÔŽËÅJoŸ ä¾í´9õ^Ž¥íŸ{.ÿ²\ÄeÒŸ1IÚÜ.‰OnOšâ¶ýlaÉÕÝ­—Îw¿noYÍuÝ^í„0¶?—£iä4ÓÈi¦‘ÓL#©3”®ÓÈi¦‘ÓL#§™FRg9Í4rºL#g™FRg9Í4ršiä4ÓHé:vúSÓè¼¼BšWÓèî,—åž8¯ßy|~I¨K×û;
NS§©‚Ó©‚Ä©‚ÓTÁiªà4U:UPºVÁiªà4Upš*H*8Mœ.Up–*H*8Mœ¦
NS¥kv“ýc}CJVaO×æaçêî°ãOn)]oüÜ>»ƒÙÐo§7w0»ÝÙìíûT» 9xŸÊêì|9ÍΗÓì|9ÍΗÓì|I]v¾fçËi2ë4™•:™UºfÖi2ë4™•:™ušÌ:Mf&³N'³'³N“Y§É¬ÓdVêdVéšY§É¬ÓdÖi2+u2ë4™uºdÖY2+u2ë4™ušÌ:Mf•®™Ý¥òãÍmpÞŸ¾³´ãz½}g¹l.t¹Û1ZϾÙí}òŸõl?n§›ä©õ+¯/¾ìß¿Ú|þ§½ÿœ[\•&ö݇:#g÷X”?¾xJNÛu§sû K÷pJΓk1½Ýüº¢éʜ盘ԕÆvcŽVN³Òpš•†Ó¬4¤.+ ‡Yi8ÍJÃiVRg¥¡t]i8ÍJÃiVRg¥á4+ §Yi8ÍJÃé¬4$ÎJÃiVN³Òpš•†ÔYi(]WN³Òpš•†Ó¬4¤ÎJÃiVN—•†³¬4¤ÎJÃiVN³Òpš•†Òu¥±ÕoóøÃyù|÷9¼;#æË9<—Ëp@¸?ØéÞnÈQ
&…N“B§I¡Ô%…“B§I¡Ó¤Pê¤PéšB§I¡Ó¤Pê¤ÐiRè4)tš:Jœ:M
@@ -13251,269 +13324,262 @@ NS¥kv“ýc}CJVaO×æaçêî°ãOn)]oüÜ>»ƒÙÐo§7w0»ÝÙìíûT» 9xŸÊêì|9ÍΗÓì|9ÍΗÓì|I]v¾fç
9‡Ó8ƒkâ¦p
8‡Ó7…É›ÂÔMaâ¦pÚælÒ¦0eS˜°)L×NÖ ®US˜¨)LÓ&i§h
4…KÏ%g§f
-3…i™Â¤ÌàZ² ^Cv‰Öen-_uœŸJ§ëT¯›ÓÿQ¯›óÇŸ¿ýüÏÉ5
+3…i™Â¤ÌàZ² ^Cv‰Öen-_uœŸJ§ëT¯›ÓÿQ?&ùÇŸ¿ýF7É
endstream
endobj
-4116 0 obj
-<< /Type /Page /Contents 4117 0 R /Resources 4115 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3779 0 R /Annots 4119 0 R >>
+4139 0 obj
+<< /Type /Page /Contents 4140 0 R /Resources 4138 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3742 0 R /Annots 4142 0 R >>
endobj
-4119 0 obj
-[ 4047 0 R 4048 0 R 4049 0 R 4050 0 R 4065 0 R 4066 0 R 4067 0 R 4068 0 R 4069 0 R 4070 0 R 4071 0 R 4072 0 R 4073 0 R 4074 0 R 4075 0 R 4076 0 R 4077 0 R 4078 0 R 4079 0 R 4080 0 R 4081 0 R 4082 0 R 4083 0 R 4084 0 R 4085 0 R 4086 0 R 4087 0 R 4088 0 R 4089 0 R 4090 0 R 4091 0 R 4092 0 R 4093 0 R 4094 0 R 4095 0 R 4096 0 R 4097 0 R 4098 0 R 4099 0 R 4100 0 R 4101 0 R 4102 0 R 4103 0 R 4104 0 R 4105 0 R ]
+4142 0 obj
+[ 4070 0 R 4071 0 R 4072 0 R 4073 0 R 4088 0 R 4089 0 R 4090 0 R 4091 0 R 4092 0 R 4093 0 R 4094 0 R 4095 0 R 4096 0 R 4097 0 R 4098 0 R 4099 0 R 4100 0 R 4101 0 R 4102 0 R 4103 0 R 4104 0 R 4105 0 R 4106 0 R 4107 0 R 4108 0 R 4109 0 R 4110 0 R 4111 0 R 4112 0 R 4113 0 R 4114 0 R 4115 0 R 4116 0 R 4117 0 R 4118 0 R 4119 0 R 4120 0 R 4121 0 R 4122 0 R 4123 0 R 4124 0 R 4125 0 R 4126 0 R 4127 0 R 4128 0 R ]
endobj
-4047 0 obj
+4070 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 78.374 758.062 199.908 769.031 ]/A << /S /GoTo /D (section.0.3) >> >>
endobj
-4048 0 obj
+4071 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 746.057 217.99 757.016 ]/A << /S /GoTo /D (subsection.0.3.1) >> >>
endobj
-4049 0 obj
+4072 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 734.102 271.838 745.17 ]/A << /S /GoTo /D (subsection.0.3.2) >> >>
endobj
-4050 0 obj
+4073 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 722.266 260.909 733.106 ]/A << /S /GoTo /D (subsection.0.3.3) >> >>
endobj
-4065 0 obj
+4088 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 709.753 282.11 721.708 ]/A << /S /GoTo /D (subsection.0.3.4) >> >>
endobj
-4066 0 obj
+4089 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 78.374 690.217 177.731 699.263 ]/A << /S /GoTo /D (section.0.4) >> >>
endobj
-4067 0 obj
+4090 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 675.88 307.764 687.835 ]/A << /S /GoTo /D (subsection.0.4.1) >> >>
endobj
-4068 0 obj
+4091 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 664.373 172.561 675.322 ]/A << /S /GoTo /D (subsection.0.4.2) >> >>
endobj
-4069 0 obj
+4092 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 652.418 214.364 663.477 ]/A << /S /GoTo /D (subsubsection.0.4.2.1) >> >>
endobj
-4070 0 obj
+4093 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 640.463 276.302 651.522 ]/A << /S /GoTo /D (subsubsection.0.4.2.2) >> >>
endobj
-4071 0 obj
+4094 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 628.508 251.943 639.457 ]/A << /S /GoTo /D (subsubsection.0.4.2.3) >> >>
endobj
-4072 0 obj
+4095 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 618.376 258.917 627.611 ]/A << /S /GoTo /D (subsection.0.4.3) >> >>
endobj
-4073 0 obj
+4096 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 78.374 596.568 197.477 605.644 ]/A << /S /GoTo /D (section.0.5) >> >>
endobj
-4074 0 obj
+4097 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 582.67 249.98 593.629 ]/A << /S /GoTo /D (subsection.0.5.1) >> >>
endobj
-4075 0 obj
+4098 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 570.715 202.349 581.674 ]/A << /S /GoTo /D (subsubsection.0.5.1.1) >> >>
endobj
-4076 0 obj
+4099 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 560.593 200.416 569.718 ]/A << /S /GoTo /D (subsubsection.0.5.1.2) >> >>
endobj
-4077 0 obj
+4100 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 546.924 243.704 557.873 ]/A << /S /GoTo /D (subsection.0.5.2) >> >>
endobj
-4078 0 obj
+4101 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 536.682 231.559 545.808 ]/A << /S /GoTo /D (subsubsection.0.5.2.1) >> >>
endobj
-4079 0 obj
+4102 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 524.727 244.312 533.853 ]/A << /S /GoTo /D (subsubsection.0.5.2.2) >> >>
endobj
-4080 0 obj
+4103 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 510.939 252.591 522.007 ]/A << /S /GoTo /D (subsection.0.5.3) >> >>
endobj
-4081 0 obj
+4104 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 499.103 269.318 509.943 ]/A << /S /GoTo /D (subsection.0.5.4) >> >>
endobj
-4082 0 obj
+4105 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 488.862 256.257 497.987 ]/A << /S /GoTo /D (subsubsection.0.5.4.1) >> >>
endobj
-4083 0 obj
+4106 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 475.083 267.465 486.032 ]/A << /S /GoTo /D (subsubsection.0.5.4.2) >> >>
endobj
-4084 0 obj
+4107 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 463.128 283.794 474.077 ]/A << /S /GoTo /D (subsubsection.0.5.4.3) >> >>
endobj
-4085 0 obj
+4108 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 451.283 259.216 462.122 ]/A << /S /GoTo /D (subsubsection.0.5.4.4) >> >>
endobj
-4086 0 obj
+4109 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 439.327 285.228 450.167 ]/A << /S /GoTo /D (subsubsection.0.5.4.5) >> >>
endobj
-4087 0 obj
+4110 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 429.086 260.89 438.212 ]/A << /S /GoTo /D (subsection.0.5.5) >> >>
endobj
-4088 0 obj
+4111 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 414.859 356.78 426.814 ]/A << /S /GoTo /D (subsubsection.0.5.5.1) >> >>
endobj
-4089 0 obj
+4112 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 402.904 423.071 414.859 ]/A << /S /GoTo /D (subsubsection.0.5.5.2) >> >>
endobj
-4090 0 obj
+4113 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 390.949 434.598 402.904 ]/A << /S /GoTo /D (subsubsection.0.5.5.3) >> >>
endobj
-4091 0 obj
+4114 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 379.552 298.12 390.5 ]/A << /S /GoTo /D (subsection.0.5.6) >> >>
endobj
-4092 0 obj
+4115 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 369.31 179.455 378.436 ]/A << /S /GoTo /D (subsection.0.5.7) >> >>
endobj
-4093 0 obj
+4116 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 78.374 345.679 226.618 356.578 ]/A << /S /GoTo /D (section.0.6) >> >>
endobj
-4094 0 obj
+4117 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 78.374 323.761 153.283 334.6 ]/A << /S /GoTo /D (section.0.7) >> >>
endobj
-4095 0 obj
+4118 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 311.686 196.72 322.645 ]/A << /S /GoTo /D (subsection.0.7.1) >> >>
endobj
-4096 0 obj
+4119 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 299.731 285.168 310.799 ]/A << /S /GoTo /D (subsection.0.7.2) >> >>
endobj
-4097 0 obj
+4120 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 287.776 215.52 298.735 ]/A << /S /GoTo /D (subsection.0.7.3) >> >>
endobj
-4098 0 obj
+4121 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 275.821 278.842 286.999 ]/A << /S /GoTo /D (subsection.0.7.4) >> >>
endobj
-4099 0 obj
+4122 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 263.875 207.39 274.824 ]/A << /S /GoTo /D (subsection.0.7.5) >> >>
endobj
-4100 0 obj
+4123 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 78.374 241.997 343.181 252.966 ]/A << /S /GoTo /D (section.0.8) >> >>
endobj
-4101 0 obj
+4124 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 229.992 222.155 240.951 ]/A << /S /GoTo /D (subsection.0.8.1) >> >>
endobj
-4102 0 obj
+4125 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 218.037 221.168 229.106 ]/A << /S /GoTo /D (subsection.0.8.2) >> >>
endobj
-4103 0 obj
+4126 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 205.644 250.508 217.599 ]/A << /S /GoTo /D (subsection.0.8.3) >> >>
endobj
-4104 0 obj
+4127 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 194.127 209.691 205.195 ]/A << /S /GoTo /D (subsection.0.8.4) >> >>
endobj
-4105 0 obj
+4128 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 182.172 235.007 193.131 ]/A << /S /GoTo /D (subsection.0.8.5) >> >>
endobj
-4118 0 obj
-<< /D [ 4116 0 R /XYZ 78.37 808.885 null ] >>
+4141 0 obj
+<< /D [ 4139 0 R /XYZ 78.37 808.885 null ] >>
endobj
-4115 0 obj
+4138 0 obj
<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F15 326 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
-4141 0 obj
-<< /Filter /FlateDecode /Length 4062 >>
+4164 0 obj
+<< /Filter /FlateDecode /Length 4060 >>
stream
-xÚÍÝÍnãÈ…á}_…o Ù$«øìqk€,ƒÞÙάf“û_¤È:§Ä’Lñ•A0èŸybSñ{Y¤Du/múß¿ÿ|é¶ßüã÷o￾ý¸ôýËÒ,c?Æ—_|Ëÿ®{™–&L/ÓØ5íؽüúëåŸkÛøóõ{·ôÃúÛ.ýóÞ¶CL¿Îmúüçí××Ð'3.mÛý–éï‡nûwÿúõ÷oíËŸéÛü^¾ÝÐÆ&ÆùöŽëW Ûÿ£»Ûú—nølÓ»ôµú)m|\š®¯Ÿ¶ méЧÑö½ÄÇk?kcÇvÝÈ×ïÛ_ô—ôé×wôº¥M?±þö»óž›®P÷íÐÌS¤º ÍØT÷]Ún®“êGªÃ˜¶{¢:Æ´Ý3ÕCŸ¶{¡zlÓvs=53ÞihÆÐQ=‡&ÌôiÒ/]Óü4IOªy¦:´cÚnú¤
-]LÛMŸ&¡ïÓvX/i»éÓ$„)m7ý¯â¶ë!¤í¦O“žT3Çs3Fú4 ÓØ„…>M›.bžTó‚Ÿ&Ë’¶›>Mb;¥í¦O“Ø i»éÓ$¦'Õ¼`Ú´ÝÖsÚnú4‰qLÛMÿËÇô¤Â6õo:¬—&¶XOSÓ ôYÓsjié³$.}Únú,RÏ–x÷µÖþ®îa}4ÝmÝÇ÷R÷q=,¹¬‡$¯ßC+šÒß¾ùOë¡ËvxÒ®/›&ÿi ÿÍ×èø”c xàSzP?œ³@­ ]zÀ´{À´{
-¤K)˜v*˜v+˜v, V-˜v.˜Î½`ÖÁ€ZÅ`ÚÉ`ÚÍ`ÚÑ@ºT£Ö[6˜q^š4ª–ÝAøõ0؇ÀC›Ï·ÀCc_ ¯¿çɵpˆó¥p†u%œa]gX×ÁÖepˆ·«à̪¤ +¤ «£çŒ"ìŠ2¬ˆ2¬†BœÊ°
-Ê°Ê°úÉpÎ'´¹ž +ž « +çr"ìp2¬n2¬l2¬jBœ£É°šÉð–LFULˆs0V/V.V-v,kR¹¦…¶2=’5IG±œwK¬»KÕ^T­g“tªZÝŸÀ:½ò]­¼Ž‹«lÔ~Ö ¦¦]¨•¤K;˜v<˜v= V>˜v?˜v@˜vA˜VB VC˜vD˜vE˜vF VG.!aÚ%aÚ)aÚ-Z1aÚ5a:ç„Y÷j…i…i'…i7é•Z¯U ¸*ãФ§üÑy»áATò¹µ|æ.¾]öXϾå?MêL,Nö½¹^c¿ïÍvŽ0}å)–¯õá×\=œÕ£;››{l"쩉°‡&š™Ìjd"쉉°&ž— k\\¦%–{V"ìQÉ°&%”ç9‰¨Ç$Ú’{H"쉰G$ÁeBVø¹™~œq<¾Pv{*öûùv<7_DÞ_™<GÛëy¯Ï^{zýzaÊrlç¬/8×—£Çíœš× w×ú‡u¶¿2í–iï±L{—…Zû,ÓÞi™Î{-³Þm¡Ö~Ë´w\¦½ç2í]é²ïÖzÛygºóÆ®ÚåpÍì¼ãv˜¢Ým¼¾Äû`±ë÷qÝ|Ë“÷qAíS×LûÜ5Ô:yÍ´Ï^3íÓ×Lûü5Ó> u>Á°OE0íSLûTÔ:t9Á´OE0í#j¨uHÍ´©™öA5Ó>ªfZ‡Õ븚iX3í#k¦}h µbt‰5ÓŽ5ÓŽ5ÓŽ5ÔŠ5ÓŽ5Ó9ÖÌ:ÖP+ÖL;ÖL;ÖL;ÖH—X×:ÌO¼†hLCc´··œi÷÷/•¼9Š}.ç%‹õFe‘ig‘ig‘igêœE†E¦E¦E¨•E¤K™v™v¡V™v™v™v™V!V™v™v™v¡V‘.YdÚYdÚYdÚY„ZYdÚYd:g‘Ygje‘ig‘ig‘igé’ÅZ‡ù™Pé×aYŽßζ]Cþ>ne ?sû¶÷›]®WjóŸ¯ç…ÊÕÛ÷}}VªîªßŽ°?¯õö„ݵ㇨ÃY V.`Ú`Ú€Z`Ú`Ú`Ú`Z€X`Ú`Ú`Ú€Z@ºD€iG€iG€iG
-ÔZ¦@­e
-ÔZ¦P½-S Ö2j-S Ö2…ê¼LaºT‘iW‘iWjU‘iW‘iW‘iW‘iUbU‘iW‘iW‘iWjUéRE¦]E¦]E¦]E¨UE¦]E¦s™u¡V™v™v™v‘.U¬u˜Ÿ¸QÖû4ͪÊõ'ßQñzëÝï/ðЛUoÍY³˜v³ ÎÍbØÍbÚÍbÚÍ‚ZÍBº4‹i7‹i7 j5‹i7‹i7‹i7‹i5 b5‹i7‹i7‹i7 j5 éÒ,¦Ý,¦Ý,¦Ý,¨Õ,¦Ý,¦s³˜u³ V³˜v³˜v³˜v³.ͪ5k–n ? iF÷÷+¹·³[Âìo0öÿq[xOùú!My¤Ë”gÚSžiOy¨5å™ö”gÚSžiOy¦5å!Ö”gÚSžiOy¦=å¡Ö”GºLy¦=å™ö”gÚSjMy¦=å™ÎSžYOy¨5å™ö”gÚSžiOy¤Ë”¯õ8<qG”!íØóx¿2y»»Ñû'Ó~¾.;»'¹ºáYò‹Å=åÍi/9ê:[r@— {ÉÁ´—L;FP+FH—1í1íA­1í1í1í1­A¬1í1í1íA­!]bÄ´cÄ´cÄ´cµbÄ´cÄtŽ³ŽÔŠÓŽÓŽÓŽÒ%Fµ^c„oe9„ôSíÂQŒv7”ÿrŒÚÝÍâ·O,y|¦¬Þ ³3eL;[Pçl1ìl1íl1ílA­l!]²Å´³Å´³µ²Å´³Å´³Å´³Å´²±²Å´³Å´³Å´³µ²…tÉÓÎÓÎÓÎÔÊÓÎÓ9[Ì:[P+[L;[L;[L;[H—lÕzŒÛ™.˜­¾k–áp UݸÿkÙêß¾jûfN^µ µ_Á´ƒÉ´ƒÉ´ƒ u&Ã&Ó&Ó&Ô
-&Ò%˜L;˜L;˜P+˜L;˜L;˜L;˜L+˜+˜L;˜L;˜L;˜P+˜H—`2í`2í`2í`B­`2í`2ƒÉ¬ƒ µ‚É´ƒÉ´ƒÉ´ƒ‰t f­×`žÚ°ƒÙµMŠÚQ0wŸYðÕ`®oßÞÖ RãVoÈYܘvܘvÜ ÎqcØqcÚqcÚqƒZqCºÄiÇiÇ jÅiÇiÇiÇiÅ bÅiÇiÇiÇ jÅ é7¦7¦7¦7¨7¦7¦sܘuÜ VܘvܘvܘvÜ.q«uO\Q‹iØ¥îÆmþoãÖ]Öòy«oØT^8§¦æf§b¥j¥j¥†êœ¦¨•¨•ªsj Vj Vj Vj Î©¡8§j¥j¥j¥†êœ¦¨•¨•¨•ªsj Vj ÞR­RCuN ÔJ ÔJ ÔJ ÓNÍ^SƒO<ÆylÚåpU}ò@~§ÕÔçÏí>Q }ÆÝG3—»þ}zì³î½
-ùísíô ©þýõsLoÞß›ßý{øÒù²oÔ?ñ³}ƒé¼o0ë}jíL{ß`ÚûÓÞ7.ûF­·}ƒ^KŽSêA8< ÛÝs~}ÒWž'ÿÃ]âþÆóAoÿèCþçÑy8èõOä$è+èL;èL;èL;èP+èH— 3í 3í 3í C­¡Å´‡Óyh1롵†ÓZL{h1í¡…tZµ~nhiÍ0Ÿ wA¿†Üo˳æöÀ?yýùçÙ}>âè'×y•W?¦³UÔZå!]VyL{•Ç´WyPk•Ç´WyL{•Ç´£À´¢
-Ì:
-P+
-L;
-L;
-L;
-H—(Ôz¾Z‡6ýzx$[ÝÓý³(øØöºJº& ÿ› ž€Üö~¾J»ÏÌz »Ý+þæm[×Ï¡û¼.c{—ÝÃÒ”Rÿ ÎFÓ!Pk„ ]FÓ!L{„0íµFÓ!Lç¬GÔ!L{„0í´GÒe„Ôz!‡ïåüqéû—¥YÆ~ýЧ?Êך–&™Æ>ý÷Û}…î~Ý…¡ÝÝþzÜÝpg!w<ÚØÄ8ß~ÑuJé°÷Ç¥>Û˜~û1¤§hÛ,õ½ô¸~þúöõéÄË
+xÚÍÝÍnãÈ…á}_…o Ù$«øìqk€,ƒÞÙάf“û_¤È:§Ä’DñµÁ`ÐÏØTø½,R¢º—6ýóï?_ºí'ÿøýÛû¯o?.}ÿ²4ËØñå×ßòŸu/ÓÒ„ée»¦»—_½üóom¾~ï–~XÚ¥ßÛvˆéǹmCŸ½ýøñúdÆ¥m»ßò1ýþÐmö¯_ÿÖ¾ü™¾ÍïåÛ mlbœo¿á¸~Å°ýÝÝÖÿ¸tãMïÒ×꧴ñqiºv¼n|Ú‚´¥CŸDÛ÷~¯ý¬Ûu#_¿o¿Ñ_Òo|¤ßÑ#è–6ýõ·ßu˜ôÜt}€ºo‡fž"Õ]hÆ~ ºïÒvsT?RÆ´ÝÕ1¦íž©ú´Ý Õc›¶›ë©™ñ†LC3†Žê94a¦O“~éš.à§IzRÍ3Õ¡ÓvÓ'UèbÚnú4 }Ÿ¶{ÄzIÛMŸ&!Li»éÿ‡´ÝX!m7}š„ô¤š9ž›1Ò§I˜Æ&,ôiæØtëô¤šü4Y–´ÝôiÛ)m7}šÄnHÛMŸ&1=©æëЦힰžÓvÓ§IŒcÚnú>¦'¶©ãÐa½4±Åzššn Ï’˜žSKKŸ%qéÓvÓgÉz¶Ä»¯ý´öwuë£énë>¾—ºëaÉe=$yýBXÑ”~÷Í¿Z]¶Ã“v |ùÝ”ø0ùWkøo¾FÿôÀ§KÀŸÒƒúáœõ
+
+Ó.
+ÓN
+Ón
+Ò%*µ^«pUÆ¡IOù£óvÓ¨äskùÌ]|?ºì±ž}Ë¿šÔ™X.œì{s½Æ~ß›íaúÊS,_ëï¹z>8«Gw67öØDØSaM„53™ÕÈDØaL„=/Ö¸$¸LK„=,ö¬DØ£’aMJ„=(ÎsQI†5%öDØ3aH‚Ë„¬ðçdúëŒãñ…âøì°ÛS±ßÏ·ã¹ùü"òþêÈä9Ú^Ï{=zíéõë…)˱=ž³¾à\_Ž·sj^'<ß]뿬³ý•iï°L{eÚ»,ÔÚg™öNËtÞk™õn µö[¦½ã2í=—iïºH—}·ÖÛÎ;Ó7vÍÐ.‡kæðdç·Ãínãõ%Þ‹]¿ëæ[ž¼ jŸºfÚ管ÖÉk¦}öšiŸ¾fÚ篙ö l¨ó©†}*‚iŸŠ`Ú§" Ö©¤Ë©¦}*‚iQC­Cj¦}LÍ´ª™öQ5Ó:¬†XÇÕLûÀšiY3íCk¨k¤K¬™v¬™v¬™v¬¡V¬™v¬™Î±fÖ±†Z±fÚ±fÚ±fÚ±FºÄºÖ!¿öÆ: a8<ÒÞÞr~x¤Ýß¿Tòæ(ös9/Y¬7ê,‹L;‹L;‹L;‹Pç,2ì,2í,2í,B­,"]²È´³È´³µ²È´³È´³È´³È´²±²È´³È´³È´³µ²ˆtÉ"ÓÎ"ÓÎ"ÓÎ"ÔÊ"ÓÎ"Ó9‹Ì:‹P+‹L;‹L;‹L;‹H—,Ö:ÌŸYæ‡e9~;Ûv ùû¸•1üÌíÛÞov¹^©Í¿¾ž*Woß÷}ôY©º«~;Âþ¼RÔÛv׎ŸF ~ g€Z@ºD€iG€iG
+ùísíô ©þùõsLoÞß›ßý{øÒù²oÔãgûÓyß`ÖûÔÚ7˜ö¾Á´÷ ¦½o ]öZ¯û¾–§Ôƒpx¶»çüú¥¯<Oþ‡»ÄýçƒÞþчüï³òpÐë¿‘“ C¬ 3í 3í 3í C­ #]‚δƒÎ´ƒÎ´ƒµ†ÓZLç¡Å¬‡ÔZL{h1í¡Å´‡ÒehÕúsCkLk†ùøÄh¸ ú5ä~CXž5·
endstream
endobj
-4140 0 obj
-<< /Type /Page /Contents 4141 0 R /Resources 4139 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3779 0 R /Annots 4143 0 R >>
+4163 0 obj
+<< /Type /Page /Contents 4164 0 R /Resources 4162 0 R /MediaBox [ 0 0 595.276 841.89 ] /Parent 3742 0 R /Annots 4166 0 R >>
endobj
-4143 0 obj
-[ 4106 0 R 4107 0 R 4108 0 R 4109 0 R 4110 0 R 4111 0 R 4112 0 R 4113 0 R 4114 0 R 4120 0 R 4121 0 R 4122 0 R 4123 0 R 4124 0 R 4125 0 R 4126 0 R 4127 0 R 4128 0 R 4129 0 R 4130 0 R 4131 0 R 4132 0 R 4133 0 R 4134 0 R 4135 0 R 4136 0 R 4137 0 R 4138 0 R ]
+4166 0 obj
+[ 4129 0 R 4130 0 R 4131 0 R 4132 0 R 4133 0 R 4134 0 R 4135 0 R 4136 0 R 4137 0 R 4143 0 R 4144 0 R 4145 0 R 4146 0 R 4147 0 R 4148 0 R 4149 0 R 4150 0 R 4151 0 R 4152 0 R 4153 0 R 4154 0 R 4155 0 R 4156 0 R 4157 0 R 4158 0 R 4159 0 R 4160 0 R 4161 0 R ]
endobj
-4106 0 obj
+4129 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 78.374 758.132 184.546 768.971 ]/A << /S /GoTo /D (section.0.9) >> >>
endobj
-4107 0 obj
+4130 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 747.89 182.752 757.016 ]/A << /S /GoTo /D (subsection.0.9.1) >> >>
endobj
-4108 0 obj
+4131 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 734.222 281.114 745.17 ]/A << /S /GoTo /D (subsection.0.9.2) >> >>
endobj
-4109 0 obj
+4132 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 722.147 266.498 733.215 ]/A << /S /GoTo /D (subsubsection.0.9.2.1) >> >>
endobj
-4110 0 obj
+4133 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 712.025 308.71 721.26 ]/A << /S /GoTo /D (subsubsection.0.9.2.2) >> >>
endobj
-4111 0 obj
+4134 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 700.07 268.292 709.305 ]/A << /S /GoTo /D (subsubsection.0.9.2.3) >> >>
endobj
-4112 0 obj
+4135 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 686.401 208.436 697.35 ]/A << /S /GoTo /D (subsubsection.0.9.2.4) >> >>
endobj
-4113 0 obj
+4136 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 676.159 258.718 685.395 ]/A << /S /GoTo /D (subsubsection.0.9.2.5) >> >>
endobj
-4114 0 obj
+4137 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 664.204 316.441 673.439 ]/A << /S /GoTo /D (subsubsection.0.9.2.6) >> >>
endobj
-4120 0 obj
+4143 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 652.249 397.756 661.484 ]/A << /S /GoTo /D (subsubsection.0.9.2.7) >> >>
endobj
-4121 0 obj
+4144 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 638.471 194.479 649.42 ]/A << /S /GoTo /D (subsubsection.0.9.2.8) >> >>
endobj
-4122 0 obj
+4145 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 626.515 223.271 637.464 ]/A << /S /GoTo /D (subsubsection.0.9.2.9) >> >>
endobj
-4123 0 obj
+4146 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 614.55 274.508 625.619 ]/A << /S /GoTo /D (subsubsection.0.9.2.10) >> >>
endobj
-4124 0 obj
+4147 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 602.605 185.562 613.664 ]/A << /S /GoTo /D (subsubsection.0.9.2.11) >> >>
endobj
-4125 0 obj
+4148 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 590.64 300.033 601.708 ]/A << /S /GoTo /D (subsubsection.0.9.2.12) >> >>
endobj
-4126 0 obj
+4149 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 578.804 227.614 589.644 ]/A << /S /GoTo /D (subsubsection.0.9.2.13) >> >>
endobj
-4127 0 obj
+4150 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 568.563 238.005 577.689 ]/A << /S /GoTo /D (subsubsection.0.9.2.14) >> >>
endobj
-4128 0 obj
+4151 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 103.28 554.894 286.653 565.843 ]/A << /S /GoTo /D (subsection.0.9.3) >> >>
endobj
-4129 0 obj
+4152 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 542.819 244.073 553.778 ]/A << /S /GoTo /D (subsubsection.0.9.3.1) >> >>
endobj
-4130 0 obj
+4153 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 530.864 240.317 541.933 ]/A << /S /GoTo /D (subsubsection.0.9.3.2) >> >>
endobj
-4131 0 obj
+4154 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 518.909 219.285 529.977 ]/A << /S /GoTo /D (subsubsection.0.9.3.3) >> >>
endobj
-4132 0 obj
+4155 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 506.954 231.609 518.022 ]/A << /S /GoTo /D (subsubsection.0.9.3.4) >> >>
endobj
-4133 0 obj
+4156 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 494.999 257.761 505.958 ]/A << /S /GoTo /D (subsubsection.0.9.3.5) >> >>
endobj
-4134 0 obj
+4157 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 483.043 432.127 494.112 ]/A << /S /GoTo /D (subsubsection.0.9.3.6) >> >>
endobj
-4135 0 obj
+4158 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 471.088 350.832 482.157 ]/A << /S /GoTo /D (subsubsection.0.9.3.7) >> >>
endobj
-4136 0 obj
+4159 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 460.966 276.381 470.202 ]/A << /S /GoTo /D (subsubsection.0.9.3.8) >> >>
endobj
-4137 0 obj
+4160 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 116.232 447.178 373.667 458.246 ]/A << /S /GoTo /D (subsubsection.0.9.3.9) >> >>
endobj
-4138 0 obj
+4161 0 obj
<< /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [ 78.374 425.32 142.892 436.139 ]/A << /S /GoTo /D (section.0.10) >> >>
endobj
-4142 0 obj
-<< /D [ 4140 0 R /XYZ 78.37 808.885 null ] >>
+4165 0 obj
+<< /D [ 4163 0 R /XYZ 78.37 808.885 null ] >>
endobj
-4139 0 obj
+4162 0 obj
<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font << /F22 357 0 R /F15 326 0 R >> /ProcSet [ /PDF /Text ] >>
endobj
1 0 obj
@@ -13525,28 +13591,28 @@ endobj
3 0 obj
<< /pgfprgb [/Pattern /DeviceRGB] >>
endobj
-4145 0 obj
+4168 0 obj
[513.9 ]
endobj
-4147 0 obj
+4170 0 obj
[686.7 0 0 0 0 0 0 0 0 0 0 560.2 0 0 0 0 0 0 571 702.2 706.8 0 0 0 686.7 ]
endobj
-4149 0 obj
+4172 0 obj
[513.9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 399.7 399.7 ]
endobj
-4150 0 obj
+4173 0 obj
[525 ]
endobj
-4151 0 obj
+4174 0 obj
[ 3 [ 602.1 ] 5 [ 602.1 ] 11 [ 602.1 602.1 ] 38 [ 602.1 ] 68 [ 602.1 602.1 602.1 ] 72 [ 602.1 602.1 ] 75 [ 602.1 602.1 ] 79 [ 602.1 602.1 602.1 602.1 602.1 ] 85 [ 602.1 602.1 602.1 602.1 602.1 ] 91 [ 602.1 ] ]
endobj
-4153 0 obj
+4176 0 obj
<< /Filter /FlateDecode /Length 20 >>
stream
xÚ›"ÁÀÀÄÀÀÀwóû
endstream
endobj
-4154 0 obj
+4177 0 obj
<< /Filter /FlateDecode /Length 11571 >>
stream
xÚí| |UÖï­ºU½%étv¶î®î& ˜&Av"J  IL¡“î,’¤cºC@DÜ ""âÂ(.ƒ(ã‚{TÔ™qG™‡apFÒè'ƒ>Ÿ£Pýþ÷Vu6Pç›÷¾÷~ßï÷Òž>·nÝ{ösî©J„xr%¡¤ ¼*oܱÇ?ý3oÔµøÚFŽ{÷1B„‘„¤¤×­+¯8šEHê4̽PßÖÐrôÖÿ±Ÿ´ï°~cCóªú;ÞzêEBÒ¯%$éÚƀϯvTÜMÈ(îOjÄ„e†èÅu®G6¶„WÆ¿.Íŵ×Ï7ë| T%2Za×-¾•m’O2àú/¸VZ}-Zóòq}’W}[{ mJtÃZBæb¿tœÒûÂMD&D/ßA& †£Åô¤^U1Î`¦TŠ¥1D+ɪDPeRQ_ì'Q¢QCªš*l3¶Ÿ,#Â/ÿ‘h?  Ù‰DˆáÂìF’â1+ðyJ,|^2ü¶y “FË‘+„ׄCÂ'·Â?E§è Åbqž¸G|EüøøWñ3ñ¸ø5NgÒEÔG;èeô
@@ -13582,10 +13648,10 @@ R ¸kBXäæ±_"‘öPS°U—;~Â@Ž1~1ncÎÌ1c¼ÆüˆØõ|»$a= b‚Ö[á¬0\Hx …ù$¿Nchäbo
å ßÓëâi×ÂL¹ËOׯÛ+¯Wéºk—ÈëöÒuWJ×^“)_»„^[ ]“I¯VéU[é•Ø´V¥W
endstream
endobj
-4152 0 obj
-<< /Type /FontDescriptor /FontName /GMFTGJ+DejaVuSansMono-Oblique /Flags 4 /FontBBox [ 0 -208 1000 760 ] /Ascent 760 /CapHeight 729 /Descent -208 /ItalicAngle 0 /StemV 86 /XHeight 547 /FontFile2 4154 0 R /CIDSet 4153 0 R >>
+4175 0 obj
+<< /Type /FontDescriptor /FontName /GMFTGJ+DejaVuSansMono-Oblique /Flags 4 /FontBBox [ 0 -208 1000 760 ] /Ascent 760 /CapHeight 729 /Descent -208 /ItalicAngle 0 /StemV 86 /XHeight 547 /FontFile2 4177 0 R /CIDSet 4176 0 R >>
endobj
-4155 0 obj
+4178 0 obj
<< /Filter /FlateDecode /Length 477 >>
stream
xÚ“Ooâ0ÅïùÞ=¤8!h…"µ¡T¬D©
@@ -13597,21 +13663,21 @@ xÚ“Ooâ0ÅïùÞ=¤8!h…"µ¡T¬D©
endstream
endobj
558 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /GMFTGJ+DejaVuSansMono-Oblique /DescendantFonts [ 4156 0 R ] /ToUnicode 4155 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /GMFTGJ+DejaVuSansMono-Oblique /DescendantFonts [ 4179 0 R ] /ToUnicode 4178 0 R >>
endobj
-4156 0 obj
-<< /Type /Font /Subtype /CIDFontType2 /CIDToGIDMap /Identity /BaseFont /GMFTGJ+DejaVuSansMono-Oblique /FontDescriptor 4152 0 R /W 4151 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4179 0 obj
+<< /Type /Font /Subtype /CIDFontType2 /CIDToGIDMap /Identity /BaseFont /GMFTGJ+DejaVuSansMono-Oblique /FontDescriptor 4175 0 R /W 4174 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4157 0 obj
+4180 0 obj
[ 3 [ 602.1 ] 6 [ 602.1 ] 11 [ 602.1 602.1 602.1 602.1 602.1 602.1 ] 18 [ 602.1 602.1 602.1 602.1 ] 29 [ 602.1 ] 31 [ 602.1 602.1 602.1 ] 68 [ 602.1 ] 70 [ 602.1 ] 72 [ 602.1 ] 74 [ 602.1 602.1 602.1 ] 78 [ 602.1 602.1 602.1 602.1 ] 83 [ 602.1 ] 85 [ 602.1 602.1 602.1 602.1 602.1 ] 91 [ 602.1 ] ]
endobj
-4159 0 obj
+4182 0 obj
<< /Filter /FlateDecode /Length 20 >>
stream
xÚ›$¿‡õ
endstream
endobj
-4160 0 obj
+4183 0 obj
<< /Filter /FlateDecode /Length 12930 >>
stream
xÚí¼ |Eú7^ÕÕÝ3™I&3!!áÈLg†d8†$†KÍE€@Hb.•cÈLH„æ
@@ -13662,10 +13728,10 @@ WTÍÇ.¥šÏ¬/†ÞkúKK«+k0O¨/w)XU»…I܃À, ùëêªK+üØ,m¨ VÕûë¹<e a㜣X W—Õ/†ÍÝ
»MgËuv«#K¹µ˜Ý¢³e׳›oZªÜ¬³›–²¥Nv£Î–ØØ :[¬³E:k¨W"YC%ŸÈõá¬~¿\Åê2äZ]§³UW+ÕëYUå@¥ª˜Ud u¶ ]«³Š4Vþ#›¿‡•é,¨³€ÎJç9•RÍ#vež“ùu6Wgst6û*«2ÛÆfØ5o±«qqu4»ÊÊ€èÑlºÎ¦élj¿>ÊÔ4V¢³béìÊ¥¬PgÑ,_gSèPeŠÎòö°ÉÙ¤Ü8eÒ(–›¥äƱ‰9qÊDMÀÕ„
endstream
endobj
-4158 0 obj
-<< /Type /FontDescriptor /FontName /FGWDXK+DejaVuSansMono /Flags 4 /FontBBox [ 0 -208 1000 760 ] /Ascent 760 /CapHeight 729 /Descent -208 /ItalicAngle 0 /StemV 86 /XHeight 547 /FontFile2 4160 0 R /CIDSet 4159 0 R >>
+4181 0 obj
+<< /Type /FontDescriptor /FontName /FGWDXK+DejaVuSansMono /Flags 4 /FontBBox [ 0 -208 1000 760 ] /Ascent 760 /CapHeight 729 /Descent -208 /ItalicAngle 0 /StemV 86 /XHeight 547 /FontFile2 4183 0 R /CIDSet 4182 0 R >>
endobj
-4161 0 obj
+4184 0 obj
<< /Filter /FlateDecode /Length 507 >>
stream
xÚ}“Koâ0…÷ùž]¤8oZ¡H@`„F}¨ N·!¾09É‚?¶i¥
@@ -13678,21 +13744,21 @@ PZƒ0=Âô  ‚0/¼
endstream
endobj
557 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /FGWDXK+DejaVuSansMono /DescendantFonts [ 4162 0 R ] /ToUnicode 4161 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /FGWDXK+DejaVuSansMono /DescendantFonts [ 4185 0 R ] /ToUnicode 4184 0 R >>
endobj
-4162 0 obj
-<< /Type /Font /Subtype /CIDFontType2 /CIDToGIDMap /Identity /BaseFont /FGWDXK+DejaVuSansMono /FontDescriptor 4158 0 R /W 4157 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4185 0 obj
+<< /Type /Font /Subtype /CIDFontType2 /CIDToGIDMap /Identity /BaseFont /FGWDXK+DejaVuSansMono /FontDescriptor 4181 0 R /W 4180 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4163 0 obj
+4186 0 obj
[ 68 [ 602.1 ] 70 [ 602.1 602.1 602.1 602.1 ] 76 [ 602.1 ] 79 [ 602.1 602.1 602.1 602.1 602.1 ] 85 [ 602.1 602.1 602.1 602.1 ] ]
endobj
-4165 0 obj
+4188 0 obj
<< /Filter /FlateDecode /Length 15 >>
stream
xÚk`€
endstream
endobj
-4166 0 obj
+4189 0 obj
<< /Filter /FlateDecode /Length 10706 >>
stream
xÚí{ xTÕ¹öÚ{í=3™I& ¹.3³g†d ¡( $@$7“pS&™I2dâÌ„-
@@ -13748,10 +13814,10 @@ L‹/ª´ø"àhéˆB¸_él÷ë
_Q ‡UzEíÀÛŽÍ4”CÛÛŽÈí*mk]#·¡m[¤Ö`®Üº†¶K6ÐõxX„‹ã¹´kZü´M³Ÿ6AR“Ò¨_¥*mP©o3]§ÒËýô²K3åËTzi&½¤ˆ®ž6F^MWeÓ•dŒ¼R¥+Šèr•Ö×Yäú4Zg¡µg˵{èÅ5iòÅÙ´&V«´ªÒ/Wí¡•~Z¡Òe*½¨<C¾h-Ï KÏÐ%gèâÍ´¬4C.ÛLK3è¢Zb¥ Šè…éô‚ùVù•ÎÿšEžo¥_³ÐysÇÊóöйç[ä¹céÜ-Òùz~±4ç¼yÎz”;/‡Îž•#Ï^FgÍÌ”gåЙ™´hFŽ\ä§3ðzF^˜Sœ-O/¥…9´
endstream
endobj
-4164 0 obj
-<< /Type /FontDescriptor /FontName /WYCBGG+DejaVuSansMono-Bold /Flags 4 /FontBBox [ 0 -207 1000 760 ] /Ascent 760 /CapHeight 729 /Descent -207 /ItalicAngle 0 /StemV 150 /XHeight 547 /FontFile2 4166 0 R /CIDSet 4165 0 R >>
+4187 0 obj
+<< /Type /FontDescriptor /FontName /WYCBGG+DejaVuSansMono-Bold /Flags 4 /FontBBox [ 0 -207 1000 760 ] /Ascent 760 /CapHeight 729 /Descent -207 /ItalicAngle 0 /StemV 150 /XHeight 547 /FontFile2 4189 0 R /CIDSet 4188 0 R >>
endobj
-4167 0 obj
+4190 0 obj
<< /Filter /FlateDecode /Length 434 >>
stream
xÚ…’Mo›@†ïû+¦KΰØÆ4‘…Tã8â+mxwìnevÑÿûîî˜DŠš Äü3¼3;“/ÏUôMš=Fók/Ø™Á
@@ -13760,21 +13826,21 @@ wX´qû==mÙRl Á
endstream
endobj
556 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /WYCBGG+DejaVuSansMono-Bold /DescendantFonts [ 4168 0 R ] /ToUnicode 4167 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /WYCBGG+DejaVuSansMono-Bold /DescendantFonts [ 4191 0 R ] /ToUnicode 4190 0 R >>
endobj
-4168 0 obj
-<< /Type /Font /Subtype /CIDFontType2 /CIDToGIDMap /Identity /BaseFont /WYCBGG+DejaVuSansMono-Bold /FontDescriptor 4164 0 R /W 4163 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4191 0 obj
+<< /Type /Font /Subtype /CIDFontType2 /CIDToGIDMap /Identity /BaseFont /WYCBGG+DejaVuSansMono-Bold /FontDescriptor 4187 0 R /W 4186 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4169 0 obj
+4192 0 obj
[ 28 [ 603 ] 35 [ 544 ] 43 [ 544 ] ]
endobj
-4171 0 obj
+4194 0 obj
<< /Filter /FlateDecode /Length 14 >>
stream
xÚc``à
endstream
endobj
-4172 0 obj
+4195 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 852 >>
stream
xÚmS]LY¾Óãʈʦ;0sÅ°b[¢£Ñ!¨¨©Y‰ò0¥ÓvdèàÌÔ
@@ -13783,10 +13849,10 @@ xÚmS]LY¾Óãʈʦ;0sÅ°b[¢£Ñ!¨¨©Y‰ò0¥ÓvdèàÌÔ
Õ|M -¶#=Ú´øœÌÎìÇJ…À×jã 6eF½>'0ªTžCbddt Yãàlø2ž•ZöoV*99­éÕ‘!Ÿ93ŒD£§cƒ)|ù'ùa½
endstream
endobj
-4170 0 obj
-<< /Type /FontDescriptor /FontName /HSGBBJ+LMRoman7-Italic /Flags 4 /FontBBox [ -528 -292 1571 1123 ] /Ascent 1123 /CapHeight 683 /Descent -292 /ItalicAngle -15 /StemV 123 /XHeight 431 /FontFile3 4172 0 R /CIDSet 4171 0 R >>
+4193 0 obj
+<< /Type /FontDescriptor /FontName /HSGBBJ+LMRoman7-Italic /Flags 4 /FontBBox [ -528 -292 1571 1123 ] /Ascent 1123 /CapHeight 683 /Descent -292 /ItalicAngle -15 /StemV 123 /XHeight 431 /FontFile3 4195 0 R /CIDSet 4194 0 R >>
endobj
-4173 0 obj
+4196 0 obj
<< /Filter /FlateDecode /Length 370 >>
stream
xÚ}R]kƒ0}ϯ¸{(´ÖØÂE„µ]7ÇúA-c¯6¹vM$Ƈþû%±¶0º ŠÇsÎõÜ£ƒ‡]<suÄ`:¦°ÇFµša°Xç5 –ŠµJ³AäÈ{¶™ÁN+–¡á"]¦R˜‘§’•-Ç^u_4Ç“7‰{ ø¼e¯óù{ð±Þ«*—OAjòR°€:ÓA˜ÒŠÿÕ%á> ~È'êF(9ƒhL)µ^$_¨Ê­×ðÂ>t!$×—œpt©I4.˜¹ e•íÉ™³sc°Je¡HC¸·dcôÙg‘p«9j!O0¼ÑJ²¶®Ktq€’$Ž…lûÙäBèvO¹e…9ÿQÂÍr8×£..S›:g¨syBÛ
@@ -13794,28 +13860,28 @@ hñÊ AÉñ´s‹ZA;íök7'ZØ9”>F‰C“i‡&šwhšt#¼Ç½ÍÕvݵZÛÅ|·>¾ .$^ë¯Uí\þôß­ÿÚ®È
endstream
endobj
544 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /HSGBBJ+LMRoman7-Italic /DescendantFonts [ 4174 0 R ] /ToUnicode 4173 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /HSGBBJ+LMRoman7-Italic /DescendantFonts [ 4197 0 R ] /ToUnicode 4196 0 R >>
endobj
-4174 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /HSGBBJ+LMRoman7-Italic /FontDescriptor 4170 0 R /W 4169 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4197 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /HSGBBJ+LMRoman7-Italic /FontDescriptor 4193 0 R /W 4192 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4175 0 obj
+4198 0 obj
[758.1 ]
endobj
-4176 0 obj
+4199 0 obj
[892.9 ]
endobj
-4177 0 obj
+4200 0 obj
[ 28 [ 525 ] 50 [ 525 ] 55 [ 525 ] 66 [ 525 ] 72 [ 525 ] 75 [ 525 ] 77 [ 525 ] 81 [ 525 ] 96 [ 525 ] 98 [ 525 ] 105 [ 525 ] 110 [ 525 ] 112 [ 525 ] 116 [ 525 ] 118 [ 525 ] ]
endobj
-4179 0 obj
+4202 0 obj
<< /Filter /FlateDecode /Length 23 >>
stream
xÚc``à``PdP˜âÀ°À©
Š
endstream
endobj
-4180 0 obj
+4203 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 1970 >>
stream
xÚV PT×¾ËroWYöºŽíQÎ-UB£<JL|Ð:ˆÊ£aµ>ÒÊÂ.»+Ë^Ø]–·
@@ -13833,10 +13899,10 @@ n¦(£Ô»ø!©sös.Ðw’ûõ ˆÐ#rÔo>Ë^Gûðr´Ï!¼^DûèÛ|ã³…)—Š@/#ˆ"É T×ðsƒ`Í
endstream
endobj
-4178 0 obj
-<< /Type /FontDescriptor /FontName /OMFOSG+LMMonoSlant10-Regular /Flags 4 /FontBBox [ -477 -316 786 1016 ] /Ascent 1016 /CapHeight 611 /Descent -316 /ItalicAngle -10 /StemV 175 /XHeight 431 /FontFile3 4180 0 R /CIDSet 4179 0 R >>
+4201 0 obj
+<< /Type /FontDescriptor /FontName /OMFOSG+LMMonoSlant10-Regular /Flags 4 /FontBBox [ -477 -316 786 1016 ] /Ascent 1016 /CapHeight 611 /Descent -316 /ItalicAngle -10 /StemV 175 /XHeight 431 /FontFile3 4203 0 R /CIDSet 4202 0 R >>
endobj
-4181 0 obj
+4204 0 obj
<< /Filter /FlateDecode /Length 437 >>
stream
xÚ“Ájã0†ïz
@@ -13845,16 +13911,16 @@ u¢kš
|Q”‘4¥N.¿›Û[Yý4rá¢Ò^®ŽåÇx¸4@',kmSr0¥:Y¹q°”®¶îJ (ñ+ÎÐu<!:ÁðšÌ†ÿ,O”d.có$õ4 ÍHó@÷}l‰ô€”!=#­‘ÖH›@³ihÎ-&H˜s1EZ"Ý#mÍзè}X‹“z@š#-Sì5ôæÇâ÷ú{+xgŒÛ‡p Âœý„¥‚ï3ÓèÆ»ÂÛðxÚoÉ,x
endstream
endobj
-428 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /OMFOSG+LMMonoSlant10-Regular /DescendantFonts [ 4182 0 R ] /ToUnicode 4181 0 R >>
+427 0 obj
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /OMFOSG+LMMonoSlant10-Regular /DescendantFonts [ 4205 0 R ] /ToUnicode 4204 0 R >>
endobj
-4182 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /OMFOSG+LMMonoSlant10-Regular /FontDescriptor 4178 0 R /W 4177 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4205 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /OMFOSG+LMMonoSlant10-Regular /FontDescriptor 4201 0 R /W 4200 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4183 0 obj
+4206 0 obj
[ 27 [ 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 ] 104 [ 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 ] 138 [ 525 525 ] 162 [ 525 525 ] 201 [ 525 525 ] 245 [ 525 525 ] 251 [ 525 525 ] 265 [ 525 525 ] 271 [ 525 525 ] 337 [ 525 525 ] 341 [ 525 525 ] 420 [ 525 525 ] 564 [ 525 525 ] 568 [ 525 525 ] 602 [ 525 ] ]
endobj
-4185 0 obj
+4208 0 obj
<< /Filter /FlateDecode /Length 47 >>
stream
xÚc``ÿÿþÿ?À`À
@@ -13862,7 +13928,7 @@ xÚc``ÿÿþÿ?À`À
endstream
endobj
-4186 0 obj
+4209 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 9121 >>
stream
xÚÍ{`ÇÖî
@@ -13910,10 +13976,10 @@ DûùçºfðÀ:2 £ì¼\È´ –î[fpéš¡’Á™HIb>ÊŽŒ‚*eç$/I·ÛáÖ#j`V!6õN+‡£AسG`vÄ+Àƒ5b
a‘LCÆß¡ÃÝ®OqüÓâë
endstream
endobj
-4184 0 obj
-<< /Type /FontDescriptor /FontName /TPIQHG+LMMono9-Regular /Flags 4 /FontBBox [ -451 -318 734 1016 ] /Ascent 1016 /CapHeight 611 /Descent -318 /ItalicAngle 0 /StemV 175 /XHeight 431 /FontFile3 4186 0 R /CIDSet 4185 0 R >>
+4207 0 obj
+<< /Type /FontDescriptor /FontName /TPIQHG+LMMono9-Regular /Flags 4 /FontBBox [ -451 -318 734 1016 ] /Ascent 1016 /CapHeight 611 /Descent -318 /ItalicAngle 0 /StemV 175 /XHeight 431 /FontFile3 4209 0 R /CIDSet 4208 0 R >>
endobj
-4187 0 obj
+4210 0 obj
<< /Filter /FlateDecode /Length 853 >>
stream
xÚ}–QOÛ:†ïû+r.¶‹®I;0¡Jmšn•ÆÆèèÜ–Äp"ѤJÛ þýIü¼ibCñÔŽý>Ÿ»ÝÞMu÷à§æSýô‡îÔW~ZÜl÷“‹‹UWv¾=~÷¾öõ¹õð9ºí»êΣÅfµi›ãÇ¡ó¦­žOµ?÷z¿ÓÒ?5í[—qžèýÿwz»ùûë—é·››®í®¦?ýÓéyÛOãñ¡ûæø<tþc¿hhŒÞoŒÂ ÿøþÐtíç(ùÇñðAÙÖE·õ“™"F³sèǦ­{åŒÆÔ“$ê¦:ŠÂßj7Ôi|øîåpô»MûØM®¯£Ù0ss8ö/!óÇÉìG_û¾iŸ~7âÐåî´ß?û1NOæó¨öÃÈC}¾ow>šî›zhmŽ/¿)ÂÛ#÷/{¥âV]íûmåûmûä'×C âyt½~æßÖ¿´Ç<õðÎÿ&ñk[õ߶GJ–ÃHqœ%ó@E 'ZJT²%´”CiLÏ”0f ¥P
@@ -13923,21 +13989,21 @@ z.ÈRB£ä,¥ÌçÉáN®~=×D.¹&r)bê‚kJ[JbM¶„4™ˆÒ¡(IBiKH/CQBè”"eYCÊ-(ô*ƒè¹”êØ[
endstream
endobj
404 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /TPIQHG+LMMono9-Regular /DescendantFonts [ 4188 0 R ] /ToUnicode 4187 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /TPIQHG+LMMono9-Regular /DescendantFonts [ 4211 0 R ] /ToUnicode 4210 0 R >>
endobj
-4188 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /TPIQHG+LMMono9-Regular /FontDescriptor 4184 0 R /W 4183 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4211 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /TPIQHG+LMMono9-Regular /FontDescriptor 4207 0 R /W 4206 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4189 0 obj
+4212 0 obj
[ 35 [ 580 ] 47 [ 624 ] 50 [ 558 ] 55 [ 536 ] 59 [ 641 ] 72 [ 513 ] 77 [ 613 ] 81 [ 636 ] 84 [ 558 ] 96 [ 602 ] 98 [ 458 ] 112 [ 613 ] 116 [ 613 ] ]
endobj
-4191 0 obj
+4214 0 obj
<< /Filter /FlateDecode /Length 23 >>
stream
xÚc````T`hñ`XÀÐ
endstream
endobj
-4192 0 obj
+4215 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 1946 >>
stream
xÚ}V p×]Y–V!À‹h¢Å»‹C˜cËuBR
@@ -13951,10 +14017,10 @@ I`K\(·åÌ­-£U±Fmjã3gúP¤ðé-u ·Ù=ûöSEÎ
mE8Òʈ#&Þª|·‚Å}ü÷8yú¢ÛÓ#NVƒÏÞ= 9Ôé‹R§ÎýòôÌF/?pù]ÓÕdvÇU-;6âqŸ¢U±kÆ<T./ ØŠØÅáHr]Tˆô
endstream
endobj
-4190 0 obj
-<< /Type /FontDescriptor /FontName /APETMS+LMRomanCaps10-Regular /Flags 4 /FontBBox [ -496 -290 1501 1100 ] /Ascent 1100 /CapHeight 683 /Descent -290 /ItalicAngle 0 /StemV 106 /XHeight 514 /FontFile3 4192 0 R /CIDSet 4191 0 R >>
+4213 0 obj
+<< /Type /FontDescriptor /FontName /APETMS+LMRomanCaps10-Regular /Flags 4 /FontBBox [ -496 -290 1501 1100 ] /Ascent 1100 /CapHeight 683 /Descent -290 /ItalicAngle 0 /StemV 106 /XHeight 514 /FontFile3 4215 0 R /CIDSet 4214 0 R >>
endobj
-4193 0 obj
+4216 0 obj
<< /Filter /FlateDecode /Length 427 >>
stream
xÚ’]k£@†ïýg/é…uÔ4–„Ö$ lÚò·fæ$;gdÔ‹üû™£-”%¬ øxÞóõ:³û*|ú„aúÈà€ Ç°ØÕm0›­5Tý;¢@1E»ØÍ+ìa^”ëRÉþÁŠKůƒÀIõoÑ^¤ú’¸>0?âïðu¿9îªðçî ›ZuÛÅ,<àe¸Ö&d.õ(û«Mù5X Ü“€/ø M'µzø‘1f?l”(tãî‚h¢i³TÂŒ“ÃÉíÄ Éû‘ü“7Ö9—\ݺ›Ru°ZAd;Ë®77?ÿC}Fª Ìï j…ÕжWtC òžm}ëÛ{Ý DÎRبìowmùJ<ÞZ„ÄsL£s-°kkŽ¦V VÖ–Ãjk¯<@%¾Åe΄V0½Æéâjã
@@ -13962,21 +14028,21 @@ xÚ’]k£@†ïýg/é…uÔ4–„Ö$ lÚò·fæ$;gdÔ‹üû™£-”%¬ øxÞóõ:³û*|ú„aúÈà€ Ç°ØÕm0
endstream
endobj
403 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /APETMS+LMRomanCaps10-Regular /DescendantFonts [ 4194 0 R ] /ToUnicode 4193 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /APETMS+LMRomanCaps10-Regular /DescendantFonts [ 4217 0 R ] /ToUnicode 4216 0 R >>
endobj
-4194 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /APETMS+LMRomanCaps10-Regular /FontDescriptor 4190 0 R /W 4189 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4217 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /APETMS+LMRomanCaps10-Regular /FontDescriptor 4213 0 R /W 4212 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4195 0 obj
+4218 0 obj
[ 28 [ 500 ] 50 [ 444 ] 52 [ 778 ] 70 [ 528 ] 72 [ 278 ] 109 [ 556 ] 112 [ 528 ] 118 [ 528 ] ]
endobj
-4197 0 obj
+4220 0 obj
<< /Filter /FlateDecode /Length 23 >>
stream
xÚc``à``Ð``j````i
endstream
endobj
-4198 0 obj
+4221 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 1359 >>
stream
xÚ}”LgÇï
@@ -13987,10 +14053,10 @@ KR·mÍÎ),ÎÑÐÕ4Yf±’:ŠÖŒ6Í¿¿ôÙl¡ÅjÒßÔYQ[u”™6Ð5ˆ´ d’‹ä#&¤9%uSZ‹E‘¾F#gÑxÔ*{Q
ÄåôìøUŸÁ¨BuœxBSøú/sÇEB×Tó!¨…šÑØoçS_<ŸŠßï…¿ÆõrÕl=±ðX^_ÍV1 Š ±§ á‘ütˆíå@…¸û‰¢ŽXx$ÇûêžjZBl!<–wIP ý,/`<<Â/Ǥixa —ùy¬ÌÎÞ0ƒ50Ïím x8µïÁŽ`âWcÞ>ŸgL ¬…(/ôzêÓr®uKÕ±ãMb¦¨ŠÿF 1ü¼¸Úá4b_¶6ím™ =Ø“6Ÿp¡Œƒ(#Qòì• è™ûúæí•CÅLºš©i©Ž(P;Îí:TgùyôI…K¦ñaø¤¼§Æ9á ¿ûŸ”hS 7a?ÎÃ±È x¾0±ç4µ^k·!Äða1åo»YÌÅ6Ôåm!^ó]ý8pÅ$|ø—æ¾›‘þ‘U\ƒmj¨K‡k‰Ékç>uë0|³ÔËö£Bû½P¿P-ÔãEÂ=!9Nb¹h“›&29§qØÝJ3ÕjW#Óâtˆ«Ä`|ÄZ:Y»|À?ž!ü¼(c°JÇkøC 9Å5ƒ`F„X½Ïãì$:mí~
endstream
endobj
-4196 0 obj
-<< /Type /FontDescriptor /FontName /ZUCODC+LMRomanSlant10-Regular /Flags 4 /FontBBox [ -457 -290 1446 1127 ] /Ascent 1127 /CapHeight 683 /Descent -290 /ItalicAngle -10 /StemV 93 /XHeight 431 /FontFile3 4198 0 R /CIDSet 4197 0 R >>
+4219 0 obj
+<< /Type /FontDescriptor /FontName /ZUCODC+LMRomanSlant10-Regular /Flags 4 /FontBBox [ -457 -290 1446 1127 ] /Ascent 1127 /CapHeight 683 /Descent -290 /ItalicAngle -10 /StemV 93 /XHeight 431 /FontFile3 4221 0 R /CIDSet 4220 0 R >>
endobj
-4199 0 obj
+4222 0 obj
<< /Filter /FlateDecode /Length 406 >>
stream
xÚ’_KÃ0Åßó)®ƒùP›nº©Œ‚¶
@@ -14000,21 +14066,21 @@ n«ÂN'óãÜZ„‰ç$4ÏÇ®­êJî‘,l 4…Å£½R‚’ÿªÓàÚîZÁðz=TØg¥Ý:Ifסt–¤Ž¦“@W.=MsO—³P»t
endstream
endobj
367 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /ZUCODC+LMRomanSlant10-Regular /DescendantFonts [ 4200 0 R ] /ToUnicode 4199 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /ZUCODC+LMRomanSlant10-Regular /DescendantFonts [ 4223 0 R ] /ToUnicode 4222 0 R >>
endobj
-4200 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /ZUCODC+LMRomanSlant10-Regular /FontDescriptor 4196 0 R /W 4195 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4223 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /ZUCODC+LMRomanSlant10-Regular /FontDescriptor 4219 0 R /W 4218 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4201 0 obj
+4224 0 obj
[ 28 [ 511 ] 35 [ 460 ] 42 [ 716 460 ] 46 [ 755 511 ] 49 [ 678 460 ] 54 [ 653 307 ] 59 [ 460 ] 63 [ 511 358 ] 66 [ 307 ] 68 [ 307 ] 70 [ 460 627 256 ] 74 [ 897 818 ] 77 [ 562 ] 81 [ 511 ] 83 [ 678 511 ] 91 [ 460 ] 96 [ 422 562 409 ] 104 [ 716 332 ] 109 [ 537 ] 111 [ 743 460 ] 114 [ 664 743 464 ] 118 [ 486 ] 125 [ 562 ] 502 [ 307 ] ]
endobj
-4203 0 obj
+4226 0 obj
<< /Filter /FlateDecode /Length 28 >>
stream
xÚc``à0N\½%BàÁÑ], $&
endstream
endobj
-4204 0 obj
+4227 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 4953 >>
stream
xÚ­Y \w¾Ÿ'¢²´j³-3:m×£VÔêS[ë®·õDÅk‘+@8’ !!×$ÿ$ä á>"w@nQÐÖz»EÛ­îÖ­G·}Û½wÛmÿ“Þ¾7­¶ŸvŸ»ï%Ÿ\“Ìüç÷÷ýþÃA&ND8Î á{÷nÚ²oáŽ{$é±â¥KmÍŠMž §gÓs@0AÏDèYš˜@“\Z0‘xÐÀëþïà ÌÜ`noðÄÑh¦&šòw?: A8ÞgÏô4Ïaß…Þ ~)pà/Á?B‚& ädòd”ƒr¦ržýÞå_ [²dù‰4W&JJμºdɲWϯ Ö‡ ¶ÅƧJr2SE‚Xq‚`[˜`g˜`—$‡=*Ì—ˆqÂäØ´D$Q)< ÈÎÊ2I2I¶4sA˜ 2Y”)È‘ÈRì«L˜&ŒÍ&²Å B™ +Y(زoo¤`³Dœ%Ø!ŠŠ3…‚E‹‚L¡Pœ•%}}ñâ¬ì¤0‰,iq"û›ÌÅiã?Ê\8oÑæð]‘‹vlÝ°i×ÞMaYŠ,A¢D&HfÅŠÒ2þíãןwIdé±ië$q­ Bq–(+ao3‘‘—‘…H²YŠ¼Š¬@V"«‘Ÿ k‘õÈFd3²yÙ†lGv"È^$9ŒÄ ±H’ŒˆtD‚H’‰d!r¤€ó— ={›Ì$a"bçÌæTpþ>AÎ]0qÒDº}—3iÚ¤­“Þ:0ù•Éǧ̞òùÔO‚K‚?ýAvÈÂÏìzv泎i»§]™.þÅŒäçògò¯ÿPöüæçõ£¡!j/½ÈËùã—öÂùn-КÍÙzbob‡Ï
@@ -14044,31 +14110,31 @@ múŸÎfü^FñÿH¨ÅaýV·¢b]|øîÿ[ŸŸòÕ—•ÌkÂuG⇠ºíÀbuZHŸ½´©«Szr‰öÂýÞ¨>ÑÛ_üççj
o3ãOaæ¡:Õþ$d
endstream
endobj
-4202 0 obj
-<< /Type /FontDescriptor /FontName /OSSEGU+LMRoman10-Italic /Flags 4 /FontBBox [ -458 -290 1386 1125 ] /Ascent 1125 /CapHeight 683 /Descent -290 /ItalicAngle -15 /StemV 102 /XHeight 431 /FontFile3 4204 0 R /CIDSet 4203 0 R >>
+4225 0 obj
+<< /Type /FontDescriptor /FontName /OSSEGU+LMRoman10-Italic /Flags 4 /FontBBox [ -458 -290 1386 1125 ] /Ascent 1125 /CapHeight 683 /Descent -290 /ItalicAngle -15 /StemV 102 /XHeight 431 /FontFile3 4227 0 R /CIDSet 4226 0 R >>
endobj
-4205 0 obj
+4228 0 obj
<< /Filter /FlateDecode /Length 535 >>
stream
xÚ}”Koâ0…÷ùž]¤8Ä¥B‘xŽ"MKÕ0£Ù†Ø0‘ˆ%aÁ¿Û禕ªa‚ør®ïãèšÑ··Ì_Êú¨üé#g磌¯m¡üõKÞx£Ñ¦.®•Òý«RRÉAížÙ[[™êÙxnR]ö&8ÕÅå*Õõï •:—ú3ÄÖaãƒúíï³lûý§ÿãå½®rp?íóKYøÜž:”ýÅDÿ?•ÝQ™KóKµ]Yëg<rÎÍ‹­–뺲vÞ„ºd“¡ïS©eK­²£mÜ B&Ë¢'rßEe¬²‡³[׫*Õ§Ú[,Øä݈]ßÞ\×ÞdßJÕ–úÌÆwz41Ùµi.Êöø—$Lª“Im<zÍ+Å&vüTµìo÷|ø<s¸5Š…Ž4\ÔRuM^¨6×gå-Œ <a‹ù$žÒò‹Îqêxš€áçt>HÅŸ¼µ‰‚µIÄy$–Â)(-ͦ 4¢-´h 4  E Q - hDTA€(ç“£wn@”sš– TˆW T˜­AOЈh>ÊIÕ‰6 ­£Å;\Š8Õ²ø£k?cd‰à`Œ:‹à ÌiDèEÀÁ¾DðLP"Ê õ õI—4m<xì¬ò`ž`ܾØU³·æc³‹kÛšµvWËí®ÝÚR«Û×Ô=åwm‡¿Kû÷ë—Fa
endstream
endobj
-366 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /OSSEGU+LMRoman10-Italic /DescendantFonts [ 4206 0 R ] /ToUnicode 4205 0 R >>
+358 0 obj
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /OSSEGU+LMRoman10-Italic /DescendantFonts [ 4229 0 R ] /ToUnicode 4228 0 R >>
endobj
-4206 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /OSSEGU+LMRoman10-Italic /FontDescriptor 4202 0 R /W 4201 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4229 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /OSSEGU+LMRoman10-Italic /FontDescriptor 4225 0 R /W 4224 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4207 0 obj
+4230 0 obj
[ 27 [ 869 559 ] 34 [ 818 639 575 ] 38 [ 575 575 ] 42 [ 831 511 ] 46 [ 882 639 ] 49 [ 756 527 575 ] 54 [ 724 351 575 575 904 575 ] 62 [ 900 639 383 436 319 ] 70 [ 607 692 319 ] 74 [ 1092 958 900 639 575 ] 80 [ 864 575 575 786 639 ] 88 [ 319 ] 90 [ 864 607 ] 95 [ 863 474 639 454 ] 100 [ 575 575 ] 104 [ 800 447 575 575 885 639 869 ] 112 [ 607 1189 831 869 607 ] 118 [ 607 ] 120 [ 511 575 671 ] 125 [ 639 ] 284 [ 575 ] 499 [ 571 571 ] ]
endobj
-4209 0 obj
+4232 0 obj
<< /Filter /FlateDecode /Length 32 >>
stream
xÚc``°6.þüxßoþýz€ 8p
endstream
endobj
-4210 0 obj
+4233 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 6898 >>
stream
xÚ•zXWÛö¬°;¨ȸ–œYØPb‰ÑXE±£ˆ
@@ -14100,10 +14166,10 @@ N}®>¹Oü1·\—Õ¨“UUÊ°Ÿô;m]‰x),uÝã`7‚Ýãa)ãÜÛ9€BÔ^m$;͈BA—V¥VghÕüx\€epLúA¦–z{
߆pɆºöóž×ñ l…'úâÁÜßZ½Š&EÈãÛ?ƒ‰·Œ°@nè»@zæÇðÀ5Vr¿
endstream
endobj
-4208 0 obj
-<< /Type /FontDescriptor /FontName /JVOFPV+LMRoman10-Bold /Flags 4 /FontBBox [ -486 -295 1607 1133 ] /Ascent 1133 /CapHeight 686 /Descent -295 /ItalicAngle 0 /StemV 106 /XHeight 444 /FontFile3 4210 0 R /CIDSet 4209 0 R >>
+4231 0 obj
+<< /Type /FontDescriptor /FontName /JVOFPV+LMRoman10-Bold /Flags 4 /FontBBox [ -486 -295 1607 1133 ] /Ascent 1133 /CapHeight 686 /Descent -295 /ItalicAngle 0 /StemV 106 /XHeight 444 /FontFile3 4233 0 R /CIDSet 4232 0 R >>
endobj
-4211 0 obj
+4234 0 obj
<< /Filter /FlateDecode /Length 646 >>
stream
xÚ}”]‹â0†ïû+²‚sÑ1ýJfüÁegÙ[m¢[д´õ¿IÞS…EVP|zÎÉyû&9½«M8VåA‡É+gkÝ”×:×áôk_½Þ¬Ì¯mÚo­•V]´ù`«ºÌ7ºeýéb¶0Eûb“&?_•î²ž'Mô©0ׇõ·úwøs·œ¯vᯯuyÙ›ˆ‡“ò¬Bîj¶E{¶¹ÿKc6ƞƘ_b§ë¦(Í‹^9çöÁ§QÓòâÞ­ ¤ :ÅǨšD²ƒ“D1SEÞùßübMrÅ›[ÓêËÂË`8dƒµ 6m}óŠ_‚Á²Vº.̉õŸ*´›kUµSÃx01¥vaëÍ÷þ¢ÙÀ½øBÙhÑÞž;ð¨ØÞ*ÍbÏÄæ¥ÒMµÏu½7' ­|ĆsûÚ¨âU‡#Ð&t…ìBùŸ}íŠ&v!ÎÓhäiêI€â±” F”zʦ áIN@4±JB?Aô‰X
@@ -14114,21 +14180,21 @@ xÚ}”]‹â0†ïû+²‚sÑ1ýJfüÁegÙ[m¢[д´õ¿IÞS…EVP|zÎÉyû&9½«M8VåA‡É+gkÝ”×:×áôk_
endstream
endobj
357 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /JVOFPV+LMRoman10-Bold /DescendantFonts [ 4212 0 R ] /ToUnicode 4211 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /JVOFPV+LMRoman10-Bold /DescendantFonts [ 4235 0 R ] /ToUnicode 4234 0 R >>
endobj
-4212 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /JVOFPV+LMRoman10-Bold /FontDescriptor 4208 0 R /W 4207 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4235 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /JVOFPV+LMRoman10-Bold /FontDescriptor 4231 0 R /W 4230 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4213 0 obj
+4236 0 obj
[ 89 [ 1161 ] ]
endobj
-4215 0 obj
+4238 0 obj
<< /Filter /FlateDecode /Length 12 >>
stream
xÚc`€
endstream
endobj
-4216 0 obj
+4239 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 514 >>
stream
xÚmQÏkQ~/YlžõÝ€š&£¨(šÝPõ x1%- i”4J=%ÛîKvɺ/ìnŒõ–ƒ nl¢%(µ("^=&±‚GÁ‹Ðƒˆx7Ϧw‚s˜™o憙#A@cq1_¼9[8››/°ÛŠy1™f†ê72ø1—Äy ñIÌãžò !M‚}"ìŽ>ÅÂc‚»g!|¿ï»¿ã~ò•œðÃr…#AßÐô qäû¦¤TêÂ4«¯XzUs`*•:Î÷— -AVY®±¦]ÓA1UÈJ0/Až5½ª§™ KTSŒ
@@ -14136,31 +14202,31 @@ xÚmQÏkQ~/YlžõÝ€š&£¨(šÝPõ x1%- i”4J=%ÛîKvɺ/ìnŒõ–ƒ nl¢%(µ("^=&±‚GÁ‹Ðƒˆx7Ϧ
é"4ljÙPµX£nŸ‘ ¨é64™U/ZÔ ŠMUh˜*µÀÑ(ÌÞX( 3ÈéËÔ´)$“
endstream
endobj
-4214 0 obj
-<< /Type /FontDescriptor /FontName /XNTVGR+LMRoman5-Bold /Flags 4 /FontBBox [ -630 -325 2006 1163 ] /Ascent 1163 /CapHeight 686 /Descent -325 /ItalicAngle 0 /StemV 145 /XHeight 444 /FontFile3 4216 0 R /CIDSet 4215 0 R >>
+4237 0 obj
+<< /Type /FontDescriptor /FontName /XNTVGR+LMRoman5-Bold /Flags 4 /FontBBox [ -630 -325 2006 1163 ] /Ascent 1163 /CapHeight 686 /Descent -325 /ItalicAngle 0 /StemV 145 /XHeight 444 /FontFile3 4239 0 R /CIDSet 4238 0 R >>
endobj
-4217 0 obj
+4240 0 obj
<< /Filter /FlateDecode /Length 358 >>
stream
xÚ}’Qkƒ0Çßó)n…öÁ;ú°"ÂÚ®CXÛa¥ôÕ&gÐD¢>øí—ÄÚ /ÿÿ¿»dòò}òÞ¹º¢÷:§`­ZÍÐÛ쳊L&[ÅÚes@äȵ^Á·Vì„ L7ñ6–¢™s,YÑr\ã¦5Þ„|Zì`šâÅ»Òógâ}íUfré­UÁ=jSRÑÆú Œc¸gÔµPrÁœRj6>$ߨÒ6Vÿþ€› Éõ®–— à‚5÷ȽYi&d“O]Ý`Ë\‘0?1bÝèÎñΈÔµ7˜Žé­ª- PEÀ17uÍ\Y‰àÛ®cnTÑt£í?Ò®BX¸8èQ™âXWCÉ’дO#wæ‰JþG§}Ö5ïCc>ƒAa?™¶u–o¦¥‹uÔÛܾ­hÇò g­ÖÝÍÎ!Z8!ñ1ÞJU6Ë-w.ÃÕ°ÑqG~:TÙ
endstream
endobj
356 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /XNTVGR+LMRoman5-Bold /DescendantFonts [ 4218 0 R ] /ToUnicode 4217 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /XNTVGR+LMRoman5-Bold /DescendantFonts [ 4241 0 R ] /ToUnicode 4240 0 R >>
endobj
-4218 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /XNTVGR+LMRoman5-Bold /FontDescriptor 4214 0 R /W 4213 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4241 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /XNTVGR+LMRoman5-Bold /FontDescriptor 4237 0 R /W 4236 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4219 0 obj
+4242 0 obj
[ 27 [ 531 531 ] 31 [ 531 ] 33 [ 531 ] 35 [ 531 531 ] 38 [ 531 531 531 531 531 531 531 ] 47 [ 531 ] 50 [ 531 531 531 ] 54 [ 531 531 531 531 ] 59 [ 531 ] 61 [ 531 531 531 531 531 531 ] 68 [ 531 ] 70 [ 531 531 531 ] 74 [ 531 531 ] 77 [ 531 531 531 531 531 531 531 531 531 531 ] 88 [ 531 ] 93 [ 531 531 ] 96 [ 531 531 531 ] 100 [ 531 531 531 531 531 531 531 531 ] 109 [ 531 531 ] 112 [ 531 ] 114 [ 531 ] 116 [ 531 ] 118 [ 531 ] 121 [ 531 ] ]
endobj
-4221 0 obj
+4244 0 obj
<< /Filter /FlateDecode /Length 25 >>
stream
xÚc``Œþi}ýõömï¿­r
endstream
endobj
-4222 0 obj
+4245 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 5721 >>
stream
xÚY \×ÖŸ2¡J]ã’©wRµ¶êVÛº Ô¥*¸Tqi]XÂNIH ì ë Ȳ "ˆ‚à†µ­­Ö´Ö¢ÑÚÚV­mŸ¾j_ß{gìµß÷Mújßïø%Ü™¹çœ{Ï9ÿsþåà@‰D¢Ñž«6z­^ç²ÒÓS­RϺV棱>ZÆ?ÏÇNˆŽâljx4ˆçļÂÁä$"cÄ;9<z—ô>Œý-[2Ž¢DÅÄÏAŠ0Ôi¼ð׸—&ZoŒqzrD‰¨ÑÔsÔ]ê7A®Tä$ùtµ3¦¹ºÎòPGÄh‚ƒtŠ®®3§X?_S¸OS,÷ñ U´¡Á
@@ -14193,10 +14259,10 @@ dºW÷·ŽÛg`èµ+­­ŽE…¹ù¥r›K¬Âù¤µ6(¿ÛaeZZX/ñŒï =ËûÝ´^¬þû§WÙšªô”.=-=1QÎtjªtÍÍÕµ{
¸³ð¤n`ï*â3ú%M†ƒ+ˆa‚ä ýLçñJq ·ì•¥ßK*Ÿ˜àh/íB«C&ý¦«$`
endstream
endobj
-4220 0 obj
-<< /Type /FontDescriptor /FontName /MOXNPT+LMMono8-Regular /Flags 4 /FontBBox [ -456 -320 743 1014 ] /Ascent 1014 /CapHeight 611 /Descent -320 /ItalicAngle 0 /StemV 177 /XHeight 431 /FontFile3 4222 0 R /CIDSet 4221 0 R >>
+4243 0 obj
+<< /Type /FontDescriptor /FontName /MOXNPT+LMMono8-Regular /Flags 4 /FontBBox [ -456 -320 743 1014 ] /Ascent 1014 /CapHeight 611 /Descent -320 /ItalicAngle 0 /StemV 177 /XHeight 431 /FontFile3 4245 0 R /CIDSet 4244 0 R >>
endobj
-4223 0 obj
+4246 0 obj
<< /Filter /FlateDecode /Length 645 >>
stream
xÚ}”Moâ0†ïùÞ=¤˜8¶i…øh%¤åC­z…Ä°‘À‰’pà߯íwÒJ+v+µôaÆžÇgz?¶»xš—G‹gÎ>LSÞêÌÄóÕ¡Šz½E™Ý®Æ¶kcr“wÑæ•më2Û™–õçËÅÒí“K^ÚìrËM—õ8ifÎ…ýNñuXo>ãÕæs½ÝÇ?W«Ò–£øÃœo—Cs¿h_´—üß<æ‚ìq…M~™º)JûʆϜs÷Å›ÍçåÕ¯‰¤Èô©°yMžìè­£aÂò"k‰ÂßìêúäïîMk®K{*£ñ˜ \å¢ië{p~Š›:7uaϬÿXÑ¥ìnUu1^‡ñh2a¹9¹]Ö‡«aöeî¢E{ÿG¾—ìï•aIà!t³27MuÈL}°g] ø„ßÝÏ$26ÿ+αêxº„î_%»PöûPû†3·çéphH½Òo’!29H 3¥ä¤°nÒ h„LŠ½€(6E‚™"‚™˜‚`¦Ò@"IÌÄ3
@@ -14208,21 +14274,21 @@ rµÆ Q°–¨ ÉÕ5yÂLS—ÐMoú¢éžñ ÞÓð^úWÚϦ¯’ÝêÚM0ÀÂŒðÓ¡°ækÆUeåW…ß0»)íióý)Œv
endstream
endobj
342 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /MOXNPT+LMMono8-Regular /DescendantFonts [ 4224 0 R ] /ToUnicode 4223 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /MOXNPT+LMMono8-Regular /DescendantFonts [ 4247 0 R ] /ToUnicode 4246 0 R >>
endobj
-4224 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /MOXNPT+LMMono8-Regular /FontDescriptor 4220 0 R /W 4219 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4247 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /MOXNPT+LMMono8-Regular /FontDescriptor 4243 0 R /W 4242 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4225 0 obj
+4248 0 obj
[ 28 [ 549 ] 47 [ 549 ] 50 [ 494 ] 59 [ 494 ] 66 [ 329 ] 75 [ 878 ] 77 [ 603 ] 81 [ 549 ] 84 [ 549 ] 91 [ 494 ] 96 [ 453 ] 98 [ 439 ] 105 [ 357 ] 109 [ 576 ] 116 [ 495 ] ]
endobj
-4227 0 obj
+4250 0 obj
<< /Filter /FlateDecode /Length 23 >>
stream
xÚc``à``TPñXàÂ
endstream
endobj
-4228 0 obj
+4251 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 2201 >>
stream
xÚ­V PéÞQ#EœÜ YÜ]ï§ÈÚS[[½ÃC
@@ -14235,10 +14301,10 @@ bEìe¬li“2vñ¿è½RÓ£÷%íIH=œ£Òªp©Àó •P"SÆ|…â³×TRQ$”½•OæIù„\%Qé öŠ€b¡-ÐN(JöC¡
«Å`F7fgidˆ¢Îë]ê{¿7á?uµ±ê¨¤Ê±íA# vvPv— Wã2I«‹Lõh> oÒ±1Ñ·S؇A Œ6k¨Z£ m¢ðÒßn
endstream
endobj
-4226 0 obj
-<< /Type /FontDescriptor /FontName /GAKDMK+LMRoman8-Italic /Flags 4 /FontBBox [ -489 -292 1472 1124 ] /Ascent 1124 /CapHeight 683 /Descent -292 /ItalicAngle -15 /StemV 110 /XHeight 431 /FontFile3 4228 0 R /CIDSet 4227 0 R >>
+4249 0 obj
+<< /Type /FontDescriptor /FontName /GAKDMK+LMRoman8-Italic /Flags 4 /FontBBox [ -489 -292 1472 1124 ] /Ascent 1124 /CapHeight 683 /Descent -292 /ItalicAngle -15 /StemV 110 /XHeight 431 /FontFile3 4251 0 R /CIDSet 4250 0 R >>
endobj
-4229 0 obj
+4252 0 obj
<< /Filter /FlateDecode /Length 432 >>
stream
xÚ}’Ëjë0†÷z
@@ -14247,22 +14313,22 @@ uH®eçâ¶C7Ó¦-I(Ý:Ò$GKF–yûJ»…’sþüÏå×hFWïÛèAè=D“F7ÐêÎpˆ–ëª!£Q¡yWƒ²¯
endstream
endobj
341 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /GAKDMK+LMRoman8-Italic /DescendantFonts [ 4230 0 R ] /ToUnicode 4229 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /GAKDMK+LMRoman8-Italic /DescendantFonts [ 4253 0 R ] /ToUnicode 4252 0 R >>
endobj
-4230 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /GAKDMK+LMRoman8-Italic /FontDescriptor 4226 0 R /W 4225 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4253 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /GAKDMK+LMRoman8-Italic /FontDescriptor 4249 0 R /W 4248 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4231 0 obj
+4254 0 obj
[ 51 [ 611 ] 56 [ 611 611 ] 78 [ 611 ] 82 [ 611 ] 100 [ 611 611 ] 106 [ 611 611 ] 121 [ 611 ] ]
endobj
-4233 0 obj
+4256 0 obj
<< /Filter /FlateDecode /Length 21 >>
stream
xÚc`
< 
endstream
endobj
-4234 0 obj
+4257 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 1695 >>
stream
xÚuU}PSWù%+…4-}Oß{¥ ¶…ÄBkQ·ŠP`@E ØÁ²Z‚y„„‡I
@@ -14277,10 +14343,10 @@ E±0Ò÷‡ý—§HÇwâ/ø²Ól:ÝNÒhÖWçòä$ô
±{>Þ4Ä`ûß·YQ$¶Õ4dì­—6}¼Ôh³¾ðóб{þÁ—FÏ}ƒÃp$ºŽp¤xse\ÞɦŽ£¿ëé«õ|Dž;2uükâ—ñwW¿÷›äÔ j@FQCCs³çÒÅA*<OøÞä¼0'àNÃiÅu
endstream
endobj
-4232 0 obj
-<< /Type /FontDescriptor /FontName /XENFPT+LMRoman6-Regular /Flags 4 /FontBBox [ -515 -298 1647 1125 ] /Ascent 1125 /CapHeight 683 /Descent -298 /ItalicAngle 0 /StemV 117 /XHeight 431 /FontFile3 4234 0 R /CIDSet 4233 0 R >>
+4255 0 obj
+<< /Type /FontDescriptor /FontName /XENFPT+LMRoman6-Regular /Flags 4 /FontBBox [ -515 -298 1647 1125 ] /Ascent 1125 /CapHeight 683 /Descent -298 /ItalicAngle 0 /StemV 117 /XHeight 431 /FontFile3 4257 0 R /CIDSet 4256 0 R >>
endobj
-4235 0 obj
+4258 0 obj
<< /Filter /FlateDecode /Length 404 >>
stream
xÚ}’K‹Â0…÷ùw‚.jSŸ£HÁ'fTT·5¹:›”´]øï'«0ŒSèãë=799Iãm»¦\0è¶)ì°P•fÌ?Óœ4 Ū e¹FäÈëj1†­Vl%4çÉ"‘¢lq"ÙµâX«þÍð"äSbçæÁq¹^mÁÇçNe©;¼T×TÔvDy5êÿ…`ªð¢
@@ -14288,22 +14354,22 @@ n˜/Ô…Pr Q›Rj~,%Ÿ«Ì®° áÝ%„µï³\ß­ÂÉ'Q¸`åÜ“e&*Û¼¿%f‰<+2™@hfE©oÎu‹„ÍQ yæ F³
endstream
endobj
339 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /XENFPT+LMRoman6-Regular /DescendantFonts [ 4236 0 R ] /ToUnicode 4235 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /XENFPT+LMRoman6-Regular /DescendantFonts [ 4259 0 R ] /ToUnicode 4258 0 R >>
endobj
-4236 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /XENFPT+LMRoman6-Regular /FontDescriptor 4232 0 R /W 4231 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4259 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /XENFPT+LMRoman6-Regular /FontDescriptor 4255 0 R /W 4254 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4237 0 obj
+4260 0 obj
[ 28 [ 510 ] 35 [ 549 ] 43 [ 472 ] 50 [ 472 531 ] 55 [ 325 531 531 ] 63 [ 549 ] 66 [ 253 ] 70 [ 519 ] 72 [ 253 ] 75 [ 844 ] 77 [ 549 531 ] 81 [ 531 531 ] 84 [ 549 ] 96 [ 363 ] 98 [ 407 ] 100 [ 531 531 ] 105 [ 384 531 531 ] 112 [ 490 ] 114 [ 726 ] 116 [ 490 ] 121 [ 531 ] ]
endobj
-4239 0 obj
+4262 0 obj
<< /Filter /FlateDecode /Length 24 >>
stream
xÚc``à0<¨4-ƒaMÁ

endstream
endobj
-4240 0 obj
+4263 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 2548 >>
stream
xÚmV TWž!L&jL+1€œŒZ-*¸`Šh "¢€¢Q0$PÑ¢‹
@@ -14324,10 +14390,10 @@ b£`÷ÅÅðóÉæBŸ“½SK)ßiº$ƒíàmEÞ CbÅcTEŠßYz,ª»ûóÚ¿×Ñ¿+«8+æÔrÛÂZúncãí[ÒGL@ä
„+¤ïú_\D¿eéÕ·S?|Þf­“5tíº) ¬–ÈMáúXúmíê-9”2íT·Nfü¢ÒÚ#2¼ÀË„ä~´È¹S}•¥„³¸í&6ß¹õ|àVTÃ&”šc5|:&)ÏO8Î$œ`?0¡Ý¼—ór×öW …wÍûÞÝkÞ7Ö 'þ³&c
endstream
endobj
-4238 0 obj
-<< /Type /FontDescriptor /FontName /PTIWQK+LMSans8-Regular /Flags 4 /FontBBox [ -446 -314 1510 1154 ] /Ascent 1154 /CapHeight 694 /Descent -314 /ItalicAngle 0 /StemV 98 /XHeight 444 /FontFile3 4240 0 R /CIDSet 4239 0 R >>
+4261 0 obj
+<< /Type /FontDescriptor /FontName /PTIWQK+LMSans8-Regular /Flags 4 /FontBBox [ -446 -314 1510 1154 ] /Ascent 1154 /CapHeight 694 /Descent -314 /ItalicAngle 0 /StemV 98 /XHeight 444 /FontFile3 4263 0 R /CIDSet 4262 0 R >>
endobj
-4241 0 obj
+4264 0 obj
<< /Filter /FlateDecode /Length 496 >>
stream
xÚ}“OÚ0Åïùî‰=dqH`…"-ÿ¤¨Ý]ºAm¯!h$p"'9ðíkû9»RE‹Êy3óÆžŒ¾ìsÿYÔGò£GÎÞ©­{U’¿~)o4ÚÔe%Ù½ C´}b{U—9ul¼Î6™¬º-Îdyé ªû¢+ù)1}Øø@¿üý!ûùý«ÿí%/d;÷ßéÜ_
@@ -14338,99 +14404,90 @@ A3”Ñ” ƒæˆ9å4í DÞÔÕ\€bÐ
endstream
endobj
338 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /PTIWQK+LMSans8-Regular /DescendantFonts [ 4242 0 R ] /ToUnicode 4241 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /PTIWQK+LMSans8-Regular /DescendantFonts [ 4265 0 R ] /ToUnicode 4264 0 R >>
endobj
-4242 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /PTIWQK+LMSans8-Regular /FontDescriptor 4238 0 R /W 4237 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4265 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /PTIWQK+LMSans8-Regular /FontDescriptor 4261 0 R /W 4260 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4243 0 obj
-[ 27 [ 796 531 ] 34 [ 752 590 ] 42 [ 767 472 295 295 ] 47 [ 590 ] 49 [ 723 472 531 ] 54 [ 693 325 531 531 834 531 ] 62 [ 796 590 354 383 295 ] 70 [ 561 664 295 ] 74 [ 973 885 ] 77 [ 590 531 ] 80 [ 826 531 531 723 590 413 413 ] 88 [ 295 826 ] 91 [ 561 ] 95 [ 782 414 590 419 ] 100 [ 531 531 531 ] 104 [ 767 413 531 531 ] 109 [ 590 ] 112 [ 561 1091 767 796 561 ] 118 [ 561 ] 121 [ 531 ] 123 [ 885 ] 125 [ 590 ] 284 [ 531 ] 499 [ 502 502 ] 502 [ 295 ] ]
+4266 0 obj
+[ 27 [ 796 531 ] 34 [ 752 590 ] 42 [ 767 472 295 295 ] 47 [ 590 ] 49 [ 723 472 531 ] 54 [ 693 325 531 531 834 531 ] 62 [ 796 590 354 383 295 ] 70 [ 561 664 295 ] 74 [ 973 885 ] 77 [ 590 531 ] 80 [ 826 531 531 723 590 413 413 ] 88 [ 295 826 ] 91 [ 561 ] 95 [ 782 414 590 419 ] 101 [ 531 531 ] 104 [ 767 413 531 531 ] 109 [ 590 ] 112 [ 561 1091 767 796 561 ] 118 [ 561 ] 121 [ 531 ] 123 [ 885 ] 125 [ 590 ] 284 [ 531 ] 499 [ 502 502 ] 502 [ 295 ] ]
endobj
-4245 0 obj
+4268 0 obj
<< /Filter /FlateDecode /Length 32 >>
stream
-xÚc``0°-þüxÛ¿‹ï¾ü
-aÀ 8
+xÚc``0°-þüxÛ¿‹Ï¾ü
+aÀ 8
endstream
endobj
-4246 0 obj
-<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 6877 >>
+4269 0 obj
+<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 6782 >>
stream
-xÚZ \׺Ÿ“¡JQ™ÆÖ=÷¥‚KkëBÕZëŠV«âÆ"KXa û–pBȾïATܪÖ[½ëÒj«WëµU»h=ƒ‡·œ€µ½¯½÷¾÷¿L¾™ùöïÿ?'"jÐ J$½á¼d½ó2ç7V¬
-òžcÿ±Â7Béfùl©0F m€0ŠF‹`%ðbA>¿b#Þc3¨Ï·’\Þ+MQ¢Â¡äh5v¸
-TE…úË=‚½å+ä«äkTQ䬿|²*Xî©ðóPúÈU>ò ŠÍòˆpEX¸Ü7L>ÅA¾ÁÏ?\¥
- ”“¿a
-¥Â#\á-öV„ÉÕ~
-ù²ë7È—ª‚Õr'/Ep¸Bno/—‡+r?µ:dÞôéê_U˜ït">]9 >ÝrýÒÖl°wZñÁ‡kÖè Þ¡–û¨ÂäÞ
-µ‡¿2ÜáÚøëû5ª° åûÞ*OÅ
-oE°Ú_M‘G¢ÆR㨩ԛÔ4ÊžšNͤfQoQïPïRs¨¹Ô<j>µ€ZH-¢Þ§SK©eÔrj%µŠZM­¡ÖR먩õÔj#åLm¦¶PÛ(wj;åAyRÞ”‚ò¡ü(*€
-¤‚¨*”
-£Â)5IES±Tœh”è‰è©è™˜D‹¼S‹-qD¥ˆ^•YÉ­ò¬ž‰§‹•âǃ|}&ñ•ôH—HŸÓNôOÖ×^ÙöÊ­Wž ~{pÁ…CtC.ظ¼j÷ªÁ–· ³íÊ -6f˜zØ…a‡Ï¾ÏÎßî &éµ)¯åËd²¯GÌqñõկ׽ñÚ§G³ãØËœ'wcÔ'£½Fïý-Ø
-$ÝGb1r†ÈšCªUþ!*ÿ†csuƒàžA8G.ÄïG"gr!bÜo£ÀlÙ‰¨cÛ"BƒƒªB[ª‹ õzç.\46MÎK3ݺŽl@<£ÍÂ0MsÀ!‹q=úf…pt„™^–’{„~¢™C¿‹%ö¥÷ú¹Tnâðp,žŠexèÝ™#Æ3ïD3‹;(fìŒLƒ—Ê5Ü…sõªm çCö¥é`Oç¨i­µíÆ£\ggø¦&޶ח$ø)3j2Û¡ ÷‘ 9˜´&æ9Ið"™RŠ§†F.ÀË9<åE6–>¤½Í›P¥Rúv\Ðd0%¾Hâ±Ræ
-‰mï‘fkx³i—[î=a–ôÖ  ™™ÖlVÁ¹íó Þ›h¡™öïô >ü*:
-z:Õ–õ0›€—ŸCU¨­:}ÿ4h1ž[Ç'étiÿØEIkëo¤<i¤‡·¯h›Éaü^#݆æà9ÈûÚíš3ûyUys@>ÇX‚-¢™%û³ µ {4¢åÚ.7"×ÆœF»¦3agÖÞ¸}£òFóÆž
-… ²²øf÷˜m® <̻̅›¼xé{.õ~UQ|DXJ`8ëY©¬ŽÌç!›â<½]Ù~^Þ@ÑÕÑÝmeÀ´v+œÂ­—*õa {ØÚœ¼Ü<Ö¶/½–{ÜséúÞ˜Ýáõ|q¡¹êˆÎ:C“žËFÅ——åÕ
-‹Ù
-M’#'†‘Ó–éi&¸¤‡õ Ûµ÷„!«wz˜u¨ˆXµ2ð(šñÆ-v|š—FæXÙ€zL¢¥Õœ„%\Ñ'PÓÂ3ƒ?ËÌ¡5ÁÁ¡ê€àšÐݦÚúF’¤§‰ëºUš‘ªßsù”ô0…}äÑÙ¾<ž€Ö~sñ/ÇÚ uº‘¤¾Âã '·5N—åÎЙÙñildTLJÀã±µD¡™¼?÷ë¾nXÆUƒš}¿úõ!}±[¢¯÷ÛQÊ—D–F•FYGU…îdcvhúÜN®Ø[iÑ߶wÚo¾þ«ˆŽK؉‡âUœÃÀ jéXü
-‹¦»:Ç‚ËÑW®ä¦º. ‰ç3¿—2_á ¿¡Ò]Ì‘§7Žœ¿P°yÃ?)…ßÕÌ¿ì/ÛZ¿(X¢ó
-v²Ûá àÿ¡æ¿©XË,5=¼iFó`ùñ½ýæ0Á07e¨ÓWÇãÁc¦ã×±ì¡=’|~°ýh-ˆ¢±[{¬‹Ü¤7…
-
-I£´ºàåé>p؆nØpšïË'ã=að ê܆í\û¨90
-MÌÏè4\vR¹‘^ªôQ,‡·K2¢)fÒzœhÆO)Íœá9ÍAc­¢™ž{¸^Š_¹}0VŸíÿä‹„B
-íýÙ‰a½Ý•Ÿ<ÙúD÷SÕf˜%> e·V\P nÏ\ü’e¦%~9óÔ8ù¼u }êbëM•Õ­Å:p¢íš¾œcìŽ×_Mÿa°G\,¤Tk×dXïÈLÉŒgãò`è’ÞèZ7–gº ,Xâã¼aQåq?SjÌ<sbÑnuM`ˆ*ÆkÚO«‘üûý,àÞD?<}d¶;þtõwîOшï˜!-#À\•²%a‡uJÚBËá¥RÄ!ÛÒ’6siñÈs§Îœø–EC&]ÃóÛ8Θµu_jq•©d/ÏÛ@OãguG¸¿w:¾;nñB<¿Êc;<BÂä&$Bm+ðRËßÁë‡Pú!ÑKèØû×öÐSOû­·-¦gorZ4;ã`@·^|rjfñx*ýt@o?Øs9Ï
-ÓÌ"¡EkYKðÓ®“ìõJÂuZ´y1l’6=#ôdÀƒQ­$­î‚lÝâB"¿Ýîà"·A} ‘?kHó/áÑTüX²37'µ˜+ÎÝeð£Ñçµ'›‹Zu#mŸ_…‘½o™EÏOôËóý¡’S*¡~#¹¾»14$jÓãyüVŸ'vb$éE0KÏšŽÁFò4 4…Ô»Ùã¥ÚØ>/¾ü#Èf$à)}Kˆ|¬E>²¦ãòüoò§+ ¢ˆG>}Ï$q†ìäR®8'¯(›GK„]hI_®$1;;¡”+ÍÎ+&
-»׊ÛêÎ…{w 8¨7nÀAZ¸ 0ø¶ 4šMФiSÁ4œ5Õ[Ðg³õ»uµ÷x;Ã$.Âêƒ,îÉJw®à§c8J2³3
-²Ù†½°¼ßnÄÑ›¡>˜Èuåg¨
-xÄ⧒9z¢jY6é™ü/¨ùÜ,‰7d'–Eó ˆö¯¢Ëy5e‡úm`h½»,Û,kâò¢x¼]D“‘«äÓŽkºÎßPÍmL†ú5ê‡Ä±Iš”TßaØA%šìŒ[XQ¾ßâÁqÉšx¨_ǔџ”$‡’æ‚xάrq„‘–Ýš–S°Šë*‚š³nËJ1å³z˜_H*ßy!G'É#i¬aãwÄzeZ6kÆé%]F¨éæûɸ "éw€¤òê$ƒ)”Ç
-®ü(Ô4õ³íFAoÜoUÝF·Å¿«.Ãy €ÚâX5›–™šž
-YcdID”:^é~Чûnç³ül€œ„Ùu§ZóÍ$æ¤_{Eî¢ÂwâÐeÙ³Ä Ÿ‚¿¹Ï«&¸ÂÎÕ^Çû.ÖNÞÄ®ÐOìœÞ?|eÇq®óvÉã.¾õ²þîvV¡l-œ™°Œ\Àù/-}É'ž‚Ž±—à_ N€Ÿª®ç×qÍ—bfTò…à¢eì
-Hã@"úñ·­ç›šR¢kÁ
-#ÉuŽ]34"Š,ûPkeM‘õ~!ɉiiàўÇÚƒÈæ%ç¤Ç½ãˆ¯­ÝÚa®®kÈK'«nTüYSmô?­Mضzù¸`á–ìLø—€ˆ° ËæUC^AN˜âëêîÒÓa:ìß¼*þæafÈkÄÿV”ð0Ááå&ÙÿõA¶–ïF 8›‰£)Ššmù¶ÃZ»È*ფÊßU%+7(§Û¼m†˜_bÔY^ƒ.k×)£¾¤AŸ“«Ï2rl^ýo!‹üh
+xÚz \×Úþ„˜ UŠÊ4¶Î虸/\Z[·ºÕº¢Õª¸±ÈvK
+÷p…—<"ØK&Wù*䫶nÞ"_© VÉý<Áá
+¹½½\®PÈ}Uª3gª"|”a>3½‰MøÌÀA£ð™–óìW¾¿a‹½ãšwßÛ°ù=Õ•Ü[&÷R¨ÜýÃþçý{ƒ2,È=p™—ÒC±ÆK¬òSESäÅQc¨ñÔj:õ:5ƒ²§fR³©9ÔÔ[ÔÛÔ<j>µ€ZH-¦–PK©eÔrj%µŠZM­¥ÖQë© ÔFjõµ™ÚBm¥œ¨íÔjåFí¦Ü)JAyS¾”åOPATJ…QᔊŠ¤¢©X*N4FôXôDôTLrE^˨e–¬ ¡’E/‹J­äV¹VOÅ3ÅâGC¼‡|*ñ‘ôJWHŸÑŽôOÖW^ÚõÒ—}shþ°%ÃtÃ.Ø8¿l÷²Á–· ³íÎ Ï1n„jÄ…F.yÈÎÏîK&ñ•i¯œ~å²pYÏ(ÏQ·^÷jÃk;F[nc}ا\ð˜]cÐX›±1c¿“‘Ù¶¯šÑv³°=JÔG™chÇÄÜýjÇ ÿ-)LÓäÆpÑšä¸4‡÷ß’„$FîžÏùÓúý§`·¿jŽófÚMZÑÀæÀLCè@#%¨VzO•Ô0²AÛ øÓh¼^r¦ j>äq%*–a(E#ÐW[Á˜hTDžõæ{uF»¦ë(ør¯‰qòïÊNn¡=öÆFzÃcù
+¾4¤Èw9kÛ·/ÒÜ7Å,êy,ä4‰û¶¡xYÌMФ%f
+$ÝCb1r†ÉšBª”~!J¿úcSU½àÞ!xœˆ—E"'r"f<l£€,Ù験»ü#Bƒƒ*C›«Š
+ôzç/Y46•MÊM5Þ¸ŠlÀ@>£ÍÂ’M³›eqî½ú^fpb”™^•œsœ~¢™¶ßåûÐ}+¶qx$OÇ2<ü‡IȮ縱ÙÌ;ÒÌRĉ†é{£
+ü¬5šíФ{ÈÛ„LZóŒx¡,PŠ§‡F.Æ«9<íy5–< ½É›PE ô͸ ©`:Jx^Äã¥Ì´ ò}Ì–ñ&i0Š’ôß~Ñ Å/záG)c5˜QÏ:4Ï(j¼ƒr.Šò™¥É‹OЦ¤jÁtŸ¹šhÎÕ¥òXt ~ÒÈ¢iU6¬¾³ó<˜>À2DM!)dºžVó«+ÃÙR$ϽYÓ¡—²ð8•ŽTŽ1²±oh]ÛÙ.ÔÜrvGc%Ä E²ó~­±¥ ¦$C7·ÛšÙ~¦þb×Uö»éÝãæ.·÷.ô« ¥‘YÚs^ÖL-±%dùf[!±#¡ánü¢e›\wn xä—æJpixC3{þ³ÃŸ_ýÄé=PÝo'[¼`×|ÀLœ³äãë_žéùl?¸y’’¤“ï“6ZCßfFGÍ"KàÝLh²IÜ7FØ!Ü œ9è%½PÓΛh{XÔÌ£´oé‡sÓñ–:`p@™ÏÓ1ZŠÞ.wį–’ê¾
+Í‚ÈŒRÌJ£Ú ïfße®/÷ÙÈŽº78-³Uðùþ×q/íª†ë6ë†5\O&Ô\àÍQôrmþ}ŽlÌx8’ÐÌ+···f|InzF”φ–ï©«/+¯QòhÚM$iì4"ÙÍýQvOÍ÷ï•ßcNÞB‘³ Y¿ý3ºÃ9ÖOÐV:½ðpb+‡F^þ{q~Š>‡é0) ìõrQoå6î,.ä Ùx˜Íãct4T—ìÓgí3€â‚ƒ'nrgê]öäò¥>™.^¬wÆV¥ÚãèÄ­]wä‚ŠgN%è3rÈéƪ2SKpaTt@âîÙWg!šgär4ò—h„¥VHJ^5 aQ"ôÅ—bAƒæÉÌã'ºî‹ŒÏȈKø‹~O‰?jžG{kHRT$)õh¢FbVÑ‹5ù-ü z©Y†s¤(GHlû¾Œ4£X³À›í\î¸ô˜YÑWÒefZ³] ?àv/€z/Þ¿™fÚ¿Ó«½ùutôp
+Ê›¡š›„WŸC•¨­ûðÞhÈr<¿–OÔéRÿE ´
+„I²Òø&·˜]éî. ,Ì«Ô™›º|å;Îu¾•Q|DXr@8ëQX˜ÏC¶Åyx¹°ïþ¼½†F"«׺ZýKiãN8Û, Ô‡Õ`k²ssrAXë¡´îQïgWÆì¯ã‹
+Ì•ÇuÖéš´´X6º0¾¬¨4·à÷å2ï´P‚iʈ€”hŽÑU:Àï«Z uÅ|u©± žû¾Á#I¿T¶u±ËTÀ,1eɱîÊ’žëü÷Òzô*\Èrš32 6Ü¥{â¾äQæz±–¤M(£[2ó¯€*³OÑà)z‰=Ð8_B1ÿêÓßF¼MÑ£)¤ž_å£K8ÿ÷Ÿ^s›¸Ù†¬žã=º}’¯Wh桇 þ:5lçQý7E÷ø7\6Dƒ t_Ê ßÏò z´ Ös ­Ps”ÿõÔ5ô“¯ŽüqñnG€£ÿÌÐ=Eë.ˆ
+P³u
+s7¯¥m†Àà ÄEŒ¾e§iòZ‚rPŸw ÔeÏÐàdÙ5ô5}¢Â²l…&q' #o[¦§™ð’^²¨_Ø®½7 Y½ÕËlB…dUkÓ ‡x¢/<Ù²ŽOrSÉ+tI°@ÍXÌ~5Í<3ôá‘ÌZªò®Ýoª©k Eú! ]w[…)"G˜Oq/óH8DnàÕáÃãIhãÍ‹9Ùj¨Õ&ý=¸qºL7ÞŸ.ÏÈŠOe#£b’Sžˆ­%BÍäþy\uÃR®â$Ôú5®è‹Ý}ïž¾8²$ª$ʺ(ª2t/³G£p;9ã`…ÅÛ¾¿ÅRøÇÀ Þ‹‡ãuœÃà jèfXtì7K5®Ë¡3‡þ¬ „£Ò¸’‹Y<´—iA¿‰ÐO3Ÿý ÷ÏXÜﶸoûÌý¹3Ó›„S×ÅÏfþIÁãw¤!ZMt
+÷ö‚÷
+ç$Éz%‡½AÉt(Ü5ÙrñöXÇÕu Ì z2ì¬ã#­Ó!C?–Ägg%q…†‚öõ‰u’þs¿5
+šëZ‰Ó'†ùVóõžìÀdö›?!ƒ]}M,leö¥gh
+Hœ¤ëµºàéá>ƒhØúnXÿ!ߟGÆ»zðõ—êÜ‚í\ûm¨92H–ƒÑþFô1¡ËSîÀÇ›£%™í}¯ )²‡ãîà‰ _üù'µ€¡æd0uÿ4#bÑZ Gî=á'ŒbºAl…—
+V“U|8˜#aŒI„¾zŽÂIì$ûµ»•´÷›’Sþ»š-ÎÊ"àFþ< ÿâØáƯø³dáièŽ,¦î ¼öúq ïÞ‘^úúÚ× ¶²¬Ž4¦˜aÚe‰Æ<¾øø‡F¦¼¯üY6,Œƒ )À1Í7BÉmM=†˜h>ålâgتÉújÅ÷go±0­i
+ðÝ,9½c]ñ{cö¤%GÝË÷ð|ÌɈ
+»U¬1ûZç%ÔúídW:-·'í,=…øTP’sâ¸X˜¼‡ÇÛèX˜X¸O—™—²²³r­Ö›Ï_Šÿˆ¨Ÿ¿=zJâòv¢Q˜R+jîF)ÝbA2Ygð_ñ°*™¼9/ Ìq®<Ì6Vµ~‡†æ+3A².G“3èéýGÓ406dh“’4ÔÀÔ,œïÊayà’];Z‚õþpPuú§j뎤+q«X¯P—™“ƒ¯žŠ…éõs?G ø™­Ó•—ƒ!¿Ð`°öhïÐÖ¬hëýËà`‚uèƯﶌ&ûHEæÓE‘Ùä&C¯N½‡ÅïîvÙ©7rz| ºO9ÏUÓ`vÕ¦û%°AÕ15e ù?r=>óD׿†q ²[ý
+º¤×º6ç™n2ªWx;mYZqÊ—P‡j3Ïœ^º_U¢ŒñœñÓz$E£¿½÷ƒeàÃëè‡'Ív§ž¬ÿÎí õS/„¢U„,k¢’w¨÷X'§.±^)E²-)n5—>w¶çô7,6å
+ ˜ØfѬ9;¥UšŠòŒÿÉP z>­=Î}Û¹èí Ë—à¡øeÛáQ&G
+sk϶ä™IÎ ^û†EGî j¢Aâв§ ü?w[PEf½‹½2Ž÷Y®º]£ŸÜ¹,;viÏ)®óVñ£.¾å ý ìœÙF8[½Œ\çÏù­,yÉ'œ…÷O²ŸÁ¿æŸ?U^Í«åš>‹™UÁlKW±ƒŠXd.xPø Î(²¡°^Ú+î»ûBê‹hüjRBiçŒÑZ-Œãð($’>ú¶å\ccÊžZ
endstream
endobj
-4244 0 obj
-<< /Type /FontDescriptor /FontName /VDSVGV+LMRoman8-Regular /Flags 4 /FontBBox [ -456 -292 1497 1125 ] /Ascent 1125 /CapHeight 683 /Descent -292 /ItalicAngle 0 /StemV 98 /XHeight 431 /FontFile3 4246 0 R /CIDSet 4245 0 R >>
+4267 0 obj
+<< /Type /FontDescriptor /FontName /WHBEGB+LMRoman8-Regular /Flags 4 /FontBBox [ -456 -292 1497 1125 ] /Ascent 1125 /CapHeight 683 /Descent -292 /ItalicAngle 0 /StemV 98 /XHeight 431 /FontFile3 4269 0 R /CIDSet 4268 0 R >>
endobj
-4247 0 obj
-<< /Filter /FlateDecode /Length 642 >>
+4270 0 obj
+<< /Filter /FlateDecode /Length 638 >>
stream
-xÚ}”]¢0†ïùÝ ç‚(´:1&*º1Ùùˆ³·Õ%ÑB
-UôÑö…}4U¾S.7éF—Ý“IÞèür+TŸõ串:—ú+ÅöaýúíÒÝáçÁÿõº­®™û[u¾]²Æìª}Ù]Löÿ™‰²QæÊTÓ–•~aásæÂJËêjwØz#²d£ÞûTê¢!Uv´â^±¢Ì;"÷›_ͨìâݽíÔu£O•7²‘é\¶]swÖOÞè½)TSê3>p49»[]_”õa7›±BLi3£·ìªØÈnS˜hÙÝÍákÍþ^+9!œW…jë,WM¦ÏÊ›š!36]›ÏÌSºø°êxš„þ¯HúPþ'kl¡pa
-AÎ- P!8bDsÄ8Uªð9(ud.:Z#3vÄCTI@è'ˆÐA™$‘I4F&­›€¨yJy­£dŠX§ òœ€È“fb‚YŒÝÆ0DäB5É…S+Ì8:$p‰× ¸"¸pܱ33 ÅŽ$Q‚a ¬#ê
-Ì$Ì<f’.“pḂ\°#—÷OÀEa‚œjÂŒSwLPâ)d†’ÌÐ]’Í s‘43"˜ILIÒ“…yJº‚¾”“~]uWB÷NEAèœÃ5-A1( Ðd†wÖ½£öõ¶'Õçi’ßšÆ%î8sç…=)J­>O¼ºªí*÷uGel[z_{æ,¥
+xÚ}”MÚ0†ïùî‰=dɧ + ´HÝj{ ‰¡‘ˆ%áÀ¿¯íw²HU)ˆ'3ö<Ç}ùØ»‹¢>J7|öØNvõµÍ¥»zÍg4JëüZIÕ¿IYÈbˆv/죭ó½ìÙxµM·ªìŸtòVå—k!‡¬'-å¹T÷S‡ò—ûóÛrýué~ÝÕU¦¦îNž¯—¬u=3êPöýÿD¦£ìA”Ùi~ȶ+kõÂügÏóôƒµ*VueVØ9²d“ÁûTª¢%Uv4⎰¢Ì{"û›WºUfðþÖõ²ÚªSíÌçl¢+—]ßÞ¬õ“3yo Ù–êÌÆuÎþÚ4i|˜ç$ +äIO­{ô–U’MÌò·…Ž–ýíQîc·F²À²á¼.d×d¹l3u–Î\7ÁKØ|£?‰#UñWÜè㠨†¿<Bùï¬5ùK=‘çE~bie‰ƒ‚
+âÈä L¢)2iÜ DÈS€È“hU 3PäÁ:‘ç DžD0ãKÌ"¬6‚'"š“\ˆÐ%¾Á,D….ÑN—;£gz€¥È’ Š±"¬/†u@à zŒXQ OAÐ¥o‡™ ‚YŒ·€ÃL¡zˆãTkà¨cÇ8ª "ô,¤YàR=ôL`ß¹ ‚ ì´ "ê:!¨KD0è‹ w ´cœ¾”“ÞŸÚ'¾=Eç[g‚V ”‚8h–à”ÚSi´¹›>ïüÚ¶úò°˜½!ÌÝP*ùyÇ5ucFÙ¯½‡‹ÚÐûÆùó²Œý
endstream
endobj
337 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /VDSVGV+LMRoman8-Regular /DescendantFonts [ 4248 0 R ] /ToUnicode 4247 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /WHBEGB+LMRoman8-Regular /DescendantFonts [ 4271 0 R ] /ToUnicode 4270 0 R >>
endobj
-4248 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /VDSVGV+LMRoman8-Regular /FontDescriptor 4244 0 R /W 4243 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4271 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /WHBEGB+LMRoman8-Regular /FontDescriptor 4267 0 R /W 4266 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4249 0 obj
+4272 0 obj
[638.9 ]
endobj
-4250 0 obj
+4273 0 obj
[446.4 446.4 0 877 0 0 0 0 0 569.4 569.4 ]
endobj
-4251 0 obj
+4274 0 obj
[668 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 607.3 ]
endobj
-4252 0 obj
+4275 0 obj
[570 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 277.8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 777.8 500 777.8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 520.6 0 0 600.2 0 0 0 0 0 0 0 0 0 571.5 ]
endobj
-4253 0 obj
+4276 0 obj
[388.9 388.9 0 777.8 0 0 0 0 500 500 500 0 500 0 0 0 0 0 0 0 0 777.8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0 444.5 0 0 0 0 0 0 0 0 0 0 555.5 0 0 0 391.7 0 388.9 ]
endobj
-4254 0 obj
+4277 0 obj
[ 28 [ 525 ] 35 [ 525 525 ] 40 [ 525 525 525 525 ] 47 [ 525 ] 49 [ 525 525 ] 55 [ 525 ] 59 [ 525 ] 61 [ 525 ] 63 [ 525 ] 65 [ 525 525 ] 72 [ 525 525 ] 75 [ 525 ] 77 [ 525 ] 79 [ 525 ] 81 [ 525 525 ] 84 [ 525 525 525 ] 91 [ 525 ] 93 [ 525 525 ] 96 [ 525 525 525 ] 103 [ 525 ] 105 [ 525 ] 109 [ 525 ] 112 [ 525 ] 116 [ 525 ] 118 [ 525 ] ]
endobj
-4256 0 obj
+4279 0 obj
<< /Filter /FlateDecode /Length 23 >>
stream
xÚc``àø˜(šp5Oì¡K
endstream
endobj
-4257 0 obj
+4280 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 4096 >>
stream
xÚ­Xyte»Ÿ´P T¥_\fä «"q²[•B¥,ÒÒÒ%ÝiJ–¦i³4ÍÎdOÓ$MÚ¦[ÚÚ´´€´¢€B…ˆ"…O\®÷|Šz”ërÕóé÷¾xî´ ½÷èýëNÎÉòÎ3ï<Ïïy~Ïó›p°„ŒÃáܳkÝÖ´­/.yqËa¥ð‘åKÓ$y¥±SÌ\æ: 0÷cÌâ*žá'X’8àjW|þð%Å¡§“âÇ“n¨Ñøõ³às0ŒÓvGìý—»à̤Øo)Ióc ß'-Àã0vv?öö'Ž“È™ÅáýùýW¤._þØza•\TZ\"á¯X¾üчcïOò×¥òŸÏ+(ÊÄå¥ü¼ÊBþó©ü-©üt¡Œ]-å/Vòó%yE|a?S°›/ Db~±H(­?˜ÊÏ,)óeBQ9Ÿý *ybA!_ZY(ñ%%þæÛ3ù›„•þ‹¥‚J±€¿t)Ÿ/ø%IÕSË–I¤Å©BQñ²"ÖF¼¬bÒH¼,vÝÒM[Ó3—¾˜¶~cúö©’ ¿H(â
@@ -14454,10 +14511,10 @@ wù©Ð÷´ó¦Z› _×ÇÇS®1xƒ7¤;R*—×ÉhZo×
•Ûo¤ÚüÖvû„d k÷ìØ}±û˜'ÒŠ"ƒúnr.À„á‰Ç‡£ô$^qß ^Lyƒy^Åûž!¦¦M/RAÍ:%U£y+ÈÝæc­ýCý_Pžno¤8“ß›·d/ºK4‘5¶\àdsx¨‡ôÙëë5&­FD-RfåËΗDÚ­v°¨zÓ›È:µ³YO…šéNšH‰v±J°!Ï”ž1RxNÿ¦|Ù’cÿ¡ÝÉI ç`öTì¯0Ùìú&&ÍW{m.x>³bYÒt:iftÆøÌÑfKì°[šÜŽ¤¤3»ÃÊþ´Y‚®¤YLûßþÅûoÞv8§
endstream
endobj
-4255 0 obj
-<< /Type /FontDescriptor /FontName /WBOIOL+LMMono10-Italic /Flags 4 /FontBBox [ -491 -316 834 1016 ] /Ascent 1016 /CapHeight 611 /Descent -316 /ItalicAngle -15 /StemV 175 /XHeight 431 /FontFile3 4257 0 R /CIDSet 4256 0 R >>
+4278 0 obj
+<< /Type /FontDescriptor /FontName /WBOIOL+LMMono10-Italic /Flags 4 /FontBBox [ -491 -316 834 1016 ] /Ascent 1016 /CapHeight 611 /Descent -316 /ItalicAngle -15 /StemV 175 /XHeight 431 /FontFile3 4280 0 R /CIDSet 4279 0 R >>
endobj
-4258 0 obj
+4281 0 obj
<< /Filter /FlateDecode /Length 531 >>
stream
xÚ}”]kâ@†ïó+f/{‘:ùÖ"ú¶–*»{3G7 “0‰þû™wÒBqWP|<ï{'Ž~¼ïügÑÈ9û ®¹ªŠüåkÙz£Ñª©®’ý‘ 1D»'ö®šjG=/‹U!ëþA'²:_ Y÷“tªåWŠÑaã=ýö-¶ÅöÅy}mdp¿èËs]ùÜíëþ¬“ÿ›ÇtÝ2Ûä'©®nä 9çú‡µËæbÆ뼉³È&ƒéc-…r>ÙÁ¸ö‚‰ºêÙÏê¢÷dŠw·®§K!7Ÿ³É‡v½ºYÏÞd«©ZžØø¾E²»¶í™Œƽ<g‚Žº³ÞÏ[y!61³BGëþö%|•ìo-±Ðr
@@ -14467,21 +14524,21 @@ A±¥d š‚ hz¶G º8Ú€bKQ€Ì"æ(¥ ×%­,Ekë9µ»ž3ëé®SÌÃuäÈ)`†
endstream
endobj
331 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /WBOIOL+LMMono10-Italic /DescendantFonts [ 4259 0 R ] /ToUnicode 4258 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /WBOIOL+LMMono10-Italic /DescendantFonts [ 4282 0 R ] /ToUnicode 4281 0 R >>
endobj
-4259 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /WBOIOL+LMMono10-Italic /FontDescriptor 4255 0 R /W 4254 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4282 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /WBOIOL+LMMono10-Italic /FontDescriptor 4278 0 R /W 4277 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4260 0 obj
+4283 0 obj
[ 28 [ 525 ] 35 [ 525 ] 43 [ 525 ] 47 [ 525 ] 50 [ 525 ] 55 [ 525 ] 66 [ 525 ] 70 [ 525 ] 72 [ 525 ] 75 [ 525 ] 77 [ 525 ] 81 [ 525 ] 84 [ 525 ] 96 [ 525 ] 98 [ 525 ] 105 [ 525 ] 109 [ 525 ] 118 [ 525 ] ]
endobj
-4262 0 obj
+4285 0 obj
<< /Filter /FlateDecode /Length 23 >>
stream
xÚc``àTdPšâÁ°À…
endstream
endobj
-4263 0 obj
+4286 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 2127 >>
stream
xÚmV{TWŸ@2YJêƒK´%zgZ­…ÊË×QôôÊCQZ ¾Zê1@Ha“
@@ -14497,10 +14554,10 @@ L™-—ºKƒëiiálêv›“q=ʧMÓ9®v¼s⤃Éêé-nS Ÿ? @&jβ„Äëu_ôÁ饋ݸ·
GEuù»AÀЖ{ŠÓYr¹]®ÝÆÑÓ5…ð ’¦IÍNf³x…l9]Q«…“ÖP@a ¿ª­ª©¨¡áÆd]„ÌÏ.ów?áñh¬p«²¾âˆL6\æpTëäQÇQÙ“|Cà/òÿ8òy
endstream
endobj
-4261 0 obj
-<< /Type /FontDescriptor /FontName /KSANKC+LMMonoLt10-Bold /Flags 4 /FontBBox [ -454 -308 734 1039 ] /Ascent 1039 /CapHeight 611 /Descent -308 /ItalicAngle 0 /StemV 175 /XHeight 431 /FontFile3 4263 0 R /CIDSet 4262 0 R >>
+4284 0 obj
+<< /Type /FontDescriptor /FontName /KSANKC+LMMonoLt10-Bold /Flags 4 /FontBBox [ -454 -308 734 1039 ] /Ascent 1039 /CapHeight 611 /Descent -308 /ItalicAngle 0 /StemV 175 /XHeight 431 /FontFile3 4286 0 R /CIDSet 4285 0 R >>
endobj
-4264 0 obj
+4287 0 obj
<< /Filter /FlateDecode /Length 444 >>
stream
xÚ}“]O³0Çïû)êÅ’y6AÍBâ˜KˆnYŒ·¬=›MFK
@@ -14510,21 +14567,21 @@ xÚ}“]O³0Çïû)êÅ’y6AÍBâ˜KˆnYŒ·¬=›MFK
endstream
endobj
330 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /KSANKC+LMMonoLt10-Bold /DescendantFonts [ 4265 0 R ] /ToUnicode 4264 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /KSANKC+LMMonoLt10-Bold /DescendantFonts [ 4288 0 R ] /ToUnicode 4287 0 R >>
endobj
-4265 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /KSANKC+LMMonoLt10-Bold /FontDescriptor 4261 0 R /W 4260 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4288 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /KSANKC+LMMonoLt10-Bold /FontDescriptor 4284 0 R /W 4283 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4266 0 obj
+4289 0 obj
[ 27 [ 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 ] 61 [ 525 525 525 525 525 525 ] 68 [ 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 ] 101 [ 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 ] 118 [ 525 ] 120 [ 525 525 ] 139 [ 525 ] 163 [ 525 ] 202 [ 525 ] 294 [ 525 ] 602 [ 525 ] ]
endobj
-4268 0 obj
+4291 0 obj
<< /Filter /FlateDecode /Length 37 >>
stream
xÚc``ÿÿÿÿ÷÷ âÿ¯  ÄÀ À
endstream
endobj
-4269 0 obj
+4292 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 8507 >>
stream
xÚÍzw\W÷÷¬°³«TÆUÜ1w°{,‰±kl £ØPA¥Ã²°”]ÊÒ™¥w–Þ›ˆ½aŲ¨1«Q“˜&FÓ4õ9“\ž÷óÎ.(äIòü~ÿ¼ŸÏ Ë,÷ιçÞsÎ÷|Ï™––„@ °}w—ýÆ-k¦ott”Ê_Ÿ3s‹Ì+ÔßMa:·žÇg­7–à^phÇXpv–:+^lea´²ìÙ¿ËÿÐ _%Añ0þ8hßî¹Õxþ¿éVM;­&âA„€°%^%¾'z–‚!‚a‚Ñÿ0ïÜYsæÌ[¡ðñòVÚÍ3gÞ Óñ-»U³ìÜöûÉU!~>vnv³ìgÙm’«ø^»©ò@;w™·›¿§ÜÓÎI¶Ó.4D¦±óRÈCƒB^›eçäíb§’+üìøo…Ì_æ"ó° ô)ì”Þ2»uÛ¶:Ù­•*í6úì—†Èìfδ³ ‘É켕ʠE³g+C½fÉ^³=ù1!³ý{…Ì6]7sí;›œfn´{ͦ­kf)Õvžr…‡Léæã2ë?×ø¢½I®pó_é!w—Ù{È•>Ê‚ÿ¡‰±üV!‚!ìˆqÄxb1‘˜DL&¦S‰×ˆiÄtb1“˜EÌ&æ¯s‰yÄ|bññ&±x‹XD,&–ˈåÄ
@@ -14557,10 +14614,10 @@ cCݤl@¹
êô?¿T@~> ÄqL¸HŪZR5øDju„Jº*+“ñŽ¢ÔÇ—| vìO‡å'V£\Ñåušì¥‹íú¡ë½®ïùo߯ÛTçU&ùV¤.ŠB1¤:&V“ÊÈ’|å2Ú=°õ`ÕÛœÐ"æSÙ‚¼œüt&«JX˜[ ¡ñ2­€-(ò>… °–Ìi.hÖ7ŠÛ*[Ò‡Zå²,F“^[B’ú¢"=ó­ˆ:až9™ÔÆ''&1qÑÂE@®?í¸Óu›/£”iÜâ÷‰½ÈXm|\*“%Ô$hJè2-–•ò],’ÿçé#d®k±{µ‡x[ë9×.º¹)·¤–É&då&çÑ™½s[cÛã‚Çáçãœrš:Ee¬>4ŒŒDø þÎ hwŠ²’š7ˆlÊÊâÛôŠîpŽ¶šü*A‹L¯Ü~h[À½]
endstream
endobj
-4267 0 obj
-<< /Type /FontDescriptor /FontName /QYILRE+LMMono10-Regular /Flags 4 /FontBBox [ -451 -316 731 1016 ] /Ascent 1016 /CapHeight 611 /Descent -316 /ItalicAngle 0 /StemV 175 /XHeight 431 /FontFile3 4269 0 R /CIDSet 4268 0 R >>
+4290 0 obj
+<< /Type /FontDescriptor /FontName /QYILRE+LMMono10-Regular /Flags 4 /FontBBox [ -451 -316 731 1016 ] /Ascent 1016 /CapHeight 611 /Descent -316 /ItalicAngle 0 /StemV 175 /XHeight 431 /FontFile3 4292 0 R /CIDSet 4291 0 R >>
endobj
-4270 0 obj
+4293 0 obj
<< /Filter /FlateDecode /Length 755 >>
stream
xÚ}•]kâ@†ïó+f/
@@ -14573,22 +14630,22 @@ xÚ}•]kâ@†ïó+f/
endstream
endobj
329 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /QYILRE+LMMono10-Regular /DescendantFonts [ 4271 0 R ] /ToUnicode 4270 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /QYILRE+LMMono10-Regular /DescendantFonts [ 4294 0 R ] /ToUnicode 4293 0 R >>
endobj
-4271 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /QYILRE+LMMono10-Regular /FontDescriptor 4267 0 R /W 4266 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4294 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /QYILRE+LMMono10-Regular /FontDescriptor 4290 0 R /W 4289 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4272 0 obj
+4295 0 obj
[ 51 [ 569 ] 56 [ 569 569 ] 78 [ 569 ] 82 [ 569 ] 100 [ 569 569 ] 106 [ 569 569 ] 121 [ 569 ] ]
endobj
-4274 0 obj
+4297 0 obj
<< /Filter /FlateDecode /Length 21 >>
stream
xÚc`
< 
endstream
endobj
-4275 0 obj
+4298 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 1685 >>
stream
xÚuUkPTG¾óȆë(uGû^QWÂCÅøZ·`‰¸ òô±™Ë0Ì0çሠjÒ3GAŠG@^òX"")E0‚kŠZ]CP*–•X,PšÑ¾nócg´öÏVmwÕéîÓ§«¿ï;Ýu„XLÿÄÈÝá »¢câ¹Lµqs`<«µÔ&ïÞN~9¿*
@@ -14598,31 +14655,31 @@ GK›êtôËdžïýmšBó—áExáæÐà}½gËZªÝ5g:÷‚\þû¥~ÕóÛBc"õZŠOI
NÁbŽâC¤^ú®×r—`à)ê|*â+Ð%æM¤Ü× 1=ÛU8⦈ˆkQʨöR¡ ‡áyÑ Ä¶ËšªJ‰mž´Ñ¹ÃprŒú~_9&꾩ûR58WCW%Ù#B)_o-ZÈ««=%…Øä-/7ýlµ|D%2–]¨•‚¨DC°bTø¸ß™ðir8ö‡ÓálkQ(\ç-µ—:KÏ—:óÿàY
endstream
endobj
-4273 0 obj
-<< /Type /FontDescriptor /FontName /TFIASI+LMRoman7-Regular /Flags 4 /FontBBox [ -483 -292 1562 1124 ] /Ascent 1124 /CapHeight 683 /Descent -292 /ItalicAngle 0 /StemV 108 /XHeight 431 /FontFile3 4275 0 R /CIDSet 4274 0 R >>
+4296 0 obj
+<< /Type /FontDescriptor /FontName /TFIASI+LMRoman7-Regular /Flags 4 /FontBBox [ -483 -292 1562 1124 ] /Ascent 1124 /CapHeight 683 /Descent -292 /ItalicAngle 0 /StemV 108 /XHeight 431 /FontFile3 4298 0 R /CIDSet 4297 0 R >>
endobj
-4276 0 obj
+4299 0 obj
<< /Filter /FlateDecode /Length 405 >>
stream
xÚ}’]KÃ0†ïó+ŽwQ›îSeætPp›¬C¼í’³X“’¶û÷ž$ëQ ýxzÞ“¼y“ÞÍ[Í¥Ùc4¼ã°ÅÚ´V`´XëõžhKÔÍQ¢ìªõ#¼Y#rlàv‘=gZ5}gZœZ‰êwÑ•þ–¸yàv‡Ñn™Íó,z]mMYèi´Åc{*lÄ]×N5'Rÿ/ªÂUðü£­•ÑÜqÎéÇ‹– SºÖ,¾¸„¸ó}PZÚ‹UØ;ã,€T¢¹Š’¢rÍù¹n°ÌôÁ°Ù bšYÕ={×}o¬D«ô‘øw¤ÉÛª:¡óœ¥)H<ÐДѺ(b·üLRU5ç¿røîÙ+„ç$Fb]m¡ÈfOa¶¤+e¨å:]ûC@tŸÉµ$> ëi zݧ,¼<=y½zð4J<MF¦Æ&憞 <M/3ð4¸ô®Ü‚ÜÞ\󭵞ß@ŸËFi¼îqe*×åo8ºƒêh³d_K}÷O
endstream
endobj
328 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /TFIASI+LMRoman7-Regular /DescendantFonts [ 4277 0 R ] /ToUnicode 4276 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /TFIASI+LMRoman7-Regular /DescendantFonts [ 4300 0 R ] /ToUnicode 4299 0 R >>
endobj
-4277 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /TFIASI+LMRoman7-Regular /FontDescriptor 4273 0 R /W 4272 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4300 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /TFIASI+LMRoman7-Regular /FontDescriptor 4296 0 R /W 4295 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4278 0 obj
+4301 0 obj
[ 28 [ 481 ] 35 [ 517 ] 43 [ 444 ] 50 [ 444 ] 55 [ 306 ] 59 [ 500 ] 63 [ 517 333 ] 66 [ 239 ] 72 [ 239 ] 75 [ 794 ] 77 [ 517 ] 81 [ 500 ] 84 [ 517 ] 96 [ 342 556 383 ] 105 [ 361 ] 109 [ 517 ] 116 [ 461 ] 118 [ 461 ] ]
endobj
-4280 0 obj
+4303 0 obj
<< /Filter /FlateDecode /Length 23 >>
stream
xÚc``àP\0Ńá 
endstream
endobj
-4281 0 obj
+4304 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 1969 >>
stream
xÚuU PSg¾—ä&¨•˜Èäâ½WתÕBÚªX¦
@@ -14634,10 +14691,10 @@ CßLKÅ­OD@Td ŒÐÔW]mW-ÚÙÝsgöF·³³Ù3ÿü÷žÿ?ÿy~gŽñùŽã~1qÉq± WÇ%i̶ EÀ‡:½Ã¤±zî
éËXŸ—m¯Áo»!ݳ¦/}™éqe øšœjIΦFó#wɈŒ,}=1žÂ¹$üëÁÛ7ú<Vǹô;Vø[|•iæþYPZô¦-ÔÐTüOTl9Ò±>üˆ<85@ždóþ…&¡) šü^̇ {R*t·MŒV®ˆŠ¸ “aòè¹þÁáT4‘ÃD=ZQ
endstream
endobj
-4279 0 obj
-<< /Type /FontDescriptor /FontName /IMUMJO+LMSans10-Regular /Flags 4 /FontBBox [ -420 -309 1431 1154 ] /Ascent 1154 /CapHeight 694 /Descent -309 /ItalicAngle 0 /StemV 93 /XHeight 444 /FontFile3 4281 0 R /CIDSet 4280 0 R >>
+4302 0 obj
+<< /Type /FontDescriptor /FontName /IMUMJO+LMSans10-Regular /Flags 4 /FontBBox [ -420 -309 1431 1154 ] /Ascent 1154 /CapHeight 694 /Descent -309 /ItalicAngle 0 /StemV 93 /XHeight 444 /FontFile3 4304 0 R /CIDSet 4303 0 R >>
endobj
-4282 0 obj
+4305 0 obj
<< /Filter /FlateDecode /Length 458 >>
stream
xÚ}“Án£0†ï~
@@ -14645,21 +14702,21 @@ xÚ}“Án£0†ï~
endstream
endobj
327 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /IMUMJO+LMSans10-Regular /DescendantFonts [ 4283 0 R ] /ToUnicode 4282 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /IMUMJO+LMSans10-Regular /DescendantFonts [ 4306 0 R ] /ToUnicode 4305 0 R >>
endobj
-4283 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /IMUMJO+LMSans10-Regular /FontDescriptor 4279 0 R /W 4278 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4306 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /IMUMJO+LMSans10-Regular /FontDescriptor 4302 0 R /W 4301 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4284 0 obj
+4307 0 obj
[ 27 [ 750 500 ] 34 [ 708 556 500 ] 38 [ 500 500 ] 41 [ 278 722 444 278 278 764 556 ] 49 [ 681 444 500 778 278 653 306 500 500 785 500 ] 62 [ 750 556 333 361 278 ] 68 [ 306 778 528 625 278 ] 74 [ 917 833 750 556 500 ] 80 [ 778 500 500 681 556 389 389 ] 88 [ 278 778 778 528 472 ] 95 [ 736 392 556 394 278 500 500 ] 104 [ 722 389 500 500 750 556 ] 112 [ 528 1028 722 750 528 ] 118 [ 528 ] 120 [ 444 500 583 833 ] 125 [ 556 556 ] 168 [ 500 ] 199 [ 778 ] 251 [ 444 ] 277 [ 444 ] 280 [ 670 ] 284 [ 500 ] 319 [ 556 556 ] 499 [ 472 472 ] 502 [ 278 ] 612 [ 500 ] ]
endobj
-4286 0 obj
+4309 0 obj
<< /Filter /FlateDecode /Length 49 >>
stream
xÚc``°®¯ÿü~ß¿ŸþüúÆ
endstream
endobj
-4287 0 obj
+4310 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 8597 >>
stream
xÚ½z\×þï¬ËDÖèŒ9ƒ½w%{ï»HïXXʲål¡÷¶°D°÷ÞHŒ1‰%±äÚnbILÌ<ÜûÞ,¨ñãͽ÷½ûÞ.ŸffÏùõß÷û›66„@ è½nö¼YNë‡/]¶:8Ð5h옑«=½e®aÖ“ó¹¾\?h ¸>÷‘€8VÈ9ÚàA¶Â=¶6m³ñÞ>"Í+,úˆ ðŸÖõàZmûñH³`=°Üv !éDˆÞ ž‚n{ý϶7j̘ s‚Cäa¾Þ>ŽãÆŒ?Âú9Åqö(ÇÅ®îþÁQáþ¾Ž®AŽ‹G9.å¸<8Š?êë8$8ÈÑÍÓÇ5ÀË1ØËq­çGY¸gX¸£wX°,$|è(ǵ>¾áŽQÁaþŽüï0Ï
@@ -14693,10 +14750,10 @@ wåÿJ¡÷
{™‰›Sˆ‚²ÓLb°xmÀhÛÎж«¥Ë•®&Þ*Dº^o8okkn2¤éÓ CjšÑ¶Ûÿ¢æQD
endstream
endobj
-4285 0 obj
-<< /Type /FontDescriptor /FontName /VBEAUW+LMRoman10-Regular /Flags 4 /FontBBox [ -430 -290 1417 1127 ] /Ascent 1127 /CapHeight 683 /Descent -290 /ItalicAngle 0 /StemV 93 /XHeight 431 /FontFile3 4287 0 R /CIDSet 4286 0 R >>
+4308 0 obj
+<< /Type /FontDescriptor /FontName /VBEAUW+LMRoman10-Regular /Flags 4 /FontBBox [ -430 -290 1417 1127 ] /Ascent 1127 /CapHeight 683 /Descent -290 /ItalicAngle 0 /StemV 93 /XHeight 431 /FontFile3 4310 0 R /CIDSet 4309 0 R >>
endobj
-4288 0 obj
+4311 0 obj
<< /Filter /FlateDecode /Length 755 >>
stream
xÚ…•Oo›@Åï|Ší!Rr öŸY–0Æ’¥6‰â4í•ÀÚE²>øÛwwßØ®ªF”(?vfçÍcؽùò² Óªý0!¿Ø«Úc_š0ûVtÁÍͲ-ÓŒOÆT¦:¯ì¥oËÙm¶^®›z¼³Áë¦Ü+sŽúwÐÂìêæâê°Û7ó3|_äé÷á×o¯í¡hâ(|5»ã¾èÃÈ¥½ÕãÞ†ÿ'’ÙeöÙ2ó½›~¨Ûæ‘Å÷QÙySeíÁ59Ê&géÛº©zRË>œö NXU—#‘ÿ[¬[.ysFsX7Û6˜ÍØÄV®‡±?yÝwÁ乯L_7;vû™H´9vÝÞ8A,
@@ -14705,21 +14762,21 @@ xÚ…•Oo›@Åï|Ší!Rr öŸY–0Æ’¥6‰â4í•ÀÚE²>øÛwwßØ®ªF”(?vfçÍcؽùò² Óªý0!¿Ø«Úc_š0
endstream
endobj
326 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /VBEAUW+LMRoman10-Regular /DescendantFonts [ 4289 0 R ] /ToUnicode 4288 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /VBEAUW+LMRoman10-Regular /DescendantFonts [ 4312 0 R ] /ToUnicode 4311 0 R >>
endobj
-4289 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /VBEAUW+LMRoman10-Regular /FontDescriptor 4285 0 R /W 4284 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4312 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /VBEAUW+LMRoman10-Regular /FontDescriptor 4308 0 R /W 4307 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4290 0 obj
+4313 0 obj
[ 27 [ 850 547 ] 34 [ 800 625 575 ] 42 [ 813 500 ] 47 [ 625 ] 49 [ 738 513 563 ] 54 [ 707 344 563 563 ] 59 [ 563 ] 62 [ 880 625 ] 65 [ 419 313 ] 70 [ 594 676 313 ] 74 [ 1067 938 880 625 563 ] 80 [ 845 563 563 769 625 438 438 ] 88 [ 313 ] 90 [ 845 ] 96 [ 460 625 444 ] 100 [ 563 563 ] 104 [ 782 438 563 563 865 625 ] 112 [ 594 ] 114 [ 813 850 594 ] 118 [ 594 ] 120 [ 500 563 656 ] 125 [ 625 ] 499 [ 551 551 ] ]
endobj
-4292 0 obj
+4315 0 obj
<< /Filter /FlateDecode /Length 29 >>
stream
xÚc``°0,¾œ¼ïß‚7v=a H
endstream
endobj
-4293 0 obj
+4316 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 6116 >>
stream
xÚY \SWÖ’‡ˆhy%Oß Š{¬NÕªuÇ [Ü‚ì vÂNr» ›E‘Å­¶v¬uiµÎ´jíbÇNKu*Õóð2óûnÀ™vÚ™ùæû„ä½»œ{ιÿóÿß'¢lm)‘Hä¼qíf¯U+§{­ß¨Œð‹œõÊŒeÊð
@@ -14749,10 +14806,10 @@ vEÜ@L¢,‚=‰‰EÑíd©$áZáKg ½> µó‚@3–_„ï¦kb÷4{²xü¤ÙXŽ'<z\.tÕ˜Úù­4³ä™-Óô†Ÿoj‹G"`®
¬Ã¤qÖG]Ö'“Ø)­Lð6žC%ení¦pw‡¡Èa˜ÅDÚóõùùzƒ¾¸¨ô¶ƒƒ¹àLÙƒ±(ß`,p.¼?ª¯Aú?<¼Ó
endstream
endobj
-4291 0 obj
-<< /Type /FontDescriptor /FontName /RJULGE+LMRoman12-Bold /Flags 4 /FontBBox [ -476 -289 1577 1137 ] /Ascent 1137 /CapHeight 686 /Descent -289 /ItalicAngle 0 /StemV 104 /XHeight 444 /FontFile3 4293 0 R /CIDSet 4292 0 R >>
+4314 0 obj
+<< /Type /FontDescriptor /FontName /RJULGE+LMRoman12-Bold /Flags 4 /FontBBox [ -476 -289 1577 1137 ] /Ascent 1137 /CapHeight 686 /Descent -289 /ItalicAngle 0 /StemV 104 /XHeight 444 /FontFile3 4316 0 R /CIDSet 4315 0 R >>
endobj
-4294 0 obj
+4317 0 obj
<< /Filter /FlateDecode /Length 618 >>
stream
xÚ}”[Ú0…ßó+Ü$ö!K®ö²BH@ ¢Ú›€V}…ØÐHĉ’ðÀ¿¯í3©BEñeÆsÎŒc¾}mý™¬ÊŸ¶Qmuirå/Þ÷µ7dU~)•î>”’JöÑö•}5U¾U.ÖÙZÝ“I^ëü|‘ªÏzœ4W§BßS¬îÔoóãçÛ÷¥ÿö¾©Ê½#^¥Ø5»¢;›Üÿ¥1ccÌ•ø¥š¶¨ô+ Ÿƒ 0–Z.ªÒöÖz#òÇF½ãc¡eC&ÙÁZöˆÉ"ïˆÜo^š!ÙÅÛkÛ©r­•7™°ÑÆÛ®¹:ÇOÞ賑ª)ô‰ :4ÛK]Ÿ•uÃo:eRMa3›}©ØÈ6¾–&Zt×Ǹ¯Ø]kÅ"Ç!Ìæ•Tm½ÏU³×'åMÌ
@@ -14761,21 +14818,21 @@ xÚ}”[Ú0…ßó+Ü$ö!K®ö²BH@ ¢Ú›€V}…ØÐHĉ’ðÀ¿¯í3©BEñeÆsÎŒc¾}mý™¬ÊŸ¶Qmuirå/Þ÷µ
endstream
endobj
325 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /RJULGE+LMRoman12-Bold /DescendantFonts [ 4295 0 R ] /ToUnicode 4294 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /RJULGE+LMRoman12-Bold /DescendantFonts [ 4318 0 R ] /ToUnicode 4317 0 R >>
endobj
-4295 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /RJULGE+LMRoman12-Bold /FontDescriptor 4291 0 R /W 4290 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4318 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /RJULGE+LMRoman12-Bold /FontDescriptor 4314 0 R /W 4313 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4296 0 obj
+4319 0 obj
[ 66 [ 245 ] 77 [ 531 ] 81 [ 514 ] 84 [ 531 ] 105 [ 371 ] ]
endobj
-4298 0 obj
+4321 0 obj
<< /Filter /FlateDecode /Length 17 >>
stream
xÚc`€
endstream
endobj
-4299 0 obj
+4322 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 764 >>
stream
xÚmRkHQ¾ã®NÑÌmµZ›½‰VfûÀ,ìaàc·²Õ6Ý !
@@ -14784,31 +14841,31 @@ J‘j¨íB.Ô¨+S- ¥%—§E…h/ºŠ€(Ð~¥UvFÀ˜ÈšLOéÁúlÙ¹iÖIê¬ä}¢¨ˆÌûUÐÒQâuöÅ5²;
­KŠóWV¸Wv^wï¥Þ4ºÚÅZ¨¹ÔüÑy‰ùƒbÑÎX4=ÓÝMQ#§»c±Îh´3z6F¥ÿçE:’
endstream
endobj
-4297 0 obj
-<< /Type /FontDescriptor /FontName /BLRUUF+LMSans9-Regular /Flags 4 /FontBBox [ -433 -313 1466 1155 ] /Ascent 1155 /CapHeight 694 /Descent -313 /ItalicAngle 0 /StemV 95 /XHeight 444 /FontFile3 4299 0 R /CIDSet 4298 0 R >>
+4320 0 obj
+<< /Type /FontDescriptor /FontName /BLRUUF+LMSans9-Regular /Flags 4 /FontBBox [ -433 -313 1466 1155 ] /Ascent 1155 /CapHeight 694 /Descent -313 /ItalicAngle 0 /StemV 95 /XHeight 444 /FontFile3 4322 0 R /CIDSet 4321 0 R >>
endobj
-4300 0 obj
+4323 0 obj
<< /Filter /FlateDecode /Length 382 >>
stream
xÚ}R]kÂ0}ϯ¸{ô¡6uº¡”Âü‚‚_X{­ÉÕÚ¤¤íƒÿ~Ij†[!¥'÷Ü“sOÚyÙ%ÞW'ô^ûöXªZ3ôfë´ Î\±:GYm9ò¶ZN`§K°‚î,žÇRT=CŽ%ËjŽ-ë9iŠ!{tøåMWûãqé­ÖI*˱·ÇK¥Ú£¶é ªÌÿå)Âó"8‘OÔ¥PrAŸRj6’ÏTnÇ+‰³~kú,$×7Ÿp²®I0
endstream
endobj
324 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /BLRUUF+LMSans9-Regular /DescendantFonts [ 4301 0 R ] /ToUnicode 4300 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /BLRUUF+LMSans9-Regular /DescendantFonts [ 4324 0 R ] /ToUnicode 4323 0 R >>
endobj
-4301 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /BLRUUF+LMSans9-Regular /FontDescriptor 4297 0 R /W 4296 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4324 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /BLRUUF+LMSans9-Regular /FontDescriptor 4320 0 R /W 4319 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4302 0 obj
+4325 0 obj
[ 28 [ 514 ] 35 [ 571 ] 42 [ 742 457 286 286 ] 47 [ 571 ] 49 [ 699 457 ] 55 [ 314 ] 58 [ 807 514 ] 63 [ 571 ] 65 [ 371 286 ] 70 [ 542 642 286 ] 75 [ 856 ] 77 [ 571 ] 80 [ 799 514 ] 83 [ 699 571 400 400 ] 88 [ 286 ] 90 [ 799 542 ] 96 [ 402 571 405 ] 104 [ 742 400 ] 109 [ 571 ] 112 [ 542 1056 742 771 542 ] 118 [ 542 ] 125 [ 571 ] 251 [ 457 ] 502 [ 286 ] ]
endobj
-4304 0 obj
+4327 0 obj
<< /Filter /FlateDecode /Length 32 >>
stream
xÚc``à°M4LžroÃ#¿XP
endstream
endobj
-4305 0 obj
+4328 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 4953 >>
stream
xÚµX{\WÚž
@@ -14832,10 +14889,10 @@ qbÒý}41­¼ÜPXÎäfj”dR}º­­®¾•ö>žÌÂl–›1Z)·‡ a¡˜ÅõAZ°™Š\ ,1Œ¼¿kÑD1kpäæ‚l|
\*Ì/f>ÍŸÜ/-¥Ù®®–M®¼# ‰ ’¥% ÆP•—Jfæjuô;¯¾ö-?Ç`¶’••Í¯ ²$c‚A¤…àÇfCð
endstream
endobj
-4303 0 obj
-<< /Type /FontDescriptor /FontName /HTCTPP+LMRoman9-Regular /Flags 4 /FontBBox [ -443 -292 1454 1128 ] /Ascent 1128 /CapHeight 683 /Descent -292 /ItalicAngle 0 /StemV 95 /XHeight 431 /FontFile3 4305 0 R /CIDSet 4304 0 R >>
+4326 0 obj
+<< /Type /FontDescriptor /FontName /HTCTPP+LMRoman9-Regular /Flags 4 /FontBBox [ -443 -292 1454 1128 ] /Ascent 1128 /CapHeight 683 /Descent -292 /ItalicAngle 0 /StemV 95 /XHeight 431 /FontFile3 4328 0 R /CIDSet 4327 0 R >>
endobj
-4306 0 obj
+4329 0 obj
<< /Filter /FlateDecode /Length 560 >>
stream
xÚ}”OÚ0Åïùî‰=dqB/+‰Q‘º»hAU¯!64q¢$øöµý&¬T•"øeÆ3oFßv{!ë£ò§Ïœ}ª®¾¶…òWoyãF뺸VJ÷ïJI%‡h÷Êvm]ìUÏÆ«íz«ËþÉ$ouq¹J5dý;i©Î¥þJ±}Øø ~ùß«Ãnçÿxû¬«\ÏüOu¾^òÖçöÔ¡ì/&ûÿ‰ÌDÙƒ(se~ª¶+kýÊ‚gιy°ÑrUWvÂΛJ6tŸJ-[’ÊŽV¸„L–EOä>‹ÊXeïo]¯ª­>ÕÞ|Î&¦sÙõíÍ©~ò&­Tm©Ïlü@£ÉÙ_›æ¢¬ƽ4eRLiãÑ{^)6±ão¥‰–ýí‘_g·F±Ðq
@@ -14843,21 +14900,21 @@ xÚ}”OÚ0Åïùî‰=dqB/+‰Q‘º»hAU¯!64q¢$øöµý&¬T•"øeÆ3oFßv{!ë£ò§Ïœ}ª®¾¶…òWo
endstream
endobj
323 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /HTCTPP+LMRoman9-Regular /DescendantFonts [ 4307 0 R ] /ToUnicode 4306 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /HTCTPP+LMRoman9-Regular /DescendantFonts [ 4330 0 R ] /ToUnicode 4329 0 R >>
endobj
-4307 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /HTCTPP+LMRoman9-Regular /FontDescriptor 4303 0 R /W 4302 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4330 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /HTCTPP+LMRoman9-Regular /FontDescriptor 4326 0 R /W 4325 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4308 0 obj
+4331 0 obj
[ 27 [ 893 575 ] 35 [ 657 ] 43 [ 526 ] 96 [ 488 ] 98 [ 467 ] 105 [ 460 ] ]
endobj
-4310 0 obj
+4333 0 obj
<< /Filter /FlateDecode /Length 18 >>
stream
xÚc```
endstream
endobj
-4311 0 obj
+4334 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 1258 >>
stream
xÚmTmLSW¾—~Ü"]•^‹Úâ½Gãd-DñƒeNNˆÀƒM)ôR*]‹m¡”XçøÓAQðcê`lR>TÔm€M ó‡[21 ?Ì–,fºèâ’é{õ¸emÌ–,Ùûã9ç=ç9çÉóüxiJ*¥hšÖäenÉ(HÎÊγd´mÐo±[M‘‹ ‰Ë°’ã)q)-rQ"/JÉ"¥dZ)}qLÆË÷ÆK«eK)Šn™ÁS±O” áô‘21Òw+“(&Š¢) ¥¥PO©¿h ó‚« ©©k·Ú«=‹¹Ò…V§¦®y-‚ÐÊ4–WÙÝÎ* 2ÚL(Ó€² (ÇîŸZÐJ» • •Fk²W ¡Õ8‡™öšjç«TPiq"·ÝQ…«C°
@@ -14865,32 +14922,32 @@ F§`B56“à@®Jm{7¿
‰»Ýjöг{q¡U 9þL*ð6bÎÓˆ«½<é|ñHÆnþ¤·;Ú¬÷`}]{½®¶XÎnö_ïñMéØ3ƒ¸í&bª-ø¨ÿËàœ|†,—é#¬ÀÈc|)̺ün»À“»Ð¬!ûä0†d*ñvó˜eXœ?¦þâ`=D³ãâ­~M_ÞϽãÃÝ}ZØÃü¼õ[bÈ# ¦ì®ì»ôeýɶ
endstream
endobj
-4309 0 obj
-<< /Type /FontDescriptor /FontName /RMWBFT+LMRoman9-Bold /Flags 4 /FontBBox [ -501 -299 1649 1136 ] /Ascent 1136 /CapHeight 686 /Descent -299 /ItalicAngle 0 /StemV 110 /XHeight 444 /FontFile3 4311 0 R /CIDSet 4310 0 R >>
+4332 0 obj
+<< /Type /FontDescriptor /FontName /RMWBFT+LMRoman9-Bold /Flags 4 /FontBBox [ -501 -299 1649 1136 ] /Ascent 1136 /CapHeight 686 /Descent -299 /ItalicAngle 0 /StemV 110 /XHeight 444 /FontFile3 4334 0 R /CIDSet 4333 0 R >>
endobj
-4312 0 obj
+4335 0 obj
<< /Filter /FlateDecode /Length 388 >>
stream
xÚ}RMkÂ@½ï¯˜=ÄlTEVT+Ú^ãîÄ.˜Ý°Iþûî‡Q(Ò@B^Þ›™÷fÓ{ÙƒW®NŒ‡X«V3 VÛ¼"½ÞZ±¶DÙì9òŽ­°×Š±þ*]§R4#N%»´;ÕsQ‚g!;ú~‡íW²É‚÷íA•¹œ‰ºð€Ú’L4#ýG†‚g¸Ÿ¨k¡ä¢!¥Ô|x“|¥J¬&áÍ„ÝBH®oádý’h\°æ†Ü“•fC¶øx­,SY(²\Bx0dÝè«ó; á‡æ¨…<Cÿ™A#8¶UuAk(‰càX˜¾f/»¼Dmê”V4קñÙµB9y«Lq¬«œ¡ÎåÉÒħ1,7æŠ Jþ‡§¾êTxhÝë¬cØO®mŸ(1}(D±C+‡¦Æ<òÊéØ¡)uhæ9#qèÆÍ=šÄ~´›e]ÚUß7ÂZ­Í:Üy¸Ø6°x?²JU¶ÊÝßÍ¢ ùÝèèÖ
endstream
endobj
322 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /RMWBFT+LMRoman9-Bold /DescendantFonts [ 4313 0 R ] /ToUnicode 4312 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /RMWBFT+LMRoman9-Bold /DescendantFonts [ 4336 0 R ] /ToUnicode 4335 0 R >>
endobj
-4313 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /RMWBFT+LMRoman9-Bold /FontDescriptor 4309 0 R /W 4308 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4336 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /RMWBFT+LMRoman9-Bold /FontDescriptor 4332 0 R /W 4331 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4314 0 obj
+4337 0 obj
[ 28 [ 515 ] 33 [ 515 ] 47 [ 515 ] 55 [ 515 ] 59 [ 515 ] 66 [ 515 ] 77 [ 515 ] 81 [ 515 ] 84 [ 515 ] 88 [ 515 ] 96 [ 515 ] 105 [ 515 ] 114 [ 515 ] 118 [ 515 ] ]
endobj
-4316 0 obj
+4339 0 obj
<< /Filter /FlateDecode /Length 23 >>
stream
xÚc``àp`dP`ñhhpP
D)
endstream
endobj
-4317 0 obj
+4340 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 1845 >>
stream
xÚuV}TWŸ!É@5ÊšiZ©3£K- ˆ_EÛAE¥ž%1„L˜BD<u¡¼
@@ -14905,72 +14962,82 @@ oŒRWƒÉ§Ç<ï§|â Ơ‡ùP"‚{än£ËPÂq%e}åGÜ®þ©”Â(ï¼WÈ—N˜)QuoY—U–O&¿˜Pn^
g÷žÇ4úÊ8Ô‚û¼ÁE>*Ó`¨ÜzŠK@E%µ¡1«Î¬xŒºhàÒà@á,ý+ñ&p–³•Š_(½›ÈN(/è?=ûuÿ0Ý•ÂLïªDB½0O>`ôåRì ±ñ’F¢¾o§§n0Äkmè(V”Ô×®·Ò–ä× ÖF"ò’3Dg¿Ï·Ñïûñö^à¢?@·%ºÖî§âxSÛEÝþV÷ûÍý!6¶ËÎúMÈ:GÓž·`xý¼#qõNfª‚Ó4¼ áe'¯Ö_%#…ÚÁÀõl|ZQ“åñ»žúýuýJØæœeŠq?ôHÒR@8(«f©½u\Þoí!d¦­¹¹u8iwîì6sÕ;ÌÚÁí£YpoÊÛši¸PÐHú&N¥gúŸ ¿Òy¾«[â”Èj;„¤ørg³ RsJc¤Oét~šwú@û[“Ífk¶9ìR©ÛéúýMíÒÿ®ÌÞÀ
endstream
endobj
-4315 0 obj
-<< /Type /FontDescriptor /FontName /CKBVSC+LMMono12-Regular /Flags 4 /FontBBox [ -444 -311 715 1019 ] /Ascent 1019 /CapHeight 611 /Descent -311 /ItalicAngle 0 /StemV 172 /XHeight 431 /FontFile3 4317 0 R /CIDSet 4316 0 R >>
+4338 0 obj
+<< /Type /FontDescriptor /FontName /CKBVSC+LMMono12-Regular /Flags 4 /FontBBox [ -444 -311 715 1019 ] /Ascent 1019 /CapHeight 611 /Descent -311 /ItalicAngle 0 /StemV 172 /XHeight 431 /FontFile3 4340 0 R /CIDSet 4339 0 R >>
endobj
-4318 0 obj
+4341 0 obj
<< /Filter /FlateDecode /Length 428 >>
stream
xÚ}’]Oƒ0†ïû+êŽ`Dpf!qÌ%D§f,Æ[ÖžÍ&£%.öïm{†&F%ðpÞóõÒÉÅkÜ ½ƒàzÊè:=A±®[2™,5Pý3€
endstream
endobj
321 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /CKBVSC+LMMono12-Regular /DescendantFonts [ 4319 0 R ] /ToUnicode 4318 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /CKBVSC+LMMono12-Regular /DescendantFonts [ 4342 0 R ] /ToUnicode 4341 0 R >>
endobj
-4319 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /CKBVSC+LMMono12-Regular /FontDescriptor 4315 0 R /W 4314 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4342 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /CKBVSC+LMMono12-Regular /FontDescriptor 4338 0 R /W 4337 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4320 0 obj
-[ 28 [ 490 ] 43 [ 435 ] 45 [ 272 ] 54 [ 639 ] 57 [ 490 ] 59 [ 490 ] 63 [ 544 ] 66 [ 272 ] 74 [ 897 ] 77 [ 544 ] 83 [ 666 ] 88 [ 272 ] 96 [ 381 ] 105 [ 381 490 490 ] 118 [ 517 ] 121 [ 490 ] ]
+4343 0 obj
+[ 27 [ 734 490 ] 45 [ 272 ] 54 [ 639 ] 57 [ 490 ] 59 [ 490 ] 66 [ 272 ] 72 [ 272 ] 77 [ 544 ] 82 [ 490 666 544 ] 88 [ 272 ] 96 [ 381 ] 105 [ 381 ] 107 [ 490 ] 118 [ 517 ] 121 [ 490 ] ]
endobj
-4322 0 obj
+4345 0 obj
<< /Filter /FlateDecode /Length 24 >>
stream
-xÚc``à`a
-TPhh(`r
+xÚc````a
+Ph±hh`r
endstream
endobj
-4323 0 obj
-<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 2369 >>
+4346 0 obj
+<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 2280 >>
stream
-xÚ¥V PWîq˜i¢ã$¡Ó¤»Í7¢š¨Q³¢ ’ ’p£Ä ˜áèÁ¹1Ž¹ƒ€„a1(`WŒ! ¢‰.FˆÀ.¦Ülv_›f­P[µÙª­ÚW]ïuýý^ÿßÿýÇûHP"ž_·%>eÍü„ Iªü4zá¢ð$e–./Mø¸ŽÍ>$Š°Ï XbK
-Y*ˆ‹•?”M.燊Ô?r¢çDpðñÀüÙ“P*yž›¾V2' è—¼€OCȳÜCþ!@3!ùS»("*êåXUA¡:'+[K-ŠŠziA`^FÅDPñi¹*ƒ&7‡J£T|µ!‚JTxiõ¢Š¦Ò•Ùiy™”*“JQn¦t¥ZCe©Uºͼ*%;GCTê\Š_ÕÊ<ešF© t´B©¦´ÙJ*nSr
-µNEk©„œ %­QRáá¥Q*©l­¶`yd¤V—¡RgEfò{4‘y6i"çÂ×½‘˜žðzìÚÄäµZ£–ÊT©)…R›–“§‰ø#§‰*u~ZÞj…*]ùºBIks´…?B‘ùH8²Y†¬@¢‘$Ù€$#›‘H² ÉEôH¡§”‚È B*‘oó÷¦}%Lö¥ ‹Ö‰¢ëâ¹â!tz#8™û§Ô̼£‡U®Ö›7 !ï} Ó‡=X Kß•Õ%£Iš²"%èo$`,zôîè!:³·7ìÀ—%lŠ§]E^_S“ïXØK¾ï=ÙÜ‹ÿT¹Ì@¹mÖè¥+åتW¿Uvá£Þ“.kßZ}(ëÜ=Ðpƒä–ž–Í‹Ùµ35ýÈIø \ùî!å&dnžñº†áö[B6 ÎÕ•k©ÝZl%Öè6åo—÷Ãpùíc§º?Þ«ð’Å™ ]Ó´Ççu50CkO.ç‹øÂÍúÓ<(‚Ït@I)D¹Uz¸iB
-QBj <x0ô+˜âs<³n³ãìvÙn¨Múéñå*S&9Ù†fZM±„;|wAÞuØ’ÉG_¶½{„„Ž;èxý®¥¤Ô‰—šv…/ÁzñaǾ ø¤Îa~ÃÍn ¥¼6‚a5<yAȦÃ2f.ûê΢2+(.#¸3“Y"ŒB3m¦˜‡ê¼# o¿l^’1 ±Öú£ä(ú:#ã,bhagŠ¤\šnúønèp‡øûö^‚±—@Ÿ©/«›µŠU±a²æ¢öì7¹{‹o~ö%¾ðµ¸•I]™õ¥$öÇ’â½…´B¾±K]k&¶½³-ëMùºñ$ø8œñ]ÿµÖòOß8D´mÞã‰åÀUHšêK]nySMS}‘w¢ìÇ¿ºxÝ_ÖÛIööœ
-Ú˜oÒã/ûÞfp¬ÉO2®Žz7Ž/¹æjIˆLN—ý:zkäü˜¾Oj=ÝmDƒ§|ß‚"ð2)}0lh ÌaèÞˆ ÂŒAì
-ÛüƒnQƒ; Ð1Юí$zè­59øâŒø¼"Òÿ,Æ&8²DD£kËSÉI7º½Ä4êh;ÃóËœ¶6’A׃H˜ˆþpéì¹s › ®øç6ò±Ç£æ!@t"äÎDôy¬Vðâ-Î’ B±O¸Ð€²Ïë*RI®uêí'ƒï
-…ýmä>ñTàÄÜR‚#aë£|Ã%€í|èä Á×B˜Ð'ókÝjÚ Uç·½~»¯k<š¡Þæ
-θ3zŸ¯š_ÂÇ¡ˆ é¿~ ŒgÜÂÊÙøªL'¶î)K1½\ZžòqnƒØïýìó6_0ö#™PgO'‡hÔu.˜ Ž{qñæA•»­±³ÝèR•>í:s|¿}zMä’ÔÕIëIn;§iX*寚õúîavã0Í„¸®kpß5,„5³se j£‹@.¾ÜÁ;õ¨­N[(/µ™-&âÎ)ÂæpBØ*ªh
+xÚ}V PWîa˜iŒ81´ãÆiìnSÆò‡'ñˆ(x"⊑õdèÁ9PFp#ƒˆr3Ì4J@Ä ×Û(oÁÂh™˜¸’`ÖJ²ûZ›ÚlV™­Úìvu½îzýÞ÷¿÷]O€øú"`LÌòu±‹WO‰^«ÊH¤§N Š•+tÊDµ÷ãvûð'Ø@„+` –²”/é/<îï;8‡k©_s¢±"¨~×Û^}Jü?à߆uø÷vœóÿñóAÈ„@^ ÿ ‚‚
+¥J¡âäñ”N#Wk(…Z¥ËÔL
+¦âRÓ4”^¥N§ø§Z®”'jäÉ”ŽN–«)mªœZºvMµDEk©è´­rZ#§‚‚(J#—S©Zm札N¬R+BRø1šå›Ašï¼ %«bâ‚¢—G.ŽY³8X›­¥RTj*Y®MLSj‚ÿk“o;bTêŒDåÂdU’|y²œÖ¦isþ‘@$™…ÌFæ"È2d%‹¬Aâxd ’†¤#YHŽ§”¿0ó’ë‹ä üÑ‚Ó>#}~&«|Çú&ùÞmíý]ü‰¸B/p¿IžnaØx½àUìhʹ$G¿‹™,¥¹x®Å¼ÓHròÁr“TÛW¡Ñ­"Ïi`i$4±XíðÈJÕVAœ„cDÐ&¾ÀMÙò€Å,ˈj‚F­®>àÁ=wÅEr
+9؈¦˜ ‘„ž[ë¿MxËS`aH&a9ÔJBëS´¿|[é„Õ:q˜a[1–‹›­ûð=1Ï|Ê«$%|5‚a5z<ý•M‚s¥Ìö/¨Ør Ì ¯€àÎ*D4¬ES,†ˆ¡rotxèÕÑ£‘æò£ä3t9#åLbhbGˆ$\¢®½ðZîÎ]·`ä-ÐièTtb£°*v²´6דº.9}W.áÊH­ãS—-Û’R¾‡Ä~ÈÏÛ•C'ËV·¨ËŒÄÆÝëdKúcá»pøOçz
+¯¬:L4Ư3ñ˜B`Ï! å{ìYMiMy%¡<Õâß߸ùÀ]p,ýÙÞv
+Øð°”ØÌ“Ñ/Ë-Ï«.«µ9 n>ç#ÍI;2 :;Ã…O/]µ £ÆM2ö¦rŽuå?´$Dß‘þ9|CÈ”ˆÎKeÖ¶cD¥ó
+ÈAÇï°¼šÎ
+ðûgßK2xt"àÄ\Á‘°áM.úÅpàD[xÚ¸ORÇâL¾3à—nXÝ‹dmP)…XÐ N0}C´ÉLÜ@yž†¸]Z¸™ÜöÿxŠ@ÕµÉ×qˆ¾€R2|47|éŒùJºÂ®'´®]uLâSW|°šÀFhê´Ã{¾ å|‡Ü5 øv@£;¥n­CMëµêŒ†l—Ûéð®ŠgæF{­Wá_ºL}Gú°Qð,&mÊôl™E‡dï%Š PŒ1œìõ\à½â¾3e+Ô‹±¨ËAþ÷1hö Ì
+ŠJˆÓν™2Ú•_]WWáöÖ48Y£õ?wëœ0Љý
+ûàHé%]I'&/ÏkØ Ç1Ü8ÞcXªN\¤˜jöӣؽ'Üa1'¼¯=×Õ|í.!wàë~(b:û<ý[c…l4œ'Õ‰Í;
+â ;ýöÆ‚ œ[)v»®^o¬÷Ã^à uñìO2ˆ†>àü8¿¥gÆûUG<ÙvÕ (27íçOvãOÎ.
+™•°0vÉmâ²DV€J¸
+NôÙ<XLc2vdÊ7áÊìZ@‚–’Y}vEUíÈ2Ðò£)ç.vtv5’p!;_tÃ}ªØŽK@Ö«½ £–õ
+Ù8xOúØøµ¢—xœéLÀW/¢?N!Uц•"›¼?¢uÞvKsÿöÌÙË ÙÚc}qY~Hº „çóqôÉŽÎNÅÓ£j¡ ›ÌÿôÞ–=÷«¯7jþzø üØeíL;Y æ-•I¼G²‘,î??X!s½‡¬«Y6²
+ªÊËb"*Nâ? øgÞén/¶ÚŠ‹KKŠ­íUþþNw¥µÔ¶Ïj-)-ñÁîõêOÒ gng
endstream
endobj
-4321 0 obj
-<< /Type /FontDescriptor /FontName /JFYJTD+LMRoman12-Regular /Flags 4 /FontBBox [ -422 -280 1394 1127 ] /Ascent 1127 /CapHeight 683 /Descent -280 /ItalicAngle 0 /StemV 91 /XHeight 431 /FontFile3 4323 0 R /CIDSet 4322 0 R >>
+4344 0 obj
+<< /Type /FontDescriptor /FontName /NIWREQ+LMRoman12-Regular /Flags 4 /FontBBox [ -422 -280 1394 1127 ] /Ascent 1127 /CapHeight 683 /Descent -280 /ItalicAngle 0 /StemV 91 /XHeight 431 /FontFile3 4346 0 R /CIDSet 4345 0 R >>
endobj
-4324 0 obj
+4347 0 obj
<< /Filter /FlateDecode /Length 454 >>
stream
-xÚ…“Mo£0†ïþî!Rz H!­"¤‰ª_J¢Õî‘Ø“ÔR°‘Cþ}m´Òj£DÄü3ó2fWÛàAè=É £èô`8ÅkÝ’Ù¬Ô|h@õo
+xÚ…“Mo£0†ïþÞC¤ô@1¶ŠZ’JHÛ´›D»½{’Z
+62pÈ¿¯íVZm´‘ˆx˜wÆ/3ÃìÇÛ.xú
+O¥§ )^yŠKOI†Ê éÞS’"a•,÷”ÆH÷HwHX%ÅšÙÚÓ• ž·H<-Rê) «Ä˜—1ŒÅHè%G/zI0–£ë½ä£kV`W|\Ý6| ŒÆØiù•ñq³
+¾¶ªÕ­Ëò—_ÇéëpôúL>›.™
endstream
endobj
320 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /JFYJTD+LMRoman12-Regular /DescendantFonts [ 4325 0 R ] /ToUnicode 4324 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /NIWREQ+LMRoman12-Regular /DescendantFonts [ 4348 0 R ] /ToUnicode 4347 0 R >>
endobj
-4325 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /JFYJTD+LMRoman12-Regular /FontDescriptor 4321 0 R /W 4320 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4348 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /NIWREQ+LMRoman12-Regular /FontDescriptor 4344 0 R /W 4343 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4326 0 obj
+4349 0 obj
[777.8 0 0 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1000 ]
endobj
-4327 0 obj
+4350 0 obj
[ 66 [ 223 ] 77 [ 484 ] 81 [ 470 ] 84 [ 484 ] 105 [ 340 ] ]
endobj
-4329 0 obj
+4352 0 obj
<< /Filter /FlateDecode /Length 17 >>
stream
xÚc`€
endstream
endobj
-4330 0 obj
+4353 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 759 >>
stream
xÚuR]HQ¾×uM'×´Ý$uö&JîìfšôâØZù³¦n¡c;îŽN;23»«E˜ýàƒÙöPaPQ½(ê*YØßFB>ô¢XD܉1h†è%è»ðÝû{¾{¸‡A
@@ -14979,10 +15046,10 @@ xÚuR]HQ¾×uM'×´Ý$uö&JîìfšôâØZù³¦n¡c;îŽN;23»«E˜ýàƒÙöPaPQ½(ê*YØßFB>ô¢
Û'5;¶îÕ¬{ßk—-MW<sÏžŒŒ>¢ÒyÎPsÈ-úT‚2LDf_Le†qgìF,™ªñ .rÍ
endstream
endobj
-4328 0 obj
-<< /Type /FontDescriptor /FontName /BTPEXR+LMSans17-Regular /Flags 4 /FontBBox [ -395 -305 1355 1159 ] /Ascent 1159 /CapHeight 694 /Descent -305 /ItalicAngle 0 /StemV 87 /XHeight 431 /FontFile3 4330 0 R /CIDSet 4329 0 R >>
+4351 0 obj
+<< /Type /FontDescriptor /FontName /BTPEXR+LMSans17-Regular /Flags 4 /FontBBox [ -395 -305 1355 1159 ] /Ascent 1159 /CapHeight 694 /Descent -305 /ItalicAngle 0 /StemV 87 /XHeight 431 /FontFile3 4353 0 R /CIDSet 4352 0 R >>
endobj
-4331 0 obj
+4354 0 obj
<< /Filter /FlateDecode /Length 383 >>
stream
xÚ}R]kÂ0}ϯ¸{ô¡6u:™”Âü‚ÂüÀ–ákMn]À&%mü÷KR«0æ
@@ -14991,21 +15058,21 @@ Oªàd¾PWBÉCJ©ÙXI¾P…°"þÍ%øï\H®oVád“`\°ú†Ü›&*Ûœ\«‹X抄!øædQÕúê\ˆ¿Óµgè?ñh
endstream
endobj
318 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /BTPEXR+LMSans17-Regular /DescendantFonts [ 4332 0 R ] /ToUnicode 4331 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /BTPEXR+LMSans17-Regular /DescendantFonts [ 4355 0 R ] /ToUnicode 4354 0 R >>
endobj
-4332 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /BTPEXR+LMSans17-Regular /FontDescriptor 4328 0 R /W 4327 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4355 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /BTPEXR+LMSans17-Regular /FontDescriptor 4351 0 R /W 4350 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4333 0 obj
+4356 0 obj
[ 28 [ 459 ] 43 [ 406 ] 50 [ 406 ] 59 [ 459 ] 63 [ 511 ] 70 [ 485 ] 84 [ 511 ] 104 [ 668 ] ]
endobj
-4335 0 obj
+4358 0 obj
<< /Filter /FlateDecode /Length 20 >>
stream
xÚc``à`PdR
endstream
endobj
-4336 0 obj
+4359 0 obj
<< /Subtype /CIDFontType0C /Filter /FlateDecode /Length 1482 >>
stream
xÚ}UkPWÞ@’Eh³Æ²¸{u¨¨HÀרԱ­Tä¡BЊm!%‰$,y`
@@ -15017,10 +15084,10 @@ xÚ}UkPWÞ@’Eh³Æ²¸{u¨¨HÀרԱ­Tä¡BЊm!%‰$,y`
‚6Ša¨†VŠ<4º¢âÀQ’B;˜·“À@U]ãÆaxs.ÕHú~ƒé,.™Ë?êÈ2ß-ÝÑ®i€t]S‹˜X§ÔGH&1’)žÉî)ÍUUU5UGmõÑz‰Äín¨vÔÖ8NgdêŸ{0¼¬
endstream
endobj
-4334 0 obj
-<< /Type /FontDescriptor /FontName /RKQUSG+LMRoman17-Regular /Flags 4 /FontBBox [ -400 -286 1338 1125 ] /Ascent 1125 /CapHeight 683 /Descent -286 /ItalicAngle 0 /StemV 83 /XHeight 431 /FontFile3 4336 0 R /CIDSet 4335 0 R >>
+4357 0 obj
+<< /Type /FontDescriptor /FontName /RKQUSG+LMRoman17-Regular /Flags 4 /FontBBox [ -400 -286 1338 1125 ] /Ascent 1125 /CapHeight 683 /Descent -286 /ItalicAngle 0 /StemV 83 /XHeight 431 /FontFile3 4359 0 R /CIDSet 4358 0 R >>
endobj
-4337 0 obj
+4360 0 obj
<< /Filter /FlateDecode /Length 401 >>
stream
xÚ…’_OÂ0Åßû)®$ø0Ö
@@ -15029,12 +15096,12 @@ ag=’ë“[Ø[ï$¬9‘û²Ò¤e›ÓcÝ`™È\‘Ù B³²¨}t¾¯I¸Öµô/™4¢´­ªZC@IÇÜÌmrzÍJ„Ð&pS
endstream
endobj
317 0 obj
-<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /RKQUSG+LMRoman17-Regular /DescendantFonts [ 4338 0 R ] /ToUnicode 4337 0 R >>
+<< /Type /Font /Subtype /Type0 /Encoding /Identity-H /BaseFont /RKQUSG+LMRoman17-Regular /DescendantFonts [ 4361 0 R ] /ToUnicode 4360 0 R >>
endobj
-4338 0 obj
-<< /Type /Font /Subtype /CIDFontType0 /BaseFont /RKQUSG+LMRoman17-Regular /FontDescriptor 4334 0 R /W 4333 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
+4361 0 obj
+<< /Type /Font /Subtype /CIDFontType0 /BaseFont /RKQUSG+LMRoman17-Regular /FontDescriptor 4357 0 R /W 4356 0 R /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> >>
endobj
-4340 0 obj
+4363 0 obj
<< /Length1 1401 /Length2 5895 /Length3 0 /Filter /FlateDecode /Length 6849 >>
stream
xÚtTSí²6EAB“Ò‚tHèMzïB”^Ò€P¡¤H“"½£€"UDš¨t¤i‚ M:Š Â~~çœïüÿZ÷®¬µ³ß™gfÞgfžÍÏcf!¦ŽÀÀ:4N ,RjC `’$üüÎù·À ‰õAaЊÿÐÄ"¡8‚M Š#
@@ -15060,10 +15127,10 @@ l/©Ð:diA®xmÄ·iQØâìÓ³gw¢m*˜Î“C7Ë‹HÕ<KÈðå ŒÙ!ðÄO ^v1|kú?Ncpv¢ßt.:¼ï>jsMg€}fh
Aü>Egiû÷(¼  oJÔ*ùh!¨cÎVBÔ”L4·Ÿi§3$éñ?ªhA2
endstream
endobj
-4339 0 obj
-<< /Type /FontDescriptor /FontName /DGBCZV+CMTT10 /Flags 4 /FontBBox [ -4 -233 537 696 ] /Ascent 611 /CapHeight 611 /Descent -222 /ItalicAngle 0 /StemV 69 /XHeight 431 /CharSet( /visiblespace) /FontFile 4340 0 R >>
+4362 0 obj
+<< /Type /FontDescriptor /FontName /DGBCZV+CMTT10 /Flags 4 /FontBBox [ -4 -233 537 696 ] /Ascent 611 /CapHeight 611 /Descent -222 /ItalicAngle 0 /StemV 69 /XHeight 431 /CharSet( /visiblespace) /FontFile 4363 0 R >>
endobj
-4342 0 obj
+4365 0 obj
<< /Length1 1808 /Length2 2831 /Length3 0 /Filter /FlateDecode /Length 3963 >>
stream
xÚµUy<TëÿÚ-á\û6«5kdoHÆZ)c挙fœ3fÆ2ÙJQ‘JQ¡èÞ,7Š­…eÉRÙ¿ù’(ÚDüÎp»Ýz}׼Μy>ïÏö¼Ÿ÷çß܉(
@@ -15079,10 +15146,10 @@ Zç,?¡™œÌüc΄®ùj^Ïœï­8SØò²cË)Æ5FQÚÞ¦)Óí—áÚu ¯FUgÔ%óŠßwRî(^Mc[7WÕÎœ
]|pãÐàªVq­{9ÀË—/>Xç]#€ØX¡a> œkÏ2¬»ÕÃ8÷ÜÈÒPô°ÌCýཙ+# Þ¹û©õ~¹90Ç/Àt‘ðü*¾ðôÌ©CUGêßo ð®IÞÐX^
endstream
endobj
-4341 0 obj
-<< /Type /FontDescriptor /FontName /MOFIWY+LMMathItalic10-Regular /Flags 4 /FontBBox [ -32 -250 1048 750 ] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 60 /XHeight 431 /CharSet( /arrowhookleft /greater /k /less /n /pi /slash /x) /FontFile 4342 0 R >>
+4364 0 obj
+<< /Type /FontDescriptor /FontName /MOFIWY+LMMathItalic10-Regular /Flags 4 /FontBBox [ -32 -250 1048 750 ] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 60 /XHeight 431 /CharSet( /arrowhookleft /greater /k /less /n /pi /slash /x) /FontFile 4365 0 R >>
endobj
-4344 0 obj
+4367 0 obj
<< /Length1 1670 /Length2 1620 /Length3 0 /Filter /FlateDecode /Length 2652 >>
stream
xÚµT{<Ti_6É´º#lÛ“VL™›;‰a afDÑî1óÌÌaæœiæLHˆÐz‰Òf+ÛE.‰¤>›[¯(]-ÕV[Q[ËæºP*¹Ôzϵ•wß?ßÏùÌ9óü®ßçû|ù¼
@@ -15106,10 +15173,10 @@ qßoœÃv&aÅ!æ)²¿î×þP~õ¥(pÙ$Á/Át
×Ñϸ>=Þ¢Û—µ<c†´2zR¤bÒèÛ)mÇì–ò¶ÞЭ…©;—$.h‰]xsÀð¹´²;ªúë¬
endstream
endobj
-4343 0 obj
-<< /Type /FontDescriptor /FontName /KDGSHG+LMMathItalic5-Regular /Flags 4 /FontBBox [ 0 -250 1349 750 ] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 84 /XHeight 431 /CharSet( /k) /FontFile 4344 0 R >>
+4366 0 obj
+<< /Type /FontDescriptor /FontName /KDGSHG+LMMathItalic5-Regular /Flags 4 /FontBBox [ 0 -250 1349 750 ] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 84 /XHeight 431 /CharSet( /k) /FontFile 4367 0 R >>
endobj
-4346 0 obj
+4369 0 obj
<< /Length1 1689 /Length2 1813 /Length3 0 /Filter /FlateDecode /Length 2856 >>
stream
xÚµTy\Lk×-uK%ÅÜõ(¥0[Ó¢B¦™iZGTʵÔiæÌÌÑtÎ4s¦¦º-¶ˆHDˆÄ I‘¥(âZ“¥å¢•("ÔåµDˆ{fâ¢÷¾¾Ÿó™sæù­ßçû|Í„À 2S€EÂ^Š“éšð€p±I¾ y.,RH  Sh4=– †pCÙ»º3.A°‡£#a B\õl
@@ -15125,10 +15192,10 @@ yÂwÜü¸m>†Ê9.¬!"Uèåª3CPµ-€Éóñâ“ý í¡ä
Ù[]õ¿/ Ù&@2¹ôöqf9>ºsÝõjÛ”Å+WÑõ„58P“2^7ºš±Ó*|KøÖŸÃ쟿µï^LãMßIáCiÑù…[›ÊΡmaWÚ²Ö%JüÖºçvKä= žÓ,\Ú&õÚÄ®ŸX¬9áí¡ôkÿHüTØá5.×~qϲ»nZõJ‡|§5'¹Ò‡i†‚Ñ­{?ÓS¶¡åWŠ¥ìtñ¯¶ pÞl_4ùã‘W¶/ŠË{fºŽSÌÃY9« 3¼s­œÂÀ3ÍœHŒTû½HöslôÝ_7zŸHŠÛË«¸UN²ô%ŸØ5Õä ŽvH×ÄL_eàÓÒdÐÐùS(O$­©#Ñu ÷4"Îå«Ëí–¯èR¾òæKu^Þ4Êyo©Wwà›s{æ´$Ùnð ïä- *ܽàëŽ>»ao|ÒpWAÕ£æì¥k{ò+ŽÕÍ|Yþväšç®cGŒ\¤écP’À•‘*׺oX¼Z÷¤Aà³XŠÃ²u;ÒˆÅáÃfÌ=3uø”øónžàéá`í¾ÚÌ‚àŠ¸¢w§Â†“uØ[:õû¬€¿°¨ÞðÎü
endstream
endobj
-4345 0 obj
-<< /Type /FontDescriptor /FontName /GFWWXD+LMMathItalic7-Regular /Flags 4 /FontBBox [ -1 -250 1171 750 ] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 72 /XHeight 431 /CharSet( /k /pi) /FontFile 4346 0 R >>
+4368 0 obj
+<< /Type /FontDescriptor /FontName /GFWWXD+LMMathItalic7-Regular /Flags 4 /FontBBox [ -1 -250 1171 750 ] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 72 /XHeight 431 /CharSet( /k /pi) /FontFile 4369 0 R >>
endobj
-4348 0 obj
+4371 0 obj
<< /Length1 1677 /Length2 1235 /Length3 0 /Filter /FlateDecode /Length 2254 >>
stream
xÚµTy\WW»`Í"^x!Ô'-9‘³®¤PHÑ$ŠUÁ!y!C’™830€‚ÖŠ*UðÂEQñ¨U©Êz ˆ¢(^»x`«µÔ…–¥o‚VaÝ?÷3ŸÌäýÎïû¾ïï¹NŠRð$2†’Ãñ… "2cta fÀÕþ¼™0ÞlÀ( â‹…BŽ«k01' )ÆÀ
@@ -15144,10 +15211,10 @@ VLÝfh¹3U²uv®âz•Ë©.á×Ù³LEÃl·L×á%yaÊ—z,ž« u߯!ö6^sn»]qÚ\¶ó=S[ÀXlʲí]ö¢X¹æICå
/>Êá–ë×(m¿-­Õçódæäú|!µq^kAÀÊ«±u„^ò•IO__Ðî¼Ï~¡g඄Õe#9‚ü²‚£–\¸ö±±gÝ’@ŸÖöH2·rMÏøó8ïµeCFyÁbmÉ–n÷ðs0Rg7H·ÄÕaSØOîÔgeüï6äxÿ;Í–
endstream
endobj
-4347 0 obj
-<< /Type /FontDescriptor /FontName /GLFSGS+LMMathItalic9-Regular /Flags 4 /FontBBox [ -29 -250 1075 750 ] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 28 /XHeight 431 /CharSet( /slash) /FontFile 4348 0 R >>
+4370 0 obj
+<< /Type /FontDescriptor /FontName /GLFSGS+LMMathItalic9-Regular /Flags 4 /FontBBox [ -29 -250 1075 750 ] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 28 /XHeight 431 /CharSet( /slash) /FontFile 4371 0 R >>
endobj
-4350 0 obj
+4373 0 obj
<< /Length1 1846 /Length2 22110 /Length3 0 /Filter /FlateDecode /Length 23294 >>
stream
xÚ´¸sxœíó>7j¬†Û¶mÛÙ8«±“ƶ­Æ¶7Nã¤ac7~Óçùøûû÷=öXÌ9¼ç:göÞ%'VR¥6³7J؃\虘x
@@ -15243,10 +15310,10 @@ cˆdw$ûÈÞwä(ßÍ<c‚|‹Ðõ Z§_rRIÅýo}[GÚe¿AûX¯PñýzëѠμË~ÜáÇm–ÏÑ™,¾E&‹kd&W
V—h‰˜Ô¸h7Sg5T%€ÂõdÔнxÙtP2{zïvòÞ5ìØè%Û| wÁÔµn.²;¿çòZƒ]Ä ²´Yõ´ß“%˜güŒ‰w;Åd›6Btšö‡K4¿¥B7Çn3Û³™Aèo-Në™3Kˆ=QÀÒç7–OëJø´tÚæ& ¦§@Gâ±,žúmÜ‚7i'‚£Ñ5)Ó>™·é`ט ]±îqp#é— E«zh!éEKÞm¦ÈI%Z“ þ9~`Gë5çéª[VÒŽ¿IÊè¹–ôãu}·ÛÏþœÿIbÜl/ÕYA±dK>@óuº¤¦T%sÊÎ ¼úš–ø+ßRøý¿‘+„u 5ÞkEM¹
endstream
endobj
-4349 0 obj
-<< /Type /FontDescriptor /FontName /DDAMXW+LMRoman10-Regular /Flags 4 /FontBBox [ -430 -290 1417 1127 ] /Ascent 689 /CapHeight 689 /Descent -194 /ItalicAngle 0 /StemV 69 /XHeight 431 /CharSet( /a /c /equal /four /n /one /parenleft /parenright /plus /r /t /two /zero) /FontFile 4350 0 R >>
+4372 0 obj
+<< /Type /FontDescriptor /FontName /DDAMXW+LMRoman10-Regular /Flags 4 /FontBBox [ -430 -290 1417 1127 ] /Ascent 689 /CapHeight 689 /Descent -194 /ItalicAngle 0 /StemV 69 /XHeight 431 /CharSet( /a /c /equal /four /n /one /parenleft /parenright /plus /r /t /two /zero) /FontFile 4373 0 R >>
endobj
-4352 0 obj
+4375 0 obj
<< /Length1 1715 /Length2 17571 /Length3 0 /Filter /FlateDecode /Length 18712 >>
stream
xÚ´÷stÝßö=ǶÛ¶ÕØvNl»I5vÛhÜØNÛ¶ó—¾ïG÷~ŸŸqÆÁžKs¯=ׯCA¢¤Ê bæ`”t°we`adæÈÉ«8ØÛs1¨
@@ -15314,10 +15381,10 @@ L ž©
ÜÁ¡^EuGí”|¼ØÊDgæ#ƒ‡-ŠŸpAꩇs‘þš&ežþyRqù}CIÝ@ͧ†“GG¸·ï²@>;ÑBáò¡Ïíø¾µˆ/úâͯ½Íôtj
endstream
endobj
-4351 0 obj
-<< /Type /FontDescriptor /FontName /LNPUMK+LMRoman7-Regular /Flags 4 /FontBBox [ -483 -292 1562 1124 ] /Ascent 689 /CapHeight 689 /Descent -194 /ItalicAngle 0 /StemV 79 /XHeight 431 /CharSet( /one /parenleft /parenright /plus /two) /FontFile 4352 0 R >>
+4374 0 obj
+<< /Type /FontDescriptor /FontName /LNPUMK+LMRoman7-Regular /Flags 4 /FontBBox [ -483 -292 1562 1124 ] /Ascent 689 /CapHeight 689 /Descent -194 /ItalicAngle 0 /StemV 79 /XHeight 431 /CharSet( /one /parenleft /parenright /plus /two) /FontFile 4375 0 R >>
endobj
-4354 0 obj
+4377 0 obj
<< /Length1 1699 /Length2 10474 /Length3 0 /Filter /FlateDecode /Length 11567 >>
stream
xÚµxeTÚ¶5Nqw îVÜݵH)N€à$¸/‡â®ÅÝÝ)VÜ)î^ Š=Úsï;÷žïýýFFdÙ^sÏ=×NFh)Õ5Y%ÌÁ¦ Y°„•“C ¬¢ tp`Õ
@@ -15359,10 +15426,10 @@ lŠ˜ÄÌÑPˆ9'󔦃âý&h–fL[mԓ莉y9ýa§\>ëç9èIÕ¥_§¸EóKŠÄËÏÃë1œE„¥ãÔ9©â
Ùj£Ì3zÝÕݳûQ&÷-¶?>kn£˜„~Yswź$m÷t¡ KÑFP Á)ÊûŽ*ãš5^*Š=¯Ö¢eD>Ï<¹­¶W¡NRí]ÚôI“åÉ:T¨Œú’¢Ë©W$2x |¶ÂÌ·e¼c¢®b‹­ð¿Ï‘¯Õ‘ ªäpõ$HLáž©D`Ô0àÉâÎtáp¦Ÿ ¦‹·1J^À"âF‰)ἦ–°wÓ©óЩ)³§¼›÷ÇürF»å
endstream
endobj
-4353 0 obj
-<< /Type /FontDescriptor /FontName /QNRZJS+LMSans9-Regular /Flags 4 /FontBBox [ -433 -313 1466 1155 ] /Ascent 694 /CapHeight 694 /Descent -194 /ItalicAngle 0 /StemV 96 /XHeight 444 /CharSet( /A /L /S /T /U /Y) /FontFile 4354 0 R >>
+4376 0 obj
+<< /Type /FontDescriptor /FontName /QNRZJS+LMSans9-Regular /Flags 4 /FontBBox [ -433 -313 1466 1155 ] /Ascent 694 /CapHeight 694 /Descent -194 /ItalicAngle 0 /StemV 96 /XHeight 444 /CharSet( /A /L /S /T /U /Y) /FontFile 4377 0 R >>
endobj
-4356 0 obj
+4379 0 obj
<< /Length1 1740 /Length2 1925 /Length3 0 /Filter /FlateDecode /Length 2996 >>
stream
xÚµTy<Tk¿¥¨‰’J²õefŒµáuk¬Ù'3²Vsp˜9gÌå">nŠŠQ ­„V*Y)"K劫ŽJŠu½gFÝ–ÏÛŸïg>gÎy~ßßò}~Ï÷÷hk0Yd €í0'Ó(æÀÙÅÂCXQ¼
@@ -15377,10 +15444,10 @@ Zé¦8iØ+w–™7»©Ä‹§zquߺg«¶w9j.Tq
ÏNQPv-.ô;ëe>¢VŸ8ãZ‚÷Ô&/Õ2¥´Ñ–ƒ?h ¬fx6×"ÙP¸öØKK£°™ku¼—9]_ÎÖXý |³®¾wZß_$ÛE£y•ÐÆûë7$¬âÿ'¯8áÍXáÙ'«}bË}m"c‹ÿšÑZrÓŸ¡Ú°ä‚Ⱥ±ÆlQyûÀü0ú.jãFôÎCËGÃhq6仦{Z{ñRW™ø!†ç4”YT»¡Â ggÝf GùzCB[oQ¯O¨o»óÀíXÿ¢yV‡~·¶¯ô,±"(ÓY¡|ÒÓüçŽ%-‰ÙŠãúsá–õôg[:ÿ éèôù
endstream
endobj
-4355 0 obj
-<< /Type /FontDescriptor /FontName /TNOUBP+LMMathSymbols10-Regular /Flags 4 /FontBBox [ -29 -960 1116 775 ] /Ascent 750 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 40 /XHeight 431 /CharSet( /arrowright /asteriskmath /minus) /FontFile 4356 0 R >>
+4378 0 obj
+<< /Type /FontDescriptor /FontName /TNOUBP+LMMathSymbols10-Regular /Flags 4 /FontBBox [ -29 -960 1116 775 ] /Ascent 750 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 40 /XHeight 431 /CharSet( /arrowright /asteriskmath /minus) /FontFile 4379 0 R >>
endobj
-4358 0 obj
+4381 0 obj
<< /Length1 1689 /Length2 1347 /Length3 0 /Filter /FlateDecode /Length 2378 >>
stream
xÚµTyT×v5µîR
@@ -15397,10 +15464,10 @@ cÊÒk©¥G<<[$…[æn›t©à`ÎÁ1@Yó‡(èÐÑÎu¾µ/†=Êó˜_z°á;ëÖ+ª‘”q¸íÚP—î×.îͼ處‰­Ÿ
¶zÂÿòÔFåŸÆÛy¦«õ£rÝ®,º×БÝÒ9÷võBG/ý§ëNrþáÍÁ
endstream
endobj
-4357 0 obj
-<< /Type /FontDescriptor /FontName /DTFCKV+LMMathSymbols6-Regular /Flags 4 /FontBBox [ -4 -948 1329 786 ] /Ascent 750 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 52 /XHeight 431 /CharSet( /asteriskmath) /FontFile 4358 0 R >>
+4380 0 obj
+<< /Type /FontDescriptor /FontName /DTFCKV+LMMathSymbols6-Regular /Flags 4 /FontBBox [ -4 -948 1329 786 ] /Ascent 750 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 52 /XHeight 431 /CharSet( /asteriskmath) /FontFile 4381 0 R >>
endobj
-4360 0 obj
+4383 0 obj
<< /Length1 1684 /Length2 1529 /Length3 0 /Filter /FlateDecode /Length 2571 >>
stream
xÚµTiX×.\
@@ -15418,10 +15485,10 @@ f|ê÷Ìew”k¼Ç¥Ç«ÏKggåYòççfô(lWÏû$¢•¯n:4ÿ׌/æT‡~ù£ûõ±±ßüåó’÷V¹6y¯(÷ÛÇm¸ù]ó
2“]ló‘þQÚ1z]dìVþÑÌfgÁ‹¦Î?™ÈùÓ:ôùŽ=»î–ÞÐïõ\d{7ò§6mù·jÙãfåï…ƒi›o–L䆬 8m_¡Úµ)'³7ØÅ|Þ·ËndéóÝÕyk“æùõ¶Ö%\v9ÊÛ/yš¶`›Oý´~Î}kyžW+àöD(ÿÓ‚S^rΠрðjüý3¯¶vÊN<ûí
endstream
endobj
-4359 0 obj
-<< /Type /FontDescriptor /FontName /CIXFWA+LMMathSymbols7-Regular /Flags 4 /FontBBox [ -15 -951 1252 782 ] /Ascent 750 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 49 /XHeight 431 /CharSet( /minus) /FontFile 4360 0 R >>
+4382 0 obj
+<< /Type /FontDescriptor /FontName /CIXFWA+LMMathSymbols7-Regular /Flags 4 /FontBBox [ -15 -951 1252 782 ] /Ascent 750 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 49 /XHeight 431 /CharSet( /minus) /FontFile 4383 0 R >>
endobj
-4362 0 obj
+4385 0 obj
<< /Length1 1748 /Length2 1585 /Length3 0 /Filter /FlateDecode /Length 2661 >>
stream
xÚµTiXWp”º *¸\@dѬ¬Ø
@@ -15441,95 +15508,95 @@ g]Ýqbã‰)@X÷ÀuêÌ‹,æåw£Ÿluˆ.9ѲgˆvßuÆQk•|LbÓ(ÛJ»¦+•&Ä»ÖÖ!gÙÍn×bóWÛÔUVŸõÍËI!%
§÷æÃù{'eFÉÿ1´ØŠùm\ȪëmÎ 3Z6Å\ÙmÊ<áI§¼¨ÄÜu®íž3úüƒ.QW}·ÞMò1)ëZfVÙ¹ü6{j”~YªÿF]¦w͆=”,ìÈÖÿµv,D8Uè87µŠ1íò4"ùPŸbh£niþ|Ü"³ÇÙMQ"ö&óTÂö{EÞ>‡~l“¼fÃŒöðÛ[ÊN³ïš7Úö ‹¹?´ÂÆ>µ-`™¿ö;W›´G½ž²!ÈåQõ‹“µ}Vû¯û¾®±’´966Œ9ùÉÄŸ4’ž«*àVž3mï±~PTQa’ùä7ŸŽU©öÁ©ïÔÌäÒ,ë/jÍJݾ‡õ}u5[3 %}Åôo¿Ì)ÆCÆ¢–2ýN'—ž®ÈÙ·*º‹7¿Æåÿ™µÉ5ûTNCIÚƒ`ï ùNs¾oÔýÜ»» -(4Å4Ëìzù¼Å±¥SÞŽÑý<*Xx3SVhzD2©!§-7gì+^ßïÛoR/6ü6˜éu4ÕsÜSVAÜ¢ÓMø Û²Z8
endstream
endobj
-4361 0 obj
-<< /Type /FontDescriptor /FontName /SRVGJC+LMMathSymbols9-Regular /Flags 4 /FontBBox [ -30 -958 1146 777 ] /Ascent 750 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 43 /XHeight 431 /CharSet( /angbracketleft /angbracketright /asteriskmath) /FontFile 4362 0 R >>
+4384 0 obj
+<< /Type /FontDescriptor /FontName /SRVGJC+LMMathSymbols9-Regular /Flags 4 /FontBBox [ -30 -958 1146 777 ] /Ascent 750 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 43 /XHeight 431 /CharSet( /angbracketleft /angbracketright /asteriskmath) /FontFile 4385 0 R >>
endobj
-4144 0 obj
+4167 0 obj
<< /Type /Encoding /Differences [ 25 /pi 44 /arrowhookleft 60 /less /slash /greater 107 /k 110 /n 120 /x ] >>
endobj
-4148 0 obj
+4171 0 obj
<< /Type /Encoding /Differences [ 0 /minus 3 /asteriskmath 33 /arrowright 104 /angbracketleft /angbracketright ] >>
endobj
-4146 0 obj
+4169 0 obj
<< /Type /Encoding /Differences [ 40 /parenleft /parenright 43 /plus 48 /zero /one /two 52 /four 61 /equal 65 /A 76 /L 83 /S /T /U 89 /Y 97 /a 99 /c 110 /n 114 /r 116 /t ] >>
endobj
604 0 obj
-<< /Type /Font /Subtype /Type1 /BaseFont /DGBCZV+CMTT10 /FontDescriptor 4339 0 R /FirstChar 32 /LastChar 32 /Widths 4150 0 R >>
+<< /Type /Font /Subtype /Type1 /BaseFont /DGBCZV+CMTT10 /FontDescriptor 4362 0 R /FirstChar 32 /LastChar 32 /Widths 4173 0 R >>
endobj
333 0 obj
-<< /Type /Font /Subtype /Type1 /BaseFont /MOFIWY+LMMathItalic10-Regular /FontDescriptor 4341 0 R /FirstChar 25 /LastChar 120 /Widths 4252 0 R /Encoding 4144 0 R >>
+<< /Type /Font /Subtype /Type1 /BaseFont /MOFIWY+LMMathItalic10-Regular /FontDescriptor 4364 0 R /FirstChar 25 /LastChar 120 /Widths 4275 0 R /Encoding 4167 0 R >>
endobj
497 0 obj
-<< /Type /Font /Subtype /Type1 /BaseFont /KDGSHG+LMMathItalic5-Regular /FontDescriptor 4343 0 R /FirstChar 107 /LastChar 107 /Widths 4175 0 R /Encoding 4144 0 R >>
+<< /Type /Font /Subtype /Type1 /BaseFont /KDGSHG+LMMathItalic5-Regular /FontDescriptor 4366 0 R /FirstChar 107 /LastChar 107 /Widths 4198 0 R /Encoding 4167 0 R >>
endobj
334 0 obj
-<< /Type /Font /Subtype /Type1 /BaseFont /GFWWXD+LMMathItalic7-Regular /FontDescriptor 4345 0 R /FirstChar 25 /LastChar 107 /Widths 4251 0 R /Encoding 4144 0 R >>
+<< /Type /Font /Subtype /Type1 /BaseFont /GFWWXD+LMMathItalic7-Regular /FontDescriptor 4368 0 R /FirstChar 25 /LastChar 107 /Widths 4274 0 R /Encoding 4167 0 R >>
endobj
-2190 0 obj
-<< /Type /Font /Subtype /Type1 /BaseFont /GLFSGS+LMMathItalic9-Regular /FontDescriptor 4347 0 R /FirstChar 61 /LastChar 61 /Widths 4145 0 R /Encoding 4144 0 R >>
+2208 0 obj
+<< /Type /Font /Subtype /Type1 /BaseFont /GLFSGS+LMMathItalic9-Regular /FontDescriptor 4370 0 R /FirstChar 61 /LastChar 61 /Widths 4168 0 R /Encoding 4167 0 R >>
endobj
319 0 obj
-<< /Type /Font /Subtype /Type1 /BaseFont /TNOUBP+LMMathSymbols10-Regular /FontDescriptor 4355 0 R /FirstChar 0 /LastChar 33 /Widths 4326 0 R /Encoding 4148 0 R >>
+<< /Type /Font /Subtype /Type1 /BaseFont /TNOUBP+LMMathSymbols10-Regular /FontDescriptor 4378 0 R /FirstChar 0 /LastChar 33 /Widths 4349 0 R /Encoding 4171 0 R >>
endobj
336 0 obj
-<< /Type /Font /Subtype /Type1 /BaseFont /DTFCKV+LMMathSymbols6-Regular /FontDescriptor 4357 0 R /FirstChar 3 /LastChar 3 /Widths 4249 0 R /Encoding 4148 0 R >>
+<< /Type /Font /Subtype /Type1 /BaseFont /DTFCKV+LMMathSymbols6-Regular /FontDescriptor 4380 0 R /FirstChar 3 /LastChar 3 /Widths 4272 0 R /Encoding 4171 0 R >>
endobj
496 0 obj
-<< /Type /Font /Subtype /Type1 /BaseFont /CIXFWA+LMMathSymbols7-Regular /FontDescriptor 4359 0 R /FirstChar 0 /LastChar 0 /Widths 4176 0 R /Encoding 4148 0 R >>
+<< /Type /Font /Subtype /Type1 /BaseFont /CIXFWA+LMMathSymbols7-Regular /FontDescriptor 4382 0 R /FirstChar 0 /LastChar 0 /Widths 4199 0 R /Encoding 4171 0 R >>
endobj
606 0 obj
-<< /Type /Font /Subtype /Type1 /BaseFont /SRVGJC+LMMathSymbols9-Regular /FontDescriptor 4361 0 R /FirstChar 3 /LastChar 105 /Widths 4149 0 R /Encoding 4148 0 R >>
+<< /Type /Font /Subtype /Type1 /BaseFont /SRVGJC+LMMathSymbols9-Regular /FontDescriptor 4384 0 R /FirstChar 3 /LastChar 105 /Widths 4172 0 R /Encoding 4171 0 R >>
endobj
332 0 obj
-<< /Type /Font /Subtype /Type1 /BaseFont /DDAMXW+LMRoman10-Regular /FontDescriptor 4349 0 R /FirstChar 40 /LastChar 116 /Widths 4253 0 R /Encoding 4146 0 R >>
+<< /Type /Font /Subtype /Type1 /BaseFont /DDAMXW+LMRoman10-Regular /FontDescriptor 4372 0 R /FirstChar 40 /LastChar 116 /Widths 4276 0 R /Encoding 4169 0 R >>
endobj
335 0 obj
-<< /Type /Font /Subtype /Type1 /BaseFont /LNPUMK+LMRoman7-Regular /FontDescriptor 4351 0 R /FirstChar 40 /LastChar 50 /Widths 4250 0 R /Encoding 4146 0 R >>
+<< /Type /Font /Subtype /Type1 /BaseFont /LNPUMK+LMRoman7-Regular /FontDescriptor 4374 0 R /FirstChar 40 /LastChar 50 /Widths 4273 0 R /Encoding 4169 0 R >>
endobj
607 0 obj
-<< /Type /Font /Subtype /Type1 /BaseFont /QNRZJS+LMSans9-Regular /FontDescriptor 4353 0 R /FirstChar 65 /LastChar 89 /Widths 4147 0 R /Encoding 4146 0 R >>
+<< /Type /Font /Subtype /Type1 /BaseFont /QNRZJS+LMSans9-Regular /FontDescriptor 4376 0 R /FirstChar 65 /LastChar 89 /Widths 4170 0 R /Encoding 4169 0 R >>
endobj
345 0 obj
-<< /Type /Pages /Parent 4363 0 R /Count 10 /Kids [ 309 0 R 353 0 R 363 0 R 382 0 R 400 0 R 415 0 R 425 0 R 436 0 R 445 0 R 452 0 R ] >>
+<< /Type /Pages /Parent 4386 0 R /Count 10 /Kids [ 309 0 R 353 0 R 364 0 R 380 0 R 400 0 R 415 0 R 424 0 R 434 0 R 445 0 R 452 0 R ] >>
endobj
-460 0 obj
-<< /Type /Pages /Parent 4363 0 R /Count 10 /Kids [ 457 0 R 464 0 R 475 0 R 481 0 R 485 0 R 493 0 R 504 0 R 515 0 R 520 0 R 528 0 R ] >>
+459 0 obj
+<< /Type /Pages /Parent 4386 0 R /Count 10 /Kids [ 456 0 R 464 0 R 475 0 R 481 0 R 485 0 R 493 0 R 504 0 R 515 0 R 520 0 R 528 0 R ] >>
endobj
548 0 obj
-<< /Type /Pages /Parent 4363 0 R /Count 10 /Kids [ 541 0 R 553 0 R 563 0 R 569 0 R 573 0 R 577 0 R 583 0 R 592 0 R 601 0 R 644 0 R ] >>
+<< /Type /Pages /Parent 4386 0 R /Count 10 /Kids [ 541 0 R 553 0 R 563 0 R 569 0 R 573 0 R 577 0 R 583 0 R 592 0 R 601 0 R 644 0 R ] >>
endobj
749 0 obj
-<< /Type /Pages /Parent 4363 0 R /Count 10 /Kids [ 695 0 R 751 0 R 779 0 R 804 0 R 825 0 R 867 0 R 903 0 R 963 0 R 1000 0 R 1056 0 R ] >>
+<< /Type /Pages /Parent 4386 0 R /Count 10 /Kids [ 695 0 R 751 0 R 779 0 R 804 0 R 825 0 R 867 0 R 903 0 R 963 0 R 1000 0 R 1056 0 R ] >>
endobj
1177 0 obj
-<< /Type /Pages /Parent 4363 0 R /Count 10 /Kids [ 1119 0 R 1179 0 R 1246 0 R 1312 0 R 1359 0 R 1415 0 R 1473 0 R 1529 0 R 1574 0 R 1625 0 R ] >>
+<< /Type /Pages /Parent 4386 0 R /Count 10 /Kids [ 1119 0 R 1179 0 R 1244 0 R 1311 0 R 1359 0 R 1413 0 R 1471 0 R 1527 0 R 1575 0 R 1622 0 R ] >>
endobj
-1731 0 obj
-<< /Type /Pages /Parent 4363 0 R /Count 10 /Kids [ 1671 0 R 1733 0 R 1779 0 R 1841 0 R 1896 0 R 1948 0 R 1990 0 R 2047 0 R 2112 0 R 2167 0 R ] >>
+1724 0 obj
+<< /Type /Pages /Parent 4386 0 R /Count 10 /Kids [ 1670 0 R 1726 0 R 1784 0 R 1835 0 R 1894 0 R 1944 0 R 1987 0 R 2040 0 R 2104 0 R 2167 0 R ] >>
endobj
-2254 0 obj
-<< /Type /Pages /Parent 4363 0 R /Count 10 /Kids [ 2219 0 R 2256 0 R 2296 0 R 2336 0 R 2388 0 R 2431 0 R 2480 0 R 2529 0 R 2563 0 R 2619 0 R ] >>
+2253 0 obj
+<< /Type /Pages /Parent 4386 0 R /Count 10 /Kids [ 2216 0 R 2255 0 R 2298 0 R 2328 0 R 2374 0 R 2425 0 R 2465 0 R 2520 0 R 2561 0 R 2598 0 R ] >>
endobj
-2726 0 obj
-<< /Type /Pages /Parent 4363 0 R /Count 10 /Kids [ 2682 0 R 2729 0 R 2776 0 R 2832 0 R 2887 0 R 2930 0 R 2989 0 R 3049 0 R 3102 0 R 3140 0 R ] >>
+2711 0 obj
+<< /Type /Pages /Parent 4386 0 R /Count 10 /Kids [ 2653 0 R 2713 0 R 2759 0 R 2808 0 R 2863 0 R 2910 0 R 2956 0 R 3015 0 R 3071 0 R 3124 0 R ] >>
endobj
-3244 0 obj
-<< /Type /Pages /Parent 4363 0 R /Count 10 /Kids [ 3193 0 R 3246 0 R 3306 0 R 3362 0 R 3429 0 R 3484 0 R 3523 0 R 3574 0 R 3619 0 R 3673 0 R ] >>
+3213 0 obj
+<< /Type /Pages /Parent 4386 0 R /Count 10 /Kids [ 3162 0 R 3216 0 R 3268 0 R 3328 0 R 3384 0 R 3451 0 R 3506 0 R 3545 0 R 3596 0 R 3641 0 R ] >>
endobj
-3779 0 obj
-<< /Type /Pages /Parent 4363 0 R /Count 9 /Kids [ 3721 0 R 3781 0 R 3838 0 R 3901 0 R 3965 0 R 4026 0 R 4052 0 R 4116 0 R 4140 0 R ] >>
+3742 0 obj
+<< /Type /Pages /Parent 4386 0 R /Count 10 /Kids [ 3695 0 R 3744 0 R 3803 0 R 3860 0 R 3923 0 R 3987 0 R 4048 0 R 4075 0 R 4139 0 R 4163 0 R ] >>
endobj
-4363 0 obj
-<< /Type /Pages /Count 99 /Kids [ 345 0 R 460 0 R 548 0 R 749 0 R 1177 0 R 1731 0 R 2254 0 R 2726 0 R 3244 0 R 3779 0 R ] >>
+4386 0 obj
+<< /Type /Pages /Count 100 /Kids [ 345 0 R 459 0 R 548 0 R 749 0 R 1177 0 R 1724 0 R 2253 0 R 2711 0 R 3213 0 R 3742 0 R ] >>
endobj
-4364 0 obj
+4387 0 obj
<< /Type /Outlines /First 6 0 R /Last 306 0 R /Count 11 >>
endobj
306 0 obj
-<< /Title 307 0 R /A 304 0 R /Parent 4364 0 R /Prev 302 0 R >>
+<< /Title 307 0 R /A 304 0 R /Parent 4387 0 R /Prev 302 0 R >>
endobj
302 0 obj
-<< /Title 303 0 R /A 300 0 R /Parent 4364 0 R /Prev 194 0 R /Next 306 0 R >>
+<< /Title 303 0 R /A 300 0 R /Parent 4387 0 R /Prev 194 0 R /Next 306 0 R >>
endobj
298 0 obj
<< /Title 299 0 R /A 296 0 R /Parent 262 0 R /Prev 294 0 R >>
@@ -15610,7 +15677,7 @@ endobj
<< /Title 199 0 R /A 196 0 R /Parent 194 0 R /Next 202 0 R >>
endobj
194 0 obj
-<< /Title 195 0 R /A 192 0 R /Parent 4364 0 R /Prev 170 0 R /Next 302 0 R /First 198 0 R /Last 262 0 R /Count -3 >>
+<< /Title 195 0 R /A 192 0 R /Parent 4387 0 R /Prev 170 0 R /Next 302 0 R /First 198 0 R /Last 262 0 R /Count -3 >>
endobj
190 0 obj
<< /Title 191 0 R /A 188 0 R /Parent 170 0 R /Prev 186 0 R >>
@@ -15628,7 +15695,7 @@ endobj
<< /Title 175 0 R /A 172 0 R /Parent 170 0 R /Next 178 0 R >>
endobj
170 0 obj
-<< /Title 171 0 R /A 168 0 R /Parent 4364 0 R /Prev 146 0 R /Next 194 0 R /First 174 0 R /Last 190 0 R /Count -5 >>
+<< /Title 171 0 R /A 168 0 R /Parent 4387 0 R /Prev 146 0 R /Next 194 0 R /First 174 0 R /Last 190 0 R /Count -5 >>
endobj
166 0 obj
<< /Title 167 0 R /A 164 0 R /Parent 146 0 R /Prev 162 0 R >>
@@ -15646,10 +15713,10 @@ endobj
<< /Title 151 0 R /A 148 0 R /Parent 146 0 R /Next 154 0 R >>
endobj
146 0 obj
-<< /Title 147 0 R /A 144 0 R /Parent 4364 0 R /Prev 142 0 R /Next 170 0 R /First 150 0 R /Last 166 0 R /Count -5 >>
+<< /Title 147 0 R /A 144 0 R /Parent 4387 0 R /Prev 142 0 R /Next 170 0 R /First 150 0 R /Last 166 0 R /Count -5 >>
endobj
142 0 obj
-<< /Title 143 0 R /A 140 0 R /Parent 4364 0 R /Prev 62 0 R /Next 146 0 R >>
+<< /Title 143 0 R /A 140 0 R /Parent 4387 0 R /Prev 62 0 R /Next 146 0 R >>
endobj
138 0 obj
<< /Title 139 0 R /A 136 0 R /Parent 62 0 R /Prev 134 0 R >>
@@ -15709,7 +15776,7 @@ endobj
<< /Title 67 0 R /A 64 0 R /Parent 62 0 R /Next 78 0 R /First 70 0 R /Last 74 0 R /Count -2 >>
endobj
62 0 obj
-<< /Title 63 0 R /A 60 0 R /Parent 4364 0 R /Prev 34 0 R /Next 142 0 R /First 66 0 R /Last 138 0 R /Count -7 >>
+<< /Title 63 0 R /A 60 0 R /Parent 4387 0 R /Prev 34 0 R /Next 142 0 R /First 66 0 R /Last 138 0 R /Count -7 >>
endobj
58 0 obj
<< /Title 59 0 R /A 56 0 R /Parent 34 0 R /Prev 42 0 R >>
@@ -15730,7 +15797,7 @@ endobj
<< /Title 39 0 R /A 36 0 R /Parent 34 0 R /Next 42 0 R >>
endobj
34 0 obj
-<< /Title 35 0 R /A 32 0 R /Parent 4364 0 R /Prev 14 0 R /Next 62 0 R /First 38 0 R /Last 58 0 R /Count -3 >>
+<< /Title 35 0 R /A 32 0 R /Parent 4387 0 R /Prev 14 0 R /Next 62 0 R /First 38 0 R /Last 58 0 R /Count -3 >>
endobj
30 0 obj
<< /Title 31 0 R /A 28 0 R /Parent 14 0 R /Prev 26 0 R >>
@@ -15745,1491 +15812,1485 @@ endobj
<< /Title 19 0 R /A 16 0 R /Parent 14 0 R /Next 22 0 R >>
endobj
14 0 obj
-<< /Title 15 0 R /A 12 0 R /Parent 4364 0 R /Prev 10 0 R /Next 34 0 R /First 18 0 R /Last 30 0 R /Count -4 >>
+<< /Title 15 0 R /A 12 0 R /Parent 4387 0 R /Prev 10 0 R /Next 34 0 R /First 18 0 R /Last 30 0 R /Count -4 >>
endobj
10 0 obj
-<< /Title 11 0 R /A 8 0 R /Parent 4364 0 R /Prev 6 0 R /Next 14 0 R >>
+<< /Title 11 0 R /A 8 0 R /Parent 4387 0 R /Prev 6 0 R /Next 14 0 R >>
endobj
6 0 obj
-<< /Title 7 0 R /A 4 0 R /Parent 4364 0 R /Next 10 0 R >>
-endobj
-4365 0 obj
-<< /Names [ (Doc-Start) 316 0 R (HD.1) 605 0 R (HD.10) 616 0 R (HD.100) 714 0 R (HD.1000) 1702 0 R (HD.1001) 1703 0 R (HD.1002) 1704 0 R (HD.1003) 1705 0 R (HD.1004) 1706 0 R (HD.1005) 1707 0 R (HD.1006) 1708 0 R (HD.1007) 1709 0 R (HD.1008) 1710 0 R (HD.1009) 1711 0 R (HD.101) 715 0 R (HD.1010) 1712 0 R (HD.1011) 1713 0 R (HD.1012) 1714 0 R (HD.1013) 1715 0 R (HD.1014) 1716 0 R (HD.1015) 1717 0 R (HD.1016) 1718 0 R (HD.1017) 1719 0 R (HD.1018) 1720 0 R (HD.1019) 1721 0 R (HD.102) 716 0 R (HD.1020) 1722 0 R (HD.1021) 1723 0 R (HD.1022) 1724 0 R (HD.1023) 1725 0 R (HD.1024) 1726 0 R (HD.1025) 1727 0 R ] /Limits [ (Doc-Start) (HD.1025) ] >>
-endobj
-4366 0 obj
-<< /Names [ (HD.1026) 1728 0 R (HD.1027) 1729 0 R (HD.1028) 1730 0 R (HD.1029) 1736 0 R (HD.103) 717 0 R (HD.1030) 1737 0 R (HD.1031) 1738 0 R (HD.1032) 1739 0 R (HD.1033) 1740 0 R (HD.1034) 1741 0 R (HD.1035) 1742 0 R (HD.1036) 1743 0 R (HD.1037) 1744 0 R (HD.1038) 1745 0 R (HD.1039) 1746 0 R (HD.104) 718 0 R (HD.1040) 1747 0 R (HD.1041) 1748 0 R (HD.1042) 1749 0 R (HD.1043) 1750 0 R (HD.1044) 1751 0 R (HD.1045) 1752 0 R (HD.1046) 1753 0 R (HD.1047) 1754 0 R (HD.1048) 1755 0 R (HD.1049) 1756 0 R (HD.105) 719 0 R (HD.1050) 1757 0 R (HD.1051) 1758 0 R (HD.1052) 1759 0 R (HD.1053) 1760 0 R (HD.1054) 1761 0 R ] /Limits [ (HD.1026) (HD.1054) ] >>
-endobj
-4367 0 obj
-<< /Names [ (HD.1055) 1762 0 R (HD.1056) 1763 0 R (HD.1057) 1764 0 R (HD.1058) 1765 0 R (HD.1059) 1766 0 R (HD.106) 720 0 R (HD.1060) 1767 0 R (HD.1061) 1768 0 R (HD.1062) 1769 0 R (HD.1063) 1770 0 R (HD.1064) 1771 0 R (HD.1065) 1772 0 R (HD.1066) 1773 0 R (HD.1067) 1774 0 R (HD.1068) 1775 0 R (HD.1069) 1776 0 R (HD.107) 721 0 R (HD.1070) 1777 0 R (HD.1071) 1782 0 R (HD.1072) 1783 0 R (HD.1073) 1784 0 R (HD.1074) 1785 0 R (HD.1075) 1786 0 R (HD.1076) 1787 0 R (HD.1077) 1788 0 R (HD.1078) 1789 0 R (HD.1079) 1790 0 R (HD.108) 722 0 R (HD.1080) 1791 0 R (HD.1081) 1792 0 R (HD.1082) 1793 0 R (HD.1083) 1794 0 R ] /Limits [ (HD.1055) (HD.1083) ] >>
-endobj
-4368 0 obj
-<< /Names [ (HD.1084) 1795 0 R (HD.1085) 1796 0 R (HD.1086) 1797 0 R (HD.1087) 1798 0 R (HD.1088) 1799 0 R (HD.1089) 1800 0 R (HD.109) 723 0 R (HD.1090) 1801 0 R (HD.1091) 1802 0 R (HD.1092) 1803 0 R (HD.1093) 1804 0 R (HD.1094) 1805 0 R (HD.1095) 1806 0 R (HD.1096) 1807 0 R (HD.1097) 1808 0 R (HD.1098) 1809 0 R (HD.1099) 1810 0 R (HD.11) 617 0 R (HD.110) 724 0 R (HD.1100) 1811 0 R (HD.1101) 1812 0 R (HD.1102) 1813 0 R (HD.1103) 1814 0 R (HD.1104) 1815 0 R (HD.1105) 1816 0 R (HD.1106) 1817 0 R (HD.1107) 1818 0 R (HD.1108) 1819 0 R (HD.1109) 1820 0 R (HD.111) 725 0 R (HD.1110) 1821 0 R (HD.1111) 1822 0 R ] /Limits [ (HD.1084) (HD.1111) ] >>
-endobj
-4369 0 obj
-<< /Names [ (HD.1112) 1823 0 R (HD.1113) 1824 0 R (HD.1114) 1825 0 R (HD.1115) 1826 0 R (HD.1116) 1827 0 R (HD.1117) 1828 0 R (HD.1118) 1829 0 R (HD.1119) 1830 0 R (HD.112) 726 0 R (HD.1120) 1831 0 R (HD.1121) 1832 0 R (HD.1122) 1833 0 R (HD.1123) 1834 0 R (HD.1124) 1835 0 R (HD.1125) 1836 0 R (HD.1126) 1837 0 R (HD.1127) 1838 0 R (HD.1128) 1839 0 R (HD.1129) 1844 0 R (HD.113) 727 0 R (HD.1130) 1845 0 R (HD.1131) 1846 0 R (HD.1132) 1847 0 R (HD.1133) 1848 0 R (HD.1134) 1849 0 R (HD.1135) 1850 0 R (HD.1136) 1851 0 R (HD.1137) 1852 0 R (HD.1138) 1853 0 R (HD.1139) 1854 0 R (HD.114) 728 0 R (HD.1140) 1855 0 R ] /Limits [ (HD.1112) (HD.1140) ] >>
-endobj
-4370 0 obj
-<< /Names [ (HD.1141) 1856 0 R (HD.1142) 1857 0 R (HD.1143) 1858 0 R (HD.1144) 1859 0 R (HD.1145) 1860 0 R (HD.1146) 1861 0 R (HD.1147) 1862 0 R (HD.1148) 1863 0 R (HD.1149) 1864 0 R (HD.115) 729 0 R (HD.1150) 1865 0 R (HD.1151) 1866 0 R (HD.1152) 1867 0 R (HD.1153) 1868 0 R (HD.1154) 1869 0 R (HD.1155) 1870 0 R (HD.1156) 1871 0 R (HD.1157) 1872 0 R (HD.1158) 1873 0 R (HD.1159) 1874 0 R (HD.116) 730 0 R (HD.1160) 1875 0 R (HD.1161) 1876 0 R (HD.1162) 1877 0 R (HD.1163) 1878 0 R (HD.1164) 1879 0 R (HD.1165) 1880 0 R (HD.1166) 1881 0 R (HD.1167) 1882 0 R (HD.1168) 1883 0 R (HD.1169) 1884 0 R (HD.117) 731 0 R ] /Limits [ (HD.1141) (HD.117) ] >>
-endobj
-4371 0 obj
-<< /Names [ (HD.1170) 1885 0 R (HD.1171) 1886 0 R (HD.1172) 1887 0 R (HD.1173) 1888 0 R (HD.1174) 1889 0 R (HD.1175) 1890 0 R (HD.1176) 1891 0 R (HD.1177) 1892 0 R (HD.1178) 1893 0 R (HD.1179) 1894 0 R (HD.118) 732 0 R (HD.1180) 1899 0 R (HD.1181) 1900 0 R (HD.1182) 1901 0 R (HD.1183) 1902 0 R (HD.1184) 1903 0 R (HD.1185) 1904 0 R (HD.1186) 1905 0 R (HD.1187) 1906 0 R (HD.1188) 1907 0 R (HD.1189) 1908 0 R (HD.119) 733 0 R (HD.1190) 1909 0 R (HD.1191) 1910 0 R (HD.1192) 1911 0 R (HD.1193) 1912 0 R (HD.1194) 1913 0 R (HD.1195) 1914 0 R (HD.1196) 1915 0 R (HD.1197) 1916 0 R (HD.1198) 1917 0 R (HD.1199) 1918 0 R ] /Limits [ (HD.1170) (HD.1199) ] >>
-endobj
-4372 0 obj
-<< /Names [ (HD.12) 618 0 R (HD.120) 734 0 R (HD.1200) 1919 0 R (HD.1201) 1920 0 R (HD.1202) 1921 0 R (HD.1203) 1922 0 R (HD.1204) 1923 0 R (HD.1205) 1924 0 R (HD.1206) 1925 0 R (HD.1207) 1926 0 R (HD.1208) 1927 0 R (HD.1209) 1928 0 R (HD.121) 735 0 R (HD.1210) 1929 0 R (HD.1211) 1930 0 R (HD.1212) 1931 0 R (HD.1213) 1932 0 R (HD.1214) 1933 0 R (HD.1215) 1934 0 R (HD.1216) 1935 0 R (HD.1217) 1936 0 R (HD.1218) 1937 0 R (HD.1219) 1938 0 R (HD.122) 736 0 R (HD.1220) 1939 0 R (HD.1221) 1940 0 R (HD.1222) 1941 0 R (HD.1223) 1942 0 R (HD.1224) 1943 0 R (HD.1225) 1944 0 R (HD.1226) 1945 0 R (HD.1227) 1946 0 R ] /Limits [ (HD.12) (HD.1227) ] >>
-endobj
-4373 0 obj
-<< /Names [ (HD.1228) 1951 0 R (HD.1229) 1952 0 R (HD.123) 737 0 R (HD.1230) 1953 0 R (HD.1231) 1954 0 R (HD.1232) 1955 0 R (HD.1233) 1956 0 R (HD.1234) 1957 0 R (HD.1235) 1958 0 R (HD.1236) 1959 0 R (HD.1237) 1960 0 R (HD.1238) 1961 0 R (HD.1239) 1962 0 R (HD.124) 738 0 R (HD.1240) 1963 0 R (HD.1241) 1964 0 R (HD.1242) 1965 0 R (HD.1243) 1966 0 R (HD.1244) 1967 0 R (HD.1245) 1968 0 R (HD.1246) 1969 0 R (HD.1247) 1970 0 R (HD.1248) 1971 0 R (HD.1249) 1972 0 R (HD.125) 739 0 R (HD.1250) 1973 0 R (HD.1251) 1974 0 R (HD.1252) 1975 0 R (HD.1253) 1976 0 R (HD.1254) 1977 0 R (HD.1255) 1978 0 R (HD.1256) 1979 0 R ] /Limits [ (HD.1228) (HD.1256) ] >>
-endobj
-4374 0 obj
-<< /Names [ (HD.1257) 1980 0 R (HD.1258) 1981 0 R (HD.1259) 1982 0 R (HD.126) 740 0 R (HD.1260) 1983 0 R (HD.1261) 1984 0 R (HD.1262) 1985 0 R (HD.1263) 1986 0 R (HD.1264) 1987 0 R (HD.1265) 1988 0 R (HD.1266) 1993 0 R (HD.1267) 1994 0 R (HD.1268) 1995 0 R (HD.1269) 1996 0 R (HD.127) 741 0 R (HD.1270) 1997 0 R (HD.1271) 1998 0 R (HD.1272) 1999 0 R (HD.1273) 2000 0 R (HD.1274) 2001 0 R (HD.1275) 2002 0 R (HD.1276) 2003 0 R (HD.1277) 2004 0 R (HD.1278) 2005 0 R (HD.1279) 2006 0 R (HD.128) 742 0 R (HD.1280) 2007 0 R (HD.1281) 2008 0 R (HD.1282) 2009 0 R (HD.1283) 2010 0 R (HD.1284) 2011 0 R (HD.1285) 2012 0 R ] /Limits [ (HD.1257) (HD.1285) ] >>
-endobj
-4375 0 obj
-<< /Names [ (HD.1286) 2013 0 R (HD.1287) 2014 0 R (HD.1288) 2015 0 R (HD.1289) 2016 0 R (HD.129) 743 0 R (HD.1290) 2017 0 R (HD.1291) 2018 0 R (HD.1292) 2019 0 R (HD.1293) 2020 0 R (HD.1294) 2021 0 R (HD.1295) 2022 0 R (HD.1296) 2023 0 R (HD.1297) 2024 0 R (HD.1298) 2025 0 R (HD.1299) 2026 0 R (HD.13) 619 0 R (HD.130) 744 0 R (HD.1300) 2027 0 R (HD.1301) 2028 0 R (HD.1302) 2029 0 R (HD.1303) 2030 0 R (HD.1304) 2031 0 R (HD.1305) 2032 0 R (HD.1306) 2033 0 R (HD.1307) 2034 0 R (HD.1308) 2035 0 R (HD.1309) 2036 0 R (HD.131) 745 0 R (HD.1310) 2037 0 R (HD.1311) 2038 0 R (HD.1312) 2039 0 R (HD.1313) 2040 0 R ] /Limits [ (HD.1286) (HD.1313) ] >>
-endobj
-4376 0 obj
-<< /Names [ (HD.1314) 2041 0 R (HD.1315) 2042 0 R (HD.1316) 2043 0 R (HD.1317) 2044 0 R (HD.1318) 2045 0 R (HD.1319) 2050 0 R (HD.132) 746 0 R (HD.1320) 2051 0 R (HD.1321) 2052 0 R (HD.1322) 2053 0 R (HD.1323) 2054 0 R (HD.1324) 2055 0 R (HD.1325) 2056 0 R (HD.1326) 2057 0 R (HD.1327) 2058 0 R (HD.1328) 2059 0 R (HD.1329) 2060 0 R (HD.133) 747 0 R (HD.1330) 2061 0 R (HD.1331) 2062 0 R (HD.1332) 2063 0 R (HD.1333) 2064 0 R (HD.1334) 2065 0 R (HD.1335) 2066 0 R (HD.1336) 2067 0 R (HD.1337) 2068 0 R (HD.1338) 2069 0 R (HD.1339) 2070 0 R (HD.134) 748 0 R (HD.1340) 2071 0 R (HD.1341) 2072 0 R (HD.1342) 2073 0 R ] /Limits [ (HD.1314) (HD.1342) ] >>
-endobj
-4377 0 obj
-<< /Names [ (HD.1343) 2074 0 R (HD.1344) 2075 0 R (HD.1345) 2076 0 R (HD.1346) 2077 0 R (HD.1347) 2078 0 R (HD.1348) 2079 0 R (HD.1349) 2080 0 R (HD.135) 754 0 R (HD.1350) 2081 0 R (HD.1351) 2082 0 R (HD.1352) 2083 0 R (HD.1353) 2084 0 R (HD.1354) 2085 0 R (HD.1355) 2086 0 R (HD.1356) 2087 0 R (HD.1357) 2088 0 R (HD.1358) 2089 0 R (HD.1359) 2090 0 R (HD.136) 755 0 R (HD.1360) 2091 0 R (HD.1361) 2092 0 R (HD.1362) 2093 0 R (HD.1363) 2094 0 R (HD.1364) 2095 0 R (HD.1365) 2096 0 R (HD.1366) 2097 0 R (HD.1367) 2098 0 R (HD.1368) 2099 0 R (HD.1369) 2100 0 R (HD.137) 756 0 R (HD.1370) 2101 0 R (HD.1371) 2102 0 R ] /Limits [ (HD.1343) (HD.1371) ] >>
-endobj
-4378 0 obj
-<< /Names [ (HD.1372) 2103 0 R (HD.1373) 2104 0 R (HD.1374) 2105 0 R (HD.1375) 2106 0 R (HD.1376) 2107 0 R (HD.1377) 2108 0 R (HD.1378) 2109 0 R (HD.1379) 2110 0 R (HD.138) 757 0 R (HD.1380) 2115 0 R (HD.1381) 2116 0 R (HD.1382) 2117 0 R (HD.1383) 2118 0 R (HD.1384) 2119 0 R (HD.1385) 2120 0 R (HD.1386) 2121 0 R (HD.1387) 2122 0 R (HD.1388) 2123 0 R (HD.1389) 2124 0 R (HD.139) 758 0 R (HD.1390) 2125 0 R (HD.1391) 2126 0 R (HD.1392) 2127 0 R (HD.1393) 2128 0 R (HD.1394) 2129 0 R (HD.1395) 2130 0 R (HD.1396) 2131 0 R (HD.1397) 2132 0 R (HD.1398) 2133 0 R (HD.1399) 2134 0 R (HD.14) 620 0 R (HD.140) 759 0 R ] /Limits [ (HD.1372) (HD.140) ] >>
-endobj
-4379 0 obj
-<< /Names [ (HD.1400) 2135 0 R (HD.1401) 2136 0 R (HD.1402) 2137 0 R (HD.1403) 2138 0 R (HD.1404) 2139 0 R (HD.1405) 2140 0 R (HD.1406) 2141 0 R (HD.1407) 2142 0 R (HD.1408) 2143 0 R (HD.1409) 2144 0 R (HD.141) 760 0 R (HD.1410) 2145 0 R (HD.1411) 2146 0 R (HD.1412) 2147 0 R (HD.1413) 2148 0 R (HD.1414) 2149 0 R (HD.1415) 2150 0 R (HD.1416) 2151 0 R (HD.1417) 2152 0 R (HD.1418) 2153 0 R (HD.1419) 2154 0 R (HD.142) 761 0 R (HD.1420) 2155 0 R (HD.1421) 2156 0 R (HD.1422) 2157 0 R (HD.1423) 2158 0 R (HD.1424) 2159 0 R (HD.1425) 2160 0 R (HD.1426) 2161 0 R (HD.1427) 2162 0 R (HD.1428) 2163 0 R (HD.1429) 2164 0 R ] /Limits [ (HD.1400) (HD.1429) ] >>
-endobj
-4380 0 obj
-<< /Names [ (HD.143) 762 0 R (HD.1430) 2165 0 R (HD.1431) 2170 0 R (HD.1432) 2171 0 R (HD.1433) 2172 0 R (HD.1434) 2173 0 R (HD.1435) 2174 0 R (HD.1436) 2175 0 R (HD.1437) 2176 0 R (HD.1438) 2177 0 R (HD.1439) 2178 0 R (HD.144) 763 0 R (HD.1440) 2179 0 R (HD.1441) 2180 0 R (HD.1442) 2181 0 R (HD.1443) 2182 0 R (HD.1444) 2183 0 R (HD.1445) 2184 0 R (HD.1446) 2185 0 R (HD.1447) 2186 0 R (HD.1448) 2187 0 R (HD.1449) 2188 0 R (HD.145) 764 0 R (HD.1450) 2189 0 R (HD.1451) 2191 0 R (HD.1452) 2192 0 R (HD.1453) 2193 0 R (HD.1454) 2194 0 R (HD.1455) 2195 0 R (HD.1456) 2196 0 R (HD.1457) 2197 0 R (HD.1458) 2198 0 R ] /Limits [ (HD.143) (HD.1458) ] >>
-endobj
-4381 0 obj
-<< /Names [ (HD.1459) 2199 0 R (HD.146) 765 0 R (HD.1460) 2200 0 R (HD.1461) 2201 0 R (HD.1462) 2202 0 R (HD.1463) 2203 0 R (HD.1464) 2204 0 R (HD.1465) 2205 0 R (HD.1466) 2206 0 R (HD.1467) 2207 0 R (HD.1468) 2208 0 R (HD.1469) 2209 0 R (HD.147) 766 0 R (HD.1470) 2210 0 R (HD.1471) 2211 0 R (HD.1472) 2212 0 R (HD.1473) 2213 0 R (HD.1474) 2214 0 R (HD.1475) 2215 0 R (HD.1476) 2216 0 R (HD.1477) 2217 0 R (HD.1478) 2222 0 R (HD.1479) 2223 0 R (HD.148) 767 0 R (HD.1480) 2224 0 R (HD.1481) 2225 0 R (HD.1482) 2226 0 R (HD.1483) 2227 0 R (HD.1484) 2228 0 R (HD.1485) 2229 0 R (HD.1486) 2230 0 R (HD.1487) 2231 0 R ] /Limits [ (HD.1459) (HD.1487) ] >>
-endobj
-4382 0 obj
-<< /Names [ (HD.1488) 2232 0 R (HD.1489) 2233 0 R (HD.149) 768 0 R (HD.1490) 2234 0 R (HD.1491) 2235 0 R (HD.1492) 2236 0 R (HD.1493) 2237 0 R (HD.1494) 2238 0 R (HD.1495) 2239 0 R (HD.1496) 2240 0 R (HD.1497) 2241 0 R (HD.1498) 2242 0 R (HD.1499) 2243 0 R (HD.15) 621 0 R (HD.150) 769 0 R (HD.1500) 2244 0 R (HD.1501) 2245 0 R (HD.1502) 2246 0 R (HD.1503) 2247 0 R (HD.1504) 2248 0 R (HD.1505) 2249 0 R (HD.1506) 2250 0 R (HD.1507) 2251 0 R (HD.1508) 2252 0 R (HD.1509) 2253 0 R (HD.151) 770 0 R (HD.1510) 2259 0 R (HD.1511) 2260 0 R (HD.1512) 2261 0 R (HD.1513) 2262 0 R (HD.1514) 2263 0 R (HD.1515) 2264 0 R ] /Limits [ (HD.1488) (HD.1515) ] >>
-endobj
-4383 0 obj
-<< /Names [ (HD.1516) 2265 0 R (HD.1517) 2266 0 R (HD.1518) 2267 0 R (HD.1519) 2268 0 R (HD.152) 771 0 R (HD.1520) 2269 0 R (HD.1521) 2271 0 R (HD.1522) 2272 0 R (HD.1523) 2273 0 R (HD.1524) 2274 0 R (HD.1525) 2275 0 R (HD.1526) 2276 0 R (HD.1527) 2277 0 R (HD.1528) 2278 0 R (HD.1529) 2279 0 R (HD.153) 772 0 R (HD.1530) 2280 0 R (HD.1531) 2281 0 R (HD.1532) 2282 0 R (HD.1533) 2283 0 R (HD.1534) 2284 0 R (HD.1535) 2285 0 R (HD.1536) 2286 0 R (HD.1537) 2287 0 R (HD.1538) 2288 0 R (HD.1539) 2289 0 R (HD.154) 773 0 R (HD.1540) 2290 0 R (HD.1541) 2291 0 R (HD.1542) 2292 0 R (HD.1543) 2293 0 R (HD.1544) 2294 0 R ] /Limits [ (HD.1516) (HD.1544) ] >>
-endobj
-4384 0 obj
-<< /Names [ (HD.1545) 2299 0 R (HD.1546) 2300 0 R (HD.1547) 2301 0 R (HD.1548) 2302 0 R (HD.1549) 2303 0 R (HD.155) 774 0 R (HD.1550) 2304 0 R (HD.1551) 2305 0 R (HD.1552) 2306 0 R (HD.1553) 2307 0 R (HD.1554) 2308 0 R (HD.1555) 2310 0 R (HD.1556) 2311 0 R (HD.1557) 2312 0 R (HD.1558) 2313 0 R (HD.1559) 2314 0 R (HD.156) 775 0 R (HD.1560) 2315 0 R (HD.1561) 2316 0 R (HD.1562) 2317 0 R (HD.1563) 2318 0 R (HD.1564) 2319 0 R (HD.1565) 2320 0 R (HD.1566) 2321 0 R (HD.1567) 2322 0 R (HD.1568) 2323 0 R (HD.1569) 2324 0 R (HD.157) 776 0 R (HD.1570) 2325 0 R (HD.1571) 2326 0 R (HD.1572) 2327 0 R (HD.1573) 2328 0 R ] /Limits [ (HD.1545) (HD.1573) ] >>
-endobj
-4385 0 obj
-<< /Names [ (HD.1574) 2329 0 R (HD.1575) 2330 0 R (HD.1576) 2331 0 R (HD.1577) 2332 0 R (HD.1578) 2333 0 R (HD.1579) 2334 0 R (HD.158) 777 0 R (HD.1580) 2339 0 R (HD.1581) 2340 0 R (HD.1582) 2341 0 R (HD.1583) 2342 0 R (HD.1584) 2343 0 R (HD.1585) 2344 0 R (HD.1586) 2345 0 R (HD.1587) 2346 0 R (HD.1588) 2347 0 R (HD.1589) 2349 0 R (HD.159) 782 0 R (HD.1590) 2350 0 R (HD.1591) 2351 0 R (HD.1592) 2352 0 R (HD.1593) 2353 0 R (HD.1594) 2354 0 R (HD.1595) 2355 0 R (HD.1596) 2356 0 R (HD.1597) 2357 0 R (HD.1598) 2358 0 R (HD.1599) 2359 0 R (HD.16) 622 0 R (HD.160) 783 0 R (HD.1600) 2360 0 R (HD.1601) 2361 0 R ] /Limits [ (HD.1574) (HD.1601) ] >>
-endobj
-4386 0 obj
-<< /Names [ (HD.1602) 2362 0 R (HD.1603) 2363 0 R (HD.1604) 2364 0 R (HD.1605) 2365 0 R (HD.1606) 2366 0 R (HD.1607) 2367 0 R (HD.1608) 2368 0 R (HD.1609) 2369 0 R (HD.161) 784 0 R (HD.1610) 2370 0 R (HD.1611) 2371 0 R (HD.1612) 2372 0 R (HD.1613) 2373 0 R (HD.1614) 2374 0 R (HD.1615) 2375 0 R (HD.1616) 2376 0 R (HD.1617) 2377 0 R (HD.1618) 2378 0 R (HD.1619) 2379 0 R (HD.162) 785 0 R (HD.1620) 2380 0 R (HD.1621) 2381 0 R (HD.1622) 2382 0 R (HD.1623) 2383 0 R (HD.1624) 2384 0 R (HD.1625) 2385 0 R (HD.1626) 2386 0 R (HD.1627) 2391 0 R (HD.1628) 2392 0 R (HD.1629) 2393 0 R (HD.163) 786 0 R (HD.1630) 2394 0 R ] /Limits [ (HD.1602) (HD.1630) ] >>
-endobj
-4387 0 obj
-<< /Names [ (HD.1631) 2395 0 R (HD.1632) 2396 0 R (HD.1633) 2397 0 R (HD.1634) 2398 0 R (HD.1635) 2399 0 R (HD.1636) 2400 0 R (HD.1637) 2401 0 R (HD.1638) 2402 0 R (HD.1639) 2403 0 R (HD.164) 787 0 R (HD.1640) 2404 0 R (HD.1641) 2405 0 R (HD.1642) 2406 0 R (HD.1643) 2407 0 R (HD.1644) 2408 0 R (HD.1645) 2409 0 R (HD.1646) 2410 0 R (HD.1647) 2411 0 R (HD.1648) 2412 0 R (HD.1649) 2413 0 R (HD.165) 788 0 R (HD.1650) 2414 0 R (HD.1651) 2415 0 R (HD.1652) 2416 0 R (HD.1653) 2417 0 R (HD.1654) 2418 0 R (HD.1655) 2419 0 R (HD.1656) 2420 0 R (HD.1657) 2421 0 R (HD.1658) 2422 0 R (HD.1659) 2423 0 R (HD.166) 789 0 R ] /Limits [ (HD.1631) (HD.166) ] >>
+<< /Title 7 0 R /A 4 0 R /Parent 4387 0 R /Next 10 0 R >>
endobj
4388 0 obj
-<< /Names [ (HD.1660) 2424 0 R (HD.1661) 2426 0 R (HD.1662) 2427 0 R (HD.1663) 2428 0 R (HD.1664) 2434 0 R (HD.1665) 2435 0 R (HD.1666) 2436 0 R (HD.1667) 2437 0 R (HD.1668) 2438 0 R (HD.1669) 2439 0 R (HD.167) 790 0 R (HD.1670) 2440 0 R (HD.1671) 2441 0 R (HD.1672) 2442 0 R (HD.1673) 2443 0 R (HD.1674) 2444 0 R (HD.1675) 2445 0 R (HD.1676) 2446 0 R (HD.1677) 2447 0 R (HD.1678) 2448 0 R (HD.1679) 2449 0 R (HD.168) 791 0 R (HD.1680) 2450 0 R (HD.1681) 2451 0 R (HD.1682) 2452 0 R (HD.1683) 2453 0 R (HD.1684) 2454 0 R (HD.1685) 2455 0 R (HD.1686) 2456 0 R (HD.1687) 2457 0 R (HD.1688) 2458 0 R (HD.1689) 2459 0 R ] /Limits [ (HD.1660) (HD.1689) ] >>
+<< /Names [ (Doc-Start) 316 0 R (HD.1) 605 0 R (HD.10) 616 0 R (HD.100) 714 0 R (HD.1000) 1702 0 R (HD.1001) 1703 0 R (HD.1002) 1704 0 R (HD.1003) 1705 0 R (HD.1004) 1706 0 R (HD.1005) 1707 0 R (HD.1006) 1708 0 R (HD.1007) 1709 0 R (HD.1008) 1710 0 R (HD.1009) 1711 0 R (HD.101) 715 0 R (HD.1010) 1712 0 R (HD.1011) 1713 0 R (HD.1012) 1714 0 R (HD.1013) 1715 0 R (HD.1014) 1716 0 R (HD.1015) 1717 0 R (HD.1016) 1718 0 R (HD.1017) 1719 0 R (HD.1018) 1720 0 R (HD.1019) 1721 0 R (HD.102) 716 0 R (HD.1020) 1722 0 R (HD.1021) 1723 0 R (HD.1022) 1729 0 R (HD.1023) 1730 0 R (HD.1024) 1731 0 R (HD.1025) 1732 0 R ] /Limits [ (Doc-Start) (HD.1025) ] >>
endobj
4389 0 obj
-<< /Names [ (HD.169) 792 0 R (HD.1690) 2460 0 R (HD.1691) 2461 0 R (HD.1692) 2462 0 R (HD.1693) 2463 0 R (HD.1694) 2464 0 R (HD.1695) 2465 0 R (HD.1696) 2466 0 R (HD.1697) 2467 0 R (HD.1698) 2468 0 R (HD.1699) 2469 0 R (HD.17) 623 0 R (HD.170) 793 0 R (HD.1700) 2470 0 R (HD.1701) 2471 0 R (HD.1702) 2472 0 R (HD.1703) 2473 0 R (HD.1704) 2474 0 R (HD.1705) 2475 0 R (HD.1706) 2476 0 R (HD.1707) 2483 0 R (HD.1708) 2484 0 R (HD.1709) 2485 0 R (HD.171) 794 0 R (HD.1710) 2486 0 R (HD.1711) 2487 0 R (HD.1712) 2488 0 R (HD.1713) 2489 0 R (HD.1714) 2490 0 R (HD.1715) 2491 0 R (HD.1716) 2492 0 R (HD.1717) 2493 0 R ] /Limits [ (HD.169) (HD.1717) ] >>
+<< /Names [ (HD.1026) 1733 0 R (HD.1027) 1734 0 R (HD.1028) 1735 0 R (HD.1029) 1736 0 R (HD.103) 717 0 R (HD.1030) 1737 0 R (HD.1031) 1738 0 R (HD.1032) 1739 0 R (HD.1033) 1740 0 R (HD.1034) 1741 0 R (HD.1035) 1742 0 R (HD.1036) 1743 0 R (HD.1037) 1744 0 R (HD.1038) 1745 0 R (HD.1039) 1746 0 R (HD.104) 718 0 R (HD.1040) 1747 0 R (HD.1041) 1748 0 R (HD.1042) 1749 0 R (HD.1043) 1750 0 R (HD.1044) 1751 0 R (HD.1045) 1752 0 R (HD.1046) 1753 0 R (HD.1047) 1754 0 R (HD.1048) 1755 0 R (HD.1049) 1756 0 R (HD.105) 719 0 R (HD.1050) 1757 0 R (HD.1051) 1758 0 R (HD.1052) 1759 0 R (HD.1053) 1760 0 R (HD.1054) 1761 0 R ] /Limits [ (HD.1026) (HD.1054) ] >>
endobj
4390 0 obj
-<< /Names [ (HD.1718) 2494 0 R (HD.1719) 2495 0 R (HD.172) 795 0 R (HD.1720) 2496 0 R (HD.1721) 2497 0 R (HD.1722) 2498 0 R (HD.1723) 2499 0 R (HD.1724) 2500 0 R (HD.1725) 2501 0 R (HD.1726) 2502 0 R (HD.1727) 2503 0 R (HD.1728) 2504 0 R (HD.1729) 2505 0 R (HD.173) 796 0 R (HD.1730) 2506 0 R (HD.1731) 2507 0 R (HD.1732) 2508 0 R (HD.1733) 2509 0 R (HD.1734) 2510 0 R (HD.1735) 2511 0 R (HD.1736) 2512 0 R (HD.1737) 2513 0 R (HD.1738) 2514 0 R (HD.1739) 2515 0 R (HD.174) 797 0 R (HD.1740) 2516 0 R (HD.1741) 2517 0 R (HD.1742) 2518 0 R (HD.1743) 2519 0 R (HD.1744) 2520 0 R (HD.1745) 2521 0 R (HD.1746) 2522 0 R ] /Limits [ (HD.1718) (HD.1746) ] >>
+<< /Names [ (HD.1055) 1762 0 R (HD.1056) 1763 0 R (HD.1057) 1764 0 R (HD.1058) 1765 0 R (HD.1059) 1766 0 R (HD.106) 720 0 R (HD.1060) 1767 0 R (HD.1061) 1768 0 R (HD.1062) 1769 0 R (HD.1063) 1770 0 R (HD.1064) 1771 0 R (HD.1065) 1772 0 R (HD.1066) 1773 0 R (HD.1067) 1774 0 R (HD.1068) 1775 0 R (HD.1069) 1776 0 R (HD.107) 721 0 R (HD.1070) 1777 0 R (HD.1071) 1778 0 R (HD.1072) 1779 0 R (HD.1073) 1780 0 R (HD.1074) 1781 0 R (HD.1075) 1782 0 R (HD.1076) 1787 0 R (HD.1077) 1788 0 R (HD.1078) 1789 0 R (HD.1079) 1790 0 R (HD.108) 722 0 R (HD.1080) 1791 0 R (HD.1081) 1792 0 R (HD.1082) 1793 0 R (HD.1083) 1794 0 R ] /Limits [ (HD.1055) (HD.1083) ] >>
endobj
4391 0 obj
-<< /Names [ (HD.1747) 2523 0 R (HD.1748) 2524 0 R (HD.1749) 2525 0 R (HD.175) 798 0 R (HD.1750) 2532 0 R (HD.1751) 2533 0 R (HD.1752) 2534 0 R (HD.1753) 2535 0 R (HD.1754) 2536 0 R (HD.1755) 2537 0 R (HD.1756) 2538 0 R (HD.1757) 2539 0 R (HD.1758) 2540 0 R (HD.1759) 2541 0 R (HD.176) 799 0 R (HD.1760) 2542 0 R (HD.1761) 2543 0 R (HD.1762) 2544 0 R (HD.1763) 2545 0 R (HD.1764) 2547 0 R (HD.1765) 2548 0 R (HD.1766) 2549 0 R (HD.1767) 2550 0 R (HD.1768) 2551 0 R (HD.1769) 2552 0 R (HD.177) 800 0 R (HD.1770) 2553 0 R (HD.1771) 2554 0 R (HD.1772) 2555 0 R (HD.1773) 2556 0 R (HD.1774) 2557 0 R (HD.1775) 2558 0 R ] /Limits [ (HD.1747) (HD.1775) ] >>
+<< /Names [ (HD.1084) 1795 0 R (HD.1085) 1796 0 R (HD.1086) 1797 0 R (HD.1087) 1798 0 R (HD.1088) 1799 0 R (HD.1089) 1800 0 R (HD.109) 723 0 R (HD.1090) 1801 0 R (HD.1091) 1802 0 R (HD.1092) 1803 0 R (HD.1093) 1804 0 R (HD.1094) 1805 0 R (HD.1095) 1806 0 R (HD.1096) 1807 0 R (HD.1097) 1808 0 R (HD.1098) 1809 0 R (HD.1099) 1810 0 R (HD.11) 617 0 R (HD.110) 724 0 R (HD.1100) 1811 0 R (HD.1101) 1812 0 R (HD.1102) 1813 0 R (HD.1103) 1814 0 R (HD.1104) 1815 0 R (HD.1105) 1816 0 R (HD.1106) 1817 0 R (HD.1107) 1818 0 R (HD.1108) 1819 0 R (HD.1109) 1820 0 R (HD.111) 725 0 R (HD.1110) 1821 0 R (HD.1111) 1822 0 R ] /Limits [ (HD.1084) (HD.1111) ] >>
endobj
4392 0 obj
-<< /Names [ (HD.1776) 2566 0 R (HD.1777) 2567 0 R (HD.1778) 2568 0 R (HD.1779) 2569 0 R (HD.178) 801 0 R (HD.1780) 2570 0 R (HD.1781) 2571 0 R (HD.1782) 2572 0 R (HD.1783) 2573 0 R (HD.1784) 2574 0 R (HD.1785) 2575 0 R (HD.1786) 2576 0 R (HD.1787) 2577 0 R (HD.1788) 2578 0 R (HD.1789) 2579 0 R (HD.179) 802 0 R (HD.1790) 2580 0 R (HD.1791) 2581 0 R (HD.1792) 2582 0 R (HD.1793) 2583 0 R (HD.1794) 2584 0 R (HD.1795) 2585 0 R (HD.1796) 2586 0 R (HD.1797) 2587 0 R (HD.1798) 2588 0 R (HD.1799) 2589 0 R (HD.18) 624 0 R (HD.180) 807 0 R (HD.1800) 2590 0 R (HD.1801) 2591 0 R (HD.1802) 2592 0 R (HD.1803) 2593 0 R ] /Limits [ (HD.1776) (HD.1803) ] >>
+<< /Names [ (HD.1112) 1823 0 R (HD.1113) 1824 0 R (HD.1114) 1825 0 R (HD.1115) 1826 0 R (HD.1116) 1827 0 R (HD.1117) 1828 0 R (HD.1118) 1829 0 R (HD.1119) 1830 0 R (HD.112) 726 0 R (HD.1120) 1831 0 R (HD.1121) 1832 0 R (HD.1122) 1833 0 R (HD.1123) 1838 0 R (HD.1124) 1839 0 R (HD.1125) 1840 0 R (HD.1126) 1841 0 R (HD.1127) 1842 0 R (HD.1128) 1843 0 R (HD.1129) 1844 0 R (HD.113) 727 0 R (HD.1130) 1845 0 R (HD.1131) 1846 0 R (HD.1132) 1847 0 R (HD.1133) 1848 0 R (HD.1134) 1849 0 R (HD.1135) 1850 0 R (HD.1136) 1851 0 R (HD.1137) 1852 0 R (HD.1138) 1853 0 R (HD.1139) 1854 0 R (HD.114) 728 0 R (HD.1140) 1855 0 R ] /Limits [ (HD.1112) (HD.1140) ] >>
endobj
4393 0 obj
-<< /Names [ (HD.1804) 2594 0 R (HD.1805) 2595 0 R (HD.1806) 2596 0 R (HD.1807) 2597 0 R (HD.1808) 2598 0 R (HD.1809) 2599 0 R (HD.181) 808 0 R (HD.1810) 2600 0 R (HD.1811) 2601 0 R (HD.1812) 2602 0 R (HD.1813) 2603 0 R (HD.1814) 2604 0 R (HD.1815) 2605 0 R (HD.1816) 2606 0 R (HD.1817) 2607 0 R (HD.1818) 2608 0 R (HD.1819) 2609 0 R (HD.182) 809 0 R (HD.1820) 2610 0 R (HD.1821) 2612 0 R (HD.1822) 2613 0 R (HD.1823) 2615 0 R (HD.1824) 2617 0 R (HD.1825) 2623 0 R (HD.1826) 2624 0 R (HD.1827) 2625 0 R (HD.1828) 2626 0 R (HD.1829) 2627 0 R (HD.183) 810 0 R (HD.1830) 2628 0 R (HD.1831) 2629 0 R (HD.1832) 2630 0 R ] /Limits [ (HD.1804) (HD.1832) ] >>
+<< /Names [ (HD.1141) 1856 0 R (HD.1142) 1857 0 R (HD.1143) 1858 0 R (HD.1144) 1859 0 R (HD.1145) 1860 0 R (HD.1146) 1861 0 R (HD.1147) 1862 0 R (HD.1148) 1863 0 R (HD.1149) 1864 0 R (HD.115) 729 0 R (HD.1150) 1865 0 R (HD.1151) 1866 0 R (HD.1152) 1867 0 R (HD.1153) 1868 0 R (HD.1154) 1869 0 R (HD.1155) 1870 0 R (HD.1156) 1871 0 R (HD.1157) 1872 0 R (HD.1158) 1873 0 R (HD.1159) 1874 0 R (HD.116) 730 0 R (HD.1160) 1875 0 R (HD.1161) 1876 0 R (HD.1162) 1877 0 R (HD.1163) 1878 0 R (HD.1164) 1879 0 R (HD.1165) 1880 0 R (HD.1166) 1881 0 R (HD.1167) 1882 0 R (HD.1168) 1883 0 R (HD.1169) 1884 0 R (HD.117) 731 0 R ] /Limits [ (HD.1141) (HD.117) ] >>
endobj
4394 0 obj
-<< /Names [ (HD.1833) 2631 0 R (HD.1834) 2632 0 R (HD.1835) 2633 0 R (HD.1836) 2634 0 R (HD.1837) 2635 0 R (HD.1838) 2636 0 R (HD.1839) 2637 0 R (HD.184) 811 0 R (HD.1840) 2638 0 R (HD.1841) 2639 0 R (HD.1842) 2640 0 R (HD.1843) 2641 0 R (HD.1844) 2642 0 R (HD.1845) 2643 0 R (HD.1846) 2644 0 R (HD.1847) 2645 0 R (HD.1848) 2646 0 R (HD.1849) 2647 0 R (HD.185) 812 0 R (HD.1850) 2648 0 R (HD.1851) 2649 0 R (HD.1852) 2650 0 R (HD.1853) 2651 0 R (HD.1854) 2652 0 R (HD.1855) 2653 0 R (HD.1856) 2654 0 R (HD.1857) 2655 0 R (HD.1858) 2656 0 R (HD.1859) 2657 0 R (HD.186) 813 0 R (HD.1860) 2658 0 R (HD.1861) 2659 0 R ] /Limits [ (HD.1833) (HD.1861) ] >>
+<< /Names [ (HD.1170) 1885 0 R (HD.1171) 1886 0 R (HD.1172) 1887 0 R (HD.1173) 1888 0 R (HD.1174) 1889 0 R (HD.1175) 1890 0 R (HD.1176) 1891 0 R (HD.1177) 1892 0 R (HD.1178) 1897 0 R (HD.1179) 1898 0 R (HD.118) 732 0 R (HD.1180) 1899 0 R (HD.1181) 1900 0 R (HD.1182) 1901 0 R (HD.1183) 1902 0 R (HD.1184) 1903 0 R (HD.1185) 1904 0 R (HD.1186) 1905 0 R (HD.1187) 1906 0 R (HD.1188) 1907 0 R (HD.1189) 1908 0 R (HD.119) 733 0 R (HD.1190) 1909 0 R (HD.1191) 1910 0 R (HD.1192) 1911 0 R (HD.1193) 1912 0 R (HD.1194) 1913 0 R (HD.1195) 1914 0 R (HD.1196) 1915 0 R (HD.1197) 1916 0 R (HD.1198) 1917 0 R (HD.1199) 1918 0 R ] /Limits [ (HD.1170) (HD.1199) ] >>
endobj
4395 0 obj
-<< /Names [ (HD.1862) 2660 0 R (HD.1863) 2661 0 R (HD.1864) 2662 0 R (HD.1865) 2663 0 R (HD.1866) 2664 0 R (HD.1867) 2665 0 R (HD.1868) 2666 0 R (HD.1869) 2667 0 R (HD.187) 814 0 R (HD.1870) 2668 0 R (HD.1871) 2669 0 R (HD.1872) 2670 0 R (HD.1873) 2671 0 R (HD.1874) 2672 0 R (HD.1875) 2673 0 R (HD.1876) 2674 0 R (HD.1877) 2675 0 R (HD.1878) 2676 0 R (HD.1879) 2677 0 R (HD.188) 815 0 R (HD.1880) 2678 0 R (HD.1881) 2679 0 R (HD.1882) 2680 0 R (HD.1883) 2685 0 R (HD.1884) 2686 0 R (HD.1885) 2687 0 R (HD.1886) 2688 0 R (HD.1887) 2689 0 R (HD.1888) 2691 0 R (HD.1889) 2692 0 R (HD.189) 816 0 R (HD.1890) 2693 0 R ] /Limits [ (HD.1862) (HD.1890) ] >>
+<< /Names [ (HD.12) 618 0 R (HD.120) 734 0 R (HD.1200) 1919 0 R (HD.1201) 1920 0 R (HD.1202) 1921 0 R (HD.1203) 1922 0 R (HD.1204) 1923 0 R (HD.1205) 1924 0 R (HD.1206) 1925 0 R (HD.1207) 1926 0 R (HD.1208) 1927 0 R (HD.1209) 1928 0 R (HD.121) 735 0 R (HD.1210) 1929 0 R (HD.1211) 1930 0 R (HD.1212) 1931 0 R (HD.1213) 1932 0 R (HD.1214) 1933 0 R (HD.1215) 1934 0 R (HD.1216) 1935 0 R (HD.1217) 1936 0 R (HD.1218) 1937 0 R (HD.1219) 1938 0 R (HD.122) 736 0 R (HD.1220) 1939 0 R (HD.1221) 1940 0 R (HD.1222) 1941 0 R (HD.1223) 1942 0 R (HD.1224) 1947 0 R (HD.1225) 1948 0 R (HD.1226) 1949 0 R (HD.1227) 1950 0 R ] /Limits [ (HD.12) (HD.1227) ] >>
endobj
4396 0 obj
-<< /Names [ (HD.1891) 2694 0 R (HD.1892) 2696 0 R (HD.1893) 2697 0 R (HD.1894) 2698 0 R (HD.1895) 2699 0 R (HD.1896) 2700 0 R (HD.1897) 2701 0 R (HD.1898) 2702 0 R (HD.1899) 2703 0 R (HD.19) 625 0 R (HD.190) 817 0 R (HD.1900) 2704 0 R (HD.1901) 2705 0 R (HD.1902) 2706 0 R (HD.1903) 2707 0 R (HD.1904) 2708 0 R (HD.1905) 2709 0 R (HD.1906) 2710 0 R (HD.1907) 2711 0 R (HD.1908) 2712 0 R (HD.1909) 2713 0 R (HD.191) 818 0 R (HD.1910) 2714 0 R (HD.1911) 2715 0 R (HD.1912) 2716 0 R (HD.1913) 2717 0 R (HD.1914) 2718 0 R (HD.1915) 2719 0 R (HD.1916) 2720 0 R (HD.1917) 2721 0 R (HD.1918) 2722 0 R (HD.1919) 2723 0 R ] /Limits [ (HD.1891) (HD.1919) ] >>
+<< /Names [ (HD.1228) 1951 0 R (HD.1229) 1952 0 R (HD.123) 737 0 R (HD.1230) 1953 0 R (HD.1231) 1954 0 R (HD.1232) 1955 0 R (HD.1233) 1956 0 R (HD.1234) 1957 0 R (HD.1235) 1958 0 R (HD.1236) 1959 0 R (HD.1237) 1960 0 R (HD.1238) 1961 0 R (HD.1239) 1962 0 R (HD.124) 738 0 R (HD.1240) 1963 0 R (HD.1241) 1964 0 R (HD.1242) 1965 0 R (HD.1243) 1966 0 R (HD.1244) 1967 0 R (HD.1245) 1968 0 R (HD.1246) 1969 0 R (HD.1247) 1970 0 R (HD.1248) 1971 0 R (HD.1249) 1972 0 R (HD.125) 739 0 R (HD.1250) 1973 0 R (HD.1251) 1974 0 R (HD.1252) 1975 0 R (HD.1253) 1976 0 R (HD.1254) 1977 0 R (HD.1255) 1978 0 R (HD.1256) 1979 0 R ] /Limits [ (HD.1228) (HD.1256) ] >>
endobj
4397 0 obj
-<< /Names [ (HD.192) 819 0 R (HD.1920) 2724 0 R (HD.1921) 2725 0 R (HD.1922) 2732 0 R (HD.1923) 2733 0 R (HD.1924) 2734 0 R (HD.1925) 2735 0 R (HD.1926) 2736 0 R (HD.1927) 2737 0 R (HD.1928) 2738 0 R (HD.1929) 2739 0 R (HD.193) 820 0 R (HD.1930) 2741 0 R (HD.1931) 2743 0 R (HD.1932) 2744 0 R (HD.1933) 2745 0 R (HD.1934) 2746 0 R (HD.1935) 2747 0 R (HD.1936) 2748 0 R (HD.1937) 2749 0 R (HD.1938) 2750 0 R (HD.1939) 2751 0 R (HD.194) 821 0 R (HD.1940) 2752 0 R (HD.1941) 2753 0 R (HD.1942) 2754 0 R (HD.1943) 2755 0 R (HD.1944) 2756 0 R (HD.1945) 2757 0 R (HD.1946) 2758 0 R (HD.1947) 2759 0 R (HD.1948) 2760 0 R ] /Limits [ (HD.192) (HD.1948) ] >>
+<< /Names [ (HD.1257) 1980 0 R (HD.1258) 1981 0 R (HD.1259) 1982 0 R (HD.126) 740 0 R (HD.1260) 1983 0 R (HD.1261) 1984 0 R (HD.1262) 1985 0 R (HD.1263) 1990 0 R (HD.1264) 1991 0 R (HD.1265) 1992 0 R (HD.1266) 1993 0 R (HD.1267) 1994 0 R (HD.1268) 1995 0 R (HD.1269) 1996 0 R (HD.127) 741 0 R (HD.1270) 1997 0 R (HD.1271) 1998 0 R (HD.1272) 1999 0 R (HD.1273) 2000 0 R (HD.1274) 2001 0 R (HD.1275) 2002 0 R (HD.1276) 2003 0 R (HD.1277) 2004 0 R (HD.1278) 2005 0 R (HD.1279) 2006 0 R (HD.128) 742 0 R (HD.1280) 2007 0 R (HD.1281) 2008 0 R (HD.1282) 2009 0 R (HD.1283) 2010 0 R (HD.1284) 2011 0 R (HD.1285) 2012 0 R ] /Limits [ (HD.1257) (HD.1285) ] >>
endobj
4398 0 obj
-<< /Names [ (HD.1949) 2761 0 R (HD.195) 822 0 R (HD.1950) 2762 0 R (HD.1951) 2763 0 R (HD.1952) 2764 0 R (HD.1953) 2765 0 R (HD.1954) 2766 0 R (HD.1955) 2767 0 R (HD.1956) 2768 0 R (HD.1957) 2769 0 R (HD.1958) 2770 0 R (HD.1959) 2771 0 R (HD.196) 823 0 R (HD.1960) 2772 0 R (HD.1961) 2779 0 R (HD.1962) 2780 0 R (HD.1963) 2781 0 R (HD.1964) 2782 0 R (HD.1965) 2783 0 R (HD.1966) 2784 0 R (HD.1967) 2785 0 R (HD.1968) 2786 0 R (HD.1969) 2787 0 R (HD.197) 828 0 R (HD.1970) 2788 0 R (HD.1971) 2789 0 R (HD.1972) 2790 0 R (HD.1973) 2791 0 R (HD.1974) 2792 0 R (HD.1975) 2793 0 R (HD.1976) 2794 0 R (HD.1977) 2795 0 R ] /Limits [ (HD.1949) (HD.1977) ] >>
+<< /Names [ (HD.1286) 2013 0 R (HD.1287) 2014 0 R (HD.1288) 2015 0 R (HD.1289) 2016 0 R (HD.129) 743 0 R (HD.1290) 2017 0 R (HD.1291) 2018 0 R (HD.1292) 2019 0 R (HD.1293) 2020 0 R (HD.1294) 2021 0 R (HD.1295) 2022 0 R (HD.1296) 2023 0 R (HD.1297) 2024 0 R (HD.1298) 2025 0 R (HD.1299) 2026 0 R (HD.13) 619 0 R (HD.130) 744 0 R (HD.1300) 2027 0 R (HD.1301) 2028 0 R (HD.1302) 2029 0 R (HD.1303) 2030 0 R (HD.1304) 2031 0 R (HD.1305) 2032 0 R (HD.1306) 2033 0 R (HD.1307) 2034 0 R (HD.1308) 2035 0 R (HD.1309) 2036 0 R (HD.131) 745 0 R (HD.1310) 2037 0 R (HD.1311) 2038 0 R (HD.1312) 2043 0 R (HD.1313) 2044 0 R ] /Limits [ (HD.1286) (HD.1313) ] >>
endobj
4399 0 obj
-<< /Names [ (HD.1978) 2796 0 R (HD.1979) 2797 0 R (HD.198) 829 0 R (HD.1980) 2798 0 R (HD.1981) 2799 0 R (HD.1982) 2800 0 R (HD.1983) 2801 0 R (HD.1984) 2802 0 R (HD.1985) 2803 0 R (HD.1986) 2804 0 R (HD.1987) 2805 0 R (HD.1988) 2806 0 R (HD.1989) 2807 0 R (HD.199) 830 0 R (HD.1990) 2808 0 R (HD.1991) 2809 0 R (HD.1992) 2810 0 R (HD.1993) 2811 0 R (HD.1994) 2812 0 R (HD.1995) 2813 0 R (HD.1996) 2814 0 R (HD.1997) 2815 0 R (HD.1998) 2816 0 R (HD.1999) 2817 0 R (HD.2) 608 0 R (HD.20) 626 0 R (HD.200) 831 0 R (HD.2000) 2818 0 R (HD.2001) 2819 0 R (HD.2002) 2820 0 R (HD.2003) 2821 0 R (HD.2004) 2822 0 R ] /Limits [ (HD.1978) (HD.2004) ] >>
+<< /Names [ (HD.1314) 2045 0 R (HD.1315) 2046 0 R (HD.1316) 2047 0 R (HD.1317) 2048 0 R (HD.1318) 2049 0 R (HD.1319) 2050 0 R (HD.132) 746 0 R (HD.1320) 2051 0 R (HD.1321) 2052 0 R (HD.1322) 2053 0 R (HD.1323) 2054 0 R (HD.1324) 2055 0 R (HD.1325) 2056 0 R (HD.1326) 2057 0 R (HD.1327) 2058 0 R (HD.1328) 2059 0 R (HD.1329) 2060 0 R (HD.133) 747 0 R (HD.1330) 2061 0 R (HD.1331) 2062 0 R (HD.1332) 2063 0 R (HD.1333) 2064 0 R (HD.1334) 2065 0 R (HD.1335) 2066 0 R (HD.1336) 2067 0 R (HD.1337) 2068 0 R (HD.1338) 2069 0 R (HD.1339) 2070 0 R (HD.134) 748 0 R (HD.1340) 2071 0 R (HD.1341) 2072 0 R (HD.1342) 2073 0 R ] /Limits [ (HD.1314) (HD.1342) ] >>
endobj
4400 0 obj
-<< /Names [ (HD.2005) 2823 0 R (HD.2006) 2824 0 R (HD.2007) 2825 0 R (HD.2008) 2826 0 R (HD.2009) 2827 0 R (HD.201) 832 0 R (HD.2010) 2828 0 R (HD.2011) 2829 0 R (HD.2012) 2830 0 R (HD.2013) 2835 0 R (HD.2014) 2836 0 R (HD.2015) 2837 0 R (HD.2016) 2838 0 R (HD.2017) 2839 0 R (HD.2018) 2840 0 R (HD.2019) 2841 0 R (HD.202) 833 0 R (HD.2020) 2842 0 R (HD.2021) 2843 0 R (HD.2022) 2844 0 R (HD.2023) 2845 0 R (HD.2024) 2846 0 R (HD.2025) 2847 0 R (HD.2026) 2848 0 R (HD.2027) 2849 0 R (HD.2028) 2850 0 R (HD.2029) 2851 0 R (HD.203) 834 0 R (HD.2030) 2852 0 R (HD.2031) 2853 0 R (HD.2032) 2854 0 R (HD.2033) 2855 0 R ] /Limits [ (HD.2005) (HD.2033) ] >>
+<< /Names [ (HD.1343) 2074 0 R (HD.1344) 2075 0 R (HD.1345) 2076 0 R (HD.1346) 2077 0 R (HD.1347) 2078 0 R (HD.1348) 2079 0 R (HD.1349) 2080 0 R (HD.135) 754 0 R (HD.1350) 2081 0 R (HD.1351) 2082 0 R (HD.1352) 2083 0 R (HD.1353) 2084 0 R (HD.1354) 2085 0 R (HD.1355) 2086 0 R (HD.1356) 2087 0 R (HD.1357) 2088 0 R (HD.1358) 2089 0 R (HD.1359) 2090 0 R (HD.136) 755 0 R (HD.1360) 2091 0 R (HD.1361) 2092 0 R (HD.1362) 2093 0 R (HD.1363) 2094 0 R (HD.1364) 2095 0 R (HD.1365) 2096 0 R (HD.1366) 2097 0 R (HD.1367) 2098 0 R (HD.1368) 2099 0 R (HD.1369) 2100 0 R (HD.137) 756 0 R (HD.1370) 2101 0 R (HD.1371) 2102 0 R ] /Limits [ (HD.1343) (HD.1371) ] >>
endobj
4401 0 obj
-<< /Names [ (HD.2034) 2856 0 R (HD.2035) 2857 0 R (HD.2036) 2858 0 R (HD.2037) 2859 0 R (HD.2038) 2860 0 R (HD.2039) 2861 0 R (HD.204) 835 0 R (HD.2040) 2862 0 R (HD.2041) 2863 0 R (HD.2042) 2864 0 R (HD.2043) 2865 0 R (HD.2044) 2866 0 R (HD.2045) 2867 0 R (HD.2046) 2868 0 R (HD.2047) 2869 0 R (HD.2048) 2870 0 R (HD.2049) 2871 0 R (HD.205) 836 0 R (HD.2050) 2872 0 R (HD.2051) 2873 0 R (HD.2052) 2874 0 R (HD.2053) 2875 0 R (HD.2054) 2876 0 R (HD.2055) 2878 0 R (HD.2056) 2879 0 R (HD.2057) 2881 0 R (HD.2058) 2882 0 R (HD.2059) 2883 0 R (HD.206) 837 0 R (HD.2060) 2884 0 R (HD.2061) 2885 0 R (HD.2062) 2890 0 R ] /Limits [ (HD.2034) (HD.2062) ] >>
+<< /Names [ (HD.1372) 2107 0 R (HD.1373) 2108 0 R (HD.1374) 2109 0 R (HD.1375) 2110 0 R (HD.1376) 2111 0 R (HD.1377) 2112 0 R (HD.1378) 2113 0 R (HD.1379) 2114 0 R (HD.138) 757 0 R (HD.1380) 2115 0 R (HD.1381) 2116 0 R (HD.1382) 2117 0 R (HD.1383) 2118 0 R (HD.1384) 2119 0 R (HD.1385) 2120 0 R (HD.1386) 2121 0 R (HD.1387) 2122 0 R (HD.1388) 2123 0 R (HD.1389) 2124 0 R (HD.139) 758 0 R (HD.1390) 2125 0 R (HD.1391) 2126 0 R (HD.1392) 2127 0 R (HD.1393) 2128 0 R (HD.1394) 2129 0 R (HD.1395) 2130 0 R (HD.1396) 2131 0 R (HD.1397) 2132 0 R (HD.1398) 2133 0 R (HD.1399) 2134 0 R (HD.14) 620 0 R (HD.140) 759 0 R ] /Limits [ (HD.1372) (HD.140) ] >>
endobj
4402 0 obj
-<< /Names [ (HD.2063) 2892 0 R (HD.2064) 2893 0 R (HD.2065) 2894 0 R (HD.2066) 2895 0 R (HD.2067) 2896 0 R (HD.2068) 2897 0 R (HD.2069) 2898 0 R (HD.207) 838 0 R (HD.2070) 2899 0 R (HD.2071) 2900 0 R (HD.2072) 2901 0 R (HD.2073) 2902 0 R (HD.2074) 2903 0 R (HD.2075) 2904 0 R (HD.2076) 2905 0 R (HD.2077) 2906 0 R (HD.2078) 2907 0 R (HD.2079) 2908 0 R (HD.208) 839 0 R (HD.2080) 2909 0 R (HD.2081) 2910 0 R (HD.2082) 2911 0 R (HD.2083) 2912 0 R (HD.2084) 2913 0 R (HD.2085) 2914 0 R (HD.2086) 2915 0 R (HD.2087) 2916 0 R (HD.2088) 2917 0 R (HD.2089) 2918 0 R (HD.209) 840 0 R (HD.2090) 2919 0 R (HD.2091) 2920 0 R ] /Limits [ (HD.2063) (HD.2091) ] >>
+<< /Names [ (HD.1400) 2135 0 R (HD.1401) 2136 0 R (HD.1402) 2137 0 R (HD.1403) 2138 0 R (HD.1404) 2139 0 R (HD.1405) 2140 0 R (HD.1406) 2141 0 R (HD.1407) 2142 0 R (HD.1408) 2143 0 R (HD.1409) 2144 0 R (HD.141) 760 0 R (HD.1410) 2145 0 R (HD.1411) 2146 0 R (HD.1412) 2147 0 R (HD.1413) 2148 0 R (HD.1414) 2149 0 R (HD.1415) 2150 0 R (HD.1416) 2151 0 R (HD.1417) 2152 0 R (HD.1418) 2153 0 R (HD.1419) 2154 0 R (HD.142) 761 0 R (HD.1420) 2155 0 R (HD.1421) 2156 0 R (HD.1422) 2157 0 R (HD.1423) 2158 0 R (HD.1424) 2159 0 R (HD.1425) 2160 0 R (HD.1426) 2161 0 R (HD.1427) 2162 0 R (HD.1428) 2163 0 R (HD.1429) 2164 0 R ] /Limits [ (HD.1400) (HD.1429) ] >>
endobj
4403 0 obj
-<< /Names [ (HD.2092) 2922 0 R (HD.2093) 2923 0 R (HD.2094) 2924 0 R (HD.2095) 2925 0 R (HD.2096) 2926 0 R (HD.2097) 2927 0 R (HD.2098) 2928 0 R (HD.2099) 2933 0 R (HD.21) 627 0 R (HD.210) 841 0 R (HD.2100) 2934 0 R (HD.2101) 2935 0 R (HD.2102) 2936 0 R (HD.2103) 2937 0 R (HD.2104) 2938 0 R (HD.2105) 2940 0 R (HD.2106) 2941 0 R (HD.2107) 2942 0 R (HD.2108) 2943 0 R (HD.2109) 2944 0 R (HD.211) 842 0 R (HD.2110) 2945 0 R (HD.2111) 2946 0 R (HD.2112) 2947 0 R (HD.2113) 2948 0 R (HD.2114) 2949 0 R (HD.2115) 2950 0 R (HD.2116) 2951 0 R (HD.2117) 2952 0 R (HD.2118) 2953 0 R (HD.2119) 2954 0 R (HD.212) 843 0 R ] /Limits [ (HD.2092) (HD.212) ] >>
+<< /Names [ (HD.143) 762 0 R (HD.1430) 2165 0 R (HD.1431) 2170 0 R (HD.1432) 2171 0 R (HD.1433) 2172 0 R (HD.1434) 2173 0 R (HD.1435) 2174 0 R (HD.1436) 2175 0 R (HD.1437) 2176 0 R (HD.1438) 2177 0 R (HD.1439) 2178 0 R (HD.144) 763 0 R (HD.1440) 2179 0 R (HD.1441) 2180 0 R (HD.1442) 2181 0 R (HD.1443) 2182 0 R (HD.1444) 2183 0 R (HD.1445) 2184 0 R (HD.1446) 2185 0 R (HD.1447) 2186 0 R (HD.1448) 2187 0 R (HD.1449) 2188 0 R (HD.145) 764 0 R (HD.1450) 2189 0 R (HD.1451) 2190 0 R (HD.1452) 2191 0 R (HD.1453) 2192 0 R (HD.1454) 2193 0 R (HD.1455) 2194 0 R (HD.1456) 2195 0 R (HD.1457) 2196 0 R (HD.1458) 2197 0 R ] /Limits [ (HD.143) (HD.1458) ] >>
endobj
4404 0 obj
-<< /Names [ (HD.2120) 2955 0 R (HD.2121) 2956 0 R (HD.2122) 2957 0 R (HD.2123) 2958 0 R (HD.2124) 2959 0 R (HD.2125) 2960 0 R (HD.2126) 2961 0 R (HD.2127) 2962 0 R (HD.2128) 2963 0 R (HD.2129) 2964 0 R (HD.213) 844 0 R (HD.2130) 2965 0 R (HD.2131) 2966 0 R (HD.2132) 2967 0 R (HD.2133) 2968 0 R (HD.2134) 2970 0 R (HD.2135) 2971 0 R (HD.2136) 2972 0 R (HD.2137) 2973 0 R (HD.2138) 2974 0 R (HD.2139) 2975 0 R (HD.214) 845 0 R (HD.2140) 2976 0 R (HD.2141) 2977 0 R (HD.2142) 2978 0 R (HD.2143) 2979 0 R (HD.2144) 2980 0 R (HD.2145) 2981 0 R (HD.2146) 2982 0 R (HD.2147) 2983 0 R (HD.2148) 2984 0 R (HD.2149) 2985 0 R ] /Limits [ (HD.2120) (HD.2149) ] >>
+<< /Names [ (HD.1459) 2198 0 R (HD.146) 765 0 R (HD.1460) 2199 0 R (HD.1461) 2200 0 R (HD.1462) 2201 0 R (HD.1463) 2202 0 R (HD.1464) 2203 0 R (HD.1465) 2204 0 R (HD.1466) 2205 0 R (HD.1467) 2206 0 R (HD.1468) 2207 0 R (HD.1469) 2209 0 R (HD.147) 766 0 R (HD.1470) 2210 0 R (HD.1471) 2211 0 R (HD.1472) 2212 0 R (HD.1473) 2213 0 R (HD.1474) 2214 0 R (HD.1475) 2219 0 R (HD.1476) 2220 0 R (HD.1477) 2221 0 R (HD.1478) 2222 0 R (HD.1479) 2223 0 R (HD.148) 767 0 R (HD.1480) 2224 0 R (HD.1481) 2225 0 R (HD.1482) 2226 0 R (HD.1483) 2227 0 R (HD.1484) 2228 0 R (HD.1485) 2229 0 R (HD.1486) 2230 0 R (HD.1487) 2231 0 R ] /Limits [ (HD.1459) (HD.1487) ] >>
endobj
4405 0 obj
-<< /Names [ (HD.215) 846 0 R (HD.2150) 2986 0 R (HD.2151) 2992 0 R (HD.2152) 2993 0 R (HD.2153) 2994 0 R (HD.2154) 2995 0 R (HD.2155) 2996 0 R (HD.2156) 2997 0 R (HD.2157) 2998 0 R (HD.2158) 2999 0 R (HD.2159) 3000 0 R (HD.216) 847 0 R (HD.2160) 3001 0 R (HD.2161) 3002 0 R (HD.2162) 3003 0 R (HD.2163) 3004 0 R (HD.2164) 3005 0 R (HD.2165) 3006 0 R (HD.2166) 3007 0 R (HD.2167) 3008 0 R (HD.2168) 3009 0 R (HD.2169) 3010 0 R (HD.217) 848 0 R (HD.2170) 3011 0 R (HD.2171) 3012 0 R (HD.2172) 3013 0 R (HD.2173) 3014 0 R (HD.2174) 3015 0 R (HD.2175) 3017 0 R (HD.2176) 3019 0 R (HD.2177) 3020 0 R (HD.2178) 3021 0 R ] /Limits [ (HD.215) (HD.2178) ] >>
+<< /Names [ (HD.1488) 2232 0 R (HD.1489) 2233 0 R (HD.149) 768 0 R (HD.1490) 2234 0 R (HD.1491) 2235 0 R (HD.1492) 2236 0 R (HD.1493) 2237 0 R (HD.1494) 2238 0 R (HD.1495) 2239 0 R (HD.1496) 2240 0 R (HD.1497) 2241 0 R (HD.1498) 2242 0 R (HD.1499) 2243 0 R (HD.15) 621 0 R (HD.150) 769 0 R (HD.1500) 2244 0 R (HD.1501) 2245 0 R (HD.1502) 2246 0 R (HD.1503) 2247 0 R (HD.1504) 2248 0 R (HD.1505) 2249 0 R (HD.1506) 2250 0 R (HD.1507) 2251 0 R (HD.1508) 2252 0 R (HD.1509) 2258 0 R (HD.151) 770 0 R (HD.1510) 2259 0 R (HD.1511) 2260 0 R (HD.1512) 2261 0 R (HD.1513) 2262 0 R (HD.1514) 2263 0 R (HD.1515) 2264 0 R ] /Limits [ (HD.1488) (HD.1515) ] >>
endobj
4406 0 obj
-<< /Names [ (HD.2179) 3022 0 R (HD.218) 849 0 R (HD.2180) 3023 0 R (HD.2181) 3024 0 R (HD.2182) 3025 0 R (HD.2183) 3026 0 R (HD.2184) 3027 0 R (HD.2185) 3028 0 R (HD.2186) 3029 0 R (HD.2187) 3030 0 R (HD.2188) 3031 0 R (HD.2189) 3032 0 R (HD.219) 850 0 R (HD.2190) 3033 0 R (HD.2191) 3034 0 R (HD.2192) 3035 0 R (HD.2193) 3036 0 R (HD.2194) 3037 0 R (HD.2195) 3038 0 R (HD.2196) 3039 0 R (HD.2197) 3040 0 R (HD.2198) 3041 0 R (HD.2199) 3042 0 R (HD.22) 628 0 R (HD.220) 851 0 R (HD.2200) 3043 0 R (HD.2201) 3044 0 R (HD.2202) 3045 0 R (HD.2203) 3046 0 R (HD.2204) 3047 0 R (HD.2205) 3052 0 R (HD.2206) 3053 0 R ] /Limits [ (HD.2179) (HD.2206) ] >>
+<< /Names [ (HD.1516) 2265 0 R (HD.1517) 2266 0 R (HD.1518) 2267 0 R (HD.1519) 2268 0 R (HD.152) 771 0 R (HD.1520) 2269 0 R (HD.1521) 2270 0 R (HD.1522) 2271 0 R (HD.1523) 2272 0 R (HD.1524) 2273 0 R (HD.1525) 2274 0 R (HD.1526) 2275 0 R (HD.1527) 2276 0 R (HD.1528) 2277 0 R (HD.1529) 2278 0 R (HD.153) 772 0 R (HD.1530) 2279 0 R (HD.1531) 2280 0 R (HD.1532) 2281 0 R (HD.1533) 2282 0 R (HD.1534) 2283 0 R (HD.1535) 2284 0 R (HD.1536) 2285 0 R (HD.1537) 2286 0 R (HD.1538) 2287 0 R (HD.1539) 2289 0 R (HD.154) 773 0 R (HD.1540) 2290 0 R (HD.1541) 2291 0 R (HD.1542) 2292 0 R (HD.1543) 2293 0 R (HD.1544) 2294 0 R ] /Limits [ (HD.1516) (HD.1544) ] >>
endobj
4407 0 obj
-<< /Names [ (HD.2207) 3054 0 R (HD.2208) 3055 0 R (HD.2209) 3056 0 R (HD.221) 852 0 R (HD.2210) 3057 0 R (HD.2211) 3058 0 R (HD.2212) 3059 0 R (HD.2213) 3060 0 R (HD.2214) 3061 0 R (HD.2215) 3062 0 R (HD.2216) 3063 0 R (HD.2217) 3064 0 R (HD.2218) 3065 0 R (HD.2219) 3066 0 R (HD.222) 853 0 R (HD.2220) 3067 0 R (HD.2221) 3068 0 R (HD.2222) 3069 0 R (HD.2223) 3070 0 R (HD.2224) 3071 0 R (HD.2225) 3072 0 R (HD.2226) 3073 0 R (HD.2227) 3074 0 R (HD.2228) 3075 0 R (HD.2229) 3076 0 R (HD.223) 854 0 R (HD.2230) 3077 0 R (HD.2231) 3078 0 R (HD.2232) 3079 0 R (HD.2233) 3080 0 R (HD.2234) 3081 0 R (HD.2235) 3082 0 R ] /Limits [ (HD.2207) (HD.2235) ] >>
+<< /Names [ (HD.1545) 2295 0 R (HD.1546) 2296 0 R (HD.1547) 2301 0 R (HD.1548) 2302 0 R (HD.1549) 2303 0 R (HD.155) 774 0 R (HD.1550) 2304 0 R (HD.1551) 2305 0 R (HD.1552) 2306 0 R (HD.1553) 2307 0 R (HD.1554) 2308 0 R (HD.1555) 2309 0 R (HD.1556) 2310 0 R (HD.1557) 2311 0 R (HD.1558) 2312 0 R (HD.1559) 2313 0 R (HD.156) 775 0 R (HD.1560) 2314 0 R (HD.1561) 2315 0 R (HD.1562) 2316 0 R (HD.1563) 2317 0 R (HD.1564) 2318 0 R (HD.1565) 2319 0 R (HD.1566) 2320 0 R (HD.1567) 2321 0 R (HD.1568) 2322 0 R (HD.1569) 2323 0 R (HD.157) 776 0 R (HD.1570) 2324 0 R (HD.1571) 2325 0 R (HD.1572) 2326 0 R (HD.1573) 2332 0 R ] /Limits [ (HD.1545) (HD.1573) ] >>
endobj
4408 0 obj
-<< /Names [ (HD.2236) 3083 0 R (HD.2237) 3084 0 R (HD.2238) 3085 0 R (HD.2239) 3086 0 R (HD.224) 855 0 R (HD.2240) 3087 0 R (HD.2241) 3088 0 R (HD.2242) 3089 0 R (HD.2243) 3090 0 R (HD.2244) 3091 0 R (HD.2245) 3092 0 R (HD.2246) 3093 0 R (HD.2247) 3094 0 R (HD.2248) 3095 0 R (HD.2249) 3096 0 R (HD.225) 856 0 R (HD.2250) 3097 0 R (HD.2251) 3098 0 R (HD.2252) 3105 0 R (HD.2253) 3106 0 R (HD.2254) 3108 0 R (HD.2255) 3109 0 R (HD.2256) 3110 0 R (HD.2257) 3111 0 R (HD.2258) 3112 0 R (HD.2259) 3113 0 R (HD.226) 857 0 R (HD.2260) 3114 0 R (HD.2261) 3115 0 R (HD.2262) 3116 0 R (HD.2263) 3117 0 R (HD.2264) 3118 0 R ] /Limits [ (HD.2236) (HD.2264) ] >>
+<< /Names [ (HD.1574) 2333 0 R (HD.1575) 2334 0 R (HD.1576) 2335 0 R (HD.1577) 2336 0 R (HD.1578) 2337 0 R (HD.1579) 2338 0 R (HD.158) 777 0 R (HD.1580) 2339 0 R (HD.1581) 2340 0 R (HD.1582) 2341 0 R (HD.1583) 2342 0 R (HD.1584) 2343 0 R (HD.1585) 2344 0 R (HD.1586) 2345 0 R (HD.1587) 2346 0 R (HD.1588) 2347 0 R (HD.1589) 2348 0 R (HD.159) 782 0 R (HD.1590) 2349 0 R (HD.1591) 2350 0 R (HD.1592) 2351 0 R (HD.1593) 2352 0 R (HD.1594) 2353 0 R (HD.1595) 2354 0 R (HD.1596) 2355 0 R (HD.1597) 2356 0 R (HD.1598) 2357 0 R (HD.1599) 2358 0 R (HD.16) 622 0 R (HD.160) 783 0 R (HD.1600) 2359 0 R (HD.1601) 2360 0 R ] /Limits [ (HD.1574) (HD.1601) ] >>
endobj
4409 0 obj
-<< /Names [ (HD.2265) 3120 0 R (HD.2266) 3121 0 R (HD.2267) 3122 0 R (HD.2268) 3123 0 R (HD.2269) 3125 0 R (HD.227) 858 0 R (HD.2270) 3127 0 R (HD.2271) 3128 0 R (HD.2272) 3129 0 R (HD.2273) 3130 0 R (HD.2274) 3131 0 R (HD.2275) 3132 0 R (HD.2276) 3133 0 R (HD.2277) 3134 0 R (HD.2278) 3135 0 R (HD.2279) 3136 0 R (HD.228) 859 0 R (HD.2280) 3137 0 R (HD.2281) 3144 0 R (HD.2282) 3145 0 R (HD.2283) 3146 0 R (HD.2284) 3147 0 R (HD.2285) 3148 0 R (HD.2286) 3149 0 R (HD.2287) 3150 0 R (HD.2288) 3151 0 R (HD.2289) 3152 0 R (HD.229) 860 0 R (HD.2290) 3153 0 R (HD.2291) 3154 0 R (HD.2292) 3155 0 R (HD.2293) 3156 0 R ] /Limits [ (HD.2265) (HD.2293) ] >>
+<< /Names [ (HD.1602) 2361 0 R (HD.1603) 2362 0 R (HD.1604) 2363 0 R (HD.1605) 2364 0 R (HD.1606) 2365 0 R (HD.1607) 2367 0 R (HD.1608) 2368 0 R (HD.1609) 2369 0 R (HD.161) 784 0 R (HD.1610) 2370 0 R (HD.1611) 2371 0 R (HD.1612) 2372 0 R (HD.1613) 2377 0 R (HD.1614) 2378 0 R (HD.1615) 2379 0 R (HD.1616) 2380 0 R (HD.1617) 2381 0 R (HD.1618) 2382 0 R (HD.1619) 2383 0 R (HD.162) 785 0 R (HD.1620) 2384 0 R (HD.1621) 2385 0 R (HD.1622) 2386 0 R (HD.1623) 2387 0 R (HD.1624) 2388 0 R (HD.1625) 2389 0 R (HD.1626) 2390 0 R (HD.1627) 2391 0 R (HD.1628) 2392 0 R (HD.1629) 2393 0 R (HD.163) 786 0 R (HD.1630) 2394 0 R ] /Limits [ (HD.1602) (HD.1630) ] >>
endobj
4410 0 obj
-<< /Names [ (HD.2294) 3157 0 R (HD.2295) 3158 0 R (HD.2296) 3159 0 R (HD.2297) 3160 0 R (HD.2298) 3161 0 R (HD.2299) 3162 0 R (HD.23) 629 0 R (HD.230) 861 0 R (HD.2300) 3163 0 R (HD.2301) 3164 0 R (HD.2302) 3165 0 R (HD.2303) 3166 0 R (HD.2304) 3167 0 R (HD.2305) 3168 0 R (HD.2306) 3169 0 R (HD.2307) 3170 0 R (HD.2308) 3171 0 R (HD.2309) 3172 0 R (HD.231) 862 0 R (HD.2310) 3173 0 R (HD.2311) 3174 0 R (HD.2312) 3175 0 R (HD.2313) 3176 0 R (HD.2314) 3177 0 R (HD.2315) 3178 0 R (HD.2316) 3179 0 R (HD.2317) 3180 0 R (HD.2318) 3181 0 R (HD.2319) 3182 0 R (HD.232) 863 0 R (HD.2320) 3183 0 R (HD.2321) 3184 0 R ] /Limits [ (HD.2294) (HD.2321) ] >>
+<< /Names [ (HD.1631) 2395 0 R (HD.1632) 2396 0 R (HD.1633) 2397 0 R (HD.1634) 2398 0 R (HD.1635) 2399 0 R (HD.1636) 2400 0 R (HD.1637) 2401 0 R (HD.1638) 2402 0 R (HD.1639) 2403 0 R (HD.164) 787 0 R (HD.1640) 2404 0 R (HD.1641) 2405 0 R (HD.1642) 2406 0 R (HD.1643) 2407 0 R (HD.1644) 2408 0 R (HD.1645) 2409 0 R (HD.1646) 2410 0 R (HD.1647) 2411 0 R (HD.1648) 2412 0 R (HD.1649) 2413 0 R (HD.165) 788 0 R (HD.1650) 2414 0 R (HD.1651) 2415 0 R (HD.1652) 2416 0 R (HD.1653) 2417 0 R (HD.1654) 2418 0 R (HD.1655) 2419 0 R (HD.1656) 2420 0 R (HD.1657) 2421 0 R (HD.1658) 2422 0 R (HD.1659) 2428 0 R (HD.166) 789 0 R ] /Limits [ (HD.1631) (HD.166) ] >>
endobj
4411 0 obj
-<< /Names [ (HD.2322) 3185 0 R (HD.2323) 3186 0 R (HD.2324) 3187 0 R (HD.2325) 3188 0 R (HD.2326) 3189 0 R (HD.2327) 3196 0 R (HD.2328) 3197 0 R (HD.2329) 3198 0 R (HD.233) 864 0 R (HD.2330) 3199 0 R (HD.2331) 3200 0 R (HD.2332) 3201 0 R (HD.2333) 3202 0 R (HD.2334) 3203 0 R (HD.2335) 3204 0 R (HD.2336) 3205 0 R (HD.2337) 3206 0 R (HD.2338) 3207 0 R (HD.2339) 3208 0 R (HD.234) 865 0 R (HD.2340) 3209 0 R (HD.2341) 3210 0 R (HD.2342) 3211 0 R (HD.2343) 3212 0 R (HD.2344) 3213 0 R (HD.2345) 3214 0 R (HD.2346) 3215 0 R (HD.2347) 3216 0 R (HD.2348) 3217 0 R (HD.2349) 3218 0 R (HD.235) 870 0 R (HD.2350) 3219 0 R ] /Limits [ (HD.2322) (HD.2350) ] >>
+<< /Names [ (HD.1660) 2429 0 R (HD.1661) 2430 0 R (HD.1662) 2431 0 R (HD.1663) 2432 0 R (HD.1664) 2433 0 R (HD.1665) 2434 0 R (HD.1666) 2435 0 R (HD.1667) 2436 0 R (HD.1668) 2437 0 R (HD.1669) 2438 0 R (HD.167) 790 0 R (HD.1670) 2439 0 R (HD.1671) 2440 0 R (HD.1672) 2441 0 R (HD.1673) 2442 0 R (HD.1674) 2443 0 R (HD.1675) 2444 0 R (HD.1676) 2445 0 R (HD.1677) 2446 0 R (HD.1678) 2447 0 R (HD.1679) 2449 0 R (HD.168) 791 0 R (HD.1680) 2450 0 R (HD.1681) 2451 0 R (HD.1682) 2452 0 R (HD.1683) 2453 0 R (HD.1684) 2454 0 R (HD.1685) 2455 0 R (HD.1686) 2456 0 R (HD.1687) 2457 0 R (HD.1688) 2458 0 R (HD.1689) 2459 0 R ] /Limits [ (HD.1660) (HD.1689) ] >>
endobj
4412 0 obj
-<< /Names [ (HD.2351) 3220 0 R (HD.2352) 3221 0 R (HD.2353) 3222 0 R (HD.2354) 3223 0 R (HD.2355) 3224 0 R (HD.2356) 3225 0 R (HD.2357) 3226 0 R (HD.2358) 3227 0 R (HD.2359) 3228 0 R (HD.236) 871 0 R (HD.2360) 3229 0 R (HD.2361) 3230 0 R (HD.2362) 3231 0 R (HD.2363) 3232 0 R (HD.2364) 3233 0 R (HD.2365) 3234 0 R (HD.2366) 3235 0 R (HD.2367) 3236 0 R (HD.2368) 3237 0 R (HD.2369) 3238 0 R (HD.237) 872 0 R (HD.2370) 3239 0 R (HD.2371) 3240 0 R (HD.2372) 3241 0 R (HD.2373) 3243 0 R (HD.2374) 3250 0 R (HD.2375) 3251 0 R (HD.2376) 3252 0 R (HD.2377) 3253 0 R (HD.2378) 3255 0 R (HD.2379) 3256 0 R (HD.238) 873 0 R ] /Limits [ (HD.2351) (HD.238) ] >>
+<< /Names [ (HD.169) 792 0 R (HD.1690) 2460 0 R (HD.1691) 2461 0 R (HD.1692) 2468 0 R (HD.1693) 2469 0 R (HD.1694) 2470 0 R (HD.1695) 2471 0 R (HD.1696) 2472 0 R (HD.1697) 2473 0 R (HD.1698) 2474 0 R (HD.1699) 2475 0 R (HD.17) 623 0 R (HD.170) 793 0 R (HD.1700) 2476 0 R (HD.1701) 2477 0 R (HD.1702) 2478 0 R (HD.1703) 2479 0 R (HD.1704) 2480 0 R (HD.1705) 2481 0 R (HD.1706) 2482 0 R (HD.1707) 2483 0 R (HD.1708) 2484 0 R (HD.1709) 2485 0 R (HD.171) 794 0 R (HD.1710) 2486 0 R (HD.1711) 2487 0 R (HD.1712) 2488 0 R (HD.1713) 2489 0 R (HD.1714) 2490 0 R (HD.1715) 2491 0 R (HD.1716) 2492 0 R (HD.1717) 2493 0 R ] /Limits [ (HD.169) (HD.1717) ] >>
endobj
4413 0 obj
-<< /Names [ (HD.2380) 3257 0 R (HD.2381) 3258 0 R (HD.2382) 3259 0 R (HD.2383) 3260 0 R (HD.2384) 3261 0 R (HD.2385) 3262 0 R (HD.2386) 3263 0 R (HD.2387) 3264 0 R (HD.2388) 3265 0 R (HD.2389) 3266 0 R (HD.239) 874 0 R (HD.2390) 3268 0 R (HD.2391) 3269 0 R (HD.2392) 3270 0 R (HD.2393) 3271 0 R (HD.2394) 3272 0 R (HD.2395) 3273 0 R (HD.2396) 3274 0 R (HD.2397) 3275 0 R (HD.2398) 3276 0 R (HD.2399) 3277 0 R (HD.24) 630 0 R (HD.240) 875 0 R (HD.2400) 3278 0 R (HD.2401) 3279 0 R (HD.2402) 3280 0 R (HD.2403) 3281 0 R (HD.2404) 3282 0 R (HD.2405) 3283 0 R (HD.2406) 3284 0 R (HD.2407) 3285 0 R (HD.2408) 3286 0 R ] /Limits [ (HD.2380) (HD.2408) ] >>
+<< /Names [ (HD.1718) 2494 0 R (HD.1719) 2495 0 R (HD.172) 795 0 R (HD.1720) 2496 0 R (HD.1721) 2497 0 R (HD.1722) 2498 0 R (HD.1723) 2499 0 R (HD.1724) 2500 0 R (HD.1725) 2501 0 R (HD.1726) 2502 0 R (HD.1727) 2503 0 R (HD.1728) 2504 0 R (HD.1729) 2505 0 R (HD.173) 796 0 R (HD.1730) 2506 0 R (HD.1731) 2507 0 R (HD.1732) 2508 0 R (HD.1733) 2509 0 R (HD.1734) 2510 0 R (HD.1735) 2511 0 R (HD.1736) 2512 0 R (HD.1737) 2513 0 R (HD.1738) 2514 0 R (HD.1739) 2515 0 R (HD.174) 797 0 R (HD.1740) 2516 0 R (HD.1741) 2517 0 R (HD.1742) 2518 0 R (HD.1743) 2523 0 R (HD.1744) 2524 0 R (HD.1745) 2525 0 R (HD.1746) 2526 0 R ] /Limits [ (HD.1718) (HD.1746) ] >>
endobj
4414 0 obj
-<< /Names [ (HD.2409) 3287 0 R (HD.241) 876 0 R (HD.2410) 3288 0 R (HD.2411) 3289 0 R (HD.2412) 3290 0 R (HD.2413) 3291 0 R (HD.2414) 3292 0 R (HD.2415) 3293 0 R (HD.2416) 3294 0 R (HD.2417) 3295 0 R (HD.2418) 3296 0 R (HD.2419) 3297 0 R (HD.242) 877 0 R (HD.2420) 3298 0 R (HD.2421) 3299 0 R (HD.2422) 3300 0 R (HD.2423) 3301 0 R (HD.2424) 3302 0 R (HD.2425) 3303 0 R (HD.2426) 3309 0 R (HD.2427) 3310 0 R (HD.2428) 3311 0 R (HD.2429) 3312 0 R (HD.243) 878 0 R (HD.2430) 3313 0 R (HD.2431) 3314 0 R (HD.2432) 3315 0 R (HD.2433) 3316 0 R (HD.2434) 3317 0 R (HD.2435) 3318 0 R (HD.2436) 3319 0 R (HD.2437) 3320 0 R ] /Limits [ (HD.2409) (HD.2437) ] >>
+<< /Names [ (HD.1747) 2527 0 R (HD.1748) 2528 0 R (HD.1749) 2529 0 R (HD.175) 798 0 R (HD.1750) 2530 0 R (HD.1751) 2531 0 R (HD.1752) 2532 0 R (HD.1753) 2533 0 R (HD.1754) 2534 0 R (HD.1755) 2535 0 R (HD.1756) 2536 0 R (HD.1757) 2537 0 R (HD.1758) 2538 0 R (HD.1759) 2539 0 R (HD.176) 799 0 R (HD.1760) 2540 0 R (HD.1761) 2541 0 R (HD.1762) 2542 0 R (HD.1763) 2543 0 R (HD.1764) 2544 0 R (HD.1765) 2545 0 R (HD.1766) 2546 0 R (HD.1767) 2547 0 R (HD.1768) 2548 0 R (HD.1769) 2549 0 R (HD.177) 800 0 R (HD.1770) 2550 0 R (HD.1771) 2551 0 R (HD.1772) 2552 0 R (HD.1773) 2553 0 R (HD.1774) 2554 0 R (HD.1775) 2555 0 R ] /Limits [ (HD.1747) (HD.1775) ] >>
endobj
4415 0 obj
-<< /Names [ (HD.2438) 3321 0 R (HD.2439) 3322 0 R (HD.244) 879 0 R (HD.2440) 3323 0 R (HD.2441) 3324 0 R (HD.2442) 3325 0 R (HD.2443) 3326 0 R (HD.2444) 3327 0 R (HD.2445) 3328 0 R (HD.2446) 3329 0 R (HD.2447) 3330 0 R (HD.2448) 3331 0 R (HD.2449) 3332 0 R (HD.245) 880 0 R (HD.2450) 3333 0 R (HD.2451) 3334 0 R (HD.2452) 3335 0 R (HD.2453) 3336 0 R (HD.2454) 3337 0 R (HD.2455) 3338 0 R (HD.2456) 3339 0 R (HD.2457) 3340 0 R (HD.2458) 3341 0 R (HD.2459) 3342 0 R (HD.246) 881 0 R (HD.2460) 3343 0 R (HD.2461) 3344 0 R (HD.2462) 3345 0 R (HD.2463) 3346 0 R (HD.2464) 3347 0 R (HD.2465) 3348 0 R (HD.2466) 3349 0 R ] /Limits [ (HD.2438) (HD.2466) ] >>
+<< /Names [ (HD.1776) 2556 0 R (HD.1777) 2557 0 R (HD.1778) 2564 0 R (HD.1779) 2565 0 R (HD.178) 801 0 R (HD.1780) 2566 0 R (HD.1781) 2567 0 R (HD.1782) 2569 0 R (HD.1783) 2570 0 R (HD.1784) 2571 0 R (HD.1785) 2572 0 R (HD.1786) 2573 0 R (HD.1787) 2574 0 R (HD.1788) 2575 0 R (HD.1789) 2576 0 R (HD.179) 802 0 R (HD.1790) 2577 0 R (HD.1791) 2578 0 R (HD.1792) 2579 0 R (HD.1793) 2580 0 R (HD.1794) 2581 0 R (HD.1795) 2582 0 R (HD.1796) 2583 0 R (HD.1797) 2584 0 R (HD.1798) 2585 0 R (HD.1799) 2586 0 R (HD.18) 624 0 R (HD.180) 807 0 R (HD.1800) 2587 0 R (HD.1801) 2588 0 R (HD.1802) 2589 0 R (HD.1803) 2590 0 R ] /Limits [ (HD.1776) (HD.1803) ] >>
endobj
4416 0 obj
-<< /Names [ (HD.2467) 3350 0 R (HD.2468) 3351 0 R (HD.2469) 3352 0 R (HD.247) 882 0 R (HD.2470) 3353 0 R (HD.2471) 3354 0 R (HD.2472) 3355 0 R (HD.2473) 3356 0 R (HD.2474) 3357 0 R (HD.2475) 3358 0 R (HD.2476) 3365 0 R (HD.2477) 3366 0 R (HD.2478) 3367 0 R (HD.2479) 3368 0 R (HD.248) 883 0 R (HD.2480) 3369 0 R (HD.2481) 3370 0 R (HD.2482) 3371 0 R (HD.2483) 3372 0 R (HD.2484) 3373 0 R (HD.2485) 3374 0 R (HD.2486) 3375 0 R (HD.2487) 3376 0 R (HD.2488) 3377 0 R (HD.2489) 3378 0 R (HD.249) 884 0 R (HD.2490) 3379 0 R (HD.2491) 3380 0 R (HD.2492) 3381 0 R (HD.2493) 3382 0 R (HD.2494) 3383 0 R (HD.2495) 3384 0 R ] /Limits [ (HD.2467) (HD.2495) ] >>
+<< /Names [ (HD.1804) 2591 0 R (HD.1805) 2592 0 R (HD.1806) 2593 0 R (HD.1807) 2601 0 R (HD.1808) 2602 0 R (HD.1809) 2603 0 R (HD.181) 808 0 R (HD.1810) 2604 0 R (HD.1811) 2605 0 R (HD.1812) 2606 0 R (HD.1813) 2607 0 R (HD.1814) 2608 0 R (HD.1815) 2609 0 R (HD.1816) 2610 0 R (HD.1817) 2611 0 R (HD.1818) 2612 0 R (HD.1819) 2613 0 R (HD.182) 809 0 R (HD.1820) 2614 0 R (HD.1821) 2615 0 R (HD.1822) 2616 0 R (HD.1823) 2617 0 R (HD.1824) 2618 0 R (HD.1825) 2619 0 R (HD.1826) 2620 0 R (HD.1827) 2621 0 R (HD.1828) 2622 0 R (HD.1829) 2623 0 R (HD.183) 810 0 R (HD.1830) 2624 0 R (HD.1831) 2625 0 R (HD.1832) 2626 0 R ] /Limits [ (HD.1804) (HD.1832) ] >>
endobj
4417 0 obj
-<< /Names [ (HD.2496) 3385 0 R (HD.2497) 3386 0 R (HD.2498) 3387 0 R (HD.2499) 3388 0 R (HD.25) 631 0 R (HD.250) 885 0 R (HD.2500) 3389 0 R (HD.2501) 3390 0 R (HD.2502) 3391 0 R (HD.2503) 3392 0 R (HD.2504) 3393 0 R (HD.2505) 3394 0 R (HD.2506) 3395 0 R (HD.2507) 3396 0 R (HD.2508) 3397 0 R (HD.2509) 3398 0 R (HD.251) 886 0 R (HD.2510) 3399 0 R (HD.2511) 3400 0 R (HD.2512) 3401 0 R (HD.2513) 3402 0 R (HD.2514) 3403 0 R (HD.2515) 3404 0 R (HD.2516) 3405 0 R (HD.2517) 3406 0 R (HD.2518) 3407 0 R (HD.2519) 3408 0 R (HD.252) 887 0 R (HD.2520) 3409 0 R (HD.2521) 3410 0 R (HD.2522) 3411 0 R (HD.2523) 3412 0 R ] /Limits [ (HD.2496) (HD.2523) ] >>
+<< /Names [ (HD.1833) 2627 0 R (HD.1834) 2628 0 R (HD.1835) 2629 0 R (HD.1836) 2630 0 R (HD.1837) 2631 0 R (HD.1838) 2632 0 R (HD.1839) 2634 0 R (HD.184) 811 0 R (HD.1840) 2635 0 R (HD.1841) 2637 0 R (HD.1842) 2639 0 R (HD.1843) 2641 0 R (HD.1844) 2642 0 R (HD.1845) 2643 0 R (HD.1846) 2644 0 R (HD.1847) 2645 0 R (HD.1848) 2646 0 R (HD.1849) 2647 0 R (HD.185) 812 0 R (HD.1850) 2648 0 R (HD.1851) 2649 0 R (HD.1852) 2650 0 R (HD.1853) 2651 0 R (HD.1854) 2656 0 R (HD.1855) 2657 0 R (HD.1856) 2658 0 R (HD.1857) 2659 0 R (HD.1858) 2660 0 R (HD.1859) 2661 0 R (HD.186) 813 0 R (HD.1860) 2662 0 R (HD.1861) 2663 0 R ] /Limits [ (HD.1833) (HD.1861) ] >>
endobj
4418 0 obj
-<< /Names [ (HD.2524) 3413 0 R (HD.2525) 3414 0 R (HD.2526) 3415 0 R (HD.2527) 3416 0 R (HD.2528) 3417 0 R (HD.2529) 3418 0 R (HD.253) 888 0 R (HD.2530) 3419 0 R (HD.2531) 3420 0 R (HD.2532) 3421 0 R (HD.2533) 3422 0 R (HD.2534) 3423 0 R (HD.2535) 3424 0 R (HD.2536) 3425 0 R (HD.2537) 3426 0 R (HD.2538) 3427 0 R (HD.2539) 3432 0 R (HD.254) 889 0 R (HD.2540) 3433 0 R (HD.2541) 3434 0 R (HD.2542) 3435 0 R (HD.2543) 3436 0 R (HD.2544) 3437 0 R (HD.2545) 3438 0 R (HD.2546) 3439 0 R (HD.2547) 3440 0 R (HD.2548) 3441 0 R (HD.2549) 3442 0 R (HD.255) 890 0 R (HD.2550) 3443 0 R (HD.2551) 3444 0 R (HD.2552) 3445 0 R ] /Limits [ (HD.2524) (HD.2552) ] >>
+<< /Names [ (HD.1862) 2664 0 R (HD.1863) 2665 0 R (HD.1864) 2666 0 R (HD.1865) 2667 0 R (HD.1866) 2668 0 R (HD.1867) 2669 0 R (HD.1868) 2670 0 R (HD.1869) 2671 0 R (HD.187) 814 0 R (HD.1870) 2672 0 R (HD.1871) 2673 0 R (HD.1872) 2674 0 R (HD.1873) 2675 0 R (HD.1874) 2676 0 R (HD.1875) 2677 0 R (HD.1876) 2678 0 R (HD.1877) 2679 0 R (HD.1878) 2680 0 R (HD.1879) 2681 0 R (HD.188) 815 0 R (HD.1880) 2682 0 R (HD.1881) 2683 0 R (HD.1882) 2684 0 R (HD.1883) 2685 0 R (HD.1884) 2686 0 R (HD.1885) 2687 0 R (HD.1886) 2688 0 R (HD.1887) 2689 0 R (HD.1888) 2690 0 R (HD.1889) 2691 0 R (HD.189) 816 0 R (HD.1890) 2692 0 R ] /Limits [ (HD.1862) (HD.1890) ] >>
endobj
4419 0 obj
-<< /Names [ (HD.2553) 3446 0 R (HD.2554) 3447 0 R (HD.2555) 3448 0 R (HD.2556) 3449 0 R (HD.2557) 3450 0 R (HD.2558) 3451 0 R (HD.2559) 3452 0 R (HD.256) 891 0 R (HD.2560) 3453 0 R (HD.2561) 3454 0 R (HD.2562) 3455 0 R (HD.2563) 3456 0 R (HD.2564) 3457 0 R (HD.2565) 3458 0 R (HD.2566) 3459 0 R (HD.2567) 3460 0 R (HD.2568) 3461 0 R (HD.2569) 3462 0 R (HD.257) 892 0 R (HD.2570) 3463 0 R (HD.2571) 3464 0 R (HD.2572) 3465 0 R (HD.2573) 3466 0 R (HD.2574) 3467 0 R (HD.2575) 3468 0 R (HD.2576) 3469 0 R (HD.2577) 3470 0 R (HD.2578) 3471 0 R (HD.2579) 3472 0 R (HD.258) 893 0 R (HD.2580) 3473 0 R (HD.2581) 3474 0 R ] /Limits [ (HD.2553) (HD.2581) ] >>
+<< /Names [ (HD.1891) 2693 0 R (HD.1892) 2694 0 R (HD.1893) 2695 0 R (HD.1894) 2696 0 R (HD.1895) 2697 0 R (HD.1896) 2698 0 R (HD.1897) 2699 0 R (HD.1898) 2700 0 R (HD.1899) 2701 0 R (HD.19) 625 0 R (HD.190) 817 0 R (HD.1900) 2702 0 R (HD.1901) 2703 0 R (HD.1902) 2704 0 R (HD.1903) 2705 0 R (HD.1904) 2706 0 R (HD.1905) 2707 0 R (HD.1906) 2709 0 R (HD.1907) 2710 0 R (HD.1908) 2716 0 R (HD.1909) 2717 0 R (HD.191) 818 0 R (HD.1910) 2719 0 R (HD.1911) 2720 0 R (HD.1912) 2721 0 R (HD.1913) 2722 0 R (HD.1914) 2723 0 R (HD.1915) 2724 0 R (HD.1916) 2725 0 R (HD.1917) 2726 0 R (HD.1918) 2727 0 R (HD.1919) 2728 0 R ] /Limits [ (HD.1891) (HD.1919) ] >>
endobj
4420 0 obj
-<< /Names [ (HD.2582) 3475 0 R (HD.2583) 3476 0 R (HD.2584) 3477 0 R (HD.2585) 3478 0 R (HD.2586) 3479 0 R (HD.2587) 3480 0 R (HD.2588) 3481 0 R (HD.2589) 3482 0 R (HD.259) 894 0 R (HD.2590) 3487 0 R (HD.2591) 3488 0 R (HD.2592) 3489 0 R (HD.2593) 3490 0 R (HD.2594) 3491 0 R (HD.2595) 3492 0 R (HD.2596) 3493 0 R (HD.2597) 3494 0 R (HD.2598) 3495 0 R (HD.2599) 3496 0 R (HD.26) 632 0 R (HD.260) 895 0 R (HD.2600) 3497 0 R (HD.2601) 3498 0 R (HD.2602) 3499 0 R (HD.2603) 3500 0 R (HD.2604) 3501 0 R (HD.2605) 3502 0 R (HD.2606) 3503 0 R (HD.2607) 3504 0 R (HD.2608) 3505 0 R (HD.2609) 3506 0 R (HD.261) 896 0 R ] /Limits [ (HD.2582) (HD.261) ] >>
+<< /Names [ (HD.192) 819 0 R (HD.1920) 2729 0 R (HD.1921) 2730 0 R (HD.1922) 2731 0 R (HD.1923) 2732 0 R (HD.1924) 2733 0 R (HD.1925) 2734 0 R (HD.1926) 2735 0 R (HD.1927) 2736 0 R (HD.1928) 2737 0 R (HD.1929) 2738 0 R (HD.193) 820 0 R (HD.1930) 2739 0 R (HD.1931) 2740 0 R (HD.1932) 2741 0 R (HD.1933) 2742 0 R (HD.1934) 2743 0 R (HD.1935) 2744 0 R (HD.1936) 2745 0 R (HD.1937) 2746 0 R (HD.1938) 2747 0 R (HD.1939) 2748 0 R (HD.194) 821 0 R (HD.1940) 2749 0 R (HD.1941) 2750 0 R (HD.1942) 2751 0 R (HD.1943) 2752 0 R (HD.1944) 2753 0 R (HD.1945) 2754 0 R (HD.1946) 2755 0 R (HD.1947) 2756 0 R (HD.1948) 2763 0 R ] /Limits [ (HD.192) (HD.1948) ] >>
endobj
4421 0 obj
-<< /Names [ (HD.2610) 3507 0 R (HD.2611) 3508 0 R (HD.2612) 3509 0 R (HD.2613) 3510 0 R (HD.2614) 3511 0 R (HD.2615) 3512 0 R (HD.2616) 3513 0 R (HD.2617) 3514 0 R (HD.2618) 3515 0 R (HD.2619) 3516 0 R (HD.262) 897 0 R (HD.2620) 3517 0 R (HD.2621) 3518 0 R (HD.2622) 3519 0 R (HD.2623) 3520 0 R (HD.2624) 3521 0 R (HD.2625) 3526 0 R (HD.2626) 3527 0 R (HD.2627) 3528 0 R (HD.2628) 3529 0 R (HD.2629) 3530 0 R (HD.263) 898 0 R (HD.2630) 3531 0 R (HD.2631) 3532 0 R (HD.2632) 3533 0 R (HD.2633) 3534 0 R (HD.2634) 3535 0 R (HD.2635) 3536 0 R (HD.2636) 3537 0 R (HD.2637) 3538 0 R (HD.2638) 3539 0 R (HD.2639) 3540 0 R ] /Limits [ (HD.2610) (HD.2639) ] >>
+<< /Names [ (HD.1949) 2765 0 R (HD.195) 822 0 R (HD.1950) 2766 0 R (HD.1951) 2767 0 R (HD.1952) 2768 0 R (HD.1953) 2769 0 R (HD.1954) 2770 0 R (HD.1955) 2771 0 R (HD.1956) 2772 0 R (HD.1957) 2773 0 R (HD.1958) 2774 0 R (HD.1959) 2775 0 R (HD.196) 823 0 R (HD.1960) 2776 0 R (HD.1961) 2777 0 R (HD.1962) 2778 0 R (HD.1963) 2779 0 R (HD.1964) 2780 0 R (HD.1965) 2781 0 R (HD.1966) 2782 0 R (HD.1967) 2783 0 R (HD.1968) 2784 0 R (HD.1969) 2785 0 R (HD.197) 828 0 R (HD.1970) 2786 0 R (HD.1971) 2787 0 R (HD.1972) 2788 0 R (HD.1973) 2789 0 R (HD.1974) 2790 0 R (HD.1975) 2791 0 R (HD.1976) 2792 0 R (HD.1977) 2793 0 R ] /Limits [ (HD.1949) (HD.1977) ] >>
endobj
4422 0 obj
-<< /Names [ (HD.264) 899 0 R (HD.2640) 3541 0 R (HD.2641) 3542 0 R (HD.2642) 3543 0 R (HD.2643) 3544 0 R (HD.2644) 3545 0 R (HD.2645) 3546 0 R (HD.2646) 3547 0 R (HD.2647) 3548 0 R (HD.2648) 3549 0 R (HD.2649) 3550 0 R (HD.265) 900 0 R (HD.2650) 3551 0 R (HD.2651) 3552 0 R (HD.2652) 3553 0 R (HD.2653) 3554 0 R (HD.2654) 3555 0 R (HD.2655) 3556 0 R (HD.2656) 3557 0 R (HD.2657) 3558 0 R (HD.2658) 3559 0 R (HD.2659) 3560 0 R (HD.266) 901 0 R (HD.2660) 3561 0 R (HD.2661) 3562 0 R (HD.2662) 3563 0 R (HD.2663) 3564 0 R (HD.2664) 3565 0 R (HD.2665) 3566 0 R (HD.2666) 3567 0 R (HD.2667) 3568 0 R (HD.2668) 3569 0 R ] /Limits [ (HD.264) (HD.2668) ] >>
+<< /Names [ (HD.1978) 2794 0 R (HD.1979) 2795 0 R (HD.198) 829 0 R (HD.1980) 2796 0 R (HD.1981) 2797 0 R (HD.1982) 2798 0 R (HD.1983) 2799 0 R (HD.1984) 2800 0 R (HD.1985) 2801 0 R (HD.1986) 2802 0 R (HD.1987) 2803 0 R (HD.1988) 2804 0 R (HD.1989) 2811 0 R (HD.199) 830 0 R (HD.1990) 2812 0 R (HD.1991) 2813 0 R (HD.1992) 2814 0 R (HD.1993) 2815 0 R (HD.1994) 2816 0 R (HD.1995) 2817 0 R (HD.1996) 2818 0 R (HD.1997) 2819 0 R (HD.1998) 2820 0 R (HD.1999) 2821 0 R (HD.2) 608 0 R (HD.20) 626 0 R (HD.200) 831 0 R (HD.2000) 2822 0 R (HD.2001) 2823 0 R (HD.2002) 2824 0 R (HD.2003) 2825 0 R (HD.2004) 2826 0 R ] /Limits [ (HD.1978) (HD.2004) ] >>
endobj
4423 0 obj
-<< /Names [ (HD.2669) 3570 0 R (HD.267) 906 0 R (HD.2670) 3571 0 R (HD.2671) 3572 0 R (HD.2672) 3577 0 R (HD.2673) 3578 0 R (HD.2674) 3579 0 R (HD.2675) 3580 0 R (HD.2676) 3581 0 R (HD.2677) 3582 0 R (HD.2678) 3583 0 R (HD.2679) 3584 0 R (HD.268) 907 0 R (HD.2680) 3585 0 R (HD.2681) 3586 0 R (HD.2682) 3587 0 R (HD.2683) 3588 0 R (HD.2684) 3589 0 R (HD.2685) 3590 0 R (HD.2686) 3591 0 R (HD.2687) 3592 0 R (HD.2688) 3593 0 R (HD.2689) 3594 0 R (HD.269) 908 0 R (HD.2690) 3595 0 R (HD.2691) 3596 0 R (HD.2692) 3597 0 R (HD.2693) 3598 0 R (HD.2694) 3599 0 R (HD.2695) 3600 0 R (HD.2696) 3601 0 R (HD.2697) 3602 0 R ] /Limits [ (HD.2669) (HD.2697) ] >>
+<< /Names [ (HD.2005) 2827 0 R (HD.2006) 2828 0 R (HD.2007) 2829 0 R (HD.2008) 2830 0 R (HD.2009) 2831 0 R (HD.201) 832 0 R (HD.2010) 2832 0 R (HD.2011) 2833 0 R (HD.2012) 2834 0 R (HD.2013) 2835 0 R (HD.2014) 2836 0 R (HD.2015) 2837 0 R (HD.2016) 2838 0 R (HD.2017) 2839 0 R (HD.2018) 2840 0 R (HD.2019) 2841 0 R (HD.202) 833 0 R (HD.2020) 2842 0 R (HD.2021) 2843 0 R (HD.2022) 2844 0 R (HD.2023) 2845 0 R (HD.2024) 2846 0 R (HD.2025) 2847 0 R (HD.2026) 2848 0 R (HD.2027) 2849 0 R (HD.2028) 2850 0 R (HD.2029) 2851 0 R (HD.203) 834 0 R (HD.2030) 2852 0 R (HD.2031) 2853 0 R (HD.2032) 2854 0 R (HD.2033) 2855 0 R ] /Limits [ (HD.2005) (HD.2033) ] >>
endobj
4424 0 obj
-<< /Names [ (HD.2698) 3603 0 R (HD.2699) 3604 0 R (HD.27) 633 0 R (HD.270) 909 0 R (HD.2700) 3605 0 R (HD.2701) 3606 0 R (HD.2702) 3607 0 R (HD.2703) 3608 0 R (HD.2704) 3609 0 R (HD.2705) 3610 0 R (HD.2706) 3611 0 R (HD.2707) 3612 0 R (HD.2708) 3613 0 R (HD.2709) 3614 0 R (HD.271) 910 0 R (HD.2710) 3615 0 R (HD.2711) 3616 0 R (HD.2712) 3617 0 R (HD.2713) 3622 0 R (HD.2714) 3623 0 R (HD.2715) 3624 0 R (HD.2716) 3625 0 R (HD.2717) 3626 0 R (HD.2718) 3627 0 R (HD.2719) 3628 0 R (HD.272) 911 0 R (HD.2720) 3629 0 R (HD.2721) 3630 0 R (HD.2722) 3631 0 R (HD.2723) 3632 0 R (HD.2724) 3633 0 R (HD.2725) 3634 0 R ] /Limits [ (HD.2698) (HD.2725) ] >>
+<< /Names [ (HD.2034) 2856 0 R (HD.2035) 2857 0 R (HD.2036) 2858 0 R (HD.2037) 2859 0 R (HD.2038) 2860 0 R (HD.2039) 2861 0 R (HD.204) 835 0 R (HD.2040) 2866 0 R (HD.2041) 2867 0 R (HD.2042) 2868 0 R (HD.2043) 2869 0 R (HD.2044) 2870 0 R (HD.2045) 2871 0 R (HD.2046) 2872 0 R (HD.2047) 2873 0 R (HD.2048) 2874 0 R (HD.2049) 2875 0 R (HD.205) 836 0 R (HD.2050) 2876 0 R (HD.2051) 2877 0 R (HD.2052) 2878 0 R (HD.2053) 2879 0 R (HD.2054) 2880 0 R (HD.2055) 2881 0 R (HD.2056) 2882 0 R (HD.2057) 2883 0 R (HD.2058) 2884 0 R (HD.2059) 2885 0 R (HD.206) 837 0 R (HD.2060) 2886 0 R (HD.2061) 2887 0 R (HD.2062) 2888 0 R ] /Limits [ (HD.2034) (HD.2062) ] >>
endobj
4425 0 obj
-<< /Names [ (HD.2726) 3635 0 R (HD.2727) 3636 0 R (HD.2728) 3637 0 R (HD.2729) 3638 0 R (HD.273) 912 0 R (HD.2730) 3639 0 R (HD.2731) 3640 0 R (HD.2732) 3641 0 R (HD.2733) 3642 0 R (HD.2734) 3643 0 R (HD.2735) 3644 0 R (HD.2736) 3645 0 R (HD.2737) 3646 0 R (HD.2738) 3647 0 R (HD.2739) 3648 0 R (HD.274) 913 0 R (HD.2740) 3649 0 R (HD.2741) 3650 0 R (HD.2742) 3651 0 R (HD.2743) 3652 0 R (HD.2744) 3653 0 R (HD.2745) 3654 0 R (HD.2746) 3655 0 R (HD.2747) 3656 0 R (HD.2748) 3657 0 R (HD.2749) 3658 0 R (HD.275) 914 0 R (HD.2750) 3659 0 R (HD.2751) 3660 0 R (HD.2752) 3661 0 R (HD.2753) 3662 0 R (HD.2754) 3663 0 R ] /Limits [ (HD.2726) (HD.2754) ] >>
+<< /Names [ (HD.2063) 2889 0 R (HD.2064) 2890 0 R (HD.2065) 2891 0 R (HD.2066) 2892 0 R (HD.2067) 2893 0 R (HD.2068) 2894 0 R (HD.2069) 2895 0 R (HD.207) 838 0 R (HD.2070) 2896 0 R (HD.2071) 2897 0 R (HD.2072) 2898 0 R (HD.2073) 2900 0 R (HD.2074) 2901 0 R (HD.2075) 2903 0 R (HD.2076) 2904 0 R (HD.2077) 2905 0 R (HD.2078) 2906 0 R (HD.2079) 2907 0 R (HD.208) 839 0 R (HD.2080) 2908 0 R (HD.2081) 2914 0 R (HD.2082) 2915 0 R (HD.2083) 2916 0 R (HD.2084) 2917 0 R (HD.2085) 2918 0 R (HD.2086) 2919 0 R (HD.2087) 2920 0 R (HD.2088) 2921 0 R (HD.2089) 2922 0 R (HD.209) 840 0 R (HD.2090) 2923 0 R (HD.2091) 2924 0 R ] /Limits [ (HD.2063) (HD.2091) ] >>
endobj
4426 0 obj
-<< /Names [ (HD.2755) 3664 0 R (HD.2756) 3665 0 R (HD.2757) 3666 0 R (HD.2758) 3667 0 R (HD.2759) 3668 0 R (HD.276) 915 0 R (HD.2760) 3669 0 R (HD.2761) 3670 0 R (HD.2762) 3671 0 R (HD.2763) 3676 0 R (HD.2764) 3677 0 R (HD.2765) 3678 0 R (HD.2766) 3679 0 R (HD.2767) 3680 0 R (HD.2768) 3681 0 R (HD.2769) 3682 0 R (HD.277) 916 0 R (HD.2770) 3683 0 R (HD.2771) 3684 0 R (HD.2772) 3685 0 R (HD.2773) 3686 0 R (HD.2774) 3687 0 R (HD.2775) 3688 0 R (HD.2776) 3689 0 R (HD.2777) 3690 0 R (HD.2778) 3691 0 R (HD.2779) 3692 0 R (HD.278) 917 0 R (HD.2780) 3693 0 R (HD.2781) 3694 0 R (HD.2782) 3695 0 R (HD.2783) 3696 0 R ] /Limits [ (HD.2755) (HD.2783) ] >>
+<< /Names [ (HD.2092) 2925 0 R (HD.2093) 2926 0 R (HD.2094) 2927 0 R (HD.2095) 2928 0 R (HD.2096) 2929 0 R (HD.2097) 2930 0 R (HD.2098) 2931 0 R (HD.2099) 2932 0 R (HD.21) 627 0 R (HD.210) 841 0 R (HD.2100) 2933 0 R (HD.2101) 2934 0 R (HD.2102) 2935 0 R (HD.2103) 2936 0 R (HD.2104) 2937 0 R (HD.2105) 2938 0 R (HD.2106) 2939 0 R (HD.2107) 2940 0 R (HD.2108) 2941 0 R (HD.2109) 2942 0 R (HD.211) 842 0 R (HD.2110) 2944 0 R (HD.2111) 2945 0 R (HD.2112) 2946 0 R (HD.2113) 2947 0 R (HD.2114) 2948 0 R (HD.2115) 2949 0 R (HD.2116) 2950 0 R (HD.2117) 2951 0 R (HD.2118) 2952 0 R (HD.2119) 2953 0 R (HD.212) 843 0 R ] /Limits [ (HD.2092) (HD.212) ] >>
endobj
4427 0 obj
-<< /Names [ (HD.2784) 3697 0 R (HD.2785) 3698 0 R (HD.2786) 3699 0 R (HD.2787) 3700 0 R (HD.2788) 3701 0 R (HD.2789) 3702 0 R (HD.279) 918 0 R (HD.2790) 3703 0 R (HD.2791) 3704 0 R (HD.2792) 3705 0 R (HD.2793) 3706 0 R (HD.2794) 3707 0 R (HD.2795) 3708 0 R (HD.2796) 3709 0 R (HD.2797) 3710 0 R (HD.2798) 3711 0 R (HD.2799) 3712 0 R (HD.28) 634 0 R (HD.280) 919 0 R (HD.2800) 3713 0 R (HD.2801) 3714 0 R (HD.2802) 3715 0 R (HD.2803) 3716 0 R (HD.2804) 3717 0 R (HD.2805) 3718 0 R (HD.2806) 3719 0 R (HD.2807) 3724 0 R (HD.2808) 3725 0 R (HD.2809) 3726 0 R (HD.281) 920 0 R (HD.2810) 3727 0 R (HD.2811) 3728 0 R ] /Limits [ (HD.2784) (HD.2811) ] >>
+<< /Names [ (HD.2120) 2954 0 R (HD.2121) 2959 0 R (HD.2122) 2960 0 R (HD.2123) 2962 0 R (HD.2124) 2963 0 R (HD.2125) 2964 0 R (HD.2126) 2965 0 R (HD.2127) 2966 0 R (HD.2128) 2967 0 R (HD.2129) 2968 0 R (HD.213) 844 0 R (HD.2130) 2969 0 R (HD.2131) 2970 0 R (HD.2132) 2971 0 R (HD.2133) 2972 0 R (HD.2134) 2973 0 R (HD.2135) 2974 0 R (HD.2136) 2975 0 R (HD.2137) 2976 0 R (HD.2138) 2977 0 R (HD.2139) 2978 0 R (HD.214) 845 0 R (HD.2140) 2979 0 R (HD.2141) 2980 0 R (HD.2142) 2981 0 R (HD.2143) 2982 0 R (HD.2144) 2983 0 R (HD.2145) 2984 0 R (HD.2146) 2985 0 R (HD.2147) 2986 0 R (HD.2148) 2987 0 R (HD.2149) 2988 0 R ] /Limits [ (HD.2120) (HD.2149) ] >>
endobj
4428 0 obj
-<< /Names [ (HD.2812) 3729 0 R (HD.2813) 3730 0 R (HD.2814) 3731 0 R (HD.2815) 3732 0 R (HD.2816) 3733 0 R (HD.2817) 3734 0 R (HD.2818) 3735 0 R (HD.2819) 3736 0 R (HD.282) 921 0 R (HD.2820) 3737 0 R (HD.2821) 3738 0 R (HD.2822) 3739 0 R (HD.2823) 3740 0 R (HD.2824) 3741 0 R (HD.2825) 3742 0 R (HD.2826) 3743 0 R (HD.2827) 3744 0 R (HD.2828) 3745 0 R (HD.2829) 3746 0 R (HD.283) 922 0 R (HD.2830) 3747 0 R (HD.2831) 3748 0 R (HD.2832) 3749 0 R (HD.2833) 3750 0 R (HD.2834) 3751 0 R (HD.2835) 3752 0 R (HD.2836) 3753 0 R (HD.2837) 3754 0 R (HD.2838) 3755 0 R (HD.2839) 3756 0 R (HD.284) 923 0 R (HD.2840) 3757 0 R ] /Limits [ (HD.2812) (HD.2840) ] >>
+<< /Names [ (HD.215) 846 0 R (HD.2150) 2989 0 R (HD.2151) 2990 0 R (HD.2152) 2992 0 R (HD.2153) 2993 0 R (HD.2154) 2994 0 R (HD.2155) 2995 0 R (HD.2156) 2996 0 R (HD.2157) 2997 0 R (HD.2158) 2998 0 R (HD.2159) 2999 0 R (HD.216) 847 0 R (HD.2160) 3000 0 R (HD.2161) 3001 0 R (HD.2162) 3002 0 R (HD.2163) 3003 0 R (HD.2164) 3004 0 R (HD.2165) 3005 0 R (HD.2166) 3006 0 R (HD.2167) 3007 0 R (HD.2168) 3008 0 R (HD.2169) 3009 0 R (HD.217) 848 0 R (HD.2170) 3010 0 R (HD.2171) 3011 0 R (HD.2172) 3012 0 R (HD.2173) 3018 0 R (HD.2174) 3019 0 R (HD.2175) 3020 0 R (HD.2176) 3021 0 R (HD.2177) 3022 0 R (HD.2178) 3023 0 R ] /Limits [ (HD.215) (HD.2178) ] >>
endobj
4429 0 obj
-<< /Names [ (HD.2841) 3758 0 R (HD.2842) 3759 0 R (HD.2843) 3760 0 R (HD.2844) 3761 0 R (HD.2845) 3762 0 R (HD.2846) 3763 0 R (HD.2847) 3764 0 R (HD.2848) 3765 0 R (HD.2849) 3766 0 R (HD.285) 924 0 R (HD.2850) 3767 0 R (HD.2851) 3768 0 R (HD.2852) 3769 0 R (HD.2853) 3770 0 R (HD.2854) 3771 0 R (HD.2855) 3772 0 R (HD.2856) 3773 0 R (HD.2857) 3774 0 R (HD.2858) 3775 0 R (HD.2859) 3776 0 R (HD.286) 925 0 R (HD.2860) 3777 0 R (HD.2861) 3778 0 R (HD.2862) 3784 0 R (HD.2863) 3785 0 R (HD.2864) 3786 0 R (HD.2865) 3787 0 R (HD.2866) 3788 0 R (HD.2867) 3789 0 R (HD.2868) 3790 0 R (HD.2869) 3791 0 R (HD.287) 926 0 R ] /Limits [ (HD.2841) (HD.287) ] >>
+<< /Names [ (HD.2179) 3024 0 R (HD.218) 849 0 R (HD.2180) 3025 0 R (HD.2181) 3026 0 R (HD.2182) 3027 0 R (HD.2183) 3028 0 R (HD.2184) 3029 0 R (HD.2185) 3030 0 R (HD.2186) 3031 0 R (HD.2187) 3032 0 R (HD.2188) 3033 0 R (HD.2189) 3034 0 R (HD.219) 850 0 R (HD.2190) 3035 0 R (HD.2191) 3036 0 R (HD.2192) 3037 0 R (HD.2193) 3039 0 R (HD.2194) 3041 0 R (HD.2195) 3042 0 R (HD.2196) 3043 0 R (HD.2197) 3044 0 R (HD.2198) 3045 0 R (HD.2199) 3046 0 R (HD.22) 628 0 R (HD.220) 851 0 R (HD.2200) 3047 0 R (HD.2201) 3048 0 R (HD.2202) 3049 0 R (HD.2203) 3050 0 R (HD.2204) 3051 0 R (HD.2205) 3052 0 R (HD.2206) 3053 0 R ] /Limits [ (HD.2179) (HD.2206) ] >>
endobj
4430 0 obj
-<< /Names [ (HD.2870) 3792 0 R (HD.2871) 3793 0 R (HD.2872) 3794 0 R (HD.2873) 3795 0 R (HD.2874) 3796 0 R (HD.2875) 3797 0 R (HD.2876) 3798 0 R (HD.2877) 3799 0 R (HD.2878) 3800 0 R (HD.2879) 3801 0 R (HD.288) 927 0 R (HD.2880) 3802 0 R (HD.2881) 3803 0 R (HD.2882) 3804 0 R (HD.2883) 3805 0 R (HD.2884) 3806 0 R (HD.2885) 3807 0 R (HD.2886) 3808 0 R (HD.2887) 3809 0 R (HD.2888) 3810 0 R (HD.2889) 3811 0 R (HD.289) 928 0 R (HD.2890) 3812 0 R (HD.2891) 3813 0 R (HD.2892) 3814 0 R (HD.2893) 3815 0 R (HD.2894) 3816 0 R (HD.2895) 3817 0 R (HD.2896) 3818 0 R (HD.2897) 3819 0 R (HD.2898) 3820 0 R (HD.2899) 3821 0 R ] /Limits [ (HD.2870) (HD.2899) ] >>
+<< /Names [ (HD.2207) 3054 0 R (HD.2208) 3055 0 R (HD.2209) 3056 0 R (HD.221) 852 0 R (HD.2210) 3057 0 R (HD.2211) 3058 0 R (HD.2212) 3059 0 R (HD.2213) 3060 0 R (HD.2214) 3061 0 R (HD.2215) 3062 0 R (HD.2216) 3063 0 R (HD.2217) 3064 0 R (HD.2218) 3065 0 R (HD.2219) 3066 0 R (HD.222) 853 0 R (HD.2220) 3067 0 R (HD.2221) 3068 0 R (HD.2222) 3069 0 R (HD.2223) 3074 0 R (HD.2224) 3075 0 R (HD.2225) 3076 0 R (HD.2226) 3077 0 R (HD.2227) 3078 0 R (HD.2228) 3079 0 R (HD.2229) 3080 0 R (HD.223) 854 0 R (HD.2230) 3081 0 R (HD.2231) 3082 0 R (HD.2232) 3083 0 R (HD.2233) 3084 0 R (HD.2234) 3085 0 R (HD.2235) 3086 0 R ] /Limits [ (HD.2207) (HD.2235) ] >>
endobj
4431 0 obj
-<< /Names [ (HD.29) 635 0 R (HD.290) 929 0 R (HD.2900) 3822 0 R (HD.2901) 3823 0 R (HD.2902) 3824 0 R (HD.2903) 3825 0 R (HD.2904) 3826 0 R (HD.2905) 3827 0 R (HD.2906) 3828 0 R (HD.2907) 3829 0 R (HD.2908) 3830 0 R (HD.2909) 3831 0 R (HD.291) 930 0 R (HD.2910) 3832 0 R (HD.2911) 3833 0 R (HD.2912) 3834 0 R (HD.2913) 3835 0 R (HD.2914) 3836 0 R (HD.2915) 3841 0 R (HD.2916) 3842 0 R (HD.2917) 3843 0 R (HD.2918) 3844 0 R (HD.2919) 3845 0 R (HD.292) 931 0 R (HD.2920) 3846 0 R (HD.2921) 3847 0 R (HD.2922) 3848 0 R (HD.2923) 3849 0 R (HD.2924) 3850 0 R (HD.2925) 3851 0 R (HD.2926) 3852 0 R (HD.2927) 3853 0 R ] /Limits [ (HD.29) (HD.2927) ] >>
+<< /Names [ (HD.2236) 3087 0 R (HD.2237) 3088 0 R (HD.2238) 3089 0 R (HD.2239) 3090 0 R (HD.224) 855 0 R (HD.2240) 3091 0 R (HD.2241) 3092 0 R (HD.2242) 3093 0 R (HD.2243) 3094 0 R (HD.2244) 3095 0 R (HD.2245) 3096 0 R (HD.2246) 3097 0 R (HD.2247) 3098 0 R (HD.2248) 3099 0 R (HD.2249) 3100 0 R (HD.225) 856 0 R (HD.2250) 3101 0 R (HD.2251) 3102 0 R (HD.2252) 3103 0 R (HD.2253) 3104 0 R (HD.2254) 3105 0 R (HD.2255) 3106 0 R (HD.2256) 3107 0 R (HD.2257) 3108 0 R (HD.2258) 3109 0 R (HD.2259) 3110 0 R (HD.226) 857 0 R (HD.2260) 3111 0 R (HD.2261) 3112 0 R (HD.2262) 3113 0 R (HD.2263) 3114 0 R (HD.2264) 3115 0 R ] /Limits [ (HD.2236) (HD.2264) ] >>
endobj
4432 0 obj
-<< /Names [ (HD.2928) 3854 0 R (HD.2929) 3855 0 R (HD.293) 932 0 R (HD.2930) 3856 0 R (HD.2931) 3857 0 R (HD.2932) 3858 0 R (HD.2933) 3859 0 R (HD.2934) 3860 0 R (HD.2935) 3861 0 R (HD.2936) 3862 0 R (HD.2937) 3863 0 R (HD.2938) 3864 0 R (HD.2939) 3865 0 R (HD.294) 933 0 R (HD.2940) 3866 0 R (HD.2941) 3867 0 R (HD.2942) 3868 0 R (HD.2943) 3869 0 R (HD.2944) 3870 0 R (HD.2945) 3871 0 R (HD.2946) 3872 0 R (HD.2947) 3873 0 R (HD.2948) 3874 0 R (HD.2949) 3875 0 R (HD.295) 934 0 R (HD.2950) 3876 0 R (HD.2951) 3877 0 R (HD.2952) 3878 0 R (HD.2953) 3879 0 R (HD.2954) 3880 0 R (HD.2955) 3881 0 R (HD.2956) 3882 0 R ] /Limits [ (HD.2928) (HD.2956) ] >>
+<< /Names [ (HD.2265) 3116 0 R (HD.2266) 3117 0 R (HD.2267) 3118 0 R (HD.2268) 3119 0 R (HD.2269) 3120 0 R (HD.227) 858 0 R (HD.2270) 3127 0 R (HD.2271) 3128 0 R (HD.2272) 3130 0 R (HD.2273) 3131 0 R (HD.2274) 3132 0 R (HD.2275) 3133 0 R (HD.2276) 3134 0 R (HD.2277) 3135 0 R (HD.2278) 3136 0 R (HD.2279) 3137 0 R (HD.228) 859 0 R (HD.2280) 3138 0 R (HD.2281) 3139 0 R (HD.2282) 3140 0 R (HD.2283) 3142 0 R (HD.2284) 3143 0 R (HD.2285) 3144 0 R (HD.2286) 3145 0 R (HD.2287) 3147 0 R (HD.2288) 3149 0 R (HD.2289) 3150 0 R (HD.229) 860 0 R (HD.2290) 3151 0 R (HD.2291) 3152 0 R (HD.2292) 3153 0 R (HD.2293) 3154 0 R ] /Limits [ (HD.2265) (HD.2293) ] >>
endobj
4433 0 obj
-<< /Names [ (HD.2957) 3883 0 R (HD.2958) 3884 0 R (HD.2959) 3885 0 R (HD.296) 935 0 R (HD.2960) 3886 0 R (HD.2961) 3887 0 R (HD.2962) 3888 0 R (HD.2963) 3889 0 R (HD.2964) 3890 0 R (HD.2965) 3891 0 R (HD.2966) 3892 0 R (HD.2967) 3893 0 R (HD.2968) 3894 0 R (HD.2969) 3895 0 R (HD.297) 936 0 R (HD.2970) 3896 0 R (HD.2971) 3897 0 R (HD.2972) 3898 0 R (HD.2973) 3899 0 R (HD.2974) 3904 0 R (HD.2975) 3905 0 R (HD.2976) 3906 0 R (HD.2977) 3907 0 R (HD.2978) 3908 0 R (HD.2979) 3909 0 R (HD.298) 937 0 R (HD.2980) 3910 0 R (HD.2981) 3911 0 R (HD.2982) 3912 0 R (HD.2983) 3913 0 R (HD.2984) 3914 0 R (HD.2985) 3915 0 R ] /Limits [ (HD.2957) (HD.2985) ] >>
+<< /Names [ (HD.2294) 3155 0 R (HD.2295) 3156 0 R (HD.2296) 3157 0 R (HD.2297) 3158 0 R (HD.2298) 3159 0 R (HD.2299) 3166 0 R (HD.23) 629 0 R (HD.230) 861 0 R (HD.2300) 3167 0 R (HD.2301) 3168 0 R (HD.2302) 3169 0 R (HD.2303) 3170 0 R (HD.2304) 3171 0 R (HD.2305) 3172 0 R (HD.2306) 3173 0 R (HD.2307) 3174 0 R (HD.2308) 3175 0 R (HD.2309) 3176 0 R (HD.231) 862 0 R (HD.2310) 3177 0 R (HD.2311) 3178 0 R (HD.2312) 3179 0 R (HD.2313) 3180 0 R (HD.2314) 3181 0 R (HD.2315) 3182 0 R (HD.2316) 3183 0 R (HD.2317) 3184 0 R (HD.2318) 3185 0 R (HD.2319) 3186 0 R (HD.232) 863 0 R (HD.2320) 3187 0 R (HD.2321) 3188 0 R ] /Limits [ (HD.2294) (HD.2321) ] >>
endobj
4434 0 obj
-<< /Names [ (HD.2986) 3916 0 R (HD.2987) 3917 0 R (HD.2988) 3918 0 R (HD.2989) 3919 0 R (HD.299) 938 0 R (HD.2990) 3920 0 R (HD.2991) 3921 0 R (HD.2992) 3922 0 R (HD.2993) 3923 0 R (HD.2994) 3924 0 R (HD.2995) 3925 0 R (HD.2996) 3926 0 R (HD.2997) 3927 0 R (HD.2998) 3928 0 R (HD.2999) 3929 0 R (HD.3) 609 0 R (HD.30) 636 0 R (HD.300) 939 0 R (HD.3000) 3930 0 R (HD.3001) 3931 0 R (HD.3002) 3932 0 R (HD.3003) 3933 0 R (HD.3004) 3934 0 R (HD.3005) 3935 0 R (HD.3006) 3936 0 R (HD.3007) 3937 0 R (HD.3008) 3938 0 R (HD.3009) 3939 0 R (HD.301) 940 0 R (HD.3010) 3940 0 R (HD.3011) 3941 0 R (HD.3012) 3942 0 R ] /Limits [ (HD.2986) (HD.3012) ] >>
+<< /Names [ (HD.2322) 3189 0 R (HD.2323) 3190 0 R (HD.2324) 3191 0 R (HD.2325) 3192 0 R (HD.2326) 3193 0 R (HD.2327) 3194 0 R (HD.2328) 3195 0 R (HD.2329) 3196 0 R (HD.233) 864 0 R (HD.2330) 3197 0 R (HD.2331) 3198 0 R (HD.2332) 3199 0 R (HD.2333) 3200 0 R (HD.2334) 3201 0 R (HD.2335) 3202 0 R (HD.2336) 3203 0 R (HD.2337) 3204 0 R (HD.2338) 3205 0 R (HD.2339) 3206 0 R (HD.234) 865 0 R (HD.2340) 3207 0 R (HD.2341) 3208 0 R (HD.2342) 3209 0 R (HD.2343) 3210 0 R (HD.2344) 3211 0 R (HD.2345) 3219 0 R (HD.2346) 3220 0 R (HD.2347) 3221 0 R (HD.2348) 3222 0 R (HD.2349) 3223 0 R (HD.235) 870 0 R (HD.2350) 3224 0 R ] /Limits [ (HD.2322) (HD.2350) ] >>
endobj
4435 0 obj
-<< /Names [ (HD.3013) 3943 0 R (HD.3014) 3944 0 R (HD.3015) 3945 0 R (HD.3016) 3946 0 R (HD.3017) 3947 0 R (HD.3018) 3948 0 R (HD.3019) 3949 0 R (HD.302) 941 0 R (HD.3020) 3950 0 R (HD.3021) 3951 0 R (HD.3022) 3952 0 R (HD.3023) 3953 0 R (HD.3024) 3954 0 R (HD.3025) 3955 0 R (HD.3026) 3956 0 R (HD.3027) 3957 0 R (HD.3028) 3958 0 R (HD.3029) 3959 0 R (HD.303) 942 0 R (HD.3030) 3960 0 R (HD.3031) 3961 0 R (HD.3032) 3962 0 R (HD.3033) 3963 0 R (HD.3034) 3968 0 R (HD.3035) 3969 0 R (HD.3036) 3970 0 R (HD.3037) 3971 0 R (HD.3038) 3972 0 R (HD.3039) 3973 0 R (HD.304) 943 0 R (HD.3040) 3974 0 R (HD.3041) 3975 0 R ] /Limits [ (HD.3013) (HD.3041) ] >>
+<< /Names [ (HD.2351) 3225 0 R (HD.2352) 3226 0 R (HD.2353) 3227 0 R (HD.2354) 3228 0 R (HD.2355) 3229 0 R (HD.2356) 3230 0 R (HD.2357) 3231 0 R (HD.2358) 3232 0 R (HD.2359) 3233 0 R (HD.236) 871 0 R (HD.2360) 3234 0 R (HD.2361) 3235 0 R (HD.2362) 3236 0 R (HD.2363) 3237 0 R (HD.2364) 3238 0 R (HD.2365) 3239 0 R (HD.2366) 3240 0 R (HD.2367) 3241 0 R (HD.2368) 3242 0 R (HD.2369) 3243 0 R (HD.237) 872 0 R (HD.2370) 3244 0 R (HD.2371) 3245 0 R (HD.2372) 3246 0 R (HD.2373) 3247 0 R (HD.2374) 3248 0 R (HD.2375) 3249 0 R (HD.2376) 3250 0 R (HD.2377) 3251 0 R (HD.2378) 3252 0 R (HD.2379) 3253 0 R (HD.238) 873 0 R ] /Limits [ (HD.2351) (HD.238) ] >>
endobj
4436 0 obj
-<< /Names [ (HD.3042) 3976 0 R (HD.3043) 3977 0 R (HD.3044) 3978 0 R (HD.3045) 3979 0 R (HD.3046) 3980 0 R (HD.3047) 3981 0 R (HD.3048) 3982 0 R (HD.3049) 3983 0 R (HD.305) 944 0 R (HD.3050) 3984 0 R (HD.3051) 3985 0 R (HD.3052) 3986 0 R (HD.3053) 3987 0 R (HD.3054) 3988 0 R (HD.3055) 3989 0 R (HD.3056) 3990 0 R (HD.3057) 3991 0 R (HD.3058) 3992 0 R (HD.3059) 3993 0 R (HD.306) 945 0 R (HD.3060) 3994 0 R (HD.3061) 3995 0 R (HD.3062) 3996 0 R (HD.3063) 3997 0 R (HD.3064) 3998 0 R (HD.3065) 3999 0 R (HD.3066) 4000 0 R (HD.3067) 4001 0 R (HD.3068) 4002 0 R (HD.3069) 4003 0 R (HD.307) 946 0 R (HD.3070) 4004 0 R ] /Limits [ (HD.3042) (HD.3070) ] >>
+<< /Names [ (HD.2380) 3254 0 R (HD.2381) 3255 0 R (HD.2382) 3256 0 R (HD.2383) 3257 0 R (HD.2384) 3258 0 R (HD.2385) 3259 0 R (HD.2386) 3260 0 R (HD.2387) 3261 0 R (HD.2388) 3262 0 R (HD.2389) 3263 0 R (HD.239) 874 0 R (HD.2390) 3264 0 R (HD.2391) 3266 0 R (HD.2392) 3272 0 R (HD.2393) 3273 0 R (HD.2394) 3274 0 R (HD.2395) 3275 0 R (HD.2396) 3277 0 R (HD.2397) 3278 0 R (HD.2398) 3279 0 R (HD.2399) 3280 0 R (HD.24) 630 0 R (HD.240) 875 0 R (HD.2400) 3281 0 R (HD.2401) 3282 0 R (HD.2402) 3283 0 R (HD.2403) 3284 0 R (HD.2404) 3285 0 R (HD.2405) 3286 0 R (HD.2406) 3287 0 R (HD.2407) 3288 0 R (HD.2408) 3290 0 R ] /Limits [ (HD.2380) (HD.2408) ] >>
endobj
4437 0 obj
-<< /Names [ (HD.3071) 4005 0 R (HD.3072) 4006 0 R (HD.3073) 4007 0 R (HD.3074) 4008 0 R (HD.3075) 4009 0 R (HD.3076) 4010 0 R (HD.3077) 4011 0 R (HD.3078) 4012 0 R (HD.3079) 4013 0 R (HD.308) 947 0 R (HD.3080) 4014 0 R (HD.3081) 4015 0 R (HD.3082) 4016 0 R (HD.3083) 4017 0 R (HD.3084) 4018 0 R (HD.3085) 4019 0 R (HD.3086) 4020 0 R (HD.3087) 4021 0 R (HD.3088) 4022 0 R (HD.3089) 4023 0 R (HD.309) 948 0 R (HD.3090) 4024 0 R (HD.3091) 4029 0 R (HD.3092) 4030 0 R (HD.3093) 4031 0 R (HD.3094) 4032 0 R (HD.3095) 4033 0 R (HD.3096) 4034 0 R (HD.3097) 4035 0 R (HD.3098) 4036 0 R (HD.3099) 4037 0 R (HD.31) 637 0 R ] /Limits [ (HD.3071) (HD.31) ] >>
+<< /Names [ (HD.2409) 3291 0 R (HD.241) 876 0 R (HD.2410) 3292 0 R (HD.2411) 3293 0 R (HD.2412) 3294 0 R (HD.2413) 3295 0 R (HD.2414) 3296 0 R (HD.2415) 3297 0 R (HD.2416) 3298 0 R (HD.2417) 3299 0 R (HD.2418) 3300 0 R (HD.2419) 3301 0 R (HD.242) 877 0 R (HD.2420) 3302 0 R (HD.2421) 3303 0 R (HD.2422) 3304 0 R (HD.2423) 3305 0 R (HD.2424) 3306 0 R (HD.2425) 3307 0 R (HD.2426) 3308 0 R (HD.2427) 3309 0 R (HD.2428) 3310 0 R (HD.2429) 3311 0 R (HD.243) 878 0 R (HD.2430) 3312 0 R (HD.2431) 3313 0 R (HD.2432) 3314 0 R (HD.2433) 3315 0 R (HD.2434) 3316 0 R (HD.2435) 3317 0 R (HD.2436) 3318 0 R (HD.2437) 3319 0 R ] /Limits [ (HD.2409) (HD.2437) ] >>
endobj
4438 0 obj
-<< /Names [ (HD.310) 949 0 R (HD.3100) 4038 0 R (HD.311) 950 0 R (HD.312) 951 0 R (HD.313) 952 0 R (HD.314) 953 0 R (HD.315) 954 0 R (HD.316) 955 0 R (HD.317) 956 0 R (HD.318) 957 0 R (HD.319) 958 0 R (HD.32) 638 0 R (HD.320) 959 0 R (HD.321) 966 0 R (HD.322) 967 0 R (HD.323) 968 0 R (HD.324) 969 0 R (HD.325) 970 0 R (HD.326) 971 0 R (HD.327) 972 0 R (HD.328) 973 0 R (HD.329) 974 0 R (HD.33) 639 0 R (HD.330) 975 0 R (HD.331) 976 0 R (HD.332) 977 0 R (HD.333) 978 0 R (HD.334) 979 0 R (HD.335) 980 0 R (HD.336) 981 0 R (HD.337) 982 0 R (HD.338) 983 0 R ] /Limits [ (HD.310) (HD.338) ] >>
+<< /Names [ (HD.2438) 3320 0 R (HD.2439) 3321 0 R (HD.244) 879 0 R (HD.2440) 3322 0 R (HD.2441) 3323 0 R (HD.2442) 3324 0 R (HD.2443) 3325 0 R (HD.2444) 3331 0 R (HD.2445) 3332 0 R (HD.2446) 3333 0 R (HD.2447) 3334 0 R (HD.2448) 3335 0 R (HD.2449) 3336 0 R (HD.245) 880 0 R (HD.2450) 3337 0 R (HD.2451) 3338 0 R (HD.2452) 3339 0 R (HD.2453) 3340 0 R (HD.2454) 3341 0 R (HD.2455) 3342 0 R (HD.2456) 3343 0 R (HD.2457) 3344 0 R (HD.2458) 3345 0 R (HD.2459) 3346 0 R (HD.246) 881 0 R (HD.2460) 3347 0 R (HD.2461) 3348 0 R (HD.2462) 3349 0 R (HD.2463) 3350 0 R (HD.2464) 3351 0 R (HD.2465) 3352 0 R (HD.2466) 3353 0 R ] /Limits [ (HD.2438) (HD.2466) ] >>
endobj
4439 0 obj
-<< /Names [ (HD.339) 984 0 R (HD.34) 640 0 R (HD.340) 985 0 R (HD.341) 986 0 R (HD.342) 987 0 R (HD.343) 988 0 R (HD.344) 989 0 R (HD.345) 990 0 R (HD.346) 991 0 R (HD.347) 992 0 R (HD.348) 993 0 R (HD.349) 994 0 R (HD.35) 641 0 R (HD.350) 995 0 R (HD.351) 996 0 R (HD.352) 997 0 R (HD.353) 1003 0 R (HD.354) 1004 0 R (HD.355) 1005 0 R (HD.356) 1006 0 R (HD.357) 1007 0 R (HD.358) 1008 0 R (HD.359) 1009 0 R (HD.36) 642 0 R (HD.360) 1010 0 R (HD.361) 1011 0 R (HD.362) 1012 0 R (HD.363) 1013 0 R (HD.364) 1014 0 R (HD.365) 1015 0 R (HD.366) 1016 0 R (HD.367) 1017 0 R ] /Limits [ (HD.339) (HD.367) ] >>
+<< /Names [ (HD.2467) 3354 0 R (HD.2468) 3355 0 R (HD.2469) 3356 0 R (HD.247) 882 0 R (HD.2470) 3357 0 R (HD.2471) 3358 0 R (HD.2472) 3359 0 R (HD.2473) 3360 0 R (HD.2474) 3361 0 R (HD.2475) 3362 0 R (HD.2476) 3363 0 R (HD.2477) 3364 0 R (HD.2478) 3365 0 R (HD.2479) 3366 0 R (HD.248) 883 0 R (HD.2480) 3367 0 R (HD.2481) 3368 0 R (HD.2482) 3369 0 R (HD.2483) 3370 0 R (HD.2484) 3371 0 R (HD.2485) 3372 0 R (HD.2486) 3373 0 R (HD.2487) 3374 0 R (HD.2488) 3375 0 R (HD.2489) 3376 0 R (HD.249) 884 0 R (HD.2490) 3377 0 R (HD.2491) 3378 0 R (HD.2492) 3379 0 R (HD.2493) 3380 0 R (HD.2494) 3387 0 R (HD.2495) 3388 0 R ] /Limits [ (HD.2467) (HD.2495) ] >>
endobj
4440 0 obj
-<< /Names [ (HD.368) 1018 0 R (HD.369) 1019 0 R (HD.37) 647 0 R (HD.370) 1020 0 R (HD.371) 1021 0 R (HD.372) 1022 0 R (HD.373) 1023 0 R (HD.374) 1024 0 R (HD.375) 1025 0 R (HD.376) 1026 0 R (HD.377) 1027 0 R (HD.378) 1028 0 R (HD.379) 1029 0 R (HD.38) 648 0 R (HD.380) 1030 0 R (HD.381) 1031 0 R (HD.382) 1032 0 R (HD.383) 1033 0 R (HD.384) 1034 0 R (HD.385) 1035 0 R (HD.386) 1036 0 R (HD.387) 1037 0 R (HD.388) 1038 0 R (HD.389) 1039 0 R (HD.39) 649 0 R (HD.390) 1040 0 R (HD.391) 1041 0 R (HD.392) 1042 0 R (HD.393) 1043 0 R (HD.394) 1044 0 R (HD.395) 1045 0 R (HD.396) 1046 0 R ] /Limits [ (HD.368) (HD.396) ] >>
+<< /Names [ (HD.2496) 3389 0 R (HD.2497) 3390 0 R (HD.2498) 3391 0 R (HD.2499) 3392 0 R (HD.25) 631 0 R (HD.250) 885 0 R (HD.2500) 3393 0 R (HD.2501) 3394 0 R (HD.2502) 3395 0 R (HD.2503) 3396 0 R (HD.2504) 3397 0 R (HD.2505) 3398 0 R (HD.2506) 3399 0 R (HD.2507) 3400 0 R (HD.2508) 3401 0 R (HD.2509) 3402 0 R (HD.251) 886 0 R (HD.2510) 3403 0 R (HD.2511) 3404 0 R (HD.2512) 3405 0 R (HD.2513) 3406 0 R (HD.2514) 3407 0 R (HD.2515) 3408 0 R (HD.2516) 3409 0 R (HD.2517) 3410 0 R (HD.2518) 3411 0 R (HD.2519) 3412 0 R (HD.252) 887 0 R (HD.2520) 3413 0 R (HD.2521) 3414 0 R (HD.2522) 3415 0 R (HD.2523) 3416 0 R ] /Limits [ (HD.2496) (HD.2523) ] >>
endobj
4441 0 obj
-<< /Names [ (HD.397) 1047 0 R (HD.398) 1048 0 R (HD.399) 1049 0 R (HD.4) 610 0 R (HD.40) 650 0 R (HD.400) 1050 0 R (HD.401) 1051 0 R (HD.402) 1052 0 R (HD.403) 1053 0 R (HD.404) 1054 0 R (HD.405) 1059 0 R (HD.406) 1060 0 R (HD.407) 1061 0 R (HD.408) 1062 0 R (HD.409) 1063 0 R (HD.41) 651 0 R (HD.410) 1064 0 R (HD.411) 1065 0 R (HD.412) 1066 0 R (HD.413) 1067 0 R (HD.414) 1068 0 R (HD.415) 1069 0 R (HD.416) 1070 0 R (HD.417) 1071 0 R (HD.418) 1072 0 R (HD.419) 1073 0 R (HD.42) 652 0 R (HD.420) 1074 0 R (HD.421) 1075 0 R (HD.422) 1076 0 R (HD.423) 1077 0 R (HD.424) 1078 0 R ] /Limits [ (HD.397) (HD.424) ] >>
+<< /Names [ (HD.2524) 3417 0 R (HD.2525) 3418 0 R (HD.2526) 3419 0 R (HD.2527) 3420 0 R (HD.2528) 3421 0 R (HD.2529) 3422 0 R (HD.253) 888 0 R (HD.2530) 3423 0 R (HD.2531) 3424 0 R (HD.2532) 3425 0 R (HD.2533) 3426 0 R (HD.2534) 3427 0 R (HD.2535) 3428 0 R (HD.2536) 3429 0 R (HD.2537) 3430 0 R (HD.2538) 3431 0 R (HD.2539) 3432 0 R (HD.254) 889 0 R (HD.2540) 3433 0 R (HD.2541) 3434 0 R (HD.2542) 3435 0 R (HD.2543) 3436 0 R (HD.2544) 3437 0 R (HD.2545) 3438 0 R (HD.2546) 3439 0 R (HD.2547) 3440 0 R (HD.2548) 3441 0 R (HD.2549) 3442 0 R (HD.255) 890 0 R (HD.2550) 3443 0 R (HD.2551) 3444 0 R (HD.2552) 3445 0 R ] /Limits [ (HD.2524) (HD.2552) ] >>
endobj
4442 0 obj
-<< /Names [ (HD.425) 1079 0 R (HD.426) 1080 0 R (HD.427) 1081 0 R (HD.428) 1082 0 R (HD.429) 1083 0 R (HD.43) 653 0 R (HD.430) 1084 0 R (HD.431) 1085 0 R (HD.432) 1086 0 R (HD.433) 1087 0 R (HD.434) 1088 0 R (HD.435) 1089 0 R (HD.436) 1090 0 R (HD.437) 1091 0 R (HD.438) 1092 0 R (HD.439) 1093 0 R (HD.44) 654 0 R (HD.440) 1094 0 R (HD.441) 1095 0 R (HD.442) 1096 0 R (HD.443) 1097 0 R (HD.444) 1098 0 R (HD.445) 1099 0 R (HD.446) 1100 0 R (HD.447) 1101 0 R (HD.448) 1102 0 R (HD.449) 1103 0 R (HD.45) 655 0 R (HD.450) 1104 0 R (HD.451) 1105 0 R (HD.452) 1106 0 R (HD.453) 1107 0 R ] /Limits [ (HD.425) (HD.453) ] >>
+<< /Names [ (HD.2553) 3446 0 R (HD.2554) 3447 0 R (HD.2555) 3448 0 R (HD.2556) 3449 0 R (HD.2557) 3454 0 R (HD.2558) 3455 0 R (HD.2559) 3456 0 R (HD.256) 891 0 R (HD.2560) 3457 0 R (HD.2561) 3458 0 R (HD.2562) 3459 0 R (HD.2563) 3460 0 R (HD.2564) 3461 0 R (HD.2565) 3462 0 R (HD.2566) 3463 0 R (HD.2567) 3464 0 R (HD.2568) 3465 0 R (HD.2569) 3466 0 R (HD.257) 892 0 R (HD.2570) 3467 0 R (HD.2571) 3468 0 R (HD.2572) 3469 0 R (HD.2573) 3470 0 R (HD.2574) 3471 0 R (HD.2575) 3472 0 R (HD.2576) 3473 0 R (HD.2577) 3474 0 R (HD.2578) 3475 0 R (HD.2579) 3476 0 R (HD.258) 893 0 R (HD.2580) 3477 0 R (HD.2581) 3478 0 R ] /Limits [ (HD.2553) (HD.2581) ] >>
endobj
4443 0 obj
-<< /Names [ (HD.454) 1108 0 R (HD.455) 1109 0 R (HD.456) 1110 0 R (HD.457) 1111 0 R (HD.458) 1112 0 R (HD.459) 1113 0 R (HD.46) 656 0 R (HD.460) 1114 0 R (HD.461) 1115 0 R (HD.462) 1116 0 R (HD.463) 1117 0 R (HD.464) 1122 0 R (HD.465) 1123 0 R (HD.466) 1124 0 R (HD.467) 1125 0 R (HD.468) 1126 0 R (HD.469) 1127 0 R (HD.47) 657 0 R (HD.470) 1128 0 R (HD.471) 1129 0 R (HD.472) 1130 0 R (HD.473) 1131 0 R (HD.474) 1132 0 R (HD.475) 1133 0 R (HD.476) 1134 0 R (HD.477) 1135 0 R (HD.478) 1136 0 R (HD.479) 1137 0 R (HD.48) 658 0 R (HD.480) 1138 0 R (HD.481) 1139 0 R (HD.482) 1140 0 R ] /Limits [ (HD.454) (HD.482) ] >>
+<< /Names [ (HD.2582) 3479 0 R (HD.2583) 3480 0 R (HD.2584) 3481 0 R (HD.2585) 3482 0 R (HD.2586) 3483 0 R (HD.2587) 3484 0 R (HD.2588) 3485 0 R (HD.2589) 3486 0 R (HD.259) 894 0 R (HD.2590) 3487 0 R (HD.2591) 3488 0 R (HD.2592) 3489 0 R (HD.2593) 3490 0 R (HD.2594) 3491 0 R (HD.2595) 3492 0 R (HD.2596) 3493 0 R (HD.2597) 3494 0 R (HD.2598) 3495 0 R (HD.2599) 3496 0 R (HD.26) 632 0 R (HD.260) 895 0 R (HD.2600) 3497 0 R (HD.2601) 3498 0 R (HD.2602) 3499 0 R (HD.2603) 3500 0 R (HD.2604) 3501 0 R (HD.2605) 3502 0 R (HD.2606) 3503 0 R (HD.2607) 3504 0 R (HD.2608) 3509 0 R (HD.2609) 3510 0 R (HD.261) 896 0 R ] /Limits [ (HD.2582) (HD.261) ] >>
endobj
4444 0 obj
-<< /Names [ (HD.483) 1141 0 R (HD.484) 1142 0 R (HD.485) 1143 0 R (HD.486) 1144 0 R (HD.487) 1145 0 R (HD.488) 1146 0 R (HD.489) 1147 0 R (HD.49) 659 0 R (HD.490) 1148 0 R (HD.491) 1149 0 R (HD.492) 1150 0 R (HD.493) 1151 0 R (HD.494) 1152 0 R (HD.495) 1153 0 R (HD.496) 1154 0 R (HD.497) 1155 0 R (HD.498) 1156 0 R (HD.499) 1157 0 R (HD.5) 611 0 R (HD.50) 660 0 R (HD.500) 1158 0 R (HD.501) 1159 0 R (HD.502) 1160 0 R (HD.503) 1161 0 R (HD.504) 1162 0 R (HD.505) 1163 0 R (HD.506) 1164 0 R (HD.507) 1165 0 R (HD.508) 1166 0 R (HD.509) 1167 0 R (HD.51) 661 0 R (HD.510) 1168 0 R ] /Limits [ (HD.483) (HD.510) ] >>
+<< /Names [ (HD.2610) 3511 0 R (HD.2611) 3512 0 R (HD.2612) 3513 0 R (HD.2613) 3514 0 R (HD.2614) 3515 0 R (HD.2615) 3516 0 R (HD.2616) 3517 0 R (HD.2617) 3518 0 R (HD.2618) 3519 0 R (HD.2619) 3520 0 R (HD.262) 897 0 R (HD.2620) 3521 0 R (HD.2621) 3522 0 R (HD.2622) 3523 0 R (HD.2623) 3524 0 R (HD.2624) 3525 0 R (HD.2625) 3526 0 R (HD.2626) 3527 0 R (HD.2627) 3528 0 R (HD.2628) 3529 0 R (HD.2629) 3530 0 R (HD.263) 898 0 R (HD.2630) 3531 0 R (HD.2631) 3532 0 R (HD.2632) 3533 0 R (HD.2633) 3534 0 R (HD.2634) 3535 0 R (HD.2635) 3536 0 R (HD.2636) 3537 0 R (HD.2637) 3538 0 R (HD.2638) 3539 0 R (HD.2639) 3540 0 R ] /Limits [ (HD.2610) (HD.2639) ] >>
endobj
4445 0 obj
-<< /Names [ (HD.511) 1169 0 R (HD.512) 1170 0 R (HD.513) 1171 0 R (HD.514) 1172 0 R (HD.515) 1173 0 R (HD.516) 1174 0 R (HD.517) 1175 0 R (HD.518) 1176 0 R (HD.519) 1182 0 R (HD.52) 662 0 R (HD.520) 1183 0 R (HD.521) 1184 0 R (HD.522) 1185 0 R (HD.523) 1186 0 R (HD.524) 1187 0 R (HD.525) 1188 0 R (HD.526) 1189 0 R (HD.527) 1190 0 R (HD.528) 1191 0 R (HD.529) 1192 0 R (HD.53) 663 0 R (HD.530) 1193 0 R (HD.531) 1194 0 R (HD.532) 1195 0 R (HD.533) 1196 0 R (HD.534) 1197 0 R (HD.535) 1198 0 R (HD.536) 1199 0 R (HD.537) 1200 0 R (HD.538) 1201 0 R (HD.539) 1202 0 R (HD.54) 664 0 R ] /Limits [ (HD.511) (HD.54) ] >>
+<< /Names [ (HD.264) 899 0 R (HD.2640) 3541 0 R (HD.2641) 3542 0 R (HD.2642) 3543 0 R (HD.2643) 3548 0 R (HD.2644) 3549 0 R (HD.2645) 3550 0 R (HD.2646) 3551 0 R (HD.2647) 3552 0 R (HD.2648) 3553 0 R (HD.2649) 3554 0 R (HD.265) 900 0 R (HD.2650) 3555 0 R (HD.2651) 3556 0 R (HD.2652) 3557 0 R (HD.2653) 3558 0 R (HD.2654) 3559 0 R (HD.2655) 3560 0 R (HD.2656) 3561 0 R (HD.2657) 3562 0 R (HD.2658) 3563 0 R (HD.2659) 3564 0 R (HD.266) 901 0 R (HD.2660) 3565 0 R (HD.2661) 3566 0 R (HD.2662) 3567 0 R (HD.2663) 3568 0 R (HD.2664) 3569 0 R (HD.2665) 3570 0 R (HD.2666) 3571 0 R (HD.2667) 3572 0 R (HD.2668) 3573 0 R ] /Limits [ (HD.264) (HD.2668) ] >>
endobj
4446 0 obj
-<< /Names [ (HD.540) 1203 0 R (HD.541) 1204 0 R (HD.542) 1205 0 R (HD.543) 1206 0 R (HD.544) 1207 0 R (HD.545) 1208 0 R (HD.546) 1209 0 R (HD.547) 1210 0 R (HD.548) 1211 0 R (HD.549) 1212 0 R (HD.55) 665 0 R (HD.550) 1213 0 R (HD.551) 1214 0 R (HD.552) 1215 0 R (HD.553) 1216 0 R (HD.554) 1217 0 R (HD.555) 1218 0 R (HD.556) 1219 0 R (HD.557) 1220 0 R (HD.558) 1221 0 R (HD.559) 1222 0 R (HD.56) 666 0 R (HD.560) 1223 0 R (HD.561) 1224 0 R (HD.562) 1225 0 R (HD.563) 1226 0 R (HD.564) 1227 0 R (HD.565) 1228 0 R (HD.566) 1229 0 R (HD.567) 1230 0 R (HD.568) 1231 0 R (HD.569) 1232 0 R ] /Limits [ (HD.540) (HD.569) ] >>
+<< /Names [ (HD.2669) 3574 0 R (HD.267) 906 0 R (HD.2670) 3575 0 R (HD.2671) 3576 0 R (HD.2672) 3577 0 R (HD.2673) 3578 0 R (HD.2674) 3579 0 R (HD.2675) 3580 0 R (HD.2676) 3581 0 R (HD.2677) 3582 0 R (HD.2678) 3583 0 R (HD.2679) 3584 0 R (HD.268) 907 0 R (HD.2680) 3585 0 R (HD.2681) 3586 0 R (HD.2682) 3587 0 R (HD.2683) 3588 0 R (HD.2684) 3589 0 R (HD.2685) 3590 0 R (HD.2686) 3591 0 R (HD.2687) 3592 0 R (HD.2688) 3593 0 R (HD.2689) 3594 0 R (HD.269) 908 0 R (HD.2690) 3599 0 R (HD.2691) 3600 0 R (HD.2692) 3601 0 R (HD.2693) 3602 0 R (HD.2694) 3603 0 R (HD.2695) 3604 0 R (HD.2696) 3605 0 R (HD.2697) 3606 0 R ] /Limits [ (HD.2669) (HD.2697) ] >>
endobj
4447 0 obj
-<< /Names [ (HD.57) 667 0 R (HD.570) 1233 0 R (HD.571) 1234 0 R (HD.572) 1235 0 R (HD.573) 1236 0 R (HD.574) 1237 0 R (HD.575) 1238 0 R (HD.576) 1239 0 R (HD.577) 1240 0 R (HD.578) 1241 0 R (HD.579) 1242 0 R (HD.58) 668 0 R (HD.580) 1243 0 R (HD.581) 1244 0 R (HD.582) 1249 0 R (HD.583) 1250 0 R (HD.584) 1251 0 R (HD.585) 1252 0 R (HD.586) 1253 0 R (HD.587) 1254 0 R (HD.588) 1255 0 R (HD.589) 1256 0 R (HD.59) 669 0 R (HD.590) 1257 0 R (HD.591) 1258 0 R (HD.592) 1259 0 R (HD.593) 1260 0 R (HD.594) 1261 0 R (HD.595) 1262 0 R (HD.596) 1263 0 R (HD.597) 1264 0 R (HD.598) 1265 0 R ] /Limits [ (HD.57) (HD.598) ] >>
+<< /Names [ (HD.2698) 3607 0 R (HD.2699) 3608 0 R (HD.27) 633 0 R (HD.270) 909 0 R (HD.2700) 3609 0 R (HD.2701) 3610 0 R (HD.2702) 3611 0 R (HD.2703) 3612 0 R (HD.2704) 3613 0 R (HD.2705) 3614 0 R (HD.2706) 3615 0 R (HD.2707) 3616 0 R (HD.2708) 3617 0 R (HD.2709) 3618 0 R (HD.271) 910 0 R (HD.2710) 3619 0 R (HD.2711) 3620 0 R (HD.2712) 3621 0 R (HD.2713) 3622 0 R (HD.2714) 3623 0 R (HD.2715) 3624 0 R (HD.2716) 3625 0 R (HD.2717) 3626 0 R (HD.2718) 3627 0 R (HD.2719) 3628 0 R (HD.272) 911 0 R (HD.2720) 3629 0 R (HD.2721) 3630 0 R (HD.2722) 3631 0 R (HD.2723) 3632 0 R (HD.2724) 3633 0 R (HD.2725) 3634 0 R ] /Limits [ (HD.2698) (HD.2725) ] >>
endobj
4448 0 obj
-<< /Names [ (HD.599) 1266 0 R (HD.6) 612 0 R (HD.60) 670 0 R (HD.600) 1267 0 R (HD.601) 1268 0 R (HD.602) 1269 0 R (HD.603) 1270 0 R (HD.604) 1271 0 R (HD.605) 1272 0 R (HD.606) 1273 0 R (HD.607) 1274 0 R (HD.608) 1275 0 R (HD.609) 1276 0 R (HD.61) 671 0 R (HD.610) 1277 0 R (HD.611) 1278 0 R (HD.612) 1279 0 R (HD.613) 1280 0 R (HD.614) 1281 0 R (HD.615) 1282 0 R (HD.616) 1283 0 R (HD.617) 1284 0 R (HD.618) 1285 0 R (HD.619) 1286 0 R (HD.62) 672 0 R (HD.620) 1287 0 R (HD.621) 1288 0 R (HD.622) 1289 0 R (HD.623) 1290 0 R (HD.624) 1291 0 R (HD.625) 1292 0 R (HD.626) 1293 0 R ] /Limits [ (HD.599) (HD.626) ] >>
+<< /Names [ (HD.2726) 3635 0 R (HD.2727) 3636 0 R (HD.2728) 3637 0 R (HD.2729) 3638 0 R (HD.273) 912 0 R (HD.2730) 3639 0 R (HD.2731) 3644 0 R (HD.2732) 3645 0 R (HD.2733) 3646 0 R (HD.2734) 3647 0 R (HD.2735) 3648 0 R (HD.2736) 3649 0 R (HD.2737) 3650 0 R (HD.2738) 3651 0 R (HD.2739) 3652 0 R (HD.274) 913 0 R (HD.2740) 3653 0 R (HD.2741) 3654 0 R (HD.2742) 3655 0 R (HD.2743) 3656 0 R (HD.2744) 3657 0 R (HD.2745) 3658 0 R (HD.2746) 3659 0 R (HD.2747) 3660 0 R (HD.2748) 3661 0 R (HD.2749) 3662 0 R (HD.275) 914 0 R (HD.2750) 3663 0 R (HD.2751) 3664 0 R (HD.2752) 3665 0 R (HD.2753) 3666 0 R (HD.2754) 3667 0 R ] /Limits [ (HD.2726) (HD.2754) ] >>
endobj
4449 0 obj
-<< /Names [ (HD.627) 1294 0 R (HD.628) 1295 0 R (HD.629) 1296 0 R (HD.63) 673 0 R (HD.630) 1297 0 R (HD.631) 1298 0 R (HD.632) 1299 0 R (HD.633) 1300 0 R (HD.634) 1301 0 R (HD.635) 1302 0 R (HD.636) 1303 0 R (HD.637) 1304 0 R (HD.638) 1305 0 R (HD.639) 1306 0 R (HD.64) 674 0 R (HD.640) 1307 0 R (HD.641) 1308 0 R (HD.642) 1309 0 R (HD.643) 1310 0 R (HD.644) 1315 0 R (HD.645) 1316 0 R (HD.646) 1317 0 R (HD.647) 1318 0 R (HD.648) 1319 0 R (HD.649) 1320 0 R (HD.65) 675 0 R (HD.650) 1321 0 R (HD.651) 1322 0 R (HD.652) 1323 0 R (HD.653) 1324 0 R (HD.654) 1325 0 R (HD.655) 1326 0 R ] /Limits [ (HD.627) (HD.655) ] >>
+<< /Names [ (HD.2755) 3668 0 R (HD.2756) 3669 0 R (HD.2757) 3670 0 R (HD.2758) 3671 0 R (HD.2759) 3672 0 R (HD.276) 915 0 R (HD.2760) 3673 0 R (HD.2761) 3674 0 R (HD.2762) 3675 0 R (HD.2763) 3676 0 R (HD.2764) 3677 0 R (HD.2765) 3678 0 R (HD.2766) 3679 0 R (HD.2767) 3680 0 R (HD.2768) 3681 0 R (HD.2769) 3682 0 R (HD.277) 916 0 R (HD.2770) 3683 0 R (HD.2771) 3684 0 R (HD.2772) 3685 0 R (HD.2773) 3686 0 R (HD.2774) 3687 0 R (HD.2775) 3688 0 R (HD.2776) 3689 0 R (HD.2777) 3690 0 R (HD.2778) 3691 0 R (HD.2779) 3692 0 R (HD.278) 917 0 R (HD.2780) 3693 0 R (HD.2781) 3698 0 R (HD.2782) 3699 0 R (HD.2783) 3700 0 R ] /Limits [ (HD.2755) (HD.2783) ] >>
endobj
4450 0 obj
-<< /Names [ (HD.656) 1327 0 R (HD.657) 1328 0 R (HD.658) 1329 0 R (HD.659) 1330 0 R (HD.66) 676 0 R (HD.660) 1331 0 R (HD.661) 1332 0 R (HD.662) 1333 0 R (HD.663) 1334 0 R (HD.664) 1335 0 R (HD.665) 1336 0 R (HD.666) 1337 0 R (HD.667) 1338 0 R (HD.668) 1339 0 R (HD.669) 1340 0 R (HD.67) 677 0 R (HD.670) 1341 0 R (HD.671) 1342 0 R (HD.672) 1343 0 R (HD.673) 1344 0 R (HD.674) 1345 0 R (HD.675) 1346 0 R (HD.676) 1347 0 R (HD.677) 1348 0 R (HD.678) 1349 0 R (HD.679) 1350 0 R (HD.68) 678 0 R (HD.680) 1351 0 R (HD.681) 1352 0 R (HD.682) 1353 0 R (HD.683) 1354 0 R (HD.684) 1355 0 R ] /Limits [ (HD.656) (HD.684) ] >>
+<< /Names [ (HD.2784) 3701 0 R (HD.2785) 3702 0 R (HD.2786) 3703 0 R (HD.2787) 3704 0 R (HD.2788) 3705 0 R (HD.2789) 3706 0 R (HD.279) 918 0 R (HD.2790) 3707 0 R (HD.2791) 3708 0 R (HD.2792) 3709 0 R (HD.2793) 3710 0 R (HD.2794) 3711 0 R (HD.2795) 3712 0 R (HD.2796) 3713 0 R (HD.2797) 3714 0 R (HD.2798) 3715 0 R (HD.2799) 3716 0 R (HD.28) 634 0 R (HD.280) 919 0 R (HD.2800) 3717 0 R (HD.2801) 3718 0 R (HD.2802) 3719 0 R (HD.2803) 3720 0 R (HD.2804) 3721 0 R (HD.2805) 3722 0 R (HD.2806) 3723 0 R (HD.2807) 3724 0 R (HD.2808) 3725 0 R (HD.2809) 3726 0 R (HD.281) 920 0 R (HD.2810) 3727 0 R (HD.2811) 3728 0 R ] /Limits [ (HD.2784) (HD.2811) ] >>
endobj
4451 0 obj
-<< /Names [ (HD.685) 1356 0 R (HD.686) 1357 0 R (HD.687) 1362 0 R (HD.688) 1363 0 R (HD.689) 1364 0 R (HD.69) 679 0 R (HD.690) 1365 0 R (HD.691) 1366 0 R (HD.692) 1367 0 R (HD.693) 1368 0 R (HD.694) 1369 0 R (HD.695) 1370 0 R (HD.696) 1371 0 R (HD.697) 1372 0 R (HD.698) 1373 0 R (HD.699) 1374 0 R (HD.7) 613 0 R (HD.70) 680 0 R (HD.700) 1375 0 R (HD.701) 1376 0 R (HD.702) 1377 0 R (HD.703) 1378 0 R (HD.704) 1379 0 R (HD.705) 1380 0 R (HD.706) 1381 0 R (HD.707) 1382 0 R (HD.708) 1383 0 R (HD.709) 1384 0 R (HD.71) 681 0 R (HD.710) 1385 0 R (HD.711) 1386 0 R (HD.712) 1387 0 R ] /Limits [ (HD.685) (HD.712) ] >>
+<< /Names [ (HD.2812) 3729 0 R (HD.2813) 3730 0 R (HD.2814) 3731 0 R (HD.2815) 3732 0 R (HD.2816) 3733 0 R (HD.2817) 3734 0 R (HD.2818) 3735 0 R (HD.2819) 3736 0 R (HD.282) 921 0 R (HD.2820) 3737 0 R (HD.2821) 3738 0 R (HD.2822) 3739 0 R (HD.2823) 3740 0 R (HD.2824) 3741 0 R (HD.2825) 3747 0 R (HD.2826) 3748 0 R (HD.2827) 3749 0 R (HD.2828) 3750 0 R (HD.2829) 3751 0 R (HD.283) 922 0 R (HD.2830) 3752 0 R (HD.2831) 3753 0 R (HD.2832) 3754 0 R (HD.2833) 3755 0 R (HD.2834) 3756 0 R (HD.2835) 3757 0 R (HD.2836) 3758 0 R (HD.2837) 3759 0 R (HD.2838) 3760 0 R (HD.2839) 3761 0 R (HD.284) 923 0 R (HD.2840) 3762 0 R ] /Limits [ (HD.2812) (HD.2840) ] >>
endobj
4452 0 obj
-<< /Names [ (HD.713) 1388 0 R (HD.714) 1389 0 R (HD.715) 1390 0 R (HD.716) 1391 0 R (HD.717) 1392 0 R (HD.718) 1393 0 R (HD.719) 1394 0 R (HD.72) 682 0 R (HD.720) 1395 0 R (HD.721) 1396 0 R (HD.722) 1397 0 R (HD.723) 1398 0 R (HD.724) 1399 0 R (HD.725) 1400 0 R (HD.726) 1401 0 R (HD.727) 1402 0 R (HD.728) 1403 0 R (HD.729) 1404 0 R (HD.73) 683 0 R (HD.730) 1405 0 R (HD.731) 1406 0 R (HD.732) 1407 0 R (HD.733) 1408 0 R (HD.734) 1409 0 R (HD.735) 1410 0 R (HD.736) 1411 0 R (HD.737) 1412 0 R (HD.738) 1413 0 R (HD.739) 1418 0 R (HD.74) 684 0 R (HD.740) 1419 0 R (HD.741) 1420 0 R ] /Limits [ (HD.713) (HD.741) ] >>
+<< /Names [ (HD.2841) 3763 0 R (HD.2842) 3764 0 R (HD.2843) 3765 0 R (HD.2844) 3766 0 R (HD.2845) 3767 0 R (HD.2846) 3768 0 R (HD.2847) 3769 0 R (HD.2848) 3770 0 R (HD.2849) 3771 0 R (HD.285) 924 0 R (HD.2850) 3772 0 R (HD.2851) 3773 0 R (HD.2852) 3774 0 R (HD.2853) 3775 0 R (HD.2854) 3776 0 R (HD.2855) 3777 0 R (HD.2856) 3778 0 R (HD.2857) 3779 0 R (HD.2858) 3780 0 R (HD.2859) 3781 0 R (HD.286) 925 0 R (HD.2860) 3782 0 R (HD.2861) 3783 0 R (HD.2862) 3784 0 R (HD.2863) 3785 0 R (HD.2864) 3786 0 R (HD.2865) 3787 0 R (HD.2866) 3788 0 R (HD.2867) 3789 0 R (HD.2868) 3790 0 R (HD.2869) 3791 0 R (HD.287) 926 0 R ] /Limits [ (HD.2841) (HD.287) ] >>
endobj
4453 0 obj
-<< /Names [ (HD.742) 1421 0 R (HD.743) 1422 0 R (HD.744) 1423 0 R (HD.745) 1424 0 R (HD.746) 1425 0 R (HD.747) 1426 0 R (HD.748) 1427 0 R (HD.749) 1428 0 R (HD.75) 685 0 R (HD.750) 1429 0 R (HD.751) 1430 0 R (HD.752) 1431 0 R (HD.753) 1432 0 R (HD.754) 1433 0 R (HD.755) 1434 0 R (HD.756) 1435 0 R (HD.757) 1436 0 R (HD.758) 1437 0 R (HD.759) 1438 0 R (HD.76) 686 0 R (HD.760) 1439 0 R (HD.761) 1440 0 R (HD.762) 1441 0 R (HD.763) 1442 0 R (HD.764) 1443 0 R (HD.765) 1444 0 R (HD.766) 1445 0 R (HD.767) 1446 0 R (HD.768) 1447 0 R (HD.769) 1448 0 R (HD.77) 687 0 R (HD.770) 1449 0 R ] /Limits [ (HD.742) (HD.770) ] >>
+<< /Names [ (HD.2870) 3792 0 R (HD.2871) 3793 0 R (HD.2872) 3794 0 R (HD.2873) 3795 0 R (HD.2874) 3796 0 R (HD.2875) 3797 0 R (HD.2876) 3798 0 R (HD.2877) 3799 0 R (HD.2878) 3800 0 R (HD.2879) 3801 0 R (HD.288) 927 0 R (HD.2880) 3806 0 R (HD.2881) 3807 0 R (HD.2882) 3808 0 R (HD.2883) 3809 0 R (HD.2884) 3810 0 R (HD.2885) 3811 0 R (HD.2886) 3812 0 R (HD.2887) 3813 0 R (HD.2888) 3814 0 R (HD.2889) 3815 0 R (HD.289) 928 0 R (HD.2890) 3816 0 R (HD.2891) 3817 0 R (HD.2892) 3818 0 R (HD.2893) 3819 0 R (HD.2894) 3820 0 R (HD.2895) 3821 0 R (HD.2896) 3822 0 R (HD.2897) 3823 0 R (HD.2898) 3824 0 R (HD.2899) 3825 0 R ] /Limits [ (HD.2870) (HD.2899) ] >>
endobj
4454 0 obj
-<< /Names [ (HD.771) 1450 0 R (HD.772) 1451 0 R (HD.773) 1452 0 R (HD.774) 1453 0 R (HD.775) 1454 0 R (HD.776) 1455 0 R (HD.777) 1456 0 R (HD.778) 1457 0 R (HD.779) 1458 0 R (HD.78) 688 0 R (HD.780) 1459 0 R (HD.781) 1460 0 R (HD.782) 1461 0 R (HD.783) 1462 0 R (HD.784) 1463 0 R (HD.785) 1464 0 R (HD.786) 1465 0 R (HD.787) 1466 0 R (HD.788) 1467 0 R (HD.789) 1468 0 R (HD.79) 689 0 R (HD.790) 1469 0 R (HD.791) 1470 0 R (HD.792) 1471 0 R (HD.793) 1476 0 R (HD.794) 1477 0 R (HD.795) 1478 0 R (HD.796) 1479 0 R (HD.797) 1480 0 R (HD.798) 1481 0 R (HD.799) 1482 0 R (HD.8) 614 0 R ] /Limits [ (HD.771) (HD.8) ] >>
+<< /Names [ (HD.29) 635 0 R (HD.290) 929 0 R (HD.2900) 3826 0 R (HD.2901) 3827 0 R (HD.2902) 3828 0 R (HD.2903) 3829 0 R (HD.2904) 3830 0 R (HD.2905) 3831 0 R (HD.2906) 3832 0 R (HD.2907) 3833 0 R (HD.2908) 3834 0 R (HD.2909) 3835 0 R (HD.291) 930 0 R (HD.2910) 3836 0 R (HD.2911) 3837 0 R (HD.2912) 3838 0 R (HD.2913) 3839 0 R (HD.2914) 3840 0 R (HD.2915) 3841 0 R (HD.2916) 3842 0 R (HD.2917) 3843 0 R (HD.2918) 3844 0 R (HD.2919) 3845 0 R (HD.292) 931 0 R (HD.2920) 3846 0 R (HD.2921) 3847 0 R (HD.2922) 3848 0 R (HD.2923) 3849 0 R (HD.2924) 3850 0 R (HD.2925) 3851 0 R (HD.2926) 3852 0 R (HD.2927) 3853 0 R ] /Limits [ (HD.29) (HD.2927) ] >>
endobj
4455 0 obj
-<< /Names [ (HD.80) 690 0 R (HD.800) 1483 0 R (HD.801) 1484 0 R (HD.802) 1485 0 R (HD.803) 1486 0 R (HD.804) 1487 0 R (HD.805) 1488 0 R (HD.806) 1489 0 R (HD.807) 1490 0 R (HD.808) 1491 0 R (HD.809) 1492 0 R (HD.81) 691 0 R (HD.810) 1493 0 R (HD.811) 1494 0 R (HD.812) 1495 0 R (HD.813) 1496 0 R (HD.814) 1497 0 R (HD.815) 1498 0 R (HD.816) 1499 0 R (HD.817) 1500 0 R (HD.818) 1501 0 R (HD.819) 1502 0 R (HD.82) 692 0 R (HD.820) 1503 0 R (HD.821) 1504 0 R (HD.822) 1505 0 R (HD.823) 1506 0 R (HD.824) 1507 0 R (HD.825) 1508 0 R (HD.826) 1509 0 R (HD.827) 1510 0 R (HD.828) 1511 0 R ] /Limits [ (HD.80) (HD.828) ] >>
+<< /Names [ (HD.2928) 3854 0 R (HD.2929) 3855 0 R (HD.293) 932 0 R (HD.2930) 3856 0 R (HD.2931) 3857 0 R (HD.2932) 3858 0 R (HD.2933) 3863 0 R (HD.2934) 3864 0 R (HD.2935) 3865 0 R (HD.2936) 3866 0 R (HD.2937) 3867 0 R (HD.2938) 3868 0 R (HD.2939) 3869 0 R (HD.294) 933 0 R (HD.2940) 3870 0 R (HD.2941) 3871 0 R (HD.2942) 3872 0 R (HD.2943) 3873 0 R (HD.2944) 3874 0 R (HD.2945) 3875 0 R (HD.2946) 3876 0 R (HD.2947) 3877 0 R (HD.2948) 3878 0 R (HD.2949) 3879 0 R (HD.295) 934 0 R (HD.2950) 3880 0 R (HD.2951) 3881 0 R (HD.2952) 3882 0 R (HD.2953) 3883 0 R (HD.2954) 3884 0 R (HD.2955) 3885 0 R (HD.2956) 3886 0 R ] /Limits [ (HD.2928) (HD.2956) ] >>
endobj
4456 0 obj
-<< /Names [ (HD.829) 1512 0 R (HD.83) 693 0 R (HD.830) 1513 0 R (HD.831) 1514 0 R (HD.832) 1515 0 R (HD.833) 1516 0 R (HD.834) 1517 0 R (HD.835) 1518 0 R (HD.836) 1519 0 R (HD.837) 1520 0 R (HD.838) 1521 0 R (HD.839) 1522 0 R (HD.84) 698 0 R (HD.840) 1523 0 R (HD.841) 1524 0 R (HD.842) 1525 0 R (HD.843) 1526 0 R (HD.844) 1532 0 R (HD.845) 1533 0 R (HD.846) 1534 0 R (HD.847) 1535 0 R (HD.848) 1536 0 R (HD.849) 1537 0 R (HD.85) 699 0 R (HD.850) 1538 0 R (HD.851) 1539 0 R (HD.852) 1540 0 R (HD.853) 1541 0 R (HD.854) 1542 0 R (HD.855) 1543 0 R (HD.856) 1544 0 R (HD.857) 1545 0 R ] /Limits [ (HD.829) (HD.857) ] >>
+<< /Names [ (HD.2957) 3887 0 R (HD.2958) 3888 0 R (HD.2959) 3889 0 R (HD.296) 935 0 R (HD.2960) 3890 0 R (HD.2961) 3891 0 R (HD.2962) 3892 0 R (HD.2963) 3893 0 R (HD.2964) 3894 0 R (HD.2965) 3895 0 R (HD.2966) 3896 0 R (HD.2967) 3897 0 R (HD.2968) 3898 0 R (HD.2969) 3899 0 R (HD.297) 936 0 R (HD.2970) 3900 0 R (HD.2971) 3901 0 R (HD.2972) 3902 0 R (HD.2973) 3903 0 R (HD.2974) 3904 0 R (HD.2975) 3905 0 R (HD.2976) 3906 0 R (HD.2977) 3907 0 R (HD.2978) 3908 0 R (HD.2979) 3909 0 R (HD.298) 937 0 R (HD.2980) 3910 0 R (HD.2981) 3911 0 R (HD.2982) 3912 0 R (HD.2983) 3913 0 R (HD.2984) 3914 0 R (HD.2985) 3915 0 R ] /Limits [ (HD.2957) (HD.2985) ] >>
endobj
4457 0 obj
-<< /Names [ (HD.858) 1546 0 R (HD.859) 1547 0 R (HD.86) 700 0 R (HD.860) 1548 0 R (HD.861) 1549 0 R (HD.862) 1550 0 R (HD.863) 1551 0 R (HD.864) 1552 0 R (HD.865) 1553 0 R (HD.866) 1554 0 R (HD.867) 1555 0 R (HD.868) 1556 0 R (HD.869) 1557 0 R (HD.87) 701 0 R (HD.870) 1558 0 R (HD.871) 1559 0 R (HD.872) 1560 0 R (HD.873) 1561 0 R (HD.874) 1562 0 R (HD.875) 1563 0 R (HD.876) 1564 0 R (HD.877) 1565 0 R (HD.878) 1566 0 R (HD.879) 1567 0 R (HD.88) 702 0 R (HD.880) 1568 0 R (HD.881) 1569 0 R (HD.882) 1570 0 R (HD.883) 1577 0 R (HD.884) 1578 0 R (HD.885) 1579 0 R (HD.886) 1580 0 R ] /Limits [ (HD.858) (HD.886) ] >>
+<< /Names [ (HD.2986) 3916 0 R (HD.2987) 3917 0 R (HD.2988) 3918 0 R (HD.2989) 3919 0 R (HD.299) 938 0 R (HD.2990) 3920 0 R (HD.2991) 3921 0 R (HD.2992) 3926 0 R (HD.2993) 3927 0 R (HD.2994) 3928 0 R (HD.2995) 3929 0 R (HD.2996) 3930 0 R (HD.2997) 3931 0 R (HD.2998) 3932 0 R (HD.2999) 3933 0 R (HD.3) 609 0 R (HD.30) 636 0 R (HD.300) 939 0 R (HD.3000) 3934 0 R (HD.3001) 3935 0 R (HD.3002) 3936 0 R (HD.3003) 3937 0 R (HD.3004) 3938 0 R (HD.3005) 3939 0 R (HD.3006) 3940 0 R (HD.3007) 3941 0 R (HD.3008) 3942 0 R (HD.3009) 3943 0 R (HD.301) 940 0 R (HD.3010) 3944 0 R (HD.3011) 3945 0 R (HD.3012) 3946 0 R ] /Limits [ (HD.2986) (HD.3012) ] >>
endobj
4458 0 obj
-<< /Names [ (HD.887) 1581 0 R (HD.888) 1582 0 R (HD.889) 1583 0 R (HD.89) 703 0 R (HD.890) 1584 0 R (HD.891) 1585 0 R (HD.892) 1586 0 R (HD.893) 1587 0 R (HD.894) 1588 0 R (HD.895) 1589 0 R (HD.896) 1590 0 R (HD.897) 1591 0 R (HD.898) 1592 0 R (HD.899) 1593 0 R (HD.9) 615 0 R (HD.90) 704 0 R (HD.900) 1594 0 R (HD.901) 1595 0 R (HD.902) 1596 0 R (HD.903) 1597 0 R (HD.904) 1598 0 R (HD.905) 1599 0 R (HD.906) 1600 0 R (HD.907) 1601 0 R (HD.908) 1602 0 R (HD.909) 1603 0 R (HD.91) 705 0 R (HD.910) 1604 0 R (HD.911) 1605 0 R (HD.912) 1606 0 R (HD.913) 1607 0 R (HD.914) 1608 0 R ] /Limits [ (HD.887) (HD.914) ] >>
+<< /Names [ (HD.3013) 3947 0 R (HD.3014) 3948 0 R (HD.3015) 3949 0 R (HD.3016) 3950 0 R (HD.3017) 3951 0 R (HD.3018) 3952 0 R (HD.3019) 3953 0 R (HD.302) 941 0 R (HD.3020) 3954 0 R (HD.3021) 3955 0 R (HD.3022) 3956 0 R (HD.3023) 3957 0 R (HD.3024) 3958 0 R (HD.3025) 3959 0 R (HD.3026) 3960 0 R (HD.3027) 3961 0 R (HD.3028) 3962 0 R (HD.3029) 3963 0 R (HD.303) 942 0 R (HD.3030) 3964 0 R (HD.3031) 3965 0 R (HD.3032) 3966 0 R (HD.3033) 3967 0 R (HD.3034) 3968 0 R (HD.3035) 3969 0 R (HD.3036) 3970 0 R (HD.3037) 3971 0 R (HD.3038) 3972 0 R (HD.3039) 3973 0 R (HD.304) 943 0 R (HD.3040) 3974 0 R (HD.3041) 3975 0 R ] /Limits [ (HD.3013) (HD.3041) ] >>
endobj
4459 0 obj
-<< /Names [ (HD.915) 1609 0 R (HD.916) 1610 0 R (HD.917) 1611 0 R (HD.918) 1612 0 R (HD.919) 1613 0 R (HD.92) 706 0 R (HD.920) 1614 0 R (HD.921) 1615 0 R (HD.922) 1616 0 R (HD.923) 1617 0 R (HD.924) 1618 0 R (HD.925) 1619 0 R (HD.926) 1620 0 R (HD.927) 1621 0 R (HD.928) 1622 0 R (HD.929) 1623 0 R (HD.93) 707 0 R (HD.930) 1628 0 R (HD.931) 1629 0 R (HD.932) 1630 0 R (HD.933) 1631 0 R (HD.934) 1632 0 R (HD.935) 1633 0 R (HD.936) 1634 0 R (HD.937) 1635 0 R (HD.938) 1636 0 R (HD.939) 1637 0 R (HD.94) 708 0 R (HD.940) 1638 0 R (HD.941) 1639 0 R (HD.942) 1640 0 R (HD.943) 1641 0 R ] /Limits [ (HD.915) (HD.943) ] >>
+<< /Names [ (HD.3042) 3976 0 R (HD.3043) 3977 0 R (HD.3044) 3978 0 R (HD.3045) 3979 0 R (HD.3046) 3980 0 R (HD.3047) 3981 0 R (HD.3048) 3982 0 R (HD.3049) 3983 0 R (HD.305) 944 0 R (HD.3050) 3984 0 R (HD.3051) 3985 0 R (HD.3052) 3990 0 R (HD.3053) 3991 0 R (HD.3054) 3992 0 R (HD.3055) 3993 0 R (HD.3056) 3994 0 R (HD.3057) 3995 0 R (HD.3058) 3996 0 R (HD.3059) 3997 0 R (HD.306) 945 0 R (HD.3060) 3998 0 R (HD.3061) 3999 0 R (HD.3062) 4000 0 R (HD.3063) 4001 0 R (HD.3064) 4002 0 R (HD.3065) 4003 0 R (HD.3066) 4004 0 R (HD.3067) 4005 0 R (HD.3068) 4006 0 R (HD.3069) 4007 0 R (HD.307) 946 0 R (HD.3070) 4008 0 R ] /Limits [ (HD.3042) (HD.3070) ] >>
endobj
4460 0 obj
-<< /Names [ (HD.944) 1642 0 R (HD.945) 1643 0 R (HD.946) 1644 0 R (HD.947) 1645 0 R (HD.948) 1646 0 R (HD.949) 1647 0 R (HD.95) 709 0 R (HD.950) 1648 0 R (HD.951) 1649 0 R (HD.952) 1650 0 R (HD.953) 1651 0 R (HD.954) 1652 0 R (HD.955) 1653 0 R (HD.956) 1654 0 R (HD.957) 1655 0 R (HD.958) 1656 0 R (HD.959) 1657 0 R (HD.96) 710 0 R (HD.960) 1658 0 R (HD.961) 1659 0 R (HD.962) 1660 0 R (HD.963) 1661 0 R (HD.964) 1662 0 R (HD.965) 1663 0 R (HD.966) 1664 0 R (HD.967) 1665 0 R (HD.968) 1666 0 R (HD.969) 1667 0 R (HD.97) 711 0 R (HD.970) 1668 0 R (HD.971) 1669 0 R (HD.972) 1674 0 R ] /Limits [ (HD.944) (HD.972) ] >>
+<< /Names [ (HD.3071) 4009 0 R (HD.3072) 4010 0 R (HD.3073) 4011 0 R (HD.3074) 4012 0 R (HD.3075) 4013 0 R (HD.3076) 4014 0 R (HD.3077) 4015 0 R (HD.3078) 4016 0 R (HD.3079) 4017 0 R (HD.308) 947 0 R (HD.3080) 4018 0 R (HD.3081) 4019 0 R (HD.3082) 4020 0 R (HD.3083) 4021 0 R (HD.3084) 4022 0 R (HD.3085) 4023 0 R (HD.3086) 4024 0 R (HD.3087) 4025 0 R (HD.3088) 4026 0 R (HD.3089) 4027 0 R (HD.309) 948 0 R (HD.3090) 4028 0 R (HD.3091) 4029 0 R (HD.3092) 4030 0 R (HD.3093) 4031 0 R (HD.3094) 4032 0 R (HD.3095) 4033 0 R (HD.3096) 4034 0 R (HD.3097) 4035 0 R (HD.3098) 4036 0 R (HD.3099) 4037 0 R (HD.31) 637 0 R ] /Limits [ (HD.3071) (HD.31) ] >>
endobj
4461 0 obj
-<< /Names [ (HD.973) 1675 0 R (HD.974) 1676 0 R (HD.975) 1677 0 R (HD.976) 1678 0 R (HD.977) 1679 0 R (HD.978) 1680 0 R (HD.979) 1681 0 R (HD.98) 712 0 R (HD.980) 1682 0 R (HD.981) 1683 0 R (HD.982) 1684 0 R (HD.983) 1685 0 R (HD.984) 1686 0 R (HD.985) 1687 0 R (HD.986) 1688 0 R (HD.987) 1689 0 R (HD.988) 1690 0 R (HD.989) 1691 0 R (HD.99) 713 0 R (HD.990) 1692 0 R (HD.991) 1693 0 R (HD.992) 1694 0 R (HD.993) 1695 0 R (HD.994) 1696 0 R (HD.995) 1697 0 R (HD.996) 1698 0 R (HD.997) 1699 0 R (HD.998) 1700 0 R (HD.999) 1701 0 R (Hfootnote.1) 340 0 R (Hfootnote.10) 406 0 R (Hfootnote.11) 407 0 R ] /Limits [ (HD.973) (Hfootnote.11) ] >>
+<< /Names [ (HD.310) 949 0 R (HD.3100) 4038 0 R (HD.3101) 4039 0 R (HD.3102) 4040 0 R (HD.3103) 4041 0 R (HD.3104) 4042 0 R (HD.3105) 4043 0 R (HD.3106) 4044 0 R (HD.3107) 4045 0 R (HD.3108) 4046 0 R (HD.3109) 4051 0 R (HD.311) 950 0 R (HD.3110) 4052 0 R (HD.3111) 4053 0 R (HD.3112) 4054 0 R (HD.3113) 4055 0 R (HD.3114) 4056 0 R (HD.3115) 4057 0 R (HD.3116) 4058 0 R (HD.3117) 4059 0 R (HD.3118) 4060 0 R (HD.312) 951 0 R (HD.313) 952 0 R (HD.314) 953 0 R (HD.315) 954 0 R (HD.316) 955 0 R (HD.317) 956 0 R (HD.318) 957 0 R (HD.319) 958 0 R (HD.32) 638 0 R (HD.320) 959 0 R (HD.321) 966 0 R ] /Limits [ (HD.310) (HD.321) ] >>
endobj
4462 0 obj
-<< /Names [ (Hfootnote.12) 408 0 R (Hfootnote.13) 418 0 R (Hfootnote.14) 430 0 R (Hfootnote.15) 431 0 R (Hfootnote.16) 440 0 R (Hfootnote.17) 441 0 R (Hfootnote.18) 448 0 R (Hfootnote.19) 449 0 R (Hfootnote.2) 344 0 R (Hfootnote.20) 467 0 R (Hfootnote.21) 478 0 R (Hfootnote.22) 498 0 R (Hfootnote.23) 499 0 R (Hfootnote.24) 500 0 R (Hfootnote.25) 501 0 R (Hfootnote.26) 531 0 R (Hfootnote.27) 532 0 R (Hfootnote.28) 545 0 R (Hfootnote.29) 546 0 R (Hfootnote.3) 368 0 R (Hfootnote.30) 547 0 R (Hfootnote.31) 566 0 R (Hfootnote.32) 598 0 R (Hfootnote.33) 595 0 R (Hfootnote.34) 596 0 R (Hfootnote.35) 597 0 R (Hfootnote.36) 1571 0 R (Hfootnote.37) 2477 0 R (Hfootnote.38) 2559 0 R (Hfootnote.39) 2560 0 R (Hfootnote.4) 369 0 R (Hfootnote.40) 2773 0 R ] /Limits [ (Hfootnote.12) (Hfootnote.40) ] >>
+<< /Names [ (HD.322) 967 0 R (HD.323) 968 0 R (HD.324) 969 0 R (HD.325) 970 0 R (HD.326) 971 0 R (HD.327) 972 0 R (HD.328) 973 0 R (HD.329) 974 0 R (HD.33) 639 0 R (HD.330) 975 0 R (HD.331) 976 0 R (HD.332) 977 0 R (HD.333) 978 0 R (HD.334) 979 0 R (HD.335) 980 0 R (HD.336) 981 0 R (HD.337) 982 0 R (HD.338) 983 0 R (HD.339) 984 0 R (HD.34) 640 0 R (HD.340) 985 0 R (HD.341) 986 0 R (HD.342) 987 0 R (HD.343) 988 0 R (HD.344) 989 0 R (HD.345) 990 0 R (HD.346) 991 0 R (HD.347) 992 0 R (HD.348) 993 0 R (HD.349) 994 0 R (HD.35) 641 0 R (HD.350) 995 0 R ] /Limits [ (HD.322) (HD.350) ] >>
endobj
4463 0 obj
-<< /Names [ (Hfootnote.41) 3099 0 R (Hfootnote.42) 3190 0 R (Hfootnote.43) 3359 0 R (Hfootnote.5) 370 0 R (Hfootnote.6) 385 0 R (Hfootnote.7) 386 0 R (Hfootnote.8) 387 0 R (Hfootnote.9) 405 0 R (page.1) 315 0 R (page.10) 454 0 R (page.11) 459 0 R (page.12) 466 0 R (page.13) 477 0 R (page.14) 483 0 R (page.15) 487 0 R (page.16) 495 0 R (page.17) 506 0 R (page.18) 517 0 R (page.19) 522 0 R (page.2) 355 0 R (page.20) 530 0 R (page.21) 543 0 R (page.22) 555 0 R (page.23) 565 0 R (page.24) 571 0 R (page.25) 575 0 R (page.26) 579 0 R (page.27) 585 0 R (page.28) 594 0 R (page.29) 603 0 R (page.3) 365 0 R (page.30) 646 0 R ] /Limits [ (Hfootnote.41) (page.30) ] >>
+<< /Names [ (HD.351) 996 0 R (HD.352) 997 0 R (HD.353) 1003 0 R (HD.354) 1004 0 R (HD.355) 1005 0 R (HD.356) 1006 0 R (HD.357) 1007 0 R (HD.358) 1008 0 R (HD.359) 1009 0 R (HD.36) 642 0 R (HD.360) 1010 0 R (HD.361) 1011 0 R (HD.362) 1012 0 R (HD.363) 1013 0 R (HD.364) 1014 0 R (HD.365) 1015 0 R (HD.366) 1016 0 R (HD.367) 1017 0 R (HD.368) 1018 0 R (HD.369) 1019 0 R (HD.37) 647 0 R (HD.370) 1020 0 R (HD.371) 1021 0 R (HD.372) 1022 0 R (HD.373) 1023 0 R (HD.374) 1024 0 R (HD.375) 1025 0 R (HD.376) 1026 0 R (HD.377) 1027 0 R (HD.378) 1028 0 R (HD.379) 1029 0 R (HD.38) 648 0 R ] /Limits [ (HD.351) (HD.38) ] >>
endobj
4464 0 obj
-<< /Names [ (page.31) 697 0 R (page.32) 753 0 R (page.33) 781 0 R (page.34) 806 0 R (page.35) 827 0 R (page.36) 869 0 R (page.37) 905 0 R (page.38) 965 0 R (page.39) 1002 0 R (page.4) 384 0 R (page.40) 1058 0 R (page.41) 1121 0 R (page.42) 1181 0 R (page.43) 1248 0 R (page.44) 1314 0 R (page.45) 1361 0 R (page.46) 1417 0 R (page.47) 1475 0 R (page.48) 1531 0 R (page.49) 1576 0 R (page.5) 402 0 R (page.50) 1627 0 R (page.51) 1673 0 R (page.52) 1735 0 R (page.53) 1781 0 R (page.54) 1843 0 R (page.55) 1898 0 R (page.56) 1950 0 R (page.57) 1992 0 R (page.58) 2049 0 R (page.59) 2114 0 R (page.6) 417 0 R ] /Limits [ (page.31) (page.6) ] >>
+<< /Names [ (HD.380) 1030 0 R (HD.381) 1031 0 R (HD.382) 1032 0 R (HD.383) 1033 0 R (HD.384) 1034 0 R (HD.385) 1035 0 R (HD.386) 1036 0 R (HD.387) 1037 0 R (HD.388) 1038 0 R (HD.389) 1039 0 R (HD.39) 649 0 R (HD.390) 1040 0 R (HD.391) 1041 0 R (HD.392) 1042 0 R (HD.393) 1043 0 R (HD.394) 1044 0 R (HD.395) 1045 0 R (HD.396) 1046 0 R (HD.397) 1047 0 R (HD.398) 1048 0 R (HD.399) 1049 0 R (HD.4) 610 0 R (HD.40) 650 0 R (HD.400) 1050 0 R (HD.401) 1051 0 R (HD.402) 1052 0 R (HD.403) 1053 0 R (HD.404) 1054 0 R (HD.405) 1059 0 R (HD.406) 1060 0 R (HD.407) 1061 0 R (HD.408) 1062 0 R ] /Limits [ (HD.380) (HD.408) ] >>
endobj
4465 0 obj
-<< /Names [ (page.60) 2169 0 R (page.61) 2221 0 R (page.62) 2258 0 R (page.63) 2298 0 R (page.64) 2338 0 R (page.65) 2390 0 R (page.66) 2433 0 R (page.67) 2482 0 R (page.68) 2531 0 R (page.69) 2565 0 R (page.7) 427 0 R (page.70) 2621 0 R (page.71) 2684 0 R (page.72) 2731 0 R (page.73) 2778 0 R (page.74) 2834 0 R (page.75) 2889 0 R (page.76) 2932 0 R (page.77) 2991 0 R (page.78) 3051 0 R (page.79) 3104 0 R (page.8) 438 0 R (page.80) 3142 0 R (page.81) 3195 0 R (page.82) 3248 0 R (page.83) 3308 0 R (page.84) 3364 0 R (page.85) 3431 0 R (page.86) 3486 0 R (page.87) 3525 0 R (page.88) 3576 0 R (page.89) 3621 0 R ] /Limits [ (page.60) (page.89) ] >>
+<< /Names [ (HD.409) 1063 0 R (HD.41) 651 0 R (HD.410) 1064 0 R (HD.411) 1065 0 R (HD.412) 1066 0 R (HD.413) 1067 0 R (HD.414) 1068 0 R (HD.415) 1069 0 R (HD.416) 1070 0 R (HD.417) 1071 0 R (HD.418) 1072 0 R (HD.419) 1073 0 R (HD.42) 652 0 R (HD.420) 1074 0 R (HD.421) 1075 0 R (HD.422) 1076 0 R (HD.423) 1077 0 R (HD.424) 1078 0 R (HD.425) 1079 0 R (HD.426) 1080 0 R (HD.427) 1081 0 R (HD.428) 1082 0 R (HD.429) 1083 0 R (HD.43) 653 0 R (HD.430) 1084 0 R (HD.431) 1085 0 R (HD.432) 1086 0 R (HD.433) 1087 0 R (HD.434) 1088 0 R (HD.435) 1089 0 R (HD.436) 1090 0 R (HD.437) 1091 0 R ] /Limits [ (HD.409) (HD.437) ] >>
endobj
4466 0 obj
-<< /Names [ (page.9) 447 0 R (page.90) 3675 0 R (page.91) 3723 0 R (page.92) 3783 0 R (page.93) 3840 0 R (page.94) 3903 0 R (page.95) 3967 0 R (page.96) 4028 0 R (page.97) 4054 0 R (page.98) 4118 0 R (page.99) 4142 0 R (piton:passe) 439 0 R (piton:transpose) 429 0 R (section*.1) 2270 0 R (section*.10) 2690 0 R (section*.11) 2695 0 R (section*.12) 2740 0 R (section*.13) 2742 0 R (section*.14) 2877 0 R (section*.15) 2880 0 R (section*.16) 2891 0 R (section*.17) 2921 0 R (section*.18) 2939 0 R (section*.19) 2969 0 R (section*.2) 2309 0 R (section*.20) 3016 0 R (section*.21) 3018 0 R (section*.22) 3107 0 R (section*.23) 3119 0 R (section*.24) 3124 0 R (section*.25) 3126 0 R (section*.26) 3143 0 R ] /Limits [ (page.9) (section*.26) ] >>
+<< /Names [ (HD.438) 1092 0 R (HD.439) 1093 0 R (HD.44) 654 0 R (HD.440) 1094 0 R (HD.441) 1095 0 R (HD.442) 1096 0 R (HD.443) 1097 0 R (HD.444) 1098 0 R (HD.445) 1099 0 R (HD.446) 1100 0 R (HD.447) 1101 0 R (HD.448) 1102 0 R (HD.449) 1103 0 R (HD.45) 655 0 R (HD.450) 1104 0 R (HD.451) 1105 0 R (HD.452) 1106 0 R (HD.453) 1107 0 R (HD.454) 1108 0 R (HD.455) 1109 0 R (HD.456) 1110 0 R (HD.457) 1111 0 R (HD.458) 1112 0 R (HD.459) 1113 0 R (HD.46) 656 0 R (HD.460) 1114 0 R (HD.461) 1115 0 R (HD.462) 1116 0 R (HD.463) 1117 0 R (HD.464) 1122 0 R (HD.465) 1123 0 R (HD.466) 1124 0 R ] /Limits [ (HD.438) (HD.466) ] >>
endobj
4467 0 obj
-<< /Names [ (section*.27) 3242 0 R (section*.28) 3249 0 R (section*.29) 3254 0 R (section*.3) 2348 0 R (section*.30) 3267 0 R (section*.31) 4039 0 R (section*.32) 4040 0 R (section*.33) 4041 0 R (section*.34) 4042 0 R (section*.35) 4043 0 R (section*.36) 4044 0 R (section*.37) 4055 0 R (section*.38) 4056 0 R (section*.39) 4057 0 R (section*.4) 2425 0 R (section*.40) 4058 0 R (section*.41) 4059 0 R (section*.42) 4060 0 R (section*.43) 4061 0 R (section*.44) 4062 0 R (section*.45) 4063 0 R (section*.5) 2546 0 R (section*.6) 2611 0 R (section*.7) 2614 0 R (section*.8) 2616 0 R (section*.9) 2622 0 R (section.0.1) 5 0 R (section.0.10) 301 0 R (section.0.2) 9 0 R (section.0.3) 13 0 R (section.0.4) 33 0 R (section.0.5) 61 0 R ] /Limits [ (section*.27) (section.0.5) ] >>
+<< /Names [ (HD.467) 1125 0 R (HD.468) 1126 0 R (HD.469) 1127 0 R (HD.47) 657 0 R (HD.470) 1128 0 R (HD.471) 1129 0 R (HD.472) 1130 0 R (HD.473) 1131 0 R (HD.474) 1132 0 R (HD.475) 1133 0 R (HD.476) 1134 0 R (HD.477) 1135 0 R (HD.478) 1136 0 R (HD.479) 1137 0 R (HD.48) 658 0 R (HD.480) 1138 0 R (HD.481) 1139 0 R (HD.482) 1140 0 R (HD.483) 1141 0 R (HD.484) 1142 0 R (HD.485) 1143 0 R (HD.486) 1144 0 R (HD.487) 1145 0 R (HD.488) 1146 0 R (HD.489) 1147 0 R (HD.49) 659 0 R (HD.490) 1148 0 R (HD.491) 1149 0 R (HD.492) 1150 0 R (HD.493) 1151 0 R (HD.494) 1152 0 R (HD.495) 1153 0 R ] /Limits [ (HD.467) (HD.495) ] >>
endobj
4468 0 obj
-<< /Names [ (section.0.6) 141 0 R (section.0.7) 145 0 R (section.0.8) 169 0 R (section.0.9) 193 0 R (subsection.0.3.1) 17 0 R (subsection.0.3.2) 21 0 R (subsection.0.3.3) 25 0 R (subsection.0.3.4) 29 0 R (subsection.0.4.1) 37 0 R (subsection.0.4.2) 41 0 R (subsection.0.4.3) 57 0 R (subsection.0.5.1) 65 0 R (subsection.0.5.2) 77 0 R (subsection.0.5.3) 89 0 R (subsection.0.5.4) 93 0 R (subsection.0.5.5) 117 0 R (subsection.0.5.6) 133 0 R (subsection.0.5.7) 137 0 R (subsection.0.7.1) 149 0 R (subsection.0.7.2) 153 0 R (subsection.0.7.3) 157 0 R (subsection.0.7.4) 161 0 R (subsection.0.7.5) 165 0 R (subsection.0.8.1) 173 0 R (subsection.0.8.2) 177 0 R (subsection.0.8.3) 181 0 R (subsection.0.8.4) 185 0 R (subsection.0.8.5) 189 0 R (subsection.0.9.1) 197 0 R (subsection.0.9.2) 201 0 R (subsection.0.9.3) 261 0 R (subsubsection.0.4.2.1) 45 0 R ] /Limits [ (section.0.6) (subsubsection.0.4.2.1) ] >>
+<< /Names [ (HD.496) 1154 0 R (HD.497) 1155 0 R (HD.498) 1156 0 R (HD.499) 1157 0 R (HD.5) 611 0 R (HD.50) 660 0 R (HD.500) 1158 0 R (HD.501) 1159 0 R (HD.502) 1160 0 R (HD.503) 1161 0 R (HD.504) 1162 0 R (HD.505) 1163 0 R (HD.506) 1164 0 R (HD.507) 1165 0 R (HD.508) 1166 0 R (HD.509) 1167 0 R (HD.51) 661 0 R (HD.510) 1168 0 R (HD.511) 1169 0 R (HD.512) 1170 0 R (HD.513) 1171 0 R (HD.514) 1172 0 R (HD.515) 1173 0 R (HD.516) 1174 0 R (HD.517) 1175 0 R (HD.518) 1176 0 R (HD.519) 1182 0 R (HD.52) 662 0 R (HD.520) 1183 0 R (HD.521) 1184 0 R (HD.522) 1185 0 R (HD.523) 1186 0 R ] /Limits [ (HD.496) (HD.523) ] >>
endobj
4469 0 obj
-<< /Names [ (subsubsection.0.4.2.2) 49 0 R (subsubsection.0.4.2.3) 53 0 R (subsubsection.0.5.1.1) 69 0 R (subsubsection.0.5.1.2) 73 0 R (subsubsection.0.5.2.1) 81 0 R (subsubsection.0.5.2.2) 85 0 R (subsubsection.0.5.4.1) 97 0 R (subsubsection.0.5.4.2) 101 0 R (subsubsection.0.5.4.3) 105 0 R (subsubsection.0.5.4.4) 109 0 R (subsubsection.0.5.4.5) 113 0 R (subsubsection.0.5.5.1) 121 0 R (subsubsection.0.5.5.2) 125 0 R (subsubsection.0.5.5.3) 129 0 R (subsubsection.0.9.2.1) 205 0 R (subsubsection.0.9.2.10) 241 0 R (subsubsection.0.9.2.11) 245 0 R (subsubsection.0.9.2.12) 249 0 R (subsubsection.0.9.2.13) 253 0 R (subsubsection.0.9.2.14) 257 0 R (subsubsection.0.9.2.2) 209 0 R (subsubsection.0.9.2.3) 213 0 R (subsubsection.0.9.2.4) 217 0 R (subsubsection.0.9.2.5) 221 0 R (subsubsection.0.9.2.6) 225 0 R (subsubsection.0.9.2.7) 229 0 R (subsubsection.0.9.2.8) 233 0 R (subsubsection.0.9.2.9) 237 0 R (subsubsection.0.9.3.1) 265 0 R (subsubsection.0.9.3.2) 269 0 R (subsubsection.0.9.3.3) 273 0 R (subsubsection.0.9.3.4) 277 0 R ] /Limits [ (subsubsection.0.4.2.2) (subsubsection.0.9.3.4) ] >>
+<< /Names [ (HD.524) 1187 0 R (HD.525) 1188 0 R (HD.526) 1189 0 R (HD.527) 1190 0 R (HD.528) 1191 0 R (HD.529) 1192 0 R (HD.53) 663 0 R (HD.530) 1193 0 R (HD.531) 1194 0 R (HD.532) 1195 0 R (HD.533) 1196 0 R (HD.534) 1197 0 R (HD.535) 1198 0 R (HD.536) 1199 0 R (HD.537) 1200 0 R (HD.538) 1201 0 R (HD.539) 1202 0 R (HD.54) 664 0 R (HD.540) 1203 0 R (HD.541) 1204 0 R (HD.542) 1205 0 R (HD.543) 1206 0 R (HD.544) 1207 0 R (HD.545) 1208 0 R (HD.546) 1209 0 R (HD.547) 1210 0 R (HD.548) 1211 0 R (HD.549) 1212 0 R (HD.55) 665 0 R (HD.550) 1213 0 R (HD.551) 1214 0 R (HD.552) 1215 0 R ] /Limits [ (HD.524) (HD.552) ] >>
endobj
4470 0 obj
-<< /Names [ (subsubsection.0.9.3.5) 281 0 R (subsubsection.0.9.3.6) 285 0 R (subsubsection.0.9.3.7) 289 0 R (subsubsection.0.9.3.8) 293 0 R (subsubsection.0.9.3.9) 297 0 R (toc1.1) 305 0 R ] /Limits [ (subsubsection.0.9.3.5) (toc1.1) ] >>
+<< /Names [ (HD.553) 1216 0 R (HD.554) 1217 0 R (HD.555) 1218 0 R (HD.556) 1219 0 R (HD.557) 1220 0 R (HD.558) 1221 0 R (HD.559) 1222 0 R (HD.56) 666 0 R (HD.560) 1223 0 R (HD.561) 1224 0 R (HD.562) 1225 0 R (HD.563) 1226 0 R (HD.564) 1227 0 R (HD.565) 1228 0 R (HD.566) 1229 0 R (HD.567) 1230 0 R (HD.568) 1231 0 R (HD.569) 1232 0 R (HD.57) 667 0 R (HD.570) 1233 0 R (HD.571) 1234 0 R (HD.572) 1235 0 R (HD.573) 1236 0 R (HD.574) 1237 0 R (HD.575) 1238 0 R (HD.576) 1239 0 R (HD.577) 1240 0 R (HD.578) 1241 0 R (HD.579) 1242 0 R (HD.58) 668 0 R (HD.580) 1247 0 R (HD.581) 1248 0 R ] /Limits [ (HD.553) (HD.581) ] >>
endobj
4471 0 obj
-<< /Kids [ 4365 0 R 4366 0 R 4367 0 R 4368 0 R 4369 0 R 4370 0 R 4371 0 R 4372 0 R 4373 0 R 4374 0 R 4375 0 R 4376 0 R 4377 0 R 4378 0 R 4379 0 R 4380 0 R 4381 0 R 4382 0 R 4383 0 R 4384 0 R 4385 0 R 4386 0 R 4387 0 R 4388 0 R 4389 0 R 4390 0 R 4391 0 R 4392 0 R 4393 0 R 4394 0 R 4395 0 R 4396 0 R ] /Limits [ (Doc-Start) (HD.1919) ] >>
+<< /Names [ (HD.582) 1249 0 R (HD.583) 1250 0 R (HD.584) 1251 0 R (HD.585) 1252 0 R (HD.586) 1253 0 R (HD.587) 1254 0 R (HD.588) 1255 0 R (HD.589) 1256 0 R (HD.59) 669 0 R (HD.590) 1257 0 R (HD.591) 1258 0 R (HD.592) 1259 0 R (HD.593) 1260 0 R (HD.594) 1261 0 R (HD.595) 1262 0 R (HD.596) 1263 0 R (HD.597) 1264 0 R (HD.598) 1265 0 R (HD.599) 1266 0 R (HD.6) 612 0 R (HD.60) 670 0 R (HD.600) 1267 0 R (HD.601) 1268 0 R (HD.602) 1269 0 R (HD.603) 1270 0 R (HD.604) 1271 0 R (HD.605) 1272 0 R (HD.606) 1273 0 R (HD.607) 1274 0 R (HD.608) 1275 0 R (HD.609) 1276 0 R (HD.61) 671 0 R ] /Limits [ (HD.582) (HD.61) ] >>
endobj
4472 0 obj
-<< /Kids [ 4397 0 R 4398 0 R 4399 0 R 4400 0 R 4401 0 R 4402 0 R 4403 0 R 4404 0 R 4405 0 R 4406 0 R 4407 0 R 4408 0 R 4409 0 R 4410 0 R 4411 0 R 4412 0 R 4413 0 R 4414 0 R 4415 0 R 4416 0 R 4417 0 R 4418 0 R 4419 0 R 4420 0 R 4421 0 R 4422 0 R 4423 0 R 4424 0 R 4425 0 R 4426 0 R 4427 0 R 4428 0 R ] /Limits [ (HD.192) (HD.2840) ] >>
+<< /Names [ (HD.610) 1277 0 R (HD.611) 1278 0 R (HD.612) 1279 0 R (HD.613) 1280 0 R (HD.614) 1281 0 R (HD.615) 1282 0 R (HD.616) 1283 0 R (HD.617) 1284 0 R (HD.618) 1285 0 R (HD.619) 1286 0 R (HD.62) 672 0 R (HD.620) 1287 0 R (HD.621) 1288 0 R (HD.622) 1289 0 R (HD.623) 1290 0 R (HD.624) 1291 0 R (HD.625) 1292 0 R (HD.626) 1293 0 R (HD.627) 1294 0 R (HD.628) 1295 0 R (HD.629) 1296 0 R (HD.63) 673 0 R (HD.630) 1297 0 R (HD.631) 1298 0 R (HD.632) 1299 0 R (HD.633) 1300 0 R (HD.634) 1301 0 R (HD.635) 1302 0 R (HD.636) 1303 0 R (HD.637) 1304 0 R (HD.638) 1305 0 R (HD.639) 1306 0 R ] /Limits [ (HD.610) (HD.639) ] >>
endobj
4473 0 obj
-<< /Kids [ 4429 0 R 4430 0 R 4431 0 R 4432 0 R 4433 0 R 4434 0 R 4435 0 R 4436 0 R 4437 0 R 4438 0 R 4439 0 R 4440 0 R 4441 0 R 4442 0 R 4443 0 R 4444 0 R 4445 0 R 4446 0 R 4447 0 R 4448 0 R 4449 0 R 4450 0 R 4451 0 R 4452 0 R 4453 0 R 4454 0 R 4455 0 R 4456 0 R 4457 0 R 4458 0 R 4459 0 R 4460 0 R ] /Limits [ (HD.2841) (HD.972) ] >>
+<< /Names [ (HD.64) 674 0 R (HD.640) 1307 0 R (HD.641) 1308 0 R (HD.642) 1309 0 R (HD.643) 1314 0 R (HD.644) 1315 0 R (HD.645) 1316 0 R (HD.646) 1317 0 R (HD.647) 1318 0 R (HD.648) 1319 0 R (HD.649) 1320 0 R (HD.65) 675 0 R (HD.650) 1321 0 R (HD.651) 1322 0 R (HD.652) 1323 0 R (HD.653) 1324 0 R (HD.654) 1325 0 R (HD.655) 1326 0 R (HD.656) 1327 0 R (HD.657) 1328 0 R (HD.658) 1329 0 R (HD.659) 1330 0 R (HD.66) 676 0 R (HD.660) 1331 0 R (HD.661) 1332 0 R (HD.662) 1333 0 R (HD.663) 1334 0 R (HD.664) 1335 0 R (HD.665) 1336 0 R (HD.666) 1337 0 R (HD.667) 1338 0 R (HD.668) 1339 0 R ] /Limits [ (HD.64) (HD.668) ] >>
endobj
4474 0 obj
-<< /Kids [ 4461 0 R 4462 0 R 4463 0 R 4464 0 R 4465 0 R 4466 0 R 4467 0 R 4468 0 R 4469 0 R 4470 0 R ] /Limits [ (HD.973) (toc1.1) ] >>
+<< /Names [ (HD.669) 1340 0 R (HD.67) 677 0 R (HD.670) 1341 0 R (HD.671) 1342 0 R (HD.672) 1343 0 R (HD.673) 1344 0 R (HD.674) 1345 0 R (HD.675) 1346 0 R (HD.676) 1347 0 R (HD.677) 1348 0 R (HD.678) 1349 0 R (HD.679) 1350 0 R (HD.68) 678 0 R (HD.680) 1351 0 R (HD.681) 1352 0 R (HD.682) 1353 0 R (HD.683) 1354 0 R (HD.684) 1355 0 R (HD.685) 1356 0 R (HD.686) 1357 0 R (HD.687) 1362 0 R (HD.688) 1363 0 R (HD.689) 1364 0 R (HD.69) 679 0 R (HD.690) 1365 0 R (HD.691) 1366 0 R (HD.692) 1367 0 R (HD.693) 1368 0 R (HD.694) 1369 0 R (HD.695) 1370 0 R (HD.696) 1371 0 R (HD.697) 1372 0 R ] /Limits [ (HD.669) (HD.697) ] >>
endobj
4475 0 obj
-<< /Kids [ 4471 0 R 4472 0 R 4473 0 R 4474 0 R ] /Limits [ (Doc-Start) (toc1.1) ] >>
+<< /Names [ (HD.698) 1373 0 R (HD.699) 1374 0 R (HD.7) 613 0 R (HD.70) 680 0 R (HD.700) 1375 0 R (HD.701) 1376 0 R (HD.702) 1377 0 R (HD.703) 1378 0 R (HD.704) 1379 0 R (HD.705) 1380 0 R (HD.706) 1381 0 R (HD.707) 1382 0 R (HD.708) 1383 0 R (HD.709) 1384 0 R (HD.71) 681 0 R (HD.710) 1385 0 R (HD.711) 1386 0 R (HD.712) 1387 0 R (HD.713) 1388 0 R (HD.714) 1389 0 R (HD.715) 1390 0 R (HD.716) 1391 0 R (HD.717) 1392 0 R (HD.718) 1393 0 R (HD.719) 1394 0 R (HD.72) 682 0 R (HD.720) 1395 0 R (HD.721) 1396 0 R (HD.722) 1397 0 R (HD.723) 1398 0 R (HD.724) 1399 0 R (HD.725) 1400 0 R ] /Limits [ (HD.698) (HD.725) ] >>
endobj
4476 0 obj
-<< /Dests 4475 0 R >>
+<< /Names [ (HD.726) 1401 0 R (HD.727) 1402 0 R (HD.728) 1403 0 R (HD.729) 1404 0 R (HD.73) 683 0 R (HD.730) 1405 0 R (HD.731) 1406 0 R (HD.732) 1407 0 R (HD.733) 1408 0 R (HD.734) 1409 0 R (HD.735) 1410 0 R (HD.736) 1411 0 R (HD.737) 1416 0 R (HD.738) 1417 0 R (HD.739) 1418 0 R (HD.74) 684 0 R (HD.740) 1419 0 R (HD.741) 1420 0 R (HD.742) 1421 0 R (HD.743) 1422 0 R (HD.744) 1423 0 R (HD.745) 1424 0 R (HD.746) 1425 0 R (HD.747) 1426 0 R (HD.748) 1427 0 R (HD.749) 1428 0 R (HD.75) 685 0 R (HD.750) 1429 0 R (HD.751) 1430 0 R (HD.752) 1431 0 R (HD.753) 1432 0 R (HD.754) 1433 0 R ] /Limits [ (HD.726) (HD.754) ] >>
endobj
4477 0 obj
-<< /Type /Catalog /Pages 4363 0 R /Outlines 4364 0 R /Names 4476 0 R /PageMode/UseOutlines /OpenAction 308 0 R >>
+<< /Names [ (HD.755) 1434 0 R (HD.756) 1435 0 R (HD.757) 1436 0 R (HD.758) 1437 0 R (HD.759) 1438 0 R (HD.76) 686 0 R (HD.760) 1439 0 R (HD.761) 1440 0 R (HD.762) 1441 0 R (HD.763) 1442 0 R (HD.764) 1443 0 R (HD.765) 1444 0 R (HD.766) 1445 0 R (HD.767) 1446 0 R (HD.768) 1447 0 R (HD.769) 1448 0 R (HD.77) 687 0 R (HD.770) 1449 0 R (HD.771) 1450 0 R (HD.772) 1451 0 R (HD.773) 1452 0 R (HD.774) 1453 0 R (HD.775) 1454 0 R (HD.776) 1455 0 R (HD.777) 1456 0 R (HD.778) 1457 0 R (HD.779) 1458 0 R (HD.78) 688 0 R (HD.780) 1459 0 R (HD.781) 1460 0 R (HD.782) 1461 0 R (HD.783) 1462 0 R ] /Limits [ (HD.755) (HD.783) ] >>
endobj
4478 0 obj
-<< /Author(\376\377\000F\000.\000\040\000P\000a\000n\000t\000i\000g\000n\000y\000\040\000,\000\040\000f\000p\000a\000n\000t\000i\000g\000n\000y\000@\000w\000a\000n\000a\000d\000o\000o\000.\000f\000r)/Title(\376\377\000T\000h\000e\000\040\000p\000a\000c\000k\000a\000g\000e\000\040\000p\000i\000t\000o\000n)/Subject()/Creator(LaTeX with hyperref)/Keywords() /Producer (LuaTeX-1.18.0) /CreationDate (D:20240330194724+01'00') /ModDate (D:20240330194724+01'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.18.0 (MiKTeX 24.3)) >>
+<< /Names [ (HD.784) 1463 0 R (HD.785) 1464 0 R (HD.786) 1465 0 R (HD.787) 1466 0 R (HD.788) 1467 0 R (HD.789) 1468 0 R (HD.79) 689 0 R (HD.790) 1469 0 R (HD.791) 1474 0 R (HD.792) 1475 0 R (HD.793) 1476 0 R (HD.794) 1477 0 R (HD.795) 1478 0 R (HD.796) 1479 0 R (HD.797) 1480 0 R (HD.798) 1481 0 R (HD.799) 1482 0 R (HD.8) 614 0 R (HD.80) 690 0 R (HD.800) 1483 0 R (HD.801) 1484 0 R (HD.802) 1485 0 R (HD.803) 1486 0 R (HD.804) 1487 0 R (HD.805) 1488 0 R (HD.806) 1489 0 R (HD.807) 1490 0 R (HD.808) 1491 0 R (HD.809) 1492 0 R (HD.81) 691 0 R (HD.810) 1493 0 R (HD.811) 1494 0 R ] /Limits [ (HD.784) (HD.811) ] >>
+endobj
+4479 0 obj
+<< /Names [ (HD.812) 1495 0 R (HD.813) 1496 0 R (HD.814) 1497 0 R (HD.815) 1498 0 R (HD.816) 1499 0 R (HD.817) 1500 0 R (HD.818) 1501 0 R (HD.819) 1502 0 R (HD.82) 692 0 R (HD.820) 1503 0 R (HD.821) 1504 0 R (HD.822) 1505 0 R (HD.823) 1506 0 R (HD.824) 1507 0 R (HD.825) 1508 0 R (HD.826) 1509 0 R (HD.827) 1510 0 R (HD.828) 1511 0 R (HD.829) 1512 0 R (HD.83) 693 0 R (HD.830) 1513 0 R (HD.831) 1514 0 R (HD.832) 1515 0 R (HD.833) 1516 0 R (HD.834) 1517 0 R (HD.835) 1518 0 R (HD.836) 1519 0 R (HD.837) 1520 0 R (HD.838) 1521 0 R (HD.839) 1522 0 R (HD.84) 698 0 R (HD.840) 1523 0 R ] /Limits [ (HD.812) (HD.840) ] >>
+endobj
+4480 0 obj
+<< /Names [ (HD.841) 1524 0 R (HD.842) 1530 0 R (HD.843) 1531 0 R (HD.844) 1532 0 R (HD.845) 1533 0 R (HD.846) 1534 0 R (HD.847) 1535 0 R (HD.848) 1536 0 R (HD.849) 1537 0 R (HD.85) 699 0 R (HD.850) 1538 0 R (HD.851) 1539 0 R (HD.852) 1540 0 R (HD.853) 1541 0 R (HD.854) 1542 0 R (HD.855) 1543 0 R (HD.856) 1544 0 R (HD.857) 1545 0 R (HD.858) 1546 0 R (HD.859) 1547 0 R (HD.86) 700 0 R (HD.860) 1548 0 R (HD.861) 1549 0 R (HD.862) 1550 0 R (HD.863) 1551 0 R (HD.864) 1552 0 R (HD.865) 1553 0 R (HD.866) 1554 0 R (HD.867) 1555 0 R (HD.868) 1556 0 R (HD.869) 1557 0 R (HD.87) 701 0 R ] /Limits [ (HD.841) (HD.87) ] >>
+endobj
+4481 0 obj
+<< /Names [ (HD.870) 1558 0 R (HD.871) 1559 0 R (HD.872) 1560 0 R (HD.873) 1561 0 R (HD.874) 1562 0 R (HD.875) 1563 0 R (HD.876) 1564 0 R (HD.877) 1565 0 R (HD.878) 1566 0 R (HD.879) 1567 0 R (HD.88) 702 0 R (HD.880) 1568 0 R (HD.881) 1569 0 R (HD.882) 1570 0 R (HD.883) 1571 0 R (HD.884) 1578 0 R (HD.885) 1579 0 R (HD.886) 1580 0 R (HD.887) 1581 0 R (HD.888) 1582 0 R (HD.889) 1583 0 R (HD.89) 703 0 R (HD.890) 1584 0 R (HD.891) 1585 0 R (HD.892) 1586 0 R (HD.893) 1587 0 R (HD.894) 1588 0 R (HD.895) 1589 0 R (HD.896) 1590 0 R (HD.897) 1591 0 R (HD.898) 1592 0 R (HD.899) 1593 0 R ] /Limits [ (HD.870) (HD.899) ] >>
+endobj
+4482 0 obj
+<< /Names [ (HD.9) 615 0 R (HD.90) 704 0 R (HD.900) 1594 0 R (HD.901) 1595 0 R (HD.902) 1596 0 R (HD.903) 1597 0 R (HD.904) 1598 0 R (HD.905) 1599 0 R (HD.906) 1600 0 R (HD.907) 1601 0 R (HD.908) 1602 0 R (HD.909) 1603 0 R (HD.91) 705 0 R (HD.910) 1604 0 R (HD.911) 1605 0 R (HD.912) 1606 0 R (HD.913) 1607 0 R (HD.914) 1608 0 R (HD.915) 1609 0 R (HD.916) 1610 0 R (HD.917) 1611 0 R (HD.918) 1612 0 R (HD.919) 1613 0 R (HD.92) 706 0 R (HD.920) 1614 0 R (HD.921) 1615 0 R (HD.922) 1616 0 R (HD.923) 1617 0 R (HD.924) 1618 0 R (HD.925) 1619 0 R (HD.926) 1620 0 R (HD.927) 1625 0 R ] /Limits [ (HD.9) (HD.927) ] >>
+endobj
+4483 0 obj
+<< /Names [ (HD.928) 1626 0 R (HD.929) 1627 0 R (HD.93) 707 0 R (HD.930) 1628 0 R (HD.931) 1629 0 R (HD.932) 1630 0 R (HD.933) 1631 0 R (HD.934) 1632 0 R (HD.935) 1633 0 R (HD.936) 1634 0 R (HD.937) 1635 0 R (HD.938) 1636 0 R (HD.939) 1637 0 R (HD.94) 708 0 R (HD.940) 1638 0 R (HD.941) 1639 0 R (HD.942) 1640 0 R (HD.943) 1641 0 R (HD.944) 1642 0 R (HD.945) 1643 0 R (HD.946) 1644 0 R (HD.947) 1645 0 R (HD.948) 1646 0 R (HD.949) 1647 0 R (HD.95) 709 0 R (HD.950) 1648 0 R (HD.951) 1649 0 R (HD.952) 1650 0 R (HD.953) 1651 0 R (HD.954) 1652 0 R (HD.955) 1653 0 R (HD.956) 1654 0 R ] /Limits [ (HD.928) (HD.956) ] >>
+endobj
+4484 0 obj
+<< /Names [ (HD.957) 1655 0 R (HD.958) 1656 0 R (HD.959) 1657 0 R (HD.96) 710 0 R (HD.960) 1658 0 R (HD.961) 1659 0 R (HD.962) 1660 0 R (HD.963) 1661 0 R (HD.964) 1662 0 R (HD.965) 1663 0 R (HD.966) 1664 0 R (HD.967) 1665 0 R (HD.968) 1666 0 R (HD.969) 1667 0 R (HD.97) 711 0 R (HD.970) 1668 0 R (HD.971) 1673 0 R (HD.972) 1674 0 R (HD.973) 1675 0 R (HD.974) 1676 0 R (HD.975) 1677 0 R (HD.976) 1678 0 R (HD.977) 1679 0 R (HD.978) 1680 0 R (HD.979) 1681 0 R (HD.98) 712 0 R (HD.980) 1682 0 R (HD.981) 1683 0 R (HD.982) 1684 0 R (HD.983) 1685 0 R (HD.984) 1686 0 R (HD.985) 1687 0 R ] /Limits [ (HD.957) (HD.985) ] >>
+endobj
+4485 0 obj
+<< /Names [ (HD.986) 1688 0 R (HD.987) 1689 0 R (HD.988) 1690 0 R (HD.989) 1691 0 R (HD.99) 713 0 R (HD.990) 1692 0 R (HD.991) 1693 0 R (HD.992) 1694 0 R (HD.993) 1695 0 R (HD.994) 1696 0 R (HD.995) 1697 0 R (HD.996) 1698 0 R (HD.997) 1699 0 R (HD.998) 1700 0 R (HD.999) 1701 0 R (Hfootnote.1) 340 0 R (Hfootnote.10) 406 0 R (Hfootnote.11) 407 0 R (Hfootnote.12) 408 0 R (Hfootnote.13) 418 0 R (Hfootnote.14) 428 0 R (Hfootnote.15) 429 0 R (Hfootnote.16) 439 0 R (Hfootnote.17) 440 0 R (Hfootnote.18) 448 0 R (Hfootnote.19) 449 0 R (Hfootnote.2) 344 0 R (Hfootnote.20) 467 0 R (Hfootnote.21) 478 0 R (Hfootnote.22) 498 0 R (Hfootnote.23) 499 0 R (Hfootnote.24) 500 0 R ] /Limits [ (HD.986) (Hfootnote.24) ] >>
+endobj
+4486 0 obj
+<< /Names [ (Hfootnote.25) 501 0 R (Hfootnote.26) 531 0 R (Hfootnote.27) 532 0 R (Hfootnote.28) 545 0 R (Hfootnote.29) 546 0 R (Hfootnote.3) 368 0 R (Hfootnote.30) 547 0 R (Hfootnote.31) 566 0 R (Hfootnote.32) 598 0 R (Hfootnote.33) 595 0 R (Hfootnote.34) 596 0 R (Hfootnote.35) 597 0 R (Hfootnote.36) 1572 0 R (Hfootnote.37) 2462 0 R (Hfootnote.38) 2594 0 R (Hfootnote.39) 2595 0 R (Hfootnote.4) 369 0 R (Hfootnote.40) 2805 0 R (Hfootnote.41) 3121 0 R (Hfootnote.42) 3212 0 R (Hfootnote.43) 3381 0 R (Hfootnote.5) 370 0 R (Hfootnote.6) 383 0 R (Hfootnote.7) 384 0 R (Hfootnote.8) 385 0 R (Hfootnote.9) 405 0 R (page.1) 315 0 R (page.10) 454 0 R (page.100) 4165 0 R (page.11) 458 0 R (page.12) 466 0 R (page.13) 477 0 R ] /Limits [ (Hfootnote.25) (page.13) ] >>
+endobj
+4487 0 obj
+<< /Names [ (page.14) 483 0 R (page.15) 487 0 R (page.16) 495 0 R (page.17) 506 0 R (page.18) 517 0 R (page.19) 522 0 R (page.2) 355 0 R (page.20) 530 0 R (page.21) 543 0 R (page.22) 555 0 R (page.23) 565 0 R (page.24) 571 0 R (page.25) 575 0 R (page.26) 579 0 R (page.27) 585 0 R (page.28) 594 0 R (page.29) 603 0 R (page.3) 366 0 R (page.30) 646 0 R (page.31) 697 0 R (page.32) 753 0 R (page.33) 781 0 R (page.34) 806 0 R (page.35) 827 0 R (page.36) 869 0 R (page.37) 905 0 R (page.38) 965 0 R (page.39) 1002 0 R (page.4) 382 0 R (page.40) 1058 0 R (page.41) 1121 0 R (page.42) 1181 0 R ] /Limits [ (page.14) (page.42) ] >>
+endobj
+4488 0 obj
+<< /Names [ (page.43) 1246 0 R (page.44) 1313 0 R (page.45) 1361 0 R (page.46) 1415 0 R (page.47) 1473 0 R (page.48) 1529 0 R (page.49) 1577 0 R (page.5) 402 0 R (page.50) 1624 0 R (page.51) 1672 0 R (page.52) 1728 0 R (page.53) 1786 0 R (page.54) 1837 0 R (page.55) 1896 0 R (page.56) 1946 0 R (page.57) 1989 0 R (page.58) 2042 0 R (page.59) 2106 0 R (page.6) 417 0 R (page.60) 2169 0 R (page.61) 2218 0 R (page.62) 2257 0 R (page.63) 2300 0 R (page.64) 2330 0 R (page.65) 2376 0 R (page.66) 2427 0 R (page.67) 2467 0 R (page.68) 2522 0 R (page.69) 2563 0 R (page.7) 426 0 R (page.70) 2600 0 R (page.71) 2655 0 R ] /Limits [ (page.43) (page.71) ] >>
+endobj
+4489 0 obj
+<< /Names [ (page.72) 2715 0 R (page.73) 2761 0 R (page.74) 2810 0 R (page.75) 2865 0 R (page.76) 2912 0 R (page.77) 2958 0 R (page.78) 3017 0 R (page.79) 3073 0 R (page.8) 436 0 R (page.80) 3126 0 R (page.81) 3164 0 R (page.82) 3218 0 R (page.83) 3270 0 R (page.84) 3330 0 R (page.85) 3386 0 R (page.86) 3453 0 R (page.87) 3508 0 R (page.88) 3547 0 R (page.89) 3598 0 R (page.9) 447 0 R (page.90) 3643 0 R (page.91) 3697 0 R (page.92) 3746 0 R (page.93) 3805 0 R (page.94) 3862 0 R (page.95) 3925 0 R (page.96) 3989 0 R (page.97) 4050 0 R (page.98) 4077 0 R (page.99) 4141 0 R (piton:passe) 438 0 R (piton:transpose) 437 0 R ] /Limits [ (page.72) (piton:transpose) ] >>
+endobj
+4490 0 obj
+<< /Names [ (section*.1) 2288 0 R (section*.10) 2708 0 R (section*.11) 2718 0 R (section*.12) 2762 0 R (section*.13) 2764 0 R (section*.14) 2899 0 R (section*.15) 2902 0 R (section*.16) 2913 0 R (section*.17) 2943 0 R (section*.18) 2961 0 R (section*.19) 2991 0 R (section*.2) 2331 0 R (section*.20) 3038 0 R (section*.21) 3040 0 R (section*.22) 3129 0 R (section*.23) 3141 0 R (section*.24) 3146 0 R (section*.25) 3148 0 R (section*.26) 3165 0 R (section*.27) 3265 0 R (section*.28) 3271 0 R (section*.29) 3276 0 R (section*.3) 2366 0 R (section*.30) 3289 0 R (section*.31) 4061 0 R (section*.32) 4062 0 R (section*.33) 4063 0 R (section*.34) 4064 0 R (section*.35) 4065 0 R (section*.36) 4066 0 R (section*.37) 4067 0 R (section*.38) 4078 0 R ] /Limits [ (section*.1) (section*.38) ] >>
+endobj
+4491 0 obj
+<< /Names [ (section*.39) 4079 0 R (section*.4) 2448 0 R (section*.40) 4080 0 R (section*.41) 4081 0 R (section*.42) 4082 0 R (section*.43) 4083 0 R (section*.44) 4084 0 R (section*.45) 4085 0 R (section*.46) 4086 0 R (section*.5) 2568 0 R (section*.6) 2633 0 R (section*.7) 2636 0 R (section*.8) 2638 0 R (section*.9) 2640 0 R (section.0.1) 5 0 R (section.0.10) 301 0 R (section.0.2) 9 0 R (section.0.3) 13 0 R (section.0.4) 33 0 R (section.0.5) 61 0 R (section.0.6) 141 0 R (section.0.7) 145 0 R (section.0.8) 169 0 R (section.0.9) 193 0 R (subsection.0.3.1) 17 0 R (subsection.0.3.2) 21 0 R (subsection.0.3.3) 25 0 R (subsection.0.3.4) 29 0 R (subsection.0.4.1) 37 0 R (subsection.0.4.2) 41 0 R (subsection.0.4.3) 57 0 R (subsection.0.5.1) 65 0 R ] /Limits [ (section*.39) (subsection.0.5.1) ] >>
+endobj
+4492 0 obj
+<< /Names [ (subsection.0.5.2) 77 0 R (subsection.0.5.3) 89 0 R (subsection.0.5.4) 93 0 R (subsection.0.5.5) 117 0 R (subsection.0.5.6) 133 0 R (subsection.0.5.7) 137 0 R (subsection.0.7.1) 149 0 R (subsection.0.7.2) 153 0 R (subsection.0.7.3) 157 0 R (subsection.0.7.4) 161 0 R (subsection.0.7.5) 165 0 R (subsection.0.8.1) 173 0 R (subsection.0.8.2) 177 0 R (subsection.0.8.3) 181 0 R (subsection.0.8.4) 185 0 R (subsection.0.8.5) 189 0 R (subsection.0.9.1) 197 0 R (subsection.0.9.2) 201 0 R (subsection.0.9.3) 261 0 R (subsubsection.0.4.2.1) 45 0 R (subsubsection.0.4.2.2) 49 0 R (subsubsection.0.4.2.3) 53 0 R (subsubsection.0.5.1.1) 69 0 R (subsubsection.0.5.1.2) 73 0 R (subsubsection.0.5.2.1) 81 0 R (subsubsection.0.5.2.2) 85 0 R (subsubsection.0.5.4.1) 97 0 R (subsubsection.0.5.4.2) 101 0 R (subsubsection.0.5.4.3) 105 0 R (subsubsection.0.5.4.4) 109 0 R (subsubsection.0.5.4.5) 113 0 R (subsubsection.0.5.5.1) 121 0 R ] /Limits [ (subsection.0.5.2) (subsubsection.0.5.5.1) ] >>
+endobj
+4493 0 obj
+<< /Names [ (subsubsection.0.5.5.2) 125 0 R (subsubsection.0.5.5.3) 129 0 R (subsubsection.0.9.2.1) 205 0 R (subsubsection.0.9.2.10) 241 0 R (subsubsection.0.9.2.11) 245 0 R (subsubsection.0.9.2.12) 249 0 R (subsubsection.0.9.2.13) 253 0 R (subsubsection.0.9.2.14) 257 0 R (subsubsection.0.9.2.2) 209 0 R (subsubsection.0.9.2.3) 213 0 R (subsubsection.0.9.2.4) 217 0 R (subsubsection.0.9.2.5) 221 0 R (subsubsection.0.9.2.6) 225 0 R (subsubsection.0.9.2.7) 229 0 R (subsubsection.0.9.2.8) 233 0 R (subsubsection.0.9.2.9) 237 0 R (subsubsection.0.9.3.1) 265 0 R (subsubsection.0.9.3.2) 269 0 R (subsubsection.0.9.3.3) 273 0 R (subsubsection.0.9.3.4) 277 0 R (subsubsection.0.9.3.5) 281 0 R (subsubsection.0.9.3.6) 285 0 R (subsubsection.0.9.3.7) 289 0 R (subsubsection.0.9.3.8) 293 0 R (subsubsection.0.9.3.9) 297 0 R (toc1.1) 305 0 R ] /Limits [ (subsubsection.0.5.5.2) (toc1.1) ] >>
+endobj
+4494 0 obj
+<< /Kids [ 4388 0 R 4389 0 R 4390 0 R 4391 0 R 4392 0 R 4393 0 R 4394 0 R 4395 0 R 4396 0 R 4397 0 R 4398 0 R 4399 0 R 4400 0 R 4401 0 R 4402 0 R 4403 0 R 4404 0 R 4405 0 R 4406 0 R 4407 0 R 4408 0 R 4409 0 R 4410 0 R 4411 0 R 4412 0 R 4413 0 R 4414 0 R 4415 0 R 4416 0 R 4417 0 R 4418 0 R 4419 0 R ] /Limits [ (Doc-Start) (HD.1919) ] >>
+endobj
+4495 0 obj
+<< /Kids [ 4420 0 R 4421 0 R 4422 0 R 4423 0 R 4424 0 R 4425 0 R 4426 0 R 4427 0 R 4428 0 R 4429 0 R 4430 0 R 4431 0 R 4432 0 R 4433 0 R 4434 0 R 4435 0 R 4436 0 R 4437 0 R 4438 0 R 4439 0 R 4440 0 R 4441 0 R 4442 0 R 4443 0 R 4444 0 R 4445 0 R 4446 0 R 4447 0 R 4448 0 R 4449 0 R 4450 0 R 4451 0 R ] /Limits [ (HD.192) (HD.2840) ] >>
+endobj
+4496 0 obj
+<< /Kids [ 4452 0 R 4453 0 R 4454 0 R 4455 0 R 4456 0 R 4457 0 R 4458 0 R 4459 0 R 4460 0 R 4461 0 R 4462 0 R 4463 0 R 4464 0 R 4465 0 R 4466 0 R 4467 0 R 4468 0 R 4469 0 R 4470 0 R 4471 0 R 4472 0 R 4473 0 R 4474 0 R 4475 0 R 4476 0 R 4477 0 R 4478 0 R 4479 0 R 4480 0 R 4481 0 R 4482 0 R 4483 0 R ] /Limits [ (HD.2841) (HD.956) ] >>
+endobj
+4497 0 obj
+<< /Kids [ 4484 0 R 4485 0 R 4486 0 R 4487 0 R 4488 0 R 4489 0 R 4490 0 R 4491 0 R 4492 0 R 4493 0 R ] /Limits [ (HD.957) (toc1.1) ] >>
+endobj
+4498 0 obj
+<< /Kids [ 4494 0 R 4495 0 R 4496 0 R 4497 0 R ] /Limits [ (Doc-Start) (toc1.1) ] >>
+endobj
+4499 0 obj
+<< /Dests 4498 0 R >>
+endobj
+4500 0 obj
+<< /Type /Catalog /Pages 4386 0 R /Outlines 4387 0 R /Names 4499 0 R /PageMode/UseOutlines /OpenAction 308 0 R >>
+endobj
+4501 0 obj
+<< /Author(\376\377\000F\000.\000\040\000P\000a\000n\000t\000i\000g\000n\000y\000\040\000,\000\040\000f\000p\000a\000n\000t\000i\000g\000n\000y\000@\000w\000a\000n\000a\000d\000o\000o\000.\000f\000r)/Title(\376\377\000T\000h\000e\000\040\000p\000a\000c\000k\000a\000g\000e\000\040\000p\000i\000t\000o\000n)/Subject()/Creator(LaTeX with hyperref)/Keywords() /Producer (LuaTeX-1.18.1) /CreationDate (D:20240414152508+02'00') /ModDate (D:20240414152508+02'00') /Trapped /False /PTEX.FullBanner (This is LuaHBTeX, Version 1.18.1 (MiKTeX 24.3.31)) >>
endobj
xref
-0 4479
+0 4502
0000000000 65535 f
-0000574038 00000 n
-0000574083 00000 n
-0000574103 00000 n
+0000577436 00000 n
+0000577481 00000 n
+0000577501 00000 n
0000000020 00000 n
0000023423 00000 n
-0000852364 00000 n
+0000855575 00000 n
0000000067 00000 n
0000000167 00000 n
0000023483 00000 n
-0000852277 00000 n
+0000855488 00000 n
0000000214 00000 n
0000000315 00000 n
-0000029130 00000 n
-0000852151 00000 n
+0000029418 00000 n
+0000855362 00000 n
0000000363 00000 n
0000000503 00000 n
-0000029191 00000 n
-0000852077 00000 n
+0000029479 00000 n
+0000855288 00000 n
0000000556 00000 n
0000000708 00000 n
-0000029252 00000 n
-0000851990 00000 n
+0000029539 00000 n
+0000855201 00000 n
0000000761 00000 n
0000000979 00000 n
-0000029313 00000 n
-0000851903 00000 n
+0000029600 00000 n
+0000855114 00000 n
0000001032 00000 n
0000001248 00000 n
-0000029374 00000 n
-0000851829 00000 n
+0000029661 00000 n
+0000855040 00000 n
0000001301 00000 n
0000001530 00000 n
-0000034636 00000 n
-0000851703 00000 n
+0000034819 00000 n
+0000854914 00000 n
0000001578 00000 n
0000001684 00000 n
-0000034697 00000 n
-0000851629 00000 n
+0000034880 00000 n
+0000854840 00000 n
0000001737 00000 n
0000001991 00000 n
-0000053739 00000 n
-0000851505 00000 n
+0000054050 00000 n
+0000854716 00000 n
0000002044 00000 n
0000002148 00000 n
-0000053800 00000 n
-0000851431 00000 n
+0000054111 00000 n
+0000854642 00000 n
0000002206 00000 n
0000002348 00000 n
-0000057973 00000 n
-0000851344 00000 n
+0000058243 00000 n
+0000854555 00000 n
0000002406 00000 n
0000002629 00000 n
-0000058034 00000 n
-0000851270 00000 n
+0000058303 00000 n
+0000854481 00000 n
0000002687 00000 n
0000002864 00000 n
-0000063173 00000 n
-0000851196 00000 n
+0000063151 00000 n
+0000854407 00000 n
0000002917 00000 n
0000003117 00000 n
-0000063234 00000 n
-0000851068 00000 n
+0000068240 00000 n
+0000854279 00000 n
0000003165 00000 n
0000003294 00000 n
-0000063295 00000 n
-0000850957 00000 n
+0000068301 00000 n
+0000854168 00000 n
0000003347 00000 n
0000003545 00000 n
-0000063356 00000 n
-0000850883 00000 n
+0000068362 00000 n
+0000854094 00000 n
0000003603 00000 n
0000003722 00000 n
-0000068818 00000 n
-0000850809 00000 n
+0000068423 00000 n
+0000854020 00000 n
0000003780 00000 n
0000003899 00000 n
-0000072795 00000 n
-0000850685 00000 n
+0000072871 00000 n
+0000853896 00000 n
0000003952 00000 n
0000004166 00000 n
-0000072856 00000 n
-0000850611 00000 n
+0000072932 00000 n
+0000853822 00000 n
0000004224 00000 n
0000004376 00000 n
-0000072917 00000 n
-0000850537 00000 n
+0000072993 00000 n
+0000853748 00000 n
0000004434 00000 n
0000004601 00000 n
-0000080127 00000 n
-0000850450 00000 n
+0000080350 00000 n
+0000853661 00000 n
0000004654 00000 n
0000004856 00000 n
-0000085069 00000 n
-0000850324 00000 n
+0000085371 00000 n
+0000853535 00000 n
0000004909 00000 n
0000005117 00000 n
-0000085130 00000 n
-0000850249 00000 n
+0000085431 00000 n
+0000853460 00000 n
0000005175 00000 n
0000005352 00000 n
-0000088963 00000 n
-0000850158 00000 n
+0000089262 00000 n
+0000853369 00000 n
0000005411 00000 n
0000005604 00000 n
-0000089025 00000 n
-0000850066 00000 n
+0000089324 00000 n
+0000853277 00000 n
0000005663 00000 n
0000005876 00000 n
-0000089087 00000 n
-0000849974 00000 n
+0000089386 00000 n
+0000853185 00000 n
0000005935 00000 n
0000006123 00000 n
-0000092683 00000 n
-0000849896 00000 n
+0000092982 00000 n
+0000853107 00000 n
0000006182 00000 n
0000006395 00000 n
-0000098151 00000 n
-0000849766 00000 n
+0000098450 00000 n
+0000852977 00000 n
0000006449 00000 n
0000006658 00000 n
-0000098212 00000 n
-0000849687 00000 n
+0000098511 00000 n
+0000852898 00000 n
0000006717 00000 n
0000007040 00000 n
-0000098274 00000 n
-0000849594 00000 n
+0000098573 00000 n
+0000852805 00000 n
0000007099 00000 n
0000007476 00000 n
-0000101805 00000 n
-0000849515 00000 n
+0000102104 00000 n
+0000852726 00000 n
0000007535 00000 n
0000007932 00000 n
-0000107740 00000 n
-0000849423 00000 n
+0000108039 00000 n
+0000852634 00000 n
0000007986 00000 n
0000008243 00000 n
-0000107801 00000 n
-0000849345 00000 n
+0000108100 00000 n
+0000852556 00000 n
0000008297 00000 n
0000008404 00000 n
-0000107863 00000 n
-0000849252 00000 n
+0000108162 00000 n
+0000852463 00000 n
0000008453 00000 n
0000008619 00000 n
-0000111927 00000 n
-0000849119 00000 n
+0000112226 00000 n
+0000852330 00000 n
0000008668 00000 n
0000008750 00000 n
-0000111989 00000 n
-0000849040 00000 n
+0000112288 00000 n
+0000852251 00000 n
0000008804 00000 n
0000008929 00000 n
-0000112051 00000 n
-0000848947 00000 n
+0000112350 00000 n
+0000852158 00000 n
0000008983 00000 n
0000009207 00000 n
-0000116561 00000 n
-0000848854 00000 n
+0000116860 00000 n
+0000852065 00000 n
0000009261 00000 n
0000009427 00000 n
-0000121639 00000 n
-0000848761 00000 n
+0000121938 00000 n
+0000851972 00000 n
0000009481 00000 n
0000009721 00000 n
-0000124962 00000 n
-0000848682 00000 n
+0000125261 00000 n
+0000851893 00000 n
0000009775 00000 n
0000009918 00000 n
-0000129478 00000 n
-0000848549 00000 n
+0000129777 00000 n
+0000851760 00000 n
0000009967 00000 n
0000010262 00000 n
-0000129540 00000 n
-0000848470 00000 n
+0000129839 00000 n
+0000851681 00000 n
0000010316 00000 n
0000010469 00000 n
-0000133070 00000 n
-0000848377 00000 n
+0000133369 00000 n
+0000851588 00000 n
0000010523 00000 n
0000010671 00000 n
-0000136660 00000 n
-0000848284 00000 n
+0000136959 00000 n
+0000851495 00000 n
0000010725 00000 n
0000010915 00000 n
-0000140048 00000 n
-0000848191 00000 n
+0000140347 00000 n
+0000851402 00000 n
0000010969 00000 n
0000011107 00000 n
-0000142221 00000 n
-0000848112 00000 n
+0000142520 00000 n
+0000851323 00000 n
0000011161 00000 n
0000011339 00000 n
-0000146730 00000 n
-0000847979 00000 n
+0000147029 00000 n
+0000851190 00000 n
0000011388 00000 n
0000011500 00000 n
-0000146792 00000 n
-0000847900 00000 n
+0000147091 00000 n
+0000851111 00000 n
0000011554 00000 n
0000011666 00000 n
-0000150724 00000 n
-0000847767 00000 n
+0000151023 00000 n
+0000850978 00000 n
0000011720 00000 n
0000011952 00000 n
-0000150786 00000 n
-0000847688 00000 n
+0000151085 00000 n
+0000850899 00000 n
0000012011 00000 n
0000012212 00000 n
-0000168265 00000 n
-0000847595 00000 n
+0000168646 00000 n
+0000850806 00000 n
0000012271 00000 n
0000012522 00000 n
-0000187808 00000 n
-0000847502 00000 n
+0000188189 00000 n
+0000850713 00000 n
0000012581 00000 n
0000012793 00000 n
-0000208443 00000 n
-0000847409 00000 n
+0000208824 00000 n
+0000850620 00000 n
0000012852 00000 n
0000012974 00000 n
-0000234373 00000 n
-0000847316 00000 n
+0000235377 00000 n
+0000850527 00000 n
0000013033 00000 n
0000013227 00000 n
-0000235605 00000 n
-0000847223 00000 n
+0000236609 00000 n
+0000850434 00000 n
0000013286 00000 n
0000013549 00000 n
-0000239726 00000 n
-0000847130 00000 n
+0000240883 00000 n
+0000850341 00000 n
0000013608 00000 n
0000013959 00000 n
-0000285774 00000 n
-0000847037 00000 n
+0000290100 00000 n
+0000850248 00000 n
0000014018 00000 n
0000014133 00000 n
-0000296794 00000 n
-0000846944 00000 n
+0000301618 00000 n
+0000850155 00000 n
0000014192 00000 n
0000014350 00000 n
-0000302332 00000 n
-0000846851 00000 n
+0000307429 00000 n
+0000850062 00000 n
0000014410 00000 n
0000014628 00000 n
-0000312414 00000 n
-0000846758 00000 n
+0000314307 00000 n
+0000849969 00000 n
0000014688 00000 n
0000014795 00000 n
-0000313126 00000 n
-0000846665 00000 n
+0000315018 00000 n
+0000849876 00000 n
0000014855 00000 n
0000015102 00000 n
-0000326541 00000 n
-0000846572 00000 n
+0000331203 00000 n
+0000849783 00000 n
0000015162 00000 n
0000015320 00000 n
-0000327514 00000 n
-0000846493 00000 n
+0000332176 00000 n
+0000849704 00000 n
0000015380 00000 n
0000015535 00000 n
-0000332067 00000 n
-0000846375 00000 n
+0000333536 00000 n
+0000849586 00000 n
0000015589 00000 n
0000015826 00000 n
-0000366659 00000 n
-0000846296 00000 n
+0000370777 00000 n
+0000849507 00000 n
0000015885 00000 n
0000016048 00000 n
-0000408013 00000 n
-0000846203 00000 n
+0000411643 00000 n
+0000849414 00000 n
0000016107 00000 n
0000016265 00000 n
-0000437984 00000 n
-0000846110 00000 n
+0000441118 00000 n
+0000849321 00000 n
0000016324 00000 n
0000016462 00000 n
-0000450275 00000 n
-0000846017 00000 n
+0000453408 00000 n
+0000849228 00000 n
0000016521 00000 n
0000016669 00000 n
-0000467945 00000 n
-0000845924 00000 n
+0000471081 00000 n
+0000849135 00000 n
0000016728 00000 n
0000016916 00000 n
-0000485337 00000 n
-0000845831 00000 n
+0000488468 00000 n
+0000849042 00000 n
0000016975 00000 n
0000017381 00000 n
-0000485984 00000 n
-0000845738 00000 n
+0000489115 00000 n
+0000848949 00000 n
0000017440 00000 n
0000017750 00000 n
-0000497819 00000 n
-0000845645 00000 n
+0000500939 00000 n
+0000848856 00000 n
0000017809 00000 n
0000018026 00000 n
-0000504264 00000 n
-0000845566 00000 n
+0000507384 00000 n
+0000848777 00000 n
0000018085 00000 n
0000018426 00000 n
-0000545521 00000 n
-0000845472 00000 n
+0000548843 00000 n
+0000848683 00000 n
0000018476 00000 n
0000018558 00000 n
-0000550005 00000 n
-0000845392 00000 n
+0000553406 00000 n
+0000848603 00000 n
0000018602 00000 n
0000018671 00000 n
-0000022419 00000 n
-0000022609 00000 n
+0000022420 00000 n
+0000022610 00000 n
0000022920 00000 n
-0000022764 00000 n
+0000022765 00000 n
0000023668 00000 n
0000018735 00000 n
0000023299 00000 n
0000023361 00000 n
-0000753301 00000 n
-0000750409 00000 n
-0000842344 00000 n
-0000748195 00000 n
-0000744261 00000 n
-0000740915 00000 n
-0000738283 00000 n
-0000731489 00000 n
-0000729376 00000 n
-0000721307 00000 n
-0000710452 00000 n
-0000706889 00000 n
-0000703786 00000 n
-0000693125 00000 n
-0000689434 00000 n
-0000843060 00000 n
-0000841622 00000 n
-0000841984 00000 n
-0000843236 00000 n
-0000842524 00000 n
-0000682812 00000 n
-0000673917 00000 n
-0000669682 00000 n
+0000756501 00000 n
+0000753609 00000 n
+0000845544 00000 n
+0000751395 00000 n
+0000747556 00000 n
+0000744210 00000 n
+0000741578 00000 n
+0000734784 00000 n
+0000732671 00000 n
+0000724602 00000 n
+0000713747 00000 n
+0000710184 00000 n
+0000707081 00000 n
+0000696420 00000 n
+0000692729 00000 n
+0000846260 00000 n
+0000844822 00000 n
+0000845184 00000 n
+0000846436 00000 n
+0000845724 00000 n
+0000686107 00000 n
+0000677315 00000 n
+0000673080 00000 n
0000023543 00000 n
-0000666572 00000 n
-0000662849 00000 n
+0000669970 00000 n
+0000666247 00000 n
0000023112 00000 n
0000023606 00000 n
-0000843583 00000 n
-0000022556 00000 n
-0000028263 00000 n
-0000028424 00000 n
-0000028585 00000 n
-0000028746 00000 n
-0000028907 00000 n
-0000029435 00000 n
-0000028065 00000 n
+0000846783 00000 n
+0000022557 00000 n
+0000028551 00000 n
+0000028712 00000 n
+0000028873 00000 n
+0000029034 00000 n
+0000029195 00000 n
+0000029722 00000 n
+0000028353 00000 n
0000024104 00000 n
-0000029068 00000 n
-0000655131 00000 n
-0000653342 00000 n
-0000028202 00000 n
-0000034107 00000 n
-0000034263 00000 n
-0000034419 00000 n
-0000034946 00000 n
-0000033925 00000 n
-0000029637 00000 n
-0000034574 00000 n
-0000644436 00000 n
-0000637675 00000 n
-0000034758 00000 n
-0000034821 00000 n
-0000034884 00000 n
-0000034062 00000 n
-0000040024 00000 n
-0000040810 00000 n
-0000040965 00000 n
-0000040180 00000 n
-0000040336 00000 n
-0000040490 00000 n
-0000040650 00000 n
-0000046351 00000 n
-0000046510 00000 n
-0000041370 00000 n
-0000039810 00000 n
-0000035239 00000 n
-0000041120 00000 n
-0000041182 00000 n
-0000041245 00000 n
-0000041308 00000 n
-0000039947 00000 n
-0000046670 00000 n
-0000046836 00000 n
-0000047002 00000 n
-0000047158 00000 n
-0000047319 00000 n
-0000047480 00000 n
-0000047636 00000 n
-0000047792 00000 n
-0000047949 00000 n
-0000048113 00000 n
-0000048589 00000 n
-0000046097 00000 n
-0000041611 00000 n
-0000048277 00000 n
-0000634879 00000 n
-0000631435 00000 n
-0000048339 00000 n
-0000048402 00000 n
-0000048465 00000 n
-0000048527 00000 n
-0000046234 00000 n
-0000053050 00000 n
-0000053209 00000 n
-0000053366 00000 n
-0000053521 00000 n
-0000053923 00000 n
-0000052860 00000 n
-0000048856 00000 n
+0000029356 00000 n
+0000658529 00000 n
+0000656740 00000 n
+0000647834 00000 n
+0000028490 00000 n
+0000034290 00000 n
+0000034446 00000 n
+0000034602 00000 n
+0000035128 00000 n
+0000034108 00000 n
+0000029937 00000 n
+0000034757 00000 n
+0000641073 00000 n
+0000034941 00000 n
+0000035004 00000 n
+0000035067 00000 n
+0000034245 00000 n
+0000040222 00000 n
+0000041011 00000 n
+0000041166 00000 n
+0000040377 00000 n
+0000040533 00000 n
+0000040689 00000 n
+0000040850 00000 n
+0000041571 00000 n
+0000040008 00000 n
+0000035421 00000 n
+0000041321 00000 n
+0000041383 00000 n
+0000041446 00000 n
+0000041509 00000 n
+0000040145 00000 n
+0000046757 00000 n
+0000046917 00000 n
+0000047078 00000 n
+0000047243 00000 n
+0000047408 00000 n
+0000047564 00000 n
+0000047724 00000 n
+0000047884 00000 n
+0000048041 00000 n
+0000048198 00000 n
+0000048355 00000 n
+0000048517 00000 n
+0000048991 00000 n
+0000046503 00000 n
+0000041812 00000 n
+0000048679 00000 n
+0000638277 00000 n
+0000634833 00000 n
+0000048741 00000 n
+0000048804 00000 n
+0000048867 00000 n
+0000048929 00000 n
+0000046640 00000 n
+0000053359 00000 n
+0000053520 00000 n
0000053677 00000 n
-0000053861 00000 n
-0000052997 00000 n
-0000057598 00000 n
-0000057755 00000 n
-0000062574 00000 n
-0000062733 00000 n
-0000058283 00000 n
-0000057424 00000 n
-0000054203 00000 n
-0000057911 00000 n
-0000619911 00000 n
-0000058095 00000 n
-0000058159 00000 n
-0000058221 00000 n
-0000057561 00000 n
-0000062890 00000 n
-0000068444 00000 n
-0000063541 00000 n
-0000062392 00000 n
-0000058550 00000 n
-0000063047 00000 n
-0000063109 00000 n
-0000063417 00000 n
-0000063479 00000 n
-0000062529 00000 n
-0000068600 00000 n
-0000069003 00000 n
-0000068270 00000 n
-0000063847 00000 n
-0000068756 00000 n
-0000068879 00000 n
-0000068942 00000 n
-0000068407 00000 n
-0000072978 00000 n
-0000072612 00000 n
-0000069257 00000 n
-0000072733 00000 n
-0000079586 00000 n
-0000076316 00000 n
-0000076133 00000 n
-0000073232 00000 n
-0000076254 00000 n
-0000843736 00000 n
-0000079743 00000 n
-0000079904 00000 n
-0000080250 00000 n
-0000079404 00000 n
-0000076518 00000 n
-0000080065 00000 n
-0000080188 00000 n
-0000079541 00000 n
-0000084207 00000 n
-0000084368 00000 n
-0000084529 00000 n
-0000084690 00000 n
-0000084851 00000 n
-0000085254 00000 n
-0000084009 00000 n
-0000080517 00000 n
-0000085007 00000 n
-0000085191 00000 n
-0000084146 00000 n
-0000089149 00000 n
-0000088780 00000 n
-0000085521 00000 n
-0000088901 00000 n
-0000092745 00000 n
-0000092500 00000 n
-0000089377 00000 n
-0000092621 00000 n
-0000097461 00000 n
-0000097618 00000 n
-0000097775 00000 n
-0000097932 00000 n
-0000098587 00000 n
-0000097271 00000 n
-0000092921 00000 n
-0000098089 00000 n
-0000842702 00000 n
-0000841803 00000 n
-0000098336 00000 n
-0000098399 00000 n
-0000098462 00000 n
-0000098525 00000 n
-0000097408 00000 n
-0000101867 00000 n
-0000101622 00000 n
-0000098945 00000 n
-0000101743 00000 n
-0000106546 00000 n
-0000106707 00000 n
-0000106868 00000 n
-0000107028 00000 n
-0000107194 00000 n
-0000107360 00000 n
-0000107519 00000 n
-0000107925 00000 n
-0000106332 00000 n
-0000102056 00000 n
-0000107678 00000 n
-0000106469 00000 n
-0000112113 00000 n
-0000111744 00000 n
-0000108127 00000 n
-0000111865 00000 n
-0000115865 00000 n
-0000116026 00000 n
-0000116187 00000 n
-0000116342 00000 n
-0000116748 00000 n
-0000115675 00000 n
-0000112315 00000 n
-0000116499 00000 n
-0000116622 00000 n
-0000116685 00000 n
-0000115812 00000 n
-0000120481 00000 n
-0000120638 00000 n
-0000120795 00000 n
-0000120955 00000 n
-0000121115 00000 n
-0000121272 00000 n
-0000121762 00000 n
-0000120275 00000 n
-0000116989 00000 n
-0000121452 00000 n
-0000616353 00000 n
-0000121514 00000 n
-0000121576 00000 n
-0000121700 00000 n
-0000843889 00000 n
-0000120412 00000 n
-0000124588 00000 n
-0000124744 00000 n
-0000125024 00000 n
-0000124414 00000 n
-0000122029 00000 n
-0000124900 00000 n
-0000614154 00000 n
-0000601981 00000 n
-0000587327 00000 n
-0000124551 00000 n
-0000129081 00000 n
-0000129238 00000 n
-0000129664 00000 n
-0000128907 00000 n
-0000125268 00000 n
-0000129416 00000 n
-0000129602 00000 n
-0000129044 00000 n
-0000133132 00000 n
-0000132887 00000 n
-0000129905 00000 n
-0000133008 00000 n
-0000136722 00000 n
-0000136477 00000 n
-0000133295 00000 n
-0000136598 00000 n
-0000140110 00000 n
-0000139865 00000 n
-0000136911 00000 n
-0000139986 00000 n
-0000141837 00000 n
-0000141998 00000 n
-0000142283 00000 n
-0000141663 00000 n
-0000140286 00000 n
-0000142159 00000 n
-0000141800 00000 n
-0000146043 00000 n
-0000146198 00000 n
-0000146354 00000 n
-0000146511 00000 n
-0000147105 00000 n
-0000145853 00000 n
-0000142446 00000 n
-0000146668 00000 n
-0000146853 00000 n
-0000146916 00000 n
-0000146979 00000 n
-0000147042 00000 n
-0000145990 00000 n
-0000153110 00000 n
-0000150541 00000 n
-0000147398 00000 n
-0000150662 00000 n
-0000841477 00000 n
-0000150848 00000 n
-0000842880 00000 n
-0000843410 00000 n
-0000150911 00000 n
-0000150974 00000 n
-0000151037 00000 n
-0000151100 00000 n
-0000151162 00000 n
-0000151225 00000 n
-0000151288 00000 n
-0000151351 00000 n
-0000151414 00000 n
-0000151477 00000 n
-0000151539 00000 n
-0000151602 00000 n
-0000151665 00000 n
-0000151728 00000 n
-0000151791 00000 n
-0000151854 00000 n
-0000151917 00000 n
-0000151980 00000 n
-0000152043 00000 n
-0000152105 00000 n
-0000152168 00000 n
-0000152231 00000 n
-0000152294 00000 n
-0000152357 00000 n
-0000152420 00000 n
-0000152483 00000 n
-0000152546 00000 n
-0000152609 00000 n
-0000152672 00000 n
-0000152735 00000 n
-0000152798 00000 n
-0000152861 00000 n
-0000152924 00000 n
-0000152986 00000 n
-0000153048 00000 n
-0000158804 00000 n
-0000155666 00000 n
-0000153340 00000 n
-0000155787 00000 n
-0000155849 00000 n
-0000155912 00000 n
-0000155974 00000 n
-0000156037 00000 n
-0000156100 00000 n
-0000156163 00000 n
-0000156226 00000 n
-0000156289 00000 n
-0000156352 00000 n
-0000156415 00000 n
-0000156478 00000 n
-0000156541 00000 n
-0000156604 00000 n
-0000156667 00000 n
-0000156729 00000 n
-0000156792 00000 n
-0000156855 00000 n
-0000156918 00000 n
-0000156981 00000 n
-0000157044 00000 n
-0000157107 00000 n
-0000157170 00000 n
-0000157233 00000 n
-0000157296 00000 n
-0000157359 00000 n
-0000157422 00000 n
-0000157485 00000 n
-0000157548 00000 n
-0000157611 00000 n
-0000157674 00000 n
-0000157737 00000 n
-0000157800 00000 n
-0000157863 00000 n
-0000157926 00000 n
-0000157988 00000 n
-0000158051 00000 n
-0000158114 00000 n
-0000158177 00000 n
-0000158240 00000 n
-0000158303 00000 n
-0000158366 00000 n
-0000158429 00000 n
-0000158492 00000 n
-0000158554 00000 n
-0000158617 00000 n
-0000158680 00000 n
-0000158742 00000 n
-0000164437 00000 n
-0000161051 00000 n
-0000158967 00000 n
-0000161172 00000 n
-0000161234 00000 n
-0000161297 00000 n
-0000161359 00000 n
-0000161422 00000 n
-0000161485 00000 n
-0000161548 00000 n
-0000161611 00000 n
-0000161674 00000 n
-0000161737 00000 n
-0000161800 00000 n
-0000161863 00000 n
-0000161926 00000 n
-0000161989 00000 n
-0000162052 00000 n
-0000162115 00000 n
-0000162178 00000 n
-0000162241 00000 n
-0000162304 00000 n
-0000162367 00000 n
-0000162430 00000 n
-0000162493 00000 n
-0000162556 00000 n
-0000162619 00000 n
-0000162681 00000 n
-0000162744 00000 n
-0000162807 00000 n
-0000162870 00000 n
-0000162933 00000 n
-0000162996 00000 n
-0000163055 00000 n
-0000163118 00000 n
-0000163181 00000 n
-0000163244 00000 n
-0000163307 00000 n
-0000163370 00000 n
-0000163433 00000 n
-0000163496 00000 n
-0000163559 00000 n
-0000163621 00000 n
-0000163684 00000 n
-0000163747 00000 n
-0000163810 00000 n
-0000163873 00000 n
-0000163936 00000 n
-0000163998 00000 n
-0000164061 00000 n
-0000164124 00000 n
-0000164187 00000 n
-0000164250 00000 n
-0000164313 00000 n
-0000164375 00000 n
-0000844042 00000 n
-0000169082 00000 n
-0000167327 00000 n
-0000164600 00000 n
-0000167448 00000 n
-0000167510 00000 n
-0000167573 00000 n
-0000167635 00000 n
-0000167698 00000 n
-0000167761 00000 n
-0000167824 00000 n
-0000167887 00000 n
-0000167950 00000 n
-0000168013 00000 n
-0000168076 00000 n
-0000168139 00000 n
-0000168202 00000 n
-0000168327 00000 n
-0000168390 00000 n
-0000168453 00000 n
-0000168516 00000 n
-0000168579 00000 n
-0000168642 00000 n
-0000168704 00000 n
-0000168767 00000 n
-0000168830 00000 n
-0000168893 00000 n
-0000168956 00000 n
-0000169019 00000 n
-0000173766 00000 n
-0000172264 00000 n
-0000169284 00000 n
-0000172385 00000 n
-0000172447 00000 n
-0000172510 00000 n
-0000172573 00000 n
-0000172636 00000 n
-0000172699 00000 n
-0000172762 00000 n
-0000172825 00000 n
-0000172888 00000 n
-0000172950 00000 n
-0000173011 00000 n
-0000173074 00000 n
-0000173137 00000 n
-0000173200 00000 n
-0000173263 00000 n
-0000173326 00000 n
-0000173388 00000 n
-0000173451 00000 n
-0000173514 00000 n
-0000173577 00000 n
-0000173640 00000 n
-0000173703 00000 n
-0000178479 00000 n
-0000177227 00000 n
-0000173942 00000 n
-0000177348 00000 n
-0000177410 00000 n
-0000177473 00000 n
-0000177536 00000 n
-0000177599 00000 n
-0000177662 00000 n
-0000177725 00000 n
-0000177788 00000 n
-0000177850 00000 n
-0000177913 00000 n
-0000177976 00000 n
-0000178039 00000 n
-0000178101 00000 n
-0000178164 00000 n
-0000178227 00000 n
-0000178290 00000 n
-0000178353 00000 n
-0000178416 00000 n
-0000183576 00000 n
-0000181004 00000 n
-0000178668 00000 n
-0000181125 00000 n
-0000181187 00000 n
-0000181250 00000 n
-0000181313 00000 n
-0000181376 00000 n
-0000181438 00000 n
-0000181501 00000 n
-0000181564 00000 n
-0000181627 00000 n
-0000181690 00000 n
-0000181753 00000 n
-0000181816 00000 n
-0000181879 00000 n
-0000181942 00000 n
-0000182005 00000 n
-0000182067 00000 n
-0000182130 00000 n
-0000182193 00000 n
-0000182256 00000 n
-0000182319 00000 n
-0000182382 00000 n
-0000182444 00000 n
-0000182507 00000 n
-0000182570 00000 n
-0000182633 00000 n
-0000182696 00000 n
-0000182759 00000 n
-0000182822 00000 n
-0000182884 00000 n
-0000182947 00000 n
-0000183010 00000 n
-0000183073 00000 n
-0000183136 00000 n
-0000183199 00000 n
-0000183262 00000 n
-0000183324 00000 n
-0000183387 00000 n
-0000183450 00000 n
-0000183513 00000 n
-0000189065 00000 n
-0000186807 00000 n
-0000183752 00000 n
-0000186928 00000 n
-0000186990 00000 n
-0000187053 00000 n
-0000187116 00000 n
-0000187179 00000 n
-0000187242 00000 n
-0000187305 00000 n
-0000187368 00000 n
-0000187431 00000 n
-0000187494 00000 n
-0000187557 00000 n
-0000187620 00000 n
-0000187683 00000 n
-0000187745 00000 n
-0000187870 00000 n
-0000187933 00000 n
-0000187996 00000 n
-0000188059 00000 n
-0000188121 00000 n
-0000188184 00000 n
-0000188247 00000 n
-0000188310 00000 n
-0000188373 00000 n
-0000188436 00000 n
-0000188499 00000 n
-0000188562 00000 n
-0000188625 00000 n
-0000188687 00000 n
-0000188750 00000 n
-0000188813 00000 n
-0000188876 00000 n
-0000188939 00000 n
-0000189002 00000 n
-0000195099 00000 n
-0000191525 00000 n
-0000189267 00000 n
-0000191646 00000 n
-0000191708 00000 n
-0000191771 00000 n
-0000191833 00000 n
-0000191896 00000 n
-0000191959 00000 n
-0000192022 00000 n
-0000192085 00000 n
-0000192148 00000 n
-0000192211 00000 n
-0000192274 00000 n
-0000192337 00000 n
-0000192400 00000 n
-0000192463 00000 n
-0000192526 00000 n
-0000192588 00000 n
-0000192651 00000 n
-0000192712 00000 n
-0000192775 00000 n
-0000192838 00000 n
-0000192901 00000 n
-0000192964 00000 n
-0000193027 00000 n
-0000193090 00000 n
-0000193153 00000 n
-0000193216 00000 n
-0000193278 00000 n
-0000193341 00000 n
-0000193404 00000 n
-0000193467 00000 n
-0000193530 00000 n
-0000193593 00000 n
-0000193656 00000 n
-0000193719 00000 n
-0000193782 00000 n
-0000193844 00000 n
-0000193907 00000 n
-0000193970 00000 n
-0000194032 00000 n
-0000194095 00000 n
-0000194157 00000 n
-0000194220 00000 n
-0000194283 00000 n
-0000194346 00000 n
-0000194409 00000 n
-0000194472 00000 n
-0000194535 00000 n
-0000194598 00000 n
-0000194661 00000 n
-0000194724 00000 n
-0000194786 00000 n
-0000194849 00000 n
-0000194912 00000 n
-0000194975 00000 n
-0000195037 00000 n
-0000198366 00000 n
-0000198526 00000 n
-0000200763 00000 n
-0000198192 00000 n
-0000195262 00000 n
-0000198687 00000 n
-0000198749 00000 n
-0000198812 00000 n
-0000198874 00000 n
-0000198937 00000 n
-0000199000 00000 n
-0000199063 00000 n
-0000199126 00000 n
-0000199189 00000 n
-0000199252 00000 n
-0000199315 00000 n
-0000199378 00000 n
-0000199441 00000 n
-0000199504 00000 n
-0000199567 00000 n
-0000199630 00000 n
-0000199692 00000 n
-0000199755 00000 n
-0000199818 00000 n
-0000199881 00000 n
-0000199944 00000 n
-0000200007 00000 n
-0000200070 00000 n
-0000200133 00000 n
-0000200196 00000 n
-0000200259 00000 n
-0000200322 00000 n
-0000200385 00000 n
-0000200448 00000 n
-0000200511 00000 n
-0000200574 00000 n
-0000200637 00000 n
-0000200700 00000 n
-0000198329 00000 n
-0000206388 00000 n
-0000202825 00000 n
-0000200926 00000 n
-0000202948 00000 n
-0000203012 00000 n
-0000203077 00000 n
-0000203142 00000 n
-0000203207 00000 n
-0000203271 00000 n
-0000203336 00000 n
-0000203401 00000 n
-0000203466 00000 n
-0000203531 00000 n
-0000203596 00000 n
-0000203661 00000 n
-0000203726 00000 n
-0000203791 00000 n
-0000203856 00000 n
-0000203921 00000 n
-0000203986 00000 n
-0000204051 00000 n
-0000204116 00000 n
-0000204179 00000 n
-0000204244 00000 n
-0000204309 00000 n
-0000204374 00000 n
-0000204439 00000 n
-0000204504 00000 n
-0000204569 00000 n
-0000204634 00000 n
-0000204699 00000 n
-0000204764 00000 n
-0000204829 00000 n
-0000204894 00000 n
-0000204959 00000 n
-0000205024 00000 n
-0000205089 00000 n
-0000205154 00000 n
-0000205218 00000 n
-0000205283 00000 n
-0000205348 00000 n
-0000205413 00000 n
-0000205478 00000 n
-0000205543 00000 n
-0000205608 00000 n
-0000205673 00000 n
-0000205738 00000 n
-0000205803 00000 n
-0000205868 00000 n
-0000205933 00000 n
-0000205998 00000 n
-0000206063 00000 n
-0000206128 00000 n
-0000206193 00000 n
-0000206258 00000 n
-0000206323 00000 n
-0000212331 00000 n
-0000208255 00000 n
-0000206551 00000 n
-0000208379 00000 n
-0000208506 00000 n
-0000208571 00000 n
+0000053832 00000 n
+0000054234 00000 n
+0000053169 00000 n
+0000049258 00000 n
+0000053988 00000 n
+0000054172 00000 n
+0000053306 00000 n
+0000057869 00000 n
+0000058026 00000 n
+0000062487 00000 n
+0000058490 00000 n
+0000057695 00000 n
+0000054514 00000 n
+0000058181 00000 n
+0000623309 00000 n
+0000058364 00000 n
+0000058427 00000 n
+0000057832 00000 n
+0000062647 00000 n
+0000062804 00000 n
+0000063338 00000 n
+0000062305 00000 n
+0000058757 00000 n
+0000062961 00000 n
+0000063023 00000 n
+0000063087 00000 n
+0000063212 00000 n
+0000063275 00000 n
+0000062442 00000 n
+0000067866 00000 n
+0000068022 00000 n
+0000068610 00000 n
+0000067692 00000 n
+0000063631 00000 n
+0000068178 00000 n
+0000068484 00000 n
+0000068547 00000 n
+0000067829 00000 n
+0000073054 00000 n
+0000072688 00000 n
+0000068877 00000 n
+0000072809 00000 n
+0000076223 00000 n
+0000076040 00000 n
+0000073295 00000 n
+0000076161 00000 n
+0000846936 00000 n
+0000079809 00000 n
+0000079966 00000 n
+0000080127 00000 n
+0000080472 00000 n
+0000079627 00000 n
+0000076438 00000 n
+0000080288 00000 n
+0000080411 00000 n
+0000079764 00000 n
+0000084508 00000 n
+0000084669 00000 n
+0000084830 00000 n
+0000084991 00000 n
+0000085152 00000 n
+0000085553 00000 n
+0000084310 00000 n
+0000080739 00000 n
+0000085309 00000 n
+0000085492 00000 n
+0000084447 00000 n
+0000089448 00000 n
+0000089079 00000 n
+0000085820 00000 n
+0000089200 00000 n
+0000093044 00000 n
+0000092799 00000 n
+0000089676 00000 n
+0000092920 00000 n
+0000097760 00000 n
+0000097917 00000 n
+0000098074 00000 n
+0000098231 00000 n
+0000098886 00000 n
+0000097570 00000 n
+0000093220 00000 n
+0000098388 00000 n
+0000845902 00000 n
+0000845003 00000 n
+0000098635 00000 n
+0000098698 00000 n
+0000098761 00000 n
+0000098824 00000 n
+0000097707 00000 n
+0000102166 00000 n
+0000101921 00000 n
+0000099244 00000 n
+0000102042 00000 n
+0000106845 00000 n
+0000107006 00000 n
+0000107167 00000 n
+0000107327 00000 n
+0000107493 00000 n
+0000107659 00000 n
+0000107818 00000 n
+0000108224 00000 n
+0000106631 00000 n
+0000102355 00000 n
+0000107977 00000 n
+0000106768 00000 n
+0000112412 00000 n
+0000112043 00000 n
+0000108426 00000 n
+0000112164 00000 n
+0000116164 00000 n
+0000116325 00000 n
+0000116486 00000 n
+0000116641 00000 n
+0000117047 00000 n
+0000115974 00000 n
+0000112614 00000 n
+0000116798 00000 n
+0000116921 00000 n
+0000116984 00000 n
+0000116111 00000 n
+0000120780 00000 n
+0000120937 00000 n
+0000121094 00000 n
+0000121254 00000 n
+0000121414 00000 n
+0000121571 00000 n
+0000122061 00000 n
+0000120574 00000 n
+0000117288 00000 n
+0000121751 00000 n
+0000619751 00000 n
+0000121813 00000 n
+0000121875 00000 n
+0000121999 00000 n
+0000847089 00000 n
+0000120711 00000 n
+0000124887 00000 n
+0000125043 00000 n
+0000125323 00000 n
+0000124713 00000 n
+0000122328 00000 n
+0000125199 00000 n
+0000617552 00000 n
+0000605379 00000 n
+0000590725 00000 n
+0000124850 00000 n
+0000129380 00000 n
+0000129537 00000 n
+0000129963 00000 n
+0000129206 00000 n
+0000125567 00000 n
+0000129715 00000 n
+0000129901 00000 n
+0000129343 00000 n
+0000133431 00000 n
+0000133186 00000 n
+0000130204 00000 n
+0000133307 00000 n
+0000137021 00000 n
+0000136776 00000 n
+0000133594 00000 n
+0000136897 00000 n
+0000140409 00000 n
+0000140164 00000 n
+0000137210 00000 n
+0000140285 00000 n
+0000142136 00000 n
+0000142297 00000 n
+0000142582 00000 n
+0000141962 00000 n
+0000140585 00000 n
+0000142458 00000 n
+0000142099 00000 n
+0000146342 00000 n
+0000146497 00000 n
+0000146653 00000 n
+0000146810 00000 n
+0000147404 00000 n
+0000146152 00000 n
+0000142745 00000 n
+0000146967 00000 n
+0000147152 00000 n
+0000147215 00000 n
+0000147278 00000 n
+0000147341 00000 n
+0000146289 00000 n
+0000153409 00000 n
+0000150840 00000 n
+0000147697 00000 n
+0000150961 00000 n
+0000844677 00000 n
+0000151147 00000 n
+0000846080 00000 n
+0000846610 00000 n
+0000151210 00000 n
+0000151273 00000 n
+0000151336 00000 n
+0000151399 00000 n
+0000151461 00000 n
+0000151524 00000 n
+0000151587 00000 n
+0000151650 00000 n
+0000151713 00000 n
+0000151776 00000 n
+0000151838 00000 n
+0000151901 00000 n
+0000151964 00000 n
+0000152027 00000 n
+0000152090 00000 n
+0000152153 00000 n
+0000152216 00000 n
+0000152279 00000 n
+0000152342 00000 n
+0000152404 00000 n
+0000152467 00000 n
+0000152530 00000 n
+0000152593 00000 n
+0000152656 00000 n
+0000152719 00000 n
+0000152782 00000 n
+0000152845 00000 n
+0000152908 00000 n
+0000152971 00000 n
+0000153034 00000 n
+0000153097 00000 n
+0000153160 00000 n
+0000153223 00000 n
+0000153285 00000 n
+0000153347 00000 n
+0000159103 00000 n
+0000155965 00000 n
+0000153639 00000 n
+0000156086 00000 n
+0000156148 00000 n
+0000156211 00000 n
+0000156273 00000 n
+0000156336 00000 n
+0000156399 00000 n
+0000156462 00000 n
+0000156525 00000 n
+0000156588 00000 n
+0000156651 00000 n
+0000156714 00000 n
+0000156777 00000 n
+0000156840 00000 n
+0000156903 00000 n
+0000156966 00000 n
+0000157028 00000 n
+0000157091 00000 n
+0000157154 00000 n
+0000157217 00000 n
+0000157280 00000 n
+0000157343 00000 n
+0000157406 00000 n
+0000157469 00000 n
+0000157532 00000 n
+0000157595 00000 n
+0000157658 00000 n
+0000157721 00000 n
+0000157784 00000 n
+0000157847 00000 n
+0000157910 00000 n
+0000157973 00000 n
+0000158036 00000 n
+0000158099 00000 n
+0000158162 00000 n
+0000158225 00000 n
+0000158287 00000 n
+0000158350 00000 n
+0000158413 00000 n
+0000158476 00000 n
+0000158539 00000 n
+0000158602 00000 n
+0000158665 00000 n
+0000158728 00000 n
+0000158791 00000 n
+0000158853 00000 n
+0000158916 00000 n
+0000158979 00000 n
+0000159041 00000 n
+0000164736 00000 n
+0000161350 00000 n
+0000159266 00000 n
+0000161471 00000 n
+0000161533 00000 n
+0000161596 00000 n
+0000161658 00000 n
+0000161721 00000 n
+0000161784 00000 n
+0000161847 00000 n
+0000161910 00000 n
+0000161973 00000 n
+0000162036 00000 n
+0000162099 00000 n
+0000162162 00000 n
+0000162225 00000 n
+0000162288 00000 n
+0000162351 00000 n
+0000162414 00000 n
+0000162477 00000 n
+0000162540 00000 n
+0000162603 00000 n
+0000162666 00000 n
+0000162729 00000 n
+0000162792 00000 n
+0000162855 00000 n
+0000162918 00000 n
+0000162980 00000 n
+0000163043 00000 n
+0000163106 00000 n
+0000163169 00000 n
+0000163232 00000 n
+0000163295 00000 n
+0000163354 00000 n
+0000163417 00000 n
+0000163480 00000 n
+0000163543 00000 n
+0000163606 00000 n
+0000163669 00000 n
+0000163732 00000 n
+0000163795 00000 n
+0000163858 00000 n
+0000163920 00000 n
+0000163983 00000 n
+0000164046 00000 n
+0000164109 00000 n
+0000164172 00000 n
+0000164235 00000 n
+0000164297 00000 n
+0000164360 00000 n
+0000164423 00000 n
+0000164486 00000 n
+0000164549 00000 n
+0000164612 00000 n
+0000164674 00000 n
+0000847242 00000 n
+0000169463 00000 n
+0000167708 00000 n
+0000164899 00000 n
+0000167829 00000 n
+0000167891 00000 n
+0000167954 00000 n
+0000168016 00000 n
+0000168079 00000 n
+0000168142 00000 n
+0000168205 00000 n
+0000168268 00000 n
+0000168331 00000 n
+0000168394 00000 n
+0000168457 00000 n
+0000168520 00000 n
+0000168583 00000 n
+0000168708 00000 n
+0000168771 00000 n
+0000168834 00000 n
+0000168897 00000 n
+0000168960 00000 n
+0000169023 00000 n
+0000169085 00000 n
+0000169148 00000 n
+0000169211 00000 n
+0000169274 00000 n
+0000169337 00000 n
+0000169400 00000 n
+0000174147 00000 n
+0000172645 00000 n
+0000169665 00000 n
+0000172766 00000 n
+0000172828 00000 n
+0000172891 00000 n
+0000172954 00000 n
+0000173017 00000 n
+0000173080 00000 n
+0000173143 00000 n
+0000173206 00000 n
+0000173269 00000 n
+0000173331 00000 n
+0000173392 00000 n
+0000173455 00000 n
+0000173518 00000 n
+0000173581 00000 n
+0000173644 00000 n
+0000173707 00000 n
+0000173769 00000 n
+0000173832 00000 n
+0000173895 00000 n
+0000173958 00000 n
+0000174021 00000 n
+0000174084 00000 n
+0000178860 00000 n
+0000177608 00000 n
+0000174323 00000 n
+0000177729 00000 n
+0000177791 00000 n
+0000177854 00000 n
+0000177917 00000 n
+0000177980 00000 n
+0000178043 00000 n
+0000178106 00000 n
+0000178169 00000 n
+0000178231 00000 n
+0000178294 00000 n
+0000178357 00000 n
+0000178420 00000 n
+0000178482 00000 n
+0000178545 00000 n
+0000178608 00000 n
+0000178671 00000 n
+0000178734 00000 n
+0000178797 00000 n
+0000183957 00000 n
+0000181385 00000 n
+0000179049 00000 n
+0000181506 00000 n
+0000181568 00000 n
+0000181631 00000 n
+0000181694 00000 n
+0000181757 00000 n
+0000181819 00000 n
+0000181882 00000 n
+0000181945 00000 n
+0000182008 00000 n
+0000182071 00000 n
+0000182134 00000 n
+0000182197 00000 n
+0000182260 00000 n
+0000182323 00000 n
+0000182386 00000 n
+0000182448 00000 n
+0000182511 00000 n
+0000182574 00000 n
+0000182637 00000 n
+0000182700 00000 n
+0000182763 00000 n
+0000182825 00000 n
+0000182888 00000 n
+0000182951 00000 n
+0000183014 00000 n
+0000183077 00000 n
+0000183140 00000 n
+0000183203 00000 n
+0000183265 00000 n
+0000183328 00000 n
+0000183391 00000 n
+0000183454 00000 n
+0000183517 00000 n
+0000183580 00000 n
+0000183643 00000 n
+0000183705 00000 n
+0000183768 00000 n
+0000183831 00000 n
+0000183894 00000 n
+0000189446 00000 n
+0000187188 00000 n
+0000184133 00000 n
+0000187309 00000 n
+0000187371 00000 n
+0000187434 00000 n
+0000187497 00000 n
+0000187560 00000 n
+0000187623 00000 n
+0000187686 00000 n
+0000187749 00000 n
+0000187812 00000 n
+0000187875 00000 n
+0000187938 00000 n
+0000188001 00000 n
+0000188064 00000 n
+0000188126 00000 n
+0000188251 00000 n
+0000188314 00000 n
+0000188377 00000 n
+0000188440 00000 n
+0000188502 00000 n
+0000188565 00000 n
+0000188628 00000 n
+0000188691 00000 n
+0000188754 00000 n
+0000188817 00000 n
+0000188880 00000 n
+0000188943 00000 n
+0000189006 00000 n
+0000189068 00000 n
+0000189131 00000 n
+0000189194 00000 n
+0000189257 00000 n
+0000189320 00000 n
+0000189383 00000 n
+0000195480 00000 n
+0000191906 00000 n
+0000189648 00000 n
+0000192027 00000 n
+0000192089 00000 n
+0000192152 00000 n
+0000192214 00000 n
+0000192277 00000 n
+0000192340 00000 n
+0000192403 00000 n
+0000192466 00000 n
+0000192529 00000 n
+0000192592 00000 n
+0000192655 00000 n
+0000192718 00000 n
+0000192781 00000 n
+0000192844 00000 n
+0000192907 00000 n
+0000192969 00000 n
+0000193032 00000 n
+0000193093 00000 n
+0000193156 00000 n
+0000193219 00000 n
+0000193282 00000 n
+0000193345 00000 n
+0000193408 00000 n
+0000193471 00000 n
+0000193534 00000 n
+0000193597 00000 n
+0000193659 00000 n
+0000193722 00000 n
+0000193785 00000 n
+0000193848 00000 n
+0000193911 00000 n
+0000193974 00000 n
+0000194037 00000 n
+0000194100 00000 n
+0000194163 00000 n
+0000194225 00000 n
+0000194288 00000 n
+0000194351 00000 n
+0000194413 00000 n
+0000194476 00000 n
+0000194538 00000 n
+0000194601 00000 n
+0000194664 00000 n
+0000194727 00000 n
+0000194790 00000 n
+0000194853 00000 n
+0000194916 00000 n
+0000194979 00000 n
+0000195042 00000 n
+0000195105 00000 n
+0000195167 00000 n
+0000195230 00000 n
+0000195293 00000 n
+0000195356 00000 n
+0000195418 00000 n
+0000198747 00000 n
+0000198907 00000 n
+0000201144 00000 n
+0000198573 00000 n
+0000195643 00000 n
+0000199068 00000 n
+0000199130 00000 n
+0000199193 00000 n
+0000199255 00000 n
+0000199318 00000 n
+0000199381 00000 n
+0000199444 00000 n
+0000199507 00000 n
+0000199570 00000 n
+0000199633 00000 n
+0000199696 00000 n
+0000199759 00000 n
+0000199822 00000 n
+0000199885 00000 n
+0000199948 00000 n
+0000200011 00000 n
+0000200073 00000 n
+0000200136 00000 n
+0000200199 00000 n
+0000200262 00000 n
+0000200325 00000 n
+0000200388 00000 n
+0000200451 00000 n
+0000200514 00000 n
+0000200577 00000 n
+0000200640 00000 n
+0000200703 00000 n
+0000200766 00000 n
+0000200829 00000 n
+0000200892 00000 n
+0000200955 00000 n
+0000201018 00000 n
+0000201081 00000 n
+0000198710 00000 n
+0000206769 00000 n
+0000203206 00000 n
+0000201307 00000 n
+0000203329 00000 n
+0000203393 00000 n
+0000203458 00000 n
+0000203523 00000 n
+0000203588 00000 n
+0000203652 00000 n
+0000203717 00000 n
+0000203782 00000 n
+0000203847 00000 n
+0000203912 00000 n
+0000203977 00000 n
+0000204042 00000 n
+0000204107 00000 n
+0000204172 00000 n
+0000204237 00000 n
+0000204302 00000 n
+0000204367 00000 n
+0000204432 00000 n
+0000204497 00000 n
+0000204560 00000 n
+0000204625 00000 n
+0000204690 00000 n
+0000204755 00000 n
+0000204820 00000 n
+0000204885 00000 n
+0000204950 00000 n
+0000205015 00000 n
+0000205080 00000 n
+0000205145 00000 n
+0000205210 00000 n
+0000205275 00000 n
+0000205340 00000 n
+0000205405 00000 n
+0000205470 00000 n
+0000205535 00000 n
+0000205599 00000 n
+0000205664 00000 n
+0000205729 00000 n
+0000205794 00000 n
+0000205859 00000 n
+0000205924 00000 n
+0000205989 00000 n
+0000206054 00000 n
+0000206119 00000 n
+0000206184 00000 n
+0000206249 00000 n
+0000206314 00000 n
+0000206379 00000 n
+0000206444 00000 n
+0000206509 00000 n
+0000206574 00000 n
+0000206639 00000 n
+0000206704 00000 n
+0000212712 00000 n
0000208636 00000 n
-0000208701 00000 n
-0000208766 00000 n
-0000208831 00000 n
-0000208896 00000 n
-0000208960 00000 n
-0000209025 00000 n
-0000209090 00000 n
-0000209155 00000 n
-0000209220 00000 n
-0000209285 00000 n
-0000209350 00000 n
-0000209415 00000 n
-0000209480 00000 n
-0000209545 00000 n
-0000209608 00000 n
-0000209673 00000 n
-0000209738 00000 n
-0000209803 00000 n
-0000209868 00000 n
-0000209933 00000 n
-0000209998 00000 n
-0000210063 00000 n
-0000210128 00000 n
-0000210193 00000 n
-0000210257 00000 n
-0000210322 00000 n
-0000210387 00000 n
-0000210452 00000 n
-0000210517 00000 n
-0000210582 00000 n
-0000210647 00000 n
-0000210712 00000 n
-0000210777 00000 n
-0000210842 00000 n
-0000210906 00000 n
-0000210971 00000 n
-0000211036 00000 n
-0000211101 00000 n
-0000211166 00000 n
-0000211231 00000 n
-0000211296 00000 n
-0000211361 00000 n
-0000211426 00000 n
-0000211489 00000 n
-0000211554 00000 n
-0000211619 00000 n
-0000211684 00000 n
-0000211749 00000 n
-0000211814 00000 n
-0000211879 00000 n
-0000211944 00000 n
-0000212009 00000 n
-0000212073 00000 n
-0000212138 00000 n
-0000212203 00000 n
-0000212267 00000 n
-0000218380 00000 n
-0000214626 00000 n
-0000212495 00000 n
-0000214751 00000 n
-0000214815 00000 n
-0000214880 00000 n
-0000214944 00000 n
-0000215009 00000 n
-0000215074 00000 n
-0000215139 00000 n
+0000206932 00000 n
+0000208760 00000 n
+0000208887 00000 n
+0000208952 00000 n
+0000209017 00000 n
+0000209082 00000 n
+0000209147 00000 n
+0000209212 00000 n
+0000209277 00000 n
+0000209341 00000 n
+0000209406 00000 n
+0000209471 00000 n
+0000209536 00000 n
+0000209601 00000 n
+0000209666 00000 n
+0000209731 00000 n
+0000209796 00000 n
+0000209861 00000 n
+0000209926 00000 n
+0000209989 00000 n
+0000210054 00000 n
+0000210119 00000 n
+0000210184 00000 n
+0000210249 00000 n
+0000210314 00000 n
+0000210379 00000 n
+0000210444 00000 n
+0000210509 00000 n
+0000210574 00000 n
+0000210638 00000 n
+0000210703 00000 n
+0000210768 00000 n
+0000210833 00000 n
+0000210898 00000 n
+0000210963 00000 n
+0000211028 00000 n
+0000211093 00000 n
+0000211158 00000 n
+0000211223 00000 n
+0000211287 00000 n
+0000211352 00000 n
+0000211417 00000 n
+0000211482 00000 n
+0000211547 00000 n
+0000211612 00000 n
+0000211677 00000 n
+0000211742 00000 n
+0000211807 00000 n
+0000211870 00000 n
+0000211935 00000 n
+0000212000 00000 n
+0000212065 00000 n
+0000212130 00000 n
+0000212195 00000 n
+0000212260 00000 n
+0000212325 00000 n
+0000212390 00000 n
+0000212454 00000 n
+0000212519 00000 n
+0000212584 00000 n
+0000212648 00000 n
+0000218769 00000 n
+0000215015 00000 n
+0000212876 00000 n
+0000215140 00000 n
0000215204 00000 n
0000215269 00000 n
-0000215334 00000 n
-0000215399 00000 n
-0000215464 00000 n
+0000215333 00000 n
+0000215398 00000 n
+0000215463 00000 n
0000215528 00000 n
0000215593 00000 n
0000215658 00000 n
@@ -17239,31 +17300,31 @@ xref
0000215917 00000 n
0000215982 00000 n
0000216047 00000 n
-0000216111 00000 n
-0000216176 00000 n
-0000216241 00000 n
+0000216112 00000 n
+0000216177 00000 n
+0000216242 00000 n
0000216306 00000 n
0000216371 00000 n
0000216436 00000 n
-0000216501 00000 n
+0000216500 00000 n
0000216565 00000 n
0000216630 00000 n
0000216695 00000 n
0000216760 00000 n
0000216825 00000 n
0000216890 00000 n
-0000216955 00000 n
-0000217020 00000 n
-0000217085 00000 n
+0000216954 00000 n
+0000217019 00000 n
+0000217084 00000 n
0000217149 00000 n
0000217214 00000 n
0000217279 00000 n
0000217344 00000 n
0000217409 00000 n
0000217474 00000 n
-0000217539 00000 n
-0000217604 00000 n
-0000217669 00000 n
+0000217538 00000 n
+0000217603 00000 n
+0000217668 00000 n
0000217733 00000 n
0000217798 00000 n
0000217863 00000 n
@@ -17273,3311 +17334,3340 @@ xref
0000218122 00000 n
0000218187 00000 n
0000218252 00000 n
-0000218316 00000 n
-0000844197 00000 n
-0000224708 00000 n
-0000220432 00000 n
-0000218557 00000 n
-0000220557 00000 n
-0000220621 00000 n
-0000220686 00000 n
-0000220750 00000 n
-0000220815 00000 n
-0000220880 00000 n
-0000220945 00000 n
-0000221010 00000 n
-0000221075 00000 n
-0000221140 00000 n
-0000221205 00000 n
-0000221270 00000 n
-0000221334 00000 n
-0000221399 00000 n
-0000221464 00000 n
-0000221529 00000 n
-0000221594 00000 n
-0000221659 00000 n
-0000221724 00000 n
-0000221789 00000 n
-0000221854 00000 n
-0000221918 00000 n
-0000221983 00000 n
-0000222048 00000 n
-0000222113 00000 n
-0000222178 00000 n
-0000222243 00000 n
-0000222308 00000 n
-0000222373 00000 n
-0000222438 00000 n
-0000222502 00000 n
-0000222567 00000 n
-0000222632 00000 n
-0000222697 00000 n
-0000222762 00000 n
-0000222827 00000 n
-0000222892 00000 n
-0000222957 00000 n
-0000223022 00000 n
-0000223086 00000 n
-0000223151 00000 n
-0000223216 00000 n
-0000223281 00000 n
-0000223346 00000 n
-0000223411 00000 n
-0000223476 00000 n
-0000223541 00000 n
-0000223606 00000 n
-0000223670 00000 n
-0000223735 00000 n
-0000223800 00000 n
-0000223865 00000 n
-0000223930 00000 n
-0000223995 00000 n
-0000224060 00000 n
-0000224125 00000 n
-0000224190 00000 n
-0000224254 00000 n
-0000224319 00000 n
-0000224384 00000 n
-0000224449 00000 n
-0000224514 00000 n
-0000224579 00000 n
-0000224644 00000 n
-0000230992 00000 n
-0000226783 00000 n
-0000224859 00000 n
-0000226908 00000 n
-0000226972 00000 n
-0000227037 00000 n
-0000227101 00000 n
-0000227166 00000 n
-0000227231 00000 n
-0000227296 00000 n
-0000227361 00000 n
-0000227426 00000 n
-0000227491 00000 n
-0000227556 00000 n
-0000227621 00000 n
-0000227685 00000 n
-0000227750 00000 n
-0000227815 00000 n
-0000227880 00000 n
-0000227945 00000 n
-0000228010 00000 n
-0000228075 00000 n
-0000228140 00000 n
-0000228205 00000 n
-0000228269 00000 n
-0000228334 00000 n
-0000228399 00000 n
-0000228464 00000 n
-0000228529 00000 n
-0000228594 00000 n
-0000228659 00000 n
-0000228724 00000 n
-0000228789 00000 n
-0000228853 00000 n
-0000228918 00000 n
-0000228983 00000 n
-0000229048 00000 n
-0000229113 00000 n
-0000229178 00000 n
-0000229243 00000 n
-0000229308 00000 n
-0000229373 00000 n
-0000229437 00000 n
-0000229502 00000 n
-0000229567 00000 n
-0000229632 00000 n
-0000229697 00000 n
-0000229762 00000 n
-0000229827 00000 n
-0000229892 00000 n
-0000229957 00000 n
-0000230021 00000 n
-0000230086 00000 n
-0000230151 00000 n
-0000230216 00000 n
-0000230281 00000 n
-0000230346 00000 n
-0000230411 00000 n
-0000230476 00000 n
-0000230541 00000 n
-0000230605 00000 n
-0000230670 00000 n
-0000230735 00000 n
-0000230800 00000 n
-0000230864 00000 n
-0000230928 00000 n
-0000236577 00000 n
-0000233471 00000 n
-0000231143 00000 n
-0000233596 00000 n
-0000233660 00000 n
-0000233725 00000 n
-0000233789 00000 n
-0000233854 00000 n
-0000233919 00000 n
-0000233984 00000 n
-0000234049 00000 n
-0000234114 00000 n
-0000234179 00000 n
-0000234244 00000 n
-0000234308 00000 n
-0000234436 00000 n
-0000234501 00000 n
-0000234566 00000 n
-0000234631 00000 n
-0000234696 00000 n
-0000234761 00000 n
-0000234826 00000 n
-0000234891 00000 n
-0000234956 00000 n
-0000235021 00000 n
-0000235085 00000 n
-0000235150 00000 n
-0000235215 00000 n
-0000235280 00000 n
-0000235345 00000 n
-0000235410 00000 n
-0000235475 00000 n
-0000235540 00000 n
-0000235668 00000 n
-0000235733 00000 n
-0000235798 00000 n
-0000235863 00000 n
-0000235928 00000 n
-0000235993 00000 n
-0000236057 00000 n
-0000236122 00000 n
-0000236187 00000 n
-0000236252 00000 n
-0000236317 00000 n
-0000236382 00000 n
-0000236447 00000 n
-0000236512 00000 n
-0000242643 00000 n
-0000239018 00000 n
-0000236754 00000 n
-0000239143 00000 n
-0000239207 00000 n
-0000239272 00000 n
-0000239336 00000 n
-0000239401 00000 n
-0000239466 00000 n
-0000239531 00000 n
-0000239596 00000 n
-0000239661 00000 n
-0000239788 00000 n
-0000239853 00000 n
-0000239918 00000 n
-0000239983 00000 n
-0000240047 00000 n
-0000240111 00000 n
-0000240176 00000 n
-0000240241 00000 n
-0000240306 00000 n
-0000240371 00000 n
-0000240436 00000 n
-0000240500 00000 n
-0000240565 00000 n
-0000240630 00000 n
-0000240695 00000 n
-0000240760 00000 n
-0000240825 00000 n
-0000240890 00000 n
-0000240955 00000 n
-0000241020 00000 n
-0000241085 00000 n
-0000241150 00000 n
-0000241215 00000 n
-0000241280 00000 n
-0000241345 00000 n
-0000241410 00000 n
-0000241475 00000 n
-0000241540 00000 n
-0000241605 00000 n
-0000241670 00000 n
-0000241735 00000 n
-0000241800 00000 n
-0000241865 00000 n
-0000241930 00000 n
-0000241995 00000 n
-0000242060 00000 n
-0000242125 00000 n
-0000242190 00000 n
-0000242255 00000 n
-0000242320 00000 n
-0000242385 00000 n
-0000242450 00000 n
-0000242515 00000 n
-0000242579 00000 n
-0000248532 00000 n
-0000244842 00000 n
-0000242820 00000 n
-0000244967 00000 n
-0000245031 00000 n
-0000245096 00000 n
-0000245160 00000 n
-0000245225 00000 n
-0000245290 00000 n
-0000245355 00000 n
-0000245420 00000 n
-0000245485 00000 n
-0000245549 00000 n
-0000245614 00000 n
-0000245679 00000 n
-0000245744 00000 n
-0000245809 00000 n
-0000245874 00000 n
-0000245939 00000 n
-0000246004 00000 n
-0000246069 00000 n
-0000246133 00000 n
-0000246198 00000 n
-0000246263 00000 n
-0000246328 00000 n
-0000246393 00000 n
-0000246458 00000 n
-0000246523 00000 n
-0000246588 00000 n
-0000246653 00000 n
-0000246716 00000 n
-0000246781 00000 n
-0000246846 00000 n
-0000246911 00000 n
-0000246976 00000 n
-0000247041 00000 n
-0000247106 00000 n
-0000247171 00000 n
-0000247236 00000 n
-0000247301 00000 n
-0000247366 00000 n
-0000247431 00000 n
-0000247496 00000 n
-0000247560 00000 n
-0000247625 00000 n
-0000247690 00000 n
-0000247755 00000 n
-0000247820 00000 n
-0000247885 00000 n
-0000247950 00000 n
-0000248015 00000 n
-0000248080 00000 n
-0000248145 00000 n
-0000248209 00000 n
-0000248274 00000 n
-0000248339 00000 n
-0000248404 00000 n
-0000248468 00000 n
-0000254998 00000 n
-0000251505 00000 n
-0000248696 00000 n
-0000251630 00000 n
-0000251694 00000 n
-0000251759 00000 n
-0000251823 00000 n
-0000251888 00000 n
-0000251953 00000 n
-0000252018 00000 n
-0000252083 00000 n
-0000252148 00000 n
-0000252213 00000 n
-0000252278 00000 n
-0000252343 00000 n
-0000252407 00000 n
-0000252472 00000 n
-0000252537 00000 n
-0000252602 00000 n
-0000252667 00000 n
-0000252732 00000 n
-0000252797 00000 n
-0000252862 00000 n
-0000252927 00000 n
-0000252992 00000 n
-0000253057 00000 n
-0000253122 00000 n
-0000253187 00000 n
-0000253252 00000 n
-0000253317 00000 n
-0000253382 00000 n
-0000253447 00000 n
-0000253511 00000 n
-0000253576 00000 n
-0000253641 00000 n
-0000253706 00000 n
-0000253770 00000 n
-0000253835 00000 n
-0000253900 00000 n
-0000253965 00000 n
-0000254030 00000 n
-0000254095 00000 n
-0000254160 00000 n
-0000254225 00000 n
-0000254290 00000 n
-0000254351 00000 n
-0000254416 00000 n
-0000254481 00000 n
-0000254546 00000 n
-0000254611 00000 n
-0000254676 00000 n
-0000254741 00000 n
-0000254806 00000 n
-0000254871 00000 n
-0000254934 00000 n
-0000258543 00000 n
-0000261358 00000 n
-0000258370 00000 n
-0000255162 00000 n
-0000258701 00000 n
-0000258765 00000 n
-0000258830 00000 n
-0000258894 00000 n
-0000258959 00000 n
-0000259024 00000 n
-0000259089 00000 n
-0000259153 00000 n
-0000259218 00000 n
-0000259283 00000 n
-0000259348 00000 n
-0000259413 00000 n
-0000259478 00000 n
-0000259543 00000 n
-0000259607 00000 n
-0000259672 00000 n
-0000259737 00000 n
-0000259802 00000 n
-0000259866 00000 n
-0000259931 00000 n
-0000259996 00000 n
-0000260061 00000 n
-0000260125 00000 n
-0000260190 00000 n
-0000260255 00000 n
-0000260320 00000 n
-0000260385 00000 n
-0000260450 00000 n
-0000260515 00000 n
-0000260580 00000 n
-0000260645 00000 n
-0000260709 00000 n
-0000260774 00000 n
-0000260839 00000 n
-0000260904 00000 n
-0000260969 00000 n
-0000261034 00000 n
-0000261099 00000 n
-0000261164 00000 n
-0000261229 00000 n
-0000261294 00000 n
-0000258512 00000 n
-0000267548 00000 n
-0000264313 00000 n
-0000261587 00000 n
-0000264438 00000 n
-0000264502 00000 n
-0000264567 00000 n
-0000264631 00000 n
-0000264696 00000 n
-0000264761 00000 n
-0000264826 00000 n
-0000264891 00000 n
-0000264956 00000 n
-0000265021 00000 n
-0000265086 00000 n
-0000265151 00000 n
-0000265216 00000 n
-0000265281 00000 n
-0000265346 00000 n
-0000265411 00000 n
-0000265476 00000 n
-0000265540 00000 n
-0000265605 00000 n
-0000265670 00000 n
-0000265735 00000 n
-0000265800 00000 n
-0000265865 00000 n
-0000265930 00000 n
-0000265995 00000 n
-0000266060 00000 n
-0000266124 00000 n
-0000266189 00000 n
-0000266254 00000 n
-0000266318 00000 n
-0000266383 00000 n
-0000266448 00000 n
-0000266513 00000 n
-0000266578 00000 n
-0000266643 00000 n
-0000266706 00000 n
-0000266771 00000 n
-0000266836 00000 n
-0000266901 00000 n
-0000266966 00000 n
-0000267031 00000 n
-0000267096 00000 n
-0000267161 00000 n
-0000267226 00000 n
-0000267290 00000 n
-0000267355 00000 n
-0000267420 00000 n
-0000267484 00000 n
-0000273121 00000 n
-0000270207 00000 n
-0000267712 00000 n
-0000270332 00000 n
-0000270396 00000 n
-0000270460 00000 n
-0000270525 00000 n
-0000270590 00000 n
-0000270655 00000 n
-0000270719 00000 n
-0000270784 00000 n
-0000270849 00000 n
-0000270914 00000 n
-0000270979 00000 n
-0000271044 00000 n
-0000271109 00000 n
-0000271174 00000 n
-0000271239 00000 n
-0000271304 00000 n
-0000271369 00000 n
-0000271434 00000 n
-0000271499 00000 n
-0000271564 00000 n
-0000271629 00000 n
-0000271694 00000 n
-0000271759 00000 n
-0000271824 00000 n
-0000271888 00000 n
-0000271953 00000 n
-0000272018 00000 n
-0000272083 00000 n
-0000272147 00000 n
-0000272212 00000 n
-0000272277 00000 n
-0000272342 00000 n
-0000272407 00000 n
-0000272472 00000 n
-0000272537 00000 n
-0000272602 00000 n
-0000272667 00000 n
-0000272731 00000 n
-0000272796 00000 n
-0000272861 00000 n
-0000272926 00000 n
-0000272991 00000 n
-0000273056 00000 n
-0000279711 00000 n
-0000275828 00000 n
-0000273298 00000 n
-0000275953 00000 n
-0000276017 00000 n
-0000276081 00000 n
-0000276146 00000 n
-0000276211 00000 n
-0000276276 00000 n
-0000276341 00000 n
-0000276406 00000 n
-0000276471 00000 n
-0000276536 00000 n
-0000276601 00000 n
-0000276665 00000 n
-0000276730 00000 n
-0000276795 00000 n
-0000276860 00000 n
-0000276925 00000 n
-0000276988 00000 n
-0000277053 00000 n
-0000277118 00000 n
-0000277183 00000 n
-0000277248 00000 n
-0000277313 00000 n
-0000277378 00000 n
-0000277443 00000 n
-0000277508 00000 n
-0000277573 00000 n
-0000277637 00000 n
-0000277702 00000 n
-0000277767 00000 n
-0000277832 00000 n
-0000277897 00000 n
-0000277962 00000 n
-0000278027 00000 n
-0000278092 00000 n
-0000278157 00000 n
-0000278222 00000 n
-0000278286 00000 n
-0000278351 00000 n
-0000278416 00000 n
-0000278481 00000 n
-0000278546 00000 n
-0000278611 00000 n
-0000278676 00000 n
-0000278741 00000 n
-0000278806 00000 n
-0000278869 00000 n
-0000278934 00000 n
-0000278999 00000 n
-0000279064 00000 n
-0000279129 00000 n
-0000279194 00000 n
-0000279259 00000 n
-0000279324 00000 n
-0000279389 00000 n
-0000279453 00000 n
-0000279518 00000 n
-0000279583 00000 n
-0000279647 00000 n
-0000844361 00000 n
-0000285837 00000 n
-0000282857 00000 n
-0000279875 00000 n
-0000282982 00000 n
-0000283046 00000 n
-0000283111 00000 n
-0000283175 00000 n
-0000283240 00000 n
-0000283305 00000 n
-0000283370 00000 n
-0000283435 00000 n
-0000283500 00000 n
-0000283565 00000 n
-0000283630 00000 n
-0000283695 00000 n
-0000283760 00000 n
-0000283825 00000 n
-0000283890 00000 n
-0000283955 00000 n
-0000284020 00000 n
-0000284085 00000 n
-0000284150 00000 n
-0000284215 00000 n
-0000284279 00000 n
-0000284344 00000 n
-0000284409 00000 n
-0000284474 00000 n
-0000284539 00000 n
-0000284604 00000 n
-0000284669 00000 n
-0000284734 00000 n
-0000284799 00000 n
-0000284864 00000 n
-0000284929 00000 n
-0000284994 00000 n
-0000285059 00000 n
-0000285124 00000 n
-0000285189 00000 n
-0000285254 00000 n
-0000285319 00000 n
-0000285384 00000 n
-0000285449 00000 n
-0000285514 00000 n
-0000285579 00000 n
-0000285644 00000 n
-0000285709 00000 n
-0000291917 00000 n
-0000287965 00000 n
-0000286014 00000 n
-0000288090 00000 n
-0000288154 00000 n
-0000288219 00000 n
-0000288283 00000 n
-0000288348 00000 n
-0000288413 00000 n
-0000288478 00000 n
-0000288543 00000 n
-0000288608 00000 n
-0000288673 00000 n
-0000288738 00000 n
-0000288803 00000 n
-0000288868 00000 n
-0000288933 00000 n
-0000288998 00000 n
-0000289063 00000 n
-0000289128 00000 n
-0000289193 00000 n
-0000289258 00000 n
-0000289323 00000 n
-0000289388 00000 n
-0000289453 00000 n
-0000289518 00000 n
-0000289583 00000 n
-0000289648 00000 n
-0000289712 00000 n
-0000289777 00000 n
-0000289842 00000 n
-0000289907 00000 n
-0000289972 00000 n
-0000290037 00000 n
-0000290102 00000 n
-0000290167 00000 n
-0000290232 00000 n
-0000290295 00000 n
-0000290360 00000 n
-0000290425 00000 n
-0000290490 00000 n
-0000290555 00000 n
-0000290620 00000 n
-0000290685 00000 n
-0000290750 00000 n
-0000290815 00000 n
-0000290879 00000 n
-0000290944 00000 n
-0000291009 00000 n
-0000291074 00000 n
-0000291139 00000 n
-0000291204 00000 n
-0000291269 00000 n
-0000291334 00000 n
-0000291399 00000 n
-0000291463 00000 n
-0000291528 00000 n
-0000291593 00000 n
-0000291658 00000 n
-0000291723 00000 n
-0000291788 00000 n
-0000291853 00000 n
-0000297762 00000 n
-0000294204 00000 n
-0000292094 00000 n
-0000294329 00000 n
-0000294393 00000 n
-0000294458 00000 n
-0000294522 00000 n
-0000294587 00000 n
-0000294652 00000 n
-0000294717 00000 n
-0000294782 00000 n
-0000294847 00000 n
-0000294912 00000 n
-0000294977 00000 n
-0000295042 00000 n
-0000295106 00000 n
-0000295171 00000 n
-0000295236 00000 n
-0000295301 00000 n
-0000295366 00000 n
-0000295431 00000 n
-0000295496 00000 n
-0000295561 00000 n
-0000295626 00000 n
-0000295690 00000 n
-0000295755 00000 n
-0000295820 00000 n
-0000295885 00000 n
-0000295950 00000 n
-0000296015 00000 n
-0000296080 00000 n
-0000296145 00000 n
-0000296210 00000 n
-0000296274 00000 n
-0000296339 00000 n
-0000296404 00000 n
-0000296469 00000 n
-0000296534 00000 n
-0000296599 00000 n
-0000296664 00000 n
-0000296729 00000 n
-0000296857 00000 n
-0000296920 00000 n
-0000296985 00000 n
-0000297050 00000 n
-0000297115 00000 n
-0000297180 00000 n
-0000297245 00000 n
-0000297310 00000 n
-0000297375 00000 n
-0000297440 00000 n
-0000297504 00000 n
-0000297569 00000 n
-0000297634 00000 n
-0000297698 00000 n
-0000303822 00000 n
-0000300456 00000 n
-0000297939 00000 n
-0000300581 00000 n
-0000300645 00000 n
-0000300710 00000 n
-0000300774 00000 n
-0000300839 00000 n
-0000300904 00000 n
-0000300969 00000 n
-0000301034 00000 n
-0000301099 00000 n
-0000301164 00000 n
+0000218317 00000 n
+0000218382 00000 n
+0000218447 00000 n
+0000218511 00000 n
+0000218576 00000 n
+0000218641 00000 n
+0000218705 00000 n
+0000847397 00000 n
+0000225247 00000 n
+0000221103 00000 n
+0000218946 00000 n
+0000221228 00000 n
+0000221292 00000 n
+0000221357 00000 n
+0000221421 00000 n
+0000221486 00000 n
+0000221551 00000 n
+0000221616 00000 n
+0000221681 00000 n
+0000221746 00000 n
+0000221811 00000 n
+0000221876 00000 n
+0000221939 00000 n
+0000222004 00000 n
+0000222069 00000 n
+0000222134 00000 n
+0000222199 00000 n
+0000222264 00000 n
+0000222329 00000 n
+0000222394 00000 n
+0000222459 00000 n
+0000222523 00000 n
+0000222588 00000 n
+0000222653 00000 n
+0000222718 00000 n
+0000222783 00000 n
+0000222848 00000 n
+0000222913 00000 n
+0000222978 00000 n
+0000223043 00000 n
+0000223107 00000 n
+0000223172 00000 n
+0000223237 00000 n
+0000223302 00000 n
+0000223367 00000 n
+0000223432 00000 n
+0000223497 00000 n
+0000223562 00000 n
+0000223627 00000 n
+0000223691 00000 n
+0000223756 00000 n
+0000223821 00000 n
+0000223886 00000 n
+0000223951 00000 n
+0000224016 00000 n
+0000224081 00000 n
+0000224146 00000 n
+0000224211 00000 n
+0000224275 00000 n
+0000224340 00000 n
+0000224405 00000 n
+0000224470 00000 n
+0000224535 00000 n
+0000224600 00000 n
+0000224665 00000 n
+0000224730 00000 n
+0000224795 00000 n
+0000224860 00000 n
+0000224924 00000 n
+0000224989 00000 n
+0000225054 00000 n
+0000225119 00000 n
+0000225183 00000 n
+0000231604 00000 n
+0000227328 00000 n
+0000225411 00000 n
+0000227453 00000 n
+0000227517 00000 n
+0000227582 00000 n
+0000227646 00000 n
+0000227711 00000 n
+0000227776 00000 n
+0000227841 00000 n
+0000227906 00000 n
+0000227971 00000 n
+0000228036 00000 n
+0000228101 00000 n
+0000228166 00000 n
+0000228230 00000 n
+0000228295 00000 n
+0000228360 00000 n
+0000228425 00000 n
+0000228490 00000 n
+0000228555 00000 n
+0000228620 00000 n
+0000228685 00000 n
+0000228750 00000 n
+0000228814 00000 n
+0000228879 00000 n
+0000228944 00000 n
+0000229009 00000 n
+0000229074 00000 n
+0000229139 00000 n
+0000229204 00000 n
+0000229269 00000 n
+0000229334 00000 n
+0000229398 00000 n
+0000229463 00000 n
+0000229528 00000 n
+0000229593 00000 n
+0000229658 00000 n
+0000229723 00000 n
+0000229788 00000 n
+0000229853 00000 n
+0000229918 00000 n
+0000229982 00000 n
+0000230047 00000 n
+0000230112 00000 n
+0000230177 00000 n
+0000230242 00000 n
+0000230307 00000 n
+0000230372 00000 n
+0000230437 00000 n
+0000230502 00000 n
+0000230566 00000 n
+0000230631 00000 n
+0000230696 00000 n
+0000230761 00000 n
+0000230826 00000 n
+0000230891 00000 n
+0000230956 00000 n
+0000231021 00000 n
+0000231086 00000 n
+0000231150 00000 n
+0000231215 00000 n
+0000231280 00000 n
+0000231345 00000 n
+0000231410 00000 n
+0000231475 00000 n
+0000231540 00000 n
+0000237123 00000 n
+0000233957 00000 n
+0000231755 00000 n
+0000234082 00000 n
+0000234146 00000 n
+0000234211 00000 n
+0000234275 00000 n
+0000234340 00000 n
+0000234405 00000 n
+0000234470 00000 n
+0000234535 00000 n
+0000234600 00000 n
+0000234664 00000 n
+0000234729 00000 n
+0000234794 00000 n
+0000234859 00000 n
+0000234924 00000 n
+0000234989 00000 n
+0000235054 00000 n
+0000235119 00000 n
+0000235184 00000 n
+0000235249 00000 n
+0000235314 00000 n
+0000235440 00000 n
+0000235505 00000 n
+0000235570 00000 n
+0000235635 00000 n
+0000235700 00000 n
+0000235765 00000 n
+0000235830 00000 n
+0000235895 00000 n
+0000235960 00000 n
+0000236025 00000 n
+0000236089 00000 n
+0000236154 00000 n
+0000236219 00000 n
+0000236284 00000 n
+0000236349 00000 n
+0000236414 00000 n
+0000236479 00000 n
+0000236544 00000 n
+0000236671 00000 n
+0000236736 00000 n
+0000236801 00000 n
+0000236865 00000 n
+0000236930 00000 n
+0000236995 00000 n
+0000237059 00000 n
+0000243217 00000 n
+0000239721 00000 n
+0000237300 00000 n
+0000239846 00000 n
+0000239910 00000 n
+0000239975 00000 n
+0000240039 00000 n
+0000240104 00000 n
+0000240169 00000 n
+0000240234 00000 n
+0000240299 00000 n
+0000240364 00000 n
+0000240429 00000 n
+0000240494 00000 n
+0000240558 00000 n
+0000240623 00000 n
+0000240688 00000 n
+0000240753 00000 n
+0000240818 00000 n
+0000240946 00000 n
+0000241010 00000 n
+0000241075 00000 n
+0000241140 00000 n
+0000241205 00000 n
+0000241270 00000 n
+0000241335 00000 n
+0000241400 00000 n
+0000241465 00000 n
+0000241530 00000 n
+0000241595 00000 n
+0000241660 00000 n
+0000241725 00000 n
+0000241790 00000 n
+0000241855 00000 n
+0000241920 00000 n
+0000241985 00000 n
+0000242050 00000 n
+0000242115 00000 n
+0000242180 00000 n
+0000242245 00000 n
+0000242310 00000 n
+0000242375 00000 n
+0000242439 00000 n
+0000242504 00000 n
+0000242569 00000 n
+0000242634 00000 n
+0000242699 00000 n
+0000242764 00000 n
+0000242829 00000 n
+0000242894 00000 n
+0000242959 00000 n
+0000243024 00000 n
+0000243089 00000 n
+0000243153 00000 n
+0000249103 00000 n
+0000245413 00000 n
+0000243394 00000 n
+0000245538 00000 n
+0000245602 00000 n
+0000245667 00000 n
+0000245731 00000 n
+0000245796 00000 n
+0000245861 00000 n
+0000245926 00000 n
+0000245991 00000 n
+0000246056 00000 n
+0000246121 00000 n
+0000246186 00000 n
+0000246251 00000 n
+0000246315 00000 n
+0000246380 00000 n
+0000246445 00000 n
+0000246510 00000 n
+0000246575 00000 n
+0000246640 00000 n
+0000246704 00000 n
+0000246769 00000 n
+0000246834 00000 n
+0000246899 00000 n
+0000246964 00000 n
+0000247029 00000 n
+0000247094 00000 n
+0000247159 00000 n
+0000247224 00000 n
+0000247287 00000 n
+0000247352 00000 n
+0000247417 00000 n
+0000247482 00000 n
+0000247547 00000 n
+0000247612 00000 n
+0000247677 00000 n
+0000247742 00000 n
+0000247807 00000 n
+0000247872 00000 n
+0000247937 00000 n
+0000248002 00000 n
+0000248067 00000 n
+0000248132 00000 n
+0000248197 00000 n
+0000248262 00000 n
+0000248327 00000 n
+0000248392 00000 n
+0000248457 00000 n
+0000248521 00000 n
+0000248586 00000 n
+0000248651 00000 n
+0000248716 00000 n
+0000248780 00000 n
+0000248845 00000 n
+0000248910 00000 n
+0000248975 00000 n
+0000249039 00000 n
+0000255605 00000 n
+0000252113 00000 n
+0000249267 00000 n
+0000252238 00000 n
+0000252302 00000 n
+0000252367 00000 n
+0000252431 00000 n
+0000252496 00000 n
+0000252561 00000 n
+0000252626 00000 n
+0000252691 00000 n
+0000252756 00000 n
+0000252821 00000 n
+0000252886 00000 n
+0000252951 00000 n
+0000253015 00000 n
+0000253080 00000 n
+0000253145 00000 n
+0000253210 00000 n
+0000253275 00000 n
+0000253340 00000 n
+0000253405 00000 n
+0000253470 00000 n
+0000253535 00000 n
+0000253599 00000 n
+0000253664 00000 n
+0000253729 00000 n
+0000253794 00000 n
+0000253859 00000 n
+0000253924 00000 n
+0000253989 00000 n
+0000254054 00000 n
+0000254119 00000 n
+0000254184 00000 n
+0000254249 00000 n
+0000254314 00000 n
+0000254379 00000 n
+0000254444 00000 n
+0000254509 00000 n
+0000254574 00000 n
+0000254639 00000 n
+0000254702 00000 n
+0000254767 00000 n
+0000254832 00000 n
+0000254897 00000 n
+0000254958 00000 n
+0000255023 00000 n
+0000255088 00000 n
+0000255153 00000 n
+0000255218 00000 n
+0000255283 00000 n
+0000255348 00000 n
+0000255413 00000 n
+0000255478 00000 n
+0000255541 00000 n
+0000258748 00000 n
+0000261758 00000 n
+0000258575 00000 n
+0000255769 00000 n
+0000258906 00000 n
+0000258970 00000 n
+0000259035 00000 n
+0000259099 00000 n
+0000259164 00000 n
+0000259229 00000 n
+0000259294 00000 n
+0000259359 00000 n
+0000259424 00000 n
+0000259489 00000 n
+0000259554 00000 n
+0000259619 00000 n
+0000259683 00000 n
+0000259748 00000 n
+0000259813 00000 n
+0000259878 00000 n
+0000259942 00000 n
+0000260007 00000 n
+0000260072 00000 n
+0000260137 00000 n
+0000260202 00000 n
+0000260267 00000 n
+0000260332 00000 n
+0000260396 00000 n
+0000260461 00000 n
+0000260526 00000 n
+0000260591 00000 n
+0000260655 00000 n
+0000260720 00000 n
+0000260785 00000 n
+0000260850 00000 n
+0000260914 00000 n
+0000260979 00000 n
+0000261044 00000 n
+0000261109 00000 n
+0000261174 00000 n
+0000261239 00000 n
+0000261304 00000 n
+0000261369 00000 n
+0000261434 00000 n
+0000261498 00000 n
+0000261563 00000 n
+0000261628 00000 n
+0000261693 00000 n
+0000258717 00000 n
+0000267872 00000 n
+0000264902 00000 n
+0000261974 00000 n
+0000265027 00000 n
+0000265091 00000 n
+0000265155 00000 n
+0000265220 00000 n
+0000265285 00000 n
+0000265350 00000 n
+0000265415 00000 n
+0000265480 00000 n
+0000265545 00000 n
+0000265610 00000 n
+0000265675 00000 n
+0000265739 00000 n
+0000265804 00000 n
+0000265869 00000 n
+0000265932 00000 n
+0000265997 00000 n
+0000266062 00000 n
+0000266127 00000 n
+0000266191 00000 n
+0000266256 00000 n
+0000266321 00000 n
+0000266386 00000 n
+0000266451 00000 n
+0000266516 00000 n
+0000266581 00000 n
+0000266646 00000 n
+0000266711 00000 n
+0000266775 00000 n
+0000266840 00000 n
+0000266905 00000 n
+0000266970 00000 n
+0000267035 00000 n
+0000267100 00000 n
+0000267165 00000 n
+0000267230 00000 n
+0000267294 00000 n
+0000267359 00000 n
+0000267424 00000 n
+0000267485 00000 n
+0000267550 00000 n
+0000267615 00000 n
+0000267680 00000 n
+0000267744 00000 n
+0000267808 00000 n
+0000273808 00000 n
+0000270765 00000 n
+0000268049 00000 n
+0000270890 00000 n
+0000270954 00000 n
+0000271019 00000 n
+0000271083 00000 n
+0000271148 00000 n
+0000271213 00000 n
+0000271278 00000 n
+0000271343 00000 n
+0000271408 00000 n
+0000271473 00000 n
+0000271538 00000 n
+0000271603 00000 n
+0000271668 00000 n
+0000271733 00000 n
+0000271798 00000 n
+0000271863 00000 n
+0000271928 00000 n
+0000271993 00000 n
+0000272058 00000 n
+0000272123 00000 n
+0000272188 00000 n
+0000272253 00000 n
+0000272318 00000 n
+0000272383 00000 n
+0000272448 00000 n
+0000272513 00000 n
+0000272578 00000 n
+0000272643 00000 n
+0000272708 00000 n
+0000272773 00000 n
+0000272838 00000 n
+0000272901 00000 n
+0000272966 00000 n
+0000273031 00000 n
+0000273096 00000 n
+0000273161 00000 n
+0000273226 00000 n
+0000273291 00000 n
+0000273356 00000 n
+0000273421 00000 n
+0000273486 00000 n
+0000273550 00000 n
+0000273615 00000 n
+0000273680 00000 n
+0000273744 00000 n
+0000280041 00000 n
+0000276544 00000 n
+0000273985 00000 n
+0000276669 00000 n
+0000276733 00000 n
+0000276798 00000 n
+0000276862 00000 n
+0000276927 00000 n
+0000276992 00000 n
+0000277057 00000 n
+0000277122 00000 n
+0000277187 00000 n
+0000277252 00000 n
+0000277317 00000 n
+0000277381 00000 n
+0000277446 00000 n
+0000277511 00000 n
+0000277576 00000 n
+0000277641 00000 n
+0000277706 00000 n
+0000277771 00000 n
+0000277836 00000 n
+0000277901 00000 n
+0000277965 00000 n
+0000278030 00000 n
+0000278095 00000 n
+0000278160 00000 n
+0000278225 00000 n
+0000278290 00000 n
+0000278355 00000 n
+0000278420 00000 n
+0000278485 00000 n
+0000278550 00000 n
+0000278615 00000 n
+0000278680 00000 n
+0000278745 00000 n
+0000278810 00000 n
+0000278875 00000 n
+0000278940 00000 n
+0000279005 00000 n
+0000279070 00000 n
+0000279135 00000 n
+0000279200 00000 n
+0000279265 00000 n
+0000279329 00000 n
+0000279394 00000 n
+0000279459 00000 n
+0000279524 00000 n
+0000279589 00000 n
+0000279654 00000 n
+0000279719 00000 n
+0000279784 00000 n
+0000279849 00000 n
+0000279913 00000 n
+0000279977 00000 n
+0000847561 00000 n
+0000286553 00000 n
+0000282862 00000 n
+0000280205 00000 n
+0000282987 00000 n
+0000283051 00000 n
+0000283116 00000 n
+0000283180 00000 n
+0000283245 00000 n
+0000283310 00000 n
+0000283375 00000 n
+0000283440 00000 n
+0000283505 00000 n
+0000283570 00000 n
+0000283635 00000 n
+0000283700 00000 n
+0000283764 00000 n
+0000283829 00000 n
+0000283894 00000 n
+0000283959 00000 n
+0000284024 00000 n
+0000284089 00000 n
+0000284154 00000 n
+0000284219 00000 n
+0000284284 00000 n
+0000284348 00000 n
+0000284413 00000 n
+0000284478 00000 n
+0000284543 00000 n
+0000284608 00000 n
+0000284673 00000 n
+0000284738 00000 n
+0000284803 00000 n
+0000284868 00000 n
+0000284932 00000 n
+0000284997 00000 n
+0000285062 00000 n
+0000285127 00000 n
+0000285192 00000 n
+0000285257 00000 n
+0000285322 00000 n
+0000285387 00000 n
+0000285452 00000 n
+0000285517 00000 n
+0000285582 00000 n
+0000285647 00000 n
+0000285712 00000 n
+0000285777 00000 n
+0000285842 00000 n
+0000285907 00000 n
+0000285971 00000 n
+0000286036 00000 n
+0000286101 00000 n
+0000286166 00000 n
+0000286231 00000 n
+0000286296 00000 n
+0000286361 00000 n
+0000286426 00000 n
+0000286489 00000 n
+0000292369 00000 n
+0000289067 00000 n
+0000286717 00000 n
+0000289192 00000 n
+0000289256 00000 n
+0000289321 00000 n
+0000289386 00000 n
+0000289451 00000 n
+0000289516 00000 n
+0000289581 00000 n
+0000289646 00000 n
+0000289711 00000 n
+0000289775 00000 n
+0000289840 00000 n
+0000289905 00000 n
+0000289970 00000 n
+0000290035 00000 n
+0000290163 00000 n
+0000290228 00000 n
+0000290293 00000 n
+0000290358 00000 n
+0000290423 00000 n
+0000290488 00000 n
+0000290553 00000 n
+0000290618 00000 n
+0000290683 00000 n
+0000290748 00000 n
+0000290813 00000 n
+0000290878 00000 n
+0000290943 00000 n
+0000291007 00000 n
+0000291072 00000 n
+0000291137 00000 n
+0000291202 00000 n
+0000291267 00000 n
+0000291332 00000 n
+0000291397 00000 n
+0000291462 00000 n
+0000291527 00000 n
+0000291591 00000 n
+0000291656 00000 n
+0000291721 00000 n
+0000291786 00000 n
+0000291851 00000 n
+0000291916 00000 n
+0000291981 00000 n
+0000292046 00000 n
+0000292111 00000 n
+0000292176 00000 n
+0000292241 00000 n
+0000292305 00000 n
+0000298330 00000 n
+0000294576 00000 n
+0000292546 00000 n
+0000294701 00000 n
+0000294765 00000 n
+0000294830 00000 n
+0000294894 00000 n
+0000294959 00000 n
+0000295024 00000 n
+0000295089 00000 n
+0000295154 00000 n
+0000295219 00000 n
+0000295284 00000 n
+0000295349 00000 n
+0000295414 00000 n
+0000295478 00000 n
+0000295543 00000 n
+0000295608 00000 n
+0000295673 00000 n
+0000295738 00000 n
+0000295803 00000 n
+0000295868 00000 n
+0000295933 00000 n
+0000295998 00000 n
+0000296062 00000 n
+0000296127 00000 n
+0000296192 00000 n
+0000296257 00000 n
+0000296322 00000 n
+0000296386 00000 n
+0000296451 00000 n
+0000296516 00000 n
+0000296581 00000 n
+0000296646 00000 n
+0000296711 00000 n
+0000296776 00000 n
+0000296841 00000 n
+0000296906 00000 n
+0000296970 00000 n
+0000297035 00000 n
+0000297100 00000 n
+0000297165 00000 n
+0000297230 00000 n
+0000297295 00000 n
+0000297360 00000 n
+0000297425 00000 n
+0000297490 00000 n
+0000297554 00000 n
+0000297619 00000 n
+0000297684 00000 n
+0000297749 00000 n
+0000297814 00000 n
+0000297879 00000 n
+0000297944 00000 n
+0000298009 00000 n
+0000298074 00000 n
+0000298135 00000 n
+0000298200 00000 n
+0000298265 00000 n
+0000304275 00000 n
+0000301040 00000 n
+0000298507 00000 n
+0000301165 00000 n
0000301229 00000 n
0000301294 00000 n
0000301358 00000 n
0000301423 00000 n
0000301488 00000 n
0000301553 00000 n
-0000301618 00000 n
-0000301683 00000 n
-0000301748 00000 n
-0000301813 00000 n
-0000301878 00000 n
-0000301942 00000 n
-0000302007 00000 n
-0000302072 00000 n
-0000302137 00000 n
-0000302202 00000 n
-0000302267 00000 n
+0000301681 00000 n
+0000301746 00000 n
+0000301811 00000 n
+0000301876 00000 n
+0000301940 00000 n
+0000302005 00000 n
+0000302070 00000 n
+0000302135 00000 n
+0000302200 00000 n
+0000302265 00000 n
+0000302330 00000 n
0000302395 00000 n
0000302460 00000 n
-0000302525 00000 n
-0000302590 00000 n
-0000302655 00000 n
-0000302720 00000 n
-0000302785 00000 n
-0000302850 00000 n
-0000302915 00000 n
+0000302524 00000 n
+0000302589 00000 n
+0000302654 00000 n
+0000302719 00000 n
+0000302784 00000 n
+0000302849 00000 n
+0000302914 00000 n
0000302979 00000 n
0000303044 00000 n
-0000303109 00000 n
-0000303174 00000 n
-0000303239 00000 n
-0000303304 00000 n
-0000303369 00000 n
-0000303434 00000 n
-0000303499 00000 n
-0000303564 00000 n
+0000303108 00000 n
+0000303173 00000 n
+0000303238 00000 n
+0000303303 00000 n
+0000303368 00000 n
+0000303433 00000 n
+0000303498 00000 n
+0000303563 00000 n
0000303628 00000 n
-0000303693 00000 n
-0000303758 00000 n
-0000309494 00000 n
-0000306846 00000 n
-0000304012 00000 n
-0000306971 00000 n
-0000307035 00000 n
-0000307100 00000 n
-0000307165 00000 n
-0000307229 00000 n
-0000307294 00000 n
-0000307357 00000 n
-0000307422 00000 n
-0000307487 00000 n
-0000307552 00000 n
-0000307617 00000 n
-0000307681 00000 n
-0000307746 00000 n
-0000307811 00000 n
-0000307876 00000 n
-0000307940 00000 n
-0000308005 00000 n
-0000308070 00000 n
-0000308135 00000 n
-0000308200 00000 n
-0000308265 00000 n
-0000308330 00000 n
-0000308395 00000 n
-0000308460 00000 n
-0000308525 00000 n
-0000308590 00000 n
-0000308655 00000 n
-0000308720 00000 n
-0000308785 00000 n
-0000308850 00000 n
-0000308911 00000 n
-0000308976 00000 n
-0000309041 00000 n
-0000309106 00000 n
-0000309171 00000 n
-0000309236 00000 n
-0000309301 00000 n
-0000309366 00000 n
-0000309430 00000 n
-0000315523 00000 n
-0000311772 00000 n
-0000309671 00000 n
-0000311897 00000 n
-0000311961 00000 n
-0000312026 00000 n
-0000312090 00000 n
-0000312154 00000 n
-0000312219 00000 n
-0000312284 00000 n
-0000312349 00000 n
-0000312477 00000 n
-0000312542 00000 n
-0000312607 00000 n
-0000312672 00000 n
-0000312737 00000 n
-0000312801 00000 n
-0000312866 00000 n
-0000312931 00000 n
-0000312996 00000 n
-0000313061 00000 n
-0000313189 00000 n
-0000313254 00000 n
-0000313319 00000 n
-0000313384 00000 n
-0000313449 00000 n
-0000313514 00000 n
-0000313579 00000 n
-0000313643 00000 n
-0000313707 00000 n
-0000313772 00000 n
-0000313837 00000 n
-0000313902 00000 n
-0000313967 00000 n
-0000314032 00000 n
-0000314097 00000 n
-0000314162 00000 n
-0000314227 00000 n
-0000314292 00000 n
-0000314355 00000 n
-0000314420 00000 n
-0000314485 00000 n
-0000314550 00000 n
-0000314615 00000 n
-0000314680 00000 n
-0000314745 00000 n
-0000314810 00000 n
-0000314875 00000 n
-0000314940 00000 n
-0000315005 00000 n
-0000315070 00000 n
-0000315135 00000 n
-0000315200 00000 n
-0000315265 00000 n
-0000315330 00000 n
-0000315395 00000 n
-0000315459 00000 n
-0000321848 00000 n
-0000317702 00000 n
-0000315687 00000 n
-0000317827 00000 n
-0000317891 00000 n
-0000317956 00000 n
-0000318020 00000 n
-0000318084 00000 n
-0000318149 00000 n
-0000318214 00000 n
-0000318279 00000 n
-0000318344 00000 n
-0000318409 00000 n
-0000318474 00000 n
-0000318539 00000 n
-0000318604 00000 n
-0000318669 00000 n
-0000318733 00000 n
-0000318798 00000 n
-0000318863 00000 n
-0000318928 00000 n
-0000318993 00000 n
-0000319058 00000 n
-0000319123 00000 n
-0000319188 00000 n
-0000319253 00000 n
-0000319318 00000 n
-0000319383 00000 n
-0000319448 00000 n
-0000319512 00000 n
-0000319577 00000 n
-0000319642 00000 n
-0000319707 00000 n
-0000319772 00000 n
-0000319837 00000 n
-0000319902 00000 n
-0000319967 00000 n
-0000320032 00000 n
-0000320097 00000 n
-0000320161 00000 n
-0000320226 00000 n
-0000320291 00000 n
-0000320356 00000 n
-0000320421 00000 n
-0000320486 00000 n
-0000320551 00000 n
-0000320616 00000 n
-0000320681 00000 n
-0000320746 00000 n
-0000320810 00000 n
-0000320875 00000 n
-0000320940 00000 n
-0000321005 00000 n
-0000321070 00000 n
-0000321135 00000 n
-0000321200 00000 n
-0000321265 00000 n
-0000321330 00000 n
-0000321395 00000 n
-0000321460 00000 n
-0000321525 00000 n
-0000321590 00000 n
-0000321655 00000 n
-0000321720 00000 n
-0000321784 00000 n
-0000327576 00000 n
-0000323950 00000 n
-0000321999 00000 n
-0000324075 00000 n
-0000324139 00000 n
-0000324204 00000 n
-0000324268 00000 n
-0000324333 00000 n
-0000324398 00000 n
-0000324463 00000 n
-0000324528 00000 n
-0000324593 00000 n
-0000324658 00000 n
-0000324723 00000 n
-0000324788 00000 n
-0000324852 00000 n
-0000324917 00000 n
-0000324982 00000 n
-0000325047 00000 n
-0000325112 00000 n
-0000325177 00000 n
-0000325242 00000 n
-0000325307 00000 n
-0000325372 00000 n
-0000325437 00000 n
-0000325502 00000 n
-0000325567 00000 n
-0000325632 00000 n
-0000325697 00000 n
-0000325762 00000 n
-0000325827 00000 n
-0000325892 00000 n
-0000325957 00000 n
-0000326022 00000 n
-0000326087 00000 n
-0000326152 00000 n
-0000326217 00000 n
-0000326282 00000 n
-0000326347 00000 n
-0000326412 00000 n
-0000326476 00000 n
-0000326604 00000 n
-0000326669 00000 n
-0000326734 00000 n
-0000326799 00000 n
-0000326864 00000 n
-0000326929 00000 n
-0000326994 00000 n
-0000327059 00000 n
-0000327124 00000 n
-0000327189 00000 n
-0000327254 00000 n
-0000327319 00000 n
-0000327384 00000 n
-0000327449 00000 n
-0000333880 00000 n
-0000330581 00000 n
-0000327740 00000 n
-0000330706 00000 n
-0000330770 00000 n
-0000330835 00000 n
-0000330899 00000 n
-0000330964 00000 n
-0000331029 00000 n
-0000331094 00000 n
-0000331159 00000 n
-0000331224 00000 n
-0000331289 00000 n
-0000331354 00000 n
-0000331419 00000 n
-0000331483 00000 n
-0000331548 00000 n
-0000331613 00000 n
-0000331678 00000 n
-0000331743 00000 n
-0000331808 00000 n
-0000331873 00000 n
-0000331938 00000 n
-0000332003 00000 n
-0000842164 00000 n
-0000332130 00000 n
-0000332195 00000 n
-0000332260 00000 n
-0000332325 00000 n
-0000332390 00000 n
-0000332455 00000 n
-0000332520 00000 n
-0000332584 00000 n
-0000332649 00000 n
-0000332714 00000 n
-0000332779 00000 n
-0000332844 00000 n
-0000332909 00000 n
-0000332974 00000 n
-0000333039 00000 n
-0000333104 00000 n
-0000333169 00000 n
-0000333233 00000 n
-0000333298 00000 n
-0000333363 00000 n
-0000333428 00000 n
-0000333493 00000 n
-0000333558 00000 n
-0000333623 00000 n
-0000333688 00000 n
-0000333753 00000 n
-0000333817 00000 n
-0000339749 00000 n
-0000337488 00000 n
-0000334137 00000 n
-0000337613 00000 n
-0000337677 00000 n
-0000337742 00000 n
-0000337805 00000 n
-0000337870 00000 n
-0000337935 00000 n
-0000338000 00000 n
-0000338065 00000 n
-0000338130 00000 n
-0000338195 00000 n
-0000338260 00000 n
-0000338325 00000 n
-0000338390 00000 n
-0000338454 00000 n
-0000338519 00000 n
-0000338584 00000 n
-0000338648 00000 n
-0000338713 00000 n
-0000338778 00000 n
-0000338843 00000 n
-0000338908 00000 n
-0000338973 00000 n
-0000339038 00000 n
-0000339103 00000 n
-0000339168 00000 n
-0000339233 00000 n
-0000339298 00000 n
-0000339363 00000 n
-0000339427 00000 n
-0000339491 00000 n
-0000339556 00000 n
-0000339621 00000 n
-0000339685 00000 n
-0000844525 00000 n
-0000345349 00000 n
-0000342828 00000 n
-0000339965 00000 n
-0000342953 00000 n
-0000343017 00000 n
-0000343082 00000 n
-0000343146 00000 n
-0000343211 00000 n
-0000343276 00000 n
-0000343341 00000 n
-0000343406 00000 n
-0000343471 00000 n
-0000343536 00000 n
-0000343601 00000 n
-0000343666 00000 n
-0000343731 00000 n
-0000343794 00000 n
-0000343859 00000 n
-0000343924 00000 n
-0000343988 00000 n
-0000344053 00000 n
-0000344118 00000 n
-0000344183 00000 n
-0000344248 00000 n
-0000344313 00000 n
-0000344378 00000 n
-0000344443 00000 n
-0000344508 00000 n
-0000344573 00000 n
-0000344638 00000 n
-0000344703 00000 n
-0000344768 00000 n
-0000344832 00000 n
-0000344897 00000 n
-0000344962 00000 n
-0000345027 00000 n
-0000345091 00000 n
-0000345156 00000 n
-0000345221 00000 n
-0000345285 00000 n
-0000350445 00000 n
-0000347925 00000 n
+0000303691 00000 n
+0000303756 00000 n
+0000303821 00000 n
+0000303886 00000 n
+0000303951 00000 n
+0000304016 00000 n
+0000304081 00000 n
+0000304146 00000 n
+0000304210 00000 n
+0000310024 00000 n
+0000307240 00000 n
+0000304465 00000 n
+0000307365 00000 n
+0000307492 00000 n
+0000307557 00000 n
+0000307622 00000 n
+0000307687 00000 n
+0000307752 00000 n
+0000307817 00000 n
+0000307882 00000 n
+0000307947 00000 n
+0000308011 00000 n
+0000308076 00000 n
+0000308141 00000 n
+0000308206 00000 n
+0000308271 00000 n
+0000308336 00000 n
+0000308401 00000 n
+0000308466 00000 n
+0000308531 00000 n
+0000308596 00000 n
+0000308661 00000 n
+0000308725 00000 n
+0000308790 00000 n
+0000308855 00000 n
+0000308920 00000 n
+0000308985 00000 n
+0000309050 00000 n
+0000309115 00000 n
+0000309180 00000 n
+0000309245 00000 n
+0000309310 00000 n
+0000309375 00000 n
+0000309440 00000 n
+0000309505 00000 n
+0000309570 00000 n
+0000309635 00000 n
+0000309700 00000 n
+0000309765 00000 n
+0000309830 00000 n
+0000309895 00000 n
+0000309960 00000 n
+0000315793 00000 n
+0000312302 00000 n
+0000310201 00000 n
+0000312427 00000 n
+0000312491 00000 n
+0000312556 00000 n
+0000312620 00000 n
+0000312685 00000 n
+0000312750 00000 n
+0000312815 00000 n
+0000312880 00000 n
+0000312945 00000 n
+0000313010 00000 n
+0000313075 00000 n
+0000313140 00000 n
+0000313205 00000 n
+0000313270 00000 n
+0000313335 00000 n
+0000313400 00000 n
+0000313465 00000 n
+0000313530 00000 n
+0000313595 00000 n
+0000313658 00000 n
+0000313723 00000 n
+0000313788 00000 n
+0000313853 00000 n
+0000313917 00000 n
+0000313982 00000 n
+0000314047 00000 n
+0000314112 00000 n
+0000314177 00000 n
+0000314242 00000 n
+0000314370 00000 n
+0000314435 00000 n
+0000314500 00000 n
+0000314565 00000 n
+0000314628 00000 n
+0000314693 00000 n
+0000314758 00000 n
+0000314823 00000 n
+0000314888 00000 n
+0000314953 00000 n
+0000315081 00000 n
+0000315146 00000 n
+0000315211 00000 n
+0000315276 00000 n
+0000315341 00000 n
+0000315406 00000 n
+0000315470 00000 n
+0000315535 00000 n
+0000315600 00000 n
+0000315665 00000 n
+0000315729 00000 n
+0000322056 00000 n
+0000317975 00000 n
+0000315957 00000 n
+0000318100 00000 n
+0000318164 00000 n
+0000318229 00000 n
+0000318293 00000 n
+0000318358 00000 n
+0000318423 00000 n
+0000318488 00000 n
+0000318553 00000 n
+0000318618 00000 n
+0000318683 00000 n
+0000318748 00000 n
+0000318813 00000 n
+0000318878 00000 n
+0000318943 00000 n
+0000319007 00000 n
+0000319072 00000 n
+0000319137 00000 n
+0000319202 00000 n
+0000319267 00000 n
+0000319332 00000 n
+0000319397 00000 n
+0000319462 00000 n
+0000319527 00000 n
+0000319592 00000 n
+0000319657 00000 n
+0000319722 00000 n
+0000319787 00000 n
+0000319852 00000 n
+0000319917 00000 n
+0000319982 00000 n
+0000320047 00000 n
+0000320112 00000 n
+0000320177 00000 n
+0000320242 00000 n
+0000320307 00000 n
+0000320371 00000 n
+0000320435 00000 n
+0000320500 00000 n
+0000320565 00000 n
+0000320630 00000 n
+0000320695 00000 n
+0000320760 00000 n
+0000320825 00000 n
+0000320890 00000 n
+0000320955 00000 n
+0000321020 00000 n
+0000321084 00000 n
+0000321149 00000 n
+0000321214 00000 n
+0000321279 00000 n
+0000321344 00000 n
+0000321409 00000 n
+0000321474 00000 n
+0000321539 00000 n
+0000321604 00000 n
+0000321669 00000 n
+0000321734 00000 n
+0000321799 00000 n
+0000321863 00000 n
+0000321928 00000 n
+0000321992 00000 n
+0000328181 00000 n
+0000324165 00000 n
+0000322207 00000 n
+0000324290 00000 n
+0000324354 00000 n
+0000324419 00000 n
+0000324483 00000 n
+0000324548 00000 n
+0000324613 00000 n
+0000324678 00000 n
+0000324743 00000 n
+0000324808 00000 n
+0000324873 00000 n
+0000324938 00000 n
+0000325003 00000 n
+0000325067 00000 n
+0000325132 00000 n
+0000325197 00000 n
+0000325262 00000 n
+0000325327 00000 n
+0000325392 00000 n
+0000325457 00000 n
+0000325522 00000 n
+0000325587 00000 n
+0000325651 00000 n
+0000325716 00000 n
+0000325781 00000 n
+0000325846 00000 n
+0000325911 00000 n
+0000325976 00000 n
+0000326041 00000 n
+0000326106 00000 n
+0000326171 00000 n
+0000326235 00000 n
+0000326300 00000 n
+0000326365 00000 n
+0000326430 00000 n
+0000326495 00000 n
+0000326560 00000 n
+0000326625 00000 n
+0000326690 00000 n
+0000326755 00000 n
+0000326819 00000 n
+0000326884 00000 n
+0000326949 00000 n
+0000327014 00000 n
+0000327079 00000 n
+0000327144 00000 n
+0000327209 00000 n
+0000327274 00000 n
+0000327339 00000 n
+0000327404 00000 n
+0000327469 00000 n
+0000327534 00000 n
+0000327599 00000 n
+0000327664 00000 n
+0000327728 00000 n
+0000327793 00000 n
+0000327858 00000 n
+0000327923 00000 n
+0000327988 00000 n
+0000328053 00000 n
+0000328117 00000 n
+0000333987 00000 n
+0000330755 00000 n
+0000328332 00000 n
+0000330880 00000 n
+0000330944 00000 n
+0000331009 00000 n
+0000331073 00000 n
+0000331138 00000 n
+0000331266 00000 n
+0000331331 00000 n
+0000331396 00000 n
+0000331461 00000 n
+0000331526 00000 n
+0000331591 00000 n
+0000331656 00000 n
+0000331721 00000 n
+0000331786 00000 n
+0000331851 00000 n
+0000331916 00000 n
+0000331981 00000 n
+0000332046 00000 n
+0000332111 00000 n
+0000332239 00000 n
+0000332304 00000 n
+0000332368 00000 n
+0000332433 00000 n
+0000332498 00000 n
+0000332563 00000 n
+0000332628 00000 n
+0000332693 00000 n
+0000332758 00000 n
+0000332823 00000 n
+0000332888 00000 n
+0000332952 00000 n
+0000333017 00000 n
+0000333082 00000 n
+0000333147 00000 n
+0000333212 00000 n
+0000333277 00000 n
+0000333342 00000 n
+0000333407 00000 n
+0000333472 00000 n
+0000845364 00000 n
+0000333599 00000 n
+0000333664 00000 n
+0000333729 00000 n
+0000333794 00000 n
+0000333859 00000 n
+0000333923 00000 n
+0000340049 00000 n
+0000337655 00000 n
+0000334218 00000 n
+0000337780 00000 n
+0000337844 00000 n
+0000337909 00000 n
+0000337973 00000 n
+0000338038 00000 n
+0000338103 00000 n
+0000338168 00000 n
+0000338233 00000 n
+0000338298 00000 n
+0000338363 00000 n
+0000338428 00000 n
+0000338493 00000 n
+0000338558 00000 n
+0000338621 00000 n
+0000338686 00000 n
+0000338751 00000 n
+0000338816 00000 n
+0000338881 00000 n
+0000338946 00000 n
+0000339011 00000 n
+0000339076 00000 n
+0000339141 00000 n
+0000339205 00000 n
+0000339270 00000 n
+0000339335 00000 n
+0000339400 00000 n
+0000339465 00000 n
+0000339530 00000 n
+0000339595 00000 n
+0000339660 00000 n
+0000339725 00000 n
+0000339789 00000 n
+0000339854 00000 n
+0000339919 00000 n
+0000339984 00000 n
+0000847725 00000 n
+0000345362 00000 n
+0000342645 00000 n
+0000340265 00000 n
+0000342770 00000 n
+0000342834 00000 n
+0000342899 00000 n
+0000342964 00000 n
+0000343029 00000 n
+0000343093 00000 n
+0000343158 00000 n
+0000343223 00000 n
+0000343287 00000 n
+0000343352 00000 n
+0000343417 00000 n
+0000343482 00000 n
+0000343547 00000 n
+0000343612 00000 n
+0000343677 00000 n
+0000343742 00000 n
+0000343807 00000 n
+0000343872 00000 n
+0000343937 00000 n
+0000344002 00000 n
+0000344067 00000 n
+0000344132 00000 n
+0000344197 00000 n
+0000344262 00000 n
+0000344327 00000 n
+0000344392 00000 n
+0000344455 00000 n
+0000344520 00000 n
+0000344585 00000 n
+0000344650 00000 n
+0000344715 00000 n
+0000344780 00000 n
+0000344844 00000 n
+0000344909 00000 n
+0000344974 00000 n
+0000345039 00000 n
+0000345104 00000 n
+0000345169 00000 n
+0000345233 00000 n
+0000345298 00000 n
+0000349938 00000 n
+0000348061 00000 n
0000345565 00000 n
-0000348050 00000 n
-0000348114 00000 n
-0000348179 00000 n
-0000348243 00000 n
-0000348308 00000 n
-0000348373 00000 n
-0000348438 00000 n
-0000348503 00000 n
-0000348568 00000 n
-0000348633 00000 n
-0000348698 00000 n
-0000348763 00000 n
-0000348826 00000 n
-0000348891 00000 n
-0000348956 00000 n
-0000349021 00000 n
-0000349086 00000 n
-0000349151 00000 n
-0000349216 00000 n
-0000349281 00000 n
-0000349346 00000 n
-0000349411 00000 n
-0000349476 00000 n
-0000349541 00000 n
-0000349606 00000 n
-0000349669 00000 n
-0000349734 00000 n
-0000349799 00000 n
-0000349864 00000 n
-0000349929 00000 n
-0000349994 00000 n
-0000350059 00000 n
-0000350120 00000 n
-0000350185 00000 n
-0000350250 00000 n
-0000350315 00000 n
-0000350380 00000 n
-0000355986 00000 n
-0000352685 00000 n
-0000350648 00000 n
-0000352810 00000 n
-0000352874 00000 n
-0000352939 00000 n
-0000353003 00000 n
-0000353068 00000 n
-0000353133 00000 n
-0000353198 00000 n
-0000353263 00000 n
-0000353328 00000 n
-0000353393 00000 n
-0000353458 00000 n
-0000353522 00000 n
-0000353587 00000 n
-0000353650 00000 n
-0000353715 00000 n
-0000353780 00000 n
-0000353845 00000 n
-0000353910 00000 n
-0000353975 00000 n
-0000354040 00000 n
-0000354105 00000 n
-0000354170 00000 n
-0000354235 00000 n
-0000354300 00000 n
-0000354365 00000 n
-0000354429 00000 n
-0000354494 00000 n
-0000354559 00000 n
-0000354624 00000 n
-0000354689 00000 n
-0000354754 00000 n
-0000354819 00000 n
-0000354884 00000 n
-0000354949 00000 n
-0000355014 00000 n
-0000355079 00000 n
-0000355144 00000 n
-0000355209 00000 n
-0000355274 00000 n
-0000355339 00000 n
-0000355404 00000 n
-0000355469 00000 n
-0000355534 00000 n
-0000355599 00000 n
-0000355664 00000 n
-0000355728 00000 n
-0000355793 00000 n
-0000355858 00000 n
-0000355922 00000 n
-0000361539 00000 n
-0000358887 00000 n
-0000356189 00000 n
-0000359012 00000 n
-0000359076 00000 n
-0000359141 00000 n
-0000359206 00000 n
-0000359271 00000 n
-0000359336 00000 n
-0000359401 00000 n
-0000359466 00000 n
-0000359531 00000 n
-0000359596 00000 n
-0000359661 00000 n
-0000359726 00000 n
-0000359791 00000 n
-0000359855 00000 n
-0000359920 00000 n
-0000359985 00000 n
-0000360050 00000 n
-0000360114 00000 n
-0000360179 00000 n
-0000360244 00000 n
-0000360309 00000 n
-0000360374 00000 n
-0000360439 00000 n
-0000360504 00000 n
-0000360569 00000 n
-0000360634 00000 n
-0000360698 00000 n
-0000360763 00000 n
-0000360828 00000 n
-0000360893 00000 n
-0000360958 00000 n
-0000361023 00000 n
-0000361088 00000 n
-0000361153 00000 n
-0000361217 00000 n
-0000361282 00000 n
-0000361345 00000 n
-0000361410 00000 n
-0000361475 00000 n
-0000364751 00000 n
-0000367889 00000 n
-0000364578 00000 n
-0000361755 00000 n
-0000364909 00000 n
-0000364973 00000 n
-0000365038 00000 n
-0000365103 00000 n
-0000365168 00000 n
-0000365233 00000 n
-0000365298 00000 n
-0000365363 00000 n
-0000365427 00000 n
-0000365492 00000 n
-0000365557 00000 n
-0000365622 00000 n
-0000365687 00000 n
-0000365752 00000 n
-0000365817 00000 n
-0000365882 00000 n
-0000365947 00000 n
-0000366011 00000 n
-0000366076 00000 n
-0000366141 00000 n
-0000366206 00000 n
-0000366271 00000 n
-0000366336 00000 n
-0000366401 00000 n
-0000366464 00000 n
-0000366529 00000 n
-0000366594 00000 n
-0000366722 00000 n
-0000366787 00000 n
-0000366852 00000 n
-0000366917 00000 n
-0000366982 00000 n
-0000367047 00000 n
-0000367111 00000 n
-0000367176 00000 n
-0000367241 00000 n
-0000367306 00000 n
-0000367371 00000 n
-0000367436 00000 n
-0000367501 00000 n
-0000367566 00000 n
-0000367631 00000 n
-0000367695 00000 n
-0000367760 00000 n
-0000367825 00000 n
-0000364720 00000 n
-0000374469 00000 n
-0000371491 00000 n
-0000368144 00000 n
-0000371616 00000 n
-0000371680 00000 n
-0000371745 00000 n
-0000371809 00000 n
-0000371874 00000 n
-0000371939 00000 n
-0000372004 00000 n
-0000372069 00000 n
-0000372134 00000 n
-0000372199 00000 n
-0000372264 00000 n
-0000372329 00000 n
-0000372393 00000 n
-0000372458 00000 n
-0000372523 00000 n
-0000372588 00000 n
-0000372653 00000 n
-0000372718 00000 n
-0000372783 00000 n
-0000372848 00000 n
-0000372913 00000 n
-0000372977 00000 n
-0000373042 00000 n
-0000373107 00000 n
-0000373172 00000 n
-0000373237 00000 n
-0000373302 00000 n
-0000373367 00000 n
-0000373432 00000 n
-0000373497 00000 n
-0000373561 00000 n
-0000373626 00000 n
-0000373691 00000 n
-0000373756 00000 n
-0000373821 00000 n
-0000373886 00000 n
-0000373951 00000 n
-0000374016 00000 n
-0000374081 00000 n
-0000374145 00000 n
-0000374210 00000 n
-0000374275 00000 n
-0000374340 00000 n
-0000374405 00000 n
-0000378368 00000 n
-0000378525 00000 n
-0000380625 00000 n
-0000378186 00000 n
-0000374672 00000 n
-0000378682 00000 n
-0000378746 00000 n
-0000378811 00000 n
-0000378875 00000 n
-0000378940 00000 n
-0000379005 00000 n
-0000379070 00000 n
-0000379135 00000 n
-0000379200 00000 n
-0000379265 00000 n
-0000379330 00000 n
-0000379395 00000 n
-0000379460 00000 n
-0000379525 00000 n
-0000379590 00000 n
-0000379655 00000 n
-0000379717 00000 n
-0000379782 00000 n
-0000379847 00000 n
-0000379911 00000 n
-0000379976 00000 n
-0000380041 00000 n
-0000380106 00000 n
-0000380171 00000 n
-0000380236 00000 n
-0000380301 00000 n
-0000380366 00000 n
-0000380431 00000 n
-0000380496 00000 n
-0000380561 00000 n
-0000378328 00000 n
-0000386234 00000 n
-0000382675 00000 n
-0000380906 00000 n
-0000382800 00000 n
-0000382864 00000 n
-0000382929 00000 n
-0000382993 00000 n
-0000383058 00000 n
-0000383123 00000 n
-0000383188 00000 n
-0000383253 00000 n
-0000383318 00000 n
-0000383383 00000 n
-0000383448 00000 n
-0000383513 00000 n
-0000383577 00000 n
-0000383642 00000 n
-0000383707 00000 n
-0000383772 00000 n
-0000383837 00000 n
-0000383902 00000 n
-0000383967 00000 n
-0000384031 00000 n
-0000384096 00000 n
-0000384161 00000 n
-0000384226 00000 n
-0000384291 00000 n
-0000384356 00000 n
-0000384421 00000 n
-0000384486 00000 n
-0000384551 00000 n
-0000384615 00000 n
-0000384680 00000 n
-0000384745 00000 n
-0000384810 00000 n
-0000384875 00000 n
-0000384940 00000 n
-0000385005 00000 n
-0000385070 00000 n
-0000385135 00000 n
-0000385199 00000 n
-0000385264 00000 n
-0000385329 00000 n
-0000385394 00000 n
-0000385459 00000 n
-0000385524 00000 n
-0000385589 00000 n
-0000385654 00000 n
-0000385719 00000 n
-0000385783 00000 n
-0000385847 00000 n
-0000385912 00000 n
-0000385977 00000 n
-0000386041 00000 n
-0000386106 00000 n
-0000386170 00000 n
-0000392234 00000 n
-0000388218 00000 n
-0000386411 00000 n
-0000388343 00000 n
-0000388407 00000 n
-0000388471 00000 n
-0000388536 00000 n
-0000388601 00000 n
-0000388666 00000 n
-0000388731 00000 n
-0000388796 00000 n
-0000388861 00000 n
-0000388926 00000 n
-0000388991 00000 n
-0000389055 00000 n
-0000389120 00000 n
-0000389185 00000 n
-0000389250 00000 n
-0000389315 00000 n
-0000389380 00000 n
-0000389445 00000 n
-0000389510 00000 n
-0000389575 00000 n
-0000389639 00000 n
-0000389704 00000 n
-0000389769 00000 n
-0000389834 00000 n
-0000389899 00000 n
-0000389964 00000 n
-0000390029 00000 n
-0000390094 00000 n
-0000390159 00000 n
-0000390223 00000 n
-0000390288 00000 n
-0000390353 00000 n
-0000390418 00000 n
-0000390483 00000 n
-0000390548 00000 n
-0000390613 00000 n
-0000390678 00000 n
-0000390743 00000 n
-0000390807 00000 n
-0000390872 00000 n
-0000390937 00000 n
-0000391002 00000 n
-0000391067 00000 n
-0000391132 00000 n
-0000391197 00000 n
-0000391262 00000 n
-0000391327 00000 n
-0000391391 00000 n
-0000391456 00000 n
-0000391521 00000 n
-0000391586 00000 n
-0000391651 00000 n
-0000391716 00000 n
-0000391781 00000 n
-0000391846 00000 n
-0000391911 00000 n
-0000391975 00000 n
-0000392040 00000 n
-0000392105 00000 n
-0000392170 00000 n
-0000398347 00000 n
-0000395501 00000 n
-0000392424 00000 n
-0000395626 00000 n
-0000395690 00000 n
-0000395755 00000 n
-0000395819 00000 n
-0000395884 00000 n
-0000395949 00000 n
-0000396014 00000 n
-0000396078 00000 n
-0000396143 00000 n
-0000396208 00000 n
-0000396273 00000 n
-0000396338 00000 n
-0000396402 00000 n
-0000396467 00000 n
-0000396532 00000 n
-0000396597 00000 n
-0000396662 00000 n
-0000396727 00000 n
-0000396792 00000 n
-0000396857 00000 n
-0000396921 00000 n
-0000396986 00000 n
-0000397051 00000 n
-0000397116 00000 n
-0000397181 00000 n
-0000397246 00000 n
-0000397311 00000 n
-0000397376 00000 n
-0000397440 00000 n
-0000397505 00000 n
-0000397570 00000 n
-0000397635 00000 n
-0000397700 00000 n
-0000397765 00000 n
-0000397830 00000 n
-0000397895 00000 n
-0000397960 00000 n
-0000398025 00000 n
-0000398089 00000 n
-0000398154 00000 n
-0000398219 00000 n
-0000398283 00000 n
-0000844689 00000 n
-0000401691 00000 n
-0000404638 00000 n
-0000401518 00000 n
-0000398563 00000 n
-0000401849 00000 n
-0000401913 00000 n
-0000401978 00000 n
-0000402043 00000 n
-0000402108 00000 n
-0000402173 00000 n
-0000402238 00000 n
-0000402303 00000 n
-0000402368 00000 n
-0000402433 00000 n
-0000402497 00000 n
-0000402562 00000 n
-0000402626 00000 n
-0000402691 00000 n
-0000402756 00000 n
-0000402821 00000 n
-0000402886 00000 n
-0000402951 00000 n
-0000403016 00000 n
-0000403081 00000 n
-0000403146 00000 n
-0000403211 00000 n
-0000403276 00000 n
-0000403341 00000 n
-0000403406 00000 n
-0000403471 00000 n
-0000403536 00000 n
-0000403601 00000 n
-0000403666 00000 n
-0000403731 00000 n
-0000403796 00000 n
-0000403860 00000 n
-0000403925 00000 n
-0000403990 00000 n
-0000404055 00000 n
-0000404120 00000 n
-0000404185 00000 n
-0000404250 00000 n
-0000404315 00000 n
-0000404380 00000 n
-0000404445 00000 n
-0000404510 00000 n
-0000404575 00000 n
-0000401660 00000 n
-0000410800 00000 n
-0000407175 00000 n
-0000404919 00000 n
-0000407300 00000 n
-0000407364 00000 n
-0000407429 00000 n
-0000407493 00000 n
-0000407558 00000 n
-0000407623 00000 n
-0000407688 00000 n
-0000407753 00000 n
-0000407818 00000 n
-0000407883 00000 n
-0000407948 00000 n
-0000408076 00000 n
-0000408141 00000 n
-0000408206 00000 n
-0000408271 00000 n
-0000408336 00000 n
-0000408401 00000 n
-0000408466 00000 n
-0000408531 00000 n
-0000408596 00000 n
-0000408661 00000 n
-0000408726 00000 n
-0000408791 00000 n
-0000408854 00000 n
-0000408919 00000 n
-0000408984 00000 n
-0000409049 00000 n
-0000409114 00000 n
-0000409179 00000 n
-0000409244 00000 n
-0000409309 00000 n
-0000409374 00000 n
-0000409439 00000 n
-0000409504 00000 n
-0000409569 00000 n
-0000409634 00000 n
-0000409699 00000 n
-0000409764 00000 n
-0000409829 00000 n
-0000409894 00000 n
-0000409958 00000 n
-0000410023 00000 n
-0000410088 00000 n
-0000410153 00000 n
-0000410218 00000 n
-0000410283 00000 n
-0000410348 00000 n
-0000410413 00000 n
-0000410478 00000 n
-0000410542 00000 n
-0000410607 00000 n
-0000410672 00000 n
-0000410736 00000 n
-0000416847 00000 n
-0000413353 00000 n
-0000410977 00000 n
-0000413478 00000 n
-0000413542 00000 n
-0000413607 00000 n
-0000413671 00000 n
-0000413736 00000 n
-0000413801 00000 n
-0000413866 00000 n
-0000413931 00000 n
-0000413996 00000 n
-0000414060 00000 n
-0000414125 00000 n
-0000414190 00000 n
-0000414255 00000 n
-0000414320 00000 n
-0000414385 00000 n
-0000414450 00000 n
-0000414515 00000 n
-0000414579 00000 n
-0000414644 00000 n
-0000414709 00000 n
-0000414774 00000 n
-0000414839 00000 n
-0000414904 00000 n
-0000414969 00000 n
-0000415034 00000 n
-0000415099 00000 n
-0000415163 00000 n
-0000415228 00000 n
-0000415293 00000 n
-0000415358 00000 n
-0000415423 00000 n
-0000415488 00000 n
-0000415553 00000 n
-0000415618 00000 n
-0000415683 00000 n
-0000415747 00000 n
-0000415812 00000 n
-0000415877 00000 n
-0000415942 00000 n
-0000416007 00000 n
-0000416072 00000 n
-0000416137 00000 n
-0000416202 00000 n
-0000416267 00000 n
-0000416331 00000 n
-0000416395 00000 n
-0000416460 00000 n
-0000416524 00000 n
-0000416589 00000 n
-0000416654 00000 n
-0000416719 00000 n
-0000416783 00000 n
-0000422419 00000 n
-0000419702 00000 n
-0000417024 00000 n
-0000419827 00000 n
-0000419891 00000 n
-0000419956 00000 n
-0000420020 00000 n
-0000420085 00000 n
-0000420150 00000 n
-0000420215 00000 n
-0000420280 00000 n
-0000420343 00000 n
-0000420408 00000 n
-0000420473 00000 n
-0000420538 00000 n
-0000420603 00000 n
-0000420668 00000 n
-0000420733 00000 n
-0000420798 00000 n
-0000420863 00000 n
-0000420928 00000 n
-0000420993 00000 n
-0000421058 00000 n
-0000421123 00000 n
-0000421188 00000 n
-0000421253 00000 n
-0000421318 00000 n
-0000421383 00000 n
-0000421448 00000 n
-0000421513 00000 n
-0000421578 00000 n
-0000421643 00000 n
-0000421708 00000 n
-0000421773 00000 n
-0000421838 00000 n
-0000421903 00000 n
-0000421967 00000 n
-0000422032 00000 n
-0000422097 00000 n
-0000422161 00000 n
-0000422226 00000 n
-0000422291 00000 n
-0000422355 00000 n
-0000428226 00000 n
-0000424536 00000 n
-0000422622 00000 n
-0000424661 00000 n
-0000424725 00000 n
-0000424790 00000 n
-0000424854 00000 n
-0000424919 00000 n
-0000424984 00000 n
-0000425049 00000 n
-0000425114 00000 n
-0000425178 00000 n
-0000425242 00000 n
-0000425307 00000 n
-0000425372 00000 n
-0000425437 00000 n
-0000425502 00000 n
-0000425567 00000 n
-0000425632 00000 n
-0000425697 00000 n
-0000425762 00000 n
-0000425827 00000 n
-0000425892 00000 n
-0000425957 00000 n
-0000426022 00000 n
-0000426087 00000 n
-0000426152 00000 n
-0000426216 00000 n
-0000426281 00000 n
-0000426346 00000 n
-0000426411 00000 n
-0000426476 00000 n
-0000426541 00000 n
-0000426606 00000 n
-0000426671 00000 n
-0000426736 00000 n
-0000426800 00000 n
-0000426865 00000 n
-0000426930 00000 n
-0000426995 00000 n
-0000427060 00000 n
-0000427124 00000 n
-0000427189 00000 n
-0000427254 00000 n
-0000427319 00000 n
-0000427384 00000 n
-0000427449 00000 n
-0000427514 00000 n
-0000427579 00000 n
-0000427644 00000 n
-0000427709 00000 n
-0000427774 00000 n
-0000427839 00000 n
-0000427904 00000 n
-0000427968 00000 n
-0000428033 00000 n
-0000428098 00000 n
-0000428162 00000 n
-0000437113 00000 n
-0000433981 00000 n
-0000430160 00000 n
-0000428429 00000 n
-0000430285 00000 n
-0000430349 00000 n
-0000430414 00000 n
-0000430478 00000 n
-0000430543 00000 n
-0000430608 00000 n
-0000430673 00000 n
-0000430738 00000 n
-0000430803 00000 n
-0000430868 00000 n
-0000430933 00000 n
-0000430998 00000 n
-0000431062 00000 n
-0000431127 00000 n
-0000431192 00000 n
-0000431257 00000 n
-0000431322 00000 n
-0000431387 00000 n
-0000431452 00000 n
-0000431517 00000 n
-0000431582 00000 n
-0000431646 00000 n
-0000431711 00000 n
-0000431776 00000 n
-0000431841 00000 n
-0000431906 00000 n
-0000431970 00000 n
-0000432035 00000 n
-0000432099 00000 n
-0000432164 00000 n
-0000432229 00000 n
-0000432294 00000 n
-0000432359 00000 n
-0000432424 00000 n
-0000432489 00000 n
-0000432554 00000 n
-0000432619 00000 n
-0000432684 00000 n
-0000432748 00000 n
-0000432813 00000 n
-0000432878 00000 n
-0000432943 00000 n
-0000433008 00000 n
-0000433073 00000 n
-0000433138 00000 n
-0000433203 00000 n
-0000433268 00000 n
-0000433332 00000 n
-0000433397 00000 n
-0000433462 00000 n
-0000433527 00000 n
-0000433592 00000 n
-0000433657 00000 n
-0000433722 00000 n
-0000433787 00000 n
-0000433852 00000 n
-0000433916 00000 n
-0000440511 00000 n
-0000436940 00000 n
-0000434145 00000 n
-0000437271 00000 n
-0000437335 00000 n
-0000437400 00000 n
-0000437465 00000 n
-0000437530 00000 n
-0000437595 00000 n
-0000437659 00000 n
-0000437724 00000 n
-0000437789 00000 n
-0000437854 00000 n
-0000437919 00000 n
-0000438047 00000 n
-0000438112 00000 n
-0000438177 00000 n
-0000438242 00000 n
-0000438307 00000 n
-0000438372 00000 n
-0000438437 00000 n
-0000438502 00000 n
-0000438567 00000 n
-0000438632 00000 n
-0000438695 00000 n
-0000438760 00000 n
-0000438825 00000 n
-0000438890 00000 n
-0000438955 00000 n
-0000439020 00000 n
-0000439085 00000 n
-0000439150 00000 n
-0000439215 00000 n
-0000439279 00000 n
-0000439344 00000 n
-0000439409 00000 n
-0000439474 00000 n
-0000439539 00000 n
-0000439604 00000 n
-0000439669 00000 n
-0000439734 00000 n
-0000439799 00000 n
-0000439863 00000 n
-0000439928 00000 n
-0000439993 00000 n
-0000440058 00000 n
-0000440123 00000 n
-0000440188 00000 n
-0000440253 00000 n
-0000440318 00000 n
-0000440383 00000 n
-0000440447 00000 n
-0000437082 00000 n
-0000445081 00000 n
-0000442759 00000 n
-0000440766 00000 n
-0000442884 00000 n
-0000442948 00000 n
-0000443013 00000 n
-0000443078 00000 n
-0000443141 00000 n
-0000443206 00000 n
-0000443271 00000 n
-0000443336 00000 n
-0000443401 00000 n
-0000443465 00000 n
-0000443530 00000 n
-0000443595 00000 n
-0000443660 00000 n
-0000443725 00000 n
-0000443790 00000 n
-0000443855 00000 n
-0000443919 00000 n
-0000443984 00000 n
-0000444048 00000 n
-0000444112 00000 n
-0000444176 00000 n
-0000444239 00000 n
-0000444304 00000 n
-0000444368 00000 n
-0000444433 00000 n
-0000444498 00000 n
-0000444561 00000 n
-0000444626 00000 n
-0000444691 00000 n
-0000444756 00000 n
-0000444821 00000 n
-0000444886 00000 n
-0000444951 00000 n
-0000445016 00000 n
-0000447782 00000 n
-0000451179 00000 n
-0000447609 00000 n
-0000445297 00000 n
-0000447940 00000 n
-0000448004 00000 n
-0000448068 00000 n
-0000448133 00000 n
-0000448198 00000 n
-0000448263 00000 n
-0000448328 00000 n
-0000448393 00000 n
-0000448458 00000 n
-0000448523 00000 n
-0000448588 00000 n
-0000448652 00000 n
-0000448717 00000 n
-0000448782 00000 n
-0000448847 00000 n
-0000448912 00000 n
-0000448977 00000 n
-0000449042 00000 n
-0000449107 00000 n
-0000449172 00000 n
-0000449236 00000 n
-0000449301 00000 n
-0000449366 00000 n
-0000449431 00000 n
-0000449496 00000 n
-0000449561 00000 n
-0000449626 00000 n
-0000449691 00000 n
-0000449756 00000 n
-0000449821 00000 n
-0000449886 00000 n
-0000449951 00000 n
-0000450016 00000 n
-0000450081 00000 n
-0000450145 00000 n
-0000450210 00000 n
-0000450337 00000 n
-0000450402 00000 n
-0000450467 00000 n
-0000450531 00000 n
-0000450596 00000 n
-0000450661 00000 n
-0000450726 00000 n
-0000450791 00000 n
-0000450856 00000 n
-0000450921 00000 n
-0000450986 00000 n
-0000451051 00000 n
-0000451116 00000 n
-0000447751 00000 n
-0000457313 00000 n
-0000454010 00000 n
-0000451408 00000 n
-0000454135 00000 n
-0000454199 00000 n
-0000454264 00000 n
-0000454328 00000 n
-0000454393 00000 n
-0000454458 00000 n
-0000454523 00000 n
-0000454588 00000 n
-0000454653 00000 n
-0000454718 00000 n
-0000454783 00000 n
-0000454847 00000 n
-0000454912 00000 n
-0000454977 00000 n
-0000455042 00000 n
-0000455107 00000 n
-0000455172 00000 n
-0000455237 00000 n
-0000455302 00000 n
-0000455367 00000 n
-0000455431 00000 n
-0000455496 00000 n
-0000455561 00000 n
-0000455626 00000 n
-0000455691 00000 n
-0000455756 00000 n
-0000455821 00000 n
-0000455886 00000 n
-0000455951 00000 n
-0000456015 00000 n
-0000456080 00000 n
-0000456145 00000 n
-0000456210 00000 n
-0000456275 00000 n
-0000456340 00000 n
-0000456405 00000 n
-0000456470 00000 n
-0000456535 00000 n
-0000456600 00000 n
-0000456665 00000 n
-0000456730 00000 n
-0000456794 00000 n
-0000456859 00000 n
-0000456924 00000 n
-0000456989 00000 n
-0000457054 00000 n
-0000457119 00000 n
-0000457184 00000 n
-0000457248 00000 n
-0000844853 00000 n
-0000463108 00000 n
-0000459355 00000 n
-0000457516 00000 n
-0000459480 00000 n
-0000459544 00000 n
-0000459608 00000 n
-0000459673 00000 n
-0000459738 00000 n
-0000459803 00000 n
-0000459868 00000 n
-0000459932 00000 n
-0000459997 00000 n
-0000460062 00000 n
-0000460127 00000 n
-0000460192 00000 n
-0000460257 00000 n
-0000460322 00000 n
-0000460387 00000 n
-0000460451 00000 n
-0000460516 00000 n
-0000460581 00000 n
-0000460646 00000 n
-0000460711 00000 n
-0000460775 00000 n
-0000460840 00000 n
-0000460905 00000 n
-0000460970 00000 n
-0000461035 00000 n
-0000461100 00000 n
-0000461165 00000 n
-0000461230 00000 n
-0000461294 00000 n
-0000461359 00000 n
-0000461424 00000 n
-0000461489 00000 n
-0000461554 00000 n
-0000461619 00000 n
-0000461684 00000 n
-0000461749 00000 n
-0000461814 00000 n
-0000461877 00000 n
-0000461942 00000 n
-0000462007 00000 n
-0000462072 00000 n
-0000462137 00000 n
-0000462202 00000 n
-0000462267 00000 n
-0000462332 00000 n
-0000462397 00000 n
-0000462461 00000 n
-0000462526 00000 n
-0000462591 00000 n
-0000462656 00000 n
-0000462721 00000 n
-0000462786 00000 n
-0000462851 00000 n
-0000462916 00000 n
-0000462981 00000 n
-0000463044 00000 n
-0000465712 00000 n
-0000469305 00000 n
-0000465539 00000 n
-0000463285 00000 n
-0000465870 00000 n
-0000465934 00000 n
-0000465999 00000 n
-0000466063 00000 n
-0000466128 00000 n
-0000466192 00000 n
-0000466257 00000 n
-0000466322 00000 n
-0000466387 00000 n
-0000466452 00000 n
-0000466517 00000 n
-0000466582 00000 n
-0000466647 00000 n
-0000466712 00000 n
-0000466776 00000 n
-0000466841 00000 n
-0000466906 00000 n
-0000466971 00000 n
-0000467036 00000 n
-0000467101 00000 n
-0000467166 00000 n
-0000467231 00000 n
-0000467296 00000 n
-0000467361 00000 n
-0000467426 00000 n
-0000467491 00000 n
-0000467556 00000 n
-0000467621 00000 n
-0000467686 00000 n
-0000467750 00000 n
-0000467815 00000 n
-0000467880 00000 n
-0000468008 00000 n
-0000468073 00000 n
-0000468138 00000 n
-0000468203 00000 n
-0000468268 00000 n
-0000468333 00000 n
-0000468398 00000 n
-0000468462 00000 n
-0000468527 00000 n
-0000468592 00000 n
-0000468657 00000 n
-0000468722 00000 n
-0000468787 00000 n
-0000468852 00000 n
-0000468917 00000 n
-0000468982 00000 n
-0000469046 00000 n
-0000469111 00000 n
-0000469176 00000 n
-0000469241 00000 n
-0000465681 00000 n
-0000475951 00000 n
-0000471675 00000 n
-0000469534 00000 n
-0000471800 00000 n
-0000471864 00000 n
-0000471929 00000 n
-0000471993 00000 n
-0000472058 00000 n
-0000472123 00000 n
-0000472188 00000 n
-0000472253 00000 n
-0000472318 00000 n
-0000472383 00000 n
-0000472448 00000 n
-0000472513 00000 n
-0000472577 00000 n
-0000472642 00000 n
-0000472707 00000 n
-0000472772 00000 n
-0000472837 00000 n
-0000472902 00000 n
-0000472967 00000 n
-0000473032 00000 n
-0000473097 00000 n
-0000473161 00000 n
-0000473226 00000 n
-0000473291 00000 n
-0000473356 00000 n
-0000473421 00000 n
-0000473486 00000 n
-0000473551 00000 n
-0000473616 00000 n
-0000473681 00000 n
-0000473745 00000 n
-0000473810 00000 n
-0000473875 00000 n
-0000473940 00000 n
-0000474005 00000 n
-0000474070 00000 n
-0000474135 00000 n
-0000474200 00000 n
-0000474265 00000 n
-0000474329 00000 n
-0000474394 00000 n
-0000474459 00000 n
-0000474524 00000 n
-0000474589 00000 n
-0000474654 00000 n
-0000474719 00000 n
-0000474784 00000 n
-0000474849 00000 n
-0000474913 00000 n
-0000474978 00000 n
-0000475043 00000 n
-0000475108 00000 n
-0000475173 00000 n
-0000475238 00000 n
-0000475303 00000 n
-0000475368 00000 n
-0000475433 00000 n
-0000475497 00000 n
-0000475562 00000 n
-0000475627 00000 n
-0000475692 00000 n
-0000475757 00000 n
-0000475822 00000 n
-0000475887 00000 n
-0000482156 00000 n
-0000478660 00000 n
-0000476102 00000 n
-0000478785 00000 n
-0000478849 00000 n
-0000478914 00000 n
-0000478978 00000 n
-0000479043 00000 n
-0000479108 00000 n
-0000479173 00000 n
+0000348186 00000 n
+0000348250 00000 n
+0000348315 00000 n
+0000348380 00000 n
+0000348445 00000 n
+0000348510 00000 n
+0000348575 00000 n
+0000348640 00000 n
+0000348705 00000 n
+0000348769 00000 n
+0000348834 00000 n
+0000348899 00000 n
+0000348964 00000 n
+0000349029 00000 n
+0000349094 00000 n
+0000349159 00000 n
+0000349224 00000 n
+0000349289 00000 n
+0000349354 00000 n
+0000349419 00000 n
+0000349484 00000 n
+0000349549 00000 n
+0000349614 00000 n
+0000349679 00000 n
+0000349744 00000 n
+0000349809 00000 n
+0000349874 00000 n
+0000355323 00000 n
+0000352409 00000 n
+0000350141 00000 n
+0000352534 00000 n
+0000352598 00000 n
+0000352662 00000 n
+0000352727 00000 n
+0000352792 00000 n
+0000352857 00000 n
+0000352922 00000 n
+0000352987 00000 n
+0000353052 00000 n
+0000353116 00000 n
+0000353181 00000 n
+0000353246 00000 n
+0000353311 00000 n
+0000353376 00000 n
+0000353441 00000 n
+0000353506 00000 n
+0000353571 00000 n
+0000353636 00000 n
+0000353701 00000 n
+0000353766 00000 n
+0000353831 00000 n
+0000353896 00000 n
+0000353961 00000 n
+0000354026 00000 n
+0000354091 00000 n
+0000354156 00000 n
+0000354220 00000 n
+0000354285 00000 n
+0000354350 00000 n
+0000354415 00000 n
+0000354480 00000 n
+0000354545 00000 n
+0000354610 00000 n
+0000354675 00000 n
+0000354740 00000 n
+0000354805 00000 n
+0000354870 00000 n
+0000354934 00000 n
+0000354999 00000 n
+0000355064 00000 n
+0000355129 00000 n
+0000355194 00000 n
+0000355258 00000 n
+0000360614 00000 n
+0000357438 00000 n
+0000355539 00000 n
+0000357563 00000 n
+0000357627 00000 n
+0000357692 00000 n
+0000357756 00000 n
+0000357821 00000 n
+0000357886 00000 n
+0000357951 00000 n
+0000358016 00000 n
+0000358081 00000 n
+0000358146 00000 n
+0000358210 00000 n
+0000358275 00000 n
+0000358340 00000 n
+0000358405 00000 n
+0000358470 00000 n
+0000358535 00000 n
+0000358600 00000 n
+0000358664 00000 n
+0000358729 00000 n
+0000358794 00000 n
+0000358859 00000 n
+0000358924 00000 n
+0000358989 00000 n
+0000359054 00000 n
+0000359119 00000 n
+0000359184 00000 n
+0000359249 00000 n
+0000359314 00000 n
+0000359379 00000 n
+0000359444 00000 n
+0000359509 00000 n
+0000359574 00000 n
+0000359639 00000 n
+0000359704 00000 n
+0000359769 00000 n
+0000359834 00000 n
+0000359899 00000 n
+0000359964 00000 n
+0000360029 00000 n
+0000360094 00000 n
+0000360159 00000 n
+0000360224 00000 n
+0000360289 00000 n
+0000360354 00000 n
+0000360419 00000 n
+0000360484 00000 n
+0000360549 00000 n
+0000363913 00000 n
+0000366405 00000 n
+0000363740 00000 n
+0000360791 00000 n
+0000364071 00000 n
+0000364135 00000 n
+0000364200 00000 n
+0000364265 00000 n
+0000364330 00000 n
+0000364395 00000 n
+0000364460 00000 n
+0000364525 00000 n
+0000364590 00000 n
+0000364655 00000 n
+0000364719 00000 n
+0000364784 00000 n
+0000364849 00000 n
+0000364914 00000 n
+0000364979 00000 n
+0000365044 00000 n
+0000365109 00000 n
+0000365174 00000 n
+0000365239 00000 n
+0000365304 00000 n
+0000365369 00000 n
+0000365434 00000 n
+0000365498 00000 n
+0000365563 00000 n
+0000365627 00000 n
+0000365692 00000 n
+0000365757 00000 n
+0000365822 00000 n
+0000365887 00000 n
+0000365952 00000 n
+0000366017 00000 n
+0000366082 00000 n
+0000366147 00000 n
+0000366212 00000 n
+0000366277 00000 n
+0000366341 00000 n
+0000363882 00000 n
+0000373109 00000 n
+0000369549 00000 n
+0000366673 00000 n
+0000369674 00000 n
+0000369738 00000 n
+0000369803 00000 n
+0000369867 00000 n
+0000369932 00000 n
+0000369997 00000 n
+0000370062 00000 n
+0000370127 00000 n
+0000370192 00000 n
+0000370257 00000 n
+0000370322 00000 n
+0000370387 00000 n
+0000370452 00000 n
+0000370517 00000 n
+0000370582 00000 n
+0000370647 00000 n
+0000370712 00000 n
+0000370840 00000 n
+0000370905 00000 n
+0000370969 00000 n
+0000371034 00000 n
+0000371099 00000 n
+0000371164 00000 n
+0000371229 00000 n
+0000371294 00000 n
+0000371359 00000 n
+0000371424 00000 n
+0000371489 00000 n
+0000371553 00000 n
+0000371618 00000 n
+0000371683 00000 n
+0000371748 00000 n
+0000371813 00000 n
+0000371878 00000 n
+0000371943 00000 n
+0000372008 00000 n
+0000372073 00000 n
+0000372137 00000 n
+0000372202 00000 n
+0000372267 00000 n
+0000372332 00000 n
+0000372397 00000 n
+0000372462 00000 n
+0000372527 00000 n
+0000372592 00000 n
+0000372657 00000 n
+0000372721 00000 n
+0000372786 00000 n
+0000372851 00000 n
+0000372916 00000 n
+0000372981 00000 n
+0000373045 00000 n
+0000379082 00000 n
+0000376623 00000 n
+0000373312 00000 n
+0000376748 00000 n
+0000376812 00000 n
+0000376877 00000 n
+0000376941 00000 n
+0000377006 00000 n
+0000377071 00000 n
+0000377136 00000 n
+0000377201 00000 n
+0000377266 00000 n
+0000377331 00000 n
+0000377396 00000 n
+0000377461 00000 n
+0000377525 00000 n
+0000377590 00000 n
+0000377655 00000 n
+0000377720 00000 n
+0000377785 00000 n
+0000377850 00000 n
+0000377915 00000 n
+0000377980 00000 n
+0000378045 00000 n
+0000378109 00000 n
+0000378174 00000 n
+0000378239 00000 n
+0000378304 00000 n
+0000378369 00000 n
+0000378433 00000 n
+0000378498 00000 n
+0000378563 00000 n
+0000378628 00000 n
+0000378693 00000 n
+0000378758 00000 n
+0000378823 00000 n
+0000378888 00000 n
+0000378953 00000 n
+0000379017 00000 n
+0000382720 00000 n
+0000382877 00000 n
+0000385174 00000 n
+0000382538 00000 n
+0000379298 00000 n
+0000383034 00000 n
+0000383098 00000 n
+0000383161 00000 n
+0000383226 00000 n
+0000383291 00000 n
+0000383356 00000 n
+0000383420 00000 n
+0000383485 00000 n
+0000383550 00000 n
+0000383615 00000 n
+0000383680 00000 n
+0000383745 00000 n
+0000383810 00000 n
+0000383875 00000 n
+0000383940 00000 n
+0000384005 00000 n
+0000384070 00000 n
+0000384135 00000 n
+0000384200 00000 n
+0000384265 00000 n
+0000384330 00000 n
+0000384395 00000 n
+0000384460 00000 n
+0000384525 00000 n
+0000384590 00000 n
+0000384655 00000 n
+0000384720 00000 n
+0000384784 00000 n
+0000384849 00000 n
+0000384914 00000 n
+0000384979 00000 n
+0000385044 00000 n
+0000385109 00000 n
+0000382680 00000 n
+0000390632 00000 n
+0000387137 00000 n
+0000385442 00000 n
+0000387262 00000 n
+0000387326 00000 n
+0000387391 00000 n
+0000387456 00000 n
+0000387521 00000 n
+0000387586 00000 n
+0000387650 00000 n
+0000387715 00000 n
+0000387780 00000 n
+0000387845 00000 n
+0000387910 00000 n
+0000387975 00000 n
+0000388040 00000 n
+0000388105 00000 n
+0000388170 00000 n
+0000388234 00000 n
+0000388299 00000 n
+0000388364 00000 n
+0000388429 00000 n
+0000388494 00000 n
+0000388559 00000 n
+0000388624 00000 n
+0000388689 00000 n
+0000388754 00000 n
+0000388819 00000 n
+0000388884 00000 n
+0000388949 00000 n
+0000389014 00000 n
+0000389079 00000 n
+0000389144 00000 n
+0000389209 00000 n
+0000389274 00000 n
+0000389339 00000 n
+0000389404 00000 n
+0000389468 00000 n
+0000389533 00000 n
+0000389598 00000 n
+0000389662 00000 n
+0000389727 00000 n
+0000389791 00000 n
+0000389856 00000 n
+0000389920 00000 n
+0000389985 00000 n
+0000390050 00000 n
+0000390115 00000 n
+0000390180 00000 n
+0000390245 00000 n
+0000390310 00000 n
+0000390374 00000 n
+0000390439 00000 n
+0000390504 00000 n
+0000390568 00000 n
+0000396444 00000 n
+0000392688 00000 n
+0000390796 00000 n
+0000392813 00000 n
+0000392877 00000 n
+0000392942 00000 n
+0000393006 00000 n
+0000393071 00000 n
+0000393136 00000 n
+0000393201 00000 n
+0000393266 00000 n
+0000393331 00000 n
+0000393396 00000 n
+0000393461 00000 n
+0000393526 00000 n
+0000393590 00000 n
+0000393655 00000 n
+0000393720 00000 n
+0000393785 00000 n
+0000393850 00000 n
+0000393915 00000 n
+0000393980 00000 n
+0000394045 00000 n
+0000394110 00000 n
+0000394174 00000 n
+0000394239 00000 n
+0000394304 00000 n
+0000394369 00000 n
+0000394434 00000 n
+0000394499 00000 n
+0000394564 00000 n
+0000394629 00000 n
+0000394694 00000 n
+0000394758 00000 n
+0000394823 00000 n
+0000394888 00000 n
+0000394953 00000 n
+0000395018 00000 n
+0000395083 00000 n
+0000395148 00000 n
+0000395213 00000 n
+0000395278 00000 n
+0000395342 00000 n
+0000395407 00000 n
+0000395472 00000 n
+0000395537 00000 n
+0000395602 00000 n
+0000395667 00000 n
+0000395732 00000 n
+0000395797 00000 n
+0000395862 00000 n
+0000395927 00000 n
+0000395992 00000 n
+0000396057 00000 n
+0000396122 00000 n
+0000396187 00000 n
+0000396252 00000 n
+0000396316 00000 n
+0000396380 00000 n
+0000847889 00000 n
+0000402844 00000 n
+0000399999 00000 n
+0000396634 00000 n
+0000400124 00000 n
+0000400188 00000 n
+0000400253 00000 n
+0000400317 00000 n
+0000400381 00000 n
+0000400446 00000 n
+0000400511 00000 n
+0000400575 00000 n
+0000400640 00000 n
+0000400705 00000 n
+0000400770 00000 n
+0000400835 00000 n
+0000400900 00000 n
+0000400965 00000 n
+0000401030 00000 n
+0000401095 00000 n
+0000401159 00000 n
+0000401224 00000 n
+0000401288 00000 n
+0000401353 00000 n
+0000401418 00000 n
+0000401483 00000 n
+0000401548 00000 n
+0000401613 00000 n
+0000401678 00000 n
+0000401743 00000 n
+0000401808 00000 n
+0000401873 00000 n
+0000401938 00000 n
+0000402002 00000 n
+0000402067 00000 n
+0000402132 00000 n
+0000402197 00000 n
+0000402262 00000 n
+0000402327 00000 n
+0000402392 00000 n
+0000402457 00000 n
+0000402522 00000 n
+0000402586 00000 n
+0000402651 00000 n
+0000402716 00000 n
+0000402780 00000 n
+0000405803 00000 n
+0000408879 00000 n
+0000405630 00000 n
+0000403073 00000 n
+0000405961 00000 n
+0000406025 00000 n
+0000406089 00000 n
+0000406154 00000 n
+0000406218 00000 n
+0000406283 00000 n
+0000406348 00000 n
+0000406413 00000 n
+0000406478 00000 n
+0000406543 00000 n
+0000406608 00000 n
+0000406673 00000 n
+0000406738 00000 n
+0000406803 00000 n
+0000406868 00000 n
+0000406933 00000 n
+0000406998 00000 n
+0000407063 00000 n
+0000407128 00000 n
+0000407192 00000 n
+0000407257 00000 n
+0000407322 00000 n
+0000407387 00000 n
+0000407452 00000 n
+0000407517 00000 n
+0000407582 00000 n
+0000407647 00000 n
+0000407712 00000 n
+0000407776 00000 n
+0000407841 00000 n
+0000407906 00000 n
+0000407971 00000 n
+0000408036 00000 n
+0000408100 00000 n
+0000408165 00000 n
+0000408230 00000 n
+0000408295 00000 n
+0000408360 00000 n
+0000408425 00000 n
+0000408490 00000 n
+0000408555 00000 n
+0000408620 00000 n
+0000408684 00000 n
+0000408749 00000 n
+0000408814 00000 n
+0000405772 00000 n
+0000415012 00000 n
+0000411454 00000 n
+0000409147 00000 n
+0000411579 00000 n
+0000411706 00000 n
+0000411770 00000 n
+0000411835 00000 n
+0000411900 00000 n
+0000411965 00000 n
+0000412030 00000 n
+0000412095 00000 n
+0000412160 00000 n
+0000412224 00000 n
+0000412289 00000 n
+0000412354 00000 n
+0000412419 00000 n
+0000412484 00000 n
+0000412549 00000 n
+0000412614 00000 n
+0000412679 00000 n
+0000412744 00000 n
+0000412808 00000 n
+0000412873 00000 n
+0000412938 00000 n
+0000413003 00000 n
+0000413068 00000 n
+0000413133 00000 n
+0000413198 00000 n
+0000413263 00000 n
+0000413327 00000 n
+0000413392 00000 n
+0000413457 00000 n
+0000413522 00000 n
+0000413587 00000 n
+0000413652 00000 n
+0000413717 00000 n
+0000413782 00000 n
+0000413847 00000 n
+0000413910 00000 n
+0000413975 00000 n
+0000414040 00000 n
+0000414105 00000 n
+0000414170 00000 n
+0000414235 00000 n
+0000414300 00000 n
+0000414365 00000 n
+0000414430 00000 n
+0000414495 00000 n
+0000414560 00000 n
+0000414625 00000 n
+0000414690 00000 n
+0000414755 00000 n
+0000414820 00000 n
+0000414885 00000 n
+0000414948 00000 n
+0000420178 00000 n
+0000417202 00000 n
+0000415189 00000 n
+0000417327 00000 n
+0000417391 00000 n
+0000417456 00000 n
+0000417520 00000 n
+0000417585 00000 n
+0000417650 00000 n
+0000417715 00000 n
+0000417780 00000 n
+0000417845 00000 n
+0000417910 00000 n
+0000417975 00000 n
+0000418039 00000 n
+0000418104 00000 n
+0000418169 00000 n
+0000418234 00000 n
+0000418299 00000 n
+0000418364 00000 n
+0000418429 00000 n
+0000418494 00000 n
+0000418559 00000 n
+0000418623 00000 n
+0000418688 00000 n
+0000418753 00000 n
+0000418818 00000 n
+0000418883 00000 n
+0000418948 00000 n
+0000419013 00000 n
+0000419078 00000 n
+0000419143 00000 n
+0000419207 00000 n
+0000419270 00000 n
+0000419335 00000 n
+0000419400 00000 n
+0000419465 00000 n
+0000419530 00000 n
+0000419594 00000 n
+0000419659 00000 n
+0000419724 00000 n
+0000419788 00000 n
+0000419853 00000 n
+0000419918 00000 n
+0000419983 00000 n
+0000420048 00000 n
+0000420113 00000 n
+0000425964 00000 n
+0000423053 00000 n
+0000420342 00000 n
+0000423178 00000 n
+0000423242 00000 n
+0000423306 00000 n
+0000423371 00000 n
+0000423436 00000 n
+0000423501 00000 n
+0000423566 00000 n
+0000423631 00000 n
+0000423696 00000 n
+0000423760 00000 n
+0000423825 00000 n
+0000423890 00000 n
+0000423955 00000 n
+0000424020 00000 n
+0000424085 00000 n
+0000424150 00000 n
+0000424214 00000 n
+0000424279 00000 n
+0000424344 00000 n
+0000424409 00000 n
+0000424474 00000 n
+0000424539 00000 n
+0000424604 00000 n
+0000424669 00000 n
+0000424734 00000 n
+0000424799 00000 n
+0000424864 00000 n
+0000424928 00000 n
+0000424993 00000 n
+0000425058 00000 n
+0000425123 00000 n
+0000425188 00000 n
+0000425252 00000 n
+0000425317 00000 n
+0000425382 00000 n
+0000425447 00000 n
+0000425512 00000 n
+0000425577 00000 n
+0000425642 00000 n
+0000425706 00000 n
+0000425771 00000 n
+0000425836 00000 n
+0000425900 00000 n
+0000431685 00000 n
+0000427998 00000 n
+0000426167 00000 n
+0000428123 00000 n
+0000428187 00000 n
+0000428252 00000 n
+0000428316 00000 n
+0000428379 00000 n
+0000428444 00000 n
+0000428509 00000 n
+0000428574 00000 n
+0000428639 00000 n
+0000428704 00000 n
+0000428767 00000 n
+0000428832 00000 n
+0000428897 00000 n
+0000428962 00000 n
+0000429027 00000 n
+0000429091 00000 n
+0000429156 00000 n
+0000429221 00000 n
+0000429286 00000 n
+0000429351 00000 n
+0000429416 00000 n
+0000429481 00000 n
+0000429546 00000 n
+0000429611 00000 n
+0000429675 00000 n
+0000429740 00000 n
+0000429805 00000 n
+0000429870 00000 n
+0000429935 00000 n
+0000430000 00000 n
+0000430065 00000 n
+0000430130 00000 n
+0000430195 00000 n
+0000430259 00000 n
+0000430323 00000 n
+0000430388 00000 n
+0000430453 00000 n
+0000430518 00000 n
+0000430583 00000 n
+0000430648 00000 n
+0000430713 00000 n
+0000430778 00000 n
+0000430843 00000 n
+0000430908 00000 n
+0000430973 00000 n
+0000431038 00000 n
+0000431103 00000 n
+0000431168 00000 n
+0000431233 00000 n
+0000431298 00000 n
+0000431363 00000 n
+0000431427 00000 n
+0000431492 00000 n
+0000431557 00000 n
+0000431621 00000 n
+0000440247 00000 n
+0000437253 00000 n
+0000433691 00000 n
+0000431888 00000 n
+0000433816 00000 n
+0000433880 00000 n
+0000433945 00000 n
+0000434009 00000 n
+0000434074 00000 n
+0000434139 00000 n
+0000434204 00000 n
+0000434269 00000 n
+0000434334 00000 n
+0000434399 00000 n
+0000434464 00000 n
+0000434529 00000 n
+0000434593 00000 n
+0000434658 00000 n
+0000434723 00000 n
+0000434788 00000 n
+0000434853 00000 n
+0000434918 00000 n
+0000434983 00000 n
+0000435048 00000 n
+0000435113 00000 n
+0000435177 00000 n
+0000435241 00000 n
+0000435306 00000 n
+0000435370 00000 n
+0000435435 00000 n
+0000435500 00000 n
+0000435565 00000 n
+0000435630 00000 n
+0000435695 00000 n
+0000435760 00000 n
+0000435825 00000 n
+0000435890 00000 n
+0000435955 00000 n
+0000436020 00000 n
+0000436085 00000 n
+0000436150 00000 n
+0000436215 00000 n
+0000436279 00000 n
+0000436344 00000 n
+0000436409 00000 n
+0000436474 00000 n
+0000436539 00000 n
+0000436604 00000 n
+0000436669 00000 n
+0000436734 00000 n
+0000436799 00000 n
+0000436863 00000 n
+0000436928 00000 n
+0000436993 00000 n
+0000437058 00000 n
+0000437123 00000 n
+0000437188 00000 n
+0000443646 00000 n
+0000440074 00000 n
+0000437417 00000 n
+0000440405 00000 n
+0000440469 00000 n
+0000440534 00000 n
+0000440599 00000 n
+0000440664 00000 n
+0000440729 00000 n
+0000440794 00000 n
+0000440859 00000 n
+0000440924 00000 n
+0000440989 00000 n
+0000441053 00000 n
+0000441180 00000 n
+0000441245 00000 n
+0000441310 00000 n
+0000441375 00000 n
+0000441440 00000 n
+0000441505 00000 n
+0000441570 00000 n
+0000441635 00000 n
+0000441700 00000 n
+0000441765 00000 n
+0000441830 00000 n
+0000441894 00000 n
+0000441959 00000 n
+0000442024 00000 n
+0000442089 00000 n
+0000442154 00000 n
+0000442219 00000 n
+0000442284 00000 n
+0000442349 00000 n
+0000442414 00000 n
+0000442478 00000 n
+0000442543 00000 n
+0000442608 00000 n
+0000442673 00000 n
+0000442738 00000 n
+0000442803 00000 n
+0000442868 00000 n
+0000442933 00000 n
+0000442998 00000 n
+0000443062 00000 n
+0000443127 00000 n
+0000443192 00000 n
+0000443257 00000 n
+0000443322 00000 n
+0000443387 00000 n
+0000443452 00000 n
+0000443517 00000 n
+0000443582 00000 n
+0000440216 00000 n
+0000448213 00000 n
+0000445891 00000 n
+0000443901 00000 n
+0000446016 00000 n
+0000446080 00000 n
+0000446145 00000 n
+0000446210 00000 n
+0000446273 00000 n
+0000446338 00000 n
+0000446403 00000 n
+0000446468 00000 n
+0000446533 00000 n
+0000446597 00000 n
+0000446662 00000 n
+0000446727 00000 n
+0000446792 00000 n
+0000446857 00000 n
+0000446922 00000 n
+0000446987 00000 n
+0000447051 00000 n
+0000447116 00000 n
+0000447180 00000 n
+0000447244 00000 n
+0000447308 00000 n
+0000447371 00000 n
+0000447436 00000 n
+0000447500 00000 n
+0000447565 00000 n
+0000447630 00000 n
+0000447693 00000 n
+0000447758 00000 n
+0000447823 00000 n
+0000447888 00000 n
+0000447953 00000 n
+0000448018 00000 n
+0000448083 00000 n
+0000448148 00000 n
+0000450915 00000 n
+0000454312 00000 n
+0000450742 00000 n
+0000448429 00000 n
+0000451073 00000 n
+0000451137 00000 n
+0000451201 00000 n
+0000451266 00000 n
+0000451331 00000 n
+0000451396 00000 n
+0000451461 00000 n
+0000451526 00000 n
+0000451591 00000 n
+0000451656 00000 n
+0000451721 00000 n
+0000451785 00000 n
+0000451850 00000 n
+0000451915 00000 n
+0000451980 00000 n
+0000452045 00000 n
+0000452110 00000 n
+0000452175 00000 n
+0000452240 00000 n
+0000452305 00000 n
+0000452369 00000 n
+0000452434 00000 n
+0000452499 00000 n
+0000452564 00000 n
+0000452629 00000 n
+0000452694 00000 n
+0000452759 00000 n
+0000452824 00000 n
+0000452889 00000 n
+0000452954 00000 n
+0000453019 00000 n
+0000453084 00000 n
+0000453149 00000 n
+0000453214 00000 n
+0000453278 00000 n
+0000453343 00000 n
+0000453470 00000 n
+0000453535 00000 n
+0000453600 00000 n
+0000453664 00000 n
+0000453729 00000 n
+0000453794 00000 n
+0000453859 00000 n
+0000453924 00000 n
+0000453989 00000 n
+0000454054 00000 n
+0000454119 00000 n
+0000454184 00000 n
+0000454249 00000 n
+0000848053 00000 n
+0000450884 00000 n
+0000460450 00000 n
+0000457147 00000 n
+0000454541 00000 n
+0000457272 00000 n
+0000457336 00000 n
+0000457401 00000 n
+0000457465 00000 n
+0000457530 00000 n
+0000457595 00000 n
+0000457660 00000 n
+0000457725 00000 n
+0000457790 00000 n
+0000457855 00000 n
+0000457920 00000 n
+0000457984 00000 n
+0000458049 00000 n
+0000458114 00000 n
+0000458179 00000 n
+0000458244 00000 n
+0000458309 00000 n
+0000458374 00000 n
+0000458439 00000 n
+0000458504 00000 n
+0000458568 00000 n
+0000458633 00000 n
+0000458698 00000 n
+0000458763 00000 n
+0000458828 00000 n
+0000458893 00000 n
+0000458958 00000 n
+0000459023 00000 n
+0000459088 00000 n
+0000459152 00000 n
+0000459217 00000 n
+0000459282 00000 n
+0000459347 00000 n
+0000459412 00000 n
+0000459477 00000 n
+0000459542 00000 n
+0000459607 00000 n
+0000459672 00000 n
+0000459737 00000 n
+0000459802 00000 n
+0000459867 00000 n
+0000459931 00000 n
+0000459996 00000 n
+0000460061 00000 n
+0000460126 00000 n
+0000460191 00000 n
+0000460256 00000 n
+0000460321 00000 n
+0000460385 00000 n
+0000466247 00000 n
+0000462494 00000 n
+0000460653 00000 n
+0000462619 00000 n
+0000462683 00000 n
+0000462747 00000 n
+0000462812 00000 n
+0000462877 00000 n
+0000462942 00000 n
+0000463007 00000 n
+0000463071 00000 n
+0000463136 00000 n
+0000463201 00000 n
+0000463266 00000 n
+0000463331 00000 n
+0000463396 00000 n
+0000463461 00000 n
+0000463526 00000 n
+0000463590 00000 n
+0000463655 00000 n
+0000463720 00000 n
+0000463785 00000 n
+0000463850 00000 n
+0000463914 00000 n
+0000463979 00000 n
+0000464044 00000 n
+0000464109 00000 n
+0000464174 00000 n
+0000464239 00000 n
+0000464304 00000 n
+0000464369 00000 n
+0000464433 00000 n
+0000464498 00000 n
+0000464563 00000 n
+0000464628 00000 n
+0000464693 00000 n
+0000464758 00000 n
+0000464823 00000 n
+0000464888 00000 n
+0000464953 00000 n
+0000465016 00000 n
+0000465081 00000 n
+0000465146 00000 n
+0000465211 00000 n
+0000465276 00000 n
+0000465341 00000 n
+0000465406 00000 n
+0000465471 00000 n
+0000465536 00000 n
+0000465600 00000 n
+0000465665 00000 n
+0000465730 00000 n
+0000465795 00000 n
+0000465860 00000 n
+0000465925 00000 n
+0000465990 00000 n
+0000466055 00000 n
+0000466120 00000 n
+0000466183 00000 n
+0000468848 00000 n
+0000472441 00000 n
+0000468675 00000 n
+0000466424 00000 n
+0000469006 00000 n
+0000469070 00000 n
+0000469135 00000 n
+0000469199 00000 n
+0000469264 00000 n
+0000469328 00000 n
+0000469393 00000 n
+0000469458 00000 n
+0000469523 00000 n
+0000469588 00000 n
+0000469653 00000 n
+0000469718 00000 n
+0000469783 00000 n
+0000469848 00000 n
+0000469912 00000 n
+0000469977 00000 n
+0000470042 00000 n
+0000470107 00000 n
+0000470172 00000 n
+0000470237 00000 n
+0000470302 00000 n
+0000470367 00000 n
+0000470432 00000 n
+0000470497 00000 n
+0000470562 00000 n
+0000470627 00000 n
+0000470692 00000 n
+0000470757 00000 n
+0000470822 00000 n
+0000470886 00000 n
+0000470951 00000 n
+0000471016 00000 n
+0000471144 00000 n
+0000471209 00000 n
+0000471274 00000 n
+0000471339 00000 n
+0000471404 00000 n
+0000471469 00000 n
+0000471534 00000 n
+0000471598 00000 n
+0000471663 00000 n
+0000471728 00000 n
+0000471793 00000 n
+0000471858 00000 n
+0000471923 00000 n
+0000471988 00000 n
+0000472053 00000 n
+0000472118 00000 n
+0000472182 00000 n
+0000472247 00000 n
+0000472312 00000 n
+0000472377 00000 n
+0000468817 00000 n
+0000479087 00000 n
+0000474811 00000 n
+0000472670 00000 n
+0000474936 00000 n
+0000475000 00000 n
+0000475065 00000 n
+0000475129 00000 n
+0000475194 00000 n
+0000475259 00000 n
+0000475324 00000 n
+0000475389 00000 n
+0000475454 00000 n
+0000475519 00000 n
+0000475584 00000 n
+0000475649 00000 n
+0000475713 00000 n
+0000475778 00000 n
+0000475843 00000 n
+0000475908 00000 n
+0000475973 00000 n
+0000476038 00000 n
+0000476103 00000 n
+0000476168 00000 n
+0000476233 00000 n
+0000476297 00000 n
+0000476362 00000 n
+0000476427 00000 n
+0000476492 00000 n
+0000476557 00000 n
+0000476622 00000 n
+0000476687 00000 n
+0000476752 00000 n
+0000476817 00000 n
+0000476881 00000 n
+0000476946 00000 n
+0000477011 00000 n
+0000477076 00000 n
+0000477141 00000 n
+0000477206 00000 n
+0000477271 00000 n
+0000477336 00000 n
+0000477401 00000 n
+0000477465 00000 n
+0000477530 00000 n
+0000477595 00000 n
+0000477660 00000 n
+0000477725 00000 n
+0000477790 00000 n
+0000477855 00000 n
+0000477920 00000 n
+0000477985 00000 n
+0000478049 00000 n
+0000478114 00000 n
+0000478179 00000 n
+0000478244 00000 n
+0000478309 00000 n
+0000478374 00000 n
+0000478439 00000 n
+0000478504 00000 n
+0000478569 00000 n
+0000478633 00000 n
+0000478698 00000 n
+0000478763 00000 n
+0000478828 00000 n
+0000478893 00000 n
+0000478958 00000 n
+0000479023 00000 n
+0000485286 00000 n
+0000481790 00000 n
0000479238 00000 n
-0000479303 00000 n
-0000479368 00000 n
-0000479433 00000 n
-0000479498 00000 n
-0000479562 00000 n
-0000479627 00000 n
-0000479692 00000 n
-0000479757 00000 n
-0000479822 00000 n
-0000479887 00000 n
-0000479952 00000 n
-0000480016 00000 n
-0000480081 00000 n
-0000480146 00000 n
-0000480211 00000 n
-0000480276 00000 n
-0000480341 00000 n
-0000480406 00000 n
-0000480471 00000 n
-0000480536 00000 n
-0000480600 00000 n
-0000480665 00000 n
-0000480730 00000 n
-0000480795 00000 n
-0000480859 00000 n
-0000480924 00000 n
-0000480989 00000 n
-0000481054 00000 n
-0000481119 00000 n
-0000481184 00000 n
-0000481249 00000 n
-0000481314 00000 n
-0000481379 00000 n
-0000481444 00000 n
-0000481509 00000 n
-0000481574 00000 n
-0000481639 00000 n
-0000481704 00000 n
-0000481769 00000 n
-0000481834 00000 n
-0000481898 00000 n
-0000481963 00000 n
-0000482028 00000 n
-0000482092 00000 n
-0000487410 00000 n
-0000484824 00000 n
-0000482320 00000 n
-0000484949 00000 n
-0000485013 00000 n
-0000485078 00000 n
-0000485142 00000 n
-0000485207 00000 n
-0000485272 00000 n
-0000485400 00000 n
-0000485465 00000 n
-0000485530 00000 n
-0000485595 00000 n
-0000485660 00000 n
-0000485725 00000 n
-0000485789 00000 n
-0000485854 00000 n
-0000485919 00000 n
-0000486047 00000 n
-0000486112 00000 n
-0000486177 00000 n
-0000486242 00000 n
-0000486307 00000 n
-0000486372 00000 n
-0000486436 00000 n
-0000486501 00000 n
-0000486566 00000 n
-0000486631 00000 n
-0000486696 00000 n
-0000486761 00000 n
-0000486826 00000 n
-0000486890 00000 n
-0000486955 00000 n
-0000487020 00000 n
-0000487085 00000 n
-0000487150 00000 n
-0000487215 00000 n
-0000487280 00000 n
-0000487345 00000 n
-0000493345 00000 n
-0000490110 00000 n
-0000487613 00000 n
-0000490235 00000 n
-0000490299 00000 n
-0000490364 00000 n
-0000490429 00000 n
-0000490494 00000 n
-0000490559 00000 n
-0000490624 00000 n
-0000490689 00000 n
-0000490754 00000 n
-0000490819 00000 n
-0000490884 00000 n
-0000490948 00000 n
-0000491013 00000 n
-0000491078 00000 n
-0000491143 00000 n
-0000491208 00000 n
-0000491272 00000 n
-0000491337 00000 n
-0000491402 00000 n
-0000491467 00000 n
-0000491532 00000 n
-0000491597 00000 n
-0000491662 00000 n
-0000491727 00000 n
-0000491792 00000 n
-0000491855 00000 n
-0000491920 00000 n
-0000491985 00000 n
-0000492050 00000 n
-0000492115 00000 n
-0000492180 00000 n
-0000492245 00000 n
-0000492310 00000 n
-0000492375 00000 n
-0000492440 00000 n
-0000492504 00000 n
-0000492569 00000 n
-0000492634 00000 n
-0000492699 00000 n
-0000492764 00000 n
-0000492829 00000 n
-0000492894 00000 n
-0000492959 00000 n
-0000493024 00000 n
-0000493089 00000 n
-0000493154 00000 n
-0000493219 00000 n
-0000493283 00000 n
-0000498981 00000 n
-0000496073 00000 n
-0000493535 00000 n
-0000496198 00000 n
-0000496262 00000 n
-0000496327 00000 n
-0000496392 00000 n
-0000496457 00000 n
-0000496521 00000 n
-0000496586 00000 n
-0000496651 00000 n
-0000496716 00000 n
-0000496781 00000 n
-0000496846 00000 n
-0000496911 00000 n
-0000496976 00000 n
-0000497040 00000 n
-0000497105 00000 n
-0000497170 00000 n
-0000497235 00000 n
-0000497300 00000 n
-0000497365 00000 n
-0000497430 00000 n
-0000497495 00000 n
-0000497560 00000 n
-0000497625 00000 n
-0000497689 00000 n
-0000497754 00000 n
-0000497881 00000 n
-0000497944 00000 n
-0000498009 00000 n
-0000498074 00000 n
-0000498139 00000 n
-0000498204 00000 n
-0000498269 00000 n
-0000498334 00000 n
-0000498399 00000 n
-0000498464 00000 n
-0000498529 00000 n
-0000498593 00000 n
-0000498658 00000 n
-0000498723 00000 n
-0000498788 00000 n
-0000498853 00000 n
-0000498918 00000 n
-0000504910 00000 n
-0000501415 00000 n
-0000499171 00000 n
-0000501540 00000 n
-0000501604 00000 n
-0000501669 00000 n
-0000501733 00000 n
-0000501798 00000 n
-0000501863 00000 n
-0000501928 00000 n
-0000501993 00000 n
-0000502058 00000 n
-0000502123 00000 n
-0000502188 00000 n
-0000502253 00000 n
-0000502318 00000 n
-0000502383 00000 n
-0000502448 00000 n
-0000502512 00000 n
-0000502577 00000 n
-0000502642 00000 n
-0000502707 00000 n
-0000502772 00000 n
-0000502837 00000 n
-0000502902 00000 n
-0000502967 00000 n
-0000503032 00000 n
-0000503096 00000 n
-0000503161 00000 n
-0000503226 00000 n
-0000503291 00000 n
-0000503356 00000 n
-0000503421 00000 n
-0000503486 00000 n
-0000503551 00000 n
-0000503616 00000 n
-0000503680 00000 n
-0000503745 00000 n
-0000503810 00000 n
-0000503875 00000 n
-0000503940 00000 n
-0000504005 00000 n
-0000504070 00000 n
-0000504135 00000 n
-0000504200 00000 n
-0000504327 00000 n
-0000504392 00000 n
-0000504457 00000 n
-0000504522 00000 n
-0000504587 00000 n
-0000504652 00000 n
-0000504717 00000 n
-0000504782 00000 n
-0000504846 00000 n
-0000510778 00000 n
-0000507737 00000 n
-0000505100 00000 n
-0000507862 00000 n
-0000507926 00000 n
-0000507991 00000 n
-0000508055 00000 n
-0000508120 00000 n
-0000508185 00000 n
-0000508249 00000 n
-0000508314 00000 n
-0000508379 00000 n
-0000508444 00000 n
-0000508508 00000 n
-0000508573 00000 n
-0000508638 00000 n
-0000508703 00000 n
-0000508768 00000 n
-0000508833 00000 n
-0000508898 00000 n
-0000508963 00000 n
-0000509028 00000 n
-0000509093 00000 n
-0000509158 00000 n
-0000509223 00000 n
-0000509288 00000 n
-0000509352 00000 n
-0000509417 00000 n
-0000509482 00000 n
-0000509547 00000 n
-0000509612 00000 n
-0000509677 00000 n
-0000509742 00000 n
-0000509807 00000 n
-0000509872 00000 n
-0000509936 00000 n
-0000510001 00000 n
-0000510066 00000 n
-0000510131 00000 n
-0000510196 00000 n
-0000510260 00000 n
-0000510325 00000 n
-0000510390 00000 n
-0000510455 00000 n
-0000510520 00000 n
-0000510585 00000 n
-0000510650 00000 n
-0000510714 00000 n
-0000517230 00000 n
-0000513475 00000 n
-0000510981 00000 n
-0000513600 00000 n
-0000513664 00000 n
-0000513729 00000 n
-0000513793 00000 n
-0000513858 00000 n
-0000513923 00000 n
-0000513988 00000 n
-0000514053 00000 n
-0000514118 00000 n
-0000514183 00000 n
-0000514248 00000 n
-0000514313 00000 n
-0000514377 00000 n
-0000514442 00000 n
-0000514507 00000 n
-0000514572 00000 n
-0000514637 00000 n
-0000514702 00000 n
-0000514767 00000 n
-0000514832 00000 n
-0000514897 00000 n
-0000514962 00000 n
-0000515027 00000 n
-0000515092 00000 n
-0000515157 00000 n
-0000515222 00000 n
-0000515287 00000 n
-0000515352 00000 n
-0000515417 00000 n
-0000515482 00000 n
-0000515545 00000 n
-0000515610 00000 n
-0000515675 00000 n
-0000515740 00000 n
-0000515805 00000 n
-0000515870 00000 n
-0000515935 00000 n
-0000516000 00000 n
-0000516065 00000 n
-0000516130 00000 n
-0000516195 00000 n
-0000516260 00000 n
-0000516324 00000 n
-0000516389 00000 n
-0000516454 00000 n
-0000516519 00000 n
-0000516583 00000 n
-0000516648 00000 n
-0000516713 00000 n
-0000516778 00000 n
-0000516843 00000 n
-0000516908 00000 n
-0000516973 00000 n
-0000517038 00000 n
-0000517102 00000 n
-0000517166 00000 n
-0000845017 00000 n
-0000523770 00000 n
-0000520145 00000 n
-0000517420 00000 n
-0000520270 00000 n
+0000481915 00000 n
+0000481979 00000 n
+0000482044 00000 n
+0000482108 00000 n
+0000482173 00000 n
+0000482238 00000 n
+0000482303 00000 n
+0000482368 00000 n
+0000482433 00000 n
+0000482498 00000 n
+0000482563 00000 n
+0000482628 00000 n
+0000482692 00000 n
+0000482757 00000 n
+0000482822 00000 n
+0000482887 00000 n
+0000482952 00000 n
+0000483017 00000 n
+0000483082 00000 n
+0000483146 00000 n
+0000483211 00000 n
+0000483276 00000 n
+0000483341 00000 n
+0000483406 00000 n
+0000483471 00000 n
+0000483536 00000 n
+0000483601 00000 n
+0000483666 00000 n
+0000483730 00000 n
+0000483795 00000 n
+0000483860 00000 n
+0000483925 00000 n
+0000483989 00000 n
+0000484054 00000 n
+0000484119 00000 n
+0000484184 00000 n
+0000484249 00000 n
+0000484314 00000 n
+0000484379 00000 n
+0000484444 00000 n
+0000484509 00000 n
+0000484574 00000 n
+0000484639 00000 n
+0000484704 00000 n
+0000484769 00000 n
+0000484834 00000 n
+0000484899 00000 n
+0000484964 00000 n
+0000485028 00000 n
+0000485093 00000 n
+0000485158 00000 n
+0000485222 00000 n
+0000490541 00000 n
+0000487955 00000 n
+0000485450 00000 n
+0000488080 00000 n
+0000488144 00000 n
+0000488209 00000 n
+0000488273 00000 n
+0000488338 00000 n
+0000488403 00000 n
+0000488531 00000 n
+0000488596 00000 n
+0000488661 00000 n
+0000488726 00000 n
+0000488791 00000 n
+0000488856 00000 n
+0000488920 00000 n
+0000488985 00000 n
+0000489050 00000 n
+0000489178 00000 n
+0000489243 00000 n
+0000489308 00000 n
+0000489373 00000 n
+0000489438 00000 n
+0000489503 00000 n
+0000489567 00000 n
+0000489632 00000 n
+0000489697 00000 n
+0000489762 00000 n
+0000489827 00000 n
+0000489892 00000 n
+0000489957 00000 n
+0000490021 00000 n
+0000490086 00000 n
+0000490151 00000 n
+0000490216 00000 n
+0000490281 00000 n
+0000490346 00000 n
+0000490411 00000 n
+0000490476 00000 n
+0000496473 00000 n
+0000493238 00000 n
+0000490744 00000 n
+0000493363 00000 n
+0000493427 00000 n
+0000493492 00000 n
+0000493557 00000 n
+0000493622 00000 n
+0000493687 00000 n
+0000493752 00000 n
+0000493817 00000 n
+0000493882 00000 n
+0000493947 00000 n
+0000494012 00000 n
+0000494076 00000 n
+0000494141 00000 n
+0000494206 00000 n
+0000494271 00000 n
+0000494336 00000 n
+0000494400 00000 n
+0000494465 00000 n
+0000494530 00000 n
+0000494595 00000 n
+0000494660 00000 n
+0000494725 00000 n
+0000494790 00000 n
+0000494855 00000 n
+0000494920 00000 n
+0000494983 00000 n
+0000495048 00000 n
+0000495113 00000 n
+0000495178 00000 n
+0000495243 00000 n
+0000495308 00000 n
+0000495373 00000 n
+0000495438 00000 n
+0000495503 00000 n
+0000495568 00000 n
+0000495632 00000 n
+0000495697 00000 n
+0000495762 00000 n
+0000495827 00000 n
+0000495892 00000 n
+0000495957 00000 n
+0000496022 00000 n
+0000496087 00000 n
+0000496152 00000 n
+0000496217 00000 n
+0000496282 00000 n
+0000496347 00000 n
+0000496411 00000 n
+0000502101 00000 n
+0000499193 00000 n
+0000496663 00000 n
+0000499318 00000 n
+0000499382 00000 n
+0000499447 00000 n
+0000499512 00000 n
+0000499577 00000 n
+0000499641 00000 n
+0000499706 00000 n
+0000499771 00000 n
+0000499836 00000 n
+0000499901 00000 n
+0000499966 00000 n
+0000500031 00000 n
+0000500096 00000 n
+0000500160 00000 n
+0000500225 00000 n
+0000500290 00000 n
+0000500355 00000 n
+0000500420 00000 n
+0000500485 00000 n
+0000500550 00000 n
+0000500615 00000 n
+0000500680 00000 n
+0000500745 00000 n
+0000500809 00000 n
+0000500874 00000 n
+0000501001 00000 n
+0000501064 00000 n
+0000501129 00000 n
+0000501194 00000 n
+0000501259 00000 n
+0000501324 00000 n
+0000501389 00000 n
+0000501454 00000 n
+0000501519 00000 n
+0000501584 00000 n
+0000501649 00000 n
+0000501713 00000 n
+0000501778 00000 n
+0000501843 00000 n
+0000501908 00000 n
+0000501973 00000 n
+0000502038 00000 n
+0000508030 00000 n
+0000504535 00000 n
+0000502291 00000 n
+0000504660 00000 n
+0000504724 00000 n
+0000504789 00000 n
+0000504853 00000 n
+0000504918 00000 n
+0000504983 00000 n
+0000505048 00000 n
+0000505113 00000 n
+0000505178 00000 n
+0000505243 00000 n
+0000505308 00000 n
+0000505373 00000 n
+0000505438 00000 n
+0000505503 00000 n
+0000505568 00000 n
+0000505632 00000 n
+0000505697 00000 n
+0000505762 00000 n
+0000505827 00000 n
+0000505892 00000 n
+0000505957 00000 n
+0000506022 00000 n
+0000506087 00000 n
+0000506152 00000 n
+0000506216 00000 n
+0000506281 00000 n
+0000506346 00000 n
+0000506411 00000 n
+0000506476 00000 n
+0000506541 00000 n
+0000506606 00000 n
+0000506671 00000 n
+0000506736 00000 n
+0000506800 00000 n
+0000506865 00000 n
+0000506930 00000 n
+0000506995 00000 n
+0000507060 00000 n
+0000507125 00000 n
+0000507190 00000 n
+0000507255 00000 n
+0000507320 00000 n
+0000507447 00000 n
+0000507512 00000 n
+0000507577 00000 n
+0000507642 00000 n
+0000507707 00000 n
+0000507772 00000 n
+0000507837 00000 n
+0000507902 00000 n
+0000507966 00000 n
+0000513898 00000 n
+0000510857 00000 n
+0000508220 00000 n
+0000510982 00000 n
+0000511046 00000 n
+0000511111 00000 n
+0000511175 00000 n
+0000511240 00000 n
+0000511305 00000 n
+0000511369 00000 n
+0000511434 00000 n
+0000511499 00000 n
+0000511564 00000 n
+0000511628 00000 n
+0000511693 00000 n
+0000511758 00000 n
+0000511823 00000 n
+0000511888 00000 n
+0000511953 00000 n
+0000512018 00000 n
+0000512083 00000 n
+0000512148 00000 n
+0000512213 00000 n
+0000512278 00000 n
+0000512343 00000 n
+0000512408 00000 n
+0000512472 00000 n
+0000512537 00000 n
+0000512602 00000 n
+0000512667 00000 n
+0000512732 00000 n
+0000512797 00000 n
+0000512862 00000 n
+0000512927 00000 n
+0000512992 00000 n
+0000513056 00000 n
+0000513121 00000 n
+0000513186 00000 n
+0000513251 00000 n
+0000513316 00000 n
+0000513380 00000 n
+0000513445 00000 n
+0000513510 00000 n
+0000513575 00000 n
+0000513640 00000 n
+0000513705 00000 n
+0000513770 00000 n
+0000513834 00000 n
+0000848217 00000 n
0000520334 00000 n
-0000520399 00000 n
-0000520464 00000 n
-0000520528 00000 n
-0000520593 00000 n
-0000520658 00000 n
-0000520723 00000 n
-0000520788 00000 n
-0000520853 00000 n
-0000520917 00000 n
-0000520982 00000 n
-0000521047 00000 n
-0000521112 00000 n
-0000521177 00000 n
-0000521242 00000 n
-0000521307 00000 n
-0000521372 00000 n
-0000521437 00000 n
-0000521500 00000 n
-0000521565 00000 n
-0000521630 00000 n
-0000521695 00000 n
-0000521760 00000 n
-0000521825 00000 n
-0000521890 00000 n
-0000521955 00000 n
-0000522020 00000 n
-0000522085 00000 n
-0000522150 00000 n
-0000522215 00000 n
-0000522280 00000 n
-0000522345 00000 n
-0000522410 00000 n
-0000522475 00000 n
-0000522540 00000 n
-0000522605 00000 n
-0000522669 00000 n
-0000522734 00000 n
-0000522799 00000 n
-0000522864 00000 n
-0000522929 00000 n
-0000522994 00000 n
-0000523059 00000 n
-0000523124 00000 n
-0000523188 00000 n
-0000523253 00000 n
-0000523318 00000 n
-0000523383 00000 n
-0000523447 00000 n
-0000523512 00000 n
-0000523577 00000 n
-0000523642 00000 n
-0000523706 00000 n
-0000530182 00000 n
-0000526167 00000 n
-0000523973 00000 n
-0000526292 00000 n
-0000526356 00000 n
-0000526421 00000 n
-0000526485 00000 n
-0000526550 00000 n
-0000526615 00000 n
-0000526680 00000 n
-0000526745 00000 n
-0000526810 00000 n
+0000516579 00000 n
+0000514101 00000 n
+0000516704 00000 n
+0000516768 00000 n
+0000516833 00000 n
+0000516897 00000 n
+0000516962 00000 n
+0000517027 00000 n
+0000517092 00000 n
+0000517157 00000 n
+0000517222 00000 n
+0000517287 00000 n
+0000517352 00000 n
+0000517417 00000 n
+0000517481 00000 n
+0000517546 00000 n
+0000517611 00000 n
+0000517676 00000 n
+0000517741 00000 n
+0000517806 00000 n
+0000517871 00000 n
+0000517936 00000 n
+0000518001 00000 n
+0000518066 00000 n
+0000518131 00000 n
+0000518196 00000 n
+0000518261 00000 n
+0000518326 00000 n
+0000518391 00000 n
+0000518456 00000 n
+0000518521 00000 n
+0000518586 00000 n
+0000518649 00000 n
+0000518714 00000 n
+0000518779 00000 n
+0000518844 00000 n
+0000518909 00000 n
+0000518974 00000 n
+0000519039 00000 n
+0000519104 00000 n
+0000519169 00000 n
+0000519234 00000 n
+0000519299 00000 n
+0000519364 00000 n
+0000519428 00000 n
+0000519493 00000 n
+0000519558 00000 n
+0000519623 00000 n
+0000519687 00000 n
+0000519752 00000 n
+0000519817 00000 n
+0000519882 00000 n
+0000519947 00000 n
+0000520012 00000 n
+0000520077 00000 n
+0000520142 00000 n
+0000520206 00000 n
+0000520270 00000 n
0000526875 00000 n
-0000526940 00000 n
-0000527005 00000 n
-0000527069 00000 n
-0000527134 00000 n
-0000527199 00000 n
-0000527264 00000 n
-0000527329 00000 n
-0000527394 00000 n
-0000527459 00000 n
-0000527523 00000 n
-0000527588 00000 n
-0000527653 00000 n
-0000527718 00000 n
-0000527783 00000 n
-0000527848 00000 n
-0000527913 00000 n
-0000527978 00000 n
-0000528043 00000 n
-0000528106 00000 n
-0000528171 00000 n
-0000528236 00000 n
-0000528301 00000 n
-0000528366 00000 n
-0000528431 00000 n
-0000528496 00000 n
-0000528561 00000 n
-0000528626 00000 n
-0000528691 00000 n
-0000528756 00000 n
-0000528821 00000 n
-0000528886 00000 n
-0000528951 00000 n
-0000529016 00000 n
-0000529081 00000 n
-0000529146 00000 n
-0000529211 00000 n
-0000529276 00000 n
-0000529340 00000 n
-0000529405 00000 n
-0000529470 00000 n
-0000529535 00000 n
-0000529600 00000 n
-0000529665 00000 n
-0000529730 00000 n
-0000529795 00000 n
-0000529860 00000 n
-0000529924 00000 n
-0000529989 00000 n
-0000530054 00000 n
-0000530118 00000 n
-0000536467 00000 n
-0000532387 00000 n
-0000530346 00000 n
-0000532512 00000 n
-0000532576 00000 n
-0000532641 00000 n
-0000532705 00000 n
-0000532770 00000 n
-0000532835 00000 n
-0000532900 00000 n
-0000532965 00000 n
-0000533030 00000 n
-0000533095 00000 n
-0000533160 00000 n
-0000533225 00000 n
-0000533290 00000 n
-0000533355 00000 n
-0000533420 00000 n
-0000533484 00000 n
-0000533549 00000 n
-0000533614 00000 n
-0000533679 00000 n
-0000533744 00000 n
-0000533809 00000 n
-0000533874 00000 n
-0000533939 00000 n
-0000534004 00000 n
-0000534069 00000 n
-0000534134 00000 n
-0000534199 00000 n
-0000534264 00000 n
-0000534329 00000 n
-0000534394 00000 n
-0000534459 00000 n
-0000534524 00000 n
-0000534589 00000 n
-0000534654 00000 n
-0000534717 00000 n
-0000534782 00000 n
-0000534847 00000 n
-0000534912 00000 n
-0000534977 00000 n
-0000535042 00000 n
-0000535107 00000 n
-0000535172 00000 n
-0000535237 00000 n
-0000535301 00000 n
-0000535366 00000 n
-0000535431 00000 n
-0000535496 00000 n
-0000535561 00000 n
-0000535626 00000 n
-0000535690 00000 n
-0000535755 00000 n
-0000535820 00000 n
-0000535885 00000 n
-0000535950 00000 n
-0000536015 00000 n
-0000536080 00000 n
-0000536145 00000 n
-0000536210 00000 n
-0000536274 00000 n
-0000536339 00000 n
-0000536403 00000 n
-0000542550 00000 n
-0000538666 00000 n
-0000536631 00000 n
+0000523250 00000 n
+0000520524 00000 n
+0000523375 00000 n
+0000523439 00000 n
+0000523504 00000 n
+0000523569 00000 n
+0000523633 00000 n
+0000523698 00000 n
+0000523763 00000 n
+0000523828 00000 n
+0000523893 00000 n
+0000523958 00000 n
+0000524022 00000 n
+0000524087 00000 n
+0000524152 00000 n
+0000524217 00000 n
+0000524282 00000 n
+0000524347 00000 n
+0000524412 00000 n
+0000524477 00000 n
+0000524542 00000 n
+0000524605 00000 n
+0000524670 00000 n
+0000524735 00000 n
+0000524800 00000 n
+0000524865 00000 n
+0000524930 00000 n
+0000524995 00000 n
+0000525060 00000 n
+0000525125 00000 n
+0000525190 00000 n
+0000525255 00000 n
+0000525320 00000 n
+0000525385 00000 n
+0000525450 00000 n
+0000525515 00000 n
+0000525580 00000 n
+0000525645 00000 n
+0000525710 00000 n
+0000525774 00000 n
+0000525839 00000 n
+0000525904 00000 n
+0000525969 00000 n
+0000526034 00000 n
+0000526099 00000 n
+0000526164 00000 n
+0000526229 00000 n
+0000526293 00000 n
+0000526358 00000 n
+0000526423 00000 n
+0000526488 00000 n
+0000526552 00000 n
+0000526617 00000 n
+0000526682 00000 n
+0000526747 00000 n
+0000526811 00000 n
+0000533292 00000 n
+0000529277 00000 n
+0000527078 00000 n
+0000529402 00000 n
+0000529466 00000 n
+0000529531 00000 n
+0000529595 00000 n
+0000529660 00000 n
+0000529725 00000 n
+0000529790 00000 n
+0000529855 00000 n
+0000529920 00000 n
+0000529985 00000 n
+0000530050 00000 n
+0000530115 00000 n
+0000530179 00000 n
+0000530244 00000 n
+0000530309 00000 n
+0000530374 00000 n
+0000530439 00000 n
+0000530504 00000 n
+0000530569 00000 n
+0000530633 00000 n
+0000530698 00000 n
+0000530763 00000 n
+0000530828 00000 n
+0000530893 00000 n
+0000530958 00000 n
+0000531023 00000 n
+0000531088 00000 n
+0000531153 00000 n
+0000531216 00000 n
+0000531281 00000 n
+0000531346 00000 n
+0000531411 00000 n
+0000531476 00000 n
+0000531541 00000 n
+0000531606 00000 n
+0000531671 00000 n
+0000531736 00000 n
+0000531801 00000 n
+0000531866 00000 n
+0000531931 00000 n
+0000531996 00000 n
+0000532061 00000 n
+0000532126 00000 n
+0000532191 00000 n
+0000532256 00000 n
+0000532321 00000 n
+0000532386 00000 n
+0000532450 00000 n
+0000532515 00000 n
+0000532580 00000 n
+0000532645 00000 n
+0000532710 00000 n
+0000532775 00000 n
+0000532840 00000 n
+0000532905 00000 n
+0000532970 00000 n
+0000533034 00000 n
+0000533099 00000 n
+0000533164 00000 n
+0000533228 00000 n
+0000539568 00000 n
+0000535488 00000 n
+0000533456 00000 n
+0000535613 00000 n
+0000535677 00000 n
+0000535742 00000 n
+0000535806 00000 n
+0000535871 00000 n
+0000535936 00000 n
+0000536001 00000 n
+0000536066 00000 n
+0000536131 00000 n
+0000536196 00000 n
+0000536261 00000 n
+0000536326 00000 n
+0000536391 00000 n
+0000536456 00000 n
+0000536521 00000 n
+0000536585 00000 n
+0000536650 00000 n
+0000536715 00000 n
+0000536780 00000 n
+0000536845 00000 n
+0000536910 00000 n
+0000536975 00000 n
+0000537040 00000 n
+0000537105 00000 n
+0000537170 00000 n
+0000537235 00000 n
+0000537300 00000 n
+0000537365 00000 n
+0000537430 00000 n
+0000537495 00000 n
+0000537560 00000 n
+0000537625 00000 n
+0000537690 00000 n
+0000537755 00000 n
+0000537818 00000 n
+0000537883 00000 n
+0000537948 00000 n
+0000538013 00000 n
+0000538078 00000 n
+0000538143 00000 n
+0000538208 00000 n
+0000538273 00000 n
+0000538338 00000 n
+0000538402 00000 n
+0000538467 00000 n
+0000538532 00000 n
+0000538597 00000 n
+0000538662 00000 n
+0000538727 00000 n
0000538791 00000 n
-0000538855 00000 n
-0000538920 00000 n
-0000538984 00000 n
-0000539049 00000 n
-0000539114 00000 n
-0000539179 00000 n
-0000539244 00000 n
-0000539309 00000 n
-0000539374 00000 n
-0000539439 00000 n
+0000538856 00000 n
+0000538921 00000 n
+0000538986 00000 n
+0000539051 00000 n
+0000539116 00000 n
+0000539181 00000 n
+0000539246 00000 n
+0000539311 00000 n
+0000539375 00000 n
+0000539440 00000 n
0000539504 00000 n
-0000539569 00000 n
-0000539634 00000 n
-0000539698 00000 n
-0000539763 00000 n
-0000539828 00000 n
-0000539893 00000 n
-0000539958 00000 n
-0000540023 00000 n
-0000540088 00000 n
-0000540153 00000 n
-0000540217 00000 n
-0000540282 00000 n
-0000540347 00000 n
-0000540412 00000 n
-0000540477 00000 n
-0000540542 00000 n
-0000540607 00000 n
-0000540672 00000 n
-0000540737 00000 n
-0000540801 00000 n
-0000540866 00000 n
-0000540931 00000 n
-0000540996 00000 n
-0000541061 00000 n
-0000541126 00000 n
-0000541191 00000 n
-0000541256 00000 n
-0000541321 00000 n
-0000541385 00000 n
-0000541450 00000 n
-0000541515 00000 n
-0000541580 00000 n
-0000541645 00000 n
-0000541710 00000 n
-0000541775 00000 n
-0000541840 00000 n
-0000541905 00000 n
-0000541969 00000 n
-0000542034 00000 n
-0000542099 00000 n
-0000542164 00000 n
-0000542229 00000 n
-0000542294 00000 n
-0000542359 00000 n
-0000542424 00000 n
-0000542488 00000 n
-0000545966 00000 n
-0000544683 00000 n
-0000542727 00000 n
-0000544808 00000 n
-0000544872 00000 n
-0000544937 00000 n
-0000545001 00000 n
-0000545066 00000 n
-0000545131 00000 n
-0000545196 00000 n
-0000545261 00000 n
-0000545326 00000 n
-0000545391 00000 n
-0000545456 00000 n
-0000545584 00000 n
-0000545648 00000 n
-0000545712 00000 n
-0000545776 00000 n
-0000545838 00000 n
-0000545902 00000 n
-0000549118 00000 n
-0000549274 00000 n
-0000557153 00000 n
-0000557309 00000 n
-0000557469 00000 n
-0000557629 00000 n
-0000550132 00000 n
-0000548936 00000 n
-0000546210 00000 n
-0000549429 00000 n
-0000549493 00000 n
-0000549557 00000 n
-0000549621 00000 n
-0000549685 00000 n
-0000549749 00000 n
-0000549813 00000 n
-0000549877 00000 n
-0000549941 00000 n
-0000550068 00000 n
-0000549078 00000 n
-0000557790 00000 n
-0000557950 00000 n
-0000558106 00000 n
-0000558266 00000 n
-0000558427 00000 n
-0000558594 00000 n
-0000558761 00000 n
-0000558928 00000 n
-0000559089 00000 n
-0000559245 00000 n
-0000559404 00000 n
-0000559571 00000 n
-0000559738 00000 n
-0000559899 00000 n
-0000560066 00000 n
-0000560233 00000 n
-0000560394 00000 n
-0000560555 00000 n
-0000560722 00000 n
-0000560889 00000 n
-0000561056 00000 n
-0000561223 00000 n
-0000561390 00000 n
-0000561550 00000 n
-0000561716 00000 n
-0000561883 00000 n
-0000562050 00000 n
-0000562208 00000 n
-0000562368 00000 n
-0000562524 00000 n
-0000562678 00000 n
-0000562838 00000 n
-0000562999 00000 n
-0000563159 00000 n
-0000563320 00000 n
-0000563480 00000 n
-0000563636 00000 n
-0000563797 00000 n
-0000563958 00000 n
-0000564119 00000 n
-0000564280 00000 n
-0000569204 00000 n
-0000569360 00000 n
-0000569520 00000 n
-0000569680 00000 n
-0000569847 00000 n
-0000570012 00000 n
-0000570178 00000 n
-0000570344 00000 n
-0000570511 00000 n
-0000564505 00000 n
-0000556584 00000 n
-0000550322 00000 n
-0000564441 00000 n
-0000556726 00000 n
-0000570678 00000 n
-0000570845 00000 n
-0000571011 00000 n
-0000571178 00000 n
-0000571345 00000 n
-0000571513 00000 n
-0000571680 00000 n
-0000571848 00000 n
-0000572016 00000 n
-0000572177 00000 n
-0000572344 00000 n
-0000572511 00000 n
-0000572678 00000 n
-0000572845 00000 n
-0000573012 00000 n
-0000573179 00000 n
-0000573346 00000 n
-0000573513 00000 n
-0000573680 00000 n
-0000573900 00000 n
-0000568788 00000 n
-0000564643 00000 n
-0000573836 00000 n
-0000568930 00000 n
-0000841022 00000 n
-0000574156 00000 n
-0000841284 00000 n
-0000574183 00000 n
-0000841150 00000 n
-0000574276 00000 n
-0000574515 00000 n
-0000574540 00000 n
-0000586525 00000 n
-0000574768 00000 n
-0000574871 00000 n
-0000586767 00000 n
-0000587491 00000 n
-0000587725 00000 n
-0000601157 00000 n
-0000588041 00000 n
-0000588144 00000 n
-0000601391 00000 n
-0000602137 00000 n
-0000602363 00000 n
-0000613397 00000 n
-0000602510 00000 n
-0000602608 00000 n
-0000613637 00000 n
-0000614315 00000 n
-0000614546 00000 n
-0000615657 00000 n
-0000614601 00000 n
-0000614698 00000 n
-0000615900 00000 n
-0000616510 00000 n
-0000616714 00000 n
-0000616741 00000 n
-0000616768 00000 n
-0000619143 00000 n
-0000616960 00000 n
-0000617066 00000 n
-0000619391 00000 n
-0000620074 00000 n
-0000620284 00000 n
-0000630259 00000 n
-0000620901 00000 n
-0000621031 00000 n
-0000630499 00000 n
-0000631592 00000 n
-0000631796 00000 n
-0000634122 00000 n
-0000631963 00000 n
-0000632069 00000 n
-0000634369 00000 n
-0000635042 00000 n
-0000635252 00000 n
-0000636937 00000 n
-0000635365 00000 n
-0000635471 00000 n
-0000637186 00000 n
-0000637839 00000 n
-0000638050 00000 n
-0000643574 00000 n
-0000638403 00000 n
-0000638514 00000 n
-0000643818 00000 n
-0000644594 00000 n
-0000644799 00000 n
-0000652373 00000 n
-0000645253 00000 n
-0000645368 00000 n
-0000652613 00000 n
-0000653498 00000 n
-0000653701 00000 n
-0000654451 00000 n
-0000653735 00000 n
-0000653830 00000 n
-0000654690 00000 n
-0000655286 00000 n
-0000655488 00000 n
-0000661881 00000 n
-0000655945 00000 n
-0000656053 00000 n
-0000662121 00000 n
-0000663006 00000 n
-0000663210 00000 n
-0000665814 00000 n
-0000663400 00000 n
-0000663506 00000 n
-0000666057 00000 n
-0000666729 00000 n
-0000666933 00000 n
-0000668953 00000 n
-0000667047 00000 n
-0000667151 00000 n
-0000669195 00000 n
-0000669840 00000 n
-0000670045 00000 n
-0000673098 00000 n
-0000670336 00000 n
-0000670443 00000 n
-0000673338 00000 n
-0000674074 00000 n
-0000674278 00000 n
-0000681846 00000 n
-0000674747 00000 n
-0000674862 00000 n
-0000682087 00000 n
-0000682970 00000 n
-0000683175 00000 n
-0000683202 00000 n
-0000683263 00000 n
-0000683456 00000 n
-0000683697 00000 n
-0000683914 00000 n
-0000688578 00000 n
-0000684269 00000 n
-0000684375 00000 n
-0000688820 00000 n
-0000689591 00000 n
-0000689795 00000 n
-0000692358 00000 n
-0000690018 00000 n
-0000690124 00000 n
-0000692598 00000 n
-0000693282 00000 n
-0000693486 00000 n
-0000702707 00000 n
-0000693973 00000 n
-0000694093 00000 n
-0000702948 00000 n
-0000703944 00000 n
-0000704149 00000 n
-0000706159 00000 n
-0000704263 00000 n
-0000704367 00000 n
-0000706401 00000 n
-0000707047 00000 n
-0000707252 00000 n
-0000709670 00000 n
-0000707488 00000 n
-0000707594 00000 n
-0000709911 00000 n
-0000710610 00000 n
-0000710815 00000 n
-0000720227 00000 n
-0000711391 00000 n
-0000711523 00000 n
-0000720469 00000 n
-0000721466 00000 n
-0000721672 00000 n
-0000728435 00000 n
-0000722100 00000 n
-0000722212 00000 n
-0000728675 00000 n
-0000729532 00000 n
-0000729735 00000 n
-0000730784 00000 n
-0000729813 00000 n
-0000729913 00000 n
-0000731024 00000 n
-0000731646 00000 n
-0000731850 00000 n
-0000737399 00000 n
-0000732224 00000 n
-0000732339 00000 n
-0000737640 00000 n
-0000738441 00000 n
-0000738646 00000 n
-0000740205 00000 n
-0000738739 00000 n
-0000738840 00000 n
-0000740444 00000 n
-0000741070 00000 n
-0000741272 00000 n
-0000743509 00000 n
-0000741451 00000 n
-0000741557 00000 n
-0000743750 00000 n
-0000744419 00000 n
-0000744624 00000 n
-0000747416 00000 n
-0000744833 00000 n
-0000744940 00000 n
-0000747658 00000 n
-0000748354 00000 n
-0000748560 00000 n
-0000748658 00000 n
-0000749702 00000 n
-0000748736 00000 n
-0000748836 00000 n
-0000749943 00000 n
-0000750567 00000 n
-0000750772 00000 n
-0000752575 00000 n
-0000750883 00000 n
-0000750986 00000 n
-0000752817 00000 n
-0000753460 00000 n
-0000760637 00000 n
-0000753666 00000 n
-0000764955 00000 n
-0000760870 00000 n
-0000768018 00000 n
-0000765244 00000 n
-0000771235 00000 n
-0000768257 00000 n
-0000773855 00000 n
-0000771479 00000 n
-0000797517 00000 n
-0000774100 00000 n
-0000816659 00000 n
-0000797824 00000 n
-0000828621 00000 n
-0000816931 00000 n
-0000831989 00000 n
-0000828871 00000 n
-0000834762 00000 n
-0000832262 00000 n
-0000837707 00000 n
-0000835014 00000 n
-0000840736 00000 n
-0000837953 00000 n
-0000845171 00000 n
-0000845315 00000 n
-0000852437 00000 n
-0000853102 00000 n
-0000853771 00000 n
-0000854440 00000 n
-0000855106 00000 n
-0000855775 00000 n
-0000856443 00000 n
-0000857114 00000 n
-0000857778 00000 n
-0000858447 00000 n
-0000859116 00000 n
-0000859782 00000 n
-0000860451 00000 n
-0000861120 00000 n
-0000861785 00000 n
-0000862456 00000 n
-0000863124 00000 n
-0000863793 00000 n
-0000864459 00000 n
-0000865128 00000 n
-0000865797 00000 n
-0000866463 00000 n
-0000867132 00000 n
-0000867800 00000 n
-0000868471 00000 n
-0000869136 00000 n
-0000869805 00000 n
-0000870474 00000 n
-0000871140 00000 n
-0000871809 00000 n
-0000872478 00000 n
-0000873147 00000 n
-0000873815 00000 n
-0000874483 00000 n
-0000875152 00000 n
-0000875814 00000 n
-0000876483 00000 n
-0000877152 00000 n
-0000877821 00000 n
-0000878486 00000 n
-0000879157 00000 n
-0000879825 00000 n
-0000880491 00000 n
-0000881160 00000 n
-0000881829 00000 n
-0000882498 00000 n
-0000883164 00000 n
-0000883833 00000 n
-0000884501 00000 n
-0000885169 00000 n
-0000885838 00000 n
-0000886507 00000 n
-0000887176 00000 n
-0000887842 00000 n
-0000888511 00000 n
-0000889180 00000 n
-0000889845 00000 n
-0000890516 00000 n
-0000891184 00000 n
-0000891853 00000 n
-0000892519 00000 n
-0000893188 00000 n
-0000893857 00000 n
-0000894523 00000 n
-0000895192 00000 n
-0000895860 00000 n
-0000896531 00000 n
-0000897195 00000 n
-0000897864 00000 n
-0000898533 00000 n
-0000899195 00000 n
-0000899864 00000 n
-0000900533 00000 n
-0000901199 00000 n
-0000901808 00000 n
-0000902429 00000 n
-0000903064 00000 n
-0000903696 00000 n
-0000904331 00000 n
-0000904966 00000 n
-0000905598 00000 n
-0000906232 00000 n
-0000906869 00000 n
-0000907503 00000 n
-0000908135 00000 n
-0000908770 00000 n
-0000909405 00000 n
-0000910037 00000 n
-0000910672 00000 n
-0000911307 00000 n
-0000911939 00000 n
-0000912573 00000 n
-0000913208 00000 n
-0000913843 00000 n
-0000914475 00000 n
-0000915110 00000 n
-0000915745 00000 n
-0000916402 00000 n
-0000917217 00000 n
-0000917900 00000 n
-0000918560 00000 n
-0000919231 00000 n
-0000919991 00000 n
-0000920783 00000 n
-0000921705 00000 n
-0000922822 00000 n
-0000923079 00000 n
-0000923435 00000 n
-0000923788 00000 n
-0000924141 00000 n
-0000924295 00000 n
-0000924398 00000 n
-0000924438 00000 n
-0000924570 00000 n
+0000545663 00000 n
+0000541779 00000 n
+0000539732 00000 n
+0000541904 00000 n
+0000541968 00000 n
+0000542033 00000 n
+0000542097 00000 n
+0000542162 00000 n
+0000542227 00000 n
+0000542292 00000 n
+0000542357 00000 n
+0000542422 00000 n
+0000542487 00000 n
+0000542552 00000 n
+0000542617 00000 n
+0000542682 00000 n
+0000542747 00000 n
+0000542811 00000 n
+0000542876 00000 n
+0000542941 00000 n
+0000543006 00000 n
+0000543071 00000 n
+0000543136 00000 n
+0000543201 00000 n
+0000543266 00000 n
+0000543330 00000 n
+0000543395 00000 n
+0000543460 00000 n
+0000543525 00000 n
+0000543590 00000 n
+0000543655 00000 n
+0000543720 00000 n
+0000543785 00000 n
+0000543850 00000 n
+0000543914 00000 n
+0000543979 00000 n
+0000544044 00000 n
+0000544109 00000 n
+0000544174 00000 n
+0000544239 00000 n
+0000544304 00000 n
+0000544369 00000 n
+0000544434 00000 n
+0000544498 00000 n
+0000544563 00000 n
+0000544628 00000 n
+0000544693 00000 n
+0000544758 00000 n
+0000544823 00000 n
+0000544888 00000 n
+0000544953 00000 n
+0000545018 00000 n
+0000545082 00000 n
+0000545147 00000 n
+0000545212 00000 n
+0000545277 00000 n
+0000545342 00000 n
+0000545407 00000 n
+0000545472 00000 n
+0000545537 00000 n
+0000545601 00000 n
+0000549354 00000 n
+0000548005 00000 n
+0000545840 00000 n
+0000548130 00000 n
+0000548194 00000 n
+0000548259 00000 n
+0000548323 00000 n
+0000548388 00000 n
+0000548453 00000 n
+0000548518 00000 n
+0000548583 00000 n
+0000548648 00000 n
+0000548713 00000 n
+0000548778 00000 n
+0000548906 00000 n
+0000548970 00000 n
+0000549034 00000 n
+0000549098 00000 n
+0000549162 00000 n
+0000549226 00000 n
+0000549290 00000 n
+0000552519 00000 n
+0000552675 00000 n
+0000560553 00000 n
+0000560709 00000 n
+0000560869 00000 n
+0000561029 00000 n
+0000553533 00000 n
+0000552337 00000 n
+0000549611 00000 n
+0000552830 00000 n
+0000552894 00000 n
+0000552958 00000 n
+0000553022 00000 n
+0000553086 00000 n
+0000553150 00000 n
+0000553214 00000 n
+0000553278 00000 n
+0000553342 00000 n
+0000553469 00000 n
+0000552479 00000 n
+0000561190 00000 n
+0000561350 00000 n
+0000561506 00000 n
+0000561666 00000 n
+0000561827 00000 n
+0000561994 00000 n
+0000562161 00000 n
+0000562328 00000 n
+0000562489 00000 n
+0000562645 00000 n
+0000562804 00000 n
+0000562971 00000 n
+0000563138 00000 n
+0000563299 00000 n
+0000563466 00000 n
+0000563633 00000 n
+0000563794 00000 n
+0000563955 00000 n
+0000564122 00000 n
+0000564289 00000 n
+0000564456 00000 n
+0000564623 00000 n
+0000564790 00000 n
+0000564950 00000 n
+0000565116 00000 n
+0000565283 00000 n
+0000565450 00000 n
+0000565608 00000 n
+0000565768 00000 n
+0000565924 00000 n
+0000566078 00000 n
+0000566238 00000 n
+0000566399 00000 n
+0000566559 00000 n
+0000566720 00000 n
+0000566880 00000 n
+0000567036 00000 n
+0000567197 00000 n
+0000567358 00000 n
+0000567519 00000 n
+0000567680 00000 n
+0000572602 00000 n
+0000572758 00000 n
+0000572918 00000 n
+0000573078 00000 n
+0000573245 00000 n
+0000573410 00000 n
+0000573576 00000 n
+0000573742 00000 n
+0000573909 00000 n
+0000567905 00000 n
+0000559984 00000 n
+0000553723 00000 n
+0000567841 00000 n
+0000560126 00000 n
+0000574076 00000 n
+0000574243 00000 n
+0000574409 00000 n
+0000574576 00000 n
+0000574743 00000 n
+0000574911 00000 n
+0000575078 00000 n
+0000575246 00000 n
+0000575414 00000 n
+0000575575 00000 n
+0000575742 00000 n
+0000575909 00000 n
+0000576076 00000 n
+0000576243 00000 n
+0000576410 00000 n
+0000576577 00000 n
+0000576744 00000 n
+0000576911 00000 n
+0000577078 00000 n
+0000577298 00000 n
+0000572186 00000 n
+0000568043 00000 n
+0000577234 00000 n
+0000572328 00000 n
+0000844222 00000 n
+0000577554 00000 n
+0000844484 00000 n
+0000577581 00000 n
+0000844350 00000 n
+0000577674 00000 n
+0000577913 00000 n
+0000577938 00000 n
+0000589923 00000 n
+0000578166 00000 n
+0000578269 00000 n
+0000590165 00000 n
+0000590889 00000 n
+0000591123 00000 n
+0000604555 00000 n
+0000591439 00000 n
+0000591542 00000 n
+0000604789 00000 n
+0000605535 00000 n
+0000605761 00000 n
+0000616795 00000 n
+0000605908 00000 n
+0000606006 00000 n
+0000617035 00000 n
+0000617713 00000 n
+0000617944 00000 n
+0000619055 00000 n
+0000617999 00000 n
+0000618096 00000 n
+0000619298 00000 n
+0000619908 00000 n
+0000620112 00000 n
+0000620139 00000 n
+0000620166 00000 n
+0000622541 00000 n
+0000620358 00000 n
+0000620464 00000 n
+0000622789 00000 n
+0000623472 00000 n
+0000623682 00000 n
+0000633657 00000 n
+0000624299 00000 n
+0000624429 00000 n
+0000633897 00000 n
+0000634990 00000 n
+0000635194 00000 n
+0000637520 00000 n
+0000635361 00000 n
+0000635467 00000 n
+0000637767 00000 n
+0000638440 00000 n
+0000638650 00000 n
+0000640335 00000 n
+0000638763 00000 n
+0000638869 00000 n
+0000640584 00000 n
+0000641237 00000 n
+0000641448 00000 n
+0000646972 00000 n
+0000641801 00000 n
+0000641912 00000 n
+0000647216 00000 n
+0000647992 00000 n
+0000648197 00000 n
+0000655771 00000 n
+0000648651 00000 n
+0000648766 00000 n
+0000656011 00000 n
+0000656896 00000 n
+0000657099 00000 n
+0000657849 00000 n
+0000657133 00000 n
+0000657228 00000 n
+0000658088 00000 n
+0000658684 00000 n
+0000658886 00000 n
+0000665279 00000 n
+0000659343 00000 n
+0000659451 00000 n
+0000665519 00000 n
+0000666404 00000 n
+0000666608 00000 n
+0000669212 00000 n
+0000666798 00000 n
+0000666904 00000 n
+0000669455 00000 n
+0000670127 00000 n
+0000670331 00000 n
+0000672351 00000 n
+0000670445 00000 n
+0000670549 00000 n
+0000672593 00000 n
+0000673238 00000 n
+0000673443 00000 n
+0000676496 00000 n
+0000673734 00000 n
+0000673841 00000 n
+0000676736 00000 n
+0000677472 00000 n
+0000677676 00000 n
+0000685145 00000 n
+0000678141 00000 n
+0000678256 00000 n
+0000685386 00000 n
+0000686265 00000 n
+0000686470 00000 n
+0000686497 00000 n
+0000686558 00000 n
+0000686751 00000 n
+0000686992 00000 n
+0000687209 00000 n
+0000691873 00000 n
+0000687564 00000 n
+0000687670 00000 n
+0000692115 00000 n
+0000692886 00000 n
+0000693090 00000 n
+0000695653 00000 n
+0000693313 00000 n
+0000693419 00000 n
+0000695893 00000 n
+0000696577 00000 n
+0000696781 00000 n
+0000706002 00000 n
+0000697268 00000 n
+0000697388 00000 n
+0000706243 00000 n
+0000707239 00000 n
+0000707444 00000 n
+0000709454 00000 n
+0000707558 00000 n
+0000707662 00000 n
+0000709696 00000 n
+0000710342 00000 n
+0000710547 00000 n
+0000712965 00000 n
+0000710783 00000 n
+0000710889 00000 n
+0000713206 00000 n
+0000713905 00000 n
+0000714110 00000 n
+0000723522 00000 n
+0000714686 00000 n
+0000714818 00000 n
+0000723764 00000 n
+0000724761 00000 n
+0000724967 00000 n
+0000731730 00000 n
+0000725395 00000 n
+0000725507 00000 n
+0000731970 00000 n
+0000732827 00000 n
+0000733030 00000 n
+0000734079 00000 n
+0000733108 00000 n
+0000733208 00000 n
+0000734319 00000 n
+0000734941 00000 n
+0000735145 00000 n
+0000740694 00000 n
+0000735519 00000 n
+0000735634 00000 n
+0000740935 00000 n
+0000741736 00000 n
+0000741941 00000 n
+0000743500 00000 n
+0000742034 00000 n
+0000742135 00000 n
+0000743739 00000 n
+0000744365 00000 n
+0000744567 00000 n
+0000746804 00000 n
+0000744746 00000 n
+0000744852 00000 n
+0000747045 00000 n
+0000747714 00000 n
+0000747919 00000 n
+0000750616 00000 n
+0000748122 00000 n
+0000748229 00000 n
+0000750858 00000 n
+0000751554 00000 n
+0000751760 00000 n
+0000751858 00000 n
+0000752902 00000 n
+0000751936 00000 n
+0000752036 00000 n
+0000753143 00000 n
+0000753767 00000 n
+0000753972 00000 n
+0000755775 00000 n
+0000754083 00000 n
+0000754186 00000 n
+0000756017 00000 n
+0000756660 00000 n
+0000763837 00000 n
+0000756866 00000 n
+0000768155 00000 n
+0000764070 00000 n
+0000771218 00000 n
+0000768444 00000 n
+0000774435 00000 n
+0000771457 00000 n
+0000777055 00000 n
+0000774679 00000 n
+0000800717 00000 n
+0000777300 00000 n
+0000819859 00000 n
+0000801024 00000 n
+0000831821 00000 n
+0000820131 00000 n
+0000835189 00000 n
+0000832071 00000 n
+0000837962 00000 n
+0000835462 00000 n
+0000840907 00000 n
+0000838214 00000 n
+0000843936 00000 n
+0000841153 00000 n
+0000848381 00000 n
+0000848526 00000 n
+0000855648 00000 n
+0000856313 00000 n
+0000856982 00000 n
+0000857651 00000 n
+0000858317 00000 n
+0000858986 00000 n
+0000859654 00000 n
+0000860325 00000 n
+0000860989 00000 n
+0000861658 00000 n
+0000862327 00000 n
+0000862993 00000 n
+0000863662 00000 n
+0000864331 00000 n
+0000864996 00000 n
+0000865667 00000 n
+0000866335 00000 n
+0000867004 00000 n
+0000867670 00000 n
+0000868339 00000 n
+0000869008 00000 n
+0000869674 00000 n
+0000870343 00000 n
+0000871011 00000 n
+0000871682 00000 n
+0000872347 00000 n
+0000873016 00000 n
+0000873685 00000 n
+0000874351 00000 n
+0000875020 00000 n
+0000875689 00000 n
+0000876358 00000 n
+0000877026 00000 n
+0000877694 00000 n
+0000878363 00000 n
+0000879025 00000 n
+0000879694 00000 n
+0000880363 00000 n
+0000881032 00000 n
+0000881697 00000 n
+0000882368 00000 n
+0000883036 00000 n
+0000883702 00000 n
+0000884371 00000 n
+0000885040 00000 n
+0000885709 00000 n
+0000886375 00000 n
+0000887044 00000 n
+0000887712 00000 n
+0000888380 00000 n
+0000889049 00000 n
+0000889718 00000 n
+0000890387 00000 n
+0000891053 00000 n
+0000891722 00000 n
+0000892391 00000 n
+0000893056 00000 n
+0000893727 00000 n
+0000894395 00000 n
+0000895064 00000 n
+0000895730 00000 n
+0000896399 00000 n
+0000897068 00000 n
+0000897734 00000 n
+0000898403 00000 n
+0000899071 00000 n
+0000899742 00000 n
+0000900406 00000 n
+0000901075 00000 n
+0000901744 00000 n
+0000902406 00000 n
+0000903075 00000 n
+0000903744 00000 n
+0000904410 00000 n
+0000905056 00000 n
+0000905662 00000 n
+0000906294 00000 n
+0000906928 00000 n
+0000907563 00000 n
+0000908198 00000 n
+0000908833 00000 n
+0000909465 00000 n
+0000910100 00000 n
+0000910735 00000 n
+0000911366 00000 n
+0000912003 00000 n
+0000912637 00000 n
+0000913272 00000 n
+0000913904 00000 n
+0000914539 00000 n
+0000915174 00000 n
+0000915806 00000 n
+0000916441 00000 n
+0000917075 00000 n
+0000917712 00000 n
+0000918342 00000 n
+0000918977 00000 n
+0000919612 00000 n
+0000920340 00000 n
+0000921120 00000 n
+0000921764 00000 n
+0000922433 00000 n
+0000923122 00000 n
+0000923929 00000 n
+0000924747 00000 n
+0000925755 00000 n
+0000926657 00000 n
+0000927013 00000 n
+0000927366 00000 n
+0000927719 00000 n
+0000927873 00000 n
+0000927976 00000 n
+0000928016 00000 n
+0000928148 00000 n
trailer
-<< /Size 4479 /Root 4477 0 R /Info 4478 0 R /ID [ <C9F20A8D89B27EDA17D779CBC22D293D> <C9F20A8D89B27EDA17D779CBC22D293D> ] >>
+<< /Size 4502 /Root 4500 0 R /Info 4501 0 R /ID [ <72B0ADAD148795187FD4FF4E06FB6E37> <72B0ADAD148795187FD4FF4E06FB6E37> ] >>
startxref
-925131
+928712
%%EOF