texlive[57789] trunk: l3 (18feb21)

commits+karl at tug.org commits+karl at tug.org
Thu Feb 18 23:17:57 CET 2021


Revision: 57789
          http://tug.org/svn/texlive?view=revision&revision=57789
Author:   karl
Date:     2021-02-18 23:17:56 +0100 (Thu, 18 Feb 2021)
Log Message:
-----------
l3 (18feb21)

Modified Paths:
--------------
    trunk/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl
    trunk/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/l3backend/README.md
    trunk/Master/texmf-dist/doc/latex/l3backend/l3backend-code.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/l3experimental/README.md
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3benchmark/l3benchmark.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3bitset/l3bitset.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw-code.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3graphics/l3graphics.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3str/l3str-format.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3sys-shell/l3sys-shell.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/xcoffins/xcoffins.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/xgalley/l3galley.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/xgalley/xgalley.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/l3kernel/README.md
    trunk/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news01.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news02.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news03.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news04.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news05.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news06.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news07.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news08.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news09.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news10.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news11.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news12.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/source3.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/source3body.tex
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3bitset/l3bitset.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3.ins
    trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3text.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3benchmark/l3benchmark.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3bitset/l3bitset.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3draw/l3draw.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3graphics/l3graphics.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-format.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3sys-shell/l3sys-shell.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty

Added Paths:
-----------
    trunk/Master/texmf-dist/source/latex/l3kernel/l3color.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx

Removed Paths:
-------------
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3color/
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3pdf/
    trunk/Master/texmf-dist/source/latex/l3experimental/l3color/
    trunk/Master/texmf-dist/source/latex/l3experimental/l3pdf/
    trunk/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3color/
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3pdf/

Modified: trunk/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl	2021-02-18 22:17:56 UTC (rev 57789)
@@ -1,12 +1,12 @@
 #!/usr/bin/env perl
-# $Id: tlmgr.pl 57705 2021-02-10 22:57:28Z karl $
+# $Id: tlmgr.pl 57772 2021-02-17 19:01:36Z karl $
 #
-# Copyright 2008-2020 Norbert Preining
+# Copyright 2008-2021 Norbert Preining
 # This file is licensed under the GNU General Public License version 2
 # or any later version.
 
-my $svnrev = '$Revision: 57705 $';
-my $datrev = '$Date: 2021-02-10 23:57:28 +0100 (Wed, 10 Feb 2021) $';
+my $svnrev = '$Revision: 57772 $';
+my $datrev = '$Date: 2021-02-17 20:01:36 +0100 (Wed, 17 Feb 2021) $';
 my $tlmgrrevision;
 my $tlmgrversion;
 my $prg;
@@ -10117,7 +10117,7 @@
 distribution (L<https://tug.org/texlive>) and both are licensed under the
 GNU General Public License Version 2 or later.
 
-$Id: tlmgr.pl 57705 2021-02-10 22:57:28Z karl $
+$Id: tlmgr.pl 57772 2021-02-17 19:01:36Z karl $
 =cut
 
 # test HTML version: pod2html --cachedir=/tmp tlmgr.pl >/tmp/tlmgr.html

Modified: trunk/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md	2021-02-18 22:17:56 UTC (rev 57789)
@@ -6,6 +6,14 @@
 
 ## [Unreleased]
 
+## [2021-02-18]
+
+### Changed
+- Update tracking of PDF management functions
+
+### Fixed
+- Opacity support for pdfTeX/LuaTeX
+
 ## [2021-02-06]
 
 ### Changed
@@ -151,7 +159,8 @@
 - Include `l3backend` in file names
 - Moved backend code to internal for each 'parent' module
 
-[Unreleased]: https://github.com/latex3/latex3/compare/2021-02-06...HEAD
+[Unreleased]: https://github.com/latex3/latex3/compare/2021-02-18...HEAD
+[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

Modified: trunk/Master/texmf-dist/doc/latex/l3backend/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3backend/README.md	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/doc/latex/l3backend/README.md	2021-02-18 22:17:56 UTC (rev 57789)
@@ -1,7 +1,7 @@
 LaTeX3 Backend Drivers
 ======================
 
-Release 2021-02-06
+Release 2021-02-18
 
 This package forms parts of `expl3`, and contains the code used to interface
 with backends (drivers) across the `expl3` codebase. The functions here are

Modified: trunk/Master/texmf-dist/doc/latex/l3backend/l3backend-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3experimental/CHANGELOG.md	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/doc/latex/l3experimental/CHANGELOG.md	2021-02-18 22:17:56 UTC (rev 57789)
@@ -7,6 +7,12 @@
 
 ## [Unreleased]
 
+## [2021-02-18]
+
+### Removed
+- `l3color`: moved to `l3kernel`
+- `l3pdf`: moved to `l3kernel`
+
 ## [2021-02-06]
 
 ### Changed
@@ -195,7 +201,8 @@
 - New `l3color` module using `xcolor`-like expression syntax
 - New `l3draw` module, based on `pgf` layer of the TikZ system
 
-[Unreleased]: https://github.com/latex3/latex3/compare/2021-02-06...HEAD
+[Unreleased]: https://github.com/latex3/latex3/compare/2021-02-18...HEAD
+[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-10-27...2021-01-29
 [2020-10-27]: https://github.com/latex3/latex3/compare/2020-09-24...2020-10-27

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3experimental/README.md	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/doc/latex/l3experimental/README.md	2021-02-18 22:17:56 UTC (rev 57789)
@@ -1,7 +1,7 @@
 Experimental LaTeX3 Concepts
 ============================
 
-Release 2021-02-06
+Release 2021-02-18
 
 Overview
 --------
@@ -22,7 +22,6 @@
 Currently included in the CTAN release of l3experimental are the following
 bundles:
 * `l3benchmark`
-* `l3color`
 * `l3draw`
 * `l3graphics`
 * `l3pdf`
@@ -36,15 +35,6 @@
 
 This module provides support for benchmarking the performance of code.
 
-
-`l3color`
----------
-
-This module provides support for setting colors using a range of color models.
-It also allows the construction of 'color expressions', in which multiple colors
-are mixed together at the macro level. There is also support for spot colors:
-the latter is highly experimental.
-
 `l3draw`
 --------
 
@@ -127,7 +117,7 @@
 ------------------
 
 Development of LaTeX3 is carried out by
-[The LaTeX Project](https://www.latex-project.org/latex3/). 
+[The LaTeX Project](https://www.latex-project.org/latex3/).
 
 The development team can be contacted
 by e-mail: <latex-team at latex-project.org>; for general LaTeX3 discussion

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3benchmark/l3benchmark.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3bitset/l3bitset.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3graphics/l3graphics.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3str/l3str-format.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3sys-shell/l3sys-shell.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/xcoffins/xcoffins.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/xgalley/l3galley.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/xgalley/xgalley.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md	2021-02-18 22:17:56 UTC (rev 57789)
@@ -7,6 +7,17 @@
 
 ## [Unreleased]
 
+## [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
@@ -755,35 +766,35 @@
 ## [2018-05-13]
 
 ### Fixed
-- Cor­rect date string in `ex­pl3.dtx`
-- Cor­rect `\c_sys_en­gine_ver­sion_str` when using XeTeX
+- 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`
-- Im­ple­ment `\c_sys_en­gine_ver­sion_str`
-- Im­ple­ment `\seq_in­dexed_map_func­tion/in­line`
-- Im­ple­ment `\in­tar­ray_gzero:N`
-- Im­ple­ment `\in­tar­ray_const_from_clist:Nn`
-- Im­ple­ment `\bool_set_in­verse:N`
-- Im­ple­ment `\bool_xor:nnTF` in­stead of just `\bool_xor_p:nn`
-- Im­ple­ment can­di­date `\int_rand:n`
-- Im­ple­ment `\in­tar­ray_gset_rand:Nnn`
-- Im­ple­ment can­di­date `l3f­par­ray` mod­ule
+- 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
-- Up­date min­i­mal re­quired ver­sions of XeTeX and LuaTeX
-- Dep­re­cate named in­te­ger con­stants `\c_zero`. etc.
-- Move all prim­i­tives to `\tex_...:D names­pace`,
-  dep­re­cat­ing older en­gine-de­pen­dent pre­fixes
+- 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
-- Ex­pand boolean ex­pres­sion be­fore call­ing `\chardef` (fixes #461)
+- Expand boolean expression before calling `\chardef` (fixes #461)
 
 ### Removed
-- Re­move un­doc­u­mented `\fp_func­tion:Nw` and `\fp_new_func­tion:Npn`
+- Remove undocumented `\fp_function:Nw` and `\fp_new_function:Npn`
 
 ## [2018-04-30]
 
@@ -833,10 +844,11 @@
 
 ### Added
 - Tuple support in fp expressions
-- Step func­tions have been added for dim vari­ables,
-  e.g. `\dim_step_in­line:nnnn`
+- Step functions have been added for dim variables,
+  e.g. `\dim_step_inline:nnnn`
 
-[Unreleased]: https://github.com/latex3/latex3/compare/2021-02-06...HEAD
+[Unreleased]: https://github.com/latex3/latex3/compare/2021-02-18...HEAD
+[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

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/README.md	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/README.md	2021-02-18 22:17:56 UTC (rev 57789)
@@ -1,7 +1,7 @@
 LaTeX3 Programming Conventions
 ==============================
 
-Release 2021-02-06
+Release 2021-02-18
 
 Overview
 --------

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex	2021-02-18 22:17:56 UTC (rev 57789)
@@ -1,6 +1,6 @@
 \iffalse meta-comment
 
-File: interfaces3.tex
+File: interface3.tex
 
 Copyright (C) 1990-2011,2017-2021 The LaTeX Project
 
@@ -54,7 +54,7 @@
          {latex-team at latex-project.org}%
    }%
 }
-\date{Released 2021-02-06}
+\date{Released 2021-02-18}
 
 \pagenumbering{roman}
 \maketitle

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news01.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news02.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news03.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news04.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news05.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news06.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news07.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news08.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news09.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news10.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news11.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news12.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv	2021-02-18 22:17:56 UTC (rev 57789)
@@ -4,6 +4,7 @@
 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,

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex	2021-02-18 22:17:56 UTC (rev 57789)
@@ -32,7 +32,7 @@
         {latex-team at latex-project.org}%
     }%
 }
-\date{Released 2021-02-06}
+\date{Released 2021-02-18}
 
 \begin{document}
 

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex	2021-02-18 22:17:56 UTC (rev 57789)
@@ -32,7 +32,7 @@
         {latex-team at latex-project.org}%
     }%
 }
-\date{Released 2021-02-06}
+\date{Released 2021-02-18}
 
 \newcommand{\TF}{\textit{(TF)}}
 

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex	2021-02-18 22:17:56 UTC (rev 57789)
@@ -32,7 +32,7 @@
         {latex-team at latex-project.org}%
     }%
 }
-\date{Released 2021-02-06}
+\date{Released 2021-02-18}
 
 \newcommand{\TF}{\textit{(TF)}}
 

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/source3.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex	2021-02-18 22:17:56 UTC (rev 57789)
@@ -53,7 +53,7 @@
          {latex-team at latex-project.org}%
    }%
 }
-\date{Released 2021-02-06}
+\date{Released 2021-02-18}
 
 \pagenumbering{roman}
 \maketitle

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/source3body.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/source3body.tex	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/source3body.tex	2021-02-18 22:17:56 UTC (rev 57789)
@@ -55,33 +55,14 @@
 not required or encouraged: the \pkg{expl3} modules define an
 independent low-level \LaTeX3 programming language.
 
-At present, the \pkg{expl3} modules are designed to be loaded on top of
-\LaTeXe{}. In time, a \LaTeX3 format will be produced based on this code.
-This allows the code to be used in \LaTeXe{} packages \emph{now} while a
-stand-alone \LaTeX3 is developed.
+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.
 
-\begin{bfseries}
-  While \pkg{expl3} is still experimental, the bundle is now regarded as
-  broadly stable. 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}.
-
-  New modules will be added to the distributed version of \pkg{expl3} as
-  they reach maturity.
-\end{bfseries}
-
 \end{abstract}
 
-\clearpage
-
-{%
-  \def\\{:}% fix "newlines" in the ToC
-  \tableofcontents
-}
-
-\clearpage
-\pagenumbering{arabic}
-
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 % Each of the following \DocInput lines includes a file with extension
@@ -97,8 +78,79 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 \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 at chapter}
+\renewcommand \thesection {\thechapter.\@arabic\c at section}
+\newcommand*\chaptermark[1]{}
+\setcounter{secnumdepth}{2}
+\newcommand\@chapapp{\chaptername}
+\newcommand\chaptername{Chapter}
+  \def\ps at headings{%
+    \let\@oddfoot\@empty
+    \def\@oddhead{{\slshape\rightmark}\hfil\thepage}%
+    \let\@mkboth\markboth
+    \def\chaptermark##1{%
+      \markright {\MakeUppercase{%
+        \ifnum \c at secnumdepth >\m at 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 at chapter[2]{%
+  \ifnum \c at tocdepth >\m at 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 at xt@\@pnumwidth{\hss #2%
+                                 \kern-\p@\kern\p@}\par
+      \penalty\@highpenalty
+    \endgroup
+  \fi}
+\renewcommand*\l at section{\@dottedtocline{1}{1.5em}{2.8em}}
+\renewcommand*\l at subsection{\@dottedtocline{2}{3.8em}{3.2em}}
+\renewcommand*\l at subsubsection{\@dottedtocline{3}{7.0em}{4.1em}}
 \def\partname{Part}
-\def\maketitle{\clearpage\part{\@title}}
+\def\toclevel at part{-1}
+\def\maketitle{\chapter{\@title}}
 \let\thanks\@gobble
 \let\DelayPrintIndex\PrintIndex
 \let\PrintIndex\@empty
@@ -105,8 +157,20 @@
 \providecommand*{\hexnum}[1]{\text{\texttt{\char`\"}#1}}
 \makeatother
 
-\part{Introduction to \pkg{expl3} and this document}
+\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}.
@@ -441,27 +505,43 @@
 
 \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{l3quark.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{l3str.dtx}
 \DocInput{l3str-convert.dtx}
+\DocInput{l3quark.dtx}
 \DocInput{l3seq.dtx}
 \DocInput{l3int.dtx}
 \DocInput{l3flag.dtx}
-\DocInput{l3prg.dtx}
-\DocInput{l3sys.dtx}
 \DocInput{l3clist.dtx}
 \DocInput{l3token.dtx}
 \DocInput{l3prop.dtx}
-\DocInput{l3msg.dtx}
-\DocInput{l3file.dtx}
 \DocInput{l3skip.dtx}
 \DocInput{l3keys.dtx}
 \DocInput{l3intarray.dtx}
@@ -489,13 +569,9 @@
 
 \DocInput{l3fparray.dtx}
 \DocInput{l3cctab.dtx}
-\DocInput{l3sort.dtx}
-\DocInput{l3tl-analysis.dtx}
-\DocInput{l3regex.dtx}
-\DocInput{l3box.dtx}
-\DocInput{l3coffins.dtx}
-\DocInput{l3color-base.dtx}
-\DocInput{l3luatex.dtx}
+
+\part{Text manipulation}
+
 \DocInput{l3unicode.dtx}
 \DocInput{l3text.dtx}
 \ExplSyntaxOn
@@ -505,7 +581,16 @@
     l3text-purify.dtx
   }
 \ExplSyntaxOff
-\DocInput{l3legacy.dtx}
+
+\part{Typesetting}
+
+\DocInput{l3box.dtx}
+\DocInput{l3coffins.dtx}
+\DocInput{l3color.dtx}
+\DocInput{l3pdf.dtx}
+
+\part{Additions and removals}
+
 \DocInput{l3candidates.dtx}
 
 \ExplSyntaxOn

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -70,27 +70,27 @@
 %    \begin{macrocode}
 \ProvidesExplFile
 %<*dvipdfmx>
-  {l3backend-dvipdfmx.def}{2021-02-06}{}
+  {l3backend-dvipdfmx.def}{2021-02-18}{}
   {L3 backend support: dvipdfmx}
 %</dvipdfmx>
 %<*dvips>
-  {l3backend-dvips.def}{2021-02-06}{}
+  {l3backend-dvips.def}{2021-02-18}{}
   {L3 backend support: dvips}
 %</dvips>
 %<*dvisvgm>
-  {l3backend-dvisvgm.def}{2021-02-06}{}
+  {l3backend-dvisvgm.def}{2021-02-18}{}
   {L3 backend support: dvisvgm}
 %</dvisvgm>
 %<*luatex>
-  {l3backend-luatex.def}{2021-02-06}{}
+  {l3backend-luatex.def}{2021-02-18}{}
   {L3 backend support: PDF output (LuaTeX)}
 %</luatex>
 %<*pdftex>
-  {l3backend-pdftex.def}{2021-02-06}{}
+  {l3backend-pdftex.def}{2021-02-18}{}
   {L3 backend support: PDF output (pdfTeX)}
 %</pdftex>
 %<*xetex>
-  {l3backend-xetex.def}{2021-02-06}{}
+  {l3backend-xetex.def}{2021-02-18}{}
   {L3 backend support: XeTeX}
 %</xetex>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -241,13 +241,13 @@
 % \end{variable}
 % \end{macro}
 %
-% \begin{macro}{\@@_backend_stack_push:nn, \@@_backend_stack_push:nx}
-% \begin{macro}{\@@_backend_stack_pop:n}
+% \begin{macro}{\__kernel_color_backend_stack_push:nn, \__kernel_color_backend_stack_push:nx}
+% \begin{macro}{\__kernel_color_backend_stack_pop:n}
 %   Simple enough but needs a version check.
 %    \begin{macrocode}
 \int_compare:nNnF \c__kernel_sys_dvipdfmx_version_int < { 20201111 }
   {
-    \cs_new_protected:Npn \@@_backend_stack_push:nn #1#2
+    \cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2
       {
         \__kernel_backend_literal:x
           {
@@ -256,8 +256,8 @@
             push ~ (#2)
           }
       }
-    \cs_generate_variant:Nn \@@_backend_stack_push:nn { nx }
-    \cs_new_protected:Npn \@@_backend_stack_pop:n #1
+    \cs_generate_variant:Nn \__kernel_color_backend_stack_push:nn { nx }
+    \cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1
       {
         \__kernel_backend_literal:x
           {
@@ -300,10 +300,10 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_backend_stack_push:nn, \@@_backend_stack_push:nx}
-% \begin{macro}{\@@_backend_stack_pop:n}
+% \begin{macro}{\__kernel_color_backend_stack_push:nn, \__kernel_color_backend_stack_push:nx}
+% \begin{macro}{\__kernel_color_backend_stack_pop:n}
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_stack_push:nn #1#2
+\cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2
   {
 %<*luatex>
     \tex_pdfextension:D colorstack ~
@@ -313,8 +313,8 @@
 %</pdftex>
       \int_eval:n {#1} ~ push ~ {#2}
   }
-\cs_generate_variant:Nn \@@_backend_stack_push:nn { nx }
-\cs_new_protected:Npn \@@_backend_stack_pop:n #1
+\cs_generate_variant:Nn \__kernel_color_backend_stack_push:nn { nx }
+\cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1
   {
 %<*luatex>
     \tex_pdfextension:D colorstack ~
@@ -410,11 +410,11 @@
   {
     \tl_set:Nn \l_@@_backend_fill_tl {#1}
     \tl_set:Nn \l_@@_backend_stroke_tl {#2}
-    \@@_backend_stack_push:nn \l_@@_backend_stack_int { #1 ~ #2 }
+    \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int { #1 ~ #2 }
     \group_insert_after:N \@@_backend_reset:
   }
 \cs_new_protected:Npn \@@_backend_reset:
-  { \@@_backend_stack_pop:n \l_@@_backend_stack_int }
+  { \__kernel_color_backend_stack_pop:n \l_@@_backend_stack_int }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -790,7 +790,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_backend_separation_init:nnnnn #1#2#3#4#5
   {
-    \pdf_object_now:nx { dict }
+    \pdf_object_unnamed_write:nx { dict }
       {
         /FunctionType ~ 2
         /Domain ~ [0 ~ 1]
@@ -802,21 +802,22 @@
       {
         /Separation ~
         / \str_convert_pdfname:n {#1} ~ #2 ~
-        \pdf_object_last:
+        \pdf_object_ref_last:
       }
-    \use:x
+    \cs_if_exist:NT \pdfmanagement_add:nnn
       {
-        \pdfmanagement_add:nnn
-          { Page / Resources / ColorSpace }
-          { color \int_use:N \g_@@_model_int }
-          { \pdf_object_last: }
+        \use:x
+          {
+            \pdfmanagement_add:nnn
+              { Page / Resources / ColorSpace }
+              { color \int_use:N \g_@@_model_int }
+              { \pdf_object_ref_last: }
+          }
       }
   }
-\cs_if_exist:NF \pdf_object_now:nn
-  { \cs_gset_protected:Npn \@@_backend_separation_init:nnnnn #1#2#3#4#5 { } }
 \cs_new_protected:Npn \@@_backend_separation_init:n #1
   {
-    \pdf_object_now:nx { array } {#1}
+    \pdf_object_unnamed_write:nx { array } {#1}
   }
 %    \end{macrocode}
 %   For CIELAB colors, we need one object per document for the illuminant,
@@ -844,7 +845,7 @@
       { 100 ~ 0 ~ 0 }
       {#3}
   }
-\cs_if_exist:NF \pdf_object_now:nn
+\cs_if_exist:NF \pdf_object_unnamed_write:nn
   {
     \cs_gset_protected:Npn \@@_backend_separation_init_CIELAB:nnn #1#2#3
       { }
@@ -862,7 +863,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_backend_devicen_init:nnn #1#2#3
   {
-    \pdf_object_now:nx { stream }
+    \pdf_object_unnamed_write:nx { stream }
       {
         {
           /FunctionType ~ 4 ~
@@ -889,18 +890,19 @@
         /DeviceN ~
         [ ~ #1 ~ ] ~
         #2 ~
-        \pdf_object_last:
+        \pdf_object_ref_last:
       }
-    \use:x
+    \cs_if_exist:NT \pdfmanagement_add:nnn
       {
-        \pdfmanagement_add:nnn
-          { Page / Resources / ColorSpace }
-          { color \int_use:N \g_@@_model_int }
-          { \pdf_object_last: }
+        \use:x
+          {
+            \pdfmanagement_add:nnn
+              { Page / Resources / ColorSpace }
+              { color \int_use:N \g_@@_model_int }
+              { \pdf_object_ref_last: }
+          }
       }
   }
-\cs_if_exist:NF \pdf_object_now:nn
-  { \cs_gset_protected:Npn \@@_backend_devicen_init:nnn #1#2#3 { } }
 \cs_new:Npn \@@_backend_devicen_init:w #1 ~ #2 \s_@@_stop
   {
     + 1
@@ -976,7 +978,7 @@
 \cs_new_protected:Npn \@@_backend_fill:n #1
   {
     \tl_set:Nn \l_@@_backend_fill_tl {#1}
-    \@@_backend_stack_push:nn \l_@@_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int
       { #1 ~ \l_@@_backend_stroke_tl }
     \group_insert_after:N \@@_backend_reset:
   }
@@ -989,7 +991,7 @@
 \cs_new_protected:Npn \@@_backend_stroke:n #1
   {
     \tl_set:Nn \l_@@_backend_stroke_tl {#1}
-    \@@_backend_stack_push:nn \l_@@_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int
       { \l_@@_backend_fill_tl \c_space_tl #1 }
     \group_insert_after:N \@@_backend_reset:
   }

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -151,7 +151,7 @@
     \pdfmanagement_add:nnn { Page / Resources / ExtGState }
       { opacity #1 }
       { << /ca ~ #1 /CA ~ #1 >> }
-    \@@_backend_stack_push:nn \c_@@_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \c_@@_backend_stack_int
       { /opacity #1 ~ gs }
     \group_insert_after:N \@@_backend_reset:
   }
@@ -160,7 +160,7 @@
     \cs_gset_protected:Npn \@@_backend_select_aux:n #1 { }
   }
 \cs_new_protected:Npn \@@_backend_reset:
- { \@@_backend_stack_pop:n \c_@@_backend_stack_int }
+ { \__kernel_color_backend_stack_pop:n \c_@@_backend_stack_int }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -195,7 +195,7 @@
         \pdfmanagement_add:nnn { Page / Resources / ExtGState }
           { opacity.stroke #1 }
           { << /CA ~ #2 >> }
-        \@@_backend_stack_push:nn \c_@@_backend_stack_int
+        \__kernel_color_backend_stack_push:nn \c_@@_backend_stack_int
          { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs }
         \group_insert_after:N \@@_backend_reset:
       }

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -129,7 +129,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{l3benchmark}{2021-02-06}{}
+\ProvidesExplPackage{l3benchmark}{2021-02-18}{}
   {L3 Experimental benchmarking}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3bitset/l3bitset.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3bitset/l3bitset.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3bitset/l3bitset.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -42,7 +42,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 % \begin{documentation}
@@ -264,7 +264,7 @@
 %<@@=bitset>
 %    \end{macrocode}
 %    \begin{macrocode}
-\ProvidesExplPackage{l3bitset}{2021-02-06}{}
+\ProvidesExplPackage{l3bitset}{2021-02-18}{}
   {L3 Experimental bitset support}
 %    \end{macrocode}
 % A bitset is a string variable.

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -110,7 +110,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -231,7 +231,7 @@
 %   \begin{syntax}
 %     \cs{draw_linewidth:n} \Arg{width}
 %   \end{syntax}
-%   Sets the width to be used for stroking to the \meta{width} (an 
+%   Sets the width to be used for stroking to the \meta{width} (an
 %   \meta{fp expr}).
 % \end{function}
 %
@@ -268,7 +268,7 @@
 %     \draw_end:
 %   \end{demo}
 %   Setting an empty pattern will produce a solid line.
-%   
+%
 %   Note the \meta{pattern} interface here is different from that in \pkg{pgf}:
 %   the list is comma-separated not given in brace groups.
 % \end{function}
@@ -410,7 +410,7 @@
 %   Gives the co-ordinates of the point at \meta{angle} (an \meta{fp expr} in
 %   \emph{degrees}) and \meta{radius}. The three-argument version accepts
 %   two radii of different lengths.
-%   
+%
 %   Note the interface here is somewhat different from that in \pkg{pgf}:
 %   the one- and two-radii versions in \pkg{l3draw} use separate functions,
 %   whilst in \pkg{pgf} they use the same function and a keyword.
@@ -470,7 +470,7 @@
 %   \emph{degrees}) and \meta{radius}, relative to the prevailing
 %   $x$- and $y$-vectors. The three-argument version accepts two radii of
 %   different lengths.
-%   
+%
 %   Note the interface here is somewhat different from that in \pkg{pgf}:
 %   the one- and two-radii versions in \pkg{l3draw} use separate functions,
 %   whilst in \pkg{pgf} they use the same function and a keyword.
@@ -795,7 +795,7 @@
 %   \begin{syntax}
 %     \cs{draw_path_circle:nn} \Arg{center} \Arg{radius}
 %   \end{syntax}
-%   Appends a circle of \meta{radius} at \meta{center} to the current path. 
+%   Appends a circle of \meta{radius} at \meta{center} to the current path.
 %   This is a shortcut for \cs{draw_path_ellipse:nnn}.
 % \end{function}
 %
@@ -1136,14 +1136,10 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{l3draw}{2021-02-06}{}
+\ProvidesExplPackage{l3draw}{2021-02-18}{}
   {L3 Experimental core drawing support}
 %    \end{macrocode}
 %
-%    \begin{macrocode}
-\RequirePackage { l3color }
-%    \end{macrocode}
-%
 % \subsection{Internal auxiliaries}
 %
 % \begin{variable}{\s_@@_mark,\s_@@_stop}

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -240,7 +240,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{l3graphics}{2021-02-06}{}
+\ProvidesExplPackage{l3graphics}{2021-02-18}{}
   {L3 Experimental graphics inclusion support}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -48,7 +48,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -166,7 +166,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{l3str-format}{2021-02-06}{}
+\ProvidesExplPackage{l3str-format}{2021-02-18}{}
   {L3 Experimental string formatting}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -135,7 +135,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{l3sys-shell}{2021-02-06}{}
+\ProvidesExplPackage{l3sys-shell}{2021-02-18}{}
   {L3 Experimental system shell functions}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -53,7 +53,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -672,7 +672,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xcoffins}{2021-02-06}{}
+\ProvidesExplPackage{xcoffins}{2021-02-18}{}
   {L3 Experimental design level coffins}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -61,7 +61,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -686,7 +686,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{l3galley}{2021-02-06}{}
+\ProvidesExplPackage{l3galley}{2021-02-18}{}
   {L3 Experimental galley code}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -731,7 +731,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xgalley}{2021-02-06}{}
+\ProvidesExplPackage{xgalley}{2021-02-18}{}
   {L3 Experimental galley}
 \RequirePackage{xtemplate,l3galley}
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -24,7 +24,7 @@
 %
 %<*driver|generic|package|2ekernel>
 %</driver|generic|package|2ekernel>
-\def\ExplFileDate{2021-02-06}%
+\def\ExplFileDate{2021-02-18}%
 %<*driver>
 \documentclass[full]{l3doc}
 \usepackage{graphicx}
@@ -51,7 +51,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3.ins	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3.ins	2021-02-18 22:17:56 UTC (rev 57789)
@@ -99,7 +99,8 @@
         \from{l3tl-analysis.dtx}{package}
         \from{l3regex.dtx}      {package}
         \from{l3box.dtx}        {package}
-        \from{l3color-base.dtx} {package}
+        \from{l3color.dtx}      {package}
+        \from{l3pdf.dtx}        {package}
         \from{l3coffins.dtx}    {package}
         \from{l3luatex.dtx}     {package,tex}
         \from{l3unicode.dtx}    {package}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -86,8 +86,6 @@
 %
 % \section{Additions to \pkg{l3box}}
 %
-% \subsection{Viewing part of a box}
-%
 % \begin{function}[updated = 2019-01-23]
 %   {\box_clip:N, \box_clip:c, \box_gclip:N, \box_gclip:c}
 %   \begin{syntax}
@@ -254,8 +252,6 @@
 %   This is not available in older versions of \XeTeX{}.
 % \end{function}
 %
-% \subsection{Working with contents of integer arrays}
-%
 % \begin{function}[added = 2018-05-04, rEXP]{\intarray_to_clist:N}
 %   \begin{syntax}
 %     \cs{intarray_to_clist:N} \meta{intarray~var}
@@ -279,32 +275,6 @@
 %   |1+2| then this logs |> 1+2=3.|
 % \end{function}
 %
-% \begin{function}[added = 2017-12-04]
-%   {
-%     \msg_show:nnnnnn ,
-%     \msg_show:nnnnn  ,
-%     \msg_show:nnnn   ,
-%     \msg_show:nnn    ,
-%     \msg_show:nn     ,
-%     \msg_show:nnxxxx ,
-%     \msg_show:nnxxx  ,
-%     \msg_show:nnxx   ,
-%     \msg_show:nnx
-%   }
-%   \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}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -2247,34 +2247,6 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{macro}{\@@_color:n}
-%   Calls \tn{color}, and otherwise does nothing if \tn{color} is not defined.
-%   As this is relatively rarely used, we have it self-define rather than delay
-%   using a hook.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_color:n #1 {#1}
-\bool_lazy_and:nnT
-  { \cs_if_exist_p:N \fmtname }
-  { \str_if_eq_p:Vn \fmtname { LaTeX2e } }
-  {
-    \cs_gset_protected:Npn \@@_color:n
-      {
-        \cs_gset_protected:Npx \@@_color:n
-          {
-            \cs_if_exist:NTF \color_select:n
-              { \color_select:n }
-              {
-                \cs_if_exist:NTF \color
-                  { \exp_not:N \color }
-                  { \exp_not:N \use_none:n }
-              }
-          }
-        \@@_color:n
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{\@@_rule:nn}
 %   Abstract out creation of rules here until there is a higher-level interface.
 %    \begin{macrocode}
@@ -2298,7 +2270,7 @@
   {
     \hcoffin_set:Nn \l_@@_display_pole_coffin
       {
-        \@@_color:n {#4}
+        \color_select:n {#4}
         \@@_rule:nn { 1pt } { 1pt }
       }
     \@@_attach_mark:NnnNnnnn #1 {#2} {#3}
@@ -2305,7 +2277,7 @@
       \l_@@_display_pole_coffin { hc } { vc } { 0pt } { 0pt }
     \hcoffin_set:Nn \l_@@_display_coord_coffin
       {
-        \@@_color:n {#4}
+        \color_select:n {#4}
         \l_@@_display_font_tl
         ( \tl_to_str:n { #2 , #3 } )
       }
@@ -2357,7 +2329,7 @@
   {
     \hcoffin_set:Nn \l_@@_display_pole_coffin
       {
-        \@@_color:n {#2}
+        \color_select:n {#2}
         \@@_rule:nn { 1pt } { 1pt }
       }
     \prop_set_eq:Nc \l_@@_display_poles_prop
@@ -2398,7 +2370,7 @@
               { 0pt } { 0pt }
             \hcoffin_set:Nn \l_@@_display_coord_coffin
               {
-                \@@_color:n {#6}
+                \color_select:n {#6}
                 \l_@@_display_font_tl
                 ( \tl_to_str:n { #1 , ##1 } )
               }

Deleted: trunk/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -1,183 +0,0 @@
-% \iffalse meta-comment
-%
-%% File: l3color-base.dtx
-%
-% Copyright (C) 2011,2012,2014,2016-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 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 \textsf{l3color-base} package\\ Color support^^A
-% }
-%
-% \author{^^A
-%  The \LaTeX{} Project\thanks
-%    {^^A
-%      E-mail:
-%        \href{mailto:latex-team at latex-project.org}
-%          {latex-team at latex-project.org}^^A
-%    }^^A
-% }
-%
-% \date{Released 2021-02-06}
-%
-% \maketitle
-%
-% \begin{documentation}
-%
-% This module provides support for color in \LaTeX3{}. At present, the
-% material here is mainly intended to support a small number of low-level
-% requirements in other \pkg{l3kernel} modules.
-%
-% \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}
-%
-% \end{documentation}
-%
-% \begin{implementation}
-%
-% \section{\pkg{l3color-base} Implementation}
-%
-%    \begin{macrocode}
-%<*package>
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-%<@@=color>
-%    \end{macrocode}
-%
-% \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:
-  {
-    \@@_backend_pickup:N \l_@@_current_tl
-    \@@_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}
-% \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 experimental material.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_select: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}
-%
-%    \begin{macrocode}
-%</package>
-%    \end{macrocode}
-%
-% \end{implementation}
-%
-% \PrintIndex

Added: trunk/Master/texmf-dist/source/latex/l3kernel/l3color.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3color.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3color.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -0,0 +1,2655 @@
+% \iffalse meta-comment
+%
+%% File: l3color.dtx
+%
+% Copyright (C) 2017-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
+%
+%    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 \textsf{l3color} package\\ Color support^^A
+% }
+%
+% \author{^^A
+%  The \LaTeX{} Project\thanks
+%    {^^A
+%      E-mail:
+%        \href{mailto:latex-team at latex-project.org}
+%          {latex-team at latex-project.org}^^A
+%    }^^A
+% }
+%
+% \date{Released 2021-02-18}
+%
+% \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|.
+%
+% 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 percentage. The latter is 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 percentage 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}}. 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}{\color_show:n}
+%   \begin{syntax}
+%     \cs{color_show:n} \Arg{name}
+%   \end{syntax}
+%   Displays the color specification stored in the \meta{name} on the
+%   terminal.
+% \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.
+%
+% \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:}.
+%
+% Note that the \emph{current color} is the fill color, as this is used for
+% running text.
+%
+% \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}{color.sc}
+%   When using \texttt{dvips}, this PostScript variables hold the stroke color.
+% \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{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{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}
+%
+% \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:
+  {
+    \@@_backend_pickup:N \l_@@_current_tl
+    \@@_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}
+% \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 experimental material.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_select: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}
+%
+% \subsection{Utility functions}
+%
+% \begin{macro}[int, TF, EXP]{\@@_if_defined:n}
+%   A simple wrapper to avoid needing to have the lookup repeated in too many
+%   places.
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \@@_if_defined:n #1 { T, F, TF }
+  {
+    \prop_if_exist:cTF { l_@@_named_ #1 _prop }
+      \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}[aux, EXP]
+%   {
+%     \@@_convert_gray_rgb:w
+%     \@@_convert_gray_cmyk:w
+%     \@@_convert_cmyk_gray:w
+%     \@@_convert_cmyk_rgb:w
+%     \@@_convert_rgb_gray:w
+%     \@@_convert_rgb_cmyk:w
+%   }
+%  \begin{macro}[aux, EXP]{\@@_convert_rgb_cmyk:nnnn}
+%    Model conversion is carried out using standard formulae, as described in
+%    the manual for \pkg{xcolor} (see also the \emph{PostScript Language
+%    Reference Manual}).
+%    \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_new_protected:Npn \@@_convert:nnnN #1#2#3#4
+  {
+    \tl_set:Nx #4
+      {
+        \cs_if_exist:cTF { @@_convert_ #1 _ #2 :w }
+          { \use:c { @@_convert_ #1 _ #2 :w } #3 ~ 0 ~ 0 ~ 0 \s_@@_stop }
+          { \use:c { c_@@_fallback_ #2 _tl } }
+      }
+  }
+\cs_generate_variant:Nn \@@_convert:nnnN { nV , nnV }
+\cs_new:Npn \@@_convert_gray_rgb:w #1 ~ #2 \s_@@_stop
+  { #1 ~ #1 ~ #1 }
+\cs_new:Npn \@@_convert_gray_cmyk:w #1 ~ #2 \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 ~ #4 \s_@@_stop
+  { \fp_eval:n { 0.3 * #1 + 0.59 * #2 + 0.11 * #3 } }
+%    \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.
+%    \begin{macrocode}
+\cs_new:Npn \@@_convert_rgb_cmyk:w #1 ~ #2 ~ #3 ~ #4 \s_@@_stop
+  {
+    \exp_args:Nf \@@_convert_rgb_cmyk:nnnn
+      { \fp_eval:n { min ( 1 - #1 , 1 - #2 , 1 - #3 ) } } {#1} {#2} {#3}
+  }
+\cs_new:Npn \@@_convert_rgb_cmyk:nnnn #1#2#3#4
+  {
+    \fp_eval:n { min ( 1 , max ( 0 , 1 - #2 - #1 ) ) } \c_space_tl
+    \fp_eval:n { min ( 1 , max ( 0 , 1 - #3 - #1 ) ) } \c_space_tl
+    \fp_eval:n { min ( 1 , max ( 0 , 1 - #4 - #1 ) ) } \c_space_tl
+    #1
+  }
+\cs_new:Npn \@@_convert_cmyk_gray:w #1 ~ #2 ~ #3 ~ #4 ~ #5 \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 ~ #5 \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 ) }
+  }
+%    \end{macrocode}
+% \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:nn}
+% \begin{macro}{\@@_parse_gray:n, \@@_parse_std:n}
+% \begin{macro}{\@@_parse_break:w}
+% \begin{macro}{\@@_parse_end:}
+% \begin{macro}[aux, EXP]{\@@_parse_mix:Nnnn, \@@_parse_mix:NVVn}
+% \begin{macro}[aux, EXP]{\@@_parse_mix:nNnn}
+% \begin{macro}[aux, 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:Npx \@@_parse:nN #1#2
+  {
+    \exp_not:N \@@_backend_pickup:N \exp_not:N \l_@@_current_tl
+    \tl_set:Nx \exp_not:c { l_@@_named_ . _tl }
+      { \exp_not:N \@@_model:N \exp_not:N \l_@@_current_tl }
+    \prop_put:NVx \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
+  {
+    \tl_if_exist:cTF { l_@@_named_ #1 _prop }
+      { \@@_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:Nx #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:Nx #2
+          {
+            {#1}
+            { \l_@@_value_tl }
+          }
+      }
+  }
+\cs_new_protected:Npn \@@_parse:Nw #1#2 ! #3 \s_@@_stop
+  {
+    \@@_if_defined:nTF {#2}
+      {
+        \tl_if_blank:nTF {#3}
+          { \@@_parse_set_eq:Nn #1 {#2} }
+          { \@@_parse_loop_init:Nnn #1 {#2} {#3} }
+      }
+      {
+        \__kernel_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:Nx \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
+  {
+    \bool_lazy_or:nnF
+      { \tl_if_blank_p:n {#1} }
+      { \int_compare_p:nNn {#1} = { 100 } }
+      {
+        \int_compare:nNnTF {#1} = { 0 }
+          {
+            \tl_if_blank:nTF {#2}
+              { \@@_extract:nNN { white } }
+              { \@@_extract:nNN {#2} }
+                \l_@@_model_tl \l_@@_value_tl
+          }
+          {
+            \use:x
+              {
+                \@@_parse_loop:nn {#1}
+                  { \tl_if_blank:nTF {#2} { white } {#2} }
+              }
+          }
+      }
+    \tl_if_blank:nF {#3}
+      { \@@_parse_loop:w #3 ! #4 ! #5 \s_@@_stop }
+    \@@_parse_end:
+  }
+%    \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
+  {
+    \@@_if_defined: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:Nx \l_@@_value_tl
+          {
+            \@@_parse_mix:NVVn
+              \l_@@_model_tl \l_@@_value_tl \l_@@_next_value_tl {#1}
+          }
+      }
+      {
+        \__kernel_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}
+%
+% \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 {#1 / 240} }
+      { \fp_eval:n {#2 / 240} }
+      { \fp_eval:n {#3 / 240} }
+  }
+\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}
+%
+% \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:Nx #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}{\@@_select:}
+%   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:Npx \@@_select:
+  {
+    \tl_set:Nx \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:NVx \exp_not:c { l_@@_named_ . _prop }
+      \exp_not:c { l_@@_named_ . _tl }
+      { \exp_not:N \@@_values:N \exp_not:N \l_@@_current_tl }
+    \@@_select: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
+    \@@_select:
+  }
+\cs_new_protected:Npn \color_select:nn #1#2
+  {
+    \@@_select_main:Nw \l_@@_current_tl
+      #1 / / \s_@@_mark #2 / / \s_@@_stop
+    \@@_select:
+  }
+%    \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:Nx #3
+          { \use:c { @@_parse_model_ #1 :w } #2 , 0 , 0 , 0 , 0 \s_@@_stop }
+      }
+      { \__kernel_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:Nx #1
+      { { \l_color_fixed_model_tl } { \l_@@_value_tl } }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \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} }
+%    \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}
+% \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:cx { l_@@_named_ #1 _tl }
+          { \@@_model:N \l_@@_named_tl }
+        \prop_clear_new:c { l_@@_named_ #1 _prop }
+        \prop_put:cvx { 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:
+                  \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:cxx { l_@@_named_ #1 _prop }
+                  { \@@_model:N \l_@@_internal_tl }
+                  { \@@_values:N \l_@@_internal_tl }
+              }
+          }
+      }
+  }
+\cs_new_protected:Npx \color_set:nnn #1#2#3
+  {
+    \exp_not:N \str_if_eq:nnF {#1} { . }
+      {
+        \tl_clear_new:c { l_@@_named_ #1 _tl }
+        \prop_clear_new:c { l_@@_named_ #1 _prop }
+        \exp_not:N \@@_set_colon:nnw {#1} {#3}
+          #2 \c_colon_str \c_colon_str \exp_not:N \s_@@_stop
+      }
+  }
+\use:x
+  {
+    \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:Nx \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:cVx { 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
+  {
+    \@@_if_defined: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:cx { l_@@_named_ #1 _tl }
+              { \@@_model:N \l_@@_current_tl }
+            \prop_put:cvx { 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 }
+          }
+      }
+      {
+        \__kernel_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:cx { 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 }
+      {
+        \__kernel_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_HTML_tl           ,
+%     \c_@@_export_space-sep-cmyk_tl ,
+%     \c_@@_export_space-sep-rgb_tl
+%   }
+%    \begin{macrocode}
+\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_space-sep-cmyk:nnN}
+% \begin{macro}{\@@_export_space-sep-cmyk:Nw}
+%    \begin{macrocode}
+\cs_new_protected:cpx { @@_export_format_space-sep-cmyk:nnN } #1#2#3
+  {
+    \exp_not:N \@@_export:nnnNN { cmyk } {#1} {#2} #3
+      \exp_not:c { @@_export_space-sep-cmyk:Nw }
+  }
+\cs_new_protected:cpn { @@_export_space-sep-cmyk:Nw } #1#2 \s_@@_stop
+  { \tl_set:Nx #1 {#2} }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     \@@_export_format_HTML:nnN          ,
+%     \@@_export_format_space-sep-rgb:nnN
+%   }
+% \begin{macro}
+%   {
+%     \@@_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:Npn \@@_export_format_HTML:nnN #1#2#3
+  { \@@_export:nnnNN { rgb } {#1} {#2}#3 \@@_export_HTML:Nw }
+\cs_new_protected:cpx { @@_export_format_space-sep-rgb:nnN } #1#2#3
+  {
+    \exp_not:N \@@_export:nnnNN { rgb } {#1} {#2} #3
+      \exp_not:c { @@_export_space-sep-rgb:Nw }
+  }
+\cs_new_protected:Npn \@@_export_HTML:Nw #1#2 ~ #3 ~ #4 \s_@@_stop
+  {
+    \tl_set:Nx #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 }
+      { \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:Nx #1 {#2} }
+%    \end{macrocode}
+% \end{macro}
+% \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}
+%   Conversion from Separation or DeviceN spaces may not be possible; have
+%   a fallback to black.
+%    \begin{macrocode}
+\tl_const:Nn \c_@@_fallback_cmyk_tl { 0 ~ 0 ~ 0 ~ 1 }
+\tl_const:Nn \c_@@_fallback_gray_tl { 1 }
+\tl_const:Nn \c_@@_fallback_rgb_tl { 1 ~ 1 ~ 1 }
+%    \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_foldcase:n {#2} } {#3}
+  }
+\cs_new_protected:Npn \@@_model_new:nnn #1#2#3
+  {
+    \cs_if_exist:cTF { @@_parse_model_ #1 :w }
+      {
+        \__kernel_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}
+          }
+          {
+            \__kernel_msg_error:nnn { color } { unknown-model-type } {#2}
+          }
+      }
+  }
+%    \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}
+      }
+      {
+        \__kernel_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}
+      }
+      {
+        \__kernel_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}
+          }
+          {
+            \__kernel_msg_error:nnn { color }
+              { separation-alternative-values } {#2}
+          }
+      }
+      {
+        \__kernel_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
+  {
+    \int_gincr:N \g_@@_model_int
+    \tl_const:cn { c_@@_fallback_ #6 _tl } { 1 }
+    \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} } }
+    \clist_map_inline:nn { fill , stroke , select }
+      {
+        \cs_new_protected:cpx { @@_backend_ ##1 _ #6 :n } ####1
+          {
+            \exp_not:c { @@_backend_ ##1 _ separation:nn }
+              { color \int_use:N \g_@@_model_int } {####1}
+          }
+      }
+    \use:c { @@_model_separation_ #8 :nnnnnn }
+      {#6} {#7} {#1} {#2} {#3} {#4}
+    \prop_gput:Nnn \g_@@_alternative_model_prop {#6} {#8}
+    \prop_gput:Nnx \g_@@_colorants_prop {#6}
+      { \str_convert_pdfname:n {#7} }
+    \cs_new_protected:cpx { @@_model_ #6 _white: }
+      {
+        \prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#6} { 0 }
+        \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0
+          { \group_insert_after:N \exp_not:c { @@_model_ #6 _ white: } }
+      }
+    \use:c { @@_model_ #6 _white: }
+  }
+\cs_new_protected:Npn \@@_model_separation_cmyk:nnnnnn #1#2#3#4#5#6
+  {
+    \cs_new:cpn { @@_convert_ #1 _cmyk:w } ##1 ~ ##2 \s_@@_stop
+      {
+         \fp_eval:n {##1 * #3} ~
+         \fp_eval:n {##1 * #4} ~
+         \fp_eval:n {##1 * #5} ~
+         \fp_eval:n {##1 * #6}
+      }
+    \@@_model_convert:nnn {#1} { cmyk } { rgb }
+    \@@_model_convert:nnn {#1} { cmyk } { gray }
+    \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
+  {
+    \cs_new:cpn { @@_convert_ #1 _rgb:w } ##1 ~ ##2 \s_@@_stop
+      {
+         \fp_eval:n {##1 * #3} ~
+         \fp_eval:n {##1 * #4} ~
+         \fp_eval:n {##1 * #5}
+      }
+    \@@_model_convert:nnn {#1} { rgb } { cmyk }
+    \@@_model_convert:nnn {#1} { rgb } { gray }
+    \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
+  {
+    \cs_new:cpn { @@_convert_ #1 _cmyk:w } ##1 ~ ##2 \s_@@_stop
+      {
+        \fp_eval:n {##1 * #3} ~
+        \fp_eval:n {##1 * #3} ~
+        \fp_eval:n {##1 * #3} ~
+        \fp_eval:n {##1 * #3}
+      }
+    \cs_new:cpn { @@_convert_ #1 _gray:w } ##1 ~ ##2 \s_@@_stop
+      { \fp_eval:n {##1 * #3} }
+    \cs_new:cpn { @@_convert_ #1 _rgb:w } ##1 ~ ##2 \s_@@_stop
+      {
+        \fp_eval:n {##1 * #3} ~
+        \fp_eval:n {##1 * #3} ~
+        \fp_eval:n {##1 * #3}
+      }
+    \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:cpx { @@_convert_ #1 _ #3 :w } ##1 ~ ##2 \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 ~ ##2 \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
+      {
+        \__kernel_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: 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 }
+        \cs_new:cpn { @@_convert_ #2 _cmyk:w } ##1 ~ ##2 \s_@@_stop
+          { 0 ~ 0 ~ 0 ~ 1 }
+        \cs_new:cpn { @@_convert_ #2 _rgb:w } ##1 ~ ##2 \s_@@_stop
+          { 1 ~ 1 ~ 1 }
+        \cs_new:cpn { @@_convert_ #2 _gray:w } ##1 ~ ##2 \s_@@_stop
+          { 1 }
+      }
+      {
+        \__kernel_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}
+      }
+      {
+        \__kernel_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
+                  {
+                    \__kernel_msg_error:nnn { color }
+                      { DeviceN-inconsistent-alternative }
+                      {#2}
+                    \clist_map_break:n { \use_none:nnnn }
+                  }
+               }
+          }
+          {
+            \str_if_eq:nnF {##1} { none }
+              {
+                \__kernel_msg_error:nnn { color }
+                  { DeviceN-no-alternative }
+                  {#2}
+              }
+          }
+      }
+    \tl_if_empty:NTF \l_@@_model_tl
+      {
+        \__kernel_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:Nx \@@_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
+  {
+    \int_gincr:N \g_@@_model_int
+    \tl_const:cx { c_@@_fallback_ #4 _tl }
+      { \prg_replicate:nn {#1} { 1 ~ } }
+    \cs_if_exist_use:cF { @@_model_devicen_parse_ #1 :nn }
+      { \@@_model_devicen_parse_generic:nn }
+        {#4} {#1}
+    \clist_map_inline:nn { fill , stroke , select }
+      {
+        \cs_new_protected:cpx { @@_backend_ ##1 _ #4 :n } ####1
+          {
+            \exp_not:c { @@_backend_ ##1 _ devicen:nn }
+              { color \int_use:N \g_@@_model_int } {####1}
+          }
+      }
+    \cs_new_protected:cpx { @@_model_ #4 _white: }
+      {
+        \prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#4}
+          { \prg_replicate:nn {#1} { 0 ~ } }
+        \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0
+          { \group_insert_after:N \exp_not:c { @@_model_ #4 _ white: } }
+      }
+    \use:c { @@_model_ #4 _white: }
+    \@@_model_devicen_init:nnn {#1} {#2} {#3}
+    \@@_model_devicen_convert:nnn {#4} {#2} {#3}
+  }
+%    \end{macrocode}
+%   For short lists of DeviceN colors, wee 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:cpx { @@_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:Nx \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:Nx \l_@@_internal_tl
+      {
+        \prg_replicate:nn {#1}
+          { neg ~ 1.0 ~ add ~ #1 ~ -1 ~ roll ~ }
+        \int_eval:n { #2 + 4 } ~ 4 ~ roll
+        \prg_replicate:nn {#2} { ~ pop }
+      }
+    \use:x
+      {
+        \@@_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 { #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:Nx \l_@@_internal_tl
+      {
+        \fp_compare:nNnF {#3} = \c_zero_fp
+          {
+            \int_eval:n { #1 - \l_@@_internal_int + #2 } ~ index ~
+              #3 ~ neg ~ 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:nnn #1#2#3
+  {
+    \use:c { @@_model_devicen_convert_ #2 :nn } {#1} {#3}
+  }
+\cs_new_protected:Npn \@@_model_devicen_convert_cmyk:nn #1#2
+  {
+    \@@_model_convert:nnn {#1} { cmyk } { gray }
+    \@@_model_convert:nnn {#1} { cmyk } { rgb }
+    \@@_model_devicen_convert:nnnn {#1} { cmyk } { 4 } {#2}
+  }
+\cs_new_protected:Npn \@@_model_devicen_convert_gray:nn #1#2
+  {
+    \@@_model_convert:nnn {#1} { gray } { cmyk }
+    \@@_model_convert:nnn {#1} { gray } { rgb }
+    \@@_model_devicen_convert:nnnn {#1} { gray } { 1 } {#2}
+  }
+\cs_new_protected:Npn \@@_model_devicen_convert_rgb:nn #1#2
+  {
+    \@@_model_convert:nnn {#1} { rgb } { cmyk }
+    \@@_model_convert:nnn {#1} { rgb } { gray }
+    \@@_model_devicen_convert:nnnn {#1} { rgb } { 3 } {#2}
+  }
+\cs_new_protected:Npn \@@_model_devicen_convert:nnnn #1#2#3#4
+  {
+    \cs_new:cpx { @@_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_cmyk:nnnnnn {#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}
+%
+% \subsection{Diagnostics}
+%
+% \begin{macro}{\color_show:n}
+% \begin{macro}{\@@_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 #1
+  {
+    \msg_show:nnxxxx { LaTeX / color } { show }
+      {#1}
+      {
+        \@@_if_defined:nT {#1}
+          {
+            \exp_args:Nv \@@_show:n { l_@@_named_ #1 _tl }
+            \prop_map_function:cN
+              { l_@@_named_ #1 _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}
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\__kernel_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


Property changes on: trunk/Master/texmf-dist/source/latex/l3kernel/l3color.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -79,7 +79,7 @@
 %
 % \title{The \cls{l3doc} class}
 % \author{\Team}
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 % \maketitle
 % \tableofcontents
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -63,7 +63,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 % \maketitle
 %
 % \begin{documentation}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 % \maketitle
 %
 % \begin{documentation}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -49,7 +49,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -444,6 +444,34 @@
 %   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:nnxxxx ,
+%     \msg_show:nnxxx  ,
+%     \msg_show:nnxx   ,
+%     \msg_show:nnx
+%   }
+%   \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}
+%
 % \subsection{Expandable error messages}
 %
 % In very rare cases it may be necessary to produce errors in an

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Added: trunk/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -0,0 +1,458 @@
+% \iffalse meta-comment
+%
+%% File: l3pdf.dtx
+%
+% 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
+%
+%    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} package\\ Core PDF support^^A
+% }
+%
+% \author{^^A
+%  The \LaTeX{} Project\thanks
+%    {^^A
+%      E-mail:
+%        \href{mailto:latex-team at latex-project.org}
+%          {latex-team at latex-project.org}^^A
+%    }^^A
+% }
+%
+% \date{Released 2021-02-18}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{\pkg{l3pdf} documentation}
+%
+% \subsection{Objects}
+%
+% \begin{function}[added = 2021-02-10]{\pdf_object_new:nn}
+%   \begin{syntax}
+%     \cs{pdf_object_new:nn} \Arg{object} \Arg{type}
+%   \end{syntax}
+%   Declares \meta{object} as a PDF object of \meta{type}, which should be
+%   one of
+%   \begin{itemize}
+%     \item \texttt{array}
+%     \item \texttt{dict}
+%     \item \texttt{fstream}
+%     \item \texttt{stream}
+%   \end{itemize}
+%   The object may be referenced from this point on, and written later
+%   using \cs{pdf_object_write:nn}.
+% \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}
+%   \end{syntax}
+%   Tests whether an object with name \Arg{object} has been defined.
+% \end{function}
+% \begin{function}[added = 2021-02-10]
+%   {\pdf_object_write:nn, \pdf_object_write:nx}
+%   \begin{syntax}
+%     \cs{pdf_object_write:nn} \Arg{object} \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
+% \end{function}
+%
+% \begin{function}[added = 2021-02-10]
+%   {\pdf_object_unnamed_write:nn, \pdf_object_unnamed_write:nx}
+%   \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{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_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}
+%
+% \subsection{Version}
+%
+% \begin{function}[pTF, EXP, added = 2021-02-10]{\pdf_version_compare:Nn}
+%   \begin{syntax}
+%     \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.
+% \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}
+%
+% \subsection{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}
+%
+% \subsection{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{variable}{\s_@@_stop}
+%   Internal scan marks.
+%    \begin{macrocode}
+\scan_new:N \s_@@_stop
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_init_bool}
+%   A flag 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 at finalise@setup@@@@ }
+  {
+    \tl_gput_right:Nn \@expl at finalise@setup@@@@
+      {
+        \tl_gput_right:Nn \@kernel at 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{macro}{\pdf_object_new:nn, \pdf_object_write:nn, \pdf_object_write:nx}
+% \begin{macro}[pTF]{\pdf_object_if_exist:n}
+% \begin{macro}{\pdf_object_ref:n}
+% \begin{macro}{\pdf_object_unnamed_write:nn, \pdf_object_unnamed_write:nx}
+% \begin{macro}{\pdf_object_ref_last:}
+%   Simple to do.
+%    \begin{macrocode}
+\cs_new_protected:Npn \pdf_object_new:nn #1#2
+  { \@@_backend_object_new:nn {#1} {#2} }
+\prg_new_conditional:Npnn \pdf_object_if_exist:n #1 { p , T , F , TF }
+  {
+    \int_if_exist:cTF { c_@@_backend_object_ \tl_to_str:n {#1} _int }
+     { \prg_return_true: }
+     { \prg_return_false:}
+  }
+\cs_new_protected:Npn \pdf_object_write:nn #1#2
+  {
+    \@@_backend_object_write:nn {#1} {#2}
+    \bool_gset_true:N \g_@@_init_bool
+  }
+\cs_generate_variant:Nn \pdf_object_write:nn { nx }
+\cs_new:Npn \pdf_object_ref:n #1 { \@@_backend_object_ref:n {#1} }
+\cs_new_protected:Npn \pdf_object_unnamed_write:nn #1#2
+  {
+    \@@_backend_object_now:nn {#1} {#2}
+    \bool_gset_true:N \g_@@_init_bool
+  }
+\cs_generate_variant:Nn \pdf_object_unnamed_write:nn { nx }
+\cs_new:Npn \pdf_object_ref_last: { \@@_backend_object_last: }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \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}{\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{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}
+%    \begin{macrocode}
+%</package>
+%    \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex


Property changes on: trunk/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -7033,6 +7033,13 @@
   }
 %    \end{macrocode}
 %
+% Some escaped alphanumerics are not allowed everywhere.
+%    \begin{macrocode}
+\__kernel_msg_new:nnnn { kernel } { backwards-quantifier }
+  { Quantifer~"{#1,#2}"~is~backwards. }
+  { The~values~given~in~a~quantifier~must~be~in~order. }
+%    \end{macrocode}
+%
 % Used when showing a regex.
 %    \begin{macrocode}
 \__kernel_msg_new:nnn { kernel } { show-regex }

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -106,6 +106,8 @@
 %     \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}
@@ -317,6 +319,17 @@
 \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}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3text.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3text.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3text.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %
@@ -107,6 +107,7 @@
 %   function name. The category code of letters are not changed by this
 %   process (at least where they can be represented by the engine as a single
 %   token: $8$-bit engines may require 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
@@ -194,7 +195,6 @@
 %  \cs{l_text_titlecase_check_letter_bool} is \texttt{false}, the first
 %  character is uppercased, and the rest lowercased, irrespective of the nature
 %  of the character.
-% \end{function}
 %
 % \subsection{Removing formatting from text}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-06}
+% \date{Released 2021-02-18}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def	2021-02-18 22:17:56 UTC (rev 57789)
@@ -26,7 +26,7 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-dvipdfmx.def}{2021-02-06}{}
+  {l3backend-dvipdfmx.def}{2021-02-18}{}
   {L3 backend support: dvipdfmx}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
@@ -128,7 +128,7 @@
   }
 \int_compare:nNnF \c__kernel_sys_dvipdfmx_version_int < { 20201111 }
   {
-    \cs_new_protected:Npn \__color_backend_stack_push:nn #1#2
+    \cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2
       {
         \__kernel_backend_literal:x
           {
@@ -137,8 +137,8 @@
             push ~ (#2)
           }
       }
-    \cs_generate_variant:Nn \__color_backend_stack_push:nn { nx }
-    \cs_new_protected:Npn \__color_backend_stack_pop:n #1
+    \cs_generate_variant:Nn \__kernel_color_backend_stack_push:nn { nx }
+    \cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1
       {
         \__kernel_backend_literal:x
           {
@@ -160,11 +160,11 @@
   {
     \tl_set:Nn \l__color_backend_fill_tl {#1}
     \tl_set:Nn \l__color_backend_stroke_tl {#2}
-    \__color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 }
+    \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 }
     \group_insert_after:N \__color_backend_reset:
   }
 \cs_new_protected:Npn \__color_backend_reset:
-  { \__color_backend_stack_pop:n \l__color_backend_stack_int }
+  { \__kernel_color_backend_stack_pop:n \l__color_backend_stack_int }
 \int_compare:nNnT \c__kernel_sys_dvipdfmx_version_int < { 20201111 }
   {
     \cs_gset_protected:Npn \__color_backend_select_cmyk:n #1
@@ -182,7 +182,7 @@
 \cs_new_eq:NN \__color_backend_select_devicen:nn \__color_backend_select_separation:nn
 \cs_new_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5
   {
-    \pdf_object_now:nx { dict }
+    \pdf_object_unnamed_write:nx { dict }
       {
         /FunctionType ~ 2
         /Domain ~ [0 ~ 1]
@@ -194,21 +194,22 @@
       {
         /Separation ~
         / \str_convert_pdfname:n {#1} ~ #2 ~
-        \pdf_object_last:
+        \pdf_object_ref_last:
       }
-    \use:x
+    \cs_if_exist:NT \pdfmanagement_add:nnn
       {
-        \pdfmanagement_add:nnn
-          { Page / Resources / ColorSpace }
-          { color \int_use:N \g__color_model_int }
-          { \pdf_object_last: }
+        \use:x
+          {
+            \pdfmanagement_add:nnn
+              { Page / Resources / ColorSpace }
+              { color \int_use:N \g__color_model_int }
+              { \pdf_object_ref_last: }
+          }
       }
   }
-\cs_if_exist:NF \pdf_object_now:nn
-  { \cs_gset_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5 { } }
 \cs_new_protected:Npn \__color_backend_separation_init:n #1
   {
-    \pdf_object_now:nx { array } {#1}
+    \pdf_object_unnamed_write:nx { array } {#1}
   }
 \cs_new_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
   {
@@ -232,7 +233,7 @@
       { 100 ~ 0 ~ 0 }
       {#3}
   }
-\cs_if_exist:NF \pdf_object_now:nn
+\cs_if_exist:NF \pdf_object_unnamed_write:nn
   {
     \cs_gset_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
       { }
@@ -239,7 +240,7 @@
   }
 \cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3
   {
-    \pdf_object_now:nx { stream }
+    \pdf_object_unnamed_write:nx { stream }
       {
         {
           /FunctionType ~ 4 ~
@@ -266,18 +267,19 @@
         /DeviceN ~
         [ ~ #1 ~ ] ~
         #2 ~
-        \pdf_object_last:
+        \pdf_object_ref_last:
       }
-    \use:x
+    \cs_if_exist:NT \pdfmanagement_add:nnn
       {
-        \pdfmanagement_add:nnn
-          { Page / Resources / ColorSpace }
-          { color \int_use:N \g__color_model_int }
-          { \pdf_object_last: }
+        \use:x
+          {
+            \pdfmanagement_add:nnn
+              { Page / Resources / ColorSpace }
+              { color \int_use:N \g__color_model_int }
+              { \pdf_object_ref_last: }
+          }
       }
   }
-\cs_if_exist:NF \pdf_object_now:nn
-  { \cs_gset_protected:Npn \__color_backend_devicen_init:nnn #1#2#3 { } }
 \cs_new:Npn \__color_backend_devicen_init:w #1 ~ #2 \s__color_stop
   {
     + 1
@@ -300,7 +302,7 @@
 \cs_new_protected:Npn \__color_backend_fill:n #1
   {
     \tl_set:Nn \l__color_backend_fill_tl {#1}
-    \__color_backend_stack_push:nn \l__color_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int
       { #1 ~ \l__color_backend_stroke_tl }
     \group_insert_after:N \__color_backend_reset:
   }
@@ -313,7 +315,7 @@
 \cs_new_protected:Npn \__color_backend_stroke:n #1
   {
     \tl_set:Nn \l__color_backend_stroke_tl {#1}
-    \__color_backend_stack_push:nn \l__color_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int
       { \l__color_backend_fill_tl \c_space_tl #1 }
     \group_insert_after:N \__color_backend_reset:
   }
@@ -902,7 +904,7 @@
     \pdfmanagement_add:nnn { Page / Resources / ExtGState }
       { opacity #1 }
       { << /ca ~ #1 /CA ~ #1 >> }
-    \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int
       { /opacity #1 ~ gs }
     \group_insert_after:N \__opacity_backend_reset:
   }
@@ -911,7 +913,7 @@
     \cs_gset_protected:Npn \__opacity_backend_select_aux:n #1 { }
   }
 \cs_new_protected:Npn \__opacity_backend_reset:
- { \__opacity_backend_stack_pop:n \c__opacity_backend_stack_int }
+ { \__kernel_color_backend_stack_pop:n \c__opacity_backend_stack_int }
 \cs_new_protected:Npn \__opacity_backend_fill:n #1
   {
     \__opacity_backend_fill_stroke:xx
@@ -937,7 +939,7 @@
         \pdfmanagement_add:nnn { Page / Resources / ExtGState }
           { opacity.stroke #1 }
           { << /CA ~ #2 >> }
-        \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int
+        \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int
          { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs }
         \group_insert_after:N \__opacity_backend_reset:
       }

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def	2021-02-18 22:17:56 UTC (rev 57789)
@@ -26,7 +26,7 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-dvips.def}{2021-02-06}{}
+  {l3backend-dvips.def}{2021-02-18}{}
   {L3 backend support: dvips}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def	2021-02-18 22:17:56 UTC (rev 57789)
@@ -26,7 +26,7 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-dvisvgm.def}{2021-02-06}{}
+  {l3backend-dvisvgm.def}{2021-02-18}{}
   {L3 backend support: dvisvgm}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def	2021-02-18 22:17:56 UTC (rev 57789)
@@ -26,7 +26,7 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-luatex.def}{2021-02-06}{}
+  {l3backend-luatex.def}{2021-02-18}{}
   {L3 backend support: PDF output (LuaTeX)}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
@@ -114,13 +114,13 @@
         {#3}
       }
   }
-\cs_new_protected:Npn \__color_backend_stack_push:nn #1#2
+\cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2
   {
     \tex_pdfextension:D colorstack ~
       \int_eval:n {#1} ~ push ~ {#2}
   }
-\cs_generate_variant:Nn \__color_backend_stack_push:nn { nx }
-\cs_new_protected:Npn \__color_backend_stack_pop:n #1
+\cs_generate_variant:Nn \__kernel_color_backend_stack_push:nn { nx }
+\cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1
   {
     \tex_pdfextension:D colorstack ~
       \int_eval:n {#1} ~ pop \scan_stop:
@@ -137,17 +137,17 @@
   {
     \tl_set:Nn \l__color_backend_fill_tl {#1}
     \tl_set:Nn \l__color_backend_stroke_tl {#2}
-    \__color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 }
+    \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 }
     \group_insert_after:N \__color_backend_reset:
   }
 \cs_new_protected:Npn \__color_backend_reset:
-  { \__color_backend_stack_pop:n \l__color_backend_stack_int }
+  { \__kernel_color_backend_stack_pop:n \l__color_backend_stack_int }
 \cs_new_protected:Npn \__color_backend_select_separation:nn #1#2
   { \__color_backend_select:nn { /#1 ~ cs ~ #2 ~ scn  } { /#1 ~ CS ~ #2 ~ SCN } }
 \cs_new_eq:NN \__color_backend_select_devicen:nn \__color_backend_select_separation:nn
 \cs_new_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5
   {
-    \pdf_object_now:nx { dict }
+    \pdf_object_unnamed_write:nx { dict }
       {
         /FunctionType ~ 2
         /Domain ~ [0 ~ 1]
@@ -159,21 +159,22 @@
       {
         /Separation ~
         / \str_convert_pdfname:n {#1} ~ #2 ~
-        \pdf_object_last:
+        \pdf_object_ref_last:
       }
-    \use:x
+    \cs_if_exist:NT \pdfmanagement_add:nnn
       {
-        \pdfmanagement_add:nnn
-          { Page / Resources / ColorSpace }
-          { color \int_use:N \g__color_model_int }
-          { \pdf_object_last: }
+        \use:x
+          {
+            \pdfmanagement_add:nnn
+              { Page / Resources / ColorSpace }
+              { color \int_use:N \g__color_model_int }
+              { \pdf_object_ref_last: }
+          }
       }
   }
-\cs_if_exist:NF \pdf_object_now:nn
-  { \cs_gset_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5 { } }
 \cs_new_protected:Npn \__color_backend_separation_init:n #1
   {
-    \pdf_object_now:nx { array } {#1}
+    \pdf_object_unnamed_write:nx { array } {#1}
   }
 \cs_new_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
   {
@@ -197,7 +198,7 @@
       { 100 ~ 0 ~ 0 }
       {#3}
   }
-\cs_if_exist:NF \pdf_object_now:nn
+\cs_if_exist:NF \pdf_object_unnamed_write:nn
   {
     \cs_gset_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
       { }
@@ -204,7 +205,7 @@
   }
 \cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3
   {
-    \pdf_object_now:nx { stream }
+    \pdf_object_unnamed_write:nx { stream }
       {
         {
           /FunctionType ~ 4 ~
@@ -231,18 +232,19 @@
         /DeviceN ~
         [ ~ #1 ~ ] ~
         #2 ~
-        \pdf_object_last:
+        \pdf_object_ref_last:
       }
-    \use:x
+    \cs_if_exist:NT \pdfmanagement_add:nnn
       {
-        \pdfmanagement_add:nnn
-          { Page / Resources / ColorSpace }
-          { color \int_use:N \g__color_model_int }
-          { \pdf_object_last: }
+        \use:x
+          {
+            \pdfmanagement_add:nnn
+              { Page / Resources / ColorSpace }
+              { color \int_use:N \g__color_model_int }
+              { \pdf_object_ref_last: }
+          }
       }
   }
-\cs_if_exist:NF \pdf_object_now:nn
-  { \cs_gset_protected:Npn \__color_backend_devicen_init:nnn #1#2#3 { } }
 \cs_new:Npn \__color_backend_devicen_init:w #1 ~ #2 \s__color_stop
   {
     + 1
@@ -259,7 +261,7 @@
 \cs_new_protected:Npn \__color_backend_fill:n #1
   {
     \tl_set:Nn \l__color_backend_fill_tl {#1}
-    \__color_backend_stack_push:nn \l__color_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int
       { #1 ~ \l__color_backend_stroke_tl }
     \group_insert_after:N \__color_backend_reset:
   }
@@ -272,7 +274,7 @@
 \cs_new_protected:Npn \__color_backend_stroke:n #1
   {
     \tl_set:Nn \l__color_backend_stroke_tl {#1}
-    \__color_backend_stack_push:nn \l__color_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int
       { \l__color_backend_fill_tl \c_space_tl #1 }
     \group_insert_after:N \__color_backend_reset:
   }
@@ -773,7 +775,7 @@
     \pdfmanagement_add:nnn { Page / Resources / ExtGState }
       { opacity #1 }
       { << /ca ~ #1 /CA ~ #1 >> }
-    \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int
       { /opacity #1 ~ gs }
     \group_insert_after:N \__opacity_backend_reset:
   }
@@ -782,7 +784,7 @@
     \cs_gset_protected:Npn \__opacity_backend_select_aux:n #1 { }
   }
 \cs_new_protected:Npn \__opacity_backend_reset:
- { \__opacity_backend_stack_pop:n \c__opacity_backend_stack_int }
+ { \__kernel_color_backend_stack_pop:n \c__opacity_backend_stack_int }
 \cs_new_protected:Npn \__opacity_backend_fill:n #1
   {
     \__opacity_backend_fill_stroke:xx
@@ -808,7 +810,7 @@
         \pdfmanagement_add:nnn { Page / Resources / ExtGState }
           { opacity.stroke #1 }
           { << /CA ~ #2 >> }
-        \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int
+        \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int
          { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs }
         \group_insert_after:N \__opacity_backend_reset:
       }

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def	2021-02-18 22:17:56 UTC (rev 57789)
@@ -26,7 +26,7 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-pdftex.def}{2021-02-06}{}
+  {l3backend-pdftex.def}{2021-02-18}{}
   {L3 backend support: PDF output (pdfTeX)}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
@@ -114,13 +114,13 @@
         {#3}
       }
   }
-\cs_new_protected:Npn \__color_backend_stack_push:nn #1#2
+\cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2
   {
     \tex_pdfcolorstack:D
       \int_eval:n {#1} ~ push ~ {#2}
   }
-\cs_generate_variant:Nn \__color_backend_stack_push:nn { nx }
-\cs_new_protected:Npn \__color_backend_stack_pop:n #1
+\cs_generate_variant:Nn \__kernel_color_backend_stack_push:nn { nx }
+\cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1
   {
     \tex_pdfcolorstack:D
       \int_eval:n {#1} ~ pop \scan_stop:
@@ -137,17 +137,17 @@
   {
     \tl_set:Nn \l__color_backend_fill_tl {#1}
     \tl_set:Nn \l__color_backend_stroke_tl {#2}
-    \__color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 }
+    \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 }
     \group_insert_after:N \__color_backend_reset:
   }
 \cs_new_protected:Npn \__color_backend_reset:
-  { \__color_backend_stack_pop:n \l__color_backend_stack_int }
+  { \__kernel_color_backend_stack_pop:n \l__color_backend_stack_int }
 \cs_new_protected:Npn \__color_backend_select_separation:nn #1#2
   { \__color_backend_select:nn { /#1 ~ cs ~ #2 ~ scn  } { /#1 ~ CS ~ #2 ~ SCN } }
 \cs_new_eq:NN \__color_backend_select_devicen:nn \__color_backend_select_separation:nn
 \cs_new_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5
   {
-    \pdf_object_now:nx { dict }
+    \pdf_object_unnamed_write:nx { dict }
       {
         /FunctionType ~ 2
         /Domain ~ [0 ~ 1]
@@ -159,21 +159,22 @@
       {
         /Separation ~
         / \str_convert_pdfname:n {#1} ~ #2 ~
-        \pdf_object_last:
+        \pdf_object_ref_last:
       }
-    \use:x
+    \cs_if_exist:NT \pdfmanagement_add:nnn
       {
-        \pdfmanagement_add:nnn
-          { Page / Resources / ColorSpace }
-          { color \int_use:N \g__color_model_int }
-          { \pdf_object_last: }
+        \use:x
+          {
+            \pdfmanagement_add:nnn
+              { Page / Resources / ColorSpace }
+              { color \int_use:N \g__color_model_int }
+              { \pdf_object_ref_last: }
+          }
       }
   }
-\cs_if_exist:NF \pdf_object_now:nn
-  { \cs_gset_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5 { } }
 \cs_new_protected:Npn \__color_backend_separation_init:n #1
   {
-    \pdf_object_now:nx { array } {#1}
+    \pdf_object_unnamed_write:nx { array } {#1}
   }
 \cs_new_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
   {
@@ -197,7 +198,7 @@
       { 100 ~ 0 ~ 0 }
       {#3}
   }
-\cs_if_exist:NF \pdf_object_now:nn
+\cs_if_exist:NF \pdf_object_unnamed_write:nn
   {
     \cs_gset_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
       { }
@@ -204,7 +205,7 @@
   }
 \cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3
   {
-    \pdf_object_now:nx { stream }
+    \pdf_object_unnamed_write:nx { stream }
       {
         {
           /FunctionType ~ 4 ~
@@ -231,18 +232,19 @@
         /DeviceN ~
         [ ~ #1 ~ ] ~
         #2 ~
-        \pdf_object_last:
+        \pdf_object_ref_last:
       }
-    \use:x
+    \cs_if_exist:NT \pdfmanagement_add:nnn
       {
-        \pdfmanagement_add:nnn
-          { Page / Resources / ColorSpace }
-          { color \int_use:N \g__color_model_int }
-          { \pdf_object_last: }
+        \use:x
+          {
+            \pdfmanagement_add:nnn
+              { Page / Resources / ColorSpace }
+              { color \int_use:N \g__color_model_int }
+              { \pdf_object_ref_last: }
+          }
       }
   }
-\cs_if_exist:NF \pdf_object_now:nn
-  { \cs_gset_protected:Npn \__color_backend_devicen_init:nnn #1#2#3 { } }
 \cs_new:Npn \__color_backend_devicen_init:w #1 ~ #2 \s__color_stop
   {
     + 1
@@ -259,7 +261,7 @@
 \cs_new_protected:Npn \__color_backend_fill:n #1
   {
     \tl_set:Nn \l__color_backend_fill_tl {#1}
-    \__color_backend_stack_push:nn \l__color_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int
       { #1 ~ \l__color_backend_stroke_tl }
     \group_insert_after:N \__color_backend_reset:
   }
@@ -272,7 +274,7 @@
 \cs_new_protected:Npn \__color_backend_stroke:n #1
   {
     \tl_set:Nn \l__color_backend_stroke_tl {#1}
-    \__color_backend_stack_push:nn \l__color_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int
       { \l__color_backend_fill_tl \c_space_tl #1 }
     \group_insert_after:N \__color_backend_reset:
   }
@@ -773,7 +775,7 @@
     \pdfmanagement_add:nnn { Page / Resources / ExtGState }
       { opacity #1 }
       { << /ca ~ #1 /CA ~ #1 >> }
-    \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int
       { /opacity #1 ~ gs }
     \group_insert_after:N \__opacity_backend_reset:
   }
@@ -782,7 +784,7 @@
     \cs_gset_protected:Npn \__opacity_backend_select_aux:n #1 { }
   }
 \cs_new_protected:Npn \__opacity_backend_reset:
- { \__opacity_backend_stack_pop:n \c__opacity_backend_stack_int }
+ { \__kernel_color_backend_stack_pop:n \c__opacity_backend_stack_int }
 \cs_new_protected:Npn \__opacity_backend_fill:n #1
   {
     \__opacity_backend_fill_stroke:xx
@@ -808,7 +810,7 @@
         \pdfmanagement_add:nnn { Page / Resources / ExtGState }
           { opacity.stroke #1 }
           { << /CA ~ #2 >> }
-        \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int
+        \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int
          { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs }
         \group_insert_after:N \__opacity_backend_reset:
       }

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def	2021-02-18 22:17:56 UTC (rev 57789)
@@ -26,7 +26,7 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-xetex.def}{2021-02-06}{}
+  {l3backend-xetex.def}{2021-02-18}{}
   {L3 backend support: XeTeX}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
@@ -128,7 +128,7 @@
   }
 \int_compare:nNnF \c__kernel_sys_dvipdfmx_version_int < { 20201111 }
   {
-    \cs_new_protected:Npn \__color_backend_stack_push:nn #1#2
+    \cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2
       {
         \__kernel_backend_literal:x
           {
@@ -137,8 +137,8 @@
             push ~ (#2)
           }
       }
-    \cs_generate_variant:Nn \__color_backend_stack_push:nn { nx }
-    \cs_new_protected:Npn \__color_backend_stack_pop:n #1
+    \cs_generate_variant:Nn \__kernel_color_backend_stack_push:nn { nx }
+    \cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1
       {
         \__kernel_backend_literal:x
           {
@@ -160,11 +160,11 @@
   {
     \tl_set:Nn \l__color_backend_fill_tl {#1}
     \tl_set:Nn \l__color_backend_stroke_tl {#2}
-    \__color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 }
+    \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int { #1 ~ #2 }
     \group_insert_after:N \__color_backend_reset:
   }
 \cs_new_protected:Npn \__color_backend_reset:
-  { \__color_backend_stack_pop:n \l__color_backend_stack_int }
+  { \__kernel_color_backend_stack_pop:n \l__color_backend_stack_int }
 \int_compare:nNnT \c__kernel_sys_dvipdfmx_version_int < { 20201111 }
   {
     \cs_gset_protected:Npn \__color_backend_select_cmyk:n #1
@@ -182,7 +182,7 @@
 \cs_new_eq:NN \__color_backend_select_devicen:nn \__color_backend_select_separation:nn
 \cs_new_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5
   {
-    \pdf_object_now:nx { dict }
+    \pdf_object_unnamed_write:nx { dict }
       {
         /FunctionType ~ 2
         /Domain ~ [0 ~ 1]
@@ -194,21 +194,22 @@
       {
         /Separation ~
         / \str_convert_pdfname:n {#1} ~ #2 ~
-        \pdf_object_last:
+        \pdf_object_ref_last:
       }
-    \use:x
+    \cs_if_exist:NT \pdfmanagement_add:nnn
       {
-        \pdfmanagement_add:nnn
-          { Page / Resources / ColorSpace }
-          { color \int_use:N \g__color_model_int }
-          { \pdf_object_last: }
+        \use:x
+          {
+            \pdfmanagement_add:nnn
+              { Page / Resources / ColorSpace }
+              { color \int_use:N \g__color_model_int }
+              { \pdf_object_ref_last: }
+          }
       }
   }
-\cs_if_exist:NF \pdf_object_now:nn
-  { \cs_gset_protected:Npn \__color_backend_separation_init:nnnnn #1#2#3#4#5 { } }
 \cs_new_protected:Npn \__color_backend_separation_init:n #1
   {
-    \pdf_object_now:nx { array } {#1}
+    \pdf_object_unnamed_write:nx { array } {#1}
   }
 \cs_new_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
   {
@@ -232,7 +233,7 @@
       { 100 ~ 0 ~ 0 }
       {#3}
   }
-\cs_if_exist:NF \pdf_object_now:nn
+\cs_if_exist:NF \pdf_object_unnamed_write:nn
   {
     \cs_gset_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
       { }
@@ -239,7 +240,7 @@
   }
 \cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3
   {
-    \pdf_object_now:nx { stream }
+    \pdf_object_unnamed_write:nx { stream }
       {
         {
           /FunctionType ~ 4 ~
@@ -266,18 +267,19 @@
         /DeviceN ~
         [ ~ #1 ~ ] ~
         #2 ~
-        \pdf_object_last:
+        \pdf_object_ref_last:
       }
-    \use:x
+    \cs_if_exist:NT \pdfmanagement_add:nnn
       {
-        \pdfmanagement_add:nnn
-          { Page / Resources / ColorSpace }
-          { color \int_use:N \g__color_model_int }
-          { \pdf_object_last: }
+        \use:x
+          {
+            \pdfmanagement_add:nnn
+              { Page / Resources / ColorSpace }
+              { color \int_use:N \g__color_model_int }
+              { \pdf_object_ref_last: }
+          }
       }
   }
-\cs_if_exist:NF \pdf_object_now:nn
-  { \cs_gset_protected:Npn \__color_backend_devicen_init:nnn #1#2#3 { } }
 \cs_new:Npn \__color_backend_devicen_init:w #1 ~ #2 \s__color_stop
   {
     + 1
@@ -300,7 +302,7 @@
 \cs_new_protected:Npn \__color_backend_fill:n #1
   {
     \tl_set:Nn \l__color_backend_fill_tl {#1}
-    \__color_backend_stack_push:nn \l__color_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int
       { #1 ~ \l__color_backend_stroke_tl }
     \group_insert_after:N \__color_backend_reset:
   }
@@ -313,7 +315,7 @@
 \cs_new_protected:Npn \__color_backend_stroke:n #1
   {
     \tl_set:Nn \l__color_backend_stroke_tl {#1}
-    \__color_backend_stack_push:nn \l__color_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \l__color_backend_stack_int
       { \l__color_backend_fill_tl \c_space_tl #1 }
     \group_insert_after:N \__color_backend_reset:
   }
@@ -948,7 +950,7 @@
     \pdfmanagement_add:nnn { Page / Resources / ExtGState }
       { opacity #1 }
       { << /ca ~ #1 /CA ~ #1 >> }
-    \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int
+    \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int
       { /opacity #1 ~ gs }
     \group_insert_after:N \__opacity_backend_reset:
   }
@@ -957,7 +959,7 @@
     \cs_gset_protected:Npn \__opacity_backend_select_aux:n #1 { }
   }
 \cs_new_protected:Npn \__opacity_backend_reset:
- { \__opacity_backend_stack_pop:n \c__opacity_backend_stack_int }
+ { \__kernel_color_backend_stack_pop:n \c__opacity_backend_stack_int }
 \cs_new_protected:Npn \__opacity_backend_fill:n #1
   {
     \__opacity_backend_fill_stroke:xx
@@ -983,7 +985,7 @@
         \pdfmanagement_add:nnn { Page / Resources / ExtGState }
           { opacity.stroke #1 }
           { << /CA ~ #2 >> }
-        \__opacity_backend_stack_push:nn \c__opacity_backend_stack_int
+        \__kernel_color_backend_stack_push:nn \c__opacity_backend_stack_int
          { /opacity.fill #1 ~ gs /opacity.stroke #2 ~ gs }
         \group_insert_after:N \__opacity_backend_reset:
       }

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3benchmark/l3benchmark.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3benchmark/l3benchmark.sty	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3benchmark/l3benchmark.sty	2021-02-18 22:17:56 UTC (rev 57789)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3benchmark.dtx
 \RequirePackage{expl3}
-\ProvidesExplPackage{l3benchmark}{2021-02-06}{}
+\ProvidesExplPackage{l3benchmark}{2021-02-18}{}
   {L3 Experimental benchmarking}
 \sys_if_engine_luatex:TF
   {

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3bitset/l3bitset.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3bitset/l3bitset.sty	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3bitset/l3bitset.sty	2021-02-18 22:17:56 UTC (rev 57789)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3bitset.dtx
-\ProvidesExplPackage{l3bitset}{2021-02-06}{}
+\ProvidesExplPackage{l3bitset}{2021-02-18}{}
   {L3 Experimental bitset support}
 \cs_new_protected:Npn \bitset_new:N #1
   {

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3draw/l3draw.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3draw/l3draw.sty	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3draw/l3draw.sty	2021-02-18 22:17:56 UTC (rev 57789)
@@ -28,9 +28,8 @@
 %% 
 %% File: l3draw.dtx
 \RequirePackage{expl3}
-\ProvidesExplPackage{l3draw}{2021-02-06}{}
+\ProvidesExplPackage{l3draw}{2021-02-18}{}
   {L3 Experimental core drawing support}
-\RequirePackage { l3color }
 \scan_new:N \s__draw_mark
 \scan_new:N \s__draw_stop
 \quark_new:N \q__draw_recursion_tail

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3graphics/l3graphics.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3graphics/l3graphics.sty	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3graphics/l3graphics.sty	2021-02-18 22:17:56 UTC (rev 57789)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3graphics.dtx
 \RequirePackage{expl3}
-\ProvidesExplPackage{l3graphics}{2021-02-06}{}
+\ProvidesExplPackage{l3graphics}{2021-02-18}{}
   {L3 Experimental graphics inclusion support}
 \ior_new:N \l__graphics_tmp_ior
 \tl_new:N  \l__graphics_tmp_tl

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-format.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-format.sty	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-format.sty	2021-02-18 22:17:56 UTC (rev 57789)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3str-format.dtx
 \RequirePackage{expl3}
-\ProvidesExplPackage{l3str-format}{2021-02-06}{}
+\ProvidesExplPackage{l3str-format}{2021-02-18}{}
   {L3 Experimental string formatting}
 \cs_generate_variant:Nn \use:nn { nf }
 \cs_generate_variant:Nn \use:nnn { fnf }

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3sys-shell/l3sys-shell.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3sys-shell/l3sys-shell.sty	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3sys-shell/l3sys-shell.sty	2021-02-18 22:17:56 UTC (rev 57789)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3sys-shell.dtx
 \RequirePackage{expl3}
-\ProvidesExplPackage{l3sys-shell}{2021-02-06}{}
+\ProvidesExplPackage{l3sys-shell}{2021-02-18}{}
   {L3 Experimental system shell functions}
 \scan_new:N \s__sys_stop
 \quark_new:N \q__sys_nil

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty	2021-02-18 22:17:56 UTC (rev 57789)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: xcoffins.dtx
-\ProvidesExplPackage{xcoffins}{2021-02-06}{}
+\ProvidesExplPackage{xcoffins}{2021-02-18}{}
   {L3 Experimental design level coffins}
 \keys_define:nn { coffin }
   {

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty	2021-02-18 22:17:56 UTC (rev 57789)
@@ -32,7 +32,7 @@
       }%
     \endinput
   }
-\ProvidesExplPackage{l3galley}{2021-02-06}{}
+\ProvidesExplPackage{l3galley}{2021-02-18}{}
   {L3 Experimental galley code}
 \int_new:N \l__galley_tmp_int
 \seq_new:N \g__galley_tmpa_seq

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty	2021-02-18 22:17:56 UTC (rev 57789)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: xgalley.dtx
-\ProvidesExplPackage{xgalley}{2021-02-06}{}
+\ProvidesExplPackage{xgalley}{2021-02-18}{}
   {L3 Experimental galley}
 \RequirePackage{xtemplate,l3galley}
 \clist_new:N \l__galley_tmpa_clist

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex	2021-02-18 22:17:56 UTC (rev 57789)
@@ -45,7 +45,8 @@
 %% l3tl-analysis.dtx  (with options: `package')
 %% l3regex.dtx  (with options: `package')
 %% l3box.dtx  (with options: `package')
-%% l3color-base.dtx  (with options: `package')
+%% l3color.dtx  (with options: `package')
+%% l3pdf.dtx  (with options: `package')
 %% l3coffins.dtx  (with options: `package')
 %% l3luatex.dtx  (with options: `package,tex')
 %% l3unicode.dtx  (with options: `package')
@@ -69,7 +70,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2021-02-06}%
+\def\ExplFileDate{2021-02-18}%
 \begingroup
   \def\next{\endgroup}%
   \expandafter\ifx\csname PackageError\endcsname\relax
@@ -21146,6 +21147,17 @@
 \prop_gput:Nnn \g__str_alias_prop { utf32le } { utf32 }
 \prop_gput:Nnn \g__str_alias_prop { utf32be } { utf32 }
 \prop_gput:Nnn \g__str_alias_prop { hexadecimal } { hex }
+\bool_lazy_any:nTF
+  {
+    \sys_if_engine_luatex_p:
+    \sys_if_engine_xetex_p:
+  }
+  {
+    \prop_gput:Nnn \g__str_alias_prop { default } {  }
+  }
+  {
+    \prop_gput:Nnn \g__str_alias_prop { default } { utf8 }
+  }
 \bool_new:N \g__str_error_bool
 \flag_new:n { str_byte }
 \flag_new:n { str_error }
@@ -26497,6 +26509,9 @@
     missing~right~
     \int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } .
   }
+\__kernel_msg_new:nnnn { kernel } { backwards-quantifier }
+  { Quantifer~"{#1,#2}"~is~backwards. }
+  { The~values~given~in~a~quantifier~must~be~in~order. }
 \__kernel_msg_new:nnn { kernel } { show-regex }
   {
     >~Compiled~regex~
@@ -27218,7 +27233,7 @@
           }
       }
   }
-%% File: l3color-base.dtx
+%% File: l3color.dtx
 \cs_new_eq:NN \color_group_begin: \group_begin:
 \cs_new_eq:NN \color_group_end:   \group_end:
 \cs_new_protected:Npn \color_ensure_current:
@@ -27233,6 +27248,1533 @@
   { \use:c { __color_backend_select_ #1 :n } {#2} }
 \tl_new:N \l__color_current_tl
 \tl_set:Nn \l__color_current_tl { { gray } { 0 } }
+
+\int_new:N \l__color_internal_int
+\tl_new:N \l__color_internal_tl
+\scan_new:N \s__color_mark
+\prg_new_conditional:Npnn \__color_if_defined:n #1 { T, F, TF }
+  {
+    \prop_if_exist:cTF { l__color_named_ #1 _prop }
+      \prg_return_true:
+      \prg_return_false:
+  }
+\cs_new:Npn \__color_model:N #1 { \exp_after:wN \use_i:nn #1 }
+\cs_new:Npn \__color_values:N #1 { \exp_after:wN \use_ii:nn #1 }
+\cs_new_protected:Npn \__color_extract:nNN #1#2#3
+  {
+    \tl_set_eq:Nc #2 { l__color_named_ #1 _tl }
+    \prop_get:cVN { l__color_named_ #1 _prop } #2 #3
+  }
+\cs_generate_variant:Nn \__color_extract:nNN { V }
+\cs_new_protected:Npn \__color_convert:nnN #1#2#3
+  { \__color_convert:nnVN {#1} {#2} #3 #3 }
+\cs_generate_variant:Nn \__color_convert:nnN { VV }
+\cs_new_protected:Npn \__color_convert:nnnN #1#2#3#4
+  {
+    \tl_set:Nx #4
+      {
+        \cs_if_exist:cTF { __color_convert_ #1 _ #2 :w }
+          { \use:c { __color_convert_ #1 _ #2 :w } #3 ~ 0 ~ 0 ~ 0 \s__color_stop }
+          { \use:c { c__color_fallback_ #2 _tl } }
+      }
+  }
+\cs_generate_variant:Nn \__color_convert:nnnN { nV , nnV }
+\cs_new:Npn \__color_convert_gray_rgb:w #1 ~ #2 \s__color_stop
+  { #1 ~ #1 ~ #1 }
+\cs_new:Npn \__color_convert_gray_cmyk:w #1 ~ #2 \s__color_stop
+  { 0 ~ 0 ~ 0 ~ \fp_eval:n { 1 - #1 } }
+\cs_new:Npn \__color_convert_rgb_gray:w #1 ~ #2 ~ #3 ~ #4 \s__color_stop
+  { \fp_eval:n { 0.3 * #1 + 0.59 * #2 + 0.11 * #3 } }
+\cs_new:Npn \__color_convert_rgb_cmyk:w #1 ~ #2 ~ #3 ~ #4 \s__color_stop
+  {
+    \exp_args:Nf \__color_convert_rgb_cmyk:nnnn
+      { \fp_eval:n { min ( 1 - #1 , 1 - #2 , 1 - #3 ) } } {#1} {#2} {#3}
+  }
+\cs_new:Npn \__color_convert_rgb_cmyk:nnnn #1#2#3#4
+  {
+    \fp_eval:n { min ( 1 , max ( 0 , 1 - #2 - #1 ) ) } \c_space_tl
+    \fp_eval:n { min ( 1 , max ( 0 , 1 - #3 - #1 ) ) } \c_space_tl
+    \fp_eval:n { min ( 1 , max ( 0 , 1 - #4 - #1 ) ) } \c_space_tl
+    #1
+  }
+\cs_new:Npn \__color_convert_cmyk_gray:w #1 ~ #2 ~ #3 ~ #4 ~ #5 \s__color_stop
+  { \fp_eval:n { 1 - min ( 1 , 0.3 * #1 + 0.59 * #2 + 0.11 * #3 + #4 ) } }
+\cs_new:Npn \__color_convert_cmyk_rgb:w #1 ~ #2 ~ #3 ~ #4 ~ #5 \s__color_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 ) }
+  }
+\tl_new:N \l__color_model_tl
+\tl_new:N \l__color_value_tl
+\tl_new:N \l__color_next_model_tl
+\tl_new:N \l__color_next_value_tl
+\cs_new_protected:Npx \__color_parse:nN #1#2
+  {
+    \exp_not:N \__color_backend_pickup:N \exp_not:N \l__color_current_tl
+    \tl_set:Nx \exp_not:c { l__color_named_ . _tl }
+      { \exp_not:N \__color_model:N \exp_not:N \l__color_current_tl }
+    \prop_put:NVx \exp_not:c { l__color_named_ . _prop }
+      \exp_not:c { l__color_named_ . _tl }
+      { \exp_not:N \__color_values:N \exp_not:N \l__color_current_tl }
+    \exp_not:N \exp_args:Ne \exp_not:N \__color_parse_aux:nN
+      { \exp_not:N \tl_to_str:n {#1} } #2
+  }
+\cs_new_protected:Npn \__color_parse_aux:nN #1#2
+  {
+    \tl_if_exist:cTF { l__color_named_ #1 _prop }
+      { \__color_parse_set_eq:Nn #2 {#1} }
+      { \__color_parse:Nw #2#1 ! \s__color_stop }
+    \__color_check_model:N #2
+  }
+\cs_new_protected:Npn \__color_parse_set_eq:Nn #1#2
+  {
+    \tl_if_empty:NTF \l_color_fixed_model_tl
+       { \exp_args:Nv \__color_parse_set_eq:nNn { l__color_named_ #2 _tl } }
+       { \exp_args:NV \__color_parse_set_eq:nNn \l_color_fixed_model_tl }
+         #1 {#2}
+  }
+\cs_new_protected:Npn \__color_parse_set_eq:nNn #1#2#3
+  {
+    \prop_get:cnNTF
+      { l__color_named_ #3 _prop } {#1}
+      \l__color_value_tl
+      { \tl_set:Nx #2 { {#1} { \l__color_value_tl } } }
+      {
+        \tl_set_eq:Nc \l__color_model_tl { l__color_named_ #3 _tl }
+        \prop_get:cVN { l__color_named_ #3 _prop } \l__color_model_tl
+          \l__color_value_tl
+         \__color_convert:nnN
+           \l__color_model_tl {#1} \l__color_value_tl
+        \tl_set:Nx #2
+          {
+            {#1}
+            { \l__color_value_tl }
+          }
+      }
+  }
+\cs_new_protected:Npn \__color_parse:Nw #1#2 ! #3 \s__color_stop
+  {
+    \__color_if_defined:nTF {#2}
+      {
+        \tl_if_blank:nTF {#3}
+          { \__color_parse_set_eq:Nn #1 {#2} }
+          { \__color_parse_loop_init:Nnn #1 {#2} {#3} }
+      }
+      {
+        \__kernel_msg_error:nnn { color } { unknown-color } {#2}
+        \tl_set:Nn \l__color_current_tl { { gray } { 0 } }
+      }
+  }
+\cs_new_protected:Npn \__color_parse_loop_init:Nnn #1#2#3
+  {
+    \group_begin:
+      \__color_extract:nNN {#2} \l__color_model_tl \l__color_value_tl
+      \__color_parse_loop:w #3 ! ! ! ! \s__color_stop
+      \tl_set:Nx \l__color_internal_tl
+        { { \l__color_model_tl } { \l__color_value_tl } }
+    \exp_args:NNNV \group_end:
+    \tl_set:Nn #1 \l__color_internal_tl
+  }
+\cs_new_protected:Npn \__color_parse_loop:w #1 ! #2 ! #3 ! #4 ! #5 \s__color_stop
+  {
+    \bool_lazy_or:nnF
+      { \tl_if_blank_p:n {#1} }
+      { \int_compare_p:nNn {#1} = { 100 } }
+      {
+        \int_compare:nNnTF {#1} = { 0 }
+          {
+            \tl_if_blank:nTF {#2}
+              { \__color_extract:nNN { white } }
+              { \__color_extract:nNN {#2} }
+                \l__color_model_tl \l__color_value_tl
+          }
+          {
+            \use:x
+              {
+                \__color_parse_loop:nn {#1}
+                  { \tl_if_blank:nTF {#2} { white } {#2} }
+              }
+          }
+      }
+    \tl_if_blank:nF {#3}
+      { \__color_parse_loop:w #3 ! #4 ! #5 \s__color_stop }
+    \__color_parse_end:
+  }
+\cs_new_protected:Npn \__color_parse_loop:nn #1#2
+  {
+    \__color_if_defined:nTF {#2}
+      {
+        \__color_extract:nNN {#2} \l__color_next_model_tl \l__color_next_value_tl
+        \tl_if_eq:NNF \l__color_model_tl \l__color_next_model_tl
+          {
+            \str_if_eq:VnTF \l__color_model_tl { gray }
+              { \__color_parse_gray:n {#2} }
+              { \__color_parse_std:n {#2} }
+          }
+        \tl_set:Nx \l__color_value_tl
+          {
+            \__color_parse_mix:NVVn
+              \l__color_model_tl \l__color_value_tl \l__color_next_value_tl {#1}
+          }
+      }
+      {
+        \__kernel_msg_error:nnn { color } { unknown-color } {#2}
+        \__color_extract:nNN { black } \l__color_model_tl \l__color_value_tl
+        \__color_parse_break:w
+      }
+  }
+\cs_new_protected:Npn \__color_parse_gray:n #1
+  {
+    \tl_set_eq:NN \l__color_model_tl \l__color_next_model_tl
+    \tl_set:Nn \l__color_next_model_tl { gray }
+    \exp_args:NnV \__color_convert:nnN { gray } \l__color_model_tl
+      \l__color_value_tl
+    \prop_get:cVN { l__color_named_ #1 _prop } \l__color_model_tl
+      \l__color_next_value_tl
+  }
+\cs_new_protected:Npn \__color_parse_std:n #1
+  {
+    \prop_get:cVNF { l__color_named_ #1 _prop }
+      \l__color_model_tl
+      \l__color_next_value_tl
+        {
+          \__color_convert:VVN
+            \l__color_next_model_tl
+            \l__color_model_tl
+            \l__color_next_value_tl
+        }
+  }
+\cs_new_protected:Npn \__color_parse_break:w #1 \__color_parse_end: { }
+\cs_new_protected:Npn \__color_parse_end: { }
+\cs_new:Npn \__color_parse_mix:Nnnn #1#2#3#4
+  {
+    \exp_args:Nf \__color_parse_mix:nNnn
+      { \fp_eval:n { #4 / 100 } }
+      #1 {#2} {#3}
+  }
+\cs_generate_variant:Nn \__color_parse_mix:Nnnn { NVV }
+\cs_new:Npn \__color_parse_mix:nNnn #1#2#3#4
+  {
+    \use:c { __color_parse_mix_ #2 :nw } {#1}
+      #3 \s__color_mark #4 \s__color_stop
+  }
+\cs_new:Npn \__color_parse_mix_gray:nw #1#2 \s__color_mark #3 \s__color_stop
+  { \fp_eval:n { #2 * #1 + #3 * ( 1 - #1 ) } }
+\cs_new:Npn \__color_parse_mix_rgb:nw
+  #1#2 ~ #3 ~ #4 \s__color_mark #5 ~ #6 ~ #7 \s__color_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 \__color_parse_mix_cmyk:nw
+  #1#2 ~ #3 ~ #4 ~ #5 \s__color_mark #6 ~ #7 ~ #8 ~ #9 \s__color_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 ) }
+  }
+\cs_new:Npn \__color_parse_model_gray:w #1 , #2 \s__color_stop
+  { { gray } { \__color_parse_number:n {#1} } }
+\cs_new:Npn \__color_parse_model_rgb:w #1 , #2 , #3 , #4 \s__color_stop
+  {
+    { rgb }
+    {
+      \__color_parse_number:n {#1} ~
+      \__color_parse_number:n {#2} ~
+      \__color_parse_number:n {#3}
+    }
+  }
+\cs_new:Npn \__color_parse_model_cmyk:w #1 , #2 , #3 , #4 , #5 \s__color_stop
+  {
+    { cmyk }
+    {
+      \__color_parse_number:n {#1} ~
+      \__color_parse_number:n {#2} ~
+      \__color_parse_number:n {#3} ~
+      \__color_parse_number:n {#4}
+    }
+  }
+\cs_new:Npn \__color_parse_number:n #1
+  {  \__color_parse_number:w #1 . 0 . \s__color_stop }
+\cs_new:Npn \__color_parse_number:w #1 . #2 . #3 \s__color_stop
+  { \tl_if_blank:nTF {#1} { 0 } {#1} . #2 }
+\cs_new:Npn \__color_parse_model_Gray:w #1 , #2 \s__color_stop
+  { { gray } { \fp_eval:n { #1 / 15 } } }
+\cs_new:Npn \__color_parse_model_hsb:w #1 , #2 , #3 , #4 \s__color_stop
+  { \__color_parse_model_hsb:nnn {#1} {#2} {#3} }
+\cs_new:Npn \__color_parse_model_Hsb:w #1 , #2 , #3 , #4 \s__color_stop
+  {
+    \exp_args:Ne \__color_parse_model_hsb:nnn { \fp_eval:n { #1 / 360 } }
+      {#2} {#3}
+  }
+\cs_new:Npn \__color_parse_model_hsb:nnn #1#2#3
+  {
+    { rgb }
+    {
+      \exp_args:Ne \__color_parse_model_hsb_aux:nnn
+        { \fp_eval:n { 6 * #1 } } {#2} {#3}
+    }
+  }
+\cs_new:Npn \__color_parse_model_hsb_aux:nnn #1#2#3
+  {
+    \exp_args:Nee \__color_parse_model_hsb_aux:nnnn
+      { \fp_eval:n { floor(#1) } } { \fp_eval:n { #1 - floor(#1) } }
+      {#2} {#3}
+  }
+\cs_new:Npn \__color_parse_model_hsb_aux:nnnn #1#2#3#4
+  {
+    \use:e
+      {
+        \exp_not:N \__color_parse_model_hsb_aux:nnnnn
+         { \__color_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 \__color_parse_model_hsb_aux:nnnnn #1#2#3#4#5
+  { \use:c { __color_parse_model_hsb_ #5 :nnnn } {#1} {#2} {#3} {#4} }
+\cs_new:cpn { __color_parse_model_hsb_0:nnnn } #1#2#3#4 { #1 ~ #4 ~ #2 }
+\cs_new:cpn { __color_parse_model_hsb_1:nnnn } #1#2#3#4 { #3 ~ #1 ~ #2 }
+\cs_new:cpn { __color_parse_model_hsb_2:nnnn } #1#2#3#4 { #2 ~ #1 ~ #4 }
+\cs_new:cpn { __color_parse_model_hsb_3:nnnn } #1#2#3#4 { #2 ~ #3 ~ #1 }
+\cs_new:cpn { __color_parse_model_hsb_4:nnnn } #1#2#3#4 { #4 ~ #2 ~ #1 }
+\cs_new:cpn { __color_parse_model_hsb_5:nnnn } #1#2#3#4 { #1 ~ #2 ~ #3 }
+\cs_new:cpn { __color_parse_model_hsb_6:nnnn } #1#2#3#4 { #1 ~ #2 ~ #2 }
+\cs_new:Npn \__color_parse_model_HSB:w #1 , #2 , #3 , #4 \s__color_stop
+  {
+    \exp_args:Neee \__color_parse_model_hsb:nnn
+      { \fp_eval:n {#1 / 240} }
+      { \fp_eval:n {#2 / 240} }
+      { \fp_eval:n {#3 / 240} }
+  }
+\cs_new:Npn \__color_parse_model_HTML:w #1 , #2 \s__color_stop
+  { \__color_parse_model_HTML_aux:w #1 0 0 0 0 0 0 \s__color_stop }
+\cs_new:Npn \__color_parse_model_HTML_aux:w #1#2#3#4#5#6#7 \s__color_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 \__color_parse_model_RGB:w #1 , #2 , #3 , #4 \s__color_stop
+  {
+    { rgb }
+    {
+      \fp_eval:n { round(#1 / 255,5) } ~
+      \fp_eval:n { round(#2 / 255,5) } ~
+      \fp_eval:n { round(#3 / 255,5) }
+    }
+  }
+\cs_new:Npn \__color_parse_model_wave:w #1 , #2 \s__color_stop
+  {
+    { rgb }
+    {
+      \fp_compare:nNnTF {#1} < { 420 }
+        { \__color_parse_model_wave_auxi:nn {#1} { 0.3 + 0.7 * (#1 - 380) / 40 }
+        }
+        {
+          \fp_compare:nNnTF {#1} > { 700 }
+            { \__color_parse_model_wave_auxi:nn {#1} { 0.3 + 0.7 * (#1 - 780) / -80 } }
+            { \__color_parse_model_wave_auxi:nn {#1} { 1 } }
+        }
+    }
+  }
+\cs_new:Npn \__color_parse_model_wave_auxi:nn #1#2
+  {
+    \fp_compare:nNnTF {#1} < { 440 }
+      {
+        \__color_parse_model_wave_auxii:nn
+          { 4 + \__color_parse_model_wave_rho:n { (#1 - 440) / -60 } }
+          {#2}
+      }
+      {
+        \fp_compare:nNnTF {#1} < { 490 }
+          {
+            \__color_parse_model_wave_auxii:nn
+              { 4 - \__color_parse_model_wave_rho:n { (#1 - 440) / 50 } }
+              {#2}
+          }
+          {
+            \fp_compare:nNnTF {#1} < { 510 }
+              {
+                \__color_parse_model_wave_auxii:nn
+                  { 2 + \__color_parse_model_wave_rho:n { (#1 - 510) / -20 } }
+                  {#2}
+              }
+              {
+                \fp_compare:nNnTF {#1} < { 580 }
+                  {
+                    \__color_parse_model_wave_auxii:nn
+                      { 2 - \__color_parse_model_wave_rho:n { (#1 - 510) / 70 } }
+                      {#2}
+                  }
+                  {
+                    \fp_compare:nNnTF {#1} < { 645 }
+                      {
+                        \__color_parse_model_wave_auxii:nn
+                          { \__color_parse_model_wave_rho:n { (#1 - 645) / -65 } }
+                          {#2}
+                      }
+                      { \__color_parse_model_wave_auxii:nn { 0 } {#2} }
+                  }
+              }
+          }
+      }
+  }
+\cs_new:Npn \__color_parse_model_wave_auxii:nn #1#2
+  {
+    \exp_args:Neee \__color_parse_model_hsb_aux:nnn
+      { \fp_eval:n {#1} }
+      { 1 }
+      { \__color_parse_model_wave_rho:n {#2} }
+  }
+\cs_new:Npn \__color_parse_model_wave_rho:n #1
+  { \fp_eval:n { min(1, max(0,#1) ) } }
+\tl_new:N \l_color_fixed_model_tl
+\cs_new_protected:Npn \__color_check_model:N #1
+  {
+    \tl_if_empty:NF \l_color_fixed_model_tl
+      {
+        \exp_after:wN \__color_check_model:nn #1
+        \tl_if_eq:NNF \l__color_model_tl \l_color_fixed_model_tl
+          {
+            \__color_convert:VVN \l__color_model_tl \l_color_fixed_model_tl
+              \l__color_value_tl
+          }
+        \tl_set:Nx #1
+          { { \l_color_fixed_model_tl } { \l__color_value_tl } }
+      }
+  }
+\cs_new_protected:Npn \__color_check_model:nn #1#2
+  {
+    \tl_set:Nn \l__color_model_tl {#1}
+    \tl_set:Nn \l__color_value_tl {#2}
+  }
+\cs_new_protected:Npx \__color_select:
+  {
+    \tl_set:Nx \exp_not:c { l__color_named_ . _tl }
+      { \exp_not:N \__color_model:N \exp_not:N \l__color_current_tl }
+    \prop_clear:N \exp_not:c { l__color_named_ . _prop }
+    \prop_put:NVx \exp_not:c { l__color_named_ . _prop }
+      \exp_not:c { l__color_named_ . _tl }
+      { \exp_not:N \__color_values:N \exp_not:N \l__color_current_tl }
+    \__color_select:N \exp_not:N \l__color_current_tl
+  }
+\cs_new_protected:Npn \color_select:n #1
+  {
+    \__color_parse:nN {#1} \l__color_current_tl
+    \__color_select:
+  }
+\cs_new_protected:Npn \color_select:nn #1#2
+  {
+    \__color_select_main:Nw \l__color_current_tl
+      #1 / / \s__color_mark #2 / / \s__color_stop
+    \__color_select:
+  }
+\cs_new_protected:Npn \__color_select_main:Nw
+  #1 #2 / #3 / #4 \s__color_mark #5 / #6 / #7 \s__color_stop
+  {
+    \__color_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 }
+      { \__color_select_loop:Nw #1 #3 / #4 \s__color_mark #6 / #7 \s__color_stop }
+  }
+\cs_new_protected:Npn \__color_select_loop:Nw
+  #1 #2 / #3 \s__color_mark #4 / #5 \s__color_stop
+  {
+    \str_if_eq:nVTF {#2} \l_color_fixed_model_tl
+      { \__color_select:nnN {#2} {#4} #1 }
+      {
+        \tl_if_blank:nTF {#2}
+          { \exp_after:wN \__color_select_swap:Nnn \exp_after:wN #1 #1 }
+          { \__color_select_loop:Nw #1 #3 \s__color_mark #5 \s__color_stop }
+      }
+  }
+\cs_new_protected:Npn \__color_select:nnN #1#2#3
+  {
+    \cs_if_exist:cTF { __color_parse_model_ #1 :w }
+      {
+        \tl_set:Nx #3
+          { \use:c { __color_parse_model_ #1 :w } #2 , 0 , 0 , 0 , 0 \s__color_stop }
+      }
+      { \__kernel_msg_error:nnn { color } { unknown-model } {#1} }
+  }
+\cs_new_protected:Npn \__color_select_swap:Nnn #1#2#3
+  {
+    \__color_convert:nVnN {#2} \l_color_fixed_model_tl {#3} \l__color_value_tl
+    \tl_set:Nx #1
+      { { \l_color_fixed_model_tl } { \l__color_value_tl } }
+  }
+\cs_new_protected:Npn \color_fill:n #1
+  {
+    \__color_parse:nN {#1} \l__color_current_tl
+    \exp_after:wN \__color_draw:nnn \l__color_current_tl { fill }
+  }
+\cs_new_protected:Npn \color_stroke:n #1
+  {
+    \__color_parse:nN {#1} \l__color_current_tl
+    \exp_after:wN \__color_draw:nnn \l__color_current_tl { stroke }
+  }
+\cs_new_protected:Npn \color_fill:nn #1#2
+  {
+    \__color_select_main:Nw \l__color_current_tl
+      #1 / / \s__color_mark #2 / / \s__color_stop
+    \exp_after:wN \__color_draw:nnn \l__color_current_tl { fill }
+  }
+\cs_new_protected:Npn \color_stroke:nn #1#2
+  {
+    \__color_select_main:Nw \l__color_current_tl
+      #1 / / \s__color_mark #2 / / \s__color_stop
+    \exp_after:wN \__color_draw:nnn \l__color_current_tl { stroke }
+  }
+\cs_new_protected:Npn \__color_draw:nnn #1#2#3
+  { \use:c { __color_backend_ #3 _ #1 :n } {#2} }
+\tl_new:N \l__color_named_tl
+\cs_new_protected:Npn \color_set:nn #1#2
+  {
+    \exp_args:NV \__color_set:nnn
+      \l_color_fixed_model_tl {#1} {#2}
+  }
+\cs_new_protected:Npn \__color_set:nnn #1#2#3
+  {
+    \tl_clear:N \l_color_fixed_model_tl
+    \__color_set:nn {#2} {#3}
+    \tl_set:Nn \l_color_fixed_model_tl {#1}
+  }
+\cs_new_protected:Npn \__color_set:nn #1#2
+  {
+    \str_if_eq:nnF {#1} { . }
+      {
+        \__color_parse:nN {#2} \l__color_named_tl
+        \tl_clear_new:c { l__color_named_ #1 _tl }
+        \tl_set:cx { l__color_named_ #1 _tl }
+          { \__color_model:N \l__color_named_tl }
+        \prop_clear_new:c { l__color_named_ #1 _prop }
+        \prop_put:cvx { l__color_named_ #1 _prop } { l__color_named_ #1 _tl }
+          { \__color_values:N \l__color_named_tl }
+        \__color_set:nnw {#1} {#2} #2 ! \s__color_stop
+      }
+  }
+\cs_new_protected:Npn \__color_set:nnw #1#2#3 ! #4 \s__color_stop
+  {
+    \clist_map_inline:nn { cmyk , gray , rgb }
+      {
+        \prop_get:cnNT { l__color_named_ #3 _prop } {##1} \l__color_internal_tl
+          {
+            \prop_if_in:cnF { l__color_named_ #1 _prop } {##1}
+              {
+                \group_begin:
+                  \tl_set:cn { l__color_named_ #3 _tl } {##1}
+                  \__color_parse:nN {#2} \l__color_internal_tl
+                \exp_args:NNNV \group_end:
+                \tl_set:Nn \l__color_internal_tl \l__color_internal_tl
+                \prop_put:cxx { l__color_named_ #1 _prop }
+                  { \__color_model:N \l__color_internal_tl }
+                  { \__color_values:N \l__color_internal_tl }
+              }
+          }
+      }
+  }
+\cs_new_protected:Npx \color_set:nnn #1#2#3
+  {
+    \exp_not:N \str_if_eq:nnF {#1} { . }
+      {
+        \tl_clear_new:c { l__color_named_ #1 _tl }
+        \prop_clear_new:c { l__color_named_ #1 _prop }
+        \exp_not:N \__color_set_colon:nnw {#1} {#3}
+          #2 \c_colon_str \c_colon_str \exp_not:N \s__color_stop
+      }
+  }
+\use:x
+  {
+    \cs_new_protected:Npn \exp_not:N \__color_set_colon:nnw
+      ##1##2 ##3 \c_colon_str ##4 \c_colon_str
+      ##5 \exp_not:N \s__color_stop
+  }
+  {
+    \tl_if_blank:nTF {#4}
+      { \__color_set_loop:nw {#1} #3 }
+      { \__color_set_loop:nw {#1} #4 }
+        / / \s__color_mark #2 / / \s__color_stop
+  }
+\cs_new_protected:Npn \__color_set_loop:nw
+  #1#2 / #3 \s__color_mark #4 / #5 \s__color_stop
+  {
+    \tl_if_blank:nF {#2}
+      {
+        \__color_select:nnN {#2} {#4} \l__color_named_tl
+        \tl_set:Nx \l__color_internal_tl { \__color_model:N \l__color_named_tl }
+        \tl_if_empty:cT { l__color_named_ #1 _tl }
+          { \tl_set_eq:cN { l__color_named_ #1 _tl } \l__color_internal_tl }
+        \prop_put:cVx { l__color_named_ #1 _prop } \l__color_internal_tl
+          { \__color_values:N \l__color_named_tl }
+        \__color_set_loop:nw {#1} #3 \s__color_mark #5 \s__color_stop
+      }
+  }
+\cs_new_protected:Npn \color_set_eq:nn #1#2
+  {
+    \__color_if_defined:nTF {#2}
+      {
+        \tl_clear_new:c { l__color_named_ #1 _tl }
+        \prop_clear_new:c { l__color_named_ #1 _prop }
+        \str_if_eq:nnTF {#2} { . }
+          {
+            \tl_set:cx { l__color_named_ #1 _tl }
+              { \__color_model:N \l__color_current_tl }
+            \prop_put:cvx { l__color_named_ #1 _prop } { l__color_named_ #1 _tl }
+              { \__color_values:N \l__color_current_tl }
+          }
+          {
+            \tl_set_eq:cc { l__color_named_ #1 _tl } { l__color_named_ #2 _tl }
+            \prop_set_eq:cc { l__color_named_ #1 _prop } { l__color_named_ #2 _prop }
+          }
+      }
+      {
+        \__kernel_msg_error:nnn { color } { unknown-color } {#2}
+      }
+  }
+\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 }
+\prop_new:c { l__color_named_._prop }
+\tl_new:c { l__color_named_._tl }
+\tl_set:cx { l__color_named_._tl } { \__color_model:N \l__color_current_tl }
+\cs_new_protected:Npn \color_export:nnN #1#2#3
+  {
+    \group_begin:
+      \tl_if_exist:cT { c__color_export_ #2 _tl }
+        { \tl_set_eq:Nc \l_color_fixed_model_tl { c__color_export_ #2 _tl } }
+      \__color_parse:nN {#1} #3
+      \__color_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
+  {
+    \__color_select_main:Nw #4
+      #1 / / \s__color_mark #2 / / \s__color_stop
+    \__color_export:nN {#3} #4
+  }
+\cs_new_protected:Npn \__color_export:nN #1#2
+  { \exp_after:wN \__color_export:nnnN #2 {#1} #2 }
+\cs_new:Npn \__color_export:nnnN #1#2#3#4
+  {
+    \cs_if_exist_use:cF { __color_export_format_ #3 :nnN }
+      {
+        \__kernel_msg_error:nnn { color } { unknown-export-format } {#3}
+        \use_none:nnn
+      }
+        {#1} {#2} #4
+  }
+\cs_new_protected:Npn \__color_export_format_backend:nnN #1#2#3
+  { \tl_set:Nn #3 { {#1} {#2} } }
+\cs_new_protected:Npn \__color_export:nnnNN #1#2#3#4#5
+  {
+    \str_if_eq:nnTF {#2} {#1}
+      { #5 #4 #3 \s__color_stop }
+      {
+        \__color_convert:nnnN {#2} {#1} {#3} #4
+        \exp_after:wN #5 \exp_after:wN #4
+          #4 \s__color_stop
+      }
+  }
+\tl_const:Nn \c__color_export_HTML_tl { rgb }
+\tl_const:cn { c__color_export_space-sep-cmyk_tl } { cmyk }
+\tl_const:cn { c__color_export_space-sep-rgb_tl } { rgb }
+\cs_new_protected:cpx { __color_export_format_space-sep-cmyk:nnN } #1#2#3
+  {
+    \exp_not:N \__color_export:nnnNN { cmyk } {#1} {#2} #3
+      \exp_not:c { __color_export_space-sep-cmyk:Nw }
+  }
+\cs_new_protected:cpn { __color_export_space-sep-cmyk:Nw } #1#2 \s__color_stop
+  { \tl_set:Nx #1 {#2} }
+\cs_new_protected:Npn \__color_export_format_HTML:nnN #1#2#3
+  { \__color_export:nnnNN { rgb } {#1} {#2}#3 \__color_export_HTML:Nw }
+\cs_new_protected:cpx { __color_export_format_space-sep-rgb:nnN } #1#2#3
+  {
+    \exp_not:N \__color_export:nnnNN { rgb } {#1} {#2} #3
+      \exp_not:c { __color_export_space-sep-rgb:Nw }
+  }
+\cs_new_protected:Npn \__color_export_HTML:Nw #1#2 ~ #3 ~ #4 \s__color_stop
+  {
+    \tl_set:Nx #1
+      {
+        \__color_export_HTML:n {#2}
+        \__color_export_HTML:n {#3}
+        \__color_export_HTML:n {#4}
+      }
+  }
+\cs_new:Npn \__color_export_HTML:n #1
+  {
+    \fp_compare:nNnTF {#1} = { 0 }
+      { 00 }
+      { \int_to_Hex:n { \fp_to_int:n { #1 * 255 } } }
+  }
+\cs_new_protected:cpn { __color_export_space-sep-rgb:Nw } #1#2 \s__color_stop
+  { \tl_set:Nx #1 {#2} }
+\prop_new:N \l__color_internal_prop
+\int_new:N \g__color_model_int
+\tl_const:Nn \c__color_fallback_cmyk_tl { 0 ~ 0 ~ 0 ~ 1 }
+\tl_const:Nn \c__color_fallback_gray_tl { 1 }
+\tl_const:Nn \c__color_fallback_rgb_tl { 1 ~ 1 ~ 1 }
+\prop_new:N \g__color_colorants_prop
+\prop_gput:Nnn \g__color_colorants_prop { black }   { Black }
+\prop_gput:Nnn \g__color_colorants_prop { blue }    { Blue }
+\prop_gput:Nnn \g__color_colorants_prop { cyan }    { Cyan }
+\prop_gput:Nnn \g__color_colorants_prop { green }   { Green }
+\prop_gput:Nnn \g__color_colorants_prop { magenta } { Magenta }
+\prop_gput:Nnn \g__color_colorants_prop { none }    { None }
+\prop_gput:Nnn \g__color_colorants_prop { red }     { Red }
+\prop_gput:Nnn \g__color_colorants_prop { yellow }  { Yellow }
+\tl_const:Nn \c__color_model_whitepoint_CIELAB_a_tl      { 1.0985 ~ 1 ~ 0.3558 }
+\tl_const:Nn \c__color_model_whitepoint_CIELAB_b_tl      { 0.9807 ~ 1 ~ 1.1822 }
+\tl_const:Nn \c__color_model_whitepoint_CIELAB_e_tl      { 1 ~ 1 ~ 1 }
+\tl_const:cn { c__color_model_whitepoint_CIELAB_d50_tl } { 0.9642 ~ 1 ~ 0.8251 }
+\tl_const:cn { c__color_model_whitepoint_CIELAB_d55_tl } { 0.9568 ~ 1 ~ 0.9214 }
+\tl_const:cn { c__color_model_whitepoint_CIELAB_d65_tl } { 0.9504 ~ 1 ~ 1.0888 }
+\tl_const:cn { c__color_model_whitepoint_CIELAB_d75_tl } { 0.9497 ~ 1 ~ 1.2261 }
+\tl_const:Nn \c__color_model_range_CIELAB_tl { 0 ~ 100 ~ -128 ~ 127 ~ -128 ~ 127 }
+\prop_new:N \g__color_alternative_model_prop
+\clist_map_inline:nn { cyan , magenta , yellow , black }
+  { \prop_gput:Nnn \g__color_alternative_model_prop {#1} { cmyk } }
+\clist_map_inline:nn { red , green , blue }
+  { \prop_gput:Nnn \g__color_alternative_model_prop {#1} { rgb } }
+\prop_new:N \g__color_alternative_values_prop
+\prop_gput:Nnn \g__color_alternative_values_prop { cyan }    {  1 , 0 , 0 , 0 }
+\prop_gput:Nnn \g__color_alternative_values_prop { magenta } {  0 , 1 , 0 , 0 }
+\prop_gput:Nnn \g__color_alternative_values_prop { yellow }  {  0 , 0 , 1 , 0 }
+\prop_gput:Nnn \g__color_alternative_values_prop { black }   {  0 , 0 , 0 , 1 }
+\prop_gput:Nnn \g__color_alternative_values_prop { red }   {  1 , 0 , 0 }
+\prop_gput:Nnn \g__color_alternative_values_prop { green } {  0 , 1 , 0 }
+\prop_gput:Nnn \g__color_alternative_values_prop { blue }  {  0 , 0 , 1 }
+\cs_new_protected:Npn \color_model_new:nnn #1#2#3
+  {
+    \exp_args:Nee \__color_model_new:nnn
+      { \tl_to_str:n {#1} }
+      { \str_foldcase:n {#2} } {#3}
+  }
+\cs_new_protected:Npn \__color_model_new:nnn #1#2#3
+  {
+    \cs_if_exist:cTF { __color_parse_model_ #1 :w }
+      {
+        \__kernel_msg_error:nnn { color } { model-already-defined } {#1}
+      }
+      {
+        \cs_if_exist:cTF { __color_model_ #2 :n }
+          {
+            \prop_set_from_keyval:Nn \l__color_internal_prop {#3}
+            \use:c { __color_model_ #2 :n } {#1}
+          }
+          {
+            \__kernel_msg_error:nnn { color } { unknown-model-type } {#2}
+          }
+      }
+  }
+\cs_new_protected:Npn \__color_model_separation:n #1
+  {
+    \prop_get:NnNTF \l__color_internal_prop { name }
+      \l__color_internal_tl
+      {
+        \exp_args:NV \__color_model_separation:nn
+          \l__color_internal_tl {#1}
+      }
+      {
+        \__kernel_msg_error:nnn { color }
+          { separation-requires-name } {#1}
+      }
+  }
+\cs_new_protected:Npn \__color_model_separation:nn #1#2
+  {
+    \prop_get:NnNTF \l__color_internal_prop { alternative-model }
+      \l__color_internal_tl
+      {
+        \exp_args:NV \__color_model_separation:nnn
+          \l__color_internal_tl {#2} {#1}
+      }
+      {
+        \__kernel_msg_error:nnn { color }
+          { separation-alternative-model } {#2}
+      }
+  }
+\cs_new_protected:Npn \__color_model_separation:nnn #1#2#3
+  {
+    \cs_if_exist:cTF { __color_model_separation_ #1 :nnnnnn }
+      {
+        \prop_get:NnNTF \l__color_internal_prop { alternative-values }
+          \l__color_internal_tl
+          {
+            \exp_after:wN \__color_model_separation:w \l__color_internal_tl
+              , 0 , 0 , 0 , 0 \s__color_stop {#2} {#3} {#1}
+          }
+          {
+            \__kernel_msg_error:nnn { color }
+              { separation-alternative-values } {#2}
+          }
+      }
+      {
+        \__kernel_msg_error:nnn { color }
+          { unknown-alternative-model } {#1}
+      }
+  }
+\cs_new_protected:Npn \__color_model_separation:w
+  #1 , #2 , #3 , #4 , #5 \s__color_stop #6#7#8
+  {
+    \int_gincr:N \g__color_model_int
+    \tl_const:cn { c__color_fallback_ #6 _tl } { 1 }
+    \cs_new_eq:cN { __color_parse_mix_ #6 :nw } \__color_parse_mix_gray:nw
+    \cs_new:cpn { __color_parse_model_ #6 :w } ##1 , ##2 \s__color_stop
+      { {#6} { \__color_parse_number:n {##1} } }
+    \clist_map_inline:nn { fill , stroke , select }
+      {
+        \cs_new_protected:cpx { __color_backend_ ##1 _ #6 :n } ####1
+          {
+            \exp_not:c { __color_backend_ ##1 _ separation:nn }
+              { color \int_use:N \g__color_model_int } {####1}
+          }
+      }
+    \use:c { __color_model_separation_ #8 :nnnnnn }
+      {#6} {#7} {#1} {#2} {#3} {#4}
+    \prop_gput:Nnn \g__color_alternative_model_prop {#6} {#8}
+    \prop_gput:Nnx \g__color_colorants_prop {#6}
+      { \str_convert_pdfname:n {#7} }
+    \cs_new_protected:cpx { __color_model_ #6 _white: }
+      {
+        \prop_put:Nnn \exp_not:N \l__color_named_white_prop {#6} { 0 }
+        \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0
+          { \group_insert_after:N \exp_not:c { __color_model_ #6 _ white: } }
+      }
+    \use:c { __color_model_ #6 _white: }
+  }
+\cs_new_protected:Npn \__color_model_separation_cmyk:nnnnnn #1#2#3#4#5#6
+  {
+    \cs_new:cpn { __color_convert_ #1 _cmyk:w } ##1 ~ ##2 \s__color_stop
+      {
+         \fp_eval:n {##1 * #3} ~
+         \fp_eval:n {##1 * #4} ~
+         \fp_eval:n {##1 * #5} ~
+         \fp_eval:n {##1 * #6}
+      }
+    \__color_model_convert:nnn {#1} { cmyk } { rgb }
+    \__color_model_convert:nnn {#1} { cmyk } { gray }
+    \prop_gput:Nnn \g__color_alternative_values_prop {#1} { #3 , #4 , #5 , #6 }
+    \__color_backend_separation_init:nnnnn {#2} { /DeviceCMYK } { }
+      { 0 ~ 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 ~ #6 }
+  }
+\cs_new_protected:Npn \__color_model_separation_rgb:nnnnnn #1#2#3#4#5#6
+  {
+    \cs_new:cpn { __color_convert_ #1 _rgb:w } ##1 ~ ##2 \s__color_stop
+      {
+         \fp_eval:n {##1 * #3} ~
+         \fp_eval:n {##1 * #4} ~
+         \fp_eval:n {##1 * #5}
+      }
+    \__color_model_convert:nnn {#1} { rgb } { cmyk }
+    \__color_model_convert:nnn {#1} { rgb } { gray }
+    \prop_gput:Nnn \g__color_alternative_values_prop {#1} { #3 , #4 , #5 }
+    \__color_backend_separation_init:nnnnn {#2} { /DeviceRGB } { }
+      { 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 }
+  }
+\cs_new_protected:Npn \__color_model_separation_gray:nnnnnn #1#2#3#4#5#6
+  {
+    \cs_new:cpn { __color_convert_ #1 _cmyk:w } ##1 ~ ##2 \s__color_stop
+      {
+        \fp_eval:n {##1 * #3} ~
+        \fp_eval:n {##1 * #3} ~
+        \fp_eval:n {##1 * #3} ~
+        \fp_eval:n {##1 * #3}
+      }
+    \cs_new:cpn { __color_convert_ #1 _gray:w } ##1 ~ ##2 \s__color_stop
+      { \fp_eval:n {##1 * #3} }
+    \cs_new:cpn { __color_convert_ #1 _rgb:w } ##1 ~ ##2 \s__color_stop
+      {
+        \fp_eval:n {##1 * #3} ~
+        \fp_eval:n {##1 * #3} ~
+        \fp_eval:n {##1 * #3}
+      }
+    \prop_gput:Nnn \g__color_alternative_values_prop {#1} {#3}
+    \__color_backend_separation_init:nnnnn {#2} { /DeviceGray } { } { 0 } {#3}
+  }
+\cs_new_protected:Npn \__color_model_convert:nnn #1#2#3
+  {
+    \cs_new:cpx { __color_convert_ #1 _ #3 :w } ##1 ~ ##2 \s__color_stop
+      {
+        \exp_not:N \exp_args:NNe \exp_not:N \use:nn
+        \exp_not:c { __color_convert_  #2 _ #3 :w }
+          { \exp_not:c { __color_convert_ #1 _ #2 :w } ##1 ~ ##2 \s__color_stop }
+          \c_space_tl \exp_not:N \s__color_stop
+      }
+  }
+\cs_new_protected:Npn \__color_model_separation_CIELAB:nnnnnn #1#2#3#4#5#6
+  {
+    \prop_get:NnNF \l__color_internal_prop { illuminant }
+      \l__color_internal_tl
+      {
+        \__kernel_msg_error:nnn { color }
+          { CIELAB-requires-illuminant } {#1}
+        \tl_set:Nn \l__color_internal_tl { d50 }
+      }
+    \exp_args:NV \__color_model_separation_CIELAB:nnnnnnn
+      \l__color_internal_tl {#1} {#2} {#3} {#4} {#5} {#6}
+  }
+\cs_new_protected:Npn \__color_model_separation_CIELAB:nnnnnnn #1#2#3#4#5#6#7
+  {
+    \tl_if_exist:cTF { c__color_model_whitepoint_CIELAB_ #1 _tl }
+      {
+        \__color_backend_separation_init_CIELAB:nnn {#1} {#3} { #4 ~ #5 ~ #6 }
+        \cs_new:cpn { __color_convert_ #2 _cmyk:w } ##1 ~ ##2 \s__color_stop
+          { 0 ~ 0 ~ 0 ~ 1 }
+        \cs_new:cpn { __color_convert_ #2 _rgb:w } ##1 ~ ##2 \s__color_stop
+          { 1 ~ 1 ~ 1 }
+        \cs_new:cpn { __color_convert_ #2 _gray:w } ##1 ~ ##2 \s__color_stop
+          { 1 }
+      }
+      {
+        \__kernel_msg_error:nnn { color }
+          { unknown-CIELAB-illuminant } {#1}
+      }
+  }
+\cs_new_protected:Npn \__color_model_devicen:n #1
+  {
+    \prop_get:NnNTF \l__color_internal_prop { names }
+      \l__color_internal_tl
+      {
+        \exp_args:NV \__color_model_devicen:nn
+          \l__color_internal_tl {#1}
+      }
+      {
+        \__kernel_msg_error:nnn { color }
+          { DeviceN-requires-names } {#1}
+      }
+  }
+\cs_new_protected:Npn \__color_model_devicen:nn #1#2
+  {
+    \tl_clear:N \l__color_model_tl
+    \clist_map_inline:nn {#1}
+      {
+        \prop_get:NnNTF \g__color_alternative_model_prop {##1}
+          \l__color_internal_tl
+          {
+            \tl_if_empty:NTF \l__color_model_tl
+              { \tl_set_eq:NN \l__color_model_tl \l__color_internal_tl }
+              {
+                \str_if_eq:VVF \l__color_model_tl \l__color_internal_tl
+                  {
+                    \__kernel_msg_error:nnn { color }
+                      { DeviceN-inconsistent-alternative }
+                      {#2}
+                    \clist_map_break:n { \use_none:nnnn }
+                  }
+               }
+          }
+          {
+            \str_if_eq:nnF {##1} { none }
+              {
+                \__kernel_msg_error:nnn { color }
+                  { DeviceN-no-alternative }
+                  {#2}
+              }
+          }
+      }
+    \tl_if_empty:NTF \l__color_model_tl
+      {
+        \__kernel_msg_error:nnn { color }
+          { DeviceN-no-alternative } {#2}
+      }
+      { \exp_args:NV \__color_model_devicen:nnn \l__color_model_tl {#1} {#2} }
+  }
+\cs_new_protected:Npn \__color_model_devicen:nnn #1#2#3
+  {
+    \exp_args:Nx \__color_model_devicen:nnnn
+      { \clist_count:n {#2} } {#1} {#2} {#3}
+  }
+\cs_new_protected:Npn \__color_model_devicen:nnnn #1#2#3#4
+  {
+    \int_gincr:N \g__color_model_int
+    \tl_const:cx { c__color_fallback_ #4 _tl }
+      { \prg_replicate:nn {#1} { 1 ~ } }
+    \cs_if_exist_use:cF { __color_model_devicen_parse_ #1 :nn }
+      { \__color_model_devicen_parse_generic:nn }
+        {#4} {#1}
+    \clist_map_inline:nn { fill , stroke , select }
+      {
+        \cs_new_protected:cpx { __color_backend_ ##1 _ #4 :n } ####1
+          {
+            \exp_not:c { __color_backend_ ##1 _ devicen:nn }
+              { color \int_use:N \g__color_model_int } {####1}
+          }
+      }
+    \cs_new_protected:cpx { __color_model_ #4 _white: }
+      {
+        \prop_put:Nnn \exp_not:N \l__color_named_white_prop {#4}
+          { \prg_replicate:nn {#1} { 0 ~ } }
+        \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0
+          { \group_insert_after:N \exp_not:c { __color_model_ #4 _ white: } }
+      }
+    \use:c { __color_model_ #4 _white: }
+    \__color_model_devicen_init:nnn {#1} {#2} {#3}
+    \__color_model_devicen_convert:nnn {#4} {#2} {#3}
+  }
+\cs_new_protected:cpn { __color_model_devicen_parse_1:nn } #1#2
+  {
+    \cs_new:cpn { __color_parse_model_ #1 :w  } ##1 , ##2 \s__color_stop
+      { {#1} { \__color_parse_number:n {##1} } }
+    \cs_new_eq:cN { __color_parse_mix_ #1 :nw  } \__color_parse_mix_gray:nw
+  }
+\cs_new_protected:cpn { __color_model_devicen_parse_2:nn } #1#2
+  {
+    \cs_new:cpn { __color_parse_model_ #1 :w  } ##1 , ##2 , ##3 \s__color_stop
+      { {#1} { \__color_parse_number:n {##1} ~ \__color_parse_number:n {##2} } }
+    \cs_new:cpn { __color_parse_mix_ #1 :nw }
+      ##1##2 ~ ##3 \s__color_mark ##4 ~ ##5 \s__color_stop
+      {
+        \fp_eval:n { ##2 * ##1 + ##4 * ( 1 - ##1 ) } \c_space_tl
+        \fp_eval:n { ##3 * ##1 + ##5 * ( 1 - ##1 ) }
+      }
+  }
+\cs_new_protected:cpn { __color_model_devicen_parse_3:nn } #1#2
+  {
+    \cs_new:cpn { __color_parse_model_ #1 :w  } ##1 , ##2 , ##3 , ##4 \s__color_stop
+      {
+        {#1}
+        {
+          \__color_parse_number:n {##1} ~
+          \__color_parse_number:n {##2} ~
+          \__color_parse_number:n {##3}
+        }
+      }
+    \cs_new_eq:cN { __color_parse_mix_ #1 :nw  } \__color_parse_mix_rgb:nw
+  }
+\cs_new_protected:cpn { __color_model_devicen_parse_4:nn } #1#2
+  {
+    \cs_new:cpn { __color_parse_model_ #1 :w  }
+      ##1 , ##2 , ##3 , ##4 , ##5 \s__color_stop
+      {
+        {#1}
+        {
+          \__color_parse_number:n {##1} ~
+          \__color_parse_number:n {##2} ~
+          \__color_parse_number:n {##3} ~
+          \__color_parse_number:n {##4}
+        }
+      }
+  \cs_new_eq:cN { __color_parse_mix_ #1 :nw } \__color_parse_mix_cmyk:nw
+  }
+\cs_new_protected:Npn \__color_model_devicen_parse_generic:nn #1#2
+  {
+    \cs_new:cpn { __color_parse_model_ #1 :w  } ##1 , ##2 \s__color_stop
+      {
+        {#1}
+        { \__color_model_devicen_parse:nw {#2} ##1 , ##2 , \q_nil , \s__color_stop }
+      }
+    \cs_new:cpx { __color_parse_mix_ #1 :nw }
+      ##1 ##2 \s__color_mark ##3 \s__color_stop
+      {
+        \exp_not:N \__color_model_devicen_mix:nw {##1}
+          ##2 \c_space_tl \exp_not:N \q_nil \c_space_tl \exp_not:N \s__color_mark
+          ##3 \c_space_tl \exp_not:N \q_nil \c_space_tl \exp_not:N \s__color_stop
+      }
+  }
+\cs_new:Npn \__color_model_devicen_parse:nw #1#2 , #3 \s__color_stop
+  {
+    \int_compare:nNnT {#1} > 0
+      {
+        \quark_if_nil:nTF {#2}
+          { \prg_replicate:nn {#1} { 0 ~ } }
+          {
+            \__color_parse_number:n {#2}
+            \int_compare:nNnT {#1} > 1 { ~ }
+            \exp_args:Nf \__color_model_devicen_parse:nw
+              { \int_eval:n { #1 - 1 } } #3 \s__color_stop
+          }
+      }
+  }
+\cs_new:Npn \__color_model_devicen_mix:nw #1#2 ~ #3 \s__color_mark #4 ~ #5 \s__color_stop
+  {
+    \fp_eval:n { #2 * #1 + #4 * ( 1 - #1 ) }
+    \quark_if_nil:oF { \tl_head:w #3 \q_stop }
+      {
+        \c_space_tl
+        \__color_model_devicen_mix:nw {#1} #3 \s__color_mark #5 \s__color_stop
+      }
+  }
+\cs_new_protected:Npn \__color_model_devicen_init:nnn #1#2#3
+  {
+    \exp_args:Ne \__color_model_devicen_init:nnnn
+      {
+        \str_case:nn {#2}
+          {
+            { cmyk } { 4 }
+            { gray } { 1 }
+            { rgb }  { 3 }
+          }
+      }
+      {#1} {#2} {#3}
+  }
+\cs_new_protected:Npn \__color_model_devicen_init:nnnn #1#2#3#4
+  {
+    \tl_set:Nx \l__color_internal_tl
+      { \prg_replicate:nn {#1} { 1.0 ~ }   }
+    \int_zero:N \l__color_internal_int
+    \clist_map_inline:nn {#4}
+      {
+        \int_incr:N \l__color_internal_int
+        \prop_get:NnN \g__color_alternative_values_prop {##1}
+          \l__color_value_tl
+        \exp_after:wN \__color_model_devicen_transform:w
+          \l__color_value_tl , 0 , 0 , 0 \s__color_stop {#1} {#2}
+      }
+    \tl_put_right:Nx \l__color_internal_tl
+      {
+        \prg_replicate:nn {#1}
+          { neg ~ 1.0 ~ add ~ #1 ~ -1 ~ roll ~ }
+        \int_eval:n { #2 + 4 } ~ 4 ~ roll
+        \prg_replicate:nn {#2} { ~ pop }
+      }
+    \use:x
+      {
+        \__color_backend_devicen_init:nnn
+          {
+            \clist_map_function:nN {#4}
+              \__color_model_devicen_colorant:n
+          }
+          {
+            \str_case:nn {#3}
+              {
+                { cmyk } { /DeviceCMYK }
+                { gray } { /DeviceGray }
+                { rgb }  { /DeviceRGB }
+              }
+          }
+          { \exp_not:V \l__color_internal_tl }
+      }
+  }
+\cs_new_protected:Npn \__color_model_devicen_transform:w
+  #1 , #2 , #3 , #4 , #5 \s__color_stop #6#7
+  {
+    \use:c { __color_model_devicen_transform_ #6 :nnnnn }
+      {#1} {#2} {#3} {#4} {#7}
+  }
+\cs_new_protected:cpn { __color_model_devicen_transform_1:nnnnn } #1#2#3#4#5
+  { \__color_model_devicen_transform:nnn {#5} { 1 } {#1} }
+\cs_new_protected:cpn { __color_model_devicen_transform_3:nnnnn } #1#2#3#4#5
+  {
+    \clist_map_inline { #1 , #2 , #3 }
+      { \__color_model_devicen_transform:nnn {#5} { 3 } {##1} }
+  }
+\cs_new_protected:cpn { __color_model_devicen_transform_4:nnnnn } #1#2#3#4#5
+  {
+    \clist_map_inline:nn { #1 , #2 , #3 , #4 }
+      { \__color_model_devicen_transform:nnn {#5} { 4 } {##1} }
+  }
+\cs_new_protected:Npn \__color_model_devicen_transform:nnn #1#2#3
+  {
+    \tl_put_right:Nx \l__color_internal_tl
+      {
+        \fp_compare:nNnF {#3} = \c_zero_fp
+          {
+            \int_eval:n { #1 - \l__color_internal_int + #2 } ~ index ~
+              #3 ~ neg ~ mul ~ 1.0 ~ add ~ mul ~
+          }
+        #2 ~ -1 ~ roll ~
+      }
+  }
+\cs_new:Npn \__color_model_devicen_colorant:n #1
+  {
+    / \prop_item:Nn \g__color_colorants_prop {#1} ~
+  }
+\cs_new_protected:Npn \__color_model_devicen_convert:nnn #1#2#3
+  {
+    \use:c { __color_model_devicen_convert_ #2 :nn } {#1} {#3}
+  }
+\cs_new_protected:Npn \__color_model_devicen_convert_cmyk:nn #1#2
+  {
+    \__color_model_convert:nnn {#1} { cmyk } { gray }
+    \__color_model_convert:nnn {#1} { cmyk } { rgb }
+    \__color_model_devicen_convert:nnnn {#1} { cmyk } { 4 } {#2}
+  }
+\cs_new_protected:Npn \__color_model_devicen_convert_gray:nn #1#2
+  {
+    \__color_model_convert:nnn {#1} { gray } { cmyk }
+    \__color_model_convert:nnn {#1} { gray } { rgb }
+    \__color_model_devicen_convert:nnnn {#1} { gray } { 1 } {#2}
+  }
+\cs_new_protected:Npn \__color_model_devicen_convert_rgb:nn #1#2
+  {
+    \__color_model_convert:nnn {#1} { rgb } { cmyk }
+    \__color_model_convert:nnn {#1} { rgb } { gray }
+    \__color_model_devicen_convert:nnnn {#1} { rgb } { 3 } {#2}
+  }
+\cs_new_protected:Npn \__color_model_devicen_convert:nnnn #1#2#3#4
+  {
+    \cs_new:cpx { __color_convert_ #1 _ #2 :w } ##1 \s__color_stop
+      {
+        \exp_not:c { __color_convert_devicen_ #2 : \prg_replicate:nn {#3} { n } w }
+          \prg_replicate:nn {#3} { { 1 } }
+          ##1 \exp_not:N \s__color_mark
+          \clist_map_function:nN {#4} \__color_model_devicen_convert:n
+          \exp_not:N \s__color_stop
+      }
+  }
+\cs_new:Npn \__color_model_devicen_convert:n #1
+  {
+    {
+      \exp_args:Ne \__color_model_devicen_convert_aux:n
+        { \prop_item:Nn \g__color_alternative_values_prop {#1} }
+    }
+  }
+\cs_new:Npn \__color_model_devicen_convert_aux:n #1
+  { \__color_model_devicen_convert_aux:w #1 , , , , \s__color_stop }
+\cs_new:Npn \__color_model_devicen_convert_aux:w #1 , #2 , #3 , #4 , #5 \s__color_stop
+  {
+    {#1}
+    \tl_if_blank:nF {#2}
+      {
+        {#2}
+        \tl_if_blank:nF {#3}
+          {
+            {#3}
+            \tl_if_blank:nF {#4} { {#4} }
+          }
+      }
+  }
+\cs_new:Npn \__color_convert_devicen_cmyk:nnnnw
+  #1#2#3#4#5 ~ #6 \s__color_mark #7#8 \s__color_stop
+  {
+    \__color_convert_devicen_cmyk:nnnnnnnnn {#5} {#1} {#2} {#3} {#4} #7
+      #6 \s__color_mark #8 \s__color_stop
+  }
+\cs_new:Npn \__color_convert_devicen_cmyk:nnnnnnnnn #1#2#3#4#5#6#7#8#9
+  {
+    \use:e
+      {
+        \exp_not:N \__color_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 \__color_convert_devicen_cmyk_aux:nnnnw
+  #1#2#3#4 #5 \s__color_mark #6 \s__color_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 }
+      }
+      {
+        \__color_convert_devicen_cmyk:nnnnw {#1} {#2} {#3} {#4}
+          #5 \s__color_mark #6 \s__color_stop
+      }
+  }
+\cs_new:Npn \__color_convert_devicen_gray:nw
+  #1#2 ~ #3 \s__color_mark #4#5 \s__color_stop
+  {
+    \__color_convert_devicen_gray:nnn {#2} {#1} #4
+      #3 \s__color_mark #5 \s__color_stop
+  }
+\cs_new:Npn \__color_convert_devicen_gray:nnn #1#2#3
+  {
+    \exp_arsgs:Ne \__color_convert_devicen_gray_aux:nw
+      { \fp_eval:n { #2 * (1 - (#1 * #3)) } }
+  }
+\cs_new:Npn \__color_convert_devicen_gray_aux:nw
+  #1 #2 \s__color_mark #3 \s__color_stop
+  {
+    \tl_if_blank:nTF {#2}
+      { \fp_eval:n { 1 - #1 } }
+      {
+        \__color_convert_devicen_gray:nw {#1}
+          #2 \s__color_mark #3 \s__color_stop
+      }
+  }
+\cs_new:Npn \__color_convert_devicen_rgb:nnnw
+  #1#2#3#4 ~ #5 \s__color_mark #6#7 \s__color_stop
+  {
+    \__color_convert_devicen_cmyk:nnnnnn {#4} {#1} {#2} {#3} #6
+      #5 \s__color_mark #7 \s__color_stop
+  }
+\cs_new:Npn \__color_convert_devicen_rgb:nnnnnnn #1#2#3#4#5#6#7
+  {
+    \use:e
+      {
+        \exp_not:N \__color_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 \__color_convert_devicen_rgb_aux:nnnw
+  #1#2#3 #4 \s__color_mark #5 \s__color_stop
+  {
+    \tl_if_blank:nTF {#4}
+      {
+        \fp_eval:n { 1 - #1 } ~
+        \fp_eval:n { 1 - #2 } ~
+        \fp_eval:n { 1 - #3 }
+      }
+      {
+        \__color_convert_devicen_rgb:nnnw {#1} {#2} {#3}
+          #4 \s__color_mark #5 \s__color_stop
+      }
+  }
+\cs_new_protected:Npn \color_show:n #1
+  {
+    \msg_show:nnxxxx { LaTeX / color } { show }
+      {#1}
+      {
+        \__color_if_defined:nT {#1}
+          {
+            \exp_args:Nv \__color_show:n { l__color_named_ #1 _tl }
+            \prop_map_function:cN
+              { l__color_named_ #1 _prop }
+              \msg_show_item_unbraced:nn
+          }
+      }
+      { }
+      { }
+  }
+\cs_new:Npn \__color_show:n #1
+  {
+    \msg_show_item_unbraced:nn { model } {#1}
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_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.
+  }
+\__kernel_msg_new:nnn { color } { show }
+  {
+    The~color~#1~
+    \tl_if_empty:nTF {#2}
+      { is~undefined. }
+      { has~the~properties: #2 }
+  }
+%% File: l3pdf.dtx
+\scan_new:N \s__pdf_stop
+\bool_new:N \g__pdf_init_bool
+\bool_lazy_and:nnT
+  { \str_if_eq_p:Vn \fmtname { LaTeX2e } }
+  { \tl_if_exist_p:N \@expl at finalise@setup@@ }
+  {
+    \tl_gput_right:Nn \@expl at finalise@setup@@
+      {
+        \tl_gput_right:Nn \@kernel at after@begindocument
+          { \bool_gset_true:N \g__pdf_init_bool }
+      }
+  }
+\cs_new_protected:Npn \pdf_uncompress:
+  {
+    \bool_if:NF \g__pdf_init_bool
+      {
+        \__pdf_backend_compresslevel:n { 0 }
+        \__pdf_backend_compress_objects:n { \c_false_bool }
+      }
+  }
+\cs_new_protected:Npn \pdf_object_new:nn #1#2
+  { \__pdf_backend_object_new:nn {#1} {#2} }
+\prg_new_conditional:Npnn \pdf_object_if_exist:n #1 { p , T , F , TF }
+  {
+    \int_if_exist:cTF { c__pdf_backend_object_ \tl_to_str:n {#1} _int }
+     { \prg_return_true: }
+     { \prg_return_false:}
+  }
+\cs_new_protected:Npn \pdf_object_write:nn #1#2
+  {
+    \__pdf_backend_object_write:nn {#1} {#2}
+    \bool_gset_true:N \g__pdf_init_bool
+  }
+\cs_generate_variant:Nn \pdf_object_write:nn { nx }
+\cs_new:Npn \pdf_object_ref:n #1 { \__pdf_backend_object_ref:n {#1} }
+\cs_new_protected:Npn \pdf_object_unnamed_write:nn #1#2
+  {
+    \__pdf_backend_object_now:nn {#1} {#2}
+    \bool_gset_true:N \g__pdf_init_bool
+  }
+\cs_generate_variant:Nn \pdf_object_unnamed_write:nn { nx }
+\cs_new:Npn \pdf_object_ref_last: { \__pdf_backend_object_last: }
+\cs_new:Npn \pdf_pageobject_ref:n #1
+  { \__pdf_backend_pageobject_ref:n {#1} }
+\prg_new_conditional:Npnn \pdf_version_compare:Nn #1#2 { p , T , F , TF }
+  { \use:c { __pdf_version_compare_ #1 :w } #2 . . \s__pdf_stop }
+\cs_new:cpn { __pdf_version_compare_=:w } #1 . #2 . #3 \s__pdf_stop
+ {
+   \bool_lazy_and:nnTF
+    { \int_compare_p:nNn \__pdf_backend_version_major: = {#1} }
+    { \int_compare_p:nNn \__pdf_backend_version_minor: = {#2} }
+    { \prg_return_true: }
+    { \prg_return_false: }
+ }
+\cs_new:cpn { __pdf_version_compare_<:w } #1 . #2 . #3 \s__pdf_stop
+ {
+   \bool_lazy_or:nnTF
+    { \int_compare_p:nNn \__pdf_backend_version_major: < {#1} }
+    {
+      \bool_lazy_and_p:nn
+        { \int_compare_p:nNn \__pdf_backend_version_major: = {#1} }
+        { \int_compare_p:nNn \__pdf_backend_version_minor: < {#2} }
+    }
+    { \prg_return_true: }
+    { \prg_return_false: }
+ }
+\cs_new:cpn { __pdf_version_compare_>:w } #1 . #2 . #3 \s__pdf_stop
+ {
+   \bool_lazy_or:nnTF
+    { \int_compare_p:nNn \__pdf_backend_version_major: > {#1} }
+    {
+      \bool_lazy_and_p:nn
+        { \int_compare_p:nNn \__pdf_backend_version_major: = {#1} }
+        { \int_compare_p:nNn \__pdf_backend_version_minor: > {#2} }
+    }
+    { \prg_return_true: }
+    { \prg_return_false: }
+ }
+\cs_new_protected:Npn \pdf_version_gset:n #1
+  { \__pdf_version_gset:w  #1 . . \s__pdf_stop }
+\cs_new_protected:Npn \pdf_version_min_gset:n #1
+  {
+    \pdf_version_compare:NnT < {#1}
+      { \__pdf_version_gset:w  #1 . . \s__pdf_stop }
+  }
+\cs_new_protected:Npn \__pdf_version_gset:w  #1 . #2 . #3\s__pdf_stop
+  {
+    \bool_if:NF \g__pdf_init_bool
+      {
+        \__pdf_backend_version_major_gset:n {#1}
+        \__pdf_backend_version_minor_gset:n {#2}
+      }
+  }
+\cs_new:Npn \pdf_version:
+  { \__pdf_backend_version_major: . \__pdf_backend_version_minor: }
+\cs_new:Npn \pdf_version_major: { \__pdf_backend_version_major: }
+\cs_new:Npn \pdf_version_minor: { \__pdf_backend_version_minor: }
+\cs_new_protected:Npn \pdf_destination:nn #1#2
+  { \__pdf_backend_destination:nn {#1} {#2} }
+\cs_new_protected:Npn \pdf_destination:nnnn #1#2#3#4
+  {
+    \hbox_to_zero:n
+      { \__pdf_backend_destination:nnnn {#1} {#2} {#3} {#4} }
+  }
 %% File: l3coffins.dtx
 \box_new:N \l__coffin_internal_box
 \dim_new:N \l__coffin_internal_dim
@@ -28276,26 +29818,6 @@
     \tl_set:Nn \l__coffin_display_font_tl
       { \sffamily \tiny }
   }
-\cs_new_protected:Npn \__coffin_color:n #1 {#1}
-\bool_lazy_and:nnT
-  { \cs_if_exist_p:N \fmtname }
-  { \str_if_eq_p:Vn \fmtname { LaTeX2e } }
-  {
-    \cs_gset_protected:Npn \__coffin_color:n
-      {
-        \cs_gset_protected:Npx \__coffin_color:n
-          {
-            \cs_if_exist:NTF \color_select:n
-              { \color_select:n }
-              {
-                \cs_if_exist:NTF \color
-                  { \exp_not:N \color }
-                  { \exp_not:N \use_none:n }
-              }
-          }
-        \__coffin_color:n
-      }
-  }
 \cs_new_protected:Npn \__coffin_rule:nn #1#2
   {
     \mode_leave_vertical:
@@ -28305,7 +29827,7 @@
   {
     \hcoffin_set:Nn \l__coffin_display_pole_coffin
       {
-        \__coffin_color:n {#4}
+        \color_select:n {#4}
         \__coffin_rule:nn { 1pt } { 1pt }
       }
     \__coffin_attach_mark:NnnNnnnn #1 {#2} {#3}
@@ -28312,7 +29834,7 @@
       \l__coffin_display_pole_coffin { hc } { vc } { 0pt } { 0pt }
     \hcoffin_set:Nn \l__coffin_display_coord_coffin
       {
-        \__coffin_color:n {#4}
+        \color_select:n {#4}
         \l__coffin_display_font_tl
         ( \tl_to_str:n { #2 , #3 } )
       }
@@ -28350,7 +29872,7 @@
   {
     \hcoffin_set:Nn \l__coffin_display_pole_coffin
       {
-        \__coffin_color:n {#2}
+        \color_select:n {#2}
         \__coffin_rule:nn { 1pt } { 1pt }
       }
     \prop_set_eq:Nc \l__coffin_display_poles_prop
@@ -28385,7 +29907,7 @@
               { 0pt } { 0pt }
             \hcoffin_set:Nn \l__coffin_display_coord_coffin
               {
-                \__coffin_color:n {#6}
+                \color_select:n {#6}
                 \l__coffin_display_font_tl
                 ( \tl_to_str:n { #1 , ##1 } )
               }

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex	2021-02-18 22:17:56 UTC (rev 57789)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2021-02-06}%
+\def\ExplFileDate{2021-02-18}%
 \let\ExplLoaderFileDate\ExplFileDate
 \begingroup
   \catcode`\_=11

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx	2021-02-18 22:17:56 UTC (rev 57789)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2021-02-06}%
+\def\ExplFileDate{2021-02-18}%
 \let\ExplLoaderFileDate\ExplFileDate
 \begingroup
   \catcode`\_=11

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty	2021-02-18 21:47:38 UTC (rev 57788)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty	2021-02-18 22:17:56 UTC (rev 57789)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2021-02-06}%
+\def\ExplFileDate{2021-02-18}%
 \let\ExplLoaderFileDate\ExplFileDate
 \ProvidesPackage{expl3}
   [%



More information about the tex-live-commits mailing list.