From 6caf348b43edcfc1dce127bf0895a5fb9bd77f2d Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 15 Jul 2014 22:56:45 +0000 Subject: luaotfload (15jul14) git-svn-id: svn://tug.org/texlive/trunk@34622 c570f23f-e606-0410-a88d-b1316a301751 --- .../linked_scripts/luaotfload/luaotfload-tool.lua | 702 +- Master/texmf-dist/doc/luatex/luaotfload/COPYING | 350 + Master/texmf-dist/doc/luatex/luaotfload/NEWS | 29 +- Master/texmf-dist/doc/luatex/luaotfload/README | 1 + .../texmf-dist/doc/luatex/luaotfload/filegraph.pdf | Bin 45545 -> 45642 bytes .../doc/luatex/luaotfload/luaotfload.conf.example | 30 + .../doc/luatex/luaotfload/luaotfload.pdf | Bin 222144 -> 170441 bytes .../luaotfload/valgrind-kpse-suppression.sup | 140 + Master/texmf-dist/doc/man/man1/luaotfload-tool.1 | 122 +- .../doc/man/man1/luaotfload-tool.man1.pdf | Bin 15440 -> 18400 bytes Master/texmf-dist/doc/man/man5/luaotfload.conf.5 | 545 + .../scripts/luaotfload/luaotfload-legacy-tool.lua | 105 - .../scripts/luaotfload/luaotfload-tool.lua | 702 +- Master/texmf-dist/scripts/luaotfload/mkcharacters | 6 +- Master/texmf-dist/scripts/luaotfload/mkglyphlist | 13 +- Master/texmf-dist/scripts/luaotfload/mkstatus | 84 +- .../texmf-dist/source/luatex/luaotfload/Makefile | 254 +- .../source/luatex/luaotfload/filegraph.dot | 287 + .../source/luatex/luaotfload/luaotfload-latex.tex | 448 + .../source/luatex/luaotfload/luaotfload-main.tex | 1590 + .../source/luatex/luaotfload/luaotfload-tool.rst | 325 + .../source/luatex/luaotfload/luaotfload.conf.rst | 347 + .../source/luatex/luaotfload/luaotfload.dtx | 2685 -- .../tex/luatex/luaotfload/luaotfload-auxiliary.lua | 231 +- .../luatex/luaotfload/luaotfload-basics-gen.lua | 25 + .../luatex/luaotfload/luaotfload-basics-nod.lua | 15 +- .../tex/luatex/luaotfload/luaotfload-blacklist.cnf | 8 - .../luatex/luaotfload/luaotfload-characters.lua | 34728 ++++++++++++------- .../tex/luatex/luaotfload/luaotfload-colors.lua | 39 +- .../luatex/luaotfload/luaotfload-configuration.lua | 704 + .../tex/luatex/luaotfload/luaotfload-database.lua | 1412 +- .../luatex/luaotfload/luaotfload-diagnostics.lua | 52 +- .../tex/luatex/luaotfload/luaotfload-features.lua | 389 +- .../luatex/luaotfload/luaotfload-fontloader.lua | 1522 +- .../tex/luatex/luaotfload/luaotfload-fonts-inj.lua | 526 + .../tex/luatex/luaotfload/luaotfload-fonts-otn.lua | 2848 ++ .../luaotfload/luaotfload-legacy-attributes.lua | 27 - .../luaotfload/luaotfload-legacy-database.lua | 724 - .../luatex/luaotfload/luaotfload-legacy-merged.lua | 8157 ----- .../tex/luatex/luaotfload/luaotfload-legacy.lua | 402 - .../luatex/luaotfload/luaotfload-letterspace.lua | 15 +- .../tex/luatex/luaotfload/luaotfload-loaders.lua | 4 +- .../tex/luatex/luaotfload/luaotfload-log.lua | 404 + .../tex/luatex/luaotfload/luaotfload-main.lua | 708 + .../tex/luatex/luaotfload/luaotfload-override.lua | 405 +- .../tex/luatex/luaotfload/luaotfload-parsers.lua | 701 + .../tex/luatex/luaotfload/luaotfload-status.lua | 54 +- .../tex/luatex/luaotfload/luaotfload.lua | 442 - .../tex/luatex/luaotfload/luaotfload.sty | 57 +- Master/tlpkg/tlpsrc/luaotfload.tlpsrc | 1 + 50 files changed, 36260 insertions(+), 27105 deletions(-) create mode 100644 Master/texmf-dist/doc/luatex/luaotfload/COPYING create mode 100644 Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.example create mode 100644 Master/texmf-dist/doc/luatex/luaotfload/valgrind-kpse-suppression.sup create mode 100644 Master/texmf-dist/doc/man/man5/luaotfload.conf.5 delete mode 100755 Master/texmf-dist/scripts/luaotfload/luaotfload-legacy-tool.lua create mode 100644 Master/texmf-dist/source/luatex/luaotfload/filegraph.dot create mode 100644 Master/texmf-dist/source/luatex/luaotfload/luaotfload-latex.tex create mode 100644 Master/texmf-dist/source/luatex/luaotfload/luaotfload-main.tex create mode 100644 Master/texmf-dist/source/luatex/luaotfload/luaotfload-tool.rst create mode 100644 Master/texmf-dist/source/luatex/luaotfload/luaotfload.conf.rst delete mode 100644 Master/texmf-dist/source/luatex/luaotfload/luaotfload.dtx create mode 100644 Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua create mode 100644 Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fonts-inj.lua create mode 100644 Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fonts-otn.lua delete mode 100644 Master/texmf-dist/tex/luatex/luaotfload/luaotfload-legacy-attributes.lua delete mode 100644 Master/texmf-dist/tex/luatex/luaotfload/luaotfload-legacy-database.lua delete mode 100644 Master/texmf-dist/tex/luatex/luaotfload/luaotfload-legacy-merged.lua delete mode 100644 Master/texmf-dist/tex/luatex/luaotfload/luaotfload-legacy.lua create mode 100644 Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua create mode 100644 Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua create mode 100644 Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua delete mode 100644 Master/texmf-dist/tex/luatex/luaotfload/luaotfload.lua diff --git a/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua b/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua index 5607c045039..4c5550891b2 100755 --- a/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua +++ b/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua @@ -2,17 +2,22 @@ ----------------------------------------------------------------------- -- FILE: luaotfload-tool.lua -- DESCRIPTION: database functionality --- REQUIREMENTS: luaotfload 2.4 +-- REQUIREMENTS: luaotfload 2.5 -- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang --- VERSION: 2.4-4 --- LICENSE: GPL v2 --- MODIFIED: 2013-07-28 13:12:04+0200 +-- VERSION: 2.5 +-- LICENSE: GPL v2.0 +-- MODIFIED: 2014-05-15 21:47:39+0200 ----------------------------------------------------------------------- -local version = "2.4-4" --- . +luaotfload = luaotfload or { } +local version = "2.5" --- .- +luaotfload.version = version +luaotfload.self = "luaotfload-tool" --[[doc-- +luaotfload-tool(1) + This file was originally written (as \fileent{mkluatexfontdb.lua}) by Elie Roux and Khaled Hosny and, as a derived work of ConTeXt, is provided under the terms of the GPL v2.0 license as printed in full @@ -33,17 +38,16 @@ kpse.set_program_name "luatex" --[[doc-- We test for Lua 5.1 by means of capability detection to see if - we’re running an outdated Luatex. If so, we hand over control to - the legacy db runner. + we’re running an outdated Luatex. If so, we bail. \url{http://lua-users.org/wiki/LuaVersionCompatibility} --doc]]-- -local ioopen = io.open local iowrite = io.write local kpsefind_file = kpse.find_file +local mathfloor = math.floor local next = next local osdate = os.date local ostype = os.type @@ -63,8 +67,10 @@ if _G.getfenv ~= nil then -- 5.1 or LJ runtime = { "jit", jit.version } else runtime = { "stock", _VERSION } - local oldscript = kpsefind_file "luaotfload-legacy-tool.lua" - return require (oldscript) + print "FATAL ERROR" + print "Luaotfload requires a Luatex version >=0.76." + print "Please update your TeX distribution!" + os.exit (-1) end else -- 5.2 runtime = { "stock", _VERSION } @@ -83,56 +89,19 @@ string.quoted = string.quoted or function (str) return string.format("%q",str) end -require(loader_path) +require (loader_path) --[[doc-- -Depending on how the script is called we change its behavior. -For backwards compatibility, moving or symlinking the script to a -file name starting with \fileent{mkluatexfontdb} will cause it to -trigger a database update on every run. -Running as \fileent{luaotfload-tool} -- the new name -- will do this upon -request only. - -There are two naming conventions followed here: firstly that of -utilities such as \fileent{mktexpk}, \fileent{mktexlsr} and the likes, -and secondly that of \fileent{fmtutil}. -After support for querying the database was added, the latter appeared -to be the more appropriate. ---doc]]-- -config = config or { } -local config = config -local luaotfloadconfig = config.luaotfload or { } -config.luaotfload = luaotfloadconfig -luaotfloadconfig.version = luaotfloadconfig.version or version -luaotfloadconfig.names_dir = luaotfloadconfig.names_dir or "names" -luaotfloadconfig.cache_dir = luaotfloadconfig.cache_dir or "fonts" -luaotfloadconfig.index_file = luaotfloadconfig.index_file - or "luaotfload-names.lua" -luaotfloadconfig.formats = luaotfloadconfig.formats - or "otf,ttf,ttc,dfont" -luaotfloadconfig.reload = false -if not luaotfloadconfig.strip then - luaotfloadconfig.strip = true -end + XXX: + Creating the config table will be moved to the common + initialization when the times comes. -do -- we don’t have file.basename and the likes yet, so inline parser ftw - local slash = P"/" - local dot = P"." - local noslash = 1 - slash - local slashes = slash^1 - local path = slashes^-1 * (noslash^1 * slashes)^1 - local thename = (1 - slash - dot)^1 - local extension = dot * (1 - slash - dot)^1 - local p_basename = path^-1 * C(thename) * extension^-1 * P(-1) - - local self = lpegmatch(p_basename, stringlower(arg[0])) - if self == "luaotfload-tool" then - luaotfloadconfig.self = "luaotfload-tool" - else - luaotfloadconfig.self = "mkluatexfontdb" - end -end +--doc]]-- + +config = config or { } +local config = config +config.luaotfload = config.luaotfload or { } config.lualibs = config.lualibs or { } config.lualibs.verbose = false @@ -140,8 +109,13 @@ config.lualibs.prefer_merged = true config.lualibs.load_extended = true require "lualibs" -local tabletohash = table.tohash +local iosavedata = io.savedata +local lfsisdir = lfs.isdir +local lfsisfile = lfs.isfile local stringsplit = string.split +local tableserialize = table.serialize +local tablesortedkeys = table.sortedkeys +local tabletohash = table.tohash --[[doc-- \fileent{luatex-basics-gen.lua} calls functions from the @@ -169,22 +143,17 @@ require"luaotfload-basics-gen.lua" texio.write, texio.write_nl = backup.write, backup.write_nl utilities = backup.utilities -require"luaotfload-override.lua" --- this populates the logs.* namespace -require"luaotfload-database" -require"alt_getopt" - -local names = fonts.names - -local status_file = "luaotfload-status" -local luaotfloadstatus = require (status_file) -luaotfloadconfig.status = luaotfloadstatus +require "luaotfload-log.lua" --- this populates the luaotfload.log.* namespace +require "luaotfload-parsers" --- fonts.conf, configuration, and request syntax +require "luaotfload-configuration" --- configuration file handling +require "luaotfload-database" +require "alt_getopt" +local names = fonts.names local sanitize_fontname = names.sanitize_fontname -local pathdata = names.path -local names_plain = pathdata.index.lua -local names_gzip = names_plain .. ".gz" -local names_bin = pathdata.index.luc +local log = luaotfload.log +local report = log.report local help_messages = { ["luaotfload-tool"] = [[ @@ -211,9 +180,6 @@ Usage: %s [OPTIONS...] "environment", "index", "permissions", or "repository" - --alias= force behavior of "luaotfload-tool" or legacy - "mkluatexfontdb" - ------------------------------------------------------------------------------- DATABASE @@ -221,6 +187,7 @@ Usage: %s [OPTIONS...] -n --no-reload suppress db update --no-strip keep redundant information in db -f --force force re-indexing all fonts + -L --local scan font files in $PWD -c --no-compress do not gzip index file (text version only) -l --flush-lookups empty lookup cache of font requests -D --dry-run skip loading of fonts, just scan @@ -243,6 +210,10 @@ Usage: %s [OPTIONS...] --fields=,,…, which fields to print with --list -b --show-blacklist show blacklisted files + --bisect= control database bisection: valid + directives are "start", "stop", "run", "status", + "good", "bad" + The font database will be saved to %s %s @@ -258,49 +229,37 @@ The font cache will be written to ]], mkluatexfontdb = [[ - -Usage: %s [OPTION]... - -Rebuild or update the Luaotfload font names database. - -Valid options: - -f --force force re-indexing all fonts - -q --quiet don't output anything - -v --verbose=LEVEL be more verbose (print the searched directories) - -vv print the loaded fonts - -vvv print all steps of directory searching - -V --version print version and exit - -h --help print this message - --alias= force behavior of "luaotfload-tool" or legacy - "mkluatexfontdb" - -The font database will be saved to - %s - %s - +FATAL ERROR +As of Luaotfload v2.5, legacy behavior is not supported anymore. Please +update your scripts and/or habits! Kthxbye. ]], short = [[ Usage: luaotfload-tool [--help] [--version] [--verbose=] - [--update] [--force] [--prefer-texmf] + [--update] [--force] [--prefer-texmf] [--local] [--dry-run] [--formats=] [--find=] [--fuzzy] [--info] [--inspect] [--list=] [--fields=] [--cache=] [--flush-lookups] [--show-blacklist] [--diagnose=] + [--no-compress] [--no-strip] [--local] + [--max-fonts=] [--bisect=] Enter 'luaotfload-tool --help' for a larger list of options. ]] } local help_msg = function (version) - local template = help_messages[version] + local template = help_messages[version] + local paths = config.luaotfload.paths + local names_plain = paths.index_path_lua + local names_gzip = names_plain .. ".gz" + local names_bin = paths.index_path_luc + iowrite(stringformat(template, - luaotfloadconfig.self, --- names_plain, + luaotfload.self, names_gzip, names_bin, - caches.getwritablepath ( - luaotfloadconfig.cache_dir))) + caches.getwritablepath (config.luaotfload.cache_dir))) end local about = [[ @@ -311,16 +270,28 @@ local about = [[ ]] local version_msg = function ( ) - local out = function (...) texiowrite_nl (stringformat (...)) end - out (about, luaotfloadconfig.self) - out ("%s version %q", luaotfloadconfig.self, version) - out ("revision %q", luaotfloadstatus.notes.revision) - out ("database version %q", names.version) + local out = function (...) texiowrite_nl (stringformat (...)) end + local uname = os.uname () + local meta = names.getmetadata () + out (about, luaotfload.self) + out ("%s version: %q", luaotfload.self, version) + out ("Revision: %q", config.luaotfload.status.notes.revision) out ("Lua interpreter: %s; version %q", runtime[1], runtime[2]) - out ("Luatex SVN revision %d", status.luatex_svn) - out ("Luatex version %.2f.%d", + out ("Luatex SVN revision: %d", status.luatex_svn) + out ("Luatex version: %.2f.%d", status.luatex_version / 100, status.luatex_revision) + out ("Platform: type=%s name=%s", os.type, os.name) + + local uname_vars = tablesortedkeys (uname) + for i = 1, #uname_vars do + local var = uname_vars[i] + out (" + %8s: %s", var, uname[var]) + end + out ("Index: version=%q created=%q modified=%q", + config.luaotfload.status.notes.revision, + meta.created or "ages ago", + meta.modified or "ages ago") out "" end @@ -332,7 +303,7 @@ local head_adornchars = { } local textwidth = 80 -local wd_leftcolumn = math.floor(textwidth * .25) +local wd_leftcolumn = mathfloor(textwidth * .25) local key_fmt = stringformat([[%%%ds]], wd_leftcolumn) local val_fmt = [[%s]] local fieldseparator = ":" @@ -380,15 +351,36 @@ local print_heading = function (title, level) texiowrite_nl (s .. stringrep(adornchar, textwidth-utf.len(s))) end +local baseindent = " " + +--[[doc-- + + show_info_items -- Together with show_info_table prints the table returned by + fontloader.info(), recursing into nested tables if appropriate (as necessitated + by Luatex versions 0.78+ which include the pfminfo table in the result. + +--doc]]-- + +local show_info_table show_info_table = function (t, depth) + depth = depth or 0 + local indent = stringrep (baseindent, depth) + local keys = tablesortedkeys (t) + for n = 1, #keys do + local key = keys [n] + local val = t [key] + if type (val) == "table" then + texiowrite_nl (indent .. stringformat (info_fmt, key, "")) + show_info_table (val, depth + 1) + else + texiowrite_nl (indent .. stringformat (info_fmt, key, val)) + end + end +end + local show_info_items = function (fontinfo) - local items = table.sortedkeys(fontinfo) - print_heading(fontinfo.fullname, 1) + print_heading (fontinfo.fullname, 1) texiowrite_nl "" - for n = 1, #items do - local item = items[n] - texiowrite_nl(stringformat( - info_fmt, item, fontinfo[item])) - end + show_info_table (fontinfo) texiowrite_nl "" end @@ -707,9 +699,9 @@ local show_font_info = function (basename, askedname, detail, warnings) if nfonts > 0 then -- true type collection local subfont if askedname then - logs.names_report(true, 1, "resolve", - [[%s is part of the font collection %s]], - askedname, basename) + report (true, 1, "resolve", + [[%s is part of the font collection %s]], + askedname, basename) subfont = subfont_by_name(shortinfo, askedname) end if subfont then @@ -718,11 +710,11 @@ local show_font_info = function (basename, askedname, detail, warnings) show_full_info(fullname, subfont, warnings) end else -- list all subfonts - logs.names_report(true, 1, "resolve", - [[%s is a font collection]], basename) + report (true, 1, "resolve", + [[%s is a font collection]], basename) for subfont = 1, nfonts do - logs.names_report(true, 1, "resolve", - [[Showing info for font no. %d]], n) + report (true, 1, "resolve", + [[Showing info for font no. %d]], n) show_info_items(shortinfo[subfont]) if detail == true then show_full_info(fullname, subfont, warnings) @@ -736,8 +728,7 @@ local show_font_info = function (basename, askedname, detail, warnings) end end else - logs.names_report(true, 1, "resolve", - "Font %s not found", filename) + report (true, 1, "resolve", "Font %s not found", filename) end end @@ -748,23 +739,40 @@ set. --]]-- local action_sequence = { - "loglevel", "help", "version", "diagnose", - "blacklist", "cache", "flush", "generate", - "list", "query", + "config", "loglevel", "help", "version", + "diagnose", "blacklist", "cache", "flush", + "bisect", "generate", "list", "query", } local action_pending = tabletohash(action_sequence, false) +action_pending.config = true --- always read the configuration action_pending.loglevel = true --- always set the loglevel action_pending.generate = false --- this is the default action local actions = { } --- (jobspec -> (bool * bool)) list actions.loglevel = function (job) - logs.set_loglevel(job.log_level) - logs.names_report("info", 3, "util", - "Setting log level", "%d", job.log_level) - logs.names_report("log", 2, "util", "Lua=%s", _VERSION) + local lvl = job.log_level + if lvl then + log.set_loglevel(lvl) + report ("info", 3, "util", "Setting the log level to %d.", lvl) + report ("log", 2, "util", "Lua=%q", _VERSION) + end + return true, true +end + +actions.config = function (job) + local defaults = luaotfload.default_config + local vars = config.actions.read (job.extra_config) + config.luaotfload = config.actions.apply (defaults, vars) + config.luaotfload = config.actions.apply (config.luaotfload, job.config) + + --inspect(config.luaotfload) + --os.exit() + if not config.actions.reconfigure () then + return false, false + end return true, true end @@ -781,29 +789,322 @@ end actions.blacklist = function (job) names.read_blacklist() local n = 0 - for n, entry in next, table.sortedkeys(names.blacklist) do + for n, entry in next, tablesortedkeys(names.blacklist) do iowrite (stringformat("(%d %s)\n", n, entry)) end return true, false end actions.generate = function (job) - local fontnames, savedname - fontnames = names.update(fontnames, job.force_reload, job.dry_run) - logs.names_report("info", 2, "db", - "Fonts in the database: %i", #fontnames.mappings) - if names.data() then + local _ = names.update (fontnames, job.force_reload, job.dry_run) + local namedata = names.data () + if namedata then + report ("info", 2, "db", "Fonts in the database: %i", #namedata.mappings) return true, true end return false, false end +------------------------------------------------------------------------------- +--- bisect mode +------------------------------------------------------------------------------- + +local bisect_status_path = caches.getwritablepath "bisect" +local bisect_status_file = bisect_status_path .."/" .. "luaotfload-bisect-status.lua" +local bisect_status_fmt = [[ +--[==[------------------------------------------------------------------------- + This file is generated by Luaotfload. It can be safely deleted. + Creation date: %s. +-------------------------------------------------------------------------]==]-- + +%s + +--- vim:ft=lua:ts=8:et:sw=2 +]] + +--[[doc-- + + write_bisect_status -- Write the history of the current bisection to disk. + +--doc]]-- + +--- state list -> bool +local write_bisect_status = function (data) + local payload = tableserialize (data, true) + local status = stringformat (bisect_status_fmt, + osdate ("%Y-%m-d %H:%M:%S", os.time ()), + payload) + if status and iosavedata (bisect_status_file, status) then + report ("info", 4, "bisect", + "Bisection state written to %s.", bisect_status_file) + return true + end + report ("info", 0, "bisect", + "Failed to write bisection state to %s.", bisect_status_file) + return false +end + +--[[doc-- + + read_bisect_status -- Read the bisect log from disk. + +--doc]]-- + +--- unit -> state list +local read_bisect_status = function () + report ("info", 4, "bisect", "Testing for status file: %q.", bisect_status_file) + if not lfsisfile (bisect_status_file) then + report ("info", 2, "bisect", "No such file: %q.", bisect_status_file) + report ("info", 0, "bisect", "Not in bisect mode.") + return false + end + report ("info", 4, "bisect", "Reading status file: %q.", bisect_status_file) + local success, status = pcall (dofile, bisect_status_file) + if not success then + report ("info", 0, "bisect", "Could not read status file.") + return false + end + return status +end + +--[[doc-- + + bisect_start -- Begin a bisect session. Determines the number of + fonts and sets the initial high, low, and pivot values. + +--doc]]-- + +local bisect_start = function () + if lfsisfile (bisect_status_file) then + report ("info", 0, "bisect", + "Bisect session in progress.", + bisect_status_file) + report ("info", 0, "bisect", + "Use --bisect=stop to erase it before starting over.") + return false, false + end + report ("info", 2, "bisect", + "Starting bisection of font database %q.", bisect_status_file) + local n = names.count_font_files () + local pivot = mathfloor (n / 2) + local data = { { 1, n, pivot } } + report ("info", 0, "bisect", "Initializing pivot to %d.", pivot) + if write_bisect_status (data) then + return true, false + end + return false, false +end + +--[[doc-- + + bisect_stop -- Terminate bisection session by removing all state info. + +--doc]]-- + +local bisect_stop = function () + report ("info", 3, "bisect", "Erasing bisection state at %s.", bisect_status_file) + if lfsisfile (bisect_status_file) then + local success, msg = os.remove (bisect_status_file) + if not success then + report ("info", 2, "bisect", + "Failed to erase file %s (%s).", + bisect_status_file, msg) + end + end + if lfsisdir (bisect_status_path) then + local success, msg = os.remove (bisect_status_path) + if not success then + report ("info", 2, "bisect", + "Failed to erase directory %s (%s).", + bisect_status_path, msg) + end + end + if lfsisfile (bisect_status_file) then + return false, false + end + return true, false +end + +--[[doc-- + + bisect_terminate -- Wrap up a bisect session by printing the + offending font and removing the state file. + +--doc]]-- + +local bisect_terminate = function (nsteps, culprit) + report ("info", 1, "bisect", + "Bisection completed after %d steps.", nsteps) + report ("info", 0, "bisect", + "Bad file: %s.", names.nth_font_filename (culprit)) + report ("info", 0, "bisect", + "Run with --bisect=stop to finish bisection.") + return true, false +end + +--[[doc-- + + list_remainder -- Show remaining fonts in bisect slice. + +--doc]]-- + +local list_remainder = function (lo, hi) + local fonts = names.font_slice (lo, hi) + report ("info", 0, "bisect", "%d fonts left.", hi - lo + 1) + for i = 1, #fonts do + report ("info", 1, "bisect", " · %2d: %s", lo, fonts[i]) + lo = lo + 1 + end +end + +--[[doc-- + + bisect_set -- Prepare the next bisection step by setting high, low, + and pivot to new values. + + The “run” directive always picks the segment below the pivot so we + can rely on the “outcome parameter” to be referring to that. + +--doc]]-- + +local bisect_set = function (outcome) + local status = read_bisect_status () + if not status then + return false, false + end + + local nsteps = #status + local previous = status[nsteps] + if previous == true then + --- Bisection already completed; we exit early through + --- bisect_terminate() to avoid further writes to the + --- state files that mess up step counting. + nsteps = nsteps - 1 + return bisect_terminate (nsteps, status[nsteps][1]) + end + + local lo, hi, pivot = unpack (previous) + + report ("info", 3, "bisect", "Previous step %d: lo=%d, hi=%d, pivot=%d.", + nsteps, lo, hi, pivot) + + if outcome == "bad" then + hi = pivot + if lo >= hi then --- complete + status[nsteps + 1] = { lo, lo, lo } + status[nsteps + 2] = true + write_bisect_status (status) + return bisect_terminate (nsteps, lo) + end + pivot = mathfloor ((lo + hi) / 2) + report ("info", 0, "bisect", + "Continuing with the lower segment: lo=%d, hi=%d, pivot=%d.", + lo, hi, pivot) + elseif outcome == "good" then + lo = pivot + 1 + if lo >= hi then --- complete + status[nsteps + 1] = { lo, lo, lo } + write_bisect_status (status) + status[nsteps + 2] = true + return bisect_terminate (nsteps, lo) + end + pivot = mathfloor ((lo + hi) / 2) + report ("info", 0, "bisect", + "Continuing with the upper segment: lo=%d, hi=%d, pivot=%d.", + lo, hi, pivot) + else -- can’t happen + report ("info", 0, "bisect", "What the hell?", lo, hi, pivot) + return false, false + end + + status[nsteps + 1] = { lo, hi, pivot } + write_bisect_status (status) + if hi - lo <= 10 then + list_remainder (lo, hi) + end + return true, false +end + +--[[doc-- + + bisect_status -- Output information about the current bisect session. + +--doc]]-- + +local bisect_status = function () + local status = read_bisect_status () + if not status then + return false, false + end + local nsteps = #status + if nsteps > 1 then + for i = nsteps - 1, 1, -1 do + local step = status[i] + report ("info", 2, "bisect", "Step %d: lo=%d, hi=%d, pivot=%d.", + i, unpack (step)) + end + end + local current = status[nsteps] + report ("info", 0, "bisect", "Step %d: lo=%d, hi=%d, pivot=%d.", + nsteps, unpack (current)) + return true, false +end + +--[[doc-- + + bisect_run -- Run Luaotfload utilizing the current bisection state. + This should be combined with the --update mode, possibly with the + --force option. + + Luaotfload always tests the segment below the pivot first. + +--doc]]-- + +local bisect_run = function () + local status = read_bisect_status () + if not status then + return false, false + end + local nsteps = #status + local currentstep = nsteps + 1 + local current = status[nsteps] + if current == true then -- final step + current = status[nsteps - 1] + end + local lo, hi, pivot = unpack (current) + report ("info", 3, "bisect", "Previous step %d: lo=%d, hi=%d, pivot=%d.", + nsteps, lo, hi, pivot) + report ("info", 1, "bisect", "Step %d: Testing fonts from %d to %d.", + currentstep, lo, pivot) + config.luaotfload.misc.bisect = { lo, pivot } + return true, true +end + +local bisect_modes = { + start = bisect_start, + good = function () return bisect_set "good" end, + bad = function () return bisect_set "bad" end, + stop = bisect_stop, + status = bisect_status, + run = bisect_run, +} + +actions.bisect = function (job) + local mode = job.bisect + local runner = bisect_modes[mode] + if not runner then + report ("info", 0, "bisect", "Unknown directive %q.", mode) + return false, false + end + return runner (job) +end + actions.flush = function (job) - local success, lookups = names.flush_lookup_cache() + local success = names.flush_lookup_cache() if success then local success = names.save_lookups() if success then - logs.names_report("info", 2, "cache", "Lookup cache emptied") + report ("info", 2, "cache", "Lookup cache emptied") return true, true end end @@ -819,8 +1120,8 @@ local cache_directives = { actions.cache = function (job) local directive = cache_directives[job.cache] if not directive or type(directive) ~= "function" then - logs.names_report("info", 2, "cache", - "Invalid font cache directive %s.", job.cache) + report ("info", 2, "cache", + "Invalid font cache directive %s.", job.cache) return false, false end if directive() then @@ -856,36 +1157,35 @@ actions.query = function (job) then foundname, subfont = names.resolve_name (tmpspec) if foundname then - foundname, _, success = names.crude_file_lookup (foundname) + foundname, _, success = names.font_file_lookup (foundname) end elseif tmpspec.lookup == "file" then foundname, _, success = - names.crude_file_lookup (tmpspec.name) + names.font_file_lookup (tmpspec.name) end if success then - logs.names_report(false, 0, - "resolve", "Font %q found!", query) + report (false, 0, "resolve", "Font %q found!", query) if subfont then - logs.names_report(false, 0, "resolve", - "Resolved file name %q, subfont nr. %q", + report (false, 0, "resolve", + "Resolved file name %q, subfont nr. %q", foundname, subfont) else - logs.names_report(false, 0, "resolve", - "Resolved file name %q", foundname) + report (false, 0, "resolve", + "Resolved file name %q", foundname) end if job.show_info then show_font_info (foundname, query, job.full_info, job.warnings) iowrite "\n" end else - logs.names_report(false, 0, - "resolve", "Cannot find %q in index.", query) - logs.names_report(false, 0, - "resolve", "Hint: use the --fuzzy option to display suggestions.", query) + report (false, 0, "resolve", "Cannot find %q in index.", query) + report (false, 0, "resolve", + "Hint: use the --fuzzy option to display suggestions.", + query) if job.fuzzy == true then - logs.names_report(false, 0, - "resolve", "Looking for close matches, this may take a while ...") + report (false, 0, "resolve", + "Looking for close matches, this may take a while ...") local _success = names.find_closest(query, job.fuzzy_limit) end end @@ -959,7 +1259,7 @@ set_primary_field = function (fields, addme, acc, n) return acc end -local splitcomma = names.patterns.splitcomma +local splitcomma = luaotfload.parsers.splitcomma actions.list = function (job) local criterion = job.criterion @@ -983,7 +1283,7 @@ actions.list = function (job) local nmappings = #mappings if criterion == "*" then - logs.names_report(false, 1, "list", "All %d entries", nmappings) + report (false, 1, "list", "All %d entries", nmappings) for i=1, nmappings do local entry = mappings[i] local fields = get_fields(entry, asked_fields) @@ -998,12 +1298,12 @@ actions.list = function (job) criterion = criterion[1] asked_fields = set_primary_field(asked_fields, criterion) - logs.names_report(false, 1, "list", "By %s", criterion) + report (false, 1, "list", "By %s", criterion) --- firstly, build a list of fonts to operate on local targets = { } if asked_value then --- only those whose value matches - logs.names_report(false, 2, "list", "Restricting to value %s", asked_value) + report (false, 2, "list", "Restricting to value %s", asked_value) for i=1, nmappings do local entry = mappings[i] if entry[criterion] @@ -1048,7 +1348,7 @@ actions.list = function (job) end end local ntargets = #targets - logs.names_report(false, 2, "list", "%d entries", ntargets) + report (false, 2, "list", "%d entries", ntargets) --- now, output the collection for i=1, ntargets do @@ -1088,7 +1388,7 @@ end --[[-- Command-line processing. -mkluatexfontdb.lua relies on the script alt_getopt to process argv and +luaotfload-tool relies on the script alt_getopt to process argv and analyzes its output. TODO with extended lualibs we have the functionality from the @@ -1103,13 +1403,15 @@ local process_cmdline = function ( ) -- unit -> jobspec warnings = false, criterion = "", query = "", - log_level = 0, --- 2 is approx. the old behavior + log_level = nil, + bisect = nil, + config = { db = { }, misc = { }, run = { }, paths = { } }, } local long_options = { - alias = 1, + ["bisect"] = 1, cache = 1, - ["no-compress"] = "c", + conf = 1, diagnose = 1, ["dry-run"] = "D", ["flush-lookups"] = "l", @@ -1123,12 +1425,15 @@ local process_cmdline = function ( ) -- unit -> jobspec inspect = "I", limit = 1, list = 1, + ["local"] = "L", log = 1, ["max-fonts"] = 1, + ["no-compress"] = "c", ["no-reload"] = "n", ["no-strip"] = 0, ["skip-read"] = "R", ["prefer-texmf"] = "p", + ["print-conf"] = 0, quiet = "q", ["show-blacklist"] = "b", stats = "S", @@ -1138,7 +1443,7 @@ local process_cmdline = function ( ) -- unit -> jobspec warnings = "w", } - local short_options = "bcDfFiIlnpqRSuvVhw" + local short_options = "bcDfFiIlLnpqRSuvVhw" local options, _, optarg = alt_getopt.get_ordered_opts (arg, short_options, long_options) @@ -1151,11 +1456,13 @@ local process_cmdline = function ( ) -- unit -> jobspec elseif v == "u" then action_pending["generate"] = true elseif v == "v" then - if result.log_level > 0 then - result.log_level = result.log_level + 1 + local lvl = result.log_level + if not lvl or lvl < 1 then + lvl = 1 else - result.log_level = 1 + lvl = lvl + 1 end + result.log_level = lvl elseif v == "V" then action_pending["version"] = true elseif v == "h" then @@ -1177,7 +1484,7 @@ local process_cmdline = function ( ) -- unit -> jobspec elseif v == "log" then local str = optarg[n] if str then - finalizers = logs.set_logout(str, finalizers) + finalizers = log.set_logout(str, finalizers) end elseif v == "find" then action_pending["query"] = true @@ -1194,10 +1501,11 @@ local process_cmdline = function ( ) -- unit -> jobspec elseif v == "I" then result.show_info = true result.full_info = true - elseif v == "alias" then - luaotfloadconfig.self = optarg[n] elseif v == "l" then action_pending["flush"] = true + elseif v == "L" then + action_pending["generate"] = true + result.config.db.scan_local = true elseif v == "list" then action_pending["list"] = true result.criterion = optarg[n] @@ -1218,35 +1526,46 @@ local process_cmdline = function ( ) -- unit -> jobspec action_pending["diagnose"] = true result.asked_diagnostics = optarg[n] elseif v == "formats" then - names.set_font_filter (optarg[n]) + result.config.db.formats = optarg[n] + --names.set_font_filter (optarg[n]) elseif v == "n" then - luaotfloadconfig.update_live = false + result.config.db.update_live = false elseif v == "S" then - luaotfloadconfig.statistics = true + result.config.misc.statistics = true elseif v == "R" then --- dev only, undocumented - luaotfloadconfig.skip_read = true + result.config.db.skip_read = true elseif v == "c" then - luaotfloadconfig.compress = false + result.config.db.compress = false elseif v == "no-strip" then - luaotfloadconfig.strip = false + result.config.db.strip = false elseif v == "max-fonts" then local n = optarg[n] if n then n = tonumber(n) if n and n > 0 then - luaotfloadconfig.max_fonts = n + result.config.db.max_fonts = n end end + elseif v == "bisect" then + result.bisect = optarg[n] + action_pending.bisect = true + elseif v == "conf" then + local extra = stringexplode (optarg[n], ",+") + if extra then + local extra_config = result.extra_config + if extra_config then + table.append (extra_config, extra) + else + result.extra_config = extra + end + end + elseif v == "print-conf" then + result.print_config = true end end - if luaotfloadconfig.self == "mkluatexfontdb" then --- TODO drop legacy ballast after 2.4 - result.help_version = "mkluatexfontdb" - action_pending["generate"] = true - result.log_level = math.max(1, result.log_level) - logs.set_logout("stdout", finalizers) - elseif nopts == 0 then + if nopts == 0 then action_pending["help"] = true result.help_version = "short" end @@ -1264,24 +1583,23 @@ local main = function ( ) -- unit -> int local actionname = action_sequence[i] local exit = false if action_pending[actionname] then - logs.names_report("log", 3, "util", "Preparing for task", - "%s", actionname) + report ("log", 3, "util", "Preparing for task", "%s", actionname) local action = actions[actionname] local success, continue = action(job) if not success then - logs.names_report(false, 0, "util", - "Could not finish task", "%s", actionname) + report (false, 0, "util", + "Failed to execute task.", "%s", actionname) retval = -1 exit = true elseif not continue then - logs.names_report(false, 3, "util", - "Task completed, exiting", "%s", actionname) - exit = true + report (false, 3, "util", + "Task completed, exiting.", "%s", actionname) + exit = true else - logs.names_report(false, 3, "util", - "Task completed successfully", "%s", actionname) + report (false, 3, "util", + "Task completed successfully.", "%s", actionname) end end if exit then break end diff --git a/Master/texmf-dist/doc/luatex/luaotfload/COPYING b/Master/texmf-dist/doc/luatex/luaotfload/COPYING new file mode 100644 index 00000000000..d769b3faa1a --- /dev/null +++ b/Master/texmf-dist/doc/luatex/luaotfload/COPYING @@ -0,0 +1,350 @@ +Context, where the fontloader Luaotfload is built around originates, is +licensed under the GPL version 2.0 (exactly). As a derived work, anything +Luaotflaod adds to that is also subject to the same license at the same +version. The “any later version” clause as used by the FSF in the license text +*does not apply* to either Context or Luaotfload, despite being kept around in +the license text given below. + +------------------------------------------------------------------------------- + LICENSE TEXT BELOW +------------------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/Master/texmf-dist/doc/luatex/luaotfload/NEWS b/Master/texmf-dist/doc/luatex/luaotfload/NEWS index a87417fa268..c460f620675 100644 --- a/Master/texmf-dist/doc/luatex/luaotfload/NEWS +++ b/Master/texmf-dist/doc/luatex/luaotfload/NEWS @@ -1,14 +1,27 @@ Change History -------------- -2014/05/18, luaotfload v2.4-4 - * Fix incorrect handling of font file formats (backport of commit - 828a69ef... to the 2.5 branch). - -2014/02/05, luaotfload v2.4-3 - * Add contact info to --version output of luaotfload-tool (backport from - 2.5). - * Fix bug with broken font names (backport from 2.5). +2014/07/13, luaotfload v2.5 + * Remove legacy code. + * Remove compatibility with the old mkluatexfontdb script. + * Remove test directory. Use https://bitbucket.org/phg/lua-la-tex-tests + instead. + * Remove luaotfload.lua from luaotfload.dtx; it is now a separate file + luaotfload-main.lua. + * Standard source tree structure: the code is now located in the ./doc, + ./scripts, ./src, ./build, and ./misc directories. + * Move the heavier LPEG parsers from luaotfload-features (syntax) and + luaotfload-database (fontconfig) into the new file + luaotfload-parsers.lua. + * Move logging routines from luaotfload-override in to luaotfload-log. + * Scan local font files (``--local`` flag to luaotfload-tool, flag + ``scan_local`` during TeX run). + * Add bisection mode (``--bisect``) to luaotfload-tool. + * Add functions for accessing the database: ``aux.font_index()`` and + ``aux.read_font_index()``. + * Distinguish XDG configuration paths (Reuben Thomas) + * Optional configuration via rc files. + * Configure default features via configuration file. 2013/12/31, luaotfload v2.4 * Additional self-tests, now in separate file (luaotfload-diagnostics.lua) diff --git a/Master/texmf-dist/doc/luatex/luaotfload/README b/Master/texmf-dist/doc/luatex/luaotfload/README index 903551f70c3..75575d2ddc6 100644 --- a/Master/texmf-dist/doc/luatex/luaotfload/README +++ b/Master/texmf-dist/doc/luatex/luaotfload/README @@ -32,6 +32,7 @@ Elie Roux Will Robertson Philipp Gesang Dohyun Kim +Reuben Thomas Installation diff --git a/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf b/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf index bd2d0a6039b..50d4160abf2 100644 Binary files a/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf and b/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf differ diff --git a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.example b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.example new file mode 100644 index 00000000000..2756d62126a --- /dev/null +++ b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.example @@ -0,0 +1,30 @@ +;; Example configuration file for Luaotfload. This file contains the +;; defaults only, see luaotfload.conf(5) for more information. + +[db] + compress = true + formats = otf, ttf, ttc, dfont + max-fonts = 2.2517998136852e15 + scan-local = false + skip-read = false + strip = true + update-live = true + +[misc] + statistics = false + termwidth = nil + +[paths] + cache-dir = fonts + names-dir = names + index-file = luaotfload-names.lua + lookups-file = luaotfload-lookup-cache.lua + +[run] + color-callback = pre_linebreak_filter + definer = patch + log-level = 0 + resolver = cached + +;; vim:ft=dosini:et:sw=4:ts=8 + diff --git a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.pdf b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.pdf index 4e5f71ebe60..6572c7b121f 100644 Binary files a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.pdf and b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.pdf differ diff --git a/Master/texmf-dist/doc/luatex/luaotfload/valgrind-kpse-suppression.sup b/Master/texmf-dist/doc/luatex/luaotfload/valgrind-kpse-suppression.sup new file mode 100644 index 00000000000..dc325869fa1 --- /dev/null +++ b/Master/texmf-dist/doc/luatex/luaotfload/valgrind-kpse-suppression.sup @@ -0,0 +1,140 @@ +{ + kpathsea-garbage-1 + Memcheck:Leak + match-leak-kinds: all + ... + fun:kpathsea_cnf_get +} + +{ + kpathsea-garbage-2 + Memcheck:Leak + match-leak-kinds: all + ... + fun:kpse_program_basename +} + + +{ + kpathsea-garbage-3 + Memcheck:Leak + match-leak-kinds: all + ... + fun:kpse_find_file +} + + +{ + kpathsea-garbage-4 + Memcheck:Leak + match-leak-kinds: all + ... + fun:find_file +} + +{ + kpathsea-garbage-5 + Memcheck:Leak + match-leak-kinds: all + ... + fun:lua_kpse_lookup +} + +{ + kpathsea-garbage-6 + Memcheck:Leak + match-leak-kinds: all + ... + fun:find_file +} + + +{ + kpathsea-garbage-7 + Memcheck:Leak + match-leak-kinds: all + ... + fun:expand_path +} + +{ + kpathsea-garbage-8 + Memcheck:Leak + match-leak-kinds: all + ... + fun:do_lua_kpathsea_lookup +} + + +{ + kpathsea-garbage-9 + Memcheck:Leak + match-leak-kinds: all + ... + fun:kpathsea_find_file +} + + +{ + kpathsea-garbage-10 + Memcheck:Leak + match-leak-kinds: all + ... + fun:kpathsea_init_db +} + + +{ + kpathsea-garbage-11 + Memcheck:Leak + match-leak-kinds: all + ... + fun:kpathsea_find_file_generic +} + + +{ + kpathsea-garbage-12 + Memcheck:Leak + match-leak-kinds: all + ... + fun:expand_var +} + + +{ + kpathsea-garbage-13 + Memcheck:Leak + match-leak-kinds: all + ... + fun:init_path +} + + +{ + kpathsea-garbage-14 + Memcheck:Leak + match-leak-kinds: all + ... + fun:kpse_in_name_ok +} + + +{ + kpathsea-garbage-15 + Memcheck:Leak + match-leak-kinds: all + ... + fun:kpathsea_var_value +} + + +{ + kpathsea-garbage-16 + Memcheck:Leak + match-leak-kinds: all + ... + fun:kpse_set_program_name +} + + diff --git a/Master/texmf-dist/doc/man/man1/luaotfload-tool.1 b/Master/texmf-dist/doc/man/man1/luaotfload-tool.1 index d368e35f84a..dd8abe2999f 100644 --- a/Master/texmf-dist/doc/man/man1/luaotfload-tool.1 +++ b/Master/texmf-dist/doc/man/man1/luaotfload-tool.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH LUAOTFLOAD-TOOL 1 "2014-05-18" "2.4-4" "text processing" +.TH LUAOTFLOAD-TOOL 1 "2014-03-30" "2.5" "text processing" .SH NAME luaotfload-tool \- generate and query the Luaotfload font names database . @@ -32,13 +32,14 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .. .SH SYNOPSIS .sp -\fBluaotfload\-tool\fP [ \-bDfFiIlnpquvVhw ] +\fBluaotfload\-tool\fP [ \-bcDfFiIlLnpqRSuvVhw ] .INDENT 0.0 .TP .B \fBluaotfload\-tool\fP \-\-update [ \-\-force ] [ \-\-quiet ] [ \-\-verbose ] [ \-\-prefer\-texmf ] [ \-\-dry\-run ] [ \-\-formats=[+|\-]EXTENSIONS ] [ \-\-no\-compress ] [ \-\-no\-strip ] +[ \-\-local ] [ \-\-max\-fonts=N ] .TP .B \fBluaotfload\-tool\fP \-\-find=FONTNAME [ \-\-fuzzy ] [ \-\-info ] [ \-\-inspect ] [ \-\-no\-reload ] @@ -50,6 +51,8 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .sp \fBluaotfload\-tool\fP \-\-list=CRITERION[:VALUE] [ \-\-fields=F1,F2,...,Fn ] .sp +\fBluaotfload\-tool\fP \-\-bisect=DIRECTIVE +.sp \fBluaotfload\-tool\fP \-\-help .sp \fBluaotfload\-tool\fP \-\-version @@ -68,10 +71,6 @@ the \fILuaotfload\fP package. There are two general modes: \fBupdate\fP and .IP \(bu 2 \fBquery\fP: resolve a font name or display close matches. .UNINDENT -.sp -Note that if the script is named \fBmkluatexfontdb\fP it will behave like -earlier versions (<=1.3) and always update the database first. Also, -the verbosity level will be set to 2. .SH OPTIONS .SS update mode .INDENT 0.0 @@ -83,16 +82,19 @@ Update the database; indexes new fonts. Force rebuilding of the database; re\-indexes all fonts. .TP +.B \-\-local\fP,\fB \-L +Include font files in \fB$PWD\fP\&. This option +will cause large parts of the database to be +rebuilt. Thus it is quite inefficient. +Additionally, if local font files are found, +the database is prevented from being saved +to disk, so the local fonts need to be parsed +with every invocation of \fBluaotfload\-tool\fP\&. +.TP .B \-\-no\-reload\fP,\fB \-n Suppress auto\-updates to the database (e.g. when \fB\-\-find\fP is passed an unknown name). .TP -.B \-\-no\-strip -Do not strip redundant information after -building the database. Warning: this will -inflate the index to about two to three times -the normal size. -.TP .B \-\-no\-compress\fP,\fB \-c Do not filter the plain text version of the font index through gzip. Useful for debugging @@ -103,10 +105,6 @@ Organize the file name database in a way so that it prefer fonts in the \fITEXMF\fP tree over system fonts if they are installed in both. .TP -.BI \-\-max\-fonts\fB= N -Process at most \fIN\fP font files, including fonts -already indexed in the count. -.TP .BI \-\-formats\fB= EXTENSIONS Extensions of the font files to index. Where \fIEXTENSIONS\fP is a comma\-separated list of @@ -130,10 +128,6 @@ standard TeX Live installation this will grow the database considerably and slow down font indexing. .UNINDENT -.TP -.B \-\-dry\-run\fP,\fB \-D -Don’t load fonts, scan directories only. -(For debugging file system related issues.) .UNINDENT .SS query mode .INDENT 0.0 @@ -167,9 +161,6 @@ Print the warnings generated by the fontloader library (assumes \fB\-I\fP). Automatically enabled if the verbosity level exceeds 2. .TP -.B \-\-show\-blacklist\fP,\fB \-b -Show blacklisted files (not directories). -.TP .BI \-\-list\fB= CRITERION Show entries, where \fICRITERION\fP is one of the following: @@ -260,6 +251,84 @@ cache; \fBshow\fP \-> print stats. .UNINDENT .UNINDENT +.SS debugging methods +.INDENT 0.0 +.TP +.B \-\-show\-blacklist\fP,\fB \-b +Show blacklisted files (not directories). +.TP +.B \-\-dry\-run\fP,\fB \-D +Don’t load fonts when updating the database; +scan directories only. +(For debugging file system related issues.) +.TP +.B \-\-no\-strip +Do not strip redundant information after +building the database. Warning: this will +inflate the index to about two to three times +the normal size. +.TP +.BI \-\-max\-fonts\fB= N +Process at most \fIN\fP font files, including fonts +already indexed in the count. +.TP +.BI \-\-bisect\fB= DIRECTIVE +Bisection of the font database. +This mode is intended as assistance in +debugging the Luatex engine, especially when +tracking memleaks or buggy fonts. +.sp +\fIDIRECTIVE\fP can be one of the following: +.INDENT 7.0 +.IP 1. 3 +\fBrun\fP \-> Make \fBluaotfload\-tool\fP respect +the bisection progress when running. +Combined with \fB\-\-update\fP and possibly +\fB\-\-force\fP this will only process the files +from the start up until the pivot and ignore +the rest. +.IP 2. 3 +\fBstart\fP \-> Start bisection: create a +bisection state file and initialize the low, +high, and pivot indices. +.IP 3. 3 +\fBstop\fP \-> Terminate the current bisection +session by deleting the state file. +.IP 4. 3 +\fBgood\fP | \fBbad\fP \-> Mark the section +processed last as “good” or “bad”, +respectively. The next bisection step will +continue with the bad section. +.IP 5. 3 +\fBstatus\fP \-> Print status information about +the current bisection session. Hint: Use +with higher verbosity settings for more +output. +.UNINDENT +.sp +A bisection session is initiated by issuing the +\fBstart\fP directive. This sets the pivot to the +middle of the list of available font files. +Now run \fIluaotfload\-tool\fP with the \fB\-\-update\fP +flag set as well as \fB\-\-bisect=run\fP: only the +fonts up to the pivot will be considered. If +that task exhibited the issue you are tracking, +then tell Luaotfload using \fB\-\-bisect=bad\fP\&. +The next step of \fB\-\-bisect=run\fP will continue +bisection with the part of the files below the +pivot. +Likewise, issue \fB\-\-bisect=good\fP in order to +continue with the fonts above the pivot, +assuming the tested part of the list did not +trigger the bug. +.sp +Once the culprit font is tracked down, \fBgood\fP +or \fBbad\fP will have no effect anymore. \fBrun\fP +will always end up processing the single font +file that was left. +Use \fB\-\-bisect=stop\fP to clear the bisection +state. +.UNINDENT .SS miscellaneous .INDENT 0.0 .TP @@ -276,15 +345,16 @@ troubleshooting), where \fICHANNEL\fP can be .INDENT 7.0 .IP 1. 3 \fBstdout\fP \-> all output will be -dumped to the terminal; or +dumped to the terminal (default); or .IP 2. 3 \fBfile\fP \-> write to a file to the temporary directory (the name will be chosen -automatically (\fBexperimental!\fP). +automatically. .UNINDENT .TP .B \-\-version\fP,\fB \-V -Show version info of components and exit. +Show version numbers of components as well as +some basic information and exit. .TP .B \-\-help\fP,\fB \-h Show help message and exit. diff --git a/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf b/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf index ee830d8378d..39103c39cd8 100644 Binary files a/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf and b/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf differ diff --git a/Master/texmf-dist/doc/man/man5/luaotfload.conf.5 b/Master/texmf-dist/doc/man/man5/luaotfload.conf.5 new file mode 100644 index 00000000000..68d40eba01f --- /dev/null +++ b/Master/texmf-dist/doc/man/man5/luaotfload.conf.5 @@ -0,0 +1,545 @@ +.\" Man page generated from reStructuredText. +. +.TH LUAOTFLOAD.CONF 5 "2014-06-09" "2.5" "text processing" +.SH NAME +luaotfload.conf \- Luaotfload configuration file +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.SH SYNOPSIS +.INDENT 0.0 +.IP \(bu 2 +\fB\&./luaotfload{.conf,rc}\fP +.IP \(bu 2 +\fBXDG_CONFIG_HOME/luaotfload/luaotfload{.conf,rc}\fP +.IP \(bu 2 +\fB~/.luaotfloadrc\fP +.UNINDENT +.SH DESCRIPTION +.sp +The file \fBluaotfload.conf\fP contains configuration options for +\fILuaotfload\fP, a font loading and font management component for LuaTeX. +.SH EXAMPLE +.sp +A small Luaotfload configuration file with few customizations could +look as follows: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +[db] + formats = afm, pfa, pfb + compress = false + +[misc] + termwidth = 60 + +[run] + log\-level = 6 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +This will make Luaotfload ignore all font files except for PostScript +formats. NB: With a default Tex Live install the PS fonts will take +much longer to index than OpenType or TrueType ones. Also, an +uncompressed index file will be dumped which is going to be much larger +due to the huge amount of PostScript fonts indexed. The terminal width +is truncated to 60 characters which influences the verbose output +during indexing. Finally, the verbosity is increased greatly: each font +file being processed will be printed to the stdout on a separate line, +along with lots of other information. +.sp +To observe the difference in behavior, save above snippet to +\fB\&./luaotfload.conf\fP and update the font index: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +luaotfload \-\-update \-\-force +.ft P +.fi +.UNINDENT +.UNINDENT +.SH SYNTAX +.sp +The configuration file syntax follows the common INI format. For a more +detailed description please refer to the section “CONFIGURATION FILE” +of \fBgit\-config\fP(1). A brief list of rules is given below: +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +Blank lines and lines starting with a semicolon (\fB;\fP) are ignored. +.IP \(bu 2 +A configuration file is partitioned into sections that are declared +by specifying the section title in brackets on a separate line: +.INDENT 2.0 +.INDENT 3.5 +.sp +.nf +.ft C +[some\-section] +\&... section content ... +.ft P +.fi +.UNINDENT +.UNINDENT +.IP \(bu 2 +Sections consist of one or more variable assignments of the form +\fBvariable\-name = value\fP E. g.: +.INDENT 2.0 +.INDENT 3.5 +.sp +.nf +.ft C +[foo] + bar = baz + quux = xyzzy + ... +.ft P +.fi +.UNINDENT +.UNINDENT +.IP \(bu 2 +Section and variable names may contain only uppercase and lowercase +letters as well as dashes (\fB\-\fP). +.UNINDENT +.UNINDENT +.UNINDENT +.SH VARIABLES +.sp +Variables in belong into a configuration section and their values must +be of a certain type. Some of them have further constraints. For +example, the “color callback” must be a string of one of the values +\fBpre_linebreak_filter\fP or \fBpre_output_filter\fP, defined in the +section \fIrun\fP\&. +.sp +Currently, the configuration is organized into four sections: +.INDENT 0.0 +.TP +.B db +Options relating to the font index. +.TP +.B misc +Options without a clearly defined category. +.TP +.B paths +Path and file name settings. +.TP +.B run +Options controlling runtime behavior of Luaotfload. +.UNINDENT +.sp +The list of valid variables, the sections they are part of and their +type is given below. Types represent Lua types that the values must be +convertible to; they are abbreviated as follows: \fBs\fP for the \fIstring\fP +type, \fBn\fP for \fInumber\fP, \fBb\fP for \fIboolean\fP\&. A value of \fBnil\fP means +the variable is unset. +.SS Section \fBdb\fP +.TS +center; +|l|l|l|. +_ +T{ +variable +T} T{ +type +T} T{ +default +T} +_ +T{ +compress +T} T{ +b +T} T{ +\fBtrue\fP +T} +_ +T{ +formats +T} T{ +s +T} T{ +\fB"otf,ttf,ttc,dfont"\fP +T} +_ +T{ +max\-fonts +T} T{ +n +T} T{ +\fB2^51\fP +T} +_ +T{ +scan\-local +T} T{ +b +T} T{ +\fBfalse\fP +T} +_ +T{ +skip\-read +T} T{ +b +T} T{ +\fBfalse\fP +T} +_ +T{ +strip +T} T{ +b +T} T{ +\fBtrue\fP +T} +_ +T{ +update\-live +T} T{ +b +T} T{ +\fBtrue\fP +T} +_ +.TE +.sp +The flag \fBcompress\fP determines whether the font index (usually +\fBluaotfload\-names.lua[.gz]\fP will be stored in compressed forms. +If unset it is equivalent of passing \fB\-\-no\-compress\fP to +\fBluaotfload\-tool\fP\&. Since the file is only created for convenience +and has no effect on the runtime behavior of Luaotfload, the flag +should remain set. Most editors come with zlib support anyways. +.sp +The list of \fBformats\fP must be a comma separated sequence of strings +containing one or more of these elements: +.INDENT 0.0 +.IP \(bu 2 +\fBotf\fP (OpenType format), +.IP \(bu 2 +\fBttf\fP and \fBttc\fP (TrueType format), +.IP \(bu 2 +\fBdfont\fP (Macintosh TrueType format), +.IP \(bu 2 +\fBafm\fP (Adobe Font Metrics), +.IP \(bu 2 +\fBpfb\fP and \fBpfa\fP (PostScript format). +.UNINDENT +.sp +It corresponds loosely to the \fB\-\-formats\fP option to +\fBluaotfload\-tool\fP\&. Invalid or duplicate members are ignored; if the +list does not contain any useful identifiers, the default list +\fB"otf,ttf,ttc,dfont"\fP will be used. +.sp +The variable \fBmax\-fonts\fP determines after processing how many font +files the font scanner will terminate the search. This is useful for +debugging issues with the font index and has the same effect as the +option \fB\-\-max\-fonts\fP to \fBluaotfload\-tools\fP\&. +.sp +The \fBscan\-local\fP flag, if set, will incorporate the current working +directory as a font search location. NB: This will potentially slow +down document processing because a font index with local fonts will not +be saved to disk, so these fonts will have to be re\-indexed whenever +the document is built. +.sp +The \fBskip\-read\fP flag is only useful for debugging: It makes +Luaotfload skip reading fonts. The font information for rebuilding the +index is taken from the presently existing one. +.sp +Unsetting the \fBstrip\fP flag prevents Luaotfload from removing data +from the index that is only useful when processing font files. NB: this +can increase the size of the index files significantly and has no +effect on the runtime behavior. +.sp +If \fBupdate\-live\fP is set, Luaotfload will reload the database if it +cannot find a requested font. Those who prefer to update manually using +\fBluaotfload\-tool\fP should unset this flag. +.SS Section \fBdefault\-features\fP +.sp +By default Luaotfload enables \fBnode\fP mode and picks the default font +features that are prescribed in the OpenType standard. This behavior +may be overridden in the \fBdefault\-features\fP section. Global defaults +that will be applied for all scripts can be set via the \fBglobal\fP +option, others by the script they are to be applied to. For example, +a setting of +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +[default\-features] + global = mode=base,color=0000FF + dflt = smcp,onum +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +would force \fIbase\fP mode, tint all fonts blue and activate small +capitals and text figures globally. Features are specified as a comma +separated list of variables or variable\-value pairs. Variables without +an explicit value are set to \fBtrue\fP\&. +.SS Section \fBmisc\fP +.TS +center; +|l|l|l|. +_ +T{ +variable +T} T{ +type +T} T{ +default +T} +_ +T{ +statistics +T} T{ +b +T} T{ +\fBfalse\fP +T} +_ +T{ +termwidth +T} T{ +n +T} T{ +\fBnil\fP +T} +_ +T{ +version +T} T{ +s +T} T{ + +T} +_ +.TE +.sp +With \fBstatistics\fP enabled, extra statistics will be collected during +index creation and appended to the index file. It may then be queried +at the Lua end or inspected by reading the file itself. +.sp +The value of \fBtermwidth\fP, if set, overrides the value retrieved by +querying the properties of the terminal in which Luatex runs. This is +useful if the engine runs with \fBshell_escape\fP disabled and the actual +terminal dimensions cannot be retrieved. +.sp +The value of \fBversion\fP is derived from the version string hard\-coded +in the Luaotfload source. Override at your own risk. +.SS Section \fBpaths\fP +.TS +center; +|l|l|l|. +_ +T{ +variable +T} T{ +type +T} T{ +default +T} +_ +T{ +cache\-dir +T} T{ +s +T} T{ +\fB"fonts"\fP +T} +_ +T{ +names\-dir +T} T{ +s +T} T{ +\fB"names"\fP +T} +_ +T{ +index\-file +T} T{ +s +T} T{ +\fB"luaotfload\-names.lua"\fP +T} +_ +T{ +lookups\-file +T} T{ +s +T} T{ +\fB"luaotfload\-lookup\-cache.lua"\fP +T} +_ +.TE +.sp +The paths \fBcache\-dir\fP and \fBnames\-dir\fP determine the subdirectory +inside the Luaotfload subtree of the \fBluatex\-cache\fP directory where +the font cache and the font index will be stored, respectively. +.sp +Inside the index directory, the names of the index file and the font +lookup cache will be derived from the respective values of +\fBindex\-file\fP and \fBlookups\-file\fP\&. This is the filename base for the +bytecode compiled version as well as \-\- for the index \-\- the gzipped +version. +.SS Section \fBrun\fP +.TS +center; +|l|l|l|. +_ +T{ +variable +T} T{ +type +T} T{ +default +T} +_ +T{ +color\-callback +T} T{ +s +T} T{ +\fB"pre_linebreak_filter"\fP +T} +_ +T{ +definer +T} T{ +s +T} T{ +\fB"patch"\fP +T} +_ +T{ +log\-level +T} T{ +n +T} T{ +\fB0\fP +T} +_ +T{ +resolver +T} T{ +s +T} T{ +\fB"cached"\fP +T} +_ +.TE +.sp +The \fBcolor\-callback\fP option determines the stage at which fonts that +defined with a \fBcolor=xxyyzz\fP feature will be colorized. By default +this happens in a \fBpre_linebreak_filter\fP but alternatively the +\fBpre_output_filter\fP may be chosen, which is faster but might produce +inconsistent output. The latter also was the default in the 1.x series +of Luaotfload. +.sp +The \fBdefiner\fP allows for switching the \fBdefine_font\fP callback. +Apart from the default \fBpatch\fP one may also choose the \fBgeneric\fP +one that comes with the vanilla fontloader. Beware that this might +break tools like Fontspect that rely on the \fBpatch_font\fP callback +provided by Luaotfload to perform important corrections on font data. +.sp +The value of \fBlog\-level\fP sets the default verbosity of messages +printed by Luaotfload. Only messages defined with a verbosity of less +than or equal to the supplied value will be output on the terminal. +At a log level of five Luaotfload can be very noisy. Also, printing too +many messages will slow down the interpreter due to line buffering +being disabled (see \fBsetbuf\fP(3)). +.sp +The \fBresolver\fP setting allows choosing the font name resolution +function: With the default value \fBcached\fP Luaotfload saves the result +of a successful font name request to a cache file to speed up +subsequent lookups. The alternative, \fBnormal\fP circumvents the cache +and resolves every request individually. (Since to the restructuring of +the font name index in Luaotfload 2.4 the performance difference +between the cached and uncached lookups should be marginal.) +.SH FILES +.sp +Luaotfload only processes the first configuration file it encounters at +one of the search locations. The file name may be either +\fBluaotfload.conf\fP or \fBluaotfloadrc\fP, except for the dotfile in the +user’s home directory which is expected at \fB~/.luaotfloadrc\fP\&. +.sp +Configuration files are located following a series of steps. The search +terminates as soon as a suitable file is encountered. The sequence of +locations that Luaotfload looks at is +.INDENT 0.0 +.IP i. 5 +The current working directory of the LuaTeX process. +.IP ii. 5 +The subdirectory \fBluaotfload/\fP inside the XDG configuration +tree, e. g. \fB/home/oenothea/config/luaotfload/\fP\&. +.IP iii. 5 +The dotfile. +.IP iv. 5 +The \fITEXMF\fP (using kpathsea). +.UNINDENT +.SH SEE ALSO +.sp +\fBluaotfload\-tool\fP(1), \fBluatex\fP(1), \fBlua\fP(1) +.INDENT 0.0 +.IP \(bu 2 +\fBtexdoc luaotfload\fP to display the PDF manual for the \fILuaotfload\fP +package +.IP \(bu 2 +Luaotfload development \fI\%https://github.com/lualatex/luaotfload\fP +.IP \(bu 2 +LuaLaTeX mailing list \fI\%http://tug.org/pipermail/lualatex\-dev/\fP +.IP \(bu 2 +LuaTeX \fI\%http://luatex.org/\fP +.IP \(bu 2 +Luaotfload on CTAN \fI\%http://ctan.org/pkg/luaotfload\fP +.UNINDENT +.SH REFERENCES +.INDENT 0.0 +.IP \(bu 2 +The XDG base specification +\fI\%http://standards.freedesktop.org/basedir\-spec/basedir\-spec\-latest.html\fP\&. +.UNINDENT +.SH AUTHORS +.sp +\fILuaotfload\fP is maintained by the LuaLaTeX dev team +(\fI\%https://github.com/lualatex/\fP). +.sp +This manual page was written by Philipp Gesang +<\fI\%philipp.gesang@alumni.uni\-heidelberg.de\fP>. +.SH COPYRIGHT +GPL v2.0 +.\" Generated by docutils manpage writer. +. diff --git a/Master/texmf-dist/scripts/luaotfload/luaotfload-legacy-tool.lua b/Master/texmf-dist/scripts/luaotfload/luaotfload-legacy-tool.lua deleted file mode 100755 index 30ab13b6e3a..00000000000 --- a/Master/texmf-dist/scripts/luaotfload/luaotfload-legacy-tool.lua +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env texlua ---[[ -This file is copyright 2010 Elie Roux and Khaled Hosny and is under CC0 -license (see http://creativecommons.org/publicdomain/zero/1.0/legalcode). - -This file is a wrapper for the luaotfload's font names module. It is part of the -luaotfload bundle, please see the luaotfload documentation for more info. ---]] - -kpse.set_program_name("luatex") - -require("lualibs") ---> current -require("luaotfload-legacy-database") ---> old -require("alt_getopt") ---> ? - -local name = "mkluatexfontdb" -local version = "1.31 (legacy)" - -local names = fonts.names - -local function help_msg() - texio.write(string.format([[ -Usage: %s [OPTION]... - -================================================================================ - please update your luatex binary - this version is unsupported and likely to break things -================================================================================ - -Rebuild the LuaTeX font database. - -Valid options: - -f --force force re-indexing all fonts - -q --quiet don't output anything - -v --verbose=LEVEL be more verbose (print the searched directories) - -vv print the loaded fonts - -vvv print all steps of directory searching - -V --version print version and exit - -h --help print this message - -The output database file is named otfl-names.lua and is placed under: - - %s - -contact: https://github.com/lualatex/luaotfload - -]], name, names.path.localdir)) -end - -local function version_msg() - texio.write(string.format( - "%s version %s, database version %s.\n", name, version, names.version)) -end - ---[[ -Command-line processing. -Here we fill cmdargs with the good values, and then analyze it. ---]] - -local long_opts = { - force = "f", - quiet = "q", - help = "h", - verbose = 1 , - version = "V", -} - -local short_opts = "fqpvVh" - -local force_reload = nil - -local function process_cmdline() - local opts, optind, optarg = alt_getopt.get_ordered_opts (arg, short_opts, long_opts) - local log_level = 1 - for i,v in ipairs(opts) do - if v == "q" then - log_level = 0 - elseif v == "v" then - if log_level > 0 then - log_level = log_level + 1 - else - log_level = 2 - end - elseif v == "V" then - version_msg() - os.exit(0) - elseif v == "h" then - help_msg() - os.exit(0) - elseif v == "f" then - force_reload = 1 - end - end - names.set_log_level(log_level) -end - -local function generate(force) - local fontnames, saved - fontnames = names.update(fontnames, force) - logs.report("%s fonts in the database", #fontnames.mappings) - saved = names.save(fontnames) -end - -process_cmdline() -generate(force_reload) diff --git a/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua b/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua index 5607c045039..4c5550891b2 100755 --- a/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua +++ b/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua @@ -2,17 +2,22 @@ ----------------------------------------------------------------------- -- FILE: luaotfload-tool.lua -- DESCRIPTION: database functionality --- REQUIREMENTS: luaotfload 2.4 +-- REQUIREMENTS: luaotfload 2.5 -- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang --- VERSION: 2.4-4 --- LICENSE: GPL v2 --- MODIFIED: 2013-07-28 13:12:04+0200 +-- VERSION: 2.5 +-- LICENSE: GPL v2.0 +-- MODIFIED: 2014-05-15 21:47:39+0200 ----------------------------------------------------------------------- -local version = "2.4-4" --- . +luaotfload = luaotfload or { } +local version = "2.5" --- .- +luaotfload.version = version +luaotfload.self = "luaotfload-tool" --[[doc-- +luaotfload-tool(1) + This file was originally written (as \fileent{mkluatexfontdb.lua}) by Elie Roux and Khaled Hosny and, as a derived work of ConTeXt, is provided under the terms of the GPL v2.0 license as printed in full @@ -33,17 +38,16 @@ kpse.set_program_name "luatex" --[[doc-- We test for Lua 5.1 by means of capability detection to see if - we’re running an outdated Luatex. If so, we hand over control to - the legacy db runner. + we’re running an outdated Luatex. If so, we bail. \url{http://lua-users.org/wiki/LuaVersionCompatibility} --doc]]-- -local ioopen = io.open local iowrite = io.write local kpsefind_file = kpse.find_file +local mathfloor = math.floor local next = next local osdate = os.date local ostype = os.type @@ -63,8 +67,10 @@ if _G.getfenv ~= nil then -- 5.1 or LJ runtime = { "jit", jit.version } else runtime = { "stock", _VERSION } - local oldscript = kpsefind_file "luaotfload-legacy-tool.lua" - return require (oldscript) + print "FATAL ERROR" + print "Luaotfload requires a Luatex version >=0.76." + print "Please update your TeX distribution!" + os.exit (-1) end else -- 5.2 runtime = { "stock", _VERSION } @@ -83,56 +89,19 @@ string.quoted = string.quoted or function (str) return string.format("%q",str) end -require(loader_path) +require (loader_path) --[[doc-- -Depending on how the script is called we change its behavior. -For backwards compatibility, moving or symlinking the script to a -file name starting with \fileent{mkluatexfontdb} will cause it to -trigger a database update on every run. -Running as \fileent{luaotfload-tool} -- the new name -- will do this upon -request only. - -There are two naming conventions followed here: firstly that of -utilities such as \fileent{mktexpk}, \fileent{mktexlsr} and the likes, -and secondly that of \fileent{fmtutil}. -After support for querying the database was added, the latter appeared -to be the more appropriate. ---doc]]-- -config = config or { } -local config = config -local luaotfloadconfig = config.luaotfload or { } -config.luaotfload = luaotfloadconfig -luaotfloadconfig.version = luaotfloadconfig.version or version -luaotfloadconfig.names_dir = luaotfloadconfig.names_dir or "names" -luaotfloadconfig.cache_dir = luaotfloadconfig.cache_dir or "fonts" -luaotfloadconfig.index_file = luaotfloadconfig.index_file - or "luaotfload-names.lua" -luaotfloadconfig.formats = luaotfloadconfig.formats - or "otf,ttf,ttc,dfont" -luaotfloadconfig.reload = false -if not luaotfloadconfig.strip then - luaotfloadconfig.strip = true -end + XXX: + Creating the config table will be moved to the common + initialization when the times comes. -do -- we don’t have file.basename and the likes yet, so inline parser ftw - local slash = P"/" - local dot = P"." - local noslash = 1 - slash - local slashes = slash^1 - local path = slashes^-1 * (noslash^1 * slashes)^1 - local thename = (1 - slash - dot)^1 - local extension = dot * (1 - slash - dot)^1 - local p_basename = path^-1 * C(thename) * extension^-1 * P(-1) - - local self = lpegmatch(p_basename, stringlower(arg[0])) - if self == "luaotfload-tool" then - luaotfloadconfig.self = "luaotfload-tool" - else - luaotfloadconfig.self = "mkluatexfontdb" - end -end +--doc]]-- + +config = config or { } +local config = config +config.luaotfload = config.luaotfload or { } config.lualibs = config.lualibs or { } config.lualibs.verbose = false @@ -140,8 +109,13 @@ config.lualibs.prefer_merged = true config.lualibs.load_extended = true require "lualibs" -local tabletohash = table.tohash +local iosavedata = io.savedata +local lfsisdir = lfs.isdir +local lfsisfile = lfs.isfile local stringsplit = string.split +local tableserialize = table.serialize +local tablesortedkeys = table.sortedkeys +local tabletohash = table.tohash --[[doc-- \fileent{luatex-basics-gen.lua} calls functions from the @@ -169,22 +143,17 @@ require"luaotfload-basics-gen.lua" texio.write, texio.write_nl = backup.write, backup.write_nl utilities = backup.utilities -require"luaotfload-override.lua" --- this populates the logs.* namespace -require"luaotfload-database" -require"alt_getopt" - -local names = fonts.names - -local status_file = "luaotfload-status" -local luaotfloadstatus = require (status_file) -luaotfloadconfig.status = luaotfloadstatus +require "luaotfload-log.lua" --- this populates the luaotfload.log.* namespace +require "luaotfload-parsers" --- fonts.conf, configuration, and request syntax +require "luaotfload-configuration" --- configuration file handling +require "luaotfload-database" +require "alt_getopt" +local names = fonts.names local sanitize_fontname = names.sanitize_fontname -local pathdata = names.path -local names_plain = pathdata.index.lua -local names_gzip = names_plain .. ".gz" -local names_bin = pathdata.index.luc +local log = luaotfload.log +local report = log.report local help_messages = { ["luaotfload-tool"] = [[ @@ -211,9 +180,6 @@ Usage: %s [OPTIONS...] "environment", "index", "permissions", or "repository" - --alias= force behavior of "luaotfload-tool" or legacy - "mkluatexfontdb" - ------------------------------------------------------------------------------- DATABASE @@ -221,6 +187,7 @@ Usage: %s [OPTIONS...] -n --no-reload suppress db update --no-strip keep redundant information in db -f --force force re-indexing all fonts + -L --local scan font files in $PWD -c --no-compress do not gzip index file (text version only) -l --flush-lookups empty lookup cache of font requests -D --dry-run skip loading of fonts, just scan @@ -243,6 +210,10 @@ Usage: %s [OPTIONS...] --fields=,,…, which fields to print with --list -b --show-blacklist show blacklisted files + --bisect= control database bisection: valid + directives are "start", "stop", "run", "status", + "good", "bad" + The font database will be saved to %s %s @@ -258,49 +229,37 @@ The font cache will be written to ]], mkluatexfontdb = [[ - -Usage: %s [OPTION]... - -Rebuild or update the Luaotfload font names database. - -Valid options: - -f --force force re-indexing all fonts - -q --quiet don't output anything - -v --verbose=LEVEL be more verbose (print the searched directories) - -vv print the loaded fonts - -vvv print all steps of directory searching - -V --version print version and exit - -h --help print this message - --alias= force behavior of "luaotfload-tool" or legacy - "mkluatexfontdb" - -The font database will be saved to - %s - %s - +FATAL ERROR +As of Luaotfload v2.5, legacy behavior is not supported anymore. Please +update your scripts and/or habits! Kthxbye. ]], short = [[ Usage: luaotfload-tool [--help] [--version] [--verbose=] - [--update] [--force] [--prefer-texmf] + [--update] [--force] [--prefer-texmf] [--local] [--dry-run] [--formats=] [--find=] [--fuzzy] [--info] [--inspect] [--list=] [--fields=] [--cache=] [--flush-lookups] [--show-blacklist] [--diagnose=] + [--no-compress] [--no-strip] [--local] + [--max-fonts=] [--bisect=] Enter 'luaotfload-tool --help' for a larger list of options. ]] } local help_msg = function (version) - local template = help_messages[version] + local template = help_messages[version] + local paths = config.luaotfload.paths + local names_plain = paths.index_path_lua + local names_gzip = names_plain .. ".gz" + local names_bin = paths.index_path_luc + iowrite(stringformat(template, - luaotfloadconfig.self, --- names_plain, + luaotfload.self, names_gzip, names_bin, - caches.getwritablepath ( - luaotfloadconfig.cache_dir))) + caches.getwritablepath (config.luaotfload.cache_dir))) end local about = [[ @@ -311,16 +270,28 @@ local about = [[ ]] local version_msg = function ( ) - local out = function (...) texiowrite_nl (stringformat (...)) end - out (about, luaotfloadconfig.self) - out ("%s version %q", luaotfloadconfig.self, version) - out ("revision %q", luaotfloadstatus.notes.revision) - out ("database version %q", names.version) + local out = function (...) texiowrite_nl (stringformat (...)) end + local uname = os.uname () + local meta = names.getmetadata () + out (about, luaotfload.self) + out ("%s version: %q", luaotfload.self, version) + out ("Revision: %q", config.luaotfload.status.notes.revision) out ("Lua interpreter: %s; version %q", runtime[1], runtime[2]) - out ("Luatex SVN revision %d", status.luatex_svn) - out ("Luatex version %.2f.%d", + out ("Luatex SVN revision: %d", status.luatex_svn) + out ("Luatex version: %.2f.%d", status.luatex_version / 100, status.luatex_revision) + out ("Platform: type=%s name=%s", os.type, os.name) + + local uname_vars = tablesortedkeys (uname) + for i = 1, #uname_vars do + local var = uname_vars[i] + out (" + %8s: %s", var, uname[var]) + end + out ("Index: version=%q created=%q modified=%q", + config.luaotfload.status.notes.revision, + meta.created or "ages ago", + meta.modified or "ages ago") out "" end @@ -332,7 +303,7 @@ local head_adornchars = { } local textwidth = 80 -local wd_leftcolumn = math.floor(textwidth * .25) +local wd_leftcolumn = mathfloor(textwidth * .25) local key_fmt = stringformat([[%%%ds]], wd_leftcolumn) local val_fmt = [[%s]] local fieldseparator = ":" @@ -380,15 +351,36 @@ local print_heading = function (title, level) texiowrite_nl (s .. stringrep(adornchar, textwidth-utf.len(s))) end +local baseindent = " " + +--[[doc-- + + show_info_items -- Together with show_info_table prints the table returned by + fontloader.info(), recursing into nested tables if appropriate (as necessitated + by Luatex versions 0.78+ which include the pfminfo table in the result. + +--doc]]-- + +local show_info_table show_info_table = function (t, depth) + depth = depth or 0 + local indent = stringrep (baseindent, depth) + local keys = tablesortedkeys (t) + for n = 1, #keys do + local key = keys [n] + local val = t [key] + if type (val) == "table" then + texiowrite_nl (indent .. stringformat (info_fmt, key, "
")) + show_info_table (val, depth + 1) + else + texiowrite_nl (indent .. stringformat (info_fmt, key, val)) + end + end +end + local show_info_items = function (fontinfo) - local items = table.sortedkeys(fontinfo) - print_heading(fontinfo.fullname, 1) + print_heading (fontinfo.fullname, 1) texiowrite_nl "" - for n = 1, #items do - local item = items[n] - texiowrite_nl(stringformat( - info_fmt, item, fontinfo[item])) - end + show_info_table (fontinfo) texiowrite_nl "" end @@ -707,9 +699,9 @@ local show_font_info = function (basename, askedname, detail, warnings) if nfonts > 0 then -- true type collection local subfont if askedname then - logs.names_report(true, 1, "resolve", - [[%s is part of the font collection %s]], - askedname, basename) + report (true, 1, "resolve", + [[%s is part of the font collection %s]], + askedname, basename) subfont = subfont_by_name(shortinfo, askedname) end if subfont then @@ -718,11 +710,11 @@ local show_font_info = function (basename, askedname, detail, warnings) show_full_info(fullname, subfont, warnings) end else -- list all subfonts - logs.names_report(true, 1, "resolve", - [[%s is a font collection]], basename) + report (true, 1, "resolve", + [[%s is a font collection]], basename) for subfont = 1, nfonts do - logs.names_report(true, 1, "resolve", - [[Showing info for font no. %d]], n) + report (true, 1, "resolve", + [[Showing info for font no. %d]], n) show_info_items(shortinfo[subfont]) if detail == true then show_full_info(fullname, subfont, warnings) @@ -736,8 +728,7 @@ local show_font_info = function (basename, askedname, detail, warnings) end end else - logs.names_report(true, 1, "resolve", - "Font %s not found", filename) + report (true, 1, "resolve", "Font %s not found", filename) end end @@ -748,23 +739,40 @@ set. --]]-- local action_sequence = { - "loglevel", "help", "version", "diagnose", - "blacklist", "cache", "flush", "generate", - "list", "query", + "config", "loglevel", "help", "version", + "diagnose", "blacklist", "cache", "flush", + "bisect", "generate", "list", "query", } local action_pending = tabletohash(action_sequence, false) +action_pending.config = true --- always read the configuration action_pending.loglevel = true --- always set the loglevel action_pending.generate = false --- this is the default action local actions = { } --- (jobspec -> (bool * bool)) list actions.loglevel = function (job) - logs.set_loglevel(job.log_level) - logs.names_report("info", 3, "util", - "Setting log level", "%d", job.log_level) - logs.names_report("log", 2, "util", "Lua=%s", _VERSION) + local lvl = job.log_level + if lvl then + log.set_loglevel(lvl) + report ("info", 3, "util", "Setting the log level to %d.", lvl) + report ("log", 2, "util", "Lua=%q", _VERSION) + end + return true, true +end + +actions.config = function (job) + local defaults = luaotfload.default_config + local vars = config.actions.read (job.extra_config) + config.luaotfload = config.actions.apply (defaults, vars) + config.luaotfload = config.actions.apply (config.luaotfload, job.config) + + --inspect(config.luaotfload) + --os.exit() + if not config.actions.reconfigure () then + return false, false + end return true, true end @@ -781,29 +789,322 @@ end actions.blacklist = function (job) names.read_blacklist() local n = 0 - for n, entry in next, table.sortedkeys(names.blacklist) do + for n, entry in next, tablesortedkeys(names.blacklist) do iowrite (stringformat("(%d %s)\n", n, entry)) end return true, false end actions.generate = function (job) - local fontnames, savedname - fontnames = names.update(fontnames, job.force_reload, job.dry_run) - logs.names_report("info", 2, "db", - "Fonts in the database: %i", #fontnames.mappings) - if names.data() then + local _ = names.update (fontnames, job.force_reload, job.dry_run) + local namedata = names.data () + if namedata then + report ("info", 2, "db", "Fonts in the database: %i", #namedata.mappings) return true, true end return false, false end +------------------------------------------------------------------------------- +--- bisect mode +------------------------------------------------------------------------------- + +local bisect_status_path = caches.getwritablepath "bisect" +local bisect_status_file = bisect_status_path .."/" .. "luaotfload-bisect-status.lua" +local bisect_status_fmt = [[ +--[==[------------------------------------------------------------------------- + This file is generated by Luaotfload. It can be safely deleted. + Creation date: %s. +-------------------------------------------------------------------------]==]-- + +%s + +--- vim:ft=lua:ts=8:et:sw=2 +]] + +--[[doc-- + + write_bisect_status -- Write the history of the current bisection to disk. + +--doc]]-- + +--- state list -> bool +local write_bisect_status = function (data) + local payload = tableserialize (data, true) + local status = stringformat (bisect_status_fmt, + osdate ("%Y-%m-d %H:%M:%S", os.time ()), + payload) + if status and iosavedata (bisect_status_file, status) then + report ("info", 4, "bisect", + "Bisection state written to %s.", bisect_status_file) + return true + end + report ("info", 0, "bisect", + "Failed to write bisection state to %s.", bisect_status_file) + return false +end + +--[[doc-- + + read_bisect_status -- Read the bisect log from disk. + +--doc]]-- + +--- unit -> state list +local read_bisect_status = function () + report ("info", 4, "bisect", "Testing for status file: %q.", bisect_status_file) + if not lfsisfile (bisect_status_file) then + report ("info", 2, "bisect", "No such file: %q.", bisect_status_file) + report ("info", 0, "bisect", "Not in bisect mode.") + return false + end + report ("info", 4, "bisect", "Reading status file: %q.", bisect_status_file) + local success, status = pcall (dofile, bisect_status_file) + if not success then + report ("info", 0, "bisect", "Could not read status file.") + return false + end + return status +end + +--[[doc-- + + bisect_start -- Begin a bisect session. Determines the number of + fonts and sets the initial high, low, and pivot values. + +--doc]]-- + +local bisect_start = function () + if lfsisfile (bisect_status_file) then + report ("info", 0, "bisect", + "Bisect session in progress.", + bisect_status_file) + report ("info", 0, "bisect", + "Use --bisect=stop to erase it before starting over.") + return false, false + end + report ("info", 2, "bisect", + "Starting bisection of font database %q.", bisect_status_file) + local n = names.count_font_files () + local pivot = mathfloor (n / 2) + local data = { { 1, n, pivot } } + report ("info", 0, "bisect", "Initializing pivot to %d.", pivot) + if write_bisect_status (data) then + return true, false + end + return false, false +end + +--[[doc-- + + bisect_stop -- Terminate bisection session by removing all state info. + +--doc]]-- + +local bisect_stop = function () + report ("info", 3, "bisect", "Erasing bisection state at %s.", bisect_status_file) + if lfsisfile (bisect_status_file) then + local success, msg = os.remove (bisect_status_file) + if not success then + report ("info", 2, "bisect", + "Failed to erase file %s (%s).", + bisect_status_file, msg) + end + end + if lfsisdir (bisect_status_path) then + local success, msg = os.remove (bisect_status_path) + if not success then + report ("info", 2, "bisect", + "Failed to erase directory %s (%s).", + bisect_status_path, msg) + end + end + if lfsisfile (bisect_status_file) then + return false, false + end + return true, false +end + +--[[doc-- + + bisect_terminate -- Wrap up a bisect session by printing the + offending font and removing the state file. + +--doc]]-- + +local bisect_terminate = function (nsteps, culprit) + report ("info", 1, "bisect", + "Bisection completed after %d steps.", nsteps) + report ("info", 0, "bisect", + "Bad file: %s.", names.nth_font_filename (culprit)) + report ("info", 0, "bisect", + "Run with --bisect=stop to finish bisection.") + return true, false +end + +--[[doc-- + + list_remainder -- Show remaining fonts in bisect slice. + +--doc]]-- + +local list_remainder = function (lo, hi) + local fonts = names.font_slice (lo, hi) + report ("info", 0, "bisect", "%d fonts left.", hi - lo + 1) + for i = 1, #fonts do + report ("info", 1, "bisect", " · %2d: %s", lo, fonts[i]) + lo = lo + 1 + end +end + +--[[doc-- + + bisect_set -- Prepare the next bisection step by setting high, low, + and pivot to new values. + + The “run” directive always picks the segment below the pivot so we + can rely on the “outcome parameter” to be referring to that. + +--doc]]-- + +local bisect_set = function (outcome) + local status = read_bisect_status () + if not status then + return false, false + end + + local nsteps = #status + local previous = status[nsteps] + if previous == true then + --- Bisection already completed; we exit early through + --- bisect_terminate() to avoid further writes to the + --- state files that mess up step counting. + nsteps = nsteps - 1 + return bisect_terminate (nsteps, status[nsteps][1]) + end + + local lo, hi, pivot = unpack (previous) + + report ("info", 3, "bisect", "Previous step %d: lo=%d, hi=%d, pivot=%d.", + nsteps, lo, hi, pivot) + + if outcome == "bad" then + hi = pivot + if lo >= hi then --- complete + status[nsteps + 1] = { lo, lo, lo } + status[nsteps + 2] = true + write_bisect_status (status) + return bisect_terminate (nsteps, lo) + end + pivot = mathfloor ((lo + hi) / 2) + report ("info", 0, "bisect", + "Continuing with the lower segment: lo=%d, hi=%d, pivot=%d.", + lo, hi, pivot) + elseif outcome == "good" then + lo = pivot + 1 + if lo >= hi then --- complete + status[nsteps + 1] = { lo, lo, lo } + write_bisect_status (status) + status[nsteps + 2] = true + return bisect_terminate (nsteps, lo) + end + pivot = mathfloor ((lo + hi) / 2) + report ("info", 0, "bisect", + "Continuing with the upper segment: lo=%d, hi=%d, pivot=%d.", + lo, hi, pivot) + else -- can’t happen + report ("info", 0, "bisect", "What the hell?", lo, hi, pivot) + return false, false + end + + status[nsteps + 1] = { lo, hi, pivot } + write_bisect_status (status) + if hi - lo <= 10 then + list_remainder (lo, hi) + end + return true, false +end + +--[[doc-- + + bisect_status -- Output information about the current bisect session. + +--doc]]-- + +local bisect_status = function () + local status = read_bisect_status () + if not status then + return false, false + end + local nsteps = #status + if nsteps > 1 then + for i = nsteps - 1, 1, -1 do + local step = status[i] + report ("info", 2, "bisect", "Step %d: lo=%d, hi=%d, pivot=%d.", + i, unpack (step)) + end + end + local current = status[nsteps] + report ("info", 0, "bisect", "Step %d: lo=%d, hi=%d, pivot=%d.", + nsteps, unpack (current)) + return true, false +end + +--[[doc-- + + bisect_run -- Run Luaotfload utilizing the current bisection state. + This should be combined with the --update mode, possibly with the + --force option. + + Luaotfload always tests the segment below the pivot first. + +--doc]]-- + +local bisect_run = function () + local status = read_bisect_status () + if not status then + return false, false + end + local nsteps = #status + local currentstep = nsteps + 1 + local current = status[nsteps] + if current == true then -- final step + current = status[nsteps - 1] + end + local lo, hi, pivot = unpack (current) + report ("info", 3, "bisect", "Previous step %d: lo=%d, hi=%d, pivot=%d.", + nsteps, lo, hi, pivot) + report ("info", 1, "bisect", "Step %d: Testing fonts from %d to %d.", + currentstep, lo, pivot) + config.luaotfload.misc.bisect = { lo, pivot } + return true, true +end + +local bisect_modes = { + start = bisect_start, + good = function () return bisect_set "good" end, + bad = function () return bisect_set "bad" end, + stop = bisect_stop, + status = bisect_status, + run = bisect_run, +} + +actions.bisect = function (job) + local mode = job.bisect + local runner = bisect_modes[mode] + if not runner then + report ("info", 0, "bisect", "Unknown directive %q.", mode) + return false, false + end + return runner (job) +end + actions.flush = function (job) - local success, lookups = names.flush_lookup_cache() + local success = names.flush_lookup_cache() if success then local success = names.save_lookups() if success then - logs.names_report("info", 2, "cache", "Lookup cache emptied") + report ("info", 2, "cache", "Lookup cache emptied") return true, true end end @@ -819,8 +1120,8 @@ local cache_directives = { actions.cache = function (job) local directive = cache_directives[job.cache] if not directive or type(directive) ~= "function" then - logs.names_report("info", 2, "cache", - "Invalid font cache directive %s.", job.cache) + report ("info", 2, "cache", + "Invalid font cache directive %s.", job.cache) return false, false end if directive() then @@ -856,36 +1157,35 @@ actions.query = function (job) then foundname, subfont = names.resolve_name (tmpspec) if foundname then - foundname, _, success = names.crude_file_lookup (foundname) + foundname, _, success = names.font_file_lookup (foundname) end elseif tmpspec.lookup == "file" then foundname, _, success = - names.crude_file_lookup (tmpspec.name) + names.font_file_lookup (tmpspec.name) end if success then - logs.names_report(false, 0, - "resolve", "Font %q found!", query) + report (false, 0, "resolve", "Font %q found!", query) if subfont then - logs.names_report(false, 0, "resolve", - "Resolved file name %q, subfont nr. %q", + report (false, 0, "resolve", + "Resolved file name %q, subfont nr. %q", foundname, subfont) else - logs.names_report(false, 0, "resolve", - "Resolved file name %q", foundname) + report (false, 0, "resolve", + "Resolved file name %q", foundname) end if job.show_info then show_font_info (foundname, query, job.full_info, job.warnings) iowrite "\n" end else - logs.names_report(false, 0, - "resolve", "Cannot find %q in index.", query) - logs.names_report(false, 0, - "resolve", "Hint: use the --fuzzy option to display suggestions.", query) + report (false, 0, "resolve", "Cannot find %q in index.", query) + report (false, 0, "resolve", + "Hint: use the --fuzzy option to display suggestions.", + query) if job.fuzzy == true then - logs.names_report(false, 0, - "resolve", "Looking for close matches, this may take a while ...") + report (false, 0, "resolve", + "Looking for close matches, this may take a while ...") local _success = names.find_closest(query, job.fuzzy_limit) end end @@ -959,7 +1259,7 @@ set_primary_field = function (fields, addme, acc, n) return acc end -local splitcomma = names.patterns.splitcomma +local splitcomma = luaotfload.parsers.splitcomma actions.list = function (job) local criterion = job.criterion @@ -983,7 +1283,7 @@ actions.list = function (job) local nmappings = #mappings if criterion == "*" then - logs.names_report(false, 1, "list", "All %d entries", nmappings) + report (false, 1, "list", "All %d entries", nmappings) for i=1, nmappings do local entry = mappings[i] local fields = get_fields(entry, asked_fields) @@ -998,12 +1298,12 @@ actions.list = function (job) criterion = criterion[1] asked_fields = set_primary_field(asked_fields, criterion) - logs.names_report(false, 1, "list", "By %s", criterion) + report (false, 1, "list", "By %s", criterion) --- firstly, build a list of fonts to operate on local targets = { } if asked_value then --- only those whose value matches - logs.names_report(false, 2, "list", "Restricting to value %s", asked_value) + report (false, 2, "list", "Restricting to value %s", asked_value) for i=1, nmappings do local entry = mappings[i] if entry[criterion] @@ -1048,7 +1348,7 @@ actions.list = function (job) end end local ntargets = #targets - logs.names_report(false, 2, "list", "%d entries", ntargets) + report (false, 2, "list", "%d entries", ntargets) --- now, output the collection for i=1, ntargets do @@ -1088,7 +1388,7 @@ end --[[-- Command-line processing. -mkluatexfontdb.lua relies on the script alt_getopt to process argv and +luaotfload-tool relies on the script alt_getopt to process argv and analyzes its output. TODO with extended lualibs we have the functionality from the @@ -1103,13 +1403,15 @@ local process_cmdline = function ( ) -- unit -> jobspec warnings = false, criterion = "", query = "", - log_level = 0, --- 2 is approx. the old behavior + log_level = nil, + bisect = nil, + config = { db = { }, misc = { }, run = { }, paths = { } }, } local long_options = { - alias = 1, + ["bisect"] = 1, cache = 1, - ["no-compress"] = "c", + conf = 1, diagnose = 1, ["dry-run"] = "D", ["flush-lookups"] = "l", @@ -1123,12 +1425,15 @@ local process_cmdline = function ( ) -- unit -> jobspec inspect = "I", limit = 1, list = 1, + ["local"] = "L", log = 1, ["max-fonts"] = 1, + ["no-compress"] = "c", ["no-reload"] = "n", ["no-strip"] = 0, ["skip-read"] = "R", ["prefer-texmf"] = "p", + ["print-conf"] = 0, quiet = "q", ["show-blacklist"] = "b", stats = "S", @@ -1138,7 +1443,7 @@ local process_cmdline = function ( ) -- unit -> jobspec warnings = "w", } - local short_options = "bcDfFiIlnpqRSuvVhw" + local short_options = "bcDfFiIlLnpqRSuvVhw" local options, _, optarg = alt_getopt.get_ordered_opts (arg, short_options, long_options) @@ -1151,11 +1456,13 @@ local process_cmdline = function ( ) -- unit -> jobspec elseif v == "u" then action_pending["generate"] = true elseif v == "v" then - if result.log_level > 0 then - result.log_level = result.log_level + 1 + local lvl = result.log_level + if not lvl or lvl < 1 then + lvl = 1 else - result.log_level = 1 + lvl = lvl + 1 end + result.log_level = lvl elseif v == "V" then action_pending["version"] = true elseif v == "h" then @@ -1177,7 +1484,7 @@ local process_cmdline = function ( ) -- unit -> jobspec elseif v == "log" then local str = optarg[n] if str then - finalizers = logs.set_logout(str, finalizers) + finalizers = log.set_logout(str, finalizers) end elseif v == "find" then action_pending["query"] = true @@ -1194,10 +1501,11 @@ local process_cmdline = function ( ) -- unit -> jobspec elseif v == "I" then result.show_info = true result.full_info = true - elseif v == "alias" then - luaotfloadconfig.self = optarg[n] elseif v == "l" then action_pending["flush"] = true + elseif v == "L" then + action_pending["generate"] = true + result.config.db.scan_local = true elseif v == "list" then action_pending["list"] = true result.criterion = optarg[n] @@ -1218,35 +1526,46 @@ local process_cmdline = function ( ) -- unit -> jobspec action_pending["diagnose"] = true result.asked_diagnostics = optarg[n] elseif v == "formats" then - names.set_font_filter (optarg[n]) + result.config.db.formats = optarg[n] + --names.set_font_filter (optarg[n]) elseif v == "n" then - luaotfloadconfig.update_live = false + result.config.db.update_live = false elseif v == "S" then - luaotfloadconfig.statistics = true + result.config.misc.statistics = true elseif v == "R" then --- dev only, undocumented - luaotfloadconfig.skip_read = true + result.config.db.skip_read = true elseif v == "c" then - luaotfloadconfig.compress = false + result.config.db.compress = false elseif v == "no-strip" then - luaotfloadconfig.strip = false + result.config.db.strip = false elseif v == "max-fonts" then local n = optarg[n] if n then n = tonumber(n) if n and n > 0 then - luaotfloadconfig.max_fonts = n + result.config.db.max_fonts = n end end + elseif v == "bisect" then + result.bisect = optarg[n] + action_pending.bisect = true + elseif v == "conf" then + local extra = stringexplode (optarg[n], ",+") + if extra then + local extra_config = result.extra_config + if extra_config then + table.append (extra_config, extra) + else + result.extra_config = extra + end + end + elseif v == "print-conf" then + result.print_config = true end end - if luaotfloadconfig.self == "mkluatexfontdb" then --- TODO drop legacy ballast after 2.4 - result.help_version = "mkluatexfontdb" - action_pending["generate"] = true - result.log_level = math.max(1, result.log_level) - logs.set_logout("stdout", finalizers) - elseif nopts == 0 then + if nopts == 0 then action_pending["help"] = true result.help_version = "short" end @@ -1264,24 +1583,23 @@ local main = function ( ) -- unit -> int local actionname = action_sequence[i] local exit = false if action_pending[actionname] then - logs.names_report("log", 3, "util", "Preparing for task", - "%s", actionname) + report ("log", 3, "util", "Preparing for task", "%s", actionname) local action = actions[actionname] local success, continue = action(job) if not success then - logs.names_report(false, 0, "util", - "Could not finish task", "%s", actionname) + report (false, 0, "util", + "Failed to execute task.", "%s", actionname) retval = -1 exit = true elseif not continue then - logs.names_report(false, 3, "util", - "Task completed, exiting", "%s", actionname) - exit = true + report (false, 3, "util", + "Task completed, exiting.", "%s", actionname) + exit = true else - logs.names_report(false, 3, "util", - "Task completed successfully", "%s", actionname) + report (false, 3, "util", + "Task completed successfully.", "%s", actionname) end end if exit then break end diff --git a/Master/texmf-dist/scripts/luaotfload/mkcharacters b/Master/texmf-dist/scripts/luaotfload/mkcharacters index 5d4a2f47bd2..abed2c936ba 100755 --- a/Master/texmf-dist/scripts/luaotfload/mkcharacters +++ b/Master/texmf-dist/scripts/luaotfload/mkcharacters @@ -5,8 +5,8 @@ -- DESCRIPTION: import parts of char-def.lua -- REQUIREMENTS: lua, ConTeXt, the lualibs package -- AUTHOR: Philipp Gesang (Phg), --- VERSION: 2.4 --- CREATED: 2013-05-17 12:41:39+0200 +-- VERSION: 2.5 +-- MODIFIED: 2014-02-11 07:24:25+0100 ----------------------------------------------------------------------- -- we create a stripped-down version of char-def.lua ----------------------------------------------------------------------- @@ -14,7 +14,7 @@ ----------------------------------------------------------------------- -- config ----------------------------------------------------------------------- -local charfile = "./luaotfload-characters.lua" +local charfile = "./build/luaotfload-characters.lua" local chardef = "/home/phg/base/char-def.lua" --- for every code point char-def.lua provides a set of fields. they diff --git a/Master/texmf-dist/scripts/luaotfload/mkglyphlist b/Master/texmf-dist/scripts/luaotfload/mkglyphlist index f7a1cb941cf..8fde098f1a5 100755 --- a/Master/texmf-dist/scripts/luaotfload/mkglyphlist +++ b/Master/texmf-dist/scripts/luaotfload/mkglyphlist @@ -5,19 +5,21 @@ -- DESCRIPTION: part of the luaotfload package -- REQUIREMENTS: lua, lpeg, luasocket, the lualibs package -- AUTHOR: Philipp Gesang (Phg), --- VERSION: 2.4 --- CREATED: 04/23/2013 12:42:17 PM CEST +-- VERSION: 2.5 +-- MODIFIED: 2014-02-11 06:44:50+0100 ----------------------------------------------------------------------- -- interesting thread on the Context list: -- http://www.ntg.nl/pipermail/ntg-context/2008/029057.html +-- +-- N.B. this script assumes network connectivity! ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- config ----------------------------------------------------------------------- -local glyphfile = "./glyphlist.txt" -local font_age = "./luaotfload-glyphlist.lua" +local glyphfile = "./build/glyphlist.txt" +local font_age = "./build/luaotfload-glyphlist.lua" local glyph_source = "http://partners.adobe.com/public/developer/en/opentype/glyphlist.txt" ----------------------------------------------------------------------- @@ -133,6 +135,7 @@ end local get_raw get_raw = function (retry) local fh = io.open(glyphfile, "rb") if fh then + print ("info: reading glyph list from", glyphfile) local data = fh:read"*all" fh:close() if data then return data end @@ -143,7 +146,7 @@ local get_raw get_raw = function (retry) if glyphdata then local fh = io.open(glyphfile, "wb") if not fh then - print"error: glyph file not writable" + print (string.format ("error: glyph file (%s) not writable", glyphfile)) os.exit(-1) end fh:write(glyphdata) diff --git a/Master/texmf-dist/scripts/luaotfload/mkstatus b/Master/texmf-dist/scripts/luaotfload/mkstatus index 9940970e46f..15cb97cf207 100755 --- a/Master/texmf-dist/scripts/luaotfload/mkstatus +++ b/Master/texmf-dist/scripts/luaotfload/mkstatus @@ -24,39 +24,44 @@ local md5sumhexa = md5.sumhexa local ioloaddata = io.loaddata local iosavedata = io.savedata local iopopen = io.popen +local iowrite = io.write +local lfsisdir = lfs.isdir ----------------------------------------------------------------------- -- settings ----------------------------------------------------------------------- -local filelist = "luaotfload-status.lua" --- result +local verbose = false +local filelist = "./build/luaotfload-status.lua" --- result local names = { --- only the runtime files and scripts - "luaotfload-auxiliary.lua", - "luaotfload-basics-gen.lua", - "luaotfload-basics-nod.lua", - "luaotfload-characters.lua", - "luaotfload-colors.lua", - "luaotfload-database.lua", - "luaotfload-diagnostics.lua", - "luaotfload-features.lua", - "luaotfload-fonts-cbk.lua", - "luaotfload-fonts-def.lua", - "luaotfload-fonts-enc.lua", - "luaotfload-fonts-ext.lua", - "luaotfload-fonts-lua.lua", - "luaotfload-fonts-tfm.lua", - "luaotfload-glyphlist.lua", - "luaotfload-letterspace.lua", - "luaotfload-loaders.lua", - "luaotfload.lua", - "luaotfload-fontloader.lua", - "luaotfload-override.lua", - "luaotfload-tool.lua", - "mkcharacters", - "mkglyphlist", - "mkstatus", + { "src", "luaotfload-auxiliary.lua", }, + { "src", "luaotfload-basics-gen.lua", }, + { "src", "luaotfload-basics-nod.lua", }, + { "build", "luaotfload-characters.lua", }, + { "src", "luaotfload-colors.lua", }, + { "src", "luaotfload-database.lua", }, + { "src", "luaotfload-diagnostics.lua", }, + { "src", "luaotfload-features.lua", }, + { "src", "luaotfload-fonts-cbk.lua", }, + { "src", "luaotfload-fonts-def.lua", }, + { "src", "luaotfload-fonts-enc.lua", }, + { "src", "luaotfload-fonts-ext.lua", }, + { "src", "luaotfload-fonts-lua.lua", }, + { "src", "luaotfload-fonts-tfm.lua", }, + { "build", "luaotfload-glyphlist.lua", }, + { "src", "luaotfload-letterspace.lua", }, + { "src", "luaotfload-loaders.lua", }, + { "src", "luaotfload-log.lua", }, + { "src", "luaotfload-main.lua", }, + { "src", "luaotfload-fontloader.lua", }, + { "src", "luaotfload-override.lua", }, + { "src", "luaotfload-parsers.lua", }, + { "src", "luaotfload-tool.lua", }, + { "scripts", "mkcharacters", }, + { "scripts", "mkglyphlist", }, + { "scripts", "mkstatus", }, } ----------------------------------------------------------------------- @@ -120,17 +125,38 @@ hash_all = function (list, acc) return hash_all (table.fastcopy (names), { }) end - local fname = list[#list] + local finfo = list[#list] list[#list] = nil - if fname then - local sum = hash_file (fname) - acc[#acc+1] = { fname, sum } + if finfo then + local fpath + if type (finfo) == "table" then + local d, f = finfo [1], finfo [2] + if lfs.isdir (d) then + fpath = file.join (d, f) + else + fpath = f + end + else + fpath = finfo + end + if verbose then + iowrite "· md5(" + iowrite (fpath) + end + local sum = hash_file (fpath) + if verbose then + iowrite ") = \"" + iowrite (sum) + iowrite "\"\n" + end + acc[#acc+1] = { fpath, sum } return hash_all (list, acc) end return acc end local main = function () + if arg [1] == "-v" then verbose = true end local hashes = hash_all () local notes = git_info () local serialized = table.serialize ({ notes = notes, diff --git a/Master/texmf-dist/source/luatex/luaotfload/Makefile b/Master/texmf-dist/source/luatex/luaotfload/Makefile index 2d618e7f525..c27ffd41850 100644 --- a/Master/texmf-dist/source/luatex/luaotfload/Makefile +++ b/Master/texmf-dist/source/luatex/luaotfload/Makefile @@ -1,177 +1,203 @@ # Makefile for luaotfload -NAME = luaotfload -DOC = $(NAME).pdf -DTX = $(NAME).dtx -OTFL = $(wildcard luaotfload-*.lua) luaotfload-blacklist.cnf +NAME = luaotfload -GLYPHSCRIPT = mkglyphlist -GLYPHSOURCE = glyphlist.txt -CHARSCRIPT = mkcharacters -STATUSSCRIPT = mkstatus +DOCSRCDIR = ./doc +SCRIPTSRCDIR = ./scripts +SRCSRCDIR = ./src +BUILDDIR = ./build +MISCDIR = ./misc + +SRC = $(wildcard $(SRCSRCDIR)/luaotfload-*.lua) +SRC += $(SRCSRCDIR)/luaotfload.sty +SRC += $(MISCDIR)/luaotfload-blacklist.cnf + +VGND = $(MISCDIR)/valgrind-kpse-suppression.sup +CONFDEMO = $(MISCDIR)/luaotfload.conf.example + +GLYPHSCRIPT = $(SCRIPTSRCDIR)/mkglyphlist +CHARSCRIPT = $(SCRIPTSRCDIR)/mkcharacters +STATUSSCRIPT = $(SCRIPTSRCDIR)/mkstatus + +GLYPHSOURCE = $(BUILDDIR)/glyphlist.txt RESOURCESCRIPTS = $(GLYPHSCRIPT) $(CHARSCRIPT) $(STATUSSCRIPT) -SCRIPTNAME = luaotfload-tool -SCRIPT = $(SCRIPTNAME).lua -MANSOURCE = $(SCRIPTNAME).rst -MANPAGE = $(SCRIPTNAME).1 -OLDSCRIPT = luaotfload-legacy-tool.lua +TOOLNAME = luaotfload-tool +TOOL = $(SRCSRCDIR)/$(TOOLNAME).lua + +CONFNAME = luaotfload.conf + +GRAPH = filegraph +DOCSRC = $(addprefix $(DOCSRCDIR)/$(NAME), -main.tex -latex.tex) +GRAPHSRC = $(DOCSRCDIR)/$(GRAPH).dot +MANSRC = $(DOCSRCDIR)/$(TOOLNAME).rst $(DOCSRCDIR)/$(CONFNAME).rst -GRAPH = filegraph -DOTPDF = $(GRAPH).pdf -DOT = $(GRAPH).dot +DOCPDF = $(DOCSRCDIR)/$(NAME).pdf +DOTPDF = $(DOCSRCDIR)/$(GRAPH).pdf +TOOLMAN = $(DOCSRCDIR)/$(TOOLNAME).1 +CONFMAN = $(DOCSRCDIR)/$(CONFNAME).5 +MANPAGES = $(TOOLMAN) $(CONFMAN) + +DOCS = $(DOCPDF) $(DOTPDF) $(MANPAGES) # Files grouped by generation mode -GLYPHS = luaotfload-glyphlist.lua -CHARS = luaotfload-characters.lua -STATUS = luaotfload-status.lua +GLYPHS = $(BUILDDIR)/$(NAME)-glyphlist.lua +CHARS = $(BUILDDIR)/$(NAME)-characters.lua +STATUS = $(BUILDDIR)/$(NAME)-status.lua RESOURCES = $(GLYPHS) $(CHARS) $(STATUS) -GRAPHED = $(DOTPDF) -MAN = $(MANPAGE) -COMPILED = $(DOC) -UNPACKED = luaotfload.sty luaotfload.lua -GENERATED = $(GRAPHED) $(UNPACKED) $(COMPILED) $(RESOURCES) $(MAN) -SOURCE = $(DTX) $(MANSOURCE) $(OTFL) README Makefile NEWS $(RESOURCESCRIPTS) - -# test files -TESTDIR = tests -TESTSTATUS = $(wildcard $(TESTDIR)/*.tex $(TESTDIR)/*.ltx) -TESTSTATUS_SYS = $(TESTDIR)/systemfonts.tex $(TESTDIR)/fontconfig_conf_reading.tex -TESTSTATUS_TL = $(filter-out $(TESTSTATUS_SYS), $(TESTSTATUS)) +SOURCE = $(DOCSRC) $(MANSRC) $(SRC) README COPYING Makefile NEWS $(RESOURCESCRIPTS) # Files grouped by installation location -SCRIPTSTATUS = $(SCRIPT) $(OLDSCRIPT) $(RESOURCESCRIPTS) -RUNSTATUS = $(UNPACKED) $(filter-out $(SCRIPTSTATUS),$(OTFL)) -DOCSTATUS = $(DOC) $(DOTPDF) README NEWS -MANSTATUS = $(MANPAGE) -SRCSTATUS = $(DTX) Makefile +SCRIPTSTATUS = $(TOOL) $(RESOURCESCRIPTS) +RUNSTATUS = $(filter-out $(SCRIPTSTATUS),$(SRC)) +DOCSTATUS = $(DOCPDF) $(DOTPDF) README NEWS COPYING +SRCSTATUS = $(DOCSRC) $(MANSRC) $(GRAPHSRC) Makefile # The following definitions should be equivalent # ALL_STATUS = $(RUNSTATUS) $(DOCSTATUS) $(SRCSTATUS) -ALL_STATUS = $(GENERATED) $(SOURCE) +ALL_STATUS = $(RESOURCES) $(SOURCE) # Installation locations -FORMAT = luatex -SCRIPTDIR = $(TEXMFROOT)/scripts/$(NAME) -RUNDIR = $(TEXMFROOT)/tex/$(FORMAT)/$(NAME) -DOCDIR = $(TEXMFROOT)/doc/$(FORMAT)/$(NAME) -MANDIR = $(TEXMFROOT)/doc/man/man1/ -SRCDIR = $(TEXMFROOT)/source/$(FORMAT)/$(NAME) -TEXMFROOT = $(shell kpsewhich --var-value TEXMFHOME) +FORMAT = luatex +SCRIPTDIR = $(TEXMFROOT)/scripts/$(NAME) +RUNDIR = $(TEXMFROOT)/tex/$(FORMAT)/$(NAME) +DOCDIR = $(TEXMFROOT)/doc/$(FORMAT)/$(NAME) +MAN1DIR = $(TEXMFROOT)/doc/man/man1/ +MAN5DIR = $(TEXMFROOT)/doc/man/man5/ +SRCDIR = $(TEXMFROOT)/source/$(FORMAT)/$(NAME) +TEXMFROOT = $(shell kpsewhich --var-value TEXMFHOME) # CTAN-friendly subdirectory for packaging -DISTDIR = ./luaotfload - -CTAN_ZIP = $(NAME).zip -TDS_ZIP = $(NAME).tds.zip -ZIPS = $(CTAN_ZIP) $(TDS_ZIP) - -LUA = texlua - -DO_TEX = luatex --interaction=batchmode $< >/dev/null -DO_LATEXMK = latexmk -e '$$max_repeat = 5' -pdf -lualatex -silent $< >/dev/null -# latexmk does only one run on my machine, so we’re not going to rely on it -DO_LATEX = lualatex -interaction=batchmode $< >/dev/null -DO_GRAPHVIZ = dot -Tpdf -o $@ $< > /dev/null -DO_GLYPHS = $(LUA) $(GLYPHSCRIPT) > /dev/null -DO_CHARS = $(LUA) $(CHARSCRIPT) > /dev/null -DO_STATUS = $(LUA) $(STATUSSCRIPT) > /dev/null -DO_DOCUTILS = rst2man $< >$@ 2>/dev/null - -all: $(GENERATED) -graph: $(GRAPHED) -doc: $(GRAPHED) $(COMPILED) $(MAN) -manual: $(MAN) -unpack: $(UNPACKED) +DISTDIR = $(BUILDDIR)/$(NAME) + +CTAN_ZIPFILE = $(NAME).zip +TDS_ZIPFILE = $(NAME).tds.zip +CTAN_ZIP = $(BUILDDIR)/$(CTAN_ZIPFILE) +TDS_ZIP = $(BUILDDIR)/$(TDS_ZIPFILE) +ZIPS = $(CTAN_ZIP) $(TDS_ZIP) + +LUA = texlua + +## For now the $(BUILDDIR) is hardcoded in the scripts +## but we might just as well pass it to them by as environment +## variables. +DO_GLYPHS = $(LUA) $(GLYPHSCRIPT) > /dev/null +DO_CHARS = $(LUA) $(CHARSCRIPT) > /dev/null +DO_STATUS = $(LUA) $(STATUSSCRIPT) > /dev/null + +show: showtargets + +all: ctan +builddir: $(BUILDDIR) resources: $(RESOURCES) chars: $(CHARS) status: $(STATUS) ctan: $(CTAN_ZIP) tds: $(TDS_ZIP) -world: all ctan -$(GLYPHS): /dev/null - $(DO_GLYPHS) +graph: $(DOTPDF) +doc: $(DOCS) +pdf: $(DOCPDF) +manual: $(MANPAGES) -$(CHARS): /dev/null - $(DO_CHARS) +$(DOTPDF): + @$(MAKE) -C $(DOCSRCDIR) graph -$(STATUS): /dev/null - $(DO_STATUS) +$(DOCPDF): + @$(MAKE) -C $(DOCSRCDIR) doc -$(GRAPHED): $(DOT) - $(DO_GRAPHVIZ) +$(MANPAGES): + @$(MAKE) -C $(DOCSRCDIR) manuals -$(COMPILED): $(DTX) - $(DO_LATEX) - $(DO_LATEX) +$(GLYPHS): builddir + $(DO_GLYPHS) -$(UNPACKED): $(DTX) - $(DO_TEX) +$(CHARS): builddir + $(DO_CHARS) -$(MAN): $(MANSOURCE) - $(DO_DOCUTILS) +$(STATUS): builddir + $(DO_STATUS) + +$(BUILDDIR): /dev/null + mkdir -p $(BUILDDIR) define make-ctandir @$(RM) -rf $(DISTDIR) -@mkdir -p $(DISTDIR) && cp $(SOURCE) $(COMPILED) $(DISTDIR) +@mkdir -p $(DISTDIR) && cp $(RESOURCES) $(DOCPDF) $(VGND) $(CONFDEMO) $(SOURCE) $(DISTDIR) endef -$(CTAN_ZIP): $(SOURCE) $(COMPILED) $(TDS_ZIP) +$(CTAN_ZIP): $(DOCS) $(SOURCE) $(TDS_ZIP) @echo "Making $@ for CTAN upload." @$(RM) -- $@ $(make-ctandir) - @zip -r -9 $@ $(TDS_ZIP) $(DISTDIR) >/dev/null + cd $(BUILDDIR) && zip -r -9 $(CTAN_ZIPFILE) $(TDS_ZIPFILE) $(NAME) >/dev/null + +define run-install-doc +@mkdir -p $(DOCDIR) && cp -- $(DOCSTATUS) $(VGND) $(CONFDEMO) $(DOCDIR) +@mkdir -p $(SRCDIR) && cp -- $(SRCSTATUS) $(SRCDIR) +@mkdir -p $(MAN1DIR) && cp -- $(TOOLMAN) $(MAN1DIR) +@mkdir -p $(MAN5DIR) && cp -- $(CONFMAN) $(MAN5DIR) +endef define run-install -@mkdir -p $(SCRIPTDIR) && cp $(SCRIPTSTATUS) $(SCRIPTDIR) -@mkdir -p $(RUNDIR) && cp $(RUNSTATUS) $(RUNDIR) -@mkdir -p $(DOCDIR) && cp $(DOCSTATUS) $(DOCDIR) -@mkdir -p $(SRCDIR) && cp $(SRCSTATUS) $(SRCDIR) -@mkdir -p $(MANDIR) && cp $(MANSTATUS) $(MANDIR) +@mkdir -p $(SCRIPTDIR) && cp -- $(SCRIPTSTATUS) $(SCRIPTDIR) +@mkdir -p $(RUNDIR) && cp -- $(RESOURCES) $(RUNSTATUS) $(RUNDIR) endef $(TDS_ZIP): TEXMFROOT=./tmp-texmf -$(TDS_ZIP): $(ALL_STATUS) +$(TDS_ZIP): $(DOCS) $(ALL_STATUS) @echo "Making TDS-ready archive $@." @$(RM) -- $@ + $(run-install-doc) $(run-install) @cd $(TEXMFROOT) && zip -9 ../$@ -r . >/dev/null @$(RM) -r -- $(TEXMFROOT) -.PHONY: install manifest clean mrproper +.PHONY: install manifest clean mrproper show showtargets install: $(ALL_STATUS) @echo "Installing in '$(TEXMFROOT)'." + $(run-install-docs) $(run-install) -check: $(RUNSTATUS) $(TESTSTATUS_TL) - @rm -rf var - @for f in $(TESTSTATUS_TL); do \ - echo "check: luatex $$f"; \ - luatex --interaction=batchmode $$f \ - > /dev/null || exit $$?; \ - done - -check-all: $(TESTSTATUS_SYS) check - @cd $(TESTDIR); for f in $(TESTSTATUS_SYS); do \ - echo "check: luatex $$f"; \ - $(TESTENV) luatex --interaction=batchmode ../$$f \ - > /dev/null || exit $$?; \ - done - -manifest: +manifest: @echo "Source files:" @for f in $(SOURCE); do echo $$f; done @echo "" @echo "Derived files:" @for f in $(GENERATED); do echo $$f; done -clean: - @$(RM) -- *.log *.aux *.toc *.idx *.ind *.ilg *.out $(TESTDIR)/*.log +CLEANEXTS = log aux toc idx ind ilg out +CLEANME = $(foreach ext,$(CLEANEXTS),$(wildcard *.$(ext))) +CLEANME += $(foreach ext,$(CLEANEXTS),$(wildcard $(BUILDDIR)/*$(ext))) -mrproper: clean - @$(RM) -- $(GENERATED) $(ZIPS) $(GLYPHSOURCE) $(TESTDIR)/*.pdf - @$(RM) -r -- $(DISTDIR) +clean: + $(MAKE) -C $(DOCSRCDIR) $@ + @$(RM) -- $(CLEANME) +mrproper: clean + $(MAKE) -C $(DOCSRCDIR) $@ + @$(RM) -- $(GENERATED) $(ZIPS) $(GLYPHSOURCE) + @$(RM) -r -- $(BUILDDIR) + +############################################################################### +showtargets: + @echo "Available targets:" + @echo + @echo " doc compile PDF documentation" + @echo " resources generate resource files (chars, glyphs)" + @echo + @echo " pdf build luaotfload.pdf" + @echo " manual crate manpages for luaotfload-tool(1) and" + @echo " luaotfload.conf(5) (requires Docutils)" + @echo " graph generate file graph (requires GraphViz)" + @echo + @echo " chars import char-def.lua as luaotfload-characters.lua" + @echo " status create repository info (luaotfload-status.lua)" + @echo + @echo " tds package a zipball according to the TDS" + @echo " ctan package a zipball for uploading to CTAN" + @echo + +# vim:noexpandtab:tabstop=8:shiftwidth=2 diff --git a/Master/texmf-dist/source/luatex/luaotfload/filegraph.dot b/Master/texmf-dist/source/luatex/luaotfload/filegraph.dot new file mode 100644 index 00000000000..47db9ea3fcc --- /dev/null +++ b/Master/texmf-dist/source/luatex/luaotfload/filegraph.dot @@ -0,0 +1,287 @@ +strict digraph luaotfload_files { //looks weird with circo ... + compound = true; + +// label = "Schematic of the files included in Luaotfload."; +// labelloc = "b"; + + fontsize = "14.4"; + labelfontname = "Iwona Medium Regular"; + fontname = "Iwona Light Regular"; + size = "21cm"; + + rankdir = LR; + ranksep = 0.618; + nodesep = 1.618; + + edge [ + arrowhead = onormal, + fontname = "Iwona Cond Regular", + penwidth = 1.0, + ]; + node [ + //penwidth = 0.7, + fontname = "Liberation Mono", + fontsize = 12, + ]; + +/* ···································································· + * file structure + * ································································· */ + fontdbutil -> font_names [label="--update", + style=dashed] + + luaotfload -> otfl_fonts_merged [label="merged"] + luaotfload -> merged_lua_libs [label="unmerged", style=solid] + luaotfload -> merged_luatex_fonts [label="unmerged", style=solid] + luaotfload -> merged_context_libs [label="unmerged", style=solid] + + luaotfload -> luaotfload_libs + luaotfload -> otfl_blacklist_cnf + + otfl_fonts_merged -> merged_lua_libs [label="merged", + style=dotted, + lhead=cluster_merged] + otfl_fonts_merged -> merged_luatex_fonts [label="merged", + style=dotted, + lhead=cluster_merged] + otfl_fonts_merged -> merged_context_libs [label="merged", + style=dotted, + lhead=cluster_merged] + + merged_luatex_fonts -> font_age [label="luatex-fonts-enc.lua", + ltail=cluster_merged] + + fontdbutil -> fontdbutil_diagnostics [label="--diagnose"] + + fontdbutil -> status [label="version information"] + + fontdbutil_diagnostics -> status [constraint=no, label="hash files"] + + merged_luatex_fonts -> characters [label="luaotfload-auxiliary.lua", + ltail=cluster_merged] + + luaotfload_libs -> font_names [label="luaotfload-database.lua"] + + mkstatus -> status [label="generates from distribution files", + style=dashed] + + mkglyphlist -> font_age [label="generates from glyphlist.txt", + style=dashed] + + mkcharacters -> characters [label="generates from Context’s char-def.lua", + style=dashed] + + subgraph { rank = same; + mkcharacters; + mkglyphlist; + mkstatus; + fontdbutil; + luaotfload } + +/* ···································································· + * main files + * ································································· */ + + fontdbutil [label = "luaotfload-tool.lua", + shape = rect, + width = "3.2cm", + height = "1.2cm", + color = "#01012222", + style = "filled,rounded", + penwidth=2] + + fontdbutil_diagnostics [label = "luaotfload-diagnostics.lua", + shape = rect, + width = "3.2cm", + height = "1.2cm", + color = "#01012222", + style = "filled,rounded", + penwidth=2] + + mkstatus [label = "mkstatus", + shape = rect, + width = "3.2cm", + height = "1.2cm", + color = "#01012222", + style = "filled,rounded", + penwidth=2] + + mkglyphlist [label = "mkglyphlist", + shape = rect, + width = "3.2cm", + height = "1.2cm", + color = "#01012222", + style = "filled,rounded", + penwidth=2] + + mkcharacters [label = "mkcharacters", + shape = rect, + width = "3.2cm", + height = "1.2cm", + color = "#01012222", + style = "filled,rounded", + penwidth=2] + + luaotfload [label = "luaotfload-main.lua", + shape = rect, + width = "3.2cm", + height = "1.2cm", + color = "#01012222", + style = "filled,rounded", + penwidth=2] + /* + *otfl_fonts [label = "luaotfload-fonts.lua", + * shape = rect, + * width = "3.2cm", + * height = "1.2cm", + * color = "#01012222", + * style = "filled,rounded", + * penwidth=2] + */ + otfl_fonts_merged [label = "luaotfload-fontloader.lua", + shape = rect, + width = "3.2cm", + height = "1.2cm", + color = "#01012222", + style = "filled,rounded", + penwidth=2] + +/* ···································································· + * luaotfload files + * ································································· */ + + characters [style = "filled,dashed", + shape = rect, + width = "3.2cm", + fillcolor = "#01012222", + color = grey40, + style = "filled,dotted,rounded", + label = "luaotfload-characters.lua"] + + font_age [style = "filled,dashed", + shape = rect, + width = "3.2cm", + fillcolor = "#01012222", + color = grey40, + style = "filled,dotted,rounded", + label = "luaotfload-glyphlist.lua"] + + font_names [style = "filled,dashed", + shape = rect, + width = "3.2cm", + fillcolor = "#01012222", + color = grey40, + style = "filled,dotted,rounded", + label = "luaotfload-names.lua.gz\nluaotfload-names.luc"] + + status [style = "filled,dashed", + shape = rect, + width = "3.2cm", + fillcolor = "#01012222", + color = grey40, + style = "filled,dotted,rounded", + label = "luaotfload-status.lua"] + + otfl_blacklist_cnf [style = "filled,dashed", + shape = rect, + width = "3.2cm", + fillcolor = "#01012222", + color = grey40, + style = "filled,dotted,rounded", + label = "luaotfload-blacklist.cnf"] + + luaotfload_libs [ + shape = box, + style = "filled,rounded", + color = "grey90:goldenrod4", + fontsize = 10, + label = < +
+ + + + + + +
Luaotfload Libraries
luaotfload-auxiliary.lua luaotfload-features.lua
luaotfload-override.lua luaotfload-loaders.lua
luaotfload-log.lua luaotfload-letterspace.lua
luaotfload-parsers.lua luaotfload-database.lua
luaotfload-color.lua
+ >, + ] + +/* ···································································· + * merged files + * ································································· */ + + subgraph cluster_merged { + node [style=filled, color=white]; + style = "filled,rounded"; + color = "grey90:dodgerblue4"; + //nodesep = "3.0"; + rank = same; + label = "Merged Libraries"; + gradientangle=0; + merged_lua_libs; + merged_luatex_fonts; + merged_context_libs; + } + + otfl_fonts_merged -> merged_lua_libs + otfl_fonts_merged -> merged_luatex_fonts + otfl_fonts_merged -> merged_context_libs + + merged_lua_libs [ + shape = box, + style = "filled,rounded", + color = "#FFFFFFAA", + fontsize = 10, + label = < + + + + + + +
Lua Libraries from Context
l-lua.lua l-lpeg.lua l-function.lua
l-string.lua l-table.lua l-io.lua
l-file.lua l-boolean.lua l-math.lua
util-str.lua
+ >, + ] + + merged_luatex_fonts [ + shape = box, + style = "filled,rounded", + color = "#FFFFFFAA", + fontsize = 10, + label = < + + + + + + + + + + + + + +
Font Loader (LuaTeX-Fonts)
luatex-basics-gen.lua luatex-basics-nod.lua
luatex-fonts-enc.lua luatex-fonts-syn.lua
luatex-font-tfm.lua luatex-font-afm.lua
luatex-font-afk.lua luatex-fonts-tfm.lua
luatex-fonts-chr.lua luatex-fonts-lua.lua
luatex-fonts-inj.lua luatex-fonts-otn.lua
luatex-fonts-def.lua luatex-fonts-ext.lua
luatex-fonts-cbk.lua
+ >, + ] + + merged_context_libs [ + shape = box, + style = "filled,rounded", + color = "#FFFFFFAA", + fontsize = 10, + label = < + + + + + + +
Font and Node Libraries from Context
data-con.lua font-ini.lua font-con.lua
font-cid.lua font-map.lua font-oti.lua
font-otf.lua font-otb.lua font-ota.lua
font-def.lua
+ >, + ] +} + +// vim:ft=dot:sw=4:ts=4:expandtab diff --git a/Master/texmf-dist/source/luatex/luaotfload/luaotfload-latex.tex b/Master/texmf-dist/source/luatex/luaotfload/luaotfload-latex.tex new file mode 100644 index 00000000000..34c494d58f7 --- /dev/null +++ b/Master/texmf-dist/source/luatex/luaotfload/luaotfload-latex.tex @@ -0,0 +1,448 @@ +\luatexsuppresslongerror1%% sigh ... +%% Copyright (C) 2009-2014 +%% +%% by Elie Roux +%% and Khaled Hosny +%% and Philipp Gesang +%% +%% This file is part of Luaotfload. +%% +%% Home: https://github.com/lualatex/luaotfload +%% Support: . +%% +%% Luaotfload is under the GPL v2.0 (exactly) license. +%% +%% ---------------------------------------------------------------------------- +%% +%% Luaotfload is free software; you can redistribute it and/or +%% modify it under the terms of the GNU General Public License +%% as published by the Free Software Foundation; version 2 +%% of the License. +%% +%% Luaotfload is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%% GNU General Public License for more details. +%% +%% You should have received a copy of the GNU General Public License +%% along with Luaotfload; if not, see . +%% +%% ---------------------------------------------------------------------------- +%% + +\documentclass{ltxdoc} + +\makeatletter + +\usepackage {metalogo,multicol,fancyvrb,xspace} +\usepackage [x11names] {xcolor} + +\def \primarycolor {DodgerBlue4} %%-> rgb 16 78 139 | #104e8b +\def \secondarycolor {Goldenrod4} %%-> rgb 139 105 200 | #8b6914 + +\usepackage[ + bookmarks=true, + colorlinks=true, + linkcolor=\primarycolor, + urlcolor=\secondarycolor, + citecolor=\primarycolor, + pdftitle={The Luaotfload package}, + pdfsubject={OpenType layout system for Plain TeX and LaTeX}, + pdfauthor={Elie Roux & Khaled Hosny & Philipp Gesang}, + pdfkeywords={luatex, lualatex, unicode, opentype} +]{hyperref} + +\usepackage {fontspec} +\usepackage {unicode-math} + +\setmainfont[ +% Numbers = OldStyle, %% buggy with font cache + Ligatures = TeX, + BoldFont = {Linux Libertine O Bold}, + ItalicFont = {Linux Libertine O Italic}, + SlantedFont = {Linux Libertine O Italic}, +]{Linux Libertine O} +\setmonofont[Ligatures=TeX,Scale=MatchLowercase]{Liberation Mono} +%setsansfont[Ligatures=TeX]{Linux Biolinum O} +\setsansfont[Ligatures=TeX,Scale=MatchLowercase]{Iwona Medium} +%setmathfont{XITS Math} + +\usepackage{hologo} + +\newcommand\TEX {\TeX\xspace} +\newcommand\LUA {Lua\xspace} +\newcommand\PDFTEX {pdf\TeX\xspace} +\newcommand\LUATEX {Lua\TeX\xspace} +\newcommand\XETEX {\XeTeX\xspace} +\newcommand\LATEX {\LaTeX\xspace} +\newcommand\LUALATEX {Lua\LaTeX\xspace} +\newcommand\CONTEXT {Con\TeX t\xspace} +\newcommand\OpenType {\identifier{Open\kern-.25ex Type}\xspace} + +%% \groupedcommand, with some omissions taken from syst-aux.mkiv +\let \handlegroupnormalbefore \relax +\let \handlegroupnormalafter \relax + +\protected \def \handlegroupnormal #1#2{% + \bgroup % 1 + \def \handlegroupbefore {#1}% + \def \handlegroupafter {#2}% + \afterassignment \handlegroupnormalbefore + \let \next = +} + +\def \handlegroupnormalbefore {% + \bgroup % 2 + \handlegroupbefore + \bgroup % 3 + \aftergroup \handlegroupnormalafter% +} + +\def \handlegroupnormalafter {% + \handlegroupafter + \egroup % 3 + \egroup % 2 +} + +\let \groupedcommand \handlegroupnormal %% only the two arg version + +\def \definehighlight [#1][#2]{% + \ifcsname #1\endcsname\else + \expandafter\def\csname #1\endcsname{% + \leavevmode + \groupedcommand {#2}\empty% + } + \fi% +} + +%% old, simplistic definition: obsolete now that we have +%% \groupedcommand +%\def\definehighlight[#1][#2]% + %{\ifcsname #1\endcsname\else + %\expandafter\def\csname #1\endcsname% + %{\bgroup#2\csname #1_indeed\endcsname} + %\expandafter\def\csname #1_indeed\endcsname##1% + %{##1\egroup}% + %\fi} + +\def\restoreunderscore{\catcode`\_=12\relax} + +\definehighlight [fileent][\ttfamily\restoreunderscore] %% files, dirs +\definehighlight [texmacro][\sffamily\itshape\textbackslash] %% cs +\definehighlight [luafunction][\sffamily\itshape\restoreunderscore] %% lua identifiers +\definehighlight [identifier][\sffamily] %% names +\definehighlight [abbrev][\rmfamily\scshape] %% acronyms +\definehighlight [emphasis][\rmfamily\slshape] %% level 1 emph + +\definehighlight [Largefont][\Large] %% font size +\definehighlight [smallcaps][\sc] %% font feature +\definehighlight [nonproportional][\tt] %% font switch + +\newcommand*\email[1]{\href{mailto:#1}{#1}} + +\renewcommand\partname{Part}%% gets rid of the stupid “file” heading + +\usepackage{syntax}%% bnf for font request syntax + +\usepackage{titlesec} + +\def\movecountertomargin#1{\llap{\rmfamily\upshape#1\hskip2em}} +\def\zeropoint{0pt} +\titleformat \part + {\normalsize\rmfamily\bfseries} + {\movecountertomargin\thepart} \zeropoint {} +\titleformat \section + {\normalsize\rmfamily\scshape} + {\movecountertomargin\thesection} \zeropoint {} +\titleformat \subsection + {\small\rmfamily\itshape} + {\movecountertomargin\thesubsection} \zeropoint {} +\titleformat \subsubsection + {\normalsize\rmfamily\upshape} + {\movecountertomargin\thesubsubsection} \zeropoint {} + +\usepackage{tocloft} +\renewcommand \cftpartfont {\rmfamily\upshape} +\renewcommand \cftsecfont {\rmfamily\upshape} +\renewcommand \cftsubsecfont {\rmfamily\upshape} +\setlength \cftbeforepartskip {1ex} +\setlength \cftbeforesecskip {1ex} + +\VerbatimFootnotes + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% structurals +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def \definestructural #1{% + \expandafter \let \csname end#1\endcsname \relax + + \expandafter \def \csname begin#1\endcsname {% + \@ifnextchar[{\csname begin#1indeed\endcsname} + {\csname begin#1indeed\endcsname[]}% + } + + \expandafter \def \csname begin#1indeed\endcsname [##1]##2{% + \edef \first {##1}% + \ifx \first \empty + \csname #1\endcsname [##2]{##2}% + \else + \csname #1\endcsname [\first]{##2}% + \fi + } +} + +\definestructural {section} +\definestructural {subsection} +\definestructural {subsubsection} + +\def \fakesection #1{\section*{#1}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% inline verbatim +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Context offers both \type{…} and \type<<…>>, but not an unbalanced +%% one that we could map directly onto Latex’s \verb|…|. + +\usepackage {listings} +\lstset { + basicstyle=\ttfamily, +} + +%\let \inlinecode \lstinline +\protected \def \inlinecode {\lstinline} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% codelistings; this sucks hard since we lack access to buffers +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newcount \othercatcode \othercatcode 12 +\newcount \activecatcode \othercatcode 13 + +\newluatexcatcodetable \vrbcatcodes +\setluatexcatcodetable \vrbcatcodes {% + \luatexcatcodetable \CatcodeTableIniTeX + \catcode 9 \othercatcode %% \tabasciicode + \catcode 13 \othercatcode %% \endoflineasciicode + \catcode 12 \othercatcode %% \formfeedasciicode + \catcode 26 \othercatcode %% \endoffileasciicode + \catcode 32 \othercatcode %% \spaceasciicode +} + +\newluatexcatcodetable \literalcatcodes +\setluatexcatcodetable \literalcatcodes {% + \luatexcatcodetable \CatcodeTableString + \catcode 32 \activecatcode %% \spaceasciicode +} + +\def \beginlisting {% + \begingroup + \luatexcatcodetable \vrbcatcodes + \beginlistingindeed% +} + +\directlua { + local texprint = tex.print + local stringsub = string.sub + local backslash = string.byte (0x5c) + document = document or { } + document.printlines = function (buffer) + for _, line in next, string.explode (buffer, "\noexpand\n") do + if stringsub (line, 1, 1) == " " then + line = backslash .. line + end + texprint (-1, line) + texprint (-1, "") + end + end +} + +\def \beginlistingindeed#1\endlisting{% + \endgroup + \begingroup + \ttfamily + \small + \begin {quote} + \bgroup + \addfontfeature {RawFeature=-tlig;-liga}%% So one can’t just turn them all off at once using the ``Ligatures`` key? + \luatexcatcodetable \literalcatcodes + \obeyspaces + \obeylines + \directlua{document.printlines ([==[\detokenize {#1}]==])} + \egroup + \end {quote} + \endgroup +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% enumerations and lists +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def \definelist [#1]#2{% name, itemcode + \expandafter \def \csname begin#1\endcsname {% + \begin {itemize} + \let \normalitem = \item + \def \altitem ####1{% + \def \first {####1}% + #2 + } + \let \beginnormalitem \item + \let \endnormalitem \relax + \let \beginaltitem \altitem + \let \endaltitem \relax + } + + \expandafter \def \csname end#1\endcsname {% + \end {itemize} + } +} + +\definelist [descriptions]{\normalitem {\textbf \first}\hfill\break} +\definelist [definitions]{\normalitem {\fileent {\first}}} +\definelist [filelist]{\normalitem {\fileent {\first}}\space--\hskip 1em} +\definelist [functionlist]{\normalitem {\luafunction {\first}}\hfill\break} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% columns +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def \begindoublecolumns {\begin {multicols} {2}} +\def \enddoublecolumns {\end {multicols}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% alignment +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def \begincentered {\begin {center}} +\def \endcentered {\end {center}} + +\def \beginnarrower {\begin {quote}} +\def \endnarrower {\end {quote}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% special elements +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\let \beginfrontmatter \relax +\let \endfrontmatter \relax + +\def \beginabstractcontent {\begin {abstract}} +\def \endabstractcontent {\end {abstract}} + +\let \setdocumenttitle \title +\let \setdocumentdate \date +\let \setdocumentauthor \author +\let \typesetdocumenttitle \maketitle + +\AtBeginDocument {%% seriously? + \let \typesetcontent \tableofcontents% +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% floats +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% syntax definition +\def \beginsyntaxfloat #1#2{%% #1:label #2:caption + \begin {figure} [b] + \edef \syntaxlabel {#1}% + \def \syntaxcaption {#2}% + \setlength\grammarparsep{12pt plus 2pt minus 2pt}% + \setlength\grammarindent{5cm}% + \begingroup + \small + \begin {grammar} +} + +\def \endsyntaxfloat {% + \end {grammar} + \endgroup + \caption \syntaxcaption + \label \syntaxlabel + \end {figure} +} + +%% figures, e.g. the file graph +\def \figurefloat #1#2#3{%% #1:label #2:caption #3:file + \begin {figure} [b] + \caption {#2}% + \includegraphics[width=\textwidth]{#3}% + \label {#1} + \end {figure} +} + +%% tables +\def \tablefloat #1#2{%% #1:label #2:caption + \begin {table} [t] + \hrule + \caption {#2}% + \label {#1} + \hrule + \end {table} +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% hyperlinks +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\protected \def \hyperlink{% + \@ifnextchar[{\hyperlinkindeed}% + {\hyperlinkindeed[]}% +} + +\def \hyperlinkindeed [#1]#2{% + \def \first {#1}% + \ifx \first \empty + \url {#2}% + \else + \href {#2}{#1}% + \fi% +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% tables +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Our tables aren’t anything special so we stick with “tabular” on the +%% Latex end. +%% +%% This is going to be largely incompatible with Context since format +%% specifications work quite differently (even between different +%% Context table variants). + +\def \begintabulate [#1]#2\endtabulate{% + \begingroup + \let \beginrow = \relax %% -> \NC in Context + \let \newcell = & %% -> \NC + \let \endrow = \cr %% -> \NC \NR + \begin {tabular}{#1}% + #2 + \end {tabular} + \endgroup +} + +\let \endtabulate \relax + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% escaped characters +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\let \charpercent \textpercent +\let \charbackslash \textbackslash +\let \chartilde \textasciitilde + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% main +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\makeatother + +\newif \ifcontextmkiv \contextmkivfalse + +\begin {document} + \input {luaotfload-main.tex} +\end {document} + + diff --git a/Master/texmf-dist/source/luatex/luaotfload/luaotfload-main.tex b/Master/texmf-dist/source/luatex/luaotfload/luaotfload-main.tex new file mode 100644 index 00000000000..2e89ff000e8 --- /dev/null +++ b/Master/texmf-dist/source/luatex/luaotfload/luaotfload-main.tex @@ -0,0 +1,1590 @@ +%% Copyright (C) 2009-2014 +%% +%% by Elie Roux +%% and Khaled Hosny +%% and Philipp Gesang +%% +%% This file is part of Luaotfload. +%% +%% Home: https://github.com/lualatex/luaotfload +%% Support: . +%% +%% Luaotfload is under the GPL v2.0 (exactly) license. +%% +%% ---------------------------------------------------------------------------- +%% +%% Luaotfload is free software; you can redistribute it and/or +%% modify it under the terms of the GNU General Public License +%% as published by the Free Software Foundation; version 2 +%% of the License. +%% +%% Luaotfload is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%% GNU General Public License for more details. +%% +%% You should have received a copy of the GNU General Public License +%% along with Luaotfload; if not, see . +%% +%% ---------------------------------------------------------------------------- +%% + +\beginfrontmatter + + \setdocumenttitle {The \identifier{luaotfload} package} + \setdocumentdate {2014/07/13 v2.5} + \setdocumentauthor {Elie Roux · Khaled Hosny · Philipp Gesang\\ + Home: \hyperlink {https://github.com/lualatex/luaotfload}\\ + Support: \email {lualatex-dev@tug.org}} + + \typesetdocumenttitle + + \beginabstractcontent + This package is an adaptation of the \CONTEXT font loading system. + It allows for loading \OpenType fonts with an extended syntax and adds + support for a variety of font features. + \endabstractcontent + +\endfrontmatter + +\typesetcontent + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\beginsection {Introduction} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Font management and installation has always been painful with \TEX. A +lot of files are needed for one font (\abbrev{tfm}, \abbrev{pfb}, +\abbrev{map}, \abbrev{fd}, \abbrev{vf}), and due to the 8-Bit encoding +each font is limited to 256 characters. + +But the font world has evolved since the original \TEX, and new +typographic systems have appeared, most notably the so called +\emphasis{smart font} technologies like \OpenType fonts (\abbrev{otf}). + +These fonts can contain many more characters than \TEX fonts, as well +as additional functionality like ligatures, old-style numbers, small +capitals, etc., and support more complex writing systems like Arabic +and Indic\footnote{% + Unfortunately, \identifier{luaotfload} doesn‘t support many Indic + scripts right now. + Assistance in implementing the prerequisites is greatly + appreciated. +} +scripts. + +\OpenType fonts are widely deployed and available for all modern +operating systems. + +As of 2013 they have become the de facto standard for advanced text +layout. + +However, until recently the only way to use them directly in the \TEX +world was with the \XETEX engine. + +Unlike \XETEX, \LUATEX has no built-in support for \OpenType or +technologies other than the original \TEX fonts. + +Instead, it provides hooks for executing \LUA code during the \TEX run +that allow implementing extensions for loading fonts and manipulating +how input text is processed without modifying the underlying engine. + +This is where \identifier{luaotfload} comes into play: +Based on code from \CONTEXT, it extends \LUATEX with functionality necessary +for handling \OpenType fonts. + +Additionally, it provides means for accessing fonts known to the operating +system conveniently by indexing the metadata. + +\endsection + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\beginsection {Thanks} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\identifier{Luaotfload} is part of \LUALATEX, the community-driven +project to provide a foundation for using the \LATEX format with the +full capabilites of the \LUATEX engine. +% +As such, the distinction between end users, contributors, and project +maintainers is intentionally kept less strict, lest we unduly +personalize the common effort. + +Nevertheless, the current maintainers would like to express their +gratitude to Khaled Hosny, Akira Kakuto, Hironori Kitagawa and Dohyun +Kim. +% +Their contributions -- be it patches, advice, or systematic +testing -- made the switch from version 1.x to 2.2 possible. +% +Also, Hans Hagen, the author of the font loader, made porting the +code to \LATEX a breeze due to the extra effort he invested into +isolating it from the rest of \CONTEXT, not to mention his assistance +in the task and willingness to respond to our suggestions. + +\endsection + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\beginsection {Loading Fonts} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\identifier{luaotfload} supports an extended font request syntax: + +\beginnarrower + \nonproportional{\string\font\string\foo\space= \string{}% + \meta{prefix}\nonproportional{:}% + \meta{font name}\nonproportional{:}% + \meta{font features}\nonproportional{\string}}% + \meta{\TEX font features} +\endnarrower + +\noindent +The curly brackets are optional and escape the spaces in the enclosed +font name. +% +Alternatively, double quotes serve the same purpose. +% +A selection of individual parts of the syntax are discussed below; +for a more formal description see figure \ref{font-syntax}. + +\beginsyntaxfloat + {font-syntax} + {Font request syntax. + Braces or double quotes around the + \emphasis{specification} rule will + preserve whitespace in file names. + In addition to the font style modifiers + (\emphasis{slash-notation}) given above, there + are others that are recognized but will be silently + ignored: \nonproportional{aat}, + \nonproportional{icu}, and + \nonproportional{gr}. + The special terminals are: + \smallcaps {feature\textunderscore id} for a valid font + feature name and + \smallcaps {feature\textunderscore value} for the corresponding + value. + \smallcaps {tfmname} is the name of a \abbrev{tfm} file. + \smallcaps {digit} again refers to bytes 48--57, and + \smallcaps {all\textunderscore characters} to all byte values. + \smallcaps {csname} and \smallcaps {dimension} are the \TEX concepts.} +% + ::= `\\font', {\sc csname}, `=', , [ ] ; + + ::= `at', {\sc dimension} ; + + ::= `"', `"' + \alt `{', `}' + \alt ; + + ::= , [`:', ] + \alt `[', `]', [ [`:'], ] ; + + ::= , [ ], \{ \} + \alt , \{ \} ; + + ::= `file:', + \alt `name:', ; + + ::= \{ \} ; + + ::= \{ \} ; + + ::= {\sc tfmname} | ; + + ::= \{ {\sc all_characters} - `]' \} ; + + ::= `/', (`I' | `B' | `BI' | `IB' | `S=', \{ {\sc digit} \} ) ; + + ::= `(', \{ {\sc digit} \}, `)' ; + + ::= , \{ `;', \} ; + + ::= {\sc feature_id}, `=', {\sc feature_value} + \alt , {\sc feature_id} ; + + ::= `+' | `-' ; + + ::= {\sc all_characters} - ( `(' | `/' | `:' ) ; +\endsyntaxfloat + +\beginsubsection{Prefix -- the \identifier{luaotfload}{ }Way} + +In \identifier{luaotfload}, the canonical syntax for font requests +requires a \emphasis{prefix}: +% +\beginnarrower + \nonproportional{\string\font\string\fontname\space= }% + \meta{prefix}% + \nonproportional{:}% + \meta{fontname}% + \dots +\endnarrower +% +where \meta{prefix} is either \inlinecode{file:} or \inlinecode {name:}.\footnote{% + The development version also knows two further prefixes, + \inlinecode {kpse:} and \inlinecode {my:}. + % + A \inlinecode {kpse} lookup is restricted to files that can be found by + \identifier{kpathsea} and + will not attempt to locate system fonts. + % + This behavior can be of value when an extra degree of encapsulation is + needed, for instance when supplying a customized tex distribution. + + The \inlinecode {my} lookup takes this a step further: it lets you define + a custom resolver function and hook it into the \luafunction{resolve_font} + callback. + % + This ensures full control over how a file is located. + % + For a working example see the + \hyperlink [test repo]{https://bitbucket.org/phg/lua-la-tex-tests/src/5f6a535d/pln-lookup-callback-1.tex}. +} +% +It determines whether the font loader should interpret the request as +a \emphasis{file name} or + \emphasis{font name}, respectively, +which again influences how it will attempt to locate the font. +% +Examples for font names are + “Latin Modern Italic”, + “GFS Bodoni Rg”, and + “PT Serif Caption” +-- they are the human readable identifiers +usually listed in drop-down menus and the like.\footnote{% + Font names may appear like a great choice at first because they + offer seemingly more intuitive identifiers in comparison to arguably + cryptic file names: + % + “PT Sans Bold” is a lot more descriptive than \fileent{PTS75F.ttf}. + On the other hand, font names are quite arbitrary and there is no + universal method to determine their meaning. + % + While \identifier{luaotfload} provides fairly sophisticated heuristic + to figure out a matching font style, weight, and optical size, it + cannot be relied upon to work satisfactorily for all font files. + % + For an in-depth analysis of the situation and how broken font names + are, please refer to + \hyperlink [this post]{http://www.ntg.nl/pipermail/ntg-context/2013/073889.html} + by Hans Hagen, the author of the font loader. + % + If in doubt, use filenames. + % + \fileent{luaotfload-tool} can perform the matching for you with the + option \inlinecode {--find=}, and you can use the file name it returns + in your font definition. +} +% +In order for fonts installed both in system locations and in your +\fileent{texmf} to be accessible by font name, \identifier{luaotfload} must +first collect the metadata included in the files. +% +Please refer to section~\ref{sec:fontdb} below for instructions on how to +create the database. + +File names are whatever your file system allows them to be, except +that that they may not contain the characters + \inlinecode {(}, + \inlinecode {:}, and + \inlinecode {/}. +% +As is obvious from the last exception, the \inlinecode {file:} lookup will +not process paths to the font location -- only those +files found when generating the database are addressable this way. +% +Continue below in the \XETEX section if you need to load your fonts +by path. +% +The file names corresponding to the example font names above are + \fileent{lmroman12-italic.otf}, + \fileent{GFSBodoni.otf}, and + \fileent{PTZ56F.ttf}. + +\endsubsection + +\beginsubsection {Compatibility Layer} + +In addition to the regular prefixed requests, \identifier{luaotfload} +accepts loading fonts the \XETEX way. +% +There are again two modes: bracketed and unbracketed. +A bracketed request looks as follows. + +\beginnarrower + \nonproportional{\string\font\string\fontname\space = [}% + \meta{/path/to/file}% + \nonproportional{]} +\endnarrower + +\noindent +Inside the square brackets, every character except for a closing +bracket is permitted, allowing for specifying paths to a font file. +% +Naturally, path-less file names are equally valid and processed the +same way as an ordinary \inlinecode {file:} lookup. + +\beginnarrower + \nonproportional{\string\font\string\fontname\space= }% + \meta{font name} + \dots +\endnarrower + +Unbracketed (or, for lack of a better word: \emphasis{anonymous}) +font requests resemble the conventional \TEX syntax. +% +However, they have a broader spectrum of possible interpretations: +before anything else, \identifier{luaotfload} attempts to load a +traditional \TEX Font Metric (\abbrev{tfm} or \abbrev{ofm}). +% +If this fails, it performs a \inlinecode {name:} lookup, which itself will +fall back to a \inlinecode {file:} lookup if no database entry matches +\meta{font name}. + +Furthermore, \identifier{luaotfload} supports the slashed (shorthand) +font style notation from \XETEX. + +\beginnarrower + \nonproportional{\string\font\string\fontname\space= }% + \meta{font name}% + \nonproportional{/}% + \meta{modifier} + \dots +\endnarrower + +\noindent +Currently, four style modifiers are supported: + \inlinecode {I} for italic shape, + \inlinecode {B} for bold weight, + \inlinecode {BI} or \inlinecode {IB} for the combination of both. +% +Other “slashed” modifiers are too specific to the \XETEX engine and +have no meaning in \LUATEX. + +\endsubsection + +\beginsubsection{Examples} + +\beginsubsubsection{Loading by File Name} + +For example, conventional \abbrev{type1} font can be loaded with a +\inlinecode {file:} request like so: + +\beginlisting + \font \lmromanten = {file:ec-lmr10} at 10pt +\endlisting + +The \OpenType version of Janusz Nowacki’s font \emphasis{Antykwa +Półtawskiego}\footnote{% + \hyperlink {http://jmn.pl/antykwa-poltawskiego/}, also available in + in \TEX Live. +} +in its condensed variant can be loaded as follows: + +\beginlisting + \font \apcregular = file:antpoltltcond-regular.otf at 42pt +\endlisting + +The next example shows how to load the \emphasis{Porson} font digitized by +the Greek Font Society using \XETEX-style syntax and an absolute path from a +non-standard directory: + +\beginlisting + \font \gfsporson = "[/tmp/GFSPorson.otf]" at 12pt +\endlisting + +\endsubsubsection + +\beginsubsubsection{Loading by Font Name} + +The \inlinecode {name:} lookup does not depend on cryptic filenames: + +\beginlisting + \font \pagellaregular = {name:TeX Gyre Pagella} at 9pt +\endlisting + +A bit more specific but essentially the same lookup would be: + +\beginlisting + \font \pagellaregular = {name:TeX Gyre Pagella Regular} at 9pt +\endlisting + +\noindent +Which fits nicely with the whole set: + +\beginlisting + \font\pagellaregular = {name:TeX Gyre Pagella Regular} at 9pt + \font\pagellaitalic = {name:TeX Gyre Pagella Italic} at 9pt + \font\pagellabold = {name:TeX Gyre Pagella Bold} at 9pt + \font\pagellabolditalic = {name:TeX Gyre Pagella Bolditalic} at 9pt + + {\pagellaregular foo bar baz\endgraf} + {\pagellaitalic foo bar baz\endgraf} + {\pagellabold foo bar baz\endgraf} + {\pagellabolditalic foo bar baz\endgraf} + + ... +\endlisting + +\endsubsubsection + +\beginsubsubsection{Modifiers} + +If the entire \emphasis{Iwona} family\footnote{% + \hyperlink {http://jmn.pl/kurier-i-iwona/}, + also in \TEX Live. +} +is installed in some location accessible by \identifier{luaotfload}, +the regular shape can be loaded as follows: + +\beginlisting + \font \iwona = Iwona at 20pt +\endlisting + +\noindent +To load the most common of the other styles, the slash notation can +be employed as shorthand: + +\beginlisting + \font \iwonaitalic = Iwona/I at 20pt + \font \iwonabold = Iwona/B at 20pt + \font \iwonabolditalic = Iwona/BI at 20pt +\endlisting + +\noindent +which is equivalent to these full names: + +\beginlisting + \font \iwonaitalic = "Iwona Italic" at 20pt + \font \iwonabold = "Iwona Bold" at 20pt + \font \iwonabolditalic = "Iwona BoldItalic" at 20pt +\endlisting + +\endsubsubsection +\endsubsection +\endsection + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\beginsection {Font features} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\emphasis{Font features} are the second to last component in the +general scheme for font requests: + +\beginnarrower + \nonproportional{\string\font\string\foo\space= "}% + \meta{prefix}% + \nonproportional{:}% + \meta{font name}% + \nonproportional{:}% + \meta{font features}% + \meta{\TEX font features}% + \nonproportional{"} +\endnarrower + +\noindent +If style modifiers are present (\XETEX style), they must precede +\meta{font features}. + +The element \meta{font features} is a semicolon-separated list of feature +tags\footnote{% + Cf. \hyperlink {http://www.microsoft.com/typography/otspec/featurelist.htm}. +} +and font options. +% +Prepending a font feature with a \inlinecode{+} (plus sign) enables it, +whereas a \inlinecode{-} (minus) disables it. For instance, the request + +\beginlisting + \font \test = LatinModernRoman:+clig;-kern +\endlisting + +\noindent activates contextual ligatures (\inlinecode{clig}) and +disables kerning (\inlinecode{kern}). +% +Alternatively the options \inlinecode{true} or \inlinecode{false} can +be passed to the feature in a key/value expression. +% +The following request has the same meaning as the last one: + +\beginlisting + \font \test = LatinModernRoman:clig=true;kern=false +\endlisting + +\noindent +Furthermore, this second syntax is required should a font feature +accept other options besides a true/false switch. +% +For example, \emphasis{stylistic alternates} (\inlinecode{salt}) are +variants of given glyphs. +% +They can be selected either explicitly by supplying the variant +index (starting from one), or randomly by setting the value to, +obviously, \inlinecode{random}. + +%% TODO verify that this actually works with a font that supports +%% the salt/random feature!\fi +\beginlisting + \font \librmsaltfirst = LatinModernRoman:salt=1 +\endlisting + +\beginsubsection {Basic font features} + +\begindescriptions + + \beginaltitem {mode} + \identifier{luaotfload} has two \OpenType processing + \emphasis{modes}: + \identifier{base} and \identifier{node}. + + \identifier{base} mode works by mapping \OpenType + features to traditional \TEX ligature and kerning mechanisms. + % + Supporting only non-contextual substitutions and kerning + pairs, it is the slightly faster, albeit somewhat limited, variant. + % + \identifier{node} mode works by processing \TeX’s internal + node list directly at the \LUA end and supports + a wider range of \OpenType features. + % + The downside is that the intricate operations required for + \identifier{node} mode may slow down typesetting especially + with complex fonts and it does not work in math mode. + + By default \identifier{luaotfload} is in \identifier{node} + mode, and \identifier{base} mode has to be requested where needed, + e.~g. for math fonts. + \endaltitem + + \beginaltitem {script} \label{script-tag} + An \OpenType script tag;\footnote{% + See \hyperlink {http://www.microsoft.com/typography/otspec/scripttags.htm} + for a list of valid values. + % + For scripts derived from the Latin alphabet the value + \inlinecode{latn} is good choice. + } + the default value is \inlinecode{dlft}. + % + Some fonts, including very popular ones by foundries like Adobe, + do not assign features to the \inlinecode{dflt} script, in + which case the script needs to be set explicitly. + \endaltitem + + \beginaltitem {language} + An \OpenType language system identifier,\footnote{% + Cf. \hyperlink {http://www.microsoft.com/typography/otspec/languagetags.htm}. + } + defaulting to \inlinecode{dflt}. + \endaltitem + + \beginaltitem {featurefile} + A comma-separated list of feature files to be applied to the + font. + % + Feature files contain a textual representation of + \OpenType tables and extend the features of a font + on fly. + % + After they are applied to a font, features defined in a + feature file can be enabled or disabled just like any + other font feature. + % + The syntax is documented in \identifier{Adobe}’s + \OpenType Feature File Specification.\footnote{% + Cf. \hyperlink {http://www.adobe.com/devnet/opentype/afdko/topic_feature_file_syntax.html}. + Feature file support is part of the engine which at the + time of this writing (2014) implements the spec only + partially. + See the + \hyperlink [\LUATEX tracker]{http://tracker.luatex.org/view.php?id=231} + for details. + } + + For a demonstration of how to set a \inlinecode{tkrn} feature consult + the file \inlinecode{tkrn.fea} that is part of \identifier{luaotfload}. + It can be read and applied as follows: + + \inlinecode{\\font \\test = Latin Modern Roman:featurefile=tkrn.fea;+tkrn} + \endaltitem + + \beginaltitem {color} + A font color, defined as a triplet of two-digit hexadecimal + \abbrev{rgb} values, with an optional fourth value for + transparency + (where \inlinecode{00} is completely transparent and + \inlinecode{FF} is opaque). + + For example, in order to set text in semitransparent red: + + \beginlisting +\font \test = "Latin Modern Roman:color=FF0000BB" + \endlisting + \endaltitem + + \beginaltitem {kernfactor \& letterspace} + Define a font with letterspacing (tracking) enabled. + % + In \identifier{luaotfload}, letterspacing is implemented by + inserting additional kerning between glyphs. + + This approach is derived from and still quite similar to the + \emphasis{character kerning} (\texmacro{setcharacterkerning} / + \texmacro{definecharacterkerning} \& al.) functionality of + Context, see the file \fileent{typo-krn.lua} there. + % + The main difference is that \identifier{luaotfload} does not + use \LUATEX attributes to assign letterspacing to regions, + but defines virtual letterspaced versions of a font. + + The option \identifier{kernfactor} accepts a numeric value that + determines the letterspacing factor to be applied to the font + size. + % + E.~g. a kern factor of $0.42$ applied to a $10$ pt font + results in $4.2$ pt of additional kerning applied to each + pair of glyphs. + % + Ligatures are split into their component glyphs unless + explicitly ignored (see below). + + For compatibility with \XETEX an alternative + \identifier{letterspace} option is supplied that interprets the + supplied value as a \emphasis{percentage} of the font size but + is otherwise identical to \identifier{kernfactor}. + % + Consequently, both definitions in below snippet yield the same + letterspacing width: + + \beginlisting +\font \iwonakernedA = "file:Iwona-Regular.otf:kernfactor=0.125" +\font \iwonakernedB = "file:Iwona-Regular.otf:letterspace=12.5" + \endlisting + + Specific pairs of letters and ligatures may be exempt from + letterspacing by defining the \LUA functions + \luafunction{keeptogether} and \luafunction{keepligature}, + respectively, inside the namespace \inlinecode {luaotfload.letterspace}. + % + Both functions are called whenever the letterspacing callback + encounters an appropriate node or set of nodes. + % + If they return a true-ish value, no extra kern is inserted at + the current position. + % + \luafunction{keeptogether} receives a pair of consecutive + glyph nodes in order of their appearance in the node list. + % + \luafunction{keepligature} receives a single node which can be + analyzed into components. + % + (For details refer to the \emphasis{glyph nodes} section in the + \LUATEX reference manual.) + % + The implementation of both functions is left entirely to the + user. + \endaltitem + +\ifcontextmkiv + \startbuffer [printvectors] + \directlua{inspect(fonts.protrusions.setups.default) + inspect(fonts.expansions.setups.default)} + \stopbuffer +\fi + + \beginaltitem {protrusion \& expansion} + These keys control microtypographic features of the font, + namely \emphasis{character protrusion} and \emphasis{font + expansion}. + % + Their arguments are names of \LUA tables that contain + values for the respective features.\footnote{% + For examples of the table layout please refer to the + section of the file \fileent{luaotfload-fonts-ext.lua} where the + default values are defined. + % + Alternatively and with loss of information, you can dump + those tables into your terminal by issuing + \unless \ifcontextmkiv + \beginlisting + \directlua{inspect(fonts.protrusions.setups.default) + inspect(fonts.expansions.setups.default)} + \endlisting + \else + \typebuffer [printvectors] + \fi + at some point after loading \fileent{luaotfload.sty}. + } + % + For both, only the set \identifier{default} is predefined. + + For example, to define a font with the default + protrusion vector applied\footnote{% + You also need to set + \inlinecode {pdfprotrudechars=2} and + \inlinecode {pdfadjustspacing=2} + to activate protrusion and expansion, respectively. + See the + \hyperlink [\PDFTEX manual]{http://mirrors.ctan.org/systems/pdftex/manual/pdftex-a.pdf}% + for details. + }: + + \beginlisting +\font \test = LatinModernRoman:protrusion=default + \endlisting + \endaltitem +\enddescriptions + +\endsubsection + +\beginsubsection {Non-standard font features} +\identifier{luaotfload} adds a number of features that are not defined +in the original \OpenType specification, most of them +aiming at emulating the behavior familiar from other \TEX engines. +% +Currently (2014) there are three of them: + +\begindescriptions + + \beginaltitem {anum} + Substitutes the glyphs in the \abbrev{ascii} number range + with their counterparts from eastern Arabic or Persian, + depending on the value of \identifier{language}. + \endaltitem + + \beginaltitem {tlig} + Applies legacy \TEX ligatures\footnote{% + These contain the feature set \inlinecode {trep} of earlier + versions of \identifier{luaotfload}. + + Note to \XETEX users: this is the equivalent of the + assignment \inlinecode {mapping=text-tex} using \XETEX's input + remapping feature. + }: + + \unless \ifcontextmkiv + %% Using braced arg syntax with inline code appears to be + %% impossible within Latex tables -- just ignore the weird + %% exclamation points below. + \begintabulate [rlrl] + \beginrow `` \newcell {\inlinecode !``! } \newcell '' \newcell {\inlinecode !''!} \endrow + \beginrow ` \newcell {\inlinecode !`! } \newcell ' \newcell {\inlinecode !'! } \endrow + \beginrow " \newcell {\inlinecode !"! } \newcell -- \newcell {\inlinecode !--!} \endrow + \beginrow --- \newcell {\inlinecode !---!} \newcell !` \newcell {\inlinecode ?!`?} \endrow + \beginrow ?` \newcell {\inlinecode !?`! } \newcell \newcell \endrow + \endtabulate + \else + %% XXX find a way to wrap these in the tabulate environment + \startframed [frame=off,width=broad,align=middle] + \startframed [frame=off,width=\dimexpr(\textwidth/2)] + \startxtable [align=middle] + \startxrow \startxcell `` \stopxcell \startxcell \inlinecode {``} \stopxcell \startxcell '' \stopxcell \startxcell \inlinecode {''} \stopxcell \stopxrow + \startxrow \startxcell ` \stopxcell \startxcell \inlinecode {`} \stopxcell \startxcell ' \stopxcell \startxcell \inlinecode {'} \stopxcell \stopxrow + \startxrow \startxcell " \stopxcell \startxcell \inlinecode {"} \stopxcell \startxcell -- \stopxcell \startxcell \inlinecode {--} \stopxcell \stopxrow + \startxrow \startxcell --- \stopxcell \startxcell \inlinecode {---} \stopxcell \startxcell !` \stopxcell \startxcell \inlinecode {!`} \stopxcell \stopxrow + \startxrow \startxcell ?` \stopxcell \startxcell \inlinecode {?`} \stopxcell \startxcell \stopxcell \startxcell \stopxcell \stopxrow + \stopxtable + \stopframed + \stopframed + \fi + \endaltitem + + \beginaltitem {itlc} + Computes italic correction values (active by default). + \endaltitem + +\enddescriptions + +\endsubsection +\endsection + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\beginsection {Font names database} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\label{sec:fontdb} + +As mentioned above, \identifier{luaotfload} keeps track of which +fonts are available to \LUATEX by means of a \emphasis{database}. +% +This allows referring to fonts not only by explicit filenames but +also by the proper names contained in the metadata which is often +more accessible to humans.\footnote{% + The tool \hyperlink[\fileent{otfinfo}]{http://www.lcdf.org/type/} + (comes with \TEX Live), when invoked on a font file with the + \inlinecode {-i} option, lists the variety of name fields defined for + it. +} + +When \identifier{luaotfload} is asked to load a font by a font name, +it will check if the database exists and load it, or else generate a +fresh one. +% +Should it then fail to locate the font, an update to the database is +performed in case the font has been added to the system only +recently. +% +As soon as the database is updated, the resolver will try +and look up the font again, all without user intervention. +% +The goal is for \identifier{luaotfload} to act in the background and +behave as unobtrusively as possible, while providing a convenient +interface to the fonts installed on the system. + +Generating the database for the first time may take a while since it +inspects every font file on your computer. +% +This is particularly noticeable if it occurs during a typesetting run. +In any case, subsequent updates to the database will be quite fast. + +\beginsubsection[luaotfload-tool] + {\fileent{luaotfload-tool}} + +It can still be desirable at times to do some of these steps +manually, and without having to compile a document. +% +To this end, \identifier{luaotfload} comes with the utility +\fileent{luaotfload-tool} that offers an interface to the database +functionality. +% +Being a \LUA script, there are two ways to run it: +either make it executable (\inlinecode {chmod +x} on unixoid systems) or +pass it as an argument to \fileent{texlua}.\footnote{% + Tests by the maintainer show only marginal performance gain by + running with Luigi Scarso’s + \hyperlink [\identifier{Luajit\kern-.25ex\TEX}]{https://foundry.supelec.fr/projects/luajittex/}, + which is probably due to the fact that most of the time is spent + on file system operations. + + \emphasis{Note}: + On \abbrev{MS} \identifier{Windows} systems, the script can be run + either by calling the wrapper application + \fileent{luaotfload-tool.exe} or as + \inlinecode {texlua.exe luaotfload-tool.lua}. +} +% +Invoked with the argument \inlinecode {--update} it will perform a database +update, scanning for fonts not indexed. + +\beginlisting + luaotfload-tool --update +\endlisting + +Adding the \inlinecode {--force} switch will initiate a complete +rebuild of the database. + +\beginlisting + luaotfload-tool --update --force +\endlisting + +\endsubsection + +\beginsubsection{Search Paths} + +\identifier{luaotfload} scans those directories where fonts are +expected to be located on a given system. +% +On a Linux machine it follows the paths listed in the +\identifier{Fontconfig} configuration files; +consult \inlinecode {man 5 fonts.conf} for further information. +% +On \identifier{Windows} systems, the standard location is +\inlinecode {Windows\\Fonts}, +% +while \identifier{Mac OS~X} requires a multitude of paths to +be examined. +% +The complete list is is given in table \ref{table-searchpaths}. +Other paths can be specified by setting the environment variable +\inlinecode {OSFONTDIR}. +% +If it is non-empty, then search will be extended to the included +directories. + +\tablefloat {table-searchpaths} + {List of paths searched for each supported operating system.} + {% + \unless \ifcontextmkiv + \begincentered + \begintabulate [lp{.5\textwidth}] + \beginrow + Windows \newcell \inlinecode !\% WINDIR\%\\ Fonts! + \endrow + \beginrow + Linux \newcell \fileent{/usr/local/etc/fonts/fonts.conf} and\hfill\break + \fileent{/etc/fonts/fonts.conf} + \endrow + \beginrow + Mac \newcell \fileent{\textasciitilde/Library/Fonts},\break + \fileent{/Library/Fonts},\break + \fileent{/System/Library/Fonts}, and\hfill\break + \fileent{/Network/Library/Fonts} + \endrow + \endtabulate + \endcentered + \else + \setuplocalinterlinespace [14pt] + \starttabulate [|l|p(.5\textwidth)|] + \NC Windows \NC \inlinecode {\% WINDIR\%\\ Fonts} \NC \NR + \NC Linux \NC \fileent{/usr/local/etc/fonts/fonts.conf} and\crlf + \fileent{/etc/fonts/fonts.conf} \NC \NR + \NC + Mac \NC \fileent{\textasciitilde/Library/Fonts},\crlf + \fileent{/Library/Fonts},\break + \fileent{/System/Library/Fonts}, and\crlf + \fileent{/Network/Library/Fonts} \NC \NR + \stoptabulate + \fi% + } + +\endsubsection + +\beginsubsection{Querying from Outside} + +\fileent{luaotfload-tool} also provides rudimentary means of +accessing the information collected in the font database. +% +If the option \inlinecode {--find=}\emphasis{name} is given, the script will +try and search the fonts indexed by \identifier{luaotfload} for a +matching name. +% +For instance, the invocation + +\beginlisting + luaotfload-tool --find="Iwona Regular" +\endlisting + +\noindent +will verify if “Iwona Regular” is found in the database and can be +readily requested in a document. + +If you are unsure about the actual font name, then add the +\inlinecode {-F} (or \inlinecode {--fuzzy}) switch to the command line to enable +approximate matching. +% +Suppose you cannot precisely remember if the variant of +\identifier{Iwona} you are looking for was “Bright” or “Light”. +The query + +\beginlisting + luaotfload-tool -F --find="Iwona Bright" +\endlisting + +\noindent +will tell you that indeed the latter name is correct. + +Basic information about fonts in the database can be displayed +using the \inlinecode {-i} option (\inlinecode {--info}). +% +\beginlisting + luaotfload-tool -i --find="Iwona Light Italic" +\endlisting +% +\noindent +The meaning of the printed values is described in section 4.4 of the +\LUATEX reference manual.\footnote{% + In \TEX Live: \fileent{texmf-dist/doc/luatex/base/luatexref-t.pdf}. +} + +For a much more detailed report about a given font try the +\inlinecode {-I} option instead (\inlinecode {--inspect}). +\beginlisting + luaotfload-tool -I --find="Iwona Light Italic" +\endlisting + +\inlinecode {luaotfload-tool --help} will list the available command line +switches, including some not discussed in detail here. +% +For a full documentation of \identifier{luaotfload-tool} and its +capabilities refer to the manpage +(\inlinecode {man 1 luaotfload-tool}).\footnote{% + Or see \inlinecode {luaotfload-tool.rst} in the source directory. +} + +\endsubsection + +\beginsubsection {Blacklisting Fonts} +\label{font-blacklist} + +Some fonts are problematic in general, or just in \LUATEX. +% +If you find that compiling your document takes far too long or eats +away all your system’s memory, you can track down the culprit by +running \inlinecode {luaotfload-tool -v} to increase verbosity. +% +Take a note of the \emphasis{filename} of the font that database +creation fails with and append it to the file +\fileent{luaotfload-blacklist.cnf}. + +A blacklist file is a list of font filenames, one per line. +Specifying the full path to where the file is located is optional, the +plain filename should suffice. +% +File extensions (\fileent{.otf}, \fileent{.ttf}, etc.) may be omitted. +% +Anything after a percent (\inlinecode {\%}) character until the end of the line +is ignored, so use this to add comments. +% +Place this file to some location where the \identifier{kpse} +library can find it, e.~g. +\fileent{texmf-local/tex/luatex/luaotfload} if you are running +\identifier{\TEX Live},\footnote{% + You may have to run \inlinecode {mktexlsr} if you created a new file in + your \fileent{texmf} tree. +} +or just leave it in the working directory of your document. +% +\identifier{luaotfload} reads all files named +\fileent{luaotfload-blacklist.cnf} it finds, so the fonts in +\fileent{./luaotfload-blacklist.cnf} extend the global blacklist. + +Furthermore, a filename prepended with a dash character (\inlinecode{-}) is +removed from the blacklist, causing it to be temporarily whitelisted +without modifying the global file. +% +An example with explicit paths: + +\beginlisting +% example otf-blacklist.cnf +/Library/Fonts/GillSans.ttc % Luaotfload ignores this font. +-/Library/Fonts/Optima.ttc % This one is usable again, even if + % blacklisted somewhere else. +\endlisting + +\endsubsection +\endsection + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\beginsection {Files from \CONTEXT and \LUATEX-Fonts} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\identifier{luaotfload} relies on code originally written by Hans +Hagen for the \hyperlink[\identifier{\CONTEXT}]{http://wiki.contextgarden.net} +format. +% +It integrates the font loader as distributed in +the \identifier{\LUATEX-Fonts} package. +% +The original \LUA source files have been combined using the +\fileent{mtx-package} script into a single, self-contained blob. +In this form the font loader has no further dependencies\footnote{% + It covers, however, to some extent the functionality of the + \identifier{lualibs} package. +} +and requires only minor adaptions to integrate into +\identifier{luaotfload}. +% +The guiding principle is to let \CONTEXT/\LUATEX-Fonts take care of +the implementation, and update the imported code from time to time. +% +As maintainers, we aim at importing files from upstream essentially +\emphasis{unmodified}, except for renaming them to prevent name +clashes. +% +This job has been greatly alleviated since the advent of +\LUATEX-Fonts, prior to which the individual dependencies had to be +manually spotted and extracted from the \CONTEXT source code in a +complicated and error-prone fashion. + +Below is a commented list of the files distributed with +\identifier{luaotfload} in one way or the other. +% +See figure \ref{file-graph} on page \pageref{file-graph} for a +graphical representation of the dependencies. +% +From \LUATEX-Fonts, only the file \fileent{luatex-fonts-merged.lua} +has been imported as \fileent{luaotfload-fontloader.lua}. +% +It is generated by \fileent{mtx-package}, a \LUA source code merging +too developed by Hans Hagen.\footnote{% + \fileent{mtx-package} is + \hyperlink [part of \CONTEXT]{http://repo.or.cz/w/context.git/blob_plain/refs/heads/origin:/scripts/context/lua/mtx-package.lua} + and requires \fileent{mtxrun}. + Run + \inlinecode {mtxrun --script package --help} + to display further information. + For the actual merging code see the file + \fileent{util-mrg.lua} that is part of \CONTEXT. +} +It houses several \LUA files that can be classed in three +categories. + +\begindefinitions + \beginnormalitem + \emphasis{\LUA utility libraries}, a subset + of what is provided by the \identifier{lualibs} + package. + + \begindoublecolumns + \begindefinitions + \beginaltitem {l-lua.lua} \endaltitem + \beginaltitem {l-lpeg.lua} \endaltitem + \beginaltitem {l-function.lua} \endaltitem + \beginaltitem {l-string.lua} \endaltitem + \beginaltitem {l-table.lua} \endaltitem + \beginaltitem {l-io.lua} \endaltitem + \beginaltitem {l-file.lua} \endaltitem + \beginaltitem {l-boolean.lua} \endaltitem + \beginaltitem {l-math.lua} \endaltitem + \beginaltitem {util-str.lua} \endaltitem + \enddefinitions + \enddoublecolumns + \endnormalitem + + \beginnormalitem + The \emphasis{font loader} itself. + These files have been written for + \LUATEX-Fonts and they are distributed along + with \identifier{luaotfload}. + \begindoublecolumns + \begindefinitions + \beginaltitem{luatex-basics-gen.lua} \endaltitem + \beginaltitem{luatex-basics-nod.lua} \endaltitem + \beginaltitem{luatex-fonts-enc.lua} \endaltitem + \beginaltitem{luatex-fonts-syn.lua} \endaltitem + \beginaltitem{luatex-fonts-tfm.lua} \endaltitem + \beginaltitem{luatex-fonts-chr.lua} \endaltitem + \beginaltitem{luatex-fonts-lua.lua} \endaltitem + \beginaltitem{luatex-fonts-inj.lua} \endaltitem + \beginaltitem{luatex-fonts-otn.lua} \endaltitem + \beginaltitem{luatex-fonts-def.lua} \endaltitem + \beginaltitem{luatex-fonts-ext.lua} \endaltitem + \beginaltitem{luatex-fonts-cbk.lua} \endaltitem + \enddefinitions + \enddoublecolumns + \endnormalitem + + \beginnormalitem + Code related to \emphasis{font handling and + node processing}, taken directly from + \CONTEXT. + \begindoublecolumns + \begindefinitions + \beginaltitem{data-con.lua} \endaltitem + \beginaltitem{font-ini.lua} \endaltitem + \beginaltitem{font-con.lua} \endaltitem + \beginaltitem{font-cid.lua} \endaltitem + \beginaltitem{font-map.lua} \endaltitem + \beginaltitem{font-oti.lua} \endaltitem + \beginaltitem{font-otf.lua} \endaltitem + \beginaltitem{font-otb.lua} \endaltitem + \beginaltitem{font-ota.lua} \endaltitem + \beginaltitem{font-def.lua} \endaltitem + \beginaltitem{font-otp.lua} \endaltitem + \enddefinitions + \enddoublecolumns + \endnormalitem +\enddefinitions + +Note that if \identifier{luaotfload} cannot locate the +merged file, it will load the individual \LUA libraries +instead. +% +Their names remain the same as in \CONTEXT (without the +\inlinecode {otfl}-prefix) since we imported the relevant section of +\fileent{luatex-fonts.lua} unmodified into \fileent{luaotfload-main.lua}. +Thus if you prefer running bleeding edge code from the +\CONTEXT beta, all you have to do is remove +\fileent{luaotfload-merged.lua} from the search path. + +Also, the merged file at some point loads the Adobe Glyph List from a +\LUA table that is contained in \fileent{luaotfload-glyphlist.lua}, +which is automatically generated by the script +\fileent{mkglyphlist}.\footnote{% + See \fileent{luaotfload-font-enc.lua}. + The hard-coded file name is why we have to replace the procedure + that loads the file in \fileent{luaotfload-override.lua}. +} +There is a make target \identifier{glyphs} that will create a fresh +glyph list so we don’t need to import it from \CONTEXT any longer. + +In addition to these, \identifier{luaotfload} requires a number of +files not contained in the merge. Some of these have no equivalent in +\LUATEX-Fonts or \CONTEXT, some were taken unmodified from the latter. + + +\beginfilelist + \beginaltitem {luaotfload-features.lua} + font feature handling; incorporates some of the code from + \fileent{font-otc} from \CONTEXT; + \endaltitem + \beginaltitem {luaotfload-override.lua} + overrides the \CONTEXT logging functionality. + \endaltitem + \beginaltitem {luaotfload-loaders.lua} + registers the \OpenType font reader as handler for Postscript + fonts (\abbrev{pfa}, \abbrev{pfb}). + \endaltitem + \beginaltitem {luaotfload-parsers.lua} + various \abbrev{lpeg}-based parsers. + \endaltitem + \beginaltitem {luaotfload-database.lua} + font names database. + \endaltitem + \beginaltitem {luaotfload-colors.lua} + color handling. + \endaltitem + \beginaltitem {luaotfload-auxiliary.lua} + access to internal functionality for package authors (proposals + for additions welcome). + \endaltitem + \beginaltitem {luaotfload-letterspace.lua} + font-based letterspacing. + \endaltitem +\endfilelist + +\figurefloat + {file-graph} + {Schematic of the files in \identifier{Luaotfload}} + {filegraph.pdf} + +\endsection + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\beginsection {Auxiliary Functions} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +With release version 2.2, \identifier{luaotfload} received +additional functions for package authors to call from outside +(see the file \fileent{luaotfload-auxiliary.lua} for details). +% +The purpose of this addition twofold. +% +Firstly, \identifier{luaotfload} failed to provide a stable interface +to internals in the past which resulted in an unmanageable situation +of different packages abusing the raw access to font objects by means +of the \luafunction{patch_font} callback. +% +When the structure of the font object changed due to an update, all +of these imploded and several packages had to be fixed while +simultaneously providing fallbacks for earlier versions. +% +Now the patching is done on the \identifier{luaotfload} side and can +be adapted with future modifications to font objects without touching +the packages that depend on it. +% +Second, some the capabilities of the font loader and the names +database are not immediately relevant in \identifier{luaotfload} +itself but might nevertheless be of great value to package authors or +end users. + +Note that the current interface is not yet set in stone and the +development team is open to suggestions for improvements or +additions. + +\beginsubsection {Callback Functions} + +The \luafunction{patch_font} callback is inserted in the wrapper +\identifier{luaotfload} provides for the font definition callback. +% +At this place it allows manipulating the font object immediately after +the font loader is done creating it. +% +For a short demonstration of its usefulness, here is a snippet that +writes an entire font object to the file \fileent{fontdump.lua}: + +\beginlisting + \input luaotfload.sty + \directlua{ + local dumpfile = "fontdump.lua" + local dump_font = function (tfmdata) + local data = table.serialize(tfmdata) + io.savedata(dumpfile, data) + end + + luatexbase.add_to_callback( + "luaotfload.patch_font", + dump_font, + "my_private_callbacks.dump_font" + ) + } + \font \dumpme = name:Iwona + \bye +\endlisting + +\emphasis{Beware}: this creates a Lua file of around 150,000 lines of +code, taking up 3~\abbrev{mb} of disk space. +% +By inspecting the output you can get a first impression of how a font +is structured in \LUATEX’s memory, what elements it is composed of, +and in what ways it can be rearranged. + +\beginsubsubsection {Compatibility with Earlier Versions} + +As has been touched on in the preface to this section, the structure +of the object as returned by the fontloader underwent rather drastic +changes during different stages of its development, and not all +packages that made use of font patching have kept up with every one +of it. +% +To ensure compatibility with these as well as older versions of +some packages, \identifier{luaotfload} sets up copies of or references +to data in the font table where it used to be located. +% +For instance, important parameters like the requested point size, the +units factor, and the font name have again been made accessible from +the toplevel of the table even though they were migrated to different +subtables in the meantime. + +\endsubsubsection + +\beginsubsubsection{Patches} + +These are mostly concerned with establishing compatibility with \XETEX. + +\beginfunctionlist + + \beginaltitem {set_sscale_dimens} + Calculate \texmacro{fontdimen}s 10 and 11 to emulate \XETEX. + \endaltitem + + \beginaltitem {set_capheight} + Calculates \texmacro{fontdimen} 8 like \XETEX. + \endaltitem + + \beginaltitem {patch_cambria_domh} + Correct some values of the font \emphasis{Cambria Math}. + \endaltitem + +\endfunctionlist + +\endsubsection + +\beginsubsection {Package Author’s Interface} + +As \LUATEX release 1.0 is nearing, the demand for a reliable interface +for package authors increases. + +\endsubsubsection + +\beginsubsubsection{Font Properties} + +Below functions mostly concern querying the different components of a +font like for instance the glyphs it contains, or what font features +are defined for which scripts. + +\beginfunctionlist + + \beginaltitem {aux.font_has_glyph (id : int, index : int)} + Predicate that returns true if the font \luafunction{id} + has glyph \luafunction{index}. + \endaltitem + + \beginaltitem {aux.slot_of_name(name : string)} + Translates an Adobe Glyph name to the corresponding glyph + slot. + \endaltitem + + \beginaltitem {aux.name_of_slot(slot : int)} + The inverse of \luafunction{slot_of_name}; note that this + might be incomplete as multiple glyph names may map to the + same codepoint, only one of which is returned by + \luafunction{name_of_slot}. + \endaltitem + + \beginaltitem {aux.provides_script(id : int, script : string)} + Test if a font supports \luafunction{script}. + \endaltitem + + \beginaltitem {aux.provides_language(id : int, script : string, language : string)} + Test if a font defines \luafunction{language} for a given + \luafunction{script}. + \endaltitem + + \beginaltitem {aux.provides_feature(id : int, script : string, + language : string, feature : string)} + Test if a font defines \luafunction{feature} for + \luafunction{language} for a given \luafunction{script}. + \endaltitem + + \beginaltitem {aux.get_math_dimension(id : int, dimension : string)} + Get the dimension \luafunction{dimension} of font \luafunction{id}. + \endaltitem + + \beginaltitem {aux.sprint_math_dimension(id : int, dimension : string)} + Same as \luafunction{get_math_dimension()}, but output the value + in scaled points at the \TEX end. + \endaltitem + +\endfunctionlist + +\endsubsubsection + +\beginsubsubsection{Database} + +%% not implemented, may come back later +\beginfunctionlist +% \beginaltitem {aux.scan_external_dir(dir : string)} +% Include fonts in directory \luafunction{dir} in font lookups without +% adding them to the database. +% + \beginaltitem {aux.read_font_index (void)} + Read the index file from the appropriate location (usually + the bytecode file \fileent{luaotfload-names.luc} somewhere + in the \fileent{texmf-var} tree) and return the result as a + table. The file is processed with each call so it is up to + the user to store the result for later access. + \endaltitem + + \beginaltitem {aux.font_index (void)} + Return a reference of the font names table used internally + by \identifier{luaotfload}. The index will be read if it + has not been loaded up to this point. Also a font scan that + overwrites the current index file might be triggered. Since + the return value points to the actual index, any + modifications to the table might influence runtime behavior + of \identifier{luaotfload}. + \endaltitem + +\endfunctionlist + +\endsubsubsection + +\endsubsection +\endsection + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\beginsection {Troubleshooting} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\beginsubsection {Database Generation} + +If you encounter problems with some fonts, please first update to the +latest version of this package before reporting a bug, as +\identifier{luaotfload} is under active development and still a moving +target. +% +The development takes place on \identifier{github} at +\hyperlink {https://github.com/lualatex/luaotfload} where there is an issue +tracker for submitting bug reports, feature requests and the likes. + +Bug reports are more likely to be addressed if they contain the output +of + +\beginlisting + luaotfload-tool --diagnose=environment,files,permissions +\endlisting + +\noindent Consult the man page for a description of these options. + +Errors during database generation can be traced by increasing the +verbosity level and redirecting log output to \fileent{stdout}: + +\beginlisting + luaotfload-tool -fuvvv --log=stdout +\endlisting + +\noindent or to a file in \fileent{/tmp}: + +\beginlisting + luaotfload-tool -fuvvv --log=file +\endlisting + +\noindent In the latter case, invoke the \inlinecode {tail(1)} utility on the +file for live monitoring of the progress. + +If database generation fails, the font last printed to the terminal or +log file is likely to be the culprit. +% +Please specify it when reporting a bug, and blacklist it for the time +being (see above, page \pageref{font-blacklist}). + +\endsubsection + +\beginsubsection {Font Features} + +A common problem is the lack of features for some +\OpenType fonts even when specified. +% +This can be related to the fact that some fonts do not provide features +for the \inlinecode {dflt} script (see above on page \pageref{script-tag}), +which is the default one in this package. +% +If this happens, assigning a noth script when the font is defined should +fix it. +% +For example with \inlinecode {latn}: + +\beginlisting + \font \test = file:MyFont.otf:script=latn;+liga; +\endlisting + +You can get a list of features that a font defines for scripts and +languages by querying it in \fileent{luaotfload-tool}: + +\beginlisting + luaotfload-tool --find="Iwona" --inspect +\endlisting + +\endsubsection + +\beginsubsection {\LUATEX Programming} + +Another strategy that helps avoiding problems is to not access raw +\LUATEX internals directly. +% +Some of them, even though they are dangerous to access, have not been +overridden or disabled. +% +Thus, whenever possible prefer the functions in the \luafunction{aux} +namespace over direct manipulation of font objects. For example, raw +access to the \luafunction{font.fonts} table like: + +\beginlisting + local somefont = font.fonts[2] +\endlisting + +\noindent can render already defined fonts unusable. +% +Instead, the function \luafunction{font.getfont()} should be used +because it has been replaced by a safe variant. + +However, \luafunction{font.getfont()} only covers fonts handled by the +font loader, e.~g. \identifier{OpenType} and \identifier{TrueType} +fonts, but not \abbrev{tfm} or \abbrev{ofm}. +% +Should you absolutely require access to all fonts known to \LUATEX, +including the virtual and autogenerated ones, then you need to query +both \luafunction{font.getfont()} and \luafunction{font.fonts}. +% +In this case, best define you own accessor: + +\beginlisting + local unsafe_getfont = function (id) + local tfmdata = font.getfont (id) + if not tfmdata then + tfmdata = font.fonts[id] + end + return tfmdata + end + + --- use like getfont() + local somefont = unsafe_getfont (2) +\endlisting + +\endsubsection +\endsection + +\beginsection {License} + +\identifier {luaotfload} is licensed under the terms of the +\hyperlink [GNU General Public License version 2.0]% + {https://www.gnu.org/licenses/old-licenses/gpl-2.0.html}. +Following the underlying fontloader code \identifier {luaotfload} +recognizes only that exact version as its license. +The „any later version” clause of the original license text as +copyrighted by the \hyperlink [Free Software Foundation]{http://www.fsf.org/} +\emphasis {does not apply} to either \identifier {luaotfload} or the +code imported from \CONTEXT. + +The complete text of the license is given as a separate file \fileent +{COPYING} in the toplevel directory of the +\hyperlink [\fileent {Luaotfload} Git repository]{https://github.com/lualatex/luaotfload/blob/master/COPYING}. +Distributions probably package it as \fileent +{doc/luatex/luaotfload/COPYING} in the relevant \fileent {texmf} tree. + +\endsection + +\endinput + diff --git a/Master/texmf-dist/source/luatex/luaotfload/luaotfload-tool.rst b/Master/texmf-dist/source/luatex/luaotfload/luaotfload-tool.rst new file mode 100644 index 00000000000..4b1a93456f3 --- /dev/null +++ b/Master/texmf-dist/source/luatex/luaotfload/luaotfload-tool.rst @@ -0,0 +1,325 @@ +======================================================================= + luaotfload-tool +======================================================================= + +----------------------------------------------------------------------- + generate and query the Luaotfload font names database +----------------------------------------------------------------------- + +:Date: 2014-03-30 +:Copyright: GPL v2.0 +:Version: 2.5 +:Manual section: 1 +:Manual group: text processing + +SYNOPSIS +======================================================================= + +**luaotfload-tool** [ -bcDfFiIlLnpqRSuvVhw ] + +**luaotfload-tool** --update [ --force ] [ --quiet ] [ --verbose ] + [ --prefer-texmf ] [ --dry-run ] + [ --formats=[+|-]EXTENSIONS ] + [ --no-compress ] [ --no-strip ] + [ --local ] [ --max-fonts=N ] + +**luaotfload-tool** --find=FONTNAME [ --fuzzy ] [ --info ] [ --inspect ] + [ --no-reload ] + +**luaotfload-tool** --flush-lookups + +**luaotfload-tool** --cache=DIRECTIVE + +**luaotfload-tool** --list=CRITERION[:VALUE] [ --fields=F1,F2,...,Fn ] + +**luaotfload-tool** --bisect=DIRECTIVE + +**luaotfload-tool** --help + +**luaotfload-tool** --version + +**luaotfload-tool** --show-blacklist + +**luaotfload-tool** --diagnose=CHECK + +DESCRIPTION +======================================================================= + +luaotfload-tool accesses the font names database that is required by +the *Luaotfload* package. There are two general modes: **update** and +**query**. + ++ **update**: update the database or rebuild it entirely; ++ **query**: resolve a font name or display close matches. + +OPTIONS +======================================================================= + +update mode +----------------------------------------------------------------------- +--update, -u Update the database; indexes new fonts. +--force, -f Force rebuilding of the database; re-indexes + all fonts. +--local, -L Include font files in ``$PWD``. This option + will cause large parts of the database to be + rebuilt. Thus it is quite inefficient. + Additionally, if local font files are found, + the database is prevented from being saved + to disk, so the local fonts need to be parsed + with every invocation of ``luaotfload-tool``. +--no-reload, -n Suppress auto-updates to the database (e.g. + when ``--find`` is passed an unknown name). +--no-compress, -c Do not filter the plain text version of the + font index through gzip. Useful for debugging + if your editor is built without zlib. + +--prefer-texmf, -p Organize the file name database in a way so + that it prefer fonts in the *TEXMF* tree over + system fonts if they are installed in both. +--formats=EXTENSIONS Extensions of the font files to index. + Where *EXTENSIONS* is a comma-separated list of + supported file extensions (otf, ttf, ttc, + dfont, pfa, and pfb). If the list is prefixed + with a ``+`` sign, the given list is added to + the currently active one; ``-`` subtracts. + Default: *otf,ttf,ttc,dfont*. + Examples: + + 1) ``--formats=-ttc,ttf`` would skip + TrueType fonts and font collections; + 2) ``--formats=otf`` would scan only OpenType + files; + 3) ``--formats=+pfb`` includes binary + Postscript files. **Warning**: with a + standard TeX Live installation this will + grow the database considerably and slow down + font indexing. + +query mode +----------------------------------------------------------------------- +--find=NAME Resolve a font name; this looks up in + the database and prints the file name it is + mapped to. + ``--find`` also understands request syntax, + i.e. ``--find=file:foo.otf`` checks whether + ``foo.otf`` is indexed. +--fuzzy, -F Show approximate matches to the file name if + the lookup was unsuccessful (requires + ``--find``). + +--info, -i Display basic information to a resolved font + file (requires ``--find``). +--inspect, -I Display detailed information by loading the + font and analyzing the font table; very slow! + For the meaning of the returned fields see + the LuaTeX documentation. + (requires ``--find``). +--warnings, -w Print the warnings generated by the fontloader + library (assumes ``-I``). Automatically enabled + if the verbosity level exceeds 2. + +--list=CRITERION Show entries, where *CRITERION* is one of the + following: + + 1) the character ``*``, selecting all entries; + 2) a field of a database entry, for instance + *version* or *format**, according to which + the output will be sorted. + Information in an unstripped database (see + the option ``--no-strip`` above) is nested: + Subfields of a record can be addressed using + the ``->`` separator, e. g. + ``file->location``, ``style->units_per_em``, + or + ``names->sanitized->english->prefmodifiers``. + NB: shell syntax requires that arguments + containing ``->`` be properly quoted! + 3) an expression of the form ``field:value`` to + limit the output to entries whose ``field`` + matches ``value``. + + For example, in order to output file names and + corresponding versions, sorted by the font + format:: + + ./luaotfload-tool.lua --list="format" --fields="file->base,version" + + This prints:: + + otf latinmodern-math.otf Version 1.958 + otf lmromancaps10-oblique.otf 2.004 + otf lmmono8-regular.otf 2.004 + otf lmmonoproplt10-bold.otf 2.004 + otf lmsans10-oblique.otf 2.004 + otf lmromanslant8-regular.otf 2.004 + otf lmroman12-italic.otf 2.004 + otf lmsansdemicond10-oblique.otf 2.004 + ... + +--fields=FIELDS Comma-separated list of fields that should be + printed. + Information in an unstripped database (see the + option ``--no-strip`` above) is nested: + Subfields of a record can be addressed using + the ``->`` separator, e. g. + ``file->location``, ``style->units_per_em``, + or ``names->sanitized->english->subfamily``. + The default is plainname,version*. + (Only meaningful with ``--list``.) + +font and lookup caches +----------------------------------------------------------------------- +--flush-lookups Clear font name lookup cache (experimental). + +--cache=DIRECTIVE Cache control, where *DIRECTIVE* is one of the + following: + + 1) ``purge`` -> delete Lua files from cache; + 2) ``erase`` -> delete Lua and Luc files from + cache; + 3) ``show`` -> print stats. + +debugging methods +----------------------------------------------------------------------- +--show-blacklist, -b Show blacklisted files (not directories). +--dry-run, -D Don’t load fonts when updating the database; + scan directories only. + (For debugging file system related issues.) +--no-strip Do not strip redundant information after + building the database. Warning: this will + inflate the index to about two to three times + the normal size. +--max-fonts=N Process at most *N* font files, including fonts + already indexed in the count. +--bisect=DIRECTIVE Bisection of the font database. + This mode is intended as assistance in + debugging the Luatex engine, especially when + tracking memleaks or buggy fonts. + + *DIRECTIVE* can be one of the following: + + 1) ``run`` -> Make ``luaotfload-tool`` respect + the bisection progress when running. + Combined with ``--update`` and possibly + ``--force`` this will only process the files + from the start up until the pivot and ignore + the rest. + 2) ``start`` -> Start bisection: create a + bisection state file and initialize the low, + high, and pivot indices. + 3) ``stop`` -> Terminate the current bisection + session by deleting the state file. + 4) ``good`` | ``bad`` -> Mark the section + processed last as “good” or “bad”, + respectively. The next bisection step will + continue with the bad section. + 5) ``status`` -> Print status information about + the current bisection session. Hint: Use + with higher verbosity settings for more + output. + + A bisection session is initiated by issuing the + ``start`` directive. This sets the pivot to the + middle of the list of available font files. + Now run *luaotfload-tool* with the ``--update`` + flag set as well as ``--bisect=run``: only the + fonts up to the pivot will be considered. If + that task exhibited the issue you are tracking, + then tell Luaotfload using ``--bisect=bad``. + The next step of ``--bisect=run`` will continue + bisection with the part of the files below the + pivot. + Likewise, issue ``--bisect=good`` in order to + continue with the fonts above the pivot, + assuming the tested part of the list did not + trigger the bug. + + Once the culprit font is tracked down, ``good`` + or ``bad`` will have no effect anymore. ``run`` + will always end up processing the single font + file that was left. + Use ``--bisect=stop`` to clear the bisection + state. + +miscellaneous +----------------------------------------------------------------------- +--verbose=N, -v Set verbosity level to *n* or the number of + repetitions of ``-v``. +--quiet No verbose output (log level set to zero). +--log=CHANNEL Redirect log output (for database + troubleshooting), where *CHANNEL* can be + + 1) ``stdout`` -> all output will be + dumped to the terminal (default); or + 2) ``file`` -> write to a file to the temporary + directory (the name will be chosen + automatically. + +--version, -V Show version numbers of components as well as + some basic information and exit. +--help, -h Show help message and exit. + +--diagnose=CHECK Run the diagnostic procedure *CHECK*. Available + procedures are: + + 1) ``files`` -> check *Luaotfload* files for + modifications; + 2) ``permissions`` -> check permissions of + cache directories and files; + 3) ``environment`` -> print relevant + environment and kpse variables; + 4) ``repository`` -> check the git repository + for new releases, + 5) ``index`` -> check database, display + information about it. + + Procedures can be chained by concatenating with + commas, e.g. ``--diagnose=files,permissions``. + Specify ``thorough`` to run all checks. + +FILES +======================================================================= + +The font name database is usually located in the directory +``texmf-var/luatex-cache/generic/names/`` (``$TEXMFCACHE`` as set in +``texmf.cnf``) of your *TeX Live* distribution as a zlib-compressed +file ``luaotfload-names.lua.gz``. +The experimental lookup cache will be created as +``luaotfload-lookup-cache.lua`` in the same directory. +These Lua tables are not used directly by Luaotfload, though. +Instead, they are compiled to Lua bytecode which is written to +corresponding files with the extension ``.luc`` in the same directory. +When modifying the files by hand keep in mind that only if the bytecode +files are missing will Luaotfload use the plain version instead. +Both kinds of files are safe to delete, at the cost of regenerating +them with the next run of *LuaTeX*. + +SEE ALSO +======================================================================= + +**luatex** (1), **lua** (1) + +* ``texdoc luaotfload`` to display the manual for the *Luaotfload* + package +* Luaotfload development ``_ +* LuaLaTeX mailing list ``_ +* LuaTeX ``_ +* ConTeXt ``_ +* Luaotfload on CTAN ``_ + +BUGS +======================================================================= + +Tons, probably. + +AUTHORS +======================================================================= + +*Luaotfload* is maintained by the LuaLaTeX dev team +(``__). +The fontloader code is provided by Hans Hagen of Pragma ADE, Hasselt +NL (``__). + +This manual page was written by Philipp Gesang +. + diff --git a/Master/texmf-dist/source/luatex/luaotfload/luaotfload.conf.rst b/Master/texmf-dist/source/luatex/luaotfload/luaotfload.conf.rst new file mode 100644 index 00000000000..774095b5dec --- /dev/null +++ b/Master/texmf-dist/source/luatex/luaotfload/luaotfload.conf.rst @@ -0,0 +1,347 @@ +======================================================================= + luaotfload.conf +======================================================================= + +----------------------------------------------------------------------- + Luaotfload configuration file +----------------------------------------------------------------------- + +:Date: 2014-06-09 +:Copyright: GPL v2.0 +:Version: 2.5 +:Manual section: 5 +:Manual group: text processing + +SYNOPSIS +======================================================================= + +- **./luaotfload{.conf,rc}** +- **XDG_CONFIG_HOME/luaotfload/luaotfload{.conf,rc}** +- **~/.luaotfloadrc** + +DESCRIPTION +======================================================================= + +The file ``luaotfload.conf`` contains configuration options for +*Luaotfload*, a font loading and font management component for LuaTeX. + + +EXAMPLE +======================================================================= + +A small Luaotfload configuration file with few customizations could +look as follows: :: + + [db] + formats = afm, pfa, pfb + compress = false + + [misc] + termwidth = 60 + + [run] + log-level = 6 + +This will make Luaotfload ignore all font files except for PostScript +formats. NB: With a default Tex Live install the PS fonts will take +much longer to index than OpenType or TrueType ones. Also, an +uncompressed index file will be dumped which is going to be much larger +due to the huge amount of PostScript fonts indexed. The terminal width +is truncated to 60 characters which influences the verbose output +during indexing. Finally, the verbosity is increased greatly: each font +file being processed will be printed to the stdout on a separate line, +along with lots of other information. + +To observe the difference in behavior, save above snippet to +``./luaotfload.conf`` and update the font index: :: + + luaotfload --update --force + + +SYNTAX +======================================================================= + +The configuration file syntax follows the common INI format. For a more +detailed description please refer to the section “CONFIGURATION FILE” +of **git-config**\(1). A brief list of rules is given below: + + * Blank lines and lines starting with a semicolon (``;``) are ignored. + + * A configuration file is partitioned into sections that are declared + by specifying the section title in brackets on a separate line: :: + + [some-section] + ... section content ... + + * Sections consist of one or more variable assignments of the form + ``variable-name = value`` E. g.:: + + [foo] + bar = baz + quux = xyzzy + ... + + * Section and variable names may contain only uppercase and lowercase + letters as well as dashes (``-``). + + +VARIABLES +======================================================================= + +Variables in belong into a configuration section and their values must +be of a certain type. Some of them have further constraints. For +example, the “color callback” must be a string of one of the values +``pre_linebreak_filter`` or ``pre_output_filter``, defined in the +section *run*. + +Currently, the configuration is organized into four sections: + +db + Options relating to the font index. + +misc + Options without a clearly defined category. + +paths + Path and file name settings. + +run + Options controlling runtime behavior of Luaotfload. + +The list of valid variables, the sections they are part of and their +type is given below. Types represent Lua types that the values must be +convertible to; they are abbreviated as follows: ``s`` for the *string* +type, ``n`` for *number*, ``b`` for *boolean*. A value of ``nil`` means +the variable is unset. + + +Section ``db`` +----------------------------------------------------------------------- + ++---------------+--------+---------------------------+ +| variable | type | default | ++---------------+--------+---------------------------+ +| compress | b | ``true`` | ++---------------+--------+---------------------------+ +| formats | s | ``"otf,ttf,ttc,dfont"`` | ++---------------+--------+---------------------------+ +| max-fonts | n | ``2^51`` | ++---------------+--------+---------------------------+ +| scan-local | b | ``false`` | ++---------------+--------+---------------------------+ +| skip-read | b | ``false`` | ++---------------+--------+---------------------------+ +| strip | b | ``true`` | ++---------------+--------+---------------------------+ +| update-live | b | ``true`` | ++---------------+--------+---------------------------+ + +The flag ``compress`` determines whether the font index (usually +``luaotfload-names.lua[.gz]`` will be stored in compressed forms. +If unset it is equivalent of passing ``--no-compress`` to +**luaotfload-tool**. Since the file is only created for convenience +and has no effect on the runtime behavior of Luaotfload, the flag +should remain set. Most editors come with zlib support anyways. + +The list of ``formats`` must be a comma separated sequence of strings +containing one or more of these elements: + +* ``otf`` (OpenType format), +* ``ttf`` and ``ttc`` (TrueType format), +* ``dfont`` (Macintosh TrueType format), +* ``afm`` (Adobe Font Metrics), +* ``pfb`` and ``pfa`` (PostScript format). + +It corresponds loosely to the ``--formats`` option to +**luaotfload-tool**. Invalid or duplicate members are ignored; if the +list does not contain any useful identifiers, the default list +``"otf,ttf,ttc,dfont"`` will be used. + +The variable ``max-fonts`` determines after processing how many font +files the font scanner will terminate the search. This is useful for +debugging issues with the font index and has the same effect as the +option ``--max-fonts`` to **luaotfload-tools**. + +The ``scan-local`` flag, if set, will incorporate the current working +directory as a font search location. NB: This will potentially slow +down document processing because a font index with local fonts will not +be saved to disk, so these fonts will have to be re-indexed whenever +the document is built. + +The ``skip-read`` flag is only useful for debugging: It makes +Luaotfload skip reading fonts. The font information for rebuilding the +index is taken from the presently existing one. + +Unsetting the ``strip`` flag prevents Luaotfload from removing data +from the index that is only useful when processing font files. NB: this +can increase the size of the index files significantly and has no +effect on the runtime behavior. + +If ``update-live`` is set, Luaotfload will reload the database if it +cannot find a requested font. Those who prefer to update manually using +**luaotfload-tool** should unset this flag. + + +Section ``default-features`` +----------------------------------------------------------------------- + +By default Luaotfload enables ``node`` mode and picks the default font +features that are prescribed in the OpenType standard. This behavior +may be overridden in the ``default-features`` section. Global defaults +that will be applied for all scripts can be set via the ``global`` +option, others by the script they are to be applied to. For example, +a setting of :: + + [default-features] + global = mode=base,color=0000FF + dflt = smcp,onum + +would force *base* mode, tint all fonts blue and activate small +capitals and text figures globally. Features are specified as a comma +separated list of variables or variable-value pairs. Variables without +an explicit value are set to ``true``. + + +Section ``misc`` +----------------------------------------------------------------------- + ++---------------+--------+-------------------------+ +| variable | type | default | ++---------------+--------+-------------------------+ +| statistics | b | ``false`` | ++---------------+--------+-------------------------+ +| termwidth | n | ``nil`` | ++---------------+--------+-------------------------+ +| version | s | | ++---------------+--------+-------------------------+ + +With ``statistics`` enabled, extra statistics will be collected during +index creation and appended to the index file. It may then be queried +at the Lua end or inspected by reading the file itself. + +The value of ``termwidth``, if set, overrides the value retrieved by +querying the properties of the terminal in which Luatex runs. This is +useful if the engine runs with ``shell_escape`` disabled and the actual +terminal dimensions cannot be retrieved. + +The value of ``version`` is derived from the version string hard-coded +in the Luaotfload source. Override at your own risk. + + +Section ``paths`` +----------------------------------------------------------------------- + ++------------------+--------+------------------------------------+ +| variable | type | default | ++------------------+--------+------------------------------------+ +| cache-dir | s | ``"fonts"`` | ++------------------+--------+------------------------------------+ +| names-dir | s | ``"names"`` | ++------------------+--------+------------------------------------+ +| index-file | s | ``"luaotfload-names.lua"`` | ++------------------+--------+------------------------------------+ +| lookups-file | s | ``"luaotfload-lookup-cache.lua"`` | ++------------------+--------+------------------------------------+ + +The paths ``cache-dir`` and ``names-dir`` determine the subdirectory +inside the Luaotfload subtree of the ``luatex-cache`` directory where +the font cache and the font index will be stored, respectively. + +Inside the index directory, the names of the index file and the font +lookup cache will be derived from the respective values of +``index-file`` and ``lookups-file``. This is the filename base for the +bytecode compiled version as well as -- for the index -- the gzipped +version. + + +Section ``run`` +----------------------------------------------------------------------- + ++------------------+--------+------------------------------+ +| variable | type | default | ++------------------+--------+------------------------------+ +| color-callback | s | ``"pre_linebreak_filter"`` | ++------------------+--------+------------------------------+ +| definer | s | ``"patch"`` | ++------------------+--------+------------------------------+ +| log-level | n | ``0`` | ++------------------+--------+------------------------------+ +| resolver | s | ``"cached"`` | ++------------------+--------+------------------------------+ + +The ``color-callback`` option determines the stage at which fonts that +defined with a ``color=xxyyzz`` feature will be colorized. By default +this happens in a ``pre_linebreak_filter`` but alternatively the +``pre_output_filter`` may be chosen, which is faster but might produce +inconsistent output. The latter also was the default in the 1.x series +of Luaotfload. + +The ``definer`` allows for switching the ``define_font`` callback. +Apart from the default ``patch`` one may also choose the ``generic`` +one that comes with the vanilla fontloader. Beware that this might +break tools like Fontspect that rely on the ``patch_font`` callback +provided by Luaotfload to perform important corrections on font data. + +The value of ``log-level`` sets the default verbosity of messages +printed by Luaotfload. Only messages defined with a verbosity of less +than or equal to the supplied value will be output on the terminal. +At a log level of five Luaotfload can be very noisy. Also, printing too +many messages will slow down the interpreter due to line buffering +being disabled (see **setbuf**\(3)). + +The ``resolver`` setting allows choosing the font name resolution +function: With the default value ``cached`` Luaotfload saves the result +of a successful font name request to a cache file to speed up +subsequent lookups. The alternative, ``normal`` circumvents the cache +and resolves every request individually. (Since to the restructuring of +the font name index in Luaotfload 2.4 the performance difference +between the cached and uncached lookups should be marginal.) + + +FILES +======================================================================= + +Luaotfload only processes the first configuration file it encounters at +one of the search locations. The file name may be either +``luaotfload.conf`` or ``luaotfloadrc``, except for the dotfile in the +user’s home directory which is expected at ``~/.luaotfloadrc``. + +Configuration files are located following a series of steps. The search +terminates as soon as a suitable file is encountered. The sequence of +locations that Luaotfload looks at is + +i. The current working directory of the LuaTeX process. +ii. The subdirectory ``luaotfload/`` inside the XDG configuration + tree, e. g. ``/home/oenothea/config/luaotfload/``. +iii. The dotfile. +iv. The *TEXMF* (using kpathsea). + + +SEE ALSO +======================================================================= + +**luaotfload-tool**\(1), **luatex**\(1), **lua**\(1) + +* ``texdoc luaotfload`` to display the PDF manual for the *Luaotfload* + package +* Luaotfload development ``_ +* LuaLaTeX mailing list ``_ +* LuaTeX ``_ +* Luaotfload on CTAN ``_ + + +REFERENCES +======================================================================= + +* The XDG base specification + ``_. + +AUTHORS +======================================================================= + +*Luaotfload* is maintained by the LuaLaTeX dev team +(``_). + +This manual page was written by Philipp Gesang +. + diff --git a/Master/texmf-dist/source/luatex/luaotfload/luaotfload.dtx b/Master/texmf-dist/source/luatex/luaotfload/luaotfload.dtx deleted file mode 100644 index 3615fa8328b..00000000000 --- a/Master/texmf-dist/source/luatex/luaotfload/luaotfload.dtx +++ /dev/null @@ -1,2685 +0,0 @@ -% \iffalse meta-comment -% -% Copyright (C) 2009-2014 -% by Elie Roux -% and Khaled Hosny -% and Philipp Gesang -% -% Home: https://github.com/lualatex/luaotfload -% Support: . -% -% This work is under the GPL v2.0 license. -% -% This work consists of the main source file luaotfload.dtx -% and the derived files -% luaotfload.sty, luaotfload.lua -% -% Unpacking: -% tex luaotfload.dtx -% -% Documentation: -% lualatex luaotfload.dtx -% -% The class ltxdoc loads the configuration file ltxdoc.cfg -% if available. Here you can specify further options, e.g. -% use A4 as paper format: -% \PassOptionsToClass{a4paper}{article} -% -% -% -%<*ignore> -\begingroup - \def\x{LaTeX2e}% -\expandafter\endgroup -\ifcase 0\ifx\install y1\fi\expandafter - \ifx\csname processbatchFile\endcsname\relax\else1\fi - \ifx\fmtname\x\else 1\fi\relax -\else\csname fi\endcsname -% -%<*install> -\input docstrip.tex -\Msg{************************************************************************} -\Msg{* Installation} -\Msg{* Package: luaotfload v2.4-4 OpenType layout system} -\Msg{************************************************************************} - -\keepsilent -\askforoverwritefalse - -\let\MetaPrefix\relax - -\preamble -This is a generated file. - -Copyright (C) 2009-2014 - by Elie Roux - and Khaled Hosny - and Philipp Gesang - - Home: https://github.com/lualatex/luaotfload - Support: . - -This work is under the GPL v2.0 license. - -This work consists of the main source file luaotfload.dtx -and the derived files - luaotfload.sty, luaotfload.lua - -\endpreamble - -\let\MetaPrefix\DoubleperCent - -\generate{% - \usedir{tex/luatex/luaotfload}% - \file{luaotfload.sty}{\from{luaotfload.dtx}{package}}% -} - -% The following hacks are to generate a lua file with lua comments starting with -% -- instead of %% - -\def\MetaPrefix{-- } - -\def\luapostamble{% - \MetaPrefix^^J% - \MetaPrefix\space End of File `\outFileName'.% -} - -\def\currentpostamble{\luapostamble}% - -\generate{% - \usedir{tex/luatex/luaotfload}% - \file{luaotfload.lua}{\from{luaotfload.dtx}{lua}}%% -} - -\obeyspaces -\Msg{************************************************************************} -\Msg{*} -\Msg{* To finish the installation you have to move the following} -\Msg{* files into a directory searched by TeX:} -\Msg{*} -\Msg{* luaotfload.sty, luaotfload.lua} -\Msg{*} -\Msg{* Happy TeXing!} -\Msg{*} -\Msg{************************************************************************} - -\endbatchfile -% -%<*ignore> -\fi -% -%<*driver> -\NeedsTeXFormat{LaTeX2e} -\ProvidesFile{luaotfload.drv}% - [2014/05/18 v2.4-4 OpenType layout system]% -\documentclass{ltxdoc} -\usepackage{metalogo,multicol,mdwlist,fancyvrb,xspace} -\usepackage[x11names]{xcolor} -% -\def\primarycolor{DodgerBlue4} %%-> rgb 16 78 139 | #104e8b -\def\secondarycolor{Goldenrod4} %%-> rgb 139 105 200 | #8b6914 -% -\usepackage[ - bookmarks=true, - colorlinks=true, - linkcolor=\primarycolor, - urlcolor=\secondarycolor, - citecolor=\primarycolor, - pdftitle={The luaotfload package}, - pdfsubject={OpenType layout system for Plain TeX and LaTeX}, - pdfauthor={Elie Roux & Khaled Hosny & Philipp Gesang}, - pdfkeywords={luatex, lualatex, unicode, opentype} -]{hyperref} -\usepackage{fontspec} -\usepackage{unicode-math} -\setmainfont[ -% Numbers = OldStyle, %% buggy with font cache - Ligatures = TeX, - BoldFont = {Linux Libertine O Bold}, - ItalicFont = {Linux Libertine O Italic}, - SlantedFont = {Linux Libertine O Italic}, -]{Linux Libertine O} -\setmonofont[Ligatures=TeX,Scale=MatchLowercase]{Liberation Mono} -%setsansfont[Ligatures=TeX]{Linux Biolinum O} -\setsansfont[Ligatures=TeX,Scale=MatchLowercase]{Iwona Medium} -%setmathfont{XITS Math} - -\usepackage{hologo} - -\newcommand\TEX {\TeX\xspace} -\newcommand\LUA {Lua\xspace} -\newcommand\PDFTEX {pdf\TeX\xspace} -\newcommand\LUATEX {Lua\TeX\xspace} -\newcommand\XETEX {\XeTeX\xspace} -\newcommand\LATEX {\LaTeX\xspace} -\newcommand\LUALATEX {Lua\LaTeX\xspace} -\newcommand\CONTEXT {Con\TeX t\xspace} -\newcommand\OpenType {\identifier{Open\kern-.25ex Type}\xspace} - -\def\definehighlight[#1][#2]% - {\ifcsname #1\endcsname\else - \expandafter\def\csname #1\endcsname% - {\bgroup#2\csname #1_indeed\endcsname} - \expandafter\def\csname #1_indeed\endcsname##1% - {##1\egroup}% - \fi} - -\def\restoreunderscore{\catcode`\_=12\relax} - -\definehighlight [fileent][\ttfamily\restoreunderscore] %% files, dirs -\definehighlight [texmacro][\sffamily\itshape\textbackslash] %% cs -\definehighlight[luafunction][\sffamily\itshape\restoreunderscore] %% lua identifiers -\definehighlight [identifier][\sffamily] %% names -\definehighlight [abbrev][\rmfamily\scshape] %% acronyms -\definehighlight [emphasis][\rmfamily\slshape] %% level 1 emph - -\newcommand*\email[1]{\href{mailto:#1}{#1}} - -\renewcommand\partname{Part}%% gets rid of the stupid “file” heading - -\usepackage{syntax}%% bnf for font request syntax - -\usepackage{titlesec} - -\def\movecountertomargin#1{\llap{\rmfamily\upshape#1\hskip2em}} -\def\zeropoint{0pt} -\titleformat \part - {\normalsize\rmfamily\bfseries} - {\movecountertomargin\thepart} \zeropoint {} -\titleformat \section - {\normalsize\rmfamily\scshape} - {\movecountertomargin\thesection} \zeropoint {} -\titleformat \subsection - {\small\rmfamily\itshape} - {\movecountertomargin\thesubsection} \zeropoint {} -\titleformat \subsubsection - {\normalsize\rmfamily\upshape} - {\movecountertomargin\thesubsubsection} \zeropoint {} - -\usepackage{tocloft} -\renewcommand \cftpartfont {\rmfamily\upshape} -\renewcommand \cftsecfont {\rmfamily\upshape} -\renewcommand \cftsubsecfont {\rmfamily\upshape} -\setlength \cftbeforepartskip {1ex} -\setlength \cftbeforesecskip {1ex} - -\VerbatimFootnotes -\begin{document} - \DocInput{luaotfload.dtx}% -\end{document} -% -% \fi -% -% \CheckSum{0} -% -% \CharacterTable -% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z -% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z -% Digits \0\1\2\3\4\5\6\7\8\9 -% Exclamation \! Double quote \" Hash (number) \# -% Dollar \$ Percent \% Ampersand \& -% Acute accent \' Left paren \( Right paren \) -% Asterisk \* Plus \+ Comma \, -% Minus \- Point \. Solidus \/ -% Colon \: Semicolon \; Less than \< -% Equals \= Greater than \> Question mark \? -% Commercial at \@ Left bracket \[ Backslash \\ -% Right bracket \] Circumflex \^ Underscore \_ -% Grave accent \` Left brace \{ Vertical bar \| -% Right brace \} Tilde \~} -% -% \GetFileInfo{luaotfload.drv} -% -% \title{The \identifier{luaotfload} package} -% \date{2014/05/18 v2.4-4} -% \author{Elie Roux · Khaled Hosny · Philipp Gesang\\ -% Home: \url{https://github.com/lualatex/luaotfload}\\ -% Support: \email{lualatex-dev@tug.org}} -% -% \maketitle -% -% \begin{abstract} -% This package is an adaptation of the \CONTEXT font loading system. -% It allows for loading \OpenType fonts with an extended syntax and adds -% support for a variety of font features. -% \end{abstract} -% -% \tableofcontents -% -% \part{Package Description} -% -% \section{Introduction} -% -% Font management and installation has always been painful with \TEX. A lot of -% files are needed for one font (\abbrev{tfm}, \abbrev{pfb}, \abbrev{map}, -% \abbrev{fd}, \abbrev{vf}), and due to the 8-Bit encoding each font is limited -% to 256 characters. -% But the font world has evolved since the original -% \TEX, and new typographic systems have appeared, most notably the so -% called \emphasis{smart font} technologies like \OpenType -% fonts (\abbrev{otf}). -% These fonts can contain many more characters than \TEX fonts, as well as additional -% functionality like ligatures, old-style numbers, small capitals, -% etc., and support more complex writing systems like Arabic and -% Indic\footnote{% -% Unfortunately, \identifier{luaotfload} doesn‘t support many Indic -% scripts right now. -% Assistance in implementing the prerequisites is greatly -% appreciated. -% } -% scripts. -% \OpenType fonts are widely deployed and available for all -% modern operating systems. -% As of 2013 they have become the de facto standard for advanced text -% layout. -% However, until recently the only way to use them directly in the \TEX -% world was with the \XETEX engine. -% -% Unlike \XETEX, \LUATEX has no built-in support for -% \OpenType or technologies other than the original \TEX fonts. -% Instead, it provides hooks for executing \LUA code during the \TEX run -% that allow implementing extensions for loading fonts and manipulating -% how input text is processed without modifying the underlying engine. -% This is where \identifier{luaotfload} comes into play: -% Based on code from \CONTEXT, it extends \LUATEX with functionality necessary -% for handling \OpenType fonts. -% Additionally, it provides means for accessing fonts known to the operating -% system conveniently by indexing the metadata. -% -% -% \section{Thanks} -% -% \identifier{Luaotfload} is part of \LUALATEX, the community-driven -% project to provide a foundation for using the \LATEX format with the -% full capabilites of the \LUATEX engine. -% As such, the distinction between end users, contributors, and project -% maintainers is intentionally kept less strict, lest we unduly -% personalize the common effort. -% -% Nevertheless, the current maintainers would like to express their -% gratitude to Khaled Hosny, Akira Kakuto, Hironori Kitagawa and Dohyun -% Kim. -% Their contributions -- be it patches, advice, or systematic -% testing -- made the switch from version 1.x to 2.2 possible. -% Also, Hans Hagen, the author of the font loader, made porting the -% code to \LATEX a breeze due to the extra effort he invested into -% isolating it from the rest of \CONTEXT, not to mention his assistance -% in the task and willingness to respond to our suggestions. -% -% -% \section{Loading Fonts} -% -% \identifier{luaotfload} supports an extended font request syntax: -% -% \begin{quote} -% |\font\foo={|% -% \meta{prefix}|:|% -% \meta{font name}|:|% -% \meta{font features}|}|% -% \meta{\TEX font features} -% \end{quote} -% -% \noindent -% The curly brackets are optional and escape the spaces in the enclosed -% font name. -% Alternatively, double quotes serve the same purpose. -% A selection of individual parts of the syntax are discussed below; -% for a more formal description see figure \ref{font-syntax}. -% -% \begin{figure}[b] -% \setlength\grammarparsep{12pt plus 2pt minus 2pt} -% \setlength\grammarindent{5cm} -% \begingroup -% \small -% \begin{grammar} -% ::= `\\font', {\sc csname}, `=', , [ ] ; -% -% ::= `at', {\sc dimension} ; -% -% ::= `"', `"' -% \alt `{', `}' -% \alt ; -% -% ::= , [`:', ] -% \alt `[', `]', [ [`:'], ] ; -% -% ::= , [ ], \{ \} -% \alt , \{ \} ; -% -% ::= `file:', -% \alt `name:', ; -% -% ::= \{ \} ; -% -% ::= \{ \} ; -% -% ::= {\sc tfmname} | ; -% -% ::= \{ {\sc all_characters} - `]' \} ; -% -% ::= `/', (`I' | `B' | `BI' | `IB' | `S=', \{ {\sc digit} \} ) ; -% -% ::= `(', \{ {\sc digit} \}, `)' ; -% -% ::= , \{ `;', \} ; -% -% ::= {\sc feature_id}, `=', {\sc feature_value} -% \alt , {\sc feature_id} ; -% -% ::= `+' | `-' ; -% -% ::= {\sc all_characters} - ( `(' | `/' | `:' ) ; -% \end{grammar} -% \endgroup -% \caption{Font request syntax. -% Braces or double quotes around the -% \emphasis{specification} rule will -% preserve whitespace in file names. -% In addition to the font style modifiers -% (\emphasis{slash-notation}) given above, there -% are others that are recognized but will be silently -% ignored: {\ttfamily aat}, -% {\ttfamily icu}, and -% {\ttfamily gr}. -% The special terminals are: -% {\sc feature\textunderscore id} for a valid font -% feature name and -% {\sc feature\textunderscore value} for the corresponding -% value. -% {\sc tfmname} is the name of a \abbrev{tfm} file. -% {\sc digit} again refers to bytes 48--57, and -% {\sc all\textunderscore characters} to all byte values. -% {\sc csname} and {\sc dimension} are the \TEX concepts.} -% \label{font-syntax} -% \end{figure} -% -% \subsection{Prefix -- the \identifier{luaotfload}{ }Way} -% -% In \identifier{luaotfload}, the canonical syntax for font requests -% requires a \emphasis{prefix}: -% \begin{quote} -% |\font\fontname=|\meta{prefix}|:|\meta{fontname}\dots -% \end{quote} -% where \meta{prefix} is either \verb|file:| or \verb|name:|.\footnote{% -% The development version also knows two further prefixes, -% \verb|kpse:| and \verb|my:|. -% A \verb|kpse| lookup is restricted to files that can be found by -% \identifier{kpathsea} and -% will not attempt to locate system fonts. -% This behavior can be of value when an extra degree of encapsulation is -% needed, for instance when supplying a customized tex distribution. -% -% The \verb|my| lookup takes this a step further: it lets you define -% a custom resolver function and hook it into the \luafunction{resolve_font} -% callback. -% This ensures full control over how a file is located. -% For a working example see the -% \href{https://bitbucket.org/phg/lua-la-tex-tests/src/5f6a535d/pln-lookup-callback-1.tex} -% {test repo}. -% } -% It determines whether the font loader should interpret the request as -% a \emphasis{file name} or -% \emphasis{font name}, respectively, -% which again influences how it will attempt to locate the font. -% Examples for font names are -% “Latin Modern Italic”, -% “GFS Bodoni Rg”, and -% “PT Serif Caption” -% -- they are the human readable identifiers -% usually listed in drop-down menus and the like.\footnote{% -% Font names may appear like a great choice at first because they -% offer seemingly more intuitive identifiers in comparison to arguably -% cryptic file names: -% “PT Sans Bold” is a lot more descriptive than \fileent{PTS75F.ttf}. -% On the other hand, font names are quite arbitrary and there is no -% universal method to determine their meaning. -% While \identifier{luaotfload} provides fairly sophisticated heuristic -% to figure out a matching font style, weight, and optical size, it -% cannot be relied upon to work satisfactorily for all font files. -% For an in-depth analysis of the situation and how broken font names -% are, please refer to -% \href{http://www.ntg.nl/pipermail/ntg-context/2013/073889.html} -% {this post} -% by Hans Hagen, the author of the font loader. -% If in doubt, use filenames. -% \fileent{luaotfload-tool} can perform the matching for you with the -% option \verb|--find=|, and you can use the file name it returns -% in your font definition. -% } -% In order for fonts installed both in system locations and in your -% \fileent{texmf} to be accessible by font name, \identifier{luaotfload} must -% first collect the metadata included in the files. -% Please refer to section~\ref{sec:fontdb} below for instructions on how to -% create the database. -% -% File names are whatever your file system allows them to be, except -% that that they may not contain the characters -% \verb|(|, -% \verb|:|, and -% \verb|/|. -% As is obvious from the last exception, the \verb|file:| lookup will -% not process paths to the font location -- only those -% files found when generating the database are addressable this way. -% Continue below in the \XETEX section if you need to load your fonts -% by path. -% The file names corresponding to the example font names above are -% \fileent{lmroman12-italic.otf}, -% \fileent{GFSBodoni.otf}, and -% \fileent{PTZ56F.ttf}. -% -% \subsection{Compatibility Layer} -% -% In addition to the regular prefixed requests, \identifier{luaotfload} -% accepts loading fonts the \XETEX way. -% There are again two modes: bracketed and unbracketed. -% A bracketed request looks as follows. -% -% \begin{quote} -% |\font\fontname=[|\meta{path to file}|]| -% \end{quote} -% -% \noindent -% Inside the square brackets, every character except for a closing -% bracket is permitted, allowing for specifying paths to a font file. -% Naturally, path-less file names are equally valid and processed the -% same way as an ordinary \verb|file:| lookup. -% -% \begin{quote} -% |\font\fontname=|\meta{font name} \dots -% \end{quote} -% -% Unbracketed (or, for lack of a better word: \emphasis{anonymous}) -% font requests resemble the conventional \TEX syntax. -% However, they have a broader spectrum of possible interpretations: -% before anything else, \identifier{luaotfload} attempts to load a -% traditional \TEX Font Metric (\abbrev{tfm} or \abbrev{ofm}). -% If this fails, it performs a \verb|name:| lookup, which itself will -% fall back to a \verb|file:| lookup if no database entry matches -% \meta{font name}. -% -% Furthermore, \identifier{luaotfload} supports the slashed (shorthand) -% font style notation from \XETEX. -% -% \begin{quote} -% |\font\fontname=|\meta{font name}|/|\meta{modifier}\dots -% \end{quote} -% -% \noindent -% Currently, four style modifiers are supported: -% \verb|I| for italic shape, -% \verb|B| for bold weight, -% \verb|BI| or \verb|IB| for the combination of both. -% Other “slashed” modifiers are too specific to the \XETEX engine and -% have no meaning in \LUATEX. -% -% \subsection{Examples} -% -% \subsubsection{Loading by File Name} -% -% For example, conventional \abbrev{type1} font can be loaded with a \verb|file:| -% request like so: -% -% \begin{quote} -% \begin{verbatim} -% \font\lmromanten={file:ec-lmr10} at 10pt -% \end{verbatim} -% \end{quote} -% -% The \OpenType version of Janusz Nowacki’s font \emphasis{Antykwa -% Półtawskiego}\footnote{% -% \url{http://jmn.pl/antykwa-poltawskiego/}, also available in -% in \TEX Live. -% } -% in its condensed variant can be loaded as follows: -% -% \begin{quote} -% \begin{verbatim} -% \font\apcregular=file:antpoltltcond-regular.otf at 42pt -% \end{verbatim} -% \end{quote} -% -% The next example shows how to load the \emphasis{Porson} font digitized by -% the Greek Font Society using \XETEX-style syntax and an absolute path from a -% non-standard directory: -% -% \begin{quote} -% \begin{verbatim} -% \font\gfsporson="[/tmp/GFSPorson.otf]" at 12pt -% \end{verbatim} -% \end{quote} -% -% \subsubsection{Loading by Font Name} -% -% The \verb|name:| lookup does not depend on cryptic filenames: -% -% \begin{quote} -% \begin{verbatim} -% \font\pagellaregular={name:TeX Gyre Pagella} at 9pt -% \end{verbatim} -% \end{quote} -% -% A bit more specific but essentially the same lookup would be: -% -% \begin{quote} -% \begin{verbatim} -% \font\pagellaregular={name:TeX Gyre Pagella Regular} at 9pt -% \end{verbatim} -% \end{quote} -% -% \noindent -% Which fits nicely with the whole set: -% -% \begin{quote} -% \begin{verbatim} -% \font\pagellaregular ={name:TeX Gyre Pagella Regular} at 9pt -% \font\pagellaitalic ={name:TeX Gyre Pagella Italic} at 9pt -% \font\pagellabold ={name:TeX Gyre Pagella Bold} at 9pt -% \font\pagellabolditalic={name:TeX Gyre Pagella Bolditalic} at 9pt -% -% {\pagellaregular foo bar baz\endgraf} -% {\pagellaitalic foo bar baz\endgraf} -% {\pagellabold foo bar baz\endgraf} -% {\pagellabolditalic foo bar baz\endgraf} -% -% ... -% \end{verbatim} -% \end{quote} -% -% \subsubsection{Modifiers} -% -% If the entire \emphasis{Iwona} family\footnote{% -% \url{http://jmn.pl/kurier-i-iwona/}, -% also in \TEX Live. -% } -% is installed in some location accessible by \identifier{luaotfload}, -% the regular shape can be loaded as follows: -% -% \begin{quote} -% \begin{verbatim} -% \font\iwona=Iwona at 20pt -% \end{verbatim} -% \end{quote} -% -% \noindent -% To load the most common of the other styles, the slash notation can -% be employed as shorthand: -% -% \begin{quote} -% \begin{verbatim} -% \font\iwonaitalic =Iwona/I at 20pt -% \font\iwonabold =Iwona/B at 20pt -% \font\iwonabolditalic=Iwona/BI at 20pt -% \end{verbatim} -% \end{quote} -% -% \noindent -% which is equivalent to these full names: -% -% \begin{quote} -% \begin{verbatim} -% \font\iwonaitalic ="Iwona Italic" at 20pt -% \font\iwonabold ="Iwona Bold" at 20pt -% \font\iwonabolditalic="Iwona BoldItalic" at 20pt -% \end{verbatim} -% \end{quote} -% -% \section{Font features} -% -% \emphasis{Font features} are the second to last component in the -% general scheme for font requests: -% -% \begin{quote} -% |\font\foo={|% -% \meta{prefix}|:|% -% \meta{font name}|:|% -% \meta{font features}|}|% -% \meta{\TEX font features} -% \end{quote} -% -% \noindent -% If style modifiers are present (\XETEX style), they must precede -% \meta{font features}. -% -% The element \meta{font features} is a semicolon-separated list of feature -% tags\footnote{% -% Cf. \url{http://www.microsoft.com/typography/otspec/featurelist.htm}. -% } -% and font options. -% Prepending a font feature with a |+| (plus sign) enables it, whereas -% a |-| (minus) disables it. For instance, the request -% -% \begin{quote} -% \begin{verbatim} -% \font\test=LatinModernRoman:+clig;-kern -% \end{verbatim} -% \end{quote} -% -% \noindent activates contextual ligatures (|clig|) and disables -% kerning (|kern|). -% Alternatively the options |true| or |false| can be passed to -% the feature in a key/value expression. -% The following request has the same meaning as the last one: -% -% \begin{quote} -% \begin{verbatim} -% \font\test=LatinModernRoman:clig=true;kern=false -% \end{verbatim} -% \end{quote} -% -% \noindent -% Furthermore, this second syntax is required should a font feature -% accept other options besides a true/false switch. -% For example, \emphasis{stylistic alternates} (|salt|) are variants of given -% glyphs. -% They can be selected either explicitly by supplying the variant -% index (starting from one), or randomly by setting the value to, -% obviously, |random|. -% -% \iffalse TODO verify that this actually works with a font that supports -% the salt/random feature!\fi -% \begin{quote} -% \begin{verbatim} -% \font\librmsaltfirst=LatinModernRoman:salt=1 -% \end{verbatim} -% \end{quote} -% -% \noindent Other font options include: -% -% \begin{description} -% -% \item [mode] \hfill \\ -% \identifier{luaotfload} has two \OpenType processing -% \emphasis{modes}: -% \identifier{base} and \identifier{node}. -% -% \identifier{base} mode works by mapping \OpenType -% features to traditional \TEX ligature and kerning mechanisms. -% Supporting only non-contextual substitutions and kerning -% pairs, it is the slightly faster, albeit somewhat limited, variant. -% \identifier{node} mode works by processing \TeX’s internal -% node list directly at the \LUA end and supports -% a wider range of \OpenType features. -% The downside is that the intricate operations required for -% \identifier{node} mode may slow down typesetting especially -% with complex fonts and it does not work in math mode. -% -% By default \identifier{luaotfload} is in \identifier{node} -% mode, and \identifier{base} mode has to be requested where needed, -% e.~g. for math fonts. -% -% \item [script] \label{script-tag} \hfill \\ -% An \OpenType script tag;\footnote{% -% See \url{http://www.microsoft.com/typography/otspec/scripttags.htm} -% for a list of valid values. -% For scripts derived from the Latin alphabet the value -% |latn| is good choice. -% } -% the default value is |dlft|. -% Some fonts, including very popular ones by foundries like Adobe, -% do not assign features to the |dflt| script, in -% which case the script needs to be set explicitly. -% -% \item [language] \hfill \\ -% An \OpenType language system identifier,\footnote{% -% Cf. \url{http://www.microsoft.com/typography/otspec/languagetags.htm}. -% } -% defaulting to |dflt|. -% -% \item [featurefile] \hfill \\ -% A comma-separated list of feature files to be applied to the -% font. -% Feature files contain a textual representation of -% \OpenType tables and extend the features of a font -% on fly. -% After they are applied to a font, features defined in a -% feature file can be enabled or disabled just like any -% other font feature. -% The syntax is documented in \identifier{Adobe}’s -% \OpenType Feature File Specification.\footnote{% -% Cf. \url{http://www.adobe.com/devnet/opentype/afdko/topic_feature_file_syntax.html}. -% } -% -% For a demonstration of how to set a |tkrn| feature consult -% the file |tkrn.fea| that is part of \identifier{luaotfload}. -% It can be read and applied as follows: -% -% |\font\test=Latin Modern Roman:featurefile=tkrn.fea;+tkrn| -% -% \item [color] \hfill \\ -% A font color, defined as a triplet of two-digit hexadecimal -% \abbrev{rgb} values, with an optional fourth value for -% transparency -% (where |00| is completely transparent and |FF| is opaque). -% -% For example, in order to set text in semitransparent red: -% -% \begin{quote} -% \begin{verbatim} -% \font\test={Latin Modern Roman}:color=FF0000BB -% \end{verbatim} -% \end{quote} -% -% \item [kernfactor \& letterspace] \hfill \\ -% Define a font with letterspacing (tracking) enabled. -% In \identifier{luaotfload}, letterspacing is implemented by -% inserting additional kerning between glyphs. -% -% This approach is derived from and still quite similar to the -% \emphasis{character kerning} (\texmacro{setcharacterkerning} / -% \texmacro{definecharacterkerning} \& al.) functionality of -% Context, see the file \fileent{typo-krn.lua} there. -% The main difference is that \identifier{luaotfload} does not -% use \LUATEX attributes to assign letterspacing to regions, -% but defines virtual letterspaced versions of a font. -% -% The option \identifier{kernfactor} accepts a numeric value that -% determines the letterspacing factor to be applied to the font -% size. -% E.~g. a kern factor of $0.42$ applied to a $10$ pt font -% results in $4.2$ pt of additional kerning applied to each -% pair of glyphs. -% Ligatures are split into their component glyphs unless -% explicitly ignored (see below). -% -% For compatibility with \XETEX an alternative -% \identifier{letterspace} option is supplied that interprets the -% supplied value as a \emphasis{percentage} of the font size but -% is otherwise identical to \identifier{kernfactor}. -% Consequently, both definitions in below snippet yield the same -% letterspacing width: -% -% \begin{quote} -% \begin{verbatim} -% \font\iwonakernedA="file:Iwona-Regular.otf:kernfactor=0.125" -% \font\iwonakernedB="file:Iwona-Regular.otf:letterspace=12.5" -% \end{verbatim} -% \end{quote} -% -% Specific pairs of letters and ligatures may be exempt from -% letterspacing by defining the \LUA functions -% \luafunction{keeptogether} and \luafunction{keepligature}, -% respectively, inside the namespace \verb|luaotfload.letterspace|. -% Both functions are called whenever the letterspacing callback -% encounters an appropriate node or set of nodes. -% If they return a true-ish value, no extra kern is inserted at -% the current position. -% \luafunction{keeptogether} receives a pair of consecutive -% glyph nodes in order of their appearance in the node list. -% \luafunction{keepligature} receives a single node which can be -% analyzed into components. -% (For details refer to the \emphasis{glyph nodes} section in the -% \LUATEX reference manual.) -% The implementation of both functions is left entirely to the -% user. -% -% -% \item [protrusion \& expansion] \hfill \\ -% These keys control microtypographic features of the font, -% namely \emphasis{character protrusion} and \emphasis{font -% expansion}. -% Their arguments are names of \LUA tables that contain -% values for the respective features.\footnote{% -% For examples of the table layout please refer to the -% section of the file \fileent{luaotfload-fonts-ext.lua} where the -% default values are defined. -% Alternatively and with loss of information, you can dump -% those tables into your terminal by issuing -% \begin{verbatim} -% \directlua{inspect(fonts.protrusions.setups.default) -% inspect(fonts.expansions.setups.default)} -% \end{verbatim} -% at some point after loading \fileent{luaotfload.sty}. -% } -% For both, only the set \identifier{default} is predefined. -% -% For example, to define a font with the default -% protrusion vector applied\footnote{% -% You also need to set -% \verb|pdfprotrudechars=2| and -% \verb|pdfadjustspacing=2| -% to activate protrusion and expansion, respectively. -% See the -% \href{http://mirrors.ctan.org/systems/pdftex/manual/pdftex-a.pdf}% -% {\PDFTEX manual} -% for details. -% }: -% -% \begin{quote} -% \begin{verbatim} -% \font\test=LatinModernRoman:protrusion=default -% \end{verbatim} -% \end{quote} -% \end{description} -% -% \paragraph{Non-standard font features} -% \identifier{luaotfload} adds a number of features that are not defined -% in the original \OpenType specification, most of them -% aiming at emulating the behavior familiar from other \TEX engines. -% Currently (2013) there are three of them: -% -% \begin{description} -% -% \item [anum] -% Substitutes the glyphs in the \abbrev{ascii} number range -% with their counterparts from eastern Arabic or Persian, -% depending on the value of \identifier{language}. -% -% \item [tlig] -% Applies legacy \TEX ligatures: -% -% \begin{tabular}{rlrl} -% `` & \verb|``| & '' & \verb|''| \\ -% ` & \verb|`| & ' & \verb|'| \\ -% " & \verb|"| & -- & \verb|--| \\ -% --- & \verb|---| & !` & \verb|!`| \\ -% ?` & \verb|?`| & & \\ -% \end{tabular} -% -% \footnote{% -% These contain the feature set \verb|trep| of earlier -% versions of \identifier{luaotfload}. -% -% Note to \XETEX users: this is the equivalent of the -% assignment \verb|mapping=text-tex| using \XETEX's input -% remapping feature. -% } -% -% \item [itlc] -% Computes italic correction values (active by default). -% -% \end{description} -% -% -% -% \section{Font names database} -% \label{sec:fontdb} -% -% As mentioned above, \identifier{luaotfload} keeps track of which -% fonts are available to \LUATEX by means of a \emphasis{database}. -% This allows referring to fonts not only by explicit filenames but -% also by the proper names contained in the metadata which is often -% more accessible to humans.\footnote{% -% The tool \href{http://www.lcdf.org/type/}{\fileent{otfinfo}} (comes -% with \TEX Live), when invoked on a font file with the \verb|-i| -% option, lists the variety of name fields defined for it. -% } -% -% When \identifier{luaotfload} is asked to load a font by a font name, -% it will check if the database exists and load it, or else generate a -% fresh one. -% Should it then fail to locate the font, an update to the database is -% performed in case the font has been added to the system only -% recently. As soon as the database is updated, the resolver will try -% and look up the font again, all without user intervention. -% The goal is for \identifier{luaotfload} to act in the background and -% behave as unobtrusively as possible, while providing a convenient -% interface to the fonts installed on the system. -% -% Generating the database for the first time may take a while since it -% inspects every font file on your computer. -% This is particularly noticeable if it occurs during a typesetting run. -% In any case, subsequent updates to the database will be quite fast. -% -% \subsection[luaotfload-tool / mkluatexfontdb.lua]% -% {\fileent{luaotfload-tool} / -% \fileent{mkluatexfontdb.lua}\footnote{% -% The script may be named just \fileent{mkluatexfontdb} in your -% distribution. -% }} -% -% It can still be desirable at times to do some of these steps -% manually, and without having to compile a document. -% To this end, \identifier{luaotfload} comes with the utility -% \fileent{luaotfload-tool} that offers an interface to the database -% functionality. -% Being a \LUA script, there are two ways to run it: -% either make it executable (\verb|chmod +x| on unixoid systems) or -% pass it as an argument to \fileent{texlua}.\footnote{% -% Tests by the maintainer show only marginal performance gain by -% running with Luigi Scarso’s -% \href{https://foundry.supelec.fr/projects/luajittex/}% -% {\identifier{Luajit\kern-.25ex\TEX}}, -% which is probably due to the fact that most of the time is spent -% on file system operations. -% -% \emphasis{Note}: -% On \abbrev{MS} \identifier{Windows} systems, the script can be run -% either by calling the wrapper application -% \fileent{luaotfload-tool.exe} or as -% \verb|texlua.exe luaotfload-tool.lua|. -% } -% Invoked with the argument \verb|--update| it will perform a database -% update, scanning for fonts not indexed. -% -% \begin{quote} -% \begin{verbatim} -% luaotfload-tool --update -% \end{verbatim} -% \end{quote} -% -% Adding the \verb|--force| switch will initiate a complete -% rebuild of the database. -% -% \begin{quote} -% \begin{verbatim} -% luaotfload-tool --update --force -% \end{verbatim} -% \end{quote} -% -% For sake of backwards compatibility, \fileent{luaotfload-tool} may be -% renamed or symlinked to \fileent{mkluatexfontdb}. -% Whenever it is run under this name, it will update the database -% first, mimicking the behavior of earlier versions of -% \identifier{luaotfload}. -% -% \subsection{Search Paths} -% -% \identifier{luaotfload} scans those directories where fonts are -% expected to be located on a given system. -% On a Linux machine it follows the paths listed in the -% \identifier{Fontconfig} configuration files; -% consult \verb|man 5 fonts.conf| for further information. -% On \identifier{Windows} systems, the standard location is -% \verb|Windows\Fonts|, -% while \identifier{Mac OS~X} requires a multitude of paths to -% be examined. -% The complete list is is given in table \ref{table-searchpaths}. -% Other paths can be specified by setting the environment variable -% \verb+OSFONTDIR+. -% If it is non-empty, then search will be extended to the included -% directories. -% -% \begin{table}[t] -% \hrule -% \caption{List of paths searched for each supported operating -% system.} -% \renewcommand{\arraystretch}{1.2} -% \begin{center} -% \begin{tabular}{lp{.5\textwidth}} -% Windows & \verb|%WINDIR%\Fonts| -% \\ -% Linux & \fileent{/usr/local/etc/fonts/fonts.conf} and\hfill\break -% \fileent{/etc/fonts/fonts.conf} -% \\ -% Mac & \fileent{\textasciitilde/Library/Fonts},\break -% \fileent{/Library/Fonts},\break -% \fileent{/System/Library/Fonts}, and\hfill\break -% \fileent{/Network/Library/Fonts} -% \\ -% \end{tabular} -% \end{center} -% \label{table-searchpaths} -% \hrule -% \end{table} -% -% \subsection{Querying from Outside} -% -% \fileent{luaotfload-tool} also provides rudimentary means of -% accessing the information collected in the font database. -% If the option \verb|--find=|\emphasis{name} is given, the script will -% try and search the fonts indexed by \identifier{luaotfload} for a -% matching name. -% For instance, the invocation -% -% \begin{quote} -% \begin{verbatim} -% luaotfload-tool --find="Iwona Regular" -% \end{verbatim} -% \end{quote} -% -% \noindent -% will verify if “Iwona Regular” is found in the database and can be -% readily requested in a document. -% -% If you are unsure about the actual font name, then add the -% \verb|-F| (or \verb|--fuzzy|) switch to the command line to enable -% approximate matching. -% Suppose you cannot precisely remember if the variant of -% \identifier{Iwona} you are looking for was “Bright” or “Light”. -% The query -% -% \begin{quote} -% \begin{verbatim} -% luaotfload-tool -F --find="Iwona Bright" -% \end{verbatim} -% \end{quote} -% -% \noindent -% will tell you that indeed the latter name is correct. -% -% Basic information about fonts in the database can be displayed -% using the \verb|-i| option (\verb|--info|). -% \begin{quote} -% \begin{verbatim} -% luaotfload-tool -i --find="Iwona Light Italic" -% \end{verbatim} -% \end{quote} -% \noindent -% The meaning of the printed values is described in section 4.4 of the -% \LUATEX reference manual.\footnote{% -% In \TEX Live: \fileent{texmf-dist/doc/luatex/base/luatexref-t.pdf}. -% } -% -% For a much more detailed report about a given font try the \verb|-I| option -% instead (\verb|--inspect|). -% \begin{quote} -% \begin{verbatim} -% luaotfload-tool -I --find="Iwona Light Italic" -% \end{verbatim} -% \end{quote} -% -% \verb|luaotfload-tool --help| will list the available command line -% switches, including some not discussed in detail here. -% For a full documentation of \identifier{luaotfload-tool} and its -% capabilities refer to the manpage -% (\verb|man 1 luaotfload-tool|).\footnote{% -% Or see \verb|luaotfload-tool.rst| in the source directory. -% } -% -% \subsection{Blacklisting Fonts} -% \label{font-blacklist} -% -% Some fonts are problematic in general, or just in \LUATEX. -% If you find that compiling your document takes far too long or eats -% away all your system’s memory, you can track down the culprit by -% running \verb|luaotfload-tool -v| to increase verbosity. -% Take a note of the \emphasis{filename} of the font that database -% creation fails with and append it to the file -% \fileent{luaotfload-blacklist.cnf}. -% -% A blacklist file is a list of font filenames, one per line. -% Specifying the full path to where the file is located is optional, the -% plain filename should suffice. -% File extensions (\fileent{.otf}, \fileent{.ttf}, etc.) may be omitted. -% Anything after a percent (|%|) character until the end of the line -% is ignored, so use this to add comments. -% Place this file to some location where the \identifier{kpse} -% library can find it, e.~g. -% \fileent{texmf-local/tex/luatex/luaotfload} if you are running -% \identifier{\TEX Live},\footnote{% -% You may have to run \verb|mktexlsr| if you created a new file in -% your \fileent{texmf} tree. -% } -% or just leave it in the working directory of your document. -% \identifier{luaotfload} reads all files named -% \fileent{luaotfload-blacklist.cnf} it finds, so the fonts in -% \fileent{./luaotfload-blacklist.cnf} extend the global blacklist. -% -% Furthermore, a filename prepended with a dash character (|-|) is -% removed from the blacklist, causing it to be temporarily whitelisted -% without modifying the global file. -% An example with explicit paths: -% -% \begin{verbatim} -% % example otf-blacklist.cnf -% /Library/Fonts/GillSans.ttc % Luaotfload ignores this font. -% -/Library/Fonts/Optima.ttc % This one is usable again, even if -% % blacklisted somewhere else. -% \end{verbatim} -% -% \section{Files from \CONTEXT and \LUATEX-Fonts} -% -% \identifier{luaotfload} relies on code originally written by Hans -% Hagen\footnote{% -% The creator of the \href{http://wiki.contextgarden.net}{\CONTEXT} -% format. -% } -% for and tested with \CONTEXT. -% It integrates the font loader as distributed in -% the \identifier{\LUATEX-Fonts} package. -% The original \LUA source files have been combined using the -% \fileent{mtx-package} script into a single, self-contained blob. -% In this form the font loader has no further dependencies\footnote{% -% It covers, however, to some extent the functionality of the -% \identifier{lualibs} package. -% } -% and requires only minor adaptions to integrate into -% \identifier{luaotfload}. -% The guiding principle is to let \CONTEXT/\LUATEX-Fonts take care of -% the implementation, and update the imported code from time to time. -% As maintainers, we aim at importing files from upstream essentially -% \emphasis{unmodified}, except for renaming them to prevent name -% clashes. -% This job has been greatly alleviated since the advent of -% \LUATEX-Fonts, prior to which the individual dependencies had to be -% manually spotted and extracted from the \CONTEXT source code in a -% complicated and error-prone fashion. -% -% Below is a commented list of the files distributed with -% \identifier{luaotfload} in one way or the other. -% See figure \ref{file-graph} on page \pageref{file-graph} for a -% graphical representation of the dependencies. -% From \LUATEX-Fonts, only the file \fileent{luatex-fonts-merged.lua} -% has been imported as \fileent{luaotfload-fontloader.lua}. -% It is generated by \fileent{mtx-package}, a \LUA source code merging -% too developed by Hans Hagen.\footnote{% -% \fileent{mtx-package} is -% \href -% {http://repo.or.cz/w/context.git/blob_plain/refs/heads/origin:/scripts/context/lua/mtx-package.lua} -% {part of \CONTEXT} -% and requires \fileent{mtxrun}. -% Run -% \verb|mtxrun --script package --help| -% to display further information. -% For the actual merging code see the file -% \fileent{util-mrg.lua} that is part of \CONTEXT. -% } -% It houses several \LUA files that can be classed in three -% categories. -% -% \begin{itemize} -% \let\normalitem=\item -% \def\incitem#1{% -% \normalitem{\fileent{#1}} -% } -% \normalitem \emphasis{\LUA utility libraries}, a subset -% of what is provided by the \identifier{lualibs} -% package. -% -% \begin{multicols}{2} -% \begin{itemize} -% \incitem{l-lua.lua} \incitem{l-lpeg.lua} -% \incitem{l-function.lua} \incitem{l-string.lua} -% \incitem{l-table.lua} \incitem{l-io.lua} -% \incitem{l-file.lua} \incitem{l-boolean.lua} -% \incitem{l-math.lua} \incitem{util-str.lua} -% \end{itemize} -% \end{multicols} -% -% \normalitem The \emphasis{font loader} itself. -% These files have been written for -% \LUATEX-Fonts and they are distributed along -% with \identifier{luaotfload}. -% \begin{multicols}{2} -% \begin{itemize} -% \incitem{luatex-basics-gen.lua} -% \incitem{luatex-basics-nod.lua} -% \incitem{luatex-fonts-enc.lua} -% \incitem{luatex-fonts-syn.lua} -% \incitem{luatex-fonts-tfm.lua} -% \incitem{luatex-fonts-chr.lua} -% \incitem{luatex-fonts-lua.lua} -% \incitem{luatex-fonts-def.lua} -% \incitem{luatex-fonts-ext.lua} -% \incitem{luatex-fonts-cbk.lua} -% \end{itemize} -% \end{multicols} -% -% \normalitem Code related to \emphasis{font handling and -% node processing}, taken directly from -% \CONTEXT. -% \begin{multicols}{2} -% \begin{itemize} -% \incitem{data-con.lua} \incitem{font-ini.lua} -% \incitem{font-con.lua} \incitem{font-cid.lua} -% \incitem{font-map.lua} \incitem{font-oti.lua} -% \incitem{font-otf.lua} \incitem{font-otb.lua} -% \incitem{node-inj.lua} \incitem{font-ota.lua} -% \incitem{font-otn.lua} \incitem{font-def.lua} -% \incitem{font-otp.lua} -% \end{itemize} -% \end{multicols} -% \end{itemize} -% -% Note that if \identifier{luaotfload} cannot locate the -% merged file, it will load the individual \LUA libraries -% instead. -% Their names remain the same as in \CONTEXT (without the -% \verb|otfl|-prefix) since we imported the relevant section of -% \fileent{luatex-fonts.lua} unmodified into \fileent{luaotfload.lua}. -% Thus if you prefer running bleeding edge code from the -% \CONTEXT beta, all you have to do is remove -% \fileent{luaotfload-merged.lua} from the search path. -% -% Also, the merged file at some point -% loads the Adobe Glyph List from a \LUA table that is contained in -% \fileent{luaotfload-glyphlist.lua}, which is automatically generated by the -% script \fileent{mkglyphlist}.\footnote{% -% See \fileent{luaotfload-font-enc.lua}. -% The hard-coded file name is why we have to replace the procedure -% that loads the file in \fileent{luaotfload-override.lua}. -% } -% There is a make target \identifier{glyphs} that will create a fresh -% glyph list so we don’t need to import it from \CONTEXT -% any longer. -% -% In addition to these, \identifier{luaotfload} requires a number of -% files not contained in the merge. Some of these have no equivalent in -% \LUATEX-Fonts or \CONTEXT, some were taken unmodified from the -% latter. -% -% \begin{itemize} -% \let\normalitem=\item -% \def\ouritem#1{% -% \normalitem{\fileent{#1}}% -% \space--\hskip1em -% } -% \ouritem {luaotfload-features.lua} font feature handling; -% incorporates some of the code from -% \fileent{font-otc} from \CONTEXT; -% \ouritem {luaotfload-override.lua} overrides the \CONTEXT logging -% functionality. -% \ouritem {luaotfload-loaders.lua} registers the \OpenType -% font reader as handler for -% Postscript fonts -% (\abbrev{pfa}, \abbrev{pfb}). -% \ouritem {luaotfload-database.lua} font names database. -% \ouritem {luaotfload-colors.lua} color handling. -% \ouritem {luaotfload-auxiliary.lua} access to internal functionality -% for package authors -% (proposals for additions welcome). -% \ouritem {luaotfload-letterspace.lua} font-based letterspacing. -% \end{itemize} -% -% \begin{figure}[b] -% \caption{Schematic of the files in \identifier{Luaotfload}} -% \includegraphics[width=\textwidth]{filegraph.pdf} -% \label{file-graph} -% \end{figure} -% -% \section{Auxiliary Functions} -% -% With release version 2.2, \identifier{luaotfload} received -% additional functions for package authors to call from outside -% (see the file \fileent{luaotfload-auxiliary.lua} for details). -% The purpose of this addition twofold. -% Firstly, \identifier{luaotfload} failed to provide a stable interface -% to internals in the past which resulted in an unmanageable situation -% of different packages abusing the raw access to font objects by means -% of the \luafunction{patch_font} callback. -% When the structure of the font object changed due to an update, all -% of these imploded and several packages had to be fixed while -% simultaneously providing fallbacks for earlier versions. -% Now the patching is done on the \identifier{luaotfload} side and can -% be adapted with future modifications to font objects without touching -% the packages that depend on it. -% Second, some the capabilities of the font loader and the names -% database are not immediately relevant in \identifier{luaotfload} -% itself but might nevertheless be of great value to package authors or -% end users. -% -% Note that the current interface is not yet set in stone and the -% development team is open to suggestions for improvements or -% additions. -% -% \subsection{Callback Functions} -% -% The \luafunction{patch_font} callback is inserted in the wrapper -% \identifier{luaotfload} provides for the font definition callback -% (see below, page \pageref{define-font}). -% At this place it allows manipulating the font object immediately after -% the font loader is done creating it. -% For a short demonstration of its usefulness, here is a snippet that -% writes an entire font object to the file \fileent{fontdump.lua}: -% -% \begin{quote} -% \begin{verbatim} -% \input luaotfload.sty -% \directlua{ -% local dumpfile = "fontdump.lua" -% local dump_font = function (tfmdata) -% local data = table.serialize(tfmdata) -% io.savedata(dumpfile, data) -% end -% -% luatexbase.add_to_callback( -% "luaotfload.patch_font", -% dump_font, -% "my_private_callbacks.dump_font" -% ) -% } -% \font\dumpme=name:Iwona -% \bye -% \end{verbatim} -% \end{quote} -% -% \emphasis{Beware}: this creates a Lua file of around 150,000 lines of -% code, taking up 3~\abbrev{mb} of disk space. -% By inspecting the output you can get a first impression of how a font -% is structured in \LUATEX’s memory, what elements it is composed of, -% and in what ways it can be rearranged. -% -% \subsubsection{Compatibility with Earlier Versions} -% -% As has been touched on in the preface to this section, the structure -% of the object as returned by the fontloader underwent rather drastic -% changes during different stages of its development, and not all -% packages that made use of font patching have kept up with every one -% of it. -% To ensure compatibility with these as well as older versions of -% some packages, \identifier{luaotfload} sets up copies of or references -% to data in the font table where it used to be located. -% For instance, important parameters like the requested point size, the -% units factor, and the font name have again been made accessible from -% the toplevel of the table even though they were migrated to different -% subtables in the meantime. -% -% \subsubsection{Patches} -% -% These are mostly concerned with establishing compatibility with -% \XETEX. -% -% \begin{itemize} -% \let\normalitem=\item -% \def\ouritem#1{% -% \normalitem{\luafunction{#1}}% -% \hfill\break -% } -% -% \ouritem {set_sscale_dimens} -% Calculate \texmacro{fontdimen}s 10 and 11 to emulate \XETEX. -% -% \ouritem {set_capheight} -% Calculates \texmacro{fontdimen} 8 like \XETEX. -% -% \ouritem {patch_cambria_domh} -% Correct some values of the font \emphasis{Cambria Math}. -% -% \end{itemize} -% -% \subsection{Package Author’s Interface} -% -% As \LUATEX release 1.0 is nearing, the demand for a reliable interface -% for package authors increases. -% -% \subsubsection{Font Properties} -% -% Below functions mostly concern querying the different components of a -% font like for instance the glyphs it contains, or what font features -% are defined for which scripts. -% -% \begin{itemize} -% \let\normalitem=\item -% \def\ouritem#1{% -% \normalitem{\luafunction{#1}}% -% \hfill\break -% } -% -% \ouritem {aux.font_has_glyph (id : int, index : int)} -% Predicate that returns true if the font \luafunction{id} -% has glyph \luafunction{index}. -% -% \ouritem {aux.slot_of_name(name : string)} -% Translates an Adobe Glyph name to the corresponding glyph -% slot. -% -% \ouritem {aux.name_of_slot(slot : int)} -% The inverse of \luafunction{slot_of_name}; note that this -% might be incomplete as multiple glyph names may map to the -% same codepoint, only one of which is returned by -% \luafunction{name_of_slot}. -% -% \ouritem {aux.provides_script(id : int, script : string)} -% Test if a font supports \luafunction{script}. -% -% \ouritem {aux.provides_language(id : int, script : string, language : string)} -% Test if a font defines \luafunction{language} for a given -% \luafunction{script}. -% -% \ouritem {aux.provides_feature(id : int, script : string, -% language : string, feature : string)} -% Test if a font defines \luafunction{feature} for -% \luafunction{language} for a given \luafunction{script}. -% -% \ouritem {aux.get_math_dimension(id : int, dimension : string)} -% Get the dimension \luafunction{dimension} of font \luafunction{id}. -% -% \ouritem {aux.sprint_math_dimension(id : int, dimension : string)} -% Same as \luafunction{get_math_dimension()}, but output the value -% in scaled points at the \TEX end. -% -% \end{itemize} -% -% \subsubsection{Database} -% -% \begin{itemize} -% \let\normalitem=\item -% \def\ouritem#1{% -% \normalitem{\luafunction{#1}}% -% \hfill\break -% } -% -% \ouritem {aux.scan_external_dir(dir : string)} -% Include fonts in directory \luafunction{dir} in font lookups without -% adding them to the database. -% -% \end{itemize} -% -% \section{Troubleshooting} -% -% \subsection {Database Generation} -% If you encounter problems with some fonts, please first update to the latest -% version of this package before reporting a bug, as -% \identifier{luaotfload} is under active development and still a -% moving target. -% The development takes place on \identifier{github} at -% \url{https://github.com/lualatex/luaotfload} where there is an issue -% tracker for submitting bug reports, feature requests and the likes -% requests and the likes. -% -% Bug reports are more likely to be addressed if they contain the output of -% -% \begin{quote} -% \begin{verbatim} -% luaotfload-tool --diagnose=environment,files,permissions -% \end{verbatim} -% \end{quote} -% -% \noindent Consult the man page for a description of these options. -% -% Errors during database generation can be traced by increasing the -% verbosity level and redirecting log output to \fileent{stdout}: -% -% \begin{quote} -% \begin{verbatim} -% luaotfload-tool -fuvvv --log=stdout -% \end{verbatim} -% \end{quote} -% -% \noindent or to a file in \fileent{/tmp}: -% -% \begin{quote} -% \begin{verbatim} -% luaotfload-tool -fuvvv --log=file -% \end{verbatim} -% \end{quote} -% -% \noindent In the latter case, invoke the \verb|tail(1)| utility on the file -% for live monitoring of the progress. -% -% If database generation fails, the font last printed to the terminal or log -% file is likely to be the culprit. -% Please specify it when reporting a bug, and blacklist it for the time -% being (see above, page \pageref{font-blacklist}). -% -% \subsection {Font Features} -% A common problem is the lack of features for some -% \OpenType fonts even when specified. -% This can be related to the fact that some fonts do not provide -% features for the \verb|dflt| script (see above on page -% \pageref{script-tag}), -% which is the default one in this package. -% If this happens, assigning a noth script when the font is defined should -% fix it. -% For example with \verb|latn|: -% -% \begin{quote} -% \begin{verbatim} -% \font\test=file:MyFont.otf:script=latn;+liga; -% \end{verbatim} -% \end{quote} -% -% You can get a list of features that a font defines for scripts and languages -% by querying it in \fileent{luaotfload-tool}: -% -% \begin{quote} -% \begin{verbatim} -% luaotfload-tool --find="Iwona" --inspect -% \end{verbatim} -% \end{quote} -% -% \subsection {\LUATEX Programming} -% Another strategy that helps avoiding problems is to not access raw \LUATEX -% internals directly. -% Some of them, even though they are dangerous to access, have not been -% overridden or disabled. -% Thus, whenever possible prefer the functions in the -% \luafunction{aux} namespace over direct manipulation of font objects. -% For example, raw access to the \luafunction{font.fonts} table like: -% -% \begin{quote} -% \begin{verbatim} -% local somefont = font.fonts[2] -% \end{verbatim} -% \end{quote} -% -% \noindent can render already defined fonts unusable. -% Instead, the function \luafunction{font.getfont()} should be used because -% it has been replaced by a safe variant. -% -% However, \luafunction{font.getfont()} only covers fonts handled by the font -% loader, e.~g. \identifier{OpenType} and \identifier{TrueType} fonts, but -% not \abbrev{tfm} or \abbrev{ofm}. -% Should you absolutely require access to all fonts known to \LUATEX, including -% the virtual and autogenerated ones, then you need to query both -% \luafunction{font.getfont()} and \luafunction{font.fonts}. -% In this case, best define you own accessor: -% -% \begin{quote} -% \begin{verbatim} -% local unsafe_getfont = function (id) -% local tfmdata = font.getfont (id) -% if not tfmdata then -% tfmdata = font.fonts[id] -% end -% return tfmdata -% end -% -% --- use like getfont() -% local somefont = unsafe_getfont (2) -% \end{verbatim} -% \end{quote} -% -% \part{Implementation} -% -% \section{\fileent{luaotfload.lua}} -% -% This file initializes the system and loads the font loader. -% To minimize potential conflicts between other packages and the -% code imported from \CONTEXT, several precautions are in order. -% Some of the functionality that the font loader expects to be present, -% like raw access to callbacks, are assumed to have been disabled by -% \identifier{luatexbase} when this file is processed. -% In some cases it is possible to trick it by putting dummies into -% place and restoring the behavior from \identifier{luatexbase} after -% initilization. -% Other cases such as attribute allocation require that we hook the -% functionality from \identifier{luatexbase} into locations where they -% normally wouldn’t be. -% -% Anyways we can import the code base without modifications, which is -% due mostly to the extra effort by -% Hans Hagen to make \LUATEX-Fonts self-contained and encapsulate it, -% and especially due to his willingness to incorporate our suggestions. -% -% \iffalse -%<*lua> -% \fi -% \begin{macrocode} -luaotfload = luaotfload or {} -local luaotfload = luaotfload - -config = config or { } -config.luaotfload = config.luaotfload or { } -------.luaotfload.resolver = config.luaotfload.resolver or "normal" -config.luaotfload.resolver = config.luaotfload.resolver or "cached" -config.luaotfload.definer = config.luaotfload.definer or "patch" -config.luaotfload.compatibility = config.luaotfload.compatibility or false -config.luaotfload.loglevel = config.luaotfload.loglevel or 2 -config.luaotfload.color_callback = config.luaotfload.color_callback or "pre_linebreak_filter" -config.luaotfload.prioritize = config.luaotfload.prioritize or "sys" -config.luaotfload.names_dir = config.luaotfload.names_dir or "names" -config.luaotfload.cache_dir = config.luaotfload.cache_dir or "fonts" -config.luaotfload.index_file = config.luaotfload.index_file or "luaotfload-names.lua" -config.luaotfload.formats = config.luaotfload.formats or "otf,ttf,ttc,dfont" -if not config.luaotfload.strip then - config.luaotfload.strip = true -end - -luaotfload.module = { - name = "luaotfload", - version = 2.40005, --- 2.4-4 - date = "2014/05/18", - description = "OpenType layout system.", - author = "Elie Roux & Hans Hagen", - copyright = "Elie Roux", - license = "GPL v2.0" -} - -local luatexbase = luatexbase - -local setmetatable = setmetatable -local type, next = type, next - -local kpsefind_file = kpse.find_file -local lfsisfile = lfs.isfile - -local add_to_callback, create_callback = - luatexbase.add_to_callback, luatexbase.create_callback -local reset_callback, call_callback = - luatexbase.reset_callback, luatexbase.call_callback - -local dummy_function = function () end - -local error, warning, info, log = - luatexbase.provides_module(luaotfload.module) - -luaotfload.error = error -luaotfload.warning = warning -luaotfload.info = info -luaotfload.log = log - -% \end{macrocode} -% We set the minimum version requirement for \LUATEX to v0.76, -% because the font loader requires recent features like direct -% attribute indexing and \luafunction{node.end_of_math()} that aren’t -% available in earlier versions.\footnote{% -% See Taco’s announcement of v0.76: -% \url{http://comments.gmane.org/gmane.comp.tex.luatex.user/4042} -% and this commit by Hans that introduced those features. -% \url{http://repo.or.cz/w/context.git/commitdiff/a51f6cf6ee087046a2ae5927ed4edff0a1acec1b}. -% } -% -% \begin{macrocode} - -local luatex_version = 76 - -if tex.luatexversion < luatex_version then - warning("LuaTeX v%.2f is old, v%.2f is recommended.", - tex.luatexversion/100, - luatex_version /100) - --- we install a fallback for older versions as a safety - if not node.end_of_math then - local math_t = node.id"math" - local traverse_nodes = node.traverse_id - node.end_of_math = function (n) - for n in traverse_nodes(math_t, n.next) do - return n - end - end - end -end - -% \end{macrocode} -% \subsection{Module loading} -% We load the files imported from \CONTEXT with this function. -% It automatically prepends the prefix \fileent{luaotfload-} to its -% argument, so we can refer to the files with their actual \CONTEXT name. -% -% \begin{macrocode} - -local fl_prefix = "luaotfload" -- “luatex” for luatex-plain -local loadmodule = function (name) - require(fl_prefix .."-"..name) -end - -% \end{macrocode} -% Before \TeX Live 2013 version, \LUATEX had a bug that made ofm fonts fail -% when called with their extension. There was a side-effect making ofm -% totally unloadable when luaotfload was present. The following lines are -% a patch for this bug. The utility of these lines is questionable as they -% are not necessary since \TeX Live 2013. They should be removed in the next -% version. -% -% \begin{macrocode} -local Cs, P, lpegmatch = lpeg.Cs, lpeg.P, lpeg.match - -local p_dot, p_slash = P".", P"/" -local p_suffix = (p_dot * (1 - p_dot - p_slash)^1 * P(-1)) / "" -local p_removesuffix = Cs((p_suffix + 1)^1) - -local find_vf_file = function (name) - local fullname = kpsefind_file(name, "ovf") - if not fullname then - --fullname = kpsefind_file(file.removesuffix(name), "ovf") - fullname = kpsefind_file(lpegmatch(p_removesuffix, name), "ovf") - end - if fullname then - log("loading virtual font file %s.", fullname) - end - return fullname -end - -% \end{macrocode} -% \subsection{Preparing the Font Loader} -% We treat the fontloader as a black box so behavior is consistent -% between formats. -% We do no longer run the intermediate wrapper file -% \fileent{luaotfload-fonts.lua} which we used to import from -% \href{http://standalone.contextgarden.net/current/context/experimental/tex/generic/context/luatex/}{\LUATEX-Plain}. -% Rather, we load the fontloader code directly in the same fashion as -% \identifier{luatex-fonts}. -% How this is executed depends on the presence on the \emphasis{merged -% font loader code}. -% In \identifier{luaotfload} this is contained in the file -% \fileent{luaotfload-merged.lua}. -% If this file cannot be found, the original libraries from \CONTEXT of -% which the merged code was composed are loaded instead. -% The imported font loader will call \luafunction{callback.register} once -% while reading \fileent{font-def.lua}. -% This is unavoidable unless we modify the imported files, but harmless -% if we make it call a dummy instead. -% However, this problem might vanish if we decide to do the merging -% ourselves, like the \identifier{lualibs} package does. -% With this step we would obtain the freedom to load our own overrides in -% the process right where they are needed, at the cost of losing -% encapsulation. -% The decision on how to progress is currently on indefinite hold. -% -% \begin{macrocode} - -local starttime = os.gettimeofday() - -local trapped_register = callback.register -callback.register = dummy_function - -% \end{macrocode} -% By default, the fontloader requires a number of \emphasis{private -% attributes} for internal use. -% These must be kept consistent with the attribute handling methods as -% provided by \identifier{luatexbase}. -% Our strategy is to override the function that allocates new attributes -% before we initialize the font loader, making it a wrapper around -% \luafunction{luatexbase.new_attribute}.\footnote{% -% Many thanks, again, to Hans Hagen for making this part -% configurable! -% } -% The attribute identifiers are prefixed “\fileent{luaotfload@}” to -% avoid name clashes. -% -% \begin{macrocode} - -do - local new_attribute = luatexbase.new_attribute - local the_attributes = luatexbase.attributes - - attributes = attributes or { } - - attributes.private = function (name) - local attr = "luaotfload@" .. name --- used to be: “otfl@” - local number = the_attributes[attr] - if not number then - number = new_attribute(attr) - end - return number - end -end - -% \end{macrocode} -% These next lines replicate the behavior of \fileent{luatex-fonts.lua}. -% -% \begin{macrocode} - -local context_environment = { } - -local push_namespaces = function () - log("push namespace for font loader") - local normalglobal = { } - for k, v in next, _G do - normalglobal[k] = v - end - return normalglobal -end - -local pop_namespaces = function (normalglobal, isolate) - if normalglobal then - local _G = _G - local mode = "non-destructive" - if isolate then mode = "destructive" end - log("pop namespace from font loader -- " .. mode) - for k, v in next, _G do - if not normalglobal[k] then - context_environment[k] = v - if isolate then - _G[k] = nil - end - end - end - for k, v in next, normalglobal do - _G[k] = v - end - -- just to be sure: - setmetatable(context_environment,_G) - else - log("irrecoverable error during pop_namespace: no globals to restore") - os.exit() - end -end - -luaotfload.context_environment = context_environment -luaotfload.push_namespaces = push_namespaces -luaotfload.pop_namespaces = pop_namespaces - -local our_environment = push_namespaces() - -% \end{macrocode} -% The font loader requires that the attribute with index zero be zero. -% We happily oblige. -% (Cf. \fileent{luatex-fonts-nod.lua}.) -% -% \begin{macrocode} - -tex.attribute[0] = 0 - -% \end{macrocode} -% Now that things are sorted out we can finally load the fontloader. -% -% \begin{macrocode} - -loadmodule"fontloader.lua" ----loadmodule"font-odv.lua" --- <= Devanagari support from Context - -if fonts then - - if not fonts._merge_loaded_message_done_ then - log [["I am using the merged version of 'luaotfload.lua' here.]] - log [[ If you run into problems or experience unexpected]] - log [[ behaviour, and if you have ConTeXt installed you can try]] - log [[ to delete the file 'luaotfload-merged.lua' as I might]] - log [[ then use the possibly updated libraries. The merged]] - log [[ version is not supported as it is a frozen instance.]] - log [[ Problems can be reported to the ConTeXt mailing list."]] - end - fonts._merge_loaded_message_done_ = true - -else--- the loading sequence is known to change, so this might have to - --- be updated with future updates! - --- do not modify it though unless there is a change to the merged - --- package! - loadmodule("l-lua.lua") - loadmodule("l-lpeg.lua") - loadmodule("l-function.lua") - loadmodule("l-string.lua") - loadmodule("l-table.lua") - loadmodule("l-io.lua") - loadmodule("l-file.lua") - loadmodule("l-boolean.lua") - loadmodule("l-math.lua") - loadmodule("util-str.lua") - loadmodule('luatex-basics-gen.lua') - loadmodule('data-con.lua') - loadmodule('luatex-basics-nod.lua') - loadmodule('font-ini.lua') - loadmodule('font-con.lua') - loadmodule('luatex-fonts-enc.lua') - loadmodule('font-cid.lua') - loadmodule('font-map.lua') - loadmodule('luatex-fonts-syn.lua') - loadmodule('luatex-fonts-tfm.lua') - loadmodule('font-oti.lua') - loadmodule('font-otf.lua') - loadmodule('font-otb.lua') - loadmodule('node-inj.lua') - loadmodule('font-ota.lua') - loadmodule('font-otn.lua') - loadmodule('font-otp.lua')--- since 2013-04-23 - loadmodule('luatex-fonts-lua.lua') - loadmodule('font-def.lua') - loadmodule('luatex-fonts-def.lua') - loadmodule('luatex-fonts-ext.lua') - loadmodule('luatex-fonts-cbk.lua') -end --- non-merge fallback scope - -% \end{macrocode} -% Here we adjust the globals created during font loader initialization. -% If the second argument to \luafunction{pop_namespaces()} is \verb|true| -% this will restore the state of \luafunction{_G}, eliminating every -% global generated since the last call to \luafunction{push_namespaces()}. -% At the moment we see no reason to do this, and since the font loader is -% considered an essential part of \identifier{luatex} as well as a very -% well organized piece of code, we happily concede it the right to add to -% \luafunction{_G} if needed. -% -% \begin{macrocode} - -pop_namespaces(our_environment, false)-- true) - -log("fontloader loaded in %0.3f seconds", os.gettimeofday()-starttime) - -% \end{macrocode} -% \subsection{Callbacks} -% After the fontloader is ready we can restore the callback trap from -% \identifier{luatexbase}. -% -% \begin{macrocode} - -callback.register = trapped_register - -% \end{macrocode} -% We do our own callback handling with the means provided by luatexbase. -% Note: \luafunction{pre_linebreak_filter} and \luafunction{hpack_filter} -% are coupled in \CONTEXT in the concept of \emphasis{node processor}. -% -% \begin{macrocode} - -add_to_callback("pre_linebreak_filter", - nodes.simple_font_handler, - "luaotfload.node_processor", - 1) -add_to_callback("hpack_filter", - nodes.simple_font_handler, - "luaotfload.node_processor", - 1) -add_to_callback("find_vf_file", - find_vf_file, "luaotfload.find_vf_file") - -loadmodule"override.lua" --- “luat-ovr” - -logs.set_loglevel(config.luaotfload.loglevel) - -% \end{macrocode} -% Now we load the modules written for \identifier{luaotfload}. -% -% \begin{macrocode} -loadmodule"loaders.lua" --- “font-pfb” new in 2.0, added 2011 -loadmodule"database.lua" --- “font-nms” -loadmodule"colors.lua" --- “font-clr” - -% \end{macrocode} -% Relying on the \verb|name:| resolver for everything has been the source -% of permanent trouble with the database. -% With the introduction of the new syntax parser we now have enough -% granularity to distinguish between the \XETEX emulation layer and the -% genuine \verb|name:| and \verb|file:| lookups of \LUATEX-Fonts. -% Another benefit is that we can now easily plug in or replace new lookup -% behaviors if necessary. -% The name resolver remains untouched, but it calls -% \luafunction{fonts.names.resolve()} internally anyways (see -% \fileent{luaotfload-database.lua}). -% -% \begin{macrocode} - -local filesuffix = file.suffix -local fileremovesuffix = file.removesuffix -local request_resolvers = fonts.definers.resolvers -local formats = fonts.formats -local names = fonts.names -formats.ofm = "type1" - -fonts.encodings.known = fonts.encodings.known or { } - -% \end{macrocode} -% \identifier{luaotfload} promises easy access to system fonts. -% Without additional precautions, this cannot be achieved by -% \identifier{kpathsea} alone, because it searches only the -% \fileent{texmf} directories by default. -% Although it is possible for \identifier{kpathsea} to include extra -% paths by adding them to the \verb|OSFONTDIR| environment variable, -% this is still short of the goal »\emphasis{it just works!}«. -% When building the font database \identifier{luaotfload} scans -% system font directories anyways, so we already have all the -% information for looking sytem fonts. -% With the release version 2.2 the file names are indexed in the database -% as well and we are ready to resolve \verb|file:| lookups this way. -% Thus we no longer need to call the \identifier{kpathsea} library in -% most cases when looking up font files, only when generating the database, -% and when verifying the existence of a file in the \fileent{texmf} tree. -% -% \begin{macrocode} - -local resolve_file = names.crude_file_lookup ---local resolve_file = names.crude_file_lookup_verbose -local resolve_name = names.resolve_name - -local file_resolver = function (specification) - local name = resolve_file (specification.name) - local suffix = filesuffix(name) - if formats[suffix] then - specification.forced = string.lower (suffix) - specification.forcedname = file.removesuffix(name) - else - specification.name = name - end -end - -request_resolvers.file = file_resolver - -% \end{macrocode} -% We classify as \verb|anon:| those requests that have neither a -% prefix nor brackets. According to Khaled\footnote{% -% \url{https://github.com/phi-gamma/luaotfload/issues/4#issuecomment-17090553}. -% } -% they are the \XETEX equivalent of a \verb|name:| request, so we will be -% treating them as such. -% -% \begin{macrocode} - ---request_resolvers.anon = request_resolvers.name - -% \end{macrocode} -% There is one drawback, though. -% This syntax is also used for requesting fonts in \identifier{Type1} -% (\abbrev{tfm}, \abbrev{ofm}) format. -% These are essentially \verb|file:| lookups and must be caught before -% the \verb|name:| resolver kicks in, lest they cause the database to -% update. -% Even if we were to require the \verb|file:| prefix for all -% \identifier{Type1} requests, tests have shown that certain fonts still -% include further fonts (e.~g. \fileent{omlgcb.ofm} will ask for -% \fileent{omsecob.tfm}) \emphasis{using the old syntax}. -% For this reason, we introduce an extra check with an early return. -% -% \begin{macrocode} - -local type1_formats = { "tfm", "ofm", } - -request_resolvers.anon = function (specification) - local name = specification.name - for i=1, #type1_formats do - local format = type1_formats[i] - if resolvers.findfile(name, format) then - specification.forcedname = file.addsuffix(name, format) - specification.forced = format - return - end - end - --- under some weird circumstances absolute paths get - --- passed to the definer; we have to catch them - --- before the name: resolver misinterprets them. - name = specification.specification - local exists, _ = lfsisfile(name) - if exists then --- garbage; we do this because we are nice, - --- not because it is correct - logs.names_report("log", 1, "load", "file %q exists", name) - logs.names_report("log", 1, "load", - "... overriding borked anon: lookup with path: lookup") - specification.name = name - request_resolvers.path(specification) - return - end - request_resolvers.name(specification) -end - -% \end{macrocode} -% Prior to version 2.2, \identifier{luaotfload} did not distinguish -% \verb|file:| and \verb|path:| lookups, causing complications with the -% resolver. -% Now we test if the requested name is an absolute path in the file -% system, otherwise we fall back to the \verb|file:| lookup. -% -% \begin{macrocode} - -request_resolvers.path = function (specification) - local name = specification.name - local exists, _ = lfsisfile(name) - if not exists then -- resort to file: lookup - logs.names_report("log", 1, "load", - "path lookup of %q unsuccessful, falling back to file:", - name) - file_resolver (specification) - else - local suffix = filesuffix (name) - if formats[suffix] then - specification.forced = string.lower (suffix) - specification.name = file.removesuffix(name) - specification.forcedname = name - else - specification.name = name - end - end -end - -% \end{macrocode} -% {\bfseries EXPERIMENTAL}: -% \identifier{kpse}-only resolver, for those who can do without system -% fonts. -% -% \begin{macrocode} - -request_resolvers.kpse = function (specification) - local name = specification.name - local suffix = filesuffix(name) - if suffix and formats[suffix] then - name = file.removesuffix(name) - if resolvers.findfile(name, suffix) then - specification.forced = string.lower (suffix) - specification.forcedname = name - return - end - end - for t, format in next, formats do --- brute force - if kpse.find_file (name, format) then - specification.forced = t - specification.name = name - return - end - end -end - -% \end{macrocode} -% The \verb|name:| resolver wraps the database function -% \luafunction{resolve_name}. -% -% \begin{macrocode} - ---- fonts.names.resolvers.name -- Customized version of the ---- generic name resolver. - -request_resolvers.name = function (specification) - local resolved, subfont = resolve_name (specification) - if resolved then - specification.resolved = resolved - specification.sub = subfont - specification.forced = string.lower (filesuffix (resolved) or "") - specification.forcedname = resolved - specification.name = fileremovesuffix (resolved) - else - file_resolver (specification) - end -end - -% \end{macrocode} -% Also {\bfseries EXPERIMENTAL}: -% custom file resolvers via callback. -% -% \begin{macrocode} -create_callback("luaotfload.resolve_font", "simple", dummy_function) - -request_resolvers.my = function (specification) - call_callback("luaotfload.resolve_font", specification) -end - -% \end{macrocode} -% We create a callback for patching fonts on the fly, to be used by other -% packages. -% It initially contains the empty function that we are going to override -% below. -% -% \begin{macrocode} - -create_callback("luaotfload.patch_font", "simple", dummy_function) - -% \end{macrocode} -% \subsection{\CONTEXT override} -% \label{define-font} -% We provide a simplified version of the original font definition -% callback. -% -% \begin{macrocode} - -local read_font_file = fonts.definers.read - ---- spec -> size -> id -> tmfdata -local patch_defined_font = function (specification, size, id) - local tfmdata = read_font_file(specification, size, id) - if type(tfmdata) == "table" and tfmdata.shared then - --- We need to test for the “shared” field here - --- or else the fontspec capheight callback will - --- operate on tfm fonts. - call_callback("luaotfload.patch_font", tfmdata, specification) - end - return tfmdata -end - -reset_callback "define_font" - -% \end{macrocode} -% Finally we register the callbacks. -% -% \begin{macrocode} - -local font_definer = config.luaotfload.definer - -if font_definer == "generic" then - add_to_callback("define_font", - fonts.definers.read, - "luaotfload.define_font", - 1) -elseif font_definer == "patch" then - add_to_callback("define_font", - patch_defined_font, - "luaotfload.define_font", - 1) -end - -loadmodule"features.lua" --- contains what was “font-ltx” and “font-otc” -loadmodule"letterspace.lua" --- extra character kerning -loadmodule"auxiliary.lua" --- additionaly high-level functionality (new) - -luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec - --- vim:tw=71:sw=4:ts=4:expandtab - -% \end{macrocode} -% -% \iffalse -% -% \fi -% -% \section{\fileent{luaotfload.sty}} -% -% \iffalse -%<*package> -% \fi -% -% Classical Plain+\LATEX package initialization. -% -% \begin{macrocode} -\csname ifluaotfloadloaded\endcsname -\let\ifluaotfloadloaded\endinput -\bgroup\expandafter\expandafter\expandafter\egroup -\expandafter\ifx\csname ProvidesPackage\endcsname\relax - \input luatexbase.sty -\else - \NeedsTeXFormat{LaTeX2e} - \ProvidesPackage{luaotfload}% - [2014/05/18 v2.4-4 OpenType layout system] - \RequirePackage{luatexbase} -\fi -\ifnum\luatexversion<76 - %% here some deprecation warning would be in order - \RequireLuaModule{lualibs} - \RequireLuaModule{luaotfload-legacy} -\else - \RequireLuaModule{luaotfload} -\fi -\endinput -% \end{macrocode} -% \iffalse -% -% \fi -% -% \clearpage -% \section{The GNU GPL License v2} -% -% The GPL requires the complete license text to be distributed along -% with the code. I recommend the canonical source, instead: -% \url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html}. -% But if you insist on an included copy, here it is. -% You might want to zoom in. -% -% \newsavebox{\gpl} -% \begin{lrbox}{\gpl} -% \begin{minipage}{3\textwidth} -% \columnsep=3\columnsep -% \begin{multicols}{3} -% \begin{center} -% {\Large GNU GENERAL PUBLIC LICENSE\par} -% \bigskip -% {Version 2, June 1991} -% \end{center} -% -% \begin{center} -% {\parindent 0in -% -% Copyright \textcopyright\ 1989, 1991 Free Software Foundation, Inc. -% -% \bigskip -% -% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -% -% \bigskip -% -% Everyone is permitted to copy and distribute verbatim copies -% of this license document, but changing it is not allowed. -% } -% \end{center} -% -% \begin{center} -% {\bf\large Preamble} -% \end{center} -% -% -% The licenses for most software are designed to take away your freedom to -% share and change it. By contrast, the GNU General Public License is -% intended to guarantee your freedom to share and change free software---to -% make sure the software is free for all its users. This General Public -% License applies to most of the Free Software Foundation's software and to -% any other program whose authors commit to using it. (Some other Free -% Software Foundation software is covered by the GNU Library General Public -% License instead.) You can apply it to your programs, too. -% -% When we speak of free software, we are referring to freedom, not price. -% Our General Public Licenses are designed to make sure that you have the -% freedom to distribute copies of free software (and charge for this service -% if you wish), that you receive source code or can get it if you want it, -% that you can change the software or use pieces of it in new free programs; -% and that you know you can do these things. -% -% To protect your rights, we need to make restrictions that forbid anyone to -% deny you these rights or to ask you to surrender the rights. These -% restrictions translate to certain responsibilities for you if you -% distribute copies of the software, or if you modify it. -% -% For example, if you distribute copies of such a program, whether gratis or -% for a fee, you must give the recipients all the rights that you have. You -% must make sure that they, too, receive or can get the source code. And -% you must show them these terms so they know their rights. -% -% We protect your rights with two steps: (1) copyright the software, and (2) -% offer you this license which gives you legal permission to copy, -% distribute and/or modify the software. -% -% Also, for each author's protection and ours, we want to make certain that -% everyone understands that there is no warranty for this free software. If -% the software is modified by someone else and passed on, we want its -% recipients to know that what they have is not the original, so that any -% problems introduced by others will not reflect on the original authors' -% reputations. -% -% Finally, any free program is threatened constantly by software patents. -% We wish to avoid the danger that redistributors of a free program will -% individually obtain patent licenses, in effect making the program -% proprietary. To prevent this, we have made it clear that any patent must -% be licensed for everyone's free use or not licensed at all. -% -% The precise terms and conditions for copying, distribution and -% modification follow. -% -% \begin{center} -% {\Large \sc Terms and Conditions For Copying, Distribution and -% Modification} -% \end{center} -% -% \begin{enumerate} -% \item -% This License applies to any program or other work which contains a notice -% placed by the copyright holder saying it may be distributed under the -% terms of this General Public License. The ``Program'', below, refers to -% any such program or work, and a ``work based on the Program'' means either -% the Program or any derivative work under copyright law: that is to say, a -% work containing the Program or a portion of it, either verbatim or with -% modifications and/or translated into another language. (Hereinafter, -% translation is included without limitation in the term ``modification''.) -% Each licensee is addressed as ``you''. -% -% Activities other than copying, distribution and modification are not -% covered by this License; they are outside its scope. The act of -% running the Program is not restricted, and the output from the Program -% is covered only if its contents constitute a work based on the -% Program (independent of having been made by running the Program). -% Whether that is true depends on what the Program does. -% -% \item You may copy and distribute verbatim copies of the Program's source -% code as you receive it, in any medium, provided that you conspicuously -% and appropriately publish on each copy an appropriate copyright notice -% and disclaimer of warranty; keep intact all the notices that refer to -% this License and to the absence of any warranty; and give any other -% recipients of the Program a copy of this License along with the Program. -% -% You may charge a fee for the physical act of transferring a copy, and you -% may at your option offer warranty protection in exchange for a fee. -% -% \item -% You may modify your copy or copies of the Program or any portion -% of it, thus forming a work based on the Program, and copy and -% distribute such modifications or work under the terms of Section 1 -% above, provided that you also meet all of these conditions: -% -% \begin{enumerate} -% -% \item -% You must cause the modified files to carry prominent notices stating that -% you changed the files and the date of any change. -% -% \item -% You must cause any work that you distribute or publish, that in -% whole or in part contains or is derived from the Program or any -% part thereof, to be licensed as a whole at no charge to all third -% parties under the terms of this License. -% -% \item -% If the modified program normally reads commands interactively -% when run, you must cause it, when started running for such -% interactive use in the most ordinary way, to print or display an -% announcement including an appropriate copyright notice and a -% notice that there is no warranty (or else, saying that you provide -% a warranty) and that users may redistribute the program under -% these conditions, and telling the user how to view a copy of this -% License. (Exception: if the Program itself is interactive but -% does not normally print such an announcement, your work based on -% the Program is not required to print an announcement.) -% -% \end{enumerate} -% -% -% These requirements apply to the modified work as a whole. If -% identifiable sections of that work are not derived from the Program, -% and can be reasonably considered independent and separate works in -% themselves, then this License, and its terms, do not apply to those -% sections when you distribute them as separate works. But when you -% distribute the same sections as part of a whole which is a work based -% on the Program, the distribution of the whole must be on the terms of -% this License, whose permissions for other licensees extend to the -% entire whole, and thus to each and every part regardless of who wrote it. -% -% Thus, it is not the intent of this section to claim rights or contest -% your rights to work written entirely by you; rather, the intent is to -% exercise the right to control the distribution of derivative or -% collective works based on the Program. -% -% In addition, mere aggregation of another work not based on the Program -% with the Program (or with a work based on the Program) on a volume of -% a storage or distribution medium does not bring the other work under -% the scope of this License. -% -% \item -% You may copy and distribute the Program (or a work based on it, -% under Section 2) in object code or executable form under the terms of -% Sections 1 and 2 above provided that you also do one of the following: -% -% \begin{enumerate} -% -% \item -% -% Accompany it with the complete corresponding machine-readable -% source code, which must be distributed under the terms of Sections -% 1 and 2 above on a medium customarily used for software interchange; or, -% -% \item -% -% Accompany it with a written offer, valid for at least three -% years, to give any third party, for a charge no more than your -% cost of physically performing source distribution, a complete -% machine-readable copy of the corresponding source code, to be -% distributed under the terms of Sections 1 and 2 above on a medium -% customarily used for software interchange; or, -% -% \item -% -% Accompany it with the information you received as to the offer -% to distribute corresponding source code. (This alternative is -% allowed only for noncommercial distribution and only if you -% received the program in object code or executable form with such -% an offer, in accord with Subsection b above.) -% -% \end{enumerate} -% -% -% The source code for a work means the preferred form of the work for -% making modifications to it. For an executable work, complete source -% code means all the source code for all modules it contains, plus any -% associated interface definition files, plus the scripts used to -% control compilation and installation of the executable. However, as a -% special exception, the source code distributed need not include -% anything that is normally distributed (in either source or binary -% form) with the major components (compiler, kernel, and so on) of the -% operating system on which the executable runs, unless that component -% itself accompanies the executable. -% -% If distribution of executable or object code is made by offering -% access to copy from a designated place, then offering equivalent -% access to copy the source code from the same place counts as -% distribution of the source code, even though third parties are not -% compelled to copy the source along with the object code. -% -% \item -% You may not copy, modify, sublicense, or distribute the Program -% except as expressly provided under this License. Any attempt -% otherwise to copy, modify, sublicense or distribute the Program is -% void, and will automatically terminate your rights under this License. -% However, parties who have received copies, or rights, from you under -% this License will not have their licenses terminated so long as such -% parties remain in full compliance. -% -% \item -% You are not required to accept this License, since you have not -% signed it. However, nothing else grants you permission to modify or -% distribute the Program or its derivative works. These actions are -% prohibited by law if you do not accept this License. Therefore, by -% modifying or distributing the Program (or any work based on the -% Program), you indicate your acceptance of this License to do so, and -% all its terms and conditions for copying, distributing or modifying -% the Program or works based on it. -% -% \item -% Each time you redistribute the Program (or any work based on the -% Program), the recipient automatically receives a license from the -% original licensor to copy, distribute or modify the Program subject to -% these terms and conditions. You may not impose any further -% restrictions on the recipients' exercise of the rights granted herein. -% You are not responsible for enforcing compliance by third parties to -% this License. -% -% \item -% If, as a consequence of a court judgment or allegation of patent -% infringement or for any other reason (not limited to patent issues), -% conditions are imposed on you (whether by court order, agreement or -% otherwise) that contradict the conditions of this License, they do not -% excuse you from the conditions of this License. If you cannot -% distribute so as to satisfy simultaneously your obligations under this -% License and any other pertinent obligations, then as a consequence you -% may not distribute the Program at all. For example, if a patent -% license would not permit royalty-free redistribution of the Program by -% all those who receive copies directly or indirectly through you, then -% the only way you could satisfy both it and this License would be to -% refrain entirely from distribution of the Program. -% -% If any portion of this section is held invalid or unenforceable under -% any particular circumstance, the balance of the section is intended to -% apply and the section as a whole is intended to apply in other -% circumstances. -% -% It is not the purpose of this section to induce you to infringe any -% patents or other property right claims or to contest validity of any -% such claims; this section has the sole purpose of protecting the -% integrity of the free software distribution system, which is -% implemented by public license practices. Many people have made -% generous contributions to the wide range of software distributed -% through that system in reliance on consistent application of that -% system; it is up to the author/donor to decide if he or she is willing -% to distribute software through any other system and a licensee cannot -% impose that choice. -% -% This section is intended to make thoroughly clear what is believed to -% be a consequence of the rest of this License. -% -% \item -% If the distribution and/or use of the Program is restricted in -% certain countries either by patents or by copyrighted interfaces, the -% original copyright holder who places the Program under this License -% may add an explicit geographical distribution limitation excluding -% those countries, so that distribution is permitted only in or among -% countries not thus excluded. In such case, this License incorporates -% the limitation as if written in the body of this License. -% -% \item -% The Free Software Foundation may publish revised and/or new versions -% of the General Public License from time to time. Such new versions will -% be similar in spirit to the present version, but may differ in detail to -% address new problems or concerns. -% -% Each version is given a distinguishing version number. If the Program -% specifies a version number of this License which applies to it and ``any -% later version'', you have the option of following the terms and conditions -% either of that version or of any later version published by the Free -% Software Foundation. If the Program does not specify a version number of -% this License, you may choose any version ever published by the Free Software -% Foundation. -% -% \item -% If you wish to incorporate parts of the Program into other free -% programs whose distribution conditions are different, write to the author -% to ask for permission. For software which is copyrighted by the Free -% Software Foundation, write to the Free Software Foundation; we sometimes -% make exceptions for this. Our decision will be guided by the two goals -% of preserving the free status of all derivatives of our free software and -% of promoting the sharing and reuse of software generally. -% -% \begin{center} -% {\Large\sc -% No Warranty -% } -% \end{center} -% -% \item -% {\sc Because the program is licensed free of charge, there is no warranty -% for the program, to the extent permitted by applicable law. Except when -% otherwise stated in writing the copyright holders and/or other parties -% provide the program ``as is'' without warranty of any kind, either expressed -% or implied, including, but not limited to, the implied warranties of -% merchantability and fitness for a particular purpose. The entire risk as -% to the quality and performance of the program is with you. Should the -% program prove defective, you assume the cost of all necessary servicing, -% repair or correction.} -% -% \item -% {\sc In no event unless required by applicable law or agreed to in writing -% will any copyright holder, or any other party who may modify and/or -% redistribute the program as permitted above, be liable to you for damages, -% including any general, special, incidental or consequential damages arising -% out of the use or inability to use the program (including but not limited -% to loss of data or data being rendered inaccurate or losses sustained by -% you or third parties or a failure of the program to operate with any other -% programs), even if such holder or other party has been advised of the -% possibility of such damages.} -% -% \end{enumerate} -% -% -% \begin{center} -% {\Large\sc End of Terms and Conditions} -% \end{center} -% -% -% \pagebreak[2] -% -% \section*{Appendix: How to Apply These Terms to Your New Programs} -% -% If you develop a new program, and you want it to be of the greatest -% possible use to the public, the best way to achieve this is to make it -% free software which everyone can redistribute and change under these -% terms. -% -% To do so, attach the following notices to the program. It is safest to -% attach them to the start of each source file to most effectively convey -% the exclusion of warranty; and each file should have at least the -% ``copyright'' line and a pointer to where the full notice is found. -% -% \begin{quote} -% one line to give the program's name and a brief idea of what it does. \\ -% Copyright (C) yyyy name of author \\ -% -% This program is free software; you can redistribute it and/or modify -% it under the terms of the GNU General Public License as published by -% the Free Software Foundation; either version 2 of the License, or -% (at your option) any later version. -% -% This program is distributed in the hope that it will be useful, -% but WITHOUT ANY WARRANTY; without even the implied warranty of -% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -% GNU General Public License for more details. -% -% You should have received a copy of the GNU General Public License -% along with this program; if not, write to the Free Software -% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -% \end{quote} -% -% Also add information on how to contact you by electronic and paper mail. -% -% If the program is interactive, make it output a short notice like this -% when it starts in an interactive mode: -% -% \begin{quote} -% Gnomovision version 69, Copyright (C) yyyy name of author \\ -% Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. \\ -% This is free software, and you are welcome to redistribute it -% under certain conditions; type `show c' for details. -% \end{quote} -% -% -% The hypothetical commands {\tt show w} and {\tt show c} should show the -% appropriate parts of the General Public License. Of course, the commands -% you use may be called something other than {\tt show w} and {\tt show c}; -% they could even be mouse-clicks or menu items---whatever suits your -% program. -% -% You should also get your employer (if you work as a programmer) or your -% school, if any, to sign a ``copyright disclaimer'' for the program, if -% necessary. Here is a sample; alter the names: -% -% \begin{quote} -% Yoyodyne, Inc., hereby disclaims all copyright interest in the program \\ -% `Gnomovision' (which makes passes at compilers) written by James Hacker. \\ -% -% signature of Ty Coon, 1 April 1989 \\ -% Ty Coon, President of Vice -% \end{quote} -% -% -% This General Public License does not permit incorporating your program -% into proprietary programs. If your program is a subroutine library, you -% may consider it more useful to permit linking proprietary applications -% with the library. If this is what you want to do, use the GNU Library -% General Public License instead of this License. -% -% \end{multicols} -% \end{minipage} -% \end{lrbox} -% -% \begin{center} -% \scalebox{0.33}{\usebox{\gpl}} -% \end{center} -% -% \Finale -\endinput diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua index d3de7313f07..89bf51b4d83 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua @@ -2,10 +2,10 @@ ----------------------------------------------------------------------- -- FILE: luaotfload-auxiliary.lua -- DESCRIPTION: part of luaotfload --- REQUIREMENTS: luaotfload 2.4 +-- REQUIREMENTS: luaotfload 2.5 -- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang --- VERSION: 2.4 --- CREATED: 2013-05-01 14:40:50+0200 +-- VERSION: 2.5 +-- MODIFIED: 2014-01-02 21:24:25+0100 ----------------------------------------------------------------------- -- @@ -15,28 +15,26 @@ luaotfload = luaotfload or {} luaotfload.aux = luaotfload.aux or { } -config = config or { } -config.luaotfload = config.luaotfload or { } - -local aux = luaotfload.aux -local log = luaotfload.log -local warning = luaotfload.log -local fonthashes = fonts.hashes -local identifiers = fonthashes.identifiers - -local fontid = font.id -local texsprint = tex.sprint - -local dofile = dofile -local getmetatable = getmetatable -local setmetatable = setmetatable -local utf8 = unicode.utf8 -local stringlower = string.lower -local stringformat = string.format -local stringgsub = string.gsub -local stringbyte = string.byte -local stringfind = string.find -local tablecopy = table.copy +local aux = luaotfload.aux +local log = luaotfload.log +local report = log.report +local fonthashes = fonts.hashes +local identifiers = fonthashes.identifiers +local fontnames = fonts.names + +local fontid = font.id +local texsprint = tex.sprint + +local dofile = dofile +local getmetatable = getmetatable +local setmetatable = setmetatable +local utf8 = unicode.utf8 +local stringlower = string.lower +local stringformat = string.format +local stringgsub = string.gsub +local stringbyte = string.byte +local stringfind = string.find +local tablecopy = table.copy ----------------------------------------------------------------------- --- font patches @@ -57,8 +55,8 @@ local start_rewrite_fontname = function () rewrite_fontname, "luaotfload.rewrite_fontname") rewriting = true - logs.names_report ("log", 0, "aux", - "start rewriting tfmdata.name field") + report ("log", 1, "aux", + "start rewriting tfmdata.name field") end end @@ -69,97 +67,13 @@ local stop_rewrite_fontname = function () luatexbase.remove_fromt_callback ("luaotfload.patch_font", "luaotfload.rewrite_fontname") rewriting = false - logs.names_report ("log", 0, "aux", - "stop rewriting tfmdata.name field") + report ("log", 1, "aux", + "stop rewriting tfmdata.name field") end end aux.stop_rewrite_fontname = stop_rewrite_fontname ---- as of 2.3 the compatibility hacks for TL 2013 are made optional - -if config.luaotfload.compatibility == true then - ---[[doc-- - -The font object (tfmdata) structure has changed since version 1.x, so -in case other packages haven’t been updated we put fallbacks in place -where they’d expect them. Specifically we have in mind: - - · fontspec - · unicode-math - · microtype (most likely fixed till TL2013) - ---doc]]-- - ---- fontobj -> fontobj -local add_fontdata_fallbacks = function (fontdata) - if type(fontdata) == "table" then - local fontparameters = fontdata.parameters - local metadata - if not fontdata.shared then --- that would be a tfm - --- we can’t really catch everything that - --- goes wrong; for some reason, fontspec.lua - --- just assumes it always gets an otf object, - --- so its capheight callback, which does not - --- bother to do any checks, will access - --- fontdata.shared no matter what ... - fontdata.units = fontdata.units_per_em - - else --- otf - metadata = fontdata.shared.rawdata.metadata - fontdata.name = metadata.origname or fontdata.name - fontdata.units = fontdata.units_per_em - fontdata.size = fontdata.size or fontparameters.size - local resources = fontdata.resources - --- for legacy fontspec.lua and unicode-math.lua - fontdata.shared.otfdata = { - pfminfo = { os2_capheight = metadata.pfminfo.os2_capheight }, - metadata = { ascent = metadata.ascent }, - } - --- for microtype and fontspec - --local fake_features = { } - local fake_features = table.copy(resources.features) - setmetatable(fake_features, { __index = function (tab, idx) - warning("some package (probably fontspec) is outdated") - warning( - "attempt to index " .. - "tfmdata.shared.otfdata.luatex.features (%s)", - idx) - --os.exit(1) - return tab[idx] - end, - }) - fontdata.shared.otfdata.luatex = { - unicodes = resources.unicodes, - features = fake_features, - } - end - end - return fontdata -end - -luatexbase.add_to_callback( - "luaotfload.patch_font", - add_fontdata_fallbacks, - "luaotfload.fontdata_fallbacks") - ---[[doc-- - -Additionally, the font registry is expected at fonts.identifiers -(fontspec) or fonts.ids (microtype), but in the meantime it has been -migrated to fonts.hashes.identifiers. We’ll make luaotfload satisfy -those assumptions. (Maybe it’d be more appropriate to use -font.getfont() since Hans made it a harmless wrapper [1].) - -[1] http://www.ntg.nl/pipermail/ntg-context/2013/072166.html - ---doc]]-- - -fonts.identifiers = fonts.hashes.identifiers -fonts.ids = fonts.hashes.identifiers - -end --[[doc-- This sets two dimensions apparently relied upon by the unicode-math @@ -453,7 +367,7 @@ do local load_chardef = function () - log ("Loading character metadata from %s.", chardef) + report ("both", 1, "aux", "Loading character metadata from %s.", chardef) chardata = dofile (kpse.find_file (chardef, "lua")) if chardata == nil then @@ -511,19 +425,19 @@ local provides_script = function (font_id, asked_script) --- where method: "gpos" | "gsub" for feature, data in next, featuredata do if data[asked_script] then - log(stringformat( - "font no %d (%s) defines feature %s for script %s", - font_id, fontname, feature, asked_script)) + report ("log", 1, "aux", + "font no %d (%s) defines feature %s for script %s", + font_id, fontname, feature, asked_script) return true end end end - log(stringformat( - "font no %d (%s) defines no feature for script %s", - font_id, fontname, asked_script)) + report ("log", 0, "aux", + "font no %d (%s) defines no feature for script %s", + font_id, fontname, asked_script) end end - log(stringformat("no font with id %d", font_id)) + report ("log", 0, "aux", "no font with id %d", font_id) return false end @@ -550,20 +464,22 @@ local provides_language = function (font_id, asked_script, asked_language) for feature, data in next, featuredata do local scriptdata = data[asked_script] if scriptdata and scriptdata[asked_language] then - log(stringformat("font no %d (%s) defines feature %s " - .. "for script %s with language %s", - font_id, fontname, feature, - asked_script, asked_language)) + report ("log", 1, "aux", + "font no %d (%s) defines feature %s " + .. "for script %s with language %s", + font_id, fontname, feature, + asked_script, asked_language) return true end end end - log(stringformat( - "font no %d (%s) defines no feature for script %s with language %s", - font_id, fontname, asked_script, asked_language)) + report ("log", 0, "aux", + "font no %d (%s) defines no feature " + .. "for script %s with language %s", + font_id, fontname, asked_script, asked_language) end end - log(stringformat("no font with id %d", font_id)) + report ("log", 0, "aux", "no font with id %d", font_id) return false end @@ -621,20 +537,21 @@ local provides_feature = function (font_id, asked_script, if feature then local scriptdata = feature[asked_script] if scriptdata and scriptdata[asked_language] then - log(stringformat("font no %d (%s) defines feature %s " - .. "for script %s with language %s", - font_id, fontname, asked_feature, - asked_script, asked_language)) + report ("log", 1, "aux", + "font no %d (%s) defines feature %s " + .. "for script %s with language %s", + font_id, fontname, asked_feature, + asked_script, asked_language) return true end end end - log(stringformat( - "font no %d (%s) does not define feature %s for script %s with language %s", - font_id, fontname, asked_feature, asked_script, asked_language)) + report ("log", 0, "aux", + "font no %d (%s) does not define feature %s for script %s with language %s", + font_id, fontname, asked_feature, asked_script, asked_language) end end - log(stringformat("no font with id %d", font_id)) + report ("log", 0, "aux", "no font with id %d", font_id) return false end @@ -674,8 +591,8 @@ aux.sprint_math_dimension = sprint_math_dimension --- extra database functions ----------------------------------------------------------------------- -local namesresolve = fonts.names.resolve -local namesscan_dir = fonts.names.scan_dir +local namesresolve = fontnames.resolve +local namesscan_dir = fontnames.scan_dir --[====[-- TODO -> port this to new db model @@ -747,6 +664,42 @@ end aux.resolve_fontlist = resolve_fontlist +--- index access ------------------------------------------------------ + +--- Based on a discussion on the Luatex mailing list: +--- http://tug.org/pipermail/luatex/2014-June/004881.html + +--[[doc-- + + aux.read_font_index -- Read the names index from the canonical + location and return its contents. This does not affect the behavior + of Luaotfload: The returned table is independent of what the font + resolvers use internally. Access is raw: each call to the function + will result in the entire table being re-read from disk. + +--doc]]-- + +local load_names = fontnames.load +local access_font_index = fontnames.access_font_index + +local read_font_index = function () + return load_names (true) or { } +end + +--[[doc-- + + aux.font_index -- Access Luaotfload’s internal database. If the + database hasn’t been loaded yet this will cause it to be loaded, with + all the possible side-effects like for instance creating the index + file if it doesn’t exist, reading all font files, &c. + +--doc]]-- + +local font_index = function () return access_font_index () end + +aux.read_font_index = read_font_index +aux.font_index = font_index + --- loaded fonts ------------------------------------------------------ --- just a proof of concept diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-basics-gen.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-basics-gen.lua index 9cf5b93172a..c19a49af39f 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-basics-gen.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-basics-gen.lua @@ -254,6 +254,18 @@ function caches.loaddata(paths,name) for i=1,#paths do local data = false local luaname, lucname = makefullname(paths[i],name) + if lucname and not lfs.isfile(lucname) and type(caches.compile) == "function" then + -- in case we used luatex and luajittex mixed ... lub or luc file + texio.write(string.format("(compiling luc: %s)",lucname)) + data = loadfile(luaname) + if data then + data = data() + end + if data then + caches.compile(data,luaname,lucname) + return data + end + end if lucname and lfs.isfile(lucname) then -- maybe also check for size texio.write(string.format("(load luc: %s)",lucname)) data = loadfile(lucname) @@ -341,3 +353,16 @@ end function table.setmetatableindex(t,f) setmetatable(t,{ __index = f }) end + +-- helper for plain: + +arguments = { } + +if arg then + for i=1,#arg do + local k, v = string.match(arg[i],"^%-%-([^=]+)=?(.-)$") + if k and v then + arguments[k] = v + end + end +end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-basics-nod.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-basics-nod.lua index 50a1e862790..373dab5a8c7 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-basics-nod.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-basics-nod.lua @@ -54,22 +54,33 @@ nodes.handlers = { } local nodecodes = { } for k,v in next, node.types () do nodecodes[string.gsub(v,"_","")] = k end local whatcodes = { } for k,v in next, node.whatsits() do whatcodes[string.gsub(v,"_","")] = k end local glyphcodes = { [0] = "character", "glyph", "ligature", "ghost", "left", "right" } +local disccodes = { [0] = "discretionary", "explicit", "automatic", "regular", "first", "second" } nodes.nodecodes = nodecodes nodes.whatcodes = whatcodes nodes.whatsitcodes = whatcodes nodes.glyphcodes = glyphcodes +nodes.disccodes = disccodes local free_node = node.free local remove_node = node.remove local new_node = node.new local traverse_id = node.traverse_id -local math_code = nodecodes.math - nodes.handlers.protectglyphs = node.protect_glyphs nodes.handlers.unprotectglyphs = node.unprotect_glyphs +local math_code = nodecodes.math +local end_of_math = node.end_of_math + +function node.end_of_math(n) + if n.id == math_code and n.subtype == 1 then + return n + else + return end_of_math(n) + end +end + function nodes.remove(head, current, free_too) local t = current head, current = remove_node(head,current) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-blacklist.cnf b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-blacklist.cnf index 5c03dc298f2..e82669b9f87 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-blacklist.cnf +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-blacklist.cnf @@ -1,12 +1,4 @@ -% Takes ages to load -LastResort.ttf % a MacOSX font, but also available for free from unicode.org -% Segfaults under LuaTeX 0.76 -lingoes.ttf -% http://tug.org/pipermail/luatex/2013-May/004239.html -Diablindall.ttf spltfgbd.ttf spltfgbi.ttf spltfgit.ttf spltfgrg.ttf -% Buggy Max OS font, see https://github.com/lualatex/luaotfload/issues/139 -Skia.ttf diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-characters.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-characters.lua index 13f0482bb2d..771e10fddb3 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-characters.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-characters.lua @@ -3591,6 +3591,10 @@ return { category="po", direction="on", }, + [0x037F]={ + category="lu", + direction="l", + }, [0x0384]={ category="sk", direction="on", @@ -5259,6 +5263,38 @@ return { category="ll", direction="l", }, + [0x0528]={ + category="lu", + direction="l", + }, + [0x0529]={ + category="ll", + direction="l", + }, + [0x052A]={ + category="lu", + direction="l", + }, + [0x052B]={ + category="ll", + direction="l", + }, + [0x052C]={ + category="lu", + direction="l", + }, + [0x052D]={ + category="ll", + direction="l", + }, + [0x052E]={ + category="lu", + direction="l", + }, + [0x052F]={ + category="ll", + direction="l", + }, [0x0531]={ category="lu", direction="l", @@ -5603,6 +5639,14 @@ return { category="pd", direction="on", }, + [0x058D]={ + category="so", + direction="on", + }, + [0x058E]={ + category="so", + direction="on", + }, [0x058F]={ category="sc", direction="et", @@ -5975,6 +6019,10 @@ return { category="cf", direction="an", }, + [0x0605]={ + category="cf", + direction="an", + }, [0x0606]={ category="sm", direction="on", @@ -6063,6 +6111,10 @@ return { category="po", direction="al", }, + [0x061C]={ + category="cf", + direction="al", + }, [0x061E]={ category="po", direction="al", @@ -8267,6 +8319,10 @@ return { category="lo", direction="al", }, + [0x08A1]={ + category="lo", + direction="al", + }, [0x08A2]={ category="lo", direction="al", @@ -8311,6 +8367,30 @@ return { category="lo", direction="al", }, + [0x08AD]={ + category="lo", + direction="al", + }, + [0x08AE]={ + category="lo", + direction="al", + }, + [0x08AF]={ + category="lo", + direction="al", + }, + [0x08B0]={ + category="lo", + direction="al", + }, + [0x08B1]={ + category="lo", + direction="al", + }, + [0x08B2]={ + category="lo", + direction="al", + }, [0x08E4]={ category="mn", direction="nsm", @@ -8419,6 +8499,10 @@ return { category="mn", direction="nsm", }, + [0x08FF]={ + category="mn", + direction="nsm", + }, [0x0900]={ category="mn", direction="nsm", @@ -8899,6 +8983,10 @@ return { category="lo", direction="l", }, + [0x0978]={ + category="lo", + direction="l", + }, [0x0979]={ category="lo", direction="l", @@ -8927,6 +9015,10 @@ return { category="lo", direction="l", }, + [0x0980]={ + category="lo", + direction="l", + }, [0x0981]={ category="mn", direction="nsm", @@ -10595,6 +10687,10 @@ return { category="so", direction="on", }, + [0x0C00]={ + category="mn", + direction="nsm", + }, [0x0C01]={ category="mc", direction="l", @@ -10783,6 +10879,10 @@ return { category="lo", direction="l", }, + [0x0C34]={ + category="lo", + direction="l", + }, [0x0C35]={ category="lo", direction="l", @@ -10967,6 +11067,10 @@ return { category="so", direction="l", }, + [0x0C81]={ + category="mn", + direction="nsm", + }, [0x0C82]={ category="mc", direction="l", @@ -11311,6 +11415,10 @@ return { category="so", direction="l", }, + [0x0D01]={ + category="mn", + direction="nsm", + }, [0x0D02]={ category="mc", direction="l", @@ -12011,6 +12119,46 @@ return { category="mc", direction="l", }, + [0x0DE6]={ + category="nd", + direction="l", + }, + [0x0DE7]={ + category="nd", + direction="l", + }, + [0x0DE8]={ + category="nd", + direction="l", + }, + [0x0DE9]={ + category="nd", + direction="l", + }, + [0x0DEA]={ + category="nd", + direction="l", + }, + [0x0DEB]={ + category="nd", + direction="l", + }, + [0x0DEC]={ + category="nd", + direction="l", + }, + [0x0DED]={ + category="nd", + direction="l", + }, + [0x0DEE]={ + category="nd", + direction="l", + }, + [0x0DEF]={ + category="nd", + direction="l", + }, [0x0DF2]={ category="mc", direction="l", @@ -20381,6 +20529,38 @@ return { category="nl", direction="l", }, + [0x16F1]={ + category="lo", + direction="l", + }, + [0x16F2]={ + category="lo", + direction="l", + }, + [0x16F3]={ + category="lo", + direction="l", + }, + [0x16F4]={ + category="lo", + direction="l", + }, + [0x16F5]={ + category="lo", + direction="l", + }, + [0x16F6]={ + category="lo", + direction="l", + }, + [0x16F7]={ + category="lo", + direction="l", + }, + [0x16F8]={ + category="lo", + direction="l", + }, [0x1700]={ category="lo", direction="l", @@ -21219,7 +21399,7 @@ return { }, [0x180E]={ category="zs", - direction="ws", + direction="bn", }, [0x1810]={ category="nd", @@ -22181,6 +22361,14 @@ return { category="lo", direction="l", }, + [0x191D]={ + category="lo", + direction="l", + }, + [0x191E]={ + category="lo", + direction="l", + }, [0x1920]={ category="mn", direction="nsm", @@ -23039,7 +23227,7 @@ return { }, [0x1A1B]={ category="mc", - direction="l", + direction="nsm", }, [0x1A1E]={ category="po", @@ -23557,6 +23745,66 @@ return { category="po", direction="l", }, + [0x1AB0]={ + category="mn", + direction="nsm", + }, + [0x1AB1]={ + category="mn", + direction="nsm", + }, + [0x1AB2]={ + category="mn", + direction="nsm", + }, + [0x1AB3]={ + category="mn", + direction="nsm", + }, + [0x1AB4]={ + category="mn", + direction="nsm", + }, + [0x1AB5]={ + category="mn", + direction="nsm", + }, + [0x1AB6]={ + category="mn", + direction="nsm", + }, + [0x1AB7]={ + category="mn", + direction="nsm", + }, + [0x1AB8]={ + category="mn", + direction="nsm", + }, + [0x1AB9]={ + category="mn", + direction="nsm", + }, + [0x1ABA]={ + category="mn", + direction="nsm", + }, + [0x1ABB]={ + category="mn", + direction="nsm", + }, + [0x1ABC]={ + category="mn", + direction="nsm", + }, + [0x1ABD]={ + category="mn", + direction="nsm", + }, + [0x1ABE]={ + category="me", + direction="nsm", + }, [0x1B00]={ category="mn", direction="nsm", @@ -24219,11 +24467,11 @@ return { }, [0x1BAC]={ category="mc", - direction="l", + direction="nsm", }, [0x1BAD]={ category="mc", - direction="l", + direction="nsm", }, [0x1BAE]={ category="lo", @@ -25197,6 +25445,14 @@ return { category="lo", direction="l", }, + [0x1CF8]={ + category="mn", + direction="nsm", + }, + [0x1CF9]={ + category="mn", + direction="nsm", + }, [0x1D00]={ category="ll", direction="l", @@ -26121,6 +26377,66 @@ return { category="mn", direction="nsm", }, + [0x1DE7]={ + category="mn", + direction="nsm", + }, + [0x1DE8]={ + category="mn", + direction="nsm", + }, + [0x1DE9]={ + category="mn", + direction="nsm", + }, + [0x1DEA]={ + category="mn", + direction="nsm", + }, + [0x1DEB]={ + category="mn", + direction="nsm", + }, + [0x1DEC]={ + category="mn", + direction="nsm", + }, + [0x1DED]={ + category="mn", + direction="nsm", + }, + [0x1DEE]={ + category="mn", + direction="nsm", + }, + [0x1DEF]={ + category="mn", + direction="nsm", + }, + [0x1DF0]={ + category="mn", + direction="nsm", + }, + [0x1DF1]={ + category="mn", + direction="nsm", + }, + [0x1DF2]={ + category="mn", + direction="nsm", + }, + [0x1DF3]={ + category="mn", + direction="nsm", + }, + [0x1DF4]={ + category="mn", + direction="nsm", + }, + [0x1DF5]={ + category="mn", + direction="nsm", + }, [0x1DFC]={ category="mn", direction="nsm", @@ -28503,6 +28819,22 @@ return { category="cf", direction="bn", }, + [0x2066]={ + category="cf", + direction="lri", + }, + [0x2067]={ + category="cf", + direction="rli", + }, + [0x2068]={ + category="cf", + direction="fsi", + }, + [0x2069]={ + category="cf", + direction="pdi", + }, [0x206A]={ category="cf", direction="bn", @@ -28811,6 +29143,18 @@ return { category="sc", direction="et", }, + [0x20BB]={ + category="sc", + direction="et", + }, + [0x20BC]={ + category="sc", + direction="et", + }, + [0x20BD]={ + category="sc", + direction="et", + }, [0x20D0]={ category="mn", direction="nsm", @@ -32063,6 +32407,34 @@ return { category="so", direction="on", }, + [0x23F4]={ + category="so", + direction="on", + }, + [0x23F5]={ + category="so", + direction="on", + }, + [0x23F6]={ + category="so", + direction="on", + }, + [0x23F7]={ + category="so", + direction="on", + }, + [0x23F8]={ + category="so", + direction="on", + }, + [0x23F9]={ + category="so", + direction="on", + }, + [0x23FA]={ + category="so", + direction="on", + }, [0x2400]={ category="so", direction="on", @@ -34951,6 +35323,10 @@ return { category="so", direction="on", }, + [0x2700]={ + category="so", + direction="on", + }, [0x2701]={ category="so", direction="on", @@ -39513,6 +39889,18 @@ return { category="sm", direction="on", }, + [0x2B4D]={ + category="so", + direction="on", + }, + [0x2B4E]={ + category="so", + direction="on", + }, + [0x2B4F]={ + category="so", + direction="on", + }, [0x2B50]={ category="so", direction="on", @@ -39553,6 +39941,454 @@ return { category="so", direction="on", }, + [0x2B5A]={ + category="so", + direction="on", + }, + [0x2B5B]={ + category="so", + direction="on", + }, + [0x2B5C]={ + category="so", + direction="on", + }, + [0x2B5D]={ + category="so", + direction="on", + }, + [0x2B5E]={ + category="so", + direction="on", + }, + [0x2B5F]={ + category="so", + direction="on", + }, + [0x2B60]={ + category="so", + direction="on", + }, + [0x2B61]={ + category="so", + direction="on", + }, + [0x2B62]={ + category="so", + direction="on", + }, + [0x2B63]={ + category="so", + direction="on", + }, + [0x2B64]={ + category="so", + direction="on", + }, + [0x2B65]={ + category="so", + direction="on", + }, + [0x2B66]={ + category="so", + direction="on", + }, + [0x2B67]={ + category="so", + direction="on", + }, + [0x2B68]={ + category="so", + direction="on", + }, + [0x2B69]={ + category="so", + direction="on", + }, + [0x2B6A]={ + category="so", + direction="on", + }, + [0x2B6B]={ + category="so", + direction="on", + }, + [0x2B6C]={ + category="so", + direction="on", + }, + [0x2B6D]={ + category="so", + direction="on", + }, + [0x2B6E]={ + category="so", + direction="on", + }, + [0x2B6F]={ + category="so", + direction="on", + }, + [0x2B70]={ + category="so", + direction="on", + }, + [0x2B71]={ + category="so", + direction="on", + }, + [0x2B72]={ + category="so", + direction="on", + }, + [0x2B73]={ + category="so", + direction="on", + }, + [0x2B76]={ + category="so", + direction="on", + }, + [0x2B77]={ + category="so", + direction="on", + }, + [0x2B78]={ + category="so", + direction="on", + }, + [0x2B79]={ + category="so", + direction="on", + }, + [0x2B7A]={ + category="so", + direction="on", + }, + [0x2B7B]={ + category="so", + direction="on", + }, + [0x2B7C]={ + category="so", + direction="on", + }, + [0x2B7D]={ + category="so", + direction="on", + }, + [0x2B7E]={ + category="so", + direction="on", + }, + [0x2B7F]={ + category="so", + direction="on", + }, + [0x2B80]={ + category="so", + direction="on", + }, + [0x2B81]={ + category="so", + direction="on", + }, + [0x2B82]={ + category="so", + direction="on", + }, + [0x2B83]={ + category="so", + direction="on", + }, + [0x2B84]={ + category="so", + direction="on", + }, + [0x2B85]={ + category="so", + direction="on", + }, + [0x2B86]={ + category="so", + direction="on", + }, + [0x2B87]={ + category="so", + direction="on", + }, + [0x2B88]={ + category="so", + direction="on", + }, + [0x2B89]={ + category="so", + direction="on", + }, + [0x2B8A]={ + category="so", + direction="on", + }, + [0x2B8B]={ + category="so", + direction="on", + }, + [0x2B8C]={ + category="so", + direction="on", + }, + [0x2B8D]={ + category="so", + direction="on", + }, + [0x2B8E]={ + category="so", + direction="on", + }, + [0x2B8F]={ + category="so", + direction="on", + }, + [0x2B90]={ + category="so", + direction="on", + }, + [0x2B91]={ + category="so", + direction="on", + }, + [0x2B92]={ + category="so", + direction="on", + }, + [0x2B93]={ + category="so", + direction="on", + }, + [0x2B94]={ + category="so", + direction="on", + }, + [0x2B95]={ + category="so", + direction="on", + }, + [0x2B98]={ + category="so", + direction="on", + }, + [0x2B99]={ + category="so", + direction="on", + }, + [0x2B9A]={ + category="so", + direction="on", + }, + [0x2B9B]={ + category="so", + direction="on", + }, + [0x2B9C]={ + category="so", + direction="on", + }, + [0x2B9D]={ + category="so", + direction="on", + }, + [0x2B9E]={ + category="so", + direction="on", + }, + [0x2B9F]={ + category="so", + direction="on", + }, + [0x2BA0]={ + category="so", + direction="on", + }, + [0x2BA1]={ + category="so", + direction="on", + }, + [0x2BA2]={ + category="so", + direction="on", + }, + [0x2BA3]={ + category="so", + direction="on", + }, + [0x2BA4]={ + category="so", + direction="on", + }, + [0x2BA5]={ + category="so", + direction="on", + }, + [0x2BA6]={ + category="so", + direction="on", + }, + [0x2BA7]={ + category="so", + direction="on", + }, + [0x2BA8]={ + category="so", + direction="on", + }, + [0x2BA9]={ + category="so", + direction="on", + }, + [0x2BAA]={ + category="so", + direction="on", + }, + [0x2BAB]={ + category="so", + direction="on", + }, + [0x2BAC]={ + category="so", + direction="on", + }, + [0x2BAD]={ + category="so", + direction="on", + }, + [0x2BAE]={ + category="so", + direction="on", + }, + [0x2BAF]={ + category="so", + direction="on", + }, + [0x2BB0]={ + category="so", + direction="on", + }, + [0x2BB1]={ + category="so", + direction="on", + }, + [0x2BB2]={ + category="so", + direction="on", + }, + [0x2BB3]={ + category="so", + direction="on", + }, + [0x2BB4]={ + category="so", + direction="on", + }, + [0x2BB5]={ + category="so", + direction="on", + }, + [0x2BB6]={ + category="so", + direction="on", + }, + [0x2BB7]={ + category="so", + direction="on", + }, + [0x2BB8]={ + category="so", + direction="on", + }, + [0x2BB9]={ + category="so", + direction="on", + }, + [0x2BBD]={ + category="so", + direction="on", + }, + [0x2BBE]={ + category="so", + direction="on", + }, + [0x2BBF]={ + category="so", + direction="on", + }, + [0x2BC0]={ + category="so", + direction="on", + }, + [0x2BC1]={ + category="so", + direction="on", + }, + [0x2BC2]={ + category="so", + direction="on", + }, + [0x2BC3]={ + category="so", + direction="on", + }, + [0x2BC4]={ + category="so", + direction="on", + }, + [0x2BC5]={ + category="so", + direction="on", + }, + [0x2BC6]={ + category="so", + direction="on", + }, + [0x2BC7]={ + category="so", + direction="on", + }, + [0x2BC8]={ + category="so", + direction="on", + }, + [0x2BCA]={ + category="so", + direction="on", + }, + [0x2BCB]={ + category="so", + direction="on", + }, + [0x2BCC]={ + category="so", + direction="on", + }, + [0x2BCD]={ + category="so", + direction="on", + }, + [0x2BCE]={ + category="so", + direction="on", + }, + [0x2BCF]={ + category="so", + direction="on", + }, + [0x2BD0]={ + category="so", + direction="on", + }, + [0x2BD1]={ + category="so", + direction="on", + }, [0x2C00]={ category="lu", direction="l", @@ -41649,6 +42485,34 @@ return { category="pd", direction="on", }, + [0x2E3C]={ + category="po", + direction="on", + }, + [0x2E3D]={ + category="po", + direction="on", + }, + [0x2E3E]={ + category="po", + direction="on", + }, + [0x2E3F]={ + category="po", + direction="on", + }, + [0x2E40]={ + category="pd", + direction="on", + }, + [0x2E41]={ + category="po", + direction="on", + }, + [0x2E42]={ + category="ps", + direction="on", + }, [0x2E80]={ category="so", direction="on", @@ -53883,6 +54747,30 @@ return { category="ll", direction="l", }, + [0xA698]={ + category="lu", + direction="l", + }, + [0xA699]={ + category="ll", + direction="l", + }, + [0xA69A]={ + category="lu", + direction="l", + }, + [0xA69B]={ + category="ll", + direction="l", + }, + [0xA69C]={ + category="lm", + direction="l", + }, + [0xA69D]={ + category="lm", + direction="l", + }, [0xA69F]={ category="mn", direction="nsm", @@ -54827,6 +55715,54 @@ return { category="ll", direction="l", }, + [0xA794]={ + category="ll", + direction="l", + }, + [0xA795]={ + category="ll", + direction="l", + }, + [0xA796]={ + category="lu", + direction="l", + }, + [0xA797]={ + category="ll", + direction="l", + }, + [0xA798]={ + category="lu", + direction="l", + }, + [0xA799]={ + category="ll", + direction="l", + }, + [0xA79A]={ + category="lu", + direction="l", + }, + [0xA79B]={ + category="ll", + direction="l", + }, + [0xA79C]={ + category="lu", + direction="l", + }, + [0xA79D]={ + category="ll", + direction="l", + }, + [0xA79E]={ + category="lu", + direction="l", + }, + [0xA79F]={ + category="ll", + direction="l", + }, [0xA7A0]={ category="lu", direction="l", @@ -54871,6 +55807,30 @@ return { category="lu", direction="l", }, + [0xA7AB]={ + category="lu", + direction="l", + }, + [0xA7AC]={ + category="lu", + direction="l", + }, + [0xA7AD]={ + category="lu", + direction="l", + }, + [0xA7B0]={ + category="lu", + direction="l", + }, + [0xA7B1]={ + category="lu", + direction="l", + }, + [0xA7F7]={ + category="lo", + direction="l", + }, [0xA7F8]={ category="lm", direction="l", @@ -56599,6 +57559,130 @@ return { category="po", direction="l", }, + [0xA9E0]={ + category="lo", + direction="l", + }, + [0xA9E1]={ + category="lo", + direction="l", + }, + [0xA9E2]={ + category="lo", + direction="l", + }, + [0xA9E3]={ + category="lo", + direction="l", + }, + [0xA9E4]={ + category="lo", + direction="l", + }, + [0xA9E5]={ + category="mn", + direction="nsm", + }, + [0xA9E6]={ + category="lm", + direction="l", + }, + [0xA9E7]={ + category="lo", + direction="l", + }, + [0xA9E8]={ + category="lo", + direction="l", + }, + [0xA9E9]={ + category="lo", + direction="l", + }, + [0xA9EA]={ + category="lo", + direction="l", + }, + [0xA9EB]={ + category="lo", + direction="l", + }, + [0xA9EC]={ + category="lo", + direction="l", + }, + [0xA9ED]={ + category="lo", + direction="l", + }, + [0xA9EE]={ + category="lo", + direction="l", + }, + [0xA9EF]={ + category="lo", + direction="l", + }, + [0xA9F0]={ + category="nd", + direction="l", + }, + [0xA9F1]={ + category="nd", + direction="l", + }, + [0xA9F2]={ + category="nd", + direction="l", + }, + [0xA9F3]={ + category="nd", + direction="l", + }, + [0xA9F4]={ + category="nd", + direction="l", + }, + [0xA9F5]={ + category="nd", + direction="l", + }, + [0xA9F6]={ + category="nd", + direction="l", + }, + [0xA9F7]={ + category="nd", + direction="l", + }, + [0xA9F8]={ + category="nd", + direction="l", + }, + [0xA9F9]={ + category="nd", + direction="l", + }, + [0xA9FA]={ + category="lo", + direction="l", + }, + [0xA9FB]={ + category="lo", + direction="l", + }, + [0xA9FC]={ + category="lo", + direction="l", + }, + [0xA9FD]={ + category="lo", + direction="l", + }, + [0xA9FE]={ + category="lo", + direction="l", + }, [0xAA00]={ category="lo", direction="l", @@ -57043,6 +58127,22 @@ return { category="mc", direction="l", }, + [0xAA7C]={ + category="mn", + direction="nsm", + }, + [0xAA7D]={ + category="mc", + direction="l", + }, + [0xAA7E]={ + category="lo", + direction="l", + }, + [0xAA7F]={ + category="lo", + direction="l", + }, [0xAA80]={ category="lo", direction="l", @@ -57551,6 +58651,206 @@ return { category="lo", direction="l", }, + [0xAB30]={ + category="ll", + direction="l", + }, + [0xAB31]={ + category="ll", + direction="l", + }, + [0xAB32]={ + category="ll", + direction="l", + }, + [0xAB33]={ + category="ll", + direction="l", + }, + [0xAB34]={ + category="ll", + direction="l", + }, + [0xAB35]={ + category="ll", + direction="l", + }, + [0xAB36]={ + category="ll", + direction="l", + }, + [0xAB37]={ + category="ll", + direction="l", + }, + [0xAB38]={ + category="ll", + direction="l", + }, + [0xAB39]={ + category="ll", + direction="l", + }, + [0xAB3A]={ + category="ll", + direction="l", + }, + [0xAB3B]={ + category="ll", + direction="l", + }, + [0xAB3C]={ + category="ll", + direction="l", + }, + [0xAB3D]={ + category="ll", + direction="l", + }, + [0xAB3E]={ + category="ll", + direction="l", + }, + [0xAB3F]={ + category="ll", + direction="l", + }, + [0xAB40]={ + category="ll", + direction="l", + }, + [0xAB41]={ + category="ll", + direction="l", + }, + [0xAB42]={ + category="ll", + direction="l", + }, + [0xAB43]={ + category="ll", + direction="l", + }, + [0xAB44]={ + category="ll", + direction="l", + }, + [0xAB45]={ + category="ll", + direction="l", + }, + [0xAB46]={ + category="ll", + direction="l", + }, + [0xAB47]={ + category="ll", + direction="l", + }, + [0xAB48]={ + category="ll", + direction="l", + }, + [0xAB49]={ + category="ll", + direction="l", + }, + [0xAB4A]={ + category="ll", + direction="l", + }, + [0xAB4B]={ + category="ll", + direction="l", + }, + [0xAB4C]={ + category="ll", + direction="l", + }, + [0xAB4D]={ + category="ll", + direction="l", + }, + [0xAB4E]={ + category="ll", + direction="l", + }, + [0xAB4F]={ + category="ll", + direction="l", + }, + [0xAB50]={ + category="ll", + direction="l", + }, + [0xAB51]={ + category="ll", + direction="l", + }, + [0xAB52]={ + category="ll", + direction="l", + }, + [0xAB53]={ + category="ll", + direction="l", + }, + [0xAB54]={ + category="ll", + direction="l", + }, + [0xAB55]={ + category="ll", + direction="l", + }, + [0xAB56]={ + category="ll", + direction="l", + }, + [0xAB57]={ + category="ll", + direction="l", + }, + [0xAB58]={ + category="ll", + direction="l", + }, + [0xAB59]={ + category="ll", + direction="l", + }, + [0xAB5A]={ + category="ll", + direction="l", + }, + [0xAB5B]={ + category="sk", + direction="l", + }, + [0xAB5C]={ + category="lm", + direction="l", + }, + [0xAB5D]={ + category="lm", + direction="l", + }, + [0xAB5E]={ + category="lm", + direction="l", + }, + [0xAB5F]={ + category="lm", + direction="l", + }, + [0xAB64]={ + category="ll", + direction="l", + }, + [0xAB65]={ + category="ll", + direction="l", + }, [0xABC0]={ category="lo", direction="l", @@ -62791,6 +64091,34 @@ return { category="mn", direction="nsm", }, + [0xFE27]={ + category="mn", + direction="nsm", + }, + [0xFE28]={ + category="mn", + direction="nsm", + }, + [0xFE29]={ + category="mn", + direction="nsm", + }, + [0xFE2A]={ + category="mn", + direction="nsm", + }, + [0xFE2B]={ + category="mn", + direction="nsm", + }, + [0xFE2C]={ + category="mn", + direction="nsm", + }, + [0xFE2D]={ + category="mn", + direction="nsm", + }, [0xFE30]={ category="po", direction="on", @@ -65919,6 +67247,14 @@ return { category="no", direction="on", }, + [0x1018B]={ + category="no", + direction="on", + }, + [0x1018C]={ + category="so", + direction="on", + }, [0x10190]={ category="so", direction="on", @@ -65967,6 +67303,10 @@ return { category="so", direction="on", }, + [0x101A0]={ + category="so", + direction="on", + }, [0x101D0]={ category="so", direction="l", @@ -66463,6 +67803,118 @@ return { category="lo", direction="l", }, + [0x102E0]={ + category="mn", + direction="nsm", + }, + [0x102E1]={ + category="no", + direction="en", + }, + [0x102E2]={ + category="no", + direction="en", + }, + [0x102E3]={ + category="no", + direction="en", + }, + [0x102E4]={ + category="no", + direction="en", + }, + [0x102E5]={ + category="no", + direction="en", + }, + [0x102E6]={ + category="no", + direction="en", + }, + [0x102E7]={ + category="no", + direction="en", + }, + [0x102E8]={ + category="no", + direction="en", + }, + [0x102E9]={ + category="no", + direction="en", + }, + [0x102EA]={ + category="no", + direction="en", + }, + [0x102EB]={ + category="no", + direction="en", + }, + [0x102EC]={ + category="no", + direction="en", + }, + [0x102ED]={ + category="no", + direction="en", + }, + [0x102EE]={ + category="no", + direction="en", + }, + [0x102EF]={ + category="no", + direction="en", + }, + [0x102F0]={ + category="no", + direction="en", + }, + [0x102F1]={ + category="no", + direction="en", + }, + [0x102F2]={ + category="no", + direction="en", + }, + [0x102F3]={ + category="no", + direction="en", + }, + [0x102F4]={ + category="no", + direction="en", + }, + [0x102F5]={ + category="no", + direction="en", + }, + [0x102F6]={ + category="no", + direction="en", + }, + [0x102F7]={ + category="no", + direction="en", + }, + [0x102F8]={ + category="no", + direction="en", + }, + [0x102F9]={ + category="no", + direction="en", + }, + [0x102FA]={ + category="no", + direction="en", + }, + [0x102FB]={ + category="no", + direction="en", + }, [0x10300]={ category="lo", direction="l", @@ -66587,6 +68039,10 @@ return { category="lo", direction="l", }, + [0x1031F]={ + category="lo", + direction="l", + }, [0x10320]={ category="no", direction="l", @@ -66711,6 +68167,178 @@ return { category="nl", direction="l", }, + [0x10350]={ + category="lo", + direction="l", + }, + [0x10351]={ + category="lo", + direction="l", + }, + [0x10352]={ + category="lo", + direction="l", + }, + [0x10353]={ + category="lo", + direction="l", + }, + [0x10354]={ + category="lo", + direction="l", + }, + [0x10355]={ + category="lo", + direction="l", + }, + [0x10356]={ + category="lo", + direction="l", + }, + [0x10357]={ + category="lo", + direction="l", + }, + [0x10358]={ + category="lo", + direction="l", + }, + [0x10359]={ + category="lo", + direction="l", + }, + [0x1035A]={ + category="lo", + direction="l", + }, + [0x1035B]={ + category="lo", + direction="l", + }, + [0x1035C]={ + category="lo", + direction="l", + }, + [0x1035D]={ + category="lo", + direction="l", + }, + [0x1035E]={ + category="lo", + direction="l", + }, + [0x1035F]={ + category="lo", + direction="l", + }, + [0x10360]={ + category="lo", + direction="l", + }, + [0x10361]={ + category="lo", + direction="l", + }, + [0x10362]={ + category="lo", + direction="l", + }, + [0x10363]={ + category="lo", + direction="l", + }, + [0x10364]={ + category="lo", + direction="l", + }, + [0x10365]={ + category="lo", + direction="l", + }, + [0x10366]={ + category="lo", + direction="l", + }, + [0x10367]={ + category="lo", + direction="l", + }, + [0x10368]={ + category="lo", + direction="l", + }, + [0x10369]={ + category="lo", + direction="l", + }, + [0x1036A]={ + category="lo", + direction="l", + }, + [0x1036B]={ + category="lo", + direction="l", + }, + [0x1036C]={ + category="lo", + direction="l", + }, + [0x1036D]={ + category="lo", + direction="l", + }, + [0x1036E]={ + category="lo", + direction="l", + }, + [0x1036F]={ + category="lo", + direction="l", + }, + [0x10370]={ + category="lo", + direction="l", + }, + [0x10371]={ + category="lo", + direction="l", + }, + [0x10372]={ + category="lo", + direction="l", + }, + [0x10373]={ + category="lo", + direction="l", + }, + [0x10374]={ + category="lo", + direction="l", + }, + [0x10375]={ + category="lo", + direction="l", + }, + [0x10376]={ + category="mn", + direction="nsm", + }, + [0x10377]={ + category="mn", + direction="nsm", + }, + [0x10378]={ + category="mn", + direction="nsm", + }, + [0x10379]={ + category="mn", + direction="nsm", + }, + [0x1037A]={ + category="mn", + direction="nsm", + }, [0x10380]={ category="lo", direction="l", @@ -67707,26831 +69335,36559 @@ return { category="nd", direction="l", }, - [0x10800]={ + [0x10500]={ category="lo", - direction="r", + direction="l", }, - [0x10801]={ + [0x10501]={ category="lo", - direction="r", + direction="l", }, - [0x10802]={ + [0x10502]={ category="lo", - direction="r", + direction="l", }, - [0x10803]={ + [0x10503]={ category="lo", - direction="r", + direction="l", }, - [0x10804]={ + [0x10504]={ category="lo", - direction="r", + direction="l", }, - [0x10805]={ + [0x10505]={ category="lo", - direction="r", + direction="l", }, - [0x10808]={ + [0x10506]={ category="lo", - direction="r", + direction="l", }, - [0x1080A]={ + [0x10507]={ category="lo", - direction="r", + direction="l", }, - [0x1080B]={ + [0x10508]={ category="lo", - direction="r", + direction="l", }, - [0x1080C]={ + [0x10509]={ category="lo", - direction="r", + direction="l", }, - [0x1080D]={ + [0x1050A]={ category="lo", - direction="r", + direction="l", }, - [0x1080E]={ + [0x1050B]={ category="lo", - direction="r", + direction="l", }, - [0x1080F]={ + [0x1050C]={ category="lo", - direction="r", + direction="l", }, - [0x10810]={ + [0x1050D]={ category="lo", - direction="r", + direction="l", }, - [0x10811]={ + [0x1050E]={ category="lo", - direction="r", + direction="l", }, - [0x10812]={ + [0x1050F]={ category="lo", - direction="r", + direction="l", }, - [0x10813]={ + [0x10510]={ category="lo", - direction="r", + direction="l", }, - [0x10814]={ + [0x10511]={ category="lo", - direction="r", + direction="l", }, - [0x10815]={ + [0x10512]={ category="lo", - direction="r", + direction="l", }, - [0x10816]={ + [0x10513]={ category="lo", - direction="r", + direction="l", }, - [0x10817]={ + [0x10514]={ category="lo", - direction="r", + direction="l", }, - [0x10818]={ + [0x10515]={ category="lo", - direction="r", + direction="l", }, - [0x10819]={ + [0x10516]={ category="lo", - direction="r", + direction="l", }, - [0x1081A]={ + [0x10517]={ category="lo", - direction="r", + direction="l", }, - [0x1081B]={ + [0x10518]={ category="lo", - direction="r", + direction="l", }, - [0x1081C]={ + [0x10519]={ category="lo", - direction="r", + direction="l", }, - [0x1081D]={ + [0x1051A]={ category="lo", - direction="r", + direction="l", }, - [0x1081E]={ + [0x1051B]={ category="lo", - direction="r", + direction="l", }, - [0x1081F]={ + [0x1051C]={ category="lo", - direction="r", + direction="l", }, - [0x10820]={ + [0x1051D]={ category="lo", - direction="r", + direction="l", }, - [0x10821]={ + [0x1051E]={ category="lo", - direction="r", + direction="l", }, - [0x10822]={ + [0x1051F]={ category="lo", - direction="r", + direction="l", }, - [0x10823]={ + [0x10520]={ category="lo", - direction="r", + direction="l", }, - [0x10824]={ + [0x10521]={ category="lo", - direction="r", + direction="l", }, - [0x10825]={ + [0x10522]={ category="lo", - direction="r", + direction="l", }, - [0x10826]={ + [0x10523]={ category="lo", - direction="r", + direction="l", }, - [0x10827]={ + [0x10524]={ category="lo", - direction="r", + direction="l", }, - [0x10828]={ + [0x10525]={ category="lo", - direction="r", + direction="l", }, - [0x10829]={ + [0x10526]={ category="lo", - direction="r", + direction="l", }, - [0x1082A]={ + [0x10527]={ category="lo", - direction="r", + direction="l", }, - [0x1082B]={ + [0x10530]={ category="lo", - direction="r", + direction="l", }, - [0x1082C]={ + [0x10531]={ category="lo", - direction="r", + direction="l", }, - [0x1082D]={ + [0x10532]={ category="lo", - direction="r", + direction="l", }, - [0x1082E]={ + [0x10533]={ category="lo", - direction="r", + direction="l", }, - [0x1082F]={ + [0x10534]={ category="lo", - direction="r", + direction="l", }, - [0x10830]={ + [0x10535]={ category="lo", - direction="r", + direction="l", }, - [0x10831]={ + [0x10536]={ category="lo", - direction="r", + direction="l", }, - [0x10832]={ + [0x10537]={ category="lo", - direction="r", + direction="l", }, - [0x10833]={ + [0x10538]={ category="lo", - direction="r", + direction="l", }, - [0x10834]={ + [0x10539]={ category="lo", - direction="r", + direction="l", }, - [0x10835]={ + [0x1053A]={ category="lo", - direction="r", + direction="l", }, - [0x10837]={ + [0x1053B]={ category="lo", - direction="r", + direction="l", }, - [0x10838]={ + [0x1053C]={ category="lo", - direction="r", + direction="l", }, - [0x1083C]={ + [0x1053D]={ category="lo", - direction="r", + direction="l", }, - [0x1083F]={ + [0x1053E]={ category="lo", - direction="r", + direction="l", }, - [0x10840]={ + [0x1053F]={ category="lo", - direction="r", + direction="l", }, - [0x10841]={ + [0x10540]={ category="lo", - direction="r", + direction="l", }, - [0x10842]={ + [0x10541]={ category="lo", - direction="r", + direction="l", }, - [0x10843]={ + [0x10542]={ category="lo", - direction="r", + direction="l", }, - [0x10844]={ + [0x10543]={ category="lo", - direction="r", + direction="l", }, - [0x10845]={ + [0x10544]={ category="lo", - direction="r", + direction="l", }, - [0x10846]={ + [0x10545]={ category="lo", - direction="r", + direction="l", }, - [0x10847]={ + [0x10546]={ category="lo", - direction="r", + direction="l", }, - [0x10848]={ + [0x10547]={ category="lo", - direction="r", + direction="l", }, - [0x10849]={ + [0x10548]={ category="lo", - direction="r", + direction="l", }, - [0x1084A]={ + [0x10549]={ category="lo", - direction="r", + direction="l", }, - [0x1084B]={ + [0x1054A]={ category="lo", - direction="r", + direction="l", }, - [0x1084C]={ + [0x1054B]={ category="lo", - direction="r", + direction="l", }, - [0x1084D]={ + [0x1054C]={ category="lo", - direction="r", + direction="l", }, - [0x1084E]={ + [0x1054D]={ category="lo", - direction="r", + direction="l", }, - [0x1084F]={ + [0x1054E]={ category="lo", - direction="r", + direction="l", }, - [0x10850]={ + [0x1054F]={ category="lo", - direction="r", + direction="l", }, - [0x10851]={ + [0x10550]={ category="lo", - direction="r", + direction="l", }, - [0x10852]={ + [0x10551]={ category="lo", - direction="r", + direction="l", }, - [0x10853]={ + [0x10552]={ category="lo", - direction="r", + direction="l", }, - [0x10854]={ + [0x10553]={ category="lo", - direction="r", + direction="l", }, - [0x10855]={ + [0x10554]={ category="lo", - direction="r", + direction="l", }, - [0x10857]={ - category="po", - direction="r", + [0x10555]={ + category="lo", + direction="l", }, - [0x10858]={ - category="no", - direction="r", + [0x10556]={ + category="lo", + direction="l", }, - [0x10859]={ - category="no", - direction="r", + [0x10557]={ + category="lo", + direction="l", }, - [0x1085A]={ - category="no", - direction="r", + [0x10558]={ + category="lo", + direction="l", }, - [0x1085B]={ - category="no", - direction="r", + [0x10559]={ + category="lo", + direction="l", }, - [0x1085C]={ - category="no", - direction="r", + [0x1055A]={ + category="lo", + direction="l", }, - [0x1085D]={ - category="no", - direction="r", + [0x1055B]={ + category="lo", + direction="l", }, - [0x1085E]={ - category="no", - direction="r", - }, - [0x1085F]={ - category="no", - direction="r", + [0x1055C]={ + category="lo", + direction="l", }, - [0x10900]={ + [0x1055D]={ category="lo", - direction="r", + direction="l", }, - [0x10901]={ + [0x1055E]={ category="lo", - direction="r", + direction="l", }, - [0x10902]={ + [0x1055F]={ category="lo", - direction="r", + direction="l", }, - [0x10903]={ + [0x10560]={ category="lo", - direction="r", + direction="l", }, - [0x10904]={ + [0x10561]={ category="lo", - direction="r", + direction="l", }, - [0x10905]={ + [0x10562]={ category="lo", - direction="r", + direction="l", }, - [0x10906]={ + [0x10563]={ category="lo", - direction="r", + direction="l", }, - [0x10907]={ + [0x1056F]={ + category="po", + direction="l", + }, + [0x10600]={ category="lo", - direction="r", + direction="l", }, - [0x10908]={ + [0x10601]={ category="lo", - direction="r", + direction="l", }, - [0x10909]={ + [0x10602]={ category="lo", - direction="r", + direction="l", }, - [0x1090A]={ + [0x10603]={ category="lo", - direction="r", + direction="l", }, - [0x1090B]={ + [0x10604]={ category="lo", - direction="r", + direction="l", }, - [0x1090C]={ + [0x10605]={ category="lo", - direction="r", + direction="l", }, - [0x1090D]={ + [0x10606]={ category="lo", - direction="r", + direction="l", }, - [0x1090E]={ + [0x10607]={ category="lo", - direction="r", + direction="l", }, - [0x1090F]={ + [0x10608]={ category="lo", - direction="r", + direction="l", }, - [0x10910]={ + [0x10609]={ category="lo", - direction="r", + direction="l", }, - [0x10911]={ + [0x1060A]={ category="lo", - direction="r", + direction="l", }, - [0x10912]={ + [0x1060B]={ category="lo", - direction="r", + direction="l", }, - [0x10913]={ + [0x1060C]={ category="lo", - direction="r", + direction="l", }, - [0x10914]={ + [0x1060D]={ category="lo", - direction="r", + direction="l", }, - [0x10915]={ + [0x1060E]={ category="lo", - direction="r", + direction="l", }, - [0x10916]={ - category="no", - direction="r", + [0x1060F]={ + category="lo", + direction="l", }, - [0x10917]={ - category="no", - direction="r", + [0x10610]={ + category="lo", + direction="l", }, - [0x10918]={ - category="no", - direction="r", + [0x10611]={ + category="lo", + direction="l", }, - [0x10919]={ - category="no", - direction="r", + [0x10612]={ + category="lo", + direction="l", }, - [0x1091A]={ - category="no", - direction="r", + [0x10613]={ + category="lo", + direction="l", }, - [0x1091B]={ - category="no", - direction="r", + [0x10614]={ + category="lo", + direction="l", }, - [0x1091F]={ - category="po", - direction="on", + [0x10615]={ + category="lo", + direction="l", }, - [0x10920]={ + [0x10616]={ category="lo", - direction="r", + direction="l", }, - [0x10921]={ + [0x10617]={ category="lo", - direction="r", + direction="l", }, - [0x10922]={ + [0x10618]={ category="lo", - direction="r", + direction="l", }, - [0x10923]={ + [0x10619]={ category="lo", - direction="r", + direction="l", }, - [0x10924]={ + [0x1061A]={ category="lo", - direction="r", + direction="l", }, - [0x10925]={ + [0x1061B]={ category="lo", - direction="r", + direction="l", }, - [0x10926]={ + [0x1061C]={ category="lo", - direction="r", + direction="l", }, - [0x10927]={ + [0x1061D]={ category="lo", - direction="r", + direction="l", }, - [0x10928]={ + [0x1061E]={ category="lo", - direction="r", + direction="l", }, - [0x10929]={ + [0x1061F]={ category="lo", - direction="r", + direction="l", }, - [0x1092A]={ + [0x10620]={ category="lo", - direction="r", + direction="l", }, - [0x1092B]={ + [0x10621]={ category="lo", - direction="r", + direction="l", }, - [0x1092C]={ + [0x10622]={ category="lo", - direction="r", + direction="l", }, - [0x1092D]={ + [0x10623]={ category="lo", - direction="r", + direction="l", }, - [0x1092E]={ + [0x10624]={ category="lo", - direction="r", + direction="l", }, - [0x1092F]={ + [0x10625]={ category="lo", - direction="r", + direction="l", }, - [0x10930]={ + [0x10626]={ category="lo", - direction="r", + direction="l", }, - [0x10931]={ + [0x10627]={ category="lo", - direction="r", + direction="l", }, - [0x10932]={ + [0x10628]={ category="lo", - direction="r", + direction="l", }, - [0x10933]={ + [0x10629]={ category="lo", - direction="r", + direction="l", }, - [0x10934]={ + [0x1062A]={ category="lo", - direction="r", + direction="l", }, - [0x10935]={ + [0x1062B]={ category="lo", - direction="r", + direction="l", }, - [0x10936]={ + [0x1062C]={ category="lo", - direction="r", + direction="l", }, - [0x10937]={ + [0x1062D]={ category="lo", - direction="r", + direction="l", }, - [0x10938]={ + [0x1062E]={ category="lo", - direction="r", + direction="l", }, - [0x10939]={ + [0x1062F]={ category="lo", - direction="r", + direction="l", }, - [0x1093F]={ - category="po", - direction="r", + [0x10630]={ + category="lo", + direction="l", }, - [0x10980]={ + [0x10631]={ category="lo", - direction="r", + direction="l", }, - [0x10981]={ + [0x10632]={ category="lo", - direction="r", + direction="l", }, - [0x10982]={ + [0x10633]={ category="lo", - direction="r", + direction="l", }, - [0x10983]={ + [0x10634]={ category="lo", - direction="r", + direction="l", }, - [0x10984]={ + [0x10635]={ category="lo", - direction="r", + direction="l", }, - [0x10985]={ + [0x10636]={ category="lo", - direction="r", + direction="l", }, - [0x10986]={ + [0x10637]={ category="lo", - direction="r", + direction="l", }, - [0x10987]={ + [0x10638]={ category="lo", - direction="r", + direction="l", }, - [0x10988]={ + [0x10639]={ category="lo", - direction="r", + direction="l", }, - [0x10989]={ + [0x1063A]={ category="lo", - direction="r", + direction="l", }, - [0x1098A]={ + [0x1063B]={ category="lo", - direction="r", + direction="l", }, - [0x1098B]={ + [0x1063C]={ category="lo", - direction="r", + direction="l", }, - [0x1098C]={ + [0x1063D]={ category="lo", - direction="r", + direction="l", }, - [0x1098D]={ + [0x1063E]={ category="lo", - direction="r", + direction="l", }, - [0x1098E]={ + [0x1063F]={ category="lo", - direction="r", + direction="l", }, - [0x1098F]={ + [0x10640]={ category="lo", - direction="r", + direction="l", }, - [0x10990]={ + [0x10641]={ category="lo", - direction="r", + direction="l", }, - [0x10991]={ + [0x10642]={ category="lo", - direction="r", + direction="l", }, - [0x10992]={ + [0x10643]={ category="lo", - direction="r", + direction="l", }, - [0x10993]={ + [0x10644]={ category="lo", - direction="r", + direction="l", }, - [0x10994]={ + [0x10645]={ category="lo", - direction="r", + direction="l", }, - [0x10995]={ + [0x10646]={ category="lo", - direction="r", + direction="l", }, - [0x10996]={ + [0x10647]={ category="lo", - direction="r", + direction="l", }, - [0x10997]={ + [0x10648]={ category="lo", - direction="r", + direction="l", }, - [0x10998]={ + [0x10649]={ category="lo", - direction="r", + direction="l", }, - [0x10999]={ + [0x1064A]={ category="lo", - direction="r", + direction="l", }, - [0x1099A]={ + [0x1064B]={ category="lo", - direction="r", + direction="l", }, - [0x1099B]={ + [0x1064C]={ category="lo", - direction="r", + direction="l", }, - [0x1099C]={ + [0x1064D]={ category="lo", - direction="r", + direction="l", }, - [0x1099D]={ + [0x1064E]={ category="lo", - direction="r", + direction="l", }, - [0x1099E]={ + [0x1064F]={ category="lo", - direction="r", + direction="l", }, - [0x1099F]={ + [0x10650]={ category="lo", - direction="r", + direction="l", }, - [0x109A0]={ + [0x10651]={ category="lo", - direction="r", + direction="l", }, - [0x109A1]={ + [0x10652]={ category="lo", - direction="r", + direction="l", }, - [0x109A2]={ + [0x10653]={ category="lo", - direction="r", + direction="l", }, - [0x109A3]={ + [0x10654]={ category="lo", - direction="r", + direction="l", }, - [0x109A4]={ + [0x10655]={ category="lo", - direction="r", + direction="l", }, - [0x109A5]={ + [0x10656]={ category="lo", - direction="r", + direction="l", }, - [0x109A6]={ + [0x10657]={ category="lo", - direction="r", + direction="l", }, - [0x109A7]={ + [0x10658]={ category="lo", - direction="r", + direction="l", }, - [0x109A8]={ + [0x10659]={ category="lo", - direction="r", + direction="l", }, - [0x109A9]={ + [0x1065A]={ category="lo", - direction="r", + direction="l", }, - [0x109AA]={ + [0x1065B]={ category="lo", - direction="r", + direction="l", }, - [0x109AB]={ + [0x1065C]={ category="lo", - direction="r", + direction="l", }, - [0x109AC]={ + [0x1065D]={ category="lo", - direction="r", + direction="l", }, - [0x109AD]={ + [0x1065E]={ category="lo", - direction="r", + direction="l", }, - [0x109AE]={ + [0x1065F]={ category="lo", - direction="r", + direction="l", }, - [0x109AF]={ + [0x10660]={ category="lo", - direction="r", + direction="l", }, - [0x109B0]={ + [0x10661]={ category="lo", - direction="r", + direction="l", }, - [0x109B1]={ + [0x10662]={ category="lo", - direction="r", + direction="l", }, - [0x109B2]={ + [0x10663]={ category="lo", - direction="r", + direction="l", }, - [0x109B3]={ + [0x10664]={ category="lo", - direction="r", + direction="l", }, - [0x109B4]={ + [0x10665]={ category="lo", - direction="r", + direction="l", }, - [0x109B5]={ + [0x10666]={ category="lo", - direction="r", + direction="l", }, - [0x109B6]={ + [0x10667]={ category="lo", - direction="r", + direction="l", }, - [0x109B7]={ + [0x10668]={ category="lo", - direction="r", + direction="l", }, - [0x109BE]={ + [0x10669]={ category="lo", - direction="r", + direction="l", }, - [0x109BF]={ + [0x1066A]={ category="lo", - direction="r", + direction="l", }, - [0x10A00]={ + [0x1066B]={ category="lo", - direction="r", + direction="l", }, - [0x10A01]={ - category="mn", - direction="nsm", + [0x1066C]={ + category="lo", + direction="l", }, - [0x10A02]={ - category="mn", - direction="nsm", + [0x1066D]={ + category="lo", + direction="l", }, - [0x10A03]={ - category="mn", - direction="nsm", + [0x1066E]={ + category="lo", + direction="l", }, - [0x10A05]={ - category="mn", - direction="nsm", + [0x1066F]={ + category="lo", + direction="l", }, - [0x10A06]={ - category="mn", - direction="nsm", + [0x10670]={ + category="lo", + direction="l", }, - [0x10A0C]={ - category="mn", - direction="nsm", + [0x10671]={ + category="lo", + direction="l", }, - [0x10A0D]={ - category="mn", - direction="nsm", + [0x10672]={ + category="lo", + direction="l", }, - [0x10A0E]={ - category="mn", - direction="nsm", + [0x10673]={ + category="lo", + direction="l", }, - [0x10A0F]={ - category="mn", - direction="nsm", + [0x10674]={ + category="lo", + direction="l", }, - [0x10A10]={ + [0x10675]={ category="lo", - direction="r", + direction="l", }, - [0x10A11]={ + [0x10676]={ category="lo", - direction="r", + direction="l", }, - [0x10A12]={ + [0x10677]={ category="lo", - direction="r", + direction="l", }, - [0x10A13]={ + [0x10678]={ category="lo", - direction="r", + direction="l", }, - [0x10A15]={ + [0x10679]={ category="lo", - direction="r", + direction="l", }, - [0x10A16]={ + [0x1067A]={ category="lo", - direction="r", + direction="l", }, - [0x10A17]={ + [0x1067B]={ category="lo", - direction="r", + direction="l", }, - [0x10A19]={ + [0x1067C]={ category="lo", - direction="r", + direction="l", }, - [0x10A1A]={ + [0x1067D]={ category="lo", - direction="r", + direction="l", }, - [0x10A1B]={ + [0x1067E]={ category="lo", - direction="r", + direction="l", }, - [0x10A1C]={ + [0x1067F]={ category="lo", - direction="r", + direction="l", }, - [0x10A1D]={ + [0x10680]={ category="lo", - direction="r", + direction="l", }, - [0x10A1E]={ + [0x10681]={ category="lo", - direction="r", + direction="l", }, - [0x10A1F]={ + [0x10682]={ category="lo", - direction="r", + direction="l", }, - [0x10A20]={ + [0x10683]={ category="lo", - direction="r", + direction="l", }, - [0x10A21]={ + [0x10684]={ category="lo", - direction="r", + direction="l", }, - [0x10A22]={ + [0x10685]={ category="lo", - direction="r", + direction="l", }, - [0x10A23]={ + [0x10686]={ category="lo", - direction="r", + direction="l", }, - [0x10A24]={ + [0x10687]={ category="lo", - direction="r", + direction="l", }, - [0x10A25]={ + [0x10688]={ category="lo", - direction="r", + direction="l", }, - [0x10A26]={ + [0x10689]={ category="lo", - direction="r", + direction="l", }, - [0x10A27]={ + [0x1068A]={ category="lo", - direction="r", + direction="l", }, - [0x10A28]={ + [0x1068B]={ category="lo", - direction="r", + direction="l", }, - [0x10A29]={ + [0x1068C]={ category="lo", - direction="r", + direction="l", }, - [0x10A2A]={ + [0x1068D]={ category="lo", - direction="r", + direction="l", }, - [0x10A2B]={ + [0x1068E]={ category="lo", - direction="r", + direction="l", }, - [0x10A2C]={ + [0x1068F]={ category="lo", - direction="r", + direction="l", }, - [0x10A2D]={ + [0x10690]={ category="lo", - direction="r", + direction="l", }, - [0x10A2E]={ + [0x10691]={ category="lo", - direction="r", + direction="l", }, - [0x10A2F]={ + [0x10692]={ category="lo", - direction="r", + direction="l", }, - [0x10A30]={ + [0x10693]={ category="lo", - direction="r", + direction="l", }, - [0x10A31]={ + [0x10694]={ category="lo", - direction="r", + direction="l", }, - [0x10A32]={ + [0x10695]={ category="lo", - direction="r", + direction="l", }, - [0x10A33]={ + [0x10696]={ category="lo", - direction="r", - }, - [0x10A38]={ - category="mn", - direction="nsm", + direction="l", }, - [0x10A39]={ - category="mn", - direction="nsm", + [0x10697]={ + category="lo", + direction="l", }, - [0x10A3A]={ - category="mn", - direction="nsm", + [0x10698]={ + category="lo", + direction="l", }, - [0x10A3F]={ - category="mn", - direction="nsm", + [0x10699]={ + category="lo", + direction="l", }, - [0x10A40]={ - category="no", - direction="r", + [0x1069A]={ + category="lo", + direction="l", }, - [0x10A41]={ - category="no", - direction="r", + [0x1069B]={ + category="lo", + direction="l", }, - [0x10A42]={ - category="no", - direction="r", + [0x1069C]={ + category="lo", + direction="l", }, - [0x10A43]={ - category="no", - direction="r", + [0x1069D]={ + category="lo", + direction="l", }, - [0x10A44]={ - category="no", - direction="r", + [0x1069E]={ + category="lo", + direction="l", }, - [0x10A45]={ - category="no", - direction="r", + [0x1069F]={ + category="lo", + direction="l", }, - [0x10A46]={ - category="no", - direction="r", + [0x106A0]={ + category="lo", + direction="l", }, - [0x10A47]={ - category="no", - direction="r", + [0x106A1]={ + category="lo", + direction="l", }, - [0x10A50]={ - category="po", - direction="r", + [0x106A2]={ + category="lo", + direction="l", }, - [0x10A51]={ - category="po", - direction="r", + [0x106A3]={ + category="lo", + direction="l", }, - [0x10A52]={ - category="po", - direction="r", + [0x106A4]={ + category="lo", + direction="l", }, - [0x10A53]={ - category="po", - direction="r", + [0x106A5]={ + category="lo", + direction="l", }, - [0x10A54]={ - category="po", - direction="r", + [0x106A6]={ + category="lo", + direction="l", }, - [0x10A55]={ - category="po", - direction="r", + [0x106A7]={ + category="lo", + direction="l", }, - [0x10A56]={ - category="po", - direction="r", + [0x106A8]={ + category="lo", + direction="l", }, - [0x10A57]={ - category="po", - direction="r", + [0x106A9]={ + category="lo", + direction="l", }, - [0x10A58]={ - category="po", - direction="r", + [0x106AA]={ + category="lo", + direction="l", }, - [0x10A60]={ + [0x106AB]={ category="lo", - direction="r", + direction="l", }, - [0x10A61]={ + [0x106AC]={ category="lo", - direction="r", + direction="l", }, - [0x10A62]={ + [0x106AD]={ category="lo", - direction="r", + direction="l", }, - [0x10A63]={ + [0x106AE]={ category="lo", - direction="r", + direction="l", }, - [0x10A64]={ + [0x106AF]={ category="lo", - direction="r", + direction="l", }, - [0x10A65]={ + [0x106B0]={ category="lo", - direction="r", + direction="l", }, - [0x10A66]={ + [0x106B1]={ category="lo", - direction="r", + direction="l", }, - [0x10A67]={ + [0x106B2]={ category="lo", - direction="r", + direction="l", }, - [0x10A68]={ + [0x106B3]={ category="lo", - direction="r", + direction="l", }, - [0x10A69]={ + [0x106B4]={ category="lo", - direction="r", + direction="l", }, - [0x10A6A]={ + [0x106B5]={ category="lo", - direction="r", + direction="l", }, - [0x10A6B]={ + [0x106B6]={ category="lo", - direction="r", + direction="l", }, - [0x10A6C]={ + [0x106B7]={ category="lo", - direction="r", + direction="l", }, - [0x10A6D]={ + [0x106B8]={ category="lo", - direction="r", + direction="l", }, - [0x10A6E]={ + [0x106B9]={ category="lo", - direction="r", + direction="l", }, - [0x10A6F]={ + [0x106BA]={ category="lo", - direction="r", + direction="l", }, - [0x10A70]={ + [0x106BB]={ category="lo", - direction="r", + direction="l", }, - [0x10A71]={ + [0x106BC]={ category="lo", - direction="r", + direction="l", }, - [0x10A72]={ + [0x106BD]={ category="lo", - direction="r", + direction="l", }, - [0x10A73]={ + [0x106BE]={ category="lo", - direction="r", + direction="l", }, - [0x10A74]={ + [0x106BF]={ category="lo", - direction="r", + direction="l", }, - [0x10A75]={ + [0x106C0]={ category="lo", - direction="r", + direction="l", }, - [0x10A76]={ + [0x106C1]={ category="lo", - direction="r", + direction="l", }, - [0x10A77]={ + [0x106C2]={ category="lo", - direction="r", + direction="l", }, - [0x10A78]={ + [0x106C3]={ category="lo", - direction="r", + direction="l", }, - [0x10A79]={ + [0x106C4]={ category="lo", - direction="r", + direction="l", }, - [0x10A7A]={ + [0x106C5]={ category="lo", - direction="r", + direction="l", }, - [0x10A7B]={ + [0x106C6]={ category="lo", - direction="r", + direction="l", }, - [0x10A7C]={ + [0x106C7]={ category="lo", - direction="r", + direction="l", }, - [0x10A7D]={ - category="no", - direction="r", + [0x106C8]={ + category="lo", + direction="l", }, - [0x10A7E]={ - category="no", - direction="r", + [0x106C9]={ + category="lo", + direction="l", }, - [0x10A7F]={ - category="po", - direction="r", + [0x106CA]={ + category="lo", + direction="l", }, - [0x10B00]={ + [0x106CB]={ category="lo", - direction="r", + direction="l", }, - [0x10B01]={ + [0x106CC]={ category="lo", - direction="r", + direction="l", }, - [0x10B02]={ + [0x106CD]={ category="lo", - direction="r", + direction="l", }, - [0x10B03]={ + [0x106CE]={ category="lo", - direction="r", + direction="l", }, - [0x10B04]={ + [0x106CF]={ category="lo", - direction="r", + direction="l", }, - [0x10B05]={ + [0x106D0]={ category="lo", - direction="r", + direction="l", }, - [0x10B06]={ + [0x106D1]={ category="lo", - direction="r", + direction="l", }, - [0x10B07]={ + [0x106D2]={ category="lo", - direction="r", + direction="l", }, - [0x10B08]={ + [0x106D3]={ category="lo", - direction="r", + direction="l", }, - [0x10B09]={ + [0x106D4]={ category="lo", - direction="r", + direction="l", }, - [0x10B0A]={ + [0x106D5]={ category="lo", - direction="r", + direction="l", }, - [0x10B0B]={ + [0x106D6]={ category="lo", - direction="r", + direction="l", }, - [0x10B0C]={ + [0x106D7]={ category="lo", - direction="r", + direction="l", }, - [0x10B0D]={ + [0x106D8]={ category="lo", - direction="r", + direction="l", }, - [0x10B0E]={ + [0x106D9]={ category="lo", - direction="r", + direction="l", }, - [0x10B0F]={ + [0x106DA]={ category="lo", - direction="r", + direction="l", }, - [0x10B10]={ + [0x106DB]={ category="lo", - direction="r", + direction="l", }, - [0x10B11]={ + [0x106DC]={ category="lo", - direction="r", + direction="l", }, - [0x10B12]={ + [0x106DD]={ category="lo", - direction="r", + direction="l", }, - [0x10B13]={ + [0x106DE]={ category="lo", - direction="r", + direction="l", }, - [0x10B14]={ + [0x106DF]={ category="lo", - direction="r", + direction="l", }, - [0x10B15]={ + [0x106E0]={ category="lo", - direction="r", + direction="l", }, - [0x10B16]={ + [0x106E1]={ category="lo", - direction="r", + direction="l", }, - [0x10B17]={ + [0x106E2]={ category="lo", - direction="r", + direction="l", }, - [0x10B18]={ + [0x106E3]={ category="lo", - direction="r", + direction="l", }, - [0x10B19]={ + [0x106E4]={ category="lo", - direction="r", + direction="l", }, - [0x10B1A]={ + [0x106E5]={ category="lo", - direction="r", + direction="l", }, - [0x10B1B]={ + [0x106E6]={ category="lo", - direction="r", + direction="l", }, - [0x10B1C]={ + [0x106E7]={ category="lo", - direction="r", + direction="l", }, - [0x10B1D]={ + [0x106E8]={ category="lo", - direction="r", + direction="l", }, - [0x10B1E]={ + [0x106E9]={ category="lo", - direction="r", + direction="l", }, - [0x10B1F]={ + [0x106EA]={ category="lo", - direction="r", + direction="l", }, - [0x10B20]={ + [0x106EB]={ category="lo", - direction="r", + direction="l", }, - [0x10B21]={ + [0x106EC]={ category="lo", - direction="r", + direction="l", }, - [0x10B22]={ + [0x106ED]={ category="lo", - direction="r", + direction="l", }, - [0x10B23]={ + [0x106EE]={ category="lo", - direction="r", + direction="l", }, - [0x10B24]={ + [0x106EF]={ category="lo", - direction="r", + direction="l", }, - [0x10B25]={ + [0x106F0]={ category="lo", - direction="r", + direction="l", }, - [0x10B26]={ + [0x106F1]={ category="lo", - direction="r", + direction="l", }, - [0x10B27]={ + [0x106F2]={ category="lo", - direction="r", + direction="l", }, - [0x10B28]={ + [0x106F3]={ category="lo", - direction="r", + direction="l", }, - [0x10B29]={ + [0x106F4]={ category="lo", - direction="r", + direction="l", }, - [0x10B2A]={ + [0x106F5]={ category="lo", - direction="r", + direction="l", }, - [0x10B2B]={ + [0x106F6]={ category="lo", - direction="r", + direction="l", }, - [0x10B2C]={ + [0x106F7]={ category="lo", - direction="r", + direction="l", }, - [0x10B2D]={ + [0x106F8]={ category="lo", - direction="r", + direction="l", }, - [0x10B2E]={ + [0x106F9]={ category="lo", - direction="r", + direction="l", }, - [0x10B2F]={ + [0x106FA]={ category="lo", - direction="r", + direction="l", }, - [0x10B30]={ + [0x106FB]={ category="lo", - direction="r", + direction="l", }, - [0x10B31]={ + [0x106FC]={ category="lo", - direction="r", + direction="l", }, - [0x10B32]={ + [0x106FD]={ category="lo", - direction="r", + direction="l", }, - [0x10B33]={ + [0x106FE]={ category="lo", - direction="r", + direction="l", }, - [0x10B34]={ + [0x106FF]={ category="lo", - direction="r", + direction="l", }, - [0x10B35]={ + [0x10700]={ category="lo", - direction="r", + direction="l", }, - [0x10B39]={ - category="po", - direction="on", + [0x10701]={ + category="lo", + direction="l", }, - [0x10B3A]={ - category="po", - direction="on", + [0x10702]={ + category="lo", + direction="l", }, - [0x10B3B]={ - category="po", - direction="on", + [0x10703]={ + category="lo", + direction="l", }, - [0x10B3C]={ - category="po", - direction="on", + [0x10704]={ + category="lo", + direction="l", }, - [0x10B3D]={ - category="po", - direction="on", + [0x10705]={ + category="lo", + direction="l", }, - [0x10B3E]={ - category="po", - direction="on", + [0x10706]={ + category="lo", + direction="l", }, - [0x10B3F]={ - category="po", - direction="on", + [0x10707]={ + category="lo", + direction="l", }, - [0x10B40]={ + [0x10708]={ category="lo", - direction="r", + direction="l", }, - [0x10B41]={ + [0x10709]={ category="lo", - direction="r", + direction="l", }, - [0x10B42]={ + [0x1070A]={ category="lo", - direction="r", + direction="l", }, - [0x10B43]={ + [0x1070B]={ category="lo", - direction="r", + direction="l", }, - [0x10B44]={ + [0x1070C]={ category="lo", - direction="r", + direction="l", }, - [0x10B45]={ + [0x1070D]={ category="lo", - direction="r", + direction="l", }, - [0x10B46]={ + [0x1070E]={ category="lo", - direction="r", + direction="l", }, - [0x10B47]={ + [0x1070F]={ category="lo", - direction="r", + direction="l", }, - [0x10B48]={ + [0x10710]={ category="lo", - direction="r", + direction="l", }, - [0x10B49]={ + [0x10711]={ category="lo", - direction="r", + direction="l", }, - [0x10B4A]={ + [0x10712]={ category="lo", - direction="r", + direction="l", }, - [0x10B4B]={ + [0x10713]={ category="lo", - direction="r", + direction="l", }, - [0x10B4C]={ + [0x10714]={ category="lo", - direction="r", + direction="l", }, - [0x10B4D]={ + [0x10715]={ category="lo", - direction="r", + direction="l", }, - [0x10B4E]={ + [0x10716]={ category="lo", - direction="r", + direction="l", }, - [0x10B4F]={ + [0x10717]={ category="lo", - direction="r", + direction="l", }, - [0x10B50]={ + [0x10718]={ category="lo", - direction="r", + direction="l", }, - [0x10B51]={ + [0x10719]={ category="lo", - direction="r", + direction="l", }, - [0x10B52]={ + [0x1071A]={ category="lo", - direction="r", + direction="l", }, - [0x10B53]={ + [0x1071B]={ category="lo", - direction="r", + direction="l", }, - [0x10B54]={ + [0x1071C]={ category="lo", - direction="r", + direction="l", }, - [0x10B55]={ + [0x1071D]={ category="lo", - direction="r", + direction="l", }, - [0x10B58]={ - category="no", - direction="r", + [0x1071E]={ + category="lo", + direction="l", }, - [0x10B59]={ - category="no", - direction="r", + [0x1071F]={ + category="lo", + direction="l", }, - [0x10B5A]={ - category="no", - direction="r", + [0x10720]={ + category="lo", + direction="l", }, - [0x10B5B]={ - category="no", - direction="r", + [0x10721]={ + category="lo", + direction="l", }, - [0x10B5C]={ - category="no", - direction="r", + [0x10722]={ + category="lo", + direction="l", }, - [0x10B5D]={ - category="no", - direction="r", + [0x10723]={ + category="lo", + direction="l", }, - [0x10B5E]={ - category="no", - direction="r", + [0x10724]={ + category="lo", + direction="l", }, - [0x10B5F]={ - category="no", - direction="r", + [0x10725]={ + category="lo", + direction="l", }, - [0x10B60]={ + [0x10726]={ category="lo", - direction="r", + direction="l", }, - [0x10B61]={ + [0x10727]={ category="lo", - direction="r", + direction="l", }, - [0x10B62]={ + [0x10728]={ category="lo", - direction="r", + direction="l", }, - [0x10B63]={ + [0x10729]={ category="lo", - direction="r", + direction="l", }, - [0x10B64]={ + [0x1072A]={ category="lo", - direction="r", + direction="l", }, - [0x10B65]={ + [0x1072B]={ category="lo", - direction="r", + direction="l", }, - [0x10B66]={ + [0x1072C]={ category="lo", - direction="r", + direction="l", }, - [0x10B67]={ + [0x1072D]={ category="lo", - direction="r", + direction="l", }, - [0x10B68]={ + [0x1072E]={ category="lo", - direction="r", + direction="l", }, - [0x10B69]={ + [0x1072F]={ category="lo", - direction="r", + direction="l", }, - [0x10B6A]={ + [0x10730]={ category="lo", - direction="r", + direction="l", }, - [0x10B6B]={ + [0x10731]={ category="lo", - direction="r", + direction="l", }, - [0x10B6C]={ + [0x10732]={ category="lo", - direction="r", + direction="l", }, - [0x10B6D]={ + [0x10733]={ category="lo", - direction="r", + direction="l", }, - [0x10B6E]={ + [0x10734]={ category="lo", - direction="r", + direction="l", }, - [0x10B6F]={ + [0x10735]={ category="lo", - direction="r", + direction="l", }, - [0x10B70]={ + [0x10736]={ category="lo", - direction="r", + direction="l", }, - [0x10B71]={ + [0x10740]={ category="lo", - direction="r", + direction="l", }, - [0x10B72]={ + [0x10741]={ category="lo", - direction="r", + direction="l", }, - [0x10B78]={ - category="no", - direction="r", + [0x10742]={ + category="lo", + direction="l", }, - [0x10B79]={ - category="no", - direction="r", + [0x10743]={ + category="lo", + direction="l", }, - [0x10B7A]={ - category="no", - direction="r", + [0x10744]={ + category="lo", + direction="l", }, - [0x10B7B]={ - category="no", - direction="r", + [0x10745]={ + category="lo", + direction="l", }, - [0x10B7C]={ - category="no", + [0x10746]={ + category="lo", + direction="l", + }, + [0x10747]={ + category="lo", + direction="l", + }, + [0x10748]={ + category="lo", + direction="l", + }, + [0x10749]={ + category="lo", + direction="l", + }, + [0x1074A]={ + category="lo", + direction="l", + }, + [0x1074B]={ + category="lo", + direction="l", + }, + [0x1074C]={ + category="lo", + direction="l", + }, + [0x1074D]={ + category="lo", + direction="l", + }, + [0x1074E]={ + category="lo", + direction="l", + }, + [0x1074F]={ + category="lo", + direction="l", + }, + [0x10750]={ + category="lo", + direction="l", + }, + [0x10751]={ + category="lo", + direction="l", + }, + [0x10752]={ + category="lo", + direction="l", + }, + [0x10753]={ + category="lo", + direction="l", + }, + [0x10754]={ + category="lo", + direction="l", + }, + [0x10755]={ + category="lo", + direction="l", + }, + [0x10760]={ + category="lo", + direction="l", + }, + [0x10761]={ + category="lo", + direction="l", + }, + [0x10762]={ + category="lo", + direction="l", + }, + [0x10763]={ + category="lo", + direction="l", + }, + [0x10764]={ + category="lo", + direction="l", + }, + [0x10765]={ + category="lo", + direction="l", + }, + [0x10766]={ + category="lo", + direction="l", + }, + [0x10767]={ + category="lo", + direction="l", + }, + [0x10800]={ + category="lo", direction="r", }, - [0x10B7D]={ - category="no", + [0x10801]={ + category="lo", direction="r", }, - [0x10B7E]={ - category="no", + [0x10802]={ + category="lo", direction="r", }, - [0x10B7F]={ - category="no", + [0x10803]={ + category="lo", direction="r", }, - [0x10C00]={ + [0x10804]={ category="lo", direction="r", }, - [0x10C01]={ + [0x10805]={ category="lo", direction="r", }, - [0x10C02]={ + [0x10808]={ category="lo", direction="r", }, - [0x10C03]={ + [0x1080A]={ category="lo", direction="r", }, - [0x10C04]={ + [0x1080B]={ category="lo", direction="r", }, - [0x10C05]={ + [0x1080C]={ category="lo", direction="r", }, - [0x10C06]={ + [0x1080D]={ category="lo", direction="r", }, - [0x10C07]={ + [0x1080E]={ category="lo", direction="r", }, - [0x10C08]={ + [0x1080F]={ category="lo", direction="r", }, - [0x10C09]={ + [0x10810]={ category="lo", direction="r", }, - [0x10C0A]={ + [0x10811]={ category="lo", direction="r", }, - [0x10C0B]={ + [0x10812]={ category="lo", direction="r", }, - [0x10C0C]={ + [0x10813]={ category="lo", direction="r", }, - [0x10C0D]={ + [0x10814]={ category="lo", direction="r", }, - [0x10C0E]={ + [0x10815]={ category="lo", direction="r", }, - [0x10C0F]={ + [0x10816]={ category="lo", direction="r", }, - [0x10C10]={ + [0x10817]={ category="lo", direction="r", }, - [0x10C11]={ + [0x10818]={ category="lo", direction="r", }, - [0x10C12]={ + [0x10819]={ category="lo", direction="r", }, - [0x10C13]={ + [0x1081A]={ category="lo", direction="r", }, - [0x10C14]={ + [0x1081B]={ category="lo", direction="r", }, - [0x10C15]={ + [0x1081C]={ category="lo", direction="r", }, - [0x10C16]={ + [0x1081D]={ category="lo", direction="r", }, - [0x10C17]={ + [0x1081E]={ category="lo", direction="r", }, - [0x10C18]={ + [0x1081F]={ category="lo", direction="r", }, - [0x10C19]={ + [0x10820]={ category="lo", direction="r", }, - [0x10C1A]={ + [0x10821]={ category="lo", direction="r", }, - [0x10C1B]={ + [0x10822]={ category="lo", direction="r", }, - [0x10C1C]={ + [0x10823]={ category="lo", direction="r", }, - [0x10C1D]={ + [0x10824]={ category="lo", direction="r", }, - [0x10C1E]={ + [0x10825]={ category="lo", direction="r", }, - [0x10C1F]={ + [0x10826]={ category="lo", direction="r", }, - [0x10C20]={ + [0x10827]={ category="lo", direction="r", }, - [0x10C21]={ + [0x10828]={ category="lo", direction="r", }, - [0x10C22]={ + [0x10829]={ category="lo", direction="r", }, - [0x10C23]={ + [0x1082A]={ category="lo", direction="r", }, - [0x10C24]={ + [0x1082B]={ category="lo", direction="r", }, - [0x10C25]={ + [0x1082C]={ category="lo", direction="r", }, - [0x10C26]={ + [0x1082D]={ category="lo", direction="r", }, - [0x10C27]={ + [0x1082E]={ category="lo", direction="r", }, - [0x10C28]={ + [0x1082F]={ category="lo", direction="r", }, - [0x10C29]={ + [0x10830]={ category="lo", direction="r", }, - [0x10C2A]={ + [0x10831]={ category="lo", direction="r", }, - [0x10C2B]={ + [0x10832]={ category="lo", direction="r", }, - [0x10C2C]={ + [0x10833]={ category="lo", direction="r", }, - [0x10C2D]={ + [0x10834]={ category="lo", direction="r", }, - [0x10C2E]={ + [0x10835]={ category="lo", direction="r", }, - [0x10C2F]={ + [0x10837]={ category="lo", direction="r", }, - [0x10C30]={ + [0x10838]={ category="lo", direction="r", }, - [0x10C31]={ + [0x1083C]={ category="lo", direction="r", }, - [0x10C32]={ + [0x1083F]={ category="lo", direction="r", }, - [0x10C33]={ + [0x10840]={ category="lo", direction="r", }, - [0x10C34]={ + [0x10841]={ category="lo", direction="r", }, - [0x10C35]={ + [0x10842]={ category="lo", direction="r", }, - [0x10C36]={ + [0x10843]={ category="lo", direction="r", }, - [0x10C37]={ + [0x10844]={ category="lo", direction="r", }, - [0x10C38]={ + [0x10845]={ category="lo", direction="r", }, - [0x10C39]={ + [0x10846]={ category="lo", direction="r", }, - [0x10C3A]={ + [0x10847]={ category="lo", direction="r", }, - [0x10C3B]={ + [0x10848]={ category="lo", direction="r", }, - [0x10C3C]={ + [0x10849]={ category="lo", direction="r", }, - [0x10C3D]={ + [0x1084A]={ category="lo", direction="r", }, - [0x10C3E]={ + [0x1084B]={ category="lo", direction="r", }, - [0x10C3F]={ + [0x1084C]={ category="lo", direction="r", }, - [0x10C40]={ + [0x1084D]={ category="lo", direction="r", }, - [0x10C41]={ + [0x1084E]={ category="lo", direction="r", }, - [0x10C42]={ + [0x1084F]={ category="lo", direction="r", }, - [0x10C43]={ + [0x10850]={ category="lo", direction="r", }, - [0x10C44]={ + [0x10851]={ category="lo", direction="r", }, - [0x10C45]={ + [0x10852]={ category="lo", direction="r", }, - [0x10C46]={ + [0x10853]={ category="lo", direction="r", }, - [0x10C47]={ + [0x10854]={ category="lo", direction="r", }, - [0x10C48]={ + [0x10855]={ category="lo", direction="r", }, - [0x10E60]={ - category="no", - direction="an", + [0x10857]={ + category="po", + direction="r", }, - [0x10E61]={ + [0x10858]={ category="no", - direction="an", + direction="r", }, - [0x10E62]={ + [0x10859]={ category="no", - direction="an", + direction="r", }, - [0x10E63]={ + [0x1085A]={ category="no", - direction="an", + direction="r", }, - [0x10E64]={ + [0x1085B]={ category="no", - direction="an", + direction="r", }, - [0x10E65]={ + [0x1085C]={ category="no", - direction="an", + direction="r", }, - [0x10E66]={ + [0x1085D]={ category="no", - direction="an", + direction="r", }, - [0x10E67]={ + [0x1085E]={ category="no", - direction="an", + direction="r", }, - [0x10E68]={ + [0x1085F]={ category="no", - direction="an", + direction="r", }, - [0x10E69]={ - category="no", - direction="an", + [0x10860]={ + category="lo", + direction="r", }, - [0x10E6A]={ - category="no", - direction="an", + [0x10861]={ + category="lo", + direction="r", }, - [0x10E6B]={ - category="no", - direction="an", + [0x10862]={ + category="lo", + direction="r", }, - [0x10E6C]={ - category="no", - direction="an", + [0x10863]={ + category="lo", + direction="r", }, - [0x10E6D]={ - category="no", - direction="an", + [0x10864]={ + category="lo", + direction="r", }, - [0x10E6E]={ - category="no", - direction="an", + [0x10865]={ + category="lo", + direction="r", }, - [0x10E6F]={ - category="no", - direction="an", + [0x10866]={ + category="lo", + direction="r", }, - [0x10E70]={ - category="no", - direction="an", + [0x10867]={ + category="lo", + direction="r", }, - [0x10E71]={ - category="no", - direction="an", + [0x10868]={ + category="lo", + direction="r", }, - [0x10E72]={ - category="no", - direction="an", + [0x10869]={ + category="lo", + direction="r", }, - [0x10E73]={ - category="no", - direction="an", + [0x1086A]={ + category="lo", + direction="r", }, - [0x10E74]={ - category="no", - direction="an", + [0x1086B]={ + category="lo", + direction="r", }, - [0x10E75]={ - category="no", - direction="an", + [0x1086C]={ + category="lo", + direction="r", }, - [0x10E76]={ - category="no", - direction="an", + [0x1086D]={ + category="lo", + direction="r", }, - [0x10E77]={ - category="no", - direction="an", + [0x1086E]={ + category="lo", + direction="r", }, - [0x10E78]={ - category="no", - direction="an", + [0x1086F]={ + category="lo", + direction="r", }, - [0x10E79]={ - category="no", - direction="an", + [0x10870]={ + category="lo", + direction="r", }, - [0x10E7A]={ + [0x10871]={ + category="lo", + direction="r", + }, + [0x10872]={ + category="lo", + direction="r", + }, + [0x10873]={ + category="lo", + direction="r", + }, + [0x10874]={ + category="lo", + direction="r", + }, + [0x10875]={ + category="lo", + direction="r", + }, + [0x10876]={ + category="lo", + direction="r", + }, + [0x10877]={ + category="so", + direction="r", + }, + [0x10878]={ + category="so", + direction="r", + }, + [0x10879]={ category="no", - direction="an", + direction="r", }, - [0x10E7B]={ + [0x1087A]={ category="no", - direction="an", + direction="r", }, - [0x10E7C]={ + [0x1087B]={ category="no", - direction="an", + direction="r", }, - [0x10E7D]={ + [0x1087C]={ category="no", - direction="an", + direction="r", }, - [0x10E7E]={ + [0x1087D]={ category="no", - direction="an", + direction="r", }, - [0x11000]={ - category="mc", - direction="l", + [0x1087E]={ + category="no", + direction="r", }, - [0x11001]={ - category="mn", - direction="nsm", + [0x1087F]={ + category="no", + direction="r", }, - [0x11002]={ - category="mc", - direction="l", + [0x10880]={ + category="lo", + direction="r", }, - [0x11003]={ + [0x10881]={ category="lo", - direction="l", + direction="r", }, - [0x11004]={ + [0x10882]={ category="lo", - direction="l", + direction="r", }, - [0x11005]={ + [0x10883]={ category="lo", - direction="l", + direction="r", }, - [0x11006]={ + [0x10884]={ category="lo", - direction="l", + direction="r", }, - [0x11007]={ + [0x10885]={ category="lo", - direction="l", + direction="r", }, - [0x11008]={ + [0x10886]={ category="lo", - direction="l", + direction="r", }, - [0x11009]={ + [0x10887]={ category="lo", - direction="l", + direction="r", }, - [0x1100A]={ + [0x10888]={ category="lo", - direction="l", + direction="r", }, - [0x1100B]={ + [0x10889]={ category="lo", - direction="l", + direction="r", }, - [0x1100C]={ + [0x1088A]={ category="lo", - direction="l", + direction="r", }, - [0x1100D]={ + [0x1088B]={ category="lo", - direction="l", + direction="r", }, - [0x1100E]={ + [0x1088C]={ category="lo", - direction="l", + direction="r", }, - [0x1100F]={ + [0x1088D]={ category="lo", - direction="l", + direction="r", }, - [0x11010]={ + [0x1088E]={ category="lo", - direction="l", + direction="r", }, - [0x11011]={ + [0x1088F]={ category="lo", - direction="l", + direction="r", }, - [0x11012]={ + [0x10890]={ category="lo", - direction="l", + direction="r", }, - [0x11013]={ + [0x10891]={ category="lo", - direction="l", + direction="r", }, - [0x11014]={ + [0x10892]={ category="lo", - direction="l", + direction="r", }, - [0x11015]={ + [0x10893]={ category="lo", - direction="l", + direction="r", }, - [0x11016]={ + [0x10894]={ category="lo", - direction="l", + direction="r", }, - [0x11017]={ + [0x10895]={ category="lo", - direction="l", + direction="r", }, - [0x11018]={ + [0x10896]={ category="lo", - direction="l", + direction="r", }, - [0x11019]={ + [0x10897]={ category="lo", - direction="l", + direction="r", }, - [0x1101A]={ + [0x10898]={ category="lo", - direction="l", + direction="r", }, - [0x1101B]={ + [0x10899]={ category="lo", - direction="l", + direction="r", }, - [0x1101C]={ + [0x1089A]={ category="lo", - direction="l", + direction="r", }, - [0x1101D]={ + [0x1089B]={ category="lo", - direction="l", + direction="r", }, - [0x1101E]={ + [0x1089C]={ category="lo", - direction="l", + direction="r", }, - [0x1101F]={ + [0x1089D]={ category="lo", - direction="l", + direction="r", }, - [0x11020]={ + [0x1089E]={ category="lo", - direction="l", + direction="r", }, - [0x11021]={ - category="lo", - direction="l", + [0x108A7]={ + category="no", + direction="r", }, - [0x11022]={ - category="lo", - direction="l", + [0x108A8]={ + category="no", + direction="r", }, - [0x11023]={ - category="lo", - direction="l", + [0x108A9]={ + category="no", + direction="r", }, - [0x11024]={ - category="lo", - direction="l", + [0x108AA]={ + category="no", + direction="r", }, - [0x11025]={ - category="lo", - direction="l", + [0x108AB]={ + category="no", + direction="r", }, - [0x11026]={ - category="lo", - direction="l", + [0x108AC]={ + category="no", + direction="r", }, - [0x11027]={ - category="lo", - direction="l", + [0x108AD]={ + category="no", + direction="r", }, - [0x11028]={ - category="lo", - direction="l", + [0x108AE]={ + category="no", + direction="r", }, - [0x11029]={ - category="lo", - direction="l", + [0x108AF]={ + category="no", + direction="r", }, - [0x1102A]={ + [0x10900]={ category="lo", - direction="l", + direction="r", }, - [0x1102B]={ + [0x10901]={ category="lo", - direction="l", + direction="r", }, - [0x1102C]={ + [0x10902]={ category="lo", - direction="l", + direction="r", }, - [0x1102D]={ + [0x10903]={ category="lo", - direction="l", + direction="r", }, - [0x1102E]={ + [0x10904]={ category="lo", - direction="l", + direction="r", }, - [0x1102F]={ + [0x10905]={ category="lo", - direction="l", + direction="r", }, - [0x11030]={ + [0x10906]={ category="lo", - direction="l", + direction="r", }, - [0x11031]={ + [0x10907]={ category="lo", - direction="l", + direction="r", }, - [0x11032]={ + [0x10908]={ category="lo", - direction="l", + direction="r", }, - [0x11033]={ + [0x10909]={ category="lo", - direction="l", + direction="r", }, - [0x11034]={ + [0x1090A]={ category="lo", - direction="l", + direction="r", }, - [0x11035]={ + [0x1090B]={ category="lo", - direction="l", + direction="r", }, - [0x11036]={ + [0x1090C]={ category="lo", - direction="l", + direction="r", }, - [0x11037]={ + [0x1090D]={ category="lo", - direction="l", - }, - [0x11038]={ - category="mn", - direction="nsm", - }, - [0x11039]={ - category="mn", - direction="nsm", - }, - [0x1103A]={ - category="mn", - direction="nsm", - }, - [0x1103B]={ - category="mn", - direction="nsm", - }, - [0x1103C]={ - category="mn", - direction="nsm", - }, - [0x1103D]={ - category="mn", - direction="nsm", - }, - [0x1103E]={ - category="mn", - direction="nsm", - }, - [0x1103F]={ - category="mn", - direction="nsm", - }, - [0x11040]={ - category="mn", - direction="nsm", - }, - [0x11041]={ - category="mn", - direction="nsm", - }, - [0x11042]={ - category="mn", - direction="nsm", - }, - [0x11043]={ - category="mn", - direction="nsm", - }, - [0x11044]={ - category="mn", - direction="nsm", - }, - [0x11045]={ - category="mn", - direction="nsm", - }, - [0x11046]={ - category="mn", - direction="nsm", - }, - [0x11047]={ - category="po", - direction="l", - }, - [0x11048]={ - category="po", - direction="l", - }, - [0x11049]={ - category="po", - direction="l", - }, - [0x1104A]={ - category="po", - direction="l", - }, - [0x1104B]={ - category="po", - direction="l", - }, - [0x1104C]={ - category="po", - direction="l", - }, - [0x1104D]={ - category="po", - direction="l", - }, - [0x11052]={ - category="no", - direction="on", - }, - [0x11053]={ - category="no", - direction="on", - }, - [0x11054]={ - category="no", - direction="on", - }, - [0x11055]={ - category="no", - direction="on", - }, - [0x11056]={ - category="no", - direction="on", + direction="r", }, - [0x11057]={ - category="no", - direction="on", + [0x1090E]={ + category="lo", + direction="r", }, - [0x11058]={ - category="no", - direction="on", + [0x1090F]={ + category="lo", + direction="r", }, - [0x11059]={ - category="no", - direction="on", + [0x10910]={ + category="lo", + direction="r", }, - [0x1105A]={ - category="no", - direction="on", + [0x10911]={ + category="lo", + direction="r", }, - [0x1105B]={ - category="no", - direction="on", + [0x10912]={ + category="lo", + direction="r", }, - [0x1105C]={ - category="no", - direction="on", + [0x10913]={ + category="lo", + direction="r", }, - [0x1105D]={ - category="no", - direction="on", + [0x10914]={ + category="lo", + direction="r", }, - [0x1105E]={ - category="no", - direction="on", + [0x10915]={ + category="lo", + direction="r", }, - [0x1105F]={ + [0x10916]={ category="no", - direction="on", + direction="r", }, - [0x11060]={ + [0x10917]={ category="no", - direction="on", + direction="r", }, - [0x11061]={ + [0x10918]={ category="no", - direction="on", + direction="r", }, - [0x11062]={ + [0x10919]={ category="no", - direction="on", + direction="r", }, - [0x11063]={ + [0x1091A]={ category="no", - direction="on", + direction="r", }, - [0x11064]={ + [0x1091B]={ category="no", - direction="on", + direction="r", }, - [0x11065]={ - category="no", + [0x1091F]={ + category="po", direction="on", }, - [0x11066]={ - category="nd", - direction="l", - }, - [0x11067]={ - category="nd", - direction="l", - }, - [0x11068]={ - category="nd", - direction="l", - }, - [0x11069]={ - category="nd", - direction="l", - }, - [0x1106A]={ - category="nd", - direction="l", - }, - [0x1106B]={ - category="nd", - direction="l", - }, - [0x1106C]={ - category="nd", - direction="l", - }, - [0x1106D]={ - category="nd", - direction="l", - }, - [0x1106E]={ - category="nd", - direction="l", - }, - [0x1106F]={ - category="nd", - direction="l", - }, - [0x11080]={ - category="mn", - direction="nsm", - }, - [0x11081]={ - category="mn", - direction="nsm", - }, - [0x11082]={ - category="mc", - direction="l", - }, - [0x11083]={ + [0x10920]={ category="lo", - direction="l", + direction="r", }, - [0x11084]={ + [0x10921]={ category="lo", - direction="l", + direction="r", }, - [0x11085]={ + [0x10922]={ category="lo", - direction="l", + direction="r", }, - [0x11086]={ + [0x10923]={ category="lo", - direction="l", + direction="r", }, - [0x11087]={ + [0x10924]={ category="lo", - direction="l", + direction="r", }, - [0x11088]={ + [0x10925]={ category="lo", - direction="l", + direction="r", }, - [0x11089]={ + [0x10926]={ category="lo", - direction="l", + direction="r", }, - [0x1108A]={ + [0x10927]={ category="lo", - direction="l", + direction="r", }, - [0x1108B]={ + [0x10928]={ category="lo", - direction="l", + direction="r", }, - [0x1108C]={ + [0x10929]={ category="lo", - direction="l", + direction="r", }, - [0x1108D]={ + [0x1092A]={ category="lo", - direction="l", + direction="r", }, - [0x1108E]={ + [0x1092B]={ category="lo", - direction="l", + direction="r", }, - [0x1108F]={ + [0x1092C]={ category="lo", - direction="l", + direction="r", }, - [0x11090]={ + [0x1092D]={ category="lo", - direction="l", + direction="r", }, - [0x11091]={ + [0x1092E]={ category="lo", - direction="l", + direction="r", }, - [0x11092]={ + [0x1092F]={ category="lo", - direction="l", + direction="r", }, - [0x11093]={ + [0x10930]={ category="lo", - direction="l", + direction="r", }, - [0x11094]={ + [0x10931]={ category="lo", - direction="l", + direction="r", }, - [0x11095]={ + [0x10932]={ category="lo", - direction="l", + direction="r", }, - [0x11096]={ + [0x10933]={ category="lo", - direction="l", + direction="r", }, - [0x11097]={ + [0x10934]={ category="lo", - direction="l", + direction="r", }, - [0x11098]={ + [0x10935]={ category="lo", - direction="l", + direction="r", }, - [0x11099]={ + [0x10936]={ category="lo", - direction="l", + direction="r", }, - [0x1109A]={ + [0x10937]={ category="lo", - direction="l", + direction="r", }, - [0x1109B]={ + [0x10938]={ category="lo", - direction="l", + direction="r", }, - [0x1109C]={ + [0x10939]={ category="lo", - direction="l", + direction="r", }, - [0x1109D]={ - category="lo", - direction="l", + [0x1093F]={ + category="po", + direction="r", }, - [0x1109E]={ + [0x10980]={ category="lo", - direction="l", + direction="r", }, - [0x1109F]={ + [0x10981]={ category="lo", - direction="l", + direction="r", }, - [0x110A0]={ + [0x10982]={ category="lo", - direction="l", + direction="r", }, - [0x110A1]={ + [0x10983]={ category="lo", - direction="l", + direction="r", }, - [0x110A2]={ + [0x10984]={ category="lo", - direction="l", + direction="r", }, - [0x110A3]={ + [0x10985]={ category="lo", - direction="l", + direction="r", }, - [0x110A4]={ + [0x10986]={ category="lo", - direction="l", + direction="r", }, - [0x110A5]={ + [0x10987]={ category="lo", - direction="l", + direction="r", }, - [0x110A6]={ + [0x10988]={ category="lo", - direction="l", + direction="r", }, - [0x110A7]={ + [0x10989]={ category="lo", - direction="l", + direction="r", }, - [0x110A8]={ + [0x1098A]={ category="lo", - direction="l", + direction="r", }, - [0x110A9]={ + [0x1098B]={ category="lo", - direction="l", + direction="r", }, - [0x110AA]={ + [0x1098C]={ category="lo", - direction="l", + direction="r", }, - [0x110AB]={ + [0x1098D]={ category="lo", - direction="l", + direction="r", }, - [0x110AC]={ + [0x1098E]={ category="lo", - direction="l", + direction="r", }, - [0x110AD]={ + [0x1098F]={ category="lo", - direction="l", + direction="r", }, - [0x110AE]={ + [0x10990]={ category="lo", - direction="l", + direction="r", }, - [0x110AF]={ + [0x10991]={ category="lo", - direction="l", - }, - [0x110B0]={ - category="mc", - direction="l", - }, - [0x110B1]={ - category="mc", - direction="l", - }, - [0x110B2]={ - category="mc", - direction="l", - }, - [0x110B3]={ - category="mn", - direction="nsm", - }, - [0x110B4]={ - category="mn", - direction="nsm", - }, - [0x110B5]={ - category="mn", - direction="nsm", - }, - [0x110B6]={ - category="mn", - direction="nsm", - }, - [0x110B7]={ - category="mc", - direction="l", + direction="r", }, - [0x110B8]={ - category="mc", - direction="l", + [0x10992]={ + category="lo", + direction="r", }, - [0x110B9]={ - category="mn", - direction="nsm", + [0x10993]={ + category="lo", + direction="r", }, - [0x110BA]={ - category="mn", - direction="nsm", + [0x10994]={ + category="lo", + direction="r", }, - [0x110BB]={ - category="po", - direction="l", + [0x10995]={ + category="lo", + direction="r", }, - [0x110BC]={ - category="po", - direction="l", + [0x10996]={ + category="lo", + direction="r", }, - [0x110BD]={ - category="cf", - direction="l", + [0x10997]={ + category="lo", + direction="r", }, - [0x110BE]={ - category="po", - direction="l", + [0x10998]={ + category="lo", + direction="r", }, - [0x110BF]={ - category="po", - direction="l", + [0x10999]={ + category="lo", + direction="r", }, - [0x110C0]={ - category="po", - direction="l", + [0x1099A]={ + category="lo", + direction="r", }, - [0x110C1]={ - category="po", - direction="l", + [0x1099B]={ + category="lo", + direction="r", }, - [0x110D0]={ + [0x1099C]={ category="lo", - direction="l", + direction="r", }, - [0x110D1]={ + [0x1099D]={ category="lo", - direction="l", + direction="r", }, - [0x110D2]={ + [0x1099E]={ category="lo", - direction="l", + direction="r", }, - [0x110D3]={ + [0x1099F]={ category="lo", - direction="l", + direction="r", }, - [0x110D4]={ + [0x109A0]={ category="lo", - direction="l", + direction="r", }, - [0x110D5]={ + [0x109A1]={ category="lo", - direction="l", + direction="r", }, - [0x110D6]={ + [0x109A2]={ category="lo", - direction="l", + direction="r", }, - [0x110D7]={ + [0x109A3]={ category="lo", - direction="l", + direction="r", }, - [0x110D8]={ + [0x109A4]={ category="lo", - direction="l", + direction="r", }, - [0x110D9]={ + [0x109A5]={ category="lo", - direction="l", + direction="r", }, - [0x110DA]={ + [0x109A6]={ category="lo", - direction="l", + direction="r", }, - [0x110DB]={ + [0x109A7]={ category="lo", - direction="l", + direction="r", }, - [0x110DC]={ + [0x109A8]={ category="lo", - direction="l", + direction="r", }, - [0x110DD]={ + [0x109A9]={ category="lo", - direction="l", + direction="r", }, - [0x110DE]={ + [0x109AA]={ category="lo", - direction="l", + direction="r", }, - [0x110DF]={ + [0x109AB]={ category="lo", - direction="l", + direction="r", }, - [0x110E0]={ + [0x109AC]={ category="lo", - direction="l", + direction="r", }, - [0x110E1]={ + [0x109AD]={ category="lo", - direction="l", + direction="r", }, - [0x110E2]={ + [0x109AE]={ category="lo", - direction="l", + direction="r", }, - [0x110E3]={ + [0x109AF]={ category="lo", - direction="l", + direction="r", }, - [0x110E4]={ + [0x109B0]={ category="lo", - direction="l", + direction="r", }, - [0x110E5]={ + [0x109B1]={ category="lo", - direction="l", + direction="r", }, - [0x110E6]={ + [0x109B2]={ category="lo", - direction="l", + direction="r", }, - [0x110E7]={ + [0x109B3]={ category="lo", - direction="l", + direction="r", }, - [0x110E8]={ + [0x109B4]={ category="lo", - direction="l", + direction="r", }, - [0x110F0]={ - category="nd", - direction="l", + [0x109B5]={ + category="lo", + direction="r", }, - [0x110F1]={ - category="nd", - direction="l", + [0x109B6]={ + category="lo", + direction="r", }, - [0x110F2]={ - category="nd", - direction="l", + [0x109B7]={ + category="lo", + direction="r", }, - [0x110F3]={ - category="nd", - direction="l", + [0x109BE]={ + category="lo", + direction="r", }, - [0x110F4]={ - category="nd", - direction="l", + [0x109BF]={ + category="lo", + direction="r", }, - [0x110F5]={ - category="nd", - direction="l", + [0x10A00]={ + category="lo", + direction="r", }, - [0x110F6]={ - category="nd", - direction="l", + [0x10A01]={ + category="mn", + direction="nsm", }, - [0x110F7]={ - category="nd", - direction="l", + [0x10A02]={ + category="mn", + direction="nsm", }, - [0x110F8]={ - category="nd", - direction="l", + [0x10A03]={ + category="mn", + direction="nsm", }, - [0x110F9]={ - category="nd", - direction="l", + [0x10A05]={ + category="mn", + direction="nsm", }, - [0x11100]={ + [0x10A06]={ category="mn", direction="nsm", }, - [0x11101]={ + [0x10A0C]={ category="mn", direction="nsm", }, - [0x11102]={ + [0x10A0D]={ category="mn", direction="nsm", }, - [0x11103]={ - category="lo", - direction="l", + [0x10A0E]={ + category="mn", + direction="nsm", }, - [0x11104]={ - category="lo", - direction="l", + [0x10A0F]={ + category="mn", + direction="nsm", }, - [0x11105]={ + [0x10A10]={ category="lo", - direction="l", + direction="r", }, - [0x11106]={ + [0x10A11]={ category="lo", - direction="l", + direction="r", }, - [0x11107]={ + [0x10A12]={ category="lo", - direction="l", + direction="r", }, - [0x11108]={ + [0x10A13]={ category="lo", - direction="l", + direction="r", }, - [0x11109]={ + [0x10A15]={ category="lo", - direction="l", + direction="r", }, - [0x1110A]={ + [0x10A16]={ category="lo", - direction="l", + direction="r", }, - [0x1110B]={ + [0x10A17]={ category="lo", - direction="l", + direction="r", }, - [0x1110C]={ + [0x10A19]={ category="lo", - direction="l", + direction="r", }, - [0x1110D]={ + [0x10A1A]={ category="lo", - direction="l", + direction="r", }, - [0x1110E]={ + [0x10A1B]={ category="lo", - direction="l", + direction="r", }, - [0x1110F]={ + [0x10A1C]={ category="lo", - direction="l", + direction="r", }, - [0x11110]={ + [0x10A1D]={ category="lo", - direction="l", + direction="r", }, - [0x11111]={ + [0x10A1E]={ category="lo", - direction="l", + direction="r", }, - [0x11112]={ + [0x10A1F]={ category="lo", - direction="l", + direction="r", }, - [0x11113]={ + [0x10A20]={ category="lo", - direction="l", + direction="r", }, - [0x11114]={ + [0x10A21]={ category="lo", - direction="l", + direction="r", }, - [0x11115]={ + [0x10A22]={ category="lo", - direction="l", + direction="r", }, - [0x11116]={ + [0x10A23]={ category="lo", - direction="l", + direction="r", }, - [0x11117]={ + [0x10A24]={ category="lo", - direction="l", + direction="r", }, - [0x11118]={ + [0x10A25]={ category="lo", - direction="l", + direction="r", }, - [0x11119]={ + [0x10A26]={ category="lo", - direction="l", + direction="r", }, - [0x1111A]={ + [0x10A27]={ category="lo", - direction="l", + direction="r", }, - [0x1111B]={ + [0x10A28]={ category="lo", - direction="l", + direction="r", }, - [0x1111C]={ + [0x10A29]={ category="lo", - direction="l", + direction="r", }, - [0x1111D]={ + [0x10A2A]={ category="lo", - direction="l", + direction="r", }, - [0x1111E]={ + [0x10A2B]={ category="lo", - direction="l", + direction="r", }, - [0x1111F]={ + [0x10A2C]={ category="lo", - direction="l", + direction="r", }, - [0x11120]={ + [0x10A2D]={ category="lo", - direction="l", + direction="r", }, - [0x11121]={ + [0x10A2E]={ category="lo", - direction="l", + direction="r", }, - [0x11122]={ + [0x10A2F]={ category="lo", - direction="l", + direction="r", }, - [0x11123]={ + [0x10A30]={ category="lo", - direction="l", + direction="r", }, - [0x11124]={ + [0x10A31]={ category="lo", - direction="l", + direction="r", }, - [0x11125]={ + [0x10A32]={ category="lo", - direction="l", + direction="r", }, - [0x11126]={ + [0x10A33]={ category="lo", - direction="l", + direction="r", }, - [0x11127]={ + [0x10A38]={ category="mn", direction="nsm", }, - [0x11128]={ + [0x10A39]={ category="mn", direction="nsm", }, - [0x11129]={ + [0x10A3A]={ category="mn", direction="nsm", }, - [0x1112A]={ + [0x10A3F]={ category="mn", direction="nsm", }, - [0x1112B]={ - category="mn", - direction="nsm", + [0x10A40]={ + category="no", + direction="r", }, - [0x1112C]={ - category="mc", - direction="l", + [0x10A41]={ + category="no", + direction="r", }, - [0x1112D]={ - category="mn", - direction="nsm", + [0x10A42]={ + category="no", + direction="r", }, - [0x1112E]={ - category="mn", - direction="nsm", - }, - [0x1112F]={ - category="mn", - direction="nsm", - }, - [0x11130]={ - category="mn", - direction="nsm", - }, - [0x11131]={ - category="mn", - direction="nsm", - }, - [0x11132]={ - category="mn", - direction="nsm", - }, - [0x11133]={ - category="mn", - direction="nsm", - }, - [0x11134]={ - category="mn", - direction="nsm", - }, - [0x11136]={ - category="nd", - direction="l", - }, - [0x11137]={ - category="nd", - direction="l", - }, - [0x11138]={ - category="nd", - direction="l", - }, - [0x11139]={ - category="nd", - direction="l", + [0x10A43]={ + category="no", + direction="r", }, - [0x1113A]={ - category="nd", - direction="l", + [0x10A44]={ + category="no", + direction="r", }, - [0x1113B]={ - category="nd", - direction="l", + [0x10A45]={ + category="no", + direction="r", }, - [0x1113C]={ - category="nd", - direction="l", + [0x10A46]={ + category="no", + direction="r", }, - [0x1113D]={ - category="nd", - direction="l", + [0x10A47]={ + category="no", + direction="r", }, - [0x1113E]={ - category="nd", - direction="l", + [0x10A50]={ + category="po", + direction="r", }, - [0x1113F]={ - category="nd", - direction="l", + [0x10A51]={ + category="po", + direction="r", }, - [0x11140]={ + [0x10A52]={ category="po", - direction="l", + direction="r", }, - [0x11141]={ + [0x10A53]={ category="po", - direction="l", + direction="r", }, - [0x11142]={ + [0x10A54]={ category="po", - direction="l", + direction="r", }, - [0x11143]={ + [0x10A55]={ category="po", - direction="l", + direction="r", }, - [0x11180]={ - category="mn", - direction="nsm", + [0x10A56]={ + category="po", + direction="r", }, - [0x11181]={ - category="mn", - direction="nsm", + [0x10A57]={ + category="po", + direction="r", }, - [0x11182]={ - category="mc", - direction="l", + [0x10A58]={ + category="po", + direction="r", }, - [0x11183]={ + [0x10A60]={ category="lo", - direction="l", + direction="r", }, - [0x11184]={ + [0x10A61]={ category="lo", - direction="l", + direction="r", }, - [0x11185]={ + [0x10A62]={ category="lo", - direction="l", + direction="r", }, - [0x11186]={ + [0x10A63]={ category="lo", - direction="l", + direction="r", }, - [0x11187]={ + [0x10A64]={ category="lo", - direction="l", + direction="r", }, - [0x11188]={ + [0x10A65]={ category="lo", - direction="l", + direction="r", }, - [0x11189]={ + [0x10A66]={ category="lo", - direction="l", + direction="r", }, - [0x1118A]={ + [0x10A67]={ category="lo", - direction="l", + direction="r", }, - [0x1118B]={ + [0x10A68]={ category="lo", - direction="l", + direction="r", }, - [0x1118C]={ + [0x10A69]={ category="lo", - direction="l", + direction="r", }, - [0x1118D]={ + [0x10A6A]={ category="lo", - direction="l", + direction="r", }, - [0x1118E]={ + [0x10A6B]={ category="lo", - direction="l", + direction="r", }, - [0x1118F]={ + [0x10A6C]={ category="lo", - direction="l", + direction="r", }, - [0x11190]={ + [0x10A6D]={ category="lo", - direction="l", + direction="r", }, - [0x11191]={ + [0x10A6E]={ category="lo", - direction="l", + direction="r", }, - [0x11192]={ + [0x10A6F]={ category="lo", - direction="l", + direction="r", }, - [0x11193]={ + [0x10A70]={ category="lo", - direction="l", + direction="r", }, - [0x11194]={ + [0x10A71]={ category="lo", - direction="l", + direction="r", }, - [0x11195]={ + [0x10A72]={ category="lo", - direction="l", + direction="r", }, - [0x11196]={ + [0x10A73]={ category="lo", - direction="l", + direction="r", }, - [0x11197]={ + [0x10A74]={ category="lo", - direction="l", + direction="r", }, - [0x11198]={ + [0x10A75]={ category="lo", - direction="l", + direction="r", }, - [0x11199]={ + [0x10A76]={ category="lo", - direction="l", + direction="r", }, - [0x1119A]={ + [0x10A77]={ category="lo", - direction="l", + direction="r", }, - [0x1119B]={ + [0x10A78]={ category="lo", - direction="l", + direction="r", }, - [0x1119C]={ + [0x10A79]={ category="lo", - direction="l", + direction="r", }, - [0x1119D]={ + [0x10A7A]={ category="lo", - direction="l", + direction="r", }, - [0x1119E]={ + [0x10A7B]={ category="lo", - direction="l", + direction="r", }, - [0x1119F]={ + [0x10A7C]={ category="lo", - direction="l", + direction="r", }, - [0x111A0]={ - category="lo", - direction="l", + [0x10A7D]={ + category="no", + direction="r", }, - [0x111A1]={ + [0x10A7E]={ + category="no", + direction="r", + }, + [0x10A7F]={ + category="po", + direction="r", + }, + [0x10A80]={ category="lo", - direction="l", + direction="r", }, - [0x111A2]={ + [0x10A81]={ category="lo", - direction="l", + direction="r", }, - [0x111A3]={ + [0x10A82]={ category="lo", - direction="l", + direction="r", }, - [0x111A4]={ + [0x10A83]={ category="lo", - direction="l", + direction="r", }, - [0x111A5]={ + [0x10A84]={ category="lo", - direction="l", + direction="r", }, - [0x111A6]={ + [0x10A85]={ category="lo", - direction="l", + direction="r", }, - [0x111A7]={ + [0x10A86]={ category="lo", - direction="l", + direction="r", }, - [0x111A8]={ + [0x10A87]={ category="lo", - direction="l", + direction="r", }, - [0x111A9]={ + [0x10A88]={ category="lo", - direction="l", + direction="r", }, - [0x111AA]={ + [0x10A89]={ category="lo", - direction="l", + direction="r", }, - [0x111AB]={ + [0x10A8A]={ category="lo", - direction="l", + direction="r", }, - [0x111AC]={ + [0x10A8B]={ category="lo", - direction="l", + direction="r", }, - [0x111AD]={ + [0x10A8C]={ category="lo", - direction="l", + direction="r", }, - [0x111AE]={ + [0x10A8D]={ category="lo", - direction="l", + direction="r", }, - [0x111AF]={ + [0x10A8E]={ category="lo", - direction="l", + direction="r", }, - [0x111B0]={ + [0x10A8F]={ category="lo", - direction="l", + direction="r", }, - [0x111B1]={ + [0x10A90]={ category="lo", - direction="l", + direction="r", }, - [0x111B2]={ + [0x10A91]={ category="lo", - direction="l", + direction="r", }, - [0x111B3]={ - category="mc", - direction="l", + [0x10A92]={ + category="lo", + direction="r", }, - [0x111B4]={ - category="mc", - direction="l", + [0x10A93]={ + category="lo", + direction="r", }, - [0x111B5]={ - category="mc", - direction="l", + [0x10A94]={ + category="lo", + direction="r", }, - [0x111B6]={ - category="mn", - direction="nsm", + [0x10A95]={ + category="lo", + direction="r", }, - [0x111B7]={ - category="mn", - direction="nsm", + [0x10A96]={ + category="lo", + direction="r", }, - [0x111B8]={ - category="mn", - direction="nsm", + [0x10A97]={ + category="lo", + direction="r", }, - [0x111B9]={ - category="mn", - direction="nsm", + [0x10A98]={ + category="lo", + direction="r", }, - [0x111BA]={ - category="mn", - direction="nsm", + [0x10A99]={ + category="lo", + direction="r", }, - [0x111BB]={ - category="mn", - direction="nsm", + [0x10A9A]={ + category="lo", + direction="r", }, - [0x111BC]={ - category="mn", - direction="nsm", + [0x10A9B]={ + category="lo", + direction="r", }, - [0x111BD]={ - category="mn", - direction="nsm", + [0x10A9C]={ + category="lo", + direction="r", }, - [0x111BE]={ - category="mn", - direction="nsm", + [0x10A9D]={ + category="no", + direction="r", }, - [0x111BF]={ - category="mc", - direction="l", + [0x10A9E]={ + category="no", + direction="r", }, - [0x111C0]={ - category="mc", - direction="l", + [0x10A9F]={ + category="no", + direction="r", }, - [0x111C1]={ + [0x10AC0]={ category="lo", - direction="l", + direction="r", }, - [0x111C2]={ + [0x10AC1]={ category="lo", - direction="l", + direction="r", }, - [0x111C3]={ + [0x10AC2]={ category="lo", - direction="l", + direction="r", }, - [0x111C4]={ + [0x10AC3]={ category="lo", - direction="l", - }, - [0x111C5]={ - category="po", - direction="l", - }, - [0x111C6]={ - category="po", - direction="l", - }, - [0x111C7]={ - category="po", - direction="l", - }, - [0x111C8]={ - category="po", - direction="l", - }, - [0x111D0]={ - category="nd", - direction="l", + direction="r", }, - [0x111D1]={ - category="nd", - direction="l", + [0x10AC4]={ + category="lo", + direction="r", }, - [0x111D2]={ - category="nd", - direction="l", + [0x10AC5]={ + category="lo", + direction="r", }, - [0x111D3]={ - category="nd", - direction="l", + [0x10AC6]={ + category="lo", + direction="r", }, - [0x111D4]={ - category="nd", - direction="l", + [0x10AC7]={ + category="lo", + direction="r", }, - [0x111D5]={ - category="nd", - direction="l", + [0x10AC8]={ + category="so", + direction="r", }, - [0x111D6]={ - category="nd", - direction="l", + [0x10AC9]={ + category="lo", + direction="r", }, - [0x111D7]={ - category="nd", - direction="l", + [0x10ACA]={ + category="lo", + direction="r", }, - [0x111D8]={ - category="nd", - direction="l", + [0x10ACB]={ + category="lo", + direction="r", }, - [0x111D9]={ - category="nd", - direction="l", + [0x10ACC]={ + category="lo", + direction="r", }, - [0x11680]={ + [0x10ACD]={ category="lo", - direction="l", + direction="r", }, - [0x11681]={ + [0x10ACE]={ category="lo", - direction="l", + direction="r", }, - [0x11682]={ + [0x10ACF]={ category="lo", - direction="l", + direction="r", }, - [0x11683]={ + [0x10AD0]={ category="lo", - direction="l", + direction="r", }, - [0x11684]={ + [0x10AD1]={ category="lo", - direction="l", + direction="r", }, - [0x11685]={ + [0x10AD2]={ category="lo", - direction="l", + direction="r", }, - [0x11686]={ + [0x10AD3]={ category="lo", - direction="l", + direction="r", }, - [0x11687]={ + [0x10AD4]={ category="lo", - direction="l", + direction="r", }, - [0x11688]={ + [0x10AD5]={ category="lo", - direction="l", + direction="r", }, - [0x11689]={ + [0x10AD6]={ category="lo", - direction="l", + direction="r", }, - [0x1168A]={ + [0x10AD7]={ category="lo", - direction="l", + direction="r", }, - [0x1168B]={ + [0x10AD8]={ category="lo", - direction="l", + direction="r", }, - [0x1168C]={ + [0x10AD9]={ category="lo", - direction="l", + direction="r", }, - [0x1168D]={ + [0x10ADA]={ category="lo", - direction="l", + direction="r", }, - [0x1168E]={ + [0x10ADB]={ category="lo", - direction="l", + direction="r", }, - [0x1168F]={ + [0x10ADC]={ category="lo", - direction="l", + direction="r", }, - [0x11690]={ + [0x10ADD]={ category="lo", - direction="l", + direction="r", }, - [0x11691]={ + [0x10ADE]={ category="lo", - direction="l", + direction="r", }, - [0x11692]={ + [0x10ADF]={ category="lo", - direction="l", + direction="r", }, - [0x11693]={ + [0x10AE0]={ category="lo", - direction="l", + direction="r", }, - [0x11694]={ + [0x10AE1]={ category="lo", - direction="l", + direction="r", }, - [0x11695]={ + [0x10AE2]={ category="lo", - direction="l", + direction="r", }, - [0x11696]={ + [0x10AE3]={ category="lo", - direction="l", + direction="r", }, - [0x11697]={ + [0x10AE4]={ category="lo", - direction="l", + direction="r", }, - [0x11698]={ - category="lo", - direction="l", + [0x10AE5]={ + category="mn", + direction="nsm", }, - [0x11699]={ - category="lo", - direction="l", + [0x10AE6]={ + category="mn", + direction="nsm", }, - [0x1169A]={ - category="lo", - direction="l", + [0x10AEB]={ + category="no", + direction="r", }, - [0x1169B]={ - category="lo", - direction="l", + [0x10AEC]={ + category="no", + direction="r", }, - [0x1169C]={ - category="lo", - direction="l", + [0x10AED]={ + category="no", + direction="r", }, - [0x1169D]={ - category="lo", - direction="l", + [0x10AEE]={ + category="no", + direction="r", }, - [0x1169E]={ - category="lo", - direction="l", + [0x10AEF]={ + category="no", + direction="r", }, - [0x1169F]={ - category="lo", - direction="l", + [0x10AF0]={ + category="po", + direction="r", }, - [0x116A0]={ - category="lo", - direction="l", + [0x10AF1]={ + category="po", + direction="r", }, - [0x116A1]={ - category="lo", - direction="l", + [0x10AF2]={ + category="po", + direction="r", }, - [0x116A2]={ - category="lo", - direction="l", + [0x10AF3]={ + category="po", + direction="r", }, - [0x116A3]={ - category="lo", - direction="l", + [0x10AF4]={ + category="po", + direction="r", }, - [0x116A4]={ - category="lo", - direction="l", + [0x10AF5]={ + category="po", + direction="r", }, - [0x116A5]={ - category="lo", - direction="l", + [0x10AF6]={ + category="po", + direction="r", }, - [0x116A6]={ + [0x10B00]={ category="lo", - direction="l", + direction="r", }, - [0x116A7]={ + [0x10B01]={ category="lo", - direction="l", + direction="r", }, - [0x116A8]={ + [0x10B02]={ category="lo", - direction="l", + direction="r", }, - [0x116A9]={ + [0x10B03]={ category="lo", - direction="l", + direction="r", }, - [0x116AA]={ + [0x10B04]={ category="lo", - direction="l", - }, - [0x116AB]={ - category="mn", - direction="nsm", - }, - [0x116AC]={ - category="mc", - direction="l", - }, - [0x116AD]={ - category="mn", - direction="nsm", - }, - [0x116AE]={ - category="mc", - direction="l", - }, - [0x116AF]={ - category="mc", - direction="l", - }, - [0x116B0]={ - category="mn", - direction="nsm", - }, - [0x116B1]={ - category="mn", - direction="nsm", - }, - [0x116B2]={ - category="mn", - direction="nsm", - }, - [0x116B3]={ - category="mn", - direction="nsm", - }, - [0x116B4]={ - category="mn", - direction="nsm", - }, - [0x116B5]={ - category="mn", - direction="nsm", - }, - [0x116B6]={ - category="mc", - direction="l", - }, - [0x116B7]={ - category="mn", - direction="nsm", - }, - [0x116C0]={ - category="nd", - direction="l", - }, - [0x116C1]={ - category="nd", - direction="l", - }, - [0x116C2]={ - category="nd", - direction="l", - }, - [0x116C3]={ - category="nd", - direction="l", - }, - [0x116C4]={ - category="nd", - direction="l", - }, - [0x116C5]={ - category="nd", - direction="l", - }, - [0x116C6]={ - category="nd", - direction="l", - }, - [0x116C7]={ - category="nd", - direction="l", - }, - [0x116C8]={ - category="nd", - direction="l", - }, - [0x116C9]={ - category="nd", - direction="l", + direction="r", }, - [0x12000]={ + [0x10B05]={ category="lo", - direction="l", + direction="r", }, - [0x12001]={ + [0x10B06]={ category="lo", - direction="l", + direction="r", }, - [0x12002]={ + [0x10B07]={ category="lo", - direction="l", + direction="r", }, - [0x12003]={ + [0x10B08]={ category="lo", - direction="l", + direction="r", }, - [0x12004]={ + [0x10B09]={ category="lo", - direction="l", + direction="r", }, - [0x12005]={ + [0x10B0A]={ category="lo", - direction="l", + direction="r", }, - [0x12006]={ + [0x10B0B]={ category="lo", - direction="l", + direction="r", }, - [0x12007]={ + [0x10B0C]={ category="lo", - direction="l", + direction="r", }, - [0x12008]={ + [0x10B0D]={ category="lo", - direction="l", + direction="r", }, - [0x12009]={ + [0x10B0E]={ category="lo", - direction="l", + direction="r", }, - [0x1200A]={ + [0x10B0F]={ category="lo", - direction="l", + direction="r", }, - [0x1200B]={ + [0x10B10]={ category="lo", - direction="l", + direction="r", }, - [0x1200C]={ + [0x10B11]={ category="lo", - direction="l", + direction="r", }, - [0x1200D]={ + [0x10B12]={ category="lo", - direction="l", + direction="r", }, - [0x1200E]={ + [0x10B13]={ category="lo", - direction="l", + direction="r", }, - [0x1200F]={ + [0x10B14]={ category="lo", - direction="l", + direction="r", }, - [0x12010]={ + [0x10B15]={ category="lo", - direction="l", + direction="r", }, - [0x12011]={ + [0x10B16]={ category="lo", - direction="l", + direction="r", }, - [0x12012]={ + [0x10B17]={ category="lo", - direction="l", + direction="r", }, - [0x12013]={ + [0x10B18]={ category="lo", - direction="l", + direction="r", }, - [0x12014]={ + [0x10B19]={ category="lo", - direction="l", + direction="r", }, - [0x12015]={ + [0x10B1A]={ category="lo", - direction="l", + direction="r", }, - [0x12016]={ + [0x10B1B]={ category="lo", - direction="l", + direction="r", }, - [0x12017]={ + [0x10B1C]={ category="lo", - direction="l", + direction="r", }, - [0x12018]={ + [0x10B1D]={ category="lo", - direction="l", + direction="r", }, - [0x12019]={ + [0x10B1E]={ category="lo", - direction="l", + direction="r", }, - [0x1201A]={ + [0x10B1F]={ category="lo", - direction="l", + direction="r", }, - [0x1201B]={ + [0x10B20]={ category="lo", - direction="l", + direction="r", }, - [0x1201C]={ + [0x10B21]={ category="lo", - direction="l", + direction="r", }, - [0x1201D]={ + [0x10B22]={ category="lo", - direction="l", + direction="r", }, - [0x1201E]={ + [0x10B23]={ category="lo", - direction="l", + direction="r", }, - [0x1201F]={ + [0x10B24]={ category="lo", - direction="l", + direction="r", }, - [0x12020]={ + [0x10B25]={ category="lo", - direction="l", + direction="r", }, - [0x12021]={ + [0x10B26]={ category="lo", - direction="l", + direction="r", }, - [0x12022]={ + [0x10B27]={ category="lo", - direction="l", + direction="r", }, - [0x12023]={ + [0x10B28]={ category="lo", - direction="l", + direction="r", }, - [0x12024]={ + [0x10B29]={ category="lo", - direction="l", + direction="r", }, - [0x12025]={ + [0x10B2A]={ category="lo", - direction="l", + direction="r", }, - [0x12026]={ + [0x10B2B]={ category="lo", - direction="l", + direction="r", }, - [0x12027]={ + [0x10B2C]={ category="lo", - direction="l", + direction="r", }, - [0x12028]={ + [0x10B2D]={ category="lo", - direction="l", + direction="r", }, - [0x12029]={ + [0x10B2E]={ category="lo", - direction="l", + direction="r", }, - [0x1202A]={ + [0x10B2F]={ category="lo", - direction="l", + direction="r", }, - [0x1202B]={ + [0x10B30]={ category="lo", - direction="l", + direction="r", }, - [0x1202C]={ + [0x10B31]={ category="lo", - direction="l", + direction="r", }, - [0x1202D]={ + [0x10B32]={ category="lo", - direction="l", + direction="r", }, - [0x1202E]={ + [0x10B33]={ category="lo", - direction="l", + direction="r", }, - [0x1202F]={ + [0x10B34]={ category="lo", - direction="l", + direction="r", }, - [0x12030]={ + [0x10B35]={ category="lo", - direction="l", + direction="r", }, - [0x12031]={ - category="lo", - direction="l", + [0x10B39]={ + category="po", + direction="on", }, - [0x12032]={ - category="lo", - direction="l", + [0x10B3A]={ + category="po", + direction="on", }, - [0x12033]={ - category="lo", - direction="l", + [0x10B3B]={ + category="po", + direction="on", }, - [0x12034]={ - category="lo", - direction="l", + [0x10B3C]={ + category="po", + direction="on", }, - [0x12035]={ - category="lo", - direction="l", + [0x10B3D]={ + category="po", + direction="on", }, - [0x12036]={ - category="lo", - direction="l", + [0x10B3E]={ + category="po", + direction="on", }, - [0x12037]={ - category="lo", - direction="l", + [0x10B3F]={ + category="po", + direction="on", }, - [0x12038]={ + [0x10B40]={ category="lo", - direction="l", + direction="r", }, - [0x12039]={ + [0x10B41]={ category="lo", - direction="l", + direction="r", }, - [0x1203A]={ + [0x10B42]={ category="lo", - direction="l", + direction="r", }, - [0x1203B]={ + [0x10B43]={ category="lo", - direction="l", + direction="r", }, - [0x1203C]={ + [0x10B44]={ category="lo", - direction="l", + direction="r", }, - [0x1203D]={ + [0x10B45]={ category="lo", - direction="l", + direction="r", }, - [0x1203E]={ + [0x10B46]={ category="lo", - direction="l", + direction="r", }, - [0x1203F]={ + [0x10B47]={ category="lo", - direction="l", + direction="r", }, - [0x12040]={ + [0x10B48]={ category="lo", - direction="l", + direction="r", }, - [0x12041]={ + [0x10B49]={ category="lo", - direction="l", + direction="r", }, - [0x12042]={ + [0x10B4A]={ category="lo", - direction="l", + direction="r", }, - [0x12043]={ + [0x10B4B]={ category="lo", - direction="l", + direction="r", }, - [0x12044]={ + [0x10B4C]={ category="lo", - direction="l", + direction="r", }, - [0x12045]={ + [0x10B4D]={ category="lo", - direction="l", + direction="r", }, - [0x12046]={ + [0x10B4E]={ category="lo", - direction="l", + direction="r", }, - [0x12047]={ + [0x10B4F]={ category="lo", - direction="l", + direction="r", }, - [0x12048]={ + [0x10B50]={ category="lo", - direction="l", + direction="r", }, - [0x12049]={ + [0x10B51]={ category="lo", - direction="l", + direction="r", }, - [0x1204A]={ + [0x10B52]={ category="lo", - direction="l", + direction="r", }, - [0x1204B]={ + [0x10B53]={ category="lo", - direction="l", + direction="r", }, - [0x1204C]={ + [0x10B54]={ category="lo", - direction="l", + direction="r", }, - [0x1204D]={ + [0x10B55]={ category="lo", - direction="l", + direction="r", }, - [0x1204E]={ - category="lo", - direction="l", + [0x10B58]={ + category="no", + direction="r", }, - [0x1204F]={ - category="lo", - direction="l", + [0x10B59]={ + category="no", + direction="r", }, - [0x12050]={ - category="lo", - direction="l", + [0x10B5A]={ + category="no", + direction="r", }, - [0x12051]={ - category="lo", - direction="l", + [0x10B5B]={ + category="no", + direction="r", }, - [0x12052]={ - category="lo", - direction="l", + [0x10B5C]={ + category="no", + direction="r", }, - [0x12053]={ - category="lo", - direction="l", + [0x10B5D]={ + category="no", + direction="r", }, - [0x12054]={ - category="lo", - direction="l", + [0x10B5E]={ + category="no", + direction="r", }, - [0x12055]={ - category="lo", - direction="l", + [0x10B5F]={ + category="no", + direction="r", }, - [0x12056]={ + [0x10B60]={ category="lo", - direction="l", + direction="r", }, - [0x12057]={ + [0x10B61]={ category="lo", - direction="l", + direction="r", }, - [0x12058]={ + [0x10B62]={ category="lo", - direction="l", + direction="r", }, - [0x12059]={ + [0x10B63]={ category="lo", - direction="l", + direction="r", }, - [0x1205A]={ + [0x10B64]={ category="lo", - direction="l", + direction="r", }, - [0x1205B]={ + [0x10B65]={ category="lo", - direction="l", + direction="r", }, - [0x1205C]={ + [0x10B66]={ category="lo", - direction="l", + direction="r", }, - [0x1205D]={ + [0x10B67]={ category="lo", - direction="l", + direction="r", }, - [0x1205E]={ + [0x10B68]={ category="lo", - direction="l", + direction="r", }, - [0x1205F]={ + [0x10B69]={ category="lo", - direction="l", + direction="r", }, - [0x12060]={ + [0x10B6A]={ category="lo", - direction="l", + direction="r", }, - [0x12061]={ + [0x10B6B]={ category="lo", - direction="l", + direction="r", }, - [0x12062]={ + [0x10B6C]={ category="lo", - direction="l", + direction="r", }, - [0x12063]={ + [0x10B6D]={ category="lo", - direction="l", + direction="r", }, - [0x12064]={ + [0x10B6E]={ category="lo", - direction="l", + direction="r", }, - [0x12065]={ + [0x10B6F]={ category="lo", - direction="l", + direction="r", }, - [0x12066]={ + [0x10B70]={ category="lo", - direction="l", + direction="r", }, - [0x12067]={ + [0x10B71]={ category="lo", - direction="l", + direction="r", }, - [0x12068]={ + [0x10B72]={ category="lo", - direction="l", + direction="r", }, - [0x12069]={ - category="lo", - direction="l", + [0x10B78]={ + category="no", + direction="r", }, - [0x1206A]={ - category="lo", - direction="l", + [0x10B79]={ + category="no", + direction="r", }, - [0x1206B]={ - category="lo", - direction="l", + [0x10B7A]={ + category="no", + direction="r", }, - [0x1206C]={ - category="lo", - direction="l", + [0x10B7B]={ + category="no", + direction="r", }, - [0x1206D]={ - category="lo", - direction="l", + [0x10B7C]={ + category="no", + direction="r", }, - [0x1206E]={ - category="lo", - direction="l", + [0x10B7D]={ + category="no", + direction="r", }, - [0x1206F]={ - category="lo", - direction="l", + [0x10B7E]={ + category="no", + direction="r", }, - [0x12070]={ - category="lo", - direction="l", + [0x10B7F]={ + category="no", + direction="r", }, - [0x12071]={ + [0x10B80]={ category="lo", - direction="l", + direction="r", }, - [0x12072]={ + [0x10B81]={ category="lo", - direction="l", + direction="r", }, - [0x12073]={ + [0x10B82]={ category="lo", - direction="l", + direction="r", }, - [0x12074]={ + [0x10B83]={ category="lo", - direction="l", + direction="r", }, - [0x12075]={ + [0x10B84]={ category="lo", - direction="l", + direction="r", }, - [0x12076]={ + [0x10B85]={ category="lo", - direction="l", + direction="r", }, - [0x12077]={ + [0x10B86]={ category="lo", - direction="l", + direction="r", }, - [0x12078]={ + [0x10B87]={ category="lo", - direction="l", + direction="r", }, - [0x12079]={ + [0x10B88]={ category="lo", - direction="l", + direction="r", }, - [0x1207A]={ + [0x10B89]={ category="lo", - direction="l", + direction="r", }, - [0x1207B]={ + [0x10B8A]={ category="lo", - direction="l", + direction="r", }, - [0x1207C]={ + [0x10B8B]={ category="lo", - direction="l", + direction="r", }, - [0x1207D]={ + [0x10B8C]={ category="lo", - direction="l", + direction="r", }, - [0x1207E]={ + [0x10B8D]={ category="lo", - direction="l", + direction="r", }, - [0x1207F]={ + [0x10B8E]={ category="lo", - direction="l", + direction="r", }, - [0x12080]={ + [0x10B8F]={ category="lo", - direction="l", + direction="r", }, - [0x12081]={ + [0x10B90]={ category="lo", - direction="l", + direction="r", }, - [0x12082]={ + [0x10B91]={ category="lo", - direction="l", + direction="r", }, - [0x12083]={ - category="lo", - direction="l", + [0x10B99]={ + category="po", + direction="r", }, - [0x12084]={ - category="lo", - direction="l", + [0x10B9A]={ + category="po", + direction="r", }, - [0x12085]={ - category="lo", - direction="l", + [0x10B9B]={ + category="po", + direction="r", }, - [0x12086]={ - category="lo", - direction="l", + [0x10B9C]={ + category="po", + direction="r", }, - [0x12087]={ - category="lo", - direction="l", + [0x10BA9]={ + category="no", + direction="r", }, - [0x12088]={ - category="lo", - direction="l", + [0x10BAA]={ + category="no", + direction="r", }, - [0x12089]={ - category="lo", - direction="l", + [0x10BAB]={ + category="no", + direction="r", }, - [0x1208A]={ - category="lo", - direction="l", + [0x10BAC]={ + category="no", + direction="r", }, - [0x1208B]={ - category="lo", - direction="l", + [0x10BAD]={ + category="no", + direction="r", }, - [0x1208C]={ - category="lo", - direction="l", + [0x10BAE]={ + category="no", + direction="r", }, - [0x1208D]={ - category="lo", - direction="l", + [0x10BAF]={ + category="no", + direction="r", }, - [0x1208E]={ + [0x10C00]={ category="lo", - direction="l", + direction="r", }, - [0x1208F]={ + [0x10C01]={ category="lo", - direction="l", + direction="r", }, - [0x12090]={ + [0x10C02]={ category="lo", - direction="l", + direction="r", }, - [0x12091]={ + [0x10C03]={ category="lo", - direction="l", + direction="r", }, - [0x12092]={ + [0x10C04]={ category="lo", - direction="l", + direction="r", }, - [0x12093]={ + [0x10C05]={ category="lo", - direction="l", + direction="r", }, - [0x12094]={ + [0x10C06]={ category="lo", - direction="l", + direction="r", }, - [0x12095]={ + [0x10C07]={ category="lo", - direction="l", + direction="r", }, - [0x12096]={ + [0x10C08]={ category="lo", - direction="l", + direction="r", }, - [0x12097]={ + [0x10C09]={ category="lo", - direction="l", + direction="r", }, - [0x12098]={ + [0x10C0A]={ category="lo", - direction="l", + direction="r", }, - [0x12099]={ + [0x10C0B]={ category="lo", - direction="l", + direction="r", }, - [0x1209A]={ + [0x10C0C]={ category="lo", - direction="l", + direction="r", }, - [0x1209B]={ + [0x10C0D]={ category="lo", - direction="l", + direction="r", }, - [0x1209C]={ + [0x10C0E]={ category="lo", - direction="l", + direction="r", }, - [0x1209D]={ + [0x10C0F]={ category="lo", - direction="l", + direction="r", }, - [0x1209E]={ + [0x10C10]={ category="lo", - direction="l", + direction="r", }, - [0x1209F]={ + [0x10C11]={ category="lo", - direction="l", + direction="r", }, - [0x120A0]={ + [0x10C12]={ category="lo", - direction="l", + direction="r", }, - [0x120A1]={ + [0x10C13]={ category="lo", - direction="l", + direction="r", }, - [0x120A2]={ + [0x10C14]={ category="lo", - direction="l", + direction="r", }, - [0x120A3]={ + [0x10C15]={ category="lo", - direction="l", + direction="r", }, - [0x120A4]={ + [0x10C16]={ category="lo", - direction="l", + direction="r", }, - [0x120A5]={ + [0x10C17]={ category="lo", - direction="l", + direction="r", }, - [0x120A6]={ + [0x10C18]={ category="lo", - direction="l", + direction="r", }, - [0x120A7]={ + [0x10C19]={ category="lo", - direction="l", + direction="r", }, - [0x120A8]={ + [0x10C1A]={ category="lo", - direction="l", + direction="r", }, - [0x120A9]={ + [0x10C1B]={ category="lo", - direction="l", + direction="r", }, - [0x120AA]={ + [0x10C1C]={ category="lo", - direction="l", + direction="r", }, - [0x120AB]={ + [0x10C1D]={ category="lo", - direction="l", + direction="r", }, - [0x120AC]={ + [0x10C1E]={ category="lo", - direction="l", + direction="r", }, - [0x120AD]={ + [0x10C1F]={ category="lo", - direction="l", + direction="r", }, - [0x120AE]={ + [0x10C20]={ category="lo", - direction="l", + direction="r", }, - [0x120AF]={ + [0x10C21]={ category="lo", - direction="l", + direction="r", }, - [0x120B0]={ + [0x10C22]={ category="lo", - direction="l", + direction="r", }, - [0x120B1]={ + [0x10C23]={ category="lo", - direction="l", + direction="r", }, - [0x120B2]={ + [0x10C24]={ category="lo", - direction="l", + direction="r", }, - [0x120B3]={ + [0x10C25]={ category="lo", - direction="l", + direction="r", }, - [0x120B4]={ + [0x10C26]={ category="lo", - direction="l", + direction="r", }, - [0x120B5]={ + [0x10C27]={ category="lo", - direction="l", + direction="r", }, - [0x120B6]={ + [0x10C28]={ category="lo", - direction="l", + direction="r", }, - [0x120B7]={ + [0x10C29]={ category="lo", - direction="l", + direction="r", }, - [0x120B8]={ + [0x10C2A]={ category="lo", - direction="l", + direction="r", }, - [0x120B9]={ + [0x10C2B]={ category="lo", - direction="l", + direction="r", }, - [0x120BA]={ + [0x10C2C]={ category="lo", - direction="l", + direction="r", }, - [0x120BB]={ + [0x10C2D]={ category="lo", - direction="l", + direction="r", }, - [0x120BC]={ + [0x10C2E]={ category="lo", - direction="l", + direction="r", }, - [0x120BD]={ + [0x10C2F]={ category="lo", - direction="l", + direction="r", }, - [0x120BE]={ + [0x10C30]={ category="lo", - direction="l", + direction="r", }, - [0x120BF]={ + [0x10C31]={ category="lo", - direction="l", + direction="r", }, - [0x120C0]={ + [0x10C32]={ category="lo", - direction="l", + direction="r", }, - [0x120C1]={ + [0x10C33]={ category="lo", - direction="l", + direction="r", }, - [0x120C2]={ + [0x10C34]={ category="lo", - direction="l", + direction="r", }, - [0x120C3]={ + [0x10C35]={ category="lo", - direction="l", + direction="r", }, - [0x120C4]={ + [0x10C36]={ category="lo", - direction="l", + direction="r", }, - [0x120C5]={ + [0x10C37]={ category="lo", - direction="l", + direction="r", }, - [0x120C6]={ + [0x10C38]={ category="lo", - direction="l", + direction="r", }, - [0x120C7]={ + [0x10C39]={ category="lo", - direction="l", + direction="r", }, - [0x120C8]={ + [0x10C3A]={ category="lo", - direction="l", + direction="r", }, - [0x120C9]={ + [0x10C3B]={ category="lo", - direction="l", + direction="r", }, - [0x120CA]={ + [0x10C3C]={ category="lo", - direction="l", + direction="r", }, - [0x120CB]={ + [0x10C3D]={ category="lo", - direction="l", + direction="r", }, - [0x120CC]={ + [0x10C3E]={ category="lo", - direction="l", + direction="r", }, - [0x120CD]={ + [0x10C3F]={ category="lo", - direction="l", + direction="r", }, - [0x120CE]={ + [0x10C40]={ category="lo", - direction="l", + direction="r", }, - [0x120CF]={ + [0x10C41]={ category="lo", - direction="l", + direction="r", }, - [0x120D0]={ + [0x10C42]={ category="lo", - direction="l", + direction="r", }, - [0x120D1]={ + [0x10C43]={ category="lo", - direction="l", + direction="r", }, - [0x120D2]={ + [0x10C44]={ category="lo", - direction="l", + direction="r", }, - [0x120D3]={ + [0x10C45]={ category="lo", - direction="l", + direction="r", }, - [0x120D4]={ + [0x10C46]={ category="lo", - direction="l", + direction="r", }, - [0x120D5]={ + [0x10C47]={ category="lo", - direction="l", + direction="r", }, - [0x120D6]={ + [0x10C48]={ category="lo", - direction="l", + direction="r", }, - [0x120D7]={ - category="lo", - direction="l", + [0x10E60]={ + category="no", + direction="an", }, - [0x120D8]={ - category="lo", - direction="l", + [0x10E61]={ + category="no", + direction="an", }, - [0x120D9]={ - category="lo", - direction="l", + [0x10E62]={ + category="no", + direction="an", }, - [0x120DA]={ - category="lo", - direction="l", + [0x10E63]={ + category="no", + direction="an", }, - [0x120DB]={ - category="lo", - direction="l", + [0x10E64]={ + category="no", + direction="an", }, - [0x120DC]={ - category="lo", - direction="l", + [0x10E65]={ + category="no", + direction="an", }, - [0x120DD]={ - category="lo", - direction="l", + [0x10E66]={ + category="no", + direction="an", }, - [0x120DE]={ - category="lo", - direction="l", + [0x10E67]={ + category="no", + direction="an", }, - [0x120DF]={ - category="lo", - direction="l", + [0x10E68]={ + category="no", + direction="an", }, - [0x120E0]={ - category="lo", - direction="l", + [0x10E69]={ + category="no", + direction="an", }, - [0x120E1]={ - category="lo", - direction="l", + [0x10E6A]={ + category="no", + direction="an", }, - [0x120E2]={ - category="lo", - direction="l", + [0x10E6B]={ + category="no", + direction="an", }, - [0x120E3]={ - category="lo", - direction="l", + [0x10E6C]={ + category="no", + direction="an", }, - [0x120E4]={ - category="lo", - direction="l", + [0x10E6D]={ + category="no", + direction="an", }, - [0x120E5]={ - category="lo", - direction="l", + [0x10E6E]={ + category="no", + direction="an", }, - [0x120E6]={ - category="lo", - direction="l", + [0x10E6F]={ + category="no", + direction="an", }, - [0x120E7]={ - category="lo", - direction="l", + [0x10E70]={ + category="no", + direction="an", }, - [0x120E8]={ - category="lo", - direction="l", + [0x10E71]={ + category="no", + direction="an", }, - [0x120E9]={ - category="lo", - direction="l", + [0x10E72]={ + category="no", + direction="an", }, - [0x120EA]={ - category="lo", - direction="l", + [0x10E73]={ + category="no", + direction="an", }, - [0x120EB]={ - category="lo", - direction="l", + [0x10E74]={ + category="no", + direction="an", }, - [0x120EC]={ - category="lo", - direction="l", + [0x10E75]={ + category="no", + direction="an", }, - [0x120ED]={ - category="lo", - direction="l", + [0x10E76]={ + category="no", + direction="an", }, - [0x120EE]={ - category="lo", - direction="l", + [0x10E77]={ + category="no", + direction="an", }, - [0x120EF]={ - category="lo", - direction="l", + [0x10E78]={ + category="no", + direction="an", }, - [0x120F0]={ - category="lo", - direction="l", + [0x10E79]={ + category="no", + direction="an", }, - [0x120F1]={ - category="lo", - direction="l", + [0x10E7A]={ + category="no", + direction="an", }, - [0x120F2]={ - category="lo", - direction="l", + [0x10E7B]={ + category="no", + direction="an", }, - [0x120F3]={ - category="lo", - direction="l", + [0x10E7C]={ + category="no", + direction="an", }, - [0x120F4]={ - category="lo", - direction="l", + [0x10E7D]={ + category="no", + direction="an", }, - [0x120F5]={ - category="lo", - direction="l", + [0x10E7E]={ + category="no", + direction="an", }, - [0x120F6]={ - category="lo", + [0x11000]={ + category="mc", direction="l", }, - [0x120F7]={ - category="lo", - direction="l", + [0x11001]={ + category="mn", + direction="nsm", }, - [0x120F8]={ - category="lo", + [0x11002]={ + category="mc", direction="l", }, - [0x120F9]={ + [0x11003]={ category="lo", direction="l", }, - [0x120FA]={ + [0x11004]={ category="lo", direction="l", }, - [0x120FB]={ + [0x11005]={ category="lo", direction="l", }, - [0x120FC]={ + [0x11006]={ category="lo", direction="l", }, - [0x120FD]={ + [0x11007]={ category="lo", direction="l", }, - [0x120FE]={ + [0x11008]={ category="lo", direction="l", }, - [0x120FF]={ + [0x11009]={ category="lo", direction="l", }, - [0x12100]={ + [0x1100A]={ category="lo", direction="l", }, - [0x12101]={ + [0x1100B]={ category="lo", direction="l", }, - [0x12102]={ + [0x1100C]={ category="lo", direction="l", }, - [0x12103]={ + [0x1100D]={ category="lo", direction="l", }, - [0x12104]={ + [0x1100E]={ category="lo", direction="l", }, - [0x12105]={ + [0x1100F]={ category="lo", direction="l", }, - [0x12106]={ + [0x11010]={ category="lo", direction="l", }, - [0x12107]={ + [0x11011]={ category="lo", direction="l", }, - [0x12108]={ + [0x11012]={ category="lo", direction="l", }, - [0x12109]={ + [0x11013]={ category="lo", direction="l", }, - [0x1210A]={ + [0x11014]={ category="lo", direction="l", }, - [0x1210B]={ + [0x11015]={ category="lo", direction="l", }, - [0x1210C]={ + [0x11016]={ category="lo", direction="l", }, - [0x1210D]={ + [0x11017]={ category="lo", direction="l", }, - [0x1210E]={ + [0x11018]={ category="lo", direction="l", }, - [0x1210F]={ + [0x11019]={ category="lo", direction="l", }, - [0x12110]={ + [0x1101A]={ category="lo", direction="l", }, - [0x12111]={ + [0x1101B]={ category="lo", direction="l", }, - [0x12112]={ + [0x1101C]={ category="lo", direction="l", }, - [0x12113]={ + [0x1101D]={ category="lo", direction="l", }, - [0x12114]={ + [0x1101E]={ category="lo", direction="l", }, - [0x12115]={ + [0x1101F]={ category="lo", direction="l", }, - [0x12116]={ + [0x11020]={ category="lo", direction="l", }, - [0x12117]={ + [0x11021]={ category="lo", direction="l", }, - [0x12118]={ + [0x11022]={ category="lo", direction="l", }, - [0x12119]={ + [0x11023]={ category="lo", direction="l", }, - [0x1211A]={ + [0x11024]={ category="lo", direction="l", }, - [0x1211B]={ + [0x11025]={ category="lo", direction="l", }, - [0x1211C]={ + [0x11026]={ category="lo", direction="l", }, - [0x1211D]={ + [0x11027]={ category="lo", direction="l", }, - [0x1211E]={ + [0x11028]={ category="lo", direction="l", }, - [0x1211F]={ + [0x11029]={ category="lo", direction="l", }, - [0x12120]={ + [0x1102A]={ category="lo", direction="l", }, - [0x12121]={ + [0x1102B]={ category="lo", direction="l", }, - [0x12122]={ + [0x1102C]={ category="lo", direction="l", }, - [0x12123]={ + [0x1102D]={ category="lo", direction="l", }, - [0x12124]={ + [0x1102E]={ category="lo", direction="l", }, - [0x12125]={ + [0x1102F]={ category="lo", direction="l", }, - [0x12126]={ + [0x11030]={ category="lo", direction="l", }, - [0x12127]={ + [0x11031]={ category="lo", direction="l", }, - [0x12128]={ + [0x11032]={ category="lo", direction="l", }, - [0x12129]={ + [0x11033]={ category="lo", direction="l", }, - [0x1212A]={ + [0x11034]={ category="lo", direction="l", }, - [0x1212B]={ + [0x11035]={ category="lo", direction="l", }, - [0x1212C]={ + [0x11036]={ category="lo", direction="l", }, - [0x1212D]={ + [0x11037]={ category="lo", direction="l", }, - [0x1212E]={ - category="lo", - direction="l", + [0x11038]={ + category="mn", + direction="nsm", }, - [0x1212F]={ - category="lo", - direction="l", + [0x11039]={ + category="mn", + direction="nsm", }, - [0x12130]={ - category="lo", - direction="l", + [0x1103A]={ + category="mn", + direction="nsm", }, - [0x12131]={ - category="lo", - direction="l", + [0x1103B]={ + category="mn", + direction="nsm", }, - [0x12132]={ - category="lo", - direction="l", + [0x1103C]={ + category="mn", + direction="nsm", }, - [0x12133]={ - category="lo", - direction="l", + [0x1103D]={ + category="mn", + direction="nsm", }, - [0x12134]={ - category="lo", - direction="l", + [0x1103E]={ + category="mn", + direction="nsm", }, - [0x12135]={ - category="lo", - direction="l", + [0x1103F]={ + category="mn", + direction="nsm", }, - [0x12136]={ - category="lo", - direction="l", + [0x11040]={ + category="mn", + direction="nsm", }, - [0x12137]={ - category="lo", - direction="l", + [0x11041]={ + category="mn", + direction="nsm", }, - [0x12138]={ - category="lo", - direction="l", + [0x11042]={ + category="mn", + direction="nsm", }, - [0x12139]={ - category="lo", - direction="l", + [0x11043]={ + category="mn", + direction="nsm", }, - [0x1213A]={ - category="lo", - direction="l", + [0x11044]={ + category="mn", + direction="nsm", }, - [0x1213B]={ - category="lo", - direction="l", + [0x11045]={ + category="mn", + direction="nsm", }, - [0x1213C]={ - category="lo", - direction="l", + [0x11046]={ + category="mn", + direction="nsm", }, - [0x1213D]={ - category="lo", + [0x11047]={ + category="po", direction="l", }, - [0x1213E]={ - category="lo", + [0x11048]={ + category="po", direction="l", }, - [0x1213F]={ - category="lo", + [0x11049]={ + category="po", direction="l", }, - [0x12140]={ - category="lo", + [0x1104A]={ + category="po", direction="l", }, - [0x12141]={ - category="lo", + [0x1104B]={ + category="po", direction="l", }, - [0x12142]={ - category="lo", + [0x1104C]={ + category="po", direction="l", }, - [0x12143]={ - category="lo", + [0x1104D]={ + category="po", direction="l", }, - [0x12144]={ - category="lo", - direction="l", + [0x11052]={ + category="no", + direction="on", }, - [0x12145]={ - category="lo", - direction="l", + [0x11053]={ + category="no", + direction="on", }, - [0x12146]={ - category="lo", - direction="l", + [0x11054]={ + category="no", + direction="on", }, - [0x12147]={ - category="lo", - direction="l", + [0x11055]={ + category="no", + direction="on", }, - [0x12148]={ - category="lo", - direction="l", + [0x11056]={ + category="no", + direction="on", }, - [0x12149]={ - category="lo", - direction="l", + [0x11057]={ + category="no", + direction="on", }, - [0x1214A]={ - category="lo", - direction="l", + [0x11058]={ + category="no", + direction="on", }, - [0x1214B]={ - category="lo", - direction="l", + [0x11059]={ + category="no", + direction="on", }, - [0x1214C]={ - category="lo", - direction="l", + [0x1105A]={ + category="no", + direction="on", }, - [0x1214D]={ - category="lo", - direction="l", + [0x1105B]={ + category="no", + direction="on", }, - [0x1214E]={ - category="lo", - direction="l", + [0x1105C]={ + category="no", + direction="on", }, - [0x1214F]={ - category="lo", - direction="l", + [0x1105D]={ + category="no", + direction="on", }, - [0x12150]={ - category="lo", - direction="l", + [0x1105E]={ + category="no", + direction="on", }, - [0x12151]={ - category="lo", - direction="l", + [0x1105F]={ + category="no", + direction="on", }, - [0x12152]={ - category="lo", - direction="l", + [0x11060]={ + category="no", + direction="on", }, - [0x12153]={ - category="lo", - direction="l", + [0x11061]={ + category="no", + direction="on", }, - [0x12154]={ - category="lo", - direction="l", + [0x11062]={ + category="no", + direction="on", }, - [0x12155]={ - category="lo", - direction="l", + [0x11063]={ + category="no", + direction="on", }, - [0x12156]={ - category="lo", - direction="l", + [0x11064]={ + category="no", + direction="on", }, - [0x12157]={ - category="lo", - direction="l", + [0x11065]={ + category="no", + direction="on", }, - [0x12158]={ - category="lo", + [0x11066]={ + category="nd", direction="l", }, - [0x12159]={ - category="lo", + [0x11067]={ + category="nd", direction="l", }, - [0x1215A]={ - category="lo", + [0x11068]={ + category="nd", direction="l", }, - [0x1215B]={ - category="lo", + [0x11069]={ + category="nd", direction="l", }, - [0x1215C]={ - category="lo", + [0x1106A]={ + category="nd", direction="l", }, - [0x1215D]={ - category="lo", + [0x1106B]={ + category="nd", direction="l", }, - [0x1215E]={ - category="lo", + [0x1106C]={ + category="nd", direction="l", }, - [0x1215F]={ - category="lo", + [0x1106D]={ + category="nd", direction="l", }, - [0x12160]={ - category="lo", + [0x1106E]={ + category="nd", direction="l", }, - [0x12161]={ - category="lo", + [0x1106F]={ + category="nd", direction="l", }, - [0x12162]={ - category="lo", - direction="l", + [0x1107F]={ + category="mn", + direction="nsm", }, - [0x12163]={ - category="lo", - direction="l", + [0x11080]={ + category="mn", + direction="nsm", }, - [0x12164]={ - category="lo", - direction="l", + [0x11081]={ + category="mn", + direction="nsm", }, - [0x12165]={ - category="lo", + [0x11082]={ + category="mc", direction="l", }, - [0x12166]={ + [0x11083]={ category="lo", direction="l", }, - [0x12167]={ + [0x11084]={ category="lo", direction="l", }, - [0x12168]={ + [0x11085]={ category="lo", direction="l", }, - [0x12169]={ + [0x11086]={ category="lo", direction="l", }, - [0x1216A]={ + [0x11087]={ category="lo", direction="l", }, - [0x1216B]={ + [0x11088]={ category="lo", direction="l", }, - [0x1216C]={ + [0x11089]={ category="lo", direction="l", }, - [0x1216D]={ + [0x1108A]={ category="lo", direction="l", }, - [0x1216E]={ + [0x1108B]={ category="lo", direction="l", }, - [0x1216F]={ + [0x1108C]={ category="lo", direction="l", }, - [0x12170]={ + [0x1108D]={ category="lo", direction="l", }, - [0x12171]={ + [0x1108E]={ category="lo", direction="l", }, - [0x12172]={ + [0x1108F]={ category="lo", direction="l", }, - [0x12173]={ + [0x11090]={ category="lo", direction="l", }, - [0x12174]={ + [0x11091]={ category="lo", direction="l", }, - [0x12175]={ + [0x11092]={ category="lo", direction="l", }, - [0x12176]={ + [0x11093]={ category="lo", direction="l", }, - [0x12177]={ + [0x11094]={ category="lo", direction="l", }, - [0x12178]={ + [0x11095]={ category="lo", direction="l", }, - [0x12179]={ + [0x11096]={ category="lo", direction="l", }, - [0x1217A]={ + [0x11097]={ category="lo", direction="l", }, - [0x1217B]={ + [0x11098]={ category="lo", direction="l", }, - [0x1217C]={ + [0x11099]={ category="lo", direction="l", }, - [0x1217D]={ + [0x1109A]={ category="lo", direction="l", }, - [0x1217E]={ + [0x1109B]={ category="lo", direction="l", }, - [0x1217F]={ + [0x1109C]={ category="lo", direction="l", }, - [0x12180]={ + [0x1109D]={ category="lo", direction="l", }, - [0x12181]={ + [0x1109E]={ category="lo", direction="l", }, - [0x12182]={ + [0x1109F]={ category="lo", direction="l", }, - [0x12183]={ + [0x110A0]={ category="lo", direction="l", }, - [0x12184]={ + [0x110A1]={ category="lo", direction="l", }, - [0x12185]={ + [0x110A2]={ category="lo", direction="l", }, - [0x12186]={ + [0x110A3]={ category="lo", direction="l", }, - [0x12187]={ + [0x110A4]={ category="lo", direction="l", }, - [0x12188]={ + [0x110A5]={ category="lo", direction="l", }, - [0x12189]={ + [0x110A6]={ category="lo", direction="l", }, - [0x1218A]={ + [0x110A7]={ category="lo", direction="l", }, - [0x1218B]={ + [0x110A8]={ category="lo", direction="l", }, - [0x1218C]={ + [0x110A9]={ category="lo", direction="l", }, - [0x1218D]={ + [0x110AA]={ category="lo", direction="l", }, - [0x1218E]={ + [0x110AB]={ category="lo", direction="l", }, - [0x1218F]={ + [0x110AC]={ category="lo", direction="l", }, - [0x12190]={ + [0x110AD]={ category="lo", direction="l", }, - [0x12191]={ + [0x110AE]={ category="lo", direction="l", }, - [0x12192]={ + [0x110AF]={ category="lo", direction="l", }, - [0x12193]={ - category="lo", + [0x110B0]={ + category="mc", direction="l", }, - [0x12194]={ - category="lo", + [0x110B1]={ + category="mc", direction="l", }, - [0x12195]={ - category="lo", + [0x110B2]={ + category="mc", direction="l", }, - [0x12196]={ - category="lo", - direction="l", + [0x110B3]={ + category="mn", + direction="nsm", }, - [0x12197]={ - category="lo", - direction="l", + [0x110B4]={ + category="mn", + direction="nsm", }, - [0x12198]={ - category="lo", - direction="l", + [0x110B5]={ + category="mn", + direction="nsm", }, - [0x12199]={ - category="lo", - direction="l", + [0x110B6]={ + category="mn", + direction="nsm", }, - [0x1219A]={ - category="lo", + [0x110B7]={ + category="mc", direction="l", }, - [0x1219B]={ - category="lo", + [0x110B8]={ + category="mc", direction="l", }, - [0x1219C]={ - category="lo", - direction="l", + [0x110B9]={ + category="mn", + direction="nsm", }, - [0x1219D]={ - category="lo", - direction="l", + [0x110BA]={ + category="mn", + direction="nsm", }, - [0x1219E]={ - category="lo", + [0x110BB]={ + category="po", direction="l", }, - [0x1219F]={ - category="lo", + [0x110BC]={ + category="po", direction="l", }, - [0x121A0]={ - category="lo", + [0x110BD]={ + category="cf", direction="l", }, - [0x121A1]={ - category="lo", + [0x110BE]={ + category="po", direction="l", }, - [0x121A2]={ - category="lo", + [0x110BF]={ + category="po", direction="l", }, - [0x121A3]={ - category="lo", + [0x110C0]={ + category="po", direction="l", }, - [0x121A4]={ - category="lo", + [0x110C1]={ + category="po", direction="l", }, - [0x121A5]={ + [0x110D0]={ category="lo", direction="l", }, - [0x121A6]={ + [0x110D1]={ category="lo", direction="l", }, - [0x121A7]={ + [0x110D2]={ category="lo", direction="l", }, - [0x121A8]={ + [0x110D3]={ category="lo", direction="l", }, - [0x121A9]={ + [0x110D4]={ category="lo", direction="l", }, - [0x121AA]={ + [0x110D5]={ category="lo", direction="l", }, - [0x121AB]={ + [0x110D6]={ category="lo", direction="l", }, - [0x121AC]={ + [0x110D7]={ category="lo", direction="l", }, - [0x121AD]={ + [0x110D8]={ category="lo", direction="l", }, - [0x121AE]={ + [0x110D9]={ category="lo", direction="l", }, - [0x121AF]={ + [0x110DA]={ category="lo", direction="l", }, - [0x121B0]={ + [0x110DB]={ category="lo", direction="l", }, - [0x121B1]={ + [0x110DC]={ category="lo", direction="l", }, - [0x121B2]={ + [0x110DD]={ category="lo", direction="l", }, - [0x121B3]={ + [0x110DE]={ category="lo", direction="l", }, - [0x121B4]={ + [0x110DF]={ category="lo", direction="l", }, - [0x121B5]={ + [0x110E0]={ category="lo", direction="l", }, - [0x121B6]={ + [0x110E1]={ category="lo", direction="l", }, - [0x121B7]={ + [0x110E2]={ category="lo", direction="l", }, - [0x121B8]={ + [0x110E3]={ category="lo", direction="l", }, - [0x121B9]={ + [0x110E4]={ category="lo", direction="l", }, - [0x121BA]={ + [0x110E5]={ category="lo", direction="l", }, - [0x121BB]={ + [0x110E6]={ category="lo", direction="l", }, - [0x121BC]={ + [0x110E7]={ category="lo", direction="l", }, - [0x121BD]={ + [0x110E8]={ category="lo", direction="l", }, - [0x121BE]={ - category="lo", + [0x110F0]={ + category="nd", direction="l", }, - [0x121BF]={ - category="lo", + [0x110F1]={ + category="nd", direction="l", }, - [0x121C0]={ - category="lo", + [0x110F2]={ + category="nd", direction="l", }, - [0x121C1]={ - category="lo", + [0x110F3]={ + category="nd", direction="l", }, - [0x121C2]={ - category="lo", + [0x110F4]={ + category="nd", direction="l", }, - [0x121C3]={ - category="lo", + [0x110F5]={ + category="nd", direction="l", }, - [0x121C4]={ - category="lo", + [0x110F6]={ + category="nd", direction="l", }, - [0x121C5]={ - category="lo", + [0x110F7]={ + category="nd", direction="l", }, - [0x121C6]={ - category="lo", + [0x110F8]={ + category="nd", direction="l", }, - [0x121C7]={ - category="lo", + [0x110F9]={ + category="nd", direction="l", }, - [0x121C8]={ - category="lo", - direction="l", + [0x11100]={ + category="mn", + direction="nsm", }, - [0x121C9]={ - category="lo", - direction="l", + [0x11101]={ + category="mn", + direction="nsm", }, - [0x121CA]={ - category="lo", - direction="l", + [0x11102]={ + category="mn", + direction="nsm", }, - [0x121CB]={ + [0x11103]={ category="lo", direction="l", }, - [0x121CC]={ + [0x11104]={ category="lo", direction="l", }, - [0x121CD]={ + [0x11105]={ category="lo", direction="l", }, - [0x121CE]={ + [0x11106]={ category="lo", direction="l", }, - [0x121CF]={ + [0x11107]={ category="lo", direction="l", }, - [0x121D0]={ + [0x11108]={ category="lo", direction="l", }, - [0x121D1]={ + [0x11109]={ category="lo", direction="l", }, - [0x121D2]={ + [0x1110A]={ category="lo", direction="l", }, - [0x121D3]={ + [0x1110B]={ category="lo", direction="l", }, - [0x121D4]={ + [0x1110C]={ category="lo", direction="l", }, - [0x121D5]={ + [0x1110D]={ category="lo", direction="l", }, - [0x121D6]={ + [0x1110E]={ category="lo", direction="l", }, - [0x121D7]={ + [0x1110F]={ category="lo", direction="l", }, - [0x121D8]={ + [0x11110]={ category="lo", direction="l", }, - [0x121D9]={ + [0x11111]={ category="lo", direction="l", }, - [0x121DA]={ + [0x11112]={ category="lo", direction="l", }, - [0x121DB]={ + [0x11113]={ category="lo", direction="l", }, - [0x121DC]={ + [0x11114]={ category="lo", direction="l", }, - [0x121DD]={ + [0x11115]={ category="lo", direction="l", }, - [0x121DE]={ + [0x11116]={ category="lo", direction="l", }, - [0x121DF]={ + [0x11117]={ category="lo", direction="l", }, - [0x121E0]={ + [0x11118]={ category="lo", direction="l", }, - [0x121E1]={ + [0x11119]={ category="lo", direction="l", }, - [0x121E2]={ + [0x1111A]={ category="lo", direction="l", }, - [0x121E3]={ + [0x1111B]={ category="lo", direction="l", }, - [0x121E4]={ + [0x1111C]={ category="lo", direction="l", }, - [0x121E5]={ + [0x1111D]={ category="lo", direction="l", }, - [0x121E6]={ + [0x1111E]={ category="lo", direction="l", }, - [0x121E7]={ + [0x1111F]={ category="lo", direction="l", }, - [0x121E8]={ + [0x11120]={ category="lo", direction="l", }, - [0x121E9]={ + [0x11121]={ category="lo", direction="l", }, - [0x121EA]={ + [0x11122]={ category="lo", direction="l", }, - [0x121EB]={ + [0x11123]={ category="lo", direction="l", }, - [0x121EC]={ + [0x11124]={ category="lo", direction="l", }, - [0x121ED]={ + [0x11125]={ category="lo", direction="l", }, - [0x121EE]={ + [0x11126]={ category="lo", direction="l", }, - [0x121EF]={ - category="lo", - direction="l", + [0x11127]={ + category="mn", + direction="nsm", }, - [0x121F0]={ - category="lo", - direction="l", + [0x11128]={ + category="mn", + direction="nsm", }, - [0x121F1]={ - category="lo", - direction="l", + [0x11129]={ + category="mn", + direction="nsm", }, - [0x121F2]={ - category="lo", - direction="l", + [0x1112A]={ + category="mn", + direction="nsm", }, - [0x121F3]={ - category="lo", - direction="l", + [0x1112B]={ + category="mn", + direction="nsm", }, - [0x121F4]={ - category="lo", + [0x1112C]={ + category="mc", direction="l", }, - [0x121F5]={ - category="lo", - direction="l", + [0x1112D]={ + category="mn", + direction="nsm", }, - [0x121F6]={ - category="lo", - direction="l", + [0x1112E]={ + category="mn", + direction="nsm", }, - [0x121F7]={ - category="lo", + [0x1112F]={ + category="mn", + direction="nsm", + }, + [0x11130]={ + category="mn", + direction="nsm", + }, + [0x11131]={ + category="mn", + direction="nsm", + }, + [0x11132]={ + category="mn", + direction="nsm", + }, + [0x11133]={ + category="mn", + direction="nsm", + }, + [0x11134]={ + category="mn", + direction="nsm", + }, + [0x11136]={ + category="nd", direction="l", }, - [0x121F8]={ - category="lo", + [0x11137]={ + category="nd", direction="l", }, - [0x121F9]={ - category="lo", + [0x11138]={ + category="nd", direction="l", }, - [0x121FA]={ - category="lo", + [0x11139]={ + category="nd", direction="l", }, - [0x121FB]={ - category="lo", + [0x1113A]={ + category="nd", direction="l", }, - [0x121FC]={ - category="lo", + [0x1113B]={ + category="nd", direction="l", }, - [0x121FD]={ - category="lo", + [0x1113C]={ + category="nd", direction="l", }, - [0x121FE]={ - category="lo", + [0x1113D]={ + category="nd", direction="l", }, - [0x121FF]={ - category="lo", + [0x1113E]={ + category="nd", direction="l", }, - [0x12200]={ - category="lo", + [0x1113F]={ + category="nd", direction="l", }, - [0x12201]={ - category="lo", + [0x11140]={ + category="po", direction="l", }, - [0x12202]={ - category="lo", + [0x11141]={ + category="po", direction="l", }, - [0x12203]={ - category="lo", + [0x11142]={ + category="po", direction="l", }, - [0x12204]={ - category="lo", + [0x11143]={ + category="po", direction="l", }, - [0x12205]={ + [0x11150]={ category="lo", direction="l", }, - [0x12206]={ + [0x11151]={ category="lo", direction="l", }, - [0x12207]={ + [0x11152]={ category="lo", direction="l", }, - [0x12208]={ + [0x11153]={ category="lo", direction="l", }, - [0x12209]={ + [0x11154]={ category="lo", direction="l", }, - [0x1220A]={ + [0x11155]={ category="lo", direction="l", }, - [0x1220B]={ + [0x11156]={ category="lo", direction="l", }, - [0x1220C]={ + [0x11157]={ category="lo", direction="l", }, - [0x1220D]={ + [0x11158]={ category="lo", direction="l", }, - [0x1220E]={ + [0x11159]={ category="lo", direction="l", }, - [0x1220F]={ + [0x1115A]={ category="lo", direction="l", }, - [0x12210]={ + [0x1115B]={ category="lo", direction="l", }, - [0x12211]={ + [0x1115C]={ category="lo", direction="l", }, - [0x12212]={ + [0x1115D]={ category="lo", direction="l", }, - [0x12213]={ + [0x1115E]={ category="lo", direction="l", }, - [0x12214]={ + [0x1115F]={ category="lo", direction="l", }, - [0x12215]={ + [0x11160]={ category="lo", direction="l", }, - [0x12216]={ + [0x11161]={ category="lo", direction="l", }, - [0x12217]={ + [0x11162]={ category="lo", direction="l", }, - [0x12218]={ + [0x11163]={ category="lo", direction="l", }, - [0x12219]={ + [0x11164]={ category="lo", direction="l", }, - [0x1221A]={ + [0x11165]={ category="lo", direction="l", }, - [0x1221B]={ + [0x11166]={ category="lo", direction="l", }, - [0x1221C]={ + [0x11167]={ category="lo", direction="l", }, - [0x1221D]={ + [0x11168]={ category="lo", direction="l", }, - [0x1221E]={ + [0x11169]={ category="lo", direction="l", }, - [0x1221F]={ + [0x1116A]={ category="lo", direction="l", }, - [0x12220]={ + [0x1116B]={ category="lo", direction="l", }, - [0x12221]={ + [0x1116C]={ category="lo", direction="l", }, - [0x12222]={ + [0x1116D]={ category="lo", direction="l", }, - [0x12223]={ + [0x1116E]={ category="lo", direction="l", }, - [0x12224]={ + [0x1116F]={ category="lo", direction="l", }, - [0x12225]={ + [0x11170]={ category="lo", direction="l", }, - [0x12226]={ + [0x11171]={ category="lo", direction="l", }, - [0x12227]={ + [0x11172]={ category="lo", direction="l", }, - [0x12228]={ - category="lo", + [0x11173]={ + category="mn", + direction="nsm", + }, + [0x11174]={ + category="po", direction="l", }, - [0x12229]={ - category="lo", + [0x11175]={ + category="po", direction="l", }, - [0x1222A]={ + [0x11176]={ category="lo", direction="l", }, - [0x1222B]={ - category="lo", + [0x11180]={ + category="mn", + direction="nsm", + }, + [0x11181]={ + category="mn", + direction="nsm", + }, + [0x11182]={ + category="mc", direction="l", }, - [0x1222C]={ + [0x11183]={ category="lo", direction="l", }, - [0x1222D]={ + [0x11184]={ category="lo", direction="l", }, - [0x1222E]={ + [0x11185]={ category="lo", direction="l", }, - [0x1222F]={ + [0x11186]={ category="lo", direction="l", }, - [0x12230]={ + [0x11187]={ category="lo", direction="l", }, - [0x12231]={ + [0x11188]={ category="lo", direction="l", }, - [0x12232]={ + [0x11189]={ category="lo", direction="l", }, - [0x12233]={ + [0x1118A]={ category="lo", direction="l", }, - [0x12234]={ + [0x1118B]={ category="lo", direction="l", }, - [0x12235]={ + [0x1118C]={ category="lo", direction="l", }, - [0x12236]={ + [0x1118D]={ category="lo", direction="l", }, - [0x12237]={ + [0x1118E]={ category="lo", direction="l", }, - [0x12238]={ + [0x1118F]={ category="lo", direction="l", }, - [0x12239]={ + [0x11190]={ category="lo", direction="l", }, - [0x1223A]={ + [0x11191]={ category="lo", direction="l", }, - [0x1223B]={ + [0x11192]={ category="lo", direction="l", }, - [0x1223C]={ + [0x11193]={ category="lo", direction="l", }, - [0x1223D]={ + [0x11194]={ category="lo", direction="l", }, - [0x1223E]={ + [0x11195]={ category="lo", direction="l", }, - [0x1223F]={ + [0x11196]={ category="lo", direction="l", }, - [0x12240]={ + [0x11197]={ category="lo", direction="l", }, - [0x12241]={ + [0x11198]={ category="lo", direction="l", }, - [0x12242]={ + [0x11199]={ category="lo", direction="l", }, - [0x12243]={ + [0x1119A]={ category="lo", direction="l", }, - [0x12244]={ + [0x1119B]={ category="lo", direction="l", }, - [0x12245]={ + [0x1119C]={ category="lo", direction="l", }, - [0x12246]={ + [0x1119D]={ category="lo", direction="l", }, - [0x12247]={ + [0x1119E]={ category="lo", direction="l", }, - [0x12248]={ + [0x1119F]={ category="lo", direction="l", }, - [0x12249]={ + [0x111A0]={ category="lo", direction="l", }, - [0x1224A]={ + [0x111A1]={ category="lo", direction="l", }, - [0x1224B]={ + [0x111A2]={ category="lo", direction="l", }, - [0x1224C]={ + [0x111A3]={ category="lo", direction="l", }, - [0x1224D]={ + [0x111A4]={ category="lo", direction="l", }, - [0x1224E]={ + [0x111A5]={ category="lo", direction="l", }, - [0x1224F]={ + [0x111A6]={ category="lo", direction="l", }, - [0x12250]={ + [0x111A7]={ category="lo", direction="l", }, - [0x12251]={ + [0x111A8]={ category="lo", direction="l", }, - [0x12252]={ + [0x111A9]={ category="lo", direction="l", }, - [0x12253]={ + [0x111AA]={ category="lo", direction="l", }, - [0x12254]={ + [0x111AB]={ category="lo", direction="l", }, - [0x12255]={ + [0x111AC]={ category="lo", direction="l", }, - [0x12256]={ + [0x111AD]={ category="lo", direction="l", }, - [0x12257]={ + [0x111AE]={ category="lo", direction="l", }, - [0x12258]={ + [0x111AF]={ category="lo", direction="l", }, - [0x12259]={ + [0x111B0]={ category="lo", direction="l", }, - [0x1225A]={ + [0x111B1]={ category="lo", direction="l", }, - [0x1225B]={ + [0x111B2]={ category="lo", direction="l", }, - [0x1225C]={ - category="lo", + [0x111B3]={ + category="mc", direction="l", }, - [0x1225D]={ - category="lo", + [0x111B4]={ + category="mc", direction="l", }, - [0x1225E]={ - category="lo", + [0x111B5]={ + category="mc", direction="l", }, - [0x1225F]={ - category="lo", + [0x111B6]={ + category="mn", + direction="nsm", + }, + [0x111B7]={ + category="mn", + direction="nsm", + }, + [0x111B8]={ + category="mn", + direction="nsm", + }, + [0x111B9]={ + category="mn", + direction="nsm", + }, + [0x111BA]={ + category="mn", + direction="nsm", + }, + [0x111BB]={ + category="mn", + direction="nsm", + }, + [0x111BC]={ + category="mn", + direction="nsm", + }, + [0x111BD]={ + category="mn", + direction="nsm", + }, + [0x111BE]={ + category="mn", + direction="nsm", + }, + [0x111BF]={ + category="mc", direction="l", }, - [0x12260]={ - category="lo", + [0x111C0]={ + category="mc", direction="l", }, - [0x12261]={ + [0x111C1]={ category="lo", direction="l", }, - [0x12262]={ + [0x111C2]={ category="lo", direction="l", }, - [0x12263]={ + [0x111C3]={ category="lo", direction="l", }, - [0x12264]={ + [0x111C4]={ category="lo", direction="l", }, - [0x12265]={ - category="lo", + [0x111C5]={ + category="po", direction="l", }, - [0x12266]={ - category="lo", + [0x111C6]={ + category="po", direction="l", }, - [0x12267]={ - category="lo", + [0x111C7]={ + category="po", direction="l", }, - [0x12268]={ - category="lo", + [0x111C8]={ + category="po", direction="l", }, - [0x12269]={ - category="lo", + [0x111CD]={ + category="po", direction="l", }, - [0x1226A]={ - category="lo", + [0x111D0]={ + category="nd", direction="l", }, - [0x1226B]={ - category="lo", + [0x111D1]={ + category="nd", direction="l", }, - [0x1226C]={ - category="lo", + [0x111D2]={ + category="nd", direction="l", }, - [0x1226D]={ - category="lo", + [0x111D3]={ + category="nd", direction="l", }, - [0x1226E]={ - category="lo", + [0x111D4]={ + category="nd", direction="l", }, - [0x1226F]={ - category="lo", + [0x111D5]={ + category="nd", direction="l", }, - [0x12270]={ - category="lo", + [0x111D6]={ + category="nd", direction="l", }, - [0x12271]={ - category="lo", + [0x111D7]={ + category="nd", direction="l", }, - [0x12272]={ - category="lo", + [0x111D8]={ + category="nd", direction="l", }, - [0x12273]={ - category="lo", + [0x111D9]={ + category="nd", direction="l", }, - [0x12274]={ + [0x111DA]={ category="lo", direction="l", }, - [0x12275]={ - category="lo", + [0x111E1]={ + category="no", direction="l", }, - [0x12276]={ - category="lo", + [0x111E2]={ + category="no", direction="l", }, - [0x12277]={ - category="lo", + [0x111E3]={ + category="no", direction="l", }, - [0x12278]={ - category="lo", + [0x111E4]={ + category="no", direction="l", }, - [0x12279]={ - category="lo", + [0x111E5]={ + category="no", direction="l", }, - [0x1227A]={ - category="lo", + [0x111E6]={ + category="no", direction="l", }, - [0x1227B]={ - category="lo", + [0x111E7]={ + category="no", direction="l", }, - [0x1227C]={ - category="lo", + [0x111E8]={ + category="no", direction="l", }, - [0x1227D]={ - category="lo", + [0x111E9]={ + category="no", direction="l", }, - [0x1227E]={ - category="lo", + [0x111EA]={ + category="no", direction="l", }, - [0x1227F]={ - category="lo", + [0x111EB]={ + category="no", direction="l", }, - [0x12280]={ - category="lo", + [0x111EC]={ + category="no", direction="l", }, - [0x12281]={ - category="lo", + [0x111ED]={ + category="no", direction="l", }, - [0x12282]={ - category="lo", + [0x111EE]={ + category="no", direction="l", }, - [0x12283]={ - category="lo", + [0x111EF]={ + category="no", direction="l", }, - [0x12284]={ - category="lo", + [0x111F0]={ + category="no", direction="l", }, - [0x12285]={ - category="lo", + [0x111F1]={ + category="no", direction="l", }, - [0x12286]={ - category="lo", + [0x111F2]={ + category="no", direction="l", }, - [0x12287]={ - category="lo", + [0x111F3]={ + category="no", direction="l", }, - [0x12288]={ - category="lo", + [0x111F4]={ + category="no", direction="l", }, - [0x12289]={ + [0x11200]={ category="lo", direction="l", }, - [0x1228A]={ + [0x11201]={ category="lo", direction="l", }, - [0x1228B]={ + [0x11202]={ category="lo", direction="l", }, - [0x1228C]={ + [0x11203]={ category="lo", direction="l", }, - [0x1228D]={ + [0x11204]={ category="lo", direction="l", }, - [0x1228E]={ + [0x11205]={ category="lo", direction="l", }, - [0x1228F]={ + [0x11206]={ category="lo", direction="l", }, - [0x12290]={ + [0x11207]={ category="lo", direction="l", }, - [0x12291]={ + [0x11208]={ category="lo", direction="l", }, - [0x12292]={ + [0x11209]={ category="lo", direction="l", }, - [0x12293]={ + [0x1120A]={ category="lo", direction="l", }, - [0x12294]={ + [0x1120B]={ category="lo", direction="l", }, - [0x12295]={ + [0x1120C]={ category="lo", direction="l", }, - [0x12296]={ + [0x1120D]={ category="lo", direction="l", }, - [0x12297]={ + [0x1120E]={ category="lo", direction="l", }, - [0x12298]={ + [0x1120F]={ category="lo", direction="l", }, - [0x12299]={ + [0x11210]={ category="lo", direction="l", }, - [0x1229A]={ + [0x11211]={ category="lo", direction="l", }, - [0x1229B]={ + [0x11213]={ category="lo", direction="l", }, - [0x1229C]={ + [0x11214]={ category="lo", direction="l", }, - [0x1229D]={ + [0x11215]={ category="lo", direction="l", }, - [0x1229E]={ + [0x11216]={ category="lo", direction="l", }, - [0x1229F]={ + [0x11217]={ category="lo", direction="l", }, - [0x122A0]={ + [0x11218]={ category="lo", direction="l", }, - [0x122A1]={ + [0x11219]={ category="lo", direction="l", }, - [0x122A2]={ + [0x1121A]={ category="lo", direction="l", }, - [0x122A3]={ + [0x1121B]={ category="lo", direction="l", }, - [0x122A4]={ + [0x1121C]={ category="lo", direction="l", }, - [0x122A5]={ + [0x1121D]={ category="lo", direction="l", }, - [0x122A6]={ + [0x1121E]={ category="lo", direction="l", }, - [0x122A7]={ + [0x1121F]={ category="lo", direction="l", }, - [0x122A8]={ + [0x11220]={ category="lo", direction="l", }, - [0x122A9]={ + [0x11221]={ category="lo", direction="l", }, - [0x122AA]={ + [0x11222]={ category="lo", direction="l", }, - [0x122AB]={ + [0x11223]={ category="lo", direction="l", }, - [0x122AC]={ + [0x11224]={ category="lo", direction="l", }, - [0x122AD]={ + [0x11225]={ category="lo", direction="l", }, - [0x122AE]={ + [0x11226]={ category="lo", direction="l", }, - [0x122AF]={ + [0x11227]={ category="lo", direction="l", }, - [0x122B0]={ + [0x11228]={ category="lo", direction="l", }, - [0x122B1]={ + [0x11229]={ category="lo", direction="l", }, - [0x122B2]={ + [0x1122A]={ category="lo", direction="l", }, - [0x122B3]={ + [0x1122B]={ category="lo", direction="l", }, - [0x122B4]={ - category="lo", + [0x1122C]={ + category="mc", direction="l", }, - [0x122B5]={ - category="lo", + [0x1122D]={ + category="mc", direction="l", }, - [0x122B6]={ - category="lo", + [0x1122E]={ + category="mc", direction="l", }, - [0x122B7]={ - category="lo", + [0x1122F]={ + category="mn", + direction="nsm", + }, + [0x11230]={ + category="mn", + direction="nsm", + }, + [0x11231]={ + category="mn", + direction="nsm", + }, + [0x11232]={ + category="mc", direction="l", }, - [0x122B8]={ - category="lo", + [0x11233]={ + category="mc", direction="l", }, - [0x122B9]={ - category="lo", + [0x11234]={ + category="mn", + direction="nsm", + }, + [0x11235]={ + category="mc", direction="l", }, - [0x122BA]={ - category="lo", + [0x11236]={ + category="mn", + direction="nsm", + }, + [0x11237]={ + category="mn", + direction="nsm", + }, + [0x11238]={ + category="po", direction="l", }, - [0x122BB]={ - category="lo", + [0x11239]={ + category="po", direction="l", }, - [0x122BC]={ - category="lo", + [0x1123A]={ + category="po", direction="l", }, - [0x122BD]={ - category="lo", + [0x1123B]={ + category="po", direction="l", }, - [0x122BE]={ - category="lo", + [0x1123C]={ + category="po", direction="l", }, - [0x122BF]={ - category="lo", + [0x1123D]={ + category="po", direction="l", }, - [0x122C0]={ + [0x112B0]={ category="lo", direction="l", }, - [0x122C1]={ + [0x112B1]={ category="lo", direction="l", }, - [0x122C2]={ + [0x112B2]={ category="lo", direction="l", }, - [0x122C3]={ + [0x112B3]={ category="lo", direction="l", }, - [0x122C4]={ + [0x112B4]={ category="lo", direction="l", }, - [0x122C5]={ + [0x112B5]={ category="lo", direction="l", }, - [0x122C6]={ + [0x112B6]={ category="lo", direction="l", }, - [0x122C7]={ + [0x112B7]={ category="lo", direction="l", }, - [0x122C8]={ + [0x112B8]={ category="lo", direction="l", }, - [0x122C9]={ + [0x112B9]={ category="lo", direction="l", }, - [0x122CA]={ + [0x112BA]={ category="lo", direction="l", }, - [0x122CB]={ + [0x112BB]={ category="lo", direction="l", }, - [0x122CC]={ + [0x112BC]={ category="lo", direction="l", }, - [0x122CD]={ + [0x112BD]={ category="lo", direction="l", }, - [0x122CE]={ + [0x112BE]={ category="lo", direction="l", }, - [0x122CF]={ + [0x112BF]={ category="lo", direction="l", }, - [0x122D0]={ + [0x112C0]={ category="lo", direction="l", }, - [0x122D1]={ + [0x112C1]={ category="lo", direction="l", }, - [0x122D2]={ + [0x112C2]={ category="lo", direction="l", }, - [0x122D3]={ + [0x112C3]={ category="lo", direction="l", }, - [0x122D4]={ + [0x112C4]={ category="lo", direction="l", }, - [0x122D5]={ + [0x112C5]={ category="lo", direction="l", }, - [0x122D6]={ + [0x112C6]={ category="lo", direction="l", }, - [0x122D7]={ + [0x112C7]={ category="lo", direction="l", }, - [0x122D8]={ + [0x112C8]={ category="lo", direction="l", }, - [0x122D9]={ + [0x112C9]={ category="lo", direction="l", }, - [0x122DA]={ + [0x112CA]={ category="lo", direction="l", }, - [0x122DB]={ + [0x112CB]={ category="lo", direction="l", }, - [0x122DC]={ + [0x112CC]={ category="lo", direction="l", }, - [0x122DD]={ + [0x112CD]={ category="lo", direction="l", }, - [0x122DE]={ + [0x112CE]={ category="lo", direction="l", }, - [0x122DF]={ + [0x112CF]={ category="lo", direction="l", }, - [0x122E0]={ + [0x112D0]={ category="lo", direction="l", }, - [0x122E1]={ + [0x112D1]={ category="lo", direction="l", }, - [0x122E2]={ + [0x112D2]={ category="lo", direction="l", }, - [0x122E3]={ + [0x112D3]={ category="lo", direction="l", }, - [0x122E4]={ + [0x112D4]={ category="lo", direction="l", }, - [0x122E5]={ + [0x112D5]={ category="lo", direction="l", }, - [0x122E6]={ + [0x112D6]={ category="lo", direction="l", }, - [0x122E7]={ + [0x112D7]={ category="lo", direction="l", }, - [0x122E8]={ + [0x112D8]={ category="lo", direction="l", }, - [0x122E9]={ + [0x112D9]={ category="lo", direction="l", }, - [0x122EA]={ + [0x112DA]={ category="lo", direction="l", }, - [0x122EB]={ + [0x112DB]={ category="lo", direction="l", }, - [0x122EC]={ + [0x112DC]={ category="lo", direction="l", }, - [0x122ED]={ + [0x112DD]={ category="lo", direction="l", }, - [0x122EE]={ + [0x112DE]={ category="lo", direction="l", }, - [0x122EF]={ - category="lo", + [0x112DF]={ + category="mn", + direction="nsm", + }, + [0x112E0]={ + category="mc", direction="l", }, - [0x122F0]={ - category="lo", + [0x112E1]={ + category="mc", direction="l", }, - [0x122F1]={ - category="lo", + [0x112E2]={ + category="mc", direction="l", }, - [0x122F2]={ - category="lo", + [0x112E3]={ + category="mn", + direction="nsm", + }, + [0x112E4]={ + category="mn", + direction="nsm", + }, + [0x112E5]={ + category="mn", + direction="nsm", + }, + [0x112E6]={ + category="mn", + direction="nsm", + }, + [0x112E7]={ + category="mn", + direction="nsm", + }, + [0x112E8]={ + category="mn", + direction="nsm", + }, + [0x112E9]={ + category="mn", + direction="nsm", + }, + [0x112EA]={ + category="mn", + direction="nsm", + }, + [0x112F0]={ + category="nd", direction="l", }, - [0x122F3]={ - category="lo", + [0x112F1]={ + category="nd", direction="l", }, - [0x122F4]={ - category="lo", + [0x112F2]={ + category="nd", direction="l", }, - [0x122F5]={ - category="lo", + [0x112F3]={ + category="nd", direction="l", }, - [0x122F6]={ - category="lo", + [0x112F4]={ + category="nd", direction="l", }, - [0x122F7]={ - category="lo", + [0x112F5]={ + category="nd", direction="l", }, - [0x122F8]={ - category="lo", + [0x112F6]={ + category="nd", direction="l", }, - [0x122F9]={ - category="lo", + [0x112F7]={ + category="nd", direction="l", }, - [0x122FA]={ - category="lo", + [0x112F8]={ + category="nd", direction="l", }, - [0x122FB]={ - category="lo", + [0x112F9]={ + category="nd", direction="l", }, - [0x122FC]={ - category="lo", + [0x11301]={ + category="mn", + direction="nsm", + }, + [0x11302]={ + category="mc", direction="l", }, - [0x122FD]={ - category="lo", + [0x11303]={ + category="mc", direction="l", }, - [0x122FE]={ + [0x11305]={ category="lo", direction="l", }, - [0x122FF]={ + [0x11306]={ category="lo", direction="l", }, - [0x12300]={ + [0x11307]={ category="lo", direction="l", }, - [0x12301]={ + [0x11308]={ category="lo", direction="l", }, - [0x12302]={ + [0x11309]={ category="lo", direction="l", }, - [0x12303]={ + [0x1130A]={ category="lo", direction="l", }, - [0x12304]={ + [0x1130B]={ category="lo", direction="l", }, - [0x12305]={ + [0x1130C]={ category="lo", direction="l", }, - [0x12306]={ + [0x1130F]={ category="lo", direction="l", }, - [0x12307]={ + [0x11310]={ category="lo", direction="l", }, - [0x12308]={ + [0x11313]={ category="lo", direction="l", }, - [0x12309]={ + [0x11314]={ category="lo", direction="l", }, - [0x1230A]={ + [0x11315]={ category="lo", direction="l", }, - [0x1230B]={ + [0x11316]={ category="lo", direction="l", }, - [0x1230C]={ + [0x11317]={ category="lo", direction="l", }, - [0x1230D]={ + [0x11318]={ category="lo", direction="l", }, - [0x1230E]={ + [0x11319]={ category="lo", direction="l", }, - [0x1230F]={ + [0x1131A]={ category="lo", direction="l", }, - [0x12310]={ + [0x1131B]={ category="lo", direction="l", }, - [0x12311]={ + [0x1131C]={ category="lo", direction="l", }, - [0x12312]={ + [0x1131D]={ category="lo", direction="l", }, - [0x12313]={ + [0x1131E]={ category="lo", direction="l", }, - [0x12314]={ + [0x1131F]={ category="lo", direction="l", }, - [0x12315]={ + [0x11320]={ category="lo", direction="l", }, - [0x12316]={ + [0x11321]={ category="lo", direction="l", }, - [0x12317]={ + [0x11322]={ category="lo", direction="l", }, - [0x12318]={ + [0x11323]={ category="lo", direction="l", }, - [0x12319]={ + [0x11324]={ category="lo", direction="l", }, - [0x1231A]={ + [0x11325]={ category="lo", direction="l", }, - [0x1231B]={ + [0x11326]={ category="lo", direction="l", }, - [0x1231C]={ + [0x11327]={ category="lo", direction="l", }, - [0x1231D]={ + [0x11328]={ category="lo", direction="l", }, - [0x1231E]={ + [0x1132A]={ category="lo", direction="l", }, - [0x1231F]={ + [0x1132B]={ category="lo", direction="l", }, - [0x12320]={ + [0x1132C]={ category="lo", direction="l", }, - [0x12321]={ + [0x1132D]={ category="lo", direction="l", }, - [0x12322]={ + [0x1132E]={ category="lo", direction="l", }, - [0x12323]={ + [0x1132F]={ category="lo", direction="l", }, - [0x12324]={ + [0x11330]={ category="lo", direction="l", }, - [0x12325]={ + [0x11332]={ category="lo", direction="l", }, - [0x12326]={ + [0x11333]={ category="lo", direction="l", }, - [0x12327]={ + [0x11335]={ category="lo", direction="l", }, - [0x12328]={ + [0x11336]={ category="lo", direction="l", }, - [0x12329]={ + [0x11337]={ category="lo", direction="l", }, - [0x1232A]={ + [0x11338]={ category="lo", direction="l", }, - [0x1232B]={ + [0x11339]={ category="lo", direction="l", }, - [0x1232C]={ + [0x1133C]={ + category="mn", + direction="nsm", + }, + [0x1133D]={ category="lo", direction="l", }, - [0x1232D]={ - category="lo", + [0x1133E]={ + category="mc", direction="l", }, - [0x1232E]={ - category="lo", + [0x1133F]={ + category="mc", direction="l", }, - [0x1232F]={ - category="lo", + [0x11340]={ + category="mn", + direction="nsm", + }, + [0x11341]={ + category="mc", direction="l", }, - [0x12330]={ - category="lo", + [0x11342]={ + category="mc", direction="l", }, - [0x12331]={ - category="lo", + [0x11343]={ + category="mc", direction="l", }, - [0x12332]={ - category="lo", + [0x11344]={ + category="mc", direction="l", }, - [0x12333]={ - category="lo", + [0x11347]={ + category="mc", direction="l", }, - [0x12334]={ - category="lo", + [0x11348]={ + category="mc", direction="l", }, - [0x12335]={ - category="lo", + [0x1134B]={ + category="mc", direction="l", }, - [0x12336]={ - category="lo", + [0x1134C]={ + category="mc", direction="l", }, - [0x12337]={ - category="lo", + [0x1134D]={ + category="mc", direction="l", }, - [0x12338]={ - category="lo", + [0x11357]={ + category="mc", direction="l", }, - [0x12339]={ + [0x1135D]={ category="lo", direction="l", }, - [0x1233A]={ + [0x1135E]={ category="lo", direction="l", }, - [0x1233B]={ + [0x1135F]={ category="lo", direction="l", }, - [0x1233C]={ + [0x11360]={ category="lo", direction="l", }, - [0x1233D]={ + [0x11361]={ category="lo", direction="l", }, - [0x1233E]={ - category="lo", + [0x11362]={ + category="mc", direction="l", }, - [0x1233F]={ - category="lo", + [0x11363]={ + category="mc", direction="l", }, - [0x12340]={ + [0x11366]={ + category="mn", + direction="nsm", + }, + [0x11367]={ + category="mn", + direction="nsm", + }, + [0x11368]={ + category="mn", + direction="nsm", + }, + [0x11369]={ + category="mn", + direction="nsm", + }, + [0x1136A]={ + category="mn", + direction="nsm", + }, + [0x1136B]={ + category="mn", + direction="nsm", + }, + [0x1136C]={ + category="mn", + direction="nsm", + }, + [0x11370]={ + category="mn", + direction="nsm", + }, + [0x11371]={ + category="mn", + direction="nsm", + }, + [0x11372]={ + category="mn", + direction="nsm", + }, + [0x11373]={ + category="mn", + direction="nsm", + }, + [0x11374]={ + category="mn", + direction="nsm", + }, + [0x11480]={ category="lo", direction="l", }, - [0x12341]={ + [0x11481]={ category="lo", direction="l", }, - [0x12342]={ + [0x11482]={ category="lo", direction="l", }, - [0x12343]={ + [0x11483]={ category="lo", direction="l", }, - [0x12344]={ + [0x11484]={ category="lo", direction="l", }, - [0x12345]={ + [0x11485]={ category="lo", direction="l", }, - [0x12346]={ + [0x11486]={ category="lo", direction="l", }, - [0x12347]={ + [0x11487]={ category="lo", direction="l", }, - [0x12348]={ + [0x11488]={ category="lo", direction="l", }, - [0x12349]={ + [0x11489]={ category="lo", direction="l", }, - [0x1234A]={ + [0x1148A]={ category="lo", direction="l", }, - [0x1234B]={ + [0x1148B]={ category="lo", direction="l", }, - [0x1234C]={ + [0x1148C]={ category="lo", direction="l", }, - [0x1234D]={ + [0x1148D]={ category="lo", direction="l", }, - [0x1234E]={ + [0x1148E]={ category="lo", direction="l", }, - [0x1234F]={ + [0x1148F]={ category="lo", direction="l", }, - [0x12350]={ + [0x11490]={ category="lo", direction="l", }, - [0x12351]={ + [0x11491]={ category="lo", direction="l", }, - [0x12352]={ + [0x11492]={ category="lo", direction="l", }, - [0x12353]={ + [0x11493]={ category="lo", direction="l", }, - [0x12354]={ + [0x11494]={ category="lo", direction="l", }, - [0x12355]={ + [0x11495]={ category="lo", direction="l", }, - [0x12356]={ + [0x11496]={ category="lo", direction="l", }, - [0x12357]={ + [0x11497]={ category="lo", direction="l", }, - [0x12358]={ + [0x11498]={ category="lo", direction="l", }, - [0x12359]={ + [0x11499]={ category="lo", direction="l", }, - [0x1235A]={ + [0x1149A]={ category="lo", direction="l", }, - [0x1235B]={ + [0x1149B]={ category="lo", direction="l", }, - [0x1235C]={ + [0x1149C]={ category="lo", direction="l", }, - [0x1235D]={ + [0x1149D]={ category="lo", direction="l", }, - [0x1235E]={ + [0x1149E]={ category="lo", direction="l", }, - [0x1235F]={ + [0x1149F]={ category="lo", direction="l", }, - [0x12360]={ + [0x114A0]={ category="lo", direction="l", }, - [0x12361]={ + [0x114A1]={ category="lo", direction="l", }, - [0x12362]={ + [0x114A2]={ category="lo", direction="l", }, - [0x12363]={ + [0x114A3]={ category="lo", direction="l", }, - [0x12364]={ + [0x114A4]={ category="lo", direction="l", }, - [0x12365]={ + [0x114A5]={ category="lo", direction="l", }, - [0x12366]={ + [0x114A6]={ category="lo", direction="l", }, - [0x12367]={ + [0x114A7]={ category="lo", direction="l", }, - [0x12368]={ + [0x114A8]={ category="lo", direction="l", }, - [0x12369]={ + [0x114A9]={ category="lo", direction="l", }, - [0x1236A]={ + [0x114AA]={ category="lo", direction="l", }, - [0x1236B]={ + [0x114AB]={ category="lo", direction="l", }, - [0x1236C]={ + [0x114AC]={ category="lo", direction="l", }, - [0x1236D]={ + [0x114AD]={ category="lo", direction="l", }, - [0x1236E]={ + [0x114AE]={ category="lo", direction="l", }, - [0x12400]={ - category="nl", + [0x114AF]={ + category="lo", direction="l", }, - [0x12401]={ - category="nl", + [0x114B0]={ + category="mc", direction="l", }, - [0x12402]={ - category="nl", + [0x114B1]={ + category="mc", direction="l", }, - [0x12403]={ - category="nl", + [0x114B2]={ + category="mc", direction="l", }, - [0x12404]={ - category="nl", + [0x114B3]={ + category="mn", + direction="nsm", + }, + [0x114B4]={ + category="mn", + direction="nsm", + }, + [0x114B5]={ + category="mn", + direction="nsm", + }, + [0x114B6]={ + category="mn", + direction="nsm", + }, + [0x114B7]={ + category="mn", + direction="nsm", + }, + [0x114B8]={ + category="mn", + direction="nsm", + }, + [0x114B9]={ + category="mc", direction="l", }, - [0x12405]={ - category="nl", + [0x114BA]={ + category="mn", + direction="nsm", + }, + [0x114BB]={ + category="mc", direction="l", }, - [0x12406]={ - category="nl", + [0x114BC]={ + category="mc", direction="l", }, - [0x12407]={ - category="nl", + [0x114BD]={ + category="mc", direction="l", }, - [0x12408]={ - category="nl", + [0x114BE]={ + category="mc", direction="l", }, - [0x12409]={ - category="nl", + [0x114BF]={ + category="mn", + direction="nsm", + }, + [0x114C0]={ + category="mn", + direction="nsm", + }, + [0x114C1]={ + category="mc", direction="l", }, - [0x1240A]={ - category="nl", + [0x114C2]={ + category="mn", + direction="nsm", + }, + [0x114C3]={ + category="mn", + direction="nsm", + }, + [0x114C4]={ + category="lo", direction="l", }, - [0x1240B]={ - category="nl", + [0x114C5]={ + category="lo", direction="l", }, - [0x1240C]={ - category="nl", + [0x114C6]={ + category="po", direction="l", }, - [0x1240D]={ - category="nl", + [0x114C7]={ + category="lo", direction="l", }, - [0x1240E]={ - category="nl", + [0x114D0]={ + category="nd", direction="l", }, - [0x1240F]={ - category="nl", + [0x114D1]={ + category="nd", direction="l", }, - [0x12410]={ - category="nl", + [0x114D2]={ + category="nd", direction="l", }, - [0x12411]={ - category="nl", + [0x114D3]={ + category="nd", direction="l", }, - [0x12412]={ - category="nl", + [0x114D4]={ + category="nd", direction="l", }, - [0x12413]={ - category="nl", + [0x114D5]={ + category="nd", direction="l", }, - [0x12414]={ - category="nl", + [0x114D6]={ + category="nd", direction="l", }, - [0x12415]={ - category="nl", + [0x114D7]={ + category="nd", direction="l", }, - [0x12416]={ - category="nl", + [0x114D8]={ + category="nd", direction="l", }, - [0x12417]={ - category="nl", + [0x114D9]={ + category="nd", direction="l", }, - [0x12418]={ - category="nl", + [0x11580]={ + category="lo", direction="l", }, - [0x12419]={ - category="nl", + [0x11581]={ + category="lo", direction="l", }, - [0x1241A]={ - category="nl", + [0x11582]={ + category="lo", direction="l", }, - [0x1241B]={ - category="nl", + [0x11583]={ + category="lo", direction="l", }, - [0x1241C]={ - category="nl", + [0x11584]={ + category="lo", direction="l", }, - [0x1241D]={ - category="nl", + [0x11585]={ + category="lo", direction="l", }, - [0x1241E]={ - category="nl", + [0x11586]={ + category="lo", direction="l", }, - [0x1241F]={ - category="nl", + [0x11587]={ + category="lo", direction="l", }, - [0x12420]={ - category="nl", + [0x11588]={ + category="lo", direction="l", }, - [0x12421]={ - category="nl", + [0x11589]={ + category="lo", direction="l", }, - [0x12422]={ - category="nl", + [0x1158A]={ + category="lo", direction="l", }, - [0x12423]={ - category="nl", + [0x1158B]={ + category="lo", direction="l", }, - [0x12424]={ - category="nl", + [0x1158C]={ + category="lo", direction="l", }, - [0x12425]={ - category="nl", + [0x1158D]={ + category="lo", direction="l", }, - [0x12426]={ - category="nl", + [0x1158E]={ + category="lo", direction="l", }, - [0x12427]={ - category="nl", + [0x1158F]={ + category="lo", direction="l", }, - [0x12428]={ - category="nl", + [0x11590]={ + category="lo", direction="l", }, - [0x12429]={ - category="nl", + [0x11591]={ + category="lo", direction="l", }, - [0x1242A]={ - category="nl", + [0x11592]={ + category="lo", direction="l", }, - [0x1242B]={ - category="nl", - direction="l", - }, - [0x1242C]={ - category="nl", - direction="l", - }, - [0x1242D]={ - category="nl", - direction="l", - }, - [0x1242E]={ - category="nl", - direction="l", - }, - [0x1242F]={ - category="nl", - direction="l", - }, - [0x12430]={ - category="nl", - direction="l", - }, - [0x12431]={ - category="nl", - direction="l", - }, - [0x12432]={ - category="nl", + [0x11593]={ + category="lo", direction="l", }, - [0x12433]={ - category="nl", + [0x11594]={ + category="lo", direction="l", }, - [0x12434]={ - category="nl", + [0x11595]={ + category="lo", direction="l", }, - [0x12435]={ - category="nl", + [0x11596]={ + category="lo", direction="l", }, - [0x12436]={ - category="nl", + [0x11597]={ + category="lo", direction="l", }, - [0x12437]={ - category="nl", + [0x11598]={ + category="lo", direction="l", }, - [0x12438]={ - category="nl", + [0x11599]={ + category="lo", direction="l", }, - [0x12439]={ - category="nl", + [0x1159A]={ + category="lo", direction="l", }, - [0x1243A]={ - category="nl", + [0x1159B]={ + category="lo", direction="l", }, - [0x1243B]={ - category="nl", + [0x1159C]={ + category="lo", direction="l", }, - [0x1243C]={ - category="nl", + [0x1159D]={ + category="lo", direction="l", }, - [0x1243D]={ - category="nl", + [0x1159E]={ + category="lo", direction="l", }, - [0x1243E]={ - category="nl", + [0x1159F]={ + category="lo", direction="l", }, - [0x1243F]={ - category="nl", + [0x115A0]={ + category="lo", direction="l", }, - [0x12440]={ - category="nl", + [0x115A1]={ + category="lo", direction="l", }, - [0x12441]={ - category="nl", + [0x115A2]={ + category="lo", direction="l", }, - [0x12442]={ - category="nl", + [0x115A3]={ + category="lo", direction="l", }, - [0x12443]={ - category="nl", + [0x115A4]={ + category="lo", direction="l", }, - [0x12444]={ - category="nl", + [0x115A5]={ + category="lo", direction="l", }, - [0x12445]={ - category="nl", + [0x115A6]={ + category="lo", direction="l", }, - [0x12446]={ - category="nl", + [0x115A7]={ + category="lo", direction="l", }, - [0x12447]={ - category="nl", + [0x115A8]={ + category="lo", direction="l", }, - [0x12448]={ - category="nl", + [0x115A9]={ + category="lo", direction="l", }, - [0x12449]={ - category="nl", + [0x115AA]={ + category="lo", direction="l", }, - [0x1244A]={ - category="nl", + [0x115AB]={ + category="lo", direction="l", }, - [0x1244B]={ - category="nl", + [0x115AC]={ + category="lo", direction="l", }, - [0x1244C]={ - category="nl", + [0x115AD]={ + category="lo", direction="l", }, - [0x1244D]={ - category="nl", + [0x115AE]={ + category="lo", direction="l", }, - [0x1244E]={ - category="nl", + [0x115AF]={ + category="mc", direction="l", }, - [0x1244F]={ - category="nl", + [0x115B0]={ + category="mc", direction="l", }, - [0x12450]={ - category="nl", + [0x115B1]={ + category="mc", direction="l", }, - [0x12451]={ - category="nl", - direction="l", + [0x115B2]={ + category="mn", + direction="nsm", }, - [0x12452]={ - category="nl", - direction="l", + [0x115B3]={ + category="mn", + direction="nsm", }, - [0x12453]={ - category="nl", - direction="l", + [0x115B4]={ + category="mn", + direction="nsm", }, - [0x12454]={ - category="nl", - direction="l", + [0x115B5]={ + category="mn", + direction="nsm", }, - [0x12455]={ - category="nl", + [0x115B8]={ + category="mc", direction="l", }, - [0x12456]={ - category="nl", + [0x115B9]={ + category="mc", direction="l", }, - [0x12457]={ - category="nl", + [0x115BA]={ + category="mc", direction="l", }, - [0x12458]={ - category="nl", + [0x115BB]={ + category="mc", direction="l", }, - [0x12459]={ - category="nl", - direction="l", + [0x115BC]={ + category="mn", + direction="nsm", }, - [0x1245A]={ - category="nl", - direction="l", + [0x115BD]={ + category="mn", + direction="nsm", }, - [0x1245B]={ - category="nl", + [0x115BE]={ + category="mc", direction="l", }, - [0x1245C]={ - category="nl", - direction="l", + [0x115BF]={ + category="mn", + direction="nsm", }, - [0x1245D]={ - category="nl", - direction="l", + [0x115C0]={ + category="mn", + direction="nsm", }, - [0x1245E]={ - category="nl", + [0x115C1]={ + category="po", direction="l", }, - [0x1245F]={ - category="nl", + [0x115C2]={ + category="po", direction="l", }, - [0x12460]={ - category="nl", + [0x115C3]={ + category="po", direction="l", }, - [0x12461]={ - category="nl", + [0x115C4]={ + category="po", direction="l", }, - [0x12462]={ - category="nl", + [0x115C5]={ + category="po", direction="l", }, - [0x12470]={ + [0x115C6]={ category="po", direction="l", }, - [0x12471]={ + [0x115C7]={ category="po", direction="l", }, - [0x12472]={ + [0x115C8]={ category="po", direction="l", }, - [0x12473]={ + [0x115C9]={ category="po", direction="l", }, - [0x13000]={ + [0x11600]={ category="lo", direction="l", }, - [0x13001]={ + [0x11601]={ category="lo", direction="l", }, - [0x13002]={ + [0x11602]={ category="lo", direction="l", }, - [0x13003]={ + [0x11603]={ category="lo", direction="l", }, - [0x13004]={ + [0x11604]={ category="lo", direction="l", }, - [0x13005]={ + [0x11605]={ category="lo", direction="l", }, - [0x13006]={ + [0x11606]={ category="lo", direction="l", }, - [0x13007]={ + [0x11607]={ category="lo", direction="l", }, - [0x13008]={ + [0x11608]={ category="lo", direction="l", }, - [0x13009]={ + [0x11609]={ category="lo", direction="l", }, - [0x1300A]={ + [0x1160A]={ category="lo", direction="l", }, - [0x1300B]={ + [0x1160B]={ category="lo", direction="l", }, - [0x1300C]={ + [0x1160C]={ category="lo", direction="l", }, - [0x1300D]={ + [0x1160D]={ category="lo", direction="l", }, - [0x1300E]={ + [0x1160E]={ category="lo", direction="l", }, - [0x1300F]={ + [0x1160F]={ category="lo", direction="l", }, - [0x13010]={ + [0x11610]={ category="lo", direction="l", }, - [0x13011]={ + [0x11611]={ category="lo", direction="l", }, - [0x13012]={ + [0x11612]={ category="lo", direction="l", }, - [0x13013]={ + [0x11613]={ category="lo", direction="l", }, - [0x13014]={ + [0x11614]={ category="lo", direction="l", }, - [0x13015]={ + [0x11615]={ category="lo", direction="l", }, - [0x13016]={ + [0x11616]={ category="lo", direction="l", }, - [0x13017]={ + [0x11617]={ category="lo", direction="l", }, - [0x13018]={ + [0x11618]={ category="lo", direction="l", }, - [0x13019]={ + [0x11619]={ category="lo", direction="l", }, - [0x1301A]={ + [0x1161A]={ category="lo", direction="l", }, - [0x1301B]={ + [0x1161B]={ category="lo", direction="l", }, - [0x1301C]={ + [0x1161C]={ category="lo", direction="l", }, - [0x1301D]={ + [0x1161D]={ category="lo", direction="l", }, - [0x1301E]={ + [0x1161E]={ category="lo", direction="l", }, - [0x1301F]={ + [0x1161F]={ category="lo", direction="l", }, - [0x13020]={ + [0x11620]={ category="lo", direction="l", }, - [0x13021]={ + [0x11621]={ category="lo", direction="l", }, - [0x13022]={ + [0x11622]={ category="lo", direction="l", }, - [0x13023]={ + [0x11623]={ category="lo", direction="l", }, - [0x13024]={ + [0x11624]={ category="lo", direction="l", }, - [0x13025]={ + [0x11625]={ category="lo", direction="l", }, - [0x13026]={ + [0x11626]={ category="lo", direction="l", }, - [0x13027]={ + [0x11627]={ category="lo", direction="l", }, - [0x13028]={ + [0x11628]={ category="lo", direction="l", }, - [0x13029]={ + [0x11629]={ category="lo", direction="l", }, - [0x1302A]={ + [0x1162A]={ category="lo", direction="l", }, - [0x1302B]={ + [0x1162B]={ category="lo", direction="l", }, - [0x1302C]={ + [0x1162C]={ category="lo", direction="l", }, - [0x1302D]={ + [0x1162D]={ category="lo", direction="l", }, - [0x1302E]={ + [0x1162E]={ category="lo", direction="l", }, - [0x1302F]={ + [0x1162F]={ category="lo", direction="l", }, - [0x13030]={ - category="lo", + [0x11630]={ + category="mc", direction="l", }, - [0x13031]={ - category="lo", + [0x11631]={ + category="mc", direction="l", }, - [0x13032]={ - category="lo", + [0x11632]={ + category="mc", direction="l", }, - [0x13033]={ - category="lo", - direction="l", + [0x11633]={ + category="mn", + direction="nsm", }, - [0x13034]={ - category="lo", - direction="l", + [0x11634]={ + category="mn", + direction="nsm", }, - [0x13035]={ - category="lo", - direction="l", + [0x11635]={ + category="mn", + direction="nsm", }, - [0x13036]={ - category="lo", - direction="l", + [0x11636]={ + category="mn", + direction="nsm", }, - [0x13037]={ - category="lo", - direction="l", + [0x11637]={ + category="mn", + direction="nsm", }, - [0x13038]={ - category="lo", - direction="l", + [0x11638]={ + category="mn", + direction="nsm", }, - [0x13039]={ - category="lo", - direction="l", + [0x11639]={ + category="mn", + direction="nsm", }, - [0x1303A]={ - category="lo", - direction="l", + [0x1163A]={ + category="mn", + direction="nsm", }, - [0x1303B]={ - category="lo", + [0x1163B]={ + category="mc", direction="l", }, - [0x1303C]={ - category="lo", + [0x1163C]={ + category="mc", direction="l", }, - [0x1303D]={ - category="lo", - direction="l", + [0x1163D]={ + category="mn", + direction="nsm", }, - [0x1303E]={ - category="lo", + [0x1163E]={ + category="mc", direction="l", }, - [0x1303F]={ - category="lo", - direction="l", + [0x1163F]={ + category="mn", + direction="nsm", }, - [0x13040]={ - category="lo", - direction="l", + [0x11640]={ + category="mn", + direction="nsm", }, - [0x13041]={ - category="lo", + [0x11641]={ + category="po", direction="l", }, - [0x13042]={ - category="lo", + [0x11642]={ + category="po", direction="l", }, - [0x13043]={ - category="lo", + [0x11643]={ + category="po", direction="l", }, - [0x13044]={ + [0x11644]={ category="lo", direction="l", }, - [0x13045]={ - category="lo", + [0x11650]={ + category="nd", direction="l", }, - [0x13046]={ - category="lo", + [0x11651]={ + category="nd", direction="l", }, - [0x13047]={ - category="lo", + [0x11652]={ + category="nd", direction="l", }, - [0x13048]={ - category="lo", + [0x11653]={ + category="nd", direction="l", }, - [0x13049]={ - category="lo", + [0x11654]={ + category="nd", direction="l", }, - [0x1304A]={ - category="lo", + [0x11655]={ + category="nd", direction="l", }, - [0x1304B]={ - category="lo", + [0x11656]={ + category="nd", direction="l", }, - [0x1304C]={ - category="lo", + [0x11657]={ + category="nd", direction="l", }, - [0x1304D]={ - category="lo", + [0x11658]={ + category="nd", direction="l", }, - [0x1304E]={ - category="lo", + [0x11659]={ + category="nd", direction="l", }, - [0x1304F]={ + [0x11680]={ category="lo", direction="l", }, - [0x13050]={ + [0x11681]={ category="lo", direction="l", }, - [0x13051]={ + [0x11682]={ category="lo", direction="l", }, - [0x13052]={ + [0x11683]={ category="lo", direction="l", }, - [0x13053]={ + [0x11684]={ category="lo", direction="l", }, - [0x13054]={ + [0x11685]={ category="lo", direction="l", }, - [0x13055]={ + [0x11686]={ category="lo", direction="l", }, - [0x13056]={ + [0x11687]={ category="lo", direction="l", }, - [0x13057]={ + [0x11688]={ category="lo", direction="l", }, - [0x13058]={ + [0x11689]={ category="lo", direction="l", }, - [0x13059]={ + [0x1168A]={ category="lo", direction="l", }, - [0x1305A]={ + [0x1168B]={ category="lo", direction="l", }, - [0x1305B]={ + [0x1168C]={ category="lo", direction="l", }, - [0x1305C]={ + [0x1168D]={ category="lo", direction="l", }, - [0x1305D]={ + [0x1168E]={ category="lo", direction="l", }, - [0x1305E]={ + [0x1168F]={ category="lo", direction="l", }, - [0x1305F]={ + [0x11690]={ category="lo", direction="l", }, - [0x13060]={ + [0x11691]={ category="lo", direction="l", }, - [0x13061]={ + [0x11692]={ category="lo", direction="l", }, - [0x13062]={ + [0x11693]={ category="lo", direction="l", }, - [0x13063]={ + [0x11694]={ category="lo", direction="l", }, - [0x13064]={ + [0x11695]={ category="lo", direction="l", }, - [0x13065]={ + [0x11696]={ category="lo", direction="l", }, - [0x13066]={ + [0x11697]={ category="lo", direction="l", }, - [0x13067]={ + [0x11698]={ category="lo", direction="l", }, - [0x13068]={ + [0x11699]={ category="lo", direction="l", }, - [0x13069]={ + [0x1169A]={ category="lo", direction="l", }, - [0x1306A]={ + [0x1169B]={ category="lo", direction="l", }, - [0x1306B]={ + [0x1169C]={ category="lo", direction="l", }, - [0x1306C]={ + [0x1169D]={ category="lo", direction="l", }, - [0x1306D]={ + [0x1169E]={ category="lo", direction="l", }, - [0x1306E]={ + [0x1169F]={ category="lo", direction="l", }, - [0x1306F]={ + [0x116A0]={ category="lo", direction="l", }, - [0x13070]={ + [0x116A1]={ category="lo", direction="l", }, - [0x13071]={ + [0x116A2]={ category="lo", direction="l", }, - [0x13072]={ + [0x116A3]={ category="lo", direction="l", }, - [0x13073]={ + [0x116A4]={ category="lo", direction="l", }, - [0x13074]={ + [0x116A5]={ category="lo", direction="l", }, - [0x13075]={ + [0x116A6]={ category="lo", direction="l", }, - [0x13076]={ + [0x116A7]={ category="lo", direction="l", }, - [0x13077]={ + [0x116A8]={ category="lo", direction="l", }, - [0x13078]={ + [0x116A9]={ category="lo", direction="l", }, - [0x13079]={ + [0x116AA]={ category="lo", direction="l", }, - [0x1307A]={ - category="lo", - direction="l", + [0x116AB]={ + category="mn", + direction="nsm", }, - [0x1307B]={ - category="lo", + [0x116AC]={ + category="mc", direction="l", }, - [0x1307C]={ - category="lo", - direction="l", + [0x116AD]={ + category="mn", + direction="nsm", }, - [0x1307D]={ - category="lo", + [0x116AE]={ + category="mc", direction="l", }, - [0x1307E]={ - category="lo", + [0x116AF]={ + category="mc", direction="l", }, - [0x1307F]={ - category="lo", - direction="l", + [0x116B0]={ + category="mn", + direction="nsm", }, - [0x13080]={ - category="lo", - direction="l", + [0x116B1]={ + category="mn", + direction="nsm", }, - [0x13081]={ - category="lo", - direction="l", + [0x116B2]={ + category="mn", + direction="nsm", }, - [0x13082]={ - category="lo", - direction="l", + [0x116B3]={ + category="mn", + direction="nsm", }, - [0x13083]={ - category="lo", - direction="l", + [0x116B4]={ + category="mn", + direction="nsm", }, - [0x13084]={ - category="lo", - direction="l", + [0x116B5]={ + category="mn", + direction="nsm", }, - [0x13085]={ - category="lo", + [0x116B6]={ + category="mc", direction="l", }, - [0x13086]={ - category="lo", - direction="l", + [0x116B7]={ + category="mn", + direction="nsm", }, - [0x13087]={ - category="lo", + [0x116C0]={ + category="nd", direction="l", }, - [0x13088]={ - category="lo", + [0x116C1]={ + category="nd", direction="l", }, - [0x13089]={ - category="lo", + [0x116C2]={ + category="nd", direction="l", }, - [0x1308A]={ - category="lo", + [0x116C3]={ + category="nd", direction="l", }, - [0x1308B]={ - category="lo", + [0x116C4]={ + category="nd", direction="l", }, - [0x1308C]={ - category="lo", + [0x116C5]={ + category="nd", direction="l", }, - [0x1308D]={ - category="lo", + [0x116C6]={ + category="nd", direction="l", }, - [0x1308E]={ - category="lo", + [0x116C7]={ + category="nd", direction="l", }, - [0x1308F]={ - category="lo", + [0x116C8]={ + category="nd", direction="l", }, - [0x13090]={ - category="lo", + [0x116C9]={ + category="nd", direction="l", }, - [0x13091]={ - category="lo", + [0x118A0]={ + category="lu", direction="l", }, - [0x13092]={ - category="lo", + [0x118A1]={ + category="lu", direction="l", }, - [0x13093]={ - category="lo", + [0x118A2]={ + category="lu", direction="l", }, - [0x13094]={ - category="lo", + [0x118A3]={ + category="lu", direction="l", }, - [0x13095]={ - category="lo", + [0x118A4]={ + category="lu", direction="l", }, - [0x13096]={ - category="lo", + [0x118A5]={ + category="lu", direction="l", }, - [0x13097]={ - category="lo", + [0x118A6]={ + category="lu", direction="l", }, - [0x13098]={ - category="lo", + [0x118A7]={ + category="lu", direction="l", }, - [0x13099]={ - category="lo", + [0x118A8]={ + category="lu", direction="l", }, - [0x1309A]={ - category="lo", + [0x118A9]={ + category="lu", direction="l", }, - [0x1309B]={ - category="lo", + [0x118AA]={ + category="lu", direction="l", }, - [0x1309C]={ - category="lo", + [0x118AB]={ + category="lu", direction="l", }, - [0x1309D]={ - category="lo", + [0x118AC]={ + category="lu", direction="l", }, - [0x1309E]={ - category="lo", + [0x118AD]={ + category="lu", direction="l", }, - [0x1309F]={ - category="lo", + [0x118AE]={ + category="lu", direction="l", }, - [0x130A0]={ - category="lo", + [0x118AF]={ + category="lu", direction="l", }, - [0x130A1]={ - category="lo", + [0x118B0]={ + category="lu", direction="l", }, - [0x130A2]={ - category="lo", + [0x118B1]={ + category="lu", direction="l", }, - [0x130A3]={ - category="lo", + [0x118B2]={ + category="lu", direction="l", }, - [0x130A4]={ - category="lo", + [0x118B3]={ + category="lu", direction="l", }, - [0x130A5]={ - category="lo", + [0x118B4]={ + category="lu", direction="l", }, - [0x130A6]={ - category="lo", + [0x118B5]={ + category="lu", direction="l", }, - [0x130A7]={ - category="lo", + [0x118B6]={ + category="lu", direction="l", }, - [0x130A8]={ - category="lo", + [0x118B7]={ + category="lu", direction="l", }, - [0x130A9]={ - category="lo", + [0x118B8]={ + category="lu", direction="l", }, - [0x130AA]={ - category="lo", + [0x118B9]={ + category="lu", direction="l", }, - [0x130AB]={ - category="lo", + [0x118BA]={ + category="lu", direction="l", }, - [0x130AC]={ - category="lo", + [0x118BB]={ + category="lu", direction="l", }, - [0x130AD]={ - category="lo", + [0x118BC]={ + category="lu", direction="l", }, - [0x130AE]={ - category="lo", + [0x118BD]={ + category="lu", direction="l", }, - [0x130AF]={ - category="lo", + [0x118BE]={ + category="lu", direction="l", }, - [0x130B0]={ - category="lo", + [0x118BF]={ + category="lu", direction="l", }, - [0x130B1]={ - category="lo", + [0x118C0]={ + category="ll", direction="l", }, - [0x130B2]={ - category="lo", + [0x118C1]={ + category="ll", direction="l", }, - [0x130B3]={ - category="lo", + [0x118C2]={ + category="ll", direction="l", }, - [0x130B4]={ - category="lo", + [0x118C3]={ + category="ll", direction="l", }, - [0x130B5]={ - category="lo", + [0x118C4]={ + category="ll", direction="l", }, - [0x130B6]={ - category="lo", + [0x118C5]={ + category="ll", direction="l", }, - [0x130B7]={ - category="lo", + [0x118C6]={ + category="ll", direction="l", }, - [0x130B8]={ - category="lo", + [0x118C7]={ + category="ll", direction="l", }, - [0x130B9]={ - category="lo", + [0x118C8]={ + category="ll", direction="l", }, - [0x130BA]={ - category="lo", + [0x118C9]={ + category="ll", direction="l", }, - [0x130BB]={ - category="lo", + [0x118CA]={ + category="ll", direction="l", }, - [0x130BC]={ - category="lo", + [0x118CB]={ + category="ll", direction="l", }, - [0x130BD]={ - category="lo", + [0x118CC]={ + category="ll", direction="l", }, - [0x130BE]={ - category="lo", + [0x118CD]={ + category="ll", direction="l", }, - [0x130BF]={ - category="lo", + [0x118CE]={ + category="ll", direction="l", }, - [0x130C0]={ - category="lo", + [0x118CF]={ + category="ll", direction="l", }, - [0x130C1]={ - category="lo", + [0x118D0]={ + category="ll", direction="l", }, - [0x130C2]={ - category="lo", + [0x118D1]={ + category="ll", direction="l", }, - [0x130C3]={ - category="lo", + [0x118D2]={ + category="ll", direction="l", }, - [0x130C4]={ - category="lo", + [0x118D3]={ + category="ll", direction="l", }, - [0x130C5]={ - category="lo", + [0x118D4]={ + category="ll", direction="l", }, - [0x130C6]={ - category="lo", + [0x118D5]={ + category="ll", direction="l", }, - [0x130C7]={ - category="lo", + [0x118D6]={ + category="ll", direction="l", }, - [0x130C8]={ - category="lo", + [0x118D7]={ + category="ll", direction="l", }, - [0x130C9]={ - category="lo", + [0x118D8]={ + category="ll", direction="l", }, - [0x130CA]={ - category="lo", + [0x118D9]={ + category="ll", direction="l", }, - [0x130CB]={ - category="lo", + [0x118DA]={ + category="ll", direction="l", }, - [0x130CC]={ - category="lo", + [0x118DB]={ + category="ll", direction="l", }, - [0x130CD]={ - category="lo", + [0x118DC]={ + category="ll", direction="l", }, - [0x130CE]={ - category="lo", + [0x118DD]={ + category="ll", direction="l", }, - [0x130CF]={ - category="lo", + [0x118DE]={ + category="ll", direction="l", }, - [0x130D0]={ - category="lo", + [0x118DF]={ + category="ll", direction="l", }, - [0x130D1]={ - category="lo", + [0x118E0]={ + category="nd", direction="l", }, - [0x130D2]={ - category="lo", + [0x118E1]={ + category="nd", direction="l", }, - [0x130D3]={ - category="lo", + [0x118E2]={ + category="nd", direction="l", }, - [0x130D4]={ - category="lo", + [0x118E3]={ + category="nd", direction="l", }, - [0x130D5]={ - category="lo", + [0x118E4]={ + category="nd", direction="l", }, - [0x130D6]={ - category="lo", + [0x118E5]={ + category="nd", direction="l", }, - [0x130D7]={ - category="lo", + [0x118E6]={ + category="nd", direction="l", }, - [0x130D8]={ - category="lo", + [0x118E7]={ + category="nd", direction="l", }, - [0x130D9]={ - category="lo", + [0x118E8]={ + category="nd", direction="l", }, - [0x130DA]={ - category="lo", + [0x118E9]={ + category="nd", direction="l", }, - [0x130DB]={ - category="lo", + [0x118EA]={ + category="no", direction="l", }, - [0x130DC]={ - category="lo", + [0x118EB]={ + category="no", direction="l", }, - [0x130DD]={ - category="lo", + [0x118EC]={ + category="no", direction="l", }, - [0x130DE]={ - category="lo", + [0x118ED]={ + category="no", direction="l", }, - [0x130DF]={ - category="lo", + [0x118EE]={ + category="no", direction="l", }, - [0x130E0]={ - category="lo", + [0x118EF]={ + category="no", direction="l", }, - [0x130E1]={ - category="lo", + [0x118F0]={ + category="no", direction="l", }, - [0x130E2]={ - category="lo", + [0x118F1]={ + category="no", direction="l", }, - [0x130E3]={ - category="lo", + [0x118F2]={ + category="no", direction="l", }, - [0x130E4]={ + [0x118FF]={ category="lo", direction="l", }, - [0x130E5]={ + [0x11AC0]={ category="lo", direction="l", }, - [0x130E6]={ + [0x11AC1]={ category="lo", direction="l", }, - [0x130E7]={ + [0x11AC2]={ category="lo", direction="l", }, - [0x130E8]={ + [0x11AC3]={ category="lo", direction="l", }, - [0x130E9]={ + [0x11AC4]={ category="lo", direction="l", }, - [0x130EA]={ + [0x11AC5]={ category="lo", direction="l", }, - [0x130EB]={ + [0x11AC6]={ category="lo", direction="l", }, - [0x130EC]={ + [0x11AC7]={ category="lo", direction="l", }, - [0x130ED]={ + [0x11AC8]={ category="lo", direction="l", }, - [0x130EE]={ + [0x11AC9]={ category="lo", direction="l", }, - [0x130EF]={ + [0x11ACA]={ category="lo", direction="l", }, - [0x130F0]={ + [0x11ACB]={ category="lo", direction="l", }, - [0x130F1]={ + [0x11ACC]={ category="lo", direction="l", }, - [0x130F2]={ + [0x11ACD]={ category="lo", direction="l", }, - [0x130F3]={ + [0x11ACE]={ category="lo", direction="l", }, - [0x130F4]={ + [0x11ACF]={ category="lo", direction="l", }, - [0x130F5]={ + [0x11AD0]={ category="lo", direction="l", }, - [0x130F6]={ + [0x11AD1]={ category="lo", direction="l", }, - [0x130F7]={ + [0x11AD2]={ category="lo", direction="l", }, - [0x130F8]={ + [0x11AD3]={ category="lo", direction="l", }, - [0x130F9]={ + [0x11AD4]={ category="lo", direction="l", }, - [0x130FA]={ + [0x11AD5]={ category="lo", direction="l", }, - [0x130FB]={ + [0x11AD6]={ category="lo", direction="l", }, - [0x130FC]={ + [0x11AD7]={ category="lo", direction="l", }, - [0x130FD]={ + [0x11AD8]={ category="lo", direction="l", }, - [0x130FE]={ + [0x11AD9]={ category="lo", direction="l", }, - [0x130FF]={ + [0x11ADA]={ category="lo", direction="l", }, - [0x13100]={ + [0x11ADB]={ category="lo", direction="l", }, - [0x13101]={ + [0x11ADC]={ category="lo", direction="l", }, - [0x13102]={ + [0x11ADD]={ category="lo", direction="l", }, - [0x13103]={ + [0x11ADE]={ category="lo", direction="l", }, - [0x13104]={ + [0x11ADF]={ category="lo", direction="l", }, - [0x13105]={ + [0x11AE0]={ category="lo", direction="l", }, - [0x13106]={ + [0x11AE1]={ category="lo", direction="l", }, - [0x13107]={ + [0x11AE2]={ category="lo", direction="l", }, - [0x13108]={ + [0x11AE3]={ category="lo", direction="l", }, - [0x13109]={ + [0x11AE4]={ category="lo", direction="l", }, - [0x1310A]={ + [0x11AE5]={ category="lo", direction="l", }, - [0x1310B]={ + [0x11AE6]={ category="lo", direction="l", }, - [0x1310C]={ + [0x11AE7]={ category="lo", direction="l", }, - [0x1310D]={ + [0x11AE8]={ category="lo", direction="l", }, - [0x1310E]={ + [0x11AE9]={ category="lo", direction="l", }, - [0x1310F]={ + [0x11AEA]={ category="lo", direction="l", }, - [0x13110]={ + [0x11AEB]={ category="lo", direction="l", }, - [0x13111]={ + [0x11AEC]={ category="lo", direction="l", }, - [0x13112]={ + [0x11AED]={ category="lo", direction="l", }, - [0x13113]={ + [0x11AEE]={ category="lo", direction="l", }, - [0x13114]={ + [0x11AEF]={ category="lo", direction="l", }, - [0x13115]={ + [0x11AF0]={ category="lo", direction="l", }, - [0x13116]={ + [0x11AF1]={ category="lo", direction="l", }, - [0x13117]={ + [0x11AF2]={ category="lo", direction="l", }, - [0x13118]={ + [0x11AF3]={ category="lo", direction="l", }, - [0x13119]={ + [0x11AF4]={ category="lo", direction="l", }, - [0x1311A]={ + [0x11AF5]={ category="lo", direction="l", }, - [0x1311B]={ + [0x11AF6]={ category="lo", direction="l", }, - [0x1311C]={ + [0x11AF7]={ category="lo", direction="l", }, - [0x1311D]={ + [0x11AF8]={ category="lo", direction="l", }, - [0x1311E]={ + [0x12000]={ category="lo", direction="l", }, - [0x1311F]={ + [0x12001]={ category="lo", direction="l", }, - [0x13120]={ + [0x12002]={ category="lo", direction="l", }, - [0x13121]={ + [0x12003]={ category="lo", direction="l", }, - [0x13122]={ + [0x12004]={ category="lo", direction="l", }, - [0x13123]={ + [0x12005]={ category="lo", direction="l", }, - [0x13124]={ + [0x12006]={ category="lo", direction="l", }, - [0x13125]={ + [0x12007]={ category="lo", direction="l", }, - [0x13126]={ + [0x12008]={ category="lo", direction="l", }, - [0x13127]={ + [0x12009]={ category="lo", direction="l", }, - [0x13128]={ + [0x1200A]={ category="lo", direction="l", }, - [0x13129]={ + [0x1200B]={ category="lo", direction="l", }, - [0x1312A]={ + [0x1200C]={ category="lo", direction="l", }, - [0x1312B]={ + [0x1200D]={ category="lo", direction="l", }, - [0x1312C]={ + [0x1200E]={ category="lo", direction="l", }, - [0x1312D]={ + [0x1200F]={ category="lo", direction="l", }, - [0x1312E]={ + [0x12010]={ category="lo", direction="l", }, - [0x1312F]={ + [0x12011]={ category="lo", direction="l", }, - [0x13130]={ + [0x12012]={ category="lo", direction="l", }, - [0x13131]={ + [0x12013]={ category="lo", direction="l", }, - [0x13132]={ + [0x12014]={ category="lo", direction="l", }, - [0x13133]={ + [0x12015]={ category="lo", direction="l", }, - [0x13134]={ + [0x12016]={ category="lo", direction="l", }, - [0x13135]={ + [0x12017]={ category="lo", direction="l", }, - [0x13136]={ + [0x12018]={ category="lo", direction="l", }, - [0x13137]={ + [0x12019]={ category="lo", direction="l", }, - [0x13138]={ + [0x1201A]={ category="lo", direction="l", }, - [0x13139]={ + [0x1201B]={ category="lo", direction="l", }, - [0x1313A]={ + [0x1201C]={ category="lo", direction="l", }, - [0x1313B]={ + [0x1201D]={ category="lo", direction="l", }, - [0x1313C]={ + [0x1201E]={ category="lo", direction="l", }, - [0x1313D]={ + [0x1201F]={ category="lo", direction="l", }, - [0x1313E]={ + [0x12020]={ category="lo", direction="l", }, - [0x1313F]={ + [0x12021]={ category="lo", direction="l", }, - [0x13140]={ + [0x12022]={ category="lo", direction="l", }, - [0x13141]={ + [0x12023]={ category="lo", direction="l", }, - [0x13142]={ + [0x12024]={ category="lo", direction="l", }, - [0x13143]={ + [0x12025]={ category="lo", direction="l", }, - [0x13144]={ + [0x12026]={ category="lo", direction="l", }, - [0x13145]={ + [0x12027]={ category="lo", direction="l", }, - [0x13146]={ + [0x12028]={ category="lo", direction="l", }, - [0x13147]={ + [0x12029]={ category="lo", direction="l", }, - [0x13148]={ + [0x1202A]={ category="lo", direction="l", }, - [0x13149]={ + [0x1202B]={ category="lo", direction="l", }, - [0x1314A]={ + [0x1202C]={ category="lo", direction="l", }, - [0x1314B]={ + [0x1202D]={ category="lo", direction="l", }, - [0x1314C]={ + [0x1202E]={ category="lo", direction="l", }, - [0x1314D]={ + [0x1202F]={ category="lo", direction="l", }, - [0x1314E]={ + [0x12030]={ category="lo", direction="l", }, - [0x1314F]={ + [0x12031]={ category="lo", direction="l", }, - [0x13150]={ + [0x12032]={ category="lo", direction="l", }, - [0x13151]={ + [0x12033]={ category="lo", direction="l", }, - [0x13152]={ + [0x12034]={ category="lo", direction="l", }, - [0x13153]={ + [0x12035]={ category="lo", direction="l", }, - [0x13154]={ + [0x12036]={ category="lo", direction="l", }, - [0x13155]={ + [0x12037]={ category="lo", direction="l", }, - [0x13156]={ + [0x12038]={ category="lo", direction="l", }, - [0x13157]={ + [0x12039]={ category="lo", direction="l", }, - [0x13158]={ + [0x1203A]={ category="lo", direction="l", }, - [0x13159]={ + [0x1203B]={ category="lo", direction="l", }, - [0x1315A]={ + [0x1203C]={ category="lo", direction="l", }, - [0x1315B]={ + [0x1203D]={ category="lo", direction="l", }, - [0x1315C]={ + [0x1203E]={ category="lo", direction="l", }, - [0x1315D]={ + [0x1203F]={ category="lo", direction="l", }, - [0x1315E]={ + [0x12040]={ category="lo", direction="l", }, - [0x1315F]={ + [0x12041]={ category="lo", direction="l", }, - [0x13160]={ + [0x12042]={ category="lo", direction="l", }, - [0x13161]={ + [0x12043]={ category="lo", direction="l", }, - [0x13162]={ + [0x12044]={ category="lo", direction="l", }, - [0x13163]={ + [0x12045]={ category="lo", direction="l", }, - [0x13164]={ + [0x12046]={ category="lo", direction="l", }, - [0x13165]={ + [0x12047]={ category="lo", direction="l", }, - [0x13166]={ + [0x12048]={ category="lo", direction="l", }, - [0x13167]={ + [0x12049]={ category="lo", direction="l", }, - [0x13168]={ + [0x1204A]={ category="lo", direction="l", }, - [0x13169]={ + [0x1204B]={ category="lo", direction="l", }, - [0x1316A]={ + [0x1204C]={ category="lo", direction="l", }, - [0x1316B]={ + [0x1204D]={ category="lo", direction="l", }, - [0x1316C]={ + [0x1204E]={ category="lo", direction="l", }, - [0x1316D]={ + [0x1204F]={ category="lo", direction="l", }, - [0x1316E]={ + [0x12050]={ category="lo", direction="l", }, - [0x1316F]={ + [0x12051]={ category="lo", direction="l", }, - [0x13170]={ + [0x12052]={ category="lo", direction="l", }, - [0x13171]={ + [0x12053]={ category="lo", direction="l", }, - [0x13172]={ + [0x12054]={ category="lo", direction="l", }, - [0x13173]={ + [0x12055]={ category="lo", direction="l", }, - [0x13174]={ + [0x12056]={ category="lo", direction="l", }, - [0x13175]={ + [0x12057]={ category="lo", direction="l", }, - [0x13176]={ + [0x12058]={ category="lo", direction="l", }, - [0x13177]={ + [0x12059]={ category="lo", direction="l", }, - [0x13178]={ + [0x1205A]={ category="lo", direction="l", }, - [0x13179]={ + [0x1205B]={ category="lo", direction="l", }, - [0x1317A]={ + [0x1205C]={ category="lo", direction="l", }, - [0x1317B]={ + [0x1205D]={ category="lo", direction="l", }, - [0x1317C]={ + [0x1205E]={ category="lo", direction="l", }, - [0x1317D]={ + [0x1205F]={ category="lo", direction="l", }, - [0x1317E]={ + [0x12060]={ category="lo", direction="l", }, - [0x1317F]={ + [0x12061]={ category="lo", direction="l", }, - [0x13180]={ + [0x12062]={ category="lo", direction="l", }, - [0x13181]={ + [0x12063]={ category="lo", direction="l", }, - [0x13182]={ + [0x12064]={ category="lo", direction="l", }, - [0x13183]={ + [0x12065]={ category="lo", direction="l", }, - [0x13184]={ + [0x12066]={ category="lo", direction="l", }, - [0x13185]={ + [0x12067]={ category="lo", direction="l", }, - [0x13186]={ + [0x12068]={ category="lo", direction="l", }, - [0x13187]={ + [0x12069]={ category="lo", direction="l", }, - [0x13188]={ + [0x1206A]={ category="lo", direction="l", }, - [0x13189]={ + [0x1206B]={ category="lo", direction="l", }, - [0x1318A]={ + [0x1206C]={ category="lo", direction="l", }, - [0x1318B]={ + [0x1206D]={ category="lo", direction="l", }, - [0x1318C]={ + [0x1206E]={ category="lo", direction="l", }, - [0x1318D]={ + [0x1206F]={ category="lo", direction="l", }, - [0x1318E]={ + [0x12070]={ category="lo", direction="l", }, - [0x1318F]={ + [0x12071]={ category="lo", direction="l", }, - [0x13190]={ + [0x12072]={ category="lo", direction="l", }, - [0x13191]={ + [0x12073]={ category="lo", direction="l", }, - [0x13192]={ + [0x12074]={ category="lo", direction="l", }, - [0x13193]={ + [0x12075]={ category="lo", direction="l", }, - [0x13194]={ + [0x12076]={ category="lo", direction="l", }, - [0x13195]={ + [0x12077]={ category="lo", direction="l", }, - [0x13196]={ + [0x12078]={ category="lo", direction="l", }, - [0x13197]={ + [0x12079]={ category="lo", direction="l", }, - [0x13198]={ + [0x1207A]={ category="lo", direction="l", }, - [0x13199]={ + [0x1207B]={ category="lo", direction="l", }, - [0x1319A]={ + [0x1207C]={ category="lo", direction="l", }, - [0x1319B]={ + [0x1207D]={ category="lo", direction="l", }, - [0x1319C]={ + [0x1207E]={ category="lo", direction="l", }, - [0x1319D]={ + [0x1207F]={ category="lo", direction="l", }, - [0x1319E]={ + [0x12080]={ category="lo", direction="l", }, - [0x1319F]={ + [0x12081]={ category="lo", direction="l", }, - [0x131A0]={ + [0x12082]={ category="lo", direction="l", }, - [0x131A1]={ + [0x12083]={ category="lo", direction="l", }, - [0x131A2]={ + [0x12084]={ category="lo", direction="l", }, - [0x131A3]={ + [0x12085]={ category="lo", direction="l", }, - [0x131A4]={ + [0x12086]={ category="lo", direction="l", }, - [0x131A5]={ + [0x12087]={ category="lo", direction="l", }, - [0x131A6]={ + [0x12088]={ category="lo", direction="l", }, - [0x131A7]={ + [0x12089]={ category="lo", direction="l", }, - [0x131A8]={ + [0x1208A]={ category="lo", direction="l", }, - [0x131A9]={ + [0x1208B]={ category="lo", direction="l", }, - [0x131AA]={ + [0x1208C]={ category="lo", direction="l", }, - [0x131AB]={ + [0x1208D]={ category="lo", direction="l", }, - [0x131AC]={ + [0x1208E]={ category="lo", direction="l", }, - [0x131AD]={ + [0x1208F]={ category="lo", direction="l", }, - [0x131AE]={ + [0x12090]={ category="lo", direction="l", }, - [0x131AF]={ + [0x12091]={ category="lo", direction="l", }, - [0x131B0]={ + [0x12092]={ category="lo", direction="l", }, - [0x131B1]={ + [0x12093]={ category="lo", direction="l", }, - [0x131B2]={ + [0x12094]={ category="lo", direction="l", }, - [0x131B3]={ + [0x12095]={ category="lo", direction="l", }, - [0x131B4]={ + [0x12096]={ category="lo", direction="l", }, - [0x131B5]={ + [0x12097]={ category="lo", direction="l", }, - [0x131B6]={ + [0x12098]={ category="lo", direction="l", }, - [0x131B7]={ + [0x12099]={ category="lo", direction="l", }, - [0x131B8]={ + [0x1209A]={ category="lo", direction="l", }, - [0x131B9]={ + [0x1209B]={ category="lo", direction="l", }, - [0x131BA]={ + [0x1209C]={ category="lo", direction="l", }, - [0x131BB]={ + [0x1209D]={ category="lo", direction="l", }, - [0x131BC]={ + [0x1209E]={ category="lo", direction="l", }, - [0x131BD]={ + [0x1209F]={ category="lo", direction="l", }, - [0x131BE]={ + [0x120A0]={ category="lo", direction="l", }, - [0x131BF]={ + [0x120A1]={ category="lo", direction="l", }, - [0x131C0]={ + [0x120A2]={ category="lo", direction="l", }, - [0x131C1]={ + [0x120A3]={ category="lo", direction="l", }, - [0x131C2]={ + [0x120A4]={ category="lo", direction="l", }, - [0x131C3]={ + [0x120A5]={ category="lo", direction="l", }, - [0x131C4]={ + [0x120A6]={ category="lo", direction="l", }, - [0x131C5]={ + [0x120A7]={ category="lo", direction="l", }, - [0x131C6]={ + [0x120A8]={ category="lo", direction="l", }, - [0x131C7]={ + [0x120A9]={ category="lo", direction="l", }, - [0x131C8]={ + [0x120AA]={ category="lo", direction="l", }, - [0x131C9]={ + [0x120AB]={ category="lo", direction="l", }, - [0x131CA]={ + [0x120AC]={ category="lo", direction="l", }, - [0x131CB]={ + [0x120AD]={ category="lo", direction="l", }, - [0x131CC]={ + [0x120AE]={ category="lo", direction="l", }, - [0x131CD]={ + [0x120AF]={ category="lo", direction="l", }, - [0x131CE]={ + [0x120B0]={ category="lo", direction="l", }, - [0x131CF]={ + [0x120B1]={ category="lo", direction="l", }, - [0x131D0]={ + [0x120B2]={ category="lo", direction="l", }, - [0x131D1]={ + [0x120B3]={ category="lo", direction="l", }, - [0x131D2]={ + [0x120B4]={ category="lo", direction="l", }, - [0x131D3]={ + [0x120B5]={ category="lo", direction="l", }, - [0x131D4]={ + [0x120B6]={ category="lo", direction="l", }, - [0x131D5]={ + [0x120B7]={ category="lo", direction="l", }, - [0x131D6]={ + [0x120B8]={ category="lo", direction="l", }, - [0x131D7]={ + [0x120B9]={ category="lo", direction="l", }, - [0x131D8]={ + [0x120BA]={ category="lo", direction="l", }, - [0x131D9]={ + [0x120BB]={ category="lo", direction="l", }, - [0x131DA]={ + [0x120BC]={ category="lo", direction="l", }, - [0x131DB]={ + [0x120BD]={ category="lo", direction="l", }, - [0x131DC]={ + [0x120BE]={ category="lo", direction="l", }, - [0x131DD]={ + [0x120BF]={ category="lo", direction="l", }, - [0x131DE]={ + [0x120C0]={ category="lo", direction="l", }, - [0x131DF]={ + [0x120C1]={ category="lo", direction="l", }, - [0x131E0]={ + [0x120C2]={ category="lo", direction="l", }, - [0x131E1]={ + [0x120C3]={ category="lo", direction="l", }, - [0x131E2]={ + [0x120C4]={ category="lo", direction="l", }, - [0x131E3]={ + [0x120C5]={ category="lo", direction="l", }, - [0x131E4]={ + [0x120C6]={ category="lo", direction="l", }, - [0x131E5]={ + [0x120C7]={ category="lo", direction="l", }, - [0x131E6]={ + [0x120C8]={ category="lo", direction="l", }, - [0x131E7]={ + [0x120C9]={ category="lo", direction="l", }, - [0x131E8]={ + [0x120CA]={ category="lo", direction="l", }, - [0x131E9]={ + [0x120CB]={ category="lo", direction="l", }, - [0x131EA]={ + [0x120CC]={ category="lo", direction="l", }, - [0x131EB]={ + [0x120CD]={ category="lo", direction="l", }, - [0x131EC]={ + [0x120CE]={ category="lo", direction="l", }, - [0x131ED]={ + [0x120CF]={ category="lo", direction="l", }, - [0x131EE]={ + [0x120D0]={ category="lo", direction="l", }, - [0x131EF]={ + [0x120D1]={ category="lo", direction="l", }, - [0x131F0]={ + [0x120D2]={ category="lo", direction="l", }, - [0x131F1]={ + [0x120D3]={ category="lo", direction="l", }, - [0x131F2]={ + [0x120D4]={ category="lo", direction="l", }, - [0x131F3]={ + [0x120D5]={ category="lo", direction="l", }, - [0x131F4]={ + [0x120D6]={ category="lo", direction="l", }, - [0x131F5]={ + [0x120D7]={ category="lo", direction="l", }, - [0x131F6]={ + [0x120D8]={ category="lo", direction="l", }, - [0x131F7]={ + [0x120D9]={ category="lo", direction="l", }, - [0x131F8]={ + [0x120DA]={ category="lo", direction="l", }, - [0x131F9]={ + [0x120DB]={ category="lo", direction="l", }, - [0x131FA]={ + [0x120DC]={ category="lo", direction="l", }, - [0x131FB]={ + [0x120DD]={ category="lo", direction="l", }, - [0x131FC]={ + [0x120DE]={ category="lo", direction="l", }, - [0x131FD]={ + [0x120DF]={ category="lo", direction="l", }, - [0x131FE]={ + [0x120E0]={ category="lo", direction="l", }, - [0x131FF]={ + [0x120E1]={ category="lo", direction="l", }, - [0x13200]={ + [0x120E2]={ category="lo", direction="l", }, - [0x13201]={ + [0x120E3]={ category="lo", direction="l", }, - [0x13202]={ + [0x120E4]={ category="lo", direction="l", }, - [0x13203]={ + [0x120E5]={ category="lo", direction="l", }, - [0x13204]={ + [0x120E6]={ category="lo", direction="l", }, - [0x13205]={ + [0x120E7]={ category="lo", direction="l", }, - [0x13206]={ + [0x120E8]={ category="lo", direction="l", }, - [0x13207]={ + [0x120E9]={ category="lo", direction="l", }, - [0x13208]={ + [0x120EA]={ category="lo", direction="l", }, - [0x13209]={ + [0x120EB]={ category="lo", direction="l", }, - [0x1320A]={ + [0x120EC]={ category="lo", direction="l", }, - [0x1320B]={ + [0x120ED]={ category="lo", direction="l", }, - [0x1320C]={ + [0x120EE]={ category="lo", direction="l", }, - [0x1320D]={ + [0x120EF]={ category="lo", direction="l", }, - [0x1320E]={ + [0x120F0]={ category="lo", direction="l", }, - [0x1320F]={ + [0x120F1]={ category="lo", direction="l", }, - [0x13210]={ + [0x120F2]={ category="lo", direction="l", }, - [0x13211]={ + [0x120F3]={ category="lo", direction="l", }, - [0x13212]={ + [0x120F4]={ category="lo", direction="l", }, - [0x13213]={ + [0x120F5]={ category="lo", direction="l", }, - [0x13214]={ + [0x120F6]={ category="lo", direction="l", }, - [0x13215]={ + [0x120F7]={ category="lo", direction="l", }, - [0x13216]={ + [0x120F8]={ category="lo", direction="l", }, - [0x13217]={ + [0x120F9]={ category="lo", direction="l", }, - [0x13218]={ + [0x120FA]={ category="lo", direction="l", }, - [0x13219]={ + [0x120FB]={ category="lo", direction="l", }, - [0x1321A]={ + [0x120FC]={ category="lo", direction="l", }, - [0x1321B]={ + [0x120FD]={ category="lo", direction="l", }, - [0x1321C]={ + [0x120FE]={ category="lo", direction="l", }, - [0x1321D]={ + [0x120FF]={ category="lo", direction="l", }, - [0x1321E]={ + [0x12100]={ category="lo", direction="l", }, - [0x1321F]={ + [0x12101]={ category="lo", direction="l", }, - [0x13220]={ + [0x12102]={ category="lo", direction="l", }, - [0x13221]={ + [0x12103]={ category="lo", direction="l", }, - [0x13222]={ + [0x12104]={ category="lo", direction="l", }, - [0x13223]={ + [0x12105]={ category="lo", direction="l", }, - [0x13224]={ + [0x12106]={ category="lo", direction="l", }, - [0x13225]={ + [0x12107]={ category="lo", direction="l", }, - [0x13226]={ + [0x12108]={ category="lo", direction="l", }, - [0x13227]={ + [0x12109]={ category="lo", direction="l", }, - [0x13228]={ + [0x1210A]={ category="lo", direction="l", }, - [0x13229]={ + [0x1210B]={ category="lo", direction="l", }, - [0x1322A]={ + [0x1210C]={ category="lo", direction="l", }, - [0x1322B]={ + [0x1210D]={ category="lo", direction="l", }, - [0x1322C]={ + [0x1210E]={ category="lo", direction="l", }, - [0x1322D]={ + [0x1210F]={ category="lo", direction="l", }, - [0x1322E]={ + [0x12110]={ category="lo", direction="l", }, - [0x1322F]={ + [0x12111]={ category="lo", direction="l", }, - [0x13230]={ + [0x12112]={ category="lo", direction="l", }, - [0x13231]={ + [0x12113]={ category="lo", direction="l", }, - [0x13232]={ + [0x12114]={ category="lo", direction="l", }, - [0x13233]={ + [0x12115]={ category="lo", direction="l", }, - [0x13234]={ + [0x12116]={ category="lo", direction="l", }, - [0x13235]={ + [0x12117]={ category="lo", direction="l", }, - [0x13236]={ + [0x12118]={ category="lo", direction="l", }, - [0x13237]={ + [0x12119]={ category="lo", direction="l", }, - [0x13238]={ + [0x1211A]={ category="lo", direction="l", }, - [0x13239]={ + [0x1211B]={ category="lo", direction="l", }, - [0x1323A]={ + [0x1211C]={ category="lo", direction="l", }, - [0x1323B]={ + [0x1211D]={ category="lo", direction="l", }, - [0x1323C]={ + [0x1211E]={ category="lo", direction="l", }, - [0x1323D]={ + [0x1211F]={ category="lo", direction="l", }, - [0x1323E]={ + [0x12120]={ category="lo", direction="l", }, - [0x1323F]={ + [0x12121]={ category="lo", direction="l", }, - [0x13240]={ + [0x12122]={ category="lo", direction="l", }, - [0x13241]={ + [0x12123]={ category="lo", direction="l", }, - [0x13242]={ + [0x12124]={ category="lo", direction="l", }, - [0x13243]={ + [0x12125]={ category="lo", direction="l", }, - [0x13244]={ + [0x12126]={ category="lo", direction="l", }, - [0x13245]={ + [0x12127]={ category="lo", direction="l", }, - [0x13246]={ + [0x12128]={ category="lo", direction="l", }, - [0x13247]={ + [0x12129]={ category="lo", direction="l", }, - [0x13248]={ + [0x1212A]={ category="lo", direction="l", }, - [0x13249]={ + [0x1212B]={ category="lo", direction="l", }, - [0x1324A]={ + [0x1212C]={ category="lo", direction="l", }, - [0x1324B]={ + [0x1212D]={ category="lo", direction="l", }, - [0x1324C]={ + [0x1212E]={ category="lo", direction="l", }, - [0x1324D]={ + [0x1212F]={ category="lo", direction="l", }, - [0x1324E]={ + [0x12130]={ category="lo", direction="l", }, - [0x1324F]={ + [0x12131]={ category="lo", direction="l", }, - [0x13250]={ + [0x12132]={ category="lo", direction="l", }, - [0x13251]={ + [0x12133]={ category="lo", direction="l", }, - [0x13252]={ + [0x12134]={ category="lo", direction="l", }, - [0x13253]={ + [0x12135]={ category="lo", direction="l", }, - [0x13254]={ + [0x12136]={ category="lo", direction="l", }, - [0x13255]={ + [0x12137]={ category="lo", direction="l", }, - [0x13256]={ + [0x12138]={ category="lo", direction="l", }, - [0x13257]={ + [0x12139]={ category="lo", direction="l", }, - [0x13258]={ + [0x1213A]={ category="lo", direction="l", }, - [0x13259]={ + [0x1213B]={ category="lo", direction="l", }, - [0x1325A]={ + [0x1213C]={ category="lo", direction="l", }, - [0x1325B]={ + [0x1213D]={ category="lo", direction="l", }, - [0x1325C]={ + [0x1213E]={ category="lo", direction="l", }, - [0x1325D]={ + [0x1213F]={ category="lo", direction="l", }, - [0x1325E]={ + [0x12140]={ category="lo", direction="l", }, - [0x1325F]={ + [0x12141]={ category="lo", direction="l", }, - [0x13260]={ + [0x12142]={ category="lo", direction="l", }, - [0x13261]={ + [0x12143]={ category="lo", direction="l", }, - [0x13262]={ + [0x12144]={ category="lo", direction="l", }, - [0x13263]={ + [0x12145]={ category="lo", direction="l", }, - [0x13264]={ + [0x12146]={ category="lo", direction="l", }, - [0x13265]={ + [0x12147]={ category="lo", direction="l", }, - [0x13266]={ + [0x12148]={ category="lo", direction="l", }, - [0x13267]={ + [0x12149]={ category="lo", direction="l", }, - [0x13268]={ + [0x1214A]={ category="lo", direction="l", }, - [0x13269]={ + [0x1214B]={ category="lo", direction="l", }, - [0x1326A]={ + [0x1214C]={ category="lo", direction="l", }, - [0x1326B]={ + [0x1214D]={ category="lo", direction="l", }, - [0x1326C]={ + [0x1214E]={ category="lo", direction="l", }, - [0x1326D]={ + [0x1214F]={ category="lo", direction="l", }, - [0x1326E]={ + [0x12150]={ category="lo", direction="l", }, - [0x1326F]={ + [0x12151]={ category="lo", direction="l", }, - [0x13270]={ + [0x12152]={ category="lo", direction="l", }, - [0x13271]={ + [0x12153]={ category="lo", direction="l", }, - [0x13272]={ + [0x12154]={ category="lo", direction="l", }, - [0x13273]={ + [0x12155]={ category="lo", direction="l", }, - [0x13274]={ + [0x12156]={ category="lo", direction="l", }, - [0x13275]={ + [0x12157]={ category="lo", direction="l", }, - [0x13276]={ + [0x12158]={ category="lo", direction="l", }, - [0x13277]={ + [0x12159]={ category="lo", direction="l", }, - [0x13278]={ + [0x1215A]={ category="lo", direction="l", }, - [0x13279]={ + [0x1215B]={ category="lo", direction="l", }, - [0x1327A]={ + [0x1215C]={ category="lo", direction="l", }, - [0x1327B]={ + [0x1215D]={ category="lo", direction="l", }, - [0x1327C]={ + [0x1215E]={ category="lo", direction="l", }, - [0x1327D]={ + [0x1215F]={ category="lo", direction="l", }, - [0x1327E]={ + [0x12160]={ category="lo", direction="l", }, - [0x1327F]={ + [0x12161]={ category="lo", direction="l", }, - [0x13280]={ + [0x12162]={ category="lo", direction="l", }, - [0x13281]={ + [0x12163]={ category="lo", direction="l", }, - [0x13282]={ + [0x12164]={ category="lo", direction="l", }, - [0x13283]={ + [0x12165]={ category="lo", direction="l", }, - [0x13284]={ + [0x12166]={ category="lo", direction="l", }, - [0x13285]={ + [0x12167]={ category="lo", direction="l", }, - [0x13286]={ + [0x12168]={ category="lo", direction="l", }, - [0x13287]={ + [0x12169]={ category="lo", direction="l", }, - [0x13288]={ + [0x1216A]={ category="lo", direction="l", }, - [0x13289]={ + [0x1216B]={ category="lo", direction="l", }, - [0x1328A]={ + [0x1216C]={ category="lo", direction="l", }, - [0x1328B]={ + [0x1216D]={ category="lo", direction="l", }, - [0x1328C]={ + [0x1216E]={ category="lo", direction="l", }, - [0x1328D]={ + [0x1216F]={ category="lo", direction="l", }, - [0x1328E]={ + [0x12170]={ category="lo", direction="l", }, - [0x1328F]={ + [0x12171]={ category="lo", direction="l", }, - [0x13290]={ + [0x12172]={ category="lo", direction="l", }, - [0x13291]={ + [0x12173]={ category="lo", direction="l", }, - [0x13292]={ + [0x12174]={ category="lo", direction="l", }, - [0x13293]={ + [0x12175]={ category="lo", direction="l", }, - [0x13294]={ + [0x12176]={ category="lo", direction="l", }, - [0x13295]={ + [0x12177]={ category="lo", direction="l", }, - [0x13296]={ + [0x12178]={ category="lo", direction="l", }, - [0x13297]={ + [0x12179]={ category="lo", direction="l", }, - [0x13298]={ + [0x1217A]={ category="lo", direction="l", }, - [0x13299]={ + [0x1217B]={ category="lo", direction="l", }, - [0x1329A]={ + [0x1217C]={ category="lo", direction="l", }, - [0x1329B]={ + [0x1217D]={ category="lo", direction="l", }, - [0x1329C]={ + [0x1217E]={ category="lo", direction="l", }, - [0x1329D]={ + [0x1217F]={ category="lo", direction="l", }, - [0x1329E]={ + [0x12180]={ category="lo", direction="l", }, - [0x1329F]={ + [0x12181]={ category="lo", direction="l", }, - [0x132A0]={ + [0x12182]={ category="lo", direction="l", }, - [0x132A1]={ + [0x12183]={ category="lo", direction="l", }, - [0x132A2]={ + [0x12184]={ category="lo", direction="l", }, - [0x132A3]={ + [0x12185]={ category="lo", direction="l", }, - [0x132A4]={ + [0x12186]={ category="lo", direction="l", }, - [0x132A5]={ + [0x12187]={ category="lo", direction="l", }, - [0x132A6]={ + [0x12188]={ category="lo", direction="l", }, - [0x132A7]={ + [0x12189]={ category="lo", direction="l", }, - [0x132A8]={ + [0x1218A]={ category="lo", direction="l", }, - [0x132A9]={ + [0x1218B]={ category="lo", direction="l", }, - [0x132AA]={ + [0x1218C]={ category="lo", direction="l", }, - [0x132AB]={ + [0x1218D]={ category="lo", direction="l", }, - [0x132AC]={ + [0x1218E]={ category="lo", direction="l", }, - [0x132AD]={ + [0x1218F]={ category="lo", direction="l", }, - [0x132AE]={ + [0x12190]={ category="lo", direction="l", }, - [0x132AF]={ + [0x12191]={ category="lo", direction="l", }, - [0x132B0]={ + [0x12192]={ category="lo", direction="l", }, - [0x132B1]={ + [0x12193]={ category="lo", direction="l", }, - [0x132B2]={ + [0x12194]={ category="lo", direction="l", }, - [0x132B3]={ + [0x12195]={ category="lo", direction="l", }, - [0x132B4]={ + [0x12196]={ category="lo", direction="l", }, - [0x132B5]={ + [0x12197]={ category="lo", direction="l", }, - [0x132B6]={ + [0x12198]={ category="lo", direction="l", }, - [0x132B7]={ + [0x12199]={ category="lo", direction="l", }, - [0x132B8]={ + [0x1219A]={ category="lo", direction="l", }, - [0x132B9]={ + [0x1219B]={ category="lo", direction="l", }, - [0x132BA]={ + [0x1219C]={ category="lo", direction="l", }, - [0x132BB]={ + [0x1219D]={ category="lo", direction="l", }, - [0x132BC]={ + [0x1219E]={ category="lo", direction="l", }, - [0x132BD]={ + [0x1219F]={ category="lo", direction="l", }, - [0x132BE]={ + [0x121A0]={ category="lo", direction="l", }, - [0x132BF]={ + [0x121A1]={ category="lo", direction="l", }, - [0x132C0]={ + [0x121A2]={ category="lo", direction="l", }, - [0x132C1]={ + [0x121A3]={ category="lo", direction="l", }, - [0x132C2]={ + [0x121A4]={ category="lo", direction="l", }, - [0x132C3]={ + [0x121A5]={ category="lo", direction="l", }, - [0x132C4]={ + [0x121A6]={ category="lo", direction="l", }, - [0x132C5]={ + [0x121A7]={ category="lo", direction="l", }, - [0x132C6]={ + [0x121A8]={ category="lo", direction="l", }, - [0x132C7]={ + [0x121A9]={ category="lo", direction="l", }, - [0x132C8]={ + [0x121AA]={ category="lo", direction="l", }, - [0x132C9]={ + [0x121AB]={ category="lo", direction="l", }, - [0x132CA]={ + [0x121AC]={ category="lo", direction="l", }, - [0x132CB]={ + [0x121AD]={ category="lo", direction="l", }, - [0x132CC]={ + [0x121AE]={ category="lo", direction="l", }, - [0x132CD]={ + [0x121AF]={ category="lo", direction="l", }, - [0x132CE]={ + [0x121B0]={ category="lo", direction="l", }, - [0x132CF]={ + [0x121B1]={ category="lo", direction="l", }, - [0x132D0]={ + [0x121B2]={ category="lo", direction="l", }, - [0x132D1]={ + [0x121B3]={ category="lo", direction="l", }, - [0x132D2]={ + [0x121B4]={ category="lo", direction="l", }, - [0x132D3]={ + [0x121B5]={ category="lo", direction="l", }, - [0x132D4]={ + [0x121B6]={ category="lo", direction="l", }, - [0x132D5]={ + [0x121B7]={ category="lo", direction="l", }, - [0x132D6]={ + [0x121B8]={ category="lo", direction="l", }, - [0x132D7]={ + [0x121B9]={ category="lo", direction="l", }, - [0x132D8]={ + [0x121BA]={ category="lo", direction="l", }, - [0x132D9]={ + [0x121BB]={ category="lo", direction="l", }, - [0x132DA]={ + [0x121BC]={ category="lo", direction="l", }, - [0x132DB]={ + [0x121BD]={ category="lo", direction="l", }, - [0x132DC]={ + [0x121BE]={ category="lo", direction="l", }, - [0x132DD]={ + [0x121BF]={ category="lo", direction="l", }, - [0x132DE]={ + [0x121C0]={ category="lo", direction="l", }, - [0x132DF]={ + [0x121C1]={ category="lo", direction="l", }, - [0x132E0]={ + [0x121C2]={ category="lo", direction="l", }, - [0x132E1]={ + [0x121C3]={ category="lo", direction="l", }, - [0x132E2]={ + [0x121C4]={ category="lo", direction="l", }, - [0x132E3]={ + [0x121C5]={ category="lo", direction="l", }, - [0x132E4]={ + [0x121C6]={ category="lo", direction="l", }, - [0x132E5]={ + [0x121C7]={ category="lo", direction="l", }, - [0x132E6]={ + [0x121C8]={ category="lo", direction="l", }, - [0x132E7]={ + [0x121C9]={ category="lo", direction="l", }, - [0x132E8]={ + [0x121CA]={ category="lo", direction="l", }, - [0x132E9]={ + [0x121CB]={ category="lo", direction="l", }, - [0x132EA]={ + [0x121CC]={ category="lo", direction="l", }, - [0x132EB]={ + [0x121CD]={ category="lo", direction="l", }, - [0x132EC]={ + [0x121CE]={ category="lo", direction="l", }, - [0x132ED]={ + [0x121CF]={ category="lo", direction="l", }, - [0x132EE]={ + [0x121D0]={ category="lo", direction="l", }, - [0x132EF]={ + [0x121D1]={ category="lo", direction="l", }, - [0x132F0]={ + [0x121D2]={ category="lo", direction="l", }, - [0x132F1]={ + [0x121D3]={ category="lo", direction="l", }, - [0x132F2]={ + [0x121D4]={ category="lo", direction="l", }, - [0x132F3]={ + [0x121D5]={ category="lo", direction="l", }, - [0x132F4]={ + [0x121D6]={ category="lo", direction="l", }, - [0x132F5]={ + [0x121D7]={ category="lo", direction="l", }, - [0x132F6]={ + [0x121D8]={ category="lo", direction="l", }, - [0x132F7]={ + [0x121D9]={ category="lo", direction="l", }, - [0x132F8]={ + [0x121DA]={ category="lo", direction="l", }, - [0x132F9]={ + [0x121DB]={ category="lo", direction="l", }, - [0x132FA]={ + [0x121DC]={ category="lo", direction="l", }, - [0x132FB]={ + [0x121DD]={ category="lo", direction="l", }, - [0x132FC]={ + [0x121DE]={ category="lo", direction="l", }, - [0x132FD]={ + [0x121DF]={ category="lo", direction="l", }, - [0x132FE]={ + [0x121E0]={ category="lo", direction="l", }, - [0x132FF]={ + [0x121E1]={ category="lo", direction="l", }, - [0x13300]={ + [0x121E2]={ category="lo", direction="l", }, - [0x13301]={ + [0x121E3]={ category="lo", direction="l", }, - [0x13302]={ + [0x121E4]={ category="lo", direction="l", }, - [0x13303]={ + [0x121E5]={ category="lo", direction="l", }, - [0x13304]={ + [0x121E6]={ category="lo", direction="l", }, - [0x13305]={ + [0x121E7]={ category="lo", direction="l", }, - [0x13306]={ + [0x121E8]={ category="lo", direction="l", }, - [0x13307]={ + [0x121E9]={ category="lo", direction="l", }, - [0x13308]={ + [0x121EA]={ category="lo", direction="l", }, - [0x13309]={ + [0x121EB]={ category="lo", direction="l", }, - [0x1330A]={ + [0x121EC]={ category="lo", direction="l", }, - [0x1330B]={ + [0x121ED]={ category="lo", direction="l", }, - [0x1330C]={ + [0x121EE]={ category="lo", direction="l", }, - [0x1330D]={ + [0x121EF]={ category="lo", direction="l", }, - [0x1330E]={ + [0x121F0]={ category="lo", direction="l", }, - [0x1330F]={ + [0x121F1]={ category="lo", direction="l", }, - [0x13310]={ + [0x121F2]={ category="lo", direction="l", }, - [0x13311]={ + [0x121F3]={ category="lo", direction="l", }, - [0x13312]={ + [0x121F4]={ category="lo", direction="l", }, - [0x13313]={ + [0x121F5]={ category="lo", direction="l", }, - [0x13314]={ + [0x121F6]={ category="lo", direction="l", }, - [0x13315]={ + [0x121F7]={ category="lo", direction="l", }, - [0x13316]={ + [0x121F8]={ category="lo", direction="l", }, - [0x13317]={ + [0x121F9]={ category="lo", direction="l", }, - [0x13318]={ + [0x121FA]={ category="lo", direction="l", }, - [0x13319]={ + [0x121FB]={ category="lo", direction="l", }, - [0x1331A]={ + [0x121FC]={ category="lo", direction="l", }, - [0x1331B]={ + [0x121FD]={ category="lo", direction="l", }, - [0x1331C]={ + [0x121FE]={ category="lo", direction="l", }, - [0x1331D]={ + [0x121FF]={ category="lo", direction="l", }, - [0x1331E]={ + [0x12200]={ category="lo", direction="l", }, - [0x1331F]={ + [0x12201]={ category="lo", direction="l", }, - [0x13320]={ + [0x12202]={ category="lo", direction="l", }, - [0x13321]={ + [0x12203]={ category="lo", direction="l", }, - [0x13322]={ + [0x12204]={ category="lo", direction="l", }, - [0x13323]={ + [0x12205]={ category="lo", direction="l", }, - [0x13324]={ + [0x12206]={ category="lo", direction="l", }, - [0x13325]={ + [0x12207]={ category="lo", direction="l", }, - [0x13326]={ + [0x12208]={ category="lo", direction="l", }, - [0x13327]={ + [0x12209]={ category="lo", direction="l", }, - [0x13328]={ + [0x1220A]={ category="lo", direction="l", }, - [0x13329]={ + [0x1220B]={ category="lo", direction="l", }, - [0x1332A]={ + [0x1220C]={ category="lo", direction="l", }, - [0x1332B]={ + [0x1220D]={ category="lo", direction="l", }, - [0x1332C]={ + [0x1220E]={ category="lo", direction="l", }, - [0x1332D]={ + [0x1220F]={ category="lo", direction="l", }, - [0x1332E]={ + [0x12210]={ category="lo", direction="l", }, - [0x1332F]={ + [0x12211]={ category="lo", direction="l", }, - [0x13330]={ + [0x12212]={ category="lo", direction="l", }, - [0x13331]={ + [0x12213]={ category="lo", direction="l", }, - [0x13332]={ + [0x12214]={ category="lo", direction="l", }, - [0x13333]={ + [0x12215]={ category="lo", direction="l", }, - [0x13334]={ + [0x12216]={ category="lo", direction="l", }, - [0x13335]={ + [0x12217]={ category="lo", direction="l", }, - [0x13336]={ + [0x12218]={ category="lo", direction="l", }, - [0x13337]={ + [0x12219]={ category="lo", direction="l", }, - [0x13338]={ + [0x1221A]={ category="lo", direction="l", }, - [0x13339]={ + [0x1221B]={ category="lo", direction="l", }, - [0x1333A]={ + [0x1221C]={ category="lo", direction="l", }, - [0x1333B]={ + [0x1221D]={ category="lo", direction="l", }, - [0x1333C]={ + [0x1221E]={ category="lo", direction="l", }, - [0x1333D]={ + [0x1221F]={ category="lo", direction="l", }, - [0x1333E]={ + [0x12220]={ category="lo", direction="l", }, - [0x1333F]={ + [0x12221]={ category="lo", direction="l", }, - [0x13340]={ + [0x12222]={ category="lo", direction="l", }, - [0x13341]={ + [0x12223]={ category="lo", direction="l", }, - [0x13342]={ + [0x12224]={ category="lo", direction="l", }, - [0x13343]={ + [0x12225]={ category="lo", direction="l", }, - [0x13344]={ + [0x12226]={ category="lo", direction="l", }, - [0x13345]={ + [0x12227]={ category="lo", direction="l", }, - [0x13346]={ + [0x12228]={ category="lo", direction="l", }, - [0x13347]={ + [0x12229]={ category="lo", direction="l", }, - [0x13348]={ + [0x1222A]={ category="lo", direction="l", }, - [0x13349]={ + [0x1222B]={ category="lo", direction="l", }, - [0x1334A]={ + [0x1222C]={ category="lo", direction="l", }, - [0x1334B]={ + [0x1222D]={ category="lo", direction="l", }, - [0x1334C]={ + [0x1222E]={ category="lo", direction="l", }, - [0x1334D]={ + [0x1222F]={ category="lo", direction="l", }, - [0x1334E]={ + [0x12230]={ category="lo", direction="l", }, - [0x1334F]={ + [0x12231]={ category="lo", direction="l", }, - [0x13350]={ + [0x12232]={ category="lo", direction="l", }, - [0x13351]={ + [0x12233]={ category="lo", direction="l", }, - [0x13352]={ + [0x12234]={ category="lo", direction="l", }, - [0x13353]={ + [0x12235]={ category="lo", direction="l", }, - [0x13354]={ + [0x12236]={ category="lo", direction="l", }, - [0x13355]={ + [0x12237]={ category="lo", direction="l", }, - [0x13356]={ + [0x12238]={ category="lo", direction="l", }, - [0x13357]={ + [0x12239]={ category="lo", direction="l", }, - [0x13358]={ + [0x1223A]={ category="lo", direction="l", }, - [0x13359]={ + [0x1223B]={ category="lo", direction="l", }, - [0x1335A]={ + [0x1223C]={ category="lo", direction="l", }, - [0x1335B]={ + [0x1223D]={ category="lo", direction="l", }, - [0x1335C]={ + [0x1223E]={ category="lo", direction="l", }, - [0x1335D]={ + [0x1223F]={ category="lo", direction="l", }, - [0x1335E]={ + [0x12240]={ category="lo", direction="l", }, - [0x1335F]={ + [0x12241]={ category="lo", direction="l", }, - [0x13360]={ + [0x12242]={ category="lo", direction="l", }, - [0x13361]={ + [0x12243]={ category="lo", direction="l", }, - [0x13362]={ + [0x12244]={ category="lo", direction="l", }, - [0x13363]={ + [0x12245]={ category="lo", direction="l", }, - [0x13364]={ + [0x12246]={ category="lo", direction="l", }, - [0x13365]={ + [0x12247]={ category="lo", direction="l", }, - [0x13366]={ + [0x12248]={ category="lo", direction="l", }, - [0x13367]={ + [0x12249]={ category="lo", direction="l", }, - [0x13368]={ + [0x1224A]={ category="lo", direction="l", }, - [0x13369]={ + [0x1224B]={ category="lo", direction="l", }, - [0x1336A]={ + [0x1224C]={ category="lo", direction="l", }, - [0x1336B]={ + [0x1224D]={ category="lo", direction="l", }, - [0x1336C]={ + [0x1224E]={ category="lo", direction="l", }, - [0x1336D]={ + [0x1224F]={ category="lo", direction="l", }, - [0x1336E]={ + [0x12250]={ category="lo", direction="l", }, - [0x1336F]={ + [0x12251]={ category="lo", direction="l", }, - [0x13370]={ + [0x12252]={ category="lo", direction="l", }, - [0x13371]={ + [0x12253]={ category="lo", direction="l", }, - [0x13372]={ + [0x12254]={ category="lo", direction="l", }, - [0x13373]={ + [0x12255]={ category="lo", direction="l", }, - [0x13374]={ + [0x12256]={ category="lo", direction="l", }, - [0x13375]={ + [0x12257]={ category="lo", direction="l", }, - [0x13376]={ + [0x12258]={ category="lo", direction="l", }, - [0x13377]={ + [0x12259]={ category="lo", direction="l", }, - [0x13378]={ + [0x1225A]={ category="lo", direction="l", }, - [0x13379]={ + [0x1225B]={ category="lo", direction="l", }, - [0x1337A]={ + [0x1225C]={ category="lo", direction="l", }, - [0x1337B]={ + [0x1225D]={ category="lo", direction="l", }, - [0x1337C]={ + [0x1225E]={ category="lo", direction="l", }, - [0x1337D]={ + [0x1225F]={ category="lo", direction="l", }, - [0x1337E]={ + [0x12260]={ category="lo", direction="l", }, - [0x1337F]={ + [0x12261]={ category="lo", direction="l", }, - [0x13380]={ + [0x12262]={ category="lo", direction="l", }, - [0x13381]={ + [0x12263]={ category="lo", direction="l", }, - [0x13382]={ + [0x12264]={ category="lo", direction="l", }, - [0x13383]={ + [0x12265]={ category="lo", direction="l", }, - [0x13384]={ + [0x12266]={ category="lo", direction="l", }, - [0x13385]={ + [0x12267]={ category="lo", direction="l", }, - [0x13386]={ + [0x12268]={ category="lo", direction="l", }, - [0x13387]={ + [0x12269]={ category="lo", direction="l", }, - [0x13388]={ + [0x1226A]={ category="lo", direction="l", }, - [0x13389]={ + [0x1226B]={ category="lo", direction="l", }, - [0x1338A]={ + [0x1226C]={ category="lo", direction="l", }, - [0x1338B]={ + [0x1226D]={ category="lo", direction="l", }, - [0x1338C]={ + [0x1226E]={ category="lo", direction="l", }, - [0x1338D]={ + [0x1226F]={ category="lo", direction="l", }, - [0x1338E]={ + [0x12270]={ category="lo", direction="l", }, - [0x1338F]={ + [0x12271]={ category="lo", direction="l", }, - [0x13390]={ + [0x12272]={ category="lo", direction="l", }, - [0x13391]={ + [0x12273]={ category="lo", direction="l", }, - [0x13392]={ + [0x12274]={ category="lo", direction="l", }, - [0x13393]={ + [0x12275]={ category="lo", direction="l", }, - [0x13394]={ + [0x12276]={ category="lo", direction="l", }, - [0x13395]={ + [0x12277]={ category="lo", direction="l", }, - [0x13396]={ + [0x12278]={ category="lo", direction="l", }, - [0x13397]={ + [0x12279]={ category="lo", direction="l", }, - [0x13398]={ + [0x1227A]={ category="lo", direction="l", }, - [0x13399]={ + [0x1227B]={ category="lo", direction="l", }, - [0x1339A]={ + [0x1227C]={ category="lo", direction="l", }, - [0x1339B]={ + [0x1227D]={ category="lo", direction="l", }, - [0x1339C]={ + [0x1227E]={ category="lo", direction="l", }, - [0x1339D]={ + [0x1227F]={ category="lo", direction="l", }, - [0x1339E]={ + [0x12280]={ category="lo", direction="l", }, - [0x1339F]={ + [0x12281]={ category="lo", direction="l", }, - [0x133A0]={ + [0x12282]={ category="lo", direction="l", }, - [0x133A1]={ + [0x12283]={ category="lo", direction="l", }, - [0x133A2]={ + [0x12284]={ category="lo", direction="l", }, - [0x133A3]={ + [0x12285]={ category="lo", direction="l", }, - [0x133A4]={ + [0x12286]={ category="lo", direction="l", }, - [0x133A5]={ + [0x12287]={ category="lo", direction="l", }, - [0x133A6]={ + [0x12288]={ category="lo", direction="l", }, - [0x133A7]={ + [0x12289]={ category="lo", direction="l", }, - [0x133A8]={ + [0x1228A]={ category="lo", direction="l", }, - [0x133A9]={ + [0x1228B]={ category="lo", direction="l", }, - [0x133AA]={ + [0x1228C]={ category="lo", direction="l", }, - [0x133AB]={ + [0x1228D]={ category="lo", direction="l", }, - [0x133AC]={ + [0x1228E]={ category="lo", direction="l", }, - [0x133AD]={ + [0x1228F]={ category="lo", direction="l", }, - [0x133AE]={ + [0x12290]={ category="lo", direction="l", }, - [0x133AF]={ + [0x12291]={ category="lo", direction="l", }, - [0x133B0]={ + [0x12292]={ category="lo", direction="l", }, - [0x133B1]={ + [0x12293]={ category="lo", direction="l", }, - [0x133B2]={ + [0x12294]={ category="lo", direction="l", }, - [0x133B3]={ + [0x12295]={ category="lo", direction="l", }, - [0x133B4]={ + [0x12296]={ category="lo", direction="l", }, - [0x133B5]={ + [0x12297]={ category="lo", direction="l", }, - [0x133B6]={ + [0x12298]={ category="lo", direction="l", }, - [0x133B7]={ + [0x12299]={ category="lo", direction="l", }, - [0x133B8]={ + [0x1229A]={ category="lo", direction="l", }, - [0x133B9]={ + [0x1229B]={ category="lo", direction="l", }, - [0x133BA]={ + [0x1229C]={ category="lo", direction="l", }, - [0x133BB]={ + [0x1229D]={ category="lo", direction="l", }, - [0x133BC]={ + [0x1229E]={ category="lo", direction="l", }, - [0x133BD]={ + [0x1229F]={ category="lo", direction="l", }, - [0x133BE]={ + [0x122A0]={ category="lo", direction="l", }, - [0x133BF]={ + [0x122A1]={ category="lo", direction="l", }, - [0x133C0]={ + [0x122A2]={ category="lo", direction="l", }, - [0x133C1]={ + [0x122A3]={ category="lo", direction="l", }, - [0x133C2]={ + [0x122A4]={ category="lo", direction="l", }, - [0x133C3]={ + [0x122A5]={ category="lo", direction="l", }, - [0x133C4]={ + [0x122A6]={ category="lo", direction="l", }, - [0x133C5]={ + [0x122A7]={ category="lo", direction="l", }, - [0x133C6]={ + [0x122A8]={ category="lo", direction="l", }, - [0x133C7]={ + [0x122A9]={ category="lo", direction="l", }, - [0x133C8]={ + [0x122AA]={ category="lo", direction="l", }, - [0x133C9]={ + [0x122AB]={ category="lo", direction="l", }, - [0x133CA]={ + [0x122AC]={ category="lo", direction="l", }, - [0x133CB]={ + [0x122AD]={ category="lo", direction="l", }, - [0x133CC]={ + [0x122AE]={ category="lo", direction="l", }, - [0x133CD]={ + [0x122AF]={ category="lo", direction="l", }, - [0x133CE]={ + [0x122B0]={ category="lo", direction="l", }, - [0x133CF]={ + [0x122B1]={ category="lo", direction="l", }, - [0x133D0]={ + [0x122B2]={ category="lo", direction="l", }, - [0x133D1]={ + [0x122B3]={ category="lo", direction="l", }, - [0x133D2]={ + [0x122B4]={ category="lo", direction="l", }, - [0x133D3]={ + [0x122B5]={ category="lo", direction="l", }, - [0x133D4]={ + [0x122B6]={ category="lo", direction="l", }, - [0x133D5]={ + [0x122B7]={ category="lo", direction="l", }, - [0x133D6]={ + [0x122B8]={ category="lo", direction="l", }, - [0x133D7]={ + [0x122B9]={ category="lo", direction="l", }, - [0x133D8]={ + [0x122BA]={ category="lo", direction="l", }, - [0x133D9]={ + [0x122BB]={ category="lo", direction="l", }, - [0x133DA]={ + [0x122BC]={ category="lo", direction="l", }, - [0x133DB]={ + [0x122BD]={ category="lo", direction="l", }, - [0x133DC]={ + [0x122BE]={ category="lo", direction="l", }, - [0x133DD]={ + [0x122BF]={ category="lo", direction="l", }, - [0x133DE]={ + [0x122C0]={ category="lo", direction="l", }, - [0x133DF]={ + [0x122C1]={ category="lo", direction="l", }, - [0x133E0]={ + [0x122C2]={ category="lo", direction="l", }, - [0x133E1]={ + [0x122C3]={ category="lo", direction="l", }, - [0x133E2]={ + [0x122C4]={ category="lo", direction="l", }, - [0x133E3]={ + [0x122C5]={ category="lo", direction="l", }, - [0x133E4]={ + [0x122C6]={ category="lo", direction="l", }, - [0x133E5]={ + [0x122C7]={ category="lo", direction="l", }, - [0x133E6]={ + [0x122C8]={ category="lo", direction="l", }, - [0x133E7]={ + [0x122C9]={ category="lo", direction="l", }, - [0x133E8]={ + [0x122CA]={ category="lo", direction="l", }, - [0x133E9]={ + [0x122CB]={ category="lo", direction="l", }, - [0x133EA]={ + [0x122CC]={ category="lo", direction="l", }, - [0x133EB]={ + [0x122CD]={ category="lo", direction="l", }, - [0x133EC]={ + [0x122CE]={ category="lo", direction="l", }, - [0x133ED]={ + [0x122CF]={ category="lo", direction="l", }, - [0x133EE]={ + [0x122D0]={ category="lo", direction="l", }, - [0x133EF]={ + [0x122D1]={ category="lo", direction="l", }, - [0x133F0]={ + [0x122D2]={ category="lo", direction="l", }, - [0x133F1]={ + [0x122D3]={ category="lo", direction="l", }, - [0x133F2]={ + [0x122D4]={ category="lo", direction="l", }, - [0x133F3]={ + [0x122D5]={ category="lo", direction="l", }, - [0x133F4]={ + [0x122D6]={ category="lo", direction="l", }, - [0x133F5]={ + [0x122D7]={ category="lo", direction="l", }, - [0x133F6]={ + [0x122D8]={ category="lo", direction="l", }, - [0x133F7]={ + [0x122D9]={ category="lo", direction="l", }, - [0x133F8]={ + [0x122DA]={ category="lo", direction="l", }, - [0x133F9]={ + [0x122DB]={ category="lo", direction="l", }, - [0x133FA]={ + [0x122DC]={ category="lo", direction="l", }, - [0x133FB]={ + [0x122DD]={ category="lo", direction="l", }, - [0x133FC]={ + [0x122DE]={ category="lo", direction="l", }, - [0x133FD]={ + [0x122DF]={ category="lo", direction="l", }, - [0x133FE]={ + [0x122E0]={ category="lo", direction="l", }, - [0x133FF]={ + [0x122E1]={ category="lo", direction="l", }, - [0x13400]={ + [0x122E2]={ category="lo", direction="l", }, - [0x13401]={ + [0x122E3]={ category="lo", direction="l", }, - [0x13402]={ + [0x122E4]={ category="lo", direction="l", }, - [0x13403]={ + [0x122E5]={ category="lo", direction="l", }, - [0x13404]={ + [0x122E6]={ category="lo", direction="l", }, - [0x13405]={ + [0x122E7]={ category="lo", direction="l", }, - [0x13406]={ + [0x122E8]={ category="lo", direction="l", }, - [0x13407]={ + [0x122E9]={ category="lo", direction="l", }, - [0x13408]={ + [0x122EA]={ category="lo", direction="l", }, - [0x13409]={ + [0x122EB]={ category="lo", direction="l", }, - [0x1340A]={ + [0x122EC]={ category="lo", direction="l", }, - [0x1340B]={ + [0x122ED]={ category="lo", direction="l", }, - [0x1340C]={ + [0x122EE]={ category="lo", direction="l", }, - [0x1340D]={ + [0x122EF]={ category="lo", direction="l", }, - [0x1340E]={ + [0x122F0]={ category="lo", direction="l", }, - [0x1340F]={ + [0x122F1]={ category="lo", direction="l", }, - [0x13410]={ + [0x122F2]={ category="lo", direction="l", }, - [0x13411]={ + [0x122F3]={ category="lo", direction="l", }, - [0x13412]={ + [0x122F4]={ category="lo", direction="l", }, - [0x13413]={ + [0x122F5]={ category="lo", direction="l", }, - [0x13414]={ + [0x122F6]={ category="lo", direction="l", }, - [0x13415]={ + [0x122F7]={ category="lo", direction="l", }, - [0x13416]={ + [0x122F8]={ category="lo", direction="l", }, - [0x13417]={ + [0x122F9]={ category="lo", direction="l", }, - [0x13418]={ + [0x122FA]={ category="lo", direction="l", }, - [0x13419]={ + [0x122FB]={ category="lo", direction="l", }, - [0x1341A]={ + [0x122FC]={ category="lo", direction="l", }, - [0x1341B]={ + [0x122FD]={ category="lo", direction="l", }, - [0x1341C]={ + [0x122FE]={ category="lo", direction="l", }, - [0x1341D]={ + [0x122FF]={ category="lo", direction="l", }, - [0x1341E]={ + [0x12300]={ category="lo", direction="l", }, - [0x1341F]={ + [0x12301]={ category="lo", direction="l", }, - [0x13420]={ + [0x12302]={ category="lo", direction="l", }, - [0x13421]={ + [0x12303]={ category="lo", direction="l", }, - [0x13422]={ + [0x12304]={ category="lo", direction="l", }, - [0x13423]={ + [0x12305]={ category="lo", direction="l", }, - [0x13424]={ + [0x12306]={ category="lo", direction="l", }, - [0x13425]={ + [0x12307]={ category="lo", direction="l", }, - [0x13426]={ + [0x12308]={ category="lo", direction="l", }, - [0x13427]={ + [0x12309]={ category="lo", direction="l", }, - [0x13428]={ + [0x1230A]={ category="lo", direction="l", }, - [0x13429]={ + [0x1230B]={ category="lo", direction="l", }, - [0x1342A]={ + [0x1230C]={ category="lo", direction="l", }, - [0x1342B]={ + [0x1230D]={ category="lo", direction="l", }, - [0x1342C]={ + [0x1230E]={ category="lo", direction="l", }, - [0x1342D]={ + [0x1230F]={ category="lo", direction="l", }, - [0x1342E]={ + [0x12310]={ category="lo", direction="l", }, - [0x16800]={ + [0x12311]={ category="lo", direction="l", }, - [0x16801]={ + [0x12312]={ category="lo", direction="l", }, - [0x16802]={ + [0x12313]={ category="lo", direction="l", }, - [0x16803]={ + [0x12314]={ category="lo", direction="l", }, - [0x16804]={ + [0x12315]={ category="lo", direction="l", }, - [0x16805]={ + [0x12316]={ category="lo", direction="l", }, - [0x16806]={ + [0x12317]={ category="lo", direction="l", }, - [0x16807]={ + [0x12318]={ category="lo", direction="l", }, - [0x16808]={ + [0x12319]={ category="lo", direction="l", }, - [0x16809]={ + [0x1231A]={ category="lo", direction="l", }, - [0x1680A]={ + [0x1231B]={ category="lo", direction="l", }, - [0x1680B]={ + [0x1231C]={ category="lo", direction="l", }, - [0x1680C]={ + [0x1231D]={ category="lo", direction="l", }, - [0x1680D]={ + [0x1231E]={ category="lo", direction="l", }, - [0x1680E]={ + [0x1231F]={ category="lo", direction="l", }, - [0x1680F]={ + [0x12320]={ category="lo", direction="l", }, - [0x16810]={ + [0x12321]={ category="lo", direction="l", }, - [0x16811]={ + [0x12322]={ category="lo", direction="l", }, - [0x16812]={ + [0x12323]={ category="lo", direction="l", }, - [0x16813]={ + [0x12324]={ category="lo", direction="l", }, - [0x16814]={ + [0x12325]={ category="lo", direction="l", }, - [0x16815]={ + [0x12326]={ category="lo", direction="l", }, - [0x16816]={ + [0x12327]={ category="lo", direction="l", }, - [0x16817]={ + [0x12328]={ category="lo", direction="l", }, - [0x16818]={ + [0x12329]={ category="lo", direction="l", }, - [0x16819]={ + [0x1232A]={ category="lo", direction="l", }, - [0x1681A]={ + [0x1232B]={ category="lo", direction="l", }, - [0x1681B]={ + [0x1232C]={ category="lo", direction="l", }, - [0x1681C]={ + [0x1232D]={ category="lo", direction="l", }, - [0x1681D]={ + [0x1232E]={ category="lo", direction="l", }, - [0x1681E]={ + [0x1232F]={ category="lo", direction="l", }, - [0x1681F]={ + [0x12330]={ category="lo", direction="l", }, - [0x16820]={ + [0x12331]={ category="lo", direction="l", }, - [0x16821]={ + [0x12332]={ category="lo", direction="l", }, - [0x16822]={ + [0x12333]={ category="lo", direction="l", }, - [0x16823]={ + [0x12334]={ category="lo", direction="l", }, - [0x16824]={ + [0x12335]={ category="lo", direction="l", }, - [0x16825]={ + [0x12336]={ category="lo", direction="l", }, - [0x16826]={ + [0x12337]={ category="lo", direction="l", }, - [0x16827]={ + [0x12338]={ category="lo", direction="l", }, - [0x16828]={ + [0x12339]={ category="lo", direction="l", }, - [0x16829]={ + [0x1233A]={ category="lo", direction="l", }, - [0x1682A]={ + [0x1233B]={ category="lo", direction="l", }, - [0x1682B]={ + [0x1233C]={ category="lo", direction="l", }, - [0x1682C]={ + [0x1233D]={ category="lo", direction="l", }, - [0x1682D]={ + [0x1233E]={ category="lo", direction="l", }, - [0x1682E]={ + [0x1233F]={ category="lo", direction="l", }, - [0x1682F]={ + [0x12340]={ category="lo", direction="l", }, - [0x16830]={ + [0x12341]={ category="lo", direction="l", }, - [0x16831]={ + [0x12342]={ category="lo", direction="l", }, - [0x16832]={ + [0x12343]={ category="lo", direction="l", }, - [0x16833]={ + [0x12344]={ category="lo", direction="l", }, - [0x16834]={ + [0x12345]={ category="lo", direction="l", }, - [0x16835]={ + [0x12346]={ category="lo", direction="l", }, - [0x16836]={ + [0x12347]={ category="lo", direction="l", }, - [0x16837]={ + [0x12348]={ category="lo", direction="l", }, - [0x16838]={ + [0x12349]={ category="lo", direction="l", }, - [0x16839]={ + [0x1234A]={ category="lo", direction="l", }, - [0x1683A]={ + [0x1234B]={ category="lo", direction="l", }, - [0x1683B]={ + [0x1234C]={ category="lo", direction="l", }, - [0x1683C]={ + [0x1234D]={ category="lo", direction="l", }, - [0x1683D]={ + [0x1234E]={ category="lo", direction="l", }, - [0x1683E]={ + [0x1234F]={ category="lo", direction="l", }, - [0x1683F]={ + [0x12350]={ category="lo", direction="l", }, - [0x16840]={ + [0x12351]={ category="lo", direction="l", }, - [0x16841]={ + [0x12352]={ category="lo", direction="l", }, - [0x16842]={ + [0x12353]={ category="lo", direction="l", }, - [0x16843]={ + [0x12354]={ category="lo", direction="l", }, - [0x16844]={ + [0x12355]={ category="lo", direction="l", }, - [0x16845]={ + [0x12356]={ category="lo", direction="l", }, - [0x16846]={ + [0x12357]={ category="lo", direction="l", }, - [0x16847]={ + [0x12358]={ category="lo", direction="l", }, - [0x16848]={ + [0x12359]={ category="lo", direction="l", }, - [0x16849]={ + [0x1235A]={ category="lo", direction="l", }, - [0x1684A]={ + [0x1235B]={ category="lo", direction="l", }, - [0x1684B]={ + [0x1235C]={ category="lo", direction="l", }, - [0x1684C]={ + [0x1235D]={ category="lo", direction="l", }, - [0x1684D]={ + [0x1235E]={ category="lo", direction="l", }, - [0x1684E]={ + [0x1235F]={ category="lo", direction="l", }, - [0x1684F]={ + [0x12360]={ category="lo", direction="l", }, - [0x16850]={ + [0x12361]={ category="lo", direction="l", }, - [0x16851]={ + [0x12362]={ category="lo", direction="l", }, - [0x16852]={ + [0x12363]={ category="lo", direction="l", }, - [0x16853]={ + [0x12364]={ category="lo", direction="l", }, - [0x16854]={ + [0x12365]={ category="lo", direction="l", }, - [0x16855]={ + [0x12366]={ category="lo", direction="l", }, - [0x16856]={ + [0x12367]={ category="lo", direction="l", }, - [0x16857]={ + [0x12368]={ category="lo", direction="l", }, - [0x16858]={ + [0x12369]={ category="lo", direction="l", }, - [0x16859]={ + [0x1236A]={ category="lo", direction="l", }, - [0x1685A]={ + [0x1236B]={ category="lo", direction="l", }, - [0x1685B]={ + [0x1236C]={ category="lo", direction="l", }, - [0x1685C]={ + [0x1236D]={ category="lo", direction="l", }, - [0x1685D]={ + [0x1236E]={ category="lo", direction="l", }, - [0x1685E]={ + [0x1236F]={ category="lo", direction="l", }, - [0x1685F]={ + [0x12370]={ category="lo", direction="l", }, - [0x16860]={ + [0x12371]={ category="lo", direction="l", }, - [0x16861]={ + [0x12372]={ category="lo", direction="l", }, - [0x16862]={ + [0x12373]={ category="lo", direction="l", }, - [0x16863]={ + [0x12374]={ category="lo", direction="l", }, - [0x16864]={ + [0x12375]={ category="lo", direction="l", }, - [0x16865]={ + [0x12376]={ category="lo", direction="l", }, - [0x16866]={ + [0x12377]={ category="lo", direction="l", }, - [0x16867]={ + [0x12378]={ category="lo", direction="l", }, - [0x16868]={ + [0x12379]={ category="lo", direction="l", }, - [0x16869]={ + [0x1237A]={ category="lo", direction="l", }, - [0x1686A]={ + [0x1237B]={ category="lo", direction="l", }, - [0x1686B]={ + [0x1237C]={ category="lo", direction="l", }, - [0x1686C]={ + [0x1237D]={ category="lo", direction="l", }, - [0x1686D]={ + [0x1237E]={ category="lo", direction="l", }, - [0x1686E]={ + [0x1237F]={ category="lo", direction="l", }, - [0x1686F]={ + [0x12380]={ category="lo", direction="l", }, - [0x16870]={ + [0x12381]={ category="lo", direction="l", }, - [0x16871]={ + [0x12382]={ category="lo", direction="l", }, - [0x16872]={ + [0x12383]={ category="lo", direction="l", }, - [0x16873]={ + [0x12384]={ category="lo", direction="l", }, - [0x16874]={ + [0x12385]={ category="lo", direction="l", }, - [0x16875]={ + [0x12386]={ category="lo", direction="l", }, - [0x16876]={ + [0x12387]={ category="lo", direction="l", }, - [0x16877]={ + [0x12388]={ category="lo", direction="l", }, - [0x16878]={ + [0x12389]={ category="lo", direction="l", }, - [0x16879]={ + [0x1238A]={ category="lo", direction="l", }, - [0x1687A]={ + [0x1238B]={ category="lo", direction="l", }, - [0x1687B]={ + [0x1238C]={ category="lo", direction="l", }, - [0x1687C]={ + [0x1238D]={ category="lo", direction="l", }, - [0x1687D]={ + [0x1238E]={ category="lo", direction="l", }, - [0x1687E]={ + [0x1238F]={ category="lo", direction="l", }, - [0x1687F]={ + [0x12390]={ category="lo", direction="l", }, - [0x16880]={ + [0x12391]={ category="lo", direction="l", }, - [0x16881]={ + [0x12392]={ category="lo", direction="l", }, - [0x16882]={ + [0x12393]={ category="lo", direction="l", }, - [0x16883]={ + [0x12394]={ category="lo", direction="l", }, - [0x16884]={ + [0x12395]={ category="lo", direction="l", }, - [0x16885]={ + [0x12396]={ category="lo", direction="l", }, - [0x16886]={ + [0x12397]={ category="lo", direction="l", }, - [0x16887]={ + [0x12398]={ category="lo", direction="l", }, - [0x16888]={ - category="lo", + [0x12400]={ + category="nl", direction="l", }, - [0x16889]={ - category="lo", + [0x12401]={ + category="nl", direction="l", }, - [0x1688A]={ - category="lo", + [0x12402]={ + category="nl", direction="l", }, - [0x1688B]={ - category="lo", + [0x12403]={ + category="nl", direction="l", }, - [0x1688C]={ - category="lo", + [0x12404]={ + category="nl", direction="l", }, - [0x1688D]={ - category="lo", + [0x12405]={ + category="nl", direction="l", }, - [0x1688E]={ - category="lo", + [0x12406]={ + category="nl", direction="l", }, - [0x1688F]={ - category="lo", + [0x12407]={ + category="nl", direction="l", }, - [0x16890]={ - category="lo", + [0x12408]={ + category="nl", direction="l", }, - [0x16891]={ - category="lo", + [0x12409]={ + category="nl", direction="l", }, - [0x16892]={ - category="lo", + [0x1240A]={ + category="nl", direction="l", }, - [0x16893]={ - category="lo", + [0x1240B]={ + category="nl", direction="l", }, - [0x16894]={ - category="lo", + [0x1240C]={ + category="nl", direction="l", }, - [0x16895]={ - category="lo", + [0x1240D]={ + category="nl", direction="l", }, - [0x16896]={ - category="lo", + [0x1240E]={ + category="nl", direction="l", }, - [0x16897]={ - category="lo", + [0x1240F]={ + category="nl", direction="l", }, - [0x16898]={ - category="lo", + [0x12410]={ + category="nl", direction="l", }, - [0x16899]={ - category="lo", + [0x12411]={ + category="nl", direction="l", }, - [0x1689A]={ - category="lo", + [0x12412]={ + category="nl", direction="l", }, - [0x1689B]={ - category="lo", + [0x12413]={ + category="nl", direction="l", }, - [0x1689C]={ - category="lo", + [0x12414]={ + category="nl", direction="l", }, - [0x1689D]={ - category="lo", + [0x12415]={ + category="nl", direction="l", }, - [0x1689E]={ - category="lo", + [0x12416]={ + category="nl", direction="l", }, - [0x1689F]={ - category="lo", + [0x12417]={ + category="nl", direction="l", }, - [0x168A0]={ - category="lo", + [0x12418]={ + category="nl", direction="l", }, - [0x168A1]={ - category="lo", + [0x12419]={ + category="nl", direction="l", }, - [0x168A2]={ - category="lo", + [0x1241A]={ + category="nl", direction="l", }, - [0x168A3]={ - category="lo", + [0x1241B]={ + category="nl", direction="l", }, - [0x168A4]={ - category="lo", + [0x1241C]={ + category="nl", direction="l", }, - [0x168A5]={ - category="lo", + [0x1241D]={ + category="nl", direction="l", }, - [0x168A6]={ - category="lo", + [0x1241E]={ + category="nl", direction="l", }, - [0x168A7]={ - category="lo", + [0x1241F]={ + category="nl", direction="l", }, - [0x168A8]={ - category="lo", + [0x12420]={ + category="nl", direction="l", }, - [0x168A9]={ - category="lo", + [0x12421]={ + category="nl", direction="l", }, - [0x168AA]={ - category="lo", + [0x12422]={ + category="nl", direction="l", }, - [0x168AB]={ - category="lo", + [0x12423]={ + category="nl", direction="l", }, - [0x168AC]={ - category="lo", + [0x12424]={ + category="nl", direction="l", }, - [0x168AD]={ - category="lo", + [0x12425]={ + category="nl", direction="l", }, - [0x168AE]={ - category="lo", + [0x12426]={ + category="nl", direction="l", }, - [0x168AF]={ - category="lo", + [0x12427]={ + category="nl", direction="l", }, - [0x168B0]={ - category="lo", + [0x12428]={ + category="nl", direction="l", }, - [0x168B1]={ - category="lo", + [0x12429]={ + category="nl", direction="l", }, - [0x168B2]={ - category="lo", + [0x1242A]={ + category="nl", direction="l", }, - [0x168B3]={ - category="lo", + [0x1242B]={ + category="nl", direction="l", }, - [0x168B4]={ - category="lo", + [0x1242C]={ + category="nl", direction="l", }, - [0x168B5]={ - category="lo", + [0x1242D]={ + category="nl", direction="l", }, - [0x168B6]={ - category="lo", + [0x1242E]={ + category="nl", direction="l", }, - [0x168B7]={ - category="lo", + [0x1242F]={ + category="nl", direction="l", }, - [0x168B8]={ - category="lo", + [0x12430]={ + category="nl", direction="l", }, - [0x168B9]={ - category="lo", + [0x12431]={ + category="nl", direction="l", }, - [0x168BA]={ - category="lo", + [0x12432]={ + category="nl", direction="l", }, - [0x168BB]={ - category="lo", + [0x12433]={ + category="nl", direction="l", }, - [0x168BC]={ - category="lo", + [0x12434]={ + category="nl", direction="l", }, - [0x168BD]={ - category="lo", + [0x12435]={ + category="nl", direction="l", }, - [0x168BE]={ - category="lo", + [0x12436]={ + category="nl", direction="l", }, - [0x168BF]={ - category="lo", + [0x12437]={ + category="nl", direction="l", }, - [0x168C0]={ - category="lo", + [0x12438]={ + category="nl", direction="l", }, - [0x168C1]={ - category="lo", + [0x12439]={ + category="nl", direction="l", }, - [0x168C2]={ - category="lo", + [0x1243A]={ + category="nl", direction="l", }, - [0x168C3]={ - category="lo", + [0x1243B]={ + category="nl", direction="l", }, - [0x168C4]={ - category="lo", + [0x1243C]={ + category="nl", direction="l", }, - [0x168C5]={ - category="lo", + [0x1243D]={ + category="nl", direction="l", }, - [0x168C6]={ - category="lo", + [0x1243E]={ + category="nl", direction="l", }, - [0x168C7]={ - category="lo", + [0x1243F]={ + category="nl", direction="l", }, - [0x168C8]={ - category="lo", + [0x12440]={ + category="nl", direction="l", }, - [0x168C9]={ - category="lo", + [0x12441]={ + category="nl", direction="l", }, - [0x168CA]={ - category="lo", + [0x12442]={ + category="nl", direction="l", }, - [0x168CB]={ - category="lo", + [0x12443]={ + category="nl", direction="l", }, - [0x168CC]={ - category="lo", + [0x12444]={ + category="nl", direction="l", }, - [0x168CD]={ - category="lo", + [0x12445]={ + category="nl", direction="l", }, - [0x168CE]={ - category="lo", + [0x12446]={ + category="nl", direction="l", }, - [0x168CF]={ - category="lo", + [0x12447]={ + category="nl", direction="l", }, - [0x168D0]={ - category="lo", + [0x12448]={ + category="nl", direction="l", }, - [0x168D1]={ - category="lo", + [0x12449]={ + category="nl", direction="l", }, - [0x168D2]={ - category="lo", + [0x1244A]={ + category="nl", direction="l", }, - [0x168D3]={ - category="lo", + [0x1244B]={ + category="nl", direction="l", }, - [0x168D4]={ - category="lo", + [0x1244C]={ + category="nl", direction="l", }, - [0x168D5]={ - category="lo", + [0x1244D]={ + category="nl", direction="l", }, - [0x168D6]={ - category="lo", + [0x1244E]={ + category="nl", direction="l", }, - [0x168D7]={ - category="lo", + [0x1244F]={ + category="nl", direction="l", }, - [0x168D8]={ - category="lo", + [0x12450]={ + category="nl", direction="l", }, - [0x168D9]={ - category="lo", + [0x12451]={ + category="nl", direction="l", }, - [0x168DA]={ - category="lo", + [0x12452]={ + category="nl", direction="l", }, - [0x168DB]={ - category="lo", + [0x12453]={ + category="nl", direction="l", }, - [0x168DC]={ - category="lo", + [0x12454]={ + category="nl", direction="l", }, - [0x168DD]={ - category="lo", + [0x12455]={ + category="nl", direction="l", }, - [0x168DE]={ - category="lo", + [0x12456]={ + category="nl", direction="l", }, - [0x168DF]={ - category="lo", + [0x12457]={ + category="nl", direction="l", }, - [0x168E0]={ - category="lo", + [0x12458]={ + category="nl", direction="l", }, - [0x168E1]={ - category="lo", + [0x12459]={ + category="nl", direction="l", }, - [0x168E2]={ - category="lo", + [0x1245A]={ + category="nl", direction="l", }, - [0x168E3]={ - category="lo", + [0x1245B]={ + category="nl", direction="l", }, - [0x168E4]={ - category="lo", + [0x1245C]={ + category="nl", direction="l", }, - [0x168E5]={ - category="lo", + [0x1245D]={ + category="nl", direction="l", }, - [0x168E6]={ - category="lo", + [0x1245E]={ + category="nl", direction="l", }, - [0x168E7]={ - category="lo", + [0x1245F]={ + category="nl", direction="l", }, - [0x168E8]={ - category="lo", + [0x12460]={ + category="nl", direction="l", }, - [0x168E9]={ - category="lo", + [0x12461]={ + category="nl", direction="l", }, - [0x168EA]={ - category="lo", + [0x12462]={ + category="nl", direction="l", }, - [0x168EB]={ - category="lo", + [0x12463]={ + category="nl", direction="l", }, - [0x168EC]={ - category="lo", + [0x12464]={ + category="nl", direction="l", }, - [0x168ED]={ - category="lo", + [0x12465]={ + category="nl", direction="l", }, - [0x168EE]={ - category="lo", + [0x12466]={ + category="nl", direction="l", }, - [0x168EF]={ - category="lo", + [0x12467]={ + category="nl", direction="l", }, - [0x168F0]={ - category="lo", + [0x12468]={ + category="nl", direction="l", }, - [0x168F1]={ - category="lo", + [0x12469]={ + category="nl", direction="l", }, - [0x168F2]={ - category="lo", + [0x1246A]={ + category="nl", direction="l", }, - [0x168F3]={ - category="lo", + [0x1246B]={ + category="nl", direction="l", }, - [0x168F4]={ - category="lo", + [0x1246C]={ + category="nl", direction="l", }, - [0x168F5]={ - category="lo", + [0x1246D]={ + category="nl", direction="l", }, - [0x168F6]={ - category="lo", + [0x1246E]={ + category="nl", direction="l", }, - [0x168F7]={ - category="lo", + [0x12470]={ + category="po", direction="l", }, - [0x168F8]={ - category="lo", + [0x12471]={ + category="po", direction="l", }, - [0x168F9]={ - category="lo", + [0x12472]={ + category="po", direction="l", }, - [0x168FA]={ - category="lo", + [0x12473]={ + category="po", direction="l", }, - [0x168FB]={ - category="lo", + [0x12474]={ + category="po", direction="l", }, - [0x168FC]={ + [0x13000]={ category="lo", direction="l", }, - [0x168FD]={ + [0x13001]={ category="lo", direction="l", }, - [0x168FE]={ + [0x13002]={ category="lo", direction="l", }, - [0x168FF]={ + [0x13003]={ category="lo", direction="l", }, - [0x16900]={ + [0x13004]={ category="lo", direction="l", }, - [0x16901]={ + [0x13005]={ category="lo", direction="l", }, - [0x16902]={ + [0x13006]={ category="lo", direction="l", }, - [0x16903]={ + [0x13007]={ category="lo", direction="l", }, - [0x16904]={ + [0x13008]={ category="lo", direction="l", }, - [0x16905]={ + [0x13009]={ category="lo", direction="l", }, - [0x16906]={ + [0x1300A]={ category="lo", direction="l", }, - [0x16907]={ + [0x1300B]={ category="lo", direction="l", }, - [0x16908]={ + [0x1300C]={ category="lo", direction="l", }, - [0x16909]={ + [0x1300D]={ category="lo", direction="l", }, - [0x1690A]={ + [0x1300E]={ category="lo", direction="l", }, - [0x1690B]={ + [0x1300F]={ category="lo", direction="l", }, - [0x1690C]={ + [0x13010]={ category="lo", direction="l", }, - [0x1690D]={ + [0x13011]={ category="lo", direction="l", }, - [0x1690E]={ + [0x13012]={ category="lo", direction="l", }, - [0x1690F]={ + [0x13013]={ category="lo", direction="l", }, - [0x16910]={ + [0x13014]={ category="lo", direction="l", }, - [0x16911]={ + [0x13015]={ category="lo", direction="l", }, - [0x16912]={ + [0x13016]={ category="lo", direction="l", }, - [0x16913]={ + [0x13017]={ category="lo", direction="l", }, - [0x16914]={ + [0x13018]={ category="lo", direction="l", }, - [0x16915]={ + [0x13019]={ category="lo", direction="l", }, - [0x16916]={ + [0x1301A]={ category="lo", direction="l", }, - [0x16917]={ + [0x1301B]={ category="lo", direction="l", }, - [0x16918]={ + [0x1301C]={ category="lo", direction="l", }, - [0x16919]={ + [0x1301D]={ category="lo", direction="l", }, - [0x1691A]={ + [0x1301E]={ category="lo", direction="l", }, - [0x1691B]={ + [0x1301F]={ category="lo", direction="l", }, - [0x1691C]={ + [0x13020]={ category="lo", direction="l", }, - [0x1691D]={ + [0x13021]={ category="lo", direction="l", }, - [0x1691E]={ + [0x13022]={ category="lo", direction="l", }, - [0x1691F]={ + [0x13023]={ category="lo", direction="l", }, - [0x16920]={ + [0x13024]={ category="lo", direction="l", }, - [0x16921]={ + [0x13025]={ category="lo", direction="l", }, - [0x16922]={ + [0x13026]={ category="lo", direction="l", }, - [0x16923]={ + [0x13027]={ category="lo", direction="l", }, - [0x16924]={ + [0x13028]={ category="lo", direction="l", }, - [0x16925]={ + [0x13029]={ category="lo", direction="l", }, - [0x16926]={ + [0x1302A]={ category="lo", direction="l", }, - [0x16927]={ + [0x1302B]={ category="lo", direction="l", }, - [0x16928]={ + [0x1302C]={ category="lo", direction="l", }, - [0x16929]={ + [0x1302D]={ category="lo", direction="l", }, - [0x1692A]={ + [0x1302E]={ category="lo", direction="l", }, - [0x1692B]={ + [0x1302F]={ category="lo", direction="l", }, - [0x1692C]={ + [0x13030]={ category="lo", direction="l", }, - [0x1692D]={ + [0x13031]={ category="lo", direction="l", }, - [0x1692E]={ + [0x13032]={ category="lo", direction="l", }, - [0x1692F]={ + [0x13033]={ category="lo", direction="l", }, - [0x16930]={ + [0x13034]={ category="lo", direction="l", }, - [0x16931]={ + [0x13035]={ category="lo", direction="l", }, - [0x16932]={ + [0x13036]={ category="lo", direction="l", }, - [0x16933]={ + [0x13037]={ category="lo", direction="l", }, - [0x16934]={ + [0x13038]={ category="lo", direction="l", }, - [0x16935]={ + [0x13039]={ category="lo", direction="l", }, - [0x16936]={ + [0x1303A]={ category="lo", direction="l", }, - [0x16937]={ + [0x1303B]={ category="lo", direction="l", }, - [0x16938]={ + [0x1303C]={ category="lo", direction="l", }, - [0x16939]={ + [0x1303D]={ category="lo", direction="l", }, - [0x1693A]={ + [0x1303E]={ category="lo", direction="l", }, - [0x1693B]={ + [0x1303F]={ category="lo", direction="l", }, - [0x1693C]={ + [0x13040]={ category="lo", direction="l", }, - [0x1693D]={ + [0x13041]={ category="lo", direction="l", }, - [0x1693E]={ + [0x13042]={ category="lo", direction="l", }, - [0x1693F]={ + [0x13043]={ category="lo", direction="l", }, - [0x16940]={ + [0x13044]={ category="lo", direction="l", }, - [0x16941]={ + [0x13045]={ category="lo", direction="l", }, - [0x16942]={ + [0x13046]={ category="lo", direction="l", }, - [0x16943]={ + [0x13047]={ category="lo", direction="l", }, - [0x16944]={ + [0x13048]={ category="lo", direction="l", }, - [0x16945]={ + [0x13049]={ category="lo", direction="l", }, - [0x16946]={ + [0x1304A]={ category="lo", direction="l", }, - [0x16947]={ + [0x1304B]={ category="lo", direction="l", }, - [0x16948]={ + [0x1304C]={ category="lo", direction="l", }, - [0x16949]={ + [0x1304D]={ category="lo", direction="l", }, - [0x1694A]={ + [0x1304E]={ category="lo", direction="l", }, - [0x1694B]={ + [0x1304F]={ category="lo", direction="l", }, - [0x1694C]={ + [0x13050]={ category="lo", direction="l", }, - [0x1694D]={ + [0x13051]={ category="lo", direction="l", }, - [0x1694E]={ + [0x13052]={ category="lo", direction="l", }, - [0x1694F]={ + [0x13053]={ category="lo", direction="l", }, - [0x16950]={ + [0x13054]={ category="lo", direction="l", }, - [0x16951]={ + [0x13055]={ category="lo", direction="l", }, - [0x16952]={ + [0x13056]={ category="lo", direction="l", }, - [0x16953]={ + [0x13057]={ category="lo", direction="l", }, - [0x16954]={ + [0x13058]={ category="lo", direction="l", }, - [0x16955]={ + [0x13059]={ category="lo", direction="l", }, - [0x16956]={ + [0x1305A]={ category="lo", direction="l", }, - [0x16957]={ + [0x1305B]={ category="lo", direction="l", }, - [0x16958]={ + [0x1305C]={ category="lo", direction="l", }, - [0x16959]={ + [0x1305D]={ category="lo", direction="l", }, - [0x1695A]={ + [0x1305E]={ category="lo", direction="l", }, - [0x1695B]={ + [0x1305F]={ category="lo", direction="l", }, - [0x1695C]={ + [0x13060]={ category="lo", direction="l", }, - [0x1695D]={ + [0x13061]={ category="lo", direction="l", }, - [0x1695E]={ + [0x13062]={ category="lo", direction="l", }, - [0x1695F]={ + [0x13063]={ category="lo", direction="l", }, - [0x16960]={ + [0x13064]={ category="lo", direction="l", }, - [0x16961]={ + [0x13065]={ category="lo", direction="l", }, - [0x16962]={ + [0x13066]={ category="lo", direction="l", }, - [0x16963]={ + [0x13067]={ category="lo", direction="l", }, - [0x16964]={ + [0x13068]={ category="lo", direction="l", }, - [0x16965]={ + [0x13069]={ category="lo", direction="l", }, - [0x16966]={ + [0x1306A]={ category="lo", direction="l", }, - [0x16967]={ + [0x1306B]={ category="lo", direction="l", }, - [0x16968]={ + [0x1306C]={ category="lo", direction="l", }, - [0x16969]={ + [0x1306D]={ category="lo", direction="l", }, - [0x1696A]={ + [0x1306E]={ category="lo", direction="l", }, - [0x1696B]={ + [0x1306F]={ category="lo", direction="l", }, - [0x1696C]={ + [0x13070]={ category="lo", direction="l", }, - [0x1696D]={ + [0x13071]={ category="lo", direction="l", }, - [0x1696E]={ + [0x13072]={ category="lo", direction="l", }, - [0x1696F]={ + [0x13073]={ category="lo", direction="l", }, - [0x16970]={ + [0x13074]={ category="lo", direction="l", }, - [0x16971]={ + [0x13075]={ category="lo", direction="l", }, - [0x16972]={ + [0x13076]={ category="lo", direction="l", }, - [0x16973]={ + [0x13077]={ category="lo", direction="l", }, - [0x16974]={ + [0x13078]={ category="lo", direction="l", }, - [0x16975]={ + [0x13079]={ category="lo", direction="l", }, - [0x16976]={ + [0x1307A]={ category="lo", direction="l", }, - [0x16977]={ + [0x1307B]={ category="lo", direction="l", }, - [0x16978]={ + [0x1307C]={ category="lo", direction="l", }, - [0x16979]={ + [0x1307D]={ category="lo", direction="l", }, - [0x1697A]={ + [0x1307E]={ category="lo", direction="l", }, - [0x1697B]={ + [0x1307F]={ category="lo", direction="l", }, - [0x1697C]={ + [0x13080]={ category="lo", direction="l", }, - [0x1697D]={ + [0x13081]={ category="lo", direction="l", }, - [0x1697E]={ + [0x13082]={ category="lo", direction="l", }, - [0x1697F]={ + [0x13083]={ category="lo", direction="l", }, - [0x16980]={ + [0x13084]={ category="lo", direction="l", }, - [0x16981]={ + [0x13085]={ category="lo", direction="l", }, - [0x16982]={ + [0x13086]={ category="lo", direction="l", }, - [0x16983]={ + [0x13087]={ category="lo", direction="l", }, - [0x16984]={ + [0x13088]={ category="lo", direction="l", }, - [0x16985]={ + [0x13089]={ category="lo", direction="l", }, - [0x16986]={ + [0x1308A]={ category="lo", direction="l", }, - [0x16987]={ + [0x1308B]={ category="lo", direction="l", }, - [0x16988]={ + [0x1308C]={ category="lo", direction="l", }, - [0x16989]={ + [0x1308D]={ category="lo", direction="l", }, - [0x1698A]={ + [0x1308E]={ category="lo", direction="l", }, - [0x1698B]={ + [0x1308F]={ category="lo", direction="l", }, - [0x1698C]={ + [0x13090]={ category="lo", direction="l", }, - [0x1698D]={ + [0x13091]={ category="lo", direction="l", }, - [0x1698E]={ + [0x13092]={ category="lo", direction="l", }, - [0x1698F]={ + [0x13093]={ category="lo", direction="l", }, - [0x16990]={ + [0x13094]={ category="lo", direction="l", }, - [0x16991]={ + [0x13095]={ category="lo", direction="l", }, - [0x16992]={ + [0x13096]={ category="lo", direction="l", }, - [0x16993]={ + [0x13097]={ category="lo", direction="l", }, - [0x16994]={ + [0x13098]={ category="lo", direction="l", }, - [0x16995]={ + [0x13099]={ category="lo", direction="l", }, - [0x16996]={ + [0x1309A]={ category="lo", direction="l", }, - [0x16997]={ + [0x1309B]={ category="lo", direction="l", }, - [0x16998]={ + [0x1309C]={ category="lo", direction="l", }, - [0x16999]={ + [0x1309D]={ category="lo", direction="l", }, - [0x1699A]={ + [0x1309E]={ category="lo", direction="l", }, - [0x1699B]={ + [0x1309F]={ category="lo", direction="l", }, - [0x1699C]={ + [0x130A0]={ category="lo", direction="l", }, - [0x1699D]={ + [0x130A1]={ category="lo", direction="l", }, - [0x1699E]={ + [0x130A2]={ category="lo", direction="l", }, - [0x1699F]={ + [0x130A3]={ category="lo", direction="l", }, - [0x169A0]={ + [0x130A4]={ category="lo", direction="l", }, - [0x169A1]={ + [0x130A5]={ category="lo", direction="l", }, - [0x169A2]={ + [0x130A6]={ category="lo", direction="l", }, - [0x169A3]={ + [0x130A7]={ category="lo", direction="l", }, - [0x169A4]={ + [0x130A8]={ category="lo", direction="l", }, - [0x169A5]={ + [0x130A9]={ category="lo", direction="l", }, - [0x169A6]={ + [0x130AA]={ category="lo", direction="l", }, - [0x169A7]={ + [0x130AB]={ category="lo", direction="l", }, - [0x169A8]={ + [0x130AC]={ category="lo", direction="l", }, - [0x169A9]={ + [0x130AD]={ category="lo", direction="l", }, - [0x169AA]={ + [0x130AE]={ category="lo", direction="l", }, - [0x169AB]={ + [0x130AF]={ category="lo", direction="l", }, - [0x169AC]={ + [0x130B0]={ category="lo", direction="l", }, - [0x169AD]={ + [0x130B1]={ category="lo", direction="l", }, - [0x169AE]={ + [0x130B2]={ category="lo", direction="l", }, - [0x169AF]={ + [0x130B3]={ category="lo", direction="l", }, - [0x169B0]={ + [0x130B4]={ category="lo", direction="l", }, - [0x169B1]={ + [0x130B5]={ category="lo", direction="l", }, - [0x169B2]={ + [0x130B6]={ category="lo", direction="l", }, - [0x169B3]={ + [0x130B7]={ category="lo", direction="l", }, - [0x169B4]={ + [0x130B8]={ category="lo", direction="l", }, - [0x169B5]={ + [0x130B9]={ category="lo", direction="l", }, - [0x169B6]={ + [0x130BA]={ category="lo", direction="l", }, - [0x169B7]={ + [0x130BB]={ category="lo", direction="l", }, - [0x169B8]={ + [0x130BC]={ category="lo", direction="l", }, - [0x169B9]={ + [0x130BD]={ category="lo", direction="l", }, - [0x169BA]={ + [0x130BE]={ category="lo", direction="l", }, - [0x169BB]={ + [0x130BF]={ category="lo", direction="l", }, - [0x169BC]={ + [0x130C0]={ category="lo", direction="l", }, - [0x169BD]={ + [0x130C1]={ category="lo", direction="l", }, - [0x169BE]={ + [0x130C2]={ category="lo", direction="l", }, - [0x169BF]={ + [0x130C3]={ category="lo", direction="l", }, - [0x169C0]={ + [0x130C4]={ category="lo", direction="l", }, - [0x169C1]={ + [0x130C5]={ category="lo", direction="l", }, - [0x169C2]={ + [0x130C6]={ category="lo", direction="l", }, - [0x169C3]={ + [0x130C7]={ category="lo", direction="l", }, - [0x169C4]={ + [0x130C8]={ category="lo", direction="l", }, - [0x169C5]={ + [0x130C9]={ category="lo", direction="l", }, - [0x169C6]={ + [0x130CA]={ category="lo", direction="l", }, - [0x169C7]={ + [0x130CB]={ category="lo", direction="l", }, - [0x169C8]={ + [0x130CC]={ category="lo", direction="l", }, - [0x169C9]={ + [0x130CD]={ category="lo", direction="l", }, - [0x169CA]={ + [0x130CE]={ category="lo", direction="l", }, - [0x169CB]={ + [0x130CF]={ category="lo", direction="l", }, - [0x169CC]={ + [0x130D0]={ category="lo", direction="l", }, - [0x169CD]={ + [0x130D1]={ category="lo", direction="l", }, - [0x169CE]={ + [0x130D2]={ category="lo", direction="l", }, - [0x169CF]={ + [0x130D3]={ category="lo", direction="l", }, - [0x169D0]={ + [0x130D4]={ category="lo", direction="l", }, - [0x169D1]={ + [0x130D5]={ category="lo", direction="l", }, - [0x169D2]={ + [0x130D6]={ category="lo", direction="l", }, - [0x169D3]={ + [0x130D7]={ category="lo", direction="l", }, - [0x169D4]={ + [0x130D8]={ category="lo", direction="l", }, - [0x169D5]={ + [0x130D9]={ category="lo", direction="l", }, - [0x169D6]={ + [0x130DA]={ category="lo", direction="l", }, - [0x169D7]={ + [0x130DB]={ category="lo", direction="l", }, - [0x169D8]={ + [0x130DC]={ category="lo", direction="l", }, - [0x169D9]={ + [0x130DD]={ category="lo", direction="l", }, - [0x169DA]={ + [0x130DE]={ category="lo", direction="l", }, - [0x169DB]={ + [0x130DF]={ category="lo", direction="l", }, - [0x169DC]={ + [0x130E0]={ category="lo", direction="l", }, - [0x169DD]={ + [0x130E1]={ category="lo", direction="l", }, - [0x169DE]={ + [0x130E2]={ category="lo", direction="l", }, - [0x169DF]={ + [0x130E3]={ category="lo", direction="l", }, - [0x169E0]={ + [0x130E4]={ category="lo", direction="l", }, - [0x169E1]={ + [0x130E5]={ category="lo", direction="l", }, - [0x169E2]={ + [0x130E6]={ category="lo", direction="l", }, - [0x169E3]={ + [0x130E7]={ category="lo", direction="l", }, - [0x169E4]={ + [0x130E8]={ category="lo", direction="l", }, - [0x169E5]={ + [0x130E9]={ category="lo", direction="l", }, - [0x169E6]={ + [0x130EA]={ category="lo", direction="l", }, - [0x169E7]={ + [0x130EB]={ category="lo", direction="l", }, - [0x169E8]={ + [0x130EC]={ category="lo", direction="l", }, - [0x169E9]={ + [0x130ED]={ category="lo", direction="l", }, - [0x169EA]={ + [0x130EE]={ category="lo", direction="l", }, - [0x169EB]={ + [0x130EF]={ category="lo", direction="l", }, - [0x169EC]={ + [0x130F0]={ category="lo", direction="l", }, - [0x169ED]={ + [0x130F1]={ category="lo", direction="l", }, - [0x169EE]={ + [0x130F2]={ category="lo", direction="l", }, - [0x169EF]={ + [0x130F3]={ category="lo", direction="l", }, - [0x169F0]={ + [0x130F4]={ category="lo", direction="l", }, - [0x169F1]={ + [0x130F5]={ category="lo", direction="l", }, - [0x169F2]={ + [0x130F6]={ category="lo", direction="l", }, - [0x169F3]={ + [0x130F7]={ category="lo", direction="l", }, - [0x169F4]={ + [0x130F8]={ category="lo", direction="l", }, - [0x169F5]={ + [0x130F9]={ category="lo", direction="l", }, - [0x169F6]={ + [0x130FA]={ category="lo", direction="l", }, - [0x169F7]={ + [0x130FB]={ category="lo", direction="l", }, - [0x169F8]={ + [0x130FC]={ category="lo", direction="l", }, - [0x169F9]={ + [0x130FD]={ category="lo", direction="l", }, - [0x169FA]={ + [0x130FE]={ category="lo", direction="l", }, - [0x169FB]={ + [0x130FF]={ category="lo", direction="l", }, - [0x169FC]={ + [0x13100]={ category="lo", direction="l", }, - [0x169FD]={ + [0x13101]={ category="lo", direction="l", }, - [0x169FE]={ + [0x13102]={ category="lo", direction="l", }, - [0x169FF]={ + [0x13103]={ category="lo", direction="l", }, - [0x16A00]={ + [0x13104]={ category="lo", direction="l", }, - [0x16A01]={ + [0x13105]={ category="lo", direction="l", }, - [0x16A02]={ + [0x13106]={ category="lo", direction="l", }, - [0x16A03]={ + [0x13107]={ category="lo", direction="l", }, - [0x16A04]={ + [0x13108]={ category="lo", direction="l", }, - [0x16A05]={ + [0x13109]={ category="lo", direction="l", }, - [0x16A06]={ + [0x1310A]={ category="lo", direction="l", }, - [0x16A07]={ + [0x1310B]={ category="lo", direction="l", }, - [0x16A08]={ + [0x1310C]={ category="lo", direction="l", }, - [0x16A09]={ + [0x1310D]={ category="lo", direction="l", }, - [0x16A0A]={ + [0x1310E]={ category="lo", direction="l", }, - [0x16A0B]={ + [0x1310F]={ category="lo", direction="l", }, - [0x16A0C]={ + [0x13110]={ category="lo", direction="l", }, - [0x16A0D]={ + [0x13111]={ category="lo", direction="l", }, - [0x16A0E]={ + [0x13112]={ category="lo", direction="l", }, - [0x16A0F]={ + [0x13113]={ category="lo", direction="l", }, - [0x16A10]={ + [0x13114]={ category="lo", direction="l", }, - [0x16A11]={ + [0x13115]={ category="lo", direction="l", }, - [0x16A12]={ + [0x13116]={ category="lo", direction="l", }, - [0x16A13]={ + [0x13117]={ category="lo", direction="l", }, - [0x16A14]={ + [0x13118]={ category="lo", direction="l", }, - [0x16A15]={ + [0x13119]={ category="lo", direction="l", }, - [0x16A16]={ + [0x1311A]={ category="lo", direction="l", }, - [0x16A17]={ + [0x1311B]={ category="lo", direction="l", }, - [0x16A18]={ + [0x1311C]={ category="lo", direction="l", }, - [0x16A19]={ + [0x1311D]={ category="lo", direction="l", }, - [0x16A1A]={ + [0x1311E]={ category="lo", direction="l", }, - [0x16A1B]={ + [0x1311F]={ category="lo", direction="l", }, - [0x16A1C]={ + [0x13120]={ category="lo", direction="l", }, - [0x16A1D]={ + [0x13121]={ category="lo", direction="l", }, - [0x16A1E]={ + [0x13122]={ category="lo", direction="l", }, - [0x16A1F]={ + [0x13123]={ category="lo", direction="l", }, - [0x16A20]={ + [0x13124]={ category="lo", direction="l", }, - [0x16A21]={ + [0x13125]={ category="lo", direction="l", }, - [0x16A22]={ + [0x13126]={ category="lo", direction="l", }, - [0x16A23]={ + [0x13127]={ category="lo", direction="l", }, - [0x16A24]={ + [0x13128]={ category="lo", direction="l", }, - [0x16A25]={ + [0x13129]={ category="lo", direction="l", }, - [0x16A26]={ + [0x1312A]={ category="lo", direction="l", }, - [0x16A27]={ + [0x1312B]={ category="lo", direction="l", }, - [0x16A28]={ + [0x1312C]={ category="lo", direction="l", }, - [0x16A29]={ + [0x1312D]={ category="lo", direction="l", }, - [0x16A2A]={ + [0x1312E]={ category="lo", direction="l", }, - [0x16A2B]={ + [0x1312F]={ category="lo", direction="l", }, - [0x16A2C]={ + [0x13130]={ category="lo", direction="l", }, - [0x16A2D]={ + [0x13131]={ category="lo", direction="l", }, - [0x16A2E]={ + [0x13132]={ category="lo", direction="l", }, - [0x16A2F]={ + [0x13133]={ category="lo", direction="l", }, - [0x16A30]={ + [0x13134]={ category="lo", direction="l", }, - [0x16A31]={ + [0x13135]={ category="lo", direction="l", }, - [0x16A32]={ + [0x13136]={ category="lo", direction="l", }, - [0x16A33]={ + [0x13137]={ category="lo", direction="l", }, - [0x16A34]={ + [0x13138]={ category="lo", direction="l", }, - [0x16A35]={ + [0x13139]={ category="lo", direction="l", }, - [0x16A36]={ + [0x1313A]={ category="lo", direction="l", }, - [0x16A37]={ + [0x1313B]={ category="lo", direction="l", }, - [0x16A38]={ + [0x1313C]={ category="lo", direction="l", }, - [0x16F00]={ + [0x1313D]={ category="lo", direction="l", }, - [0x16F01]={ + [0x1313E]={ category="lo", direction="l", }, - [0x16F02]={ + [0x1313F]={ category="lo", direction="l", }, - [0x16F03]={ + [0x13140]={ category="lo", direction="l", }, - [0x16F04]={ + [0x13141]={ category="lo", direction="l", }, - [0x16F05]={ + [0x13142]={ category="lo", direction="l", }, - [0x16F06]={ + [0x13143]={ category="lo", direction="l", }, - [0x16F07]={ + [0x13144]={ category="lo", direction="l", }, - [0x16F08]={ + [0x13145]={ category="lo", direction="l", }, - [0x16F09]={ + [0x13146]={ category="lo", direction="l", }, - [0x16F0A]={ + [0x13147]={ category="lo", direction="l", }, - [0x16F0B]={ + [0x13148]={ category="lo", direction="l", }, - [0x16F0C]={ + [0x13149]={ category="lo", direction="l", }, - [0x16F0D]={ + [0x1314A]={ category="lo", direction="l", }, - [0x16F0E]={ + [0x1314B]={ category="lo", direction="l", }, - [0x16F0F]={ + [0x1314C]={ category="lo", direction="l", }, - [0x16F10]={ + [0x1314D]={ category="lo", direction="l", }, - [0x16F11]={ + [0x1314E]={ category="lo", direction="l", }, - [0x16F12]={ + [0x1314F]={ category="lo", direction="l", }, - [0x16F13]={ + [0x13150]={ category="lo", direction="l", }, - [0x16F14]={ + [0x13151]={ category="lo", direction="l", }, - [0x16F15]={ + [0x13152]={ category="lo", direction="l", }, - [0x16F16]={ + [0x13153]={ category="lo", direction="l", }, - [0x16F17]={ + [0x13154]={ category="lo", direction="l", }, - [0x16F18]={ + [0x13155]={ category="lo", direction="l", }, - [0x16F19]={ + [0x13156]={ category="lo", direction="l", }, - [0x16F1A]={ + [0x13157]={ category="lo", direction="l", }, - [0x16F1B]={ + [0x13158]={ category="lo", direction="l", }, - [0x16F1C]={ + [0x13159]={ category="lo", direction="l", }, - [0x16F1D]={ + [0x1315A]={ category="lo", direction="l", }, - [0x16F1E]={ + [0x1315B]={ category="lo", direction="l", }, - [0x16F1F]={ + [0x1315C]={ category="lo", direction="l", }, - [0x16F20]={ + [0x1315D]={ category="lo", direction="l", }, - [0x16F21]={ + [0x1315E]={ category="lo", direction="l", }, - [0x16F22]={ + [0x1315F]={ category="lo", direction="l", }, - [0x16F23]={ + [0x13160]={ category="lo", direction="l", }, - [0x16F24]={ + [0x13161]={ category="lo", direction="l", }, - [0x16F25]={ + [0x13162]={ category="lo", direction="l", }, - [0x16F26]={ + [0x13163]={ category="lo", direction="l", }, - [0x16F27]={ + [0x13164]={ category="lo", direction="l", }, - [0x16F28]={ + [0x13165]={ category="lo", direction="l", }, - [0x16F29]={ + [0x13166]={ category="lo", direction="l", }, - [0x16F2A]={ + [0x13167]={ category="lo", direction="l", }, - [0x16F2B]={ + [0x13168]={ category="lo", direction="l", }, - [0x16F2C]={ + [0x13169]={ category="lo", direction="l", }, - [0x16F2D]={ + [0x1316A]={ category="lo", direction="l", }, - [0x16F2E]={ + [0x1316B]={ category="lo", direction="l", }, - [0x16F2F]={ + [0x1316C]={ category="lo", direction="l", }, - [0x16F30]={ + [0x1316D]={ category="lo", direction="l", }, - [0x16F31]={ + [0x1316E]={ category="lo", direction="l", }, - [0x16F32]={ + [0x1316F]={ category="lo", direction="l", }, - [0x16F33]={ + [0x13170]={ category="lo", direction="l", }, - [0x16F34]={ + [0x13171]={ category="lo", direction="l", }, - [0x16F35]={ + [0x13172]={ category="lo", direction="l", }, - [0x16F36]={ + [0x13173]={ category="lo", direction="l", }, - [0x16F37]={ + [0x13174]={ category="lo", direction="l", }, - [0x16F38]={ + [0x13175]={ category="lo", direction="l", }, - [0x16F39]={ + [0x13176]={ category="lo", direction="l", }, - [0x16F3A]={ + [0x13177]={ category="lo", direction="l", }, - [0x16F3B]={ + [0x13178]={ category="lo", direction="l", }, - [0x16F3C]={ + [0x13179]={ category="lo", direction="l", }, - [0x16F3D]={ + [0x1317A]={ category="lo", direction="l", }, - [0x16F3E]={ + [0x1317B]={ category="lo", direction="l", }, - [0x16F3F]={ + [0x1317C]={ category="lo", direction="l", }, - [0x16F40]={ + [0x1317D]={ category="lo", direction="l", }, - [0x16F41]={ + [0x1317E]={ category="lo", direction="l", }, - [0x16F42]={ + [0x1317F]={ category="lo", direction="l", }, - [0x16F43]={ + [0x13180]={ category="lo", direction="l", }, - [0x16F44]={ + [0x13181]={ category="lo", direction="l", }, - [0x16F50]={ + [0x13182]={ category="lo", direction="l", }, - [0x16F51]={ - category="mc", + [0x13183]={ + category="lo", direction="l", }, - [0x16F52]={ - category="mc", + [0x13184]={ + category="lo", direction="l", }, - [0x16F53]={ - category="mc", + [0x13185]={ + category="lo", direction="l", }, - [0x16F54]={ - category="mc", + [0x13186]={ + category="lo", direction="l", }, - [0x16F55]={ - category="mc", + [0x13187]={ + category="lo", direction="l", }, - [0x16F56]={ - category="mc", + [0x13188]={ + category="lo", direction="l", }, - [0x16F57]={ - category="mc", + [0x13189]={ + category="lo", direction="l", }, - [0x16F58]={ - category="mc", + [0x1318A]={ + category="lo", direction="l", }, - [0x16F59]={ - category="mc", + [0x1318B]={ + category="lo", direction="l", }, - [0x16F5A]={ - category="mc", + [0x1318C]={ + category="lo", direction="l", }, - [0x16F5B]={ - category="mc", + [0x1318D]={ + category="lo", direction="l", }, - [0x16F5C]={ - category="mc", + [0x1318E]={ + category="lo", direction="l", }, - [0x16F5D]={ - category="mc", + [0x1318F]={ + category="lo", direction="l", }, - [0x16F5E]={ - category="mc", + [0x13190]={ + category="lo", direction="l", }, - [0x16F5F]={ - category="mc", + [0x13191]={ + category="lo", direction="l", }, - [0x16F60]={ - category="mc", + [0x13192]={ + category="lo", direction="l", }, - [0x16F61]={ - category="mc", + [0x13193]={ + category="lo", direction="l", }, - [0x16F62]={ - category="mc", + [0x13194]={ + category="lo", direction="l", }, - [0x16F63]={ - category="mc", + [0x13195]={ + category="lo", direction="l", }, - [0x16F64]={ - category="mc", + [0x13196]={ + category="lo", direction="l", }, - [0x16F65]={ - category="mc", + [0x13197]={ + category="lo", direction="l", }, - [0x16F66]={ - category="mc", + [0x13198]={ + category="lo", direction="l", }, - [0x16F67]={ - category="mc", + [0x13199]={ + category="lo", direction="l", }, - [0x16F68]={ - category="mc", + [0x1319A]={ + category="lo", direction="l", }, - [0x16F69]={ - category="mc", + [0x1319B]={ + category="lo", direction="l", }, - [0x16F6A]={ - category="mc", + [0x1319C]={ + category="lo", direction="l", }, - [0x16F6B]={ - category="mc", + [0x1319D]={ + category="lo", direction="l", }, - [0x16F6C]={ - category="mc", + [0x1319E]={ + category="lo", direction="l", }, - [0x16F6D]={ - category="mc", + [0x1319F]={ + category="lo", direction="l", }, - [0x16F6E]={ - category="mc", + [0x131A0]={ + category="lo", direction="l", }, - [0x16F6F]={ - category="mc", + [0x131A1]={ + category="lo", direction="l", }, - [0x16F70]={ - category="mc", + [0x131A2]={ + category="lo", direction="l", }, - [0x16F71]={ - category="mc", + [0x131A3]={ + category="lo", direction="l", }, - [0x16F72]={ - category="mc", + [0x131A4]={ + category="lo", direction="l", }, - [0x16F73]={ - category="mc", + [0x131A5]={ + category="lo", direction="l", }, - [0x16F74]={ - category="mc", + [0x131A6]={ + category="lo", direction="l", }, - [0x16F75]={ - category="mc", + [0x131A7]={ + category="lo", direction="l", }, - [0x16F76]={ - category="mc", + [0x131A8]={ + category="lo", direction="l", }, - [0x16F77]={ - category="mc", + [0x131A9]={ + category="lo", direction="l", }, - [0x16F78]={ - category="mc", + [0x131AA]={ + category="lo", direction="l", }, - [0x16F79]={ - category="mc", + [0x131AB]={ + category="lo", direction="l", }, - [0x16F7A]={ - category="mc", + [0x131AC]={ + category="lo", direction="l", }, - [0x16F7B]={ - category="mc", + [0x131AD]={ + category="lo", direction="l", }, - [0x16F7C]={ - category="mc", + [0x131AE]={ + category="lo", direction="l", }, - [0x16F7D]={ - category="mc", + [0x131AF]={ + category="lo", direction="l", }, - [0x16F7E]={ - category="mc", + [0x131B0]={ + category="lo", direction="l", }, - [0x16F8F]={ - category="mn", - direction="nsm", - }, - [0x16F90]={ - category="mn", - direction="nsm", - }, - [0x16F91]={ - category="mn", - direction="nsm", - }, - [0x16F92]={ - category="mn", - direction="nsm", - }, - [0x16F93]={ - category="lm", + [0x131B1]={ + category="lo", direction="l", }, - [0x16F94]={ - category="lm", + [0x131B2]={ + category="lo", direction="l", }, - [0x16F95]={ - category="lm", + [0x131B3]={ + category="lo", direction="l", }, - [0x16F96]={ - category="lm", + [0x131B4]={ + category="lo", direction="l", }, - [0x16F97]={ - category="lm", + [0x131B5]={ + category="lo", direction="l", }, - [0x16F98]={ - category="lm", + [0x131B6]={ + category="lo", direction="l", }, - [0x16F99]={ - category="lm", + [0x131B7]={ + category="lo", direction="l", }, - [0x16F9A]={ - category="lm", + [0x131B8]={ + category="lo", direction="l", }, - [0x16F9B]={ - category="lm", + [0x131B9]={ + category="lo", direction="l", }, - [0x16F9C]={ - category="lm", + [0x131BA]={ + category="lo", direction="l", }, - [0x16F9D]={ - category="lm", + [0x131BB]={ + category="lo", direction="l", }, - [0x16F9E]={ - category="lm", + [0x131BC]={ + category="lo", direction="l", }, - [0x16F9F]={ - category="lm", + [0x131BD]={ + category="lo", direction="l", }, - [0x1B000]={ + [0x131BE]={ category="lo", direction="l", }, - [0x1B001]={ + [0x131BF]={ category="lo", direction="l", }, - [0x1D000]={ - category="so", + [0x131C0]={ + category="lo", direction="l", }, - [0x1D001]={ - category="so", + [0x131C1]={ + category="lo", direction="l", }, - [0x1D002]={ - category="so", + [0x131C2]={ + category="lo", direction="l", }, - [0x1D003]={ - category="so", + [0x131C3]={ + category="lo", direction="l", }, - [0x1D004]={ - category="so", + [0x131C4]={ + category="lo", direction="l", }, - [0x1D005]={ - category="so", + [0x131C5]={ + category="lo", direction="l", }, - [0x1D006]={ - category="so", + [0x131C6]={ + category="lo", direction="l", }, - [0x1D007]={ - category="so", + [0x131C7]={ + category="lo", direction="l", }, - [0x1D008]={ - category="so", + [0x131C8]={ + category="lo", direction="l", }, - [0x1D009]={ - category="so", + [0x131C9]={ + category="lo", direction="l", }, - [0x1D00A]={ - category="so", + [0x131CA]={ + category="lo", direction="l", }, - [0x1D00B]={ - category="so", + [0x131CB]={ + category="lo", direction="l", }, - [0x1D00C]={ - category="so", + [0x131CC]={ + category="lo", direction="l", }, - [0x1D00D]={ - category="so", + [0x131CD]={ + category="lo", direction="l", }, - [0x1D00E]={ - category="so", + [0x131CE]={ + category="lo", direction="l", }, - [0x1D00F]={ - category="so", + [0x131CF]={ + category="lo", direction="l", }, - [0x1D010]={ - category="so", + [0x131D0]={ + category="lo", direction="l", }, - [0x1D011]={ - category="so", + [0x131D1]={ + category="lo", direction="l", }, - [0x1D012]={ - category="so", + [0x131D2]={ + category="lo", direction="l", }, - [0x1D013]={ - category="so", + [0x131D3]={ + category="lo", direction="l", }, - [0x1D014]={ - category="so", + [0x131D4]={ + category="lo", direction="l", }, - [0x1D015]={ - category="so", + [0x131D5]={ + category="lo", direction="l", }, - [0x1D016]={ - category="so", + [0x131D6]={ + category="lo", direction="l", }, - [0x1D017]={ - category="so", + [0x131D7]={ + category="lo", direction="l", }, - [0x1D018]={ - category="so", + [0x131D8]={ + category="lo", direction="l", }, - [0x1D019]={ - category="so", + [0x131D9]={ + category="lo", direction="l", }, - [0x1D01A]={ - category="so", + [0x131DA]={ + category="lo", direction="l", }, - [0x1D01B]={ - category="so", + [0x131DB]={ + category="lo", direction="l", }, - [0x1D01C]={ - category="so", + [0x131DC]={ + category="lo", direction="l", }, - [0x1D01D]={ - category="so", + [0x131DD]={ + category="lo", direction="l", }, - [0x1D01E]={ - category="so", + [0x131DE]={ + category="lo", direction="l", }, - [0x1D01F]={ - category="so", + [0x131DF]={ + category="lo", direction="l", }, - [0x1D020]={ - category="so", + [0x131E0]={ + category="lo", direction="l", }, - [0x1D021]={ - category="so", + [0x131E1]={ + category="lo", direction="l", }, - [0x1D022]={ - category="so", + [0x131E2]={ + category="lo", direction="l", }, - [0x1D023]={ - category="so", + [0x131E3]={ + category="lo", direction="l", }, - [0x1D024]={ - category="so", + [0x131E4]={ + category="lo", direction="l", }, - [0x1D025]={ - category="so", + [0x131E5]={ + category="lo", direction="l", }, - [0x1D026]={ - category="so", + [0x131E6]={ + category="lo", direction="l", }, - [0x1D027]={ - category="so", + [0x131E7]={ + category="lo", direction="l", }, - [0x1D028]={ - category="so", + [0x131E8]={ + category="lo", direction="l", }, - [0x1D029]={ - category="so", + [0x131E9]={ + category="lo", direction="l", }, - [0x1D02A]={ - category="so", + [0x131EA]={ + category="lo", direction="l", }, - [0x1D02B]={ - category="so", + [0x131EB]={ + category="lo", direction="l", }, - [0x1D02C]={ - category="so", + [0x131EC]={ + category="lo", direction="l", }, - [0x1D02D]={ - category="so", + [0x131ED]={ + category="lo", direction="l", }, - [0x1D02E]={ - category="so", + [0x131EE]={ + category="lo", direction="l", }, - [0x1D02F]={ - category="so", + [0x131EF]={ + category="lo", direction="l", }, - [0x1D030]={ - category="so", + [0x131F0]={ + category="lo", direction="l", }, - [0x1D031]={ - category="so", + [0x131F1]={ + category="lo", direction="l", }, - [0x1D032]={ - category="so", + [0x131F2]={ + category="lo", direction="l", }, - [0x1D033]={ - category="so", + [0x131F3]={ + category="lo", direction="l", }, - [0x1D034]={ - category="so", + [0x131F4]={ + category="lo", direction="l", }, - [0x1D035]={ - category="so", + [0x131F5]={ + category="lo", direction="l", }, - [0x1D036]={ - category="so", + [0x131F6]={ + category="lo", direction="l", }, - [0x1D037]={ - category="so", + [0x131F7]={ + category="lo", direction="l", }, - [0x1D038]={ - category="so", + [0x131F8]={ + category="lo", direction="l", }, - [0x1D039]={ - category="so", + [0x131F9]={ + category="lo", direction="l", }, - [0x1D03A]={ - category="so", + [0x131FA]={ + category="lo", direction="l", }, - [0x1D03B]={ - category="so", + [0x131FB]={ + category="lo", direction="l", }, - [0x1D03C]={ - category="so", + [0x131FC]={ + category="lo", direction="l", }, - [0x1D03D]={ - category="so", + [0x131FD]={ + category="lo", direction="l", }, - [0x1D03E]={ - category="so", + [0x131FE]={ + category="lo", direction="l", }, - [0x1D03F]={ - category="so", + [0x131FF]={ + category="lo", direction="l", }, - [0x1D040]={ - category="so", + [0x13200]={ + category="lo", direction="l", }, - [0x1D041]={ - category="so", + [0x13201]={ + category="lo", direction="l", }, - [0x1D042]={ - category="so", + [0x13202]={ + category="lo", direction="l", }, - [0x1D043]={ - category="so", + [0x13203]={ + category="lo", direction="l", }, - [0x1D044]={ - category="so", + [0x13204]={ + category="lo", direction="l", }, - [0x1D045]={ - category="so", + [0x13205]={ + category="lo", direction="l", }, - [0x1D046]={ - category="so", + [0x13206]={ + category="lo", direction="l", }, - [0x1D047]={ - category="so", + [0x13207]={ + category="lo", direction="l", }, - [0x1D048]={ - category="so", + [0x13208]={ + category="lo", direction="l", }, - [0x1D049]={ - category="so", + [0x13209]={ + category="lo", direction="l", }, - [0x1D04A]={ - category="so", + [0x1320A]={ + category="lo", direction="l", }, - [0x1D04B]={ - category="so", + [0x1320B]={ + category="lo", direction="l", }, - [0x1D04C]={ - category="so", + [0x1320C]={ + category="lo", direction="l", }, - [0x1D04D]={ - category="so", + [0x1320D]={ + category="lo", direction="l", }, - [0x1D04E]={ - category="so", + [0x1320E]={ + category="lo", direction="l", }, - [0x1D04F]={ - category="so", + [0x1320F]={ + category="lo", direction="l", }, - [0x1D050]={ - category="so", + [0x13210]={ + category="lo", direction="l", }, - [0x1D051]={ - category="so", + [0x13211]={ + category="lo", direction="l", }, - [0x1D052]={ - category="so", + [0x13212]={ + category="lo", direction="l", }, - [0x1D053]={ - category="so", + [0x13213]={ + category="lo", direction="l", }, - [0x1D054]={ - category="so", + [0x13214]={ + category="lo", direction="l", }, - [0x1D055]={ - category="so", + [0x13215]={ + category="lo", direction="l", }, - [0x1D056]={ - category="so", + [0x13216]={ + category="lo", direction="l", }, - [0x1D057]={ - category="so", + [0x13217]={ + category="lo", direction="l", }, - [0x1D058]={ - category="so", + [0x13218]={ + category="lo", direction="l", }, - [0x1D059]={ - category="so", + [0x13219]={ + category="lo", direction="l", }, - [0x1D05A]={ - category="so", + [0x1321A]={ + category="lo", direction="l", }, - [0x1D05B]={ - category="so", + [0x1321B]={ + category="lo", direction="l", }, - [0x1D05C]={ - category="so", + [0x1321C]={ + category="lo", direction="l", }, - [0x1D05D]={ - category="so", + [0x1321D]={ + category="lo", direction="l", }, - [0x1D05E]={ - category="so", + [0x1321E]={ + category="lo", direction="l", }, - [0x1D05F]={ - category="so", + [0x1321F]={ + category="lo", direction="l", }, - [0x1D060]={ - category="so", + [0x13220]={ + category="lo", direction="l", }, - [0x1D061]={ - category="so", + [0x13221]={ + category="lo", direction="l", }, - [0x1D062]={ - category="so", + [0x13222]={ + category="lo", direction="l", }, - [0x1D063]={ - category="so", + [0x13223]={ + category="lo", direction="l", }, - [0x1D064]={ - category="so", + [0x13224]={ + category="lo", direction="l", }, - [0x1D065]={ - category="so", + [0x13225]={ + category="lo", direction="l", }, - [0x1D066]={ - category="so", + [0x13226]={ + category="lo", direction="l", }, - [0x1D067]={ - category="so", + [0x13227]={ + category="lo", direction="l", }, - [0x1D068]={ - category="so", + [0x13228]={ + category="lo", direction="l", }, - [0x1D069]={ - category="so", + [0x13229]={ + category="lo", direction="l", }, - [0x1D06A]={ - category="so", + [0x1322A]={ + category="lo", direction="l", }, - [0x1D06B]={ - category="so", + [0x1322B]={ + category="lo", direction="l", }, - [0x1D06C]={ - category="so", + [0x1322C]={ + category="lo", direction="l", }, - [0x1D06D]={ - category="so", + [0x1322D]={ + category="lo", direction="l", }, - [0x1D06E]={ - category="so", + [0x1322E]={ + category="lo", direction="l", }, - [0x1D06F]={ - category="so", + [0x1322F]={ + category="lo", direction="l", }, - [0x1D070]={ - category="so", + [0x13230]={ + category="lo", direction="l", }, - [0x1D071]={ - category="so", + [0x13231]={ + category="lo", direction="l", }, - [0x1D072]={ - category="so", + [0x13232]={ + category="lo", direction="l", }, - [0x1D073]={ - category="so", + [0x13233]={ + category="lo", direction="l", }, - [0x1D074]={ - category="so", + [0x13234]={ + category="lo", direction="l", }, - [0x1D075]={ - category="so", + [0x13235]={ + category="lo", direction="l", }, - [0x1D076]={ - category="so", + [0x13236]={ + category="lo", direction="l", }, - [0x1D077]={ - category="so", + [0x13237]={ + category="lo", direction="l", }, - [0x1D078]={ - category="so", + [0x13238]={ + category="lo", direction="l", }, - [0x1D079]={ - category="so", + [0x13239]={ + category="lo", direction="l", }, - [0x1D07A]={ - category="so", + [0x1323A]={ + category="lo", direction="l", }, - [0x1D07B]={ - category="so", + [0x1323B]={ + category="lo", direction="l", }, - [0x1D07C]={ - category="so", + [0x1323C]={ + category="lo", direction="l", }, - [0x1D07D]={ - category="so", + [0x1323D]={ + category="lo", direction="l", }, - [0x1D07E]={ - category="so", + [0x1323E]={ + category="lo", direction="l", }, - [0x1D07F]={ - category="so", + [0x1323F]={ + category="lo", direction="l", }, - [0x1D080]={ - category="so", + [0x13240]={ + category="lo", direction="l", }, - [0x1D081]={ - category="so", + [0x13241]={ + category="lo", direction="l", }, - [0x1D082]={ - category="so", + [0x13242]={ + category="lo", direction="l", }, - [0x1D083]={ - category="so", + [0x13243]={ + category="lo", direction="l", }, - [0x1D084]={ - category="so", + [0x13244]={ + category="lo", direction="l", }, - [0x1D085]={ - category="so", + [0x13245]={ + category="lo", direction="l", }, - [0x1D086]={ - category="so", + [0x13246]={ + category="lo", direction="l", }, - [0x1D087]={ - category="so", + [0x13247]={ + category="lo", direction="l", }, - [0x1D088]={ - category="so", + [0x13248]={ + category="lo", direction="l", }, - [0x1D089]={ - category="so", + [0x13249]={ + category="lo", direction="l", }, - [0x1D08A]={ - category="so", + [0x1324A]={ + category="lo", direction="l", }, - [0x1D08B]={ - category="so", + [0x1324B]={ + category="lo", direction="l", }, - [0x1D08C]={ - category="so", + [0x1324C]={ + category="lo", direction="l", }, - [0x1D08D]={ - category="so", + [0x1324D]={ + category="lo", direction="l", }, - [0x1D08E]={ - category="so", + [0x1324E]={ + category="lo", direction="l", }, - [0x1D08F]={ - category="so", + [0x1324F]={ + category="lo", direction="l", }, - [0x1D090]={ - category="so", + [0x13250]={ + category="lo", direction="l", }, - [0x1D091]={ - category="so", + [0x13251]={ + category="lo", direction="l", }, - [0x1D092]={ - category="so", + [0x13252]={ + category="lo", direction="l", }, - [0x1D093]={ - category="so", + [0x13253]={ + category="lo", direction="l", }, - [0x1D094]={ - category="so", + [0x13254]={ + category="lo", direction="l", }, - [0x1D095]={ - category="so", + [0x13255]={ + category="lo", direction="l", }, - [0x1D096]={ - category="so", + [0x13256]={ + category="lo", direction="l", }, - [0x1D097]={ - category="so", + [0x13257]={ + category="lo", direction="l", }, - [0x1D098]={ - category="so", + [0x13258]={ + category="lo", direction="l", }, - [0x1D099]={ - category="so", + [0x13259]={ + category="lo", direction="l", }, - [0x1D09A]={ - category="so", + [0x1325A]={ + category="lo", direction="l", }, - [0x1D09B]={ - category="so", + [0x1325B]={ + category="lo", direction="l", }, - [0x1D09C]={ - category="so", + [0x1325C]={ + category="lo", direction="l", }, - [0x1D09D]={ - category="so", + [0x1325D]={ + category="lo", direction="l", }, - [0x1D09E]={ - category="so", + [0x1325E]={ + category="lo", direction="l", }, - [0x1D09F]={ - category="so", + [0x1325F]={ + category="lo", direction="l", }, - [0x1D0A0]={ - category="so", + [0x13260]={ + category="lo", direction="l", }, - [0x1D0A1]={ - category="so", + [0x13261]={ + category="lo", direction="l", }, - [0x1D0A2]={ - category="so", + [0x13262]={ + category="lo", direction="l", }, - [0x1D0A3]={ - category="so", + [0x13263]={ + category="lo", direction="l", }, - [0x1D0A4]={ - category="so", + [0x13264]={ + category="lo", direction="l", }, - [0x1D0A5]={ - category="so", + [0x13265]={ + category="lo", direction="l", }, - [0x1D0A6]={ - category="so", + [0x13266]={ + category="lo", direction="l", }, - [0x1D0A7]={ - category="so", + [0x13267]={ + category="lo", direction="l", }, - [0x1D0A8]={ - category="so", + [0x13268]={ + category="lo", direction="l", }, - [0x1D0A9]={ - category="so", + [0x13269]={ + category="lo", direction="l", }, - [0x1D0AA]={ - category="so", + [0x1326A]={ + category="lo", direction="l", }, - [0x1D0AB]={ - category="so", + [0x1326B]={ + category="lo", direction="l", }, - [0x1D0AC]={ - category="so", + [0x1326C]={ + category="lo", direction="l", }, - [0x1D0AD]={ - category="so", + [0x1326D]={ + category="lo", direction="l", }, - [0x1D0AE]={ - category="so", + [0x1326E]={ + category="lo", direction="l", }, - [0x1D0AF]={ - category="so", + [0x1326F]={ + category="lo", direction="l", }, - [0x1D0B0]={ - category="so", + [0x13270]={ + category="lo", direction="l", }, - [0x1D0B1]={ - category="so", + [0x13271]={ + category="lo", direction="l", }, - [0x1D0B2]={ - category="so", + [0x13272]={ + category="lo", direction="l", }, - [0x1D0B3]={ - category="so", + [0x13273]={ + category="lo", direction="l", }, - [0x1D0B4]={ - category="so", + [0x13274]={ + category="lo", direction="l", }, - [0x1D0B5]={ - category="so", + [0x13275]={ + category="lo", direction="l", }, - [0x1D0B6]={ - category="so", + [0x13276]={ + category="lo", direction="l", }, - [0x1D0B7]={ - category="so", + [0x13277]={ + category="lo", direction="l", }, - [0x1D0B8]={ - category="so", + [0x13278]={ + category="lo", direction="l", }, - [0x1D0B9]={ - category="so", + [0x13279]={ + category="lo", direction="l", }, - [0x1D0BA]={ - category="so", + [0x1327A]={ + category="lo", direction="l", }, - [0x1D0BB]={ - category="so", + [0x1327B]={ + category="lo", direction="l", }, - [0x1D0BC]={ - category="so", + [0x1327C]={ + category="lo", direction="l", }, - [0x1D0BD]={ - category="so", + [0x1327D]={ + category="lo", direction="l", }, - [0x1D0BE]={ - category="so", + [0x1327E]={ + category="lo", direction="l", }, - [0x1D0BF]={ - category="so", + [0x1327F]={ + category="lo", direction="l", }, - [0x1D0C0]={ - category="so", + [0x13280]={ + category="lo", direction="l", }, - [0x1D0C1]={ - category="so", + [0x13281]={ + category="lo", direction="l", }, - [0x1D0C2]={ - category="so", + [0x13282]={ + category="lo", direction="l", }, - [0x1D0C3]={ - category="so", + [0x13283]={ + category="lo", direction="l", }, - [0x1D0C4]={ - category="so", + [0x13284]={ + category="lo", direction="l", }, - [0x1D0C5]={ - category="so", + [0x13285]={ + category="lo", direction="l", }, - [0x1D0C6]={ - category="so", + [0x13286]={ + category="lo", direction="l", }, - [0x1D0C7]={ - category="so", + [0x13287]={ + category="lo", direction="l", }, - [0x1D0C8]={ - category="so", + [0x13288]={ + category="lo", direction="l", }, - [0x1D0C9]={ - category="so", + [0x13289]={ + category="lo", direction="l", }, - [0x1D0CA]={ - category="so", + [0x1328A]={ + category="lo", direction="l", }, - [0x1D0CB]={ - category="so", + [0x1328B]={ + category="lo", direction="l", }, - [0x1D0CC]={ - category="so", + [0x1328C]={ + category="lo", direction="l", }, - [0x1D0CD]={ - category="so", + [0x1328D]={ + category="lo", direction="l", }, - [0x1D0CE]={ - category="so", + [0x1328E]={ + category="lo", direction="l", }, - [0x1D0CF]={ - category="so", + [0x1328F]={ + category="lo", direction="l", }, - [0x1D0D0]={ - category="so", + [0x13290]={ + category="lo", direction="l", }, - [0x1D0D1]={ - category="so", + [0x13291]={ + category="lo", direction="l", }, - [0x1D0D2]={ - category="so", + [0x13292]={ + category="lo", direction="l", }, - [0x1D0D3]={ - category="so", + [0x13293]={ + category="lo", direction="l", }, - [0x1D0D4]={ - category="so", + [0x13294]={ + category="lo", direction="l", }, - [0x1D0D5]={ - category="so", + [0x13295]={ + category="lo", direction="l", }, - [0x1D0D6]={ - category="so", + [0x13296]={ + category="lo", direction="l", }, - [0x1D0D7]={ - category="so", + [0x13297]={ + category="lo", direction="l", }, - [0x1D0D8]={ - category="so", + [0x13298]={ + category="lo", direction="l", }, - [0x1D0D9]={ - category="so", + [0x13299]={ + category="lo", direction="l", }, - [0x1D0DA]={ - category="so", + [0x1329A]={ + category="lo", direction="l", }, - [0x1D0DB]={ - category="so", + [0x1329B]={ + category="lo", direction="l", }, - [0x1D0DC]={ - category="so", + [0x1329C]={ + category="lo", direction="l", }, - [0x1D0DD]={ - category="so", + [0x1329D]={ + category="lo", direction="l", }, - [0x1D0DE]={ - category="so", + [0x1329E]={ + category="lo", direction="l", }, - [0x1D0DF]={ - category="so", + [0x1329F]={ + category="lo", direction="l", }, - [0x1D0E0]={ - category="so", + [0x132A0]={ + category="lo", direction="l", }, - [0x1D0E1]={ - category="so", + [0x132A1]={ + category="lo", direction="l", }, - [0x1D0E2]={ - category="so", + [0x132A2]={ + category="lo", direction="l", }, - [0x1D0E3]={ - category="so", + [0x132A3]={ + category="lo", direction="l", }, - [0x1D0E4]={ - category="so", + [0x132A4]={ + category="lo", direction="l", }, - [0x1D0E5]={ - category="so", + [0x132A5]={ + category="lo", direction="l", }, - [0x1D0E6]={ - category="so", + [0x132A6]={ + category="lo", direction="l", }, - [0x1D0E7]={ - category="so", + [0x132A7]={ + category="lo", direction="l", }, - [0x1D0E8]={ - category="so", + [0x132A8]={ + category="lo", direction="l", }, - [0x1D0E9]={ - category="so", + [0x132A9]={ + category="lo", direction="l", }, - [0x1D0EA]={ - category="so", + [0x132AA]={ + category="lo", direction="l", }, - [0x1D0EB]={ - category="so", + [0x132AB]={ + category="lo", direction="l", }, - [0x1D0EC]={ - category="so", + [0x132AC]={ + category="lo", direction="l", }, - [0x1D0ED]={ - category="so", + [0x132AD]={ + category="lo", direction="l", }, - [0x1D0EE]={ - category="so", + [0x132AE]={ + category="lo", direction="l", }, - [0x1D0EF]={ - category="so", + [0x132AF]={ + category="lo", direction="l", }, - [0x1D0F0]={ - category="so", + [0x132B0]={ + category="lo", direction="l", }, - [0x1D0F1]={ - category="so", + [0x132B1]={ + category="lo", direction="l", }, - [0x1D0F2]={ - category="so", + [0x132B2]={ + category="lo", direction="l", }, - [0x1D0F3]={ - category="so", + [0x132B3]={ + category="lo", direction="l", }, - [0x1D0F4]={ - category="so", + [0x132B4]={ + category="lo", direction="l", }, - [0x1D0F5]={ - category="so", + [0x132B5]={ + category="lo", direction="l", }, - [0x1D100]={ - category="so", + [0x132B6]={ + category="lo", direction="l", }, - [0x1D101]={ - category="so", + [0x132B7]={ + category="lo", direction="l", }, - [0x1D102]={ - category="so", + [0x132B8]={ + category="lo", direction="l", }, - [0x1D103]={ - category="so", + [0x132B9]={ + category="lo", direction="l", }, - [0x1D104]={ - category="so", + [0x132BA]={ + category="lo", direction="l", }, - [0x1D105]={ - category="so", + [0x132BB]={ + category="lo", direction="l", }, - [0x1D106]={ - category="so", + [0x132BC]={ + category="lo", direction="l", }, - [0x1D107]={ - category="so", + [0x132BD]={ + category="lo", direction="l", }, - [0x1D108]={ - category="so", + [0x132BE]={ + category="lo", direction="l", }, - [0x1D109]={ - category="so", + [0x132BF]={ + category="lo", direction="l", }, - [0x1D10A]={ - category="so", + [0x132C0]={ + category="lo", direction="l", }, - [0x1D10B]={ - category="so", + [0x132C1]={ + category="lo", direction="l", }, - [0x1D10C]={ - category="so", + [0x132C2]={ + category="lo", direction="l", }, - [0x1D10D]={ - category="so", + [0x132C3]={ + category="lo", direction="l", }, - [0x1D10E]={ - category="so", + [0x132C4]={ + category="lo", direction="l", }, - [0x1D10F]={ - category="so", + [0x132C5]={ + category="lo", direction="l", }, - [0x1D110]={ - category="so", + [0x132C6]={ + category="lo", direction="l", }, - [0x1D111]={ - category="so", + [0x132C7]={ + category="lo", direction="l", }, - [0x1D112]={ - category="so", + [0x132C8]={ + category="lo", direction="l", }, - [0x1D113]={ - category="so", + [0x132C9]={ + category="lo", direction="l", }, - [0x1D114]={ - category="so", + [0x132CA]={ + category="lo", direction="l", }, - [0x1D115]={ - category="so", + [0x132CB]={ + category="lo", direction="l", }, - [0x1D116]={ - category="so", + [0x132CC]={ + category="lo", direction="l", }, - [0x1D117]={ - category="so", + [0x132CD]={ + category="lo", direction="l", }, - [0x1D118]={ - category="so", + [0x132CE]={ + category="lo", direction="l", }, - [0x1D119]={ - category="so", + [0x132CF]={ + category="lo", direction="l", }, - [0x1D11A]={ - category="so", + [0x132D0]={ + category="lo", direction="l", }, - [0x1D11B]={ - category="so", + [0x132D1]={ + category="lo", direction="l", }, - [0x1D11C]={ - category="so", + [0x132D2]={ + category="lo", direction="l", }, - [0x1D11D]={ - category="so", + [0x132D3]={ + category="lo", direction="l", }, - [0x1D11E]={ - category="so", + [0x132D4]={ + category="lo", direction="l", }, - [0x1D11F]={ - category="so", + [0x132D5]={ + category="lo", direction="l", }, - [0x1D120]={ - category="so", + [0x132D6]={ + category="lo", direction="l", }, - [0x1D121]={ - category="so", + [0x132D7]={ + category="lo", direction="l", }, - [0x1D122]={ - category="so", + [0x132D8]={ + category="lo", direction="l", }, - [0x1D123]={ - category="so", + [0x132D9]={ + category="lo", direction="l", }, - [0x1D124]={ - category="so", + [0x132DA]={ + category="lo", direction="l", }, - [0x1D125]={ - category="so", + [0x132DB]={ + category="lo", direction="l", }, - [0x1D126]={ - category="so", + [0x132DC]={ + category="lo", direction="l", }, - [0x1D129]={ - category="so", + [0x132DD]={ + category="lo", direction="l", }, - [0x1D12A]={ - category="so", + [0x132DE]={ + category="lo", direction="l", }, - [0x1D12B]={ - category="so", + [0x132DF]={ + category="lo", direction="l", }, - [0x1D12C]={ - category="so", + [0x132E0]={ + category="lo", direction="l", }, - [0x1D12D]={ - category="so", + [0x132E1]={ + category="lo", direction="l", }, - [0x1D12E]={ - category="so", + [0x132E2]={ + category="lo", direction="l", }, - [0x1D12F]={ - category="so", + [0x132E3]={ + category="lo", direction="l", }, - [0x1D130]={ - category="so", + [0x132E4]={ + category="lo", direction="l", }, - [0x1D131]={ - category="so", + [0x132E5]={ + category="lo", direction="l", }, - [0x1D132]={ - category="so", + [0x132E6]={ + category="lo", direction="l", }, - [0x1D133]={ - category="so", + [0x132E7]={ + category="lo", direction="l", }, - [0x1D134]={ - category="so", + [0x132E8]={ + category="lo", direction="l", }, - [0x1D135]={ - category="so", + [0x132E9]={ + category="lo", direction="l", }, - [0x1D136]={ - category="so", + [0x132EA]={ + category="lo", direction="l", }, - [0x1D137]={ - category="so", + [0x132EB]={ + category="lo", direction="l", }, - [0x1D138]={ - category="so", + [0x132EC]={ + category="lo", direction="l", }, - [0x1D139]={ - category="so", + [0x132ED]={ + category="lo", direction="l", }, - [0x1D13A]={ - category="so", + [0x132EE]={ + category="lo", direction="l", }, - [0x1D13B]={ - category="so", + [0x132EF]={ + category="lo", direction="l", }, - [0x1D13C]={ - category="so", + [0x132F0]={ + category="lo", direction="l", }, - [0x1D13D]={ - category="so", + [0x132F1]={ + category="lo", direction="l", }, - [0x1D13E]={ - category="so", + [0x132F2]={ + category="lo", direction="l", }, - [0x1D13F]={ - category="so", + [0x132F3]={ + category="lo", direction="l", }, - [0x1D140]={ - category="so", + [0x132F4]={ + category="lo", direction="l", }, - [0x1D141]={ - category="so", + [0x132F5]={ + category="lo", direction="l", }, - [0x1D142]={ - category="so", + [0x132F6]={ + category="lo", direction="l", }, - [0x1D143]={ - category="so", + [0x132F7]={ + category="lo", direction="l", }, - [0x1D144]={ - category="so", + [0x132F8]={ + category="lo", direction="l", }, - [0x1D145]={ - category="so", + [0x132F9]={ + category="lo", direction="l", }, - [0x1D146]={ - category="so", + [0x132FA]={ + category="lo", direction="l", }, - [0x1D147]={ - category="so", + [0x132FB]={ + category="lo", direction="l", }, - [0x1D148]={ - category="so", + [0x132FC]={ + category="lo", direction="l", }, - [0x1D149]={ - category="so", + [0x132FD]={ + category="lo", direction="l", }, - [0x1D14A]={ - category="so", + [0x132FE]={ + category="lo", direction="l", }, - [0x1D14B]={ - category="so", + [0x132FF]={ + category="lo", direction="l", }, - [0x1D14C]={ - category="so", + [0x13300]={ + category="lo", direction="l", }, - [0x1D14D]={ - category="so", + [0x13301]={ + category="lo", direction="l", }, - [0x1D14E]={ - category="so", + [0x13302]={ + category="lo", direction="l", }, - [0x1D14F]={ - category="so", + [0x13303]={ + category="lo", direction="l", }, - [0x1D150]={ - category="so", + [0x13304]={ + category="lo", direction="l", }, - [0x1D151]={ - category="so", + [0x13305]={ + category="lo", direction="l", }, - [0x1D152]={ - category="so", + [0x13306]={ + category="lo", direction="l", }, - [0x1D153]={ - category="so", + [0x13307]={ + category="lo", direction="l", }, - [0x1D154]={ - category="so", + [0x13308]={ + category="lo", direction="l", }, - [0x1D155]={ - category="so", + [0x13309]={ + category="lo", direction="l", }, - [0x1D156]={ - category="so", + [0x1330A]={ + category="lo", direction="l", }, - [0x1D157]={ - category="so", + [0x1330B]={ + category="lo", direction="l", }, - [0x1D158]={ - category="so", + [0x1330C]={ + category="lo", direction="l", }, - [0x1D159]={ - category="so", + [0x1330D]={ + category="lo", direction="l", }, - [0x1D15A]={ - category="so", + [0x1330E]={ + category="lo", direction="l", }, - [0x1D15B]={ - category="so", + [0x1330F]={ + category="lo", direction="l", }, - [0x1D15C]={ - category="so", + [0x13310]={ + category="lo", direction="l", }, - [0x1D15D]={ - category="so", + [0x13311]={ + category="lo", direction="l", }, - [0x1D15E]={ - category="so", + [0x13312]={ + category="lo", direction="l", }, - [0x1D15F]={ - category="so", + [0x13313]={ + category="lo", direction="l", }, - [0x1D160]={ - category="so", + [0x13314]={ + category="lo", direction="l", }, - [0x1D161]={ - category="so", + [0x13315]={ + category="lo", direction="l", }, - [0x1D162]={ - category="so", + [0x13316]={ + category="lo", direction="l", }, - [0x1D163]={ - category="so", + [0x13317]={ + category="lo", direction="l", }, - [0x1D164]={ - category="so", + [0x13318]={ + category="lo", direction="l", }, - [0x1D165]={ - category="mc", + [0x13319]={ + category="lo", direction="l", }, - [0x1D166]={ - category="mc", + [0x1331A]={ + category="lo", direction="l", }, - [0x1D167]={ - category="mn", - direction="nsm", + [0x1331B]={ + category="lo", + direction="l", }, - [0x1D168]={ - category="mn", - direction="nsm", + [0x1331C]={ + category="lo", + direction="l", }, - [0x1D169]={ - category="mn", - direction="nsm", + [0x1331D]={ + category="lo", + direction="l", }, - [0x1D16A]={ - category="so", + [0x1331E]={ + category="lo", direction="l", }, - [0x1D16B]={ - category="so", + [0x1331F]={ + category="lo", direction="l", }, - [0x1D16C]={ - category="so", + [0x13320]={ + category="lo", direction="l", }, - [0x1D16D]={ - category="mc", + [0x13321]={ + category="lo", direction="l", }, - [0x1D16E]={ - category="mc", + [0x13322]={ + category="lo", direction="l", }, - [0x1D16F]={ - category="mc", + [0x13323]={ + category="lo", direction="l", }, - [0x1D170]={ - category="mc", + [0x13324]={ + category="lo", direction="l", }, - [0x1D171]={ - category="mc", + [0x13325]={ + category="lo", direction="l", }, - [0x1D172]={ - category="mc", + [0x13326]={ + category="lo", direction="l", }, - [0x1D173]={ - category="cf", - direction="bn", + [0x13327]={ + category="lo", + direction="l", }, - [0x1D174]={ - category="cf", - direction="bn", + [0x13328]={ + category="lo", + direction="l", }, - [0x1D175]={ - category="cf", - direction="bn", + [0x13329]={ + category="lo", + direction="l", }, - [0x1D176]={ - category="cf", - direction="bn", + [0x1332A]={ + category="lo", + direction="l", }, - [0x1D177]={ - category="cf", - direction="bn", + [0x1332B]={ + category="lo", + direction="l", }, - [0x1D178]={ - category="cf", - direction="bn", + [0x1332C]={ + category="lo", + direction="l", }, - [0x1D179]={ - category="cf", - direction="bn", + [0x1332D]={ + category="lo", + direction="l", }, - [0x1D17A]={ - category="cf", - direction="bn", + [0x1332E]={ + category="lo", + direction="l", }, - [0x1D17B]={ - category="mn", - direction="nsm", + [0x1332F]={ + category="lo", + direction="l", }, - [0x1D17C]={ - category="mn", - direction="nsm", + [0x13330]={ + category="lo", + direction="l", }, - [0x1D17D]={ - category="mn", - direction="nsm", + [0x13331]={ + category="lo", + direction="l", }, - [0x1D17E]={ - category="mn", - direction="nsm", + [0x13332]={ + category="lo", + direction="l", }, - [0x1D17F]={ - category="mn", - direction="nsm", + [0x13333]={ + category="lo", + direction="l", }, - [0x1D180]={ - category="mn", - direction="nsm", + [0x13334]={ + category="lo", + direction="l", }, - [0x1D181]={ - category="mn", - direction="nsm", + [0x13335]={ + category="lo", + direction="l", }, - [0x1D182]={ - category="mn", - direction="nsm", + [0x13336]={ + category="lo", + direction="l", }, - [0x1D183]={ - category="so", + [0x13337]={ + category="lo", direction="l", }, - [0x1D184]={ - category="so", + [0x13338]={ + category="lo", direction="l", }, - [0x1D185]={ - category="mn", - direction="nsm", + [0x13339]={ + category="lo", + direction="l", }, - [0x1D186]={ - category="mn", - direction="nsm", + [0x1333A]={ + category="lo", + direction="l", }, - [0x1D187]={ - category="mn", - direction="nsm", + [0x1333B]={ + category="lo", + direction="l", }, - [0x1D188]={ - category="mn", - direction="nsm", + [0x1333C]={ + category="lo", + direction="l", }, - [0x1D189]={ - category="mn", - direction="nsm", + [0x1333D]={ + category="lo", + direction="l", }, - [0x1D18A]={ - category="mn", - direction="nsm", + [0x1333E]={ + category="lo", + direction="l", }, - [0x1D18B]={ - category="mn", - direction="nsm", + [0x1333F]={ + category="lo", + direction="l", }, - [0x1D18C]={ - category="so", + [0x13340]={ + category="lo", direction="l", }, - [0x1D18D]={ - category="so", + [0x13341]={ + category="lo", direction="l", }, - [0x1D18E]={ - category="so", + [0x13342]={ + category="lo", direction="l", }, - [0x1D18F]={ - category="so", + [0x13343]={ + category="lo", direction="l", }, - [0x1D190]={ - category="so", + [0x13344]={ + category="lo", direction="l", }, - [0x1D191]={ - category="so", + [0x13345]={ + category="lo", direction="l", }, - [0x1D192]={ - category="so", + [0x13346]={ + category="lo", direction="l", }, - [0x1D193]={ - category="so", + [0x13347]={ + category="lo", direction="l", }, - [0x1D194]={ - category="so", + [0x13348]={ + category="lo", direction="l", }, - [0x1D195]={ - category="so", + [0x13349]={ + category="lo", direction="l", }, - [0x1D196]={ - category="so", + [0x1334A]={ + category="lo", direction="l", }, - [0x1D197]={ - category="so", + [0x1334B]={ + category="lo", direction="l", }, - [0x1D198]={ - category="so", + [0x1334C]={ + category="lo", direction="l", }, - [0x1D199]={ - category="so", + [0x1334D]={ + category="lo", direction="l", }, - [0x1D19A]={ - category="so", + [0x1334E]={ + category="lo", direction="l", }, - [0x1D19B]={ - category="so", + [0x1334F]={ + category="lo", direction="l", }, - [0x1D19C]={ - category="so", + [0x13350]={ + category="lo", direction="l", }, - [0x1D19D]={ - category="so", + [0x13351]={ + category="lo", direction="l", }, - [0x1D19E]={ - category="so", + [0x13352]={ + category="lo", direction="l", }, - [0x1D19F]={ - category="so", + [0x13353]={ + category="lo", direction="l", }, - [0x1D1A0]={ - category="so", + [0x13354]={ + category="lo", direction="l", }, - [0x1D1A1]={ - category="so", + [0x13355]={ + category="lo", direction="l", }, - [0x1D1A2]={ - category="so", + [0x13356]={ + category="lo", direction="l", }, - [0x1D1A3]={ - category="so", + [0x13357]={ + category="lo", direction="l", }, - [0x1D1A4]={ - category="so", + [0x13358]={ + category="lo", direction="l", }, - [0x1D1A5]={ - category="so", + [0x13359]={ + category="lo", direction="l", }, - [0x1D1A6]={ - category="so", + [0x1335A]={ + category="lo", direction="l", }, - [0x1D1A7]={ - category="so", + [0x1335B]={ + category="lo", direction="l", }, - [0x1D1A8]={ - category="so", + [0x1335C]={ + category="lo", direction="l", }, - [0x1D1A9]={ - category="so", + [0x1335D]={ + category="lo", direction="l", }, - [0x1D1AA]={ - category="mn", - direction="nsm", + [0x1335E]={ + category="lo", + direction="l", }, - [0x1D1AB]={ - category="mn", - direction="nsm", + [0x1335F]={ + category="lo", + direction="l", }, - [0x1D1AC]={ - category="mn", - direction="nsm", + [0x13360]={ + category="lo", + direction="l", }, - [0x1D1AD]={ - category="mn", - direction="nsm", + [0x13361]={ + category="lo", + direction="l", }, - [0x1D1AE]={ - category="so", + [0x13362]={ + category="lo", direction="l", }, - [0x1D1AF]={ - category="so", + [0x13363]={ + category="lo", direction="l", }, - [0x1D1B0]={ - category="so", + [0x13364]={ + category="lo", direction="l", }, - [0x1D1B1]={ - category="so", + [0x13365]={ + category="lo", direction="l", }, - [0x1D1B2]={ - category="so", + [0x13366]={ + category="lo", direction="l", }, - [0x1D1B3]={ - category="so", + [0x13367]={ + category="lo", direction="l", }, - [0x1D1B4]={ - category="so", + [0x13368]={ + category="lo", direction="l", }, - [0x1D1B5]={ - category="so", + [0x13369]={ + category="lo", direction="l", }, - [0x1D1B6]={ - category="so", + [0x1336A]={ + category="lo", direction="l", }, - [0x1D1B7]={ - category="so", + [0x1336B]={ + category="lo", direction="l", }, - [0x1D1B8]={ - category="so", + [0x1336C]={ + category="lo", direction="l", }, - [0x1D1B9]={ - category="so", + [0x1336D]={ + category="lo", direction="l", }, - [0x1D1BA]={ - category="so", + [0x1336E]={ + category="lo", direction="l", }, - [0x1D1BB]={ - category="so", + [0x1336F]={ + category="lo", direction="l", }, - [0x1D1BC]={ - category="so", + [0x13370]={ + category="lo", direction="l", }, - [0x1D1BD]={ - category="so", + [0x13371]={ + category="lo", direction="l", }, - [0x1D1BE]={ - category="so", + [0x13372]={ + category="lo", direction="l", }, - [0x1D1BF]={ - category="so", + [0x13373]={ + category="lo", direction="l", }, - [0x1D1C0]={ - category="so", + [0x13374]={ + category="lo", direction="l", }, - [0x1D1C1]={ - category="so", + [0x13375]={ + category="lo", direction="l", }, - [0x1D1C2]={ - category="so", + [0x13376]={ + category="lo", direction="l", }, - [0x1D1C3]={ - category="so", + [0x13377]={ + category="lo", direction="l", }, - [0x1D1C4]={ - category="so", + [0x13378]={ + category="lo", direction="l", }, - [0x1D1C5]={ - category="so", + [0x13379]={ + category="lo", direction="l", }, - [0x1D1C6]={ - category="so", + [0x1337A]={ + category="lo", direction="l", }, - [0x1D1C7]={ - category="so", + [0x1337B]={ + category="lo", direction="l", }, - [0x1D1C8]={ - category="so", + [0x1337C]={ + category="lo", direction="l", }, - [0x1D1C9]={ - category="so", + [0x1337D]={ + category="lo", direction="l", }, - [0x1D1CA]={ - category="so", + [0x1337E]={ + category="lo", direction="l", }, - [0x1D1CB]={ - category="so", + [0x1337F]={ + category="lo", direction="l", }, - [0x1D1CC]={ - category="so", + [0x13380]={ + category="lo", direction="l", }, - [0x1D1CD]={ - category="so", + [0x13381]={ + category="lo", direction="l", }, - [0x1D1CE]={ - category="so", + [0x13382]={ + category="lo", direction="l", }, - [0x1D1CF]={ - category="so", + [0x13383]={ + category="lo", direction="l", }, - [0x1D1D0]={ - category="so", + [0x13384]={ + category="lo", direction="l", }, - [0x1D1D1]={ - category="so", + [0x13385]={ + category="lo", direction="l", }, - [0x1D1D2]={ - category="so", + [0x13386]={ + category="lo", direction="l", }, - [0x1D1D3]={ - category="so", + [0x13387]={ + category="lo", direction="l", }, - [0x1D1D4]={ - category="so", + [0x13388]={ + category="lo", direction="l", }, - [0x1D1D5]={ - category="so", + [0x13389]={ + category="lo", direction="l", }, - [0x1D1D6]={ - category="so", + [0x1338A]={ + category="lo", direction="l", }, - [0x1D1D7]={ - category="so", + [0x1338B]={ + category="lo", direction="l", }, - [0x1D1D8]={ - category="so", + [0x1338C]={ + category="lo", direction="l", }, - [0x1D1D9]={ - category="so", + [0x1338D]={ + category="lo", direction="l", }, - [0x1D1DA]={ - category="so", + [0x1338E]={ + category="lo", direction="l", }, - [0x1D1DB]={ - category="so", + [0x1338F]={ + category="lo", direction="l", }, - [0x1D1DC]={ - category="so", + [0x13390]={ + category="lo", direction="l", }, - [0x1D1DD]={ - category="so", + [0x13391]={ + category="lo", direction="l", }, - [0x1D200]={ - category="so", - direction="on", + [0x13392]={ + category="lo", + direction="l", }, - [0x1D201]={ - category="so", - direction="on", + [0x13393]={ + category="lo", + direction="l", }, - [0x1D202]={ - category="so", - direction="on", + [0x13394]={ + category="lo", + direction="l", }, - [0x1D203]={ - category="so", - direction="on", + [0x13395]={ + category="lo", + direction="l", }, - [0x1D204]={ - category="so", - direction="on", + [0x13396]={ + category="lo", + direction="l", }, - [0x1D205]={ - category="so", - direction="on", + [0x13397]={ + category="lo", + direction="l", }, - [0x1D206]={ - category="so", - direction="on", + [0x13398]={ + category="lo", + direction="l", }, - [0x1D207]={ - category="so", - direction="on", + [0x13399]={ + category="lo", + direction="l", }, - [0x1D208]={ - category="so", - direction="on", + [0x1339A]={ + category="lo", + direction="l", }, - [0x1D209]={ - category="so", - direction="on", + [0x1339B]={ + category="lo", + direction="l", }, - [0x1D20A]={ - category="so", - direction="on", + [0x1339C]={ + category="lo", + direction="l", }, - [0x1D20B]={ - category="so", - direction="on", + [0x1339D]={ + category="lo", + direction="l", }, - [0x1D20C]={ - category="so", - direction="on", + [0x1339E]={ + category="lo", + direction="l", }, - [0x1D20D]={ - category="so", + [0x1339F]={ + category="lo", + direction="l", + }, + [0x133A0]={ + category="lo", + direction="l", + }, + [0x133A1]={ + category="lo", + direction="l", + }, + [0x133A2]={ + category="lo", + direction="l", + }, + [0x133A3]={ + category="lo", + direction="l", + }, + [0x133A4]={ + category="lo", + direction="l", + }, + [0x133A5]={ + category="lo", + direction="l", + }, + [0x133A6]={ + category="lo", + direction="l", + }, + [0x133A7]={ + category="lo", + direction="l", + }, + [0x133A8]={ + category="lo", + direction="l", + }, + [0x133A9]={ + category="lo", + direction="l", + }, + [0x133AA]={ + category="lo", + direction="l", + }, + [0x133AB]={ + category="lo", + direction="l", + }, + [0x133AC]={ + category="lo", + direction="l", + }, + [0x133AD]={ + category="lo", + direction="l", + }, + [0x133AE]={ + category="lo", + direction="l", + }, + [0x133AF]={ + category="lo", + direction="l", + }, + [0x133B0]={ + category="lo", + direction="l", + }, + [0x133B1]={ + category="lo", + direction="l", + }, + [0x133B2]={ + category="lo", + direction="l", + }, + [0x133B3]={ + category="lo", + direction="l", + }, + [0x133B4]={ + category="lo", + direction="l", + }, + [0x133B5]={ + category="lo", + direction="l", + }, + [0x133B6]={ + category="lo", + direction="l", + }, + [0x133B7]={ + category="lo", + direction="l", + }, + [0x133B8]={ + category="lo", + direction="l", + }, + [0x133B9]={ + category="lo", + direction="l", + }, + [0x133BA]={ + category="lo", + direction="l", + }, + [0x133BB]={ + category="lo", + direction="l", + }, + [0x133BC]={ + category="lo", + direction="l", + }, + [0x133BD]={ + category="lo", + direction="l", + }, + [0x133BE]={ + category="lo", + direction="l", + }, + [0x133BF]={ + category="lo", + direction="l", + }, + [0x133C0]={ + category="lo", + direction="l", + }, + [0x133C1]={ + category="lo", + direction="l", + }, + [0x133C2]={ + category="lo", + direction="l", + }, + [0x133C3]={ + category="lo", + direction="l", + }, + [0x133C4]={ + category="lo", + direction="l", + }, + [0x133C5]={ + category="lo", + direction="l", + }, + [0x133C6]={ + category="lo", + direction="l", + }, + [0x133C7]={ + category="lo", + direction="l", + }, + [0x133C8]={ + category="lo", + direction="l", + }, + [0x133C9]={ + category="lo", + direction="l", + }, + [0x133CA]={ + category="lo", + direction="l", + }, + [0x133CB]={ + category="lo", + direction="l", + }, + [0x133CC]={ + category="lo", + direction="l", + }, + [0x133CD]={ + category="lo", + direction="l", + }, + [0x133CE]={ + category="lo", + direction="l", + }, + [0x133CF]={ + category="lo", + direction="l", + }, + [0x133D0]={ + category="lo", + direction="l", + }, + [0x133D1]={ + category="lo", + direction="l", + }, + [0x133D2]={ + category="lo", + direction="l", + }, + [0x133D3]={ + category="lo", + direction="l", + }, + [0x133D4]={ + category="lo", + direction="l", + }, + [0x133D5]={ + category="lo", + direction="l", + }, + [0x133D6]={ + category="lo", + direction="l", + }, + [0x133D7]={ + category="lo", + direction="l", + }, + [0x133D8]={ + category="lo", + direction="l", + }, + [0x133D9]={ + category="lo", + direction="l", + }, + [0x133DA]={ + category="lo", + direction="l", + }, + [0x133DB]={ + category="lo", + direction="l", + }, + [0x133DC]={ + category="lo", + direction="l", + }, + [0x133DD]={ + category="lo", + direction="l", + }, + [0x133DE]={ + category="lo", + direction="l", + }, + [0x133DF]={ + category="lo", + direction="l", + }, + [0x133E0]={ + category="lo", + direction="l", + }, + [0x133E1]={ + category="lo", + direction="l", + }, + [0x133E2]={ + category="lo", + direction="l", + }, + [0x133E3]={ + category="lo", + direction="l", + }, + [0x133E4]={ + category="lo", + direction="l", + }, + [0x133E5]={ + category="lo", + direction="l", + }, + [0x133E6]={ + category="lo", + direction="l", + }, + [0x133E7]={ + category="lo", + direction="l", + }, + [0x133E8]={ + category="lo", + direction="l", + }, + [0x133E9]={ + category="lo", + direction="l", + }, + [0x133EA]={ + category="lo", + direction="l", + }, + [0x133EB]={ + category="lo", + direction="l", + }, + [0x133EC]={ + category="lo", + direction="l", + }, + [0x133ED]={ + category="lo", + direction="l", + }, + [0x133EE]={ + category="lo", + direction="l", + }, + [0x133EF]={ + category="lo", + direction="l", + }, + [0x133F0]={ + category="lo", + direction="l", + }, + [0x133F1]={ + category="lo", + direction="l", + }, + [0x133F2]={ + category="lo", + direction="l", + }, + [0x133F3]={ + category="lo", + direction="l", + }, + [0x133F4]={ + category="lo", + direction="l", + }, + [0x133F5]={ + category="lo", + direction="l", + }, + [0x133F6]={ + category="lo", + direction="l", + }, + [0x133F7]={ + category="lo", + direction="l", + }, + [0x133F8]={ + category="lo", + direction="l", + }, + [0x133F9]={ + category="lo", + direction="l", + }, + [0x133FA]={ + category="lo", + direction="l", + }, + [0x133FB]={ + category="lo", + direction="l", + }, + [0x133FC]={ + category="lo", + direction="l", + }, + [0x133FD]={ + category="lo", + direction="l", + }, + [0x133FE]={ + category="lo", + direction="l", + }, + [0x133FF]={ + category="lo", + direction="l", + }, + [0x13400]={ + category="lo", + direction="l", + }, + [0x13401]={ + category="lo", + direction="l", + }, + [0x13402]={ + category="lo", + direction="l", + }, + [0x13403]={ + category="lo", + direction="l", + }, + [0x13404]={ + category="lo", + direction="l", + }, + [0x13405]={ + category="lo", + direction="l", + }, + [0x13406]={ + category="lo", + direction="l", + }, + [0x13407]={ + category="lo", + direction="l", + }, + [0x13408]={ + category="lo", + direction="l", + }, + [0x13409]={ + category="lo", + direction="l", + }, + [0x1340A]={ + category="lo", + direction="l", + }, + [0x1340B]={ + category="lo", + direction="l", + }, + [0x1340C]={ + category="lo", + direction="l", + }, + [0x1340D]={ + category="lo", + direction="l", + }, + [0x1340E]={ + category="lo", + direction="l", + }, + [0x1340F]={ + category="lo", + direction="l", + }, + [0x13410]={ + category="lo", + direction="l", + }, + [0x13411]={ + category="lo", + direction="l", + }, + [0x13412]={ + category="lo", + direction="l", + }, + [0x13413]={ + category="lo", + direction="l", + }, + [0x13414]={ + category="lo", + direction="l", + }, + [0x13415]={ + category="lo", + direction="l", + }, + [0x13416]={ + category="lo", + direction="l", + }, + [0x13417]={ + category="lo", + direction="l", + }, + [0x13418]={ + category="lo", + direction="l", + }, + [0x13419]={ + category="lo", + direction="l", + }, + [0x1341A]={ + category="lo", + direction="l", + }, + [0x1341B]={ + category="lo", + direction="l", + }, + [0x1341C]={ + category="lo", + direction="l", + }, + [0x1341D]={ + category="lo", + direction="l", + }, + [0x1341E]={ + category="lo", + direction="l", + }, + [0x1341F]={ + category="lo", + direction="l", + }, + [0x13420]={ + category="lo", + direction="l", + }, + [0x13421]={ + category="lo", + direction="l", + }, + [0x13422]={ + category="lo", + direction="l", + }, + [0x13423]={ + category="lo", + direction="l", + }, + [0x13424]={ + category="lo", + direction="l", + }, + [0x13425]={ + category="lo", + direction="l", + }, + [0x13426]={ + category="lo", + direction="l", + }, + [0x13427]={ + category="lo", + direction="l", + }, + [0x13428]={ + category="lo", + direction="l", + }, + [0x13429]={ + category="lo", + direction="l", + }, + [0x1342A]={ + category="lo", + direction="l", + }, + [0x1342B]={ + category="lo", + direction="l", + }, + [0x1342C]={ + category="lo", + direction="l", + }, + [0x1342D]={ + category="lo", + direction="l", + }, + [0x1342E]={ + category="lo", + direction="l", + }, + [0x16800]={ + category="lo", + direction="l", + }, + [0x16801]={ + category="lo", + direction="l", + }, + [0x16802]={ + category="lo", + direction="l", + }, + [0x16803]={ + category="lo", + direction="l", + }, + [0x16804]={ + category="lo", + direction="l", + }, + [0x16805]={ + category="lo", + direction="l", + }, + [0x16806]={ + category="lo", + direction="l", + }, + [0x16807]={ + category="lo", + direction="l", + }, + [0x16808]={ + category="lo", + direction="l", + }, + [0x16809]={ + category="lo", + direction="l", + }, + [0x1680A]={ + category="lo", + direction="l", + }, + [0x1680B]={ + category="lo", + direction="l", + }, + [0x1680C]={ + category="lo", + direction="l", + }, + [0x1680D]={ + category="lo", + direction="l", + }, + [0x1680E]={ + category="lo", + direction="l", + }, + [0x1680F]={ + category="lo", + direction="l", + }, + [0x16810]={ + category="lo", + direction="l", + }, + [0x16811]={ + category="lo", + direction="l", + }, + [0x16812]={ + category="lo", + direction="l", + }, + [0x16813]={ + category="lo", + direction="l", + }, + [0x16814]={ + category="lo", + direction="l", + }, + [0x16815]={ + category="lo", + direction="l", + }, + [0x16816]={ + category="lo", + direction="l", + }, + [0x16817]={ + category="lo", + direction="l", + }, + [0x16818]={ + category="lo", + direction="l", + }, + [0x16819]={ + category="lo", + direction="l", + }, + [0x1681A]={ + category="lo", + direction="l", + }, + [0x1681B]={ + category="lo", + direction="l", + }, + [0x1681C]={ + category="lo", + direction="l", + }, + [0x1681D]={ + category="lo", + direction="l", + }, + [0x1681E]={ + category="lo", + direction="l", + }, + [0x1681F]={ + category="lo", + direction="l", + }, + [0x16820]={ + category="lo", + direction="l", + }, + [0x16821]={ + category="lo", + direction="l", + }, + [0x16822]={ + category="lo", + direction="l", + }, + [0x16823]={ + category="lo", + direction="l", + }, + [0x16824]={ + category="lo", + direction="l", + }, + [0x16825]={ + category="lo", + direction="l", + }, + [0x16826]={ + category="lo", + direction="l", + }, + [0x16827]={ + category="lo", + direction="l", + }, + [0x16828]={ + category="lo", + direction="l", + }, + [0x16829]={ + category="lo", + direction="l", + }, + [0x1682A]={ + category="lo", + direction="l", + }, + [0x1682B]={ + category="lo", + direction="l", + }, + [0x1682C]={ + category="lo", + direction="l", + }, + [0x1682D]={ + category="lo", + direction="l", + }, + [0x1682E]={ + category="lo", + direction="l", + }, + [0x1682F]={ + category="lo", + direction="l", + }, + [0x16830]={ + category="lo", + direction="l", + }, + [0x16831]={ + category="lo", + direction="l", + }, + [0x16832]={ + category="lo", + direction="l", + }, + [0x16833]={ + category="lo", + direction="l", + }, + [0x16834]={ + category="lo", + direction="l", + }, + [0x16835]={ + category="lo", + direction="l", + }, + [0x16836]={ + category="lo", + direction="l", + }, + [0x16837]={ + category="lo", + direction="l", + }, + [0x16838]={ + category="lo", + direction="l", + }, + [0x16839]={ + category="lo", + direction="l", + }, + [0x1683A]={ + category="lo", + direction="l", + }, + [0x1683B]={ + category="lo", + direction="l", + }, + [0x1683C]={ + category="lo", + direction="l", + }, + [0x1683D]={ + category="lo", + direction="l", + }, + [0x1683E]={ + category="lo", + direction="l", + }, + [0x1683F]={ + category="lo", + direction="l", + }, + [0x16840]={ + category="lo", + direction="l", + }, + [0x16841]={ + category="lo", + direction="l", + }, + [0x16842]={ + category="lo", + direction="l", + }, + [0x16843]={ + category="lo", + direction="l", + }, + [0x16844]={ + category="lo", + direction="l", + }, + [0x16845]={ + category="lo", + direction="l", + }, + [0x16846]={ + category="lo", + direction="l", + }, + [0x16847]={ + category="lo", + direction="l", + }, + [0x16848]={ + category="lo", + direction="l", + }, + [0x16849]={ + category="lo", + direction="l", + }, + [0x1684A]={ + category="lo", + direction="l", + }, + [0x1684B]={ + category="lo", + direction="l", + }, + [0x1684C]={ + category="lo", + direction="l", + }, + [0x1684D]={ + category="lo", + direction="l", + }, + [0x1684E]={ + category="lo", + direction="l", + }, + [0x1684F]={ + category="lo", + direction="l", + }, + [0x16850]={ + category="lo", + direction="l", + }, + [0x16851]={ + category="lo", + direction="l", + }, + [0x16852]={ + category="lo", + direction="l", + }, + [0x16853]={ + category="lo", + direction="l", + }, + [0x16854]={ + category="lo", + direction="l", + }, + [0x16855]={ + category="lo", + direction="l", + }, + [0x16856]={ + category="lo", + direction="l", + }, + [0x16857]={ + category="lo", + direction="l", + }, + [0x16858]={ + category="lo", + direction="l", + }, + [0x16859]={ + category="lo", + direction="l", + }, + [0x1685A]={ + category="lo", + direction="l", + }, + [0x1685B]={ + category="lo", + direction="l", + }, + [0x1685C]={ + category="lo", + direction="l", + }, + [0x1685D]={ + category="lo", + direction="l", + }, + [0x1685E]={ + category="lo", + direction="l", + }, + [0x1685F]={ + category="lo", + direction="l", + }, + [0x16860]={ + category="lo", + direction="l", + }, + [0x16861]={ + category="lo", + direction="l", + }, + [0x16862]={ + category="lo", + direction="l", + }, + [0x16863]={ + category="lo", + direction="l", + }, + [0x16864]={ + category="lo", + direction="l", + }, + [0x16865]={ + category="lo", + direction="l", + }, + [0x16866]={ + category="lo", + direction="l", + }, + [0x16867]={ + category="lo", + direction="l", + }, + [0x16868]={ + category="lo", + direction="l", + }, + [0x16869]={ + category="lo", + direction="l", + }, + [0x1686A]={ + category="lo", + direction="l", + }, + [0x1686B]={ + category="lo", + direction="l", + }, + [0x1686C]={ + category="lo", + direction="l", + }, + [0x1686D]={ + category="lo", + direction="l", + }, + [0x1686E]={ + category="lo", + direction="l", + }, + [0x1686F]={ + category="lo", + direction="l", + }, + [0x16870]={ + category="lo", + direction="l", + }, + [0x16871]={ + category="lo", + direction="l", + }, + [0x16872]={ + category="lo", + direction="l", + }, + [0x16873]={ + category="lo", + direction="l", + }, + [0x16874]={ + category="lo", + direction="l", + }, + [0x16875]={ + category="lo", + direction="l", + }, + [0x16876]={ + category="lo", + direction="l", + }, + [0x16877]={ + category="lo", + direction="l", + }, + [0x16878]={ + category="lo", + direction="l", + }, + [0x16879]={ + category="lo", + direction="l", + }, + [0x1687A]={ + category="lo", + direction="l", + }, + [0x1687B]={ + category="lo", + direction="l", + }, + [0x1687C]={ + category="lo", + direction="l", + }, + [0x1687D]={ + category="lo", + direction="l", + }, + [0x1687E]={ + category="lo", + direction="l", + }, + [0x1687F]={ + category="lo", + direction="l", + }, + [0x16880]={ + category="lo", + direction="l", + }, + [0x16881]={ + category="lo", + direction="l", + }, + [0x16882]={ + category="lo", + direction="l", + }, + [0x16883]={ + category="lo", + direction="l", + }, + [0x16884]={ + category="lo", + direction="l", + }, + [0x16885]={ + category="lo", + direction="l", + }, + [0x16886]={ + category="lo", + direction="l", + }, + [0x16887]={ + category="lo", + direction="l", + }, + [0x16888]={ + category="lo", + direction="l", + }, + [0x16889]={ + category="lo", + direction="l", + }, + [0x1688A]={ + category="lo", + direction="l", + }, + [0x1688B]={ + category="lo", + direction="l", + }, + [0x1688C]={ + category="lo", + direction="l", + }, + [0x1688D]={ + category="lo", + direction="l", + }, + [0x1688E]={ + category="lo", + direction="l", + }, + [0x1688F]={ + category="lo", + direction="l", + }, + [0x16890]={ + category="lo", + direction="l", + }, + [0x16891]={ + category="lo", + direction="l", + }, + [0x16892]={ + category="lo", + direction="l", + }, + [0x16893]={ + category="lo", + direction="l", + }, + [0x16894]={ + category="lo", + direction="l", + }, + [0x16895]={ + category="lo", + direction="l", + }, + [0x16896]={ + category="lo", + direction="l", + }, + [0x16897]={ + category="lo", + direction="l", + }, + [0x16898]={ + category="lo", + direction="l", + }, + [0x16899]={ + category="lo", + direction="l", + }, + [0x1689A]={ + category="lo", + direction="l", + }, + [0x1689B]={ + category="lo", + direction="l", + }, + [0x1689C]={ + category="lo", + direction="l", + }, + [0x1689D]={ + category="lo", + direction="l", + }, + [0x1689E]={ + category="lo", + direction="l", + }, + [0x1689F]={ + category="lo", + direction="l", + }, + [0x168A0]={ + category="lo", + direction="l", + }, + [0x168A1]={ + category="lo", + direction="l", + }, + [0x168A2]={ + category="lo", + direction="l", + }, + [0x168A3]={ + category="lo", + direction="l", + }, + [0x168A4]={ + category="lo", + direction="l", + }, + [0x168A5]={ + category="lo", + direction="l", + }, + [0x168A6]={ + category="lo", + direction="l", + }, + [0x168A7]={ + category="lo", + direction="l", + }, + [0x168A8]={ + category="lo", + direction="l", + }, + [0x168A9]={ + category="lo", + direction="l", + }, + [0x168AA]={ + category="lo", + direction="l", + }, + [0x168AB]={ + category="lo", + direction="l", + }, + [0x168AC]={ + category="lo", + direction="l", + }, + [0x168AD]={ + category="lo", + direction="l", + }, + [0x168AE]={ + category="lo", + direction="l", + }, + [0x168AF]={ + category="lo", + direction="l", + }, + [0x168B0]={ + category="lo", + direction="l", + }, + [0x168B1]={ + category="lo", + direction="l", + }, + [0x168B2]={ + category="lo", + direction="l", + }, + [0x168B3]={ + category="lo", + direction="l", + }, + [0x168B4]={ + category="lo", + direction="l", + }, + [0x168B5]={ + category="lo", + direction="l", + }, + [0x168B6]={ + category="lo", + direction="l", + }, + [0x168B7]={ + category="lo", + direction="l", + }, + [0x168B8]={ + category="lo", + direction="l", + }, + [0x168B9]={ + category="lo", + direction="l", + }, + [0x168BA]={ + category="lo", + direction="l", + }, + [0x168BB]={ + category="lo", + direction="l", + }, + [0x168BC]={ + category="lo", + direction="l", + }, + [0x168BD]={ + category="lo", + direction="l", + }, + [0x168BE]={ + category="lo", + direction="l", + }, + [0x168BF]={ + category="lo", + direction="l", + }, + [0x168C0]={ + category="lo", + direction="l", + }, + [0x168C1]={ + category="lo", + direction="l", + }, + [0x168C2]={ + category="lo", + direction="l", + }, + [0x168C3]={ + category="lo", + direction="l", + }, + [0x168C4]={ + category="lo", + direction="l", + }, + [0x168C5]={ + category="lo", + direction="l", + }, + [0x168C6]={ + category="lo", + direction="l", + }, + [0x168C7]={ + category="lo", + direction="l", + }, + [0x168C8]={ + category="lo", + direction="l", + }, + [0x168C9]={ + category="lo", + direction="l", + }, + [0x168CA]={ + category="lo", + direction="l", + }, + [0x168CB]={ + category="lo", + direction="l", + }, + [0x168CC]={ + category="lo", + direction="l", + }, + [0x168CD]={ + category="lo", + direction="l", + }, + [0x168CE]={ + category="lo", + direction="l", + }, + [0x168CF]={ + category="lo", + direction="l", + }, + [0x168D0]={ + category="lo", + direction="l", + }, + [0x168D1]={ + category="lo", + direction="l", + }, + [0x168D2]={ + category="lo", + direction="l", + }, + [0x168D3]={ + category="lo", + direction="l", + }, + [0x168D4]={ + category="lo", + direction="l", + }, + [0x168D5]={ + category="lo", + direction="l", + }, + [0x168D6]={ + category="lo", + direction="l", + }, + [0x168D7]={ + category="lo", + direction="l", + }, + [0x168D8]={ + category="lo", + direction="l", + }, + [0x168D9]={ + category="lo", + direction="l", + }, + [0x168DA]={ + category="lo", + direction="l", + }, + [0x168DB]={ + category="lo", + direction="l", + }, + [0x168DC]={ + category="lo", + direction="l", + }, + [0x168DD]={ + category="lo", + direction="l", + }, + [0x168DE]={ + category="lo", + direction="l", + }, + [0x168DF]={ + category="lo", + direction="l", + }, + [0x168E0]={ + category="lo", + direction="l", + }, + [0x168E1]={ + category="lo", + direction="l", + }, + [0x168E2]={ + category="lo", + direction="l", + }, + [0x168E3]={ + category="lo", + direction="l", + }, + [0x168E4]={ + category="lo", + direction="l", + }, + [0x168E5]={ + category="lo", + direction="l", + }, + [0x168E6]={ + category="lo", + direction="l", + }, + [0x168E7]={ + category="lo", + direction="l", + }, + [0x168E8]={ + category="lo", + direction="l", + }, + [0x168E9]={ + category="lo", + direction="l", + }, + [0x168EA]={ + category="lo", + direction="l", + }, + [0x168EB]={ + category="lo", + direction="l", + }, + [0x168EC]={ + category="lo", + direction="l", + }, + [0x168ED]={ + category="lo", + direction="l", + }, + [0x168EE]={ + category="lo", + direction="l", + }, + [0x168EF]={ + category="lo", + direction="l", + }, + [0x168F0]={ + category="lo", + direction="l", + }, + [0x168F1]={ + category="lo", + direction="l", + }, + [0x168F2]={ + category="lo", + direction="l", + }, + [0x168F3]={ + category="lo", + direction="l", + }, + [0x168F4]={ + category="lo", + direction="l", + }, + [0x168F5]={ + category="lo", + direction="l", + }, + [0x168F6]={ + category="lo", + direction="l", + }, + [0x168F7]={ + category="lo", + direction="l", + }, + [0x168F8]={ + category="lo", + direction="l", + }, + [0x168F9]={ + category="lo", + direction="l", + }, + [0x168FA]={ + category="lo", + direction="l", + }, + [0x168FB]={ + category="lo", + direction="l", + }, + [0x168FC]={ + category="lo", + direction="l", + }, + [0x168FD]={ + category="lo", + direction="l", + }, + [0x168FE]={ + category="lo", + direction="l", + }, + [0x168FF]={ + category="lo", + direction="l", + }, + [0x16900]={ + category="lo", + direction="l", + }, + [0x16901]={ + category="lo", + direction="l", + }, + [0x16902]={ + category="lo", + direction="l", + }, + [0x16903]={ + category="lo", + direction="l", + }, + [0x16904]={ + category="lo", + direction="l", + }, + [0x16905]={ + category="lo", + direction="l", + }, + [0x16906]={ + category="lo", + direction="l", + }, + [0x16907]={ + category="lo", + direction="l", + }, + [0x16908]={ + category="lo", + direction="l", + }, + [0x16909]={ + category="lo", + direction="l", + }, + [0x1690A]={ + category="lo", + direction="l", + }, + [0x1690B]={ + category="lo", + direction="l", + }, + [0x1690C]={ + category="lo", + direction="l", + }, + [0x1690D]={ + category="lo", + direction="l", + }, + [0x1690E]={ + category="lo", + direction="l", + }, + [0x1690F]={ + category="lo", + direction="l", + }, + [0x16910]={ + category="lo", + direction="l", + }, + [0x16911]={ + category="lo", + direction="l", + }, + [0x16912]={ + category="lo", + direction="l", + }, + [0x16913]={ + category="lo", + direction="l", + }, + [0x16914]={ + category="lo", + direction="l", + }, + [0x16915]={ + category="lo", + direction="l", + }, + [0x16916]={ + category="lo", + direction="l", + }, + [0x16917]={ + category="lo", + direction="l", + }, + [0x16918]={ + category="lo", + direction="l", + }, + [0x16919]={ + category="lo", + direction="l", + }, + [0x1691A]={ + category="lo", + direction="l", + }, + [0x1691B]={ + category="lo", + direction="l", + }, + [0x1691C]={ + category="lo", + direction="l", + }, + [0x1691D]={ + category="lo", + direction="l", + }, + [0x1691E]={ + category="lo", + direction="l", + }, + [0x1691F]={ + category="lo", + direction="l", + }, + [0x16920]={ + category="lo", + direction="l", + }, + [0x16921]={ + category="lo", + direction="l", + }, + [0x16922]={ + category="lo", + direction="l", + }, + [0x16923]={ + category="lo", + direction="l", + }, + [0x16924]={ + category="lo", + direction="l", + }, + [0x16925]={ + category="lo", + direction="l", + }, + [0x16926]={ + category="lo", + direction="l", + }, + [0x16927]={ + category="lo", + direction="l", + }, + [0x16928]={ + category="lo", + direction="l", + }, + [0x16929]={ + category="lo", + direction="l", + }, + [0x1692A]={ + category="lo", + direction="l", + }, + [0x1692B]={ + category="lo", + direction="l", + }, + [0x1692C]={ + category="lo", + direction="l", + }, + [0x1692D]={ + category="lo", + direction="l", + }, + [0x1692E]={ + category="lo", + direction="l", + }, + [0x1692F]={ + category="lo", + direction="l", + }, + [0x16930]={ + category="lo", + direction="l", + }, + [0x16931]={ + category="lo", + direction="l", + }, + [0x16932]={ + category="lo", + direction="l", + }, + [0x16933]={ + category="lo", + direction="l", + }, + [0x16934]={ + category="lo", + direction="l", + }, + [0x16935]={ + category="lo", + direction="l", + }, + [0x16936]={ + category="lo", + direction="l", + }, + [0x16937]={ + category="lo", + direction="l", + }, + [0x16938]={ + category="lo", + direction="l", + }, + [0x16939]={ + category="lo", + direction="l", + }, + [0x1693A]={ + category="lo", + direction="l", + }, + [0x1693B]={ + category="lo", + direction="l", + }, + [0x1693C]={ + category="lo", + direction="l", + }, + [0x1693D]={ + category="lo", + direction="l", + }, + [0x1693E]={ + category="lo", + direction="l", + }, + [0x1693F]={ + category="lo", + direction="l", + }, + [0x16940]={ + category="lo", + direction="l", + }, + [0x16941]={ + category="lo", + direction="l", + }, + [0x16942]={ + category="lo", + direction="l", + }, + [0x16943]={ + category="lo", + direction="l", + }, + [0x16944]={ + category="lo", + direction="l", + }, + [0x16945]={ + category="lo", + direction="l", + }, + [0x16946]={ + category="lo", + direction="l", + }, + [0x16947]={ + category="lo", + direction="l", + }, + [0x16948]={ + category="lo", + direction="l", + }, + [0x16949]={ + category="lo", + direction="l", + }, + [0x1694A]={ + category="lo", + direction="l", + }, + [0x1694B]={ + category="lo", + direction="l", + }, + [0x1694C]={ + category="lo", + direction="l", + }, + [0x1694D]={ + category="lo", + direction="l", + }, + [0x1694E]={ + category="lo", + direction="l", + }, + [0x1694F]={ + category="lo", + direction="l", + }, + [0x16950]={ + category="lo", + direction="l", + }, + [0x16951]={ + category="lo", + direction="l", + }, + [0x16952]={ + category="lo", + direction="l", + }, + [0x16953]={ + category="lo", + direction="l", + }, + [0x16954]={ + category="lo", + direction="l", + }, + [0x16955]={ + category="lo", + direction="l", + }, + [0x16956]={ + category="lo", + direction="l", + }, + [0x16957]={ + category="lo", + direction="l", + }, + [0x16958]={ + category="lo", + direction="l", + }, + [0x16959]={ + category="lo", + direction="l", + }, + [0x1695A]={ + category="lo", + direction="l", + }, + [0x1695B]={ + category="lo", + direction="l", + }, + [0x1695C]={ + category="lo", + direction="l", + }, + [0x1695D]={ + category="lo", + direction="l", + }, + [0x1695E]={ + category="lo", + direction="l", + }, + [0x1695F]={ + category="lo", + direction="l", + }, + [0x16960]={ + category="lo", + direction="l", + }, + [0x16961]={ + category="lo", + direction="l", + }, + [0x16962]={ + category="lo", + direction="l", + }, + [0x16963]={ + category="lo", + direction="l", + }, + [0x16964]={ + category="lo", + direction="l", + }, + [0x16965]={ + category="lo", + direction="l", + }, + [0x16966]={ + category="lo", + direction="l", + }, + [0x16967]={ + category="lo", + direction="l", + }, + [0x16968]={ + category="lo", + direction="l", + }, + [0x16969]={ + category="lo", + direction="l", + }, + [0x1696A]={ + category="lo", + direction="l", + }, + [0x1696B]={ + category="lo", + direction="l", + }, + [0x1696C]={ + category="lo", + direction="l", + }, + [0x1696D]={ + category="lo", + direction="l", + }, + [0x1696E]={ + category="lo", + direction="l", + }, + [0x1696F]={ + category="lo", + direction="l", + }, + [0x16970]={ + category="lo", + direction="l", + }, + [0x16971]={ + category="lo", + direction="l", + }, + [0x16972]={ + category="lo", + direction="l", + }, + [0x16973]={ + category="lo", + direction="l", + }, + [0x16974]={ + category="lo", + direction="l", + }, + [0x16975]={ + category="lo", + direction="l", + }, + [0x16976]={ + category="lo", + direction="l", + }, + [0x16977]={ + category="lo", + direction="l", + }, + [0x16978]={ + category="lo", + direction="l", + }, + [0x16979]={ + category="lo", + direction="l", + }, + [0x1697A]={ + category="lo", + direction="l", + }, + [0x1697B]={ + category="lo", + direction="l", + }, + [0x1697C]={ + category="lo", + direction="l", + }, + [0x1697D]={ + category="lo", + direction="l", + }, + [0x1697E]={ + category="lo", + direction="l", + }, + [0x1697F]={ + category="lo", + direction="l", + }, + [0x16980]={ + category="lo", + direction="l", + }, + [0x16981]={ + category="lo", + direction="l", + }, + [0x16982]={ + category="lo", + direction="l", + }, + [0x16983]={ + category="lo", + direction="l", + }, + [0x16984]={ + category="lo", + direction="l", + }, + [0x16985]={ + category="lo", + direction="l", + }, + [0x16986]={ + category="lo", + direction="l", + }, + [0x16987]={ + category="lo", + direction="l", + }, + [0x16988]={ + category="lo", + direction="l", + }, + [0x16989]={ + category="lo", + direction="l", + }, + [0x1698A]={ + category="lo", + direction="l", + }, + [0x1698B]={ + category="lo", + direction="l", + }, + [0x1698C]={ + category="lo", + direction="l", + }, + [0x1698D]={ + category="lo", + direction="l", + }, + [0x1698E]={ + category="lo", + direction="l", + }, + [0x1698F]={ + category="lo", + direction="l", + }, + [0x16990]={ + category="lo", + direction="l", + }, + [0x16991]={ + category="lo", + direction="l", + }, + [0x16992]={ + category="lo", + direction="l", + }, + [0x16993]={ + category="lo", + direction="l", + }, + [0x16994]={ + category="lo", + direction="l", + }, + [0x16995]={ + category="lo", + direction="l", + }, + [0x16996]={ + category="lo", + direction="l", + }, + [0x16997]={ + category="lo", + direction="l", + }, + [0x16998]={ + category="lo", + direction="l", + }, + [0x16999]={ + category="lo", + direction="l", + }, + [0x1699A]={ + category="lo", + direction="l", + }, + [0x1699B]={ + category="lo", + direction="l", + }, + [0x1699C]={ + category="lo", + direction="l", + }, + [0x1699D]={ + category="lo", + direction="l", + }, + [0x1699E]={ + category="lo", + direction="l", + }, + [0x1699F]={ + category="lo", + direction="l", + }, + [0x169A0]={ + category="lo", + direction="l", + }, + [0x169A1]={ + category="lo", + direction="l", + }, + [0x169A2]={ + category="lo", + direction="l", + }, + [0x169A3]={ + category="lo", + direction="l", + }, + [0x169A4]={ + category="lo", + direction="l", + }, + [0x169A5]={ + category="lo", + direction="l", + }, + [0x169A6]={ + category="lo", + direction="l", + }, + [0x169A7]={ + category="lo", + direction="l", + }, + [0x169A8]={ + category="lo", + direction="l", + }, + [0x169A9]={ + category="lo", + direction="l", + }, + [0x169AA]={ + category="lo", + direction="l", + }, + [0x169AB]={ + category="lo", + direction="l", + }, + [0x169AC]={ + category="lo", + direction="l", + }, + [0x169AD]={ + category="lo", + direction="l", + }, + [0x169AE]={ + category="lo", + direction="l", + }, + [0x169AF]={ + category="lo", + direction="l", + }, + [0x169B0]={ + category="lo", + direction="l", + }, + [0x169B1]={ + category="lo", + direction="l", + }, + [0x169B2]={ + category="lo", + direction="l", + }, + [0x169B3]={ + category="lo", + direction="l", + }, + [0x169B4]={ + category="lo", + direction="l", + }, + [0x169B5]={ + category="lo", + direction="l", + }, + [0x169B6]={ + category="lo", + direction="l", + }, + [0x169B7]={ + category="lo", + direction="l", + }, + [0x169B8]={ + category="lo", + direction="l", + }, + [0x169B9]={ + category="lo", + direction="l", + }, + [0x169BA]={ + category="lo", + direction="l", + }, + [0x169BB]={ + category="lo", + direction="l", + }, + [0x169BC]={ + category="lo", + direction="l", + }, + [0x169BD]={ + category="lo", + direction="l", + }, + [0x169BE]={ + category="lo", + direction="l", + }, + [0x169BF]={ + category="lo", + direction="l", + }, + [0x169C0]={ + category="lo", + direction="l", + }, + [0x169C1]={ + category="lo", + direction="l", + }, + [0x169C2]={ + category="lo", + direction="l", + }, + [0x169C3]={ + category="lo", + direction="l", + }, + [0x169C4]={ + category="lo", + direction="l", + }, + [0x169C5]={ + category="lo", + direction="l", + }, + [0x169C6]={ + category="lo", + direction="l", + }, + [0x169C7]={ + category="lo", + direction="l", + }, + [0x169C8]={ + category="lo", + direction="l", + }, + [0x169C9]={ + category="lo", + direction="l", + }, + [0x169CA]={ + category="lo", + direction="l", + }, + [0x169CB]={ + category="lo", + direction="l", + }, + [0x169CC]={ + category="lo", + direction="l", + }, + [0x169CD]={ + category="lo", + direction="l", + }, + [0x169CE]={ + category="lo", + direction="l", + }, + [0x169CF]={ + category="lo", + direction="l", + }, + [0x169D0]={ + category="lo", + direction="l", + }, + [0x169D1]={ + category="lo", + direction="l", + }, + [0x169D2]={ + category="lo", + direction="l", + }, + [0x169D3]={ + category="lo", + direction="l", + }, + [0x169D4]={ + category="lo", + direction="l", + }, + [0x169D5]={ + category="lo", + direction="l", + }, + [0x169D6]={ + category="lo", + direction="l", + }, + [0x169D7]={ + category="lo", + direction="l", + }, + [0x169D8]={ + category="lo", + direction="l", + }, + [0x169D9]={ + category="lo", + direction="l", + }, + [0x169DA]={ + category="lo", + direction="l", + }, + [0x169DB]={ + category="lo", + direction="l", + }, + [0x169DC]={ + category="lo", + direction="l", + }, + [0x169DD]={ + category="lo", + direction="l", + }, + [0x169DE]={ + category="lo", + direction="l", + }, + [0x169DF]={ + category="lo", + direction="l", + }, + [0x169E0]={ + category="lo", + direction="l", + }, + [0x169E1]={ + category="lo", + direction="l", + }, + [0x169E2]={ + category="lo", + direction="l", + }, + [0x169E3]={ + category="lo", + direction="l", + }, + [0x169E4]={ + category="lo", + direction="l", + }, + [0x169E5]={ + category="lo", + direction="l", + }, + [0x169E6]={ + category="lo", + direction="l", + }, + [0x169E7]={ + category="lo", + direction="l", + }, + [0x169E8]={ + category="lo", + direction="l", + }, + [0x169E9]={ + category="lo", + direction="l", + }, + [0x169EA]={ + category="lo", + direction="l", + }, + [0x169EB]={ + category="lo", + direction="l", + }, + [0x169EC]={ + category="lo", + direction="l", + }, + [0x169ED]={ + category="lo", + direction="l", + }, + [0x169EE]={ + category="lo", + direction="l", + }, + [0x169EF]={ + category="lo", + direction="l", + }, + [0x169F0]={ + category="lo", + direction="l", + }, + [0x169F1]={ + category="lo", + direction="l", + }, + [0x169F2]={ + category="lo", + direction="l", + }, + [0x169F3]={ + category="lo", + direction="l", + }, + [0x169F4]={ + category="lo", + direction="l", + }, + [0x169F5]={ + category="lo", + direction="l", + }, + [0x169F6]={ + category="lo", + direction="l", + }, + [0x169F7]={ + category="lo", + direction="l", + }, + [0x169F8]={ + category="lo", + direction="l", + }, + [0x169F9]={ + category="lo", + direction="l", + }, + [0x169FA]={ + category="lo", + direction="l", + }, + [0x169FB]={ + category="lo", + direction="l", + }, + [0x169FC]={ + category="lo", + direction="l", + }, + [0x169FD]={ + category="lo", + direction="l", + }, + [0x169FE]={ + category="lo", + direction="l", + }, + [0x169FF]={ + category="lo", + direction="l", + }, + [0x16A00]={ + category="lo", + direction="l", + }, + [0x16A01]={ + category="lo", + direction="l", + }, + [0x16A02]={ + category="lo", + direction="l", + }, + [0x16A03]={ + category="lo", + direction="l", + }, + [0x16A04]={ + category="lo", + direction="l", + }, + [0x16A05]={ + category="lo", + direction="l", + }, + [0x16A06]={ + category="lo", + direction="l", + }, + [0x16A07]={ + category="lo", + direction="l", + }, + [0x16A08]={ + category="lo", + direction="l", + }, + [0x16A09]={ + category="lo", + direction="l", + }, + [0x16A0A]={ + category="lo", + direction="l", + }, + [0x16A0B]={ + category="lo", + direction="l", + }, + [0x16A0C]={ + category="lo", + direction="l", + }, + [0x16A0D]={ + category="lo", + direction="l", + }, + [0x16A0E]={ + category="lo", + direction="l", + }, + [0x16A0F]={ + category="lo", + direction="l", + }, + [0x16A10]={ + category="lo", + direction="l", + }, + [0x16A11]={ + category="lo", + direction="l", + }, + [0x16A12]={ + category="lo", + direction="l", + }, + [0x16A13]={ + category="lo", + direction="l", + }, + [0x16A14]={ + category="lo", + direction="l", + }, + [0x16A15]={ + category="lo", + direction="l", + }, + [0x16A16]={ + category="lo", + direction="l", + }, + [0x16A17]={ + category="lo", + direction="l", + }, + [0x16A18]={ + category="lo", + direction="l", + }, + [0x16A19]={ + category="lo", + direction="l", + }, + [0x16A1A]={ + category="lo", + direction="l", + }, + [0x16A1B]={ + category="lo", + direction="l", + }, + [0x16A1C]={ + category="lo", + direction="l", + }, + [0x16A1D]={ + category="lo", + direction="l", + }, + [0x16A1E]={ + category="lo", + direction="l", + }, + [0x16A1F]={ + category="lo", + direction="l", + }, + [0x16A20]={ + category="lo", + direction="l", + }, + [0x16A21]={ + category="lo", + direction="l", + }, + [0x16A22]={ + category="lo", + direction="l", + }, + [0x16A23]={ + category="lo", + direction="l", + }, + [0x16A24]={ + category="lo", + direction="l", + }, + [0x16A25]={ + category="lo", + direction="l", + }, + [0x16A26]={ + category="lo", + direction="l", + }, + [0x16A27]={ + category="lo", + direction="l", + }, + [0x16A28]={ + category="lo", + direction="l", + }, + [0x16A29]={ + category="lo", + direction="l", + }, + [0x16A2A]={ + category="lo", + direction="l", + }, + [0x16A2B]={ + category="lo", + direction="l", + }, + [0x16A2C]={ + category="lo", + direction="l", + }, + [0x16A2D]={ + category="lo", + direction="l", + }, + [0x16A2E]={ + category="lo", + direction="l", + }, + [0x16A2F]={ + category="lo", + direction="l", + }, + [0x16A30]={ + category="lo", + direction="l", + }, + [0x16A31]={ + category="lo", + direction="l", + }, + [0x16A32]={ + category="lo", + direction="l", + }, + [0x16A33]={ + category="lo", + direction="l", + }, + [0x16A34]={ + category="lo", + direction="l", + }, + [0x16A35]={ + category="lo", + direction="l", + }, + [0x16A36]={ + category="lo", + direction="l", + }, + [0x16A37]={ + category="lo", + direction="l", + }, + [0x16A38]={ + category="lo", + direction="l", + }, + [0x16A40]={ + category="lo", + direction="l", + }, + [0x16A41]={ + category="lo", + direction="l", + }, + [0x16A42]={ + category="lo", + direction="l", + }, + [0x16A43]={ + category="lo", + direction="l", + }, + [0x16A44]={ + category="lo", + direction="l", + }, + [0x16A45]={ + category="lo", + direction="l", + }, + [0x16A46]={ + category="lo", + direction="l", + }, + [0x16A47]={ + category="lo", + direction="l", + }, + [0x16A48]={ + category="lo", + direction="l", + }, + [0x16A49]={ + category="lo", + direction="l", + }, + [0x16A4A]={ + category="lo", + direction="l", + }, + [0x16A4B]={ + category="lo", + direction="l", + }, + [0x16A4C]={ + category="lo", + direction="l", + }, + [0x16A4D]={ + category="lo", + direction="l", + }, + [0x16A4E]={ + category="lo", + direction="l", + }, + [0x16A4F]={ + category="lo", + direction="l", + }, + [0x16A50]={ + category="lo", + direction="l", + }, + [0x16A51]={ + category="lo", + direction="l", + }, + [0x16A52]={ + category="lo", + direction="l", + }, + [0x16A53]={ + category="lo", + direction="l", + }, + [0x16A54]={ + category="lo", + direction="l", + }, + [0x16A55]={ + category="lo", + direction="l", + }, + [0x16A56]={ + category="lo", + direction="l", + }, + [0x16A57]={ + category="lo", + direction="l", + }, + [0x16A58]={ + category="lo", + direction="l", + }, + [0x16A59]={ + category="lo", + direction="l", + }, + [0x16A5A]={ + category="lo", + direction="l", + }, + [0x16A5B]={ + category="lo", + direction="l", + }, + [0x16A5C]={ + category="lo", + direction="l", + }, + [0x16A5D]={ + category="lo", + direction="l", + }, + [0x16A5E]={ + category="lo", + direction="l", + }, + [0x16A60]={ + category="nd", + direction="l", + }, + [0x16A61]={ + category="nd", + direction="l", + }, + [0x16A62]={ + category="nd", + direction="l", + }, + [0x16A63]={ + category="nd", + direction="l", + }, + [0x16A64]={ + category="nd", + direction="l", + }, + [0x16A65]={ + category="nd", + direction="l", + }, + [0x16A66]={ + category="nd", + direction="l", + }, + [0x16A67]={ + category="nd", + direction="l", + }, + [0x16A68]={ + category="nd", + direction="l", + }, + [0x16A69]={ + category="nd", + direction="l", + }, + [0x16A6E]={ + category="po", + direction="l", + }, + [0x16A6F]={ + category="po", + direction="l", + }, + [0x16AD0]={ + category="lo", + direction="l", + }, + [0x16AD1]={ + category="lo", + direction="l", + }, + [0x16AD2]={ + category="lo", + direction="l", + }, + [0x16AD3]={ + category="lo", + direction="l", + }, + [0x16AD4]={ + category="lo", + direction="l", + }, + [0x16AD5]={ + category="lo", + direction="l", + }, + [0x16AD6]={ + category="lo", + direction="l", + }, + [0x16AD7]={ + category="lo", + direction="l", + }, + [0x16AD8]={ + category="lo", + direction="l", + }, + [0x16AD9]={ + category="lo", + direction="l", + }, + [0x16ADA]={ + category="lo", + direction="l", + }, + [0x16ADB]={ + category="lo", + direction="l", + }, + [0x16ADC]={ + category="lo", + direction="l", + }, + [0x16ADD]={ + category="lo", + direction="l", + }, + [0x16ADE]={ + category="lo", + direction="l", + }, + [0x16ADF]={ + category="lo", + direction="l", + }, + [0x16AE0]={ + category="lo", + direction="l", + }, + [0x16AE1]={ + category="lo", + direction="l", + }, + [0x16AE2]={ + category="lo", + direction="l", + }, + [0x16AE3]={ + category="lo", + direction="l", + }, + [0x16AE4]={ + category="lo", + direction="l", + }, + [0x16AE5]={ + category="lo", + direction="l", + }, + [0x16AE6]={ + category="lo", + direction="l", + }, + [0x16AE7]={ + category="lo", + direction="l", + }, + [0x16AE8]={ + category="lo", + direction="l", + }, + [0x16AE9]={ + category="lo", + direction="l", + }, + [0x16AEA]={ + category="lo", + direction="l", + }, + [0x16AEB]={ + category="lo", + direction="l", + }, + [0x16AEC]={ + category="lo", + direction="l", + }, + [0x16AED]={ + category="lo", + direction="l", + }, + [0x16AF0]={ + category="mn", + direction="nsm", + }, + [0x16AF1]={ + category="mn", + direction="nsm", + }, + [0x16AF2]={ + category="mn", + direction="nsm", + }, + [0x16AF3]={ + category="mn", + direction="nsm", + }, + [0x16AF4]={ + category="mn", + direction="nsm", + }, + [0x16AF5]={ + category="po", + direction="l", + }, + [0x16B00]={ + category="lo", + direction="l", + }, + [0x16B01]={ + category="lo", + direction="l", + }, + [0x16B02]={ + category="lo", + direction="l", + }, + [0x16B03]={ + category="lo", + direction="l", + }, + [0x16B04]={ + category="lo", + direction="l", + }, + [0x16B05]={ + category="lo", + direction="l", + }, + [0x16B06]={ + category="lo", + direction="l", + }, + [0x16B07]={ + category="lo", + direction="l", + }, + [0x16B08]={ + category="lo", + direction="l", + }, + [0x16B09]={ + category="lo", + direction="l", + }, + [0x16B0A]={ + category="lo", + direction="l", + }, + [0x16B0B]={ + category="lo", + direction="l", + }, + [0x16B0C]={ + category="lo", + direction="l", + }, + [0x16B0D]={ + category="lo", + direction="l", + }, + [0x16B0E]={ + category="lo", + direction="l", + }, + [0x16B0F]={ + category="lo", + direction="l", + }, + [0x16B10]={ + category="lo", + direction="l", + }, + [0x16B11]={ + category="lo", + direction="l", + }, + [0x16B12]={ + category="lo", + direction="l", + }, + [0x16B13]={ + category="lo", + direction="l", + }, + [0x16B14]={ + category="lo", + direction="l", + }, + [0x16B15]={ + category="lo", + direction="l", + }, + [0x16B16]={ + category="lo", + direction="l", + }, + [0x16B17]={ + category="lo", + direction="l", + }, + [0x16B18]={ + category="lo", + direction="l", + }, + [0x16B19]={ + category="lo", + direction="l", + }, + [0x16B1A]={ + category="lo", + direction="l", + }, + [0x16B1B]={ + category="lo", + direction="l", + }, + [0x16B1C]={ + category="lo", + direction="l", + }, + [0x16B1D]={ + category="lo", + direction="l", + }, + [0x16B1E]={ + category="lo", + direction="l", + }, + [0x16B1F]={ + category="lo", + direction="l", + }, + [0x16B20]={ + category="lo", + direction="l", + }, + [0x16B21]={ + category="lo", + direction="l", + }, + [0x16B22]={ + category="lo", + direction="l", + }, + [0x16B23]={ + category="lo", + direction="l", + }, + [0x16B24]={ + category="lo", + direction="l", + }, + [0x16B25]={ + category="lo", + direction="l", + }, + [0x16B26]={ + category="lo", + direction="l", + }, + [0x16B27]={ + category="lo", + direction="l", + }, + [0x16B28]={ + category="lo", + direction="l", + }, + [0x16B29]={ + category="lo", + direction="l", + }, + [0x16B2A]={ + category="lo", + direction="l", + }, + [0x16B2B]={ + category="lo", + direction="l", + }, + [0x16B2C]={ + category="lo", + direction="l", + }, + [0x16B2D]={ + category="lo", + direction="l", + }, + [0x16B2E]={ + category="lo", + direction="l", + }, + [0x16B2F]={ + category="lo", + direction="l", + }, + [0x16B30]={ + category="mn", + direction="nsm", + }, + [0x16B31]={ + category="mn", + direction="nsm", + }, + [0x16B32]={ + category="mn", + direction="nsm", + }, + [0x16B33]={ + category="mn", + direction="nsm", + }, + [0x16B34]={ + category="mn", + direction="nsm", + }, + [0x16B35]={ + category="mn", + direction="nsm", + }, + [0x16B36]={ + category="mn", + direction="nsm", + }, + [0x16B37]={ + category="po", + direction="l", + }, + [0x16B38]={ + category="po", + direction="l", + }, + [0x16B39]={ + category="po", + direction="l", + }, + [0x16B3A]={ + category="po", + direction="l", + }, + [0x16B3B]={ + category="po", + direction="l", + }, + [0x16B3C]={ + category="so", + direction="l", + }, + [0x16B3D]={ + category="so", + direction="l", + }, + [0x16B3E]={ + category="so", + direction="l", + }, + [0x16B3F]={ + category="so", + direction="l", + }, + [0x16B40]={ + category="lm", + direction="l", + }, + [0x16B41]={ + category="lm", + direction="l", + }, + [0x16B42]={ + category="lm", + direction="l", + }, + [0x16B43]={ + category="lm", + direction="l", + }, + [0x16B44]={ + category="po", + direction="l", + }, + [0x16B45]={ + category="so", + direction="l", + }, + [0x16B50]={ + category="nd", + direction="l", + }, + [0x16B51]={ + category="nd", + direction="l", + }, + [0x16B52]={ + category="nd", + direction="l", + }, + [0x16B53]={ + category="nd", + direction="l", + }, + [0x16B54]={ + category="nd", + direction="l", + }, + [0x16B55]={ + category="nd", + direction="l", + }, + [0x16B56]={ + category="nd", + direction="l", + }, + [0x16B57]={ + category="nd", + direction="l", + }, + [0x16B58]={ + category="nd", + direction="l", + }, + [0x16B59]={ + category="nd", + direction="l", + }, + [0x16B5B]={ + category="no", + direction="l", + }, + [0x16B5C]={ + category="no", + direction="l", + }, + [0x16B5D]={ + category="no", + direction="l", + }, + [0x16B5E]={ + category="no", + direction="l", + }, + [0x16B5F]={ + category="no", + direction="l", + }, + [0x16B60]={ + category="no", + direction="l", + }, + [0x16B61]={ + category="no", + direction="l", + }, + [0x16B63]={ + category="lo", + direction="l", + }, + [0x16B64]={ + category="lo", + direction="l", + }, + [0x16B65]={ + category="lo", + direction="l", + }, + [0x16B66]={ + category="lo", + direction="l", + }, + [0x16B67]={ + category="lo", + direction="l", + }, + [0x16B68]={ + category="lo", + direction="l", + }, + [0x16B69]={ + category="lo", + direction="l", + }, + [0x16B6A]={ + category="lo", + direction="l", + }, + [0x16B6B]={ + category="lo", + direction="l", + }, + [0x16B6C]={ + category="lo", + direction="l", + }, + [0x16B6D]={ + category="lo", + direction="l", + }, + [0x16B6E]={ + category="lo", + direction="l", + }, + [0x16B6F]={ + category="lo", + direction="l", + }, + [0x16B70]={ + category="lo", + direction="l", + }, + [0x16B71]={ + category="lo", + direction="l", + }, + [0x16B72]={ + category="lo", + direction="l", + }, + [0x16B73]={ + category="lo", + direction="l", + }, + [0x16B74]={ + category="lo", + direction="l", + }, + [0x16B75]={ + category="lo", + direction="l", + }, + [0x16B76]={ + category="lo", + direction="l", + }, + [0x16B77]={ + category="lo", + direction="l", + }, + [0x16B7D]={ + category="lo", + direction="l", + }, + [0x16B7E]={ + category="lo", + direction="l", + }, + [0x16B7F]={ + category="lo", + direction="l", + }, + [0x16B80]={ + category="lo", + direction="l", + }, + [0x16B81]={ + category="lo", + direction="l", + }, + [0x16B82]={ + category="lo", + direction="l", + }, + [0x16B83]={ + category="lo", + direction="l", + }, + [0x16B84]={ + category="lo", + direction="l", + }, + [0x16B85]={ + category="lo", + direction="l", + }, + [0x16B86]={ + category="lo", + direction="l", + }, + [0x16B87]={ + category="lo", + direction="l", + }, + [0x16B88]={ + category="lo", + direction="l", + }, + [0x16B89]={ + category="lo", + direction="l", + }, + [0x16B8A]={ + category="lo", + direction="l", + }, + [0x16B8B]={ + category="lo", + direction="l", + }, + [0x16B8C]={ + category="lo", + direction="l", + }, + [0x16B8D]={ + category="lo", + direction="l", + }, + [0x16B8E]={ + category="lo", + direction="l", + }, + [0x16B8F]={ + category="lo", + direction="l", + }, + [0x16F00]={ + category="lo", + direction="l", + }, + [0x16F01]={ + category="lo", + direction="l", + }, + [0x16F02]={ + category="lo", + direction="l", + }, + [0x16F03]={ + category="lo", + direction="l", + }, + [0x16F04]={ + category="lo", + direction="l", + }, + [0x16F05]={ + category="lo", + direction="l", + }, + [0x16F06]={ + category="lo", + direction="l", + }, + [0x16F07]={ + category="lo", + direction="l", + }, + [0x16F08]={ + category="lo", + direction="l", + }, + [0x16F09]={ + category="lo", + direction="l", + }, + [0x16F0A]={ + category="lo", + direction="l", + }, + [0x16F0B]={ + category="lo", + direction="l", + }, + [0x16F0C]={ + category="lo", + direction="l", + }, + [0x16F0D]={ + category="lo", + direction="l", + }, + [0x16F0E]={ + category="lo", + direction="l", + }, + [0x16F0F]={ + category="lo", + direction="l", + }, + [0x16F10]={ + category="lo", + direction="l", + }, + [0x16F11]={ + category="lo", + direction="l", + }, + [0x16F12]={ + category="lo", + direction="l", + }, + [0x16F13]={ + category="lo", + direction="l", + }, + [0x16F14]={ + category="lo", + direction="l", + }, + [0x16F15]={ + category="lo", + direction="l", + }, + [0x16F16]={ + category="lo", + direction="l", + }, + [0x16F17]={ + category="lo", + direction="l", + }, + [0x16F18]={ + category="lo", + direction="l", + }, + [0x16F19]={ + category="lo", + direction="l", + }, + [0x16F1A]={ + category="lo", + direction="l", + }, + [0x16F1B]={ + category="lo", + direction="l", + }, + [0x16F1C]={ + category="lo", + direction="l", + }, + [0x16F1D]={ + category="lo", + direction="l", + }, + [0x16F1E]={ + category="lo", + direction="l", + }, + [0x16F1F]={ + category="lo", + direction="l", + }, + [0x16F20]={ + category="lo", + direction="l", + }, + [0x16F21]={ + category="lo", + direction="l", + }, + [0x16F22]={ + category="lo", + direction="l", + }, + [0x16F23]={ + category="lo", + direction="l", + }, + [0x16F24]={ + category="lo", + direction="l", + }, + [0x16F25]={ + category="lo", + direction="l", + }, + [0x16F26]={ + category="lo", + direction="l", + }, + [0x16F27]={ + category="lo", + direction="l", + }, + [0x16F28]={ + category="lo", + direction="l", + }, + [0x16F29]={ + category="lo", + direction="l", + }, + [0x16F2A]={ + category="lo", + direction="l", + }, + [0x16F2B]={ + category="lo", + direction="l", + }, + [0x16F2C]={ + category="lo", + direction="l", + }, + [0x16F2D]={ + category="lo", + direction="l", + }, + [0x16F2E]={ + category="lo", + direction="l", + }, + [0x16F2F]={ + category="lo", + direction="l", + }, + [0x16F30]={ + category="lo", + direction="l", + }, + [0x16F31]={ + category="lo", + direction="l", + }, + [0x16F32]={ + category="lo", + direction="l", + }, + [0x16F33]={ + category="lo", + direction="l", + }, + [0x16F34]={ + category="lo", + direction="l", + }, + [0x16F35]={ + category="lo", + direction="l", + }, + [0x16F36]={ + category="lo", + direction="l", + }, + [0x16F37]={ + category="lo", + direction="l", + }, + [0x16F38]={ + category="lo", + direction="l", + }, + [0x16F39]={ + category="lo", + direction="l", + }, + [0x16F3A]={ + category="lo", + direction="l", + }, + [0x16F3B]={ + category="lo", + direction="l", + }, + [0x16F3C]={ + category="lo", + direction="l", + }, + [0x16F3D]={ + category="lo", + direction="l", + }, + [0x16F3E]={ + category="lo", + direction="l", + }, + [0x16F3F]={ + category="lo", + direction="l", + }, + [0x16F40]={ + category="lo", + direction="l", + }, + [0x16F41]={ + category="lo", + direction="l", + }, + [0x16F42]={ + category="lo", + direction="l", + }, + [0x16F43]={ + category="lo", + direction="l", + }, + [0x16F44]={ + category="lo", + direction="l", + }, + [0x16F50]={ + category="lo", + direction="l", + }, + [0x16F51]={ + category="mc", + direction="l", + }, + [0x16F52]={ + category="mc", + direction="l", + }, + [0x16F53]={ + category="mc", + direction="l", + }, + [0x16F54]={ + category="mc", + direction="l", + }, + [0x16F55]={ + category="mc", + direction="l", + }, + [0x16F56]={ + category="mc", + direction="l", + }, + [0x16F57]={ + category="mc", + direction="l", + }, + [0x16F58]={ + category="mc", + direction="l", + }, + [0x16F59]={ + category="mc", + direction="l", + }, + [0x16F5A]={ + category="mc", + direction="l", + }, + [0x16F5B]={ + category="mc", + direction="l", + }, + [0x16F5C]={ + category="mc", + direction="l", + }, + [0x16F5D]={ + category="mc", + direction="l", + }, + [0x16F5E]={ + category="mc", + direction="l", + }, + [0x16F5F]={ + category="mc", + direction="l", + }, + [0x16F60]={ + category="mc", + direction="l", + }, + [0x16F61]={ + category="mc", + direction="l", + }, + [0x16F62]={ + category="mc", + direction="l", + }, + [0x16F63]={ + category="mc", + direction="l", + }, + [0x16F64]={ + category="mc", + direction="l", + }, + [0x16F65]={ + category="mc", + direction="l", + }, + [0x16F66]={ + category="mc", + direction="l", + }, + [0x16F67]={ + category="mc", + direction="l", + }, + [0x16F68]={ + category="mc", + direction="l", + }, + [0x16F69]={ + category="mc", + direction="l", + }, + [0x16F6A]={ + category="mc", + direction="l", + }, + [0x16F6B]={ + category="mc", + direction="l", + }, + [0x16F6C]={ + category="mc", + direction="l", + }, + [0x16F6D]={ + category="mc", + direction="l", + }, + [0x16F6E]={ + category="mc", + direction="l", + }, + [0x16F6F]={ + category="mc", + direction="l", + }, + [0x16F70]={ + category="mc", + direction="l", + }, + [0x16F71]={ + category="mc", + direction="l", + }, + [0x16F72]={ + category="mc", + direction="l", + }, + [0x16F73]={ + category="mc", + direction="l", + }, + [0x16F74]={ + category="mc", + direction="l", + }, + [0x16F75]={ + category="mc", + direction="l", + }, + [0x16F76]={ + category="mc", + direction="l", + }, + [0x16F77]={ + category="mc", + direction="l", + }, + [0x16F78]={ + category="mc", + direction="l", + }, + [0x16F79]={ + category="mc", + direction="l", + }, + [0x16F7A]={ + category="mc", + direction="l", + }, + [0x16F7B]={ + category="mc", + direction="l", + }, + [0x16F7C]={ + category="mc", + direction="l", + }, + [0x16F7D]={ + category="mc", + direction="l", + }, + [0x16F7E]={ + category="mc", + direction="l", + }, + [0x16F8F]={ + category="mn", + direction="nsm", + }, + [0x16F90]={ + category="mn", + direction="nsm", + }, + [0x16F91]={ + category="mn", + direction="nsm", + }, + [0x16F92]={ + category="mn", + direction="nsm", + }, + [0x16F93]={ + category="lm", + direction="l", + }, + [0x16F94]={ + category="lm", + direction="l", + }, + [0x16F95]={ + category="lm", + direction="l", + }, + [0x16F96]={ + category="lm", + direction="l", + }, + [0x16F97]={ + category="lm", + direction="l", + }, + [0x16F98]={ + category="lm", + direction="l", + }, + [0x16F99]={ + category="lm", + direction="l", + }, + [0x16F9A]={ + category="lm", + direction="l", + }, + [0x16F9B]={ + category="lm", + direction="l", + }, + [0x16F9C]={ + category="lm", + direction="l", + }, + [0x16F9D]={ + category="lm", + direction="l", + }, + [0x16F9E]={ + category="lm", + direction="l", + }, + [0x16F9F]={ + category="lm", + direction="l", + }, + [0x1B000]={ + category="lo", + direction="l", + }, + [0x1B001]={ + category="lo", + direction="l", + }, + [0x1BC00]={ + category="lo", + direction="l", + }, + [0x1BC01]={ + category="lo", + direction="l", + }, + [0x1BC02]={ + category="lo", + direction="l", + }, + [0x1BC03]={ + category="lo", + direction="l", + }, + [0x1BC04]={ + category="lo", + direction="l", + }, + [0x1BC05]={ + category="lo", + direction="l", + }, + [0x1BC06]={ + category="lo", + direction="l", + }, + [0x1BC07]={ + category="lo", + direction="l", + }, + [0x1BC08]={ + category="lo", + direction="l", + }, + [0x1BC09]={ + category="lo", + direction="l", + }, + [0x1BC0A]={ + category="lo", + direction="l", + }, + [0x1BC0B]={ + category="lo", + direction="l", + }, + [0x1BC0C]={ + category="lo", + direction="l", + }, + [0x1BC0D]={ + category="lo", + direction="l", + }, + [0x1BC0E]={ + category="lo", + direction="l", + }, + [0x1BC0F]={ + category="lo", + direction="l", + }, + [0x1BC10]={ + category="lo", + direction="l", + }, + [0x1BC11]={ + category="lo", + direction="l", + }, + [0x1BC12]={ + category="lo", + direction="l", + }, + [0x1BC13]={ + category="lo", + direction="l", + }, + [0x1BC14]={ + category="lo", + direction="l", + }, + [0x1BC15]={ + category="lo", + direction="l", + }, + [0x1BC16]={ + category="lo", + direction="l", + }, + [0x1BC17]={ + category="lo", + direction="l", + }, + [0x1BC18]={ + category="lo", + direction="l", + }, + [0x1BC19]={ + category="lo", + direction="l", + }, + [0x1BC1A]={ + category="lo", + direction="l", + }, + [0x1BC1B]={ + category="lo", + direction="l", + }, + [0x1BC1C]={ + category="lo", + direction="l", + }, + [0x1BC1D]={ + category="lo", + direction="l", + }, + [0x1BC1E]={ + category="lo", + direction="l", + }, + [0x1BC1F]={ + category="lo", + direction="l", + }, + [0x1BC20]={ + category="lo", + direction="l", + }, + [0x1BC21]={ + category="lo", + direction="l", + }, + [0x1BC22]={ + category="lo", + direction="l", + }, + [0x1BC23]={ + category="lo", + direction="l", + }, + [0x1BC24]={ + category="lo", + direction="l", + }, + [0x1BC25]={ + category="lo", + direction="l", + }, + [0x1BC26]={ + category="lo", + direction="l", + }, + [0x1BC27]={ + category="lo", + direction="l", + }, + [0x1BC28]={ + category="lo", + direction="l", + }, + [0x1BC29]={ + category="lo", + direction="l", + }, + [0x1BC2A]={ + category="lo", + direction="l", + }, + [0x1BC2B]={ + category="lo", + direction="l", + }, + [0x1BC2C]={ + category="lo", + direction="l", + }, + [0x1BC2D]={ + category="lo", + direction="l", + }, + [0x1BC2E]={ + category="lo", + direction="l", + }, + [0x1BC2F]={ + category="lo", + direction="l", + }, + [0x1BC30]={ + category="lo", + direction="l", + }, + [0x1BC31]={ + category="lo", + direction="l", + }, + [0x1BC32]={ + category="lo", + direction="l", + }, + [0x1BC33]={ + category="lo", + direction="l", + }, + [0x1BC34]={ + category="lo", + direction="l", + }, + [0x1BC35]={ + category="lo", + direction="l", + }, + [0x1BC36]={ + category="lo", + direction="l", + }, + [0x1BC37]={ + category="lo", + direction="l", + }, + [0x1BC38]={ + category="lo", + direction="l", + }, + [0x1BC39]={ + category="lo", + direction="l", + }, + [0x1BC3A]={ + category="lo", + direction="l", + }, + [0x1BC3B]={ + category="lo", + direction="l", + }, + [0x1BC3C]={ + category="lo", + direction="l", + }, + [0x1BC3D]={ + category="lo", + direction="l", + }, + [0x1BC3E]={ + category="lo", + direction="l", + }, + [0x1BC3F]={ + category="lo", + direction="l", + }, + [0x1BC40]={ + category="lo", + direction="l", + }, + [0x1BC41]={ + category="lo", + direction="l", + }, + [0x1BC42]={ + category="lo", + direction="l", + }, + [0x1BC43]={ + category="lo", + direction="l", + }, + [0x1BC44]={ + category="lo", + direction="l", + }, + [0x1BC45]={ + category="lo", + direction="l", + }, + [0x1BC46]={ + category="lo", + direction="l", + }, + [0x1BC47]={ + category="lo", + direction="l", + }, + [0x1BC48]={ + category="lo", + direction="l", + }, + [0x1BC49]={ + category="lo", + direction="l", + }, + [0x1BC4A]={ + category="lo", + direction="l", + }, + [0x1BC4B]={ + category="lo", + direction="l", + }, + [0x1BC4C]={ + category="lo", + direction="l", + }, + [0x1BC4D]={ + category="lo", + direction="l", + }, + [0x1BC4E]={ + category="lo", + direction="l", + }, + [0x1BC4F]={ + category="lo", + direction="l", + }, + [0x1BC50]={ + category="lo", + direction="l", + }, + [0x1BC51]={ + category="lo", + direction="l", + }, + [0x1BC52]={ + category="lo", + direction="l", + }, + [0x1BC53]={ + category="lo", + direction="l", + }, + [0x1BC54]={ + category="lo", + direction="l", + }, + [0x1BC55]={ + category="lo", + direction="l", + }, + [0x1BC56]={ + category="lo", + direction="l", + }, + [0x1BC57]={ + category="lo", + direction="l", + }, + [0x1BC58]={ + category="lo", + direction="l", + }, + [0x1BC59]={ + category="lo", + direction="l", + }, + [0x1BC5A]={ + category="lo", + direction="l", + }, + [0x1BC5B]={ + category="lo", + direction="l", + }, + [0x1BC5C]={ + category="lo", + direction="l", + }, + [0x1BC5D]={ + category="lo", + direction="l", + }, + [0x1BC5E]={ + category="lo", + direction="l", + }, + [0x1BC5F]={ + category="lo", + direction="l", + }, + [0x1BC60]={ + category="lo", + direction="l", + }, + [0x1BC61]={ + category="lo", + direction="l", + }, + [0x1BC62]={ + category="lo", + direction="l", + }, + [0x1BC63]={ + category="lo", + direction="l", + }, + [0x1BC64]={ + category="lo", + direction="l", + }, + [0x1BC65]={ + category="lo", + direction="l", + }, + [0x1BC66]={ + category="lo", + direction="l", + }, + [0x1BC67]={ + category="lo", + direction="l", + }, + [0x1BC68]={ + category="lo", + direction="l", + }, + [0x1BC69]={ + category="lo", + direction="l", + }, + [0x1BC6A]={ + category="lo", + direction="l", + }, + [0x1BC70]={ + category="lo", + direction="l", + }, + [0x1BC71]={ + category="lo", + direction="l", + }, + [0x1BC72]={ + category="lo", + direction="l", + }, + [0x1BC73]={ + category="lo", + direction="l", + }, + [0x1BC74]={ + category="lo", + direction="l", + }, + [0x1BC75]={ + category="lo", + direction="l", + }, + [0x1BC76]={ + category="lo", + direction="l", + }, + [0x1BC77]={ + category="lo", + direction="l", + }, + [0x1BC78]={ + category="lo", + direction="l", + }, + [0x1BC79]={ + category="lo", + direction="l", + }, + [0x1BC7A]={ + category="lo", + direction="l", + }, + [0x1BC7B]={ + category="lo", + direction="l", + }, + [0x1BC7C]={ + category="lo", + direction="l", + }, + [0x1BC80]={ + category="lo", + direction="l", + }, + [0x1BC81]={ + category="lo", + direction="l", + }, + [0x1BC82]={ + category="lo", + direction="l", + }, + [0x1BC83]={ + category="lo", + direction="l", + }, + [0x1BC84]={ + category="lo", + direction="l", + }, + [0x1BC85]={ + category="lo", + direction="l", + }, + [0x1BC86]={ + category="lo", + direction="l", + }, + [0x1BC87]={ + category="lo", + direction="l", + }, + [0x1BC88]={ + category="lo", + direction="l", + }, + [0x1BC90]={ + category="lo", + direction="l", + }, + [0x1BC91]={ + category="lo", + direction="l", + }, + [0x1BC92]={ + category="lo", + direction="l", + }, + [0x1BC93]={ + category="lo", + direction="l", + }, + [0x1BC94]={ + category="lo", + direction="l", + }, + [0x1BC95]={ + category="lo", + direction="l", + }, + [0x1BC96]={ + category="lo", + direction="l", + }, + [0x1BC97]={ + category="lo", + direction="l", + }, + [0x1BC98]={ + category="lo", + direction="l", + }, + [0x1BC99]={ + category="lo", + direction="l", + }, + [0x1BC9C]={ + category="so", + direction="l", + }, + [0x1BC9D]={ + category="mn", + direction="nsm", + }, + [0x1BC9E]={ + category="mn", + direction="nsm", + }, + [0x1BC9F]={ + category="po", + direction="l", + }, + [0x1BCA0]={ + category="cf", + direction="bn", + }, + [0x1BCA1]={ + category="cf", + direction="bn", + }, + [0x1BCA2]={ + category="cf", + direction="bn", + }, + [0x1BCA3]={ + category="cf", + direction="bn", + }, + [0x1D000]={ + category="so", + direction="l", + }, + [0x1D001]={ + category="so", + direction="l", + }, + [0x1D002]={ + category="so", + direction="l", + }, + [0x1D003]={ + category="so", + direction="l", + }, + [0x1D004]={ + category="so", + direction="l", + }, + [0x1D005]={ + category="so", + direction="l", + }, + [0x1D006]={ + category="so", + direction="l", + }, + [0x1D007]={ + category="so", + direction="l", + }, + [0x1D008]={ + category="so", + direction="l", + }, + [0x1D009]={ + category="so", + direction="l", + }, + [0x1D00A]={ + category="so", + direction="l", + }, + [0x1D00B]={ + category="so", + direction="l", + }, + [0x1D00C]={ + category="so", + direction="l", + }, + [0x1D00D]={ + category="so", + direction="l", + }, + [0x1D00E]={ + category="so", + direction="l", + }, + [0x1D00F]={ + category="so", + direction="l", + }, + [0x1D010]={ + category="so", + direction="l", + }, + [0x1D011]={ + category="so", + direction="l", + }, + [0x1D012]={ + category="so", + direction="l", + }, + [0x1D013]={ + category="so", + direction="l", + }, + [0x1D014]={ + category="so", + direction="l", + }, + [0x1D015]={ + category="so", + direction="l", + }, + [0x1D016]={ + category="so", + direction="l", + }, + [0x1D017]={ + category="so", + direction="l", + }, + [0x1D018]={ + category="so", + direction="l", + }, + [0x1D019]={ + category="so", + direction="l", + }, + [0x1D01A]={ + category="so", + direction="l", + }, + [0x1D01B]={ + category="so", + direction="l", + }, + [0x1D01C]={ + category="so", + direction="l", + }, + [0x1D01D]={ + category="so", + direction="l", + }, + [0x1D01E]={ + category="so", + direction="l", + }, + [0x1D01F]={ + category="so", + direction="l", + }, + [0x1D020]={ + category="so", + direction="l", + }, + [0x1D021]={ + category="so", + direction="l", + }, + [0x1D022]={ + category="so", + direction="l", + }, + [0x1D023]={ + category="so", + direction="l", + }, + [0x1D024]={ + category="so", + direction="l", + }, + [0x1D025]={ + category="so", + direction="l", + }, + [0x1D026]={ + category="so", + direction="l", + }, + [0x1D027]={ + category="so", + direction="l", + }, + [0x1D028]={ + category="so", + direction="l", + }, + [0x1D029]={ + category="so", + direction="l", + }, + [0x1D02A]={ + category="so", + direction="l", + }, + [0x1D02B]={ + category="so", + direction="l", + }, + [0x1D02C]={ + category="so", + direction="l", + }, + [0x1D02D]={ + category="so", + direction="l", + }, + [0x1D02E]={ + category="so", + direction="l", + }, + [0x1D02F]={ + category="so", + direction="l", + }, + [0x1D030]={ + category="so", + direction="l", + }, + [0x1D031]={ + category="so", + direction="l", + }, + [0x1D032]={ + category="so", + direction="l", + }, + [0x1D033]={ + category="so", + direction="l", + }, + [0x1D034]={ + category="so", + direction="l", + }, + [0x1D035]={ + category="so", + direction="l", + }, + [0x1D036]={ + category="so", + direction="l", + }, + [0x1D037]={ + category="so", + direction="l", + }, + [0x1D038]={ + category="so", + direction="l", + }, + [0x1D039]={ + category="so", + direction="l", + }, + [0x1D03A]={ + category="so", + direction="l", + }, + [0x1D03B]={ + category="so", + direction="l", + }, + [0x1D03C]={ + category="so", + direction="l", + }, + [0x1D03D]={ + category="so", + direction="l", + }, + [0x1D03E]={ + category="so", + direction="l", + }, + [0x1D03F]={ + category="so", + direction="l", + }, + [0x1D040]={ + category="so", + direction="l", + }, + [0x1D041]={ + category="so", + direction="l", + }, + [0x1D042]={ + category="so", + direction="l", + }, + [0x1D043]={ + category="so", + direction="l", + }, + [0x1D044]={ + category="so", + direction="l", + }, + [0x1D045]={ + category="so", + direction="l", + }, + [0x1D046]={ + category="so", + direction="l", + }, + [0x1D047]={ + category="so", + direction="l", + }, + [0x1D048]={ + category="so", + direction="l", + }, + [0x1D049]={ + category="so", + direction="l", + }, + [0x1D04A]={ + category="so", + direction="l", + }, + [0x1D04B]={ + category="so", + direction="l", + }, + [0x1D04C]={ + category="so", + direction="l", + }, + [0x1D04D]={ + category="so", + direction="l", + }, + [0x1D04E]={ + category="so", + direction="l", + }, + [0x1D04F]={ + category="so", + direction="l", + }, + [0x1D050]={ + category="so", + direction="l", + }, + [0x1D051]={ + category="so", + direction="l", + }, + [0x1D052]={ + category="so", + direction="l", + }, + [0x1D053]={ + category="so", + direction="l", + }, + [0x1D054]={ + category="so", + direction="l", + }, + [0x1D055]={ + category="so", + direction="l", + }, + [0x1D056]={ + category="so", + direction="l", + }, + [0x1D057]={ + category="so", + direction="l", + }, + [0x1D058]={ + category="so", + direction="l", + }, + [0x1D059]={ + category="so", + direction="l", + }, + [0x1D05A]={ + category="so", + direction="l", + }, + [0x1D05B]={ + category="so", + direction="l", + }, + [0x1D05C]={ + category="so", + direction="l", + }, + [0x1D05D]={ + category="so", + direction="l", + }, + [0x1D05E]={ + category="so", + direction="l", + }, + [0x1D05F]={ + category="so", + direction="l", + }, + [0x1D060]={ + category="so", + direction="l", + }, + [0x1D061]={ + category="so", + direction="l", + }, + [0x1D062]={ + category="so", + direction="l", + }, + [0x1D063]={ + category="so", + direction="l", + }, + [0x1D064]={ + category="so", + direction="l", + }, + [0x1D065]={ + category="so", + direction="l", + }, + [0x1D066]={ + category="so", + direction="l", + }, + [0x1D067]={ + category="so", + direction="l", + }, + [0x1D068]={ + category="so", + direction="l", + }, + [0x1D069]={ + category="so", + direction="l", + }, + [0x1D06A]={ + category="so", + direction="l", + }, + [0x1D06B]={ + category="so", + direction="l", + }, + [0x1D06C]={ + category="so", + direction="l", + }, + [0x1D06D]={ + category="so", + direction="l", + }, + [0x1D06E]={ + category="so", + direction="l", + }, + [0x1D06F]={ + category="so", + direction="l", + }, + [0x1D070]={ + category="so", + direction="l", + }, + [0x1D071]={ + category="so", + direction="l", + }, + [0x1D072]={ + category="so", + direction="l", + }, + [0x1D073]={ + category="so", + direction="l", + }, + [0x1D074]={ + category="so", + direction="l", + }, + [0x1D075]={ + category="so", + direction="l", + }, + [0x1D076]={ + category="so", + direction="l", + }, + [0x1D077]={ + category="so", + direction="l", + }, + [0x1D078]={ + category="so", + direction="l", + }, + [0x1D079]={ + category="so", + direction="l", + }, + [0x1D07A]={ + category="so", + direction="l", + }, + [0x1D07B]={ + category="so", + direction="l", + }, + [0x1D07C]={ + category="so", + direction="l", + }, + [0x1D07D]={ + category="so", + direction="l", + }, + [0x1D07E]={ + category="so", + direction="l", + }, + [0x1D07F]={ + category="so", + direction="l", + }, + [0x1D080]={ + category="so", + direction="l", + }, + [0x1D081]={ + category="so", + direction="l", + }, + [0x1D082]={ + category="so", + direction="l", + }, + [0x1D083]={ + category="so", + direction="l", + }, + [0x1D084]={ + category="so", + direction="l", + }, + [0x1D085]={ + category="so", + direction="l", + }, + [0x1D086]={ + category="so", + direction="l", + }, + [0x1D087]={ + category="so", + direction="l", + }, + [0x1D088]={ + category="so", + direction="l", + }, + [0x1D089]={ + category="so", + direction="l", + }, + [0x1D08A]={ + category="so", + direction="l", + }, + [0x1D08B]={ + category="so", + direction="l", + }, + [0x1D08C]={ + category="so", + direction="l", + }, + [0x1D08D]={ + category="so", + direction="l", + }, + [0x1D08E]={ + category="so", + direction="l", + }, + [0x1D08F]={ + category="so", + direction="l", + }, + [0x1D090]={ + category="so", + direction="l", + }, + [0x1D091]={ + category="so", + direction="l", + }, + [0x1D092]={ + category="so", + direction="l", + }, + [0x1D093]={ + category="so", + direction="l", + }, + [0x1D094]={ + category="so", + direction="l", + }, + [0x1D095]={ + category="so", + direction="l", + }, + [0x1D096]={ + category="so", + direction="l", + }, + [0x1D097]={ + category="so", + direction="l", + }, + [0x1D098]={ + category="so", + direction="l", + }, + [0x1D099]={ + category="so", + direction="l", + }, + [0x1D09A]={ + category="so", + direction="l", + }, + [0x1D09B]={ + category="so", + direction="l", + }, + [0x1D09C]={ + category="so", + direction="l", + }, + [0x1D09D]={ + category="so", + direction="l", + }, + [0x1D09E]={ + category="so", + direction="l", + }, + [0x1D09F]={ + category="so", + direction="l", + }, + [0x1D0A0]={ + category="so", + direction="l", + }, + [0x1D0A1]={ + category="so", + direction="l", + }, + [0x1D0A2]={ + category="so", + direction="l", + }, + [0x1D0A3]={ + category="so", + direction="l", + }, + [0x1D0A4]={ + category="so", + direction="l", + }, + [0x1D0A5]={ + category="so", + direction="l", + }, + [0x1D0A6]={ + category="so", + direction="l", + }, + [0x1D0A7]={ + category="so", + direction="l", + }, + [0x1D0A8]={ + category="so", + direction="l", + }, + [0x1D0A9]={ + category="so", + direction="l", + }, + [0x1D0AA]={ + category="so", + direction="l", + }, + [0x1D0AB]={ + category="so", + direction="l", + }, + [0x1D0AC]={ + category="so", + direction="l", + }, + [0x1D0AD]={ + category="so", + direction="l", + }, + [0x1D0AE]={ + category="so", + direction="l", + }, + [0x1D0AF]={ + category="so", + direction="l", + }, + [0x1D0B0]={ + category="so", + direction="l", + }, + [0x1D0B1]={ + category="so", + direction="l", + }, + [0x1D0B2]={ + category="so", + direction="l", + }, + [0x1D0B3]={ + category="so", + direction="l", + }, + [0x1D0B4]={ + category="so", + direction="l", + }, + [0x1D0B5]={ + category="so", + direction="l", + }, + [0x1D0B6]={ + category="so", + direction="l", + }, + [0x1D0B7]={ + category="so", + direction="l", + }, + [0x1D0B8]={ + category="so", + direction="l", + }, + [0x1D0B9]={ + category="so", + direction="l", + }, + [0x1D0BA]={ + category="so", + direction="l", + }, + [0x1D0BB]={ + category="so", + direction="l", + }, + [0x1D0BC]={ + category="so", + direction="l", + }, + [0x1D0BD]={ + category="so", + direction="l", + }, + [0x1D0BE]={ + category="so", + direction="l", + }, + [0x1D0BF]={ + category="so", + direction="l", + }, + [0x1D0C0]={ + category="so", + direction="l", + }, + [0x1D0C1]={ + category="so", + direction="l", + }, + [0x1D0C2]={ + category="so", + direction="l", + }, + [0x1D0C3]={ + category="so", + direction="l", + }, + [0x1D0C4]={ + category="so", + direction="l", + }, + [0x1D0C5]={ + category="so", + direction="l", + }, + [0x1D0C6]={ + category="so", + direction="l", + }, + [0x1D0C7]={ + category="so", + direction="l", + }, + [0x1D0C8]={ + category="so", + direction="l", + }, + [0x1D0C9]={ + category="so", + direction="l", + }, + [0x1D0CA]={ + category="so", + direction="l", + }, + [0x1D0CB]={ + category="so", + direction="l", + }, + [0x1D0CC]={ + category="so", + direction="l", + }, + [0x1D0CD]={ + category="so", + direction="l", + }, + [0x1D0CE]={ + category="so", + direction="l", + }, + [0x1D0CF]={ + category="so", + direction="l", + }, + [0x1D0D0]={ + category="so", + direction="l", + }, + [0x1D0D1]={ + category="so", + direction="l", + }, + [0x1D0D2]={ + category="so", + direction="l", + }, + [0x1D0D3]={ + category="so", + direction="l", + }, + [0x1D0D4]={ + category="so", + direction="l", + }, + [0x1D0D5]={ + category="so", + direction="l", + }, + [0x1D0D6]={ + category="so", + direction="l", + }, + [0x1D0D7]={ + category="so", + direction="l", + }, + [0x1D0D8]={ + category="so", + direction="l", + }, + [0x1D0D9]={ + category="so", + direction="l", + }, + [0x1D0DA]={ + category="so", + direction="l", + }, + [0x1D0DB]={ + category="so", + direction="l", + }, + [0x1D0DC]={ + category="so", + direction="l", + }, + [0x1D0DD]={ + category="so", + direction="l", + }, + [0x1D0DE]={ + category="so", + direction="l", + }, + [0x1D0DF]={ + category="so", + direction="l", + }, + [0x1D0E0]={ + category="so", + direction="l", + }, + [0x1D0E1]={ + category="so", + direction="l", + }, + [0x1D0E2]={ + category="so", + direction="l", + }, + [0x1D0E3]={ + category="so", + direction="l", + }, + [0x1D0E4]={ + category="so", + direction="l", + }, + [0x1D0E5]={ + category="so", + direction="l", + }, + [0x1D0E6]={ + category="so", + direction="l", + }, + [0x1D0E7]={ + category="so", + direction="l", + }, + [0x1D0E8]={ + category="so", + direction="l", + }, + [0x1D0E9]={ + category="so", + direction="l", + }, + [0x1D0EA]={ + category="so", + direction="l", + }, + [0x1D0EB]={ + category="so", + direction="l", + }, + [0x1D0EC]={ + category="so", + direction="l", + }, + [0x1D0ED]={ + category="so", + direction="l", + }, + [0x1D0EE]={ + category="so", + direction="l", + }, + [0x1D0EF]={ + category="so", + direction="l", + }, + [0x1D0F0]={ + category="so", + direction="l", + }, + [0x1D0F1]={ + category="so", + direction="l", + }, + [0x1D0F2]={ + category="so", + direction="l", + }, + [0x1D0F3]={ + category="so", + direction="l", + }, + [0x1D0F4]={ + category="so", + direction="l", + }, + [0x1D0F5]={ + category="so", + direction="l", + }, + [0x1D100]={ + category="so", + direction="l", + }, + [0x1D101]={ + category="so", + direction="l", + }, + [0x1D102]={ + category="so", + direction="l", + }, + [0x1D103]={ + category="so", + direction="l", + }, + [0x1D104]={ + category="so", + direction="l", + }, + [0x1D105]={ + category="so", + direction="l", + }, + [0x1D106]={ + category="so", + direction="l", + }, + [0x1D107]={ + category="so", + direction="l", + }, + [0x1D108]={ + category="so", + direction="l", + }, + [0x1D109]={ + category="so", + direction="l", + }, + [0x1D10A]={ + category="so", + direction="l", + }, + [0x1D10B]={ + category="so", + direction="l", + }, + [0x1D10C]={ + category="so", + direction="l", + }, + [0x1D10D]={ + category="so", + direction="l", + }, + [0x1D10E]={ + category="so", + direction="l", + }, + [0x1D10F]={ + category="so", + direction="l", + }, + [0x1D110]={ + category="so", + direction="l", + }, + [0x1D111]={ + category="so", + direction="l", + }, + [0x1D112]={ + category="so", + direction="l", + }, + [0x1D113]={ + category="so", + direction="l", + }, + [0x1D114]={ + category="so", + direction="l", + }, + [0x1D115]={ + category="so", + direction="l", + }, + [0x1D116]={ + category="so", + direction="l", + }, + [0x1D117]={ + category="so", + direction="l", + }, + [0x1D118]={ + category="so", + direction="l", + }, + [0x1D119]={ + category="so", + direction="l", + }, + [0x1D11A]={ + category="so", + direction="l", + }, + [0x1D11B]={ + category="so", + direction="l", + }, + [0x1D11C]={ + category="so", + direction="l", + }, + [0x1D11D]={ + category="so", + direction="l", + }, + [0x1D11E]={ + category="so", + direction="l", + }, + [0x1D11F]={ + category="so", + direction="l", + }, + [0x1D120]={ + category="so", + direction="l", + }, + [0x1D121]={ + category="so", + direction="l", + }, + [0x1D122]={ + category="so", + direction="l", + }, + [0x1D123]={ + category="so", + direction="l", + }, + [0x1D124]={ + category="so", + direction="l", + }, + [0x1D125]={ + category="so", + direction="l", + }, + [0x1D126]={ + category="so", + direction="l", + }, + [0x1D129]={ + category="so", + direction="l", + }, + [0x1D12A]={ + category="so", + direction="l", + }, + [0x1D12B]={ + category="so", + direction="l", + }, + [0x1D12C]={ + category="so", + direction="l", + }, + [0x1D12D]={ + category="so", + direction="l", + }, + [0x1D12E]={ + category="so", + direction="l", + }, + [0x1D12F]={ + category="so", + direction="l", + }, + [0x1D130]={ + category="so", + direction="l", + }, + [0x1D131]={ + category="so", + direction="l", + }, + [0x1D132]={ + category="so", + direction="l", + }, + [0x1D133]={ + category="so", + direction="l", + }, + [0x1D134]={ + category="so", + direction="l", + }, + [0x1D135]={ + category="so", + direction="l", + }, + [0x1D136]={ + category="so", + direction="l", + }, + [0x1D137]={ + category="so", + direction="l", + }, + [0x1D138]={ + category="so", + direction="l", + }, + [0x1D139]={ + category="so", + direction="l", + }, + [0x1D13A]={ + category="so", + direction="l", + }, + [0x1D13B]={ + category="so", + direction="l", + }, + [0x1D13C]={ + category="so", + direction="l", + }, + [0x1D13D]={ + category="so", + direction="l", + }, + [0x1D13E]={ + category="so", + direction="l", + }, + [0x1D13F]={ + category="so", + direction="l", + }, + [0x1D140]={ + category="so", + direction="l", + }, + [0x1D141]={ + category="so", + direction="l", + }, + [0x1D142]={ + category="so", + direction="l", + }, + [0x1D143]={ + category="so", + direction="l", + }, + [0x1D144]={ + category="so", + direction="l", + }, + [0x1D145]={ + category="so", + direction="l", + }, + [0x1D146]={ + category="so", + direction="l", + }, + [0x1D147]={ + category="so", + direction="l", + }, + [0x1D148]={ + category="so", + direction="l", + }, + [0x1D149]={ + category="so", + direction="l", + }, + [0x1D14A]={ + category="so", + direction="l", + }, + [0x1D14B]={ + category="so", + direction="l", + }, + [0x1D14C]={ + category="so", + direction="l", + }, + [0x1D14D]={ + category="so", + direction="l", + }, + [0x1D14E]={ + category="so", + direction="l", + }, + [0x1D14F]={ + category="so", + direction="l", + }, + [0x1D150]={ + category="so", + direction="l", + }, + [0x1D151]={ + category="so", + direction="l", + }, + [0x1D152]={ + category="so", + direction="l", + }, + [0x1D153]={ + category="so", + direction="l", + }, + [0x1D154]={ + category="so", + direction="l", + }, + [0x1D155]={ + category="so", + direction="l", + }, + [0x1D156]={ + category="so", + direction="l", + }, + [0x1D157]={ + category="so", + direction="l", + }, + [0x1D158]={ + category="so", + direction="l", + }, + [0x1D159]={ + category="so", + direction="l", + }, + [0x1D15A]={ + category="so", + direction="l", + }, + [0x1D15B]={ + category="so", + direction="l", + }, + [0x1D15C]={ + category="so", + direction="l", + }, + [0x1D15D]={ + category="so", + direction="l", + }, + [0x1D15E]={ + category="so", + direction="l", + }, + [0x1D15F]={ + category="so", + direction="l", + }, + [0x1D160]={ + category="so", + direction="l", + }, + [0x1D161]={ + category="so", + direction="l", + }, + [0x1D162]={ + category="so", + direction="l", + }, + [0x1D163]={ + category="so", + direction="l", + }, + [0x1D164]={ + category="so", + direction="l", + }, + [0x1D165]={ + category="mc", + direction="l", + }, + [0x1D166]={ + category="mc", + direction="l", + }, + [0x1D167]={ + category="mn", + direction="nsm", + }, + [0x1D168]={ + category="mn", + direction="nsm", + }, + [0x1D169]={ + category="mn", + direction="nsm", + }, + [0x1D16A]={ + category="so", + direction="l", + }, + [0x1D16B]={ + category="so", + direction="l", + }, + [0x1D16C]={ + category="so", + direction="l", + }, + [0x1D16D]={ + category="mc", + direction="l", + }, + [0x1D16E]={ + category="mc", + direction="l", + }, + [0x1D16F]={ + category="mc", + direction="l", + }, + [0x1D170]={ + category="mc", + direction="l", + }, + [0x1D171]={ + category="mc", + direction="l", + }, + [0x1D172]={ + category="mc", + direction="l", + }, + [0x1D173]={ + category="cf", + direction="bn", + }, + [0x1D174]={ + category="cf", + direction="bn", + }, + [0x1D175]={ + category="cf", + direction="bn", + }, + [0x1D176]={ + category="cf", + direction="bn", + }, + [0x1D177]={ + category="cf", + direction="bn", + }, + [0x1D178]={ + category="cf", + direction="bn", + }, + [0x1D179]={ + category="cf", + direction="bn", + }, + [0x1D17A]={ + category="cf", + direction="bn", + }, + [0x1D17B]={ + category="mn", + direction="nsm", + }, + [0x1D17C]={ + category="mn", + direction="nsm", + }, + [0x1D17D]={ + category="mn", + direction="nsm", + }, + [0x1D17E]={ + category="mn", + direction="nsm", + }, + [0x1D17F]={ + category="mn", + direction="nsm", + }, + [0x1D180]={ + category="mn", + direction="nsm", + }, + [0x1D181]={ + category="mn", + direction="nsm", + }, + [0x1D182]={ + category="mn", + direction="nsm", + }, + [0x1D183]={ + category="so", + direction="l", + }, + [0x1D184]={ + category="so", + direction="l", + }, + [0x1D185]={ + category="mn", + direction="nsm", + }, + [0x1D186]={ + category="mn", + direction="nsm", + }, + [0x1D187]={ + category="mn", + direction="nsm", + }, + [0x1D188]={ + category="mn", + direction="nsm", + }, + [0x1D189]={ + category="mn", + direction="nsm", + }, + [0x1D18A]={ + category="mn", + direction="nsm", + }, + [0x1D18B]={ + category="mn", + direction="nsm", + }, + [0x1D18C]={ + category="so", + direction="l", + }, + [0x1D18D]={ + category="so", + direction="l", + }, + [0x1D18E]={ + category="so", + direction="l", + }, + [0x1D18F]={ + category="so", + direction="l", + }, + [0x1D190]={ + category="so", + direction="l", + }, + [0x1D191]={ + category="so", + direction="l", + }, + [0x1D192]={ + category="so", + direction="l", + }, + [0x1D193]={ + category="so", + direction="l", + }, + [0x1D194]={ + category="so", + direction="l", + }, + [0x1D195]={ + category="so", + direction="l", + }, + [0x1D196]={ + category="so", + direction="l", + }, + [0x1D197]={ + category="so", + direction="l", + }, + [0x1D198]={ + category="so", + direction="l", + }, + [0x1D199]={ + category="so", + direction="l", + }, + [0x1D19A]={ + category="so", + direction="l", + }, + [0x1D19B]={ + category="so", + direction="l", + }, + [0x1D19C]={ + category="so", + direction="l", + }, + [0x1D19D]={ + category="so", + direction="l", + }, + [0x1D19E]={ + category="so", + direction="l", + }, + [0x1D19F]={ + category="so", + direction="l", + }, + [0x1D1A0]={ + category="so", + direction="l", + }, + [0x1D1A1]={ + category="so", + direction="l", + }, + [0x1D1A2]={ + category="so", + direction="l", + }, + [0x1D1A3]={ + category="so", + direction="l", + }, + [0x1D1A4]={ + category="so", + direction="l", + }, + [0x1D1A5]={ + category="so", + direction="l", + }, + [0x1D1A6]={ + category="so", + direction="l", + }, + [0x1D1A7]={ + category="so", + direction="l", + }, + [0x1D1A8]={ + category="so", + direction="l", + }, + [0x1D1A9]={ + category="so", + direction="l", + }, + [0x1D1AA]={ + category="mn", + direction="nsm", + }, + [0x1D1AB]={ + category="mn", + direction="nsm", + }, + [0x1D1AC]={ + category="mn", + direction="nsm", + }, + [0x1D1AD]={ + category="mn", + direction="nsm", + }, + [0x1D1AE]={ + category="so", + direction="l", + }, + [0x1D1AF]={ + category="so", + direction="l", + }, + [0x1D1B0]={ + category="so", + direction="l", + }, + [0x1D1B1]={ + category="so", + direction="l", + }, + [0x1D1B2]={ + category="so", + direction="l", + }, + [0x1D1B3]={ + category="so", + direction="l", + }, + [0x1D1B4]={ + category="so", + direction="l", + }, + [0x1D1B5]={ + category="so", + direction="l", + }, + [0x1D1B6]={ + category="so", + direction="l", + }, + [0x1D1B7]={ + category="so", + direction="l", + }, + [0x1D1B8]={ + category="so", + direction="l", + }, + [0x1D1B9]={ + category="so", + direction="l", + }, + [0x1D1BA]={ + category="so", + direction="l", + }, + [0x1D1BB]={ + category="so", + direction="l", + }, + [0x1D1BC]={ + category="so", + direction="l", + }, + [0x1D1BD]={ + category="so", + direction="l", + }, + [0x1D1BE]={ + category="so", + direction="l", + }, + [0x1D1BF]={ + category="so", + direction="l", + }, + [0x1D1C0]={ + category="so", + direction="l", + }, + [0x1D1C1]={ + category="so", + direction="l", + }, + [0x1D1C2]={ + category="so", + direction="l", + }, + [0x1D1C3]={ + category="so", + direction="l", + }, + [0x1D1C4]={ + category="so", + direction="l", + }, + [0x1D1C5]={ + category="so", + direction="l", + }, + [0x1D1C6]={ + category="so", + direction="l", + }, + [0x1D1C7]={ + category="so", + direction="l", + }, + [0x1D1C8]={ + category="so", + direction="l", + }, + [0x1D1C9]={ + category="so", + direction="l", + }, + [0x1D1CA]={ + category="so", + direction="l", + }, + [0x1D1CB]={ + category="so", + direction="l", + }, + [0x1D1CC]={ + category="so", + direction="l", + }, + [0x1D1CD]={ + category="so", + direction="l", + }, + [0x1D1CE]={ + category="so", + direction="l", + }, + [0x1D1CF]={ + category="so", + direction="l", + }, + [0x1D1D0]={ + category="so", + direction="l", + }, + [0x1D1D1]={ + category="so", + direction="l", + }, + [0x1D1D2]={ + category="so", + direction="l", + }, + [0x1D1D3]={ + category="so", + direction="l", + }, + [0x1D1D4]={ + category="so", + direction="l", + }, + [0x1D1D5]={ + category="so", + direction="l", + }, + [0x1D1D6]={ + category="so", + direction="l", + }, + [0x1D1D7]={ + category="so", + direction="l", + }, + [0x1D1D8]={ + category="so", + direction="l", + }, + [0x1D1D9]={ + category="so", + direction="l", + }, + [0x1D1DA]={ + category="so", + direction="l", + }, + [0x1D1DB]={ + category="so", + direction="l", + }, + [0x1D1DC]={ + category="so", + direction="l", + }, + [0x1D1DD]={ + category="so", + direction="l", + }, + [0x1D200]={ + category="so", + direction="on", + }, + [0x1D201]={ + category="so", + direction="on", + }, + [0x1D202]={ + category="so", + direction="on", + }, + [0x1D203]={ + category="so", + direction="on", + }, + [0x1D204]={ + category="so", + direction="on", + }, + [0x1D205]={ + category="so", + direction="on", + }, + [0x1D206]={ + category="so", + direction="on", + }, + [0x1D207]={ + category="so", + direction="on", + }, + [0x1D208]={ + category="so", + direction="on", + }, + [0x1D209]={ + category="so", + direction="on", + }, + [0x1D20A]={ + category="so", + direction="on", + }, + [0x1D20B]={ + category="so", + direction="on", + }, + [0x1D20C]={ + category="so", + direction="on", + }, + [0x1D20D]={ + category="so", + direction="on", + }, + [0x1D20E]={ + category="so", + direction="on", + }, + [0x1D20F]={ + category="so", + direction="on", + }, + [0x1D210]={ + category="so", + direction="on", + }, + [0x1D211]={ + category="so", + direction="on", + }, + [0x1D212]={ + category="so", + direction="on", + }, + [0x1D213]={ + category="so", + direction="on", + }, + [0x1D214]={ + category="so", + direction="on", + }, + [0x1D215]={ + category="so", + direction="on", + }, + [0x1D216]={ + category="so", + direction="on", + }, + [0x1D217]={ + category="so", + direction="on", + }, + [0x1D218]={ + category="so", + direction="on", + }, + [0x1D219]={ + category="so", + direction="on", + }, + [0x1D21A]={ + category="so", + direction="on", + }, + [0x1D21B]={ + category="so", + direction="on", + }, + [0x1D21C]={ + category="so", + direction="on", + }, + [0x1D21D]={ + category="so", + direction="on", + }, + [0x1D21E]={ + category="so", + direction="on", + }, + [0x1D21F]={ + category="so", + direction="on", + }, + [0x1D220]={ + category="so", + direction="on", + }, + [0x1D221]={ + category="so", + direction="on", + }, + [0x1D222]={ + category="so", + direction="on", + }, + [0x1D223]={ + category="so", + direction="on", + }, + [0x1D224]={ + category="so", + direction="on", + }, + [0x1D225]={ + category="so", + direction="on", + }, + [0x1D226]={ + category="so", + direction="on", + }, + [0x1D227]={ + category="so", + direction="on", + }, + [0x1D228]={ + category="so", + direction="on", + }, + [0x1D229]={ + category="so", + direction="on", + }, + [0x1D22A]={ + category="so", + direction="on", + }, + [0x1D22B]={ + category="so", + direction="on", + }, + [0x1D22C]={ + category="so", + direction="on", + }, + [0x1D22D]={ + category="so", + direction="on", + }, + [0x1D22E]={ + category="so", + direction="on", + }, + [0x1D22F]={ + category="so", + direction="on", + }, + [0x1D230]={ + category="so", + direction="on", + }, + [0x1D231]={ + category="so", + direction="on", + }, + [0x1D232]={ + category="so", + direction="on", + }, + [0x1D233]={ + category="so", + direction="on", + }, + [0x1D234]={ + category="so", + direction="on", + }, + [0x1D235]={ + category="so", + direction="on", + }, + [0x1D236]={ + category="so", + direction="on", + }, + [0x1D237]={ + category="so", + direction="on", + }, + [0x1D238]={ + category="so", + direction="on", + }, + [0x1D239]={ + category="so", + direction="on", + }, + [0x1D23A]={ + category="so", + direction="on", + }, + [0x1D23B]={ + category="so", + direction="on", + }, + [0x1D23C]={ + category="so", + direction="on", + }, + [0x1D23D]={ + category="so", + direction="on", + }, + [0x1D23E]={ + category="so", + direction="on", + }, + [0x1D23F]={ + category="so", + direction="on", + }, + [0x1D240]={ + category="so", + direction="on", + }, + [0x1D241]={ + category="so", + direction="on", + }, + [0x1D242]={ + category="mn", + direction="nsm", + }, + [0x1D243]={ + category="mn", + direction="nsm", + }, + [0x1D244]={ + category="mn", + direction="nsm", + }, + [0x1D245]={ + category="so", + direction="on", + }, + [0x1D300]={ + category="so", + direction="on", + }, + [0x1D301]={ + category="so", + direction="on", + }, + [0x1D302]={ + category="so", + direction="on", + }, + [0x1D303]={ + category="so", + direction="on", + }, + [0x1D304]={ + category="so", + direction="on", + }, + [0x1D305]={ + category="so", + direction="on", + }, + [0x1D306]={ + category="so", + direction="on", + }, + [0x1D307]={ + category="so", + direction="on", + }, + [0x1D308]={ + category="so", + direction="on", + }, + [0x1D309]={ + category="so", + direction="on", + }, + [0x1D30A]={ + category="so", + direction="on", + }, + [0x1D30B]={ + category="so", + direction="on", + }, + [0x1D30C]={ + category="so", + direction="on", + }, + [0x1D30D]={ + category="so", + direction="on", + }, + [0x1D30E]={ + category="so", + direction="on", + }, + [0x1D30F]={ + category="so", + direction="on", + }, + [0x1D310]={ + category="so", + direction="on", + }, + [0x1D311]={ + category="so", + direction="on", + }, + [0x1D312]={ + category="so", + direction="on", + }, + [0x1D313]={ + category="so", + direction="on", + }, + [0x1D314]={ + category="so", + direction="on", + }, + [0x1D315]={ + category="so", + direction="on", + }, + [0x1D316]={ + category="so", + direction="on", + }, + [0x1D317]={ + category="so", + direction="on", + }, + [0x1D318]={ + category="so", + direction="on", + }, + [0x1D319]={ + category="so", + direction="on", + }, + [0x1D31A]={ + category="so", + direction="on", + }, + [0x1D31B]={ + category="so", + direction="on", + }, + [0x1D31C]={ + category="so", + direction="on", + }, + [0x1D31D]={ + category="so", + direction="on", + }, + [0x1D31E]={ + category="so", + direction="on", + }, + [0x1D31F]={ + category="so", + direction="on", + }, + [0x1D320]={ + category="so", + direction="on", + }, + [0x1D321]={ + category="so", + direction="on", + }, + [0x1D322]={ + category="so", + direction="on", + }, + [0x1D323]={ + category="so", + direction="on", + }, + [0x1D324]={ + category="so", + direction="on", + }, + [0x1D325]={ + category="so", + direction="on", + }, + [0x1D326]={ + category="so", + direction="on", + }, + [0x1D327]={ + category="so", + direction="on", + }, + [0x1D328]={ + category="so", + direction="on", + }, + [0x1D329]={ + category="so", + direction="on", + }, + [0x1D32A]={ + category="so", + direction="on", + }, + [0x1D32B]={ + category="so", + direction="on", + }, + [0x1D32C]={ + category="so", + direction="on", + }, + [0x1D32D]={ + category="so", + direction="on", + }, + [0x1D32E]={ + category="so", + direction="on", + }, + [0x1D32F]={ + category="so", + direction="on", + }, + [0x1D330]={ + category="so", + direction="on", + }, + [0x1D331]={ + category="so", + direction="on", + }, + [0x1D332]={ + category="so", + direction="on", + }, + [0x1D333]={ + category="so", + direction="on", + }, + [0x1D334]={ + category="so", + direction="on", + }, + [0x1D335]={ + category="so", + direction="on", + }, + [0x1D336]={ + category="so", + direction="on", + }, + [0x1D337]={ + category="so", + direction="on", + }, + [0x1D338]={ + category="so", + direction="on", + }, + [0x1D339]={ + category="so", + direction="on", + }, + [0x1D33A]={ + category="so", + direction="on", + }, + [0x1D33B]={ + category="so", + direction="on", + }, + [0x1D33C]={ + category="so", + direction="on", + }, + [0x1D33D]={ + category="so", + direction="on", + }, + [0x1D33E]={ + category="so", + direction="on", + }, + [0x1D33F]={ + category="so", + direction="on", + }, + [0x1D340]={ + category="so", + direction="on", + }, + [0x1D341]={ + category="so", + direction="on", + }, + [0x1D342]={ + category="so", + direction="on", + }, + [0x1D343]={ + category="so", + direction="on", + }, + [0x1D344]={ + category="so", + direction="on", + }, + [0x1D345]={ + category="so", + direction="on", + }, + [0x1D346]={ + category="so", + direction="on", + }, + [0x1D347]={ + category="so", + direction="on", + }, + [0x1D348]={ + category="so", + direction="on", + }, + [0x1D349]={ + category="so", + direction="on", + }, + [0x1D34A]={ + category="so", + direction="on", + }, + [0x1D34B]={ + category="so", + direction="on", + }, + [0x1D34C]={ + category="so", + direction="on", + }, + [0x1D34D]={ + category="so", + direction="on", + }, + [0x1D34E]={ + category="so", + direction="on", + }, + [0x1D34F]={ + category="so", + direction="on", + }, + [0x1D350]={ + category="so", + direction="on", + }, + [0x1D351]={ + category="so", + direction="on", + }, + [0x1D352]={ + category="so", + direction="on", + }, + [0x1D353]={ + category="so", + direction="on", + }, + [0x1D354]={ + category="so", + direction="on", + }, + [0x1D355]={ + category="so", + direction="on", + }, + [0x1D356]={ + category="so", direction="on", }, - [0x1D20E]={ - category="so", - direction="on", + [0x1D360]={ + category="no", + direction="l", + }, + [0x1D361]={ + category="no", + direction="l", + }, + [0x1D362]={ + category="no", + direction="l", + }, + [0x1D363]={ + category="no", + direction="l", + }, + [0x1D364]={ + category="no", + direction="l", + }, + [0x1D365]={ + category="no", + direction="l", + }, + [0x1D366]={ + category="no", + direction="l", + }, + [0x1D367]={ + category="no", + direction="l", + }, + [0x1D368]={ + category="no", + direction="l", + }, + [0x1D369]={ + category="no", + direction="l", + }, + [0x1D36A]={ + category="no", + direction="l", + }, + [0x1D36B]={ + category="no", + direction="l", + }, + [0x1D36C]={ + category="no", + direction="l", + }, + [0x1D36D]={ + category="no", + direction="l", + }, + [0x1D36E]={ + category="no", + direction="l", + }, + [0x1D36F]={ + category="no", + direction="l", + }, + [0x1D370]={ + category="no", + direction="l", + }, + [0x1D371]={ + category="no", + direction="l", + }, + [0x1D400]={ + category="lu", + direction="l", + }, + [0x1D401]={ + category="lu", + direction="l", + }, + [0x1D402]={ + category="lu", + direction="l", + }, + [0x1D403]={ + category="lu", + direction="l", + }, + [0x1D404]={ + category="lu", + direction="l", + }, + [0x1D405]={ + category="lu", + direction="l", + }, + [0x1D406]={ + category="lu", + direction="l", + }, + [0x1D407]={ + category="lu", + direction="l", + }, + [0x1D408]={ + category="lu", + direction="l", + }, + [0x1D409]={ + category="lu", + direction="l", + }, + [0x1D40A]={ + category="lu", + direction="l", + }, + [0x1D40B]={ + category="lu", + direction="l", + }, + [0x1D40C]={ + category="lu", + direction="l", + }, + [0x1D40D]={ + category="lu", + direction="l", + }, + [0x1D40E]={ + category="lu", + direction="l", + }, + [0x1D40F]={ + category="lu", + direction="l", + }, + [0x1D410]={ + category="lu", + direction="l", + }, + [0x1D411]={ + category="lu", + direction="l", + }, + [0x1D412]={ + category="lu", + direction="l", + }, + [0x1D413]={ + category="lu", + direction="l", + }, + [0x1D414]={ + category="lu", + direction="l", + }, + [0x1D415]={ + category="lu", + direction="l", + }, + [0x1D416]={ + category="lu", + direction="l", + }, + [0x1D417]={ + category="lu", + direction="l", + }, + [0x1D418]={ + category="lu", + direction="l", + }, + [0x1D419]={ + category="lu", + direction="l", + }, + [0x1D41A]={ + category="ll", + direction="l", + }, + [0x1D41B]={ + category="ll", + direction="l", + }, + [0x1D41C]={ + category="ll", + direction="l", + }, + [0x1D41D]={ + category="ll", + direction="l", + }, + [0x1D41E]={ + category="ll", + direction="l", + }, + [0x1D41F]={ + category="ll", + direction="l", + }, + [0x1D420]={ + category="ll", + direction="l", + }, + [0x1D421]={ + category="ll", + direction="l", + }, + [0x1D422]={ + category="ll", + direction="l", + }, + [0x1D423]={ + category="ll", + direction="l", + }, + [0x1D424]={ + category="ll", + direction="l", + }, + [0x1D425]={ + category="ll", + direction="l", + }, + [0x1D426]={ + category="ll", + direction="l", + }, + [0x1D427]={ + category="ll", + direction="l", + }, + [0x1D428]={ + category="ll", + direction="l", + }, + [0x1D429]={ + category="ll", + direction="l", + }, + [0x1D42A]={ + category="ll", + direction="l", + }, + [0x1D42B]={ + category="ll", + direction="l", + }, + [0x1D42C]={ + category="ll", + direction="l", + }, + [0x1D42D]={ + category="ll", + direction="l", + }, + [0x1D42E]={ + category="ll", + direction="l", + }, + [0x1D42F]={ + category="ll", + direction="l", + }, + [0x1D430]={ + category="ll", + direction="l", + }, + [0x1D431]={ + category="ll", + direction="l", + }, + [0x1D432]={ + category="ll", + direction="l", + }, + [0x1D433]={ + category="ll", + direction="l", + }, + [0x1D434]={ + category="lu", + direction="l", + }, + [0x1D435]={ + category="lu", + direction="l", + }, + [0x1D436]={ + category="lu", + direction="l", + }, + [0x1D437]={ + category="lu", + direction="l", + }, + [0x1D438]={ + category="lu", + direction="l", + }, + [0x1D439]={ + category="lu", + direction="l", + }, + [0x1D43A]={ + category="lu", + direction="l", + }, + [0x1D43B]={ + category="lu", + direction="l", + }, + [0x1D43C]={ + category="lu", + direction="l", + }, + [0x1D43D]={ + category="lu", + direction="l", + }, + [0x1D43E]={ + category="lu", + direction="l", + }, + [0x1D43F]={ + category="lu", + direction="l", + }, + [0x1D440]={ + category="lu", + direction="l", + }, + [0x1D441]={ + category="lu", + direction="l", + }, + [0x1D442]={ + category="lu", + direction="l", + }, + [0x1D443]={ + category="lu", + direction="l", + }, + [0x1D444]={ + category="lu", + direction="l", + }, + [0x1D445]={ + category="lu", + direction="l", + }, + [0x1D446]={ + category="lu", + direction="l", + }, + [0x1D447]={ + category="lu", + direction="l", + }, + [0x1D448]={ + category="lu", + direction="l", + }, + [0x1D449]={ + category="lu", + direction="l", + }, + [0x1D44A]={ + category="lu", + direction="l", + }, + [0x1D44B]={ + category="lu", + direction="l", + }, + [0x1D44C]={ + category="lu", + direction="l", + }, + [0x1D44D]={ + category="lu", + direction="l", + }, + [0x1D44E]={ + category="ll", + direction="l", + }, + [0x1D44F]={ + category="ll", + direction="l", + }, + [0x1D450]={ + category="ll", + direction="l", + }, + [0x1D451]={ + category="ll", + direction="l", + }, + [0x1D452]={ + category="ll", + direction="l", + }, + [0x1D453]={ + category="ll", + direction="l", + }, + [0x1D454]={ + category="ll", + direction="l", + }, + [0x1D456]={ + category="ll", + direction="l", + }, + [0x1D457]={ + category="ll", + direction="l", + }, + [0x1D458]={ + category="ll", + direction="l", + }, + [0x1D459]={ + category="ll", + direction="l", + }, + [0x1D45A]={ + category="ll", + direction="l", + }, + [0x1D45B]={ + category="ll", + direction="l", + }, + [0x1D45C]={ + category="ll", + direction="l", + }, + [0x1D45D]={ + category="ll", + direction="l", + }, + [0x1D45E]={ + category="ll", + direction="l", + }, + [0x1D45F]={ + category="ll", + direction="l", + }, + [0x1D460]={ + category="ll", + direction="l", + }, + [0x1D461]={ + category="ll", + direction="l", + }, + [0x1D462]={ + category="ll", + direction="l", + }, + [0x1D463]={ + category="ll", + direction="l", + }, + [0x1D464]={ + category="ll", + direction="l", + }, + [0x1D465]={ + category="ll", + direction="l", + }, + [0x1D466]={ + category="ll", + direction="l", + }, + [0x1D467]={ + category="ll", + direction="l", + }, + [0x1D468]={ + category="lu", + direction="l", + }, + [0x1D469]={ + category="lu", + direction="l", + }, + [0x1D46A]={ + category="lu", + direction="l", + }, + [0x1D46B]={ + category="lu", + direction="l", + }, + [0x1D46C]={ + category="lu", + direction="l", + }, + [0x1D46D]={ + category="lu", + direction="l", + }, + [0x1D46E]={ + category="lu", + direction="l", + }, + [0x1D46F]={ + category="lu", + direction="l", + }, + [0x1D470]={ + category="lu", + direction="l", + }, + [0x1D471]={ + category="lu", + direction="l", + }, + [0x1D472]={ + category="lu", + direction="l", + }, + [0x1D473]={ + category="lu", + direction="l", + }, + [0x1D474]={ + category="lu", + direction="l", + }, + [0x1D475]={ + category="lu", + direction="l", + }, + [0x1D476]={ + category="lu", + direction="l", + }, + [0x1D477]={ + category="lu", + direction="l", + }, + [0x1D478]={ + category="lu", + direction="l", + }, + [0x1D479]={ + category="lu", + direction="l", + }, + [0x1D47A]={ + category="lu", + direction="l", + }, + [0x1D47B]={ + category="lu", + direction="l", + }, + [0x1D47C]={ + category="lu", + direction="l", + }, + [0x1D47D]={ + category="lu", + direction="l", + }, + [0x1D47E]={ + category="lu", + direction="l", + }, + [0x1D47F]={ + category="lu", + direction="l", + }, + [0x1D480]={ + category="lu", + direction="l", + }, + [0x1D481]={ + category="lu", + direction="l", + }, + [0x1D482]={ + category="ll", + direction="l", + }, + [0x1D483]={ + category="ll", + direction="l", + }, + [0x1D484]={ + category="ll", + direction="l", + }, + [0x1D485]={ + category="ll", + direction="l", + }, + [0x1D486]={ + category="ll", + direction="l", + }, + [0x1D487]={ + category="ll", + direction="l", + }, + [0x1D488]={ + category="ll", + direction="l", + }, + [0x1D489]={ + category="ll", + direction="l", + }, + [0x1D48A]={ + category="ll", + direction="l", + }, + [0x1D48B]={ + category="ll", + direction="l", + }, + [0x1D48C]={ + category="ll", + direction="l", + }, + [0x1D48D]={ + category="ll", + direction="l", + }, + [0x1D48E]={ + category="ll", + direction="l", + }, + [0x1D48F]={ + category="ll", + direction="l", + }, + [0x1D490]={ + category="ll", + direction="l", + }, + [0x1D491]={ + category="ll", + direction="l", + }, + [0x1D492]={ + category="ll", + direction="l", + }, + [0x1D493]={ + category="ll", + direction="l", + }, + [0x1D494]={ + category="ll", + direction="l", + }, + [0x1D495]={ + category="ll", + direction="l", + }, + [0x1D496]={ + category="ll", + direction="l", + }, + [0x1D497]={ + category="ll", + direction="l", + }, + [0x1D498]={ + category="ll", + direction="l", + }, + [0x1D499]={ + category="ll", + direction="l", + }, + [0x1D49A]={ + category="ll", + direction="l", + }, + [0x1D49B]={ + category="ll", + direction="l", + }, + [0x1D49C]={ + category="lu", + direction="l", + }, + [0x1D49E]={ + category="lu", + direction="l", + }, + [0x1D49F]={ + category="lu", + direction="l", + }, + [0x1D4A2]={ + category="lu", + direction="l", + }, + [0x1D4A5]={ + category="lu", + direction="l", + }, + [0x1D4A6]={ + category="lu", + direction="l", + }, + [0x1D4A9]={ + category="lu", + direction="l", + }, + [0x1D4AA]={ + category="lu", + direction="l", + }, + [0x1D4AB]={ + category="lu", + direction="l", + }, + [0x1D4AC]={ + category="lu", + direction="l", + }, + [0x1D4AE]={ + category="lu", + direction="l", + }, + [0x1D4AF]={ + category="lu", + direction="l", + }, + [0x1D4B0]={ + category="lu", + direction="l", + }, + [0x1D4B1]={ + category="lu", + direction="l", + }, + [0x1D4B2]={ + category="lu", + direction="l", + }, + [0x1D4B3]={ + category="lu", + direction="l", + }, + [0x1D4B4]={ + category="lu", + direction="l", + }, + [0x1D4B5]={ + category="lu", + direction="l", + }, + [0x1D4B6]={ + category="ll", + direction="l", + }, + [0x1D4B7]={ + category="ll", + direction="l", + }, + [0x1D4B8]={ + category="ll", + direction="l", + }, + [0x1D4B9]={ + category="ll", + direction="l", + }, + [0x1D4BB]={ + category="ll", + direction="l", + }, + [0x1D4BD]={ + category="ll", + direction="l", + }, + [0x1D4BE]={ + category="ll", + direction="l", + }, + [0x1D4BF]={ + category="ll", + direction="l", + }, + [0x1D4C0]={ + category="ll", + direction="l", + }, + [0x1D4C1]={ + category="ll", + direction="l", + }, + [0x1D4C2]={ + category="ll", + direction="l", + }, + [0x1D4C3]={ + category="ll", + direction="l", + }, + [0x1D4C5]={ + category="ll", + direction="l", + }, + [0x1D4C6]={ + category="ll", + direction="l", + }, + [0x1D4C7]={ + category="ll", + direction="l", + }, + [0x1D4C8]={ + category="ll", + direction="l", + }, + [0x1D4C9]={ + category="ll", + direction="l", + }, + [0x1D4CA]={ + category="ll", + direction="l", + }, + [0x1D4CB]={ + category="ll", + direction="l", + }, + [0x1D4CC]={ + category="ll", + direction="l", + }, + [0x1D4CD]={ + category="ll", + direction="l", + }, + [0x1D4CE]={ + category="ll", + direction="l", + }, + [0x1D4CF]={ + category="ll", + direction="l", + }, + [0x1D4D0]={ + category="lu", + direction="l", + }, + [0x1D4D1]={ + category="lu", + direction="l", + }, + [0x1D4D2]={ + category="lu", + direction="l", + }, + [0x1D4D3]={ + category="lu", + direction="l", + }, + [0x1D4D4]={ + category="lu", + direction="l", + }, + [0x1D4D5]={ + category="lu", + direction="l", + }, + [0x1D4D6]={ + category="lu", + direction="l", + }, + [0x1D4D7]={ + category="lu", + direction="l", + }, + [0x1D4D8]={ + category="lu", + direction="l", + }, + [0x1D4D9]={ + category="lu", + direction="l", + }, + [0x1D4DA]={ + category="lu", + direction="l", + }, + [0x1D4DB]={ + category="lu", + direction="l", + }, + [0x1D4DC]={ + category="lu", + direction="l", + }, + [0x1D4DD]={ + category="lu", + direction="l", + }, + [0x1D4DE]={ + category="lu", + direction="l", + }, + [0x1D4DF]={ + category="lu", + direction="l", + }, + [0x1D4E0]={ + category="lu", + direction="l", + }, + [0x1D4E1]={ + category="lu", + direction="l", + }, + [0x1D4E2]={ + category="lu", + direction="l", + }, + [0x1D4E3]={ + category="lu", + direction="l", + }, + [0x1D4E4]={ + category="lu", + direction="l", + }, + [0x1D4E5]={ + category="lu", + direction="l", + }, + [0x1D4E6]={ + category="lu", + direction="l", + }, + [0x1D4E7]={ + category="lu", + direction="l", + }, + [0x1D4E8]={ + category="lu", + direction="l", + }, + [0x1D4E9]={ + category="lu", + direction="l", + }, + [0x1D4EA]={ + category="ll", + direction="l", + }, + [0x1D4EB]={ + category="ll", + direction="l", + }, + [0x1D4EC]={ + category="ll", + direction="l", + }, + [0x1D4ED]={ + category="ll", + direction="l", + }, + [0x1D4EE]={ + category="ll", + direction="l", + }, + [0x1D4EF]={ + category="ll", + direction="l", + }, + [0x1D4F0]={ + category="ll", + direction="l", + }, + [0x1D4F1]={ + category="ll", + direction="l", + }, + [0x1D4F2]={ + category="ll", + direction="l", + }, + [0x1D4F3]={ + category="ll", + direction="l", + }, + [0x1D4F4]={ + category="ll", + direction="l", + }, + [0x1D4F5]={ + category="ll", + direction="l", + }, + [0x1D4F6]={ + category="ll", + direction="l", + }, + [0x1D4F7]={ + category="ll", + direction="l", + }, + [0x1D4F8]={ + category="ll", + direction="l", + }, + [0x1D4F9]={ + category="ll", + direction="l", + }, + [0x1D4FA]={ + category="ll", + direction="l", + }, + [0x1D4FB]={ + category="ll", + direction="l", + }, + [0x1D4FC]={ + category="ll", + direction="l", + }, + [0x1D4FD]={ + category="ll", + direction="l", + }, + [0x1D4FE]={ + category="ll", + direction="l", + }, + [0x1D4FF]={ + category="ll", + direction="l", + }, + [0x1D500]={ + category="ll", + direction="l", + }, + [0x1D501]={ + category="ll", + direction="l", + }, + [0x1D502]={ + category="ll", + direction="l", + }, + [0x1D503]={ + category="ll", + direction="l", + }, + [0x1D504]={ + category="lu", + direction="l", + }, + [0x1D505]={ + category="lu", + direction="l", + }, + [0x1D507]={ + category="lu", + direction="l", + }, + [0x1D508]={ + category="lu", + direction="l", + }, + [0x1D509]={ + category="lu", + direction="l", + }, + [0x1D50A]={ + category="lu", + direction="l", + }, + [0x1D50D]={ + category="lu", + direction="l", + }, + [0x1D50E]={ + category="lu", + direction="l", + }, + [0x1D50F]={ + category="lu", + direction="l", + }, + [0x1D510]={ + category="lu", + direction="l", + }, + [0x1D511]={ + category="lu", + direction="l", + }, + [0x1D512]={ + category="lu", + direction="l", + }, + [0x1D513]={ + category="lu", + direction="l", + }, + [0x1D514]={ + category="lu", + direction="l", + }, + [0x1D516]={ + category="lu", + direction="l", + }, + [0x1D517]={ + category="lu", + direction="l", + }, + [0x1D518]={ + category="lu", + direction="l", + }, + [0x1D519]={ + category="lu", + direction="l", + }, + [0x1D51A]={ + category="lu", + direction="l", + }, + [0x1D51B]={ + category="lu", + direction="l", + }, + [0x1D51C]={ + category="lu", + direction="l", + }, + [0x1D51E]={ + category="ll", + direction="l", + }, + [0x1D51F]={ + category="ll", + direction="l", + }, + [0x1D520]={ + category="ll", + direction="l", + }, + [0x1D521]={ + category="ll", + direction="l", + }, + [0x1D522]={ + category="ll", + direction="l", + }, + [0x1D523]={ + category="ll", + direction="l", + }, + [0x1D524]={ + category="ll", + direction="l", + }, + [0x1D525]={ + category="ll", + direction="l", + }, + [0x1D526]={ + category="ll", + direction="l", + }, + [0x1D527]={ + category="ll", + direction="l", + }, + [0x1D528]={ + category="ll", + direction="l", + }, + [0x1D529]={ + category="ll", + direction="l", + }, + [0x1D52A]={ + category="ll", + direction="l", + }, + [0x1D52B]={ + category="ll", + direction="l", + }, + [0x1D52C]={ + category="ll", + direction="l", + }, + [0x1D52D]={ + category="ll", + direction="l", + }, + [0x1D52E]={ + category="ll", + direction="l", + }, + [0x1D52F]={ + category="ll", + direction="l", + }, + [0x1D530]={ + category="ll", + direction="l", + }, + [0x1D531]={ + category="ll", + direction="l", + }, + [0x1D532]={ + category="ll", + direction="l", + }, + [0x1D533]={ + category="ll", + direction="l", + }, + [0x1D534]={ + category="ll", + direction="l", + }, + [0x1D535]={ + category="ll", + direction="l", + }, + [0x1D536]={ + category="ll", + direction="l", + }, + [0x1D537]={ + category="ll", + direction="l", + }, + [0x1D538]={ + category="lu", + direction="l", + }, + [0x1D539]={ + category="lu", + direction="l", + }, + [0x1D53B]={ + category="lu", + direction="l", + }, + [0x1D53C]={ + category="lu", + direction="l", + }, + [0x1D53D]={ + category="lu", + direction="l", + }, + [0x1D53E]={ + category="lu", + direction="l", + }, + [0x1D540]={ + category="lu", + direction="l", + }, + [0x1D541]={ + category="lu", + direction="l", + }, + [0x1D542]={ + category="lu", + direction="l", + }, + [0x1D543]={ + category="lu", + direction="l", + }, + [0x1D544]={ + category="lu", + direction="l", + }, + [0x1D546]={ + category="lu", + direction="l", + }, + [0x1D54A]={ + category="lu", + direction="l", + }, + [0x1D54B]={ + category="lu", + direction="l", + }, + [0x1D54C]={ + category="lu", + direction="l", + }, + [0x1D54D]={ + category="lu", + direction="l", + }, + [0x1D54E]={ + category="lu", + direction="l", + }, + [0x1D54F]={ + category="lu", + direction="l", + }, + [0x1D550]={ + category="lu", + direction="l", + }, + [0x1D552]={ + category="ll", + direction="l", + }, + [0x1D553]={ + category="ll", + direction="l", + }, + [0x1D554]={ + category="ll", + direction="l", + }, + [0x1D555]={ + category="ll", + direction="l", + }, + [0x1D556]={ + category="ll", + direction="l", + }, + [0x1D557]={ + category="ll", + direction="l", + }, + [0x1D558]={ + category="ll", + direction="l", + }, + [0x1D559]={ + category="ll", + direction="l", + }, + [0x1D55A]={ + category="ll", + direction="l", + }, + [0x1D55B]={ + category="ll", + direction="l", + }, + [0x1D55C]={ + category="ll", + direction="l", + }, + [0x1D55D]={ + category="ll", + direction="l", + }, + [0x1D55E]={ + category="ll", + direction="l", + }, + [0x1D55F]={ + category="ll", + direction="l", + }, + [0x1D560]={ + category="ll", + direction="l", + }, + [0x1D561]={ + category="ll", + direction="l", + }, + [0x1D562]={ + category="ll", + direction="l", + }, + [0x1D563]={ + category="ll", + direction="l", + }, + [0x1D564]={ + category="ll", + direction="l", + }, + [0x1D565]={ + category="ll", + direction="l", + }, + [0x1D566]={ + category="ll", + direction="l", + }, + [0x1D567]={ + category="ll", + direction="l", + }, + [0x1D568]={ + category="ll", + direction="l", + }, + [0x1D569]={ + category="ll", + direction="l", + }, + [0x1D56A]={ + category="ll", + direction="l", + }, + [0x1D56B]={ + category="ll", + direction="l", + }, + [0x1D56C]={ + category="lu", + direction="l", + }, + [0x1D56D]={ + category="lu", + direction="l", + }, + [0x1D56E]={ + category="lu", + direction="l", + }, + [0x1D56F]={ + category="lu", + direction="l", + }, + [0x1D570]={ + category="lu", + direction="l", + }, + [0x1D571]={ + category="lu", + direction="l", + }, + [0x1D572]={ + category="lu", + direction="l", + }, + [0x1D573]={ + category="lu", + direction="l", + }, + [0x1D574]={ + category="lu", + direction="l", + }, + [0x1D575]={ + category="lu", + direction="l", + }, + [0x1D576]={ + category="lu", + direction="l", + }, + [0x1D577]={ + category="lu", + direction="l", + }, + [0x1D578]={ + category="lu", + direction="l", + }, + [0x1D579]={ + category="lu", + direction="l", + }, + [0x1D57A]={ + category="lu", + direction="l", + }, + [0x1D57B]={ + category="lu", + direction="l", + }, + [0x1D57C]={ + category="lu", + direction="l", + }, + [0x1D57D]={ + category="lu", + direction="l", + }, + [0x1D57E]={ + category="lu", + direction="l", + }, + [0x1D57F]={ + category="lu", + direction="l", + }, + [0x1D580]={ + category="lu", + direction="l", + }, + [0x1D581]={ + category="lu", + direction="l", + }, + [0x1D582]={ + category="lu", + direction="l", + }, + [0x1D583]={ + category="lu", + direction="l", + }, + [0x1D584]={ + category="lu", + direction="l", + }, + [0x1D585]={ + category="lu", + direction="l", + }, + [0x1D586]={ + category="ll", + direction="l", + }, + [0x1D587]={ + category="ll", + direction="l", + }, + [0x1D588]={ + category="ll", + direction="l", + }, + [0x1D589]={ + category="ll", + direction="l", + }, + [0x1D58A]={ + category="ll", + direction="l", + }, + [0x1D58B]={ + category="ll", + direction="l", + }, + [0x1D58C]={ + category="ll", + direction="l", + }, + [0x1D58D]={ + category="ll", + direction="l", + }, + [0x1D58E]={ + category="ll", + direction="l", + }, + [0x1D58F]={ + category="ll", + direction="l", + }, + [0x1D590]={ + category="ll", + direction="l", + }, + [0x1D591]={ + category="ll", + direction="l", + }, + [0x1D592]={ + category="ll", + direction="l", + }, + [0x1D593]={ + category="ll", + direction="l", + }, + [0x1D594]={ + category="ll", + direction="l", + }, + [0x1D595]={ + category="ll", + direction="l", + }, + [0x1D596]={ + category="ll", + direction="l", + }, + [0x1D597]={ + category="ll", + direction="l", + }, + [0x1D598]={ + category="ll", + direction="l", + }, + [0x1D599]={ + category="ll", + direction="l", + }, + [0x1D59A]={ + category="ll", + direction="l", + }, + [0x1D59B]={ + category="ll", + direction="l", + }, + [0x1D59C]={ + category="ll", + direction="l", + }, + [0x1D59D]={ + category="ll", + direction="l", + }, + [0x1D59E]={ + category="ll", + direction="l", + }, + [0x1D59F]={ + category="ll", + direction="l", + }, + [0x1D5A0]={ + category="lu", + direction="l", + }, + [0x1D5A1]={ + category="lu", + direction="l", + }, + [0x1D5A2]={ + category="lu", + direction="l", + }, + [0x1D5A3]={ + category="lu", + direction="l", + }, + [0x1D5A4]={ + category="lu", + direction="l", + }, + [0x1D5A5]={ + category="lu", + direction="l", + }, + [0x1D5A6]={ + category="lu", + direction="l", + }, + [0x1D5A7]={ + category="lu", + direction="l", + }, + [0x1D5A8]={ + category="lu", + direction="l", + }, + [0x1D5A9]={ + category="lu", + direction="l", + }, + [0x1D5AA]={ + category="lu", + direction="l", + }, + [0x1D5AB]={ + category="lu", + direction="l", + }, + [0x1D5AC]={ + category="lu", + direction="l", + }, + [0x1D5AD]={ + category="lu", + direction="l", + }, + [0x1D5AE]={ + category="lu", + direction="l", + }, + [0x1D5AF]={ + category="lu", + direction="l", + }, + [0x1D5B0]={ + category="lu", + direction="l", + }, + [0x1D5B1]={ + category="lu", + direction="l", + }, + [0x1D5B2]={ + category="lu", + direction="l", + }, + [0x1D5B3]={ + category="lu", + direction="l", + }, + [0x1D5B4]={ + category="lu", + direction="l", + }, + [0x1D5B5]={ + category="lu", + direction="l", + }, + [0x1D5B6]={ + category="lu", + direction="l", + }, + [0x1D5B7]={ + category="lu", + direction="l", + }, + [0x1D5B8]={ + category="lu", + direction="l", + }, + [0x1D5B9]={ + category="lu", + direction="l", + }, + [0x1D5BA]={ + category="ll", + direction="l", + }, + [0x1D5BB]={ + category="ll", + direction="l", + }, + [0x1D5BC]={ + category="ll", + direction="l", + }, + [0x1D5BD]={ + category="ll", + direction="l", + }, + [0x1D5BE]={ + category="ll", + direction="l", + }, + [0x1D5BF]={ + category="ll", + direction="l", + }, + [0x1D5C0]={ + category="ll", + direction="l", + }, + [0x1D5C1]={ + category="ll", + direction="l", + }, + [0x1D5C2]={ + category="ll", + direction="l", + }, + [0x1D5C3]={ + category="ll", + direction="l", + }, + [0x1D5C4]={ + category="ll", + direction="l", + }, + [0x1D5C5]={ + category="ll", + direction="l", + }, + [0x1D5C6]={ + category="ll", + direction="l", + }, + [0x1D5C7]={ + category="ll", + direction="l", + }, + [0x1D5C8]={ + category="ll", + direction="l", + }, + [0x1D5C9]={ + category="ll", + direction="l", + }, + [0x1D5CA]={ + category="ll", + direction="l", + }, + [0x1D5CB]={ + category="ll", + direction="l", + }, + [0x1D5CC]={ + category="ll", + direction="l", + }, + [0x1D5CD]={ + category="ll", + direction="l", + }, + [0x1D5CE]={ + category="ll", + direction="l", + }, + [0x1D5CF]={ + category="ll", + direction="l", + }, + [0x1D5D0]={ + category="ll", + direction="l", + }, + [0x1D5D1]={ + category="ll", + direction="l", + }, + [0x1D5D2]={ + category="ll", + direction="l", + }, + [0x1D5D3]={ + category="ll", + direction="l", + }, + [0x1D5D4]={ + category="lu", + direction="l", + }, + [0x1D5D5]={ + category="lu", + direction="l", + }, + [0x1D5D6]={ + category="lu", + direction="l", + }, + [0x1D5D7]={ + category="lu", + direction="l", + }, + [0x1D5D8]={ + category="lu", + direction="l", + }, + [0x1D5D9]={ + category="lu", + direction="l", + }, + [0x1D5DA]={ + category="lu", + direction="l", + }, + [0x1D5DB]={ + category="lu", + direction="l", + }, + [0x1D5DC]={ + category="lu", + direction="l", + }, + [0x1D5DD]={ + category="lu", + direction="l", + }, + [0x1D5DE]={ + category="lu", + direction="l", + }, + [0x1D5DF]={ + category="lu", + direction="l", + }, + [0x1D5E0]={ + category="lu", + direction="l", + }, + [0x1D5E1]={ + category="lu", + direction="l", + }, + [0x1D5E2]={ + category="lu", + direction="l", + }, + [0x1D5E3]={ + category="lu", + direction="l", + }, + [0x1D5E4]={ + category="lu", + direction="l", + }, + [0x1D5E5]={ + category="lu", + direction="l", + }, + [0x1D5E6]={ + category="lu", + direction="l", + }, + [0x1D5E7]={ + category="lu", + direction="l", + }, + [0x1D5E8]={ + category="lu", + direction="l", + }, + [0x1D5E9]={ + category="lu", + direction="l", + }, + [0x1D5EA]={ + category="lu", + direction="l", + }, + [0x1D5EB]={ + category="lu", + direction="l", + }, + [0x1D5EC]={ + category="lu", + direction="l", + }, + [0x1D5ED]={ + category="lu", + direction="l", + }, + [0x1D5EE]={ + category="ll", + direction="l", }, - [0x1D20F]={ - category="so", - direction="on", + [0x1D5EF]={ + category="ll", + direction="l", }, - [0x1D210]={ - category="so", - direction="on", + [0x1D5F0]={ + category="ll", + direction="l", }, - [0x1D211]={ - category="so", - direction="on", + [0x1D5F1]={ + category="ll", + direction="l", }, - [0x1D212]={ - category="so", - direction="on", + [0x1D5F2]={ + category="ll", + direction="l", }, - [0x1D213]={ - category="so", - direction="on", + [0x1D5F3]={ + category="ll", + direction="l", }, - [0x1D214]={ - category="so", - direction="on", + [0x1D5F4]={ + category="ll", + direction="l", }, - [0x1D215]={ - category="so", - direction="on", + [0x1D5F5]={ + category="ll", + direction="l", }, - [0x1D216]={ - category="so", - direction="on", + [0x1D5F6]={ + category="ll", + direction="l", }, - [0x1D217]={ - category="so", - direction="on", + [0x1D5F7]={ + category="ll", + direction="l", }, - [0x1D218]={ - category="so", - direction="on", + [0x1D5F8]={ + category="ll", + direction="l", }, - [0x1D219]={ - category="so", - direction="on", + [0x1D5F9]={ + category="ll", + direction="l", }, - [0x1D21A]={ - category="so", - direction="on", + [0x1D5FA]={ + category="ll", + direction="l", }, - [0x1D21B]={ - category="so", - direction="on", + [0x1D5FB]={ + category="ll", + direction="l", }, - [0x1D21C]={ - category="so", - direction="on", + [0x1D5FC]={ + category="ll", + direction="l", }, - [0x1D21D]={ - category="so", - direction="on", + [0x1D5FD]={ + category="ll", + direction="l", }, - [0x1D21E]={ - category="so", - direction="on", + [0x1D5FE]={ + category="ll", + direction="l", }, - [0x1D21F]={ - category="so", - direction="on", + [0x1D5FF]={ + category="ll", + direction="l", }, - [0x1D220]={ - category="so", - direction="on", + [0x1D600]={ + category="ll", + direction="l", }, - [0x1D221]={ - category="so", - direction="on", + [0x1D601]={ + category="ll", + direction="l", }, - [0x1D222]={ - category="so", - direction="on", + [0x1D602]={ + category="ll", + direction="l", }, - [0x1D223]={ - category="so", - direction="on", + [0x1D603]={ + category="ll", + direction="l", }, - [0x1D224]={ - category="so", - direction="on", + [0x1D604]={ + category="ll", + direction="l", }, - [0x1D225]={ - category="so", - direction="on", + [0x1D605]={ + category="ll", + direction="l", }, - [0x1D226]={ - category="so", - direction="on", + [0x1D606]={ + category="ll", + direction="l", }, - [0x1D227]={ - category="so", - direction="on", + [0x1D607]={ + category="ll", + direction="l", }, - [0x1D228]={ - category="so", - direction="on", + [0x1D608]={ + category="lu", + direction="l", }, - [0x1D229]={ - category="so", - direction="on", + [0x1D609]={ + category="lu", + direction="l", }, - [0x1D22A]={ - category="so", - direction="on", + [0x1D60A]={ + category="lu", + direction="l", }, - [0x1D22B]={ - category="so", - direction="on", + [0x1D60B]={ + category="lu", + direction="l", }, - [0x1D22C]={ - category="so", - direction="on", + [0x1D60C]={ + category="lu", + direction="l", }, - [0x1D22D]={ - category="so", - direction="on", + [0x1D60D]={ + category="lu", + direction="l", }, - [0x1D22E]={ - category="so", - direction="on", + [0x1D60E]={ + category="lu", + direction="l", }, - [0x1D22F]={ - category="so", - direction="on", + [0x1D60F]={ + category="lu", + direction="l", }, - [0x1D230]={ - category="so", - direction="on", + [0x1D610]={ + category="lu", + direction="l", }, - [0x1D231]={ - category="so", - direction="on", + [0x1D611]={ + category="lu", + direction="l", }, - [0x1D232]={ - category="so", - direction="on", + [0x1D612]={ + category="lu", + direction="l", }, - [0x1D233]={ - category="so", - direction="on", + [0x1D613]={ + category="lu", + direction="l", }, - [0x1D234]={ - category="so", - direction="on", + [0x1D614]={ + category="lu", + direction="l", }, - [0x1D235]={ - category="so", - direction="on", + [0x1D615]={ + category="lu", + direction="l", }, - [0x1D236]={ - category="so", - direction="on", + [0x1D616]={ + category="lu", + direction="l", }, - [0x1D237]={ - category="so", - direction="on", + [0x1D617]={ + category="lu", + direction="l", }, - [0x1D238]={ - category="so", - direction="on", + [0x1D618]={ + category="lu", + direction="l", }, - [0x1D239]={ - category="so", - direction="on", + [0x1D619]={ + category="lu", + direction="l", }, - [0x1D23A]={ - category="so", - direction="on", + [0x1D61A]={ + category="lu", + direction="l", }, - [0x1D23B]={ - category="so", - direction="on", + [0x1D61B]={ + category="lu", + direction="l", }, - [0x1D23C]={ - category="so", - direction="on", + [0x1D61C]={ + category="lu", + direction="l", }, - [0x1D23D]={ - category="so", - direction="on", + [0x1D61D]={ + category="lu", + direction="l", }, - [0x1D23E]={ - category="so", - direction="on", + [0x1D61E]={ + category="lu", + direction="l", }, - [0x1D23F]={ - category="so", - direction="on", + [0x1D61F]={ + category="lu", + direction="l", }, - [0x1D240]={ - category="so", - direction="on", + [0x1D620]={ + category="lu", + direction="l", }, - [0x1D241]={ - category="so", - direction="on", + [0x1D621]={ + category="lu", + direction="l", }, - [0x1D242]={ - category="mn", - direction="nsm", + [0x1D622]={ + category="ll", + direction="l", }, - [0x1D243]={ - category="mn", - direction="nsm", + [0x1D623]={ + category="ll", + direction="l", }, - [0x1D244]={ - category="mn", - direction="nsm", + [0x1D624]={ + category="ll", + direction="l", }, - [0x1D245]={ - category="so", - direction="on", + [0x1D625]={ + category="ll", + direction="l", }, - [0x1D300]={ - category="so", - direction="on", + [0x1D626]={ + category="ll", + direction="l", }, - [0x1D301]={ - category="so", - direction="on", + [0x1D627]={ + category="ll", + direction="l", }, - [0x1D302]={ - category="so", - direction="on", + [0x1D628]={ + category="ll", + direction="l", }, - [0x1D303]={ - category="so", - direction="on", + [0x1D629]={ + category="ll", + direction="l", }, - [0x1D304]={ - category="so", - direction="on", + [0x1D62A]={ + category="ll", + direction="l", }, - [0x1D305]={ - category="so", - direction="on", + [0x1D62B]={ + category="ll", + direction="l", }, - [0x1D306]={ - category="so", - direction="on", + [0x1D62C]={ + category="ll", + direction="l", }, - [0x1D307]={ - category="so", - direction="on", + [0x1D62D]={ + category="ll", + direction="l", }, - [0x1D308]={ - category="so", - direction="on", + [0x1D62E]={ + category="ll", + direction="l", }, - [0x1D309]={ - category="so", - direction="on", + [0x1D62F]={ + category="ll", + direction="l", }, - [0x1D30A]={ - category="so", - direction="on", + [0x1D630]={ + category="ll", + direction="l", }, - [0x1D30B]={ - category="so", - direction="on", + [0x1D631]={ + category="ll", + direction="l", }, - [0x1D30C]={ - category="so", - direction="on", + [0x1D632]={ + category="ll", + direction="l", }, - [0x1D30D]={ - category="so", - direction="on", + [0x1D633]={ + category="ll", + direction="l", + }, + [0x1D634]={ + category="ll", + direction="l", + }, + [0x1D635]={ + category="ll", + direction="l", + }, + [0x1D636]={ + category="ll", + direction="l", + }, + [0x1D637]={ + category="ll", + direction="l", + }, + [0x1D638]={ + category="ll", + direction="l", + }, + [0x1D639]={ + category="ll", + direction="l", + }, + [0x1D63A]={ + category="ll", + direction="l", + }, + [0x1D63B]={ + category="ll", + direction="l", + }, + [0x1D63C]={ + category="lu", + direction="l", + }, + [0x1D63D]={ + category="lu", + direction="l", + }, + [0x1D63E]={ + category="lu", + direction="l", + }, + [0x1D63F]={ + category="lu", + direction="l", + }, + [0x1D640]={ + category="lu", + direction="l", + }, + [0x1D641]={ + category="lu", + direction="l", + }, + [0x1D642]={ + category="lu", + direction="l", + }, + [0x1D643]={ + category="lu", + direction="l", + }, + [0x1D644]={ + category="lu", + direction="l", + }, + [0x1D645]={ + category="lu", + direction="l", + }, + [0x1D646]={ + category="lu", + direction="l", + }, + [0x1D647]={ + category="lu", + direction="l", + }, + [0x1D648]={ + category="lu", + direction="l", + }, + [0x1D649]={ + category="lu", + direction="l", + }, + [0x1D64A]={ + category="lu", + direction="l", }, - [0x1D30E]={ - category="so", - direction="on", + [0x1D64B]={ + category="lu", + direction="l", }, - [0x1D30F]={ - category="so", - direction="on", + [0x1D64C]={ + category="lu", + direction="l", }, - [0x1D310]={ - category="so", - direction="on", + [0x1D64D]={ + category="lu", + direction="l", }, - [0x1D311]={ - category="so", - direction="on", + [0x1D64E]={ + category="lu", + direction="l", }, - [0x1D312]={ - category="so", - direction="on", + [0x1D64F]={ + category="lu", + direction="l", }, - [0x1D313]={ - category="so", - direction="on", + [0x1D650]={ + category="lu", + direction="l", }, - [0x1D314]={ - category="so", - direction="on", + [0x1D651]={ + category="lu", + direction="l", }, - [0x1D315]={ - category="so", - direction="on", + [0x1D652]={ + category="lu", + direction="l", }, - [0x1D316]={ - category="so", - direction="on", + [0x1D653]={ + category="lu", + direction="l", }, - [0x1D317]={ - category="so", - direction="on", + [0x1D654]={ + category="lu", + direction="l", }, - [0x1D318]={ - category="so", - direction="on", + [0x1D655]={ + category="lu", + direction="l", }, - [0x1D319]={ - category="so", - direction="on", + [0x1D656]={ + category="ll", + direction="l", }, - [0x1D31A]={ - category="so", - direction="on", + [0x1D657]={ + category="ll", + direction="l", }, - [0x1D31B]={ - category="so", - direction="on", + [0x1D658]={ + category="ll", + direction="l", }, - [0x1D31C]={ - category="so", - direction="on", + [0x1D659]={ + category="ll", + direction="l", }, - [0x1D31D]={ - category="so", - direction="on", + [0x1D65A]={ + category="ll", + direction="l", }, - [0x1D31E]={ - category="so", - direction="on", + [0x1D65B]={ + category="ll", + direction="l", }, - [0x1D31F]={ - category="so", - direction="on", + [0x1D65C]={ + category="ll", + direction="l", }, - [0x1D320]={ - category="so", - direction="on", + [0x1D65D]={ + category="ll", + direction="l", }, - [0x1D321]={ - category="so", - direction="on", + [0x1D65E]={ + category="ll", + direction="l", }, - [0x1D322]={ - category="so", - direction="on", + [0x1D65F]={ + category="ll", + direction="l", }, - [0x1D323]={ - category="so", - direction="on", + [0x1D660]={ + category="ll", + direction="l", }, - [0x1D324]={ - category="so", - direction="on", + [0x1D661]={ + category="ll", + direction="l", }, - [0x1D325]={ - category="so", - direction="on", + [0x1D662]={ + category="ll", + direction="l", }, - [0x1D326]={ - category="so", - direction="on", + [0x1D663]={ + category="ll", + direction="l", }, - [0x1D327]={ - category="so", - direction="on", + [0x1D664]={ + category="ll", + direction="l", }, - [0x1D328]={ - category="so", - direction="on", + [0x1D665]={ + category="ll", + direction="l", }, - [0x1D329]={ - category="so", - direction="on", + [0x1D666]={ + category="ll", + direction="l", }, - [0x1D32A]={ - category="so", - direction="on", + [0x1D667]={ + category="ll", + direction="l", }, - [0x1D32B]={ - category="so", - direction="on", + [0x1D668]={ + category="ll", + direction="l", }, - [0x1D32C]={ - category="so", - direction="on", + [0x1D669]={ + category="ll", + direction="l", }, - [0x1D32D]={ - category="so", - direction="on", + [0x1D66A]={ + category="ll", + direction="l", }, - [0x1D32E]={ - category="so", - direction="on", + [0x1D66B]={ + category="ll", + direction="l", }, - [0x1D32F]={ - category="so", - direction="on", + [0x1D66C]={ + category="ll", + direction="l", }, - [0x1D330]={ - category="so", - direction="on", + [0x1D66D]={ + category="ll", + direction="l", }, - [0x1D331]={ - category="so", - direction="on", + [0x1D66E]={ + category="ll", + direction="l", }, - [0x1D332]={ - category="so", - direction="on", + [0x1D66F]={ + category="ll", + direction="l", }, - [0x1D333]={ - category="so", - direction="on", + [0x1D670]={ + category="lu", + direction="l", }, - [0x1D334]={ - category="so", - direction="on", + [0x1D671]={ + category="lu", + direction="l", }, - [0x1D335]={ - category="so", - direction="on", + [0x1D672]={ + category="lu", + direction="l", }, - [0x1D336]={ - category="so", - direction="on", + [0x1D673]={ + category="lu", + direction="l", }, - [0x1D337]={ - category="so", - direction="on", + [0x1D674]={ + category="lu", + direction="l", }, - [0x1D338]={ - category="so", - direction="on", + [0x1D675]={ + category="lu", + direction="l", }, - [0x1D339]={ - category="so", - direction="on", + [0x1D676]={ + category="lu", + direction="l", }, - [0x1D33A]={ - category="so", - direction="on", + [0x1D677]={ + category="lu", + direction="l", }, - [0x1D33B]={ - category="so", - direction="on", + [0x1D678]={ + category="lu", + direction="l", }, - [0x1D33C]={ - category="so", - direction="on", + [0x1D679]={ + category="lu", + direction="l", }, - [0x1D33D]={ - category="so", - direction="on", + [0x1D67A]={ + category="lu", + direction="l", }, - [0x1D33E]={ - category="so", - direction="on", + [0x1D67B]={ + category="lu", + direction="l", }, - [0x1D33F]={ - category="so", - direction="on", + [0x1D67C]={ + category="lu", + direction="l", }, - [0x1D340]={ - category="so", - direction="on", + [0x1D67D]={ + category="lu", + direction="l", }, - [0x1D341]={ - category="so", - direction="on", + [0x1D67E]={ + category="lu", + direction="l", }, - [0x1D342]={ - category="so", - direction="on", + [0x1D67F]={ + category="lu", + direction="l", }, - [0x1D343]={ - category="so", - direction="on", + [0x1D680]={ + category="lu", + direction="l", }, - [0x1D344]={ - category="so", - direction="on", + [0x1D681]={ + category="lu", + direction="l", }, - [0x1D345]={ - category="so", - direction="on", + [0x1D682]={ + category="lu", + direction="l", }, - [0x1D346]={ - category="so", - direction="on", + [0x1D683]={ + category="lu", + direction="l", }, - [0x1D347]={ - category="so", - direction="on", + [0x1D684]={ + category="lu", + direction="l", }, - [0x1D348]={ - category="so", - direction="on", + [0x1D685]={ + category="lu", + direction="l", }, - [0x1D349]={ - category="so", - direction="on", + [0x1D686]={ + category="lu", + direction="l", }, - [0x1D34A]={ - category="so", - direction="on", + [0x1D687]={ + category="lu", + direction="l", }, - [0x1D34B]={ - category="so", - direction="on", + [0x1D688]={ + category="lu", + direction="l", }, - [0x1D34C]={ - category="so", - direction="on", + [0x1D689]={ + category="lu", + direction="l", }, - [0x1D34D]={ - category="so", - direction="on", + [0x1D68A]={ + category="ll", + direction="l", }, - [0x1D34E]={ - category="so", - direction="on", + [0x1D68B]={ + category="ll", + direction="l", }, - [0x1D34F]={ - category="so", - direction="on", + [0x1D68C]={ + category="ll", + direction="l", }, - [0x1D350]={ - category="so", - direction="on", + [0x1D68D]={ + category="ll", + direction="l", }, - [0x1D351]={ - category="so", - direction="on", + [0x1D68E]={ + category="ll", + direction="l", }, - [0x1D352]={ - category="so", - direction="on", + [0x1D68F]={ + category="ll", + direction="l", }, - [0x1D353]={ - category="so", - direction="on", + [0x1D690]={ + category="ll", + direction="l", }, - [0x1D354]={ - category="so", - direction="on", + [0x1D691]={ + category="ll", + direction="l", }, - [0x1D355]={ - category="so", - direction="on", + [0x1D692]={ + category="ll", + direction="l", }, - [0x1D356]={ - category="so", - direction="on", + [0x1D693]={ + category="ll", + direction="l", }, - [0x1D360]={ - category="no", + [0x1D694]={ + category="ll", direction="l", }, - [0x1D361]={ - category="no", + [0x1D695]={ + category="ll", direction="l", }, - [0x1D362]={ - category="no", + [0x1D696]={ + category="ll", direction="l", }, - [0x1D363]={ - category="no", + [0x1D697]={ + category="ll", direction="l", }, - [0x1D364]={ - category="no", + [0x1D698]={ + category="ll", direction="l", }, - [0x1D365]={ - category="no", + [0x1D699]={ + category="ll", direction="l", }, - [0x1D366]={ - category="no", + [0x1D69A]={ + category="ll", direction="l", }, - [0x1D367]={ - category="no", + [0x1D69B]={ + category="ll", direction="l", }, - [0x1D368]={ - category="no", + [0x1D69C]={ + category="ll", direction="l", }, - [0x1D369]={ - category="no", + [0x1D69D]={ + category="ll", direction="l", }, - [0x1D36A]={ - category="no", + [0x1D69E]={ + category="ll", direction="l", }, - [0x1D36B]={ - category="no", + [0x1D69F]={ + category="ll", direction="l", }, - [0x1D36C]={ - category="no", + [0x1D6A0]={ + category="ll", direction="l", }, - [0x1D36D]={ - category="no", + [0x1D6A1]={ + category="ll", direction="l", }, - [0x1D36E]={ - category="no", + [0x1D6A2]={ + category="ll", direction="l", }, - [0x1D36F]={ - category="no", + [0x1D6A3]={ + category="ll", direction="l", }, - [0x1D370]={ - category="no", + [0x1D6A4]={ + category="ll", direction="l", }, - [0x1D371]={ - category="no", + [0x1D6A5]={ + category="ll", direction="l", }, - [0x1D400]={ + [0x1D6A8]={ category="lu", direction="l", }, - [0x1D401]={ + [0x1D6A9]={ category="lu", direction="l", }, - [0x1D402]={ + [0x1D6AA]={ category="lu", direction="l", }, - [0x1D403]={ + [0x1D6AB]={ category="lu", direction="l", }, - [0x1D404]={ + [0x1D6AC]={ category="lu", direction="l", }, - [0x1D405]={ + [0x1D6AD]={ category="lu", direction="l", }, - [0x1D406]={ + [0x1D6AE]={ category="lu", direction="l", }, - [0x1D407]={ + [0x1D6AF]={ category="lu", direction="l", }, - [0x1D408]={ + [0x1D6B0]={ category="lu", direction="l", }, - [0x1D409]={ + [0x1D6B1]={ category="lu", direction="l", }, - [0x1D40A]={ + [0x1D6B2]={ category="lu", direction="l", }, - [0x1D40B]={ + [0x1D6B3]={ category="lu", direction="l", }, - [0x1D40C]={ + [0x1D6B4]={ category="lu", direction="l", }, - [0x1D40D]={ + [0x1D6B5]={ category="lu", direction="l", }, - [0x1D40E]={ + [0x1D6B6]={ category="lu", direction="l", }, - [0x1D40F]={ + [0x1D6B7]={ category="lu", direction="l", }, - [0x1D410]={ + [0x1D6B8]={ category="lu", direction="l", }, - [0x1D411]={ + [0x1D6B9]={ category="lu", direction="l", }, - [0x1D412]={ + [0x1D6BA]={ category="lu", direction="l", }, - [0x1D413]={ + [0x1D6BB]={ category="lu", direction="l", }, - [0x1D414]={ + [0x1D6BC]={ category="lu", direction="l", }, - [0x1D415]={ + [0x1D6BD]={ category="lu", direction="l", }, - [0x1D416]={ + [0x1D6BE]={ category="lu", direction="l", }, - [0x1D417]={ + [0x1D6BF]={ category="lu", direction="l", }, - [0x1D418]={ + [0x1D6C0]={ category="lu", direction="l", }, - [0x1D419]={ - category="lu", + [0x1D6C1]={ + category="sm", direction="l", }, - [0x1D41A]={ + [0x1D6C2]={ category="ll", direction="l", }, - [0x1D41B]={ + [0x1D6C3]={ category="ll", direction="l", }, - [0x1D41C]={ + [0x1D6C4]={ category="ll", direction="l", }, - [0x1D41D]={ + [0x1D6C5]={ category="ll", direction="l", }, - [0x1D41E]={ + [0x1D6C6]={ category="ll", direction="l", }, - [0x1D41F]={ + [0x1D6C7]={ category="ll", direction="l", }, - [0x1D420]={ + [0x1D6C8]={ category="ll", direction="l", }, - [0x1D421]={ + [0x1D6C9]={ category="ll", direction="l", }, - [0x1D422]={ + [0x1D6CA]={ category="ll", direction="l", }, - [0x1D423]={ + [0x1D6CB]={ category="ll", direction="l", }, - [0x1D424]={ + [0x1D6CC]={ category="ll", direction="l", }, - [0x1D425]={ + [0x1D6CD]={ category="ll", direction="l", }, - [0x1D426]={ + [0x1D6CE]={ category="ll", direction="l", }, - [0x1D427]={ + [0x1D6CF]={ category="ll", direction="l", }, - [0x1D428]={ + [0x1D6D0]={ category="ll", direction="l", }, - [0x1D429]={ + [0x1D6D1]={ category="ll", direction="l", }, - [0x1D42A]={ + [0x1D6D2]={ category="ll", direction="l", }, - [0x1D42B]={ + [0x1D6D3]={ category="ll", direction="l", }, - [0x1D42C]={ + [0x1D6D4]={ category="ll", direction="l", }, - [0x1D42D]={ + [0x1D6D5]={ category="ll", direction="l", }, - [0x1D42E]={ + [0x1D6D6]={ category="ll", direction="l", }, - [0x1D42F]={ + [0x1D6D7]={ category="ll", direction="l", }, - [0x1D430]={ + [0x1D6D8]={ category="ll", direction="l", }, - [0x1D431]={ + [0x1D6D9]={ category="ll", direction="l", }, - [0x1D432]={ + [0x1D6DA]={ category="ll", direction="l", }, - [0x1D433]={ + [0x1D6DB]={ + category="sm", + direction="on", + }, + [0x1D6DC]={ category="ll", direction="l", }, - [0x1D434]={ - category="lu", + [0x1D6DD]={ + category="ll", direction="l", }, - [0x1D435]={ + [0x1D6DE]={ + category="ll", + direction="l", + }, + [0x1D6DF]={ + category="ll", + direction="l", + }, + [0x1D6E0]={ + category="ll", + direction="l", + }, + [0x1D6E1]={ + category="ll", + direction="l", + }, + [0x1D6E2]={ category="lu", direction="l", }, - [0x1D436]={ + [0x1D6E3]={ category="lu", direction="l", }, - [0x1D437]={ + [0x1D6E4]={ category="lu", direction="l", }, - [0x1D438]={ + [0x1D6E5]={ category="lu", direction="l", }, - [0x1D439]={ + [0x1D6E6]={ category="lu", direction="l", }, - [0x1D43A]={ + [0x1D6E7]={ category="lu", direction="l", }, - [0x1D43B]={ + [0x1D6E8]={ category="lu", direction="l", }, - [0x1D43C]={ + [0x1D6E9]={ category="lu", direction="l", }, - [0x1D43D]={ + [0x1D6EA]={ category="lu", direction="l", }, - [0x1D43E]={ + [0x1D6EB]={ category="lu", direction="l", }, - [0x1D43F]={ + [0x1D6EC]={ category="lu", direction="l", }, - [0x1D440]={ + [0x1D6ED]={ category="lu", direction="l", }, - [0x1D441]={ + [0x1D6EE]={ category="lu", direction="l", }, - [0x1D442]={ + [0x1D6EF]={ category="lu", direction="l", }, - [0x1D443]={ + [0x1D6F0]={ category="lu", direction="l", }, - [0x1D444]={ + [0x1D6F1]={ category="lu", direction="l", }, - [0x1D445]={ + [0x1D6F2]={ category="lu", direction="l", }, - [0x1D446]={ + [0x1D6F3]={ category="lu", direction="l", }, - [0x1D447]={ + [0x1D6F4]={ category="lu", direction="l", }, - [0x1D448]={ + [0x1D6F5]={ category="lu", direction="l", }, - [0x1D449]={ + [0x1D6F6]={ category="lu", direction="l", }, - [0x1D44A]={ + [0x1D6F7]={ category="lu", direction="l", }, - [0x1D44B]={ + [0x1D6F8]={ category="lu", direction="l", }, - [0x1D44C]={ + [0x1D6F9]={ category="lu", direction="l", }, - [0x1D44D]={ + [0x1D6FA]={ category="lu", direction="l", }, - [0x1D44E]={ + [0x1D6FB]={ + category="sm", + direction="l", + }, + [0x1D6FC]={ category="ll", direction="l", }, - [0x1D44F]={ + [0x1D6FD]={ category="ll", direction="l", }, - [0x1D450]={ + [0x1D6FE]={ category="ll", direction="l", }, - [0x1D451]={ + [0x1D6FF]={ category="ll", direction="l", }, - [0x1D452]={ + [0x1D700]={ category="ll", direction="l", }, - [0x1D453]={ + [0x1D701]={ category="ll", direction="l", }, - [0x1D454]={ + [0x1D702]={ category="ll", direction="l", }, - [0x1D456]={ + [0x1D703]={ category="ll", direction="l", }, - [0x1D457]={ + [0x1D704]={ category="ll", direction="l", }, - [0x1D458]={ + [0x1D705]={ category="ll", direction="l", }, - [0x1D459]={ + [0x1D706]={ category="ll", direction="l", }, - [0x1D45A]={ + [0x1D707]={ category="ll", direction="l", }, - [0x1D45B]={ + [0x1D708]={ category="ll", direction="l", }, - [0x1D45C]={ + [0x1D709]={ category="ll", direction="l", }, - [0x1D45D]={ + [0x1D70A]={ category="ll", direction="l", }, - [0x1D45E]={ + [0x1D70B]={ category="ll", direction="l", }, - [0x1D45F]={ + [0x1D70C]={ category="ll", direction="l", }, - [0x1D460]={ + [0x1D70D]={ category="ll", direction="l", }, - [0x1D461]={ + [0x1D70E]={ category="ll", direction="l", }, - [0x1D462]={ + [0x1D70F]={ category="ll", direction="l", }, - [0x1D463]={ + [0x1D710]={ category="ll", direction="l", }, - [0x1D464]={ + [0x1D711]={ category="ll", direction="l", }, - [0x1D465]={ + [0x1D712]={ category="ll", direction="l", }, - [0x1D466]={ + [0x1D713]={ category="ll", direction="l", }, - [0x1D467]={ + [0x1D714]={ category="ll", direction="l", }, - [0x1D468]={ - category="lu", + [0x1D715]={ + category="sm", + direction="on", + }, + [0x1D716]={ + category="ll", direction="l", }, - [0x1D469]={ + [0x1D717]={ + category="ll", + direction="l", + }, + [0x1D718]={ + category="ll", + direction="l", + }, + [0x1D719]={ + category="ll", + direction="l", + }, + [0x1D71A]={ + category="ll", + direction="l", + }, + [0x1D71B]={ + category="ll", + direction="l", + }, + [0x1D71C]={ category="lu", direction="l", }, - [0x1D46A]={ + [0x1D71D]={ category="lu", direction="l", }, - [0x1D46B]={ + [0x1D71E]={ category="lu", direction="l", }, - [0x1D46C]={ + [0x1D71F]={ category="lu", direction="l", }, - [0x1D46D]={ + [0x1D720]={ category="lu", direction="l", }, - [0x1D46E]={ + [0x1D721]={ category="lu", direction="l", }, - [0x1D46F]={ + [0x1D722]={ category="lu", direction="l", }, - [0x1D470]={ + [0x1D723]={ category="lu", direction="l", }, - [0x1D471]={ + [0x1D724]={ category="lu", direction="l", }, - [0x1D472]={ + [0x1D725]={ category="lu", direction="l", }, - [0x1D473]={ + [0x1D726]={ category="lu", direction="l", }, - [0x1D474]={ + [0x1D727]={ category="lu", direction="l", }, - [0x1D475]={ + [0x1D728]={ category="lu", direction="l", }, - [0x1D476]={ + [0x1D729]={ category="lu", direction="l", }, - [0x1D477]={ + [0x1D72A]={ category="lu", direction="l", }, - [0x1D478]={ + [0x1D72B]={ category="lu", direction="l", }, - [0x1D479]={ + [0x1D72C]={ category="lu", direction="l", }, - [0x1D47A]={ + [0x1D72D]={ category="lu", direction="l", }, - [0x1D47B]={ + [0x1D72E]={ category="lu", direction="l", }, - [0x1D47C]={ + [0x1D72F]={ category="lu", direction="l", }, - [0x1D47D]={ + [0x1D730]={ category="lu", direction="l", }, - [0x1D47E]={ + [0x1D731]={ category="lu", direction="l", }, - [0x1D47F]={ + [0x1D732]={ category="lu", direction="l", }, - [0x1D480]={ + [0x1D733]={ category="lu", direction="l", }, - [0x1D481]={ + [0x1D734]={ category="lu", direction="l", }, - [0x1D482]={ + [0x1D735]={ + category="sm", + direction="l", + }, + [0x1D736]={ category="ll", direction="l", }, - [0x1D483]={ + [0x1D737]={ category="ll", direction="l", }, - [0x1D484]={ + [0x1D738]={ category="ll", direction="l", }, - [0x1D485]={ + [0x1D739]={ category="ll", direction="l", }, - [0x1D486]={ + [0x1D73A]={ category="ll", direction="l", }, - [0x1D487]={ + [0x1D73B]={ category="ll", direction="l", }, - [0x1D488]={ + [0x1D73C]={ category="ll", direction="l", }, - [0x1D489]={ + [0x1D73D]={ category="ll", direction="l", }, - [0x1D48A]={ + [0x1D73E]={ category="ll", direction="l", }, - [0x1D48B]={ + [0x1D73F]={ category="ll", direction="l", }, - [0x1D48C]={ + [0x1D740]={ category="ll", direction="l", }, - [0x1D48D]={ + [0x1D741]={ category="ll", direction="l", }, - [0x1D48E]={ + [0x1D742]={ category="ll", direction="l", }, - [0x1D48F]={ + [0x1D743]={ category="ll", direction="l", }, - [0x1D490]={ + [0x1D744]={ category="ll", direction="l", }, - [0x1D491]={ + [0x1D745]={ category="ll", direction="l", }, - [0x1D492]={ + [0x1D746]={ category="ll", direction="l", }, - [0x1D493]={ + [0x1D747]={ category="ll", direction="l", }, - [0x1D494]={ + [0x1D748]={ category="ll", direction="l", }, - [0x1D495]={ + [0x1D749]={ category="ll", direction="l", }, - [0x1D496]={ + [0x1D74A]={ category="ll", direction="l", }, - [0x1D497]={ + [0x1D74B]={ category="ll", direction="l", }, - [0x1D498]={ + [0x1D74C]={ category="ll", direction="l", }, - [0x1D499]={ + [0x1D74D]={ category="ll", direction="l", }, - [0x1D49A]={ + [0x1D74E]={ category="ll", direction="l", }, - [0x1D49B]={ + [0x1D74F]={ + category="sm", + direction="on", + }, + [0x1D750]={ category="ll", direction="l", }, - [0x1D49C]={ + [0x1D751]={ + category="ll", + direction="l", + }, + [0x1D752]={ + category="ll", + direction="l", + }, + [0x1D753]={ + category="ll", + direction="l", + }, + [0x1D754]={ + category="ll", + direction="l", + }, + [0x1D755]={ + category="ll", + direction="l", + }, + [0x1D756]={ category="lu", direction="l", }, - [0x1D49E]={ + [0x1D757]={ category="lu", direction="l", }, - [0x1D49F]={ + [0x1D758]={ category="lu", direction="l", }, - [0x1D4A2]={ + [0x1D759]={ category="lu", direction="l", }, - [0x1D4A5]={ + [0x1D75A]={ category="lu", direction="l", }, - [0x1D4A6]={ + [0x1D75B]={ category="lu", direction="l", }, - [0x1D4A9]={ + [0x1D75C]={ category="lu", direction="l", }, - [0x1D4AA]={ + [0x1D75D]={ category="lu", direction="l", }, - [0x1D4AB]={ + [0x1D75E]={ category="lu", direction="l", }, - [0x1D4AC]={ + [0x1D75F]={ category="lu", direction="l", }, - [0x1D4AE]={ + [0x1D760]={ category="lu", direction="l", }, - [0x1D4AF]={ + [0x1D761]={ category="lu", direction="l", }, - [0x1D4B0]={ + [0x1D762]={ category="lu", direction="l", }, - [0x1D4B1]={ + [0x1D763]={ category="lu", direction="l", }, - [0x1D4B2]={ + [0x1D764]={ category="lu", direction="l", }, - [0x1D4B3]={ + [0x1D765]={ category="lu", direction="l", }, - [0x1D4B4]={ + [0x1D766]={ category="lu", direction="l", }, - [0x1D4B5]={ + [0x1D767]={ category="lu", direction="l", }, - [0x1D4B6]={ + [0x1D768]={ + category="lu", + direction="l", + }, + [0x1D769]={ + category="lu", + direction="l", + }, + [0x1D76A]={ + category="lu", + direction="l", + }, + [0x1D76B]={ + category="lu", + direction="l", + }, + [0x1D76C]={ + category="lu", + direction="l", + }, + [0x1D76D]={ + category="lu", + direction="l", + }, + [0x1D76E]={ + category="lu", + direction="l", + }, + [0x1D76F]={ + category="sm", + direction="l", + }, + [0x1D770]={ category="ll", direction="l", }, - [0x1D4B7]={ + [0x1D771]={ category="ll", direction="l", }, - [0x1D4B8]={ + [0x1D772]={ category="ll", direction="l", }, - [0x1D4B9]={ + [0x1D773]={ category="ll", direction="l", }, - [0x1D4BB]={ + [0x1D774]={ category="ll", direction="l", }, - [0x1D4BD]={ + [0x1D775]={ category="ll", direction="l", }, - [0x1D4BE]={ + [0x1D776]={ category="ll", direction="l", }, - [0x1D4BF]={ + [0x1D777]={ category="ll", direction="l", }, - [0x1D4C0]={ + [0x1D778]={ category="ll", direction="l", }, - [0x1D4C1]={ + [0x1D779]={ + category="ll", + direction="l", + }, + [0x1D77A]={ + category="ll", + direction="l", + }, + [0x1D77B]={ + category="ll", + direction="l", + }, + [0x1D77C]={ + category="ll", + direction="l", + }, + [0x1D77D]={ + category="ll", + direction="l", + }, + [0x1D77E]={ + category="ll", + direction="l", + }, + [0x1D77F]={ + category="ll", + direction="l", + }, + [0x1D780]={ + category="ll", + direction="l", + }, + [0x1D781]={ category="ll", direction="l", }, - [0x1D4C2]={ + [0x1D782]={ category="ll", direction="l", }, - [0x1D4C3]={ + [0x1D783]={ category="ll", direction="l", }, - [0x1D4C5]={ + [0x1D784]={ category="ll", direction="l", }, - [0x1D4C6]={ + [0x1D785]={ category="ll", direction="l", }, - [0x1D4C7]={ + [0x1D786]={ category="ll", direction="l", }, - [0x1D4C8]={ + [0x1D787]={ category="ll", direction="l", }, - [0x1D4C9]={ + [0x1D788]={ category="ll", direction="l", }, - [0x1D4CA]={ + [0x1D789]={ + category="sm", + direction="on", + }, + [0x1D78A]={ category="ll", direction="l", }, - [0x1D4CB]={ + [0x1D78B]={ category="ll", direction="l", }, - [0x1D4CC]={ + [0x1D78C]={ category="ll", direction="l", }, - [0x1D4CD]={ + [0x1D78D]={ category="ll", direction="l", }, - [0x1D4CE]={ + [0x1D78E]={ category="ll", direction="l", }, - [0x1D4CF]={ + [0x1D78F]={ category="ll", direction="l", }, - [0x1D4D0]={ + [0x1D790]={ category="lu", direction="l", }, - [0x1D4D1]={ + [0x1D791]={ category="lu", direction="l", }, - [0x1D4D2]={ + [0x1D792]={ category="lu", direction="l", }, - [0x1D4D3]={ + [0x1D793]={ category="lu", direction="l", }, - [0x1D4D4]={ + [0x1D794]={ category="lu", direction="l", }, - [0x1D4D5]={ + [0x1D795]={ category="lu", direction="l", }, - [0x1D4D6]={ + [0x1D796]={ category="lu", direction="l", }, - [0x1D4D7]={ + [0x1D797]={ category="lu", direction="l", }, - [0x1D4D8]={ + [0x1D798]={ category="lu", direction="l", }, - [0x1D4D9]={ + [0x1D799]={ category="lu", direction="l", }, - [0x1D4DA]={ + [0x1D79A]={ category="lu", direction="l", }, - [0x1D4DB]={ + [0x1D79B]={ category="lu", direction="l", }, - [0x1D4DC]={ + [0x1D79C]={ category="lu", direction="l", }, - [0x1D4DD]={ + [0x1D79D]={ category="lu", direction="l", }, - [0x1D4DE]={ + [0x1D79E]={ category="lu", direction="l", }, - [0x1D4DF]={ + [0x1D79F]={ category="lu", direction="l", }, - [0x1D4E0]={ + [0x1D7A0]={ category="lu", direction="l", }, - [0x1D4E1]={ + [0x1D7A1]={ category="lu", direction="l", }, - [0x1D4E2]={ + [0x1D7A2]={ category="lu", direction="l", }, - [0x1D4E3]={ + [0x1D7A3]={ category="lu", direction="l", }, - [0x1D4E4]={ + [0x1D7A4]={ category="lu", direction="l", }, - [0x1D4E5]={ + [0x1D7A5]={ category="lu", direction="l", }, - [0x1D4E6]={ + [0x1D7A6]={ category="lu", direction="l", }, - [0x1D4E7]={ + [0x1D7A7]={ category="lu", direction="l", }, - [0x1D4E8]={ + [0x1D7A8]={ category="lu", direction="l", }, - [0x1D4E9]={ - category="lu", + [0x1D7A9]={ + category="sm", direction="l", }, - [0x1D4EA]={ + [0x1D7AA]={ category="ll", direction="l", }, - [0x1D4EB]={ + [0x1D7AB]={ category="ll", direction="l", }, - [0x1D4EC]={ + [0x1D7AC]={ category="ll", direction="l", }, - [0x1D4ED]={ + [0x1D7AD]={ category="ll", direction="l", }, - [0x1D4EE]={ + [0x1D7AE]={ category="ll", direction="l", }, - [0x1D4EF]={ + [0x1D7AF]={ category="ll", direction="l", }, - [0x1D4F0]={ + [0x1D7B0]={ category="ll", direction="l", }, - [0x1D4F1]={ + [0x1D7B1]={ category="ll", direction="l", }, - [0x1D4F2]={ + [0x1D7B2]={ category="ll", direction="l", }, - [0x1D4F3]={ + [0x1D7B3]={ category="ll", direction="l", }, - [0x1D4F4]={ + [0x1D7B4]={ category="ll", direction="l", }, - [0x1D4F5]={ + [0x1D7B5]={ category="ll", direction="l", }, - [0x1D4F6]={ + [0x1D7B6]={ category="ll", direction="l", }, - [0x1D4F7]={ + [0x1D7B7]={ category="ll", direction="l", }, - [0x1D4F8]={ + [0x1D7B8]={ category="ll", direction="l", }, - [0x1D4F9]={ + [0x1D7B9]={ category="ll", direction="l", }, - [0x1D4FA]={ + [0x1D7BA]={ category="ll", direction="l", }, - [0x1D4FB]={ + [0x1D7BB]={ category="ll", direction="l", }, - [0x1D4FC]={ + [0x1D7BC]={ category="ll", direction="l", }, - [0x1D4FD]={ + [0x1D7BD]={ category="ll", direction="l", }, - [0x1D4FE]={ + [0x1D7BE]={ category="ll", direction="l", }, - [0x1D4FF]={ + [0x1D7BF]={ category="ll", direction="l", }, - [0x1D500]={ + [0x1D7C0]={ category="ll", direction="l", }, - [0x1D501]={ + [0x1D7C1]={ category="ll", direction="l", }, - [0x1D502]={ + [0x1D7C2]={ category="ll", direction="l", }, - [0x1D503]={ + [0x1D7C3]={ + category="sm", + direction="on", + }, + [0x1D7C4]={ category="ll", direction="l", }, - [0x1D504]={ - category="lu", + [0x1D7C5]={ + category="ll", direction="l", }, - [0x1D505]={ - category="lu", + [0x1D7C6]={ + category="ll", direction="l", }, - [0x1D507]={ - category="lu", + [0x1D7C7]={ + category="ll", direction="l", }, - [0x1D508]={ - category="lu", + [0x1D7C8]={ + category="ll", direction="l", }, - [0x1D509]={ - category="lu", + [0x1D7C9]={ + category="ll", direction="l", }, - [0x1D50A]={ + [0x1D7CA]={ category="lu", direction="l", }, - [0x1D50D]={ - category="lu", + [0x1D7CB]={ + category="ll", direction="l", }, - [0x1D50E]={ - category="lu", - direction="l", + [0x1D7CE]={ + category="nd", + direction="en", }, - [0x1D50F]={ - category="lu", - direction="l", + [0x1D7CF]={ + category="nd", + direction="en", }, - [0x1D510]={ - category="lu", - direction="l", + [0x1D7D0]={ + category="nd", + direction="en", }, - [0x1D511]={ - category="lu", - direction="l", + [0x1D7D1]={ + category="nd", + direction="en", }, - [0x1D512]={ - category="lu", - direction="l", + [0x1D7D2]={ + category="nd", + direction="en", }, - [0x1D513]={ - category="lu", - direction="l", + [0x1D7D3]={ + category="nd", + direction="en", }, - [0x1D514]={ - category="lu", - direction="l", + [0x1D7D4]={ + category="nd", + direction="en", }, - [0x1D516]={ - category="lu", - direction="l", + [0x1D7D5]={ + category="nd", + direction="en", }, - [0x1D517]={ - category="lu", - direction="l", + [0x1D7D6]={ + category="nd", + direction="en", }, - [0x1D518]={ - category="lu", - direction="l", + [0x1D7D7]={ + category="nd", + direction="en", }, - [0x1D519]={ - category="lu", - direction="l", + [0x1D7D8]={ + category="nd", + direction="en", }, - [0x1D51A]={ - category="lu", - direction="l", + [0x1D7D9]={ + category="nd", + direction="en", }, - [0x1D51B]={ - category="lu", - direction="l", + [0x1D7DA]={ + category="nd", + direction="en", }, - [0x1D51C]={ - category="lu", - direction="l", + [0x1D7DB]={ + category="nd", + direction="en", + }, + [0x1D7DC]={ + category="nd", + direction="en", + }, + [0x1D7DD]={ + category="nd", + direction="en", + }, + [0x1D7DE]={ + category="nd", + direction="en", + }, + [0x1D7DF]={ + category="nd", + direction="en", + }, + [0x1D7E0]={ + category="nd", + direction="en", + }, + [0x1D7E1]={ + category="nd", + direction="en", + }, + [0x1D7E2]={ + category="nd", + direction="en", + }, + [0x1D7E3]={ + category="nd", + direction="en", + }, + [0x1D7E4]={ + category="nd", + direction="en", + }, + [0x1D7E5]={ + category="nd", + direction="en", + }, + [0x1D7E6]={ + category="nd", + direction="en", + }, + [0x1D7E7]={ + category="nd", + direction="en", + }, + [0x1D7E8]={ + category="nd", + direction="en", + }, + [0x1D7E9]={ + category="nd", + direction="en", + }, + [0x1D7EA]={ + category="nd", + direction="en", + }, + [0x1D7EB]={ + category="nd", + direction="en", + }, + [0x1D7EC]={ + category="nd", + direction="en", + }, + [0x1D7ED]={ + category="nd", + direction="en", + }, + [0x1D7EE]={ + category="nd", + direction="en", + }, + [0x1D7EF]={ + category="nd", + direction="en", + }, + [0x1D7F0]={ + category="nd", + direction="en", + }, + [0x1D7F1]={ + category="nd", + direction="en", + }, + [0x1D7F2]={ + category="nd", + direction="en", + }, + [0x1D7F3]={ + category="nd", + direction="en", + }, + [0x1D7F4]={ + category="nd", + direction="en", + }, + [0x1D7F5]={ + category="nd", + direction="en", + }, + [0x1D7F6]={ + category="nd", + direction="en", + }, + [0x1D7F7]={ + category="nd", + direction="en", + }, + [0x1D7F8]={ + category="nd", + direction="en", + }, + [0x1D7F9]={ + category="nd", + direction="en", + }, + [0x1D7FA]={ + category="nd", + direction="en", + }, + [0x1D7FB]={ + category="nd", + direction="en", + }, + [0x1D7FC]={ + category="nd", + direction="en", + }, + [0x1D7FD]={ + category="nd", + direction="en", + }, + [0x1D7FE]={ + category="nd", + direction="en", + }, + [0x1D7FF]={ + category="nd", + direction="en", + }, + [0x1E800]={ + category="lo", + direction="r", + }, + [0x1E801]={ + category="lo", + direction="r", + }, + [0x1E802]={ + category="lo", + direction="r", + }, + [0x1E803]={ + category="lo", + direction="r", + }, + [0x1E804]={ + category="lo", + direction="r", + }, + [0x1E805]={ + category="lo", + direction="r", + }, + [0x1E806]={ + category="lo", + direction="r", + }, + [0x1E807]={ + category="lo", + direction="r", + }, + [0x1E808]={ + category="lo", + direction="r", + }, + [0x1E809]={ + category="lo", + direction="r", + }, + [0x1E80A]={ + category="lo", + direction="r", + }, + [0x1E80B]={ + category="lo", + direction="r", + }, + [0x1E80C]={ + category="lo", + direction="r", + }, + [0x1E80D]={ + category="lo", + direction="r", + }, + [0x1E80E]={ + category="lo", + direction="r", + }, + [0x1E80F]={ + category="lo", + direction="r", + }, + [0x1E810]={ + category="lo", + direction="r", + }, + [0x1E811]={ + category="lo", + direction="r", + }, + [0x1E812]={ + category="lo", + direction="r", + }, + [0x1E813]={ + category="lo", + direction="r", + }, + [0x1E814]={ + category="lo", + direction="r", + }, + [0x1E815]={ + category="lo", + direction="r", + }, + [0x1E816]={ + category="lo", + direction="r", + }, + [0x1E817]={ + category="lo", + direction="r", + }, + [0x1E818]={ + category="lo", + direction="r", + }, + [0x1E819]={ + category="lo", + direction="r", + }, + [0x1E81A]={ + category="lo", + direction="r", + }, + [0x1E81B]={ + category="lo", + direction="r", + }, + [0x1E81C]={ + category="lo", + direction="r", + }, + [0x1E81D]={ + category="lo", + direction="r", + }, + [0x1E81E]={ + category="lo", + direction="r", + }, + [0x1E81F]={ + category="lo", + direction="r", + }, + [0x1E820]={ + category="lo", + direction="r", + }, + [0x1E821]={ + category="lo", + direction="r", + }, + [0x1E822]={ + category="lo", + direction="r", + }, + [0x1E823]={ + category="lo", + direction="r", + }, + [0x1E824]={ + category="lo", + direction="r", + }, + [0x1E825]={ + category="lo", + direction="r", + }, + [0x1E826]={ + category="lo", + direction="r", }, - [0x1D51E]={ - category="ll", - direction="l", + [0x1E827]={ + category="lo", + direction="r", }, - [0x1D51F]={ - category="ll", - direction="l", + [0x1E828]={ + category="lo", + direction="r", }, - [0x1D520]={ - category="ll", - direction="l", + [0x1E829]={ + category="lo", + direction="r", }, - [0x1D521]={ - category="ll", - direction="l", + [0x1E82A]={ + category="lo", + direction="r", }, - [0x1D522]={ - category="ll", - direction="l", + [0x1E82B]={ + category="lo", + direction="r", }, - [0x1D523]={ - category="ll", - direction="l", + [0x1E82C]={ + category="lo", + direction="r", }, - [0x1D524]={ - category="ll", - direction="l", + [0x1E82D]={ + category="lo", + direction="r", }, - [0x1D525]={ - category="ll", - direction="l", + [0x1E82E]={ + category="lo", + direction="r", }, - [0x1D526]={ - category="ll", - direction="l", + [0x1E82F]={ + category="lo", + direction="r", }, - [0x1D527]={ - category="ll", - direction="l", + [0x1E830]={ + category="lo", + direction="r", }, - [0x1D528]={ - category="ll", - direction="l", + [0x1E831]={ + category="lo", + direction="r", }, - [0x1D529]={ - category="ll", - direction="l", + [0x1E832]={ + category="lo", + direction="r", }, - [0x1D52A]={ - category="ll", - direction="l", + [0x1E833]={ + category="lo", + direction="r", }, - [0x1D52B]={ - category="ll", - direction="l", + [0x1E834]={ + category="lo", + direction="r", }, - [0x1D52C]={ - category="ll", - direction="l", + [0x1E835]={ + category="lo", + direction="r", }, - [0x1D52D]={ - category="ll", - direction="l", + [0x1E836]={ + category="lo", + direction="r", }, - [0x1D52E]={ - category="ll", - direction="l", + [0x1E837]={ + category="lo", + direction="r", }, - [0x1D52F]={ - category="ll", - direction="l", + [0x1E838]={ + category="lo", + direction="r", }, - [0x1D530]={ - category="ll", - direction="l", + [0x1E839]={ + category="lo", + direction="r", }, - [0x1D531]={ - category="ll", - direction="l", + [0x1E83A]={ + category="lo", + direction="r", }, - [0x1D532]={ - category="ll", - direction="l", + [0x1E83B]={ + category="lo", + direction="r", }, - [0x1D533]={ - category="ll", - direction="l", + [0x1E83C]={ + category="lo", + direction="r", }, - [0x1D534]={ - category="ll", - direction="l", + [0x1E83D]={ + category="lo", + direction="r", }, - [0x1D535]={ - category="ll", - direction="l", + [0x1E83E]={ + category="lo", + direction="r", }, - [0x1D536]={ - category="ll", - direction="l", + [0x1E83F]={ + category="lo", + direction="r", }, - [0x1D537]={ - category="ll", - direction="l", + [0x1E840]={ + category="lo", + direction="r", }, - [0x1D538]={ - category="lu", - direction="l", + [0x1E841]={ + category="lo", + direction="r", }, - [0x1D539]={ - category="lu", - direction="l", + [0x1E842]={ + category="lo", + direction="r", }, - [0x1D53B]={ - category="lu", - direction="l", + [0x1E843]={ + category="lo", + direction="r", }, - [0x1D53C]={ - category="lu", - direction="l", + [0x1E844]={ + category="lo", + direction="r", }, - [0x1D53D]={ - category="lu", - direction="l", + [0x1E845]={ + category="lo", + direction="r", }, - [0x1D53E]={ - category="lu", - direction="l", + [0x1E846]={ + category="lo", + direction="r", }, - [0x1D540]={ - category="lu", - direction="l", + [0x1E847]={ + category="lo", + direction="r", }, - [0x1D541]={ - category="lu", - direction="l", + [0x1E848]={ + category="lo", + direction="r", }, - [0x1D542]={ - category="lu", - direction="l", + [0x1E849]={ + category="lo", + direction="r", }, - [0x1D543]={ - category="lu", - direction="l", + [0x1E84A]={ + category="lo", + direction="r", }, - [0x1D544]={ - category="lu", - direction="l", + [0x1E84B]={ + category="lo", + direction="r", }, - [0x1D546]={ - category="lu", - direction="l", + [0x1E84C]={ + category="lo", + direction="r", }, - [0x1D54A]={ - category="lu", - direction="l", + [0x1E84D]={ + category="lo", + direction="r", }, - [0x1D54B]={ - category="lu", - direction="l", + [0x1E84E]={ + category="lo", + direction="r", }, - [0x1D54C]={ - category="lu", - direction="l", + [0x1E84F]={ + category="lo", + direction="r", }, - [0x1D54D]={ - category="lu", - direction="l", + [0x1E850]={ + category="lo", + direction="r", }, - [0x1D54E]={ - category="lu", - direction="l", + [0x1E851]={ + category="lo", + direction="r", }, - [0x1D54F]={ - category="lu", - direction="l", + [0x1E852]={ + category="lo", + direction="r", }, - [0x1D550]={ - category="lu", - direction="l", + [0x1E853]={ + category="lo", + direction="r", }, - [0x1D552]={ - category="ll", - direction="l", + [0x1E854]={ + category="lo", + direction="r", }, - [0x1D553]={ - category="ll", - direction="l", + [0x1E855]={ + category="lo", + direction="r", }, - [0x1D554]={ - category="ll", - direction="l", + [0x1E856]={ + category="lo", + direction="r", }, - [0x1D555]={ - category="ll", - direction="l", + [0x1E857]={ + category="lo", + direction="r", }, - [0x1D556]={ - category="ll", - direction="l", + [0x1E858]={ + category="lo", + direction="r", }, - [0x1D557]={ - category="ll", - direction="l", + [0x1E859]={ + category="lo", + direction="r", }, - [0x1D558]={ - category="ll", - direction="l", + [0x1E85A]={ + category="lo", + direction="r", }, - [0x1D559]={ - category="ll", - direction="l", + [0x1E85B]={ + category="lo", + direction="r", }, - [0x1D55A]={ - category="ll", - direction="l", + [0x1E85C]={ + category="lo", + direction="r", }, - [0x1D55B]={ - category="ll", - direction="l", + [0x1E85D]={ + category="lo", + direction="r", }, - [0x1D55C]={ - category="ll", - direction="l", + [0x1E85E]={ + category="lo", + direction="r", }, - [0x1D55D]={ - category="ll", - direction="l", + [0x1E85F]={ + category="lo", + direction="r", }, - [0x1D55E]={ - category="ll", - direction="l", + [0x1E860]={ + category="lo", + direction="r", }, - [0x1D55F]={ - category="ll", - direction="l", + [0x1E861]={ + category="lo", + direction="r", }, - [0x1D560]={ - category="ll", - direction="l", + [0x1E862]={ + category="lo", + direction="r", }, - [0x1D561]={ - category="ll", - direction="l", + [0x1E863]={ + category="lo", + direction="r", }, - [0x1D562]={ - category="ll", - direction="l", + [0x1E864]={ + category="lo", + direction="r", }, - [0x1D563]={ - category="ll", - direction="l", + [0x1E865]={ + category="lo", + direction="r", }, - [0x1D564]={ - category="ll", - direction="l", + [0x1E866]={ + category="lo", + direction="r", }, - [0x1D565]={ - category="ll", - direction="l", + [0x1E867]={ + category="lo", + direction="r", }, - [0x1D566]={ - category="ll", - direction="l", + [0x1E868]={ + category="lo", + direction="r", }, - [0x1D567]={ - category="ll", - direction="l", + [0x1E869]={ + category="lo", + direction="r", }, - [0x1D568]={ - category="ll", - direction="l", + [0x1E86A]={ + category="lo", + direction="r", }, - [0x1D569]={ - category="ll", - direction="l", + [0x1E86B]={ + category="lo", + direction="r", }, - [0x1D56A]={ - category="ll", - direction="l", + [0x1E86C]={ + category="lo", + direction="r", }, - [0x1D56B]={ - category="ll", - direction="l", + [0x1E86D]={ + category="lo", + direction="r", }, - [0x1D56C]={ - category="lu", - direction="l", + [0x1E86E]={ + category="lo", + direction="r", }, - [0x1D56D]={ - category="lu", - direction="l", + [0x1E86F]={ + category="lo", + direction="r", }, - [0x1D56E]={ - category="lu", - direction="l", + [0x1E870]={ + category="lo", + direction="r", }, - [0x1D56F]={ - category="lu", - direction="l", + [0x1E871]={ + category="lo", + direction="r", }, - [0x1D570]={ - category="lu", - direction="l", + [0x1E872]={ + category="lo", + direction="r", }, - [0x1D571]={ - category="lu", - direction="l", + [0x1E873]={ + category="lo", + direction="r", }, - [0x1D572]={ - category="lu", - direction="l", + [0x1E874]={ + category="lo", + direction="r", }, - [0x1D573]={ - category="lu", - direction="l", + [0x1E875]={ + category="lo", + direction="r", }, - [0x1D574]={ - category="lu", - direction="l", + [0x1E876]={ + category="lo", + direction="r", }, - [0x1D575]={ - category="lu", - direction="l", + [0x1E877]={ + category="lo", + direction="r", }, - [0x1D576]={ - category="lu", - direction="l", + [0x1E878]={ + category="lo", + direction="r", }, - [0x1D577]={ - category="lu", - direction="l", + [0x1E879]={ + category="lo", + direction="r", }, - [0x1D578]={ - category="lu", - direction="l", + [0x1E87A]={ + category="lo", + direction="r", }, - [0x1D579]={ - category="lu", - direction="l", + [0x1E87B]={ + category="lo", + direction="r", }, - [0x1D57A]={ - category="lu", - direction="l", + [0x1E87C]={ + category="lo", + direction="r", }, - [0x1D57B]={ - category="lu", - direction="l", + [0x1E87D]={ + category="lo", + direction="r", }, - [0x1D57C]={ - category="lu", - direction="l", + [0x1E87E]={ + category="lo", + direction="r", }, - [0x1D57D]={ - category="lu", - direction="l", + [0x1E87F]={ + category="lo", + direction="r", }, - [0x1D57E]={ - category="lu", - direction="l", + [0x1E880]={ + category="lo", + direction="r", }, - [0x1D57F]={ - category="lu", - direction="l", + [0x1E881]={ + category="lo", + direction="r", }, - [0x1D580]={ - category="lu", - direction="l", + [0x1E882]={ + category="lo", + direction="r", }, - [0x1D581]={ - category="lu", - direction="l", + [0x1E883]={ + category="lo", + direction="r", }, - [0x1D582]={ - category="lu", - direction="l", + [0x1E884]={ + category="lo", + direction="r", }, - [0x1D583]={ - category="lu", - direction="l", + [0x1E885]={ + category="lo", + direction="r", }, - [0x1D584]={ - category="lu", - direction="l", + [0x1E886]={ + category="lo", + direction="r", }, - [0x1D585]={ - category="lu", - direction="l", + [0x1E887]={ + category="lo", + direction="r", }, - [0x1D586]={ - category="ll", - direction="l", + [0x1E888]={ + category="lo", + direction="r", }, - [0x1D587]={ - category="ll", - direction="l", + [0x1E889]={ + category="lo", + direction="r", }, - [0x1D588]={ - category="ll", - direction="l", + [0x1E88A]={ + category="lo", + direction="r", }, - [0x1D589]={ - category="ll", - direction="l", + [0x1E88B]={ + category="lo", + direction="r", }, - [0x1D58A]={ - category="ll", - direction="l", + [0x1E88C]={ + category="lo", + direction="r", + }, + [0x1E88D]={ + category="lo", + direction="r", }, - [0x1D58B]={ - category="ll", - direction="l", + [0x1E88E]={ + category="lo", + direction="r", }, - [0x1D58C]={ - category="ll", - direction="l", + [0x1E88F]={ + category="lo", + direction="r", }, - [0x1D58D]={ - category="ll", - direction="l", + [0x1E890]={ + category="lo", + direction="r", }, - [0x1D58E]={ - category="ll", - direction="l", + [0x1E891]={ + category="lo", + direction="r", }, - [0x1D58F]={ - category="ll", - direction="l", + [0x1E892]={ + category="lo", + direction="r", }, - [0x1D590]={ - category="ll", - direction="l", + [0x1E893]={ + category="lo", + direction="r", }, - [0x1D591]={ - category="ll", - direction="l", + [0x1E894]={ + category="lo", + direction="r", }, - [0x1D592]={ - category="ll", - direction="l", + [0x1E895]={ + category="lo", + direction="r", }, - [0x1D593]={ - category="ll", - direction="l", + [0x1E896]={ + category="lo", + direction="r", }, - [0x1D594]={ - category="ll", - direction="l", + [0x1E897]={ + category="lo", + direction="r", }, - [0x1D595]={ - category="ll", - direction="l", + [0x1E898]={ + category="lo", + direction="r", }, - [0x1D596]={ - category="ll", - direction="l", + [0x1E899]={ + category="lo", + direction="r", }, - [0x1D597]={ - category="ll", - direction="l", + [0x1E89A]={ + category="lo", + direction="r", }, - [0x1D598]={ - category="ll", - direction="l", + [0x1E89B]={ + category="lo", + direction="r", }, - [0x1D599]={ - category="ll", - direction="l", + [0x1E89C]={ + category="lo", + direction="r", }, - [0x1D59A]={ - category="ll", - direction="l", + [0x1E89D]={ + category="lo", + direction="r", }, - [0x1D59B]={ - category="ll", - direction="l", + [0x1E89E]={ + category="lo", + direction="r", }, - [0x1D59C]={ - category="ll", - direction="l", + [0x1E89F]={ + category="lo", + direction="r", }, - [0x1D59D]={ - category="ll", - direction="l", + [0x1E8A0]={ + category="lo", + direction="r", }, - [0x1D59E]={ - category="ll", - direction="l", + [0x1E8A1]={ + category="lo", + direction="r", }, - [0x1D59F]={ - category="ll", - direction="l", + [0x1E8A2]={ + category="lo", + direction="r", }, - [0x1D5A0]={ - category="lu", - direction="l", + [0x1E8A3]={ + category="lo", + direction="r", }, - [0x1D5A1]={ - category="lu", - direction="l", + [0x1E8A4]={ + category="lo", + direction="r", }, - [0x1D5A2]={ - category="lu", - direction="l", + [0x1E8A5]={ + category="lo", + direction="r", }, - [0x1D5A3]={ - category="lu", - direction="l", + [0x1E8A6]={ + category="lo", + direction="r", }, - [0x1D5A4]={ - category="lu", - direction="l", + [0x1E8A7]={ + category="lo", + direction="r", }, - [0x1D5A5]={ - category="lu", - direction="l", + [0x1E8A8]={ + category="lo", + direction="r", }, - [0x1D5A6]={ - category="lu", - direction="l", + [0x1E8A9]={ + category="lo", + direction="r", }, - [0x1D5A7]={ - category="lu", - direction="l", + [0x1E8AA]={ + category="lo", + direction="r", }, - [0x1D5A8]={ - category="lu", - direction="l", + [0x1E8AB]={ + category="lo", + direction="r", }, - [0x1D5A9]={ - category="lu", - direction="l", + [0x1E8AC]={ + category="lo", + direction="r", }, - [0x1D5AA]={ - category="lu", - direction="l", + [0x1E8AD]={ + category="lo", + direction="r", }, - [0x1D5AB]={ - category="lu", - direction="l", + [0x1E8AE]={ + category="lo", + direction="r", }, - [0x1D5AC]={ - category="lu", - direction="l", + [0x1E8AF]={ + category="lo", + direction="r", }, - [0x1D5AD]={ - category="lu", - direction="l", + [0x1E8B0]={ + category="lo", + direction="r", }, - [0x1D5AE]={ - category="lu", - direction="l", + [0x1E8B1]={ + category="lo", + direction="r", }, - [0x1D5AF]={ - category="lu", - direction="l", + [0x1E8B2]={ + category="lo", + direction="r", }, - [0x1D5B0]={ - category="lu", - direction="l", + [0x1E8B3]={ + category="lo", + direction="r", }, - [0x1D5B1]={ - category="lu", - direction="l", + [0x1E8B4]={ + category="lo", + direction="r", }, - [0x1D5B2]={ - category="lu", - direction="l", + [0x1E8B5]={ + category="lo", + direction="r", }, - [0x1D5B3]={ - category="lu", - direction="l", + [0x1E8B6]={ + category="lo", + direction="r", }, - [0x1D5B4]={ - category="lu", - direction="l", + [0x1E8B7]={ + category="lo", + direction="r", }, - [0x1D5B5]={ - category="lu", - direction="l", + [0x1E8B8]={ + category="lo", + direction="r", }, - [0x1D5B6]={ - category="lu", - direction="l", + [0x1E8B9]={ + category="lo", + direction="r", }, - [0x1D5B7]={ - category="lu", - direction="l", + [0x1E8BA]={ + category="lo", + direction="r", }, - [0x1D5B8]={ - category="lu", - direction="l", + [0x1E8BB]={ + category="lo", + direction="r", }, - [0x1D5B9]={ - category="lu", - direction="l", + [0x1E8BC]={ + category="lo", + direction="r", }, - [0x1D5BA]={ - category="ll", - direction="l", + [0x1E8BD]={ + category="lo", + direction="r", }, - [0x1D5BB]={ - category="ll", - direction="l", + [0x1E8BE]={ + category="lo", + direction="r", }, - [0x1D5BC]={ - category="ll", - direction="l", + [0x1E8BF]={ + category="lo", + direction="r", }, - [0x1D5BD]={ - category="ll", - direction="l", + [0x1E8C0]={ + category="lo", + direction="r", }, - [0x1D5BE]={ - category="ll", - direction="l", + [0x1E8C1]={ + category="lo", + direction="r", }, - [0x1D5BF]={ - category="ll", - direction="l", + [0x1E8C2]={ + category="lo", + direction="r", }, - [0x1D5C0]={ - category="ll", - direction="l", + [0x1E8C3]={ + category="lo", + direction="r", }, - [0x1D5C1]={ - category="ll", - direction="l", + [0x1E8C4]={ + category="lo", + direction="r", }, - [0x1D5C2]={ - category="ll", - direction="l", + [0x1E8C7]={ + category="no", + direction="r", }, - [0x1D5C3]={ - category="ll", - direction="l", + [0x1E8C8]={ + category="no", + direction="r", }, - [0x1D5C4]={ - category="ll", - direction="l", + [0x1E8C9]={ + category="no", + direction="r", }, - [0x1D5C5]={ - category="ll", - direction="l", + [0x1E8CA]={ + category="no", + direction="r", }, - [0x1D5C6]={ - category="ll", - direction="l", + [0x1E8CB]={ + category="no", + direction="r", }, - [0x1D5C7]={ - category="ll", - direction="l", + [0x1E8CC]={ + category="no", + direction="r", }, - [0x1D5C8]={ - category="ll", - direction="l", + [0x1E8CD]={ + category="no", + direction="r", }, - [0x1D5C9]={ - category="ll", - direction="l", + [0x1E8CE]={ + category="no", + direction="r", }, - [0x1D5CA]={ - category="ll", - direction="l", + [0x1E8CF]={ + category="no", + direction="r", }, - [0x1D5CB]={ - category="ll", - direction="l", + [0x1E8D0]={ + category="mn", + direction="nsm", }, - [0x1D5CC]={ - category="ll", - direction="l", + [0x1E8D1]={ + category="mn", + direction="nsm", }, - [0x1D5CD]={ - category="ll", - direction="l", + [0x1E8D2]={ + category="mn", + direction="nsm", }, - [0x1D5CE]={ - category="ll", - direction="l", + [0x1E8D3]={ + category="mn", + direction="nsm", }, - [0x1D5CF]={ - category="ll", - direction="l", + [0x1E8D4]={ + category="mn", + direction="nsm", }, - [0x1D5D0]={ - category="ll", - direction="l", + [0x1E8D5]={ + category="mn", + direction="nsm", }, - [0x1D5D1]={ - category="ll", - direction="l", + [0x1E8D6]={ + category="mn", + direction="nsm", }, - [0x1D5D2]={ - category="ll", - direction="l", + [0x1EE00]={ + category="lo", + direction="al", }, - [0x1D5D3]={ - category="ll", - direction="l", + [0x1EE01]={ + category="lo", + direction="al", }, - [0x1D5D4]={ - category="lu", - direction="l", + [0x1EE02]={ + category="lo", + direction="al", }, - [0x1D5D5]={ - category="lu", - direction="l", + [0x1EE03]={ + category="lo", + direction="al", }, - [0x1D5D6]={ - category="lu", - direction="l", + [0x1EE05]={ + category="lo", + direction="al", }, - [0x1D5D7]={ - category="lu", - direction="l", + [0x1EE06]={ + category="lo", + direction="al", }, - [0x1D5D8]={ - category="lu", - direction="l", + [0x1EE07]={ + category="lo", + direction="al", }, - [0x1D5D9]={ - category="lu", - direction="l", + [0x1EE08]={ + category="lo", + direction="al", }, - [0x1D5DA]={ - category="lu", - direction="l", + [0x1EE09]={ + category="lo", + direction="al", }, - [0x1D5DB]={ - category="lu", - direction="l", + [0x1EE0A]={ + category="lo", + direction="al", }, - [0x1D5DC]={ - category="lu", - direction="l", + [0x1EE0B]={ + category="lo", + direction="al", }, - [0x1D5DD]={ - category="lu", - direction="l", + [0x1EE0C]={ + category="lo", + direction="al", }, - [0x1D5DE]={ - category="lu", - direction="l", + [0x1EE0D]={ + category="lo", + direction="al", }, - [0x1D5DF]={ - category="lu", - direction="l", + [0x1EE0E]={ + category="lo", + direction="al", }, - [0x1D5E0]={ - category="lu", - direction="l", + [0x1EE0F]={ + category="lo", + direction="al", }, - [0x1D5E1]={ - category="lu", - direction="l", + [0x1EE10]={ + category="lo", + direction="al", }, - [0x1D5E2]={ - category="lu", - direction="l", + [0x1EE11]={ + category="lo", + direction="al", }, - [0x1D5E3]={ - category="lu", - direction="l", + [0x1EE12]={ + category="lo", + direction="al", }, - [0x1D5E4]={ - category="lu", - direction="l", + [0x1EE13]={ + category="lo", + direction="al", }, - [0x1D5E5]={ - category="lu", - direction="l", + [0x1EE14]={ + category="lo", + direction="al", }, - [0x1D5E6]={ - category="lu", - direction="l", + [0x1EE15]={ + category="lo", + direction="al", }, - [0x1D5E7]={ - category="lu", - direction="l", + [0x1EE16]={ + category="lo", + direction="al", }, - [0x1D5E8]={ - category="lu", - direction="l", + [0x1EE17]={ + category="lo", + direction="al", }, - [0x1D5E9]={ - category="lu", - direction="l", + [0x1EE18]={ + category="lo", + direction="al", }, - [0x1D5EA]={ - category="lu", - direction="l", + [0x1EE19]={ + category="lo", + direction="al", }, - [0x1D5EB]={ - category="lu", - direction="l", + [0x1EE1A]={ + category="lo", + direction="al", }, - [0x1D5EC]={ - category="lu", - direction="l", + [0x1EE1B]={ + category="lo", + direction="al", }, - [0x1D5ED]={ - category="lu", - direction="l", + [0x1EE1C]={ + category="lo", + direction="al", }, - [0x1D5EE]={ - category="ll", - direction="l", + [0x1EE1D]={ + category="lo", + direction="al", }, - [0x1D5EF]={ - category="ll", - direction="l", + [0x1EE1E]={ + category="lo", + direction="al", }, - [0x1D5F0]={ - category="ll", - direction="l", + [0x1EE1F]={ + category="lo", + direction="al", }, - [0x1D5F1]={ - category="ll", - direction="l", + [0x1EE21]={ + category="lo", + direction="al", }, - [0x1D5F2]={ - category="ll", - direction="l", + [0x1EE22]={ + category="lo", + direction="al", }, - [0x1D5F3]={ - category="ll", - direction="l", + [0x1EE24]={ + category="lo", + direction="al", }, - [0x1D5F4]={ - category="ll", - direction="l", + [0x1EE27]={ + category="lo", + direction="al", }, - [0x1D5F5]={ - category="ll", - direction="l", + [0x1EE29]={ + category="lo", + direction="al", }, - [0x1D5F6]={ - category="ll", - direction="l", + [0x1EE2A]={ + category="lo", + direction="al", }, - [0x1D5F7]={ - category="ll", - direction="l", + [0x1EE2B]={ + category="lo", + direction="al", }, - [0x1D5F8]={ - category="ll", - direction="l", + [0x1EE2C]={ + category="lo", + direction="al", }, - [0x1D5F9]={ - category="ll", - direction="l", + [0x1EE2D]={ + category="lo", + direction="al", }, - [0x1D5FA]={ - category="ll", - direction="l", + [0x1EE2E]={ + category="lo", + direction="al", }, - [0x1D5FB]={ - category="ll", - direction="l", + [0x1EE2F]={ + category="lo", + direction="al", }, - [0x1D5FC]={ - category="ll", - direction="l", + [0x1EE30]={ + category="lo", + direction="al", }, - [0x1D5FD]={ - category="ll", - direction="l", + [0x1EE31]={ + category="lo", + direction="al", }, - [0x1D5FE]={ - category="ll", - direction="l", + [0x1EE32]={ + category="lo", + direction="al", }, - [0x1D5FF]={ - category="ll", - direction="l", + [0x1EE34]={ + category="lo", + direction="al", }, - [0x1D600]={ - category="ll", - direction="l", + [0x1EE35]={ + category="lo", + direction="al", }, - [0x1D601]={ - category="ll", - direction="l", + [0x1EE36]={ + category="lo", + direction="al", }, - [0x1D602]={ - category="ll", - direction="l", + [0x1EE37]={ + category="lo", + direction="al", }, - [0x1D603]={ - category="ll", - direction="l", + [0x1EE39]={ + category="lo", + direction="al", }, - [0x1D604]={ - category="ll", - direction="l", + [0x1EE3B]={ + category="lo", + direction="al", }, - [0x1D605]={ - category="ll", - direction="l", + [0x1EE42]={ + category="lo", + direction="al", }, - [0x1D606]={ - category="ll", - direction="l", + [0x1EE47]={ + category="lo", + direction="al", }, - [0x1D607]={ - category="ll", - direction="l", + [0x1EE49]={ + category="lo", + direction="al", }, - [0x1D608]={ - category="lu", - direction="l", + [0x1EE4B]={ + category="lo", + direction="al", }, - [0x1D609]={ - category="lu", - direction="l", + [0x1EE4D]={ + category="lo", + direction="al", }, - [0x1D60A]={ - category="lu", - direction="l", + [0x1EE4E]={ + category="lo", + direction="al", }, - [0x1D60B]={ - category="lu", - direction="l", + [0x1EE4F]={ + category="lo", + direction="al", }, - [0x1D60C]={ - category="lu", - direction="l", + [0x1EE51]={ + category="lo", + direction="al", }, - [0x1D60D]={ - category="lu", - direction="l", + [0x1EE52]={ + category="lo", + direction="al", }, - [0x1D60E]={ - category="lu", - direction="l", + [0x1EE54]={ + category="lo", + direction="al", }, - [0x1D60F]={ - category="lu", - direction="l", + [0x1EE57]={ + category="lo", + direction="al", }, - [0x1D610]={ - category="lu", - direction="l", + [0x1EE59]={ + category="lo", + direction="al", }, - [0x1D611]={ - category="lu", - direction="l", + [0x1EE5B]={ + category="lo", + direction="al", }, - [0x1D612]={ - category="lu", - direction="l", + [0x1EE5D]={ + category="lo", + direction="al", }, - [0x1D613]={ - category="lu", - direction="l", + [0x1EE5F]={ + category="lo", + direction="al", }, - [0x1D614]={ - category="lu", - direction="l", + [0x1EE61]={ + category="lo", + direction="al", }, - [0x1D615]={ - category="lu", - direction="l", + [0x1EE62]={ + category="lo", + direction="al", }, - [0x1D616]={ - category="lu", - direction="l", + [0x1EE64]={ + category="lo", + direction="al", }, - [0x1D617]={ - category="lu", - direction="l", + [0x1EE67]={ + category="lo", + direction="al", }, - [0x1D618]={ - category="lu", - direction="l", + [0x1EE68]={ + category="lo", + direction="al", }, - [0x1D619]={ - category="lu", - direction="l", + [0x1EE69]={ + category="lo", + direction="al", }, - [0x1D61A]={ - category="lu", - direction="l", + [0x1EE6A]={ + category="lo", + direction="al", }, - [0x1D61B]={ - category="lu", - direction="l", + [0x1EE6C]={ + category="lo", + direction="al", }, - [0x1D61C]={ - category="lu", - direction="l", + [0x1EE6D]={ + category="lo", + direction="al", }, - [0x1D61D]={ - category="lu", - direction="l", + [0x1EE6E]={ + category="lo", + direction="al", }, - [0x1D61E]={ - category="lu", - direction="l", + [0x1EE6F]={ + category="lo", + direction="al", }, - [0x1D61F]={ - category="lu", - direction="l", + [0x1EE70]={ + category="lo", + direction="al", }, - [0x1D620]={ - category="lu", - direction="l", + [0x1EE71]={ + category="lo", + direction="al", }, - [0x1D621]={ - category="lu", - direction="l", + [0x1EE72]={ + category="lo", + direction="al", }, - [0x1D622]={ - category="ll", - direction="l", + [0x1EE74]={ + category="lo", + direction="al", }, - [0x1D623]={ - category="ll", - direction="l", + [0x1EE75]={ + category="lo", + direction="al", }, - [0x1D624]={ - category="ll", - direction="l", + [0x1EE76]={ + category="lo", + direction="al", }, - [0x1D625]={ - category="ll", - direction="l", + [0x1EE77]={ + category="lo", + direction="al", }, - [0x1D626]={ - category="ll", - direction="l", + [0x1EE79]={ + category="lo", + direction="al", }, - [0x1D627]={ - category="ll", - direction="l", + [0x1EE7A]={ + category="lo", + direction="al", }, - [0x1D628]={ - category="ll", - direction="l", + [0x1EE7B]={ + category="lo", + direction="al", }, - [0x1D629]={ - category="ll", - direction="l", + [0x1EE7C]={ + category="lo", + direction="al", }, - [0x1D62A]={ - category="ll", - direction="l", + [0x1EE7E]={ + category="lo", + direction="al", }, - [0x1D62B]={ - category="ll", - direction="l", + [0x1EE80]={ + category="lo", + direction="al", }, - [0x1D62C]={ - category="ll", - direction="l", + [0x1EE81]={ + category="lo", + direction="al", }, - [0x1D62D]={ - category="ll", - direction="l", + [0x1EE82]={ + category="lo", + direction="al", }, - [0x1D62E]={ - category="ll", - direction="l", + [0x1EE83]={ + category="lo", + direction="al", }, - [0x1D62F]={ - category="ll", - direction="l", + [0x1EE84]={ + category="lo", + direction="al", }, - [0x1D630]={ - category="ll", - direction="l", + [0x1EE85]={ + category="lo", + direction="al", }, - [0x1D631]={ - category="ll", - direction="l", + [0x1EE86]={ + category="lo", + direction="al", }, - [0x1D632]={ - category="ll", - direction="l", + [0x1EE87]={ + category="lo", + direction="al", }, - [0x1D633]={ - category="ll", - direction="l", + [0x1EE88]={ + category="lo", + direction="al", }, - [0x1D634]={ - category="ll", - direction="l", + [0x1EE89]={ + category="lo", + direction="al", }, - [0x1D635]={ - category="ll", - direction="l", + [0x1EE8B]={ + category="lo", + direction="al", }, - [0x1D636]={ - category="ll", - direction="l", + [0x1EE8C]={ + category="lo", + direction="al", }, - [0x1D637]={ - category="ll", - direction="l", + [0x1EE8D]={ + category="lo", + direction="al", }, - [0x1D638]={ - category="ll", - direction="l", + [0x1EE8E]={ + category="lo", + direction="al", }, - [0x1D639]={ - category="ll", - direction="l", + [0x1EE8F]={ + category="lo", + direction="al", }, - [0x1D63A]={ - category="ll", - direction="l", + [0x1EE90]={ + category="lo", + direction="al", }, - [0x1D63B]={ - category="ll", - direction="l", + [0x1EE91]={ + category="lo", + direction="al", }, - [0x1D63C]={ - category="lu", - direction="l", + [0x1EE92]={ + category="lo", + direction="al", }, - [0x1D63D]={ - category="lu", - direction="l", + [0x1EE93]={ + category="lo", + direction="al", }, - [0x1D63E]={ - category="lu", - direction="l", + [0x1EE94]={ + category="lo", + direction="al", }, - [0x1D63F]={ - category="lu", - direction="l", + [0x1EE95]={ + category="lo", + direction="al", }, - [0x1D640]={ - category="lu", - direction="l", + [0x1EE96]={ + category="lo", + direction="al", + }, + [0x1EE97]={ + category="lo", + direction="al", }, - [0x1D641]={ - category="lu", - direction="l", + [0x1EE98]={ + category="lo", + direction="al", }, - [0x1D642]={ - category="lu", - direction="l", + [0x1EE99]={ + category="lo", + direction="al", }, - [0x1D643]={ - category="lu", - direction="l", + [0x1EE9A]={ + category="lo", + direction="al", }, - [0x1D644]={ - category="lu", - direction="l", + [0x1EE9B]={ + category="lo", + direction="al", }, - [0x1D645]={ - category="lu", - direction="l", + [0x1EEA1]={ + category="lo", + direction="al", }, - [0x1D646]={ - category="lu", - direction="l", + [0x1EEA2]={ + category="lo", + direction="al", }, - [0x1D647]={ - category="lu", - direction="l", + [0x1EEA3]={ + category="lo", + direction="al", }, - [0x1D648]={ - category="lu", - direction="l", + [0x1EEA5]={ + category="lo", + direction="al", }, - [0x1D649]={ - category="lu", - direction="l", + [0x1EEA6]={ + category="lo", + direction="al", }, - [0x1D64A]={ - category="lu", - direction="l", + [0x1EEA7]={ + category="lo", + direction="al", }, - [0x1D64B]={ - category="lu", - direction="l", + [0x1EEA8]={ + category="lo", + direction="al", }, - [0x1D64C]={ - category="lu", - direction="l", + [0x1EEA9]={ + category="lo", + direction="al", }, - [0x1D64D]={ - category="lu", - direction="l", + [0x1EEAB]={ + category="lo", + direction="al", }, - [0x1D64E]={ - category="lu", - direction="l", + [0x1EEAC]={ + category="lo", + direction="al", }, - [0x1D64F]={ - category="lu", - direction="l", + [0x1EEAD]={ + category="lo", + direction="al", }, - [0x1D650]={ - category="lu", - direction="l", + [0x1EEAE]={ + category="lo", + direction="al", }, - [0x1D651]={ - category="lu", - direction="l", + [0x1EEAF]={ + category="lo", + direction="al", }, - [0x1D652]={ - category="lu", - direction="l", + [0x1EEB0]={ + category="lo", + direction="al", }, - [0x1D653]={ - category="lu", - direction="l", + [0x1EEB1]={ + category="lo", + direction="al", }, - [0x1D654]={ - category="lu", - direction="l", + [0x1EEB2]={ + category="lo", + direction="al", }, - [0x1D655]={ - category="lu", - direction="l", + [0x1EEB3]={ + category="lo", + direction="al", }, - [0x1D656]={ - category="ll", - direction="l", + [0x1EEB4]={ + category="lo", + direction="al", }, - [0x1D657]={ - category="ll", - direction="l", + [0x1EEB5]={ + category="lo", + direction="al", }, - [0x1D658]={ - category="ll", - direction="l", + [0x1EEB6]={ + category="lo", + direction="al", }, - [0x1D659]={ - category="ll", - direction="l", + [0x1EEB7]={ + category="lo", + direction="al", }, - [0x1D65A]={ - category="ll", - direction="l", + [0x1EEB8]={ + category="lo", + direction="al", }, - [0x1D65B]={ - category="ll", - direction="l", + [0x1EEB9]={ + category="lo", + direction="al", }, - [0x1D65C]={ - category="ll", - direction="l", + [0x1EEBA]={ + category="lo", + direction="al", }, - [0x1D65D]={ - category="ll", - direction="l", + [0x1EEBB]={ + category="lo", + direction="al", }, - [0x1D65E]={ - category="ll", - direction="l", + [0x1EEF0]={ + category="sm", + direction="on", }, - [0x1D65F]={ - category="ll", - direction="l", + [0x1EEF1]={ + category="sm", + direction="on", }, - [0x1D660]={ - category="ll", - direction="l", + [0x1F000]={ + category="so", + direction="on", }, - [0x1D661]={ - category="ll", - direction="l", + [0x1F001]={ + category="so", + direction="on", }, - [0x1D662]={ - category="ll", - direction="l", + [0x1F002]={ + category="so", + direction="on", }, - [0x1D663]={ - category="ll", - direction="l", + [0x1F003]={ + category="so", + direction="on", }, - [0x1D664]={ - category="ll", - direction="l", + [0x1F004]={ + category="so", + direction="on", }, - [0x1D665]={ - category="ll", - direction="l", + [0x1F005]={ + category="so", + direction="on", }, - [0x1D666]={ - category="ll", - direction="l", + [0x1F006]={ + category="so", + direction="on", }, - [0x1D667]={ - category="ll", - direction="l", + [0x1F007]={ + category="so", + direction="on", }, - [0x1D668]={ - category="ll", - direction="l", + [0x1F008]={ + category="so", + direction="on", }, - [0x1D669]={ - category="ll", - direction="l", + [0x1F009]={ + category="so", + direction="on", }, - [0x1D66A]={ - category="ll", - direction="l", + [0x1F00A]={ + category="so", + direction="on", }, - [0x1D66B]={ - category="ll", - direction="l", + [0x1F00B]={ + category="so", + direction="on", }, - [0x1D66C]={ - category="ll", - direction="l", + [0x1F00C]={ + category="so", + direction="on", }, - [0x1D66D]={ - category="ll", - direction="l", + [0x1F00D]={ + category="so", + direction="on", }, - [0x1D66E]={ - category="ll", - direction="l", + [0x1F00E]={ + category="so", + direction="on", }, - [0x1D66F]={ - category="ll", - direction="l", + [0x1F00F]={ + category="so", + direction="on", }, - [0x1D670]={ - category="lu", - direction="l", + [0x1F010]={ + category="so", + direction="on", }, - [0x1D671]={ - category="lu", - direction="l", + [0x1F011]={ + category="so", + direction="on", }, - [0x1D672]={ - category="lu", - direction="l", + [0x1F012]={ + category="so", + direction="on", }, - [0x1D673]={ - category="lu", - direction="l", + [0x1F013]={ + category="so", + direction="on", }, - [0x1D674]={ - category="lu", - direction="l", + [0x1F014]={ + category="so", + direction="on", }, - [0x1D675]={ - category="lu", - direction="l", + [0x1F015]={ + category="so", + direction="on", }, - [0x1D676]={ - category="lu", - direction="l", + [0x1F016]={ + category="so", + direction="on", }, - [0x1D677]={ - category="lu", - direction="l", + [0x1F017]={ + category="so", + direction="on", }, - [0x1D678]={ - category="lu", - direction="l", + [0x1F018]={ + category="so", + direction="on", }, - [0x1D679]={ - category="lu", - direction="l", + [0x1F019]={ + category="so", + direction="on", }, - [0x1D67A]={ - category="lu", - direction="l", + [0x1F01A]={ + category="so", + direction="on", }, - [0x1D67B]={ - category="lu", - direction="l", + [0x1F01B]={ + category="so", + direction="on", }, - [0x1D67C]={ - category="lu", - direction="l", + [0x1F01C]={ + category="so", + direction="on", }, - [0x1D67D]={ - category="lu", - direction="l", + [0x1F01D]={ + category="so", + direction="on", }, - [0x1D67E]={ - category="lu", - direction="l", + [0x1F01E]={ + category="so", + direction="on", }, - [0x1D67F]={ - category="lu", - direction="l", + [0x1F01F]={ + category="so", + direction="on", }, - [0x1D680]={ - category="lu", - direction="l", + [0x1F020]={ + category="so", + direction="on", }, - [0x1D681]={ - category="lu", - direction="l", + [0x1F021]={ + category="so", + direction="on", }, - [0x1D682]={ - category="lu", - direction="l", + [0x1F022]={ + category="so", + direction="on", }, - [0x1D683]={ - category="lu", - direction="l", + [0x1F023]={ + category="so", + direction="on", }, - [0x1D684]={ - category="lu", - direction="l", + [0x1F024]={ + category="so", + direction="on", }, - [0x1D685]={ - category="lu", - direction="l", + [0x1F025]={ + category="so", + direction="on", }, - [0x1D686]={ - category="lu", - direction="l", + [0x1F026]={ + category="so", + direction="on", }, - [0x1D687]={ - category="lu", - direction="l", + [0x1F027]={ + category="so", + direction="on", }, - [0x1D688]={ - category="lu", - direction="l", + [0x1F028]={ + category="so", + direction="on", }, - [0x1D689]={ - category="lu", - direction="l", + [0x1F029]={ + category="so", + direction="on", }, - [0x1D68A]={ - category="ll", - direction="l", + [0x1F02A]={ + category="so", + direction="on", }, - [0x1D68B]={ - category="ll", - direction="l", + [0x1F02B]={ + category="so", + direction="on", }, - [0x1D68C]={ - category="ll", - direction="l", + [0x1F030]={ + category="so", + direction="on", }, - [0x1D68D]={ - category="ll", - direction="l", + [0x1F031]={ + category="so", + direction="on", }, - [0x1D68E]={ - category="ll", - direction="l", + [0x1F032]={ + category="so", + direction="on", }, - [0x1D68F]={ - category="ll", - direction="l", + [0x1F033]={ + category="so", + direction="on", }, - [0x1D690]={ - category="ll", - direction="l", + [0x1F034]={ + category="so", + direction="on", }, - [0x1D691]={ - category="ll", - direction="l", + [0x1F035]={ + category="so", + direction="on", }, - [0x1D692]={ - category="ll", - direction="l", + [0x1F036]={ + category="so", + direction="on", }, - [0x1D693]={ - category="ll", - direction="l", + [0x1F037]={ + category="so", + direction="on", }, - [0x1D694]={ - category="ll", - direction="l", + [0x1F038]={ + category="so", + direction="on", }, - [0x1D695]={ - category="ll", - direction="l", + [0x1F039]={ + category="so", + direction="on", }, - [0x1D696]={ - category="ll", - direction="l", + [0x1F03A]={ + category="so", + direction="on", }, - [0x1D697]={ - category="ll", - direction="l", + [0x1F03B]={ + category="so", + direction="on", }, - [0x1D698]={ - category="ll", - direction="l", + [0x1F03C]={ + category="so", + direction="on", }, - [0x1D699]={ - category="ll", - direction="l", + [0x1F03D]={ + category="so", + direction="on", }, - [0x1D69A]={ - category="ll", - direction="l", + [0x1F03E]={ + category="so", + direction="on", }, - [0x1D69B]={ - category="ll", - direction="l", + [0x1F03F]={ + category="so", + direction="on", }, - [0x1D69C]={ - category="ll", - direction="l", + [0x1F040]={ + category="so", + direction="on", }, - [0x1D69D]={ - category="ll", - direction="l", + [0x1F041]={ + category="so", + direction="on", }, - [0x1D69E]={ - category="ll", - direction="l", + [0x1F042]={ + category="so", + direction="on", }, - [0x1D69F]={ - category="ll", - direction="l", + [0x1F043]={ + category="so", + direction="on", }, - [0x1D6A0]={ - category="ll", - direction="l", + [0x1F044]={ + category="so", + direction="on", }, - [0x1D6A1]={ - category="ll", - direction="l", + [0x1F045]={ + category="so", + direction="on", }, - [0x1D6A2]={ - category="ll", - direction="l", + [0x1F046]={ + category="so", + direction="on", }, - [0x1D6A3]={ - category="ll", - direction="l", + [0x1F047]={ + category="so", + direction="on", }, - [0x1D6A4]={ - category="ll", - direction="l", + [0x1F048]={ + category="so", + direction="on", }, - [0x1D6A5]={ - category="ll", - direction="l", + [0x1F049]={ + category="so", + direction="on", }, - [0x1D6A8]={ - category="lu", - direction="l", + [0x1F04A]={ + category="so", + direction="on", }, - [0x1D6A9]={ - category="lu", - direction="l", + [0x1F04B]={ + category="so", + direction="on", }, - [0x1D6AA]={ - category="lu", - direction="l", + [0x1F04C]={ + category="so", + direction="on", }, - [0x1D6AB]={ - category="lu", - direction="l", + [0x1F04D]={ + category="so", + direction="on", }, - [0x1D6AC]={ - category="lu", - direction="l", + [0x1F04E]={ + category="so", + direction="on", }, - [0x1D6AD]={ - category="lu", - direction="l", + [0x1F04F]={ + category="so", + direction="on", }, - [0x1D6AE]={ - category="lu", - direction="l", + [0x1F050]={ + category="so", + direction="on", }, - [0x1D6AF]={ - category="lu", - direction="l", + [0x1F051]={ + category="so", + direction="on", }, - [0x1D6B0]={ - category="lu", - direction="l", + [0x1F052]={ + category="so", + direction="on", }, - [0x1D6B1]={ - category="lu", - direction="l", + [0x1F053]={ + category="so", + direction="on", }, - [0x1D6B2]={ - category="lu", - direction="l", + [0x1F054]={ + category="so", + direction="on", }, - [0x1D6B3]={ - category="lu", - direction="l", + [0x1F055]={ + category="so", + direction="on", }, - [0x1D6B4]={ - category="lu", - direction="l", + [0x1F056]={ + category="so", + direction="on", }, - [0x1D6B5]={ - category="lu", - direction="l", + [0x1F057]={ + category="so", + direction="on", }, - [0x1D6B6]={ - category="lu", - direction="l", + [0x1F058]={ + category="so", + direction="on", }, - [0x1D6B7]={ - category="lu", - direction="l", + [0x1F059]={ + category="so", + direction="on", }, - [0x1D6B8]={ - category="lu", - direction="l", + [0x1F05A]={ + category="so", + direction="on", }, - [0x1D6B9]={ - category="lu", - direction="l", + [0x1F05B]={ + category="so", + direction="on", }, - [0x1D6BA]={ - category="lu", - direction="l", + [0x1F05C]={ + category="so", + direction="on", }, - [0x1D6BB]={ - category="lu", - direction="l", + [0x1F05D]={ + category="so", + direction="on", }, - [0x1D6BC]={ - category="lu", - direction="l", + [0x1F05E]={ + category="so", + direction="on", }, - [0x1D6BD]={ - category="lu", - direction="l", + [0x1F05F]={ + category="so", + direction="on", }, - [0x1D6BE]={ - category="lu", - direction="l", + [0x1F060]={ + category="so", + direction="on", }, - [0x1D6BF]={ - category="lu", - direction="l", + [0x1F061]={ + category="so", + direction="on", }, - [0x1D6C0]={ - category="lu", - direction="l", + [0x1F062]={ + category="so", + direction="on", }, - [0x1D6C1]={ - category="sm", - direction="l", + [0x1F063]={ + category="so", + direction="on", }, - [0x1D6C2]={ - category="ll", - direction="l", + [0x1F064]={ + category="so", + direction="on", }, - [0x1D6C3]={ - category="ll", - direction="l", + [0x1F065]={ + category="so", + direction="on", }, - [0x1D6C4]={ - category="ll", - direction="l", + [0x1F066]={ + category="so", + direction="on", }, - [0x1D6C5]={ - category="ll", - direction="l", + [0x1F067]={ + category="so", + direction="on", }, - [0x1D6C6]={ - category="ll", - direction="l", + [0x1F068]={ + category="so", + direction="on", }, - [0x1D6C7]={ - category="ll", - direction="l", + [0x1F069]={ + category="so", + direction="on", }, - [0x1D6C8]={ - category="ll", - direction="l", + [0x1F06A]={ + category="so", + direction="on", }, - [0x1D6C9]={ - category="ll", - direction="l", + [0x1F06B]={ + category="so", + direction="on", }, - [0x1D6CA]={ - category="ll", - direction="l", + [0x1F06C]={ + category="so", + direction="on", }, - [0x1D6CB]={ - category="ll", - direction="l", + [0x1F06D]={ + category="so", + direction="on", }, - [0x1D6CC]={ - category="ll", - direction="l", + [0x1F06E]={ + category="so", + direction="on", }, - [0x1D6CD]={ - category="ll", - direction="l", + [0x1F06F]={ + category="so", + direction="on", }, - [0x1D6CE]={ - category="ll", - direction="l", + [0x1F070]={ + category="so", + direction="on", }, - [0x1D6CF]={ - category="ll", - direction="l", + [0x1F071]={ + category="so", + direction="on", }, - [0x1D6D0]={ - category="ll", - direction="l", + [0x1F072]={ + category="so", + direction="on", }, - [0x1D6D1]={ - category="ll", - direction="l", + [0x1F073]={ + category="so", + direction="on", }, - [0x1D6D2]={ - category="ll", - direction="l", + [0x1F074]={ + category="so", + direction="on", }, - [0x1D6D3]={ - category="ll", - direction="l", + [0x1F075]={ + category="so", + direction="on", }, - [0x1D6D4]={ - category="ll", - direction="l", + [0x1F076]={ + category="so", + direction="on", }, - [0x1D6D5]={ - category="ll", - direction="l", + [0x1F077]={ + category="so", + direction="on", }, - [0x1D6D6]={ - category="ll", - direction="l", + [0x1F078]={ + category="so", + direction="on", }, - [0x1D6D7]={ - category="ll", - direction="l", + [0x1F079]={ + category="so", + direction="on", }, - [0x1D6D8]={ - category="ll", - direction="l", + [0x1F07A]={ + category="so", + direction="on", }, - [0x1D6D9]={ - category="ll", - direction="l", + [0x1F07B]={ + category="so", + direction="on", }, - [0x1D6DA]={ - category="ll", - direction="l", + [0x1F07C]={ + category="so", + direction="on", }, - [0x1D6DB]={ - category="sm", + [0x1F07D]={ + category="so", direction="on", }, - [0x1D6DC]={ - category="ll", - direction="l", + [0x1F07E]={ + category="so", + direction="on", }, - [0x1D6DD]={ - category="ll", - direction="l", + [0x1F07F]={ + category="so", + direction="on", }, - [0x1D6DE]={ - category="ll", - direction="l", + [0x1F080]={ + category="so", + direction="on", }, - [0x1D6DF]={ - category="ll", - direction="l", + [0x1F081]={ + category="so", + direction="on", }, - [0x1D6E0]={ - category="ll", - direction="l", + [0x1F082]={ + category="so", + direction="on", }, - [0x1D6E1]={ - category="ll", - direction="l", + [0x1F083]={ + category="so", + direction="on", }, - [0x1D6E2]={ - category="lu", - direction="l", + [0x1F084]={ + category="so", + direction="on", }, - [0x1D6E3]={ - category="lu", - direction="l", + [0x1F085]={ + category="so", + direction="on", }, - [0x1D6E4]={ - category="lu", - direction="l", + [0x1F086]={ + category="so", + direction="on", }, - [0x1D6E5]={ - category="lu", - direction="l", + [0x1F087]={ + category="so", + direction="on", }, - [0x1D6E6]={ - category="lu", - direction="l", + [0x1F088]={ + category="so", + direction="on", }, - [0x1D6E7]={ - category="lu", - direction="l", + [0x1F089]={ + category="so", + direction="on", }, - [0x1D6E8]={ - category="lu", - direction="l", + [0x1F08A]={ + category="so", + direction="on", }, - [0x1D6E9]={ - category="lu", - direction="l", + [0x1F08B]={ + category="so", + direction="on", }, - [0x1D6EA]={ - category="lu", - direction="l", + [0x1F08C]={ + category="so", + direction="on", }, - [0x1D6EB]={ - category="lu", - direction="l", + [0x1F08D]={ + category="so", + direction="on", }, - [0x1D6EC]={ - category="lu", - direction="l", + [0x1F08E]={ + category="so", + direction="on", + }, + [0x1F08F]={ + category="so", + direction="on", }, - [0x1D6ED]={ - category="lu", - direction="l", + [0x1F090]={ + category="so", + direction="on", }, - [0x1D6EE]={ - category="lu", - direction="l", + [0x1F091]={ + category="so", + direction="on", }, - [0x1D6EF]={ - category="lu", - direction="l", + [0x1F092]={ + category="so", + direction="on", }, - [0x1D6F0]={ - category="lu", - direction="l", + [0x1F093]={ + category="so", + direction="on", }, - [0x1D6F1]={ - category="lu", - direction="l", + [0x1F0A0]={ + category="so", + direction="on", }, - [0x1D6F2]={ - category="lu", - direction="l", + [0x1F0A1]={ + category="so", + direction="on", }, - [0x1D6F3]={ - category="lu", - direction="l", + [0x1F0A2]={ + category="so", + direction="on", }, - [0x1D6F4]={ - category="lu", - direction="l", + [0x1F0A3]={ + category="so", + direction="on", }, - [0x1D6F5]={ - category="lu", - direction="l", + [0x1F0A4]={ + category="so", + direction="on", }, - [0x1D6F6]={ - category="lu", - direction="l", + [0x1F0A5]={ + category="so", + direction="on", }, - [0x1D6F7]={ - category="lu", - direction="l", + [0x1F0A6]={ + category="so", + direction="on", }, - [0x1D6F8]={ - category="lu", - direction="l", + [0x1F0A7]={ + category="so", + direction="on", }, - [0x1D6F9]={ - category="lu", - direction="l", + [0x1F0A8]={ + category="so", + direction="on", }, - [0x1D6FA]={ - category="lu", - direction="l", + [0x1F0A9]={ + category="so", + direction="on", }, - [0x1D6FB]={ - category="sm", - direction="l", + [0x1F0AA]={ + category="so", + direction="on", }, - [0x1D6FC]={ - category="ll", - direction="l", + [0x1F0AB]={ + category="so", + direction="on", }, - [0x1D6FD]={ - category="ll", - direction="l", + [0x1F0AC]={ + category="so", + direction="on", }, - [0x1D6FE]={ - category="ll", - direction="l", + [0x1F0AD]={ + category="so", + direction="on", }, - [0x1D6FF]={ - category="ll", - direction="l", + [0x1F0AE]={ + category="so", + direction="on", }, - [0x1D700]={ - category="ll", - direction="l", + [0x1F0B1]={ + category="so", + direction="on", }, - [0x1D701]={ - category="ll", - direction="l", + [0x1F0B2]={ + category="so", + direction="on", }, - [0x1D702]={ - category="ll", - direction="l", + [0x1F0B3]={ + category="so", + direction="on", }, - [0x1D703]={ - category="ll", - direction="l", + [0x1F0B4]={ + category="so", + direction="on", }, - [0x1D704]={ - category="ll", - direction="l", + [0x1F0B5]={ + category="so", + direction="on", }, - [0x1D705]={ - category="ll", - direction="l", + [0x1F0B6]={ + category="so", + direction="on", }, - [0x1D706]={ - category="ll", - direction="l", + [0x1F0B7]={ + category="so", + direction="on", }, - [0x1D707]={ - category="ll", - direction="l", + [0x1F0B8]={ + category="so", + direction="on", }, - [0x1D708]={ - category="ll", - direction="l", + [0x1F0B9]={ + category="so", + direction="on", }, - [0x1D709]={ - category="ll", - direction="l", + [0x1F0BA]={ + category="so", + direction="on", }, - [0x1D70A]={ - category="ll", - direction="l", + [0x1F0BB]={ + category="so", + direction="on", }, - [0x1D70B]={ - category="ll", - direction="l", + [0x1F0BC]={ + category="so", + direction="on", }, - [0x1D70C]={ - category="ll", - direction="l", + [0x1F0BD]={ + category="so", + direction="on", }, - [0x1D70D]={ - category="ll", - direction="l", + [0x1F0BE]={ + category="so", + direction="on", }, - [0x1D70E]={ - category="ll", - direction="l", + [0x1F0BF]={ + category="so", + direction="on", }, - [0x1D70F]={ - category="ll", - direction="l", + [0x1F0C1]={ + category="so", + direction="on", }, - [0x1D710]={ - category="ll", - direction="l", + [0x1F0C2]={ + category="so", + direction="on", }, - [0x1D711]={ - category="ll", - direction="l", + [0x1F0C3]={ + category="so", + direction="on", }, - [0x1D712]={ - category="ll", - direction="l", + [0x1F0C4]={ + category="so", + direction="on", }, - [0x1D713]={ - category="ll", - direction="l", + [0x1F0C5]={ + category="so", + direction="on", }, - [0x1D714]={ - category="ll", - direction="l", + [0x1F0C6]={ + category="so", + direction="on", }, - [0x1D715]={ - category="sm", + [0x1F0C7]={ + category="so", direction="on", }, - [0x1D716]={ - category="ll", - direction="l", + [0x1F0C8]={ + category="so", + direction="on", }, - [0x1D717]={ - category="ll", - direction="l", + [0x1F0C9]={ + category="so", + direction="on", }, - [0x1D718]={ - category="ll", - direction="l", + [0x1F0CA]={ + category="so", + direction="on", }, - [0x1D719]={ - category="ll", - direction="l", + [0x1F0CB]={ + category="so", + direction="on", }, - [0x1D71A]={ - category="ll", - direction="l", + [0x1F0CC]={ + category="so", + direction="on", }, - [0x1D71B]={ - category="ll", - direction="l", + [0x1F0CD]={ + category="so", + direction="on", }, - [0x1D71C]={ - category="lu", - direction="l", + [0x1F0CE]={ + category="so", + direction="on", }, - [0x1D71D]={ - category="lu", - direction="l", + [0x1F0CF]={ + category="so", + direction="on", }, - [0x1D71E]={ - category="lu", - direction="l", + [0x1F0D1]={ + category="so", + direction="on", }, - [0x1D71F]={ - category="lu", - direction="l", + [0x1F0D2]={ + category="so", + direction="on", }, - [0x1D720]={ - category="lu", - direction="l", + [0x1F0D3]={ + category="so", + direction="on", }, - [0x1D721]={ - category="lu", - direction="l", + [0x1F0D4]={ + category="so", + direction="on", }, - [0x1D722]={ - category="lu", - direction="l", + [0x1F0D5]={ + category="so", + direction="on", }, - [0x1D723]={ - category="lu", - direction="l", + [0x1F0D6]={ + category="so", + direction="on", }, - [0x1D724]={ - category="lu", - direction="l", + [0x1F0D7]={ + category="so", + direction="on", }, - [0x1D725]={ - category="lu", - direction="l", + [0x1F0D8]={ + category="so", + direction="on", }, - [0x1D726]={ - category="lu", - direction="l", + [0x1F0D9]={ + category="so", + direction="on", }, - [0x1D727]={ - category="lu", - direction="l", + [0x1F0DA]={ + category="so", + direction="on", }, - [0x1D728]={ - category="lu", - direction="l", + [0x1F0DB]={ + category="so", + direction="on", }, - [0x1D729]={ - category="lu", - direction="l", + [0x1F0DC]={ + category="so", + direction="on", }, - [0x1D72A]={ - category="lu", - direction="l", + [0x1F0DD]={ + category="so", + direction="on", }, - [0x1D72B]={ - category="lu", - direction="l", + [0x1F0DE]={ + category="so", + direction="on", }, - [0x1D72C]={ - category="lu", - direction="l", + [0x1F0DF]={ + category="so", + direction="on", }, - [0x1D72D]={ - category="lu", - direction="l", + [0x1F0E0]={ + category="so", + direction="on", }, - [0x1D72E]={ - category="lu", - direction="l", + [0x1F0E1]={ + category="so", + direction="on", }, - [0x1D72F]={ - category="lu", - direction="l", + [0x1F0E2]={ + category="so", + direction="on", }, - [0x1D730]={ - category="lu", - direction="l", + [0x1F0E3]={ + category="so", + direction="on", }, - [0x1D731]={ - category="lu", - direction="l", + [0x1F0E4]={ + category="so", + direction="on", }, - [0x1D732]={ - category="lu", - direction="l", + [0x1F0E5]={ + category="so", + direction="on", }, - [0x1D733]={ - category="lu", - direction="l", + [0x1F0E6]={ + category="so", + direction="on", }, - [0x1D734]={ - category="lu", - direction="l", + [0x1F0E7]={ + category="so", + direction="on", }, - [0x1D735]={ - category="sm", - direction="l", + [0x1F0E8]={ + category="so", + direction="on", }, - [0x1D736]={ - category="ll", - direction="l", + [0x1F0E9]={ + category="so", + direction="on", }, - [0x1D737]={ - category="ll", - direction="l", + [0x1F0EA]={ + category="so", + direction="on", }, - [0x1D738]={ - category="ll", - direction="l", + [0x1F0EB]={ + category="so", + direction="on", }, - [0x1D739]={ - category="ll", - direction="l", + [0x1F0EC]={ + category="so", + direction="on", }, - [0x1D73A]={ - category="ll", - direction="l", + [0x1F0ED]={ + category="so", + direction="on", }, - [0x1D73B]={ - category="ll", - direction="l", + [0x1F0EE]={ + category="so", + direction="on", }, - [0x1D73C]={ - category="ll", - direction="l", + [0x1F0EF]={ + category="so", + direction="on", }, - [0x1D73D]={ - category="ll", - direction="l", + [0x1F0F0]={ + category="so", + direction="on", }, - [0x1D73E]={ - category="ll", - direction="l", + [0x1F0F1]={ + category="so", + direction="on", }, - [0x1D73F]={ - category="ll", - direction="l", + [0x1F0F2]={ + category="so", + direction="on", }, - [0x1D740]={ - category="ll", - direction="l", + [0x1F0F3]={ + category="so", + direction="on", }, - [0x1D741]={ - category="ll", - direction="l", + [0x1F0F4]={ + category="so", + direction="on", }, - [0x1D742]={ - category="ll", - direction="l", + [0x1F0F5]={ + category="so", + direction="on", }, - [0x1D743]={ - category="ll", - direction="l", + [0x1F100]={ + category="no", + direction="en", }, - [0x1D744]={ - category="ll", - direction="l", + [0x1F101]={ + category="no", + direction="en", }, - [0x1D745]={ - category="ll", - direction="l", + [0x1F102]={ + category="no", + direction="en", }, - [0x1D746]={ - category="ll", - direction="l", + [0x1F103]={ + category="no", + direction="en", }, - [0x1D747]={ - category="ll", - direction="l", + [0x1F104]={ + category="no", + direction="en", }, - [0x1D748]={ - category="ll", - direction="l", + [0x1F105]={ + category="no", + direction="en", }, - [0x1D749]={ - category="ll", - direction="l", + [0x1F106]={ + category="no", + direction="en", }, - [0x1D74A]={ - category="ll", - direction="l", + [0x1F107]={ + category="no", + direction="en", }, - [0x1D74B]={ - category="ll", - direction="l", + [0x1F108]={ + category="no", + direction="en", }, - [0x1D74C]={ - category="ll", - direction="l", + [0x1F109]={ + category="no", + direction="en", }, - [0x1D74D]={ - category="ll", - direction="l", + [0x1F10A]={ + category="no", + direction="en", }, - [0x1D74E]={ - category="ll", - direction="l", + [0x1F10B]={ + category="no", + direction="on", }, - [0x1D74F]={ - category="sm", + [0x1F10C]={ + category="no", direction="on", }, - [0x1D750]={ - category="ll", + [0x1F110]={ + category="so", direction="l", }, - [0x1D751]={ - category="ll", + [0x1F111]={ + category="so", direction="l", }, - [0x1D752]={ - category="ll", + [0x1F112]={ + category="so", direction="l", }, - [0x1D753]={ - category="ll", + [0x1F113]={ + category="so", direction="l", }, - [0x1D754]={ - category="ll", + [0x1F114]={ + category="so", direction="l", }, - [0x1D755]={ - category="ll", + [0x1F115]={ + category="so", direction="l", }, - [0x1D756]={ - category="lu", + [0x1F116]={ + category="so", direction="l", }, - [0x1D757]={ - category="lu", + [0x1F117]={ + category="so", direction="l", }, - [0x1D758]={ - category="lu", + [0x1F118]={ + category="so", direction="l", }, - [0x1D759]={ - category="lu", + [0x1F119]={ + category="so", direction="l", }, - [0x1D75A]={ - category="lu", + [0x1F11A]={ + category="so", direction="l", }, - [0x1D75B]={ - category="lu", + [0x1F11B]={ + category="so", direction="l", }, - [0x1D75C]={ - category="lu", + [0x1F11C]={ + category="so", direction="l", }, - [0x1D75D]={ - category="lu", + [0x1F11D]={ + category="so", direction="l", }, - [0x1D75E]={ - category="lu", + [0x1F11E]={ + category="so", direction="l", }, - [0x1D75F]={ - category="lu", + [0x1F11F]={ + category="so", direction="l", }, - [0x1D760]={ - category="lu", + [0x1F120]={ + category="so", direction="l", }, - [0x1D761]={ - category="lu", + [0x1F121]={ + category="so", direction="l", }, - [0x1D762]={ - category="lu", + [0x1F122]={ + category="so", direction="l", }, - [0x1D763]={ - category="lu", + [0x1F123]={ + category="so", direction="l", }, - [0x1D764]={ - category="lu", + [0x1F124]={ + category="so", direction="l", }, - [0x1D765]={ - category="lu", + [0x1F125]={ + category="so", direction="l", }, - [0x1D766]={ - category="lu", + [0x1F126]={ + category="so", direction="l", }, - [0x1D767]={ - category="lu", + [0x1F127]={ + category="so", direction="l", }, - [0x1D768]={ - category="lu", + [0x1F128]={ + category="so", direction="l", }, - [0x1D769]={ - category="lu", + [0x1F129]={ + category="so", direction="l", }, - [0x1D76A]={ - category="lu", + [0x1F12A]={ + category="so", direction="l", }, - [0x1D76B]={ - category="lu", + [0x1F12B]={ + category="so", direction="l", }, - [0x1D76C]={ - category="lu", + [0x1F12C]={ + category="so", direction="l", }, - [0x1D76D]={ - category="lu", + [0x1F12D]={ + category="so", direction="l", }, - [0x1D76E]={ - category="lu", + [0x1F12E]={ + category="so", direction="l", }, - [0x1D76F]={ - category="sm", + [0x1F130]={ + category="so", direction="l", }, - [0x1D770]={ - category="ll", + [0x1F131]={ + category="so", direction="l", }, - [0x1D771]={ - category="ll", + [0x1F132]={ + category="so", direction="l", }, - [0x1D772]={ - category="ll", + [0x1F133]={ + category="so", direction="l", }, - [0x1D773]={ - category="ll", + [0x1F134]={ + category="so", direction="l", }, - [0x1D774]={ - category="ll", + [0x1F135]={ + category="so", direction="l", }, - [0x1D775]={ - category="ll", + [0x1F136]={ + category="so", direction="l", }, - [0x1D776]={ - category="ll", + [0x1F137]={ + category="so", direction="l", }, - [0x1D777]={ - category="ll", + [0x1F138]={ + category="so", direction="l", }, - [0x1D778]={ - category="ll", + [0x1F139]={ + category="so", direction="l", }, - [0x1D779]={ - category="ll", + [0x1F13A]={ + category="so", direction="l", }, - [0x1D77A]={ - category="ll", + [0x1F13B]={ + category="so", direction="l", }, - [0x1D77B]={ - category="ll", + [0x1F13C]={ + category="so", direction="l", }, - [0x1D77C]={ - category="ll", + [0x1F13D]={ + category="so", direction="l", }, - [0x1D77D]={ - category="ll", + [0x1F13E]={ + category="so", direction="l", }, - [0x1D77E]={ - category="ll", + [0x1F13F]={ + category="so", direction="l", }, - [0x1D77F]={ - category="ll", + [0x1F140]={ + category="so", direction="l", }, - [0x1D780]={ - category="ll", + [0x1F141]={ + category="so", direction="l", }, - [0x1D781]={ - category="ll", + [0x1F142]={ + category="so", direction="l", }, - [0x1D782]={ - category="ll", + [0x1F143]={ + category="so", direction="l", }, - [0x1D783]={ - category="ll", + [0x1F144]={ + category="so", direction="l", }, - [0x1D784]={ - category="ll", + [0x1F145]={ + category="so", direction="l", }, - [0x1D785]={ - category="ll", + [0x1F146]={ + category="so", direction="l", }, - [0x1D786]={ - category="ll", + [0x1F147]={ + category="so", direction="l", }, - [0x1D787]={ - category="ll", + [0x1F148]={ + category="so", direction="l", }, - [0x1D788]={ - category="ll", + [0x1F149]={ + category="so", direction="l", }, - [0x1D789]={ - category="sm", - direction="on", - }, - [0x1D78A]={ - category="ll", + [0x1F14A]={ + category="so", direction="l", }, - [0x1D78B]={ - category="ll", + [0x1F14B]={ + category="so", direction="l", }, - [0x1D78C]={ - category="ll", + [0x1F14C]={ + category="so", direction="l", }, - [0x1D78D]={ - category="ll", + [0x1F14D]={ + category="so", direction="l", }, - [0x1D78E]={ - category="ll", + [0x1F14E]={ + category="so", direction="l", }, - [0x1D78F]={ - category="ll", + [0x1F14F]={ + category="so", direction="l", }, - [0x1D790]={ - category="lu", + [0x1F150]={ + category="so", direction="l", }, - [0x1D791]={ - category="lu", + [0x1F151]={ + category="so", direction="l", }, - [0x1D792]={ - category="lu", + [0x1F152]={ + category="so", direction="l", }, - [0x1D793]={ - category="lu", + [0x1F153]={ + category="so", direction="l", }, - [0x1D794]={ - category="lu", + [0x1F154]={ + category="so", direction="l", }, - [0x1D795]={ - category="lu", + [0x1F155]={ + category="so", direction="l", }, - [0x1D796]={ - category="lu", + [0x1F156]={ + category="so", direction="l", }, - [0x1D797]={ - category="lu", + [0x1F157]={ + category="so", direction="l", }, - [0x1D798]={ - category="lu", + [0x1F158]={ + category="so", direction="l", }, - [0x1D799]={ - category="lu", + [0x1F159]={ + category="so", direction="l", }, - [0x1D79A]={ - category="lu", + [0x1F15A]={ + category="so", direction="l", }, - [0x1D79B]={ - category="lu", + [0x1F15B]={ + category="so", direction="l", }, - [0x1D79C]={ - category="lu", + [0x1F15C]={ + category="so", direction="l", }, - [0x1D79D]={ - category="lu", + [0x1F15D]={ + category="so", direction="l", }, - [0x1D79E]={ - category="lu", + [0x1F15E]={ + category="so", direction="l", }, - [0x1D79F]={ - category="lu", + [0x1F15F]={ + category="so", direction="l", }, - [0x1D7A0]={ - category="lu", + [0x1F160]={ + category="so", direction="l", }, - [0x1D7A1]={ - category="lu", + [0x1F161]={ + category="so", direction="l", }, - [0x1D7A2]={ - category="lu", + [0x1F162]={ + category="so", direction="l", }, - [0x1D7A3]={ - category="lu", + [0x1F163]={ + category="so", direction="l", }, - [0x1D7A4]={ - category="lu", + [0x1F164]={ + category="so", direction="l", }, - [0x1D7A5]={ - category="lu", + [0x1F165]={ + category="so", direction="l", }, - [0x1D7A6]={ - category="lu", + [0x1F166]={ + category="so", direction="l", }, - [0x1D7A7]={ - category="lu", + [0x1F167]={ + category="so", direction="l", }, - [0x1D7A8]={ - category="lu", + [0x1F168]={ + category="so", direction="l", }, - [0x1D7A9]={ - category="sm", + [0x1F169]={ + category="so", direction="l", }, - [0x1D7AA]={ - category="ll", - direction="l", + [0x1F16A]={ + category="so", + direction="on", }, - [0x1D7AB]={ - category="ll", - direction="l", + [0x1F16B]={ + category="so", + direction="on", }, - [0x1D7AC]={ - category="ll", + [0x1F170]={ + category="so", direction="l", }, - [0x1D7AD]={ - category="ll", + [0x1F171]={ + category="so", direction="l", }, - [0x1D7AE]={ - category="ll", + [0x1F172]={ + category="so", direction="l", }, - [0x1D7AF]={ - category="ll", + [0x1F173]={ + category="so", direction="l", }, - [0x1D7B0]={ - category="ll", + [0x1F174]={ + category="so", direction="l", }, - [0x1D7B1]={ - category="ll", + [0x1F175]={ + category="so", direction="l", }, - [0x1D7B2]={ - category="ll", + [0x1F176]={ + category="so", direction="l", }, - [0x1D7B3]={ - category="ll", + [0x1F177]={ + category="so", direction="l", }, - [0x1D7B4]={ - category="ll", + [0x1F178]={ + category="so", direction="l", }, - [0x1D7B5]={ - category="ll", + [0x1F179]={ + category="so", direction="l", }, - [0x1D7B6]={ - category="ll", + [0x1F17A]={ + category="so", direction="l", }, - [0x1D7B7]={ - category="ll", + [0x1F17B]={ + category="so", direction="l", }, - [0x1D7B8]={ - category="ll", + [0x1F17C]={ + category="so", direction="l", }, - [0x1D7B9]={ - category="ll", + [0x1F17D]={ + category="so", direction="l", }, - [0x1D7BA]={ - category="ll", + [0x1F17E]={ + category="so", direction="l", }, - [0x1D7BB]={ - category="ll", + [0x1F17F]={ + category="so", direction="l", }, - [0x1D7BC]={ - category="ll", + [0x1F180]={ + category="so", direction="l", }, - [0x1D7BD]={ - category="ll", + [0x1F181]={ + category="so", direction="l", }, - [0x1D7BE]={ - category="ll", + [0x1F182]={ + category="so", direction="l", }, - [0x1D7BF]={ - category="ll", + [0x1F183]={ + category="so", direction="l", }, - [0x1D7C0]={ - category="ll", + [0x1F184]={ + category="so", direction="l", }, - [0x1D7C1]={ - category="ll", + [0x1F185]={ + category="so", direction="l", }, - [0x1D7C2]={ - category="ll", + [0x1F186]={ + category="so", direction="l", }, - [0x1D7C3]={ - category="sm", - direction="on", - }, - [0x1D7C4]={ - category="ll", + [0x1F187]={ + category="so", direction="l", }, - [0x1D7C5]={ - category="ll", + [0x1F188]={ + category="so", direction="l", }, - [0x1D7C6]={ - category="ll", + [0x1F189]={ + category="so", direction="l", }, - [0x1D7C7]={ - category="ll", + [0x1F18A]={ + category="so", direction="l", }, - [0x1D7C8]={ - category="ll", + [0x1F18B]={ + category="so", direction="l", }, - [0x1D7C9]={ - category="ll", + [0x1F18C]={ + category="so", direction="l", }, - [0x1D7CA]={ - category="lu", + [0x1F18D]={ + category="so", direction="l", }, - [0x1D7CB]={ - category="ll", + [0x1F18E]={ + category="so", direction="l", }, - [0x1D7CE]={ - category="nd", - direction="en", + [0x1F18F]={ + category="so", + direction="l", }, - [0x1D7CF]={ - category="nd", - direction="en", + [0x1F190]={ + category="so", + direction="l", }, - [0x1D7D0]={ - category="nd", - direction="en", + [0x1F191]={ + category="so", + direction="l", }, - [0x1D7D1]={ - category="nd", - direction="en", + [0x1F192]={ + category="so", + direction="l", }, - [0x1D7D2]={ - category="nd", - direction="en", + [0x1F193]={ + category="so", + direction="l", }, - [0x1D7D3]={ - category="nd", - direction="en", + [0x1F194]={ + category="so", + direction="l", }, - [0x1D7D4]={ - category="nd", - direction="en", + [0x1F195]={ + category="so", + direction="l", }, - [0x1D7D5]={ - category="nd", - direction="en", + [0x1F196]={ + category="so", + direction="l", }, - [0x1D7D6]={ - category="nd", - direction="en", + [0x1F197]={ + category="so", + direction="l", }, - [0x1D7D7]={ - category="nd", - direction="en", + [0x1F198]={ + category="so", + direction="l", }, - [0x1D7D8]={ - category="nd", - direction="en", + [0x1F199]={ + category="so", + direction="l", }, - [0x1D7D9]={ - category="nd", - direction="en", + [0x1F19A]={ + category="so", + direction="l", }, - [0x1D7DA]={ - category="nd", - direction="en", + [0x1F1E6]={ + category="so", + direction="l", }, - [0x1D7DB]={ - category="nd", - direction="en", + [0x1F1E7]={ + category="so", + direction="l", }, - [0x1D7DC]={ - category="nd", - direction="en", + [0x1F1E8]={ + category="so", + direction="l", }, - [0x1D7DD]={ - category="nd", - direction="en", + [0x1F1E9]={ + category="so", + direction="l", }, - [0x1D7DE]={ - category="nd", - direction="en", + [0x1F1EA]={ + category="so", + direction="l", }, - [0x1D7DF]={ - category="nd", - direction="en", + [0x1F1EB]={ + category="so", + direction="l", }, - [0x1D7E0]={ - category="nd", - direction="en", + [0x1F1EC]={ + category="so", + direction="l", }, - [0x1D7E1]={ - category="nd", - direction="en", + [0x1F1ED]={ + category="so", + direction="l", }, - [0x1D7E2]={ - category="nd", - direction="en", + [0x1F1EE]={ + category="so", + direction="l", }, - [0x1D7E3]={ - category="nd", - direction="en", + [0x1F1EF]={ + category="so", + direction="l", }, - [0x1D7E4]={ - category="nd", - direction="en", + [0x1F1F0]={ + category="so", + direction="l", }, - [0x1D7E5]={ - category="nd", - direction="en", + [0x1F1F1]={ + category="so", + direction="l", }, - [0x1D7E6]={ - category="nd", - direction="en", + [0x1F1F2]={ + category="so", + direction="l", }, - [0x1D7E7]={ - category="nd", - direction="en", + [0x1F1F3]={ + category="so", + direction="l", }, - [0x1D7E8]={ - category="nd", - direction="en", + [0x1F1F4]={ + category="so", + direction="l", }, - [0x1D7E9]={ - category="nd", - direction="en", + [0x1F1F5]={ + category="so", + direction="l", }, - [0x1D7EA]={ - category="nd", - direction="en", + [0x1F1F6]={ + category="so", + direction="l", }, - [0x1D7EB]={ - category="nd", - direction="en", + [0x1F1F7]={ + category="so", + direction="l", }, - [0x1D7EC]={ - category="nd", - direction="en", + [0x1F1F8]={ + category="so", + direction="l", }, - [0x1D7ED]={ - category="nd", - direction="en", + [0x1F1F9]={ + category="so", + direction="l", }, - [0x1D7EE]={ - category="nd", - direction="en", + [0x1F1FA]={ + category="so", + direction="l", }, - [0x1D7EF]={ - category="nd", - direction="en", + [0x1F1FB]={ + category="so", + direction="l", }, - [0x1D7F0]={ - category="nd", - direction="en", + [0x1F1FC]={ + category="so", + direction="l", }, - [0x1D7F1]={ - category="nd", - direction="en", + [0x1F1FD]={ + category="so", + direction="l", }, - [0x1D7F2]={ - category="nd", - direction="en", + [0x1F1FE]={ + category="so", + direction="l", }, - [0x1D7F3]={ - category="nd", - direction="en", + [0x1F1FF]={ + category="so", + direction="l", }, - [0x1D7F4]={ - category="nd", - direction="en", + [0x1F200]={ + category="so", + direction="l", }, - [0x1D7F5]={ - category="nd", - direction="en", + [0x1F201]={ + category="so", + direction="l", }, - [0x1D7F6]={ - category="nd", - direction="en", + [0x1F202]={ + category="so", + direction="l", }, - [0x1D7F7]={ - category="nd", - direction="en", + [0x1F210]={ + category="so", + direction="l", }, - [0x1D7F8]={ - category="nd", - direction="en", + [0x1F211]={ + category="so", + direction="l", }, - [0x1D7F9]={ - category="nd", - direction="en", + [0x1F212]={ + category="so", + direction="l", }, - [0x1D7FA]={ - category="nd", - direction="en", + [0x1F213]={ + category="so", + direction="l", }, - [0x1D7FB]={ - category="nd", - direction="en", + [0x1F214]={ + category="so", + direction="l", }, - [0x1D7FC]={ - category="nd", - direction="en", + [0x1F215]={ + category="so", + direction="l", }, - [0x1D7FD]={ - category="nd", - direction="en", + [0x1F216]={ + category="so", + direction="l", }, - [0x1D7FE]={ - category="nd", - direction="en", + [0x1F217]={ + category="so", + direction="l", }, - [0x1D7FF]={ - category="nd", - direction="en", + [0x1F218]={ + category="so", + direction="l", }, - [0x1EE00]={ - category="lo", - direction="al", + [0x1F219]={ + category="so", + direction="l", }, - [0x1EE01]={ - category="lo", - direction="al", + [0x1F21A]={ + category="so", + direction="l", }, - [0x1EE02]={ - category="lo", - direction="al", + [0x1F21B]={ + category="so", + direction="l", }, - [0x1EE03]={ - category="lo", - direction="al", + [0x1F21C]={ + category="so", + direction="l", }, - [0x1EE05]={ - category="lo", - direction="al", + [0x1F21D]={ + category="so", + direction="l", }, - [0x1EE06]={ - category="lo", - direction="al", + [0x1F21E]={ + category="so", + direction="l", }, - [0x1EE07]={ - category="lo", - direction="al", + [0x1F21F]={ + category="so", + direction="l", }, - [0x1EE08]={ - category="lo", - direction="al", + [0x1F220]={ + category="so", + direction="l", }, - [0x1EE09]={ - category="lo", - direction="al", + [0x1F221]={ + category="so", + direction="l", }, - [0x1EE0A]={ - category="lo", - direction="al", + [0x1F222]={ + category="so", + direction="l", }, - [0x1EE0B]={ - category="lo", - direction="al", + [0x1F223]={ + category="so", + direction="l", }, - [0x1EE0C]={ - category="lo", - direction="al", + [0x1F224]={ + category="so", + direction="l", }, - [0x1EE0D]={ - category="lo", - direction="al", + [0x1F225]={ + category="so", + direction="l", }, - [0x1EE0E]={ - category="lo", - direction="al", + [0x1F226]={ + category="so", + direction="l", }, - [0x1EE0F]={ - category="lo", - direction="al", + [0x1F227]={ + category="so", + direction="l", }, - [0x1EE10]={ - category="lo", - direction="al", + [0x1F228]={ + category="so", + direction="l", }, - [0x1EE11]={ - category="lo", - direction="al", + [0x1F229]={ + category="so", + direction="l", }, - [0x1EE12]={ - category="lo", - direction="al", + [0x1F22A]={ + category="so", + direction="l", }, - [0x1EE13]={ - category="lo", - direction="al", + [0x1F22B]={ + category="so", + direction="l", }, - [0x1EE14]={ - category="lo", - direction="al", + [0x1F22C]={ + category="so", + direction="l", }, - [0x1EE15]={ - category="lo", - direction="al", + [0x1F22D]={ + category="so", + direction="l", }, - [0x1EE16]={ - category="lo", - direction="al", + [0x1F22E]={ + category="so", + direction="l", }, - [0x1EE17]={ - category="lo", - direction="al", + [0x1F22F]={ + category="so", + direction="l", }, - [0x1EE18]={ - category="lo", - direction="al", + [0x1F230]={ + category="so", + direction="l", }, - [0x1EE19]={ - category="lo", - direction="al", + [0x1F231]={ + category="so", + direction="l", }, - [0x1EE1A]={ - category="lo", - direction="al", + [0x1F232]={ + category="so", + direction="l", }, - [0x1EE1B]={ - category="lo", - direction="al", + [0x1F233]={ + category="so", + direction="l", }, - [0x1EE1C]={ - category="lo", - direction="al", + [0x1F234]={ + category="so", + direction="l", }, - [0x1EE1D]={ - category="lo", - direction="al", + [0x1F235]={ + category="so", + direction="l", }, - [0x1EE1E]={ - category="lo", - direction="al", + [0x1F236]={ + category="so", + direction="l", }, - [0x1EE1F]={ - category="lo", - direction="al", + [0x1F237]={ + category="so", + direction="l", }, - [0x1EE21]={ - category="lo", - direction="al", + [0x1F238]={ + category="so", + direction="l", }, - [0x1EE22]={ - category="lo", - direction="al", + [0x1F239]={ + category="so", + direction="l", }, - [0x1EE24]={ - category="lo", - direction="al", + [0x1F23A]={ + category="so", + direction="l", }, - [0x1EE27]={ - category="lo", - direction="al", + [0x1F240]={ + category="so", + direction="l", }, - [0x1EE29]={ - category="lo", - direction="al", + [0x1F241]={ + category="so", + direction="l", }, - [0x1EE2A]={ - category="lo", - direction="al", + [0x1F242]={ + category="so", + direction="l", }, - [0x1EE2B]={ - category="lo", - direction="al", + [0x1F243]={ + category="so", + direction="l", }, - [0x1EE2C]={ - category="lo", - direction="al", + [0x1F244]={ + category="so", + direction="l", }, - [0x1EE2D]={ - category="lo", - direction="al", + [0x1F245]={ + category="so", + direction="l", }, - [0x1EE2E]={ - category="lo", - direction="al", + [0x1F246]={ + category="so", + direction="l", }, - [0x1EE2F]={ - category="lo", - direction="al", + [0x1F247]={ + category="so", + direction="l", }, - [0x1EE30]={ - category="lo", - direction="al", + [0x1F248]={ + category="so", + direction="l", }, - [0x1EE31]={ - category="lo", - direction="al", + [0x1F250]={ + category="so", + direction="l", }, - [0x1EE32]={ - category="lo", - direction="al", + [0x1F251]={ + category="so", + direction="l", }, - [0x1EE34]={ - category="lo", - direction="al", + [0x1F300]={ + category="so", + direction="on", }, - [0x1EE35]={ - category="lo", - direction="al", + [0x1F301]={ + category="so", + direction="on", }, - [0x1EE36]={ - category="lo", - direction="al", + [0x1F302]={ + category="so", + direction="on", }, - [0x1EE37]={ - category="lo", - direction="al", + [0x1F303]={ + category="so", + direction="on", }, - [0x1EE39]={ - category="lo", - direction="al", + [0x1F304]={ + category="so", + direction="on", }, - [0x1EE3B]={ - category="lo", - direction="al", + [0x1F305]={ + category="so", + direction="on", }, - [0x1EE42]={ - category="lo", - direction="al", + [0x1F306]={ + category="so", + direction="on", }, - [0x1EE47]={ - category="lo", - direction="al", + [0x1F307]={ + category="so", + direction="on", }, - [0x1EE49]={ - category="lo", - direction="al", + [0x1F308]={ + category="so", + direction="on", }, - [0x1EE4B]={ - category="lo", - direction="al", + [0x1F309]={ + category="so", + direction="on", }, - [0x1EE4D]={ - category="lo", - direction="al", + [0x1F30A]={ + category="so", + direction="on", }, - [0x1EE4E]={ - category="lo", - direction="al", + [0x1F30B]={ + category="so", + direction="on", }, - [0x1EE4F]={ - category="lo", - direction="al", + [0x1F30C]={ + category="so", + direction="on", }, - [0x1EE51]={ - category="lo", - direction="al", + [0x1F30D]={ + category="so", + direction="on", }, - [0x1EE52]={ - category="lo", - direction="al", + [0x1F30E]={ + category="so", + direction="on", }, - [0x1EE54]={ - category="lo", - direction="al", + [0x1F30F]={ + category="so", + direction="on", }, - [0x1EE57]={ - category="lo", - direction="al", + [0x1F310]={ + category="so", + direction="on", }, - [0x1EE59]={ - category="lo", - direction="al", + [0x1F311]={ + category="so", + direction="on", }, - [0x1EE5B]={ - category="lo", - direction="al", + [0x1F312]={ + category="so", + direction="on", }, - [0x1EE5D]={ - category="lo", - direction="al", + [0x1F313]={ + category="so", + direction="on", }, - [0x1EE5F]={ - category="lo", - direction="al", + [0x1F314]={ + category="so", + direction="on", }, - [0x1EE61]={ - category="lo", - direction="al", + [0x1F315]={ + category="so", + direction="on", }, - [0x1EE62]={ - category="lo", - direction="al", + [0x1F316]={ + category="so", + direction="on", }, - [0x1EE64]={ - category="lo", - direction="al", + [0x1F317]={ + category="so", + direction="on", }, - [0x1EE67]={ - category="lo", - direction="al", + [0x1F318]={ + category="so", + direction="on", }, - [0x1EE68]={ - category="lo", - direction="al", + [0x1F319]={ + category="so", + direction="on", }, - [0x1EE69]={ - category="lo", - direction="al", + [0x1F31A]={ + category="so", + direction="on", }, - [0x1EE6A]={ - category="lo", - direction="al", + [0x1F31B]={ + category="so", + direction="on", }, - [0x1EE6C]={ - category="lo", - direction="al", + [0x1F31C]={ + category="so", + direction="on", }, - [0x1EE6D]={ - category="lo", - direction="al", + [0x1F31D]={ + category="so", + direction="on", }, - [0x1EE6E]={ - category="lo", - direction="al", + [0x1F31E]={ + category="so", + direction="on", }, - [0x1EE6F]={ - category="lo", - direction="al", + [0x1F31F]={ + category="so", + direction="on", }, - [0x1EE70]={ - category="lo", - direction="al", + [0x1F320]={ + category="so", + direction="on", }, - [0x1EE71]={ - category="lo", - direction="al", + [0x1F321]={ + category="so", + direction="on", }, - [0x1EE72]={ - category="lo", - direction="al", + [0x1F322]={ + category="so", + direction="on", }, - [0x1EE74]={ - category="lo", - direction="al", + [0x1F323]={ + category="so", + direction="on", }, - [0x1EE75]={ - category="lo", - direction="al", + [0x1F324]={ + category="so", + direction="on", }, - [0x1EE76]={ - category="lo", - direction="al", + [0x1F325]={ + category="so", + direction="on", }, - [0x1EE77]={ - category="lo", - direction="al", + [0x1F326]={ + category="so", + direction="on", }, - [0x1EE79]={ - category="lo", - direction="al", + [0x1F327]={ + category="so", + direction="on", }, - [0x1EE7A]={ - category="lo", - direction="al", + [0x1F328]={ + category="so", + direction="on", }, - [0x1EE7B]={ - category="lo", - direction="al", + [0x1F329]={ + category="so", + direction="on", }, - [0x1EE7C]={ - category="lo", - direction="al", + [0x1F32A]={ + category="so", + direction="on", }, - [0x1EE7E]={ - category="lo", - direction="al", + [0x1F32B]={ + category="so", + direction="on", }, - [0x1EE80]={ - category="lo", - direction="al", + [0x1F32C]={ + category="so", + direction="on", }, - [0x1EE81]={ - category="lo", - direction="al", + [0x1F330]={ + category="so", + direction="on", }, - [0x1EE82]={ - category="lo", - direction="al", + [0x1F331]={ + category="so", + direction="on", }, - [0x1EE83]={ - category="lo", - direction="al", + [0x1F332]={ + category="so", + direction="on", }, - [0x1EE84]={ - category="lo", - direction="al", + [0x1F333]={ + category="so", + direction="on", }, - [0x1EE85]={ - category="lo", - direction="al", + [0x1F334]={ + category="so", + direction="on", }, - [0x1EE86]={ - category="lo", - direction="al", + [0x1F335]={ + category="so", + direction="on", }, - [0x1EE87]={ - category="lo", - direction="al", + [0x1F336]={ + category="so", + direction="on", }, - [0x1EE88]={ - category="lo", - direction="al", + [0x1F337]={ + category="so", + direction="on", }, - [0x1EE89]={ - category="lo", - direction="al", + [0x1F338]={ + category="so", + direction="on", }, - [0x1EE8B]={ - category="lo", - direction="al", + [0x1F339]={ + category="so", + direction="on", }, - [0x1EE8C]={ - category="lo", - direction="al", + [0x1F33A]={ + category="so", + direction="on", }, - [0x1EE8D]={ - category="lo", - direction="al", + [0x1F33B]={ + category="so", + direction="on", }, - [0x1EE8E]={ - category="lo", - direction="al", + [0x1F33C]={ + category="so", + direction="on", }, - [0x1EE8F]={ - category="lo", - direction="al", + [0x1F33D]={ + category="so", + direction="on", }, - [0x1EE90]={ - category="lo", - direction="al", + [0x1F33E]={ + category="so", + direction="on", }, - [0x1EE91]={ - category="lo", - direction="al", + [0x1F33F]={ + category="so", + direction="on", }, - [0x1EE92]={ - category="lo", - direction="al", + [0x1F340]={ + category="so", + direction="on", }, - [0x1EE93]={ - category="lo", - direction="al", + [0x1F341]={ + category="so", + direction="on", }, - [0x1EE94]={ - category="lo", - direction="al", + [0x1F342]={ + category="so", + direction="on", }, - [0x1EE95]={ - category="lo", - direction="al", + [0x1F343]={ + category="so", + direction="on", }, - [0x1EE96]={ - category="lo", - direction="al", + [0x1F344]={ + category="so", + direction="on", }, - [0x1EE97]={ - category="lo", - direction="al", + [0x1F345]={ + category="so", + direction="on", }, - [0x1EE98]={ - category="lo", - direction="al", + [0x1F346]={ + category="so", + direction="on", }, - [0x1EE99]={ - category="lo", - direction="al", + [0x1F347]={ + category="so", + direction="on", }, - [0x1EE9A]={ - category="lo", - direction="al", + [0x1F348]={ + category="so", + direction="on", }, - [0x1EE9B]={ - category="lo", - direction="al", + [0x1F349]={ + category="so", + direction="on", }, - [0x1EEA1]={ - category="lo", - direction="al", + [0x1F34A]={ + category="so", + direction="on", }, - [0x1EEA2]={ - category="lo", - direction="al", + [0x1F34B]={ + category="so", + direction="on", }, - [0x1EEA3]={ - category="lo", - direction="al", + [0x1F34C]={ + category="so", + direction="on", }, - [0x1EEA5]={ - category="lo", - direction="al", + [0x1F34D]={ + category="so", + direction="on", }, - [0x1EEA6]={ - category="lo", - direction="al", + [0x1F34E]={ + category="so", + direction="on", }, - [0x1EEA7]={ - category="lo", - direction="al", + [0x1F34F]={ + category="so", + direction="on", }, - [0x1EEA8]={ - category="lo", - direction="al", + [0x1F350]={ + category="so", + direction="on", }, - [0x1EEA9]={ - category="lo", - direction="al", + [0x1F351]={ + category="so", + direction="on", }, - [0x1EEAB]={ - category="lo", - direction="al", + [0x1F352]={ + category="so", + direction="on", }, - [0x1EEAC]={ - category="lo", - direction="al", + [0x1F353]={ + category="so", + direction="on", }, - [0x1EEAD]={ - category="lo", - direction="al", + [0x1F354]={ + category="so", + direction="on", }, - [0x1EEAE]={ - category="lo", - direction="al", + [0x1F355]={ + category="so", + direction="on", }, - [0x1EEAF]={ - category="lo", - direction="al", + [0x1F356]={ + category="so", + direction="on", }, - [0x1EEB0]={ - category="lo", - direction="al", + [0x1F357]={ + category="so", + direction="on", }, - [0x1EEB1]={ - category="lo", - direction="al", + [0x1F358]={ + category="so", + direction="on", }, - [0x1EEB2]={ - category="lo", - direction="al", + [0x1F359]={ + category="so", + direction="on", }, - [0x1EEB3]={ - category="lo", - direction="al", + [0x1F35A]={ + category="so", + direction="on", }, - [0x1EEB4]={ - category="lo", - direction="al", + [0x1F35B]={ + category="so", + direction="on", }, - [0x1EEB5]={ - category="lo", - direction="al", + [0x1F35C]={ + category="so", + direction="on", }, - [0x1EEB6]={ - category="lo", - direction="al", + [0x1F35D]={ + category="so", + direction="on", }, - [0x1EEB7]={ - category="lo", - direction="al", + [0x1F35E]={ + category="so", + direction="on", }, - [0x1EEB8]={ - category="lo", - direction="al", + [0x1F35F]={ + category="so", + direction="on", }, - [0x1EEB9]={ - category="lo", - direction="al", + [0x1F360]={ + category="so", + direction="on", }, - [0x1EEBA]={ - category="lo", - direction="al", + [0x1F361]={ + category="so", + direction="on", }, - [0x1EEBB]={ - category="lo", - direction="al", + [0x1F362]={ + category="so", + direction="on", }, - [0x1EEF0]={ - category="sm", + [0x1F363]={ + category="so", direction="on", }, - [0x1EEF1]={ - category="sm", + [0x1F364]={ + category="so", direction="on", }, - [0x1F000]={ + [0x1F365]={ category="so", direction="on", }, - [0x1F001]={ + [0x1F366]={ category="so", direction="on", }, - [0x1F002]={ + [0x1F367]={ category="so", direction="on", }, - [0x1F003]={ + [0x1F368]={ category="so", direction="on", }, - [0x1F004]={ + [0x1F369]={ category="so", direction="on", }, - [0x1F005]={ + [0x1F36A]={ category="so", direction="on", }, - [0x1F006]={ + [0x1F36B]={ category="so", direction="on", }, - [0x1F007]={ + [0x1F36C]={ category="so", direction="on", }, - [0x1F008]={ + [0x1F36D]={ category="so", direction="on", }, - [0x1F009]={ + [0x1F36E]={ category="so", direction="on", }, - [0x1F00A]={ + [0x1F36F]={ category="so", direction="on", }, - [0x1F00B]={ + [0x1F370]={ category="so", direction="on", }, - [0x1F00C]={ + [0x1F371]={ category="so", direction="on", }, - [0x1F00D]={ + [0x1F372]={ category="so", direction="on", }, - [0x1F00E]={ + [0x1F373]={ category="so", direction="on", }, - [0x1F00F]={ + [0x1F374]={ category="so", direction="on", }, - [0x1F010]={ + [0x1F375]={ category="so", direction="on", }, - [0x1F011]={ + [0x1F376]={ category="so", direction="on", }, - [0x1F012]={ + [0x1F377]={ category="so", direction="on", }, - [0x1F013]={ + [0x1F378]={ category="so", direction="on", }, - [0x1F014]={ + [0x1F379]={ category="so", direction="on", }, - [0x1F015]={ + [0x1F37A]={ category="so", direction="on", }, - [0x1F016]={ + [0x1F37B]={ category="so", direction="on", }, - [0x1F017]={ + [0x1F37C]={ category="so", direction="on", }, - [0x1F018]={ + [0x1F37D]={ category="so", direction="on", }, - [0x1F019]={ + [0x1F380]={ category="so", direction="on", }, - [0x1F01A]={ + [0x1F381]={ category="so", direction="on", }, - [0x1F01B]={ + [0x1F382]={ category="so", direction="on", }, - [0x1F01C]={ + [0x1F383]={ category="so", direction="on", }, - [0x1F01D]={ + [0x1F384]={ category="so", direction="on", }, - [0x1F01E]={ + [0x1F385]={ category="so", direction="on", }, - [0x1F01F]={ + [0x1F386]={ category="so", direction="on", }, - [0x1F020]={ + [0x1F387]={ category="so", direction="on", }, - [0x1F021]={ + [0x1F388]={ category="so", direction="on", }, - [0x1F022]={ + [0x1F389]={ category="so", direction="on", }, - [0x1F023]={ + [0x1F38A]={ category="so", direction="on", }, - [0x1F024]={ + [0x1F38B]={ category="so", direction="on", }, - [0x1F025]={ + [0x1F38C]={ category="so", direction="on", }, - [0x1F026]={ + [0x1F38D]={ category="so", direction="on", }, - [0x1F027]={ + [0x1F38E]={ category="so", direction="on", }, - [0x1F028]={ + [0x1F38F]={ category="so", direction="on", }, - [0x1F029]={ + [0x1F390]={ category="so", direction="on", }, - [0x1F02A]={ + [0x1F391]={ category="so", direction="on", }, - [0x1F02B]={ + [0x1F392]={ category="so", direction="on", }, - [0x1F030]={ + [0x1F393]={ category="so", direction="on", }, - [0x1F031]={ + [0x1F394]={ category="so", direction="on", }, - [0x1F032]={ + [0x1F395]={ category="so", direction="on", }, - [0x1F033]={ + [0x1F396]={ category="so", direction="on", }, - [0x1F034]={ + [0x1F397]={ category="so", direction="on", }, - [0x1F035]={ + [0x1F398]={ category="so", direction="on", }, - [0x1F036]={ + [0x1F399]={ category="so", direction="on", }, - [0x1F037]={ + [0x1F39A]={ category="so", direction="on", }, - [0x1F038]={ + [0x1F39B]={ category="so", direction="on", }, - [0x1F039]={ + [0x1F39C]={ category="so", direction="on", }, - [0x1F03A]={ + [0x1F39D]={ category="so", direction="on", }, - [0x1F03B]={ + [0x1F39E]={ category="so", direction="on", }, - [0x1F03C]={ + [0x1F39F]={ category="so", direction="on", }, - [0x1F03D]={ + [0x1F3A0]={ category="so", direction="on", }, - [0x1F03E]={ + [0x1F3A1]={ category="so", direction="on", }, - [0x1F03F]={ + [0x1F3A2]={ category="so", direction="on", }, - [0x1F040]={ + [0x1F3A3]={ category="so", direction="on", }, - [0x1F041]={ + [0x1F3A4]={ category="so", direction="on", }, - [0x1F042]={ + [0x1F3A5]={ category="so", direction="on", }, - [0x1F043]={ + [0x1F3A6]={ category="so", direction="on", }, - [0x1F044]={ + [0x1F3A7]={ category="so", direction="on", }, - [0x1F045]={ + [0x1F3A8]={ category="so", direction="on", }, - [0x1F046]={ + [0x1F3A9]={ category="so", direction="on", }, - [0x1F047]={ + [0x1F3AA]={ category="so", direction="on", }, - [0x1F048]={ + [0x1F3AB]={ category="so", direction="on", }, - [0x1F049]={ + [0x1F3AC]={ category="so", direction="on", }, - [0x1F04A]={ + [0x1F3AD]={ category="so", direction="on", }, - [0x1F04B]={ + [0x1F3AE]={ category="so", direction="on", }, - [0x1F04C]={ + [0x1F3AF]={ category="so", direction="on", }, - [0x1F04D]={ + [0x1F3B0]={ category="so", direction="on", }, - [0x1F04E]={ + [0x1F3B1]={ category="so", direction="on", }, - [0x1F04F]={ + [0x1F3B2]={ category="so", direction="on", }, - [0x1F050]={ + [0x1F3B3]={ category="so", direction="on", }, - [0x1F051]={ + [0x1F3B4]={ category="so", direction="on", }, - [0x1F052]={ + [0x1F3B5]={ category="so", direction="on", }, - [0x1F053]={ + [0x1F3B6]={ category="so", direction="on", }, - [0x1F054]={ + [0x1F3B7]={ category="so", direction="on", }, - [0x1F055]={ + [0x1F3B8]={ category="so", direction="on", }, - [0x1F056]={ + [0x1F3B9]={ category="so", direction="on", }, - [0x1F057]={ + [0x1F3BA]={ category="so", direction="on", }, - [0x1F058]={ + [0x1F3BB]={ category="so", direction="on", }, - [0x1F059]={ + [0x1F3BC]={ category="so", direction="on", }, - [0x1F05A]={ + [0x1F3BD]={ category="so", direction="on", }, - [0x1F05B]={ + [0x1F3BE]={ category="so", direction="on", }, - [0x1F05C]={ + [0x1F3BF]={ category="so", direction="on", }, - [0x1F05D]={ + [0x1F3C0]={ category="so", direction="on", }, - [0x1F05E]={ + [0x1F3C1]={ category="so", direction="on", }, - [0x1F05F]={ + [0x1F3C2]={ category="so", direction="on", }, - [0x1F060]={ + [0x1F3C3]={ category="so", direction="on", }, - [0x1F061]={ + [0x1F3C4]={ category="so", direction="on", }, - [0x1F062]={ + [0x1F3C5]={ category="so", direction="on", }, - [0x1F063]={ + [0x1F3C6]={ category="so", direction="on", }, - [0x1F064]={ + [0x1F3C7]={ category="so", direction="on", }, - [0x1F065]={ + [0x1F3C8]={ category="so", direction="on", }, - [0x1F066]={ + [0x1F3C9]={ category="so", direction="on", }, - [0x1F067]={ + [0x1F3CA]={ category="so", direction="on", }, - [0x1F068]={ + [0x1F3CB]={ category="so", direction="on", }, - [0x1F069]={ + [0x1F3CC]={ category="so", direction="on", }, - [0x1F06A]={ + [0x1F3CD]={ category="so", direction="on", }, - [0x1F06B]={ + [0x1F3CE]={ category="so", direction="on", }, - [0x1F06C]={ + [0x1F3D4]={ category="so", direction="on", }, - [0x1F06D]={ + [0x1F3D5]={ category="so", direction="on", }, - [0x1F06E]={ + [0x1F3D6]={ category="so", direction="on", }, - [0x1F06F]={ + [0x1F3D7]={ category="so", direction="on", }, - [0x1F070]={ + [0x1F3D8]={ category="so", direction="on", }, - [0x1F071]={ + [0x1F3D9]={ category="so", direction="on", }, - [0x1F072]={ + [0x1F3DA]={ category="so", direction="on", }, - [0x1F073]={ + [0x1F3DB]={ category="so", direction="on", }, - [0x1F074]={ + [0x1F3DC]={ category="so", direction="on", }, - [0x1F075]={ + [0x1F3DD]={ category="so", direction="on", }, - [0x1F076]={ + [0x1F3DE]={ category="so", direction="on", }, - [0x1F077]={ + [0x1F3DF]={ category="so", direction="on", }, - [0x1F078]={ + [0x1F3E0]={ category="so", direction="on", }, - [0x1F079]={ + [0x1F3E1]={ category="so", direction="on", }, - [0x1F07A]={ + [0x1F3E2]={ category="so", direction="on", }, - [0x1F07B]={ + [0x1F3E3]={ category="so", direction="on", }, - [0x1F07C]={ + [0x1F3E4]={ category="so", direction="on", }, - [0x1F07D]={ + [0x1F3E5]={ category="so", direction="on", }, - [0x1F07E]={ + [0x1F3E6]={ category="so", direction="on", }, - [0x1F07F]={ + [0x1F3E7]={ category="so", direction="on", }, - [0x1F080]={ + [0x1F3E8]={ category="so", direction="on", }, - [0x1F081]={ + [0x1F3E9]={ category="so", direction="on", }, - [0x1F082]={ + [0x1F3EA]={ category="so", direction="on", }, - [0x1F083]={ + [0x1F3EB]={ category="so", direction="on", }, - [0x1F084]={ + [0x1F3EC]={ category="so", direction="on", }, - [0x1F085]={ + [0x1F3ED]={ category="so", direction="on", }, - [0x1F086]={ + [0x1F3EE]={ category="so", direction="on", }, - [0x1F087]={ + [0x1F3EF]={ category="so", direction="on", }, - [0x1F088]={ + [0x1F3F0]={ category="so", direction="on", }, - [0x1F089]={ + [0x1F3F1]={ category="so", direction="on", }, - [0x1F08A]={ + [0x1F3F2]={ category="so", direction="on", }, - [0x1F08B]={ + [0x1F3F3]={ category="so", direction="on", }, - [0x1F08C]={ + [0x1F3F4]={ category="so", direction="on", }, - [0x1F08D]={ + [0x1F3F5]={ category="so", direction="on", }, - [0x1F08E]={ + [0x1F3F6]={ category="so", direction="on", }, - [0x1F08F]={ + [0x1F3F7]={ category="so", direction="on", }, - [0x1F090]={ + [0x1F400]={ category="so", direction="on", }, - [0x1F091]={ + [0x1F401]={ category="so", direction="on", }, - [0x1F092]={ + [0x1F402]={ category="so", direction="on", }, - [0x1F093]={ + [0x1F403]={ category="so", direction="on", }, - [0x1F0A0]={ + [0x1F404]={ category="so", direction="on", }, - [0x1F0A1]={ + [0x1F405]={ category="so", direction="on", }, - [0x1F0A2]={ + [0x1F406]={ category="so", direction="on", }, - [0x1F0A3]={ + [0x1F407]={ category="so", direction="on", }, - [0x1F0A4]={ + [0x1F408]={ category="so", direction="on", }, - [0x1F0A5]={ + [0x1F409]={ category="so", direction="on", }, - [0x1F0A6]={ + [0x1F40A]={ category="so", direction="on", }, - [0x1F0A7]={ + [0x1F40B]={ category="so", direction="on", }, - [0x1F0A8]={ + [0x1F40C]={ category="so", direction="on", }, - [0x1F0A9]={ + [0x1F40D]={ category="so", direction="on", }, - [0x1F0AA]={ + [0x1F40E]={ category="so", direction="on", }, - [0x1F0AB]={ + [0x1F40F]={ category="so", direction="on", }, - [0x1F0AC]={ + [0x1F410]={ category="so", direction="on", }, - [0x1F0AD]={ + [0x1F411]={ category="so", direction="on", }, - [0x1F0AE]={ + [0x1F412]={ category="so", direction="on", }, - [0x1F0B1]={ + [0x1F413]={ category="so", direction="on", }, - [0x1F0B2]={ + [0x1F414]={ category="so", direction="on", }, - [0x1F0B3]={ + [0x1F415]={ category="so", direction="on", }, - [0x1F0B4]={ + [0x1F416]={ category="so", direction="on", }, - [0x1F0B5]={ + [0x1F417]={ category="so", direction="on", }, - [0x1F0B6]={ + [0x1F418]={ category="so", direction="on", }, - [0x1F0B7]={ + [0x1F419]={ category="so", direction="on", }, - [0x1F0B8]={ + [0x1F41A]={ category="so", direction="on", }, - [0x1F0B9]={ + [0x1F41B]={ category="so", direction="on", }, - [0x1F0BA]={ + [0x1F41C]={ category="so", direction="on", }, - [0x1F0BB]={ + [0x1F41D]={ category="so", direction="on", }, - [0x1F0BC]={ + [0x1F41E]={ category="so", direction="on", }, - [0x1F0BD]={ + [0x1F41F]={ category="so", direction="on", }, - [0x1F0BE]={ + [0x1F420]={ category="so", direction="on", }, - [0x1F0C1]={ + [0x1F421]={ category="so", direction="on", }, - [0x1F0C2]={ + [0x1F422]={ category="so", direction="on", }, - [0x1F0C3]={ + [0x1F423]={ category="so", direction="on", }, - [0x1F0C4]={ + [0x1F424]={ category="so", direction="on", }, - [0x1F0C5]={ + [0x1F425]={ category="so", direction="on", }, - [0x1F0C6]={ + [0x1F426]={ category="so", direction="on", }, - [0x1F0C7]={ + [0x1F427]={ category="so", direction="on", }, - [0x1F0C8]={ + [0x1F428]={ category="so", direction="on", }, - [0x1F0C9]={ + [0x1F429]={ category="so", direction="on", }, - [0x1F0CA]={ + [0x1F42A]={ category="so", direction="on", }, - [0x1F0CB]={ + [0x1F42B]={ category="so", direction="on", }, - [0x1F0CC]={ + [0x1F42C]={ category="so", direction="on", }, - [0x1F0CD]={ + [0x1F42D]={ category="so", direction="on", }, - [0x1F0CE]={ + [0x1F42E]={ category="so", direction="on", }, - [0x1F0CF]={ + [0x1F42F]={ category="so", direction="on", }, - [0x1F0D1]={ + [0x1F430]={ category="so", direction="on", }, - [0x1F0D2]={ + [0x1F431]={ category="so", direction="on", }, - [0x1F0D3]={ + [0x1F432]={ category="so", direction="on", }, - [0x1F0D4]={ + [0x1F433]={ category="so", direction="on", }, - [0x1F0D5]={ + [0x1F434]={ category="so", direction="on", }, - [0x1F0D6]={ + [0x1F435]={ + category="so", + direction="on", + }, + [0x1F436]={ category="so", direction="on", }, - [0x1F0D7]={ + [0x1F437]={ category="so", direction="on", }, - [0x1F0D8]={ + [0x1F438]={ category="so", direction="on", }, - [0x1F0D9]={ + [0x1F439]={ category="so", direction="on", }, - [0x1F0DA]={ + [0x1F43A]={ category="so", direction="on", }, - [0x1F0DB]={ + [0x1F43B]={ category="so", direction="on", }, - [0x1F0DC]={ + [0x1F43C]={ category="so", direction="on", }, - [0x1F0DD]={ + [0x1F43D]={ category="so", direction="on", }, - [0x1F0DE]={ + [0x1F43E]={ category="so", direction="on", }, - [0x1F0DF]={ + [0x1F43F]={ category="so", direction="on", }, - [0x1F100]={ - category="no", - direction="en", - }, - [0x1F101]={ - category="no", - direction="en", - }, - [0x1F102]={ - category="no", - direction="en", - }, - [0x1F103]={ - category="no", - direction="en", - }, - [0x1F104]={ - category="no", - direction="en", - }, - [0x1F105]={ - category="no", - direction="en", - }, - [0x1F106]={ - category="no", - direction="en", - }, - [0x1F107]={ - category="no", - direction="en", - }, - [0x1F108]={ - category="no", - direction="en", - }, - [0x1F109]={ - category="no", - direction="en", - }, - [0x1F10A]={ - category="no", - direction="en", - }, - [0x1F110]={ + [0x1F440]={ category="so", - direction="l", + direction="on", }, - [0x1F111]={ + [0x1F441]={ category="so", - direction="l", + direction="on", }, - [0x1F112]={ + [0x1F442]={ category="so", - direction="l", + direction="on", }, - [0x1F113]={ + [0x1F443]={ category="so", - direction="l", + direction="on", }, - [0x1F114]={ + [0x1F444]={ category="so", - direction="l", + direction="on", }, - [0x1F115]={ + [0x1F445]={ category="so", - direction="l", + direction="on", }, - [0x1F116]={ + [0x1F446]={ category="so", - direction="l", + direction="on", }, - [0x1F117]={ + [0x1F447]={ category="so", - direction="l", + direction="on", }, - [0x1F118]={ + [0x1F448]={ category="so", - direction="l", + direction="on", }, - [0x1F119]={ + [0x1F449]={ category="so", - direction="l", + direction="on", }, - [0x1F11A]={ + [0x1F44A]={ category="so", - direction="l", + direction="on", }, - [0x1F11B]={ + [0x1F44B]={ category="so", - direction="l", + direction="on", }, - [0x1F11C]={ + [0x1F44C]={ category="so", - direction="l", + direction="on", }, - [0x1F11D]={ + [0x1F44D]={ category="so", - direction="l", + direction="on", }, - [0x1F11E]={ + [0x1F44E]={ category="so", - direction="l", + direction="on", }, - [0x1F11F]={ + [0x1F44F]={ category="so", - direction="l", + direction="on", }, - [0x1F120]={ + [0x1F450]={ category="so", - direction="l", + direction="on", }, - [0x1F121]={ + [0x1F451]={ category="so", - direction="l", + direction="on", }, - [0x1F122]={ + [0x1F452]={ category="so", - direction="l", + direction="on", }, - [0x1F123]={ + [0x1F453]={ category="so", - direction="l", + direction="on", }, - [0x1F124]={ + [0x1F454]={ category="so", - direction="l", + direction="on", }, - [0x1F125]={ + [0x1F455]={ category="so", - direction="l", + direction="on", }, - [0x1F126]={ + [0x1F456]={ category="so", - direction="l", + direction="on", }, - [0x1F127]={ + [0x1F457]={ category="so", - direction="l", + direction="on", }, - [0x1F128]={ + [0x1F458]={ category="so", - direction="l", + direction="on", }, - [0x1F129]={ + [0x1F459]={ category="so", - direction="l", + direction="on", }, - [0x1F12A]={ + [0x1F45A]={ category="so", - direction="l", + direction="on", }, - [0x1F12B]={ + [0x1F45B]={ category="so", - direction="l", + direction="on", }, - [0x1F12C]={ + [0x1F45C]={ category="so", - direction="l", + direction="on", }, - [0x1F12D]={ + [0x1F45D]={ category="so", - direction="l", + direction="on", }, - [0x1F12E]={ + [0x1F45E]={ category="so", - direction="l", + direction="on", }, - [0x1F130]={ + [0x1F45F]={ category="so", - direction="l", + direction="on", }, - [0x1F131]={ + [0x1F460]={ category="so", - direction="l", + direction="on", }, - [0x1F132]={ + [0x1F461]={ category="so", - direction="l", + direction="on", }, - [0x1F133]={ + [0x1F462]={ category="so", - direction="l", + direction="on", }, - [0x1F134]={ + [0x1F463]={ category="so", - direction="l", + direction="on", }, - [0x1F135]={ + [0x1F464]={ category="so", - direction="l", + direction="on", }, - [0x1F136]={ + [0x1F465]={ category="so", - direction="l", + direction="on", }, - [0x1F137]={ + [0x1F466]={ category="so", - direction="l", + direction="on", }, - [0x1F138]={ + [0x1F467]={ category="so", - direction="l", + direction="on", }, - [0x1F139]={ + [0x1F468]={ category="so", - direction="l", + direction="on", }, - [0x1F13A]={ + [0x1F469]={ category="so", - direction="l", + direction="on", }, - [0x1F13B]={ + [0x1F46A]={ category="so", - direction="l", + direction="on", }, - [0x1F13C]={ + [0x1F46B]={ category="so", - direction="l", + direction="on", }, - [0x1F13D]={ + [0x1F46C]={ category="so", - direction="l", + direction="on", }, - [0x1F13E]={ + [0x1F46D]={ category="so", - direction="l", + direction="on", }, - [0x1F13F]={ + [0x1F46E]={ category="so", - direction="l", + direction="on", }, - [0x1F140]={ + [0x1F46F]={ category="so", - direction="l", + direction="on", }, - [0x1F141]={ + [0x1F470]={ category="so", - direction="l", + direction="on", }, - [0x1F142]={ + [0x1F471]={ category="so", - direction="l", + direction="on", }, - [0x1F143]={ + [0x1F472]={ category="so", - direction="l", + direction="on", }, - [0x1F144]={ + [0x1F473]={ category="so", - direction="l", + direction="on", }, - [0x1F145]={ + [0x1F474]={ category="so", - direction="l", + direction="on", }, - [0x1F146]={ + [0x1F475]={ category="so", - direction="l", + direction="on", }, - [0x1F147]={ + [0x1F476]={ category="so", - direction="l", + direction="on", }, - [0x1F148]={ + [0x1F477]={ category="so", - direction="l", + direction="on", }, - [0x1F149]={ + [0x1F478]={ category="so", - direction="l", + direction="on", }, - [0x1F14A]={ + [0x1F479]={ category="so", - direction="l", + direction="on", }, - [0x1F14B]={ + [0x1F47A]={ category="so", - direction="l", + direction="on", }, - [0x1F14C]={ + [0x1F47B]={ category="so", - direction="l", + direction="on", }, - [0x1F14D]={ + [0x1F47C]={ category="so", - direction="l", + direction="on", }, - [0x1F14E]={ + [0x1F47D]={ category="so", - direction="l", + direction="on", }, - [0x1F14F]={ + [0x1F47E]={ category="so", - direction="l", + direction="on", }, - [0x1F150]={ + [0x1F47F]={ category="so", - direction="l", + direction="on", }, - [0x1F151]={ + [0x1F480]={ category="so", - direction="l", + direction="on", }, - [0x1F152]={ + [0x1F481]={ category="so", - direction="l", + direction="on", }, - [0x1F153]={ + [0x1F482]={ category="so", - direction="l", + direction="on", }, - [0x1F154]={ + [0x1F483]={ category="so", - direction="l", + direction="on", }, - [0x1F155]={ + [0x1F484]={ category="so", - direction="l", + direction="on", }, - [0x1F156]={ + [0x1F485]={ category="so", - direction="l", + direction="on", }, - [0x1F157]={ + [0x1F486]={ category="so", - direction="l", + direction="on", }, - [0x1F158]={ + [0x1F487]={ category="so", - direction="l", + direction="on", }, - [0x1F159]={ + [0x1F488]={ category="so", - direction="l", + direction="on", }, - [0x1F15A]={ + [0x1F489]={ category="so", - direction="l", + direction="on", }, - [0x1F15B]={ + [0x1F48A]={ category="so", - direction="l", + direction="on", }, - [0x1F15C]={ + [0x1F48B]={ category="so", - direction="l", + direction="on", }, - [0x1F15D]={ + [0x1F48C]={ category="so", - direction="l", + direction="on", }, - [0x1F15E]={ + [0x1F48D]={ category="so", - direction="l", + direction="on", }, - [0x1F15F]={ + [0x1F48E]={ category="so", - direction="l", + direction="on", }, - [0x1F160]={ + [0x1F48F]={ category="so", - direction="l", + direction="on", }, - [0x1F161]={ + [0x1F490]={ category="so", - direction="l", + direction="on", }, - [0x1F162]={ + [0x1F491]={ category="so", - direction="l", + direction="on", }, - [0x1F163]={ + [0x1F492]={ category="so", - direction="l", + direction="on", }, - [0x1F164]={ + [0x1F493]={ category="so", - direction="l", + direction="on", }, - [0x1F165]={ + [0x1F494]={ category="so", - direction="l", + direction="on", }, - [0x1F166]={ + [0x1F495]={ category="so", - direction="l", + direction="on", }, - [0x1F167]={ + [0x1F496]={ category="so", - direction="l", + direction="on", }, - [0x1F168]={ + [0x1F497]={ category="so", - direction="l", + direction="on", }, - [0x1F169]={ + [0x1F498]={ category="so", - direction="l", + direction="on", }, - [0x1F16A]={ + [0x1F499]={ category="so", direction="on", }, - [0x1F16B]={ + [0x1F49A]={ category="so", direction="on", }, - [0x1F170]={ + [0x1F49B]={ category="so", - direction="l", + direction="on", }, - [0x1F171]={ + [0x1F49C]={ category="so", - direction="l", + direction="on", }, - [0x1F172]={ + [0x1F49D]={ category="so", - direction="l", + direction="on", }, - [0x1F173]={ + [0x1F49E]={ category="so", - direction="l", + direction="on", }, - [0x1F174]={ + [0x1F49F]={ category="so", - direction="l", + direction="on", }, - [0x1F175]={ + [0x1F4A0]={ category="so", - direction="l", + direction="on", }, - [0x1F176]={ + [0x1F4A1]={ category="so", - direction="l", + direction="on", }, - [0x1F177]={ + [0x1F4A2]={ category="so", - direction="l", + direction="on", }, - [0x1F178]={ + [0x1F4A3]={ category="so", - direction="l", + direction="on", }, - [0x1F179]={ + [0x1F4A4]={ category="so", - direction="l", + direction="on", }, - [0x1F17A]={ + [0x1F4A5]={ category="so", - direction="l", + direction="on", }, - [0x1F17B]={ + [0x1F4A6]={ category="so", - direction="l", + direction="on", }, - [0x1F17C]={ + [0x1F4A7]={ category="so", - direction="l", + direction="on", }, - [0x1F17D]={ + [0x1F4A8]={ category="so", - direction="l", + direction="on", }, - [0x1F17E]={ + [0x1F4A9]={ category="so", - direction="l", + direction="on", }, - [0x1F17F]={ + [0x1F4AA]={ category="so", - direction="l", + direction="on", }, - [0x1F180]={ + [0x1F4AB]={ category="so", - direction="l", + direction="on", }, - [0x1F181]={ + [0x1F4AC]={ category="so", - direction="l", + direction="on", }, - [0x1F182]={ + [0x1F4AD]={ category="so", - direction="l", + direction="on", }, - [0x1F183]={ + [0x1F4AE]={ category="so", - direction="l", + direction="on", }, - [0x1F184]={ + [0x1F4AF]={ category="so", - direction="l", + direction="on", }, - [0x1F185]={ + [0x1F4B0]={ category="so", - direction="l", + direction="on", }, - [0x1F186]={ + [0x1F4B1]={ category="so", - direction="l", + direction="on", }, - [0x1F187]={ + [0x1F4B2]={ category="so", - direction="l", + direction="on", }, - [0x1F188]={ + [0x1F4B3]={ category="so", - direction="l", + direction="on", }, - [0x1F189]={ + [0x1F4B4]={ category="so", - direction="l", + direction="on", }, - [0x1F18A]={ + [0x1F4B5]={ category="so", - direction="l", + direction="on", }, - [0x1F18B]={ + [0x1F4B6]={ category="so", - direction="l", + direction="on", }, - [0x1F18C]={ + [0x1F4B7]={ category="so", - direction="l", + direction="on", }, - [0x1F18D]={ + [0x1F4B8]={ category="so", - direction="l", + direction="on", }, - [0x1F18E]={ + [0x1F4B9]={ category="so", - direction="l", + direction="on", }, - [0x1F18F]={ + [0x1F4BA]={ category="so", - direction="l", + direction="on", }, - [0x1F190]={ + [0x1F4BB]={ category="so", - direction="l", + direction="on", }, - [0x1F191]={ + [0x1F4BC]={ category="so", - direction="l", + direction="on", }, - [0x1F192]={ + [0x1F4BD]={ category="so", - direction="l", + direction="on", }, - [0x1F193]={ + [0x1F4BE]={ category="so", - direction="l", + direction="on", }, - [0x1F194]={ + [0x1F4BF]={ category="so", - direction="l", + direction="on", }, - [0x1F195]={ + [0x1F4C0]={ category="so", - direction="l", + direction="on", }, - [0x1F196]={ + [0x1F4C1]={ category="so", - direction="l", + direction="on", }, - [0x1F197]={ + [0x1F4C2]={ category="so", - direction="l", + direction="on", }, - [0x1F198]={ + [0x1F4C3]={ category="so", - direction="l", + direction="on", }, - [0x1F199]={ + [0x1F4C4]={ category="so", - direction="l", + direction="on", }, - [0x1F19A]={ + [0x1F4C5]={ category="so", - direction="l", + direction="on", }, - [0x1F1E6]={ + [0x1F4C6]={ category="so", - direction="l", + direction="on", }, - [0x1F1E7]={ + [0x1F4C7]={ category="so", - direction="l", + direction="on", }, - [0x1F1E8]={ + [0x1F4C8]={ category="so", - direction="l", + direction="on", }, - [0x1F1E9]={ + [0x1F4C9]={ category="so", - direction="l", + direction="on", }, - [0x1F1EA]={ + [0x1F4CA]={ category="so", - direction="l", + direction="on", }, - [0x1F1EB]={ + [0x1F4CB]={ category="so", - direction="l", + direction="on", }, - [0x1F1EC]={ + [0x1F4CC]={ category="so", - direction="l", + direction="on", }, - [0x1F1ED]={ + [0x1F4CD]={ category="so", - direction="l", + direction="on", }, - [0x1F1EE]={ + [0x1F4CE]={ category="so", - direction="l", + direction="on", }, - [0x1F1EF]={ + [0x1F4CF]={ category="so", - direction="l", + direction="on", }, - [0x1F1F0]={ + [0x1F4D0]={ category="so", - direction="l", + direction="on", }, - [0x1F1F1]={ + [0x1F4D1]={ category="so", - direction="l", + direction="on", }, - [0x1F1F2]={ + [0x1F4D2]={ category="so", - direction="l", + direction="on", }, - [0x1F1F3]={ + [0x1F4D3]={ category="so", - direction="l", + direction="on", }, - [0x1F1F4]={ + [0x1F4D4]={ category="so", - direction="l", + direction="on", }, - [0x1F1F5]={ + [0x1F4D5]={ category="so", - direction="l", + direction="on", }, - [0x1F1F6]={ + [0x1F4D6]={ category="so", - direction="l", + direction="on", }, - [0x1F1F7]={ + [0x1F4D7]={ category="so", - direction="l", + direction="on", }, - [0x1F1F8]={ + [0x1F4D8]={ category="so", - direction="l", + direction="on", }, - [0x1F1F9]={ + [0x1F4D9]={ category="so", - direction="l", + direction="on", }, - [0x1F1FA]={ + [0x1F4DA]={ category="so", - direction="l", + direction="on", }, - [0x1F1FB]={ + [0x1F4DB]={ category="so", - direction="l", + direction="on", }, - [0x1F1FC]={ + [0x1F4DC]={ category="so", - direction="l", + direction="on", }, - [0x1F1FD]={ + [0x1F4DD]={ category="so", - direction="l", + direction="on", }, - [0x1F1FE]={ + [0x1F4DE]={ category="so", - direction="l", + direction="on", }, - [0x1F1FF]={ + [0x1F4DF]={ category="so", - direction="l", + direction="on", }, - [0x1F200]={ + [0x1F4E0]={ category="so", - direction="l", + direction="on", }, - [0x1F201]={ + [0x1F4E1]={ category="so", - direction="l", + direction="on", }, - [0x1F202]={ + [0x1F4E2]={ category="so", - direction="l", + direction="on", }, - [0x1F210]={ + [0x1F4E3]={ category="so", - direction="l", + direction="on", }, - [0x1F211]={ + [0x1F4E4]={ category="so", - direction="l", + direction="on", }, - [0x1F212]={ + [0x1F4E5]={ category="so", - direction="l", + direction="on", }, - [0x1F213]={ + [0x1F4E6]={ category="so", - direction="l", + direction="on", }, - [0x1F214]={ + [0x1F4E7]={ category="so", - direction="l", + direction="on", }, - [0x1F215]={ + [0x1F4E8]={ category="so", - direction="l", + direction="on", }, - [0x1F216]={ + [0x1F4E9]={ category="so", - direction="l", + direction="on", }, - [0x1F217]={ + [0x1F4EA]={ category="so", - direction="l", + direction="on", }, - [0x1F218]={ + [0x1F4EB]={ category="so", - direction="l", + direction="on", }, - [0x1F219]={ + [0x1F4EC]={ category="so", - direction="l", + direction="on", }, - [0x1F21A]={ + [0x1F4ED]={ category="so", - direction="l", + direction="on", }, - [0x1F21B]={ + [0x1F4EE]={ category="so", - direction="l", + direction="on", }, - [0x1F21C]={ + [0x1F4EF]={ category="so", - direction="l", + direction="on", }, - [0x1F21D]={ + [0x1F4F0]={ category="so", - direction="l", + direction="on", }, - [0x1F21E]={ + [0x1F4F1]={ category="so", - direction="l", + direction="on", }, - [0x1F21F]={ + [0x1F4F2]={ category="so", - direction="l", + direction="on", }, - [0x1F220]={ + [0x1F4F3]={ category="so", - direction="l", + direction="on", }, - [0x1F221]={ + [0x1F4F4]={ category="so", - direction="l", + direction="on", }, - [0x1F222]={ + [0x1F4F5]={ category="so", - direction="l", + direction="on", }, - [0x1F223]={ + [0x1F4F6]={ category="so", - direction="l", + direction="on", }, - [0x1F224]={ + [0x1F4F7]={ category="so", - direction="l", + direction="on", }, - [0x1F225]={ + [0x1F4F8]={ category="so", - direction="l", + direction="on", }, - [0x1F226]={ + [0x1F4F9]={ category="so", - direction="l", + direction="on", }, - [0x1F227]={ + [0x1F4FA]={ category="so", - direction="l", + direction="on", }, - [0x1F228]={ + [0x1F4FB]={ category="so", - direction="l", + direction="on", }, - [0x1F229]={ + [0x1F4FC]={ category="so", - direction="l", + direction="on", }, - [0x1F22A]={ + [0x1F4FD]={ category="so", - direction="l", + direction="on", }, - [0x1F22B]={ + [0x1F4FE]={ category="so", - direction="l", + direction="on", }, - [0x1F22C]={ + [0x1F500]={ category="so", - direction="l", + direction="on", }, - [0x1F22D]={ + [0x1F501]={ category="so", - direction="l", + direction="on", }, - [0x1F22E]={ + [0x1F502]={ category="so", - direction="l", + direction="on", }, - [0x1F22F]={ + [0x1F503]={ category="so", - direction="l", + direction="on", }, - [0x1F230]={ + [0x1F504]={ category="so", - direction="l", + direction="on", }, - [0x1F231]={ + [0x1F505]={ category="so", - direction="l", + direction="on", }, - [0x1F232]={ + [0x1F506]={ category="so", - direction="l", + direction="on", }, - [0x1F233]={ + [0x1F507]={ category="so", - direction="l", + direction="on", }, - [0x1F234]={ + [0x1F508]={ category="so", - direction="l", + direction="on", }, - [0x1F235]={ + [0x1F509]={ category="so", - direction="l", + direction="on", }, - [0x1F236]={ + [0x1F50A]={ category="so", - direction="l", + direction="on", }, - [0x1F237]={ + [0x1F50B]={ category="so", - direction="l", + direction="on", }, - [0x1F238]={ + [0x1F50C]={ category="so", - direction="l", + direction="on", }, - [0x1F239]={ + [0x1F50D]={ category="so", - direction="l", + direction="on", }, - [0x1F23A]={ + [0x1F50E]={ category="so", - direction="l", + direction="on", }, - [0x1F240]={ + [0x1F50F]={ category="so", - direction="l", + direction="on", }, - [0x1F241]={ + [0x1F510]={ category="so", - direction="l", + direction="on", }, - [0x1F242]={ + [0x1F511]={ category="so", - direction="l", + direction="on", }, - [0x1F243]={ + [0x1F512]={ category="so", - direction="l", + direction="on", }, - [0x1F244]={ + [0x1F513]={ category="so", - direction="l", + direction="on", }, - [0x1F245]={ + [0x1F514]={ category="so", - direction="l", + direction="on", }, - [0x1F246]={ + [0x1F515]={ category="so", - direction="l", + direction="on", }, - [0x1F247]={ + [0x1F516]={ category="so", - direction="l", + direction="on", }, - [0x1F248]={ + [0x1F517]={ category="so", - direction="l", + direction="on", }, - [0x1F250]={ + [0x1F518]={ category="so", - direction="l", + direction="on", }, - [0x1F251]={ + [0x1F519]={ category="so", - direction="l", + direction="on", }, - [0x1F300]={ + [0x1F51A]={ category="so", direction="on", }, - [0x1F301]={ + [0x1F51B]={ category="so", direction="on", }, - [0x1F302]={ + [0x1F51C]={ category="so", direction="on", }, - [0x1F303]={ + [0x1F51D]={ category="so", direction="on", }, - [0x1F304]={ + [0x1F51E]={ category="so", direction="on", }, - [0x1F305]={ + [0x1F51F]={ category="so", direction="on", }, - [0x1F306]={ + [0x1F520]={ category="so", direction="on", }, - [0x1F307]={ + [0x1F521]={ category="so", direction="on", }, - [0x1F308]={ + [0x1F522]={ category="so", direction="on", }, - [0x1F309]={ + [0x1F523]={ category="so", direction="on", }, - [0x1F30A]={ + [0x1F524]={ category="so", direction="on", }, - [0x1F30B]={ + [0x1F525]={ category="so", direction="on", }, - [0x1F30C]={ + [0x1F526]={ category="so", direction="on", }, - [0x1F30D]={ + [0x1F527]={ category="so", direction="on", }, - [0x1F30E]={ + [0x1F528]={ category="so", direction="on", }, - [0x1F30F]={ + [0x1F529]={ category="so", direction="on", }, - [0x1F310]={ + [0x1F52A]={ category="so", direction="on", }, - [0x1F311]={ + [0x1F52B]={ category="so", direction="on", }, - [0x1F312]={ + [0x1F52C]={ category="so", direction="on", }, - [0x1F313]={ + [0x1F52D]={ category="so", direction="on", }, - [0x1F314]={ + [0x1F52E]={ category="so", direction="on", }, - [0x1F315]={ + [0x1F52F]={ category="so", direction="on", }, - [0x1F316]={ + [0x1F530]={ category="so", direction="on", }, - [0x1F317]={ + [0x1F531]={ category="so", direction="on", }, - [0x1F318]={ + [0x1F532]={ category="so", direction="on", }, - [0x1F319]={ + [0x1F533]={ category="so", direction="on", }, - [0x1F31A]={ + [0x1F534]={ category="so", direction="on", }, - [0x1F31B]={ + [0x1F535]={ category="so", direction="on", }, - [0x1F31C]={ + [0x1F536]={ category="so", direction="on", }, - [0x1F31D]={ + [0x1F537]={ category="so", direction="on", }, - [0x1F31E]={ + [0x1F538]={ category="so", direction="on", }, - [0x1F31F]={ + [0x1F539]={ category="so", direction="on", }, - [0x1F320]={ + [0x1F53A]={ category="so", direction="on", }, - [0x1F330]={ + [0x1F53B]={ category="so", direction="on", }, - [0x1F331]={ + [0x1F53C]={ category="so", direction="on", }, - [0x1F332]={ + [0x1F53D]={ category="so", direction="on", }, - [0x1F333]={ + [0x1F53E]={ category="so", direction="on", }, - [0x1F334]={ + [0x1F53F]={ category="so", direction="on", }, - [0x1F335]={ + [0x1F540]={ category="so", direction="on", }, - [0x1F337]={ + [0x1F541]={ category="so", direction="on", }, - [0x1F338]={ + [0x1F542]={ category="so", direction="on", }, - [0x1F339]={ + [0x1F543]={ category="so", direction="on", }, - [0x1F33A]={ + [0x1F544]={ category="so", direction="on", }, - [0x1F33B]={ + [0x1F545]={ category="so", direction="on", }, - [0x1F33C]={ + [0x1F546]={ category="so", direction="on", }, - [0x1F33D]={ + [0x1F547]={ category="so", direction="on", }, - [0x1F33E]={ + [0x1F548]={ category="so", direction="on", }, - [0x1F33F]={ + [0x1F549]={ category="so", direction="on", }, - [0x1F340]={ + [0x1F54A]={ category="so", direction="on", }, - [0x1F341]={ + [0x1F550]={ category="so", direction="on", }, - [0x1F342]={ + [0x1F551]={ category="so", direction="on", }, - [0x1F343]={ + [0x1F552]={ category="so", direction="on", }, - [0x1F344]={ + [0x1F553]={ category="so", direction="on", }, - [0x1F345]={ + [0x1F554]={ category="so", direction="on", }, - [0x1F346]={ + [0x1F555]={ category="so", direction="on", }, - [0x1F347]={ + [0x1F556]={ category="so", direction="on", }, - [0x1F348]={ + [0x1F557]={ category="so", direction="on", }, - [0x1F349]={ + [0x1F558]={ category="so", direction="on", }, - [0x1F34A]={ + [0x1F559]={ category="so", direction="on", }, - [0x1F34B]={ + [0x1F55A]={ category="so", direction="on", }, - [0x1F34C]={ + [0x1F55B]={ category="so", direction="on", }, - [0x1F34D]={ + [0x1F55C]={ category="so", direction="on", }, - [0x1F34E]={ + [0x1F55D]={ category="so", direction="on", }, - [0x1F34F]={ + [0x1F55E]={ category="so", direction="on", }, - [0x1F350]={ + [0x1F55F]={ category="so", direction="on", }, - [0x1F351]={ + [0x1F560]={ category="so", direction="on", }, - [0x1F352]={ + [0x1F561]={ category="so", direction="on", }, - [0x1F353]={ + [0x1F562]={ category="so", direction="on", }, - [0x1F354]={ + [0x1F563]={ category="so", direction="on", }, - [0x1F355]={ + [0x1F564]={ category="so", direction="on", }, - [0x1F356]={ + [0x1F565]={ category="so", direction="on", }, - [0x1F357]={ + [0x1F566]={ category="so", direction="on", }, - [0x1F358]={ + [0x1F567]={ category="so", direction="on", }, - [0x1F359]={ + [0x1F568]={ category="so", direction="on", }, - [0x1F35A]={ + [0x1F569]={ category="so", direction="on", }, - [0x1F35B]={ + [0x1F56A]={ category="so", direction="on", }, - [0x1F35C]={ + [0x1F56B]={ category="so", direction="on", }, - [0x1F35D]={ + [0x1F56C]={ category="so", direction="on", }, - [0x1F35E]={ + [0x1F56D]={ category="so", direction="on", }, - [0x1F35F]={ + [0x1F56E]={ category="so", direction="on", }, - [0x1F360]={ + [0x1F56F]={ category="so", direction="on", }, - [0x1F361]={ + [0x1F570]={ category="so", direction="on", }, - [0x1F362]={ + [0x1F571]={ category="so", direction="on", }, - [0x1F363]={ + [0x1F572]={ category="so", direction="on", }, - [0x1F364]={ + [0x1F573]={ category="so", direction="on", }, - [0x1F365]={ + [0x1F574]={ category="so", direction="on", }, - [0x1F366]={ + [0x1F575]={ category="so", direction="on", }, - [0x1F367]={ + [0x1F576]={ category="so", direction="on", }, - [0x1F368]={ + [0x1F577]={ category="so", direction="on", }, - [0x1F369]={ + [0x1F578]={ category="so", direction="on", }, - [0x1F36A]={ + [0x1F579]={ category="so", direction="on", }, - [0x1F36B]={ + [0x1F57B]={ category="so", direction="on", }, - [0x1F36C]={ + [0x1F57C]={ category="so", direction="on", }, - [0x1F36D]={ + [0x1F57D]={ category="so", direction="on", }, - [0x1F36E]={ + [0x1F57E]={ category="so", direction="on", }, - [0x1F36F]={ + [0x1F57F]={ category="so", direction="on", }, - [0x1F370]={ + [0x1F580]={ category="so", direction="on", }, - [0x1F371]={ + [0x1F581]={ category="so", direction="on", }, - [0x1F372]={ + [0x1F582]={ category="so", direction="on", }, - [0x1F373]={ + [0x1F583]={ category="so", direction="on", }, - [0x1F374]={ + [0x1F584]={ category="so", direction="on", }, - [0x1F375]={ + [0x1F585]={ category="so", direction="on", }, - [0x1F376]={ + [0x1F586]={ category="so", direction="on", }, - [0x1F377]={ + [0x1F587]={ category="so", direction="on", }, - [0x1F378]={ + [0x1F588]={ category="so", direction="on", }, - [0x1F379]={ + [0x1F589]={ category="so", direction="on", }, - [0x1F37A]={ + [0x1F58A]={ category="so", direction="on", }, - [0x1F37B]={ + [0x1F58B]={ category="so", direction="on", }, - [0x1F37C]={ + [0x1F58C]={ category="so", direction="on", }, - [0x1F380]={ + [0x1F58D]={ category="so", direction="on", }, - [0x1F381]={ + [0x1F58E]={ category="so", direction="on", }, - [0x1F382]={ + [0x1F58F]={ category="so", direction="on", }, - [0x1F383]={ + [0x1F590]={ category="so", direction="on", }, - [0x1F384]={ + [0x1F591]={ category="so", direction="on", }, - [0x1F385]={ + [0x1F592]={ category="so", direction="on", }, - [0x1F386]={ + [0x1F593]={ category="so", direction="on", }, - [0x1F387]={ + [0x1F594]={ category="so", direction="on", }, - [0x1F388]={ + [0x1F595]={ category="so", direction="on", }, - [0x1F389]={ + [0x1F596]={ category="so", direction="on", }, - [0x1F38A]={ + [0x1F597]={ category="so", direction="on", }, - [0x1F38B]={ + [0x1F598]={ category="so", direction="on", }, - [0x1F38C]={ + [0x1F599]={ category="so", direction="on", }, - [0x1F38D]={ + [0x1F59A]={ category="so", direction="on", }, - [0x1F38E]={ + [0x1F59B]={ category="so", direction="on", }, - [0x1F38F]={ + [0x1F59C]={ category="so", direction="on", }, - [0x1F390]={ + [0x1F59D]={ category="so", direction="on", }, - [0x1F391]={ + [0x1F59E]={ category="so", direction="on", }, - [0x1F392]={ + [0x1F59F]={ category="so", direction="on", }, - [0x1F393]={ + [0x1F5A0]={ category="so", direction="on", }, - [0x1F3A0]={ + [0x1F5A1]={ category="so", direction="on", }, - [0x1F3A1]={ + [0x1F5A2]={ category="so", direction="on", }, - [0x1F3A2]={ + [0x1F5A3]={ category="so", direction="on", }, - [0x1F3A3]={ + [0x1F5A5]={ category="so", direction="on", }, - [0x1F3A4]={ + [0x1F5A6]={ category="so", direction="on", }, - [0x1F3A5]={ + [0x1F5A7]={ category="so", direction="on", }, - [0x1F3A6]={ + [0x1F5A8]={ category="so", direction="on", }, - [0x1F3A7]={ + [0x1F5A9]={ category="so", direction="on", }, - [0x1F3A8]={ + [0x1F5AA]={ category="so", direction="on", }, - [0x1F3A9]={ + [0x1F5AB]={ category="so", direction="on", }, - [0x1F3AA]={ + [0x1F5AC]={ category="so", direction="on", }, - [0x1F3AB]={ + [0x1F5AD]={ category="so", direction="on", }, - [0x1F3AC]={ + [0x1F5AE]={ category="so", direction="on", }, - [0x1F3AD]={ + [0x1F5AF]={ category="so", direction="on", }, - [0x1F3AE]={ + [0x1F5B0]={ category="so", direction="on", }, - [0x1F3AF]={ + [0x1F5B1]={ category="so", direction="on", }, - [0x1F3B0]={ + [0x1F5B2]={ category="so", direction="on", }, - [0x1F3B1]={ + [0x1F5B3]={ category="so", direction="on", }, - [0x1F3B2]={ + [0x1F5B4]={ category="so", direction="on", }, - [0x1F3B3]={ + [0x1F5B5]={ category="so", direction="on", }, - [0x1F3B4]={ + [0x1F5B6]={ category="so", direction="on", }, - [0x1F3B5]={ + [0x1F5B7]={ category="so", direction="on", }, - [0x1F3B6]={ + [0x1F5B8]={ category="so", direction="on", }, - [0x1F3B7]={ + [0x1F5B9]={ category="so", direction="on", }, - [0x1F3B8]={ + [0x1F5BA]={ category="so", direction="on", }, - [0x1F3B9]={ + [0x1F5BB]={ category="so", direction="on", }, - [0x1F3BA]={ + [0x1F5BC]={ category="so", direction="on", }, - [0x1F3BB]={ + [0x1F5BD]={ category="so", direction="on", }, - [0x1F3BC]={ + [0x1F5BE]={ category="so", direction="on", }, - [0x1F3BD]={ + [0x1F5BF]={ category="so", direction="on", }, - [0x1F3BE]={ + [0x1F5C0]={ category="so", direction="on", }, - [0x1F3BF]={ + [0x1F5C1]={ category="so", direction="on", }, - [0x1F3C0]={ + [0x1F5C2]={ category="so", direction="on", }, - [0x1F3C1]={ + [0x1F5C3]={ category="so", direction="on", }, - [0x1F3C2]={ + [0x1F5C4]={ category="so", direction="on", }, - [0x1F3C3]={ + [0x1F5C5]={ category="so", direction="on", }, - [0x1F3C4]={ + [0x1F5C6]={ category="so", direction="on", }, - [0x1F3C6]={ + [0x1F5C7]={ category="so", direction="on", }, - [0x1F3C7]={ + [0x1F5C8]={ category="so", direction="on", }, - [0x1F3C8]={ + [0x1F5C9]={ category="so", direction="on", }, - [0x1F3C9]={ + [0x1F5CA]={ category="so", direction="on", }, - [0x1F3CA]={ + [0x1F5CB]={ category="so", direction="on", }, - [0x1F3E0]={ + [0x1F5CC]={ category="so", direction="on", }, - [0x1F3E1]={ + [0x1F5CD]={ category="so", direction="on", }, - [0x1F3E2]={ + [0x1F5CE]={ category="so", direction="on", }, - [0x1F3E3]={ + [0x1F5CF]={ category="so", direction="on", }, - [0x1F3E4]={ + [0x1F5D0]={ category="so", direction="on", }, - [0x1F3E5]={ + [0x1F5D1]={ category="so", direction="on", }, - [0x1F3E6]={ + [0x1F5D2]={ category="so", direction="on", }, - [0x1F3E7]={ + [0x1F5D3]={ category="so", direction="on", }, - [0x1F3E8]={ + [0x1F5D4]={ category="so", direction="on", }, - [0x1F3E9]={ + [0x1F5D5]={ category="so", direction="on", }, - [0x1F3EA]={ + [0x1F5D6]={ category="so", direction="on", }, - [0x1F3EB]={ + [0x1F5D7]={ category="so", direction="on", }, - [0x1F3EC]={ + [0x1F5D8]={ category="so", direction="on", }, - [0x1F3ED]={ + [0x1F5D9]={ category="so", direction="on", }, - [0x1F3EE]={ + [0x1F5DA]={ category="so", direction="on", }, - [0x1F3EF]={ + [0x1F5DB]={ category="so", direction="on", }, - [0x1F3F0]={ + [0x1F5DC]={ category="so", direction="on", }, - [0x1F400]={ + [0x1F5DD]={ category="so", direction="on", }, - [0x1F401]={ + [0x1F5DE]={ category="so", direction="on", }, - [0x1F402]={ + [0x1F5DF]={ category="so", direction="on", }, - [0x1F403]={ + [0x1F5E0]={ category="so", direction="on", }, - [0x1F404]={ + [0x1F5E1]={ category="so", direction="on", }, - [0x1F405]={ + [0x1F5E2]={ category="so", direction="on", }, - [0x1F406]={ + [0x1F5E3]={ category="so", direction="on", }, - [0x1F407]={ + [0x1F5E4]={ category="so", direction="on", }, - [0x1F408]={ + [0x1F5E5]={ category="so", direction="on", }, - [0x1F409]={ + [0x1F5E6]={ category="so", direction="on", }, - [0x1F40A]={ + [0x1F5E7]={ category="so", direction="on", }, - [0x1F40B]={ + [0x1F5E8]={ category="so", direction="on", }, - [0x1F40C]={ + [0x1F5E9]={ category="so", direction="on", }, - [0x1F40D]={ + [0x1F5EA]={ category="so", direction="on", }, - [0x1F40E]={ + [0x1F5EB]={ category="so", direction="on", }, - [0x1F40F]={ + [0x1F5EC]={ category="so", direction="on", }, - [0x1F410]={ + [0x1F5ED]={ category="so", direction="on", }, - [0x1F411]={ + [0x1F5EE]={ category="so", direction="on", }, - [0x1F412]={ + [0x1F5EF]={ category="so", direction="on", }, - [0x1F413]={ + [0x1F5F0]={ category="so", direction="on", }, - [0x1F414]={ + [0x1F5F1]={ category="so", direction="on", }, - [0x1F415]={ + [0x1F5F2]={ category="so", direction="on", }, - [0x1F416]={ + [0x1F5F3]={ category="so", direction="on", }, - [0x1F417]={ + [0x1F5F4]={ category="so", direction="on", }, - [0x1F418]={ + [0x1F5F5]={ category="so", direction="on", }, - [0x1F419]={ + [0x1F5F6]={ category="so", direction="on", }, - [0x1F41A]={ + [0x1F5F7]={ category="so", direction="on", }, - [0x1F41B]={ + [0x1F5F8]={ category="so", direction="on", }, - [0x1F41C]={ + [0x1F5F9]={ category="so", direction="on", }, - [0x1F41D]={ + [0x1F5FA]={ category="so", direction="on", }, - [0x1F41E]={ + [0x1F5FB]={ category="so", direction="on", }, - [0x1F41F]={ + [0x1F5FC]={ category="so", direction="on", }, - [0x1F420]={ + [0x1F5FD]={ category="so", direction="on", }, - [0x1F421]={ + [0x1F5FE]={ category="so", direction="on", }, - [0x1F422]={ + [0x1F5FF]={ category="so", direction="on", }, - [0x1F423]={ + [0x1F600]={ category="so", direction="on", }, - [0x1F424]={ + [0x1F601]={ category="so", direction="on", }, - [0x1F425]={ + [0x1F602]={ category="so", direction="on", }, - [0x1F426]={ + [0x1F603]={ category="so", direction="on", }, - [0x1F427]={ + [0x1F604]={ category="so", direction="on", }, - [0x1F428]={ + [0x1F605]={ category="so", direction="on", }, - [0x1F429]={ + [0x1F606]={ category="so", direction="on", }, - [0x1F42A]={ + [0x1F607]={ category="so", direction="on", }, - [0x1F42B]={ + [0x1F608]={ category="so", direction="on", }, - [0x1F42C]={ + [0x1F609]={ category="so", direction="on", }, - [0x1F42D]={ + [0x1F60A]={ category="so", direction="on", }, - [0x1F42E]={ + [0x1F60B]={ category="so", direction="on", }, - [0x1F42F]={ + [0x1F60C]={ category="so", direction="on", }, - [0x1F430]={ + [0x1F60D]={ category="so", direction="on", }, - [0x1F431]={ + [0x1F60E]={ category="so", direction="on", }, - [0x1F432]={ + [0x1F60F]={ category="so", direction="on", }, - [0x1F433]={ + [0x1F610]={ category="so", direction="on", }, - [0x1F434]={ + [0x1F611]={ category="so", direction="on", }, - [0x1F435]={ + [0x1F612]={ category="so", direction="on", }, - [0x1F436]={ + [0x1F613]={ category="so", direction="on", }, - [0x1F437]={ + [0x1F614]={ category="so", direction="on", }, - [0x1F438]={ + [0x1F615]={ category="so", direction="on", }, - [0x1F439]={ + [0x1F616]={ category="so", direction="on", }, - [0x1F43A]={ + [0x1F617]={ category="so", direction="on", }, - [0x1F43B]={ + [0x1F618]={ category="so", direction="on", }, - [0x1F43C]={ + [0x1F619]={ category="so", direction="on", }, - [0x1F43D]={ + [0x1F61A]={ category="so", direction="on", }, - [0x1F43E]={ + [0x1F61B]={ category="so", direction="on", }, - [0x1F440]={ + [0x1F61C]={ category="so", direction="on", }, - [0x1F442]={ + [0x1F61D]={ category="so", direction="on", }, - [0x1F443]={ + [0x1F61E]={ category="so", direction="on", }, - [0x1F444]={ + [0x1F61F]={ category="so", direction="on", }, - [0x1F445]={ + [0x1F620]={ category="so", direction="on", }, - [0x1F446]={ + [0x1F621]={ category="so", direction="on", }, - [0x1F447]={ + [0x1F622]={ category="so", direction="on", }, - [0x1F448]={ + [0x1F623]={ category="so", direction="on", }, - [0x1F449]={ + [0x1F624]={ category="so", direction="on", }, - [0x1F44A]={ + [0x1F625]={ category="so", direction="on", }, - [0x1F44B]={ + [0x1F626]={ category="so", direction="on", }, - [0x1F44C]={ + [0x1F627]={ category="so", direction="on", }, - [0x1F44D]={ + [0x1F628]={ category="so", direction="on", }, - [0x1F44E]={ + [0x1F629]={ category="so", direction="on", }, - [0x1F44F]={ + [0x1F62A]={ category="so", direction="on", }, - [0x1F450]={ + [0x1F62B]={ category="so", direction="on", }, - [0x1F451]={ + [0x1F62C]={ category="so", direction="on", }, - [0x1F452]={ + [0x1F62D]={ category="so", direction="on", }, - [0x1F453]={ + [0x1F62E]={ category="so", direction="on", }, - [0x1F454]={ + [0x1F62F]={ category="so", direction="on", }, - [0x1F455]={ + [0x1F630]={ category="so", direction="on", }, - [0x1F456]={ + [0x1F631]={ category="so", direction="on", }, - [0x1F457]={ + [0x1F632]={ category="so", direction="on", }, - [0x1F458]={ + [0x1F633]={ category="so", direction="on", }, - [0x1F459]={ + [0x1F634]={ category="so", direction="on", }, - [0x1F45A]={ + [0x1F635]={ category="so", direction="on", }, - [0x1F45B]={ + [0x1F636]={ category="so", direction="on", }, - [0x1F45C]={ + [0x1F637]={ category="so", direction="on", }, - [0x1F45D]={ + [0x1F638]={ category="so", direction="on", }, - [0x1F45E]={ + [0x1F639]={ category="so", direction="on", }, - [0x1F45F]={ + [0x1F63A]={ category="so", direction="on", }, - [0x1F460]={ + [0x1F63B]={ category="so", direction="on", }, - [0x1F461]={ + [0x1F63C]={ category="so", direction="on", }, - [0x1F462]={ + [0x1F63D]={ category="so", direction="on", }, - [0x1F463]={ + [0x1F63E]={ category="so", direction="on", }, - [0x1F464]={ + [0x1F63F]={ category="so", direction="on", }, - [0x1F465]={ + [0x1F640]={ category="so", direction="on", }, - [0x1F466]={ + [0x1F641]={ category="so", direction="on", }, - [0x1F467]={ + [0x1F642]={ category="so", direction="on", }, - [0x1F468]={ + [0x1F645]={ category="so", direction="on", }, - [0x1F469]={ + [0x1F646]={ category="so", direction="on", }, - [0x1F46A]={ + [0x1F647]={ category="so", direction="on", }, - [0x1F46B]={ + [0x1F648]={ category="so", direction="on", }, - [0x1F46C]={ + [0x1F649]={ category="so", direction="on", }, - [0x1F46D]={ + [0x1F64A]={ category="so", direction="on", }, - [0x1F46E]={ + [0x1F64B]={ category="so", direction="on", }, - [0x1F46F]={ + [0x1F64C]={ category="so", direction="on", }, - [0x1F470]={ + [0x1F64D]={ category="so", direction="on", }, - [0x1F471]={ + [0x1F64E]={ category="so", direction="on", }, - [0x1F472]={ + [0x1F64F]={ category="so", direction="on", }, - [0x1F473]={ + [0x1F650]={ category="so", direction="on", }, - [0x1F474]={ + [0x1F651]={ category="so", direction="on", }, - [0x1F475]={ + [0x1F652]={ category="so", direction="on", }, - [0x1F476]={ + [0x1F653]={ category="so", direction="on", }, - [0x1F477]={ + [0x1F654]={ category="so", direction="on", }, - [0x1F478]={ + [0x1F655]={ category="so", direction="on", }, - [0x1F479]={ + [0x1F656]={ category="so", direction="on", }, - [0x1F47A]={ + [0x1F657]={ category="so", direction="on", }, - [0x1F47B]={ + [0x1F658]={ category="so", direction="on", }, - [0x1F47C]={ + [0x1F659]={ category="so", direction="on", }, - [0x1F47D]={ + [0x1F65A]={ category="so", direction="on", }, - [0x1F47E]={ + [0x1F65B]={ category="so", direction="on", }, - [0x1F47F]={ + [0x1F65C]={ category="so", direction="on", }, - [0x1F480]={ + [0x1F65D]={ category="so", direction="on", }, - [0x1F481]={ + [0x1F65E]={ category="so", direction="on", }, - [0x1F482]={ + [0x1F65F]={ category="so", direction="on", }, - [0x1F483]={ + [0x1F660]={ category="so", direction="on", }, - [0x1F484]={ + [0x1F661]={ category="so", direction="on", }, - [0x1F485]={ + [0x1F662]={ category="so", direction="on", }, - [0x1F486]={ + [0x1F663]={ category="so", direction="on", }, - [0x1F487]={ + [0x1F664]={ category="so", direction="on", }, - [0x1F488]={ + [0x1F665]={ category="so", direction="on", }, - [0x1F489]={ + [0x1F666]={ category="so", direction="on", }, - [0x1F48A]={ + [0x1F667]={ category="so", direction="on", }, - [0x1F48B]={ + [0x1F668]={ category="so", direction="on", }, - [0x1F48C]={ + [0x1F669]={ category="so", direction="on", }, - [0x1F48D]={ + [0x1F66A]={ category="so", direction="on", }, - [0x1F48E]={ + [0x1F66B]={ category="so", direction="on", }, - [0x1F48F]={ + [0x1F66C]={ category="so", direction="on", }, - [0x1F490]={ + [0x1F66D]={ category="so", direction="on", }, - [0x1F491]={ + [0x1F66E]={ category="so", direction="on", }, - [0x1F492]={ + [0x1F66F]={ category="so", direction="on", }, - [0x1F493]={ + [0x1F670]={ category="so", direction="on", }, - [0x1F494]={ + [0x1F671]={ category="so", direction="on", }, - [0x1F495]={ + [0x1F672]={ category="so", direction="on", }, - [0x1F496]={ + [0x1F673]={ category="so", direction="on", }, - [0x1F497]={ + [0x1F674]={ category="so", direction="on", }, - [0x1F498]={ + [0x1F675]={ category="so", direction="on", }, - [0x1F499]={ + [0x1F676]={ category="so", direction="on", }, - [0x1F49A]={ + [0x1F677]={ category="so", direction="on", }, - [0x1F49B]={ + [0x1F678]={ category="so", direction="on", }, - [0x1F49C]={ + [0x1F679]={ category="so", direction="on", }, - [0x1F49D]={ + [0x1F67A]={ category="so", direction="on", }, - [0x1F49E]={ + [0x1F67B]={ category="so", direction="on", }, - [0x1F49F]={ + [0x1F67C]={ category="so", direction="on", }, - [0x1F4A0]={ + [0x1F67D]={ category="so", direction="on", }, - [0x1F4A1]={ + [0x1F67E]={ category="so", direction="on", }, - [0x1F4A2]={ + [0x1F67F]={ category="so", direction="on", }, - [0x1F4A3]={ + [0x1F680]={ category="so", direction="on", }, - [0x1F4A4]={ + [0x1F681]={ category="so", direction="on", }, - [0x1F4A5]={ + [0x1F682]={ category="so", direction="on", }, - [0x1F4A6]={ + [0x1F683]={ category="so", direction="on", }, - [0x1F4A7]={ + [0x1F684]={ category="so", direction="on", }, - [0x1F4A8]={ + [0x1F685]={ category="so", direction="on", }, - [0x1F4A9]={ + [0x1F686]={ category="so", direction="on", }, - [0x1F4AA]={ + [0x1F687]={ category="so", direction="on", }, - [0x1F4AB]={ + [0x1F688]={ category="so", direction="on", }, - [0x1F4AC]={ + [0x1F689]={ category="so", direction="on", }, - [0x1F4AD]={ + [0x1F68A]={ category="so", direction="on", }, - [0x1F4AE]={ + [0x1F68B]={ category="so", direction="on", }, - [0x1F4AF]={ + [0x1F68C]={ category="so", direction="on", }, - [0x1F4B0]={ + [0x1F68D]={ category="so", direction="on", }, - [0x1F4B1]={ + [0x1F68E]={ category="so", direction="on", }, - [0x1F4B2]={ + [0x1F68F]={ category="so", direction="on", }, - [0x1F4B3]={ + [0x1F690]={ category="so", direction="on", }, - [0x1F4B4]={ + [0x1F691]={ category="so", direction="on", }, - [0x1F4B5]={ + [0x1F692]={ category="so", direction="on", }, - [0x1F4B6]={ + [0x1F693]={ category="so", direction="on", }, - [0x1F4B7]={ + [0x1F694]={ category="so", direction="on", }, - [0x1F4B8]={ + [0x1F695]={ category="so", direction="on", }, - [0x1F4B9]={ + [0x1F696]={ category="so", direction="on", }, - [0x1F4BA]={ + [0x1F697]={ category="so", direction="on", }, - [0x1F4BB]={ + [0x1F698]={ category="so", direction="on", }, - [0x1F4BC]={ + [0x1F699]={ category="so", direction="on", }, - [0x1F4BD]={ + [0x1F69A]={ category="so", direction="on", }, - [0x1F4BE]={ + [0x1F69B]={ category="so", direction="on", }, - [0x1F4BF]={ + [0x1F69C]={ category="so", direction="on", }, - [0x1F4C0]={ + [0x1F69D]={ category="so", direction="on", }, - [0x1F4C1]={ + [0x1F69E]={ category="so", direction="on", }, - [0x1F4C2]={ + [0x1F69F]={ category="so", direction="on", }, - [0x1F4C3]={ + [0x1F6A0]={ category="so", direction="on", }, - [0x1F4C4]={ + [0x1F6A1]={ category="so", direction="on", }, - [0x1F4C5]={ + [0x1F6A2]={ category="so", direction="on", }, - [0x1F4C6]={ + [0x1F6A3]={ category="so", direction="on", }, - [0x1F4C7]={ + [0x1F6A4]={ category="so", direction="on", }, - [0x1F4C8]={ + [0x1F6A5]={ category="so", direction="on", }, - [0x1F4C9]={ + [0x1F6A6]={ category="so", direction="on", }, - [0x1F4CA]={ + [0x1F6A7]={ category="so", direction="on", }, - [0x1F4CB]={ + [0x1F6A8]={ category="so", direction="on", }, - [0x1F4CC]={ + [0x1F6A9]={ category="so", direction="on", }, - [0x1F4CD]={ + [0x1F6AA]={ category="so", direction="on", }, - [0x1F4CE]={ + [0x1F6AB]={ category="so", direction="on", }, - [0x1F4CF]={ + [0x1F6AC]={ category="so", direction="on", }, - [0x1F4D0]={ + [0x1F6AD]={ category="so", direction="on", }, - [0x1F4D1]={ + [0x1F6AE]={ category="so", direction="on", }, - [0x1F4D2]={ + [0x1F6AF]={ category="so", direction="on", }, - [0x1F4D3]={ + [0x1F6B0]={ category="so", direction="on", }, - [0x1F4D4]={ + [0x1F6B1]={ category="so", direction="on", }, - [0x1F4D5]={ + [0x1F6B2]={ category="so", direction="on", }, - [0x1F4D6]={ + [0x1F6B3]={ category="so", direction="on", }, - [0x1F4D7]={ + [0x1F6B4]={ category="so", direction="on", }, - [0x1F4D8]={ + [0x1F6B5]={ category="so", direction="on", }, - [0x1F4D9]={ + [0x1F6B6]={ category="so", direction="on", }, - [0x1F4DA]={ + [0x1F6B7]={ category="so", direction="on", }, - [0x1F4DB]={ + [0x1F6B8]={ category="so", direction="on", }, - [0x1F4DC]={ + [0x1F6B9]={ category="so", direction="on", }, - [0x1F4DD]={ + [0x1F6BA]={ category="so", direction="on", }, - [0x1F4DE]={ + [0x1F6BB]={ category="so", direction="on", }, - [0x1F4DF]={ + [0x1F6BC]={ category="so", direction="on", }, - [0x1F4E0]={ + [0x1F6BD]={ category="so", direction="on", }, - [0x1F4E1]={ + [0x1F6BE]={ category="so", direction="on", }, - [0x1F4E2]={ + [0x1F6BF]={ category="so", direction="on", }, - [0x1F4E3]={ + [0x1F6C0]={ category="so", direction="on", }, - [0x1F4E4]={ + [0x1F6C1]={ category="so", direction="on", }, - [0x1F4E5]={ + [0x1F6C2]={ category="so", direction="on", }, - [0x1F4E6]={ + [0x1F6C3]={ category="so", direction="on", }, - [0x1F4E7]={ + [0x1F6C4]={ category="so", direction="on", }, - [0x1F4E8]={ + [0x1F6C5]={ category="so", direction="on", }, - [0x1F4E9]={ + [0x1F6C6]={ category="so", direction="on", }, - [0x1F4EA]={ + [0x1F6C7]={ category="so", direction="on", }, - [0x1F4EB]={ + [0x1F6C8]={ category="so", direction="on", }, - [0x1F4EC]={ + [0x1F6C9]={ category="so", direction="on", }, - [0x1F4ED]={ + [0x1F6CA]={ category="so", direction="on", }, - [0x1F4EE]={ + [0x1F6CB]={ category="so", direction="on", }, - [0x1F4EF]={ + [0x1F6CC]={ category="so", direction="on", }, - [0x1F4F0]={ + [0x1F6CD]={ category="so", direction="on", }, - [0x1F4F1]={ + [0x1F6CE]={ category="so", direction="on", }, - [0x1F4F2]={ + [0x1F6CF]={ category="so", direction="on", }, - [0x1F4F3]={ + [0x1F6E0]={ category="so", direction="on", }, - [0x1F4F4]={ + [0x1F6E1]={ category="so", direction="on", }, - [0x1F4F5]={ + [0x1F6E2]={ category="so", direction="on", }, - [0x1F4F6]={ + [0x1F6E3]={ category="so", direction="on", }, - [0x1F4F7]={ + [0x1F6E4]={ category="so", direction="on", }, - [0x1F4F9]={ + [0x1F6E5]={ category="so", direction="on", }, - [0x1F4FA]={ + [0x1F6E6]={ category="so", direction="on", }, - [0x1F4FB]={ + [0x1F6E7]={ category="so", direction="on", }, - [0x1F4FC]={ + [0x1F6E8]={ category="so", direction="on", }, - [0x1F500]={ + [0x1F6E9]={ category="so", direction="on", }, - [0x1F501]={ + [0x1F6EA]={ category="so", direction="on", }, - [0x1F502]={ + [0x1F6EB]={ category="so", direction="on", }, - [0x1F503]={ + [0x1F6EC]={ category="so", direction="on", }, - [0x1F504]={ + [0x1F6F0]={ category="so", direction="on", }, - [0x1F505]={ + [0x1F6F1]={ category="so", direction="on", }, - [0x1F506]={ + [0x1F6F2]={ category="so", direction="on", }, - [0x1F507]={ + [0x1F6F3]={ category="so", direction="on", }, - [0x1F508]={ + [0x1F700]={ category="so", direction="on", }, - [0x1F509]={ + [0x1F701]={ category="so", direction="on", }, - [0x1F50A]={ + [0x1F702]={ category="so", direction="on", }, - [0x1F50B]={ + [0x1F703]={ category="so", direction="on", }, - [0x1F50C]={ + [0x1F704]={ category="so", direction="on", }, - [0x1F50D]={ + [0x1F705]={ category="so", direction="on", }, - [0x1F50E]={ + [0x1F706]={ category="so", direction="on", }, - [0x1F50F]={ + [0x1F707]={ category="so", direction="on", }, - [0x1F510]={ + [0x1F708]={ category="so", direction="on", }, - [0x1F511]={ + [0x1F709]={ category="so", direction="on", }, - [0x1F512]={ + [0x1F70A]={ category="so", direction="on", }, - [0x1F513]={ + [0x1F70B]={ category="so", direction="on", }, - [0x1F514]={ + [0x1F70C]={ category="so", direction="on", }, - [0x1F515]={ + [0x1F70D]={ category="so", direction="on", }, - [0x1F516]={ + [0x1F70E]={ category="so", direction="on", }, - [0x1F517]={ + [0x1F70F]={ category="so", direction="on", }, - [0x1F518]={ + [0x1F710]={ category="so", direction="on", }, - [0x1F519]={ + [0x1F711]={ category="so", direction="on", }, - [0x1F51A]={ + [0x1F712]={ category="so", direction="on", }, - [0x1F51B]={ + [0x1F713]={ category="so", direction="on", }, - [0x1F51C]={ + [0x1F714]={ category="so", direction="on", }, - [0x1F51D]={ + [0x1F715]={ category="so", direction="on", }, - [0x1F51E]={ + [0x1F716]={ category="so", direction="on", }, - [0x1F51F]={ + [0x1F717]={ category="so", direction="on", }, - [0x1F520]={ + [0x1F718]={ category="so", direction="on", }, - [0x1F521]={ + [0x1F719]={ category="so", direction="on", }, - [0x1F522]={ + [0x1F71A]={ category="so", direction="on", }, - [0x1F523]={ + [0x1F71B]={ category="so", direction="on", }, - [0x1F524]={ + [0x1F71C]={ category="so", direction="on", }, - [0x1F525]={ + [0x1F71D]={ category="so", direction="on", }, - [0x1F526]={ + [0x1F71E]={ category="so", direction="on", }, - [0x1F527]={ + [0x1F71F]={ category="so", direction="on", }, - [0x1F528]={ + [0x1F720]={ category="so", direction="on", }, - [0x1F529]={ + [0x1F721]={ category="so", direction="on", }, - [0x1F52A]={ + [0x1F722]={ category="so", direction="on", }, - [0x1F52B]={ + [0x1F723]={ category="so", direction="on", }, - [0x1F52C]={ + [0x1F724]={ category="so", direction="on", }, - [0x1F52D]={ + [0x1F725]={ category="so", direction="on", }, - [0x1F52E]={ + [0x1F726]={ category="so", direction="on", }, - [0x1F52F]={ + [0x1F727]={ category="so", direction="on", }, - [0x1F530]={ + [0x1F728]={ category="so", direction="on", }, - [0x1F531]={ + [0x1F729]={ category="so", direction="on", }, - [0x1F532]={ + [0x1F72A]={ category="so", direction="on", }, - [0x1F533]={ + [0x1F72B]={ category="so", direction="on", }, - [0x1F534]={ + [0x1F72C]={ category="so", direction="on", }, - [0x1F535]={ + [0x1F72D]={ category="so", direction="on", }, - [0x1F536]={ + [0x1F72E]={ category="so", direction="on", }, - [0x1F537]={ + [0x1F72F]={ category="so", direction="on", }, - [0x1F538]={ + [0x1F730]={ category="so", direction="on", }, - [0x1F539]={ + [0x1F731]={ category="so", direction="on", }, - [0x1F53A]={ + [0x1F732]={ category="so", direction="on", }, - [0x1F53B]={ + [0x1F733]={ category="so", direction="on", }, - [0x1F53C]={ + [0x1F734]={ category="so", direction="on", }, - [0x1F53D]={ + [0x1F735]={ category="so", direction="on", }, - [0x1F540]={ + [0x1F736]={ category="so", direction="on", }, - [0x1F541]={ + [0x1F737]={ category="so", direction="on", }, - [0x1F542]={ + [0x1F738]={ category="so", direction="on", }, - [0x1F543]={ + [0x1F739]={ category="so", direction="on", }, - [0x1F550]={ + [0x1F73A]={ category="so", direction="on", }, - [0x1F551]={ + [0x1F73B]={ category="so", direction="on", }, - [0x1F552]={ + [0x1F73C]={ category="so", direction="on", }, - [0x1F553]={ + [0x1F73D]={ category="so", direction="on", }, - [0x1F554]={ + [0x1F73E]={ category="so", direction="on", }, - [0x1F555]={ + [0x1F73F]={ category="so", direction="on", }, - [0x1F556]={ + [0x1F740]={ category="so", direction="on", }, - [0x1F557]={ + [0x1F741]={ category="so", direction="on", }, - [0x1F558]={ + [0x1F742]={ category="so", direction="on", }, - [0x1F559]={ + [0x1F743]={ category="so", direction="on", }, - [0x1F55A]={ + [0x1F744]={ category="so", direction="on", }, - [0x1F55B]={ + [0x1F745]={ category="so", direction="on", }, - [0x1F55C]={ + [0x1F746]={ category="so", direction="on", }, - [0x1F55D]={ + [0x1F747]={ category="so", direction="on", }, - [0x1F55E]={ + [0x1F748]={ category="so", direction="on", }, - [0x1F55F]={ + [0x1F749]={ category="so", direction="on", }, - [0x1F560]={ + [0x1F74A]={ category="so", direction="on", }, - [0x1F561]={ + [0x1F74B]={ category="so", direction="on", }, - [0x1F562]={ + [0x1F74C]={ category="so", direction="on", }, - [0x1F563]={ + [0x1F74D]={ category="so", direction="on", }, - [0x1F564]={ + [0x1F74E]={ category="so", direction="on", }, - [0x1F565]={ + [0x1F74F]={ category="so", direction="on", }, - [0x1F566]={ + [0x1F750]={ category="so", direction="on", }, - [0x1F567]={ + [0x1F751]={ category="so", direction="on", }, - [0x1F5FB]={ + [0x1F752]={ category="so", direction="on", }, - [0x1F5FC]={ + [0x1F753]={ category="so", direction="on", }, - [0x1F5FD]={ + [0x1F754]={ category="so", direction="on", }, - [0x1F5FE]={ + [0x1F755]={ category="so", direction="on", }, - [0x1F5FF]={ + [0x1F756]={ category="so", direction="on", }, - [0x1F600]={ + [0x1F757]={ category="so", direction="on", }, - [0x1F601]={ + [0x1F758]={ category="so", direction="on", }, - [0x1F602]={ + [0x1F759]={ category="so", direction="on", }, - [0x1F603]={ + [0x1F75A]={ category="so", direction="on", }, - [0x1F604]={ + [0x1F75B]={ category="so", direction="on", }, - [0x1F605]={ + [0x1F75C]={ category="so", direction="on", }, - [0x1F606]={ + [0x1F75D]={ category="so", direction="on", }, - [0x1F607]={ + [0x1F75E]={ category="so", direction="on", }, - [0x1F608]={ + [0x1F75F]={ category="so", direction="on", }, - [0x1F609]={ + [0x1F760]={ category="so", direction="on", }, - [0x1F60A]={ + [0x1F761]={ category="so", direction="on", }, - [0x1F60B]={ + [0x1F762]={ category="so", direction="on", }, - [0x1F60C]={ + [0x1F763]={ category="so", direction="on", }, - [0x1F60D]={ + [0x1F764]={ category="so", direction="on", }, - [0x1F60E]={ + [0x1F765]={ category="so", direction="on", }, - [0x1F60F]={ + [0x1F766]={ category="so", direction="on", }, - [0x1F610]={ + [0x1F767]={ category="so", direction="on", }, - [0x1F611]={ + [0x1F768]={ category="so", direction="on", }, - [0x1F612]={ + [0x1F769]={ category="so", direction="on", }, - [0x1F613]={ + [0x1F76A]={ category="so", direction="on", }, - [0x1F614]={ + [0x1F76B]={ category="so", direction="on", }, - [0x1F615]={ + [0x1F76C]={ category="so", direction="on", }, - [0x1F616]={ + [0x1F76D]={ category="so", direction="on", }, - [0x1F617]={ + [0x1F76E]={ category="so", direction="on", }, - [0x1F618]={ + [0x1F76F]={ category="so", direction="on", }, - [0x1F619]={ + [0x1F770]={ category="so", direction="on", }, - [0x1F61A]={ + [0x1F771]={ category="so", direction="on", }, - [0x1F61B]={ + [0x1F772]={ category="so", direction="on", }, - [0x1F61C]={ + [0x1F773]={ category="so", direction="on", }, - [0x1F61D]={ + [0x1F780]={ category="so", direction="on", }, - [0x1F61E]={ + [0x1F781]={ category="so", direction="on", }, - [0x1F61F]={ + [0x1F782]={ category="so", direction="on", }, - [0x1F620]={ + [0x1F783]={ category="so", direction="on", }, - [0x1F621]={ + [0x1F784]={ category="so", direction="on", }, - [0x1F622]={ + [0x1F785]={ category="so", direction="on", }, - [0x1F623]={ + [0x1F786]={ category="so", direction="on", }, - [0x1F624]={ + [0x1F787]={ category="so", direction="on", }, - [0x1F625]={ + [0x1F788]={ category="so", direction="on", }, - [0x1F626]={ + [0x1F789]={ category="so", direction="on", }, - [0x1F627]={ + [0x1F78A]={ category="so", direction="on", }, - [0x1F628]={ + [0x1F78B]={ category="so", direction="on", }, - [0x1F629]={ + [0x1F78C]={ category="so", direction="on", }, - [0x1F62A]={ + [0x1F78D]={ category="so", direction="on", }, - [0x1F62B]={ + [0x1F78E]={ category="so", direction="on", }, - [0x1F62C]={ + [0x1F78F]={ category="so", direction="on", }, - [0x1F62D]={ + [0x1F790]={ category="so", direction="on", }, - [0x1F62E]={ + [0x1F791]={ category="so", direction="on", }, - [0x1F62F]={ + [0x1F792]={ category="so", direction="on", }, - [0x1F630]={ + [0x1F793]={ category="so", direction="on", }, - [0x1F631]={ + [0x1F794]={ category="so", direction="on", }, - [0x1F632]={ + [0x1F795]={ category="so", direction="on", }, - [0x1F633]={ + [0x1F796]={ category="so", direction="on", }, - [0x1F634]={ + [0x1F797]={ category="so", direction="on", }, - [0x1F635]={ + [0x1F798]={ category="so", direction="on", }, - [0x1F636]={ + [0x1F799]={ category="so", direction="on", }, - [0x1F637]={ + [0x1F79A]={ category="so", direction="on", }, - [0x1F638]={ + [0x1F79B]={ category="so", direction="on", }, - [0x1F639]={ + [0x1F79C]={ category="so", direction="on", }, - [0x1F63A]={ + [0x1F79D]={ category="so", direction="on", }, - [0x1F63B]={ + [0x1F79E]={ category="so", direction="on", }, - [0x1F63C]={ + [0x1F79F]={ category="so", direction="on", }, - [0x1F63D]={ + [0x1F7A0]={ category="so", direction="on", }, - [0x1F63E]={ + [0x1F7A1]={ category="so", direction="on", }, - [0x1F63F]={ + [0x1F7A2]={ category="so", direction="on", }, - [0x1F640]={ + [0x1F7A3]={ category="so", direction="on", }, - [0x1F645]={ + [0x1F7A4]={ category="so", direction="on", }, - [0x1F646]={ + [0x1F7A5]={ category="so", direction="on", }, - [0x1F647]={ + [0x1F7A6]={ category="so", direction="on", }, - [0x1F648]={ + [0x1F7A7]={ category="so", direction="on", }, - [0x1F649]={ + [0x1F7A8]={ category="so", direction="on", }, - [0x1F64A]={ + [0x1F7A9]={ category="so", direction="on", }, - [0x1F64B]={ + [0x1F7AA]={ category="so", direction="on", }, - [0x1F64C]={ + [0x1F7AB]={ category="so", direction="on", }, - [0x1F64D]={ + [0x1F7AC]={ category="so", direction="on", }, - [0x1F64E]={ + [0x1F7AD]={ category="so", direction="on", }, - [0x1F64F]={ + [0x1F7AE]={ category="so", direction="on", }, - [0x1F680]={ + [0x1F7AF]={ category="so", direction="on", }, - [0x1F681]={ + [0x1F7B0]={ category="so", direction="on", }, - [0x1F682]={ + [0x1F7B1]={ category="so", direction="on", }, - [0x1F683]={ + [0x1F7B2]={ category="so", direction="on", }, - [0x1F684]={ + [0x1F7B3]={ category="so", direction="on", }, - [0x1F685]={ + [0x1F7B4]={ category="so", direction="on", }, - [0x1F686]={ + [0x1F7B5]={ category="so", direction="on", }, - [0x1F687]={ + [0x1F7B6]={ category="so", direction="on", }, - [0x1F688]={ + [0x1F7B7]={ category="so", direction="on", }, - [0x1F689]={ + [0x1F7B8]={ category="so", direction="on", }, - [0x1F68A]={ + [0x1F7B9]={ category="so", direction="on", }, - [0x1F68B]={ + [0x1F7BA]={ category="so", direction="on", }, - [0x1F68C]={ + [0x1F7BB]={ category="so", direction="on", }, - [0x1F68D]={ + [0x1F7BC]={ category="so", direction="on", }, - [0x1F68E]={ + [0x1F7BD]={ category="so", direction="on", }, - [0x1F68F]={ + [0x1F7BE]={ category="so", direction="on", }, - [0x1F690]={ + [0x1F7BF]={ category="so", direction="on", }, - [0x1F691]={ + [0x1F7C0]={ category="so", direction="on", }, - [0x1F692]={ + [0x1F7C1]={ category="so", direction="on", }, - [0x1F693]={ + [0x1F7C2]={ category="so", direction="on", }, - [0x1F694]={ + [0x1F7C3]={ category="so", direction="on", }, - [0x1F695]={ + [0x1F7C4]={ category="so", direction="on", }, - [0x1F696]={ + [0x1F7C5]={ category="so", direction="on", }, - [0x1F697]={ + [0x1F7C6]={ category="so", direction="on", }, - [0x1F698]={ + [0x1F7C7]={ category="so", direction="on", }, - [0x1F699]={ + [0x1F7C8]={ category="so", direction="on", }, - [0x1F69A]={ + [0x1F7C9]={ category="so", direction="on", }, - [0x1F69B]={ + [0x1F7CA]={ category="so", direction="on", }, - [0x1F69C]={ + [0x1F7CB]={ category="so", direction="on", }, - [0x1F69D]={ + [0x1F7CC]={ category="so", direction="on", }, - [0x1F69E]={ + [0x1F7CD]={ category="so", direction="on", }, - [0x1F69F]={ + [0x1F7CE]={ category="so", direction="on", }, - [0x1F6A0]={ + [0x1F7CF]={ category="so", direction="on", }, - [0x1F6A1]={ + [0x1F7D0]={ category="so", direction="on", }, - [0x1F6A2]={ + [0x1F7D1]={ category="so", direction="on", }, - [0x1F6A3]={ + [0x1F7D2]={ category="so", direction="on", }, - [0x1F6A4]={ + [0x1F7D3]={ category="so", direction="on", }, - [0x1F6A5]={ + [0x1F7D4]={ category="so", direction="on", }, - [0x1F6A6]={ + [0x1F800]={ category="so", direction="on", }, - [0x1F6A7]={ + [0x1F801]={ category="so", direction="on", }, - [0x1F6A8]={ + [0x1F802]={ category="so", direction="on", }, - [0x1F6A9]={ + [0x1F803]={ category="so", direction="on", }, - [0x1F6AA]={ + [0x1F804]={ category="so", direction="on", }, - [0x1F6AB]={ + [0x1F805]={ category="so", direction="on", }, - [0x1F6AC]={ + [0x1F806]={ category="so", direction="on", }, - [0x1F6AD]={ + [0x1F807]={ category="so", direction="on", }, - [0x1F6AE]={ + [0x1F808]={ category="so", direction="on", }, - [0x1F6AF]={ + [0x1F809]={ category="so", direction="on", }, - [0x1F6B0]={ + [0x1F80A]={ category="so", direction="on", }, - [0x1F6B1]={ + [0x1F80B]={ category="so", direction="on", }, - [0x1F6B2]={ + [0x1F810]={ category="so", direction="on", }, - [0x1F6B3]={ + [0x1F811]={ category="so", direction="on", }, - [0x1F6B4]={ + [0x1F812]={ category="so", direction="on", }, - [0x1F6B5]={ + [0x1F813]={ category="so", direction="on", }, - [0x1F6B6]={ + [0x1F814]={ category="so", direction="on", }, - [0x1F6B7]={ + [0x1F815]={ category="so", direction="on", }, - [0x1F6B8]={ + [0x1F816]={ category="so", direction="on", }, - [0x1F6B9]={ + [0x1F817]={ category="so", direction="on", }, - [0x1F6BA]={ + [0x1F818]={ category="so", direction="on", }, - [0x1F6BB]={ + [0x1F819]={ category="so", direction="on", }, - [0x1F6BC]={ + [0x1F81A]={ category="so", direction="on", }, - [0x1F6BD]={ + [0x1F81B]={ category="so", direction="on", }, - [0x1F6BE]={ + [0x1F81C]={ category="so", direction="on", }, - [0x1F6BF]={ + [0x1F81D]={ category="so", direction="on", }, - [0x1F6C0]={ + [0x1F81E]={ category="so", direction="on", }, - [0x1F6C1]={ + [0x1F81F]={ category="so", direction="on", }, - [0x1F6C2]={ + [0x1F820]={ category="so", direction="on", }, - [0x1F6C3]={ + [0x1F821]={ category="so", direction="on", }, - [0x1F6C4]={ + [0x1F822]={ category="so", direction="on", }, - [0x1F6C5]={ + [0x1F823]={ category="so", direction="on", }, - [0x1F700]={ + [0x1F824]={ category="so", direction="on", }, - [0x1F701]={ + [0x1F825]={ category="so", direction="on", }, - [0x1F702]={ + [0x1F826]={ category="so", direction="on", }, - [0x1F703]={ + [0x1F827]={ category="so", direction="on", }, - [0x1F704]={ + [0x1F828]={ category="so", direction="on", }, - [0x1F705]={ + [0x1F829]={ category="so", direction="on", }, - [0x1F706]={ + [0x1F82A]={ category="so", direction="on", }, - [0x1F707]={ + [0x1F82B]={ category="so", direction="on", }, - [0x1F708]={ + [0x1F82C]={ category="so", direction="on", }, - [0x1F709]={ + [0x1F82D]={ category="so", direction="on", }, - [0x1F70A]={ + [0x1F82E]={ category="so", direction="on", }, - [0x1F70B]={ + [0x1F82F]={ category="so", direction="on", }, - [0x1F70C]={ + [0x1F830]={ category="so", direction="on", }, - [0x1F70D]={ + [0x1F831]={ category="so", direction="on", }, - [0x1F70E]={ + [0x1F832]={ category="so", direction="on", }, - [0x1F70F]={ + [0x1F833]={ category="so", direction="on", }, - [0x1F710]={ + [0x1F834]={ category="so", direction="on", }, - [0x1F711]={ + [0x1F835]={ category="so", direction="on", }, - [0x1F712]={ + [0x1F836]={ category="so", direction="on", }, - [0x1F713]={ + [0x1F837]={ category="so", direction="on", }, - [0x1F714]={ + [0x1F838]={ category="so", direction="on", }, - [0x1F715]={ + [0x1F839]={ category="so", direction="on", }, - [0x1F716]={ + [0x1F83A]={ category="so", direction="on", }, - [0x1F717]={ + [0x1F83B]={ category="so", direction="on", }, - [0x1F718]={ + [0x1F83C]={ category="so", direction="on", }, - [0x1F719]={ + [0x1F83D]={ category="so", direction="on", }, - [0x1F71A]={ + [0x1F83E]={ category="so", direction="on", }, - [0x1F71B]={ + [0x1F83F]={ category="so", direction="on", }, - [0x1F71C]={ + [0x1F840]={ category="so", direction="on", }, - [0x1F71D]={ + [0x1F841]={ category="so", direction="on", }, - [0x1F71E]={ + [0x1F842]={ category="so", direction="on", }, - [0x1F71F]={ + [0x1F843]={ category="so", direction="on", }, - [0x1F720]={ + [0x1F844]={ category="so", direction="on", }, - [0x1F721]={ + [0x1F845]={ category="so", direction="on", }, - [0x1F722]={ + [0x1F846]={ category="so", direction="on", }, - [0x1F723]={ + [0x1F847]={ category="so", direction="on", }, - [0x1F724]={ + [0x1F850]={ category="so", direction="on", }, - [0x1F725]={ + [0x1F851]={ category="so", direction="on", }, - [0x1F726]={ + [0x1F852]={ category="so", direction="on", }, - [0x1F727]={ + [0x1F853]={ category="so", direction="on", }, - [0x1F728]={ + [0x1F854]={ category="so", direction="on", }, - [0x1F729]={ + [0x1F855]={ category="so", direction="on", }, - [0x1F72A]={ + [0x1F856]={ category="so", direction="on", }, - [0x1F72B]={ + [0x1F857]={ category="so", direction="on", }, - [0x1F72C]={ + [0x1F858]={ category="so", direction="on", }, - [0x1F72D]={ + [0x1F859]={ category="so", direction="on", }, - [0x1F72E]={ + [0x1F860]={ category="so", direction="on", }, - [0x1F72F]={ + [0x1F861]={ category="so", direction="on", }, - [0x1F730]={ + [0x1F862]={ category="so", direction="on", }, - [0x1F731]={ + [0x1F863]={ category="so", direction="on", }, - [0x1F732]={ + [0x1F864]={ category="so", direction="on", }, - [0x1F733]={ + [0x1F865]={ category="so", direction="on", }, - [0x1F734]={ + [0x1F866]={ category="so", direction="on", }, - [0x1F735]={ + [0x1F867]={ category="so", direction="on", }, - [0x1F736]={ + [0x1F868]={ category="so", direction="on", }, - [0x1F737]={ + [0x1F869]={ category="so", direction="on", }, - [0x1F738]={ + [0x1F86A]={ category="so", direction="on", }, - [0x1F739]={ + [0x1F86B]={ category="so", direction="on", }, - [0x1F73A]={ + [0x1F86C]={ category="so", direction="on", }, - [0x1F73B]={ + [0x1F86D]={ category="so", direction="on", }, - [0x1F73C]={ + [0x1F86E]={ category="so", direction="on", }, - [0x1F73D]={ + [0x1F86F]={ category="so", direction="on", }, - [0x1F73E]={ + [0x1F870]={ category="so", direction="on", }, - [0x1F73F]={ + [0x1F871]={ category="so", direction="on", }, - [0x1F740]={ + [0x1F872]={ category="so", direction="on", }, - [0x1F741]={ + [0x1F873]={ category="so", direction="on", }, - [0x1F742]={ + [0x1F874]={ category="so", direction="on", }, - [0x1F743]={ + [0x1F875]={ category="so", direction="on", }, - [0x1F744]={ + [0x1F876]={ category="so", direction="on", }, - [0x1F745]={ + [0x1F877]={ category="so", direction="on", }, - [0x1F746]={ + [0x1F878]={ category="so", direction="on", }, - [0x1F747]={ + [0x1F879]={ category="so", direction="on", }, - [0x1F748]={ + [0x1F87A]={ category="so", direction="on", }, - [0x1F749]={ + [0x1F87B]={ category="so", direction="on", }, - [0x1F74A]={ + [0x1F87C]={ category="so", direction="on", }, - [0x1F74B]={ + [0x1F87D]={ category="so", direction="on", }, - [0x1F74C]={ + [0x1F87E]={ category="so", direction="on", }, - [0x1F74D]={ + [0x1F87F]={ category="so", direction="on", }, - [0x1F74E]={ + [0x1F880]={ category="so", direction="on", }, - [0x1F74F]={ + [0x1F881]={ category="so", direction="on", }, - [0x1F750]={ + [0x1F882]={ category="so", direction="on", }, - [0x1F751]={ + [0x1F883]={ category="so", direction="on", }, - [0x1F752]={ + [0x1F884]={ category="so", direction="on", }, - [0x1F753]={ + [0x1F885]={ category="so", direction="on", }, - [0x1F754]={ + [0x1F886]={ category="so", direction="on", }, - [0x1F755]={ + [0x1F887]={ category="so", direction="on", }, - [0x1F756]={ + [0x1F890]={ category="so", direction="on", }, - [0x1F757]={ + [0x1F891]={ category="so", direction="on", }, - [0x1F758]={ + [0x1F892]={ category="so", direction="on", }, - [0x1F759]={ + [0x1F893]={ category="so", direction="on", }, - [0x1F75A]={ + [0x1F894]={ category="so", direction="on", }, - [0x1F75B]={ + [0x1F895]={ category="so", direction="on", }, - [0x1F75C]={ + [0x1F896]={ category="so", direction="on", }, - [0x1F75D]={ + [0x1F897]={ category="so", direction="on", }, - [0x1F75E]={ + [0x1F898]={ category="so", direction="on", }, - [0x1F75F]={ + [0x1F899]={ category="so", direction="on", }, - [0x1F760]={ + [0x1F89A]={ category="so", direction="on", }, - [0x1F761]={ + [0x1F89B]={ category="so", direction="on", }, - [0x1F762]={ + [0x1F89C]={ category="so", direction="on", }, - [0x1F763]={ + [0x1F89D]={ category="so", direction="on", }, - [0x1F764]={ + [0x1F89E]={ category="so", direction="on", }, - [0x1F765]={ + [0x1F89F]={ category="so", direction="on", }, - [0x1F766]={ + [0x1F8A0]={ category="so", direction="on", }, - [0x1F767]={ + [0x1F8A1]={ category="so", direction="on", }, - [0x1F768]={ + [0x1F8A2]={ category="so", direction="on", }, - [0x1F769]={ + [0x1F8A3]={ category="so", direction="on", }, - [0x1F76A]={ + [0x1F8A4]={ category="so", direction="on", }, - [0x1F76B]={ + [0x1F8A5]={ category="so", direction="on", }, - [0x1F76C]={ + [0x1F8A6]={ category="so", direction="on", }, - [0x1F76D]={ + [0x1F8A7]={ category="so", direction="on", }, - [0x1F76E]={ + [0x1F8A8]={ category="so", direction="on", }, - [0x1F76F]={ + [0x1F8A9]={ category="so", direction="on", }, - [0x1F770]={ + [0x1F8AA]={ category="so", direction="on", }, - [0x1F771]={ + [0x1F8AB]={ category="so", direction="on", }, - [0x1F772]={ + [0x1F8AC]={ category="so", direction="on", }, - [0x1F773]={ + [0x1F8AD]={ category="so", direction="on", }, diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua index b8ecb875c7d..9be29746c4b 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua @@ -1,9 +1,9 @@ if not modules then modules = { } end modules ['luaotfload-colors'] = { - version = "2.4", - comment = "companion to luaotfload.lua (font color)", + version = "2.5", + comment = "companion to luaotfload-main.lua (font color)", author = "Khaled Hosny, Elie Roux, Philipp Gesang", copyright = "Luaotfload Development Team", - license = "GNU GPL v2" + license = "GNU GPL v2.0" } --[[doc-- @@ -19,14 +19,8 @@ explanation: http://tug.org/pipermail/luatex/2013-May/004305.html --doc]]-- - -local color_callback = config.luaotfload.color_callback -if not color_callback then - --- maybe this would be better as a method: "early" | "late" - color_callback = "pre_linebreak_filter" --- color_callback = "pre_output_filter" --- old behavior, breaks expansion -end - +local log = luaotfload.log +local logreport = log.report local newnode = node.new local nodetype = node.id @@ -34,6 +28,9 @@ local traverse_nodes = node.traverse local insert_node_before = node.insert_before local insert_node_after = node.insert_after +local texset = tex.set +local texget = tex.get + local stringformat = string.format local stringgsub = string.gsub local stringfind = string.find @@ -86,8 +83,9 @@ local sanitize_color_expression = function (digits) digits = tostring(digits) local sanitized = lpegmatch(valid_digits, digits) if not sanitized then - luaotfload.warning( - "%q is not a valid rgb[a] color expression", digits) + logreport("both", 0, "color", + "%q is not a valid rgb[a] color expression", + digits) return nil end return sanitized @@ -276,20 +274,24 @@ local color_handler = function (head) local new_head = node_colorize(head, nil, nil) -- now append our page resources if res then - res["1"] = true - local tpr, t = tex.pdfpageresources, "" + res["1"] = true + local tpr = texget("pdfpageresources") + local t = "" for k in pairs(res) do local str = stringformat("/TransGs%s<>", k, k, k) if not stringfind(tpr,str) then t = t .. str end end + print"" if t ~= "" then + print(">>", tpr, "<<") if not stringfind(tpr,"/ExtGState<<.*>>") then tpr = tpr.."/ExtGState<<>>" end tpr = stringgsub(tpr,"/ExtGState<<","%1"..t) - tex.pdfpageresources = tpr + texset("global", "pdfpageresources", tpr) + print(">>", tpr, "<<") end res = nil -- reset res end @@ -300,6 +302,11 @@ local color_callback_activated = 0 --- unit -> unit add_color_callback = function ( ) + local color_callback = config.luaotfload.run.color_callback + if not color_callback then + color_callback = "pre_linebreak_filter" + end + if color_callback_activated == 0 then luatexbase.add_to_callback(color_callback, color_handler, diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua new file mode 100644 index 00000000000..dfa222c9070 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua @@ -0,0 +1,704 @@ +#!/usr/bin/env texlua +------------------------------------------------------------------------------- +-- FILE: luaotfload-configuration.lua +-- DESCRIPTION: config file reader +-- REQUIREMENTS: Luaotfload 2.5 or above +-- AUTHOR: Philipp Gesang (Phg), +-- VERSION: same as Luaotfload +-- MODIFIED: 2014-07-13 14:19:32+0200 +------------------------------------------------------------------------------- +-- + +if not modules then modules = { } end modules ["luaotfload-configuration"] = { + version = "2.5", + comment = "part of Luaotfload", + author = "Philipp Gesang", + copyright = "Luaotfload Development Team", + license = "GNU GPL v2.0" +} + +luaotfload = luaotfload or { } +config = config or { } +config.luaotfload = { } + +local status_file = "luaotfload-status" +local luaotfloadstatus = require (status_file) + +local string = string +local stringsub = string.sub +local stringexplode = string.explode +local stringstrip = string.strip +local stringfind = string.find + +local table = table +local tableappend = table.append +local tablecopy = table.copy +local tableconcat = table.concat +local tabletohash = table.tohash + +local math = math +local mathfloor = math.floor + +local io = io +local ioloaddata = io.loaddata +local iopopen = io.popen + +local os = os +local osgetenv = os.getenv + +local lpeg = require "lpeg" +local lpegmatch = lpeg.match +local commasplitter = lpeg.splitat "," +local equalssplitter = lpeg.splitat "=" + +local kpse = kpse +local kpseexpand_path = kpse.expand_path +local kpselookup = kpse.lookup + +local lfs = lfs +local lfsisfile = lfs.isfile +local lfsisdir = lfs.isdir + +local file = file +local filejoin = file.join +local filereplacesuffix = file.replacesuffix + + +local parsers = luaotfload.parsers + +local log = luaotfload.log +local logreport = log.report + +local config_parser = parsers.config +local stripslashes = parsers.stripslashes + +local getwritablepath = caches.getwritablepath + +------------------------------------------------------------------------------- +--- SETTINGS +------------------------------------------------------------------------------- + +local path_t = 0 +local kpse_t = 1 + +local val_home = kpseexpand_path "~" +local val_xdg_config_home = kpseexpand_path "$XDG_CONFIG_HOME" + +if val_xdg_config_home == "" then val_xdg_config_home = "~/.config" end + +local config_paths = { + --- needs adapting for those other OS + { path_t, "./luaotfload.conf" }, + { path_t, "./luaotfloadrc" }, + { path_t, filejoin (val_xdg_config_home, "luaotfload/luaotfload.conf") }, + { path_t, filejoin (val_xdg_config_home, "luaotfload/luaotfloadrc") }, + { path_t, filejoin (val_home, ".luaotfloadrc") }, + { kpse_t, "luaotfloadrc" }, + { kpse_t, "luaotfload.conf" }, +} + +local valid_formats = tabletohash { + "otf", "ttc", "ttf", "dfont", "afm", "pfb", "pfa", +} + +local feature_presets = { + arab = tabletohash { + "ccmp", "locl", "isol", "fina", "fin2", + "fin3", "medi", "med2", "init", "rlig", + "calt", "liga", "cswh", "mset", "curs", + "kern", "mark", "mkmk", + }, + deva = tabletohash { + "ccmp", "locl", "init", "nukt", "akhn", + "rphf", "blwf", "half", "pstf", "vatu", + "pres", "blws", "abvs", "psts", "haln", + "calt", "blwm", "abvm", "dist", "kern", + "mark", "mkmk", + }, + khmr = tabletohash { + "ccmp", "locl", "pref", "blwf", "abvf", + "pstf", "pres", "blws", "abvs", "psts", + "clig", "calt", "blwm", "abvm", "dist", + "kern", "mark", "mkmk", + }, + thai = tabletohash { + "ccmp", "locl", "liga", "kern", "mark", + "mkmk", + }, +} + + + +------------------------------------------------------------------------------- +--- DEFAULTS +------------------------------------------------------------------------------- + +local default_config = { + db = { + formats = "otf,ttf,ttc,dfont", + scan_local = false, + skip_read = false, + strip = true, + update_live = true, + compress = true, + max_fonts = 2^51, + }, + run = { + resolver = "cached", + definer = "patch", + log_level = 0, + color_callback = "pre_linebreak_filter", + }, + misc = { + bisect = false, + version = luaotfload.version, + statistics = false, + termwidth = nil, + }, + paths = { + names_dir = "names", + cache_dir = "fonts", + index_file = "luaotfload-names.lua", + lookups_file = "luaotfload-lookup-cache.lua", + lookup_path_lua = nil, + lookup_path_luc = nil, + index_path_lua = nil, + index_path_luc = nil, + }, + default_features = { + global = { mode = "node" }, + dflt = tabletohash { + "ccmp", "locl", "rlig", "liga", "clig", + "kern", "mark", "mkmk", 'itlc', + }, + + arab = feature_presets.arab, + syrc = feature_presets.arab, + mong = feature_presets.arab, + nko = feature_presets.arab, + + deva = feature_presets.deva, + beng = feature_presets.deva, + guru = feature_presets.deva, + gujr = feature_presets.deva, + orya = feature_presets.deva, + taml = feature_presets.deva, + telu = feature_presets.deva, + knda = feature_presets.deva, + mlym = feature_presets.deva, + sinh = feature_presets.deva, + + khmr = feature_presets.khmr, + tibt = feature_presets.khmr, + thai = feature_presets.thai, + lao = feature_presets.thai, + + hang = tabletohash { "ccmp", "ljmo", "vjmo", "tjmo", }, + }, +} + +------------------------------------------------------------------------------- +--- RECONFIGURATION TASKS +------------------------------------------------------------------------------- + +--[[doc-- + + Procedures to be executed in order to put the new configuration into effect. + +--doc]]-- + +local reconf_tasks = nil + +local min_terminal_width = 40 + +--- The “termwidth” value is only considered when printing +--- short status messages, e.g. when building the database +--- online. +local check_termwidth = function () + if config.luaotfload.misc.termwidth == nil then + local tw = 79 + if not ( os.type == "windows" --- Assume broken terminal. + or osgetenv "TERM" == "dumb") + then + local p = iopopen "tput cols" + if p then + result = tonumber (p:read "*all") + p:close () + if result then + tw = result + else + logreport ("log", 2, "db", "tput returned non-number.") + end + else + logreport ("log", 2, "db", "Shell escape disabled or tput executable missing.") + logreport ("log", 2, "db", "Assuming 79 cols terminal width.") + end + end + config.luaotfload.misc.termwidth = tw + end + return true +end + +local set_font_filter = function () + local names = fonts.names + if names and names.set_font_filter then + local formats = config.luaotfload.db.formats + if not formats or formats == "" then + formats = default_config.db.formats + end + names.set_font_filter (formats) + end + return true +end + +local set_name_resolver = function () + local names = fonts.names + if names and names.resolve_cached then + --- replace the resolver from luatex-fonts + if config.luaotfload.db.resolver == "cached" then + logreport ("both", 2, "cache", "Caching of name: lookups active.") + names.resolvespec = names.resolve_cached + else + names.resolvespec = names.resolve_name + end + end + return true +end + +local set_loglevel = function () + log.set_loglevel (config.luaotfload.run.log_level) + return true +end + +local build_cache_paths = function () + local paths = config.luaotfload.paths + local prefix = getwritablepath (paths.names_dir, "") + + if not prefix then + luaotfload.error ("Impossible to find a suitable writeable cache...") + return false + end + + prefix = lpegmatch (stripslashes, prefix) + logreport ("log", 0, "conf", "Root cache directory is %s.", prefix) + + local index_file = filejoin (prefix, paths.index_file) + local lookups_file = filejoin (prefix, paths.lookups_file) + + paths.prefix = prefix + paths.index_path_lua = filereplacesuffix (index_file, "lua") + paths.index_path_luc = filereplacesuffix (index_file, "luc") + paths.lookup_path_lua = filereplacesuffix (lookups_file, "lua") + paths.lookup_path_luc = filereplacesuffix (lookups_file, "luc") + return true +end + + +local set_default_features = function () + local default_features = config.luaotfload.default_features + luaotfload.features = luaotfload.features or { + global = { }, + defaults = { }, + } + current_features = luaotfload.features + for var, val in next, default_features do + if var == "global" then + current_features.global = val + else + current_features.defaults[var] = val + end + end + return true +end + + +reconf_tasks = { + { "Set the log level" , set_loglevel }, + { "Build cache paths" , build_cache_paths }, + { "Check terminal dimensions" , check_termwidth }, + { "Set the font filter" , set_font_filter }, + { "Install font name resolver", set_name_resolver }, + { "Set default features" , set_default_features }, +} + +------------------------------------------------------------------------------- +--- OPTION SPECIFICATION +------------------------------------------------------------------------------- + +local string_t = "string" +local table_t = "table" +local number_t = "number" +local boolean_t = "boolean" +local function_t = "function" + +local tointeger = function (n) + n = tonumber (n) + if n then + return mathfloor (n + 0.5) + end +end + +local toarray = function (s) + local fields = { lpegmatch (commasplitter, s) } + local ret = { } + for i = 1, #fields do + local field = stringstrip (fields[i]) + if field and field ~= "" then + ret[#ret + 1] = field + end + end + return ret +end + +local tohash = function (s) + local result = { } + local fields = toarray (s) + for _, field in next, fields do + local var, val + if stringfind (field, "=") then + local tmp + var, tmp = lpegmatch (equalssplitter, field) + if tmp == "true" or tmp == "yes" then val = true else val = tmp end + else + var, val = field, true + end + result[var] = val + end + return result +end + +local option_spec = { + db = { + formats = { + in_t = string_t, + out_t = string_t, + transform = function (f) + local fields = toarray (f) + + --- check validity + if not fields then + logreport ("both", 0, "conf", + "Expected list of identifiers, got %q.", f) + return nil + end + + --- strip dupes + local known = { } + local result = { } + for i = 1, #fields do + local field = fields[i] + if known[field] ~= true then + --- yet unknown, tag as seen + known[field] = true + --- include in output if valid + if valid_formats[field] == true then + result[#result + 1] = field + else + logreport ("both", 4, "conf", + "Invalid font format identifier %q, ignoring.", + field) + end + end + end + if #result == 0 then + --- force defaults + return nil + end + return tableconcat (result, ",") + end + }, + scan_local = { in_t = boolean_t, }, + skip_read = { in_t = boolean_t, }, + strip = { in_t = boolean_t, }, + update_live = { in_t = boolean_t, }, + compress = { in_t = boolean_t, }, + max_fonts = { + in_t = number_t, + out_t = number_t, --- TODO int_t from 5.3.x on + transform = tointeger, + }, + }, + run = { + resolver = { + in_t = string_t, + out_t = string_t, + transform = function (r) return r == "normal" and r or "cached" end, + }, + definer = { + in_t = string_t, + out_t = string_t, + transform = function (d) return d == "generic" and d or "patch" end, + }, + log_level = { + in_t = number_t, + out_t = number_t, --- TODO int_t from 5.3.x on + transform = tointeger, + }, + color_callback = { + in_t = string_t, + out_t = string_t, + transform = function (cb) + --- These are the two that make sense. + return cb == "pre_output_filter" and cb or "pre_linebreak_filter" + end, + }, + }, + misc = { + bisect = { in_t = boolean_t, }, --- doesn’t make sense in a config file + version = { in_t = string_t, }, + statistics = { in_t = boolean_t, }, + termwidth = { + in_t = number_t, + out_t = number_t, + transform = function (w) + w = tointeger (w) + if w < min_terminal_width then + return min_terminal_width + end + return w + end, + }, + }, + paths = { + names_dir = { in_t = string_t, }, + cache_dir = { in_t = string_t, }, + index_file = { in_t = string_t, }, + lookups_file = { in_t = string_t, }, + lookup_path_lua = { in_t = string_t, }, + lookup_path_luc = { in_t = string_t, }, + index_path_lua = { in_t = string_t, }, + index_path_luc = { in_t = string_t, }, + }, + default_features = { + __default = { in_t = string_t, out_t = table_t, transform = tohash, }, + }, +} + +------------------------------------------------------------------------------- +--- MAIN FUNCTIONALITY +------------------------------------------------------------------------------- + +--[[doc-- + + tilde_expand -- Rudimentary tilde expansion; covers just the “substitute ‘~’ + by the current users’s $HOME” part. + +--doc]]-- + +local tilde_expand = function (p) + if #p > 2 then + if stringsub (p, 1, 2) == "~/" then + local homedir = osgetenv "HOME" + if homedir and lfsisdir (homedir) then + p = filejoin (homedir, stringsub (p, 3)) + end + end + end + return p +end + +local resolve_config_path = function () + for i = 1, #config_paths do + local t, p = unpack (config_paths[i]) + local fullname + if t == kpse_t then + fullname = kpse.lookup (p) + logreport ("both", 6, "conf", "kpse lookup: %s -> %s.", p, fullname) + elseif t == path_t then + local expanded = tilde_expand (p) + if lfsisfile (expanded) then + fullname = expanded + end + logreport ("both", 6, "conf", "path lookup: %s -> %s.", p, fullname) + end + if fullname then + logreport ("both", 3, "conf", "Reading configuration file at %q.", fullname) + return fullname + end + end + logreport ("both", 2, "conf", "No configuration file found.") + return false +end + +local add_config_paths = function (t) + if not next (t) then + return + end + local result = { } + for i = 1, #t do + local path = t[i] + result[#result + 1] = { path_t, path } + end + config_paths = tableappend (result, config_paths) +end + +local process_options = function (opts) + local new = { } + for i = 1, #opts do + local section = opts[i] + local title = section.section.title + local vars = section.variables + + if not title then --- trigger warning: arrow code ahead + logreport ("both", 2, "conf", "Section %d lacks a title; skipping.", i) + elseif not vars then + logreport ("both", 2, "conf", "Section %d (%s) lacks a variable section; skipping.", i, title) + else + local spec = option_spec[title] + if not spec then + logreport ("both", 2, "conf", "Section %d (%s) unknown; skipping.", i, title) + else + local newsection = new[title] + if not newsection then + newsection = { } + new[title] = newsection + end + + for var, val in next, vars do + local vspec = spec[var] or spec.__default + local t_val = type (val) + if not vspec then + logreport ("both", 2, "conf", + "Section %d (%s): invalid configuration variable %q (%q); ignoring.", + i, title, + var, tostring (val)) + elseif t_val ~= vspec.in_t then + logreport ("both", 2, "conf", + "Section %d (%s): type mismatch of input value %q (%q, %s != %s); ignoring.", + i, title, + var, tostring (val), t_val, vspec.in_t) + else --- type matches + local transform = vspec.transform + if transform then + local dval + local t_transform = type (transform) + if t_transform == function_t then + dval = transform (val) + elseif t_transform == table_t then + dval = transform[val] + end + if dval then + local out_t = vspec.out_t + if out_t then + local t_dval = type (dval) + if t_dval == out_t then + newsection[var] = dval + else + logreport ("both", 2, "conf", + "Section %d (%s): type mismatch of derived value of %q (%q, %s != %s); ignoring.", + i, title, + var, tostring (dval), t_dval, out_t) + end + else + newsection[var] = dval + end + else + logreport ("both", 2, "conf", + "Section %d (%s): value of %q could not be derived via %s from input %q; ignoring.", + i, title, var, t_transform, tostring (val)) + end + else --- insert as is + newsection[var] = val + end + end + end + end + end + end + return new +end + +local apply +apply = function (old, new) + if not new then + if not old then + return false + end + return tablecopy (old) + elseif not old then + return tablecopy (new) + end + local result = tablecopy (old) + for name, section in next, new do + local t_section = type (section) + if t_section ~= table_t then + logreport ("both", 1, "conf", + "Error applying configuration: entry %s is %s, expected table.", + section, t_section) + --- ignore + else + local currentsection = result[name] + for var, val in next, section do + currentsection[var] = val + end + end + end + result.status = luaotfloadstatus + return result +end + +local reconfigure = function () + for i = 1, #reconf_tasks do + local name, task = unpack (reconf_tasks[i]) + logreport ("both", 3, "conf", "Launch post-configuration task %q.", name) + if not task () then + logreport ("both", 0, "conf", "Post-configuration task %q failed.", name) + return false + end + end + return true +end + +local read = function (extra) + if extra then + add_config_paths (extra) + end + + local readme = resolve_config_path () + if readme == false then + logreport ("both", 2, "conf", "No configuration file.") + return false + end + + local raw = ioloaddata (readme) + if not raw then + logreport ("both", 2, "conf", "Error reading the configuration file %q.", readme) + return false + end + + local parsed = lpegmatch (parsers.config, raw) + if not parsed then + logreport ("both", 2, "conf", "Error parsing configuration file %q.", readme) + return false + end + + local ret, msg = process_options (parsed) + if not ret then + logreport ("both", 2, "conf", "File %q is not a valid configuration file.", readme) + logreport ("both", 2, "conf", "Error: %s", msg) + return false + end + return ret +end + +local apply_defaults = function () + local defaults = default_config + local vars = read () + --- Side-effects galore ... + config.luaotfload = apply (defaults, vars) + return reconfigure () +end + +------------------------------------------------------------------------------- +--- EXPORTS +------------------------------------------------------------------------------- + +luaotfload.default_config = default_config + +config.actions = { + read = read, + apply = apply, + apply_defaults = apply_defaults, + reconfigure = reconfigure, +} + diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua index cb3ec330e35..7a01ca626bf 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua @@ -1,9 +1,9 @@ if not modules then modules = { } end modules ['luaotfload-database'] = { - version = "2.4", - comment = "companion to luaotfload.lua", + version = "2.5", + comment = "companion to luaotfload-main.lua", author = "Khaled Hosny, Elie Roux, Philipp Gesang", copyright = "Luaotfload Development Team", - license = "GNU GPL v2" + license = "GNU GPL v2.0" } --[[doc-- @@ -36,13 +36,20 @@ if not modules then modules = { } end modules ['luaotfload-database'] = { --doc]]-- -local lpeg = require "lpeg" +local lpeg = require "lpeg" +local P, Cc, lpegmatch = lpeg.P, lpeg.Cc, lpeg.match -local P, R, S, lpegmatch - = lpeg.P, lpeg.R, lpeg.S, lpeg.match +local parsers = luaotfload.parsers +local read_fonts_conf = parsers.read_fonts_conf +local stripslashes = parsers.stripslashes +local splitcomma = parsers.splitcomma + +local log = luaotfload.log +local report = log.report +local report_status = log.names_status +local report_status_start = log.names_status_start +local report_status_stop = log.names_status_stop -local C, Cc, Cf, Cg, Cs, Ct - = lpeg.C, lpeg.Cc, lpeg.Cf, lpeg.Cg, lpeg.Cs, lpeg.Ct --- Luatex builtins local load = load @@ -60,7 +67,6 @@ local iolines = io.lines local ioopen = io.open local iopopen = io.popen local kpseexpand_path = kpse.expand_path -local kpseexpand_var = kpse.expand_var local kpsefind_file = kpse.find_file local kpselookup = kpse.lookup local kpsereadable_file = kpse.readable_file @@ -70,6 +76,7 @@ local lfscurrentdir = lfs.currentdir local lfsdir = lfs.dir local mathabs = math.abs local mathmin = math.min +local osgetenv = os.getenv local osgettimeofday = os.gettimeofday local osremove = os.remove local stringfind = string.find @@ -106,12 +113,12 @@ local stringis_empty = string.is_empty local stringsplit = string.split local stringstrip = string.strip local tableappend = table.append +local tablecontains = table.contains local tablecopy = table.copy local tablefastcopy = table.fastcopy local tabletofile = table.tofile local tabletohash = table.tohash local tableserialize = table.serialize -local runasscript = caches == nil --- the font loader namespace is “fonts”, same as in Context --- we need to put some fallbacks into place for when running --- as a script @@ -119,80 +126,19 @@ fonts = fonts or { } fonts.names = fonts.names or { } fonts.definers = fonts.definers or { } -local luaotfloadconfig = config.luaotfload --- always present -luaotfloadconfig.resolver = luaotfloadconfig.resolver or "normal" -luaotfloadconfig.formats = luaotfloadconfig.formats or "otf,ttf,ttc,dfont" -luaotfloadconfig.strip = luaotfloadconfig.strip == true - ---- this option allows for disabling updates ---- during a TeX run -luaotfloadconfig.update_live = luaotfloadconfig.update_live ~= false -luaotfloadconfig.compress = luaotfloadconfig.compress ~= false - local names = fonts.names local name_index = nil --> upvalue for names.data local lookup_cache = nil --> for names.lookups -names.version = 2.41 +names.version = 2.51 names.data = nil --- contains the loaded database names.lookups = nil --- contains the lookup cache -names.path = { index = { }, lookups = { } } -names.path.globals = { - prefix = "", --- writable_path/names_dir - names_dir = luaotfloadconfig.names_dir or "names", - index_file = luaotfloadconfig.index_file - or "luaotfload-names.lua", - lookups_file = "luaotfload-lookup-cache.lua", -} - --- string -> (string * string) local make_luanames = function (path) return filereplacesuffix(path, "lua"), filereplacesuffix(path, "luc") end -local report = logs.names_report -local report_status = logs.names_status -local report_status_start = logs.names_status_start -local report_status_stop = logs.names_status_stop - ---- The “termwidth” value is only considered when printing ---- short status messages, e.g. when building the database ---- online. -if not luaotfloadconfig.termwidth then - local tw = 79 - if not ( os.type == "windows" --- Assume broken terminal. - or os.getenv "TERM" == "dumb") - then - local p = iopopen "tput cols" - if p then - result = tonumber (p:read "*all") - p:close () - if result then - tw = result - else - report ("log", 2, "db", "tput returned non-number.") - end - else - report ("log", 2, "db", "Shell escape disabled or tput executable missing.") - report ("log", 2, "db", "Assuming 79 cols terminal width.") - end - end - luaotfloadconfig.termwidth = tw -end - -names.patterns = { } -local patterns = names.patterns - -local trailingslashes = P"/"^1 * P(-1) -local stripslashes = C((1 - trailingslashes)^0) -patterns.stripslashes = stripslashes - -local comma = P"," -local noncomma = 1-comma -local splitcomma = Ct((C(noncomma^1) + comma)^1) -patterns.splitcomma = splitcomma - local format_precedence = { "otf", "ttc", "ttf", "dfont", "afm", "pfb", @@ -208,47 +154,9 @@ local set_location_precedence = function (precedence) end --[[doc-- - We use the functions in the cache.* namespace that come with the - fontloader (see luat-basics-gen). it’s safe to use for the most part - since most checks and directory creations are already done. It - uses TEXMFCACHE or TEXMFVAR as starting points. - - There is one quirk, though: ``getwritablepath()`` will always - assume that files in subdirectories of the cache tree are writable. - It gives no feedback at all if it fails to open a file in write - mode. This may cause trouble when the index or lookup cache were - created by different user. ---doc]]-- - -if not runasscript then - local globals = names.path.globals - local names_dir = globals.names_dir - prefix = getwritablepath (names_dir, "") - if not prefix then - luaotfload.error - ("Impossible to find a suitable writeable cache...") - else - prefix = lpegmatch (stripslashes, prefix) - report ("log", 0, "db", - "Root cache directory is %s.", prefix) - end - - globals.prefix = prefix - local lookup_path = names.path.lookups - local index = names.path.index - local lookups_file = filejoin (prefix, globals.lookups_file) - local index_file = filejoin (prefix, globals.index_file) - lookup_path.lua, lookup_path.luc = make_luanames (lookups_file) - index.lua, index.luc = make_luanames (index_file) -else --- running as script, inject some dummies - caches = { } - logs = { report = function () end } -end + Auxiliary functions - ---[[doc-- -Auxiliary functions --doc]]-- --- fontnames contain all kinds of garbage; as a precaution we @@ -343,7 +251,6 @@ This is a sketch of the luaotfload db: status : filestatus; mappings : fontentry list; meta : metadata; - names : namedata; // TODO: check for relevance after db is finalized } and familytable = { local : (format, familyentry) hash; // specified with include dir @@ -351,21 +258,24 @@ This is a sketch of the luaotfload db: system : (format, familyentry) hash; } and familyentry = { - regular : sizes; - italic : sizes; - bold : sizes; - bolditalic : sizes; + r : sizes; // regular + i : sizes; // italic + b : sizes; // bold + bi : sizes; // bold italic } and sizes = { default : int; // points into mappings or names optical : (int, int) list; // design size -> index entry } and metadata = { + created : string // creation time formats : string list; // { "otf", "ttf", "ttc", "dfont" } - statistics : TODO; - version : float; + local : bool; (* set if local fonts were added to the db *) + modified : string // modification time + statistics : TODO; // created when built with "--stats" + version : float; // index version } - and filemap = { + and filemap = { // created by generate_filedata() base : { local : (string, int) hash; // basename -> idx system : (string, int) hash; @@ -378,36 +288,36 @@ This is a sketch of the luaotfload db: }; full : (int, string) hash; // idx -> full path } - and fontentry = { - barename : string; - familyname : string; - filename : string; - fontname : string; // <- metadata - fullname : string; // <- metadata - sanitized : { - family : string; - fontstyle_name : string; // <- new in 2.4 - fontname : string; // <- metadata - fullname : string; // <- namedata.names - metafamily : string; - pfullname : string; - prefmodifiers : string; - psname : string; - subfamily : string; - }; - size : int list; - slant : int; - subfont : int; - location : local | system | texmf; - weight : int; - width : int; - units_per_em : int; // mainly 1000, but also 2048 or 256 + and fontentry = { // finalized by collect_families() + basename : string; // file name without path "foo.otf" + conflicts : { barename : int; basename : int }; // filename conflict with font at index; happens with subfonts + familyname : string; // sanitized name of the font family the font belongs to, usually from the names table + fontname : string; // sanitized name of the font + fontstyle_name : string; // the fontstyle_name field returned by fontloader.info() + format : string; // "otf" | "ttf" | "dfont" | "pfa" | "pfb" | "afm" + fullname : string; // sanitized full name of the font including style modifiers + fullpath : string; // path to font in filesystem + index : int; // index in the mappings table + italicangle : float; // italic angle; non-zero with oblique faces + location : string; // "texmf" | "system" | "local" + metafamily : string; // alternative family identifier if appropriate, sanitized + plainname : string; // unsanitized font name + prefmodifiers : string; // sanitized preferred subfamily (names table 14) + psname : string; // PostScript name + size : (false | float * float * float); // if available, size info from the size table converted from decipoints + splainname : string; // sanitized version of the “plainname” field + splitstyle : string; // style information obtained by splitting the full name at the last dash + subfamily : string; // sanitized subfamily (names table 2) + subfont : (int | bool); // integer if font is part of a TrueType collection ("ttc") + version : string; // font version string + weight : int; // usWeightClass } and filestatus = (string, // fullname { index : int list; // pointer into mappings timestamp : int; }) dict -beware that this is a reconstruction and may be incomplete. +beware that this is a reconstruction and may be incomplete or out of +date. Last update: 2014-04-06, describing version 2.51. mtx-fonts has in names.tma: @@ -444,7 +354,10 @@ mtx-fonts has in names.tma: --doc]]-- -local initialize_namedata = function (formats) --- returns dbobj +--- string list -> string option -> dbobj + +local initialize_namedata = function (formats, created) + local now = os.date "%F %T" return { --families = { }, status = { }, -- was: status; map abspath -> mapping @@ -452,7 +365,10 @@ local initialize_namedata = function (formats) --- returns dbobj names = { }, -- files = { }, -- created later meta = { + created = created or now, formats = formats, + ["local"] = false, + modified = now, statistics = { }, version = names.version, }, @@ -536,29 +452,32 @@ local load_lua_file = function (path) end --- define locals in scope -local crude_file_lookup -local crude_file_lookup_verbose +local access_font_index +local collect_families +local font_file_lookup local find_closest local flush_lookup_cache -local ot_fullinfo -local t1_fullinfo -local load_names +local generate_filedata +local get_font_filter +local group_modifiers local load_lookups +local load_names +local getmetadata +local order_design_sizes +local ot_fullinfo local read_blacklist -local read_fonts_conf local reload_db -local resolve_name local resolve_cached local resolve_fullpath -local save_names +local resolve_name local save_lookups -local update_names -local get_font_filter +local save_names local set_font_filter +local t1_fullinfo +local update_names --- state of the database local fonts_reloaded = false -local fonts_read = 0 --- limit output when approximate font matching (luaotfload-tool -F) local fuzzy_limit = 1 --- display closest only @@ -566,15 +485,17 @@ local fuzzy_limit = 1 --- display closest only --- bool? -> dbobj load_names = function (dry_run) local starttime = osgettimeofday () - local foundname, data = load_lua_file (names.path.index.lua) + local foundname, data = load_lua_file (config.luaotfload.paths.index_path_lua) if data then - report ("both", 2, "db", - "Font names database loaded", "%s", foundname) + report ("log", 0, "db", + "Font names database loaded from %s", foundname) + report ("term", 3, "db", + "Font names database loaded from %s", foundname) report ("info", 3, "db", "Loading took %0.f ms.", 1000 * (osgettimeofday () - starttime)) - local db_version, nms_version + local db_version, names_version if data.meta then db_version = data.meta.version else @@ -583,11 +504,11 @@ load_names = function (dry_run) --- an earlier index version broke. db_version = data.version or -42 --- invalid end - nms_version = names.version - if db_version ~= nms_version then + names_version = names.version + if db_version ~= names_version then report ("both", 0, "db", [[Version mismatch; expected %4.3f, got %4.3f.]], - nms_version, db_version) + names_version, db_version) if not fonts_reloaded then report ("both", 0, "db", [[Force rebuild.]]) data = update_names ({ }, true, false) @@ -611,11 +532,29 @@ load_names = function (dry_run) return data end +--[[doc-- + + access_font_index -- Provide a reference of the index table. Will + cause the index to be loaded if not present. + +--doc]]-- + +access_font_index = function () + if not name_index then name_index = load_names () end + return name_index +end + +getmetadata = function () + if not name_index then name_index = load_names() end + return tablefastcopy (name_index.meta) +end + --- unit -> unit load_lookups = function ( ) - local foundname, data = load_lua_file(names.path.lookups.lua) + local foundname, data = load_lua_file(config.luaotfload.paths.lookup_path_lua) if data then - report("both", 3, "cache", + report("log", 0, "cache", "Lookup cache loaded from %s.", foundname) + report("term", 3, "cache", "Lookup cache loaded from %s.", foundname) else report("both", 1, "cache", @@ -650,57 +589,10 @@ local style_category = { i = "italic", } -local type1_formats = { "tfm", "ofm", } +local type1_metrics = { "tfm", "ofm", } local dummy_findfile = resolvers.findfile -- from basics-gen ---- filemap -> string -> string -> (string | bool) -local verbose_lookup = function (data, kind, filename) - local found = data[kind][filename] - if found ~= nil then - found = data.full[found] - if found == nil then --> texmf - report("info", 0, "db", - "Crude file lookup: req=%s; hit=%s => kpse.", - filename, kind) - found = dummy_findfile(filename) - else - report("info", 0, "db", - "Crude file lookup: req=%s; hit=%s; ret=%s.", - filename, kind, found) - end - return found - end - return false -end - ---- string -> (string * string * bool) -crude_file_lookup_verbose = function (filename) - if not name_index then name_index = load_names() end - local mappings = name_index.mappings - local files = name_index.files - local found - - --- look up in db first ... - found = verbose_lookup(files, "bare", filename) - if found then - return found, nil, true - end - found = verbose_lookup(files, "base", filename) - if found then - return found, nil, true - end - - --- ofm and tfm, returns pair - for i=1, #type1_formats do - local format = type1_formats[i] - if resolvers.findfile(filename, format) then - return file.addsuffix(filename, format), format, true - end - end - return filename, nil, false -end - local lookup_filename = function (filename) if not name_index then name_index = load_names () end local files = name_index.files @@ -736,8 +628,18 @@ local lookup_filename = function (filename) end end ---- string -> (string * string * bool) -crude_file_lookup = function (filename) +--[[doc-- + + font_file_lookup -- The ``file:`` are ultimately delegated here. + The lookups are kind of a blunt instrument since they try locating + the file using every conceivable method, which is quite + inefficient. Nevertheless, resolving files that way is rarely the + bottleneck. + +--doc]]-- + +--- string -> string * string * bool +font_file_lookup = function (filename) local found = lookup_filename (filename) if not found then @@ -748,21 +650,37 @@ crude_file_lookup = function (filename) return found, nil, true end - for i=1, #type1_formats do - local format = type1_formats[i] + for i=1, #type1_metrics do + local format = type1_metrics[i] if resolvers.findfile(filename, format) then return file.addsuffix(filename, format), format, true end end + if not fonts_reloaded and config.luaotfload.db.update_live == true then + return reload_db (stringformat ("File not found: %s.", filename), + font_file_lookup, + filename) + end return filename, nil, false end --[[doc-- -Existence of the resolved file name is verified differently depending -on whether the index entry has a texmf flag set. + + get_font_file -- Look up the file of an entry in the mappings + table. If the index is valid, pass on the name and subfont index + after verifing the existence of the resolved file. This + verification differs depending the index entry’s ``location`` + field: + + * ``texmf`` fonts are verified using the (slow) function + ``kpse.lookup()``; + * other locations are tested by resolving the full path and + checking for the presence of a file there. + --doc]]-- +--- int -> bool * (string * int) option local get_font_file = function (index) local entry = name_index.mappings [index] if not entry then @@ -809,29 +727,20 @@ We’ll just store successful name: lookups in a separate cache file. type lookup_cache = (string, (string * num)) dict -Complete, needs testing: - × 1) add cache to dbobj - × 2) wrap lookups in cached versions - × 3) make caching optional (via the config table) for debugging - × 4) make names_update() cache aware (nil if “force”) - × 5) add logging - × 6) add cache control to luaotfload-tool - × 7) incr db version (now 2.203) - × 8) save cache only at the end of a run - -The spec is modified in place (ugh), so we’ll have to catalogue what -fields actually influence its behavior. +The spec is expected to be modified in place (ugh), so we’ll have to +catalogue what fields actually influence its behavior. Idk what the “spec” resolver is for. lookup inspects modifies + ---------- ----------------- --------------------------- file: name forced, name - name:* name, style, sub, resolved, sub, name, forced + name:[*] name, style, sub, resolved, sub, name, forced optsize, size spec: name, sub resolved, sub, name, forced -* name: contains both the name resolver from luatex-fonts and - resolve_name() below +[*] name: contains both the name resolver from luatex-fonts and + resolve_name() below From my reading of font-def.lua, what a resolver does is basically rewrite the “name” field of the specification record @@ -1178,13 +1087,11 @@ resolve_name = function (specification) name, style) end - if not resolved then - resolved = specification.name, false - end if not resolved then - if not fonts_reloaded then - return reload_db ("Font not found.", + if not fonts_reloaded and config.luaotfload.db.update_live == true then + return reload_db (stringformat ("Font %s not found.", + specification.name or ""), resolve_name, specification) end @@ -1225,7 +1132,7 @@ reload_db = function (why, caller, ...) local namedata = name_index local formats = tableconcat (namedata.meta.formats, ",") - report ("both", 1, "db", + report ("both", 0, "db", "Reload initiated (formats: %s); reason: %q.", formats, why) @@ -1277,7 +1184,7 @@ find_closest = function (name, limit) if not name_index then name_index = load_names () end if not name_index or type (name_index) ~= "table" then if not fonts_reloaded then - return reload_db("no database", find_closest, name) + return reload_db("Font index missing.", find_closest, name) end return false end @@ -1345,10 +1252,18 @@ end --- find_closest() regarding the omission of ``fontloader.close()``. + TODO -- check if fontloader.info() is ready for prime in 0.78+ + -- fields /tables needed: + -- names + -- postscriptname + -- validation_state + -- .. + --doc]]-- local load_font_file = function (filename, subfont) local rawfont, _msg = fontloaderopen (filename, subfont) + --local rawfont, _msg = fontloaderinfo (filename, subfont) if not rawfont then report ("log", 1, "db", "ERROR: failed to open %s.", filename) return @@ -1379,42 +1294,87 @@ local get_size_info = function (metadata) return false end -local get_english_names = function (names, basename) - +local get_english_names = function (metadata) + local names = metadata.names local english_names if names then --inspect(names) for _, raw_namedata in next, names do if raw_namedata.lang == "English (US)" then - english_names = raw_namedata.names + return raw_namedata.names end end - else - -- no names table, probably a broken font - report("log", 1, "db", - "Broken font %s rejected due to missing names table.", + end + + -- no (English) names table, probably a broken font + report("both", 3, "db", + "%s: missing or broken English names table.", basename) + return { fontname = metadata.fontname, + fullname = metadata.fullname, } +end + +--[[-- + In case of broken PS names we set some dummies. However, we cannot + directly modify the font data as returned by fontloader.open() because + it is a userdata object. + + For this reason we copy what is necessary whilst keeping the table + structure the same as in the tfmdata. +--]]-- +local get_raw_info = function (metadata, basename) + local fullname + local fontname = metadata.fontname + local fullname = metadata.fullname + local psname + + local validation_state = metadata.validation_state + if (validation_state and tablecontains (validation_state, "bad_ps_fontname")) + or not fontname + then + --- Broken names table, e.g. avkv.ttf with UTF-16 strings; + --- we put some dummies in place like the fontloader + --- (font-otf.lua) does. + report("both", 3, "db", + "%s has invalid postscript font names, using dummies.", basename) + fontname = "bad-fontname-" .. basename + fullname = "bad-fullname-" .. basename end - return english_names or { } + return { + familyname = metadata.familyname, + fontname = fontname, + fontstyle_name = metadata.fontstyle_name, + fullname = fullname, + italicangle = metadata.italicangle, + names = metadata.names, + pfminfo = metadata.pfminfo, + units_per_em = metadata.units_per_em, + version = metadata.version, + design_size = metadata.design_size, + design_range_top = metadata.design_range_top, + design_range_bottom = metadata.design_range_bottom, + } end -local organize_namedata = function (metadata, +local organize_namedata = function (rawinfo, english_names, basename, info) local default_name = english_names.compatfull or english_names.fullname or english_names.postscriptname - or metadata.fullname - or metadata.fontname - or info.fullname --- TODO check if fontloader.info() is ready for prime + or rawinfo.fullname + or rawinfo.fontname + or info.fullname or info.fontname local default_family = english_names.preffamily or english_names.family - or metadata.familyname + or rawinfo.familyname or info.familyname +-- local default_modifier = english_names.prefmodifiers +-- or english_names.subfamily local fontnames = { --- see --- https://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html @@ -1445,9 +1405,9 @@ local organize_namedata = function (metadata, }, metadata = { - fullname = metadata.fullname, - fontname = metadata.fontname, - familyname = metadata.familyname, + fullname = rawinfo.fullname, + fontname = rawinfo.fontname, + familyname = rawinfo.familyname, }, info = { @@ -1458,14 +1418,14 @@ local organize_namedata = function (metadata, } -- see http://www.microsoft.com/typography/OTSPEC/features_pt.htm#size - if metadata.fontstyle_name then + if rawinfo.fontstyle_name then --- not present in all fonts, often differs from the preferred --- subfamily as well as subfamily fields, e.g. with --- LMSans10-BoldOblique: --- subfamily: “Bold Italic” --- prefmodifiers: “10 Bold Oblique” --- fontstyle_name: “Bold Oblique” - for _, name in next, metadata.fontstyle_name do + for _, name in next, rawinfo.fontstyle_name do if name.lang == 1033 then --- I hate magic numbers fontnames.fontstyle_name = name.name end @@ -1474,11 +1434,10 @@ local organize_namedata = function (metadata, return { sanitized = sanitize_fontnames (fontnames), - fontname = metadata.fontname, - fullname = metadata.fullname, - familyname = metadata.familyname, + fontname = rawinfo.fontname, + fullname = rawinfo.fullname, + familyname = rawinfo.familyname, } - end @@ -1498,23 +1457,16 @@ local organize_styledata = function (fontname, metadata, english_names, info) - local pfminfo = metadata.pfminfo + local pfminfo = metadata.pfminfo or { } local names = metadata.names return { - -- see http://www.microsoft.com/typography/OTSPEC/features_pt.htm#size + --- see http://www.microsoft.com/typography/OTSPEC/features_pt.htm#size size = get_size_info (metadata), - weight = { - pfminfo.weight, -- integer (multiple of 100?) - sanitize_fontname (info.weight), -- style name - }, + weight = pfminfo.weight or 400, split = split_fontname (fontname), width = pfminfo.width, italicangle = metadata.italicangle, --- italicangle = { --- metadata.italicangle, -- float --- info.italicangle, -- truncated to integer point size? --- }, --- this is for querying, see www.ntg.nl/maps/40/07.pdf for details units_per_em = metadata.units_per_em, version = metadata.version, @@ -1541,13 +1493,18 @@ ot_fullinfo = function (filename, return nil end - local english_names = get_english_names (metadata.names, basename) - local namedata = organize_namedata (metadata, + local rawinfo = get_raw_info (metadata, basename) + --- Closing the file manually is a tad faster and more memory + --- efficient than having it closed by the gc + fontloaderclose (metadata) + + local english_names = get_english_names (rawinfo) + local namedata = organize_namedata (rawinfo, english_names, basename, info) local style = organize_styledata (namedata.fontname, - metadata, + rawinfo, english_names, info) @@ -1559,11 +1516,8 @@ ot_fullinfo = function (filename, format = format, names = namedata, style = style, - version = metadata.version, + version = rawinfo.version, } - --- Closing the file manually is a tad faster and more memory - --- efficient than having it closed by the gc - fontloaderclose (metadata) return res end @@ -1626,8 +1580,7 @@ t1_fullinfo = function (filename, _subfont, location, basename, format) size = false, splitstyle = splitstyle, fontstyle_name = style ~= "" and style or weight, - weight = { metadata.pfminfo.weight, - weight }, + weight = metadata.pfminfo.weight or 400, italicangle = italicangle, } end @@ -1946,13 +1899,16 @@ read_blacklist = function () local whitelist = { } if files and type(files) == "table" then - for _,v in next, files do - for line in iolines(v) do + for _, path in next, files do + for line in iolines (path) do line = stringstrip(line) -- to get rid of lines like " % foo" - local first_chr = stringsub(line, 1, 1) --- faster than find + local first_chr = stringsub(line, 1, 1) if first_chr == "%" or stringis_empty(line) then -- comment or empty line elseif first_chr == "-" then + report ("both", 3, "db", + "Whitelisted file %q via %q.", + line, path) whitelist[#whitelist+1] = stringsub(line, 2, -1) else local cmt = stringfind(line, "%%") @@ -1960,7 +1916,9 @@ read_blacklist = function () line = stringsub(line, 1, cmt - 1) end line = stringstrip(line) - report("log", 2, "db", "Blacklisted file %q.", line) + report ("both", 3, "db", + "Blacklisted file %q via %q.", + line, path) blacklist[#blacklist+1] = line end end @@ -2033,9 +1991,6 @@ do get_font_filter = function (formats) return tablefastcopy (current_formats) end - - --- initialize - set_font_filter (luaotfloadconfig.formats) end local process_dir_tree @@ -2138,7 +2093,7 @@ end --- indicates the number of characters already consumed on the --- line. local truncate_string = function (str, restrict) - local tw = luaotfloadconfig.termwidth + local tw = config.luaotfload.misc.termwidth local wd = tw - restrict local len = utf8len (str) if wd - len < 0 then @@ -2148,73 +2103,44 @@ local truncate_string = function (str, restrict) return str end ---[[doc-- - scan_dir() scans a directory and populates the list of fonts - with all the fonts it finds. +--[[doc-- - · dirname : name of the directory to scan - · currentnames : current font db object - · targetnames : font db object to fill - · dry_run : don’t touch anything + collect_font_filenames_dir -- Traverse the directory root at + ``dirname`` looking for font files. Returns a list of {*filename*; + *location*} pairs. --doc]]-- ---- string -> dbobj -> dbobj -> bool -> bool -> (int * int) - -local scan_dir = function (dirname, currentnames, targetnames, - dry_run, location) +--- string -> string -> string * string list +local collect_font_filenames_dir = function (dirname, location) if lpegmatch (p_blacklist, dirname) then report ("both", 4, "db", "Skipping blacklisted directory %s.", dirname) --- ignore - return 0, 0 + return { } end - local found = find_font_files (dirname, location ~= "texmf") + local found = find_font_files (dirname, location ~= "texmf" and location ~= "local") if not found then report ("both", 4, "db", "No such directory: %q; skipping.", dirname) - return 0, 0 + return { } end - report ("both", 4, "db", "Scanning directory %s.", dirname) - local n_new = 0 --- total of fonts collected - local n_found = #found - local max_fonts = luaotfloadconfig.max_fonts - - report ("both", 4, "db", "%d font files detected.", n_found) - for j=1, n_found do - if max_fonts and fonts_read >= max_fonts then - break - end + local nfound = #found + local files = { } + report ("both", 4, "db", + "%d font files detected in %s.", + nfound, dirname) + for j = 1, nfound do local fullname = found[j] - fullname = path_normalize(fullname) - local new - - if dry_run == true then - local truncated = truncate_string (fullname, 43) - report ("log", 2, "db", - "Would have been loading %s.", fullname) - report_status ("term", "db", - "Would have been loading %s", truncated) - else - local truncated = truncate_string (fullname, 32) - report ("log", 2, "db", "Loading font %s.", fullname) - report_status ("term", "db", "Loading font %s", truncated) - local new = read_font_names (fullname, currentnames, - targetnames, texmf) - if new == true then - fonts_read = fonts_read + 1 - n_new = n_new + 1 - end - end + files[#files + 1] = { path_normalize (fullname), location } end - report ("both", 4, "db", "Done. %d fonts indexed in %q.", - n_found, dirname) - return n_found, n_new + return files end + --- string list -> string list local filter_out_pwd = function (dirs) local result = { } @@ -2233,27 +2159,29 @@ end local path_separator = ostype == "windows" and ";" or ":" --[[doc-- - scan_texmf_fonts() scans all fonts in the texmf tree through the - kpathsea variables OPENTYPEFONTS and TTFONTS of texmf.cnf. + + collect_font_filenames_texmf -- Scan texmf tree for font files + relying on the kpathsea variables $OPENTYPEFONTS and $TTFONTS of + texmf.cnf. The current working directory comes as “.” (texlive) or absolute path (miktex) and will always be filtered out. ---doc]]-- ---- dbobj -> dbobj -> bool? -> (int * int) + Returns a list of { *filename*; *location* } pairs. + +--doc]]-- -local scan_texmf_fonts = function (currentnames, targetnames, dry_run) +--- unit -> string * string list +local collect_font_filenames_texmf = function () - local n_scanned, n_new, fontdirs = 0, 0 local osfontdir = kpseexpand_path "$OSFONTDIR" if stringis_empty (osfontdir) then - report ("info", 1, "db", "Scanning TEXMF fonts...") + report ("info", 1, "db", "Scanning TEXMF for fonts...") else - report ("info", 1, "db", "Scanning TEXMF and OS fonts...") - if logs.get_loglevel () > 3 then + report ("info", 1, "db", "Scanning TEXMF and $OSFONTDIR for fonts...") + if log.get_loglevel () > 3 then local osdirs = filesplitpath (osfontdir) - report ("info", 0, "db", - "$OSFONTDIR has %d entries:", #osdirs) + report ("info", 0, "db", "$OSFONTDIR has %d entries:", #osdirs) for i = 1, #osdirs do report ("info", 0, "db", "[%d] %s", i, osdirs[i]) end @@ -2264,255 +2192,22 @@ local scan_texmf_fonts = function (currentnames, targetnames, dry_run) fontdirs = fontdirs .. path_separator .. kpseexpand_path "$TTFONTS" fontdirs = fontdirs .. path_separator .. kpseexpand_path "$T1FONTS" - if not stringis_empty (fontdirs) then - local tasks = filter_out_pwd (filesplitpath (fontdirs)) - report ("info", 3, "db", - "Initiating scan of %d directories.", #tasks) - report_status_start (2, 4) - for _, d in next, tasks do - local found, new = scan_dir (d, currentnames, targetnames, - dry_run, "texmf") - n_scanned = n_scanned + found - n_new = n_new + new - end - report_status_stop ("term", "db", "Scanned %d files, %d new.", n_scanned, n_new) - end - - return n_scanned, n_new -end - ---[[ - For the OS fonts, there are several options: - - if OSFONTDIR is set (which is the case under windows by default but - not on the other OSs), it scans it at the same time as the texmf tree, - in the scan_texmf_fonts. - - if not: - - under Windows and Mac OSX, we take a look at some hardcoded directories - - under Unix, we read /etc/fonts/fonts.conf and read the directories in it - - This means that if you have fonts in fancy directories, you need to set them - in OSFONTDIR. -]] - -local read_fonts_conf -do --- closure for read_fonts_conf() - - local alpha = R("az", "AZ") - local digit = R"09" - local tag_name = C(alpha^1) - local whitespace = S" \n\r\t\v" - local ws = whitespace^1 - local comment = P"" - - ---> header specifica - local xml_declaration = P"")^0 * P"?>" - local xml_doctype = P"")^0 * P">" - local header = xml_declaration^-1 - * (xml_doctype + comment + ws)^0 - - ---> enforce root node - local root_start = P"<" * ws^-1 * P"fontconfig" * ws^-1 * P">" - local root_stop = P"" - - local dquote, squote = P[["]], P"'" - local xml_namestartchar = S":_" + alpha --- ascii only, funk the rest - local xml_namechar = S":._" + alpha + digit - local xml_name = ws^-1 - * C(xml_namestartchar * xml_namechar^0) - local xml_attvalue = dquote * C((1 - S[[%&"]])^1) * dquote * ws^-1 - + squote * C((1 - S[[%&']])^1) * squote * ws^-1 - local xml_attr = Cg(xml_name * P"=" * xml_attvalue) - local xml_attr_list = Cf(Ct"" * xml_attr^1, rawset) - - --[[doc-- - scan_node creates a parser for a given xml tag. - --doc]]-- - --- string -> bool -> lpeg_t - local scan_node = function (tag) - --- Node attributes go into a table with the index “attributes” - --- (relevant for “prefix="xdg"” and the likes). - local p_tag = P(tag) - local with_attributes = P"<" * p_tag - * Cg(xml_attr_list, "attributes")^-1 - * ws^-1 - * P">" - local plain = P"<" * p_tag * ws^-1 * P">" - local node_start = plain + with_attributes - local node_stop = P"" - --- there is no nesting, the earth is flat ... - local node = node_start - * Cc(tag) * C(comment + (1 - node_stop)^1) - * node_stop - return Ct(node) -- returns {string, string [, attributes = { key = val }] } - end - - --[[doc-- - At the moment, the interesting tags are “dir” for - directory declarations, and “include” for including - further configuration files. - - spec: http://freedesktop.org/software/fontconfig/fontconfig-user.html - --doc]]-- - local include_node = scan_node"include" - local dir_node = scan_node"dir" - - local element = dir_node - + include_node - + comment --> ignore - + P(1-root_stop) --> skip byte - - local root = root_start * Ct(element^0) * root_stop - local p_cheapxml = header * root - - --lpeg.print(p_cheapxml) ---> 757 rules with v0.10 - - --[[doc-- - fonts_conf_scanner() handles configuration files. - It is called on an abolute path to a config file (e.g. - /home/luser/.config/fontconfig/fonts.conf) and returns a list - of the nodes it managed to extract from the file. - --doc]]-- - --- string -> path list - local fonts_conf_scanner = function (path) - local fh = ioopen(path, "r") - if not fh then - report("both", 3, "db", "Cannot open fontconfig file %s.", path) - return - end - local raw = fh:read"*all" - fh:close() - - local confdata = lpegmatch(p_cheapxml, raw) - if not confdata then - report("both", 3, "db", "Cannot scan fontconfig file %s.", path) - return - end - return confdata - end - - local p_conf = P".conf" * P(-1) - local p_filter = (1 - p_conf)^1 * p_conf - - local conf_filter = function (path) - if lpegmatch (p_filter, path) then - return true - end - return false + if stringis_empty (fontdirs) then + return { } end - --[[doc-- - read_fonts_conf_indeed() is called with six arguments; the - latter three are tables that represent the state and are - always returned. - The first three are - · the path to the file - · the expanded $HOME - · the expanded $XDG_CONFIG_DIR - --doc]]-- - --- string -> string -> string -> tab -> tab -> (tab * tab * tab) - local read_fonts_conf_indeed - read_fonts_conf_indeed = function (start, home, xdg_home, - acc, done, dirs_done) - - local paths = fonts_conf_scanner(start) - if not paths then --- nothing to do - return acc, done, dirs_done - end - - for i=1, #paths do - local pathobj = paths[i] - local kind, path = pathobj[1], pathobj[2] - local attributes = pathobj.attributes - if attributes and attributes.prefix == "xdg" then - --- this prepends the xdg root (usually ~/.config) - path = filejoin(xdg_home, path) - end - - if kind == "dir" then - if stringsub(path, 1, 1) == "~" then - path = filejoin(home, stringsub(path, 2)) - end - --- We exclude paths with texmf in them, as they should be - --- found anyway; also duplicates are ignored by checking - --- if they are elements of dirs_done. - --- - --- FIXME does this mean we cannot access paths from - --- distributions (e.g. Context minimals) installed - --- separately? - if not (stringfind(path, "texmf") or dirs_done[path]) then - acc[#acc+1] = path - dirs_done[path] = true - end + local tasks = filter_out_pwd (filesplitpath (fontdirs)) + report ("info", 3, "db", + "Initiating scan of %d directories.", #tasks) - elseif kind == "include" then - --- here the path can be four things: a directory or a file, - --- in absolute or relative path. - if stringsub(path, 1, 1) == "~" then - path = filejoin(home, stringsub(path, 2)) - elseif --- if the path is relative, we make it absolute - not ( lfsisfile(path) or lfsisdir(path) ) - then - path = filejoin(filedirname(start), path) - end - if lfsisfile(path) - and kpsereadable_file(path) - and not done[path] - then - --- we exclude path with texmf in them, as they should - --- be found otherwise - acc = read_fonts_conf_indeed( - path, home, xdg_home, - acc, done, dirs_done) - elseif lfsisdir(path) then --- arrow code ahead - local config_files = find_files (path, conf_filter) - for _, filename in next, config_files do - if not done[filename] then - acc = read_fonts_conf_indeed( - filename, home, xdg_home, - acc, done, dirs_done) - end - end - end --- match “kind” - end --- iterate paths - end - - --inspect(acc) - --inspect(done) - return acc, done, dirs_done - end --- read_fonts_conf_indeed() - - --[[doc-- - read_fonts_conf() sets up an accumulator and two sets - for tracking what’s been done. - - Also, the environment variables HOME and XDG_CONFIG_HOME -- - which are constants anyways -- are expanded so don’t have to - repeat that over and over again as with the old parser. - Now they’re just passed on to every call of - read_fonts_conf_indeed(). - - read_fonts_conf() is also the only reference visible outside - the closure. - --doc]]-- - --- list -> list - read_fonts_conf = function (path_list) - local home = kpseexpand_path"~" --- could be os.getenv"HOME" - local xdg_home = kpseexpand_path"$XDG_CONFIG_HOME" - if xdg_home == "" then xdg_home = filejoin(home, ".config") end - local acc = { } ---> list: paths collected - local done = { } ---> set: files inspected - local dirs_done = { } ---> set: dirs in list - for i=1, #path_list do --- we keep the state between files - acc, done, dirs_done = read_fonts_conf_indeed( - path_list[i], home, xdg_home, - acc, done, dirs_done) - end - return acc + local files = { } + for _, dir in next, tasks do + files = tableappend (files, collect_font_filenames_dir (dir, "texmf")) end -end --- read_fonts_conf closure + report ("term", 3, "db", "Collected %d files.", #files) + return files +end ---- TODO stuff those paths into some writable table --- unit -> string list local function get_os_dirs () if os.name == 'macosx' then @@ -2523,14 +2218,14 @@ local function get_os_dirs () "/Network/Library/Fonts", } elseif os.type == "windows" or os.type == "msdos" then - local windir = os.getenv("WINDIR") + local windir = osgetenv("WINDIR") return { filejoin(windir, 'Fonts') } else local fonts_conves = { --- plural, much? "/usr/local/etc/fonts/fonts.conf", "/etc/fonts/fonts.conf", } - local os_dirs = read_fonts_conf(fonts_conves) + local os_dirs = read_fonts_conf(fonts_conves, find_files) return os_dirs end return {} @@ -2538,51 +2233,118 @@ end --[[doc-- - scan_os_fonts() scans the OS fonts through - - fontconfig for Unix (reads the fonts.conf file[s] and scans the - directories) - - a static set of directories for Windows and MacOSX + retrieve_namedata -- Scan the list of collected fonts and populate + the list of namedata. + + · dirname : name of the directory to scan + · currentnames : current font db object + · targetnames : font db object to fill + · dry_run : don’t touch anything - **NB**: If $OSFONTDIR is nonempty, as it appears to be by default - on Windows setups, the system fonts will have already been - processed while scanning the TEXMF. Thus, this function is - never called. + Returns the number of fonts that were actually added to the index. --doc]]-- ---- dbobj -> dbobj -> bool? -> (int * int) -local scan_os_fonts = function (currentnames, - targetnames, - dry_run) +--- string * string list -> dbobj -> dbobj -> bool? -> int +local retrieve_namedata = function (files, currentnames, targetnames, dry_run) + + local nfiles = #files + local nnew = 0 + + report ("info", 1, "db", "Scanning %d collected font files ...", nfiles) + + local bylocation = { texmf = { 0, 0 } + , ["local"] = { 0, 0 } + , system = { 0, 0 } + } + report_status_start (2, 4) + for i = 1, nfiles do + local fullname, location = unpack (files[i]) + local count = bylocation[location] + count[1] = count[1] + 1 + if dry_run == true then + local truncated = truncate_string (fullname, 43) + report ("log", 2, "db", "Would have been loading %s.", fullname) + report_status ("term", "db", "Would have been loading %s", truncated) + --- skip the read_font_names part + else + local truncated = truncate_string (fullname, 32) + report ("log", 2, "db", "Loading font %s.", fullname) + report_status ("term", "db", "Loading font %s", truncated) + local new = read_font_names (fullname, currentnames, + targetnames, location) + if new == true then + nnew = nnew + 1 + count[2] = count[2] + 1 + end + end + end + report_status_stop ("term", "db", "Scanned %d files, %d new.", nfiles, nnew) + for location, count in next, bylocation do + report ("term", 4, "db", " * %s: %d files, %d new", + location, count[1], count[2]) + end + return nnew +end + +--- unit -> string * string list +local collect_font_filenames_system = function () local n_scanned, n_new = 0, 0 - report ("info", 1, "db", "Scanning OS fonts...") + report ("info", 1, "db", "Scanning system fonts...") report ("info", 2, "db", "Searching in static system directories...") - report_status_start (2, 4) - for _, d in next, get_os_dirs () do - local found, new = scan_dir (d, currentnames, - targetnames, dry_run) - n_scanned = n_scanned + found - n_new = n_new + new + local files = { } + for _, dir in next, get_os_dirs () do + tableappend (files, collect_font_filenames_dir (dir, "system")) end - report_status_stop ("term", "db", "Scanned %d files, %d new.", n_scanned, n_new) - - return n_scanned, n_new + report ("term", 3, "db", "Collected %d files.", #files) + return files end ---- unit -> (bool, lookup_cache) +--- unit -> bool flush_lookup_cache = function () lookup_cache = { } collectgarbage "collect" - return true, lookup_cache + return true +end + +--[[doc-- + + collect_font_filenames_local -- Scan $PWD (during a TeX run) + for font files. + + Side effect: This sets the “local” flag in the subtable “meta” to + prevent the merged table from being saved to disk. + + TODO the local tree could be cached in $PWD. + +--doc]]-- + +--- unit -> string * string list +local collect_font_filenames_local = function () + local pwd = lfscurrentdir () + report ("both", 1, "db", "Scanning for fonts in $PWD (%q) ...", pwd) + + local files = collect_font_filenames_dir (pwd, "local") + local nfiles = #files + if nfiles > 0 then + targetnames.meta["local"] = true --- prevent saving to disk + report ("term", 1, "db", "Found %d files.", pwd) + else + report ("term", 1, "db", + "Couldn’t find a thing here. What a waste.", pwd) + end + report ("term", 3, "db", "Collected %d files.", #files) + return files end +--- dbobj -> dbobj -> int * int --- fontentry list -> filemap -local generate_filedata = function (mappings) +generate_filedata = function (mappings) report ("both", 2, "db", "Creating filename map.") @@ -2715,11 +2477,16 @@ do local splitfontname = lpeg.splitat "-" local choose_exact = function (field) + --- only clean matches, without guessing if italic_synonym [field] then return "i" - elseif field == "bold" then + end + + if field == "bold" then return "b" - elseif field == "bolditalic" or field == "boldoblique" then + end + + if field == "bolditalic" or field == "boldoblique" then return "bi" end @@ -2741,19 +2508,30 @@ do style = choose_exact (subfamily) end end --- if not style and splitstyle then --- style = choose_exact (splitstyle) --- end return style end + pick_fallback_style = function (italicangle, weight) + --- more aggressive, but only to determine bold faces + if weight > 500 then --- bold spectrum matches + if italicangle == 0 then + return tostring (weight) + else + return tostring (weight) .. "i" + end + end + return false + end + --- we use only exact matches here since there are constructs --- like “regularitalic” (Cabin, Bodoni Old Fashion) check_regular = function (fontstyle_name, prefmodifiers, subfamily, - splitstyle) + splitstyle, + italicangle, + weight) if fontstyle_name then return regular_synonym [fontstyle_name] @@ -2763,6 +2541,8 @@ do return regular_synonym [subfamily] elseif splitstyle then return regular_synonym [splitstyle] + elseif italicangle == 0 and weight == 400 then + return true end return nil @@ -2786,7 +2566,7 @@ local pull_values = function (entry) --- pull name info ... entry.psname = english.psname - entry.fontname = info.fontname + entry.fontname = info.fontname or metadata.fontname entry.fullname = english.fullname or info.fullname entry.splainname = metadata.fullname entry.prefmodifiers = english.prefmodifiers @@ -2806,7 +2586,7 @@ local pull_values = function (entry) entry.splitstyle = style.split entry.weight = style.weight - if luaotfloadconfig.strip == true then + if config.luaotfload.db.strip == true then entry.file = nil entry.names = nil entry.style = nil @@ -2814,7 +2594,7 @@ local pull_values = function (entry) end local add_family = function (name, subtable, modifier, entry) - if not name then + if not name then --- probably borked font return end local familytable = subtable [name] @@ -2823,33 +2603,28 @@ local add_family = function (name, subtable, modifier, entry) subtable [name] = familytable end - --- the style table is treated as an unordered list - local styletable = familytable [modifier] - if not styletable then - styletable = { } - familytable [modifier] = styletable - end + local size = entry.size - if not entry.prefmodifiers then --- default size for this style/family combo - styletable.default = entry.index - end + familytable [#familytable + 1] = { + index = entry.index, + modifier = modifier, + } +end - local size = entry.size --- dsnsize * high * low - if size then - styletable [#styletable + 1] = { - size [1], - size [2], - size [3], - entry.index, - } - else - styletable.default = entry.index +local get_subtable = function (families, entry) + local location = entry.location + local format = entry.format + local subtable = families [location] [format] + if not subtable then + subtable = { } + families [location] [format] = subtable end + return subtable end -local collect_families = function (mappings) +collect_families = function (mappings) - report ("info", 2, "db", "Analyzing families, sizes, and styles.") + report ("info", 2, "db", "Analyzing families.") local families = { ["local"] = { }, @@ -2865,14 +2640,7 @@ local collect_families = function (mappings) pull_values (entry) end - local location = entry.location - local format = entry.format - - local subtable = families [location] [format] - if not subtable then - subtable = { } - families [location] [format] = subtable - end + local subtable = get_subtable (families, entry) local familyname = entry.familyname local metafamily = entry.metafamily @@ -2893,7 +2661,9 @@ local collect_families = function (mappings) modifier = check_regular (fontstyle_name, prefmodifiers, subfamily, - splitstyle) + splitstyle, + italicangle, + weight) end if modifier then @@ -2921,6 +2691,11 @@ local collect_families = function (mappings) -- if metafamily and metafamily ~= familyname then -- add_family (metafamily, subtable, modifier, entry) -- end + elseif weight > 500 then -- in bold spectrum + modifier = pick_fallback_style (italicangle, weight) + if modifier then + add_family (familyname, subtable, modifier, entry) + end end end @@ -2928,11 +2703,121 @@ local collect_families = function (mappings) return families end +--[[doc-- + + group_modifiers -- For not-quite-bold faces, determine whether + they can fill in for a missing bold face slot in a matching family. + + Some families like Lucida do not contain real bold / bold italic + members. Instead, they have semibold variants at weight 600 which + we must add in a separate pass. + +--doc]]-- + +local bold_spectrum_low = 501 --- 500 is medium, 900 heavy/black +local bold_weight = 700 +local style_categories = { "r", "b", "i", "bi" } +local bold_categories = { "b", "bi" } + +group_modifiers = function (mappings, families) + report ("info", 2, "db", "Analyzing shapes, weights, and styles.") + for location, location_data in next, families do + for format, format_data in next, location_data do + for familyname, collected in next, format_data do + local styledata = { } --- will replace the “collected” table + --- First, fill in the ordinary style data that + --- fits neatly into the four relevant modifier + --- categories. + for _, modifier in next, style_categories do + local entries + for key, info in next, collected do + if info.modifier == modifier then + if not entries then + entries = { } + end + local index = info.index + local entry = mappings [index] + local size = entry.size + if size then + entries [#entries + 1] = { + size [1], + size [2], + size [3], + index, + } + else + entries.default = index + end + collected [key] = nil + end + styledata [modifier] = entries + end + end + + --- At this point the family set may still lack + --- entries for bold or bold italic. We will fill + --- those in using the modifier with the numeric + --- weight that is closest to bold (700). + if next (collected) then --- there are uncategorized entries + for _, modifier in next, bold_categories do + if not styledata [modifier] then + local closest + local minimum = 2^51 + for key, info in next, collected do + local info_modifier = tonumber (info.modifier) and "b" or "bi" + if modifier == info_modifier then + local index = info.index + local entry = mappings [index] + local weight = entry.weight + local diff = weight < 700 and 700 - weight or weight - 700 + if diff < minimum then + minimum = diff + closest = weight + end + end + end + if closest then + --- We know there is a substitute face for the modifier. + --- Now we scan the list again to extract the size data + --- in case the shape is available at multiple sizes. + local entries = { } + for key, info in next, collected do + local info_modifier = tonumber (info.modifier) and "b" or "bi" + if modifier == info_modifier then + local index = info.index + local entry = mappings [index] + local size = entry.size + if entry.weight == closest then + if size then + entries [#entries + 1] = { + size [1], + size [2], + size [3], + index, + } + else + entries.default = index + end + end + end + end + styledata [modifier] = entries + end + end + end + end + format_data [familyname] = styledata + end + end + end + return families +end + local cmp_sizes = function (a, b) return a [1] < b [1] end -local order_design_sizes = function (families) +order_design_sizes = function (families) report ("info", 2, "db", "Ordering design sizes.") @@ -2949,27 +2834,89 @@ local order_design_sizes = function (families) return families end -local retrieve_namedata = function (currentnames, - targetnames, - dry_run, - n_rawnames, - n_newnames) +--[[doc-- - local rawnames, new = scan_texmf_fonts (currentnames, - targetnames, - dry_run) + collect_font_filenames -- Scan the three search path categories for + font files. This constitutes the first pass of the update mode. + +--doc]]-- - n_rawnames = n_rawnames + rawnames - n_newnames = n_newnames + new +--- unit -> string * bool list +local collect_font_filenames = function () - rawnames, new = scan_os_fonts (currentnames, targetnames, dry_run) + report ("info", 4, "db", "Scanning the filesystem for font files.") - n_rawnames = n_rawnames + rawnames - n_newnames = n_newnames + new + local filenames = { } + local bisect = config.luaotfload.misc.bisect + local max_fonts = config.luaotfload.db.max_fonts --- XXX revisit for lua 5.3 wrt integers - return n_rawnames, n_newnames + tableappend (filenames, collect_font_filenames_texmf ()) + tableappend (filenames, collect_font_filenames_system ()) + if config.luaotfload.db.scan_local == true then + tableappend (filenames, collect_font_filenames_local ()) + end + --- Now drop everything above max_fonts. + if max_fonts < #filenames then + filenames = { unpack (filenames, 1, max_fonts) } + end + --- And choose the requested slice if in bisect mode. + if bisect then + return { unpack (filenames, bisect[1], bisect[2]) } + end + return filenames end +--[[doc-- + + nth_font_file -- Return the filename of the nth font. + +--doc]]-- + +--- int -> string +local nth_font_filename = function (n) + report ("info", 4, "db", "Picking font file no. %d.", n) + if not p_blacklist then + read_blacklist () + end + local filenames = collect_font_filenames () + return filenames[n] and filenames[n][1] or "" +end + +--[[doc-- + + font_slice -- Return the fonts in the range from lo to hi. + +--doc]]-- + +local font_slice = function (lo, hi) + report ("info", 4, "db", "Retrieving font files nos. %d--%d.", lo, hi) + if not p_blacklist then + read_blacklist () + end + local filenames = collect_font_filenames () + local result = { } + for i = lo, hi do + result[#result + 1] = filenames[i][1] + end + return result +end + +--[[doc + + count_font_files -- Return the number of files found by + collect_font_filenames. This function is exported primarily + for use with luaotfload-tool.lua in bisect mode. + +--doc]]-- + +--- unit -> int +local count_font_files = function () + report ("info", 4, "db", "Counting font files.") + if not p_blacklist then + read_blacklist () + end + return #collect_font_filenames () +end --- dbobj -> stats @@ -3053,7 +3000,7 @@ local collect_statistics = function (mappings) local n_fullname = setsize (fullname) local n_family = setsize (family) - if logs.get_loglevel () > 1 then + if log.get_loglevel () > 1 then local pprint_top = function (hash, n, set) local freqs = { } @@ -3142,18 +3089,16 @@ end --- dbobj? -> bool? -> bool? -> dbobj update_names = function (currentnames, force, dry_run) - local targetnames - if luaotfloadconfig.update_live == false then + if config.luaotfload.db.update_live == false then report ("info", 2, "db", "Skipping database update.") --- skip all db updates return currentnames or name_index end - local starttime = osgettimeofday () - local n_rawnames, n_newnames = 0, 0 + local starttime = osgettimeofday () --[[ The main function, scans everything @@ -3163,10 +3108,7 @@ update_names = function (currentnames, force, dry_run) report("both", 1, "db", "Updating the font names database" .. (force and " forcefully." or ".")) - --- pass 1 get raw data: read font files (normal case) or reuse - --- information present in index - - if luaotfloadconfig.skip_read == true then + if config.luaotfload.db.skip_read == true then --- the difference to a “dry run” is that we don’t search --- for font files entirely. we also ignore the “force” --- parameter since it concerns only the font files. @@ -3188,22 +3130,28 @@ update_names = function (currentnames, force, dry_run) end end - targetnames = initialize_namedata (get_font_filter ()) + targetnames = initialize_namedata (get_font_filter (), + currentnames.meta and currentnames.meta.created) read_blacklist () - local n_raw, n_new= retrieve_namedata (currentnames, - targetnames, - dry_run, - n_rawnames, - n_newnames) + --- pass 1: Collect the names of all fonts we are going to process. + local font_filenames = collect_font_filenames () + + --- pass 2: read font files (normal case) or reuse information + --- present in index + + n_new = retrieve_namedata (font_filenames, + currentnames, + targetnames, + dry_run) report ("info", 3, "db", - "Scanned %d font files; %d new entries.", - n_rawnames, n_newnames) + "Found %d font files; %d new entries.", + #font_filenames, n_new) end - --- pass 2 (optional): collect some stats about the raw font info - if luaotfloadconfig.statistics == true then + --- pass 3 (optional): collect some stats about the raw font info + if config.luaotfload.misc.statistics == true then targetnames.meta.statistics = collect_statistics (targetnames.mappings) end @@ -3212,13 +3160,17 @@ update_names = function (currentnames, force, dry_run) --- non-texmf entries are redirected there and the mapping --- needs to be 100% consistent - --- pass 3: build filename table + --- pass 4: build filename table targetnames.files = generate_filedata (targetnames.mappings) - --- pass 4: build family lookup table - targetnames.families = collect_families (targetnames.mappings) + --- pass 5: build family lookup table + targetnames.families = collect_families (targetnames.mappings) + + --- pass 6: arrange style and size info + targetnames.families = group_modifiers (targetnames.mappings, + targetnames.families) - --- pass 5: order design size tables + --- pass 7: order design size tables targetnames.families = order_design_sizes (targetnames.families) @@ -3229,25 +3181,29 @@ update_names = function (currentnames, force, dry_run) if dry_run ~= true then - save_names () - - local success, _lookups = flush_lookup_cache () - if success then - local success = save_lookups () - if success then - logs.names_report ("info", 2, "cache", - "Lookup cache emptied.") - return targetnames + if n_new == 0 then + report ("info", 2, "db", "No new fonts found, skip saving to disk.") + else + local success, reason = save_names () + if not success then + report ("both", 0, "db", + "Failed to save database to disk: %s", + reason) end end + + if flush_lookup_cache () and save_lookups () then + report ("both", 2, "cache", "Lookup cache emptied.") + return targetnames + end end return targetnames end --- unit -> bool save_lookups = function ( ) - local path = names.path.lookups - local luaname, lucname = path.lua, path.luc + local paths = config.luaotfload.paths + local luaname, lucname = paths.lookup_path_lua, paths.lookup_path_luc if fileiswritable (luaname) and fileiswritable (lucname) then tabletofile (luaname, lookup_cache, true) osremove (lucname) @@ -3271,17 +3227,22 @@ save_lookups = function ( ) end --- save_names() is usually called without the argument ---- dbobj? -> bool +--- dbobj? -> bool * string option save_names = function (currentnames) if not currentnames then currentnames = name_index end - local path = names.path.index - local luaname, lucname = path.lua, path.luc + if not currentnames or type (currentnames) ~= "table" then + return false, "invalid names table" + elseif currentnames.meta and currentnames.meta["local"] then + return false, "table contains local entries" + end + local paths = config.luaotfload.paths + local luaname, lucname = paths.index_path_lua, paths.index_path_luc if fileiswritable (luaname) and fileiswritable (lucname) then osremove (lucname) local gzname = luaname .. ".gz" - if luaotfloadconfig.compress then + if config.luaotfload.db.compress then local serialized = tableserialize (currentnames, true) save_gzipped (gzname, serialized) caches.compile (currentnames, "", lucname) @@ -3399,7 +3360,7 @@ end local getwritablecachepath = function ( ) --- fonts.handlers.otf doesn’t exist outside a Luatex run, --- so we have to improvise - local writable = getwritablepath (luaotfloadconfig.cache_dir) + local writable = getwritablepath (config.luaotfload.paths.cache_dir) if writable then return writable end @@ -3407,7 +3368,7 @@ end local getreadablecachepaths = function ( ) local readables = caches.getreadablepaths - (luaotfloadconfig.cache_dir) + (config.luaotfload.paths.cache_dir) local result = { } if readables then for i=1, #readables do @@ -3424,7 +3385,7 @@ end local purge_cache = function ( ) local writable_path = getwritablecachepath () local luanames, lucnames, rest = collect_cache(writable_path) - if logs.get_loglevel() > 1 then + if log.get_loglevel() > 1 then print_cache("writable path", writable_path, luanames, lucnames, rest) end local success = purge_from_cache("writable path", writable_path, luanames, false) @@ -3435,7 +3396,7 @@ end local erase_cache = function ( ) local writable_path = getwritablecachepath () local luanames, lucnames, rest, all = collect_cache(writable_path) - if logs.get_loglevel() > 1 then + if log.get_loglevel() > 1 then print_cache("writable path", writable_path, luanames, lucnames, rest) end local success = purge_from_cache("writable path", writable_path, all, true) @@ -3472,36 +3433,31 @@ end --- export functionality to the namespace “fonts.names” ----------------------------------------------------------------------- -names.scan_dir = scan_dir names.set_font_filter = set_font_filter names.flush_lookup_cache = flush_lookup_cache names.save_lookups = save_lookups names.load = load_names +names.access_font_index = access_font_index names.data = function () return name_index end names.save = save_names names.update = update_names -names.crude_file_lookup = crude_file_lookup -names.crude_file_lookup_verbose = crude_file_lookup_verbose +names.font_file_lookup = font_file_lookup names.read_blacklist = read_blacklist names.sanitize_fontname = sanitize_fontname names.getfilename = resolve_fullpath +names.getmetadata = getmetadata names.set_location_precedence = set_location_precedence +names.count_font_files = count_font_files +names.nth_font_filename = nth_font_filename +names.font_slice = font_slice +names.resolve_cached = resolve_cached +names.resolve_name = resolve_name --- font cache names.purge_cache = purge_cache names.erase_cache = erase_cache names.show_cache = show_cache ---- replace the resolver from luatex-fonts -if luaotfloadconfig.resolver == "cached" then - report("both", 2, "cache", "Caching of name: lookups active.") - names.resolvespec = resolve_cached - names.resolve_name = resolve_cached -else - names.resolvespec = resolve_name - names.resolve_name = resolve_name -end - names.find_closest = find_closest -- for testing purpose diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua index 68ed18c456b..80e461ccac5 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua @@ -4,13 +4,11 @@ -- DESCRIPTION: functionality accessible by the --diagnose option -- REQUIREMENTS: luaotfload-tool.lua -- AUTHOR: Philipp Gesang (Phg), --- VERSION: 2.4 --- CREATED: 2013-07-28 10:01:18+0200 +-- VERSION: 2.5 +-- MODIFIED: 2014-01-02 21:23:06+0100 ----------------------------------------------------------------------- -- local names = fonts.names -local luatexstatus = status -local status = config.luaotfload.status local kpse = require "kpse" local kpseexpand_path = kpse.expand_path @@ -49,10 +47,15 @@ local lpeg = require "lpeg" local C, Cg, Ct = lpeg.C, lpeg.Cg, lpeg.Ct local lpegmatch = lpeg.match +local report = luaotfload.log.report local out = function (...) - logs.names_report (false, 0, "diagnose", ...) + report (false, 0, "diagnose", ...) end +local parsers = luaotfload.parsers +local stripslashes = parsers.stripslashes +local splitcomma = parsers.splitcomma + local check_index = function (errcnt) out "================= font names ==================" @@ -94,8 +97,9 @@ local check_index = function (errcnt) return errcnt end -local verify_files = function (errcnt, status) +local verify_files = function (errcnt) out "================ verify files =================" + local status = config.luaotfload.status local hashes = status.hashes local notes = status.notes if not hashes or #hashes == 0 then @@ -163,8 +167,6 @@ local analyze_permissions = function (raw) return lpegmatch (p_permissions, raw) end -local stripslashes = names.patterns.stripslashes - local get_permissions = function (t, location) if stringsub (location, #location) == "/" then --- strip trailing slashes (lfs idiosyncrasy on Win) @@ -238,19 +240,23 @@ local check_conformance = function (spec, permissions, errcnt) return errcnt end -local path = names.path - -local desired_permissions = { - { "d", {"r","w"}, function () return caches.getwritablepath () end }, - { "d", {"r","w"}, path.globals.prefix }, - { "f", {"r","w"}, path.index.lua .. ".gz" }, - { "f", {"r","w"}, path.index.luc }, - { "f", {"r","w"}, path.lookups.lua }, - { "f", {"r","w"}, path.lookups.luc }, -} +local desired_permissions +local init_desired_permissions = function () + inspect(config.luaotfload.paths) + local paths = config.luaotfload.paths + desired_permissions = { + { "d", {"r","w"}, function () return caches.getwritablepath () end }, + { "d", {"r","w"}, paths.prefix }, + { "f", {"r","w"}, paths.index_path_lua .. ".gz" }, + { "f", {"r","w"}, paths.index_path_luc }, + { "f", {"r","w"}, paths.lookup_path_lua }, + { "f", {"r","w"}, paths.lookup_path_luc }, + } +end local check_permissions = function (errcnt) out [[=============== file permissions ==============]] + if not desired_permissions then init_desired_permissions () end for i = 1, #desired_permissions do local t, spec, path = unpack (desired_permissions[i]) if type (path) == "function" then @@ -334,8 +340,7 @@ else end out ("Requesting <%s>.", request) - local response, code, headers, status - = https.request (request) + local response, code, headers, status = https.request (request) if status ~= alright then out "Request failed!" return false @@ -605,8 +610,6 @@ local anamneses = { "permissions" } -local splitcomma = names.patterns.splitcomma - local diagnose = function (job) local errcnt = 0 local asked = job.asked_diagnostics @@ -628,7 +631,7 @@ local diagnose = function (job) end if asked.files == true then - errcnt = verify_files (errcnt, status) + errcnt = verify_files (errcnt) asked.files = nil end @@ -638,6 +641,7 @@ local diagnose = function (job) end if asked.repository == true then + local status = config.luaotfload.status check_upstream (status.notes.revision) asked.repository = nil end @@ -663,7 +667,7 @@ local diagnose = function (job) carefully and get a clean version from CTAN or github: - × http://ctan.org/tex-archive/macros/luatex/generic/luaotfload + × http://www.ctan.org/pkg/luaotfload × https://github.com/lualatex/luaotfload/releases If you are uncertain as to how to proceed, then diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua index 4b2f20619ff..1fb6d7c6785 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua @@ -1,15 +1,26 @@ if not modules then modules = { } end modules ["features"] = { - version = "2.4", - comment = "companion to luaotfload.lua", + version = "2.5", + comment = "companion to luaotfload-main.lua", author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } -local type, next = type, next +local type = type +local next = next local tonumber = tonumber local tostring = tostring + +local lpeg = require "lpeg" local lpegmatch = lpeg.match +local P = lpeg.P +local R = lpeg.R +local C = lpeg.C + +local table = table +local tabletohash = table.tohash +local setmetatableindex = table.setmetatableindex +local insert = table.insert ---[[ begin included font-ltx.lua ]] --- this appears to be based in part on luatex-fonts-def.lua @@ -43,7 +54,8 @@ function fonts.definers.getspecification(str) return "", str, "", ":", str end -local report = logs.names_report +local log = luaotfload.log +local report = log.report local stringfind = string.find local stringlower = string.lower @@ -53,58 +65,6 @@ local stringformat = string.format local stringis_empty = string.is_empty local mathceil = math.ceil -local defaults = { - dflt = { - "ccmp", "locl", "rlig", "liga", "clig", - "kern", "mark", "mkmk", 'itlc', - }, - arab = { - "ccmp", "locl", "isol", "fina", "fin2", - "fin3", "medi", "med2", "init", "rlig", - "calt", "liga", "cswh", "mset", "curs", - "kern", "mark", "mkmk", - }, - deva = { - "ccmp", "locl", "init", "nukt", "akhn", - "rphf", "blwf", "half", "pstf", "vatu", - "pres", "blws", "abvs", "psts", "haln", - "calt", "blwm", "abvm", "dist", "kern", - "mark", "mkmk", - }, - khmr = { - "ccmp", "locl", "pref", "blwf", "abvf", - "pstf", "pres", "blws", "abvs", "psts", - "clig", "calt", "blwm", "abvm", "dist", - "kern", "mark", "mkmk", - }, - thai = { - "ccmp", "locl", "liga", "kern", "mark", - "mkmk", - }, - hang = { - "ccmp", "ljmo", "vjmo", "tjmo", - }, -} - -local global_defaults = { mode = "node" } - -defaults.beng = defaults.deva -defaults.guru = defaults.deva -defaults.gujr = defaults.deva -defaults.orya = defaults.deva -defaults.taml = defaults.deva -defaults.telu = defaults.deva -defaults.knda = defaults.deva -defaults.mlym = defaults.deva -defaults.sinh = defaults.deva - -defaults.syrc = defaults.arab -defaults.mong = defaults.arab -defaults.nko = defaults.arab - -defaults.tibt = defaults.khmr - -defaults.lao = defaults.thai ---[[ begin excerpt from font-ott.lua ]] @@ -749,7 +709,7 @@ local verbosebaselines = swapped(baselines) --doc]]-- -local support_incomplete = table.tohash({ +local support_incomplete = tabletohash({ "deva", "beng", "guru", "gujr", "orya", "taml", "telu", "knda", "mlym", "sinh", @@ -764,6 +724,8 @@ local support_incomplete = table.tohash({ --- (string, string) dict -> (string, string) dict local set_default_features = function (speclist) + local default_features = luaotfload.features + speclist = speclist or { } speclist[""] = nil --- invalid options stub @@ -788,32 +750,31 @@ local set_default_features = function (speclist) or "dflt" if support_incomplete[script] then report("log", 0, "load", - "support for the requested script: " - .. "%q may be incomplete", script) + "Support for the requested script: " + .. "%q may be incomplete.", script) end else script = "dflt" end speclist.script = script - report("log", 0, "load", - "auto-selecting default features for script: %s", + report("log", 1, "load", + "Auto-selecting default features for script: %s.", script) - local requested = defaults[script] + local requested = default_features.defaults[script] if not requested then - report("log", 0, "load", - "no defaults for script %q, falling back to \"dflt\"", + report("log", 1, "load", + "No default features for script %q, falling back to \"dflt\".", script) - requested = defaults.dflt + requested = default_features.defaults.dflt end - for i=1, #requested do - local feat = requested[i] - if speclist[feat] ~= false then speclist[feat] = true end + for feat, state in next, requested do + if not speclist[feat] then speclist[feat] = state end end - for feat, state in next, global_defaults do + for feat, state in next, default_features.global do --- This is primarily intended for setting node --- mode unless “base” is requested, as stated --- in the manual. @@ -822,259 +783,6 @@ local set_default_features = function (speclist) return speclist end ------------------------------------------------------------------------ ---- request syntax parser 2.2 ------------------------------------------------------------------------ ---- the luaotfload font request syntax (see manual) ---- has a canonical form: ---- ---- \font=:: ---- ---- where ---- is the control sequence that activates the font ---- is either “file” or “name”, determining the lookup ---- is either a file name (no path) or a font ---- name, depending on the lookup ---- is a list of switches or options, separated by ---- semicolons or commas; a switch is of the form “+” foo ---- or “-” foo, options are of the form lhs “=” rhs ---- ---- however, to ensure backward compatibility we also have ---- support for Xetex-style requests. ---- ---- for the Xetex emulation see: ---- · The XeTeX Reference Guide by Will Robertson, 2011 ---- · The XeTeX Companion by Michel Goosens, 2010 ---- · About XeTeX by Jonathan Kew, 2005 ---- ---- ---- caueat emptor. ---- the request is parsed into one of **four** different ---- lookup categories: the regular ones, file and name, ---- as well as the Xetex compatibility ones, path and anon. ---- (maybe a better choice of identifier would be “ambig”.) ---- ---- according to my reconstruction, the correct chaining ---- of the lookups for each category is as follows: ---- ---- | File -> ( db/filename lookup ) ---- ---- | Name -> ( db/name lookup, ---- db/filename lookup ) ---- ---- | Path -> ( db/filename lookup, ---- fullpath lookup ) ---- ---- | Anon -> ( kpse.find_file(), // <- for tfm, ofm ---- db/name lookup, ---- db/filename lookup, ---- fullpath lookup ) ---- ---- caching of successful lookups is essential. we now ---- as of v2.2 have an experimental lookup cache that is ---- stored in a separate file. it pertains only to name: ---- lookups, and is described in more detail in ---- luaotfload-database.lua. ---- ------------------------------------------------------------------------ - ---[[doc-- - - One further incompatibility between Xetex and Luatex-Fonts consists - in their option list syntax: apparently, Xetex requires key-value - options to be prefixed by a "+" (ascii “plus”) character. We - silently accept this as well, dropping the first byte if it is a - plus or minus character. - - Reference: https://github.com/lualatex/luaotfload/issues/79#issuecomment-18104483 - ---doc]]-- - -local handle_normal_option = function (key, val) - val = stringlower(val) - --- the former “toboolean()” handler - if val == "true" then - val = true - elseif val == "false" then - val = false - end - return key, val -end - ---[[doc-- - - Xetex style indexing begins at zero which we just increment before - passing it along to the font loader. Ymmv. - ---doc]]-- - -local handle_xetex_option = function (key, val) - val = stringlower(val) - local numeric = tonumber(val) --- decimal only; keeps colors intact - if numeric then --- ugh - if mathceil(numeric) == numeric then -- integer, possible index - val = tostring(numeric + 1) - end - elseif val == "true" then - val = true - elseif val == "false" then - val = false - end - return key, val -end - ---[[doc-- - - Instead of silently ignoring invalid options we emit a warning to - the log. - - Note that we have to return a pair to please rawset(). This creates - an entry on the resulting features hash which will later be removed - during set_default_features(). - ---doc]]-- - -local handle_invalid_option = function (opt) - report("log", 0, "load", "font option %q unknown.", opt) - return "", false -end - ---[[doc-- - - Dirty test if a file: request is actually a path: lookup; don’t - ask! Note this fails on Windows-style absolute paths. These will - *really* have to use the correct request. - ---doc]]-- - -local check_garbage = function (_,i, garbage) - if stringfind(garbage, "/") then - report("log", 0, "load", --- ffs use path! - "warning: path in file: lookups is deprecated; ") - report("log", 0, "load", "use bracket syntax instead!") - report("log", 0, "load", - "position: %d; full match: %q", - i, garbage) - return true - end - return false -end - -local lpegmatch = lpeg.match -local P, S, R = lpeg.P, lpeg.S, lpeg.R -local C, Cc, Cf, Cg, Cmt, Cs, Ct - = lpeg.C, lpeg.Cc, lpeg.Cf, lpeg.Cg, lpeg.Cmt, lpeg.Cs, lpeg.Ct - ---- terminals and low-level classes ----------------------------------- ---- note we could use the predefined ones from lpeg.patterns -local dot = P"." -local colon = P":" -local featuresep = S",;" -local slash = P"/" -local equals = P"=" -local lbrk, rbrk = P"[", P"]" - -local spacing = S" \t\v" -local ws = spacing^0 - -local digit = R"09" -local alpha = R("az", "AZ") -local anum = alpha + digit -local decimal = digit^1 * (dot * digit^0)^-1 - ---- modifiers --------------------------------------------------------- ---[[doc-- - The slash notation: called “modifiers” (Kew) or “font options” - (Robertson, Goosens) - we only support the shorthands for italic / bold / bold italic - shapes, as well as setting optical size, the rest is ignored. ---doc]]-- -local style_modifier = (P"BI" + P"IB" + P"bi" + P"ib" + S"biBI") - / stringlower -local size_modifier = S"Ss" * P"=" --- optical size - * Cc"optsize" * C(decimal) -local other_modifier = P"AAT" + P"aat" --- apple stuff; unsupported - + P"ICU" + P"icu" --- not applicable - + P"GR" + P"gr" --- sil stuff; unsupported -local garbage_modifier = ((1 - colon - slash)^0 * Cc(false)) -local modifier = slash * (other_modifier --> ignore - + Cs(style_modifier) --> collect - + Ct(size_modifier) --> collect - + garbage_modifier) --> warn -local modifier_list = Cg(Ct(modifier^0), "modifiers") - ---- lookups ----------------------------------------------------------- -local fontname = C((1-S":(/")^1) --- like luatex-fonts -local unsupported = Cmt((1-S":(")^1, check_garbage) -local prefixed = P"name:" * ws * Cg(fontname, "name") ---- initially we intended file: to emulate the behavior of ---- luatex-fonts, i.e. no paths allowed. after all, we do have XeTeX ---- emulation with the path lookup and it interferes with db lookups. ---- turns out fontspec and other widely used packages rely on file: ---- with paths already, so we’ll add a less strict rule here. anyways, ---- we’ll emit a warning. - + P"file:" * ws * Cg(unsupported, "path") - + P"file:" * ws * Cg(fontname, "file") ---- EXPERIMENTAL: kpse lookup - + P"kpse:" * ws * Cg(fontname, "kpse") ---- EXPERIMENTAL: custom lookup - + P"my:" * ws * Cg(fontname, "my") -local unprefixed = Cg(fontname, "anon") -local path_lookup = lbrk * Cg(C((1-rbrk)^1), "path") * rbrk - ---- features ---------------------------------------------------------- -local field_char = anum + S"+-." --- sic! -local field = field_char^1 ---- assignments are “lhs=rhs” ---- or “+lhs=rhs” (Xetex-style) ---- switches are “+key” | “-key” -local normal_option = C(field) * ws * equals * ws * C(field) * ws -local xetex_option = P"+" * ws * normal_option -local ignore_option = (1 - equals - featuresep)^1 - * equals - * (1 - featuresep)^1 -local assignment = xetex_option / handle_xetex_option - + normal_option / handle_normal_option - + ignore_option / handle_invalid_option -local switch = P"+" * ws * C(field) * Cc(true) - + P"-" * ws * C(field) * Cc(false) - + C(field) * Cc(true) --- default -local feature_expr = ws * Cg(assignment + switch) * ws -local option = feature_expr -local feature_list = Cf(Ct"" - * option - * (featuresep * option^-1)^0 - , rawset) - * featuresep^-1 - ---- other ------------------------------------------------------------- ---- This rule is present in the original parser. It sets the “sub” ---- field of the specification which allows addressing a specific ---- font inside a TTC container. Neither in Luatex-Fonts nor in ---- Luaotfload is this documented, so we might as well silently drop ---- it. However, as backward compatibility is one of our prime goals we ---- just insert it here and leave it undocumented until someone cares ---- to ask. (Note: afair subfonts are numbered, but this rule matches a ---- string; I won’t mess with it though until someone reports a ---- problem.) ---- local subvalue = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim ---- Note to self: subfonts apparently start at index 0. Tested with ---- Cambria.ttc that includes “Cambria Math” at 0 and “Cambria” at 1. ---- Other values cause luatex to segfault. -local subfont = P"(" * Cg((1 - S"()")^1, "sub") * P")" ---- top-level rules --------------------------------------------------- ---- \font\foo=: -local features = Cg(feature_list, "features") -local specification = (prefixed + unprefixed) - * subfont^-1 - * modifier_list^-1 -local font_request = Ct(path_lookup * (colon^-1 * features)^-1 - + specification * (colon * features)^-1) - --- lpeg.print(font_request) ---- new parser: 657 rules ---- old parser: 230 rules - local import_values = { --- That’s what the 1.x parser did, not quite as graciously, --- with an array of branch expressions. @@ -1138,7 +846,7 @@ end --- spec -> spec local handle_request = function (specification) - local request = lpegmatch(font_request, + local request = lpegmatch(luaotfload.parsers.font_request, specification.specification) if not request then --- happens when called with an absolute path @@ -1230,7 +938,6 @@ local report_otf = logs.reporter("fonts","otf loading") local otf = fonts.handlers.otf local registerotffeature = otf.features.register -local setmetatableindex = table.setmetatableindex --[[HH-- @@ -1286,6 +993,7 @@ local function addfeature(data,feature,specifications) local subtables = specification.subtables or { specification.data } or { } local featuretype = types[specification.type or "substitution"] local featureflags = specification.flags or noflags + local featureorder = specification.order or { feature } local added = false local featurename = stringformat("ctx_%s_%s",feature,s) local st = { } @@ -1346,17 +1054,23 @@ local function addfeature(data,feature,specifications) -- script = { lang1, lang2, lang3 } or script = { lang1 = true, ... } for k, v in next, askedfeatures do if v[1] then - askedfeatures[k] = table.tohash(v) + askedfeatures[k] = tabletohash(v) end end - sequences[#sequences+1] = { + local sequence = { chain = 0, features = { [feature] = askedfeatures }, flags = featureflags, name = featurename, + order = featureorder, subtables = st, type = featuretype, } + if specification.prepend then + insert(sequences,1,sequence) + else + insert(sequences,sequence) + end -- register in metadata (merge as there can be a few) if not gsubfeatures then gsubfeatures = { } @@ -1386,6 +1100,7 @@ local function addfeature(data,feature,specifications) end end + otf.enhancers.addfeature = addfeature local extrafeatures = { } @@ -1414,6 +1129,8 @@ local tlig = { [0x0060] = 0x2018, -- quoteright }, flags = { }, + order = { "tlig" }, + prepend = true, }, { type = "ligature", @@ -1432,6 +1149,8 @@ local tlig = { [0x00BB] = {0x003E, 0x003E}, -- RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK }, flags = { }, + order = { "tlig" }, + prepend = true, }, { type = "ligature", @@ -1443,6 +1162,8 @@ local tlig = { [0x00BF] = {0x003F, 0x0060}, -- questiondown }, flags = { }, + order = { "tlig" }, + prepend = true, }, } @@ -1494,6 +1215,7 @@ local anum_specification = { features = { arab = { far = true, urd = true, snd = true } }, data = anum_persian, flags = { }, + order = { "anum" }, valid = valid, }, { @@ -1501,23 +1223,16 @@ local anum_specification = { features = { arab = { ["*"] = true } }, data = anum_arabic, flags = { }, + order = { "anum" }, valid = valid, }, } ---[[doc-- - - Below the specifications as given in the removed font-otc.lua. - The rest was identical to what this file had from the beginning. - Both make the “anum.tex” test pass anyways. - ---doc]]-- - -otf.addfeature("anum",anum_specification) +otf.addfeature ("anum", anum_specification) registerotffeature { - name = 'anum', - description = 'arabic digits', + name = "anum", + description = "arabic digits", } -- vim:tw=71:sw=4:ts=4:expandtab diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fontloader.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fontloader.lua index 177324145e3..2f26be70e21 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fontloader.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fontloader.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 12/24/13 17:52:44 +-- merge date : 07/06/14 22:50:12 do -- begin closure to overcome local limits and interference @@ -82,6 +82,9 @@ function optionalrequire(...) return result end end +if lua then + lua.mask=load([[τεχ = 1]]) and "utf" or "ascii" +end end -- closure @@ -101,7 +104,9 @@ local byte,char,gmatch,format=string.byte,string.char,string.gmatch,string.forma local floor=math.floor local P,R,S,V,Ct,C,Cs,Cc,Cp,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.V,lpeg.Ct,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Cp,lpeg.Cmt local lpegtype,lpegmatch,lpegprint=lpeg.type,lpeg.match,lpeg.print -setinspector(function(v) if lpegtype(v) then lpegprint(v) return true end end) +if setinspector then + setinspector(function(v) if lpegtype(v) then lpegprint(v) return true end end) +end lpeg.patterns=lpeg.patterns or {} local patterns=lpeg.patterns local anything=P(1) @@ -120,7 +125,7 @@ local uppercase=R("AZ") local underscore=P("_") local hexdigit=digit+lowercase+uppercase local cr,lf,crlf=P("\r"),P("\n"),P("\r\n") -local newline=crlf+S("\r\n") +local newline=P("\r")*(P("\n")+P(true))+P("\n") local escaped=P("\\")*anything local squote=P("'") local dquote=P('"') @@ -142,8 +147,8 @@ patterns.utfbom_32_le=utfbom_32_le patterns.utfbom_16_be=utfbom_16_be patterns.utfbom_16_le=utfbom_16_le patterns.utfbom_8=utfbom_8 -patterns.utf_16_be_nl=P("\000\r\000\n")+P("\000\r")+P("\000\n") -patterns.utf_16_le_nl=P("\r\000\n\000")+P("\r\000")+P("\n\000") +patterns.utf_16_be_nl=P("\000\r\000\n")+P("\000\r")+P("\000\n") +patterns.utf_16_le_nl=P("\r\000\n\000")+P("\r\000")+P("\n\000") patterns.utf8one=R("\000\127") patterns.utf8two=R("\194\223")*utf8next patterns.utf8three=R("\224\239")*utf8next*utf8next @@ -170,9 +175,11 @@ patterns.spacer=spacer patterns.whitespace=whitespace patterns.nonspacer=nonspacer patterns.nonwhitespace=nonwhitespace -local stripper=spacer^0*C((spacer^0*nonspacer^1)^0) +local stripper=spacer^0*C((spacer^0*nonspacer^1)^0) +local fullstripper=whitespace^0*C((whitespace^0*nonwhitespace^1)^0) local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0)) patterns.stripper=stripper +patterns.fullstripper=fullstripper patterns.collapser=collapser patterns.lowercase=lowercase patterns.uppercase=uppercase @@ -210,9 +217,12 @@ patterns.integer=sign^-1*digit^1 patterns.unsigned=digit^0*period*digit^1 patterns.float=sign^-1*patterns.unsigned patterns.cunsigned=digit^0*comma*digit^1 +patterns.cpunsigned=digit^0*(period+comma)*digit^1 patterns.cfloat=sign^-1*patterns.cunsigned +patterns.cpfloat=sign^-1*patterns.cpunsigned patterns.number=patterns.float+patterns.integer patterns.cnumber=patterns.cfloat+patterns.integer +patterns.cpnumber=patterns.cpfloat+patterns.integer patterns.oct=zero*octdigit^1 patterns.octal=patterns.oct patterns.HEX=zero*P("X")*(digit+uppercase)^1 @@ -395,7 +405,7 @@ function lpeg.replacer(one,two,makefunction,isutf) return pattern end end -function lpeg.finder(lst,makefunction) +function lpeg.finder(lst,makefunction,isutf) local pattern if type(lst)=="table" then pattern=P(false) @@ -411,7 +421,11 @@ function lpeg.finder(lst,makefunction) else pattern=P(lst) end - pattern=(1-pattern)^0*pattern + if isutf then + pattern=((utf8char or 1)-pattern)^0*pattern + else + pattern=(1-pattern)^0*pattern + end if makefunction then return function(str) return lpegmatch(pattern,str) @@ -625,21 +639,22 @@ function lpeg.append(list,pp,delayed,checked) end return p end -local function make(t) - local p +local function make(t,hash) + local p=P(false) local keys=sortedkeys(t) for i=1,#keys do local k=keys[i] local v=t[k] - if not p then + local h=hash[v] + if h then if next(v) then - p=P(k)*make(v) + p=p+P(k)*(make(v,hash)+P(true)) else - p=P(k) + p=p+P(k)*P(true) end else if next(v) then - p=p+P(k)*make(v) + p=p+P(k)*make(v,hash) else p=p+P(k) end @@ -649,16 +664,37 @@ local function make(t) end function lpeg.utfchartabletopattern(list) local tree={} - for i=1,#list do - local t=tree - for c in gmatch(list[i],".") do - if not t[c] then - t[c]={} + local hash={} + local n=#list + if n==0 then + for s in next,list do + local t=tree + for c in gmatch(s,".") do + local tc=t[c] + if not tc then + tc={} + t[c]=tc + end + t=tc end - t=t[c] + hash[t]=s + end + else + for i=1,n do + local t=tree + local s=list[i] + for c in gmatch(s,".") do + local tc=t[c] + if not tc then + tc={} + t[c]=tc + end + t=tc + end + hash[t]=s end end - return make(tree) + return make(tree,hash) end patterns.containseol=lpeg.finder(eol) local function nextstep(n,step,result) @@ -748,11 +784,15 @@ function string.limit(str,n,sentinel) end end local stripper=patterns.stripper +local fullstripper=patterns.fullstripper local collapser=patterns.collapser local longtostring=patterns.longtostring function string.strip(str) return lpegmatch(stripper,str) or "" end +function string.fullstrip(str) + return lpegmatch(fullstripper,str) or "" +end function string.collapsespaces(str) return lpegmatch(collapser,str) or "" end @@ -886,6 +926,36 @@ local function sortedkeys(tab) return {} end end +local function sortedhashonly(tab) + if tab then + local srt,s={},0 + for key,_ in next,tab do + if type(key)=="string" then + s=s+1 + srt[s]=key + end + end + sort(srt) + return srt + else + return {} + end +end +local function sortedindexonly(tab) + if tab then + local srt,s={},0 + for key,_ in next,tab do + if type(key)=="number" then + s=s+1 + srt[s]=key + end + end + sort(srt) + return srt + else + return {} + end +end local function sortedhashkeys(tab,cmp) if tab then local srt,s={},0 @@ -911,6 +981,8 @@ function table.allkeys(t) return sortedkeys(keys) end table.sortedkeys=sortedkeys +table.sortedhashonly=sortedhashonly +table.sortedindexonly=sortedindexonly table.sortedhashkeys=sortedhashkeys local function nothing() end local function sortedhash(t,cmp) @@ -923,14 +995,14 @@ local function sortedhash(t,cmp) end local n=0 local m=#s - local function kv(s) + local function kv() if n=first and k<=last then if tv=="number" then if hexify then - handle(format("%s 0x%04X,",depth,v)) + handle(format("%s 0x%X,",depth,v)) else handle(format("%s %s,",depth,v)) end @@ -1206,25 +1278,25 @@ local function do_serialize(root,name,depth,level,indexed) elseif tv=="number" then if tk=="number" then if hexify then - handle(format("%s [0x%04X]=0x%04X,",depth,k,v)) + handle(format("%s [0x%X]=0x%X,",depth,k,v)) else handle(format("%s [%s]=%s,",depth,k,v)) end elseif tk=="boolean" then if hexify then - handle(format("%s [%s]=0x%04X,",depth,k and "true" or "false",v)) + handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v)) else handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) end elseif noquotes and not reserved[k] and lpegmatch(propername,k) then if hexify then - handle(format("%s %s=0x%04X,",depth,k,v)) + handle(format("%s %s=0x%X,",depth,k,v)) else handle(format("%s %s=%s,",depth,k,v)) end else if hexify then - handle(format("%s [%q]=0x%04X,",depth,k,v)) + handle(format("%s [%q]=0x%X,",depth,k,v)) else handle(format("%s [%q]=%s,",depth,k,v)) end @@ -1233,7 +1305,7 @@ local function do_serialize(root,name,depth,level,indexed) if reduce and tonumber(v) then if tk=="number" then if hexify then - handle(format("%s [0x%04X]=%s,",depth,k,v)) + handle(format("%s [0x%X]=%s,",depth,k,v)) else handle(format("%s [%s]=%s,",depth,k,v)) end @@ -1247,7 +1319,7 @@ local function do_serialize(root,name,depth,level,indexed) else if tk=="number" then if hexify then - handle(format("%s [0x%04X]=%q,",depth,k,v)) + handle(format("%s [0x%X]=%q,",depth,k,v)) else handle(format("%s [%s]=%q,",depth,k,v)) end @@ -1263,7 +1335,7 @@ local function do_serialize(root,name,depth,level,indexed) if not next(v) then if tk=="number" then if hexify then - handle(format("%s [0x%04X]={},",depth,k)) + handle(format("%s [0x%X]={},",depth,k)) else handle(format("%s [%s]={},",depth,k)) end @@ -1279,7 +1351,7 @@ local function do_serialize(root,name,depth,level,indexed) if st then if tk=="number" then if hexify then - handle(format("%s [0x%04X]={ %s },",depth,k,concat(st,", "))) + handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", "))) else handle(format("%s [%s]={ %s },",depth,k,concat(st,", "))) end @@ -1299,7 +1371,7 @@ local function do_serialize(root,name,depth,level,indexed) elseif tv=="boolean" then if tk=="number" then if hexify then - handle(format("%s [0x%04X]=%s,",depth,k,v and "true" or "false")) + handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false")) else handle(format("%s [%s]=%s,",depth,k,v and "true" or "false")) end @@ -1315,7 +1387,7 @@ local function do_serialize(root,name,depth,level,indexed) local f=getinfo(v).what=="C" and dump(dummy) or dump(v) if tk=="number" then if hexify then - handle(format("%s [0x%04X]=load(%q),",depth,k,f)) + handle(format("%s [0x%X]=load(%q),",depth,k,f)) else handle(format("%s [%s]=load(%q),",depth,k,f)) end @@ -1330,7 +1402,7 @@ local function do_serialize(root,name,depth,level,indexed) else if tk=="number" then if hexify then - handle(format("%s [0x%04X]=%q,",depth,k,tostring(v))) + handle(format("%s [0x%X]=%q,",depth,k,tostring(v))) else handle(format("%s [%s]=%q,",depth,k,tostring(v))) end @@ -1384,7 +1456,7 @@ local function serialize(_handle,root,name,specification) end elseif tname=="number" then if hexify then - handle(format("[0x%04X]={",name)) + handle(format("[0x%X]={",name)) else handle("["..name.."]={") end @@ -1636,7 +1708,9 @@ function table.print(t,...) serialize(print,t,...) end end -setinspector(function(v) if type(v)=="table" then serialize(print,v,"table") return true end end) +if setinspector then + setinspector(function(v) if type(v)=="table" then serialize(print,v,"table") return true end end) +end function table.sub(t,i,j) return { unpack(t,i,j) } end @@ -1689,6 +1763,44 @@ function table.values(t,s) return {} end end +function table.filtered(t,pattern,sort,cmp) + if t and type(pattern)=="string" then + if sort then + local s + if cmp then + s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end) + else + s=sortedkeys(t) + end + local n=0 + local m=#s + local function kv(s) + while n -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n) + else + return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n) + end +end local format_g=function(f) n=n+1 return format("format('%%%sg',a%s)",f,n) @@ -2948,7 +3137,7 @@ local builder=Cs { "start", ( P("%")/""*( V("!") -+V("s")+V("q")+V("i")+V("d")+V("f")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o") ++V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o") +V("c")+V("C")+V("S") +V("Q") +V("N") @@ -2968,6 +3157,7 @@ local builder=Cs { "start", ["i"]=(prefix_any*P("i"))/format_i, ["d"]=(prefix_any*P("d"))/format_d, ["f"]=(prefix_any*P("f"))/format_f, + ["F"]=(prefix_any*P("F"))/format_F, ["g"]=(prefix_any*P("g"))/format_g, ["G"]=(prefix_any*P("G"))/format_G, ["e"]=(prefix_any*P("e"))/format_e, @@ -3005,8 +3195,8 @@ local builder=Cs { "start", ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension, } local direct=Cs ( - P("%")/""*Cc([[local format = string.format return function(str) return format("%]])*(S("+- .")+R("09"))^0*S("sqidfgGeExXo")*Cc([[",str) end]])*P(-1) - ) + P("%")*(S("+- .")+R("09"))^0*S("sqidfgGeExXo")*P(-1)/[[local format = string.format return function(str) return format("%0",str) end]] +) local function make(t,str) local f local p @@ -3015,10 +3205,10 @@ local function make(t,str) f=loadstripped(p)() else n=0 - p=lpegmatch(builder,str,1,"..",t._extensions_) + p=lpegmatch(builder,str,1,t._connector_,t._extensions_) if n>0 then p=format(template,preamble,t._preamble_,arguments[n],p) - f=loadstripped(p)() + f=loadstripped(p,t._environment_)() else f=function() return str end end @@ -3030,10 +3220,22 @@ local function use(t,fmt,...) return t[fmt](...) end strings.formatters={} -function strings.formatters.new() - local t={ _extensions_={},_preamble_="",_type_="formatter" } - setmetatable(t,{ __index=make,__call=use }) - return t +if _LUAVERSION<5.2 then + function strings.formatters.new(noconcat) + local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} } + setmetatable(t,{ __index=make,__call=use }) + return t + end +else + function strings.formatters.new(noconcat) + local e={} + for k,v in next,environment do + e[k]=v + end + local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e } + setmetatable(t,{ __index=make,__call=use }) + return t + end end local formatters=strings.formatters.new() string.formatters=formatters @@ -3041,8 +3243,12 @@ string.formatter=function(str,...) return formatters[str](...) end local function add(t,name,template,preamble) if type(t)=="table" and t._type_=="formatter" then t._extensions_[name]=template or "%s" - if preamble then + if type(preamble)=="string" then t._preamble_=preamble.."\n"..t._preamble_ + elseif type(preamble)=="table" then + for k,v in next,preamble do + t._environment_[k]=v + end end end end @@ -3051,9 +3257,24 @@ patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"" patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0) patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0) patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"')) -add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],[[local xmlescape = lpeg.patterns.xmlescape]]) -add(formatters,"tex",[[lpegmatch(texescape,%s)]],[[local texescape = lpeg.patterns.texescape]]) -add(formatters,"lua",[[lpegmatch(luaescape,%s)]],[[local luaescape = lpeg.patterns.luaescape]]) +if _LUAVERSION<5.2 then + add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape") + add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape") + add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape") +else + add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape }) + add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape }) + add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape }) +end +local dquote=patterns.dquote +local equote=patterns.escaped+dquote/'\\"'+1 +local space=patterns.space +local cquote=Cc('"') +local pattern=Cs(dquote*(equote-P(-2))^0*dquote) ++Cs(cquote*(equote-space)^0*space*equote^0*cquote) +function string.optionalquoted(str) + return lpegmatch(pattern,str) or str +end end -- closure @@ -3250,6 +3471,17 @@ function caches.loaddata(paths,name) for i=1,#paths do local data=false local luaname,lucname=makefullname(paths[i],name) + if lucname and not lfs.isfile(lucname) and type(caches.compile)=="function" then + texio.write(string.format("(compiling luc: %s)",lucname)) + data=loadfile(luaname) + if data then + data=data() + end + if data then + caches.compile(data,luaname,lucname) + return data + end + end if lucname and lfs.isfile(lucname) then texio.write(string.format("(load luc: %s)",lucname)) data=loadfile(lucname) @@ -3305,6 +3537,15 @@ end function table.setmetatableindex(t,f) setmetatable(t,{ __index=f }) end +arguments={} +if arg then + for i=1,#arg do + local k,v=string.match(arg[i],"^%-%-([^=]+)=?(.-)$") + if k and v then + arguments[k]=v + end + end +end end -- closure @@ -3473,9 +3714,17 @@ local free_node=node.free local remove_node=node.remove local new_node=node.new local traverse_id=node.traverse_id -local math_code=nodecodes.math nodes.handlers.protectglyphs=node.protect_glyphs nodes.handlers.unprotectglyphs=node.unprotect_glyphs +local math_code=nodecodes.math +local end_of_math=node.end_of_math +function node.end_of_math(n) + if n.id==math_code and n.subtype==1 then + return n + else + return end_of_math(n) + end +end function nodes.remove(head,current,free_too) local t=current head,current=remove_node(head,current) @@ -3769,14 +4018,15 @@ constructors.sharefonts=false constructors.nofsharedfonts=0 local sharednames={} function constructors.trytosharefont(target,tfmdata) - if constructors.sharefonts then + if constructors.sharefonts then local characters=target.characters local n=1 local t={ target.psname } local u=sortedkeys(characters) for i=1,#u do + local k=u[i] n=n+1;t[n]=k - n=n+1;t[n]=characters[u[i]].index or k + n=n+1;t[n]=characters[k].index or k end local h=md5.HEX(concat(t," ")) local s=sharednames[h] @@ -4006,6 +4256,7 @@ function constructors.scale(tfmdata,specification) if changed then local c=changed[unicode] if c then + local ligatures=character.ligatures description=descriptions[c] or descriptions[unicode] or character character=characters[c] or character index=description.index or c @@ -4017,6 +4268,9 @@ function constructors.scale(tfmdata,specification) touni=tounicode[i] end end + if ligatures and not character.ligatures then + character.ligatures=ligatures + end else description=descriptions[unicode] or character index=description.index or unicode @@ -4694,6 +4948,7 @@ end local fonts=fonts fonts.encodings={} fonts.encodings.agl={} +fonts.encodings.known={} setmetatable(fonts.encodings.agl,{ __index=function(t,k) if k=="unicodes" then texio.write(" ") @@ -5620,7 +5875,6 @@ unify=function(data,filename) if unicode then krn[unicode]=kern else - print(unicode,name) end end description.kerns=krn @@ -6405,7 +6659,7 @@ local type,next,tonumber,tostring=type,next,tonumber,tostring local abs=math.abs local insert=table.insert local lpegmatch=lpeg.match -local reversed,concat,remove=table.reversed,table.concat,table.remove +local reversed,concat,remove,sortedkeys=table.reversed,table.concat,table.remove,table.sortedkeys local ioflush=io.flush local fastcopy,tohash,derivetable=table.fastcopy,table.tohash,table.derive local formatters=string.formatters @@ -6427,7 +6681,7 @@ local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf otf.glists={ "gsub","gpos" } -otf.version=2.749 +otf.version=2.756 otf.cache=containers.define("fonts","otf",otf.version,true) local fontdata=fonts.hashes.identifiers local chardata=characters and characters.data @@ -6579,6 +6833,7 @@ local valid_fields=table.tohash { "upos", "use_typo_metrics", "uwidth", + "validation_state", "version", "vert_base", "weight", @@ -6969,15 +7224,22 @@ actions["prepare glyphs"]=function(data,filename,raw) local glyph=cidglyphs[index] if glyph then local unicode=glyph.unicode +if unicode>=0x00E000 and unicode<=0x00F8FF then + unicode=-1 +elseif unicode>=0x0F0000 and unicode<=0x0FFFFD then + unicode=-1 +elseif unicode>=0x100000 and unicode<=0x10FFFD then + unicode=-1 +end local name=glyph.name or cidnames[index] - if not unicode or unicode==-1 or unicode>=criterium then + if not unicode or unicode==-1 then unicode=cidunicodes[index] end if unicode and descriptions[unicode] then report_otf("preventing glyph %a at index %H to overload unicode %U",name or "noname",index,unicode) unicode=-1 end - if not unicode or unicode==-1 or unicode>=criterium then + if not unicode or unicode==-1 then if not name then name=format("u%06X",private) end @@ -7023,7 +7285,7 @@ actions["prepare glyphs"]=function(data,filename,raw) if glyph then local unicode=glyph.unicode local name=glyph.name - if not unicode or unicode==-1 or unicode>=criterium then + if not unicode or unicode==-1 then unicode=private unicodes[name]=private if trace_private then @@ -7045,7 +7307,6 @@ actions["prepare glyphs"]=function(data,filename,raw) } local altuni=glyph.altuni if altuni then - local d for i=1,#altuni do local a=altuni[i] local u=a.unicode @@ -7058,15 +7319,8 @@ actions["prepare glyphs"]=function(data,filename,raw) vv={ [u]=unicode } variants[v]=vv end - elseif d then - d[#d+1]=u - else - d={ u } end end - if d then - duplicates[unicode]=d - end end else report_otf("potential problem: glyph %U is used but empty",index) @@ -7084,47 +7338,45 @@ actions["check encoding"]=function(data,filename,raw) local duplicates=resources.duplicates local mapdata=raw.map or {} local unicodetoindex=mapdata and mapdata.map or {} + local indextounicode=mapdata and mapdata.backmap or {} local encname=lower(data.enc_name or mapdata.enc_name or "") - local criterium=0xFFFF + local criterium=0xFFFF + local privateoffset=constructors.privateoffset if find(encname,"unicode") then if trace_loading then report_otf("checking embedded unicode map %a",encname) end - for unicode,index in next,unicodetoindex do - if unicode<=criterium and not descriptions[unicode] then - local parent=indices[index] - if not parent then - report_otf("weird, unicode %U points to nowhere with index %H",unicode,index) + local reported={} + for maybeunicode,index in next,unicodetoindex do + if descriptions[maybeunicode] then + else + local unicode=indices[index] + if not unicode then + elseif maybeunicode==unicode then + elseif unicode>privateoffset then else - local parentdescription=descriptions[parent] - if parentdescription then - local altuni=parentdescription.altuni - if not altuni then - altuni={ { unicode=unicode } } - parentdescription.altuni=altuni - duplicates[parent]={ unicode } + local d=descriptions[unicode] + if d then + local c=d.copies + if c then + c[maybeunicode]=true else - local done=false - for i=1,#altuni do - if altuni[i].unicode==unicode then - done=true - break - end - end - if not done then - insert(altuni,{ unicode=unicode }) - insert(duplicates[parent],unicode) - end - end - if trace_loading then - report_otf("weird, unicode %U points to nowhere with index %H",unicode,index) + d.copies={ [maybeunicode]=true } end - else - report_otf("weird, unicode %U points to %U with index %H",unicode,index) + elseif index and not reported[index] then + report_otf("missing index %i",index) + reported[index]=true end end end end + for unicode,data in next,descriptions do + local d=data.copies + if d then + duplicates[unicode]=sortedkeys(d) + data.copies=nil + end + end elseif properties.cidinfo then report_otf("warning: no unicode map, used cidmap %a",properties.cidinfo.usedname) else @@ -7132,6 +7384,7 @@ actions["check encoding"]=function(data,filename,raw) end if mapdata then mapdata.map={} + mapdata.backmap={} end end actions["add duplicates"]=function(data,filename,raw) @@ -7142,28 +7395,37 @@ actions["add duplicates"]=function(data,filename,raw) local indices=resources.indices local duplicates=resources.duplicates for unicode,d in next,duplicates do - for i=1,#d do - local u=d[i] - if not descriptions[u] then - local description=descriptions[unicode] - local duplicate=table.copy(description) - duplicate.comment=format("copy of U+%05X",unicode) - descriptions[u]=duplicate - local n=0 - for _,description in next,descriptions do - if kerns then - local kerns=description.kerns - for _,k in next,kerns do - local ku=k[unicode] - if ku then - k[u]=ku - n=n+1 + local nofduplicates=#d + if nofduplicates>4 then + if trace_loading then + report_otf("ignoring excessive duplicates of %U (n=%s)",unicode,nofduplicates) + end + else + for i=1,nofduplicates do + local u=d[i] + if not descriptions[u] then + local description=descriptions[unicode] + local n=0 + for _,description in next,descriptions do + if kerns then + local kerns=description.kerns + for _,k in next,kerns do + local ku=k[unicode] + if ku then + k[u]=ku + n=n+1 + end end end end - end - if trace_loading then - report_otf("duplicating %U to %U with index %H (%s kerns)",unicode,u,description.index,n) + if u>0 then + local duplicate=table.copy(description) + duplicate.comment=format("copy of U+%05X",unicode) + descriptions[u]=duplicate + if trace_loading then + report_otf("duplicating %U to %U with index %H (%s kerns)",unicode,u,description.index,n) + end + end end end end @@ -7358,10 +7620,16 @@ actions["reorganize subtables"]=function(data,filename,raw) report_otf("skipping weird lookup number %s",k) elseif features then local f={} + local o={} for i=1,#features do local df=features[i] local tag=strip(lower(df.tag)) - local ft=f[tag] if not ft then ft={} f[tag]=ft end + local ft=f[tag] + if not ft then + ft={} + f[tag]=ft + o[#o+1]=tag + end local dscripts=df.scripts for i=1,#dscripts do local d=dscripts[i] @@ -7381,6 +7649,7 @@ actions["reorganize subtables"]=function(data,filename,raw) subtables=subtables, markclass=markclass, features=f, + order=o, } else lookups[name]={ @@ -7616,6 +7885,14 @@ actions["reorganize lookups"]=function(data,filename,raw) rule.current=s_hashed(names,s_h_cache) end rule.glyphs=nil + local lookups=rule.lookups + if lookups then + for i=1,#names do + if not lookups[i] then + lookups[i]="" + end + end + end end end end @@ -7887,6 +8164,11 @@ actions["check metadata"]=function(data,filename,raw) ttftables[i].data="deleted" end end + if metadata.validation_state and table.contains(metadata.validation_state,"bad_ps_fontname") then + local name=file.nameonly(filename) + metadata.fontname="bad-fontname-"..name + metadata.fullname="bad-fullname-"..name + end end actions["cleanup tables"]=function(data,filename,raw) data.resources.indices=nil @@ -8184,6 +8466,24 @@ local function otftotfm(specification) local features=specification.features.normal local rawdata=otf.load(filename,sub,features and features.featurefile) if rawdata and next(rawdata) then + local descriptions=rawdata.descriptions + local duplicates=rawdata.resources.duplicates + if duplicates then + local nofduplicates,nofduplicated=0,0 + for parent,list in next,duplicates do + for i=1,#list do + local unicode=list[i] + if not descriptions[unicode] then + descriptions[unicode]=descriptions[parent] + nofduplicated=nofduplicated+1 + end + end + nofduplicates=nofduplicates+#list + end + if trace_otf and nofduplicated~=nofduplicates then + report_otf("%i extra duplicates copied out of %i",nofduplicated,nofduplicates) + end + end rawdata.lookuphash={} tfmdata=copytotfm(rawdata,cache_id) if tfmdata and next(tfmdata) then @@ -8341,13 +8641,14 @@ local function gref(descriptions,n) return f_unicode(n) end elseif n then - local num,nam={},{} - for i=2,#n do + local num,nam,j={},{},0 + for i=1,#n do local ni=n[i] if tonumber(ni) then + j=j+1 local di=descriptions[ni] - num[i]=f_unicode(ni) - nam[i]=di and di.name or "-" + num[j]=f_unicode(ni) + nam[j]=di and di.name or "-" end end return f_unilist(num,nam) @@ -8430,8 +8731,8 @@ local function finalize_ligatures(tfmdata,ligatures) local ligature=ligatures[i] if ligature then local unicode,lookupdata=ligature[1],ligature[2] - if trace then - trace_ligatures_detail("building % a into %a",lookupdata,unicode) + if trace_ligatures_detail then + report_prepare("building % a into %a",lookupdata,unicode) end local size=#lookupdata local firstcode=lookupdata[1] @@ -8443,8 +8744,8 @@ local function finalize_ligatures(tfmdata,ligatures) local firstdata=characters[firstcode] if not firstdata then firstcode=private - if trace then - trace_ligatures_detail("defining %a as %a",firstname,firstcode) + if trace_ligatures_detail then + report_prepare("defining %a as %a",firstname,firstcode) end unicodes[firstname]=firstcode firstdata={ intermediate=true,ligatures={} } @@ -8467,8 +8768,8 @@ local function finalize_ligatures(tfmdata,ligatures) break end end - if trace then - trace_ligatures_detail("codes (%a,%a) + (%a,%a) -> %a",firstname,firstcode,secondname,secondcode,target) + if trace_ligatures_detail then + report_prepare("codes (%a,%a) + (%a,%a) -> %a",firstname,firstcode,secondname,secondcode,target) end local firstligs=firstdata.ligatures if firstligs then @@ -8479,6 +8780,8 @@ local function finalize_ligatures(tfmdata,ligatures) firstcode=target firstname=secondname end + elseif trace_ligatures_detail then + report_prepare("no glyph (%a,%a) for building %a",firstname,firstcode,target) end if okay then ligatures[i]=false @@ -8488,12 +8791,14 @@ local function finalize_ligatures(tfmdata,ligatures) end alldone=done==0 end - if trace then - for k,v in next,characters do - if v.ligatures then table.print(v,k) end + if trace_ligatures_detail then + for k,v in table.sortedhash(characters) do + if v.ligatures then + table.print(v,k) + end end end - tfmdata.resources.private=private + resources.private=private end end local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist) @@ -8712,7 +9017,7 @@ local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplis end changed[unicode]=data elseif lookuptype=="alternate" then - local replacement=data[alternate] + local replacement=data[alternate] if replacement then changed[unicode]=replacement if trace_alternatives then @@ -8803,8 +9108,9 @@ basemethods.shared={ basemethod="independent" local function featuresinitializer(tfmdata,value) if true then - local t=trace_preparing and os.clock() + local starttime=trace_preparing and os.clock() local features=tfmdata.shared.features + local fullname=trace_preparing and tfmdata.properties.fullname if features then applybasemethod("initializehashes",tfmdata) local collectlookups=otf.collectlookups @@ -8814,26 +9120,34 @@ local function featuresinitializer(tfmdata,value) local language=properties.language local basesubstitutions=rawdata.resources.features.gsub local basepositionings=rawdata.resources.features.gpos - if basesubstitutions then - for feature,data in next,basesubstitutions do - local value=features[feature] - if value then - local validlookups,lookuplist=collectlookups(rawdata,feature,script,language) - if validlookups then - applybasemethod("preparesubstitutions",tfmdata,feature,value,validlookups,lookuplist) - registerbasefeature(feature,value) - end - end - end - end - if basepositionings then - for feature,data in next,basepositionings do - local value=features[feature] - if value then - local validlookups,lookuplist=collectlookups(rawdata,feature,script,language) - if validlookups then - applybasemethod("preparepositionings",tfmdata,feature,features[feature],validlookups,lookuplist) - registerbasefeature(feature,value) + if basesubstitutions or basepositionings then + local sequences=tfmdata.resources.sequences + for s=1,#sequences do + local sequence=sequences[s] + local sfeatures=sequence.features + if sfeatures then + local order=sequence.order + if order then + for i=1,#order do + local feature=order[i] + if features[feature] then + local validlookups,lookuplist=collectlookups(rawdata,feature,script,language) + if not validlookups then + elseif basesubstitutions and basesubstitutions[feature] then + if trace_preparing then + report_prepare("filtering base feature %a for %a",feature,fullname) + end + applybasemethod("preparesubstitutions",tfmdata,feature,value,validlookups,lookuplist) + registerbasefeature(feature,value) + elseif basepositionings and basepositionings[feature] then + if trace_preparing then + report_prepare("filtering base feature %a for %a",feature,fullname) + end + applybasemethod("preparepositionings",tfmdata,feature,features[feature],validlookups,lookuplist) + registerbasefeature(feature,value) + end + end + end end end end @@ -8841,7 +9155,7 @@ local function featuresinitializer(tfmdata,value) registerbasehash(tfmdata) end if trace_preparing then - report_prepare("preparation time is %0.3f seconds for %a",os.clock()-t,tfmdata.properties.fullname) + report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname) end end end @@ -8881,26 +9195,12 @@ nodes.injections=nodes.injections or {} local injections=nodes.injections local nodecodes=nodes.nodecodes local glyph_code=nodecodes.glyph -local disc_code=nodecodes.disc local kern_code=nodecodes.kern -local nuts=nodes.nuts -local nodepool=nuts.pool +local nodepool=nodes.pool local newkern=nodepool.kern -local tonode=nuts.tonode -local tonut=nuts.tonut -local getfield=nuts.getfield -local getnext=nuts.getnext -local getprev=nuts.getprev -local getid=nuts.getid -local getattr=nuts.getattr -local getfont=nuts.getfont -local getsubtype=nuts.getsubtype -local getchar=nuts.getchar -local setfield=nuts.setfield -local setattr=nuts.setattr -local traverse_id=nuts.traverse_id -local insert_node_before=nuts.insert_before -local insert_node_after=nuts.insert_after +local traverse_id=node.traverse_id +local insert_node_before=node.insert_before +local insert_node_after=node.insert_after local a_kernpair=attributes.private('kernpair') local a_ligacomp=attributes.private('ligacomp') local a_markbase=attributes.private('markbase') @@ -8919,21 +9219,21 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne local dx,dy=factor*(exit[1]-entry[1]),factor*(exit[2]-entry[2]) local ws,wn=tfmstart.width,tfmnext.width local bound=#cursives+1 - setattr(start,a_cursbase,bound) - setattr(nxt,a_curscurs,bound) + start[a_cursbase]=bound + nxt[a_curscurs]=bound cursives[bound]={ rlmode,dx,dy,ws,wn } return dx,dy,bound end function injections.setpair(current,factor,rlmode,r2lflag,spec,tfmchr) local x,y,w,h=factor*spec[1],factor*spec[2],factor*spec[3],factor*spec[4] if x~=0 or w~=0 or y~=0 or h~=0 then - local bound=getattr(current,a_kernpair) + local bound=current[a_kernpair] if bound then local kb=kerns[bound] kb[2],kb[3],kb[4],kb[5]=(kb[2] or 0)+x,(kb[3] or 0)+y,(kb[4] or 0)+w,(kb[5] or 0)+h else bound=#kerns+1 - setattr(current,a_kernpair,bound) + current[a_kernpair]=bound kerns[bound]={ rlmode,x,y,w,h,r2lflag,tfmchr.width } end return x,y,w,h,bound @@ -8944,35 +9244,35 @@ function injections.setkern(current,factor,rlmode,x,tfmchr) local dx=factor*x if dx~=0 then local bound=#kerns+1 - setattr(current,a_kernpair,bound) + current[a_kernpair]=bound kerns[bound]={ rlmode,dx } return dx,bound else return 0,0 end end -function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark) - local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2]) - local bound=getattr(base,a_markbase) +function injections.setmark(start,base,factor,rlmode,ba,ma) + local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2]) + local bound=base[a_markbase] local index=1 if bound then local mb=marks[bound] if mb then index=#mb+1 mb[index]={ dx,dy,rlmode } - setattr(start,a_markmark,bound) - setattr(start,a_markdone,index) + start[a_markmark]=bound + start[a_markdone]=index return dx,dy,bound else - report_injections("possible problem, %U is base mark without data (id %a)",getchar(base),bound) + report_injections("possible problem, %U is base mark without data (id %a)",base.char,bound) end end index=index or 1 bound=#marks+1 - setattr(base,a_markbase,bound) - setattr(start,a_markmark,bound) - setattr(start,a_markdone,index) - marks[bound]={ [index]={ dx,dy,rlmode,baseismark } } + base[a_markbase]=bound + start[a_markmark]=bound + start[a_markdone]=index + marks[bound]={ [index]={ dx,dy,rlmode } } return dx,dy,bound end local function dir(n) @@ -8981,15 +9281,15 @@ end local function trace(head) report_injections("begin run") for n in traverse_id(glyph_code,head) do - if getsubtype(n)<256 then - local kp=getattr(n,a_kernpair) - local mb=getattr(n,a_markbase) - local mm=getattr(n,a_markmark) - local md=getattr(n,a_markdone) - local cb=getattr(n,a_cursbase) - local cc=getattr(n,a_curscurs) - local char=getchar(n) - report_injections("font %s, char %U, glyph %c",getfont(n),char,char) + if n.subtype<256 then + local kp=n[a_kernpair] + local mb=n[a_markbase] + local mm=n[a_markmark] + local md=n[a_markdone] + local cb=n[a_cursbase] + local cc=n[a_curscurs] + local char=n.char + report_injections("font %s, char %U, glyph %c",n.font,char,char) if kp then local k=kerns[kp] if k[3] then @@ -9030,23 +9330,21 @@ local function show_result(head) local current=head local skipping=false while current do - local id=getid(current) + local id=current.id if id==glyph_code then - report_injections("char: %C, width %p, xoffset %p, yoffset %p", - getchar(current),getfield(current,"width"),getfield(current,"xoffset"),getfield(current,"yoffset")) + report_injections("char: %C, width %p, xoffset %p, yoffset %p",current.char,current.width,current.xoffset,current.yoffset) skipping=false elseif id==kern_code then - report_injections("kern: %p",getfield(current,"kern")) + report_injections("kern: %p",current.kern) skipping=false elseif not skipping then report_injections() skipping=true end - current=getnext(current) + current=current.next end end function injections.handler(head,where,keep) - head=tonut(head) local has_marks,has_cursives,has_kerns=next(marks),next(cursives),next(kerns) if has_marks or has_cursives then if trace_injections then @@ -9056,18 +9354,17 @@ function injections.handler(head,where,keep) if has_kerns then local nf,tm=nil,nil for n in traverse_id(glyph_code,head) do - if getsubtype(n)<256 then + if n.subtype<256 then nofvalid=nofvalid+1 valid[nofvalid]=n - local f=getfont(n) - if f~=nf then - nf=f - tm=fontdata[nf].resources.marks + if n.font~=nf then + nf=n.font + tm=fontdata[nf].resources.marks end if tm then - mk[n]=tm[getchar(n)] + mk[n]=tm[n.char] end - local k=getattr(n,a_kernpair) + local k=n[a_kernpair] if k then local kk=kerns[k] if kk then @@ -9087,16 +9384,15 @@ function injections.handler(head,where,keep) else local nf,tm=nil,nil for n in traverse_id(glyph_code,head) do - if getsubtype(n)<256 then + if n.subtype<256 then nofvalid=nofvalid+1 valid[nofvalid]=n - local f=getfont(n) - if f~=nf then - nf=f - tm=fontdata[nf].resources.marks + if n.font~=nf then + nf=n.font + tm=fontdata[nf].resources.marks end if tm then - mk[n]=tm[getchar(n)] + mk[n]=tm[n.char] end end end @@ -9105,7 +9401,7 @@ function injections.handler(head,where,keep) local cx={} if has_kerns and next(ky) then for n,k in next,ky do - setfield(n,"yoffset",k) + n.yoffset=k end end if has_cursives then @@ -9114,9 +9410,9 @@ function injections.handler(head,where,keep) for i=1,nofvalid do local n=valid[i] if not mk[n] then - local n_cursbase=getattr(n,a_cursbase) + local n_cursbase=n[a_cursbase] if p_cursbase then - local n_curscurs=getattr(n,a_curscurs) + local n_curscurs=n[a_curscurs] if p_cursbase==n_curscurs then local c=cursives[n_curscurs] if c then @@ -9139,20 +9435,20 @@ function injections.handler(head,where,keep) end end elseif maxt>0 then - local ny=getfield(n,"yoffset") + local ny=n.yoffset for i=maxt,1,-1 do ny=ny+d[i] local ti=t[i] - setfield(ti,"yoffset",getfield(ti,"yoffset")+ny) + ti.yoffset=ti.yoffset+ny end maxt=0 end if not n_cursbase and maxt>0 then - local ny=getfield(n,"yoffset") + local ny=n.yoffset for i=maxt,1,-1 do ny=ny+d[i] local ti=t[i] - setfield(ti,"yoffset",ny) + ti.yoffset=ny end maxt=0 end @@ -9160,11 +9456,11 @@ function injections.handler(head,where,keep) end end if maxt>0 then - local ny=getfield(n,"yoffset") + local ny=n.yoffset for i=maxt,1,-1 do ny=ny+d[i] local ti=t[i] - setfield(ti,"yoffset",ny) + ti.yoffset=ny end maxt=0 end @@ -9175,66 +9471,57 @@ function injections.handler(head,where,keep) if has_marks then for i=1,nofvalid do local p=valid[i] - local p_markbase=getattr(p,a_markbase) + local p_markbase=p[a_markbase] if p_markbase then local mrks=marks[p_markbase] local nofmarks=#mrks - for n in traverse_id(glyph_code,getnext(p)) do - local n_markmark=getattr(n,a_markmark) + for n in traverse_id(glyph_code,p.next) do + local n_markmark=n[a_markmark] if p_markbase==n_markmark then - local index=getattr(n,a_markdone) or 1 + local index=n[a_markdone] or 1 local d=mrks[index] if d then local rlmode=d[3] local k=wx[p] - local px=getfield(p,"xoffset") - local ox=0 if k then local x=k[2] local w=k[4] if w then if rlmode and rlmode>=0 then - ox=px-getfield(p,"width")+d[1]-(w-x) + n.xoffset=p.xoffset-p.width+d[1]-(w-x) else - ox=px-d[1]-x + n.xoffset=p.xoffset-d[1]-x end else if rlmode and rlmode>=0 then - ox=px-getfield(p,"width")+d[1] + n.xoffset=p.xoffset-p.width+d[1] else - ox=px-d[1]-x + n.xoffset=p.xoffset-d[1]-x end end else - local wp=getfield(p,"width") - local wn=getfield(n,"width") if rlmode and rlmode>=0 then - ox=px-wp+d[1] + n.xoffset=p.xoffset-p.width+d[1] else - ox=px-d[1] + n.xoffset=p.xoffset-d[1] end - if wn~=0 then - insert_node_before(head,n,newkern(-wn/2)) - insert_node_after(head,n,newkern(-wn/2)) + local w=n.width + if w~=0 then + insert_node_before(head,n,newkern(-w/2)) + insert_node_after(head,n,newkern(-w/2)) end end - setfield(n,"xoffset",ox) - local py=getfield(p,"yoffset") - local oy=0 if mk[p] then - oy=py+d[2] + n.yoffset=p.yoffset+d[2] else - oy=getfield(n,"yoffset")+py+d[2] + n.yoffset=n.yoffset+p.yoffset+d[2] end - setfield(n,"yoffset",oy) if nofmarks==1 then break else nofmarks=nofmarks-1 end end - elseif not n_markmark then - break else end end @@ -9286,7 +9573,6 @@ function injections.handler(head,where,keep) if not keep then kerns={} end -head=tonode(head) return head,true elseif not keep then kerns,cursives,marks={},{},{} @@ -9296,14 +9582,14 @@ head=tonode(head) trace(head) end for n in traverse_id(glyph_code,head) do - if getsubtype(n)<256 then - local k=getattr(n,a_kernpair) + if n.subtype<256 then + local k=n[a_kernpair] if k then local kk=kerns[k] if kk then local rl,x,y,w=kk[1],kk[2] or 0,kk[3],kk[4] if y and y~=0 then - setfield(n,"yoffset",y) + n.yoffset=y end if w then local wx=w-x @@ -9334,10 +9620,10 @@ head=tonode(head) if not keep then kerns={} end - return tonode(head),true + return head,true else end - return tonode(head),false + return head,false end end -- closure @@ -9511,6 +9797,7 @@ local isolated={ [0x0856]=true,[0x0858]=true,[0x0857]=true, [0x07FA]=true, [zwnj]=true, + [0x08AD]=true, } local final={ [0x0622]=true,[0x0623]=true,[0x0624]=true,[0x0625]=true, @@ -9528,15 +9815,16 @@ local final={ [0x06D3]=true,[0x06D5]=true,[0x06EE]=true,[0x06EF]=true, [0x0759]=true,[0x075A]=true,[0x075B]=true,[0x076B]=true, [0x076C]=true,[0x0771]=true,[0x0773]=true,[0x0774]=true, - [0x0778]=true,[0x0779]=true, + [0x0778]=true,[0x0779]=true, [0x08AA]=true,[0x08AB]=true,[0x08AC]=true, [0xFEF5]=true,[0xFEF7]=true,[0xFEF9]=true,[0xFEFB]=true, - [0x0710]=true,[0x0715]=true,[0x0716]=true,[0x0717]=true, - [0x0718]=true,[0x0719]=true,[0x0728]=true,[0x072A]=true, - [0x072C]=true,[0x071E]=true, + [0x0710]=true,[0x0715]=true,[0x0716]=true,[0x0717]=true, + [0x0718]=true,[0x0719]=true,[0x0728]=true,[0x072A]=true, + [0x072C]=true,[0x071E]=true, [0x072F]=true,[0x074D]=true, [0x0840]=true,[0x0849]=true,[0x0854]=true,[0x0846]=true, - [0x084F]=true + [0x084F]=true, + [0x08AE]=true,[0x08B1]=true,[0x08B2]=true, } local medial={ [0x0626]=true,[0x0628]=true,[0x062A]=true,[0x062B]=true, @@ -9596,8 +9884,8 @@ local medial={ [0x07D2]=true,[0x07D0]=true,[0x07CF]=true,[0x07CD]=true, [0x07CB]=true,[0x07D3]=true,[0x07E4]=true,[0x07D5]=true, [0x07E6]=true, - [tatweel]=true, - [zwj]=true, + [tatweel]=true,[zwj]=true, + [0x08A1]=true,[0x08AF]=true,[0x08B0]=true, } local arab_warned={} local function warning(current,what) @@ -9752,25 +10040,12 @@ registertracker("otf.positions","otf.marks,otf.kerns,otf.cursive") registertracker("otf.actions","otf.replacements,otf.positions") registertracker("otf.injections","nodes.injections") registertracker("*otf.sample","otf.steps,otf.actions,otf.analyzing") -local nuts=nodes.nuts -local tonode=nuts.tonode -local tonut=nuts.tonut -local getfield=nuts.getfield -local getnext=nuts.getnext -local getprev=nuts.getprev -local getid=nuts.getid -local getattr=nuts.getattr -local getfont=nuts.getfont -local getsubtype=nuts.getsubtype -local getchar=nuts.getchar -local setfield=nuts.setfield -local setattr=nuts.setattr -local insert_node_after=nuts.insert_after -local delete_node=nuts.delete -local copy_node=nuts.copy -local find_node_tail=nuts.tail -local flush_node_list=nuts.flush_list -local end_of_math=nuts.end_of_math +local insert_node_after=node.insert_after +local delete_node=nodes.delete +local copy_node=node.copy +local find_node_tail=node.tail or node.slide +local flush_node_list=node.flush_list +local end_of_math=node.end_of_math local setmetatableindex=table.setmetatableindex local zwnj=0x200C local zwj=0x200D @@ -9881,83 +10156,83 @@ local function pref(kind,lookupname) return formatters["feature %a, lookup %a"](kind,lookupname) end local function copy_glyph(g) - local components=getfield(g,"components") + local components=g.components if components then - setfield(g,"components",nil) + g.components=nil local n=copy_node(g) - setfield(g,"components",components) + g.components=components return n else return copy_node(g) end end local function markstoligature(kind,lookupname,head,start,stop,char) - if start==stop and getchar(start)==char then + if start==stop and start.char==char then return head,start else - local prev=getprev(start) - local next=getnext(stop) - setfield(start,"prev",nil) - setfield(stop,"next",nil) + local prev=start.prev + local next=stop.next + start.prev=nil + stop.next=nil local base=copy_glyph(start) if head==start then head=base end - setfield(base,"char",char) - setfield(base,"subtype",ligature_code) - setfield(base,"components",start) + base.char=char + base.subtype=ligature_code + base.components=start if prev then - setfield(prev,"next",base) + prev.next=base end if next then - setfield(next,"prev",base) + next.prev=base end - setfield(base,"next",next) - setfield(base,"prev",prev) + base.next=next + base.prev=prev return head,base end end local function getcomponentindex(start) - if getid(start)~=glyph_code then + if start.id~=glyph_code then return 0 - elseif getsubtype(start)==ligature_code then + elseif start.subtype==ligature_code then local i=0 - local components=getfield(start,"components") + local components=start.components while components do i=i+getcomponentindex(components) - components=getnext(components) + components=components.next end return i - elseif not marks[getchar(start)] then + elseif not marks[start.char] then return 1 else return 0 end end local function toligature(kind,lookupname,head,start,stop,char,markflag,discfound) - if start==stop and getchar(start)==char then - setfield(start,"char",char) + if start==stop and start.char==char then + start.char=char return head,start end - local prev=getprev(start) - local next=getnext(stop) - setfield(start,"prev",nil) - setfield(stop,"next",nil) + local prev=start.prev + local next=stop.next + start.prev=nil + stop.next=nil local base=copy_glyph(start) if start==head then head=base end - setfield(base,"char",char) - setfield(base,"subtype",ligature_code) - setfield(base,"components",start) + base.char=char + base.subtype=ligature_code + base.components=start if prev then - setfield(prev,"next",base) + prev.next=base end if next then - setfield(next,"prev",base) + next.prev=base end - setfield(base,"next",next) - setfield(base,"prev",prev) + base.next=next + base.prev=prev if not discfound then local deletemarks=markflag~="mark" local components=start @@ -9966,42 +10241,42 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun local head=base local current=base while start do - local char=getchar(start) + local char=start.char if not marks[char] then baseindex=baseindex+componentindex componentindex=getcomponentindex(start) elseif not deletemarks then - setattr(start,a_ligacomp,baseindex+(getattr(start,a_ligacomp) or componentindex)) + start[a_ligacomp]=baseindex+(start[a_ligacomp] or componentindex) if trace_marks then - logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),getattr(start,a_ligacomp)) + logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp]) end head,current=insert_node_after(head,current,copy_node(start)) elseif trace_marks then logwarning("%s: delete mark %s",pref(kind,lookupname),gref(char)) end - start=getnext(start) + start=start.next end - local start=getnext(current) - while start and getid(start)==glyph_code do - local char=getchar(start) + local start=current.next + while start and start.id==glyph_code do + local char=start.char if marks[char] then - setattr(start,a_ligacomp,baseindex+(getattr(start,a_ligacomp) or componentindex)) + start[a_ligacomp]=baseindex+(start[a_ligacomp] or componentindex) if trace_marks then - logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),getattr(start,a_ligacomp)) + logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp]) end else break end - start=getnext(start) + start=start.next end end return head,base end function handlers.gsub_single(head,start,kind,lookupname,replacement) if trace_singles then - logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(getchar(start)),gref(replacement)) + logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(start.char),gref(replacement)) end - setfield(start,"char",replacement) + start.char=replacement return head,start,true end local function get_alternative_glyph(start,alternatives,value,trace_alternatives) @@ -10027,7 +10302,7 @@ local function get_alternative_glyph(start,alternatives,value,trace_alternatives return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range") end elseif value==0 then - return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change") + return start.char,trace_alternatives and formatters["invalid value %a, %s"](value,"no change") elseif value<1 then return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1) else @@ -10038,25 +10313,25 @@ end local function multiple_glyphs(head,start,multiple,ignoremarks) local nofmultiples=#multiple if nofmultiples>0 then - setfield(start,"char",multiple[1]) + start.char=multiple[1] if nofmultiples>1 then - local sn=getnext(start) + local sn=start.next for k=2,nofmultiples do local n=copy_node(start) - setfield(n,"char",multiple[k]) - setfield(n,"next",sn) - setfield(n,"prev",start) + n.char=multiple[k] + n.next=sn + n.prev=start if sn then - setfield(sn,"prev",n) + sn.prev=n end - setfield(start,"next",n) + start.next=n start=n end end return head,start,true else if trace_multiples then - logprocess("no multiple for %s",gref(getchar(start))) + logprocess("no multiple for %s",gref(start.char)) end return head,start,false end @@ -10066,34 +10341,34 @@ function handlers.gsub_alternate(head,start,kind,lookupname,alternative,sequence local choice,comment=get_alternative_glyph(start,alternative,value,trace_alternatives) if choice then if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(getchar(start)),choice,gref(choice),comment) + logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(start.char),choice,gref(choice),comment) end - setfield(start,"char",choice) + start.char=choice else if trace_alternatives then - logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(getchar(start)),comment) + logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(start.char),comment) end end return head,start,true end function handlers.gsub_multiple(head,start,kind,lookupname,multiple,sequence) if trace_multiples then - logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(getchar(start)),gref(multiple)) + logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(start.char),gref(multiple)) end return multiple_glyphs(head,start,multiple,sequence.flags[1]) end function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) - local s,stop,discfound=getnext(start),nil,false - local startchar=getchar(start) + local s,stop,discfound=start.next,nil,false + local startchar=start.char if marks[startchar] then while s do - local id=getid(s) - if id==glyph_code and getfont(s)==currentfont and getsubtype(s)<256 then - local lg=ligature[getchar(s)] + local id=s.id + if id==glyph_code and s.font==currentfont and s.subtype<256 then + local lg=ligature[s.char] if lg then stop=s ligature=lg - s=getnext(s) + s=s.next else break end @@ -10105,9 +10380,9 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) local lig=ligature.ligature if lig then if trace_ligatures then - local stopchar=getchar(stop) + local stopchar=stop.char head,start=markstoligature(kind,lookupname,head,start,stop,lig) - logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(getchar(start))) + logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) else head,start=markstoligature(kind,lookupname,head,start,stop,lig) end @@ -10118,18 +10393,18 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) else local skipmark=sequence.flags[1] while s do - local id=getid(s) - if id==glyph_code and getsubtype(s)<256 then - if getfont(s)==currentfont then - local char=getchar(s) + local id=s.id + if id==glyph_code and s.subtype<256 then + if s.font==currentfont then + local char=s.char if skipmark and marks[char] then - s=getnext(s) + s=s.next else local lg=ligature[char] if lg then stop=s ligature=lg - s=getnext(s) + s=s.next else break end @@ -10139,7 +10414,7 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) end elseif id==disc_code then discfound=true - s=getnext(s) + s=s.next else break end @@ -10148,35 +10423,36 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) if lig then if stop then if trace_ligatures then - local stopchar=getchar(stop) + local stopchar=stop.char head,start=toligature(kind,lookupname,head,start,stop,lig,skipmark,discfound) - logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(getchar(start))) + logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) else head,start=toligature(kind,lookupname,head,start,stop,lig,skipmark,discfound) end + return head,start,true else - setfield(start,"char",lig) + start.char=lig if trace_ligatures then logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(kind,lookupname),gref(startchar),gref(lig)) end + return head,start,true end - return head,start,true else end end return head,start,false end function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence) - local markchar=getchar(start) + local markchar=start.char if marks[markchar] then - local base=getprev(start) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - local basechar=getchar(base) + local base=start.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + local basechar=base.char if marks[basechar] then while true do - base=getprev(base) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - basechar=getchar(base) + base=base.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + basechar=base.char if not marks[basechar] then break end @@ -10225,16 +10501,16 @@ function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence return head,start,false end function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequence) - local markchar=getchar(start) + local markchar=start.char if marks[markchar] then - local base=getprev(start) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - local basechar=getchar(base) + local base=start.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + local basechar=base.char if marks[basechar] then while true do - base=getprev(base) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - basechar=getchar(base) + base=base.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + basechar=base.char if not marks[basechar] then break end @@ -10246,7 +10522,7 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ end end end - local index=getattr(start,a_ligacomp) + local index=start[a_ligacomp] local baseanchors=descriptions[basechar] if baseanchors then baseanchors=baseanchors.anchors @@ -10291,22 +10567,22 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ return head,start,false end function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence) - local markchar=getchar(start) + local markchar=start.char if marks[markchar] then - local base=getprev(start) - local slc=getattr(start,a_ligacomp) + local base=start.prev + local slc=start[a_ligacomp] if slc then while base do - local blc=getattr(base,a_ligacomp) + local blc=base[a_ligacomp] if blc and blc~=slc then - base=getprev(base) + base=base.prev else break end end end - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - local basechar=getchar(base) + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + local basechar=base.char local baseanchors=descriptions[basechar] if baseanchors then baseanchors=baseanchors.anchors @@ -10344,20 +10620,20 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence return head,start,false end function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) - local alreadydone=cursonce and getattr(start,a_cursbase) + local alreadydone=cursonce and start[a_cursbase] if not alreadydone then local done=false - local startchar=getchar(start) + local startchar=start.char if marks[startchar] then if trace_cursive then logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar)) end else - local nxt=getnext(start) - while not done and nxt and getid(nxt)==glyph_code and getfont(nxt)==currentfont and getsubtype(nxt)<256 do - local nextchar=getchar(nxt) + local nxt=start.next + while not done and nxt and nxt.id==glyph_code and nxt.font==currentfont and nxt.subtype<256 do + local nextchar=nxt.char if marks[nextchar] then - nxt=getnext(nxt) + nxt=nxt.next else local entryanchors=descriptions[nextchar] if entryanchors then @@ -10391,13 +10667,13 @@ function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) return head,start,done else if trace_cursive and trace_details then - logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(getchar(start)),alreadydone) + logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone) end return head,start,false end end function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence) - local startchar=getchar(start) + local startchar=start.char local dx,dy,w,h=setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) if trace_kerns then logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) @@ -10405,33 +10681,33 @@ function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence) return head,start,false end function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) - local snext=getnext(start) + local snext=start.next if not snext then return head,start,false else local prev,done=start,false local factor=tfmdata.parameters.factor local lookuptype=lookuptypes[lookupname] - while snext and getid(snext)==glyph_code and getfont(snext)==currentfont and getsubtype(snext)<256 do - local nextchar=getchar(snext) + while snext and snext.id==glyph_code and snext.font==currentfont and snext.subtype<256 do + local nextchar=snext.char local krn=kerns[nextchar] if not krn and marks[nextchar] then prev=snext - snext=getnext(snext) + snext=snext.next else if not krn then elseif type(krn)=="table" then if lookuptype=="pair" then local a,b=krn[2],krn[3] if a and #a>0 then - local startchar=getchar(start) + local startchar=start.char local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b>0 then - local startchar=getchar(start) + local startchar=start.char local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) @@ -10444,7 +10720,7 @@ function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) elseif krn~=0 then local k=setkern(snext,factor,rlmode,krn) if trace_kerns then - logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(getchar(prev)),gref(nextchar)) + logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar)) end done=true end @@ -10479,13 +10755,13 @@ function chainmores.chainsub(head,start,stop,kind,chainname,currentcontext,looku return head,start,false end function chainprocs.reversesub(head,start,stop,kind,chainname,currentcontext,lookuphash,replacements) - local char=getchar(start) + local char=start.char local replacement=replacements[char] if replacement then if trace_singles then logprocess("%s: single reverse replacement of %s by %s",cref(kind,chainname),gref(char),gref(replacement)) end - setfield(start,"char",replacement) + start.char=replacement return head,start,true else return head,start,false @@ -10498,8 +10774,8 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo logwarning("todo: check if we need to loop over the replacements: %s",concat(subtables," ")) end while current do - if getid(current)==glyph_code then - local currentchar=getchar(current) + if current.id==glyph_code then + local currentchar=current.char local lookupname=subtables[1] local replacement=lookuphash[lookupname] if not replacement then @@ -10516,21 +10792,21 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo if trace_singles then logprocess("%s: replacing single %s by %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar),gref(replacement)) end - setfield(current,"char",replacement) + current.char=replacement end end return head,start,true elseif current==stop then break else - current=getnext(current) + current=current.next end end return head,start,false end chainmores.gsub_single=chainprocs.gsub_single function chainprocs.gsub_multiple(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local startchar=getchar(start) + local startchar=start.char local subtables=currentlookup.subtables local lookupname=subtables[1] local replacements=lookuphash[lookupname] @@ -10559,8 +10835,8 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext local subtables=currentlookup.subtables local value=featurevalue==true and tfmdata.shared.features[kind] or featurevalue while current do - if getid(current)==glyph_code then - local currentchar=getchar(current) + if current.id==glyph_code then + local currentchar=current.char local lookupname=subtables[1] local alternatives=lookuphash[lookupname] if not alternatives then @@ -10575,7 +10851,7 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext if trace_alternatives then logprocess("%s: replacing %s by alternative %a to %s, %s",cref(kind,chainname,chainlookupname,lookupname),gref(char),choice,gref(choice),comment) end - setfield(start,"char",choice) + start.char=choice else if trace_alternatives then logwarning("%s: no variant %a for %s, %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(char),comment) @@ -10589,14 +10865,14 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext elseif current==stop then break else - current=getnext(current) + current=current.next end end return head,start,false end chainmores.gsub_alternate=chainprocs.gsub_alternate function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex) - local startchar=getchar(start) + local startchar=start.char local subtables=currentlookup.subtables local lookupname=subtables[1] local ligatures=lookuphash[lookupname] @@ -10611,20 +10887,20 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, logwarning("%s: no ligatures starting with %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) end else - local s=getnext(start) + local s=start.next local discfound=false local last=stop local nofreplacements=0 local skipmark=currentlookup.flags[1] while s do - local id=getid(s) + local id=s.id if id==disc_code then - s=getnext(s) + s=s.next discfound=true else - local schar=getchar(s) + local schar=s.char if skipmark and marks[schar] then - s=getnext(s) + s=s.next else local lg=ligatures[schar] if lg then @@ -10632,7 +10908,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if s==stop then break else - s=getnext(s) + s=s.next end else break @@ -10649,7 +10925,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if start==stop then logprocess("%s: replacing character %s by ligature %s case 3",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(l2)) else - logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(getchar(stop)),gref(l2)) + logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char),gref(l2)) end end head,start=toligature(kind,lookupname,head,start,stop,l2,currentlookup.flags[1],discfound) @@ -10658,7 +10934,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if start==stop then logwarning("%s: replacing character %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) else - logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(getchar(stop))) + logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char)) end end end @@ -10667,7 +10943,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, end chainmores.gsub_ligature=chainprocs.gsub_ligature function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar=getchar(start) + local markchar=start.char if marks[markchar] then local subtables=currentlookup.subtables local lookupname=subtables[1] @@ -10676,14 +10952,14 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext markanchors=markanchors[markchar] end if markanchors then - local base=getprev(start) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - local basechar=getchar(base) + local base=start.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + local basechar=base.char if marks[basechar] then while true do - base=getprev(base) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - basechar=getchar(base) + base=base.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + basechar=base.char if not marks[basechar] then break end @@ -10730,7 +11006,7 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext return head,start,false end function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar=getchar(start) + local markchar=start.char if marks[markchar] then local subtables=currentlookup.subtables local lookupname=subtables[1] @@ -10739,14 +11015,14 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon markanchors=markanchors[markchar] end if markanchors then - local base=getprev(start) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - local basechar=getchar(base) + local base=start.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + local basechar=base.char if marks[basechar] then while true do - base=getprev(base) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - basechar=getchar(base) + base=base.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + basechar=base.char if not marks[basechar] then break end @@ -10758,7 +11034,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon end end end - local index=getattr(start,a_ligacomp) + local index=start[a_ligacomp] local baseanchors=descriptions[basechar].anchors if baseanchors then local baseanchors=baseanchors['baselig'] @@ -10797,7 +11073,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon return head,start,false end function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar=getchar(start) + local markchar=start.char if marks[markchar] then local subtables=currentlookup.subtables local lookupname=subtables[1] @@ -10806,20 +11082,20 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext markanchors=markanchors[markchar] end if markanchors then - local base=getprev(start) - local slc=getattr(start,a_ligacomp) + local base=start.prev + local slc=start[a_ligacomp] if slc then while base do - local blc=getattr(base,a_ligacomp) + local blc=base[a_ligacomp] if blc and blc~=slc then - base=getprev(base) + base=base.prev else break end end end - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - local basechar=getchar(base) + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + local basechar=base.char local baseanchors=descriptions[basechar].anchors if baseanchors then baseanchors=baseanchors['basemark'] @@ -10855,9 +11131,9 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext return head,start,false end function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local alreadydone=cursonce and getattr(start,a_cursbase) + local alreadydone=cursonce and start[a_cursbase] if not alreadydone then - local startchar=getchar(start) + local startchar=start.char local subtables=currentlookup.subtables local lookupname=subtables[1] local exitanchors=lookuphash[lookupname] @@ -10871,11 +11147,11 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar)) end else - local nxt=getnext(start) - while not done and nxt and getid(nxt)==glyph_code and getfont(nxt)==currentfont and getsubtype(nxt)<256 do - local nextchar=getchar(nxt) + local nxt=start.next + while not done and nxt and nxt.id==glyph_code and nxt.font==currentfont and nxt.subtype<256 do + local nextchar=nxt.char if marks[nextchar] then - nxt=getnext(nxt) + nxt=nxt.next else local entryanchors=descriptions[nextchar] if entryanchors then @@ -10909,7 +11185,7 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l return head,start,done else if trace_cursive and trace_details then - logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(getchar(start)),alreadydone) + logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone) end return head,start,false end @@ -10917,7 +11193,7 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l return head,start,false end function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) - local startchar=getchar(start) + local startchar=start.char local subtables=currentlookup.subtables local lookupname=subtables[1] local kerns=lookuphash[lookupname] @@ -10934,9 +11210,9 @@ function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lo end chainmores.gpos_single=chainprocs.gpos_single function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) - local snext=getnext(start) + local snext=start.next if snext then - local startchar=getchar(start) + local startchar=start.char local subtables=currentlookup.subtables local lookupname=subtables[1] local kerns=lookuphash[lookupname] @@ -10946,26 +11222,26 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look local lookuptype=lookuptypes[lookupname] local prev,done=start,false local factor=tfmdata.parameters.factor - while snext and getid(snext)==glyph_code and getfont(snext)==currentfont and getsubtype(snext)<256 do - local nextchar=getchar(snext) + while snext and snext.id==glyph_code and snext.font==currentfont and snext.subtype<256 do + local nextchar=snext.char local krn=kerns[nextchar] if not krn and marks[nextchar] then prev=snext - snext=getnext(snext) + snext=snext.next else if not krn then elseif type(krn)=="table" then if lookuptype=="pair" then local a,b=krn[2],krn[3] if a and #a>0 then - local startchar=getchar(start) + local startchar=start.char local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b>0 then - local startchar=getchar(start) + local startchar=start.char local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) @@ -10977,7 +11253,7 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look if a and a~=0 then local k=setkern(snext,factor,rlmode,a) if trace_kerns then - logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar)) + logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar)) end end if b and b~=0 then @@ -10988,7 +11264,7 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look elseif krn~=0 then local k=setkern(snext,factor,rlmode,krn) if trace_kerns then - logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar)) + logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar)) end done=true end @@ -11009,10 +11285,6 @@ local function show_skip(kind,chainname,char,ck,class) logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(kind,chainname),gref(char),class,ck[1],ck[2]) end end -local quit_on_no_replacement=true -directives.register("otf.chain.quitonnoreplacement",function(value) - quit_on_no_replacement=value -end) local function normal_handle_contextchain(head,start,kind,chainname,contexts,sequence,lookuphash) local flags=sequence.flags local done=false @@ -11030,7 +11302,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq local seq=ck[3] local s=#seq if s==1 then - match=getid(current)==glyph_code and getfont(current)==currentfont and getsubtype(current)<256 and seq[1][getchar(current)] + match=current.id==glyph_code and current.font==currentfont and current.subtype<256 and seq[1][current.char] else local f,l=ck[4],ck[5] if f==1 and f==l then @@ -11038,13 +11310,13 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if f==l then else local n=f+1 - last=getnext(last) + last=last.next while n<=l do if last then - local id=getid(last) + local id=last.id if id==glyph_code then - if getfont(last)==currentfont and getsubtype(last)<256 then - local char=getchar(last) + if last.font==currentfont and last.subtype<256 then + local char=last.char local ccd=descriptions[char] if ccd then local class=ccd.class @@ -11053,10 +11325,10 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if trace_skips then show_skip(kind,chainname,char,ck,class) end - last=getnext(last) + last=last.next elseif seq[n][char] then if n1 then - local prev=getprev(start) + local prev=start.prev if prev then local n=f-1 while n>=1 do if prev then - local id=getid(prev) + local id=prev.id if id==glyph_code then - if getfont(prev)==currentfont and getsubtype(prev)<256 then - local char=getchar(prev) + if prev.font==currentfont and prev.subtype<256 then + local char=prev.char local ccd=descriptions[char] if ccd then local class=ccd.class @@ -11123,7 +11395,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq match=false break end - prev=getprev(prev) + prev=prev.prev elseif seq[n][32] then n=n -1 else @@ -11143,15 +11415,15 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end end if match and s>l then - local current=last and getnext(last) + local current=last and last.next if current then local n=l+1 while n<=s do if current then - local id=getid(current) + local id=current.id if id==glyph_code then - if getfont(current)==currentfont and getsubtype(current)<256 then - local char=getchar(current) + if current.font==currentfont and current.subtype<256 then + local char=current.char local ccd=descriptions[char] if ccd then local class=ccd.class @@ -11181,7 +11453,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq match=false break end - current=getnext(current) + current=current.next elseif seq[n][32] then n=n+1 else @@ -11204,7 +11476,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if match then if trace_contexts then local rule,lookuptype,f,l=ck[1],ck[2],ck[4],ck[5] - local char=getchar(start) + local char=start.char if ck[9] then logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %a, %a => %a", cref(kind,chainname),rule,gref(char),f-1,l-f+1,s-l,lookuptype,ck[9],ck[10]) @@ -11238,12 +11510,12 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq repeat if skipped then while true do - local char=getchar(start) + local char=start.char local ccd=descriptions[char] if ccd then local class=ccd.class if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then - start=getnext(start) + start=start.next else break end @@ -11273,7 +11545,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end end if start then - start=getnext(start) + start=start.next else end until i>nofchainlookups @@ -11283,7 +11555,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if replacements then head,start,done=chainprocs.reversesub(head,start,last,kind,chainname,ck,lookuphash,replacements) else - done=quit_on_no_replacement + done=true if trace_contexts then logprocess("%s: skipping match",cref(kind,chainname)) end @@ -11352,14 +11624,20 @@ local autofeatures=fonts.analyzers.features local function initialize(sequence,script,language,enabled) local features=sequence.features if features then - for kind,scripts in next,features do - local valid=enabled[kind] - if valid then - local languages=scripts[script] or scripts[wildcard] - if languages and (languages[language] or languages[wildcard]) then - return { valid,autofeatures[kind] or false,sequence.chain or 0,kind,sequence } + local order=sequence.order + if order then + for i=1,#order do + local kind=order[i] + local valid=enabled[kind] + if valid then + local scripts=features[kind] + local languages=scripts[script] or scripts[wildcard] + if languages and (languages[language] or languages[wildcard]) then + return { valid,autofeatures[kind] or false,sequence.chain or 0,kind,sequence } + end end end + else end end return false @@ -11386,12 +11664,12 @@ function otf.dataset(tfmdata,font) } rs[language]=rl local sequences=tfmdata.resources.sequences -for s=1,#sequences do - local v=enabled and initialize(sequences[s],script,language,enabled) - if v then - rl[#rl+1]=v - end -end + for s=1,#sequences do + local v=enabled and initialize(sequences[s],script,language,enabled) + if v then + rl[#rl+1]=v + end + end end return rl end @@ -11400,7 +11678,6 @@ local function featuresprocessor(head,font,attr) if not lookuphash then return head,false end - head=tonut(head) if trace_steps then checkstep(head) end @@ -11433,10 +11710,10 @@ local function featuresprocessor(head,font,attr) local handler=handlers[typ] local start=find_node_tail(head) while start do - local id=getid(start) + local id=start.id if id==glyph_code then - if getfont(start)==font and getsubtype(start)<256 then - local a=getattr(start,0) + if start.font==font and start.subtype<256 then + local a=start[0] if a then a=a==attr else @@ -11447,7 +11724,7 @@ local function featuresprocessor(head,font,attr) local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[getchar(start)] + local lookupmatch=lookupcache[start.char] if lookupmatch then head,start,success=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) if success then @@ -11458,15 +11735,15 @@ local function featuresprocessor(head,font,attr) report_missing_cache(typ,lookupname) end end - if start then start=getprev(start) end + if start then start=start.prev end else - start=getprev(start) + start=start.prev end else - start=getprev(start) + start=start.prev end else - start=getprev(start) + start=start.prev end end else @@ -11484,16 +11761,16 @@ local function featuresprocessor(head,font,attr) local head=start local done=false while start do - local id=getid(start) - if id==glyph_code and getfont(start)==font and getsubtype(start)<256 then - local a=getattr(start,0) + local id=start.id + if id==glyph_code and start.font==font and start.subtype<256 then + local a=start[0] if a then - a=(a==attr) and (not attribute or getattr(start,a_state)==attribute) + a=(a==attr) and (not attribute or start[a_state]==attribute) else - a=not attribute or getattr(start,a_state)==attribute + a=not attribute or start[a_state]==attribute end if a then - local lookupmatch=lookupcache[getchar(start)] + local lookupmatch=lookupcache[start.char] if lookupmatch then local ok head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) @@ -11501,12 +11778,12 @@ local function featuresprocessor(head,font,attr) done=true end end - if start then start=getnext(start) end + if start then start=start.next end else - start=getnext(start) + start=start.next end else - start=getnext(start) + start=start.next end end if done then @@ -11515,18 +11792,18 @@ local function featuresprocessor(head,font,attr) end end local function kerndisc(disc) - local prev=getprev(disc) - local next=getnext(disc) + local prev=disc.prev + local next=disc.next if prev and next then - setfield(prev,"next",next) - local a=getattr(prev,0) + prev.next=next + local a=prev[0] if a then - a=(a==attr) and (not attribute or getattr(prev,a_state)==attribute) + a=(a==attr) and (not attribute or prev[a_state]==attribute) else - a=not attribute or getattr(prev,a_state)==attribute + a=not attribute or prev[a_state]==attribute end if a then - local lookupmatch=lookupcache[getchar(prev)] + local lookupmatch=lookupcache[prev.char] if lookupmatch then local h,d,ok=handler(head,prev,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) if ok then @@ -11535,22 +11812,22 @@ local function featuresprocessor(head,font,attr) end end end - setfield(prev,"next",disc) + prev.next=disc end return next end while start do - local id=getid(start) + local id=start.id if id==glyph_code then - if getfont(start)==font and getsubtype(start)<256 then - local a=getattr(start,0) + if start.font==font and start.subtype<256 then + local a=start[0] if a then - a=(a==attr) and (not attribute or getattr(start,a_state)==attribute) + a=(a==attr) and (not attribute or start[a_state]==attribute) else - a=not attribute or getattr(start,a_state)==attribute + a=not attribute or start[a_state]==attribute end if a then - local lookupmatch=lookupcache[getchar(start)] + local lookupmatch=lookupcache[start.char] if lookupmatch then local ok head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) @@ -11558,38 +11835,38 @@ local function featuresprocessor(head,font,attr) success=true end end - if start then start=getnext(start) end + if start then start=start.next end else - start=getnext(start) + start=start.next end else - start=getnext(start) + start=start.next end elseif id==disc_code then - if getsubtype(start)==discretionary_code then - local pre=getfield(start,"pre") + if start.subtype==discretionary_code then + local pre=start.pre if pre then local new=subrun(pre) - if new then setfield(start,"pre",new) end + if new then start.pre=new end end - local post=getfield(start,"post") + local post=start.post if post then local new=subrun(post) - if new then setfield(start,"post",new) end + if new then start.post=new end end - local replace=getfield(start,"replace") + local replace=start.replace if replace then local new=subrun(replace) - if new then setfield(start,"replace",new) end + if new then start.replace=new end end elseif typ=="gpos_single" or typ=="gpos_pair" then kerndisc(start) end - start=getnext(start) + start=start.next elseif id==whatsit_code then - local subtype=getsubtype(start) + local subtype=start.subtype if subtype==dir_code then - local dir=getfield(start,"dir") + local dir=start.dir if dir=="+TRT" or dir=="+TLT" then topstack=topstack+1 dirstack[topstack]=dir @@ -11608,7 +11885,7 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir) end elseif subtype==localpar_code then - local dir=getfield(start,"dir") + local dir=start.dir if dir=="TRT" then rlparmode=-1 elseif dir=="TLT" then @@ -11621,11 +11898,11 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode) end end - start=getnext(start) + start=start.next elseif id==math_code then - start=getnext(end_of_math(start)) + start=end_of_math(start).next else - start=getnext(start) + start=start.next end end end @@ -11634,20 +11911,20 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then local head=start local done=false while start do - local id=getid(start) - if id==glyph_code and getfont(start)==font and getsubtype(start)<256 then - local a=getattr(start,0) + local id=start.id + if id==glyph_code and start.id==font and start.subtype<256 then + local a=start[0] if a then - a=(a==attr) and (not attribute or getattr(start,a_state)==attribute) + a=(a==attr) and (not attribute or start[a_state]==attribute) else - a=not attribute or getattr(start,a_state)==attribute + a=not attribute or start[a_state]==attribute end if a then for i=1,ns do local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[getchar(start)] + local lookupmatch=lookupcache[start.char] if lookupmatch then local ok head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) @@ -11662,12 +11939,12 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then report_missing_cache(typ,lookupname) end end - if start then start=getnext(start) end + if start then start=start.next end else - start=getnext(start) + start=start.next end else - start=getnext(start) + start=start.next end end if done then @@ -11676,22 +11953,22 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then end end local function kerndisc(disc) - local prev=getprev(disc) - local next=getnext(disc) + local prev=disc.prev + local next=disc.next if prev and next then - setfield(prev,"next",next) - local a=getattr(prev,0) + prev.next=next + local a=prev[0] if a then - a=(a==attr) and (not attribute or getattr(prev,a_state)==attribute) + a=(a==attr) and (not attribute or prev[a_state]==attribute) else - a=not attribute or getattr(prev,a_state)==attribute + a=not attribute or prev[a_state]==attribute end if a then for i=1,ns do local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[getchar(prev)] + local lookupmatch=lookupcache[prev.char] if lookupmatch then local h,d,ok=handler(head,prev,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) if ok then @@ -11704,26 +11981,26 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then end end end - setfield(prev,"next",disc) + prev.next=disc end return next end while start do - local id=getid(start) + local id=start.id if id==glyph_code then - if getfont(start)==font and getsubtype(start)<256 then - local a=getattr(start,0) + if start.font==font and start.subtype<256 then + local a=start[0] if a then - a=(a==attr) and (not attribute or getattr(start,a_state)==attribute) + a=(a==attr) and (not attribute or start[a_state]==attribute) else - a=not attribute or getattr(start,a_state)==attribute + a=not attribute or start[a_state]==attribute end if a then for i=1,ns do local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[getchar(start)] + local lookupmatch=lookupcache[start.char] if lookupmatch then local ok head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) @@ -11738,38 +12015,38 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then report_missing_cache(typ,lookupname) end end - if start then start=getnext(start) end + if start then start=start.next end else - start=getnext(start) + start=start.next end else - start=getnext(start) + start=start.next end elseif id==disc_code then - if getsubtype(start)==discretionary_code then - local pre=getfield(start,"pre") + if start.subtype==discretionary_code then + local pre=start.pre if pre then local new=subrun(pre) - if new then setfield(start,"pre",new) end + if new then start.pre=new end end - local post=getfield(start,"post") + local post=start.post if post then local new=subrun(post) - if new then setfield(start,"post",new) end + if new then start.post=new end end - local replace=getfield(start,"replace") + local replace=start.replace if replace then local new=subrun(replace) - if new then setfield(start,"replace",new) end + if new then start.replace=new end end elseif typ=="gpos_single" or typ=="gpos_pair" then kerndisc(start) end - start=getnext(start) + start=start.next elseif id==whatsit_code then - local subtype=getsubtype(start) + local subtype=start.subtype if subtype==dir_code then - local dir=getfield(start,"dir") + local dir=start.dir if dir=="+TRT" or dir=="+TLT" then topstack=topstack+1 dirstack[topstack]=dir @@ -11788,7 +12065,7 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir) end elseif subtype==localpar_code then - local dir=getfield(start,"dir") + local dir=start.dir if dir=="TRT" then rlparmode=-1 elseif dir=="TLT" then @@ -11801,11 +12078,11 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode) end end - start=getnext(start) + start=start.next elseif id==math_code then - start=getnext(end_of_math(start)) + start=end_of_math(start).next else - start=getnext(start) + start=start.next end end end @@ -11817,7 +12094,6 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then registerstep(head) end end - head=tonode(head) return head,done end local function generic(lookupdata,lookupname,unicode,lookuphash) @@ -12420,6 +12696,14 @@ local function packdata(data) features[script]=pack_normal(feature) end end + local order=sequence.order + if order then + sequence.order=pack_indexed(order) + end + local markclass=sequence.markclass + if markclass then + sequence.markclass=pack_boolean(markclass) + end end end local lookups=resources.lookups @@ -12832,6 +13116,20 @@ local function unpackdata(data) end end end + local order=feature.order + if order then + local tv=tables[order] + if tv then + feature.order=tv + end + end + local markclass=feature.markclass + if markclass then + local tv=tables[markclass] + if tv then + feature.markclass=tv + end + end end end local lookups=resources.lookups diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fonts-inj.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fonts-inj.lua new file mode 100644 index 00000000000..ae48150a6ca --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fonts-inj.lua @@ -0,0 +1,526 @@ +if not modules then modules = { } end modules ['node-inj'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +-- This is very experimental (this will change when we have luatex > .50 and +-- a few pending thingies are available. Also, Idris needs to make a few more +-- test fonts. Btw, future versions of luatex will have extended glyph properties +-- that can be of help. Some optimizations can go away when we have faster machines. + +-- todo: make a special one for context + +local next = next +local utfchar = utf.char + +local trace_injections = false trackers.register("nodes.injections", function(v) trace_injections = v end) + +local report_injections = logs.reporter("nodes","injections") + +local attributes, nodes, node = attributes, nodes, node + +fonts = fonts +local fontdata = fonts.hashes.identifiers + +nodes.injections = nodes.injections or { } +local injections = nodes.injections + +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph +local kern_code = nodecodes.kern +local nodepool = nodes.pool +local newkern = nodepool.kern + +local traverse_id = node.traverse_id +local insert_node_before = node.insert_before +local insert_node_after = node.insert_after + +local a_kernpair = attributes.private('kernpair') +local a_ligacomp = attributes.private('ligacomp') +local a_markbase = attributes.private('markbase') +local a_markmark = attributes.private('markmark') +local a_markdone = attributes.private('markdone') +local a_cursbase = attributes.private('cursbase') +local a_curscurs = attributes.private('curscurs') +local a_cursdone = attributes.private('cursdone') + +-- This injector has been tested by Idris Samawi Hamid (several arabic fonts as well as +-- the rather demanding Husayni font), Khaled Hosny (latin and arabic) and Kaj Eigner +-- (arabic, hebrew and thai) and myself (whatever font I come across). I'm pretty sure +-- that this code is not 100% okay but examples are needed to figure things out. + +function injections.installnewkern(nk) + newkern = nk or newkern +end + +local cursives = { } +local marks = { } +local kerns = { } + +-- Currently we do gpos/kern in a bit inofficial way but when we have the extra fields in +-- glyphnodes to manipulate ht/dp/wd explicitly I will provide an alternative; also, we +-- can share tables. + +-- For the moment we pass the r2l key ... volt/arabtype tests .. idris: this needs +-- checking with husayni (volt and fontforge). + +function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext) + local dx, dy = factor*(exit[1]-entry[1]), factor*(exit[2]-entry[2]) + local ws, wn = tfmstart.width, tfmnext.width + local bound = #cursives + 1 + start[a_cursbase] = bound + nxt[a_curscurs] = bound + cursives[bound] = { rlmode, dx, dy, ws, wn } + return dx, dy, bound +end + +function injections.setpair(current,factor,rlmode,r2lflag,spec,tfmchr) + local x, y, w, h = factor*spec[1], factor*spec[2], factor*spec[3], factor*spec[4] + -- dy = y - h + if x ~= 0 or w ~= 0 or y ~= 0 or h ~= 0 then + local bound = current[a_kernpair] + if bound then + local kb = kerns[bound] + -- inefficient but singles have less, but weird anyway, needs checking + kb[2], kb[3], kb[4], kb[5] = (kb[2] or 0) + x, (kb[3] or 0) + y, (kb[4] or 0)+ w, (kb[5] or 0) + h + else + bound = #kerns + 1 + current[a_kernpair] = bound + kerns[bound] = { rlmode, x, y, w, h, r2lflag, tfmchr.width } + end + return x, y, w, h, bound + end + return x, y, w, h -- no bound +end + +function injections.setkern(current,factor,rlmode,x,tfmchr) + local dx = factor*x + if dx ~= 0 then + local bound = #kerns + 1 + current[a_kernpair] = bound + kerns[bound] = { rlmode, dx } + return dx, bound + else + return 0, 0 + end +end + +function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark) -- ba=baseanchor, ma=markanchor + local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2]) -- the index argument is no longer used but when this + local bound = base[a_markbase] -- fails again we should pass it + local index = 1 + if bound then + local mb = marks[bound] + if mb then + -- if not index then index = #mb + 1 end + index = #mb + 1 + mb[index] = { dx, dy, rlmode } + start[a_markmark] = bound + start[a_markdone] = index + return dx, dy, bound + else + report_injections("possible problem, %U is base mark without data (id %a)",base.char,bound) + end + end +-- index = index or 1 + index = index or 1 + bound = #marks + 1 + base[a_markbase] = bound + start[a_markmark] = bound + start[a_markdone] = index + marks[bound] = { [index] = { dx, dy, rlmode, baseismark } } + return dx, dy, bound +end + +local function dir(n) + return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset" +end + +local function trace(head) + report_injections("begin run") + for n in traverse_id(glyph_code,head) do + if n.subtype < 256 then + local kp = n[a_kernpair] + local mb = n[a_markbase] + local mm = n[a_markmark] + local md = n[a_markdone] + local cb = n[a_cursbase] + local cc = n[a_curscurs] + local char = n.char + report_injections("font %s, char %U, glyph %c",n.font,char,char) + if kp then + local k = kerns[kp] + if k[3] then + report_injections(" pairkern: dir %a, x %p, y %p, w %p, h %p",dir(k[1]),k[2],k[3],k[4],k[5]) + else + report_injections(" kern: dir %a, dx %p",dir(k[1]),k[2]) + end + end + if mb then + report_injections(" markbase: bound %a",mb) + end + if mm then + local m = marks[mm] + if mb then + local m = m[mb] + if m then + report_injections(" markmark: bound %a, index %a, dx %p, dy %p",mm,md,m[1],m[2]) + else + report_injections(" markmark: bound %a, missing index",mm) + end + else + m = m[1] + report_injections(" markmark: bound %a, dx %p, dy %p",mm,m and m[1],m and m[2]) + end + end + if cb then + report_injections(" cursbase: bound %a",cb) + end + if cc then + local c = cursives[cc] + report_injections(" curscurs: bound %a, dir %a, dx %p, dy %p",cc,dir(c[1]),c[2],c[3]) + end + end + end + report_injections("end run") +end + +-- todo: reuse tables (i.e. no collection), but will be extra fields anyway +-- todo: check for attribute + +-- We can have a fast test on a font being processed, so we can check faster for marks etc +-- but I'll make a context variant anyway. + +local function show_result(head) + local current = head + local skipping = false + while current do + local id = current.id + if id == glyph_code then + report_injections("char: %C, width %p, xoffset %p, yoffset %p",current.char,current.width,current.xoffset,current.yoffset) + skipping = false + elseif id == kern_code then + report_injections("kern: %p",current.kern) + skipping = false + elseif not skipping then + report_injections() + skipping = true + end + current = current.next + end +end + +function injections.handler(head,where,keep) + local has_marks, has_cursives, has_kerns = next(marks), next(cursives), next(kerns) + if has_marks or has_cursives then + if trace_injections then + trace(head) + end + -- in the future variant we will not copy items but refs to tables + local done, ky, rl, valid, cx, wx, mk, nofvalid = false, { }, { }, { }, { }, { }, { }, 0 + if has_kerns then -- move outside loop + local nf, tm = nil, nil + for n in traverse_id(glyph_code,head) do -- only needed for relevant fonts + if n.subtype < 256 then + nofvalid = nofvalid + 1 + valid[nofvalid] = n + if n.font ~= nf then + nf = n.font + tm = fontdata[nf].resources.marks + end + if tm then + mk[n] = tm[n.char] + end + local k = n[a_kernpair] + if k then + local kk = kerns[k] + if kk then + local x, y, w, h = kk[2] or 0, kk[3] or 0, kk[4] or 0, kk[5] or 0 + local dy = y - h + if dy ~= 0 then + ky[n] = dy + end + if w ~= 0 or x ~= 0 then + wx[n] = kk + end + rl[n] = kk[1] -- could move in test + end + end + end + end + else + local nf, tm = nil, nil + for n in traverse_id(glyph_code,head) do + if n.subtype < 256 then + nofvalid = nofvalid + 1 + valid[nofvalid] = n + if n.font ~= nf then + nf = n.font + tm = fontdata[nf].resources.marks + end + if tm then + mk[n] = tm[n.char] + end + end + end + end + if nofvalid > 0 then + -- we can assume done == true because we have cursives and marks + local cx = { } + if has_kerns and next(ky) then + for n, k in next, ky do + n.yoffset = k + end + end + -- todo: reuse t and use maxt + if has_cursives then + local p_cursbase, p = nil, nil + -- since we need valid[n+1] we can also use a "while true do" + local t, d, maxt = { }, { }, 0 + for i=1,nofvalid do -- valid == glyphs + local n = valid[i] + if not mk[n] then + local n_cursbase = n[a_cursbase] + if p_cursbase then + local n_curscurs = n[a_curscurs] + if p_cursbase == n_curscurs then + local c = cursives[n_curscurs] + if c then + local rlmode, dx, dy, ws, wn = c[1], c[2], c[3], c[4], c[5] + if rlmode >= 0 then + dx = dx - ws + else + dx = dx + wn + end + if dx ~= 0 then + cx[n] = dx + rl[n] = rlmode + end + -- if rlmode and rlmode < 0 then + dy = -dy + -- end + maxt = maxt + 1 + t[maxt] = p + d[maxt] = dy + else + maxt = 0 + end + end + elseif maxt > 0 then + local ny = n.yoffset + for i=maxt,1,-1 do + ny = ny + d[i] + local ti = t[i] + ti.yoffset = ti.yoffset + ny + end + maxt = 0 + end + if not n_cursbase and maxt > 0 then + local ny = n.yoffset + for i=maxt,1,-1 do + ny = ny + d[i] + local ti = t[i] + ti.yoffset = ny + end + maxt = 0 + end + p_cursbase, p = n_cursbase, n + end + end + if maxt > 0 then + local ny = n.yoffset + for i=maxt,1,-1 do + ny = ny + d[i] + local ti = t[i] + ti.yoffset = ny + end + maxt = 0 + end + if not keep then + cursives = { } + end + end + if has_marks then + for i=1,nofvalid do + local p = valid[i] + local p_markbase = p[a_markbase] + if p_markbase then + local mrks = marks[p_markbase] + local nofmarks = #mrks + for n in traverse_id(glyph_code,p.next) do + local n_markmark = n[a_markmark] + if p_markbase == n_markmark then + local index = n[a_markdone] or 1 + local d = mrks[index] + if d then + local rlmode = d[3] + -- + local k = wx[p] + if k then + local x = k[2] + local w = k[4] + if w then + if rlmode and rlmode >= 0 then + -- kern(x) glyph(p) kern(w-x) mark(n) + n.xoffset = p.xoffset - p.width + d[1] - (w-x) + else + -- kern(w-x) glyph(p) kern(x) mark(n) + n.xoffset = p.xoffset - d[1] - x + end + else + if rlmode and rlmode >= 0 then + -- okay for husayni + n.xoffset = p.xoffset - p.width + d[1] + else + -- needs checking: is x ok here? + n.xoffset = p.xoffset - d[1] - x + end + end + else + if rlmode and rlmode >= 0 then + n.xoffset = p.xoffset - p.width + d[1] + else + n.xoffset = p.xoffset - d[1] + end + local w = n.width + if w ~= 0 then + insert_node_before(head,n,newkern(-w/2)) + insert_node_after(head,n,newkern(-w/2)) + end + end + -- -- + if mk[p] then + n.yoffset = p.yoffset + d[2] + else + n.yoffset = n.yoffset + p.yoffset + d[2] + end + -- + if nofmarks == 1 then + break + else + nofmarks = nofmarks - 1 + end + end + else + -- KE: there can be sequences in ligatures + end + end + end + end + if not keep then + marks = { } + end + end + -- todo : combine + if next(wx) then + for n, k in next, wx do + -- only w can be nil (kernclasses), can be sped up when w == nil + local x = k[2] + local w = k[4] + if w then + local rl = k[1] -- r2l = k[6] + local wx = w - x + if rl < 0 then -- KE: don't use r2l here + if wx ~= 0 then + insert_node_before(head,n,newkern(wx)) -- type 0/2 + end + if x ~= 0 then + insert_node_after (head,n,newkern(x)) -- type 0/2 + end + else + if x ~= 0 then + insert_node_before(head,n,newkern(x)) -- type 0/2 + end + if wx ~= 0 then + insert_node_after (head,n,newkern(wx)) -- type 0/2 + end + end + elseif x ~= 0 then + -- this needs checking for rl < 0 but it is unlikely that a r2l script + -- uses kernclasses between glyphs so we're probably safe (KE has a + -- problematic font where marks interfere with rl < 0 in the previous + -- case) + insert_node_before(head,n,newkern(x)) -- a real font kern, type 0 + end + end + end + if next(cx) then + for n, k in next, cx do + if k ~= 0 then + local rln = rl[n] + if rln and rln < 0 then + insert_node_before(head,n,newkern(-k)) -- type 0/2 + else + insert_node_before(head,n,newkern(k)) -- type 0/2 + end + end + end + end + if not keep then + kerns = { } + end + -- if trace_injections then + -- show_result(head) + -- end + return head, true + elseif not keep then + kerns, cursives, marks = { }, { }, { } + end + elseif has_kerns then + if trace_injections then + trace(head) + end + for n in traverse_id(glyph_code,head) do + if n.subtype < 256 then + local k = n[a_kernpair] + if k then + local kk = kerns[k] + if kk then + local rl, x, y, w = kk[1], kk[2] or 0, kk[3], kk[4] + if y and y ~= 0 then + n.yoffset = y -- todo: h ? + end + if w then + -- copied from above + -- local r2l = kk[6] + local wx = w - x + if rl < 0 then -- KE: don't use r2l here + if wx ~= 0 then + insert_node_before(head,n,newkern(wx)) + end + if x ~= 0 then + insert_node_after (head,n,newkern(x)) + end + else + if x ~= 0 then + insert_node_before(head,n,newkern(x)) + end + if wx ~= 0 then + insert_node_after(head,n,newkern(wx)) + end + end + else + -- simple (e.g. kernclass kerns) + if x ~= 0 then + insert_node_before(head,n,newkern(x)) + end + end + end + end + end + end + if not keep then + kerns = { } + end + -- if trace_injections then + -- show_result(head) + -- end + return head, true + else + -- no tracing needed + end + return head, false +end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fonts-otn.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fonts-otn.lua new file mode 100644 index 00000000000..c57be5f0278 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fonts-otn.lua @@ -0,0 +1,2848 @@ +if not modules then modules = { } end modules ['font-otn'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +-- preprocessors = { "nodes" } + +-- this is still somewhat preliminary and it will get better in due time; +-- much functionality could only be implemented thanks to the husayni font +-- of Idris Samawi Hamid to who we dedicate this module. + +-- in retrospect it always looks easy but believe it or not, it took a lot +-- of work to get proper open type support done: buggy fonts, fuzzy specs, +-- special made testfonts, many skype sessions between taco, idris and me, +-- torture tests etc etc ... unfortunately the code does not show how much +-- time it took ... + +-- todo: +-- +-- kerning is probably not yet ok for latin around dics nodes (interesting challenge) +-- extension infrastructure (for usage out of context) +-- sorting features according to vendors/renderers +-- alternative loop quitters +-- check cursive and r2l +-- find out where ignore-mark-classes went +-- default features (per language, script) +-- handle positions (we need example fonts) +-- handle gpos_single (we might want an extra width field in glyph nodes because adding kerns might interfere) +-- mark (to mark) code is still not what it should be (too messy but we need some more extreem husayni tests) +-- remove some optimizations (when I have a faster machine) +-- +-- maybe redo the lot some way (more context specific) + +--[[ldx-- +

This module is a bit more split up that I'd like but since we also want to test +with plain it has to be so. This module is part of +and discussion about improvements and functionality mostly happens on the + mailing list.

+ +

The specification of OpenType is kind of vague. Apart from a lack of a proper +free specifications there's also the problem that Microsoft and Adobe +may have their own interpretation of how and in what order to apply features. +In general the Microsoft website has more detailed specifications and is a +better reference. There is also some information in the FontForge help files.

+ +

Because there is so much possible, fonts might contain bugs and/or be made to +work with certain rederers. These may evolve over time which may have the side +effect that suddenly fonts behave differently.

+ +

After a lot of experiments (mostly by Taco, me and Idris) we're now at yet another +implementation. Of course all errors are mine and of course the code can be +improved. There are quite some optimizations going on here and processing speed +is currently acceptable. Not all functions are implemented yet, often because I +lack the fonts for testing. Many scripts are not yet supported either, but I will +look into them as soon as users ask for it.

+ +

Because there are different interpretations possible, I will extend the code +with more (configureable) variants. I can also add hooks for users so that they can +write their own extensions.

+ +

Glyphs are indexed not by unicode but in their own way. This is because there is no +relationship with unicode at all, apart from the fact that a font might cover certain +ranges of characters. One character can have multiple shapes. However, at the + end we use unicode so and all extra glyphs are mapped into a private +space. This is needed because we need to access them and has to include +then in the output eventually.

+ +

The raw table as it coms from gets reorganized in to fit out needs. +In that table is packed (similar tables are shared) and cached on disk +so that successive runs can use the optimized table (after loading the table is +unpacked). The flattening code used later is a prelude to an even more compact table +format (and as such it keeps evolving).

+ +

This module is sparsely documented because it is a moving target. The table format +of the reader changes and we experiment a lot with different methods for supporting +features.

+ +

As with the code, we may decide to store more information in the + table.

+ +

Incrementing the version number will force a re-cache. We jump the number by one +when there's a fix in the library or code that +results in different tables.

+--ldx]]-- + +-- action handler chainproc chainmore comment +-- +-- gsub_single ok ok ok +-- gsub_multiple ok ok not implemented yet +-- gsub_alternate ok ok not implemented yet +-- gsub_ligature ok ok ok +-- gsub_context ok -- +-- gsub_contextchain ok -- +-- gsub_reversecontextchain ok -- +-- chainsub -- ok +-- reversesub -- ok +-- gpos_mark2base ok ok +-- gpos_mark2ligature ok ok +-- gpos_mark2mark ok ok +-- gpos_cursive ok untested +-- gpos_single ok ok +-- gpos_pair ok ok +-- gpos_context ok -- +-- gpos_contextchain ok -- +-- +-- todo: contextpos and contextsub and class stuff +-- +-- actions: +-- +-- handler : actions triggered by lookup +-- chainproc : actions triggered by contextual lookup +-- chainmore : multiple substitutions triggered by contextual lookup (e.g. fij -> f + ij) +-- +-- remark: the 'not implemented yet' variants will be done when we have fonts that use them +-- remark: we need to check what to do with discretionaries + +-- We used to have independent hashes for lookups but as the tags are unique +-- we now use only one hash. If needed we can have multiple again but in that +-- case I will probably prefix (i.e. rename) the lookups in the cached font file. + +-- Todo: make plugin feature that operates on char/glyphnode arrays + +local concat, insert, remove = table.concat, table.insert, table.remove +local gmatch, gsub, find, match, lower, strip = string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip +local type, next, tonumber, tostring = type, next, tonumber, tostring +local lpegmatch = lpeg.match +local random = math.random +local formatters = string.formatters + +local logs, trackers, nodes, attributes = logs, trackers, nodes, attributes + +local registertracker = trackers.register + +local fonts = fonts +local otf = fonts.handlers.otf + +local trace_lookups = false registertracker("otf.lookups", function(v) trace_lookups = v end) +local trace_singles = false registertracker("otf.singles", function(v) trace_singles = v end) +local trace_multiples = false registertracker("otf.multiples", function(v) trace_multiples = v end) +local trace_alternatives = false registertracker("otf.alternatives", function(v) trace_alternatives = v end) +local trace_ligatures = false registertracker("otf.ligatures", function(v) trace_ligatures = v end) +local trace_contexts = false registertracker("otf.contexts", function(v) trace_contexts = v end) +local trace_marks = false registertracker("otf.marks", function(v) trace_marks = v end) +local trace_kerns = false registertracker("otf.kerns", function(v) trace_kerns = v end) +local trace_cursive = false registertracker("otf.cursive", function(v) trace_cursive = v end) +local trace_preparing = false registertracker("otf.preparing", function(v) trace_preparing = v end) +local trace_bugs = false registertracker("otf.bugs", function(v) trace_bugs = v end) +local trace_details = false registertracker("otf.details", function(v) trace_details = v end) +local trace_applied = false registertracker("otf.applied", function(v) trace_applied = v end) +local trace_steps = false registertracker("otf.steps", function(v) trace_steps = v end) +local trace_skips = false registertracker("otf.skips", function(v) trace_skips = v end) +local trace_directions = false registertracker("otf.directions", function(v) trace_directions = v end) + +local report_direct = logs.reporter("fonts","otf direct") +local report_subchain = logs.reporter("fonts","otf subchain") +local report_chain = logs.reporter("fonts","otf chain") +local report_process = logs.reporter("fonts","otf process") +local report_prepare = logs.reporter("fonts","otf prepare") +local report_warning = logs.reporter("fonts","otf warning") + +registertracker("otf.verbose_chain", function(v) otf.setcontextchain(v and "verbose") end) +registertracker("otf.normal_chain", function(v) otf.setcontextchain(v and "normal") end) + +registertracker("otf.replacements", "otf.singles,otf.multiples,otf.alternatives,otf.ligatures") +registertracker("otf.positions","otf.marks,otf.kerns,otf.cursive") +registertracker("otf.actions","otf.replacements,otf.positions") +registertracker("otf.injections","nodes.injections") + +registertracker("*otf.sample","otf.steps,otf.actions,otf.analyzing") + +local insert_node_after = node.insert_after +local delete_node = nodes.delete +local copy_node = node.copy +local find_node_tail = node.tail or node.slide +local flush_node_list = node.flush_list +local end_of_math = node.end_of_math + +local setmetatableindex = table.setmetatableindex + +local zwnj = 0x200C +local zwj = 0x200D +local wildcard = "*" +local default = "dflt" + +local nodecodes = nodes.nodecodes +local whatcodes = nodes.whatcodes +local glyphcodes = nodes.glyphcodes +local disccodes = nodes.disccodes + +local glyph_code = nodecodes.glyph +local glue_code = nodecodes.glue +local disc_code = nodecodes.disc +local whatsit_code = nodecodes.whatsit +local math_code = nodecodes.math + +local dir_code = whatcodes.dir +local localpar_code = whatcodes.localpar + +local discretionary_code = disccodes.discretionary + +local ligature_code = glyphcodes.ligature + +local privateattribute = attributes.private + +-- Something is messed up: we have two mark / ligature indices, one at the injection +-- end and one here ... this is bases in KE's patches but there is something fishy +-- there as I'm pretty sure that for husayni we need some connection (as it's much +-- more complex than an average font) but I need proper examples of all cases, not +-- of only some. + +local a_state = privateattribute('state') +local a_markbase = privateattribute('markbase') +local a_markmark = privateattribute('markmark') +local a_markdone = privateattribute('markdone') -- assigned at the injection end +local a_cursbase = privateattribute('cursbase') +local a_curscurs = privateattribute('curscurs') +local a_cursdone = privateattribute('cursdone') +local a_kernpair = privateattribute('kernpair') +local a_ligacomp = privateattribute('ligacomp') -- assigned here (ideally it should be combined) + +local injections = nodes.injections +local setmark = injections.setmark +local setcursive = injections.setcursive +local setkern = injections.setkern +local setpair = injections.setpair + +local markonce = true +local cursonce = true +local kernonce = true + +local fonthashes = fonts.hashes +local fontdata = fonthashes.identifiers + +local otffeatures = fonts.constructors.newfeatures("otf") +local registerotffeature = otffeatures.register + +local onetimemessage = fonts.loggers.onetimemessage or function() end + +otf.defaultnodealternate = "none" -- first last + +-- we share some vars here, after all, we have no nested lookups and less code + +local tfmdata = false +local characters = false +local descriptions = false +local resources = false +local marks = false +local currentfont = false +local lookuptable = false +local anchorlookups = false +local lookuptypes = false +local handlers = { } +local rlmode = 0 +local featurevalue = false + +-- head is always a whatsit so we can safely assume that head is not changed + +-- we use this for special testing and documentation + +local checkstep = (nodes and nodes.tracers and nodes.tracers.steppers.check) or function() end +local registerstep = (nodes and nodes.tracers and nodes.tracers.steppers.register) or function() end +local registermessage = (nodes and nodes.tracers and nodes.tracers.steppers.message) or function() end + +local function logprocess(...) + if trace_steps then + registermessage(...) + end + report_direct(...) +end + +local function logwarning(...) + report_direct(...) +end + +local f_unicode = formatters["%U"] +local f_uniname = formatters["%U (%s)"] +local f_unilist = formatters["% t (% t)"] + +local function gref(n) -- currently the same as in font-otb + if type(n) == "number" then + local description = descriptions[n] + local name = description and description.name + if name then + return f_uniname(n,name) + else + return f_unicode(n) + end + elseif n then + local num, nam = { }, { } + for i=1,#n do + local ni = n[i] + if tonumber(ni) then -- later we will start at 2 + local di = descriptions[ni] + num[i] = f_unicode(ni) + nam[i] = di and di.name or "-" + end + end + return f_unilist(num,nam) + else + return "" + end +end + +local function cref(kind,chainname,chainlookupname,lookupname,index) -- not in the mood to alias f_ + if index then + return formatters["feature %a, chain %a, sub %a, lookup %a, index %a"](kind,chainname,chainlookupname,lookupname,index) + elseif lookupname then + return formatters["feature %a, chain %a, sub %a, lookup %a"](kind,chainname,chainlookupname,lookupname) + elseif chainlookupname then + return formatters["feature %a, chain %a, sub %a"](kind,chainname,chainlookupname) + elseif chainname then + return formatters["feature %a, chain %a"](kind,chainname) + else + return formatters["feature %a"](kind) + end +end + +local function pref(kind,lookupname) + return formatters["feature %a, lookup %a"](kind,lookupname) +end + +-- We can assume that languages that use marks are not hyphenated. We can also assume +-- that at most one discretionary is present. + +-- We do need components in funny kerning mode but maybe I can better reconstruct then +-- as we do have the font components info available; removing components makes the +-- previous code much simpler. Also, later on copying and freeing becomes easier. +-- However, for arabic we need to keep them around for the sake of mark placement +-- and indices. + +local function copy_glyph(g) -- next and prev are untouched ! + local components = g.components + if components then + g.components = nil + local n = copy_node(g) + g.components = components + return n + else + return copy_node(g) + end +end + +-- start is a mark and we need to keep that one + +local function markstoligature(kind,lookupname,head,start,stop,char) + if start == stop and start.char == char then + return head, start + else + local prev = start.prev + local next = stop.next + start.prev = nil + stop.next = nil + local base = copy_glyph(start) + if head == start then + head = base + end + base.char = char + base.subtype = ligature_code + base.components = start + if prev then + prev.next = base + end + if next then + next.prev = base + end + base.next = next + base.prev = prev + return head, base + end +end + +-- The next code is somewhat complicated by the fact that some fonts can have ligatures made +-- from ligatures that themselves have marks. This was identified by Kai in for instance +-- arabtype: KAF LAM SHADDA ALEF FATHA (0x0643 0x0644 0x0651 0x0627 0x064E). This becomes +-- KAF LAM-ALEF with a SHADDA on the first and a FATHA op de second component. In a next +-- iteration this becomes a KAF-LAM-ALEF with a SHADDA on the second and a FATHA on the +-- third component. + +local function getcomponentindex(start) + if start.id ~= glyph_code then + return 0 + elseif start.subtype == ligature_code then + local i = 0 + local components = start.components + while components do + i = i + getcomponentindex(components) + components = components.next + end + return i + elseif not marks[start.char] then + return 1 + else + return 0 + end +end + +-- eventually we will do positioning in an other way (needs addional w/h/d fields) + +local function toligature(kind,lookupname,head,start,stop,char,markflag,discfound) -- brr head + if start == stop and start.char == char then + start.char = char + return head, start + end + local prev = start.prev + local next = stop.next + start.prev = nil + stop.next = nil + local base = copy_glyph(start) + if start == head then + head = base + end + base.char = char + base.subtype = ligature_code + base.components = start -- start can have components + if prev then + prev.next = base + end + if next then + next.prev = base + end + base.next = next + base.prev = prev + if not discfound then + local deletemarks = markflag ~= "mark" + local components = start + local baseindex = 0 + local componentindex = 0 + local head = base + local current = base + -- first we loop over the glyphs in start .. stop + while start do + local char = start.char + if not marks[char] then + baseindex = baseindex + componentindex + componentindex = getcomponentindex(start) + elseif not deletemarks then -- quite fishy + start[a_ligacomp] = baseindex + (start[a_ligacomp] or componentindex) + if trace_marks then + logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp]) + end + head, current = insert_node_after(head,current,copy_node(start)) -- unlikely that mark has components + elseif trace_marks then + logwarning("%s: delete mark %s",pref(kind,lookupname),gref(char)) + end + start = start.next + end + -- we can have one accent as part of a lookup and another following + -- local start = components -- was wrong (component scanning was introduced when more complex ligs in devanagari was added) + local start = current.next + while start and start.id == glyph_code do + local char = start.char + if marks[char] then + start[a_ligacomp] = baseindex + (start[a_ligacomp] or componentindex) + if trace_marks then + logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp]) + end + else + break + end + start = start.next + end + end + return head, base +end + +function handlers.gsub_single(head,start,kind,lookupname,replacement) + if trace_singles then + logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(start.char),gref(replacement)) + end + start.char = replacement + return head, start, true +end + +local function get_alternative_glyph(start,alternatives,value,trace_alternatives) + local n = #alternatives + if value == "random" then + local r = random(1,n) + return alternatives[r], trace_alternatives and formatters["value %a, taking %a"](value,r) + elseif value == "first" then + return alternatives[1], trace_alternatives and formatters["value %a, taking %a"](value,1) + elseif value == "last" then + return alternatives[n], trace_alternatives and formatters["value %a, taking %a"](value,n) + else + value = tonumber(value) + if type(value) ~= "number" then + return alternatives[1], trace_alternatives and formatters["invalid value %s, taking %a"](value,1) + elseif value > n then + local defaultalt = otf.defaultnodealternate + if defaultalt == "first" then + return alternatives[n], trace_alternatives and formatters["invalid value %s, taking %a"](value,1) + elseif defaultalt == "last" then + return alternatives[1], trace_alternatives and formatters["invalid value %s, taking %a"](value,n) + else + return false, trace_alternatives and formatters["invalid value %a, %s"](value,"out of range") + end + elseif value == 0 then + return start.char, trace_alternatives and formatters["invalid value %a, %s"](value,"no change") + elseif value < 1 then + return alternatives[1], trace_alternatives and formatters["invalid value %a, taking %a"](value,1) + else + return alternatives[value], trace_alternatives and formatters["value %a, taking %a"](value,value) + end + end +end + +local function multiple_glyphs(head,start,multiple,ignoremarks) + local nofmultiples = #multiple + if nofmultiples > 0 then + start.char = multiple[1] + if nofmultiples > 1 then + local sn = start.next + for k=2,nofmultiples do -- todo: use insert_node +-- untested: +-- +-- while ignoremarks and marks[sn.char] then +-- local sn = sn.next +-- end + local n = copy_node(start) -- ignore components + n.char = multiple[k] + n.next = sn + n.prev = start + if sn then + sn.prev = n + end + start.next = n + start = n + end + end + return head, start, true + else + if trace_multiples then + logprocess("no multiple for %s",gref(start.char)) + end + return head, start, false + end +end + +function handlers.gsub_alternate(head,start,kind,lookupname,alternative,sequence) + local value = featurevalue == true and tfmdata.shared.features[kind] or featurevalue + local choice, comment = get_alternative_glyph(start,alternative,value,trace_alternatives) + if choice then + if trace_alternatives then + logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(start.char),choice,gref(choice),comment) + end + start.char = choice + else + if trace_alternatives then + logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(start.char),comment) + end + end + return head, start, true +end + +function handlers.gsub_multiple(head,start,kind,lookupname,multiple,sequence) + if trace_multiples then + logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(start.char),gref(multiple)) + end + return multiple_glyphs(head,start,multiple,sequence.flags[1]) +end + +function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) + local s, stop, discfound = start.next, nil, false + local startchar = start.char + if marks[startchar] then + while s do + local id = s.id + if id == glyph_code and s.font == currentfont and s.subtype<256 then + local lg = ligature[s.char] + if lg then + stop = s + ligature = lg + s = s.next + else + break + end + else + break + end + end + if stop then + local lig = ligature.ligature + if lig then + if trace_ligatures then + local stopchar = stop.char + head, start = markstoligature(kind,lookupname,head,start,stop,lig) + logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) + else + head, start = markstoligature(kind,lookupname,head,start,stop,lig) + end + return head, start, true + else + -- ok, goto next lookup + end + end + else + local skipmark = sequence.flags[1] + while s do + local id = s.id + if id == glyph_code and s.subtype<256 then + if s.font == currentfont then + local char = s.char + if skipmark and marks[char] then + s = s.next + else + local lg = ligature[char] + if lg then + stop = s + ligature = lg + s = s.next + else + break + end + end + else + break + end + elseif id == disc_code then + discfound = true + s = s.next + else + break + end + end + local lig = ligature.ligature + if lig then + if stop then + if trace_ligatures then + local stopchar = stop.char + head, start = toligature(kind,lookupname,head,start,stop,lig,skipmark,discfound) + logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) + else + head, start = toligature(kind,lookupname,head,start,stop,lig,skipmark,discfound) + end + return head, start, true + else + -- weird but happens (in some arabic font) + start.char = lig + if trace_ligatures then + logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(kind,lookupname),gref(startchar),gref(lig)) + end + return head, start, true + end + else + -- weird but happens + end + end + return head, start, false +end + +--[[ldx-- +

We get hits on a mark, but we're not sure if the it has to be applied so +we need to explicitly test for basechar, baselig and basemark entries.

+--ldx]]-- + +function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence) + local markchar = start.char + if marks[markchar] then + local base = start.prev -- [glyph] [start=mark] + if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then + local basechar = base.char + if marks[basechar] then + while true do + base = base.prev + if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then + basechar = base.char + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar)) + end + return head, start, false + end + end + end + local baseanchors = descriptions[basechar] + if baseanchors then + baseanchors = baseanchors.anchors + end + if baseanchors then + local baseanchors = baseanchors['basechar'] + if baseanchors then + local al = anchorlookups[lookupname] + for anchor,ba in next, baseanchors do + if al[anchor] then + local ma = markanchors[anchor] + if ma then + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", + pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) + end + return head, start, true + end + end + end + if trace_bugs then + logwarning("%s, no matching anchors for mark %s and base %s",pref(kind,lookupname),gref(markchar),gref(basechar)) + end + end + elseif trace_bugs then + -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(basechar)) + onetimemessage(currentfont,basechar,"no base anchors",report_fonts) + end + elseif trace_bugs then + logwarning("%s: prev node is no char",pref(kind,lookupname)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar)) + end + return head, start, false +end + +function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequence) + -- check chainpos variant + local markchar = start.char + if marks[markchar] then + local base = start.prev -- [glyph] [optional marks] [start=mark] + if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then + local basechar = base.char + if marks[basechar] then + while true do + base = base.prev + if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then + basechar = base.char + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar)) + end + return head, start, false + end + end + end + local index = start[a_ligacomp] + local baseanchors = descriptions[basechar] + if baseanchors then + baseanchors = baseanchors.anchors + if baseanchors then + local baseanchors = baseanchors['baselig'] + if baseanchors then + local al = anchorlookups[lookupname] + for anchor, ba in next, baseanchors do + if al[anchor] then + local ma = markanchors[anchor] + if ma then + ba = ba[index] + if ba then + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) -- index + if trace_marks then + logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", + pref(kind,lookupname),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy) + end + return head, start, true + else + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and baselig %s with index %a",pref(kind,lookupname),gref(markchar),gref(basechar),index) + end + end + end + end + end + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and baselig %s",pref(kind,lookupname),gref(markchar),gref(basechar)) + end + end + end + elseif trace_bugs then + -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(basechar)) + onetimemessage(currentfont,basechar,"no base anchors",report_fonts) + end + elseif trace_bugs then + logwarning("%s: prev node is no char",pref(kind,lookupname)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar)) + end + return head, start, false +end + +function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence) + local markchar = start.char + if marks[markchar] then + local base = start.prev -- [glyph] [basemark] [start=mark] + local slc = start[a_ligacomp] + if slc then -- a rather messy loop ... needs checking with husayni + while base do + local blc = base[a_ligacomp] + if blc and blc ~= slc then + base = base.prev + else + break + end + end + end + if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then -- subtype test can go + local basechar = base.char + local baseanchors = descriptions[basechar] + if baseanchors then + baseanchors = baseanchors.anchors + if baseanchors then + baseanchors = baseanchors['basemark'] + if baseanchors then + local al = anchorlookups[lookupname] + for anchor,ba in next, baseanchors do + if al[anchor] then + local ma = markanchors[anchor] + if ma then + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,true) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", + pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) + end + return head, start, true + end + end + end + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and basemark %s",pref(kind,lookupname),gref(markchar),gref(basechar)) + end + end + end + elseif trace_bugs then + -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(basechar)) + onetimemessage(currentfont,basechar,"no base anchors",report_fonts) + end + elseif trace_bugs then + logwarning("%s: prev node is no mark",pref(kind,lookupname)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar)) + end + return head, start, false +end + +function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) -- to be checked + local alreadydone = cursonce and start[a_cursbase] + if not alreadydone then + local done = false + local startchar = start.char + if marks[startchar] then + if trace_cursive then + logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar)) + end + else + local nxt = start.next + while not done and nxt and nxt.id == glyph_code and nxt.font == currentfont and nxt.subtype<256 do + local nextchar = nxt.char + if marks[nextchar] then + -- should not happen (maybe warning) + nxt = nxt.next + else + local entryanchors = descriptions[nextchar] + if entryanchors then + entryanchors = entryanchors.anchors + if entryanchors then + entryanchors = entryanchors['centry'] + if entryanchors then + local al = anchorlookups[lookupname] + for anchor, entry in next, entryanchors do + if al[anchor] then + local exit = exitanchors[anchor] + if exit then + local dx, dy, bound = setcursive(start,nxt,tfmdata.parameters.factor,rlmode,exit,entry,characters[startchar],characters[nextchar]) + if trace_cursive then + logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode) + end + done = true + break + end + end + end + end + end + elseif trace_bugs then + -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(startchar)) + onetimemessage(currentfont,startchar,"no entry anchors",report_fonts) + end + break + end + end + end + return head, start, done + else + if trace_cursive and trace_details then + logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone) + end + return head, start, false + end +end + +function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence) + local startchar = start.char + local dx, dy, w, h = setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) + if trace_kerns then + logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) + end + return head, start, false +end + +function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) + -- todo: kerns in disc nodes: pre, post, replace -> loop over disc too + -- todo: kerns in components of ligatures + local snext = start.next + if not snext then + return head, start, false + else + local prev, done = start, false + local factor = tfmdata.parameters.factor + local lookuptype = lookuptypes[lookupname] + while snext and snext.id == glyph_code and snext.font == currentfont and snext.subtype<256 do + local nextchar = snext.char + local krn = kerns[nextchar] + if not krn and marks[nextchar] then + prev = snext + snext = snext.next + else + if not krn then + -- skip + elseif type(krn) == "table" then + if lookuptype == "pair" then -- probably not needed + local a, b = krn[2], krn[3] + if a and #a > 0 then + local startchar = start.char + local x, y, w, h = setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) + if trace_kerns then + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) + end + end + if b and #b > 0 then + local startchar = start.char + local x, y, w, h = setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) + if trace_kerns then + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) + end + end + else -- wrong ... position has different entries + report_process("%s: check this out (old kern stuff)",pref(kind,lookupname)) + -- local a, b = krn[2], krn[6] + -- if a and a ~= 0 then + -- local k = setkern(snext,factor,rlmode,a) + -- if trace_kerns then + -- logprocess("%s: inserting first kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar)) + -- end + -- end + -- if b and b ~= 0 then + -- logwarning("%s: ignoring second kern xoff %s",pref(kind,lookupname),b*factor) + -- end + end + done = true + elseif krn ~= 0 then + local k = setkern(snext,factor,rlmode,krn) + if trace_kerns then + logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar)) + end + done = true + end + break + end + end + return head, start, done + end +end + +--[[ldx-- +

I will implement multiple chain replacements once I run into a font that uses +it. It's not that complex to handle.

+--ldx]]-- + +local chainmores = { } +local chainprocs = { } + +local function logprocess(...) + if trace_steps then + registermessage(...) + end + report_subchain(...) +end + +local logwarning = report_subchain + +local function logprocess(...) + if trace_steps then + registermessage(...) + end + report_chain(...) +end + +local logwarning = report_chain + +-- We could share functions but that would lead to extra function calls with many +-- arguments, redundant tests and confusing messages. + +function chainprocs.chainsub(head,start,stop,kind,chainname,currentcontext,lookuphash,lookuplist,chainlookupname) + logwarning("%s: a direct call to chainsub cannot happen",cref(kind,chainname,chainlookupname)) + return head, start, false +end + +function chainmores.chainsub(head,start,stop,kind,chainname,currentcontext,lookuphash,lookuplist,chainlookupname,n) + logprocess("%s: a direct call to chainsub cannot happen",cref(kind,chainname,chainlookupname)) + return head, start, false +end + +-- The reversesub is a special case, which is why we need to store the replacements +-- in a bit weird way. There is no lookup and the replacement comes from the lookup +-- itself. It is meant mostly for dealing with Urdu. + +function chainprocs.reversesub(head,start,stop,kind,chainname,currentcontext,lookuphash,replacements) + local char = start.char + local replacement = replacements[char] + if replacement then + if trace_singles then + logprocess("%s: single reverse replacement of %s by %s",cref(kind,chainname),gref(char),gref(replacement)) + end + start.char = replacement + return head, start, true + else + return head, start, false + end +end + +--[[ldx-- +

This chain stuff is somewhat tricky since we can have a sequence of actions to be +applied: single, alternate, multiple or ligature where ligature can be an invalid +one in the sense that it will replace multiple by one but not neccessary one that +looks like the combination (i.e. it is the counterpart of multiple then). For +example, the following is valid:

+ + +xxxabcdexxx [single a->A][multiple b->BCD][ligature cde->E] xxxABCDExxx + + +

Therefore we we don't really do the replacement here already unless we have the +single lookup case. The efficiency of the replacements can be improved by deleting +as less as needed but that would also make the code even more messy.

+--ldx]]-- + +-- local function delete_till_stop(head,start,stop,ignoremarks) -- keeps start +-- local n = 1 +-- if start == stop then +-- -- done +-- elseif ignoremarks then +-- repeat -- start x x m x x stop => start m +-- local next = start.next +-- if not marks[next.char] then +-- local components = next.components +-- if components then -- probably not needed +-- flush_node_list(components) +-- end +-- head = delete_node(head,next) +-- end +-- n = n + 1 +-- until next == stop +-- else -- start x x x stop => start +-- repeat +-- local next = start.next +-- local components = next.components +-- if components then -- probably not needed +-- flush_node_list(components) +-- end +-- head = delete_node(head,next) +-- n = n + 1 +-- until next == stop +-- end +-- return head, n +-- end + +--[[ldx-- +

Here we replace start by a single variant, First we delete the rest of the +match.

+--ldx]]-- + +function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex) + -- todo: marks ? + local current = start + local subtables = currentlookup.subtables + if #subtables > 1 then + logwarning("todo: check if we need to loop over the replacements: %s",concat(subtables," ")) + end + while current do + if current.id == glyph_code then + local currentchar = current.char + local lookupname = subtables[1] -- only 1 + local replacement = lookuphash[lookupname] + if not replacement then + if trace_bugs then + logwarning("%s: no single hits",cref(kind,chainname,chainlookupname,lookupname,chainindex)) + end + else + replacement = replacement[currentchar] + if not replacement or replacement == "" then + if trace_bugs then + logwarning("%s: no single for %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar)) + end + else + if trace_singles then + logprocess("%s: replacing single %s by %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar),gref(replacement)) + end + current.char = replacement + end + end + return head, start, true + elseif current == stop then + break + else + current = current.next + end + end + return head, start, false +end + +chainmores.gsub_single = chainprocs.gsub_single + +--[[ldx-- +

Here we replace start by a sequence of new glyphs. First we delete the rest of +the match.

+--ldx]]-- + +function chainprocs.gsub_multiple(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) + -- local head, n = delete_till_stop(head,start,stop) + local startchar = start.char + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local replacements = lookuphash[lookupname] + if not replacements then + if trace_bugs then + logwarning("%s: no multiple hits",cref(kind,chainname,chainlookupname,lookupname)) + end + else + replacements = replacements[startchar] + if not replacements or replacement == "" then + if trace_bugs then + logwarning("%s: no multiple for %s",cref(kind,chainname,chainlookupname,lookupname),gref(startchar)) + end + else + if trace_multiples then + logprocess("%s: replacing %s by multiple characters %s",cref(kind,chainname,chainlookupname,lookupname),gref(startchar),gref(replacements)) + end + return multiple_glyphs(head,start,replacements,currentlookup.flags[1]) + end + end + return head, start, false +end + +chainmores.gsub_multiple = chainprocs.gsub_multiple + +--[[ldx-- +

Here we replace start by new glyph. First we delete the rest of the match.

+--ldx]]-- + +-- char_1 mark_1 -> char_x mark_1 (ignore marks) +-- char_1 mark_1 -> char_x + +-- to be checked: do we always have just one glyph? +-- we can also have alternates for marks +-- marks come last anyway +-- are there cases where we need to delete the mark + +function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) + local current = start + local subtables = currentlookup.subtables + local value = featurevalue == true and tfmdata.shared.features[kind] or featurevalue + while current do + if current.id == glyph_code then -- is this check needed? + local currentchar = current.char + local lookupname = subtables[1] + local alternatives = lookuphash[lookupname] + if not alternatives then + if trace_bugs then + logwarning("%s: no alternative hit",cref(kind,chainname,chainlookupname,lookupname)) + end + else + alternatives = alternatives[currentchar] + if alternatives then + local choice, comment = get_alternative_glyph(current,alternatives,value,trace_alternatives) + if choice then + if trace_alternatives then + logprocess("%s: replacing %s by alternative %a to %s, %s",cref(kind,chainname,chainlookupname,lookupname),gref(char),choice,gref(choice),comment) + end + start.char = choice + else + if trace_alternatives then + logwarning("%s: no variant %a for %s, %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(char),comment) + end + end + elseif trace_bugs then + logwarning("%s: no alternative for %s, %s",cref(kind,chainname,chainlookupname,lookupname),gref(currentchar),comment) + end + end + return head, start, true + elseif current == stop then + break + else + current = current.next + end + end + return head, start, false +end + +chainmores.gsub_alternate = chainprocs.gsub_alternate + +--[[ldx-- +

When we replace ligatures we use a helper that handles the marks. I might change +this function (move code inline and handle the marks by a separate function). We +assume rather stupid ligatures (no complex disc nodes).

+--ldx]]-- + +function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex) + local startchar = start.char + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local ligatures = lookuphash[lookupname] + if not ligatures then + if trace_bugs then + logwarning("%s: no ligature hits",cref(kind,chainname,chainlookupname,lookupname,chainindex)) + end + else + ligatures = ligatures[startchar] + if not ligatures then + if trace_bugs then + logwarning("%s: no ligatures starting with %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) + end + else + local s = start.next + local discfound = false + local last = stop + local nofreplacements = 0 + local skipmark = currentlookup.flags[1] + while s do + local id = s.id + if id == disc_code then + s = s.next + discfound = true + else + local schar = s.char + if skipmark and marks[schar] then -- marks + s = s.next + else + local lg = ligatures[schar] + if lg then + ligatures, last, nofreplacements = lg, s, nofreplacements + 1 + if s == stop then + break + else + s = s.next + end + else + break + end + end + end + end + local l2 = ligatures.ligature + if l2 then + if chainindex then + stop = last + end + if trace_ligatures then + if start == stop then + logprocess("%s: replacing character %s by ligature %s case 3",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(l2)) + else + logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char),gref(l2)) + end + end + head, start = toligature(kind,lookupname,head,start,stop,l2,currentlookup.flags[1],discfound) + return head, start, true, nofreplacements + elseif trace_bugs then + if start == stop then + logwarning("%s: replacing character %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) + else + logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char)) + end + end + end + end + return head, start, false, 0 +end + +chainmores.gsub_ligature = chainprocs.gsub_ligature + +function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) + local markchar = start.char + if marks[markchar] then + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local markanchors = lookuphash[lookupname] + if markanchors then + markanchors = markanchors[markchar] + end + if markanchors then + local base = start.prev -- [glyph] [start=mark] + if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then + local basechar = base.char + if marks[basechar] then + while true do + base = base.prev + if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then + basechar = base.char + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar)) + end + return head, start, false + end + end + end + local baseanchors = descriptions[basechar].anchors + if baseanchors then + local baseanchors = baseanchors['basechar'] + if baseanchors then + local al = anchorlookups[lookupname] + for anchor,ba in next, baseanchors do + if al[anchor] then + local ma = markanchors[anchor] + if ma then + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", + cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) + end + return head, start, true + end + end + end + if trace_bugs then + logwarning("%s, no matching anchors for mark %s and base %s",cref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar)) + end + end + end + elseif trace_bugs then + logwarning("%s: prev node is no char",cref(kind,chainname,chainlookupname,lookupname)) + end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar)) + end + return head, start, false +end + +function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) + local markchar = start.char + if marks[markchar] then + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local markanchors = lookuphash[lookupname] + if markanchors then + markanchors = markanchors[markchar] + end + if markanchors then + local base = start.prev -- [glyph] [optional marks] [start=mark] + if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then + local basechar = base.char + if marks[basechar] then + while true do + base = base.prev + if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then + basechar = base.char + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s",cref(kind,chainname,chainlookupname,lookupname),markchar) + end + return head, start, false + end + end + end + -- todo: like marks a ligatures hash + local index = start[a_ligacomp] + local baseanchors = descriptions[basechar].anchors + if baseanchors then + local baseanchors = baseanchors['baselig'] + if baseanchors then + local al = anchorlookups[lookupname] + for anchor,ba in next, baseanchors do + if al[anchor] then + local ma = markanchors[anchor] + if ma then + ba = ba[index] + if ba then + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) -- index + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", + cref(kind,chainname,chainlookupname,lookupname),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy) + end + return head, start, true + end + end + end + end + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and baselig %s",cref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar)) + end + end + end + elseif trace_bugs then + logwarning("feature %s, lookup %s: prev node is no char",kind,lookupname) + end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar)) + end + return head, start, false +end + +function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) + local markchar = start.char + if marks[markchar] then + -- local alreadydone = markonce and start[a_markmark] + -- if not alreadydone then + -- local markanchors = descriptions[markchar].anchors markanchors = markanchors and markanchors.mark + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local markanchors = lookuphash[lookupname] + if markanchors then + markanchors = markanchors[markchar] + end + if markanchors then + local base = start.prev -- [glyph] [basemark] [start=mark] + local slc = start[a_ligacomp] + if slc then -- a rather messy loop ... needs checking with husayni + while base do + local blc = base[a_ligacomp] + if blc and blc ~= slc then + base = base.prev + else + break + end + end + end + if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then -- subtype test can go + local basechar = base.char + local baseanchors = descriptions[basechar].anchors + if baseanchors then + baseanchors = baseanchors['basemark'] + if baseanchors then + local al = anchorlookups[lookupname] + for anchor,ba in next, baseanchors do + if al[anchor] then + local ma = markanchors[anchor] + if ma then + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,true) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", + cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) + end + return head, start, true + end + end + end + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and basemark %s",gref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar)) + end + end + end + elseif trace_bugs then + logwarning("%s: prev node is no mark",cref(kind,chainname,chainlookupname,lookupname)) + end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar)) + end + -- elseif trace_marks and trace_details then + -- logprocess("%s, mark %s is already bound (n=%s), ignoring mark2mark",pref(kind,lookupname),gref(markchar),alreadydone) + -- end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar)) + end + return head, start, false +end + +function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) + local alreadydone = cursonce and start[a_cursbase] + if not alreadydone then + local startchar = start.char + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local exitanchors = lookuphash[lookupname] + if exitanchors then + exitanchors = exitanchors[startchar] + end + if exitanchors then + local done = false + if marks[startchar] then + if trace_cursive then + logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar)) + end + else + local nxt = start.next + while not done and nxt and nxt.id == glyph_code and nxt.font == currentfont and nxt.subtype<256 do + local nextchar = nxt.char + if marks[nextchar] then + -- should not happen (maybe warning) + nxt = nxt.next + else + local entryanchors = descriptions[nextchar] + if entryanchors then + entryanchors = entryanchors.anchors + if entryanchors then + entryanchors = entryanchors['centry'] + if entryanchors then + local al = anchorlookups[lookupname] + for anchor, entry in next, entryanchors do + if al[anchor] then + local exit = exitanchors[anchor] + if exit then + local dx, dy, bound = setcursive(start,nxt,tfmdata.parameters.factor,rlmode,exit,entry,characters[startchar],characters[nextchar]) + if trace_cursive then + logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode) + end + done = true + break + end + end + end + end + end + elseif trace_bugs then + -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(startchar)) + onetimemessage(currentfont,startchar,"no entry anchors",report_fonts) + end + break + end + end + end + return head, start, done + else + if trace_cursive and trace_details then + logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone) + end + return head, start, false + end + end + return head, start, false +end + +function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) + -- untested .. needs checking for the new model + local startchar = start.char + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local kerns = lookuphash[lookupname] + if kerns then + kerns = kerns[startchar] -- needed ? + if kerns then + local dx, dy, w, h = setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) + if trace_kerns then + logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),dx,dy,w,h) + end + end + end + return head, start, false +end + +chainmores.gpos_single = chainprocs.gpos_single -- okay? + +-- when machines become faster i will make a shared function + +function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) + local snext = start.next + if snext then + local startchar = start.char + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local kerns = lookuphash[lookupname] + if kerns then + kerns = kerns[startchar] + if kerns then + local lookuptype = lookuptypes[lookupname] + local prev, done = start, false + local factor = tfmdata.parameters.factor + while snext and snext.id == glyph_code and snext.font == currentfont and snext.subtype<256 do + local nextchar = snext.char + local krn = kerns[nextchar] + if not krn and marks[nextchar] then + prev = snext + snext = snext.next + else + if not krn then + -- skip + elseif type(krn) == "table" then + if lookuptype == "pair" then + local a, b = krn[2], krn[3] + if a and #a > 0 then + local startchar = start.char + local x, y, w, h = setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) + if trace_kerns then + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) + end + end + if b and #b > 0 then + local startchar = start.char + local x, y, w, h = setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) + if trace_kerns then + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) + end + end + else + report_process("%s: check this out (old kern stuff)",cref(kind,chainname,chainlookupname)) + local a, b = krn[2], krn[6] + if a and a ~= 0 then + local k = setkern(snext,factor,rlmode,a) + if trace_kerns then + logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar)) + end + end + if b and b ~= 0 then + logwarning("%s: ignoring second kern xoff %s",cref(kind,chainname,chainlookupname),b*factor) + end + end + done = true + elseif krn ~= 0 then + local k = setkern(snext,factor,rlmode,krn) + if trace_kerns then + logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar)) + end + done = true + end + break + end + end + return head, start, done + end + end + end + return head, start, false +end + +chainmores.gpos_pair = chainprocs.gpos_pair -- okay? + +-- what pointer to return, spec says stop +-- to be discussed ... is bidi changer a space? +-- elseif char == zwnj and sequence[n][32] then -- brrr + +-- somehow l or f is global +-- we don't need to pass the currentcontext, saves a bit +-- make a slow variant then can be activated but with more tracing + +local function show_skip(kind,chainname,char,ck,class) + if ck[9] then + logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a, %a => %a",cref(kind,chainname),gref(char),class,ck[1],ck[2],ck[9],ck[10]) + else + logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(kind,chainname),gref(char),class,ck[1],ck[2]) + end +end + +local function normal_handle_contextchain(head,start,kind,chainname,contexts,sequence,lookuphash) + -- local rule, lookuptype, sequence, f, l, lookups = ck[1], ck[2] ,ck[3], ck[4], ck[5], ck[6] + local flags = sequence.flags + local done = false + local skipmark = flags[1] + local skipligature = flags[2] + local skipbase = flags[3] + local someskip = skipmark or skipligature or skipbase -- could be stored in flags for a fast test (hm, flags could be false !) + local markclass = sequence.markclass -- todo, first we need a proper test + local skipped = false + for k=1,#contexts do + local match = true + local current = start + local last = start + local ck = contexts[k] + local seq = ck[3] + local s = #seq + -- f..l = mid string + if s == 1 then + -- never happens + match = current.id == glyph_code and current.font == currentfont and current.subtype<256 and seq[1][current.char] + else + -- maybe we need a better space check (maybe check for glue or category or combination) + -- we cannot optimize for n=2 because there can be disc nodes + local f, l = ck[4], ck[5] + -- current match + if f == 1 and f == l then -- current only + -- already a hit + -- match = true + else -- before/current/after | before/current | current/after + -- no need to test first hit (to be optimized) + if f == l then -- new, else last out of sync (f is > 1) + -- match = true + else + local n = f + 1 + last = last.next + while n <= l do + if last then + local id = last.id + if id == glyph_code then + if last.font == currentfont and last.subtype<256 then + local char = last.char + local ccd = descriptions[char] + if ccd then + local class = ccd.class + if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then + skipped = true + if trace_skips then + show_skip(kind,chainname,char,ck,class) + end + last = last.next + elseif seq[n][char] then + if n < l then + last = last.next + end + n = n + 1 + else + match = false + break + end + else + match = false + break + end + else + match = false + break + end + elseif id == disc_code then + last = last.next + else + match = false + break + end + else + match = false + break + end + end + end + end + -- before + if match and f > 1 then + local prev = start.prev + if prev then + local n = f-1 + while n >= 1 do + if prev then + local id = prev.id + if id == glyph_code then + if prev.font == currentfont and prev.subtype<256 then -- normal char + local char = prev.char + local ccd = descriptions[char] + if ccd then + local class = ccd.class + if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then + skipped = true + if trace_skips then + show_skip(kind,chainname,char,ck,class) + end + elseif seq[n][char] then + n = n -1 + else + match = false + break + end + else + match = false + break + end + else + match = false + break + end + elseif id == disc_code then + -- skip 'm + elseif seq[n][32] then + n = n -1 + else + match = false + break + end + prev = prev.prev + elseif seq[n][32] then -- somewhat special, as zapfino can have many preceding spaces + n = n -1 + else + match = false + break + end + end + elseif f == 2 then + match = seq[1][32] + else + for n=f-1,1 do + if not seq[n][32] then + match = false + break + end + end + end + end + -- after + if match and s > l then + local current = last and last.next + if current then + -- removed optimization for s-l == 1, we have to deal with marks anyway + local n = l + 1 + while n <= s do + if current then + local id = current.id + if id == glyph_code then + if current.font == currentfont and current.subtype<256 then -- normal char + local char = current.char + local ccd = descriptions[char] + if ccd then + local class = ccd.class + if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then + skipped = true + if trace_skips then + show_skip(kind,chainname,char,ck,class) + end + elseif seq[n][char] then + n = n + 1 + else + match = false + break + end + else + match = false + break + end + else + match = false + break + end + elseif id == disc_code then + -- skip 'm + elseif seq[n][32] then -- brrr + n = n + 1 + else + match = false + break + end + current = current.next + elseif seq[n][32] then + n = n + 1 + else + match = false + break + end + end + elseif s-l == 1 then + match = seq[s][32] + else + for n=l+1,s do + if not seq[n][32] then + match = false + break + end + end + end + end + end + if match then + -- ck == currentcontext + if trace_contexts then + local rule, lookuptype, f, l = ck[1], ck[2], ck[4], ck[5] + local char = start.char + if ck[9] then + logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %a, %a => %a", + cref(kind,chainname),rule,gref(char),f-1,l-f+1,s-l,lookuptype,ck[9],ck[10]) + else + logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %a", + cref(kind,chainname),rule,gref(char),f-1,l-f+1,s-l,lookuptype) + end + end + local chainlookups = ck[6] + if chainlookups then + local nofchainlookups = #chainlookups + -- we can speed this up if needed + if nofchainlookups == 1 then + local chainlookupname = chainlookups[1] + local chainlookup = lookuptable[chainlookupname] + if chainlookup then + local cp = chainprocs[chainlookup.type] + if cp then + local ok + head, start, ok = cp(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence) + if ok then + done = true + end + else + logprocess("%s: %s is not yet supported",cref(kind,chainname,chainlookupname),chainlookup.type) + end + else -- shouldn't happen + logprocess("%s is not yet supported",cref(kind,chainname,chainlookupname)) + end + else + local i = 1 + repeat + if skipped then + while true do + local char = start.char + local ccd = descriptions[char] + if ccd then + local class = ccd.class + if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then + start = start.next + else + break + end + else + break + end + end + end + local chainlookupname = chainlookups[i] + local chainlookup = lookuptable[chainlookupname] + if not chainlookup then + -- okay, n matches, < n replacements + i = i + 1 + else + local cp = chainmores[chainlookup.type] + if not cp then + -- actually an error + logprocess("%s: %s is not yet supported",cref(kind,chainname,chainlookupname),chainlookup.type) + i = i + 1 + else + local ok, n + head, start, ok, n = cp(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,i,sequence) + -- messy since last can be changed ! + if ok then + done = true + -- skip next one(s) if ligature + i = i + (n or 1) + else + i = i + 1 + end + end + end + if start then + start = start.next + else + -- weird + end + until i > nofchainlookups + end + else + local replacements = ck[7] + if replacements then + head, start, done = chainprocs.reversesub(head,start,last,kind,chainname,ck,lookuphash,replacements) -- sequence + else + done = true -- can be meant to be skipped + if trace_contexts then + logprocess("%s: skipping match",cref(kind,chainname)) + end + end + end + end + end + return head, start, done +end + +-- Because we want to keep this elsewhere (an because speed is less an issue) we +-- pass the font id so that the verbose variant can access the relevant helper tables. + +local verbose_handle_contextchain = function(font,...) + logwarning("no verbose handler installed, reverting to 'normal'") + otf.setcontextchain() + return normal_handle_contextchain(...) +end + +otf.chainhandlers = { + normal = normal_handle_contextchain, + verbose = verbose_handle_contextchain, +} + +function otf.setcontextchain(method) + if not method or method == "normal" or not otf.chainhandlers[method] then + if handlers.contextchain then -- no need for a message while making the format + logwarning("installing normal contextchain handler") + end + handlers.contextchain = normal_handle_contextchain + else + logwarning("installing contextchain handler %a",method) + local handler = otf.chainhandlers[method] + handlers.contextchain = function(...) + return handler(currentfont,...) -- hm, get rid of ... + end + end + handlers.gsub_context = handlers.contextchain + handlers.gsub_contextchain = handlers.contextchain + handlers.gsub_reversecontextchain = handlers.contextchain + handlers.gpos_contextchain = handlers.contextchain + handlers.gpos_context = handlers.contextchain +end + +otf.setcontextchain() + +local missing = { } -- we only report once + +local function logprocess(...) + if trace_steps then + registermessage(...) + end + report_process(...) +end + +local logwarning = report_process + +local function report_missing_cache(typ,lookup) + local f = missing[currentfont] if not f then f = { } missing[currentfont] = f end + local t = f[typ] if not t then t = { } f[typ] = t end + if not t[lookup] then + t[lookup] = true + logwarning("missing cache for lookup %a, type %a, font %a, name %a",lookup,typ,currentfont,tfmdata.properties.fullname) + end +end + +local resolved = { } -- we only resolve a font,script,language pair once + +-- todo: pass all these 'locals' in a table + +local lookuphashes = { } + +setmetatableindex(lookuphashes, function(t,font) + local lookuphash = fontdata[font].resources.lookuphash + if not lookuphash or not next(lookuphash) then + lookuphash = false + end + t[font] = lookuphash + return lookuphash +end) + +-- fonts.hashes.lookups = lookuphashes + +local autofeatures = fonts.analyzers.features -- was: constants + +local function initialize(sequence,script,language,enabled) + local features = sequence.features + if features then + for kind, scripts in next, features do + local valid = enabled[kind] + if valid then + local languages = scripts[script] or scripts[wildcard] + if languages and (languages[language] or languages[wildcard]) then + return { valid, autofeatures[kind] or false, sequence.chain or 0, kind, sequence } + end + end + end + end + return false +end + +function otf.dataset(tfmdata,font) -- generic variant, overloaded in context + local shared = tfmdata.shared + local properties = tfmdata.properties + local language = properties.language or "dflt" + local script = properties.script or "dflt" + local enabled = shared.features + local res = resolved[font] + if not res then + res = { } + resolved[font] = res + end + local rs = res[script] + if not rs then + rs = { } + res[script] = rs + end + local rl = rs[language] + if not rl then + rl = { + -- indexed but we can also add specific data by key + } + rs[language] = rl + local sequences = tfmdata.resources.sequences +-- setmetatableindex(rl, function(t,k) +-- if type(k) == "number" then +-- local v = enabled and initialize(sequences[k],script,language,enabled) +-- t[k] = v +-- return v +-- end +-- end) +for s=1,#sequences do + local v = enabled and initialize(sequences[s],script,language,enabled) + if v then + rl[#rl+1] = v + end +end + end + return rl +end + +-- elseif id == glue_code then +-- if p[5] then -- chain +-- local pc = pp[32] +-- if pc then +-- start, ok = start, false -- p[1](start,kind,p[2],pc,p[3],p[4]) +-- if ok then +-- done = true +-- end +-- if start then start = start.next end +-- else +-- start = start.next +-- end +-- else +-- start = start.next +-- end + +-- there will be a new direction parser (pre-parsed etc) + +-- less bytecode: 290 -> 254 +-- +-- attr = attr or false +-- +-- local a = getattr(start,0) +-- if (a == attr and (not attribute or getattr(start,a_state) == attribute)) or (not attribute or getattr(start,a_state) == attribute) then +-- -- the action +-- end + +local function featuresprocessor(head,font,attr) + + local lookuphash = lookuphashes[font] -- we can also check sequences here + + if not lookuphash then + return head, false + end + + if trace_steps then + checkstep(head) + end + + tfmdata = fontdata[font] + descriptions = tfmdata.descriptions + characters = tfmdata.characters + resources = tfmdata.resources + + marks = resources.marks + anchorlookups = resources.lookup_to_anchor + lookuptable = resources.lookups + lookuptypes = resources.lookuptypes + + currentfont = font + rlmode = 0 + + local sequences = resources.sequences + local done = false + local datasets = otf.dataset(tfmdata,font,attr) + + local dirstack = { } -- could move outside function + + -- We could work on sub start-stop ranges instead but I wonder if there is that + -- much speed gain (experiments showed that it made not much sense) and we need + -- to keep track of directions anyway. Also at some point I want to play with + -- font interactions and then we do need the full sweeps. + + -- Keeping track of the headnode is needed for devanagari (I generalized it a bit + -- so that multiple cases are also covered.) + + for s=1,#datasets do + local dataset = datasets[s] + featurevalue = dataset[1] -- todo: pass to function instead of using a global + + local sequence = dataset[5] -- sequences[s] -- also dataset[5] + local rlparmode = 0 + local topstack = 0 + local success = false + local attribute = dataset[2] + local chain = dataset[3] -- sequence.chain or 0 + local typ = sequence.type + local subtables = sequence.subtables + if chain < 0 then + -- this is a limited case, no special treatments like 'init' etc + local handler = handlers[typ] + -- we need to get rid of this slide! probably no longer needed in latest luatex + local start = find_node_tail(head) -- slow (we can store tail because there's always a skip at the end): todo + while start do + local id = start.id + if id == glyph_code then + if start.font == font and start.subtype<256 then + local a = start[0] + if a then + a = a == attr + else + a = true + end + if a then + for i=1,#subtables do + local lookupname = subtables[i] + local lookupcache = lookuphash[lookupname] + if lookupcache then + local lookupmatch = lookupcache[start.char] + if lookupmatch then + head, start, success = handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) + if success then + break + end + end + else + report_missing_cache(typ,lookupname) + end + end + if start then start = start.prev end + else + start = start.prev + end + else + start = start.prev + end + else + start = start.prev + end + end + else + local handler = handlers[typ] + local ns = #subtables + local start = head -- local ? + rlmode = 0 -- to be checked ? + if ns == 1 then -- happens often + local lookupname = subtables[1] + local lookupcache = lookuphash[lookupname] + if not lookupcache then -- also check for empty cache + report_missing_cache(typ,lookupname) + else + + local function subrun(start) + -- mostly for gsub, gpos would demand a more clever approach + local head = start + local done = false + while start do + local id = start.id + if id == glyph_code and start.font == font and start.subtype <256 then + local a = start[0] + if a then + a = (a == attr) and (not attribute or start[a_state] == attribute) + else + a = not attribute or start[a_state] == attribute + end + if a then + local lookupmatch = lookupcache[start.char] + if lookupmatch then + -- sequence kan weg + local ok + head, start, ok = handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) + if ok then + done = true + end + end + if start then start = start.next end + else + start = start.next + end + else + start = start.next + end + end + if done then + success = true + return head + end + end + + local function kerndisc(disc) -- we can assume that prev and next are glyphs + local prev = disc.prev + local next = disc.next + if prev and next then + prev.next = next + -- next.prev = prev + local a = prev[0] + if a then + a = (a == attr) and (not attribute or prev[a_state] == attribute) + else + a = not attribute or prev[a_state] == attribute + end + if a then + local lookupmatch = lookupcache[prev.char] + if lookupmatch then + -- sequence kan weg + local h, d, ok = handler(head,prev,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) + if ok then + done = true + success = true + end + end + end + prev.next = disc + -- next.prev = disc + end + return next + end + + while start do + local id = start.id + if id == glyph_code then + if start.font == font and start.subtype<256 then + local a = start[0] + if a then + a = (a == attr) and (not attribute or start[a_state] == attribute) + else + a = not attribute or start[a_state] == attribute + end + if a then + local lookupmatch = lookupcache[start.char] + if lookupmatch then + -- sequence kan weg + local ok + head, start, ok = handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) + if ok then + success = true + end + end + if start then start = start.next end + else + start = start.next + end + else + start = start.next + end + elseif id == disc_code then + -- mostly for gsub + if start.subtype == discretionary_code then + local pre = start.pre + if pre then + local new = subrun(pre) + if new then start.pre = new end + end + local post = start.post + if post then + local new = subrun(post) + if new then start.post = new end + end + local replace = start.replace + if replace then + local new = subrun(replace) + if new then start.replace = new end + end +elseif typ == "gpos_single" or typ == "gpos_pair" then + kerndisc(start) + end + start = start.next + elseif id == whatsit_code then -- will be function + local subtype = start.subtype + if subtype == dir_code then + local dir = start.dir + if dir == "+TRT" or dir == "+TLT" then + topstack = topstack + 1 + dirstack[topstack] = dir + elseif dir == "-TRT" or dir == "-TLT" then + topstack = topstack - 1 + end + local newdir = dirstack[topstack] + if newdir == "+TRT" then + rlmode = -1 + elseif newdir == "+TLT" then + rlmode = 1 + else + rlmode = rlparmode + end + if trace_directions then + report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir) + end + elseif subtype == localpar_code then + local dir = start.dir + if dir == "TRT" then + rlparmode = -1 + elseif dir == "TLT" then + rlparmode = 1 + else + rlparmode = 0 + end + -- one might wonder if the par dir should be looked at, so we might as well drop the next line + rlmode = rlparmode + if trace_directions then + report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode) + end + end + start = start.next + elseif id == math_code then + start = end_of_math(start).next + else + start = start.next + end + end + end + else + + local function subrun(start) + -- mostly for gsub, gpos would demand a more clever approach + local head = start + local done = false + while start do + local id = start.id + if id == glyph_code and start.id == font and start.subtype <256 then + local a = start[0] + if a then + a = (a == attr) and (not attribute or start[a_state] == attribute) + else + a = not attribute or start[a_state] == attribute + end + if a then + for i=1,ns do + local lookupname = subtables[i] + local lookupcache = lookuphash[lookupname] + if lookupcache then + local lookupmatch = lookupcache[start.char] + if lookupmatch then + -- we could move all code inline but that makes things even more unreadable + local ok + head, start, ok = handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) + if ok then + done = true + break + elseif not start then + -- don't ask why ... shouldn't happen + break + end + end + else + report_missing_cache(typ,lookupname) + end + end + if start then start = start.next end + else + start = start.next + end + else + start = start.next + end + end + if done then + success = true + return head + end + end + + local function kerndisc(disc) -- we can assume that prev and next are glyphs + local prev = disc.prev + local next = disc.next + if prev and next then + prev.next = next + -- next.prev = prev + local a = prev[0] + if a then + a = (a == attr) and (not attribute or prev[a_state] == attribute) + else + a = not attribute or prev[a_state] == attribute + end + if a then + for i=1,ns do + local lookupname = subtables[i] + local lookupcache = lookuphash[lookupname] + if lookupcache then + local lookupmatch = lookupcache[prev.char] + if lookupmatch then + -- we could move all code inline but that makes things even more unreadable + local h, d, ok = handler(head,prev,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) + if ok then + done = true + break + end + end + else + report_missing_cache(typ,lookupname) + end + end + end + prev.next = disc + -- next.prev = disc + end + return next + end + + while start do + local id = start.id + if id == glyph_code then + if start.font == font and start.subtype<256 then + local a = start[0] + if a then + a = (a == attr) and (not attribute or start[a_state] == attribute) + else + a = not attribute or start[a_state] == attribute + end + if a then + for i=1,ns do + local lookupname = subtables[i] + local lookupcache = lookuphash[lookupname] + if lookupcache then + local lookupmatch = lookupcache[start.char] + if lookupmatch then + -- we could move all code inline but that makes things even more unreadable + local ok + head, start, ok = handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) + if ok then + success = true + break + elseif not start then + -- don't ask why ... shouldn't happen + break + end + end + else + report_missing_cache(typ,lookupname) + end + end + if start then start = start.next end + else + start = start.next + end + else + start = start.next + end + elseif id == disc_code then + -- mostly for gsub + if start.subtype == discretionary_code then + local pre = start.pre + if pre then + local new = subrun(pre) + if new then start.pre = new end + end + local post = start.post + if post then + local new = subrun(post) + if new then start.post = new end + end + local replace = start.replace + if replace then + local new = subrun(replace) + if new then start.replace = new end + end +elseif typ == "gpos_single" or typ == "gpos_pair" then + kerndisc(start) + end + start = start.next + elseif id == whatsit_code then + local subtype = start.subtype + if subtype == dir_code then + local dir = start.dir + if dir == "+TRT" or dir == "+TLT" then + topstack = topstack + 1 + dirstack[topstack] = dir + elseif dir == "-TRT" or dir == "-TLT" then + topstack = topstack - 1 + end + local newdir = dirstack[topstack] + if newdir == "+TRT" then + rlmode = -1 + elseif newdir == "+TLT" then + rlmode = 1 + else + rlmode = rlparmode + end + if trace_directions then + report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir) + end + elseif subtype == localpar_code then + local dir = start.dir + if dir == "TRT" then + rlparmode = -1 + elseif dir == "TLT" then + rlparmode = 1 + else + rlparmode = 0 + end + rlmode = rlparmode + if trace_directions then + report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode) + end + end + start = start.next + elseif id == math_code then + start = end_of_math(start).next + else + start = start.next + end + end + end + end + if success then + done = true + end + if trace_steps then -- ? + registerstep(head) + end + end + return head, done +end + +local function generic(lookupdata,lookupname,unicode,lookuphash) + local target = lookuphash[lookupname] + if target then + target[unicode] = lookupdata + else + lookuphash[lookupname] = { [unicode] = lookupdata } + end +end + +local action = { + + substitution = generic, + multiple = generic, + alternate = generic, + position = generic, + + ligature = function(lookupdata,lookupname,unicode,lookuphash) + local target = lookuphash[lookupname] + if not target then + target = { } + lookuphash[lookupname] = target + end + for i=1,#lookupdata do + local li = lookupdata[i] + local tu = target[li] + if not tu then + tu = { } + target[li] = tu + end + target = tu + end + target.ligature = unicode + end, + + pair = function(lookupdata,lookupname,unicode,lookuphash) + local target = lookuphash[lookupname] + if not target then + target = { } + lookuphash[lookupname] = target + end + local others = target[unicode] + local paired = lookupdata[1] + if others then + others[paired] = lookupdata + else + others = { [paired] = lookupdata } + target[unicode] = others + end + end, + +} + +local function prepare_lookups(tfmdata) + + local rawdata = tfmdata.shared.rawdata + local resources = rawdata.resources + local lookuphash = resources.lookuphash + local anchor_to_lookup = resources.anchor_to_lookup + local lookup_to_anchor = resources.lookup_to_anchor + local lookuptypes = resources.lookuptypes + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + + -- we cannot free the entries in the descriptions as sometimes we access + -- then directly (for instance anchors) ... selectively freeing does save + -- much memory as it's only a reference to a table and the slot in the + -- description hash is not freed anyway + + for unicode, character in next, characters do -- we cannot loop over descriptions ! + + local description = descriptions[unicode] + + if description then + + local lookups = description.slookups + if lookups then + for lookupname, lookupdata in next, lookups do + action[lookuptypes[lookupname]](lookupdata,lookupname,unicode,lookuphash) + end + end + + local lookups = description.mlookups + if lookups then + for lookupname, lookuplist in next, lookups do + local lookuptype = lookuptypes[lookupname] + for l=1,#lookuplist do + local lookupdata = lookuplist[l] + action[lookuptype](lookupdata,lookupname,unicode,lookuphash) + end + end + end + + local list = description.kerns + if list then + for lookup, krn in next, list do -- ref to glyph, saves lookup + local target = lookuphash[lookup] + if target then + target[unicode] = krn + else + lookuphash[lookup] = { [unicode] = krn } + end + end + end + + local list = description.anchors + if list then + for typ, anchors in next, list do -- types + if typ == "mark" or typ == "cexit" then -- or entry? + for name, anchor in next, anchors do + local lookups = anchor_to_lookup[name] + if lookups then + for lookup, _ in next, lookups do + local target = lookuphash[lookup] + if target then + target[unicode] = anchors + else + lookuphash[lookup] = { [unicode] = anchors } + end + end + end + end + end + end + end + + end + + end + +end + +local function split(replacement,original) + local result = { } + for i=1,#replacement do + result[original[i]] = replacement[i] + end + return result +end + +local valid = { + coverage = { chainsub = true, chainpos = true, contextsub = true }, + reversecoverage = { reversesub = true }, + glyphs = { chainsub = true, chainpos = true }, +} + +local function prepare_contextchains(tfmdata) + local rawdata = tfmdata.shared.rawdata + local resources = rawdata.resources + local lookuphash = resources.lookuphash + local lookups = rawdata.lookups + if lookups then + for lookupname, lookupdata in next, rawdata.lookups do + local lookuptype = lookupdata.type + if lookuptype then + local rules = lookupdata.rules + if rules then + local format = lookupdata.format + local validformat = valid[format] + if not validformat then + report_prepare("unsupported format %a",format) + elseif not validformat[lookuptype] then + -- todo: dejavu-serif has one (but i need to see what use it has) + report_prepare("unsupported format %a, lookuptype %a, lookupname %a",format,lookuptype,lookupname) + else + local contexts = lookuphash[lookupname] + if not contexts then + contexts = { } + lookuphash[lookupname] = contexts + end + local t, nt = { }, 0 + for nofrules=1,#rules do + local rule = rules[nofrules] + local current = rule.current + local before = rule.before + local after = rule.after + local replacements = rule.replacements + local sequence = { } + local nofsequences = 0 + -- Eventually we can store start, stop and sequence in the cached file + -- but then less sharing takes place so best not do that without a lot + -- of profiling so let's forget about it. + if before then + for n=1,#before do + nofsequences = nofsequences + 1 + sequence[nofsequences] = before[n] + end + end + local start = nofsequences + 1 + for n=1,#current do + nofsequences = nofsequences + 1 + sequence[nofsequences] = current[n] + end + local stop = nofsequences + if after then + for n=1,#after do + nofsequences = nofsequences + 1 + sequence[nofsequences] = after[n] + end + end + if sequence[1] then + -- Replacements only happen with reverse lookups as they are single only. We + -- could pack them into current (replacement value instead of true) and then + -- use sequence[start] instead but it's somewhat ugly. + nt = nt + 1 + t[nt] = { nofrules, lookuptype, sequence, start, stop, rule.lookups, replacements } + for unic, _ in next, sequence[start] do + local cu = contexts[unic] + if not cu then + contexts[unic] = t + end + end + end + end + end + else + -- no rules + end + else + report_prepare("missing lookuptype for lookupname %a",lookupname) + end + end + end +end + +-- we can consider lookuphash == false (initialized but empty) vs lookuphash == table + +local function featuresinitializer(tfmdata,value) + if true then -- value then + -- beware we need to use the topmost properties table + local rawdata = tfmdata.shared.rawdata + local properties = rawdata.properties + if not properties.initialized then + local starttime = trace_preparing and os.clock() + local resources = rawdata.resources + resources.lookuphash = resources.lookuphash or { } + prepare_contextchains(tfmdata) + prepare_lookups(tfmdata) + properties.initialized = true + if trace_preparing then + report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,tfmdata.properties.fullname) + end + end + end +end + +registerotffeature { + name = "features", + description = "features", + default = true, + initializers = { + position = 1, + node = featuresinitializer, + }, + processors = { + node = featuresprocessor, + } +} + +-- This can be used for extra handlers, but should be used with care! + +otf.handlers = handlers diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-legacy-attributes.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-legacy-attributes.lua deleted file mode 100644 index c6130b4f781..00000000000 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-legacy-attributes.lua +++ /dev/null @@ -1,27 +0,0 @@ ------------------------------------------------------------------------ --- FILE: otfl-luat-att.lua --- USAGE: with old luaotfload --- DESCRIPTION: setting attributes abide luatexbase rules --- REQUIREMENTS: some old luatex --- AUTHOR: Philipp Gesang (Phg), --- CREATED: 2013-05-10 20:37:19+0200 ------------------------------------------------------------------------ --- - -if not modules then modules = { } end modules ['otfl-luat-att'] = { - version = math.pi/42, - comment = "companion to luaotfload.lua", - author = "Philipp Gesang", - copyright = "Luaotfload Development Team", - license = "GNU GPL v2" -} - -function attributes.private(name) - local attr = "otfl@" .. name - local number = luatexbase.attributes[attr] - if not number then - number = luatexbase.new_attribute(attr) - end - return number -end - diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-legacy-database.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-legacy-database.lua deleted file mode 100644 index b31fe885264..00000000000 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-legacy-database.lua +++ /dev/null @@ -1,724 +0,0 @@ -if not modules then modules = { } end modules ['font-nms'] = { - version = "old", - comment = "companion to luaotfload.lua", - author = "Khaled Hosny and Elie Roux", - copyright = "Luaotfload Development Team", - license = "GNU GPL v2" -} - -fonts = fonts or { } -fonts.names = fonts.names or { } - -local names = fonts.names -local names_dir = "luatex-cache/generic/names" -names.version = "old" -- not the same as in context -names.data = nil -names.path = { - basename = "otfl-names.lua", --- different from current - localdir = file.join(kpse.expand_var("$TEXMFVAR"), names_dir), - systemdir = file.join(kpse.expand_var("$TEXMFSYSVAR"), names_dir), -} - - -local splitpath, expandpath = file.split_path, kpse.expand_path -local glob, basename = dir.glob, file.basename -local upper, lower, format = string.upper, string.lower, string.format -local gsub, match, rpadd = string.gsub, string.match, string.rpadd -local gmatch, sub, find = string.gmatch, string.sub, string.find -local utfgsub = unicode.utf8.gsub - -local trace_short = false --tracing adapted to rebuilding of the database inside a document -local trace_search = false --trackers.register("names.search", function(v) trace_search = v end) -local trace_loading = false --trackers.register("names.loading", function(v) trace_loading = v end) - -local function sanitize(str) - if str then - return utfgsub(lower(str), "[^%a%d]", "") - else - return str -- nil - end -end - -local function fontnames_init() - return { - mappings = { }, - status = { }, - version = names.version, - } -end - -local function load_names() - local localpath = file.join(names.path.localdir, names.path.basename) - local systempath = file.join(names.path.systemdir, names.path.basename) - local kpsefound = kpse.find_file(names.path.basename) - local foundname - local data - if kpsefound and file.isreadable(kpsefound) then - data = dofile(kpsefound) - foundname = kpsefound - elseif file.isreadable(localpath) then - data = dofile(localpath) - foundname = localpath - elseif file.isreadable(systempath) then - data = dofile(systempath) - foundname = systempath - end - if data then - logs.info("Font names database loaded: " .. foundname) - else - logs.info([[Font names database not found, generating new one. - This can take several minutes; please be patient.]]) - data = names.update(fontnames_init()) - names.save(data) - end - return data -end - -local synonyms = { - regular = { "normal", "roman", "plain", "book", "medium" }, - -- boldregular was for old versions of Linux Libertine, is it still useful? - -- semibold is in new versions of Linux Libertine, but there is also a bold, - -- not sure it's useful here... - bold = { "demi", "demibold", "semibold", "boldregular" }, - italic = { "regularitalic", "normalitalic", "oblique", "slanted" }, - bolditalic = { "boldoblique", "boldslanted", "demiitalic", "demioblique", "demislanted", "demibolditalic", "semibolditalic" }, -} - -local loaded = false -local reloaded = false - -function names.resolve(specification) - local name = sanitize(specification.name) - local style = sanitize(specification.style) or "regular" - - local size - if specification.optsize then - size = tonumber(specification.optsize) - elseif specification.size then - size = specification.size / 65536 - end - - - if not loaded then - names.data = names.load() - loaded = true - end - - local data = names.data - if type(data) == "table" and data.version == names.version then - if data.mappings then - local found = { } - for _,face in next, data.mappings do - local family, subfamily, fullname, psname - local optsize, dsnsize, maxsize, minsize - - if face.names then - family = sanitize(face.names.family) - subfamily = sanitize(face.names.subfamily) - fullname = sanitize(face.names.fullname) - psname = sanitize(face.names.psname) - end - local fontname = sanitize(face.fontname) - local pfullname = sanitize(face.fullname) - if #face.size > 0 then - optsize = face.size - dsnsize = optsize[1] and optsize[1] / 10 - -- can be nil - maxsize = optsize[2] and optsize[2] / 10 or dsnsize - minsize = optsize[3] and optsize[3] / 10 or dsnsize - end - if name == family then - if subfamily == style then - if optsize then - if dsnsize == size - or (size > minsize and size <= maxsize) then - found[1] = face - break - else - found[#found+1] = face - end - else - found[1] = face - break - end - elseif synonyms[style] and - table.contains(synonyms[style], subfamily) then - if optsize then - if dsnsize == size - or (size > minsize and size <= maxsize) then - found[1] = face - break - else - found[#found+1] = face - end - else - found[1] = face - break - end - elseif subfamily == "regular" or - table.contains(synonyms.regular, subfamily) then - found.fallback = face - elseif name == fullname - or name == pfullname - or name == fontname - or name == psname then - if optsize then - if dsnsize == size - or (size > minsize and size <= maxsize) then - found[1] = face - break - else - found[#found+1] = face - end - else - found[1] = face - break - end - end - else - if name == fullname - or name == pfullname - or name == fontname - or name == psname then - if optsize then - if dsnsize == size - or (size > minsize and size <= maxsize) then - found[1] = face - break - else - found[#found+1] = face - end - else - found[1] = face - break - end - end - end - end - if #found == 1 then - if kpse.lookup(found[1].filename[1]) then - logs.report("load font", - "font family='%s', subfamily='%s' found: %s", - name, style, found[1].filename[1]) - return found[1].filename[1], found[1].filename[2] - elseif lfs.isfile(found[1].found_at) then - logs.report("load font", - "font family='%s', subfamily='%s' found: %s", - name, style, found[1].found_at) - return found[1].found_at, found[1].filename[2] - end - elseif #found > 1 then - -- we found matching font(s) but not in the requested optical - -- sizes, so we loop through the matches to find the one with - -- least difference from the requested size. - local closest - local least = math.huge -- initial value is infinity - for i,face in next, found do - local dsnsize = face.size[1]/10 - local difference = math.abs(dsnsize-size) - if difference < least then - closest = face - least = difference - end - end - if kpse.lookup(closest.filename[1]) then - logs.report("load font", - "font family='%s', subfamily='%s' found: %s", - name, style, closest.filename[1]) - return closest.filename[1], closest.filename[2] - elseif lfs.isfile(closest.found_at) then - logs.report("load font", - "font family='%s', subfamily='%s' found: %s", - name, style, closest.found_at) - return closest.found_at, closest.filename[2] - end - elseif found.fallback then - return found.fallback.filename[1], found.fallback.filename[2] - end - -- no font found so far - if not reloaded then - -- try reloading the database - names.data = names.update(names.data) - names.save(names.data) - reloaded = true - return names.resolve(specification) - else - -- else, fallback to filename - return specification.name, false - end - end - else - if not reloaded then - names.data = names.update() - names.save(names.data) - reloaded = true - return names.resolve(specification) - else - return specification.name, false - end - end -end - -names.resolvespec = names.resolve - -function names.set_log_level(level) - if level == 2 then - trace_loading = true - elseif level >= 3 then - trace_loading = true - trace_search = true - end -end - -local lastislog = 0 - -local function log(fmt, ...) - lastislog = 1 - texio.write_nl(format("luaotfload | %s", format(fmt,...))) - io.flush() -end - -logs = logs or { } -logs.report = logs.report or log -logs.info = logs.info or log - -local function font_fullinfo(filename, subfont, texmf) - local found_at = filename - local t = { } - local f = fontloader.open(filename, subfont) - if not f then - if trace_loading then - logs.report("error: failed to open %s", filename) - end - return - end - local m = fontloader.to_table(f) - fontloader.close(f) - collectgarbage('collect') - -- see http://www.microsoft.com/typography/OTSPEC/features_pt.htm#size - if m.fontstyle_name then - for _,v in next, m.fontstyle_name do - if v.lang == 1033 then - t.fontstyle_name = v.name - end - end - end - if m.names then - for _,v in next, m.names do - if v.lang == "English (US)" then - t.names = { - -- see - -- http://developer.apple.com/textfonts/ - -- TTRefMan/RM06/Chap6name.html - fullname = v.names.compatfull or v.names.fullname, - family = v.names.preffamilyname or v.names.family, - subfamily= t.fontstyle_name or v.names.prefmodifiers or v.names.subfamily, - psname = v.names.postscriptname - } - end - end - else - -- no names table, propably a broken font - if trace_loading then - logs.report("broken font rejected: %s", basefile) - end - return - end - t.fontname = m.fontname - t.fullname = m.fullname - t.familyname = m.familyname - t.filename = { texmf and basename(filename) or filename, subfont } - t.weight = m.pfminfo.weight - t.width = m.pfminfo.width - t.slant = m.italicangle - -- don't waste the space with zero values - t.size = { - m.design_size ~= 0 and m.design_size or nil, - m.design_range_top ~= 0 and m.design_range_top or nil, - m.design_range_bottom ~= 0 and m.design_range_bottom or nil, - } - -- rather, waste space on paths - t.found_at = found_at - return t -end - -local function load_font(filename, fontnames, newfontnames, texmf) - local newmappings = newfontnames.mappings - local newstatus = newfontnames.status - local mappings = fontnames.mappings - local status = fontnames.status - local basefile = texmf and basename(filename) or filename - if filename then - if table.contains(names.blacklist, filename) or - table.contains(names.blacklist, basename(filename)) then - if trace_search then - logs.report("ignoring font '%s'", filename) - end - return - end - local timestamp, db_timestamp - db_timestamp = status[basefile] and status[basefile].timestamp - timestamp = lfs.attributes(filename, "modification") - - local index_status = newstatus[basefile] or (not texmf and newstatus[basename(filename)]) - if index_status and index_status.timestamp == timestamp then - -- already indexed this run - return - end - - newstatus[basefile] = newstatus[basefile] or { } - newstatus[basefile].timestamp = timestamp - newstatus[basefile].index = newstatus[basefile].index or { } - - if db_timestamp == timestamp and not newstatus[basefile].index[1] then - for _,v in next, status[basefile].index do - local index = #newstatus[basefile].index - newmappings[#newmappings+1] = mappings[v] - newstatus[basefile].index[index+1] = #newmappings - end - if trace_loading then - logs.report("font already indexed: %s", basefile) - end - return - end - local info = fontloader.info(filename) - if info then - if type(info) == "table" and #info > 1 then - for i in next, info do - local fullinfo = font_fullinfo(filename, i-1, texmf) - if not fullinfo then - return - end - local index = newstatus[basefile].index[i] - if not index then - index = #newmappings+1 - end - newmappings[index] = fullinfo - newstatus[basefile].index[i] = index - end - else - local fullinfo = font_fullinfo(filename, false, texmf) - if not fullinfo then - return - end - local index = newstatus[basefile].index[1] - if not index then - index = #newmappings+1 - end - newmappings[index] = fullinfo - newstatus[basefile].index[1] = index - end - else - if trace_loading then - logs.report("failed to load %s", basefile) - end - end - end -end - -local function path_normalize(path) - --[[ - path normalization: - - a\b\c -> a/b/c - - a/../b -> b - - /cygdrive/a/b -> a:/b - - reading symlinks under non-Win32 - - using kpse.readable_file on Win32 - ]] - if os.type == "windows" or os.type == "msdos" then - path = path:gsub('\\', '/') - path = path:lower() - path = path:gsub('^/cygdrive/(%a)/', '%1:/') - end - if os.type ~= "windows" and os.type ~= "msdos" then - local dest = lfs.readlink(path) - if dest then - if kpse.readable_file(dest) then - path = dest - elseif kpse.readable_file(file.join(file.dirname(path), dest)) then - path = file.join(file.dirname(path), dest) - else - -- broken symlink? - end - end - end - path = file.collapse_path(path) - return path -end - -fonts.path_normalize = path_normalize - -names.blacklist = { } - -local function read_blacklist() - local files = { - kpse.lookup("otfl-blacklist.cnf", {all=true, format="tex"}) - } - local blacklist = names.blacklist - - if files and type(files) == "table" then - for _,v in next, files do - for line in io.lines(v) do - line = line:strip() -- to get rid of lines like " % foo" - if line:find("^%%") or line:is_empty() then - -- comment or empty line - else - line = line:split("%")[1] - line = line:strip() - if trace_search then - logs.report("blacklisted file: %s", line) - end - blacklist[#blacklist+1] = line - end - end - end - end -end - -local font_extensions = { "otf", "ttf", "ttc", "dfont" } - -local function scan_dir(dirname, fontnames, newfontnames, texmf) - --[[ - This function scans a directory and populates the list of fonts - with all the fonts it finds. - - dirname is the name of the directory to scan - - names is the font database to fill - - texmf is a boolean saying if we are scanning a texmf directory - ]] - local list, found = { }, { } - local nbfound = 0 - if trace_search then - logs.report("scanning '%s'", dirname) - end - for _,i in next, font_extensions do - for _,ext in next, { i, upper(i) } do - found = glob(format("%s/**.%s$", dirname, ext)) - -- note that glob fails silently on broken symlinks, which happens - -- sometimes in TeX Live. - if trace_search then - logs.report("%s '%s' fonts found", #found, ext) - end - nbfound = nbfound + #found - table.append(list, found) - end - end - if trace_search then - logs.report("%d fonts found in '%s'", nbfound, dirname) - end - - for _,file in next, list do - file = path_normalize(file) - if trace_loading then - logs.report("loading font: %s", file) - end - load_font(file, fontnames, newfontnames, texmf) - end -end - -local function scan_texmf_fonts(fontnames, newfontnames) - --[[ - This function scans all fonts in the texmf tree, through kpathsea - variables OPENTYPEFONTS and TTFONTS of texmf.cnf - ]] - if expandpath("$OSFONTDIR"):is_empty() then - logs.info("Scanning TEXMF fonts...") - else - logs.info("Scanning TEXMF and OS fonts...") - end - local fontdirs = expandpath("$OPENTYPEFONTS"):gsub("^%.", "") - fontdirs = fontdirs .. expandpath("$TTFONTS"):gsub("^%.", "") - if not fontdirs:is_empty() then - for _,d in next, splitpath(fontdirs) do - scan_dir(d, fontnames, newfontnames, true) - end - end -end - ---[[ - For the OS fonts, there are several options: - - if OSFONTDIR is set (which is the case under windows by default but - not on the other OSs), it scans it at the same time as the texmf tree, - in the scan_texmf_fonts. - - in addition: - - under Windows and Mac OSX, we take a look at some hardcoded directories - - under Unix, we read /etc/fonts/fonts.conf and read the directories in it - - This means that if you have fonts in fancy directories, you need to set them - in OSFONTDIR if they cannot be found by fontconfig. -]] - -local function read_fonts_conf(path, results, passed_paths) - --[[ - This function parses /etc/fonts/fonts.conf and returns all the dir it finds. - The code is minimal, please report any error it may generate. - ]] - local f = io.open(path) - table.insert(passed_paths, path) - if not f then - logs.info("Warning: unable to read "..path.. ", skipping...") - return results - end - local incomments = false - for line in f:lines() do - while line and line ~= "" do - -- spaghetti code... hmmm... - if incomments then - local tmp = find(line, '-->') - if tmp then - incomments = false - line = sub(line, tmp+3) - else - line = nil - end - else - local tmp = find(line, ' since 2014-01-07, replaces node-inj.lua + loadmodule('font-ota.lua') + loadmodule('luatex-fonts-otn.lua') --> since 2014-01-07, replaces font-otn.lua + loadmodule('font-otp.lua') --> since 2013-04-23 + loadmodule('luatex-fonts-lua.lua') + loadmodule('font-def.lua') + loadmodule('luatex-fonts-def.lua') + loadmodule('luatex-fonts-ext.lua') + loadmodule('luatex-fonts-cbk.lua') +end --- non-merge fallback scope + +--[[doc-- + + Here we adjust the globals created during font loader + initialization. If the second argument to + \luafunction{pop_namespaces()} is \verb|true| this will restore the + state of \luafunction{_G}, eliminating every global generated since + the last call to \luafunction{push_namespaces()}. At the moment we + see no reason to do this, and since the font loader is considered + an essential part of \identifier{luatex} as well as a very well + organized piece of code, we happily concede it the right to add to + \luafunction{_G} if needed. + +--doc]]-- + +pop_namespaces(our_environment, false)-- true) + +logreport ("both", 0, "main", + "fontloader loaded in %0.3f seconds", os.gettimeofday()-starttime) + +--[[doc-- + + \subsection{Callbacks} + After the fontloader is ready we can restore the callback trap from + \identifier{luatexbase}. + +--doc]]-- + +callback.register = trapped_register + +--[[doc-- + + We do our own callback handling with the means provided by + luatexbase. + Note: \luafunction{pre_linebreak_filter} and + \luafunction{hpack_filter} are coupled in \CONTEXT in the concept + of \emphasis{node processor}. + +--doc]]-- + +add_to_callback("pre_linebreak_filter", + nodes.simple_font_handler, + "luaotfload.node_processor", + 1) +add_to_callback("hpack_filter", + nodes.simple_font_handler, + "luaotfload.node_processor", + 1) +add_to_callback("find_vf_file", + find_vf_file, "luaotfload.find_vf_file") + +loadmodule "override.lua" --- load glyphlist on demand + +--[[doc-- + + Now we load the modules written for \identifier{luaotfload}. + +--doc]]-- + +loadmodule "parsers.lua" --- fonts.conf and syntax +loadmodule "configuration.lua" --- configuration options + +if not config.actions.apply_defaults () then + logreport ("log", 0, "load", "Configuration unsuccessful.") +end + +loadmodule "loaders.lua" --- Type1 font wrappers +loadmodule "database.lua" --- Font management. +loadmodule "colors.lua" --- Per-font colors. + +if not config.actions.reconfigure () then + logreport ("log", 0, "load", "Post-configuration hooks failed.") +end + +--[[doc-- + + Relying on the \verb|name:| resolver for everything has been the + source of permanent trouble with the database. + With the introduction of the new syntax parser we now have enough + granularity to distinguish between the \XETEX emulation layer and + the genuine \verb|name:| and \verb|file:| lookups of \LUATEX-Fonts. + Another benefit is that we can now easily plug in or replace new + lookup behaviors if necessary. + The name resolver remains untouched, but it calls + \luafunction{fonts.names.resolve()} internally anyways (see + \fileent{luaotfload-database.lua}). + +--doc]]-- + +local filesuffix = file.suffix +local fileremovesuffix = file.removesuffix +local request_resolvers = fonts.definers.resolvers +local formats = fonts.formats +local names = fonts.names +formats.ofm = "type1" + +fonts.encodings.known = fonts.encodings.known or { } + +--[[doc-- + + \identifier{luaotfload} promises easy access to system fonts. + Without additional precautions, this cannot be achieved by + \identifier{kpathsea} alone, because it searches only the + \fileent{texmf} directories by default. + Although it is possible for \identifier{kpathsea} to include extra + paths by adding them to the \verb|OSFONTDIR| environment variable, + this is still short of the goal »\emphasis{it just works!}«. + When building the font database \identifier{luaotfload} scans + system font directories anyways, so we already have all the + information for looking sytem fonts. + With the release version 2.2 the file names are indexed in the + database as well and we are ready to resolve \verb|file:| lookups + this way. + Thus we no longer need to call the \identifier{kpathsea} library in + most cases when looking up font files, only when generating the + database, and when verifying the existence of a file in the + \fileent{texmf} tree. + +--doc]]-- + +local resolve_file = names.font_file_lookup + +local file_resolver = function (specification) + local name = resolve_file (specification.name) + local suffix = filesuffix(name) + if formats[suffix] then + specification.forced = stringlower (suffix) + specification.forcedname = file.removesuffix(name) + else + specification.name = name + end +end + +request_resolvers.file = file_resolver + +--[[doc-- + + We classify as \verb|anon:| those requests that have neither a + prefix nor brackets. According to Khaled\footnote{% + \url{https://github.com/phi-gamma/luaotfload/issues/4#issuecomment-17090553}. + } + they are the \XETEX equivalent of a \verb|name:| request, so we + will be treating them as such. + +--doc]]-- + +--request_resolvers.anon = request_resolvers.name + +--[[doc-- + + There is one drawback, though. + This syntax is also used for requesting fonts in \identifier{Type1} + (\abbrev{tfm}, \abbrev{ofm}) format. + These are essentially \verb|file:| lookups and must be caught + before the \verb|name:| resolver kicks in, lest they cause the + database to update. + Even if we were to require the \verb|file:| prefix for all + \identifier{Type1} requests, tests have shown that certain fonts + still include further fonts (e.~g. \fileent{omlgcb.ofm} will ask + for \fileent{omsecob.tfm}) \emphasis{using the old syntax}. + For this reason, we introduce an extra check with an early return. + +--doc]]-- + +local type1_formats = { "tfm", "ofm", "TFM", "OFM", } + +request_resolvers.anon = function (specification) + local name = specification.name + for i=1, #type1_formats do + local format = type1_formats[i] + if resolvers.findfile(name, format) then + specification.forcedname = file.addsuffix(name, format) + specification.forced = format + return + end + end + --- under some weird circumstances absolute paths get + --- passed to the definer; we have to catch them + --- before the name: resolver misinterprets them. + name = specification.specification + local exists, _ = lfsisfile(name) + if exists then --- garbage; we do this because we are nice, + --- not because it is correct + logreport ("log", 1, "load", "file %q exists", name) + logreport ("log", 1, "load", + "... overriding borked anon: lookup with path: lookup") + specification.name = name + request_resolvers.path(specification) + return + end + request_resolvers.name(specification) +end + +--[[doc-- + + Prior to version 2.2, \identifier{luaotfload} did not distinguish + \verb|file:| and \verb|path:| lookups, causing complications with + the resolver. + Now we test if the requested name is an absolute path in the file + system, otherwise we fall back to the \verb|file:| lookup. + +--doc]]-- + +request_resolvers.path = function (specification) + local name = specification.name + local exists, _ = lfsisfile(name) + if not exists then -- resort to file: lookup + logreport ("log", 0, "load", + "path lookup of %q unsuccessful, falling back to file:", + name) + file_resolver (specification) + else + local suffix = filesuffix (name) + if formats[suffix] then + specification.forced = stringlower (suffix) + specification.name = file.removesuffix(name) + specification.forcedname = name + else + specification.name = name + end + end +end + +--[[doc-- + + {\bfseries EXPERIMENTAL}: + \identifier{kpse}-only resolver, for those who can do without + system fonts. + +--doc]]-- + +request_resolvers.kpse = function (specification) + local name = specification.name + local suffix = filesuffix(name) + if suffix and formats[suffix] then + name = file.removesuffix(name) + if resolvers.findfile(name, suffix) then + specification.forced = stringlower (suffix) + specification.forcedname = name + return + end + end + for t, format in next, formats do --- brute force + if kpse.find_file (name, format) then + specification.forced = t + specification.name = name + return + end + end +end + +--[[doc-- + + The \verb|name:| resolver. + +--doc]]-- + +--- fonts.names.resolvers.name -- Customized version of the +--- generic name resolver. + +request_resolvers.name = function (specification) + local resolver = names.resolve_cached + if config.luaotfload.run.resolver == "normal" then + resolver = names.resolve_name + end + local resolved, subfont = resolver (specification) + if resolved then + logreport ("log", 0, "load", "Lookup/name: %q -> \"%s%s\"", + specification.name, + resolved, + subfont and stringformat ("(%d)", subfont) or "") + specification.resolved = resolved + specification.sub = subfont + specification.forced = stringlower (filesuffix (resolved) or "") + specification.forcedname = resolved + specification.name = fileremovesuffix (resolved) + else + file_resolver (specification) + end +end + +--[[doc-- + + Also {\bfseries EXPERIMENTAL}: custom file resolvers via callback. + +--doc]]-- +create_callback("luaotfload.resolve_font", "simple", dummy_function) + +request_resolvers.my = function (specification) + call_callback("luaotfload.resolve_font", specification) +end + +--[[doc-- + + We create a callback for patching fonts on the fly, to be used by + other packages. + It initially contains the empty function that we are going to + override below. + +--doc]]-- + +create_callback("luaotfload.patch_font", "simple", dummy_function) + +--[[doc-- + + \subsection{\CONTEXT override} + \label{define-font} + We provide a simplified version of the original font definition + callback. + +--doc]]-- + +local read_font_file = fonts.definers.read + +local definers = { + generic = read_font_file, + --- spec -> size -> id -> tmfdata + patch = function (specification, size, id) + local tfmdata = read_font_file (specification, size, id) + if type (tfmdata) == "table" and tfmdata.shared then + --- We need to test for the “shared” field here + --- or else the fontspec capheight callback will + --- operate on tfm fonts. + call_callback ("luaotfload.patch_font", tfmdata, specification) + end + return tfmdata + end, +} + +reset_callback "define_font" + +--[[doc-- + + Finally we register the callbacks. + +--doc]]-- + +local definer = config.luaotfload.run.definer +add_to_callback ("define_font", definers[definer], "luaotfload.define_font", 1) + +loadmodule "features.lua" --- font request and feature handling +loadmodule "letterspace.lua" --- extra character kerning +loadmodule "auxiliary.lua" --- additional high-level functionality + +luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec + +-- vim:tw=79:sw=4:ts=4:et diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-override.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-override.lua index fe70dcb4209..b75530b5cdf 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-override.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-override.lua @@ -1,360 +1,16 @@ -if not modules then modules = { } end modules ['luat-ovr'] = { - version = "2.4", - comment = "companion to luatex-*.tex", +if not modules then modules = { } end modules ["luaotfload-override"] = { + version = "2.5", + comment = "companion to Luaotfload", author = "Khaled Hosny, Elie Roux, Philipp Gesang", copyright = "Luaotfload Development Team", - license = "GNU GPL v2" + license = "GNU GPL v2.0" } ---[[doc-- -The logging system is slow in general, as we always have the function -call overhead even if we aren’t going to output anything. On the other -hand, the more efficient approach followed by Context isn’t an option -because we lack a user interface to toggle per-subsystem tracing. ---doc]]-- - -local module_name = "luaotfload" - -local ioopen = io.open -local iowrite = io.write -local lfsisdir = lfs.isdir -local lfsisfile = lfs.isfile -local md5sumhexa = md5.sumhexa -local osdate = os.date -local ostime = os.time -local select = select -local stringformat = string.format -local stringsub = string.sub -local tableconcat = table.concat -local texio_write_nl = texio.write_nl -local texiowrite_nl = texio.write_nl -local texio_write = texio.write -local texiowrite = texio.write -local type = type - -local dummyfunction = function () end - -local texjob = false -if tex and (tex.jobname or tex.formatname) then - --- TeX - texjob = true -end - -local loglevel = 0 --- default -local logout = "log" - ---- int -> bool -local set_loglevel = function (n) - if type(n) == "number" then - loglevel = n - end - return true -end -logs.setloglevel = set_loglevel -logs.set_loglevel = set_loglevel -logs.set_log_level = set_loglevel --- accomodating lazy typists - ---- unit -> int -local get_loglevel = function ( ) - return loglevel -end -logs.getloglevel = get_loglevel -logs.get_loglevel = get_loglevel -logs.get_log_level = get_loglevel - -local writeln --- pointer to terminal/log writer -local statusln --- terminal writer that reuses the current line -local first_status = true --- indicate the begin of a status region - -local log_msg = [[ -logging output redirected to %s -to monitor the progress run "tail -f %s" in another terminal -]] - -local tmppath = os.getenv "TMPDIR" or "/tmp" - -local choose_logfile = function ( ) - if lfsisdir (tmppath) then - local fname - repeat --- ensure that file of that name doesn’t exist - fname = tmppath .. "/luaotfload-log-" - .. stringsub (md5sumhexa (ostime ()), 1, 8) - until not lfsisfile (fname) - iowrite (stringformat (log_msg, fname, fname)) - return ioopen (fname, "w") - end - --- missing /tmp - return false -end - -local set_logout = function (s, finalizers) - if s == "stdout" then - logout = "redirect" - elseif s == "file" then --- inject custom logger - logout = "redirect" - local chan = choose_logfile () - chan:write (stringformat ("logging initiated at %s", - osdate ("%F %T", ostime ()))) - local writefile = function (...) - if select ("#", ...) == 2 then - chan:write (select (2, ...)) - else - chan:write (select (1, ...)) - end - end - local writefile_nl= function (...) - chan:write "\n" - if select ("#", ...) == 2 then - chan:write (select (2, ...)) - else - chan:write (select (1, ...)) - end - end - - local writeln_orig = writeln - - texiowrite = writefile - texiowrite_nl = writefile_nl - writeln = writefile_nl - statusln = dummyfunction - - finalizers[#finalizers+1] = function () - chan:write (stringformat ("\nlogging finished at %s\n", - osdate ("%F %T", ostime ()))) - chan:close () - texiowrite = texio.write - texiowrite_nl = texio.write_nl - writeln = writeln_orig - end - --else --- remains “log” - end - return finalizers -end - -logs.set_logout = set_logout - -local log = function (category, fmt, ...) - local res = { module_name, "|", category, ":" } - if fmt then - res [#res + 1] = stringformat (fmt, ...) - end - texiowrite_nl (logout, tableconcat(res, " ")) -end - ---- with faux db update with maximum verbosity: ---- ---- --------- -------- ---- buffering time (s) ---- --------- -------- ---- full 4.12 ---- line 4.20 ---- none 4.39 ---- --------- -------- ---- - -io.stdout:setvbuf "no" -io.stderr:setvbuf "no" - -local kill_line = "\r\x1b[K" - -if texjob == true then - --- We imitate the texio.* functions so the output is consistent. - writeln = function (str) - iowrite "\n" - iowrite(str) - end - statusln = function (str) - if first_status == false then - iowrite (kill_line) - else - iowrite "\n" - end - iowrite (str) - end -else - writeln = function (str) - iowrite(str) - iowrite "\n" - end - statusln = function (str) - if first_status == false then - iowrite (kill_line) - end - iowrite (str) - end -end - -stdout = function (writer, category, ...) - local res = { module_name, "|", category, ":" } - local nargs = select("#", ...) - if nargs == 0 then - --writeln tableconcat(res, " ") - --return - elseif nargs == 1 then - res[#res+1] = select(1, ...) -- around 30% faster than unpack() - else - res[#res+1] = stringformat(...) - end - writer (tableconcat(res, " ")) -end - ---- at default (zero), we aim to be quiet -local level_ids = { common = 1, loading = 2, search = 3 } - ---[[doc-- - - The names_report logger is used more or less all over luaotfload. - Its requirements are twofold: - - 1) Provide two logging channels, the terminal and the log file; - 2) Allow for control over verbosity levels. - - The first part is addressed by specifying the log *mode* as the - first argument that can be either “log”, meaning the log file, or - “both”: log file and stdout. Anything else is taken as referring to - stdout only. - - Verbosity levels, though not as fine-grained as e.g. Context’s - system of tracers, allow keeping the logging spam caused by - different subsystems manageable. By default, luaotfload will not - emit anything if things are running smoothly on level zero. Only - warning messages are relayed, while the other messages are skipped - over. (This is a little sub-optimal performance-wise since the - function calls to the logger are executed regardless.) The log - level during a Luatex run can be adjusted by setting the “loglevel” - field in config.luaotfload, or by calling logs.set_loglevel() as - defined above. - ---doc]]-- - -local names_report = function (mode, lvl, ...) - if type(lvl) == "string" then - lvl = level_ids[lvl] - end - if not lvl then lvl = 0 end - - if loglevel >= lvl then - if mode == "log" then - log (...) - elseif mode == "both" and logout ~= "redirect" then - log (...) - stdout (writeln, ...) - else - stdout (writeln, ...) - end - end -end - -logs.names_report = names_report - ---[[doc-- - - status_logger -- Overwrites the most recently printed line of the - terminal. Its purpose is to provide feedback without spamming - stdout with irrelevant messages, i.e. when building the database. - - Status logging must be initialized by calling status_start() and - properly reset via status_stop(). - - The arguments low and high indicate the loglevel threshold at which - linewise and full logging is triggered, respectively. E.g. - - names_status (1, 4, "term", "Hello, world!") - - will print nothing if the loglevel is less than one, reuse the - current line if the loglevel ranges from one to three inclusively, - and output the message on a separate line otherwise. - ---doc]]-- - -local status_logger = function (mode, ...) - if mode == "log" then - log (...) - else - if mode == "both" and logout ~= "redirect" then - log (...) - stdout (statusln, ...) - else - stdout (statusln, ...) - end - first_status = false - end -end - ---[[doc-- - - status_start -- Initialize status logging. This installs the status - logger if the loglevel is in the specified range, and the normal - logger otherwise. It also resets the first line state which - causing the next line printed using the status logger to not kill - the current line. - ---doc]]-- - -local status_writer -local status_low = 99 -local status_high = 99 - -local status_start = function (low, high) - first_status = true - status_low = low - status_high = high - - if os.type == "windows" --- Assume broken terminal. - or os.getenv "TERM" == "dumb" - then - status_writer = function (mode, ...) - names_report (mode, high, ...) - end - return - end +local findfile = resolvers.findfile +local encodings = fonts.encodings - if low <= loglevel and loglevel < high then - status_writer = status_logger - else - status_writer = function (mode, ...) - names_report (mode, high, ...) - end - end -end - ---[[doc-- - - status_stop -- Finalize a status region by outputting a newline and - printing a message. - ---doc]]-- - -local status_stop = function (...) - if first_status == false then - status_writer(...) - if texjob == false then - writeln "" - end - end -end - -logs.names_status = function (...) status_writer (...) end -logs.names_status_start = status_start -logs.names_status_stop = status_stop - ---[[doc-- - - The fontloader comes with the Context logging mechanisms - inaccessible. Instead, it provides dumb fallbacks based - on the functions in texio.write*() that can be overridden - by providing a function texio.reporter(). - - The fontloader output can be quite verbose, so we disable - it entirely by default. - ---doc]]-- - -local texioreporter = function (message) - names_report("log", 2, message) -end - -texio.reporter = texioreporter +local log = luaotfload.log +local report = log.report --[[doc-- @@ -374,34 +30,23 @@ texio.reporter = texioreporter --doc]]-- -if fonts then --- need to be running TeX - if next(fonts.encodings.agl) then - --- unnecessary because the file shouldn’t be loaded at this time - --- but we’re just making sure - fonts.encodings.agl = nil - collectgarbage"collect" - end - - - fonts.encodings.agl = { } +encodings.agl = { } - setmetatable(fonts.encodings.agl, { __index = function (t, k) - if k == "unicodes" then - local glyphlist = resolvers.findfile"luaotfload-glyphlist.lua" - if glyphlist then - names_report("log", 1, "load", "loading the Adobe glyph list") - else - glyphlist = resolvers.findfile"font-age.lua" - names_report("both", 0, "load", - "loading the extended glyph list from ConTeXt") - end - local unicodes = dofile(glyphlist) - fonts.encodings.agl = { unicodes = unicodes } - return unicodes - else - return nil - end - end }) -end +setmetatable(fonts.encodings.agl, { __index = function (t, k) + if k ~= "unicodes" then + return nil + end + local glyphlist = findfile "luaotfload-glyphlist.lua" + if glyphlist then + report ("log", 1, "load", "loading the Adobe glyph list") + else + glyphlist = findfile "font-age.lua" + report ("both", 0, "load", + "loading the extended glyph list from ConTeXt") + end + local unicodes = dofile(glyphlist) + encodings.agl = { unicodes = unicodes } + return unicodes +end }) -- vim:tw=71:sw=4:ts=4:expandtab diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua new file mode 100644 index 00000000000..3eeb614a202 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua @@ -0,0 +1,701 @@ +#!/usr/bin/env texlua +------------------------------------------------------------------------------- +-- FILE: luaotfload-parsers.lua +-- DESCRIPTION: various lpeg-based parsers used in Luaotfload +-- REQUIREMENTS: Luaotfload > 2.4 +-- AUTHOR: Philipp Gesang (Phg), +-- VERSION: same as Luaotfload +-- CREATED: 2014-01-14 10:15:20+0100 +------------------------------------------------------------------------------- +-- + +if not modules then modules = { } end modules ['luaotfload-parsers'] = { + version = "2.5", + comment = "companion to luaotfload-main.lua", + author = "Philipp Gesang", + copyright = "Luaotfload Development Team", + license = "GNU GPL v2.0" +} + +luaotfload = luaotfload or { } +luaotfload.parsers = luaotfload.parsers or { } +local parsers = luaotfload.parsers + +local rawset = rawset + +local lpeg = require "lpeg" +local P, R, S = lpeg.P, lpeg.R, lpeg.S +local lpegmatch = lpeg.match +local C, Cc, Cf = lpeg.C, lpeg.Cc, lpeg.Cf +local Cg, Cmt, Cs, Ct = lpeg.Cg, lpeg.Cmt, lpeg.Cs, lpeg.Ct + +local kpse = kpse +local kpseexpand_path = kpse.expand_path +local kpsereadable_file = kpse.readable_file + +local file = file +local filejoin = file.join +local filedirname = file.dirname + +local io = io +local ioopen = io.open + +local log = luaotfload.log +local logreport = log.report + +local string = string +local stringsub = string.sub +local stringfind = string.find +local stringlower = string.lower + +local mathceil = math.ceil + +local lfs = lfs +local lfsisfile = lfs.isfile +local lfsisdir = lfs.isdir + +------------------------------------------------------------------------------- +--- COMMON PATTERNS +------------------------------------------------------------------------------- + +local dot = P"." +local colon = P":" +local semicolon = P";" +local comma = P"," +local noncomma = 1 - comma +local slash = P"/" +local backslash = P"\\" +local equals = P"=" +local dash = P"-" +local gartenzaun = P"#" +local lbrk, rbrk = P"[", P"]" +local squote = P"'" +local dquote = P"\"" + +local newline = P"\n" +local returnchar = P"\r" +local spacing = S" \t\v" +local linebreak = S"\n\r" +local whitespace = spacing + linebreak +local ws = spacing^0 +local xmlws = whitespace^1 +local eol = P"\n\r" + P"\r\n" + linebreak + +local digit = R"09" +local alpha = R("az", "AZ") +local anum = alpha + digit +local decimal = digit^1 * (dot * digit^0)^-1 + +------------------------------------------------------------------------------- +--- FONTCONFIG +------------------------------------------------------------------------------- + +--[[doc-- + + For fonts installed on the operating system, there are several + options to make Luaotfload index them: + + - If OSFONTDIR is set (which is the case under windows by default + but not on the other OSs), it scans it at the same time as the + texmf tree, in the function scan_texmf_fonts(). + + - Otherwise + - under Windows and Mac OSX, we take a look at some hardcoded + directories, + - under Unix, it reads /etc/fonts/fonts.conf and processes the + directories specified there. + + This means that if you have fonts in fancy directories, you need to + set them in OSFONTDIR. + + Beware: OSFONTDIR is a kpathsea variable, so fonts found in these + paths, though technically system fonts, are registered in the + category “texmf”, not “system”. This may have consequences for the + lookup order when a font file (or a font with the same name + information) is located in both the system and the texmf tree. + +--doc]]-- + +local tag_name = C(alpha^1) +local comment = P"" + +---> header specifica +local xml_declaration = P"")^0 * P"?>" +local xml_doctype = P"")^0 * P">" +local header = xml_declaration^-1 + * (xml_doctype + comment + xmlws)^0 + +---> enforce root node +local root_start = P"<" * xmlws^-1 * P"fontconfig" * xmlws^-1 * P">" +local root_stop = P"" + +local dquote, squote = P[["]], P"'" +local xml_namestartchar = S":_" + alpha --- ascii only, funk the rest +local xml_namechar = S":._" + alpha + digit +local xml_name = xmlws^-1 + * C(xml_namestartchar * xml_namechar^0) +local xml_attvalue = dquote * C((1 - S[[%&"]])^1) * dquote * xmlws^-1 + + squote * C((1 - S[[%&']])^1) * squote * xmlws^-1 +local xml_attr = Cg(xml_name * P"=" * xml_attvalue) +local xml_attr_list = Cf(Ct"" * xml_attr^1, rawset) + +--[[doc-- + scan_node creates a parser for a given xml tag. +--doc]]-- +--- string -> bool -> lpeg_t +local scan_node = function (tag) + --- Node attributes go into a table with the index “attributes” + --- (relevant for “prefix="xdg"” and the likes). + local p_tag = P(tag) + local with_attributes = P"<" * p_tag + * Cg(xml_attr_list, "attributes")^-1 + * xmlws^-1 + * P">" + local plain = P"<" * p_tag * xmlws^-1 * P">" + local node_start = plain + with_attributes + local node_stop = P"" + --- there is no nesting, the earth is flat ... + local node = node_start + * Cc(tag) * C(comment + (1 - node_stop)^1) + * node_stop + return Ct(node) -- returns {string, string [, attributes = { key = val }] } +end + +--[[doc-- + At the moment, the interesting tags are “dir” for + directory declarations, and “include” for including + further configuration files. + + spec: http://freedesktop.org/software/fontconfig/fontconfig-user.html +--doc]]-- +local include_node = scan_node"include" +local dir_node = scan_node"dir" + +local element = dir_node + + include_node + + comment --> ignore + + P(1-root_stop) --> skip byte + +local root = root_start * Ct(element^0) * root_stop +local p_cheapxml = header * root + +--lpeg.print(p_cheapxml) ---> 757 rules with v0.10 + +--[[doc-- + fonts_conf_scanner() handles configuration files. + It is called on an abolute path to a config file (e.g. + /home/luser/.config/fontconfig/fonts.conf) and returns a list + of the nodes it managed to extract from the file. +--doc]]-- +--- string -> path list +local fonts_conf_scanner = function (path) + local fh = ioopen(path, "r") + if not fh then + logreport("both", 3, "db", "Cannot open fontconfig file %s.", path) + return + end + local raw = fh:read"*all" + fh:close() + + local confdata = lpegmatch(p_cheapxml, raw) + if not confdata then + logreport("both", 3, "db", "Cannot scan fontconfig file %s.", path) + return + end + return confdata +end + +local p_conf = P".conf" * P(-1) +local p_filter = (1 - p_conf)^1 * p_conf + +local conf_filter = function (path) + if lpegmatch (p_filter, path) then + return true + end + return false +end + +--[[doc-- + read_fonts_conf_indeed() is called with seven arguments; the + latter three are tables that represent the state and are + always returned. + The first four are + · the path to the file + · the expanded $HOME + · the expanded $XDG_CONFIG_HOME + · the expanded $XDG_DATA_HOME +--doc]]-- +--- string -> string -> string -> tab -> tab -> (tab * tab * tab) +local read_fonts_conf_indeed +read_fonts_conf_indeed = function (start, home, xdg_config_home, + xdg_data_home, + acc, done, dirs_done, + find_files) + + local paths = fonts_conf_scanner(start) + if not paths then --- nothing to do + return acc, done, dirs_done + end + + for i=1, #paths do + local pathobj = paths[i] + local kind, path = pathobj[1], pathobj[2] + local attributes = pathobj.attributes + + if kind == "dir" then + if attributes and attributes.prefix == "xdg" then + path = filejoin(xdg_data_home, path) + end + if stringsub(path, 1, 1) == "~" then + path = filejoin(home, stringsub(path, 2)) + end + --- We exclude paths with texmf in them, as they should be + --- found anyway; also duplicates are ignored by checking + --- if they are elements of dirs_done. + --- + --- FIXME does this mean we cannot access paths from + --- distributions (e.g. Context minimals) installed + --- separately? + if not (stringfind(path, "texmf") or dirs_done[path]) then + acc[#acc+1] = path + dirs_done[path] = true + end + + elseif kind == "include" then + if attributes and attributes.prefix == "xdg" then + path = filejoin(xdg_config_home, path) + end + --- here the path can be four things: a directory or a file, + --- in absolute or relative path. + if stringsub(path, 1, 1) == "~" then + path = filejoin(home, stringsub(path, 2)) + elseif --- if the path is relative, we make it absolute + not ( lfsisfile(path) or lfsisdir(path) ) + then + path = filejoin(filedirname(start), path) + end + if lfsisfile(path) + and kpsereadable_file(path) + and not done[path] + then + --- we exclude path with texmf in them, as they should + --- be found otherwise + acc = read_fonts_conf_indeed( + path, home, xdg_config_home, xdg_data_home, + acc, done, dirs_done) + elseif lfsisdir(path) then --- arrow code ahead + local config_files = find_files (path, conf_filter) + for _, filename in next, config_files do + if not done[filename] then + acc = read_fonts_conf_indeed( + filename, home, xdg_config_home, xdg_data_home, + acc, done, dirs_done) + end + end + end --- match “kind” + end --- iterate paths + end + + --inspect(acc) + --inspect(done) + return acc, done, dirs_done + end --- read_fonts_conf_indeed() + +--[[doc-- + read_fonts_conf() sets up an accumulator and two sets + for tracking what’s been done. + + Also, the environment variables HOME, XDG_DATA_HOME and + XDG_CONFIG_HOME -- which are constants anyways -- are expanded + so we don’t have to repeat that over and over again as with the + old parser. Now they’re just passed on to every call of + read_fonts_conf_indeed(). +--doc]]-- + +--- list -> (string -> function option -> string list) -> list + +local read_fonts_conf = function (path_list, find_files) + local home = kpseexpand_path"~" --- could be os.getenv"HOME" + local xdg_config_home = kpseexpand_path"$XDG_CONFIG_HOME" + if xdg_config_home == "" then xdg_config_home = filejoin(home, ".config") end + local xdg_data_home = kpseexpand_path"$XDG_DATA_HOME" + if xdg_data_home == "" then xdg_data_home = filejoin(home, ".local/share") end + local acc = { } ---> list: paths collected + local done = { } ---> set: files inspected + local dirs_done = { } ---> set: dirs in list + for i=1, #path_list do --- we keep the state between files + acc, done, dirs_done = read_fonts_conf_indeed( + path_list[i], home, xdg_config_home, + xdg_data_home, + acc, done, dirs_done, + find_files) + end + return acc +end + +luaotfload.parsers.read_fonts_conf = read_fonts_conf + + + +------------------------------------------------------------------------------- +--- MISC PARSERS +------------------------------------------------------------------------------- + + +local trailingslashes = slash^1 * P(-1) +local stripslashes = C((1 - trailingslashes)^0) +parsers.stripslashes = stripslashes + +local splitcomma = Ct((C(noncomma^1) + comma)^1) +parsers.splitcomma = splitcomma + + + +------------------------------------------------------------------------------- +--- FONT REQUEST +------------------------------------------------------------------------------- + + +--[[doc------------------------------------------------------------------------ + + The luaotfload font request syntax (see manual) + has a canonical form: + + \font=:: + + where + is the control sequence that activates the font + is either “file” or “name”, determining the lookup + is either a file name (no path) or a font + name, depending on the lookup + is a list of switches or options, separated by + semicolons or commas; a switch is of the form “+” foo + or “-” foo, options are of the form lhs “=” rhs + + however, to ensure backward compatibility we also have + support for Xetex-style requests. + + for the Xetex emulation see: + · The XeTeX Reference Guide by Will Robertson, 2011 + · The XeTeX Companion by Michel Goosens, 2010 + · About XeTeX by Jonathan Kew, 2005 + + + caueat emptor. + + the request is parsed into one of **four** different lookup + categories: the regular ones, file and name, as well as the + Xetex compatibility ones, path and anon. (maybe a better choice + of identifier would be “ambig”.) + + according to my reconstruction, the correct chaining of the + lookups for each category is as follows: + + | File -> ( db/filename lookup ) + + | Name -> ( db/name lookup, + db/filename lookup ) + + | Path -> ( db/filename lookup, + fullpath lookup ) + + | Anon -> ( kpse.find_file(), // <- for tfm, ofm + db/name lookup, + db/filename lookup, + fullpath lookup ) + + caching of successful lookups is essential. we now as of v2.2 + have a lookup cache that is stored in a separate file. it + pertains only to name: lookups, and is described in more detail + in luaotfload-database.lua. + +------------------------------------------------------------------------------- + + One further incompatibility between Xetex and Luatex-Fonts consists + in their option list syntax: apparently, Xetex requires key-value + options to be prefixed by a "+" (ascii “plus”) character. We + silently accept this as well, dropping the first byte if it is a + plus or minus character. + + Reference: https://github.com/lualatex/luaotfload/issues/79#issuecomment-18104483 + +--doc]]------------------------------------------------------------------------ + + +local handle_normal_option = function (key, val) + val = stringlower(val) + --- the former “toboolean()” handler + if val == "true" then + val = true + elseif val == "false" then + val = false + end + return key, val +end + +--[[doc-- + + Xetex style indexing begins at zero which we just increment before + passing it along to the font loader. Ymmv. + +--doc]]-- + +local handle_xetex_option = function (key, val) + val = stringlower(val) + local numeric = tonumber(val) --- decimal only; keeps colors intact + if numeric then --- ugh + if mathceil(numeric) == numeric then -- integer, possible index + val = tostring(numeric + 1) + end + elseif val == "true" then + val = true + elseif val == "false" then + val = false + end + return key, val +end + +--[[doc-- + + Instead of silently ignoring invalid options we emit a warning to + the log. + + Note that we have to return a pair to please rawset(). This creates + an entry on the resulting features hash which will later be removed + during set_default_features(). + +--doc]]-- + +local handle_invalid_option = function (opt) + logreport("log", 0, "load", "font option %q unknown.", opt) + return "", false +end + +--[[doc-- + + Dirty test if a file: request is actually a path: lookup; don’t + ask! Note this fails on Windows-style absolute paths. These will + *really* have to use the correct request. + +--doc]]-- + +local check_garbage = function (_,i, garbage) + if stringfind(garbage, "/") then + logreport("log", 0, "load", --- ffs use path! + "warning: path in file: lookups is deprecated; ") + logreport("log", 0, "load", "use bracket syntax instead!") + logreport("log", 0, "load", + "position: %d; full match: %q", + i, garbage) + return true + end + return false +end + +local featuresep = comma + semicolon + +--- modifiers --------------------------------------------------------- +--[[doc-- + The slash notation: called “modifiers” (Kew) or “font options” + (Robertson, Goosens) + we only support the shorthands for italic / bold / bold italic + shapes, as well as setting optical size, the rest is ignored. +--doc]]-- +local style_modifier = (P"BI" + P"IB" + P"bi" + P"ib" + S"biBI") + / stringlower +local size_modifier = S"Ss" * P"=" --- optical size + * Cc"optsize" * C(decimal) +local other_modifier = P"AAT" + P"aat" --- apple stuff; unsupported + + P"ICU" + P"icu" --- not applicable + + P"GR" + P"gr" --- sil stuff; unsupported +local garbage_modifier = ((1 - colon - slash)^0 * Cc(false)) +local modifier = slash * (other_modifier --> ignore + + Cs(style_modifier) --> collect + + Ct(size_modifier) --> collect + + garbage_modifier) --> warn +local modifier_list = Cg(Ct(modifier^0), "modifiers") + +--- lookups ----------------------------------------------------------- +local fontname = C((1-S":(/")^1) --- like luatex-fonts +local unsupported = Cmt((1-S":(")^1, check_garbage) +local prefixed = P"name:" * ws * Cg(fontname, "name") +--- initially we intended file: to emulate the behavior of +--- luatex-fonts, i.e. no paths allowed. after all, we do have XeTeX +--- emulation with the path lookup and it interferes with db lookups. +--- turns out fontspec and other widely used packages rely on file: +--- with paths already, so we’ll add a less strict rule here. anyways, +--- we’ll emit a warning. + + P"file:" * ws * Cg(unsupported, "path") + + P"file:" * ws * Cg(fontname, "file") +--- EXPERIMENTAL: kpse lookup + + P"kpse:" * ws * Cg(fontname, "kpse") +--- EXPERIMENTAL: custom lookup + + P"my:" * ws * Cg(fontname, "my") +local unprefixed = Cg(fontname, "anon") +local path_lookup = lbrk * Cg(C((1-rbrk)^1), "path") * rbrk + +--- features ---------------------------------------------------------- +local field_char = anum + S"+-." --- sic! +local field = field_char^1 +--- assignments are “lhs=rhs” +--- or “+lhs=rhs” (Xetex-style) +--- switches are “+key” | “-key” +local normal_option = C(field) * ws * equals * ws * C(field) * ws +local xetex_option = P"+" * ws * normal_option +local ignore_option = (1 - equals - featuresep)^1 + * equals + * (1 - featuresep)^1 +local assignment = xetex_option / handle_xetex_option + + normal_option / handle_normal_option + + ignore_option / handle_invalid_option +local switch = P"+" * ws * C(field) * Cc(true) + + P"-" * ws * C(field) * Cc(false) + + C(field) * Cc(true) --- default +local feature_expr = ws * Cg(assignment + switch) * ws +local option = feature_expr +local feature_list = Cf(Ct"" + * option + * (featuresep * option^-1)^0 + , rawset) + * featuresep^-1 + +--- other ------------------------------------------------------------- +--- This rule is present in the original parser. It sets the “sub” +--- field of the specification which allows addressing a specific +--- font inside a TTC container. Neither in Luatex-Fonts nor in +--- Luaotfload is this documented, so we might as well silently drop +--- it. However, as backward compatibility is one of our prime goals we +--- just insert it here and leave it undocumented until someone cares +--- to ask. (Note: afair subfonts are numbered, but this rule matches a +--- string; I won’t mess with it though until someone reports a +--- problem.) +--- local subvalue = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim +--- Note to self: subfonts apparently start at index 0. Tested with +--- Cambria.ttc that includes “Cambria Math” at 0 and “Cambria” at 1. +--- Other values cause luatex to segfault. +local subfont = P"(" * Cg((1 - S"()")^1, "sub") * P")" +--- top-level rules --------------------------------------------------- +--- \font\foo=: +local features = Cg(feature_list, "features") +local specification = (prefixed + unprefixed) + * subfont^-1 + * modifier_list^-1 +local font_request = Ct(path_lookup * (colon^-1 * features)^-1 + + specification * (colon * features)^-1) + +-- lpeg.print(font_request) +--- v2.5 parser: 1065 rules +--- v1.2 parser: 230 rules + +luaotfload.parsers.font_request = font_request + +------------------------------------------------------------------------------- +--- INI FILES +------------------------------------------------------------------------------- + +--[[doc-- + + Luaotfload uses the pervasive flavor of the INI files that allows '#' in + addition to ';' to indicate comment lines (see git-config(1) for a + description of the syntax we’re targeting). + +--doc]]-- + +local truth_ids = { + ["true"] = true, + ["1"] = true, + yes = true, + on = true, + ["false"] = false, + ["2"] = false, + no = false, + off = false, +} + +local maybe_cast = function (var) + local bool = truth_ids[var] + if bool ~= nil then + return bool + end + return tonumber (var) or var +end +local escape = function (chr, repl) + return (backslash * P(chr) / (repl or chr)) +end +local valid_escapes = escape "\"" + + escape "\\" + + escape ("n", "\n") + + escape ("t", "\t") + + escape ("b", "\b") +local comment_char = semicolon + gartenzaun +local comment_line = ws * comment_char * (1 - eol)^0 * eol +local blank_line = ws * eol +local skip_line = comment_line + blank_line +local ini_id_char = alpha + (dash / "_") +local ini_id = Cs(alpha * ini_id_char^0) / stringlower +local ini_value_char = (valid_escapes + (1 - newline - backslash - comment_char)) +local ini_value = (Cs (ini_value_char^0) / string.strip) + * (comment_char * (1 - eol)^0)^-1 +local ini_string_char = (valid_escapes + (1 - newline - dquote - backslash)) +local ini_string = dquote + * Cs (ini_string_char^0) + * dquote + +local ini_heading_title = Ct (Cg (ini_id, "title") + * (ws * Cg (ini_string / stringlower, "subtitle"))^-1) +local ini_heading = lbrk * ws + * Cg (ini_heading_title, "section") + * ws * rbrk * ws * eol + +local ini_variable_full = Cg (ws + * ini_id + * ws + * equals + * ws + * (ini_string + (ini_value / maybe_cast)) + * ws + * eol) +local ini_variable_true = Cg (ws * ini_id * ws * eol * Cc (true)) +local ini_variable = ini_variable_full + + ini_variable_true + + skip_line +local ini_variables = Cg (Cf (Ct "" * ini_variable^0, rawset), "variables") + +local ini_section = Ct (ini_heading * ini_variables) +local ini_sections = skip_line^0 * ini_section^0 +local config = Ct (ini_sections) + +--[=[doc-- + + The INI parser converts an input of the form + + [==[ + [foo] + bar = baz + xyzzy = no + buzz + + [lavernica "brutalitops"] + # It’s a locomotive that runs on us. + laan-ev = zip zop zooey ; jib-jab + Crouton = "Fibrosis \"\\ # " + + ]==] + + to a Lua table of the form + + { { section = { title = "foo" }, + variables = { bar = "baz", + xyzzy = false, + buzz = true } }, + { section = { title = "boing", + subtitle = "brutalitops" }, + variables = { ["laan-ev"] = "zip zop zooey", + crouton = "Fibrosis \"\\ # " } } } + +--doc]=]-- + +luaotfload.parsers.config = config + +-- vim:ft=lua:tw=71:et:sts=4:ts=8 diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua index c04f048d048..d613883235a 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua @@ -1,33 +1,35 @@ return { ["hashes"]={ - { "mkstatus", "51af30205d30c2b7f5bfd5169d9911a0" }, - { "mkglyphlist", "a8d64d29927ad8aebd1280a11d335895" }, - { "mkcharacters", "f25363cbe04fc5f1210930a10635247f" }, - { "luaotfload-tool.lua", "978fc97d7f3e60cc36a56e4375aabebb" }, - { "luaotfload-override.lua", "d0e40ea83d625813aa0fe2f9e76d8ef5" }, - { "luaotfload-fontloader.lua", "21b625efe6630b76250e18f7d2832cff" }, - { "luaotfload.lua", "408064879902b664459e931e6abb75f3" }, - { "luaotfload-loaders.lua", "b04c6d9aa2974d56895fe3dff3fea90d" }, - { "luaotfload-letterspace.lua", "19e6181076dda7c8c34e7096cee1f873" }, - { "luaotfload-glyphlist.lua", "ff440162d1b8a78a586375ee65630c21" }, - { "luaotfload-fonts-tfm.lua", "8fd3865240e4e87e99e0739abeda2322" }, - { "luaotfload-fonts-lua.lua", "50b8edb1db7009b6c661ab71ff24a466" }, - { "luaotfload-fonts-ext.lua", "0eee87fb26b7d135da88ac0a43a8037a" }, - { "luaotfload-fonts-enc.lua", "32775266bfc9eb6bbd9a16e3a7de398d" }, - { "luaotfload-fonts-def.lua", "8dc05f2aa96d2fd0245242c8fd3320eb" }, - { "luaotfload-fonts-cbk.lua", "c1b7a4e5508d68f45a99cdc38c2d0885" }, - { "luaotfload-features.lua", "0d97a50852fb55be4133874c8f487832" }, - { "luaotfload-diagnostics.lua", "eed12e7b7fe6545daa6786fed1405a4f" }, - { "luaotfload-database.lua", "db8d9e939910a7fce9b811546edd95c2" }, - { "luaotfload-colors.lua", "248c4c42586c17e934a4d046c3c873b9" }, - { "luaotfload-characters.lua", "2673ffb19e8505af4782aad437a76a4f" }, - { "luaotfload-basics-nod.lua", "d6b26ec86c0b1c1516936b425df04432" }, - { "luaotfload-basics-gen.lua", "3dadc2cd31ab348f7effb28e335af3ae" }, - { "luaotfload-auxiliary.lua", "7efa9d365f12006d5c4c7c38e0e2872c" }, + { "scripts/mkstatus", "fe7c02e1ecc0482033dc6bffd0974c10" }, + { "scripts/mkglyphlist", "62bc2c915a0fc936f9249deb0eddcaf3" }, + { "scripts/mkcharacters", "ec694a87f77067912eb73402ec99040d" }, + { "src/luaotfload-tool.lua", "741ba3e814cbd08ea026f56073e88162" }, + { "src/luaotfload-parsers.lua", "3dd1cb4175729c2f21dad158db4c633f" }, + { "src/luaotfload-override.lua", "e6f67a268fa9362d5ebc5cbecad1a900" }, + { "src/luaotfload-fontloader.lua", "f3055735e2d0b624000a9ce73b9dedc0" }, + { "src/luaotfload-main.lua", "cb35ddba0c110fb53908e4c0a2541839" }, + { "src/luaotfload-log.lua", "3c74574876352137b32073b763defbbf" }, + { "src/luaotfload-loaders.lua", "c364151f603514433fa3128939825d16" }, + { "src/luaotfload-letterspace.lua", "06cfb1e742d496b99c8980fdfd3f29f4" }, + { "build/luaotfload-glyphlist.lua", "ff440162d1b8a78a586375ee65630c21" }, + { "src/luaotfload-fonts-tfm.lua", "8fd3865240e4e87e99e0739abeda2322" }, + { "src/luaotfload-fonts-lua.lua", "50b8edb1db7009b6c661ab71ff24a466" }, + { "src/luaotfload-fonts-ext.lua", "0eee87fb26b7d135da88ac0a43a8037a" }, + { "src/luaotfload-fonts-enc.lua", "32775266bfc9eb6bbd9a16e3a7de398d" }, + { "src/luaotfload-fonts-def.lua", "8dc05f2aa96d2fd0245242c8fd3320eb" }, + { "src/luaotfload-fonts-cbk.lua", "c1b7a4e5508d68f45a99cdc38c2d0885" }, + { "src/luaotfload-features.lua", "6c3e33f4bd1090883851b7f63d45e7fc" }, + { "src/luaotfload-diagnostics.lua", "273afde55dff486fb222a50981b3b1d7" }, + { "src/luaotfload-database.lua", "9ea266330bbe2d974179e8dbb83997a5" }, + { "src/luaotfload-colors.lua", "99878378ef0954d0b67f13db8456dea7" }, + { "build/luaotfload-characters.lua", "9b9820f9fb6ec694df43b648026fc444" }, + { "src/luaotfload-basics-nod.lua", "7fdaff58d8c32e3115286504cbd7bcac" }, + { "src/luaotfload-basics-gen.lua", "9d5c3fc031af110ba67f3faa1a569779" }, + { "src/luaotfload-auxiliary.lua", "b3c893f68217b4147e5d3ba694648583" }, }, ["notes"]={ ["committer"]="Philipp Gesang ", - ["revision"]="828a69efb1f899f8707270f4515db20d485ccc34", - ["timestamp"]="2014-05-18 21:35:56 +0200", + ["revision"]="5dc362a7098d9ecd4bfd446b59d7e895107f6e5e", + ["timestamp"]="2014-07-13 22:03:26 +0200", }, } \ No newline at end of file diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.lua deleted file mode 100644 index 014249efd78..00000000000 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.lua +++ /dev/null @@ -1,442 +0,0 @@ --- --- This is file `luaotfload.lua', --- generated with the docstrip utility. --- --- The original source files were: --- --- luaotfload.dtx (with options: `lua') --- This is a generated file. --- --- Copyright (C) 2009-2014 --- by Elie Roux --- and Khaled Hosny --- and Philipp Gesang --- --- Home: https://github.com/lualatex/luaotfload --- Support: . --- --- This work is under the GPL v2.0 license. --- --- This work consists of the main source file luaotfload.dtx --- and the derived files --- luaotfload.sty, luaotfload.lua --- -luaotfload = luaotfload or {} -local luaotfload = luaotfload - -config = config or { } -config.luaotfload = config.luaotfload or { } -------.luaotfload.resolver = config.luaotfload.resolver or "normal" -config.luaotfload.resolver = config.luaotfload.resolver or "cached" -config.luaotfload.definer = config.luaotfload.definer or "patch" -config.luaotfload.compatibility = config.luaotfload.compatibility or false -config.luaotfload.loglevel = config.luaotfload.loglevel or 2 -config.luaotfload.color_callback = config.luaotfload.color_callback or "pre_linebreak_filter" -config.luaotfload.prioritize = config.luaotfload.prioritize or "sys" -config.luaotfload.names_dir = config.luaotfload.names_dir or "names" -config.luaotfload.cache_dir = config.luaotfload.cache_dir or "fonts" -config.luaotfload.index_file = config.luaotfload.index_file or "luaotfload-names.lua" -config.luaotfload.formats = config.luaotfload.formats or "otf,ttf,ttc,dfont" -if not config.luaotfload.strip then - config.luaotfload.strip = true -end - -luaotfload.module = { - name = "luaotfload", - version = 2.40005, --- 2.4-4 - date = "2014/05/18", - description = "OpenType layout system.", - author = "Elie Roux & Hans Hagen", - copyright = "Elie Roux", - license = "GPL v2.0" -} - -local luatexbase = luatexbase - -local setmetatable = setmetatable -local type, next = type, next - -local kpsefind_file = kpse.find_file -local lfsisfile = lfs.isfile - -local add_to_callback, create_callback = - luatexbase.add_to_callback, luatexbase.create_callback -local reset_callback, call_callback = - luatexbase.reset_callback, luatexbase.call_callback - -local dummy_function = function () end - -local error, warning, info, log = - luatexbase.provides_module(luaotfload.module) - -luaotfload.error = error -luaotfload.warning = warning -luaotfload.info = info -luaotfload.log = log - - -local luatex_version = 76 - -if tex.luatexversion < luatex_version then - warning("LuaTeX v%.2f is old, v%.2f is recommended.", - tex.luatexversion/100, - luatex_version /100) - --- we install a fallback for older versions as a safety - if not node.end_of_math then - local math_t = node.id"math" - local traverse_nodes = node.traverse_id - node.end_of_math = function (n) - for n in traverse_nodes(math_t, n.next) do - return n - end - end - end -end - - -local fl_prefix = "luaotfload" -- “luatex” for luatex-plain -local loadmodule = function (name) - require(fl_prefix .."-"..name) -end - -local Cs, P, lpegmatch = lpeg.Cs, lpeg.P, lpeg.match - -local p_dot, p_slash = P".", P"/" -local p_suffix = (p_dot * (1 - p_dot - p_slash)^1 * P(-1)) / "" -local p_removesuffix = Cs((p_suffix + 1)^1) - -local find_vf_file = function (name) - local fullname = kpsefind_file(name, "ovf") - if not fullname then - --fullname = kpsefind_file(file.removesuffix(name), "ovf") - fullname = kpsefind_file(lpegmatch(p_removesuffix, name), "ovf") - end - if fullname then - log("loading virtual font file %s.", fullname) - end - return fullname -end - - -local starttime = os.gettimeofday() - -local trapped_register = callback.register -callback.register = dummy_function - - -do - local new_attribute = luatexbase.new_attribute - local the_attributes = luatexbase.attributes - - attributes = attributes or { } - - attributes.private = function (name) - local attr = "luaotfload@" .. name --- used to be: “otfl@” - local number = the_attributes[attr] - if not number then - number = new_attribute(attr) - end - return number - end -end - - -local context_environment = { } - -local push_namespaces = function () - log("push namespace for font loader") - local normalglobal = { } - for k, v in next, _G do - normalglobal[k] = v - end - return normalglobal -end - -local pop_namespaces = function (normalglobal, isolate) - if normalglobal then - local _G = _G - local mode = "non-destructive" - if isolate then mode = "destructive" end - log("pop namespace from font loader -- " .. mode) - for k, v in next, _G do - if not normalglobal[k] then - context_environment[k] = v - if isolate then - _G[k] = nil - end - end - end - for k, v in next, normalglobal do - _G[k] = v - end - -- just to be sure: - setmetatable(context_environment,_G) - else - log("irrecoverable error during pop_namespace: no globals to restore") - os.exit() - end -end - -luaotfload.context_environment = context_environment -luaotfload.push_namespaces = push_namespaces -luaotfload.pop_namespaces = pop_namespaces - -local our_environment = push_namespaces() - - -tex.attribute[0] = 0 - - -loadmodule"fontloader.lua" ----loadmodule"font-odv.lua" --- <= Devanagari support from Context - -if fonts then - - if not fonts._merge_loaded_message_done_ then - log [["I am using the merged version of 'luaotfload.lua' here.]] - log [[ If you run into problems or experience unexpected]] - log [[ behaviour, and if you have ConTeXt installed you can try]] - log [[ to delete the file 'luaotfload-merged.lua' as I might]] - log [[ then use the possibly updated libraries. The merged]] - log [[ version is not supported as it is a frozen instance.]] - log [[ Problems can be reported to the ConTeXt mailing list."]] - end - fonts._merge_loaded_message_done_ = true - -else--- the loading sequence is known to change, so this might have to - --- be updated with future updates! - --- do not modify it though unless there is a change to the merged - --- package! - loadmodule("l-lua.lua") - loadmodule("l-lpeg.lua") - loadmodule("l-function.lua") - loadmodule("l-string.lua") - loadmodule("l-table.lua") - loadmodule("l-io.lua") - loadmodule("l-file.lua") - loadmodule("l-boolean.lua") - loadmodule("l-math.lua") - loadmodule("util-str.lua") - loadmodule('luatex-basics-gen.lua') - loadmodule('data-con.lua') - loadmodule('luatex-basics-nod.lua') - loadmodule('font-ini.lua') - loadmodule('font-con.lua') - loadmodule('luatex-fonts-enc.lua') - loadmodule('font-cid.lua') - loadmodule('font-map.lua') - loadmodule('luatex-fonts-syn.lua') - loadmodule('luatex-fonts-tfm.lua') - loadmodule('font-oti.lua') - loadmodule('font-otf.lua') - loadmodule('font-otb.lua') - loadmodule('node-inj.lua') - loadmodule('font-ota.lua') - loadmodule('font-otn.lua') - loadmodule('font-otp.lua')--- since 2013-04-23 - loadmodule('luatex-fonts-lua.lua') - loadmodule('font-def.lua') - loadmodule('luatex-fonts-def.lua') - loadmodule('luatex-fonts-ext.lua') - loadmodule('luatex-fonts-cbk.lua') -end --- non-merge fallback scope - - -pop_namespaces(our_environment, false)-- true) - -log("fontloader loaded in %0.3f seconds", os.gettimeofday()-starttime) - - -callback.register = trapped_register - - -add_to_callback("pre_linebreak_filter", - nodes.simple_font_handler, - "luaotfload.node_processor", - 1) -add_to_callback("hpack_filter", - nodes.simple_font_handler, - "luaotfload.node_processor", - 1) -add_to_callback("find_vf_file", - find_vf_file, "luaotfload.find_vf_file") - -loadmodule"override.lua" --- “luat-ovr” - -logs.set_loglevel(config.luaotfload.loglevel) - -loadmodule"loaders.lua" --- “font-pfb” new in 2.0, added 2011 -loadmodule"database.lua" --- “font-nms” -loadmodule"colors.lua" --- “font-clr” - - -local filesuffix = file.suffix -local fileremovesuffix = file.removesuffix -local request_resolvers = fonts.definers.resolvers -local formats = fonts.formats -local names = fonts.names -formats.ofm = "type1" - -fonts.encodings.known = fonts.encodings.known or { } - - -local resolve_file = names.crude_file_lookup ---local resolve_file = names.crude_file_lookup_verbose -local resolve_name = names.resolve_name - -local file_resolver = function (specification) - local name = resolve_file (specification.name) - local suffix = filesuffix(name) - if formats[suffix] then - specification.forced = string.lower (suffix) - specification.forcedname = file.removesuffix(name) - else - specification.name = name - end -end - -request_resolvers.file = file_resolver - - ---request_resolvers.anon = request_resolvers.name - - -local type1_formats = { "tfm", "ofm", } - -request_resolvers.anon = function (specification) - local name = specification.name - for i=1, #type1_formats do - local format = type1_formats[i] - if resolvers.findfile(name, format) then - specification.forcedname = file.addsuffix(name, format) - specification.forced = format - return - end - end - --- under some weird circumstances absolute paths get - --- passed to the definer; we have to catch them - --- before the name: resolver misinterprets them. - name = specification.specification - local exists, _ = lfsisfile(name) - if exists then --- garbage; we do this because we are nice, - --- not because it is correct - logs.names_report("log", 1, "load", "file %q exists", name) - logs.names_report("log", 1, "load", - "... overriding borked anon: lookup with path: lookup") - specification.name = name - request_resolvers.path(specification) - return - end - request_resolvers.name(specification) -end - - -request_resolvers.path = function (specification) - local name = specification.name - local exists, _ = lfsisfile(name) - if not exists then -- resort to file: lookup - logs.names_report("log", 1, "load", - "path lookup of %q unsuccessful, falling back to file:", - name) - file_resolver (specification) - else - local suffix = filesuffix (name) - if formats[suffix] then - specification.forced = string.lower (suffix) - specification.name = file.removesuffix(name) - specification.forcedname = name - else - specification.name = name - end - end -end - - -request_resolvers.kpse = function (specification) - local name = specification.name - local suffix = filesuffix(name) - if suffix and formats[suffix] then - name = file.removesuffix(name) - if resolvers.findfile(name, suffix) then - specification.forced = string.lower (suffix) - specification.forcedname = name - return - end - end - for t, format in next, formats do --- brute force - if kpse.find_file (name, format) then - specification.forced = t - specification.name = name - return - end - end -end - - ---- fonts.names.resolvers.name -- Customized version of the ---- generic name resolver. - -request_resolvers.name = function (specification) - local resolved, subfont = resolve_name (specification) - if resolved then - specification.resolved = resolved - specification.sub = subfont - specification.forced = string.lower (filesuffix (resolved) or "") - specification.forcedname = resolved - specification.name = fileremovesuffix (resolved) - else - file_resolver (specification) - end -end - -create_callback("luaotfload.resolve_font", "simple", dummy_function) - -request_resolvers.my = function (specification) - call_callback("luaotfload.resolve_font", specification) -end - - -create_callback("luaotfload.patch_font", "simple", dummy_function) - - -local read_font_file = fonts.definers.read - ---- spec -> size -> id -> tmfdata -local patch_defined_font = function (specification, size, id) - local tfmdata = read_font_file(specification, size, id) - if type(tfmdata) == "table" and tfmdata.shared then - --- We need to test for the “shared” field here - --- or else the fontspec capheight callback will - --- operate on tfm fonts. - call_callback("luaotfload.patch_font", tfmdata, specification) - end - return tfmdata -end - -reset_callback "define_font" - - -local font_definer = config.luaotfload.definer - -if font_definer == "generic" then - add_to_callback("define_font", - fonts.definers.read, - "luaotfload.define_font", - 1) -elseif font_definer == "patch" then - add_to_callback("define_font", - patch_defined_font, - "luaotfload.define_font", - 1) -end - -loadmodule"features.lua" --- contains what was “font-ltx” and “font-otc” -loadmodule"letterspace.lua" --- extra character kerning -loadmodule"auxiliary.lua" --- additionaly high-level functionality (new) - -luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec - --- vim:tw=71:sw=4:ts=4:expandtab - --- --- End of File `luaotfload.lua'. diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty index 3d27502135b..9848a223d53 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty @@ -1,26 +1,35 @@ -%% -%% This is file `luaotfload.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% luaotfload.dtx (with options: `package') -%% This is a generated file. -%% %% Copyright (C) 2009-2014 +%% %% by Elie Roux %% and Khaled Hosny %% and Philipp Gesang -%% +%% +%% This file is part of Luaotfload. +%% %% Home: https://github.com/lualatex/luaotfload %% Support: . -%% -%% This work is under the GPL v2.0 license. -%% -%% This work consists of the main source file luaotfload.dtx -%% and the derived files -%% luaotfload.sty, luaotfload.lua -%% +%% +%% Luaotfload is under the GPL v2.0 (exactly) license. +%% +%% ---------------------------------------------------------------------------- +%% +%% Luaotfload is free software; you can redistribute it and/or +%% modify it under the terms of the GNU General Public License +%% as published by the Free Software Foundation; version 2 +%% of the License. +%% +%% Luaotfload is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%% GNU General Public License for more details. +%% +%% You should have received a copy of the GNU General Public License +%% along with Luaotfload; if not, see . +%% +%% ---------------------------------------------------------------------------- +%% +%% Classical Plain+\LATEX package initialization. +%% \csname ifluaotfloadloaded\endcsname \let\ifluaotfloadloaded\endinput \bgroup\expandafter\expandafter\expandafter\egroup @@ -29,16 +38,8 @@ \else \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{luaotfload}% - [2014/05/18 v2.4-4 OpenType layout system] + [2014/07/13 v2.5 OpenType layout system] \RequirePackage{luatexbase} \fi -\ifnum\luatexversion<76 - %% here some deprecation warning would be in order - \RequireLuaModule{lualibs} - \RequireLuaModule{luaotfload-legacy} -\else - \RequireLuaModule{luaotfload} -\fi -\endinput -%% -%% End of file `luaotfload.sty'. +\RequireLuaModule{luaotfload-main} + diff --git a/Master/tlpkg/tlpsrc/luaotfload.tlpsrc b/Master/tlpkg/tlpsrc/luaotfload.tlpsrc index 9a41a47865c..77a102cedd8 100644 --- a/Master/tlpkg/tlpsrc/luaotfload.tlpsrc +++ b/Master/tlpkg/tlpsrc/luaotfload.tlpsrc @@ -1,3 +1,4 @@ binpattern f bin/${ARCH}/mkluatexfontdb binpattern f bin/${ARCH}/luaotfload-tool docpattern +f texmf-dist/doc/man/man1/luaotfload-tool.* +docpattern +f texmf-dist/doc/man/man5/luaotfload.conf.* -- cgit v1.2.3