%%
%% This is file 'bxcoloremoji.sty'.
%%
%% Copyright (c) 2017-2026 Takayuki YATO (aka. "ZR")
%%   GitHub:   https://github.com/zr-tex8r
%%   Twitter:  @zr_tex8r
%%
%% This package is distributed under the MIT License.
%%

%% package declarations
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{bxcoloremoji}[2026/06/22 v1.1]
\def\bxce@pkgname{bxcoloremoji}
\providecommand\bxDebug[1]{}

%% code guard
\edef\bxce@restore@codes{%
  \catcode33=\the\catcode33%
  \catcode34=\the\catcode34%
  \catcode39=\the\catcode39%
  \catcode43=\the\catcode43%
  \catcode45=\the\catcode45%
  \catcode46=\the\catcode46%
  \catcode47=\the\catcode47%
  \catcode58=\the\catcode58%
  \catcode59=\the\catcode59%
  \catcode60=\the\catcode60%
  \catcode62=\the\catcode62%
  \catcode63=\the\catcode63%
  \catcode96=\the\catcode96%
  \catcode124=\the\catcode124%
  \catcode126=\the\catcode126%
  \endlinechar=\the\endlinechar%
\relax}
\catcode33=12 % <!>
\catcode34=12 % <">
\catcode39=12 % <'>
\catcode43=12 % <+>
\catcode45=12 % <->
\catcode46=12 % <.>
\catcode47=12 % </>
\catcode58=12 % <:>
\catcode59=12 % <;>
\catcode60=12 % <<>
\catcode62=12 % <>>
\catcode63=12 % <?>
\catcode96=12 % <`>
\catcode124=12 % <|>
\catcode126=13 % <~>
\AtEndOfPackage{%
  \bxce@restore@codes
  \let\bxce@restore@codes\relax}

%--------------------------------------- public settings

%% packages
\RequirePackage{etoolbox}[2011/01/03]% v2.1
\RequirePackage{keyval}

%% e-TeX check
\ifx\numdef\@undefined % etoolbox is aborted
  % etoolbox has already issued an error
  \PackageWarningNoLine\bxce@pkgname
   {Package loading is aborted}
  \DeclareOption*{}
  \ProcessOptions*
\expandafter\endinput\fi\relax

%%<*D> \coloremojidir : base directory
\newcommand*\coloremojidir{emoji_images/}
\chardef\bxce@abool@@false=0
\chardef\bxce@abool@@auto=1
\chardef\bxce@abool@@true=2
%% switch bxce@nodvidriver@opt : is 'nodvidriver' given?
\newbool{bxce@nodvidriver@opt}
%% \bxce@bbparam@opt : 'bbparam' value
\let\bxce@bbparam@opt\bxce@abool@@auto
%% \bxce@jatype@opt : 'jatype' value
\let\bxce@jatype@opt\bxce@abool@@auto
%% switch bxce@names
\newbool{bxce@names}
\bxce@namestrue
%% \bxce@preload@names@opt : 'preload-names' value
\let\bxce@preload@names@opt\bxce@abool@@auto
%% \bxce@bxghost@opt : 'bxghost' value
\let\bxce@bxghost@opt\bxce@abool@@auto
%% \bxce@output@type : output type
\chardef\bxce@ot@@none=0   % no image
\chardef\bxce@ot@@std=1    % use standard family
\chardef\bxce@ot@@custom=2 % use custom family
\chardef\bxce@ot@@twemojis=3 % use twemojis package
\let\bxce@output@type\bxce@ot@@none
%% switch bxce@use@pua
\newbool{bxce@use@pua}
%% switch bxce@twm@skip@tikz
\newbool{bxce@twm@skip@tikz}
\bxce@twm@skip@tikztrue
%% switch bxce@dvisvgm@adjust
\newbool{bxce@dvisvgm@adjust}
\bxce@dvisvgm@adjusttrue
%% bxce@family : image family
\let\bxce@family\@undefined
%% bxce@bb : image bbox
\let\bxce@bb\relax
%% bxce@ext : image file extension
\let\bxce@ext\relax
%% bxce@prefix : image file prefix
\let\bxce@prefix\relax
%% bxce@scale : image scale
\def\bxce@scale{1}
%% bxce@size : image size
\let\bxce@size\@empty
%% bxce@size@var : image size for *-form
\let\bxce@size@var\@empty
%% \bxce@count@from : starting value of emoji orders
% (used in \coloremoji(code)successor(of))
\def\bxce@count@from{1}

%% switch bxce@in@command
% Whether the key process is for command options.
\newif\ifbxce@in@command

%% \bxce@opt@in@cmd{<name>}{<code>}
% Process a key that is only valid in command options.
\def\bxce@opt@in@cmd#1#2{%
  \ifbxce@in@command #2%
  \else \bxce@err@naopt{#1}%
  \fi
}

%% \bxce@expd{<code>}
% Fully-expands the code and runs it.
\def\bxce@expd#1{%
  \edef\bxce@tmp@expd{#1}%
  \bxce@tmp@expd
}

%% \bxce@initialize@setup
\def\bxce@initialize@setup{%
  \let\bxce@output@type\bxce@ot@@none
  \let\bxce@family\relax
  \let\bxce@bb\relax
  \let\bxce@ext\relax
  \let\bxce@prefix\relax
}

%% \bxce@warn@dpcmd
\def\bxce@warn@dpcmd{%
  \PackageWarningNoLine\bxce@pkgname
   {Parameter '\string\coloremojidir' is DEPRECATED\MessageBreak
    and will be abolished in future, where\MessageBreak
    the parameter is ignored and regarded as\MessageBreak
    always empty}%
}

%% \bxce@warn@dpopt{<name>}
\def\bxce@warn@dpopt#1{%
  \PackageWarningNoLine\bxce@pkgname
   {Option '#1' is DEPRECATED\MessageBreak
    and will be abolished in future.\MessageBreak
    It might no longer work now}%
}

%% \bxce@err@ivval{<name>}{<value>}
\def\bxce@err@ivval#1#2{%
  \PackageError\bxce@pkgname
   {Invalid value for key '#1' found\MessageBreak
    (#2)}%
   {\@eha}%
}

%% \bxce@err@naopt{<name>}
\def\bxce@err@naopt#1{%
  \PackageError\bxce@pkgname
   {You cannot use '#1' here}%
   {\@eha}%
}

%% \bxce@check@opt@key{<key>}{<value>}{<check>}{<true>}{<false>}
\def\bxce@check@opt@key#1#2#3#4#5{%
  \ifcsdef{#3#2}{#4}{%else
    \bxce@err@ivval{#1}{#2}%
    #5%
  }%
}

%% \bxce@invalidate@opt@key{<name>}
\def\bxce@invalidate@opt@key#1{%
  \define@key{bxce}{#1}[]{\bxce@err@naopt{#1}}%
}

%% family options
\define@key{bxce}{no-image}[]{%
  \bxce@initialize@setup
}
\define@key{bxce}{twemoji-pdf}[]{%
  \bxce@use@custom@family{twemoji-pdf}%
}
\define@key{bxce}{twemoji-png}[]{%
  \bxce@use@custom@family{twemoji-png}%
}
%% 'twemojis'
\define@key{bxce}{twemojis}[]{%
  \bxce@initialize@setup
  \let\bxce@output@type\bxce@ot@@twemojis
  \def\bxce@family{twemojis}%
  \def\bxce@bb{0 0 27 27}%
}
\define@key{bxce}{twitter}[]{% *DEPRECATED*
  \bxce@warn@dpopt{twitter}%
  \let\bxce@output@type\bxce@ot@@std
  \def\bxce@family{twitter}%
  \def\bxce@bb{0 0 38 38}%
  \def\bxce@ext{pdf}%
  \def\bxce@prefix{\coloremojidir twitter/}%
}
\define@key{bxce}{hires}[]{% *DEPRECATED*
  \bxce@warn@dpopt{hires}%
  \let\bxce@output@type\bxce@ot@@std
  \def\bxce@family{hires}%
  \def\bxce@bb{0 0 11.338600 11.338600}%
  \def\bxce@ext{pdf}%
  \def\bxce@prefix{\coloremojidir hires/}%
}
\define@key{bxce}{lowres}[]{% *DEPRECATED*
  \bxce@warn@dpopt{lowres}%
  \let\bxce@output@type\bxce@ot@@std
  \def\bxce@family{lowres}%
  \def\bxce@bb{0 0 4.535430 4.535430}%
  \def\bxce@ext{pdf}%
  \def\bxce@prefix{\coloremojidir lowres/}%
}

%% 'scale=<real>'
\define@key{bxce}{scale}{%
  \def\bxce@scale{#1}%
}

%% 'size=<length>'
\define@key{bxce}{size}{%
  \def\bxce@size{#1}%
}
%% 'size*=<length>'
\define@key{bxce}{size*}{%
  \def\bxce@size@var{#1}%
}

%% 'basedir=<path>'
\define@key{bxce}{basedir}{% *DEPRECATED*
  \bxce@warn@dpopt{basedir}%
  \def\coloremojidir{#1}%
}

%% 'bbparam=<bool/auto>'
\define@key{bxce}{bbparam}[true]{%
  \bxce@check@opt@key{bbparam}{#1}{bxce@abool@@}{%
    \letcs\bxce@bbparam@opt{bxce@abool@@#1}%
  }{}%
}

%% 'jatype=<bool/auto>'
\define@key{bxce}{jatype}[true]{%
  \bxce@check@opt@key{jatype}{#1}{bxce@abool@@}{%
    \letcs\bxce@jatype@opt{bxce@abool@@#1}%
  }{}%
}

%% 'names=<bool>'
\define@key{bxce}{names}[true]{%
  \bxce@check@opt@key{names}{#1}{bxce@names}{%
    \csuse{bxce@names#1}%
  }{}%
}

%% 'preload-names=<bool/auto>'
\define@key{bxce}{preload-names}[true]{%
  \bxce@check@opt@key{preload-names}{#1}{bxce@abool@@}{%
    \letcs\bxce@preload@names@opt{bxce@abool@@#1}%
  }{}%
}

%% 'bxghost=<bool/auto>'
\define@key{bxce}{bxghost}[true]{%
  \bxce@check@opt@key{bxghost}{#1}{bxce@abool@@}{%
    \letcs\bxce@bxghost@opt{bxce@abool@@#1}%
  }{}%
}

%% 'pua=<bool>'
\define@key{bxce}{pua}[true]{%
  \bxce@check@opt@key{pua}{#1}{bxce@use@pua}{%
    \csuse{bxce@use@pua#1}%
  }{}%
}

%% 'twemojis-skip-tikz=<bool>'
\define@key{bxce}{twemojis-skip-tikz}[true]{%
  \bxce@check@opt@key{twemojis-skip-tikz}{#1}{bxce@twm@skip@tikz}{%
    \csuse{bxce@twm@skip@tikz#1}%
  }{}%
}

%% 'dvisvgm-adjust=<bool>'
\define@key{bxce}{dvisvgm-adjust}[true]{%
  \bxce@check@opt@key{dvisvgm-adjust}{#1}{bxce@dvisvgm@adjust}{%
    \csuse{bxce@dvisvgm@adjust#1}%
  }{}%
}

%% 'count-from=<number>'
\define@key{bxce}{count-from}{%
  \def\bxce@count@from{#1}%
}

%% 'family=<name>'
\define@key{bxce}{family}{%
  \bxce@use@custom@family{#1}%
}
% tentative definition, redefined later
\def\bxce@use@custom@family#1{%
  \bxce@initialize@setup
  \let\bxce@output@type\bxce@ot@@custom
  \def\bxce@family{#1}%
}

%--------------------------------------- package options

%% 'nodvidriver'
\DeclareOption{nodvidriver}{%
  \bxce@nodvidriver@opttrue
}
%% 'resetdvidriver'
\DeclareOption{resetdvidriver}{%
  \bxce@nodvidriver@optfalse
}
%% keyval options
\DeclareOption*{%
  \bxce@expd{\noexpand\setkeys{bxce}{\CurrentOption}}%
}
%% dispatch
\ProcessOptions*

%% set default family
\unless\ifdefined\bxce@family
  \setkeys{bxce}{twemojis}
\fi

%% invalidate some keys
\bxce@invalidate@opt@key{basedir}
\bxce@invalidate@opt@key{bbparam}
\bxce@invalidate@opt@key{jatype}
\bxce@invalidate@opt@key{names}
\bxce@invalidate@opt@key{preload-names}
\bxce@invalidate@opt@key{bxghost}
\bxce@invalidate@opt@key{twemoji-skip-tikz}

\AtBeginDocument{%
  \@tempswatrue
  \def\bxce@do{\ifx\coloremojidir\bxce@tmpa\@tempswafalse\fi}%
  \def\bxce@tmpa{emoji_images/}\bxce@do
  \let\bxce@tmpa\@empty\bxce@do \long\def\bxce@tmpa{}\bxce@do
  \if@tempswa \bxce@warn@dpcmd \fi
}

%--------------------------------------- environment check

%% \bxce@engine : engine type
\let\bxce@engine\relax
%% switch 'bxce@jaok' : Japanese OK?
\newbool{bxce@jaok}
%% switch 'bxce@ptex' : engine is pTeX-ish?
\newbool{bxce@ptex}
%% switch 'bxce@hitex' : engine is HiTeX-ish?
\newbool{bxce@hitex}
%% switch 'bxce@raw@graphics@avail' : raw graphics is available?
\newbool{bxce@raw@graphics@avail}
%% \bxce@raw@put@image : raw graphics handler
\let\bxce@raw@put@image\@undefined
%% switch 'bxce@ucs@avail' : '\ucs' (of pTeX) is available?
\newbool{bxce@ucs@avail}
%% switch 'bxce@luatexja' : LuaTeX-ja is loaded?
\newbool{bxce@luatexja}
%% switch 'bxce@CJK' : CJK is loaded?
\newbool{bxce@CJK}
%% switch 'bxce@inputenc' : use inputenc?
\newbool{bxce@inputenc}
%% switch 'bxce@use@image' : use images?
\newbool{bxce@use@image}
%% switch 'bxce@use@bb' : use bb parameter?
\newbool{bxce@use@bb}
%% switch 'bxce@bxghost' : use bxghost?
\newbool{bxce@bxghost}

%% set \bxce@engine
\@onlypreamble\bxce@if@primitive
\def\bxce@if@primitive#1#2{%
  \edef\bxce@tmpa{\string#1}\edef\bxce@tmpb{\meaning#1}%
  \ifx\bxce@tmpa\bxce@tmpb #2\fi
}
\let\bxce@engine=d
\bxce@if@primitive\Uchar{\let\bxce@engine=w}
\bxce@if@primitive\kanjiskip{\let\bxce@engine=p}
\bxce@if@primitive\enablecjktoken{\let\bxce@engine=u}
\bxce@if@primitive\XeTeXversion{\let\bxce@engine=x}
\bxce@if@primitive\luatexversion{\let\bxce@engine=l}
% Here upTeX whose internal kanji code is not Unicode
% will be regarded as 'pTeX'.
\if u\bxce@engine
  \ifnum\ucs"3000="3000 \else \let\bxce@engine=p\fi
\fi

%% set switch 'bxce@ptex'
\bxce@ptexfalse
\if p\bxce@engine \bxce@ptextrue \fi
\if u\bxce@engine \bxce@ptextrue \fi
% NB. bxce@luatexja will be set at \bxce@resolve@image@metric

%% set switch 'bxce@ucs@avail'
\bxce@ucs@availfalse
\ifbxce@ptex
  \bxce@if@primitive\ucs{\bxce@ucs@availtrue}
\fi

%% set switch 'bxce@hitex'
% NB. Currently HiTeX does not support PDF inclusion.
\bxce@if@primitive\HINTversion{\bxce@hitextrue}

%% set switch 'bxce@raw@graphics@avail'
\ifbxce@hitex \bxce@raw@graphics@availtrue \fi

%% \bxce@check@inputenc
\let\bxce@check@inputenc\relax
\ifnum0\ifbxce@ptex1\fi\ifx d\bxce@engine1\fi >0
  \def\bxce@tmpa{utf8}%
  \ifx\inputencodingname\bxce@tmpa
    \bxce@inputenctrue
  \else\unless\ifx u\bxce@engine
    \def\bxce@check@inputenc{%
      \global\let\bxce@check@inputenc\relax
      \PackageError\bxce@pkgname
       {You must load 'inputenc' before this package\MessageBreak
        and use input encoding 'utf8'}\@ehc
    }%
  \fi\fi
\fi

%% set switch 'bxce@use@image'
\unless\ifbxce@nodvidriver@opt
  \bxce@use@imagetrue
\fi

%% \bxce@resolve@image@setup
\bxce@use@bbfalse
\def\bxce@resolve@image@setup{%
  \global\let\bxce@resolve@image@setup\relax
  \ifbxce@use@image \unless\ifbxce@raw@graphics@avail
    \@ifpackageloaded{graphicx}{}{%else
      \PackageError\bxce@pkgname
       {Package 'graphicx' is not loaded}\@ehc
      \global\bxce@use@imagefalse
    }%
  \fi\fi
  \unless\ifbxce@use@image
  \else\ifbxce@hitex
    \bxce@okfalse
    \ifx\Gin@driver\@undefined \bxce@oktrue \fi
    \def\bxce@tmpa{dvips.def}%
    \ifx\Gin@driver\bxce@tmpa \bxce@oktrue \fi
    \unless\ifnum\bxce@bbparam@opt=\bxce@abool@@false
      \global\bxce@use@bbtrue
    \fi
    \ifbxce@ok
      \global\let\bxce@raw@put@image\bxce@raw@put@image@hitex
    \fi
  \else\ifnum\bxce@bbparam@opt=\bxce@abool@@true
    \global\bxce@use@bbtrue
  \else\ifnum\bxce@bbparam@opt=\bxce@abool@@auto
    \def\bxce@tmpa{dvipdfmx.def}%
    \ifx\Gin@driver\bxce@tmpa \global\bxce@use@bbtrue \fi
    \def\bxce@tmpa{dvipdfm.def}%
    \ifx\Gin@driver\bxce@tmpa \global\bxce@use@bbtrue \fi
    \def\bxce@tmpa{dvisvgm.def}%
    \ifx\Gin@driver\bxce@tmpa
      \global\bxce@use@bbtrue
      \ifbxce@dvisvgm@adjust
        \global\let\bxce@driver@hook\bxce@driver@hook@dvisvgm
        \global\let\bxce@Ginclude@bitmap\bxce@Ginclude@bitmap@dvisvgm
      \fi
    \fi
  \fi\fi\fi\fi
  \bxce@resolve@image@metric
}
\AtBeginDocument{\bxce@resolve@image@setup}
% auto-load graphicx if possible
\ifbxce@use@image
  % check if a global driver option is given
  \chardef\bxce@do\z@
  \@for\bxce@tmpa:=\@classoptionslist\do{%
    \@for\bxce@tmpb:={dvipdfmx,dvipdfm,dvisvgm,dvips}\do{%
      \ifx\bxce@tmpa\bxce@tmpb \chardef\bxce@do\@ne \fi
    }
  }
  \ifnum\ifnum\bxce@do>\z@ \@ne
        \else\ifdefined\pdfoutput \pdfoutput
        \else\ifdefined\outputmode \outputmode
        \else\ifx x\bxce@engine \@ne
        \else \z@ \fi\fi\fi\fi >\z@
    \RequirePackage{graphicx}[]%
    \@ifpackageloaded{xcolor}{}{%else
      \@ifl@t@r\fmtversion{2021/06/01}{%
        \RequirePackage{color}[]%
      }{}%
    }
    % if 'twemojis' option is given auto-load 'twemojis' package
    \ifnum\bxce@output@type=\bxce@ot@@twemojis
        \@ifpackageloaded{tikz}{\bxce@twm@skip@tikzfalse}{}%
        \ifbxce@twm@skip@tikz
          % avoid loading tikz in twemojis
          \cslet{ver@tikz.sty}\@empty
          \RequirePackage{twemojis}[]%
          \csundef{ver@tikz.sty}%
        \else
          \RequirePackage{twemojis}[]%
        \fi
      \@ifpackageloaded{twemojis}{}{%else
        % not installed, error is already issued
        \bxce@use@imagefalse
      }
    \fi
  \fi
\fi

%% set switch 'bxce@bxghost'
\ifnum\bxce@jatype@opt=\bxce@abool@@false % skip
\else\ifnum\bxce@bxghost@opt=\bxce@abool@@true
  \bxce@bxghosttrue
\else\ifnum\bxce@bxghost@opt=\bxce@abool@@auto
  \@ifpackageloaded{luatexja}{\let\bxce@tmpa=t}{\let\bxce@tmpa=f}
  \if \ifbxce@ptex T\else\if t\bxce@tmpa T\else F\fi\fi T%
    \IfFileExists{bxghost-lib.sty}{\bxce@bxghosttrue}{}
  \fi
\fi\fi\fi
\ifbxce@bxghost
  \IfFileExists{bxghost-lib.sty}{%
    \RequirePackage{bxghost-lib}[]%
  }{%else
    \RequirePackage{bxghost}[]%
  }
  \unless\ifdefined\jghostguarded
    % not installed, error is already issued
    \bxce@bxghostfalse
  \fi
\fi

%--------------------------------------- helpers

%% variables
\newbool{bxce@ok}
\newcount\bxce@cnta
\newcount\bxce@cnto
\let\bxce@arg\relax
% (flags)
%[bxce@f/ee] : error occurred in input text expansion
%[bxce@f/jg] : ja-geta is needed in PDF strings

%% unique tokens
\def\bxce@end{\bxce@end@}
\def\bxce@mt{\bxce@mt@}
\let\bxce@mk\indent

%% \bxce@hex{<number>}
\letcs\bxce@hex{int_to_Hex:n}
\unless\ifdefined\bxce@hex
  \input{binhex}
  \let\bxce@hex\hex
\fi

%% \bxce@@BS
\begingroup \lccode`\*=`\\
\lowercase{\global\let\bxce@@BS=*}
\endgroup

%% \bxce@nihil
\def\bxce@nihil{%
  \vrule\@width\z@\relax
}

%% \bxce@cond\ifXXX...\fi{<true>}{<false>}
\@gobbletwo\if\if \def\bxce@cond#1\fi{%
  #1\expandafter\@firstoftwo
  \else \expandafter\@secondoftwo \fi
}

%% \bxce@skip@space\CScont<space>
\def\bxce@skip@space#1 {#1}

%% \bxce@raise@flag{<name>}
\def\bxce@raise@flag#1{%
  \expandafter\@gobble\csname bxce@f/#1\endcsname
}
%% \bxce@if@flag@raised{<name>}
\def\bxce@if@flag@raised#1{%
  \ifcsdef{bxce@f/#1}%
}

%% \bxce@hedge@options@with\CS<options>{<arg>}
% Expands to \CS{<options>}{<arg>}.
\def\bxce@hedge@options@with#1#2#{% brace delimit
  #1{#2}%
}

%% \bxce@with@star{<str>}{<true>}{<false>}
% Checks whether the string starts with '*'.
\def\bxce@with@star#1{%
  \bxce@with@star@a#1.\bxce@end
}
\def\bxce@with@star@a#1#2\bxce@end{%
  \bxce@cond\ifx*#1\fi
}

%% \bxce@lowercase@edef
\def\bxce@lowercase@edef#1#2{%
  \edef\bxce@tmp@le{\noexpand\bxce@lowercase@edef@a{#2}}%
  \bxce@tmp@le#1%
}
\def\bxce@lowercase@edef@a#1#2{%
  \lowercase{\def#2{#1}}%
}

%--------------------------------------- character database

%% character properties
\chardef\bxce@cp@base=1 % base char
\chardef\bxce@cp@comb=2 % combining char
\chardef\bxce@cp@mod=7 % modifier char
\chardef\bxce@cp@ris=3 % region indicator
\chardef\bxce@cp@evs=4 % emoji variant selector
\chardef\bxce@cp@zwj=5 % zero width joiner
\chardef\bxce@cp@tag=6 % tag char

%% constants
%[bxce@cp/<code>] : Unicode -> char property
%[bxce@ju/<jis>] : JIS-code -> Unicode (for jachar trick)

%% variables
\let\bxce@cp\relax

%% \bxce@@<codevalue>;
\let\bxce@@\relax % normally unexpandable

%% \bxce@csn@cp{<codevalue>}
\def\bxce@csn@cp#1{%
  bxce@cp/\number#1%
}
\ifbxce@use@pua
  \def\bxce@csn@cp#1{%
    bxce@cp/%
    \ifnum#1<"E000 \number#1%
    \else\ifnum#1<"F900 48%
    \else\ifnum#1<"F0000 \number#1%
    \else 48%
    \fi\fi\fi
  }
\fi

%% \bxce@set@cp<cp-value>{<range>,...}
\@onlypreamble\bxce@set@cp
\def\bxce@set@cp#1#2{%
  \let\bxce@cp=#1%
  \@for\bxce@arg:={#2}\do{%
    \expandafter\bxce@set@cp@a\bxce@arg--\bxce@end}%
}
\@onlypreamble\bxce@set@cp@a
\def\bxce@set@cp@a#1-#2-#3\bxce@end{%
  \ifx-#2-\bxce@set@cp@b{#1}{#1}%
  \else \bxce@set@cp@b{#1}{#2}%
  \fi
}
\@onlypreamble\bxce@set@cp@b
\def\bxce@set@cp@b#1#2{%
  \bxce@cnta="#1\relax
  \numdef\bxce@tmpb{"#2+1}%
  \@whilenum{\bxce@cnta<\bxce@tmpb}\do{%
    \edef\bxce@arg{{\the\bxce@cnta}{\bxce@hex{\bxce@cnta}}}%
    \expandafter\bxce@set@cp@c\bxce@arg
    \advance\bxce@cnta1 }%
}
\@onlypreamble\bxce@set@cp@c
\def\bxce@set@cp@c#1#2{%
  \cslet{bxce@cp/#1}\bxce@cp
  \bxce@set@cp@d{#1}{#2}%
}
\@onlypreamble\bxce@set@cp@d
\ifx u\bxce@engine
\def\bxce@set@cp@d#1#2{%
  \ifbxce@inputenc
    \ifnum#1>127 \ifnum\kcatcode#1=15
      \DeclareUnicodeCharacter{#2}{\bxce@@#2;}%
    \fi\fi
  \else
    \PackageWarningNoLine\bxce@pkgname
     {Some emoji characters might not be output.\MessageBreak
      You must load 'inputenc' before this package\MessageBreak
      and use input encoding 'utf8'}
    \let\bxce@set@cp@d\@gobbletwo
  \fi
}
\else
\def\bxce@set@cp@d#1#2{%
  \ifbxce@inputenc\ifnum#1>127
    \DeclareUnicodeCharacter{#2}{\bxce@@#2;}%
  \fi\fi
}
\fi

%%-------- data

%% make [bxce@cp] table
\bxce@set@cp\bxce@cp@base{%
  0023,002A,0030-0039,00A9,00AE,203C,2049,2122,2139,2194-2199,%
  21A9-21AA,231A-231B,2328,23CF,23E9-23EC,23ED-23EE,23EF,23F0,%
  23F1-23F2,23F3,23F8-23FA,24C2,25AA-25AB,25B6,25C0,25FB-25FE,%
  2600-2601,2602-2603,2604,260E,2611,2614-2615,2618,261D,2620,%
  2622-2623,2626,262A,262E,262F,2638-2639,263A,2640,2642,2648-2653,%
  265F,2660,2663,2665-2666,2668,267B,267E,267F,2692,2693,2694,2695,%
  2696-2697,2699,269B-269C,26A0-26A1,26A7,26AA-26AB,26B0-26B1,%
  26BD-26BE,26C4-26C5,26C8,26CE,26CF,26D1,26D3,26D4,26E9,26EA,%
  26F0-26F1,26F2-26F3,26F4,26F5,26F7-26F9,26FA,26FD,2702,2705,%
  2708-270C,270D,270F,2712,2714,2716,271D,2721,2728,2733-2734,2744,%
  2747,274C,274E,2753-2755,2757,2763,2764,2795-2797,27A1,27B0,27BF,%
  2934-2935,2B05-2B07,2B1B-2B1C,2B50,2B55,3030,303D,3297,3299,1F004,%
  1F0CF,1F170-1F171,1F17E-1F17F,1F18E,1F191-1F19A,1F1E6-1F1FF,%
  1F201-1F202,1F21A,1F22F,1F232-1F23A,1F250-1F251,1F300-1F30C,%
  1F30D-1F30E,1F30F,1F310,1F311,1F312,1F313-1F315,1F316-1F318,1F319,%
  1F31A,1F31B,1F31C,1F31D-1F31E,1F31F-1F320,1F321,1F324-1F32C,%
  1F32D-1F32F,1F330-1F331,1F332-1F333,1F334-1F335,1F336,1F337-1F34A,%
  1F34B,1F34C-1F34F,1F350,1F351-1F37B,1F37C,1F37D,1F37E-1F37F,%
  1F380-1F393,1F396-1F397,1F399-1F39B,1F39E-1F39F,1F3A0-1F3C4,1F3C5,%
  1F3C6,1F3C7,1F3C8,1F3C9,1F3CA,1F3CB-1F3CE,1F3CF-1F3D3,1F3D4-1F3DF,%
  1F3E0-1F3E3,1F3E4,1F3E5-1F3F0,1F3F3,1F3F4,1F3F5,1F3F7,1F3F8-1F407,%
  1F408,1F409-1F40B,1F40C-1F40E,1F40F-1F410,1F411-1F412,1F413,1F414,%
  1F415,1F416,1F417-1F429,1F42A,1F42B-1F43E,1F43F,1F440,1F441,%
  1F442-1F464,1F465,1F466-1F46B,1F46C-1F46D,1F46E-1F4AC,1F4AD,%
  1F4AE-1F4B5,1F4B6-1F4B7,1F4B8-1F4EB,1F4EC-1F4ED,1F4EE,1F4EF,%
  1F4F0-1F4F4,1F4F5,1F4F6-1F4F7,1F4F8,1F4F9-1F4FC,1F4FD,1F4FF-1F502,%
  1F503,1F504-1F507,1F508,1F509,1F50A-1F514,1F515,1F516-1F52B,%
  1F52C-1F52D,1F52E-1F53D,1F549-1F54A,1F54B-1F54E,1F550-1F55B,%
  1F55C-1F567,1F56F-1F570,1F573-1F579,1F57A,1F587,1F58A-1F58D,1F590,%
  1F595-1F596,1F5A4,1F5A5,1F5A8,1F5B1-1F5B2,1F5BC,1F5C2-1F5C4,%
  1F5D1-1F5D3,1F5DC-1F5DE,1F5E1,1F5E3,1F5E8,1F5EF,1F5F3,1F5FA,%
  1F5FB-1F5FF,1F600,1F601-1F606,1F607-1F608,1F609-1F60D,1F60E,1F60F,%
  1F610,1F611,1F612-1F614,1F615,1F616,1F617,1F618,1F619,1F61A,1F61B,%
  1F61C-1F61E,1F61F,1F620-1F625,1F626-1F627,1F628-1F62B,1F62C,1F62D,%
  1F62E-1F62F,1F630-1F633,1F634,1F635,1F636,1F637-1F640,1F641-1F644,%
  1F645-1F64F,1F680,1F681-1F682,1F683-1F685,1F686,1F687,1F688,1F689,%
  1F68A-1F68B,1F68C,1F68D,1F68E,1F68F,1F690,1F691-1F693,1F694,1F695,%
  1F696,1F697,1F698,1F699-1F69A,1F69B-1F6A1,1F6A2,1F6A3,1F6A4-1F6A5,%
  1F6A6,1F6A7-1F6AD,1F6AE-1F6B1,1F6B2,1F6B3-1F6B5,1F6B6,1F6B7-1F6B8,%
  1F6B9-1F6BE,1F6BF,1F6C0,1F6C1-1F6C5,1F6CB,1F6CC,1F6CD-1F6CF,1F6D0,%
  1F6D1-1F6D2,1F6D5,1F6D6-1F6D7,1F6DD-1F6DF,1F6E0-1F6E5,1F6E9,%
  1F6EB-1F6EC,1F6F0,1F6F3,1F6F4-1F6F6,1F6F7-1F6F8,1F6F9,1F6FA,%
  1F6FB-1F6FC,1F7E0-1F7EB,1F7F0,1F90C,1F90D-1F90F,1F910-1F918,%
  1F919-1F91E,1F91F,1F920-1F927,1F928-1F92F,1F930,1F931-1F932,%
  1F933-1F93A,1F93C-1F93E,1F93F,1F940-1F945,1F947-1F94B,1F94C,%
  1F94D-1F94F,1F950-1F95E,1F95F-1F96B,1F96C-1F970,1F971,1F972,%
  1F973-1F976,1F977-1F978,1F979,1F97A,1F97B,1F97C-1F97F,1F980-1F984,%
  1F985-1F991,1F992-1F997,1F998-1F9A2,1F9A3-1F9A4,1F9A5-1F9AA,%
  1F9AB-1F9AD,1F9AE-1F9AF,1F9B0-1F9B9,1F9BA-1F9BF,1F9C0,1F9C1-1F9C2,%
  1F9C3-1F9CA,1F9CB,1F9CC,1F9CD-1F9CF,1F9D0-1F9E6,1F9E7-1F9FF,%
  1FA70-1FA73,1FA74,1FA78-1FA7A,1FA7B-1FA7C,1FA80-1FA82,1FA83-1FA86,%
  1FA90-1FA95,1FA96-1FAA8,1FAA9-1FAAC,1FAB0-1FAB6,1FAB7-1FABA,%
  1FAC0-1FAC2,1FAC3-1FAC5,1FAD0-1FAD6,1FAD7-1FAD9,1FAE0-1FAE7,%
  1FAF0-1FAF6}
\bxce@set@cp\bxce@cp@comb{%
  20E0,20E3}
\bxce@set@cp\bxce@cp@mod{%
  1F3FB-1F3FF}
\bxce@set@cp\bxce@cp@ris{%
  1F1E6-1F1FF}
\bxce@set@cp\bxce@cp@evs{%
  FE0E-FE0F}
\bxce@set@cp\bxce@cp@zwj{%
  200D}
\bxce@set@cp\bxce@cp@tag{%
  E0020-E007F}

%% make [bxce@ju] table
\ifx p\bxce@engine
  \def\bxce@do#1#2{\csedef{bxce@ju/\jis"#1}{\number"#2}}
  \bxce@do{2169}{2642}
  \bxce@do{216A}{2640}
\fi

%--------------------------------------- user interface

%%<*> \coloremojisetup{<key>=<value>,...}
\newrobustcmd*{\coloremojisetup}[1]{%
  \setkeys{bxce}{#1}%
}

%%<*> \coloremoji*[<option>,...]{<text>}
\newrobustcmd*{\coloremoji}{%
  \bxce@enghost@with@opt\bxce@coloremoji@a
}
\def\bxce@coloremoji@a#1{%
  \bxce@ghost@guarded{%
    \bxce@parse@text{#1}%
    \bxce@output
  }%
}

% TODO: Make \coloremojiucs an alias to \coloremojicode.

%%<*> \coloremojiucs*[<option>,...]{<codevalue> ...}
\newrobustcmd*{\coloremojiucs}{%
  \bxce@enghost@with@opt\bxce@coloremojicode@a
}
\def\bxce@coloremojicode@a#1{%
  \bxce@ghost@guarded{%
    \bxce@parse@text@ccseq{#1}%
    \bxce@output
  }%
}

%%<*> \coloremojicode*[<option>,...]{<codevalue> ...}
% An alias to \coloremojiucs.
\newcommand*{\coloremojicode}{\coloremojiucs}

%--------------------------------------- parse text

%% variables
\newbool{bxce@escape}
\let\bxce@text\relax
\let\bxce@cseq\@empty

%% error messages
\def\bxce@err@intcc#1#2{%
  \PackageError\bxce@pkgname
   {INTERNAL ERROR (#1)\MessageBreak
    (code = U+#2)}%
   {\@ehc}%
}
\def\bxce@warn@locmb#1{%
  \PackageWarning\bxce@pkgname
   {Lone combining character found\MessageBreak
    (code = U+#1)}%
}
\def\bxce@warn@lotag#1{%
  \PackageWarning\bxce@pkgname
   {Lone tag character found\MessageBreak
    (code = U+#1)}%
}
\def\bxce@warn@loris#1{%
  \PackageWarning\bxce@pkgname
   {Unpaired region indicator symbol found\MessageBreak
    (code = U+#1)}%
}
\def\bxce@warn@lschr{%
  \PackageWarning\bxce@pkgname
   {Some characters given to \string\coloremoji\space are\MessageBreak
    unimplemented and thus lost,}%
}

%% \bxce@expand@text{<text>}
\def\bxce@expand@text#1{%
  \bxce@check@inputenc
  \begingroup
    \ifbxce@CJK \bxce@CJK@preproc
    \else \bxce@std@preproc
    \fi
    % Here protected expansion is needed, but still active UTF-8 byte
    % sequences need to be expanded.
    \ifdefined\UTFviii@two@octets@combine \bxce@newltx@patch \fi
    \let\GenericError\bxce@GenericError
    \def\bxce@@{\"}\let\IeC\@firstofone \let\"\relax
    \protected@xdef\@gtempa{#1}%
    \bxce@if@flag@raised{ee}{%
      \bxce@warn@lschr
    }{}%
  \endgroup
  \let\bxce@text\@gtempa
}
\def\bxce@GenericError#1#2#3#4{%
  \bxce@raise@flag{ee}}
\def\bxce@newltx@patch{%
  \let\UTF@two@octets@noexpand\@empty
  \let\UTF@three@octets@noexpand\@empty
  \let\UTF@four@octets@noexpand\@empty
}

%% \bxce@parse@text{<text>}
\def\bxce@parse@text#1{%
  \bxce@expand@text{#1}%
  \edef\bxce@text{\detokenize\expandafter{\bxce@text}}%
  \expandafter\bxce@parse@first\bxce@text\bxce@end
\bxDebug{first=\meaning\bxce@text}%
  \expandafter\bxce@parse@second\bxce@text\bxce@end
\bxDebug{second=\meaning\bxce@text}%
  \expandafter\bxce@parse@third\bxce@text\bxce@end
\bxDebug{third=\meaning\bxce@text}%
}
% first stage
\let\bxce@T\relax
\let\bxce@O\relax
\let\bxce@S\relax
\let\bxce@E\relax
\let\bxce@J\relax
\let\bxce@c\relax
\def\bxce@parse@first{%
  \let\bxce@text\@empty
  \bxce@escapefalse
  \bxce@parse@first@a
}
\def\bxce@parse@first@a{%
  \futurelet\bxce@arg\bxce@parse@first@b
}
\def\bxce@parse@first@b{%
  \bxce@cond\ifx\bxce@arg\bxce@end\fi{%
    \appto\bxce@text{\bxce@T.}%
    \@gobble
  }{\bxce@cond\ifx\bxce@arg\@sptoken\fi{%
    \bxce@escapefalse
    \appto\bxce@text{\bxce@S.}%
    \bxce@skip@space\bxce@parse@first@a
  }{\bxce@cond\ifbxce@escape\fi{%
    \bxce@parse@first@c
  }{%else
    \bxce@parse@first@d
  }}}%
}
\def\bxce@parse@first@c#1{%
  \bxce@escapefalse
  \bxce@cond\if#1"\fi{%
    \bxce@parse@first@f
  }{%else
    \bxce@parse@first@e{#1}%
    \bxce@parse@first@a
  }%
}
\def\bxce@parse@first@d#1{%
  \bxce@cond\if#1\bxce@@BS\fi{%
    \bxce@escapetrue
  }{%else
    \bxce@parse@first@e{#1}%
  }%
  \bxce@parse@first@a
}
\def\bxce@parse@first@e#1{%
  \bxce@cnta=`#1\relax
  \bxce@parse@first@trick#1%
  \letcs\bxce@tmpa{\bxce@csn@cp\bxce@cnta}%
  \ifdefined\bxce@tmpa
    \eappto\bxce@text{\bxce@E\the\bxce@tmpa{\bxce@hex{\bxce@cnta}}}%
  \else
    \appto\bxce@text{\bxce@O#1}%
  \fi
}
\def\bxce@parse@first@f#1;{%
  \bxce@cnta="#1\relax
  \letcs\bxce@tmpa{\bxce@csn@cp\bxce@cnta}%
  \unless\ifdefined\bxce@tmpa
    \chardef\bxce@tmpa\z@
    \bxce@err@intcc{1}{#1}%
  \fi
  \eappto\bxce@text{\bxce@E\the\bxce@tmpa{#1}}%
  \bxce@parse@first@a
}
% second stage
\def\bxce@parse@second{%
  \let\bxce@text\@empty
  \let\bxce@T\bxce@parse@second@T
  \let\bxce@O\bxce@parse@second@O
  \let\bxce@S\bxce@parse@second@S
  \let\bxce@E\bxce@parse@second@E
}
\protected\def\bxce@parse@second@T.\bxce@end{%
  \appto\bxce@text{\bxce@T}%
}
\protected\def\bxce@parse@second@O#1{%
  \appto\bxce@text{\bxce@O{#1}}%
}
\protected\def\bxce@parse@second@S#1{%
  \appto\bxce@text{\bxce@O{ }}%
}
\protected\def\bxce@parse@second@E#1#2#3#4{%
  % check if look-ahead is EVS
  \ifnum0\ifx#3\bxce@E \ifnum#4=\bxce@cp@evs 1\fi\fi=1
    \expandafter\bxce@parse@second@E@a
  \else \expandafter\bxce@parse@second@E@b
  \fi #1{#2}#3#4%
}
\def\bxce@parse@second@E@a#1#2#3#4#5{%
  % purge the EVS entry and go back
  \bxce@parse@second@E#1{#2}%
}
\def\bxce@parse@second@E@b#1#2#3#4{%
  % current character: #1=cp, #2=code
  % look-ahead character: #3=type, #4=cp
  \ifnum#1=\bxce@cp@base
    \ifnum0\ifx#3\bxce@E \ifnum#4=\bxce@cp@comb 1%
                         \else\ifnum#4=\bxce@cp@mod 1%
                         \else\ifnum#4=\bxce@cp@tag 1\fi\fi\fi\fi=1
      % head of modifier/combining sequence
      \def\bxce@cseq{#1{#2}}%
    \else
      % simple base character
      \appto\bxce@text{\bxce@E{#1{#2}}}%
    \fi
  \else\ifnum#1=\bxce@cp@comb
    \ifx\bxce@cseq\@empty
      % headless combining character, fallback
      \bxce@warn@locmb{#2}%
      \appto\bxce@text{\bxce@O{#2}}%
    \else\ifnum0\ifx#3\bxce@E \ifnum#4=\bxce@cp@comb 1\fi\fi=1
      % midst of combining sequence
      \appto\bxce@cseq{#1{#2}}%
    \else
      % tail of combining sequence
      \eappto\bxce@text{\bxce@E{\bxce@cseq#1{#2}}}%
      \let\bxce@cseq\@empty
    \fi\fi
  \else\ifnum#1=\bxce@cp@mod
    \ifx\bxce@cseq\@empty
      % baseless modifier character is a loner
      \eappto\bxce@text{\bxce@E{\the\bxce@cp@base{#2}}}%
    \else\ifnum0\ifx#3\bxce@E \ifnum#4=\bxce@cp@comb 1\fi\fi=1
      % midst of combining sequence
      \appto\bxce@cseq{#1{#2}}%
    \else
      % tail of modifier sequence
      \eappto\bxce@text{\bxce@E{\bxce@cseq#1{#2}}}%
      \let\bxce@cseq\@empty
    \fi\fi
  \else\ifnum#1=\bxce@cp@ris
    \ifx\bxce@cseq\@empty
      \ifnum0\ifx#3\bxce@E \ifnum#4=\bxce@cp@ris 1\fi\fi=1
        % nead of region indicator sequence
        \def\bxce@cseq{#1{#2}}%
      \else
        % lone region indicator characer, fallback
        \bxce@warn@loris{#2}%
        \eappto\bxce@text{\bxce@E{\the\bxce@cp@base{#2}}}%
      \fi
    \else
      % tail of region indicator sequence
      \eappto\bxce@text{\bxce@E{\bxce@cseq#1{#2}}}%
      \let\bxce@cseq\@empty
    \fi
  \else\ifnum#1=\bxce@cp@tag
    \ifx\bxce@cseq\@empty
      % headless tag character, fallback
      \bxce@warn@lotag{#2}%
      \appto\bxce@text{\bxce@O{#2}}%
    \else\ifnum0\ifx#3\bxce@E \ifnum#4=\bxce@cp@tag 1\fi\fi=1
      % midst of emoji tag sequence
      \appto\bxce@cseq{#1{#2}}%
    \else
      % tail of emoji tag sequence
      \eappto\bxce@text{\bxce@E{\bxce@cseq#1{#2}}}%
      \let\bxce@cseq\@empty
    \fi\fi
  \else\ifnum#1=\bxce@cp@evs
    % currently EVS is totally ignored
  \else\ifnum#1=\bxce@cp@zwj
    \appto\bxce@text{\bxce@J}%
  \fi\fi\fi\fi\fi\fi\fi
  #3#4% NB #4 is unbraced
}
% third stage
\def\bxce@parse@third{%
  \let\bxce@text\@empty
  \let\bxce@cseq\@empty
  \let\bxce@T\bxce@parse@third@T
  \let\bxce@O\bxce@parse@third@O
  \let\bxce@E\bxce@parse@third@E
  \let\bxce@J\bxce@parse@third@J
}
\protected\def\bxce@parse@third@T\bxce@end{}
\protected\def\bxce@parse@third@O#1{%
  \appto\bxce@text{\bxce@wr{#1}}%
}
\protected\def\bxce@parse@third@E#1#2{%
  \appto\bxce@cseq{#1}%
  \unless\ifx#2\bxce@J
    \bxce@parse@third@out
    \let\bxce@cseq\@empty
  \fi
  #2%
}
\protected\def\bxce@parse@third@J#1{%
  \ifx\bxce@cseq\@empty
    \appto\bxce@text{\bxce@put{200D}}%
  \else\unless\ifx#1\bxce@E
    \bxce@parse@third@out
    \let\bxce@cseq\@empty
    \appto\bxce@text{\bxce@put{200D}}%
  \else
    \eappto\bxce@cseq{\the\bxce@cp@zwj{200D}}%
  \fi\fi
  #1%
}
\def\bxce@parse@third@out{%
  \ifnum\bxce@output@type=\bxce@ot@@twemojis
    \bxce@twm@parse@third@out
  \else
    \bxce@parse@third@out@
  \fi
}
\def\bxce@parse@third@out@{%
  \let\bxce@tmpa\@empty
  \def\bxce@tmpb{\bxce@put@cseq}%
  \expandafter\bxce@parse@third@out@a\bxce@cseq..%
}
\def\bxce@parse@third@out@a#1#2{%
  \bxce@cond\ifx.#1\fi{%
    \eappto\bxce@text{\bxce@tmpb{\bxce@tmpa}}%
  }{%else
    \ifnum#1=\bxce@cp@tag
      \def\bxce@tmpb{\bxce@put@cseqtag}%
    \fi
    \appto\bxce@tmpa{\bxce@c{#2}}%
    \bxce@parse@third@out@a
  }%
}

%% \bxce@parse@text@ccseq
\def\bxce@parse@text@ccseq#1{%
  \bxce@parse@first@ccseq{#1}%
\bxDebug{first=\meaning\bxce@text}%
  \expandafter\bxce@parse@second\bxce@text\bxce@end
\bxDebug{second=\meaning\bxce@text}%
  \expandafter\bxce@parse@third\bxce@text\bxce@end
\bxDebug{third=\meaning\bxce@text}%
}
\def\bxce@parse@first@ccseq#1{%
  \edef\bxce@tmpa{#1}%
  \edef\bxce@tmpa{{\detokenize\expandafter{\bxce@tmpa}}}%
  \expandafter\bxce@parse@ccseq\bxce@tmpa\bxce@parse@first@ccseq@a
}
\def\bxce@parse@first@ccseq@a#1{%
  \let\bxce@do\bxce@parse@first@ccseq@do
  \let\bxce@bad\bxce@warn@ivcod
  \let\bxce@text\@empty
  #1%
  \appto\bxce@text{\bxce@T.}%
}

%% \bxce@parse@first@ccseq@do{<code-value>}
\def\bxce@parse@first@ccseq@do#1{%
  \bxce@cnta"0#1\relax
  \letcs\bxce@tmpa{\bxce@csn@cp\bxce@cnta}%
  \ifdefined\bxce@tmpa
    \eappto\bxce@text{\bxce@E\the\bxce@tmpa{#1}}%
  \else
    \bxce@char@token\bxce@tmpa\bxce@cnta
    \eappto\bxce@text{\bxce@O\bxce@tmpa}%
  \fi
}

%% \bxce@parse@first@trick<char>
% The engine-specific "trick".
\ifx p\bxce@engine % pTeX
  %% trick to hedge ja-chars
  \def\bxce@parse@first@trick#1{%
    \ifnum\bxce@cnta>\@cclv % ja-char
      \bxce@cnta0\@nameuse{bxce@ju/\the\bxce@cnta}\relax
    \fi
  }
\else\ifx x\bxce@engine % XeTeX
  %% trick to avoid anomaly of old XeTeX
  \def\bxce@parse@first@trick#1{%
    \@tempcnta\bxce@cnta \divide\@tempcnta"800
    \ifnum\@tempcnta=27 % surrogate value
      \bxce@parse@first@surrogate
    \fi
  }
  \def\bxce@parse@first@surrogate#1\bxce@parse@first@a#2{%
    \bxce@cnta=\numexpr\bxce@cnta*"400+`#2-"35FDC00\relax
    #1\bxce@parse@first@a % continue!
  }
\else
  \let\bxce@parse@first@trick\@gobble
\fi\fi

%--------------------------------------- twemojis something

%% constants
%[bxce@cptd/<code>] : defined if text-default emoji code

%% variables
\let\bxce@twm@good@name\relax

%% make [bxce@cptd] table
\def\bxce@set@cp@c#1#2{%
  \cslet{bxce@cptd/#1}\bxce@cp
}
\bxce@set@cp\@ne{%
  0023,002A,0030-0039,00A9,00AE,203C,2049,2122,2139,2194-2199,%
  21A9-21AA,2328,23CF,23ED-23EF,23F1-23F2,23F8-23FA,24C2,25AA-25AB,%
  25B6,25C0,25FB-25FC,2600-2604,260E,2611,2618,261D,2620,2622-2623,%
  2626,262A,262E-262F,2638-263A,2640,2642,265F-2660,2663,2665-2666,%
  2668,267B,267E,2692,2694-2697,2699,269B-269C,26A0,26A7,26B0-26B1,%
  26C8,26CF,26D1,26D3,26E9,26F0-26F1,26F4,26F7-26F9,2702,2708-2709,%
  270C-270D,270F,2712,2714,2716,271D,2721,2733-2734,2744,2747,%
  2763-2764,27A1,2934-2935,2B05-2B07,3030,303D,3297,3299,1F170-1F171,%
  1F17E-1F17F,1F202,1F237,1F321,1F324-1F32C,1F336,1F37D,1F396-1F397,%
  1F399-1F39B,1F39E-1F39F,1F3CB-1F3CE,1F3D4-1F3DF,1F3F3,1F3F5,1F3F7,%
  1F43F,1F441,1F4FD,1F549-1F54A,1F56F-1F570,1F573-1F579,1F587,%
  1F58A-1F58D,1F590,1F5A5,1F5A8,1F5B1-1F5B2,1F5BC,1F5C2-1F5C4,%
  1F5D1-1F5D3,1F5DC-1F5DE,1F5E1,1F5E3,1F5E8,1F5EF,1F5F3,1F5FA,1F6CB,%
  1F6CD-1F6CF,1F6E0-1F6E5,1F6E9,1F6F0,1F6F3}

%% \bxce@err@nltwm
\def\bxce@err@nltwm{%
  \PackageError\bxce@pkgname
   {Package 'twemojis' is not
    \ifdefined\bxce@raw@put@image available\else loaded\fi}%
   {\@ehc}%
}

%% \bxce@if@valid@twm@name{<twm-name>}
\def\bxce@if@valid@twm@name#1{%
  \ifcsdef{twemoji #1}%
}

%% \bxce@twm@dispatch
\def\bxce@twm@dispatch{%
  \twemoji
}

%% \bxce@if@twm@image@exists{<name>}
\def\bxce@if@twm@image@exists#1{%
  \bxce@lowercase@edef\bxce@tmpa{#1}%
  \bxce@if@valid@twm@name\bxce@tmpa
}

%% \bxce@twm@put@image{<name>}
\def\bxce@twm@put@image#1{%
  \bxce@lowercase@edef\bxce@tmpa{#1}%
\bxDebug{put@twm@image:\bxce@tmpa}%
  \bxce@expd{%
    \lower\bxce@disp@dim\hbox{%
      \ifbxce@ctdir\noexpand\rotatebox[origin=c]{90}\fi{%
      \noexpand\bxce@twm@dispatch
      [width=\bxce@cwd
      \ifbxce@use@bb\unless\ifx\bxce@bb\relax ,bb=\bxce@bb \fi\fi]%
      {\bxce@tmpa}}}}%
  \hskip\bxce@inter@skip
}

%% \bxce@twm@check@image@setup
\def\bxce@twm@check@image@setup{%
  \ifnum0%
      \ifdefined\defineTwemoji\unless\ifdefined\bxce@raw@put@image1\fi\fi
      >\z@
    \global\let\bxce@twm@check@image@setup\bxce@oktrue
    \bxce@oktrue
  \else
    \bxce@err@nltwm
    \global\let\bxce@err@nltwm\relax
    \bxce@okfalse
  \fi
}
\AtBeginDocument{%
  \ifnum\bxce@output@type=\bxce@ot@@twemojis
    \bxce@twm@check@image@setup
  \fi
}

%% \bxce@twm@parse@third@out
% The routine that replaces \bxce@parse@third@out in twemojis mode.
\let\bxce@c@evs\relax
\def\bxce@twm@parse@third@out{%
  \let\bxce@tmpa\@empty
  \def\bxce@tmpb{\bxce@put@cseq}%
  \expandafter\bxce@twm@parse@third@out@a\bxce@cseq..%
}
\def\bxce@twm@parse@third@out@a#1#2{%
  \bxce@cond\ifx.#1\fi{%
    \bxce@twm@find@good@name{\bxce@tmpa}%
\bxDebug{find@good@name:\bxce@tmpa->\bxce@twm@good@name}%
    \eappto\bxce@text{\bxce@tmpb{\bxce@twm@good@name}}%
  }{\bxce@cond\ifnum#1=\bxce@cp@base\fi{%
    \ifcsdef{bxce@cptd/\number"#2}{%
      \bxce@twm@parse@third@out@c{#1}{#2}%
    }{%else
    \bxce@twm@parse@third@out@b{#1}{#2}%
    }%
  }{%else
    \bxce@twm@parse@third@out@b{#1}{#2}%
  }}%
}
\def\bxce@twm@parse@third@out@b#1#2{%
  \ifnum#1=\bxce@cp@tag
    \def\bxce@tmpb{\bxce@put@cseqtag}%
  \fi
  \appto\bxce@tmpa{\bxce@c{#2}}%
  \bxce@twm@parse@third@out@a
}
\def\bxce@twm@parse@third@out@c#1#2#3{%
  \bxce@cond\ifnum\bxce@twm@dh{#3}=\bxce@cp@mod\fi{%
    \bxce@twm@parse@third@out@b{#1}{#2}{#3}%
  }{%else
    \appto\bxce@tmpa{\bxce@c{#2}\bxce@c@evs{FE0F}}%
    \bxce@twm@parse@third@out@a{#3}%
  }%
}
\def\bxce@twm@dh#1{%
  \if.#1\m@ne\else#1\fi
}

%% \bxce@twm@find@good@name{<name>}
% Finds the right name sequence by filling in the omitted EVSes,
% and sets to \bxce@twm@good@name.
\def\bxce@twm@find@good@name#1{%
  \begingroup
    \edef\bxce@twm@good@name{#1}%
    \bxce@twm@find@good@name@a\bxce@c
    \bxce@if@valid@twm@name\bxce@tmpa{}{%
      \bxce@twm@find@good@name@a\@gobble
    }%
  \endgroup
  \let\bxce@twm@good@name\bxce@g@tmpa
}
\def\bxce@twm@find@good@name@a#1{%
  \let\bxce@c\relax \def\bxce@c@evs{#1}%
  \xdef\bxce@g@tmpa{\bxce@twm@good@name}%
  \let\bxce@c\bxce@c@hyph
  \bxce@lowercase@edef\bxce@tmpa{\expandafter\bxce@c@first\bxce@g@tmpa}%
}

%--------------------------------------- emoji name database

%% variables
\let\bxce@ndindex\relax
%[bxce@nd/<name>] : name -> ccseq
%[bxce@ndi/<char>] : first char -> sector
%[bxce@ndrs/<sector>] : the sector is already read?

%% \bxce@read@name@data@file{<sector>}
\def\bxce@read@name@data@file#1{%
  \begingroup
    \endlinechar\m@ne
    \catcode13=9 \catcode32=10 \catcode64=11
    \catcode37=14 \catcode92=0 \catcode123=1 \catcode125=2
    \catcode45=12 \catcode46=12 \catcode47=12
    \catcode91=12 \catcode93=12
    \ifnum#1<\z@ % initialize
      \let\bxce@ndindex\m@ne
      \let\bxce@do\bxce@read@name@data@file@init@do
    \else\ifnum#1=\@M
      \chardef\bxce@ndindex\z@
      \PackageInfo\bxce@pkgname
       {Loading emoji name data file\MessageBreak
        (at once)}%
      \let\bxce@do\bxce@read@name@data@file@sec@do
      \bxce@prepare@load@all
    \else % read a sector
      \chardef\bxce@ndindex=#1\relax
      \PackageInfo\bxce@pkgname
       {Loading emoji name data file\MessageBreak
        (sector \the\bxce@ndindex)}%
      \global\cslet{bxce@ndrs/\the\bxce@ndindex}{t}%
      \let\bxce@do\bxce@read@name@data@file@sec@do
    \fi\fi
    \input{bxcoloremoji-names.def}%
  \endgroup
}
\let\bxce@ndbegin\relax
\let\bxce@ndend\relax
\def\bxce@read@name@data@file@init@do#1#2{%
  %\bxDebug{nd-init:#1=#2}%
  \csgdef{bxce@ndi/#1}{#2}%
}
\def\bxce@read@name@data@file@sec@do#1#2{%
  %\bxDebug{nd-sec-\the\bxce@ndindex:#1=#2}%
  \csgdef{bxce@nd/#1}{#2}%
}
% if 'names' is false, annihilate
\unless\ifbxce@names
  \let\bxce@read@name@data@file\@gobble
\fi

%% initialize
\bxce@read@name@data@file{-1}

%% additional definitions
\csgdef{bxce@nd/+}{200D}
\csgdef{bxce@nd/@}{E007F}
\csgdef{bxce@nd/!<}{2B05}
\csgdef{bxce@nd/!>}{27A1}
\csgdef{bxce@nd/!male}{2642}
\csgdef{bxce@nd/!female}{2640}
\csgdef{bxce@nd/!flag}{1F3F4}
\csgdef{bxce@nd/!black}{2B1B}
\csgdef{bxce@nd/!white}{2B1C}
\csgdef{bxce@nd/!red}{1F7E5}
\csgdef{bxce@nd/!blue}{1F7E6}
\csgdef{bxce@nd/!orange}{1F7E7}
\csgdef{bxce@nd/!yellow}{1F7E8}
\csgdef{bxce@nd/!green}{1F7E9}
\csgdef{bxce@nd/!purple}{1F7EA}
\csgdef{bxce@nd/!brown}{1F7EB}
\csgdef{bxce@nd//1}{1F3FB}
\csgdef{bxce@nd//2}{1F3FC}
\csgdef{bxce@nd//3}{1F3FD}
\csgdef{bxce@nd//4}{1F3FE}
\csgdef{bxce@nd//5}{1F3FF}
\csgdef{bxce@nd/!/red}{1F9B0}
\csgdef{bxce@nd/!/curly}{1F9B1}
\csgdef{bxce@nd/!/bald}{1F9B2}
\csgdef{bxce@nd/!/white}{1F9B3}
\AtEndOfPackage{%
  \begingroup
    \def\bxce@do#1"#2\relax{\def\bxce@tmpa{#2}}%
    \bxce@cnta="20
    \@whilenum{\bxce@cnta<"7F}\do{%
      % register '@!'--'@~' (U+E0021--E007E)
      \chardef\bxce@tmpa\bxce@cnta
      \expandafter\bxce@do\meaning\bxce@tmpa\relax
      \bxce@char@token\bxce@tmpb\bxce@cnta
      \csxdef{bxce@nd/@\bxce@tmpb}{E00\bxce@tmpa}%
      \ifnum\bxce@cnta>"40 \ifnum\bxce@cnta<"5B
        % register '!A'--'!Z' (U+1F1E6--1F1FF)
        \chardef\bxce@tmpa\numexpr\bxce@cnta+"A5\relax
        \expandafter\bxce@do\meaning\bxce@tmpa\relax
        \csxdef{bxce@nd/!\bxce@tmpb}{1F1\bxce@tmpa}%
      \fi\fi
      \advance\bxce@cnta\@ne
    }%
  \endgroup
}

%% \bxce@load@sname@definition{<sname>}
\def\bxce@load@sname@definition#1{%
  \bxce@load@sname@definition@a#1\bxce@end
}
\def\bxce@load@sname@definition@a#1#2\bxce@end{%
  \letcs\bxce@tmpa{bxce@ndi/#1}%
  \ifdefined\bxce@tmpa
    \ifcsdef{bxce@ndrs/\number\bxce@tmpa}{}{%else
      \bxce@read@name@data@file{\bxce@tmpa}%
    }%
  \fi
}

%%<+> \coloremojiLoadNames{<sname> ...}
\newrobustcmd*\coloremojiLoadNames[1]{%
  \edef\bxce@tmpa{#1}%
  \bxce@load@names
}
\def\bxce@load@names{%
  \edef\bxce@tmpa{\detokenize\expandafter{\bxce@tmpa} @ }%
  \expandafter\bxce@load@names@a\bxce@tmpa
}
\def\bxce@load@names@a#1 {%
  \bxce@cond\ifx @#1\fi{}{%else
    \bxce@load@names@b#1??\bxce@end
    \bxce@load@names@a
  }%
}
\def\bxce@load@names@b#1#2\bxce@end{%
  \ifx:#1%
    \bxce@load@sname@definition{#2}%
  \else
    \bxce@load@sname@definition{#1#2}%
  \fi
}

%%<+> \coloremojiLoadAllNames
\newrobustcmd*\coloremojiLoadAllNames{%
  \bxce@read@name@data@file\@M
  % annihilate
  \global\let\bxce@read@name@data@file\@undefined
  \global\let\bxce@load@sname@definition\@undefined
  \global\let\bxce@load@sname@definition@a\@undefined
  \global\let\bxce@load@names\relax
  \global\let\bxce@load@names@a\@undefined
  \global\let\bxce@load@names@b\@undefined
  \global\let\coloremojiLoadAllNames\relax
  \global\let\bxce@lookup@sname\bxce@parse@sname
}

%% \bxce@prepare@load@all
\begingroup \catcode`\|=0
  \gdef\bxce@prepare@load@all{%
    \def\bxce@ndbegin{|let|bxce@org@or|or|let|or|relax}%
    \def\bxce@ndend{|let|or|bxce@org@or}%
  }
\endgroup

%% exercise 'preload-names'
\ifnum0\unless\ifbxce@names 1%
    \else\ifnum\bxce@preload@names@opt=\bxce@abool@@true 1%
    \else\ifnum\bxce@preload@names@opt=\bxce@abool@@auto
      \if l\bxce@engine1\fi\if x\bxce@engine1\fi\if u\bxce@engine1\fi
      \ifcsname use:n\endcsname1\fi % expl3 is on
    \fi\fi\fi >\z@
  \AtEndOfPackage{\coloremojiLoadAllNames}%
\fi

%--------------------------------------- parse character code

% A character code is either of the following:
% - a hex string of the Unicode value (case-insensitive);
% - a short name input ':<short-name>:' (in lowercase);
%   here ':' of the either side can be omitted as long as the input
%   is unambiguous (not regarded as code value).

%% error message
\def\bxce@warn@ivcod#1{%
  \PackageWarning\bxce@pkgname
   {Invalid character code found\MessageBreak
    (#1)}%
}

%% \bxce@parse@ccseq{<cc> ...}\CScont
% Parses a character code sequence and returns the
% \bxce@do-list of the code values; i.e. it expands to
% \CScont{\bxce@do{<cv>}...}.
% Unknown names are converted to \bxce@bad{<name>}.
\def\bxce@parse@ccseq#1{%{<in>}|\CScont
  \bxce@parse@ccseq@a#1 @ @%
}
% (\bxce@parse@ccseq@a<in> @ <out>@\CScont)
\def\bxce@parse@ccseq@a#1 {%<cc> |...
  \bxce@cond\ifx @#1\fi{%
    \bxce@parse@ccseq@e
  }{\bxce@cond\ifx\bxce@mt#1\bxce@mt\fi{%empty-string
    \bxce@parse@ccseq@a
  }{%else
    \bxce@parse@cc{#1}\bxce@parse@ccseq@b\bxce@parse@ccseq@c
        \bxce@parse@ccseq@d{#1}%
  }}%
}
\def\bxce@parse@ccseq@b#1#2#3@#4@{%{<hex>}{<cc>}<in> @ <out>@|...
  \bxce@parse@ccseq@a#3@#4\bxce@do{#1}@%
}
\def\bxce@parse@ccseq@c#1#2{%{<seq>}{<cc>}|<in> @...
  \bxce@parse@ccseq@a#1 %
}
\def\bxce@parse@ccseq@d#1#2@#3@{%{<cc>}<in> @ <out>@|...
  \bxce@parse@ccseq@a#2@#3\bxce@bad{#1}@%
}
\def\bxce@parse@ccseq@e#1@#2{%<out>@\CScont
  #2{#1}%
}

%% \bxce@parse@cc{<cc>}\CSok\CSrs\CSerr
% Parses the character name or code value, and expands to:
% \CSok{<code-value>} if <cc> is a valid hex string;
% \CSrs{<out-cc> ...} if <Cc> is a short name; or
% \CSerr otherwise.
\def\bxce@parse@cc#1{%{<cc>}|...
  \bxce@parse@hex{#1}\bxce@parse@cc@a\bxce@parse@cc@b{#1}%
}
\def\bxce@parse@cc@a#1#2#3#4#5{%{<hex>}{<cc>}\CSok\CSrs\CSerr
  #3{#1}%
}
\def\bxce@parse@cc@b#1#2{%{<cc>}\CSok|\CSrs\CSerr
  \bxce@trim@colons{#1}\bxce@lookup@sname
}

%% \bxce@trim@colons{<word>}\CScont
\def\bxce@trim@colons#1{%{<word>}|\CScont
  \bxce@trim@colons@a#1@:@\bxce@mk
}
\def\bxce@trim@colons@a#1#2:@#3\bxce@mk{%
  \bxce@cond\if:#1\fi{%
    \bxce@trim@colons@b#2@\bxce@mk
  }{%else
    \bxce@trim@colons@b#1#2@\bxce@mk
  }%
}
\def\bxce@trim@colons@b#1@#2\bxce@mk#3{%
  #3{#1}%
}

%% \bxce@lookup@sname{<sname>}\CSok\CSerr
\def\bxce@lookup@sname#1{%{<sname>}|\CSok\CSerr
  \ifcsdef{bxce@nd/#1}{%
    \bxce@parse@sname@out{#1}%
  }{%else
    \bxce@load@sname@definition{#1}%
    \bxce@parse@sname{#1}%
  }%
}

%% \bxce@parse@sname{<sname>}\CSok\CSerr
\def\bxce@parse@sname#1{%{<sname>}|\CSok\CSerr
  \ifcsdef{bxce@nd/#1}{%
    \bxce@parse@sname@out{#1}%
  }{%else
    \@secondoftwo
  }%
}
\def\bxce@parse@sname@out#1{%{<sname>}|\CSok\CSerr
  \expandafter\expandafter\expandafter
      \bxce@parse@sname@out@a\csname bxce@nd/#1\endcsname\bxce@end
}
\def\bxce@parse@sname@out@a#1\bxce@end#2#3{%<res>\end\CSok\CSerr
  #2{#1}%
}

%--------------------------------------- image output

%% variables
\newbool{bxce@ctdir}
\newbool{bxce@var}% *-form is used?
\newdimen\bxce@cwd
\newdimen\bxce@disp@dim
\newskip\bxce@inter@skip
\let\bxce@image@name\relax
\let\bxce@image@argpath\relax

%% \bxce@image@path{<name>}
\def\bxce@image@path#1{%
  \bxce@prefix#1.\bxce@ext
}

%% \bxce@unit / \bxce@disp / \bxce@inter
\def\bxce@unit{em}
\def\bxce@disp{0.12}
\def\bxce@inter{0pt plus 0.1em}

%% \bxce@output
\def\bxce@output{%
  \ifmmode \nfss@text{\bxce@output@a}%
  \else \bxce@output@a
  \fi
}
\def\bxce@output@a{%
  \bxce@resolve@image@setup
  \bxce@check@image@setup
  \bxce@driver@hook
  \bxce@iftdir{\bxce@ctdirtrue}{\bxce@ctdirfalse}%
  \bxce@set@cwd
  \bxce@disp@dim=\bxce@disp\bxce@cwd\relax
  \bxce@inter@skip=\bxce@inter\relax
  \bxce@text
  \unskip
}

%% \bxce@driver@hook
\let\bxce@driver@hook\relax

%% \bxce@check@image@setup
\def\bxce@check@image@setup{%
  \unless\ifbxce@use@image
    \let\bxce@output@type\bxce@ot@@none
  \fi
  \ifnum\bxce@output@type=\bxce@ot@@twemojis
    \bxce@twm@check@image@setup
    \unless\ifbxce@ok
      \let\bxce@output@type\bxce@ot@@none
    \fi
  \fi
}

%% \bxce@set@cwd
\def\bxce@set@cwd{%
  \ifbxce@var \let\bxce@tmpa\bxce@size@var
  \else \let\bxce@tmpa\bxce@size
  \fi
  \ifx\bxce@tmpa\@empty
    \bxce@cwd=\bxce@scale\bxce@unit\relax
  \else
    \begingroup
      \let\em\bxce@set@cwd@em
      \let\Em\bxce@set@cwd@Em
      \setlength\bxce@cwd{\bxce@tmpa}%
      \xdef\bxce@g@tmpa{\the\bxce@cwd}%
    \endgroup
    \bxce@cwd=\bxce@g@tmpa\relax \bxce@cwd=\bxce@scale\bxce@cwd
  \fi
}
\def\bxce@set@cwd@em{\dimexpr1\bxce@unit\relax}
\def\bxce@set@cwd@Em{\dimexpr\f@size\p@\relax}

%% \bxce@wr{<char>}
\def\bxce@wr#1{%
  #1\hskip\bxce@inter@skip
}

%% \bxce@put{<code1>}
\def\bxce@put#1{%
  \bxce@if@image@exists{#1}{%
    \bxce@put@image{#1}%
  }{%else
    \bxce@char@token\bxce@arg{"#1}%
    \bxce@arg \hskip\bxce@inter@skip
  }%
}

%% \bxce@put@cseq{\bxce@c<cp>{<code>}...}
\def\bxce@c@hyph#1{-#1}
\def\bxce@c@first#1#2{#2}
\protected\def\bxce@put@cseq#1{%
  \let\bxce@c\bxce@c@hyph
  \edef\bxce@cseq{\bxce@c@first#1}%
\bxDebug{cseq:\bxce@cseq}%
  \bxce@if@image@exists{\bxce@cseq}{%
    \bxce@put@image{\bxce@cseq}%
  }{%else
    \let\bxce@c\bxce@put@cseq@a#1%
  }%
}
\def\bxce@@ZWJ@code{200D}
\def\bxce@@EVS@code{FE0F}
\def\bxce@put@cseq@a#1{%
  \def\bxce@tmpa{#1}\ifx\bxce@tmpa\bxce@@ZWJ@code
    \bxce@depict@fallback@ZWJ
  \else\unless\ifx\bxce@tmpa\bxce@@EVS@code
    \bxce@put{#1}%
  \fi\fi
}

%% \bxce@put@cseqtag{\bxce@c<cp>{<code>}...}
\protected\def\bxce@put@cseqtag#1{%
  \let\bxce@c\bxce@c@hyph
  \edef\bxce@cseq{\bxce@c@first#1}%
\bxDebug{cseqtag:\bxce@cseq}%
  \bxce@if@image@exists{\bxce@cseq}{%
    \bxce@put@image{\bxce@cseq}%
  }{%else
    \bxce@put@cseqtag@a#1\bxce@end
  }%
}
\def\bxce@put@cseqtag@a#1#2#3\bxce@end{%
  \bxce@put{#2}%
  \bxce@char@token\bxce@arg\bxce@repch
  \bxce@arg \hskip\bxce@inter@skip
}

%% \bxce@if@image@exists{<name>}
\def\bxce@if@image@exists#1{%
  \bxce@cond\ifnum\bxce@output@type=\bxce@ot@@none\fi{%
    \@secondoftwo % always false
  }{\bxce@cond\ifnum\bxce@output@type=\bxce@ot@@twemojis\fi{%
    \bxce@if@twm@image@exists{#1}%
  }{%else
    \IfFileExists{\bxce@image@path{#1}}%
  }}%
}

%% \bxce@put@image{<name>}
\def\bxce@put@image{%
  \bxce@cond\ifnum\bxce@output@type=\bxce@ot@@twemojis\fi{%
    \bxce@twm@put@image
  }{%else
    \bxce@put@image@a
  }%
}
\def\bxce@put@image@a#1{%
  \def\bxce@image@name{#1}%
  \ifcsdef{bxce@fabs/\bxce@family}{%
    \bxce@set@image@abs@argpath
  }{%else
    \edef\bxce@image@argpath{\bxce@image@path{\bxce@image@name}}%
  }%
  \ifdef\bxce@raw@put@image{%
    \bxce@raw@put@image
  }{%else
    \bxce@std@put@image
  }%
  \hskip\bxce@inter@skip
}

%% \bxce@std@put@image
\def\bxce@std@put@image{%
  \bxce@expd{%
    \lower\bxce@disp@dim\hbox{%
      \ifbxce@ctdir\noexpand\rotatebox[origin=c]{90}\fi{%
      \noexpand\includegraphics
      [width=\bxce@cwd
      \ifbxce@use@bb\unless\ifx\bxce@bb\relax ,bb=\bxce@bb \fi\fi]%
      {\bxce@image@argpath}}}}%
}

%--------------------------------------- driver hooks

%% \bxce@driver@hook@dvisvgm
\@onlypreamble\bxce@driver@hook@dvisvgm
\def\bxce@driver@hook@dvisvgm{%
  \let\Ginclude@bitmap\bxce@Ginclude@bitmap
}

%% \bxce@Ginclude@bitmap@dvisvgm
% An alternative Ginclude routine for bitmaps on dvisvgm.
% It will enable dvisvgm's '--embed-bitmaps' options to work.
% NB: It does not support the dvipdfmx options 'viewport'/'trim'.
\@onlypreamble\bxce@Ginclude@bitmap@dvisvgm
\def\bxce@Ginclude@bitmap@dvisvgm#1{%
  \bxce@set@image@abspath{#1}%
  \special{dvisvgm:img
      \the\Gin@req@width\GPT@space\the\Gin@req@height\GPT@space
      \bxce@image@abspath}%
}

%% \bxce@raw@put@image@hitex
\@onlypreamble\bxce@raw@put@image@hitex
\def\bxce@raw@put@image@hitex{%
  \lower\bxce@disp@dim\hbox{%
    \HINTimage \bxce@image@argpath
      \space width \bxce@cwd
      \space height \bxce@cwd}%
}

%--------------------------------------- image absolute path

% Some engines/drivers do not handle well relative paths based on
% kpsewhich search in their backend process. The package employs
% absolute paths to avoid this problem.

%% varaibles
\let\bxce@image@abspath\relax
%\[bxce@fabs/<prefix>]% absolute dir for family (setting)
%\[bxce@pabs/<prefix>]% absolute dir for prefix (cache)

%%<+> \coloremojiSetAbsolutePath{<family>}{<directory>}
% Sets the absolute directory for a family.
\newrobustcmd*\coloremojiSetAbsolutePath[2]{%
  \global\csdef{bxce@fabs/#1}{#2}%
}

%% \bxce@set@image@abs@argpath
% Returns to \bxce@image@argpath.
\def\bxce@set@image@abs@argpath{%
  \edef\bxce@image@argpath{%
    \csuse{bxce@fabs/\bxce@family}/\bxce@image@path{\bxce@image@name}}%
}

%% \bxce@set@image@abspath{<path>}
% Returns to \bxce@image@abspath.
\def\bxce@set@image@abspath#1{%
  \ifcsdef{bxce@fabs/\bxce@family}{%
    % argpath is already absolute
    \let\bxce@image@abspath\bxce@image@argpath
  }{%else
    \ifcsdef{bxce@pabs/\bxce@prefix}{}{%else
      % find absolute dir for prefix
      \bxce@kpsewhich{#1}%
      \ifx\bxce@image@abspath\relax
        \PackageWarning\bxce@pkgname
         {Cannot find absolute path for prefix\MessageBreak
          \@spaces'\bxce@prefix',\MessageBreak reported}%
        \global\cslet{bxce@pabs/\bxce@prefix}\@empty
      \else
        \bxDebug{abspath:\bxce@prefix->\bxce@image@abspath}%
        \global\cslet{bxce@pabs/\bxce@prefix}\bxce@image@abspath
      \fi
    }%
    \edef\bxce@image@abspath{%
      \csuse{bxce@pabs/\bxce@prefix}\bxce@image@name.\bxce@ext}%
  }%
}

%% \bxce@shell@avail
\chardef\bxce@shell@avail=%
    \ifdefined\pdfshellescape \pdfshellescape
    \else\ifdefined\shellescape \shellescape
    \else \z@ \fi\fi

%% \bxce@kpsewhich{<path>}
% Returns to \bxce@image@abspath.
\ifnum\bxce@shell@avail=\z@
\def\bxce@kpsewhich#1{%
  \let\bxce@image@abspath\relax
}
\else
\def\bxce@kpsewhich{%
  \edef\bxce@tmpa{\bxce@image@name.\bxce@ext}%
  \expandafter\bxce@kpsewhich@a\detokenize\expandafter{\bxce@tmpa}\bxce@mk
}
\def\bxce@kpsewhich@a#1\bxce@mk#2{%
  \let\bxce@image@abspath\relax
  \bxce@cnto\endlinechar \endlinechar\m@ne
  \openin\@inputcheck="|kpsewhich #2"\relax
  \unless\ifeof\@inputcheck
    \readline\@inputcheck to\bxce@tmpb
    \def\bxce@tmpa##1#1\bxce@mk##2\bxce@end{%
      \ifstrempty{##2}{}{\def\bxce@image@abspath{##1}}}%
    \expandafter\bxce@tmpa\bxce@tmpb\bxce@mk#1\bxce@mk\bxce@end
  \fi
  \closein\@inputcheck
  \endlinechar\bxce@cnto
}
\fi

%--------------------------------------- fallback ZWJ

%%<+> \coloremojiZWJSymbolColor
\newcommand\coloremojiZWJSymbolColor{green}

\def\bxce@depict@fallback@ZWJ{%
  \begingroup
    \bxce@set@ZWJ@color
    \bxce@ZWJ@sym
  \endgroup
}

%% \bxce@ZWJ@sym
\def\bxce@ZWJ@sym{%
  \lower\dimexpr\bxce@disp\bxce@unit+0.2\bxce@unit\hb@xt@\z@{%
    \kern-0.2\bxce@unit\relax
    \vrule\@width0.1\bxce@unit\@height0.2\bxce@unit\relax
    \vrule\@width0.2\bxce@unit\@height0.1\bxce@unit\relax
    \vrule\@width0.1\bxce@unit\@height0.2\bxce@unit\relax
    \hss}%
}

%% \bxce@set@ZWJ@color
\def\bxce@set@ZWJ@color{%
  \ifdefined\color
    \bxce@expd{\noexpand\color{\coloremojiZWJSymbolColor}}%
  \fi
}

%--------------------------------------- tate direction

%% constants
\chardef\bxce@luatexja@tate=3

%% \bxce@iftdir{<tate>}{<yoko>}
\let\bxce@iftdir\@secondoftwo % always yoko

%% \bxce@resolve@image@metric
% NB. This macro will be called more than once.
\@onlypreamble\bxce@resolve@image@metric
\def\bxce@resolve@image@metric{%
  % set 'bxce@luatexja'
  \if l\bxce@engine
    \@ifpackageloaded{luatexja}{%
      \global\bxce@luatexjatrue
    }{}%
  \fi
  % jatype settings
  \ifnum\bxce@jatype@opt=\bxce@abool@@false
    % skip jatype settings
  \else\ifbxce@luatexja
    \global\bxce@jaoktrue
    \global\chardef\bxce@zspc="3000
    \ifdefined\ltj@curtfnt
      \gdef\bxce@iftdir{\bxce@cond
        \ifnum\ltjgetparameter{direction}=\bxce@luatexja@tate\fi}%
    \fi
    \gdef\bxce@unit{\zw}%
    \gdef\bxce@disp{\bxce@iftdir{0.5}{0.12}}%
    \gdef\bxce@inter{%
      \expandafter\bxce@inter@a\number\ltjgetparameter{kanjiskip}\relax}%
    \gdef\bxce@inter@a##1\relax{%
      \ifdim\glueexpr##1=\maxdimen \z@skip \else ##1\fi}%
  \else\ifbxce@ptex
    \global\bxce@jaoktrue
    \global\chardef\bxce@zspc=\jis"2121\relax
    \gdef\bxce@iftdir{%
      \ifbool{tdir}{\notbool{mdir}}{\@secondoftwo}}%
    \gdef\bxce@unit{zw}%
    \gdef\bxce@disp{\bxce@iftdir{0.5}{0.12}}%
    \gdef\bxce@inter{\kanjiskip}%
  \else\ifnum\bxce@jatype@opt=\bxce@abool@@true
    \ifnum0\if x\bxce@engine1\fi\if l\bxce@engine1\fi >\z@
      \global\bxce@jaoktrue
      \global\chardef\bxce@zspc="3000
    \fi
  \fi\fi\fi\fi
  \if d\bxce@engine
    \@ifpackageloaded{CJK}{%
      \bxce@resolve@image@metric@CJK
    }{}%
  \fi
}
%% \bxce@resolve@image@metric@CJK
\@onlypreamble\bxce@resolve@image@metric@CJK
\def\bxce@resolve@image@metric@CJK{%
  \global\let\bxce@resolve@image@metric@CJK\relax
  \unless\ifdefined\CJKhook \let\CJKhook\@empty \fi
  \gappto\CJKhook{\bxce@CJKtrue}%
}

%% try once now
\AtEndOfPackage{%
  \bxce@resolve@image@metric
}

%--------------------------------------- character token

%% \bxce@max@ascii
\chardef\bxce@max@ascii="7F
%% \bxce@max@unicode
\protected\def\bxce@max@unicode{"10FFFF }

%% \bxce@geta : geta mark
%% \bxce@ageta : 'ASCII' geta mark
%% \bxce@maxcc : max 'valid' codevalue
%% \bxce@repch : replacement char
\chardef\bxce@ageta=`\=\relax
\ifx d\bxce@engine
  \chardef\bxce@geta=\bxce@ageta
  \chardef\bxce@maxcc=\bxce@max@ascii
  \chardef\bxce@repch=\bxce@geta
\else\ifx p\bxce@engine
  \chardef\bxce@geta=\jis"222E\relax
  \chardef\bxce@maxcc=\bxce@max@ascii
  \ifbxce@ucs@avail \let\bxce@maxcc\bxce@max@unicode \fi
  \chardef\bxce@repch=\bxce@geta
\else
  \chardef\bxce@geta="3013
  \chardef\bxce@maxcc=\bxce@max@unicode
  \chardef\bxce@repch="FFFD
\fi\fi

%% \bxce@forcecjktoken
% Does '\forcecjktoken' if available.
\let\bxce@forcecjktoken\relax
\bxce@if@primitive{\forcecjktoken}{\let\bxce@forcecjktoken\forcecjktoken}

%% \bxce@char@token\CS{<codvalue>}
% Lets \CS be a macro that expands to a character token of the given
% Unicode value. If the value is invalid, \bxce@geta is used.
% NB. On pTeX without \ucs, only ASCII is regarded as valid.
\def\bxce@char@token#1#2{%
  \begingroup
    \bxce@cnta=#2\relax
    \ifnum\bxce@cnta<\z@ \bxce@cnta=\bxce@geta \fi
    \ifnum\bxce@cnta>\bxce@maxcc \bxce@cnta=\bxce@geta \fi
    \bxce@char@token@a
  \endgroup
  \let#1=\@gtempa
}
\def\bxce@char@token@al{%
  \lccode`\*=\bxce@cnta
  \lowercase{\xdef\@gtempa{*}}%
}
\let\bxce@char@token@a\bxce@char@token@al
\ifnum0\ifx p\bxce@engine \ifbxce@ucs@avail 1\fi\fi>\z@
  % pTeX with '\ucs'
  \def\bxce@char@token@a{%
    \ifnum\bxce@cnta>\bxce@max@ascii
      \bxce@forcecjktoken
      \bxce@cnta=\ucs\bxce@cnta\relax % -1 for non-JIS char
      \kansujichar\@ne=\ifnum\bxce@cnta<\z@ \bxce@geta \else \bxce@cnta \fi
      \xdef\@gtempa{\kansuji\@ne}% \kansuji trick
    \else \bxce@char@token@al
    \fi
  }
\else\ifbxce@ptex
  % pTeX without '\ucs', or upTeX
  \def\bxce@char@token@a{%
    \ifnum\bxce@cnta>\bxce@max@ascii
      \bxce@forcecjktoken
      \kansujichar\@ne=\bxce@cnta
      \xdef\@gtempa{\kansuji\@ne}% \kansuji trick
    \else \bxce@char@token@al
    \fi
  }
\fi\fi

%% \bxce@geta@char
%% \bxce@ageta@char
\bxce@char@token\bxce@geta@char\bxce@geta
\bxce@char@token\bxce@ageta@char\bxce@ageta

%% \bxce@put@geta
% Puts \bxce@geta if bxce@jaok, otherwise puts \bxce@ageta.
\def\bxce@put@geta{%
  \ifbxce@jaok \bxce@put@geta@do
  \else \bxce@put@ageta
  \fi
}
\protected\def\bxce@put@geta@do{%
  \bxce@geta@char
}

%% \bxce@put@ageta
\protected\def\bxce@put@ageta{%
  \bxce@ageta@char
}

%% \bxce@put@geta@for{<options>}
% The suitable geta char for given options. (fully-expandable)
\def\bxce@put@geta@for#1{%
  \bxce@with@star{#1}\bxce@put@ageta\bxce@put@geta
}

%--------------------------------------- ghost something

%% \bxce@zspc : zenkaku space
\let\bxce@zspc\@undefined

%% \bxce@ghost
\let\bxce@ghost\relax
%% \bxce@postghost
\let\bxce@postghost\relax

%% \bxce@enghost\CScont*...
% Invokes \CScont..., after resolving the star and building a ghost
% enclosure.
% NB. The process starting with \CScont must end with an invocation
% of \bxce@ghost@guarded.
\def\bxce@enghost#1{%
  \@ifstar{%
    \bxce@vartrue
    \bxce@enghost@a{#1}%
  }{%
    \bxce@varfalse
    \bxce@enghost@a{#1}%
  }%
}
\def\bxce@enghost@a#1{%
  \bxce@build@ghost
  \begingroup
    #1%
}

%% \bxce@ghost@guarded{<text>}
\def\bxce@ghost@guarded#1{%
    \bxce@ghost
    #1%
    \bxce@postghost
  \endgroup
}

%% \bxce@build@ghost
\def\bxce@build@ghost{%
% NB. It could be called before \bxce@resolve@image@metric.
% Then ghost setting could be inappropriate.
  \ifbxce@jaok
    \ifmmode
      \let\bxce@ghost\relax
      \let\bxce@postghost\relax
    \else\ifbxce@var
      \let\bxce@ghost\bxce@nihil
      \let\bxce@postghost\bxce@nihil
    \else
      \let\bxce@ghost\bxce@ghost@jachar
      \let\bxce@postghost\bxce@postghost@jachar
    \fi\fi
  \else
    \let\bxce@ghost\leavevmode
    \let\bxce@postghost\relax
  \fi
}

%% \bxce@ghost@jachar
%% \bxce@postghost@jachar
\ifbxce@bxghost
  \def\bxce@ghost@jachar#1\bxce@postghost{%
    \leavevmode\jghostguarded{#1}%
  }
  \let\bxce@postghost@jachar\relax
\else
  \def\bxce@ghost@jachar{%
    \bxce@zspc \kern-1\bxce@unit\relax
  }
  \def\bxce@postghost@jachar{%
    \kern-1\bxce@unit\relax \bxce@zspc
  }
\fi

%% \bxce@enghost@with@opt\CScont*[<option>,...]...
% Invokes \CScont..., after resolving the star and the options
% and preparing the ghost enclosure.
\def\bxce@enghost@with@opt#1{%
  \bxce@enghost{\bxce@enghost@with@opt@a{#1}}%
}
\def\bxce@enghost@with@opt@a#1{%
  \@ifnextchar[%]
      {\bxce@enghost@with@opt@b{#1}}%
      {#1}%
}
\def\bxce@enghost@with@opt@b#1[#2]{%
  \bxce@in@commandtrue
  \setkeys{bxce}{#2}%
  #1%
}

%--------------------------------------- preprocess for expansion

%% variables
%[bxce@n(?)] : de-protected definition of active-byte '?'
%[bxce@n<?>] : (CJK package something)
%[bxce@o<?>] : (CJK package something)

%% \bxce@std@preproc
\let\bxce@std@preproc\@empty
\ifnum0\ifbxce@ptex1\fi\ifx d\bxce@engine1\fi >0
\begingroup
  \edef\bxce@tmp@good@prefix{\detokenize{\protected macro}}
  \def\bxce@tmpa#1#2#3{% \[bxce@n(?)] ?13 ?12
    \expandafter\bxce@do\meaning#2:\relax#1#2%
  }
  \def\bxce@do#1:#2\relax#3#4{%
    \def\bxce@tmpb{#1}\ifx\bxce@tmpb\bxce@tmp@good@prefix
      \expandafter\gdef\expandafter#3\expandafter{#4}%
      \gappto\bxce@std@preproc{\let#4#3}%
    \fi
  }
  \@tempcnta=194
  \loop\ifnum\@tempcnta<245
    \lccode`\+=\@tempcnta \lccode`\~=\@tempcnta
    \lowercase{\expandafter\bxce@tmpa\csname bxce@n(+)\endcsname~+}%
    \advance\@tempcnta\@ne
  \repeat
\endgroup
\fi

%% \bxce@CJK@preproc
\let\bxce@CJK@preproc\@empty
\if d\bxce@engine
\begingroup
  \def\bxce@tmpa#1#2#3#4{% \[bxce@n<?>]\[bxce@o<?>] ?13 ?12
    \gappto\bxce@CJK@preproc{\let#2#3\let#3#1}%
    \ifnum\@tempcnta<224 %2-byte
      \gdef#1##1##2##3{\expandafter
        \ifx\csname u8:#4\string##1\endcsname\relax
        #2##1\else\csname u8:#4\string##1\endcsname\fi}%
    \else\ifnum\@tempcnta<240 %3-byte
      \gdef#1##1##2{\expandafter
        \ifx\csname u8:#4\string##1\string##2\endcsname\relax
        #2##1##2\else\csname u8:#4\string##1\string##2\endcsname\fi}%
    \else %4-byte
      \gdef#1##1##2##3{\expandafter
        \ifx\csname u8:#4\string##1\string##2\string##3\endcsname\relax
        #2##1##2##3\else
        \csname u8:#4\string##1\string##2\string##3\endcsname\fi}%
    \fi\fi
  }
  \@tempcnta=194
  \loop\ifnum\@tempcnta<245
    \lccode`\+=\@tempcnta \lccode`\~=\@tempcnta
    \lowercase{\expandafter\bxce@tmpa\csname bxce@n<+>\expandafter
        \endcsname\csname bxce@o<+>\endcsname~+}%
    \advance\@tempcnta\@ne
  \repeat
\endgroup
\fi

%--------------------------------------- hyperref something

%% add to hook
\appto\pdfstringdefPreHook{%
  \coloremojiLoadAllNames
  \let\coloremoji\bxce@hy@coloremoji
  \let\coloremojiucs\bxce@hy@coloremojicode
  \def\bxce@@#1;{\bxce@hy@ucs{#1}}%
  \let\bxce@do\bxce@hy@ucs
  \def\bxce@bad#1{\bxce@hy@geta}%
  \let\bxce@put@geta@do\bxce@geta@char
  \let\bxce@put@ageta\bxce@ageta@char
  \let\bxce@keycap@of@good\bxce@hy@keycap@of@good
  \let\bxce@keycap@of@bad\bxce@hy@keycap@of@bad
}

%% \bxce@hy@coloremoji
% \coloremoji in PDF strings. (fully-expandable)
\def\bxce@hy@coloremoji#1#{% brace delimit
  \@firstofone  % just put the characters
}

%% \bxce@hy@ucs{<codevalue-hex>}
% Puts the character with the given code value. (fully-expandable)
\def\bxce@hy@ucs#1{%
  % If 'unicode' is on, then \unichar (provided by hyperref)
  % is availble.
  \ifdefined\ifpdfstringunicode \expandafter\ifpdfstringunicode
  \else \expandafter\@secondoftwo
  \fi {\unichar{"#1}}{\bxce@hy@ucs@a{#1}}%
}
\def\bxce@hy@ucs@a#1{%
  % If pxjahyper is loaded, then \Ux can be used.
  \ifdefined\pxDeclarePdfTextCommand
    \ifdefined\Ux \Ux{#1}%
    \else \bxce@hy@geta
    \fi
  \else \bxce@put@ageta
  \fi
}

%% \bxce@hy@geta
\def\bxce@hy@geta{%
  \ifbxce@jaok
    \bxce@if@flag@raised{jg}{\bxce@geta@char}{\bxce@ageta@char}%
  \else \bxce@ageta@char
  \fi
}

%% \bxce@hy@coloremojicode
% \coloremojicode in PDF strings. (fully-expandable)
\def\bxce@hy@coloremojicode{%
  \bxce@hedge@options@with\bxce@hy@coloremojicode@a
}
\def\bxce@hy@coloremojicode@a#1#2{%
  \bxce@with@star{#1}{}{\bxce@raise@flag{jg}}%
  \expandafter\bxce@parse@ccseq\expandafter{\detokenize{#2}}\@firstofone
}

%--------------------------------------- hex strings

%% \bxce@parse@hex{<word>}\CSok\CSerr
% Expands to \CSok{<res>} or \CSerr.
\def\bxce@parse@hex#1{%
  \bxce@parse@hex@a#1@@%
}
\def\bxce@parse@hex@a#1{%<ic>|...
  \bxce@cond\ifx @#1\fi{%
    \bxce@parse@hex@c
  }{%else
    \expandafter\expandafter\expandafter
        \bxce@parse@hex@b\csname bxce@H/#1\endcsname
  }%
}
\def\bxce@parse@hex@b#1#2@#3@{%<ic><iw>@<ow>@|\CSok\CSerr
  \bxce@cond\ifx#1\relax\fi{% unknown char
    \@secondoftwo
  }{%else
    \bxce@parse@hex@a#2@#3#1@%
  }%
}
\def\bxce@parse@hex@c#1{%
  \bxce@cond\if @#1\fi{%
    \bxce@parse@hex@d0@%
  }{\bxce@cond\if0#1\fi{%
    \bxce@parse@hex@c
  }{%else
    \bxce@parse@hex@d#1%
  }}%
}
\def\bxce@parse@hex@d#1@#2#3{%<ow>@\CSok\CSerr
  #2{#1}%
}

%% \bxce@H/*
\begingroup
  \lccode`H=`H
  \def\bxce@tmpa#1\bxce@end{%
    \lowercase{\csgdef{bxce@H/#1}}{#1}%
    \csgdef{bxce@H/#1}{#1}%
  }
  \@tfor\x:=0123456789ABCDEF\do{%
    \expandafter\bxce@tmpa\x\bxce@end
  }
\endgroup

%--------------------------------------- unparse

%% \bxce@unparse@first{<first>}
% The inverse of \bxce@parse@first@ccseq.
% But here \bxce@O and \bxce@S are illegal.
\def\bxce@unparse@first{%
  \let\bxce@text\@empty
  \let\bxce@T\bxce@unparse@first@T
  \let\bxce@O\bxce@unparse@first@O
  \let\bxce@S\bxce@unparse@first@S
  \let\bxce@E\bxce@unparse@first@E
}
\def\bxce@unparse@first@a#1{%
  \bxce@unparse@first@b#1%
}
\def\bxce@unparse@first@b#1.\bxce@end{%
  \def\bxce@text{#1}%
}
\protected\def\bxce@unparse@first@T.\bxce@end{%
  \expandafter\bxce@unparse@first@a\bxce@text.\bxce@end
}
\protected\def\bxce@unparse@first@O#1{%
  \PackageError\bxce@pkgname
   {Illegal character [\bxce@hex{`#1}]}{\@ehc}%
}
\protected\def\bxce@unparse@first@S#1{%
  \bxce@unparse@first@O{\ }%
}
\protected\def\bxce@unparse@first@E#1#2{%
  \unless\ifnum#1=\bxce@cp@evs
    \edef\bxce@text{\bxce@text\space#2}%
  \fi
}

%% \bxce@normalize@text{<text>}
\def\bxce@normalize@text#1{%
  \bxce@expand@text{#1}%
  \edef\bxce@text{\detokenize\expandafter{\bxce@text}}%
  \expandafter\bxce@parse@first\bxce@text\bxce@end
  \expandafter\bxce@unparse@first\bxce@text\bxce@end
}

%% \bxce@normalize@ccseq{<ccseq>}
\def\bxce@normalize@ccseq#1{%
  \bxce@parse@first@ccseq{#1}%
  \expandafter\bxce@unparse@first\bxce@text\bxce@end
}

%--------------------------------------- family config file

%% variables
\let\bxce@cfg@file\relax
\let\bxce@config\relax

%% errors
\def\bxce@err@secfg#1{%
  \PackageError\bxce@pkgname
   {Problem in '\bxce@cfg@file':\MessageBreak
    #1}%
   {The custom family is ignored.\MessageBreak
    \@ehc}%
}

%% \bxce@use@custom@family{<name>}
\def\bxce@use@custom@family#1{%
  % start from invalidated state
  \bxce@initialize@setup
  % load configuration file
  \ifcsdef{bxce@config/#1}{%
    \bxce@oktrue
  }{%else
    \edef\bxce@cfg@file{\bxce@pkgname-#1.cfg}%
    \IfFileExists{\bxce@cfg@file}{%
      \edef\bxce@family{#1}%
      \bxce@read@cfg@file
    }{%else
      \ifcsdef{bxce@fbconfig/#1}{%
        \bxce@oktrue
        \letcs\bxce@config{bxce@fbconfig/#1}%
        \PackageInfo\bxce@pkgname
         {Using preset config for '#1'\@gobble}%
      }{%
      \bxce@okfalse
      \PackageError\bxce@pkgname
       {The custom family '#1' is unavaiable\MessageBreak
        since file '\bxce@cfg@file' is not found}%
       {\@ehc}%
      }%
    }%
    \ifbxce@ok
      \bxce@check@cfg@values
    \fi
    \ifbxce@ok
      \global\cslet{bxce@config/#1}\bxce@config
    \fi
  }%
  % apply configuration
  \ifbxce@ok
    \let\bxce@output@type\bxce@ot@@custom
    \edef\bxce@family{#1}%
    \csuse{bxce@config/#1}%
  \fi
}

%% \bxce@read@cfg@file
% Reads the file \bxce@cfg@file and stores the result to \bxce@config.
% It sets to bxce@ok whether the reading succeeded.
\def\bxce@read@cfg@file{%
  \PackageInfo\bxce@pkgname
   {Loading custom family config file\MessageBreak
    '\bxce@cfg@file'}%
  \bxce@okfalse
  \let\bxce@config\relax
  \openin\@inputcheck=\bxce@cfg@file\relax
  \global\let\bxce@g@tmpa\@empty
  \begingroup
    \endlinechar\m@ne
    \bxce@oktrue
    \@whilesw\ifbxce@ok\fi{%
      \ifeof\@inputcheck
        \bxce@okfalse
        \aftergroup\bxce@read@cfg@file@eof
      \else
        \readline\@inputcheck to\bxce@tmpa
        \bxce@read@cfg@file@cc
        \unless\ifx\bxce@tmpa\@empty
          \expandafter\bxce@read@cfg@file@a\bxce@tmpa\bxce@mk=\bxce@end
        \fi
      \fi
    }%
  \endgroup
  % here 'bxce@ok' means whether loading succeeded
  \closein\@inputcheck
}
\def\bxce@read@cfg@file@eof{%
  \bxce@oktrue
  \let\bxce@config\bxce@g@tmpa
}
\def\bxce@read@cfg@file@a#1=#2\bxce@end{%
  \ifx\bxce@mt#2\bxce@mt
    \bxce@err@secfg{missing '='}\bxce@okfalse
  \else
    \edef\bxce@tmpa{\zap@space#1 \@empty}%
    \bxce@read@cfg@file@b#2\bxce@end
  \fi
}
\def\bxce@read@cfg@file@b#1\bxce@mk#2\bxce@end{%
  \edef\bxce@tmpb{\@firstofone#1\@empty}%
  \ifcsdef{bxce@read@cfg@file@@\bxce@tmpa}{%
    \csuse{bxce@read@cfg@file@@\bxce@tmpa}%
  }{%else
    \bxce@err@secfg{unknown key '\bxce@tmpa'}\bxce@okfalse
  }%
}
\def\bxce@tmpa#1{%
  \def\bxce@read@cfg@file@cc{%
    \expandafter\bxce@read@cfg@file@cc@a\bxce@tmpa#1\bxce@end}%
  \def\bxce@read@cfg@file@cc@a##1#1##2\bxce@end{%
    \ifblank{##1}{\let\bxce@tmpa\@empty}{%else
      \def\bxce@tmpa{##1}}}%
}\expandafter\bxce@tmpa\@percentchar
% key handlers
\def\bxce@read@cfg@file@@bbox{%
  \xappto\bxce@g@tmpa{\def\bxce@bb{\bxce@tmpb}}%
}
\def\bxce@read@cfg@file@@extension{%
  \xappto\bxce@g@tmpa{\def\bxce@ext{\bxce@tmpb}}%
}
\def\bxce@read@cfg@file@@prefix{%
  \xappto\bxce@g@tmpa{\def\bxce@prefix{\bxce@tmpb}}%
}

%% \bxce@check@cfg@values
% Checks if \bxce@config is valid and sets the result to bxce@ok.
\def\bxce@check@cfg@values{%
  \bxce@oktrue
  \begingroup
    \bxce@config
    % NB: 'bbox' is optional.
    \ifx\bxce@ext\relax
      \bxce@err@secfg{'extension' is not given}%
      \aftergroup\bxce@okfalse
    \fi
    \ifx\bxce@prefix\relax
      \bxce@err@secfg{'prefix' is not given}%
      \aftergroup\bxce@okfalse
    \fi
  \endgroup
}

\csdef{bxce@fbconfig/twemoji-pdf}{%
  \def\bxce@bb{0 0 27 27}%
  \def\bxce@ext{pdf}%
  \def\bxce@prefix{\coloremojidir twemoji-pdf/twemoji-}%
}
\csdef{bxce@fbconfig/twemoji-png}{%
  \def\bxce@bb{0 0 72 72}%
  \def\bxce@ext{png}%
  \def\bxce@prefix{\coloremojidir twemoji-png/twemoji-}%
}

%% invoke the custom family set by a package option
\ifnum\bxce@output@type=\bxce@ot@@custom
  \bxce@expd{\noexpand\bxce@use@custom@family{\bxce@family}}%
\fi

%--------------------------------------- emoji order list

%% variables
%[bxce@oen/<ccseq>]
\let\bxce@oehead\relax
\let\bxce@oeprev\relax
\let\bxce@oecur\relax

\AtBeginDocument{% empty should stay invalid
  \csundef{bxce@oen/}%
}

%%<+> \bxcoloremojiDeclareOrder{<ccseq>,...}
\@onlypreamble\bxcoloremojiDeclareOrder
\newrobustcmd*\bxcoloremojiDeclareOrder[1]{%
  \begingroup
    \@for\bxce@oecur:=#1\do{%
      \bxce@normalize@ccseq\bxce@oecur
      \let\bxce@oecur\bxce@text
      \ifx\bxce@oecur\@empty
      \else\ifcsname bxce@oen/\bxce@oecur\endcsname
        \PackageError\bxce@pkgname
         {Already registered in some emoji order list:\MessageBreak
          \space\space[\bxce@oecur]}%
         {\@eha}%
      \else
        \ifx\bxce@oehead\relax
          \let\bxce@oehead\bxce@oecur
        \else
          \global\cslet{bxce@oen/\bxce@oeprev}\bxce@oecur
        \fi
        \let\bxce@oeprev\bxce@oecur
      \fi\fi}%
    \unless\ifx\bxce@prev\relax
      \global\cslet{bxce@oen/\bxce@oeprev}\bxce@oehead
    \fi
  \endgroup
}

%%<+> \bxcoloremojiUndeclareOrder{<ccseq>,...}
\@onlypreamble\bxcoloremojiUndeclareOrder
\newrobustcmd*\bxcoloremojiUndeclareOrder[1]{%
  \begingroup
    \@for\bxce@oecur:=#1\do{%
      \bxce@normalize@ccseq\bxce@oecur
      \let\bxce@oecur\bxce@text
      \ifx\bxce@oecur\@empty
      \else\ifcsname bxce@oen/\bxce@oecur\endcsname
        \global\csundef{bxce@oen/\bxce@oecur}%
      \fi\fi
    }%
  \endgroup
}

%%<+> \bxcoloremojiTestOrder{<count>}{<ccseq_0>}
\newrobustcmd*\bxcoloremojiTestOrder[2]{%
  \begingroup
    \bxce@normalize@ccseq{#2}%
    \typeout{Order for <\bxce@text>:}%
    \ifcsname bxce@oen/\bxce@text\endcsname
      \let\bxce@oecur\bxce@text
      \bxce@cnto=#1\relax
      \@whilenum{\bxce@cnto>\z@}\do{%
        \message{<\bxce@oecur>}%
        \coloremojicode{\bxce@oecur}\space
        \letcs\bxce@oecur{bxce@oen/\bxce@oecur}%
        \ifdefined\bxce@oecur \advance\bxce@cnto\m@ne
        \else \bxce@cnto\z@
        \fi
      }%
      \unskip\typeout{done}%
    \else \typeout{(not declared)}%
    \fi
  \endgroup
}

%--------------------------------------- pifont-like functions

%%<*> \coloremojifill{<text>}
\newrobustcmd*{\coloremojifill}{%
  \bxce@coloremojifill{\coloremoji*}%
}
%%<*> \coloremojicodefill{<ccseq>}
\newrobustcmd*{\coloremojicodefill}{%
  \bxce@coloremojifill{\coloremojicode*}%
}
\def\bxce@coloremojifill#1#2{%
  \leavevmode
  \leaders\hbox{\kern.375\bxce@unit{#1{#2}}\kern.375\bxce@unit}\hfill
  \kern\z@
}

%%<*> \coloremojiline{<text>}
\newrobustcmd*{\coloremojiline}{%
  \bxce@coloremojiline{\coloremoji*}%
}
%%<*> \coloremojicodeline{<ccseq>}
\newrobustcmd*{\coloremojicodeline}{%
  \bxce@coloremojiline{\coloremojicode*}%
}
\def\bxce@coloremojiline#1#2{%
  \par\noindent\hspace{0.5in}%
  \bxce@coloremojifill{#1}{#2}%
  \hspace{0.5in}\kern\z@
  \par
}

%%<*> \begin{coloremojilist}{<text>}
\newenvironment*{coloremojilist}[1]{%
  \begin{list}{\coloremoji*{#1}}{}%
}{%
  \end{list}%
}
%%<*> \begin{coloremojicodelist}{<ccseq>}
\newenvironment*{coloremojicodelist}[1]{%
  \begin{list}{\coloremojicode*{#1}}{}%
}{%
  \end{list}%
}

%% \bxce@ctrformat
\def\bxce@ctrformat#1#2{%
  \protect\bxce@ctrformat@{#1}{\arabic{#2}}%
}
\def\bxce@ctrformat@#1#2{%
  \begingroup
    \bxce@cnto=#2\relax
    \edef\bxce@text{#1}%
    \bxce@get@successor
    \ifx\bxce@text\relax
      \bxce@put@ageta
    \else
      \coloremojicode*{\bxce@text}%
    \fi
  \endgroup
}

%%<*> \begin{coloremojiautolist}{<text_0>}
\newenvironment*{coloremojiautolist}[1]{%
  \bxce@normalize@text{#1}%
  \bxce@coloremojiautolist
}{%
  \endlist
}
%%<*> \begin{coloremojicodeautolist}{<ccseq>}
\newenvironment*{coloremojicodeautolist}[1]{%
  \bxce@normalize@ccseq{#1}%
  \bxce@coloremojiautolist
}{%
  \endlist
}
\def\bxce@coloremojiautolist{%
  \unless\ifcsname bxce@oen/\bxce@text\endcsname
    \PackageError\bxce@pkgname
     {Not registered in any emoji order list:\MessageBreak
      \space\space[\bxce@text]}%
     {\@ehc}%
    \let\bxce@text\@empty
  \fi
  \ifnum\@enumdepth>\thr@@
    \@toodeep
  \else
    \advance\@enumdepth\@ne
    \edef\@enumctr{enum\romannumeral\@enumdepth}%
    \cslet{p@\@enumctr}\@empty
    \csedef{label\@enumctr}{\noexpand\csuse{the\@enumctr}}%
    \csedef{the\@enumctr}{%
      \noexpand\bxce@ctrformat{\bxce@text}{\@enumctr}}%
    \list{\csuse{label\@enumctr}}{%
      \@nmbrlisttrue
      \edef\@listctr{\@enumctr}%
      \setcounter{\@enumctr}{\m@ne}%
      \def\makelabel##1{\hss\llap{##1}}}%
  \fi
}

%% 'coloremojiucs' aliases
\newcommand*{\coloremojiucsfill}{\coloremojicodefill}
\newcommand*{\coloremojiucsline}{\coloremojicodeline}
\@ifdefinable{\coloremojiucslist}{%
  \let\coloremojiucslist\coloremojicodelist
  \let\endcoloremojiucslist\endcoloremojicodelist
}
\@ifdefinable{\coloremojiucsautolist}{%
  \let\coloremojiucsautolist\coloremojicodeautolist
  \let\endcoloremojiucsautolist\endcoloremojicodeautolist
}

%--------------------------------------- keycap numbering

%% constants
%[bxce@kcn/<n>] : ccseq of keycap emoji for number <n>

%% make table
\bxce@cnta\z@
\@for\bxce@tmpa:={%
  0030 20E3,0031 20E3,0032 20E3,0033 20E3,0034 20E3,%
  0035 20E3,0036 20E3,0037 20E3,0038 20E3,0039 20E3,1F51F%
}\do{%
  \csedef{bxce@kcn/\the\bxce@cnta}{\bxce@tmpa}%
  \advance\bxce@cnta\@ne
}

%%<*> \coloremojikeycapof*[<option>,...]{<number>}
% Puts the keycap emoji for the number.
% (It expands to an invocation of \coloremojicode.)
\newcommand*\coloremojikeycapof{%
  \bxce@hedge@options@with\bxce@keycap@of
}
\def\bxce@keycap@of#1#2{%
  \expandafter\bxce@keycap@of@a\number#2\bxce@mk{#1}%
}
\def\bxce@keycap@of@a#1\bxce@mk#2{%
  \ifnum#1<\z@
    \bxce@put@geta@for{#2}%
  \else\ifcsname bxce@kcn/#1\endcsname
    \expandafter\expandafter\expandafter\bxce@keycap@of@b\csname
        bxce@kcn/#1\endcsname\bxce@end{#1}{#2}%
  \else
    \bxce@keycap@of@bad{#1}%
  \fi\fi
}
\def\bxce@keycap@of@b#1\bxce@end#2#3{%
  \bxce@keycap@of@good{#3}{#1}{#2}%
}

%% \bxce@keycap@of@bad{<number>}
\def\bxce@keycap@of@bad#1{%
  \begingroup \fboxsep=\z@ \fboxrule=.6\p@
    \fbox{\rule[-.1em]{0pt}{.85em}#1}% fallback
  \endgroup
}
\def\bxce@hy@keycap@of@bad#1{[#1]}
%% \bxce@keycap@of@good{...}{<codevalue>}{<number>}
\def\bxce@keycap@of@good#1#2#3{%
  \coloremojicode#1{#2}%
}
\def\bxce@hy@keycap@of@good#1#2#3{%
  \ifdefined\ifpdfstringunicode \expandafter\ifpdfstringunicode
  \else \expandafter\@secondoftwo
  \fi {\coloremojicode#1{#2}}{\bxce@keycap@of@bad{#3}}%
}

%%<*> \coloremojikeycap*[<option>,...]{<counter>}
% Puts the keycap emoji for the current counter value.
% (It expands to an invocation of \coloremojicode.)
\newcommand*\coloremojikeycap{%
  \bxce@hedge@options@with\bxce@keycap
}
\def\bxce@keycap#1#2{%
  \bxce@keycap@of{#1}{\value{#2}}%
}

%% \@coloremojikeycap{<number>}
% This macro is needed for \pagenumbering.
\def\@coloremojikeycap#1{%
  \bxce@keycap@of{}{#1}%
}

%--------------------------------------- successor something

%% \bxce@get@successor
% Find the \bxce@cnto-th successor of ccseq \bxce@text and
% set the result to \bxce@text.
\def\bxce@get@successor{%
  \ifnum\bxce@cnto<\z@ \bxce@cnto\z@ \fi
  \@tempcnta\z@
  \let\bxce@tmpb\bxce@text
  \@whilenum{\bxce@cnto>\z@}\do{%
    \letcs\bxce@tmpb{bxce@oen/\bxce@tmpb}%
    \advance\bxce@cnto\m@ne
    \advance\@tempcnta\@ne
    \unless\ifdefined\bxce@tmpb
      \bxce@cnto\z@
    \else\ifx\bxce@text\bxce@tmpb % loop detected
      % shortcut
      \@tempcntb\bxce@cnto
      \divide\@tempcntb\@tempcnta
      \advance\bxce@cnto-\numexpr\@tempcntb*\@tempcnta\relax
    \fi\fi
  }%
  \ifdefined\bxce@tmpb
    \let\bxce@text\bxce@tmpb
  \else
    \let\bxce@text\relax
  \fi
}

%--------------------------------------- emoji order database

%\bxcoloremojiDeclareOrder{% snowman (for test)
%  2603, 26C4}
\bxcoloremojiDeclareOrder{% zodiac symbol
  2648, 2649, 264A, 264B, 264C, 264D, 264E, 264F, 2650, 2651,
  2652, 2653}
\bxcoloremojiDeclareOrder{% playing card suit
  2660, 2665, 2666, 2663}
%\bxcoloremojiDeclareOrder{% color heart (provisional)
%  2764, 1F49B, 1F49A, 1F499, 1F49C}% cf. 1F9E1
%\bxcoloremojiDeclareOrder{% color circle (provisional)
%  1F534, 1F535}
\bxcoloremojiDeclareOrder{% clock face
  1F550, 1F551, 1F552, 1F553, 1F554, 1F555, 1F556, 1F557, 1F558, 1F559,
  1F55A, 1F55B}
\bxcoloremojiDeclareOrder{% keycap number
  0030 20E3, 0031 20E3, 0032 20E3, 0033 20E3, 0034 20E3,
  0035 20E3, 0036 20E3, 0037 20E3, 0038 20E3, 0039 20E3, 1F51F}

%--------------------------------------- done
\endinput
%% EOF
